@starwind-ui/core 0.1.1 → 1.1.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 (51) hide show
  1. package/dist/index.js +16 -16
  2. package/dist/index.js.map +1 -1
  3. package/dist/src/components/accordion/Accordion.astro +6 -6
  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 +20 -28
  8. package/dist/src/components/alert/AlertDescription.astro +6 -1
  9. package/dist/src/components/alert/AlertTitle.astro +6 -7
  10. package/dist/src/components/avatar/Avatar.astro +26 -23
  11. package/dist/src/components/avatar/AvatarFallback.astro +7 -6
  12. package/dist/src/components/avatar/AvatarImage.astro +9 -12
  13. package/dist/src/components/badge/Badge.astro +85 -33
  14. package/dist/src/components/button/Button.astro +40 -50
  15. package/dist/src/components/card/Card.astro +6 -4
  16. package/dist/src/components/card/CardContent.astro +6 -1
  17. package/dist/src/components/card/CardDescription.astro +6 -1
  18. package/dist/src/components/card/CardFooter.astro +6 -1
  19. package/dist/src/components/card/CardHeader.astro +6 -1
  20. package/dist/src/components/card/CardTitle.astro +6 -1
  21. package/dist/src/components/checkbox/Checkbox.astro +100 -54
  22. package/dist/src/components/dialog/DialogContent.astro +30 -18
  23. package/dist/src/components/dialog/DialogDescription.astro +6 -1
  24. package/dist/src/components/dialog/DialogFooter.astro +6 -1
  25. package/dist/src/components/dialog/DialogHeader.astro +6 -1
  26. package/dist/src/components/dialog/DialogTitle.astro +6 -1
  27. package/dist/src/components/input/Input.astro +19 -13
  28. package/dist/src/components/label/Label.astro +19 -13
  29. package/dist/src/components/pagination/Pagination.astro +6 -1
  30. package/dist/src/components/pagination/PaginationContent.astro +6 -1
  31. package/dist/src/components/pagination/PaginationEllipsis.astro +6 -1
  32. package/dist/src/components/pagination/PaginationItem.astro +6 -1
  33. package/dist/src/components/pagination/PaginationLink.astro +28 -32
  34. package/dist/src/components/pagination/PaginationNext.astro +7 -4
  35. package/dist/src/components/pagination/PaginationPrevious.astro +7 -4
  36. package/dist/src/components/select/Select.astro +1 -1
  37. package/dist/src/components/select/SelectContent.astro +26 -11
  38. package/dist/src/components/select/SelectItem.astro +16 -9
  39. package/dist/src/components/select/SelectLabel.astro +6 -1
  40. package/dist/src/components/select/SelectSeparator.astro +6 -1
  41. package/dist/src/components/select/SelectTrigger.astro +11 -8
  42. package/dist/src/components/select/SelectValue.astro +7 -2
  43. package/dist/src/components/switch/Switch.astro +57 -37
  44. package/dist/src/components/tabs/Tabs.astro +6 -1
  45. package/dist/src/components/tabs/TabsContent.astro +6 -1
  46. package/dist/src/components/tabs/TabsList.astro +6 -4
  47. package/dist/src/components/tabs/TabsTrigger.astro +11 -7
  48. package/dist/src/components/textarea/Textarea.astro +19 -12
  49. package/dist/src/components/tooltip/Tooltip.astro +6 -1
  50. package/dist/src/components/tooltip/TooltipContent.astro +75 -22
  51. package/package.json +1 -1
@@ -1,10 +1,11 @@
1
1
  ---
2
2
  import type { HTMLAttributes } from "astro/types";
3
+ import { tv } from "tailwind-variants";
3
4
 
