@eifi1/ui-kit 0.31.1 → 0.32.1

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 (565) hide show
  1. package/README.md +51 -28
  2. package/dist/account/delete-account-setting.d.ts +8 -3
  3. package/dist/admin/admin-action-confirm.d.ts +8 -3
  4. package/dist/admin/admin-action-log.d.ts +1 -1
  5. package/dist/admin/admin-action-log.js +4 -2
  6. package/dist/admin/admin-action-log.js.map +1 -1
  7. package/dist/admin/invitations-panel.d.ts +8 -3
  8. package/dist/admin/invitations-panel.js +29 -26
  9. package/dist/admin/invitations-panel.js.map +1 -1
  10. package/dist/admin/reviewer-scope-editor.d.ts +8 -3
  11. package/dist/admin/role-select.d.ts +10 -5
  12. package/dist/admin/transfer-ownership-dialog.d.ts +8 -3
  13. package/dist/admin/user-roster.d.ts +10 -5
  14. package/dist/admin/user-roster.js +8 -47
  15. package/dist/admin/user-roster.js.map +1 -1
  16. package/dist/auth/auth-errors.d.ts +43 -8
  17. package/dist/auth/auth-errors.js +24 -1
  18. package/dist/auth/auth-errors.js.map +1 -1
  19. package/dist/auth/register-form.d.ts +8 -3
  20. package/dist/billing/billing-banner.d.ts +184 -0
  21. package/dist/billing/billing-banner.js +98 -0
  22. package/dist/billing/billing-banner.js.map +1 -0
  23. package/dist/billing/billing-labels.d.ts +100 -0
  24. package/dist/billing/billing-labels.js +76 -0
  25. package/dist/billing/billing-labels.js.map +1 -0
  26. package/dist/billing/billing-lock.d.ts +158 -0
  27. package/dist/billing/billing-lock.js +17 -0
  28. package/dist/billing/billing-lock.js.map +1 -0
  29. package/dist/billing/billing-standing.d.ts +149 -0
  30. package/dist/billing/billing-standing.js +28 -0
  31. package/dist/billing/billing-standing.js.map +1 -0
  32. package/dist/billing/plan-card.d.ts +248 -0
  33. package/dist/billing/plan-card.js +248 -0
  34. package/dist/billing/plan-card.js.map +1 -0
  35. package/dist/billing/plan-limit-notice.d.ts +156 -0
  36. package/dist/billing/plan-limit-notice.js +76 -0
  37. package/dist/billing/plan-limit-notice.js.map +1 -0
  38. package/dist/billing/plan-limit.d.ts +34 -0
  39. package/dist/billing/plan-limit.js +20 -0
  40. package/dist/billing/plan-limit.js.map +1 -0
  41. package/dist/billing/plan-price.d.ts +61 -0
  42. package/dist/billing/plan-price.js +45 -0
  43. package/dist/billing/plan-price.js.map +1 -0
  44. package/dist/billing/subscription-actions.d.ts +133 -0
  45. package/dist/billing/subscription-actions.js +28 -0
  46. package/dist/billing/subscription-actions.js.map +1 -0
  47. package/dist/billing/subscription-status-chip.d.ts +149 -0
  48. package/dist/billing/subscription-status-chip.js +48 -0
  49. package/dist/billing/subscription-status-chip.js.map +1 -0
  50. package/dist/chart.d.ts +9 -3
  51. package/dist/chart.js.map +1 -1
  52. package/dist/components/account-chips.d.ts +16 -4
  53. package/dist/components/account-chips.js +21 -3
  54. package/dist/components/account-chips.js.map +1 -1
  55. package/dist/components/alert-banner.d.ts +6 -1
  56. package/dist/components/alert-banner.js +5 -4
  57. package/dist/components/alert-banner.js.map +1 -1
  58. package/dist/components/amount-input.d.ts +8 -3
  59. package/dist/components/amount-input.js +5 -5
  60. package/dist/components/amount-input.js.map +1 -1
  61. package/dist/components/appearance-labels.d.ts +38 -0
  62. package/dist/components/appearance-labels.js +19 -0
  63. package/dist/components/appearance-labels.js.map +1 -0
  64. package/dist/components/autocomplete.js +2 -2
  65. package/dist/components/autocomplete.js.map +1 -1
  66. package/dist/components/breadcrumbs.js +3 -2
  67. package/dist/components/breadcrumbs.js.map +1 -1
  68. package/dist/components/bulk-action-bar.d.ts +2 -2
  69. package/dist/components/bulk-action-bar.js +7 -12
  70. package/dist/components/bulk-action-bar.js.map +1 -1
  71. package/dist/components/button-group.d.ts +8 -3
  72. package/dist/components/button-group.js +7 -1
  73. package/dist/components/button-group.js.map +1 -1
  74. package/dist/components/calculator.d.ts +8 -3
  75. package/dist/components/calculator.js +4 -3
  76. package/dist/components/calculator.js.map +1 -1
  77. package/dist/components/calendar-heatmap.js +5 -5
  78. package/dist/components/calendar-heatmap.js.map +1 -1
  79. package/dist/components/chart-height.d.ts +23 -0
  80. package/dist/components/chart-height.js +15 -0
  81. package/dist/components/chart-height.js.map +1 -0
  82. package/dist/components/chart-zoom.js +6 -1
  83. package/dist/components/chart-zoom.js.map +1 -1
  84. package/dist/components/checkbox-group.js +2 -2
  85. package/dist/components/checkbox-group.js.map +1 -1
  86. package/dist/components/checkbox.d.ts +10 -0
  87. package/dist/components/checkbox.js +25 -10
  88. package/dist/components/checkbox.js.map +1 -1
  89. package/dist/components/chip.d.ts +19 -3
  90. package/dist/components/chip.js +54 -23
  91. package/dist/components/chip.js.map +1 -1
  92. package/dist/components/choice-card.d.ts +1 -1
  93. package/dist/components/choice-card.js +9 -8
  94. package/dist/components/choice-card.js.map +1 -1
  95. package/dist/components/column-mapper.js +1 -1
  96. package/dist/components/column-mapper.js.map +1 -1
  97. package/dist/components/combobox-core.js +8 -7
  98. package/dist/components/combobox-core.js.map +1 -1
  99. package/dist/components/combobox.js +8 -8
  100. package/dist/components/combobox.js.map +1 -1
  101. package/dist/components/confirm-dialog.d.ts +8 -3
  102. package/dist/components/copy-button.d.ts +10 -5
  103. package/dist/components/country-select.js +1 -1
  104. package/dist/components/country-select.js.map +1 -1
  105. package/dist/components/currency-select.js +3 -3
  106. package/dist/components/currency-select.js.map +1 -1
  107. package/dist/components/danger-confirm.d.ts +8 -3
  108. package/dist/components/data-table-cells.d.ts +1 -1
  109. package/dist/components/data-table-filter-popover.d.ts +1 -1
  110. package/dist/components/data-table-filter-popover.js +4 -1
  111. package/dist/components/data-table-filter-popover.js.map +1 -1
  112. package/dist/components/data-table-filters.d.ts +1 -1
  113. package/dist/components/data-table-labels.d.ts +1 -1
  114. package/dist/components/data-table-pagination.d.ts +3 -2
  115. package/dist/components/data-table-pagination.js +15 -6
  116. package/dist/components/data-table-pagination.js.map +1 -1
  117. package/dist/components/data-table.d.ts +1 -1
  118. package/dist/components/data-table.js +123 -52
  119. package/dist/components/data-table.js.map +1 -1
  120. package/dist/components/date-picker.d.ts +1 -1
  121. package/dist/components/date-picker.js +18 -6
  122. package/dist/components/date-picker.js.map +1 -1
  123. package/dist/components/description-list.js +2 -2
  124. package/dist/components/description-list.js.map +1 -1
  125. package/dist/components/dialog-frame.js +2 -1
  126. package/dist/components/dialog-frame.js.map +1 -1
  127. package/dist/components/disclosure.js +3 -2
  128. package/dist/components/disclosure.js.map +1 -1
  129. package/dist/components/dropdown.d.ts +1 -1
  130. package/dist/components/dropdown.js +7 -1
  131. package/dist/components/dropdown.js.map +1 -1
  132. package/dist/components/facing-pair.d.ts +19 -6
  133. package/dist/components/facing-pair.js +3 -2
  134. package/dist/components/facing-pair.js.map +1 -1
  135. package/dist/components/field-parts.d.ts +102 -6
  136. package/dist/components/field-parts.js +81 -6
  137. package/dist/components/field-parts.js.map +1 -1
  138. package/dist/components/field-sync.d.ts +4 -1
  139. package/dist/components/field-sync.js +12 -2
  140. package/dist/components/field-sync.js.map +1 -1
  141. package/dist/components/field.js +2 -2
  142. package/dist/components/field.js.map +1 -1
  143. package/dist/components/file-button.d.ts +8 -3
  144. package/dist/components/file-dropzone.d.ts +8 -3
  145. package/dist/components/floating-panel.js +7 -4
  146. package/dist/components/floating-panel.js.map +1 -1
  147. package/dist/components/focus-ring.d.ts +12 -0
  148. package/dist/components/focus-ring.js +8 -0
  149. package/dist/components/focus-ring.js.map +1 -0
  150. package/dist/components/form-actions.d.ts +8 -3
  151. package/dist/components/form-actions.js +33 -19
  152. package/dist/components/form-actions.js.map +1 -1
  153. package/dist/components/full-bleed-dialog.d.ts +11 -1
  154. package/dist/components/full-bleed-dialog.js +3 -1
  155. package/dist/components/full-bleed-dialog.js.map +1 -1
  156. package/dist/components/iban-input.d.ts +8 -3
  157. package/dist/components/image-grid.js +1 -1
  158. package/dist/components/image-grid.js.map +1 -1
  159. package/dist/components/inline-edit-field.js +10 -4
  160. package/dist/components/inline-edit-field.js.map +1 -1
  161. package/dist/components/language-select.d.ts +8 -3
  162. package/dist/components/legal-page.d.ts +26 -5
  163. package/dist/components/legal-page.js +3 -1
  164. package/dist/components/legal-page.js.map +1 -1
  165. package/dist/components/legal.d.ts +8 -3
  166. package/dist/components/legal.js +2 -1
  167. package/dist/components/legal.js.map +1 -1
  168. package/dist/components/lightbox.js +24 -2
  169. package/dist/components/lightbox.js.map +1 -1
  170. package/dist/components/line-items.js +2 -1
  171. package/dist/components/line-items.js.map +1 -1
  172. package/dist/components/list.d.ts +5 -0
  173. package/dist/components/list.js +13 -9
  174. package/dist/components/list.js.map +1 -1
  175. package/dist/components/measured-grid.d.ts +3 -1
  176. package/dist/components/measured-grid.js +38 -20
  177. package/dist/components/measured-grid.js.map +1 -1
  178. package/dist/components/menu-item.js +2 -1
  179. package/dist/components/menu-item.js.map +1 -1
  180. package/dist/components/mini-calendar.js +8 -4
  181. package/dist/components/mini-calendar.js.map +1 -1
  182. package/dist/components/money-field.d.ts +8 -3
  183. package/dist/components/month-picker.js +50 -39
  184. package/dist/components/month-picker.js.map +1 -1
  185. package/dist/components/nav-pills.js +1 -1
  186. package/dist/components/nav-pills.js.map +1 -1
  187. package/dist/components/number-field.d.ts +8 -3
  188. package/dist/components/number-input.d.ts +11 -4
  189. package/dist/components/number-input.js +8 -6
  190. package/dist/components/number-input.js.map +1 -1
  191. package/dist/components/numpad-sheet.d.ts +8 -3
  192. package/dist/components/numpad-sheet.js +2 -1
  193. package/dist/components/numpad-sheet.js.map +1 -1
  194. package/dist/components/one-time-code-input.js +2 -2
  195. package/dist/components/one-time-code-input.js.map +1 -1
  196. package/dist/components/page-contents.js +2 -2
  197. package/dist/components/page-contents.js.map +1 -1
  198. package/dist/components/phone-input.d.ts +8 -3
  199. package/dist/components/phone-input.js +4 -4
  200. package/dist/components/phone-input.js.map +1 -1
  201. package/dist/components/pie-chart.d.ts +8 -2
  202. package/dist/components/pie-chart.js +11 -7
  203. package/dist/components/pie-chart.js.map +1 -1
  204. package/dist/components/popover.d.ts +9 -1
  205. package/dist/components/popover.js +8 -4
  206. package/dist/components/popover.js.map +1 -1
  207. package/dist/components/row-actions.d.ts +100 -0
  208. package/dist/components/row-actions.js +231 -0
  209. package/dist/components/row-actions.js.map +1 -0
  210. package/dist/components/scroll-area.js +1 -1
  211. package/dist/components/scroll-area.js.map +1 -1
  212. package/dist/components/search-field.js +3 -2
  213. package/dist/components/search-field.js.map +1 -1
  214. package/dist/components/series-chart-budget.d.ts +30 -7
  215. package/dist/components/series-chart-budget.js +12 -4
  216. package/dist/components/series-chart-budget.js.map +1 -1
  217. package/dist/components/series-chart-ticks.d.ts +7 -1
  218. package/dist/components/series-chart-ticks.js +6 -0
  219. package/dist/components/series-chart-ticks.js.map +1 -1
  220. package/dist/components/series-chart.d.ts +58 -28
  221. package/dist/components/series-chart.js +42 -32
  222. package/dist/components/series-chart.js.map +1 -1
  223. package/dist/components/settings-fields.d.ts +57 -8
  224. package/dist/components/settings-fields.js +39 -1
  225. package/dist/components/settings-fields.js.map +1 -1
  226. package/dist/components/share-card.d.ts +11 -6
  227. package/dist/components/share-card.js +8 -2
  228. package/dist/components/share-card.js.map +1 -1
  229. package/dist/components/sign-chip.d.ts +4 -0
  230. package/dist/components/sign-chip.js +17 -4
  231. package/dist/components/sign-chip.js.map +1 -1
  232. package/dist/components/signature-pad.d.ts +3 -1
  233. package/dist/components/signature-pad.js +8 -5
  234. package/dist/components/signature-pad.js.map +1 -1
  235. package/dist/components/slider.js +7 -6
  236. package/dist/components/slider.js.map +1 -1
  237. package/dist/components/sparkline.d.ts +5 -1
  238. package/dist/components/sparkline.js +4 -2
  239. package/dist/components/sparkline.js.map +1 -1
  240. package/dist/components/stat-tile.d.ts +17 -1
  241. package/dist/components/stat-tile.js +48 -20
  242. package/dist/components/stat-tile.js.map +1 -1
  243. package/dist/components/status-dot.d.ts +4 -0
  244. package/dist/components/status-dot.js +9 -2
  245. package/dist/components/status-dot.js.map +1 -1
  246. package/dist/components/swipeable-row.js +10 -2
  247. package/dist/components/swipeable-row.js.map +1 -1
  248. package/dist/components/switch.d.ts +21 -7
  249. package/dist/components/switch.js +24 -11
  250. package/dist/components/switch.js.map +1 -1
  251. package/dist/components/table.js +2 -2
  252. package/dist/components/table.js.map +1 -1
  253. package/dist/components/text-link.d.ts +8 -3
  254. package/dist/components/text-link.js +1 -1
  255. package/dist/components/text-link.js.map +1 -1
  256. package/dist/components/text.d.ts +7 -2
  257. package/dist/components/text.js +5 -5
  258. package/dist/components/text.js.map +1 -1
  259. package/dist/components/tile-radio.js +2 -1
  260. package/dist/components/tile-radio.js.map +1 -1
  261. package/dist/components/time-input.d.ts +8 -3
  262. package/dist/components/toast.d.ts +18 -2
  263. package/dist/components/toast.js +8 -5
  264. package/dist/components/toast.js.map +1 -1
  265. package/dist/components/toggle-group.d.ts +25 -3
  266. package/dist/components/toggle-group.js +40 -11
  267. package/dist/components/toggle-group.js.map +1 -1
  268. package/dist/components/toggle-legend.d.ts +10 -1
  269. package/dist/components/toggle-legend.js +21 -7
  270. package/dist/components/toggle-legend.js.map +1 -1
  271. package/dist/components/translation-review-editor.js +1 -1
  272. package/dist/components/translation-review-editor.js.map +1 -1
  273. package/dist/components/translation-review-parts.d.ts +4 -0
  274. package/dist/components/translation-review.d.ts +4 -0
  275. package/dist/components/translation-review.js +3 -3
  276. package/dist/components/translation-review.js.map +1 -1
  277. package/dist/components/tree-view.js +3 -2
  278. package/dist/components/tree-view.js.map +1 -1
  279. package/dist/components/treemap.d.ts +5 -2
  280. package/dist/components/treemap.js +33 -16
  281. package/dist/components/treemap.js.map +1 -1
  282. package/dist/components/ui.d.ts +8 -3
  283. package/dist/components/ui.js +207 -119
  284. package/dist/components/ui.js.map +1 -1
  285. package/dist/components/use-table-state.d.ts +1 -1
  286. package/dist/components/user-avatar.d.ts +5 -1
  287. package/dist/components/user-avatar.js +1 -1
  288. package/dist/components/user-avatar.js.map +1 -1
  289. package/dist/components/wizard-stepper.js +20 -14
  290. package/dist/components/wizard-stepper.js.map +1 -1
  291. package/dist/{data-table-labels-DUELeXpa.d.ts → data-table-labels-kpAAVi6g.d.ts} +26 -2
  292. package/dist/data-table.d.ts +1 -1
  293. package/dist/{delete-account-setting-CpIhzxxZ.d.ts → delete-account-setting-FLyJf-kZ.d.ts} +642 -60
  294. package/dist/demo/demo-banner.js +1 -0
  295. package/dist/demo/demo-banner.js.map +1 -1
  296. package/dist/feedback/feedback-attachment.d.ts +8 -3
  297. package/dist/feedback/feedback-context.d.ts +8 -3
  298. package/dist/feedback/feedback-crash.d.ts +8 -3
  299. package/dist/feedback/feedback-dialog.d.ts +8 -3
  300. package/dist/feedback/feedback-dialog.js +3 -3
  301. package/dist/feedback/feedback-dialog.js.map +1 -1
  302. package/dist/feedback/feedback-inbox.d.ts +8 -3
  303. package/dist/feedback/feedback-inbox.js +2 -2
  304. package/dist/feedback/feedback-inbox.js.map +1 -1
  305. package/dist/feedback/feedback-labels.d.ts +8 -3
  306. package/dist/feedback/feedback-menu.d.ts +9 -4
  307. package/dist/feedback/feedback-record.d.ts +8 -3
  308. package/dist/feedback/feedback-row-detail.d.ts +8 -3
  309. package/dist/feedback/feedback-status-undo.d.ts +8 -3
  310. package/dist/feedback/feedback-submit.d.ts +8 -3
  311. package/dist/feedback/feedback-swipe.d.ts +8 -3
  312. package/dist/feedback/feedback-table.d.ts +8 -3
  313. package/dist/feedback/feedback-thread.d.ts +8 -3
  314. package/dist/feedback/feedback-thread.js +3 -3
  315. package/dist/feedback/feedback-thread.js.map +1 -1
  316. package/dist/feedback.d.ts +8 -3
  317. package/dist/hooks/use-anchored-panel.d.ts +32 -3
  318. package/dist/hooks/use-anchored-panel.js +21 -3
  319. package/dist/hooks/use-anchored-panel.js.map +1 -1
  320. package/dist/hooks/use-breakpoint.d.ts +88 -0
  321. package/dist/hooks/use-breakpoint.js +50 -0
  322. package/dist/hooks/use-breakpoint.js.map +1 -0
  323. package/dist/hooks/use-file-drop.d.ts +8 -3
  324. package/dist/hooks/use-large-text.d.ts +29 -0
  325. package/dist/hooks/use-large-text.js +20 -0
  326. package/dist/hooks/use-large-text.js.map +1 -0
  327. package/dist/hooks/use-windowed-rows.d.ts +52 -8
  328. package/dist/hooks/use-windowed-rows.js +94 -5
  329. package/dist/hooks/use-windowed-rows.js.map +1 -1
  330. package/dist/i18n/defaults.d.ts +8 -3
  331. package/dist/i18n/defaults.js +8 -0
  332. package/dist/i18n/defaults.js.map +1 -1
  333. package/dist/i18n/german.d.ts +8 -3
  334. package/dist/i18n/german.js +94 -3
  335. package/dist/i18n/german.js.map +1 -1
  336. package/dist/i18n/kit-labels.d.ts +8 -3
  337. package/dist/i18n/kit-labels.js.map +1 -1
  338. package/dist/i18n/languages.d.ts +10 -5
  339. package/dist/i18n/locales/de-CH.d.ts +8 -3
  340. package/dist/i18n/locales/en.d.ts +8 -3
  341. package/dist/i18n/locales/es.d.ts +8 -3
  342. package/dist/i18n/locales/es.js +89 -3
  343. package/dist/i18n/locales/es.js.map +1 -1
  344. package/dist/i18n/locales/fr.d.ts +8 -3
  345. package/dist/i18n/locales/fr.js +91 -3
  346. package/dist/i18n/locales/fr.js.map +1 -1
  347. package/dist/i18n/locales/hu.d.ts +8 -3
  348. package/dist/i18n/locales/hu.js +91 -3
  349. package/dist/i18n/locales/hu.js.map +1 -1
  350. package/dist/i18n/locales/it.d.ts +8 -3
  351. package/dist/i18n/locales/it.js +92 -3
  352. package/dist/i18n/locales/it.js.map +1 -1
  353. package/dist/i18n/locales/zh.d.ts +8 -3
  354. package/dist/i18n/locales/zh.js +89 -3
  355. package/dist/i18n/locales/zh.js.map +1 -1
  356. package/dist/i18n/review.d.ts +8 -3
  357. package/dist/i18n/review.js +15 -1
  358. package/dist/i18n/review.js.map +1 -1
  359. package/dist/index.d.ts +27 -11
  360. package/dist/index.js +77 -4
  361. package/dist/index.js.map +1 -1
  362. package/dist/landing/landing-actions.d.ts +8 -3
  363. package/dist/landing/landing-sections.d.ts +8 -3
  364. package/dist/landing/landing-sections.js +7 -3
  365. package/dist/landing/landing-sections.js.map +1 -1
  366. package/dist/landing/public-header.d.ts +9 -4
  367. package/dist/landing/public-header.js +3 -3
  368. package/dist/landing/public-header.js.map +1 -1
  369. package/dist/landing/routing.d.ts +8 -3
  370. package/dist/lib/cn.js +3 -2
  371. package/dist/lib/cn.js.map +1 -1
  372. package/dist/rhf/fields.d.ts +8 -3
  373. package/dist/rhf/fields.js +1 -1
  374. package/dist/rhf/fields.js.map +1 -1
  375. package/dist/rhf/form.d.ts +8 -3
  376. package/dist/rhf/form.js +2 -2
  377. package/dist/rhf/form.js.map +1 -1
  378. package/dist/rhf.d.ts +8 -3
  379. package/dist/search/command-palette.d.ts +1 -1
  380. package/dist/search/command-palette.js +9 -8
  381. package/dist/search/command-palette.js.map +1 -1
  382. package/dist/settings/settings-layout.js +2 -1
  383. package/dist/settings/settings-layout.js.map +1 -1
  384. package/dist/settings/settings-section.d.ts +8 -3
  385. package/dist/settings/use-account-appearance.d.ts +92 -0
  386. package/dist/settings/use-account-appearance.js +63 -0
  387. package/dist/settings/use-account-appearance.js.map +1 -0
  388. package/dist/settings/use-settings-route.d.ts +1 -1
  389. package/dist/settings/use-settings-route.js +2 -3
  390. package/dist/settings/use-settings-route.js.map +1 -1
  391. package/dist/shell/app-shell.d.ts +12 -171
  392. package/dist/shell/app-shell.js +144 -28
  393. package/dist/shell/app-shell.js.map +1 -1
  394. package/dist/shell/auth-layout.js +1 -1
  395. package/dist/shell/auth-layout.js.map +1 -1
  396. package/dist/shell/option-switcher-menu.js +1 -1
  397. package/dist/shell/option-switcher-menu.js.map +1 -1
  398. package/dist/shell/top-bar-brand.d.ts +8 -3
  399. package/dist/shell/top-bar-brand.js +3 -1
  400. package/dist/shell/top-bar-brand.js.map +1 -1
  401. package/dist/shell/topbar-action-menu.d.ts +4 -0
  402. package/dist/shell/topbar-action-menu.js +3 -3
  403. package/dist/shell/topbar-action-menu.js.map +1 -1
  404. package/dist/shell/topbar-controls.js +4 -4
  405. package/dist/shell/topbar-controls.js.map +1 -1
  406. package/dist/shell.d.ts +9 -5
  407. package/dist/theme/contrast-tokens.d.ts +41 -0
  408. package/dist/theme/contrast-tokens.js +59 -0
  409. package/dist/theme/contrast-tokens.js.map +1 -0
  410. package/dist/theme/contrast.d.ts +110 -0
  411. package/dist/theme/contrast.js +128 -0
  412. package/dist/theme/contrast.js.map +1 -0
  413. package/dist/theme/palette-presets.d.ts +12 -1
  414. package/dist/theme/palette-presets.js +9 -4
  415. package/dist/theme/palette-presets.js.map +1 -1
  416. package/dist/theme/palette-store.js.map +1 -1
  417. package/dist/theme/text-size.d.ts +173 -0
  418. package/dist/theme/text-size.js +121 -0
  419. package/dist/theme/text-size.js.map +1 -0
  420. package/dist/wizard/stepper-nav.d.ts +8 -3
  421. package/dist/wizard/wizard-summary.js +1 -1
  422. package/dist/wizard/wizard-summary.js.map +1 -1
  423. package/dist/wizard.d.ts +8 -3
  424. package/package.json +1 -1
  425. package/src/admin/admin-action-log.tsx +6 -1
  426. package/src/admin/invitations-panel.tsx +36 -29
  427. package/src/admin/user-roster.tsx +17 -72
  428. package/src/auth/auth-errors.ts +68 -7
  429. package/src/billing/billing-banner.tsx +205 -0
  430. package/src/billing/billing-labels.ts +240 -0
  431. package/src/billing/billing-lock.ts +75 -0
  432. package/src/billing/billing-standing.ts +72 -0
  433. package/src/billing/plan-card.tsx +458 -0
  434. package/src/billing/plan-limit-notice.tsx +145 -0
  435. package/src/billing/plan-limit.ts +53 -0
  436. package/src/billing/plan-price.ts +101 -0
  437. package/src/billing/subscription-actions.tsx +76 -0
  438. package/src/billing/subscription-status-chip.tsx +95 -0
  439. package/src/chart.ts +2 -0
  440. package/src/components/account-chips.tsx +36 -10
  441. package/src/components/alert-banner.tsx +16 -7
  442. package/src/components/amount-input.tsx +5 -5
  443. package/src/components/appearance-labels.ts +47 -0
  444. package/src/components/autocomplete.tsx +2 -2
  445. package/src/components/breadcrumbs.tsx +3 -3
  446. package/src/components/bulk-action-bar.tsx +11 -14
  447. package/src/components/button-group.tsx +21 -0
  448. package/src/components/calculator.tsx +4 -3
  449. package/src/components/calendar-heatmap.tsx +5 -5
  450. package/src/components/chart-height.ts +30 -0
  451. package/src/components/chart-zoom.tsx +6 -1
  452. package/src/components/checkbox-group.tsx +2 -2
  453. package/src/components/checkbox.tsx +62 -20
  454. package/src/components/chip.tsx +139 -30
  455. package/src/components/choice-card.tsx +16 -11
  456. package/src/components/column-mapper.tsx +1 -1
  457. package/src/components/combobox-core.tsx +8 -7
  458. package/src/components/combobox.tsx +8 -8
  459. package/src/components/country-select.tsx +1 -1
  460. package/src/components/currency-select.tsx +3 -3
  461. package/src/components/data-table-filter-popover.tsx +7 -1
  462. package/src/components/data-table-pagination.tsx +60 -31
  463. package/src/components/data-table.tsx +164 -43
  464. package/src/components/date-picker.tsx +44 -10
  465. package/src/components/description-list.tsx +2 -2
  466. package/src/components/dialog-frame.tsx +2 -1
  467. package/src/components/disclosure.tsx +3 -2
  468. package/src/components/dropdown.tsx +10 -2
  469. package/src/components/facing-pair.ts +12 -5
  470. package/src/components/field-parts.tsx +190 -7
  471. package/src/components/field-sync.tsx +17 -3
  472. package/src/components/field.tsx +2 -2
  473. package/src/components/floating-panel.tsx +7 -4
  474. package/src/components/focus-ring.ts +12 -0
  475. package/src/components/form-actions.tsx +55 -18
  476. package/src/components/full-bleed-dialog.tsx +18 -4
  477. package/src/components/image-grid.tsx +1 -1
  478. package/src/components/inline-edit-field.tsx +26 -4
  479. package/src/components/legal-page.tsx +28 -2
  480. package/src/components/legal.tsx +19 -1
  481. package/src/components/lightbox.tsx +24 -2
  482. package/src/components/line-items.tsx +7 -1
  483. package/src/components/list.tsx +36 -10
  484. package/src/components/measured-grid.tsx +49 -24
  485. package/src/components/menu-item.tsx +2 -2
  486. package/src/components/mini-calendar.tsx +8 -4
  487. package/src/components/month-picker.tsx +15 -6
  488. package/src/components/nav-pills.tsx +1 -1
  489. package/src/components/number-input.tsx +14 -7
  490. package/src/components/numpad-sheet.tsx +2 -2
  491. package/src/components/one-time-code-input.tsx +2 -2
  492. package/src/components/page-contents.tsx +2 -2
  493. package/src/components/phone-input.tsx +9 -4
  494. package/src/components/pie-chart.tsx +19 -9
  495. package/src/components/popover.tsx +22 -5
  496. package/src/components/row-actions.tsx +450 -0
  497. package/src/components/scroll-area.tsx +1 -1
  498. package/src/components/search-field.tsx +4 -2
  499. package/src/components/series-chart-budget.ts +40 -8
  500. package/src/components/series-chart-ticks.ts +10 -0
  501. package/src/components/series-chart.tsx +123 -72
  502. package/src/components/settings-fields.tsx +89 -5
  503. package/src/components/share-card.tsx +31 -2
  504. package/src/components/sign-chip.tsx +28 -4
  505. package/src/components/signature-pad.tsx +13 -7
  506. package/src/components/slider.tsx +22 -9
  507. package/src/components/sparkline.tsx +11 -3
  508. package/src/components/stat-tile.tsx +70 -14
  509. package/src/components/status-dot.tsx +25 -2
  510. package/src/components/swipeable-row.tsx +10 -2
  511. package/src/components/switch.tsx +57 -23
  512. package/src/components/table.tsx +2 -2
  513. package/src/components/text-link.tsx +1 -1
  514. package/src/components/text.tsx +11 -6
  515. package/src/components/tile-radio.tsx +4 -1
  516. package/src/components/toast.tsx +27 -7
  517. package/src/components/toggle-group.tsx +115 -14
  518. package/src/components/toggle-legend.tsx +53 -8
  519. package/src/components/translation-review-editor.tsx +1 -1
  520. package/src/components/translation-review.tsx +11 -5
  521. package/src/components/tree-view.tsx +3 -2
  522. package/src/components/treemap.tsx +27 -10
  523. package/src/components/ui.tsx +353 -153
  524. package/src/components/user-avatar.tsx +1 -1
  525. package/src/components/wizard-stepper.tsx +5 -1
  526. package/src/demo/demo-banner.tsx +5 -0
  527. package/src/feedback/feedback-dialog.tsx +3 -3
  528. package/src/feedback/feedback-inbox.tsx +2 -2
  529. package/src/feedback/feedback-thread.tsx +3 -3
  530. package/src/hooks/use-anchored-panel.ts +67 -5
  531. package/src/hooks/use-breakpoint.ts +132 -0
  532. package/src/hooks/use-large-text.ts +41 -0
  533. package/src/hooks/use-windowed-rows.ts +168 -12
  534. package/src/i18n/defaults.ts +8 -0
  535. package/src/i18n/german.ts +107 -0
  536. package/src/i18n/kit-labels.tsx +12 -0
  537. package/src/i18n/locales/es.ts +98 -0
  538. package/src/i18n/locales/fr.ts +102 -0
  539. package/src/i18n/locales/hu.ts +100 -0
  540. package/src/i18n/locales/it.ts +103 -0
  541. package/src/i18n/locales/zh.ts +94 -0
  542. package/src/i18n/review.ts +14 -0
  543. package/src/index.ts +76 -6
  544. package/src/landing/landing-sections.tsx +7 -3
  545. package/src/landing/public-header.tsx +4 -4
  546. package/src/lib/cn.ts +13 -2
  547. package/src/rhf/fields.tsx +1 -1
  548. package/src/rhf/form.tsx +2 -2
  549. package/src/search/command-palette.tsx +10 -9
  550. package/src/settings/settings-layout.tsx +2 -1
  551. package/src/settings/use-account-appearance.ts +148 -0
  552. package/src/settings/use-settings-route.ts +3 -4
  553. package/src/shell/app-shell.tsx +278 -54
  554. package/src/shell/auth-layout.tsx +1 -1
  555. package/src/shell/option-switcher-menu.tsx +1 -1
  556. package/src/shell/top-bar-brand.tsx +3 -1
  557. package/src/shell/topbar-action-menu.tsx +3 -3
  558. package/src/shell/topbar-controls.tsx +4 -4
  559. package/src/theme/contrast-tokens.ts +112 -0
  560. package/src/theme/contrast.ts +225 -0
  561. package/src/theme/palette-presets.ts +24 -4
  562. package/src/theme/palette-store.ts +6 -1
  563. package/src/theme/text-size.ts +283 -0
  564. package/src/wizard/wizard-summary.tsx +4 -2
  565. package/tokens.css +158 -8
