@starwind-ui/core 1.15.1 → 1.15.2
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.
- package/dist/index.d.ts +28 -0
- package/dist/index.js +108 -0
- package/dist/index.js.map +1 -0
- package/dist/src/components/accordion/Accordion.astro +254 -0
- package/dist/src/components/accordion/AccordionContent.astro +33 -0
- package/dist/src/components/accordion/AccordionItem.astro +27 -0
- package/dist/src/components/accordion/AccordionTrigger.astro +32 -0
- package/dist/src/components/accordion/index.ts +15 -0
- package/dist/src/components/alert/Alert.astro +31 -0
- package/dist/src/components/alert/AlertDescription.astro +14 -0
- package/dist/src/components/alert/AlertTitle.astro +16 -0
- package/dist/src/components/alert/index.ts +13 -0
- package/dist/src/components/alert-dialog/AlertDialog.astro +275 -0
- package/dist/src/components/alert-dialog/AlertDialogAction.astro +44 -0
- package/dist/src/components/alert-dialog/AlertDialogCancel.astro +45 -0
- package/dist/src/components/alert-dialog/AlertDialogContent.astro +52 -0
- package/dist/src/components/alert-dialog/AlertDialogDescription.astro +18 -0
- package/dist/src/components/alert-dialog/AlertDialogFooter.astro +16 -0
- package/dist/src/components/alert-dialog/AlertDialogHeader.astro +14 -0
- package/dist/src/components/alert-dialog/AlertDialogTitle.astro +20 -0
- package/dist/src/components/alert-dialog/AlertDialogTrigger.astro +47 -0
- package/dist/src/components/alert-dialog/index.ts +46 -0
- package/dist/src/components/aspect-ratio/AspectRatio.astro +32 -0
- package/dist/src/components/aspect-ratio/index.ts +7 -0
- package/dist/src/components/avatar/Avatar.astro +29 -0
- package/dist/src/components/avatar/AvatarFallback.astro +18 -0
- package/dist/src/components/avatar/AvatarImage.astro +49 -0
- package/dist/src/components/avatar/index.ts +13 -0
- package/dist/src/components/badge/Badge.astro +55 -0
- package/dist/src/components/badge/index.ts +7 -0
- package/dist/src/components/breadcrumb/Breadcrumb.astro +11 -0
- package/dist/src/components/breadcrumb/BreadcrumbEllipsis.astro +28 -0
- package/dist/src/components/breadcrumb/BreadcrumbItem.astro +14 -0
- package/dist/src/components/breadcrumb/BreadcrumbLink.astro +22 -0
- package/dist/src/components/breadcrumb/BreadcrumbList.astro +16 -0
- package/dist/src/components/breadcrumb/BreadcrumbPage.astro +21 -0
- package/dist/src/components/breadcrumb/BreadcrumbSeparator.astro +23 -0
- package/dist/src/components/breadcrumb/index.ts +37 -0
- package/dist/src/components/button/Button.astro +55 -0
- package/dist/src/components/button/index.ts +7 -0
- package/dist/src/components/button-group/ButtonGroup.astro +62 -0
- package/dist/src/components/button-group/ButtonGroupSeparator.astro +27 -0
- package/dist/src/components/button-group/ButtonGroupText.astro +19 -0
- package/dist/src/components/button-group/index.ts +17 -0
- package/dist/src/components/card/Card.astro +14 -0
- package/dist/src/components/card/CardContent.astro +14 -0
- package/dist/src/components/card/CardDescription.astro +14 -0
- package/dist/src/components/card/CardFooter.astro +14 -0
- package/dist/src/components/card/CardHeader.astro +14 -0
- package/dist/src/components/card/CardTitle.astro +14 -0
- package/dist/src/components/card/index.ts +26 -0
- package/dist/src/components/carousel/Carousel.astro +55 -0
- package/dist/src/components/carousel/CarouselContent.astro +26 -0
- package/dist/src/components/carousel/CarouselItem.astro +26 -0
- package/dist/src/components/carousel/CarouselNext.astro +37 -0
- package/dist/src/components/carousel/CarouselPrevious.astro +37 -0
- package/dist/src/components/carousel/carousel-script.ts +191 -0
- package/dist/src/components/carousel/index.ts +32 -0
- package/dist/src/components/checkbox/Checkbox.astro +128 -0
- package/dist/src/components/checkbox/index.ts +7 -0
- package/dist/src/components/collapsible/Collapsible.astro +161 -0
- package/dist/src/components/collapsible/CollapsibleContent.astro +22 -0
- package/dist/src/components/collapsible/CollapsibleTrigger.astro +44 -0
- package/dist/src/components/collapsible/index.ts +13 -0
- package/dist/src/components/dialog/Dialog.astro +389 -0
- package/dist/src/components/dialog/DialogClose.astro +35 -0
- package/dist/src/components/dialog/DialogContent.astro +78 -0
- package/dist/src/components/dialog/DialogDescription.astro +14 -0
- package/dist/src/components/dialog/DialogFooter.astro +14 -0
- package/dist/src/components/dialog/DialogHeader.astro +14 -0
- package/dist/src/components/dialog/DialogTitle.astro +22 -0
- package/dist/src/components/dialog/DialogTrigger.astro +47 -0
- package/dist/src/components/dialog/index.ts +45 -0
- package/dist/src/components/dropdown/Dropdown.astro +377 -0
- package/dist/src/components/dropdown/DropdownContent.astro +81 -0
- package/dist/src/components/dropdown/DropdownItem.astro +48 -0
- package/dist/src/components/dropdown/DropdownLabel.astro +29 -0
- package/dist/src/components/dropdown/DropdownSeparator.astro +21 -0
- package/dist/src/components/dropdown/DropdownTrigger.astro +52 -0
- package/dist/src/components/dropdown/index.ts +33 -0
- package/dist/src/components/dropzone/Dropzone.astro +236 -0
- package/dist/src/components/dropzone/DropzoneFilesList.astro +26 -0
- package/dist/src/components/dropzone/DropzoneLoadingIndicator.astro +10 -0
- package/dist/src/components/dropzone/DropzoneUploadIndicator.astro +10 -0
- package/dist/src/components/dropzone/index.ts +24 -0
- package/dist/src/components/image/Image.astro +24 -0
- package/dist/src/components/image/index.ts +9 -0
- package/dist/src/components/input/Input.astro +25 -0
- package/dist/src/components/input/index.ts +7 -0
- package/dist/src/components/input-otp/InputOtp.astro +352 -0
- package/dist/src/components/input-otp/InputOtpGroup.astro +16 -0
- package/dist/src/components/input-otp/InputOtpSeparator.astro +25 -0
- package/dist/src/components/input-otp/InputOtpSlot.astro +48 -0
- package/dist/src/components/input-otp/InputOtpTypes.ts +6 -0
- package/dist/src/components/input-otp/index.ts +33 -0
- package/dist/src/components/item/Item.astro +52 -0
- package/dist/src/components/item/ItemActions.astro +16 -0
- package/dist/src/components/item/ItemContent.astro +16 -0
- package/dist/src/components/item/ItemDescription.astro +19 -0
- package/dist/src/components/item/ItemFooter.astro +16 -0
- package/dist/src/components/item/ItemGroup.astro +16 -0
- package/dist/src/components/item/ItemHeader.astro +16 -0
- package/dist/src/components/item/ItemMedia.astro +40 -0
- package/dist/src/components/item/ItemSeparator.astro +21 -0
- package/dist/src/components/item/ItemTitle.astro +16 -0
- package/dist/src/components/item/index.ts +50 -0
- package/dist/src/components/kbd/Kbd.astro +21 -0
- package/dist/src/components/kbd/KbdGroup.astro +16 -0
- package/dist/src/components/kbd/index.ts +11 -0
- package/dist/src/components/label/Label.astro +22 -0
- package/dist/src/components/label/index.ts +7 -0
- package/dist/src/components/pagination/Pagination.astro +20 -0
- package/dist/src/components/pagination/PaginationContent.astro +16 -0
- package/dist/src/components/pagination/PaginationEllipsis.astro +35 -0
- package/dist/src/components/pagination/PaginationItem.astro +16 -0
- package/dist/src/components/pagination/PaginationLink.astro +24 -0
- package/dist/src/components/pagination/PaginationNext.astro +30 -0
- package/dist/src/components/pagination/PaginationPrevious.astro +30 -0
- package/dist/src/components/pagination/index.ts +38 -0
- package/dist/src/components/progress/Progress.astro +155 -0
- package/dist/src/components/progress/index.ts +10 -0
- package/dist/src/components/prose/Prose.astro +617 -0
- package/dist/src/components/prose/index.ts +9 -0
- package/dist/src/components/radio-group/RadioGroup.astro +162 -0
- package/dist/src/components/radio-group/RadioGroupItem.astro +129 -0
- package/dist/src/components/radio-group/RadioGroupTypes.ts +6 -0
- package/dist/src/components/radio-group/index.ts +23 -0
- package/dist/src/components/select/Select.astro +752 -0
- package/dist/src/components/select/SelectContent.astro +94 -0
- package/dist/src/components/select/SelectGroup.astro +9 -0
- package/dist/src/components/select/SelectItem.astro +51 -0
- package/dist/src/components/select/SelectLabel.astro +14 -0
- package/dist/src/components/select/SelectSearch.astro +49 -0
- package/dist/src/components/select/SelectSeparator.astro +12 -0
- package/dist/src/components/select/SelectTrigger.astro +54 -0
- package/dist/src/components/select/SelectTypes.ts +13 -0
- package/dist/src/components/select/SelectValue.astro +19 -0
- package/dist/src/components/select/index.ts +49 -0
- package/dist/src/components/separator/Separator.astro +36 -0
- package/dist/src/components/separator/index.ts +7 -0
- package/dist/src/components/sheet/Sheet.astro +13 -0
- package/dist/src/components/sheet/SheetClose.astro +13 -0
- package/dist/src/components/sheet/SheetContent.astro +92 -0
- package/dist/src/components/sheet/SheetDescription.astro +16 -0
- package/dist/src/components/sheet/SheetFooter.astro +16 -0
- package/dist/src/components/sheet/SheetHeader.astro +16 -0
- package/dist/src/components/sheet/SheetTitle.astro +16 -0
- package/dist/src/components/sheet/SheetTrigger.astro +13 -0
- package/dist/src/components/sheet/index.ts +41 -0
- package/dist/src/components/sidebar/Sidebar.astro +213 -0
- package/dist/src/components/sidebar/SidebarContent.astro +24 -0
- package/dist/src/components/sidebar/SidebarFooter.astro +21 -0
- package/dist/src/components/sidebar/SidebarGroup.astro +21 -0
- package/dist/src/components/sidebar/SidebarGroupContent.astro +21 -0
- package/dist/src/components/sidebar/SidebarGroupLabel.astro +52 -0
- package/dist/src/components/sidebar/SidebarHeader.astro +21 -0
- package/dist/src/components/sidebar/SidebarInput.astro +22 -0
- package/dist/src/components/sidebar/SidebarInset.astro +21 -0
- package/dist/src/components/sidebar/SidebarMenu.astro +21 -0
- package/dist/src/components/sidebar/SidebarMenuAction.astro +59 -0
- package/dist/src/components/sidebar/SidebarMenuBadge.astro +30 -0
- package/dist/src/components/sidebar/SidebarMenuButton.astro +129 -0
- package/dist/src/components/sidebar/SidebarMenuItem.astro +21 -0
- package/dist/src/components/sidebar/SidebarMenuSkeleton.astro +40 -0
- package/dist/src/components/sidebar/SidebarMenuSub.astro +24 -0
- package/dist/src/components/sidebar/SidebarMenuSubButton.astro +49 -0
- package/dist/src/components/sidebar/SidebarMenuSubItem.astro +16 -0
- package/dist/src/components/sidebar/SidebarProvider.astro +213 -0
- package/dist/src/components/sidebar/SidebarRail.astro +71 -0
- package/dist/src/components/sidebar/SidebarSeparator.astro +22 -0
- package/dist/src/components/sidebar/SidebarTrigger.astro +66 -0
- package/dist/src/components/sidebar/index.ts +103 -0
- package/dist/src/components/skeleton/Skeleton.astro +14 -0
- package/dist/src/components/skeleton/index.ts +9 -0
- package/dist/src/components/slider/Slider.astro +411 -0
- package/dist/src/components/slider/index.ts +9 -0
- package/dist/src/components/spinner/Spinner.astro +21 -0
- package/dist/src/components/spinner/index.ts +7 -0
- package/dist/src/components/switch/Switch.astro +192 -0
- package/dist/src/components/switch/SwitchTypes.ts +6 -0
- package/dist/src/components/switch/index.ts +12 -0
- package/dist/src/components/table/Table.astro +18 -0
- package/dist/src/components/table/TableBody.astro +16 -0
- package/dist/src/components/table/TableCaption.astro +16 -0
- package/dist/src/components/table/TableCell.astro +16 -0
- package/dist/src/components/table/TableFoot.astro +16 -0
- package/dist/src/components/table/TableHead.astro +16 -0
- package/dist/src/components/table/TableHeader.astro +16 -0
- package/dist/src/components/table/TableRow.astro +16 -0
- package/dist/src/components/table/index.ts +42 -0
- package/dist/src/components/tabs/Tabs.astro +271 -0
- package/dist/src/components/tabs/TabsContent.astro +28 -0
- package/dist/src/components/tabs/TabsList.astro +22 -0
- package/dist/src/components/tabs/TabsTrigger.astro +34 -0
- package/dist/src/components/tabs/index.ts +20 -0
- package/dist/src/components/textarea/Textarea.astro +29 -0
- package/dist/src/components/textarea/index.ts +9 -0
- package/dist/src/components/theme-toggle/ThemeToggle.astro +208 -0
- package/dist/src/components/theme-toggle/index.ts +7 -0
- package/dist/src/components/toast/ToastDescription.astro +21 -0
- package/dist/src/components/toast/ToastItem.astro +54 -0
- package/dist/src/components/toast/ToastTemplate.astro +25 -0
- package/dist/src/components/toast/ToastTitle.astro +57 -0
- package/dist/src/components/toast/Toaster.astro +982 -0
- package/dist/src/components/toast/index.ts +29 -0
- package/dist/src/components/toast/toast-manager.ts +216 -0
- package/dist/src/components/toggle/Toggle.astro +174 -0
- package/dist/src/components/toggle/ToggleTypes.ts +14 -0
- package/dist/src/components/toggle/index.ts +8 -0
- package/dist/src/components/tooltip/Tooltip.astro +282 -0
- package/dist/src/components/tooltip/TooltipContent.astro +89 -0
- package/dist/src/components/tooltip/TooltipTrigger.astro +10 -0
- package/dist/src/components/tooltip/index.ts +16 -0
- package/dist/src/components/video/Video.astro +120 -0
- package/dist/src/components/video/index.ts +9 -0
- package/package.json +1 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { PromiseOptions, PromiseStateOption, ToastOptions, Variant } from "./toast-manager";
|
|
2
|
+
import { toast } from "./toast-manager";
|
|
3
|
+
import ToastDescription from "./ToastDescription.astro";
|
|
4
|
+
import Toaster from "./Toaster.astro";
|
|
5
|
+
import ToastItem from "./ToastItem.astro";
|
|
6
|
+
import ToastTemplate from "./ToastTemplate.astro";
|
|
7
|
+
import ToastTitle from "./ToastTitle.astro";
|
|
8
|
+
|
|
9
|
+
export {
|
|
10
|
+
type PromiseOptions,
|
|
11
|
+
type PromiseStateOption,
|
|
12
|
+
toast,
|
|
13
|
+
ToastDescription,
|
|
14
|
+
Toaster,
|
|
15
|
+
ToastItem,
|
|
16
|
+
type ToastOptions,
|
|
17
|
+
ToastTemplate,
|
|
18
|
+
ToastTitle,
|
|
19
|
+
type Variant,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default {
|
|
23
|
+
Manager: toast,
|
|
24
|
+
Viewport: Toaster,
|
|
25
|
+
Item: ToastItem,
|
|
26
|
+
Title: ToastTitle,
|
|
27
|
+
Description: ToastDescription,
|
|
28
|
+
Template: ToastTemplate,
|
|
29
|
+
};
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Starwind Toast API
|
|
3
|
+
*
|
|
4
|
+
* A simple, framework-agnostic toast notification system.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { toast } from "@/components/starwind/toast";
|
|
9
|
+
*
|
|
10
|
+
* // Simple usage
|
|
11
|
+
* toast("Hello world");
|
|
12
|
+
* toast({ title: "Success", description: "Item saved" });
|
|
13
|
+
*
|
|
14
|
+
* // Variant shortcuts
|
|
15
|
+
* toast.success("Saved successfully");
|
|
16
|
+
* toast.error("Something went wrong");
|
|
17
|
+
* toast.warning("Please check your input");
|
|
18
|
+
* toast.info("New update available");
|
|
19
|
+
* toast.loading("Processing...");
|
|
20
|
+
*
|
|
21
|
+
* // Promise handling
|
|
22
|
+
* toast.promise(saveData(), {
|
|
23
|
+
* loading: "Saving...",
|
|
24
|
+
* success: "Saved!",
|
|
25
|
+
* error: "Failed to save",
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* // Management
|
|
29
|
+
* const id = toast("Processing...");
|
|
30
|
+
* toast.update(id, { title: "Almost done..." });
|
|
31
|
+
* toast.dismiss(id);
|
|
32
|
+
* toast.dismiss(); // dismiss all
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
export type Variant = "default" | "success" | "error" | "warning" | "info" | "loading";
|
|
37
|
+
|
|
38
|
+
export interface ToastOptions {
|
|
39
|
+
id?: string;
|
|
40
|
+
title?: string;
|
|
41
|
+
description?: string;
|
|
42
|
+
variant?: Variant;
|
|
43
|
+
/** Duration in ms. Set to 0 for infinite (no auto-dismiss). */
|
|
44
|
+
duration?: number;
|
|
45
|
+
/** Callback when toast close animation starts */
|
|
46
|
+
onClose?: () => void;
|
|
47
|
+
/** Callback when toast is removed from DOM */
|
|
48
|
+
onRemove?: () => void;
|
|
49
|
+
action?: {
|
|
50
|
+
label: string;
|
|
51
|
+
onClick: () => void;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface PromiseStateOption {
|
|
56
|
+
title?: string;
|
|
57
|
+
description?: string;
|
|
58
|
+
duration?: number;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export type PromiseStateValue<T> =
|
|
62
|
+
| string
|
|
63
|
+
| PromiseStateOption
|
|
64
|
+
| ((data: T) => string | PromiseStateOption);
|
|
65
|
+
|
|
66
|
+
export interface PromiseOptions<T, E = Error> {
|
|
67
|
+
loading: string | PromiseStateOption;
|
|
68
|
+
success: PromiseStateValue<T>;
|
|
69
|
+
error: PromiseStateValue<E>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
interface ToastManager {
|
|
73
|
+
add(options: ToastOptions): string;
|
|
74
|
+
update(id: string, options: Partial<ToastOptions>): void;
|
|
75
|
+
close(id: string): void;
|
|
76
|
+
closeAll(): void;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Get the toast manager instance from the window
|
|
81
|
+
*/
|
|
82
|
+
function getManager(): ToastManager | null {
|
|
83
|
+
if (typeof window === "undefined") return null;
|
|
84
|
+
return (window as any).__starwind__.toast as ToastManager | null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Normalize a string or options object to ToastOptions
|
|
89
|
+
*/
|
|
90
|
+
function normalizeOption<T>(
|
|
91
|
+
value: string | PromiseStateOption | ((data: T) => string | PromiseStateOption),
|
|
92
|
+
data?: T,
|
|
93
|
+
): Omit<ToastOptions, "variant"> {
|
|
94
|
+
const resolved = typeof value === "function" ? value(data as T) : value;
|
|
95
|
+
if (typeof resolved === "string") {
|
|
96
|
+
return { title: resolved };
|
|
97
|
+
}
|
|
98
|
+
return resolved;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Create a toast notification
|
|
103
|
+
*/
|
|
104
|
+
function createToast(
|
|
105
|
+
messageOrOptions: string | ToastOptions,
|
|
106
|
+
extraOptions?: Omit<ToastOptions, "title">,
|
|
107
|
+
): string {
|
|
108
|
+
let options: ToastOptions;
|
|
109
|
+
if (typeof messageOrOptions === "string") {
|
|
110
|
+
options = { title: messageOrOptions, ...extraOptions };
|
|
111
|
+
} else {
|
|
112
|
+
options = messageOrOptions;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const manager = getManager();
|
|
116
|
+
if (manager) {
|
|
117
|
+
return manager.add(options);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
console.warn("Toast: No Toaster found. Add <Toaster /> to your layout.");
|
|
121
|
+
return "";
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Create a toast with a specific variant
|
|
126
|
+
*/
|
|
127
|
+
function createVariantToast(
|
|
128
|
+
variant: Variant,
|
|
129
|
+
message: string,
|
|
130
|
+
options?: Omit<ToastOptions, "variant">,
|
|
131
|
+
): string {
|
|
132
|
+
return createToast({ ...options, title: message, variant });
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Toast API interface
|
|
137
|
+
*/
|
|
138
|
+
interface ToastAPI {
|
|
139
|
+
(message: string, options?: Omit<ToastOptions, "title">): string;
|
|
140
|
+
(options: ToastOptions): string;
|
|
141
|
+
success(message: string, options?: Omit<ToastOptions, "variant">): string;
|
|
142
|
+
error(message: string, options?: Omit<ToastOptions, "variant">): string;
|
|
143
|
+
warning(message: string, options?: Omit<ToastOptions, "variant">): string;
|
|
144
|
+
info(message: string, options?: Omit<ToastOptions, "variant">): string;
|
|
145
|
+
loading(message: string, options?: Omit<ToastOptions, "variant">): string;
|
|
146
|
+
promise<T, E = Error>(promise: Promise<T>, options: PromiseOptions<T, E>): Promise<T>;
|
|
147
|
+
update(id: string, options: Partial<ToastOptions>): void;
|
|
148
|
+
dismiss(id?: string): void;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Main toast function with variant methods attached
|
|
153
|
+
*/
|
|
154
|
+
const toast = createToast as ToastAPI;
|
|
155
|
+
|
|
156
|
+
toast.success = (message: string, options?: Omit<ToastOptions, "variant">) =>
|
|
157
|
+
createVariantToast("success", message, options);
|
|
158
|
+
|
|
159
|
+
toast.error = (message: string, options?: Omit<ToastOptions, "variant">) =>
|
|
160
|
+
createVariantToast("error", message, options);
|
|
161
|
+
|
|
162
|
+
toast.warning = (message: string, options?: Omit<ToastOptions, "variant">) =>
|
|
163
|
+
createVariantToast("warning", message, options);
|
|
164
|
+
|
|
165
|
+
toast.info = (message: string, options?: Omit<ToastOptions, "variant">) =>
|
|
166
|
+
createVariantToast("info", message, options);
|
|
167
|
+
|
|
168
|
+
toast.loading = (message: string, options?: Omit<ToastOptions, "variant">) =>
|
|
169
|
+
createVariantToast("loading", message, { ...options, duration: 0 });
|
|
170
|
+
|
|
171
|
+
toast.promise = async <T, E = Error>(
|
|
172
|
+
promise: Promise<T>,
|
|
173
|
+
options: PromiseOptions<T, E>,
|
|
174
|
+
): Promise<T> => {
|
|
175
|
+
const loadingOpts = normalizeOption(options.loading);
|
|
176
|
+
const id = createToast({
|
|
177
|
+
...loadingOpts,
|
|
178
|
+
variant: "loading",
|
|
179
|
+
duration: 0, // Don't auto-dismiss while loading
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
try {
|
|
183
|
+
const data = await promise;
|
|
184
|
+
const successOpts = normalizeOption(options.success, data);
|
|
185
|
+
toast.update(id, { ...successOpts, variant: "success" });
|
|
186
|
+
return data;
|
|
187
|
+
} catch (error) {
|
|
188
|
+
const errorOpts = normalizeOption(options.error, error as E);
|
|
189
|
+
toast.update(id, { ...errorOpts, variant: "error" });
|
|
190
|
+
throw error;
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
toast.update = (id: string, options: Partial<ToastOptions>): void => {
|
|
195
|
+
const manager = getManager();
|
|
196
|
+
if (manager) {
|
|
197
|
+
manager.update(id, options);
|
|
198
|
+
} else {
|
|
199
|
+
console.warn("Toast: No Toaster found. Add <Toaster /> to your layout.");
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
toast.dismiss = (id?: string): void => {
|
|
204
|
+
const manager = getManager();
|
|
205
|
+
if (!manager) {
|
|
206
|
+
// Can't dismiss if manager isn't ready
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
if (id) {
|
|
210
|
+
manager.close(id);
|
|
211
|
+
} else {
|
|
212
|
+
manager.closeAll();
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
export { toast };
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from "astro/types";
|
|
3
|
+
import { tv, type VariantProps } from "tailwind-variants";
|
|
4
|
+
|
|
5
|
+
export const toggle = tv({
|
|
6
|
+
base: [
|
|
7
|
+
"inline-flex items-center justify-center gap-2 rounded-md font-medium whitespace-nowrap",
|
|
8
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
9
|
+
"data-[state=on]:bg-accent data-[state=on]:text-accent-foreground",
|
|
10
|
+
"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
11
|
+
"focus-visible:border-outline focus-visible:ring-outline/50 focus-visible:ring-3",
|
|
12
|
+
"transition-colors outline-none",
|
|
13
|
+
"aria-invalid:ring-error/40 aria-invalid:border-error",
|
|
14
|
+
],
|
|
15
|
+
variants: {
|
|
16
|
+
variant: {
|
|
17
|
+
default: "hover:bg-muted hover:text-muted-foreground bg-transparent",
|
|
18
|
+
outline:
|
|
19
|
+
"border-input hover:bg-accent hover:text-accent-foreground border bg-transparent shadow-xs",
|
|
20
|
+
},
|
|
21
|
+
size: {
|
|
22
|
+
sm: "h-9 min-w-9 px-2 text-sm",
|
|
23
|
+
md: "h-11 min-w-11 px-2.5 text-base",
|
|
24
|
+
lg: "h-12 min-w-12 px-3 text-lg",
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
defaultVariants: {
|
|
28
|
+
variant: "default",
|
|
29
|
+
size: "md",
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
type Props = VariantProps<typeof toggle> &
|
|
34
|
+
HTMLAttributes<"button"> & {
|
|
35
|
+
/**
|
|
36
|
+
* The pressed state of the toggle when initially rendered
|
|
37
|
+
*/
|
|
38
|
+
defaultPressed?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Optional sync group name. When set, all toggles with the same sync group will mirror each other's state
|
|
41
|
+
*/
|
|
42
|
+
syncGroup?: string;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const { class: className, defaultPressed = false, syncGroup, variant, size, ...rest } = Astro.props;
|
|
46
|
+
|
|
47
|
+
const dataState = defaultPressed ? "on" : "off";
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
<button
|
|
51
|
+
type="button"
|
|
52
|
+
class={toggle({ variant, size, class: `starwind-toggle ${className || ""}` })}
|
|
53
|
+
data-slot="toggle"
|
|
54
|
+
data-state={dataState}
|
|
55
|
+
data-sync-group={syncGroup}
|
|
56
|
+
aria-pressed={defaultPressed}
|
|
57
|
+
{...rest}
|
|
58
|
+
>
|
|
59
|
+
<slot />
|
|
60
|
+
</button>
|
|
61
|
+
|
|
62
|
+
<script>
|
|
63
|
+
import type { ToggleChangeEvent, ToggleSyncEvent } from "./ToggleTypes";
|
|
64
|
+
|
|
65
|
+
class ToggleHandler {
|
|
66
|
+
private toggle: HTMLButtonElement;
|
|
67
|
+
private syncGroup?: string;
|
|
68
|
+
|
|
69
|
+
constructor(toggle: HTMLButtonElement, idx: number) {
|
|
70
|
+
this.toggle = toggle;
|
|
71
|
+
this.syncGroup = toggle.dataset.syncGroup;
|
|
72
|
+
|
|
73
|
+
if (!this.toggle.id) {
|
|
74
|
+
this.toggle.id = `starwind-toggle${idx}`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
this.setupEventListeners();
|
|
78
|
+
|
|
79
|
+
if (this.syncGroup) {
|
|
80
|
+
this.setupSyncListener();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private setupEventListeners(): void {
|
|
85
|
+
this.toggle.addEventListener("click", () => this.handleToggle());
|
|
86
|
+
this.toggle.addEventListener("keydown", (event) => this.handleKeyDown(event));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private setupSyncListener(): void {
|
|
90
|
+
if (!this.syncGroup) return;
|
|
91
|
+
|
|
92
|
+
document.addEventListener(`starwind-toggle-sync:${this.syncGroup}`, ((e: ToggleSyncEvent) => {
|
|
93
|
+
// Don't sync if this toggle triggered the event
|
|
94
|
+
if (e.detail.sourceId === this.toggle.id) return;
|
|
95
|
+
|
|
96
|
+
const newPressed = e.detail.pressed;
|
|
97
|
+
this.updateState(newPressed, false); // false = don't dispatch sync event
|
|
98
|
+
}) as EventListener);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
private handleToggle(): void {
|
|
102
|
+
if (this.isDisabled()) return;
|
|
103
|
+
|
|
104
|
+
const isPressed = this.toggle.getAttribute("aria-pressed") === "true";
|
|
105
|
+
const newPressed = !isPressed;
|
|
106
|
+
|
|
107
|
+
this.updateState(newPressed, true);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private handleKeyDown(event: KeyboardEvent): void {
|
|
111
|
+
if (this.isDisabled()) return;
|
|
112
|
+
|
|
113
|
+
if (event.key === " " || event.key === "Enter") {
|
|
114
|
+
event.preventDefault();
|
|
115
|
+
this.handleToggle();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
private isDisabled(): boolean {
|
|
120
|
+
return this.toggle.disabled;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private updateState(pressed: boolean, dispatchSync: boolean): void {
|
|
124
|
+
const newState = pressed ? "on" : "off";
|
|
125
|
+
|
|
126
|
+
this.toggle.setAttribute("aria-pressed", pressed.toString());
|
|
127
|
+
this.toggle.setAttribute("data-state", newState);
|
|
128
|
+
|
|
129
|
+
// Dispatch change event (always fired for user to listen to)
|
|
130
|
+
const changeEvent = new CustomEvent<ToggleChangeEvent["detail"]>("starwind-toggle:change", {
|
|
131
|
+
detail: {
|
|
132
|
+
pressed,
|
|
133
|
+
toggleId: this.toggle.id,
|
|
134
|
+
syncGroup: this.syncGroup,
|
|
135
|
+
},
|
|
136
|
+
bubbles: true,
|
|
137
|
+
cancelable: true,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
this.toggle.dispatchEvent(changeEvent);
|
|
141
|
+
|
|
142
|
+
// Dispatch sync event if in a sync group and requested
|
|
143
|
+
if (this.syncGroup && dispatchSync) {
|
|
144
|
+
const syncEvent = new CustomEvent<ToggleSyncEvent["detail"]>(
|
|
145
|
+
`starwind-toggle-sync:${this.syncGroup}`,
|
|
146
|
+
{
|
|
147
|
+
detail: {
|
|
148
|
+
pressed,
|
|
149
|
+
sourceId: this.toggle.id,
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
document.dispatchEvent(syncEvent);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Store instances in a WeakMap to avoid memory leaks
|
|
160
|
+
const toggleInstances = new WeakMap<HTMLElement, ToggleHandler>();
|
|
161
|
+
let toggleCounter = 0;
|
|
162
|
+
|
|
163
|
+
const setupToggles = () => {
|
|
164
|
+
document.querySelectorAll<HTMLButtonElement>(".starwind-toggle").forEach((toggle) => {
|
|
165
|
+
if (!toggleInstances.has(toggle)) {
|
|
166
|
+
toggleInstances.set(toggle, new ToggleHandler(toggle, toggleCounter++));
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
setupToggles();
|
|
172
|
+
document.addEventListener("astro:after-swap", setupToggles);
|
|
173
|
+
document.addEventListener("starwind:init", setupToggles);
|
|
174
|
+
</script>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ToggleChangeEvent extends CustomEvent {
|
|
2
|
+
detail: {
|
|
3
|
+
pressed: boolean;
|
|
4
|
+
toggleId: string;
|
|
5
|
+
syncGroup?: string;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface ToggleSyncEvent extends CustomEvent {
|
|
10
|
+
detail: {
|
|
11
|
+
pressed: boolean;
|
|
12
|
+
sourceId: string;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import Toggle, { toggle } from "./Toggle.astro";
|
|
2
|
+
import type { ToggleChangeEvent, ToggleSyncEvent } from "./ToggleTypes";
|
|
3
|
+
|
|
4
|
+
const ToggleVariants = { toggle };
|
|
5
|
+
|
|
6
|
+
export { Toggle, type ToggleChangeEvent, type ToggleSyncEvent, ToggleVariants };
|
|
7
|
+
|
|
8
|
+
export default Toggle;
|