@starwind-ui/core 1.0.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/index.js +22 -99
  2. package/dist/index.js.map +1 -1
  3. package/dist/src/components/accordion/Accordion.astro +5 -12
  4. package/dist/src/components/accordion/AccordionContent.astro +11 -7
  5. package/dist/src/components/accordion/AccordionItem.astro +6 -10
  6. package/dist/src/components/accordion/AccordionTrigger.astro +12 -9
  7. package/dist/src/components/alert/Alert.astro +18 -28
  8. package/dist/src/components/alert/AlertDescription.astro +4 -1
  9. package/dist/src/components/alert/AlertTitle.astro +6 -7
  10. package/dist/src/components/avatar/Avatar.astro +19 -23
  11. package/dist/src/components/avatar/AvatarFallback.astro +7 -6
  12. package/dist/src/components/avatar/AvatarImage.astro +9 -23
  13. package/dist/src/components/avatar/index.ts +1 -1
  14. package/dist/src/components/badge/Badge.astro +39 -34
  15. package/dist/src/components/button/Button.astro +37 -50
  16. package/dist/src/components/card/Card.astro +4 -4
  17. package/dist/src/components/card/CardContent.astro +4 -1
  18. package/dist/src/components/card/CardDescription.astro +4 -1
  19. package/dist/src/components/card/CardFooter.astro +4 -1
  20. package/dist/src/components/card/CardHeader.astro +4 -1
  21. package/dist/src/components/card/CardTitle.astro +4 -1
  22. package/dist/src/components/checkbox/Checkbox.astro +82 -54
  23. package/dist/src/components/dialog/DialogContent.astro +32 -29
  24. package/dist/src/components/dialog/DialogDescription.astro +4 -1
  25. package/dist/src/components/dialog/DialogFooter.astro +4 -1
  26. package/dist/src/components/dialog/DialogHeader.astro +4 -1
  27. package/dist/src/components/dialog/DialogTitle.astro +4 -1
  28. package/dist/src/components/input/Input.astro +15 -17
  29. package/dist/src/components/label/Label.astro +12 -16
  30. package/dist/src/components/pagination/Pagination.astro +5 -9
  31. package/dist/src/components/pagination/PaginationContent.astro +5 -4
  32. package/dist/src/components/pagination/PaginationEllipsis.astro +6 -5
  33. package/dist/src/components/pagination/PaginationItem.astro +5 -4
  34. package/dist/src/components/pagination/PaginationLink.astro +25 -32
  35. package/dist/src/components/pagination/PaginationNext.astro +7 -8
  36. package/dist/src/components/pagination/PaginationPrevious.astro +7 -8
  37. package/dist/src/components/select/Select.astro +5 -13
  38. package/dist/src/components/select/SelectContent.astro +25 -11
  39. package/dist/src/components/select/SelectGroup.astro +1 -3
  40. package/dist/src/components/select/SelectItem.astro +14 -9
  41. package/dist/src/components/select/SelectLabel.astro +4 -1
  42. package/dist/src/components/select/SelectSeparator.astro +4 -1
  43. package/dist/src/components/select/SelectTrigger.astro +12 -9
  44. package/dist/src/components/select/SelectValue.astro +5 -2
  45. package/dist/src/components/switch/Switch.astro +40 -41
  46. package/dist/src/components/tabs/Tabs.astro +5 -4
  47. package/dist/src/components/tabs/TabsContent.astro +4 -1
  48. package/dist/src/components/tabs/TabsList.astro +6 -9
  49. package/dist/src/components/tabs/TabsTrigger.astro +11 -7
  50. package/dist/src/components/textarea/Textarea.astro +18 -15
  51. package/dist/src/components/tooltip/Tooltip.astro +4 -1
  52. package/dist/src/components/tooltip/TooltipContent.astro +44 -22
  53. package/dist/src/components/tooltip/TooltipTrigger.astro +1 -3
  54. package/package.json +1 -2
@@ -1,15 +1,16 @@
1
1
  ---
2
- import type { HTMLAttributes } from "astro/types";
3
2
  import Dots from "@tabler/icons/outline/dots.svg";
3
+ import type { HTMLAttributes } from "astro/types";
4
+ import { tv } from "tailwind-variants";
5
+
6
+ type Props = HTMLAttributes<"span"> & { children?: any };
4
7
 
