@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.
- package/README.md +45 -45
- package/package.json +2 -2
- package/src/components/accordion/Accordion.astro +248 -248
- package/src/components/accordion/AccordionContent.astro +26 -26
- package/src/components/accordion/AccordionItem.astro +36 -36
- package/src/components/accordion/AccordionTrigger.astro +118 -118
- package/src/components/accordion/CHANGELOG.md +41 -41
- package/src/components/accordion/index.ts +4 -4
- package/src/components/alert/Alert.astro +167 -167
- package/src/components/alert/AlertDescription.astro +24 -24
- package/src/components/alert/AlertTitle.astro +24 -24
- package/src/components/alert/CHANGELOG.md +5 -5
- package/src/components/alert/index.ts +4 -4
- package/src/components/avatar/Avatar.astro +197 -197
- package/src/components/avatar/AvatarBadge.astro +44 -44
- package/src/components/avatar/AvatarFallback.astro +26 -26
- package/src/components/avatar/AvatarGroup.astro +26 -26
- package/src/components/avatar/AvatarGroupCount.astro +30 -30
- package/src/components/avatar/AvatarImage.astro +46 -46
- package/src/components/avatar/CHANGELOG.md +44 -44
- package/src/components/avatar/index.ts +6 -6
- package/src/components/badge/Badge.astro +167 -167
- package/src/components/badge/CHANGELOG.md +49 -49
- package/src/components/badge/index.ts +2 -2
- package/src/components/breadcrumb/Breadcrumb.astro +76 -76
- package/src/components/breadcrumb/BreadcrumbItem.astro +32 -32
- package/src/components/breadcrumb/BreadcrumbList.astro +26 -26
- package/src/components/breadcrumb/BreadcrumbSeparator.astro +26 -26
- package/src/components/breadcrumb/CHANGELOG.md +24 -24
- package/src/components/breadcrumb/index.ts +5 -5
- package/src/components/button/Button.astro +233 -233
- package/src/components/button/CHANGELOG.md +41 -41
- package/src/components/button/index.ts +2 -2
- package/src/components/button-group/ButtonGroup.astro +130 -130
- package/src/components/button-group/ButtonGroupSeparator.astro +30 -30
- package/src/components/button-group/ButtonGroupText.astro +21 -21
- package/src/components/button-group/CHANGELOG.md +34 -34
- package/src/components/button-group/index.ts +3 -3
- package/src/components/callout/CHANGELOG.md +32 -0
- package/src/components/callout/Callout.astro +147 -0
- package/src/components/callout/CalloutDescription.astro +16 -0
- package/src/components/callout/CalloutTitle.astro +16 -0
- package/src/components/callout/index.ts +3 -0
- package/src/components/card/CHANGELOG.md +162 -119
- package/src/components/card/Card.astro +197 -182
- package/src/components/card/CardAction.astro +26 -26
- package/src/components/card/CardContent.astro +28 -28
- package/src/components/card/CardDescription.astro +28 -28
- package/src/components/card/CardFooter.astro +24 -24
- package/src/components/card/CardHeader.astro +30 -30
- package/src/components/card/CardMedia.astro +27 -27
- package/src/components/card/CardMediaActions.astro +21 -0
- package/src/components/card/CardMediaSelect.astro +21 -0
- package/src/components/card/CardOverlay.astro +32 -32
- package/src/components/card/CardTitle.astro +21 -21
- package/src/components/card/index.ts +12 -10
- package/src/components/carousel/CHANGELOG.md +5 -5
- package/src/components/carousel/Carousel.astro +106 -106
- package/src/components/carousel/CarouselSlide.astro +22 -22
- package/src/components/carousel/index.ts +3 -3
- package/src/components/checkbox/CHANGELOG.md +58 -58
- package/src/components/checkbox/Checkbox.astro +159 -159
- package/src/components/checkbox/index.ts +1 -1
- package/src/components/collapsible/CHANGELOG.md +5 -5
- package/src/components/collapsible/Collapsible.astro +202 -202
- package/src/components/collapsible/CollapsibleContent.astro +36 -36
- package/src/components/collapsible/CollapsibleTrigger.astro +34 -34
- package/src/components/collapsible/index.ts +4 -4
- package/src/components/combobox/CHANGELOG.md +27 -27
- package/src/components/combobox/Combobox.astro +365 -365
- package/src/components/combobox/ComboboxContent.astro +37 -37
- package/src/components/combobox/ComboboxEmpty.astro +18 -18
- package/src/components/combobox/ComboboxGroup.astro +19 -19
- package/src/components/combobox/ComboboxInput.astro +74 -74
- package/src/components/combobox/ComboboxItem.astro +39 -39
- package/src/components/combobox/ComboboxLabel.astro +18 -18
- package/src/components/combobox/ComboboxList.astro +21 -21
- package/src/components/combobox/ComboboxSeparator.astro +17 -17
- package/src/components/combobox/ComboboxTrigger.astro +30 -30
- package/src/components/combobox/ComboboxValue.astro +22 -22
- package/src/components/combobox/index.ts +11 -11
- package/src/components/date/CHANGELOG.md +18 -18
- package/src/components/date/Date.astro +137 -137
- package/src/components/date/index.ts +2 -2
- package/src/components/dialog/CHANGELOG.md +39 -39
- package/src/components/dialog/Dialog.astro +196 -196
- package/src/components/dialog/DialogClose.astro +23 -23
- package/src/components/dialog/DialogContent.astro +42 -42
- package/src/components/dialog/DialogDescription.astro +18 -18
- package/src/components/dialog/DialogFooter.astro +18 -18
- package/src/components/dialog/DialogHeader.astro +18 -18
- package/src/components/dialog/DialogOverlay.astro +19 -19
- package/src/components/dialog/DialogTitle.astro +18 -18
- package/src/components/dialog/DialogTrigger.astro +37 -37
- package/src/components/dialog/index.ts +9 -9
- package/src/components/dropdown-menu/CHANGELOG.md +194 -194
- package/src/components/dropdown-menu/DropdownMenu.astro +226 -226
- package/src/components/dropdown-menu/DropdownMenuCheckboxItem.astro +114 -114
- package/src/components/dropdown-menu/DropdownMenuContent.astro +42 -42
- package/src/components/dropdown-menu/DropdownMenuGroup.astro +19 -19
- package/src/components/dropdown-menu/DropdownMenuItem.astro +220 -220
- package/src/components/dropdown-menu/DropdownMenuItemContent.astro +79 -79
- package/src/components/dropdown-menu/DropdownMenuLabel.astro +20 -20
- package/src/components/dropdown-menu/DropdownMenuPortal.astro +13 -13
- package/src/components/dropdown-menu/DropdownMenuRadioGroup.astro +13 -13
- package/src/components/dropdown-menu/DropdownMenuRadioItem.astro +101 -101
- package/src/components/dropdown-menu/DropdownMenuSeparator.astro +18 -18
- package/src/components/dropdown-menu/DropdownMenuShortcut.astro +18 -18
- package/src/components/dropdown-menu/DropdownMenuTrigger.astro +49 -49
- package/src/components/dropdown-menu/dropdown-menu-item-variants.ts +24 -24
- package/src/components/dropdown-menu/index.ts +12 -12
- package/src/components/field/CHANGELOG.md +33 -33
- package/src/components/field/Field.astro +664 -664
- package/src/components/field/FieldContent.astro +20 -20
- package/src/components/field/FieldDescription.astro +22 -22
- package/src/components/field/FieldError.astro +51 -51
- package/src/components/field/FieldGroup.astro +20 -20
- package/src/components/field/FieldLabel.astro +22 -22
- package/src/components/field/FieldLegend.astro +23 -23
- package/src/components/field/FieldSeparator.astro +30 -30
- package/src/components/field/FieldSet.astro +20 -20
- package/src/components/field/FieldTitle.astro +20 -20
- package/src/components/field/index.ts +10 -10
- package/src/components/hover-card/CHANGELOG.md +20 -20
- package/src/components/hover-card/HoverCard.astro +235 -235
- package/src/components/hover-card/HoverCardContent.astro +54 -54
- package/src/components/hover-card/HoverCardTrigger.astro +38 -38
- package/src/components/hover-card/index.ts +3 -3
- package/src/components/input/CHANGELOG.md +44 -29
- package/src/components/input/Input.astro +130 -130
- package/src/components/input/InputOTP.astro +211 -0
- package/src/components/input/index.ts +2 -2
- package/src/components/input-group/CHANGELOG.md +49 -49
- package/src/components/input-group/InputGroup.astro +135 -135
- package/src/components/input-group/InputGroupAddon.astro +49 -49
- package/src/components/input-group/InputGroupButton.astro +58 -58
- package/src/components/input-group/InputGroupInput.astro +18 -18
- package/src/components/input-group/InputGroupText.astro +21 -21
- package/src/components/input-group/InputGroupTextarea.astro +17 -17
- package/src/components/input-group/controlClasses.ts +2 -2
- package/src/components/input-group/index.ts +6 -6
- package/src/components/item/CHANGELOG.md +27 -27
- package/src/components/item/Item.astro +122 -122
- package/src/components/item/ItemActions.astro +21 -21
- package/src/components/item/ItemContent.astro +25 -25
- package/src/components/item/ItemDescription.astro +25 -25
- package/src/components/item/ItemFooter.astro +24 -24
- package/src/components/item/ItemGroup.astro +24 -24
- package/src/components/item/ItemHeader.astro +24 -24
- package/src/components/item/ItemMedia.astro +47 -47
- package/src/components/item/ItemSeparator.astro +21 -21
- package/src/components/item/ItemTitle.astro +25 -25
- package/src/components/item/index.ts +10 -10
- package/src/components/kbd/CHANGELOG.md +5 -5
- package/src/components/kbd/Kbd.astro +145 -145
- package/src/components/kbd/KbdGroup.astro +55 -55
- package/src/components/kbd/index.ts +2 -2
- package/src/components/label/CHANGELOG.md +28 -28
- package/src/components/label/Label.astro +97 -97
- package/src/components/label/index.ts +2 -2
- package/src/components/link-group/CHANGELOG.md +75 -75
- package/src/components/link-group/LinkGroup.astro +67 -67
- package/src/components/link-group/LinkGroupItem.astro +32 -32
- package/src/components/link-group/LinkGroupList.astro +25 -25
- package/src/components/link-group/LinkGroupTitle.astro +22 -22
- package/src/components/link-group/index.ts +5 -5
- package/src/components/link-group/link-group-list-variants.ts +15 -15
- package/src/components/logo/CHANGELOG.md +17 -0
- package/src/components/logo/Logo.astro +90 -0
- package/src/components/logo/index.ts +3 -0
- package/src/components/logo/logo-paths.ts +57 -0
- package/src/components/marquee/CHANGELOG.md +5 -5
- package/src/components/marquee/Marquee.astro +119 -119
- package/src/components/marquee/index.ts +2 -2
- package/src/components/native-select/CHANGELOG.md +5 -5
- package/src/components/native-select/NativeSelect.astro +125 -125
- package/src/components/native-select/NativeSelectOptGroup.astro +14 -14
- package/src/components/native-select/NativeSelectOption.astro +9 -9
- package/src/components/native-select/index.ts +3 -3
- package/src/components/navigation-menu/CHANGELOG.md +63 -63
- package/src/components/navigation-menu/NavigationMenu.astro +414 -414
- package/src/components/navigation-menu/NavigationMenuContent.astro +37 -37
- package/src/components/navigation-menu/NavigationMenuIndicator.astro +24 -24
- package/src/components/navigation-menu/NavigationMenuItem.astro +22 -22
- package/src/components/navigation-menu/NavigationMenuLink.astro +18 -18
- package/src/components/navigation-menu/NavigationMenuList.astro +21 -21
- package/src/components/navigation-menu/NavigationMenuPositioner.astro +44 -44
- package/src/components/navigation-menu/NavigationMenuTrigger.astro +30 -30
- package/src/components/navigation-menu/NavigationMenuViewport.astro +19 -19
- package/src/components/navigation-menu/index.ts +10 -10
- package/src/components/organisms/lightning-sidebar-nav/CHANGELOG.md +50 -0
- package/src/components/organisms/lightning-sidebar-nav/LightningSidebarNav.astro +176 -0
- package/src/components/organisms/lightning-sidebar-nav/SidebarNav.astro +50 -0
- package/src/components/organisms/lightning-sidebar-nav/SidebarNavGroup.astro +74 -0
- package/src/components/organisms/lightning-sidebar-nav/SidebarNavItem.astro +94 -0
- package/src/components/organisms/lightning-sidebar-nav/SidebarNavProBadge.astro +26 -0
- package/src/components/organisms/lightning-sidebar-nav/SidebarNavSection.astro +71 -0
- package/src/components/organisms/lightning-sidebar-nav/SidebarNavSkeleton.astro +67 -0
- package/src/components/organisms/lightning-sidebar-nav/SidebarNavSubItem.astro +69 -0
- package/src/components/organisms/lightning-sidebar-nav/SidebarNavUsage.astro +78 -0
- package/src/components/organisms/lightning-sidebar-nav/SidebarNavWorkspaceAvatar.astro +46 -0
- package/src/components/organisms/lightning-sidebar-nav/SidebarNavWorkspaceSwitcher.astro +130 -0
- package/src/components/organisms/lightning-sidebar-nav/icons.ts +46 -0
- package/src/components/organisms/lightning-sidebar-nav/index.ts +18 -0
- package/src/components/organisms/lightning-sidebar-nav/types.ts +77 -0
- package/src/components/popover/CHANGELOG.md +20 -20
- package/src/components/popover/Popover.astro +211 -211
- package/src/components/popover/PopoverClose.astro +18 -18
- package/src/components/popover/PopoverContent.astro +50 -50
- package/src/components/popover/PopoverDescription.astro +18 -18
- package/src/components/popover/PopoverHeader.astro +18 -18
- package/src/components/popover/PopoverTitle.astro +18 -18
- package/src/components/popover/PopoverTrigger.astro +35 -35
- package/src/components/popover/index.ts +7 -7
- package/src/components/radio-group/CHANGELOG.md +31 -31
- package/src/components/radio-group/RadioGroup.astro +81 -81
- package/src/components/radio-group/RadioGroupItem.astro +51 -51
- package/src/components/radio-group/index.ts +3 -3
- package/src/components/select/CHANGELOG.md +39 -39
- package/src/components/select/Select.astro +373 -373
- package/src/components/select/SelectContent.astro +91 -91
- package/src/components/select/SelectGroup.astro +19 -19
- package/src/components/select/SelectItem.astro +48 -48
- package/src/components/select/SelectLabel.astro +18 -18
- package/src/components/select/SelectSeparator.astro +17 -17
- package/src/components/select/SelectTrigger.astro +34 -34
- package/src/components/select/SelectValue.astro +22 -22
- package/src/components/select/index.ts +8 -8
- package/src/components/separator/CHANGELOG.md +5 -5
- package/src/components/separator/Separator.astro +60 -60
- package/src/components/separator/index.ts +2 -2
- package/src/components/skeleton/CHANGELOG.md +5 -5
- package/src/components/skeleton/Skeleton.astro +121 -121
- package/src/components/skeleton/index.ts +1 -1
- package/src/components/slider/CHANGELOG.md +5 -5
- package/src/components/slider/Slider.astro +198 -198
- package/src/components/slider/index.ts +1 -1
- package/src/components/spinner/CHANGELOG.md +18 -18
- package/src/components/spinner/Spinner.astro +135 -135
- package/src/components/spinner/index.ts +1 -1
- package/src/components/sticky-surface/CHANGELOG.md +5 -5
- package/src/components/sticky-surface/StickySurface.astro +152 -152
- package/src/components/sticky-surface/index.ts +2 -2
- package/src/components/switch/CHANGELOG.md +29 -29
- package/src/components/switch/Switch.astro +106 -106
- package/src/components/switch/index.ts +1 -1
- package/src/components/table/CHANGELOG.md +24 -24
- package/src/components/table/Table.astro +358 -251
- package/src/components/table/TableBody.astro +17 -18
- package/src/components/table/TableBulkToolbar.astro +37 -0
- package/src/components/table/TableCaption.astro +17 -17
- package/src/components/table/TableCell.astro +45 -21
- package/src/components/table/TableCellText.astro +17 -0
- package/src/components/table/TableColumnMenu.astro +50 -0
- package/src/components/table/TableEditableCell.astro +287 -0
- package/src/components/table/TableEmpty.astro +17 -0
- package/src/components/table/TableFolderCell.astro +38 -0
- package/src/components/table/TableFooter.astro +21 -21
- package/src/components/table/TableHead.astro +90 -21
- package/src/components/table/TableHeader.astro +17 -17
- package/src/components/table/TablePagination.astro +57 -0
- package/src/components/table/TableRow.astro +52 -21
- package/src/components/table/TableSelectAllBanner.astro +34 -0
- package/src/components/table/TableSelectCell.astro +50 -0
- package/src/components/table/TableSkeletonRow.astro +21 -0
- package/src/components/table/index.ts +19 -9
- package/src/components/table/table-cell-variants.ts +29 -0
- package/src/components/tabs/CHANGELOG.md +5 -5
- package/src/components/tabs/Tabs.astro +306 -306
- package/src/components/tabs/TabsContent.astro +47 -47
- package/src/components/tabs/TabsList.astro +69 -69
- package/src/components/tabs/TabsTrigger.astro +40 -40
- package/src/components/tabs/index.ts +6 -6
- package/src/components/textarea/CHANGELOG.md +22 -22
- package/src/components/textarea/Textarea.astro +58 -58
- package/src/components/textarea/index.ts +2 -2
- package/src/components/toggle/CHANGELOG.md +23 -23
- package/src/components/toggle/Toggle.astro +150 -150
- package/src/components/toggle/index.ts +1 -1
- package/src/components/toggle-group/CHANGELOG.md +18 -18
- package/src/components/toggle-group/ToggleGroup.astro +236 -236
- package/src/components/toggle-group/ToggleGroupItem.astro +48 -48
- package/src/components/toggle-group/index.ts +2 -2
- package/src/components/tooltip/CHANGELOG.md +22 -22
- package/src/components/tooltip/Tooltip.astro +357 -357
- package/src/components/tooltip/TooltipContent.astro +85 -85
- package/src/components/tooltip/TooltipTrigger.astro +34 -34
- package/src/components/tooltip/index.ts +3 -3
- package/src/lib/table-controller.ts +1090 -0
- package/src/lib/toggle-group-controller.ts +113 -113
- package/src/lib/toggle-shared.ts +27 -27
- package/src/lib/utils.ts +6 -6
- 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.
|