@eifi1/ui-kit 0.51.6 → 0.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (805) hide show
  1. package/README.md +146 -26
  2. package/dist/account/account-parts.d.ts +10 -8
  3. package/dist/account/account-parts.js +1 -18
  4. package/dist/account/account-parts.js.map +1 -1
  5. package/dist/account/data-export-setting-labels.js +1 -1
  6. package/dist/account/data-export-setting-labels.js.map +1 -1
  7. package/dist/account/delete-account-setting-labels.js +1 -1
  8. package/dist/account/delete-account-setting-labels.js.map +1 -1
  9. package/dist/account/email-change-setting-labels.js +1 -1
  10. package/dist/account/email-change-setting-labels.js.map +1 -1
  11. package/dist/account/passkeys-setting.d.ts +9 -2
  12. package/dist/account/passkeys-setting.js +41 -29
  13. package/dist/account/passkeys-setting.js.map +1 -1
  14. package/dist/account/sessions-setting.d.ts +3 -2
  15. package/dist/account/sessions-setting.js +10 -8
  16. package/dist/account/sessions-setting.js.map +1 -1
  17. package/dist/admin/admin-action-confirm.js +3 -7
  18. package/dist/admin/admin-action-confirm.js.map +1 -1
  19. package/dist/admin/admin-parts.d.ts +6 -3
  20. package/dist/admin/admin-parts.js +6 -21
  21. package/dist/admin/admin-parts.js.map +1 -1
  22. package/dist/admin/mail-test-card-labels.js +1 -1
  23. package/dist/admin/mail-test-card-labels.js.map +1 -1
  24. package/dist/admin/plan-change-labels.d.ts +2 -2
  25. package/dist/admin/plan-change-labels.js +1 -17
  26. package/dist/admin/plan-change-labels.js.map +1 -1
  27. package/dist/admin/plan-change.d.ts +3 -42
  28. package/dist/admin/plan-change.js +1 -1
  29. package/dist/admin/plan-change.js.map +1 -1
  30. package/dist/admin/reviewer-scope-editor.js +3 -3
  31. package/dist/admin/reviewer-scope-editor.js.map +1 -1
  32. package/dist/auth/auth-errors-labels.d.ts +11 -0
  33. package/dist/auth/auth-errors-labels.js +13 -0
  34. package/dist/auth/auth-errors-labels.js.map +1 -0
  35. package/dist/auth/auth-errors.d.ts +7 -23
  36. package/dist/auth/auth-errors.js +2 -15
  37. package/dist/auth/auth-errors.js.map +1 -1
  38. package/dist/auth/complete-name-dialog.d.ts +3 -2
  39. package/dist/auth/complete-name-dialog.js +3 -5
  40. package/dist/auth/complete-name-dialog.js.map +1 -1
  41. package/dist/auth/forgot-password-form-labels.js +1 -1
  42. package/dist/auth/forgot-password-form-labels.js.map +1 -1
  43. package/dist/auth/forgot-password-form.js +7 -2
  44. package/dist/auth/forgot-password-form.js.map +1 -1
  45. package/dist/auth/register-form-labels.js +1 -1
  46. package/dist/auth/register-form-labels.js.map +1 -1
  47. package/dist/auth/reset-password-form-labels.js +1 -1
  48. package/dist/auth/reset-password-form-labels.js.map +1 -1
  49. package/dist/auth/reset-password-form.js +5 -1
  50. package/dist/auth/reset-password-form.js.map +1 -1
  51. package/dist/auth/sign-in-form-labels.js +1 -1
  52. package/dist/auth/sign-in-form-labels.js.map +1 -1
  53. package/dist/auth/status-parts.d.ts +0 -3
  54. package/dist/auth/status-parts.js +0 -4
  55. package/dist/auth/status-parts.js.map +1 -1
  56. package/dist/auth/verify-email-labels.js +1 -1
  57. package/dist/auth/verify-email-labels.js.map +1 -1
  58. package/dist/auth/verify-email.js +7 -2
  59. package/dist/auth/verify-email.js.map +1 -1
  60. package/dist/billing/cancel-request.d.ts +11 -2
  61. package/dist/billing/cancel-request.js +15 -3
  62. package/dist/billing/cancel-request.js.map +1 -1
  63. package/dist/billing/cancel-subscription.d.ts +22 -10
  64. package/dist/billing/cancel-subscription.js +8 -11
  65. package/dist/billing/cancel-subscription.js.map +1 -1
  66. package/dist/billing/dialog-close.d.ts +29 -0
  67. package/dist/billing/dialog-close.js +8 -0
  68. package/dist/billing/dialog-close.js.map +1 -0
  69. package/dist/billing/plan-card.d.ts +14 -4
  70. package/dist/billing/plan-card.js +15 -8
  71. package/dist/billing/plan-card.js.map +1 -1
  72. package/dist/billing/plan-change-labels.d.ts +42 -0
  73. package/dist/billing/plan-change-labels.js +22 -0
  74. package/dist/billing/plan-change-labels.js.map +1 -0
  75. package/dist/billing/plan-switch.d.ts +21 -9
  76. package/dist/billing/plan-switch.js +10 -8
  77. package/dist/billing/plan-switch.js.map +1 -1
  78. package/dist/chart.d.ts +12 -0
  79. package/dist/chart.js +16 -1
  80. package/dist/chart.js.map +1 -1
  81. package/dist/components/account-chips.d.ts +5 -5
  82. package/dist/components/account-chips.js +11 -13
  83. package/dist/components/account-chips.js.map +1 -1
  84. package/dist/components/alert-banner.d.ts +16 -5
  85. package/dist/components/alert-banner.js +46 -1
  86. package/dist/components/alert-banner.js.map +1 -1
  87. package/dist/components/amount-input.d.ts +22 -4
  88. package/dist/components/amount-input.js +3 -3
  89. package/dist/components/amount-input.js.map +1 -1
  90. package/dist/components/autocomplete.js +57 -65
  91. package/dist/components/autocomplete.js.map +1 -1
  92. package/dist/components/bulk-action-bar.d.ts +12 -2
  93. package/dist/components/bulk-action-bar.js +65 -21
  94. package/dist/components/bulk-action-bar.js.map +1 -1
  95. package/dist/components/button-look.d.ts +5 -5
  96. package/dist/components/button-look.js.map +1 -1
  97. package/dist/components/button.d.ts +2 -2
  98. package/dist/components/button.js.map +1 -1
  99. package/dist/components/calculator.d.ts +21 -2
  100. package/dist/components/calculator.js +53 -14
  101. package/dist/components/calculator.js.map +1 -1
  102. package/dist/components/chart-edge.d.ts +16 -0
  103. package/dist/components/chart-edge.js +14 -1
  104. package/dist/components/chart-edge.js.map +1 -1
  105. package/dist/components/chart-figure.d.ts +13 -0
  106. package/dist/components/chart-figure.js +15 -0
  107. package/dist/components/chart-figure.js.map +1 -0
  108. package/dist/components/chart-zoom-core.js +1 -4
  109. package/dist/components/chart-zoom-core.js.map +1 -1
  110. package/dist/components/chart.d.ts +8 -1
  111. package/dist/components/chart.js +19 -10
  112. package/dist/components/chart.js.map +1 -1
  113. package/dist/components/combobox-core.d.ts +119 -7
  114. package/dist/components/combobox-core.js +151 -46
  115. package/dist/components/combobox-core.js.map +1 -1
  116. package/dist/components/combobox.d.ts +1 -1
  117. package/dist/components/combobox.js +142 -131
  118. package/dist/components/combobox.js.map +1 -1
  119. package/dist/components/copy-button.d.ts +6 -5
  120. package/dist/components/copy-button.js +5 -3
  121. package/dist/components/copy-button.js.map +1 -1
  122. package/dist/components/country-select.js +2 -2
  123. package/dist/components/country-select.js.map +1 -1
  124. package/dist/components/data-table-column-settings.d.ts +1 -1
  125. package/dist/components/data-table-column-settings.js +33 -7
  126. package/dist/components/data-table-column-settings.js.map +1 -1
  127. package/dist/components/data-table-filters.d.ts +4 -2
  128. package/dist/components/data-table-filters.js +2 -2
  129. package/dist/components/data-table-filters.js.map +1 -1
  130. package/dist/components/data-table-fit.d.ts +6 -4
  131. package/dist/components/data-table-fit.js +4 -1
  132. package/dist/components/data-table-fit.js.map +1 -1
  133. package/dist/components/data-table-groups.d.ts +1 -1
  134. package/dist/components/data-table-groups.js.map +1 -1
  135. package/dist/components/data-table-head.d.ts +1 -1
  136. package/dist/components/data-table-head.js +15 -12
  137. package/dist/components/data-table-head.js.map +1 -1
  138. package/dist/components/data-table-mobile.d.ts +36 -7
  139. package/dist/components/data-table-mobile.js +63 -31
  140. package/dist/components/data-table-mobile.js.map +1 -1
  141. package/dist/components/data-table-pagination.js +11 -6
  142. package/dist/components/data-table-pagination.js.map +1 -1
  143. package/dist/components/data-table-resize.d.ts +1 -1
  144. package/dist/components/data-table-resize.js.map +1 -1
  145. package/dist/components/data-table-row-actions.d.ts +2 -2
  146. package/dist/components/data-table-row-actions.js.map +1 -1
  147. package/dist/components/data-table-row.d.ts +6 -2
  148. package/dist/components/data-table-row.js +17 -10
  149. package/dist/components/data-table-row.js.map +1 -1
  150. package/dist/components/data-table-selection.d.ts +1 -1
  151. package/dist/components/data-table-selection.js.map +1 -1
  152. package/dist/components/data-table-shared.d.ts +10 -2
  153. package/dist/components/data-table-shared.js +18 -0
  154. package/dist/components/data-table-shared.js.map +1 -1
  155. package/dist/components/data-table-sort.d.ts +21 -2
  156. package/dist/components/data-table-sort.js +24 -0
  157. package/dist/components/data-table-sort.js.map +1 -1
  158. package/dist/components/data-table-virtual.d.ts +1 -1
  159. package/dist/components/data-table-virtual.js +18 -6
  160. package/dist/components/data-table-virtual.js.map +1 -1
  161. package/dist/components/data-table.d.ts +25 -8
  162. package/dist/components/data-table.js +154 -25
  163. package/dist/components/data-table.js.map +1 -1
  164. package/dist/components/date-field.d.ts +24 -2
  165. package/dist/components/date-field.js +33 -8
  166. package/dist/components/date-field.js.map +1 -1
  167. package/dist/components/date-picker.d.ts +15 -2
  168. package/dist/components/date-picker.js +55 -26
  169. package/dist/components/date-picker.js.map +1 -1
  170. package/dist/components/date-range-picker.d.ts +47 -20
  171. package/dist/components/date-range-picker.js +23 -7
  172. package/dist/components/date-range-picker.js.map +1 -1
  173. package/dist/components/dialog-frame.d.ts +2 -1
  174. package/dist/components/dialog-frame.js.map +1 -1
  175. package/dist/components/entity-combobox.js +4 -2
  176. package/dist/components/entity-combobox.js.map +1 -1
  177. package/dist/components/error-boundary.js +37 -30
  178. package/dist/components/error-boundary.js.map +1 -1
  179. package/dist/components/{ui-labels.d.ts → field-base-labels.d.ts} +0 -2
  180. package/dist/components/{ui-labels.js → field-base-labels.js} +2 -9
  181. package/dist/components/field-base-labels.js.map +1 -0
  182. package/dist/components/field-base.d.ts +4 -3
  183. package/dist/components/field-base.js +3 -3
  184. package/dist/components/field-base.js.map +1 -1
  185. package/dist/components/field-sync-labels.d.ts +1 -0
  186. package/dist/components/field-sync-labels.js.map +1 -1
  187. package/dist/components/field-sync.d.ts +23 -1
  188. package/dist/components/field-sync.js.map +1 -1
  189. package/dist/components/form-actions.js +11 -5
  190. package/dist/components/form-actions.js.map +1 -1
  191. package/dist/components/hover-menu.d.ts +3 -0
  192. package/dist/components/hover-menu.js +5 -3
  193. package/dist/components/hover-menu.js.map +1 -1
  194. package/dist/components/icon-button.js +14 -9
  195. package/dist/components/icon-button.js.map +1 -1
  196. package/dist/components/inline-confirm.d.ts +43 -0
  197. package/dist/components/inline-confirm.js +67 -0
  198. package/dist/components/inline-confirm.js.map +1 -0
  199. package/dist/components/inline-entity-combobox.d.ts +4 -3
  200. package/dist/components/inline-entity-combobox.js +150 -141
  201. package/dist/components/inline-entity-combobox.js.map +1 -1
  202. package/dist/components/input.js +1 -1
  203. package/dist/components/input.js.map +1 -1
  204. package/dist/components/jump-calendar.js +28 -112
  205. package/dist/components/jump-calendar.js.map +1 -1
  206. package/dist/components/legal-page.d.ts +3 -1
  207. package/dist/components/legal-page.js +3 -2
  208. package/dist/components/legal-page.js.map +1 -1
  209. package/dist/components/legal.d.ts +4 -2
  210. package/dist/components/legal.js.map +1 -1
  211. package/dist/components/lightbox.d.ts +2 -2
  212. package/dist/components/lightbox.js +17 -6
  213. package/dist/components/lightbox.js.map +1 -1
  214. package/dist/components/list.d.ts +6 -2
  215. package/dist/components/list.js +4 -3
  216. package/dist/components/list.js.map +1 -1
  217. package/dist/components/measured-grid.d.ts +1 -1
  218. package/dist/components/measured-grid.js +2 -1
  219. package/dist/components/measured-grid.js.map +1 -1
  220. package/dist/components/mini-calendar.js +3 -5
  221. package/dist/components/mini-calendar.js.map +1 -1
  222. package/dist/components/modal.d.ts +24 -0
  223. package/dist/components/modal.js +12 -4
  224. package/dist/components/modal.js.map +1 -1
  225. package/dist/components/money-draft.js +7 -5
  226. package/dist/components/money-draft.js.map +1 -1
  227. package/dist/components/money-field.d.ts +2 -2
  228. package/dist/components/money-field.js.map +1 -1
  229. package/dist/components/month-grid.d.ts +55 -0
  230. package/dist/components/month-grid.js +148 -0
  231. package/dist/components/month-grid.js.map +1 -0
  232. package/dist/components/month-picker.d.ts +36 -4
  233. package/dist/components/month-picker.js +123 -146
  234. package/dist/components/month-picker.js.map +1 -1
  235. package/dist/components/multi-entity-combobox.js +2 -1
  236. package/dist/components/multi-entity-combobox.js.map +1 -1
  237. package/dist/components/multi-select.d.ts +2 -2
  238. package/dist/components/multi-select.js +11 -6
  239. package/dist/components/multi-select.js.map +1 -1
  240. package/dist/components/number-field.d.ts +6 -4
  241. package/dist/components/number-field.js +3 -2
  242. package/dist/components/number-field.js.map +1 -1
  243. package/dist/components/number-input.d.ts +4 -1
  244. package/dist/components/number-input.js +3 -2
  245. package/dist/components/number-input.js.map +1 -1
  246. package/dist/components/numpad-sheet.js.map +1 -1
  247. package/dist/components/picker-sheet.js +2 -1
  248. package/dist/components/picker-sheet.js.map +1 -1
  249. package/dist/components/pie-chart-labels.d.ts +7 -0
  250. package/dist/components/pie-chart-labels.js +1 -0
  251. package/dist/components/pie-chart-labels.js.map +1 -1
  252. package/dist/components/pie-chart.d.ts +5 -3
  253. package/dist/components/pie-chart.js +7 -22
  254. package/dist/components/pie-chart.js.map +1 -1
  255. package/dist/components/popover.d.ts +3 -0
  256. package/dist/components/popover.js +7 -1
  257. package/dist/components/popover.js.map +1 -1
  258. package/dist/components/reauth-dialog.d.ts +4 -5
  259. package/dist/components/reauth-dialog.js +1 -4
  260. package/dist/components/reauth-dialog.js.map +1 -1
  261. package/dist/components/row-actions.js +2 -1
  262. package/dist/components/row-actions.js.map +1 -1
  263. package/dist/components/section-nav.d.ts +7 -0
  264. package/dist/components/section-nav.js.map +1 -1
  265. package/dist/components/series-chart-axes.d.ts +10 -3
  266. package/dist/components/series-chart-axes.js +1 -0
  267. package/dist/components/series-chart-axes.js.map +1 -1
  268. package/dist/components/series-chart-labels.d.ts +7 -4
  269. package/dist/components/series-chart-labels.js.map +1 -1
  270. package/dist/components/series-chart.d.ts +31 -7
  271. package/dist/components/series-chart.js +72 -29
  272. package/dist/components/series-chart.js.map +1 -1
  273. package/dist/components/share-card.js +3 -3
  274. package/dist/components/share-card.js.map +1 -1
  275. package/dist/components/sign-chip-labels.d.ts +1 -0
  276. package/dist/components/sign-chip-labels.js.map +1 -1
  277. package/dist/components/sign-chip.d.ts +10 -1
  278. package/dist/components/sign-chip.js.map +1 -1
  279. package/dist/components/tabs-labels.d.ts +2 -0
  280. package/dist/components/tabs-labels.js +11 -0
  281. package/dist/components/tabs-labels.js.map +1 -0
  282. package/dist/components/tabs.d.ts +1 -1
  283. package/dist/components/tabs.js +13 -11
  284. package/dist/components/tabs.js.map +1 -1
  285. package/dist/components/toggle-legend.d.ts +2 -2
  286. package/dist/components/toggle-legend.js +6 -6
  287. package/dist/components/toggle-legend.js.map +1 -1
  288. package/dist/components/translation-review-editor.d.ts +4 -2
  289. package/dist/components/translation-review-editor.js +2 -3
  290. package/dist/components/translation-review-editor.js.map +1 -1
  291. package/dist/components/translation-review.d.ts +2 -1
  292. package/dist/components/translation-review.js +2 -2
  293. package/dist/components/translation-review.js.map +1 -1
  294. package/dist/components/treemap-labels.d.ts +26 -0
  295. package/dist/components/treemap-labels.js +10 -0
  296. package/dist/components/treemap-labels.js.map +1 -0
  297. package/dist/components/treemap-layout.d.ts +62 -0
  298. package/dist/components/treemap-layout.js +126 -0
  299. package/dist/components/treemap-layout.js.map +1 -0
  300. package/dist/components/treemap.d.ts +140 -17
  301. package/dist/components/treemap.js +324 -97
  302. package/dist/components/treemap.js.map +1 -1
  303. package/dist/components/use-table-state.d.ts +5 -5
  304. package/dist/components/use-table-state.js +4 -1
  305. package/dist/components/use-table-state.js.map +1 -1
  306. package/dist/data-table.d.ts +6 -2
  307. package/dist/data-table.js +7 -2
  308. package/dist/data-table.js.map +1 -1
  309. package/dist/eslint/index.js +1 -1
  310. package/dist/eslint/role-utilities.d.ts +36 -7
  311. package/dist/eslint/role-utilities.js +42 -9
  312. package/dist/eslint/role-utilities.js.map +1 -1
  313. package/dist/feedback/feedback-dialog.d.ts +25 -16
  314. package/dist/feedback/feedback-dialog.js +6 -2
  315. package/dist/feedback/feedback-dialog.js.map +1 -1
  316. package/dist/feedback/feedback-mutation.d.ts +30 -0
  317. package/dist/feedback/feedback-mutation.js +16 -0
  318. package/dist/feedback/feedback-mutation.js.map +1 -0
  319. package/dist/feedback/feedback-page-link.d.ts +53 -0
  320. package/dist/feedback/feedback-page-link.js +37 -0
  321. package/dist/feedback/feedback-page-link.js.map +1 -0
  322. package/dist/feedback/feedback-public-list.d.ts +12 -3
  323. package/dist/feedback/feedback-public-list.js +2 -1
  324. package/dist/feedback/feedback-public-list.js.map +1 -1
  325. package/dist/feedback/feedback-replies.d.ts +3 -1
  326. package/dist/feedback/feedback-replies.js +5 -4
  327. package/dist/feedback/feedback-replies.js.map +1 -1
  328. package/dist/feedback/feedback-row-detail-labels.js +5 -0
  329. package/dist/feedback/feedback-row-detail-labels.js.map +1 -1
  330. package/dist/feedback/feedback-row-detail.d.ts +64 -28
  331. package/dist/feedback/feedback-row-detail.js +30 -28
  332. package/dist/feedback/feedback-row-detail.js.map +1 -1
  333. package/dist/feedback/feedback-status-undo.d.ts +30 -11
  334. package/dist/feedback/feedback-status-undo.js +10 -15
  335. package/dist/feedback/feedback-status-undo.js.map +1 -1
  336. package/dist/feedback/feedback-submit-dialog.d.ts +1 -1
  337. package/dist/feedback/feedback-submit-dialog.js +1 -1
  338. package/dist/feedback/feedback-submit-dialog.js.map +1 -1
  339. package/dist/feedback/feedback-submit.js +9 -3
  340. package/dist/feedback/feedback-submit.js.map +1 -1
  341. package/dist/feedback/feedback-swipe.d.ts +1 -1
  342. package/dist/feedback/feedback-swipe.js.map +1 -1
  343. package/dist/feedback/feedback-table.d.ts +21 -9
  344. package/dist/feedback/feedback-table.js +45 -25
  345. package/dist/feedback/feedback-table.js.map +1 -1
  346. package/dist/feedback/feedback-thread-labels.d.ts +2 -2
  347. package/dist/feedback/feedback-thread-labels.js.map +1 -1
  348. package/dist/feedback/feedback-thread.d.ts +24 -23
  349. package/dist/feedback/feedback-thread.js +2 -1
  350. package/dist/feedback/feedback-thread.js.map +1 -1
  351. package/dist/feedback.d.ts +34 -0
  352. package/dist/feedback.js +42 -0
  353. package/dist/feedback.js.map +1 -1
  354. package/dist/hooks/use-dismiss.js.map +1 -1
  355. package/dist/hooks/use-focus-trap.d.ts +35 -0
  356. package/dist/hooks/use-focus-trap.js +6 -4
  357. package/dist/hooks/use-focus-trap.js.map +1 -1
  358. package/dist/hooks/use-hotkey.d.ts +5 -2
  359. package/dist/hooks/use-hotkey.js +5 -4
  360. package/dist/hooks/use-hotkey.js.map +1 -1
  361. package/dist/hooks/use-long-press.d.ts +7 -4
  362. package/dist/hooks/use-long-press.js +3 -0
  363. package/dist/hooks/use-long-press.js.map +1 -1
  364. package/dist/hooks/use-media-query.js +12 -4
  365. package/dist/hooks/use-media-query.js.map +1 -1
  366. package/dist/hooks/use-mounted.d.ts +22 -0
  367. package/dist/hooks/use-mounted.js +24 -0
  368. package/dist/hooks/use-mounted.js.map +1 -0
  369. package/dist/hooks/use-overlay-history.d.ts +7 -1
  370. package/dist/hooks/use-overlay-history.js +35 -5
  371. package/dist/hooks/use-overlay-history.js.map +1 -1
  372. package/dist/i18n/defaults.js +4 -5
  373. package/dist/i18n/defaults.js.map +1 -1
  374. package/dist/i18n/german.js +7 -1
  375. package/dist/i18n/german.js.map +1 -1
  376. package/dist/i18n/kit-labels.d.ts +9 -2
  377. package/dist/i18n/kit-labels.js.map +1 -1
  378. package/dist/i18n/locales/en.js +20 -41
  379. package/dist/i18n/locales/en.js.map +3 -3
  380. package/dist/i18n/locales/es.js +7 -1
  381. package/dist/i18n/locales/es.js.map +1 -1
  382. package/dist/i18n/locales/fr.js +20 -10
  383. package/dist/i18n/locales/fr.js.map +1 -1
  384. package/dist/i18n/locales/hu.js +9 -1
  385. package/dist/i18n/locales/hu.js.map +1 -1
  386. package/dist/i18n/locales/it.js +7 -1
  387. package/dist/i18n/locales/it.js.map +1 -1
  388. package/dist/i18n/locales/zh.js +8 -1
  389. package/dist/i18n/locales/zh.js.map +1 -1
  390. package/dist/i18n/review.js +5 -0
  391. package/dist/i18n/review.js.map +1 -1
  392. package/dist/index.d.ts +64 -17
  393. package/dist/index.js +77 -12
  394. package/dist/index.js.map +1 -1
  395. package/dist/landing/routing.d.ts +3 -1
  396. package/dist/landing/routing.js +4 -7
  397. package/dist/landing/routing.js.map +1 -1
  398. package/dist/lib/broadcast.d.ts +17 -0
  399. package/dist/lib/broadcast.js +30 -0
  400. package/dist/lib/broadcast.js.map +1 -0
  401. package/dist/lib/calc.d.ts +7 -1
  402. package/dist/lib/calc.js +3 -1
  403. package/dist/lib/calc.js.map +1 -1
  404. package/dist/lib/clipboard-minus.d.ts +2 -2
  405. package/dist/lib/clipboard-minus.js +1 -1
  406. package/dist/lib/clipboard-minus.js.map +1 -1
  407. package/dist/lib/date-format.d.ts +37 -2
  408. package/dist/lib/date-format.js +34 -8
  409. package/dist/lib/date-format.js.map +1 -1
  410. package/dist/lib/day-format.d.ts +46 -0
  411. package/dist/lib/day-format.js +46 -0
  412. package/dist/lib/day-format.js.map +1 -0
  413. package/dist/lib/decimal-marks.d.ts +7 -1
  414. package/dist/lib/decimal-marks.js +5 -2
  415. package/dist/lib/decimal-marks.js.map +1 -1
  416. package/dist/lib/describe-failure.d.ts +14 -0
  417. package/dist/lib/describe-failure.js +9 -0
  418. package/dist/lib/describe-failure.js.map +1 -0
  419. package/dist/lib/direction.d.ts +16 -0
  420. package/dist/lib/direction.js +9 -1
  421. package/dist/lib/direction.js.map +1 -1
  422. package/dist/lib/focus-left.d.ts +63 -0
  423. package/dist/lib/focus-left.js +67 -0
  424. package/dist/lib/focus-left.js.map +1 -0
  425. package/dist/lib/format.d.ts +5 -3
  426. package/dist/lib/format.js +16 -13
  427. package/dist/lib/format.js.map +1 -1
  428. package/dist/lib/http-status.d.ts +24 -0
  429. package/dist/lib/http-status.js +14 -0
  430. package/dist/lib/http-status.js.map +1 -0
  431. package/dist/lib/intl-cache.d.ts +14 -0
  432. package/dist/lib/intl-cache.js +15 -0
  433. package/dist/lib/intl-cache.js.map +1 -0
  434. package/dist/lib/isin.d.ts +10 -0
  435. package/dist/lib/isin.js.map +1 -1
  436. package/dist/lib/iso-day.d.ts +11 -0
  437. package/dist/lib/iso-day.js +8 -0
  438. package/dist/lib/iso-day.js.map +1 -0
  439. package/dist/lib/lazy-with-fallback.d.ts +31 -0
  440. package/dist/lib/lazy-with-fallback.js +40 -0
  441. package/dist/lib/lazy-with-fallback.js.map +1 -0
  442. package/dist/lib/path-pattern.d.ts +34 -0
  443. package/dist/lib/path-pattern.js +24 -0
  444. package/dist/lib/path-pattern.js.map +1 -0
  445. package/dist/lib/reduced-motion.d.ts +2 -1
  446. package/dist/lib/reduced-motion.js.map +1 -1
  447. package/dist/lib/round.d.ts +2 -1
  448. package/dist/lib/round.js +2 -1
  449. package/dist/lib/round.js.map +1 -1
  450. package/dist/lib/safe-storage.d.ts +24 -5
  451. package/dist/lib/safe-storage.js +27 -2
  452. package/dist/lib/safe-storage.js.map +1 -1
  453. package/dist/lib/session-refresh.js +1 -1
  454. package/dist/lib/session-refresh.js.map +1 -1
  455. package/dist/lib/share-format.d.ts +13 -0
  456. package/dist/lib/share-format.js +10 -0
  457. package/dist/lib/share-format.js.map +1 -0
  458. package/dist/lib/text-case.d.ts +17 -0
  459. package/dist/lib/text-case.js +8 -0
  460. package/dist/lib/text-case.js.map +1 -0
  461. package/dist/lib/text-match.d.ts +38 -0
  462. package/dist/lib/text-match.js +24 -2
  463. package/dist/lib/text-match.js.map +1 -1
  464. package/dist/lib/thenable.d.ts +13 -0
  465. package/dist/lib/thenable.js +8 -0
  466. package/dist/lib/thenable.js.map +1 -0
  467. package/dist/lib/translation-review.d.ts +7 -2
  468. package/dist/lib/translation-review.js +4 -4
  469. package/dist/lib/translation-review.js.map +1 -1
  470. package/dist/notifications/device-zone-report.js +1 -1
  471. package/dist/notifications/device-zone-report.js.map +1 -1
  472. package/dist/notifications/notification-bell.d.ts +2 -1
  473. package/dist/notifications/notification-bell.js +3 -3
  474. package/dist/notifications/notification-bell.js.map +1 -1
  475. package/dist/notifications/notification-inbox.d.ts +10 -6
  476. package/dist/notifications/notification-inbox.js +26 -48
  477. package/dist/notifications/notification-inbox.js.map +1 -1
  478. package/dist/notifications/notification-parts.d.ts +3 -2
  479. package/dist/notifications/notification-parts.js +1 -3
  480. package/dist/notifications/notification-parts.js.map +1 -1
  481. package/dist/notifications/notification-types-setting.js +1 -1
  482. package/dist/notifications/notification-types-setting.js.map +1 -1
  483. package/dist/notifications/notifications-labels.d.ts +6 -0
  484. package/dist/notifications/notifications-labels.js +1 -0
  485. package/dist/notifications/notifications-labels.js.map +1 -1
  486. package/dist/notifications/push-device-setting.js +1 -1
  487. package/dist/notifications/push-device-setting.js.map +1 -1
  488. package/dist/notifications/push-devices-setting.d.ts +2 -1
  489. package/dist/notifications/push-devices-setting.js +27 -49
  490. package/dist/notifications/push-devices-setting.js.map +1 -1
  491. package/dist/notifications/quiet-hours-setting.d.ts +10 -3
  492. package/dist/notifications/quiet-hours-setting.js +65 -26
  493. package/dist/notifications/quiet-hours-setting.js.map +1 -1
  494. package/dist/notifications/unsubscribe-panel.js +4 -7
  495. package/dist/notifications/unsubscribe-panel.js.map +1 -1
  496. package/dist/notifications/use-push-device.d.ts +39 -1
  497. package/dist/notifications/use-push-device.js +28 -7
  498. package/dist/notifications/use-push-device.js.map +1 -1
  499. package/dist/offline/query-persistence.d.ts +3 -1
  500. package/dist/offline/query-persistence.js +19 -2
  501. package/dist/offline/query-persistence.js.map +1 -1
  502. package/dist/rhf/fields.d.ts +11 -4
  503. package/dist/rhf/fields.js.map +1 -1
  504. package/dist/search/command-palette.js +1 -1
  505. package/dist/search/command-palette.js.map +1 -1
  506. package/dist/search/global-search.js +19 -9
  507. package/dist/search/global-search.js.map +1 -1
  508. package/dist/search/use-command-key.d.ts +12 -1
  509. package/dist/search/use-command-key.js +3 -12
  510. package/dist/search/use-command-key.js.map +1 -1
  511. package/dist/search.d.ts +7 -0
  512. package/dist/search.js +10 -0
  513. package/dist/search.js.map +1 -1
  514. package/dist/settings/use-settings-focus.js +1 -0
  515. package/dist/settings/use-settings-focus.js.map +1 -1
  516. package/dist/shell/account-menu-language.d.ts +21 -5
  517. package/dist/shell/account-menu-language.js +3 -1
  518. package/dist/shell/account-menu-language.js.map +1 -1
  519. package/dist/shell/account-menu-text-size.d.ts +26 -9
  520. package/dist/shell/account-menu-text-size.js +3 -2
  521. package/dist/shell/account-menu-text-size.js.map +1 -1
  522. package/dist/shell/dev-menu.js +5 -18
  523. package/dist/shell/dev-menu.js.map +1 -1
  524. package/dist/shell/role-switcher.d.ts +7 -0
  525. package/dist/shell/role-switcher.js.map +1 -1
  526. package/dist/shell/top-bar-actions.d.ts +1 -1
  527. package/dist/shell/top-bar-actions.js.map +1 -1
  528. package/dist/shell/top-bar-parts-labels.d.ts +0 -2
  529. package/dist/shell/top-bar-parts-labels.js +0 -1
  530. package/dist/shell/top-bar-parts-labels.js.map +1 -1
  531. package/dist/shell.d.ts +27 -8
  532. package/dist/shell.js +28 -7
  533. package/dist/shell.js.map +1 -1
  534. package/dist/sync/engine.d.ts +30 -4
  535. package/dist/sync/engine.js +172 -52
  536. package/dist/sync/engine.js.map +1 -1
  537. package/dist/sync.d.ts +6 -2
  538. package/dist/sync.js +6 -1
  539. package/dist/sync.js.map +1 -1
  540. package/dist/testing/css-variables.js +3 -8
  541. package/dist/testing/css-variables.js.map +1 -1
  542. package/dist/theme/contrast.d.ts +2 -1
  543. package/dist/theme/contrast.js +3 -8
  544. package/dist/theme/contrast.js.map +1 -1
  545. package/dist/theme/palette-store.js +6 -6
  546. package/dist/theme/palette-store.js.map +1 -1
  547. package/dist/theme/text-size.js +3 -8
  548. package/dist/theme/text-size.js.map +1 -1
  549. package/dist/theme/theme-store.js +3 -6
  550. package/dist/theme/theme-store.js.map +1 -1
  551. package/dist/tour/tour-catalogue.d.ts +7 -4
  552. package/dist/tour/tour-catalogue.js +12 -10
  553. package/dist/tour/tour-catalogue.js.map +1 -1
  554. package/dist/tour/tour-dock.d.ts +0 -2
  555. package/dist/tour/tour-dock.js +0 -2
  556. package/dist/tour/tour-dock.js.map +1 -1
  557. package/dist/tour/tour-gates.d.ts +4 -0
  558. package/dist/tour/tour-gates.js +14 -0
  559. package/dist/tour/tour-gates.js.map +1 -1
  560. package/dist/tour/tour-overlay.d.ts +27 -0
  561. package/dist/tour/tour-overlay.js +741 -0
  562. package/dist/tour/tour-overlay.js.map +1 -0
  563. package/dist/tour/tour.d.ts +16 -4
  564. package/dist/tour/tour.js +62 -778
  565. package/dist/tour/tour.js.map +1 -1
  566. package/dist/tour/use-tour-progress.js +1 -1
  567. package/dist/tour/use-tour-progress.js.map +1 -1
  568. package/dist/tour/use-tour-url-sync.js +2 -2
  569. package/dist/tour/use-tour-url-sync.js.map +1 -1
  570. package/dist/wizard/stepper-nav.d.ts +5 -1
  571. package/dist/wizard/stepper-nav.js.map +1 -1
  572. package/dist/wizard/types.d.ts +6 -2
  573. package/dist/wizard/types.js.map +1 -1
  574. package/dist/wizard/use-wizard.d.ts +3 -1
  575. package/dist/wizard/use-wizard.js.map +1 -1
  576. package/dist/wizard/validation.d.ts +3 -1
  577. package/dist/wizard/validation.js.map +1 -1
  578. package/package.json +12 -8
  579. package/src/account/account-parts.ts +5 -25
  580. package/src/account/data-export-setting-labels.ts +1 -1
  581. package/src/account/delete-account-setting-labels.ts +1 -1
  582. package/src/account/email-change-setting-labels.ts +1 -1
  583. package/src/account/passkeys-setting.tsx +60 -38
  584. package/src/account/sessions-setting.tsx +18 -12
  585. package/src/admin/admin-action-confirm.tsx +5 -10
  586. package/src/admin/admin-parts.ts +11 -25
  587. package/src/admin/mail-test-card-labels.ts +1 -1
  588. package/src/admin/plan-change-labels.ts +5 -23
  589. package/src/admin/plan-change.tsx +7 -44
  590. package/src/admin/reviewer-scope-editor.tsx +3 -3
  591. package/src/auth/auth-errors-labels.ts +23 -0
  592. package/src/auth/auth-errors.ts +11 -38
  593. package/src/auth/complete-name-dialog.tsx +9 -8
  594. package/src/auth/forgot-password-form-labels.ts +1 -1
  595. package/src/auth/forgot-password-form.tsx +11 -6
  596. package/src/auth/register-form-labels.ts +1 -1
  597. package/src/auth/reset-password-form-labels.ts +1 -1
  598. package/src/auth/reset-password-form.tsx +8 -4
  599. package/src/auth/sign-in-form-labels.ts +1 -1
  600. package/src/auth/status-parts.tsx +0 -6
  601. package/src/auth/verify-email-labels.ts +1 -1
  602. package/src/auth/verify-email.tsx +11 -6
  603. package/src/billing/cancel-request.ts +28 -6
  604. package/src/billing/cancel-subscription.tsx +29 -22
  605. package/src/billing/dialog-close.ts +34 -0
  606. package/src/billing/plan-card.tsx +36 -11
  607. package/src/billing/plan-change-labels.ts +66 -0
  608. package/src/billing/plan-switch.tsx +31 -20
  609. package/src/chart.ts +21 -3
  610. package/src/components/account-chips.tsx +20 -23
  611. package/src/components/alert-banner.tsx +82 -5
  612. package/src/components/amount-input.tsx +32 -14
  613. package/src/components/autocomplete.tsx +64 -70
  614. package/src/components/bulk-action-bar.tsx +70 -2
  615. package/src/components/button-look.ts +5 -5
  616. package/src/components/button.tsx +2 -2
  617. package/src/components/calculator.tsx +98 -17
  618. package/src/components/chart-edge.ts +34 -1
  619. package/src/components/chart-figure.tsx +35 -0
  620. package/src/components/chart-zoom-core.tsx +6 -5
  621. package/src/components/chart.tsx +26 -5
  622. package/src/components/combobox-core.tsx +303 -69
  623. package/src/components/combobox.tsx +184 -155
  624. package/src/components/copy-button.tsx +34 -23
  625. package/src/components/country-select.tsx +16 -11
  626. package/src/components/data-table-column-settings.tsx +52 -10
  627. package/src/components/data-table-filters.ts +6 -4
  628. package/src/components/data-table-fit.ts +19 -5
  629. package/src/components/data-table-groups.tsx +1 -1
  630. package/src/components/data-table-head.tsx +32 -22
  631. package/src/components/data-table-mobile.tsx +110 -27
  632. package/src/components/data-table-pagination.tsx +21 -6
  633. package/src/components/data-table-resize.ts +1 -1
  634. package/src/components/data-table-row-actions.tsx +3 -3
  635. package/src/components/data-table-row.tsx +25 -14
  636. package/src/components/data-table-selection.ts +1 -1
  637. package/src/components/data-table-shared.tsx +33 -1
  638. package/src/components/data-table-sort.ts +57 -2
  639. package/src/components/data-table-virtual.ts +32 -8
  640. package/src/components/data-table.tsx +267 -41
  641. package/src/components/date-field.tsx +65 -8
  642. package/src/components/date-picker.tsx +125 -48
  643. package/src/components/date-range-picker.tsx +82 -31
  644. package/src/components/dialog-frame.tsx +2 -1
  645. package/src/components/entity-combobox.tsx +4 -1
  646. package/src/components/error-boundary.tsx +53 -39
  647. package/src/components/field-base-labels.ts +20 -0
  648. package/src/components/field-base.tsx +13 -7
  649. package/src/components/field-sync-labels.ts +1 -0
  650. package/src/components/field-sync.tsx +23 -1
  651. package/src/components/form-actions.tsx +20 -5
  652. package/src/components/hover-menu.tsx +18 -8
  653. package/src/components/icon-button.tsx +14 -9
  654. package/src/components/inline-confirm.tsx +116 -0
  655. package/src/components/inline-entity-combobox.tsx +198 -152
  656. package/src/components/input.tsx +1 -1
  657. package/src/components/jump-calendar.tsx +30 -146
  658. package/src/components/legal-page.tsx +10 -7
  659. package/src/components/legal.tsx +4 -2
  660. package/src/components/lightbox.tsx +21 -8
  661. package/src/components/list.tsx +14 -5
  662. package/src/components/measured-grid.tsx +8 -4
  663. package/src/components/mini-calendar.tsx +6 -5
  664. package/src/components/modal.tsx +45 -4
  665. package/src/components/money-draft.ts +16 -5
  666. package/src/components/money-field.tsx +2 -2
  667. package/src/components/month-grid.tsx +229 -0
  668. package/src/components/month-picker.tsx +192 -200
  669. package/src/components/multi-entity-combobox.tsx +1 -0
  670. package/src/components/multi-select.tsx +21 -9
  671. package/src/components/number-field.tsx +14 -7
  672. package/src/components/number-input.tsx +9 -3
  673. package/src/components/numpad-sheet.tsx +4 -3
  674. package/src/components/picker-sheet.tsx +12 -9
  675. package/src/components/pie-chart-labels.ts +8 -0
  676. package/src/components/pie-chart.tsx +22 -28
  677. package/src/components/popover.tsx +18 -1
  678. package/src/components/reauth-dialog.tsx +6 -10
  679. package/src/components/row-actions.tsx +2 -1
  680. package/src/components/section-nav.tsx +7 -0
  681. package/src/components/series-chart-axes.ts +11 -3
  682. package/src/components/series-chart-labels.ts +7 -4
  683. package/src/components/series-chart.tsx +178 -69
  684. package/src/components/share-card.tsx +6 -6
  685. package/src/components/sign-chip-labels.ts +1 -0
  686. package/src/components/sign-chip.tsx +10 -1
  687. package/src/components/tabs-labels.ts +13 -0
  688. package/src/components/tabs.tsx +35 -19
  689. package/src/components/toggle-legend.tsx +16 -11
  690. package/src/components/translation-review-editor.tsx +6 -5
  691. package/src/components/translation-review.tsx +4 -3
  692. package/src/components/treemap-labels.ts +39 -0
  693. package/src/components/treemap-layout.ts +210 -0
  694. package/src/components/treemap.tsx +722 -133
  695. package/src/components/use-table-state.ts +12 -9
  696. package/src/data-table.ts +9 -2
  697. package/src/eslint/role-utilities.ts +97 -19
  698. package/src/feedback/feedback-dialog.tsx +30 -19
  699. package/src/feedback/feedback-mutation.ts +41 -0
  700. package/src/feedback/feedback-page-link.ts +90 -0
  701. package/src/feedback/feedback-public-list.tsx +17 -5
  702. package/src/feedback/feedback-replies.tsx +13 -6
  703. package/src/feedback/feedback-row-detail-labels.ts +5 -0
  704. package/src/feedback/feedback-row-detail.tsx +103 -67
  705. package/src/feedback/feedback-status-undo.ts +41 -27
  706. package/src/feedback/feedback-submit-dialog.tsx +2 -2
  707. package/src/feedback/feedback-submit.tsx +21 -7
  708. package/src/feedback/feedback-swipe.tsx +1 -1
  709. package/src/feedback/feedback-table.tsx +86 -38
  710. package/src/feedback/feedback-thread-labels.ts +2 -2
  711. package/src/feedback/feedback-thread.tsx +27 -25
  712. package/src/feedback.ts +42 -0
  713. package/src/hooks/use-dismiss.ts +3 -2
  714. package/src/hooks/use-focus-trap.ts +8 -24
  715. package/src/hooks/use-hotkey.ts +24 -7
  716. package/src/hooks/use-long-press.ts +16 -2
  717. package/src/hooks/use-media-query.ts +20 -4
  718. package/src/hooks/use-mounted.ts +39 -0
  719. package/src/hooks/use-overlay-history.ts +70 -5
  720. package/src/i18n/defaults.ts +4 -5
  721. package/src/i18n/german.ts +8 -2
  722. package/src/i18n/kit-labels.tsx +9 -2
  723. package/src/i18n/locales/es.ts +8 -2
  724. package/src/i18n/locales/fr.ts +21 -13
  725. package/src/i18n/locales/hu.ts +10 -2
  726. package/src/i18n/locales/it.ts +8 -2
  727. package/src/i18n/locales/zh.ts +9 -2
  728. package/src/i18n/review.ts +5 -0
  729. package/src/index.ts +103 -13
  730. package/src/landing/routing.tsx +14 -10
  731. package/src/lib/broadcast.ts +52 -0
  732. package/src/lib/calc.ts +13 -2
  733. package/src/lib/clipboard-minus.ts +14 -4
  734. package/src/lib/date-format.ts +89 -13
  735. package/src/lib/day-format.ts +96 -0
  736. package/src/lib/decimal-marks.ts +12 -3
  737. package/src/lib/describe-failure.ts +18 -0
  738. package/src/lib/direction.ts +39 -0
  739. package/src/lib/focus-left.ts +156 -0
  740. package/src/lib/format.ts +34 -19
  741. package/src/lib/http-status.ts +38 -0
  742. package/src/lib/intl-cache.ts +25 -0
  743. package/src/lib/isin.ts +10 -0
  744. package/src/lib/iso-day.ts +13 -0
  745. package/src/lib/lazy-with-fallback.ts +82 -0
  746. package/src/lib/path-pattern.ts +55 -0
  747. package/src/lib/reduced-motion.ts +2 -1
  748. package/src/lib/round.ts +7 -2
  749. package/src/lib/safe-storage.ts +48 -6
  750. package/src/lib/session-refresh.ts +1 -1
  751. package/src/lib/share-format.ts +18 -0
  752. package/src/lib/text-case.ts +19 -0
  753. package/src/lib/text-match.ts +69 -2
  754. package/src/lib/thenable.ts +19 -0
  755. package/src/lib/translation-review.ts +13 -5
  756. package/src/notifications/device-zone-report.ts +1 -1
  757. package/src/notifications/notification-bell.tsx +7 -4
  758. package/src/notifications/notification-inbox.tsx +40 -58
  759. package/src/notifications/notification-parts.tsx +3 -4
  760. package/src/notifications/notification-types-setting.tsx +1 -1
  761. package/src/notifications/notifications-labels.ts +7 -0
  762. package/src/notifications/push-device-setting.tsx +1 -1
  763. package/src/notifications/push-devices-setting.tsx +30 -55
  764. package/src/notifications/quiet-hours-setting.tsx +93 -31
  765. package/src/notifications/unsubscribe-panel.tsx +4 -7
  766. package/src/notifications/use-push-device.ts +76 -10
  767. package/src/offline/query-persistence.ts +35 -3
  768. package/src/rhf/fields.tsx +11 -4
  769. package/src/search/command-palette.tsx +2 -4
  770. package/src/search/global-search.tsx +36 -15
  771. package/src/search/use-command-key.ts +13 -12
  772. package/src/search.ts +9 -0
  773. package/src/settings/use-settings-focus.ts +3 -0
  774. package/src/shell/account-menu-language.tsx +27 -5
  775. package/src/shell/account-menu-text-size.tsx +32 -10
  776. package/src/shell/dev-menu.tsx +7 -21
  777. package/src/shell/role-switcher.tsx +7 -0
  778. package/src/shell/top-bar-actions.tsx +1 -1
  779. package/src/shell/top-bar-parts-labels.ts +0 -3
  780. package/src/shell.ts +40 -9
  781. package/src/sync/engine.ts +339 -61
  782. package/src/sync.ts +8 -1
  783. package/src/testing/css-variables.ts +8 -9
  784. package/src/theme/contrast.ts +8 -9
  785. package/src/theme/palette-store.ts +9 -9
  786. package/src/theme/text-size.ts +6 -8
  787. package/src/theme/theme-store.ts +7 -9
  788. package/src/tour/tour-catalogue.tsx +26 -15
  789. package/src/tour/tour-dock.ts +0 -2
  790. package/src/tour/tour-gates.ts +23 -0
  791. package/src/tour/tour-overlay.tsx +1170 -0
  792. package/src/tour/tour.tsx +116 -1193
  793. package/src/tour/use-tour-progress.ts +1 -1
  794. package/src/tour/use-tour-url-sync.ts +7 -3
  795. package/src/wizard/stepper-nav.tsx +3 -1
  796. package/src/wizard/types.ts +11 -2
  797. package/src/wizard/use-wizard.ts +2 -1
  798. package/src/wizard/validation.ts +8 -2
  799. package/tokens.css +2 -1
  800. package/dist/components/ui-labels.js.map +0 -1
  801. package/dist/shell/dev-switchers.d.ts +0 -6
  802. package/dist/shell/dev-switchers.js +0 -12
  803. package/dist/shell/dev-switchers.js.map +0 -1
  804. package/src/components/ui-labels.ts +0 -24
  805. package/src/shell/dev-switchers.tsx +0 -18
