@cl-light-ds/ui 0.2.0 → 0.3.0

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 (283) hide show
  1. package/README.md +45 -45
  2. package/package.json +1 -1
  3. package/src/components/accordion/Accordion.astro +248 -248
  4. package/src/components/accordion/AccordionContent.astro +26 -26
  5. package/src/components/accordion/AccordionItem.astro +36 -36
  6. package/src/components/accordion/AccordionTrigger.astro +118 -118
  7. package/src/components/accordion/CHANGELOG.md +41 -41
  8. package/src/components/accordion/index.ts +4 -4
  9. package/src/components/alert/Alert.astro +167 -167
  10. package/src/components/alert/AlertDescription.astro +24 -24
  11. package/src/components/alert/AlertTitle.astro +24 -24
  12. package/src/components/alert/CHANGELOG.md +5 -5
  13. package/src/components/alert/index.ts +4 -4
  14. package/src/components/avatar/Avatar.astro +197 -197
  15. package/src/components/avatar/AvatarBadge.astro +44 -44
  16. package/src/components/avatar/AvatarFallback.astro +26 -26
  17. package/src/components/avatar/AvatarGroup.astro +26 -26
  18. package/src/components/avatar/AvatarGroupCount.astro +30 -30
  19. package/src/components/avatar/AvatarImage.astro +46 -46
  20. package/src/components/avatar/CHANGELOG.md +44 -44
  21. package/src/components/avatar/index.ts +6 -6
  22. package/src/components/badge/Badge.astro +167 -167
  23. package/src/components/badge/CHANGELOG.md +49 -49
  24. package/src/components/badge/index.ts +2 -2
  25. package/src/components/breadcrumb/Breadcrumb.astro +76 -76
  26. package/src/components/breadcrumb/BreadcrumbItem.astro +32 -32
  27. package/src/components/breadcrumb/BreadcrumbList.astro +26 -26
  28. package/src/components/breadcrumb/BreadcrumbSeparator.astro +26 -26
  29. package/src/components/breadcrumb/CHANGELOG.md +24 -24
  30. package/src/components/breadcrumb/index.ts +5 -5
  31. package/src/components/button/Button.astro +233 -233
  32. package/src/components/button/CHANGELOG.md +41 -41
  33. package/src/components/button/index.ts +2 -2
  34. package/src/components/button-group/ButtonGroup.astro +130 -130
  35. package/src/components/button-group/ButtonGroupSeparator.astro +30 -30
  36. package/src/components/button-group/ButtonGroupText.astro +21 -21
  37. package/src/components/button-group/CHANGELOG.md +34 -34
  38. package/src/components/button-group/index.ts +3 -3
  39. package/src/components/card/CHANGELOG.md +162 -119
  40. package/src/components/card/Card.astro +197 -182
  41. package/src/components/card/CardAction.astro +26 -26
  42. package/src/components/card/CardContent.astro +28 -28
  43. package/src/components/card/CardDescription.astro +28 -28
  44. package/src/components/card/CardFooter.astro +24 -24
  45. package/src/components/card/CardHeader.astro +30 -30
  46. package/src/components/card/CardMedia.astro +27 -27
  47. package/src/components/card/CardMediaActions.astro +21 -0
  48. package/src/components/card/CardMediaSelect.astro +21 -0
  49. package/src/components/card/CardOverlay.astro +32 -32
  50. package/src/components/card/CardTitle.astro +21 -21
  51. package/src/components/card/index.ts +12 -10
  52. package/src/components/carousel/CHANGELOG.md +5 -5
  53. package/src/components/carousel/Carousel.astro +106 -106
  54. package/src/components/carousel/CarouselSlide.astro +22 -22
  55. package/src/components/carousel/index.ts +3 -3
  56. package/src/components/checkbox/CHANGELOG.md +58 -58
  57. package/src/components/checkbox/Checkbox.astro +159 -159
  58. package/src/components/checkbox/index.ts +1 -1
  59. package/src/components/collapsible/CHANGELOG.md +5 -5
  60. package/src/components/collapsible/Collapsible.astro +202 -202
  61. package/src/components/collapsible/CollapsibleContent.astro +36 -36
  62. package/src/components/collapsible/CollapsibleTrigger.astro +34 -34
  63. package/src/components/collapsible/index.ts +4 -4
  64. package/src/components/combobox/CHANGELOG.md +27 -27
  65. package/src/components/combobox/Combobox.astro +365 -365
  66. package/src/components/combobox/ComboboxContent.astro +37 -37
  67. package/src/components/combobox/ComboboxEmpty.astro +18 -18
  68. package/src/components/combobox/ComboboxGroup.astro +19 -19
  69. package/src/components/combobox/ComboboxInput.astro +74 -74
  70. package/src/components/combobox/ComboboxItem.astro +39 -39
  71. package/src/components/combobox/ComboboxLabel.astro +18 -18
  72. package/src/components/combobox/ComboboxList.astro +21 -21
  73. package/src/components/combobox/ComboboxSeparator.astro +17 -17
  74. package/src/components/combobox/ComboboxTrigger.astro +30 -30
  75. package/src/components/combobox/ComboboxValue.astro +22 -22
  76. package/src/components/combobox/index.ts +11 -11
  77. package/src/components/date/CHANGELOG.md +18 -18
  78. package/src/components/date/Date.astro +137 -137
  79. package/src/components/date/index.ts +2 -2
  80. package/src/components/dialog/CHANGELOG.md +39 -39
  81. package/src/components/dialog/Dialog.astro +196 -196
  82. package/src/components/dialog/DialogClose.astro +23 -23
  83. package/src/components/dialog/DialogContent.astro +42 -42
  84. package/src/components/dialog/DialogDescription.astro +18 -18
  85. package/src/components/dialog/DialogFooter.astro +18 -18
  86. package/src/components/dialog/DialogHeader.astro +18 -18
  87. package/src/components/dialog/DialogOverlay.astro +19 -19
  88. package/src/components/dialog/DialogTitle.astro +18 -18
  89. package/src/components/dialog/DialogTrigger.astro +37 -37
  90. package/src/components/dialog/index.ts +9 -9
  91. package/src/components/dropdown-menu/CHANGELOG.md +194 -194
  92. package/src/components/dropdown-menu/DropdownMenu.astro +226 -226
  93. package/src/components/dropdown-menu/DropdownMenuCheckboxItem.astro +114 -114
  94. package/src/components/dropdown-menu/DropdownMenuContent.astro +42 -42
  95. package/src/components/dropdown-menu/DropdownMenuGroup.astro +19 -19
  96. package/src/components/dropdown-menu/DropdownMenuItem.astro +220 -220
  97. package/src/components/dropdown-menu/DropdownMenuItemContent.astro +79 -79
  98. package/src/components/dropdown-menu/DropdownMenuLabel.astro +20 -20
  99. package/src/components/dropdown-menu/DropdownMenuPortal.astro +13 -13
  100. package/src/components/dropdown-menu/DropdownMenuRadioGroup.astro +13 -13
  101. package/src/components/dropdown-menu/DropdownMenuRadioItem.astro +101 -101
  102. package/src/components/dropdown-menu/DropdownMenuSeparator.astro +18 -18
  103. package/src/components/dropdown-menu/DropdownMenuShortcut.astro +18 -18
  104. package/src/components/dropdown-menu/DropdownMenuTrigger.astro +49 -49
  105. package/src/components/dropdown-menu/dropdown-menu-item-variants.ts +24 -24
  106. package/src/components/dropdown-menu/index.ts +12 -12
  107. package/src/components/field/CHANGELOG.md +33 -33
  108. package/src/components/field/Field.astro +664 -664
  109. package/src/components/field/FieldContent.astro +20 -20
  110. package/src/components/field/FieldDescription.astro +22 -22
  111. package/src/components/field/FieldError.astro +51 -51
  112. package/src/components/field/FieldGroup.astro +20 -20
  113. package/src/components/field/FieldLabel.astro +22 -22
  114. package/src/components/field/FieldLegend.astro +23 -23
  115. package/src/components/field/FieldSeparator.astro +30 -30
  116. package/src/components/field/FieldSet.astro +20 -20
  117. package/src/components/field/FieldTitle.astro +20 -20
  118. package/src/components/field/index.ts +10 -10
  119. package/src/components/hover-card/CHANGELOG.md +20 -20
  120. package/src/components/hover-card/HoverCard.astro +235 -235
  121. package/src/components/hover-card/HoverCardContent.astro +54 -54
  122. package/src/components/hover-card/HoverCardTrigger.astro +38 -38
  123. package/src/components/hover-card/index.ts +3 -3
  124. package/src/components/input/CHANGELOG.md +29 -29
  125. package/src/components/input/Input.astro +130 -130
  126. package/src/components/input/index.ts +2 -2
  127. package/src/components/input-group/CHANGELOG.md +49 -49
  128. package/src/components/input-group/InputGroup.astro +135 -135
  129. package/src/components/input-group/InputGroupAddon.astro +49 -49
  130. package/src/components/input-group/InputGroupButton.astro +58 -58
  131. package/src/components/input-group/InputGroupInput.astro +18 -18
  132. package/src/components/input-group/InputGroupText.astro +21 -21
  133. package/src/components/input-group/InputGroupTextarea.astro +17 -17
  134. package/src/components/input-group/controlClasses.ts +2 -2
  135. package/src/components/input-group/index.ts +6 -6
  136. package/src/components/item/CHANGELOG.md +27 -27
  137. package/src/components/item/Item.astro +122 -122
  138. package/src/components/item/ItemActions.astro +21 -21
  139. package/src/components/item/ItemContent.astro +25 -25
  140. package/src/components/item/ItemDescription.astro +25 -25
  141. package/src/components/item/ItemFooter.astro +24 -24
  142. package/src/components/item/ItemGroup.astro +24 -24
  143. package/src/components/item/ItemHeader.astro +24 -24
  144. package/src/components/item/ItemMedia.astro +47 -47
  145. package/src/components/item/ItemSeparator.astro +21 -21
  146. package/src/components/item/ItemTitle.astro +25 -25
  147. package/src/components/item/index.ts +10 -10
  148. package/src/components/kbd/CHANGELOG.md +5 -5
  149. package/src/components/kbd/Kbd.astro +145 -145
  150. package/src/components/kbd/KbdGroup.astro +55 -55
  151. package/src/components/kbd/index.ts +2 -2
  152. package/src/components/label/CHANGELOG.md +28 -28
  153. package/src/components/label/Label.astro +97 -97
  154. package/src/components/label/index.ts +2 -2
  155. package/src/components/link-group/CHANGELOG.md +75 -75
  156. package/src/components/link-group/LinkGroup.astro +67 -67
  157. package/src/components/link-group/LinkGroupItem.astro +32 -32
  158. package/src/components/link-group/LinkGroupList.astro +25 -25
  159. package/src/components/link-group/LinkGroupTitle.astro +22 -22
  160. package/src/components/link-group/index.ts +5 -5
  161. package/src/components/link-group/link-group-list-variants.ts +15 -15
  162. package/src/components/marquee/CHANGELOG.md +5 -5
  163. package/src/components/marquee/Marquee.astro +119 -119
  164. package/src/components/marquee/index.ts +2 -2
  165. package/src/components/native-select/CHANGELOG.md +5 -5
  166. package/src/components/native-select/NativeSelect.astro +125 -125
  167. package/src/components/native-select/NativeSelectOptGroup.astro +14 -14
  168. package/src/components/native-select/NativeSelectOption.astro +9 -9
  169. package/src/components/native-select/index.ts +3 -3
  170. package/src/components/navigation-menu/CHANGELOG.md +63 -63
  171. package/src/components/navigation-menu/NavigationMenu.astro +414 -414
  172. package/src/components/navigation-menu/NavigationMenuContent.astro +37 -37
  173. package/src/components/navigation-menu/NavigationMenuIndicator.astro +24 -24
  174. package/src/components/navigation-menu/NavigationMenuItem.astro +22 -22
  175. package/src/components/navigation-menu/NavigationMenuLink.astro +18 -18
  176. package/src/components/navigation-menu/NavigationMenuList.astro +21 -21
  177. package/src/components/navigation-menu/NavigationMenuPositioner.astro +44 -44
  178. package/src/components/navigation-menu/NavigationMenuTrigger.astro +30 -30
  179. package/src/components/navigation-menu/NavigationMenuViewport.astro +19 -19
  180. package/src/components/navigation-menu/index.ts +10 -10
  181. package/src/components/organisms/lightning-sidebar-nav/CHANGELOG.md +50 -0
  182. package/src/components/organisms/lightning-sidebar-nav/LightningSidebarNav.astro +176 -0
  183. package/src/components/organisms/lightning-sidebar-nav/SidebarNav.astro +50 -0
  184. package/src/components/organisms/lightning-sidebar-nav/SidebarNavGroup.astro +74 -0
  185. package/src/components/organisms/lightning-sidebar-nav/SidebarNavItem.astro +94 -0
  186. package/src/components/organisms/lightning-sidebar-nav/SidebarNavProBadge.astro +26 -0
  187. package/src/components/organisms/lightning-sidebar-nav/SidebarNavSection.astro +71 -0
  188. package/src/components/organisms/lightning-sidebar-nav/SidebarNavSkeleton.astro +67 -0
  189. package/src/components/organisms/lightning-sidebar-nav/SidebarNavSubItem.astro +69 -0
  190. package/src/components/organisms/lightning-sidebar-nav/SidebarNavUsage.astro +78 -0
  191. package/src/components/organisms/lightning-sidebar-nav/SidebarNavWorkspaceAvatar.astro +46 -0
  192. package/src/components/organisms/lightning-sidebar-nav/SidebarNavWorkspaceSwitcher.astro +130 -0
  193. package/src/components/organisms/lightning-sidebar-nav/icons.ts +46 -0
  194. package/src/components/organisms/lightning-sidebar-nav/index.ts +18 -0
  195. package/src/components/organisms/lightning-sidebar-nav/types.ts +77 -0
  196. package/src/components/popover/CHANGELOG.md +20 -20
  197. package/src/components/popover/Popover.astro +211 -211
  198. package/src/components/popover/PopoverClose.astro +18 -18
  199. package/src/components/popover/PopoverContent.astro +50 -50
  200. package/src/components/popover/PopoverDescription.astro +18 -18
  201. package/src/components/popover/PopoverHeader.astro +18 -18
  202. package/src/components/popover/PopoverTitle.astro +18 -18
  203. package/src/components/popover/PopoverTrigger.astro +35 -35
  204. package/src/components/popover/index.ts +7 -7
  205. package/src/components/radio-group/CHANGELOG.md +31 -31
  206. package/src/components/radio-group/RadioGroup.astro +81 -81
  207. package/src/components/radio-group/RadioGroupItem.astro +51 -51
  208. package/src/components/radio-group/index.ts +3 -3
  209. package/src/components/select/CHANGELOG.md +39 -39
  210. package/src/components/select/Select.astro +373 -373
  211. package/src/components/select/SelectContent.astro +91 -91
  212. package/src/components/select/SelectGroup.astro +19 -19
  213. package/src/components/select/SelectItem.astro +48 -48
  214. package/src/components/select/SelectLabel.astro +18 -18
  215. package/src/components/select/SelectSeparator.astro +17 -17
  216. package/src/components/select/SelectTrigger.astro +34 -34
  217. package/src/components/select/SelectValue.astro +22 -22
  218. package/src/components/select/index.ts +8 -8
  219. package/src/components/separator/CHANGELOG.md +5 -5
  220. package/src/components/separator/Separator.astro +60 -60
  221. package/src/components/separator/index.ts +2 -2
  222. package/src/components/skeleton/CHANGELOG.md +5 -5
  223. package/src/components/skeleton/Skeleton.astro +121 -121
  224. package/src/components/skeleton/index.ts +1 -1
  225. package/src/components/slider/CHANGELOG.md +5 -5
  226. package/src/components/slider/Slider.astro +198 -198
  227. package/src/components/slider/index.ts +1 -1
  228. package/src/components/spinner/CHANGELOG.md +18 -18
  229. package/src/components/spinner/Spinner.astro +135 -135
  230. package/src/components/spinner/index.ts +1 -1
  231. package/src/components/sticky-surface/CHANGELOG.md +5 -5
  232. package/src/components/sticky-surface/StickySurface.astro +152 -152
  233. package/src/components/sticky-surface/index.ts +2 -2
  234. package/src/components/switch/CHANGELOG.md +29 -29
  235. package/src/components/switch/Switch.astro +106 -106
  236. package/src/components/switch/index.ts +1 -1
  237. package/src/components/table/CHANGELOG.md +24 -24
  238. package/src/components/table/Table.astro +358 -251
  239. package/src/components/table/TableBody.astro +17 -18
  240. package/src/components/table/TableBulkToolbar.astro +37 -0
  241. package/src/components/table/TableCaption.astro +17 -17
  242. package/src/components/table/TableCell.astro +45 -21
  243. package/src/components/table/TableCellText.astro +17 -0
  244. package/src/components/table/TableColumnMenu.astro +50 -0
  245. package/src/components/table/TableEditableCell.astro +287 -0
  246. package/src/components/table/TableEmpty.astro +17 -0
  247. package/src/components/table/TableFolderCell.astro +38 -0
  248. package/src/components/table/TableFooter.astro +21 -21
  249. package/src/components/table/TableHead.astro +90 -21
  250. package/src/components/table/TableHeader.astro +17 -17
  251. package/src/components/table/TablePagination.astro +57 -0
  252. package/src/components/table/TableRow.astro +52 -21
  253. package/src/components/table/TableSelectAllBanner.astro +34 -0
  254. package/src/components/table/TableSelectCell.astro +50 -0
  255. package/src/components/table/TableSkeletonRow.astro +21 -0
  256. package/src/components/table/index.ts +19 -9
  257. package/src/components/table/table-cell-variants.ts +29 -0
  258. package/src/components/tabs/CHANGELOG.md +5 -5
  259. package/src/components/tabs/Tabs.astro +306 -306
  260. package/src/components/tabs/TabsContent.astro +47 -47
  261. package/src/components/tabs/TabsList.astro +69 -69
  262. package/src/components/tabs/TabsTrigger.astro +40 -40
  263. package/src/components/tabs/index.ts +6 -6
  264. package/src/components/textarea/CHANGELOG.md +22 -22
  265. package/src/components/textarea/Textarea.astro +58 -58
  266. package/src/components/textarea/index.ts +2 -2
  267. package/src/components/toggle/CHANGELOG.md +23 -23
  268. package/src/components/toggle/Toggle.astro +150 -150
  269. package/src/components/toggle/index.ts +1 -1
  270. package/src/components/toggle-group/CHANGELOG.md +18 -18
  271. package/src/components/toggle-group/ToggleGroup.astro +236 -236
  272. package/src/components/toggle-group/ToggleGroupItem.astro +48 -48
  273. package/src/components/toggle-group/index.ts +2 -2
  274. package/src/components/tooltip/CHANGELOG.md +22 -22
  275. package/src/components/tooltip/Tooltip.astro +357 -357
  276. package/src/components/tooltip/TooltipContent.astro +85 -85
  277. package/src/components/tooltip/TooltipTrigger.astro +34 -34
  278. package/src/components/tooltip/index.ts +3 -3
  279. package/src/lib/table-controller.ts +1090 -0
  280. package/src/lib/toggle-group-controller.ts +113 -113
  281. package/src/lib/toggle-shared.ts +27 -27
  282. package/src/lib/utils.ts +6 -6
  283. package/src/styles/globals.css +197 -177
