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