@eifi1/ui-kit 0.22.0 → 0.23.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 (205) hide show
  1. package/README.md +42 -25
  2. package/dist/chart.d.ts +11 -8
  3. package/dist/components/amount-input.d.ts +28 -8
  4. package/dist/components/amount-input.js +3 -1
  5. package/dist/components/amount-input.js.map +1 -1
  6. package/dist/components/autocomplete.d.ts +21 -0
  7. package/dist/components/autocomplete.js +128 -103
  8. package/dist/components/autocomplete.js.map +1 -1
  9. package/dist/components/button-group.d.ts +11 -8
  10. package/dist/components/calculator.d.ts +11 -8
  11. package/dist/components/column-mapper.d.ts +182 -0
  12. package/dist/components/column-mapper.js +375 -0
  13. package/dist/components/column-mapper.js.map +1 -0
  14. package/dist/components/combobox-core.d.ts +39 -2
  15. package/dist/components/combobox-core.js +29 -6
  16. package/dist/components/combobox-core.js.map +1 -1
  17. package/dist/components/combobox.d.ts +80 -2
  18. package/dist/components/combobox.js +448 -311
  19. package/dist/components/combobox.js.map +1 -1
  20. package/dist/components/confirm-dialog.d.ts +11 -8
  21. package/dist/components/confirm-dialog.js +7 -8
  22. package/dist/components/confirm-dialog.js.map +1 -1
  23. package/dist/components/copy-button.d.ts +8 -5
  24. package/dist/components/country-select.d.ts +50 -7
  25. package/dist/components/country-select.js +65 -9
  26. package/dist/components/country-select.js.map +1 -1
  27. package/dist/components/danger-confirm.d.ts +11 -8
  28. package/dist/components/danger-confirm.js +13 -3
  29. package/dist/components/danger-confirm.js.map +1 -1
  30. package/dist/components/date-picker.d.ts +41 -0
  31. package/dist/components/date-picker.js +269 -8
  32. package/dist/components/date-picker.js.map +1 -1
  33. package/dist/components/entity-combobox.d.ts +35 -1
  34. package/dist/components/entity-combobox.js +148 -112
  35. package/dist/components/entity-combobox.js.map +1 -1
  36. package/dist/components/facing-pair.d.ts +11 -8
  37. package/dist/components/field-parts.d.ts +116 -6
  38. package/dist/components/field-parts.js +84 -0
  39. package/dist/components/field-parts.js.map +1 -1
  40. package/dist/components/field-strip.d.ts +105 -0
  41. package/dist/components/field-strip.js +46 -0
  42. package/dist/components/field-strip.js.map +1 -0
  43. package/dist/components/file-button.d.ts +11 -8
  44. package/dist/components/file-dropzone.d.ts +11 -8
  45. package/dist/components/form-actions.d.ts +10 -7
  46. package/dist/components/form-actions.js +8 -2
  47. package/dist/components/form-actions.js.map +1 -1
  48. package/dist/components/iban-input.d.ts +11 -8
  49. package/dist/components/icon-picker.d.ts +10 -1
  50. package/dist/components/icon-picker.js +12 -4
  51. package/dist/components/icon-picker.js.map +1 -1
  52. package/dist/components/language-select.d.ts +11 -8
  53. package/dist/components/money-field.d.ts +14 -8
  54. package/dist/components/money-field.js.map +1 -1
  55. package/dist/components/month-picker.js +2 -1
  56. package/dist/components/month-picker.js.map +1 -1
  57. package/dist/components/multi-entity-combobox.d.ts +26 -1
  58. package/dist/components/multi-entity-combobox.js +143 -102
  59. package/dist/components/multi-entity-combobox.js.map +1 -1
  60. package/dist/components/number-field.d.ts +11 -8
  61. package/dist/components/number-input.d.ts +11 -8
  62. package/dist/components/numpad-sheet.d.ts +11 -8
  63. package/dist/components/phone-input.d.ts +11 -8
  64. package/dist/components/reauth-dialog.d.ts +2 -2
  65. package/dist/components/reauth-dialog.js +6 -8
  66. package/dist/components/reauth-dialog.js.map +1 -1
  67. package/dist/components/series-chart.d.ts +11 -8
  68. package/dist/components/settings-fields.d.ts +11 -8
  69. package/dist/components/share-card.d.ts +10 -7
  70. package/dist/components/swatch-picker.d.ts +17 -1
  71. package/dist/components/swatch-picker.js +10 -4
  72. package/dist/components/swatch-picker.js.map +1 -1
  73. package/dist/components/text-link.d.ts +10 -7
  74. package/dist/components/tile-radio.d.ts +20 -0
  75. package/dist/components/tile-radio.js +25 -8
  76. package/dist/components/tile-radio.js.map +1 -1
  77. package/dist/components/time-input.d.ts +11 -8
  78. package/dist/components/toggle-group.js +2 -2
  79. package/dist/components/toggle-group.js.map +1 -1
  80. package/dist/components/trigger-aria.d.ts +3 -0
  81. package/dist/components/trigger-aria.js +3 -1
  82. package/dist/components/trigger-aria.js.map +1 -1
  83. package/dist/components/ui.d.ts +8 -5
  84. package/dist/components/ui.js +5 -11
  85. package/dist/components/ui.js.map +1 -1
  86. package/dist/feedback/feedback-attachment.d.ts +1 -1
  87. package/dist/feedback/feedback-attachment.js +156 -56
  88. package/dist/feedback/feedback-attachment.js.map +1 -1
  89. package/dist/feedback/feedback-dialog.d.ts +1 -1
  90. package/dist/feedback/feedback-dialog.js.map +1 -1
  91. package/dist/feedback/feedback-inbox.d.ts +3 -2
  92. package/dist/feedback/feedback-inbox.js.map +1 -1
  93. package/dist/feedback/feedback-thread.d.ts +68 -287
  94. package/dist/feedback/feedback-thread.js +8 -1
  95. package/dist/feedback/feedback-thread.js.map +1 -1
  96. package/dist/{kit-labels-R8mIAc9N.d.ts → feedback-BxeQVzwq.d.ts} +405 -22
  97. package/dist/{feedback-attachment-NhUm7Zga.d.ts → feedback-attachment-fGAzZPf0.d.ts} +112 -10
  98. package/dist/feedback.d.ts +66 -2
  99. package/dist/hooks/use-file-drop.d.ts +11 -8
  100. package/dist/i18n/defaults.d.ts +11 -8
  101. package/dist/i18n/defaults.js +3 -1
  102. package/dist/i18n/defaults.js.map +1 -1
  103. package/dist/i18n/german.d.ts +11 -8
  104. package/dist/i18n/german.js +36 -2
  105. package/dist/i18n/german.js.map +1 -1
  106. package/dist/i18n/kit-labels.d.ts +7 -4
  107. package/dist/i18n/kit-labels.js.map +1 -1
  108. package/dist/i18n/languages.d.ts +11 -8
  109. package/dist/i18n/locales/de-CH.d.ts +11 -8
  110. package/dist/i18n/locales/en.d.ts +11 -8
  111. package/dist/i18n/locales/en.js +7 -0
  112. package/dist/i18n/locales/en.js.map +1 -1
  113. package/dist/i18n/locales/es.d.ts +11 -8
  114. package/dist/i18n/locales/es.js +37 -2
  115. package/dist/i18n/locales/es.js.map +1 -1
  116. package/dist/i18n/locales/fr.d.ts +11 -8
  117. package/dist/i18n/locales/fr.js +36 -2
  118. package/dist/i18n/locales/fr.js.map +1 -1
  119. package/dist/i18n/locales/hu.d.ts +11 -8
  120. package/dist/i18n/locales/hu.js +38 -2
  121. package/dist/i18n/locales/hu.js.map +1 -1
  122. package/dist/i18n/locales/it.d.ts +11 -8
  123. package/dist/i18n/locales/it.js +37 -2
  124. package/dist/i18n/locales/it.js.map +1 -1
  125. package/dist/i18n/locales/zh.d.ts +11 -8
  126. package/dist/i18n/locales/zh.js +34 -2
  127. package/dist/i18n/locales/zh.js.map +1 -1
  128. package/dist/i18n/review.d.ts +11 -8
  129. package/dist/i18n/review.js +20 -1
  130. package/dist/i18n/review.js.map +1 -1
  131. package/dist/index.d.ts +7 -3
  132. package/dist/index.js +16 -0
  133. package/dist/index.js.map +1 -1
  134. package/dist/lib/column-mapping.d.ts +81 -0
  135. package/dist/lib/column-mapping.js +108 -0
  136. package/dist/lib/column-mapping.js.map +1 -0
  137. package/dist/lib/table-text.d.ts +109 -1
  138. package/dist/lib/table-text.js +122 -1
  139. package/dist/lib/table-text.js.map +1 -1
  140. package/dist/rhf/fields.d.ts +89 -11
  141. package/dist/rhf/fields.js +124 -0
  142. package/dist/rhf/fields.js.map +1 -1
  143. package/dist/rhf/form.d.ts +11 -8
  144. package/dist/rhf.d.ts +12 -9
  145. package/dist/rhf.js.map +1 -1
  146. package/dist/shell/app-shell.d.ts +10 -7
  147. package/dist/shell/top-bar-brand.d.ts +11 -8
  148. package/dist/shell/topbar-action-menu.d.ts +36 -3
  149. package/dist/shell/topbar-action-menu.js +74 -33
  150. package/dist/shell/topbar-action-menu.js.map +1 -1
  151. package/dist/shell.d.ts +10 -7
  152. package/dist/table-text.d.ts +1 -1
  153. package/dist/wizard/stepper-nav.d.ts +41 -10
  154. package/dist/wizard/stepper-nav.js +4 -0
  155. package/dist/wizard/stepper-nav.js.map +1 -1
  156. package/dist/wizard.d.ts +11 -8
  157. package/package.json +1 -1
  158. package/src/components/amount-input.tsx +20 -1
  159. package/src/components/autocomplete.tsx +172 -111
  160. package/src/components/column-mapper.tsx +666 -0
  161. package/src/components/combobox-core.tsx +82 -9
  162. package/src/components/combobox.tsx +614 -332
  163. package/src/components/confirm-dialog.tsx +12 -8
  164. package/src/components/country-select.tsx +135 -22
  165. package/src/components/danger-confirm.tsx +91 -12
  166. package/src/components/date-picker.tsx +423 -10
  167. package/src/components/entity-combobox.tsx +217 -126
  168. package/src/components/field-parts.tsx +224 -5
  169. package/src/components/field-strip.tsx +149 -0
  170. package/src/components/form-actions.tsx +32 -4
  171. package/src/components/icon-picker.tsx +23 -4
  172. package/src/components/money-field.tsx +3 -0
  173. package/src/components/month-picker.tsx +2 -1
  174. package/src/components/multi-entity-combobox.tsx +207 -120
  175. package/src/components/reauth-dialog.tsx +17 -18
  176. package/src/components/swatch-picker.tsx +29 -5
  177. package/src/components/tile-radio.tsx +74 -13
  178. package/src/components/toggle-group.tsx +2 -2
  179. package/src/components/trigger-aria.ts +5 -0
  180. package/src/components/ui.tsx +7 -33
  181. package/src/feedback/feedback-attachment.tsx +308 -61
  182. package/src/feedback/feedback-dialog.tsx +7 -3
  183. package/src/feedback/feedback-inbox.tsx +3 -2
  184. package/src/feedback/feedback-thread.tsx +47 -4
  185. package/src/i18n/defaults.ts +2 -0
  186. package/src/i18n/german.ts +42 -0
  187. package/src/i18n/kit-labels.tsx +4 -0
  188. package/src/i18n/locales/en.ts +27 -5
  189. package/src/i18n/locales/es.ts +41 -0
  190. package/src/i18n/locales/fr.ts +42 -0
  191. package/src/i18n/locales/hu.ts +37 -0
  192. package/src/i18n/locales/it.ts +41 -0
  193. package/src/i18n/locales/zh.ts +32 -0
  194. package/src/i18n/review.ts +19 -0
  195. package/src/index.ts +18 -0
  196. package/src/lib/column-mapping.ts +234 -0
  197. package/src/lib/table-text.ts +271 -0
  198. package/src/rhf/fields.tsx +254 -0
  199. package/src/rhf.ts +2 -1
  200. package/src/shell/topbar-action-menu.tsx +134 -38
  201. package/src/wizard/stepper-nav.tsx +35 -1
  202. package/dist/components/field-anatomy.d.ts +0 -95
  203. package/dist/components/field-anatomy.js +0 -84
  204. package/dist/components/field-anatomy.js.map +0 -1
  205. package/src/components/field-anatomy.tsx +0 -190
