@kanzo-tech/ui 0.11.0 → 0.13.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 (104) hide show
  1. package/dist/analytics.d.ts +1 -0
  2. package/dist/analytics.d.ts.map +1 -1
  3. package/dist/charts/chart-inputs.d.ts +6 -5
  4. package/dist/charts/chart-inputs.d.ts.map +1 -1
  5. package/dist/charts/chart-inputs.js +78 -77
  6. package/dist/charts/chart-inputs.js.map +1 -1
  7. package/dist/charts/chart-marks.d.ts +2 -1
  8. package/dist/charts/chart-marks.d.ts.map +1 -1
  9. package/dist/charts/chart-marks.js.map +1 -1
  10. package/dist/charts/chart-root.d.ts +8 -3
  11. package/dist/charts/chart-root.d.ts.map +1 -1
  12. package/dist/charts/chart-root.js +60 -60
  13. package/dist/charts/chart-root.js.map +1 -1
  14. package/dist/charts/chart-spec.d.ts +11 -4
  15. package/dist/charts/chart-spec.d.ts.map +1 -1
  16. package/dist/charts/chart-spec.js +44 -40
  17. package/dist/charts/chart-spec.js.map +1 -1
  18. package/dist/charts/chart-stat.d.ts +3 -2
  19. package/dist/charts/chart-stat.d.ts.map +1 -1
  20. package/dist/charts/chart-stat.js +10 -9
  21. package/dist/charts/chart-stat.js.map +1 -1
  22. package/dist/composites/language-picker.d.ts +51 -0
  23. package/dist/composites/language-picker.d.ts.map +1 -0
  24. package/dist/composites/language-picker.js +165 -0
  25. package/dist/composites/language-picker.js.map +1 -0
  26. package/dist/index.d.ts +8 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +687 -677
  29. package/dist/index.js.map +1 -1
  30. package/dist/lib/control-size.d.ts +26 -0
  31. package/dist/lib/control-size.d.ts.map +1 -0
  32. package/dist/lib/control-size.js +11 -0
  33. package/dist/lib/control-size.js.map +1 -0
  34. package/dist/lib/use-async-collection.d.ts +57 -0
  35. package/dist/lib/use-async-collection.d.ts.map +1 -0
  36. package/dist/lib/use-async-collection.js +43 -0
  37. package/dist/lib/use-async-collection.js.map +1 -0
  38. package/dist/lib/use-debounced-commit.d.ts +28 -0
  39. package/dist/lib/use-debounced-commit.d.ts.map +1 -0
  40. package/dist/lib/use-debounced-commit.js +26 -0
  41. package/dist/lib/use-debounced-commit.js.map +1 -0
  42. package/dist/shark-parity.divergences.d.ts.map +1 -1
  43. package/dist/simples/button.d.ts.map +1 -1
  44. package/dist/simples/button.js +34 -33
  45. package/dist/simples/button.js.map +1 -1
  46. package/dist/simples/checkbox.d.ts.map +1 -1
  47. package/dist/simples/checkbox.js +42 -42
  48. package/dist/simples/checkbox.js.map +1 -1
  49. package/dist/simples/combobox.d.ts.map +1 -1
  50. package/dist/simples/combobox.js +48 -49
  51. package/dist/simples/combobox.js.map +1 -1
  52. package/dist/simples/date-picker.d.ts +58 -2
  53. package/dist/simples/date-picker.d.ts.map +1 -1
  54. package/dist/simples/date-picker.js +210 -73
  55. package/dist/simples/date-picker.js.map +1 -1
  56. package/dist/simples/field.d.ts +35 -2
  57. package/dist/simples/field.d.ts.map +1 -1
  58. package/dist/simples/field.js +146 -116
  59. package/dist/simples/field.js.map +1 -1
  60. package/dist/simples/input-group.d.ts +9 -9
  61. package/dist/simples/input-group.d.ts.map +1 -1
  62. package/dist/simples/input-group.js +68 -78
  63. package/dist/simples/input-group.js.map +1 -1
  64. package/dist/simples/input.d.ts +9 -9
  65. package/dist/simples/input.d.ts.map +1 -1
  66. package/dist/simples/input.js +13 -14
  67. package/dist/simples/input.js.map +1 -1
  68. package/dist/simples/locale.d.ts +4 -0
  69. package/dist/simples/locale.d.ts.map +1 -0
  70. package/dist/simples/locale.js +8 -0
  71. package/dist/simples/locale.js.map +1 -0
  72. package/dist/simples/native-select.d.ts +9 -9
  73. package/dist/simples/native-select.d.ts.map +1 -1
  74. package/dist/simples/native-select.js +29 -28
  75. package/dist/simples/native-select.js.map +1 -1
  76. package/dist/simples/number-input.d.ts +9 -9
  77. package/dist/simples/number-input.d.ts.map +1 -1
  78. package/dist/simples/number-input.js +27 -27
  79. package/dist/simples/number-input.js.map +1 -1
  80. package/dist/simples/password-input.d.ts.map +1 -1
  81. package/dist/simples/password-input.js +24 -20
  82. package/dist/simples/password-input.js.map +1 -1
  83. package/dist/simples/pin-input.d.ts +9 -9
  84. package/dist/simples/pin-input.d.ts.map +1 -1
  85. package/dist/simples/pin-input.js +30 -29
  86. package/dist/simples/pin-input.js.map +1 -1
  87. package/dist/simples/radio-group.d.ts.map +1 -1
  88. package/dist/simples/radio-group.js +44 -43
  89. package/dist/simples/radio-group.js.map +1 -1
  90. package/dist/simples/segment-group.d.ts +8 -0
  91. package/dist/simples/segment-group.d.ts.map +1 -1
  92. package/dist/simples/segment-group.js +66 -52
  93. package/dist/simples/segment-group.js.map +1 -1
  94. package/dist/simples/switch.d.ts.map +1 -1
  95. package/dist/simples/switch.js +18 -12
  96. package/dist/simples/switch.js.map +1 -1
  97. package/dist/simples/tags-input.d.ts.map +1 -1
  98. package/dist/simples/tags-input.js +44 -39
  99. package/dist/simples/tags-input.js.map +1 -1
  100. package/dist/simples/toggle.d.ts +9 -9
  101. package/dist/simples/toggle.d.ts.map +1 -1
  102. package/dist/simples/toggle.js +24 -23
  103. package/dist/simples/toggle.js.map +1 -1
  104. package/package.json +5 -5
@@ -1,12 +1,13 @@
1
1
  "use client";
2
- import { jsx as s } from "react/jsx-runtime";
3
- import { ark as p } from "@ark-ui/react/factory";
4
- import { tv as l } from "tailwind-variants";
2
+ import { jsx as n } from "react/jsx-runtime";
3
+ import { ark as l } from "@ark-ui/react/factory";
4
+ import { tv as p } from "tailwind-variants";
5
5
  import { cn as o } from "../lib/cn.js";