@@ -0,0 +1,450 @@
1
+ import { isValidElement } from "react";
2
+ import type { KeyboardEvent, MouseEvent, ReactElement, ReactNode } from "react";
3
+ import { MoreHorizontal } from "lucide-react";
4
+ import type { LucideIcon } from "lucide-react";
5
+ import { cn } from "../lib/cn";
6
+ import { useLargeText } from "../hooks/use-large-text";
7
+ import { useKitLabels } from "../i18n/kit-labels";
8
+ import { Popover } from "./popover";
9
+ import { Button, CompactControls, IconButton } from "./ui";
10
+ import { useCommitReason } from "./write-lock";
11
+ import type { IconButtonSize } from "./ui";
12
+ import type { DataTableColumn } from "./data-table";
13
+
14
+ /**
15
+ * A row's actions — inline icons at Normal, one "⋯" menu at Large and above
16
+ * (docs/text-size-harmonization.md §10.8).
17
+ *
18
+ * At Large an IconButton shows its label as text (§4). In a dense row — a register's
19
+ * action column, a list row's end — every label at once does not fit: Kurvenschmiede
20
+ * has 44 IconButtons in rows, kastlan 119. So a row's actions collapse instead, into
21
+ * the menu the user roster has used since 0.31 (`UserRowActions`, now built on this):
22
+ * one "⋯" button, and a menu with each action's icon AND words, where a locked one stays
23
+ * listed and says why.
24
+ *
25
+ * The data is the roster's `UserRowActionList`, generalised: entries, and `false` /
26
+ * `null` for the ones a condition left out (`row.locked || {…}`).
27
+ */
28
+
29
+ /** One action of a row. */
30
+ export interface RowAction {
31
+ /** React key. Default: the label. */
32
+ key?: string;
33
+ /** The action's name: the inline icon's name and tooltip, the menu entry's words. */
34
+ label: string;
35
+ /**
36
+ * Runs it. The kit sends nothing — the app opens its confirmation or calls its API.
37
+ * Optional only beside `href`; an action has one or the other (or both: `onSelect`
38
+ * then runs as the link is followed).
39
+ */
40
+ onSelect?: () => void;
41
+ /**
42
+ * The action NAVIGATES — an edit page, a mail to compose (0.32.1, kastlan's 0.32
43
+ * report): a real link inline and in the menu, so open in a new tab, a middle click
44
+ * and the URL on hover work, which `onSelect` + `navigate` lost. The kit's link rule
45
+ * applies ({@link Button}'s `href`): in-app through the provider's `linkComponent`, an
46
+ * external or `#anchor` one a plain `<a>`, `mailto:` included.
47
+ *
48
+ * A link cannot carry a reason or a spinner, so an action with a `disabledReason`
49
+ * (or under a write lock, with `commit`) or `pending` stays a button and says why.
50
+ */
51
+ href?: string;
52
+ /** With `href`: leaves the app — a new tab, and a screen reader is told so. */
53
+ external?: boolean;
54
+ /**
55
+ * The glyph: a Lucide icon (`Pencil`), or an element (`<Pencil />`, an app's own
56
+ * svg) — DataTable's `rowActions` hand their `icon` node through. Inline, an action
57
+ * without one is a small text button; in the menu it is the words alone.
58
+ */
59
+ icon?: LucideIcon | ReactElement;
60
+ /** `danger` for delete, revoke, erase: the quiet red of IconButton's `tone="danger"`
61
+ * inline, the danger text tone in the menu. */
62
+ tone?: "default" | "danger";
63
+ /** Why it is not available for this row. It stays listed, focusable, and says so — an
64
+ * action that silently vanished would leave the reader looking for it. */
65
+ disabledReason?: ReactNode;
66
+ /**
67
+ * This action COMMITS — it saves, sends, deletes: under a locked
68
+ * {@link WriteLockProvider} it is refused with the lock's reason, as {@link Button}'s
69
+ * `commit` is, inline and in the menu alike. No provider, or an unlocked one: no effect.
70
+ */
71
+ commit?: boolean;
72
+ /**
73
+ * In flight — the request it started has not answered. Inline, the icon turns into
74
+ * IconButton's spinner (`pending`); collapsed, the "⋯" button does, since the menu
75
+ * closed when the action was chosen. Either way nothing in the row can be pressed again
76
+ * until it settles: the "⋯" opens no menu while busy.
77
+ */
78
+ pending?: boolean;
79
+ /**
80
+ * Not available for a moment, with nothing to explain — another action of the list
81
+ * is in flight (an admin panel's `busy`). The plain `disabled`; a lasting refusal is a
82
+ * `disabledReason`, which says why.
83
+ */
84
+ disabled?: boolean;
85
+ /** Leave it out for this row. */
86
+ hidden?: boolean;
87
+ }
88
+
89
+ /** What a row's actions may be: entries, and `false` / `null` / `undefined` for the ones
90
+ * a condition left out. */
91
+ export type RowActionList = readonly (RowAction | false | null | undefined)[];
92
+
93
+ export interface RowActionsLabels {
94
+ /** The menu button's name when the row has no name of its own; also the actions
95
+ * column's (hidden) header in {@link rowActionsColumn}. */
96
+ actions: string;
97
+ /** The menu button's name, given the row's: "Actions for Ada Example". */
98
+ actionsFor: (name: string) => string;
99
+ }
100
+
101
+ export const DEFAULT_ROW_ACTIONS_LABELS: RowActionsLabels = {
102
+ actions: "Actions",
103
+ actionsFor: (name) => `Actions for ${name}`,
104
+ };
105
+
106
+ /**
107
+ * - `"auto"` (default): the icons inline at Normal; the "⋯" menu at Large and Extra
108
+ * large once there are two or more (§10.8). A single action stays inline at every
109
+ * size, with its label as text at Large — one label fits a row, and a menu of one is
110
+ * a detour.
111
+ * - `"menu"`: the menu at every size — the roster's choice, whose actions grow (§2.4
112
+ * there) and do not fit a phone card as a strip.
113
+ * - `"inline"`: the icons at every size — for a row the app knows has room; at Large
114
+ * each then shows its label (IconButton's `labelVisible`).
115
+ */
116
+ export type RowActionsCollapse = "auto" | "menu" | "inline";
117
+
118
+ /** The sizes a row action comes in: IconButton's row steps. `2xs` is DataTable's
119
+ * compact density. At Large every one is at least a 48 px target (IconButton). */
120
+ export type RowActionsSize = Extract<IconButtonSize, "md" | "sm" | "xs" | "2xs">;
121
+
122
+ export interface RowActionsProps {
123
+ actions: RowActionList;
124
+ /** The row's name, for the menu button's name — "Actions for Ada Example". Without it
125
+ * (or `null`, as API fields often are) the button is "Actions". */
126
+ name?: string | null;
127
+ /** When the actions collapse into the menu — see {@link RowActionsCollapse}. */
128
+ collapse?: RowActionsCollapse;
129
+ /** The inline icons' and the "⋯" button's size. Default `xs`, a list row's action. */
130
+ size?: RowActionsSize;
131
+ /** The menu's width. Default `"15rem"`, in rem so it grows with the words (§3.2). */
132
+ menuWidth?: `${number}rem`;
133
+ /** On the wrapper: the inline strip, or the "⋯" button's box. */
134
+ className?: string;
135
+ labels?: Partial<RowActionsLabels>;
136
+ }
137
+
138
+ function visibleActions(actions: RowActionList): RowAction[] {
139
+ return actions.filter((a): a is RowAction => Boolean(a) && !(a as RowAction).hidden);
140
+ }
141
+
142
+ /** An action's glyph as a node: a component is rendered, an element is used as is. */
143
+ function glyphOf(icon: RowAction["icon"]): ReactNode {
144
+ if (icon === undefined) return null;
145
+ if (isValidElement(icon)) return icon;
146
+ const Icon = icon as LucideIcon;
147
+ return <Icon />;
148
+ }
149
+
150
+ /**
151
+ * A row's actions, inline or as a "⋯" menu — see {@link RowActionsCollapse}. Every
152
+ * control stops its click (and the Enter/Space it stands for) from reaching the row, so
153
+ * a clickable row or a DataTable `rowLink` does not open as well; in a DataTable column
154
+ * also set `noRowLink: true`, as {@link rowActionsColumn} does.
155
+ *
156
+ * Inline, the icons sit in a {@link CompactControls} region at Normal: their labels
157
+ * stay the names and the tooltips, and a locked one keeps its reason in the tooltip — a
158
+ * line under one icon of a row would break the row. In the menu a locked action's
159
+ * reason is a line under its words at Large and on touch (Button's
160
+ * `disabledReasonDisplay`).
161
+ *
162
+ * The menu is portalled, so a table's scroller cannot clip it; Escape and an outside
163
+ * press close it, and focus goes back to the "⋯" button, which is where a confirmation
164
+ * dialog then returns it.
165
+ */
166
+ export function RowActions({
167
+ actions,
168
+ name,
169
+ collapse = "auto",
170
+ size = "xs",
171
+ menuWidth = "15rem",
172
+ className,
173
+ labels: labelsProp,
174
+ }: RowActionsProps) {
175
+ const labels = useKitLabels("rowActions", DEFAULT_ROW_ACTIONS_LABELS, labelsProp);
176
+ const large = useLargeText();
177
+ const entries = visibleActions(actions);
178
+ if (entries.length === 0) return null;
179
+ const asMenu = collapse === "menu" || (collapse === "auto" && large && entries.length > 1);
180
+ if (!asMenu) {
181
+ const strip = (
182
+ <div data-slot="row-actions" className={cn("inline-flex items-center gap-0.5", className)}>
183
+ {entries.map((action) => (
184
+ <InlineAction key={action.key ?? action.label} action={action} size={size} />
185
+ ))}
186
+ </div>
187
+ );
188
+ // Compact at Normal (no room for a reason line in a row); at Large an inline action
189
+ // is the app's choice ("inline") or the row's only one, and shows its words.
190
+ return large ? strip : <CompactControls>{strip}</CompactControls>;
191
+ }
192
+ const title = name ? labels.actionsFor(name) : labels.actions;
193
+ // The menu closed when the action was chosen, so what is in flight shows on "⋯".
194
+ const busy = entries.some((action) => action.pending);
195
+ return (
196
+ <Popover
197
+ width={menuWidth}
198
+ aria-label={title}
199
+ className="p-1"
200
+ trigger={({ open, toggle, ref }) => (
201
+ <IconButton
202
+ ref={ref}
203
+ size={size}
204
+ label={title}
205
+ // "⋯" is read by everyone as "more actions"; the menu it opens is the words.
206
+ labelVisible={false}
207
+ aria-haspopup="dialog"
208
+ aria-expanded={open}
209
+ pending={busy}
210
+ stopPropagation
211
+ onClick={toggle}
212
+ className={className}
213
+ >
214
+ <MoreHorizontal />
215
+ </IconButton>
216
+ )}
217
+ >
218
+ {(close) => (
219
+ // React carries an event out of a portal along the COMPONENT tree, so a click on
220
+ // an entry (or between two) reached a clickable row or a DataTable `onRowClick`
221
+ // the menu was opened from, though the panel is nowhere near it in the page —
222
+ // only the "⋯" trigger stopped its own (0.32.1, keksdose's 0.32 report). Stopped
223
+ // here for the whole panel: clicks, and the Enter / Space a row also listens for.
224
+ // Escape goes on, to the popover that closes on it.
225
+ <div role="presentation" onClick={stopClick} onKeyDown={stopActivationKeys}>
226
+ <ul data-slot="row-actions-menu" className="space-y-0.5">
227
+ {entries.map((action) => (
228
+ <li key={action.key ?? action.label}>
229
+ <MenuAction action={action} close={close} />
230
+ </li>
231
+ ))}
232
+ </ul>
233
+ </div>
234
+ )}
235
+ </Popover>
236
+ );
237
+ }
238
+
239
+ function stopClick(e: MouseEvent) {
240
+ e.stopPropagation();
241
+ }
242
+
243
+ function stopActivationKeys(e: KeyboardEvent) {
244
+ if (e.key === "Enter" || e.key === " ") e.stopPropagation();
245
+ }
246
+
247
+ /**
248
+ * The `href` an action renders as a link with, or `undefined` for a button: a link
249
+ * cannot carry a reason or a spinner (Button's link form has neither), so a refused
250
+ * action — its own `disabledReason`, or a write lock on a `commit` — and a pending one
251
+ * stay buttons and say so.
252
+ */
253
+ function useActionHref(action: RowAction): string | undefined {
254
+ const reason = useCommitReason(action.commit, action.disabledReason);
255
+ const refused = reason !== undefined && reason !== null && reason !== false && reason !== "";
256
+ return action.href !== undefined && !action.pending && !refused ? action.href : undefined;
257
+ }
258
+
259
+ /** One entry of the "⋯" menu: the words, as a link for an `href`, else a button. */
260
+ function MenuAction({ action, close }: { action: RowAction; close: () => void }) {
261
+ const href = useActionHref(action);
262
+ const glyph = glyphOf(action.icon);
263
+ const words = (
264
+ <>
265
+ {glyph && (
266
+ <span aria-hidden className="flex shrink-0 [&_svg]:size-4">
267
+ {glyph}
268
+ </span>
269
+ )}
270
+ {action.label}
271
+ </>
272
+ );
273
+ const tone = action.tone === "danger" ? "danger" : undefined;
274
+ const select = () => {
275
+ close();
276
+ action.onSelect?.();
277
+ };
278
+ if (href !== undefined) {
279
+ return (
280
+ <Button
281
+ href={href}
282
+ external={action.external}
283
+ variant="ghost"
284
+ size="sm"
285
+ stretch
286
+ tone={tone}
287
+ disabled={action.disabled}
288
+ className="w-full justify-start text-start"
289
+ onClick={select}
290
+ >
291
+ {words}
292
+ </Button>
293
+ );
294
+ }
295
+ return (
296
+ <Button
297
+ type="button"
298
+ variant="ghost"
299
+ size="sm"
300
+ stretch
301
+ tone={tone}
302
+ disabledReason={action.disabledReason}
303
+ commit={action.commit}
304
+ pending={action.pending}
305
+ disabled={action.disabled}
306
+ className="w-full justify-start text-start"
307
+ onClick={select}
308
+ >
309
+ {words}
310
+ </Button>
311
+ );
312
+ }
313
+
314
+ /** One inline action: an IconButton with its icon, else a small text button — each a
315
+ * link for an `href` (see {@link useActionHref}). */
316
+ function InlineAction({ action, size }: { action: RowAction; size: RowActionsSize }) {
317
+ const href = useActionHref(action);
318
+ const glyph = glyphOf(action.icon);
319
+ const tone = action.tone === "danger" ? "danger" : undefined;
320
+ if (glyph) {
321
+ if (href !== undefined) {
322
+ return (
323
+ <IconButton
324
+ href={href}
325
+ external={action.external}
326
+ size={size}
327
+ label={action.label}
328
+ tone={tone}
329
+ disabled={action.disabled}
330
+ stopPropagation
331
+ onClick={() => action.onSelect?.()}
332
+ >
333
+ {glyph}
334
+ </IconButton>
335
+ );
336
+ }
337
+ return (
338
+ <IconButton
339
+ size={size}
340
+ label={action.label}
341
+ tone={tone}
342
+ disabledReason={action.disabledReason}
343
+ commit={action.commit}
344
+ pending={action.pending}
345
+ disabled={action.disabled}
346
+ stopPropagation
347
+ onClick={() => action.onSelect?.()}
348
+ >
349
+ {glyph}
350
+ </IconButton>
351
+ );
352
+ }
353
+ // A row listening for clicks must not open as well (IconButton's stopPropagation).
354
+ const stop = {
355
+ onClick: (e: MouseEvent) => {
356
+ e.stopPropagation();
357
+ action.onSelect?.();
358
+ },
359
+ onKeyDown: (e: KeyboardEvent) => {
360
+ if (e.key === "Enter" || e.key === " ") e.stopPropagation();
361
+ },
362
+ };
363
+ if (href !== undefined) {
364
+ return (
365
+ <Button href={href} external={action.external} variant="ghost" size="sm" tone={tone} disabled={action.disabled} {...stop}>
366
+ {action.label}
367
+ </Button>
368
+ );
369
+ }
370
+ return (
371
+ <Button
372
+ type="button"
373
+ variant="ghost"
374
+ size="sm"
375
+ tone={tone}
376
+ disabledReason={action.disabledReason}
377
+ commit={action.commit}
378
+ pending={action.pending}
379
+ disabled={action.disabled}
380
+ {...stop}
381
+ >
382
+ {action.label}
383
+ </Button>
384
+ );
385
+ }
386
+
387
+ /** The actions column's hidden header, in the provider's words. */
388
+ function RowActionsHeader({ text, labels }: { text?: string; labels?: Partial<RowActionsLabels> }) {
389
+ const resolved = useKitLabels("rowActions", DEFAULT_ROW_ACTIONS_LABELS, labels);
390
+ return <span className="sr-only">{text ?? resolved.actions}</span>;
391
+ }
392
+
393
+ export interface RowActionsColumnOptions<T> {
394
+ /** The column's key. Default `"actions"`. */
395
+ key?: string;
396
+ /** The row's actions — `false` / `null` for the ones a condition leaves out. */
397
+ actions: (row: T) => RowActionList;
398
+ /** The row's name, for the "⋯" button's name ("Actions for Ada Example"). `null` and
399
+ * `undefined` both mean "Actions". */
400
+ name?: (row: T) => string | null | undefined;
401
+ collapse?: RowActionsCollapse;
402
+ /** Default `xs`. */
403
+ size?: RowActionsSize;
404
+ /**
405
+ * The column's name as plain text — the column-settings checklist and the phone
406
+ * card's label read it (`DataTableColumn.headerText`). Pass the app's own word; left
407
+ * out, the header shows the provider's `rowActions.actions` to a screen reader and
408
+ * the plain-text places fall back to the column's `key`.
409
+ */
410
+ headerText?: string;
411
+ labels?: Partial<RowActionsLabels>;
412
+ /** Anything else for the column (`mobileHidden`, `cellProps`…), merged last. */
413
+ column?: Partial<DataTableColumn<T>>;
414
+ }
415
+
416
+ /**
417
+ * A DataTable column of {@link RowActions} — an app's action column in one line
418
+ * (§10.8): inline icons at Normal, the "⋯" menu at Large with two or more actions.
419
+ *
420
+ * columns={[...columns, rowActionsColumn({ actions: (r) => [...], name: (r) => r.name })]}
421
+ *
422
+ * The header is visually hidden (the icons say what the column is), the column hugs its
423
+ * content at the row's end, and `noRowLink` keeps a `rowHref` anchor off it, so the
424
+ * buttons keep their own clicks. On a phone it is a line of the card like any column;
425
+ * set `column: { mobileHidden: true }` to drop it there (with `mobileDetailsInRow` it
426
+ * then shows in the opened row instead).
427
+ */
428
+ export function rowActionsColumn<T>({
429
+ key = "actions",
430
+ actions,
431
+ name,
432
+ collapse,
433
+ size,
434
+ headerText,
435
+ labels,
436
+ column,
437
+ }: RowActionsColumnOptions<T>): DataTableColumn<T> {
438
+ return {
439
+ key,
440
+ header: <RowActionsHeader text={headerText} labels={labels} />,
441
+ headerText,
442
+ cell: (row) => (
443
+ <RowActions actions={actions(row)} name={name?.(row)} collapse={collapse} size={size} labels={labels} />
444
+ ),
445
+ className: "w-px whitespace-nowrap text-end",
446
+ headClassName: "w-px",
447
+ noRowLink: true,
448
+ ...column,
449
+ };
450
+ }
@@ -121,7 +121,7 @@ export function ScrollArea({
121
121
  // a row with its own background would cover exactly the part of the ring that
122
122
  // says where focus is. An outline paints above it, and the negative offset
123
123
  // keeps it inside a parent that clips.
124
- "focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-[var(--brand)]",
124
+ "focus-visible:outline-[length:var(--focus-ring-width)] focus-visible:-outline-offset-2 focus-visible:outline-[var(--brand)]",
125
125
  className,
126
126
  )}
