@@ -115,29 +115,41 @@ class PushMenu {
115115 * Expand the sidebar menu.
116116 */
117117 expand ( ) : void {
118+ // Remove the sidebar-collapse class. Only on mobile, add the sidebar-open
119+ // class to indicate the sidebar is explicitly open.
120+
118121 document . body . classList . remove ( CLASS_NAME_SIDEBAR_COLLAPSE )
119122
120123 if ( this . isMobileSize ( ) ) {
121124 document . body . classList . add ( CLASS_NAME_SIDEBAR_OPEN )
122125 }
123126
127+ // Dispatch the expand event.
128+
124129 this . _element . dispatchEvent ( new Event ( EVENT_OPEN ) )
125130 }
126131
127132 /**
128133 * Collapse the sidebar menu.
129134 */
130135 collapse ( ) : void {
136+ // Remove the sidebar-open class (if present), and add the sidebar-collapse
137+ // class.
138+
131139 document . body . classList . remove ( CLASS_NAME_SIDEBAR_OPEN )
132140 document . body . classList . add ( CLASS_NAME_SIDEBAR_COLLAPSE )
133141
142+ // Dispatch the collapse event.
143+
134144 this . _element . dispatchEvent ( new Event ( EVENT_COLLAPSE ) )
135145 }
136146
137147 /**
138148 * Toggle the sidebar menu state.
139149 */
140150 toggle ( ) : void {
151+ // Toggle the sidebar state.
152+
141153 const isCollapsed = this . isCollapsed ( )
142154
143155 if ( isCollapsed ) {
@@ -146,6 +158,8 @@ class PushMenu {
146158 this . collapse ( )
147159 }
148160
161+ // If persistence is enabled, save the new state to localStorage.
162+
149163 if ( this . _config . enablePersistence ) {
150164 this . saveSidebarState (
151165 isCollapsed ? CLASS_NAME_SIDEBAR_OPEN : CLASS_NAME_SIDEBAR_COLLAPSE
@@ -155,18 +169,28 @@ class PushMenu {
155169
156170 /**
157171 * Read the CSS breakpoint of the sidebar from the DOM and update the
158- * sidebarBreakpoint config.
172+ * sidebarBreakpoint config. This breakpoint is defined using a CSS ::before
173+ * pseudo element on the sidebar-expand element when @media queries are used
174+ * to change the sidebar behavior based on screen size.
159175 */
160176 setupSidebarBreakPoint ( ) : void {
177+ // Find the sidebar-expand element in the DOM.
178+
161179 const sidebarExpand = document . querySelector ( SELECTOR_SIDEBAR_EXPAND )
162180
163181 if ( ! sidebarExpand ) {
164182 return
165183 }
166184
185+ // Read the content property of the ::before pseudo element to get the
186+ // breakpoint value.
187+
167188 const content = globalThis . getComputedStyle ( sidebarExpand , '::before' )
168189 . getPropertyValue ( 'content' )
169190
191+ // Update the config.sidebarBreakpoint value by extracting the numeric
192+ // value from the content string.
193+
170194 if ( ! content || content === 'none' ) {
171195 return
172196 }
@@ -186,10 +210,16 @@ class PushMenu {
186210 */
187211 updateStateByResponsiveLogic ( ) : void {
188212 if ( this . isMobileSize ( ) ) {
213+ // On mobile sizes, keep the sidebar collapsed unless explicitly opened
214+ // by the user to prevent unintended collapse on scroll or resize events.
215+
189216 if ( ! this . isExplicitlyOpen ( ) ) {
190217 this . collapse ( )
191218 }
192219 } else {
220+ // On big screen sizes, keep the sidebar expanded unless in mini mode and
221+ // explicitly collapsed.
222+
193223 if ( ! ( this . isMiniMode ( ) && this . isCollapsed ( ) ) ) {
194224 this . expand ( )
195225 }
@@ -202,25 +232,34 @@ class PushMenu {
202232 * @param state The state to save ('sidebar-open' or 'sidebar-collapse').
203233 */
204234 saveSidebarState ( state : string ) : void {
235+ // Check for localStorage availability (not a SSR environment).
236+
205237 if ( globalThis . localStorage === undefined ) {
206238 return
207239 }
208240
241+ // Save the sidebar state to local storage.
242+
209243 try {
210244 localStorage . setItem ( STORAGE_KEY_SIDEBAR_STATE , state )
211245 } catch {
212- // localStorage may be unavailable (private browsing, quota exceeded, etc.)
246+ // The localStorage may be unavailable (private browsing, quota exceeded,
247+ // etc.). Fail silently in these cases.
213248 }
214249 }
215250
216251 /**
217252 * Load sidebar state from localStorage.
218253 */
219254 loadSidebarState ( ) : void {
255+ // Check for localStorage availability (not a SSR environment).
256+
220257 if ( globalThis . localStorage === undefined ) {
221258 return
222259 }
223260
261+ // Load the sidebar state from local storage.
262+
224263 try {
225264 const storedState = localStorage . getItem ( STORAGE_KEY_SIDEBAR_STATE )
226265
@@ -229,9 +268,11 @@ class PushMenu {
229268 } else if ( storedState === CLASS_NAME_SIDEBAR_OPEN ) {
230269 this . expand ( )
231270 } else {
271+ // If null (never saved), let the responsive logic apply.
232272 this . updateStateByResponsiveLogic ( )
233273 }
234274 } catch {
275+ // The localStorage may be unavailable. Let the responsive logic apply.
235276 this . updateStateByResponsiveLogic ( )
236277 }
237278 }
@@ -240,27 +281,42 @@ class PushMenu {
240281 * Clear sidebar state from localStorage.
241282 */
242283 clearSidebarState ( ) : void {
284+ // Check for localStorage availability (not a SSR environment).
285+
243286 if ( globalThis . localStorage === undefined ) {
244287 return
245288 }
246289
290+ // Clear the sidebar state from local storage.
291+
247292 try {
248293 localStorage . removeItem ( STORAGE_KEY_SIDEBAR_STATE )
249294 } catch {
250- // localStorage may be unavailable
295+ // The localStorage may be unavailable. Fail silently in these cases.
251296 }
252297 }
253298
254299 /**
255300 * Initialize the push menu plugin and setup the initial sidebar state.
256301 */
257302 init ( ) : void {
303+ // Read and setup the sidebar breakpoint from the DOM. This breakpoint is
304+ // used to determine when the sidebar should be considered "mobile" vs
305+ // "desktop".
306+
258307 this . setupSidebarBreakPoint ( )
259308
309+ // When persistence is not enabled, clear any saved state, just for safety.
310+
260311 if ( ! this . _config . enablePersistence ) {
261312 this . clearSidebarState ( )
262313 }
263314
315+ // When persistence is enabled and screen size is above the breakpoint, load
316+ // the saved sidebar state from local storage. Otherwise, use responsive
317+ // logic to set the initial state. On low screen sizes, the sidebar should
318+ // always be collapsed by default unless explicitly opened.
319+
264320 if ( this . _config . enablePersistence && ! this . isMobileSize ( ) ) {
265321 this . loadSidebarState ( )
266322 } else {
@@ -276,13 +332,16 @@ class PushMenu {
276332 */
277333
278334onDOMContentLoaded ( ( ) => {
335+ // Find the sidebar element in the DOM.
336+
279337 const sidebar = document ?. querySelector ( SELECTOR_APP_SIDEBAR ) as HTMLElement | undefined
280338
281339 if ( ! sidebar ) {
282340 return
283341 }
284342
285- // Read config from data attributes on the sidebar element.
343+ // Read config from data attributes on the sidebar element, falling back to
344+ // Defaults if not present.
286345
287346 const sidebarBreakpointAttr = sidebar . dataset . sidebarBreakpoint
288347 const enablePersistenceAttr = sidebar . dataset . enablePersistence
@@ -314,7 +373,9 @@ onDOMContentLoaded(() => {
314373 sidebarOverlay . className = CLASS_NAME_SIDEBAR_OVERLAY
315374 document . querySelector ( SELECTOR_APP_WRAPPER ) ?. append ( sidebarOverlay )
316375
317- // Handle touch events on overlay.
376+ // Handle touch events on overlay (area outside sidebar), usually we want to
377+ // close the sidebar when the user taps outside the sidebar on mobile
378+ // devices.
318379
319380 let overlayTouchMoved = false
320381
0 commit comments