@mbao01/common 0.0.48 → 0.0.49

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 (62) hide show
  1. package/dist/types/components/Command/Command.d.ts +6 -6
  2. package/dist/types/components/Form/MultiSelect/MultiSelect.d.ts +2 -2
  3. package/dist/types/components/Sidebar/Sidebar.d.ts +39 -0
  4. package/dist/types/components/Sidebar/SidebarContext.d.ts +2 -0
  5. package/dist/types/components/Sidebar/SidebarGroup.d.ts +13 -0
  6. package/dist/types/components/Sidebar/SidebarMenu.d.ts +30 -0
  7. package/dist/types/components/Sidebar/constants.d.ts +48 -0
  8. package/dist/types/components/Sidebar/hooks/index.d.ts +1 -0
  9. package/dist/types/components/Sidebar/hooks/useSidebar/index.d.ts +1 -0
  10. package/dist/types/components/Sidebar/hooks/useSidebar/useSidebar.d.ts +1 -0
  11. package/dist/types/components/Sidebar/index.d.ts +4 -0
  12. package/dist/types/components/Sidebar/stories/examples/Sidebar.example.d.ts +57 -0
  13. package/dist/types/components/Sidebar/stories/examples/components/AppMain.d.ts +3 -0
  14. package/dist/types/components/Sidebar/stories/examples/components/AppSidebar.d.ts +6 -0
  15. package/dist/types/components/Sidebar/stories/examples/components/SearchForm.d.ts +1 -0
  16. package/dist/types/components/Sidebar/stories/examples/components/VersionSwitcher.d.ts +4 -0
  17. package/dist/types/components/Sidebar/types.d.ts +55 -0
  18. package/dist/types/hooks/index.d.ts +1 -0
  19. package/dist/types/hooks/useIsMobile/index.d.ts +1 -0
  20. package/dist/types/hooks/useIsMobile/useIsMobile.d.ts +1 -0
  21. package/dist/types/index.d.ts +2 -0
  22. package/package.json +3 -3
  23. package/src/components/Anchor/Anchor.tsx +2 -2
  24. package/src/components/Calendar/Calendar.tsx +1 -1
  25. package/src/components/Carousel/Carousel.tsx +1 -1
  26. package/src/components/Chart/stories/examples/LineChart.tsx +2 -2
  27. package/src/components/Combobox/Combobox.tsx +2 -2
  28. package/src/components/Command/Command.tsx +2 -2
  29. package/src/components/DatePicker/DatePicker.tsx +2 -2
  30. package/src/components/DatePicker/DateRangePicker.tsx +2 -2
  31. package/src/components/DatePicker/MultipleDatesPicker.tsx +2 -2
  32. package/src/components/Dialog/Dialog.tsx +2 -2
  33. package/src/components/FileUploader/FileUploader.tsx +2 -2
  34. package/src/components/Form/DatetimeInput/DatetimeCalendar.tsx +2 -2
  35. package/src/components/Form/MultiSelect/MultiSelect.tsx +2 -2
  36. package/src/components/Form/Select/Select.tsx +1 -1
  37. package/src/components/Form/TagsInput/TagsInput.tsx +2 -2
  38. package/src/components/Menu/ContextMenu/ContextMenu.tsx +2 -2
  39. package/src/components/Menu/DropdownMenu/DropdownMenu.tsx +2 -2
  40. package/src/components/Menu/Menubar/Menubar.tsx +2 -2
  41. package/src/components/Menu/NavigationMenu/NavigationMenu.tsx +1 -1
  42. package/src/components/Pagination/Pagination.tsx +2 -2
  43. package/src/components/Sidebar/Sidebar.tsx +326 -0
  44. package/src/components/Sidebar/SidebarContext.tsx +6 -0
  45. package/src/components/Sidebar/SidebarGroup.tsx +72 -0
  46. package/src/components/Sidebar/SidebarMenu.tsx +205 -0
  47. package/src/components/Sidebar/constants.ts +206 -0
  48. package/src/components/Sidebar/hooks/index.ts +1 -0
  49. package/src/components/Sidebar/hooks/useSidebar/index.ts +1 -0
  50. package/src/components/Sidebar/hooks/useSidebar/useSidebar.ts +11 -0
  51. package/src/components/Sidebar/index.ts +4 -0
  52. package/src/components/Sidebar/stories/examples/Sidebar.example.tsx +155 -0
  53. package/src/components/Sidebar/stories/examples/components/AppMain.tsx +36 -0
  54. package/src/components/Sidebar/stories/examples/components/AppSidebar.tsx +531 -0
  55. package/src/components/Sidebar/stories/examples/components/SearchForm.tsx +26 -0
  56. package/src/components/Sidebar/stories/examples/components/VersionSwitcher.tsx +45 -0
  57. package/src/components/Sidebar/types.ts +74 -0
  58. package/src/components/Widget/Widgets.example.tsx +2 -2
  59. package/src/hooks/index.ts +1 -0
  60. package/src/hooks/useIsMobile/index.ts +1 -0
  61. package/src/hooks/useIsMobile/useIsMobile.ts +19 -0
  62. package/src/index.ts +3 -0
