@starwind-ui/core 1.14.0 → 1.15.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 (179) hide show
  1. package/package.json +1 -1
  2. package/dist/index.d.ts +0 -28
  3. package/dist/index.js +0 -85
  4. package/dist/index.js.map +0 -1
  5. package/dist/src/components/accordion/Accordion.astro +0 -254
  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 -275
  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 -49
  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 -54
  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 -128
  61. package/dist/src/components/checkbox/index.ts +0 -7
  62. package/dist/src/components/dialog/Dialog.astro +0 -355
  63. package/dist/src/components/dialog/DialogClose.astro +0 -35
  64. package/dist/src/components/dialog/DialogContent.astro +0 -78
  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 -22
  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 -377
  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 -236
  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/image/Image.astro +0 -24
  84. package/dist/src/components/image/index.ts +0 -9
  85. package/dist/src/components/input/Input.astro +0 -25
  86. package/dist/src/components/input/index.ts +0 -7
  87. package/dist/src/components/item/Item.astro +0 -52
  88. package/dist/src/components/item/ItemActions.astro +0 -16
  89. package/dist/src/components/item/ItemContent.astro +0 -16
  90. package/dist/src/components/item/ItemDescription.astro +0 -19
  91. package/dist/src/components/item/ItemFooter.astro +0 -16
  92. package/dist/src/components/item/ItemGroup.astro +0 -16
  93. package/dist/src/components/item/ItemHeader.astro +0 -16
  94. package/dist/src/components/item/ItemMedia.astro +0 -40
  95. package/dist/src/components/item/ItemSeparator.astro +0 -21
  96. package/dist/src/components/item/ItemTitle.astro +0 -16
  97. package/dist/src/components/item/index.ts +0 -50
  98. package/dist/src/components/kbd/Kbd.astro +0 -21
  99. package/dist/src/components/kbd/KbdGroup.astro +0 -16
  100. package/dist/src/components/kbd/index.ts +0 -11
  101. package/dist/src/components/label/Label.astro +0 -22
  102. package/dist/src/components/label/index.ts +0 -7
  103. package/dist/src/components/pagination/Pagination.astro +0 -20
  104. package/dist/src/components/pagination/PaginationContent.astro +0 -16
  105. package/dist/src/components/pagination/PaginationEllipsis.astro +0 -35
  106. package/dist/src/components/pagination/PaginationItem.astro +0 -16
  107. package/dist/src/components/pagination/PaginationLink.astro +0 -24
  108. package/dist/src/components/pagination/PaginationNext.astro +0 -30
  109. package/dist/src/components/pagination/PaginationPrevious.astro +0 -30
  110. package/dist/src/components/pagination/index.ts +0 -38
  111. package/dist/src/components/progress/Progress.astro +0 -155
  112. package/dist/src/components/progress/index.ts +0 -10
  113. package/dist/src/components/radio-group/RadioGroup.astro +0 -162
  114. package/dist/src/components/radio-group/RadioGroupItem.astro +0 -129
  115. package/dist/src/components/radio-group/RadioGroupTypes.ts +0 -6
  116. package/dist/src/components/radio-group/index.ts +0 -23
  117. package/dist/src/components/select/Select.astro +0 -751
  118. package/dist/src/components/select/SelectContent.astro +0 -94
  119. package/dist/src/components/select/SelectGroup.astro +0 -9
  120. package/dist/src/components/select/SelectItem.astro +0 -51
  121. package/dist/src/components/select/SelectLabel.astro +0 -14
  122. package/dist/src/components/select/SelectSearch.astro +0 -49
  123. package/dist/src/components/select/SelectSeparator.astro +0 -12
  124. package/dist/src/components/select/SelectTrigger.astro +0 -54
  125. package/dist/src/components/select/SelectTypes.ts +0 -13
  126. package/dist/src/components/select/SelectValue.astro +0 -19
  127. package/dist/src/components/select/index.ts +0 -49
  128. package/dist/src/components/separator/Separator.astro +0 -36
  129. package/dist/src/components/separator/index.ts +0 -7
  130. package/dist/src/components/sheet/Sheet.astro +0 -13
  131. package/dist/src/components/sheet/SheetClose.astro +0 -13
  132. package/dist/src/components/sheet/SheetContent.astro +0 -92
  133. package/dist/src/components/sheet/SheetDescription.astro +0 -16
  134. package/dist/src/components/sheet/SheetFooter.astro +0 -16
  135. package/dist/src/components/sheet/SheetHeader.astro +0 -16
  136. package/dist/src/components/sheet/SheetTitle.astro +0 -16
  137. package/dist/src/components/sheet/SheetTrigger.astro +0 -13
  138. package/dist/src/components/sheet/index.ts +0 -41
  139. package/dist/src/components/skeleton/Skeleton.astro +0 -14
  140. package/dist/src/components/skeleton/index.ts +0 -9
  141. package/dist/src/components/slider/Slider.astro +0 -411
  142. package/dist/src/components/slider/index.ts +0 -9
  143. package/dist/src/components/spinner/Spinner.astro +0 -21
  144. package/dist/src/components/spinner/index.ts +0 -7
  145. package/dist/src/components/switch/Switch.astro +0 -192
  146. package/dist/src/components/switch/SwitchTypes.ts +0 -6
  147. package/dist/src/components/switch/index.ts +0 -12
  148. package/dist/src/components/table/Table.astro +0 -18
  149. package/dist/src/components/table/TableBody.astro +0 -16
  150. package/dist/src/components/table/TableCaption.astro +0 -16
  151. package/dist/src/components/table/TableCell.astro +0 -16
  152. package/dist/src/components/table/TableFoot.astro +0 -16
  153. package/dist/src/components/table/TableHead.astro +0 -16
  154. package/dist/src/components/table/TableHeader.astro +0 -16
  155. package/dist/src/components/table/TableRow.astro +0 -16
  156. package/dist/src/components/table/index.ts +0 -42
  157. package/dist/src/components/tabs/Tabs.astro +0 -271
  158. package/dist/src/components/tabs/TabsContent.astro +0 -28
  159. package/dist/src/components/tabs/TabsList.astro +0 -22
  160. package/dist/src/components/tabs/TabsTrigger.astro +0 -34
  161. package/dist/src/components/tabs/index.ts +0 -20
  162. package/dist/src/components/textarea/Textarea.astro +0 -29
  163. package/dist/src/components/textarea/index.ts +0 -9
  164. package/dist/src/components/toast/ToastDescription.astro +0 -21
  165. package/dist/src/components/toast/ToastItem.astro +0 -54
  166. package/dist/src/components/toast/ToastTemplate.astro +0 -25
  167. package/dist/src/components/toast/ToastTitle.astro +0 -57
  168. package/dist/src/components/toast/Toaster.astro +0 -982
  169. package/dist/src/components/toast/index.ts +0 -29
  170. package/dist/src/components/toast/toast-manager.ts +0 -216
  171. package/dist/src/components/toggle/Toggle.astro +0 -174
  172. package/dist/src/components/toggle/ToggleTypes.ts +0 -14
  173. package/dist/src/components/toggle/index.ts +0 -8
  174. package/dist/src/components/tooltip/Tooltip.astro +0 -239
  175. package/dist/src/components/tooltip/TooltipContent.astro +0 -114
  176. package/dist/src/components/tooltip/TooltipTrigger.astro +0 -10
  177. package/dist/src/components/tooltip/index.ts +0 -16
  178. package/dist/src/components/video/Video.astro +0 -120
  179. package/dist/src/components/video/index.ts +0 -9