127
127
  />
@@ -2,7 +2,7 @@ import { forwardRef, useRef } from "react";
2
2
  import type { InputHTMLAttributes } from "react";
3
3
  import { Search, X } from "lucide-react";
4
4
  import { cn } from "../lib/cn";
5
- import { FIELD_BASE } from "./ui";
5
+ import { FIELD_BASE, FIELD_TOUCH_TEXT } from "./ui";
6
6
  import { DEFAULT_COMMON_LABELS, useKitLabels } from "../i18n/kit-labels";
7
7
 
8
8
  interface SearchFieldOwnProps
@@ -62,7 +62,9 @@ interface SearchFieldOwnProps
62
62
  // itself) without even its baseline, because the header it sits in already draws
63
63
  // the line. No `text-*` size, on purpose — the input inherits the caller's.
64
64
  const SEARCH_INLINE =
65
- "block w-full min-w-0 border-0 bg-transparent py-1 text-[var(--text-primary)] shadow-none placeholder:text-[var(--text-placeholder)] focus:outline-none focus:ring-0";
65
+ "block w-full min-w-0 border-0 bg-transparent py-1 text-[var(--text-primary)] shadow-none placeholder:text-[var(--text-placeholder)] focus:outline-none focus:ring-0 " +
66
+ // FIELD_BASE carries the 16 px touch floor (§10.1); the inline look needs it too.
67
+ FIELD_TOUCH_TEXT;
66
68
 