@@ -2,8 +2,8 @@
2
2
 
3
3
  import type { ComponentRef, KeyboardEvent, MouseEvent, SyntheticEvent } from "react";
4
4
  import { forwardRef, useCallback, useRef, useState } from "react";
5
- import { CheckIcon, Cross2Icon } from "@radix-ui/react-icons";
6
5
  import { Command as CommandPrimitive } from "cmdk";
6
+ import { CheckIcon, XIcon } from "lucide-react";
7
7
  import type {
8
8
  Item,
9
9
  MultiSelectContentProps,
@@ -235,7 +235,7 @@ export const MultiSelectTrigger = ({
235
235
  disabled={disabled}
236
236
  >
237
237
  <span className="sr-only">Remove {label} option</span>
238
- <Cross2Icon className="h-4 w-4 hover:stroke-destructive" />
238
+ <XIcon className="h-4 w-4 hover:stroke-destructive" />
239
239
  </button>
240
240
  </Badge>
241
241
  );
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
 
3
3
  import * as React from "react";
4
- import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "@radix-ui/react-icons";
5
4
  import * as SelectPrimitive from "@radix-ui/react-select";
5
+ import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
6
6
  import type { SelectContentProps, SelectItemProps, SelectTriggerProps } from "./types";
7
7
  import { cn } from "../../../utilities";
8
8
  import {
@@ -2,7 +2,7 @@
2
2
 
3
3
  import type { ChangeEvent, ClipboardEvent, KeyboardEvent, MouseEvent, SyntheticEvent } from "react";
4
4
  import { forwardRef, useCallback, useEffect, useRef, useState } from "react";
5
- import { Cross2Icon } from "@radix-ui/react-icons";
5
+ import { XIcon } from "lucide-react";
6
6
  import type { TagsInputProps } from "./types";
7
7
  import { cn } from "../../../utilities";
8
8
  import { Badge } from "../../Badge";
@@ -250,7 +250,7 @@ export const TagsInput = forwardRef<HTMLDivElement, TagsInputProps>(
250
250
  className={cn(getTagDeleteClasses())}
251
251
  >
252
252
  <span className="sr-only">Remove {tag} option</span>
253
- <Cross2Icon className="h-4 w-4" />
253
+ <XIcon className="h-4 w-4" />
254
254
  </button>
255
255
  </Badge>
256
256
  ))}
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { forwardRef } from "react";
4
4
  import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
5
- import { CheckIcon, ChevronRightIcon, DotFilledIcon } from "@radix-ui/react-icons";
5
+ import { CheckIcon, ChevronRightIcon, DotIcon } from "lucide-react";
6
6
  import type {
7
7
  ContextMenuCheckboxItemProps,
8
8
  ContextMenuContentProps,
@@ -113,7 +113,7 @@ const ContextMenuRadioItem = forwardRef<
113
113
  >
114
114
  <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
115
115
  <ContextMenuPrimitive.ItemIndicator>
116
- <DotFilledIcon className="h-4 w-4 fill-current" />
116
+ <DotIcon className="h-4 w-4 fill-current" />
117
117
  </ContextMenuPrimitive.ItemIndicator>
118
118
  </span>
119
119
  {children}
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { forwardRef } from "react";
4
4
  import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
5
- import { CheckIcon, ChevronRightIcon, DotFilledIcon } from "@radix-ui/react-icons";
5
+ import { CheckIcon, ChevronRightIcon, DotIcon } from "lucide-react";
6
6
  import type {
7
7
  DropdownMenuCheckboxItemProps,
8
8
  DropdownMenuContentProps,
@@ -114,7 +114,7 @@ const DropdownMenuRadioItem = forwardRef<
114
114
  >
115
115
  <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
116
116
  <DropdownMenuPrimitive.ItemIndicator>
117
- <DotFilledIcon className="h-4 w-4 fill-current" />
117
+ <DotIcon className="h-4 w-4 fill-current" />
118
118
  </DropdownMenuPrimitive.ItemIndicator>
119
119
  </span>
120
120
  {children}
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
 
3
3
  import { forwardRef } from "react";
4
- import { CheckIcon, ChevronRightIcon, DotFilledIcon } from "@radix-ui/react-icons";
5
4
  import * as MenubarPrimitive from "@radix-ui/react-menubar";
5
+ import { CheckIcon, ChevronRightIcon, DotIcon } from "lucide-react";
6
6
  import type {
7
7
  MenubarCheckboxItemProps,
8
8
  MenubarContentProps,
@@ -137,7 +137,7 @@ const MenubarRadioItem = forwardRef<
137
137
  >
138
138
  <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
139
139
  <MenubarPrimitive.ItemIndicator>
140
- <DotFilledIcon className="h-4 w-4 fill-current" />
140
+ <DotIcon className="h-4 w-4 fill-current" />
141
141
  </MenubarPrimitive.ItemIndicator>
142
142
  </span>
143
143
  {children}
@@ -1,6 +1,6 @@
1
1
  import { forwardRef } from "react";
2
- import { ChevronDownIcon } from "@radix-ui/react-icons";
3
2
  import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu";
3
+ import { ChevronDownIcon } from "lucide-react";
4
4
  import type {
5
5
  NavigationMenuContentProps,
6
6
  NavigationMenuIndicatorProps,
@@ -1,5 +1,5 @@
1
1
  import { forwardRef } from "react";
2
- import { ChevronLeftIcon, ChevronRightIcon, DotsHorizontalIcon } from "@radix-ui/react-icons";
2
+ import { ChevronLeftIcon, ChevronRightIcon, EllipsisIcon } from "lucide-react";
3
3
  import type { PaginationProps } from "./types";
4
4
  import { cn } from "../../utilities";
5
5
  import { getButtonClasses } from "../Button/constants";
@@ -92,7 +92,7 @@ PaginationNext.displayName = "PaginationNext";
92
92
 
93
93
  const PaginationEllipsis = ({ className, ...props }: PaginationEllipsisProps) => (
94
94
  <span aria-hidden className={cn(getPaginationEllipsisClasses(), className)} {...props}>
95
- <DotsHorizontalIcon className="h-4 w-4" />
95
+ <EllipsisIcon className="h-4 w-4" />
96
96
  <span className="sr-only">More pages</span>
97
97
  </span>
98
98
  );
@@ -0,0 +1,326 @@
1
+ "use client";
2
+
3
+ import type { ComponentProps, CSSProperties, ElementRef, HTMLAttributes, MouseEvent } from "react";
4
+ import { forwardRef, useCallback, useEffect, useMemo, useState } from "react";
5
+ import { PanelLeftIcon } from "lucide-react";
6
+ import type { ButtonProps } from "../Button/types";
7
+ import type { InputProps } from "../Form/Input/types";
8
+ import type { SeparatorProps } from "../Separator/types";
9
+ import type { SidebarContextProps, SidebarProps, SidebarProviderProps } from "./types";
10
+ import { useIsMobile } from "../../hooks";
11
+ import { cn } from "../../utilities";
12
+ import { Button } from "../Button";
13
+ import { Dialog } from "../Dialog";
14
+ import { Input } from "../Form";
15
+ import { Separator } from "../Separator";
16
+ import { Tooltip } from "../Tooltip";
17
+ import {
18
+ getSidebarClasses,
19
+ getSidebarContentClasses,
20
+ getSidebarFooterClasses,
21
+ getSidebarGapClasses,
22
+ getSidebarHeaderClasses,
23
+ getSidebarInnerClasses,
24
+ getSidebarInputClasses,
25
+ getSidebarInsetClasses,
26
+ getSidebarMobileClasses,
27
+ getSidebarOuterClasses,
28
+ getSidebarProviderClasses,
29
+ getSidebarRailClasses,
30
+ getSidebarSeparatorClasses,
31
+ getSidebarTriggerClasses,
32
+ SIDEBAR_COOKIE_MAX_AGE,
33
+ SIDEBAR_COOKIE_NAME,
34
+ SIDEBAR_KEYBOARD_SHORTCUT,
35
+ SIDEBAR_WIDTH,
36
+ SIDEBAR_WIDTH_ICON,
37
+ SIDEBAR_WIDTH_MOBILE,
38
+ } from "./constants";
39
+ import { useSidebar } from "./hooks";
40
+ import { SidebarContext } from "./SidebarContext";
41
+
42
+ const Sidebar = ({
43
+ side = "left",
44
+ variant = "sidebar",
45
+ collapsible = "offcanvas",
46
+ className,
47
+ children,
48
+ ...props
49
+ }: SidebarProps) => {
50
+ const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
51
+
52
+ if (collapsible === "none") {
53
+ return (
54
+ <div className={cn(getSidebarClasses({ collapsible }), className)} {...props}>
55
+ {children}
56
+ </div>
57
+ );
58
+ }
59
+
60
+ if (isMobile) {
61
+ return (
62
+ <Dialog open={openMobile} onOpenChange={setOpenMobile} {...props}>
63
+ <Dialog.Content
64
+ side={side}
65
+ variant="sheet"
66
+ data-mobile="true"
67
+ data-sidebar="sidebar"
68
+ className={cn(getSidebarMobileClasses({ isMobile }), className)}
69
+ style={
70
+ {
71
+ "--sidebar-width": SIDEBAR_WIDTH_MOBILE,
72
+ } as CSSProperties
73
+ }
74
+ >
75
+ <div className="flex h-full w-full flex-col">{children}</div>
76
+ </Dialog.Content>
77
+ </Dialog>
78
+ );
79
+ }
80
+
81
+ return (
82
+ <div
83
+ data-side={side}
84
+ data-state={state}
85
+ data-collapsible={state === "collapsed" ? collapsible : ""}
86
+ data-variant={variant}
87
+ className={getSidebarOuterClasses()}
88
+ >
89
+ {/* This is what handles the sidebar gap on desktop */}
90
+ <div className={getSidebarGapClasses({ variant })} />
91
+ <div className={getSidebarInnerClasses({ side, variant })} {...props}>
92
+ <div
93
+ data-sidebar="sidebar"
94
+ className={cn(getSidebarMobileClasses({ isMobile }), className)}
95
+ >
96
+ {children}
97
+ </div>
98
+ </div>
99
+ </div>
100
+ );
101
+ };
102
+ Sidebar.displayName = "Sidebar";
103
+
104
+ const SidebarTrigger = forwardRef<ElementRef<typeof Button>, ButtonProps>(
105
+ ({ className, onClick, ...props }, ref) => {
106
+ const { toggleSidebar } = useSidebar();
107
+
108
+ return (
109
+ <Button
110
+ ref={ref}
111
+ variant="ghost"
112
+ data-sidebar="trigger"
113
+ className={cn(getSidebarTriggerClasses(), className)}
114
+ onClick={(event: MouseEvent<HTMLButtonElement>) => {
115
+ onClick?.(event);
116
+ toggleSidebar();
117
+ }}
118
+ {...props}
119
+ >
120
+ <PanelLeftIcon className="w-4 h-4" />
121
+ <span className="sr-only">Toggle Sidebar</span>
122
+ </Button>
123
+ );
124
+ }
125
+ );
126
+ SidebarTrigger.displayName = "SidebarTrigger";
127
+
128
+ const SidebarRail = forwardRef<HTMLButtonElement, ComponentProps<"button">>(
129
+ ({ className, ...props }, ref) => {
130
+ const { toggleSidebar } = useSidebar();
131
+
132
+ return (
133
+ <button
134
+ ref={ref}
135
+ data-sidebar="rail"
136
+ aria-label="Toggle Sidebar"
137
+ tabIndex={-1}
138
+ onClick={toggleSidebar}
139
+ title="Toggle Sidebar"
140
+ className={cn(getSidebarRailClasses(), className)}
141
+ {...props}
142
+ />
143
+ );
144
+ }
145
+ );
146
+ SidebarRail.displayName = "SidebarRail";
147
+
148
+ const SidebarInset = forwardRef<HTMLDivElement, ComponentProps<"main">>(
149
+ ({ className, ...props }, ref) => {
150
+ return <main ref={ref} className={cn(getSidebarInsetClasses(), className)} {...props} />;
151
+ }
152
+ );
153
+ SidebarInset.displayName = "SidebarInset";
154
+
155
+ const SidebarInput = forwardRef<ElementRef<typeof Input>, InputProps>(
156
+ ({ className, ...props }, ref) => {
157
+ return (
158
+ <Input
159
+ ref={ref}
160
+ data-sidebar="input"
161
+ className={cn(getSidebarInputClasses(), className)}
162
+ {...props}
163
+ />
164
+ );
165
+ }
166
+ );
167
+ SidebarInput.displayName = "SidebarInput";
168
+
169
+ const SidebarHeader = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(
170
+ ({ className, ...props }, ref) => {
171
+ return (
172
+ <div
173
+ ref={ref}
174
+ data-sidebar="header"
175
+ className={cn(getSidebarHeaderClasses(), className)}
176
+ {...props}
177
+ />
178
+ );
179
+ }
180
+ );
181
+ SidebarHeader.displayName = "SidebarHeader";
182
+
183
+ const SidebarFooter = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(
184
+ ({ className, ...props }, ref) => {
185
+ return (
186
+ <div
187
+ ref={ref}
188
+ data-sidebar="footer"
189
+ className={cn(getSidebarFooterClasses(), className)}
190
+ {...props}
191
+ />
192
+ );
193
+ }
194
+ );
195
+ SidebarFooter.displayName = "SidebarFooter";
196
+
197
+ const SidebarSeparator = ({ className, ...props }: SeparatorProps) => {
198
+ return (
199
+ <Separator
200
+ data-sidebar="separator"
201
+ className={cn(getSidebarSeparatorClasses(), className)}
202
+ {...props}
203
+ />
204
+ );
205
+ };
206
+ SidebarSeparator.displayName = "SidebarSeparator";
207
+
208
+ const SidebarContent = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(
209
+ ({ className, ...props }, ref) => {
210
+ return (
211
+ <div
212
+ ref={ref}
213
+ data-sidebar="content"
214
+ className={cn(getSidebarContentClasses(), className)}
215
+ {...props}
216
+ />
217
+ );
218
+ }
219
+ );
220
+ SidebarContent.displayName = "SidebarContent";
221
+
222
+ const SidebarProvider = forwardRef<HTMLDivElement, SidebarProviderProps>(
223
+ (
224
+ {
225
+ defaultOpen = true,
226
+ open: openProp,
227
+ onOpenChange: setOpenProp,
228
+ className,
229
+ style,
230
+ children,
231
+ tooltipProvider,
232
+ ...props
233
+ },
234
+ ref
235
+ ) => {
236
+ const isMobile = useIsMobile();
237
+ const [openMobile, setOpenMobile] = useState(false);
238
+
239
+ // This is the internal state of the sidebar.
240
+ // We use openProp and setOpenProp for control from outside the component.
241
+ const [_open, _setOpen] = useState(defaultOpen);
242
+ const open = openProp ?? _open;
243
+ const setOpen = useCallback(
244
+ (value: boolean | ((value: boolean) => boolean)) => {
245
+ if (setOpenProp) {
246
+ return setOpenProp?.(typeof value === "function" ? value(open) : value);
247
+ }
248
+
249
+ _setOpen(value);
250
+
251
+ // This sets the cookie to keep the sidebar state.
252
+ document.cookie = `${SIDEBAR_COOKIE_NAME}=${open}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
253
+ },
254
+ [setOpenProp, open]
255
+ );
256
+
257
+ // Helper to toggle the sidebar.
258
+ const toggleSidebar = useCallback(() => {
259
+ return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open);
260
+ }, [isMobile, setOpen, setOpenMobile]);
261
+
262
+ // Adds a keyboard shortcut to toggle the sidebar.
263
+ useEffect(() => {
264
+ const handleKeyDown = (event: KeyboardEvent) => {
265
+ if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
266
+ event.preventDefault();
267
+ toggleSidebar();
268
+ }
269
+ };
270
+
271
+ window.addEventListener("keydown", handleKeyDown);
272
+ return () => window.removeEventListener("keydown", handleKeyDown);
273
+ }, [toggleSidebar]);
274
+
275
+ // We add a state so that we can do data-state="expanded" or "collapsed".
276
+ // This makes it easier to style the sidebar with Tailwind classes.
277
+ const state = open ? "expanded" : "collapsed";
278
+
279
+ const contextValue = useMemo<SidebarContextProps>(
280
+ () => ({
281
+ state,
282
+ open,
283
+ setOpen,
284
+ isMobile,
285
+ openMobile,
286
+ setOpenMobile,
287
+ toggleSidebar,
288
+ }),
289
+ [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
290
+ );
291
+
292
+ return (
293
+ <SidebarContext.Provider value={contextValue}>
294
+ <Tooltip.Provider delayDuration={0} {...tooltipProvider}>
295
+ <div
296
+ style={
297
+ {
298
+ "--sidebar-width": SIDEBAR_WIDTH,
299
+ "--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
300
+ ...style,
301
+ } as CSSProperties
302
+ }
303
+ className={cn(getSidebarProviderClasses(), className)}
304
+ ref={ref}
305
+ {...props}
306
+ >
307
+ {children}
308
+ </div>
309
+ </Tooltip.Provider>
310
+ </SidebarContext.Provider>
311
+ );
312
+ }
313
+ );
314
+ SidebarProvider.displayName = "SidebarProvider";
315
+
316
+ Sidebar.Content = SidebarContent;
317
+ Sidebar.Footer = SidebarFooter;
318
+ Sidebar.Header = SidebarHeader;
319
+ Sidebar.Input = SidebarInput;
320
+ Sidebar.Inset = SidebarInset;
321
+ Sidebar.Provider = SidebarProvider;
322
+ Sidebar.Rail = SidebarRail;
323
+ Sidebar.Separator = SidebarSeparator;
324
+ Sidebar.Trigger = SidebarTrigger;
325
+
326
+ export { Sidebar };
@@ -0,0 +1,6 @@
1
+ "use client";
2
+
3
+ import { createContext } from "react";
4
+ import { type SidebarContextProps } from "./types";
5
+
6
+ export const SidebarContext = createContext<SidebarContextProps | null>(null);
@@ -0,0 +1,72 @@
1
+ import { forwardRef } from "react";
2
+ import { Slot } from "@radix-ui/react-slot";
3
+ import type {
4
+ SidebarGroupActionProps,
5
+ SidebarGroupContentProps,
6
+ SidebarGroupLabelProps,
7
+ SidebarGroupProps,
8
+ } from "./types";
9
+ import { cn } from "../../utilities";
10
+ import {
11
+ getSidebarGroupActionClasses,
12
+ getSidebarGroupClasses,
13
+ getSidebarGroupContentClasses,
14
+ getSidebarGroupLabelClasses,
15
+ } from "./constants";
16
+
17
+ const SidebarGroup = ({ className, ...props }: SidebarGroupProps) => {
18
+ return (
19
+ <div data-sidebar="group" className={cn(getSidebarGroupClasses(), className)} {...props} />
20
+ );
21
+ };
22
+ SidebarGroup.displayName = "SidebarGroup";
23
+
24
+ const SidebarGroupLabel = forwardRef<HTMLDivElement, SidebarGroupLabelProps>(
25
+ ({ className, asChild = false, ...props }, ref) => {
26
+ const Comp = asChild ? Slot : "div";
27
+
28
+ return (
29
+ <Comp
30
+ ref={ref}
31
+ data-sidebar="group-label"
32
+ className={cn(getSidebarGroupLabelClasses(), className)}
33
+ {...props}
34
+ />
35
+ );
36
+ }
37
+ );
38
+ SidebarGroupLabel.displayName = "SidebarGroupLabel";
39
+
40
+ const SidebarGroupAction = forwardRef<HTMLButtonElement, SidebarGroupActionProps>(
41
+ ({ className, asChild = false, ...props }, ref) => {
42
+ const Comp = asChild ? Slot : "button";
43
+
44
+ return (
45
+ <Comp
46
+ ref={ref}
47
+ data-sidebar="group-action"
48
+ className={cn(getSidebarGroupActionClasses(), className)}
49
+ {...props}
50
+ />
51
+ );
52
+ }
53
+ );
54
+ SidebarGroupAction.displayName = "SidebarGroupAction";
55
+
56
+ const SidebarGroupContent = forwardRef<HTMLDivElement, SidebarGroupContentProps>(
57
+ ({ className, ...props }, ref) => (
58
+ <div
59
+ ref={ref}
60
+ data-sidebar="group-content"
61
+ className={cn(getSidebarGroupContentClasses(), className)}
62
+ {...props}
63
+ />
64
+ )
65
+ );
66
+ SidebarGroupContent.displayName = "SidebarGroupContent";
67
+
68
+ SidebarGroup.Action = SidebarGroupAction;
69
+ SidebarGroup.Content = SidebarGroupContent;
70
+ SidebarGroup.Label = SidebarGroupLabel;
71
+
72
+ export { SidebarGroup };