@starwind-ui/core 0.0.1 → 0.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 (70) hide show
  1. package/dist/index.js +86 -2
  2. package/dist/index.js.map +1 -1
  3. package/dist/src/components/accordion/Accordion.astro +248 -0
  4. package/dist/src/components/accordion/AccordionContent.astro +28 -0
  5. package/dist/src/components/accordion/AccordionItem.astro +25 -0
  6. package/dist/src/components/accordion/AccordionTrigger.astro +26 -0
  7. package/dist/src/components/accordion/index.ts +13 -0
  8. package/dist/src/components/alert/Alert.astro +44 -0
  9. package/dist/src/components/alert/AlertDescription.astro +11 -0
  10. package/dist/src/components/alert/AlertTitle.astro +17 -0
  11. package/dist/src/components/alert/index.ts +11 -0
  12. package/dist/src/components/avatar/Avatar.astro +44 -0
  13. package/dist/src/components/avatar/AvatarFallback.astro +16 -0
  14. package/dist/src/components/avatar/AvatarImage.astro +48 -0
  15. package/dist/src/components/avatar/index.ts +11 -0
  16. package/dist/src/components/card/Card.astro +14 -0
  17. package/dist/src/components/card/CardContent.astro +11 -0
  18. package/dist/src/components/card/CardDescription.astro +11 -0
  19. package/dist/src/components/card/CardFooter.astro +11 -0
  20. package/dist/src/components/card/CardHeader.astro +11 -0
  21. package/dist/src/components/card/CardTitle.astro +11 -0
  22. package/dist/src/components/card/index.ts +17 -0
  23. package/dist/src/components/checkbox/Checkbox.astro +105 -0
  24. package/dist/src/components/checkbox/index.ts +5 -0
  25. package/dist/src/components/dialog/Dialog.astro +175 -0
  26. package/dist/src/components/dialog/DialogClose.astro +30 -0
  27. package/dist/src/components/dialog/DialogContent.astro +57 -0
  28. package/dist/src/components/dialog/DialogDescription.astro +11 -0
  29. package/dist/src/components/dialog/DialogFooter.astro +11 -0
  30. package/dist/src/components/dialog/DialogHeader.astro +11 -0
  31. package/dist/src/components/dialog/DialogTitle.astro +16 -0
  32. package/dist/src/components/dialog/DialogTrigger.astro +35 -0
  33. package/dist/src/components/dialog/index.ts +30 -0
  34. package/dist/src/components/input/Input.astro +26 -0
  35. package/dist/src/components/input/index.ts +5 -0
  36. package/dist/src/components/label/Label.astro +25 -0
  37. package/dist/src/components/label/index.ts +5 -0
  38. package/dist/src/components/pagination/Pagination.astro +18 -0
  39. package/dist/src/components/pagination/PaginationContent.astro +13 -0
  40. package/dist/src/components/pagination/PaginationEllipsis.astro +15 -0
  41. package/dist/src/components/pagination/PaginationItem.astro +13 -0
  42. package/dist/src/components/pagination/PaginationLink.astro +50 -0
  43. package/dist/src/components/pagination/PaginationNext.astro +23 -0
  44. package/dist/src/components/pagination/PaginationPrevious.astro +23 -0
  45. package/dist/src/components/pagination/index.ts +27 -0
  46. package/dist/src/components/select/Select.astro +452 -0
  47. package/dist/src/components/select/SelectContent.astro +57 -0
  48. package/dist/src/components/select/SelectGroup.astro +10 -0
  49. package/dist/src/components/select/SelectItem.astro +41 -0
  50. package/dist/src/components/select/SelectLabel.astro +11 -0
  51. package/dist/src/components/select/SelectSeparator.astro +9 -0
  52. package/dist/src/components/select/SelectTrigger.astro +40 -0
  53. package/dist/src/components/select/SelectTypes.ts +7 -0
  54. package/dist/src/components/select/SelectValue.astro +16 -0
  55. package/dist/src/components/select/index.ts +30 -0
  56. package/dist/src/components/switch/Switch.astro +189 -0
  57. package/dist/src/components/switch/SwitchTypes.ts +6 -0
  58. package/dist/src/components/switch/index.ts +6 -0
  59. package/dist/src/components/tabs/Tabs.astro +246 -0
  60. package/dist/src/components/tabs/TabsContent.astro +22 -0
  61. package/dist/src/components/tabs/TabsList.astro +19 -0
  62. package/dist/src/components/tabs/TabsTrigger.astro +27 -0
  63. package/dist/src/components/tabs/index.ts +13 -0
  64. package/dist/src/components/textarea/Textarea.astro +25 -0
  65. package/dist/src/components/textarea/index.ts +5 -0
  66. package/dist/src/components/tooltip/Tooltip.astro +233 -0
  67. package/dist/src/components/tooltip/TooltipContent.astro +76 -0
  68. package/dist/src/components/tooltip/TooltipTrigger.astro +11 -0
  69. package/dist/src/components/tooltip/index.ts +11 -0
  70. package/package.json +1 -1