@@ -51,6 +51,14 @@ import { Tooltip } from "./tooltip";
51
51
  * where a tile would hide the text behind a bubble and repeat it.
52
52
  *
53
53
  * No strings of its own: every name is an item's `label`, the "none" tile's included.
54
+ *
55
+ * ## A tile that cannot be chosen
56
+ *
57
+ * `disabled` takes a tile out of the choice AND out of reach: the arrow keys skip it
58
+ * and Tab never lands on it, so a dimmed square says nothing about why. Give it a
59
+ * `disabledReason` instead and it stays reachable, `aria-disabled`, with the reason in
60
+ * its bubble and its description — and choosing it does nothing (0.23, the kit's later
61
+ * list after keksdose K3; {@link Button}'s `disabledReason`, one tile at a time).
54
62
  */
55
63
 
56
64
  /** A tile's size: 28 / 32 / 44px — see {@link TILE_SIZE}. */
@@ -73,7 +81,19 @@ export interface TileItem<T extends string> {
73
81
  /** Said after the name, and shown in the bubble under it. Marks the tile with a
74
82
  * dot, so the note is visible without hovering every tile to find it. */
75
83
  note?: string;
84
+ /** Out of the choice and out of reach: natively disabled, skipped by the arrow keys,
85
+ * never the tab stop. */
76
86
  disabled?: boolean;
87
+ /**
88
+ * Why this tile cannot be chosen right now — a colour another category already wears,
89
+ * a symbol only an owner may set. The tile LOOKS disabled but is `aria-disabled`, not
90
+ * `disabled`: Tab and the arrow keys still reach it, the reason shows in its bubble
91
+ * under its name (and its `note`) and describes it, and a click, Space / Enter or an
92
+ * arrow under automatic activation chooses nothing — the focus moves, the checked
93
+ * tile stays. Wins over `disabled`, as on {@link Button}; the whole group's
94
+ * `disabled` still wins over it.
95
+ */
96
+ disabledReason?: ReactNode;
77
97
  }
78
98
 
79
99
  export interface TileRadioGroupProps<T extends string> {
@@ -119,6 +139,22 @@ const TILE_IDLE =
119
139
  "border-[var(--border)] bg-[var(--bg-surface)] hover:border-[var(--border-strong)] hover:bg-[var(--bg-hover)]";
120
140
  const TILE_SELECTED =
121
141
  "border-[var(--text-primary)] bg-[var(--bg-surface)] ring-1 ring-[var(--text-primary)]";
142
+ /** A locked tile: the disabled look without `disabled` — dimmed, a not-allowed cursor. */
143
+ const TILE_LOCKED = "cursor-not-allowed opacity-50";
144
+ /** …and no hover offer on an idle one, which cannot be chosen. Not on the selected
145
+ * tile, whose frame IS its state. */
146
+ const TILE_LOCKED_IDLE = "hover:border-[var(--border)] hover:bg-[var(--bg-surface)]";
147
+
148
+ /** `undefined`, `null`, `false` and `""` are no reason — what `cond && "…"` gives. */
149
+ function isLocked(item: TileItem<string>): boolean {
150
+ const r = item.disabledReason;
151
+ return r !== undefined && r !== null && r !== false && r !== "";
152
+ }
153
+
154
+ /** Out of reach: natively disabled. A reason keeps a `disabled` tile reachable. */
155
+ function isOff(item: TileItem<string>): boolean {
156
+ return Boolean(item.disabled) && !isLocked(item);
157
+ }
122
158
 
123
159
  /**
124
160
  * The tiles of one radio group, without the group element — render them inside a
@@ -139,15 +175,17 @@ export function TileRadioGroup<T extends string>({
139
175
  }: TileRadioGroupProps<T>) {
140
176
  const refs = useRef<Array<HTMLButtonElement | null>>([]);
141
177
  const noteId = useId();
178
+ const reasonId = useId();
142
179
  const s = TILE_SIZE[size];
143
180
  const checkedIndex =
144
181
  checked === undefined ? -1 : items.findIndex((it) => it.key === checked);
145
- // The ONE tab stop: the checked tile, else the first that can be chosen — the APG
146
- // rule, so Tab into a group with nothing checked still lands somewhere.
182
+ // The ONE tab stop: the checked tile, else the first that can be reached — the APG
183
+ // rule, so Tab into a group with nothing checked still lands somewhere. A locked
184
+ // tile is reachable: landing on it is how its reason is read.
147
185
  const tabStop =
148
- checkedIndex >= 0 && !items[checkedIndex].disabled
186
+ checkedIndex >= 0 && !isOff(items[checkedIndex])
149
187
  ? checkedIndex
150
- : items.findIndex((it) => !it.disabled);
188
+ : items.findIndex((it) => !isOff(it));
151
189
 
152
190
  const onKeyDown = (e: KeyboardEvent<HTMLButtonElement>, index: number) => {
153
191
  // Left and right are VISUAL directions: in a right-to-left page the row runs the
@@ -175,7 +213,8 @@ export function TileRadioGroup<T extends string>({
175
213
  return;
176
214
  }
177
215
  e.preventDefault();
178
- const enabled = items.map((it, i) => (it.disabled ? -1 : i)).filter((i) => i >= 0);
216
+ // Locked tiles are in the walk; natively disabled ones are not.
217
+ const enabled = items.map((it, i) => (isOff(it) ? -1 : i)).filter((i) => i >= 0);
179
218
  if (!enabled.length) return;
180
219
  const at = enabled.indexOf(index);
181
220
  let target: number;
@@ -184,13 +223,17 @@ export function TileRadioGroup<T extends string>({
184
223
  // Wrapping, as a native radio group does: the last tile's "next" is the first.
185
224
  else target = enabled[(at + step + enabled.length) % enabled.length];
186
225
  refs.current[target]?.focus();
187
- if (activation === "automatic") onSelect(items[target].key);
226
+ // Onto a locked tile the focus moves and the choice does not: the checked tile
227
+ // stays checked, and the next arrow walks on from here.
228
+ if (activation === "automatic" && !isLocked(items[target])) onSelect(items[target].key);
188
229
  };
189
230
 
190
231
  return (
191
232
  <>
192
233
  {items.map((item, i) => {
193
234
  const selected = i === checkedIndex;
235
+ const locked = isLocked(item);
236
+ const describedBy = [item.note && `${noteId}-${i}`, locked && `${reasonId}-${i}`].filter(Boolean).join(" ");
194
237
  const button = (
195
238
  <button
196
239
  ref={(el) => {
@@ -201,18 +244,25 @@ export function TileRadioGroup<T extends string>({
201
244
  aria-checked={selected}
202
245
  aria-label={item.label}
203
246
  // The note is a DESCRIPTION, read after the name and the state, not glued
204
- // into the name — the punctuation between the two would be English's.
205
- aria-describedby={item.note ? `${noteId}-${i}` : undefined}
247
+ // into the name — the punctuation between the two would be English's. So
248
+ // is a lock's reason, after the note.
249
+ aria-describedby={describedBy || undefined}
206
250
  tabIndex={i === tabStop ? 0 : -1}
207
- disabled={disabled || item.disabled}
251
+ // A reason wins over the tile's own `disabled` (as on Button): reachable,
252
+ // and refusing. The whole group's `disabled` still wins over both.
253
+ disabled={disabled || isOff(item)}
254
+ aria-disabled={(locked && !disabled) || undefined}
208
255
  // Clicking the checked tile again does nothing: a radio is not a toggle.
209
- // "None" is the way back to nothing, and it is a tile of its own.
210
- onClick={() => !selected && onSelect(item.key)}
256
+ // "None" is the way back to nothing, and it is a tile of its own. A locked
257
+ // tile is never chosen.
258
+ onClick={() => !selected && !locked && onSelect(item.key)}
211
259
  onKeyDown={(e) => onKeyDown(e, i)}
212
260
  className={cn(
213
261
  TILE_BASE,
214
262
  s.tile,
215
263
  selected ? TILE_SELECTED : TILE_IDLE,
264
+ locked && TILE_LOCKED,
265
+ locked && !selected && TILE_LOCKED_IDLE,
216
266
  tileClassName?.(item, selected),
217
267
  )}
218
268
  >
@@ -236,6 +286,14 @@ export function TileRadioGroup<T extends string>({
236
286
  </span>
237
287
  </>
238
288
  )}
289
+ {/* The reason's description is a `hidden` copy, as on a locked Button: the
290
+ bubble exists only while hovered or focused once portalled, and a
291
+ description that comes and goes is read inconsistently. */}
292
+ {locked && (
293
+ <span id={`${reasonId}-${i}`} hidden>
294
+ {item.disabledReason}
295
+ </span>
296
+ )}
239
297
  {selected && <SelectedTick />}
240
298
  </button>
241
299
  );
