@eifi1/ui-kit 0.51.7 → 0.53.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 (775) hide show
  1. package/README.md +178 -67
  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 +1 -3
  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.js +2 -1
  39. package/dist/auth/complete-name-dialog.js.map +1 -1
  40. package/dist/auth/forgot-password-form-labels.js +1 -1
  41. package/dist/auth/forgot-password-form-labels.js.map +1 -1
  42. package/dist/auth/forgot-password-form.js +7 -2
  43. package/dist/auth/forgot-password-form.js.map +1 -1
  44. package/dist/auth/register-form-labels.js +1 -1
  45. package/dist/auth/register-form-labels.js.map +1 -1
  46. package/dist/auth/reset-password-form-labels.js +1 -1
  47. package/dist/auth/reset-password-form-labels.js.map +1 -1
  48. package/dist/auth/reset-password-form.js +5 -1
  49. package/dist/auth/reset-password-form.js.map +1 -1
  50. package/dist/auth/sign-in-form-labels.js +1 -1
  51. package/dist/auth/sign-in-form-labels.js.map +1 -1
  52. package/dist/auth/status-parts.d.ts +0 -3
  53. package/dist/auth/status-parts.js +0 -4
  54. package/dist/auth/status-parts.js.map +1 -1
  55. package/dist/auth/verify-email-labels.js +1 -1
  56. package/dist/auth/verify-email-labels.js.map +1 -1
  57. package/dist/auth/verify-email.js +7 -2
  58. package/dist/auth/verify-email.js.map +1 -1
  59. package/dist/billing/cancel-subscription.d.ts +10 -7
  60. package/dist/billing/cancel-subscription.js +6 -6
  61. package/dist/billing/cancel-subscription.js.map +1 -1
  62. package/dist/billing/plan-card.d.ts +5 -3
  63. package/dist/billing/plan-card.js +7 -8
  64. package/dist/billing/plan-card.js.map +1 -1
  65. package/dist/billing/plan-change-labels.d.ts +42 -0
  66. package/dist/billing/plan-change-labels.js +22 -0
  67. package/dist/billing/plan-change-labels.js.map +1 -0
  68. package/dist/billing/plan-switch.d.ts +9 -6
  69. package/dist/billing/plan-switch.js +7 -5
  70. package/dist/billing/plan-switch.js.map +1 -1
  71. package/dist/chart.d.ts +4 -3
  72. package/dist/chart.js +72 -4
  73. package/dist/chart.js.map +1 -1
  74. package/dist/components/account-chips.d.ts +5 -5
  75. package/dist/components/account-chips.js +11 -13
  76. package/dist/components/account-chips.js.map +1 -1
  77. package/dist/components/alert-banner.d.ts +16 -5
  78. package/dist/components/alert-banner.js +46 -1
  79. package/dist/components/alert-banner.js.map +1 -1
  80. package/dist/components/amount-input.d.ts +13 -0
  81. package/dist/components/amount-input.js +1 -0
  82. package/dist/components/amount-input.js.map +1 -1
  83. package/dist/components/autocomplete.js +57 -65
  84. package/dist/components/autocomplete.js.map +1 -1
  85. package/dist/components/bulk-action-bar.d.ts +12 -2
  86. package/dist/components/bulk-action-bar.js +65 -21
  87. package/dist/components/bulk-action-bar.js.map +1 -1
  88. package/dist/components/button-look.d.ts +5 -5
  89. package/dist/components/button-look.js.map +1 -1
  90. package/dist/components/button.d.ts +2 -2
  91. package/dist/components/button.js.map +1 -1
  92. package/dist/components/chart-edge.d.ts +16 -0
  93. package/dist/components/chart-edge.js +14 -1
  94. package/dist/components/chart-edge.js.map +1 -1
  95. package/dist/components/chart-figure.d.ts +13 -0
  96. package/dist/components/chart-figure.js +15 -0
  97. package/dist/components/chart-figure.js.map +1 -0
  98. package/dist/components/chart-zoom-core.js +1 -4
  99. package/dist/components/chart-zoom-core.js.map +1 -1
  100. package/dist/components/chart.d.ts +8 -1
  101. package/dist/components/chart.js +19 -10
  102. package/dist/components/chart.js.map +1 -1
  103. package/dist/components/combobox-core.d.ts +111 -2
  104. package/dist/components/combobox-core.js +148 -42
  105. package/dist/components/combobox-core.js.map +1 -1
  106. package/dist/components/combobox.d.ts +1 -1
  107. package/dist/components/combobox.js +141 -130
  108. package/dist/components/combobox.js.map +1 -1
  109. package/dist/components/copy-button.d.ts +6 -5
  110. package/dist/components/copy-button.js +5 -3
  111. package/dist/components/copy-button.js.map +1 -1
  112. package/dist/components/country-select.js +2 -2
  113. package/dist/components/country-select.js.map +1 -1
  114. package/dist/components/data-table-column-settings.d.ts +1 -1
  115. package/dist/components/data-table-column-settings.js +33 -7
  116. package/dist/components/data-table-column-settings.js.map +1 -1
  117. package/dist/components/data-table-filters.d.ts +4 -2
  118. package/dist/components/data-table-filters.js +2 -2
  119. package/dist/components/data-table-filters.js.map +1 -1
  120. package/dist/components/data-table-fit.d.ts +6 -4
  121. package/dist/components/data-table-fit.js +4 -1
  122. package/dist/components/data-table-fit.js.map +1 -1
  123. package/dist/components/data-table-groups.d.ts +1 -1
  124. package/dist/components/data-table-groups.js.map +1 -1
  125. package/dist/components/data-table-head.d.ts +1 -1
  126. package/dist/components/data-table-head.js +15 -12
  127. package/dist/components/data-table-head.js.map +1 -1
  128. package/dist/components/data-table-mobile.d.ts +12 -7
  129. package/dist/components/data-table-mobile.js +43 -30
  130. package/dist/components/data-table-mobile.js.map +1 -1
  131. package/dist/components/data-table-pagination.js +11 -6
  132. package/dist/components/data-table-pagination.js.map +1 -1
  133. package/dist/components/data-table-resize.d.ts +1 -1
  134. package/dist/components/data-table-resize.js.map +1 -1
  135. package/dist/components/data-table-row-actions.d.ts +2 -2
  136. package/dist/components/data-table-row-actions.js.map +1 -1
  137. package/dist/components/data-table-row.d.ts +6 -2
  138. package/dist/components/data-table-row.js +17 -10
  139. package/dist/components/data-table-row.js.map +1 -1
  140. package/dist/components/data-table-selection.d.ts +1 -1
  141. package/dist/components/data-table-selection.js.map +1 -1
  142. package/dist/components/data-table-shared.d.ts +10 -2
  143. package/dist/components/data-table-shared.js +18 -0
  144. package/dist/components/data-table-shared.js.map +1 -1
  145. package/dist/components/data-table-sort.d.ts +21 -2
  146. package/dist/components/data-table-sort.js +24 -0
  147. package/dist/components/data-table-sort.js.map +1 -1
  148. package/dist/components/data-table-virtual.d.ts +1 -1
  149. package/dist/components/data-table-virtual.js +18 -6
  150. package/dist/components/data-table-virtual.js.map +1 -1
  151. package/dist/components/data-table.d.ts +13 -4
  152. package/dist/components/data-table.js +139 -36
  153. package/dist/components/data-table.js.map +1 -1
  154. package/dist/components/date-field.d.ts +25 -3
  155. package/dist/components/date-field.js +33 -8
  156. package/dist/components/date-field.js.map +1 -1
  157. package/dist/components/date-picker.d.ts +16 -3
  158. package/dist/components/date-picker.js +55 -26
  159. package/dist/components/date-picker.js.map +1 -1
  160. package/dist/components/date-range-picker.d.ts +38 -24
  161. package/dist/components/date-range-picker.js +23 -7
  162. package/dist/components/date-range-picker.js.map +1 -1
  163. package/dist/components/error-boundary.js +37 -30
  164. package/dist/components/error-boundary.js.map +1 -1
  165. package/dist/components/{ui-labels.d.ts → field-base-labels.d.ts} +0 -2
  166. package/dist/components/{ui-labels.js → field-base-labels.js} +2 -9
  167. package/dist/components/field-base-labels.js.map +1 -0
  168. package/dist/components/field-base.d.ts +4 -3
  169. package/dist/components/field-base.js +3 -3
  170. package/dist/components/field-base.js.map +1 -1
  171. package/dist/components/form-actions.js +11 -5
  172. package/dist/components/form-actions.js.map +1 -1
  173. package/dist/components/hover-menu.d.ts +3 -0
  174. package/dist/components/hover-menu.js +5 -3
  175. package/dist/components/hover-menu.js.map +1 -1
  176. package/dist/components/icon-button.js +14 -9
  177. package/dist/components/icon-button.js.map +1 -1
  178. package/dist/components/inline-confirm.d.ts +43 -0
  179. package/dist/components/inline-confirm.js +67 -0
  180. package/dist/components/inline-confirm.js.map +1 -0
  181. package/dist/components/inline-entity-combobox.d.ts +4 -3
  182. package/dist/components/inline-entity-combobox.js +148 -140
  183. package/dist/components/inline-entity-combobox.js.map +1 -1
  184. package/dist/components/input.js +1 -1
  185. package/dist/components/input.js.map +1 -1
  186. package/dist/components/jump-calendar.js +28 -112
  187. package/dist/components/jump-calendar.js.map +1 -1
  188. package/dist/components/legal-page.d.ts +3 -1
  189. package/dist/components/legal-page.js +3 -2
  190. package/dist/components/legal-page.js.map +1 -1
  191. package/dist/components/legal.d.ts +4 -2
  192. package/dist/components/legal.js.map +1 -1
  193. package/dist/components/lightbox.d.ts +2 -2
  194. package/dist/components/lightbox.js +17 -6
  195. package/dist/components/lightbox.js.map +1 -1
  196. package/dist/components/list.d.ts +6 -2
  197. package/dist/components/list.js +3 -2
  198. package/dist/components/list.js.map +1 -1
  199. package/dist/components/measured-grid.d.ts +1 -1
  200. package/dist/components/measured-grid.js +2 -1
  201. package/dist/components/measured-grid.js.map +1 -1
  202. package/dist/components/mini-calendar.js +3 -5
  203. package/dist/components/mini-calendar.js.map +1 -1
  204. package/dist/components/modal.js +3 -1
  205. package/dist/components/modal.js.map +1 -1
  206. package/dist/components/month-grid.d.ts +55 -0
  207. package/dist/components/month-grid.js +148 -0
  208. package/dist/components/month-grid.js.map +1 -0
  209. package/dist/components/month-picker.d.ts +36 -4
  210. package/dist/components/month-picker.js +123 -146
  211. package/dist/components/month-picker.js.map +1 -1
  212. package/dist/components/multi-select.d.ts +2 -2
  213. package/dist/components/multi-select.js +11 -6
  214. package/dist/components/multi-select.js.map +1 -1
  215. package/dist/components/nav-pills.d.ts +1 -1
  216. package/dist/components/nav-pills.js.map +1 -1
  217. package/dist/components/picker-sheet.js +2 -1
  218. package/dist/components/picker-sheet.js.map +1 -1
  219. package/dist/components/pie-chart-labels.d.ts +7 -0
  220. package/dist/components/pie-chart-labels.js +1 -0
  221. package/dist/components/pie-chart-labels.js.map +1 -1
  222. package/dist/components/pie-chart.d.ts +5 -3
  223. package/dist/components/pie-chart.js +7 -22
  224. package/dist/components/pie-chart.js.map +1 -1
  225. package/dist/components/popover.d.ts +3 -0
  226. package/dist/components/popover.js +7 -1
  227. package/dist/components/popover.js.map +1 -1
  228. package/dist/components/row-actions.js +2 -1
  229. package/dist/components/row-actions.js.map +1 -1
  230. package/dist/components/series-chart-axes.d.ts +4 -4
  231. package/dist/components/series-chart-axes.js.map +1 -1
  232. package/dist/components/series-chart-labels.d.ts +7 -4
  233. package/dist/components/series-chart-labels.js.map +1 -1
  234. package/dist/components/series-chart.d.ts +92 -23
  235. package/dist/components/series-chart.js +74 -30
  236. package/dist/components/series-chart.js.map +1 -1
  237. package/dist/components/share-card.js +3 -3
  238. package/dist/components/share-card.js.map +1 -1
  239. package/dist/components/tabs-labels.d.ts +2 -0
  240. package/dist/components/tabs-labels.js +11 -0
  241. package/dist/components/tabs-labels.js.map +1 -0
  242. package/dist/components/tabs.d.ts +1 -1
  243. package/dist/components/tabs.js +1 -1
  244. package/dist/components/tabs.js.map +1 -1
  245. package/dist/components/toggle-legend.d.ts +2 -2
  246. package/dist/components/toggle-legend.js +6 -6
  247. package/dist/components/toggle-legend.js.map +1 -1
  248. package/dist/components/translation-review-editor.d.ts +4 -2
  249. package/dist/components/translation-review-editor.js +2 -3
  250. package/dist/components/translation-review-editor.js.map +1 -1
  251. package/dist/components/translation-review.d.ts +2 -1
  252. package/dist/components/translation-review.js +2 -2
  253. package/dist/components/translation-review.js.map +1 -1
  254. package/dist/components/treemap-labels.d.ts +31 -0
  255. package/dist/components/treemap-labels.js +10 -0
  256. package/dist/components/treemap-labels.js.map +1 -0
  257. package/dist/components/treemap-layout.d.ts +62 -0
  258. package/dist/components/treemap-layout.js +126 -0
  259. package/dist/components/treemap-layout.js.map +1 -0
  260. package/dist/components/treemap.d.ts +167 -19
  261. package/dist/components/treemap.js +340 -100
  262. package/dist/components/treemap.js.map +1 -1
  263. package/dist/components/use-table-state.d.ts +5 -5
  264. package/dist/components/use-table-state.js +4 -1
  265. package/dist/components/use-table-state.js.map +1 -1
  266. package/dist/data-table.d.ts +1 -2
  267. package/dist/data-table.js +1 -4
  268. package/dist/data-table.js.map +1 -1
  269. package/dist/demo/demo-countdown.d.ts +0 -5
  270. package/dist/demo/demo-countdown.js +0 -4
  271. package/dist/demo/demo-countdown.js.map +1 -1
  272. package/dist/eslint/index.js +1 -1
  273. package/dist/eslint/role-utilities.d.ts +36 -7
  274. package/dist/eslint/role-utilities.js +42 -9
  275. package/dist/eslint/role-utilities.js.map +1 -1
  276. package/dist/feedback/feedback-dialog.d.ts +25 -16
  277. package/dist/feedback/feedback-dialog.js +6 -2
  278. package/dist/feedback/feedback-dialog.js.map +1 -1
  279. package/dist/feedback/feedback-mutation.d.ts +18 -0
  280. package/dist/feedback/feedback-mutation.js +8 -0
  281. package/dist/feedback/feedback-mutation.js.map +1 -0
  282. package/dist/feedback/feedback-page-link.d.ts +53 -0
  283. package/dist/feedback/feedback-page-link.js +37 -0
  284. package/dist/feedback/feedback-page-link.js.map +1 -0
  285. package/dist/feedback/feedback-public-list.d.ts +8 -4
  286. package/dist/feedback/feedback-public-list.js +2 -2
  287. package/dist/feedback/feedback-public-list.js.map +1 -1
  288. package/dist/feedback/feedback-replies.d.ts +3 -1
  289. package/dist/feedback/feedback-replies.js +5 -4
  290. package/dist/feedback/feedback-replies.js.map +1 -1
  291. package/dist/feedback/feedback-row-detail-labels.js +0 -3
  292. package/dist/feedback/feedback-row-detail-labels.js.map +1 -1
  293. package/dist/feedback/feedback-row-detail.d.ts +33 -44
  294. package/dist/feedback/feedback-row-detail.js +28 -34
  295. package/dist/feedback/feedback-row-detail.js.map +1 -1
  296. package/dist/feedback/feedback-status-undo.d.ts +17 -14
  297. package/dist/feedback/feedback-status-undo.js +10 -15
  298. package/dist/feedback/feedback-status-undo.js.map +1 -1
  299. package/dist/feedback/feedback-submit-dialog.d.ts +1 -1
  300. package/dist/feedback/feedback-submit-dialog.js +1 -1
  301. package/dist/feedback/feedback-submit-dialog.js.map +1 -1
  302. package/dist/feedback/feedback-submit.js +9 -3
  303. package/dist/feedback/feedback-submit.js.map +1 -1
  304. package/dist/feedback/feedback-swipe.d.ts +1 -1
  305. package/dist/feedback/feedback-swipe.js.map +1 -1
  306. package/dist/feedback/feedback-table.d.ts +21 -9
  307. package/dist/feedback/feedback-table.js +45 -25
  308. package/dist/feedback/feedback-table.js.map +1 -1
  309. package/dist/feedback/feedback-thread-labels.d.ts +2 -2
  310. package/dist/feedback/feedback-thread-labels.js.map +1 -1
  311. package/dist/feedback/feedback-thread.d.ts +15 -23
  312. package/dist/feedback/feedback-thread.js +2 -1
  313. package/dist/feedback/feedback-thread.js.map +1 -1
  314. package/dist/feedback.d.ts +6 -6
  315. package/dist/feedback.js +90 -6
  316. package/dist/feedback.js.map +1 -1
  317. package/dist/hooks/use-focus-trap.d.ts +35 -0
  318. package/dist/hooks/use-focus-trap.js +6 -4
  319. package/dist/hooks/use-focus-trap.js.map +1 -1
  320. package/dist/hooks/use-hotkey.d.ts +5 -2
  321. package/dist/hooks/use-hotkey.js +5 -4
  322. package/dist/hooks/use-hotkey.js.map +1 -1
  323. package/dist/hooks/use-long-press.d.ts +7 -4
  324. package/dist/hooks/use-long-press.js +3 -0
  325. package/dist/hooks/use-long-press.js.map +1 -1
  326. package/dist/hooks/use-media-query.js +12 -4
  327. package/dist/hooks/use-media-query.js.map +1 -1
  328. package/dist/hooks/use-mounted.d.ts +22 -0
  329. package/dist/hooks/use-mounted.js +24 -0
  330. package/dist/hooks/use-mounted.js.map +1 -0
  331. package/dist/hooks/use-overlay-history.js +19 -3
  332. package/dist/hooks/use-overlay-history.js.map +1 -1
  333. package/dist/i18n/defaults.js +4 -9
  334. package/dist/i18n/defaults.js.map +1 -1
  335. package/dist/i18n/german.js +7 -18
  336. package/dist/i18n/german.js.map +1 -1
  337. package/dist/i18n/kit-labels.d.ts +9 -11
  338. package/dist/i18n/kit-labels.js.map +1 -1
  339. package/dist/i18n/locales/en.js +15 -64
  340. package/dist/i18n/locales/en.js.map +3 -3
  341. package/dist/i18n/locales/es.js +7 -18
  342. package/dist/i18n/locales/es.js.map +1 -1
  343. package/dist/i18n/locales/fr.js +20 -27
  344. package/dist/i18n/locales/fr.js.map +1 -1
  345. package/dist/i18n/locales/hu.js +9 -18
  346. package/dist/i18n/locales/hu.js.map +1 -1
  347. package/dist/i18n/locales/it.js +7 -19
  348. package/dist/i18n/locales/it.js.map +1 -1
  349. package/dist/i18n/locales/zh.js +8 -18
  350. package/dist/i18n/locales/zh.js.map +1 -1
  351. package/dist/i18n/review.js +12 -2
  352. package/dist/i18n/review.js.map +1 -1
  353. package/dist/i18n/shared-labels.js +0 -1
  354. package/dist/i18n/shared-labels.js.map +1 -1
  355. package/dist/index.d.ts +21 -23
  356. package/dist/index.js +50 -65
  357. package/dist/index.js.map +1 -1
  358. package/dist/landing/routing.d.ts +3 -1
  359. package/dist/landing/routing.js +4 -7
  360. package/dist/landing/routing.js.map +1 -1
  361. package/dist/lib/broadcast.d.ts +17 -0
  362. package/dist/lib/broadcast.js +30 -0
  363. package/dist/lib/broadcast.js.map +1 -0
  364. package/dist/lib/date-format.d.ts +37 -2
  365. package/dist/lib/date-format.js +34 -8
  366. package/dist/lib/date-format.js.map +1 -1
  367. package/dist/lib/day-format.d.ts +46 -0
  368. package/dist/lib/day-format.js +46 -0
  369. package/dist/lib/day-format.js.map +1 -0
  370. package/dist/lib/describe-failure.d.ts +14 -0
  371. package/dist/lib/describe-failure.js +9 -0
  372. package/dist/lib/describe-failure.js.map +1 -0
  373. package/dist/lib/direction.d.ts +16 -0
  374. package/dist/lib/direction.js +9 -1
  375. package/dist/lib/direction.js.map +1 -1
  376. package/dist/lib/focus-left.d.ts +63 -0
  377. package/dist/lib/focus-left.js +67 -0
  378. package/dist/lib/focus-left.js.map +1 -0
  379. package/dist/lib/format.js +5 -14
  380. package/dist/lib/format.js.map +1 -1
  381. package/dist/lib/http-status.d.ts +24 -0
  382. package/dist/lib/http-status.js +14 -0
  383. package/dist/lib/http-status.js.map +1 -0
  384. package/dist/lib/intl-cache.d.ts +14 -0
  385. package/dist/lib/intl-cache.js +15 -0
  386. package/dist/lib/intl-cache.js.map +1 -0
  387. package/dist/lib/iso-day.d.ts +11 -0
  388. package/dist/lib/iso-day.js +8 -0
  389. package/dist/lib/iso-day.js.map +1 -0
  390. package/dist/lib/lazy-with-fallback.d.ts +31 -0
  391. package/dist/lib/lazy-with-fallback.js +40 -0
  392. package/dist/lib/lazy-with-fallback.js.map +1 -0
  393. package/dist/lib/path-pattern.d.ts +34 -0
  394. package/dist/lib/path-pattern.js +24 -0
  395. package/dist/lib/path-pattern.js.map +1 -0
  396. package/dist/lib/reduced-motion.d.ts +2 -1
  397. package/dist/lib/reduced-motion.js.map +1 -1
  398. package/dist/lib/round.d.ts +2 -1
  399. package/dist/lib/round.js +2 -1
  400. package/dist/lib/round.js.map +1 -1
  401. package/dist/lib/safe-storage.d.ts +24 -5
  402. package/dist/lib/safe-storage.js +27 -2
  403. package/dist/lib/safe-storage.js.map +1 -1
  404. package/dist/lib/session-refresh.js +1 -1
  405. package/dist/lib/session-refresh.js.map +1 -1
  406. package/dist/lib/share-format.d.ts +13 -0
  407. package/dist/lib/share-format.js +10 -0
  408. package/dist/lib/share-format.js.map +1 -0
  409. package/dist/lib/text-case.d.ts +17 -0
  410. package/dist/lib/text-case.js +8 -0
  411. package/dist/lib/text-case.js.map +1 -0
  412. package/dist/lib/text-match.d.ts +29 -0
  413. package/dist/lib/text-match.js +20 -2
  414. package/dist/lib/text-match.js.map +1 -1
  415. package/dist/lib/thenable.d.ts +13 -0
  416. package/dist/lib/thenable.js +8 -0
  417. package/dist/lib/thenable.js.map +1 -0
  418. package/dist/lib/translation-review.d.ts +7 -2
  419. package/dist/lib/translation-review.js +4 -4
  420. package/dist/lib/translation-review.js.map +1 -1
  421. package/dist/notifications/device-zone-report.js +1 -1
  422. package/dist/notifications/device-zone-report.js.map +1 -1
  423. package/dist/notifications/notification-bell.d.ts +2 -1
  424. package/dist/notifications/notification-bell.js +3 -3
  425. package/dist/notifications/notification-bell.js.map +1 -1
  426. package/dist/notifications/notification-inbox.d.ts +10 -6
  427. package/dist/notifications/notification-inbox.js +26 -48
  428. package/dist/notifications/notification-inbox.js.map +1 -1
  429. package/dist/notifications/notification-parts.d.ts +3 -2
  430. package/dist/notifications/notification-parts.js +1 -3
  431. package/dist/notifications/notification-parts.js.map +1 -1
  432. package/dist/notifications/notification-types-setting.js +1 -1
  433. package/dist/notifications/notification-types-setting.js.map +1 -1
  434. package/dist/notifications/notifications-labels.d.ts +6 -0
  435. package/dist/notifications/notifications-labels.js +1 -0
  436. package/dist/notifications/notifications-labels.js.map +1 -1
  437. package/dist/notifications/push-device-setting.js +1 -1
  438. package/dist/notifications/push-device-setting.js.map +1 -1
  439. package/dist/notifications/push-devices-setting.d.ts +2 -1
  440. package/dist/notifications/push-devices-setting.js +27 -49
  441. package/dist/notifications/push-devices-setting.js.map +1 -1
  442. package/dist/notifications/quiet-hours-setting.d.ts +10 -3
  443. package/dist/notifications/quiet-hours-setting.js +65 -26
  444. package/dist/notifications/quiet-hours-setting.js.map +1 -1
  445. package/dist/notifications/unsubscribe-panel.js +4 -7
  446. package/dist/notifications/unsubscribe-panel.js.map +1 -1
  447. package/dist/notifications/use-push-device.d.ts +39 -1
  448. package/dist/notifications/use-push-device.js +28 -7
  449. package/dist/notifications/use-push-device.js.map +1 -1
  450. package/dist/offline/query-persistence.d.ts +3 -1
  451. package/dist/offline/query-persistence.js +19 -2
  452. package/dist/offline/query-persistence.js.map +1 -1
  453. package/dist/rhf/fields.d.ts +11 -4
  454. package/dist/rhf/fields.js.map +1 -1
  455. package/dist/search/command-palette.js +1 -1
  456. package/dist/search/command-palette.js.map +1 -1
  457. package/dist/search/global-search.js +19 -9
  458. package/dist/search/global-search.js.map +1 -1
  459. package/dist/search/search-index.d.ts +0 -6
  460. package/dist/search/search-index.js +0 -4
  461. package/dist/search/search-index.js.map +1 -1
  462. package/dist/search/use-command-key.d.ts +12 -1
  463. package/dist/search/use-command-key.js +3 -12
  464. package/dist/search/use-command-key.js.map +1 -1
  465. package/dist/search.d.ts +1 -1
  466. package/dist/search.js +6 -1
  467. package/dist/search.js.map +1 -1
  468. package/dist/settings/use-settings-focus.js +1 -0
  469. package/dist/settings/use-settings-focus.js.map +1 -1
  470. package/dist/shell/account-menu-language.d.ts +5 -3
  471. package/dist/shell/account-menu-language.js +2 -2
  472. package/dist/shell/account-menu-language.js.map +1 -1
  473. package/dist/shell/account-menu-text-size.d.ts +9 -6
  474. package/dist/shell/account-menu-text-size.js +2 -2
  475. package/dist/shell/account-menu-text-size.js.map +1 -1
  476. package/dist/shell/app-shell.d.ts +0 -10
  477. package/dist/shell/app-shell.js +1 -7
  478. package/dist/shell/app-shell.js.map +1 -1
  479. package/dist/shell/company-switcher.d.ts +1 -1
  480. package/dist/shell/company-switcher.js.map +1 -1
  481. package/dist/shell/dev-menu.d.ts +1 -1
  482. package/dist/shell/dev-menu.js +5 -18
  483. package/dist/shell/dev-menu.js.map +1 -1
  484. package/dist/shell/top-bar-actions.d.ts +1 -1
  485. package/dist/shell/top-bar-actions.js.map +1 -1
  486. package/dist/shell/top-bar-parts-labels.d.ts +1 -3
  487. package/dist/shell/top-bar-parts-labels.js +0 -1
  488. package/dist/shell/top-bar-parts-labels.js.map +1 -1
  489. package/dist/shell.d.ts +7 -10
  490. package/dist/shell.js +14 -23
  491. package/dist/shell.js.map +1 -1
  492. package/dist/sync/engine.d.ts +30 -4
  493. package/dist/sync/engine.js +172 -52
  494. package/dist/sync/engine.js.map +1 -1
  495. package/dist/sync.d.ts +2 -2
  496. package/dist/sync.js +2 -10
  497. package/dist/sync.js.map +1 -1
  498. package/dist/testing/css-variables.js +3 -8
  499. package/dist/testing/css-variables.js.map +1 -1
  500. package/dist/theme/chart-palette.d.ts +0 -5
  501. package/dist/theme/chart-palette.js +0 -2
  502. package/dist/theme/chart-palette.js.map +1 -1
  503. package/dist/theme/contrast.d.ts +2 -1
  504. package/dist/theme/contrast.js +3 -8
  505. package/dist/theme/contrast.js.map +1 -1
  506. package/dist/theme/palette-store.js +6 -6
  507. package/dist/theme/palette-store.js.map +1 -1
  508. package/dist/theme/text-size.js +3 -8
  509. package/dist/theme/text-size.js.map +1 -1
  510. package/dist/theme/theme-store.js +3 -6
  511. package/dist/theme/theme-store.js.map +1 -1
  512. package/dist/tour/tour-catalogue.d.ts +7 -4
  513. package/dist/tour/tour-catalogue.js +12 -10
  514. package/dist/tour/tour-catalogue.js.map +1 -1
  515. package/dist/tour/tour-dock.d.ts +0 -2
  516. package/dist/tour/tour-dock.js +0 -2
  517. package/dist/tour/tour-dock.js.map +1 -1
  518. package/dist/tour/tour-gates.d.ts +4 -0
  519. package/dist/tour/tour-gates.js +14 -0
  520. package/dist/tour/tour-gates.js.map +1 -1
  521. package/dist/tour/tour-overlay.d.ts +27 -0
  522. package/dist/tour/tour-overlay.js +741 -0
  523. package/dist/tour/tour-overlay.js.map +1 -0
  524. package/dist/tour/tour.d.ts +13 -3
  525. package/dist/tour/tour.js +59 -781
  526. package/dist/tour/tour.js.map +1 -1
  527. package/dist/tour/use-tour-progress.js +1 -1
  528. package/dist/tour/use-tour-progress.js.map +1 -1
  529. package/dist/wizard/stepper-nav.d.ts +5 -1
  530. package/dist/wizard/stepper-nav.js.map +1 -1
  531. package/dist/wizard/types.d.ts +6 -2
  532. package/dist/wizard/types.js.map +1 -1
  533. package/dist/wizard/use-wizard.d.ts +3 -1
  534. package/dist/wizard/use-wizard.js.map +1 -1
  535. package/dist/wizard/validation.d.ts +3 -1
  536. package/dist/wizard/validation.js.map +1 -1
  537. package/package.json +10 -6
  538. package/src/account/account-parts.ts +5 -25
  539. package/src/account/data-export-setting-labels.ts +1 -1
  540. package/src/account/delete-account-setting-labels.ts +1 -1
  541. package/src/account/email-change-setting-labels.ts +1 -1
  542. package/src/account/passkeys-setting.tsx +60 -38
  543. package/src/account/sessions-setting.tsx +18 -12
  544. package/src/admin/admin-action-confirm.tsx +1 -5
  545. package/src/admin/admin-parts.ts +11 -25
  546. package/src/admin/mail-test-card-labels.ts +1 -1
  547. package/src/admin/plan-change-labels.ts +5 -23
  548. package/src/admin/plan-change.tsx +7 -44
  549. package/src/admin/reviewer-scope-editor.tsx +3 -3
  550. package/src/auth/auth-errors-labels.ts +23 -0
  551. package/src/auth/auth-errors.ts +11 -38
  552. package/src/auth/complete-name-dialog.tsx +4 -1
  553. package/src/auth/forgot-password-form-labels.ts +1 -1
  554. package/src/auth/forgot-password-form.tsx +11 -6
  555. package/src/auth/register-form-labels.ts +1 -1
  556. package/src/auth/reset-password-form-labels.ts +1 -1
  557. package/src/auth/reset-password-form.tsx +8 -4
  558. package/src/auth/sign-in-form-labels.ts +1 -1
  559. package/src/auth/status-parts.tsx +0 -6
  560. package/src/auth/verify-email-labels.ts +1 -1
  561. package/src/auth/verify-email.tsx +11 -6
  562. package/src/billing/cancel-subscription.tsx +15 -12
  563. package/src/billing/plan-card.tsx +18 -10
  564. package/src/billing/plan-change-labels.ts +66 -0
  565. package/src/billing/plan-switch.tsx +15 -12
  566. package/src/chart.ts +73 -6
  567. package/src/components/account-chips.tsx +20 -23
  568. package/src/components/alert-banner.tsx +82 -5
  569. package/src/components/amount-input.tsx +18 -7
  570. package/src/components/autocomplete.tsx +64 -70
  571. package/src/components/bulk-action-bar.tsx +70 -2
  572. package/src/components/button-look.ts +5 -5
  573. package/src/components/button.tsx +2 -2
  574. package/src/components/chart-edge.ts +34 -1
  575. package/src/components/chart-figure.tsx +35 -0
  576. package/src/components/chart-zoom-core.tsx +6 -5
  577. package/src/components/chart.tsx +26 -5
  578. package/src/components/combobox-core.tsx +293 -62
  579. package/src/components/combobox.tsx +183 -153
  580. package/src/components/copy-button.tsx +34 -23
  581. package/src/components/country-select.tsx +16 -11
  582. package/src/components/data-table-column-settings.tsx +52 -10
  583. package/src/components/data-table-filters.ts +6 -4
  584. package/src/components/data-table-fit.ts +19 -5
  585. package/src/components/data-table-groups.tsx +1 -1
  586. package/src/components/data-table-head.tsx +32 -22
  587. package/src/components/data-table-mobile.tsx +61 -26
  588. package/src/components/data-table-pagination.tsx +21 -6
  589. package/src/components/data-table-resize.ts +1 -1
  590. package/src/components/data-table-row-actions.tsx +3 -3
  591. package/src/components/data-table-row.tsx +25 -14
  592. package/src/components/data-table-selection.ts +1 -1
  593. package/src/components/data-table-shared.tsx +33 -1
  594. package/src/components/data-table-sort.ts +57 -2
  595. package/src/components/data-table-virtual.ts +32 -8
  596. package/src/components/data-table.tsx +239 -68
  597. package/src/components/date-field.tsx +66 -9
  598. package/src/components/date-picker.tsx +125 -49
  599. package/src/components/date-range-picker.tsx +71 -36
  600. package/src/components/error-boundary.tsx +53 -39
  601. package/src/components/field-base-labels.ts +20 -0
  602. package/src/components/field-base.tsx +13 -7
  603. package/src/components/form-actions.tsx +20 -5
  604. package/src/components/hover-menu.tsx +18 -8
  605. package/src/components/icon-button.tsx +14 -9
  606. package/src/components/inline-confirm.tsx +116 -0
  607. package/src/components/inline-entity-combobox.tsx +197 -153
  608. package/src/components/input.tsx +1 -1
  609. package/src/components/jump-calendar.tsx +30 -146
  610. package/src/components/legal-page.tsx +10 -7
  611. package/src/components/legal.tsx +4 -2
  612. package/src/components/lightbox.tsx +21 -8
  613. package/src/components/list.tsx +10 -4
  614. package/src/components/measured-grid.tsx +8 -4
  615. package/src/components/mini-calendar.tsx +6 -5
  616. package/src/components/modal.tsx +6 -1
  617. package/src/components/month-grid.tsx +229 -0
  618. package/src/components/month-picker.tsx +192 -200
  619. package/src/components/multi-select.tsx +21 -9
  620. package/src/components/nav-pills.tsx +1 -1
  621. package/src/components/picker-sheet.tsx +12 -9
  622. package/src/components/pie-chart-labels.ts +8 -0
  623. package/src/components/pie-chart.tsx +22 -28
  624. package/src/components/popover.tsx +18 -1
  625. package/src/components/row-actions.tsx +2 -1
  626. package/src/components/series-chart-axes.ts +9 -4
  627. package/src/components/series-chart-labels.ts +7 -4
  628. package/src/components/series-chart.tsx +253 -87
  629. package/src/components/share-card.tsx +6 -6
  630. package/src/components/tabs-labels.ts +13 -0
  631. package/src/components/tabs.tsx +2 -2
  632. package/src/components/toggle-legend.tsx +16 -11
  633. package/src/components/translation-review-editor.tsx +6 -5
  634. package/src/components/translation-review.tsx +4 -3
  635. package/src/components/treemap-labels.ts +47 -0
  636. package/src/components/treemap-layout.ts +210 -0
  637. package/src/components/treemap.tsx +780 -138
  638. package/src/components/use-table-state.ts +12 -9
  639. package/src/data-table.ts +1 -4
  640. package/src/demo/demo-countdown.ts +3 -8
  641. package/src/eslint/role-utilities.ts +97 -19
  642. package/src/feedback/feedback-dialog.tsx +30 -19
  643. package/src/feedback/feedback-mutation.ts +20 -0
  644. package/src/feedback/feedback-page-link.ts +90 -0
  645. package/src/feedback/feedback-public-list.tsx +13 -7
  646. package/src/feedback/feedback-replies.tsx +13 -6
  647. package/src/feedback/feedback-row-detail-labels.ts +0 -3
  648. package/src/feedback/feedback-row-detail.tsx +70 -84
  649. package/src/feedback/feedback-status-undo.ts +28 -28
  650. package/src/feedback/feedback-submit-dialog.tsx +2 -2
  651. package/src/feedback/feedback-submit.tsx +21 -7
  652. package/src/feedback/feedback-swipe.tsx +1 -1
  653. package/src/feedback/feedback-table.tsx +86 -38
  654. package/src/feedback/feedback-thread-labels.ts +2 -2
  655. package/src/feedback/feedback-thread.tsx +18 -26
  656. package/src/feedback.ts +89 -6
  657. package/src/hooks/use-focus-trap.ts +8 -24
  658. package/src/hooks/use-hotkey.ts +24 -7
  659. package/src/hooks/use-long-press.ts +16 -2
  660. package/src/hooks/use-media-query.ts +20 -4
  661. package/src/hooks/use-mounted.ts +39 -0
  662. package/src/hooks/use-overlay-history.ts +32 -3
  663. package/src/i18n/defaults.ts +4 -9
  664. package/src/i18n/german.ts +8 -19
  665. package/src/i18n/kit-labels.tsx +9 -11
  666. package/src/i18n/locales/es.ts +8 -19
  667. package/src/i18n/locales/fr.ts +21 -30
  668. package/src/i18n/locales/hu.ts +10 -19
  669. package/src/i18n/locales/it.ts +8 -20
  670. package/src/i18n/locales/zh.ts +9 -19
  671. package/src/i18n/review.ts +12 -2
  672. package/src/i18n/shared-labels.ts +0 -1
  673. package/src/index.ts +57 -49
  674. package/src/landing/routing.tsx +14 -10
  675. package/src/lib/broadcast.ts +52 -0
  676. package/src/lib/date-format.ts +89 -13
  677. package/src/lib/day-format.ts +96 -0
  678. package/src/lib/describe-failure.ts +18 -0
  679. package/src/lib/direction.ts +39 -0
  680. package/src/lib/focus-left.ts +156 -0
  681. package/src/lib/format.ts +5 -17
  682. package/src/lib/http-status.ts +38 -0
  683. package/src/lib/intl-cache.ts +25 -0
  684. package/src/lib/iso-day.ts +13 -0
  685. package/src/lib/lazy-with-fallback.ts +82 -0
  686. package/src/lib/path-pattern.ts +55 -0
  687. package/src/lib/reduced-motion.ts +2 -1
  688. package/src/lib/round.ts +7 -2
  689. package/src/lib/safe-storage.ts +48 -6
  690. package/src/lib/session-refresh.ts +1 -1
  691. package/src/lib/share-format.ts +18 -0
  692. package/src/lib/text-case.ts +19 -0
  693. package/src/lib/text-match.ts +57 -2
  694. package/src/lib/thenable.ts +19 -0
  695. package/src/lib/translation-review.ts +13 -5
  696. package/src/notifications/device-zone-report.ts +1 -1
  697. package/src/notifications/notification-bell.tsx +7 -4
  698. package/src/notifications/notification-inbox.tsx +40 -58
  699. package/src/notifications/notification-parts.tsx +3 -4
  700. package/src/notifications/notification-types-setting.tsx +1 -1
  701. package/src/notifications/notifications-labels.ts +7 -0
  702. package/src/notifications/push-device-setting.tsx +1 -1
  703. package/src/notifications/push-devices-setting.tsx +30 -55
  704. package/src/notifications/quiet-hours-setting.tsx +93 -31
  705. package/src/notifications/unsubscribe-panel.tsx +4 -7
  706. package/src/notifications/use-push-device.ts +76 -10
  707. package/src/offline/query-persistence.ts +35 -3
  708. package/src/rhf/fields.tsx +11 -4
  709. package/src/search/command-palette.tsx +2 -4
  710. package/src/search/global-search.tsx +36 -15
  711. package/src/search/search-index.ts +0 -15
  712. package/src/search/use-command-key.ts +13 -12
  713. package/src/search.ts +10 -1
  714. package/src/settings/use-settings-focus.ts +3 -0
  715. package/src/shell/account-menu-language.tsx +6 -4
  716. package/src/shell/account-menu-text-size.tsx +10 -7
  717. package/src/shell/app-shell.tsx +0 -13
  718. package/src/shell/company-switcher.tsx +1 -1
  719. package/src/shell/dev-menu.tsx +8 -22
  720. package/src/shell/top-bar-actions.tsx +1 -1
  721. package/src/shell/top-bar-parts-labels.ts +1 -4
  722. package/src/shell.ts +21 -17
  723. package/src/sync/engine.ts +339 -61
  724. package/src/sync.ts +2 -8
  725. package/src/testing/css-variables.ts +8 -9
  726. package/src/theme/chart-palette.ts +0 -2
  727. package/src/theme/contrast.ts +8 -9
  728. package/src/theme/palette-store.ts +9 -9
  729. package/src/theme/text-size.ts +6 -8
  730. package/src/theme/theme-store.ts +7 -9
  731. package/src/tour/tour-catalogue.tsx +26 -15
  732. package/src/tour/tour-dock.ts +0 -2
  733. package/src/tour/tour-gates.ts +23 -0
  734. package/src/tour/tour-overlay.tsx +1170 -0
  735. package/src/tour/tour.tsx +108 -1202
  736. package/src/tour/use-tour-progress.ts +1 -1
  737. package/src/wizard/stepper-nav.tsx +3 -1
  738. package/src/wizard/types.ts +11 -2
  739. package/src/wizard/use-wizard.ts +2 -1
  740. package/src/wizard/validation.ts +8 -2
  741. package/tokens.css +6 -5
  742. package/dist/components/field-sync-labels.d.ts +0 -2
  743. package/dist/components/field-sync-labels.js +0 -12
  744. package/dist/components/field-sync-labels.js.map +0 -1
  745. package/dist/components/field-sync.d.ts +0 -164
  746. package/dist/components/field-sync.js +0 -269
  747. package/dist/components/field-sync.js.map +0 -1
  748. package/dist/components/section-nav.d.ts +0 -37
  749. package/dist/components/section-nav.js +0 -33
  750. package/dist/components/section-nav.js.map +0 -1
  751. package/dist/components/sign-chip-labels.d.ts +0 -2
  752. package/dist/components/sign-chip-labels.js +0 -11
  753. package/dist/components/sign-chip-labels.js.map +0 -1
  754. package/dist/components/sign-chip.d.ts +0 -68
  755. package/dist/components/sign-chip.js +0 -47
  756. package/dist/components/sign-chip.js.map +0 -1
  757. package/dist/components/ui-labels.js.map +0 -1
  758. package/dist/lib/isin.d.ts +0 -28
  759. package/dist/lib/isin.js +0 -36
  760. package/dist/lib/isin.js.map +0 -1
  761. package/dist/shell/dev-switchers.d.ts +0 -6
  762. package/dist/shell/dev-switchers.js +0 -12
  763. package/dist/shell/dev-switchers.js.map +0 -1
  764. package/dist/shell/role-switcher.d.ts +0 -21
  765. package/dist/shell/role-switcher.js +0 -31
  766. package/dist/shell/role-switcher.js.map +0 -1
  767. package/src/components/field-sync-labels.ts +0 -13
  768. package/src/components/field-sync.tsx +0 -482
  769. package/src/components/section-nav.tsx +0 -65
  770. package/src/components/sign-chip-labels.ts +0 -12
  771. package/src/components/sign-chip.tsx +0 -124
  772. package/src/components/ui-labels.ts +0 -24
  773. package/src/lib/isin.ts +0 -62
  774. package/src/shell/dev-switchers.tsx +0 -18
  775. package/src/shell/role-switcher.tsx +0 -46
