@kushagradhawan/kookie-ui 0.1.18 → 0.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/components.css +0 -1417
  2. package/dist/cjs/components/index.d.ts +0 -1
  3. package/dist/cjs/components/index.d.ts.map +1 -1
  4. package/dist/cjs/components/index.js +1 -1
  5. package/dist/cjs/components/index.js.map +3 -3
  6. package/dist/esm/components/index.d.ts +0 -1
  7. package/dist/esm/components/index.d.ts.map +1 -1
  8. package/dist/esm/components/index.js +1 -1
  9. package/dist/esm/components/index.js.map +3 -3
  10. package/package.json +1 -1
  11. package/src/components/index.css +0 -1
  12. package/src/components/index.tsx +1 -1
  13. package/styles.css +0 -1417
  14. package/dist/cjs/components/sidebar.d.ts +0 -157
  15. package/dist/cjs/components/sidebar.d.ts.map +0 -1
  16. package/dist/cjs/components/sidebar.js +0 -2
  17. package/dist/cjs/components/sidebar.js.map +0 -7
  18. package/dist/cjs/components/sidebar.props.d.ts +0 -60
  19. package/dist/cjs/components/sidebar.props.d.ts.map +0 -1
  20. package/dist/cjs/components/sidebar.props.js +0 -2
  21. package/dist/cjs/components/sidebar.props.js.map +0 -7
  22. package/dist/esm/components/sidebar.d.ts +0 -157
  23. package/dist/esm/components/sidebar.d.ts.map +0 -1
  24. package/dist/esm/components/sidebar.js +0 -2
  25. package/dist/esm/components/sidebar.js.map +0 -7
  26. package/dist/esm/components/sidebar.props.d.ts +0 -60
  27. package/dist/esm/components/sidebar.props.d.ts.map +0 -1
  28. package/dist/esm/components/sidebar.props.js +0 -2
  29. package/dist/esm/components/sidebar.props.js.map +0 -7
  30. package/src/components/sidebar.css +0 -1043
  31. package/src/components/sidebar.props.tsx +0 -54
  32. package/src/components/sidebar.tsx +0 -740
