@dust-tt/sparkle 0.5.10 → 0.5.12

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 (86) hide show
  1. package/dist/cjs/index.js +10 -10
  2. package/dist/cjs/index.js.map +4 -4
  3. package/dist/esm/components/AttachmentChip.d.ts +20 -9
  4. package/dist/esm/components/AttachmentChip.d.ts.map +1 -1
  5. package/dist/esm/components/AttachmentChip.js +2 -5
  6. package/dist/esm/components/AttachmentChip.js.map +1 -1
  7. package/dist/esm/components/Avatar.d.ts +2 -3
  8. package/dist/esm/components/Avatar.d.ts.map +1 -1
  9. package/dist/esm/components/Avatar.js +11 -3
  10. package/dist/esm/components/Avatar.js.map +1 -1
  11. package/dist/esm/components/Card.d.ts +1 -1
  12. package/dist/esm/components/Card.d.ts.map +1 -1
  13. package/dist/esm/components/Card.js +2 -1
  14. package/dist/esm/components/Card.js.map +1 -1
  15. package/dist/esm/components/Collapsible.d.ts.map +1 -1
  16. package/dist/esm/components/Collapsible.js +3 -4
  17. package/dist/esm/components/Collapsible.js.map +1 -1
  18. package/dist/esm/components/DataTable.d.ts.map +1 -1
  19. package/dist/esm/components/DataTable.js +1 -1
  20. package/dist/esm/components/DataTable.js.map +1 -1
  21. package/dist/esm/components/NavigationList.d.ts +2 -8
  22. package/dist/esm/components/NavigationList.d.ts.map +1 -1
  23. package/dist/esm/components/NavigationList.js +33 -31
  24. package/dist/esm/components/NavigationList.js.map +1 -1
  25. package/dist/esm/icons/app/Inbox.d.ts +5 -0
  26. package/dist/esm/icons/app/Inbox.d.ts.map +1 -0
  27. package/dist/esm/icons/app/Inbox.js +7 -0
  28. package/dist/esm/icons/app/Inbox.js.map +1 -0
  29. package/dist/esm/icons/app/SpaceClosed.d.ts +5 -0
  30. package/dist/esm/icons/app/SpaceClosed.d.ts.map +1 -0
  31. package/dist/esm/icons/app/SpaceClosed.js +5 -0
  32. package/dist/esm/icons/app/SpaceClosed.js.map +1 -0
  33. package/dist/esm/icons/app/SpaceOpen.d.ts +5 -0
  34. package/dist/esm/icons/app/SpaceOpen.d.ts.map +1 -0
  35. package/dist/esm/icons/app/SpaceOpen.js +5 -0
  36. package/dist/esm/icons/app/SpaceOpen.js.map +1 -0
  37. package/dist/esm/icons/app/Spaces.d.ts +5 -0
  38. package/dist/esm/icons/app/Spaces.d.ts.map +1 -0
  39. package/dist/esm/icons/app/Spaces.js +5 -0
  40. package/dist/esm/icons/app/Spaces.js.map +1 -0
  41. package/dist/esm/icons/app/index.d.ts +4 -0
  42. package/dist/esm/icons/app/index.d.ts.map +1 -1
  43. package/dist/esm/icons/app/index.js +4 -0
  44. package/dist/esm/icons/app/index.js.map +1 -1
  45. package/dist/esm/icons/src/app/inbox.svg +5 -0
  46. package/dist/esm/icons/src/app/space-closed.svg +3 -0
  47. package/dist/esm/icons/src/app/space-open.svg +3 -0
  48. package/dist/esm/icons/src/app/spaces.svg +3 -0
  49. package/dist/esm/lottie/collapseBar.d.ts +21 -21
  50. package/dist/esm/lottie/dragArea.d.ts +24 -24
  51. package/dist/esm/lottie/spinnerDarkLG.d.ts +12 -12
  52. package/dist/esm/lottie/spinnerLightLG.d.ts +12 -12
  53. package/dist/esm/lottie/spinnerLightXS.d.ts +11 -11
  54. package/dist/esm/stories/AttachmentChip.stories.d.ts.map +1 -1
  55. package/dist/esm/stories/AttachmentChip.stories.js +6 -2
  56. package/dist/esm/stories/AttachmentChip.stories.js.map +1 -1
  57. package/dist/esm/stories/Avatar.stories.d.ts +1 -1
  58. package/dist/esm/stories/Avatar.stories.d.ts.map +1 -1
  59. package/dist/esm/stories/Avatar.stories.js +10 -4
  60. package/dist/esm/stories/Avatar.stories.js.map +1 -1
  61. package/dist/esm/stories/Card.stories.d.ts +1 -1
  62. package/dist/esm/stories/NavigationList.stories.d.ts.map +1 -1
  63. package/dist/esm/stories/NavigationList.stories.js +61 -31
  64. package/dist/esm/stories/NavigationList.stories.js.map +1 -1
  65. package/dist/sparkle.css +16 -33
  66. package/package.json +1 -1
  67. package/src/components/AttachmentChip.tsx +22 -18
  68. package/src/components/Avatar.tsx +10 -9
  69. package/src/components/Card.tsx +2 -1
  70. package/src/components/Collapsible.tsx +17 -13
  71. package/src/components/DataTable.tsx +4 -5
  72. package/src/components/NavigationList.tsx +89 -134
  73. package/src/icons/app/Inbox.tsx +17 -0
  74. package/src/icons/app/SpaceClosed.tsx +18 -0
  75. package/src/icons/app/SpaceOpen.tsx +20 -0
  76. package/src/icons/app/Spaces.tsx +20 -0
  77. package/src/icons/app/index.ts +4 -0
  78. package/src/icons/src/app/inbox.svg +5 -0
  79. package/src/icons/src/app/space-closed.svg +3 -0
  80. package/src/icons/src/app/space-open.svg +3 -0
  81. package/src/icons/src/app/spaces.svg +3 -0
  82. package/src/stories/AttachmentChip.stories.tsx +6 -2
  83. package/src/stories/Avatar.stories.tsx +6 -4
  84. package/src/stories/NavigationList.stories.tsx +111 -62
  85. package/dist/esm/icons/src/app/brain copie.svg +0 -3
  86. package/src/icons/src/app/brain copie.svg +0 -3
