@eifi1/ui-kit 0.32.2 → 0.33.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 (363) hide show
  1. package/README.md +16 -8
  2. package/dist/account/delete-account-setting.d.ts +10 -10
  3. package/dist/account/delete-account-setting.js +2 -1
  4. package/dist/account/delete-account-setting.js.map +1 -1
  5. package/dist/account/email-change-setting.d.ts +5 -0
  6. package/dist/account/email-change-setting.js +4 -3
  7. package/dist/account/email-change-setting.js.map +1 -1
  8. package/dist/account/sessions-setting.d.ts +4 -0
  9. package/dist/account/sessions-setting.js +3 -2
  10. package/dist/account/sessions-setting.js.map +1 -1
  11. package/dist/admin/admin-action-confirm.d.ts +10 -10
  12. package/dist/admin/admin-action-confirm.js.map +1 -1
  13. package/dist/admin/invitations-panel.d.ts +10 -10
  14. package/dist/admin/invitations-panel.js +4 -3
  15. package/dist/admin/invitations-panel.js.map +1 -1
  16. package/dist/admin/plan-change.d.ts +100 -0
  17. package/dist/admin/plan-change.js +208 -0
  18. package/dist/admin/plan-change.js.map +1 -0
  19. package/dist/admin/reviewer-scope-editor.d.ts +10 -10
  20. package/dist/admin/reviewer-scope-editor.js.map +1 -1
  21. package/dist/admin/role-select.d.ts +7 -7
  22. package/dist/admin/role-select.js.map +1 -1
  23. package/dist/admin/transfer-ownership-dialog.d.ts +10 -10
  24. package/dist/admin/user-roster.d.ts +7 -7
  25. package/dist/admin/user-roster.js +2 -2
  26. package/dist/admin/user-roster.js.map +1 -1
  27. package/dist/auth/auth-errors.d.ts +13 -2
  28. package/dist/auth/auth-errors.js +5 -1
  29. package/dist/auth/auth-errors.js.map +1 -1
  30. package/dist/auth/complete-name-dialog.d.ts +4 -1
  31. package/dist/auth/complete-name-dialog.js +2 -1
  32. package/dist/auth/complete-name-dialog.js.map +1 -1
  33. package/dist/auth/register-form.d.ts +10 -10
  34. package/dist/billing/billing-banner.d.ts +13 -11
  35. package/dist/billing/billing-banner.js.map +1 -1
  36. package/dist/billing/billing-labels.d.ts +10 -10
  37. package/dist/billing/billing-labels.js +10 -1
  38. package/dist/billing/billing-labels.js.map +1 -1
  39. package/dist/billing/billing-lock.d.ts +39 -12
  40. package/dist/billing/billing-lock.js +9 -3
  41. package/dist/billing/billing-lock.js.map +1 -1
  42. package/dist/billing/billing-overview.d.ts +154 -0
  43. package/dist/billing/billing-overview.js +2 -0
  44. package/dist/billing/billing-overview.js.map +1 -0
  45. package/dist/billing/billing-standing.d.ts +10 -10
  46. package/dist/billing/checkout-processing.d.ts +217 -0
  47. package/dist/billing/checkout-processing.js +198 -0
  48. package/dist/billing/checkout-processing.js.map +1 -0
  49. package/dist/billing/checkout-return.d.ts +51 -0
  50. package/dist/billing/checkout-return.js +43 -0
  51. package/dist/billing/checkout-return.js.map +1 -0
  52. package/dist/billing/pay-page.d.ts +210 -0
  53. package/dist/billing/pay-page.js +113 -0
  54. package/dist/billing/pay-page.js.map +1 -0
  55. package/dist/billing/plan-card.d.ts +10 -10
  56. package/dist/billing/plan-limit-notice.d.ts +10 -10
  57. package/dist/billing/plan-limit-toast.d.ts +143 -0
  58. package/dist/billing/plan-limit-toast.js +40 -0
  59. package/dist/billing/plan-limit-toast.js.map +1 -0
  60. package/dist/billing/subscription-actions.d.ts +38 -15
  61. package/dist/billing/subscription-actions.js +9 -2
  62. package/dist/billing/subscription-actions.js.map +1 -1
  63. package/dist/billing/subscription-status-chip.d.ts +9 -9
  64. package/dist/bin/eifi1-pay-page.mjs +166 -0
  65. package/dist/chart.d.ts +10 -10
  66. package/dist/components/account-chips.d.ts +6 -1
  67. package/dist/components/account-settings.d.ts +4 -1
  68. package/dist/components/account-settings.js +2 -1
  69. package/dist/components/account-settings.js.map +1 -1
  70. package/dist/components/amount-input.d.ts +10 -10
  71. package/dist/components/autocomplete.d.ts +2 -1
  72. package/dist/components/autocomplete.js +3 -1
  73. package/dist/components/autocomplete.js.map +1 -1
  74. package/dist/components/button-group.d.ts +10 -10
  75. package/dist/components/button-group.js +1 -1
  76. package/dist/components/button-group.js.map +1 -1
  77. package/dist/components/calculator.d.ts +10 -10
  78. package/dist/components/calculator.js +3 -3
  79. package/dist/components/calculator.js.map +1 -1
  80. package/dist/components/checkbox-group.d.ts +2 -1
  81. package/dist/components/checkbox-group.js.map +1 -1
  82. package/dist/components/checkbox.d.ts +2 -1
  83. package/dist/components/checkbox.js.map +1 -1
  84. package/dist/components/chip.d.ts +2 -1
  85. package/dist/components/chip.js +19 -17
  86. package/dist/components/chip.js.map +1 -1
  87. package/dist/components/choice-card.d.ts +3 -1
  88. package/dist/components/choice-card.js +1 -1
  89. package/dist/components/choice-card.js.map +1 -1
  90. package/dist/components/combobox.d.ts +4 -3
  91. package/dist/components/combobox.js.map +1 -1
  92. package/dist/components/confirm-dialog.d.ts +10 -10
  93. package/dist/components/confirm-dialog.js +6 -3
  94. package/dist/components/confirm-dialog.js.map +1 -1
  95. package/dist/components/copy-button.d.ts +11 -11
  96. package/dist/components/country-select.d.ts +2 -1
  97. package/dist/components/country-select.js.map +1 -1
  98. package/dist/components/danger-confirm.d.ts +10 -10
  99. package/dist/components/danger-confirm.js.map +1 -1
  100. package/dist/components/data-table-cells.d.ts +12 -1
  101. package/dist/components/data-table-filter-popover.d.ts +12 -1
  102. package/dist/components/data-table-filters.d.ts +12 -1
  103. package/dist/components/data-table-labels.d.ts +12 -1
  104. package/dist/components/data-table-pagination.d.ts +12 -1
  105. package/dist/components/data-table.d.ts +12 -1
  106. package/dist/components/data-table.js +3 -3
  107. package/dist/components/data-table.js.map +1 -1
  108. package/dist/components/date-picker.js +6 -4
  109. package/dist/components/date-picker.js.map +1 -1
  110. package/dist/components/entity-combobox.d.ts +3 -2
  111. package/dist/components/entity-combobox.js.map +1 -1
  112. package/dist/components/facing-pair.d.ts +10 -10
  113. package/dist/components/field-parts.d.ts +32 -4
  114. package/dist/components/field-parts.js +54 -19
  115. package/dist/components/field-parts.js.map +1 -1
  116. package/dist/components/file-button.d.ts +10 -10
  117. package/dist/components/file-button.js +3 -2
  118. package/dist/components/file-button.js.map +1 -1
  119. package/dist/components/file-dropzone.d.ts +11 -11
  120. package/dist/components/file-dropzone.js.map +1 -1
  121. package/dist/components/floating-panel.js +5 -5
  122. package/dist/components/floating-panel.js.map +1 -1
  123. package/dist/components/form-actions.d.ts +9 -9
  124. package/dist/components/form-actions.js +3 -3
  125. package/dist/components/form-actions.js.map +1 -1
  126. package/dist/components/iban-input.d.ts +10 -10
  127. package/dist/components/inline-edit-field.d.ts +2 -1
  128. package/dist/components/inline-edit-field.js +6 -6
  129. package/dist/components/inline-edit-field.js.map +1 -1
  130. package/dist/components/language-select.d.ts +10 -10
  131. package/dist/components/legal-page.d.ts +10 -10
  132. package/dist/components/legal.d.ts +10 -10
  133. package/dist/components/list.d.ts +2 -1
  134. package/dist/components/list.js +4 -5
  135. package/dist/components/list.js.map +1 -1
  136. package/dist/components/money-field.d.ts +10 -10
  137. package/dist/components/month-picker.js +54 -44
  138. package/dist/components/month-picker.js.map +1 -1
  139. package/dist/components/multi-entity-combobox.d.ts +3 -2
  140. package/dist/components/multi-entity-combobox.js.map +1 -1
  141. package/dist/components/number-field.d.ts +10 -10
  142. package/dist/components/number-input.d.ts +10 -10
  143. package/dist/components/numpad-sheet.d.ts +10 -10
  144. package/dist/components/numpad-sheet.js +2 -2
  145. package/dist/components/numpad-sheet.js.map +1 -1
  146. package/dist/components/phone-input.d.ts +10 -10
  147. package/dist/components/row-actions.d.ts +5 -5
  148. package/dist/components/row-actions.js +130 -32
  149. package/dist/components/row-actions.js.map +1 -1
  150. package/dist/components/series-chart.d.ts +10 -10
  151. package/dist/components/settings-fields.d.ts +10 -10
  152. package/dist/components/share-card.d.ts +7 -7
  153. package/dist/components/share-card.js +26 -10
  154. package/dist/components/share-card.js.map +1 -1
  155. package/dist/components/status-dot.d.ts +1 -0
  156. package/dist/components/status-dot.js +2 -2
  157. package/dist/components/status-dot.js.map +1 -1
  158. package/dist/components/swatch-picker.d.ts +2 -1
  159. package/dist/components/swatch-picker.js.map +1 -1
  160. package/dist/components/swipeable-row.d.ts +88 -17
  161. package/dist/components/swipeable-row.js +46 -9
  162. package/dist/components/swipeable-row.js.map +1 -1
  163. package/dist/components/switch.d.ts +2 -1
  164. package/dist/components/switch.js.map +1 -1
  165. package/dist/components/table.d.ts +2 -1
  166. package/dist/components/table.js +6 -0
  167. package/dist/components/table.js.map +1 -1
  168. package/dist/components/text-link.d.ts +9 -9
  169. package/dist/components/time-input.d.ts +10 -10
  170. package/dist/components/toggle-group.d.ts +2 -1
  171. package/dist/components/toggle-group.js +1 -1
  172. package/dist/components/toggle-group.js.map +1 -1
  173. package/dist/components/translation-review-editor.d.ts +4 -0
  174. package/dist/components/translation-review-editor.js +4 -3
  175. package/dist/components/translation-review-editor.js.map +1 -1
  176. package/dist/components/translation-review-parts.d.ts +1 -0
  177. package/dist/components/translation-review.d.ts +1 -0
  178. package/dist/components/translation-review.js +15 -18
  179. package/dist/components/translation-review.js.map +1 -1
  180. package/dist/components/ui.d.ts +9 -9
  181. package/dist/components/ui.js +47 -27
  182. package/dist/components/ui.js.map +1 -1
  183. package/dist/components/use-table-state.d.ts +12 -1
  184. package/dist/components/user-avatar.d.ts +1 -0
  185. package/dist/components/write-lock.d.ts +101 -13
  186. package/dist/components/write-lock.js +37 -13
  187. package/dist/components/write-lock.js.map +1 -1
  188. package/dist/{data-table-labels-kpAAVi6g.d.ts → data-table-labels-BJ5JE_X2.d.ts} +17 -0
  189. package/dist/data-table.d.ts +12 -1
  190. package/dist/{delete-account-setting-Dy4kJgUm.d.ts → delete-account-setting-DiPX4Vue.d.ts} +355 -41
  191. package/dist/feedback/feedback-attachment.d.ts +10 -10
  192. package/dist/feedback/feedback-attachment.js +7 -7
  193. package/dist/feedback/feedback-attachment.js.map +1 -1
  194. package/dist/feedback/feedback-context.d.ts +10 -10
  195. package/dist/feedback/feedback-crash.d.ts +10 -10
  196. package/dist/feedback/feedback-dialog.d.ts +10 -10
  197. package/dist/feedback/feedback-inbox.d.ts +9 -9
  198. package/dist/feedback/feedback-inbox.js +7 -3
  199. package/dist/feedback/feedback-inbox.js.map +1 -1
  200. package/dist/feedback/feedback-labels.d.ts +10 -10
  201. package/dist/feedback/feedback-menu.d.ts +3 -3
  202. package/dist/feedback/feedback-record.d.ts +10 -10
  203. package/dist/feedback/feedback-row-detail.d.ts +10 -10
  204. package/dist/feedback/feedback-row-detail.js.map +1 -1
  205. package/dist/feedback/feedback-status-undo.d.ts +10 -10
  206. package/dist/feedback/feedback-submit.d.ts +10 -10
  207. package/dist/feedback/feedback-swipe.d.ts +10 -10
  208. package/dist/feedback/feedback-swipe.js +3 -6
  209. package/dist/feedback/feedback-swipe.js.map +1 -1
  210. package/dist/feedback/feedback-table.d.ts +10 -10
  211. package/dist/feedback/feedback-table.js.map +1 -1
  212. package/dist/feedback/feedback-thread.d.ts +10 -10
  213. package/dist/feedback.d.ts +10 -10
  214. package/dist/hooks/use-file-drop.d.ts +10 -10
  215. package/dist/i18n/defaults.d.ts +10 -10
  216. package/dist/i18n/defaults.js +2 -0
  217. package/dist/i18n/defaults.js.map +1 -1
  218. package/dist/i18n/german.d.ts +10 -10
  219. package/dist/i18n/german.js +34 -1
  220. package/dist/i18n/german.js.map +1 -1
  221. package/dist/i18n/kit-labels.d.ts +4 -4
  222. package/dist/i18n/kit-labels.js.map +1 -1
  223. package/dist/i18n/languages.d.ts +10 -10
  224. package/dist/i18n/locales/de-CH.d.ts +10 -10
  225. package/dist/i18n/locales/en.d.ts +10 -10
  226. package/dist/i18n/locales/es.d.ts +10 -10
  227. package/dist/i18n/locales/es.js +34 -1
  228. package/dist/i18n/locales/es.js.map +1 -1
  229. package/dist/i18n/locales/fr.d.ts +10 -10
  230. package/dist/i18n/locales/fr.js +35 -1
  231. package/dist/i18n/locales/fr.js.map +1 -1
  232. package/dist/i18n/locales/hu.d.ts +10 -10
  233. package/dist/i18n/locales/hu.js +36 -1
  234. package/dist/i18n/locales/hu.js.map +1 -1
  235. package/dist/i18n/locales/it.d.ts +10 -10
  236. package/dist/i18n/locales/it.js +34 -1
  237. package/dist/i18n/locales/it.js.map +1 -1
  238. package/dist/i18n/locales/zh.d.ts +10 -10
  239. package/dist/i18n/locales/zh.js +34 -1
  240. package/dist/i18n/locales/zh.js.map +1 -1
  241. package/dist/i18n/review.d.ts +10 -10
  242. package/dist/i18n/review.js +8 -1
  243. package/dist/i18n/review.js.map +1 -1
  244. package/dist/index.d.ts +10 -5
  245. package/dist/index.js +40 -2
  246. package/dist/index.js.map +1 -1
  247. package/dist/landing/landing-actions.d.ts +10 -10
  248. package/dist/landing/landing-sections.d.ts +10 -10
  249. package/dist/landing/public-header.d.ts +10 -10
  250. package/dist/landing/routing.d.ts +10 -10
  251. package/dist/pay/.well-known/apple-developer-merchantid-domain-association +1 -0
  252. package/dist/pay/index.html +30 -0
  253. package/dist/pay/pay.css +126 -0
  254. package/dist/pay/pay.js +198 -0
  255. package/dist/rhf/fields.d.ts +10 -10
  256. package/dist/rhf/form.d.ts +10 -10
  257. package/dist/rhf.d.ts +10 -10
  258. package/dist/settings/settings-section.d.ts +10 -10
  259. package/dist/shell/app-shell.d.ts +9 -9
  260. package/dist/shell/top-bar-brand.d.ts +10 -10
  261. package/dist/shell/topbar-action-menu.d.ts +1 -0
  262. package/dist/shell.d.ts +10 -10
  263. package/dist/testing/css-variables.d.ts +74 -0
  264. package/dist/testing/css-variables.generated.d.ts +7 -0
  265. package/dist/testing/css-variables.generated.js +8 -0
  266. package/dist/testing/css-variables.generated.js.map +1 -0
  267. package/dist/testing/css-variables.js +93 -0
  268. package/dist/testing/css-variables.js.map +1 -0
  269. package/dist/testing/index.d.ts +1 -0
  270. package/dist/testing/index.js +12 -0
  271. package/dist/testing/index.js.map +1 -0
  272. package/dist/theme/contrast-tokens.d.ts +44 -1
  273. package/dist/theme/contrast-tokens.js +21 -0
  274. package/dist/theme/contrast-tokens.js.map +1 -1
  275. package/dist/theme/contrast.d.ts +2 -2
  276. package/dist/theme/palette-derive.js +60 -11
  277. package/dist/theme/palette-derive.js.map +1 -1
  278. package/dist/theme/palette-presets.js +45 -43
  279. package/dist/theme/palette-presets.js.map +1 -1
  280. package/dist/wizard/stepper-nav.d.ts +11 -11
  281. package/dist/wizard/stepper-nav.js.map +1 -1
  282. package/dist/wizard.d.ts +10 -10
  283. package/package.json +10 -2
  284. package/src/account/delete-account-setting.tsx +6 -1
  285. package/src/account/email-change-setting.tsx +9 -3
  286. package/src/account/sessions-setting.tsx +7 -2
  287. package/src/admin/admin-action-confirm.tsx +2 -1
  288. package/src/admin/invitations-panel.tsx +9 -3
  289. package/src/admin/plan-change.tsx +459 -0
  290. package/src/admin/reviewer-scope-editor.tsx +2 -1
  291. package/src/admin/role-select.tsx +2 -1
  292. package/src/admin/user-roster.tsx +5 -3
  293. package/src/auth/auth-errors.ts +25 -2
  294. package/src/auth/complete-name-dialog.tsx +6 -2
  295. package/src/billing/billing-banner.tsx +3 -1
  296. package/src/billing/billing-labels.ts +45 -0
  297. package/src/billing/billing-lock.ts +36 -3
  298. package/src/billing/billing-overview.ts +58 -0
  299. package/src/billing/checkout-processing.ts +391 -0
  300. package/src/billing/checkout-return.ts +90 -0
  301. package/src/billing/pay-page.ts +242 -0
  302. package/src/billing/plan-limit-toast.tsx +91 -0
  303. package/src/billing/subscription-actions.tsx +41 -8
  304. package/src/components/account-settings.tsx +6 -2
  305. package/src/components/autocomplete.tsx +5 -2
  306. package/src/components/button-group.tsx +4 -1
  307. package/src/components/calculator.tsx +10 -6
  308. package/src/components/checkbox-group.tsx +2 -2
  309. package/src/components/checkbox.tsx +2 -1
  310. package/src/components/chip.tsx +37 -32
  311. package/src/components/choice-card.tsx +4 -2
  312. package/src/components/combobox.tsx +4 -4
  313. package/src/components/confirm-dialog.tsx +13 -6
  314. package/src/components/country-select.tsx +2 -2
  315. package/src/components/danger-confirm.tsx +2 -2
  316. package/src/components/data-table.tsx +20 -9
  317. package/src/components/date-picker.tsx +10 -7
  318. package/src/components/entity-combobox.tsx +3 -3
  319. package/src/components/field-parts.tsx +61 -14
  320. package/src/components/file-button.tsx +5 -4
  321. package/src/components/file-dropzone.tsx +2 -2
  322. package/src/components/floating-panel.tsx +7 -5
  323. package/src/components/form-actions.tsx +12 -5
  324. package/src/components/inline-edit-field.tsx +13 -13
  325. package/src/components/list.tsx +10 -9
  326. package/src/components/month-picker.tsx +8 -2
  327. package/src/components/multi-entity-combobox.tsx +3 -3
  328. package/src/components/numpad-sheet.tsx +8 -4
  329. package/src/components/row-actions.tsx +208 -58
  330. package/src/components/share-card.tsx +67 -13
  331. package/src/components/status-dot.tsx +7 -7
  332. package/src/components/swatch-picker.tsx +2 -2
  333. package/src/components/swipeable-row.tsx +138 -27
  334. package/src/components/switch.tsx +2 -1
  335. package/src/components/table.tsx +8 -1
  336. package/src/components/toggle-group.tsx +5 -3
  337. package/src/components/translation-review-editor.tsx +8 -3
  338. package/src/components/translation-review.tsx +18 -22
  339. package/src/components/ui.tsx +92 -43
  340. package/src/components/write-lock.tsx +150 -24
  341. package/src/feedback/feedback-attachment.tsx +13 -9
  342. package/src/feedback/feedback-inbox.tsx +10 -6
  343. package/src/feedback/feedback-row-detail.tsx +3 -2
  344. package/src/feedback/feedback-swipe.tsx +6 -11
  345. package/src/feedback/feedback-table.tsx +2 -1
  346. package/src/i18n/defaults.ts +2 -0
  347. package/src/i18n/german.ts +38 -0
  348. package/src/i18n/kit-labels.tsx +4 -0
  349. package/src/i18n/locales/es.ts +34 -0
  350. package/src/i18n/locales/fr.ts +39 -0
  351. package/src/i18n/locales/hu.ts +37 -0
  352. package/src/i18n/locales/it.ts +35 -0
  353. package/src/i18n/locales/zh.ts +33 -0
  354. package/src/i18n/review.ts +7 -0
  355. package/src/index.ts +48 -4
  356. package/src/testing/css-variables.generated.ts +112 -0
  357. package/src/testing/css-variables.ts +191 -0
  358. package/src/testing/index.ts +13 -0
  359. package/src/theme/contrast-tokens.ts +53 -2
  360. package/src/theme/palette-derive.ts +87 -10
  361. package/src/theme/palette-presets.ts +45 -43
  362. package/src/wizard/stepper-nav.tsx +2 -1
  363. package/tokens.css +306 -46
