@starwind-ui/core 1.11.2 → 1.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/dist/index.d.ts +0 -28
- package/dist/index.js +0 -74
- package/dist/index.js.map +0 -1
- package/dist/src/components/accordion/Accordion.astro +0 -247
- package/dist/src/components/accordion/AccordionContent.astro +0 -33
- package/dist/src/components/accordion/AccordionItem.astro +0 -27
- package/dist/src/components/accordion/AccordionTrigger.astro +0 -32
- package/dist/src/components/accordion/index.ts +0 -15
- package/dist/src/components/alert/Alert.astro +0 -31
- package/dist/src/components/alert/AlertDescription.astro +0 -14
- package/dist/src/components/alert/AlertTitle.astro +0 -16
- package/dist/src/components/alert/index.ts +0 -13
- package/dist/src/components/alert-dialog/AlertDialog.astro +0 -273
- package/dist/src/components/alert-dialog/AlertDialogAction.astro +0 -44
- package/dist/src/components/alert-dialog/AlertDialogCancel.astro +0 -45
- package/dist/src/components/alert-dialog/AlertDialogContent.astro +0 -52
- package/dist/src/components/alert-dialog/AlertDialogDescription.astro +0 -18
- package/dist/src/components/alert-dialog/AlertDialogFooter.astro +0 -16
- package/dist/src/components/alert-dialog/AlertDialogHeader.astro +0 -14
- package/dist/src/components/alert-dialog/AlertDialogTitle.astro +0 -20
- package/dist/src/components/alert-dialog/AlertDialogTrigger.astro +0 -47
- package/dist/src/components/alert-dialog/index.ts +0 -46
- package/dist/src/components/aspect-ratio/AspectRatio.astro +0 -32
- package/dist/src/components/aspect-ratio/index.ts +0 -7
- package/dist/src/components/avatar/Avatar.astro +0 -29
- package/dist/src/components/avatar/AvatarFallback.astro +0 -18
- package/dist/src/components/avatar/AvatarImage.astro +0 -49
- package/dist/src/components/avatar/index.ts +0 -13
- package/dist/src/components/badge/Badge.astro +0 -51
- package/dist/src/components/badge/index.ts +0 -7
- package/dist/src/components/breadcrumb/Breadcrumb.astro +0 -11
- package/dist/src/components/breadcrumb/BreadcrumbEllipsis.astro +0 -28
- package/dist/src/components/breadcrumb/BreadcrumbItem.astro +0 -14
- package/dist/src/components/breadcrumb/BreadcrumbLink.astro +0 -22
- package/dist/src/components/breadcrumb/BreadcrumbList.astro +0 -16
- package/dist/src/components/breadcrumb/BreadcrumbPage.astro +0 -21
- package/dist/src/components/breadcrumb/BreadcrumbSeparator.astro +0 -23
- package/dist/src/components/breadcrumb/index.ts +0 -37
- package/dist/src/components/button/Button.astro +0 -53
- package/dist/src/components/button/index.ts +0 -7
- package/dist/src/components/card/Card.astro +0 -14
- package/dist/src/components/card/CardContent.astro +0 -14
- package/dist/src/components/card/CardDescription.astro +0 -14
- package/dist/src/components/card/CardFooter.astro +0 -14
- package/dist/src/components/card/CardHeader.astro +0 -14
- package/dist/src/components/card/CardTitle.astro +0 -14
- package/dist/src/components/card/index.ts +0 -26
- package/dist/src/components/carousel/Carousel.astro +0 -55
- package/dist/src/components/carousel/CarouselContent.astro +0 -26
- package/dist/src/components/carousel/CarouselItem.astro +0 -26
- package/dist/src/components/carousel/CarouselNext.astro +0 -37
- package/dist/src/components/carousel/CarouselPrevious.astro +0 -37
- package/dist/src/components/carousel/carousel-script.ts +0 -191
- package/dist/src/components/carousel/index.ts +0 -32
- package/dist/src/components/checkbox/Checkbox.astro +0 -127
- package/dist/src/components/checkbox/index.ts +0 -7
- package/dist/src/components/dialog/Dialog.astro +0 -263
- package/dist/src/components/dialog/DialogClose.astro +0 -35
- package/dist/src/components/dialog/DialogContent.astro +0 -67
- package/dist/src/components/dialog/DialogDescription.astro +0 -14
- package/dist/src/components/dialog/DialogFooter.astro +0 -14
- package/dist/src/components/dialog/DialogHeader.astro +0 -14
- package/dist/src/components/dialog/DialogTitle.astro +0 -20
- package/dist/src/components/dialog/DialogTrigger.astro +0 -47
- package/dist/src/components/dialog/index.ts +0 -45
- package/dist/src/components/dropdown/Dropdown.astro +0 -375
- package/dist/src/components/dropdown/DropdownContent.astro +0 -81
- package/dist/src/components/dropdown/DropdownItem.astro +0 -48
- package/dist/src/components/dropdown/DropdownLabel.astro +0 -29
- package/dist/src/components/dropdown/DropdownSeparator.astro +0 -21
- package/dist/src/components/dropdown/DropdownTrigger.astro +0 -52
- package/dist/src/components/dropdown/index.ts +0 -33
- package/dist/src/components/dropzone/Dropzone.astro +0 -233
- package/dist/src/components/dropzone/DropzoneFilesList.astro +0 -26
- package/dist/src/components/dropzone/DropzoneLoadingIndicator.astro +0 -10
- package/dist/src/components/dropzone/DropzoneUploadIndicator.astro +0 -10
- package/dist/src/components/dropzone/index.ts +0 -24
- package/dist/src/components/input/Input.astro +0 -24
- package/dist/src/components/input/index.ts +0 -7
- package/dist/src/components/item/Item.astro +0 -52
- package/dist/src/components/item/ItemActions.astro +0 -16
- package/dist/src/components/item/ItemContent.astro +0 -16
- package/dist/src/components/item/ItemDescription.astro +0 -19
- package/dist/src/components/item/ItemFooter.astro +0 -16
- package/dist/src/components/item/ItemGroup.astro +0 -16
- package/dist/src/components/item/ItemHeader.astro +0 -16
- package/dist/src/components/item/ItemMedia.astro +0 -40
- package/dist/src/components/item/ItemSeparator.astro +0 -21
- package/dist/src/components/item/ItemTitle.astro +0 -16
- package/dist/src/components/item/index.ts +0 -50
- package/dist/src/components/kbd/Kbd.astro +0 -21
- package/dist/src/components/kbd/KbdGroup.astro +0 -16
- package/dist/src/components/kbd/index.ts +0 -11
- package/dist/src/components/label/Label.astro +0 -22
- package/dist/src/components/label/index.ts +0 -7
- package/dist/src/components/pagination/Pagination.astro +0 -20
- package/dist/src/components/pagination/PaginationContent.astro +0 -16
- package/dist/src/components/pagination/PaginationEllipsis.astro +0 -25
- package/dist/src/components/pagination/PaginationItem.astro +0 -16
- package/dist/src/components/pagination/PaginationLink.astro +0 -24
- package/dist/src/components/pagination/PaginationNext.astro +0 -26
- package/dist/src/components/pagination/PaginationPrevious.astro +0 -26
- package/dist/src/components/pagination/index.ts +0 -38
- package/dist/src/components/progress/Progress.astro +0 -154
- package/dist/src/components/progress/index.ts +0 -10
- package/dist/src/components/radio-group/RadioGroup.astro +0 -157
- package/dist/src/components/radio-group/RadioGroupItem.astro +0 -129
- package/dist/src/components/radio-group/RadioGroupTypes.ts +0 -6
- package/dist/src/components/radio-group/index.ts +0 -23
- package/dist/src/components/select/Select.astro +0 -534
- package/dist/src/components/select/SelectContent.astro +0 -83
- package/dist/src/components/select/SelectGroup.astro +0 -9
- package/dist/src/components/select/SelectItem.astro +0 -49
- package/dist/src/components/select/SelectLabel.astro +0 -14
- package/dist/src/components/select/SelectSeparator.astro +0 -12
- package/dist/src/components/select/SelectTrigger.astro +0 -48
- package/dist/src/components/select/SelectTypes.ts +0 -13
- package/dist/src/components/select/SelectValue.astro +0 -19
- package/dist/src/components/select/index.ts +0 -45
- package/dist/src/components/separator/Separator.astro +0 -36
- package/dist/src/components/separator/index.ts +0 -7
- package/dist/src/components/sheet/Sheet.astro +0 -13
- package/dist/src/components/sheet/SheetClose.astro +0 -13
- package/dist/src/components/sheet/SheetContent.astro +0 -92
- package/dist/src/components/sheet/SheetDescription.astro +0 -16
- package/dist/src/components/sheet/SheetFooter.astro +0 -16
- package/dist/src/components/sheet/SheetHeader.astro +0 -16
- package/dist/src/components/sheet/SheetTitle.astro +0 -16
- package/dist/src/components/sheet/SheetTrigger.astro +0 -13
- package/dist/src/components/sheet/index.ts +0 -41
- package/dist/src/components/skeleton/Skeleton.astro +0 -14
- package/dist/src/components/skeleton/index.ts +0 -9
- package/dist/src/components/spinner/Spinner.astro +0 -21
- package/dist/src/components/spinner/index.ts +0 -7
- package/dist/src/components/switch/Switch.astro +0 -191
- package/dist/src/components/switch/SwitchTypes.ts +0 -6
- package/dist/src/components/switch/index.ts +0 -12
- package/dist/src/components/table/Table.astro +0 -18
- package/dist/src/components/table/TableBody.astro +0 -16
- package/dist/src/components/table/TableCaption.astro +0 -16
- package/dist/src/components/table/TableCell.astro +0 -16
- package/dist/src/components/table/TableFoot.astro +0 -16
- package/dist/src/components/table/TableHead.astro +0 -16
- package/dist/src/components/table/TableHeader.astro +0 -16
- package/dist/src/components/table/TableRow.astro +0 -16
- package/dist/src/components/table/index.ts +0 -42
- package/dist/src/components/tabs/Tabs.astro +0 -269
- package/dist/src/components/tabs/TabsContent.astro +0 -28
- package/dist/src/components/tabs/TabsList.astro +0 -22
- package/dist/src/components/tabs/TabsTrigger.astro +0 -34
- package/dist/src/components/tabs/index.ts +0 -20
- package/dist/src/components/textarea/Textarea.astro +0 -28
- package/dist/src/components/textarea/index.ts +0 -9
- package/dist/src/components/tooltip/Tooltip.astro +0 -237
- package/dist/src/components/tooltip/TooltipContent.astro +0 -114
- package/dist/src/components/tooltip/TooltipTrigger.astro +0 -10
- package/dist/src/components/tooltip/index.ts +0 -16
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLTag, Polymorphic } from "astro/types";
|
|
3
|
-
import { tv } from "tailwind-variants";
|
|
4
|
-
|
|
5
|
-
type Props<Tag extends HTMLTag> = Polymorphic<{ as: Tag }> & {
|
|
6
|
-
/**
|
|
7
|
-
* Whether the item is inset (has left padding)
|
|
8
|
-
*/
|
|
9
|
-
inset?: boolean;
|
|
10
|
-
/**
|
|
11
|
-
* Whether the item is disabled
|
|
12
|
-
*/
|
|
13
|
-
disabled?: boolean;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export const dropdownItem = tv({
|
|
17
|
-
base: [
|
|
18
|
-
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 transition-colors outline-none select-none",
|
|
19
|
-
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
20
|
-
"[&>svg]:size-4 [&>svg]:shrink-0",
|
|
21
|
-
],
|
|
22
|
-
variants: {
|
|
23
|
-
inset: {
|
|
24
|
-
true: "pl-8",
|
|
25
|
-
},
|
|
26
|
-
disabled: {
|
|
27
|
-
true: "pointer-events-none opacity-50",
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
defaultVariants: {
|
|
31
|
-
inset: false,
|
|
32
|
-
disabled: false,
|
|
33
|
-
},
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
const { class: className, inset = false, disabled = false, as: Tag = "div", ...rest } = Astro.props;
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
<Tag
|
|
40
|
-
class={dropdownItem({ inset, disabled, class: className })}
|
|
41
|
-
role="menuitem"
|
|
42
|
-
tabindex={disabled ? "-1" : "0"}
|
|
43
|
-
data-disabled={disabled ? "true" : undefined}
|
|
44
|
-
data-slot="dropdown-item"
|
|
45
|
-
{...rest}
|
|
46
|
-
>
|
|
47
|
-
<slot />
|
|
48
|
-
</Tag>
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
import { tv } from "tailwind-variants";
|
|
4
|
-
|
|
5
|
-
type Props = HTMLAttributes<"div"> & {
|
|
6
|
-
/**
|
|
7
|
-
* Whether the label is inset (has left padding)
|
|
8
|
-
*/
|
|
9
|
-
inset?: boolean;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export const dropdownLabel = tv({
|
|
13
|
-
base: ["px-2 py-1.5 font-semibold"],
|
|
14
|
-
variants: {
|
|
15
|
-
inset: {
|
|
16
|
-
true: "pl-8",
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
defaultVariants: {
|
|
20
|
-
inset: false,
|
|
21
|
-
},
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
const { class: className, inset = false, ...rest } = Astro.props;
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
<div class={dropdownLabel({ inset, class: className })} data-slot="dropdown-label" {...rest}>
|
|
28
|
-
<slot />
|
|
29
|
-
</div>
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
import { tv } from "tailwind-variants";
|
|
4
|
-
|
|
5
|
-
type Props = HTMLAttributes<"div">;
|
|
6
|
-
|
|
7
|
-
export const dropdownSeparator = tv({
|
|
8
|
-
base: "bg-border -mx-1 my-1 h-px",
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
const { class: className, ...rest } = Astro.props;
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
<div
|
|
15
|
-
class={dropdownSeparator({ class: className })}
|
|
16
|
-
role="separator"
|
|
17
|
-
aria-orientation="horizontal"
|
|
18
|
-
data-slot="dropdown-separator"
|
|
19
|
-
{...rest}
|
|
20
|
-
>
|
|
21
|
-
</div>
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
import { tv } from "tailwind-variants";
|
|
4
|
-
|
|
5
|
-
type Props = Omit<HTMLAttributes<"button">, "role" | "type"> & {
|
|
6
|
-
/**
|
|
7
|
-
* When true, the component will render its child element with a simple wrapper instead of a button component
|
|
8
|
-
*/
|
|
9
|
-
asChild?: boolean;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export const dropdownTrigger = tv({
|
|
13
|
-
base: [
|
|
14
|
-
"starwind-dropdown-trigger",
|
|
15
|
-
"inline-flex items-center justify-center",
|
|
16
|
-
"focus-visible:ring-outline/50 transition-[color,box-shadow] outline-none focus-visible:ring-3",
|
|
17
|
-
"disabled:pointer-events-none",
|
|
18
|
-
],
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
const { class: className, asChild = false, ...rest } = Astro.props;
|
|
22
|
-
|
|
23
|
-
// Get the first child element if asChild is true
|
|
24
|
-
let hasChildren = false;
|
|
25
|
-
if (Astro.slots.has("default")) {
|
|
26
|
-
hasChildren = true;
|
|
27
|
-
}
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
{
|
|
31
|
-
asChild && hasChildren ? (
|
|
32
|
-
<div
|
|
33
|
-
class={`starwind-dropdown-trigger ${className}`}
|
|
34
|
-
data-slot="dropdown-trigger"
|
|
35
|
-
data-as-child
|
|
36
|
-
>
|
|
37
|
-
<slot />
|
|
38
|
-
</div>
|
|
39
|
-
) : (
|
|
40
|
-
<button
|
|
41
|
-
class={dropdownTrigger({ class: className })}
|
|
42
|
-
type="button"
|
|
43
|
-
aria-haspopup="true"
|
|
44
|
-
aria-expanded="false"
|
|
45
|
-
data-state="closed"
|
|
46
|
-
data-slot="dropdown-trigger"
|
|
47
|
-
{...rest}
|
|
48
|
-
>
|
|
49
|
-
<slot />
|
|
50
|
-
</button>
|
|
51
|
-
)
|
|
52
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import Dropdown from "./Dropdown.astro";
|
|
2
|
-
import DropdownContent, { dropdownContent } from "./DropdownContent.astro";
|
|
3
|
-
import DropdownItem, { dropdownItem } from "./DropdownItem.astro";
|
|
4
|
-
import DropdownLabel, { dropdownLabel } from "./DropdownLabel.astro";
|
|
5
|
-
import DropdownSeparator, { dropdownSeparator } from "./DropdownSeparator.astro";
|
|
6
|
-
import DropdownTrigger, { dropdownTrigger } from "./DropdownTrigger.astro";
|
|
7
|
-
|
|
8
|
-
const DropdownVariants = {
|
|
9
|
-
dropdownContent,
|
|
10
|
-
dropdownItem,
|
|
11
|
-
dropdownLabel,
|
|
12
|
-
dropdownSeparator,
|
|
13
|
-
dropdownTrigger,
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export {
|
|
17
|
-
Dropdown,
|
|
18
|
-
DropdownContent,
|
|
19
|
-
DropdownItem,
|
|
20
|
-
DropdownLabel,
|
|
21
|
-
DropdownSeparator,
|
|
22
|
-
DropdownTrigger,
|
|
23
|
-
DropdownVariants,
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export default {
|
|
27
|
-
Root: Dropdown,
|
|
28
|
-
Trigger: DropdownTrigger,
|
|
29
|
-
Content: DropdownContent,
|
|
30
|
-
Item: DropdownItem,
|
|
31
|
-
Label: DropdownLabel,
|
|
32
|
-
Separator: DropdownSeparator,
|
|
33
|
-
};
|
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
import { tv } from "tailwind-variants";
|
|
4
|
-
|
|
5
|
-
import DropzoneFilesList from "./DropzoneFilesList.astro";
|
|
6
|
-
import DropzoneLoadingIndicator from "./DropzoneLoadingIndicator.astro";
|
|
7
|
-
import DropzoneUploadIndicator from "./DropzoneUploadIndicator.astro";
|
|
8
|
-
|
|
9
|
-
type Props = HTMLAttributes<"input"> & {
|
|
10
|
-
/**
|
|
11
|
-
* Whether to show the loading indicator initially
|
|
12
|
-
*/
|
|
13
|
-
isUploading?: boolean;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
// extract id separately so it can be used in the label. The input will get the same id with "-input" suffix.
|
|
17
|
-
const { class: className, id, isUploading = false, ...rest } = Astro.props as Props;
|
|
18
|
-
|
|
19
|
-
export const dropzone = tv({
|
|
20
|
-
base: [
|
|
21
|
-
"starwind-dropzone",
|
|
22
|
-
"relative flex w-full flex-col items-center justify-center gap-1 rounded-lg px-6 py-12 shadow-xs",
|
|
23
|
-
"bg-background dark:bg-input/30 text-muted-foreground border-input cursor-pointer border border-dashed text-center text-sm",
|
|
24
|
-
"data-[is-uploading=false]:hover:bg-muted/50 data-[drag-active=true]:bg-muted/50 transition",
|
|
25
|
-
"focus-visible:border-outline focus-visible:ring-outline/50 outline-none focus-visible:ring-3",
|
|
26
|
-
],
|
|
27
|
-
});
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
<label
|
|
31
|
-
id={id}
|
|
32
|
-
tabindex="0"
|
|
33
|
-
class={dropzone({ class: className })}
|
|
34
|
-
data-slot="dropzone"
|
|
35
|
-
data-drag-active="false"
|
|
36
|
-
data-has-files="false"
|
|
37
|
-
data-is-uploading={String(isUploading)}
|
|
38
|
-
>
|
|
39
|
-
<slot>
|
|
40
|
-
<DropzoneUploadIndicator />
|
|
41
|
-
<DropzoneLoadingIndicator />
|
|
42
|
-
<DropzoneFilesList />
|
|
43
|
-
</slot>
|
|
44
|
-
|
|
45
|
-
<input tabindex="-1" type="file" class="sr-only" {...rest} />
|
|
46
|
-
</label>
|
|
47
|
-
|
|
48
|
-
<script>
|
|
49
|
-
const fileSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-file"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M14 3v4a1 1 0 0 0 1 1h4" /><path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z" /></svg>`;
|
|
50
|
-
class FileInputHandler {
|
|
51
|
-
private label: HTMLLabelElement;
|
|
52
|
-
private input: HTMLInputElement;
|
|
53
|
-
private uploadIndicator: HTMLElement | null;
|
|
54
|
-
private loadingIndicator: HTMLElement | null;
|
|
55
|
-
private filesList: HTMLElement | null;
|
|
56
|
-
private files: File[] = [];
|
|
57
|
-
private hasFiles: boolean = false;
|
|
58
|
-
private isUploading: boolean = false;
|
|
59
|
-
private observer: MutationObserver | null = null;
|
|
60
|
-
|
|
61
|
-
constructor(label: HTMLLabelElement, idx: number) {
|
|
62
|
-
this.label = label;
|
|
63
|
-
const maybeInput = label.querySelector<HTMLInputElement>('input[type="file"]');
|
|
64
|
-
if (!maybeInput) {
|
|
65
|
-
throw new Error("No file input found inside starwind-dropzone");
|
|
66
|
-
}
|
|
67
|
-
this.input = maybeInput;
|
|
68
|
-
this.uploadIndicator = label.querySelector(".starwind-upload-indicator");
|
|
69
|
-
this.loadingIndicator = label.querySelector(".starwind-loading-indicator");
|
|
70
|
-
this.filesList = label.querySelector(".starwind-files-list");
|
|
71
|
-
|
|
72
|
-
// generate ID
|
|
73
|
-
if (this.label.id) {
|
|
74
|
-
const inputId = this.label.id + "-input";
|
|
75
|
-
this.input.id = inputId;
|
|
76
|
-
this.label.htmlFor = inputId;
|
|
77
|
-
} else {
|
|
78
|
-
const generatedId = `starwind-dropzone-${idx}`;
|
|
79
|
-
this.input.id = generatedId;
|
|
80
|
-
this.label.htmlFor = generatedId;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Setup event handlers
|
|
84
|
-
this.setupEvents();
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
private setActive(active: boolean) {
|
|
88
|
-
this.label.dataset.dragActive = String(active);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Set up mutation observer to watch for external attribute changes
|
|
92
|
-
private observeAttributeChanges() {
|
|
93
|
-
this.observer = new MutationObserver((mutations) => {
|
|
94
|
-
mutations.forEach((mutation) => {
|
|
95
|
-
if (mutation.type === "attributes" && mutation.attributeName === "data-is-uploading") {
|
|
96
|
-
this.handleAttributeChange();
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
this.observer.observe(this.label, {
|
|
102
|
-
attributes: true,
|
|
103
|
-
attributeFilter: ["data-is-uploading"],
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Handle attribute changes from external sources
|
|
108
|
-
private handleAttributeChange() {
|
|
109
|
-
const isUploading = this.label.dataset.isUploading === "true";
|
|
110
|
-
|
|
111
|
-
// Only update internal state if it's different
|
|
112
|
-
if (isUploading !== this.isUploading) {
|
|
113
|
-
this.isUploading = isUploading;
|
|
114
|
-
|
|
115
|
-
// Update UI
|
|
116
|
-
if (this.uploadIndicator && this.loadingIndicator) {
|
|
117
|
-
if (isUploading) {
|
|
118
|
-
this.uploadIndicator.classList.add("hidden");
|
|
119
|
-
this.loadingIndicator.classList.remove("hidden");
|
|
120
|
-
} else {
|
|
121
|
-
this.loadingIndicator.classList.add("hidden");
|
|
122
|
-
this.uploadIndicator.classList.remove("hidden");
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
private updateFilesList() {
|
|
129
|
-
if (!this.filesList) return;
|
|
130
|
-
|
|
131
|
-
const hasFiles = this.files.length > 0;
|
|
132
|
-
this.label.dataset.hasFiles = String(hasFiles);
|
|
133
|
-
|
|
134
|
-
if (hasFiles) {
|
|
135
|
-
this.filesList.classList.remove("invisible");
|
|
136
|
-
|
|
137
|
-
// Clear previous files
|
|
138
|
-
this.filesList.innerHTML = "";
|
|
139
|
-
|
|
140
|
-
// Create file list
|
|
141
|
-
this.files.forEach((file) => {
|
|
142
|
-
const fileItem = document.createElement("div");
|
|
143
|
-
|
|
144
|
-
// Insert SVG directly
|
|
145
|
-
fileItem.innerHTML = fileSvg;
|
|
146
|
-
|
|
147
|
-
const fileText = document.createElement("span");
|
|
148
|
-
fileText.textContent = file.name;
|
|
149
|
-
|
|
150
|
-
// Append text after the SVG
|
|
151
|
-
fileItem.appendChild(fileText);
|
|
152
|
-
|
|
153
|
-
// Use non-null assertion since we already checked at the beginning of the method
|
|
154
|
-
this.filesList!.appendChild(fileItem);
|
|
155
|
-
});
|
|
156
|
-
} else {
|
|
157
|
-
this.filesList.classList.add("invisible");
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
private handleFiles(files: FileList | null) {
|
|
162
|
-
if (!files || files.length === 0) return;
|
|
163
|
-
|
|
164
|
-
this.files = Array.from(files);
|
|
165
|
-
this.updateFilesList();
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
private setupEvents() {
|
|
169
|
-
this.label.addEventListener("dragover", (e) => {
|
|
170
|
-
e.preventDefault();
|
|
171
|
-
this.setActive(true);
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
this.label.addEventListener("dragleave", () => {
|
|
175
|
-
this.setActive(false);
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
this.label.addEventListener("drop", (e) => {
|
|
179
|
-
e.preventDefault();
|
|
180
|
-
this.setActive(false);
|
|
181
|
-
|
|
182
|
-
const { files } = e.dataTransfer || {};
|
|
183
|
-
if (files && files.length) {
|
|
184
|
-
const dt = new DataTransfer();
|
|
185
|
-
Array.from(files).forEach((file) => dt.items.add(file));
|
|
186
|
-
this.input.files = dt.files;
|
|
187
|
-
this.input.dispatchEvent(new Event("change", { bubbles: true }));
|
|
188
|
-
|
|
189
|
-
this.handleFiles(files);
|
|
190
|
-
}
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
// Handle file selection from dialog
|
|
194
|
-
this.input.addEventListener("change", () => {
|
|
195
|
-
this.handleFiles(this.input.files);
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
// Add keyboard accessibility for Enter and Space keys
|
|
199
|
-
this.label.addEventListener("keydown", (e) => {
|
|
200
|
-
// Handle Enter (13) and Space (32) keys
|
|
201
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
202
|
-
e.preventDefault();
|
|
203
|
-
this.input.click(); // Trigger the native file dialog
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
if (this.loadingIndicator) {
|
|
208
|
-
// Watch for external changes to data-is-uploading attribute
|
|
209
|
-
this.observeAttributeChanges();
|
|
210
|
-
// Initialize based on current attribute values
|
|
211
|
-
this.handleAttributeChange();
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// Store instances in a WeakMap to avoid memory leaks
|
|
217
|
-
const fileInputInstances = new WeakMap<HTMLElement, FileInputHandler>();
|
|
218
|
-
|
|
219
|
-
const setupFileInputs = () => {
|
|
220
|
-
document.querySelectorAll<HTMLLabelElement>(".starwind-dropzone").forEach((label, idx) => {
|
|
221
|
-
if (!fileInputInstances.has(label)) {
|
|
222
|
-
try {
|
|
223
|
-
fileInputInstances.set(label, new FileInputHandler(label, idx));
|
|
224
|
-
} catch {
|
|
225
|
-
/* ignore labels without inputs */
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
});
|
|
229
|
-
};
|
|
230
|
-
|
|
231
|
-
setupFileInputs();
|
|
232
|
-
document.addEventListener("astro:after-swap", setupFileInputs);
|
|
233
|
-
</script>
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
import { tv } from "tailwind-variants";
|
|
4
|
-
|
|
5
|
-
type Props = HTMLAttributes<"div">;
|
|
6
|
-
|
|
7
|
-
const { class: className, ...rest } = Astro.props;
|
|
8
|
-
|
|
9
|
-
export const dropzoneFilesList = tv({
|
|
10
|
-
base: [
|
|
11
|
-
"starwind-files-list",
|
|
12
|
-
"mt-1 -mb-8 min-h-8",
|
|
13
|
-
"bg-muted invisible flex flex-col items-center justify-center gap-1 rounded-md px-2 py-1 text-sm",
|
|
14
|
-
"[&_div]:flex [&_div]:items-center [&_div]:gap-1 [&_svg]:size-3.5",
|
|
15
|
-
],
|
|
16
|
-
});
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
<div
|
|
20
|
-
class={dropzoneFilesList({ class: className })}
|
|
21
|
-
aria-live="polite"
|
|
22
|
-
aria-label="Uploaded files"
|
|
23
|
-
data-slot="dropzone-files-list"
|
|
24
|
-
{...rest}
|
|
25
|
-
>
|
|
26
|
-
</div>
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import LoaderIcon from "@tabler/icons/outline/loader-2.svg";
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
<div class="starwind-loading-indicator hidden" data-slot="dropzone-loading-indicator">
|
|
6
|
-
<slot>
|
|
7
|
-
<LoaderIcon class="mx-auto size-10 animate-spin" aria-hidden="true" />
|
|
8
|
-
<p class="mt-1 text-sm">Uploading file(s)...</p>
|
|
9
|
-
</slot>
|
|
10
|
-
</div>
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import CloudUploadIcon from "@tabler/icons/outline/cloud-upload.svg";
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
<div class="starwind-upload-indicator" data-slot="dropzone-upload-indicator">
|
|
6
|
-
<slot>
|
|
7
|
-
<CloudUploadIcon class="mx-auto size-10" aria-hidden="true" />
|
|
8
|
-
<p class="mt-1 text-sm">Click to upload or drag and drop</p>
|
|
9
|
-
</slot>
|
|
10
|
-
</div>
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import Dropzone, { dropzone } from "./Dropzone.astro";
|
|
2
|
-
import DropzoneFilesList, { dropzoneFilesList } from "./DropzoneFilesList.astro";
|
|
3
|
-
import DropzoneLoadingIndicator from "./DropzoneLoadingIndicator.astro";
|
|
4
|
-
import DropzoneUploadIndicator from "./DropzoneUploadIndicator.astro";
|
|
5
|
-
|
|
6
|
-
const DropzoneVariants = {
|
|
7
|
-
dropzone,
|
|
8
|
-
dropzoneFilesList,
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export {
|
|
12
|
-
Dropzone,
|
|
13
|
-
DropzoneFilesList,
|
|
14
|
-
DropzoneLoadingIndicator,
|
|
15
|
-
DropzoneUploadIndicator,
|
|
16
|
-
DropzoneVariants,
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export default {
|
|
20
|
-
Root: Dropzone,
|
|
21
|
-
FilesList: DropzoneFilesList,
|
|
22
|
-
UploadIndicator: DropzoneUploadIndicator,
|
|
23
|
-
LoadingIndicator: DropzoneLoadingIndicator,
|
|
24
|
-
};
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
import { tv, type VariantProps } from "tailwind-variants";
|
|
4
|
-
|
|
5
|
-
type Props = HTMLAttributes<"input"> & VariantProps<typeof input>;
|
|
6
|
-
|
|
7
|
-
export const input = tv({
|
|
8
|
-
base: [
|
|
9
|
-
"border-input dark:bg-input/30 text-foreground w-full rounded-md border bg-transparent shadow-xs",
|
|
10
|
-
"focus-visible:border-outline focus-visible:ring-outline/50 transition-[color,box-shadow] focus-visible:ring-3",
|
|
11
|
-
"file:text-foreground file:my-auto file:mr-4 file:h-full file:border-0 file:bg-transparent file:text-sm file:font-medium",
|
|
12
|
-
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
13
|
-
"peer placeholder:text-muted-foreground",
|
|
14
|
-
],
|
|
15
|
-
variants: {
|
|
16
|
-
size: { sm: "h-9 px-2 text-sm", md: "h-11 px-3 text-base", lg: "h-12 px-4 text-lg" },
|
|
17
|
-
},
|
|
18
|
-
defaultVariants: { size: "md" },
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
const { size, class: className, ...rest } = Astro.props;
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
<input class={input({ size, class: className })} data-slot="input" {...rest} />
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLTag, Polymorphic } from "astro/types";
|
|
3
|
-
import { tv } from "tailwind-variants";
|
|
4
|
-
|
|
5
|
-
type Props<Tag extends HTMLTag> = Polymorphic<{ as: Tag }> & {
|
|
6
|
-
/**
|
|
7
|
-
* Variant of the item
|
|
8
|
-
* @default "default"
|
|
9
|
-
*/
|
|
10
|
-
variant?: "default" | "outline" | "muted";
|
|
11
|
-
/**
|
|
12
|
-
* Size of the item
|
|
13
|
-
* @default "default"
|
|
14
|
-
*/
|
|
15
|
-
size?: "default" | "sm";
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export const item = tv({
|
|
19
|
-
base: [
|
|
20
|
-
"group/item flex flex-wrap items-center rounded-md border border-transparent text-sm transition-colors",
|
|
21
|
-
"[a]:hover:bg-accent/50 [a]:transition-colors",
|
|
22
|
-
"focus-visible:border-ring focus-visible:ring-outline/50 outline-none focus-visible:ring-[3px]",
|
|
23
|
-
],
|
|
24
|
-
variants: {
|
|
25
|
-
variant: {
|
|
26
|
-
default: "bg-transparent",
|
|
27
|
-
outline: "border-border",
|
|
28
|
-
muted: "bg-muted/50",
|
|
29
|
-
},
|
|
30
|
-
size: {
|
|
31
|
-
default: "gap-4 p-4",
|
|
32
|
-
sm: "gap-2.5 px-4 py-3",
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
defaultVariants: {
|
|
36
|
-
variant: "default",
|
|
37
|
-
size: "default",
|
|
38
|
-
},
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
const {
|
|
42
|
-
variant = "default",
|
|
43
|
-
size = "default",
|
|
44
|
-
class: className,
|
|
45
|
-
as: Tag = "div",
|
|
46
|
-
...rest
|
|
47
|
-
} = Astro.props;
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
<Tag class={item({ variant, size, class: className })} data-slot="item" {...rest}>
|
|
51
|
-
<slot />
|
|
52
|
-
</Tag>
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
import { tv } from "tailwind-variants";
|
|
4
|
-
|
|
5
|
-
type Props = HTMLAttributes<"div">;
|
|
6
|
-
|
|
7
|
-
export const itemActions = tv({
|
|
8
|
-
base: "flex items-center gap-2",
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
const { class: className, ...rest } = Astro.props;
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
<div class={itemActions({ class: className })} data-slot="item-actions" {...rest}>
|
|
15
|
-
<slot />
|
|
16
|
-
</div>
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
import { tv } from "tailwind-variants";
|
|
4
|
-
|
|
5
|
-
type Props = HTMLAttributes<"div">;
|
|
6
|
-
|
|
7
|
-
export const itemContent = tv({
|
|
8
|
-
base: "flex flex-1 flex-col gap-1.5 [&+[data-slot=item-content]]:flex-none",
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
const { class: className, ...rest } = Astro.props;
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
<div class={itemContent({ class: className })} data-slot="item-content" {...rest}>
|
|
15
|
-
<slot />
|
|
16
|
-
</div>
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
import { tv } from "tailwind-variants";
|
|
4
|
-
|
|
5
|
-
type Props = HTMLAttributes<"p">;
|
|
6
|
-
|
|
7
|
-
export const itemDescription = tv({
|
|
8
|
-
base: [
|
|
9
|
-
"text-muted-foreground line-clamp-2 leading-snug font-normal text-balance",
|
|
10
|
-
"[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
|
|
11
|
-
],
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
const { class: className, ...rest } = Astro.props;
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
<p class={itemDescription({ class: className })} data-slot="item-description" {...rest}>
|
|
18
|
-
<slot />
|
|
19
|
-
</p>
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
import { tv } from "tailwind-variants";
|
|
4
|
-
|
|
5
|
-
type Props = HTMLAttributes<"div">;
|
|
6
|
-
|
|
7
|
-
export const itemFooter = tv({
|
|
8
|
-
base: "flex basis-full items-center justify-between gap-2",
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
const { class: className, ...rest } = Astro.props;
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
<div class={itemFooter({ class: className })} data-slot="item-footer" {...rest}>
|
|
15
|
-
<slot />
|
|
16
|
-
</div>
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
import { tv } from "tailwind-variants";
|
|
4
|
-
|
|
5
|
-
type Props = HTMLAttributes<"div">;
|
|
6
|
-
|
|
7
|
-
export const itemGroup = tv({
|
|
8
|
-
base: "group/item-group flex flex-col",
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
const { class: className, ...rest } = Astro.props;
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
<div role="list" class={itemGroup({ class: className })} data-slot="item-group" {...rest}>
|
|
15
|
-
<slot />
|
|
16
|
-
</div>
|