@@ -2,14 +2,14 @@ import { useLayoutEffect, useMemo, useRef } from "react";
2
2
  import { ChevronLeft, ChevronRight, Plus, X } from "lucide-react";
3
3
  import type { ComponentPropsWithoutRef, KeyboardEvent, ReactNode, Ref } from "react";
4
4
  import { cn } from "../lib/cn";
5
- import { FOCUS_RING_WIDTH } from "./focus-ring";
5
+ import { FOCUS_RING } from "./focus-ring";
6
6
  import { scrollIntoStrip, useStripFade } from "../lib/strip-fade";
7
7
  import { horizontalStep } from "../lib/direction";
8
8
  import { usePhoneLayout } from "../hooks/use-breakpoint";
9
9
  import { prefersReducedMotion } from "../lib/reduced-motion";
10
10
  import { useKitLabels, type LabelOverride } from "../i18n/kit-labels";
11
11
  import { mergeRefs } from "./field-parts";
12
- import { DEFAULT_TABS_LABELS } from "./ui-labels";
12
+ import { DEFAULT_TABS_LABELS } from "./tabs-labels";
13
13
  import { IconButton } from "./icon-button";
14
14
  import { HIT_AREA_LARGE } from "./button-look";
15
15
 
@@ -55,7 +55,7 @@ export interface TabsLabels {
55
55
  previous: string;
56
56
  }