@@ -2,36 +2,20 @@
2
2
  // under a ‹ caption › whose caption opens a month grid. Moved out of date-picker.tsx as
3
3
  // it was (MOD-9, refactor audit 2026-10); internal, both pickers reach it through
4
4
  // `PanelCalendar`.
5
- import { useEffect, useId, useMemo, useRef, useState } from "react";
5
+ import { useId, useMemo, useRef, useState } from "react";
6
6
  import type { KeyboardEvent } from "react";
7
7
  import { ChevronDown, ChevronLeft, ChevronRight } from "lucide-react";
8
8
  import { cn } from "../lib/cn";
9
- import { horizontalStep } from "../lib/direction";
10
- import { monthKey, pad, parseIsoDate } from "../lib/dates";
9
+ import { monthKey, parseIsoDate } from "../lib/dates";
10
+ import { upperFirst } from "../lib/text-case";
11
11
  import { useKitLabels } from "../i18n/kit-labels";
12
- import { FOCUS_RING_WIDTH } from "./focus-ring";
13
12
  import { DEFAULT_MINI_CALENDAR_LABELS, MiniCalendar, type MiniCalendarProps } from "./mini-calendar";
14
- import { DEFAULT_MONTH_PICKER_LABELS } from "./month-picker";
13
+ import { DEFAULT_MONTH_PICKER_LABELS } from "./month-picker-labels";
14
+ import { MonthGrid, clampKey, firstOfKey, shiftKey, yearArrowsBlocked } from "./month-grid";
15
15
  import { claimEscape } from "../hooks/use-dismiss";