4
5
  interface Props extends HTMLAttributes<"button">, Omit<HTMLAttributes<"a">, "type"> {
5
6
  /**
6
7
  * Sets the variant of the button
7
- * @default "primary"
8
+ * @default "default"
8
9
  */
9
10
  variant?:
10
11
  | "default"
@@ -21,63 +22,52 @@ interface Props extends HTMLAttributes<"button">, Omit<HTMLAttributes<"a">, "typ
21
22
  * @default "md"
22
23
  */
23
24
  size?: "sm" | "md" | "lg" | "icon";
24
- /**
25
- * Sets the border radius of the button
26
- * @default "md"
27
- */
28
- radius?: "none" | "xs" | "sm" | "md" | "lg" | "xl" | "full";
29
25
  }
30
26
 
31
- const { variant = "default", size = "md", radius = "md", class: className, ...rest } = Astro.props;
32
-
33
- const Tag = Astro.props.href ? "a" : "button";
34
- ---
27
+ const { variant = "default", size = "md", class: className, ...rest } = Astro.props;
35
28
 
36
- <Tag
37
- class:list={[
38
- "inline-flex items-center justify-center gap-1.5 font-medium whitespace-nowrap",
29
+ const button = tv({
30
+ base: [
31
+ "inline-flex items-center justify-center gap-1.5 rounded-md font-medium whitespace-nowrap",
39
32
  "[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
40
33
  "starwind-transition-colors",
41
34
  "focus-visible:outline-2 focus-visible:outline-offset-2",
42
35
  "disabled:pointer-events-none disabled:opacity-50",
43
- {
44
- "bg-foreground text-background hover:bg-foreground/90 focus-visible:outline-outline":
45
- variant === "default",
46
- "bg-primary text-primary-foreground hover:bg-primary/90 focus-visible:outline-primary":
47
- variant === "primary",
48
- "bg-secondary text-secondary-foreground hover:bg-secondary/90 focus-visible:outline-secondary":
49
- variant === "secondary",
50
- "border-border hover:bg-border hover:text-foreground focus-visible:outline-outline border":
51
- variant === "outline",
52
- "hover:bg-foreground/10 hover:text-foreground focus-visible:outline-outline bg-transparent":
53
- variant === "ghost",
54
- "bg-info text-info-foreground hover:bg-info/90 focus-visible:outline-info":
55
- variant === "info",
56
- "bg-success text-success-foreground hover:bg-success/90 focus-visible:outline-success":
57
- variant === "success",
58
- "bg-warning text-warning-foreground hover:bg-warning/90 focus-visible:outline-warning":
59
- variant === "warning",
60
- "bg-error text-error-foreground hover:bg-error/90 focus-visible:outline-error":
61
- variant === "error",
36
+ ],
37
+ variants: {
38
+ variant: {
39
+ default: "bg-foreground text-background hover:bg-foreground/90 focus-visible:outline-outline",
40
+ primary:
41
+ "bg-primary text-primary-foreground hover:bg-primary/90 focus-visible:outline-primary",
42
+ secondary:
43
+ "bg-secondary text-secondary-foreground hover:bg-secondary/90 focus-visible:outline-secondary",
44
+ outline:
45
+ "border-border hover:bg-border hover:text-foreground focus-visible:outline-outline border",
46
+ ghost:
47
+ "hover:bg-foreground/10 hover:text-foreground focus-visible:outline-outline bg-transparent",
48
+ info: "bg-info text-info-foreground hover:bg-info/90 focus-visible:outline-info",
49
+ success:
50
+ "bg-success text-success-foreground hover:bg-success/90 focus-visible:outline-success",
51
+ warning:
52
+ "bg-warning text-warning-foreground hover:bg-warning/90 focus-visible:outline-warning",
53
+ error: "bg-error text-error-foreground hover:bg-error/90 focus-visible:outline-error",
62
54
  },
63
- {
64
- "h-9 px-3 py-2 text-sm": size === "sm",
65
- "h-11 px-4 py-2 text-base": size === "md",
66
- "h-12 px-8 py-2 text-lg": size === "lg",
67
- "h-11 w-11": size === "icon",
55
+ size: {
56
+ sm: "h-9 px-3 py-2 text-sm",
57
+ md: "h-11 px-4 py-2 text-base",
58
+ lg: "h-12 px-8 py-2 text-lg",
59
+ icon: "h-11 w-11",
68
60
  },
69
- {
70
- "rounded-none": radius === "none",
71
- "rounded-xs": radius === "xs",
72
- "rounded-sm": radius === "sm",
73
- "rounded-md": radius === "md",
74
- "rounded-lg": radius === "lg",
75
- "rounded-xl": radius === "xl",
76
- "rounded-full": radius === "full",
77
- },
78
- className,
79
- ]}
80
- {...rest}
81
- >
61
+ },
62
+ defaultVariants: {
63
+ variant: "default",
64
+ size: "md",
65
+ },
66
+ });
67
+
68
+ const Tag = Astro.props.href ? "a" : "button";
69
+ ---
70
+
71
+ <Tag class={button({ variant, size, class: className })} {...rest}>
82
72
  <slot />
83
73
  </Tag>
@@ -1,14 +1,16 @@
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 card = tv({
8
+ base: "bg-card text-card-foreground rounded-2xl border shadow-sm",
9
+ });
10
+
6
11
  const { class: className, ...rest } = Astro.props;
7
12
  ---
8
13
 
9
- <div
10
- class:list={["bg-card text-card-foreground rounded-2xl border shadow-sm", className]}
11
- {...rest}
12
- >
14
+ <div class={card({ class: className })} {...rest}>
13
15
  <slot />
14
16
  </div>
@@ -1,11 +1,16 @@
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 cardContent = tv({
8
+ base: "p-8 pt-0",
9
+ });
10
+
6
11
  const { class: className, ...rest } = Astro.props;
7
12
  ---
8
13
 
9
- <div class:list={["p-8 pt-0", className]} {...rest}>
14
+ <div class={cardContent({ class: className })} {...rest}>
10
15
  <slot />
11
16
  </div>
@@ -1,11 +1,16 @@
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 cardDescription = tv({
8
+ base: "text-muted-foreground text-base",
9
+ });
10
+
6
11
  const { class: className, ...rest } = Astro.props;
7
12
  ---
8
13
 
9
- <div class:list={["text-muted-foreground text-base", className]} {...rest}>
14
+ <div class={cardDescription({ class: className })} {...rest}>
10
15
  <slot />
11
16
  </div>
@@ -1,11 +1,16 @@
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 cardFooter = tv({
8
+ base: "flex items-center p-8 pt-0",
9
+ });
10
+
6
11
  const { class: className, ...rest } = Astro.props;
7
12
  ---
8
13
 
9
- <div class:list={["flex items-center p-8 pt-0", className]} {...rest}>
14
+ <div class={cardFooter({ class: className })} {...rest}>
10
15
  <slot />
11
16
  </div>
@@ -1,11 +1,16 @@
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 cardHeader = tv({
8
+ base: "flex flex-col space-y-2 p-8",
9
+ });
10
+
6
11
  const { class: className, ...rest } = Astro.props;
7
12
  ---
8
13
 
9
- <div class:list={["flex flex-col space-y-2 p-8", className]} {...rest}>
14
+ <div class={cardHeader({ class: className })} {...rest}>
10
15
  <slot />
11
16
  </div>
@@ -1,11 +1,16 @@
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 cardTitle = tv({
8
+ base: "text-3xl leading-none font-semibold tracking-tight",
9
+ });
10
+
6
11
  const { class: className, ...rest } = Astro.props;
7
12
  ---
8
13
 
9
- <div class:list={["text-3xl leading-none font-semibold tracking-tight", className]} {...rest}>
14
+ <div class={cardTitle({ class: className })} {...rest}>
10
15
  <slot />
11
16
  </div>
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  import Check from "@tabler/icons/outline/check.svg";
3
3
  import type { HTMLAttributes } from "astro/types";
4
+ import { tv, type VariantProps } from "tailwind-variants";
4
5
 
5
6
  type Props = Omit<HTMLAttributes<"input">, "type"> & {
6
7
  /**
@@ -23,6 +24,77 @@ type Props = Omit<HTMLAttributes<"input">, "type"> & {
23
24
  variant?: "default" | "primary" | "secondary" | "info" | "success" | "warning" | "error";
24
25
  };
25
26
 
27
+ const checkbox = tv({
28
+ slots: {
29
+ base: "starwind-checkbox relative flex items-center space-x-2",
30
+ input: [
31
+ "peer border-input bg-background starwind-transition-colors shrink-0 transform-gpu rounded-sm border",
32
+ "focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:transition-none",
33
+ "outline-0 focus:ring-0 focus:ring-offset-0",
34
+ "not-disabled:cursor-pointer disabled:cursor-not-allowed disabled:opacity-50",
35
+ ],
36
+ icon: [
37
+ "pointer-events-none absolute stroke-3 p-0.5 opacity-0 transition-opacity peer-checked:opacity-100",
38
+ "starwind-check-icon",
39
+ ],
40
+ label:
41
+ "font-medium peer-not-disabled:cursor-pointer peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
42
+ },
43
+ variants: {
44
+ size: {
45
+ sm: {
46
+ input: "size-4",
47
+ icon: "size-4",
48
+ label: "text-sm",
49
+ },
50
+ md: {
51
+ input: "size-5",
52
+ icon: "size-5",
53
+ label: "text-base",
54
+ },
55
+ lg: {
56
+ input: "size-6",
57
+ icon: "size-6",
58
+ label: "text-lg",
59
+ },
60
+ },
61
+ variant: {
62
+ default: {
63
+ input: "checked:bg-foreground focus-visible:outline-outline",
64
+ icon: "text-background",
65
+ },
66
+ primary: {
67
+ input: "checked:bg-primary focus-visible:outline-primary",
68
+ icon: "text-primary-foreground",
69
+ },
70
+ secondary: {
71
+ input: "checked:bg-secondary focus-visible:outline-secondary",
72
+ icon: "text-secondary-foreground",
73
+ },
74
+ info: {
75
+ input: "checked:bg-info focus-visible:outline-info",
76
+ icon: "text-info-foreground",
77
+ },
78
+ success: {
79
+ input: "checked:bg-success focus-visible:outline-success",
80
+ icon: "text-success-foreground",
81
+ },
82
+ warning: {
83
+ input: "checked:bg-warning focus-visible:outline-warning",
84
+ icon: "text-warning-foreground",
85
+ },
86
+ error: {
87
+ input: "checked:bg-error focus-visible:outline-error",
88
+ icon: "text-error-foreground",
89
+ },
90
+ },
91
+ },
92
+ defaultVariants: {
93
+ size: "md",
94
+ variant: "default",
95
+ },
96
+ });
97
+
26
98
  const {
27
99
  id,
28
100
  label,
@@ -34,64 +106,15 @@ const {
34
106
  ...rest
35
107
  } = Astro.props;
36
108
 
37
- const sizeClass = {
38
- sm: "size-4",
39
- md: "size-5",
40
- lg: "size-6",
41
- };
109
+ const { base, input, icon, label: labelClass } = checkbox({ size, variant });
42
110
  ---
43
111
 
44
- <div class:list={["starwind-checkbox relative flex items-center space-x-2", className]}>
45
- <input
46
- type="checkbox"
47
- id={id}
48
- class:list={[
49
- "peer border-input bg-background starwind-transition-colors shrink-0 transform-gpu rounded-sm border",
50
- "focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:transition-none",
51
- "outline-0 focus:ring-0 focus:ring-offset-0",
52
- "not-disabled:cursor-pointer disabled:cursor-not-allowed disabled:opacity-50",
53
- sizeClass[size],
54
- {
55
- "checked:bg-foreground focus-visible:outline-outline": variant === "default",
56
- "checked:bg-primary focus-visible:outline-primary": variant === "primary",
57
- "checked:bg-secondary focus-visible:outline-secondary": variant === "secondary",
58
- "checked:bg-info focus-visible:outline-info": variant === "info",
59
- "checked:bg-success focus-visible:outline-success": variant === "success",
60
- "checked:bg-warning focus-visible:outline-warning": variant === "warning",
61
- "checked:bg-error focus-visible:outline-error": variant === "error",
62
- },
63
- ]}
64
- {checked}
65
- {...rest}
66
- />
67
- <Check
68
- class:list={[
69
- "pointer-events-none absolute stroke-3 p-0.5 opacity-0 transition-opacity peer-checked:opacity-100",
70
- sizeClass[size],
71
- {
72
- "text-background": variant === "default",
73
- "text-primary-foreground": variant === "primary",
74
- "text-secondary-foreground": variant === "secondary",
75
- "text-info-foreground": variant === "info",
76
- "text-success-foreground": variant === "success",
77
- "text-warning-foreground": variant === "warning",
78
- "text-error-foreground": variant === "error",
79
- },
80
- ]}
81
- />
112
+ <div class={base()}>
113
+ <input type="checkbox" id={id} class={input({ class: className })} {checked} {...rest} />
114
+ <Check class={icon()} />
82
115
  {
83
116
  label && (
84
- <label
85
- for={id}
86
- class:list={[
87
- "font-medium peer-not-disabled:cursor-pointer peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
88
- {
89
- "text-sm": size === "sm",
90
- "text-base": size === "md",
91
- "text-lg": size === "lg",
92
- },
93
- ]}
94
- >
117
+ <label for={id} class={labelClass()}>
95
118
  {label}
96
119
  </label>
97
120
  )
@@ -102,4 +125,27 @@ const sizeClass = {
102
125
  .starwind-checkbox input[type="checkbox"]:checked {
103
126
  background-image: none;
104
127
  }
128
+
129
+ /* Check drawing animation */
130
+ .starwind-check-icon {
131
+ stroke-dasharray: 65;
132
+ stroke-dashoffset: 65;
133
+ opacity: 0;
134
+ }
135
+
136
+ .starwind-checkbox input[type="checkbox"]:checked + .starwind-check-icon {
137
+ animation: draw-check 0.3s ease forwards;
138
+ animation-delay: 0.15s;
139
+ }
140
+
141
+ @keyframes draw-check {
142
+ 0% {
143
+ stroke-dashoffset: 65;
144
+ opacity: 1;
145
+ }
146
+ 100% {
147
+ stroke-dashoffset: 0;
148
+ opacity: 1;
149
+ }
150
+ }
105
151
  </style>
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  import X from "@tabler/icons/outline/x.svg";
3
3
  import type { HTMLAttributes } from "astro/types";
4
+ import { tv } from "tailwind-variants";
4
5
 
5
6
  type Props = HTMLAttributes<"dialog"> & {
6
7
  /**
@@ -9,16 +10,38 @@ type Props = HTMLAttributes<"dialog"> & {
9
10
  animationDuration?: number;
10
11
  };
11
12
 
13
+ const dialogBackdrop = tv({
14
+ base: [
15
+ "starwind-dialog-backdrop fixed inset-0 top-0 left-0 z-50 hidden h-screen w-screen bg-black/80",
16
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0",
17
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0",
18
+ ],
19
+ });
20
+
21
+ const dialogContent = tv({
22
+ base: [
23
+ "fixed top-16 left-[50%] z-50 translate-x-[-50%] sm:top-[50%] sm:translate-y-[-50%]",
24
+ "bg-background w-full max-w-md border p-8 shadow-lg sm:rounded-lg",
25
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
26
+ "data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=open]:slide-in-from-bottom-2",
27
+ "data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=closed]:slide-out-to-bottom-2",
28
+ ],
29
+ });
30
+
31
+ const dialogCloseButton = tv({
32
+ base: [
33
+ "starwind-dialog-close text-muted-foreground",
34
+ "absolute top-5.5 right-5.5 rounded-sm opacity-70 transition-opacity hover:opacity-100 disabled:pointer-events-none",
35
+ "focus-visible:outline-outline focus-visible:outline-2 focus-visible:outline-offset-2",
36
+ ],
37
+ });
38
+
12
39
  const { class: className, animationDuration = 200, ...rest } = Astro.props;
13
40
  ---
14
41
 
15
42
  <!-- dialog overlay -->
16
43
  <div
17
- class:list={[
18
- "starwind-dialog-backdrop fixed inset-0 top-0 left-0 z-50 hidden h-screen w-screen bg-black/80",
19
- "data-[state=open]:animate-in data-[state=open]:fade-in-0",
20
- "data-[state=closed]:animate-out data-[state=closed]:fade-out-0",
21
- ]}
44
+ class={dialogBackdrop()}
22
45
  data-state="closed"
23
46
  style={{
24
47
  animationDuration: `${animationDuration}ms`,
@@ -27,14 +50,7 @@ const { class: className, animationDuration = 200, ...rest } = Astro.props;
27
50
  </div>
28
51
 
29
52
  <dialog
30
- class:list={[
31
- "fixed top-16 left-[50%] z-50 translate-x-[-50%] sm:top-[50%] sm:translate-y-[-50%]",
32
- "bg-background w-full max-w-md border p-8 shadow-lg sm:rounded-lg",
33
- "data-[state=open]:animate-in data-[state=closed]:animate-out",
34
- "data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=open]:slide-in-from-bottom-2",
35
- "data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=closed]:slide-out-to-bottom-2",
36
- className,
37
- ]}
53
+ class={dialogContent({ class: className })}
38
54
  data-state="closed"
39
55
  {...rest}
40
56
  style={{
@@ -44,11 +60,7 @@ const { class: className, animationDuration = 200, ...rest } = Astro.props;
44
60
  <slot />
45
61
  <button
46
62
  type="button"
47
- class:list={[
48
- "starwind-dialog-close text-muted-foreground",
49
- "absolute top-5.5 right-5.5 rounded-sm opacity-70 transition-opacity hover:opacity-100 disabled:pointer-events-none",
50
- "focus-visible:outline-outline focus-visible:outline-2 focus-visible:outline-offset-2",
51
- ]}
63
+ class={dialogCloseButton()}
52
64
  data-dialog-close
53
65
  aria-label="Close dialog"
54
66
  >
@@ -1,11 +1,16 @@
1
1
  ---
2
2
  import type { HTMLAttributes } from "astro/types";
3
+ import { tv } from "tailwind-variants";
3
4
 
4
5
  type Props = HTMLAttributes<"p">;
5
6
 
7
+ const dialogDescription = tv({
8
+ base: "text-muted-foreground",
9
+ });
10
+
6
11
  const { class: className, ...rest } = Astro.props;
7
12
  ---
8
13
 
9
- <p class:list={["text-muted-foreground", className]} {...rest}>
14
+ <p class={dialogDescription({ class: className })} {...rest}>
10
15
  <slot />
11
16
  </p>
@@ -1,11 +1,16 @@
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 dialogFooter = tv({
8
+ base: "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
9
+ });
10
+
6
11
  const { class: className, ...rest } = Astro.props;
7
12
  ---
8
13
 
9
- <div class:list={["flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className]} {...rest}>
14
+ <div class={dialogFooter({ class: className })} {...rest}>
10
15
  <slot />
11
16
  </div>
@@ -1,11 +1,16 @@
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 dialogHeader = tv({
8
+ base: "flex flex-col space-y-2 text-center sm:text-left",
9
+ });
10
+
6
11
  const { class: className, ...rest } = Astro.props;
7
12
  ---
8
13
 
9
- <div class:list={["flex flex-col space-y-2 text-center sm:text-left", className]} {...rest}>
14
+ <div class={dialogHeader({ class: className })} {...rest}>
10
15
  <slot />
11
16
  </div>
@@ -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<"h2">, "id"> & {
5
6
  /**
@@ -8,9 +9,13 @@ type Props = Omit<HTMLAttributes<"h2">, "id"> & {
8
9
  children: any;
9
10
  };
10
11
 
12
+ const dialogTitle = tv({
13
+ base: "text-2xl leading-none font-semibold tracking-tight",
14
+ });
15
+
11
16
  const { class: className, ...rest } = Astro.props;
12
17
  ---
13
18
 
14
- <h2 class:list={["text-2xl leading-none font-semibold tracking-tight", className]} {...rest}>
19
+ <h2 class={dialogTitle({ class: className })} {...rest}>
15
20
  <slot />
16
21
  </h2>
@@ -1,26 +1,32 @@
1
1
  ---
2
2
  import type { HTMLAttributes } from "astro/types";
3
+ import { tv, type VariantProps } from "tailwind-variants";
3
4
 
4
5
  type Props = HTMLAttributes<"input"> & {
5
6
  size?: "sm" | "md" | "lg";
6
7
  };
7
8
 
8
- const { size = "md", class: className, ...rest } = Astro.props;
9
- ---
10
-
11
- <input
12
- class:list={[
9
+ const input = tv({
10
+ base: [
13
11
  "border-input bg-background text-foreground w-full rounded-md border",
14
12
  "focus:outline-outline focus:ring-0 focus:outline-2 focus:outline-offset-2",
15
13
  "file:text-foreground file:my-auto file:mr-4 file:h-full file:border-0 file:bg-transparent file:text-sm file:font-medium",
16
14
  "disabled:cursor-not-allowed disabled:opacity-50",
17
15
  "peer placeholder:text-muted-foreground",
18
- {
19
- "h-9 px-2 text-sm": size === "sm",
20
- "h-11 px-3 text-base": size === "md",
21
- "h-12 px-4 text-lg": size === "lg",
16
+ ],
17
+ variants: {
18
+ size: {
19
+ sm: "h-9 px-2 text-sm",
20
+ md: "h-11 px-3 text-base",
21
+ lg: "h-12 px-4 text-lg",
22
22
  },
23
- className,
24
- ]}
25
- {...rest}
26
- />
23
+ },
24
+ defaultVariants: {
25
+ size: "md",
26
+ },
27
+ });
28
+
29
+ const { size = "md", class: className, ...rest } = Astro.props;
30
+ ---
31
+
32
+ <input class={input({ size, class: className })} {...rest} />
@@ -1,25 +1,31 @@
1
1
  ---
2
2
  import type { HTMLAttributes } from "astro/types";
3
+ import { tv } from "tailwind-variants";
3
4
 
4
5
  type Props = HTMLAttributes<"label"> & {
5
6
  size?: "sm" | "md" | "lg";
6
7
  };
7
8
 
8
- const { size = "md", class: className = "", ...rest } = Astro.props;
9
- ---
10
-
11
- <label
12
- class:list={[
9
+ const label = tv({
10
+ base: [
13
11
  "text-foreground leading-none font-medium",
14
12
  "peer-disabled:cursor-not-allowed peer-disabled:opacity-70 has-[+:disabled]:cursor-not-allowed has-[+:disabled]:opacity-70",
15
- {
16
- "text-sm": size === "sm",
17
- "text-base": size === "md",
18
- "text-lg": size === "lg",
13
+ ],
14
+ variants: {
15
+ size: {
16
+ sm: "text-sm",
17
+ md: "text-base",
18
+ lg: "text-lg",
19
19
  },
20
- className,
21
- ]}
22
- {...rest}
23
- >
20
+ },
21
+ defaultVariants: {
22
+ size: "md",
23
+ },
24
+ });
25
+
26
+ const { size = "md", class: className = "", ...rest } = Astro.props;
27
+ ---
28
+
29
+ <label class={label({ size, class: className })} {...rest}>
24
30
  <slot />
25
31
  </label>