@@ -8,6 +8,7 @@ import { useLargeText } from "../hooks/use-large-text";
8
8
  import { isApplePlatform } from "../hooks/use-hotkey";
9
9
  import { Button, Spinner, type ButtonProps, type ButtonSize, type ButtonVariant } from "./ui";
10
10
  import { useWriteLock } from "./write-lock";
11
+ import type { CommitScope } from "./write-lock";
11
12
 
12
13
  /** The words {@link FormActions} renders on its own behalf — the `form` namespace. */
13
14
  export interface FormActionsLabels {
@@ -197,8 +198,11 @@ export interface FormActionsProps extends Omit<ComponentPropsWithoutRef<"div">,
197
198
  * keksdose wrote `submitDisabled={lock.locked || …}` and
198
199
  * `submitDisabledReason={lock.locked ? lock.reason : undefined}` at each form; this is
199
200
  * that pair, read from the provider.
201
+ *
202
+ * 0.33: a {@link CommitScope} — `COMMIT_EXCEPT_BILLING` for a form a lapsed plan still
203
+ * allows (the account's own settings, docs/billing-harmonization.md §12.36).
200
204
  */
201
- commit?: boolean;
205
+ commit?: CommitScope;
202
206
  /** The save button's variant. Default `brand`; `danger` for a save that destroys
203
207
  * (kastlan's `destructive` flag on its own FormActions). */
204
208
  submitVariant?: ButtonVariant;
@@ -392,7 +396,9 @@ export function FormActions({
392
396
  // column stretches but which keeps its control at the control's own width.
393
397
  const full = stacked ? "w-full" : undefined;
394
398
  const labels = useKitLabels("form", DEFAULT_FORM_ACTIONS_LABELS);
395
- const lock = useWriteLock();
399
+ // The lock as Save sees it: with its scope, so a billing lock leaves a
400
+ // `COMMIT_EXCEPT_BILLING` form's shortcut live too.
401
+ const lock = useWriteLock(commit);
396
402
  const rootRef = useRef<HTMLDivElement>(null);
397
403
  const saveRef = useRef<HTMLButtonElement | null>(null);
398
404
  // The caller's own `submitProps.ref` still gets the element.
@@ -422,7 +428,7 @@ export function FormActions({
422
428
  }, [pending]);
423
429
  // Read by the shortcut's listener at the moment of the key press, so the listener
424
430
  // itself is attached once and never sees a stale `pending`.
425
- const canSave = !pending && !submitDisabled && !(commit && lock.locked);
431
+ const canSave = !pending && !submitDisabled && !lock.locked;
426
432
  const canSaveRef = useRef(canSave);
427
433
  useEffect(() => {
428
434
  canSaveRef.current = canSave;
@@ -535,8 +541,9 @@ export function FormActions({
535
541
  disabled={pending || submitDisabled}
536
542
  disabledReason={pending ? undefined : submitDisabledReason}
537
543
  // Not while pending: the save already left, and the lock's look over the
538
- // spinner would say it had not.
539
- commit={commit && !pending}
544
+ // spinner would say it had not. A ternary, not `commit && !pending`, which
545
+ // turned a `{ except }` scope into `true` (§12.36).
546
+ commit={pending ? false : commit}
540
547
  aria-busy={pending || undefined}
541
548
  className={cn(submitProps?.className, full)}
542
549
  >
@@ -6,7 +6,7 @@ import { useKitLabels } from "../i18n/kit-labels";
6
6
  import { Input, Spinner } from "./ui";
7
7
  import { FOCUS_RING } from "./focus-ring";
8
8
  import { Tooltip } from "./tooltip";
9
- import { useCommitReason } from "./write-lock";
9
+ import { useCommitReason, type CommitScope } from "./write-lock";
10
10
 
11
11
  /**
12
12
  * Every string {@link InlineEditField} says on its own behalf — the `inlineEdit`
@@ -101,7 +101,7 @@ interface InlineEditFieldBaseProps<T> {
101
101
  /** This field COMMITS — under a locked {@link WriteLockProvider} it takes the
102
102
  * `disabledReason` path with the lock's reason (which wins over its own). No
103
103
  * provider, or an unlocked one: no effect. */
104
- commit?: boolean;
104
+ commit?: CommitScope;
105
105
  /** The value is the user's own data: `data-private` on the display and the editor,
106
106
  * so the app's demo-mode blur covers both. */
107
107
  redact?: boolean;
@@ -164,13 +164,13 @@ function RenderEditor<T>({ render, ...props }: InlineEditorProps<T> & { render:
164
164
  * big type cannot recover a cut-off end by squinting. A `large:` class, so a table of
165
165
  * these keeps its one-line cells at Normal.
166
166
  *
167
- * `break-words`, not `[overflow-wrap:anywhere]`: these live in table cells (keksdose's
168
- * budget and invoice lines), and `anywhere` lowers the value's min-content width to one
169
- * letter, so an auto-sized column could squeeze an amount to a digit per line. With
170
- * `break-word` a column keeps each word whole; the button is `w-full`, so a word wider
171
- * than a sized cell still breaks.
167
+ * 0.33 (§10.17): the kit's one `truncate-until-large` (tokens.css) in place of this
168
+ * file's own `truncate` + `large:whitespace-normal large:break-words`. The utility
169
+ * breaks with `overflow-wrap: anywhere`, which lowers the value's min-content width: in
170
+ * an auto-sized table column (keksdose's budget and invoice lines) give the column a
171
+ * width, or an amount can be squeezed to a digit per line.
172
172
  */
173
- const VALUE_WRAP_AT_LARGE = "large:whitespace-normal large:break-words";
173
+ const VALUE_TRUNCATE = "truncate-until-large";
174
174
 
175
175
  /** `onCommit`'s result, if it is a promise. */
176
176
  function asPromise(result: unknown): Promise<unknown> | null {
@@ -432,7 +432,7 @@ export function InlineEditField<T = string>(props: InlineEditFieldProps<T>) {
432
432
  let body: ReactNode;
433
433
  if (readOnly) {
434
434
  body = (
435
- <span {...private_} className={cn("block min-w-0 truncate", VALUE_WRAP_AT_LARGE, alignClass)}>
435
+ <span {...private_} className={cn("block min-w-0", VALUE_TRUNCATE, alignClass)}>
436
436
  {content}
437
437
  </span>
438
438
  );
@@ -508,8 +508,8 @@ export function InlineEditField<T = string>(props: InlineEditFieldProps<T>) {
508
508
  aria-describedby={reasonId}
509
509
  onClick={(e) => e.preventDefault()}
510
510
  className={cn(
511
- "block w-full min-w-0 cursor-not-allowed truncate rounded-sm focus:outline-none",
512
- VALUE_WRAP_AT_LARGE,
511
+ "block w-full min-w-0 cursor-not-allowed rounded-sm focus:outline-none",
512
+ VALUE_TRUNCATE,
513
513
  FOCUS_RING,
514
514
  alignClass,
515
515
  )}
@@ -533,8 +533,8 @@ export function InlineEditField<T = string>(props: InlineEditFieldProps<T>) {
533
533
  {...private_}
534
534
  onClick={() => setOpen(true)}
535
535
  className={cn(
536
- "block w-full min-w-0 truncate rounded-sm underline-offset-2 hover:underline focus:outline-none",
537
- VALUE_WRAP_AT_LARGE,
536
+ "block w-full min-w-0 rounded-sm underline-offset-2 hover:underline focus:outline-none",
537
+ VALUE_TRUNCATE,
538
538
  FOCUS_RING,
539
539
  alignClass,
540
540
  )}
@@ -12,6 +12,7 @@ import { useKitLabels, useKitLink } from "../i18n/kit-labels";
12
12
  import { pickLinkRenderer } from "./text-link";
13
13
  import { mergeDescribedBy } from "./choice-parts";
14
14
  import { LockedReason, useLockReason } from "./field-parts";
15
+ import type { CommitScope } from "./write-lock";
15
16
 
16
17
  /* ── Labels ───────────────────────────────────────────────────────────────── */
17
18
 
@@ -122,11 +123,11 @@ const TARGET_RING = cn(FOCUS_RING, "focus-visible:ring-inset");
122
123
  * §4 "ListItem: title, subtitle and meta wrap instead of truncating" at Large and Extra
123
124
  * large (docs/text-size-harmonization.md). `large:` variants over the Normal look, so
124
125
  * a list keeps its one-height rows at Normal and costs no render to switch: a one-line
125
- * `truncate` wraps (and breaks a word too long for the row), a `line-clamp-2` lets go.
126
- * An ellipsis hides the end of a name, which is the part a reader who needs big type
127
- * cannot recover by squinting.
126
+ * line is `truncate-until-large` (tokens.css, 0.33 §10.17: `truncate`, and at Large a
127
+ * wrap that breaks a word too long for the row — the kit's one name for what this file
128
+ * spelt as `WRAP_AT_LARGE`), a `line-clamp-2` lets go. An ellipsis hides the end of a
129
+ * name, which is the part a reader who needs big type cannot recover by squinting.
128
130
  */
129
- const WRAP_AT_LARGE = "large:whitespace-normal large:[overflow-wrap:anywhere]";
130
131
  const UNCLAMP_AT_LARGE = "large:line-clamp-none";
131
132
 
132
133
  interface ListItemBaseProps {
@@ -341,7 +342,7 @@ export type ListItemProps = ListItemBaseProps &
341
342
  * the `disabledReason` way with the lock's reason (which wins over its own). No
342
343
  * provider, or an unlocked one: no effect. Button's `commit`, for keksdose K3.
343
344
  */
344
- commit?: boolean;
345
+ commit?: CommitScope;
345
346
  href?: never;
346
347
  renderLink?: never;
347
348
  external?: never;
@@ -528,7 +529,7 @@ export const ListItem = forwardRef<HTMLElement, ListItemProps>(function ListItem
528
529
  now-wrapping title into a column one word wide (§4, 240 px effective width). */}
529
530
  <span className={cn("flex min-w-0 flex-1 flex-col", trailing != null && "large:basis-40")}>
530
531
  {overline != null && (
531
- <span className={cn("block truncate text-caption font-medium leading-snug text-[var(--text-muted)]", WRAP_AT_LARGE)}>
532
+ <span className="block truncate-until-large text-caption font-medium leading-snug text-[var(--text-muted)]">
532
533
  {overline}
533
534
  </span>
534
535
  )}
@@ -538,7 +539,7 @@ export const ListItem = forwardRef<HTMLElement, ListItemProps>(function ListItem
538
539
  className={cn(
539
540
  "block text-sm text-[var(--text-primary)]",
540
541
  titleLines === 1
541
- ? cn("truncate", WRAP_AT_LARGE)
542
+ ? "truncate-until-large"
542
543
  : titleLines === 2
543
544
  ? cn("line-clamp-2 break-words", UNCLAMP_AT_LARGE)
544
545
  : "break-words",
@@ -553,7 +554,7 @@ export const ListItem = forwardRef<HTMLElement, ListItemProps>(function ListItem
553
554
  <span
554
555
  className={cn(
555
556
  "block text-xs text-[var(--text-muted)]",
556
- subtitleLines === 2 ? cn("line-clamp-2 break-words", UNCLAMP_AT_LARGE) : cn("truncate", WRAP_AT_LARGE),
557
+ subtitleLines === 2 ? cn("line-clamp-2 break-words", UNCLAMP_AT_LARGE) : "truncate-until-large",
557
558
  )}
558
559
  >
559
560
  {subtitle}
@@ -563,7 +564,7 @@ export const ListItem = forwardRef<HTMLElement, ListItemProps>(function ListItem
563
564
  <span
564
565
  className={cn(
565
566
  "mt-0.5 text-caption leading-snug text-[var(--text-muted)]",
566
- metaWrap ? "flex flex-wrap items-center gap-1" : cn("block truncate", WRAP_AT_LARGE),
567
+ metaWrap ? "flex flex-wrap items-center gap-1" : "block truncate-until-large",
567
568
  )}
568
569
  >
569
570
  {meta}
@@ -10,7 +10,7 @@ import { Popover } from "./popover";
10
10
  import { splitTriggerAria } from "./trigger-aria";
11
11
  import type { TriggerAria } from "./trigger-aria";
12
12
  import { useKitDateFormatter, useKitLabels, useKitLocale } from "../i18n/kit-labels";
13
- import { FieldBox, FieldLabelLine, hasContent, useFieldMessages } from "./field-parts";
13
+ import { FieldBox, FieldLabelLine, hasContent, LABEL_ABOVE_BOX, useFieldMessages } from "./field-parts";
14
14
 
15
15
  /**
16
16
  * Every string the month picker can speak. The month and year names are NOT here —
@@ -1005,7 +1005,13 @@ export function MonthPicker(props: MonthPickerProps) {
1005
1005
  const field = (
1006
1006
  // `w-fit` for the toolbar size: the calendar glyph is placed against this box, and a
1007
1007
  // full-width box would park it at the far end of the row, away from its trigger.
1008
- <div {...wrapperRest} ref={rootRef} className={cn("relative", small && "w-fit max-w-full", className)}>
1008
+ // At Large a labelled box is a grid: the label above, the calendar glyph measured
1009
+ // against the trigger's row (LABEL_ABOVE_BOX, 0.33 §10.17).
1010
+ <div
1011
+ {...wrapperRest}
1012
+ ref={rootRef}
1013
+ className={cn("relative", small && "w-fit max-w-full", label !== undefined && LABEL_ABOVE_BOX, className)}
1014
+ >
1009
1015
  {label !== undefined && <FieldLabelLine label={label} hint={messages.labelHint} />}
1010
1016
  {/* The hidden twin the trigger is named by — see DateField. `sr-only-fixed`,
1011
1017
  and inside this `relative` root either way. */}
@@ -26,7 +26,7 @@ import {
26
26
  useLockReason,
27
27
  } from "./field-parts";
28
28
  import { assignRef, mergeDescribedBy } from "./choice-parts";
29
- import { useCommitReason } from "./write-lock";
29
+ import { useCommitReason, type CommitScope } from "./write-lock";
30
30
 
31
31
  /** `onChange` is the kit's — "a selection was made", carrying values — rather
32
32
  * than the div's form event, so the DOM's spelling of it is omitted. */
@@ -65,7 +65,7 @@ export interface MultiEntityComboboxProps<V extends string | number>
65
65
  disabledReason?: ReactNode;
66
66
  /** This picker COMMITS — toggling saves. Locked the `disabledReason` way under a
67
67
  * locked {@link WriteLockProvider}. See {@link EntityCombobox}'s `commit`. */
68
- commit?: boolean;
68
+ commit?: CommitScope;
69
69
  /** When set, a "create" row appears for a non-empty query with no exact match.
70
70
  * The panel stays open (adding the new entity to `value` is the caller's job). */
71
71
  onCreate?: (query: string) => void;
@@ -75,7 +75,7 @@ export interface MultiEntityComboboxProps<V extends string | number>
75
75
  createEmptyLabel?: string;
76
76
  /** The create row is a write while toggling is not: locked on its own under a locked
77
77
  * {@link WriteLockProvider}. See {@link EntityCombobox}'s `createCommit`. */
78
- createCommit?: boolean;
78
+ createCommit?: CommitScope;
79
79
  /** Required and unanswered — {@link FIELD_INVALID}. See {@link Input}'s `invalid`. */
80
80
  invalid?: boolean;
81
81
  /** What is wrong with the value, as {@link Input}'s `error`: rendered under the
@@ -87,11 +87,15 @@ const PAD_KEYS: PadKey[] = [
87
87
  * thinner than an outward ring plus the neighbour it would spill onto — inset keeps the
88
88
  * ring inside the key it describes.
89
89
  *
90
- * --brand rather than --border-strong: the operator keys are filled with --border, and
91
- * a ring in the colour of the thing it surrounds is not an indicator. */
90
+ * --brand rather than --border-strong: the operator keys are filled with a step of the
91
+ * ink, and a ring in the colour of the thing it surrounds is not an indicator. */
92
92
  const PAD_BTN = `flex h-14 items-center justify-center rounded-lg text-lg font-medium transition-transform select-none focus:outline-none ${FOCUS_RING} focus-visible:ring-inset active:scale-[0.97]`;
93
- const PAD_DIGIT = "bg-[var(--bg-surface-2)] text-[var(--text-primary)] active:bg-[var(--border)]";
94
- const PAD_ACCENT = "bg-[var(--border)] text-[var(--text-primary)] active:bg-[var(--bg-surface-2)]";
93
+ // Digits on the well, operators a step down on `--bg-active`, each pressing toward the
94
+ // other. `--bg-active`, not `--border` (0.33, docs/colour-roles-harmonization.md §12.9):
95
+ // More contrast steps the border until it is a 3:1 LINE, and as a fill under the label
96
+ // that left 2.7–3.3:1; `--bg-active` carries the ink at 7:1 and up at both levels.
97
+ const PAD_DIGIT = "bg-surface-2 text-primary active:bg-active";
98
+ const PAD_ACCENT = "bg-active text-primary active:bg-surface-2";
95
99
 
96
100
  export function NumberPadSheet({
97
101
  value,