@@ -1,9 +0,0 @@
1
- import Skeleton, { skeleton } from "./Skeleton.astro";
2
-
3
- const SkeletonVariants = {
4
- skeleton,
5
- };
6
-
7
- export { Skeleton, SkeletonVariants };
8
-
9
- export default Skeleton;
@@ -1,411 +0,0 @@
1
- ---
2
- import type { HTMLAttributes } from "astro/types";
3
- import { tv } from "tailwind-variants";
4
-
5
- export const slider = tv({
6
- slots: {
7
- root: "starwind-slider relative flex w-full touch-none items-center select-none data-[disabled]:opacity-50 data-[orientation=vertical]:h-full data-[orientation=vertical]:w-auto",
8
- control:
9
- "starwind-slider-control relative w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-auto",
10
- track:
11
- "starwind-slider-track bg-muted relative overflow-hidden rounded-full data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5",
12
- range:
13
- "starwind-slider-range absolute data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full",
14
- thumb:
15
- "starwind-slider-thumb absolute block size-4 shrink-0 rounded-full border bg-white shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50 data-[orientation=horizontal]:top-1/2 data-[orientation=horizontal]:-translate-x-1/2 data-[orientation=horizontal]:-translate-y-1/2 data-[orientation=vertical]:left-1/2 data-[orientation=vertical]:-translate-x-1/2 data-[orientation=vertical]:translate-y-1/2",
16
- },
17
- variants: {
18
- variant: {
19
- default: {
20
- range: "bg-foreground",
21
- thumb: "border-foreground ring-outline/50",
22
- },
23
- primary: {
24
- range: "bg-primary",
25
- thumb: "border-primary ring-primary/50",
26
- },
27
- secondary: {
28
- range: "bg-secondary",
29
- thumb: "border-secondary ring-secondary/50",
30
- },
31
- info: {
32
- range: "bg-info",
33
- thumb: "border-info ring-info/50",
34
- },
35
- success: {
36
- range: "bg-success",
37
- thumb: "border-success ring-success/50",
38
- },
39
- warning: {
40
- range: "bg-warning",
41
- thumb: "border-warning ring-warning/50",
42
- },
43
- error: {
44
- range: "bg-error",
45
- thumb: "border-error ring-error/50",
46
- },
47
- },
48
- },
49
- defaultVariants: {
50
- variant: "default",
51
- },
52
- });
53
-
54
- type Variant = "default" | "primary" | "secondary" | "info" | "success" | "warning" | "error";
55
-
56
- type Props = HTMLAttributes<"div"> & {
57
- defaultValue?: number | number[];
58
- value?: number | number[];
59
- min?: number;
60
- max?: number;
61
- step?: number;
62
- largeStep?: number;
63
- orientation?: "horizontal" | "vertical";
64
- disabled?: boolean;
65
- name?: string;
66
- variant?: Variant;
67
- "aria-label"?: string;
68
- "aria-labelledby"?: string;
69
- };
70
-
71
- const {
72
- class: className,
73
- defaultValue = 0,
74
- value,
75
- min = 0,
76
- max = 100,
77
- step = 1,
78
- largeStep = 10,
79
- orientation = "horizontal",
80
- disabled = false,
81
- name,
82
- variant = "default",
83
- "aria-label": ariaLabel,
84
- "aria-labelledby": ariaLabelledby,
85
- ...rest
86
- } = Astro.props;
87
-
88
- const { root, control, track, range, thumb } = slider({ variant });
89
-
90
- const initialValue = value ?? defaultValue;
91
- const values = Array.isArray(initialValue) ? initialValue : [initialValue];
92
- const isRange = values.length > 1;
93
-
94
- function getPercentage(val: number): number {
95
- return ((val - min) / (max - min)) * 100;
96
- }
97
-
98
- const rangeStart = isRange ? getPercentage(Math.min(...values)) : 0;
99
- const rangeEnd = isRange ? getPercentage(Math.max(...values)) : getPercentage(values[0]);
100
- ---
101
-
102
- <div
103
- class={root({ class: className })}
104
- data-slot="slider"
105
- data-orientation={orientation}
106
- data-disabled={disabled ? "" : undefined}
107
- role="group"
108
- aria-labelledby={ariaLabelledby}
109
- data-min={min}
110
- data-max={max}
111
- data-step={step}
112
- data-large-step={largeStep}
113
- {...rest}
114
- >
115
- <div class={control()} data-slot="slider-control" data-orientation={orientation}>
116
- <div class={track()} data-slot="slider-track" data-orientation={orientation}>
117
- <div
118
- class={range()}
119
- data-slot="slider-range"
120
- data-orientation={orientation}
121
- style={orientation === "horizontal"
122
- ? `left: ${rangeStart}%; width: ${rangeEnd - rangeStart}%`
123
- : `bottom: ${rangeStart}%; height: ${rangeEnd - rangeStart}%`}
124
- >
125
- </div>
126
- </div>
127
- {
128
- values.map((val, index) => (
129
- <div
130
- class={thumb()}
131
- data-slot="slider-thumb"
132
- data-index={index}
133
- data-orientation={orientation}
134
- style={
135
- orientation === "horizontal"
136
- ? `left: ${getPercentage(val)}%`
137
- : `bottom: ${getPercentage(val)}%`
138
- }
139
- tabindex={disabled ? -1 : 0}
140
- role="slider"
141
- aria-label={ariaLabel}
142
- aria-valuemin={min}
143
- aria-valuemax={max}
144
- aria-valuenow={val}
145
- aria-orientation={orientation}
146
- aria-disabled={disabled}
147
- >
148
- <input
149
- type="range"
150
- min={min}
151
- max={max}
152
- step={step}
153
- value={val}
154
- name={name ? (isRange ? `${name}[${index}]` : name) : undefined}
155
- disabled={disabled}
156
- tabindex={-1}
157
- aria-hidden="true"
158
- class="sr-only"
159
- />
160
- </div>
161
- ))
162
- }
163
- </div>
164
- </div>
165
-
166
- <script>
167
- class StarwindSlider {
168
- private root: HTMLElement;
169
- private track: HTMLElement;
170
- private range: HTMLElement;
171
- private thumbs: HTMLElement[];
172
- private inputs: HTMLInputElement[];
173
- private min: number;
174
- private max: number;
175
- private step: number;
176
- private largeStep: number;
177
- private orientation: "horizontal" | "vertical";
178
- private disabled: boolean;
179
- private values: number[];
180
- private activeThumbIndex: number = -1;
181
- private dragging: boolean = false;
182
-
183
- constructor(root: HTMLElement) {
184
- this.root = root;
185
- this.track = root.querySelector('[data-slot="slider-track"]')!;
186
- this.range = root.querySelector('[data-slot="slider-range"]')!;
187
- this.thumbs = Array.from(root.querySelectorAll('[data-slot="slider-thumb"]'));
188
- this.inputs = Array.from(root.querySelectorAll('input[type="range"]'));
189
-
190
- this.min = Number(root.dataset.min) || 0;
191
- this.max = Number(root.dataset.max) || 100;
192
- this.step = Number(root.dataset.step) || 1;
193
- this.largeStep = Number(root.dataset.largeStep) || 10;
194
- this.orientation = (root.dataset.orientation as "horizontal" | "vertical") || "horizontal";
195
- this.disabled = root.hasAttribute("data-disabled");
196
-
197
- this.values = this.inputs.map((input) => Number(input.value));
198
-
199
- this.init();
200
- }
201
-
202
- private init(): void {
203
- if (this.disabled) return;
204
-
205
- this.thumbs.forEach((thumb, index) => {
206
- thumb.addEventListener("pointerdown", (e) => this.handleThumbPointerDown(e, index));
207
- thumb.addEventListener("keydown", (e) => this.handleKeyDown(e, index));
208
- thumb.addEventListener("focus", () => this.handleFocus(index));
209
- thumb.addEventListener("blur", () => this.handleBlur());
210
- });
211
-
212
- this.track.addEventListener("pointerdown", (e) => this.handleTrackClick(e));
213
-
214
- document.addEventListener("pointermove", (e) => this.handlePointerMove(e));
215
- document.addEventListener("pointerup", () => this.handlePointerUp());
216
- }
217
-
218
- private getPercentage(val: number): number {
219
- return ((val - this.min) / (this.max - this.min)) * 100;
220
- }
221
-
222
- private getValueFromPosition(clientX: number, clientY: number): number {
223
- const rect = this.track.getBoundingClientRect();
224
- let percentage: number;
225
-
226
- if (this.orientation === "horizontal") {
227
- percentage = (clientX - rect.left) / rect.width;
228
- } else {
229
- percentage = 1 - (clientY - rect.top) / rect.height;
230
- }
231
-
232
- percentage = Math.max(0, Math.min(1, percentage));
233
- const rawValue = this.min + percentage * (this.max - this.min);
234
- return this.snapToStep(rawValue);
235
- }
236
-
237
- private snapToStep(value: number): number {
238
- const snapped = Math.round((value - this.min) / this.step) * this.step + this.min;
239
- return Math.max(this.min, Math.min(this.max, snapped));
240
- }
241
-
242
- private updateValue(index: number, newValue: number): void {
243
- const isRange = this.values.length > 1;
244
-
245
- if (isRange) {
246
- if (index === 0 && newValue > this.values[1]) {
247
- newValue = this.values[1];
248
- } else if (index === 1 && newValue < this.values[0]) {
249
- newValue = this.values[0];
250
- }
251
- }
252
-
253
- this.values[index] = newValue;
254
- this.inputs[index].value = String(newValue);
255
-
256
- this.updateVisuals();
257
- this.dispatchChangeEvent();
258
- }
259
-
260
- private updateVisuals(): void {
261
- const isRange = this.values.length > 1;
262
- const rangeStart = isRange ? this.getPercentage(Math.min(...this.values)) : 0;
263
- const rangeEnd = isRange
264
- ? this.getPercentage(Math.max(...this.values))
265
- : this.getPercentage(this.values[0]);
266
-
267
- if (this.orientation === "horizontal") {
268
- this.range.style.left = `${rangeStart}%`;
269
- this.range.style.width = `${rangeEnd - rangeStart}%`;
270
- } else {
271
- this.range.style.bottom = `${rangeStart}%`;
272
- this.range.style.height = `${rangeEnd - rangeStart}%`;
273
- }
274
-
275
- this.thumbs.forEach((thumb, index) => {
276
- const percentage = this.getPercentage(this.values[index]);
277
- if (this.orientation === "horizontal") {
278
- thumb.style.left = `${percentage}%`;
279
- } else {
280
- thumb.style.bottom = `${percentage}%`;
281
- }
282
- thumb.setAttribute("aria-valuenow", String(this.values[index]));
283
- });
284
- }
285
-
286
- private dispatchChangeEvent(): void {
287
- const value = this.values.length === 1 ? this.values[0] : [...this.values];
288
- this.root.dispatchEvent(
289
- new CustomEvent("slider-change", {
290
- detail: { value },
291
- bubbles: true,
292
- }),
293
- );
294
- }
295
-
296
- private handleThumbPointerDown(e: PointerEvent, index: number): void {
297
- if (this.disabled) return;
298
- e.preventDefault();
299
- this.activeThumbIndex = index;
300
- this.dragging = true;
301
- this.root.setAttribute("data-dragging", "");
302
- this.thumbs[index].setAttribute("data-dragging", "");
303
- this.thumbs[index].focus();
304
- (e.target as HTMLElement).setPointerCapture(e.pointerId);
305
- }
306
-
307
- private handlePointerMove(e: PointerEvent): void {
308
- if (!this.dragging || this.activeThumbIndex === -1) return;
309
- const newValue = this.getValueFromPosition(e.clientX, e.clientY);
310
- this.updateValue(this.activeThumbIndex, newValue);
311
- }
312
-
313
- private handlePointerUp(): void {
314
- if (!this.dragging) return;
315
- this.dragging = false;
316
- this.root.removeAttribute("data-dragging");
317
- this.thumbs.forEach((thumb) => thumb.removeAttribute("data-dragging"));
318
-
319
- const value = this.values.length === 1 ? this.values[0] : [...this.values];
320
- this.root.dispatchEvent(
321
- new CustomEvent("slider-commit", {
322
- detail: { value },
323
- bubbles: true,
324
- }),
325
- );
326
-
327
- this.activeThumbIndex = -1;
328
- }
329
-
330
- private handleTrackClick(e: PointerEvent): void {
331
- if (this.disabled) return;
332
- const newValue = this.getValueFromPosition(e.clientX, e.clientY);
333
-
334
- let closestIndex = 0;
335
- if (this.values.length > 1) {
336
- const distances = this.values.map((v) => Math.abs(v - newValue));
337
- closestIndex = distances.indexOf(Math.min(...distances));
338
- }
339
-
340
- this.updateValue(closestIndex, newValue);
341
- this.thumbs[closestIndex].focus();
342
- }
343
-
344
- private handleKeyDown(e: KeyboardEvent, index: number): void {
345
- if (this.disabled) return;
346
-
347
- let newValue = this.values[index];
348
- const isHorizontal = this.orientation === "horizontal";
349
-
350
- switch (e.key) {
351
- case "ArrowRight":
352
- case "ArrowUp":
353
- e.preventDefault();
354
- newValue += isHorizontal === (e.key === "ArrowRight") ? this.step : -this.step;
355
- if (e.shiftKey) newValue = this.values[index] + this.largeStep;
356
- break;
357
- case "ArrowLeft":
358
- case "ArrowDown":
359
- e.preventDefault();
360
- newValue -= isHorizontal === (e.key === "ArrowLeft") ? this.step : -this.step;
361
- if (e.shiftKey) newValue = this.values[index] - this.largeStep;
362
- break;
363
- case "PageUp":
364
- e.preventDefault();
365
- newValue += this.largeStep;
366
- break;
367
- case "PageDown":
368
- e.preventDefault();
369
- newValue -= this.largeStep;
370
- break;
371
- case "Home":
372
- e.preventDefault();
373
- newValue = this.min;
374
- break;
375
- case "End":
376
- e.preventDefault();
377
- newValue = this.max;
378
- break;
379
- default:
380
- return;
381
- }
382
-
383
- newValue = this.snapToStep(newValue);
384
- this.updateValue(index, newValue);
385
- }
386
-
387
- private handleFocus(index: number): void {
388
- this.root.setAttribute("data-focused", "");
389
- this.thumbs[index].setAttribute("data-focused", "");
390
- }
391
-
392
- private handleBlur(): void {
393
- this.root.removeAttribute("data-focused");
394
- this.thumbs.forEach((thumb) => thumb.removeAttribute("data-focused"));
395
- }
396
- }
397
-
398
- const sliderInstances = new WeakMap<HTMLElement, StarwindSlider>();
399
-
400
- function initSliders(): void {
401
- document.querySelectorAll<HTMLElement>('[data-slot="slider"]').forEach((slider) => {
402
- if (!sliderInstances.has(slider)) {
403
- sliderInstances.set(slider, new StarwindSlider(slider));
404
- }
405
- });
406
- }
407
-
408
- initSliders();
409
- document.addEventListener("astro:after-swap", initSliders);
410
- document.addEventListener("starwind:init", initSliders);
411
- </script>
@@ -1,9 +0,0 @@
1
- import Slider, { slider } from "./Slider.astro";
2
-
3
- const SliderVariants = {
4
- slider,
5
- };
6
-
7
- export { Slider, SliderVariants };
8
-
9
- export default Slider;
@@ -1,21 +0,0 @@
1
- ---
2
- import Loader2 from "@tabler/icons/outline/loader-2.svg";
3
- import type { HTMLAttributes } from "astro/types";
4
- import { tv } from "tailwind-variants";
5
-
6
- type Props = Omit<HTMLAttributes<"svg">, "role" | "aria-label">;
7
-
8
- export const spinner = tv({
9
- base: "size-4 animate-spin",
10
- });
11
-
12
- const { class: className, ...rest } = Astro.props;
13
- ---
14
-
15
- <Loader2
16
- role="status"
17
- aria-label="Loading"
18
- class={spinner({ class: className })}
19
- data-slot="spinner"
20
- {...rest}
21
- />
@@ -1,7 +0,0 @@
1
- import Spinner, { spinner } from "./Spinner.astro";
2
-
3
- const SpinnerVariants = { spinner };
4
-
5
- export { Spinner, SpinnerVariants };
6
-
7
- export default Spinner;
@@ -1,192 +0,0 @@
1
- ---
2
- import type { HTMLAttributes } from "astro/types";
3
- import { tv } from "tailwind-variants";
4
-
5
- type Props = Omit<HTMLAttributes<"button">, "role" | "type" | "aria-checked"> & {
6
- /**
7
- * Unique identifier for the switch component.
8
- */
9
- id: string;
10
- /**
11
- * Optional text label to display alongside the switch.
12
- */
13
- label?: string;
14
- /**
15
- * Controls the checked state of the switch.
16
- */
17
- checked?: boolean;
18
- /**
19
- * Custom padding in pixels to apply around the switch.
20
- */
21
- padding?: number;
22
- /**
23
- * Size variant of the switch component.
24
- */
25
- size?: "sm" | "md" | "lg";
26
- /**
27
- * Visual style variant of the switch.
28
- * @default "default"
29
- */
30
- variant?: "default" | "primary" | "secondary" | "info" | "success" | "warning" | "error";
31
- };
32
-
33
- const {
34
- id,
35
- label,
36
- checked = false,
37
- padding,
38
- size = "md",
39
- variant = "default",
40
- class: className,
41
- ...rest
42
- } = Astro.props;
43
-
44
- // if no specific padding is set, base it off of size
45
- let newPadding = padding;
46
- if (!padding) {
47
- newPadding = size === "sm" ? 2.5 : size === "lg" ? 4 : 3;
48
- }
49
-
50
- const sizeMultiplier = size === "sm" ? 4 : size === "lg" ? 6 : 5;
51
-
52
- let ariaLabel;
53
- if (rest["aria-label"]) {
54
- ariaLabel = rest["aria-label"];
55
- delete rest["aria-label"];
56
- } else if (label) {
57
- ariaLabel = label;
58
- } else {
59
- ariaLabel = "switch";
60
- }
61
-
62
- export const switchButton = tv({
63
- base: [
64
- "border-input bg-muted inline-flex h-(--height) w-(--width) items-center rounded-full border",
65
- "group peer ring-offset-background transition outline-none focus-visible:ring-3",
66
- "not-disabled:cursor-pointer disabled:cursor-not-allowed disabled:opacity-50",
67
- ],
68
- variants: {
69
- variant: {
70
- primary: "aria-checked:border-primary focus-visible:border-primary/70 focus:ring-primary/50",
71
- secondary:
72
- "aria-checked:border-secondary focus-visible:border-secondary/70 focus:ring-secondary/50",
73
- default: "aria-checked:border-foreground focus-visible:border-outline focus:ring-outline/50",
74
- info: "aria-checked:border-info focus-visible:border-info/70 focus:ring-info/50",
75
- success: "aria-checked:border-success focus-visible:border-success/70 focus:ring-success/50",
76
- warning: "aria-checked:border-warning focus-visible:border-warning/70 focus:ring-warning/50",
77
- error: "aria-checked:border-error focus-visible:border-error/70 focus:ring-error/50",
78
- },
79
- },
80
- defaultVariants: { variant: "default" },
81
- });
82
-
83
- export const switchToggle = tv({
84
- base: [
85
- "bg-foreground inline-block transform rounded-full transition-transform",
86
- "group-aria-checked:translate-x-(--translation) group-aria-[checked=false]:translate-x-[calc(var(--padding)-var(--border-offset))]",
87
- ],
88
- variants: { size: { sm: "size-4", md: "size-5", lg: "size-6" } },
89
- defaultVariants: { size: "md" },
90
- });
91
-
92
- export const switchLabel = tv({
93
- base: "text-foreground ml-2 font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
94
- variants: { size: { sm: "text-sm", md: "text-base", lg: "text-lg" } },
95
- defaultVariants: { size: "md" },
96
- });
97
- ---
98
-
99
- <div class="starwind-switch flex items-center">
100
- <button
101
- type="button"
102
- id={id}
103
- role="switch"
104
- aria-checked={checked ? "true" : "false"}
105
- aria-label={ariaLabel}
106
- class={switchButton({ variant, class: className })}
107
- style={{
108
- "--padding": `${newPadding}px`,
109
- "--height": `calc((var(--spacing) * ${sizeMultiplier}) + (var(--padding) * 2))`,
110
- "--width": `calc((var(--spacing) * ${sizeMultiplier} * 2) + (var(--padding) * 3))`,
111
- "--border-offset": "1px",
112
- }}
113
- data-slot="switch-button"
114
- {...rest}
115
- >
116
- <span
117
- class={switchToggle({ size })}
118
- data-slot="switch-toggle"
119
- style={{
120
- "--translation": `calc((var(--spacing) * ${sizeMultiplier}) + (var(--padding) * 2) - var(--border-offset))`,
121
- }}></span>
122
- </button>
123
- {
124
- label && (
125
- <label for={id} class={switchLabel({ size })} data-slot="switch-label">
126
- {label}
127
- </label>
128
- )
129
- }
130
- </div>
131
-
132
- <script>
133
- import type { SwitchChangeEvent } from "./SwitchTypes";
134
-
135
- class SwitchHandler {
136
- private switchButton: HTMLButtonElement;
137
-
138
- constructor(switchButton: HTMLButtonElement) {
139
- this.switchButton = switchButton;
140
- this.setupEventListeners();
141
- }
142
-
143
- private setupEventListeners(): void {
144
- this.switchButton.addEventListener("click", () => this.handleStateChange());
145
- this.switchButton.addEventListener("keydown", (event) => this.handleKeyDown(event));
146
- }
147
-
148
- private handleStateChange(): void {
149
- if (this.switchButton.disabled) return;
150
-
151
- const isChecked = this.switchButton.getAttribute("aria-checked") === "true";
152
- const newState = !isChecked;
153
-
154
- this.switchButton.setAttribute("aria-checked", newState.toString());
155
-
156
- // Dispatch custom event with the new state
157
- const event = new CustomEvent<SwitchChangeEvent["detail"]>("starwind-switch:change", {
158
- detail: { checked: newState, switchId: this.switchButton.id },
159
- bubbles: true,
160
- cancelable: true,
161
- });
162
-
163
- this.switchButton.dispatchEvent(event);
164
- }
165
-
166
- private handleKeyDown(event: KeyboardEvent): void {
167
- if (this.switchButton.disabled) return;
168
-
169
- if (event.key === " " || event.key === "Enter") {
170
- event.preventDefault();
171
- this.handleStateChange();
172
- }
173
- }
174
- }
175
-
176
- // Store instances in a WeakMap to avoid memory leaks
177
- const switchInstances = new WeakMap<HTMLButtonElement, SwitchHandler>();
178
-
179
- const setupSwitches = () => {
180
- document
181
- .querySelectorAll<HTMLButtonElement>('.starwind-switch button[role="switch"]')
182
- .forEach((switchButton) => {
183
- if (!switchInstances.has(switchButton)) {
184
- switchInstances.set(switchButton, new SwitchHandler(switchButton));
185
- }
186
- });
187
- };
188
-
189
- setupSwitches();
190
- document.addEventListener("astro:after-swap", setupSwitches);
191
- document.addEventListener("starwind:init", setupSwitches);
192
- </script>
@@ -1,6 +0,0 @@
1
- export interface SwitchChangeEvent extends CustomEvent {
2
- detail: {
3
- checked: boolean;
4
- switchId: string;
5
- };
6
- }
@@ -1,12 +0,0 @@
1
- import Switch, { switchButton, switchLabel, switchToggle } from "./Switch.astro";
2
- import type { SwitchChangeEvent } from "./SwitchTypes";
3
-
4
- const SwitchVariants = {
5
- switchButton,
6
- switchToggle,
7
- switchLabel,
8
- };
9
-
10
- export { Switch, type SwitchChangeEvent, SwitchVariants };
11
-
12
- export default Switch;
@@ -1,18 +0,0 @@
1
- ---
2
- import type { HTMLAttributes } from "astro/types";
3
- import { tv, type VariantProps } from "tailwind-variants";
4
-
5
- type Props = HTMLAttributes<"table"> & VariantProps<typeof table>;
6
-
7
- export const table = tv({
8
- base: "w-full caption-bottom text-sm",
9
- });
10
-
11
- const { class: className, ...rest } = Astro.props;
12
- ---
13
-
14
- <div data-slot="table-container" class="relative w-full overflow-x-auto">
15
- <table data-slot="table" class={table({ class: className })} {...rest} role="table">
16
- <slot />
17
- </table>
18
- </div>