@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
@@ -61,7 +61,7 @@ import {
61
61
  } from "./chart-zoom";
62
62
  import { STEP_DASH, strokeDash, type LegendEntry } from "./toggle-legend";
63
63
  import { DEFAULT_SERIES_CHART_LABELS, type SeriesChartLabels } from "./series-chart-labels";
64
- import { categoryTicks, integerTicks, niceTicks, timeTicksWithUnit, type TimeTickUnit } from "./series-chart-ticks";
64
+ import { categoryTicks, integerTicks, niceTicks, tickTarget, timeTicksWithUnit, type TimeTickUnit } from "./series-chart-ticks";
65
65
  // The tick module stays internal; the one type of it a public prop names is re-exported.
66
66
  export type { TimeTickUnit } from "./series-chart-ticks";
67
67
  import { autoAxisBudget, axisUnit, budgetedAxes, type SeriesChartAxisBudget } from "./series-chart-budget";
@@ -74,7 +74,9 @@ import {
74
74
  useKitLocale,
75
75
  type ChartTooltipPlacement,
76
76
  } from "../i18n/kit-labels";
77
- import { useMediaQuery } from "../hooks/use-media-query";
77
+ import { useBreakpoint } from "../hooks/use-breakpoint";
78
+ import { useTextSize } from "../theme/text-size";
79
+ import { chartHeightProps, type ChartHeight } from "./chart-height";
78
80
  import { cn } from "../lib/cn";
79
81
 
