@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
@@ -3,6 +3,7 @@ import { Chip } from "./chip";
3
3
  import { Tooltip } from "./tooltip";
4
4
  import { cn } from "../lib/cn";
5
5
  import { useKitLabels } from "../i18n/kit-labels";
6
+ import { useLargeText } from "../hooks/use-large-text";
6
7
 
7
8
  // ── Labels ────────────────────────────────────────────────────────────────────
8
9
 
@@ -17,12 +18,17 @@ export interface SignChipLabels {
17
18
  * turns it into — `current` and `next` are the two words above. The other option is
18
19
  * nowhere on screen to be read, so the name has to say both. */
19
20
  direction: (current: string, next: string) => string;
21
+ /** 0.32: what a press does, in words under the chip at Large and Extra large —
22
+ * `next` is the other direction's word ("Switch to Inflow"). The tooltip's half of
23
+ * `direction`, shown, since a fact may not live only in a tooltip there (§4). */
24
+ switchTo: (next: string) => string;
20
25
  }
21
26
 
22
27
  export const DEFAULT_SIGN_CHIP_LABELS: SignChipLabels = {
23
28
  outflow: "Outflow",
24
29
  inflow: "Inflow",
25
30
  direction: (current, next) => `Direction: ${current} — switch to ${next}`,
31
+ switchTo: (next) => `Switch to ${next}`,
26
32
  };
27
33
 
