@cl-light-ds/ui 0.2.0 → 0.4.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 (293) hide show
  1. package/README.md +45 -45
  2. package/package.json +2 -2
  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/callout/CHANGELOG.md +32 -0
  40. package/src/components/callout/Callout.astro +147 -0
  41. package/src/components/callout/CalloutDescription.astro +16 -0
  42. package/src/components/callout/CalloutTitle.astro +16 -0
  43. package/src/components/callout/index.ts +3 -0
  44. package/src/components/card/CHANGELOG.md +162 -119
  45. package/src/components/card/Card.astro +197 -182
  46. package/src/components/card/CardAction.astro +26 -26
  47. package/src/components/card/CardContent.astro +28 -28
  48. package/src/components/card/CardDescription.astro +28 -28
  49. package/src/components/card/CardFooter.astro +24 -24
  50. package/src/components/card/CardHeader.astro +30 -30
  51. package/src/components/card/CardMedia.astro +27 -27
  52. package/src/components/card/CardMediaActions.astro +21 -0
  53. package/src/components/card/CardMediaSelect.astro +21 -0
  54. package/src/components/card/CardOverlay.astro +32 -32
  55. package/src/components/card/CardTitle.astro +21 -21
  56. package/src/components/card/index.ts +12 -10
  57. package/src/components/carousel/CHANGELOG.md +5 -5
  58. package/src/components/carousel/Carousel.astro +106 -106
  59. package/src/components/carousel/CarouselSlide.astro +22 -22
  60. package/src/components/carousel/index.ts +3 -3
  61. package/src/components/checkbox/CHANGELOG.md +58 -58
  62. package/src/components/checkbox/Checkbox.astro +159 -159
  63. package/src/components/checkbox/index.ts +1 -1
  64. package/src/components/collapsible/CHANGELOG.md +5 -5
  65. package/src/components/collapsible/Collapsible.astro +202 -202
  66. package/src/components/collapsible/CollapsibleContent.astro +36 -36
  67. package/src/components/collapsible/CollapsibleTrigger.astro +34 -34
  68. package/src/components/collapsible/index.ts +4 -4
  69. package/src/components/combobox/CHANGELOG.md +27 -27
  70. package/src/components/combobox/Combobox.astro +365 -365
  71. package/src/components/combobox/ComboboxContent.astro +37 -37
  72. package/src/components/combobox/ComboboxEmpty.astro +18 -18
  73. package/src/components/combobox/ComboboxGroup.astro +19 -19
  74. package/src/components/combobox/ComboboxInput.astro +74 -74
  75. package/src/components/combobox/ComboboxItem.astro +39 -39
  76. package/src/components/combobox/ComboboxLabel.astro +18 -18
  77. package/src/components/combobox/ComboboxList.astro +21 -21
  78. package/src/components/combobox/ComboboxSeparator.astro +17 -17
  79. package/src/components/combobox/ComboboxTrigger.astro +30 -30
  80. package/src/components/combobox/ComboboxValue.astro +22 -22
  81. package/src/components/combobox/index.ts +11 -11
  82. package/src/components/date/CHANGELOG.md +18 -18
  83. package/src/components/date/Date.astro +137 -137
  84. package/src/components/date/index.ts +2 -2
  85. package/src/components/dialog/CHANGELOG.md +39 -39
  86. package/src/components/dialog/Dialog.astro +196 -196
  87. package/src/components/dialog/DialogClose.astro +23 -23
  88. package/src/components/dialog/DialogContent.astro +42 -42
  89. package/src/components/dialog/DialogDescription.astro +18 -18
  90. package/src/components/dialog/DialogFooter.astro +18 -18
  91. package/src/components/dialog/DialogHeader.astro +18 -18
  92. package/src/components/dialog/DialogOverlay.astro +19 -19
  93. package/src/components/dialog/DialogTitle.astro +18 -18
  94. package/src/components/dialog/DialogTrigger.astro +37 -37
  95. package/src/components/dialog/index.ts +9 -9
  96. package/src/components/dropdown-menu/CHANGELOG.md +194 -194
  97. package/src/components/dropdown-menu/DropdownMenu.astro +226 -226
  98. package/src/components/dropdown-menu/DropdownMenuCheckboxItem.astro +114 -114
  99. package/src/components/dropdown-menu/DropdownMenuContent.astro +42 -42
  100. package/src/components/dropdown-menu/DropdownMenuGroup.astro +19 -19
  101. package/src/components/dropdown-menu/DropdownMenuItem.astro +220 -220
  102. package/src/components/dropdown-menu/DropdownMenuItemContent.astro +79 -79
  103. package/src/components/dropdown-menu/DropdownMenuLabel.astro +20 -20
  104. package/src/components/dropdown-menu/DropdownMenuPortal.astro +13 -13
  105. package/src/components/dropdown-menu/DropdownMenuRadioGroup.astro +13 -13
  106. package/src/components/dropdown-menu/DropdownMenuRadioItem.astro +101 -101
  107. package/src/components/dropdown-menu/DropdownMenuSeparator.astro +18 -18
  108. package/src/components/dropdown-menu/DropdownMenuShortcut.astro +18 -18
  109. package/src/components/dropdown-menu/DropdownMenuTrigger.astro +49 -49
  110. package/src/components/dropdown-menu/dropdown-menu-item-variants.ts +24 -24
  111. package/src/components/dropdown-menu/index.ts +12 -12
  112. package/src/components/field/CHANGELOG.md +33 -33
  113. package/src/components/field/Field.astro +664 -664
  114. package/src/components/field/FieldContent.astro +20 -20
  115. package/src/components/field/FieldDescription.astro +22 -22
  116. package/src/components/field/FieldError.astro +51 -51
  117. package/src/components/field/FieldGroup.astro +20 -20
  118. package/src/components/field/FieldLabel.astro +22 -22
  119. package/src/components/field/FieldLegend.astro +23 -23
  120. package/src/components/field/FieldSeparator.astro +30 -30
  121. package/src/components/field/FieldSet.astro +20 -20
  122. package/src/components/field/FieldTitle.astro +20 -20
  123. package/src/components/field/index.ts +10 -10
  124. package/src/components/hover-card/CHANGELOG.md +20 -20
  125. package/src/components/hover-card/HoverCard.astro +235 -235
  126. package/src/components/hover-card/HoverCardContent.astro +54 -54
  127. package/src/components/hover-card/HoverCardTrigger.astro +38 -38
  128. package/src/components/hover-card/index.ts +3 -3
  129. package/src/components/input/CHANGELOG.md +44 -29
  130. package/src/components/input/Input.astro +130 -130
  131. package/src/components/input/InputOTP.astro +211 -0
  132. package/src/components/input/index.ts +2 -2
  133. package/src/components/input-group/CHANGELOG.md +49 -49
  134. package/src/components/input-group/InputGroup.astro +135 -135
  135. package/src/components/input-group/InputGroupAddon.astro +49 -49
  136. package/src/components/input-group/InputGroupButton.astro +58 -58
  137. package/src/components/input-group/InputGroupInput.astro +18 -18
  138. package/src/components/input-group/InputGroupText.astro +21 -21
  139. package/src/components/input-group/InputGroupTextarea.astro +17 -17
  140. package/src/components/input-group/controlClasses.ts +2 -2
  141. package/src/components/input-group/index.ts +6 -6
  142. package/src/components/item/CHANGELOG.md +27 -27
  143. package/src/components/item/Item.astro +122 -122
  144. package/src/components/item/ItemActions.astro +21 -21
  145. package/src/components/item/ItemContent.astro +25 -25
  146. package/src/components/item/ItemDescription.astro +25 -25
  147. package/src/components/item/ItemFooter.astro +24 -24
  148. package/src/components/item/ItemGroup.astro +24 -24
  149. package/src/components/item/ItemHeader.astro +24 -24
  150. package/src/components/item/ItemMedia.astro +47 -47
  151. package/src/components/item/ItemSeparator.astro +21 -21
  152. package/src/components/item/ItemTitle.astro +25 -25
  153. package/src/components/item/index.ts +10 -10
  154. package/src/components/kbd/CHANGELOG.md +5 -5
  155. package/src/components/kbd/Kbd.astro +145 -145
  156. package/src/components/kbd/KbdGroup.astro +55 -55
  157. package/src/components/kbd/index.ts +2 -2
  158. package/src/components/label/CHANGELOG.md +28 -28
  159. package/src/components/label/Label.astro +97 -97
  160. package/src/components/label/index.ts +2 -2
  161. package/src/components/link-group/CHANGELOG.md +75 -75
  162. package/src/components/link-group/LinkGroup.astro +67 -67
  163. package/src/components/link-group/LinkGroupItem.astro +32 -32
  164. package/src/components/link-group/LinkGroupList.astro +25 -25
  165. package/src/components/link-group/LinkGroupTitle.astro +22 -22
  166. package/src/components/link-group/index.ts +5 -5
  167. package/src/components/link-group/link-group-list-variants.ts +15 -15
  168. package/src/components/logo/CHANGELOG.md +17 -0
  169. package/src/components/logo/Logo.astro +90 -0
  170. package/src/components/logo/index.ts +3 -0
  171. package/src/components/logo/logo-paths.ts +57 -0
  172. package/src/components/marquee/CHANGELOG.md +5 -5
  173. package/src/components/marquee/Marquee.astro +119 -119
  174. package/src/components/marquee/index.ts +2 -2
  175. package/src/components/native-select/CHANGELOG.md +5 -5
  176. package/src/components/native-select/NativeSelect.astro +125 -125
  177. package/src/components/native-select/NativeSelectOptGroup.astro +14 -14
  178. package/src/components/native-select/NativeSelectOption.astro +9 -9
  179. package/src/components/native-select/index.ts +3 -3
  180. package/src/components/navigation-menu/CHANGELOG.md +63 -63
  181. package/src/components/navigation-menu/NavigationMenu.astro +414 -414
  182. package/src/components/navigation-menu/NavigationMenuContent.astro +37 -37
  183. package/src/components/navigation-menu/NavigationMenuIndicator.astro +24 -24
  184. package/src/components/navigation-menu/NavigationMenuItem.astro +22 -22
  185. package/src/components/navigation-menu/NavigationMenuLink.astro +18 -18
  186. package/src/components/navigation-menu/NavigationMenuList.astro +21 -21
  187. package/src/components/navigation-menu/NavigationMenuPositioner.astro +44 -44
  188. package/src/components/navigation-menu/NavigationMenuTrigger.astro +30 -30
  189. package/src/components/navigation-menu/NavigationMenuViewport.astro +19 -19
  190. package/src/components/navigation-menu/index.ts +10 -10
  191. package/src/components/organisms/lightning-sidebar-nav/CHANGELOG.md +50 -0
  192. package/src/components/organisms/lightning-sidebar-nav/LightningSidebarNav.astro +176 -0
  193. package/src/components/organisms/lightning-sidebar-nav/SidebarNav.astro +50 -0
  194. package/src/components/organisms/lightning-sidebar-nav/SidebarNavGroup.astro +74 -0
  195. package/src/components/organisms/lightning-sidebar-nav/SidebarNavItem.astro +94 -0
  196. package/src/components/organisms/lightning-sidebar-nav/SidebarNavProBadge.astro +26 -0
  197. package/src/components/organisms/lightning-sidebar-nav/SidebarNavSection.astro +71 -0
  198. package/src/components/organisms/lightning-sidebar-nav/SidebarNavSkeleton.astro +67 -0
  199. package/src/components/organisms/lightning-sidebar-nav/SidebarNavSubItem.astro +69 -0
  200. package/src/components/organisms/lightning-sidebar-nav/SidebarNavUsage.astro +78 -0
  201. package/src/components/organisms/lightning-sidebar-nav/SidebarNavWorkspaceAvatar.astro +46 -0
  202. package/src/components/organisms/lightning-sidebar-nav/SidebarNavWorkspaceSwitcher.astro +130 -0
  203. package/src/components/organisms/lightning-sidebar-nav/icons.ts +46 -0
  204. package/src/components/organisms/lightning-sidebar-nav/index.ts +18 -0
  205. package/src/components/organisms/lightning-sidebar-nav/types.ts +77 -0
  206. package/src/components/popover/CHANGELOG.md +20 -20
  207. package/src/components/popover/Popover.astro +211 -211
  208. package/src/components/popover/PopoverClose.astro +18 -18
  209. package/src/components/popover/PopoverContent.astro +50 -50
  210. package/src/components/popover/PopoverDescription.astro +18 -18
  211. package/src/components/popover/PopoverHeader.astro +18 -18
  212. package/src/components/popover/PopoverTitle.astro +18 -18
  213. package/src/components/popover/PopoverTrigger.astro +35 -35
  214. package/src/components/popover/index.ts +7 -7
  215. package/src/components/radio-group/CHANGELOG.md +31 -31
  216. package/src/components/radio-group/RadioGroup.astro +81 -81
  217. package/src/components/radio-group/RadioGroupItem.astro +51 -51
  218. package/src/components/radio-group/index.ts +3 -3
  219. package/src/components/select/CHANGELOG.md +39 -39
  220. package/src/components/select/Select.astro +373 -373
  221. package/src/components/select/SelectContent.astro +91 -91
  222. package/src/components/select/SelectGroup.astro +19 -19
  223. package/src/components/select/SelectItem.astro +48 -48
  224. package/src/components/select/SelectLabel.astro +18 -18
  225. package/src/components/select/SelectSeparator.astro +17 -17
  226. package/src/components/select/SelectTrigger.astro +34 -34
  227. package/src/components/select/SelectValue.astro +22 -22
  228. package/src/components/select/index.ts +8 -8
  229. package/src/components/separator/CHANGELOG.md +5 -5
  230. package/src/components/separator/Separator.astro +60 -60
  231. package/src/components/separator/index.ts +2 -2
  232. package/src/components/skeleton/CHANGELOG.md +5 -5
  233. package/src/components/skeleton/Skeleton.astro +121 -121
  234. package/src/components/skeleton/index.ts +1 -1
  235. package/src/components/slider/CHANGELOG.md +5 -5
  236. package/src/components/slider/Slider.astro +198 -198
  237. package/src/components/slider/index.ts +1 -1
  238. package/src/components/spinner/CHANGELOG.md +18 -18
  239. package/src/components/spinner/Spinner.astro +135 -135
  240. package/src/components/spinner/index.ts +1 -1
  241. package/src/components/sticky-surface/CHANGELOG.md +5 -5
  242. package/src/components/sticky-surface/StickySurface.astro +152 -152
  243. package/src/components/sticky-surface/index.ts +2 -2
  244. package/src/components/switch/CHANGELOG.md +29 -29
  245. package/src/components/switch/Switch.astro +106 -106
  246. package/src/components/switch/index.ts +1 -1
  247. package/src/components/table/CHANGELOG.md +24 -24
  248. package/src/components/table/Table.astro +358 -251
  249. package/src/components/table/TableBody.astro +17 -18
  250. package/src/components/table/TableBulkToolbar.astro +37 -0
  251. package/src/components/table/TableCaption.astro +17 -17
  252. package/src/components/table/TableCell.astro +45 -21
  253. package/src/components/table/TableCellText.astro +17 -0
  254. package/src/components/table/TableColumnMenu.astro +50 -0
  255. package/src/components/table/TableEditableCell.astro +287 -0
  256. package/src/components/table/TableEmpty.astro +17 -0
  257. package/src/components/table/TableFolderCell.astro +38 -0
  258. package/src/components/table/TableFooter.astro +21 -21
  259. package/src/components/table/TableHead.astro +90 -21
  260. package/src/components/table/TableHeader.astro +17 -17
  261. package/src/components/table/TablePagination.astro +57 -0
  262. package/src/components/table/TableRow.astro +52 -21
  263. package/src/components/table/TableSelectAllBanner.astro +34 -0
  264. package/src/components/table/TableSelectCell.astro +50 -0
  265. package/src/components/table/TableSkeletonRow.astro +21 -0
  266. package/src/components/table/index.ts +19 -9
  267. package/src/components/table/table-cell-variants.ts +29 -0
  268. package/src/components/tabs/CHANGELOG.md +5 -5
  269. package/src/components/tabs/Tabs.astro +306 -306
  270. package/src/components/tabs/TabsContent.astro +47 -47
  271. package/src/components/tabs/TabsList.astro +69 -69
  272. package/src/components/tabs/TabsTrigger.astro +40 -40
  273. package/src/components/tabs/index.ts +6 -6
  274. package/src/components/textarea/CHANGELOG.md +22 -22
  275. package/src/components/textarea/Textarea.astro +58 -58
  276. package/src/components/textarea/index.ts +2 -2
  277. package/src/components/toggle/CHANGELOG.md +23 -23
  278. package/src/components/toggle/Toggle.astro +150 -150
  279. package/src/components/toggle/index.ts +1 -1
  280. package/src/components/toggle-group/CHANGELOG.md +18 -18
  281. package/src/components/toggle-group/ToggleGroup.astro +236 -236
  282. package/src/components/toggle-group/ToggleGroupItem.astro +48 -48
  283. package/src/components/toggle-group/index.ts +2 -2
  284. package/src/components/tooltip/CHANGELOG.md +22 -22
  285. package/src/components/tooltip/Tooltip.astro +357 -357
  286. package/src/components/tooltip/TooltipContent.astro +85 -85
  287. package/src/components/tooltip/TooltipTrigger.astro +34 -34
  288. package/src/components/tooltip/index.ts +3 -3
  289. package/src/lib/table-controller.ts +1090 -0
  290. package/src/lib/toggle-group-controller.ts +113 -113
  291. package/src/lib/toggle-shared.ts +27 -27
  292. package/src/lib/utils.ts +6 -6
  293. package/src/styles/globals.css +209 -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.