@@ -68,9 +68,22 @@ function SidebarProvider({
6868 const [ openMobile , setOpenMobile ] = React . useState ( false ) ;
6969
7070 // This is the internal state of the sidebar.
71- // We use openProp and setOpenProp for control from outside the component.
7271 const [ _open , _setOpen ] = React . useState ( defaultOpen ) ;
7372 const open = openProp ?? _open ;
73+
74+ // Restore sidebar state from cookie on mount
75+ React . useEffect ( ( ) => {
76+ try {
77+ const cookies = document . cookie . split ( '; ' ) . find ( row => row . startsWith ( SIDEBAR_COOKIE_NAME + '=' ) ) ;
78+ if ( cookies ) {
79+ const savedState = cookies . split ( '=' ) [ 1 ] === 'true' ;
80+ _setOpen ( savedState ) ;
81+ }
82+ } catch {
83+ // Ignore cookie errors
84+ }
85+ } , [ ] ) ;
86+
7487 const setOpen = React . useCallback (
7588 ( value : boolean | ( ( value : boolean ) => boolean ) ) => {
7689 const openState = typeof value === 'function' ? value ( open ) : value ;
@@ -81,7 +94,11 @@ function SidebarProvider({
8194 }
8295
8396 // This sets the cookie to keep the sidebar state.
84- document . cookie = `${ SIDEBAR_COOKIE_NAME } =${ openState } ; path=/; max-age=${ SIDEBAR_COOKIE_MAX_AGE } ` ;
97+ try {
98+ document . cookie = `${ SIDEBAR_COOKIE_NAME } =${ openState } ; path=/; max-age=${ SIDEBAR_COOKIE_MAX_AGE } ` ;
99+ } catch {
100+
101+ }
85102 } ,
86103 [ setOpenProp , open ] ,
87104 ) ;
@@ -107,8 +124,7 @@ function SidebarProvider({
107124 return ( ) => window . removeEventListener ( 'keydown' , handleKeyDown ) ;
108125 } , [ toggleSidebar ] ) ;
109126
110- // We add a state so that we can do data-state="expanded" or "collapsed".
111- // This makes it easier to style the sidebar with Tailwind classes.
127+
112128 const state = open ? 'expanded' : 'collapsed' ;
113129
114130 const contextValue = React . useMemo < SidebarContextProps > (
@@ -231,7 +247,7 @@ function Sidebar({
231247 side === 'left'
232248 ? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'
233249 : 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]' ,
234- // Adjust the padding for floating and inset variants.
250+
235251 variant === 'floating' || variant === 'inset'
236252 ? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]'
237253 : 'group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l' ,
@@ -425,7 +441,7 @@ function SidebarGroupAction({
425441 data-sidebar = "group-action"
426442 className = { cn (
427443 'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0' ,
428- // Increases the hit area of the button on mobile.
444+
429445 'after:absolute after:-inset-2 md:after:hidden' ,
430446 'group-data-[collapsible=icon]:hidden' ,
431447 className ,
@@ -560,7 +576,7 @@ function SidebarMenuAction({
560576 data-sidebar = "menu-action"
561577 className = { cn (
562578 'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0' ,
563- // Increases the hit area of the button on mobile.
579+
564580 'after:absolute after:-inset-2 md:after:hidden' ,
565581 'peer-data-[size=sm]/menu-button:top-1' ,
566582 'peer-data-[size=default]/menu-button:top-1.5' ,
@@ -604,7 +620,7 @@ function SidebarMenuSkeleton({
604620} : React . ComponentProps < 'div' > & {
605621 showIcon ?: boolean ;
606622} ) {
607- // Random width between 50 to 90%.
623+
608624 const width = React . useMemo ( ( ) => {
609625 return `${ Math . floor ( Math . random ( ) * 40 ) + 50 } %` ;
610626 } , [ ] ) ;
0 commit comments