@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.
Files changed (166) hide show
  1. package/package.json +1 -1
  2. package/dist/index.d.ts +0 -28
  3. package/dist/index.js +0 -81
  4. package/dist/index.js.map +0 -1
  5. package/dist/src/components/accordion/Accordion.astro +0 -247
  6. package/dist/src/components/accordion/AccordionContent.astro +0 -33
  7. package/dist/src/components/accordion/AccordionItem.astro +0 -27
  8. package/dist/src/components/accordion/AccordionTrigger.astro +0 -32
  9. package/dist/src/components/accordion/index.ts +0 -15
  10. package/dist/src/components/alert/Alert.astro +0 -31
  11. package/dist/src/components/alert/AlertDescription.astro +0 -14
  12. package/dist/src/components/alert/AlertTitle.astro +0 -16
  13. package/dist/src/components/alert/index.ts +0 -13
  14. package/dist/src/components/alert-dialog/AlertDialog.astro +0 -273
  15. package/dist/src/components/alert-dialog/AlertDialogAction.astro +0 -44
  16. package/dist/src/components/alert-dialog/AlertDialogCancel.astro +0 -45
  17. package/dist/src/components/alert-dialog/AlertDialogContent.astro +0 -52
  18. package/dist/src/components/alert-dialog/AlertDialogDescription.astro +0 -18
  19. package/dist/src/components/alert-dialog/AlertDialogFooter.astro +0 -16
  20. package/dist/src/components/alert-dialog/AlertDialogHeader.astro +0 -14
  21. package/dist/src/components/alert-dialog/AlertDialogTitle.astro +0 -20
  22. package/dist/src/components/alert-dialog/AlertDialogTrigger.astro +0 -47
  23. package/dist/src/components/alert-dialog/index.ts +0 -46
  24. package/dist/src/components/aspect-ratio/AspectRatio.astro +0 -32
  25. package/dist/src/components/aspect-ratio/index.ts +0 -7
  26. package/dist/src/components/avatar/Avatar.astro +0 -29
  27. package/dist/src/components/avatar/AvatarFallback.astro +0 -18
  28. package/dist/src/components/avatar/AvatarImage.astro +0 -49
  29. package/dist/src/components/avatar/index.ts +0 -13
  30. package/dist/src/components/badge/Badge.astro +0 -51
  31. package/dist/src/components/badge/index.ts +0 -7
  32. package/dist/src/components/breadcrumb/Breadcrumb.astro +0 -11
  33. package/dist/src/components/breadcrumb/BreadcrumbEllipsis.astro +0 -28
  34. package/dist/src/components/breadcrumb/BreadcrumbItem.astro +0 -14
  35. package/dist/src/components/breadcrumb/BreadcrumbLink.astro +0 -22
  36. package/dist/src/components/breadcrumb/BreadcrumbList.astro +0 -16
  37. package/dist/src/components/breadcrumb/BreadcrumbPage.astro +0 -21
  38. package/dist/src/components/breadcrumb/BreadcrumbSeparator.astro +0 -23
  39. package/dist/src/components/breadcrumb/index.ts +0 -37
  40. package/dist/src/components/button/Button.astro +0 -53
  41. package/dist/src/components/button/index.ts +0 -7
  42. package/dist/src/components/button-group/ButtonGroup.astro +0 -62
  43. package/dist/src/components/button-group/ButtonGroupSeparator.astro +0 -27
  44. package/dist/src/components/button-group/ButtonGroupText.astro +0 -19
  45. package/dist/src/components/button-group/index.ts +0 -17
  46. package/dist/src/components/card/Card.astro +0 -14
  47. package/dist/src/components/card/CardContent.astro +0 -14
  48. package/dist/src/components/card/CardDescription.astro +0 -14
  49. package/dist/src/components/card/CardFooter.astro +0 -14
  50. package/dist/src/components/card/CardHeader.astro +0 -14
  51. package/dist/src/components/card/CardTitle.astro +0 -14
  52. package/dist/src/components/card/index.ts +0 -26
  53. package/dist/src/components/carousel/Carousel.astro +0 -55
  54. package/dist/src/components/carousel/CarouselContent.astro +0 -26
  55. package/dist/src/components/carousel/CarouselItem.astro +0 -26
  56. package/dist/src/components/carousel/CarouselNext.astro +0 -37
  57. package/dist/src/components/carousel/CarouselPrevious.astro +0 -37
  58. package/dist/src/components/carousel/carousel-script.ts +0 -191
  59. package/dist/src/components/carousel/index.ts +0 -32
  60. package/dist/src/components/checkbox/Checkbox.astro +0 -127
  61. package/dist/src/components/checkbox/index.ts +0 -7
  62. package/dist/src/components/dialog/Dialog.astro +0 -263
  63. package/dist/src/components/dialog/DialogClose.astro +0 -35
  64. package/dist/src/components/dialog/DialogContent.astro +0 -67
  65. package/dist/src/components/dialog/DialogDescription.astro +0 -14
  66. package/dist/src/components/dialog/DialogFooter.astro +0 -14
  67. package/dist/src/components/dialog/DialogHeader.astro +0 -14
  68. package/dist/src/components/dialog/DialogTitle.astro +0 -20
  69. package/dist/src/components/dialog/DialogTrigger.astro +0 -47
  70. package/dist/src/components/dialog/index.ts +0 -45
  71. package/dist/src/components/dropdown/Dropdown.astro +0 -375
  72. package/dist/src/components/dropdown/DropdownContent.astro +0 -81
  73. package/dist/src/components/dropdown/DropdownItem.astro +0 -48
  74. package/dist/src/components/dropdown/DropdownLabel.astro +0 -29
  75. package/dist/src/components/dropdown/DropdownSeparator.astro +0 -21
  76. package/dist/src/components/dropdown/DropdownTrigger.astro +0 -52
  77. package/dist/src/components/dropdown/index.ts +0 -33
  78. package/dist/src/components/dropzone/Dropzone.astro +0 -233
  79. package/dist/src/components/dropzone/DropzoneFilesList.astro +0 -26
  80. package/dist/src/components/dropzone/DropzoneLoadingIndicator.astro +0 -10
  81. package/dist/src/components/dropzone/DropzoneUploadIndicator.astro +0 -10
  82. package/dist/src/components/dropzone/index.ts +0 -24
  83. package/dist/src/components/input/Input.astro +0 -24
  84. package/dist/src/components/input/index.ts +0 -7
  85. package/dist/src/components/item/Item.astro +0 -52
  86. package/dist/src/components/item/ItemActions.astro +0 -16
  87. package/dist/src/components/item/ItemContent.astro +0 -16
  88. package/dist/src/components/item/ItemDescription.astro +0 -19
  89. package/dist/src/components/item/ItemFooter.astro +0 -16
  90. package/dist/src/components/item/ItemGroup.astro +0 -16
  91. package/dist/src/components/item/ItemHeader.astro +0 -16
  92. package/dist/src/components/item/ItemMedia.astro +0 -40
  93. package/dist/src/components/item/ItemSeparator.astro +0 -21
  94. package/dist/src/components/item/ItemTitle.astro +0 -16
  95. package/dist/src/components/item/index.ts +0 -50
  96. package/dist/src/components/kbd/Kbd.astro +0 -21
  97. package/dist/src/components/kbd/KbdGroup.astro +0 -16
  98. package/dist/src/components/kbd/index.ts +0 -11
  99. package/dist/src/components/label/Label.astro +0 -22
  100. package/dist/src/components/label/index.ts +0 -7
  101. package/dist/src/components/pagination/Pagination.astro +0 -20
  102. package/dist/src/components/pagination/PaginationContent.astro +0 -16
  103. package/dist/src/components/pagination/PaginationEllipsis.astro +0 -35
  104. package/dist/src/components/pagination/PaginationItem.astro +0 -16
  105. package/dist/src/components/pagination/PaginationLink.astro +0 -24
  106. package/dist/src/components/pagination/PaginationNext.astro +0 -30
  107. package/dist/src/components/pagination/PaginationPrevious.astro +0 -30
  108. package/dist/src/components/pagination/index.ts +0 -38
  109. package/dist/src/components/progress/Progress.astro +0 -154
  110. package/dist/src/components/progress/index.ts +0 -10
  111. package/dist/src/components/radio-group/RadioGroup.astro +0 -157
  112. package/dist/src/components/radio-group/RadioGroupItem.astro +0 -129
  113. package/dist/src/components/radio-group/RadioGroupTypes.ts +0 -6
  114. package/dist/src/components/radio-group/index.ts +0 -23
  115. package/dist/src/components/select/Select.astro +0 -696
  116. package/dist/src/components/select/SelectContent.astro +0 -94
  117. package/dist/src/components/select/SelectGroup.astro +0 -9
  118. package/dist/src/components/select/SelectItem.astro +0 -51
  119. package/dist/src/components/select/SelectLabel.astro +0 -14
  120. package/dist/src/components/select/SelectSearch.astro +0 -49
  121. package/dist/src/components/select/SelectSeparator.astro +0 -12
  122. package/dist/src/components/select/SelectTrigger.astro +0 -58
  123. package/dist/src/components/select/SelectTypes.ts +0 -13
  124. package/dist/src/components/select/SelectValue.astro +0 -19
  125. package/dist/src/components/select/index.ts +0 -49
  126. package/dist/src/components/separator/Separator.astro +0 -36
  127. package/dist/src/components/separator/index.ts +0 -7
  128. package/dist/src/components/sheet/Sheet.astro +0 -13
  129. package/dist/src/components/sheet/SheetClose.astro +0 -13
  130. package/dist/src/components/sheet/SheetContent.astro +0 -92
  131. package/dist/src/components/sheet/SheetDescription.astro +0 -16
  132. package/dist/src/components/sheet/SheetFooter.astro +0 -16
  133. package/dist/src/components/sheet/SheetHeader.astro +0 -16
  134. package/dist/src/components/sheet/SheetTitle.astro +0 -16
  135. package/dist/src/components/sheet/SheetTrigger.astro +0 -13
  136. package/dist/src/components/sheet/index.ts +0 -41
  137. package/dist/src/components/skeleton/Skeleton.astro +0 -14
  138. package/dist/src/components/skeleton/index.ts +0 -9
  139. package/dist/src/components/spinner/Spinner.astro +0 -21
  140. package/dist/src/components/spinner/index.ts +0 -7
  141. package/dist/src/components/switch/Switch.astro +0 -191
  142. package/dist/src/components/switch/SwitchTypes.ts +0 -6
  143. package/dist/src/components/switch/index.ts +0 -12
  144. package/dist/src/components/table/Table.astro +0 -18
  145. package/dist/src/components/table/TableBody.astro +0 -16
  146. package/dist/src/components/table/TableCaption.astro +0 -16
  147. package/dist/src/components/table/TableCell.astro +0 -16
  148. package/dist/src/components/table/TableFoot.astro +0 -16
  149. package/dist/src/components/table/TableHead.astro +0 -16
  150. package/dist/src/components/table/TableHeader.astro +0 -16
  151. package/dist/src/components/table/TableRow.astro +0 -16
  152. package/dist/src/components/table/index.ts +0 -42
  153. package/dist/src/components/tabs/Tabs.astro +0 -269
  154. package/dist/src/components/tabs/TabsContent.astro +0 -28
  155. package/dist/src/components/tabs/TabsList.astro +0 -22
  156. package/dist/src/components/tabs/TabsTrigger.astro +0 -34
  157. package/dist/src/components/tabs/index.ts +0 -20
  158. package/dist/src/components/textarea/Textarea.astro +0 -28
  159. package/dist/src/components/textarea/index.ts +0 -9
  160. package/dist/src/components/toggle/Toggle.astro +0 -172
  161. package/dist/src/components/toggle/ToggleTypes.ts +0 -14
  162. package/dist/src/components/toggle/index.ts +0 -8
  163. package/dist/src/components/tooltip/Tooltip.astro +0 -237
  164. package/dist/src/components/tooltip/TooltipContent.astro +0 -114
  165. package/dist/src/components/tooltip/TooltipTrigger.astro +0 -10
  166. 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,9 +0,0 @@
1
- import Textarea, { textarea } from "./Textarea.astro";
2
-
3
- const TextareaVariants = {
4
- textarea,
5
- };
6
-
7
- export { Textarea, TextareaVariants };
8
-
9
- export default 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;