@orbitkit/components 0.1.0 → 0.2.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 (133) hide show
  1. package/README.md +25 -25
  2. package/dist/astro/accordion/Accordion.astro +34 -0
  3. package/dist/astro/accordion/AccordionItem.astro +19 -0
  4. package/dist/astro/accordion/AccordionTrigger.astro +33 -0
  5. package/dist/astro/accordion/AcordionContent.astro +23 -0
  6. package/dist/astro/accordion/accordion.ts +151 -0
  7. package/dist/astro/accordion/index.ts +6 -0
  8. package/dist/astro/alert/Alert.astro +30 -30
  9. package/dist/astro/alert/AlertDescription.astro +10 -10
  10. package/dist/astro/alert/AlertTitle.astro +15 -15
  11. package/dist/astro/alert/alertVariants.ts +51 -51
  12. package/dist/astro/alert/index.ts +6 -6
  13. package/dist/astro/avatar/Avatar.astro +16 -16
  14. package/dist/astro/avatar/AvatarFallback.astro +18 -18
  15. package/dist/astro/avatar/AvatarImage.astro +14 -14
  16. package/dist/astro/avatar/avatarVariants.ts +23 -23
  17. package/dist/astro/avatar/index.ts +6 -6
  18. package/dist/astro/badge/Badge.astro +22 -22
  19. package/dist/astro/badge/badgeVariants.ts +37 -37
  20. package/dist/astro/badge/index.ts +4 -4
  21. package/dist/astro/breadcrumb/Breadcrumb.astro +12 -12
  22. package/dist/astro/breadcrumb/BreadcrumbEllipsis.astro +20 -20
  23. package/dist/astro/breadcrumb/BreadcrumbItem.astro +15 -15
  24. package/dist/astro/breadcrumb/BreadcrumbLink.astro +18 -18
  25. package/dist/astro/breadcrumb/BreadcrumbList.astro +18 -18
  26. package/dist/astro/breadcrumb/BreadcrumbPage.astro +18 -18
  27. package/dist/astro/breadcrumb/BreadcrumbSeparator.astro +17 -17
  28. package/dist/astro/breadcrumb/index.ts +17 -17
  29. package/dist/astro/button/Button.astro +29 -29
  30. package/dist/astro/button/buttonVariants.ts +61 -61
  31. package/dist/astro/button/index.ts +4 -4
  32. package/dist/astro/card/Card.astro +18 -18
  33. package/dist/astro/card/CardContent.astro +12 -12
  34. package/dist/astro/card/CardDescription.astro +12 -12
  35. package/dist/astro/card/CardFooter.astro +15 -15
  36. package/dist/astro/card/CardHeader.astro +12 -12
  37. package/dist/astro/card/CardTitle.astro +18 -18
  38. package/dist/astro/card/index.ts +15 -15
  39. package/dist/astro/checkbox/Checkbox.astro +38 -38
  40. package/dist/astro/checkbox/index.ts +3 -3
  41. package/dist/astro/collapsible/Collapsible.astro +34 -0
  42. package/dist/astro/collapsible/CollapsibleContent.astro +20 -0
  43. package/dist/astro/collapsible/collapsible.ts +81 -0
  44. package/dist/astro/collapsible/index.ts +4 -0
  45. package/dist/astro/divider/Divider.astro +22 -22
  46. package/dist/astro/divider/index.ts +3 -3
  47. package/dist/astro/drawer/Drawer.astro +19 -0
  48. package/dist/astro/drawer/DrawerContent.astro +74 -0
  49. package/dist/astro/drawer/DrawerDescription.astro +12 -0
  50. package/dist/astro/drawer/DrawerFooter.astro +15 -0
  51. package/dist/astro/drawer/DrawerHeader.astro +12 -0
  52. package/dist/astro/drawer/DrawerTitle.astro +18 -0
  53. package/dist/astro/drawer/drawer.ts +104 -0
  54. package/dist/astro/drawer/drawerVariants.ts +83 -0
  55. package/dist/astro/drawer/index.ts +17 -0
  56. package/dist/astro/dropdown/DropdownMenu.astro +19 -0
  57. package/dist/astro/dropdown/DropdownMenuContent.astro +42 -0
  58. package/dist/astro/dropdown/DropdownMenuGroup.astro +3 -0
  59. package/dist/astro/dropdown/DropdownMenuItem.astro +27 -0
  60. package/dist/astro/dropdown/DropdownMenuLabel.astro +3 -0
  61. package/dist/astro/dropdown/DropdownMenuSeparator.astro +6 -0
  62. package/dist/astro/dropdown/dropdown.ts +157 -0
  63. package/dist/astro/dropdown/dropdownVariants.ts +134 -0
  64. package/dist/astro/dropdown/index.ts +23 -0
  65. package/dist/astro/input/Input.astro +18 -18
  66. package/dist/astro/input/index.ts +4 -4
  67. package/dist/astro/input/inputVariants.ts +30 -30
  68. package/dist/astro/kbd/Kbd.astro +18 -0
  69. package/dist/astro/kbd/index.ts +3 -0
  70. package/dist/astro/label/Label.astro +14 -14
  71. package/dist/astro/label/index.ts +3 -3
  72. package/dist/astro/list/List.astro +25 -25
  73. package/dist/astro/list/ListItem.astro +39 -39
  74. package/dist/astro/list/ListVariants.ts +65 -65
  75. package/dist/astro/list/index.ts +5 -5
  76. package/dist/astro/modal/Modal.astro +19 -0
  77. package/dist/astro/modal/ModalContent.astro +71 -0
  78. package/dist/astro/modal/ModalDescription.astro +12 -0
  79. package/dist/astro/modal/ModalFooter.astro +15 -0
  80. package/dist/astro/modal/ModalHeader.astro +12 -0
  81. package/dist/astro/modal/ModalTitle.astro +18 -0
  82. package/dist/astro/modal/index.ts +15 -0
  83. package/dist/astro/modal/modal.ts +101 -0
  84. package/dist/astro/pagination/Pagination.astro +12 -0
  85. package/dist/astro/pagination/PaginationContent.astro +15 -0
  86. package/dist/astro/pagination/PaginationEllipsis.astro +33 -0
  87. package/dist/astro/pagination/PaginationItem.astro +12 -0
  88. package/dist/astro/pagination/PaginationLink.astro +21 -0
  89. package/dist/astro/pagination/PaginationNext.astro +29 -0
  90. package/dist/astro/pagination/PaginationPrevious.astro +34 -0
  91. package/dist/astro/pagination/index.ts +15 -0
  92. package/dist/astro/pagination/paginationVariants.ts +26 -0
  93. package/dist/astro/popover/Popover.astro +17 -0
  94. package/dist/astro/popover/PopoverContent.astro +39 -0
  95. package/dist/astro/popover/index.ts +5 -0
  96. package/dist/astro/popover/popover.ts +113 -0
  97. package/dist/astro/popover/popoverVariants.ts +115 -0
  98. package/dist/astro/progress/Progress.astro +23 -23
  99. package/dist/astro/progress/index.ts +4 -4
  100. package/dist/astro/progress/progressContainer.astro +17 -17
  101. package/dist/astro/radio/Radio.astro +26 -26
  102. package/dist/astro/radio/index.ts +3 -3
  103. package/dist/astro/select/Option.astro +11 -11
  104. package/dist/astro/select/Select.astro +39 -39
  105. package/dist/astro/select/index.ts +5 -5
  106. package/dist/astro/select/selectVariants.ts +30 -30
  107. package/dist/astro/skeleton/Skeleton.astro +12 -12
  108. package/dist/astro/skeleton/SkeletonItem.astro +18 -18
  109. package/dist/astro/skeleton/index.ts +4 -4
  110. package/dist/astro/stat/Stat.astro +12 -0
  111. package/dist/astro/stat/StatDescription.astro +12 -0
  112. package/dist/astro/stat/StatTitle.astro +18 -0
  113. package/dist/astro/stat/StatValue.astro +12 -0
  114. package/dist/astro/stat/index.ts +6 -0
  115. package/dist/astro/switch/Switch.astro +19 -19
  116. package/dist/astro/switch/index.ts +3 -3
  117. package/dist/astro/tab/Tab.astro +33 -0
  118. package/dist/astro/tab/TabContent.astro +19 -0
  119. package/dist/astro/tab/TabList.astro +19 -0
  120. package/dist/astro/tab/TabTrigger.astro +24 -0
  121. package/dist/astro/tab/index.ts +6 -0
  122. package/dist/astro/tab/tab.ts +142 -0
  123. package/dist/astro/textarea/Textarea.astro +19 -19
  124. package/dist/astro/textarea/TextareaVariants.ts +30 -30
  125. package/dist/astro/textarea/index.ts +4 -4
  126. package/dist/astro/tooltip/Tooltip.astro +40 -0
  127. package/dist/astro/tooltip/TooltipContent.astro +39 -0
  128. package/dist/astro/tooltip/index.ts +5 -0
  129. package/dist/astro/tooltip/tooltip.ts +137 -0
  130. package/dist/astro/tooltip/tooltipVariants.ts +115 -0
  131. package/dist/index.js +46 -1
  132. package/dist/index.js.map +1 -1
  133. package/package.json +2 -2