28
34
  export interface SignChipProps {
@@ -79,8 +85,10 @@ export function SignChip({ negative, onNegativeChange, disabled, labels: labelsP
79
85
  const current = negative ? labels.outflow : labels.inflow;
80
86
  const next = negative ? labels.inflow : labels.outflow;
81
87
  const name = labels.direction(current, next);
82
- return (
83
- <Tooltip label={name} lazy>
88
+ // §4: at Large the chip's word is joined by what a press does, as a line under it —
89
+ // and the bubble that said only that goes.
90
+ const large = useLargeText();
91
+ const chip = (
84
92
  <Chip
85
93
  size="lg"
86
94
  tone={negative ? "expense" : "income"}
@@ -91,13 +99,29 @@ export function SignChip({ negative, onNegativeChange, disabled, labels: labelsP
91
99
  // `gap-1.5 px-3`: the chip's narrower body, because on a 375px screen every
92
100
  // pixel of it is taken from the figure beside it (#430). `md:py-2.5` with the
93
101
  // hairline border is the 42px a labelled field measures (#431).
94
- className={cn("shrink-0 gap-1.5 whitespace-nowrap px-3 font-medium md:min-h-0 md:py-2.5", className)}
102
+ className={cn("shrink-0 gap-1.5 whitespace-nowrap px-3 font-medium md:min-h-0 md:py-2.5", !large && className)}
95
103
  >
96
104
  {current}
97
105
  {/* The swap arrows after the word, in the label's own row: decoration (the
98
106
  name already says what a press does), set a little apart from the word. */}
99
107
  <ArrowUpDown className="ms-1.5 inline size-3.5 align-[-0.2em] opacity-60" aria-hidden />
100
108
  </Chip>
101
- </Tooltip>
109
+ );
110
+ if (!large) {
111
+ return (
112
+ <Tooltip label={name} lazy>
113
+ {chip}
114
+ </Tooltip>
115
+ );
116
+ }
117
+ return (
118
+ // The caller's placement (`self-end`…) moves to the pair, which is now the row's item.
119
+ <span data-slot="sign-chip" className={cn("inline-flex shrink-0 flex-col items-start gap-0.5", className)}>
120
+ {chip}
121
+ {/* Hidden from the accessibility tree: the chip's name already says it. */}
122
+ <span aria-hidden className="text-xs text-[var(--text-muted)]">
123
+ {labels.switchTo(next)}
124
+ </span>
125
+ </span>
102
126
  );
103
127
  }
@@ -4,6 +4,7 @@ import { Eraser, Keyboard, PenLine, Undo2 } from "lucide-react";
4
4
  import { cn } from "../lib/cn";
5
5
  import { useAnnounce } from "../hooks/use-announce";
6
6
  import { useKitLabels } from "../i18n/kit-labels";
7
+ import { useTextSize } from "../theme/text-size";
7
8
  import { Button, FIELD_INVALID, Input } from "./ui";
8
9
 
9
10
  /**
@@ -144,7 +145,9 @@ export interface SignaturePadProps extends Omit<ComponentPropsWithoutRef<"div">,
144
145
  exportInk?: string;
145
146
  /** Fill behind the exported PNG. Default transparent. */
146
147
  exportBackground?: string;
147
- /** Base stroke width in CSS pixels. Default 2.5. */
148
+ /** Base stroke width in CSS pixels at Normal text size. Default 2.5. It grows with the
149
+ * text size (× 1.25 / × 1.5, docs/text-size-harmonization.md §10.11), as the pad's
150
+ * rem height does, so a signature keeps its weight on a larger pad. */
148
151
  lineWidth?: number;
149
152
  /** Classes for the canvas — its height, chiefly (default `h-40`). */
150
153
  canvasClassName?: string;
@@ -291,10 +294,13 @@ export const SignaturePad = forwardRef<SignaturePadHandle, SignaturePadProps>(fu
291
294
 
292
295
  // Everything the paint and export paths read that can change between renders, so
293
296
  // the observers below subscribe once instead of on every keystroke.
294
- const opts = useRef({ lineWidth, exportInk, exportBackground });
297
+ // The stroke follows the text size like everything in rem around it (§10.11).
298
+ const { scale: textScale } = useTextSize();
299
+ const strokeWidth = lineWidth * textScale;
300
+ const opts = useRef({ lineWidth: strokeWidth, exportInk, exportBackground });
295
301
  useEffect(() => {
296
- opts.current = { lineWidth, exportInk, exportBackground };
297
- }, [lineWidth, exportInk, exportBackground]);
302
+ opts.current = { lineWidth: strokeWidth, exportInk, exportBackground };
303
+ }, [strokeWidth, exportInk, exportBackground]);
298
304
 
299
305
  const sceneEmpty = () => {
300
306
  const s = scene.current;
@@ -356,10 +362,10 @@ export const SignaturePad = forwardRef<SignaturePadHandle, SignaturePadProps>(fu
356
362
  resize();
357
363
  }, [resize]);
358
364
 
359
- // A changed base width redraws what is already there.
365
+ // A changed base width — or text size — redraws what is already there.
360
366
  useEffect(() => {
361
367
  repaint();
362
- }, [lineWidth, repaint]);
368
+ }, [strokeWidth, repaint]);
363
369
 
364
370
  useEffect(() => {
365
371
  const canvas = canvasRef.current;
@@ -627,7 +633,7 @@ export const SignaturePad = forwardRef<SignaturePadHandle, SignaturePadProps>(fu
627
633
  </div>
628
634
 
629
635
  {hasError && (
630
- <p id={errorId} className="mt-1 text-[11px] leading-tight text-[var(--danger)]">
636
+ <p id={errorId} className="mt-1 text-caption leading-tight text-[var(--danger)]">
631
637
  {error}
632
638
  </p>
633
639
  )}
@@ -70,32 +70,45 @@ export function fromLogPosition(position: number, min: number, max: number, zero
70
70
  // runs the other way too. Firefox draws the fill itself with `::-moz-range-progress`,
71
71
  // which follows the direction on its own.
72
72
  //
73
- // The thumb's `-mt-[5px]` centres a 16px thumb on a 6px track: WebKit lays the thumb
74
- // out from the track's top edge, Firefox centres it, so only one carries the offset.
73
+ // The thumb's `-mt-[0.3125rem]` centres a 1rem thumb on a 0.375rem track — half the
74
+ // difference — in rem since 0.32 (§3.2): the thumb and track grow with the text, and the
75
+ // 5px it was left the thumb low of the track at 125 % and further at 150 %. WebKit lays
76
+ // the thumb out from the track's top edge, Firefox centres it, so only one carries the
77
+ // offset.
75
78
  //
76
79
  // The focus ring goes on the THUMB, not the box: the box is the full width of the
77
80
  // row, and a ring round all of it says "this row is focused" rather than "the handle
78
81
  // you are about to move is". Offset in the surface colour, because the thumb is
79
- // --brand and a --brand ring touching it would be invisible.
82
+ // --brand and a --brand ring touching it would be invisible. Its width is the kit's
83
+ // focus frame (`--focus-ring-width`, §5) — spelt out per engine, since `FOCUS_RING`'s
84
+ // classes cannot carry the pseudo-element.
85
+ //
86
+ // At Large the box is the 48 px touch target (§4) — the track stays centred in it, and
87
+ // the marks row below is pulled up by as much (see `MARKS_LARGE`).
80
88
  const TRACK = [
81
- "block h-6 w-full cursor-pointer appearance-none bg-transparent focus:outline-none disabled:cursor-not-allowed",
89
+ "block h-6 large:h-[48px] w-full cursor-pointer appearance-none bg-transparent focus:outline-none disabled:cursor-not-allowed",
82
90
  // WebKit / Blink
83
91
  "[&::-webkit-slider-runnable-track]:h-1.5 [&::-webkit-slider-runnable-track]:rounded-full",
84
92
  "[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_right,var(--brand)_var(--slider-fill),var(--border-strong)_var(--slider-fill))]",
85
93
  "rtl:[&::-webkit-slider-runnable-track]:bg-[linear-gradient(to_left,var(--brand)_var(--slider-fill),var(--border-strong)_var(--slider-fill))]",
86
- "[&::-webkit-slider-thumb]:-mt-[5px] [&::-webkit-slider-thumb]:size-4 [&::-webkit-slider-thumb]:appearance-none",
94
+ "[&::-webkit-slider-thumb]:-mt-[0.3125rem] [&::-webkit-slider-thumb]:size-4 [&::-webkit-slider-thumb]:appearance-none",
87
95
  "[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-[var(--brand)] [&::-webkit-slider-thumb]:shadow",
88
- "focus-visible:[&::-webkit-slider-thumb]:ring-2 focus-visible:[&::-webkit-slider-thumb]:ring-[var(--brand)]",
96
+ "focus-visible:[&::-webkit-slider-thumb]:ring-[length:var(--focus-ring-width)] focus-visible:[&::-webkit-slider-thumb]:ring-[var(--brand)]",
89
97
  "focus-visible:[&::-webkit-slider-thumb]:ring-offset-2 focus-visible:[&::-webkit-slider-thumb]:ring-offset-[var(--bg-surface)]",
90
98
  // Firefox
91
99
  "[&::-moz-range-track]:h-1.5 [&::-moz-range-track]:rounded-full [&::-moz-range-track]:bg-[var(--border-strong)]",
92
100
  "[&::-moz-range-progress]:h-1.5 [&::-moz-range-progress]:rounded-full [&::-moz-range-progress]:bg-[var(--brand)]",
93
101
  "[&::-moz-range-thumb]:size-4 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-0",
94
102
  "[&::-moz-range-thumb]:bg-[var(--brand)] [&::-moz-range-thumb]:shadow",
95
- "focus-visible:[&::-moz-range-thumb]:ring-2 focus-visible:[&::-moz-range-thumb]:ring-[var(--brand)]",
103
+ "focus-visible:[&::-moz-range-thumb]:ring-[length:var(--focus-ring-width)] focus-visible:[&::-moz-range-thumb]:ring-[var(--brand)]",
96
104
  "focus-visible:[&::-moz-range-thumb]:ring-offset-2 focus-visible:[&::-moz-range-thumb]:ring-offset-[var(--bg-surface)]",
97
105
  ].join(" ");
98
106
 
107
+ // The marks row sits `-mt-1.5` under a 1.5rem box, tucked against the track. In the 48 px
108
+ // box at Large the track's lower edge is `(48px + 0.375rem) / 2` down, so the row comes
109
+ // up by `(48px − 0.375rem) / 2` less the same 0.1875rem gap: `24px − 0.375rem`.
110
+ const MARKS_LARGE = "large:-mt-[calc(24px-0.375rem)]";
111
+
99
112
  /** A tick under the track. A bare number is a tick with no words. */
100
113
  export interface SliderMark {
101
114
  value: number;
@@ -293,7 +306,7 @@ export const Slider = forwardRef<HTMLInputElement, SliderProps>(function Slider(
293
306
  // without a `translate` that would need flipping for right-to-left.
294
307
  <div
295
308
  aria-hidden
296
- className={cn("relative mx-2 -mt-1.5", hasMarkLabels ? "h-5" : "h-1.5")}
309
+ className={cn("relative mx-2 -mt-1.5", MARKS_LARGE, hasMarkLabels ? "h-5" : "h-1.5")}
297
310
  >
298
311
  {normalizedMarks.map((m) => (
299
312
  <span
@@ -303,7 +316,7 @@ export const Slider = forwardRef<HTMLInputElement, SliderProps>(function Slider(
303
316
  >
304
317
  <span className="h-1.5 w-px shrink-0 bg-[var(--border-strong)]" />
305
318
  {m.label !== undefined && (
306
- <span className="mt-0.5 select-none whitespace-nowrap text-[11px] leading-tight text-[var(--text-muted)]">
319
+ <span className="mt-0.5 select-none whitespace-nowrap text-caption leading-tight text-[var(--text-muted)]">
307
320
  {m.label}
308
321
  </span>
309
322
  )}
@@ -1,6 +1,7 @@
1
1
  import type { ComponentPropsWithoutRef } from "react";
2
2
  import { cn } from "../lib/cn";
3
3
  import { useKitLabels, useKitLocale } from "../i18n/kit-labels";
4
+ import { useTextSize } from "../theme/text-size";
4
5
 
5
6
  /**
6
7
  * The words a sparkline speaks. It has no axes, no tooltip and no legend, so its
@@ -78,8 +79,12 @@ export interface SparklineProps
78
79
  /** The series, oldest first. `null`/`undefined`/`NaN` is a GAP — the line breaks
79
80
  * there rather than drawing a zero or bridging across the missing point. */
80
81
  data: ReadonlyArray<number | null | undefined>;
81
- /** Width in px. Ignored under `fluid`. */
82
+ /** Width in px at Normal. Ignored under `fluid`. The drawn box is this × the text
83
+ * size's scale (0.32, docs/text-size-harmonization.md §3.2): a sparkline stands beside
84
+ * a figure, and a 72 × 24 trend under a 150 % number reads as a speck. The strokes
85
+ * stay px (`non-scaling-stroke`), as every chart's do. */
82
86
  width?: number;
87
+ /** Height in px at Normal, × the scale likewise. */
83
88
  height?: number;
84
89
  /** Fill the container's width instead of a fixed one (the height stays fixed). */
85
90
  fluid?: boolean;
@@ -182,6 +187,7 @@ export function Sparkline({
182
187
  ...rest
183
188
  }: SparklineProps) {
184
189
  const text = useKitLabels("sparkline", DEFAULT_SPARKLINE_LABELS, labels);
190
+ const { scale } = useTextSize();
185
191
  const kitLocale = useKitLocale(locale);
186
192
  const format = formatValue ?? defaultFormat(kitLocale);
187
193
 
@@ -252,8 +258,10 @@ export function Sparkline({
252
258
  role="img"
253
259
  aria-label={name}
254
260
  {...rest}
255
- width={fluid ? "100%" : W}
256
- height={H}
261
+ // The drawing stays in its own units (the viewBox); only the box it is shown in
262
+ // grows, uniformly, so nothing is distorted and the strokes keep their px width.
263
+ width={fluid ? "100%" : W * scale}
264
+ height={H * scale}
257
265
  viewBox={`0 0 ${W} ${H}`}
258
266
  preserveAspectRatio="none"
259
267
  className={cn(fluid ? "block w-full" : "inline-block shrink-0 align-middle", "overflow-visible", className)}
@@ -5,6 +5,7 @@ import { cn } from "../lib/cn";
5
5
  import { useKitLabels, useKitLink, useKitLocale } from "../i18n/kit-labels";
6
6
  import { pickLinkRenderer, RenderedKitLink } from "./text-link";
7
7
  import { Card, FieldHint } from "./ui";
8
+ import { useInlineFacts, useLargeText } from "../hooks/use-large-text";
8
9
  import { Sparkline } from "./sparkline";
9
10
  import { Tooltip } from "./tooltip";
10
11
  // The kit's one placeholder look, so a loading tile and the Skeleton list beside it
@@ -151,7 +152,11 @@ export interface StatTileProps
151
152
  /** The explanation behind a "?" beside the label (a {@link FieldHint}) — hidden
152
153
  * until asked for, so it is for what a reader MIGHT want to know ("excludes
153
154
  * transfers between your own accounts"). For a line everyone should read, use
154
- * {@link StatTileProps.description} instead. */
155
+ * {@link StatTileProps.description} instead.
156
+ *
157
+ * 0.32 (docs/text-size-harmonization.md §4 "No fact only in a tooltip"): at Large
158
+ * and Extra large, and on a touch screen, the words are shown under the label
159
+ * instead of behind the "?". */
155
160
  hint?: string;
156
161
  /**
157
162
  * Keep the label to ONE line, cut with an ellipsis, and show the whole of it in a
@@ -169,6 +174,9 @@ export interface StatTileProps
169
174
  * your own `<Tooltip>` for the full text (keksdose's admin metrics-panel.tsx:134
170
175
  * does, from before this prop). A wrapped label shows a bubble even when nothing is
171
176
  * cut, and nests its trigger inside this one's.
177
+ *
178
+ * Ignored at Large and Extra large (0.32, §4): nothing truncates there, and the full
179
+ * label would otherwise be a fact only in a tooltip.
172
180
  */
173
181
  truncateLabel?: boolean;
174
182
  /**
@@ -199,6 +207,15 @@ export interface StatTileProps
199
207
  * Withheld while `loading`, like the sub-values.
200
208
  */
201
209
  projection?: StatTileSubValue;
210
+ /**
211
+ * Smaller figures under the headline, label left and figure right.
212
+ *
213
+ * At Large and Extra large (0.32, §4 "StatTile shows its one big number; the sparkline
214
+ * and sub-values move below"): the tile leads with the headline and its delta, and the
215
+ * projection, these rows and the sparkline follow beneath the description, each row's
216
+ * label over its figure — a 2-up tile at 150 % is 120 px of text wide, and a label
217
+ * beside a figure there squeezed both.
218
+ */
202
219
  subValues?: StatTileSubValue[];
203
220
  /** Shorthand for a fluid {@link Sparkline} named after the tile and speaking in
204
221
  * the tile's number format. The name is the label's text; see
@@ -310,6 +327,11 @@ export function StatTile({
310
327
  ...rest
311
328
  }: StatTileProps) {
312
329
  const text = useKitLabels("statTile", DEFAULT_STAT_TILE_LABELS, labels);
330
+ // §4: at Large the one big number leads and the rest follows below it; the label
331
+ // never truncates; on touch or at Large the hint is words, not a "?".
332
+ const large = useLargeText();
333
+ const inlineHint = useInlineFacts() && !!hint;
334
+ if (large) truncateLabel = false;
313
335
  // A loading StatTileGrid puts every tile in it into the loading state and says
314
336
  // "Loading…" ONCE for all of them; the tile then keeps its own sentence to itself
315
337
  // (see StatTileGrid's `loading`).
@@ -342,7 +364,9 @@ export function StatTile({
342
364
  const stretched = cn(
343
365
  "text-start uppercase tracking-wide",
344
366
  "after:absolute after:inset-0 after:rounded-lg after:content-['']",
345
- "focus-visible:outline-none focus-visible:after:ring-2 focus-visible:after:ring-inset focus-visible:after:ring-[var(--brand)]",
367
+ // The kit's focus frame (0.32, §5), on the overlay — `FOCUS_RING`'s classes cannot
368
+ // carry the `after:`, so its width is spelt out.
369
+ "focus-visible:outline-none focus-visible:after:ring-[length:var(--focus-ring-width)] focus-visible:after:ring-inset focus-visible:after:ring-[var(--brand)]",
346
370
  );
347
371
  const describedBy = d ? `${valueId} ${deltaId}` : valueId;
348
372
  let labelNode: ReactNode = label;
@@ -417,7 +441,7 @@ export function StatTile({
417
441
  {!gridLoading && <span className="sr-only">{text.loading}</span>}
418
442
  </span>
419
443
  ) : hasValue ? (
420
- <span id={valueId} data-private={priv} className={cn(valueClass, valueLabel != null && "ms-auto")}>
444
+ <span id={valueId} data-private={priv} className={cn(valueClass, valueLabel != null && !large && "ms-auto")}>
421
445
  {show(value)}
422
446
  {unit != null && (
423
447
  <span className="ms-1 text-[0.7em] font-medium text-[var(--text-muted)]">{unit}</span>
@@ -480,7 +504,7 @@ export function StatTile({
480
504
  </span>
481
505
  )}
482
506
  {/* Above the stretched link's overlay, so it stays hoverable and focusable. */}
483
- {hint && <FieldHint label={hint} side="top" className="relative z-10 shrink-0" />}
507
+ {hint && !inlineHint && <FieldHint label={hint} side="top" className="relative z-10 shrink-0" />}
484
508
  </div>
485
509
  {icon != null && (
486
510
  <span aria-hidden className="shrink-0 text-[var(--text-muted)] [&_svg]:size-4">
@@ -489,10 +513,19 @@ export function StatTile({
489
513
  )}
490
514
  </div>
491
515
 
516
+ {inlineHint && (
517
+ // §4: the hint as words under the label — the same muted type as `description`,
518
+ // in the reading case of a sentence rather than the label's capitals.
519
+ <p data-slot="stat-tile-hint" className="mt-0.5 text-xs text-[var(--text-muted)]">
520
+ {hint}
521
+ </p>
522
+ )}
523
+
492
524
  {valueLabel != null ? (
493
525
  // Period-left / value-right, matching the sub-rows below it. flex-wrap lets a
494
- // too-long amount drop to its own end-aligned line instead of overflowing.
495
- <div className="mt-1 flex flex-wrap items-baseline gap-x-1.5">
526
+ // too-long amount drop to its own end-aligned line instead of overflowing. At
527
+ // Large the period goes over the figure, which then has the tile's width.
528
+ <div className={cn("mt-1 flex items-baseline gap-x-1.5", large ? "flex-col items-start" : "flex-wrap")}>
496
529
  <span className="shrink-0 text-xs uppercase tracking-wide text-[var(--text-muted)]">{valueLabel}</span>
497
530
  {headline}
498
531
  </div>
@@ -500,7 +533,9 @@ export function StatTile({
500
533
  <div className="mt-1">{headline}</div>
501
534
  )}
502
535
 
503
- {!loading && projection && (
536
+ {/* At Large the delta and description follow the figure at once, and the
537
+ projection moves down with the other figures (see `subValues`). */}
538
+ {!large && !loading && projection && (
504
539
  <dl className="mt-0.5">
505
540
  <FigureRow figure={projection} tileTone={tone} show={show} priv={priv} />
506
541
  </dl>
@@ -508,16 +543,25 @@ export function StatTile({
508
543
 
509
544
  {deltaNode}
510
545
  {description != null && <div className="mt-1 text-xs text-[var(--text-muted)]">{description}</div>}
511
- {graphic && <div className="mt-2">{graphic}</div>}
546
+ {!large && graphic && <div className="mt-2">{graphic}</div>}
512
547
 
513
- {!loading && subValues && subValues.length > 0 && (
514
- <dl className="mt-1.5 space-y-0.5">
515
- {subValues.map((sv, i) => (
516
- <FigureRow key={i} figure={sv} tileTone={tone} show={show} priv={priv} />
548
+ {!loading && ((large && projection) || (subValues && subValues.length > 0)) && (
549
+ <dl data-slot="stat-tile-figures" className={cn("mt-1.5", large ? "space-y-1.5" : "space-y-0.5")}>
550
+ {large && projection && (
551
+ <FigureRow figure={projection} tileTone={tone} show={show} priv={priv} stacked />
552
+ )}
553
+ {subValues?.map((sv, i) => (
554
+ <FigureRow key={i} figure={sv} tileTone={tone} show={show} priv={priv} stacked={large} />
517
555
  ))}
518
556
  </dl>
519
557
  )}
520
558
 
559
+ {large && graphic && (
560
+ <div data-slot="stat-tile-graphic" className="mt-2">
561
+ {graphic}
562
+ </div>
563
+ )}
564
+
521
565
  {footer != null && <div className="mt-2">{footer}</div>}
522
566
  </Card>
523
567
  );
@@ -529,11 +573,14 @@ function FigureRow({
529
573
  tileTone,
530
574
  show,
531
575
  priv,
576
+ stacked = false,
532
577
  }: {
533
578
  figure: StatTileSubValue;
534
579
  tileTone: StatTileTone;
535
580
  show: (v: ReactNode) => ReactNode;
536
581
  priv: "" | undefined;
582
+ /** The label over the figure (Large, §4) instead of beside it. */
583
+ stacked?: boolean;
537
584
  }) {
538
585
  const own = figure.tone ?? (tileTone === "neutral" ? undefined : tileTone);
539
586
  const svTone = own === "none" ? undefined : own;
@@ -543,11 +590,20 @@ function FigureRow({
543
590
  // the period it belongs to. Now the label breaks within itself and the amount stays
544
591
  // on the label's first line, end-aligned like every other row.
545
592
  return (
546
- <div className="flex items-baseline gap-x-2 text-xs tabular-nums text-[var(--text-muted)]">
593
+ <div
594
+ className={cn(
595
+ "flex text-xs tabular-nums text-[var(--text-muted)]",
596
+ stacked ? "flex-col items-start" : "items-baseline gap-x-2",
597
+ )}
598
+ >
547
599
  <dt className="min-w-0 uppercase tracking-wide [overflow-wrap:anywhere]">{figure.label}</dt>
548
600
  <dd
549
601
  data-private={priv}
550
- className={cn("ms-auto shrink-0 whitespace-nowrap", svTone && [toneClass(svTone, figure.value), "opacity-75"])}
602
+ className={cn(
603
+ "shrink-0 whitespace-nowrap",
604
+ !stacked && "ms-auto",
605
+ svTone && [toneClass(svTone, figure.value), "opacity-75"],
606
+ )}
551
607
  >
552
608
  {show(figure.value)}
553
609
  </dd>
@@ -66,6 +66,28 @@ export function statusDotColor(tone: StatusDotTone): string {
66
66
 
67
67
  const SIZE: Record<StatusDotSize, string> = { sm: "size-2", md: "size-2.5", lg: "size-3" };
68
68
 
69
+ /**
70
+ * A labelled dot at Large and Extra large (0.32.1, keksdose's 0.32 report;
71
+ * docs/text-size-harmonization.md §4 "nothing truncates"): the label wraps instead of
72
+ * ending in "…", so a legend entry or a status keeps its last word, the one that tells
73
+ * two states apart. The dot then sits on the label's FIRST line rather than halfway down
74
+ * the block: the row aligns to the top and the dot moves down by half of what one line
75
+ * (`1lh`, the label's own line height, which the dot inherits) leaves around it.
76
+ * `large:` classes, so Normal keeps its one centred line.
77
+ *
78
+ * `break-words`, not `[overflow-wrap:anywhere]`: a legend often sits in a table, and
79
+ * `anywhere` lowers the label's min-content width to one letter, so an auto-sized column
80
+ * squeezed it to a letter per line (the showcase's tone table at 360 px, Extra large).
81
+ * `break-word` keeps each word whole wherever the width is the content's to choose, and
82
+ * still breaks one that cannot fit its line at all.
83
+ */
84
+ const LABEL_WRAP_AT_LARGE = "large:whitespace-normal large:break-words";
85
+ const DOT_ON_FIRST_LINE: Record<StatusDotSize, string> = {
86
+ sm: "large:mt-[calc((1lh_-_0.5rem)/2)]",
87
+ md: "large:mt-[calc((1lh_-_0.625rem)/2)]",
88
+ lg: "large:mt-[calc((1lh_-_0.75rem)/2)]",
89
+ };
90
+
69
91
  export interface StatusDotProps extends Omit<ComponentPropsWithoutRef<"span">, "children"> {
70
92
  tone?: StatusDotTone;
71
93
  size?: StatusDotSize;
@@ -116,6 +138,7 @@ export function StatusDot({
116
138
  SIZE[size],
117
139
  FILL[tone],
118
140
  ring && "ring-2 ring-[var(--bg-surface)]",
141
+ label != null && DOT_ON_FIRST_LINE[size],
119
142
  label == null && className,
120
143
  dotClassName,
121
144
  )}
@@ -130,9 +153,9 @@ export function StatusDot({
130
153
  return (
131
154
  // No `aria-label` here: the visible label is the text, and a name on a role-less
132
155
  // span is one ARIA forbids and screen readers ignore.
133
- <span {...rest} className={cn("inline-flex min-w-0 items-center gap-1.5 text-sm", className)}>
156
+ <span {...rest} className={cn("inline-flex min-w-0 items-center gap-1.5 text-sm large:items-start", className)}>
134
157
  {dot}
135
- <span className="min-w-0 truncate">{label}</span>
158
+ <span className={cn("min-w-0 truncate", LABEL_WRAP_AT_LARGE)}>{label}</span>
136
159
  </span>
137
160
  );
138
161
  }
@@ -1,6 +1,7 @@
1
1
  import { useEffect, useRef, useState } from "react";
2
2
  import type { ReactNode } from "react";
3
3
  import { cn } from "../lib/cn";
4
+ import { FOCUS_RING } from "./focus-ring";
4
5
  import { useRowSwipe, type SwipeStage } from "../hooks/use-row-swipe";
5
6
  import { DEFAULT_SWIPEABLE_ROW_LABELS, useKitLabels } from "../i18n/kit-labels";
6
7
 
@@ -268,9 +269,16 @@ export function SwipeableRow({
268
269
  type="button"
269
270
  onClick={action.onCommit}
270
271
  className={cn(
271
- "sr-only whitespace-nowrap rounded-md border border-[var(--border)] bg-[var(--bg-surface)] px-2 py-1 text-xs font-medium text-[var(--text-primary)] shadow-sm",
272
+ "sr-only whitespace-nowrap rounded-md border-[var(--border)] bg-[var(--bg-surface)] text-xs font-medium text-[var(--text-primary)] shadow-sm",
272
273
  "focus:not-sr-only focus:pointer-events-auto focus:inline-flex focus:items-center focus:gap-1.5",
273
- "focus-visible:ring-2 focus-visible:ring-[var(--brand)]",
274
+ // The box's padding and border only once it shows (0.32.1, keksdose's
275
+ // 0.32 report). Unconditional, `px-2` and `border` beat `sr-only`'s
276
+ // `padding: 0` and `border-width: 0`, so the hidden button was a 1 px
277
+ // box with 2 × 0.5rem of padding round it: 26 px at Extra large, running
278
+ // past the row's end from the strip's start — invisible under its clip,
279
+ // but counted in the page's scroll width (§4: nothing overflows).
280
+ "focus:border focus:px-2 focus:py-1",
281
+ FOCUS_RING,
274
282
  )}
275
283
  >
276
284
  {/* The label is the button's accessible name, so the caller's icon is