@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,37 @@
1
+ ---
2
+ import { X } from "@lucide/astro";
3
+ import { cn } from "@cl-light-ds/ui/lib/utils";
4
+ import type { HTMLAttributes } from "astro/types";
5
+ import { Badge } from "../badge";
6
+
7
+ interface Props extends HTMLAttributes<"div"> {
8
+ class?: string;
9
+ }
10
+
11
+ const { class: className = "", ...rest } = Astro.props as Props;
12
+ ---
13
+
14
+ <div
15
+ data-slot="table-bulk-toolbar"
16
+ role="toolbar"
17
+ aria-label="Bulk actions"
18
+ class={cn(
19
+ "flex min-h-14 items-center justify-between gap-3 rounded-lg border border-primary/15 bg-table-row-selected px-4 py-2",
20
+ className,
21
+ )}
22
+ {...rest}
23
+ >
24
+ <Badge
25
+ as="button"
26
+ type="button"
27
+ data-table-action="clear-selection"
28
+ aria-label="Clear selection"
29
+ class="cursor-pointer"
30
+ >
31
+ <span><span data-slot="table-selection-count">0</span> selected</span>
32
+ <X slot="tail-icon" aria-hidden="true" />
33
+ </Badge>
34
+ <div class="flex items-center gap-3">
35
+ <slot />
36
+ </div>
37
+ </div>
@@ -1,17 +1,17 @@
1
- ---
2
- import { cn } from "@cl-light-ds/ui/lib/utils";
3
- import type { HTMLAttributes } from "astro/types";
4
-
5
- interface Props extends HTMLAttributes<"caption"> {
6
- class?: string;
7
- }
8
-
9
- const {
10
- class: className = "",
11
- ...rest
12
- } = Astro.props as Props;
13
- ---
14
-
15
- <caption data-slot="table-caption" class={cn("text-muted-foreground mt-4 text-sm", className)} {...rest}>
16
- <slot />
17
- </caption>
1
+ ---
2
+ import { cn } from "@cl-light-ds/ui/lib/utils";
3
+ import type { HTMLAttributes } from "astro/types";
4
+
5
+ interface Props extends HTMLAttributes<"caption"> {
6
+ class?: string;
7
+ }
8
+
9
+ const {
10
+ class: className = "",
11
+ ...rest
12
+ } = Astro.props as Props;
13
+ ---
14
+
15
+ <caption data-slot="table-caption" class={cn("text-muted-foreground mt-4 text-sm", className)} {...rest}>
16
+ <slot />
17
+ </caption>
@@ -1,21 +1,45 @@
1
- ---
2
- import { cn } from "@cl-light-ds/ui/lib/utils";
3
- import type { HTMLAttributes } from "astro/types";
4
-
5
- interface Props extends HTMLAttributes<"td"> {
6
- class?: string;
7
- }
8
-
9
- const {
10
- class: className = "",
11
- ...rest
12
- } = Astro.props as Props;
13
- ---
14
-
15
- <td
16
- data-slot="table-cell"
17
- class={cn("p-2 align-middle whitespace-nowrap font-medium [&:has([role=checkbox])]:pr-0", className)}
18
- {...rest}
19
- >
20
- <slot />
21
- </td>
1
+ ---
2
+ import { cn } from "@cl-light-ds/ui/lib/utils";
3
+ import type { HTMLAttributes } from "astro/types";
4
+ import { cellAlign, cellBase, levelIndentStyle, type CellAlign } from "./table-cell-variants";
5
+
6
+ interface Props extends HTMLAttributes<"td"> {
7
+ class?: string;
8
+ /** Column key, matched against `TableHead` `column` for hide/pin/resize. */
9
+ column?: string;
10
+ align?: CellAlign;
11
+ /** Number content: right-aligned, semibold, tabular figures. */
12
+ numeric?: boolean;
13
+ /** Nesting level (1–3). Indents the cell content 20px per level. */
14
+ level?: 1 | 2 | 3;
15
+ }
16
+
17
+ const {
18
+ class: className = "",
19
+ column,
20
+ numeric = false,
21
+ align = numeric ? "right" : "left",
22
+ level,
23
+ style,
24
+ ...rest
25
+ } = Astro.props as Props;
26
+
27
+ const indent = levelIndentStyle(level);
28
+ ---
29
+
30
+ <td
31
+ data-slot="table-cell"
32
+ data-column={column}
33
+ style={indent ? [indent, typeof style === "string" ? style : ""].filter(Boolean).join("; ") : style}
34
+ class={cn(
35
+ cellBase,
36
+ cellAlign({ align }),
37
+ "h-12 py-2 font-medium",
38
+ numeric && "font-semibold tabular-nums",
39
+ "[&:has([type=checkbox])]:w-15 [&:has([type=checkbox])]:text-center",
40
+ className,
41
+ )}
42
+ {...rest}
43
+ >
44
+ <slot />
45
+ </td>
@@ -0,0 +1,17 @@
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
+ /** Secondary line under the label (Figma "2-Line Text"). */
8
+ subtitle?: string;
9
+ }
10
+
11
+ const { class: className = "", subtitle, ...rest } = Astro.props as Props;
12
+ ---
13
+
14
+ <div data-slot="table-cell-text" class={cn("flex min-w-0 flex-col gap-0.5", className)} {...rest}>
15
+ <span class="truncate text-sm leading-5 font-medium text-foreground"><slot /></span>
16
+ {subtitle && <span class="truncate text-xs leading-4 font-normal text-muted-foreground">{subtitle}</span>}
17
+ </div>
@@ -0,0 +1,50 @@
1
+ ---
2
+ import { Columns3 } from "@lucide/astro";
3
+ import {
4
+ DropdownMenu,
5
+ DropdownMenuCheckboxItem,
6
+ DropdownMenuContent,
7
+ DropdownMenuLabel,
8
+ DropdownMenuTrigger,
9
+ } from "../dropdown-menu";
10
+
11
+ interface ColumnOption {
12
+ column: string;
13
+ label: string;
14
+ /** Initially hidden. */
15
+ hidden?: boolean;
16
+ /** Always visible (e.g. the name column). */
17
+ disabled?: boolean;
18
+ }
19
+
20
+ interface Props {
21
+ columns: ColumnOption[];
22
+ label?: string;
23
+ class?: string;
24
+ }
25
+
26
+ const { columns, label = "Columns", class: className = "" } = Astro.props as Props;
27
+ ---
28
+
29
+ <DropdownMenu
30
+ data-table-column-menu
31
+ data-columns={JSON.stringify(columns.map((c) => c.column))}
32
+ closeOnSelect={false}
33
+ defaultValues={columns.filter((c) => !c.hidden).map((c) => c.column)}
34
+ class={className}
35
+ >
36
+ <DropdownMenuTrigger variant="outline" size="sm">
37
+ <Columns3 aria-hidden="true" />
38
+ {label}
39
+ </DropdownMenuTrigger>
40
+ <DropdownMenuContent align="end" class="w-auto min-w-44">
41
+ <DropdownMenuLabel>Toggle columns</DropdownMenuLabel>
42
+ {
43
+ columns.map((c) => (
44
+ <DropdownMenuCheckboxItem value={c.column} defaultChecked={!c.hidden} disabled={c.disabled}>
45
+ {c.label}
46
+ </DropdownMenuCheckboxItem>
47
+ ))
48
+ }
49
+ </DropdownMenuContent>
50
+ </DropdownMenu>
@@ -0,0 +1,287 @@
1
+ ---
2
+ import { Check, ChevronDown, Pencil, X } from "@lucide/astro";
3
+ import { cn } from "@cl-light-ds/ui/lib/utils";
4
+ import type { HTMLAttributes } from "astro/types";
5
+ import { Badge } from "../badge";
6
+ import { Button } from "../button";
7
+ import {
8
+ Combobox,
9
+ ComboboxContent,
10
+ ComboboxEmpty,
11
+ ComboboxInput,
12
+ ComboboxItem,
13
+ ComboboxList,
14
+ } from "../combobox";
15
+ import {
16
+ DropdownMenu,
17
+ DropdownMenuCheckboxItem,
18
+ DropdownMenuContent,
19
+ DropdownMenuRadioGroup,
20
+ DropdownMenuRadioItem,
21
+ DropdownMenuTrigger,
22
+ } from "../dropdown-menu";
23
+ import { Input } from "../input";
24
+ import { Spinner } from "../spinner";
25
+ import { cellAlign, cellBase, levelIndentStyle, type CellAlign } from "./table-cell-variants";
26
+
27
+ type BadgeVariant =
28
+ | "default"
29
+ | "secondary"
30
+ | "destructive"
31
+ | "outline"
32
+ | "success"
33
+ | "warning"
34
+ | "accent"
35
+ | "ghost";
36
+
37
+ export interface TableCellOption {
38
+ value: string;
39
+ label: string;
40
+ /** Badge variant used to render this option in select/multiselect cells. */
41
+ variant?: BadgeVariant;
42
+ }
43
+
44
+ interface Props extends Omit<HTMLAttributes<"td">, "value"> {
45
+ class?: string;
46
+ /** Column key reported in `table:edit`. */
47
+ column: string;
48
+ /** Current value. Use a string array for `multiselect`. */
49
+ value?: string | string[];
50
+ /**
51
+ * - `text`: click to edit, confirm with ✓ / Enter, cancel with ✕ / Esc.
52
+ * - `select`: badge dropdown, commits on pick.
53
+ * - `combobox`: searchable single select, commits on pick.
54
+ * - `multiselect`: badge tags with checkboxes, commits when the menu closes.
55
+ */
56
+ editor?: "text" | "select" | "combobox" | "multiselect";
57
+ options?: TableCellOption[];
58
+ /** Accessible column name, e.g. "Status". Defaults to `column`. */
59
+ label?: string;
60
+ /** Secondary line under a text value (not editable). */
61
+ subtitle?: string;
62
+ placeholder?: string;
63
+ /** Renders the value without edit affordances. */
64
+ readOnly?: boolean;
65
+ align?: CellAlign;
66
+ numeric?: boolean;
67
+ level?: 1 | 2 | 3;
68
+ /** Badges shown before collapsing the rest into "+N" (multiselect). */
69
+ maxVisible?: number;
70
+ /** Native validation for the text editor. */
71
+ required?: boolean;
72
+ pattern?: string;
73
+ minLength?: number;
74
+ maxLength?: number;
75
+ inputType?: "text" | "number" | "email" | "url";
76
+ }
77
+
78
+ const {
79
+ class: className = "",
80
+ column,
81
+ value = "",
82
+ editor = "text",
83
+ options = [],
84
+ label = column,
85
+ subtitle,
86
+ placeholder = "Empty",
87
+ readOnly = false,
88
+ numeric = false,
89
+ align = numeric ? "right" : "left",
90
+ level,
91
+ maxVisible = 2,
92
+ required = false,
93
+ pattern,
94
+ minLength,
95
+ maxLength,
96
+ inputType = "text",
97
+ ...rest
98
+ } = Astro.props as Props;
99
+
100
+ const values = Array.isArray(value) ? value : value ? [value] : [];
101
+ const optionFor = (v: string): TableCellOption =>
102
+ options.find((o) => o.value === v) ?? { value: v, label: v };
103
+ const selected = values.map(optionFor);
104
+ const visible = selected.slice(0, maxVisible);
105
+ const overflow = selected.length - visible.length;
106
+ const textValue = editor === "text" ? String(values[0] ?? "") : selected.map((o) => o.label).join(", ");
107
+ const usesBadges = editor === "select" || editor === "multiselect";
108
+ const dataValue = editor === "multiselect" ? JSON.stringify(values) : String(values[0] ?? "");
109
+
110
+ const affordance =
111
+ "group/editable -mx-2 flex min-h-8 max-w-full items-center gap-1.5 rounded-md px-2 text-left outline-none transition-[background-color,box-shadow] hover:bg-background hover:ring-1 hover:ring-border focus-visible:ring-2 focus-visible:ring-ring";
112
+ const affordanceIcon =
113
+ "size-3.5 shrink-0 text-muted-foreground opacity-0 transition-opacity group-hover/editable:opacity-100 group-focus-visible/editable:opacity-100 group-focus/cell:opacity-100";
114
+ ---
115
+
116
+ <td
117
+ data-slot="table-cell"
118
+ data-column={column}
119
+ data-editable={readOnly ? undefined : ""}
120
+ data-readonly={readOnly ? "" : undefined}
121
+ data-editor={editor}
122
+ data-value={dataValue}
123
+ data-label={label}
124
+ data-max-visible={maxVisible}
125
+ data-placeholder={placeholder}
126
+ data-state="idle"
127
+ style={levelIndentStyle(level)}
128
+ class={cn(
129
+ cellBase,
130
+ cellAlign({ align }),
131
+ "group/cell h-12 py-2 font-medium",
132
+ numeric && "font-semibold tabular-nums",
133
+ className,
134
+ )}
135
+ {...rest}
136
+ >
137
+ {
138
+ readOnly ? (
139
+ usesBadges ? (
140
+ <span class="inline-flex items-center gap-1">
141
+ {visible.map((o) => <Badge size="sm" variant={o.variant ?? "secondary"}>{o.label}</Badge>)}
142
+ {overflow > 0 && <Badge size="sm" variant="outline">+{overflow}</Badge>}
143
+ </span>
144
+ ) : (
145
+ <span class="block truncate">{textValue}</span>
146
+ )
147
+ ) : editor === "text" ? (
148
+ <>
149
+ <div
150
+ data-slot="table-cell-display"
151
+ role="button"
152
+ tabindex="-1"
153
+ aria-label={`Edit ${label}`}
154
+ class={cn(affordance, "cursor-text group-data-[state=editing]/cell:hidden group-data-[state=saving]/cell:hidden group-data-[state=error]/cell:hidden", align === "right" && "justify-end")}
155
+ >
156
+ <div class="min-w-0 flex-1">
157
+ <span data-slot="table-cell-value" class={cn("block truncate", !textValue && "text-muted-foreground font-normal")}>
158
+ {textValue || placeholder}
159
+ </span>
160
+ {subtitle && <span class="block truncate text-xs leading-4 font-normal text-muted-foreground">{subtitle}</span>}
161
+ </div>
162
+ <Pencil class={affordanceIcon} aria-hidden="true" />
163
+ </div>
164
+ <div
165
+ data-slot="table-cell-editor"
166
+ class="-mx-2 hidden items-center gap-1 group-data-[state=editing]/cell:flex group-data-[state=saving]/cell:flex group-data-[state=error]/cell:flex"
167
+ >
168
+ <Input
169
+ data-table-input
170
+ size="sm"
171
+ type={inputType}
172
+ value={textValue}
173
+ aria-label={label}
174
+ required={required}
175
+ pattern={pattern}
176
+ minlength={minLength}
177
+ maxlength={maxLength}
178
+ class={cn("min-w-24 flex-1", align === "right" && "text-right")}
179
+ />
180
+ <Button data-table-action="confirm" variant="ghost" size="icon-sm" aria-label="Save" class="text-primary">
181
+ <Check class="group-data-[state=saving]/cell:hidden" aria-hidden="true" />
182
+ <Spinner class="hidden group-data-[state=saving]/cell:block" aria-label="Saving" />
183
+ </Button>
184
+ <Button data-table-action="cancel" variant="ghost" size="icon-sm" aria-label="Cancel">
185
+ <X aria-hidden="true" />
186
+ </Button>
187
+ </div>
188
+ </>
189
+ ) : editor === "combobox" ? (
190
+ <>
191
+ <button
192
+ type="button"
193
+ data-slot="table-cell-display"
194
+ tabindex="-1"
195
+ aria-label={`Edit ${label}`}
196
+ class={cn(affordance, "cursor-pointer group-data-[state=editing]/cell:hidden")}
197
+ >
198
+ <span data-slot="table-cell-value" class={cn("truncate", !textValue && "text-muted-foreground font-normal")}>
199
+ {textValue || placeholder}
200
+ </span>
201
+ <ChevronDown class={affordanceIcon} aria-hidden="true" />
202
+ </button>
203
+ <div data-slot="table-cell-editor" class="-mx-2 hidden group-data-[state=editing]/cell:block">
204
+ <Combobox data-table-combobox defaultValue={values[0]} autoHighlight>
205
+ <ComboboxInput size="sm" placeholder={`Search ${label.toLowerCase()}…`} aria-label={label} class="w-full min-w-40" />
206
+ <ComboboxContent align="start">
207
+ <ComboboxList>
208
+ {options.map((o) => (
209
+ <ComboboxItem value={o.value} label={o.label}>{o.label}</ComboboxItem>
210
+ ))}
211
+ </ComboboxList>
212
+ <ComboboxEmpty>No results</ComboboxEmpty>
213
+ </ComboboxContent>
214
+ </Combobox>
215
+ </div>
216
+ </>
217
+ ) : (
218
+ <DropdownMenu
219
+ data-table-menu
220
+ defaultValue={editor === "select" ? values[0] ?? null : undefined}
221
+ defaultValues={editor === "multiselect" ? values : undefined}
222
+ closeOnSelect={editor === "select"}
223
+ class="-mx-2 max-w-[calc(100%+1rem)]"
224
+ >
225
+ <DropdownMenuTrigger asChild>
226
+ <button
227
+ type="button"
228
+ data-slot="table-cell-display"
229
+ tabindex="-1"
230
+ aria-label={`Edit ${label}`}
231
+ class={cn(affordance, "mx-0 cursor-pointer group-data-[state=saving]/cell:opacity-60")}
232
+ >
233
+ <span data-slot="table-cell-value" class="inline-flex min-w-0 items-center gap-1">
234
+ {visible.map((o) => <Badge size="sm" variant={o.variant ?? "secondary"}>{o.label}</Badge>)}
235
+ {overflow > 0 && <Badge size="sm" variant="outline">+{overflow}</Badge>}
236
+ {selected.length === 0 && <span class="text-muted-foreground font-normal">{placeholder}</span>}
237
+ </span>
238
+ <ChevronDown class={affordanceIcon} aria-hidden="true" />
239
+ </button>
240
+ </DropdownMenuTrigger>
241
+ <DropdownMenuContent class="w-auto min-w-44">
242
+ {
243
+ editor === "select" ? (
244
+ <DropdownMenuRadioGroup>
245
+ {options.map((o) => (
246
+ <DropdownMenuRadioItem value={o.value}>
247
+ <Badge size="sm" variant={o.variant ?? "secondary"}>{o.label}</Badge>
248
+ </DropdownMenuRadioItem>
249
+ ))}
250
+ </DropdownMenuRadioGroup>
251
+ ) : (
252
+ options.map((o) => (
253
+ <DropdownMenuCheckboxItem value={o.value} defaultChecked={values.includes(o.value)}>
254
+ <Badge size="sm" variant={o.variant ?? "secondary"}>{o.label}</Badge>
255
+ </DropdownMenuCheckboxItem>
256
+ ))
257
+ )
258
+ }
259
+ </DropdownMenuContent>
260
+ </DropdownMenu>
261
+ )
262
+ }
263
+ {
264
+ !readOnly && editor !== "text" && (
265
+ <template data-slot="table-cell-templates">
266
+ {options.map((o) =>
267
+ usesBadges ? (
268
+ <Badge data-option={o.value} size="sm" variant={o.variant ?? "secondary"}>{o.label}</Badge>
269
+ ) : (
270
+ <span data-option={o.value}>{o.label}</span>
271
+ ),
272
+ )}
273
+ {usesBadges && <Badge data-option-overflow size="sm" variant="outline">+0</Badge>}
274
+ </template>
275
+ )
276
+ }
277
+ {
278
+ !readOnly && (
279
+ <div
280
+ data-slot="table-cell-error"
281
+ role="alert"
282
+ hidden
283
+ class="fixed z-50 max-w-64 rounded-md bg-destructive px-2 py-1 text-xs font-medium whitespace-normal text-destructive-foreground shadow-md"
284
+ />
285
+ )
286
+ }
287
+ </td>
@@ -0,0 +1,17 @@
1
+ ---
2
+ import { cn } from "@cl-light-ds/ui/lib/utils";
3
+
4
+ interface Props {
5
+ /** Number of columns to span. */
6
+ colspan: number;
7
+ class?: string;
8
+ }
9
+
10
+ const { colspan, class: className = "" } = Astro.props as Props;
11
+ ---
12
+
13
+ <tr data-slot="table-empty" class="bg-background">
14
+ <td colspan={colspan} class={cn("h-40 border-b border-border px-6 text-center text-sm text-muted-foreground", className)}>
15
+ <slot>No results.</slot>
16
+ </td>
17
+ </tr>
@@ -0,0 +1,38 @@
1
+ ---
2
+ import { ChevronRight, Folder, FolderOpen } from "@lucide/astro";
3
+ import { cn } from "@cl-light-ds/ui/lib/utils";
4
+ import type { HTMLAttributes } from "astro/types";
5
+ import { cellBase, levelIndentStyle } from "./table-cell-variants";
6
+
7
+ interface Props extends HTMLAttributes<"td"> {
8
+ class?: string;
9
+ column?: string;
10
+ /** Nesting level (1–3). Match the parent `TableRow` `level`. */
11
+ level?: 1 | 2 | 3;
12
+ }
13
+
14
+ const { class: className = "", column, level, ...rest } = Astro.props as Props;
15
+ ---
16
+
17
+ <td
18
+ data-slot="table-cell"
19
+ data-column={column}
20
+ data-folder-cell
21
+ style={levelIndentStyle(level)}
22
+ class={cn(cellBase, "h-12 py-2 font-medium", className)}
23
+ {...rest}
24
+ >
25
+ <div class="flex items-center gap-1.5">
26
+ <button
27
+ type="button"
28
+ data-slot="table-row-toggle"
29
+ aria-label="Expand row"
30
+ class="-ml-1 inline-flex size-6 shrink-0 items-center justify-center rounded-md outline-none hover:bg-background-hover focus-visible:ring-2 focus-visible:ring-ring"
31
+ >
32
+ <ChevronRight class="size-4 transition-transform group-data-[expanded]/row:rotate-90" aria-hidden="true" />
33
+ </button>
34
+ <Folder class="size-4 shrink-0 group-data-[expanded]/row:hidden" aria-hidden="true" />
35
+ <FolderOpen class="hidden size-4 shrink-0 group-data-[expanded]/row:block" aria-hidden="true" />
36
+ <span class="truncate"><slot /></span>
37
+ </div>
38
+ </td>
@@ -1,21 +1,21 @@
1
- ---
2
- import { cn } from "@cl-light-ds/ui/lib/utils";
3
- import type { HTMLAttributes } from "astro/types";
4
-
5
- interface Props extends HTMLAttributes<"tfoot"> {
6
- class?: string;
7
- }
8
-
9
- const {
10
- class: className = "",
11
- ...rest
12
- } = Astro.props as Props;
13
- ---
14
-
15
- <tfoot
16
- data-slot="table-footer"
17
- class={cn("bg-muted/50 border-t font-medium [&>tr]:last:border-b-0", className)}
18
- {...rest}
19
- >
20
- <slot />
21
- </tfoot>
1
+ ---
2
+ import { cn } from "@cl-light-ds/ui/lib/utils";
3
+ import type { HTMLAttributes } from "astro/types";
4
+
5
+ interface Props extends HTMLAttributes<"tfoot"> {
6
+ class?: string;
7
+ }
8
+
9
+ const {
10
+ class: className = "",
11
+ ...rest
12
+ } = Astro.props as Props;
13
+ ---
14
+
15
+ <tfoot
16
+ data-slot="table-footer"
17
+ class={cn("font-medium [&_tr]:bg-muted [&_tr]:hover:bg-muted [&_td]:font-semibold", className)}
18
+ {...rest}
19
+ >
20
+ <slot />
21
+ </tfoot>