@financedistrict/apps-ui 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 (136) hide show
  1. package/LICENSE +19 -0
  2. package/README.md +119 -0
  3. package/dist/Radio-BYWz1n7p.d.cts +32 -0
  4. package/dist/Radio-BYWz1n7p.d.ts +32 -0
  5. package/dist/SelectTrigger-By0iPBI3.d.cts +78 -0
  6. package/dist/SelectTrigger-By0iPBI3.d.ts +78 -0
  7. package/dist/accordion.cjs +322 -0
  8. package/dist/accordion.d.cts +156 -0
  9. package/dist/accordion.d.ts +156 -0
  10. package/dist/accordion.js +2 -0
  11. package/dist/apps-ui.umd.js +1 -0
  12. package/dist/button.cjs +366 -0
  13. package/dist/button.d.cts +52 -0
  14. package/dist/button.d.ts +52 -0
  15. package/dist/button.js +3 -0
  16. package/dist/checkbox.cjs +74 -0
  17. package/dist/checkbox.d.cts +63 -0
  18. package/dist/checkbox.d.ts +63 -0
  19. package/dist/checkbox.js +2 -0
  20. package/dist/chunk-3RU7JMFE.js +27 -0
  21. package/dist/chunk-5TWRK4NW.js +783 -0
  22. package/dist/chunk-7EOSDFS3.js +9 -0
  23. package/dist/chunk-AIQ4UOGK.js +142 -0
  24. package/dist/chunk-B3MMGTPV.js +200 -0
  25. package/dist/chunk-DAHQYLUI.js +146 -0
  26. package/dist/chunk-DGBXADSS.js +1 -0
  27. package/dist/chunk-E6KPNTWW.js +295 -0
  28. package/dist/chunk-EOAB6G2D.js +149 -0
  29. package/dist/chunk-FAOVKDVM.js +32 -0
  30. package/dist/chunk-FV76Z4Z2.js +78 -0
  31. package/dist/chunk-GLTLBUZ7.js +285 -0
  32. package/dist/chunk-GTZFV43T.js +154 -0
  33. package/dist/chunk-HRGZNL4A.js +88 -0
  34. package/dist/chunk-IEVN3J2F.js +98 -0
  35. package/dist/chunk-IRS3T6LF.js +352 -0
  36. package/dist/chunk-IYYHCQXG.js +146 -0
  37. package/dist/chunk-JIXW3455.js +89 -0
  38. package/dist/chunk-N4VAP2GB.js +77 -0
  39. package/dist/chunk-SJ2ZRYVV.js +167 -0
  40. package/dist/chunk-SNU4YXOR.js +66 -0
  41. package/dist/chunk-TT6JQATV.js +99 -0
  42. package/dist/chunk-UPQ3ZPCO.js +66 -0
  43. package/dist/chunk-UVUSVFOH.js +264 -0
  44. package/dist/chunk-WJFPGGJB.js +255 -0
  45. package/dist/chunk-WXEBQA7A.js +371 -0
  46. package/dist/chunk-Y2O4YYZQ.js +184 -0
  47. package/dist/cut-corner.cjs +111 -0
  48. package/dist/cut-corner.d.cts +49 -0
  49. package/dist/cut-corner.d.ts +49 -0
  50. package/dist/cut-corner.js +1 -0
  51. package/dist/dialog.cjs +441 -0
  52. package/dist/dialog.d.cts +240 -0
  53. package/dist/dialog.d.ts +240 -0
  54. package/dist/dialog.js +3 -0
  55. package/dist/feature-card.cjs +182 -0
  56. package/dist/feature-card.d.cts +54 -0
  57. package/dist/feature-card.d.ts +54 -0
  58. package/dist/feature-card.js +2 -0
  59. package/dist/filter.cjs +873 -0
  60. package/dist/filter.d.cts +129 -0
  61. package/dist/filter.d.ts +129 -0
  62. package/dist/filter.js +6 -0
  63. package/dist/index.cjs +4583 -0
  64. package/dist/index.d.cts +29 -0
  65. package/dist/index.d.ts +29 -0
  66. package/dist/index.js +27 -0
  67. package/dist/inline-select.cjs +856 -0
  68. package/dist/inline-select.d.cts +92 -0
  69. package/dist/inline-select.d.ts +92 -0
  70. package/dist/inline-select.js +6 -0
  71. package/dist/input.cjs +263 -0
  72. package/dist/input.d.cts +157 -0
  73. package/dist/input.d.ts +157 -0
  74. package/dist/input.js +4 -0
  75. package/dist/panel.cjs +185 -0
  76. package/dist/panel.d.cts +103 -0
  77. package/dist/panel.d.ts +103 -0
  78. package/dist/panel.js +2 -0
  79. package/dist/property-grid.cjs +110 -0
  80. package/dist/property-grid.d.cts +56 -0
  81. package/dist/property-grid.d.ts +56 -0
  82. package/dist/property-grid.js +2 -0
  83. package/dist/radio.cjs +74 -0
  84. package/dist/radio.d.cts +39 -0
  85. package/dist/radio.d.ts +39 -0
  86. package/dist/radio.js +2 -0
  87. package/dist/scrollbar.cjs +34 -0
  88. package/dist/scrollbar.d.cts +35 -0
  89. package/dist/scrollbar.d.ts +35 -0
  90. package/dist/scrollbar.js +1 -0
  91. package/dist/search-bar.cjs +408 -0
  92. package/dist/search-bar.d.cts +42 -0
  93. package/dist/search-bar.d.ts +42 -0
  94. package/dist/search-bar.js +4 -0
  95. package/dist/select.cjs +998 -0
  96. package/dist/select.d.cts +357 -0
  97. package/dist/select.d.ts +357 -0
  98. package/dist/select.js +5 -0
  99. package/dist/selectable-feature-card.cjs +159 -0
  100. package/dist/selectable-feature-card.d.cts +74 -0
  101. package/dist/selectable-feature-card.d.ts +74 -0
  102. package/dist/selectable-feature-card.js +3 -0
  103. package/dist/sidebar-item.cjs +175 -0
  104. package/dist/sidebar-item.d.cts +75 -0
  105. package/dist/sidebar-item.d.ts +75 -0
  106. package/dist/sidebar-item.js +2 -0
  107. package/dist/switch.cjs +86 -0
  108. package/dist/switch.d.cts +72 -0
  109. package/dist/switch.d.ts +72 -0
  110. package/dist/switch.js +2 -0
  111. package/dist/table-cell.cjs +196 -0
  112. package/dist/table-cell.d.cts +76 -0
  113. package/dist/table-cell.d.ts +76 -0
  114. package/dist/table-cell.js +2 -0
  115. package/dist/table-title.cjs +34 -0
  116. package/dist/table-title.d.cts +16 -0
  117. package/dist/table-title.d.ts +16 -0
  118. package/dist/table-title.js +2 -0
  119. package/dist/tabs.cjs +299 -0
  120. package/dist/tabs.d.cts +116 -0
  121. package/dist/tabs.d.ts +116 -0
  122. package/dist/tabs.js +2 -0
  123. package/dist/toast.cjs +87 -0
  124. package/dist/toast.d.cts +48 -0
  125. package/dist/toast.d.ts +48 -0
  126. package/dist/toast.js +2 -0
  127. package/dist/token-input.cjs +415 -0
  128. package/dist/token-input.d.cts +90 -0
  129. package/dist/token-input.d.ts +90 -0
  130. package/dist/token-input.js +3 -0
  131. package/dist/tooltip.cjs +384 -0
  132. package/dist/tooltip.d.cts +142 -0
  133. package/dist/tooltip.d.ts +142 -0
  134. package/dist/tooltip.js +2 -0
  135. package/package.json +200 -0
  136. package/src/fonts.css +33 -0