@@ -0,0 +1,78 @@
1
+ ---
2
+ /**
3
+ * @component SidebarNavUsage
4
+ * @title Sidebar Nav Usage
5
+ * @description Plan usage rows (label … used / limit) and an optional full-width upgrade CTA, pinned to the bottom of the sidebar.
6
+ * @figmaUrl https://www.figma.com/design/qXkzdqZ3QPQqgckU3AwIAH/ClickLearn-Lightning-Design-Library?node-id=7514-198
7
+ *
8
+ * @usage
9
+ *
10
+ * ```astro nocollapse
11
+ * <SidebarNavUsage
12
+ * usage={[{ id: "recordings", label: "Recordings created", used: 5, limit: 5 }]}
13
+ * upgrade={{ label: "Upgrade to Pro", href: "/billing" }}
14
+ * />
15
+ * ```
16
+ */
17
+
18
+ import { cn } from "@cl-light-ds/ui/lib/utils";
19
+ import { Button } from "../../button";
20
+ import { Separator } from "../../separator";
21
+ import type { SidebarNavUpgrade, SidebarNavUsageMetric } from "./types";
22
+
23
+ interface Props {
24
+ usage?: SidebarNavUsageMetric[];
25
+ upgrade?: SidebarNavUpgrade | null;
26
+ class?: string;
27
+ }
28
+
29
+ const {
30
+ usage = [],
31
+ upgrade = null,
32
+ class: className = "",
33
+ } = Astro.props as Props;
34
+
35
+ const formatValue = ({ used, limit }: SidebarNavUsageMetric) =>
36
+ limit === null ? `${used} / Unlimited` : `${used} / ${limit}`;
37
+ ---
38
+
39
+ {
40
+ (usage.length > 0 || upgrade) && (
41
+ <div
42
+ data-slot="sidebar-nav-usage"
43
+ class={cn("flex flex-col gap-3", className)}
44
+ >
45
+ <Separator class="my-2" />
46
+ {usage.length > 0 && (
47
+ <dl class="flex flex-col gap-2 text-xs leading-4">
48
+ {usage.map((metric) => (
49
+ <div
50
+ data-slot="sidebar-nav-usage-metric"
51
+ data-at-limit={
52
+ metric.limit !== null && metric.used >= metric.limit
53
+ ? ""
54
+ : undefined
55
+ }
56
+ class="flex items-baseline justify-between gap-2"
57
+ >
58
+ <dt class="text-muted-foreground truncate">{metric.label}</dt>
59
+ <dd class="text-foreground shrink-0 font-semibold whitespace-nowrap">
60
+ {formatValue(metric)}
61
+ </dd>
62
+ </div>
63
+ ))}
64
+ </dl>
65
+ )}
66
+ {upgrade && (
67
+ <Button
68
+ as="a"
69
+ href={upgrade.href}
70
+ size="sm"
71
+ class="w-full font-semibold"
72
+ >
73
+ {upgrade.label}
74
+ </Button>
75
+ )}
76
+ </div>
77
+ )
78
+ }
@@ -0,0 +1,46 @@
1
+ ---
2
+ /**
3
+ * @component SidebarNavWorkspaceAvatar
4
+ * @description 24px workspace avatar: image when `avatarUrl` is set, else initials, else the user-round icon on primary.
5
+ */
6
+
7
+ import { UserRound } from "@lucide/astro";
8
+ import { cn } from "@cl-light-ds/ui/lib/utils";
9
+ import { Avatar, AvatarFallback, AvatarImage } from "../../avatar";
10
+ import type { SidebarNavWorkspace } from "./types";
11
+
12
+ interface Props {
13
+ workspace: SidebarNavWorkspace;
14
+ class?: string;
15
+ slot?: string;
16
+ }
17
+
18
+ const { workspace, class: className = "", ...rest } = Astro.props as Props;
19
+
20
+ const variant = workspace.avatarUrl
21
+ ? "image"
22
+ : workspace.initials
23
+ ? "initials"
24
+ : "icon";
25
+ ---
26
+
27
+ <Avatar
28
+ {...rest}
29
+ size="sm"
30
+ variant={variant}
31
+ icon={variant === "icon" ? UserRound : undefined}
32
+ class={cn(
33
+ variant === "icon" &&
34
+ "bg-primary [&_[data-slot=avatar-icon]]:text-primary-foreground",
35
+ className,
36
+ )}
37
+ >
38
+ {workspace.avatarUrl && <AvatarImage src={workspace.avatarUrl} alt="" />}
39
+ {
40
+ !workspace.avatarUrl && workspace.initials && (
41
+ <AvatarFallback class="bg-primary text-primary-foreground">
42
+ {workspace.initials}
43
+ </AvatarFallback>
44
+ )
45
+ }
46
+ </Avatar>
@@ -0,0 +1,130 @@
1
+ ---
2
+ /**
3
+ * @component SidebarNavWorkspaceSwitcher
4
+ * @title Sidebar Nav Workspace Switcher
5
+ * @description Current workspace (avatar + name) at the top of the sidebar. With `workspaces`, it opens a DropdownMenu to switch.
6
+ * @figmaUrl https://www.figma.com/design/qXkzdqZ3QPQqgckU3AwIAH/ClickLearn-Lightning-Design-Library?node-id=7514-183
7
+ *
8
+ * @usage
9
+ *
10
+ * ```astro nocollapse
11
+ * <SidebarNavWorkspaceSwitcher
12
+ * workspace={{ id: "nw", name: "Northwind Group" }}
13
+ * workspaces={[{ id: "nw", name: "Northwind Group" }, { id: "ct", name: "Contoso", href: "/w/ct" }]}
14
+ * />
15
+ * ```
16
+ *
17
+ * ### Events
18
+ *
19
+ * | Event | Detail | Description |
20
+ * |-------|--------|-------------|
21
+ * | `sidebar-nav:workspace-change` | `{ id: string }` | Bubbles, cancelable. Fired when a workspace is picked. If the workspace has an `href` and the event isn't cancelled, the browser navigates there. |
22
+ */
23
+
24
+ import { ChevronsUpDown } from "@lucide/astro";
25
+ import { cn } from "@cl-light-ds/ui/lib/utils";
26
+ import {
27
+ DropdownMenu,
28
+ DropdownMenuContent,
29
+ DropdownMenuLabel,
30
+ DropdownMenuRadioGroup,
31
+ DropdownMenuRadioItem,
32
+ DropdownMenuTrigger,
33
+ } from "../../dropdown-menu";
34
+ import { Separator } from "../../separator";
35
+ import type { SidebarNavWorkspace } from "./types";
36
+ import SidebarNavWorkspaceAvatar from "./SidebarNavWorkspaceAvatar.astro";
37
+
38
+ interface Props {
39
+ workspace: SidebarNavWorkspace;
40
+ /** Options in the switcher menu. Empty = static display, no menu. */
41
+ workspaces?: SidebarNavWorkspace[];
42
+ /** Heading shown at the top of the menu. */
43
+ menuLabel?: string;
44
+ class?: string;
45
+ }
46
+
47
+ const {
48
+ workspace,
49
+ workspaces = [],
50
+ menuLabel = "Workspaces",
51
+ class: className = "",
52
+ } = Astro.props as Props;
53
+
54
+ const hasMenu = workspaces.length > 0;
55
+ const rowClass =
56
+ "flex w-full items-center gap-2 overflow-hidden rounded-lg p-2 text-left text-sm leading-5 font-medium text-foreground";
57
+ ---
58
+
59
+ <div data-slot="sidebar-nav-workspace" class={cn("flex flex-col", className)}>
60
+ {
61
+ hasMenu ? (
62
+ <DropdownMenu
63
+ class="block w-full"
64
+ defaultValue={workspace.id}
65
+ highlightItemOnHover
66
+ >
67
+ <DropdownMenuTrigger asChild class="flex w-full">
68
+ <button
69
+ type="button"
70
+ aria-label={`Switch workspace, current: ${workspace.name}`}
71
+ class={cn(
72
+ rowClass,
73
+ "outline-none transition-colors hover:bg-muted focus-visible:ring-1 focus-visible:ring-sidebar-ring focus-visible:ring-inset",
74
+ )}
75
+ >
76
+ <SidebarNavWorkspaceAvatar workspace={workspace} />
77
+ <span class="min-w-0 flex-1 truncate">{workspace.name}</span>
78
+ <ChevronsUpDown
79
+ aria-hidden="true"
80
+ class="text-foreground size-4 shrink-0"
81
+ />
82
+ </button>
83
+ </DropdownMenuTrigger>
84
+ {/* --anchor-width isn't set by the runtime; match the 238px inner width of the 270px shell. */}
85
+ <DropdownMenuContent align="start" class="w-[238px]">
86
+ <DropdownMenuLabel>{menuLabel}</DropdownMenuLabel>
87
+ <DropdownMenuRadioGroup>
88
+ {workspaces.map((option) => (
89
+ <DropdownMenuRadioItem
90
+ value={option.id}
91
+ data-href={option.href}
92
+ avatar
93
+ >
94
+ <SidebarNavWorkspaceAvatar slot="avatar" workspace={option} />
95
+ {option.name}
96
+ </DropdownMenuRadioItem>
97
+ ))}
98
+ </DropdownMenuRadioGroup>
99
+ </DropdownMenuContent>
100
+ </DropdownMenu>
101
+ ) : (
102
+ <div class={rowClass}>
103
+ <SidebarNavWorkspaceAvatar workspace={workspace} />
104
+ <span class="min-w-0 flex-1 truncate">{workspace.name}</span>
105
+ </div>
106
+ )
107
+ }
108
+ <Separator class="my-2" />
109
+ </div>
110
+
111
+ <script>
112
+ document
113
+ .querySelectorAll<HTMLElement>('[data-slot="sidebar-nav-workspace"]')
114
+ .forEach((root) => {
115
+ root.addEventListener("dropdown-menu:select", (event) => {
116
+ const { value, item } = (
117
+ event as CustomEvent<{ value: string; item: HTMLElement | null }>
118
+ ).detail;
119
+ const href = item?.dataset.href;
120
+ const proceed = root.dispatchEvent(
121
+ new CustomEvent("sidebar-nav:workspace-change", {
122
+ bubbles: true,
123
+ cancelable: true,
124
+ detail: { id: value },
125
+ }),
126
+ );
127
+ if (proceed && href) window.location.assign(href);
128
+ });
129
+ });
130
+ </script>
@@ -0,0 +1,46 @@
1
+ import {
2
+ BookOpen,
3
+ ChartColumn,
4
+ CircleHelp,
5
+ FileText,
6
+ Folder,
7
+ House,
8
+ Library,
9
+ Palette,
10
+ Settings,
11
+ Trash2,
12
+ UserRound,
13
+ Users,
14
+ Video,
15
+ type AstroComponent,
16
+ } from "@lucide/astro";
17
+
18
+ /**
19
+ * String → Lucide icon registry, so backend data can name icons without
20
+ * importing components. Extend this map when a new destination needs an icon.
21
+ */
22
+ export const sidebarNavIcons = {
23
+ "book-open": BookOpen,
24
+ "chart-column": ChartColumn,
25
+ "circle-help": CircleHelp,
26
+ "file-text": FileText,
27
+ folder: Folder,
28
+ house: House,
29
+ library: Library,
30
+ palette: Palette,
31
+ settings: Settings,
32
+ "trash-2": Trash2,
33
+ "user-round": UserRound,
34
+ users: Users,
35
+ video: Video,
36
+ } satisfies Record<string, AstroComponent>;
37
+
38
+ export type SidebarNavIconName = keyof typeof sidebarNavIcons;
39
+
40
+ export const resolveSidebarNavIcon = (
41
+ icon: SidebarNavIconName | AstroComponent | undefined,
42
+ ): AstroComponent | undefined => {
43
+ if (!icon) return undefined;
44
+ if (typeof icon === "string") return sidebarNavIcons[icon];
45
+ return icon;
46
+ };
@@ -0,0 +1,18 @@
1
+ export { default as LightningSidebarNav } from "./LightningSidebarNav.astro";
2
+ export { default as SidebarNav } from "./SidebarNav.astro";
3
+ export { default as SidebarNavGroup } from "./SidebarNavGroup.astro";
4
+ export { default as SidebarNavItem } from "./SidebarNavItem.astro";
5
+ export { sidebarNavItemVariants } from "./SidebarNavItem.astro";
6
+ export { default as SidebarNavProBadge } from "./SidebarNavProBadge.astro";
7
+ export { default as SidebarNavSection } from "./SidebarNavSection.astro";
8
+ export { default as SidebarNavSkeleton } from "./SidebarNavSkeleton.astro";
9
+ export { default as SidebarNavSubItem } from "./SidebarNavSubItem.astro";
10
+ export { default as SidebarNavUsage } from "./SidebarNavUsage.astro";
11
+ export { default as SidebarNavWorkspaceAvatar } from "./SidebarNavWorkspaceAvatar.astro";
12
+ export { default as SidebarNavWorkspaceSwitcher } from "./SidebarNavWorkspaceSwitcher.astro";
13
+ export {
14
+ resolveSidebarNavIcon,
15
+ sidebarNavIcons,
16
+ type SidebarNavIconName,
17
+ } from "./icons";
18
+ export * from "./types";
@@ -0,0 +1,77 @@
1
+ import type { AstroComponent } from "@lucide/astro";
2
+ import type { SidebarNavIconName } from "./icons";
3
+
4
+ /**
5
+ * Backend contract for the Lightning Sidebar Nav.
6
+ * Everything except `AstroComponent` icons is JSON-serialisable, so a page can
7
+ * pass an API response straight into `<LightningSidebarNav />`.
8
+ */
9
+
10
+ /** Registry key (from backend data) or a Lucide component (hand-authored markup). */
11
+ export type SidebarNavIcon = SidebarNavIconName | AstroComponent;
12
+
13
+ /** A top-level destination (Figma: Group Item / Variant=Default). */
14
+ export interface SidebarNavLink {
15
+ id: string;
16
+ label: string;
17
+ href: string;
18
+ icon?: SidebarNavIcon;
19
+ /** Shows the Accent/Small "Pro" badge. The link still navigates. */
20
+ pro?: boolean;
21
+ disabled?: boolean;
22
+ }
23
+
24
+ /** A destination nested under a group (Figma: Group item / .Nav Item). */
25
+ export interface SidebarNavSubLink {
26
+ id: string;
27
+ label: string;
28
+ href: string;
29
+ pro?: boolean;
30
+ }
31
+
32
+ /** An expandable parent (Figma: Group Item / Variant=Collapsed | Expanded). */
33
+ export interface SidebarNavGroup {
34
+ id: string;
35
+ label: string;
36
+ icon?: SidebarNavIcon;
37
+ pro?: boolean;
38
+ children: SidebarNavSubLink[];
39
+ /** Force the initial open state. Groups with an active child open automatically. */
40
+ defaultOpen?: boolean;
41
+ }
42
+
43
+ export type SidebarNavEntry = SidebarNavLink | SidebarNavGroup;
44
+
45
+ /** A block of entries, optionally headed by a category label (Figma: Variant=Category). */
46
+ export interface SidebarNavSectionData {
47
+ id: string;
48
+ label?: string;
49
+ items: SidebarNavEntry[];
50
+ }
51
+
52
+ export interface SidebarNavWorkspace {
53
+ id: string;
54
+ name: string;
55
+ avatarUrl?: string;
56
+ initials?: string;
57
+ /** When set, choosing this workspace navigates here. Otherwise `sidebar-nav:workspace-change` fires. */
58
+ href?: string;
59
+ }
60
+
61
+ export interface SidebarNavUsageMetric {
62
+ id: string;
63
+ label: string;
64
+ used: number;
65
+ /** `null` means unlimited. */
66
+ limit: number | null;
67
+ }
68
+
69
+ export interface SidebarNavUpgrade {
70
+ label: string;
71
+ href: string;
72
+ }
73
+
74
+ export const isSidebarNavGroup = (
75
+ entry: SidebarNavEntry,
76
+ ): entry is SidebarNavGroup =>
77
+ Array.isArray((entry as SidebarNavGroup).children);
@@ -1,20 +1,20 @@
1
- # Changelog
2
-
3
- All notable changes to the `Popover` component family (`Popover`, `PopoverTrigger`, `PopoverContent`, `PopoverHeader`, `PopoverTitle`, `PopoverDescription`, `PopoverClose`) are documented in this file.
4
-
5
- ## 2026-09-18 — Figma alignment (ClickLearn Lightning Design Library, node `5548-11795`)
6
-
7
- Figma documents Popover across two pages: Items (the trigger button's Default/Hover/Pressed/Focus/Disabled states) and the expanded popover (12 Side × Alignment combinations, all sharing the same panel styling).
8
-
9
- ### Fixed
10
-
11
- - Added the missing `@figmaUrl` (this component never had one).
12
- - `PopoverContent`: replaced the `ring-1 ring-foreground/10` border approximation with a real `border border-border`, and `shadow-md` → `shadow-lg` — matching Figma's tokens (`border` = `#e4e4e7`, a named `shadow-lg`), same category of fix already made to `DialogContent`/`HoverCardContent`.
13
- - `PopoverContent`: removed a dead, redundant raw class string duplicating most of `contentVariants()` — same class of bug already fixed on `HoverCardContent`. It also carried two genuinely dead selectors, `data-[side=inline-start]:...`/`data-[side=inline-end]:...`, which the underlying `@data-slot/popover` behavior library never actually sets (confirmed by checking its source — it only ever sets physical `top`/`bottom`/`left`/`right`, matching the component's own `side` prop type). Also removed the dead `rounded-md` (a later `rounded-lg` always won anyway) and a `duration-100`/`duration-150` conflict (150ms was already winning).
14
- - `PopoverHeader`: `gap-1` (4px) → `gap-0.5` (2px) between `PopoverTitle`/`PopoverDescription`, matching Figma's measured 2px gap.
15
- - `PopoverTrigger`: now defaults to `variant="outline"` instead of inheriting `Button`'s own `default` (solid primary) variant — Figma's Default trigger state is a bordered/light button, matching outline exactly, and every existing usage example already passed `variant="outline"` explicitly. Visually a no-op for existing usages; makes new usages match the documented default without needing to repeat the prop.
16
-
17
- ### Notes
18
-
19
- - The trigger's Hover/Pressed/Focus/Disabled states are entirely `Button`'s own responsibility (`PopoverTrigger` just renders a `Button`) — already verified correct in earlier passes, no changes needed here.
20
- - `bg-popover`/`text-popover-foreground`, `p-4`, and `rounded-lg` already matched Figma's tokens exactly.
1
+ # Changelog
2
+
3
+ All notable changes to the `Popover` component family (`Popover`, `PopoverTrigger`, `PopoverContent`, `PopoverHeader`, `PopoverTitle`, `PopoverDescription`, `PopoverClose`) are documented in this file.
4
+
5
+ ## 2026-09-18 — Figma alignment (ClickLearn Lightning Design Library, node `5548-11795`)
6
+
7
+ Figma documents Popover across two pages: Items (the trigger button's Default/Hover/Pressed/Focus/Disabled states) and the expanded popover (12 Side × Alignment combinations, all sharing the same panel styling).
8
+
9
+ ### Fixed
10
+
11
+ - Added the missing `@figmaUrl` (this component never had one).
12
+ - `PopoverContent`: replaced the `ring-1 ring-foreground/10` border approximation with a real `border border-border`, and `shadow-md` → `shadow-lg` — matching Figma's tokens (`border` = `#e4e4e7`, a named `shadow-lg`), same category of fix already made to `DialogContent`/`HoverCardContent`.
13
+ - `PopoverContent`: removed a dead, redundant raw class string duplicating most of `contentVariants()` — same class of bug already fixed on `HoverCardContent`. It also carried two genuinely dead selectors, `data-[side=inline-start]:...`/`data-[side=inline-end]:...`, which the underlying `@data-slot/popover` behavior library never actually sets (confirmed by checking its source — it only ever sets physical `top`/`bottom`/`left`/`right`, matching the component's own `side` prop type). Also removed the dead `rounded-md` (a later `rounded-lg` always won anyway) and a `duration-100`/`duration-150` conflict (150ms was already winning).
14
+ - `PopoverHeader`: `gap-1` (4px) → `gap-0.5` (2px) between `PopoverTitle`/`PopoverDescription`, matching Figma's measured 2px gap.
15
+ - `PopoverTrigger`: now defaults to `variant="outline"` instead of inheriting `Button`'s own `default` (solid primary) variant — Figma's Default trigger state is a bordered/light button, matching outline exactly, and every existing usage example already passed `variant="outline"` explicitly. Visually a no-op for existing usages; makes new usages match the documented default without needing to repeat the prop.
16
+
17
+ ### Notes
18
+
19
+ - The trigger's Hover/Pressed/Focus/Disabled states are entirely `Button`'s own responsibility (`PopoverTrigger` just renders a `Button`) — already verified correct in earlier passes, no changes needed here.
20
+ - `bg-popover`/`text-popover-foreground`, `p-4`, and `rounded-lg` already matched Figma's tokens exactly.