@eifi1/ui-kit 0.53.0 → 0.55.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 (902) hide show
  1. package/README.md +96 -82
  2. package/dist/account/delete-account-setting.d.ts +3 -2
  3. package/dist/account/delete-account-setting.js.map +1 -1
  4. package/dist/admin/plan-change.js +2 -2
  5. package/dist/admin/plan-change.js.map +1 -1
  6. package/dist/admin/user-roster.d.ts +6 -0
  7. package/dist/admin/user-roster.js +4 -0
  8. package/dist/admin/user-roster.js.map +1 -1
  9. package/dist/auth/auth-errors.d.ts +36 -0
  10. package/dist/auth/auth-errors.js +20 -0
  11. package/dist/auth/auth-errors.js.map +1 -1
  12. package/dist/billing/billing-labels.d.ts +26 -0
  13. package/dist/billing/billing-labels.js +9 -0
  14. package/dist/billing/billing-labels.js.map +1 -1
  15. package/dist/billing/subscription-standing.d.ts +61 -0
  16. package/dist/billing/subscription-standing.js +51 -0
  17. package/dist/billing/subscription-standing.js.map +1 -0
  18. package/dist/billing/usage-meter.d.ts +52 -0
  19. package/dist/billing/usage-meter.js +52 -0
  20. package/dist/billing/usage-meter.js.map +1 -0
  21. package/dist/chart.d.ts +1 -0
  22. package/dist/chart.js +4 -0
  23. package/dist/chart.js.map +1 -1
  24. package/dist/components/alert-banner.js +2 -3
  25. package/dist/components/alert-banner.js.map +1 -1
  26. package/dist/components/amount-input.d.ts +2 -1
  27. package/dist/components/amount-input.js +3 -15
  28. package/dist/components/amount-input.js.map +1 -1
  29. package/dist/components/autocomplete.js +2 -2
  30. package/dist/components/autocomplete.js.map +1 -1
  31. package/dist/components/bulk-action-bar.js +2 -1
  32. package/dist/components/bulk-action-bar.js.map +1 -1
  33. package/dist/components/button.d.ts +35 -1
  34. package/dist/components/button.js +5 -9
  35. package/dist/components/button.js.map +1 -1
  36. package/dist/components/calendar-heatmap.js +6 -4
  37. package/dist/components/calendar-heatmap.js.map +1 -1
  38. package/dist/components/camera-button.d.ts +89 -0
  39. package/dist/components/camera-button.js +122 -0
  40. package/dist/components/camera-button.js.map +1 -0
  41. package/dist/components/camera-capture.d.ts +66 -0
  42. package/dist/components/camera-capture.js +190 -0
  43. package/dist/components/camera-capture.js.map +1 -0
  44. package/dist/components/camera-labels.d.ts +20 -0
  45. package/dist/components/camera-labels.js +15 -0
  46. package/dist/components/camera-labels.js.map +1 -0
  47. package/dist/components/chart-edge.d.ts +9 -0
  48. package/dist/components/chart-edge.js +14 -3
  49. package/dist/components/chart-edge.js.map +1 -1
  50. package/dist/components/chart-zoom-core.js +34 -29
  51. package/dist/components/chart-zoom-core.js.map +1 -1
  52. package/dist/components/checkbox-group.js +1 -1
  53. package/dist/components/checkbox-group.js.map +1 -1
  54. package/dist/components/combobox-core.js +3 -2
  55. package/dist/components/combobox-core.js.map +1 -1
  56. package/dist/components/combobox.js +2 -2
  57. package/dist/components/combobox.js.map +1 -1
  58. package/dist/components/consent-again-notice-labels.d.ts +25 -0
  59. package/dist/components/consent-again-notice-labels.js +15 -0
  60. package/dist/components/consent-again-notice-labels.js.map +1 -0
  61. package/dist/components/consent-again-notice.d.ts +85 -0
  62. package/dist/components/consent-again-notice.js +94 -0
  63. package/dist/components/consent-again-notice.js.map +1 -0
  64. package/dist/components/country-select.js +2 -7
  65. package/dist/components/country-select.js.map +1 -1
  66. package/dist/components/currency-option-list.d.ts +2 -1
  67. package/dist/components/currency-option-list.js +10 -3
  68. package/dist/components/currency-option-list.js.map +1 -1
  69. package/dist/components/currency-select.d.ts +3 -1
  70. package/dist/components/currency-select.js +2 -2
  71. package/dist/components/currency-select.js.map +1 -1
  72. package/dist/components/danger-confirm.d.ts +22 -1
  73. package/dist/components/danger-confirm.js +52 -30
  74. package/dist/components/danger-confirm.js.map +1 -1
  75. package/dist/components/data-table-column-settings.js +2 -2
  76. package/dist/components/data-table-column-settings.js.map +1 -1
  77. package/dist/components/data-table-filter-popover.d.ts +2 -1
  78. package/dist/components/data-table-filter-popover.js +3 -2
  79. package/dist/components/data-table-filter-popover.js.map +1 -1
  80. package/dist/components/data-table-filters.d.ts +33 -3
  81. package/dist/components/data-table-filters.js +6 -4
  82. package/dist/components/data-table-filters.js.map +1 -1
  83. package/dist/components/data-table-fit.js.map +1 -1
  84. package/dist/components/data-table-virtual.js +13 -3
  85. package/dist/components/data-table-virtual.js.map +1 -1
  86. package/dist/components/date-field.js +2 -2
  87. package/dist/components/date-field.js.map +1 -1
  88. package/dist/components/date-picker.js +2 -2
  89. package/dist/components/date-picker.js.map +1 -1
  90. package/dist/components/date-range-picker.js +2 -6
  91. package/dist/components/date-range-picker.js.map +1 -1
  92. package/dist/components/dialog-frame.d.ts +5 -1
  93. package/dist/components/dialog-frame.js +6 -2
  94. package/dist/components/dialog-frame.js.map +1 -1
  95. package/dist/components/dropdown.js +7 -3
  96. package/dist/components/dropdown.js.map +1 -1
  97. package/dist/components/entity-combobox.js +2 -2
  98. package/dist/components/entity-combobox.js.map +1 -1
  99. package/dist/components/field-parts.d.ts +108 -6
  100. package/dist/components/field-parts.js +59 -6
  101. package/dist/components/field-parts.js.map +1 -1
  102. package/dist/components/field-suggestion-labels.d.ts +2 -0
  103. package/dist/components/field-suggestion-labels.js +10 -0
  104. package/dist/components/field-suggestion-labels.js.map +1 -0
  105. package/dist/components/field.js +1 -1
  106. package/dist/components/field.js.map +1 -1
  107. package/dist/components/file-button.d.ts +1 -1
  108. package/dist/components/file-button.js.map +1 -1
  109. package/dist/components/floating-panel.d.ts +7 -6
  110. package/dist/components/floating-panel.js +3 -17
  111. package/dist/components/floating-panel.js.map +1 -1
  112. package/dist/components/form-actions.d.ts +3 -2
  113. package/dist/components/form-actions.js.map +1 -1
  114. package/dist/components/hover-menu.js +3 -2
  115. package/dist/components/hover-menu.js.map +1 -1
  116. package/dist/components/icon-button.d.ts +23 -5
  117. package/dist/components/icon-button.js +6 -8
  118. package/dist/components/icon-button.js.map +1 -1
  119. package/dist/components/inline-confirm.js +2 -1
  120. package/dist/components/inline-confirm.js.map +1 -1
  121. package/dist/components/inline-entity-combobox.js +2 -2
  122. package/dist/components/inline-entity-combobox.js.map +1 -1
  123. package/dist/components/input.js +2 -2
  124. package/dist/components/input.js.map +1 -1
  125. package/dist/components/jump-calendar.js +3 -3
  126. package/dist/components/jump-calendar.js.map +1 -1
  127. package/dist/components/legal.d.ts +13 -1
  128. package/dist/components/legal.js +12 -0
  129. package/dist/components/legal.js.map +1 -1
  130. package/dist/components/legended-series-chart.d.ts +80 -0
  131. package/dist/components/legended-series-chart.js +70 -0
  132. package/dist/components/legended-series-chart.js.map +1 -0
  133. package/dist/components/lightbox.js +2 -1
  134. package/dist/components/lightbox.js.map +1 -1
  135. package/dist/components/mini-calendar.js +16 -7
  136. package/dist/components/mini-calendar.js.map +1 -1
  137. package/dist/components/modal.d.ts +48 -0
  138. package/dist/components/modal.js +26 -6
  139. package/dist/components/modal.js.map +1 -1
  140. package/dist/components/month-picker.d.ts +1 -1
  141. package/dist/components/month-picker.js +6 -6
  142. package/dist/components/month-picker.js.map +1 -1
  143. package/dist/components/multi-entity-combobox.js +2 -2
  144. package/dist/components/multi-entity-combobox.js.map +1 -1
  145. package/dist/components/multi-select.js +2 -6
  146. package/dist/components/multi-select.js.map +1 -1
  147. package/dist/components/number-input.js +2 -2
  148. package/dist/components/number-input.js.map +1 -1
  149. package/dist/components/page-header-layout.d.ts +18 -0
  150. package/dist/components/page-header-layout.js +23 -0
  151. package/dist/components/page-header-layout.js.map +1 -0
  152. package/dist/components/page-header-skeleton.d.ts +41 -0
  153. package/dist/components/page-header-skeleton.js +52 -0
  154. package/dist/components/page-header-skeleton.js.map +1 -0
  155. package/dist/components/page-header.js +4 -17
  156. package/dist/components/page-header.js.map +1 -1
  157. package/dist/components/popover.js +7 -2
  158. package/dist/components/popover.js.map +1 -1
  159. package/dist/components/release-notes-labels.d.ts +16 -0
  160. package/dist/components/release-notes-labels.js +18 -0
  161. package/dist/components/release-notes-labels.js.map +1 -0
  162. package/dist/components/release-notes.d.ts +65 -0
  163. package/dist/components/release-notes.js +65 -0
  164. package/dist/components/release-notes.js.map +1 -0
  165. package/dist/components/select.js +2 -2
  166. package/dist/components/select.js.map +1 -1
  167. package/dist/components/series-chart-labels.d.ts +9 -0
  168. package/dist/components/series-chart-labels.js +3 -1
  169. package/dist/components/series-chart-labels.js.map +1 -1
  170. package/dist/components/series-chart.d.ts +5 -0
  171. package/dist/components/series-chart.js +89 -36
  172. package/dist/components/series-chart.js.map +1 -1
  173. package/dist/components/stat-tile.d.ts +21 -2
  174. package/dist/components/stat-tile.js +4 -2
  175. package/dist/components/stat-tile.js.map +1 -1
  176. package/dist/components/toggle-group.js +3 -2
  177. package/dist/components/toggle-group.js.map +1 -1
  178. package/dist/components/treemap-layout.js.map +1 -1
  179. package/dist/components/treemap.d.ts +17 -15
  180. package/dist/components/treemap.js +167 -85
  181. package/dist/components/treemap.js.map +1 -1
  182. package/dist/currencies.d.ts +16 -2
  183. package/dist/currencies.js +2 -1
  184. package/dist/currencies.js.map +1 -1
  185. package/dist/eslint/index.js +1 -1
  186. package/dist/eslint/role-utilities.d.ts +2 -2
  187. package/dist/eslint/role-utilities.js.map +1 -1
  188. package/dist/feedback/feedback-context-labels.js +2 -1
  189. package/dist/feedback/feedback-context-labels.js.map +1 -1
  190. package/dist/feedback/feedback-context.d.ts +19 -3
  191. package/dist/feedback/feedback-context.js +12 -1
  192. package/dist/feedback/feedback-context.js.map +1 -1
  193. package/dist/feedback/feedback-diagnostics.d.ts +17 -0
  194. package/dist/feedback/feedback-diagnostics.js +27 -0
  195. package/dist/feedback/feedback-diagnostics.js.map +1 -0
  196. package/dist/feedback/feedback-dialog.d.ts +10 -0
  197. package/dist/feedback/feedback-dialog.js +6 -4
  198. package/dist/feedback/feedback-dialog.js.map +1 -1
  199. package/dist/feedback/feedback-inbox-page.d.ts +260 -0
  200. package/dist/feedback/feedback-inbox-page.js +207 -0
  201. package/dist/feedback/feedback-inbox-page.js.map +1 -0
  202. package/dist/feedback/feedback-record.d.ts +5 -0
  203. package/dist/feedback/feedback-record.js.map +1 -1
  204. package/dist/feedback/feedback-row-detail-labels.js +1 -0
  205. package/dist/feedback/feedback-row-detail-labels.js.map +1 -1
  206. package/dist/feedback/feedback-row-detail.d.ts +3 -0
  207. package/dist/feedback/feedback-row-detail.js +3 -0
  208. package/dist/feedback/feedback-row-detail.js.map +1 -1
  209. package/dist/feedback/feedback-submit-dialog.d.ts +5 -1
  210. package/dist/feedback/feedback-submit-dialog.js +15 -3
  211. package/dist/feedback/feedback-submit-dialog.js.map +1 -1
  212. package/dist/feedback/feedback-submit.d.ts +30 -2
  213. package/dist/feedback/feedback-submit.js +5 -2
  214. package/dist/feedback/feedback-submit.js.map +1 -1
  215. package/dist/feedback/feedback-vocabulary.js +2 -2
  216. package/dist/feedback/feedback-vocabulary.js.map +1 -1
  217. package/dist/feedback.d.ts +1 -0
  218. package/dist/feedback.js +6 -0
  219. package/dist/feedback.js.map +1 -1
  220. package/dist/hooks/use-debounce.d.ts +32 -5
  221. package/dist/hooks/use-debounce.js +6 -5
  222. package/dist/hooks/use-debounce.js.map +1 -1
  223. package/dist/hooks/use-file-picker.d.ts +3 -1
  224. package/dist/hooks/use-file-picker.js.map +1 -1
  225. package/dist/hooks/use-focus-trap.d.ts +19 -3
  226. package/dist/hooks/use-focus-trap.js +15 -5
  227. package/dist/hooks/use-focus-trap.js.map +1 -1
  228. package/dist/hooks/use-has-camera.d.ts +36 -0
  229. package/dist/hooks/use-has-camera.js +53 -0
  230. package/dist/hooks/use-has-camera.js.map +1 -0
  231. package/dist/hooks/use-hotkey.js +2 -1
  232. package/dist/hooks/use-hotkey.js.map +1 -1
  233. package/dist/hooks/use-overlay-history.d.ts +6 -1
  234. package/dist/hooks/use-overlay-history.js +10 -2
  235. package/dist/hooks/use-overlay-history.js.map +1 -1
  236. package/dist/i18n/defaults.js +11 -1
  237. package/dist/i18n/defaults.js.map +1 -1
  238. package/dist/i18n/german.js +78 -4
  239. package/dist/i18n/german.js.map +1 -1
  240. package/dist/i18n/kit-labels.d.ts +20 -0
  241. package/dist/i18n/kit-labels.js.map +1 -1
  242. package/dist/i18n/locales/en.js +95 -5
  243. package/dist/i18n/locales/en.js.map +3 -3
  244. package/dist/i18n/locales/es.js +74 -4
  245. package/dist/i18n/locales/es.js.map +1 -1
  246. package/dist/i18n/locales/fr.js +75 -3
  247. package/dist/i18n/locales/fr.js.map +1 -1
  248. package/dist/i18n/locales/hu.js +77 -4
  249. package/dist/i18n/locales/hu.js.map +1 -1
  250. package/dist/i18n/locales/it.js +77 -4
  251. package/dist/i18n/locales/it.js.map +1 -1
  252. package/dist/i18n/locales/zh.js +74 -4
  253. package/dist/i18n/locales/zh.js.map +1 -1
  254. package/dist/i18n/review.js +22 -1
  255. package/dist/i18n/review.js.map +1 -1
  256. package/dist/index.d.ts +27 -8
  257. package/dist/index.js +41 -2
  258. package/dist/index.js.map +1 -1
  259. package/dist/landing/landing-labels.d.ts +8 -0
  260. package/dist/landing/landing-labels.js +2 -1
  261. package/dist/landing/landing-labels.js.map +1 -1
  262. package/dist/lib/changelog.d.ts +130 -0
  263. package/dist/lib/changelog.js +137 -0
  264. package/dist/lib/changelog.js.map +1 -0
  265. package/dist/lib/clipboard-minus.js +2 -2
  266. package/dist/lib/clipboard-minus.js.map +1 -1
  267. package/dist/lib/dates.d.ts +36 -4
  268. package/dist/lib/dates.js +49 -13
  269. package/dist/lib/dates.js.map +1 -1
  270. package/dist/lib/editable-content.d.ts +33 -0
  271. package/dist/lib/editable-content.js +15 -0
  272. package/dist/lib/editable-content.js.map +1 -0
  273. package/dist/lib/focus-left.d.ts +47 -1
  274. package/dist/lib/focus-left.js +11 -2
  275. package/dist/lib/focus-left.js.map +1 -1
  276. package/dist/lib/format.d.ts +37 -2
  277. package/dist/lib/format.js +25 -1
  278. package/dist/lib/format.js.map +1 -1
  279. package/dist/lib/intl-cache.d.ts +4 -2
  280. package/dist/lib/intl-cache.js.map +1 -1
  281. package/dist/lib/server-wake.d.ts +49 -9
  282. package/dist/lib/server-wake.js +25 -14
  283. package/dist/lib/server-wake.js.map +1 -1
  284. package/dist/lib/session-refresh.d.ts +53 -0
  285. package/dist/lib/session-refresh.js +27 -1
  286. package/dist/lib/session-refresh.js.map +1 -1
  287. package/dist/lib/translation-review.d.ts +26 -0
  288. package/dist/lib/translation-review.js +14 -0
  289. package/dist/lib/translation-review.js.map +1 -1
  290. package/dist/rhf/fields.js +3 -3
  291. package/dist/rhf/fields.js.map +1 -1
  292. package/dist/shell/app-shell.d.ts +25 -1
  293. package/dist/shell/app-shell.js +3 -1
  294. package/dist/shell/app-shell.js.map +1 -1
  295. package/dist/shell/dev-menu.d.ts +3 -0
  296. package/dist/shell/dev-menu.js +4 -2
  297. package/dist/shell/dev-menu.js.map +1 -1
  298. package/dist/shell/held-changes-banner-labels.d.ts +23 -0
  299. package/dist/shell/held-changes-banner-labels.js +14 -0
  300. package/dist/shell/held-changes-banner-labels.js.map +1 -0
  301. package/dist/shell/held-changes-banner.d.ts +75 -0
  302. package/dist/shell/held-changes-banner.js +106 -0
  303. package/dist/shell/held-changes-banner.js.map +1 -0
  304. package/dist/shell/sync-status-indicator.d.ts +27 -12
  305. package/dist/shell/sync-status-indicator.js +13 -4
  306. package/dist/shell/sync-status-indicator.js.map +1 -1
  307. package/dist/shell/top-bar-parts-labels.d.ts +5 -0
  308. package/dist/shell/top-bar-parts-labels.js +3 -1
  309. package/dist/shell/top-bar-parts-labels.js.map +1 -1
  310. package/dist/shell.d.ts +2 -0
  311. package/dist/shell.js +3 -0
  312. package/dist/shell.js.map +1 -1
  313. package/dist/sync/engine.d.ts +11 -2
  314. package/dist/sync/engine.js +13 -5
  315. package/dist/sync/engine.js.map +1 -1
  316. package/dist/sync/hooks.d.ts +3 -2
  317. package/dist/sync/hooks.js +4 -2
  318. package/dist/sync/hooks.js.map +1 -1
  319. package/dist/testing/css-variables.generated.d.ts +2 -2
  320. package/dist/testing/css-variables.generated.js +1 -1
  321. package/dist/testing/css-variables.generated.js.map +1 -1
  322. package/dist/theme/chart-palette.d.ts +18 -0
  323. package/dist/theme/chart-palette.js +17 -1
  324. package/dist/theme/chart-palette.js.map +1 -1
  325. package/dist/theme/contrast-tokens.d.ts +3 -3
  326. package/dist/theme/contrast-tokens.js.map +1 -1
  327. package/dist/theme/contrast.d.ts +4 -4
  328. package/dist/theme/contrast.js.map +1 -1
  329. package/dist/tour/tour-overlay.js +2 -1
  330. package/dist/tour/tour-overlay.js.map +1 -1
  331. package/package.json +5 -9
  332. package/tokens.css +19 -54
  333. package/src/account/account-parts.ts +0 -47
  334. package/src/account/account-settings-labels.ts +0 -240
  335. package/src/account/account-settings.tsx +0 -698
  336. package/src/account/data-export-setting-labels.ts +0 -20
  337. package/src/account/data-export-setting.tsx +0 -200
  338. package/src/account/delete-account-setting-labels.ts +0 -33
  339. package/src/account/delete-account-setting.tsx +0 -341
  340. package/src/account/email-change-setting-labels.ts +0 -31
  341. package/src/account/email-change-setting.tsx +0 -443
  342. package/src/account/passkeys-setting.tsx +0 -445
  343. package/src/account/sessions-setting-labels.ts +0 -24
  344. package/src/account/sessions-setting.tsx +0 -283
  345. package/src/admin/admin-action-confirm-labels.ts +0 -19
  346. package/src/admin/admin-action-confirm.tsx +0 -509
  347. package/src/admin/admin-action-log-labels.ts +0 -83
  348. package/src/admin/admin-action-log.tsx +0 -464
  349. package/src/admin/admin-area-labels.ts +0 -114
  350. package/src/admin/admin-forbidden.tsx +0 -75
  351. package/src/admin/admin-overview.tsx +0 -258
  352. package/src/admin/admin-parts.ts +0 -68
  353. package/src/admin/admin-sections.tsx +0 -208
  354. package/src/admin/admin-tool-links.tsx +0 -90
  355. package/src/admin/invitations-panel-labels.ts +0 -31
  356. package/src/admin/invitations-panel.tsx +0 -516
  357. package/src/admin/mail-test-card-labels.ts +0 -19
  358. package/src/admin/mail-test-card.tsx +0 -189
  359. package/src/admin/plan-change-labels.ts +0 -5
  360. package/src/admin/plan-change.tsx +0 -474
  361. package/src/admin/reviewer-scope-editor-labels.ts +0 -16
  362. package/src/admin/reviewer-scope-editor.tsx +0 -224
  363. package/src/admin/role-select-labels.ts +0 -16
  364. package/src/admin/role-select.tsx +0 -282
  365. package/src/admin/transfer-ownership-dialog-labels.ts +0 -20
  366. package/src/admin/transfer-ownership-dialog.tsx +0 -162
  367. package/src/admin/user-roster-labels.ts +0 -17
  368. package/src/admin/user-roster.tsx +0 -559
  369. package/src/auth/accept-invitation-labels.ts +0 -21
  370. package/src/auth/accept-invitation.tsx +0 -210
  371. package/src/auth/auth-errors-labels.ts +0 -23
  372. package/src/auth/auth-errors.ts +0 -370
  373. package/src/auth/complete-name-dialog-labels.ts +0 -16
  374. package/src/auth/complete-name-dialog.tsx +0 -253
  375. package/src/auth/email-tag.ts +0 -75
  376. package/src/auth/forgot-password-form-labels.ts +0 -20
  377. package/src/auth/forgot-password-form.tsx +0 -221
  378. package/src/auth/form-rules.ts +0 -40
  379. package/src/auth/new-password-fields.tsx +0 -85
  380. package/src/auth/not-found-page-labels.ts +0 -12
  381. package/src/auth/not-found-page.tsx +0 -95
  382. package/src/auth/register-form-labels.ts +0 -31
  383. package/src/auth/register-form.tsx +0 -456
  384. package/src/auth/reset-password-form-labels.ts +0 -27
  385. package/src/auth/reset-password-form.tsx +0 -341
  386. package/src/auth/sign-in-form-labels.ts +0 -44
  387. package/src/auth/sign-in-form.tsx +0 -858
  388. package/src/auth/status-parts.tsx +0 -132
  389. package/src/auth/verify-email-labels.ts +0 -26
  390. package/src/auth/verify-email.tsx +0 -445
  391. package/src/billing/billing-banner.tsx +0 -258
  392. package/src/billing/billing-labels.ts +0 -381
  393. package/src/billing/billing-lock.ts +0 -108
  394. package/src/billing/billing-overview.ts +0 -157
  395. package/src/billing/billing-standing.ts +0 -80
  396. package/src/billing/cancel-request.ts +0 -97
  397. package/src/billing/cancel-subscription.tsx +0 -98
  398. package/src/billing/checkout-processing.ts +0 -394
  399. package/src/billing/checkout-return.ts +0 -90
  400. package/src/billing/pay-page.ts +0 -330
  401. package/src/billing/plan-card.tsx +0 -562
  402. package/src/billing/plan-change-labels.ts +0 -66
  403. package/src/billing/plan-limit-notice.tsx +0 -148
  404. package/src/billing/plan-limit-toast.tsx +0 -90
  405. package/src/billing/plan-limit.ts +0 -52
  406. package/src/billing/plan-price.ts +0 -98
  407. package/src/billing/plan-switch.tsx +0 -216
  408. package/src/billing/provider-page.ts +0 -84
  409. package/src/billing/subscription-actions.tsx +0 -247
  410. package/src/billing/subscription-status-chip.tsx +0 -95
  411. package/src/chart.ts +0 -103
  412. package/src/components/account-chips-labels.ts +0 -16
  413. package/src/components/account-chips.tsx +0 -474
  414. package/src/components/alert-banner.tsx +0 -670
  415. package/src/components/amount-input.tsx +0 -815
  416. package/src/components/appearance-labels.ts +0 -63
  417. package/src/components/authed-image-labels.ts +0 -11
  418. package/src/components/authed-image.tsx +0 -209
  419. package/src/components/autocomplete.tsx +0 -645
  420. package/src/components/breadcrumbs-labels.ts +0 -10
  421. package/src/components/breadcrumbs.tsx +0 -205
  422. package/src/components/bulk-action-bar-labels.ts +0 -11
  423. package/src/components/bulk-action-bar.tsx +0 -443
  424. package/src/components/button-group.tsx +0 -223
  425. package/src/components/button-look.ts +0 -256
  426. package/src/components/button.tsx +0 -339
  427. package/src/components/calculator.tsx +0 -341
  428. package/src/components/calendar-heatmap-labels.ts +0 -15
  429. package/src/components/calendar-heatmap.tsx +0 -594
  430. package/src/components/card.tsx +0 -377
  431. package/src/components/chart-edge.ts +0 -106
  432. package/src/components/chart-figure.tsx +0 -35
  433. package/src/components/chart-height.ts +0 -30
  434. package/src/components/chart-zoom-core.tsx +0 -627
  435. package/src/components/chart-zoom.tsx +0 -22
  436. package/src/components/chart.tsx +0 -554
  437. package/src/components/checkbox-group.tsx +0 -247
  438. package/src/components/checkbox.tsx +0 -346
  439. package/src/components/chip-input.tsx +0 -370
  440. package/src/components/chip-labels.ts +0 -13
  441. package/src/components/chip.tsx +0 -843
  442. package/src/components/choice-card.tsx +0 -544
  443. package/src/components/column-mapper-labels.ts +0 -38
  444. package/src/components/column-mapper.tsx +0 -655
  445. package/src/components/combobox-core.tsx +0 -1321
  446. package/src/components/combobox-suggestions.tsx +0 -131
  447. package/src/components/combobox.tsx +0 -716
  448. package/src/components/confirm-context.ts +0 -7
  449. package/src/components/confirm-dialog-labels.ts +0 -13
  450. package/src/components/confirm-dialog.tsx +0 -341
  451. package/src/components/copy-button-labels.ts +0 -13
  452. package/src/components/copy-button.tsx +0 -192
  453. package/src/components/country-select-labels.ts +0 -11
  454. package/src/components/country-select.tsx +0 -539
  455. package/src/components/currency-option-list.tsx +0 -180
  456. package/src/components/currency-select.tsx +0 -341
  457. package/src/components/danger-confirm-labels.ts +0 -20
  458. package/src/components/danger-confirm.tsx +0 -934
  459. package/src/components/data-table-cells.tsx +0 -118
  460. package/src/components/data-table-column-settings.tsx +0 -198
  461. package/src/components/data-table-filter-popover.tsx +0 -281
  462. package/src/components/data-table-filters.ts +0 -287
  463. package/src/components/data-table-fit.ts +0 -301
  464. package/src/components/data-table-groups.tsx +0 -288
  465. package/src/components/data-table-head.tsx +0 -280
  466. package/src/components/data-table-labels.ts +0 -198
  467. package/src/components/data-table-leading-row.tsx +0 -58
  468. package/src/components/data-table-mobile.tsx +0 -1117
  469. package/src/components/data-table-pagination.tsx +0 -202
  470. package/src/components/data-table-resize.ts +0 -188
  471. package/src/components/data-table-row-actions.tsx +0 -302
  472. package/src/components/data-table-row.tsx +0 -496
  473. package/src/components/data-table-selection.ts +0 -71
  474. package/src/components/data-table-shared.tsx +0 -287
  475. package/src/components/data-table-sort.ts +0 -163
  476. package/src/components/data-table-virtual.ts +0 -576
  477. package/src/components/data-table.tsx +0 -2598
  478. package/src/components/date-field.tsx +0 -684
  479. package/src/components/date-format-setting.tsx +0 -64
  480. package/src/components/date-picker.tsx +0 -404
  481. package/src/components/date-range-picker.tsx +0 -518
  482. package/src/components/description-list-labels.ts +0 -9
  483. package/src/components/description-list.tsx +0 -386
  484. package/src/components/dialog-frame-labels.ts +0 -7
  485. package/src/components/dialog-frame.tsx +0 -276
  486. package/src/components/disclosure.tsx +0 -476
  487. package/src/components/dropdown.tsx +0 -461
  488. package/src/components/empty-state.tsx +0 -136
  489. package/src/components/entity-combobox.tsx +0 -422
  490. package/src/components/error-boundary-labels.ts +0 -20
  491. package/src/components/error-boundary.tsx +0 -675
  492. package/src/components/facing-pair.ts +0 -93
  493. package/src/components/field-base-labels.ts +0 -20
  494. package/src/components/field-base.tsx +0 -656
  495. package/src/components/field-parts.tsx +0 -825
  496. package/src/components/field-strip.tsx +0 -129
  497. package/src/components/field.tsx +0 -206
  498. package/src/components/file-button.tsx +0 -295
  499. package/src/components/file-dropzone.tsx +0 -559
  500. package/src/components/floating-panel-labels.ts +0 -10
  501. package/src/components/floating-panel.tsx +0 -828
  502. package/src/components/focus-ring.ts +0 -16
  503. package/src/components/form-actions-labels.ts +0 -11
  504. package/src/components/form-actions.tsx +0 -578
  505. package/src/components/full-bleed-dialog.tsx +0 -294
  506. package/src/components/grouped-picker.tsx +0 -184
  507. package/src/components/help-popover.tsx +0 -117
  508. package/src/components/hover-menu.tsx +0 -343
  509. package/src/components/iban-input-labels.ts +0 -14
  510. package/src/components/iban-input.tsx +0 -236
  511. package/src/components/icon-button.tsx +0 -959
  512. package/src/components/icon-picker-labels.ts +0 -13
  513. package/src/components/icon-picker.tsx +0 -232
  514. package/src/components/image-grid-labels.ts +0 -11
  515. package/src/components/image-grid.tsx +0 -202
  516. package/src/components/inline-confirm.tsx +0 -116
  517. package/src/components/inline-edit-field-labels.ts +0 -11
  518. package/src/components/inline-edit-field.tsx +0 -552
  519. package/src/components/inline-entity-combobox.tsx +0 -849
  520. package/src/components/input.tsx +0 -394
  521. package/src/components/jump-calendar.tsx +0 -265
  522. package/src/components/language-select.tsx +0 -93
  523. package/src/components/legal-labels.ts +0 -105
  524. package/src/components/legal-page.tsx +0 -711
  525. package/src/components/legal.tsx +0 -668
  526. package/src/components/lightbox-labels.ts +0 -18
  527. package/src/components/lightbox.tsx +0 -399
  528. package/src/components/line-items-labels.ts +0 -14
  529. package/src/components/line-items.tsx +0 -602
  530. package/src/components/list-labels.ts +0 -12
  531. package/src/components/list.tsx +0 -870
  532. package/src/components/loading-state.tsx +0 -78
  533. package/src/components/measured-grid-labels.ts +0 -25
  534. package/src/components/measured-grid.tsx +0 -837
  535. package/src/components/menu-item.tsx +0 -241
  536. package/src/components/mini-calendar-labels.ts +0 -17
  537. package/src/components/mini-calendar.tsx +0 -789
  538. package/src/components/modal.tsx +0 -505
  539. package/src/components/money-draft.ts +0 -83
  540. package/src/components/money-field.tsx +0 -76
  541. package/src/components/month-grid.tsx +0 -229
  542. package/src/components/month-picker-labels.ts +0 -22
  543. package/src/components/month-picker.tsx +0 -1087
  544. package/src/components/multi-entity-combobox.tsx +0 -369
  545. package/src/components/multi-select.tsx +0 -376
  546. package/src/components/nav-pills.tsx +0 -198
  547. package/src/components/number-field.tsx +0 -327
  548. package/src/components/number-input.tsx +0 -558
  549. package/src/components/numeric-field.ts +0 -169
  550. package/src/components/numpad-sheet.tsx +0 -285
  551. package/src/components/one-time-code-input.tsx +0 -270
  552. package/src/components/page-contents-labels.ts +0 -9
  553. package/src/components/page-contents.tsx +0 -282
  554. package/src/components/page-header-context.ts +0 -8
  555. package/src/components/page-header.tsx +0 -298
  556. package/src/components/password-strength-labels.ts +0 -22
  557. package/src/components/password-strength.tsx +0 -241
  558. package/src/components/phone-input-labels.ts +0 -10
  559. package/src/components/phone-input.tsx +0 -282
  560. package/src/components/picker-sheet.tsx +0 -330
  561. package/src/components/pie-chart-labels.ts +0 -40
  562. package/src/components/pie-chart.tsx +0 -480
  563. package/src/components/popover-labels.ts +0 -14
  564. package/src/components/popover.tsx +0 -268
  565. package/src/components/progress-bar-labels.ts +0 -10
  566. package/src/components/progress-bar.tsx +0 -479
  567. package/src/components/qr-code.tsx +0 -76
  568. package/src/components/reauth-dialog-labels.ts +0 -13
  569. package/src/components/reauth-dialog.tsx +0 -265
  570. package/src/components/row-actions-labels.ts +0 -12
  571. package/src/components/row-actions.tsx +0 -795
  572. package/src/components/scroll-area.tsx +0 -123
  573. package/src/components/search-field.tsx +0 -192
  574. package/src/components/select.tsx +0 -294
  575. package/src/components/separator.tsx +0 -33
  576. package/src/components/series-chart-axes.ts +0 -342
  577. package/src/components/series-chart-budget.ts +0 -150
  578. package/src/components/series-chart-labels.ts +0 -33
  579. package/src/components/series-chart-thin.ts +0 -180
  580. package/src/components/series-chart-ticks.ts +0 -194
  581. package/src/components/series-chart.tsx +0 -1906
  582. package/src/components/server-wake-labels.ts +0 -11
  583. package/src/components/server-wake.tsx +0 -129
  584. package/src/components/settings-fields.tsx +0 -237
  585. package/src/components/share-card-labels.ts +0 -30
  586. package/src/components/share-card.tsx +0 -675
  587. package/src/components/signature-pad-labels.ts +0 -24
  588. package/src/components/signature-pad.tsx +0 -747
  589. package/src/components/signed-amount-labels.ts +0 -10
  590. package/src/components/signed-amount.tsx +0 -336
  591. package/src/components/skeleton.tsx +0 -80
  592. package/src/components/slider.tsx +0 -338
  593. package/src/components/sparkline-labels.ts +0 -14
  594. package/src/components/sparkline.tsx +0 -322
  595. package/src/components/spinner.tsx +0 -81
  596. package/src/components/stat-tile-labels.ts +0 -15
  597. package/src/components/stat-tile.tsx +0 -725
  598. package/src/components/status-dot.tsx +0 -170
  599. package/src/components/swatch-picker-labels.ts +0 -10
  600. package/src/components/swatch-picker.tsx +0 -283
  601. package/src/components/swipeable-row.tsx +0 -386
  602. package/src/components/switch.tsx +0 -273
  603. package/src/components/table-skeleton.tsx +0 -136
  604. package/src/components/table.tsx +0 -647
  605. package/src/components/tabs-labels.ts +0 -13
  606. package/src/components/tabs.tsx +0 -693
  607. package/src/components/text-link.tsx +0 -359
  608. package/src/components/text.tsx +0 -150
  609. package/src/components/textarea.tsx +0 -330
  610. package/src/components/tile-radio.tsx +0 -332
  611. package/src/components/time-input.tsx +0 -121
  612. package/src/components/toast-labels.ts +0 -12
  613. package/src/components/toast.tsx +0 -519
  614. package/src/components/toggle-group.tsx +0 -752
  615. package/src/components/toggle-legend.tsx +0 -394
  616. package/src/components/tooltip.tsx +0 -1149
  617. package/src/components/translation-review-editor.tsx +0 -290
  618. package/src/components/translation-review-labels.ts +0 -181
  619. package/src/components/translation-review-parts.tsx +0 -272
  620. package/src/components/translation-review.tsx +0 -1240
  621. package/src/components/tree-view.tsx +0 -589
  622. package/src/components/treemap-labels.ts +0 -47
  623. package/src/components/treemap-layout.ts +0 -210
  624. package/src/components/treemap.tsx +0 -1184
  625. package/src/components/trigger-aria.ts +0 -44
  626. package/src/components/use-anchor-dir.ts +0 -20
  627. package/src/components/use-mobile-reveal.ts +0 -62
  628. package/src/components/use-table-state.ts +0 -753
  629. package/src/components/user-avatar.tsx +0 -116
  630. package/src/components/wizard-stepper.tsx +0 -42
  631. package/src/components/write-lock-labels.ts +0 -10
  632. package/src/components/write-lock.tsx +0 -253
  633. package/src/currencies.ts +0 -70
  634. package/src/data-table.ts +0 -42
  635. package/src/demo/demo-banner.tsx +0 -153
  636. package/src/demo/demo-countdown.ts +0 -136
  637. package/src/demo/demo-ended.tsx +0 -90
  638. package/src/demo/demo-labels.ts +0 -78
  639. package/src/demo/demo-session.ts +0 -32
  640. package/src/demo/demo-start.tsx +0 -156
  641. package/src/eslint/index.ts +0 -161
  642. package/src/eslint/role-utilities.generated.ts +0 -146
  643. package/src/eslint/role-utilities.ts +0 -233
  644. package/src/feedback/feedback-attachment-download.tsx +0 -77
  645. package/src/feedback/feedback-attachment-labels.ts +0 -37
  646. package/src/feedback/feedback-attachment.tsx +0 -1239
  647. package/src/feedback/feedback-capture.ts +0 -287
  648. package/src/feedback/feedback-comment-thread.tsx +0 -353
  649. package/src/feedback/feedback-context-labels.ts +0 -10
  650. package/src/feedback/feedback-context.tsx +0 -213
  651. package/src/feedback/feedback-crash.ts +0 -547
  652. package/src/feedback/feedback-dialog-labels.ts +0 -29
  653. package/src/feedback/feedback-dialog.tsx +0 -440
  654. package/src/feedback/feedback-entry-file.tsx +0 -150
  655. package/src/feedback/feedback-inbox.tsx +0 -552
  656. package/src/feedback/feedback-labels.ts +0 -144
  657. package/src/feedback/feedback-menu-labels.ts +0 -12
  658. package/src/feedback/feedback-menu.tsx +0 -177
  659. package/src/feedback/feedback-mutation.ts +0 -20
  660. package/src/feedback/feedback-page-link.ts +0 -90
  661. package/src/feedback/feedback-public-labels.ts +0 -81
  662. package/src/feedback/feedback-public-list.tsx +0 -524
  663. package/src/feedback/feedback-public-switch.tsx +0 -102
  664. package/src/feedback/feedback-public-types.ts +0 -101
  665. package/src/feedback/feedback-record.ts +0 -423
  666. package/src/feedback/feedback-replies-context.ts +0 -9
  667. package/src/feedback/feedback-replies.tsx +0 -343
  668. package/src/feedback/feedback-rework-entry-chip.tsx +0 -18
  669. package/src/feedback/feedback-row-detail-labels.ts +0 -30
  670. package/src/feedback/feedback-row-detail.tsx +0 -858
  671. package/src/feedback/feedback-status-undo.ts +0 -109
  672. package/src/feedback/feedback-submit-dialog.tsx +0 -118
  673. package/src/feedback/feedback-submit.tsx +0 -237
  674. package/src/feedback/feedback-swipe.tsx +0 -192
  675. package/src/feedback/feedback-table-labels.ts +0 -27
  676. package/src/feedback/feedback-table.tsx +0 -912
  677. package/src/feedback/feedback-thread-labels.ts +0 -22
  678. package/src/feedback/feedback-thread-parts-labels.ts +0 -41
  679. package/src/feedback/feedback-thread.tsx +0 -905
  680. package/src/feedback/feedback-vocabulary.ts +0 -263
  681. package/src/feedback/feedback-vote-button.tsx +0 -124
  682. package/src/feedback.ts +0 -116
  683. package/src/hooks/use-anchored-panel.ts +0 -396
  684. package/src/hooks/use-anchored-rect.ts +0 -77
  685. package/src/hooks/use-announce.ts +0 -85
  686. package/src/hooks/use-authed-src.ts +0 -167
  687. package/src/hooks/use-body-scroll-lock.ts +0 -119
  688. package/src/hooks/use-breakpoint.ts +0 -133
  689. package/src/hooks/use-close-transition.ts +0 -107
  690. package/src/hooks/use-copy-to-clipboard.ts +0 -122
  691. package/src/hooks/use-debounce.ts +0 -114
  692. package/src/hooks/use-dismiss.ts +0 -371
  693. package/src/hooks/use-document-title.ts +0 -33
  694. package/src/hooks/use-file-drop.ts +0 -121
  695. package/src/hooks/use-file-picker-labels.ts +0 -28
  696. package/src/hooks/use-file-picker.tsx +0 -359
  697. package/src/hooks/use-focus-trap.ts +0 -199
  698. package/src/hooks/use-hotkey.ts +0 -189
  699. package/src/hooks/use-large-text.ts +0 -41
  700. package/src/hooks/use-long-press.ts +0 -140
  701. package/src/hooks/use-media-query.ts +0 -39
  702. package/src/hooks/use-mounted.ts +0 -39
  703. package/src/hooks/use-noindex.ts +0 -37
  704. package/src/hooks/use-overlay-history.ts +0 -714
  705. package/src/hooks/use-row-swipe.ts +0 -207
  706. package/src/hooks/use-search-param-state.ts +0 -434
  707. package/src/hooks/use-windowed-rows.ts +0 -225
  708. package/src/i18n/defaults.ts +0 -267
  709. package/src/i18n/german.ts +0 -2057
  710. package/src/i18n/kit-labels.tsx +0 -1003
  711. package/src/i18n/languages.ts +0 -349
  712. package/src/i18n/locales/de-CH.ts +0 -24
  713. package/src/i18n/locales/en.ts +0 -267
  714. package/src/i18n/locales/es.ts +0 -1997
  715. package/src/i18n/locales/fr.ts +0 -2035
  716. package/src/i18n/locales/hu.ts +0 -2002
  717. package/src/i18n/locales/it.ts +0 -2012
  718. package/src/i18n/locales/zh.ts +0 -1910
  719. package/src/i18n/plurals.ts +0 -86
  720. package/src/i18n/review.ts +0 -475
  721. package/src/i18n/shared-labels.ts +0 -138
  722. package/src/i18n/swiss.ts +0 -29
  723. package/src/index.ts +0 -1179
  724. package/src/landing/access.ts +0 -93
  725. package/src/landing/landing-actions.tsx +0 -97
  726. package/src/landing/landing-labels.ts +0 -59
  727. package/src/landing/landing-sections.tsx +0 -341
  728. package/src/landing/page-seo.ts +0 -261
  729. package/src/landing/public-header.tsx +0 -121
  730. package/src/landing/public-page.tsx +0 -106
  731. package/src/landing/routing.tsx +0 -225
  732. package/src/lib/broadcast.ts +0 -52
  733. package/src/lib/calc.ts +0 -323
  734. package/src/lib/chip-edge-snap.ts +0 -212
  735. package/src/lib/clipboard-minus.ts +0 -107
  736. package/src/lib/clipping.ts +0 -34
  737. package/src/lib/cn.ts +0 -28
  738. package/src/lib/column-mapping.ts +0 -234
  739. package/src/lib/countries.ts +0 -91
  740. package/src/lib/data-attributes.ts +0 -14
  741. package/src/lib/date-format.ts +0 -227
  742. package/src/lib/dates.ts +0 -266
  743. package/src/lib/day-format.ts +0 -96
  744. package/src/lib/decimal-marks.ts +0 -108
  745. package/src/lib/describe-failure.ts +0 -18
  746. package/src/lib/device-settings.ts +0 -147
  747. package/src/lib/direction.ts +0 -74
  748. package/src/lib/document-navigation.ts +0 -17
  749. package/src/lib/document-title.ts +0 -41
  750. package/src/lib/download.ts +0 -172
  751. package/src/lib/float-clearance.ts +0 -70
  752. package/src/lib/floating-stack.ts +0 -70
  753. package/src/lib/focus-left.ts +0 -156
  754. package/src/lib/format.ts +0 -522
  755. package/src/lib/http-status.ts +0 -38
  756. package/src/lib/iban.ts +0 -251
  757. package/src/lib/ime.ts +0 -24
  758. package/src/lib/intl-cache.ts +0 -25
  759. package/src/lib/iso-day.ts +0 -13
  760. package/src/lib/lazy-with-fallback.ts +0 -82
  761. package/src/lib/logger.ts +0 -69
  762. package/src/lib/minus.ts +0 -50
  763. package/src/lib/path-pattern.ts +0 -55
  764. package/src/lib/person-name.ts +0 -155
  765. package/src/lib/phone.ts +0 -208
  766. package/src/lib/plain-text.ts +0 -22
  767. package/src/lib/presence.ts +0 -18
  768. package/src/lib/qr-encode.ts +0 -444
  769. package/src/lib/quiet-focus.ts +0 -32
  770. package/src/lib/reduced-motion.ts +0 -22
  771. package/src/lib/refs.ts +0 -22
  772. package/src/lib/round.ts +0 -43
  773. package/src/lib/safe-storage.ts +0 -119
  774. package/src/lib/server-wake.ts +0 -315
  775. package/src/lib/session-refresh.ts +0 -472
  776. package/src/lib/share-format.ts +0 -18
  777. package/src/lib/status-tone.ts +0 -43
  778. package/src/lib/strip-fade.ts +0 -287
  779. package/src/lib/table-text.ts +0 -554
  780. package/src/lib/text-case.ts +0 -19
  781. package/src/lib/text-match.ts +0 -169
  782. package/src/lib/thenable.ts +0 -19
  783. package/src/lib/translation-review.ts +0 -717
  784. package/src/notifications/device-zone-report.ts +0 -67
  785. package/src/notifications/feedback-notification-types-labels.ts +0 -33
  786. package/src/notifications/feedback-notification-types.ts +0 -71
  787. package/src/notifications/notification-bell.tsx +0 -119
  788. package/src/notifications/notification-inbox.tsx +0 -309
  789. package/src/notifications/notification-parts.tsx +0 -81
  790. package/src/notifications/notification-types-setting.tsx +0 -406
  791. package/src/notifications/notification-types.ts +0 -89
  792. package/src/notifications/notifications-labels.ts +0 -287
  793. package/src/notifications/push-device-setting.tsx +0 -230
  794. package/src/notifications/push-devices-setting.tsx +0 -374
  795. package/src/notifications/push-worker.ts +0 -168
  796. package/src/notifications/quiet-hours-setting.tsx +0 -238
  797. package/src/notifications/unsubscribe-panel.tsx +0 -200
  798. package/src/notifications/use-push-device.ts +0 -448
  799. package/src/offline/local-first.ts +0 -100
  800. package/src/offline/pwa-update-prompt-labels.ts +0 -9
  801. package/src/offline/pwa-update-prompt.tsx +0 -78
  802. package/src/offline/query-persistence.ts +0 -391
  803. package/src/offline/service-worker-updates.ts +0 -81
  804. package/src/offline/shared-computer-labels.ts +0 -8
  805. package/src/offline/shared-computer.tsx +0 -87
  806. package/src/offline/sign-out-pending-dialog-labels.ts +0 -21
  807. package/src/offline/sign-out-pending-dialog.tsx +0 -135
  808. package/src/offline.ts +0 -37
  809. package/src/push-worker.ts +0 -25
  810. package/src/rhf/fields.tsx +0 -2187
  811. package/src/rhf/form-core.tsx +0 -324
  812. package/src/rhf/form.tsx +0 -12
  813. package/src/rhf/line-items.tsx +0 -135
  814. package/src/rhf/use-rhf-wizard-step.ts +0 -104
  815. package/src/rhf.ts +0 -21
  816. package/src/search/command-palette-labels.ts +0 -16
  817. package/src/search/command-palette.tsx +0 -624
  818. package/src/search/global-search-labels.ts +0 -13
  819. package/src/search/global-search.tsx +0 -660
  820. package/src/search/search-index.ts +0 -283
  821. package/src/search/use-command-key.ts +0 -23
  822. package/src/search.ts +0 -14
  823. package/src/settings/device-reset-setting-labels.ts +0 -20
  824. package/src/settings/device-reset-setting.tsx +0 -116
  825. package/src/settings/settings-card-classes.ts +0 -11
  826. package/src/settings/settings-catalogue.ts +0 -150
  827. package/src/settings/settings-context.ts +0 -33
  828. package/src/settings/settings-heading.tsx +0 -67
  829. package/src/settings/settings-labels.ts +0 -87
  830. package/src/settings/settings-layout.tsx +0 -471
  831. package/src/settings/settings-section.tsx +0 -108
  832. package/src/settings/use-account-appearance.ts +0 -148
  833. package/src/settings/use-account-language.ts +0 -146
  834. package/src/settings/use-settings-focus.ts +0 -128
  835. package/src/settings/use-settings-route.ts +0 -258
  836. package/src/shell/account-menu-language.tsx +0 -130
  837. package/src/shell/account-menu-text-size.tsx +0 -80
  838. package/src/shell/admin-menu.tsx +0 -183
  839. package/src/shell/app-shell-labels.ts +0 -11
  840. package/src/shell/app-shell.tsx +0 -1560
  841. package/src/shell/auth-layout.tsx +0 -186
  842. package/src/shell/company-switcher-labels.ts +0 -13
  843. package/src/shell/company-switcher.tsx +0 -136
  844. package/src/shell/dev-menu.tsx +0 -257
  845. package/src/shell/fill-height.tsx +0 -45
  846. package/src/shell/language-code.ts +0 -5
  847. package/src/shell/option-switcher-menu.tsx +0 -84
  848. package/src/shell/sync-status-indicator.tsx +0 -303
  849. package/src/shell/top-bar-actions.tsx +0 -87
  850. package/src/shell/top-bar-brand.tsx +0 -78
  851. package/src/shell/top-bar-parts-labels.ts +0 -148
  852. package/src/shell/top-bar.tsx +0 -40
  853. package/src/shell/topbar-action-menu.tsx +0 -567
  854. package/src/shell/topbar-controls.tsx +0 -269
  855. package/src/shell/tour-menu.tsx +0 -187
  856. package/src/shell.ts +0 -108
  857. package/src/sync/db.ts +0 -129
  858. package/src/sync/engine.ts +0 -1011
  859. package/src/sync/hooks.ts +0 -98
  860. package/src/sync/testing.ts +0 -73
  861. package/src/sync/wire.ts +0 -61
  862. package/src/sync.ts +0 -37
  863. package/src/table-text.ts +0 -8
  864. package/src/testing/css-variables.generated.ts +0 -112
  865. package/src/testing/css-variables.ts +0 -189
  866. package/src/testing/index.ts +0 -29
  867. package/src/testing/react.ts +0 -58
  868. package/src/testing/tour.ts +0 -41
  869. package/src/testing/viewport.ts +0 -357
  870. package/src/theme/chart-palette.ts +0 -232
  871. package/src/theme/color.ts +0 -272
  872. package/src/theme/contrast-tokens.ts +0 -268
  873. package/src/theme/contrast.ts +0 -250
  874. package/src/theme/palette-derive.ts +0 -825
  875. package/src/theme/palette-presets.ts +0 -544
  876. package/src/theme/palette-store.ts +0 -108
  877. package/src/theme/text-size.ts +0 -289
  878. package/src/theme/theme-store.ts +0 -157
  879. package/src/tour/tour-catalogue-labels.ts +0 -75
  880. package/src/tour/tour-catalogue.tsx +0 -335
  881. package/src/tour/tour-dock.ts +0 -134
  882. package/src/tour/tour-engine.ts +0 -37
  883. package/src/tour/tour-gates.ts +0 -218
  884. package/src/tour/tour-guide-button.tsx +0 -64
  885. package/src/tour/tour-guide-labels.ts +0 -15
  886. package/src/tour/tour-info.ts +0 -144
  887. package/src/tour/tour-labels.ts +0 -23
  888. package/src/tour/tour-overlay.tsx +0 -1170
  889. package/src/tour/tour.tsx +0 -750
  890. package/src/tour/use-tour-progress.ts +0 -671
  891. package/src/tour/use-tour-url-sync.ts +0 -266
  892. package/src/tour.ts +0 -21
  893. package/src/vite-env.d.ts +0 -23
  894. package/src/wizard/stepper-nav.tsx +0 -360
  895. package/src/wizard/types.ts +0 -275
  896. package/src/wizard/use-wizard.ts +0 -560
  897. package/src/wizard/validation.ts +0 -39
  898. package/src/wizard/wizard-context.tsx +0 -74
  899. package/src/wizard/wizard-labels.ts +0 -29
  900. package/src/wizard/wizard-step.tsx +0 -76
  901. package/src/wizard/wizard-summary.tsx +0 -84
  902. package/src/wizard.ts +0 -15
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/rhf/fields.tsx"],"sourcesContent":["/**\n * Bound fields: one line per field of a react-hook-form form. `@eifi1/ui-kit/rhf`.\n *\n * ```tsx\n * <Form {...form}>\n * <RhfTextField name=\"name\" label=\"Name\" hint=\"As on the lease\" required\n * rules={{ required: \"Enter a name\" }} />\n * <RhfMoneyField name=\"rent\" label=\"Net rent\" currency=\"CHF\" />\n * <RhfDateField name=\"start\" label=\"Start\" />\n * <RhfSelect name=\"type\" label=\"Type\" options={TYPES} />\n * <RhfCombobox name=\"tenantId\" label=\"Tenant\" options={tenants} clearable />\n * <RhfInlineEntityCombobox name=\"accountId\" label=\"Account\" options={accounts} />\n * <RhfCheckbox name=\"isDefault\" label=\"Default account\" />\n * <RhfTimeInput name=\"meetingTime\" label=\"Time\" />\n * <RhfDateRangePicker fromName=\"periodFrom\" toName=\"periodTo\" label=\"Period\" />\n * <RhfToggleGroup name=\"interval\" label=\"Interval\" options={INTERVALS} />\n * <RhfCountrySelect name=\"country\" label=\"Country\" preferred={[\"CH\", \"DE\"]} />\n * <RhfMonthPicker name=\"fiscalYear\" label=\"Fiscal year\" mode=\"year\" valueAsNumber />\n * </Form>\n * ```\n *\n * Each folds the `FormField → FormItem → FormLabel → FormControl → field →\n * FormDescription → FormMessage` scaffold (see ./form-core) into one element, the way\n * kastlan's shared/components/form/fields.tsx does for its forms — with what that file\n * left out:\n *\n * - **The red border.** Every field gets `invalid` from the field state, so an errored\n * field PAINTS as well as announces. kastlan's number, money, date and entity fields\n * passed only `aria-invalid` through `FormControl`, or nothing, and `Input`, `Select`\n * and `Textarea` paint only from the prop (see the note in ./form-core).\n * - **Focus on error.** `field.ref` reaches the focusable element itself — the input,\n * a picker's trigger, a toggle group whose `focus()` lands on its option (since 0.34\n * every kit field takes a ref; the number field and the pickers were reached by an id\n * lookup before, API-3) — so `handleSubmit` and `trigger(…, { shouldFocus })` land the\n * caret on the first field in error, and `setFocus`'s `shouldSelect` selects.\n * - **`control` is optional**: under `<Form {...form}>` the fields find the form\n * through react-hook-form's context. Pass it for the field's value types\n * (`control={form.control}` checks `name` against the form's values).\n *\n * The common props: `name`, `control`, `label` (the label above the field;\n * omitted, none — then give the field an `aria-label`), `hint` (standing advice under\n * the field, attached to it with `aria-describedby`), `required` (the label's mark,\n * and `aria-required` where the control takes it — validation is `rules`' or the\n * resolver's), `rules`, `disabled` (the control only — the value is still submitted;\n * `excludeWhenDisabled` for react-hook-form's drop-the-value semantics), and\n * `className` for the item's box.\n *\n * {@link RhfField} is the shell they are all built on, for a control the kit does not\n * ship (an address autocomplete): it takes a `render` and wires the rest.\n */\nimport { useLayoutEffect, useMemo, useRef, type FocusEvent, type ReactElement, type ReactNode } from \"react\";\nimport {\n useController,\n type ControllerFieldState,\n type ControllerProps,\n type ControllerRenderProps,\n type FieldPath,\n type FieldValues,\n} from \"react-hook-form\";\nimport { FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, useFormField } from \"./form-core\";\nimport { Input, type InputProps } from \"../components/input\";\nimport { Select, type SelectProps } from \"../components/select\";\nimport { Textarea, type TextareaProps } from \"../components/textarea\";\nimport { NumberField, type NumberFieldProps } from \"../components/number-field\";\nimport { AmountInput } from \"../components/amount-input\";\nimport type { MoneyFieldProps } from \"../components/money-field\";\nimport { useMoneyDraft } from \"../components/money-draft\";\nimport {\n DatePicker,\n DateRangePicker,\n type DatePickerProps,\n type DateRangePickerProps,\n} from \"../components/date-picker\";\nimport { TimeInput, type TimeInputProps } from \"../components/time-input\";\nimport { IbanInput, type IbanInputProps } from \"../components/iban-input\";\nimport { PhoneInput, type PhoneInputProps } from \"../components/phone-input\";\nimport { CountrySelect, type CountrySelectProps } from \"../components/country-select\";\nimport { MonthPicker, type MonthPickerProps } from \"../components/month-picker\";\nimport {\n ToggleGroup,\n type ToggleGroupBaseProps,\n type ToggleGroupClearableProps,\n type ToggleGroupRequiredProps,\n} from \"../components/toggle-group\";\nimport { Checkbox, type CheckboxProps } from \"../components/checkbox\";\nimport { EntityCombobox, type EntityComboboxProps } from \"../components/entity-combobox\";\nimport {\n Combobox,\n InlineEntityCombobox,\n type ComboboxProps,\n type InlineEntityComboboxProps,\n} from \"../components/combobox\";\nimport type { ComboClearValue } from \"../components/combobox-core\";\nimport { fieldHelpMark, mergeRefs, useInlineHint } from \"../components/field-parts\";\nimport { useKitLocale } from \"../i18n/kit-labels\";\nimport { cn } from \"../lib/cn\";\nimport { decimalMark, readTyped } from \"../lib/decimal-marks\";\nimport { hasContent } from \"../lib/presence\";\n\n// ── the shell ────────────────────────────────────────────────────────────────\n\n/** What every bound field takes. */\nexport interface RhfFieldBaseProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> {\n name: TName;\n /** `form.control`. Optional under `<Form {...form}>`; pass it to type-check `name`. */\n control?: ControllerProps<TFieldValues, TName, TTransformed>[\"control\"];\n /** react-hook-form's `rules` (`required`, `min`, `validate` …). */\n rules?: ControllerProps<TFieldValues, TName, TTransformed>[\"rules\"];\n /** The label above the field. Omitted: no label — name the control with\n * an `aria-label` instead. */\n label?: ReactNode;\n /** Standing advice under the field (\"As printed on the card\"), attached to the\n * control with `aria-describedby`. A `FieldHint` is its words at Large and on a\n * touch screen (§4, DUP-2), not a lone \"?\"; a `HelpPopover` stays a \"?\". Beside a\n * `help` it is that caption at every size. */\n hint?: ReactNode;\n /** Help the field is usable without — why, how to choose — behind the field's one\n * \"?\" after the label: a `HelpPopover` named \"About “<label>”\" (round 0.36,\n * docs/text-size-harmonization.md §4); pass a `HelpPopover` to name it yourself.\n * `hint` stays the visible fact under the field. */\n help?: ReactNode;\n /** Draws the label's required mark and sets `aria-required` where the control\n * takes it. Whether the field IS required is `rules`' or the resolver's to say. */\n required?: boolean;\n /** Disables the control and KEEPS the value: a field locked to a preset (a lease's\n * preselected unit, a fixed period) still submits it, and `rules` still run.\n * react-hook-form's own Controller `disabled` drops the value from `handleSubmit`'s\n * data instead, which a locked preset must never do (kastlan, 0.12). To get that,\n * add `excludeWhenDisabled`. A form-wide `useForm({ disabled })` still disables\n * every field the RHF way. */\n disabled?: boolean;\n /** With `disabled`: disable through react-hook-form, so the value is left out of\n * the submitted data and validation skips it, like a disabled native input in a\n * plain form post. Default `false`. */\n excludeWhenDisabled?: boolean;\n /** Classes for the item's box (a `grid gap-1`). */\n className?: string;\n}\n\n/** What {@link RhfField}'s `render` receives. */\nexport interface RhfFieldRenderContext<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> {\n field: ControllerRenderProps<TFieldValues, TName>;\n fieldState: ControllerFieldState;\n /** The field has an error: pass it to the control's `invalid` so it paints. */\n invalid: boolean;\n /** The error's message, if any. */\n error: string | undefined;\n /** The control's id, which the label points at. The rendered element has it already\n * (unless `asControl` is false); this is for a control that routes it elsewhere. */\n id: string;\n /** The label's id, for a control that is named with `aria-labelledby`. */\n labelId: string;\n /** The ids of the rendered hint and message, if any. */\n describedBy: string | undefined;\n}\n\nexport interface RhfFieldProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> extends RhfFieldBaseProps<TFieldValues, TName, TTransformed> {\n /** The control. Given the field's `id`, `aria-describedby` and `aria-invalid` unless\n * `asControl` is false. */\n render: (ctx: RhfFieldRenderContext<TFieldValues, TName>) => ReactElement;\n /** `false`: render the control as is, for one that wires its own ids from the\n * context. Default `true`. */\n asControl?: boolean;\n /** `false`: no error message under the field, for a control that renders its own (its\n * `error` prop). Default `true`. */\n message?: boolean;\n /** `false`: no label above the field, for a control that carries its label itself (a\n * checkbox). Default `true`. */\n showLabel?: boolean;\n}\n\n/** The label, with an id the control can be named by. Inside the item, so it can read\n * the item's id. */\nfunction RhfLabel({ required, children }: { required?: boolean; children: ReactNode }) {\n const { id } = useFormField();\n return (\n <FormLabel id={`${id}-label`} required={required}>\n {children}\n </FormLabel>\n );\n}\n\nfunction ControlSlot<TFieldValues extends FieldValues, TName extends FieldPath<TFieldValues>>({\n field,\n fieldState,\n render,\n asControl,\n}: {\n field: ControllerRenderProps<TFieldValues, TName>;\n fieldState: ControllerFieldState;\n render: RhfFieldProps<TFieldValues, TName>[\"render\"];\n asControl: boolean;\n}) {\n const { id, formItemId, describedBy } = useFormField();\n const element = render({\n field,\n fieldState,\n invalid: fieldState.invalid,\n error: fieldState.error?.message,\n id: formItemId,\n labelId: `${id}-label`,\n describedBy,\n });\n return asControl ? <FormControl>{element}</FormControl> : element;\n}\n\n/**\n * The shell every bound field is built on: label, control, hint and message around\n * a `render` of your own.\n *\n * ```tsx\n * <RhfField name=\"address\" label=\"Address\" render={({ field, invalid }) => (\n * <AddressAutocomplete value={field.value ?? \"\"} onChange={field.onChange} invalid={invalid} />\n * )} />\n * ```\n */\nexport function RhfField<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n render,\n asControl = true,\n message = true,\n showLabel = true,\n}: RhfFieldProps<TFieldValues, TName, TTransformed>) {\n // §4: a FieldHint is a fact, so at Large and on a touch screen it is its words under\n // the field, not a lone \"?\" there (DUP-2, refactor audit 2026-10). A HelpPopover stays\n // a \"?\" at every size. With a `help` (0.36) its \"?\" follows the label and is the\n // field's only one, so a FieldHint is its words at every size.\n const helpMark = fieldHelpMark(help, label);\n const shownHint = useInlineHint(hint, helpMark !== undefined);\n const labelEl = showLabel && hasContent(label) && <RhfLabel required={required}>{label}</RhfLabel>;\n return (\n <FormField\n control={control}\n name={name}\n rules={rules}\n disabled={excludeWhenDisabled ? disabled : undefined}\n render={({ field, fieldState }) => (\n <FormItem className={className}>\n {helpMark === undefined ? (\n labelEl\n ) : (\n <div className=\"flex items-center gap-1\">\n {labelEl}\n <span className=\"flex shrink-0 items-center\">{helpMark}</span>\n </div>\n )}\n <ControlSlot\n field={disabled && !field.disabled ? { ...field, disabled: true } : field}\n fieldState={fieldState}\n render={render}\n asControl={asControl}\n />\n {hasContent(shownHint) && <FormDescription>{shownHint}</FormDescription>}\n {message && <FormMessage />}\n </FormItem>\n )}\n />\n );\n}\n\n// ── text ─────────────────────────────────────────────────────────────────────\n\ntype OwnInputProps = Omit<\n InputProps,\n | \"name\"\n | \"value\"\n | \"defaultValue\"\n | \"onChange\"\n | \"onBlur\"\n | \"ref\"\n | \"label\"\n | \"error\"\n | \"invalid\"\n | \"className\"\n | \"disabled\"\n | \"required\"\n | \"inputClassName\"\n> & {\n /**\n * Classes for the `<input>` — `className` is the item's box (kastlan 42: a\n * `font-mono` IBAN, a `tabular-nums` reference number). {@link RhfTextarea} and\n * {@link RhfNumberField} had it; this one only reached `Input`'s prop of the same\n * name by accident of the rest-spread, undocumented and one refactor from being\n * dropped. Declared, it is part of the contract the three share.\n */\n inputClassName?: string;\n};\n\nexport type RhfTextFieldProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> & OwnInputProps;\n\n/** A text {@link Input} — `type` for email, tel, password, url. Stores the string. */\nexport function RhfTextField<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n ...inputProps\n}: RhfTextFieldProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid }) => (\n <Input\n aria-required={required || undefined}\n {...inputProps}\n name={field.name}\n ref={field.ref}\n value={(field.value ?? \"\") as string}\n onChange={field.onChange}\n onBlur={field.onBlur}\n disabled={field.disabled}\n invalid={invalid}\n />\n )}\n />\n );\n}\n\ntype OwnTextareaProps = Omit<\n TextareaProps,\n | \"name\"\n | \"value\"\n | \"defaultValue\"\n | \"onChange\"\n | \"onBlur\"\n | \"ref\"\n | \"label\"\n | \"error\"\n | \"invalid\"\n | \"className\"\n | \"disabled\"\n | \"required\"\n> & {\n /** Classes for the `<textarea>`. */\n inputClassName?: string;\n};\n\nexport type RhfTextareaProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> & OwnTextareaProps;\n\n/** A multi-line {@link Textarea}; takes `rows`. Stores the string. */\nexport function RhfTextarea<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n inputClassName,\n ...areaProps\n}: RhfTextareaProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid }) => (\n <Textarea\n aria-required={required || undefined}\n {...areaProps}\n className={inputClassName}\n name={field.name}\n ref={field.ref}\n value={(field.value ?? \"\") as string}\n onChange={field.onChange}\n onBlur={field.onBlur}\n disabled={field.disabled}\n invalid={invalid}\n />\n )}\n />\n );\n}\n\n// ── numbers ──────────────────────────────────────────────────────────────────\n\n/**\n * A form value → the number field's `number | null`. Defaults hold `\"\"`, `null`, a\n * number, or a numeric string: a plain JS spelling (\"12.5\", \"1e-7\", what an API sends)\n * as it is, anything else the way the field reads typing in `mark` — \"1,234.5\", or\n * \"1.234,56\" in a comma locale (DUP-9, refactor audit 2026-10: a single\n * `replace(\",\", \".\")` read \"1,234,567\" as NaN, the U-14 pattern).\n */\nfunction toNumber(value: unknown, mark: \",\" | \".\"): number | null {\n if (value === null || value === undefined || value === \"\") return null;\n if (typeof value === \"number\") return Number.isFinite(value) ? value : null;\n const text = String(value).trim();\n const plain = text === \"\" ? NaN : Number(text);\n const typed = readTyped(text, mark);\n const n = Number.isFinite(plain) ? plain : typed === \"\" ? NaN : Number(typed);\n return Number.isFinite(n) ? n : null;\n}\n\n/** What a twin sets on its field itself — the value and its change, what the form\n * decides (`disabled`, `invalid`, the error, the ids) and what the shell draws (the\n * label, the hint, the item's `className`). Everything else of the field's passes\n * through (DUP-9, refactor audit 2026-10: a `Pick` allow-list dropped what the field\n * gained without a word). */\ntype BoundByForm =\n | \"value\"\n | \"defaultValue\"\n | \"onChange\"\n | \"onBlur\"\n | \"ref\"\n | \"name\"\n | \"disabled\"\n | \"required\"\n | \"invalid\"\n | \"error\"\n | \"label\"\n | \"hint\"\n | \"className\"\n | \"aria-describedby\"\n | \"aria-invalid\"\n | \"aria-required\";\n\nexport type RhfNumberFieldProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n // NumberField's own (the lock since 0.33.1, `onValueChange`, …), less the commit and\n // the id the shell owns.\n Omit<NumberFieldProps, BoundByForm | \"onCommit\" | \"nullable\" | \"id\"> & {\n /** What an emptied field stores. Default `null`; `\"\"` for a schema written\n * against a native number input (`z.coerce.number()` over `\"\"`). */\n emptyValue?: null | \"\";\n /** `false`: an emptied field snaps back to its last number instead of storing\n * `emptyValue`. Default `true`. */\n nullable?: boolean;\n };\n\n/**\n * The kit's {@link NumberField}: a parsed, rounded (`digits`) and clamped (`min` /\n * `max`) number, committed on blur or Enter in the locale's decimal mark. Stores a\n * number, or `emptyValue` when emptied.\n */\nexport function RhfNumberField<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n emptyValue = null,\n nullable = true,\n ...numberProps\n}: RhfNumberFieldProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid, id }) => (\n // FormControl clones this element with `id` / `aria-describedby` /\n // `aria-invalid`, which NumberControl hands on to the field.\n <NumberControl\n field={field as unknown as ControllerRenderProps}\n focusRef={field.ref}\n invalid={invalid}\n required={required}\n id={id}\n emptyValue={emptyValue}\n nullable={nullable}\n numberProps={numberProps}\n />\n )}\n />\n );\n}\n\nfunction NumberControl({\n field,\n focusRef,\n invalid,\n required,\n id,\n emptyValue,\n nullable,\n numberProps,\n ...aria\n}: {\n field: ControllerRenderProps;\n /** `field.ref`, handed over on its own so the compiler reads `field` as data. */\n focusRef: ControllerRenderProps[\"ref\"];\n invalid: boolean;\n required?: boolean;\n id: string;\n emptyValue: null | \"\";\n nullable: boolean;\n numberProps: Omit<RhfNumberFieldProps, keyof RhfFieldBaseProps | \"emptyValue\" | \"nullable\">;\n \"aria-describedby\"?: string;\n \"aria-invalid\"?: NumberFieldProps[\"aria-invalid\"];\n}) {\n // The field's own mark, for a stored text written the way it is typed.\n const mark = decimalMark(useKitLocale(numberProps.locale));\n return (\n <NumberField\n {...numberProps}\n // The <input> itself (API-3, refactor audit 2026-10): focus on error, and\n // `setFocus`'s `shouldSelect`, which an id-found stand-in had no `select()` for.\n ref={focusRef}\n aria-describedby={aria[\"aria-describedby\"]}\n aria-invalid={aria[\"aria-invalid\"]}\n aria-required={required || undefined}\n id={id}\n value={toNumber(field.value, mark)}\n onCommit={(n) => {\n field.onChange(n ?? emptyValue);\n field.onBlur();\n }}\n nullable={nullable}\n disabled={field.disabled}\n invalid={invalid}\n />\n );\n}\n\nexport type RhfIntegerFieldProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfNumberFieldProps<TFieldValues, TName, TTransformed>;\n\n/**\n * {@link RhfNumberField} for a whole number — a floor, a room count, a year, a\n * notice period in months. Every such call site in kastlan (item 41) spelled out the\n * same three props, `digits={0} calculator={false} emptyValue=\"\"`, and a preset\n * written thirty times is one that is eventually written wrong once:\n *\n * - `digits={0}`: rounds on commit, so \"2.5\" rooms settles to 3 instead of reaching\n * an `Integer` column and failing server-side;\n * - `calculator={false}`: a count is typed, not worked out — the trigger is noise\n * beside a two-digit field;\n * - `emptyValue=\"\"`: kastlan's integer schemas are `z.coerce.number()` over `\"\"`,\n * written against the native number inputs these fields replaced.\n *\n * Each is only a default: pass the prop to override it (`emptyValue={null}` for a\n * nullable column). Everything else is {@link RhfNumberField}'s.\n */\nexport function RhfIntegerField<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>(props: RhfIntegerFieldProps<TFieldValues, TName, TTransformed>) {\n // `??` / `=== undefined` rather than a spread over the defaults, so a caller\n // forwarding its own optional prop (`digits={props.digits}`) still gets the preset,\n // while an explicit `emptyValue={null}` keeps its null.\n return (\n <RhfNumberField\n {...props}\n digits={props.digits ?? 0}\n calculator={props.calculator ?? false}\n emptyValue={props.emptyValue === undefined ? \"\" : props.emptyValue}\n />\n );\n}\n\n// ── money ────────────────────────────────────────────────────────────────────\n\nexport type RhfMoneyFieldProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n // MoneyField's — AmountInput's, with the lock, `calculator` (keksdose K6), `labels`,\n // `currencyNames` and `variant` the hand-written list here had dropped (DUP-9) — less\n // what the form binds and the commit, which is the form's store.\n Omit<MoneyFieldProps, BoundByForm | \"onCommit\" | \"id\"> & {\n /**\n * What the form stores: `\"number\"` (default) — `12.5`, or `emptyValue` while the\n * field is empty — or `\"string\"`, the field's own text (\"12.50\") for a schema that\n * parses it itself. A half-typed sum (\"12+\") leaves the stored number as it was\n * until it resolves; a lone \"-\" left on blur goes back to it, as on MoneyField.\n */\n valueAs?: \"number\" | \"string\";\n /** What an emptied field stores when `valueAs` is `\"number\"`. Default `null`. */\n emptyValue?: null | \"\";\n };\n\nfunction MoneyControl({\n field,\n invalid,\n required,\n id,\n describedBy,\n props,\n}: {\n field: ControllerRenderProps;\n invalid: boolean;\n required?: boolean;\n id: string;\n describedBy: string | undefined;\n props: Omit<RhfMoneyFieldProps, keyof RhfFieldBaseProps>;\n}) {\n const { valueAs = \"number\", emptyValue = null, ...amountProps } = props;\n // MoneyField's draft and settle (DUP-9): the text being typed, re-read from the form\n // only when its value moves away from what the draft says, and a lone \"-\" back on the\n // stored amount when the figure settles.\n const money = useMoneyDraft(field.value, valueAs);\n const input = useRef<HTMLInputElement | null>(null);\n // AmountInput reports no blur, and react-hook-form needs one to mark the field\n // touched: listen on its <input>.\n const onBlur = field.onBlur;\n useLayoutEffect(() => {\n const el = input.current;\n if (!el) return;\n el.addEventListener(\"blur\", onBlur);\n return () => el.removeEventListener(\"blur\", onBlur);\n }, [onBlur]);\n return (\n <div>\n <AmountInput\n {...amountProps}\n id={id}\n aria-describedby={describedBy}\n aria-required={required || undefined}\n ref={(el) => {\n input.current = el;\n field.ref(el);\n }}\n value={money.draft}\n disabled={field.disabled}\n invalid={invalid}\n onChange={(text) => {\n const parsed = money.change(text);\n if (valueAs === \"string\") {\n field.onChange(text);\n return;\n }\n if (parsed === undefined) return;\n field.onChange(parsed ?? emptyValue);\n }}\n onCommit={money.settle}\n />\n </div>\n );\n}\n\n/**\n * The kit's {@link AmountInput}: a money figure with its currency chip and the\n * calculator (\"1200+80\" resolves on blur or Enter). Stores a number by default — see\n * `valueAs`.\n */\nexport function RhfMoneyField<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n ...amountProps\n}: RhfMoneyFieldProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n asControl={false}\n render={({ field, invalid, id, describedBy }) => (\n <MoneyControl\n field={field as unknown as ControllerRenderProps}\n invalid={invalid}\n required={required}\n id={id}\n describedBy={describedBy}\n props={amountProps}\n />\n )}\n />\n );\n}\n\n// ── date ─────────────────────────────────────────────────────────────────────\n\nexport type RhfDateFieldProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n // `error`: the form's message is shown by the binding (FormMessage); the picker's own\n // `error` (0.22) would show it a second time.\n Omit<DatePickerProps, \"value\" | \"onChange\" | \"label\" | \"invalid\" | \"disabled\" | \"className\" | \"id\" | \"error\"> & {\n /** Classes for the picker. Default `w-full`. */\n inputClassName?: string;\n /** What a cleared date stores. Default `\"\"`, the empty ISO string; `null` for a\n * nullable schema. */\n emptyValue?: \"\" | null;\n };\n\nfunction DateControl({\n field,\n focusRef,\n invalid,\n required,\n id,\n emptyValue,\n inputClassName,\n pickerProps,\n ...aria\n}: {\n field: ControllerRenderProps;\n /** `field.ref`, handed over on its own so the compiler reads `field` as data. */\n focusRef: ControllerRenderProps[\"ref\"];\n invalid: boolean;\n required?: boolean;\n id: string;\n emptyValue: \"\" | null;\n inputClassName?: string;\n pickerProps: Omit<DatePickerProps, \"value\" | \"onChange\" | \"label\" | \"invalid\" | \"disabled\" | \"className\" | \"id\">;\n \"aria-describedby\"?: string;\n \"aria-invalid\"?: DatePickerProps[\"aria-invalid\"];\n}) {\n const value: unknown = field.value;\n return (\n <DatePicker\n {...pickerProps}\n {...aria}\n // The trigger itself (API-3, refactor audit 2026-10), not an id lookup.\n ref={focusRef}\n aria-required={required || undefined}\n id={id}\n value={typeof value === \"string\" ? value : \"\"}\n onChange={(iso) => {\n field.onChange(iso === \"\" ? emptyValue : iso);\n field.onBlur();\n }}\n disabled={field.disabled}\n invalid={invalid}\n className={inputClassName ?? \"w-full\"}\n />\n );\n}\n\n/**\n * The kit's {@link DatePicker}, holding an ISO `\"YYYY-MM-DD\"` string. `commit` and\n * `disabledReason` are the picker's own (0.52, refactor audit 2026-10-30, API-3): a date\n * that saves itself stays focusable under a lock and says why.\n */\nexport function RhfDateField<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n inputClassName,\n emptyValue = \"\",\n ...pickerProps\n}: RhfDateFieldProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid, id }) => (\n // FormControl clones this element with `aria-describedby` / `aria-invalid`,\n // which DateControl hands on to the picker's trigger.\n <DateControl\n field={field as unknown as ControllerRenderProps}\n focusRef={field.ref}\n invalid={invalid}\n required={required}\n id={id}\n emptyValue={emptyValue}\n inputClassName={inputClassName}\n pickerProps={pickerProps}\n />\n )}\n />\n );\n}\n\n// ── date range ───────────────────────────────────────────────────────────────\n\ntype OwnDateRangeProps = Omit<\n DateRangePickerProps,\n \"from\" | \"to\" | \"onChange\" | \"label\" | \"invalid\" | \"disabled\" | \"className\" | \"id\" | \"error\"\n>;\n\nexport type RhfDateRangePickerProps<\n TFieldValues extends FieldValues = FieldValues,\n TFromName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TToName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = Omit<RhfFieldBaseProps<TFieldValues, TFromName, TTransformed>, \"name\" | \"rules\"> &\n OwnDateRangeProps & {\n /** The form field holding the range's first day, an ISO `\"YYYY-MM-DD\"`. */\n fromName: TFromName;\n /** The form field holding the range's last day. */\n toName: TToName;\n /** react-hook-form's `rules` for the start (`required`, a `validate` …). */\n fromRules?: ControllerProps<TFieldValues, TFromName, TTransformed>[\"rules\"];\n /** react-hook-form's `rules` for the end — the place for \"not before the start\",\n * which can read the start with `getValues`: the start is always written first. */\n toRules?: ControllerProps<TFieldValues, TToName, TTransformed>[\"rules\"];\n /** Classes for the picker. Default `w-full`. */\n inputClassName?: string;\n /** What an empty end stores — a clear, or the half-made range between the first\n * and second click. Default `\"\"`, the empty ISO string; `null` for a nullable\n * schema. */\n emptyValue?: \"\" | null;\n };\n\n/**\n * The kit's {@link DateRangePicker} over TWO form fields — `fromName` and `toName` —\n * the way a period is stored: as two columns, each its own schema key, not one\n * `{ from, to }` object (kastlan 4).\n *\n * ```tsx\n * <RhfDateRangePicker fromName=\"periodFrom\" toName=\"periodTo\" label=\"Billing period\"\n * presets={presets} clearable />\n * ```\n *\n * Why it is not {@link RhfField}: a `Controller` binds one name, and the range is\n * two. Built by hand — an `RhfField` on the start and a second `useController` for\n * the end, which is what kastlan's period fields needed — it works until the END is\n * the one in error: the shell's label, message and `aria-invalid` all read the\n * start's state alone, so \"End before start\" (a `refine` with `path: [\"periodTo\"]`,\n * where such a rule goes) never shows. Here both states are read:\n *\n * - **Either field's error is shown and paints.** The label turns, the trigger is\n * `aria-invalid` and wears the danger border when EITHER field has an error, and\n * both messages are listed under the field (once, if the two say the same thing),\n * each pointed at by the trigger's `aria-describedby`.\n * - **One change writes both.** The picker reports the range whole, so the start and\n * then the end are written on every change — the end too when only the start\n * moved, so a cross-field rule on the end re-runs and an \"End before start\" clears\n * the moment the start is fixed. A clear (`clearable`'s ×) empties both.\n * - **Focus on error** lands on the trigger whichever of the two is in error.\n * - **Touched** once a range is complete or cleared — not on the first click of a\n * pick, which would mark (and, with `mode: \"onTouched\"`, validate) an end the user\n * is still choosing.\n *\n * Without `apply` (the picker's default) the first calendar click is reported on its\n * own, so the form holds `(from, emptyValue)` until the second; with `apply` nothing\n * reaches the form until Apply. `apply` was `commit=\"apply\"` until 0.52 (gone in 0.53):\n * `commit` is now the write lock's, as on every other binding — with\n * `disabledReason`, the picker's own (refactor audit 2026-10-30, API-3).\n *\n * The common props (`label`, `hint`, `required`, `disabled`, `excludeWhenDisabled`,\n * `control`, `className`) apply to the pair; `rules` are per field.\n */\nexport function RhfDateRangePicker<\n TFieldValues extends FieldValues = FieldValues,\n TFromName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TToName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n fromName,\n toName,\n control,\n fromRules,\n toRules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n inputClassName,\n emptyValue = \"\",\n ...pickerProps\n}: RhfDateRangePickerProps<TFieldValues, TFromName, TToName, TTransformed>) {\n const rhfDisabled = excludeWhenDisabled ? disabled : undefined;\n // The end, read here; the start is the FormField below, which gives the label, hint\n // and ids their context. This component re-renders on the end's state, and with it\n // the FormField's render.\n const to = useController<TFieldValues, TToName, TTransformed>({\n name: toName,\n control,\n rules: toRules,\n disabled: rhfDisabled,\n });\n return (\n <FormField\n control={control}\n name={fromName}\n rules={fromRules}\n disabled={rhfDisabled}\n render={({ field, fieldState }) => (\n <FormItem className={className}>\n <RangeBody\n from={field as unknown as ControllerRenderProps}\n fromState={fieldState}\n to={to.field as unknown as ControllerRenderProps}\n toState={to.fieldState}\n label={label}\n hint={hint}\n help={help}\n required={required}\n disabled={Boolean(disabled)}\n emptyValue={emptyValue}\n inputClassName={inputClassName}\n pickerProps={pickerProps}\n />\n </FormItem>\n )}\n />\n );\n}\n\nfunction RangeBody({\n from,\n fromState,\n to,\n toState,\n label,\n hint,\n help,\n required,\n disabled,\n emptyValue,\n inputClassName,\n pickerProps,\n}: {\n from: ControllerRenderProps;\n fromState: ControllerFieldState;\n to: ControllerRenderProps;\n toState: ControllerFieldState;\n label: ReactNode;\n hint: ReactNode;\n help: ReactNode;\n required?: boolean;\n disabled: boolean;\n emptyValue: \"\" | null;\n inputClassName?: string;\n pickerProps: OwnDateRangeProps;\n}) {\n const { id, formItemId, formMessageId, describedBy } = useFormField();\n // RhfField's rule: a FieldHint is its words at Large and on touch (DUP-2) — and at\n // every size beside a `help`, whose \"?\" follows the label (0.36).\n const helpMark = fieldHelpMark(help, label);\n const shownHint = useInlineHint(hint, helpMark !== undefined);\n // Both fields' refs go to the one trigger (API-3, refactor audit 2026-10), so\n // `shouldFocusError` lands there whichever of the two is first in error.\n const triggerRef = useMemo(() => mergeRefs(from.ref, to.ref), [from.ref, to.ref]);\n const invalid = fromState.invalid || toState.invalid;\n const messages = [fromState.error?.message, toState.error?.message].filter(\n (m, i, all): m is string => typeof m === \"string\" && m !== \"\" && all.indexOf(m) === i,\n );\n const messageIds = messages.map((_, i) => `${formMessageId}-${i}`);\n const fromValue: unknown = from.value;\n const toValue: unknown = to.value;\n const labelEl = hasContent(label) && (\n // FormLabel colours from the START's error alone (its context is that field); the\n // pair's state says it here.\n <FormLabel id={`${id}-label`} required={required} data-error={invalid || undefined}>\n {label}\n </FormLabel>\n );\n return (\n <>\n {helpMark === undefined ? (\n labelEl\n ) : (\n <div className=\"flex items-center gap-1\">\n {labelEl}\n <span className=\"flex shrink-0 items-center\">{helpMark}</span>\n </div>\n )}\n <DateRangePicker\n {...pickerProps}\n ref={triggerRef}\n id={formItemId}\n // Merged, never replaced — a caller's own reference first, as FormControl does.\n aria-describedby={\n [pickerProps[\"aria-describedby\"], describedBy, ...messageIds].filter(Boolean).join(\" \") || undefined\n }\n aria-invalid={invalid || undefined}\n aria-required={required || undefined}\n from={typeof fromValue === \"string\" ? fromValue : \"\"}\n to={typeof toValue === \"string\" ? toValue : \"\"}\n onChange={(f, t) => {\n from.onChange(f === \"\" ? emptyValue : f);\n to.onChange(t === \"\" ? emptyValue : t);\n if (t !== \"\" || f === \"\") {\n from.onBlur();\n to.onBlur();\n }\n }}\n disabled={disabled || from.disabled || to.disabled}\n invalid={invalid}\n className={inputClassName ?? \"w-full\"}\n />\n {hasContent(shownHint) && <FormDescription>{shownHint}</FormDescription>}\n {messages.map((message, i) => (\n // FormMessage's look and its rule: no `role=\"alert\"` — read when focus reaches\n // the trigger, which names these in its description.\n <p key={message} id={messageIds[i]} data-slot=\"form-message\" className=\"text-caption leading-tight text-danger\">\n {message}\n </p>\n ))}\n </>\n );\n}\n\n// ── time ─────────────────────────────────────────────────────────────────────\n\nexport type RhfTimeInputProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n Omit<\n TimeInputProps,\n | \"name\"\n | \"value\"\n | \"defaultValue\"\n | \"onChange\"\n | \"onValueChange\"\n | \"onBlur\"\n | \"label\"\n | \"error\"\n | \"invalid\"\n | \"className\"\n | \"disabled\"\n | \"required\"\n > & {\n /** What a cleared time stores. Default `\"\"`; `null` for a nullable schema. */\n emptyValue?: \"\" | null;\n };\n\n/**\n * The kit's {@link TimeInput}: a time of day as `\"HH:mm\"` (`\"HH:mm:ss\"` when `step`\n * asks for seconds), normalised before it reaches the form, so the stored value\n * compares and sorts as a string. kastlan 4: the owner meeting's time was an\n * {@link RhfField} with a hand-wired `TimeInput` in its render — `ref`, `name`, the\n * `?? \"\"`, `onValueChange`, `onBlur`, `invalid` — the seven lines every bound field\n * folds into one.\n *\n * `min` / `max` paint an out-of-window time (see TimeInput) but do not fail the form:\n * validation stays the schema's or `rules`'. `rules={{ validate: (v) =>\n * isTimeInRange(v, min, max) || \"…\" }}` says it with the same window.\n */\nexport function RhfTimeInput<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n emptyValue = \"\",\n ...timeProps\n}: RhfTimeInputProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid }) => {\n const value: unknown = field.value;\n return (\n <TimeInput\n aria-required={required || undefined}\n {...timeProps}\n name={field.name}\n ref={field.ref}\n value={typeof value === \"string\" ? value : \"\"}\n onValueChange={(v) => field.onChange(v === \"\" ? emptyValue : v)}\n onBlur={field.onBlur}\n disabled={field.disabled}\n invalid={invalid}\n />\n );\n }}\n />\n );\n}\n\n// ── IBAN and phone (0.22) ────────────────────────────────────────────────────\n\ntype OwnTextishProps<P> = Omit<\n P,\n | \"name\"\n | \"value\"\n | \"defaultValue\"\n | \"onChange\"\n | \"onValueChange\"\n | \"onBlur\"\n | \"label\"\n | \"error\"\n | \"invalid\"\n | \"className\"\n | \"disabled\"\n | \"required\"\n>;\n\nexport type RhfIbanInputProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> & OwnTextishProps<IbanInputProps>;\n\n/**\n * {@link IbanInput} bound to one field, which stores the COMPACT upper-case IBAN (what\n * kastlan's server checks and its QR bill prints). The field's own checksum and\n * `kind` messages show while the form has nothing to say; a form error (the schema's\n * or `rules`') replaces them, as a caller's `error` does on the bare field. kastlan\n * asked for the field; it binds everything through react-hook-form.\n */\nexport function RhfIbanInput<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n ...ibanProps\n}: RhfIbanInputProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid }) => {\n const value: unknown = field.value;\n return (\n <IbanInput\n aria-required={required || undefined}\n {...ibanProps}\n name={field.name}\n ref={field.ref}\n value={typeof value === \"string\" ? value : \"\"}\n onValueChange={field.onChange}\n onBlur={field.onBlur}\n disabled={field.disabled}\n invalid={invalid}\n />\n );\n }}\n />\n );\n}\n\nexport type RhfPhoneInputProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> & OwnTextishProps<PhoneInputProps>;\n\n/**\n * {@link PhoneInput} bound to one field, which stores E.164 when the number reads as\n * one and the typed text unchanged otherwise — kastlan's contacts keep their old free\n * text until someone edits it. Validation (required, a pattern for E.164 only) is the\n * schema's or `rules`'.\n */\nexport function RhfPhoneInput<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n ...phoneProps\n}: RhfPhoneInputProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid }) => {\n const value: unknown = field.value;\n return (\n <PhoneInput\n aria-required={required || undefined}\n {...phoneProps}\n name={field.name}\n ref={field.ref}\n value={typeof value === \"string\" ? value : \"\"}\n onValueChange={field.onChange}\n onBlur={field.onBlur}\n disabled={field.disabled}\n invalid={invalid}\n />\n );\n }}\n />\n );\n}\n\n// ── country and month (0.23) ─────────────────────────────────────────────────\n\ntype OwnCountrySelectProps = Omit<\n CountrySelectProps<boolean>,\n | \"value\"\n | \"onChange\"\n | \"onBlur\"\n | \"label\"\n | \"hint\"\n | \"error\"\n | \"invalid\"\n | \"disabled\"\n | \"className\"\n | \"id\"\n | \"ref\"\n | \"clearable\"\n>;\n\nexport type RhfCountrySelectProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n OwnCountrySelectProps & {\n /** Offer the picker's clear \"×\" (and Delete on the trigger) while a country is\n * chosen. A clear stores `clearValue`. */\n clearable?: boolean;\n /** What a clear stores. Default `null`; `\"\"` for a schema that spells \"no\n * country\" as an empty string (a zod `z.string().max(2)`, kastlan's). The picker\n * reads either back as empty. */\n clearValue?: ComboClearValue;\n /** Classes for the picker — `className` is the item's box. */\n selectClassName?: string;\n };\n\n/**\n * {@link CountrySelect} bound to one field, which stores the ISO 3166-1 alpha-2 code\n * (\"CH\", always upper-case), or `clearValue` once cleared (`clearable`). kastlan asked\n * for it (0.22 adoption): its address form wired a `CountrySelect` through\n * {@link RhfField}'s render, and with no ref on the picker react-hook-form's\n * focus-on-error had nothing to focus — the one field on the form a failed submit\n * could not take you to.\n *\n * Bound the way {@link RhfIbanInput} and {@link RhfPhoneInput} are: `field.ref` reaches\n * the trigger (the picker's `ref`, 0.23), the form's error paints the trigger and is\n * the shell's message under it, the hint is the shell's description — so neither is\n * ever handed to the picker, and its box never changes when one comes or goes. The\n * form's label names the trigger together with the chosen country, and is the phone\n * sheet's title. `commit` and `disabledReason` are the picker's own: a country that\n * saves itself stays focusable under a lock and says why.\n *\n * ```tsx\n * <RhfCountrySelect name=\"country\" label=\"Country\" required\n * preferred={[\"CH\", \"LI\", \"DE\", \"AT\", \"FR\", \"IT\"]} rules={{ required: \"Choose a country\" }} />\n * ```\n */\nexport function RhfCountrySelect<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n clearable,\n clearValue = null,\n selectClassName,\n labels,\n ...countryProps\n}: RhfCountrySelectProps<TFieldValues, TName, TTransformed>) {\n const labelled = hasContent(label);\n // A string label is also what the field IS — the picker's `country` word, which\n // titles the phone sheet. A caller's own `labels.country` still wins.\n const ownLabels = typeof label === \"string\" ? { country: label, ...labels } : labels;\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid, labelId }) => {\n const value: unknown = field.value;\n return (\n // FormControl clones this element with `id` / `aria-describedby` /\n // `aria-invalid`, which the picker routes to its trigger.\n <CountrySelect<boolean>\n aria-required={required || undefined}\n // The form's label, then the country (see the picker's `aria-labelledby`).\n aria-labelledby={labelled ? labelId : undefined}\n {...countryProps}\n labels={ownLabels}\n className={selectClassName}\n ref={field.ref}\n value={typeof value === \"string\" ? value : null}\n clearable={clearable}\n onChange={(code) => field.onChange(code ?? clearValue)}\n // Focus leaving the picker (the wrapper's focusout) marks the field touched.\n onBlur={field.onBlur}\n disabled={field.disabled}\n invalid={invalid}\n />\n );\n }}\n />\n );\n}\n\ntype OwnMonthPickerProps = Omit<\n MonthPickerProps,\n \"value\" | \"onChange\" | \"onBlur\" | \"label\" | \"hint\" | \"error\" | \"invalid\" | \"disabled\" | \"className\" | \"id\" | \"mode\"\n>;\n\n/** `mode` picks what the form stores, and `valueAsNumber` is only offered for a year. */\ntype RhfMonthPickerMode =\n | {\n /** A month, stored as `\"YYYY-MM\"` (the default). */\n mode?: \"month\";\n valueAsNumber?: undefined;\n }\n | {\n /** A year, stored as `\"YYYY\"` — or as a number with `valueAsNumber`. */\n mode: \"year\";\n /** Store the year as a number (`2026`) rather than `\"2026\"` — kastlan's budget\n * `fiscal_year` is an integer column. A number in the form reads back as its\n * year. */\n valueAsNumber?: boolean;\n };\n\nexport type RhfMonthPickerProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n OwnMonthPickerProps & {\n /** Classes for the picker — `className` is the item's box. As {@link RhfDateField}'s. */\n inputClassName?: string;\n } & RhfMonthPickerMode;\n\nfunction MonthControl({\n field,\n focusRef,\n invalid,\n id,\n valueAsNumber,\n mode,\n inputClassName,\n pickerProps,\n required,\n ...aria\n}: {\n field: ControllerRenderProps;\n /** `field.ref`, handed over on its own so the compiler reads `field` as data. */\n focusRef: ControllerRenderProps[\"ref\"];\n invalid: boolean;\n id: string;\n valueAsNumber?: boolean;\n mode?: \"month\" | \"year\";\n inputClassName?: string;\n pickerProps: OwnMonthPickerProps;\n required?: boolean;\n \"aria-describedby\"?: string;\n \"aria-invalid\"?: MonthPickerProps[\"aria-invalid\"];\n}) {\n const value: unknown = field.value;\n return (\n <MonthPicker\n {...pickerProps}\n {...aria}\n // The trigger itself (API-3, refactor audit 2026-10) — RhfDateField's way.\n ref={focusRef}\n // MonthPicker routes `aria-required` to its trigger since 0.23.0.\n aria-required={required || undefined}\n id={id}\n mode={mode}\n value={value === null || value === undefined ? \"\" : String(value)}\n onChange={(key) => {\n field.onChange(mode === \"year\" && valueAsNumber ? Number(key) : key);\n // A pick is the whole interaction — there is no text to leave — so it touches.\n field.onBlur();\n }}\n disabled={field.disabled}\n invalid={invalid}\n className={inputClassName}\n />\n );\n}\n\n/**\n * {@link MonthPicker} bound to one field: a month as `\"YYYY-MM\"`, or with `mode=\"year\"` a\n * year as `\"YYYY\"` (`valueAsNumber` stores `2026`). kastlan asked for it with\n * {@link RhfCountrySelect}: its budget wizard's fiscal year was a `MonthPicker\n * mode=\"year\"` inside {@link RhfField}'s render — the `String()` in, the `Number()`\n * out, `invalid` by hand — and a failed submit could not focus it, because the picker\n * forwards no ref.\n *\n * Bound as {@link RhfDateField} is: `field.ref` is the picker's `ref`, its trigger (an id\n * lookup until 0.34, API-3), so focus-on-error lands there; the form's error paints the\n * trigger and is the shell's message; the hint is the shell's description; neither is\n * handed to the picker, so its box never changes. Picking marks the field touched.\n * `commit` and `disabledReason` are the picker's own (0.52, API-3).\n *\n * ```tsx\n * <RhfMonthPicker name=\"fiscalYear\" label=\"Fiscal year\" mode=\"year\" valueAsNumber\n * min=\"2020\" max=\"2029\" rules={{ required: \"Choose a year\" }} />\n * ```\n */\nexport function RhfMonthPicker<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n inputClassName,\n mode,\n valueAsNumber,\n ...pickerProps\n}: RhfMonthPickerProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid, id }) => (\n // FormControl clones this element with `aria-describedby` / `aria-invalid`,\n // which MonthControl hands on to the picker's trigger.\n <MonthControl\n field={field as unknown as ControllerRenderProps}\n focusRef={field.ref}\n invalid={invalid}\n id={id}\n mode={mode}\n valueAsNumber={valueAsNumber}\n inputClassName={inputClassName}\n pickerProps={pickerProps}\n required={required}\n />\n )}\n />\n );\n}\n\n// ── select ───────────────────────────────────────────────────────────────────\n\nexport interface RhfSelectOption {\n value: string | number;\n label: ReactNode;\n disabled?: boolean;\n}\n\nexport type RhfSelectProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n // Select's own — its lock (`commit`, `disabledReason`), `size`, … — which a `Pick`\n // list dropped until 0.34 (DUP-9). One value, so not `multiple`.\n Omit<SelectProps, BoundByForm | \"children\" | \"multiple\" | \"selectClassName\"> & {\n /** The options, as data. Or pass `<option>` children. */\n options?: readonly RhfSelectOption[];\n children?: ReactNode;\n /** A first, empty option (\"Choose…\"), selected while the value is empty. */\n placeholder?: string;\n /** Store `Number(value)` rather than the option's string. An empty choice still\n * stores `\"\"`. */\n valueAsNumber?: boolean;\n /** Classes for the select. Default `w-full`. */\n selectClassName?: string;\n };\n\n/** A native {@link Select}, from `options` or `<option>` children. */\nexport function RhfSelect<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n options,\n children,\n placeholder,\n valueAsNumber,\n selectClassName,\n ...selectProps\n}: RhfSelectProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid }) => (\n <Select\n aria-required={required || undefined}\n {...selectProps}\n className={cn(\"w-full\", selectClassName)}\n name={field.name}\n ref={field.ref}\n value={(field.value ?? \"\") as string | number}\n onChange={(e) => {\n const raw = e.target.value;\n field.onChange(valueAsNumber && raw !== \"\" ? Number(raw) : raw);\n }}\n onBlur={field.onBlur}\n disabled={field.disabled}\n invalid={invalid}\n >\n {placeholder !== undefined && <option value=\"\">{placeholder}</option>}\n {options\n ? options.map((o) => (\n <option key={String(o.value)} value={o.value} disabled={o.disabled}>\n {o.label}\n </option>\n ))\n : children}\n </Select>\n )}\n />\n );\n}\n\n// ── checkbox ─────────────────────────────────────────────────────────────────\n\nexport type RhfCheckboxProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> =\n // No `help` (0.36): a box has no label line — its label sits beside it, inside the\n // `<label>` a \"?\" cannot join — and Checkbox takes none.\n Omit<RhfFieldBaseProps<TFieldValues, TName, TTransformed>, \"help\"> &\n // Checkbox's own — its lock (`commit`, `disabledReason`) among them, which a `Pick`\n // list dropped until 0.34 (DUP-9) — less the box's state the form holds, and its\n // `description`, which is the twin's `hint`.\n Omit<CheckboxProps, BoundByForm | \"checked\" | \"defaultChecked\" | \"onCheckedChange\" | \"description\">;\n\n/**\n * The kit's {@link Checkbox}, label beside the box and `hint` under it (the\n * checkbox's own `description`). Stores a boolean. `required` is the native one here\n * — see Checkbox — so a `<form>` refuses to submit it unticked.\n */\nexport function RhfCheckbox<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n ...boxProps\n}: RhfCheckboxProps<TFieldValues, TName, TTransformed>) {\n // RhfField's rule for the box's own description: a FieldHint is its words at Large\n // and on touch (DUP-2).\n const description = useInlineHint(hint);\n return (\n <RhfField\n {...{ name, control, rules, required, disabled, excludeWhenDisabled, className }}\n showLabel={false}\n render={({ field, invalid }) => (\n <Checkbox\n {...boxProps}\n ref={field.ref}\n name={field.name}\n checked={Boolean(field.value)}\n onCheckedChange={field.onChange}\n onBlur={field.onBlur}\n disabled={field.disabled}\n required={required}\n invalid={invalid}\n label={label}\n description={description}\n />\n )}\n />\n );\n}\n\n// ── toggle group ─────────────────────────────────────────────────────────────\n\n/** The two shapes a {@link ToggleGroup} comes in, carried over: `allowEmpty` picks\n * whether a press on the chosen option clears it, and types the caption to match. */\ntype RhfToggleGroupMode<T extends string> =\n | {\n /** One option is always the answer (the default): a press on the chosen\n * option re-sends it. */\n allowEmpty?: false;\n semantics?: ToggleGroupRequiredProps<T>[\"semantics\"];\n caption?: ToggleGroupRequiredProps<T>[\"caption\"];\n emptyValue?: undefined;\n }\n | {\n /** A press on the chosen option clears it, and the form stores `emptyValue`. */\n allowEmpty: true;\n semantics?: ToggleGroupClearableProps<T>[\"semantics\"];\n caption?: ToggleGroupClearableProps<T>[\"caption\"];\n /** What a cleared group stores. Default `null`; `\"\"` for a schema that spells\n * \"no choice\" as an empty string. */\n emptyValue?: null | \"\";\n };\n\nexport type RhfToggleGroupProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n T extends string = string,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n // The group's own (its `disabledReasonDisplay` was not on the `Pick` list this was\n // until 0.34, DUP-9), less what the form binds, the ids, and the label's placement:\n // the label is the form's, above.\n Omit<ToggleGroupBaseProps<T>, BoundByForm | \"id\" | \"aria-labelledby\" | \"labelPlacement\" | \"chromeClassName\"> & {\n /** Classes for the group itself — `className` is the item's box. */\n groupClassName?: string;\n } & RhfToggleGroupMode<T>;\n\n/**\n * The kit's {@link ToggleGroup} bound to one field: a choice between a few answers\n * (\"Monthly / Quarterly / Yearly\"), stored as the chosen option's `value`. kastlan 4\n * asked for it with {@link RhfTimeInput} and {@link RhfDateRangePicker}: the controls\n * its forms still had to wire by hand through {@link RhfField}'s render.\n *\n * The label is the field's own label above the bare group, as on every other\n * bound field — the `labelPlacement=\"above\"` shape, not the group's own field chrome —\n * and it names the group (`aria-labelledby`); the hint and the message describe it,\n * and an error paints the group's border. Focus on error goes to the option a\n * keyboard user would land on (the chosen one, else the first); touched is set when\n * focus leaves the group, not when it moves between options.\n *\n * Required by default, as the group is: a press on the chosen option keeps it. With\n * `allowEmpty`, a second press clears the choice and the form stores `emptyValue`\n * (`null` by default) — the options then become toggle buttons, see ToggleGroup. A\n * value that matches no option (an empty default) leaves nothing pressed; that the\n * field still needs answering is the schema's or `rules`' to say.\n */\nexport function RhfToggleGroup<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n T extends string = string,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n ...groupProps\n}: RhfToggleGroupProps<TFieldValues, TName, T, TTransformed>) {\n const labelled = hasContent(label);\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n asControl={false}\n render={({ field, invalid, id, labelId, describedBy }) => (\n <ToggleControl<T>\n field={field as unknown as ControllerRenderProps}\n invalid={invalid}\n required={required}\n id={id}\n labelledBy={labelled ? labelId : undefined}\n describedBy={describedBy}\n groupProps={groupProps}\n />\n )}\n />\n );\n}\n\nfunction ToggleControl<T extends string>({\n field,\n invalid,\n required,\n id,\n labelledBy,\n describedBy,\n groupProps,\n}: {\n field: ControllerRenderProps;\n invalid: boolean;\n required?: boolean;\n id: string;\n labelledBy: string | undefined;\n describedBy: string | undefined;\n groupProps: Omit<RhfToggleGroupProps<FieldValues, string, T>, keyof RhfFieldBaseProps>;\n}) {\n const { groupClassName, emptyValue, allowEmpty, semantics, caption, ...rest } = groupProps;\n // React's onBlur is focusout: it fires on every move between options as well, and\n // only leaving the group is a blur of the FIELD.\n const onBlur = (e: FocusEvent<HTMLDivElement>) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) field.onBlur();\n };\n const raw: unknown = field.value;\n const value = raw === null || raw === undefined || raw === \"\" ? null : (String(raw) as T);\n const common = {\n ...rest,\n // The group (API-3, refactor audit 2026-10): its `focus()` lands on the radio shape's\n // tab stop, or the pressed shape's pressed option — the rule this adapter carried\n // as an id lookup until ToggleGroup took a ref.\n ref: field.ref,\n id,\n className: groupClassName,\n \"aria-labelledby\": labelledBy,\n \"aria-describedby\": describedBy,\n \"aria-invalid\": invalid || undefined,\n disabled: field.disabled,\n onBlur,\n };\n // The props' union pairs `allowEmpty` with its caption's type; taken apart above it no\n // longer narrows, so each branch says which half it is.\n if (allowEmpty) {\n return (\n <ToggleGroup<T>\n {...common}\n allowEmpty\n caption={caption as ToggleGroupClearableProps<T>[\"caption\"]}\n value={value}\n onChange={(v) => field.onChange(v ?? emptyValue ?? null)}\n />\n );\n }\n return (\n <ToggleGroup<T>\n {...common}\n allowEmpty={false}\n semantics={semantics}\n caption={caption as ToggleGroupRequiredProps<T>[\"caption\"]}\n // A radiogroup takes `aria-required`; a group of toggle buttons does not.\n aria-required={required && semantics !== \"pressed\" ? true : undefined}\n // An empty default matches no option: nothing pressed, the first option the tab\n // stop.\n value={(value ?? \"\") as T}\n onChange={(v) => field.onChange(v)}\n />\n );\n}\n\n// ── comboboxes ───────────────────────────────────────────────────────────────\n\nexport type RhfComboboxProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n V extends string | number = string | number,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n // The picker's own, as an `Omit` since 0.34 (DUP-9) rather than the `Pick` list it\n // was, less what the form binds and the clear value, which is the twin's below.\n Omit<EntityComboboxProps<V>, BoundByForm | \"id\" | \"clearValue\"> & {\n /** What a clear stores — the picker's `clearValue`. Default `null`; `\"\"` for a\n * schema that spells \"no choice\" as an empty string. */\n clearValue?: ComboClearValue;\n /** Classes for the picker. */\n comboClassName?: string;\n };\n\nfunction EntityControl<V extends string | number>({\n field,\n invalid,\n required,\n error,\n id,\n describedBy,\n clearValue,\n comboClassName,\n sheetTitle,\n focusRef,\n comboProps,\n}: {\n field: ControllerRenderProps;\n invalid: boolean;\n required?: boolean;\n error: string | undefined;\n id: string;\n describedBy: string | undefined;\n clearValue: ComboClearValue;\n comboClassName?: string;\n sheetTitle: ReactNode;\n /** `field.ref`, handed over on its own so the compiler reads `field` as data. */\n focusRef: ControllerRenderProps[\"ref\"];\n comboProps: Omit<RhfComboboxProps<FieldValues, string, V>, keyof RhfFieldBaseProps | \"clearValue\" | \"comboClassName\">;\n}) {\n const box = useRef<HTMLDivElement>(null);\n // EntityCombobox puts `id` and the ARIA below on its trigger, so the label's\n // `htmlFor` names it and the hint describes it; `field.ref` reaches the trigger\n // through the picker's own `ref` (0.24), as RhfCountrySelect's does.\n // EntityCombobox reports no blur: focus leaving the picker marks the field touched.\n const onBlur = field.onBlur;\n useLayoutEffect(() => {\n const el = box.current;\n if (!el) return;\n el.addEventListener(\"focusout\", onBlur);\n return () => el.removeEventListener(\"focusout\", onBlur);\n }, [onBlur]);\n const value: unknown = field.value;\n return (\n <div ref={box}>\n <EntityCombobox<V, ComboClearValue>\n // The form's label titles the phone sheet: the picker is not handed `label`,\n // which the FormLabel above already draws.\n sheetTitle={sheetTitle}\n {...comboProps}\n ref={focusRef}\n className={comboClassName}\n id={id}\n aria-describedby={describedBy}\n aria-required={required || undefined}\n value={(value ?? null) as V | ComboClearValue | null}\n clearValue={clearValue}\n onChange={(v) => field.onChange(v)}\n disabled={field.disabled}\n invalid={invalid}\n // Its own message, which it merges into the trigger's aria-describedby after\n // the hint.\n error={error}\n />\n </div>\n );\n}\n\n/**\n * The kit's {@link EntityCombobox}: an id-keyed pick from `options` or `loadOptions`.\n * Stores the option's `value`, or `clearValue` on a clear (only offered with\n * `clearable`).\n *\n * 0.24: `field.ref` goes through the picker's own `ref` to its trigger (it used to be\n * a focus handle that found the trigger by id — the same element, now by the route\n * every other binding takes); the write lock (`commit`, `disabledReason`), the create\n * row's `createEmptyLabel` / `createCommit`, `closeLabel` and `aria-label` pass\n * through; and the form's label titles the phone sheet, which fell back to the\n * placeholder. For the INLINE picker — a text input, the account field typed into —\n * see {@link RhfInlineEntityCombobox}.\n */\nexport function RhfCombobox<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n V extends string | number = string | number,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n clearValue = null,\n comboClassName,\n ...comboProps\n}: RhfComboboxProps<TFieldValues, TName, V, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n asControl={false}\n message={false}\n render={({ field, invalid, error, id, describedBy }) => (\n <EntityControl<V>\n field={field as unknown as ControllerRenderProps}\n invalid={invalid}\n required={required}\n error={error}\n id={id}\n describedBy={describedBy}\n clearValue={clearValue}\n comboClassName={comboClassName}\n sheetTitle={hasContent(label) ? label : undefined}\n focusRef={field.ref}\n comboProps={comboProps}\n />\n )}\n />\n );\n}\n\ntype OwnInlineEntityComboboxProps<V extends string | number> = Omit<\n InlineEntityComboboxProps<V, ComboClearValue>,\n | \"value\"\n | \"defaultValue\"\n | \"onChange\"\n | \"onBlur\"\n | \"label\"\n | \"hint\"\n | \"error\"\n | \"invalid\"\n | \"disabled\"\n | \"className\"\n | \"id\"\n | \"ref\"\n | \"clearValue\"\n>;\n\nexport type RhfInlineEntityComboboxProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n V extends string | number = string | number,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n OwnInlineEntityComboboxProps<V> & {\n /** What a clear stores — emptying the text, or the \"×\" with `clearable`. Default\n * `null`; `\"\"` for a schema that spells \"no choice\" as an empty string. The\n * picker reads either back as empty. */\n clearValue?: ComboClearValue;\n /** Classes for the picker — `className` is the item's box. As {@link RhfCombobox}'s. */\n comboClassName?: string;\n };\n\n/**\n * {@link InlineEntityCombobox} bound to one field, which stores the chosen option's\n * `value` (an id), or `clearValue` once the text is emptied or the \"×\" pressed.\n *\n * kastlan asked for it (0.24): its account picker IS an `InlineEntityCombobox` — the\n * account number is typed straight into the field — and the budget line-item form\n * wired it through {@link RhfField}'s render. The picker took no `ref`, so react-hook-\n * form's focus-on-error had nothing to focus: a line item saved without an account\n * failed its submit and left the caret where it was, the one field on the form a\n * failed submit could not take you to. (The same gap {@link RhfCountrySelect} closed\n * for the address form's country in 0.23.)\n *\n * Bound the way {@link RhfCountrySelect} is: `field.ref` reaches the `<input>` (the\n * picker's `ref`, 0.24), the form's error paints the input and is the shell's message\n * under it, and the hint is the shell's description — so neither is ever handed to the\n * picker, and its box never changes when one comes or goes. The form's label names\n * the input through `<label for>` and titles the phone sheet (`sheetTitle`); the picker\n * draws no floating label of its own. Focus leaving the picker marks the field\n * touched.\n *\n * Everything else is the picker's and passes through: `commit` and `disabledReason`\n * (a picker whose choice saves stays focusable under a lock and says why), `clearable`,\n * `autoFocus`, `aria-label` for an unlabelled cell, and the create row — `onCreate`,\n * `createLabel`, `createEmptyLabel`, `createCommit`. Making the record is the\n * caller's, and so is storing its id once it exists:\n *\n * ```tsx\n * <RhfInlineEntityCombobox<LineItem, \"account_id\", number>\n * name=\"account_id\" label=\"Account\" required options={accounts}\n * rules={{ required: \"Choose an account\" }}\n * onCreate={async (name) => form.setValue(\"account_id\", (await createAccount(name)).id)} />\n * ```\n *\n * For the button-shaped picker with an async `loadOptions`, see {@link RhfCombobox}.\n */\nexport function RhfInlineEntityCombobox<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n V extends string | number = string | number,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n clearValue = null,\n comboClassName,\n ...comboProps\n}: RhfInlineEntityComboboxProps<TFieldValues, TName, V, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid }) => {\n const value: unknown = field.value;\n return (\n // FormControl clones this element with `id` / `aria-describedby` /\n // `aria-invalid`, which the picker routes to its <input>.\n <InlineEntityCombobox<V, ComboClearValue>\n aria-required={required || undefined}\n // The form's label is the phone sheet's heading — the picker is not handed\n // `label`, which the FormLabel above already draws. A caller's own wins.\n sheetTitle={hasContent(label) ? label : undefined}\n {...comboProps}\n className={comboClassName}\n ref={field.ref}\n value={(value ?? null) as V | ComboClearValue | null}\n clearValue={clearValue}\n onChange={(v) => field.onChange(v)}\n // The wrapper's blur, which the <input>'s bubbles to after the picker has\n // judged any loose text — so the value is in before the field is touched.\n onBlur={field.onBlur}\n disabled={field.disabled}\n invalid={invalid}\n />\n );\n }}\n />\n );\n}\n\nexport type RhfTextComboboxProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n // The combobox's own, as an `Omit` since 0.34 (DUP-9) rather than the `Pick` list it\n // was, less what the form binds.\n Omit<ComboboxProps, BoundByForm | \"id\"> & {\n /** Classes for the combobox. */\n comboClassName?: string;\n };\n\n/**\n * The kit's free-text {@link Combobox}: type anything, or pick one of `options`.\n * Stores the string.\n */\nexport function RhfTextCombobox<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n comboClassName,\n ...comboProps\n}: RhfTextComboboxProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n asControl={false}\n message={false}\n render={({ field, invalid, error, id, describedBy }) => (\n <TextComboControl\n field={field as unknown as ControllerRenderProps}\n invalid={invalid}\n required={required}\n error={error}\n id={id}\n describedBy={describedBy}\n className={comboClassName}\n sheetTitle={hasContent(label) ? label : undefined}\n focusRef={field.ref}\n comboProps={comboProps}\n />\n )}\n />\n );\n}\n\nfunction TextComboControl({\n field,\n invalid,\n required,\n error,\n id,\n describedBy,\n className,\n sheetTitle,\n focusRef,\n comboProps,\n}: {\n field: ControllerRenderProps;\n invalid: boolean;\n required?: boolean;\n error: string | undefined;\n id: string;\n describedBy: string | undefined;\n className?: string;\n sheetTitle: ReactNode;\n /** `field.ref` — see EntityControl. */\n focusRef: ControllerRenderProps[\"ref\"];\n comboProps: Omit<RhfTextComboboxProps, keyof RhfFieldBaseProps | \"comboClassName\">;\n}) {\n // The combobox routes `id` and its ARIA to its <input>, so the label's `htmlFor`\n // names it and the hint describes it; `field.ref` reaches the <input> through the\n // combobox's own `ref` (0.24). The error is its own `error` prop, which it merges\n // in after the hint.\n const value: unknown = field.value;\n return (\n <Combobox\n // The form's label titles the phone sheet (see EntityControl).\n sheetTitle={sheetTitle}\n {...comboProps}\n ref={focusRef}\n id={id}\n aria-describedby={describedBy}\n aria-required={required || undefined}\n className={className}\n value={typeof value === \"string\" ? value : value == null ? \"\" : String(value)}\n onChange={field.onChange}\n onBlur={field.onBlur}\n disabled={field.disabled}\n invalid={invalid}\n error={error}\n />\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/rhf/fields.tsx"],"sourcesContent":["/**\n * Bound fields: one line per field of a react-hook-form form. `@eifi1/ui-kit/rhf`.\n *\n * ```tsx\n * <Form {...form}>\n * <RhfTextField name=\"name\" label=\"Name\" hint=\"As on the lease\" required\n * rules={{ required: \"Enter a name\" }} />\n * <RhfMoneyField name=\"rent\" label=\"Net rent\" currency=\"CHF\" />\n * <RhfDateField name=\"start\" label=\"Start\" />\n * <RhfSelect name=\"type\" label=\"Type\" options={TYPES} />\n * <RhfCombobox name=\"tenantId\" label=\"Tenant\" options={tenants} clearable />\n * <RhfInlineEntityCombobox name=\"accountId\" label=\"Account\" options={accounts} />\n * <RhfCheckbox name=\"isDefault\" label=\"Default account\" />\n * <RhfTimeInput name=\"meetingTime\" label=\"Time\" />\n * <RhfDateRangePicker fromName=\"periodFrom\" toName=\"periodTo\" label=\"Period\" />\n * <RhfToggleGroup name=\"interval\" label=\"Interval\" options={INTERVALS} />\n * <RhfCountrySelect name=\"country\" label=\"Country\" preferred={[\"CH\", \"DE\"]} />\n * <RhfMonthPicker name=\"fiscalYear\" label=\"Fiscal year\" mode=\"year\" valueAsNumber />\n * </Form>\n * ```\n *\n * Each folds the `FormField → FormItem → FormLabel → FormControl → field →\n * FormDescription → FormMessage` scaffold (see ./form-core) into one element, the way\n * kastlan's shared/components/form/fields.tsx does for its forms — with what that file\n * left out:\n *\n * - **The red border.** Every field gets `invalid` from the field state, so an errored\n * field PAINTS as well as announces. kastlan's number, money, date and entity fields\n * passed only `aria-invalid` through `FormControl`, or nothing, and `Input`, `Select`\n * and `Textarea` paint only from the prop (see the note in ./form-core).\n * - **Focus on error.** `field.ref` reaches the focusable element itself — the input,\n * a picker's trigger, a toggle group whose `focus()` lands on its option (since 0.34\n * every kit field takes a ref; the number field and the pickers were reached by an id\n * lookup before, API-3) — so `handleSubmit` and `trigger(…, { shouldFocus })` land the\n * caret on the first field in error, and `setFocus`'s `shouldSelect` selects.\n * - **`control` is optional**: under `<Form {...form}>` the fields find the form\n * through react-hook-form's context. Pass it for the field's value types\n * (`control={form.control}` checks `name` against the form's values).\n *\n * The common props: `name`, `control`, `label` (the label above the field;\n * omitted, none — then give the field an `aria-label`), `hint` (standing advice under\n * the field, attached to it with `aria-describedby`), `required` (the label's mark,\n * and `aria-required` where the control takes it — validation is `rules`' or the\n * resolver's), `rules`, `disabled` (the control only — the value is still submitted;\n * `excludeWhenDisabled` for react-hook-form's drop-the-value semantics), and\n * `className` for the item's box.\n *\n * {@link RhfField} is the shell they are all built on, for a control the kit does not\n * ship (an address autocomplete): it takes a `render` and wires the rest.\n */\nimport { useLayoutEffect, useMemo, useRef, type FocusEvent, type ReactElement, type ReactNode } from \"react\";\nimport {\n useController,\n type ControllerFieldState,\n type ControllerProps,\n type ControllerRenderProps,\n type FieldPath,\n type FieldValues,\n} from \"react-hook-form\";\nimport { FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, useFormField } from \"./form-core\";\nimport { Input, type InputProps } from \"../components/input\";\nimport { Select, type SelectProps } from \"../components/select\";\nimport { Textarea, type TextareaProps } from \"../components/textarea\";\nimport { NumberField, type NumberFieldProps } from \"../components/number-field\";\nimport { AmountInput } from \"../components/amount-input\";\nimport type { MoneyFieldProps } from \"../components/money-field\";\nimport { useMoneyDraft } from \"../components/money-draft\";\nimport {\n DatePicker,\n DateRangePicker,\n type DatePickerProps,\n type DateRangePickerProps,\n} from \"../components/date-picker\";\nimport { TimeInput, type TimeInputProps } from \"../components/time-input\";\nimport { IbanInput, type IbanInputProps } from \"../components/iban-input\";\nimport { PhoneInput, type PhoneInputProps } from \"../components/phone-input\";\nimport { CountrySelect, type CountrySelectProps } from \"../components/country-select\";\nimport { MonthPicker, type MonthPickerProps } from \"../components/month-picker\";\nimport {\n ToggleGroup,\n type ToggleGroupBaseProps,\n type ToggleGroupClearableProps,\n type ToggleGroupRequiredProps,\n} from \"../components/toggle-group\";\nimport { Checkbox, type CheckboxProps } from \"../components/checkbox\";\nimport { EntityCombobox, type EntityComboboxProps } from \"../components/entity-combobox\";\nimport {\n Combobox,\n InlineEntityCombobox,\n type ComboboxProps,\n type InlineEntityComboboxProps,\n} from \"../components/combobox\";\nimport type { ComboClearValue } from \"../components/combobox-core\";\nimport { fieldHelpMark, mergeRefs, useInlineHint } from \"../components/field-parts\";\nimport { useKitLocale } from \"../i18n/kit-labels\";\nimport { cn } from \"../lib/cn\";\nimport { decimalMark, readTyped } from \"../lib/decimal-marks\";\nimport { hasContent } from \"../lib/presence\";\n\n// ── the shell ────────────────────────────────────────────────────────────────\n\n/** What every bound field takes. */\nexport interface RhfFieldBaseProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> {\n name: TName;\n /** `form.control`. Optional under `<Form {...form}>`; pass it to type-check `name`. */\n control?: ControllerProps<TFieldValues, TName, TTransformed>[\"control\"];\n /** react-hook-form's `rules` (`required`, `min`, `validate` …). */\n rules?: ControllerProps<TFieldValues, TName, TTransformed>[\"rules\"];\n /** The label above the field. Omitted: no label — name the control with\n * an `aria-label` instead. */\n label?: ReactNode;\n /** Standing advice under the field (\"As printed on the card\"), attached to the\n * control with `aria-describedby`. A `FieldHint` is its words at Large and on a\n * touch screen (§4, DUP-2), not a lone \"?\"; a `HelpPopover` stays a \"?\". Beside a\n * `help` it is that caption at every size. */\n hint?: ReactNode;\n /** Help the field is usable without — why, how to choose — behind the field's one\n * \"?\" after the label: a `HelpPopover` named \"About “<label>”\" (round 0.36,\n * docs/text-size-harmonization.md §4); pass a `HelpPopover` to name it yourself.\n * `hint` stays the visible fact under the field. */\n help?: ReactNode;\n /** Draws the label's required mark and sets `aria-required` where the control\n * takes it. Whether the field IS required is `rules`' or the resolver's to say. */\n required?: boolean;\n /** Disables the control and KEEPS the value: a field locked to a preset (a lease's\n * preselected unit, a fixed period) still submits it, and `rules` still run.\n * react-hook-form's own Controller `disabled` drops the value from `handleSubmit`'s\n * data instead, which a locked preset must never do (kastlan, 0.12). To get that,\n * add `excludeWhenDisabled`. A form-wide `useForm({ disabled })` still disables\n * every field the RHF way. */\n disabled?: boolean;\n /** With `disabled`: disable through react-hook-form, so the value is left out of\n * the submitted data and validation skips it, like a disabled native input in a\n * plain form post. Default `false`. */\n excludeWhenDisabled?: boolean;\n /** Classes for the item's box (a `grid gap-1`). */\n className?: string;\n}\n\n/** What {@link RhfField}'s `render` receives. */\nexport interface RhfFieldRenderContext<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> {\n field: ControllerRenderProps<TFieldValues, TName>;\n fieldState: ControllerFieldState;\n /** The field has an error: pass it to the control's `invalid` so it paints. */\n invalid: boolean;\n /** The error's message, if any. */\n error: string | undefined;\n /** The control's id, which the label points at. The rendered element has it already\n * (unless `asControl` is false); this is for a control that routes it elsewhere. */\n id: string;\n /** The label's id, for a control that is named with `aria-labelledby`. */\n labelId: string;\n /** The ids of the rendered hint and message, if any. */\n describedBy: string | undefined;\n}\n\nexport interface RhfFieldProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> extends RhfFieldBaseProps<TFieldValues, TName, TTransformed> {\n /** The control. Given the field's `id`, `aria-describedby` and `aria-invalid` unless\n * `asControl` is false. */\n render: (ctx: RhfFieldRenderContext<TFieldValues, TName>) => ReactElement;\n /** `false`: render the control as is, for one that wires its own ids from the\n * context. Default `true`. */\n asControl?: boolean;\n /** `false`: no error message under the field, for a control that renders its own (its\n * `error` prop). Default `true`. */\n message?: boolean;\n /** `false`: no label above the field, for a control that carries its label itself (a\n * checkbox). Default `true`. */\n showLabel?: boolean;\n}\n\n/** The label, with an id the control can be named by. Inside the item, so it can read\n * the item's id. */\nfunction RhfLabel({ required, children }: { required?: boolean; children: ReactNode }) {\n const { id } = useFormField();\n return (\n <FormLabel id={`${id}-label`} required={required}>\n {children}\n </FormLabel>\n );\n}\n\nfunction ControlSlot<TFieldValues extends FieldValues, TName extends FieldPath<TFieldValues>>({\n field,\n fieldState,\n render,\n asControl,\n}: {\n field: ControllerRenderProps<TFieldValues, TName>;\n fieldState: ControllerFieldState;\n render: RhfFieldProps<TFieldValues, TName>[\"render\"];\n asControl: boolean;\n}) {\n const { id, formItemId, describedBy } = useFormField();\n const element = render({\n field,\n fieldState,\n invalid: fieldState.invalid,\n error: fieldState.error?.message,\n id: formItemId,\n labelId: `${id}-label`,\n describedBy,\n });\n return asControl ? <FormControl>{element}</FormControl> : element;\n}\n\n/**\n * The shell every bound field is built on: label, control, hint and message around\n * a `render` of your own.\n *\n * ```tsx\n * <RhfField name=\"address\" label=\"Address\" render={({ field, invalid }) => (\n * <AddressAutocomplete value={field.value ?? \"\"} onChange={field.onChange} invalid={invalid} />\n * )} />\n * ```\n */\nexport function RhfField<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n render,\n asControl = true,\n message = true,\n showLabel = true,\n}: RhfFieldProps<TFieldValues, TName, TTransformed>) {\n // §4: a FieldHint is a fact, so at Large and on a touch screen it is its words under\n // the field, not a lone \"?\" there (DUP-2, refactor audit 2026-10). A HelpPopover stays\n // a \"?\" at every size. With a `help` (0.36) its \"?\" follows the label and is the\n // field's only one, so a FieldHint is its words at every size.\n const helpMark = fieldHelpMark(help, label);\n // The label names a FieldSuggestion's button (0.55).\n const shownHint = useInlineHint(hint, helpMark !== undefined, label);\n const labelEl = showLabel && hasContent(label) && <RhfLabel required={required}>{label}</RhfLabel>;\n return (\n <FormField\n control={control}\n name={name}\n rules={rules}\n disabled={excludeWhenDisabled ? disabled : undefined}\n render={({ field, fieldState }) => (\n <FormItem className={className}>\n {helpMark === undefined ? (\n labelEl\n ) : (\n <div className=\"flex items-center gap-1\">\n {labelEl}\n <span className=\"flex shrink-0 items-center\">{helpMark}</span>\n </div>\n )}\n <ControlSlot\n field={disabled && !field.disabled ? { ...field, disabled: true } : field}\n fieldState={fieldState}\n render={render}\n asControl={asControl}\n />\n {hasContent(shownHint) && <FormDescription>{shownHint}</FormDescription>}\n {message && <FormMessage />}\n </FormItem>\n )}\n />\n );\n}\n\n// ── text ─────────────────────────────────────────────────────────────────────\n\ntype OwnInputProps = Omit<\n InputProps,\n | \"name\"\n | \"value\"\n | \"defaultValue\"\n | \"onChange\"\n | \"onBlur\"\n | \"ref\"\n | \"label\"\n | \"error\"\n | \"invalid\"\n | \"className\"\n | \"disabled\"\n | \"required\"\n | \"inputClassName\"\n> & {\n /**\n * Classes for the `<input>` — `className` is the item's box (kastlan 42: a\n * `font-mono` IBAN, a `tabular-nums` reference number). {@link RhfTextarea} and\n * {@link RhfNumberField} had it; this one only reached `Input`'s prop of the same\n * name by accident of the rest-spread, undocumented and one refactor from being\n * dropped. Declared, it is part of the contract the three share.\n */\n inputClassName?: string;\n};\n\nexport type RhfTextFieldProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> & OwnInputProps;\n\n/** A text {@link Input} — `type` for email, tel, password, url. Stores the string. */\nexport function RhfTextField<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n ...inputProps\n}: RhfTextFieldProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid }) => (\n <Input\n aria-required={required || undefined}\n {...inputProps}\n name={field.name}\n ref={field.ref}\n value={(field.value ?? \"\") as string}\n onChange={field.onChange}\n onBlur={field.onBlur}\n disabled={field.disabled}\n invalid={invalid}\n />\n )}\n />\n );\n}\n\ntype OwnTextareaProps = Omit<\n TextareaProps,\n | \"name\"\n | \"value\"\n | \"defaultValue\"\n | \"onChange\"\n | \"onBlur\"\n | \"ref\"\n | \"label\"\n | \"error\"\n | \"invalid\"\n | \"className\"\n | \"disabled\"\n | \"required\"\n> & {\n /** Classes for the `<textarea>`. */\n inputClassName?: string;\n};\n\nexport type RhfTextareaProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> & OwnTextareaProps;\n\n/** A multi-line {@link Textarea}; takes `rows`. Stores the string. */\nexport function RhfTextarea<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n inputClassName,\n ...areaProps\n}: RhfTextareaProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid }) => (\n <Textarea\n aria-required={required || undefined}\n {...areaProps}\n className={inputClassName}\n name={field.name}\n ref={field.ref}\n value={(field.value ?? \"\") as string}\n onChange={field.onChange}\n onBlur={field.onBlur}\n disabled={field.disabled}\n invalid={invalid}\n />\n )}\n />\n );\n}\n\n// ── numbers ──────────────────────────────────────────────────────────────────\n\n/**\n * A form value → the number field's `number | null`. Defaults hold `\"\"`, `null`, a\n * number, or a numeric string: a plain JS spelling (\"12.5\", \"1e-7\", what an API sends)\n * as it is, anything else the way the field reads typing in `mark` — \"1,234.5\", or\n * \"1.234,56\" in a comma locale (DUP-9, refactor audit 2026-10: a single\n * `replace(\",\", \".\")` read \"1,234,567\" as NaN, the U-14 pattern).\n */\nfunction toNumber(value: unknown, mark: \",\" | \".\"): number | null {\n if (value === null || value === undefined || value === \"\") return null;\n if (typeof value === \"number\") return Number.isFinite(value) ? value : null;\n const text = String(value).trim();\n const plain = text === \"\" ? NaN : Number(text);\n const typed = readTyped(text, mark);\n const n = Number.isFinite(plain) ? plain : typed === \"\" ? NaN : Number(typed);\n return Number.isFinite(n) ? n : null;\n}\n\n/** What a twin sets on its field itself — the value and its change, what the form\n * decides (`disabled`, `invalid`, the error, the ids) and what the shell draws (the\n * label, the hint, the item's `className`). Everything else of the field's passes\n * through (DUP-9, refactor audit 2026-10: a `Pick` allow-list dropped what the field\n * gained without a word). */\ntype BoundByForm =\n | \"value\"\n | \"defaultValue\"\n | \"onChange\"\n | \"onBlur\"\n | \"ref\"\n | \"name\"\n | \"disabled\"\n | \"required\"\n | \"invalid\"\n | \"error\"\n | \"label\"\n | \"hint\"\n | \"className\"\n | \"aria-describedby\"\n | \"aria-invalid\"\n | \"aria-required\";\n\nexport type RhfNumberFieldProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n // NumberField's own (the lock since 0.33.1, `onValueChange`, …), less the commit and\n // the id the shell owns.\n Omit<NumberFieldProps, BoundByForm | \"onCommit\" | \"nullable\" | \"id\"> & {\n /** What an emptied field stores. Default `null`; `\"\"` for a schema written\n * against a native number input (`z.coerce.number()` over `\"\"`). */\n emptyValue?: null | \"\";\n /** `false`: an emptied field snaps back to its last number instead of storing\n * `emptyValue`. Default `true`. */\n nullable?: boolean;\n };\n\n/**\n * The kit's {@link NumberField}: a parsed, rounded (`digits`) and clamped (`min` /\n * `max`) number, committed on blur or Enter in the locale's decimal mark. Stores a\n * number, or `emptyValue` when emptied.\n */\nexport function RhfNumberField<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n emptyValue = null,\n nullable = true,\n ...numberProps\n}: RhfNumberFieldProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid, id }) => (\n // FormControl clones this element with `id` / `aria-describedby` /\n // `aria-invalid`, which NumberControl hands on to the field.\n <NumberControl\n field={field as unknown as ControllerRenderProps}\n focusRef={field.ref}\n invalid={invalid}\n required={required}\n id={id}\n emptyValue={emptyValue}\n nullable={nullable}\n numberProps={numberProps}\n />\n )}\n />\n );\n}\n\nfunction NumberControl({\n field,\n focusRef,\n invalid,\n required,\n id,\n emptyValue,\n nullable,\n numberProps,\n ...aria\n}: {\n field: ControllerRenderProps;\n /** `field.ref`, handed over on its own so the compiler reads `field` as data. */\n focusRef: ControllerRenderProps[\"ref\"];\n invalid: boolean;\n required?: boolean;\n id: string;\n emptyValue: null | \"\";\n nullable: boolean;\n numberProps: Omit<RhfNumberFieldProps, keyof RhfFieldBaseProps | \"emptyValue\" | \"nullable\">;\n \"aria-describedby\"?: string;\n \"aria-invalid\"?: NumberFieldProps[\"aria-invalid\"];\n}) {\n // The field's own mark, for a stored text written the way it is typed.\n const mark = decimalMark(useKitLocale(numberProps.locale));\n return (\n <NumberField\n {...numberProps}\n // The <input> itself (API-3, refactor audit 2026-10): focus on error, and\n // `setFocus`'s `shouldSelect`, which an id-found stand-in had no `select()` for.\n ref={focusRef}\n aria-describedby={aria[\"aria-describedby\"]}\n aria-invalid={aria[\"aria-invalid\"]}\n aria-required={required || undefined}\n id={id}\n value={toNumber(field.value, mark)}\n onCommit={(n) => {\n field.onChange(n ?? emptyValue);\n field.onBlur();\n }}\n nullable={nullable}\n disabled={field.disabled}\n invalid={invalid}\n />\n );\n}\n\nexport type RhfIntegerFieldProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfNumberFieldProps<TFieldValues, TName, TTransformed>;\n\n/**\n * {@link RhfNumberField} for a whole number — a floor, a room count, a year, a\n * notice period in months. Every such call site in kastlan (item 41) spelled out the\n * same three props, `digits={0} calculator={false} emptyValue=\"\"`, and a preset\n * written thirty times is one that is eventually written wrong once:\n *\n * - `digits={0}`: rounds on commit, so \"2.5\" rooms settles to 3 instead of reaching\n * an `Integer` column and failing server-side;\n * - `calculator={false}`: a count is typed, not worked out — the trigger is noise\n * beside a two-digit field;\n * - `emptyValue=\"\"`: kastlan's integer schemas are `z.coerce.number()` over `\"\"`,\n * written against the native number inputs these fields replaced.\n *\n * Each is only a default: pass the prop to override it (`emptyValue={null}` for a\n * nullable column). Everything else is {@link RhfNumberField}'s.\n */\nexport function RhfIntegerField<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>(props: RhfIntegerFieldProps<TFieldValues, TName, TTransformed>) {\n // `??` / `=== undefined` rather than a spread over the defaults, so a caller\n // forwarding its own optional prop (`digits={props.digits}`) still gets the preset,\n // while an explicit `emptyValue={null}` keeps its null.\n return (\n <RhfNumberField\n {...props}\n digits={props.digits ?? 0}\n calculator={props.calculator ?? false}\n emptyValue={props.emptyValue === undefined ? \"\" : props.emptyValue}\n />\n );\n}\n\n// ── money ────────────────────────────────────────────────────────────────────\n\nexport type RhfMoneyFieldProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n // MoneyField's — AmountInput's, with the lock, `calculator` (keksdose K6), `labels`,\n // `currencyNames` and `variant` the hand-written list here had dropped (DUP-9) — less\n // what the form binds and the commit, which is the form's store.\n Omit<MoneyFieldProps, BoundByForm | \"onCommit\" | \"id\"> & {\n /**\n * What the form stores: `\"number\"` (default) — `12.5`, or `emptyValue` while the\n * field is empty — or `\"string\"`, the field's own text (\"12.50\") for a schema that\n * parses it itself. A half-typed sum (\"12+\") leaves the stored number as it was\n * until it resolves; a lone \"-\" left on blur goes back to it, as on MoneyField.\n */\n valueAs?: \"number\" | \"string\";\n /** What an emptied field stores when `valueAs` is `\"number\"`. Default `null`. */\n emptyValue?: null | \"\";\n };\n\nfunction MoneyControl({\n field,\n invalid,\n required,\n id,\n describedBy,\n props,\n}: {\n field: ControllerRenderProps;\n invalid: boolean;\n required?: boolean;\n id: string;\n describedBy: string | undefined;\n props: Omit<RhfMoneyFieldProps, keyof RhfFieldBaseProps>;\n}) {\n const { valueAs = \"number\", emptyValue = null, ...amountProps } = props;\n // MoneyField's draft and settle (DUP-9): the text being typed, re-read from the form\n // only when its value moves away from what the draft says, and a lone \"-\" back on the\n // stored amount when the figure settles.\n const money = useMoneyDraft(field.value, valueAs);\n const input = useRef<HTMLInputElement | null>(null);\n // AmountInput reports no blur, and react-hook-form needs one to mark the field\n // touched: listen on its <input>.\n const onBlur = field.onBlur;\n useLayoutEffect(() => {\n const el = input.current;\n if (!el) return;\n el.addEventListener(\"blur\", onBlur);\n return () => el.removeEventListener(\"blur\", onBlur);\n }, [onBlur]);\n return (\n <div>\n <AmountInput\n {...amountProps}\n id={id}\n aria-describedby={describedBy}\n aria-required={required || undefined}\n ref={(el) => {\n input.current = el;\n field.ref(el);\n }}\n value={money.draft}\n disabled={field.disabled}\n invalid={invalid}\n onChange={(text) => {\n const parsed = money.change(text);\n if (valueAs === \"string\") {\n field.onChange(text);\n return;\n }\n if (parsed === undefined) return;\n field.onChange(parsed ?? emptyValue);\n }}\n onCommit={money.settle}\n />\n </div>\n );\n}\n\n/**\n * The kit's {@link AmountInput}: a money figure with its currency chip and the\n * calculator (\"1200+80\" resolves on blur or Enter). Stores a number by default — see\n * `valueAs`.\n */\nexport function RhfMoneyField<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n ...amountProps\n}: RhfMoneyFieldProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n asControl={false}\n render={({ field, invalid, id, describedBy }) => (\n <MoneyControl\n field={field as unknown as ControllerRenderProps}\n invalid={invalid}\n required={required}\n id={id}\n describedBy={describedBy}\n props={amountProps}\n />\n )}\n />\n );\n}\n\n// ── date ─────────────────────────────────────────────────────────────────────\n\nexport type RhfDateFieldProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n // `error`: the form's message is shown by the binding (FormMessage); the picker's own\n // `error` (0.22) would show it a second time.\n Omit<DatePickerProps, \"value\" | \"onChange\" | \"label\" | \"invalid\" | \"disabled\" | \"className\" | \"id\" | \"error\"> & {\n /** Classes for the picker. Default `w-full`. */\n inputClassName?: string;\n /** What a cleared date stores. Default `\"\"`, the empty ISO string; `null` for a\n * nullable schema. */\n emptyValue?: \"\" | null;\n };\n\nfunction DateControl({\n field,\n focusRef,\n invalid,\n required,\n id,\n emptyValue,\n inputClassName,\n pickerProps,\n ...aria\n}: {\n field: ControllerRenderProps;\n /** `field.ref`, handed over on its own so the compiler reads `field` as data. */\n focusRef: ControllerRenderProps[\"ref\"];\n invalid: boolean;\n required?: boolean;\n id: string;\n emptyValue: \"\" | null;\n inputClassName?: string;\n pickerProps: Omit<DatePickerProps, \"value\" | \"onChange\" | \"label\" | \"invalid\" | \"disabled\" | \"className\" | \"id\">;\n \"aria-describedby\"?: string;\n \"aria-invalid\"?: DatePickerProps[\"aria-invalid\"];\n}) {\n const value: unknown = field.value;\n return (\n <DatePicker\n {...pickerProps}\n {...aria}\n // The trigger itself (API-3, refactor audit 2026-10), not an id lookup.\n ref={focusRef}\n aria-required={required || undefined}\n id={id}\n value={typeof value === \"string\" ? value : \"\"}\n onChange={(iso) => {\n field.onChange(iso === \"\" ? emptyValue : iso);\n field.onBlur();\n }}\n disabled={field.disabled}\n invalid={invalid}\n className={inputClassName ?? \"w-full\"}\n />\n );\n}\n\n/**\n * The kit's {@link DatePicker}, holding an ISO `\"YYYY-MM-DD\"` string. `commit` and\n * `disabledReason` are the picker's own (0.52, refactor audit 2026-10-30, API-3): a date\n * that saves itself stays focusable under a lock and says why.\n */\nexport function RhfDateField<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n inputClassName,\n emptyValue = \"\",\n ...pickerProps\n}: RhfDateFieldProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid, id }) => (\n // FormControl clones this element with `aria-describedby` / `aria-invalid`,\n // which DateControl hands on to the picker's trigger.\n <DateControl\n field={field as unknown as ControllerRenderProps}\n focusRef={field.ref}\n invalid={invalid}\n required={required}\n id={id}\n emptyValue={emptyValue}\n inputClassName={inputClassName}\n pickerProps={pickerProps}\n />\n )}\n />\n );\n}\n\n// ── date range ───────────────────────────────────────────────────────────────\n\ntype OwnDateRangeProps = Omit<\n DateRangePickerProps,\n \"from\" | \"to\" | \"onChange\" | \"label\" | \"invalid\" | \"disabled\" | \"className\" | \"id\" | \"error\"\n>;\n\nexport type RhfDateRangePickerProps<\n TFieldValues extends FieldValues = FieldValues,\n TFromName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TToName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = Omit<RhfFieldBaseProps<TFieldValues, TFromName, TTransformed>, \"name\" | \"rules\"> &\n OwnDateRangeProps & {\n /** The form field holding the range's first day, an ISO `\"YYYY-MM-DD\"`. */\n fromName: TFromName;\n /** The form field holding the range's last day. */\n toName: TToName;\n /** react-hook-form's `rules` for the start (`required`, a `validate` …). */\n fromRules?: ControllerProps<TFieldValues, TFromName, TTransformed>[\"rules\"];\n /** react-hook-form's `rules` for the end — the place for \"not before the start\",\n * which can read the start with `getValues`: the start is always written first. */\n toRules?: ControllerProps<TFieldValues, TToName, TTransformed>[\"rules\"];\n /** Classes for the picker. Default `w-full`. */\n inputClassName?: string;\n /** What an empty end stores — a clear, or the half-made range between the first\n * and second click. Default `\"\"`, the empty ISO string; `null` for a nullable\n * schema. */\n emptyValue?: \"\" | null;\n };\n\n/**\n * The kit's {@link DateRangePicker} over TWO form fields — `fromName` and `toName` —\n * the way a period is stored: as two columns, each its own schema key, not one\n * `{ from, to }` object (kastlan 4).\n *\n * ```tsx\n * <RhfDateRangePicker fromName=\"periodFrom\" toName=\"periodTo\" label=\"Billing period\"\n * presets={presets} clearable />\n * ```\n *\n * Why it is not {@link RhfField}: a `Controller` binds one name, and the range is\n * two. Built by hand — an `RhfField` on the start and a second `useController` for\n * the end, which is what kastlan's period fields needed — it works until the END is\n * the one in error: the shell's label, message and `aria-invalid` all read the\n * start's state alone, so \"End before start\" (a `refine` with `path: [\"periodTo\"]`,\n * where such a rule goes) never shows. Here both states are read:\n *\n * - **Either field's error is shown and paints.** The label turns, the trigger is\n * `aria-invalid` and wears the danger border when EITHER field has an error, and\n * both messages are listed under the field (once, if the two say the same thing),\n * each pointed at by the trigger's `aria-describedby`.\n * - **One change writes both.** The picker reports the range whole, so the start and\n * then the end are written on every change — the end too when only the start\n * moved, so a cross-field rule on the end re-runs and an \"End before start\" clears\n * the moment the start is fixed. A clear (`clearable`'s ×) empties both.\n * - **Focus on error** lands on the trigger whichever of the two is in error.\n * - **Touched** once a range is complete or cleared — not on the first click of a\n * pick, which would mark (and, with `mode: \"onTouched\"`, validate) an end the user\n * is still choosing.\n *\n * Without `apply` (the picker's default) the first calendar click is reported on its\n * own, so the form holds `(from, emptyValue)` until the second; with `apply` nothing\n * reaches the form until Apply. `apply` was `commit=\"apply\"` until 0.52 (gone in 0.53):\n * `commit` is now the write lock's, as on every other binding — with\n * `disabledReason`, the picker's own (refactor audit 2026-10-30, API-3).\n *\n * The common props (`label`, `hint`, `required`, `disabled`, `excludeWhenDisabled`,\n * `control`, `className`) apply to the pair; `rules` are per field.\n */\nexport function RhfDateRangePicker<\n TFieldValues extends FieldValues = FieldValues,\n TFromName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TToName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n fromName,\n toName,\n control,\n fromRules,\n toRules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n inputClassName,\n emptyValue = \"\",\n ...pickerProps\n}: RhfDateRangePickerProps<TFieldValues, TFromName, TToName, TTransformed>) {\n const rhfDisabled = excludeWhenDisabled ? disabled : undefined;\n // The end, read here; the start is the FormField below, which gives the label, hint\n // and ids their context. This component re-renders on the end's state, and with it\n // the FormField's render.\n const to = useController<TFieldValues, TToName, TTransformed>({\n name: toName,\n control,\n rules: toRules,\n disabled: rhfDisabled,\n });\n return (\n <FormField\n control={control}\n name={fromName}\n rules={fromRules}\n disabled={rhfDisabled}\n render={({ field, fieldState }) => (\n <FormItem className={className}>\n <RangeBody\n from={field as unknown as ControllerRenderProps}\n fromState={fieldState}\n to={to.field as unknown as ControllerRenderProps}\n toState={to.fieldState}\n label={label}\n hint={hint}\n help={help}\n required={required}\n disabled={Boolean(disabled)}\n emptyValue={emptyValue}\n inputClassName={inputClassName}\n pickerProps={pickerProps}\n />\n </FormItem>\n )}\n />\n );\n}\n\nfunction RangeBody({\n from,\n fromState,\n to,\n toState,\n label,\n hint,\n help,\n required,\n disabled,\n emptyValue,\n inputClassName,\n pickerProps,\n}: {\n from: ControllerRenderProps;\n fromState: ControllerFieldState;\n to: ControllerRenderProps;\n toState: ControllerFieldState;\n label: ReactNode;\n hint: ReactNode;\n help: ReactNode;\n required?: boolean;\n disabled: boolean;\n emptyValue: \"\" | null;\n inputClassName?: string;\n pickerProps: OwnDateRangeProps;\n}) {\n const { id, formItemId, formMessageId, describedBy } = useFormField();\n // RhfField's rule: a FieldHint is its words at Large and on touch (DUP-2) — and at\n // every size beside a `help`, whose \"?\" follows the label (0.36).\n const helpMark = fieldHelpMark(help, label);\n const shownHint = useInlineHint(hint, helpMark !== undefined, label);\n // Both fields' refs go to the one trigger (API-3, refactor audit 2026-10), so\n // `shouldFocusError` lands there whichever of the two is first in error.\n const triggerRef = useMemo(() => mergeRefs(from.ref, to.ref), [from.ref, to.ref]);\n const invalid = fromState.invalid || toState.invalid;\n const messages = [fromState.error?.message, toState.error?.message].filter(\n (m, i, all): m is string => typeof m === \"string\" && m !== \"\" && all.indexOf(m) === i,\n );\n const messageIds = messages.map((_, i) => `${formMessageId}-${i}`);\n const fromValue: unknown = from.value;\n const toValue: unknown = to.value;\n const labelEl = hasContent(label) && (\n // FormLabel colours from the START's error alone (its context is that field); the\n // pair's state says it here.\n <FormLabel id={`${id}-label`} required={required} data-error={invalid || undefined}>\n {label}\n </FormLabel>\n );\n return (\n <>\n {helpMark === undefined ? (\n labelEl\n ) : (\n <div className=\"flex items-center gap-1\">\n {labelEl}\n <span className=\"flex shrink-0 items-center\">{helpMark}</span>\n </div>\n )}\n <DateRangePicker\n {...pickerProps}\n ref={triggerRef}\n id={formItemId}\n // Merged, never replaced — a caller's own reference first, as FormControl does.\n aria-describedby={\n [pickerProps[\"aria-describedby\"], describedBy, ...messageIds].filter(Boolean).join(\" \") || undefined\n }\n aria-invalid={invalid || undefined}\n aria-required={required || undefined}\n from={typeof fromValue === \"string\" ? fromValue : \"\"}\n to={typeof toValue === \"string\" ? toValue : \"\"}\n onChange={(f, t) => {\n from.onChange(f === \"\" ? emptyValue : f);\n to.onChange(t === \"\" ? emptyValue : t);\n if (t !== \"\" || f === \"\") {\n from.onBlur();\n to.onBlur();\n }\n }}\n disabled={disabled || from.disabled || to.disabled}\n invalid={invalid}\n className={inputClassName ?? \"w-full\"}\n />\n {hasContent(shownHint) && <FormDescription>{shownHint}</FormDescription>}\n {messages.map((message, i) => (\n // FormMessage's look and its rule: no `role=\"alert\"` — read when focus reaches\n // the trigger, which names these in its description.\n <p key={message} id={messageIds[i]} data-slot=\"form-message\" className=\"text-caption leading-tight text-danger\">\n {message}\n </p>\n ))}\n </>\n );\n}\n\n// ── time ─────────────────────────────────────────────────────────────────────\n\nexport type RhfTimeInputProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n Omit<\n TimeInputProps,\n | \"name\"\n | \"value\"\n | \"defaultValue\"\n | \"onChange\"\n | \"onValueChange\"\n | \"onBlur\"\n | \"label\"\n | \"error\"\n | \"invalid\"\n | \"className\"\n | \"disabled\"\n | \"required\"\n > & {\n /** What a cleared time stores. Default `\"\"`; `null` for a nullable schema. */\n emptyValue?: \"\" | null;\n };\n\n/**\n * The kit's {@link TimeInput}: a time of day as `\"HH:mm\"` (`\"HH:mm:ss\"` when `step`\n * asks for seconds), normalised before it reaches the form, so the stored value\n * compares and sorts as a string. kastlan 4: the owner meeting's time was an\n * {@link RhfField} with a hand-wired `TimeInput` in its render — `ref`, `name`, the\n * `?? \"\"`, `onValueChange`, `onBlur`, `invalid` — the seven lines every bound field\n * folds into one.\n *\n * `min` / `max` paint an out-of-window time (see TimeInput) but do not fail the form:\n * validation stays the schema's or `rules`'. `rules={{ validate: (v) =>\n * isTimeInRange(v, min, max) || \"…\" }}` says it with the same window.\n */\nexport function RhfTimeInput<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n emptyValue = \"\",\n ...timeProps\n}: RhfTimeInputProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid }) => {\n const value: unknown = field.value;\n return (\n <TimeInput\n aria-required={required || undefined}\n {...timeProps}\n name={field.name}\n ref={field.ref}\n value={typeof value === \"string\" ? value : \"\"}\n onValueChange={(v) => field.onChange(v === \"\" ? emptyValue : v)}\n onBlur={field.onBlur}\n disabled={field.disabled}\n invalid={invalid}\n />\n );\n }}\n />\n );\n}\n\n// ── IBAN and phone (0.22) ────────────────────────────────────────────────────\n\ntype OwnTextishProps<P> = Omit<\n P,\n | \"name\"\n | \"value\"\n | \"defaultValue\"\n | \"onChange\"\n | \"onValueChange\"\n | \"onBlur\"\n | \"label\"\n | \"error\"\n | \"invalid\"\n | \"className\"\n | \"disabled\"\n | \"required\"\n>;\n\nexport type RhfIbanInputProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> & OwnTextishProps<IbanInputProps>;\n\n/**\n * {@link IbanInput} bound to one field, which stores the COMPACT upper-case IBAN (what\n * kastlan's server checks and its QR bill prints). The field's own checksum and\n * `kind` messages show while the form has nothing to say; a form error (the schema's\n * or `rules`') replaces them, as a caller's `error` does on the bare field. kastlan\n * asked for the field; it binds everything through react-hook-form.\n */\nexport function RhfIbanInput<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n ...ibanProps\n}: RhfIbanInputProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid }) => {\n const value: unknown = field.value;\n return (\n <IbanInput\n aria-required={required || undefined}\n {...ibanProps}\n name={field.name}\n ref={field.ref}\n value={typeof value === \"string\" ? value : \"\"}\n onValueChange={field.onChange}\n onBlur={field.onBlur}\n disabled={field.disabled}\n invalid={invalid}\n />\n );\n }}\n />\n );\n}\n\nexport type RhfPhoneInputProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> & OwnTextishProps<PhoneInputProps>;\n\n/**\n * {@link PhoneInput} bound to one field, which stores E.164 when the number reads as\n * one and the typed text unchanged otherwise — kastlan's contacts keep their old free\n * text until someone edits it. Validation (required, a pattern for E.164 only) is the\n * schema's or `rules`'.\n */\nexport function RhfPhoneInput<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n ...phoneProps\n}: RhfPhoneInputProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid }) => {\n const value: unknown = field.value;\n return (\n <PhoneInput\n aria-required={required || undefined}\n {...phoneProps}\n name={field.name}\n ref={field.ref}\n value={typeof value === \"string\" ? value : \"\"}\n onValueChange={field.onChange}\n onBlur={field.onBlur}\n disabled={field.disabled}\n invalid={invalid}\n />\n );\n }}\n />\n );\n}\n\n// ── country and month (0.23) ─────────────────────────────────────────────────\n\ntype OwnCountrySelectProps = Omit<\n CountrySelectProps<boolean>,\n | \"value\"\n | \"onChange\"\n | \"onBlur\"\n | \"label\"\n | \"hint\"\n | \"error\"\n | \"invalid\"\n | \"disabled\"\n | \"className\"\n | \"id\"\n | \"ref\"\n | \"clearable\"\n>;\n\nexport type RhfCountrySelectProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n OwnCountrySelectProps & {\n /** Offer the picker's clear \"×\" (and Delete on the trigger) while a country is\n * chosen. A clear stores `clearValue`. */\n clearable?: boolean;\n /** What a clear stores. Default `null`; `\"\"` for a schema that spells \"no\n * country\" as an empty string (a zod `z.string().max(2)`, kastlan's). The picker\n * reads either back as empty. */\n clearValue?: ComboClearValue;\n /** Classes for the picker — `className` is the item's box. */\n selectClassName?: string;\n };\n\n/**\n * {@link CountrySelect} bound to one field, which stores the ISO 3166-1 alpha-2 code\n * (\"CH\", always upper-case), or `clearValue` once cleared (`clearable`). kastlan asked\n * for it (0.22 adoption): its address form wired a `CountrySelect` through\n * {@link RhfField}'s render, and with no ref on the picker react-hook-form's\n * focus-on-error had nothing to focus — the one field on the form a failed submit\n * could not take you to.\n *\n * Bound the way {@link RhfIbanInput} and {@link RhfPhoneInput} are: `field.ref` reaches\n * the trigger (the picker's `ref`, 0.23), the form's error paints the trigger and is\n * the shell's message under it, the hint is the shell's description — so neither is\n * ever handed to the picker, and its box never changes when one comes or goes. The\n * form's label names the trigger together with the chosen country, and is the phone\n * sheet's title. `commit` and `disabledReason` are the picker's own: a country that\n * saves itself stays focusable under a lock and says why.\n *\n * ```tsx\n * <RhfCountrySelect name=\"country\" label=\"Country\" required\n * preferred={[\"CH\", \"LI\", \"DE\", \"AT\", \"FR\", \"IT\"]} rules={{ required: \"Choose a country\" }} />\n * ```\n */\nexport function RhfCountrySelect<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n clearable,\n clearValue = null,\n selectClassName,\n labels,\n ...countryProps\n}: RhfCountrySelectProps<TFieldValues, TName, TTransformed>) {\n const labelled = hasContent(label);\n // A string label is also what the field IS — the picker's `country` word, which\n // titles the phone sheet. A caller's own `labels.country` still wins.\n const ownLabels = typeof label === \"string\" ? { country: label, ...labels } : labels;\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid, labelId }) => {\n const value: unknown = field.value;\n return (\n // FormControl clones this element with `id` / `aria-describedby` /\n // `aria-invalid`, which the picker routes to its trigger.\n <CountrySelect<boolean>\n aria-required={required || undefined}\n // The form's label, then the country (see the picker's `aria-labelledby`).\n aria-labelledby={labelled ? labelId : undefined}\n {...countryProps}\n labels={ownLabels}\n className={selectClassName}\n ref={field.ref}\n value={typeof value === \"string\" ? value : null}\n clearable={clearable}\n onChange={(code) => field.onChange(code ?? clearValue)}\n // Focus leaving the picker (the wrapper's focusout) marks the field touched.\n onBlur={field.onBlur}\n disabled={field.disabled}\n invalid={invalid}\n />\n );\n }}\n />\n );\n}\n\ntype OwnMonthPickerProps = Omit<\n MonthPickerProps,\n \"value\" | \"onChange\" | \"onBlur\" | \"label\" | \"hint\" | \"error\" | \"invalid\" | \"disabled\" | \"className\" | \"id\" | \"mode\"\n>;\n\n/** `mode` picks what the form stores, and `valueAsNumber` is only offered for a year. */\ntype RhfMonthPickerMode =\n | {\n /** A month, stored as `\"YYYY-MM\"` (the default). */\n mode?: \"month\";\n valueAsNumber?: undefined;\n }\n | {\n /** A year, stored as `\"YYYY\"` — or as a number with `valueAsNumber`. */\n mode: \"year\";\n /** Store the year as a number (`2026`) rather than `\"2026\"` — kastlan's budget\n * `fiscal_year` is an integer column. A number in the form reads back as its\n * year. */\n valueAsNumber?: boolean;\n };\n\nexport type RhfMonthPickerProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n OwnMonthPickerProps & {\n /** Classes for the picker — `className` is the item's box. As {@link RhfDateField}'s. */\n inputClassName?: string;\n } & RhfMonthPickerMode;\n\nfunction MonthControl({\n field,\n focusRef,\n invalid,\n id,\n valueAsNumber,\n mode,\n inputClassName,\n pickerProps,\n required,\n ...aria\n}: {\n field: ControllerRenderProps;\n /** `field.ref`, handed over on its own so the compiler reads `field` as data. */\n focusRef: ControllerRenderProps[\"ref\"];\n invalid: boolean;\n id: string;\n valueAsNumber?: boolean;\n mode?: \"month\" | \"year\";\n inputClassName?: string;\n pickerProps: OwnMonthPickerProps;\n required?: boolean;\n \"aria-describedby\"?: string;\n \"aria-invalid\"?: MonthPickerProps[\"aria-invalid\"];\n}) {\n const value: unknown = field.value;\n return (\n <MonthPicker\n {...pickerProps}\n {...aria}\n // The trigger itself (API-3, refactor audit 2026-10) — RhfDateField's way.\n ref={focusRef}\n // MonthPicker routes `aria-required` to its trigger since 0.23.0.\n aria-required={required || undefined}\n id={id}\n mode={mode}\n value={value === null || value === undefined ? \"\" : String(value)}\n onChange={(key) => {\n field.onChange(mode === \"year\" && valueAsNumber ? Number(key) : key);\n // A pick is the whole interaction — there is no text to leave — so it touches.\n field.onBlur();\n }}\n disabled={field.disabled}\n invalid={invalid}\n className={inputClassName}\n />\n );\n}\n\n/**\n * {@link MonthPicker} bound to one field: a month as `\"YYYY-MM\"`, or with `mode=\"year\"` a\n * year as `\"YYYY\"` (`valueAsNumber` stores `2026`). kastlan asked for it with\n * {@link RhfCountrySelect}: its budget wizard's fiscal year was a `MonthPicker\n * mode=\"year\"` inside {@link RhfField}'s render — the `String()` in, the `Number()`\n * out, `invalid` by hand — and a failed submit could not focus it, because the picker\n * forwards no ref.\n *\n * Bound as {@link RhfDateField} is: `field.ref` is the picker's `ref`, its trigger (an id\n * lookup until 0.34, API-3), so focus-on-error lands there; the form's error paints the\n * trigger and is the shell's message; the hint is the shell's description; neither is\n * handed to the picker, so its box never changes. Picking marks the field touched.\n * `commit` and `disabledReason` are the picker's own (0.52, API-3).\n *\n * ```tsx\n * <RhfMonthPicker name=\"fiscalYear\" label=\"Fiscal year\" mode=\"year\" valueAsNumber\n * min=\"2020\" max=\"2029\" rules={{ required: \"Choose a year\" }} />\n * ```\n */\nexport function RhfMonthPicker<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n inputClassName,\n mode,\n valueAsNumber,\n ...pickerProps\n}: RhfMonthPickerProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid, id }) => (\n // FormControl clones this element with `aria-describedby` / `aria-invalid`,\n // which MonthControl hands on to the picker's trigger.\n <MonthControl\n field={field as unknown as ControllerRenderProps}\n focusRef={field.ref}\n invalid={invalid}\n id={id}\n mode={mode}\n valueAsNumber={valueAsNumber}\n inputClassName={inputClassName}\n pickerProps={pickerProps}\n required={required}\n />\n )}\n />\n );\n}\n\n// ── select ───────────────────────────────────────────────────────────────────\n\nexport interface RhfSelectOption {\n value: string | number;\n label: ReactNode;\n disabled?: boolean;\n}\n\nexport type RhfSelectProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n // Select's own — its lock (`commit`, `disabledReason`), `size`, … — which a `Pick`\n // list dropped until 0.34 (DUP-9). One value, so not `multiple`.\n Omit<SelectProps, BoundByForm | \"children\" | \"multiple\" | \"selectClassName\"> & {\n /** The options, as data. Or pass `<option>` children. */\n options?: readonly RhfSelectOption[];\n children?: ReactNode;\n /** A first, empty option (\"Choose…\"), selected while the value is empty. */\n placeholder?: string;\n /** Store `Number(value)` rather than the option's string. An empty choice still\n * stores `\"\"`. */\n valueAsNumber?: boolean;\n /** Classes for the select. Default `w-full`. */\n selectClassName?: string;\n };\n\n/** A native {@link Select}, from `options` or `<option>` children. */\nexport function RhfSelect<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n options,\n children,\n placeholder,\n valueAsNumber,\n selectClassName,\n ...selectProps\n}: RhfSelectProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid }) => (\n <Select\n aria-required={required || undefined}\n {...selectProps}\n className={cn(\"w-full\", selectClassName)}\n name={field.name}\n ref={field.ref}\n value={(field.value ?? \"\") as string | number}\n onChange={(e) => {\n const raw = e.target.value;\n field.onChange(valueAsNumber && raw !== \"\" ? Number(raw) : raw);\n }}\n onBlur={field.onBlur}\n disabled={field.disabled}\n invalid={invalid}\n >\n {placeholder !== undefined && <option value=\"\">{placeholder}</option>}\n {options\n ? options.map((o) => (\n <option key={String(o.value)} value={o.value} disabled={o.disabled}>\n {o.label}\n </option>\n ))\n : children}\n </Select>\n )}\n />\n );\n}\n\n// ── checkbox ─────────────────────────────────────────────────────────────────\n\nexport type RhfCheckboxProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> =\n // No `help` (0.36): a box has no label line — its label sits beside it, inside the\n // `<label>` a \"?\" cannot join — and Checkbox takes none.\n Omit<RhfFieldBaseProps<TFieldValues, TName, TTransformed>, \"help\"> &\n // Checkbox's own — its lock (`commit`, `disabledReason`) among them, which a `Pick`\n // list dropped until 0.34 (DUP-9) — less the box's state the form holds, and its\n // `description`, which is the twin's `hint`.\n Omit<CheckboxProps, BoundByForm | \"checked\" | \"defaultChecked\" | \"onCheckedChange\" | \"description\">;\n\n/**\n * The kit's {@link Checkbox}, label beside the box and `hint` under it (the\n * checkbox's own `description`). Stores a boolean. `required` is the native one here\n * — see Checkbox — so a `<form>` refuses to submit it unticked.\n */\nexport function RhfCheckbox<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n ...boxProps\n}: RhfCheckboxProps<TFieldValues, TName, TTransformed>) {\n // RhfField's rule for the box's own description: a FieldHint is its words at Large\n // and on touch (DUP-2).\n const description = useInlineHint(hint, false, label);\n return (\n <RhfField\n {...{ name, control, rules, required, disabled, excludeWhenDisabled, className }}\n showLabel={false}\n render={({ field, invalid }) => (\n <Checkbox\n {...boxProps}\n ref={field.ref}\n name={field.name}\n checked={Boolean(field.value)}\n onCheckedChange={field.onChange}\n onBlur={field.onBlur}\n disabled={field.disabled}\n required={required}\n invalid={invalid}\n label={label}\n description={description}\n />\n )}\n />\n );\n}\n\n// ── toggle group ─────────────────────────────────────────────────────────────\n\n/** The two shapes a {@link ToggleGroup} comes in, carried over: `allowEmpty` picks\n * whether a press on the chosen option clears it, and types the caption to match. */\ntype RhfToggleGroupMode<T extends string> =\n | {\n /** One option is always the answer (the default): a press on the chosen\n * option re-sends it. */\n allowEmpty?: false;\n semantics?: ToggleGroupRequiredProps<T>[\"semantics\"];\n caption?: ToggleGroupRequiredProps<T>[\"caption\"];\n emptyValue?: undefined;\n }\n | {\n /** A press on the chosen option clears it, and the form stores `emptyValue`. */\n allowEmpty: true;\n semantics?: ToggleGroupClearableProps<T>[\"semantics\"];\n caption?: ToggleGroupClearableProps<T>[\"caption\"];\n /** What a cleared group stores. Default `null`; `\"\"` for a schema that spells\n * \"no choice\" as an empty string. */\n emptyValue?: null | \"\";\n };\n\nexport type RhfToggleGroupProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n T extends string = string,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n // The group's own (its `disabledReasonDisplay` was not on the `Pick` list this was\n // until 0.34, DUP-9), less what the form binds, the ids, and the label's placement:\n // the label is the form's, above.\n Omit<ToggleGroupBaseProps<T>, BoundByForm | \"id\" | \"aria-labelledby\" | \"labelPlacement\" | \"chromeClassName\"> & {\n /** Classes for the group itself — `className` is the item's box. */\n groupClassName?: string;\n } & RhfToggleGroupMode<T>;\n\n/**\n * The kit's {@link ToggleGroup} bound to one field: a choice between a few answers\n * (\"Monthly / Quarterly / Yearly\"), stored as the chosen option's `value`. kastlan 4\n * asked for it with {@link RhfTimeInput} and {@link RhfDateRangePicker}: the controls\n * its forms still had to wire by hand through {@link RhfField}'s render.\n *\n * The label is the field's own label above the bare group, as on every other\n * bound field — the `labelPlacement=\"above\"` shape, not the group's own field chrome —\n * and it names the group (`aria-labelledby`); the hint and the message describe it,\n * and an error paints the group's border. Focus on error goes to the option a\n * keyboard user would land on (the chosen one, else the first); touched is set when\n * focus leaves the group, not when it moves between options.\n *\n * Required by default, as the group is: a press on the chosen option keeps it. With\n * `allowEmpty`, a second press clears the choice and the form stores `emptyValue`\n * (`null` by default) — the options then become toggle buttons, see ToggleGroup. A\n * value that matches no option (an empty default) leaves nothing pressed; that the\n * field still needs answering is the schema's or `rules`' to say.\n */\nexport function RhfToggleGroup<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n T extends string = string,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n ...groupProps\n}: RhfToggleGroupProps<TFieldValues, TName, T, TTransformed>) {\n const labelled = hasContent(label);\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n asControl={false}\n render={({ field, invalid, id, labelId, describedBy }) => (\n <ToggleControl<T>\n field={field as unknown as ControllerRenderProps}\n invalid={invalid}\n required={required}\n id={id}\n labelledBy={labelled ? labelId : undefined}\n describedBy={describedBy}\n groupProps={groupProps}\n />\n )}\n />\n );\n}\n\nfunction ToggleControl<T extends string>({\n field,\n invalid,\n required,\n id,\n labelledBy,\n describedBy,\n groupProps,\n}: {\n field: ControllerRenderProps;\n invalid: boolean;\n required?: boolean;\n id: string;\n labelledBy: string | undefined;\n describedBy: string | undefined;\n groupProps: Omit<RhfToggleGroupProps<FieldValues, string, T>, keyof RhfFieldBaseProps>;\n}) {\n const { groupClassName, emptyValue, allowEmpty, semantics, caption, ...rest } = groupProps;\n // React's onBlur is focusout: it fires on every move between options as well, and\n // only leaving the group is a blur of the FIELD.\n const onBlur = (e: FocusEvent<HTMLDivElement>) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) field.onBlur();\n };\n const raw: unknown = field.value;\n const value = raw === null || raw === undefined || raw === \"\" ? null : (String(raw) as T);\n const common = {\n ...rest,\n // The group (API-3, refactor audit 2026-10): its `focus()` lands on the radio shape's\n // tab stop, or the pressed shape's pressed option — the rule this adapter carried\n // as an id lookup until ToggleGroup took a ref.\n ref: field.ref,\n id,\n className: groupClassName,\n \"aria-labelledby\": labelledBy,\n \"aria-describedby\": describedBy,\n \"aria-invalid\": invalid || undefined,\n disabled: field.disabled,\n onBlur,\n };\n // The props' union pairs `allowEmpty` with its caption's type; taken apart above it no\n // longer narrows, so each branch says which half it is.\n if (allowEmpty) {\n return (\n <ToggleGroup<T>\n {...common}\n allowEmpty\n caption={caption as ToggleGroupClearableProps<T>[\"caption\"]}\n value={value}\n onChange={(v) => field.onChange(v ?? emptyValue ?? null)}\n />\n );\n }\n return (\n <ToggleGroup<T>\n {...common}\n allowEmpty={false}\n semantics={semantics}\n caption={caption as ToggleGroupRequiredProps<T>[\"caption\"]}\n // A radiogroup takes `aria-required`; a group of toggle buttons does not.\n aria-required={required && semantics !== \"pressed\" ? true : undefined}\n // An empty default matches no option: nothing pressed, the first option the tab\n // stop.\n value={(value ?? \"\") as T}\n onChange={(v) => field.onChange(v)}\n />\n );\n}\n\n// ── comboboxes ───────────────────────────────────────────────────────────────\n\nexport type RhfComboboxProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n V extends string | number = string | number,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n // The picker's own, as an `Omit` since 0.34 (DUP-9) rather than the `Pick` list it\n // was, less what the form binds and the clear value, which is the twin's below.\n Omit<EntityComboboxProps<V>, BoundByForm | \"id\" | \"clearValue\"> & {\n /** What a clear stores — the picker's `clearValue`. Default `null`; `\"\"` for a\n * schema that spells \"no choice\" as an empty string. */\n clearValue?: ComboClearValue;\n /** Classes for the picker. */\n comboClassName?: string;\n };\n\nfunction EntityControl<V extends string | number>({\n field,\n invalid,\n required,\n error,\n id,\n describedBy,\n clearValue,\n comboClassName,\n sheetTitle,\n focusRef,\n comboProps,\n}: {\n field: ControllerRenderProps;\n invalid: boolean;\n required?: boolean;\n error: string | undefined;\n id: string;\n describedBy: string | undefined;\n clearValue: ComboClearValue;\n comboClassName?: string;\n sheetTitle: ReactNode;\n /** `field.ref`, handed over on its own so the compiler reads `field` as data. */\n focusRef: ControllerRenderProps[\"ref\"];\n comboProps: Omit<RhfComboboxProps<FieldValues, string, V>, keyof RhfFieldBaseProps | \"clearValue\" | \"comboClassName\">;\n}) {\n const box = useRef<HTMLDivElement>(null);\n // EntityCombobox puts `id` and the ARIA below on its trigger, so the label's\n // `htmlFor` names it and the hint describes it; `field.ref` reaches the trigger\n // through the picker's own `ref` (0.24), as RhfCountrySelect's does.\n // EntityCombobox reports no blur: focus leaving the picker marks the field touched.\n const onBlur = field.onBlur;\n useLayoutEffect(() => {\n const el = box.current;\n if (!el) return;\n el.addEventListener(\"focusout\", onBlur);\n return () => el.removeEventListener(\"focusout\", onBlur);\n }, [onBlur]);\n const value: unknown = field.value;\n return (\n <div ref={box}>\n <EntityCombobox<V, ComboClearValue>\n // The form's label titles the phone sheet: the picker is not handed `label`,\n // which the FormLabel above already draws.\n sheetTitle={sheetTitle}\n {...comboProps}\n ref={focusRef}\n className={comboClassName}\n id={id}\n aria-describedby={describedBy}\n aria-required={required || undefined}\n value={(value ?? null) as V | ComboClearValue | null}\n clearValue={clearValue}\n onChange={(v) => field.onChange(v)}\n disabled={field.disabled}\n invalid={invalid}\n // Its own message, which it merges into the trigger's aria-describedby after\n // the hint.\n error={error}\n />\n </div>\n );\n}\n\n/**\n * The kit's {@link EntityCombobox}: an id-keyed pick from `options` or `loadOptions`.\n * Stores the option's `value`, or `clearValue` on a clear (only offered with\n * `clearable`).\n *\n * 0.24: `field.ref` goes through the picker's own `ref` to its trigger (it used to be\n * a focus handle that found the trigger by id — the same element, now by the route\n * every other binding takes); the write lock (`commit`, `disabledReason`), the create\n * row's `createEmptyLabel` / `createCommit`, `closeLabel` and `aria-label` pass\n * through; and the form's label titles the phone sheet, which fell back to the\n * placeholder. For the INLINE picker — a text input, the account field typed into —\n * see {@link RhfInlineEntityCombobox}.\n */\nexport function RhfCombobox<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n V extends string | number = string | number,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n clearValue = null,\n comboClassName,\n ...comboProps\n}: RhfComboboxProps<TFieldValues, TName, V, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n asControl={false}\n message={false}\n render={({ field, invalid, error, id, describedBy }) => (\n <EntityControl<V>\n field={field as unknown as ControllerRenderProps}\n invalid={invalid}\n required={required}\n error={error}\n id={id}\n describedBy={describedBy}\n clearValue={clearValue}\n comboClassName={comboClassName}\n sheetTitle={hasContent(label) ? label : undefined}\n focusRef={field.ref}\n comboProps={comboProps}\n />\n )}\n />\n );\n}\n\ntype OwnInlineEntityComboboxProps<V extends string | number> = Omit<\n InlineEntityComboboxProps<V, ComboClearValue>,\n | \"value\"\n | \"defaultValue\"\n | \"onChange\"\n | \"onBlur\"\n | \"label\"\n | \"hint\"\n | \"error\"\n | \"invalid\"\n | \"disabled\"\n | \"className\"\n | \"id\"\n | \"ref\"\n | \"clearValue\"\n>;\n\nexport type RhfInlineEntityComboboxProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n V extends string | number = string | number,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n OwnInlineEntityComboboxProps<V> & {\n /** What a clear stores — emptying the text, or the \"×\" with `clearable`. Default\n * `null`; `\"\"` for a schema that spells \"no choice\" as an empty string. The\n * picker reads either back as empty. */\n clearValue?: ComboClearValue;\n /** Classes for the picker — `className` is the item's box. As {@link RhfCombobox}'s. */\n comboClassName?: string;\n };\n\n/**\n * {@link InlineEntityCombobox} bound to one field, which stores the chosen option's\n * `value` (an id), or `clearValue` once the text is emptied or the \"×\" pressed.\n *\n * kastlan asked for it (0.24): its account picker IS an `InlineEntityCombobox` — the\n * account number is typed straight into the field — and the budget line-item form\n * wired it through {@link RhfField}'s render. The picker took no `ref`, so react-hook-\n * form's focus-on-error had nothing to focus: a line item saved without an account\n * failed its submit and left the caret where it was, the one field on the form a\n * failed submit could not take you to. (The same gap {@link RhfCountrySelect} closed\n * for the address form's country in 0.23.)\n *\n * Bound the way {@link RhfCountrySelect} is: `field.ref` reaches the `<input>` (the\n * picker's `ref`, 0.24), the form's error paints the input and is the shell's message\n * under it, and the hint is the shell's description — so neither is ever handed to the\n * picker, and its box never changes when one comes or goes. The form's label names\n * the input through `<label for>` and titles the phone sheet (`sheetTitle`); the picker\n * draws no floating label of its own. Focus leaving the picker marks the field\n * touched.\n *\n * Everything else is the picker's and passes through: `commit` and `disabledReason`\n * (a picker whose choice saves stays focusable under a lock and says why), `clearable`,\n * `autoFocus`, `aria-label` for an unlabelled cell, and the create row — `onCreate`,\n * `createLabel`, `createEmptyLabel`, `createCommit`. Making the record is the\n * caller's, and so is storing its id once it exists:\n *\n * ```tsx\n * <RhfInlineEntityCombobox<LineItem, \"account_id\", number>\n * name=\"account_id\" label=\"Account\" required options={accounts}\n * rules={{ required: \"Choose an account\" }}\n * onCreate={async (name) => form.setValue(\"account_id\", (await createAccount(name)).id)} />\n * ```\n *\n * For the button-shaped picker with an async `loadOptions`, see {@link RhfCombobox}.\n */\nexport function RhfInlineEntityCombobox<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n V extends string | number = string | number,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n clearValue = null,\n comboClassName,\n ...comboProps\n}: RhfInlineEntityComboboxProps<TFieldValues, TName, V, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n render={({ field, invalid }) => {\n const value: unknown = field.value;\n return (\n // FormControl clones this element with `id` / `aria-describedby` /\n // `aria-invalid`, which the picker routes to its <input>.\n <InlineEntityCombobox<V, ComboClearValue>\n aria-required={required || undefined}\n // The form's label is the phone sheet's heading — the picker is not handed\n // `label`, which the FormLabel above already draws. A caller's own wins.\n sheetTitle={hasContent(label) ? label : undefined}\n {...comboProps}\n className={comboClassName}\n ref={field.ref}\n value={(value ?? null) as V | ComboClearValue | null}\n clearValue={clearValue}\n onChange={(v) => field.onChange(v)}\n // The wrapper's blur, which the <input>'s bubbles to after the picker has\n // judged any loose text — so the value is in before the field is touched.\n onBlur={field.onBlur}\n disabled={field.disabled}\n invalid={invalid}\n />\n );\n }}\n />\n );\n}\n\nexport type RhfTextComboboxProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n> = RhfFieldBaseProps<TFieldValues, TName, TTransformed> &\n // The combobox's own, as an `Omit` since 0.34 (DUP-9) rather than the `Pick` list it\n // was, less what the form binds.\n Omit<ComboboxProps, BoundByForm | \"id\"> & {\n /** Classes for the combobox. */\n comboClassName?: string;\n };\n\n/**\n * The kit's free-text {@link Combobox}: type anything, or pick one of `options`.\n * Stores the string.\n */\nexport function RhfTextCombobox<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n TTransformed = TFieldValues,\n>({\n name,\n control,\n rules,\n label,\n hint,\n help,\n required,\n disabled,\n excludeWhenDisabled,\n className,\n comboClassName,\n ...comboProps\n}: RhfTextComboboxProps<TFieldValues, TName, TTransformed>) {\n return (\n <RhfField\n {...{ name, control, rules, label, hint, help, required, disabled, excludeWhenDisabled, className }}\n asControl={false}\n message={false}\n render={({ field, invalid, error, id, describedBy }) => (\n <TextComboControl\n field={field as unknown as ControllerRenderProps}\n invalid={invalid}\n required={required}\n error={error}\n id={id}\n describedBy={describedBy}\n className={comboClassName}\n sheetTitle={hasContent(label) ? label : undefined}\n focusRef={field.ref}\n comboProps={comboProps}\n />\n )}\n />\n );\n}\n\nfunction TextComboControl({\n field,\n invalid,\n required,\n error,\n id,\n describedBy,\n className,\n sheetTitle,\n focusRef,\n comboProps,\n}: {\n field: ControllerRenderProps;\n invalid: boolean;\n required?: boolean;\n error: string | undefined;\n id: string;\n describedBy: string | undefined;\n className?: string;\n sheetTitle: ReactNode;\n /** `field.ref` — see EntityControl. */\n focusRef: ControllerRenderProps[\"ref\"];\n comboProps: Omit<RhfTextComboboxProps, keyof RhfFieldBaseProps | \"comboClassName\">;\n}) {\n // The combobox routes `id` and its ARIA to its <input>, so the label's `htmlFor`\n // names it and the hint describes it; `field.ref` reaches the <input> through the\n // combobox's own `ref` (0.24). The error is its own `error` prop, which it merges\n // in after the hint.\n const value: unknown = field.value;\n return (\n <Combobox\n // The form's label titles the phone sheet (see EntityControl).\n sheetTitle={sheetTitle}\n {...comboProps}\n ref={focusRef}\n id={id}\n aria-describedby={describedBy}\n aria-required={required || undefined}\n className={className}\n value={typeof value === \"string\" ? value : value == null ? \"\" : String(value)}\n onChange={field.onChange}\n onBlur={field.onBlur}\n disabled={field.disabled}\n invalid={invalid}\n error={error}\n />\n );\n}\n"],"mappings":"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","names":[]}
@@ -157,6 +157,30 @@ export interface AppShellProps extends ComponentPropsWithoutRef<"div"> {
157
157
  topBar: ReactNode;
158
158
  /** Main content — typically the router `<Outlet />`. */
159
159
  children: ReactNode;
160
+ /**
161
+ * What the content area shows while a page in `children` suspends — a lazy route's
162
+ * chunk on its way (0.55). Given, the shell wraps `children` in `<Suspense
163
+ * fallback={pageFallback}>` INSIDE `<main>`, so the top bar, the sidebar and the bottom
164
+ * bar are there at once and only the content area waits. keksdose's boundary sat ABOVE
165
+ * the shell until 2026-10-27, and every app load was one centred spinner where the whole
166
+ * app would be (its `PageSuspense`); kastlan (`lazyPage`) and Kurvenschmiede (routes'
167
+ * `Page`) each put one per route inside the `Outlet`. This is the one boundary, in one
168
+ * place, for all three.
169
+ *
170
+ * Which outline fits which route stays the app's: the fallback renders under the
171
+ * router, so it can read the path (keksdose's `PageSkeleton` draws the budget's tables
172
+ * for `/budget`), and it is the app's to hold back for a frame or two (keksdose waits
173
+ * 150 ms, so a chunk from the service worker's cache does not flash an outline).
174
+ * `PageHeaderSkeleton` over a `TableSkeleton` is the kit's pieces for one,
175
+ * `<LoadingState />` the plain one.
176
+ *
177
+ * Everything in `children` waits together, a banner above the `<Outlet />` included;
178
+ * a boundary of the app's own inside it still catches first, so a per-route one keeps
179
+ * working beside this. Left out, there is no boundary here and a suspending page goes on
180
+ * to the app's own, as before. `null` is a boundary that shows nothing. Set it for the
181
+ * shell's life: turning it on or off later mounts the page afresh.
182
+ */
183
+ pageFallback?: ReactNode;
160
184
  /** Desktop-only footer rendered below the content (hidden on mobile). */
161
185
  footer?: ReactNode;
162
186
  /** Extra sidebar content above the collapse toggle (e.g. a version link).
@@ -247,4 +271,4 @@ export interface AppShellProps extends ComponentPropsWithoutRef<"div"> {
247
271
  * `NavLink`; domain-free — nav items, brand, footer and the top bar's actions
248
272
  * are all supplied by the app.
249
273
  */
250
- export declare function AppShell({ nav, topBar, children, footer, sidebarFooter, sidebarFooterItems, renderLink, collapseStorageKey: collapseStorageKeyProp, collapseLabel, expandLabel, subNav, mobileSubNav, mobileSubNavLayout: mobileSubNavLayoutProp, mobileMaxItems, moreLabels, toggleGroupLabel, embedded: embeddedProp, className, ref, ...rest }: AppShellProps): import("react").JSX.Element;
274
+ export declare function AppShell({ nav, topBar, children, pageFallback, footer, sidebarFooter, sidebarFooterItems, renderLink, collapseStorageKey: collapseStorageKeyProp, collapseLabel, expandLabel, subNav, mobileSubNav, mobileSubNavLayout: mobileSubNavLayoutProp, mobileMaxItems, moreLabels, toggleGroupLabel, embedded: embeddedProp, className, ref, ...rest }: AppShellProps): import("react").JSX.Element;
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import {
4
+ Suspense,
4
5
  createContext,
5
6
  useCallback,
6
7
  useContext,
@@ -111,6 +112,7 @@ function AppShell({
111
112
  nav,
112
113
  topBar,
113
114
  children,
115
+ pageFallback,
114
116
  footer,
115
117
  sidebarFooter,
116
118
  sidebarFooterItems,
@@ -260,7 +262,7 @@ function AppShell({
260
262
  // Embedded there is no document scroll to lean on below `md` either.
261
263
  embedded && "min-h-0 overflow-y-auto"
262
264
  ),
263
- children
265
+ children: pageFallback === void 0 ? children : /* @__PURE__ */ jsx(Suspense, { fallback: pageFallback, children })
264
266
  }
265
267
  ),
266
268
  footer