57
57
 
58
- // Defined in ./ui-labels, which holds no component code (0.34, KS U8).
58
+ // Defined in ./tabs-labels, which holds no component code (0.34, KS U8).
59
59
  export { DEFAULT_TABS_LABELS };
60
60
 
61
61
  /**
@@ -205,9 +205,7 @@ const TABLIST_CLASSES = "flex gap-1 overflow-x-auto overflow-y-hidden border-b b
205
205
  // selection. `--bg-active` is the kit's own selected-row fill (the sidebar's), so the
206
206
  // admin page's nav and the app's own sidebar mark "you are here" the same way.
207
207
  const TABLIST_VERTICAL_CLASSES = "flex flex-col gap-0.5";
208
- const TAB_VERTICAL_CLASSES =
209
- FOCUS_RING_WIDTH +
210
- " flex w-full items-center rounded-md px-3 py-2 text-start text-sm font-medium transition-colors focus:outline-none focus-visible:ring-strong";
208
+ const TAB_VERTICAL_CLASSES = `flex w-full items-center rounded-md px-3 py-2 text-start text-sm font-medium transition-colors focus:outline-none ${FOCUS_RING}`;
211
209
  const TAB_VERTICAL_ACTIVE_CLASSES = "bg-active text-primary";
212
210
  const TAB_VERTICAL_INACTIVE_CLASSES = "text-muted hover:bg-hover hover:text-primary";
213
211
 
@@ -215,9 +213,14 @@ const TAB_VERTICAL_INACTIVE_CLASSES = "text-muted hover:bg-hover hover:text-prim
215
213
  // links · … · 31 Punkte") made one tab 448px wide in a 390px strip, and a tab wider
216
214
  // than the strip cannot be scrolled into view — its end was simply off screen
217
215
  // (lenkbank L3). The label and detail truncate inside it instead; see `inner`.
218
- const TAB_CLASSES =
219
- FOCUS_RING_WIDTH +
220
- " max-w-full whitespace-nowrap px-3 py-2 text-sm font-medium transition-colors border-b-2 -mb-px focus:outline-none focus-visible:ring-strong";
216
+ //
217
+ // Keyboard focus on a tab, a side-nav row and the add button is the kit's one focus frame
218
+ // (text-size §5), in brand. Until 0.51.7 it rang in `ring-strong`: 2.54:1 on the light
219
+ // page and 2.76:1 on a card, under WCAG 1.4.11's 3:1 (refactor audit 2026-10-30, DSP-8;
220
+ // NavPills made the same move in 0.34, DOC-7). INSET on a tab: the strip scrolls
221
+ // (`overflow-x-auto overflow-y-hidden`), so a ring outside the tab is cut off along its
222
+ // top and bottom, and at a cut end.
223
+ const TAB_CLASSES = `max-w-full whitespace-nowrap px-3 py-2 text-sm font-medium transition-colors border-b-2 -mb-px focus:outline-none ${FOCUS_RING} focus-visible:ring-inset`;
221
224
  const TAB_ACTIVE_CLASSES = "border-[var(--text-primary)] text-primary";
222
225
  const TAB_INACTIVE_CLASSES = "border-transparent text-muted hover:text-secondary hover:border-strong";
223
226
 
@@ -225,9 +228,7 @@ const TAB_INACTIVE_CLASSES = "border-transparent text-muted hover:text-secondary
225
228
  // `onRemove`).
226
229
  const TAB_REMOVABLE_CLASSES = "pe-8";
227
230
  const TAB_EMPTY_CLASSES = "-mx-1.5 rounded border border-dashed border-strong px-1.5";
228
- const TAB_ADD_CLASSES =
229
- FOCUS_RING_WIDTH +
230
- " inline-flex items-center gap-1 whitespace-nowrap rounded-md px-3 py-2 text-sm font-medium text-muted transition-colors hover:text-primary focus:outline-none focus-visible:ring-strong disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:size-4";
231
+ const TAB_ADD_CLASSES = `inline-flex items-center gap-1 whitespace-nowrap rounded-md px-3 py-2 text-sm font-medium text-muted transition-colors hover:text-primary focus:outline-none ${FOCUS_RING} disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:size-4`;
231
232
  // `relative`: the phone's visually hidden label needs a positioned ancestor (see the
232
233
  // sr-only rule in CONTRIBUTING); `max-md:px-2` squares the lone "+".
233
234
  const TAB_ADD_PHONE_CLASSES = "relative max-md:px-2";
@@ -262,6 +263,8 @@ export function Tabs<T extends string>({
262
263
  const cue = overflowCue && !vertical;
263
264
  const cueStart = cue && (fade.overflow === "start" || fade.overflow === "both");
264
265
  const cueEnd = cue && (fade.overflow === "end" || fade.overflow === "both");
266
+ // The cue gutters (see `stripBox`): there only while the strip overflows at all.
267
+ const gutters = cue && fade.overflow !== undefined;
265
268
  // Three quarters of the visible width toward `side`; an RTL strip runs leftward.
266
269
  const onCue = (side: "start" | "end") => {
267
270
  const strip = stripRef.current;
@@ -333,15 +336,25 @@ export function Tabs<T extends string>({
333
336
  // "80 km," under the add button. Only the strip scrolls (`scrollBy` on it, not
334
337
  // `scrollIntoView`, which would scroll the page as well), and only as far as needed
335
338
  // to clear the fade.
339
+ //
340
+ // And again when the cue gutters appear (refactor audit 2026-10-30, DSP-16). They come a
341
+ // render after the strip is first measured as overflowing — on mount, or with the very
342
+ // tab that tipped it over — and take 24px off each end, so a tab scrolled clear before
343
+ // them ended 24px past the visible end, under the fade and the ›.
336
344
  useLayoutEffect(() => {
337
345
  const strip = stripRef.current;
338
346
  const tab = strip?.querySelector<HTMLElement>('[role="tab"][aria-selected="true"]');
339
347
  if (strip && tab) scrollIntoStrip(strip, tab);
340
- }, [active]);
348
+ }, [active, gutters]);
341
349
  const isRemovable = (tab: TabItem<T>) => onRemove !== undefined && tab.removable !== false;
342
350
  // Whether Delete reaches this tab: every removable tab, or only the open one.
343
351
  const deletesOnKey = (tab: TabItem<T>) => isRemovable(tab) && (removeOn === "every" || tab.id === active);
344
352
  const nameOf = (tab: TabItem<T>) => tab.name ?? (typeof tab.label === "string" ? tab.label : tab.id);
353
+ // The strip's one tab stop (see `tabIndex` below): the open tab, or the first while
354
+ // `active` names none. "No sheet open" is a real state — KS's sheet strips pass `""` —
355
+ // and with the stop on the selection alone every tab was -1, so the keyboard could not
356
+ // reach the one control that opens a sheet (refactor audit 2026-10-30, DSP-1).
357
+ const stop = tabs.some((t) => t.id === active) ? active : tabs[0]?.id;
345
358
 
346
359
  // Where focus goes once a removal the strip asked for has happened. The caller
347
360
  // owns `tabs` and may take its time (a confirmation, a request), so this waits
@@ -370,10 +383,14 @@ export function Tabs<T extends string>({
370
383
  if (focused && focused !== document.body && !strip.contains(focused) && focused !== removeRef.current) return;
371
384
  // The removed tab was open: focus follows the caller's new selection, which is
372
385
  // also the strip's tab stop. It was not: its neighbour, as the ARIA pattern has it.
373
- const target = !pending.wasActive && tabs.some((t) => t.id === pending.neighbour) ? pending.neighbour : active;
386
+ // The caller opened nothing in its place (KS drops the sheet and the selection in one
387
+ // render): the neighbour too, else the stop — not an index of -1 and the page (DSP-1).
388
+ const present = (id: T | undefined) => tabs.some((t) => t.id === id);
389
+ const target =
390
+ pending.wasActive && present(active) ? active : present(pending.neighbour) ? pending.neighbour : stop;
374
391
  const index = tabs.findIndex((t) => t.id === target);
375
392
  strip.querySelectorAll<HTMLElement>('[role="tab"]')[index]?.focus();
376
- }, [tabs, active]);
393
+ }, [tabs, active, stop]);
377
394
 
378
395
  // Arrow keys walk the strip in DOM order (ARIA tabs pattern). Home/End jump
379
396
  // to the ends. Focus only — activation stays on click/Enter/Space, because a tab
@@ -462,8 +479,8 @@ export function Tabs<T extends string>({
462
479
  // strip back on the next visit in a state they never chose. The cost is that
463
480
  // Tab out and back returns to the open tab rather than to the last one
464
481
  // looked at; the ARIA pattern allows either, and this one needs no second
465
- // piece of state shadowing `active`.
466
- tabIndex: isActive ? 0 : -1,
482
+ // piece of state shadowing `active`. With nothing open, the first tab (`stop`).
483
+ tabIndex: tab.id === stop ? 0 : -1,
467
484
  // Only the open tab: see `panelId`.
468
485
  "aria-controls": isActive ? panelId : undefined,
469
486
  id: isActive && panelId ? `${panelId}-tab` : undefined,
@@ -612,8 +629,7 @@ export function Tabs<T extends string>({
612
629
  ) : null;
613
630
  // The box the cues sit in, ‹ in the gutter before the strip and › in the one after it
614
631
  // (see `gutterAt`). There whether or not the strip overflows right now, so a resize
615
- // never re-parents it; the gutters only while it overflows at all.
616
- const gutters = cue && fade.overflow !== undefined;
632
+ // never re-parents it; the gutters only while it overflows at all (`gutters`).
617
633
  const stripBox = cue ? (
618
634
  <div className={cn("relative flex min-w-0", !onAdd && "flex-1", gutters && "px-[24px]")}>
619
635
  {tablist}
@@ -123,7 +123,7 @@ export interface LegendEntry {
123
123
  }
124
124
 
125
125
  export interface ToggleLegendProps {
126
- entries: LegendEntry[];
126
+ entries: readonly LegendEntry[];
127
127
  /** The keys currently off the chart. */