@@ -1,39 +1,39 @@
1
- ---
2
- import { cn } from "@/utils/cn";
3
- import { type HTMLAttributes } from "astro/types";
4
- import type { VariantProps } from "class-variance-authority";
5
- import { selectVariants } from "./selectVariants";
6
-
7
- interface Props
8
- extends Omit<HTMLAttributes<"select">, "disabled">,
9
- VariantProps<typeof selectVariants> {}
10
-
11
- const { class: className, multiple, variant, disabled, ...attrs } = Astro.props;
12
- ---
13
-
14
- <div class="relative">
15
- <select
16
- {...attrs}
17
- disabled={disabled}
18
- multiple={multiple}
19
- class={cn(selectVariants({ variant, disabled, className }))}
20
- >
21
- <slot />
22
- </select>
23
-
24
- {
25
- !multiple && (
26
- <svg
27
- xmlns="http://www.w3.org/2000/svg"
28
- viewBox="0 0 24 24"
29
- fill="none"
30
- stroke="currentColor"
31
- stroke-width="2"
32
- class="text-input-placeholder absolute right-2.5 top-2.5 h-5 w-5"
33
- >
34
- <path d="m7 15 5 5 5-5" />
35
- <path d="m7 9 5-5 5 5" />
36
- </svg>
37
- )
38
- }
39
- </div>
1
+ ---
2
+ import { cn } from "@/utils/cn";
3
+ import { type HTMLAttributes } from "astro/types";
4
+ import type { VariantProps } from "class-variance-authority";
5
+ import { selectVariants } from "./selectVariants";
6
+
7
+ interface Props
8
+ extends Omit<HTMLAttributes<"select">, "disabled">,
9
+ VariantProps<typeof selectVariants> {}
10
+
11
+ const { class: className, multiple, variant, disabled, ...attrs } = Astro.props;
12
+ ---
13
+
14
+ <div class="relative">
15
+ <select
16
+ {...attrs}
17
+ disabled={disabled}
18
+ multiple={multiple}
19
+ class={cn(selectVariants({ variant, disabled, className }))}
20
+ >
21
+ <slot />
22
+ </select>
23
+
24
+ {
25
+ !multiple && (
26
+ <svg
27
+ xmlns="http://www.w3.org/2000/svg"
28
+ viewBox="0 0 24 24"
29
+ fill="none"
30
+ stroke="currentColor"
31
+ stroke-width="2"
32
+ class="text-input-placeholder absolute right-2.5 top-2.5 h-5 w-5"
33
+ >
34
+ <path d="m7 15 5 5 5-5" />
35
+ <path d="m7 9 5-5 5 5" />
36
+ </svg>
37
+ )
38
+ }
39
+ </div>
@@ -1,5 +1,5 @@
1
- import Option from "./Option.astro";
2
- import Select from "./Select.astro";
3
- import { selectVariants } from "./selectVariants";
4
-
5
- export { Option, Select, selectVariants };
1
+ import Option from "./Option.astro";
2
+ import Select from "./Select.astro";
3
+ import { selectVariants } from "./selectVariants";
4
+
5
+ export { Option, Select, selectVariants };
@@ -1,30 +1,30 @@
1
- import { cva } from "class-variance-authority";
2
-
3
- const baseClass =
4
- "block w-full p-2.5 mb-2 text-sm rounded-lg outline-1 -outline-offset-1 appearance-none";
5
-
6
- const selectVariants = cva(baseClass, {
7
- variants: {
8
- variant: {
9
- default:
10
- "text-foreground bg-input outline-input-border placeholder-input-placeholder cursor-pointer",
11
- },
12
- disabled: {
13
- false: null,
14
- true: "bg-input/40 outline-input-border/40 text-muted-foreground cursor-not-allowed",
15
- },
16
- },
17
- compoundVariants: [
18
- {
19
- variant: "default",
20
- disabled: false,
21
- class: "focus:outline-2 focus:-outline-offset-2 focus:outline-primary",
22
- },
23
- ],
24
- defaultVariants: {
25
- variant: "default",
26
- disabled: false,
27
- },
28
- });
29
-
30
- export { selectVariants };
1
+ import { cva } from "class-variance-authority";
2
+
3
+ const baseClass =
4
+ "block w-full p-2.5 mb-2 text-sm rounded-lg outline-1 -outline-offset-1 appearance-none";
5
+
6
+ const selectVariants = cva(baseClass, {
7
+ variants: {
8
+ variant: {
9
+ default:
10
+ "text-foreground bg-input outline-input-border placeholder-input-placeholder cursor-pointer",
11
+ },
12
+ disabled: {
13
+ false: null,
14
+ true: "bg-input/40 outline-input-border/40 text-muted-foreground cursor-not-allowed",
15
+ },
16
+ },
17
+ compoundVariants: [
18
+ {
19
+ variant: "default",
20
+ disabled: false,
21
+ class: "focus:outline-2 focus:-outline-offset-2 focus:outline-primary",
22
+ },
23
+ ],
24
+ defaultVariants: {
25
+ variant: "default",
26
+ disabled: false,
27
+ },
28
+ });
29
+
30
+ export { selectVariants };
@@ -1,12 +1,12 @@
1
- ---
2
- import { cn } from "@/utils/cn";
3
- import type { HTMLAttributes } from "astro/types";
4
-
5
- interface Props extends HTMLAttributes<"div"> {}
6
-
7
- const { class: className, ...attrs } = Astro.props;
8
- ---
9
-
10
- <div {...attrs} role="status" class={cn("animate-pulse", className)}>
11
- <slot />
12
- </div>
1
+ ---
2
+ import { cn } from "@/utils/cn";
3
+ import type { HTMLAttributes } from "astro/types";
4
+
5
+ interface Props extends HTMLAttributes<"div"> {}
6
+
7
+ const { class: className, ...attrs } = Astro.props;
8
+ ---
9
+
10
+ <div {...attrs} role="status" class={cn("animate-pulse", className)}>
11
+ <slot />
12
+ </div>
@@ -1,18 +1,18 @@
1
- ---
2
- import { cn } from "@/utils/cn";
3
- import type { HTMLAttributes } from "astro/types";
4
-
5
- interface Props extends HTMLAttributes<"div"> {}
6
-
7
- const { class: className, ...attrs } = Astro.props;
8
- ---
9
-
10
- <div
11
- {...attrs}
12
- class={cn(
13
- "rounded-md bg-muted text-muted-foreground flex items-center justify-center",
14
- className,
15
- )}
16
- >
17
- <slot />
18
- </div>
1
+ ---
2
+ import { cn } from "@/utils/cn";
3
+ import type { HTMLAttributes } from "astro/types";
4
+
5
+ interface Props extends HTMLAttributes<"div"> {}
6
+
7
+ const { class: className, ...attrs } = Astro.props;
8
+ ---
9
+
10
+ <div
11
+ {...attrs}
12
+ class={cn(
13
+ "rounded-md bg-muted text-muted-foreground flex items-center justify-center",
14
+ className,
15
+ )}
16
+ >
17
+ <slot />
18
+ </div>
@@ -1,4 +1,4 @@
1
- import Skeleton from "./Skeleton.astro";
2
- import SkeletonItem from "./SkeletonItem.astro";
3
-
4
- export { Skeleton, SkeletonItem };
1
+ import Skeleton from "./Skeleton.astro";
2
+ import SkeletonItem from "./SkeletonItem.astro";
3
+
4
+ export { Skeleton, SkeletonItem };
@@ -0,0 +1,12 @@
1
+ ---
2
+ import { cn } from "@/utils/cn";
3
+ import type { HTMLAttributes } from "astro/types";
4
+
5
+ interface Props extends HTMLAttributes<"div"> {}
6
+
7
+ const { class: className, ...attrs } = Astro.props;
8
+ ---
9
+
10
+ <div class={cn("inline-flex flex-col gap-0.5", className)} {...attrs}>
11
+ <slot />
12
+ </div>
@@ -0,0 +1,12 @@
1
+ ---
2
+ import { cn } from "@/utils/cn";
3
+ import type { HTMLAttributes } from "astro/types";
4
+
5
+ interface Props extends HTMLAttributes<"div"> {}
6
+
7
+ const { class: className, ...attrs } = Astro.props;
8
+ ---
9
+
10
+ <p class={cn("text-sm text-foreground/70", className)} {...attrs}>
11
+ <slot />
12
+ </p>
@@ -0,0 +1,18 @@
1
+ ---
2
+ import { cn } from "@/utils/cn";
3
+ import type { HTMLAttributes } from "astro/types";
4
+
5
+ interface Props extends HTMLAttributes<"h3"> {}
6
+
7
+ const { class: className, ...attrs } = Astro.props;
8
+ ---
9
+
10
+ <h3
11
+ class={cn(
12
+ "text-sm font-medium text-foreground/80 uppercase tracking-wide",
13
+ className,
14
+ )}
15
+ {...attrs}
16
+ >
17
+ <slot />
18
+ </h3>
@@ -0,0 +1,12 @@
1
+ ---
2
+ import { cn } from "@/utils/cn";
3
+ import type { HTMLAttributes } from "astro/types";
4
+
5
+ interface Props extends HTMLAttributes<"div"> {}
6
+
7
+ const { class: className, ...attrs } = Astro.props;
8
+ ---
9
+
10
+ <span class={cn("text-3xl font-bold text-foreground", className)} {...attrs}>
11
+ <slot />
12
+ </span>
@@ -0,0 +1,6 @@
1
+ import Stat from "./Stat.astro";
2
+ import StatDescription from "./StatDescription.astro";
3
+ import StatTitle from "./StatTitle.astro";
4
+ import StatValue from "./StatValue.astro";
5
+
6
+ export { Stat, StatDescription, StatTitle, StatValue };
@@ -1,19 +1,19 @@
1
- ---
2
- import { cn } from "@/utils/cn";
3
- import { type HTMLAttributes } from "astro/types";
4
-
5
- interface Props extends Omit<HTMLAttributes<"input">, "type"> {}
6
-
7
- const { class: className, id, ...attrs } = Astro.props;
8
- ---
9
-
10
- <label class="inline-flex cursor-pointer items-center" id={id}>
11
- <input {...attrs} id={id} type="checkbox" class="peer sr-only" />
12
- <span
13
- class={cn(
14
- "relative w-11 h-6 bg-input-border rounded-full peer peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full after:content-[''] after:absolute after:top-0.5 after:start-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
15
- className,
16
- )}
17
- >
18
- </span>
19
- </label>
1
+ ---
2
+ import { cn } from "@/utils/cn";
3
+ import { type HTMLAttributes } from "astro/types";
4
+
5
+ interface Props extends Omit<HTMLAttributes<"input">, "type"> {}
6
+
7
+ const { class: className, id, ...attrs } = Astro.props;
8
+ ---
9
+
10
+ <label class="inline-flex cursor-pointer items-center" id={id}>
11
+ <input {...attrs} id={id} type="checkbox" class="peer sr-only" />
12
+ <span
13
+ class={cn(
14
+ "relative w-11 h-6 bg-input-border rounded-full peer peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full after:content-[''] after:absolute after:top-0.5 after:start-[2px] after:bg-white after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-primary peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
15
+ className,
16
+ )}
17
+ >
18
+ </span>
19
+ </label>
@@ -1,3 +1,3 @@
1
- import Switch from "./Switch.astro";
2
-
3
- export { Switch };
1
+ import Switch from "./Switch.astro";
2
+
3
+ export { Switch };
@@ -0,0 +1,33 @@
1
+ ---
2
+ import { cn } from "@/utils/cn";
3
+ import type { HTMLAttributes } from "astro/types";
4
+
5
+ interface Props extends HTMLAttributes<"div"> {
6
+ defaultValue?: string;
7
+ }
8
+
9
+ const { class: className, defaultValue, ...attrs } = Astro.props;
10
+ ---
11
+
12
+ <div
13
+ {...attrs}
14
+ data-tab
15
+ data-default-value={defaultValue}
16
+ class={cn(className)}
17
+ >
18
+ <slot />
19
+ </div>
20
+
21
+ <script>
22
+ import { Tab } from "./tab";
23
+
24
+ function init() {
25
+ const tabs = document.querySelectorAll<HTMLElement>("[data-tab]");
26
+ tabs.forEach((tab) => {
27
+ new Tab(tab);
28
+ });
29
+ }
30
+
31
+ init();
32
+ document.addEventListener("astro:page-load", () => init());
33
+ </script>
@@ -0,0 +1,19 @@
1
+ ---
2
+ interface Props {
3
+ value: string;
4
+ }
5
+
6
+ const { value } = Astro.props;
7
+ ---
8
+
9
+ <div
10
+ role="tabpanel"
11
+ aria-orientation="horizontal"
12
+ data-tab-content
13
+ data-state="inactive"
14
+ data-value={value}
15
+ hidden
16
+ class="mt-2 w-full"
17
+ >
18
+ <slot />
19
+ </div>
@@ -0,0 +1,19 @@
1
+ ---
2
+ import { cn } from "@/utils/cn";
3
+ import type { HTMLAttributes } from "astro/types";
4
+
5
+ interface Props extends HTMLAttributes<"div"> {}
6
+
7
+ const { class: className } = Astro.props;
8
+ ---
9
+
10
+ <div
11
+ role="tablist"
12
+ data-tab-list
13
+ class={cn(
14
+ "flex flex-row justify-between flex-wrap bg-surface border border-border p-1 rounded-lg w-fit",
15
+ className,
16
+ )}
17
+ >
18
+ <slot />
19
+ </div>
@@ -0,0 +1,24 @@
1
+ ---
2
+ import { cn } from "@/utils/cn";
3
+ import type { HTMLAttributes } from "astro/types";
4
+
5
+ interface Props extends HTMLAttributes<"button"> {
6
+ value: string;
7
+ }
8
+
9
+ const { class: className, value } = Astro.props;
10
+ ---
11
+
12
+ <button
13
+ role="tab"
14
+ aria-orientation="horizontal"
15
+ data-selected="false"
16
+ data-value={value}
17
+ data-tab-trigger
18
+ class={cn(
19
+ "rounded-sm px-3 py-1.5 flex justify-center gap-1.5 items-center font-medium cursor-pointer outline-none [&_svg]:pointer-events-none [&_svg]:shrink-0 transition-colors duration-100 ease-in data-[selected=true]:bg-secondary",
20
+ className,
21
+ )}
22
+ >
23
+ <slot />
24
+ </button>
@@ -0,0 +1,6 @@
1
+ import Tab from "./Tab.astro";
2
+ import TabContent from "./TabContent.astro";
3
+ import TabList from "./TabList.astro";
4
+ import TabTrigger from "./TabTrigger.astro";
5
+
6
+ export { Tab, TabContent, TabList, TabTrigger };
@@ -0,0 +1,142 @@
1
+ export class Tab {
2
+ private tab: HTMLElement;
3
+ private tabList: HTMLElement | null;
4
+ private tabsTrigger: NodeListOf<HTMLElement> | null;
5
+ private tabContents: NodeListOf<HTMLElement> | null;
6
+ private contentMap: Map<string, HTMLElement> = new Map();
7
+
8
+ constructor(tabWrapper: HTMLElement) {
9
+ this.tab = tabWrapper;
10
+ this.tabList = this.tab.querySelector("[data-tab-list]");
11
+ this.tabsTrigger =
12
+ this.tabList?.querySelectorAll("[data-tab-trigger]") || null;
13
+ this.tabContents = this.tab.querySelectorAll("[data-tab-content]");
14
+
15
+ this.initializeContentMap();
16
+ this.init();
17
+ }
18
+
19
+ private init() {
20
+ this.setupAccessibility();
21
+ this.setupEventListeners();
22
+ this.setDefaultTab();
23
+ }
24
+
25
+ private initializeContentMap(): void {
26
+ this.tabContents?.forEach((content) => {
27
+ const value = content.dataset.value?.toLowerCase();
28
+ if (value) {
29
+ if (this.contentMap.has(value)) {
30
+ console.warn(
31
+ `Duplicate data-value "${value}" found in content elements`,
32
+ );
33
+ }
34
+ this.contentMap.set(value, content);
35
+ }
36
+ });
37
+ }
38
+
39
+ private setupAccessibility() {
40
+ this.tabsTrigger?.forEach((trigger) => {
41
+ const triggerValue = trigger.dataset.value?.toLowerCase();
42
+ if (!triggerValue) return;
43
+
44
+ const content = this.contentMap.get(triggerValue);
45
+ if (!content) {
46
+ console.warn(`No content found for trigger value: ${triggerValue}`);
47
+ return;
48
+ }
49
+
50
+ const uniqueId = Math.random().toString(36).substring(2, 9);
51
+ const triggerId = trigger.id || `tab-trigger-${triggerValue}-${uniqueId}`;
52
+ const contentId = content.id || `tab-content-${triggerValue}-${uniqueId}`;
53
+
54
+ trigger.setAttribute("id", triggerId);
55
+ trigger.setAttribute("aria-controls", contentId);
56
+
57
+ content.setAttribute("id", contentId);
58
+ content.setAttribute("aria-labelledby", triggerId);
59
+ });
60
+ }
61
+
62
+ private setupEventListeners() {
63
+ this.tabsTrigger?.forEach((trigger) => {
64
+ trigger.addEventListener("click", () => this.activateTab(trigger));
65
+ trigger.addEventListener("keydown", (e) =>
66
+ this.handleKeydown(e, trigger),
67
+ );
68
+ });
69
+ }
70
+
71
+ private handleKeydown(event: KeyboardEvent, item: HTMLElement) {
72
+ const items = Array.from(this.tabsTrigger || []);
73
+ const currentItemIndex = items.indexOf(item);
74
+
75
+ const keyActions: Record<string, () => void> = {
76
+ ArrowRight: () => this.setFocusItem(items, currentItemIndex + 1),
77
+ ArrowLeft: () => this.setFocusItem(items, currentItemIndex - 1),
78
+ Home: () => this.setFocusItem(items, 0),
79
+ End: () => this.setFocusItem(items, items.length - 1),
80
+ };
81
+
82
+ const action = keyActions[event.key];
83
+ if (action) {
84
+ event.preventDefault();
85
+ action();
86
+ }
87
+ }
88
+
89
+ private setFocusItem(items: HTMLElement[], index: number) {
90
+ const newIndex = index % items.length;
91
+ if (items[newIndex]) {
92
+ this.activateTab(items[newIndex]);
93
+ }
94
+ }
95
+
96
+ private setDefaultTab() {
97
+ const defaultTrigger = this.getDefaultTrigger();
98
+ if (defaultTrigger) {
99
+ this.activateTab(defaultTrigger);
100
+ }
101
+ }
102
+
103
+ private getDefaultTrigger(): HTMLElement | undefined {
104
+ if (!this.tabsTrigger) return;
105
+
106
+ const defaultValue = this.tab.dataset.defaultValue?.toLowerCase();
107
+ if (defaultValue) {
108
+ return Array.from(this.tabsTrigger || []).find(
109
+ (trigger) => trigger.dataset.value?.toLowerCase() === defaultValue,
110
+ );
111
+ }
112
+ return this.tabsTrigger[0];
113
+ }
114
+
115
+ private activateTab(trigger: HTMLElement) {
116
+ this.tabsTrigger?.forEach((t) => {
117
+ t.setAttribute("aria-selected", "false");
118
+ t.setAttribute("data-selected", "false");
119
+ t.setAttribute("tabindex", "-1");
120
+ });
121
+
122
+ this.tabContents?.forEach((c) => {
123
+ c.setAttribute("data-state", "active");
124
+ c.setAttribute("hidden", "");
125
+ });
126
+
127
+ const triggerValue = trigger.dataset.value?.toLowerCase();
128
+ if (triggerValue) {
129
+ const content = this.contentMap.get(triggerValue);
130
+ if (content) {
131
+ content.removeAttribute("hidden");
132
+ setTimeout(() => {
133
+ content.setAttribute("data-state", "active");
134
+ trigger.setAttribute("aria-selected", "true");
135
+ trigger.setAttribute("data-selected", "true");
136
+ trigger.setAttribute("tabindex", "0");
137
+ }, 100);
138
+ trigger.focus();
139
+ }
140
+ }
141
+ }
142
+ }
@@ -1,19 +1,19 @@
1
- ---
2
- import { cn } from "@/utils/cn";
3
- import { type HTMLAttributes } from "astro/types";
4
- import type { VariantProps } from "class-variance-authority";
5
- import { textareaVariants } from "./TextareaVariants";
6
-
7
- interface Props
8
- extends Omit<HTMLAttributes<"textarea">, "disabled">,
9
- VariantProps<typeof textareaVariants> {}
10
-
11
- const { class: className, variant, disabled, ...attrs } = Astro.props;
12
- ---
13
-
14
- <textarea
15
- {...attrs}
16
- disabled={disabled}
17
- class={cn(textareaVariants({ variant, disabled, className }))}
18
- >
19
- </textarea>
1
+ ---
2
+ import { cn } from "@/utils/cn";
3
+ import { type HTMLAttributes } from "astro/types";
4
+ import type { VariantProps } from "class-variance-authority";
5
+ import { textareaVariants } from "./TextareaVariants";
6
+
7
+ interface Props
8
+ extends Omit<HTMLAttributes<"textarea">, "disabled">,
9
+ VariantProps<typeof textareaVariants> {}
10
+
11
+ const { class: className, variant, disabled, ...attrs } = Astro.props;
12
+ ---
13
+
14
+ <textarea
15
+ {...attrs}
16
+ disabled={disabled}
17
+ class={cn(textareaVariants({ variant, disabled, className }))}
18
+ >
19
+ </textarea>