16
16
 
17
17
  // ── Month jump (`monthJump`, kastlan) ─────────────────────────────────────
18
18
 
19
- /** A "YYYY-MM" key as a count of months, and back: month arithmetic with no `Date`
20
- * rollover to step around. */
21
- const monthIndex = (key: string) => Number(key.slice(0, 4)) * 12 + Number(key.slice(5, 7)) - 1;
22
- const keyOfIndex = (index: number) => `${String(Math.floor(index / 12)).padStart(4, "0")}-${pad((index % 12) + 1)}`;
23
- const shiftKey = (key: string, delta: number) => keyOfIndex(monthIndex(key) + delta);
24
- /** The 1st of a "YYYY-MM" month, for `Intl` to name. */
25
- const firstOfKey = (key: string) => new Date(Number(key.slice(0, 4)), Number(key.slice(5, 7)) - 1, 1);
26
-
27
- /** Upper-case the first letter only, as `MonthPicker` does: "julio de 2026" heads a
28
- * panel as "Julio de 2026" — not "Julio De 2026", which CSS `capitalize` would write. */
29
- const upperFirst = (text: string, locale: string | undefined) =>
30
- text.charAt(0).toLocaleUpperCase(locale) + text.slice(1);
31
-
32
- /** Months per row of the month grid — `MonthPicker`'s 4×3. */
33
- const MONTH_COLUMNS = 3;
34
-
35
19
  /**
36
20
  * The month `MiniCalendar` opens on — the selection, or today, pulled inside the
37
21
  * bounds — worked out the way it does, so the caption drawn over a calendar that was
@@ -76,14 +60,14 @@ interface DayGridMount {
76
60
  * calendar's. What this keeps is `shown`, the month on screen, for the caption — fed by
77
61
  * the arrows here, by the calendar's `onMonthChange` (PageUp, arrowing off the edge),
78
62
  * and by the value, whose changes the calendar follows WITHOUT reporting them (a preset
79
- * in `commit="apply"` moves the grid to its start). That last one is mirrored below with
63
+ * under `apply` moves the grid to its start). That last one is mirrored below with
80
64
  * the calendar's own rule, and when it lands in another month the day grid is remounted
81
65
  * there rather than steered by `month`: a `month` that changes in the same render as the
82
66
  * value would win over the value's day, and the grid's tab stop would land on the
83
67
  * month's same-numbered day instead of the preset's start.
84
68
  *
85
- * The month grid is `MonthPicker`'s, redrawn here because that one is internal to its
86
- * file; same roles, keys and words (`monthPicker` labels).
69
+ * The month grid is `MonthPicker`'s own {@link MonthGrid} (month-grid.tsx, one since
70
+ * 0.52 — refactor audit 2026-10-30, DUP-11), with its words (`monthPicker` labels).
87
71
  */