@@ -0,0 +1,167 @@
1
+ import { cn } from './chunk-7EOSDFS3.js';
2
+ import * as React from 'react';
3
+ import { cva } from 'class-variance-authority';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ var tableCellVariants = cva(
7
+ [
8
+ // The cell is the group that drives hover/active styling of its descendants.
9
+ "group",
10
+ // Layout — 56px row, slots on a horizontal axis; overflow clipped for truncation.
11
+ "flex h-14 w-full items-center gap-3 overflow-hidden px-2 py-4",
12
+ // Brand-accent background on hover / keyboard-focus / active (self). Reset
13
+ // native control chrome so an asChild button/anchor styles cleanly.
14
+ "appearance-none bg-transparent outline-none transition-colors",
15
+ "hover:bg-card-brand-accent focus-visible:bg-card-brand-accent data-[state=active]:bg-card-brand-accent"
16
+ ],
17
+ {
18
+ variants: {
19
+ last: {
20
+ // Row divider on all but the last row; recolors on hover / focus / active.
21
+ false: [
22
+ "border-b border-card-border",
23
+ "hover:border-card-brand-border-accent focus-visible:border-card-brand-border-accent data-[state=active]:border-card-brand-border-accent"
24
+ ],
25
+ true: ""
26
+ }
27
+ },
28
+ defaultVariants: {
29
+ last: false
30
+ }
31
+ }
32
+ );
33
+ function setRef(ref, node) {
34
+ if (typeof ref === "function") ref(node);
35
+ else if (ref) ref.current = node;
36
+ }
37
+ function TableCell({
38
+ className,
39
+ last = false,
40
+ leading,
41
+ trailing,
42
+ active = false,
43
+ asChild = false,
44
+ children,
45
+ ref,
46
+ ...props
47
+ }) {
48
+ const rootClassName = cn(tableCellVariants({ last }), className);
49
+ const dataState = active ? "active" : void 0;
50
+ const leadingSlot = leading != null ? /* @__PURE__ */ jsx(
51
+ "span",
52
+ {
53
+ "data-slot": "table-cell-leading",
54
+ className: "flex shrink-0 items-center",
55
+ children: leading
56
+ }
57
+ ) : null;
58
+ const trailingSlot = trailing != null ? /* @__PURE__ */ jsx(
59
+ "span",
60
+ {
61
+ "data-slot": "table-cell-trailing",
62
+ className: "flex shrink-0 items-center",
63
+ children: trailing
64
+ }
65
+ ) : null;
66
+ const middleSlot = (middle) => middle != null ? /* @__PURE__ */ jsx(
67
+ "span",
68
+ {
69
+ "data-slot": "table-cell-middle",
70
+ className: "flex min-w-0 flex-1 flex-col",
71
+ children: middle
72
+ }
73
+ ) : null;
74
+ if (asChild) {
75
+ if (!React.isValidElement(children)) {
76
+ throw new Error(
77
+ "TableCell: `asChild` requires a single React element child"
78
+ );
79
+ }
80
+ const child = children;
81
+ const childProps = child.props;
82
+ return React.cloneElement(
83
+ child,
84
+ {
85
+ ...props,
86
+ ...childProps,
87
+ "data-slot": "table-cell",
88
+ "data-state": dataState,
89
+ className: cn(
90
+ rootClassName,
91
+ childProps.className
92
+ ),
93
+ ref: (node) => {
94
+ setRef(ref, node);
95
+ setRef(childProps.ref, node);
96
+ }
97
+ },
98
+ leadingSlot,
99
+ middleSlot(childProps.children),
100
+ trailingSlot
101
+ );
102
+ }
103
+ return /* @__PURE__ */ jsxs(
104
+ "div",
105
+ {
106
+ "data-slot": "table-cell",
107
+ "data-state": dataState,
108
+ className: rootClassName,
109
+ ref,
110
+ ...props,
111
+ children: [
112
+ leadingSlot,
113
+ middleSlot(children),
114
+ trailingSlot
115
+ ]
116
+ }
117
+ );
118
+ }
119
+ function CellText({ label, meta, className, ...props }) {
120
+ const hasMeta = Array.isArray(meta) && meta.length > 0;
121
+ return /* @__PURE__ */ jsxs(
122
+ "div",
123
+ {
124
+ "data-slot": "cell-text",
125
+ className: cn("flex min-w-0 flex-col gap-0.5", className),
126
+ ...props,
127
+ children: [
128
+ /* @__PURE__ */ jsx(
129
+ "span",
130
+ {
131
+ "data-slot": "cell-text-label",
132
+ className: cn(
133
+ "body-03 min-w-0 truncate",
134
+ "text-card-foreground",
135
+ "group-hover:text-card-brand-foreground group-focus-visible:text-card-brand-foreground group-data-[state=active]:text-card-brand-foreground"
136
+ ),
137
+ children: label
138
+ }
139
+ ),
140
+ hasMeta && /* @__PURE__ */ jsx(
141
+ "div",
142
+ {
143
+ "data-slot": "cell-text-meta",
144
+ className: cn(
145
+ "flex min-w-0 items-center gap-1",
146
+ "body-mono-04",
147
+ "text-card-foreground-muted",
148
+ "group-hover:text-card-brand-foreground-muted group-focus-visible:text-card-brand-foreground-muted group-data-[state=active]:text-card-brand-foreground-muted"
149
+ ),
150
+ children: meta.map((segment, index) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
151
+ index > 0 && /* @__PURE__ */ jsx(
152
+ "span",
153
+ {
154
+ "aria-hidden": "true",
155
+ className: "size-0.5 shrink-0 rounded-full bg-current"
156
+ }
157
+ ),
158
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: segment })
159
+ ] }, index))
160
+ }
161
+ )
162
+ ]
163
+ }
164
+ );
165
+ }
166
+
167
+ export { CellText, TableCell, tableCellVariants };
@@ -0,0 +1,66 @@
1
+ import { cn } from './chunk-7EOSDFS3.js';
2
+ import { CheckIcon } from '@phosphor-icons/react';
3
+ import { cva } from 'class-variance-authority';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ var checkboxVariants = cva([
7
+ // Box — 20×20 (`size-5`), 2px radius (Figma `radius/xs`), 1px border.
8
+ // `peer` lets the sibling indicator react to :checked / :disabled.
9
+ "peer size-5 shrink-0 appearance-none rounded-xs border",
10
+ "cursor-pointer transition-colors",
11
+ // Default
12
+ "bg-background border-border",
13
+ // Hover (unselected) — focus keeps the DEFAULT border; only the ring signals
14
+ // focus (so focus doesn't visually read as hover).
15
+ "hover:border-border-accent",
16
+ // Focus ring — suppress the native ring, draw the shared `--focus` ring the
17
+ // same way ghost Button does: 2px stroke, 2px offset (`outline-solid`
18
+ // restores what `outline-none` zeroed).
19
+ "outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-solid focus-visible:outline-focus",
20
+ // Selected
21
+ "checked:bg-brand-primary-background checked:border-brand-primary-border",
22
+ "checked:hover:bg-brand-primary-accent checked:hover:border-brand-primary-border",
23
+ "checked:focus-visible:bg-brand-primary-accent checked:focus-visible:border-brand-primary-border",
24
+ // Disabled — shared neutral-muted look whether selected or not (per Figma)
25
+ "disabled:pointer-events-none disabled:cursor-not-allowed disabled:border-border-muted",
26
+ "checked:disabled:bg-background checked:disabled:border-border-muted"
27
+ ]);
28
+ function Checkbox({
29
+ className,
30
+ wrapperClassName,
31
+ onChange,
32
+ onCheckedChange,
33
+ ...props
34
+ }) {
35
+ const handleChange = (event) => {
36
+ onChange?.(event);
37
+ onCheckedChange?.(event.currentTarget.checked);
38
+ };
39
+ return /* @__PURE__ */ jsxs("span", { className: cn("relative inline-flex shrink-0", wrapperClassName), children: [
40
+ /* @__PURE__ */ jsx(
41
+ "input",
42
+ {
43
+ type: "checkbox",
44
+ "data-slot": "checkbox",
45
+ className: cn(checkboxVariants(), className),
46
+ ...props,
47
+ onChange: handleChange
48
+ }
49
+ ),
50
+ /* @__PURE__ */ jsx(
51
+ CheckIcon,
52
+ {
53
+ "aria-hidden": "true",
54
+ weight: "regular",
55
+ "data-slot": "checkbox-indicator",
56
+ className: cn(
57
+ "pointer-events-none invisible absolute inset-0 m-auto size-4",
58
+ "text-brand-primary-foreground",
59
+ "peer-checked:visible peer-disabled:text-foreground-muted"
60
+ )
61
+ }
62
+ )
63
+ ] });
64
+ }
65
+
66
+ export { Checkbox, checkboxVariants };
@@ -0,0 +1,99 @@
1
+ import { cn } from './chunk-7EOSDFS3.js';
2
+ import { cva } from 'class-variance-authority';
3
+ import { jsx, jsxs } from 'react/jsx-runtime';
4
+
5
+ var propertyGridCellVariants = cva(
6
+ [
7
+ // Layout — 40px row, single line, slots on a horizontal axis.
8
+ "flex h-10 min-w-0 items-center gap-1 py-3",
9
+ // Type — Archivo 14/20.
10
+ "body-03"
11
+ ],
12
+ {
13
+ variants: {
14
+ variant: {
15
+ title: "justify-start text-card-foreground-muted",
16
+ content: "justify-end text-card-foreground"
17
+ }
18
+ },
19
+ defaultVariants: {
20
+ variant: "title"
21
+ }
22
+ }
23
+ );
24
+ var propertyGridItemVariants = cva(["grid grid-cols-2"], {
25
+ variants: {
26
+ last: {
27
+ false: "border-b border-card-border",
28
+ true: ""
29
+ }
30
+ },
31
+ defaultVariants: {
32
+ last: false
33
+ }
34
+ });
35
+ function PropertyGridItem({
36
+ className,
37
+ last = false,
38
+ children,
39
+ ref,
40
+ ...props
41
+ }) {
42
+ return /* @__PURE__ */ jsx(
43
+ "div",
44
+ {
45
+ "data-slot": "property-grid-item",
46
+ className: cn(propertyGridItemVariants({ last }), className),
47
+ ref,
48
+ ...props,
49
+ children
50
+ }
51
+ );
52
+ }
53
+ function PropertyGridCell({
54
+ variant,
55
+ className,
56
+ leading,
57
+ trailing,
58
+ children,
59
+ ref,
60
+ ...props
61
+ }) {
62
+ const slotClass = "flex shrink-0 items-center text-card-foreground-muted [&_svg]:size-4";
63
+ return /* @__PURE__ */ jsxs(
64
+ "div",
65
+ {
66
+ "data-slot": `property-grid-${variant}`,
67
+ className: cn(propertyGridCellVariants({ variant }), className),
68
+ ref,
69
+ ...props,
70
+ children: [
71
+ leading != null && /* @__PURE__ */ jsx(
72
+ "span",
73
+ {
74
+ "data-slot": `property-grid-${variant}-leading`,
75
+ className: slotClass,
76
+ children: leading
77
+ }
78
+ ),
79
+ children != null && /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children }),
80
+ trailing != null && /* @__PURE__ */ jsx(
81
+ "span",
82
+ {
83
+ "data-slot": `property-grid-${variant}-trailing`,
84
+ className: slotClass,
85
+ children: trailing
86
+ }
87
+ )
88
+ ]
89
+ }
90
+ );
91
+ }
92
+ function PropertyGridTitle(props) {
93
+ return /* @__PURE__ */ jsx(PropertyGridCell, { variant: "title", ...props });
94
+ }
95
+ function PropertyGridContent(props) {
96
+ return /* @__PURE__ */ jsx(PropertyGridCell, { variant: "content", ...props });
97
+ }
98
+
99
+ export { PropertyGridContent, PropertyGridItem, PropertyGridTitle, propertyGridCellVariants, propertyGridItemVariants };
@@ -0,0 +1,66 @@
1
+ import { cn } from './chunk-7EOSDFS3.js';
2
+ import { CircleIcon } from '@phosphor-icons/react';
3
+ import { cva } from 'class-variance-authority';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ var radioVariants = cva([
7
+ // Circle — 20×20 (`size-5`), fully round (Figma `radius/full`), 1px border.
8
+ // `peer` lets the sibling indicator react to :checked / :disabled.
9
+ "peer size-5 shrink-0 appearance-none rounded-full border",
10
+ "cursor-pointer transition-colors",
11
+ // Default
12
+ "bg-background border-border",
13
+ // Hover (unselected) — focus keeps the DEFAULT border; only the ring signals
14
+ // focus (so focus doesn't visually read as hover).
15
+ "hover:border-border-accent",
16
+ // Focus ring — suppress the native ring, draw the shared `--focus` ring the
17
+ // same way Checkbox and ghost Button do: 2px stroke, 2px offset
18
+ // (`outline-solid` restores what `outline-none` zeroed).
19
+ "outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-solid focus-visible:outline-focus",
20
+ // Selected
21
+ "checked:bg-brand-primary-background checked:border-brand-primary-border",
22
+ "checked:hover:bg-brand-primary-accent checked:hover:border-brand-primary-border",
23
+ "checked:focus-visible:bg-brand-primary-accent checked:focus-visible:border-brand-primary-border",
24
+ // Disabled — shared neutral-muted look whether selected or not (per Figma)
25
+ "disabled:pointer-events-none disabled:cursor-not-allowed disabled:border-border-muted",
26
+ "checked:disabled:bg-background checked:disabled:border-border-muted"
27
+ ]);
28
+ function Radio({
29
+ className,
30
+ wrapperClassName,
31
+ onChange,
32
+ onCheckedChange,
33
+ ...props
34
+ }) {
35
+ const handleChange = (event) => {
36
+ onChange?.(event);
37
+ onCheckedChange?.(event.currentTarget.checked);
38
+ };
39
+ return /* @__PURE__ */ jsxs("span", { className: cn("relative inline-flex shrink-0", wrapperClassName), children: [
40
+ /* @__PURE__ */ jsx(
41
+ "input",
42
+ {
43
+ type: "radio",
44
+ "data-slot": "radio",
45
+ className: cn(radioVariants(), className),
46
+ ...props,
47
+ onChange: handleChange
48
+ }
49
+ ),
50
+ /* @__PURE__ */ jsx(
51
+ CircleIcon,
52
+ {
53
+ "aria-hidden": "true",
54
+ weight: "fill",
55
+ "data-slot": "radio-indicator",
56
+ className: cn(
57
+ "pointer-events-none invisible absolute inset-0 m-auto size-3",
58
+ "text-brand-primary-foreground",
59
+ "peer-checked:visible peer-disabled:text-foreground-muted"
60
+ )
61
+ }
62
+ )
63
+ ] });
64
+ }
65
+
66
+ export { Radio, radioVariants };
@@ -0,0 +1,264 @@
1
+ import { cn } from './chunk-7EOSDFS3.js';
2
+ import * as React from 'react';
3
+ import { cva } from 'class-variance-authority';
4
+ import { jsx } from 'react/jsx-runtime';
5
+
6
+ var tabsRootVariants = cva(["flex flex-col"]);
7
+ var tabsListVariants = cva(["inline-flex items-center"]);
8
+ var tabsTriggerVariants = cva(
9
+ [
10
+ "group inline-flex cursor-pointer items-center justify-center gap-1 px-2 py-2.5",
11
+ "body-03-medium border-b-2 transition-colors",
12
+ "outline-none focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus",
13
+ "[&_svg]:size-4 [&_svg]:shrink-0",
14
+ "disabled:cursor-not-allowed"
15
+ ],
16
+ {
17
+ variants: {
18
+ selected: {
19
+ true: "border-card-brand-border-accent text-foreground-accent",
20
+ false: "border-transparent text-foreground"
21
+ },
22
+ disabled: {
23
+ true: "text-foreground-muted",
24
+ false: ""
25
+ }
26
+ },
27
+ compoundVariants: [
28
+ // Unselected + enabled: faint underline on hover, purple text+underline
29
+ // while pressed (Figma hover / active states).
30
+ {
31
+ selected: false,
32
+ disabled: false,
33
+ className: "hover:border-card-brand-border active:border-card-brand-border-accent active:text-foreground-accent"
34
+ },
35
+ // Selected + disabled: the underline drops from accent to the faint token
36
+ // (Figma disabled-selected). Wins over the accent border from
37
+ // `selected:true` because compound variants are appended last.
38
+ {
39
+ selected: true,
40
+ disabled: true,
41
+ className: "border-card-brand-border"
42
+ }
43
+ ],
44
+ defaultVariants: {
45
+ selected: false,
46
+ disabled: false
47
+ }
48
+ }
49
+ );
50
+ var tabsContentVariants = cva([
51
+ "outline-none focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus"
52
+ ]);
53
+ var TabsContext = React.createContext(null);
54
+ function useTabsContext(part) {
55
+ const context = React.useContext(TabsContext);
56
+ if (context === null) {
57
+ throw new Error(`${part} must be used within <Tabs.Root>`);
58
+ }
59
+ return context;
60
+ }
61
+ function setRef(ref, node) {
62
+ if (typeof ref === "function") ref(node);
63
+ else if (ref) ref.current = node;
64
+ }
65
+ function TabsRoot({
66
+ value: valueProp,
67
+ defaultValue,
68
+ onValueChange,
69
+ className,
70
+ children,
71
+ ref,
72
+ ...props
73
+ }) {
74
+ const isControlled = valueProp !== void 0;
75
+ const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue);
76
+ const value = isControlled ? valueProp : uncontrolledValue;
77
+ const select = (next) => {
78
+ if (!isControlled) setUncontrolledValue(next);
79
+ onValueChange?.(next);
80
+ };
81
+ const baseId = React.useId();
82
+ const getTriggerId = (tabValue) => `${baseId}-tab-${tabValue}`;
83
+ const getPanelId = (tabValue) => `${baseId}-panel-${tabValue}`;
84
+ const [triggers, setTriggers] = React.useState([]);
85
+ const registerTrigger = React.useCallback((registration) => {
86
+ setTriggers((prev) => {
87
+ const existing = prev.findIndex((t) => t.value === registration.value);
88
+ if (existing === -1) return [...prev, registration];
89
+ const next = [...prev];
90
+ next[existing] = registration;
91
+ return next;
92
+ });
93
+ }, []);
94
+ const unregisterTrigger = React.useCallback((tabValue) => {
95
+ setTriggers((prev) => prev.filter((t) => t.value !== tabValue));
96
+ }, []);
97
+ const domOrdered = [...triggers].sort(
98
+ (a, b) => a.node.compareDocumentPosition(b.node) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1
99
+ );
100
+ const firstEnabled = domOrdered.find((t) => !t.disabled)?.value;
101
+ const tabStopValue = value ?? firstEnabled;
102
+ const onTriggerKeyDown = (event) => {
103
+ if (!["ArrowRight", "ArrowLeft", "Home", "End"].includes(event.key)) return;
104
+ const enabled = domOrdered.filter((t) => !t.disabled);
105
+ if (enabled.length === 0) return;
106
+ const currentIndex = enabled.findIndex(
107
+ (t) => t.node === event.currentTarget
108
+ );
109
+ if (currentIndex === -1) return;
110
+ event.preventDefault();
111
+ let nextIndex = currentIndex;
112
+ switch (event.key) {
113
+ case "ArrowRight":
114
+ nextIndex = (currentIndex + 1) % enabled.length;
115
+ break;
116
+ case "ArrowLeft":
117
+ nextIndex = (currentIndex - 1 + enabled.length) % enabled.length;
118
+ break;
119
+ case "Home":
120
+ nextIndex = 0;
121
+ break;
122
+ case "End":
123
+ nextIndex = enabled.length - 1;
124
+ break;
125
+ }
126
+ const target = enabled[nextIndex];
127
+ if (!target) return;
128
+ target.node.focus();
129
+ select(target.value);
130
+ };
131
+ const contextValue = {
132
+ value,
133
+ select,
134
+ tabStopValue,
135
+ registerTrigger,
136
+ unregisterTrigger,
137
+ onTriggerKeyDown,
138
+ getTriggerId,
139
+ getPanelId
140
+ };
141
+ return /* @__PURE__ */ jsx(TabsContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
142
+ "div",
143
+ {
144
+ ref,
145
+ "data-slot": "tabs",
146
+ className: cn(tabsRootVariants(), className),
147
+ ...props,
148
+ children
149
+ }
150
+ ) });
151
+ }
152
+ function TabsList({ className, children, ref, ...props }) {
153
+ useTabsContext("Tabs.List");
154
+ return /* @__PURE__ */ jsx(
155
+ "div",
156
+ {
157
+ ref,
158
+ role: "tablist",
159
+ "data-slot": "tabs-list",
160
+ className: cn(tabsListVariants(), className),
161
+ ...props,
162
+ children
163
+ }
164
+ );
165
+ }
166
+ function TabsTrigger({
167
+ value,
168
+ disabled = false,
169
+ className,
170
+ children,
171
+ onClick,
172
+ onKeyDown,
173
+ ref,
174
+ ...props
175
+ }) {
176
+ const {
177
+ value: selectedValue,
178
+ select,
179
+ tabStopValue,
180
+ registerTrigger,
181
+ unregisterTrigger,
182
+ onTriggerKeyDown,
183
+ getTriggerId,
184
+ getPanelId
185
+ } = useTabsContext("Tabs.Trigger");
186
+ const selected = value === selectedValue;
187
+ const triggerId = getTriggerId(value);
188
+ const panelId = getPanelId(value);
189
+ const buttonRef = React.useRef(null);
190
+ const setButtonRef = (node) => {
191
+ buttonRef.current = node;
192
+ setRef(ref, node);
193
+ };
194
+ React.useEffect(() => {
195
+ const node = buttonRef.current;
196
+ if (!node) return;
197
+ registerTrigger({ value, disabled, node });
198
+ return () => unregisterTrigger(value);
199
+ }, [registerTrigger, unregisterTrigger, value, disabled]);
200
+ return /* @__PURE__ */ jsx(
201
+ "button",
202
+ {
203
+ ...props,
204
+ ref: setButtonRef,
205
+ type: "button",
206
+ role: "tab",
207
+ id: triggerId,
208
+ "data-slot": "tabs-trigger",
209
+ "data-state": selected ? "active" : "inactive",
210
+ "data-disabled": disabled || void 0,
211
+ "aria-selected": selected,
212
+ "aria-controls": selected ? panelId : void 0,
213
+ tabIndex: value === tabStopValue ? 0 : -1,
214
+ disabled,
215
+ className: cn(tabsTriggerVariants({ selected, disabled }), className),
216
+ onClick: (event) => {
217
+ onClick?.(event);
218
+ if (!event.defaultPrevented) select(value);
219
+ },
220
+ onKeyDown: (event) => {
221
+ onKeyDown?.(event);
222
+ if (!event.defaultPrevented) onTriggerKeyDown(event);
223
+ },
224
+ children
225
+ }
226
+ );
227
+ }
228
+ function TabsContent({
229
+ value,
230
+ className,
231
+ children,
232
+ ref,
233
+ ...props
234
+ }) {
235
+ const {
236
+ value: selectedValue,
237
+ getTriggerId,
238
+ getPanelId
239
+ } = useTabsContext("Tabs.Content");
240
+ if (value !== selectedValue) return null;
241
+ return /* @__PURE__ */ jsx(
242
+ "div",
243
+ {
244
+ ref,
245
+ role: "tabpanel",
246
+ id: getPanelId(value),
247
+ "aria-labelledby": getTriggerId(value),
248
+ "data-slot": "tabs-content",
249
+ "data-state": "active",
250
+ tabIndex: 0,
251
+ className: cn(tabsContentVariants(), className),
252
+ ...props,
253
+ children
254
+ }
255
+ );
256
+ }
257
+ var Tabs = {
258
+ Root: TabsRoot,
259
+ List: TabsList,
260
+ Trigger: TabsTrigger,
261
+ Content: TabsContent
262
+ };
263
+
264
+ export { Tabs, TabsContent, TabsList, TabsRoot, TabsTrigger, tabsContentVariants, tabsListVariants, tabsRootVariants, tabsTriggerVariants };