80
82
  export interface SeriesChartSeries {
@@ -343,7 +345,7 @@ export interface SeriesChartX {
343
345
  * instead of being centred across it; the anchor is physical, like the plot (see
344
346
  * `ChartContainer`), so it is the same in RTL. The band under the axis grows to the
345
347
  * rotated height of the longest label on show, estimated from its length (at most
346
- * 120 px, past which a label is clipped). Default 0.
348
+ * 120 px × the text size's scale, past which a label is clipped). Default 0.
347
349
  */
348
350
  tickAngle?: number;
349
351
  /**
@@ -365,10 +367,6 @@ export interface SeriesChartX {
365
367
  /** Where the tooltip goes — see {@link SeriesChartTooltip.placement}. */
366
368
  export type SeriesChartTooltipPlacement = ChartTooltipPlacement;
367
369
 
368
- /** Below Tailwind's `sm` — where `"auto"` takes the tooltip off the plot. Narrower than
369
- * the kit's `PHONE_QUERY` (767 px) on purpose: a tablet's plot is wide enough that the
370
- * box beside the finger leaves the data in view; a phone's is not. */
371
- const TOOLTIP_READOUT_QUERY = "(max-width: 639px)";
372
370
 
373
371
  /**
374
372
  * The placement a chart actually uses: its own, else the provider's, else `"cursor"`;
@@ -537,13 +535,22 @@ export interface SeriesChartProps {
537
535
  /** A value in the tooltip, where a number stands on its own and needs its unit.
538
536
  * Default: `Intl.NumberFormat` in the kit's locale. */
539
537
  valueFormat?: (value: number) => string;
540
- /** Tailwind height class, or a height in pixels. Default `h-72`. The empty state
541
- * takes it too, so a chart losing its last line does not relayout the page under it.
542
- * A number is for a height the caller holds as a number — keksdose's report charts
543
- * take `height = 260` as a prop and wrap the chart in a `SizedSeriesChart` div
544
- * (reports/charts/networth-line.tsx) only to turn it into a style, since a class
545
- * cannot be built from a number Tailwind never saw. */
546
- height?: string | number;
538
+ /**
539
+ * The chart's height: a CSS length, a Tailwind height class, or px. Default `h-72`
540
+ * (18rem). The empty state takes it too, so a chart losing its last line does not
541
+ * relayout the page under it.
542
+ *
543
+ * - **A CSS length** (0.32) — `"20rem"`, `"min(20rem, 60dvh)"` — set inline. The form
544
+ * for a height that should grow with the text size and still stop at the screen
545
+ * (docs/text-size-harmonization.md §10.10): `min(30rem, 60dvh)` is 480 px at Normal
546
+ * on a desktop and never more than 60 % of a phone at Extra large, where a scaled
547
+ * 480 px would be 720.
548
+ * - **A Tailwind class** — `"h-72"`, `"h-64 md:h-80"` — as before.
549
+ * - **A number** is px, set inline, and does NOT follow the text size: kept for a
550
+ * height the caller holds as a number (keksdose's report charts take
551
+ * `height = 260` as a prop). Prefer `"16.25rem"`, or a `min()` with a viewport cap.
552
+ */
553
+ height?: ChartHeight;
547
554
  /** Bridge holes left by sources sampled on different grids. See {@link mergeSeries}. */
548
555
  connectNulls?: boolean;
549
556
  /** Shown, centred at the chart's height, instead of an empty chart. Default: the
@@ -587,17 +594,23 @@ export interface SeriesChartProps {
587
594
  maxVisibleAxes?: SeriesChartAxisBudget;
588
595
  /**
589
596
  * `"auto"` (the default): a chart so narrow that its axes' bands would leave the plot
590
- * under 160 px (`MIN_PLOT_WIDTH`) draws ONE axis a side — lenkbank's four-axis curve
591
- * plot on a phone, whose plot was 10 px wide. Measured on the chart's own box
592
- * (`ResizeObserver`), and applied on top of `maxVisibleAxes`.
597
+ * under 160 px (`MIN_PLOT_WIDTH`, × the text size's scale) draws ONE axis a side —
598
+ * lenkbank's four-axis curve plot on a phone, whose plot was 10 px wide. And a chart
599
+ * with an axis on EACH side that one a side still leaves too narrow (0.32: at 150 % a
600
+ * 390 px phone's plot kept about 80 px between its two bands) drops the right-hand,
601
+ * secondary axis too. Measured on the chart's own box (`ResizeObserver`), and applied
602
+ * on top of `maxVisibleAxes`. Either way the series on an axis it hid say the axis'
603
+ * unit in the tooltip and the readout ("Rack load (N)"), and in a legend built by
604
+ * {@link seriesLegendEntries} with `onAxisBudget`'s ids.
593
605
  *
594
- * On by default because it cannot touch a layout that works: it needs a side with two
595
- * or more axes AND a plot that would otherwise be under 160 px — a four-axis chart
596
- * below about 440 px, a two-left-axis one below about 300. A chart with at most one
597
- * axis a side (every facing pair, every single-axis chart) is never budgeted, at any
598
- * width. `"off"` keeps every declared axis whatever the width: for a stack of
599
- * multi-axis charts that must keep identical bands, or a caller budgeting itself.
600
- * Without layout (jsdom, SSR) nothing is measured and nothing is hidden.
606
+ * On by default because it cannot touch a layout that works: it needs a plot that
607
+ * would otherwise be under 160 px — a four-axis chart below about 440 px at Normal, a
608
+ * two-left-axis one below about 300, a one-a-side one below about 290 — and the
609
+ * left-hand axis always stays. A chart with one axis (each chart of a facing pair,
610
+ * every single-axis chart) is never budgeted, at any width. `"off"` keeps every
611
+ * declared axis whatever the width: for a stack of multi-axis charts that must keep
612
+ * identical bands, or a caller budgeting itself. Without layout (jsdom, SSR) nothing is
613
+ * measured and nothing is hidden.
601
614
  */
602
615
  axisBudget?: "auto" | "off";
603
616
  /**
@@ -621,38 +634,48 @@ export interface SeriesChartProps {
621
634
  minBarLength?: number;
622
635
  }
623
636
 
624
- /** How much of an axis band the rotated title takes, in px. Reserved rather than
625
- * shared with the ticks: a title merely offset inside the band prints on top of a
626
- * five-figure tick, and which gives way depends on the data. */
637
+ /** How much of an axis band the rotated title takes, in px at Normal — × the text size's
638
+ * scale on the chart (§3.2), since the title is text. Reserved rather than shared with
639
+ * the ticks: a title merely offset inside the band prints on top of a five-figure tick,
640
+ * and which gives way depends on the data. */
627
641
  export const AXIS_TITLE_STRIP = 16;
628
642
 
629
643
  /** Where inside its strip the rotated title sits. */
630
644
  const AXIS_TITLE_OFFSET = 10;
631
645
 
632
- /** The tallest band tilted x ticks reserve, in px. A category name longer than this at
633
- * its angle is clipped rather than squeezing the plot down to a strip. */
646
+ /** The tallest band tilted x ticks reserve, in px at Normal (× the scale). A category
647
+ * name longer than this at its angle is clipped rather than squeezing the plot down to
648
+ * a strip. */
634
649
  const MAX_TILTED_TICK_BAND = 120;
635
650
 
636
- /** What one character of a tick label is taken to be, in px, for the tilted band — the
637
- * shell's `text-xs`. An estimate: the SVG is not laid out yet when the band is decided. */
651
+ /** What one character of a tick label is taken to be, in px at Normal, for the tilted
652
+ * band — the shell's `text-xs`. An estimate: the SVG is not laid out yet when the band
653
+ * is decided. Both grow with the text size, as `text-xs` does (§3.2). */
638
654
  const TICK_CHAR_WIDTH = 7;
639
655
  const TICK_LINE_HEIGHT = 12;
640
- /** recharts' gap between the axis line and a bottom tick's text. */
656
+ /** recharts' gap between the axis line and a bottom tick's text — px, at every size:
657
+ * recharts draws it, not the type. */
641
658
  const TICK_GAP = 8;
659
+ /** recharts' own band under level x ticks. */
660
+ const LEVEL_TICK_BAND = 30;
661
+ /** The least room recharts' x ticks keep between labels, in px at Normal. */
662
+ const MIN_TICK_GAP = 32;
642
663
 
643
664
  /**
644
- * The height the x axis reserves for ticks tilted by `angle` degrees: the rotated box of
645
- * the longest label, from its length. `undefined` for level ticks — recharts' own 30 px.
665
+ * The height the x axis reserves for its ticks at a text `scale`: tilted by `angle`
666
+ * degrees, the rotated box of the longest label, from its length; level, recharts' own
667
+ * 30 px grown with the labels. `undefined` for level ticks at Normal, where recharts'
668
+ * default is exactly that.
646
669
  */
647
- function tiltedTickBand(labels: readonly string[], angle: number): number | undefined {
648
- if (!angle) return undefined;
670
+ function tiltedTickBand(labels: readonly string[], angle: number, scale = 1): number | undefined {
671
+ if (!angle) return scale === 1 ? undefined : Math.ceil(LEVEL_TICK_BAND * scale);
649
672
  const rad = (Math.abs(angle) * Math.PI) / 180;
650
- const longest = Math.max(0, ...labels.map((label) => label.length)) * TICK_CHAR_WIDTH;
651
- const band = Math.sin(rad) * longest + Math.cos(rad) * TICK_LINE_HEIGHT + TICK_GAP;
652
- return Math.min(MAX_TILTED_TICK_BAND, Math.max(30, Math.ceil(band)));
673
+ const longest = Math.max(0, ...labels.map((label) => label.length)) * TICK_CHAR_WIDTH * scale;
674
+ const band = Math.sin(rad) * longest + Math.cos(rad) * TICK_LINE_HEIGHT * scale + TICK_GAP;
675
+ return Math.min(Math.round(MAX_TILTED_TICK_BAND * scale), Math.max(Math.ceil(LEVEL_TICK_BAND * scale), Math.ceil(band)));
653
676
  }
654
677
 
655
- /** The width the ticks of a y axis get when a caller does not say. */
678
+ /** The width the ticks of a y axis get when a caller does not say, in px at Normal. */
656
679
  export const AXIS_TICK_WIDTH = 48;
657
680
 
658
681
  /**
@@ -686,10 +709,19 @@ export function padBand(low: number, high: number): [number, number] | undefined
686
709
  return [low - pad, high + pad];
687
710
  }
688
711
 
689
- /** The whole band a y axis occupies: its ticks, and its title when it draws one. For
690
- * lining a heading up over a PLOT rather than over its column. */
691
- export function axisBandWidth(tickWidth: number | undefined, titled: boolean): number {
692
- return (tickWidth ?? AXIS_TICK_WIDTH) + (titled ? AXIS_TITLE_STRIP : 0);
712
+ /**
713
+ * The whole band a y axis occupies: its ticks, and its title when it draws one. For
714
+ * lining a heading up over a PLOT rather than over its column.
715
+ *
716
+ * `scale` is the text size's (`useTextSize().scale`, §3.2, §10.10): the chart draws every
717
+ * band — the default 48 px and a caller's own `width` alike (keksdose's
718
+ * `MONEY_AXIS_WIDTH`) — this many times wider, because the ticks in it are `text-xs`
719
+ * and grow with the text. A heading lined up over the plot has to pass the same scale.
720
+ * One factor for both sides of a facing pair, so the mirrored bands stay equal.
721
+ */
722
+ export function axisBandWidth(tickWidth: number | undefined, titled: boolean, scale = 1): number {
723
+ const band = (tickWidth ?? AXIS_TICK_WIDTH) + (titled ? AXIS_TITLE_STRIP : 0);
724
+ return scale === 1 ? band : Math.round(band * scale);
693
725
  }
694
726
 
695
727
  /**
@@ -1016,10 +1048,13 @@ function focusedBarShape(index: number) {
1016
1048
  };
1017
1049
  }
1018
1050
 
1019
- /** A marker label's size and weight — the one place both the text and its width
1020
- * estimate read them from. */
1051
+ /** A marker label's size in px at Normal — the one place both the text and its width
1052
+ * estimate read it from. × the text size's scale where it is drawn (§10.10). */
1021
1053
  const MARKER_LABEL_SIZE = 11;
1022
1054
 
1055
+ /** A reference line's label, in px at Normal, × the scale likewise. */
1056
+ const REFERENCE_LABEL_SIZE = 10;
1057
+
1023
1058
  /**
1024
1059
  * A marker's label, centred over its point but clamped inside the plot. recharts'
1025
1060
  * `position: "top"` centres on the point no matter where it is, so a marker near the
@@ -1037,16 +1072,17 @@ function MarkerLabel({
1037
1072
  const plot = usePlotArea();
1038
1073
  const ref = useRef<SVGTextElement>(null);
1039
1074
  const [measured, setMeasured] = useState<number>();
1075
+ const fontSize = MARKER_LABEL_SIZE * useTextSize().scale;
1040
1076
  const text = value == null ? "" : String(value);
1041
1077
  useLayoutEffect(() => {
1042
1078
  const el = ref.current;
1043
1079
  if (!el || typeof el.getComputedTextLength !== "function") return;
1044
1080
  const w = el.getComputedTextLength();
1045
1081
  if (w > 0 && w !== measured) setMeasured(w);
1046
- }, [text, measured]);
1082
+ }, [text, measured, fontSize]);
1047
1083
  if (!viewBox || viewBox.x == null || viewBox.y == null || text === "") return null;
1048
1084
  const cx = viewBox.x + (viewBox.width ?? 0) / 2;
1049
- const half = (measured ?? text.length * MARKER_LABEL_SIZE * 0.6) / 2;
1085
+ const half = (measured ?? text.length * fontSize * 0.6) / 2;
1050
1086
  // The start clamp applied last: a label wider than the plot keeps its start on screen.
1051
1087
  const x = plot ? Math.max(plot.x + half, Math.min(cx, plot.x + plot.width - half)) : cx;
1052
1088
  return (
@@ -1055,7 +1091,7 @@ function MarkerLabel({
1055
1091
  x={x}
1056
1092
  y={viewBox.y - 5}
1057
1093
  textAnchor="middle"
1058
- fontSize={MARKER_LABEL_SIZE}
1094
+ fontSize={fontSize}
1059
1095
  fontWeight={600}
1060
1096
  fill="var(--text-primary)"
1061
1097
  className="recharts-label"
@@ -1216,12 +1252,22 @@ function SeriesPlot({
1216
1252
  const labels = useKitLabels("seriesChart", DEFAULT_SERIES_CHART_LABELS, labelsProp);
1217
1253
  const locale = useKitLocale(localeProp);
1218
1254
  const number = useDefaultFormat(localeProp);
1255
+ // The text size (docs/text-size-harmonization.md §3.2, §4, §10.10): the axis bands, the
1256
+ // tick spacing and the labels drawn in px grow with it — the tick text is `text-xs` and
1257
+ // grows by itself — and the axes aim at three ticks instead of five from Large up.
1258
+ // Strokes, dashes and the grid stay px.
1259
+ const { scale } = useTextSize();
1260
+ const ticksAim = tickTarget(scale);
1261
+ const grow = (px: number) => (scale === 1 ? px : Math.round(px * scale));
1219
1262
  // The keyboard stops' roving tab stop, and the one that has focus (see `PointKeys`).
1220
1263
  // Up here, above the empty state's early return, like every hook.
1221
1264
  const [keyStop, setKeyStop] = useState(0);
1222
1265
  const [keyFocus, setKeyFocus] = useState<number | undefined>(undefined);
1223
1266
  // Where the tooltip goes, and — off the plot — the row it is portalled into.
1224
- const phone = useMediaQuery(TOOLTIP_READOUT_QUERY, false);
1267
+ // Below `sm` (`max-sm:`, at the text size in force) — where `"auto"` takes the tooltip
1268
+ // off the plot. Narrower than the phone layout on purpose: a tablet's plot is wide
1269
+ // enough that the box beside the finger leaves the data in view; a phone's is not.
1270
+ const phone = useBreakpoint("max-sm", false);
1225
1271
  const placement = resolveTooltipPlacement(tooltip?.placement, useKitChartTooltipPlacement(), phone);
1226
1272
  const [readout, setReadout] = useState<HTMLDivElement | null>(null);
1227
1273
 
@@ -1248,8 +1294,11 @@ function SeriesPlot({
1248
1294
  ? []
1249
1295
  : budgetedAxes(
1250
1296
  afterCap,
1251
- autoAxisBudget(afterCap, width, (axis) =>
1252
- axisBandWidth(axis.width, Boolean(axis.title)),
1297
+ autoAxisBudget(
1298
+ afterCap,
1299
+ width,
1300
+ (axis) => axisBandWidth(axis.width, Boolean(axis.title), scale),
1301
+ scale,
1253
1302
  ),
1254
1303
  );
1255
1304
  const budgeted = [...capped, ...auto];
@@ -1263,10 +1312,9 @@ function SeriesPlot({
1263
1312
  onAxisBudget?.(budgetKey ? budgetKey.split("\n") : []);
1264
1313
  }, [budgetKey, onAxisBudget]);
1265
1314
 
1266
- // A number is pixels, set inline; a string is a class. Either way the one value
1267
- // sizes both the chart and its empty state.
1268
- const heightClass = typeof height === "string" ? height : undefined;
1269
- const heightStyle = typeof height === "number" ? { height } : undefined;
1315
+ // A number or a CSS length is set inline; any other string is a class. Either way the
1316
+ // one value sizes both the chart and its empty state.
1317
+ const { className: heightClass, style: heightStyle } = chartHeightProps(height);
1270
1318
 
1271
1319
  // The empty state takes the chart's own height and is centred in it: a chart that
1272
1320
  // shrank to its "nothing to draw" sentence moved everything under it up the page
@@ -1321,11 +1369,12 @@ function SeriesPlot({
1321
1369
  // overhang of the first/last x tick where no y axis covers it.
1322
1370
  const margin = {
1323
1371
  // Room for a marker's label over a point at the top of the band.
1324
- top: markers?.some((marker) => marker.label) ? 22 : 8,
1325
- right: onRight ? 0 : 10,
1326
- left: onLeft ? 0 : 10,
1372
+ top: markers?.some((marker) => marker.label) ? grow(22) : 8,
1373
+ // The first and last x tick's overhang: text, so it grows with it.
1374
+ right: onRight ? 0 : grow(10),
1375
+ left: onLeft ? 0 : grow(10),
1327
1376
  // Under the ticks, not under the whole axis: whatever comes next owns the gap.
1328
- bottom: x.title ? 18 : 2,
1377
+ bottom: x.title ? grow(18) : 2,
1329
1378
  };
1330
1379
 
1331
1380
  const refs = references ?? [];
@@ -1353,7 +1402,7 @@ function SeriesPlot({
1353
1402
  ) ?? [Infinity, -Infinity]),
1354
1403
  ));
1355
1404
 
1356
- const timeUnit = model.kind === "time" ? timeTicksWithUnit(fittedX) : undefined;
1405
+ const timeUnit = model.kind === "time" ? timeTicksWithUnit(fittedX, ticksAim) : undefined;
1357
1406
  // Whole-number ticks on a number line whose rows are all whole numbers — see
1358
1407
  // `SeriesChartX.integerTicks`.
1359
1408
  const integerX =
@@ -1370,8 +1419,8 @@ function SeriesPlot({
1370
1419
  : model.kind === "time"
1371
1420
  ? timeUnit?.ticks
1372
1421
  : integerX
1373
- ? (integerTicks(fittedX) ?? niceTicks(fittedX))
1374
- : niceTicks(fittedX));
1422
+ ? (integerTicks(fittedX, ticksAim) ?? niceTicks(fittedX, ticksAim))
1423
+ : niceTicks(fittedX, ticksAim));
1375
1424
 
1376
1425
  // Ticks and the tooltip heading, back in the caller's terms.
1377
1426
  const timeFormat = new Intl.DateTimeFormat(locale, TIME_TICK_FORMAT[timeUnit?.unit ?? "day"]);
@@ -1404,7 +1453,7 @@ function SeriesPlot({
1404
1453
  const xLabel = (position: number) => label(position, tickAt(position));
1405
1454
 
1406
1455
  const tickAngle = x.ticks === false ? 0 : (x.tickAngle ?? 0);
1407
- const tickBand = tiltedTickBand((xTicks ?? []).map((tick) => xFormat(tick)), tickAngle);
1456
+ const tickBand = tiltedTickBand((xTicks ?? []).map((tick) => xFormat(tick)), tickAngle, scale);
1408
1457
 
1409
1458
  const source: ZoomFitSource = {
1410
1459
  rows: plotted,
@@ -1597,7 +1646,7 @@ function SeriesPlot({
1597
1646
  allowDataOverflow={zoom?.xDomain !== undefined || model.kind === "category"}
1598
1647
  tickLine={false}
1599
1648
  axisLine={false}
1600
- minTickGap={32}
1649
+ minTickGap={grow(MIN_TICK_GAP)}
1601
1650
  // Where the ticks crowd, drop every Nth rather than recharts' default
1602
1651
  // `preserveEnd`, which drops whichever single tick collides: a phone's whole-week
1603
1652
  // axis came out 2 4 6 8 _ 12, a doubled gap that reads as a missing week. Every
@@ -1616,8 +1665,8 @@ function SeriesPlot({
1616
1665
  <Label
1617
1666
  value={x.title}
1618
1667
  position="insideBottom"
1619
- offset={-12}
1620
- className="fill-[var(--text-muted)] text-[11px]"
1668
+ offset={-grow(12)}
1669
+ className="fill-[var(--text-muted)] text-caption"
1621
1670
  />
1622
1671
  )}
1623
1672
  </XAxis>
@@ -1634,7 +1683,9 @@ function SeriesPlot({
1634
1683
  domain={domain}
1635
1684
  ticks={
1636
1685
  resolveTicks(axis.tickValues, domain, finite) ??
1637
- (wholeOnly(axis) ? (integerTicks(domain) ?? niceTicks(domain)) : niceTicks(domain))
1686
+ (wholeOnly(axis)
1687
+ ? (integerTicks(domain, ticksAim) ?? niceTicks(domain, ticksAim))
1688
+ : niceTicks(domain, ticksAim))
1638
1689
  }
1639
1690
  allowDataOverflow={zoomed}
1640
1691
  orientation={axis.orientation ?? "left"}
@@ -1642,7 +1693,7 @@ function SeriesPlot({
1642
1693
  // what the budget does on every resize across its threshold — kept its old
1643
1694
  // width in recharts' stacking of that side, and pushed the axes still drawn
1644
1695
  // off the chart's edge. A zero width leaves nothing stale to count.
1645
- width={axis.hide ? 0 : axisBandWidth(axis.width, Boolean(axis.title))}
1696
+ width={axis.hide ? 0 : axisBandWidth(axis.width, Boolean(axis.title), scale)}
1646
1697
  tickLine={false}
1647
1698
  axisLine={false}
1648
1699
  tickFormatter={axis.format ?? number}
@@ -1659,8 +1710,8 @@ function SeriesPlot({
1659
1710
  // Inline, so a sole series' colour beats the class's neutral fill —
1660
1711
  // and absent for a shared axis, so the class draws it.
1661
1712
  style={{ textAnchor: "middle", fill: soleSeriesColor(axis, series) }}
1662
- offset={AXIS_TITLE_OFFSET}
1663
- className="fill-[var(--text-muted)] text-[11px]"
1713
+ offset={grow(AXIS_TITLE_OFFSET)}
1714
+ className="fill-[var(--text-muted)] text-caption"
1664
1715
  />
1665
1716
  )}
1666
1717
  </YAxis>
@@ -1817,7 +1868,7 @@ function SeriesPlot({
1817
1868
  ? {
1818
1869
  value: ref.label,
1819
1870
  position: "insideTopLeft",
1820
- fontSize: 10,
1871
+ fontSize: REFERENCE_LABEL_SIZE * scale,
1821
1872
  fill: color,
1822
1873
  }
1823
1874
  : undefined
@@ -4,11 +4,19 @@ import type { SelectProps } from "./ui";
4
4
  import { ToggleGroup } from "./toggle-group";
5
5
  import type { ToggleGroupBaseProps } from "./toggle-group";
6
6
  import type { ThemePreference } from "../theme/theme-store";
7
+ import { TEXT_SIZES } from "../theme/text-size";
8
+ import type { TextSize } from "../theme/text-size";
9
+ import { CONTRAST_MODES } from "../theme/contrast";
10
+ import type { ContrastMode } from "../theme/contrast";
11
+ import { useAppearanceLabels } from "./appearance-labels";
12
+ import type { AppearanceLabels } from "./appearance-labels";
7
13
 
8
14
  /**
9
15
  * App-agnostic settings-field components (feedback #333): the language + theme
10
- * controls that every app's settings page needs, so they live in @hb/ui and the
11
- * app just supplies the current value, a change handler and translated labels.
16
+ * controls that every app's settings page needs — and, since 0.32, the text size and
17
+ * the contrast (docs/text-size-harmonization.md §6), whose words are the kit's own
18
+ * `appearance` namespace — so they live in @hb/ui and the app just supplies the
19
+ * current value, a change handler and translated labels.
12
20
  * The app owns WHERE these render (its own settings page) and any app-specific
13
21
  * fields around them.
14
22
  */
@@ -37,8 +45,12 @@ export interface ThemeSettingProps
37
45
  * one segmented control instead of a select — system, light and dark side by side, the
38
46
  * choice visible without opening anything, in every app (keksdose offered light and dark
39
47
  * only; its store already knew "system"). A {@link ToggleGroup}'s props pass through —
40
- * `labelPlacement`, `disabledReason`, `commit`, `size` — minus the options and the value,
41
- * which this owns.
48
+ * `labelPlacement`, `disabledReason`, `commit`, `size`, `overflow` — minus the options
49
+ * and the value, which this owns.
50
+ *
51
+ * The options wrap rather than truncate (`overflow="wrap"`), as in its two siblings
52
+ * {@link TextSizeSetting} and {@link ContrastSetting} (0.32.1, Kurvenschmiede's 0.32
53
+ * report: "Syst… Li… D…" in a card at Extra large on a 360 px phone).
42
54
  *
43
55
  * Bind it to the PREFERENCE (`"system"` included), never to the resolved mode: on a
44
56
  * system-dark device a control bound to the mode shows "dark" and cannot say "follow the
@@ -62,10 +74,11 @@ export interface ThemeSettingToggleProps
62
74
 
63
75
  export function ThemeSetting(props: ThemeSettingProps | ThemeSettingToggleProps) {
64
76
  if (props.variant === "toggle") {
65
- const { variant: _variant, value, onChange, label, optionLabels, ...rest } = props;
77
+ const { variant: _variant, value, onChange, label, optionLabels, overflow = "wrap", ...rest } = props;
66
78
  return (
67
79
  <ToggleGroup<ThemePreference>
68
80
  {...rest}
81
+ overflow={overflow}
69
82
  label={label}
70
83
  value={value}
71
84
  onChange={onChange}
@@ -115,3 +128,74 @@ export function LanguageSetting({ value, onChange, label, options, id, ...rest }
115
128
  </Select>
116
129
  );
117
130
  }
131
+
132
+ /**
133
+ * What {@link TextSizeSetting} and {@link ContrastSetting} take: a {@link ToggleGroup}'s
134
+ * props — `labelPlacement`, `disabledReason`, `commit`, `size`, `overflow` — minus the
135
+ * options and the value, which they own, as {@link ThemeSettingToggleProps} does.
136
+ */
137
+ type AppearanceToggleProps<T extends string> = Omit<ToggleGroupBaseProps<T>, "options" | "label" | "ariaLabel"> & {
138
+ value: T;
139
+ onChange: (value: T) => void;
140
+ /**
141
+ * The field's visible label. Leave it out inside a row already titled with the
142
+ * setting's name: the group is then named by `aria-label` / `aria-labelledby` if
143
+ * given, else by the kit's own word ("Text size", "Contrast").
144
+ */
145
+ label?: ReactNode;
146
+ /** The `appearance` namespace, for this instance. */
147
+ labels?: Partial<AppearanceLabels>;
148
+ };
149
+
150
+ export type TextSizeSettingProps = AppearanceToggleProps<TextSize>;
151
+
152
+ /**
153
+ * The text size (0.32, docs/text-size-harmonization.md §6): Normal, Large, Extra large as
154
+ * one segmented control, in the core `appearance` group after the theme. Bind it to the
155
+ * size IN FORCE — `useAccountAppearance().textSize` — and hand a pick to its
156
+ * `pickTextSize`, which stores the device's choice and, signed in, the account's.
157
+ *
158
+ * The options wrap rather than truncate (`overflow="wrap"`): at Extra large on a 360 px
159
+ * phone the group has 240 px, and "Extra large" cut to "Extra l…" would be the one
160
+ * setting that cannot read its own value.
161
+ */
162
+ export function TextSizeSetting({ value, onChange, label, labels: labelsProp, overflow = "wrap", ...rest }: TextSizeSettingProps) {
163
+ const labels = useAppearanceLabels(labelsProp);
164
+ const named = label !== undefined && label !== null && label !== false;
165
+ return (
166
+ <ToggleGroup<TextSize>
167
+ {...rest}
168
+ aria-label={named || rest["aria-labelledby"] ? rest["aria-label"] : (rest["aria-label"] ?? labels.textSize)}
169
+ label={label}
170
+ overflow={overflow}
171
+ value={value}
172
+ onChange={onChange}
173
+ options={TEXT_SIZES.map((size) => ({ value: size, label: labels.textSizes[size] }))}
174
+ />
175
+ );
176
+ }
177
+
178
+ export type ContrastSettingProps = AppearanceToggleProps<ContrastMode>;
179
+
180
+ /**
181
+ * More contrast (0.32, §5, §6): System, Standard, More as one segmented control, beside
182
+ * the text size. Bind it to the stored MODE, "system" included — never to whether more
183
+ * contrast is on at the moment, or a device that asks for more contrast would show
184
+ * "More" and could not say "follow the device" (the theme's lesson, §8 of the settings
185
+ * contract). `useAccountAppearance().contrast` is that mode.
186
+ */
187
+ export function ContrastSetting({ value, onChange, label, labels: labelsProp, overflow = "wrap", ...rest }: ContrastSettingProps) {
188
+ const labels = useAppearanceLabels(labelsProp);
189
+ const named = label !== undefined && label !== null && label !== false;
190
+ return (
191
+ <ToggleGroup<ContrastMode>
192
+ {...rest}
193
+ aria-label={named || rest["aria-labelledby"] ? rest["aria-label"] : (rest["aria-label"] ?? labels.contrast)}
194
+ label={label}
195
+ overflow={overflow}
196
+ value={value}
197
+ onChange={onChange}
198
+ options={CONTRAST_MODES.map((mode) => ({ value: mode, label: labels.contrastModes[mode] }))}
199
+ />
200
+ );
201
+ }
@@ -20,6 +20,7 @@ import { Tooltip } from "./tooltip";
20
20
  import { Button, Card, IconButton, Spinner } from "./ui";
21
21
  import { useWriteLock } from "./write-lock";
22
22
  import type { CardProps } from "./ui";
23
+ import type { DisabledReasonDisplay } from "./field-parts";
23
24
 
24
25
  /**
25
26
  * Who holds one record, and the owner's every way of changing that — Kurvenschmiede's
@@ -224,6 +225,16 @@ function ShareRoleChip({ role }: { role: ShareRole | undefined }) {
224
225
  return role.description ? <Tooltip label={role.description}>{chip}</Tooltip> : chip;
225
226
  }
226
227
 
228
+ /**
229
+ * A row's controls: the role toggle and the remove icon, or a pending grant's copy and
230
+ * revoke. Held to the row and wrapping inside it (0.32.1, the 360 px Extra-large sweep;
231
+ * docs/text-size-harmonization.md §4 "nothing overflows"): under a write lock on a touch
232
+ * screen or at Large the remove icon gives its reason as a line under it, up to 20rem
233
+ * wide, and a `shrink-0` box ran 31 px past a 390 px phone at Normal and 269 px past a
234
+ * 360 px one at Extra large. Where the controls fit in one row, nothing changes.
235
+ */
236
+ const ROW_CONTROLS = "ms-auto flex min-w-0 max-w-full flex-wrap items-center justify-end gap-1";
237
+
227
238
  /**
228
239
  * A row's role choice saves on change, so it is a commit that cannot take `commit`:
229
240
  * under a write lock it is disabled, and the lock's reason is put in the kit Tooltip
@@ -278,6 +289,12 @@ export function SharePanel({
278
289
  const roleOf = (key: string | undefined) => roles.find((r) => r.key === key);
279
290
  const choosable = roles.length > 1;
280
291
  const canAdd = !readOnly && onAdd !== undefined;
292
+ // Under a write lock the form's Share button gives the lock's sentence as a line (on
293
+ // touch and at Large). A row's remove or revoke icon then keeps it in its tooltip, as
294
+ // the role toggle beside it does, rather than repeat the same line under every row
295
+ // (0.32.1, the 360 px Extra-large sweep). Without the form the rows' lines are the
296
+ // only place it is said, so they stay — and ROW_CONTROLS wraps them.
297
+ const rowReason: DisabledReasonDisplay = canAdd ? "tooltip" : "auto";
281
298
 
282
299
  const run = async (key: string, action: () => MaybePromise): Promise<boolean> => {
283
300
  setBusy(key);
@@ -457,7 +474,7 @@ export function SharePanel({
457
474
  )}
458
475
  </div>
459
476
  {(changeable || (editable && onRemove)) && (
460
- <div className="ms-auto flex shrink-0 items-center gap-1">
477
+ <div className={ROW_CONTROLS}>
461
478
  {changeable && (
462
479
  <LockedRoleChoice reason={lock.locked ? lock.reason : undefined}>
463
480
  <ToggleGroup<string>
@@ -478,6 +495,13 @@ export function SharePanel({
478
495
  size="xs"
479
496
  commit
480
497
  label={labels.remove}
498
+ // The icon alone at every text size (§10.8): the row's one
499
+ // control beside its role toggle, where "Remove access" as
500
+ // text at Large would not fit a 240 px row. It carries a
501
+ // spinner and the write lock, which a "⋯" menu entry
502
+ // cannot, and its confirmation names the action in words.
503
+ labelVisible={false}
504
+ disabledReasonDisplay={rowReason}
481
505
  pending={busy === key}
482
506
  disabled={busy !== null}
483
507
  onClick={async () => {
@@ -523,7 +547,7 @@ export function SharePanel({
523
547
  </div>
524
548
  </div>
525
549
  {(p.link || (!readOnly && onRevokePending)) && (
526
- <div className="ms-auto flex shrink-0 items-center gap-1">
550
+ <div className={ROW_CONTROLS}>
527
551
  {p.link && <CopyButton size="xs" tone="muted" text={p.link} label={labels.copyLink} />}
528
552
  {!readOnly && onRevokePending && (
529
553
  <IconButton
@@ -531,6 +555,11 @@ export function SharePanel({
531
555
  size="xs"
532
556
  commit
533
557
  label={labels.revokePending}
558
+ // As the grantee's remove above: one action beside the
559
+ // copy icon (which is an icon at every size), and the
560
+ // confirmation says it in words.
561
+ labelVisible={false}
562
+ disabledReasonDisplay={rowReason}
534
563
  pending={busy === key}
535
564
  disabled={busy !== null}
536
565
  onClick={async () => {