package/dist/sparkle.css CHANGED
@@ -1037,6 +1037,10 @@ select {
1037
1037
  top: 0.25rem;
1038
1038
  }
1039
1039
 
1040
+ .s-top-1\.5 {
1041
+ top: 0.375rem;
1042
+ }
1043
+
1040
1044
  .s-top-1\/2 {
1041
1045
  top: 50%;
1042
1046
  }
@@ -1481,10 +1485,6 @@ select {
1481
1485
  height: 46%;
1482
1486
  }
1483
1487
 
1484
- .s-h-\[500px\] {
1485
- height: 500px;
1486
- }
1487
-
1488
1488
  .s-h-\[56\%\] {
1489
1489
  height: 56%;
1490
1490
  }
@@ -1509,6 +1509,10 @@ select {
1509
1509
  height: 76%;
1510
1510
  }
1511
1511
 
1512
+ .s-h-\[800px\] {
1513
+ height: 800px;
1514
+ }
1515
+
1512
1516
  .s-h-\[98\%\] {
1513
1517
  height: 98%;
1514
1518
  }
@@ -5737,11 +5741,6 @@ select {
5737
5741
  background-color: rgb(238 238 239 / var(--tw-bg-opacity));
5738
5742
  }
5739
5743
 
5740
- .hover\:s-bg-primary-150:hover {
5741
- --tw-bg-opacity: 1;
5742
- background-color: rgb(223 224 226 / var(--tw-bg-opacity));
5743
- }
5744
-
5745
5744
  .hover\:s-bg-primary-200:hover {
5746
5745
  --tw-bg-opacity: 1;
5747
5746
  background-color: rgb(211 213 217 / var(--tw-bg-opacity));
@@ -5874,6 +5873,10 @@ select {
5874
5873
  text-underline-offset: 2px;
5875
5874
  }
5876
5875
 
5876
+ .hover\:s-opacity-100:hover {
5877
+ opacity: 1;
5878
+ }
5879
+
5877
5880
  .hover\:s-brightness-110:hover {
5878
5881
  --tw-brightness: brightness(1.1);
5879
5882
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
@@ -5988,11 +5991,6 @@ select {
5988
5991
  background-color: rgb(223 224 226 / var(--tw-bg-opacity));
5989
5992
  }
5990
5993
 
5991
- .active\:s-bg-primary-200:active {
5992
- --tw-bg-opacity: 1;
5993
- background-color: rgb(211 213 217 / var(--tw-bg-opacity));
5994
- }
5995
-
5996
5994
  .active\:s-bg-primary-300:active {
5997
5995
  --tw-bg-opacity: 1;
5998
5996
  background-color: rgb(178 182 189 / var(--tw-bg-opacity));
@@ -6173,11 +6171,6 @@ select {
6173
6171
  background-color: transparent;
6174
6172
  }
6175
6173
 
6176
- .disabled\:hover\:s-text-muted-foreground:hover:disabled {
6177
- --tw-text-opacity: 1;
6178
- color: rgb(84 93 108 / var(--tw-text-opacity));
6179
- }
6180
-
6181
6174
  .disabled\:hover\:s-text-primary-400:hover:disabled {
6182
6175
  --tw-text-opacity: 1;
6183
6176
  color: rgb(150 156 165 / var(--tw-text-opacity));
@@ -6206,8 +6199,8 @@ select {
6206
6199
  background-color: rgb(211 213 217 / 0.7);
6207
6200
  }
6208
6201
 
6209
- .s-group\/menu-item:hover .group-hover\/menu-item\:s-pr-8 {
6210
- padding-right: 2rem;
6202
+ .s-group\/menu-item:hover .group-hover\/menu-item\:s-pr-7 {
6203
+ padding-right: 1.75rem;
6211
6204
  }
6212
6205
 
6213
6206
  .s-group\/col:hover .group-hover\/col\:s-text-highlight-500 {
@@ -6530,8 +6523,8 @@ select {
6530
6523
  opacity: 1;
6531
6524
  }
6532
6525
 
6533
- .s-group\/menu-item[data-selected=true] .group-data-\[selected\=true\]\/menu-item\:s-pr-8 {
6534
- padding-right: 2rem;
6526
+ .s-group\/menu-item[data-selected=true] .group-data-\[selected\=true\]\/menu-item\:s-pr-7 {
6527
+ padding-right: 1.75rem;
6535
6528
  }
6536
6529
 
6537
6530
  .s-group\/menu-item[data-selected=true] .group-data-\[selected\=true\]\/menu-item\:s-opacity-100 {
@@ -8616,11 +8609,6 @@ select {
8616
8609
  background-color: rgb(28 34 45 / var(--tw-bg-opacity));
8617
8610
  }
8618
8611
 
8619
- :is(.s-dark .dark\:hover\:s-bg-primary-150-night:hover) {
8620
- --tw-bg-opacity: 1;
8621
- background-color: rgb(28 34 45 / var(--tw-bg-opacity));
8622
- }
8623
-
8624
8612
  :is(.s-dark .dark\:hover\:s-bg-primary-200-night:hover) {
8625
8613
  --tw-bg-opacity: 1;
8626
8614
  background-color: rgb(42 50 65 / var(--tw-bg-opacity));
@@ -8974,11 +8962,6 @@ select {
8974
8962
  background-color: transparent;
8975
8963
  }
8976
8964
 
8977
- :is(.s-dark .dark\:disabled\:hover\:s-text-muted-foreground-night:hover:disabled) {
8978
- --tw-text-opacity: 1;
8979
- color: rgb(150 156 165 / var(--tw-text-opacity));
8980
- }
8981
-
8982
8965
  :is(.s-dark .dark\:disabled\:hover\:s-text-primary-400-night:hover:disabled) {
8983
8966
  --tw-text-opacity: 1;
8984
8967
  color: rgb(84 93 108 / var(--tw-text-opacity));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dust-tt/sparkle",
3
- "version": "0.5.10",
3
+ "version": "0.5.12",
4
4
  "scripts": {
5
5
  "build": "rm -rf dist && npm run tailwind && npm run build:esm && npm run build:cjs",
6
6
  "tailwind": "tailwindcss -i ./src/styles/tailwind.css -o dist/sparkle.css",
@@ -12,38 +12,43 @@ const attachmentChipOverrides = cn(
12
12
  "dark:s-bg-background-night dark:s-text-foreground-night"
13
13
  );
14
14
 
15
- type AttachmentChipIconProps = IconProps | DoubleIconProps;
15
+ export type AttachmentChipIconProps = IconProps;
16
+ export type AttachmentChipDoubleIconProps = DoubleIconProps;
16
17
 
17
- function isDoubleIconProps(
18
- props: AttachmentChipIconProps
19
- ): props is DoubleIconProps {
20
- return "mainIcon" in props;
21
- }
18
+ type AttachmentChipIconOptions =
19
+ | { icon?: AttachmentChipIconProps; doubleIcon?: never }
20
+ | { icon?: never; doubleIcon?: AttachmentChipDoubleIconProps };
22
21
 
23
- interface AttachmentChipBaseProps {
22
+ export type AttachmentChipBaseProps = AttachmentChipIconOptions & {
24
23
  label: string;
25
- icon?: AttachmentChipIconProps;
26
24
  size?: (typeof CHIP_SIZES)[number];
27
25
  color?: (typeof CHIP_COLORS)[number];
28
26
  className?: string;
29
27
  isBusy?: boolean;
30
28
  onRemove?: () => void;
31
- onClick?: () => void;
32
- }
29
+ children?: never;
30
+ };
33
31
 
34
- type AttachmentChipButtonProps = AttachmentChipBaseProps & {
32
+ export type AttachmentChipButtonProps = AttachmentChipBaseProps & {
35
33
  href?: never;
34
+ onClick?: () => void;
36
35
  } & {
37
36
  [K in keyof Omit<LinkWrapperProps, "children">]?: never;
38
37
  };
39
38
 
40
- type AttachmentChipLinkProps = AttachmentChipBaseProps &
41
- Omit<LinkWrapperProps, "children">;
39
+ export type AttachmentChipLinkProps = AttachmentChipBaseProps &
40
+ Omit<LinkWrapperProps, "children" | "href"> & {
41
+ href: string;
42
+ onClick?: never;
43
+ };
42
44
 
43
- type AttachmentChipProps = AttachmentChipButtonProps | AttachmentChipLinkProps;
45
+ export type AttachmentChipProps =
46
+ | AttachmentChipButtonProps
47
+ | AttachmentChipLinkProps;
44
48
 
45
49
  export function AttachmentChip({
46
50
  icon,
51
+ doubleIcon,
47
52
  className,
48
53
  label,
49
54
  size,
@@ -53,14 +58,13 @@ export function AttachmentChip({
53
58
  onClick,
54
59
  ...linkProps
55
60
  }: AttachmentChipProps) {
56
- const iconElement = icon && (
61
+ const chipClassName = cn(attachmentChipOverrides, className);
62
+ const iconElement = (icon || doubleIcon) && (
57
63
  <div className="s-shrink-0">
58
- {isDoubleIconProps(icon) ? <DoubleIcon {...icon} /> : <Icon {...icon} />}
64
+ {doubleIcon ? <DoubleIcon {...doubleIcon} /> : <Icon {...icon} />}
59
65
  </div>
60
66
  );
61
67
 
62
- const chipClassName = cn(attachmentChipOverrides, className);
63
-
64
68
  if ("href" in linkProps && linkProps.href) {
65
69
  return (
66
70
  <Chip
@@ -7,6 +7,7 @@ import { getEmojiAndBackgroundFromUrl } from "@sparkle/lib/avatar/utils";
7
7
  import { cn } from "@sparkle/lib/utils";
8
8
 
9
9
  export const AVATAR_SIZES = [
10
+ "xxs",
10
11
  "xs",
11
12
  "sm",
12
13
  "md",
@@ -25,6 +26,7 @@ const avatarVariants = cva(
25
26
  {
26
27
  variants: {
27
28
  size: {
29
+ xxs: "s-h-5 s-w-5",
28
30
  xs: "s-h-6 s-w-6",
29
31
  sm: "s-h-8 s-w-8",
30
32
  md: "s-h-10 s-w-10",
@@ -45,6 +47,11 @@ const avatarVariants = cva(
45
47
  },
46
48
  },
47
49
  compoundVariants: [
50
+ {
51
+ rounded: false,
52
+ size: "xxs",
53
+ className: "s-rounded",
54
+ },
48
55
  {
49
56
  rounded: false,
50
57
  size: "xs",
@@ -92,6 +99,7 @@ const avatarVariants = cva(
92
99
  const textVariants = cva("s-select-none s-font-semibold", {
93
100
  variants: {
94
101
  size: {
102
+ xxs: "s-text-[10px]",
95
103
  xs: "s-text-xs",
96
104
  sm: "s-text-sm",
97
105
  md: "s-text-base",
@@ -254,7 +262,6 @@ interface AvatarStackProps {
254
262
  avatars: AvatarProps[];
255
263
  nbVisibleItems?: number;
256
264
  size?: AvatarStackSizeType;
257
- isRounded?: boolean;
258
265
  hasMagnifier?: boolean;
259
266
  tooltipTriggerAsChild?: boolean;
260
267
  orientation?: "horizontal" | "vertical";
@@ -270,7 +277,6 @@ Avatar.Stack = function ({
270
277
  avatars,
271
278
  nbVisibleItems,
272
279
  size = "sm",
273
- isRounded = false,
274
280
  hasMagnifier = true,
275
281
  tooltipTriggerAsChild = false,
276
282
  orientation = "horizontal",
@@ -376,14 +382,10 @@ Avatar.Stack = function ({
376
382
  })`,
377
383
  }}
378
384
  >
379
- <Avatar
380
- {...avatarProps}
381
- size={size}
382
- isRounded={isRounded}
383
- />
385
+ <Avatar {...avatarProps} size={size} />
384
386
  </div>
385
387
  ) : (
386
- <Avatar {...avatarProps} size={size} isRounded={isRounded} />
388
+ <Avatar {...avatarProps} size={size} />
387
389
  )}
388
390
  </div>
389
391
  ))}
@@ -407,7 +409,6 @@ Avatar.Stack = function ({
407
409
  "+" +
408
410
  String(Number(remainingCount) < 10 ? remainingCount : "")
409
411
  }
410
- isRounded={isRounded}
411
412
  clickable
412
413
  />
413
414
  </div>
@@ -14,7 +14,7 @@ import { cn } from "@sparkle/lib/utils";
14
14
  export const CARD_VARIANTS = ["primary", "secondary", "tertiary"] as const;
15
15
  export type CardVariantType = (typeof CARD_VARIANTS)[number];
16
16
 
17
- export const CARD_SIZES = ["sm", "md", "lg"] as const;
17
+ export const CARD_SIZES = ["xs", "sm", "md", "lg"] as const;
18
18
  export type CardSizeType = (typeof CARD_SIZES)[number];
19
19
 
20
20
  const interactiveClasses = cn(
@@ -56,6 +56,7 @@ const cardVariants = cva(
56
56
  ),
57
57
  },
58
58
  size: {
59
+ xs: "s-px-2 s-py-1.5 s-rounded-lg",
59
60
  sm: "s-p-3 s-rounded-xl",
60
61
  md: "s-p-4 s-rounded-2xl",
61
62
  lg: "s-p-5 s-rounded-3xl",
@@ -97,21 +97,25 @@ const CollapsibleTrigger = React.forwardRef<
97
97
  )}
98
98
  {...props}
99
99
  >
100
- <span
101
- className={cn(
102
- "s-transition-transform s-duration-200",
103
- chevronVariants({ variant, disabled })
104
- )}
105
- >
106
- <Icon
107
- visual={isOpen ? ChevronDownIcon : ChevronRightIcon}
108
- size="sm"
109
- />
110
- </span>
111
100
  {children ? (
112
101
  children
113
102
  ) : (
114
- <span className={labelVariants({ variant, disabled })}>{label}</span>
103
+ <>
104
+ <span
105
+ className={cn(
106
+ "s-transition-transform s-duration-200",
107
+ chevronVariants({ variant, disabled })
108
+ )}
109
+ >
110
+ <Icon
111
+ visual={isOpen ? ChevronDownIcon : ChevronRightIcon}
112
+ size="sm"
113
+ />
114
+ </span>
115
+ <span className={labelVariants({ variant, disabled })}>
116
+ {label}
117
+ </span>
118
+ </>
115
119
  )}
116
120
  </CollapsiblePrimitive.Trigger>
117
121
  );
@@ -148,7 +152,7 @@ const CollapsibleContent = React.forwardRef<
148
152
  )}
149
153
  {...props}
150
154
  >
151
- <div className="s-py-2">{children}</div>
155
+ {children}
152
156
  </CollapsiblePrimitive.Content>
153
157
  ));
154
158
  CollapsibleContent.displayName = "CollapsibleContent";
@@ -333,9 +333,8 @@ export function DataTable<TData extends TBaseData>({
333
333
  );
334
334
  }
335
335
 
336
- export interface ScrollableDataTableProps<
337
- TData extends TBaseData,
338
- > extends DataTableProps<TData> {
336
+ export interface ScrollableDataTableProps<TData extends TBaseData>
337
+ extends DataTableProps<TData> {
339
338
  maxHeight?: string | boolean;
340
339
  onLoadMore?: () => void;
341
340
  isLoading?: boolean;
@@ -872,7 +871,8 @@ interface BaseMenuItem {
872
871
  }
873
872
 
874
873
  interface RegularMenuItem
875
- extends BaseMenuItem, Omit<DropdownMenuItemProps, "children" | "label"> {
874
+ extends BaseMenuItem,
875
+ Omit<DropdownMenuItemProps, "children" | "label"> {
876
876
  kind: "item";
877
877
  }
878
878
 
@@ -1096,7 +1096,6 @@ DataTable.CellContent = function CellContent({
1096
1096
  avatars={avatarStack.items}
1097
1097
  nbVisibleItems={avatarStack.nbVisibleItems}
1098
1098
  size="xs"
1099
- isRounded={roundedAvatar ?? false}
1100
1099
  />
1101
1100
  )}
1102
1101
  {icon && (
@@ -1,4 +1,3 @@
1
- import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
2
1
  import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
3
2
  import { cva, type VariantProps } from "class-variance-authority";
4
3
  import * as React from "react";
@@ -14,8 +13,9 @@ import { Button } from "@sparkle/components/Button";
14
13
  import {
15
14
  Collapsible,
16
15
  CollapsibleContent,
16
+ CollapsibleTrigger,
17
17
  } from "@sparkle/components/Collapsible";
18
- import { ArrowDownSIcon, ArrowRightSIcon, MoreIcon } from "@sparkle/icons/app";
18
+ import { MoreIcon } from "@sparkle/icons/app";
19
19
  import { cn } from "@sparkle/lib/utils";
20
20
 
21
21
  const NavigationListItemStyles = cva(
@@ -69,12 +69,12 @@ const NavigationList = React.forwardRef<
69
69
  NavigationList.displayName = "NavigationList";
70
70
 
71
71
  interface NavigationListItemProps
72
- extends
73
- React.HTMLAttributes<HTMLDivElement>,
72
+ extends React.HTMLAttributes<HTMLDivElement>,
74
73
  Omit<LinkWrapperProps, "children" | "className"> {
75
74
  selected?: boolean;
76
75
  label?: string;
77
76
  icon?: React.ComponentType;
77
+ avatar?: React.ReactNode;
78
78
  moreMenu?: React.ReactNode;
79
79
  status?: "idle" | "unread" | "blocked";
80
80
  }
@@ -89,6 +89,7 @@ const NavigationListItem = React.forwardRef<
89
89
  selected,
90
90
  label,
91
91
  icon,
92
+ avatar,
92
93
  href,
93
94
  target,
94
95
  rel,
@@ -162,8 +163,9 @@ const NavigationListItem = React.forwardRef<
162
163
  />
163
164
  )}
164
165
  {icon && <Icon visual={icon} size="sm" />}
166
+ {avatar}
165
167
  {label && (
166
- <span className="s-grow s-overflow-hidden s-text-ellipsis s-whitespace-nowrap group-hover/menu-item:s-pr-8 group-data-[selected=true]/menu-item:s-pr-8">
168
+ <span className="s-grow s-overflow-hidden s-text-ellipsis s-whitespace-nowrap group-hover/menu-item:s-pr-7 group-data-[selected=true]/menu-item:s-pr-7">
167
169
  {label}
168
170
  </span>
169
171
  )}
@@ -176,7 +178,8 @@ const NavigationListItem = React.forwardRef<
176
178
  );
177
179
  NavigationListItem.displayName = "NavigationListItem";
178
180
 
179
- interface NavigationListItemActionProps extends React.HTMLAttributes<HTMLDivElement> {
181
+ interface NavigationListItemActionProps
182
+ extends React.HTMLAttributes<HTMLDivElement> {
180
183
  showOnHover?: boolean;
181
184
  }
182
185
 
@@ -189,13 +192,13 @@ const NavigationListItemAction = React.forwardRef<
189
192
  ref={ref}
190
193
  data-sidebar="menu-action"
191
194
  className={cn(
192
- "s-absolute s-right-1.5 s-top-1 s-opacity-0 s-transition-opacity",
195
+ "s-absolute s-right-2 s-top-1.5 s-opacity-0 s-transition-opacity",
193
196
  "s-opacity-0 group-focus-within/menu-item:s-opacity-100 group-hover/menu-item:s-opacity-100 group-data-[selected=true]/menu-item:s-opacity-100",
194
197
  className
195
198
  )}
196
199
  {...props}
197
200
  >
198
- <Button size="mini" icon={MoreIcon} variant="ghost" />
201
+ <Button size="xmini" icon={MoreIcon} variant="ghost" />
199
202
  </div>
200
203
  );
201
204
  });
@@ -224,96 +227,38 @@ const labelStyles = cva(
224
227
  "s-flex s-items-center s-justify-between s-gap-2 s-pt-4 s-pb-2 s-pr-2 s-heading-xs s-whitespace-nowrap s-overflow-hidden s-text-ellipsis"
225
228
  );
226
229
 
227
- interface NavigationListLabelButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
228
- icon?: React.ComponentType;
229
- children?: React.ReactNode;
230
- }
231
-
232
- const NavigationListLabelButton = React.forwardRef<
233
- HTMLButtonElement,
234
- NavigationListLabelButtonProps
235
- >(({ className, icon, children, disabled, ...props }, ref) => {
236
- return (
237
- <button
238
- ref={ref}
239
- type="button"
240
- disabled={disabled}
241
- className={cn(
242
- "s-inline-flex s-flex-shrink-0 s-items-center s-justify-center",
243
- "s-rounded-md s-transition-colors s-duration-200",
244
- "s-text-muted-foreground dark:s-text-muted-foreground-night",
245
- "hover:s-text-foreground dark:hover:s-text-foreground-night",
246
- "hover:s-bg-primary-150 dark:hover:s-bg-primary-150-night",
247
- "active:s-bg-primary-200 dark:active:s-bg-primary-200-night",
248
- "focus-visible:s-outline-none focus-visible:s-ring-2 focus-visible:s-ring-ring focus-visible:s-ring-offset-1",
249
- "disabled:s-cursor-not-allowed disabled:s-opacity-50",
250
- "disabled:hover:s-text-muted-foreground dark:disabled:hover:s-text-muted-foreground-night",
251
- "disabled:hover:s-bg-transparent dark:disabled:hover:s-bg-transparent",
252
- className
253
- )}
254
- {...props}
255
- >
256
- {icon ? <Icon visual={icon} size="xs" /> : children}
257
- </button>
258
- );
259
- });
260
-
261
- NavigationListLabelButton.displayName = "NavigationListLabelButton";
262
-
263
230
  interface NavigationListLabelProps
264
- extends
265
- React.HTMLAttributes<HTMLDivElement>,
231
+ extends React.HTMLAttributes<HTMLDivElement>,
266
232
  VariantProps<typeof variantStyles> {
267
233
  label: string;
268
- isCollapsible?: boolean;
269
- isOpen?: boolean;
270
234
  action?: React.ReactNode;
271
235
  }
272
236
 
273
237
  const NavigationListLabel = React.forwardRef<
274
238
  HTMLDivElement,
275
239
  NavigationListLabelProps
276
- >(
277
- (
278
- {
279
- className,
280
- variant,
281
- label,
282
- isSticky,
283
- isCollapsible,
284
- isOpen,
285
- action,
286
- ...props
287
- },
288
- ref
289
- ) => (
290
- <div
291
- ref={ref}
292
- className={cn(
293
- labelStyles(),
294
- variantStyles({ variant, isSticky }),
295
- isCollapsible ? "s-pl-1" : "s-pl-3",
296
- className
297
- )}
298
- {...props}
299
- >
300
- <div className="s-flex s-items-center s-gap-1 s-overflow-hidden s-text-ellipsis">
301
- {isCollapsible && (
302
- <NavigationListLabelButton
303
- icon={isOpen ? ArrowDownSIcon : ArrowRightSIcon}
304
- aria-label={isOpen ? "Collapse section" : "Expand section"}
305
- />
306
- )}
307
- <span className="s-overflow-hidden s-text-ellipsis">{label}</span>
308
- </div>
309
- {action}
240
+ >(({ className, variant, label, isSticky, action, ...props }, ref) => (
241
+ <div
242
+ ref={ref}
243
+ className={cn(
244
+ labelStyles(),
245
+ variantStyles({ variant, isSticky }),
246
+ "s-pl-3",
247
+ className
248
+ )}
249
+ {...props}
250
+ >
251
+ <div className="s-flex s-items-center s-gap-1 s-overflow-hidden s-text-ellipsis">
252
+ <span className="s-overflow-hidden s-text-ellipsis">{label}</span>
310
253
  </div>
311
- )
312
- );
254
+ {action}
255
+ </div>
256
+ ));
313
257
 
314
258
  NavigationListLabel.displayName = "NavigationListLabel";
315
259
 
316
- interface NavigationListCollapsibleSectionProps extends React.HTMLAttributes<HTMLDivElement> {
260
+ interface NavigationListCollapsibleSectionProps
261
+ extends React.HTMLAttributes<HTMLDivElement> {
317
262
  label: string;
318
263
  action?: React.ReactNode;
319
264
  defaultOpen?: boolean;
@@ -322,58 +267,69 @@ interface NavigationListCollapsibleSectionProps extends React.HTMLAttributes<HTM
322
267
  children: React.ReactNode;
323
268
  }
324
269
 
325
- const NavigationListCollapsibleSection = React.forwardRef<
326
- React.ElementRef<typeof Collapsible>,
327
- NavigationListCollapsibleSectionProps
328
- >(
329
- (
330
- {
331
- label,
332
- action,
333
- defaultOpen,
334
- open,
335
- onOpenChange,
336
- children,
337
- className,
338
- ...props
270
+ const collapseableStyles = cva(
271
+ cn(
272
+ "s-py-2 s-mt-2 s-px-2.5",
273
+ "s-heading-xs s-whitespace-nowrap s-overflow-hidden s-text-ellipsis ",
274
+ "s-box-border s-flex s-items-center s-w-full s-gap-1.5",
275
+ "s-cursor-pointer s-select-none",
276
+ "s-outline-none s-rounded-xl s-transition-colors s-duration-300",
277
+ "data-[disabled]:s-pointer-events-none",
278
+ "data-[disabled]:s-text-muted-foreground dark:data-[disabled]:s-text-muted-foreground-night",
279
+ "hover:s-text-foreground dark:hover:s-text-foreground-night",
280
+ "hover:s-bg-primary-100 dark:hover:s-bg-primary-200-night"
281
+ ),
282
+ {
283
+ variants: {
284
+ state: {
285
+ active: "active:s-bg-primary-150 dark:active:s-bg-primary-200-night",
286
+ selected: cn(
287
+ "s-text-foreground dark:s-text-foreground-night",
288
+ "s-bg-primary-100 dark:s-bg-primary-200-night"
289
+ ),
290
+ unselected:
291
+ "s-text-muted-foreground dark:s-text-muted-foreground-night",
292
+ },
293
+ },
294
+ defaultVariants: {
295
+ state: "unselected",
339
296
  },
340
- ref
341
- ) => {
342
- const [internalOpen, setInternalOpen] = React.useState(
343
- defaultOpen ?? false
344
- );
345
- const isControlled = open !== undefined;
346
- const isOpen = isControlled ? open : internalOpen;
347
-
348
- const handleOpenChange = (newOpen: boolean) => {
349
- if (!isControlled) {
350
- setInternalOpen(newOpen);
351
- }
352
- onOpenChange?.(newOpen);
353
- };
354
-
355
- return (
356
- <Collapsible
357
- ref={ref}
358
- open={isOpen}
359
- onOpenChange={handleOpenChange}
360
- className={className}
361
- {...props}
362
- >
363
- <CollapsiblePrimitive.Trigger asChild>
364
- <NavigationListLabel
365
- label={label}
366
- isCollapsible={true}
367
- isOpen={isOpen}
368
- action={action}
369
- />
370
- </CollapsiblePrimitive.Trigger>
371
- <CollapsibleContent>{children}</CollapsibleContent>
372
- </Collapsible>
373
- );
374
297
  }
375
298
  );
376
299
 
300
+ const NavigationListCollapsibleSection = React.forwardRef<
301
+ React.ElementRef<typeof Collapsible>,
302
+ NavigationListCollapsibleSectionProps
303
+ >(({ label, action, children, className, ...props }) => {
304
+ return (
305
+ <Collapsible className={className} {...props}>
306
+ <div className="s-group/menu-item s-relative">
307
+ <CollapsibleTrigger>
308
+ <div className={collapseableStyles({ state: "unselected" })}>
309
+ {label}
310
+ </div>
311
+ </CollapsibleTrigger>
312
+ {action && (
313
+ <div
314
+ className={cn(
315
+ "s-absolute s-bottom-1 s-right-1.5 s-flex s-gap-1 s-opacity-0 s-transition-opacity",
316
+ "hover:s-opacity-100 group-focus-within/menu-item:s-opacity-100 group-hover/menu-item:s-opacity-100"
317
+ )}
318
+ onClick={(e) => {
319
+ e.stopPropagation();
320
+ }}
321
+ >
322
+ {action}
323
+ </div>
324
+ )}
325
+ </div>
326
+ <CollapsibleContent>
327
+ <div className="s-flex s-flex-col s-gap-0.5">{children}</div>
328
+ </CollapsibleContent>
329
+ </Collapsible>
330
+ );
331
+ });
332
+
377
333
  NavigationListCollapsibleSection.displayName =
378
334
  "NavigationListCollapsibleSection";
379
335
 
@@ -383,5 +339,4 @@ export {
383
339
  NavigationListItem,
384
340
  NavigationListItemAction,
385
341
  NavigationListLabel,
386
- NavigationListLabelButton,
387
342
  };