mirror of
https://github.com/codex-team/codex.docs.git
synced 2025-07-25 16:19:44 +02:00
Added sidebar toggler (#214)
* feat: add sidebar slider * fix: fix visibility on mobile layout * fix visibility on mobile layout * change keyboard shortcut * change css property * fix: fix shortcuts to support Mac * fix shortcuts to support Mac * add comment to explain properties * fix: fix shortcuts * resolve merge conflict * fix: remove redundant property Co-authored-by: Peter Savchenko <specc.dev@gmail.com>
This commit is contained in:
parent
136702aeb7
commit
09835e3007
6 changed files with 117 additions and 12 deletions
|
@ -1,10 +1,11 @@
|
|||
import { Storage } from '../utils/storage';
|
||||
import Shortcut from '@codexteam/shortcuts';
|
||||
|
||||
/**
|
||||
* Local storage key
|
||||
*/
|
||||
const LOCAL_STORAGE_KEY = 'docs_sidebar_state';
|
||||
|
||||
const SIDEBAR_VISIBILITY_KEY = 'docs_sidebar_visibility';
|
||||
|
||||
/**
|
||||
* Section list item height in px
|
||||
|
@ -31,6 +32,9 @@ export default class Sidebar {
|
|||
sectionList: 'docs-sidebar__section-list',
|
||||
sectionListItemActive: 'docs-sidebar__section-list-item--active',
|
||||
sidebarToggler: 'docs-sidebar__toggler',
|
||||
sidebarSlider: 'docs-sidebar__slider',
|
||||
sidebarCollapsed: 'docs-sidebar--collapsed',
|
||||
sidebarAnimated: 'docs-sidebar--animated',
|
||||
sidebarContent: 'docs-sidebar__content',
|
||||
sidebarContentHidden: 'docs-sidebar__content--hidden',
|
||||
sidebarContentInvisible: 'docs-sidebar__content--invisible',
|
||||
|
@ -45,14 +49,24 @@ export default class Sidebar {
|
|||
* Stores refs to HTML elements needed for correct sidebar work
|
||||
*/
|
||||
this.nodes = {
|
||||
sidebar: null,
|
||||
sections: [],
|
||||
sidebarContent: null,
|
||||
toggler: null,
|
||||
slider: null,
|
||||
};
|
||||
this.sidebarStorage = new Storage(LOCAL_STORAGE_KEY);
|
||||
const storedState = this.sidebarStorage.get();
|
||||
|
||||
this.sectionsState = storedState ? JSON.parse(storedState) : {};
|
||||
|
||||
// Initialize localStorage that contains sidebar visibility
|
||||
this.sidebarVisibilityStorage = new Storage(SIDEBAR_VISIBILITY_KEY);
|
||||
// Get current sidebar visibility from storage
|
||||
const storedVisibility = this.sidebarVisibilityStorage.get();
|
||||
|
||||
// Sidebar visibility
|
||||
this.isVisible = storedVisibility !== 'false';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -62,11 +76,14 @@ export default class Sidebar {
|
|||
* @param {HTMLElement} moduleEl - module element
|
||||
*/
|
||||
init(settings, moduleEl) {
|
||||
this.nodes.sidebar = moduleEl;
|
||||
this.nodes.sections = Array.from(moduleEl.querySelectorAll('.' + Sidebar.CSS.section));
|
||||
this.nodes.sections.forEach(section => this.initSection(section));
|
||||
this.nodes.sidebarContent = moduleEl.querySelector('.' + Sidebar.CSS.sidebarContent);
|
||||
this.nodes.toggler = moduleEl.querySelector('.' + Sidebar.CSS.sidebarToggler);
|
||||
this.nodes.toggler.addEventListener('click', () => this.toggleSidebar());
|
||||
this.nodes.slider = moduleEl.querySelector('.' + Sidebar.CSS.sidebarSlider);
|
||||
this.nodes.slider.addEventListener('click', () => this.handleSliderClick());
|
||||
this.ready();
|
||||
}
|
||||
|
||||
|
@ -104,7 +121,7 @@ export default class Sidebar {
|
|||
|
||||
const itemsCount = sectionList.children.length;
|
||||
|
||||
sectionList.style.maxHeight = `${ itemsCount * ITEM_HEIGHT }px`;
|
||||
sectionList.style.maxHeight = `${itemsCount * ITEM_HEIGHT}px`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -168,12 +185,52 @@ export default class Sidebar {
|
|||
this.nodes.sidebarContent.classList.toggle(Sidebar.CSS.sidebarContentHidden);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes sidebar
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
initSidebar() {
|
||||
if (!this.isVisible) {
|
||||
this.nodes.sidebar.classList.add(Sidebar.CSS.sidebarCollapsed);
|
||||
}
|
||||
|
||||
/**
|
||||
* prevent sidebar animation on page load
|
||||
* Since animated class contains transition, hiding will be animated with it
|
||||
* To prevent awkward animation when visibility is set to false, we need to remove animated class
|
||||
*/
|
||||
setTimeout(() => {
|
||||
this.nodes.sidebar.classList.add(Sidebar.CSS.sidebarAnimated);
|
||||
}, 200);
|
||||
|
||||
// add event listener to execute keyboard shortcut
|
||||
// eslint-disable-next-line no-new
|
||||
new Shortcut({
|
||||
name: 'CMD+.',
|
||||
on: document.body,
|
||||
callback: () => this.handleSliderClick(),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Slides sidebar
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
handleSliderClick() {
|
||||
this.isVisible = !this.isVisible;
|
||||
this.sidebarVisibilityStorage.set(this.isVisible);
|
||||
this.nodes.sidebar.classList.toggle(Sidebar.CSS.sidebarCollapsed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays sidebar when ready
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
ready() {
|
||||
this.initSidebar();
|
||||
this.nodes.sidebarContent.classList.remove(Sidebar.CSS.sidebarContentInvisible);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue