@starwind-ui/core 1.12.0 → 1.12.1
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/package.json +1 -1
- package/dist/index.d.ts +0 -28
- package/dist/index.js +0 -81
- package/dist/index.js.map +0 -1
- package/dist/src/components/accordion/Accordion.astro +0 -247
- package/dist/src/components/accordion/AccordionContent.astro +0 -33
- package/dist/src/components/accordion/AccordionItem.astro +0 -27
- package/dist/src/components/accordion/AccordionTrigger.astro +0 -32
- package/dist/src/components/accordion/index.ts +0 -15
- package/dist/src/components/alert/Alert.astro +0 -31
- package/dist/src/components/alert/AlertDescription.astro +0 -14
- package/dist/src/components/alert/AlertTitle.astro +0 -16
- package/dist/src/components/alert/index.ts +0 -13
- package/dist/src/components/alert-dialog/AlertDialog.astro +0 -273
- package/dist/src/components/alert-dialog/AlertDialogAction.astro +0 -44
- package/dist/src/components/alert-dialog/AlertDialogCancel.astro +0 -45
- package/dist/src/components/alert-dialog/AlertDialogContent.astro +0 -52
- package/dist/src/components/alert-dialog/AlertDialogDescription.astro +0 -18
- package/dist/src/components/alert-dialog/AlertDialogFooter.astro +0 -16
- package/dist/src/components/alert-dialog/AlertDialogHeader.astro +0 -14
- package/dist/src/components/alert-dialog/AlertDialogTitle.astro +0 -20
- package/dist/src/components/alert-dialog/AlertDialogTrigger.astro +0 -47
- package/dist/src/components/alert-dialog/index.ts +0 -46
- package/dist/src/components/aspect-ratio/AspectRatio.astro +0 -32
- package/dist/src/components/aspect-ratio/index.ts +0 -7
- package/dist/src/components/avatar/Avatar.astro +0 -29
- package/dist/src/components/avatar/AvatarFallback.astro +0 -18
- package/dist/src/components/avatar/AvatarImage.astro +0 -49
- package/dist/src/components/avatar/index.ts +0 -13
- package/dist/src/components/badge/Badge.astro +0 -51
- package/dist/src/components/badge/index.ts +0 -7
- package/dist/src/components/breadcrumb/Breadcrumb.astro +0 -11
- package/dist/src/components/breadcrumb/BreadcrumbEllipsis.astro +0 -28
- package/dist/src/components/breadcrumb/BreadcrumbItem.astro +0 -14
- package/dist/src/components/breadcrumb/BreadcrumbLink.astro +0 -22
- package/dist/src/components/breadcrumb/BreadcrumbList.astro +0 -16
- package/dist/src/components/breadcrumb/BreadcrumbPage.astro +0 -21
- package/dist/src/components/breadcrumb/BreadcrumbSeparator.astro +0 -23
- package/dist/src/components/breadcrumb/index.ts +0 -37
- package/dist/src/components/button/Button.astro +0 -53
- package/dist/src/components/button/index.ts +0 -7
- package/dist/src/components/button-group/ButtonGroup.astro +0 -62
- package/dist/src/components/button-group/ButtonGroupSeparator.astro +0 -27
- package/dist/src/components/button-group/ButtonGroupText.astro +0 -19
- package/dist/src/components/button-group/index.ts +0 -17
- package/dist/src/components/card/Card.astro +0 -14
- package/dist/src/components/card/CardContent.astro +0 -14
- package/dist/src/components/card/CardDescription.astro +0 -14
- package/dist/src/components/card/CardFooter.astro +0 -14
- package/dist/src/components/card/CardHeader.astro +0 -14
- package/dist/src/components/card/CardTitle.astro +0 -14
- package/dist/src/components/card/index.ts +0 -26
- package/dist/src/components/carousel/Carousel.astro +0 -55
- package/dist/src/components/carousel/CarouselContent.astro +0 -26
- package/dist/src/components/carousel/CarouselItem.astro +0 -26
- package/dist/src/components/carousel/CarouselNext.astro +0 -37
- package/dist/src/components/carousel/CarouselPrevious.astro +0 -37
- package/dist/src/components/carousel/carousel-script.ts +0 -191
- package/dist/src/components/carousel/index.ts +0 -32
- package/dist/src/components/checkbox/Checkbox.astro +0 -127
- package/dist/src/components/checkbox/index.ts +0 -7
- package/dist/src/components/dialog/Dialog.astro +0 -263
- package/dist/src/components/dialog/DialogClose.astro +0 -35
- package/dist/src/components/dialog/DialogContent.astro +0 -67
- package/dist/src/components/dialog/DialogDescription.astro +0 -14
- package/dist/src/components/dialog/DialogFooter.astro +0 -14
- package/dist/src/components/dialog/DialogHeader.astro +0 -14
- package/dist/src/components/dialog/DialogTitle.astro +0 -20
- package/dist/src/components/dialog/DialogTrigger.astro +0 -47
- package/dist/src/components/dialog/index.ts +0 -45
- package/dist/src/components/dropdown/Dropdown.astro +0 -375
- package/dist/src/components/dropdown/DropdownContent.astro +0 -81
- package/dist/src/components/dropdown/DropdownItem.astro +0 -48
- package/dist/src/components/dropdown/DropdownLabel.astro +0 -29
- package/dist/src/components/dropdown/DropdownSeparator.astro +0 -21
- package/dist/src/components/dropdown/DropdownTrigger.astro +0 -52
- package/dist/src/components/dropdown/index.ts +0 -33
- package/dist/src/components/dropzone/Dropzone.astro +0 -233
- package/dist/src/components/dropzone/DropzoneFilesList.astro +0 -26
- package/dist/src/components/dropzone/DropzoneLoadingIndicator.astro +0 -10
- package/dist/src/components/dropzone/DropzoneUploadIndicator.astro +0 -10
- package/dist/src/components/dropzone/index.ts +0 -24
- package/dist/src/components/input/Input.astro +0 -24
- package/dist/src/components/input/index.ts +0 -7
- package/dist/src/components/item/Item.astro +0 -52
- package/dist/src/components/item/ItemActions.astro +0 -16
- package/dist/src/components/item/ItemContent.astro +0 -16
- package/dist/src/components/item/ItemDescription.astro +0 -19
- package/dist/src/components/item/ItemFooter.astro +0 -16
- package/dist/src/components/item/ItemGroup.astro +0 -16
- package/dist/src/components/item/ItemHeader.astro +0 -16
- package/dist/src/components/item/ItemMedia.astro +0 -40
- package/dist/src/components/item/ItemSeparator.astro +0 -21
- package/dist/src/components/item/ItemTitle.astro +0 -16
- package/dist/src/components/item/index.ts +0 -50
- package/dist/src/components/kbd/Kbd.astro +0 -21
- package/dist/src/components/kbd/KbdGroup.astro +0 -16
- package/dist/src/components/kbd/index.ts +0 -11
- package/dist/src/components/label/Label.astro +0 -22
- package/dist/src/components/label/index.ts +0 -7
- package/dist/src/components/pagination/Pagination.astro +0 -20
- package/dist/src/components/pagination/PaginationContent.astro +0 -16
- package/dist/src/components/pagination/PaginationEllipsis.astro +0 -35
- package/dist/src/components/pagination/PaginationItem.astro +0 -16
- package/dist/src/components/pagination/PaginationLink.astro +0 -24
- package/dist/src/components/pagination/PaginationNext.astro +0 -30
- package/dist/src/components/pagination/PaginationPrevious.astro +0 -30
- package/dist/src/components/pagination/index.ts +0 -38
- package/dist/src/components/progress/Progress.astro +0 -154
- package/dist/src/components/progress/index.ts +0 -10
- package/dist/src/components/radio-group/RadioGroup.astro +0 -157
- package/dist/src/components/radio-group/RadioGroupItem.astro +0 -129
- package/dist/src/components/radio-group/RadioGroupTypes.ts +0 -6
- package/dist/src/components/radio-group/index.ts +0 -23
- package/dist/src/components/select/Select.astro +0 -696
- package/dist/src/components/select/SelectContent.astro +0 -94
- package/dist/src/components/select/SelectGroup.astro +0 -9
- package/dist/src/components/select/SelectItem.astro +0 -51
- package/dist/src/components/select/SelectLabel.astro +0 -14
- package/dist/src/components/select/SelectSearch.astro +0 -49
- package/dist/src/components/select/SelectSeparator.astro +0 -12
- package/dist/src/components/select/SelectTrigger.astro +0 -58
- package/dist/src/components/select/SelectTypes.ts +0 -13
- package/dist/src/components/select/SelectValue.astro +0 -19
- package/dist/src/components/select/index.ts +0 -49
- package/dist/src/components/separator/Separator.astro +0 -36
- package/dist/src/components/separator/index.ts +0 -7
- package/dist/src/components/sheet/Sheet.astro +0 -13
- package/dist/src/components/sheet/SheetClose.astro +0 -13
- package/dist/src/components/sheet/SheetContent.astro +0 -92
- package/dist/src/components/sheet/SheetDescription.astro +0 -16
- package/dist/src/components/sheet/SheetFooter.astro +0 -16
- package/dist/src/components/sheet/SheetHeader.astro +0 -16
- package/dist/src/components/sheet/SheetTitle.astro +0 -16
- package/dist/src/components/sheet/SheetTrigger.astro +0 -13
- package/dist/src/components/sheet/index.ts +0 -41
- package/dist/src/components/skeleton/Skeleton.astro +0 -14
- package/dist/src/components/skeleton/index.ts +0 -9
- package/dist/src/components/spinner/Spinner.astro +0 -21
- package/dist/src/components/spinner/index.ts +0 -7
- package/dist/src/components/switch/Switch.astro +0 -191
- package/dist/src/components/switch/SwitchTypes.ts +0 -6
- package/dist/src/components/switch/index.ts +0 -12
- package/dist/src/components/table/Table.astro +0 -18
- package/dist/src/components/table/TableBody.astro +0 -16
- package/dist/src/components/table/TableCaption.astro +0 -16
- package/dist/src/components/table/TableCell.astro +0 -16
- package/dist/src/components/table/TableFoot.astro +0 -16
- package/dist/src/components/table/TableHead.astro +0 -16
- package/dist/src/components/table/TableHeader.astro +0 -16
- package/dist/src/components/table/TableRow.astro +0 -16
- package/dist/src/components/table/index.ts +0 -42
- package/dist/src/components/tabs/Tabs.astro +0 -269
- package/dist/src/components/tabs/TabsContent.astro +0 -28
- package/dist/src/components/tabs/TabsList.astro +0 -22
- package/dist/src/components/tabs/TabsTrigger.astro +0 -34
- package/dist/src/components/tabs/index.ts +0 -20
- package/dist/src/components/textarea/Textarea.astro +0 -28
- package/dist/src/components/textarea/index.ts +0 -9
- package/dist/src/components/toggle/Toggle.astro +0 -172
- package/dist/src/components/toggle/ToggleTypes.ts +0 -14
- package/dist/src/components/toggle/index.ts +0 -8
- package/dist/src/components/tooltip/Tooltip.astro +0 -237
- package/dist/src/components/tooltip/TooltipContent.astro +0 -114
- package/dist/src/components/tooltip/TooltipTrigger.astro +0 -10
- package/dist/src/components/tooltip/index.ts +0 -16
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
import { tv } from "tailwind-variants";
|
|
4
|
-
|
|
5
|
-
interface Props extends HTMLAttributes<"div"> {
|
|
6
|
-
defaultValue?: string;
|
|
7
|
-
syncKey?: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const tabs = tv({ base: "starwind-tabs" });
|
|
11
|
-
|
|
12
|
-
const { defaultValue, syncKey, class: className, ...rest } = Astro.props;
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
<div
|
|
16
|
-
class={tabs({ class: className })}
|
|
17
|
-
data-default-value={defaultValue}
|
|
18
|
-
data-sync-key={syncKey}
|
|
19
|
-
data-slot="tabs"
|
|
20
|
-
{...rest}
|
|
21
|
-
>
|
|
22
|
-
<slot />
|
|
23
|
-
</div>
|
|
24
|
-
|
|
25
|
-
<script>
|
|
26
|
-
type TabValue = string;
|
|
27
|
-
|
|
28
|
-
interface TabsSyncEventDetail {
|
|
29
|
-
value: TabValue;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
interface TabsSyncEvent extends CustomEvent<TabsSyncEventDetail> {
|
|
33
|
-
type: `starwind-tabs-sync:${string}`;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
class TabsHandler {
|
|
37
|
-
private tabs: HTMLElement;
|
|
38
|
-
private triggers: HTMLButtonElement[];
|
|
39
|
-
private contents: HTMLElement[];
|
|
40
|
-
private currentTabIndex: number = 0;
|
|
41
|
-
private tabsId: string;
|
|
42
|
-
private syncKey?: string;
|
|
43
|
-
private storageKey: string;
|
|
44
|
-
private valueToTriggerMap: Map<string, HTMLButtonElement>;
|
|
45
|
-
private valueToContentMap: Map<string, HTMLElement>;
|
|
46
|
-
private parentHandler: TabsHandler | null = null;
|
|
47
|
-
|
|
48
|
-
constructor(tabs: HTMLElement, idx: number, parentHandler: TabsHandler | null = null) {
|
|
49
|
-
this.tabs = tabs;
|
|
50
|
-
this.parentHandler = parentHandler;
|
|
51
|
-
this.triggers = Array.from(
|
|
52
|
-
tabs.querySelectorAll(":scope > [data-tabs-list] > [data-tabs-trigger]"),
|
|
53
|
-
);
|
|
54
|
-
this.contents = Array.from(tabs.querySelectorAll(":scope > [data-tabs-content]"));
|
|
55
|
-
this.tabsId = `starwind-tabs${idx}`;
|
|
56
|
-
this.syncKey = tabs.dataset.syncKey;
|
|
57
|
-
this.storageKey = this.syncKey
|
|
58
|
-
? `starwind-tabs-${this.syncKey}`
|
|
59
|
-
: `starwind-tabs-${this.tabsId}`;
|
|
60
|
-
|
|
61
|
-
// Create maps for faster lookups
|
|
62
|
-
this.valueToTriggerMap = new Map(
|
|
63
|
-
this.triggers.map((trigger) => [trigger.getAttribute("data-value") ?? "", trigger]),
|
|
64
|
-
);
|
|
65
|
-
this.valueToContentMap = new Map(
|
|
66
|
-
this.contents.map((content) => [content.getAttribute("data-value") ?? "", content]),
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
this.setupIds();
|
|
70
|
-
this.initializeTab();
|
|
71
|
-
this.addEventListeners();
|
|
72
|
-
|
|
73
|
-
if (this.syncKey) {
|
|
74
|
-
this.setupSyncListener();
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
private initializeTab(): void {
|
|
79
|
-
const value = this.syncKey
|
|
80
|
-
? (localStorage.getItem(this.storageKey) ?? this.tabs.dataset.defaultValue)
|
|
81
|
-
: this.tabs.dataset.defaultValue;
|
|
82
|
-
|
|
83
|
-
if (value) {
|
|
84
|
-
this.showTab(value);
|
|
85
|
-
this.currentTabIndex = this.triggers.findIndex(
|
|
86
|
-
(trigger) => trigger.getAttribute("data-value") === value,
|
|
87
|
-
);
|
|
88
|
-
this.setTabIndex();
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
private setupSyncListener(): void {
|
|
93
|
-
document.addEventListener(`starwind-tabs-sync:${this.syncKey}`, ((e: TabsSyncEvent) => {
|
|
94
|
-
const value = e.detail.value;
|
|
95
|
-
const trigger = this.valueToTriggerMap.get(value);
|
|
96
|
-
const index = trigger ? this.triggers.indexOf(trigger) : -1;
|
|
97
|
-
|
|
98
|
-
if (index !== -1) {
|
|
99
|
-
this.showTab(value);
|
|
100
|
-
this.currentTabIndex = index;
|
|
101
|
-
this.setTabIndex();
|
|
102
|
-
}
|
|
103
|
-
}) as EventListener);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
private setupIds(): void {
|
|
107
|
-
this.triggers.forEach((trigger, idx) => {
|
|
108
|
-
const triggerId = `${this.tabsId}-t${idx}`;
|
|
109
|
-
const contentId = `${this.tabsId}-c${idx}`;
|
|
110
|
-
const value = trigger.getAttribute("data-value");
|
|
111
|
-
|
|
112
|
-
trigger.id = triggerId;
|
|
113
|
-
|
|
114
|
-
if (value) {
|
|
115
|
-
trigger.setAttribute("aria-controls", contentId);
|
|
116
|
-
const content = this.valueToContentMap.get(value);
|
|
117
|
-
if (content) {
|
|
118
|
-
content.id = contentId;
|
|
119
|
-
content.setAttribute("aria-labelledby", triggerId);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
private setTabIndex(): void {
|
|
126
|
-
this.triggers.forEach((trigger, index) => {
|
|
127
|
-
trigger.setAttribute("tabindex", index === this.currentTabIndex ? "0" : "-1");
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
private dispatchSyncEvent(value: TabValue): void {
|
|
132
|
-
if (!this.syncKey) return;
|
|
133
|
-
|
|
134
|
-
document.dispatchEvent(
|
|
135
|
-
new CustomEvent(`starwind-tabs-sync:${this.syncKey}`, { detail: { value } }),
|
|
136
|
-
);
|
|
137
|
-
|
|
138
|
-
localStorage.setItem(this.storageKey, value);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
private handleKeyNavigation = (e: KeyboardEvent): void => {
|
|
142
|
-
const key = e.key;
|
|
143
|
-
let newIndex = this.currentTabIndex;
|
|
144
|
-
|
|
145
|
-
switch (key) {
|
|
146
|
-
case "ArrowRight": {
|
|
147
|
-
for (let i = 1; i < this.triggers.length; i++) {
|
|
148
|
-
const index = (this.currentTabIndex + i) % this.triggers.length;
|
|
149
|
-
if (!this.triggers[index].disabled) {
|
|
150
|
-
newIndex = index;
|
|
151
|
-
break;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
break;
|
|
155
|
-
}
|
|
156
|
-
case "ArrowLeft": {
|
|
157
|
-
for (let i = 1; i < this.triggers.length; i++) {
|
|
158
|
-
const index = (this.currentTabIndex - i + this.triggers.length) % this.triggers.length;
|
|
159
|
-
if (!this.triggers[index].disabled) {
|
|
160
|
-
newIndex = index;
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
break;
|
|
165
|
-
}
|
|
166
|
-
case "Home": {
|
|
167
|
-
for (let i = 0; i < this.triggers.length; i++) {
|
|
168
|
-
if (!this.triggers[i].disabled) {
|
|
169
|
-
newIndex = i;
|
|
170
|
-
break;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
break;
|
|
174
|
-
}
|
|
175
|
-
case "End": {
|
|
176
|
-
for (let i = this.triggers.length - 1; i >= 0; i--) {
|
|
177
|
-
if (!this.triggers[i].disabled) {
|
|
178
|
-
newIndex = i;
|
|
179
|
-
break;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
break;
|
|
183
|
-
}
|
|
184
|
-
default:
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
e.preventDefault();
|
|
189
|
-
const newTrigger = this.triggers[newIndex];
|
|
190
|
-
const value = newTrigger.getAttribute("data-value");
|
|
191
|
-
if (value) {
|
|
192
|
-
this.showTab(value);
|
|
193
|
-
this.currentTabIndex = newIndex;
|
|
194
|
-
this.setTabIndex();
|
|
195
|
-
newTrigger.focus();
|
|
196
|
-
this.dispatchSyncEvent(value);
|
|
197
|
-
}
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
private handleClick = (trigger: HTMLElement, index: number): void => {
|
|
201
|
-
const value = trigger.getAttribute("data-value");
|
|
202
|
-
if (value) {
|
|
203
|
-
this.showTab(value);
|
|
204
|
-
this.currentTabIndex = index;
|
|
205
|
-
this.setTabIndex();
|
|
206
|
-
trigger.focus();
|
|
207
|
-
this.dispatchSyncEvent(value);
|
|
208
|
-
}
|
|
209
|
-
};
|
|
210
|
-
|
|
211
|
-
private addEventListeners(): void {
|
|
212
|
-
this.triggers.forEach((trigger, index) => {
|
|
213
|
-
trigger.addEventListener("click", () => this.handleClick(trigger, index));
|
|
214
|
-
trigger.addEventListener("keydown", (e) => this.handleKeyNavigation(e));
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
private showTab(value: TabValue): void {
|
|
219
|
-
const trigger = this.valueToTriggerMap.get(value);
|
|
220
|
-
const content = this.valueToContentMap.get(value);
|
|
221
|
-
|
|
222
|
-
if (!trigger || !content) return;
|
|
223
|
-
|
|
224
|
-
// Update all triggers and contents
|
|
225
|
-
this.triggers.forEach((t) => {
|
|
226
|
-
const isActive = t === trigger;
|
|
227
|
-
t.setAttribute("data-state", isActive ? "active" : "inactive");
|
|
228
|
-
t.setAttribute("aria-selected", isActive.toString());
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
this.contents.forEach((c) => {
|
|
232
|
-
const isActive = c === content;
|
|
233
|
-
c.setAttribute("data-state", isActive ? "active" : "inactive");
|
|
234
|
-
c.hidden = !isActive;
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
// Initialize any nested tabs in the active content
|
|
238
|
-
if (content.hasAttribute("data-state") && content.getAttribute("data-state") === "active") {
|
|
239
|
-
const nestedTabs = content.querySelectorAll<HTMLElement>(".starwind-tabs");
|
|
240
|
-
|
|
241
|
-
nestedTabs.forEach((nestedTab, nestedIdx) => {
|
|
242
|
-
// Skip tabs that already have instances
|
|
243
|
-
if (!tabInstances.has(nestedTab)) {
|
|
244
|
-
const uniqueIdx = 1000 + nestedIdx;
|
|
245
|
-
const handler = new TabsHandler(nestedTab, uniqueIdx, this);
|
|
246
|
-
tabInstances.set(nestedTab, handler);
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// Store instances in a WeakMap to avoid memory leaks
|
|
254
|
-
const tabInstances = new WeakMap<HTMLElement, TabsHandler>();
|
|
255
|
-
|
|
256
|
-
const setupTabs = () => {
|
|
257
|
-
// First handle top-level tabs
|
|
258
|
-
document.querySelectorAll<HTMLElement>(".starwind-tabs").forEach((tabs, idx) => {
|
|
259
|
-
// Skip tabs that are nested within other tab contents
|
|
260
|
-
const isNested = !!tabs.closest("[data-tabs-content]");
|
|
261
|
-
if (!isNested && !tabInstances.has(tabs)) {
|
|
262
|
-
tabInstances.set(tabs, new TabsHandler(tabs, idx));
|
|
263
|
-
}
|
|
264
|
-
});
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
setupTabs();
|
|
268
|
-
document.addEventListener("astro:after-swap", setupTabs);
|
|
269
|
-
</script>
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
import { tv } from "tailwind-variants";
|
|
4
|
-
|
|
5
|
-
interface Props extends Omit<HTMLAttributes<"div">, "id" | "role" | "tabindex" | "hidden"> {
|
|
6
|
-
value: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export const tabsContent = tv({
|
|
10
|
-
base: "mt-2 focus-visible:outline-2 focus-visible:outline-offset-2",
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
const { value, class: className, ...rest } = Astro.props;
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
<div
|
|
17
|
-
class={tabsContent({ class: className })}
|
|
18
|
-
data-slot="tabs-content"
|
|
19
|
-
data-tabs-content
|
|
20
|
-
data-value={value}
|
|
21
|
-
data-state="inactive"
|
|
22
|
-
role="tabpanel"
|
|
23
|
-
tabindex="0"
|
|
24
|
-
hidden
|
|
25
|
-
{...rest}
|
|
26
|
-
>
|
|
27
|
-
<slot />
|
|
28
|
-
</div>
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
import { tv } from "tailwind-variants";
|
|
4
|
-
|
|
5
|
-
type Props = Omit<HTMLAttributes<"div">, "role">;
|
|
6
|
-
|
|
7
|
-
export const tabsList = tv({
|
|
8
|
-
base: "bg-muted text-muted-foreground inline-flex w-fit items-center justify-center rounded-md p-1",
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
const { class: className, ...rest } = Astro.props;
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
<div
|
|
15
|
-
class={tabsList({ class: className })}
|
|
16
|
-
data-slot="tabs-list"
|
|
17
|
-
data-tabs-list
|
|
18
|
-
role="tablist"
|
|
19
|
-
{...rest}
|
|
20
|
-
>
|
|
21
|
-
<slot />
|
|
22
|
-
</div>
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
import { tv } from "tailwind-variants";
|
|
4
|
-
|
|
5
|
-
interface Props extends Omit<HTMLAttributes<"button">, "type" | "id" | "role"> {
|
|
6
|
-
value: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export const tabsTrigger = tv({
|
|
10
|
-
base: [
|
|
11
|
-
"inline-flex grow items-center justify-center gap-2 rounded-sm border border-transparent px-3 py-1.5 font-medium whitespace-nowrap transition-[color,box-shadow]",
|
|
12
|
-
"data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
|
|
13
|
-
"dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 dark:text-muted-foreground",
|
|
14
|
-
"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
15
|
-
"focus-visible:border-outline focus-visible:ring-outline/50 focus-visible:outline-outline focus-visible:ring-3 focus-visible:outline-1",
|
|
16
|
-
"disabled:pointer-events-none disabled:opacity-50",
|
|
17
|
-
],
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
const { value, class: className, ...rest } = Astro.props;
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
<button
|
|
24
|
-
class={tabsTrigger({ class: className })}
|
|
25
|
-
data-slot="tabs-trigger"
|
|
26
|
-
data-tabs-trigger
|
|
27
|
-
data-value={value}
|
|
28
|
-
data-state="inactive"
|
|
29
|
-
role="tab"
|
|
30
|
-
aria-selected="false"
|
|
31
|
-
{...rest}
|
|
32
|
-
>
|
|
33
|
-
<slot />
|
|
34
|
-
</button>
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import Tabs, { tabs } from "./Tabs.astro";
|
|
2
|
-
import TabsContent, { tabsContent } from "./TabsContent.astro";
|
|
3
|
-
import TabsList, { tabsList } from "./TabsList.astro";
|
|
4
|
-
import TabsTrigger, { tabsTrigger } from "./TabsTrigger.astro";
|
|
5
|
-
|
|
6
|
-
const TabsVariants = {
|
|
7
|
-
tabs,
|
|
8
|
-
tabsContent,
|
|
9
|
-
tabsList,
|
|
10
|
-
tabsTrigger,
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export { Tabs, TabsContent, TabsList, TabsTrigger, TabsVariants };
|
|
14
|
-
|
|
15
|
-
export default {
|
|
16
|
-
Root: Tabs,
|
|
17
|
-
Content: TabsContent,
|
|
18
|
-
List: TabsList,
|
|
19
|
-
Trigger: TabsTrigger,
|
|
20
|
-
};
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
import { tv, type VariantProps } from "tailwind-variants";
|
|
4
|
-
|
|
5
|
-
type Props = HTMLAttributes<"textarea"> & VariantProps<typeof textarea>;
|
|
6
|
-
|
|
7
|
-
export const textarea = tv({
|
|
8
|
-
base: [
|
|
9
|
-
"border-input dark:bg-input/30 text-foreground ring-offset-background min-h-10 w-full rounded-md border bg-transparent shadow-xs",
|
|
10
|
-
"focus-visible:border-outline focus-visible:ring-outline/50 transition-[color,box-shadow] focus-visible:ring-3",
|
|
11
|
-
"file:text-foreground file:border-0 file:bg-transparent file:text-sm file:font-medium",
|
|
12
|
-
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
13
|
-
"peer placeholder:text-muted-foreground",
|
|
14
|
-
],
|
|
15
|
-
variants: {
|
|
16
|
-
size: {
|
|
17
|
-
sm: "min-h-9 px-2 py-1 text-sm",
|
|
18
|
-
md: "min-h-10 px-3 py-2 text-base",
|
|
19
|
-
lg: "min-h-12 px-4 py-3 text-lg",
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
defaultVariants: { size: "md" },
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
const { size, class: className, ...rest } = Astro.props;
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
<textarea class={textarea({ size, class: className })} data-slot="textarea" {...rest}></textarea>
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
import { tv, type VariantProps } from "tailwind-variants";
|
|
4
|
-
|
|
5
|
-
export const toggle = tv({
|
|
6
|
-
base: [
|
|
7
|
-
"inline-flex items-center justify-center gap-2 rounded-md font-medium whitespace-nowrap",
|
|
8
|
-
"disabled:pointer-events-none disabled:opacity-50",
|
|
9
|
-
"data-[state=on]:bg-accent data-[state=on]:text-accent-foreground",
|
|
10
|
-
"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
11
|
-
"focus-visible:border-outline focus-visible:ring-outline/50 focus-visible:ring-3",
|
|
12
|
-
"transition-colors outline-none",
|
|
13
|
-
"aria-invalid:ring-error/20 dark:aria-invalid:ring-error/40 aria-invalid:border-error",
|
|
14
|
-
],
|
|
15
|
-
variants: {
|
|
16
|
-
variant: {
|
|
17
|
-
default: "hover:bg-muted hover:text-muted-foreground bg-transparent",
|
|
18
|
-
outline:
|
|
19
|
-
"border-input hover:bg-accent hover:text-accent-foreground border bg-transparent shadow-xs",
|
|
20
|
-
},
|
|
21
|
-
size: {
|
|
22
|
-
sm: "h-9 min-w-9 px-2 text-sm",
|
|
23
|
-
md: "h-11 min-w-11 px-2.5 text-base",
|
|
24
|
-
lg: "h-12 min-w-12 px-3 text-lg",
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
defaultVariants: {
|
|
28
|
-
variant: "default",
|
|
29
|
-
size: "md",
|
|
30
|
-
},
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
type Props = VariantProps<typeof toggle> &
|
|
34
|
-
HTMLAttributes<"button"> & {
|
|
35
|
-
/**
|
|
36
|
-
* The pressed state of the toggle when initially rendered
|
|
37
|
-
*/
|
|
38
|
-
defaultPressed?: boolean;
|
|
39
|
-
/**
|
|
40
|
-
* Optional sync group name. When set, all toggles with the same sync group will mirror each other's state
|
|
41
|
-
*/
|
|
42
|
-
syncGroup?: string;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const { class: className, defaultPressed = false, syncGroup, variant, size, ...rest } = Astro.props;
|
|
46
|
-
|
|
47
|
-
const dataState = defaultPressed ? "on" : "off";
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
<button
|
|
51
|
-
type="button"
|
|
52
|
-
class={toggle({ variant, size, class: `starwind-toggle ${className || ""}` })}
|
|
53
|
-
data-slot="toggle"
|
|
54
|
-
data-state={dataState}
|
|
55
|
-
data-sync-group={syncGroup}
|
|
56
|
-
aria-pressed={defaultPressed}
|
|
57
|
-
{...rest}
|
|
58
|
-
>
|
|
59
|
-
<slot />
|
|
60
|
-
</button>
|
|
61
|
-
|
|
62
|
-
<script>
|
|
63
|
-
import type { ToggleChangeEvent, ToggleSyncEvent } from "./ToggleTypes";
|
|
64
|
-
|
|
65
|
-
class ToggleHandler {
|
|
66
|
-
private toggle: HTMLButtonElement;
|
|
67
|
-
private syncGroup?: string;
|
|
68
|
-
|
|
69
|
-
constructor(toggle: HTMLButtonElement, idx: number) {
|
|
70
|
-
this.toggle = toggle;
|
|
71
|
-
this.syncGroup = toggle.dataset.syncGroup;
|
|
72
|
-
|
|
73
|
-
if (!this.toggle.id) {
|
|
74
|
-
this.toggle.id = `starwind-toggle${idx}`;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
this.setupEventListeners();
|
|
78
|
-
|
|
79
|
-
if (this.syncGroup) {
|
|
80
|
-
this.setupSyncListener();
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
private setupEventListeners(): void {
|
|
85
|
-
this.toggle.addEventListener("click", () => this.handleToggle());
|
|
86
|
-
this.toggle.addEventListener("keydown", (event) => this.handleKeyDown(event));
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
private setupSyncListener(): void {
|
|
90
|
-
if (!this.syncGroup) return;
|
|
91
|
-
|
|
92
|
-
document.addEventListener(`starwind-toggle-sync:${this.syncGroup}`, ((e: ToggleSyncEvent) => {
|
|
93
|
-
// Don't sync if this toggle triggered the event
|
|
94
|
-
if (e.detail.sourceId === this.toggle.id) return;
|
|
95
|
-
|
|
96
|
-
const newPressed = e.detail.pressed;
|
|
97
|
-
this.updateState(newPressed, false); // false = don't dispatch sync event
|
|
98
|
-
}) as EventListener);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
private handleToggle(): void {
|
|
102
|
-
if (this.isDisabled()) return;
|
|
103
|
-
|
|
104
|
-
const isPressed = this.toggle.getAttribute("aria-pressed") === "true";
|
|
105
|
-
const newPressed = !isPressed;
|
|
106
|
-
|
|
107
|
-
this.updateState(newPressed, true);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
private handleKeyDown(event: KeyboardEvent): void {
|
|
111
|
-
if (this.isDisabled()) return;
|
|
112
|
-
|
|
113
|
-
if (event.key === " " || event.key === "Enter") {
|
|
114
|
-
event.preventDefault();
|
|
115
|
-
this.handleToggle();
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
private isDisabled(): boolean {
|
|
120
|
-
return this.toggle.disabled;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
private updateState(pressed: boolean, dispatchSync: boolean): void {
|
|
124
|
-
const newState = pressed ? "on" : "off";
|
|
125
|
-
|
|
126
|
-
this.toggle.setAttribute("aria-pressed", pressed.toString());
|
|
127
|
-
this.toggle.setAttribute("data-state", newState);
|
|
128
|
-
|
|
129
|
-
// Dispatch change event (always fired for user to listen to)
|
|
130
|
-
const changeEvent = new CustomEvent<ToggleChangeEvent["detail"]>("starwind-toggle:change", {
|
|
131
|
-
detail: {
|
|
132
|
-
pressed,
|
|
133
|
-
toggleId: this.toggle.id,
|
|
134
|
-
syncGroup: this.syncGroup,
|
|
135
|
-
},
|
|
136
|
-
bubbles: true,
|
|
137
|
-
cancelable: true,
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
this.toggle.dispatchEvent(changeEvent);
|
|
141
|
-
|
|
142
|
-
// Dispatch sync event if in a sync group and requested
|
|
143
|
-
if (this.syncGroup && dispatchSync) {
|
|
144
|
-
const syncEvent = new CustomEvent<ToggleSyncEvent["detail"]>(
|
|
145
|
-
`starwind-toggle-sync:${this.syncGroup}`,
|
|
146
|
-
{
|
|
147
|
-
detail: {
|
|
148
|
-
pressed,
|
|
149
|
-
sourceId: this.toggle.id,
|
|
150
|
-
},
|
|
151
|
-
},
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
document.dispatchEvent(syncEvent);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Store instances in a WeakMap to avoid memory leaks
|
|
160
|
-
const toggleInstances = new WeakMap<HTMLElement, ToggleHandler>();
|
|
161
|
-
|
|
162
|
-
const setupToggles = () => {
|
|
163
|
-
document.querySelectorAll<HTMLButtonElement>(".starwind-toggle").forEach((toggle, idx) => {
|
|
164
|
-
if (!toggleInstances.has(toggle)) {
|
|
165
|
-
toggleInstances.set(toggle, new ToggleHandler(toggle, idx));
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
setupToggles();
|
|
171
|
-
document.addEventListener("astro:after-swap", setupToggles);
|
|
172
|
-
</script>
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export interface ToggleChangeEvent extends CustomEvent {
|
|
2
|
-
detail: {
|
|
3
|
-
pressed: boolean;
|
|
4
|
-
toggleId: string;
|
|
5
|
-
syncGroup?: string;
|
|
6
|
-
};
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface ToggleSyncEvent extends CustomEvent {
|
|
10
|
-
detail: {
|
|
11
|
-
pressed: boolean;
|
|
12
|
-
sourceId: string;
|
|
13
|
-
};
|
|
14
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import Toggle, { toggle } from "./Toggle.astro";
|
|
2
|
-
import type { ToggleChangeEvent, ToggleSyncEvent } from "./ToggleTypes";
|
|
3
|
-
|
|
4
|
-
const ToggleVariants = { toggle };
|
|
5
|
-
|
|
6
|
-
export { Toggle, type ToggleChangeEvent, type ToggleSyncEvent, ToggleVariants };
|
|
7
|
-
|
|
8
|
-
export default Toggle;
|