@@ -248,10 +306,13 @@ export function TileRadioGroup<T extends string>({
248
306
  <Tooltip
249
307
  key={item.key ?? "\u0000none"}
250
308
  label={
251
- item.note ? (
309
+ item.note || locked ? (
252
310
  <>
253
311
  <span className="block">{item.label}</span>
254
- <span className="block font-normal text-[var(--text-muted)]">{item.note}</span>
312
+ {item.note && <span className="block font-normal text-[var(--text-muted)]">{item.note}</span>}
313
+ {/* The reason in the body colour: it is the news, the note is
314
+ standing context. */}
315
+ {locked && <span className="block font-normal">{item.disabledReason}</span>}
255
316
  </>
256
317
  ) : (
257
318
  item.label
@@ -5,7 +5,7 @@ import { horizontalStep } from "../lib/direction";
5
5
  import { FIELD_INVALID, FloatingField, Label } from "./ui";
6
6
  import { Tooltip } from "./tooltip";
7
7
  import { useCommitReason } from "./write-lock";
8
- import { hasContent, LabelStrip } from "./field-anatomy";
8
+ import { hasContent, LabelStrip } from "./field-parts";
9
9
 
10
10
  export interface ToggleOption<T extends string> {
11
11
  value: T;
@@ -524,7 +524,7 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
524
524
  }
525
525
  if (strip) {
526
526
  return (
527
- <LabelStrip labelId={labelId} label={label} hint={hint} disabled={dimmed} pad="toggle" className={className}>
527
+ <LabelStrip labelId={labelId} label={label} hint={hint} disabled={dimmed} pad="field" className={className}>
528
528
  {group}
529
529
  {captionEl}
530
530
  {errorEl}
@@ -14,6 +14,9 @@ export interface TriggerAria {
14
14
  "aria-labelledby"?: string;
15
15
  "aria-describedby"?: string;
16
16
  "aria-invalid"?: boolean | "true" | "false" | "grammar" | "spelling";
17
+ /** 0.23.0: a form library's `required` (RhfMonthPicker) is announced on the trigger,
18
+ * not lost on the wrapper. */
19
+ "aria-required"?: boolean | "true" | "false";
17
20
  }
18
21
 
19
22
  /** Split a field's props into what its trigger takes and what its wrapper takes. */
@@ -26,6 +29,7 @@ export function splitTriggerAria<T extends TriggerAria>(
26
29
  "aria-labelledby": labelledBy,
27
30
  "aria-describedby": describedBy,
28
31
  "aria-invalid": invalid,
32
+ "aria-required": required,
29
33
  ...rest
30
34
  } = props;
31
35
  return [
@@ -35,6 +39,7 @@ export function splitTriggerAria<T extends TriggerAria>(
35
39
  "aria-labelledby": labelledBy,
36
40
  "aria-describedby": describedBy,
37
41
  "aria-invalid": invalid,
42
+ "aria-required": required,
38
43
  },
39
44
  rest,
40
45
  ];
@@ -17,9 +17,16 @@ import {
17
17
  LockedReason,
18
18
  useFieldHint,
19
19
  useLockReason,
20
+ FLOATING_LABEL_STATIC,
21
+ STATIC_LABEL_TYPE,
20
22
  type FieldHintParts,
21
23
  } from "./field-parts";
22
24
 
25
+ // The static label lives in field-parts since 0.23 (it is what the field anatomy
26
+ // there draws, and field-parts must not import this file); public from here as before.
27
+ export { FieldLabel, FLOATING_LABEL_STATIC } from "./field-parts";
28
+ export type { FieldLabelProps } from "./field-parts";
29
+
23
30
  export type ButtonVariant = "primary" | "secondary" | "ghost" | "danger" | "brand" | "link";
24
31
 
25
32
  // Shared base ring for every button-styled element. Kept as a named const so the
@@ -1483,22 +1490,6 @@ const FLOATING_ROW_CLASS = cn(
1483
1490
  "peer-disabled:opacity-50",
1484
1491
  );
1485
1492
 
1486
- // The TYPE of the small static label, without any placement. Split out so the
1487
- // label and anything sharing its line (see `hint` on {@link FloatingField}) are
1488
- // laid out by one flex row instead of by two absolute offsets guessing at the
1489
- // same baseline — which is what put dev#468's "?" three pixels above the word it
1490
- // belongs to.
1491
- const STATIC_LABEL_TYPE =
1492
- "text-[11px] leading-tight text-[var(--text-muted)] peer-disabled:opacity-50";
1493
-
1494
- // A field that always has a value (select / dropdown trigger) keeps the label
1495
- // permanently in the floated position — small, in the top strip, value below.
1496
- export const FLOATING_LABEL_STATIC = cn(
1497
- "pointer-events-none absolute start-3 top-1",
1498
- STATIC_LABEL_TYPE,
1499
- "max-w-[calc(100%-1.5rem)] truncate",
1500
- );
1501
-
1502
1493
  /**
1503
1494
  * The one place that assembles a labelled field: a `relative` wrapper around the
1504
1495
  * control (`children`) plus a floating label inside the top strip. Pass `staticLabel`
@@ -1650,23 +1641,6 @@ export function FieldHint({
1650
1641
  );
1651
1642
  }
1652
1643
 
1653
- /**
1654
- * The floating label for a custom-dropdown trigger (a `<span>`, since the trigger is a
1655
- * button not a labelable input). Same placement as {@link FloatingField}'s static label,
1656
- * so every labelled field lines up. Render inside a `relative` wrapper, before the trigger.
1657
- */
1658
- export interface FieldLabelProps extends ComponentPropsWithoutRef<"span"> {
1659
- children: ReactNode;
1660
- }
1661
-
1662
- export function FieldLabel({ children, className, ...rest }: FieldLabelProps) {
1663
- return (
1664
- <span {...rest} className={cn(FLOATING_LABEL_STATIC, "z-10", className)}>
1665
- {children}
1666
- </span>
1667
- );
1668
- }
1669
-
1670
1644
  export interface LabelProps extends ComponentPropsWithoutRef<"label"> {
1671
1645
  /** Draw the required mark after the text. The mark is `aria-hidden`: what a
1672
1646
  * screen reader hears is the control's own `required` / `aria-required`, which