@@ -1,740 +0,0 @@
1
- 'use client';
2
-
3
- import * as React from 'react';
4
- import classNames from 'classnames';
5
- import { Slot } from './slot';
6
- import { Accordion } from 'radix-ui';
7
-
8
- import { sidebarPropDefs } from './sidebar.props';
9
- import { Theme, useThemeContext } from './theme';
10
- import { IconButton } from './icon-button';
11
- import { ScrollArea } from './scroll-area.js';
12
- import { Separator } from './separator.js';
13
- import { ChevronDownIcon, ThickChevronRightIcon } from './icons.js';
14
- import { extractProps } from '../helpers/extract-props.js';
15
- import { Kbd } from './kbd.js';
16
- import { Badge } from './badge.js';
17
-
18
- import type { ComponentPropsWithout, RemovedProps } from '../helpers/component-props';
19
- import type { GetPropDefTypes } from '../props/prop-def';
20
- import type { BadgeProps } from './badge.js';
21
-
22
- // Badge configuration type for sidebar menu buttons
23
- type BadgeConfig = {
24
- content: React.ReactNode;
25
- variant?: BadgeProps['variant'];
26
- size?: BadgeProps['size'];
27
- color?: BadgeProps['color'];
28
- highContrast?: BadgeProps['highContrast'];
29
- radius?: BadgeProps['radius'];
30
- };
31
-
32
- // Sidebar context for state management
33
- type SidebarContextProps = {
34
- state: 'expanded' | 'collapsed';
35
- open: boolean;
36
- setOpen: (open: boolean) => void;
37
- openMobile: boolean;
38
- setOpenMobile: (open: boolean) => void;
39
- isMobile: boolean;
40
- toggleSidebar: () => void;
41
- side: 'left' | 'right';
42
- type: 'sidebar' | 'floating';
43
- variant: 'soft' | 'surface' | 'ghost';
44
- menuVariant: 'solid' | 'soft';
45
- collapsible: 'offcanvas' | 'icon' | 'none';
46
- size: '1' | '2';
47
- };
48
-
49
- const SidebarContext = React.createContext<SidebarContextProps | null>(null);
50
-
51
- function useSidebar() {
52
- const context = React.useContext(SidebarContext);
53
- if (!context) {
54
- throw new Error('useSidebar must be used within a SidebarProvider.');
55
- }
56
- return context;
57
- }
58
-
59
- // Hook to detect mobile (simplified version)
60
- function useIsMobile() {
61
- const [isMobile, setIsMobile] = React.useState(false);
62
-
63
- React.useEffect(() => {
64
- const checkIsMobile = () => {
65
- setIsMobile(window.innerWidth < 768);
66
- };
67
-
68
- checkIsMobile();
69
- window.addEventListener('resize', checkIsMobile);
70
- return () => window.removeEventListener('resize', checkIsMobile);
71
- }, []);
72
-
73
- return isMobile;
74
- }
75
-
76
- // Provider component
77
- interface SidebarProviderProps extends React.ComponentPropsWithoutRef<'div'> {
78
- defaultOpen?: boolean;
79
- open?: boolean;
80
- onOpenChange?: (open: boolean) => void;
81
- side?: 'left' | 'right';
82
- }
83
-
84
- const SidebarProvider = React.forwardRef<HTMLDivElement, SidebarProviderProps>(
85
- (
86
- {
87
- defaultOpen = true,
88
- open: openProp,
89
- onOpenChange: setOpenProp,
90
- side = 'left',
91
- className,
92
- children,
93
- ...props
94
- },
95
- forwardedRef,
96
- ) => {
97
- const isMobile = useIsMobile();
98
- const [openMobile, setOpenMobile] = React.useState(false);
99
-
100
- // Internal state for uncontrolled mode
101
- const [internalOpen, setInternalOpen] = React.useState(defaultOpen);
102
-
103
- // Use controlled state if provided, otherwise internal state
104
- const open = openProp ?? internalOpen;
105
-
106
- const setOpen = React.useCallback(
107
- (value: boolean | ((value: boolean) => boolean)) => {
108
- const openState = typeof value === 'function' ? value(open) : value;
109
- if (setOpenProp) {
110
- setOpenProp(openState);
111
- } else {
112
- setInternalOpen(openState);
113
- }
114
- },
115
- [setOpenProp, open],
116
- );
117
-
118
- // Helper to toggle the sidebar
119
- const toggleSidebar = React.useCallback(() => {
120
- return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open);
121
- }, [isMobile, setOpen, setOpenMobile]);
122
-
123
- // State for data attributes
124
- const state = open ? 'expanded' : 'collapsed';
125
-
126
- const contextValue = React.useMemo<Partial<SidebarContextProps>>(
127
- () => ({
128
- state,
129
- open,
130
- setOpen,
131
- isMobile,
132
- openMobile,
133
- setOpenMobile,
134
- toggleSidebar,
135
- side,
136
- }),
137
- [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar, side],
138
- );
139
-
140
- return (
141
- <div
142
- {...props}
143
- ref={forwardedRef}
144
- className={classNames('rt-SidebarProvider', className)}
145
- data-state={state}
146
- data-side={side}
147
- >
148
- <SidebarContext.Provider value={contextValue as SidebarContextProps}>
149
- {children}
150
- </SidebarContext.Provider>
151
- </div>
152
- );
153
- },
154
- );
155
- SidebarProvider.displayName = 'Sidebar.Provider';
156
-
157
- // Main Sidebar component
158
- type SidebarOwnProps = GetPropDefTypes<typeof sidebarPropDefs>;
159
- interface SidebarProps extends ComponentPropsWithout<'div', RemovedProps>, SidebarOwnProps {}
160
-
161
- const Sidebar = React.forwardRef<HTMLDivElement, SidebarProps>((props, forwardedRef) => {
162
- const themeContext = useThemeContext();
163
- const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
164
-
165
- const {
166
- size = sidebarPropDefs.size.default,
167
- variant = sidebarPropDefs.variant.default,
168
- menuVariant = sidebarPropDefs.menuVariant.default,
169
- type = sidebarPropDefs.type.default,
170
- side = sidebarPropDefs.side.default,
171
- collapsible = sidebarPropDefs.collapsible.default,
172
- panelBackground,
173
- color,
174
- highContrast = sidebarPropDefs.highContrast.default,
175
- asChild,
176
- } = props;
177
-
178
- const { className, children, ...rootProps } = extractProps(props, sidebarPropDefs);
179
- const { asChild: _, panelBackground: __, ...safeRootProps } = rootProps; // Remove asChild and panelBackground from DOM props
180
- const resolvedColor = color || themeContext.accentColor;
181
-
182
- // Update context with current props - we'll pass the resolved values
183
- const resolvedSize = typeof size === 'object' ? size.initial || '2' : size;
184
- const context = React.useContext(SidebarContext);
185
- if (context) {
186
- context.side = side;
187
- context.type = type;
188
- context.variant = variant;
189
- context.menuVariant = menuVariant;
190
- context.collapsible = collapsible;
191
- context.size = resolvedSize;
192
- }
193
-
194
- if (collapsible === 'none') {
195
- return (
196
- <div
197
- {...safeRootProps}
198
- ref={forwardedRef}
199
- data-accent-color={resolvedColor}
200
- data-state={state}
201
- data-side={side}
202
- data-type={type}
203
- data-collapsible={collapsible}
204
- className={classNames('rt-SidebarRoot', `rt-r-size-${size}`, className)}
205
- >
206
- <Theme>
207
- <div
208
- className={classNames('rt-SidebarContainer', `rt-variant-${variant}`)}
209
- data-accent-color={resolvedColor}
210
- data-high-contrast={highContrast || undefined}
211
- data-side={side}
212
- data-panel-background={panelBackground}
213
- >
214
- {children}
215
- </div>
216
- </Theme>
217
- </div>
218
- );
219
- }
220
-
221
- if (isMobile) {
222
- return (
223
- <div
224
- {...safeRootProps}
225
- ref={forwardedRef}
226
- data-accent-color={resolvedColor}
227
- data-state={openMobile ? 'open' : 'closed'}
228
- data-side={side}
229
- data-type={type}
230
- data-collapsible={collapsible}
231
- className={classNames('rt-SidebarRoot', 'rt-SidebarRoot--mobile', className)}
232
- >
233
- <Theme>
234
- <div
235
- className={classNames(
236
- 'rt-SidebarContainer',
237
- `rt-variant-${variant}`,
238
- `rt-r-size-${size}`,
239
- )}
240
- data-accent-color={resolvedColor}
241
- data-high-contrast={highContrast || undefined}
242
- data-side={side}
243
- data-panel-background={panelBackground}
244
- >
245
- {children}
246
- </div>
247
- </Theme>
248
- </div>
249
- );
250
- }
251
-
252
- return (
253
- <div
254
- {...safeRootProps}
255
- ref={forwardedRef}
256
- data-accent-color={resolvedColor}
257
- data-state={state}
258
- data-side={side}
259
- data-type={type}
260
- data-collapsible={collapsible}
261
- className={classNames('rt-SidebarRoot', className)}
262
- >
263
- <Theme>
264
- <div
265
- className={classNames(
266
- 'rt-SidebarContainer',
267
- `rt-variant-${variant}`,
268
- `rt-r-size-${size}`,
269
- )}
270
- data-accent-color={resolvedColor}
271
- data-high-contrast={highContrast || undefined}
272
- data-side={side}
273
- data-panel-background={panelBackground}
274
- >
275
- {children}
276
- </div>
277
- </Theme>
278
- </div>
279
- );
280
- });
281
- Sidebar.displayName = 'Sidebar.Root';
282
-
283
- // Sidebar content area
284
- interface SidebarContentProps extends React.ComponentPropsWithoutRef<'div'> {}
285
-
286
- const SidebarContent = React.forwardRef<HTMLDivElement, SidebarContentProps>(
287
- ({ className, children, ...props }, forwardedRef) => {
288
- const context = React.useContext(SidebarContext);
289
- const { size = '2', menuVariant = 'soft' } = context || {};
290
-
291
- return (
292
- <ScrollArea type="auto">
293
- <div
294
- {...props}
295
- ref={forwardedRef}
296
- className={classNames(
297
- 'rt-SidebarContent',
298
- `rt-r-size-${size}`,
299
- `rt-menu-variant-${menuVariant}`,
300
- className,
301
- )}
302
- >
303
- {children}
304
- </div>
305
- </ScrollArea>
306
- );
307
- },
308
- );
309
- SidebarContent.displayName = 'Sidebar.Content';
310
-
311
- // Sidebar header
312
- interface SidebarHeaderProps extends React.ComponentPropsWithoutRef<'div'> {
313
- /**
314
- * Whether to use the default flex container layout.
315
- * @default true
316
- */
317
- asContainer?: boolean;
318
- }
319
-
320
- const SidebarHeader = React.forwardRef<HTMLDivElement, SidebarHeaderProps>(
321
- ({ className, asContainer = true, ...props }, forwardedRef) => {
322
- const context = React.useContext(SidebarContext);
323
- const { size = '2', menuVariant = 'soft' } = context || {};
324
-
325
- return (
326
- <div
327
- {...props}
328
- ref={forwardedRef}
329
- className={classNames(
330
- 'rt-SidebarHeader',
331
- `rt-r-size-${size}`,
332
- `rt-menu-variant-${menuVariant}`,
333
- {
334
- 'rt-SidebarHeader--container': asContainer,
335
- },
336
- className,
337
- )}
338
- />
339
- );
340
- },
341
- );
342
- SidebarHeader.displayName = 'Sidebar.Header';
343
-
344
- // Sidebar footer
345
- interface SidebarFooterProps extends React.ComponentPropsWithoutRef<'div'> {
346
- /**
347
- * Whether to use the default flex container layout.
348
- * @default true
349
- */
350
- asContainer?: boolean;
351
- }
352
-
353
- const SidebarFooter = React.forwardRef<HTMLDivElement, SidebarFooterProps>(
354
- ({ className, asContainer = true, ...props }, forwardedRef) => {
355
- const context = React.useContext(SidebarContext);
356
- const { size = '2', menuVariant = 'soft' } = context || {};
357
-
358
- return (
359
- <div
360
- {...props}
361
- ref={forwardedRef}
362
- className={classNames(
363
- 'rt-SidebarFooter',
364
- `rt-r-size-${size}`,
365
- `rt-menu-variant-${menuVariant}`,
366
- {
367
- 'rt-SidebarFooter--container': asContainer,
368
- },
369
- className,
370
- )}
371
- />
372
- );
373
- },
374
- );
375
- SidebarFooter.displayName = 'Sidebar.Footer';
376
-
377
- // Sidebar trigger button
378
- interface SidebarTriggerProps extends ComponentPropsWithout<typeof IconButton, RemovedProps> {}
379
-
380
- const SidebarTrigger = React.forwardRef<React.ElementRef<typeof IconButton>, SidebarTriggerProps>(
381
- ({ onClick, children, ...props }, forwardedRef) => {
382
- const { toggleSidebar } = useSidebar();
383
-
384
- return (
385
- <IconButton
386
- {...props}
387
- ref={forwardedRef}
388
- variant="ghost"
389
- onClick={(event) => {
390
- onClick?.(event);
391
- toggleSidebar();
392
- }}
393
- >
394
- {children || <ChevronDownIcon />}
395
- </IconButton>
396
- );
397
- },
398
- );
399
- SidebarTrigger.displayName = 'Sidebar.Trigger';
400
-
401
- // Removed SidebarInset - not needed
402
-
403
- // Sidebar separator
404
- interface SidebarSeparatorProps extends ComponentPropsWithout<typeof Separator, RemovedProps> {}
405
-
406
- const SidebarSeparator = React.forwardRef<
407
- React.ComponentRef<typeof Separator>,
408
- SidebarSeparatorProps
409
- >(({ className, ...props }, forwardedRef) => (
410
- <Separator
411
- {...props}
412
- ref={forwardedRef}
413
- className={classNames('rt-SidebarSeparator', className)}
414
- />
415
- ));
416
- SidebarSeparator.displayName = 'Sidebar.Separator';
417
-
418
- // Menu components - reusing dropdown menu structure
419
- interface SidebarMenuProps extends React.ComponentPropsWithoutRef<'ul'> {}
420
-
421
- const SidebarMenu = React.forwardRef<HTMLUListElement, SidebarMenuProps>(
422
- ({ className, ...props }, forwardedRef) => (
423
- <ul {...props} ref={forwardedRef} className={classNames('rt-SidebarMenu', className)} />
424
- ),
425
- );
426
- SidebarMenu.displayName = 'Sidebar.Menu';
427
-
428
- interface SidebarMenuItemProps extends React.ComponentPropsWithoutRef<'li'> {}
429
-
430
- const SidebarMenuItem = React.forwardRef<HTMLLIElement, SidebarMenuItemProps>(
431
- ({ className, ...props }, forwardedRef) => (
432
- <li {...props} ref={forwardedRef} className={classNames('rt-SidebarMenuItem', className)} />
433
- ),
434
- );
435
- SidebarMenuItem.displayName = 'Sidebar.MenuItem';
436
-
437
- interface SidebarMenuButtonProps extends React.ComponentPropsWithoutRef<'button'> {
438
- asChild?: boolean;
439
- isActive?: boolean;
440
- shortcut?: React.ReactNode;
441
- badge?: string | BadgeConfig;
442
- }
443
-
444
- const SidebarMenuButton = React.forwardRef<HTMLButtonElement, SidebarMenuButtonProps>(
445
- (
446
- {
447
- asChild = false,
448
- isActive = false,
449
- shortcut,
450
- badge,
451
- className,
452
- children,
453
- onMouseEnter,
454
- onMouseLeave,
455
- ...props
456
- },
457
- forwardedRef,
458
- ) => {
459
- const [isHighlighted, setIsHighlighted] = React.useState(false);
460
- const context = React.useContext(SidebarContext);
461
- const { size: sidebarSize = '2' } = context || {};
462
-
463
- const Comp = asChild ? Slot : 'button';
464
-
465
- return (
466
- <Comp
467
- {...props}
468
- ref={forwardedRef}
469
- className={classNames('rt-reset', 'rt-SidebarMenuButton', className)}
470
- data-active={isActive || undefined}
471
- data-highlighted={isHighlighted || undefined}
472
- onMouseEnter={(event) => {
473
- setIsHighlighted(true);
474
- onMouseEnter?.(event);
475
- }}
476
- onMouseLeave={(event) => {
477
- setIsHighlighted(false);
478
- onMouseLeave?.(event);
479
- }}
480
- >
481
- {asChild ? (
482
- children
483
- ) : (
484
- <>
485
- {children}
486
- {/* Badge with soft variant default and size mapping to sidebar size */}
487
- {badge && (
488
- <div className="rt-SidebarMenuBadge">
489
- {typeof badge === 'string' ? (
490
- <Badge size={sidebarSize} variant="soft">
491
- {badge}
492
- </Badge>
493
- ) : (
494
- <Badge
495
- size={badge.size || sidebarSize}
496
- variant={badge.variant || 'soft'}
497
- color={badge.color}
498
- highContrast={badge.highContrast}
499
- radius={badge.radius}
500
- >
501
- {badge.content}
502
- </Badge>
503
- )}
504
- </div>
505
- )}
506
- {shortcut && (
507
- <div className="rt-BaseMenuShortcut rt-SidebarMenuShortcut">
508
- <Kbd size={sidebarSize}>{shortcut}</Kbd>
509
- </div>
510
- )}
511
- </>
512
- )}
513
- </Comp>
514
- );
515
- },
516
- );
517
- SidebarMenuButton.displayName = 'Sidebar.MenuButton';
518
-
519
- // Sub-menu components using Radix Accordion
520
- interface SidebarMenuSubProps extends React.ComponentPropsWithoutRef<'div'> {
521
- defaultOpen?: boolean;
522
- }
523
-
524
- const SidebarMenuSub = React.forwardRef<HTMLDivElement, SidebarMenuSubProps>(
525
- ({ defaultOpen = false, children, ...props }, forwardedRef) => {
526
- return (
527
- <div {...props} ref={forwardedRef}>
528
- <Accordion.Root type="single" collapsible defaultValue={defaultOpen ? 'item' : undefined}>
529
- <Accordion.Item value="item">{children}</Accordion.Item>
530
- </Accordion.Root>
531
- </div>
532
- );
533
- },
534
- );
535
- SidebarMenuSub.displayName = 'Sidebar.MenuSub';
536
-
537
- interface SidebarMenuSubTriggerProps
538
- extends React.ComponentPropsWithoutRef<typeof Accordion.Trigger> {
539
- asChild?: boolean;
540
- }
541
-
542
- const SidebarMenuSubTrigger = React.forwardRef<
543
- React.ElementRef<typeof Accordion.Trigger>,
544
- SidebarMenuSubTriggerProps
545
- >(
546
- (
547
- { asChild = false, className, children, onMouseEnter, onMouseLeave, ...props },
548
- forwardedRef,
549
- ) => {
550
- const [isHighlighted, setIsHighlighted] = React.useState(false);
551
-
552
- return (
553
- <Accordion.Header asChild>
554
- <div>
555
- <Accordion.Trigger
556
- {...props}
557
- ref={forwardedRef}
558
- asChild={asChild}
559
- className={classNames(
560
- 'rt-reset',
561
- 'rt-SidebarMenuButton',
562
- 'rt-SidebarMenuSubTrigger',
563
- className,
564
- )}
565
- data-highlighted={isHighlighted || undefined}
566
- onMouseEnter={(event) => {
567
- setIsHighlighted(true);
568
- onMouseEnter?.(event);
569
- }}
570
- onMouseLeave={(event) => {
571
- setIsHighlighted(false);
572
- onMouseLeave?.(event);
573
- }}
574
- >
575
- {asChild ? (
576
- children
577
- ) : (
578
- <>
579
- {children}
580
- <ThickChevronRightIcon
581
- className={classNames(
582
- 'rt-BaseMenuSubTriggerIcon',
583
- 'rt-SidebarMenuSubTriggerIcon',
584
- )}
585
- />
586
- </>
587
- )}
588
- </Accordion.Trigger>
589
- </div>
590
- </Accordion.Header>
591
- );
592
- },
593
- );
594
- SidebarMenuSubTrigger.displayName = 'Sidebar.MenuSubTrigger';
595
-
596
- interface SidebarMenuSubContentProps
597
- extends React.ComponentPropsWithoutRef<typeof Accordion.Content> {}
598
-
599
- const SidebarMenuSubContent = React.forwardRef<
600
- React.ElementRef<typeof Accordion.Content>,
601
- SidebarMenuSubContentProps
602
- >(({ className, children, ...props }, forwardedRef) => {
603
- return (
604
- <Accordion.Content
605
- {...props}
606
- ref={forwardedRef}
607
- className={classNames('rt-SidebarMenuSubContent', className)}
608
- >
609
- <div className="rt-SidebarMenuSubList">{children}</div>
610
- </Accordion.Content>
611
- );
612
- });
613
- SidebarMenuSubContent.displayName = 'Sidebar.MenuSubContent';
614
-
615
- // Group components
616
- interface SidebarGroupProps extends React.ComponentPropsWithoutRef<'div'> {}
617
-
618
- const SidebarGroup = React.forwardRef<HTMLDivElement, SidebarGroupProps>(
619
- ({ className, ...props }, forwardedRef) => (
620
- <div {...props} ref={forwardedRef} className={classNames('rt-SidebarGroup', className)} />
621
- ),
622
- );
623
- SidebarGroup.displayName = 'Sidebar.Group';
624
-
625
- interface SidebarGroupLabelProps extends React.ComponentPropsWithoutRef<'div'> {
626
- asChild?: boolean;
627
- }
628
-
629
- const SidebarGroupLabel = React.forwardRef<HTMLDivElement, SidebarGroupLabelProps>(
630
- ({ asChild = false, className, ...props }, forwardedRef) => {
631
- const Comp = asChild ? Slot : 'div';
632
-
633
- return (
634
- <Comp
635
- {...props}
636
- ref={forwardedRef}
637
- className={classNames('rt-SidebarGroupLabel', className)}
638
- />
639
- );
640
- },
641
- );
642
- SidebarGroupLabel.displayName = 'Sidebar.GroupLabel';
643
-
644
- interface SidebarGroupContentProps extends React.ComponentPropsWithoutRef<'div'> {}
645
-
646
- const SidebarGroupContent = React.forwardRef<HTMLDivElement, SidebarGroupContentProps>(
647
- ({ className, ...props }, forwardedRef) => (
648
- <div
649
- {...props}
650
- ref={forwardedRef}
651
- className={classNames('rt-SidebarGroupContent', className)}
652
- />
653
- ),
654
- );
655
- SidebarGroupContent.displayName = 'Sidebar.GroupContent';
656
-
657
- // Export all components following shadcn's pattern
658
- export {
659
- SidebarProvider as Provider,
660
- Sidebar as Root,
661
- SidebarContent as Content,
662
- SidebarHeader as Header,
663
- SidebarFooter as Footer,
664
- SidebarTrigger as Trigger,
665
- SidebarSeparator as Separator,
666
- SidebarMenu as Menu,
667
- SidebarMenuItem as MenuItem,
668
- SidebarMenuButton as MenuButton,
669
- SidebarMenuSub as MenuSub,
670
- SidebarMenuSubTrigger as MenuSubTrigger,
671
- SidebarMenuSubContent as MenuSubContent,
672
- SidebarGroup as Group,
673
- SidebarGroupLabel as GroupLabel,
674
- SidebarGroupContent as GroupContent,
675
- // Export hook
676
- useSidebar,
677
- };
678
-
679
- /**
680
- * Enhanced Sidebar Header and Footer Usage Examples:
681
- *
682
- * 1. Simple default container (backwards compatible):
683
- * <Sidebar.Header>
684
- * <Logo />
685
- * <span>App Name</span>
686
- * </Sidebar.Header>
687
- *
688
- * 2. Custom flex layout:
689
- * <Sidebar.Header className="rt-justify-between rt-gap-3">
690
- * <Logo />
691
- * <Sidebar.MenuButton>
692
- * <SettingsIcon />
693
- * </Sidebar.MenuButton>
694
- * </Sidebar.Header>
695
- *
696
- * 3. Column layout for multiple rows:
697
- * <Sidebar.Header className="rt-flex-col rt-gap-2" asContainer={false}>
698
- * <div className="rt-flex rt-items-center rt-gap-2">
699
- * <Logo />
700
- * <span>App Name</span>
701
- * </div>
702
- * <Sidebar.MenuButton>
703
- * <UserAvatar />
704
- * <span>John Doe</span>
705
- * </Sidebar.MenuButton>
706
- * </Sidebar.Header>
707
- *
708
- * 4. Interactive footer with menu button:
709
- * <Sidebar.Footer>
710
- * <Sidebar.MenuButton>
711
- * <UserIcon />
712
- * <span>Settings</span>
713
- * <ChevronUpIcon />
714
- * </Sidebar.MenuButton>
715
- * </Sidebar.Footer>
716
- *
717
- * 5. Custom footer layout:
718
- * <Sidebar.Footer className="rt-justify-between">
719
- * <span>v1.0.0</span>
720
- * <Sidebar.MenuButton>
721
- * <HelpIcon />
722
- * </Sidebar.MenuButton>
723
- * </Sidebar.Footer>
724
- *
725
- * Available utility classes:
726
- * - Layout: rt-flex-row, rt-flex-col
727
- * - Alignment: rt-items-center, rt-items-start, rt-items-end
728
- * - Justification: rt-justify-between, rt-justify-center, rt-justify-start, rt-justify-end
729
- * - Gap: rt-gap-1, rt-gap-2, rt-gap-3, rt-gap-4
730
- */
731
-
732
- export type {
733
- SidebarProviderProps as ProviderProps,
734
- SidebarProps as RootProps,
735
- SidebarContentProps as ContentProps,
736
- SidebarHeaderProps as HeaderProps,
737
- SidebarFooterProps as FooterProps,
738
- SidebarTriggerProps as TriggerProps,
739
- BadgeConfig,
740
- };