5
- type Props = HTMLAttributes<"span"> & {
6
- children?: any;
7
- };
8
+ const paginationEllipsis = tv({ base: "flex h-9 w-9 items-center justify-center" });
8
9
 
9
10
  const { class: className, ...rest } = Astro.props;
10
11
  ---
11
12
 
12
- <span aria-hidden class:list={["flex h-9 w-9 items-center justify-center", className]} {...rest}>
13
+ <span aria-hidden class={paginationEllipsis({ class: className })} {...rest}>
13
14
  <Dots class="size-4" />
14
15
  <span class="sr-only">More pages</span>
15
16
  </span>
@@ -1,13 +1,14 @@
1
1
  ---
2
2
  import type { HTMLAttributes } from "astro/types";
3
+ import { tv } from "tailwind-variants";
3
4
 
4
- type Props = HTMLAttributes<"li"> & {
5
- children: any;
6
- };
5
+ type Props = HTMLAttributes<"li"> & { children: any };
6
+
7
+ const paginationItem = tv({ base: "" });
7
8
 
8
9
  const { class: className, ...rest } = Astro.props;
9
10
  ---
10
11
 
11
- <li class:list={[className]} {...rest}>
12
+ <li class={paginationItem({ class: className })} {...rest}>
12
13
  <slot />
13
14
  </li>
@@ -1,49 +1,42 @@
1
1
  ---
2
2
  import type { HTMLAttributes } from "astro/types";
3
+ import { tv } from "tailwind-variants";
3
4
 
4
5
  interface Props extends HTMLAttributes<"a"> {
5
6
  isActive?: boolean;
6
7
  size?: "sm" | "md" | "lg" | "icon";
7
- radius?: "none" | "xs" | "sm" | "md" | "lg" | "xl" | "full";
8
8
  }
9
9
 