67
69
  /**
68
70
  * One of the two spellings is REQUIRED, and the union is how that survives the
@@ -26,7 +26,8 @@ interface BudgetAxis {
26
26
  }
27
27
 
28
28
  /**
29
- * The narrowest the plot may get before the automatic budget steps in, in px.
29
+ * The narrowest the plot may get before the automatic budget steps in, in px at Normal —
30
+ * × the text size's scale since 0.32 (see {@link autoAxisBudget}).
30
31
  *
31
32
  * About a phone's plot with one axis a side (390 px viewport, card padding, two bands
32
33
  * of 48 + 16), where a curve's shape still reads. It is the point below which the chart
@@ -38,6 +39,12 @@ export const MIN_PLOT_WIDTH = 160;
38
39
  /** The budget the automatic rule applies: one axis a side. */
39
40
  export const NARROW_AXIS_BUDGET: SeriesChartAxisBudget = { left: 1, right: 1 };
40
41
 
42
+ /**
43
+ * The automatic rule's second step: the left axis alone — for a chart with an axis on
44
+ * each side that even one a side leaves too little plot (0.32, see {@link autoAxisBudget}).
45
+ */
46
+ export const LEFT_AXIS_BUDGET: SeriesChartAxisBudget = { left: 1, right: 0 };
47
+
41
48
  /** The plot's margin on a side no axis band covers — `SeriesPlot`'s own. */
