@cl-light-ds/ui 0.1.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 (254) hide show
  1. package/README.md +45 -0
  2. package/package.json +59 -0
  3. package/src/components/accordion/Accordion.astro +248 -0
  4. package/src/components/accordion/AccordionContent.astro +26 -0
  5. package/src/components/accordion/AccordionItem.astro +36 -0
  6. package/src/components/accordion/AccordionTrigger.astro +118 -0
  7. package/src/components/accordion/CHANGELOG.md +41 -0
  8. package/src/components/accordion/index.ts +4 -0
  9. package/src/components/alert/Alert.astro +167 -0
  10. package/src/components/alert/AlertDescription.astro +24 -0
  11. package/src/components/alert/AlertTitle.astro +24 -0
  12. package/src/components/alert/CHANGELOG.md +5 -0
  13. package/src/components/alert/index.ts +4 -0
  14. package/src/components/avatar/Avatar.astro +197 -0
  15. package/src/components/avatar/AvatarBadge.astro +44 -0
  16. package/src/components/avatar/AvatarFallback.astro +26 -0
  17. package/src/components/avatar/AvatarGroup.astro +26 -0
  18. package/src/components/avatar/AvatarGroupCount.astro +30 -0
  19. package/src/components/avatar/AvatarImage.astro +46 -0
  20. package/src/components/avatar/CHANGELOG.md +44 -0
  21. package/src/components/avatar/index.ts +6 -0
  22. package/src/components/badge/Badge.astro +167 -0
  23. package/src/components/badge/CHANGELOG.md +49 -0
  24. package/src/components/badge/index.ts +2 -0
  25. package/src/components/breadcrumb/Breadcrumb.astro +76 -0
  26. package/src/components/breadcrumb/BreadcrumbItem.astro +32 -0
  27. package/src/components/breadcrumb/BreadcrumbList.astro +26 -0
  28. package/src/components/breadcrumb/BreadcrumbSeparator.astro +26 -0
  29. package/src/components/breadcrumb/CHANGELOG.md +24 -0
  30. package/src/components/breadcrumb/index.ts +5 -0
  31. package/src/components/button/Button.astro +233 -0
  32. package/src/components/button/CHANGELOG.md +41 -0
  33. package/src/components/button/index.ts +2 -0
  34. package/src/components/button-group/ButtonGroup.astro +130 -0
  35. package/src/components/button-group/ButtonGroupSeparator.astro +30 -0
  36. package/src/components/button-group/ButtonGroupText.astro +21 -0
  37. package/src/components/button-group/CHANGELOG.md +34 -0
  38. package/src/components/button-group/index.ts +3 -0
  39. package/src/components/card/CHANGELOG.md +119 -0
  40. package/src/components/card/Card.astro +182 -0
  41. package/src/components/card/CardAction.astro +26 -0
  42. package/src/components/card/CardContent.astro +28 -0
  43. package/src/components/card/CardDescription.astro +28 -0
  44. package/src/components/card/CardFooter.astro +24 -0
  45. package/src/components/card/CardHeader.astro +30 -0
  46. package/src/components/card/CardMedia.astro +27 -0
  47. package/src/components/card/CardOverlay.astro +32 -0
  48. package/src/components/card/CardTitle.astro +21 -0
  49. package/src/components/card/index.ts +10 -0
  50. package/src/components/carousel/CHANGELOG.md +5 -0
  51. package/src/components/carousel/Carousel.astro +106 -0
  52. package/src/components/carousel/CarouselSlide.astro +22 -0
  53. package/src/components/carousel/index.ts +3 -0
  54. package/src/components/checkbox/CHANGELOG.md +58 -0
  55. package/src/components/checkbox/Checkbox.astro +159 -0
  56. package/src/components/checkbox/index.ts +1 -0
  57. package/src/components/collapsible/CHANGELOG.md +5 -0
  58. package/src/components/collapsible/Collapsible.astro +202 -0
  59. package/src/components/collapsible/CollapsibleContent.astro +36 -0
  60. package/src/components/collapsible/CollapsibleTrigger.astro +34 -0
  61. package/src/components/collapsible/index.ts +4 -0
  62. package/src/components/combobox/CHANGELOG.md +27 -0
  63. package/src/components/combobox/Combobox.astro +365 -0
  64. package/src/components/combobox/ComboboxContent.astro +37 -0
  65. package/src/components/combobox/ComboboxEmpty.astro +18 -0
  66. package/src/components/combobox/ComboboxGroup.astro +19 -0
  67. package/src/components/combobox/ComboboxInput.astro +74 -0
  68. package/src/components/combobox/ComboboxItem.astro +39 -0
  69. package/src/components/combobox/ComboboxLabel.astro +18 -0
  70. package/src/components/combobox/ComboboxList.astro +21 -0
  71. package/src/components/combobox/ComboboxSeparator.astro +17 -0
  72. package/src/components/combobox/ComboboxTrigger.astro +30 -0
  73. package/src/components/combobox/ComboboxValue.astro +22 -0
  74. package/src/components/combobox/index.ts +11 -0
  75. package/src/components/date/CHANGELOG.md +18 -0
  76. package/src/components/date/Date.astro +137 -0
  77. package/src/components/date/index.ts +2 -0
  78. package/src/components/dialog/CHANGELOG.md +39 -0
  79. package/src/components/dialog/Dialog.astro +196 -0
  80. package/src/components/dialog/DialogClose.astro +23 -0
  81. package/src/components/dialog/DialogContent.astro +42 -0
  82. package/src/components/dialog/DialogDescription.astro +18 -0
  83. package/src/components/dialog/DialogFooter.astro +18 -0
  84. package/src/components/dialog/DialogHeader.astro +18 -0
  85. package/src/components/dialog/DialogOverlay.astro +19 -0
  86. package/src/components/dialog/DialogTitle.astro +18 -0
  87. package/src/components/dialog/DialogTrigger.astro +37 -0
  88. package/src/components/dialog/index.ts +9 -0
  89. package/src/components/dropdown-menu/CHANGELOG.md +194 -0
  90. package/src/components/dropdown-menu/DropdownMenu.astro +226 -0
  91. package/src/components/dropdown-menu/DropdownMenuCheckboxItem.astro +114 -0
  92. package/src/components/dropdown-menu/DropdownMenuContent.astro +42 -0
  93. package/src/components/dropdown-menu/DropdownMenuGroup.astro +19 -0
  94. package/src/components/dropdown-menu/DropdownMenuItem.astro +220 -0
  95. package/src/components/dropdown-menu/DropdownMenuItemContent.astro +79 -0
  96. package/src/components/dropdown-menu/DropdownMenuLabel.astro +20 -0
  97. package/src/components/dropdown-menu/DropdownMenuPortal.astro +13 -0
  98. package/src/components/dropdown-menu/DropdownMenuRadioGroup.astro +13 -0
  99. package/src/components/dropdown-menu/DropdownMenuRadioItem.astro +101 -0
  100. package/src/components/dropdown-menu/DropdownMenuSeparator.astro +18 -0
  101. package/src/components/dropdown-menu/DropdownMenuShortcut.astro +18 -0
  102. package/src/components/dropdown-menu/DropdownMenuTrigger.astro +49 -0
  103. package/src/components/dropdown-menu/dropdown-menu-item-variants.ts +24 -0
  104. package/src/components/dropdown-menu/index.ts +12 -0
  105. package/src/components/field/CHANGELOG.md +33 -0
  106. package/src/components/field/Field.astro +664 -0
  107. package/src/components/field/FieldContent.astro +20 -0
  108. package/src/components/field/FieldDescription.astro +22 -0
  109. package/src/components/field/FieldError.astro +51 -0
  110. package/src/components/field/FieldGroup.astro +20 -0
  111. package/src/components/field/FieldLabel.astro +22 -0
  112. package/src/components/field/FieldLegend.astro +23 -0
  113. package/src/components/field/FieldSeparator.astro +30 -0
  114. package/src/components/field/FieldSet.astro +20 -0
  115. package/src/components/field/FieldTitle.astro +20 -0
  116. package/src/components/field/index.ts +10 -0
  117. package/src/components/hover-card/CHANGELOG.md +20 -0
  118. package/src/components/hover-card/HoverCard.astro +235 -0
  119. package/src/components/hover-card/HoverCardContent.astro +54 -0
  120. package/src/components/hover-card/HoverCardTrigger.astro +38 -0
  121. package/src/components/hover-card/index.ts +3 -0
  122. package/src/components/input/CHANGELOG.md +29 -0
  123. package/src/components/input/Input.astro +130 -0
  124. package/src/components/input/index.ts +2 -0
  125. package/src/components/input-group/CHANGELOG.md +49 -0
  126. package/src/components/input-group/InputGroup.astro +135 -0
  127. package/src/components/input-group/InputGroupAddon.astro +49 -0
  128. package/src/components/input-group/InputGroupButton.astro +58 -0
  129. package/src/components/input-group/InputGroupInput.astro +18 -0
  130. package/src/components/input-group/InputGroupText.astro +21 -0
  131. package/src/components/input-group/InputGroupTextarea.astro +17 -0
  132. package/src/components/input-group/controlClasses.ts +2 -0
  133. package/src/components/input-group/index.ts +6 -0
  134. package/src/components/item/CHANGELOG.md +27 -0
  135. package/src/components/item/Item.astro +122 -0
  136. package/src/components/item/ItemActions.astro +21 -0
  137. package/src/components/item/ItemContent.astro +25 -0
  138. package/src/components/item/ItemDescription.astro +25 -0
  139. package/src/components/item/ItemFooter.astro +24 -0
  140. package/src/components/item/ItemGroup.astro +24 -0
  141. package/src/components/item/ItemHeader.astro +24 -0
  142. package/src/components/item/ItemMedia.astro +47 -0
  143. package/src/components/item/ItemSeparator.astro +21 -0
  144. package/src/components/item/ItemTitle.astro +25 -0
  145. package/src/components/item/index.ts +10 -0
  146. package/src/components/kbd/CHANGELOG.md +5 -0
  147. package/src/components/kbd/Kbd.astro +145 -0
  148. package/src/components/kbd/KbdGroup.astro +55 -0
  149. package/src/components/kbd/index.ts +2 -0
  150. package/src/components/label/CHANGELOG.md +28 -0
  151. package/src/components/label/Label.astro +97 -0
  152. package/src/components/label/index.ts +2 -0
  153. package/src/components/link-group/CHANGELOG.md +75 -0
  154. package/src/components/link-group/LinkGroup.astro +67 -0
  155. package/src/components/link-group/LinkGroupItem.astro +32 -0
  156. package/src/components/link-group/LinkGroupList.astro +25 -0
  157. package/src/components/link-group/LinkGroupTitle.astro +22 -0
  158. package/src/components/link-group/index.ts +5 -0
  159. package/src/components/link-group/link-group-list-variants.ts +15 -0
  160. package/src/components/marquee/CHANGELOG.md +5 -0
  161. package/src/components/marquee/Marquee.astro +119 -0
  162. package/src/components/marquee/index.ts +2 -0
  163. package/src/components/native-select/CHANGELOG.md +5 -0
  164. package/src/components/native-select/NativeSelect.astro +125 -0
  165. package/src/components/native-select/NativeSelectOptGroup.astro +14 -0
  166. package/src/components/native-select/NativeSelectOption.astro +9 -0
  167. package/src/components/native-select/index.ts +3 -0
  168. package/src/components/navigation-menu/CHANGELOG.md +63 -0
  169. package/src/components/navigation-menu/NavigationMenu.astro +414 -0
  170. package/src/components/navigation-menu/NavigationMenuContent.astro +37 -0
  171. package/src/components/navigation-menu/NavigationMenuIndicator.astro +24 -0
  172. package/src/components/navigation-menu/NavigationMenuItem.astro +22 -0
  173. package/src/components/navigation-menu/NavigationMenuLink.astro +18 -0
  174. package/src/components/navigation-menu/NavigationMenuList.astro +21 -0
  175. package/src/components/navigation-menu/NavigationMenuPositioner.astro +44 -0
  176. package/src/components/navigation-menu/NavigationMenuTrigger.astro +30 -0
  177. package/src/components/navigation-menu/NavigationMenuViewport.astro +19 -0
  178. package/src/components/navigation-menu/index.ts +10 -0
  179. package/src/components/popover/CHANGELOG.md +5 -0
  180. package/src/components/popover/Popover.astro +210 -0
  181. package/src/components/popover/PopoverClose.astro +18 -0
  182. package/src/components/popover/PopoverContent.astro +49 -0
  183. package/src/components/popover/PopoverDescription.astro +18 -0
  184. package/src/components/popover/PopoverHeader.astro +18 -0
  185. package/src/components/popover/PopoverTitle.astro +18 -0
  186. package/src/components/popover/PopoverTrigger.astro +29 -0
  187. package/src/components/popover/index.ts +7 -0
  188. package/src/components/radio-group/CHANGELOG.md +9 -0
  189. package/src/components/radio-group/RadioGroup.astro +81 -0
  190. package/src/components/radio-group/RadioGroupItem.astro +42 -0
  191. package/src/components/radio-group/index.ts +3 -0
  192. package/src/components/select/CHANGELOG.md +39 -0
  193. package/src/components/select/Select.astro +373 -0
  194. package/src/components/select/SelectContent.astro +91 -0
  195. package/src/components/select/SelectGroup.astro +19 -0
  196. package/src/components/select/SelectItem.astro +48 -0
  197. package/src/components/select/SelectLabel.astro +18 -0
  198. package/src/components/select/SelectSeparator.astro +17 -0
  199. package/src/components/select/SelectTrigger.astro +34 -0
  200. package/src/components/select/SelectValue.astro +22 -0
  201. package/src/components/select/index.ts +8 -0
  202. package/src/components/separator/CHANGELOG.md +5 -0
  203. package/src/components/separator/Separator.astro +60 -0
  204. package/src/components/separator/index.ts +2 -0
  205. package/src/components/skeleton/CHANGELOG.md +5 -0
  206. package/src/components/skeleton/Skeleton.astro +121 -0
  207. package/src/components/skeleton/index.ts +1 -0
  208. package/src/components/slider/CHANGELOG.md +5 -0
  209. package/src/components/slider/Slider.astro +198 -0
  210. package/src/components/slider/index.ts +1 -0
  211. package/src/components/spinner/CHANGELOG.md +5 -0
  212. package/src/components/spinner/Spinner.astro +134 -0
  213. package/src/components/spinner/index.ts +1 -0
  214. package/src/components/sticky-surface/CHANGELOG.md +5 -0
  215. package/src/components/sticky-surface/StickySurface.astro +152 -0
  216. package/src/components/sticky-surface/index.ts +2 -0
  217. package/src/components/switch/CHANGELOG.md +9 -0
  218. package/src/components/switch/Switch.astro +106 -0
  219. package/src/components/switch/index.ts +1 -0
  220. package/src/components/table/CHANGELOG.md +5 -0
  221. package/src/components/table/Table.astro +250 -0
  222. package/src/components/table/TableBody.astro +18 -0
  223. package/src/components/table/TableCaption.astro +17 -0
  224. package/src/components/table/TableCell.astro +21 -0
  225. package/src/components/table/TableFooter.astro +21 -0
  226. package/src/components/table/TableHead.astro +21 -0
  227. package/src/components/table/TableHeader.astro +17 -0
  228. package/src/components/table/TableRow.astro +21 -0
  229. package/src/components/table/index.ts +9 -0
  230. package/src/components/tabs/CHANGELOG.md +5 -0
  231. package/src/components/tabs/Tabs.astro +306 -0
  232. package/src/components/tabs/TabsContent.astro +47 -0
  233. package/src/components/tabs/TabsList.astro +69 -0
  234. package/src/components/tabs/TabsTrigger.astro +40 -0
  235. package/src/components/tabs/index.ts +6 -0
  236. package/src/components/textarea/CHANGELOG.md +5 -0
  237. package/src/components/textarea/Textarea.astro +36 -0
  238. package/src/components/textarea/index.ts +2 -0
  239. package/src/components/toggle/CHANGELOG.md +5 -0
  240. package/src/components/toggle/Toggle.astro +138 -0
  241. package/src/components/toggle/index.ts +1 -0
  242. package/src/components/toggle-group/CHANGELOG.md +5 -0
  243. package/src/components/toggle-group/ToggleGroup.astro +224 -0
  244. package/src/components/toggle-group/ToggleGroupItem.astro +48 -0
  245. package/src/components/toggle-group/index.ts +2 -0
  246. package/src/components/tooltip/CHANGELOG.md +5 -0
  247. package/src/components/tooltip/Tooltip.astro +331 -0
  248. package/src/components/tooltip/TooltipContent.astro +60 -0
  249. package/src/components/tooltip/TooltipTrigger.astro +34 -0
  250. package/src/components/tooltip/index.ts +3 -0
  251. package/src/lib/toggle-group-controller.ts +113 -0
  252. package/src/lib/toggle-shared.ts +26 -0
  253. package/src/lib/utils.ts +6 -0
  254. package/src/styles/globals.css +177 -0
