@cl-light-ds/ui 0.1.0 → 0.2.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 +1 -1
- 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/alert/Alert.astro +167 -167
- package/src/components/alert/AlertDescription.astro +24 -24
- package/src/components/alert/AlertTitle.astro +24 -24
- 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/badge/Badge.astro +167 -167
- 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/button/Button.astro +233 -233
- 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/card/Card.astro +182 -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/CardOverlay.astro +32 -32
- package/src/components/card/CardTitle.astro +21 -21
- package/src/components/carousel/Carousel.astro +106 -106
- package/src/components/carousel/CarouselSlide.astro +22 -22
- package/src/components/checkbox/Checkbox.astro +159 -159
- 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/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/date/Date.astro +137 -137
- 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/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/DropdownMenuLabel.astro +20 -20
- 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/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/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/input/Input.astro +130 -130
- 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/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/kbd/Kbd.astro +145 -145
- package/src/components/kbd/KbdGroup.astro +55 -55
- package/src/components/label/Label.astro +97 -97
- 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/marquee/Marquee.astro +119 -119
- package/src/components/native-select/NativeSelect.astro +125 -125
- package/src/components/native-select/NativeSelectOptGroup.astro +14 -14
- 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/popover/CHANGELOG.md +17 -2
- package/src/components/popover/Popover.astro +211 -210
- package/src/components/popover/PopoverClose.astro +18 -18
- package/src/components/popover/PopoverContent.astro +50 -49
- 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 -29
- package/src/components/radio-group/CHANGELOG.md +23 -1
- package/src/components/radio-group/RadioGroup.astro +81 -81
- package/src/components/radio-group/RadioGroupItem.astro +51 -42
- 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/separator/Separator.astro +60 -60
- package/src/components/skeleton/Skeleton.astro +121 -121
- package/src/components/slider/Slider.astro +198 -198
- package/src/components/spinner/CHANGELOG.md +14 -1
- package/src/components/spinner/Spinner.astro +135 -134
- package/src/components/sticky-surface/StickySurface.astro +152 -152
- package/src/components/switch/CHANGELOG.md +20 -0
- package/src/components/switch/Switch.astro +106 -106
- package/src/components/table/CHANGELOG.md +21 -2
- package/src/components/table/Table.astro +251 -250
- package/src/components/table/TableBody.astro +18 -18
- package/src/components/table/TableCaption.astro +17 -17
- package/src/components/table/TableCell.astro +21 -21
- package/src/components/table/TableFooter.astro +21 -21
- package/src/components/table/TableHead.astro +21 -21
- package/src/components/table/TableHeader.astro +17 -17
- package/src/components/table/TableRow.astro +21 -21
- 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/textarea/CHANGELOG.md +18 -1
- package/src/components/textarea/Textarea.astro +58 -36
- package/src/components/toggle/CHANGELOG.md +19 -1
- package/src/components/toggle/Toggle.astro +150 -138
- package/src/components/toggle-group/CHANGELOG.md +14 -1
- package/src/components/toggle-group/ToggleGroup.astro +236 -224
- package/src/components/toggle-group/ToggleGroupItem.astro +48 -48
- package/src/components/tooltip/CHANGELOG.md +19 -2
- package/src/components/tooltip/Tooltip.astro +357 -331
- package/src/components/tooltip/TooltipContent.astro +85 -60
- package/src/components/tooltip/TooltipTrigger.astro +34 -34
- package/src/lib/toggle-shared.ts +3 -2
|
@@ -1,235 +1,235 @@
|
|
|
1
|
-
---
|
|
2
|
-
/**
|
|
3
|
-
* @component HoverCard
|
|
4
|
-
* @title Hover Card
|
|
5
|
-
* @description For sighted users to preview content available behind a link.
|
|
6
|
-
* @figmaUrl https://www.figma.com/design/qXkzdqZ3QPQqgckU3AwIAH/ClickLearn-Lightning-Design-Library?node-id=5455-14770
|
|
7
|
-
*
|
|
8
|
-
* @preview
|
|
9
|
-
*
|
|
10
|
-
* <HoverCard delay={10} closeDelay={100}>
|
|
11
|
-
* <HoverCardTrigger asChild>
|
|
12
|
-
* <Button variant="link">@data-slot</Button>
|
|
13
|
-
* </HoverCardTrigger>
|
|
14
|
-
* <HoverCardContent class="flex w-64 flex-col gap-0.5">
|
|
15
|
-
* <div class="font-semibold">@data-slot</div>
|
|
16
|
-
* <div>Headless UI components for vanilla JavaScript.</div>
|
|
17
|
-
* <div class="text-muted-foreground mt-1 text-xs">
|
|
18
|
-
* Created by Bejamas in 2026
|
|
19
|
-
* </div>
|
|
20
|
-
* </HoverCardContent>
|
|
21
|
-
* </HoverCard>
|
|
22
|
-
*
|
|
23
|
-
* @usage
|
|
24
|
-
*
|
|
25
|
-
* ```astro nocollapse
|
|
26
|
-
* ---
|
|
27
|
-
* import {
|
|
28
|
-
* HoverCard,
|
|
29
|
-
* HoverCardContent,
|
|
30
|
-
* HoverCardTrigger,
|
|
31
|
-
* } from '@bejamas/ui/components/hover-card';
|
|
32
|
-
* import { Button } from '@bejamas/ui/components/button';
|
|
33
|
-
* ---
|
|
34
|
-
*
|
|
35
|
-
* <HoverCard>
|
|
36
|
-
* <HoverCardTrigger asChild>
|
|
37
|
-
* <Button variant="link">Hover Here</Button>
|
|
38
|
-
* </HoverCardTrigger>
|
|
39
|
-
* <HoverCardContent>
|
|
40
|
-
* <div class="font-semibold">@nextjs</div>
|
|
41
|
-
* <div>The React Framework - created and maintained by @vercel.</div>
|
|
42
|
-
* </HoverCardContent>
|
|
43
|
-
* </HoverCard>
|
|
44
|
-
* ```
|
|
45
|
-
*
|
|
46
|
-
* @api
|
|
47
|
-
*
|
|
48
|
-
* ### Events
|
|
49
|
-
*
|
|
50
|
-
* The hover card emits custom events that you can listen to:
|
|
51
|
-
*
|
|
52
|
-
* | Event | Detail | Description |
|
|
53
|
-
* |-------|--------|-------------|
|
|
54
|
-
* | `hover-card:change` | `{ open: boolean, reason: string, trigger: HTMLElement, content: HTMLElement }` | Fired when visibility changes |
|
|
55
|
-
*
|
|
56
|
-
* ```astro nocollapse console
|
|
57
|
-
* <HoverCard id="my-hover-card">
|
|
58
|
-
* <HoverCardTrigger asChild>
|
|
59
|
-
* <Button variant="outline">Hover me</Button>
|
|
60
|
-
* </HoverCardTrigger>
|
|
61
|
-
* <HoverCardContent>
|
|
62
|
-
* Hover card content
|
|
63
|
-
* </HoverCardContent>
|
|
64
|
-
* </HoverCard>
|
|
65
|
-
* ```
|
|
66
|
-
*
|
|
67
|
-
* ```js nocollapse
|
|
68
|
-
* const hoverCard = document.getElementById('my-hover-card');
|
|
69
|
-
*
|
|
70
|
-
* hoverCard.addEventListener('hover-card:change', (e) => {
|
|
71
|
-
* console.log('Is open:', e.detail.open);
|
|
72
|
-
* console.log('Reason:', e.detail.reason);
|
|
73
|
-
* });
|
|
74
|
-
* ```
|
|
75
|
-
*
|
|
76
|
-
* ### Programmatic Control
|
|
77
|
-
*
|
|
78
|
-
* You can control the hover card programmatically by dispatching a `hover-card:set` event:
|
|
79
|
-
*
|
|
80
|
-
* ```js nocollapse
|
|
81
|
-
* const hoverCard = document.getElementById('my-hover-card');
|
|
82
|
-
*
|
|
83
|
-
* // Open the hover card
|
|
84
|
-
* hoverCard.dispatchEvent(new CustomEvent('hover-card:set', {
|
|
85
|
-
* detail: { open: true }
|
|
86
|
-
* }));
|
|
87
|
-
*
|
|
88
|
-
* // Close the hover card
|
|
89
|
-
* hoverCard.dispatchEvent(new CustomEvent('hover-card:set', {
|
|
90
|
-
* detail: { open: false }
|
|
91
|
-
* }));
|
|
92
|
-
* ```
|
|
93
|
-
*
|
|
94
|
-
* ### Data Attributes
|
|
95
|
-
*
|
|
96
|
-
* The hover card sets these data attributes that you can use for styling or querying state:
|
|
97
|
-
*
|
|
98
|
-
* | Attribute | Element | Description |
|
|
99
|
-
* |-----------|---------|-------------|
|
|
100
|
-
* | `data-state` | hover-card, hover-card-content | Current state (`open` or `closed`) |
|
|
101
|
-
* | `data-open` | hover-card, hover-card-content | Present while open |
|
|
102
|
-
* | `data-closed` | hover-card, hover-card-content | Present while closed |
|
|
103
|
-
* | `data-side` | hover-card-content | Position relative to trigger (`top`, `right`, `bottom`, or `left`) |
|
|
104
|
-
* | `data-align` | hover-card-content | Alignment (`start`, `center`, or `end`) |
|
|
105
|
-
* | `data-side-offset` | hover-card-content | Distance from trigger in pixels (default `4`) |
|
|
106
|
-
* | `data-align-offset` | hover-card-content | Alignment-axis offset in pixels (default `0`) |
|
|
107
|
-
*
|
|
108
|
-
* @examples
|
|
109
|
-
*
|
|
110
|
-
* ### With Avatar
|
|
111
|
-
*
|
|
112
|
-
* <HoverCard>
|
|
113
|
-
* <HoverCardTrigger asChild>
|
|
114
|
-
* <Button variant="link">@thom</Button>
|
|
115
|
-
* </HoverCardTrigger>
|
|
116
|
-
* <HoverCardContent class="flex w-72 gap-3 p-3">
|
|
117
|
-
* <Avatar class="size-10 rounded-full">
|
|
118
|
-
* <AvatarImage>
|
|
119
|
-
* <img src="https://github.com/thomkrupa.png" alt="@thom" />
|
|
120
|
-
* </AvatarImage>
|
|
121
|
-
* <AvatarFallback>TK</AvatarFallback>
|
|
122
|
-
* </Avatar>
|
|
123
|
-
* <div class="space-y-1">
|
|
124
|
-
* <div class="text-sm font-semibold leading-none">@thom</div>
|
|
125
|
-
* <p class="text-muted-foreground text-sm">
|
|
126
|
-
* Building design systems and UI tooling.
|
|
127
|
-
* </p>
|
|
128
|
-
* </div>
|
|
129
|
-
* </HoverCardContent>
|
|
130
|
-
* </HoverCard>
|
|
131
|
-
*
|
|
132
|
-
* ### Different sides
|
|
133
|
-
*
|
|
134
|
-
* <div class="flex flex-wrap items-center gap-3 py-8">
|
|
135
|
-
* <HoverCard delay={10} closeDelay={80} skipDelayDuration={0}>
|
|
136
|
-
* <HoverCardTrigger asChild>
|
|
137
|
-
* <Button variant="outline">Left</Button>
|
|
138
|
-
* </HoverCardTrigger>
|
|
139
|
-
* <HoverCardContent side="left">Appears on left.</HoverCardContent>
|
|
140
|
-
* </HoverCard>
|
|
141
|
-
* <HoverCard delay={10} closeDelay={80} skipDelayDuration={0}>
|
|
142
|
-
* <HoverCardTrigger asChild>
|
|
143
|
-
* <Button variant="outline">Top</Button>
|
|
144
|
-
* </HoverCardTrigger>
|
|
145
|
-
* <HoverCardContent side="top">Appears on top.</HoverCardContent>
|
|
146
|
-
* </HoverCard>
|
|
147
|
-
* <HoverCard delay={10} closeDelay={80} skipDelayDuration={0}>
|
|
148
|
-
* <HoverCardTrigger asChild>
|
|
149
|
-
* <Button variant="outline">Bottom</Button>
|
|
150
|
-
* </HoverCardTrigger>
|
|
151
|
-
* <HoverCardContent side="bottom">Appears on bottom.</HoverCardContent>
|
|
152
|
-
* </HoverCard>
|
|
153
|
-
* <HoverCard delay={10} closeDelay={80} skipDelayDuration={0}>
|
|
154
|
-
* <HoverCardTrigger asChild>
|
|
155
|
-
* <Button variant="outline">Right</Button>
|
|
156
|
-
* </HoverCardTrigger>
|
|
157
|
-
* <HoverCardContent side="right">Appears on right.</HoverCardContent>
|
|
158
|
-
* </HoverCard>
|
|
159
|
-
* </div>
|
|
160
|
-
*
|
|
161
|
-
* ### Positioning options
|
|
162
|
-
*
|
|
163
|
-
* Configure placement options on `HoverCardContent`:
|
|
164
|
-
*
|
|
165
|
-
* <HoverCard>
|
|
166
|
-
* <HoverCardTrigger asChild>
|
|
167
|
-
* <Button variant="outline">Custom positioning</Button>
|
|
168
|
-
* </HoverCardTrigger>
|
|
169
|
-
* <HoverCardContent
|
|
170
|
-
* side="top"
|
|
171
|
-
* sideOffset={8}
|
|
172
|
-
* align="start"
|
|
173
|
-
* >
|
|
174
|
-
* Uses content-level positioning options.
|
|
175
|
-
* </HoverCardContent>
|
|
176
|
-
* </HoverCard>
|
|
177
|
-
*
|
|
178
|
-
* ### Custom timing
|
|
179
|
-
*
|
|
180
|
-
* <HoverCard delay={600} closeDelay={200} skipDelayDuration={300}>
|
|
181
|
-
* <HoverCardTrigger asChild>
|
|
182
|
-
* <Button variant="outline">Hover with delay</Button>
|
|
183
|
-
* </HoverCardTrigger>
|
|
184
|
-
* <HoverCardContent>
|
|
185
|
-
* Opens after 600ms, closes after 200ms.
|
|
186
|
-
* </HoverCardContent>
|
|
187
|
-
* </HoverCard>
|
|
188
|
-
*/
|
|
189
|
-
|
|
190
|
-
import type { HTMLAttributes } from "astro/types";
|
|
191
|
-
import { cn } from "@cl-light-ds/ui/lib/utils";
|
|
192
|
-
|
|
193
|
-
interface Props extends HTMLAttributes<"div"> {
|
|
194
|
-
class?: string;
|
|
195
|
-
defaultOpen?: boolean;
|
|
196
|
-
delay?: number;
|
|
197
|
-
skipDelayDuration?: number;
|
|
198
|
-
closeDelay?: number;
|
|
199
|
-
closeOnClickOutside?: boolean;
|
|
200
|
-
closeOnEscape?: boolean;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
const {
|
|
204
|
-
class: className = "",
|
|
205
|
-
defaultOpen = false,
|
|
206
|
-
delay = 700,
|
|
207
|
-
skipDelayDuration = 300,
|
|
208
|
-
closeDelay = 300,
|
|
209
|
-
closeOnClickOutside = true,
|
|
210
|
-
closeOnEscape = true,
|
|
211
|
-
...rest
|
|
212
|
-
} = Astro.props as Props;
|
|
213
|
-
---
|
|
214
|
-
|
|
215
|
-
<div
|
|
216
|
-
{...rest}
|
|
217
|
-
data-slot="hover-card"
|
|
218
|
-
data-default-open={String(defaultOpen)}
|
|
219
|
-
data-delay={delay}
|
|
220
|
-
data-skip-delay-duration={skipDelayDuration}
|
|
221
|
-
data-close-delay={closeDelay}
|
|
222
|
-
data-close-on-click-outside={String(closeOnClickOutside)}
|
|
223
|
-
data-close-on-escape={String(closeOnEscape)}
|
|
224
|
-
class={cn("", "inline-block", className)}
|
|
225
|
-
>
|
|
226
|
-
<slot />
|
|
227
|
-
</div>
|
|
228
|
-
|
|
229
|
-
<script>
|
|
230
|
-
import { createHoverCard } from "@data-slot/hover-card";
|
|
231
|
-
|
|
232
|
-
document.querySelectorAll('[data-slot="hover-card"]').forEach((el) => {
|
|
233
|
-
createHoverCard(el);
|
|
234
|
-
});
|
|
235
|
-
</script>
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* @component HoverCard
|
|
4
|
+
* @title Hover Card
|
|
5
|
+
* @description For sighted users to preview content available behind a link.
|
|
6
|
+
* @figmaUrl https://www.figma.com/design/qXkzdqZ3QPQqgckU3AwIAH/ClickLearn-Lightning-Design-Library?node-id=5455-14770
|
|
7
|
+
*
|
|
8
|
+
* @preview
|
|
9
|
+
*
|
|
10
|
+
* <HoverCard delay={10} closeDelay={100}>
|
|
11
|
+
* <HoverCardTrigger asChild>
|
|
12
|
+
* <Button variant="link">@data-slot</Button>
|
|
13
|
+
* </HoverCardTrigger>
|
|
14
|
+
* <HoverCardContent class="flex w-64 flex-col gap-0.5">
|
|
15
|
+
* <div class="font-semibold">@data-slot</div>
|
|
16
|
+
* <div>Headless UI components for vanilla JavaScript.</div>
|
|
17
|
+
* <div class="text-muted-foreground mt-1 text-xs">
|
|
18
|
+
* Created by Bejamas in 2026
|
|
19
|
+
* </div>
|
|
20
|
+
* </HoverCardContent>
|
|
21
|
+
* </HoverCard>
|
|
22
|
+
*
|
|
23
|
+
* @usage
|
|
24
|
+
*
|
|
25
|
+
* ```astro nocollapse
|
|
26
|
+
* ---
|
|
27
|
+
* import {
|
|
28
|
+
* HoverCard,
|
|
29
|
+
* HoverCardContent,
|
|
30
|
+
* HoverCardTrigger,
|
|
31
|
+
* } from '@bejamas/ui/components/hover-card';
|
|
32
|
+
* import { Button } from '@bejamas/ui/components/button';
|
|
33
|
+
* ---
|
|
34
|
+
*
|
|
35
|
+
* <HoverCard>
|
|
36
|
+
* <HoverCardTrigger asChild>
|
|
37
|
+
* <Button variant="link">Hover Here</Button>
|
|
38
|
+
* </HoverCardTrigger>
|
|
39
|
+
* <HoverCardContent>
|
|
40
|
+
* <div class="font-semibold">@nextjs</div>
|
|
41
|
+
* <div>The React Framework - created and maintained by @vercel.</div>
|
|
42
|
+
* </HoverCardContent>
|
|
43
|
+
* </HoverCard>
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @api
|
|
47
|
+
*
|
|
48
|
+
* ### Events
|
|
49
|
+
*
|
|
50
|
+
* The hover card emits custom events that you can listen to:
|
|
51
|
+
*
|
|
52
|
+
* | Event | Detail | Description |
|
|
53
|
+
* |-------|--------|-------------|
|
|
54
|
+
* | `hover-card:change` | `{ open: boolean, reason: string, trigger: HTMLElement, content: HTMLElement }` | Fired when visibility changes |
|
|
55
|
+
*
|
|
56
|
+
* ```astro nocollapse console
|
|
57
|
+
* <HoverCard id="my-hover-card">
|
|
58
|
+
* <HoverCardTrigger asChild>
|
|
59
|
+
* <Button variant="outline">Hover me</Button>
|
|
60
|
+
* </HoverCardTrigger>
|
|
61
|
+
* <HoverCardContent>
|
|
62
|
+
* Hover card content
|
|
63
|
+
* </HoverCardContent>
|
|
64
|
+
* </HoverCard>
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* ```js nocollapse
|
|
68
|
+
* const hoverCard = document.getElementById('my-hover-card');
|
|
69
|
+
*
|
|
70
|
+
* hoverCard.addEventListener('hover-card:change', (e) => {
|
|
71
|
+
* console.log('Is open:', e.detail.open);
|
|
72
|
+
* console.log('Reason:', e.detail.reason);
|
|
73
|
+
* });
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* ### Programmatic Control
|
|
77
|
+
*
|
|
78
|
+
* You can control the hover card programmatically by dispatching a `hover-card:set` event:
|
|
79
|
+
*
|
|
80
|
+
* ```js nocollapse
|
|
81
|
+
* const hoverCard = document.getElementById('my-hover-card');
|
|
82
|
+
*
|
|
83
|
+
* // Open the hover card
|
|
84
|
+
* hoverCard.dispatchEvent(new CustomEvent('hover-card:set', {
|
|
85
|
+
* detail: { open: true }
|
|
86
|
+
* }));
|
|
87
|
+
*
|
|
88
|
+
* // Close the hover card
|
|
89
|
+
* hoverCard.dispatchEvent(new CustomEvent('hover-card:set', {
|
|
90
|
+
* detail: { open: false }
|
|
91
|
+
* }));
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* ### Data Attributes
|
|
95
|
+
*
|
|
96
|
+
* The hover card sets these data attributes that you can use for styling or querying state:
|
|
97
|
+
*
|
|
98
|
+
* | Attribute | Element | Description |
|
|
99
|
+
* |-----------|---------|-------------|
|
|
100
|
+
* | `data-state` | hover-card, hover-card-content | Current state (`open` or `closed`) |
|
|
101
|
+
* | `data-open` | hover-card, hover-card-content | Present while open |
|
|
102
|
+
* | `data-closed` | hover-card, hover-card-content | Present while closed |
|
|
103
|
+
* | `data-side` | hover-card-content | Position relative to trigger (`top`, `right`, `bottom`, or `left`) |
|
|
104
|
+
* | `data-align` | hover-card-content | Alignment (`start`, `center`, or `end`) |
|
|
105
|
+
* | `data-side-offset` | hover-card-content | Distance from trigger in pixels (default `4`) |
|
|
106
|
+
* | `data-align-offset` | hover-card-content | Alignment-axis offset in pixels (default `0`) |
|
|
107
|
+
*
|
|
108
|
+
* @examples
|
|
109
|
+
*
|
|
110
|
+
* ### With Avatar
|
|
111
|
+
*
|
|
112
|
+
* <HoverCard>
|
|
113
|
+
* <HoverCardTrigger asChild>
|
|
114
|
+
* <Button variant="link">@thom</Button>
|
|
115
|
+
* </HoverCardTrigger>
|
|
116
|
+
* <HoverCardContent class="flex w-72 gap-3 p-3">
|
|
117
|
+
* <Avatar class="size-10 rounded-full">
|
|
118
|
+
* <AvatarImage>
|
|
119
|
+
* <img src="https://github.com/thomkrupa.png" alt="@thom" />
|
|
120
|
+
* </AvatarImage>
|
|
121
|
+
* <AvatarFallback>TK</AvatarFallback>
|
|
122
|
+
* </Avatar>
|
|
123
|
+
* <div class="space-y-1">
|
|
124
|
+
* <div class="text-sm font-semibold leading-none">@thom</div>
|
|
125
|
+
* <p class="text-muted-foreground text-sm">
|
|
126
|
+
* Building design systems and UI tooling.
|
|
127
|
+
* </p>
|
|
128
|
+
* </div>
|
|
129
|
+
* </HoverCardContent>
|
|
130
|
+
* </HoverCard>
|
|
131
|
+
*
|
|
132
|
+
* ### Different sides
|
|
133
|
+
*
|
|
134
|
+
* <div class="flex flex-wrap items-center gap-3 py-8">
|
|
135
|
+
* <HoverCard delay={10} closeDelay={80} skipDelayDuration={0}>
|
|
136
|
+
* <HoverCardTrigger asChild>
|
|
137
|
+
* <Button variant="outline">Left</Button>
|
|
138
|
+
* </HoverCardTrigger>
|
|
139
|
+
* <HoverCardContent side="left">Appears on left.</HoverCardContent>
|
|
140
|
+
* </HoverCard>
|
|
141
|
+
* <HoverCard delay={10} closeDelay={80} skipDelayDuration={0}>
|
|
142
|
+
* <HoverCardTrigger asChild>
|
|
143
|
+
* <Button variant="outline">Top</Button>
|
|
144
|
+
* </HoverCardTrigger>
|
|
145
|
+
* <HoverCardContent side="top">Appears on top.</HoverCardContent>
|
|
146
|
+
* </HoverCard>
|
|
147
|
+
* <HoverCard delay={10} closeDelay={80} skipDelayDuration={0}>
|
|
148
|
+
* <HoverCardTrigger asChild>
|
|
149
|
+
* <Button variant="outline">Bottom</Button>
|
|
150
|
+
* </HoverCardTrigger>
|
|
151
|
+
* <HoverCardContent side="bottom">Appears on bottom.</HoverCardContent>
|
|
152
|
+
* </HoverCard>
|
|
153
|
+
* <HoverCard delay={10} closeDelay={80} skipDelayDuration={0}>
|
|
154
|
+
* <HoverCardTrigger asChild>
|
|
155
|
+
* <Button variant="outline">Right</Button>
|
|
156
|
+
* </HoverCardTrigger>
|
|
157
|
+
* <HoverCardContent side="right">Appears on right.</HoverCardContent>
|
|
158
|
+
* </HoverCard>
|
|
159
|
+
* </div>
|
|
160
|
+
*
|
|
161
|
+
* ### Positioning options
|
|
162
|
+
*
|
|
163
|
+
* Configure placement options on `HoverCardContent`:
|
|
164
|
+
*
|
|
165
|
+
* <HoverCard>
|
|
166
|
+
* <HoverCardTrigger asChild>
|
|
167
|
+
* <Button variant="outline">Custom positioning</Button>
|
|
168
|
+
* </HoverCardTrigger>
|
|
169
|
+
* <HoverCardContent
|
|
170
|
+
* side="top"
|
|
171
|
+
* sideOffset={8}
|
|
172
|
+
* align="start"
|
|
173
|
+
* >
|
|
174
|
+
* Uses content-level positioning options.
|
|
175
|
+
* </HoverCardContent>
|
|
176
|
+
* </HoverCard>
|
|
177
|
+
*
|
|
178
|
+
* ### Custom timing
|
|
179
|
+
*
|
|
180
|
+
* <HoverCard delay={600} closeDelay={200} skipDelayDuration={300}>
|
|
181
|
+
* <HoverCardTrigger asChild>
|
|
182
|
+
* <Button variant="outline">Hover with delay</Button>
|
|
183
|
+
* </HoverCardTrigger>
|
|
184
|
+
* <HoverCardContent>
|
|
185
|
+
* Opens after 600ms, closes after 200ms.
|
|
186
|
+
* </HoverCardContent>
|
|
187
|
+
* </HoverCard>
|
|
188
|
+
*/
|
|
189
|
+
|
|
190
|
+
import type { HTMLAttributes } from "astro/types";
|
|
191
|
+
import { cn } from "@cl-light-ds/ui/lib/utils";
|
|
192
|
+
|
|
193
|
+
interface Props extends HTMLAttributes<"div"> {
|
|
194
|
+
class?: string;
|
|
195
|
+
defaultOpen?: boolean;
|
|
196
|
+
delay?: number;
|
|
197
|
+
skipDelayDuration?: number;
|
|
198
|
+
closeDelay?: number;
|
|
199
|
+
closeOnClickOutside?: boolean;
|
|
200
|
+
closeOnEscape?: boolean;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const {
|
|
204
|
+
class: className = "",
|
|
205
|
+
defaultOpen = false,
|
|
206
|
+
delay = 700,
|
|
207
|
+
skipDelayDuration = 300,
|
|
208
|
+
closeDelay = 300,
|
|
209
|
+
closeOnClickOutside = true,
|
|
210
|
+
closeOnEscape = true,
|
|
211
|
+
...rest
|
|
212
|
+
} = Astro.props as Props;
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
<div
|
|
216
|
+
{...rest}
|
|
217
|
+
data-slot="hover-card"
|
|
218
|
+
data-default-open={String(defaultOpen)}
|
|
219
|
+
data-delay={delay}
|
|
220
|
+
data-skip-delay-duration={skipDelayDuration}
|
|
221
|
+
data-close-delay={closeDelay}
|
|
222
|
+
data-close-on-click-outside={String(closeOnClickOutside)}
|
|
223
|
+
data-close-on-escape={String(closeOnEscape)}
|
|
224
|
+
class={cn("", "inline-block", className)}
|
|
225
|
+
>
|
|
226
|
+
<slot />
|
|
227
|
+
</div>
|
|
228
|
+
|
|
229
|
+
<script>
|
|
230
|
+
import { createHoverCard } from "@data-slot/hover-card";
|
|
231
|
+
|
|
232
|
+
document.querySelectorAll('[data-slot="hover-card"]').forEach((el) => {
|
|
233
|
+
createHoverCard(el);
|
|
234
|
+
});
|
|
235
|
+
</script>
|
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
import { cn } from "@cl-light-ds/ui/lib/utils";
|
|
4
|
-
import { cva } from "class-variance-authority";
|
|
5
|
-
|
|
6
|
-
interface Props extends HTMLAttributes<"div"> {
|
|
7
|
-
side?: "top" | "bottom" | "left" | "right";
|
|
8
|
-
sideOffset?: number;
|
|
9
|
-
align?: "start" | "center" | "end";
|
|
10
|
-
alignOffset?: number;
|
|
11
|
-
class?: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const {
|
|
15
|
-
class: className = "",
|
|
16
|
-
side = "bottom",
|
|
17
|
-
sideOffset = 4,
|
|
18
|
-
align = "center",
|
|
19
|
-
alignOffset = 0,
|
|
20
|
-
...rest
|
|
21
|
-
} = Astro.props as Props;
|
|
22
|
-
|
|
23
|
-
const contentVariants = cva([
|
|
24
|
-
// visibility
|
|
25
|
-
"duration-150 ease data-instant:duration-0 transition-discrete outline-hidden",
|
|
26
|
-
// animations
|
|
27
|
-
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
28
|
-
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
29
|
-
"data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2",
|
|
30
|
-
"data-[instant]:transition-none! data-[instant]:animate-none!",
|
|
31
|
-
"data-instant:data-[state=closed]:animate-none! data-instant:data-[state=closed]:fade-out-0! data-instant:data-[state=closed]:opacity-100! data-instant:data-[state=closed]:scale-100! data-instant:data-[state=closed]:translate-x-0! data-instant:data-[state=closed]:translate-y-0!",
|
|
32
|
-
// styles
|
|
33
|
-
"bg-popover text-popover-foreground w-64 rounded-lg border border-border p-3 text-sm shadow-lg has-[:focus-visible]:border-ring has-[:focus-visible]:ring-3 has-[:focus-visible]:ring-ring/50",
|
|
34
|
-
// origin from positioner
|
|
35
|
-
"origin-(--transform-origin)",
|
|
36
|
-
]);
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
<div data-slot="hover-card-portal" class="">
|
|
40
|
-
<div data-slot="hover-card-positioner" class="isolate z-50">
|
|
41
|
-
<div
|
|
42
|
-
{...rest}
|
|
43
|
-
hidden
|
|
44
|
-
data-slot="hover-card-content"
|
|
45
|
-
data-side={side}
|
|
46
|
-
data-side-offset={sideOffset}
|
|
47
|
-
data-align={align}
|
|
48
|
-
data-align-offset={alignOffset}
|
|
49
|
-
class={cn(contentVariants(), className)}
|
|
50
|
-
>
|
|
51
|
-
<slot />
|
|
52
|
-
</div>
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types";
|
|
3
|
+
import { cn } from "@cl-light-ds/ui/lib/utils";
|
|
4
|
+
import { cva } from "class-variance-authority";
|
|
5
|
+
|
|
6
|
+
interface Props extends HTMLAttributes<"div"> {
|
|
7
|
+
side?: "top" | "bottom" | "left" | "right";
|
|
8
|
+
sideOffset?: number;
|
|
9
|
+
align?: "start" | "center" | "end";
|
|
10
|
+
alignOffset?: number;
|
|
11
|
+
class?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const {
|
|
15
|
+
class: className = "",
|
|
16
|
+
side = "bottom",
|
|
17
|
+
sideOffset = 4,
|
|
18
|
+
align = "center",
|
|
19
|
+
alignOffset = 0,
|
|
20
|
+
...rest
|
|
21
|
+
} = Astro.props as Props;
|
|
22
|
+
|
|
23
|
+
const contentVariants = cva([
|
|
24
|
+
// visibility
|
|
25
|
+
"duration-150 ease data-instant:duration-0 transition-discrete outline-hidden",
|
|
26
|
+
// animations
|
|
27
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
28
|
+
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
29
|
+
"data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2",
|
|
30
|
+
"data-[instant]:transition-none! data-[instant]:animate-none!",
|
|
31
|
+
"data-instant:data-[state=closed]:animate-none! data-instant:data-[state=closed]:fade-out-0! data-instant:data-[state=closed]:opacity-100! data-instant:data-[state=closed]:scale-100! data-instant:data-[state=closed]:translate-x-0! data-instant:data-[state=closed]:translate-y-0!",
|
|
32
|
+
// styles
|
|
33
|
+
"bg-popover text-popover-foreground w-64 rounded-lg border border-border p-3 text-sm shadow-lg has-[:focus-visible]:border-ring has-[:focus-visible]:ring-3 has-[:focus-visible]:ring-ring/50",
|
|
34
|
+
// origin from positioner
|
|
35
|
+
"origin-(--transform-origin)",
|
|
36
|
+
]);
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
<div data-slot="hover-card-portal" class="">
|
|
40
|
+
<div data-slot="hover-card-positioner" class="isolate z-50">
|
|
41
|
+
<div
|
|
42
|
+
{...rest}
|
|
43
|
+
hidden
|
|
44
|
+
data-slot="hover-card-content"
|
|
45
|
+
data-side={side}
|
|
46
|
+
data-side-offset={sideOffset}
|
|
47
|
+
data-align={align}
|
|
48
|
+
data-align-offset={alignOffset}
|
|
49
|
+
class={cn(contentVariants(), className)}
|
|
50
|
+
>
|
|
51
|
+
<slot />
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
---
|
|
2
|
-
import { cn } from "@cl-light-ds/ui/lib/utils";
|
|
3
|
-
import type { HTMLAttributes } from "astro/types";
|
|
4
|
-
|
|
5
|
-
interface Props extends HTMLAttributes<"button"> {
|
|
6
|
-
class?: string;
|
|
7
|
-
/** Radix-like: render wrapper so the child can be the interactive element */
|
|
8
|
-
asChild?: boolean;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const {
|
|
12
|
-
class: className = "",
|
|
13
|
-
asChild = false,
|
|
14
|
-
type = "button",
|
|
15
|
-
...rest
|
|
16
|
-
} = Astro.props as Props;
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
{
|
|
20
|
-
asChild ? (
|
|
21
|
-
<div
|
|
22
|
-
data-slot="hover-card-trigger"
|
|
23
|
-
data-as-child
|
|
24
|
-
class={cn("", "inline-flex items-center", className)}
|
|
25
|
-
>
|
|
26
|
-
<slot />
|
|
27
|
-
</div>
|
|
28
|
-
) : (
|
|
29
|
-
<button
|
|
30
|
-
{...rest}
|
|
31
|
-
type={type}
|
|
32
|
-
data-slot="hover-card-trigger"
|
|
33
|
-
class={cn("", "inline-flex items-center", className)}
|
|
34
|
-
>
|
|
35
|
-
<slot />
|
|
36
|
-
</button>
|
|
37
|
-
)
|
|
38
|
-
}
|
|
1
|
+
---
|
|
2
|
+
import { cn } from "@cl-light-ds/ui/lib/utils";
|
|
3
|
+
import type { HTMLAttributes } from "astro/types";
|
|
4
|
+
|
|
5
|
+
interface Props extends HTMLAttributes<"button"> {
|
|
6
|
+
class?: string;
|
|
7
|
+
/** Radix-like: render wrapper so the child can be the interactive element */
|
|
8
|
+
asChild?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
class: className = "",
|
|
13
|
+
asChild = false,
|
|
14
|
+
type = "button",
|
|
15
|
+
...rest
|
|
16
|
+
} = Astro.props as Props;
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
{
|
|
20
|
+
asChild ? (
|
|
21
|
+
<div
|
|
22
|
+
data-slot="hover-card-trigger"
|
|
23
|
+
data-as-child
|
|
24
|
+
class={cn("", "inline-flex items-center", className)}
|
|
25
|
+
>
|
|
26
|
+
<slot />
|
|
27
|
+
</div>
|
|
28
|
+
) : (
|
|
29
|
+
<button
|
|
30
|
+
{...rest}
|
|
31
|
+
type={type}
|
|
32
|
+
data-slot="hover-card-trigger"
|
|
33
|
+
class={cn("", "inline-flex items-center", className)}
|
|
34
|
+
>
|
|
35
|
+
<slot />
|
|
36
|
+
</button>
|
|
37
|
+
)
|
|
38
|
+
}
|