42
49
  const BARE_SIDE_MARGIN = 10;
43
50
 
@@ -85,10 +92,27 @@ export function budgetedAxes(
85
92
  }
86
93
 
87
94
  /**
88
- * The automatic budget for a chart `width` px wide: {@link NARROW_AXIS_BUDGET} when the
89
- * visible axes' bands would leave the plot under {@link MIN_PLOT_WIDTH} AND some side
90
- * draws more than one axis — the only case one-a-side gives anything back. `undefined`
91
- * otherwise, and for a width that is not known (no layout, no `ResizeObserver`).
95
+ * The automatic budget for a chart `width` px wide, in two steps — each taken only when
96
+ * the plot would otherwise be narrower than {@link MIN_PLOT_WIDTH} × `scale`:
97
+ *
98
+ * 1. {@link NARROW_AXIS_BUDGET}, one axis a side, when some side draws more than one
99
+ * (lenkbank's four-axis curve plot on a phone);
100
+ * 2. {@link LEFT_AXIS_BUDGET}, the left axis alone, when the chart has an axis on EACH
101
+ * side and one a side still leaves the plot too narrow (0.32,
102
+ * docs/text-size-harmonization.md §4, §10.10). At 150 % a 390 px phone's two bands
103
+ * are 96 px each and the plot kept about 80 px. The right-hand axis is the secondary
104
+ * one — the grid hangs its rules off the left — so it goes: its lines keep their own
105
+ * scale, and its unit moves into the tooltip, the readout and the legend
106
+ * ({@link axisUnit}, `seriesLegendEntries`), where its values stay readable.
107
+ *
108
+ * `scale` is the text size's (`useTextSize().scale`): the bands grow with the type
109
+ * (`bandWidth` is handed the scaled ones), and so does the floor (§3.2, "a chart's axis
110
+ * width and tick spacing are multiplied by `scale`") — the room a curve needs between
111
+ * labels grows with the labels.
112
+ *
113
+ * `undefined` when neither step is needed, for a single-axis chart (a facing pair's two
114
+ * charts each have one) and for a width that is not known (no layout, no
115
+ * `ResizeObserver`).
92
116
  *
93
117
  * Decided on the CHART's width and the axes as declared, never on the plot the budget
94
118
  * produced, so hiding an axis cannot widen the plot back over the line and bring it
@@ -98,15 +122,23 @@ export function autoAxisBudget(
98
122
  axes: readonly BudgetAxis[],
99
123
  width: number | undefined,
100
124
  bandWidth: (axis: BudgetAxis) => number,
125
+ scale = 1,
101
126
  ): SeriesChartAxisBudget | undefined {
102
127
  if (width === undefined || !(width > 0)) return undefined;
103
128
  const visible = axes.filter((axis) => !axis.hide);
104
129
  const left = visible.filter((axis) => sideOf(axis) === "left");
105
130
  const right = visible.filter((axis) => sideOf(axis) === "right");
131
+ const floor = MIN_PLOT_WIDTH * scale;
132
+ /** The plot's width with `drawn` axes drawn: what their bands and the bare sides leave. */
133
+ const plot = (drawn: readonly BudgetAxis[]) => {
134
+ const onLeft = drawn.some((axis) => sideOf(axis) === "left");
135
+ const onRight = drawn.some((axis) => sideOf(axis) === "right");
136
+ const bands = drawn.reduce((sum, axis) => sum + bandWidth(axis), 0);
137
+ return width - bands - (onLeft ? 0 : BARE_SIDE_MARGIN) - (onRight ? 0 : BARE_SIDE_MARGIN);
138
+ };
139
+ if (left.length && right.length && plot([left[0], right[0]]) < floor) return LEFT_AXIS_BUDGET;
106
140
  if (left.length <= 1 && right.length <= 1) return undefined;