128
128
  hidden: ReadonlySet<string>;
129
129
  onToggle: (key: string) => void;
@@ -198,12 +198,15 @@ export function ToggleLegend({
198
198
  className={cn(
199
199
  "flex items-center gap-1.5 rounded text-start text-caption text-secondary transition-opacity hover:opacity-80",
200
200
  FOCUS_RING,
201
- off && "opacity-35",
202
201
  entry.align === "end" && "ms-auto",
203
202
  )}
204
203
  >
205
204
  <LegendMark entry={entry} off={off} />
206
- {entry.label}
205
+ {/* Off, the label keeps its ink and is struck through; only the mark fades
206
+ (0.52, refactor audit 2026-10-30, DSP-9). The whole entry at 35 % put the
207
+ label at 1.8:1 — on a button that brings the series back, whose label is
208
+ the only thing saying which one. `aria-pressed` carries the state. */}
209
+ <span className={cn(off && "line-through")}>{entry.label}</span>
207
210
  </button>
208
211
  );
209
212
  })}
@@ -212,7 +215,7 @@ export function ToggleLegend({
212
215
  }
213
216
 
214
217
  export interface StaticLegendProps {
215
- entries: LegendEntry[];
218
+ entries: readonly LegendEntry[];
216
219
  /** See {@link ToggleLegendProps.orientation}. */
217
220
  orientation?: "horizontal" | "vertical";
218
221
  /** The list's accessible name. Default: the `seriesChart.legend` label. */
@@ -338,13 +341,15 @@ export function LegendGroup({ title, children }: { title: ReactNode; children: R
338
341
  * A stroke is an SVG line with the chart's own `strokeDasharray`, not a CSS gradient
339
342
  * approximating it: a gradient can say "solid or dashed" and nothing more.
340
343
  *
341
- * A hidden stroke is NOT faded here: the button around it already is (`opacity-35`),
342
- * and the line used to take its own 0.35 on top — 0.35 × 0.35, about 12 %, a mark
343
- * gone rather than dimmed, while the square beside it read at the full 35 %. */
344
+ * A hidden mark fades ONCE, on its own box (`opacity-35`; since 0.52 the label beside
345
+ * it keeps its ink, DSP-9). The line used to take its own 0.35 inside a faded button —
346
+ * 0.35 × 0.35, about 12 %, a mark gone rather than dimmed, while the square beside it
347
+ * read at the full 35 %. */
344
348
  function LegendMark({ entry, off }: { entry: LegendEntry; off: boolean }) {
349
+ const fade = off && "opacity-35";
345
350
  if (entry.icon != null) {
346
351
  return (
347
- <span aria-hidden className="inline-flex shrink-0 items-center">
352
+ <span aria-hidden className={cn("inline-flex shrink-0 items-center", fade)}>
348
353
  {entry.icon}
349
354
  </span>
350
355
  );
@@ -353,7 +358,7 @@ function LegendMark({ entry, off }: { entry: LegendEntry; off: boolean }) {
353
358
  return (
354
359
  <span
355
360
  aria-hidden
356
- className="size-2 shrink-0 rounded-full"
361
+ className={cn("size-2 shrink-0 rounded-full", fade)}
357
362
  style={{
358
363
  backgroundColor: off ? "transparent" : entry.color,
359
364
  boxShadow: `inset 0 0 0 1.5px ${entry.color}`,
@@ -363,7 +368,7 @@ function LegendMark({ entry, off }: { entry: LegendEntry; off: boolean }) {
363
368
  }
364
369
  if (entry.marker === "stroke") {
365
370
  return (
366
- <svg aria-hidden viewBox="0 0 20 2" className="h-0.5 w-5 shrink-0 overflow-visible">
371
+ <svg aria-hidden viewBox="0 0 20 2" className={cn("h-0.5 w-5 shrink-0 overflow-visible", fade)}>
367
372
  <line
368
373
  x1={0}
369
374
  y1={1}
@@ -379,7 +384,7 @@ function LegendMark({ entry, off }: { entry: LegendEntry; off: boolean }) {
379
384
  return (
380
385
  <span
381
386
  aria-hidden
382
- className="h-2.5 w-2.5 shrink-0 rounded-[3px]"
387
+ className={cn("h-2.5 w-2.5 shrink-0 rounded-[3px]", fade)}
383
388
  style={{
384
389
  backgroundColor: off ? "transparent" : entry.color,
385
390
  boxShadow: `inset 0 0 0 1.5px ${entry.color}`,
@@ -3,7 +3,7 @@ import type { ReactNode } from "react";
3
3
 
4
4
  import { useKitLabels, type LabelOverride } from "../i18n/kit-labels";
5
5
  import { cn } from "../lib/cn";
6
- import { useKitFormat } from "../lib/format";
6
+ import { useDayFormatter } from "../lib/day-format";
7
7
  import { placeholderTokens, reviewWrite } from "../lib/translation-review";
8
8
  import type {
9
9
  TranslationReviewKey,
@@ -48,8 +48,10 @@ export interface TranslationReviewEditorProps {
48
48
  * opened by a tap — that one may only be opened to read.
49
49
  */
50
50
  focusWording?: boolean;
51
- /** How the verdict's date reads. Default: the kit's `formatDate`, medium, in the
52
- * provider's locale. */
51
+ /** How the verdict's date reads. Default (0.52): the `<UiKitProvider formatDate>` when
52
+ * the app set one (its date preference; the day sits in a sentence, so no weekday), else
53
+ * the kit's `formatDate`, medium, in the provider's locale and `timeZone`. An empty
54
+ * answer falls back to the kit's. */
53
55
  formatDate?: (iso: string) => string;
54
56
  /** Turns a rejection into words. Default {@link TranslationReviewLabels.failed}. */
55
57
  formatError?: (error: unknown) => ReactNode;
@@ -106,7 +108,7 @@ export function TranslationReviewEditor({
106
108
  labels: labelsProp,
107
109
  }: TranslationReviewEditorProps) {
108
110
  const labels = useKitLabels("translationReview", DEFAULT_TRANSLATION_REVIEW_LABELS, labelsProp);
109
- const { formatDate } = useKitFormat();
111
+ const date = useDayFormatter(formatDateProp);
110
112
  const review = row.review;
111
113
  const missing = row.text === "";
112
114
  const editable = !readOnly && onSave !== undefined;
@@ -127,7 +129,6 @@ export function TranslationReviewEditor({
127
129
 
128
130
  const canFlag = note.trim() !== "" || suggestion.trim() !== row.text.trim();
129
131
  const changed = row.status === "changed" ? review : null;
130
- const date = (iso: string) => (formatDateProp ? formatDateProp(iso) : formatDate(iso, "medium"));
131
132
 
132
133
  const run = async (kind: "approve" | "flag" | "clear", action: () => MaybePromise) => {
133
134
  setBusy(kind);
@@ -181,7 +181,8 @@ export interface TranslationReviewPanelProps {
181
181
  * kit's, which an app listing what it stores had to list as its own (KS U4).
182
182
  */
183
183
  storageKeyPrefix?: string;
184
- /** How a verdict's date reads in the editor. */
184
+ /** How a verdict's date reads in the editor. Default: the editor's — the
185
+ * `<UiKitProvider formatDate>`, else the kit's medium date (0.52). */
185
186
  formatDate?: (iso: string) => string;
186
187
  /** Turns a callback's rejection into words. Default {@link TranslationReviewLabels.failed}. */
187
188
  formatError?: (error: unknown) => ReactNode;
@@ -561,8 +562,8 @@ export function TranslationReviewPanel({
561
562
  // `filter` is rebuilt every render; its fields are what the list depends on.
562
563
  const { status, query, placeholdersOnly } = filter;
563
564
  const visible = useMemo(
564
- () => filterTranslationRows(rows, { status, source, namespace, query, placeholdersOnly }),
565
- [rows, status, source, namespace, query, placeholdersOnly],
565
+ () => filterTranslationRows(rows, { status, source, namespace, query, placeholdersOnly }, locale),
566
+ [rows, status, source, namespace, query, placeholdersOnly, locale],
566
567
  );
567
568
 
568
569
  // ── Groups ──
@@ -0,0 +1,39 @@
1
+ // All user-facing strings for `Treemap`, as the `treemap` namespace of
2
+ // `<UiKitProvider labels>`, and per map the `labels` prop over that (0.52, refactor audit
3
+ // 2026-10-30, DSP-5).
4
+ //
5
+ // A module of its own, with no recharts in it, for the reason `pie-chart-labels` is one:
6
+ // the label registry (src/i18n) imports the defaults, and must not pull the chart
7
+ // library in behind them.
8
+
9
+ export interface TreemapLabels {
10
+ /**
11
+ * One tile's accessible name — what a screen reader says for a tile, clickable or
12
+ * not, since its area is nothing it can say. `value` arrives through the map's
13
+ * `valueFormatter` when that returns text, else as the number in the provider's
14
+ * locale; `share` is the tile's share of what is drawn, already a formatted percent
15
+ * ("60 %" in German, "60%" in English) — the function only arranges them.
16
+ */
17
+ tile: (name: string, value: string, share: string) => string;
18
+ /**
19
+ * A group's accessible name (0.52, `TreemapNode.children`): its frame is a stop of the
20
+ * map's keyboard before its tiles, so a reader hears the group and its total once, on the
21
+ * way in. `value` and `share` as for {@link TreemapLabels.tile}, of the group's tiles
22
+ * together; the word "group" tells it from a tile of the same shape.
23
+ */
24
+ group: (name: string, value: string, share: string) => string;
25
+ /**
26
+ * A name inside a group: `name` is the tile's (or a nested group's) own, from
27
+ * {@link TreemapLabels.tile} or {@link TreemapLabels.group}, and `group` the name of the
28
+ * group round it — applied once per group, the innermost first, so a tile two levels deep
29
+ * reads "Rent: 1,050 (40%), in Housing, in Fixed costs". In the name rather than said once
30
+ * by the frame, because Home, End and a click land on a tile without passing its frame.
31
+ */
32
+ inGroup: (name: string, group: string) => string;
33
+ }
34
+
35
+ export const DEFAULT_TREEMAP_LABELS: TreemapLabels = {
36
+ tile: (name, value, share) => `${name}: ${value} (${share})`,
37
+ group: (name, value, share) => `${name}, group: ${value} (${share})`,
38
+ inGroup: (name, group) => `${name}, in ${group}`,
39
+ };
@@ -0,0 +1,210 @@
1
+ // Where `Treemap` draws each node — a pure function of the nodes, the chart's size and the
2
+ // text size, with no recharts in it (0.52 code review of treemap.tsx, findings 1 and 8).
3
+ //
4
+ // recharts lays nested data out itself, edge to edge, and 0.52 first made the groups' room
5
+ // afterwards: a group's cell took its band and margin out of its rectangle and each child's
6
+ // cell SQUEEZED the rectangle recharts gave it into what was left. Two faults followed.
7
+ // A fixed 23px is a different share of every group, so a €100 tile in a 61px group was
8
+ // drawn at two thirds of a €100 tile in a 300px one — in a chart whose one promise is that
9
+ // area is share. And the squeeze ran through a cache the group's cell wrote during render
10
+ // for its children's cells to read, which held only because recharts renders a group
11
+ // before its children.
12
+ //
13
+ // So the layout is made here, up front: squarified as recharts does it, with each group
14
+ // asking for its tiles' area PLUS its frame's, and its tiles laid out in its body. A
15
+ // frame's area depends on the rectangle it gets, so the layout is run again with each
16
+ // group's frame as measured until no frame moves by a pixel — two or three rounds.
17
+
18
+ export interface Box {
19
+ x: number;
20
+ y: number;
21
+ width: number;
22
+ height: number;
23
+ }
24
+
25
+ /** What the layout needs of a node: its key, its value, and a group's nodes. */
26
+ export interface LayoutNode {
27
+ path: string;
28
+ size: number;
29
+ children?: readonly LayoutNode[];
30
+ }
31
+
32
+ /** A node as drawn: its rectangle, and for a group the body its nodes fill and whether
33
+ * its band is drawn. Whole pixels, on shared edges, so neighbours meet without a seam. */
34
+ export interface Placed {
35
+ box: Box;
36
+ body?: Box;
37
+ banded?: boolean;
38
+ }
39
+
40
+ const PHI = (1 + Math.sqrt(5)) / 2;
41
+
42
+ /**
43
+ * A group's band, in px at Normal, × the text size's scale: the 20px floor a tile keeps
44
+ * for its own name, so the group's name sits in it as a tile's does in a tile.
45
+ */
46
+ export const BAND = 20;
47
+ /**
48
+ * The frame's margin round its body, in px. Each tile keeps its 2px gutter, half of it
49
+ * inside the tile, so 3 leaves one pixel of the frame's own colour between the group's
50
+ * gutter and its tiles' — the frame reads as one outline round the group, not as a gutter
51
+ * that happens to be wider.
52
+ */
53
+ export const FRAME_MARGIN = 3;
54
+ /**
55
+ * The least of a group's height its body keeps under the band: 1/φ. At Normal that is a
56
+ * group of 61px (20 band + 3 margin = 0.382 of it), whose body of 38px still holds a
57
+ * tile's name and its second line (the note's 36px floor) — so a single row of tiles under
58
+ * the band keeps both. A smaller group draws no band, and its name is in its tiles'
59
+ * accessible names and its tooltip rather than over their area. Since the frame's area is
60
+ * given to the group (above), this bounds the frame's share of the picture, not the tiles'.
61
+ */
62
+ export const BODY_SHARE = 1 / PHI;
63
+
64
+ /** A group drawn at `box`: whether it has the room for its band (see {@link BODY_SHARE};
65
+ * and 44px across, the floor of a word), and the body its nodes are drawn into. */
66
+ export function groupBody(box: Box, scale: number): { banded: boolean; body: Box } {
67
+ const band = BAND * scale;
68
+ const margin = Math.min(FRAME_MARGIN, Math.floor(box.width / 4), Math.floor(box.height / 4));
69
+ const banded = box.width >= 44 * scale && box.height - band - margin >= box.height * BODY_SHARE;
70
+ const top = banded ? band : margin;
71
+ return {
72
+ banded,
73
+ body: {
74
+ x: box.x + margin,
75
+ y: box.y + top,
76
+ width: Math.max(0, box.width - 2 * margin),
77
+ height: Math.max(0, box.height - top - margin),
78
+ },
79
+ };
80
+ }
81
+
82
+ /** The worst aspect ratio in a row of `area` along `side`, against the target `ratio`. */
83
+ function worst(area: number, min: number, max: number, side: number, ratio: number): number {
84
+ const along = side * side;
85
+ const across = area * area;
86
+ if (across === 0 || min === 0) return Infinity;
87
+ return Math.max((along * max * ratio) / across, across / (along * min * ratio));
88
+ }
89
+
90
+ /**
91
+ * Bruls, Huizing and van Wijk's squarified layout, as recharts runs it: `weights` share
92
+ * out `rect` in order, a row at a time along its shorter side, and a row closes when the
93
+ * next node would make its worst tile further from φ:1 (recharts' default ratio). Returns
94
+ * one rectangle per weight, in order, in fractional pixels.
95
+ */
96
+ export function squarify(weights: readonly number[], rect: Box, ratio = PHI): Box[] {
97
+ const out: Box[] = weights.map(() => ({ x: rect.x, y: rect.y, width: 0, height: 0 }));
98
+ const sum = weights.reduce((acc, w) => acc + Math.max(0, w), 0);
99
+ if (!(sum > 0) || rect.width <= 0 || rect.height <= 0) return out;
100
+ const areas = weights.map((w) => (Math.max(0, w) * rect.width * rect.height) / sum);
101
+ let { x, y, width, height } = rect;
102
+ let i = 0;
103
+ while (i < areas.length) {
104
+ const side = Math.min(width, height);
105
+ let rowArea = 0;
106
+ let min = Infinity;
107
+ let max = 0;
108
+ let best = Infinity;
109
+ let j = i;
110
+ while (j < areas.length) {
111
+ const a = areas[j]!;
112
+ const score = worst(rowArea + a, Math.min(min, a), Math.max(max, a), side, ratio);
113
+ if (j > i && score > best) break;
114
+ rowArea += a;
115
+ min = Math.min(min, a);
116
+ max = Math.max(max, a);
117
+ best = score;
118
+ j += 1;
119
+ }
120
+ // The last row takes what is left, so rounding never leaves a sliver unpainted.
121
+ const last = j === areas.length;
122
+ if (side === width) {
123
+ // A row along the top, as wide as the space.
124
+ const thick = last ? height : rowArea / width;
125
+ let at = x;
126
+ for (let k = i; k < j; k++) {
127
+ const len = k === j - 1 ? x + width - at : (areas[k]! / rowArea) * width;
128
+ out[k] = { x: at, y, width: len, height: thick };
129
+ at += len;
130
+ }
131
+ y += thick;
132
+ height -= thick;
133
+ } else {
134
+ // A column at the left, as tall as the space.
135
+ const thick = last ? width : rowArea / height;
136
+ let at = y;
137
+ for (let k = i; k < j; k++) {
138
+ const len = k === j - 1 ? y + height - at : (areas[k]! / rowArea) * height;
139
+ out[k] = { x, y: at, width: thick, height: len };
140
+ at += len;
141
+ }
142
+ x += thick;
143
+ width -= thick;
144
+ }
145
+ i = j;
146
+ }
147
+ return out;
148
+ }
149
+
150
+ /** Whole pixels on the EDGES: neighbours share an edge, so they round it alike. */
151
+ function snap(b: Box): Box {
152
+ const x = Math.round(b.x);
153
+ const y = Math.round(b.y);
154
+ return { x, y, width: Math.round(b.x + b.width) - x, height: Math.round(b.y + b.height) - y };
155
+ }
156
+
157
+ /** The rounds the frames get to settle; three is usual, more only when a band switches. */
158
+ const ROUNDS = 8;
159
+
160
+ /**
161
+ * Every node of `nodes` placed in a `width` × `height` chart, by path.
162
+ *
163
+ * Each tile's area is its value's share of what is left for tiles once the frames have
164
+ * theirs — the same density in every group and at the top. A group asks for its tiles'
165
+ * area and its own frame's (band and margin, as {@link groupBody} measures them on the
166
+ * rectangle it got last round), so its body holds exactly its tiles.
167
+ */
168
+ export function layoutTreemap(
169
+ nodes: readonly LayoutNode[],
170
+ width: number,
171
+ height: number,
172
+ scale: number,
173
+ ): Map<string, Placed> {
174
+ const total = nodes.reduce((acc, n) => acc + n.size, 0);
175
+ const frames = new Map<string, number>();
176
+ let placed = new Map<string, Placed>();
177
+ for (let round = 0; round < ROUNDS; round++) {
178
+ const framed = [...frames.values()].reduce((acc, a) => acc + a, 0);
179
+ const spare = width * height - framed;
180
+ // Frames that would take the whole chart (a tiny chart of many groups) leave nothing
181
+ // to share; the tiles then take the density they would have without frames.
182
+ const density = total > 0 ? (spare > 0 ? spare : width * height) / total : 0;
183
+ const need = (n: LayoutNode): number =>
184
+ n.children ? (frames.get(n.path) ?? 0) + n.children.reduce((acc, c) => acc + need(c), 0) : n.size * density;
185
+ let moved = 0;
186
+ placed = new Map();
187
+ const place = (list: readonly LayoutNode[], rect: Box) => {
188
+ const boxes = squarify(
189
+ list.map((n) => need(n)),
190
+ rect,
191
+ );
192
+ list.forEach((n, i) => {
193
+ const box = snap(boxes[i]!);
194
+ if (!n.children) {
195
+ placed.set(n.path, { box });
196
+ return;
197
+ }
198
+ const { banded, body } = groupBody(box, scale);
199
+ placed.set(n.path, { box, body, banded });
200
+ const frame = box.width * box.height - body.width * body.height;
201
+ moved = Math.max(moved, Math.abs(frame - (frames.get(n.path) ?? 0)));
202
+ frames.set(n.path, frame);
203
+ place(n.children, body);
204
+ });
205
+ };
206
+ place(nodes, { x: 0, y: 0, width, height });
207
+ if (moved < 1) break;
208
+ }
209
+ return placed;
210
+ }