@@ -0,0 +1,14 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types";
3
+
4
+ type Props = HTMLAttributes<"div">;
5
+
6
+ const { class: className, ...rest } = Astro.props;
7
+ ---
8
+
9
+ <div
10
+ class:list={["bg-card text-card-foreground rounded-2xl border shadow-sm", className]}
11
+ {...rest}
12
+ >
13
+ <slot />
14
+ </div>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types";
3
+
4
+ type Props = HTMLAttributes<"div">;
5
+
6
+ const { class: className, ...rest } = Astro.props;
7
+ ---
8
+
9
+ <div class:list={["p-8 pt-0", className]} {...rest}>
10
+ <slot />
11
+ </div>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types";
3
+
4
+ type Props = HTMLAttributes<"div">;
5
+
6
+ const { class: className, ...rest } = Astro.props;
7
+ ---
8
+
9
+ <div class:list={["text-muted-foreground text-base", className]} {...rest}>
10
+ <slot />
11
+ </div>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types";
3
+
4
+ type Props = HTMLAttributes<"div">;
5
+
6
+ const { class: className, ...rest } = Astro.props;
7
+ ---
8
+
9
+ <div class:list={["flex items-center p-8 pt-0", className]} {...rest}>
10
+ <slot />
11
+ </div>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types";
3
+
4
+ type Props = HTMLAttributes<"div">;
5
+
6
+ const { class: className, ...rest } = Astro.props;
7
+ ---
8
+
9
+ <div class:list={["flex flex-col space-y-2 p-8", className]} {...rest}>
10
+ <slot />
11
+ </div>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types";
3
+
4
+ type Props = HTMLAttributes<"div">;
5
+
6
+ const { class: className, ...rest } = Astro.props;
7
+ ---
8
+
9
+ <div class:list={["text-3xl leading-none font-semibold tracking-tight", className]} {...rest}>
10
+ <slot />
11
+ </div>
@@ -0,0 +1,17 @@
1
+ import Card from "./Card.astro";
2
+ import CardContent from "./CardContent.astro";
3
+ import CardDescription from "./CardDescription.astro";
4
+ import CardFooter from "./CardFooter.astro";
5
+ import CardHeader from "./CardHeader.astro";
6
+ import CardTitle from "./CardTitle.astro";
7
+
8
+ export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };
9
+
10
+ export default {
11
+ Root: Card,
12
+ Header: CardHeader,
13
+ Footer: CardFooter,
14
+ Title: CardTitle,
15
+ Description: CardDescription,
16
+ Content: CardContent,
17
+ };
@@ -0,0 +1,105 @@
1
+ ---
2
+ import Check from "@tabler/icons/outline/check.svg";
3
+ import type { HTMLAttributes } from "astro/types";
4
+
5
+ type Props = Omit<HTMLAttributes<"input">, "type"> & {
6
+ /**
7
+ * Unique identifier for the checkbox input
8
+ */
9
+ id: string;
10
+ /**
11
+ * Optional label text to display next to the checkbox
12
+ */
13
+ label?: string;
14
+ /**
15
+ * Size variant of the checkbox
16
+ * @default "md"
17
+ */
18
+ size?: "sm" | "md" | "lg";
19
+ /**
20
+ * Visual style variant of the checkbox
21
+ * @default "default"
22
+ */
23
+ variant?: "default" | "primary" | "secondary" | "info" | "success" | "warning" | "error";
24
+ };
25
+
26
+ const {
27
+ id,
28
+ label,
29
+ value,
30
+ checked,
31
+ size = "md",
32
+ variant = "default",
33
+ class: className = "",
34
+ ...rest
35
+ } = Astro.props;
36
+
37
+ const sizeClass = {
38
+ sm: "size-4",
39
+ md: "size-5",
40
+ lg: "size-6",
41
+ };
42
+ ---
43
+
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
+ />
82
+ {
83
+ 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
+ >
95
+ {label}
96
+ </label>
97
+ )
98
+ }
99
+ </div>
100
+
101
+ <style>
102
+ .starwind-checkbox input[type="checkbox"]:checked {
103
+ background-image: none;
104
+ }
105
+ </style>
@@ -0,0 +1,5 @@
1
+ import Checkbox from "./Checkbox.astro";
2
+
3
+ export { Checkbox };
4
+
5
+ export default Checkbox;
@@ -0,0 +1,175 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types";
3
+
4
+ type Props = HTMLAttributes<"div">;
5
+
6
+ const { class: className, ...rest } = Astro.props;
7
+ ---
8
+
9
+ <div class:list={["starwind-dialog", className]} {...rest}>
10
+ <slot />
11
+ </div>
12
+
13
+ <script>
14
+ class DialogHandler {
15
+ private trigger: HTMLButtonElement;
16
+ private dialog: HTMLDialogElement;
17
+ private closeButtons: NodeListOf<HTMLButtonElement>;
18
+ private backdrop: HTMLElement;
19
+ /**
20
+ * The duration of the animation in milliseconds. This is used to calculate the
21
+ * duration of close animation before hiding the dialog and backdrop
22
+ */
23
+ private animationDuration: number;
24
+
25
+ constructor(dialogWrapper: HTMLElement, dialogNumber: number) {
26
+ this.dialog = dialogWrapper.querySelector("dialog")!;
27
+ this.backdrop = dialogWrapper.querySelector(".starwind-dialog-backdrop")!;
28
+
29
+ // animationDuration is set with inline styles through passed prop to DialogContent
30
+ const animationDurationString = this.dialog.style.animationDuration;
31
+ if (animationDurationString.endsWith("ms")) {
32
+ this.animationDuration = parseFloat(animationDurationString);
33
+ } else if (animationDurationString.endsWith("s")) {
34
+ // using something like @playform/compress might optimize to use "s" instead of "ms"
35
+ this.animationDuration = parseFloat(animationDurationString) * 1000;
36
+ } else {
37
+ this.animationDuration = 200;
38
+ }
39
+
40
+ // if trigger is set with asChild, use the first child element for trigger button
41
+ const tempTrigger = dialogWrapper.querySelector(".starwind-dialog-trigger") as HTMLElement;
42
+ if (tempTrigger?.hasAttribute("data-as-child")) {
43
+ this.trigger = tempTrigger.firstElementChild as HTMLButtonElement;
44
+ } else {
45
+ this.trigger = tempTrigger as HTMLButtonElement;
46
+ }
47
+
48
+ // if closeButtons are set with asChild, swap the wrapper with its first child
49
+ const tempCloseButtons = dialogWrapper.querySelectorAll(
50
+ ".starwind-dialog-close",
51
+ ) as NodeListOf<HTMLElement>;
52
+ tempCloseButtons.forEach((button: HTMLElement) => {
53
+ if (button.hasAttribute("data-as-child")) {
54
+ const childElement = button.firstElementChild;
55
+ if (childElement) {
56
+ childElement.classList.add("starwind-dialog-close");
57
+ button.parentNode?.replaceChild(childElement, button);
58
+ }
59
+ }
60
+ return button;
61
+ });
62
+
63
+ this.closeButtons = dialogWrapper.querySelectorAll(
64
+ ".starwind-dialog-close",
65
+ ) as NodeListOf<HTMLButtonElement>;
66
+
67
+ // if any elements are not there, exit
68
+ if (!this.trigger || !this.dialog || !this.backdrop) return;
69
+
70
+ this.setupAccessibility(dialogNumber);
71
+ this.setupEvents();
72
+ }
73
+
74
+ private setupAccessibility(dialogNumber: number): void {
75
+ // get the first heading element in the dialog
76
+ const firstHeading = this.dialog.querySelector("h1, h2, h3, h4, h5, h6");
77
+ if (firstHeading) {
78
+ // create a unique ID for the heading
79
+ firstHeading.id = `starwind-dialog${dialogNumber}-heading`;
80
+ // set the aria-labelledby attribute to the first heading element
81
+ this.dialog.setAttribute("aria-labelledby", firstHeading.id);
82
+ }
83
+ }
84
+
85
+ private setupEvents(): void {
86
+ this.trigger?.addEventListener("click", () => {
87
+ this.open();
88
+ });
89
+
90
+ // Add click handlers to all close buttons
91
+ this.closeButtons?.forEach((button) => {
92
+ button.addEventListener("click", () => {
93
+ this.close();
94
+ });
95
+ });
96
+
97
+ // Close on click outside
98
+ this.dialog.addEventListener("click", (e) => {
99
+ const dialogDimensions = this.dialog.getBoundingClientRect();
100
+ const clickedInDialog =
101
+ e.clientX >= dialogDimensions.left &&
102
+ e.clientX <= dialogDimensions.right &&
103
+ e.clientY >= dialogDimensions.top &&
104
+ e.clientY <= dialogDimensions.bottom;
105
+
106
+ if (!clickedInDialog) {
107
+ this.close();
108
+ }
109
+ });
110
+
111
+ // Handle escape key
112
+ this.dialog.addEventListener("keydown", (e) => {
113
+ if (e.key === "Escape") {
114
+ // prevent default dialog closing behavior so we can add closing animation
115
+ e.preventDefault();
116
+ this.close();
117
+ }
118
+ });
119
+
120
+ // Intercept form submissions to handle dialog close
121
+ const forms = this.dialog.querySelectorAll("form");
122
+ forms.forEach((form) => {
123
+ form.addEventListener("submit", (e) => {
124
+ /**
125
+ * Default form.method = "dialog" submissions cause the dialog to close
126
+ * Default form.method = "post" submissions do not close the dialog
127
+ * Here we intercept the form submission and manage the dialog closing if method = "dialog"
128
+ * so we can add closing animation
129
+ * Normal form event listeners for "submit" will still get the form data
130
+ */
131
+ if (form.method === "dialog") {
132
+ e.preventDefault();
133
+ this.close();
134
+ }
135
+ });
136
+ });
137
+ }
138
+
139
+ private open(): void {
140
+ this.dialog.showModal();
141
+ document.body.classList.add("overflow-hidden");
142
+ this.backdrop.classList.remove("hidden");
143
+ this.backdrop.dataset.state = "open";
144
+ this.dialog.dataset.state = "open";
145
+ }
146
+
147
+ private close(): void {
148
+ document.body.classList.remove("overflow-hidden");
149
+ this.dialog.dataset.state = "closed";
150
+ this.backdrop.dataset.state = "closed";
151
+
152
+ // Wait for animation to finish before hiding backdrop
153
+ setTimeout(() => {
154
+ this.backdrop.classList.add("hidden");
155
+ this.dialog.close();
156
+ }, this.animationDuration - 10);
157
+ }
158
+ }
159
+
160
+ // Store instances in a WeakMap to avoid memory leaks
161
+ const dialogInstances = new WeakMap<HTMLElement, DialogHandler>();
162
+
163
+ // Initialize all dialogs
164
+ const setupDialogs = () => {
165
+ document.querySelectorAll(".starwind-dialog").forEach((dialogWrapper, idx) => {
166
+ const wrapper = dialogWrapper as HTMLElement;
167
+ if (!dialogInstances.has(wrapper)) {
168
+ dialogInstances.set(wrapper, new DialogHandler(wrapper, idx));
169
+ }
170
+ });
171
+ };
172
+
173
+ setupDialogs();
174
+ document.addEventListener("astro:after-swap", setupDialogs);
175
+ </script>
@@ -0,0 +1,30 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types";
3
+
4
+ type Props = HTMLAttributes<"button"> & {
5
+ /**
6
+ * When true, the component will render its child element instead of a button
7
+ */
8
+ asChild?: boolean;
9
+ };
10
+
11
+ const { class: className, asChild = false, ...rest } = Astro.props;
12
+
13
+ // Get the first child element if asChild is true
14
+ let hasChildren = false;
15
+ if (Astro.slots.has("default")) {
16
+ hasChildren = true;
17
+ }
18
+ ---
19
+
20
+ {
21
+ asChild && hasChildren ? (
22
+ <div class="starwind-dialog-close" data-as-child>
23
+ <slot />
24
+ </div>
25
+ ) : (
26
+ <button type="button" class:list={["starwind-dialog-close", className]} {...rest}>
27
+ <slot>Demo close button</slot>
28
+ </button>
29
+ )
30
+ }
@@ -0,0 +1,57 @@
1
+ ---
2
+ import X from "@tabler/icons/outline/x.svg";
3
+ import type { HTMLAttributes } from "astro/types";
4
+
5
+ type Props = HTMLAttributes<"dialog"> & {
6
+ /**
7
+ * Open and close animation duration in milliseconds
8
+ */
9
+ animationDuration?: number;
10
+ };
11
+
12
+ const { class: className, animationDuration = 200, ...rest } = Astro.props;
13
+ ---
14
+
15
+ <!-- dialog overlay -->
16
+ <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
+ ]}
22
+ data-state="closed"
23
+ style={{
24
+ animationDuration: `${animationDuration}ms`,
25
+ }}
26
+ >
27
+ </div>
28
+
29
+ <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
+ ]}
38
+ data-state="closed"
39
+ {...rest}
40
+ style={{
41
+ animationDuration: `${animationDuration}ms`,
42
+ }}
43
+ >
44
+ <slot />
45
+ <button
46
+ 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
+ ]}
52
+ data-dialog-close
53
+ aria-label="Close dialog"
54
+ >
55
+ <X class="size-5" />
56
+ </button>
57
+ </dialog>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types";
3
+
4
+ type Props = HTMLAttributes<"p">;
5
+
6
+ const { class: className, ...rest } = Astro.props;
7
+ ---
8
+
9
+ <p class:list={["text-muted-foreground", className]} {...rest}>
10
+ <slot />
11
+ </p>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types";
3
+
4
+ type Props = HTMLAttributes<"div">;
5
+
6
+ const { class: className, ...rest } = Astro.props;
7
+ ---
8
+
9
+ <div class:list={["flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className]} {...rest}>
10
+ <slot />
11
+ </div>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types";
3
+
4
+ type Props = HTMLAttributes<"div">;
5
+
6
+ const { class: className, ...rest } = Astro.props;
7
+ ---
8
+
9
+ <div class:list={["flex flex-col space-y-2 text-center sm:text-left", className]} {...rest}>
10
+ <slot />
11
+ </div>
@@ -0,0 +1,16 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types";
3
+
4
+ type Props = Omit<HTMLAttributes<"h2">, "id"> & {
5
+ /**
6
+ * The content to be rendered inside the dialog title
7
+ */
8
+ children: any;
9
+ };
10
+
11
+ const { class: className, ...rest } = Astro.props;
12
+ ---
13
+
14
+ <h2 class:list={["text-2xl leading-none font-semibold tracking-tight", className]} {...rest}>
15
+ <slot />
16
+ </h2>
@@ -0,0 +1,35 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types";
3
+
4
+ type Props = HTMLAttributes<"button"> & {
5
+ /**
6
+ * When true, the component will render its child element with a simple wrapper instead of a button component
7
+ */
8
+ asChild?: boolean;
9
+ };
10
+
11
+ const { class: className, asChild = false, ...rest } = Astro.props;
12
+
13
+ // Get the first child element if asChild is true
14
+ let hasChildren = false;
15
+ if (Astro.slots.has("default")) {
16
+ hasChildren = true;
17
+ }
18
+ ---
19
+
20
+ {
21
+ asChild && hasChildren ? (
22
+ <div class="starwind-dialog-trigger" data-as-child>
23
+ <slot />
24
+ </div>
25
+ ) : (
26
+ <button
27
+ type="button"
28
+ aria-haspopup="dialog"
29
+ class:list={["starwind-dialog-trigger", className]}
30
+ {...rest}
31
+ >
32
+ <slot />
33
+ </button>
34
+ )
35
+ }
@@ -0,0 +1,30 @@
1
+ import Dialog from "./Dialog.astro";
2
+ import DialogClose from "./DialogClose.astro";
3
+ import DialogContent from "./DialogContent.astro";
4
+ import DialogDescription from "./DialogDescription.astro";
5
+ import DialogFooter from "./DialogFooter.astro";
6
+ import DialogHeader from "./DialogHeader.astro";
7
+ import DialogTitle from "./DialogTitle.astro";
8
+ import DialogTrigger from "./DialogTrigger.astro";
9
+
10
+ export {
11
+ Dialog,
12
+ DialogTrigger,
13
+ DialogContent,
14
+ DialogHeader,
15
+ DialogFooter,
16
+ DialogTitle,
17
+ DialogDescription,
18
+ DialogClose,
19
+ };
20
+
21
+ export default {
22
+ Root: Dialog,
23
+ Trigger: DialogTrigger,
24
+ Content: DialogContent,
25
+ Header: DialogHeader,
26
+ Footer: DialogFooter,
27
+ Title: DialogTitle,
28
+ Description: DialogDescription,
29
+ Close: DialogClose,
30
+ };
@@ -0,0 +1,26 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types";
3
+
4
+ type Props = HTMLAttributes<"input"> & {
5
+ size?: "sm" | "md" | "lg";
6
+ };
7
+
8
+ const { size = "md", class: className, ...rest } = Astro.props;
9
+ ---
10
+
11
+ <input
12
+ class:list={[
13
+ "border-input bg-background text-foreground w-full rounded-md border",
14
+ "focus:outline-outline focus:ring-0 focus:outline-2 focus:outline-offset-2",
15
+ "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
+ "disabled:cursor-not-allowed disabled:opacity-50",
17
+ "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",
22
+ },
23
+ className,
24
+ ]}
25
+ {...rest}
26
+ />
@@ -0,0 +1,5 @@
1
+ import Input from "./Input.astro";
2
+
3
+ export { Input };
4
+
5
+ export default Input;
@@ -0,0 +1,25 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types";
3
+
4
+ type Props = HTMLAttributes<"label"> & {
5
+ size?: "sm" | "md" | "lg";
6
+ };
7
+
8
+ const { size = "md", class: className = "", ...rest } = Astro.props;
9
+ ---
10
+
11
+ <label
12
+ class:list={[
13
+ "text-foreground leading-none font-medium",
14
+ "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",
19
+ },
20
+ className,
21
+ ]}
22
+ {...rest}
23
+ >
24
+ <slot />
25
+ </label>
@@ -0,0 +1,5 @@
1
+ import Label from "./Label.astro";
2
+
3
+ export { Label };
4
+
5
+ export default Label;
@@ -0,0 +1,18 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types";
3
+
4
+ type Props = HTMLAttributes<"nav"> & {
5
+ children: any;
6
+ };
7
+
8
+ const { class: className, ...rest } = Astro.props;
9
+ ---
10
+
11
+ <nav
12
+ role="navigation"
13
+ aria-label="pagination"
14
+ class:list={["mx-auto flex w-full justify-center", className]}
15
+ {...rest}
16
+ >
17
+ <slot />
18
+ </nav>