88
72
  function JumpCalendar({
89
73
  from = "",
@@ -104,14 +88,11 @@ function JumpCalendar({
104
88
  const captionId = `${id}-caption`;
105
89
  const hintId = `${id}-hint`;
106
90
  const captionRef = useRef<HTMLButtonElement>(null);
107
- const monthsRef = useRef<HTMLDivElement>(null);
108
91
 
109
92
  const lo = min ? parseIsoDate(min) : null;
110
93
  const hi = max ? parseIsoDate(max) : null;
111
94
  const minKey = lo ? monthKey(lo) : null;
112
95
  const maxKey = hi ? monthKey(hi) : null;
113
- const outOfBounds = (key: string) => Boolean((minKey && key < minKey) || (maxKey && key > maxKey));
114
- const clampKey = (key: string) => (minKey && key < minKey ? minKey : maxKey && key > maxKey ? maxKey : key);
115
96
 
116
97
  const [view, setView] = useState<"days" | "months">("days");
117
98
  const [shown, setShown] = useState(() => openingMonth(from, to, lo, hi));
@@ -135,16 +116,6 @@ function JumpCalendar({
135
116
  }
136
117
  }
137
118
 
138
- // A month cell that has to take focus once it exists: opening the grid, and arrowing
139
- // across a year's edge, which relabels the same twelve buttons.
140
- const pendingFocus = useRef<string | null>(null);
141
- useEffect(() => {
142
- const key = pendingFocus.current;
143
- if (!key) return;
144
- pendingFocus.current = null;
145
- monthsRef.current?.querySelector<HTMLElement>(`[data-month="${key}"]`)?.focus();
146
- });
147
-
148
119
  const showMonth = (key: string) => {
149
120
  setShown(key);
150
121
  // Follows by `month`: the calendar keeps the day of the month (clamped), and the
@@ -152,9 +123,8 @@ function JumpCalendar({
152
123
  setDayGrid((d) => ({ ...d, month: key }));
153
124
  };
154
125
  const openMonths = () => {
155
- const start = clampKey(shown);
156
- pendingFocus.current = start;
157
- setActive(start);
126
+ // The grid takes the focus onto this month as it mounts.
127
+ setActive(clampKey(shown, minKey, maxKey));
158
128
  setView("months");
159
129
  };
160
130
  const closeMonths = (focusCaption: boolean) => {
@@ -168,10 +138,6 @@ function JumpCalendar({
168
138
  // Picked to go there: the focus goes with it, onto the days.
169
139
  setDayGrid((d) => ({ key: d.key + 1, month: key, focus: true }));
170
140
  };
171
- const moveActive = (key: string, focus: boolean) => {
172
- if (focus) pendingFocus.current = key;
173
- setActive(key);
174
- };
175
141
 
176
142
  const inDays = view === "days";
177
143
  // Escape in the month grid is "back", not "close": the month grid is a step INSIDE the
@@ -185,54 +151,12 @@ function JumpCalendar({
185
151
  closeMonths(true);
186
152
  };
187
153
 
188
- const onMonthKeyDown = (e: KeyboardEvent<HTMLButtonElement>) => {
189
- if (e.key === "Escape") return escapeToDays(e);
190
- // Left and right are visual: the grid runs the other way in a right-to-left panel.
191
- const step = horizontalStep(e.key, e.currentTarget);
192
- const col = (monthIndex(active) % 12) % MONTH_COLUMNS;
193
- let delta: number;
194
- switch (step ? "horizontal" : e.key) {
195
- case "horizontal":
196
- delta = step;
197
- break;
198
- case "ArrowUp":
199
- delta = -MONTH_COLUMNS;
200
- break;
201
- case "ArrowDown":
202
- delta = MONTH_COLUMNS;
203
- break;
204
- case "Home":
205
- delta = -col;
206
- break;
207
- case "End":
208
- delta = MONTH_COLUMNS - 1 - col;
209
- break;
210
- case "PageUp":
211
- delta = -12;
212
- break;
213
- case "PageDown":
214
- delta = 12;
215
- break;
216
- default:
217
- return;
218
- }
219
- // Before the no-op check: these keys also scroll the panel.
220
- e.preventDefault();
221
- if (delta !== 0) moveActive(shiftKey(active, delta), true);
222
- };
223
-
224
154
  const year = Number(active.slice(0, 4));
225
- // A year arrow is dead once every month of the year it leads to is out of bounds.
226
- const prevYearBlocked = Boolean(minKey && year - 1 < Number(minKey.slice(0, 4)));
227
- const nextYearBlocked = Boolean(maxKey && year + 1 > Number(maxKey.slice(0, 4)));
228
- const prevBlocked = !inDays && prevYearBlocked;
229
- const nextBlocked = !inDays && nextYearBlocked;
155
+ const yearBlocked = yearArrowsBlocked(active, minKey, maxKey);
156
+ const prevBlocked = !inDays && yearBlocked.previous;
157
+ const nextBlocked = !inDays && yearBlocked.next;
230
158
 
231
159
  const longName = useMemo(() => new Intl.DateTimeFormat(locale, { month: "long", year: "numeric" }), [locale]);
232
- const shortNames = useMemo(() => {
233
- const fmt = new Intl.DateTimeFormat(locale, { month: "short" });
234
- return Array.from({ length: 12 }, (_, i) => upperFirst(fmt.format(new Date(2000, i, 1)), locale));
235
- }, [locale]);
236
160
  const caption = inDays
237
161
  ? upperFirst(longName.format(firstOfKey(shown)), locale)
238
162
  : new Intl.DateTimeFormat(locale, { year: "numeric" }).format(new Date(year, 0, 1));
@@ -242,9 +166,6 @@ function JumpCalendar({
242
166
  const toDate = parseIsoDate(to);
243
167
  const fromKey = fromDate ? monthKey(fromDate) : null;
244
168
  const toKey = toDate ? monthKey(toDate) : null;
245
- const low = fromKey ?? toKey;
246
- const high = toKey ?? fromKey;
247
- const currentKey = monthKey(new Date());
248
169
 
249
170
  // Aria-disabled rather than disabled, like the day cells: a focused button that
250
171
  // turns `disabled` drops the focus to <body>, mid-panel.
@@ -262,8 +183,9 @@ function JumpCalendar({
262
183
  aria-label={inDays ? calendarText.previousMonth : monthText.previousYear}
263
184
  aria-disabled={prevBlocked || undefined}
264
185
  onClick={() => {
186
+ // Focus stays on the arrow being pressed — only the grid moves.
265
187
  if (inDays) showMonth(shiftKey(shown, -1));
266
- else if (!prevBlocked) moveActive(shiftKey(active, -12), false);
188
+ else if (!prevBlocked) setActive(shiftKey(active, -12));
267
189
  }}
268
190
  onKeyDown={escapeToDays}
269
191
  className={arrow}
@@ -294,7 +216,7 @@ function JumpCalendar({
294
216
  aria-disabled={nextBlocked || undefined}
295
217
  onClick={() => {
296
218
  if (inDays) showMonth(shiftKey(shown, 1));
297
- else if (!nextBlocked) moveActive(shiftKey(active, 12), false);
219
+ else if (!nextBlocked) setActive(shiftKey(active, 12));
298
220
  }}
299
221
  onKeyDown={escapeToDays}
300
222
  className={arrow}
@@ -323,58 +245,20 @@ function JumpCalendar({
323
245
  onMonthChange={showMonth}
324
246
  />
325
247
  ) : (
326
- <div ref={monthsRef} role="grid" aria-labelledby={captionId} className="grid gap-1">
327
- {Array.from({ length: 12 / MONTH_COLUMNS }, (_, row) => (
328
- <div key={row} role="row" className="grid grid-cols-3 gap-1">
329
- {Array.from({ length: MONTH_COLUMNS }, (_, c) => {
330
- const index = row * MONTH_COLUMNS + c;
331
- const key = keyOfIndex(year * 12 + index);
332
- const disabled = outOfBounds(key);
333
- const selected = low !== null && high !== null && key >= low && key <= high;
334
- const end = key === fromKey || key === toKey;
335
- const current = key === currentKey;
336
- return (
337
- <button
338
- key={c}
339
- type="button"
340
- role="gridcell"
341
- data-month={key}
342
- tabIndex={key === active ? 0 : -1}
343
- aria-label={monthText.month(longName.format(firstOfKey(key)))}
344
- aria-selected={selected}
345
- aria-disabled={disabled || undefined}
346
- aria-current={current ? "date" : undefined}
347
- onClick={() => {
348
- // The guard `disabled` would have been: out-of-bounds months stay
349
- // focusable, so the roving tab stop never falls into a hole.
350
- if (!disabled) pick(key);
351
- }}
352
- onKeyDown={onMonthKeyDown}
353
- className={cn(
354
- // 44px rows: the touch-target size, and four of them stand as tall
355
- // as a month of days, so the panel does not jump as the views swap.
356
- "h-11 rounded px-1 text-sm tabular-nums transition-colors",
357
- FOCUS_RING_WIDTH,
358
- "focus-visible:outline-none focus-visible:ring-inset",
359
- // A --brand ring on a --brand fill exists only in the DOM.
360
- end && !disabled ? "focus-visible:ring-brand-contrast" : "focus-visible:ring-brand",
361
- disabled
362
- ? "cursor-not-allowed text-placeholder"
363
- : end
364
- ? "bg-brand text-brand-contrast hover:bg-brand-hover"
365
- : selected
366
- ? "bg-brand-soft font-medium text-brand-muted hover:bg-brand-soft-hover"
367
- : "text-primary hover:bg-hover",
368
- current && !selected && !disabled && "ring-1 ring-inset ring-strong",
369
- )}
370
- >
371
- {shortNames[index]}
372
- </button>
373
- );
374
- })}
375
- </div>
376
- ))}
377
- </div>
248
+ <MonthGrid
249
+ active={active}
250
+ onActiveChange={setActive}
251
+ onPick={pick}
252
+ from={fromKey}
253
+ to={toKey}
254
+ minKey={minKey}
255
+ maxKey={maxKey}
256
+ currentKey={monthKey(new Date())}
257
+ locale={locale}
258
+ cellName={monthText.month}
259
+ labelledBy={captionId}
260
+ onEscape={escapeToDays}
261
+ />
378
262
  )}
379
263
  </div>
380
264
  );
@@ -7,7 +7,7 @@ import type { LabelOverride, UiKitLabelOverrides } from "../i18n/kit-labels";
7
7
  import { useNoIndex } from "../hooks/use-noindex";
8
8
  import { cn } from "../lib/cn";
9
9
  import { parseIsoDate } from "../lib/dates";
10
- import { formatDate } from "../lib/format";
10
+ import { useDayFormatter } from "../lib/day-format";
11
11
  import { Checkbox } from "./checkbox";
12
12
  import type { CheckboxProps } from "./checkbox";
13
13
  import {
@@ -347,7 +347,9 @@ export interface LegalPageProps {
347
347
  * 2026-10-29, gap 8). Shown under the title as `legal.updated` — "Last updated:
348
348
  * 29 October 2026", "Stand: 29. Oktober 2026" — with the date written out in `locale`,
349
349
  * so it follows the page's language like every other kit word, the switch to the
350
- * binding version included. Left out, no line. One date per page: the imprint, the
350
+ * binding version included. Since 0.52 the `<UiKitProvider formatDate>` writes it when
351
+ * the app set one (its date preference, asked for the day without a weekday), as every
352
+ * other day the kit prints. Left out, no line. One date per page: the imprint, the
351
353
  * privacy policy and the terms change on their own days.
352
354
  *
353
355
  * An app that records which terms someone accepted (keksdose) stores the terms page's
@@ -524,6 +526,7 @@ export function LegalPage({
524
526
  useNoIndex(noIndex);
525
527
  const labels = useLegalLabels(labelsProp);
526
528
  const locale = useKitLocale(localeProp) ?? "en";
529
+ const day = useDayFormatter(undefined, locale);
527
530
  // Not memoised: `countryName` keeps one `Intl.DisplayNames` per locale, so naming the
528
531
  // country again is a lookup, and the context is rebuilt with the children anyway.
529
532
  const operatorText = legalOperatorText(operator, locale);
@@ -564,17 +567,17 @@ export function LegalPage({
564
567
  )}
565
568
  </p>
566
569
  ) : undefined;
567
- // A calendar day, written out in the page's language; `formatDate` reads a bare
568
- // "YYYY-MM-DD" as that day in every zone. A malformed date shows no line rather than a
570
+ // A calendar day, in the page's language — under the app's date preference when the
571
+ // provider has one (0.52, refactor audit 2026-10-30, DUP-2: "a label that identifies a
572
+ // day follows the preference"), else written out ("29 October 2026"); a bare
573
+ // "YYYY-MM-DD" is that day in every zone. A malformed date shows no line rather than a
569
574
  // made-up one ("2026-02-30" would roll over into March).
570
575
  const updatedValid = updated !== undefined && parseIsoDate(updated) !== null;
571
576
  if (updated !== undefined && !updatedValid) {
572
577
  warnLegalOnce(`LegalPage: updated="${updated}" is not a "YYYY-MM-DD" date; no "Last updated" line is shown.`);
573
578
  }
574
579
  const updatedLine = updatedValid ? (
575
- <time dateTime={updated}>
576
- {(labels.updated ?? DEFAULT_LEGAL_LABELS.updated!)(formatDate(updated, "long", { locale }))}
577
- </time>
580
+ <time dateTime={updated}>{(labels.updated ?? DEFAULT_LEGAL_LABELS.updated!)(day(updated, { style: "long" }))}</time>
578
581
  ) : undefined;
579
582
  const summaryLabels = labels.summary ?? DEFAULT_LEGAL_LABELS.summary!;
580
583
  const SummaryHeading = context.sectionHeading;
@@ -120,8 +120,10 @@ function languageName(code: string, locale: string): string {
120
120
  }
121
121
  }
122
122
 
123
- /** @internal The operator as the texts read it: its country named in `locale` (English
124
- * without one — `countryName`'s rule, so an app that set no locale reads English). */
123
+ /** The operator as the texts read it: its country named in `locale` (English without one —
124
+ * `countryName`'s rule, so an app that set no locale reads English). Public since 0.28.1,
125
+ * for an app's own footer label in the kit's words; it carried an `@internal` tag the
126
+ * barrel contradicted until 0.52 (API-8, refactor audit 2026-10-30). */
125
127
  export function legalOperatorText(operator: LegalOperator, locale: string = "en"): LegalOperatorText {
126
128
  return {
127
129
  ...operator,
@@ -4,6 +4,7 @@ import { ChevronLeft, ChevronRight, Download, ExternalLink, FileText, ZoomIn } f
4
4
 
5
5
  import { cn } from "../lib/cn";
6
6
  import { horizontalStep } from "../lib/direction";
7
+ import { hasContent } from "../lib/presence";
7
8
  import { useKitLabels, type LabelOverride } from "../i18n/kit-labels";
8
9
  import { useAuthedSrc } from "../hooks/use-authed-src";
9
10
  import { useBreakpoint } from "../hooks/use-breakpoint";
@@ -92,8 +93,8 @@ export interface LightboxProps {
92
93
  * loaded by the browser as usual. */
93
94
  fetcher?: AuthedFetcher | null;
94
95
  /** Previous from the first goes to the last, and next from the last to the first.
95
- * Default `false`: the buttons at the ends are disabled, which says where the set
96
- * ends. */
96
+ * Default `false`: the buttons at the ends refuse (`aria-disabled`, focus kept — 0.52),
97
+ * which says where the set ends. */
97
98
  loop?: boolean;
98
99
  /** Double-click (or double-tap) the picture, or the zoom button, to see it at full
99
100
  * size and pan by scrolling. Default `true`. Pinch zoom is the browser's own. */
@@ -114,6 +115,11 @@ export interface LightboxProps {
114
115
  /** Swipes shorter than this are taps, and a drag that is mostly vertical is a scroll. */
115
116
  const SWIPE_MIN_PX = 50;
116
117
 
118
+ /** An end arrow's look: a disabled `overlay` IconButton's (its 50% and its resting disc
119
+ * under hover), for the focusable kind — `disabled:` cannot match `aria-disabled`. */
120
+ const ARROW_AT_END =
121
+ "aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:hover:bg-[color-mix(in_srgb,var(--bg-inverse)_60%,transparent)]";
122
+
117
123
  /**
118
124
  * A full-screen viewer for a set of images (and files that are not images).
119
125
  *
@@ -336,8 +342,10 @@ export function Lightbox({
336
342
  onKeyDown={onKeyDown}
337
343
  data-lightbox=""
338
344
  footer={
339
- item?.caption !== undefined && item.caption !== null && item.caption !== false ? (
340
- <p className="me-auto min-w-0 text-sm text-secondary">{item.caption}</p>
345
+ // `hasContent` (refactor audit 2026-10-30, DUP-14): a `""` caption drew an empty
346
+ // footer bar.
347
+ hasContent(item?.caption) ? (
348
+ <p className="me-auto min-w-0 text-sm text-secondary">{item?.caption}</p>
341
349
  ) : undefined
342
350
  }
343
351
  >
@@ -355,14 +363,19 @@ export function Lightbox({
355
363
  {slide}
356
364
  </div>
357
365
  {count > 1 && (
366
+ // At an end the arrow refuses rather than turns `disabled` (refactor audit
367
+ // 2026-10-30, INP-4, JumpCalendar's rule): the press that reaches the last
368
+ // picture is made with the focus on ›, and a focused button that turns
369
+ // `disabled` drops the focus out of the viewer's trap to <body>. kastlan's
370
+ // ImageGrid and keksdose's invoice review open it without `loop`.
358
371
  <>
359
372
  <IconButton
360
373
  variant="overlay"
361
374
  size="lg"
362
375
  label={labels.previous}
363
- disabled={!canPrev}
376
+ aria-disabled={!canPrev || undefined}
364
377
  onClick={() => go(-1)}
365
- className="absolute start-3 top-1/2 -translate-y-1/2"
378
+ className={cn("absolute start-3 top-1/2 -translate-y-1/2", ARROW_AT_END)}
366
379
  tooltip={false}
367
380
  >
368
381
  <ChevronLeft className="rtl:-scale-x-100" />
@@ -371,9 +384,9 @@ export function Lightbox({
371
384
  variant="overlay"
372
385
  size="lg"
373
386
  label={labels.next}
374
- disabled={!canNext}
387
+ aria-disabled={!canNext || undefined}
375
388
  onClick={() => go(1)}
376
- className="absolute end-3 top-1/2 -translate-y-1/2"
389
+ className={cn("absolute end-3 top-1/2 -translate-y-1/2", ARROW_AT_END)}
377
390
  tooltip={false}
378
391
  >
379
392
  <ChevronRight className="rtl:-scale-x-100" />
@@ -3,6 +3,7 @@ import type { ComponentPropsWithoutRef, HTMLAttributes, MouseEvent, ReactElement
3
3
  import { ChevronDown, ExternalLink } from "lucide-react";
4
4
  import type { LucideIcon } from "lucide-react";
5
5
  import { cn } from "../lib/cn";
6
+ import { hasContent } from "../lib/presence";
6
7
  import { FOCUS_RING } from "./focus-ring";
7
8
  import { Spinner } from "./spinner";
8
9
  import { StatusDot } from "./status-dot";
@@ -67,8 +68,12 @@ export interface ListProps extends Omit<ComponentPropsWithoutRef<"ul">, "role">
67
68
  * A list of `limit` rows or fewer draws them all, with no such row. Rows are counted as
68
69
  * `Children` counts them: one per `ListItem`, a fragment as one.
69
70
  *
70
- * The row is a button with `aria-expanded`, controlling the list; it sits in the list
71
- * as `role="none"`, so a reader still hears "list, 5 items" for five rows.
71
+ * The row is a button with `aria-expanded`, controlling the list, in the list's last
72
+ * item: a reader hears "list, 6 items" for five rows and the Show all. Until 0.52 that
73
+ * item was `role="none"`, which left the button standing in the list itself — axe 4.13
74
+ * fails `aria-required-children` on it, and a `<ul>` may hold nothing but items (refactor
75
+ * audit 2026-10-30, found building 0.51.7; DataTable's phone list made the same call for
76
+ * its leading row).
72
77
  */
73
78
  limit?: number;
74
79
  }
@@ -122,7 +127,7 @@ export function List({
122
127
  dropped their state — an opened row, a typed input (audit 2026-10-30 DSP-20). */}
123
128
  {folds && !open ? rows.slice(0, Math.max(0, limit!)) : (rows ?? children)}
124
129
  {folds && (
125
- <li role="none" className={MORE_PAD[density]}>
130
+ <li className={MORE_PAD[density]}>
126
131
  <Button
127
132
  type="button"
128
133
  variant="link"
@@ -584,7 +589,8 @@ export function ListItem({
584
589
  const lock = useLockReason(commit, disabledReason);
585
590
  const locked = lock.locked && isButton && !expandable;
586
591
  const inert = disabled || loading || locked;
587
- const hasBody = children !== undefined && children !== null && children !== false;
592
+ // `hasContent` (refactor audit 2026-10-30, DUP-14): a `""` body opened an empty line.
593
+ const hasBody = hasContent(children);
588
594
  // Anything under the row's own line: the box turns into a column, and the target
589
595
  // takes its own corners and hover fill (see `children`).
590
596
  const stacked = hasBody || expandable;
@@ -6,6 +6,7 @@ import { horizontalStep } from "../lib/direction";
6
6
  // The locale's mark as far as a cell can hold it — the fields' answer, the same reason
7
7
  // (DUP-11, refactor audit 2026-10: a verbatim copy lived here).
8
8
  import { decimalMark } from "../lib/decimal-marks";
9
+ import { roundHalfAway } from "../lib/round";
9
10
  // The cell pair reads ONE cell, where a comma has no columns to separate and so is
10
11
  // always a decimal mark; `splitRow` and `parseRows` read a pasted table, where it may
11
12
  // be either and the line decides. See the three named rules at the top of table-text.
@@ -105,9 +106,12 @@ const ALL_VIEWS: readonly MeasuredGridView[] = ["cells", "text"];
105
106
  const withMark = (cell: string, mark: "," | ".") =>
106
107
  mark === "," && isCellNumber(cell) ? cell.replace(".", ",") : cell;
107
108
 
108
- /** A computed number as a draft cell: rounded to `digits`, with no trailing zeros. */
109
+ /** A computed number as a draft cell: rounded to `digits`, half away from zero as the
110
+ * figure is written (1.005 → 1.01), with no trailing zeros. `toFixed` rounded the binary
111
+ * value (1.00499… → "1"), a fourth rule beside lib/round's, which BUG-11 made the kit's
112
+ * one (0.52, refactor audit 2026-10-30, DUP-14). */
109
113
  const formatCell = (value: number, digits: number, mark: "," | ".") =>
110
- withMark(String(Number(value.toFixed(digits))), mark);
114
+ withMark(String(roundHalfAway(value, digits)), mark);
111
115
 
112
116
  const hasContent = (row: readonly string[]) => row.some((cell) => cell.trim() !== "");
113
117
 
@@ -187,7 +191,7 @@ export interface MeasuredGridProps extends Omit<ComponentPropsWithRef<"div">, "c
187
191
  /** A note under the table (which columns a layout expects, say). Also the grid's
188
192
  * description. */
189
193
  hint?: ReactNode;
190
- columns: MeasuredGridColumn[];
194
+ columns: readonly MeasuredGridColumn[];
191
195
  /** The draft — typically `useMeasuredRows().props`. */
192
196
  cells: string[][];
193
197
  onCells: (next: string[][]) => void;
@@ -332,7 +336,7 @@ interface Caret {
332
336
  }
333
337
 
334
338
  interface ViewProps {
335
- columns: MeasuredGridColumn[];
339
+ columns: readonly MeasuredGridColumn[];
336
340
  cells: string[][];
337
341
  onCells: (next: string[][]) => void;
338
342
  disabled?: boolean;
@@ -3,6 +3,7 @@ import type { ComponentPropsWithRef, KeyboardEvent, ReactNode } from "react";
3
3
  import { ChevronLeft, ChevronRight } from "lucide-react";
4
4
  import { cn } from "../lib/cn";
5
5
  import { hasContent } from "../lib/presence";
6
+ import { upperFirst } from "../lib/text-case";
6
7
  import { FOCUS_RING, FOCUS_RING_WIDTH } from "./focus-ring";
7
8
  import { horizontalStep } from "../lib/direction";
8
9
  import { useAnnounce } from "../hooks/use-announce";
@@ -351,7 +352,10 @@ export function MiniCalendar({
351
352
  const weeks: (Date | null)[][] = [];
352
353
  for (let i = 0; i < cells.length; i += 7) weeks.push(cells.slice(i, i + 7));
353
354
 
354
- const monthLabel = firstOfMonth.toLocaleDateString(locale, { month: "long", year: "numeric" });
355
+ // The first letter only, not CSS `capitalize`, which upper-cased every word: Spanish
356
+ // read "Septiembre De 2026" and Hungarian "2026. Szeptember" (refactor audit
357
+ // 2026-10-30, DUP-11) — while the same panel with `monthJump` read them right.
358
+ const monthLabel = upperFirst(firstOfMonth.toLocaleDateString(locale, { month: "long", year: "numeric" }), locale);
355
359
  const formatDay = (d: Date) => d.toLocaleDateString(locale, DAY_NAME_FORMAT);
356
360
 
357
361
  // Weekday labels via locale, from the week's first day: the narrow one for the
@@ -524,10 +528,7 @@ export function MiniCalendar({
524
528
  <div
525
529
  id={monthId}
526
530
  aria-live="polite"
527
- className={cn(
528
- "capitalize",
529
- lg ? "text-base font-semibold text-primary" : "text-xs font-medium text-secondary",
530
- )}
531
+ className={lg ? "text-base font-semibold text-primary" : "text-xs font-medium text-secondary"}
531
532
  >
532
533
  {monthLabel}
533
534
  </div>
@@ -11,6 +11,7 @@ import type {
11
11
  import { cn } from "../lib/cn";
12
12
  import { mergeRefs } from "./field-parts";
13
13
  import { useFocusTrap } from "../hooks/use-focus-trap";
14
+ import { useBreakpoint } from "../hooks/use-breakpoint";
14
15
  import { useBodyScrollLock } from "../hooks/use-body-scroll-lock";
15
16
  import { useOverlayHistory } from "../hooks/use-overlay-history";
16
17
  import { useDialogParam, type DialogParam } from "../hooks/use-search-param-state";
@@ -38,6 +39,10 @@ import { runOwnKeyDown, takeEscape, useDismissLayer } from "../hooks/use-dismiss
38
39
  function useDragOffset(enabled: boolean) {
39
40
  const [offset, setOffset] = useState<{ x: number; y: number } | null>(null);
40
41
  const from = useRef<{ x: number; y: number; ox: number; oy: number } | null>(null);
42
+ // `md:` as the panel's own CSS reads it, at the text size in force: 768 px at Normal,
43
+ // 960 at Large. `innerWidth >= 768` dragged the bottom sheet of an 800 px window at
44
+ // Large (refactor audit 2026-10-30, DUP-9). Without `matchMedia` (jsdom), the desktop.
45
+ const wide = useBreakpoint("md", true);
41
46
 
42
47
  const endDrag = () => {
43
48
  from.current = null;
@@ -52,7 +57,7 @@ function useDragOffset(enabled: boolean) {
52
57
  ? undefined
53
58
  : {
54
59
  onPointerDown: (e: ReactPointerEvent<HTMLDivElement>) => {
55
- if (e.button !== 0 || window.innerWidth < 768) return;
60
+ if (e.button !== 0 || !wide) return;
56
61
  const target = e.target as HTMLElement;
57
62
  // Only the panel itself and its non-interactive chrome start a drag; a
58
63
  // press inside any control belongs to that control.