6
- import { Button as c } from "./button.js";
7
- import { Input as g } from "./input.js";
8
- import { Textarea as m } from "./textarea.js";
9
- const b = l({
6
+ import { controlSizes as c, controlMinHeight as g } from "../lib/control-size.js";
7
+ import { Button as m } from "./button.js";
8
+ import { Input as b } from "./input.js";
9
+ import { Textarea as f } from "./textarea.js";
10
+ const h = p({
10
11
  base: [
11
12
  "group/input-group",
12
13
  "relative",
@@ -15,24 +16,20 @@ const b = l({
15
16
  "bg-background bg-field",
16
17
  "rounded-lg border border-input shadow-xs/5",
17
18
  "transition-[color,box-shadow]",
18
- // **The group holds its controls; it does not press them against its border.**
19
+ // **One height, the shared one — see `lib/control-size.ts`.** A group is `min-h-(--size)`
20
+ // rather than `h-(--size)` because it also holds a `Textarea` and the two block addons, and
21
+ // those grow it; what it may never do is come out TALLER than an `Input` beside it because of
22
+ // what it holds. It did, by 14px: the `<input>` inside carried its own `h-8` and the group added
23
+ // `p-1.5` around it, so a group at `md` measured 46px against an input's 32 — measured
24
+ // 2026-09-30 on `/docs/forms/controls`, along with every control built on a group (combobox,
25
+ // date picker, password input, language picker).
19
26
  //
20
- // The height used to be fixed — `h-8` at `md`, a border-box 32px with 1px of border — while
21
- // `InputGroupButton`'s `icon-sm` is `size-8`, also 32px. A fixed box cannot contain a control
22
- // its own size, so the ✨ painted over the border a pixel above and below, and two at `sm`.
23
- // Measured on `/docs/ai/fields`.
24
- //
25
- // Sizing the control down instead was tried and rejected on sight: it made the ✨ a different
26
- // size here than the identical mark inside a `TagsInput`, which is the same component doing
27
- // the same job. **`TagsInput` is the shape, and it is now literally the same one** — `p-1.5`
28
- // around a `min-h-*` box, so the group grows to whatever it holds and every control keeps the
29
- // size it has everywhere else. A group holding a 32px mark measures 46px, exactly as
30
- // `TagsInputControl` does.
31
- //
32
- // The input's own `px-3` is replaced by `px-1.5` so the group's padding and the field's do not
33
- // add up: 1px of border plus 6px of padding plus 6px is the 13px of inset the fixed-height
34
- // version had, unchanged.
35
- "[&>input]:px-1.5 [&>textarea]:px-1.5",
27
+ // So the `<input>` inside does not carry a height of its own: it stretches to the group's
28
+ // content box (`InputGroupInput`), and the controls beside it are 24px (`InputGroupButton`),
29
+ // which leaves a 32px group 4px of inset around them, and there is no padding to add to it: at
30
+ // `sm` and compact density the group is 24.5px, and a 24px control plus the border already
31
+ // asks 26. That one case is the exception the pressable floor buys (see `InputGroupButton`).
32
+ g,
36
33
  "has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3",
37
34
  "has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3",
38
35
  "outline-none focus-within:border-primary focus-within:ring-[3px] focus-within:ring-ring",
@@ -41,37 +38,24 @@ const b = l({
41
38
  "motion-reduce:transition-none!"
42
39
  ],
43
40
  variants: {
44
- // `min-h`, not `h`: the box is sized by what it holds, and this is the floor it starts from.
45
- // A fixed height is what made a control the same size as the group overflow it.
46
- //
47
- // **The padding is what the size axis now moves, and it has to be.** A content-sized box whose
48
- // size variant only sets a floor is a size variant that does nothing: every group came out
49
- // 46px — `sm`, `md` and `lg` alike — because the `<input>` inside carries its own `h-8` and
50
- // that plus the padding cleared every floor. Measured on `/docs/forms/input-group`. Scaling
51
- // the inset instead keeps the controls identical across the three, which is the whole point of
52
- // this shape: an ✨ is the same ✨ in a small group, a large one and a `TagsInput`.
53
- size: {
54
- sm: ["min-h-7", "p-1"],
55
- md: ["min-h-8", "p-1.5"],
56
- lg: ["min-h-9", "p-2"]
57
- }
41
+ size: c
58
42
  },
59
43
  defaultVariants: {
60
44
  size: "md"
61
45
  }
62
- }), y = (r) => {
63
- const { size: t = "md", className: a, slot: e, ...n } = r;
64
- return /* @__PURE__ */ s(
65
- p.div,
46
+ }), j = (r) => {
47
+ const { size: t = "md", className: a, slot: e, ...s } = r;
48
+ return /* @__PURE__ */ n(
49
+ l.div,
66
50
  {
67
- className: o(b({ size: t }), a),
51
+ className: o(h({ size: t }), a),
68
52
  "data-size": t,
69
53
  role: "group",
70
- ...n,
54
+ ...s,
71
55
  "data-slot": e ?? "input-group"
72
56
  }
73
57
  );
74
- }, f = l({
58
+ }, v = p({
75
59
  base: [
76
60
  "h-auto",
77
61
  "flex items-center justify-center gap-2",
@@ -94,8 +78,8 @@ const b = l({
94
78
  // **A button needs no padding beside it — the group's own `p-1.5` is the inset**, and this
95
79
  // is what puts the ✨ the same distance from the border here as inside a `TagsInputControl`.
96
80
  // Text and a `kbd` still take theirs, because neither carries a box of its own.
97
- "inline-start": ["order-first ps-3", "has-[>button]:ps-0", "has-[>kbd]:ps-2"],
98
- "inline-end": ["order-last pe-3", "has-[>button]:pe-0", "has-[>kbd]:pe-2"],
81
+ "inline-start": ["order-first ps-3", "has-[>button]:ps-0.75", "has-[>kbd]:ps-2"],
82
+ "inline-end": ["order-last pe-3", "has-[>button]:pe-0.75", "has-[>kbd]:pe-2"],
99
83
  // The block padding lives on the two block aligns and nowhere else. It was `py-1.5` in the
100
84
  // base, which is right for a band across the field and wrong for a control tucked into its
101
85
  // end: measured on `docs/ai/fields`, an `inline-end` addon was **44px tall inside a 32px
@@ -117,23 +101,23 @@ const b = l({
117
101
  defaultVariants: {
118
102
  align: "inline-start"
119
103
  }
120
- }), I = (r) => {
121
- const { className: t, align: a = "inline-start", slot: e, ...n } = r;
122
- return /* @__PURE__ */ s(
123
- p.div,
104
+ }), T = (r) => {
105
+ const { className: t, align: a = "inline-start", slot: e, ...s } = r;
106
+ return /* @__PURE__ */ n(
107
+ l.div,
124
108
  {
125
- className: o(f({ align: a }), t),
109
+ className: o(v({ align: a }), t),
126
110
  "data-align": a,
127
111
  onClick: (i) => {
128
112
  var u, d;
129
113
  i.target.closest("button") || (d = (u = i.currentTarget.parentElement) == null ? void 0 : u.querySelector("input")) == null || d.focus();
130
114
  },
131
115
  role: "group",
132
- ...n,
116
+ ...s,
133
117
  "data-slot": e ?? "input-group-addon"
134
118
  }
135
119
  );
136
- }, h = l({
120
+ }, x = p({
137
121
  base: [
138
122
  "relative",
139
123
  "flex items-center gap-2",
@@ -156,37 +140,40 @@ const b = l({
156
140
  * the hit path. This is the one thing `Button` does not carry, and it is why the two were
157
141
  * decided separately rather than in one sweep.
158
142
  */
159
- sm: ["h-8", "gap-1.5", "px-2.5", "rounded-md", "has-[>svg]:px-2.5"],
160
- "icon-sm": ["size-8", "p-0", "has-[>svg]:p-0"]
143
+ // 24 CSS pixels, not `h-6`: a `rem` is 21px at compact, under the bar above, and this is the
144
+ // one size in a recipe that must not scale. Inside a group the bar and the group's own 28px
145
+ // at `sm` (24.5px at compact) are the same number, which is why 24 fits at every size.
146
+ sm: ["h-[24px]", "gap-1.5", "px-2.5", "rounded-md", "has-[>svg]:px-2.5"],
147
+ "icon-sm": ["size-[24px]", "p-0", "has-[>svg]:p-0"]
161
148
  }
162
149
  },
163
150
  defaultVariants: {
164
151
  size: "sm"
165
152
  }
166
- }), V = (r) => {
153
+ }), B = (r) => {
167
154
  const {
168
155
  className: t,
169
156
  type: a = "button",
170
157
  variant: e = "ghost",
171
- size: n = "sm",
158
+ size: s = "sm",
172
159
  slot: i,
173
160
  ...u
174
161
  } = r;
175
- return /* @__PURE__ */ s(
176
- c,
162
+ return /* @__PURE__ */ n(
163
+ m,
177
164
  {
178
- className: o(h({ size: n }), t),
179
- "data-size": n,
165
+ className: o(x({ size: s }), t),
166
+ "data-size": s,
180
167
  type: a,
181
168
  variant: e,
182
169
  ...u,
183
170
  slot: i ?? "input-group-button"
184
171
  }
185
172
  );
186
- }, j = (r) => {
173
+ }, _ = (r) => {
187
174
  const { className: t, slot: a, ...e } = r;
188
- return /* @__PURE__ */ s(
189
- p.span,
175
+ return /* @__PURE__ */ n(
176
+ l.span,
190
177
  {
191
178
  className: o(
192
179
  "flex items-center gap-2",
@@ -198,13 +185,16 @@ const b = l({
198
185
  "data-slot": a ?? "input-group-text"
199
186
  }
200
187
  );
201
- }, T = (r) => {
188
+ }, A = (r) => {
202
189
  const { className: t, slot: a, ...e } = r;
203
- return /* @__PURE__ */ s(
204
- g,
190
+ return /* @__PURE__ */ n(
191
+ b,
205
192
  {
206
193
  className: o(
207
- "flex-1",
194
+ // `h-auto self-stretch`: the group's height, not the input's own. An `Input` is
195
+ // `h-(--size)` and its size is its own, so inside a group of another size it would be a
196
+ // different height from the box around it.
197
+ "h-auto flex-1 self-stretch",
208
198
  "bg-transparent",
209
199
  "rounded-none border-0 shadow-none",
210
200
  "focus-visible:ring-0",
@@ -215,10 +205,10 @@ const b = l({
215
205
  slot: a ?? "input-group-control"
216
206
  }
217
207
  );
218
- }, B = (r) => {
208
+ }, S = (r) => {
219
209
  const { className: t, slot: a, ...e } = r;
220
- return /* @__PURE__ */ s(
221
- m,
210
+ return /* @__PURE__ */ n(
211
+ f,
222
212
  {
223
213
  className: o(
224
214
  "flex-1",
@@ -235,11 +225,11 @@ const b = l({
235
225
  );
236
226
  };
237
227
  export {
238
- y as InputGroup,
239
- I as InputGroupAddon,
240
- V as InputGroupButton,
241
- T as InputGroupInput,
242
- j as InputGroupText,
243
- B as InputGroupTextarea
228
+ j as InputGroup,
229
+ T as InputGroupAddon,
230
+ B as InputGroupButton,
231
+ A as InputGroupInput,
232
+ _ as InputGroupText,
233
+ S as InputGroupTextarea
244
234
  };
245
235
  //# sourceMappingURL=input-group.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"input-group.js","sources":["../../src/simples/input-group.tsx"],"sourcesContent":["\"use client\";\n\nimport { ark } from \"@ark-ui/react/factory\";\nimport type React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { cn } from \"../lib/cn\";\nimport { Button } from \"./button\";\nimport { Input } from \"./input\";\nimport { Textarea } from \"./textarea\";\n\nconst inpuGroupVariants = tv({\n base: [\n \"group/input-group\",\n \"relative\",\n \"w-full min-w-0\",\n \"flex items-center\",\n \"bg-background bg-field\",\n \"rounded-lg border border-input shadow-xs/5\",\n \"transition-[color,box-shadow]\",\n // **The group holds its controls; it does not press them against its border.**\n //\n // The height used to be fixed — `h-8` at `md`, a border-box 32px with 1px of border — while\n // `InputGroupButton`'s `icon-sm` is `size-8`, also 32px. A fixed box cannot contain a control\n // its own size, so the ✨ painted over the border a pixel above and below, and two at `sm`.\n // Measured on `/docs/ai/fields`.\n //\n // Sizing the control down instead was tried and rejected on sight: it made the ✨ a different\n // size here than the identical mark inside a `TagsInput`, which is the same component doing\n // the same job. **`TagsInput` is the shape, and it is now literally the same one** — `p-1.5`\n // around a `min-h-*` box, so the group grows to whatever it holds and every control keeps the\n // size it has everywhere else. A group holding a 32px mark measures 46px, exactly as\n // `TagsInputControl` does.\n //\n // The input's own `px-3` is replaced by `px-1.5` so the group's padding and the field's do not\n // add up: 1px of border plus 6px of padding plus 6px is the 13px of inset the fixed-height\n // version had, unchanged.\n \"[&>input]:px-1.5 [&>textarea]:px-1.5\",\n \"has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3\",\n \"has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3\",\n \"outline-none focus-within:border-primary focus-within:ring-[3px] focus-within:ring-ring\",\n \"has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-[3px] has-[[data-slot][aria-invalid=true]]:ring-destructive/24\",\n \"dark:has-[[data-slot][aria-invalid=true]]:border-destructive-foreground dark:has-[[data-slot][aria-invalid=true]]:ring-destructive-foreground/40\",\n \"motion-reduce:transition-none!\",\n ],\n variants: {\n // `min-h`, not `h`: the box is sized by what it holds, and this is the floor it starts from.\n // A fixed height is what made a control the same size as the group overflow it.\n //\n // **The padding is what the size axis now moves, and it has to be.** A content-sized box whose\n // size variant only sets a floor is a size variant that does nothing: every group came out\n // 46px — `sm`, `md` and `lg` alike — because the `<input>` inside carries its own `h-8` and\n // that plus the padding cleared every floor. Measured on `/docs/forms/input-group`. Scaling\n // the inset instead keeps the controls identical across the three, which is the whole point of\n // this shape: an ✨ is the same ✨ in a small group, a large one and a `TagsInput`.\n size: {\n sm: [\"min-h-7\", \"p-1\"],\n md: [\"min-h-8\", \"p-1.5\"],\n lg: [\"min-h-9\", \"p-2\"],\n },\n },\n defaultVariants: {\n size: \"md\",\n },\n});\n\nexport interface InputGroupProps\n extends React.ComponentProps<typeof ark.div>,\n VariantProps<typeof inpuGroupVariants> {}\n\nexport const InputGroup = (props: InputGroupProps) => {\n const { size = \"md\", className, slot, ...rest } = props;\n\n return (\n <ark.div\n className={cn(inpuGroupVariants({ size }), className)}\n data-size={size}\n role=\"group\"\n {...rest}\n data-slot={slot ?? \"input-group\"}\n />\n );\n};\n\nconst inputGroupAddonVariants = tv({\n base: [\n \"h-auto\",\n \"flex items-center justify-center gap-2\",\n \"select-none font-medium text-muted-foreground text-sm\",\n \"cursor-text\",\n \"group-data-[disabled=true]/input-group:opacity-64\",\n \"[&>kbd]:rounded-[calc(var(--radius)-5px)]\",\n \"[&_svg:not([class*='size-'])]:size-4\",\n ],\n variants: {\n align: {\n // **A smaller padding, not a negative margin**, and this is a measured divergence from the\n // reference rather than a taste one. Shark tucks the button in with `pe-3` plus\n // `me-[-0.45rem]`; a negative margin on the last flex item lets its border box run past the\n // container's content edge, so measured live on `docs/ai/fields` the addon sat **6.2px\n // outside the group's inline border and 6px outside its block border** — in a box with\n // `overflow: visible`, which is why it also showed up as 6px of scroll width on the parent.\n // The inner gap is what was wanted and it is unchanged: 12px of padding minus 7.2px of\n // margin is the 6px this sets directly.\n // **A button needs no padding beside it — the group's own `p-1.5` is the inset**, and this\n // is what puts the ✨ the same distance from the border here as inside a `TagsInputControl`.\n // Text and a `kbd` still take theirs, because neither carries a box of its own.\n \"inline-start\": [\"order-first ps-3\", \"has-[>button]:ps-0\", \"has-[>kbd]:ps-2\"],\n \"inline-end\": [\"order-last pe-3\", \"has-[>button]:pe-0\", \"has-[>kbd]:pe-2\"],\n // The block padding lives on the two block aligns and nowhere else. It was `py-1.5` in the\n // base, which is right for a band across the field and wrong for a control tucked into its\n // end: measured on `docs/ai/fields`, an `inline-end` addon was **44px tall inside a 32px\n // group** — 6px of transparent padding past the border on each side, in a box with\n // `overflow: visible`. The mark inside it is `size-8` and looked fine; what was wrong was the\n // group's own box.\n \"block-start\": [\n \"order-first w-full justify-start px-3 pt-3 pb-1.5\",\n \"group-has-[>input]/input-group:pt-2.5\",\n \"[.border-b]:pb-3\",\n ],\n \"block-end\": [\n \"order-last w-full justify-start px-3 pt-1.5 pb-3\",\n \"group-has-[>input]/input-group:pb-2.5\",\n \"[.border-t]:pt-3\",\n ],\n },\n },\n defaultVariants: {\n align: \"inline-start\",\n },\n});\n\ninterface InputGroupAddonProps\n extends React.ComponentProps<typeof ark.div>,\n VariantProps<typeof inputGroupAddonVariants> {}\n\nexport const InputGroupAddon = (props: InputGroupAddonProps) => {\n const { className, align = \"inline-start\", slot, ...rest } = props;\n\n return (\n <ark.div\n className={cn(inputGroupAddonVariants({ align }), className)}\n data-align={align}\n onClick={(e) => {\n if ((e.target as HTMLElement).closest(\"button\")) {\n return;\n }\n e.currentTarget.parentElement?.querySelector(\"input\")?.focus();\n }}\n role=\"group\"\n {...rest}\n data-slot={slot ?? \"input-group-addon\"}\n />\n );\n};\n\nconst inputGroupButtonVariants = tv({\n base: [\n \"relative\",\n \"flex items-center gap-2\",\n \"text-sm\",\n \"shadow-none\",\n \"pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 pointer-coarse:after:min-w-11\",\n ],\n variants: {\n size: {\n /**\n * The floor, and the default, because there is nothing legal below it.\n *\n * `xs` and `icon-xs` were `1.5rem`, which is 24px at the default root and **21px at compact** —\n * every size here is a `rem` against a root the density axis sets. That is under the 24×24\n * WCAG 2.5.8 states in CSS pixels, and it was this component's DEFAULT, so an input group\n * that said nothing got the failing size.\n *\n * The `pointer-coarse` hit area below does not save it. 44px is the touch answer and 2.5.8\n * asks about pointers generally: with a mouse the target was 21px and the `::after` is not in\n * the hit path. This is the one thing `Button` does not carry, and it is why the two were\n * decided separately rather than in one sweep.\n */\n sm: [\"h-8\", \"gap-1.5\", \"px-2.5\", \"rounded-md\", \"has-[>svg]:px-2.5\"],\n \"icon-sm\": [\"size-8\", \"p-0\", \"has-[>svg]:p-0\"],\n },\n },\n defaultVariants: {\n size: \"sm\",\n },\n});\n\ninterface InputGroupButtonProps\n extends Omit<React.ComponentProps<typeof Button>, \"size\">,\n VariantProps<typeof inputGroupButtonVariants> {}\n\nexport const InputGroupButton = (props: InputGroupButtonProps) => {\n const {\n className,\n type = \"button\",\n variant = \"ghost\",\n size = \"sm\",\n slot,\n ...rest\n } = props;\n\n return (\n <Button\n className={cn(inputGroupButtonVariants({ size }), className)}\n data-size={size}\n type={type}\n variant={variant}\n {...rest}\n slot={slot ?? \"input-group-button\"}\n />\n );\n};\n\nexport const InputGroupText = (\n props: React.ComponentProps<typeof ark.span>\n) => {\n const { className, slot, ...rest } = props;\n\n return (\n <ark.span\n className={cn(\n \"flex items-center gap-2\",\n \"text-muted-foreground text-sm\",\n \"[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"input-group-text\"}\n />\n );\n};\n\nexport const InputGroupInput = (props: React.ComponentProps<typeof Input>) => {\n const { className, slot, ...rest } = props;\n\n return (\n <Input\n className={cn(\n \"flex-1\",\n \"bg-transparent\",\n \"rounded-none border-0 shadow-none\",\n \"focus-visible:ring-0\",\n \"disabled:bg-transparent aria-invalid:ring-0 data-invalid:ring-0\",\n className\n )}\n {...rest}\n slot={slot ?? \"input-group-control\"}\n />\n );\n};\n\nexport const InputGroupTextarea = (\n props: React.ComponentProps<typeof Textarea>\n) => {\n const { className, slot, ...rest } = props;\n\n return (\n <Textarea\n className={cn(\n \"flex-1\",\n \"py-3\",\n \"bg-transparent\",\n \"resize-none rounded-none border-0 shadow-none\",\n \"focus-visible:ring-0\",\n \"disabled:bg-transparent aria-invalid:ring-0 data-invalid:ring-0\",\n className\n )}\n {...rest}\n slot={slot ?? \"input-group-control\"}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;;AAUA;AAA6B;AACrB;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUF;AACiB;AACE;AACF;AAAA;AACvB;AAEe;AACT;AAEV;AAOE;AAEA;AACE;AAAK;AAAJ;AACqD;AACzC;AACN;AACD;AACe;AAAA;AAGzB;AAEmC;AAC3B;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEQ;AACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYuE;AACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAO1D;AACb;AACA;AACA;AAAA;AAEW;AACX;AACA;AACA;AAAA;AACF;AACF;AAEe;AACR;AAEX;AAOE;AAEA;AACE;AAAK;AAAJ;AAC4D;AAC/C;;AAEV;AAGuD;AACzD;AACK;AACD;AACe;AAAA;AAGzB;AAEoC;AAC5B;AACJ;AACA;AACA;AACA;AACA;AAAA;AAEQ;AACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAc8D;AACrB;AAAA;AAC/C;AAEe;AACT;AAEV;AAOE;AAAM;AACJ;AACO;AACG;AACH;AACP;AACG;AAGL;AACE;AAAC;AAAA;AAC4D;AAChD;AACX;AACA;AACI;AACU;AAAA;AAGpB;AAKE;AAEA;AACE;AAAK;AAAJ;AACY;AACT;AACA;AACA;AACA;AAAA;AAEE;AACe;AAAA;AAGzB;AAGE;AAEA;AACE;AAAC;AAAA;AACY;AACT;AACA;AACA;AACA;AACA;AACQ;AAAA;AAEN;AACU;AAAA;AAGpB;AAKE;AAEA;AACE;AAAC;AAAA;AACY;AACT;AACA;AACA;AACA;AACA;AACA;AACQ;AAAA;AAEN;AACU;AAAA;AAGpB;;;;;;;;;"}
1
+ {"version":3,"file":"input-group.js","sources":["../../src/simples/input-group.tsx"],"sourcesContent":["\"use client\";\n\nimport { ark } from \"@ark-ui/react/factory\";\nimport type React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { cn } from \"../lib/cn\";\nimport { controlMinHeight, controlSizes } from \"../lib/control-size\";\nimport { Button } from \"./button\";\nimport { Input } from \"./input\";\nimport { Textarea } from \"./textarea\";\n\nconst inpuGroupVariants = tv({\n base: [\n \"group/input-group\",\n \"relative\",\n \"w-full min-w-0\",\n \"flex items-center\",\n \"bg-background bg-field\",\n \"rounded-lg border border-input shadow-xs/5\",\n \"transition-[color,box-shadow]\",\n // **One height, the shared one — see `lib/control-size.ts`.** A group is `min-h-(--size)`\n // rather than `h-(--size)` because it also holds a `Textarea` and the two block addons, and\n // those grow it; what it may never do is come out TALLER than an `Input` beside it because of\n // what it holds. It did, by 14px: the `<input>` inside carried its own `h-8` and the group added\n // `p-1.5` around it, so a group at `md` measured 46px against an input's 32 — measured\n // 2026-09-30 on `/docs/forms/controls`, along with every control built on a group (combobox,\n // date picker, password input, language picker).\n //\n // So the `<input>` inside does not carry a height of its own: it stretches to the group's\n // content box (`InputGroupInput`), and the controls beside it are 24px (`InputGroupButton`),\n // which leaves a 32px group 4px of inset around them, and there is no padding to add to it: at\n // `sm` and compact density the group is 24.5px, and a 24px control plus the border already\n // asks 26. That one case is the exception the pressable floor buys (see `InputGroupButton`).\n controlMinHeight,\n \"has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3\",\n \"has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3\",\n \"outline-none focus-within:border-primary focus-within:ring-[3px] focus-within:ring-ring\",\n \"has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-[3px] has-[[data-slot][aria-invalid=true]]:ring-destructive/24\",\n \"dark:has-[[data-slot][aria-invalid=true]]:border-destructive-foreground dark:has-[[data-slot][aria-invalid=true]]:ring-destructive-foreground/40\",\n \"motion-reduce:transition-none!\",\n ],\n variants: {\n size: controlSizes,\n },\n defaultVariants: {\n size: \"md\",\n },\n});\n\nexport interface InputGroupProps\n extends React.ComponentProps<typeof ark.div>,\n VariantProps<typeof inpuGroupVariants> {}\n\nexport const InputGroup = (props: InputGroupProps) => {\n const { size = \"md\", className, slot, ...rest } = props;\n\n return (\n <ark.div\n className={cn(inpuGroupVariants({ size }), className)}\n data-size={size}\n role=\"group\"\n {...rest}\n data-slot={slot ?? \"input-group\"}\n />\n );\n};\n\nconst inputGroupAddonVariants = tv({\n base: [\n \"h-auto\",\n \"flex items-center justify-center gap-2\",\n \"select-none font-medium text-muted-foreground text-sm\",\n \"cursor-text\",\n \"group-data-[disabled=true]/input-group:opacity-64\",\n \"[&>kbd]:rounded-[calc(var(--radius)-5px)]\",\n \"[&_svg:not([class*='size-'])]:size-4\",\n ],\n variants: {\n align: {\n // **A smaller padding, not a negative margin**, and this is a measured divergence from the\n // reference rather than a taste one. Shark tucks the button in with `pe-3` plus\n // `me-[-0.45rem]`; a negative margin on the last flex item lets its border box run past the\n // container's content edge, so measured live on `docs/ai/fields` the addon sat **6.2px\n // outside the group's inline border and 6px outside its block border** — in a box with\n // `overflow: visible`, which is why it also showed up as 6px of scroll width on the parent.\n // The inner gap is what was wanted and it is unchanged: 12px of padding minus 7.2px of\n // margin is the 6px this sets directly.\n // **A button needs no padding beside it — the group's own `p-1.5` is the inset**, and this\n // is what puts the ✨ the same distance from the border here as inside a `TagsInputControl`.\n // Text and a `kbd` still take theirs, because neither carries a box of its own.\n \"inline-start\": [\"order-first ps-3\", \"has-[>button]:ps-0.75\", \"has-[>kbd]:ps-2\"],\n \"inline-end\": [\"order-last pe-3\", \"has-[>button]:pe-0.75\", \"has-[>kbd]:pe-2\"],\n // The block padding lives on the two block aligns and nowhere else. It was `py-1.5` in the\n // base, which is right for a band across the field and wrong for a control tucked into its\n // end: measured on `docs/ai/fields`, an `inline-end` addon was **44px tall inside a 32px\n // group** — 6px of transparent padding past the border on each side, in a box with\n // `overflow: visible`. The mark inside it is `size-8` and looked fine; what was wrong was the\n // group's own box.\n \"block-start\": [\n \"order-first w-full justify-start px-3 pt-3 pb-1.5\",\n \"group-has-[>input]/input-group:pt-2.5\",\n \"[.border-b]:pb-3\",\n ],\n \"block-end\": [\n \"order-last w-full justify-start px-3 pt-1.5 pb-3\",\n \"group-has-[>input]/input-group:pb-2.5\",\n \"[.border-t]:pt-3\",\n ],\n },\n },\n defaultVariants: {\n align: \"inline-start\",\n },\n});\n\ninterface InputGroupAddonProps\n extends React.ComponentProps<typeof ark.div>,\n VariantProps<typeof inputGroupAddonVariants> {}\n\nexport const InputGroupAddon = (props: InputGroupAddonProps) => {\n const { className, align = \"inline-start\", slot, ...rest } = props;\n\n return (\n <ark.div\n className={cn(inputGroupAddonVariants({ align }), className)}\n data-align={align}\n onClick={(e) => {\n if ((e.target as HTMLElement).closest(\"button\")) {\n return;\n }\n e.currentTarget.parentElement?.querySelector(\"input\")?.focus();\n }}\n role=\"group\"\n {...rest}\n data-slot={slot ?? \"input-group-addon\"}\n />\n );\n};\n\nconst inputGroupButtonVariants = tv({\n base: [\n \"relative\",\n \"flex items-center gap-2\",\n \"text-sm\",\n \"shadow-none\",\n \"pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 pointer-coarse:after:min-w-11\",\n ],\n variants: {\n size: {\n /**\n * The floor, and the default, because there is nothing legal below it.\n *\n * `xs` and `icon-xs` were `1.5rem`, which is 24px at the default root and **21px at compact** —\n * every size here is a `rem` against a root the density axis sets. That is under the 24×24\n * WCAG 2.5.8 states in CSS pixels, and it was this component's DEFAULT, so an input group\n * that said nothing got the failing size.\n *\n * The `pointer-coarse` hit area below does not save it. 44px is the touch answer and 2.5.8\n * asks about pointers generally: with a mouse the target was 21px and the `::after` is not in\n * the hit path. This is the one thing `Button` does not carry, and it is why the two were\n * decided separately rather than in one sweep.\n */\n // 24 CSS pixels, not `h-6`: a `rem` is 21px at compact, under the bar above, and this is the\n // one size in a recipe that must not scale. Inside a group the bar and the group's own 28px\n // at `sm` (24.5px at compact) are the same number, which is why 24 fits at every size.\n sm: [\"h-[24px]\", \"gap-1.5\", \"px-2.5\", \"rounded-md\", \"has-[>svg]:px-2.5\"],\n \"icon-sm\": [\"size-[24px]\", \"p-0\", \"has-[>svg]:p-0\"],\n },\n },\n defaultVariants: {\n size: \"sm\",\n },\n});\n\ninterface InputGroupButtonProps\n extends Omit<React.ComponentProps<typeof Button>, \"size\">,\n VariantProps<typeof inputGroupButtonVariants> {}\n\nexport const InputGroupButton = (props: InputGroupButtonProps) => {\n const {\n className,\n type = \"button\",\n variant = \"ghost\",\n size = \"sm\",\n slot,\n ...rest\n } = props;\n\n return (\n <Button\n className={cn(inputGroupButtonVariants({ size }), className)}\n data-size={size}\n type={type}\n variant={variant}\n {...rest}\n slot={slot ?? \"input-group-button\"}\n />\n );\n};\n\nexport const InputGroupText = (\n props: React.ComponentProps<typeof ark.span>\n) => {\n const { className, slot, ...rest } = props;\n\n return (\n <ark.span\n className={cn(\n \"flex items-center gap-2\",\n \"text-muted-foreground text-sm\",\n \"[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none\",\n className\n )}\n {...rest}\n data-slot={slot ?? \"input-group-text\"}\n />\n );\n};\n\nexport const InputGroupInput = (props: React.ComponentProps<typeof Input>) => {\n const { className, slot, ...rest } = props;\n\n return (\n <Input\n className={cn(\n // `h-auto self-stretch`: the group's height, not the input's own. An `Input` is\n // `h-(--size)` and its size is its own, so inside a group of another size it would be a\n // different height from the box around it.\n \"h-auto flex-1 self-stretch\",\n \"bg-transparent\",\n \"rounded-none border-0 shadow-none\",\n \"focus-visible:ring-0\",\n \"disabled:bg-transparent aria-invalid:ring-0 data-invalid:ring-0\",\n className\n )}\n {...rest}\n slot={slot ?? \"input-group-control\"}\n />\n );\n};\n\nexport const InputGroupTextarea = (\n props: React.ComponentProps<typeof Textarea>\n) => {\n const { className, slot, ...rest } = props;\n\n return (\n <Textarea\n className={cn(\n \"flex-1\",\n \"py-3\",\n \"bg-transparent\",\n \"resize-none rounded-none border-0 shadow-none\",\n \"focus-visible:ring-0\",\n \"disabled:bg-transparent aria-invalid:ring-0 data-invalid:ring-0\",\n className\n )}\n {...rest}\n slot={slot ?? \"input-group-control\"}\n />\n );\n};\n"],"names":[],"mappings":";;;;;;;;;AAWA;AAA6B;AACrB;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEQ;AACF;AAAA;AAES;AACT;AAEV;AAOE;AAEA;AACE;AAAK;AAAJ;AACqD;AACzC;AACN;AACD;AACe;AAAA;AAGzB;AAEmC;AAC3B;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEQ;AACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAY0E;AACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAO7D;AACb;AACA;AACA;AAAA;AAEW;AACX;AACA;AACA;AAAA;AACF;AACF;AAEe;AACR;AAEX;AAOE;AAEA;AACE;AAAK;AAAJ;AAC4D;AAC/C;;AAEV;AAGuD;AACzD;AACK;AACD;AACe;AAAA;AAGzB;AAEoC;AAC5B;AACJ;AACA;AACA;AACA;AACA;AAAA;AAEQ;AACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBmE;AACrB;AAAA;AACpD;AAEe;AACT;AAEV;AAOE;AAAM;AACJ;AACO;AACG;AACH;AACP;AACG;AAGL;AACE;AAAC;AAAA;AAC4D;AAChD;AACX;AACA;AACI;AACU;AAAA;AAGpB;AAKE;AAEA;AACE;AAAK;AAAJ;AACY;AACT;AACA;AACA;AACA;AAAA;AAEE;AACe;AAAA;AAGzB;AAGE;AAEA;AACE;AAAC;AAAA;AACY;AAAA;AAAA;AAAA;AAIT;AACA;AACA;AACA;AACA;AACQ;AAAA;AAEN;AACU;AAAA;AAGpB;AAKE;AAEA;AACE;AAAC;AAAA;AACY;AACT;AACA;AACA;AACA;AACA;AACA;AACQ;AAAA;AAEN;AACU;AAAA;AAGpB;;;;;;;;;"}
@@ -3,21 +3,21 @@ import { default as React } from 'react';
3
3
  import { VariantProps } from 'tailwind-variants';
4
4
  export declare const inputVariants: import('tailwind-variants').TVReturnType<{
5
5
  size: {
6
- sm: string[];
7
- md: string[];
8
- lg: string[];
6
+ sm: "[--size:calc(var(--size-field)*7)]";
7
+ md: "[--size:calc(var(--size-field)*8)]";
8
+ lg: "[--size:calc(var(--size-field)*9)]";
9
9
  };
10
10
  }, undefined, string[], {
11
11
  size: {
12
- sm: string[];
13
- md: string[];
14
- lg: string[];
12
+ sm: "[--size:calc(var(--size-field)*7)]";
13
+ md: "[--size:calc(var(--size-field)*8)]";
14
+ lg: "[--size:calc(var(--size-field)*9)]";
15
15
  };
16
16
  }, undefined, import('tailwind-variants').TVReturnType<{
17
17
  size: {
18
- sm: string[];
19
- md: string[];
20
- lg: string[];
18
+ sm: "[--size:calc(var(--size-field)*7)]";
19
+ md: "[--size:calc(var(--size-field)*8)]";
20
+ lg: "[--size:calc(var(--size-field)*9)]";
21
21
  };
22
22
  }, undefined, string[], unknown, unknown, undefined>>;
23
23
  export interface InputProps extends Omit<React.ComponentProps<typeof FieldInput>, "size">, VariantProps<typeof inputVariants> {
@@ -1 +1 @@
1
- {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/simples/input.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAM,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAG1D,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;qDAsCxB,CAAC;AAEH,MAAM,WAAW,UACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,UAAU,CAAC,EAAE,MAAM,CAAC,EAC3D,YAAY,CAAC,OAAO,aAAa,CAAC;CAAG;AAEzC,eAAO,MAAM,KAAK,GAAI,OAAO,UAAU,sBAYtC,CAAC"}
1
+ {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/simples/input.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAM,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAI1D,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;qDAoCxB,CAAC;AAEH,MAAM,WAAW,UACf,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,UAAU,CAAC,EAAE,MAAM,CAAC,EAC3D,YAAY,CAAC,OAAO,aAAa,CAAC;CAAG;AAEzC,eAAO,MAAM,KAAK,GAAI,OAAO,UAAU,sBAYtC,CAAC"}
@@ -1,12 +1,13 @@
1
- import { jsx as n } from "react/jsx-runtime";
2
- import { FieldInput as s } from "@ark-ui/react/field";
3
- import { tv as o } from "tailwind-variants";
1
+ import { jsx as d } from "react/jsx-runtime";
2
+ import { FieldInput as n } from "@ark-ui/react/field";
3
+ import { tv as s } from "tailwind-variants";
4
4
  import { cn as l } from "../lib/cn.js";
5
- const c = o({
5
+ import { controlSizes as u, controlHeight as f } from "../lib/control-size.js";
6
+ const c = s({
6
7
  base: [
7
8
  "peer",
8
9
  // On the base, not on the size — see `button.tsx`.
9
- "h-(--size)",
10
+ f,
10
11
  "w-full min-w-0",
11
12
  "px-3",
12
13
  "bg-field",
@@ -32,29 +33,27 @@ const c = o({
32
33
  ],
33
34
  variants: {
34
35
  size: {
35
- sm: ["[--size:calc(var(--size-field)*7)]"],
36
- md: ["[--size:calc(var(--size-field)*8)]"],
37
- lg: ["[--size:calc(var(--size-field)*9)]"]
36
+ ...u
38
37
  }
39
38
  },
40
39
  defaultVariants: {
41
40
  size: "md"
42
41
  }
43
- }), p = (e) => {
44
- const { size: i = "md", type: t = "text", className: r, slot: a, ...d } = e;
45
- return /* @__PURE__ */ n(
46
- s,
42
+ }), g = (e) => {
43
+ const { size: i = "md", type: t = "text", className: r, slot: a, ...o } = e;
44
+ return /* @__PURE__ */ d(
45
+ n,
47
46
  {
48
47
  className: l(c({ size: i }), r),
49
48
  "data-size": i,
50
49
  type: t,
51
- ...d,
50
+ ...o,
52
51
  "data-slot": a ?? "input"
53
52
  }
54
53
  );
55
54
  };
56
55
  export {
57
- p as Input,
56
+ g as Input,
58
57
  c as inputVariants
59
58
  };
60
59
  //# sourceMappingURL=input.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"input.js","sources":["../../src/simples/input.tsx"],"sourcesContent":["import { FieldInput } from \"@ark-ui/react/field\";\nimport type React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { cn } from \"../lib/cn\";\n\nexport const inputVariants = tv({\n base: [\n \"peer\",\n // On the base, not on the size — see `button.tsx`.\n \"h-(--size)\",\n \"w-full min-w-0\",\n \"px-3\",\n \"bg-field\",\n \"text-base md:text-sm\",\n \"rounded-field border border-input shadow-xs/5\",\n \"placeholder:text-faint\",\n \"file:inline-flex file:h-7 file:items-center file:border-0\",\n \"file:font-medium file:text-foreground file:text-sm\",\n \"transition-[color,box-shadow]\",\n \"outline-none focus-visible:border-primary focus-visible:ring-[3px] focus-visible:ring-ring\",\n \"aria-invalid:border-destructive aria-invalid:text-destructive-foreground aria-invalid:ring-[3px] aria-invalid:ring-destructive/24\",\n \"data-invalid:border-destructive data-invalid:text-destructive-foreground data-invalid:ring-[3px] data-invalid:ring-destructive/24\",\n // The dark branch is TEXT only, and this is the site the other eleven recipes point at.\n // Shark repaints the border and the ring here too; measured across all six compiled documents,\n // `--destructive` reads 4.15:1 against that document's own dark page — over the 3:1 WCAG 1.4.11\n // asks of the visual information identifying a control or its state, so the border and the ring\n // were buying a hue rather than contrast. Text owes AA's 4.5 and 4.15 misses it, so this half\n // stays.\n \"dark:aria-invalid:text-destructive-foreground\",\n \"dark:data-invalid:text-destructive-foreground\",\n \"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-64\",\n \"motion-reduce:transition-none!\",\n ],\n variants: {\n size: {\n sm: [\"[--size:calc(var(--size-field)*7)]\"],\n md: [\"[--size:calc(var(--size-field)*8)]\"],\n lg: [\"[--size:calc(var(--size-field)*9)]\"],\n },\n },\n defaultVariants: {\n size: \"md\",\n },\n});\n\nexport interface InputProps\n extends Omit<React.ComponentProps<typeof FieldInput>, \"size\">,\n VariantProps<typeof inputVariants> {}\n\nexport const Input = (props: InputProps) => {\n const { size = \"md\", type = \"text\", className, slot, ...rest } = props;\n\n return (\n <FieldInput\n className={cn(inputVariants({ size }), className)}\n data-size={size}\n type={type}\n {...rest}\n data-slot={slot ?? \"input\"}\n />\n );\n};\n"],"names":["inputVariants","tv","Input","props","size","type","className","slot","rest","jsx","FieldInput","cn"],"mappings":";;;;AAKO,MAAMA,IAAgBC,EAAG;AAAA,EAC9B,MAAM;AAAA,IACJ;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAAA,EAEF,UAAU;AAAA,IACR,MAAM;AAAA,MACJ,IAAI,CAAC,oCAAoC;AAAA,MACzC,IAAI,CAAC,oCAAoC;AAAA,MACzC,IAAI,CAAC,oCAAoC;AAAA,IAAA;AAAA,EAC3C;AAAA,EAEF,iBAAiB;AAAA,IACf,MAAM;AAAA,EAAA;AAEV,CAAC,GAMYC,IAAQ,CAACC,MAAsB;AAC1C,QAAM,EAAE,MAAAC,IAAO,MAAM,MAAAC,IAAO,QAAQ,WAAAC,GAAW,MAAAC,GAAM,GAAGC,EAAA,IAASL;AAEjE,SACE,gBAAAM;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,WAAWC,EAAGX,EAAc,EAAE,MAAAI,EAAA,CAAM,GAAGE,CAAS;AAAA,MAChD,aAAWF;AAAA,MACX,MAAAC;AAAA,MACC,GAAGG;AAAA,MACJ,aAAWD,KAAQ;AAAA,IAAA;AAAA,EAAA;AAGzB;"}
1
+ {"version":3,"file":"input.js","sources":["../../src/simples/input.tsx"],"sourcesContent":["import { FieldInput } from \"@ark-ui/react/field\";\nimport type React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { cn } from \"../lib/cn\";\nimport { controlHeight, controlSizes } from \"../lib/control-size\";\n\nexport const inputVariants = tv({\n base: [\n \"peer\",\n // On the base, not on the size — see `button.tsx`.\n controlHeight,\n \"w-full min-w-0\",\n \"px-3\",\n \"bg-field\",\n \"text-base md:text-sm\",\n \"rounded-field border border-input shadow-xs/5\",\n \"placeholder:text-faint\",\n \"file:inline-flex file:h-7 file:items-center file:border-0\",\n \"file:font-medium file:text-foreground file:text-sm\",\n \"transition-[color,box-shadow]\",\n \"outline-none focus-visible:border-primary focus-visible:ring-[3px] focus-visible:ring-ring\",\n \"aria-invalid:border-destructive aria-invalid:text-destructive-foreground aria-invalid:ring-[3px] aria-invalid:ring-destructive/24\",\n \"data-invalid:border-destructive data-invalid:text-destructive-foreground data-invalid:ring-[3px] data-invalid:ring-destructive/24\",\n // The dark branch is TEXT only, and this is the site the other eleven recipes point at.\n // Shark repaints the border and the ring here too; measured across all six compiled documents,\n // `--destructive` reads 4.15:1 against that document's own dark page — over the 3:1 WCAG 1.4.11\n // asks of the visual information identifying a control or its state, so the border and the ring\n // were buying a hue rather than contrast. Text owes AA's 4.5 and 4.15 misses it, so this half\n // stays.\n \"dark:aria-invalid:text-destructive-foreground\",\n \"dark:data-invalid:text-destructive-foreground\",\n \"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-64\",\n \"motion-reduce:transition-none!\",\n ],\n variants: {\n size: {\n ...controlSizes,\n },\n },\n defaultVariants: {\n size: \"md\",\n },\n});\n\nexport interface InputProps\n extends Omit<React.ComponentProps<typeof FieldInput>, \"size\">,\n VariantProps<typeof inputVariants> {}\n\nexport const Input = (props: InputProps) => {\n const { size = \"md\", type = \"text\", className, slot, ...rest } = props;\n\n return (\n <FieldInput\n className={cn(inputVariants({ size }), className)}\n data-size={size}\n type={type}\n {...rest}\n data-slot={slot ?? \"input\"}\n />\n );\n};\n"],"names":["inputVariants","tv","controlHeight","controlSizes","Input","props","size","type","className","slot","rest","jsx","FieldInput","cn"],"mappings":";;;;;AAMO,MAAMA,IAAgBC,EAAG;AAAA,EAC9B,MAAM;AAAA,IACJ;AAAA;AAAA,IAEAC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAAA,EAEF,UAAU;AAAA,IACR,MAAM;AAAA,MACJ,GAAGC;AAAA,IAAA;AAAA,EACL;AAAA,EAEF,iBAAiB;AAAA,IACf,MAAM;AAAA,EAAA;AAEV,CAAC,GAMYC,IAAQ,CAACC,MAAsB;AAC1C,QAAM,EAAE,MAAAC,IAAO,MAAM,MAAAC,IAAO,QAAQ,WAAAC,GAAW,MAAAC,GAAM,GAAGC,EAAA,IAASL;AAEjE,SACE,gBAAAM;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,WAAWC,EAAGb,EAAc,EAAE,MAAAM,EAAA,CAAM,GAAGE,CAAS;AAAA,MAChD,aAAWF;AAAA,MACX,MAAAC;AAAA,MACC,GAAGG;AAAA,MACJ,aAAWD,KAAQ;AAAA,IAAA;AAAA,EAAA;AAGzB;"}
@@ -0,0 +1,4 @@
1
+ import { LocaleProvider as ArkLocaleProvider } from '@ark-ui/react/locale';
2
+ export declare const LocaleProvider: (props: React.ComponentProps<typeof ArkLocaleProvider>) => import("react").JSX.Element;
3
+ export declare const useLocale: () => import('@ark-ui/react').UseLocaleContext;
4
+ //# sourceMappingURL=locale.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../src/simples/locale.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,IAAI,iBAAiB,EAEpC,MAAM,sBAAsB,CAAC;AAO9B,eAAO,MAAM,cAAc,GACzB,OAAO,KAAK,CAAC,cAAc,CAAC,OAAO,iBAAiB,CAAC,gCAClB,CAAC;AAGtC,eAAO,MAAM,SAAS,gDAAmB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { jsx as e } from "react/jsx-runtime";
2
+ import { useLocaleContext as r, LocaleProvider as c } from "@ark-ui/react/locale";
3
+ const s = (o) => /* @__PURE__ */ e(c, { ...o }), i = r;
4
+ export {
5
+ s as LocaleProvider,
6
+ i as useLocale
7
+ };
8
+ //# sourceMappingURL=locale.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale.js","sources":["../../src/simples/locale.tsx"],"sourcesContent":["import {\n LocaleProvider as ArkLocaleProvider,\n useLocaleContext,\n} from \"@ark-ui/react/locale\";\n\n// Transparent, like `ClientOnly`: Ark's provider renders `children` and no element, so there is no\n// DOM node to slot. What it sets is the `locale` and `dir` every Ark machine below it formats and\n// mirrors by — `Format`, `DatePicker`, `useFilter`, the number and date inputs — which is why a\n// product that is not in `en-US` puts one at its root. It translates nothing: the words a\n// component draws are props on the component, written by the host.\nexport const LocaleProvider = (\n props: React.ComponentProps<typeof ArkLocaleProvider>\n) => <ArkLocaleProvider {...props} />;\n\n// Shark's name for Ark's `useLocaleContext`, by the same rule as every other context alias here.\nexport const useLocale = useLocaleContext;\n"],"names":["LocaleProvider","props","jsx","ArkLocaleProvider","useLocale","useLocaleContext"],"mappings":";;AAUO,MAAMA,IAAiB,CAC5BC,MACG,gBAAAC,EAACC,GAAA,EAAmB,GAAGF,EAAA,CAAO,GAGtBG,IAAYC;"}
@@ -4,21 +4,21 @@ import { default as React } from 'react';
4
4
  import { VariantProps } from 'tailwind-variants';
5
5
  export declare const nativeSelectVariants: import('tailwind-variants').TVReturnType<{
6
6
  size: {
7
- sm: string[];
8
- md: string[];
9
- lg: string[];
7
+ sm: "[--size:calc(var(--size-field)*7)]";
8
+ md: "[--size:calc(var(--size-field)*8)]";
9
+ lg: "[--size:calc(var(--size-field)*9)]";
10
10
  };
11
11
  }, undefined, string[], {
12
12
  size: {
13
- sm: string[];
14
- md: string[];
15
- lg: string[];
13
+ sm: "[--size:calc(var(--size-field)*7)]";
14
+ md: "[--size:calc(var(--size-field)*8)]";
15
+ lg: "[--size:calc(var(--size-field)*9)]";
16
16
  };
17
17
  }, undefined, import('tailwind-variants').TVReturnType<{
18
18
  size: {
19
- sm: string[];
20
- md: string[];
21
- lg: string[];
19
+ sm: "[--size:calc(var(--size-field)*7)]";
20
+ md: "[--size:calc(var(--size-field)*8)]";
21
+ lg: "[--size:calc(var(--size-field)*9)]";
22
22
  };
23
23
  }, undefined, string[], unknown, unknown, undefined>>;
24
24
  interface NativeSelectProps extends Omit<React.ComponentProps<typeof ArkField.Select>, "size">, VariantProps<typeof nativeSelectVariants> {
@@ -1 +1 @@
1
- {"version":3,"file":"native-select.d.ts","sourceRoot":"","sources":["../../src/simples/native-select.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAC5C,OAAO,EAAE,KAAK,IAAI,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAM,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAG1D,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;qDA8B/B,CAAC;AAEH,UAAU,iBACR,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,EAChE,YAAY,CAAC,OAAO,oBAAoB,CAAC;IAC3C;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,YAAY,GAAI,OAAO,iBAAiB,sBA0BpD,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,mBAAmB,KAAK,CAAC,cAAc,CAAC,OAAO,GAAG,CAAC,MAAM,CAAC,sBACY,CAAC;AAEzE,eAAO,MAAM,oBAAoB,GAC/B,mBAAmB,KAAK,CAAC,cAAc,CAAC,OAAO,GAAG,CAAC,QAAQ,CAAC,sBACc,CAAC"}
1
+ {"version":3,"file":"native-select.d.ts","sourceRoot":"","sources":["../../src/simples/native-select.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAC5C,OAAO,EAAE,KAAK,IAAI,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAM,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAI1D,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;qDA8B/B,CAAC;AAEH,UAAU,iBACR,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,EAChE,YAAY,CAAC,OAAO,oBAAoB,CAAC;IAC3C;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,YAAY,GAAI,OAAO,iBAAiB,sBA0BpD,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,mBAAmB,KAAK,CAAC,cAAc,CAAC,OAAO,GAAG,CAAC,MAAM,CAAC,sBACY,CAAC;AAEzE,eAAO,MAAM,oBAAoB,GAC/B,mBAAmB,KAAK,CAAC,cAAc,CAAC,OAAO,GAAG,CAAC,QAAQ,CAAC,sBACc,CAAC"}
@@ -1,16 +1,19 @@
1
- import { jsxs as d, jsx as t } from "react/jsx-runtime";
2
- import { ark as s } from "@ark-ui/react/factory";
1
+ import { jsxs as d, jsx as i } from "react/jsx-runtime";
2
+ import { ark as a } from "@ark-ui/react/factory";
3
3
  import { Field as c } from "@ark-ui/react/field";
4
- import { ChevronsUpDownIcon as v } from "lucide-react";
5
- import { tv as p } from "tailwind-variants";
6
- import { cn as a } from "../lib/cn.js";
7
- const m = p({
4
+ import { ChevronsUpDownIcon as p } from "lucide-react";
5
+ import { tv as v } from "tailwind-variants";
6
+ import { cn as o } from "../lib/cn.js";
7
+ import { controlSizes as m, controlHeight as u } from "../lib/control-size.js";
8
+ const f = v({
8
9
  base: [
9
10
  "appearance-none",
10
11
  // On the base, not on the size — see `button.tsx`. The `h-7/8/9` these variants carried was a
11
12
  // second answer to the same question, and the one that ignored the density knob.
12
- "h-(--size)",
13
- "w-full min-w-0",
13
+ u,
14
+ // `block`: an inline-level select sits on a line box, and the wrapper measured 29px around a
15
+ // 28px `sm` — the descender room under the baseline.
16
+ "block w-full min-w-0",
14
17
  "ps-2.5 pe-8",
15
18
  "select-none text-sm",
16
19
  "bg-field",
@@ -26,52 +29,50 @@ const m = p({
26
29
  ],
27
30
  variants: {
28
31
  size: {
29
- sm: ["[--size:calc(var(--size-field)*7)]"],
30
- md: ["[--size:calc(var(--size-field)*8)]"],
31
- lg: ["[--size:calc(var(--size-field)*9)]"]
32
+ ...m
32
33
  }
33
34
  },
34
35
  defaultVariants: {
35
36
  size: "md"
36
37
  }
37
- }), h = (e) => {
38
- const { size: i = "md", invalid: o, className: r, slot: n, ...l } = e;
38
+ }), k = (e) => {
39
+ const { size: t = "md", invalid: r, className: n, slot: s, ...l } = e;
39
40
  return /* @__PURE__ */ d(
40
- s.div,
41
+ a.div,
41
42
  {
42
- className: a(
43
+ className: o(
43
44
  "relative w-fit",
44
45
  "has-[select:disabled]:opacity-64",
45
46
  "[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground",
46
- r
47
+ n
47
48
  ),
48
49
  "data-slot": "native-select-wrapper",
49
50
  children: [
50
- /* @__PURE__ */ t(
51
+ /* @__PURE__ */ i(
51
52
  c.Select,
52
53
  {
53
- "aria-invalid": o,
54
- className: a(m({ size: i })),
54
+ "aria-invalid": r,
55
+ className: o(f({ size: t })),
55
56
  ...l,
56
- "data-slot": n ?? "native-select"
57
+ "data-slot": s ?? "native-select"
57
58
  }
58
59
  ),
59
- /* @__PURE__ */ t(
60
- v,
60
+ /* @__PURE__ */ i(
61
+ p,
61
62
  {
62
63
  "aria-hidden": "true",
63
- className: a("absolute inset-e-2.5 top-1/2 -translate-y-1/2"),
64
+ className: o("absolute inset-e-2.5 top-1/2 -translate-y-1/2"),
64
65
  "data-slot": "native-select-icon"
65
66
  }
66
67
  )
67
68
  ]
68
69
  }
69
70
  );
70
- }, w = ({ slot: e, ...i }) => /* @__PURE__ */ t(s.option, { ...i, "data-slot": e ?? "native-select-option" }), N = ({ slot: e, ...i }) => /* @__PURE__ */ t(s.optgroup, { ...i, "data-slot": e ?? "native-select-optgroup" });
71
+ }, z = ({ slot: e, ...t }) => /* @__PURE__ */ i(a.option, { ...t, "data-slot": e ?? "native-select-option" }), _ = ({ slot: e, ...t }) => /* @__PURE__ */ i(a.optgroup, { ...t, "data-slot": e ?? "native-select-optgroup" });
71
72
  export {
72
- h as NativeSelect,
73
- N as NativeSelectOptGroup,
74
- w as NativeSelectOption,
75
- m as nativeSelectVariants
73
+ k as NativeSelect,
74
+ _ as NativeSelectOptGroup,
75
+ z as NativeSelectOption,
76
+ f as nativeSelectVariants
76
77
  };
77
78
  //# sourceMappingURL=native-select.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"native-select.js","sources":["../../src/simples/native-select.tsx"],"sourcesContent":["import { ark } from \"@ark-ui/react/factory\";\nimport { Field as ArkField } from \"@ark-ui/react/field\";\nimport { ChevronsUpDownIcon } from \"lucide-react\";\nimport type React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { cn } from \"../lib/cn\";\n\nexport const nativeSelectVariants = tv({\n base: [\n \"appearance-none\",\n // On the base, not on the size — see `button.tsx`. The `h-7/8/9` these variants carried was a\n // second answer to the same question, and the one that ignored the density knob.\n \"h-(--size)\",\n \"w-full min-w-0\",\n \"ps-2.5 pe-8\",\n \"select-none text-sm\",\n \"bg-field\",\n \"rounded-field border border-input shadow-xs/5\",\n \"transition-colors\",\n \"outline-none\",\n \"[&:has(option[value='']:checked)]:text-faint\",\n \"disabled:pointer-events-none disabled:cursor-not-allowed\",\n \"focus-visible:border-primary focus-visible:ring-[3px] focus-visible:ring-ring\",\n \"aria-invalid:border-destructive aria-invalid:ring-[3px] aria-invalid:ring-destructive/24\",\n \"dark:aria-invalid:text-destructive-foreground\",\n \"motion-reduce:transition-none!\",\n ],\n variants: {\n size: {\n sm: [\"[--size:calc(var(--size-field)*7)]\"],\n md: [\"[--size:calc(var(--size-field)*8)]\"],\n lg: [\"[--size:calc(var(--size-field)*9)]\"],\n },\n },\n defaultVariants: {\n size: \"md\",\n },\n});\n\ninterface NativeSelectProps\n extends Omit<React.ComponentProps<typeof ArkField.Select>, \"size\">,\n VariantProps<typeof nativeSelectVariants> {\n /**\n * Whether the select is invalid.\n *\n * @default false\n */\n invalid?: boolean;\n}\n\nexport const NativeSelect = (props: NativeSelectProps) => {\n const { size = \"md\", invalid, className, slot, ...rest } = props;\n\n return (\n <ark.div\n className={cn(\n \"relative w-fit\",\n \"has-[select:disabled]:opacity-64\",\n \"[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground\",\n className\n )}\n data-slot=\"native-select-wrapper\"\n >\n <ArkField.Select\n aria-invalid={invalid}\n className={cn(nativeSelectVariants({ size }))}\n {...rest}\n data-slot={slot ?? \"native-select\"}\n />\n <ChevronsUpDownIcon\n aria-hidden=\"true\"\n className={cn(\"absolute inset-e-2.5 top-1/2 -translate-y-1/2\")}\n data-slot=\"native-select-icon\"\n />\n </ark.div>\n );\n};\n\nexport const NativeSelectOption = (\n { slot, ...rest }: React.ComponentProps<typeof ark.option>\n) => <ark.option {...rest} data-slot={slot ?? \"native-select-option\"} />;\n\nexport const NativeSelectOptGroup = (\n { slot, ...rest }: React.ComponentProps<typeof ark.optgroup>\n) => <ark.optgroup {...rest} data-slot={slot ?? \"native-select-optgroup\"} />;\n"],"names":["nativeSelectVariants","tv","NativeSelect","props","size","invalid","className","slot","rest","jsxs","ark","cn","jsx","ArkField","ChevronsUpDownIcon","NativeSelectOption","NativeSelectOptGroup"],"mappings":";;;;;;AAOO,MAAMA,IAAuBC,EAAG;AAAA,EACrC,MAAM;AAAA,IACJ;AAAA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAAA,EAEF,UAAU;AAAA,IACR,MAAM;AAAA,MACJ,IAAI,CAAC,oCAAoC;AAAA,MACzC,IAAI,CAAC,oCAAoC;AAAA,MACzC,IAAI,CAAC,oCAAoC;AAAA,IAAA;AAAA,EAC3C;AAAA,EAEF,iBAAiB;AAAA,IACf,MAAM;AAAA,EAAA;AAEV,CAAC,GAaYC,IAAe,CAACC,MAA6B;AACxD,QAAM,EAAE,MAAAC,IAAO,MAAM,SAAAC,GAAS,WAAAC,GAAW,MAAAC,GAAM,GAAGC,MAASL;AAE3D,SACE,gBAAAM;AAAA,IAACC,EAAI;AAAA,IAAJ;AAAA,MACC,WAAWC;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACAL;AAAA,MAAA;AAAA,MAEF,aAAU;AAAA,MAEV,UAAA;AAAA,QAAA,gBAAAM;AAAA,UAACC,EAAS;AAAA,UAAT;AAAA,YACC,gBAAcR;AAAA,YACd,WAAWM,EAAGX,EAAqB,EAAE,MAAAI,EAAA,CAAM,CAAC;AAAA,YAC3C,GAAGI;AAAA,YACJ,aAAWD,KAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,QAErB,gBAAAK;AAAA,UAACE;AAAA,UAAA;AAAA,YACC,eAAY;AAAA,YACZ,WAAWH,EAAG,+CAA+C;AAAA,YAC7D,aAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACZ;AAAA,IAAA;AAAA,EAAA;AAGN,GAEaI,IAAqB,CAChC,EAAE,MAAAR,GAAM,GAAGC,EAAA,MACR,gBAAAI,EAACF,EAAI,QAAJ,EAAY,GAAGF,GAAM,aAAWD,KAAQ,uBAAA,CAAwB,GAEzDS,IAAuB,CAClC,EAAE,MAAAT,GAAM,GAAGC,EAAA,MACR,gBAAAI,EAACF,EAAI,UAAJ,EAAc,GAAGF,GAAM,aAAWD,KAAQ,yBAAA,CAA0B;"}
1
+ {"version":3,"file":"native-select.js","sources":["../../src/simples/native-select.tsx"],"sourcesContent":["import { ark } from \"@ark-ui/react/factory\";\nimport { Field as ArkField } from \"@ark-ui/react/field\";\nimport { ChevronsUpDownIcon } from \"lucide-react\";\nimport type React from \"react\";\nimport { tv, type VariantProps } from \"tailwind-variants\";\nimport { cn } from \"../lib/cn\";\nimport { controlHeight, controlSizes } from \"../lib/control-size\";\n\nexport const nativeSelectVariants = tv({\n base: [\n \"appearance-none\",\n // On the base, not on the size — see `button.tsx`. The `h-7/8/9` these variants carried was a\n // second answer to the same question, and the one that ignored the density knob.\n controlHeight,\n // `block`: an inline-level select sits on a line box, and the wrapper measured 29px around a\n // 28px `sm` — the descender room under the baseline.\n \"block w-full min-w-0\",\n \"ps-2.5 pe-8\",\n \"select-none text-sm\",\n \"bg-field\",\n \"rounded-field border border-input shadow-xs/5\",\n \"transition-colors\",\n \"outline-none\",\n \"[&:has(option[value='']:checked)]:text-faint\",\n \"disabled:pointer-events-none disabled:cursor-not-allowed\",\n \"focus-visible:border-primary focus-visible:ring-[3px] focus-visible:ring-ring\",\n \"aria-invalid:border-destructive aria-invalid:ring-[3px] aria-invalid:ring-destructive/24\",\n \"dark:aria-invalid:text-destructive-foreground\",\n \"motion-reduce:transition-none!\",\n ],\n variants: {\n size: {\n ...controlSizes,\n },\n },\n defaultVariants: {\n size: \"md\",\n },\n});\n\ninterface NativeSelectProps\n extends Omit<React.ComponentProps<typeof ArkField.Select>, \"size\">,\n VariantProps<typeof nativeSelectVariants> {\n /**\n * Whether the select is invalid.\n *\n * @default false\n */\n invalid?: boolean;\n}\n\nexport const NativeSelect = (props: NativeSelectProps) => {\n const { size = \"md\", invalid, className, slot, ...rest } = props;\n\n return (\n <ark.div\n className={cn(\n \"relative w-fit\",\n \"has-[select:disabled]:opacity-64\",\n \"[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground\",\n className\n )}\n data-slot=\"native-select-wrapper\"\n >\n <ArkField.Select\n aria-invalid={invalid}\n className={cn(nativeSelectVariants({ size }))}\n {...rest}\n data-slot={slot ?? \"native-select\"}\n />\n <ChevronsUpDownIcon\n aria-hidden=\"true\"\n className={cn(\"absolute inset-e-2.5 top-1/2 -translate-y-1/2\")}\n data-slot=\"native-select-icon\"\n />\n </ark.div>\n );\n};\n\nexport const NativeSelectOption = (\n { slot, ...rest }: React.ComponentProps<typeof ark.option>\n) => <ark.option {...rest} data-slot={slot ?? \"native-select-option\"} />;\n\nexport const NativeSelectOptGroup = (\n { slot, ...rest }: React.ComponentProps<typeof ark.optgroup>\n) => <ark.optgroup {...rest} data-slot={slot ?? \"native-select-optgroup\"} />;\n"],"names":["nativeSelectVariants","tv","controlHeight","controlSizes","NativeSelect","props","size","invalid","className","slot","rest","jsxs","ark","cn","jsx","ArkField","ChevronsUpDownIcon","NativeSelectOption","NativeSelectOptGroup"],"mappings":";;;;;;;AAQO,MAAMA,IAAuBC,EAAG;AAAA,EACrC,MAAM;AAAA,IACJ;AAAA;AAAA;AAAA,IAGAC;AAAA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAAA,EAEF,UAAU;AAAA,IACR,MAAM;AAAA,MACJ,GAAGC;AAAA,IAAA;AAAA,EACL;AAAA,EAEF,iBAAiB;AAAA,IACf,MAAM;AAAA,EAAA;AAEV,CAAC,GAaYC,IAAe,CAACC,MAA6B;AACxD,QAAM,EAAE,MAAAC,IAAO,MAAM,SAAAC,GAAS,WAAAC,GAAW,MAAAC,GAAM,GAAGC,MAASL;AAE3D,SACE,gBAAAM;AAAA,IAACC,EAAI;AAAA,IAAJ;AAAA,MACC,WAAWC;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACAL;AAAA,MAAA;AAAA,MAEF,aAAU;AAAA,MAEV,UAAA;AAAA,QAAA,gBAAAM;AAAA,UAACC,EAAS;AAAA,UAAT;AAAA,YACC,gBAAcR;AAAA,YACd,WAAWM,EAAGb,EAAqB,EAAE,MAAAM,EAAA,CAAM,CAAC;AAAA,YAC3C,GAAGI;AAAA,YACJ,aAAWD,KAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,QAErB,gBAAAK;AAAA,UAACE;AAAA,UAAA;AAAA,YACC,eAAY;AAAA,YACZ,WAAWH,EAAG,+CAA+C;AAAA,YAC7D,aAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACZ;AAAA,IAAA;AAAA,EAAA;AAGN,GAEaI,IAAqB,CAChC,EAAE,MAAAR,GAAM,GAAGC,EAAA,MACR,gBAAAI,EAACF,EAAI,QAAJ,EAAY,GAAGF,GAAM,aAAWD,KAAQ,uBAAA,CAAwB,GAEzDS,IAAuB,CAClC,EAAE,MAAAT,GAAM,GAAGC,EAAA,MACR,gBAAAI,EAACF,EAAI,UAAJ,EAAc,GAAGF,GAAM,aAAWD,KAAQ,yBAAA,CAA0B;"}