package/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # @cl-light-ds/ui
2
+
3
+ ClickLearn Lightning Design System — a library of Astro UI components.
4
+
5
+ ## Requirements
6
+
7
+ Your project needs Astro 7+ and Tailwind CSS v4 already set up.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install @cl-light-ds/ui
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ Import the design tokens once, e.g. in your root layout:
18
+
19
+ ```astro
20
+ ---
21
+ import "@cl-light-ds/ui/globals.css";
22
+ ---
23
+ ```
24
+
25
+ Then import components from their individual paths:
26
+
27
+ ```astro
28
+ ---
29
+ import { Button } from "@cl-light-ds/ui/components/button";
30
+ ---
31
+
32
+ <Button>Click me</Button>
33
+ ```
34
+
35
+ Tailwind v4 needs to see these component files to extract their classes. Add a `@source` directive pointing at the
36
+ package inside your own global stylesheet:
37
+
38
+ ```css
39
+ @import "tailwindcss";
40
+ @import "@cl-light-ds/ui/globals.css";
41
+
42
+ @source "../node_modules/@cl-light-ds/ui/src/**/*.{astro,ts}";
43
+ ```
44
+
45
+ (Adjust the relative path to match where your stylesheet lives relative to `node_modules`.)
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@cl-light-ds/ui",
3
+ "version": "0.1.0",
4
+ "description": "ClickLearn Lightning Design System — Astro UI component library.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "files": [
8
+ "src"
9
+ ],
10
+ "exports": {
11
+ "./globals.css": "./src/styles/globals.css",
12
+ "./lib/*": "./src/lib/*.ts",
13
+ "./components/*": "./src/components/*.ts"
14
+ },
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "scripts": {
19
+ "lint": "eslint . --max-warnings 0"
20
+ },
21
+ "peerDependencies": {
22
+ "astro": "^7.0.6",
23
+ "tailwindcss": "^4.1.17"
24
+ },
25
+ "devDependencies": {
26
+ "@repo/eslint-config": "*",
27
+ "@repo/typescript-config": "*",
28
+ "@types/node": "^22.15.3",
29
+ "astro": "^7.0.6",
30
+ "eslint": "^9.34.0",
31
+ "shadcn": "^4.19.1",
32
+ "tailwindcss": "^4.1.17",
33
+ "tw-animate-css": "^1.4.0",
34
+ "typescript": "^5.9.3"
35
+ },
36
+ "dependencies": {
37
+ "@data-slot/accordion": "^0.2.166",
38
+ "@data-slot/collapsible": "^0.2.166",
39
+ "@data-slot/combobox": "^0.2.166",
40
+ "@data-slot/dialog": "^0.2.166",
41
+ "@data-slot/dropdown-menu": "^0.2.166",
42
+ "@data-slot/hover-card": "^0.2.166",
43
+ "@data-slot/navigation-menu": "^0.2.166",
44
+ "@data-slot/popover": "^0.2.166",
45
+ "@data-slot/radio-group": "^0.2.166",
46
+ "@data-slot/select": "^0.2.166",
47
+ "@data-slot/slider": "^0.2.166",
48
+ "@data-slot/switch": "^0.2.166",
49
+ "@data-slot/tabs": "^0.2.166",
50
+ "@data-slot/toggle": "^0.2.166",
51
+ "@data-slot/toggle-group": "^0.2.166",
52
+ "@data-slot/tooltip": "^0.2.166",
53
+ "@lucide/astro": "^1.14.0",
54
+ "bejamas": "^0.4.1",
55
+ "class-variance-authority": "^0.7.1",
56
+ "clsx": "^2.1.1",
57
+ "tailwind-merge": "^3.6.0"
58
+ }
59
+ }
@@ -0,0 +1,248 @@
1
+ ---
2
+ /**
3
+ * @component Accordion
4
+ * @title Accordion
5
+ * @description Vertically stacked collapsible sections that let users show and hide content panels.
6
+ * @figmaUrl https://www.figma.com/design/qXkzdqZ3QPQqgckU3AwIAH/ClickLearn-Lightning-Design-Library?node-id=133-7547
7
+ *
8
+ * @preview
9
+ *
10
+ * <Accordion class="w-full max-w-[420px] self-start mt-10" defaultValue="accordion-item-1">
11
+ * <AccordionItem value="accordion-item-1">
12
+ * <AccordionTrigger icon={List}>
13
+ * Is it accessible?
14
+ * </AccordionTrigger>
15
+ * <AccordionContent>
16
+ * Yes. It adheres to WAI-ARIA design patterns.
17
+ * </AccordionContent>
18
+ * </AccordionItem>
19
+ * <AccordionItem value="accordion-item-2">
20
+ * <AccordionTrigger badge="New">
21
+ * Can I customize the icon?
22
+ * </AccordionTrigger>
23
+ * <AccordionContent>
24
+ * Yes you can.
25
+ * </AccordionContent>
26
+ * </AccordionItem>
27
+ * </Accordion>
28
+ *
29
+ * <Accordion class="w-full max-w-[420px] self-start mt-10" shape="rounded" defaultValue="accordion-item-1">
30
+ * <AccordionItem value="accordion-item-1">
31
+ * <AccordionTrigger>
32
+ * Is it accessible?
33
+ * </AccordionTrigger>
34
+ * <AccordionContent>
35
+ * Yes. It adheres to WAI-ARIA design patterns.
36
+ * </AccordionContent>
37
+ * </AccordionItem>
38
+ * <AccordionItem value="accordion-item-2" disabled>
39
+ * <AccordionTrigger>
40
+ * Can I customize the icon?
41
+ * </AccordionTrigger>
42
+ * <AccordionContent>
43
+ * Yes you can.
44
+ * </AccordionContent>
45
+ * </AccordionItem>
46
+ * </Accordion>
47
+ *
48
+ * @usage
49
+ *
50
+ * ```astro nocollapse
51
+ * ---
52
+ * import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@bejamas/ui/components/accordion';
53
+ * ---
54
+ *
55
+ * <Accordion class="w-full max-w-[420px] self-start" defaultValue="accordion-item-1">
56
+ * <AccordionItem value="accordion-item-1">
57
+ * <AccordionTrigger>
58
+ * Is it accessible?
59
+ * </AccordionTrigger>
60
+ * <AccordionContent>
61
+ * Yes. It adheres to WAI-ARIA design patterns.
62
+ * </AccordionContent>
63
+ * </AccordionItem>
64
+ * </Accordion>
65
+ * ```
66
+ *
67
+ * @api
68
+ *
69
+ * ### Events
70
+ *
71
+ * The accordion emits custom events that you can listen to:
72
+ *
73
+ * | Event | Detail | Description |
74
+ * |-------|--------|-------------|
75
+ * | `accordion:change` | `{ value: string[] }` | Fired when expanded items change |
76
+ *
77
+ * ```astro nocollapse
78
+ * <Accordion id="my-accordion">
79
+ * <AccordionItem value="item-1">
80
+ * <AccordionTrigger>Item 1</AccordionTrigger>
81
+ * <AccordionContent>Content 1</AccordionContent>
82
+ * </AccordionItem>
83
+ * </Accordion>
84
+ * ```
85
+ *
86
+ * ```js nocollapse
87
+ * const accordion = document.getElementById('my-accordion');
88
+ *
89
+ * accordion.addEventListener('accordion:change', (e) => {
90
+ * console.log('Expanded items:', e.detail.value);
91
+ * });
92
+ * ```
93
+ *
94
+ * ### Programmatic Control
95
+ *
96
+ * You can control the accordion programmatically by dispatching an `accordion:set` event:
97
+ *
98
+ * ```js nocollapse
99
+ * const accordion = document.getElementById('my-accordion');
100
+ *
101
+ * // Expand a single item
102
+ * accordion.dispatchEvent(new CustomEvent('accordion:set', {
103
+ * detail: { value: 'item-1' }
104
+ * }));
105
+ *
106
+ * // Expand multiple items (when multiple prop is true)
107
+ * accordion.dispatchEvent(new CustomEvent('accordion:set', {
108
+ * detail: { value: ['item-1', 'item-2'] }
109
+ * }));
110
+ * ```
111
+ *
112
+ * ### Data Attributes
113
+ *
114
+ * The accordion sets these data attributes that you can use for styling or querying state:
115
+ *
116
+ * | Attribute | Element | Description |
117
+ * |-----------|---------|-------------|
118
+ * | `data-state` | accordion-item | Current state (`open` or `closed`) |
119
+ * | `data-shape` | accordion | Current shape (`default`, `flush`, or `rounded`) |
120
+ * | `data-disabled` | accordion-item | Present when the item is disabled |
121
+ *
122
+ * @examples
123
+ *
124
+ * ### Rounded shape
125
+ *
126
+ * <Accordion class="w-full max-w-[420px] self-start" shape="rounded" defaultValue="accordion-item-1">
127
+ * <AccordionItem value="accordion-item-1">
128
+ * <AccordionTrigger>
129
+ * Is it accessible?
130
+ * </AccordionTrigger>
131
+ * <AccordionContent>
132
+ * Yes. It adheres to WAI-ARIA design patterns.
133
+ * </AccordionContent>
134
+ * </AccordionItem>
135
+ * <AccordionItem value="accordion-item-2">
136
+ * <AccordionTrigger>
137
+ * Can I customize the icon?
138
+ * </AccordionTrigger>
139
+ * <AccordionContent>
140
+ * Yes you can.
141
+ * </AccordionContent>
142
+ * </AccordionItem>
143
+ * </Accordion>
144
+ *
145
+ * ### Disabled item
146
+ *
147
+ * <Accordion class="w-full max-w-[420px] self-start" defaultValue="accordion-item-1">
148
+ * <AccordionItem value="accordion-item-1" disabled>
149
+ * <AccordionTrigger>
150
+ * This item can't be expanded
151
+ * </AccordionTrigger>
152
+ * <AccordionContent>
153
+ * Hidden content.
154
+ * </AccordionContent>
155
+ * </AccordionItem>
156
+ * </Accordion>
157
+ *
158
+ * ### Multiple choice accordion
159
+ *
160
+ * <Accordion class="w-full max-w-[420px] self-start" multiple defaultValue={["accordion-item-1"]}>
161
+ * <AccordionItem value="accordion-item-1">
162
+ * <AccordionTrigger>
163
+ * Is it accessible?
164
+ * </AccordionTrigger>
165
+ * <AccordionContent>
166
+ * Yes. It adheres to WAI-ARIA design patterns.
167
+ * </AccordionContent>
168
+ * </AccordionItem>
169
+ * <AccordionItem value="accordion-item-2">
170
+ * <AccordionTrigger>
171
+ * Can I customize the icon?
172
+ * </AccordionTrigger>
173
+ * <AccordionContent>
174
+ * Yes you can.
175
+ * </AccordionContent>
176
+ * </AccordionItem>
177
+ * <AccordionItem value="accordion-item-3">
178
+ * <AccordionTrigger>
179
+ * Can I customize the icon?
180
+ * </AccordionTrigger>
181
+ * <AccordionContent>
182
+ * Yes you can.
183
+ * </AccordionContent>
184
+ * </AccordionItem>
185
+ * </Accordion>
186
+ *
187
+ */
188
+
189
+ import { cva } from "class-variance-authority";
190
+ import { cn } from "@cl-light-ds/ui/lib/utils";
191
+ import type { HTMLAttributes } from "astro/types";
192
+
193
+ type AccordionShape = "default" | "flush" | "rounded";
194
+
195
+ interface Props extends HTMLAttributes<"div"> {
196
+ class?: string;
197
+ multiple?: boolean;
198
+ defaultValue?: string | string[];
199
+ collapsible?: boolean;
200
+ shape?: AccordionShape;
201
+ }
202
+
203
+ const {
204
+ class: className = "",
205
+ multiple = false,
206
+ defaultValue,
207
+ collapsible = true,
208
+ shape = "default",
209
+ ...rest
210
+ } = Astro.props as Props;
211
+
212
+ const rootDefaultValue = Array.isArray(defaultValue)
213
+ ? JSON.stringify(defaultValue)
214
+ : defaultValue;
215
+
216
+ const accordionVariants = cva("group/accordion flex w-full flex-col", {
217
+ variants: {
218
+ shape: {
219
+ default: "gap-0",
220
+ flush: "gap-0",
221
+ rounded: "gap-2",
222
+ },
223
+ },
224
+ defaultVariants: {
225
+ shape: "default",
226
+ },
227
+ });
228
+ ---
229
+
230
+ <div
231
+ {...rest}
232
+ data-slot="accordion"
233
+ data-multiple={multiple ? "true" : undefined}
234
+ data-default-value={rootDefaultValue}
235
+ data-collapsible={collapsible ? undefined : "false"}
236
+ data-shape={shape}
237
+ class={cn(accordionVariants({ shape }), className)}
238
+ >
239
+ <slot />
240
+ </div>
241
+
242
+ <script>
243
+ import { createAccordion } from "@data-slot/accordion";
244
+
245
+ document.querySelectorAll('[data-slot="accordion"]').forEach((el) => {
246
+ createAccordion(el);
247
+ });
248
+ </script>
@@ -0,0 +1,26 @@
1
+ ---
2
+ import { cn } from "@cl-light-ds/ui/lib/utils";
3
+ import type { HTMLAttributes } from "astro/types";
4
+
5
+ interface Props extends HTMLAttributes<"div"> {
6
+ class?: string;
7
+ }
8
+
9
+ const { class: className = "", ...rest } = Astro.props as Props;
10
+ ---
11
+
12
+ <div
13
+ {...rest}
14
+ data-slot="accordion-content"
15
+ hidden
16
+ class="data-open:animate-accordion-down data-closed:animate-accordion-up text-muted-foreground text-xs overflow-hidden"
17
+ >
18
+ <div
19
+ class={cn(
20
+ "pr-3 pl-(--accordion-indent,--spacing(3)) pt-1 pb-3 h-(--accordion-panel-height) data-ending-style:h-0 data-starting-style:h-0 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4",
21
+ className,
22
+ )}
23
+ >
24
+ <slot />
25
+ </div>
26
+ </div>
@@ -0,0 +1,36 @@
1
+ ---
2
+ import { cn } from "@cl-light-ds/ui/lib/utils";
3
+ import type { HTMLAttributes } from "astro/types";
4
+
5
+ interface Props extends HTMLAttributes<"div"> {
6
+ value: string;
7
+ class?: string;
8
+ disabled?: boolean;
9
+ }
10
+
11
+ const {
12
+ value,
13
+ class: className = "",
14
+ disabled = false,
15
+ ...rest
16
+ } = Astro.props as Props;
17
+ ---
18
+
19
+ <div
20
+ {...rest}
21
+ data-value={value}
22
+ data-slot="accordion-item"
23
+ data-disabled={disabled ? "" : undefined}
24
+ aria-disabled={disabled ? "true" : undefined}
25
+ class={cn(
26
+ "group/accordion-item",
27
+ "[--accordion-indent:--spacing(3)] has-data-[slot=accordion-trigger-lead-icon]:[--accordion-indent:--spacing(9)]",
28
+ "group-data-[shape=default]/accordion:not-last:border-b group-data-[shape=default]/accordion:border-border",
29
+ "group-data-[shape=rounded]/accordion:rounded-lg group-data-[shape=rounded]/accordion:border group-data-[shape=rounded]/accordion:border-border group-data-[shape=rounded]/accordion:bg-card",
30
+ "has-[[data-slot=accordion-trigger]:focus-visible]:relative has-[[data-slot=accordion-trigger]:focus-visible]:z-10 has-[[data-slot=accordion-trigger]:focus-visible]:border has-[[data-slot=accordion-trigger]:focus-visible]:border-ring has-[[data-slot=accordion-trigger]:focus-visible]:ring-3 has-[[data-slot=accordion-trigger]:focus-visible]:ring-ring/50 has-[[data-slot=accordion-trigger]:focus-visible]:bg-card",
31
+ "data-disabled:opacity-50",
32
+ className,
33
+ )}
34
+ >
35
+ <slot />
36
+ </div>
@@ -0,0 +1,118 @@
1
+ ---
2
+ import { cva } from "class-variance-authority";
3
+ import { Plus, Minus, ChevronDown, ChevronUp } from "@lucide/astro";
4
+ import type { AstroComponent } from "@lucide/astro";
5
+ import Badge from "../badge/Badge.astro";
6
+ import { cn } from "@cl-light-ds/ui/lib/utils";
7
+ import type { HTMLAttributes } from "astro/types";
8
+
9
+ type IndicatorIcon = "plus-minus" | "chevron";
10
+
11
+ interface Props extends HTMLAttributes<"button"> {
12
+ class?: string;
13
+ /** Radix-like: render wrapper so the child can be the interactive element */
14
+ asChild?: boolean;
15
+ /** Leading icon rendered before the label (e.g. a lucide-astro icon). */
16
+ icon?: AstroComponent;
17
+ /** Optional badge/pill rendered next to the label. */
18
+ badge?: string | number;
19
+ disabled?: boolean;
20
+ /** Style of the built-in expand/collapse indicator. Ignored when a custom `icon` slot is provided. */
21
+ indicatorIcon?: IndicatorIcon;
22
+ }
23
+
24
+ const {
25
+ class: className = "",
26
+ asChild = false,
27
+ type = "button",
28
+ icon,
29
+ badge,
30
+ disabled = false,
31
+ indicatorIcon = "plus-minus",
32
+ ...rest
33
+ } = Astro.props as Props;
34
+
35
+ const Icon = icon;
36
+ const hasBadge = badge !== undefined && badge !== null;
37
+ const [CollapsedIndicator, ExpandedIndicator] =
38
+ indicatorIcon === "chevron" ? [ChevronDown, ChevronUp] : [Plus, Minus];
39
+
40
+ const triggerVariants = cva(
41
+ "**:data-[slot=accordion-trigger-icon]:text-muted-foreground rounded-md p-3 aria-expanded:pb-1 text-left text-xs font-semibold hover:underline **:data-[slot=accordion-trigger-icon]:size-4 group/accordion-trigger relative flex flex-1 items-start justify-between gap-2 transition-all outline-none aria-disabled:pointer-events-none aria-disabled:opacity-50 group-data-disabled/accordion-item:pointer-events-none group-data-disabled/accordion-item:opacity-50",
42
+ );
43
+ ---
44
+
45
+ {
46
+ asChild ? (
47
+ <div class="flex">
48
+ <div
49
+ data-slot="accordion-trigger"
50
+ data-as-child
51
+ class={cn(triggerVariants(), className)}
52
+ >
53
+ <slot />
54
+ </div>
55
+ </div>
56
+ ) : (
57
+ <div class="flex">
58
+ <button
59
+ {...rest}
60
+ type={type}
61
+ aria-disabled={disabled ? "true" : undefined}
62
+ data-slot="accordion-trigger"
63
+ class={cn(triggerVariants(), className)}
64
+ >
65
+ <span class="flex flex-1 items-center gap-2">
66
+ {
67
+ Icon && (
68
+ <span
69
+ data-slot="accordion-trigger-lead-icon"
70
+ class="text-foreground pointer-events-none size-4 shrink-0"
71
+ >
72
+ <Icon class="size-4" />
73
+ </span>
74
+ )
75
+ }
76
+ <span class="flex items-center gap-1.5">
77
+ <slot />
78
+ {
79
+ hasBadge && (
80
+ <Badge
81
+ data-slot="accordion-trigger-badge"
82
+ variant="outline"
83
+ shape="pill"
84
+ size="sm"
85
+ >
86
+ {badge}
87
+ </Badge>
88
+ )
89
+ }
90
+ </span>
91
+ </span>
92
+ {
93
+ Astro.slots.has("icon") ? (
94
+ <span
95
+ data-slot="accordion-trigger-icon"
96
+ class="pointer-events-none shrink-0"
97
+ >
98
+ <slot name="icon" />
99
+ </span>
100
+ ) : (
101
+ <>
102
+ <CollapsedIndicator
103
+ data-slot="accordion-trigger-icon"
104
+ class="pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden"
105
+ aria-hidden="true"
106
+ />
107
+ <ExpandedIndicator
108
+ data-slot="accordion-trigger-icon"
109
+ class="pointer-events-none hidden shrink-0 group-aria-expanded/accordion-trigger:inline"
110
+ aria-hidden="true"
111
+ />
112
+ </>
113
+ )
114
+ }
115
+ </button>
116
+ </div>
117
+ )
118
+ }
@@ -0,0 +1,41 @@
1
+ # Changelog
2
+
3
+ All notable changes to the `Accordion` component family (`Accordion`, `AccordionItem`, `AccordionTrigger`, `AccordionContent`) are documented in this file.
4
+
5
+ ## 2026-09-08 — Figma alignment (ClickLearn Lightning Design Library, node `133-7547`)
6
+
7
+ Aligned the component visually and functionally with Figma, while preserving the existing 4-part structure and all pre-existing props.
8
+
9
+ ### Added
10
+
11
+ - `Accordion`: `shape` prop (`"default" | "flush" | "rounded"`) — `default` keeps the bottom-border divider list, `flush` removes dividers entirely, `rounded` renders each item as its own bordered, rounded card with an 8px gap between items.
12
+ - `AccordionItem`: `disabled` prop.
13
+ - `AccordionTrigger`:
14
+ - `icon` — leading icon rendered before the label (e.g. a lucide-astro icon component).
15
+ - `badge` — optional pill (now backed by the shared `Badge` component: `variant="outline" shape="pill" size="sm"`) rendered next to the label.
16
+ - `disabled` prop.
17
+ - `indicatorIcon` (`"plus-minus" | "chevron"`, default `"plus-minus"`) — style of the built-in expand/collapse indicator.
18
+
19
+ ### Changed
20
+
21
+ - `AccordionTrigger`: replaced the hardcoded chevron up/down indicator with a Plus/Minus swap by default (matches Figma; chevron still available via `indicatorIcon="chevron"`).
22
+ - `AccordionTrigger`: padding `py-4` → `p-3`; bottom padding reduces to `pb-1` when expanded, tightening the header-to-body gap.
23
+ - `AccordionTrigger` / `AccordionContent`: label and caption text size `text-sm` → `text-xs` (12px), matching Figma's actual type token (this design system's `text-sm` utility is 14px).
24
+ - `AccordionContent`: caption color now explicit `text-muted-foreground` (previously inherited the default dark foreground color).
25
+ - `AccordionContent`: horizontal padding now `pr-3 pl-(--accordion-indent, --spacing(3))` — a shared `--accordion-indent` CSS variable (set on `AccordionItem`, `--spacing(3)` by default, `--spacing(9)` when the trigger has a lead icon) so the body text aligns under the label, not under the lead icon.
26
+ - `AccordionContent`: `pb-4` → `pb-3` (12px); `pt-0` → `pt-1` (4px) — combined with the trigger's `aria-expanded:pb-1`, the header-to-body gap is 8px total.
27
+ - `AccordionItem`: shape-driven classes for border/radius/background (`default` → `border-b`, `rounded` → `border` + `rounded-lg` + `bg-card`, `flush` → none).
28
+ - Focus ring moved from the trigger button to `AccordionItem` (via `has-[[data-slot=accordion-trigger]:focus-visible]:*`), so a focused item's ring wraps the whole box — including the expanded caption — not just the header row. Reverted an interim change that used `focus:` (any pointer/click focus); it is `focus-visible:` only, so a mouse click does not show the ring.
29
+ - Fixed the malformed `@figmaUrl` JSDoc (previously two concatenated URLs) to the correct single ClickLearn Lightning Design Library link.
30
+
31
+ ### Fixed
32
+
33
+ - Lead icon color: was `text-muted-foreground` (gray); Figma's actual asset is `text-foreground` (dark, matching the label).
34
+ - Lead icon size: the `<svg>` was rendering at its native 24px inside a 20px (later 16px) wrapper span, because the size class was only applied to the wrapper, not the icon itself — silently eating into the icon-to-label gap. Fixed by passing the size class directly to the icon component.
35
+ - Badge text picked up the trigger's `hover:underline` (text-decoration propagates to inline descendants). Added `no-underline` — currently not present after switching the badge to the shared `Badge` component with no `class` override, so this regressed; needs revisiting if the badge should stay non-underlined on hover.
36
+
37
+ ### Notes
38
+
39
+ - `shape` lives only on the `Accordion` root (cascades to all items uniformly) — Figma's "Nested" demo renders identically to "Rounded", so it isn't a distinct shape value.
40
+ - `disabled`, `badge`, and the `flush` shape value have no dedicated demo frame in the Figma file; they were implemented using the design system's existing muted/border tokens rather than a pixel-exact spec.
41
+ - All spacing values are token-based (Tailwind's `--spacing` scale) or reference `globals.css` color tokens — no hardcoded arbitrary pixel/rem/hex values remain in the four component files.
@@ -0,0 +1,4 @@
1
+ export { default as Accordion } from "./Accordion.astro";
2
+ export { default as AccordionItem } from "./AccordionItem.astro";
3
+ export { default as AccordionTrigger } from "./AccordionTrigger.astro";
4
+ export { default as AccordionContent } from "./AccordionContent.astro";