10
- const { class: className, isActive, size = "icon", radius = "md", ...rest } = Astro.props;
11
- ---
12
-
13
- <a
14
- aria-current={isActive ? "page" : undefined}
15
- class:list={[
16
- // default starwind button styles
17
- "inline-flex items-center justify-center gap-1.5 font-medium whitespace-nowrap",
10
+ const paginationLink = tv({
11
+ base: [
12
+ "inline-flex items-center justify-center gap-1.5 rounded-md font-medium whitespace-nowrap",
18
13
  "[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
19
14
  "starwind-transition-colors",
20
15
  "focus-visible:outline-2 focus-visible:outline-offset-2",
21
16
  "disabled:pointer-events-none disabled:opacity-50",
22
- {
23
- // default starwind button variant="outline" styles
24
- "border-border hover:bg-border hover:text-foreground focus-visible:outline-outline border":
25
- isActive,
26
- // default starwind button variant="ghost" styles
27
- "hover:bg-foreground/10 hover:text-foreground focus-visible:outline-outline bg-transparent":
28
- !isActive,
29
- },
30
- {
31
- "h-9 px-3 py-2 text-sm": size === "sm",
32
- "h-11 px-4 py-2 text-base": size === "md",
33
- "h-12 px-8 py-2 text-lg": size === "lg",
34
- "h-11 w-11": size === "icon",
17
+ ],
18
+ variants: {
19
+ isActive: {
20
+ true: "border-border hover:bg-border hover:text-foreground focus-visible:outline-outline border",
21
+ false:
22
+ "hover:bg-foreground/10 hover:text-foreground focus-visible:outline-outline bg-transparent",
35
23
  },
36
- {
37
- "rounded-none": radius === "none",
38
- "rounded-xs": radius === "xs",
39
- "rounded-sm": radius === "sm",
40
- "rounded-md": radius === "md",
41
- "rounded-lg": radius === "lg",
42
- "rounded-xl": radius === "xl",
43
- "rounded-full": radius === "full",
24
+ size: {
25
+ sm: "h-9 px-3 py-2 text-sm",
26
+ md: "h-11 px-4 py-2 text-base",
27
+ lg: "h-12 px-8 py-2 text-lg",
28
+ icon: "h-11 w-11",
44
29
  },
45
- className,
46
- ]}
30
+ },
31
+ defaultVariants: { isActive: false, size: "icon" },
32
+ });
33
+
34
+ const { class: className, isActive, size = "icon", ...rest } = Astro.props;
35
+ ---
36
+
37
+ <a
38
+ aria-current={isActive ? "page" : undefined}
39
+ class={paginationLink({ isActive, size, class: className })}
47
40
  {...rest}
48
41
  >
49
42
  <slot />
@@ -1,21 +1,20 @@
1
1
  ---
2
- import type { HTMLAttributes } from "astro/types";
3
2
  import ChevronRight from "@tabler/icons/outline/chevron-right.svg";
3
+ import type { HTMLAttributes } from "astro/types";
4
+ import { tv } from "tailwind-variants";
4
5
  import PaginationLink from "./PaginationLink.astro";
5
6
 
6
- type Props = HTMLAttributes<"a"> & {
7
- size?: "sm" | "md" | "lg" | "icon";
8
- radius?: "none" | "xs" | "sm" | "md" | "lg" | "xl" | "full";
9
- };
7
+ type Props = HTMLAttributes<"a"> & { size?: "sm" | "md" | "lg" | "icon" };
8
+
9
+ const paginationNext = tv({ base: "group gap-1" });
10
10
 
11
- const { class: className, size = "md", radius = "md", ...rest } = Astro.props;
11
+ const { class: className, size = "md", ...rest } = Astro.props;
12
12
  ---
13
13
 
14
14
  <PaginationLink
15
15
  aria-label="Go to next page"
16
16
  size={size}
17
- radius={radius}
18
- class:list={["group gap-1", className]}
17
+ class={paginationNext({ class: className })}
19
18
  {...rest}
20
19
  >
21
20
  <slot />
@@ -1,21 +1,20 @@
1
1
  ---
2
- import type { HTMLAttributes } from "astro/types";
3
2
  import ChevronLeft from "@tabler/icons/outline/chevron-left.svg";
3
+ import type { HTMLAttributes } from "astro/types";
4
+ import { tv } from "tailwind-variants";
4
5
  import PaginationLink from "./PaginationLink.astro";
5
6
 
6
- type Props = HTMLAttributes<"a"> & {
7
- size?: "sm" | "md" | "lg" | "icon";
8
- radius?: "none" | "xs" | "sm" | "md" | "lg" | "xl" | "full";
9
- };
7
+ type Props = HTMLAttributes<"a"> & { size?: "sm" | "md" | "lg" | "icon" };
8
+
9
+ const paginationPrevious = tv({ base: "group gap-1" });
10
10
 
11
- const { class: className, size = "md", radius = "md", ...rest } = Astro.props;
11
+ const { class: className, size = "md", ...rest } = Astro.props;
12
12
  ---
13
13
 
14
14
  <PaginationLink
15
15
  aria-label="Go to previous page"
16
16
  size={size}
17
- radius={radius}
18
- class:list={["group gap-1", className]}
17
+ class={paginationPrevious({ class: className })}
19
18
  {...rest}
20
19
  >
21
20
  <ChevronLeft class="size-4 transition-transform group-hover:-translate-x-1" />
@@ -1,9 +1,7 @@
1
1
  ---
2
2
  import type { HTMLAttributes } from "astro/types";
3
3
 
4
- type Props = HTMLAttributes<"div"> & {
5
- children: any;
6
- };
4
+ type Props = HTMLAttributes<"div"> & { children: any };
7
5
 
8
6
  const { class: className, ...rest } = Astro.props;
9
7
  ---
@@ -210,10 +208,8 @@ const { class: className, ...rest } = Astro.props;
210
208
  }
211
209
  });
212
210
 
213
- // passive resize listener to call setSize() on window resize
214
- window.addEventListener("resize", () => this.setSize(), {
215
- passive: true,
216
- });
211
+ // passive resize listener to call setSize()
212
+ window.addEventListener("resize", () => this.setSize(), { passive: true });
217
213
  }
218
214
 