107
- const bands = visible.reduce((sum, axis) => sum + bandWidth(axis), 0);
108
- const margins = (left.length ? 0 : BARE_SIDE_MARGIN) + (right.length ? 0 : BARE_SIDE_MARGIN);
109
- return width - bands - margins < MIN_PLOT_WIDTH ? NARROW_AXIS_BUDGET : undefined;
141
+ return plot(visible) < floor ? NARROW_AXIS_BUDGET : undefined;
110
142
  }
111
143
 
112
144
  /**
@@ -12,6 +12,16 @@
12
12
  * to about twice this, which is the price of every tick being a round number. */
13
13
  const TARGET_TICKS = 5;
14
14
 
15
+ /** The aim at Large and Extra large (docs/text-size-harmonization.md §4): the labels are
16
+ * 25–50 % wider and taller, so five of them crowd an axis that holds them at Normal. */
17
+ export const LARGE_TEXT_TARGET_TICKS = 3;
18
+
19
+ /** How many ticks to aim for at a text `scale` (`useTextSize().scale`): five at Normal,
20
+ * three from Large up. */
21
+ export function tickTarget(scale = 1): number {
22
+ return scale > 1 ? LARGE_TEXT_TARGET_TICKS : TARGET_TICKS;
23
+ }
24
+
15
25
  /** The round step closest to `span / target`: 1, 2 or 5 times a power of ten. */
16
26
  export function niceStep(span: number, target: number = TARGET_TICKS): number {
17
27
  const rough = span / Math.max(1, target);