1
0
Fork 0
mirror of https://github.com/codex-team/codex.docs.git synced 2025-08-09 07:25:21 +02:00

Update sidebar module

This commit is contained in:
Tanya Fomina 2022-06-10 15:59:51 +08:00
parent 92e62158b1
commit 6cc2d22e45
2 changed files with 76 additions and 27 deletions

View file

@ -1,7 +1,9 @@
import { Storage } from '../utils/storage';
/** /**
* Local storage key * Local storage key
*/ */
const LOCAL_STORAGE_KEY = 'docs_siedabar_state'; const LOCAL_STORAGE_KEY = 'docs_sidebar_state';
/** /**
* Sidebar module * Sidebar module
@ -32,10 +34,18 @@ export default class Sidebar {
* Creates base properties * Creates base properties
*/ */
constructor() { constructor() {
this.nodes = {}; /**
const storedState = window.localStorage.getItem(LOCAL_STORAGE_KEY); * Stores refs to HTML elements needed for correct sidebar work
*/
this.nodes = {
sections: [],
sidebarContent: null,
toggler: null,
};
this.sidebarStorage = new Storage(LOCAL_STORAGE_KEY);
const storedState = this.sidebarStorage.get();
this.collapsed = storedState ? JSON.parse(storedState) : {}; this.sectionsState = storedState ? JSON.parse(storedState) : {};
} }
/** /**
@ -46,50 +56,56 @@ export default class Sidebar {
*/ */
init(settings, moduleEl) { init(settings, moduleEl) {
this.nodes.sections = Array.from(moduleEl.querySelectorAll('.' + Sidebar.CSS.section)); this.nodes.sections = Array.from(moduleEl.querySelectorAll('.' + Sidebar.CSS.section));
this.nodes.sections.forEach(section => { this.nodes.sections.forEach(section => this.initSection(section));
const id = section.getAttribute('data-id');
const togglerEl = section.querySelector('.' + Sidebar.CSS.toggler);
if (!togglerEl) {
return;
}
togglerEl.addEventListener('click', e => this.handleSectionTogglerClick(id, section, togglerEl, e));
if (typeof this.collapsed[id] === 'undefined') {
this.collapsed[id] = false;
}
if (this.collapsed[id]) {
this.setSectionCollapsed(section, true, false);
}
});
this.nodes.sidebarContent = moduleEl.querySelector('.' + Sidebar.CSS.sidebarContent); this.nodes.sidebarContent = moduleEl.querySelector('.' + Sidebar.CSS.sidebarContent);
this.nodes.toggler = moduleEl.querySelector('.' + Sidebar.CSS.sidebarToggler); this.nodes.toggler = moduleEl.querySelector('.' + Sidebar.CSS.sidebarToggler);
this.nodes.toggler.addEventListener('click', () => this.toggleSidebar()); this.nodes.toggler.addEventListener('click', () => this.toggleSidebar());
this.ready(); this.ready();
} }
/**
* Initializes sidebar sections: applies stored state and adds event listeners
*
* @param {HTMLElement} section
* @returns {void}
*/
initSection(section) {
const id = section.dataset.id;
const togglerEl = section.querySelector('.' + Sidebar.CSS.toggler);
if (!togglerEl) {
return;
}
togglerEl.addEventListener('click', e => this.handleSectionTogglerClick(id, section, e));
if (typeof this.sectionsState[id] === 'undefined') {
this.sectionsState[id] = false;
}
if (this.sectionsState[id]) {
this.setSectionCollapsed(section, true, false);
}
}
/** /**
* Toggles section expansion * Toggles section expansion
* *
* @param {number} sectionId - id of the section to toggle * @param {number} sectionId - id of the section to toggle
* @param {HTMLElement} sectionEl - section html element * @param {HTMLElement} sectionEl - section html element
* @param {HTMLElement} togglerEl - toggler button html element
* @param {MouseEvent} event - click event * @param {MouseEvent} event - click event
* @returns {void} * @returns {void}
*/ */
handleSectionTogglerClick(sectionId, sectionEl, togglerEl, event) { handleSectionTogglerClick(sectionId, sectionEl, event) {
event.preventDefault(); event.preventDefault();
this.collapsed[sectionId] = !this.collapsed[sectionId]; this.sectionsState[sectionId] = !this.sectionsState[sectionId];
window.localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(this.collapsed)); this.sidebarStorage.set(JSON.stringify(this.sectionsState));
this.setSectionCollapsed(sectionEl, this.collapsed[sectionId]); this.setSectionCollapsed(sectionEl, this.sectionsState[sectionId]);
} }
/** /**
* Updates section's collapsed state * Updates section's collapsed state
* *
* @param {HTMLElement} sectionEl - element of the section to toggle * @param {HTMLElement} sectionEl - element of the section to toggle
* @param {HTMLElement} togglerEl - section's toggler button element
* @param {boolean} collapsed - new collapsed state * @param {boolean} collapsed - new collapsed state
* @param {boolean} [animated] - true if state should change with animation * @param {boolean} [animated] - true if state should change with animation
*/ */
@ -112,6 +128,9 @@ export default class Sidebar {
return; return;
} }
if (collapsed && animated) { if (collapsed && animated) {
/**
* Highlights section title as active with a delay to let section collapse animation finish first
*/
setTimeout(() => { setTimeout(() => {
sectionTitle.classList.toggle(Sidebar.CSS.sectionTitleActive, collapsed); sectionTitle.classList.toggle(Sidebar.CSS.sectionTitleActive, collapsed);
}, 200); }, 200);

View file

@ -0,0 +1,30 @@
/**
* Utility class to handle interaction with local storage
*/
export class Storage {
/**
* @param {string} key - storage key
*/
constructor(key) {
this.key = key;
}
/**
* Saves value to storage
*
* @param {string} value - value to be saved
*/
set(value) {
localStorage.setItem(this.key, value);
}
/**
* Retreives value from storage
*
* @returns {string}
*/
get() {
return localStorage.getItem(this.key);
}
}