219
215
  private handleNavigationKeys(e: KeyboardEvent) {
@@ -225,7 +221,7 @@ const { class: className, ...rest } = Astro.props;
225
221
  const currentIndex = Array.from(items).indexOf(activeElement as HTMLElement);
226
222
  if (e.key === "Home") {
227
223
  const firstEnabledItem = Array.from(items).find(
228
- (item) => item.getAttribute("data-disabled") !== "true"
224
+ (item) => item.getAttribute("data-disabled") !== "true",
229
225
  ) as HTMLElement;
230
226
  if (firstEnabledItem) {
231
227
  firstEnabledItem.focus();
@@ -366,11 +362,7 @@ const { class: className, ...rest } = Astro.props;
366
362
 
367
363
  // Dispatch custom event with the new value
368
364
  const event = new CustomEvent<SelectChangeEvent["detail"]>("starwind-select:change", {
369
- detail: {
370
- value: newValue,
371
- selectId: this.select.id,
372
- label: item.textContent || "",
373
- },
365
+ detail: { value: newValue, selectId: this.select.id, label: item.textContent || "" },
374
366
  bubbles: true,
375
367
  cancelable: true,
376
368
  });
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  import type { HTMLAttributes } from "astro/types";
3
+ import { tv } from "tailwind-variants";
3
4
 
4
5
  type Props = HTMLAttributes<"div"> & {
5
6
  /**
@@ -19,6 +20,28 @@ type Props = HTMLAttributes<"div"> & {
19
20
  animationDuration?: number;
20
21
  };
21
22
 
23
+ const selectContent = tv({
24
+ base: [
25
+ "starwind-select-content",
26
+ "bg-popover text-popover-foreground absolute z-50 min-w-[8rem] rounded-md border shadow-md",
27
+ "fade-in-0 zoom-in-95 animate-in overflow-hidden will-change-transform",
28
+ "data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=closed]:animate-out",
29
+ "left-0",
30
+ ],
31
+ variants: {
32
+ side: {
33
+ bottom:
34
+ "data-[side=bottom]:slide-in-from-top-4 data-[side=bottom]:top-(--select-content-offset)",
35
+ top: "data-[side=top]:slide-in-from-bottom-4 data-[side=top]:bottom-(--select-content-offset)",
36
+ },
37
+ },
38
+ defaultVariants: { side: "bottom" },
39
+ });
40
+
41
+ const selectContentInner = tv({
42
+ base: "max-h-96 w-full min-w-(--select-trigger-width) overflow-y-auto p-1",
43
+ });
44
+
22
45
  const {
23
46
  class: className,
24
47
  side = "bottom",
@@ -29,16 +52,7 @@ const {
29
52
  ---
30
53
 
31
54
  <div
32
- class:list={[
33
- "starwind-select-content",
34
- "bg-popover text-popover-foreground absolute z-50 min-w-[8rem] rounded-md border shadow-md",
35
- "fade-in-0 zoom-in-95 animate-in overflow-hidden will-change-transform",
36
- "data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=closed]:animate-out",
37
- "data-[side=bottom]:slide-in-from-top-4 data-[side=bottom]:top-(--select-content-offset)",
38
- "data-[side=top]:slide-in-from-bottom-4 data-[side=top]:bottom-(--select-content-offset)",
39
- "left-0",
40
- className,
41
- ]}
55
+ class={selectContent({ side, class: className })}
42
56
  role="listbox"
43
57
  data-side={side}
44
58
  data-state="closed"
@@ -51,7 +65,7 @@ const {
51
65
  }}
52
66
  {...rest}
53
67
  >
54
- <div class:list={["max-h-96 w-full min-w-(--select-trigger-width) overflow-y-auto p-1"]}>
68
+ <div class={selectContentInner()}>
55
69
  <slot />
56
70
  </div>
57
71
  </div>
@@ -2,9 +2,7 @@
2
2
  /**
3
3
  * This current doesn't do anything
4
4
  */
5
- type Props = {
6
- children: any;
7
- };
5
+ type Props = { children: any };
8
6
  ---
9
7
 
10
8
  <slot />
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  import Check from "@tabler/icons/outline/check.svg";
3
-
4
3
  import type { HTMLAttributes } from "astro/types";
4
+ import { tv } from "tailwind-variants";
5
5
 
6
6
  type Props = HTMLAttributes<"div"> & {
7
7
  /**
@@ -14,17 +14,22 @@ type Props = HTMLAttributes<"div"> & {
14
14
  disabled?: boolean;
15
15
  };
16
16
 
17
- const { class: className, value, disabled, ...rest } = Astro.props;
18
- ---
19
-
20
- <div
21
- class:list={[
17
+ const selectItem = tv({
18
+ base: [
22
19
  "relative flex w-full cursor-default items-center rounded-sm py-1.5 pr-2 pl-8 outline-none select-none",
23
20
  "focus:bg-accent focus:text-accent-foreground",
24
21
  "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
25
22
  "not-aria-selected:[&_svg]:hidden aria-selected:[&_svg]:flex",
26
- className,
27
- ]}
23
+ ],
24
+ });
25
+
26
+ const selectItemIcon = tv({ base: "absolute left-2 size-3.5 items-center justify-center" });
27
+
28
+ const { class: className, value, disabled, ...rest } = Astro.props;
29
+ ---
30
+
31
+ <div
32
+ class={selectItem({ class: className })}
28
33
  data-value={value}
29
34
  data-disabled={disabled}
30
35
  aria-selected="false"
@@ -32,7 +37,7 @@ const { class: className, value, disabled, ...rest } = Astro.props;
32
37
  tabindex="0"
33
38
  {...rest}
34
39
  >
35
- <span class="absolute left-2 size-3.5 items-center justify-center">
40
+ <span class={selectItemIcon()}>
36
41
  <Check class="size-4" />
37
42
  </span>
38
43
  <span>
@@ -1,11 +1,14 @@
1
1
  ---
2
2
  import type { HTMLAttributes } from "astro/types";
3
+ import { tv } from "tailwind-variants";
3
4
 
4
5
  type Props = HTMLAttributes<"div">;
5
6
 
7
+ const selectLabel = tv({ base: "py-1.5 pr-2 pl-8 font-semibold" });
8
+
6
9
  const { class: className, ...rest } = Astro.props;
7
10
  ---
8
11
 
9
- <div class:list={["py-1.5 pr-2 pl-8 font-semibold", className]} {...rest}>
12
+ <div class={selectLabel({ class: className })} {...rest}>
10
13
  <slot />
11
14
  </div>
@@ -1,9 +1,12 @@
1
1
  ---
2
2
  import type { HTMLAttributes } from "astro/types";
3
+ import { tv } from "tailwind-variants";
3
4
 
4
5
  type Props = HTMLAttributes<"div">;
5
6
 
7
+ const selectSeparator = tv({ base: "bg-muted -mx-1 my-1 h-px" });
8
+
6
9
  const { class: className, ...rest } = Astro.props;
7
10
  ---
8
11
 
9
- <div class:list={["bg-muted -mx-1 my-1 h-px", className]} {...rest}></div>
12
+ <div class={selectSeparator({ class: className })} {...rest}></div>
@@ -1,7 +1,7 @@
1
1
  ---
2
- import type { HTMLAttributes } from "astro/types";
3
-
4
2
  import ChevronDown from "@tabler/icons/outline/chevron-down.svg";
3
+ import type { HTMLAttributes } from "astro/types";
4
+ import { tv } from "tailwind-variants";
5
5
 
6
6
  type Props = Omit<HTMLAttributes<"button">, "role" | "type"> & {
7
7
  /**
@@ -14,17 +14,20 @@ type Props = Omit<HTMLAttributes<"button">, "role" | "type"> & {
14
14
  required?: boolean;
15
15
  };
16
16
 
17
- const { class: className, required = false, ...rest } = Astro.props;
18
- ---
19
-
20
- <button
21
- class:list={[
17
+ const selectTrigger = tv({
18
+ base: [
22
19
  "starwind-select-trigger",
23
20
  "border-input bg-background text-foreground ring-offset-background flex h-11 items-center justify-between rounded-md border px-3 py-2",
24
21
  "focus:outline-outline focus:outline-2 focus:outline-offset-2",
25
22
  "disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
26
- className,
27
- ]}
23
+ ],
24
+ });
25
+
26
+ const { class: className, required = false, ...rest } = Astro.props;
27
+ ---
28
+
29
+ <button
30
+ class={selectTrigger({ class: className })}
28
31
  type="button"
29
32
  role="combobox"
30
33
  aria-label="Select field"
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  import type { HTMLAttributes } from "astro/types";
3
+ import { tv } from "tailwind-variants";
3
4
 
4
5
  type Props = HTMLAttributes<"span"> & {
5
6
  /**
@@ -8,9 +9,11 @@ type Props = HTMLAttributes<"span"> & {
8
9
  placeholder?: string;
9
10
  };
10
11
 
11
- const { placeholder = "select", ...rest } = Astro.props;
12
+ const selectValue = tv({ base: "pointer-events-none" });
13
+
14
+ const { placeholder = "select", class: className, ...rest } = Astro.props;
12
15
  ---
13
16
 
14
- <span class="pointer-events-none" {...rest}>
17
+ <span class={selectValue({ class: className })} {...rest}>
15
18
  {placeholder}
16
19
  </span>
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  import type { HTMLAttributes } from "astro/types";
3
+ import { tv } from "tailwind-variants";
3
4
 
4
5
  type Props = Omit<HTMLAttributes<"button">, "role" | "type" | "aria-checked"> & {
5
6
  /**
@@ -48,12 +49,6 @@ if (!padding) {
48
49
 
49
50
  const sizeMultiplier = size === "sm" ? 4 : size === "lg" ? 6 : 5;
50
51
 
51
- const toggleSizeClass = {
52
- sm: "size-4",
53
- md: "size-5",
54
- lg: "size-6",
55
- };
56
-
57
52
  let ariaLabel;
58
53
  if (rest["aria-label"]) {
59
54
  ariaLabel = rest["aria-label"];
@@ -63,6 +58,41 @@ if (rest["aria-label"]) {
63
58
  } else {
64
59
  ariaLabel = "switch";
65
60
  }
61
+
62
+ const switchButton = tv({
63
+ base: [
64
+ "starwind-transition-colors border-input bg-muted inline-flex h-(--height) w-(--width) items-center rounded-full border",
65
+ "group peer ring-offset-background focus-visible:outline-2 focus-visible:outline-offset-2",
66
+ "not-disabled:cursor-pointer disabled:cursor-not-allowed disabled:opacity-50",
67
+ ],
68
+ variants: {
69
+ variant: {
70
+ primary: "aria-checked:border-primary focus:outline-primary",
71
+ secondary: "aria-checked:border-secondary focus:outline-secondary",
72
+ default: "aria-checked:border-foreground focus:outline-outline",
73
+ info: "aria-checked:border-info focus:outline-info",
74
+ success: "aria-checked:border-success focus:outline-success",
75
+ warning: "aria-checked:border-warning focus:outline-warning",
76
+ error: "aria-checked:border-error focus:outline-error",
77
+ },
78
+ },
79
+ defaultVariants: { variant: "default" },
80
+ });
81
+
82
+ const switchToggle = tv({
83
+ base: [
84
+ "bg-foreground inline-block transform rounded-full transition-transform",
85
+ "group-aria-checked:translate-x-(--translation) group-aria-[checked=false]:translate-x-[calc(var(--padding)-var(--border-offset))]",
86
+ ],
87
+ variants: { size: { sm: "size-4", md: "size-5", lg: "size-6" } },
88
+ defaultVariants: { size: "md" },
89
+ });
90
+
91
+ const switchLabel = tv({
92
+ base: "text-foreground ml-2 font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
93
+ variants: { size: { sm: "text-sm", md: "text-base", lg: "text-lg" } },
94
+ defaultVariants: { size: "md" },
95
+ });
66
96
  ---
67
97
 
68
98
  <div class="starwind-switch flex items-center">
@@ -72,21 +102,7 @@ if (rest["aria-label"]) {
72
102
  role="switch"
73
103
  aria-checked={checked ? "true" : "false"}
74
104
  aria-label={ariaLabel}
75
- class:list={[
76
- "starwind-transition-colors border-input bg-muted inline-flex h-(--height) w-(--width) items-center rounded-full border",
77
- "group peer ring-offset-background focus-visible:outline-2 focus-visible:outline-offset-2",
78
- "not-disabled:cursor-pointer disabled:cursor-not-allowed disabled:opacity-50",
79
- {
80
- "aria-checked:border-primary focus:outline-primary": variant === "primary",
81
- "aria-checked:border-secondary focus:outline-secondary": variant === "secondary",
82
- "aria-checked:border-foreground focus:outline-outline": variant === "default",
83
- "aria-checked:border-info focus:outline-info": variant === "info",
84
- "aria-checked:border-success focus:outline-success": variant === "success",
85
- "aria-checked:border-warning focus:outline-warning": variant === "warning",
86
- "aria-checked:border-error focus:outline-error": variant === "error",
87
- },
88
- className,
89
- ]}
105
+ class={switchButton({ variant, class: className })}
90
106
  style={{
91
107
  "--padding": `${newPadding}px`,
92
108
  "--height": `calc((var(--spacing) * ${sizeMultiplier}) + (var(--padding) * 2))`,
@@ -96,28 +112,14 @@ if (rest["aria-label"]) {
96
112
  {...rest}
97
113
  >
98
114
  <span
99
- class:list={[
100
- "bg-foreground inline-block transform rounded-full transition-transform",
101
- "group-aria-checked:translate-x-(--translation) group-aria-[checked=false]:translate-x-[calc(var(--padding)-var(--border-offset))]",
102
- toggleSizeClass[size],
103
- ]}
115
+ class={switchToggle({ size })}
104
116
  style={{
105
117
  "--translation": `calc((var(--spacing) * ${sizeMultiplier}) + (var(--padding) * 2) - var(--border-offset))`,
106
118
  }}></span>
107
119
  </button>
108
120
  {
109
121
  label && (
110
- <label
111
- for={id}
112
- class:list={[
113
- "text-foreground ml-2 font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
114
- {
115
- "text-sm": size === "sm",
116
- "text-base": size === "md",
117
- "text-lg": size === "lg",
118
- },
119
- ]}
120
- >
122
+ <label for={id} class={switchLabel({ size })}>
121
123
  {label}
122
124
  </label>
123
125
  )
@@ -150,10 +152,7 @@ if (rest["aria-label"]) {
150
152
 
151
153
  // Dispatch custom event with the new state
152
154
  const event = new CustomEvent<SwitchChangeEvent["detail"]>("starwind-switch:change", {
153
- detail: {
154
- checked: newState,
155
- switchId: this.switchButton.id,
156
- },
155
+ detail: { checked: newState, switchId: this.switchButton.id },
157
156
  bubbles: true,
158
157
  cancelable: true,
159
158
  });
@@ -1,16 +1,19 @@
1
1
  ---
2
2
  import type { HTMLAttributes } from "astro/types";
3
+ import { tv } from "tailwind-variants";
3
4
 
4
5
  interface Props extends HTMLAttributes<"div"> {
5
6
  defaultValue?: string;
6
7
  syncKey?: string;
7
8
  }
8
9
 
10
+ const tabs = tv({ base: "starwind-tabs" });
11
+
9
12
  const { defaultValue, syncKey, class: className, ...rest } = Astro.props;
10
13
  ---
11
14
 
12
15
  <div
13
- class:list={["starwind-tabs", className]}
16
+ class={tabs({ class: className })}
14
17
  data-default-value={defaultValue}
15
18
  data-sync-key={syncKey}
16
19
  {...rest}
@@ -124,9 +127,7 @@ const { defaultValue, syncKey, class: className, ...rest } = Astro.props;
124
127
  if (!this.syncKey) return;
125
128
 
126
129
  document.dispatchEvent(
127
- new CustomEvent(`starwind-tabs-sync:${this.syncKey}`, {
128
- detail: { value },
129
- }),
130
+ new CustomEvent(`starwind-tabs-sync:${this.syncKey}`, { detail: { value } }),
130
131
  );
131
132
 
132
133
  localStorage.setItem(this.storageKey, value);
@@ -1,15 +1,18 @@
1
1
  ---
2
2
  import type { HTMLAttributes } from "astro/types";
3
+ import { tv } from "tailwind-variants";
3
4
 
4
5
  interface Props extends Omit<HTMLAttributes<"div">, "id" | "role" | "tabindex" | "hidden"> {
5
6
  value: string;
6
7
  }
7
8
 
9
+ const tabsContent = tv({ base: "mt-2 focus-visible:outline-2 focus-visible:outline-offset-2" });
10
+
8
11
  const { value, class: className, ...rest } = Astro.props;
9
12
  ---
10
13
 
11
14
  <div
12
- class:list={["mt-2 focus-visible:outline-2 focus-visible:outline-offset-2", className]}
15
+ class={tabsContent({ class: className })}
13
16
  data-tabs-content
14
17
  data-value={value}
15
18
  data-state="inactive"
@@ -1,19 +1,16 @@
1
1
  ---
2
2
  import type { HTMLAttributes } from "astro/types";
3
+ import { tv } from "tailwind-variants";
3
4
 
4
5
  type Props = Omit<HTMLAttributes<"div">, "role">;
5
6
 
7
+ const tabsList = tv({
8
+ base: "bg-muted text-muted-foreground inline-flex w-full items-center justify-center rounded-md p-1",
9
+ });
10
+
6
11
  const { class: className, ...rest } = Astro.props;
7
12
  ---
8
13
 
9
- <div
10
- class:list={[
11
- "bg-muted text-muted-foreground inline-flex w-full items-center justify-center rounded-md p-1",
12
- className,
13
- ]}
14
- data-tabs-list
15
- role="tablist"
16
- {...rest}
17
- >
14
+ <div class={tabsList({ class: className })} data-tabs-list role="tablist" {...rest}>
18
15
  <slot />
19
16
  </div>