@nxgt/material 3.75.1-hotfix-20261030064707 → 3.77.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 (272) hide show
  1. package/CHANGELOG.md +72 -2
  2. package/README.md +39 -3
  3. package/dist/{alert-dialog-BfO_ri-N.js → alert-dialog-653apk3f.js} +8 -7
  4. package/dist/{async-slice-roMAJVzG.js → async-slice-CXLbQuOc.js} +1 -1
  5. package/dist/{bubble-input-B7BVd9fX.js → bubble-input-CQwVSoU3.js} +30 -29
  6. package/dist/{button-DgenqmpS.js → button-3op3rtZh.js} +5 -4
  7. package/dist/calculator-DSSaYRmM.js +1189 -0
  8. package/dist/calculator-announce-DRd2c6Dq.js +89 -0
  9. package/dist/calculator-context-BugcKuVG.js +10 -0
  10. package/dist/calculator-field.js +172 -0
  11. package/dist/calculator-panel-announce-AZSnZUSr.js +29 -0
  12. package/dist/calculator-segment-BlJE1LaS.js +22 -0
  13. package/dist/calculator.js +2 -0
  14. package/dist/charts.js +3 -3
  15. package/dist/{chip-CiDczNxO.js → chip-MuKDwtkG.js} +2 -2
  16. package/dist/{code-editor-CohlhFsA.js → code-editor-Bp2RrdNx.js} +13 -13
  17. package/dist/code-editor.js +37 -37
  18. package/dist/{code-language-items-Cs8GLYDp.js → code-language-items-B7WR5ua_.js} +19 -24
  19. package/dist/components/base-content.css +9 -4
  20. package/dist/components/ui/display/chip/chip-hairline.css +19 -0
  21. package/dist/components/ui/display/chip/chip-soft.css +18 -0
  22. package/dist/{components-zJdfH4im.js → components-ZJx47chq.js} +14086 -15417
  23. package/dist/components.js +37 -28
  24. package/dist/conversion-variant-BDFAxqe9.js +529 -0
  25. package/dist/copy-to-clipboard-Be5Ffvs_.js +7 -0
  26. package/dist/currency-B-r3ig11.js +16 -0
  27. package/dist/currency-field-DWHB5oms.js +286 -0
  28. package/dist/{number.utils-BG_eEt5g.js → date.utils-DUvqcjan.js} +1 -7
  29. package/dist/dialog-Bm5LvVlB.js +166 -0
  30. package/dist/dist-BZe2evxL.js +139 -0
  31. package/dist/dist-CxhKjOYm.js +28 -0
  32. package/dist/dist-DHdUUM1w.js +241 -0
  33. package/dist/{dist-C4wtXCjf.js → dist-DOK3zo5C.js} +33 -32
  34. package/dist/dist-DWZXlCZR.js +182 -0
  35. package/dist/dist-DkQbkF9T.js +33 -0
  36. package/dist/dnd.js +1 -1
  37. package/dist/{dropdown-menu-CzR6JP31.js → dropdown-menu-xlZ6NYUA.js} +160 -159
  38. package/dist/editor.js +299 -298
  39. package/dist/{empty-state-DjHGMp5F.js → empty-state-C0kviQdW.js} +2 -2
  40. package/dist/{field-blur-CdASxjL7.js → field-blur-DkiZOVNV.js} +178 -180
  41. package/dist/{field-blur-context-kZ4SD7xu.js → field-blur-context-BLGgf_3z.js} +2 -2
  42. package/dist/financial-variant-vZdgyMeN.js +459 -0
  43. package/dist/{hooks-Dqq8O3Az.js → hooks-Dg94jPRq.js} +12 -12
  44. package/dist/hooks.js +2 -2
  45. package/dist/{hover-card-BPKqte4a.js → hover-card-B1g55Hi6.js} +44 -43
  46. package/dist/i18n.js +3 -3
  47. package/dist/icon-badge-BcW66bRk.js +17 -0
  48. package/dist/{icon-button-Cr-DyDGg.js → icon-button-Cogxy1cy.js} +5 -4
  49. package/dist/{in-dialog-Vwkyp-M5.js → in-dialog-D61Yeaol.js} +2 -1
  50. package/dist/input-CC2joTjB.js +56 -0
  51. package/dist/key-layout-cR79xfGE.js +38 -0
  52. package/dist/lib/calculator/index.d.ts +16 -0
  53. package/dist/lib/calculator-field/index.d.ts +12 -0
  54. package/dist/lib/components/ui/collections/filter/use-filter-field-config.d.ts +2 -2
  55. package/dist/lib/components/ui/collections/row-menu/use-row-menu-focus.d.ts +11 -1
  56. package/dist/lib/components/ui/collections/server-table/partials/server-table-phone-row.d.ts +1 -1
  57. package/dist/lib/components/ui/display/entity-header/partials/entity-header-actions.d.ts +3 -1
  58. package/dist/lib/components/ui/display/entity-header/partials/entity-header-layout.d.ts +10 -0
  59. package/dist/lib/components/ui/feedback/moment/moment-body.d.ts +17 -2
  60. package/dist/lib/components/ui/feedback/moment/moment-passive.d.ts +13 -0
  61. package/dist/lib/components/ui/feedback/moment/moment.d.ts +16 -2
  62. package/dist/lib/components/ui/fields/calculator-field/apply-calculated.d.ts +17 -0
  63. package/dist/lib/components/ui/fields/calculator-field/calculator-field-content.d.ts +16 -0
  64. package/dist/lib/components/ui/fields/calculator-field/calculator-field-trigger.d.ts +4 -0
  65. package/dist/lib/components/ui/fields/calculator-field/calculator-field.d.ts +12 -0
  66. package/dist/lib/components/ui/fields/calculator-field/calculator-field.types.d.ts +31 -0
  67. package/dist/lib/components/ui/fields/calculator-field/calculator-form-field.d.ts +4 -0
  68. package/dist/lib/components/ui/fields/calculator-field/index.d.ts +3 -0
  69. package/dist/lib/components/ui/fields/calculator-field/use-calculator-field.d.ts +15 -0
  70. package/dist/lib/components/ui/fields/contacts/placeholders.d.ts +1 -1
  71. package/dist/lib/components/ui/fields/currency-field/currency-field.d.ts +7 -1
  72. package/dist/lib/components/ui/fields/quantity-field/quantity-row.d.ts +4 -3
  73. package/dist/lib/components/ui/layout/app-shell/app-sidebar-context.d.ts +4 -0
  74. package/dist/lib/components/ui/layout/app-shell/page-title.d.ts +4 -3
  75. package/dist/lib/components/ui/layout/hero/hero-backdrop.d.ts +7 -0
  76. package/dist/lib/components/ui/layout/hero/hero-parts.d.ts +27 -0
  77. package/dist/lib/components/ui/layout/hero/hero.d.ts +26 -1
  78. package/dist/lib/components/ui/primitives/tabs/tabs-manual-scroll.d.ts +16 -0
  79. package/dist/lib/components/ui/primitives/tabs/use-tabs-overflow.d.ts +1 -1
  80. package/dist/lib/components/ui/widgets/calculator/calculator-announce.d.ts +27 -0
  81. package/dist/lib/components/ui/widgets/calculator/calculator-clipboard.d.ts +19 -0
  82. package/dist/lib/components/ui/widgets/calculator/calculator-context.d.ts +49 -0
  83. package/dist/lib/components/ui/widgets/calculator/calculator-feedback.d.ts +18 -0
  84. package/dist/lib/components/ui/widgets/calculator/calculator-keyboard.d.ts +30 -0
  85. package/dist/lib/components/ui/widgets/calculator/calculator-storage.d.ts +17 -0
  86. package/dist/lib/components/ui/widgets/calculator/calculator-variant-steps.d.ts +16 -0
  87. package/dist/lib/components/ui/widgets/calculator/calculator.d.ts +11 -0
  88. package/dist/lib/components/ui/widgets/calculator/calculator.selectors.d.ts +23 -0
  89. package/dist/lib/components/ui/widgets/calculator/calculator.slice.d.ts +1881 -0
  90. package/dist/lib/components/ui/widgets/calculator/currency.d.ts +9 -0
  91. package/dist/lib/components/ui/widgets/calculator/engine.d.ts +22 -0
  92. package/dist/lib/components/ui/widgets/calculator/index.d.ts +3 -0
  93. package/dist/lib/components/ui/widgets/calculator/partials/calculator-announcer.d.ts +2 -0
  94. package/dist/lib/components/ui/widgets/calculator/partials/calculator-display.d.ts +3 -0
  95. package/dist/lib/components/ui/widgets/calculator/partials/calculator-key.d.ts +17 -0
  96. package/dist/lib/components/ui/widgets/calculator/partials/calculator-keypad.d.ts +8 -0
  97. package/dist/lib/components/ui/widgets/calculator/partials/calculator-loading.d.ts +6 -0
  98. package/dist/lib/components/ui/widgets/calculator/partials/calculator-memory.d.ts +2 -0
  99. package/dist/lib/components/ui/widgets/calculator/partials/calculator-panel-announce.d.ts +10 -0
  100. package/dist/lib/components/ui/widgets/calculator/partials/calculator-panel-body.d.ts +9 -0
  101. package/dist/lib/components/ui/widgets/calculator/partials/calculator-screen.d.ts +4 -0
  102. package/dist/lib/components/ui/widgets/calculator/partials/calculator-segment.d.ts +21 -0
  103. package/dist/lib/components/ui/widgets/calculator/partials/calculator-shell.d.ts +9 -0
  104. package/dist/lib/components/ui/widgets/calculator/partials/calculator-switcher.d.ts +5 -0
  105. package/dist/lib/components/ui/widgets/calculator/partials/calculator-tape.d.ts +4 -0
  106. package/dist/lib/components/ui/widgets/calculator/partials/calculator-tools.d.ts +4 -0
  107. package/dist/lib/components/ui/widgets/calculator/partials/keypad-navigation.d.ts +24 -0
  108. package/dist/lib/components/ui/widgets/calculator/types.d.ts +102 -0
  109. package/dist/lib/components/ui/widgets/calculator/use-calculator-clipboard.d.ts +19 -0
  110. package/dist/lib/components/ui/widgets/calculator/use-calculator-conversion.d.ts +4 -0
  111. package/dist/lib/components/ui/widgets/calculator/use-calculator-feedback.d.ts +3 -0
  112. package/dist/lib/components/ui/widgets/calculator/use-calculator-keyboard.d.ts +22 -0
  113. package/dist/lib/components/ui/widgets/calculator/use-calculator-persistence.d.ts +14 -0
  114. package/dist/lib/components/ui/widgets/calculator/use-calculator-pos.d.ts +25 -0
  115. package/dist/lib/components/ui/widgets/calculator/use-calculator-press.d.ts +26 -0
  116. package/dist/lib/components/ui/widgets/calculator/use-calculator-tape.d.ts +29 -0
  117. package/dist/lib/components/ui/widgets/calculator/use-calculator-value.d.ts +9 -0
  118. package/dist/lib/components/ui/widgets/calculator/use-calculator-variant.d.ts +23 -0
  119. package/dist/lib/components/ui/widgets/calculator/use-calculator.d.ts +10 -0
  120. package/dist/lib/components/ui/widgets/calculator/use-engine-settings.d.ts +10 -0
  121. package/dist/lib/components/ui/widgets/calculator/variants/conversion/conversion-fields.d.ts +19 -0
  122. package/dist/lib/components/ui/widgets/calculator/variants/conversion/conversion-labels.d.ts +17 -0
  123. package/dist/lib/components/ui/widgets/calculator/variants/conversion/conversion-math.d.ts +31 -0
  124. package/dist/lib/components/ui/widgets/calculator/variants/conversion/conversion-names.d.ts +4 -0
  125. package/dist/lib/components/ui/widgets/calculator/variants/conversion/conversion-panel.d.ts +7 -0
  126. package/dist/lib/components/ui/widgets/calculator/variants/conversion/conversion-rates.d.ts +29 -0
  127. package/dist/lib/components/ui/widgets/calculator/variants/conversion/conversion-result.d.ts +15 -0
  128. package/dist/lib/components/ui/widgets/calculator/variants/conversion/conversion-state.d.ts +36 -0
  129. package/dist/lib/components/ui/widgets/calculator/variants/conversion/conversion-variant.d.ts +3 -0
  130. package/dist/lib/components/ui/widgets/calculator/variants/conversion/use-conversion.d.ts +24 -0
  131. package/dist/lib/components/ui/widgets/calculator/variants/financial/financial-change.d.ts +4 -0
  132. package/dist/lib/components/ui/widgets/calculator/variants/financial/financial-figures.d.ts +43 -0
  133. package/dist/lib/components/ui/widgets/calculator/variants/financial/financial-format.d.ts +12 -0
  134. package/dist/lib/components/ui/widgets/calculator/variants/financial/financial-loan-math.d.ts +14 -0
  135. package/dist/lib/components/ui/widgets/calculator/variants/financial/financial-loan.d.ts +4 -0
  136. package/dist/lib/components/ui/widgets/calculator/variants/financial/financial-margin.d.ts +4 -0
  137. package/dist/lib/components/ui/widgets/calculator/variants/financial/financial-math.d.ts +10 -0
  138. package/dist/lib/components/ui/widgets/calculator/variants/financial/financial-panel.d.ts +7 -0
  139. package/dist/lib/components/ui/widgets/calculator/variants/financial/financial-parts.d.ts +35 -0
  140. package/dist/lib/components/ui/widgets/calculator/variants/financial/financial-table.d.ts +7 -0
  141. package/dist/lib/components/ui/widgets/calculator/variants/financial/financial-variant.d.ts +3 -0
  142. package/dist/lib/components/ui/widgets/calculator/variants/financial/financial-vat.d.ts +4 -0
  143. package/dist/lib/components/ui/widgets/calculator/variants/key-layout.d.ts +51 -0
  144. package/dist/lib/components/ui/widgets/calculator/variants/pos/pos-announce.d.ts +16 -0
  145. package/dist/lib/components/ui/widgets/calculator/variants/pos/pos-aside.d.ts +2 -0
  146. package/dist/lib/components/ui/widgets/calculator/variants/pos/pos-display.d.ts +2 -0
  147. package/dist/lib/components/ui/widgets/calculator/variants/pos/pos-fields.d.ts +2 -0
  148. package/dist/lib/components/ui/widgets/calculator/variants/pos/pos-layout.d.ts +9 -0
  149. package/dist/lib/components/ui/widgets/calculator/variants/pos/pos-line.d.ts +6 -0
  150. package/dist/lib/components/ui/widgets/calculator/variants/pos/pos-names.d.ts +2 -0
  151. package/dist/lib/components/ui/widgets/calculator/variants/pos/pos-state.d.ts +3 -0
  152. package/dist/lib/components/ui/widgets/calculator/variants/pos/pos-tender.d.ts +2 -0
  153. package/dist/lib/components/ui/widgets/calculator/variants/pos/pos-ticket-data.d.ts +41 -0
  154. package/dist/lib/components/ui/widgets/calculator/variants/pos/pos-ticket.d.ts +5 -0
  155. package/dist/lib/components/ui/widgets/calculator/variants/pos/pos-totals.d.ts +2 -0
  156. package/dist/lib/components/ui/widgets/calculator/variants/pos/pos-types.d.ts +76 -0
  157. package/dist/lib/components/ui/widgets/calculator/variants/pos/pos-variant.d.ts +3 -0
  158. package/dist/lib/components/ui/widgets/calculator/variants/pos/pos-vat.d.ts +2 -0
  159. package/dist/lib/components/ui/widgets/calculator/variants/pos/pos-view.d.ts +28 -0
  160. package/dist/lib/components/ui/widgets/calculator/variants/programmer/programmer-announce.d.ts +19 -0
  161. package/dist/lib/components/ui/widgets/calculator/variants/programmer/programmer-base.d.ts +11 -0
  162. package/dist/lib/components/ui/widgets/calculator/variants/programmer/programmer-bitpad.d.ts +14 -0
  163. package/dist/lib/components/ui/widgets/calculator/variants/programmer/programmer-display.d.ts +9 -0
  164. package/dist/lib/components/ui/widgets/calculator/variants/programmer/programmer-layout.d.ts +6 -0
  165. package/dist/lib/components/ui/widgets/calculator/variants/programmer/programmer-names.d.ts +2 -0
  166. package/dist/lib/components/ui/widgets/calculator/variants/programmer/programmer-readouts.d.ts +14 -0
  167. package/dist/lib/components/ui/widgets/calculator/variants/programmer/programmer-reduce.d.ts +29 -0
  168. package/dist/lib/components/ui/widgets/calculator/variants/programmer/programmer-state.d.ts +22 -0
  169. package/dist/lib/components/ui/widgets/calculator/variants/programmer/programmer-toolbar.d.ts +5 -0
  170. package/dist/lib/components/ui/widgets/calculator/variants/programmer/programmer-variant.d.ts +3 -0
  171. package/dist/lib/components/ui/widgets/calculator/variants/programmer/programmer-word.d.ts +15 -0
  172. package/dist/lib/components/ui/widgets/calculator/variants/registry.d.ts +21 -0
  173. package/dist/lib/components/ui/widgets/calculator/variants/scientific/scientific-layout.d.ts +3 -0
  174. package/dist/lib/components/ui/widgets/calculator/variants/scientific/scientific-names.d.ts +2 -0
  175. package/dist/lib/components/ui/widgets/calculator/variants/scientific/scientific-toolbar.d.ts +2 -0
  176. package/dist/lib/components/ui/widgets/calculator/variants/scientific/scientific-variant.d.ts +3 -0
  177. package/dist/lib/components/ui/widgets/calculator/variants/standard/standard-layout.d.ts +3 -0
  178. package/dist/lib/components/ui/widgets/calculator/variants/variant-loader.d.ts +34 -0
  179. package/dist/lib/components/ui/widgets/calculator/variants/variant-logic.d.ts +40 -0
  180. package/dist/lib/components/ui/widgets/calculator/variants/variant-types.d.ts +62 -0
  181. package/dist/lib/i18n/resources/en/en.d.ts +412 -0
  182. package/dist/lib/i18n/resources/en/material.json.d.ts +412 -0
  183. package/dist/lib/i18n/resources/fr/fr.d.ts +412 -0
  184. package/dist/lib/i18n/resources/fr/material.json.d.ts +412 -0
  185. package/dist/lib/i18n/resources/resources.d.ts +824 -0
  186. package/dist/lib/i18n/translator.d.ts +1 -1
  187. package/dist/lib.js +4 -3
  188. package/dist/main.js +52 -42
  189. package/dist/map.js +66 -65
  190. package/dist/material.css +1 -1
  191. package/dist/native-select-w_FlBLHV.js +40 -0
  192. package/dist/number.utils-CSueQZcv.js +7 -0
  193. package/dist/pdf-reader.js +1 -1
  194. package/dist/percent-field--WIXV5dX.js +14 -0
  195. package/dist/picker-surface-CV09H7Nb.js +1220 -0
  196. package/dist/popover-Cd7DkND4.js +233 -0
  197. package/dist/pos-types-DKCkOTYy.js +49 -0
  198. package/dist/pos-variant-GrUfbTTP.js +603 -0
  199. package/dist/print.js +1 -1
  200. package/dist/programmer-variant-eKJNKENL.js +501 -0
  201. package/dist/programmer-word-CNCF7DJF.js +15 -0
  202. package/dist/{public-DC9VQw4Z.js → public-y6g4ddxd.js} +895 -892
  203. package/dist/{rich-code-block-DBSL9zEN.js → rich-code-block-CRQ0iyLb.js} +5 -5
  204. package/dist/scientific-variant-2y3UxAAU.js +149 -0
  205. package/dist/{sortable-provider-C4tk5esY.js → sortable-provider-DdiI3Fwk.js} +2 -2
  206. package/dist/{spinner-B2MubVWb.js → spinner-C1QIewWv.js} +133 -159
  207. package/dist/standard-layout-BuSRr3TY.js +40 -0
  208. package/dist/tabs-BT9pSRwk.js +414 -0
  209. package/dist/{icon-badge-B9uvDoyY.js → text-field-BAdY-kpO.js} +20 -34
  210. package/dist/theme-picker.js +3 -3
  211. package/dist/{theme-toggle-BInlu21G.js → theme-toggle-C_VeiiCm.js} +2 -2
  212. package/dist/toggle-FeCCJqbg.js +40 -0
  213. package/dist/{toggle-group-DXXlqid2.js → toggle-group-CVMxEpWi.js} +1 -1
  214. package/dist/{toolbar-items-CRJSx1MU.js → toolbar-items-D310xDuM.js} +333 -554
  215. package/dist/{translate-material-pVlPJ1v4.js → translate-material-BypJJ1l5.js} +1 -1
  216. package/dist/{translator-BoYCward.js → translator-DJkf4J7t.js} +824 -0
  217. package/dist/{typography-B6YMbCge.js → typography-CYEquVeb.js} +1 -1
  218. package/dist/{use-chat-composer-BvWQogJe.js → use-chat-composer-BOx4I6Ma.js} +4198 -4600
  219. package/dist/{use-heading-spy-B_Z4ArDh.js → use-heading-spy-DJR8YYm6.js} +19 -19
  220. package/dist/{use-material-translation-CIS2n3RB.js → use-material-translation-CD6QoVal.js} +1 -1
  221. package/dist/{use-return-focus-DNQtADAR.js → use-return-focus-Cevw_6yq.js} +106 -105
  222. package/dist/useLatest-C2PnQEeD.js +8 -0
  223. package/docs/README.md +1 -0
  224. package/docs/components/data-display.md +2 -1
  225. package/docs/components/data-table-filter-and-lists.md +13 -1
  226. package/docs/components/feedback-and-status.md +10 -1
  227. package/docs/components/form-fields.md +7 -3
  228. package/docs/components/navigation-and-layout.md +29 -1
  229. package/docs/components/rich-widgets.md +108 -0
  230. package/docs/components/selection-and-choice.md +3 -1
  231. package/docs/getting-started.md +1 -0
  232. package/docs/guides/app-shell.md +6 -4
  233. package/docs/guides/calculator.md +468 -0
  234. package/docs/guides/forms.md +4 -2
  235. package/docs/guides/i18n.md +5 -0
  236. package/docs/guides/theming.md +5 -5
  237. package/docs/previews/rich-widgets-calculator-conversion.webp +0 -0
  238. package/docs/previews/rich-widgets-calculator-point-of-sale.webp +0 -0
  239. package/docs/previews/rich-widgets-calculator.webp +0 -0
  240. package/docs/roadmap.md +9 -3
  241. package/docs/troubleshooting.md +137 -2
  242. package/lib/components/base-content.css +9 -4
  243. package/lib/components/ui/display/chip/chip-hairline.css +19 -0
  244. package/lib/components/ui/display/chip/chip-soft.css +18 -0
  245. package/lib/components/ui/widgets/calculator/calculator-bands.css +146 -0
  246. package/lib/components/ui/widgets/calculator/calculator-display.css +83 -0
  247. package/lib/components/ui/widgets/calculator/calculator-keys.css +118 -0
  248. package/lib/components/ui/widgets/calculator/calculator-pos-ticket.css +185 -0
  249. package/lib/components/ui/widgets/calculator/calculator-pos.css +38 -0
  250. package/lib/components/ui/widgets/calculator/calculator-tape.css +71 -0
  251. package/lib/components/ui/widgets/calculator/calculator.css +97 -0
  252. package/lib/components/ui/widgets/calculator/variants/conversion/conversion.css +98 -0
  253. package/lib/components/ui/widgets/calculator/variants/financial/financial.css +162 -0
  254. package/lib/components/ui/widgets/calculator/variants/programmer/programmer.css +162 -0
  255. package/lib/themes/ambre.css +1 -1
  256. package/lib/themes/ardoise.css +1 -1
  257. package/lib/themes/bleumono.css +1 -1
  258. package/lib/themes/bluemoon.css +1 -1
  259. package/lib/themes/corail.css +2 -2
  260. package/lib/themes/foret.css +1 -1
  261. package/lib/themes/lavande.css +1 -1
  262. package/lib/themes/menthe.css +1 -1
  263. package/lib/themes/ocean.css +1 -1
  264. package/lib/themes/pink.css +2 -2
  265. package/lib/themes/prune.css +1 -1
  266. package/lib/themes/sable.css +1 -1
  267. package/lib/themes/slate.css +1 -1
  268. package/lib/themes/teal.css +3 -3
  269. package/package.json +17 -3
  270. package/dist/dialog-AGsB3bv4.js +0 -219
  271. package/dist/dist-B7RjY7SL.js +0 -158
  272. package/dist/dist-lmHmz_bu.js +0 -419
package/CHANGELOG.md CHANGED
@@ -1,10 +1,80 @@
1
1
  # @nxgt/material
2
2
 
3
- ## 3.75.1-hotfix-20261030064707
3
+ ## 3.77.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#2336](https://github.com/softistx/nxgt-material/pull/2336) [`bdfa59d`](https://github.com/softistx/nxgt-material/commit/bdfa59d3566b2bc65c09214b735c2a1febb1c645) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `Hero` gains `background` (the props of the `Background` of `@nxgt/material/backgrounds`: `preset`, `intensity`, `tone`, `fill`…, drawn `aria-hidden` behind the content, clipped by the band's radius, loaded on demand, replacing the built-in gradient and glows), `size="compact"` (a greeting band for a home page: `rounded-xl`, a Card's content padding, the title in `headline-lg` emphasized, a muted description, actions at the end from `lg` and wrapping below, buttons at least 44px tall) and `headingLevel` (1 to 6, default 1). `aria-label` now passes through to the section. The new type `HeroBackgroundProps` is exported from `@nxgt/material/components`. The default Hero renders as before. Fixes [#2335](https://github.com/softistx/nxgt-material/issues/2335).
8
+
9
+ - [#2378](https://github.com/softistx/nxgt-material/pull/2378) [`034fe52`](https://github.com/softistx/nxgt-material/commit/034fe5294cebca878c3bcb53fe19753f29214ec3) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Add `rowFocusProps(rowId)`, to spread on a plain row button (an edit pen opening a dialog) so `useRowMenuFocus().focusRowMenu(rowId)` hands the focus back to it like a `RowMenu` trigger, with no local map of button refs ([#2377](https://github.com/softistx/nxgt-material/issues/2377)).
10
+
11
+ ### Patch Changes
12
+
13
+ - [#2351](https://github.com/softistx/nxgt-material/pull/2351) [`4eebac0`](https://github.com/softistx/nxgt-material/commit/4eebac0fe3574ce52acf9bdef722137c3df3c47b) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Fix the app bar's page title on a phone: a long title (a record's number such as `Prescription P00000001`) now wraps to a second line before it is cut with an ellipsis, so the identifier stays readable by touch, where the `title` tooltip cannot be reached. From `md` up it is unchanged (one line, ellipsis); the full-text `title` is still set whenever the text is cut off. Fixes [#2324](https://github.com/softistx/nxgt-material/issues/2324).
14
+
15
+ - [#2374](https://github.com/softistx/nxgt-material/pull/2374) [`fef1413`](https://github.com/softistx/nxgt-material/commit/fef14130acaf94aa69a65ed4343504fd3b64870c) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Fix `ChangeHistory` on a phone: a long unbroken value (a URL, a reference) is no longer clipped inside the rail's value pill or the old value, and a long unbroken field name now wraps in both the rail and the cards instead of widening the page at 360px. Spaced text already wrapped. Fixes [#2358](https://github.com/softistx/nxgt-material/issues/2358).
16
+
17
+ - [#2370](https://github.com/softistx/nxgt-material/pull/2370) [`fcdeacc`](https://github.com/softistx/nxgt-material/commit/fcdeacc3332119aa0860d986e55edceb24095227) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Fix the unselected chips of a `ChipGroupField` (and any neutral toggle `Chip`, `aria-checked` or `aria-pressed`) having no visible container in dark mode: the tonal fill alone was about 1.2:1 over the card. An unselected toggle chip now draws a boundary of 50 % of `--foreground` over the page (64 % on hover), at least 3:1 against the page and the card in light and dark on the 14 presets, teal included (WCAG 1.4.11). Selected chips, plain and coloured chips are unchanged. Fixes [#2357](https://github.com/softistx/nxgt-material/issues/2357).
18
+
19
+ - [#2347](https://github.com/softistx/nxgt-material/pull/2347) [`875ce11`](https://github.com/softistx/nxgt-material/commit/875ce1161e95e41594cf27b50958cbed0d831494) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Fix `CurrencyField` and `CurrencyFormField` drawing the currency code in an opaque 32 px box off the field's fill, with the code at its top: the code now sits on the field's own surface and is centred on the amount's line, in light and dark and on touch screens ([#2343](https://github.com/softistx/nxgt-material/issues/2343)).
20
+
21
+ - [#2353](https://github.com/softistx/nxgt-material/pull/2353) [`5d876d4`](https://github.com/softistx/nxgt-material/commit/5d876d4e27218dd0281cee04f33572c3026bb6fe) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Paint the EntityHeader band with the Card surface (`bg-card`) instead of the page ground (`bg-background`). In dark an EntityHeader beside a Card was near-black while the Card was a lighter surface; both now sit on the same elevation, in every preset. Fixes [#2323](https://github.com/softistx/nxgt-material/issues/2323).
22
+
23
+ - [#2367](https://github.com/softistx/nxgt-material/pull/2367) [`7615ecc`](https://github.com/softistx/nxgt-material/commit/7615ecc5c8c54c3188742d1a4108ed39852dfbd5) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `EntityHeader`: a lone icon-only action (`expanded: false`) stays beside the title at narrow widths instead of taking its own row ([#2360](https://github.com/softistx/nxgt-material/issues/2360)).
24
+
25
+ - [#2338](https://github.com/softistx/nxgt-material/pull/2338) [`ddcfa2c`](https://github.com/softistx/nxgt-material/commit/ddcfa2cf9e4166f9e86e9bb574ec02f5c5942bfb) Thanks [@SteveGT96](https://github.com/SteveGT96)! - fix(quantity-field): keep the number input a 44px tap target at 375px; the unit part shrinks before the number does ([#2327](https://github.com/softistx/nxgt-material/issues/2327)).
26
+
27
+ - [#2364](https://github.com/softistx/nxgt-material/pull/2364) [`45bb1dd`](https://github.com/softistx/nxgt-material/commit/45bb1dd8fc939f3d57971054020de4622baeee96) Thanks [@SteveGT96](https://github.com/SteveGT96)! - A `ServerTable` on a phone without `actions` now puts the labelled "Select all" in the second row (with the sort and "Filters"), as it does with `actions`, instead of a blank full-width band holding a bare checkbox. Fixes [#2363](https://github.com/softistx/nxgt-material/issues/2363).
28
+
29
+ - [#2373](https://github.com/softistx/nxgt-material/pull/2373) [`cc97b1a`](https://github.com/softistx/nxgt-material/commit/cc97b1a91e4137a109e641d73a93dd9012c09172) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Docs and a code comment only: the theming guides now describe `--primary-text` (light) and the dark `--error-text` as solved shares per theme (teal 94 %, corail 89 %, pink 94 %; dark error 71 % on teal), not the fixed 96 % and 76 %. No behaviour change.
30
+
31
+ - [#2334](https://github.com/softistx/nxgt-material/pull/2334) [`599fab6`](https://github.com/softistx/nxgt-material/commit/599fab6f0b743b7b06e09fc420c5c52911bec201) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Fix `TabsNav` (and `Tabs`) leaving the active tab half under a scroll chevron after the tabs or the list changed size (a web font, a count, a rotation): the active tab is now kept revealed, clear of the chevrons, until the person scrolls the list themselves ([#2328](https://github.com/softistx/nxgt-material/issues/2328)).
32
+
33
+ - [#2362](https://github.com/softistx/nxgt-material/pull/2362) [`3bc6091`](https://github.com/softistx/nxgt-material/commit/3bc6091b15e0fa644907720b4b220ba43a09eaae) Thanks [@SteveGT96](https://github.com/SteveGT96)! - The dark `--error-text` is solved against the dark `--background` and `--card`: its share of the error colour drops below 76 % when a lighter card (the teal preset's) would leave it under 5.3:1, so a field's error message and an inline alert keep 4.5:1 in axe on that card. Other presets are unchanged. Fixes [#2332](https://github.com/softistx/nxgt-material/issues/2332).
34
+
35
+ - [#2366](https://github.com/softistx/nxgt-material/pull/2366) [`2ae3bba`](https://github.com/softistx/nxgt-material/commit/2ae3bbacf31cce96639579468d4edd2d2f66c943) Thanks [@SteveGT96](https://github.com/SteveGT96)! - fix(theme): `primary-text` (light) darkens when a tinted page would leave a tonal Button label under 4.5:1 on a striped table row; Teal's label is now AA there. `CONTRAST_PAIRS` gains `primary-text` on `primary@row15` ([#2322](https://github.com/softistx/nxgt-material/issues/2322)).
36
+ - Updated dependencies [[`cc97b1a`](https://github.com/softistx/nxgt-material/commit/cc97b1a91e4137a109e641d73a93dd9012c09172), [`3bc6091`](https://github.com/softistx/nxgt-material/commit/3bc6091b15e0fa644907720b4b220ba43a09eaae), [`2ae3bba`](https://github.com/softistx/nxgt-material/commit/2ae3bbacf31cce96639579468d4edd2d2f66c943)]:
37
+ - @nxgt/material-core@0.49.1
38
+
39
+ ## 3.76.0
40
+
41
+ ### Minor Changes
42
+
43
+ - [#2200](https://github.com/softistx/nxgt-material/pull/2200) [`c7e7530`](https://github.com/softistx/nxgt-material/commit/c7e7530a956c54c681d35f98936c6c4973a2cf02) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Add the Conversion variant to `Calculator` (`@nxgt/material/calculator`), the "Conversion" tab: a category (length, mass, temperature, volume, area, speed, time, data), a value typed in the locale's own separators, the unit it is in and the unit wanted, a swap button and the exact result in the locale (`1 in` is `2.54 cm`, `212 °F` is `100 °C`), on `@nxgt/material-core/calculator/units`. The result is read once the value stops changing, not at every digit. New prop `currencyRates` adds a Currency category: an object `{ base, rates, asOf? }`, or a function `(signal: AbortSignal) => Promise<{ base, rates, asOf? }>` with loading, error and Try again states and an "as of" date; a currency amount is rounded to the target currency's minor unit, and without `currencyRates` the category is not offered. The variant brings a `panel` (a body of its own in place of the keypad, display and tape) to the variant registry. New `material.calculator.conversion.*` strings, with the name of every unit, in English and French. The switcher now offers Conversion by default: pass `variants` for a fixed set. Refs [#2101](https://github.com/softistx/nxgt-material/issues/2101).
44
+
45
+ - [#2243](https://github.com/softistx/nxgt-material/pull/2243) [`4379476`](https://github.com/softistx/nxgt-material/commit/43794763d26f682269d1a66f63b38a017e35d894) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Add the `@nxgt/material/calculator-field` entry with `CalculatorField` and `CalculatorFormField`: a `NumberField` (a `CurrencyField` when `currency` is set) with an "Open calculator" button inside it. The button opens a `Calculator` seeded with the field's number, in a popover from 768px wide and a bottom sheet below (`surface` chooses). Apply writes the result (a currency amount rounded half-up to the currency's decimals, held to `min` and `max`; `onExactValueChange` gets the exact decimal first), Cancel and Escape keep the number, and focus goes back to the button. The calculator offers only Standard unless `calculatorVariants` lists more; `calculatorVariant` picks what opens. `CalculatorFormField` is the React Hook Form wrapper, with the same blur rule as the other pickers. The field is its own entry, so `/calculator` stays as small as before. `Calculator` gains `defaultValue` (a number it opens with, as a finished result) and `onValueChange` (the display's exact value as it changes); `CurrencyField` gains `trailingAction` (a button after the currency code). New `material.calculator.field.*` strings in English and French. Refs [#2101](https://github.com/softistx/nxgt-material/issues/2101).
46
+
47
+ - [#2189](https://github.com/softistx/nxgt-material/pull/2189) [`073c61a`](https://github.com/softistx/nxgt-material/commit/073c61acb08e1b271f47c29a3232e0afb93e3bdb) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Add the Financial variant to `Calculator` (`@nxgt/material/calculator`), a panel of forms on `@nxgt/material-core/calculator/financial` instead of a keypad: VAT (add it, or take it out of a price), margin and markup (the rates of a cost and a price, or the price or cost a rate gives), percent change, and a loan with its monthly payment, totals and a captioned amortisation `<table>`. It uses `CurrencyField`, `PercentField` and `NumberField`, rounds to the currency's minor unit, writes amounts in `locale` and announces a result once the fields settle. It reads the shared `currency` prop (decimals and code, none by default). The switcher now offers Financial too. New `material.calculator.financial.*` strings in English and French. Refs [#2101](https://github.com/softistx/nxgt-material/issues/2101).
48
+
49
+ - [#2261](https://github.com/softistx/nxgt-material/pull/2261) [`04590ee`](https://github.com/softistx/nxgt-material/commit/04590ee42c104acd6e540eb0102cc075177e84d5) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `Calculator` (`@nxgt/material/calculator`) and `CalculatorField` (`@nxgt/material/calculator-field`) load every variant but Standard on demand. Scientific, Point of sale, Financial, Conversion and Programmer, with the `@nxgt/material-core/calculator/*` engine each one uses, are separate chunks fetched the first time the variant is shown (by `variant`, `defaultVariant` or the switcher, which also warms the chunk on hover and focus), so an app that only uses Standard no longer downloads them. While a variant loads, its body is a skeleton of Standard's size with a polite status (`material.calculator.loading`); a failed load says so and offers Try again (`material.calculator.load-failed`, `material.calculator.retry`). The server renders that loading body for a non-Standard variant, then the client hydrates and fetches the chunk. The props and exports are unchanged. The loading status is announced: `aria-busy` sits on the skeleton pad, not on the `role="status"` element. Refs [#2101](https://github.com/softistx/nxgt-material/issues/2101).
50
+
51
+ - [#2190](https://github.com/softistx/nxgt-material/pull/2190) [`cb28eaf`](https://github.com/softistx/nxgt-material/commit/cb28eaf455991af4648dbe3b96c7615887043cbf) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Add the point-of-sale variant to `Calculator` (`@nxgt/material/calculator`), the "Point of sale" tab: an amount typed like a till (`1`, `2`, `5` is `1.25`, a `00` key), a quantity (`×`), a discount in percent or amount (`%`), a ticket whose lines are removed one by one (it folds away on a phone), VAT by rate with prices including it or not, the bills to hand over from your `denominations`, the change due and a Charge button that calls `onCharge(total, ticket)` with the total and a plain, JSON-safe `PosTicket` (lines, discounts, totals and VAT by rate as text). New props `currency` (shared by the variants that show amounts), `vatRates`, `pricesIncludeVat`, `denominations` and `onCharge`; amounts are exact and rounded to the currency's minor unit, the ticket is never stored, and only the total, the change and the amount due are announced. The switcher now offers the point of sale by default: pass `variants` for a fixed set. New `material.calculator.pos.*` strings and `keys.*` names in English and French. Refs [#2101](https://github.com/softistx/nxgt-material/issues/2101).
52
+
53
+ - [#2216](https://github.com/softistx/nxgt-material/pull/2216) [`e38b616`](https://github.com/softistx/nxgt-material/commit/e38b6166e51d047024a010c171298a56afecbcc6) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Add the Programmer variant to `Calculator` (`@nxgt/material/calculator`), on `@nxgt/material-core/calculator/programmer`: integers in a word of 8, 16, 32 or 64 bits, signed or unsigned (`defaultWordSize`, `defaultSigned`), with `A` to `F`, the word operators, shifts and rotates on the keypad. HEX, DEC, OCT and BIN readouts are a single choice that sets the base the digits are typed in (digits the base lacks are disabled), the word size and sign change the word and announce when a value is cut, and a bit pad of `aria-pressed` buttons flips single bits. The switcher now offers Programmer too. New `material.calculator.programmer.*` strings, key names and word announcements in English and French. Refs [#2101](https://github.com/softistx/nxgt-material/issues/2101).
54
+
55
+ - [#2161](https://github.com/softistx/nxgt-material/pull/2161) [`9f0f309`](https://github.com/softistx/nxgt-material/commit/9f0f309a07e8ede0f67603e7da759938b112eb45) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Add the Scientific variant to `Calculator` (`@nxgt/material/calculator`): `sin cos tan` and the hyperbolic functions (2nd for the inverses), `ln log log₂ 10ˣ eˣ`, powers and roots, `n!`, `1/x`, `|x|`, `π`, `e`, `EE` (a real exponent entry: `3 EE 5` is `3e5`) and `mod`, calculated exactly to 34 digits (`sin(30)` is `0.5`). A toolbar chooses the angle unit (degrees, radians, gradians) and the result notation (auto, scientific, engineering) and announces each change; the functions sit above the Standard keys on a phone and beside them on a tablet. The switcher now offers Standard and Scientific by default: pass `variants={['standard']}` for the single Standard calculator. New `material.calculator.keys.*`, `angle.*` and `notation.*` strings in English and French. Refs [#2101](https://github.com/softistx/nxgt-material/issues/2101).
56
+
57
+ - [#2138](https://github.com/softistx/nxgt-material/pull/2138) [`8040e76`](https://github.com/softistx/nxgt-material/commit/8040e768be8b72db5a9601deabea8989f0378d1f) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Add `@nxgt/material/calculator`: `Calculator`, an exact-decimal calculator with the usual precedence (`2 + 3 × 4` is 14), a large display with the expression above the result, a shaped keypad (`=` a primary pill), a tape of past results to replay and reuse, a memory, the physical keyboard (`globalKeyboard` opt-in), copy and paste, and a screen-reader announcement of each result. The Standard variant is in; the others join the same switcher. The tape and memory are kept in `localStorage` after mount (`persist`, on by default, `persist={false}` to opt out); haptics and sound are off unless `feedback` asks. The maths is `@nxgt/material-core/calculator`, with no `eval`. Nothing to migrate. Refs [#2101](https://github.com/softistx/nxgt-material/issues/2101).
58
+
59
+ - [#2315](https://github.com/softistx/nxgt-material/pull/2315) [`13e710c`](https://github.com/softistx/nxgt-material/commit/13e710c8d37d6fbd349ad44bf62a4742bcfafc47) Thanks [@SteveGT96](https://github.com/SteveGT96)! - `Moment` gains `modal={false}`, a non-modal variant for an event the user did not trigger (a live update). Focus stays where it is (no move, no trap, no return), the page behind stays interactive and the backdrop lets taps through (only the text and the close button take them), and the text is announced politely through a `role="status"` live region instead of a dialog. Same visuals, `duration` and reduced-motion behaviour. The default stays a modal dialog. Fixes [#2313](https://github.com/softistx/nxgt-material/issues/2313).
4
60
 
5
61
  ### Patch Changes
6
62
 
7
- - [`80b31fb`](https://github.com/softistx/nxgt-material/commit/80b31fbc82b47196dadc7d894c0877d045fa4dbb) Thanks [@SteveGT96](https://github.com/SteveGT96)! - fix(server-table): on a phone the list header's "Select all" box keeps a 44x44 hit area that `@nxgt/playwright`'s `expectTapTargets` accepts, with rows selected. Since [#2295](https://github.com/softistx/nxgt-material/issues/2295) the list draws no panel on a phone, so the box moved 16px nearer the screen's edge: in an 8px page gutter its centre sat 20px from it. The check moves the 44px square centred on the box inside the viewport, and that square then reached 2px past the box's `::after` onto the list bar. The label now takes back 6px instead of 14px, so the box's centre is 22px or more from the edge in any gutter of 2px or more. The "Select all" label stays whole at 375 and 412px. Fixes [#2304](https://github.com/softistx/nxgt-material/issues/2304).
63
+ - [#2250](https://github.com/softistx/nxgt-material/pull/2250) [`a574c60`](https://github.com/softistx/nxgt-material/commit/a574c6068e4818868073648aad31458a6ba9a92a) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Fix two `Calculator` details: on a phone width (under 480px) the variant switcher draws each active tab's own surface instead of one sliding indicator that spanned a single row of the two-column grid, and in the Programmer variant a base change on an expression that ends in an operator rewrites its numbers in place (`10+` in decimal is `a+` in hex) instead of collapsing it to a value. Refs [#2101](https://github.com/softistx/nxgt-material/issues/2101).
64
+
65
+ The calculator's stylesheet is opt-in: `styles.css` no longer carries it, so import `@nxgt/material/calculator.css` after `styles.css` or the calculator renders unstyled. `CalculatorField` with `currency` is a `CurrencyField`: `suffix`, `step`, `hideSteppers` and the typing-time `min` / `max` apply only without `currency`. In core, point of sale and financial share one money module: a negative amount or rate and a `digits` / `fractionDigits` outside 0 to 12 are `invalid-amount`, and the point of sale's `toMinor` is `toMinorUnits`.
66
+
67
+ - [#2181](https://github.com/softistx/nxgt-material/pull/2181) [`45a817b`](https://github.com/softistx/nxgt-material/commit/45a817b4c202e87c1a2f952496778b25382423b0) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Map the point-of-sale error codes of the calculator engine (`invalid-amount`, `duplicate-line`, `unknown-line`) to `material.calculator.error.*` messages in English and French. Refs [#2101](https://github.com/softistx/nxgt-material/issues/2101).
68
+
69
+ - [#2329](https://github.com/softistx/nxgt-material/pull/2329) [`70c5189`](https://github.com/softistx/nxgt-material/commit/70c51896f8a3934c0a84eaa1d7488a26cfb0197c) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Fix `.form-grid-layout` on a page: a short form's `form-actions` no longer draws a second slab under the fields. The actions wear the fields' tint with no gap between them, so fields and actions read as one surface, and they stay sticky at the bottom of whatever scrolls a long form. Fixes [#2307](https://github.com/softistx/nxgt-material/issues/2307).
70
+
71
+ - [#2310](https://github.com/softistx/nxgt-material/pull/2310) [`c55b426`](https://github.com/softistx/nxgt-material/commit/c55b42630810315aae2b16e53b395775563f9b15) Thanks [@SteveGT96](https://github.com/SteveGT96)! - fix(server-table): on a phone the list header's "Select all" box keeps a 44x44 hit area that `@nxgt/playwright`'s `expectTapTargets` accepts, with rows selected. Since [#2295](https://github.com/softistx/nxgt-material/issues/2295) the list draws no panel on a phone, so the box moved 16px nearer the screen's edge: in an 8px page gutter its centre sat 20px from it. The check moves the 44px square centred on the box inside the viewport, and that square then reached 2px past the box's `::after` onto the list bar. The label now takes back 6px instead of 14px, so the box's centre is 22px or more from the edge in any gutter of 2px or more. The "Select all" label stays whole at 375 and 412px. Fixes [#2304](https://github.com/softistx/nxgt-material/issues/2304).
72
+
73
+ - [#2318](https://github.com/softistx/nxgt-material/pull/2318) [`e2807c4`](https://github.com/softistx/nxgt-material/commit/e2807c446cdc39ccead6af83000360d0b24d3b78) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Fix the `ServerTable` band's title sitting 4px inside the list: the band carried `px-1` that the panel's padding used to need. On a phone the title now starts at the tile list (the layout gutter), and from 768px it lines up with the table's start and the page's other titles. A `ServerTable` sits inside a page gutter (the layout's, or the caller's own padding when used standalone, as 3.75.0 documents); the coarse-pointer select-all's 44px hit area overhangs 4px into that gutter. Fixes [#2305](https://github.com/softistx/nxgt-material/issues/2305).
74
+
75
+ - [#2325](https://github.com/softistx/nxgt-material/pull/2325) [`44823dc`](https://github.com/softistx/nxgt-material/commit/44823dcf6e57b13799dee39a641f824998faa1bb) Thanks [@SteveGT96](https://github.com/SteveGT96)! - Fix `ActivityLayout`'s phone menu sheet: a full-width `context` (a `Switcher` with `w-full`) no longer runs under the sheet's close button. The context line reserves 3rem on its right; short text contexts look unchanged. Fixes [#2306](https://github.com/softistx/nxgt-material/issues/2306).
76
+ - Updated dependencies [[`a574c60`](https://github.com/softistx/nxgt-material/commit/a574c6068e4818868073648aad31458a6ba9a92a), [`4d1a2fe`](https://github.com/softistx/nxgt-material/commit/4d1a2fe4c7393d23210adf809223f2ab16fccb1c), [`9f0f309`](https://github.com/softistx/nxgt-material/commit/9f0f309a07e8ede0f67603e7da759938b112eb45), [`073c61a`](https://github.com/softistx/nxgt-material/commit/073c61acb08e1b271f47c29a3232e0afb93e3bdb), [`76e498d`](https://github.com/softistx/nxgt-material/commit/76e498d37999d12f76b12245eb988178eafaeee4), [`45a817b`](https://github.com/softistx/nxgt-material/commit/45a817b4c202e87c1a2f952496778b25382423b0), [`8d5953a`](https://github.com/softistx/nxgt-material/commit/8d5953a9d554e0061fadd94d1441edf24336d01a), [`995f5a4`](https://github.com/softistx/nxgt-material/commit/995f5a4bbc3dbaa0e106f9239cb96c59738c2778), [`34fae43`](https://github.com/softistx/nxgt-material/commit/34fae4329d85a228ce9d1f12864294dc0deeb07d)]:
77
+ - @nxgt/material-core@0.49.0
8
78
 
9
79
  ## 3.75.0
10
80
 
package/README.md CHANGED
@@ -200,6 +200,8 @@ reads `duotone.svg`, the file that exists (it used to ask for the missing
200
200
  | `@nxgt/material/pdf-reader` | `PdfReader`, the redesigned PDF reader (header, floating page pill, rail and panel; `embedded`, `dialog`, `page` and `fullscreen` modes; single page and two-page layouts; `look="expressive"` by default, `"classic"` to opt out, type `PdfReaderLook`) and `configurePdfReader` for pdf.js's worker and assets. **Its own entry, browser-only** (pdf.js loads on first render); also exported as `PdfReader` from `/components` since 3.0 ([guide](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/pdf-reader.md)) |
201
201
  | `@nxgt/material/charts` | Native SVG charts (d3-scale and d3-shape for the maths only) with keyboard point navigation, a screen-reader summary, a "View data" table and `patterns`: `LineChart` and `AreaChart` (`LineChartProps`, `AreaChartProps`, `ChartCurve`), `BarChart` (`BarChartProps`, `BarLayout`, `BarOrientation`), `PieChart` (`PieChartProps`), `DonutChart` (`DonutChartProps`), `Gauge` (`GaugeProps`, `GaugeSize`), `RadialBarChart` (`RadialBarChartProps`), `FunnelChart` (`FunnelChartProps`), `HeatmapChart` (`HeatmapChartProps`, `HeatColumn`), `RadarChart` (`RadarChartProps`), `ScatterChart` (`ScatterChartProps`, `ScatterSeries`, `ScatterPoint`), `ComboChart` (`ComboChartProps`, `ComboSeries`: bars, areas and lines, each on a left or a right axis), `zoom` (a mini overview with a window and two slider handles that picks the rows shown; `range`, `defaultRange`, `onRangeChange`) and `scroll` (a dense plot scrolls sideways on a phone, the value axis pinned) on the line, area, bar and combo charts (`ChartRangeProps`, `ChartZoomOptions`, `ChartScrollOptions`, `ChartRange`), `bands` (shaded ranges), `thresholds` (labelled lines) and `pointTone` (a ringed point with its word, `toneLabels`) on the line and area charts, read against the value axis and carried into the tooltip, the summary and the "View data" table (`ChartBand`, `ChartThreshold`), `onPointClick` on every chart but `Gauge`, `palette` (`'soft'`: the soft palette, or `data-chart-palette="soft"` on an ancestor; `ChartPalette`) on every chart, and the shared types (`ChartSlice`, `ChartRow`, `ChartValue`, `ChartColor`, `ChartShape`, `ChartSeries`, `ChartAxis`, `ChartXAxis`, `ChartPoint`, `ChartBaseProps`). `categoryLabel` names the "View data" table's category column: on Line, Area, Bar and Combo it defaults to the x axis label, on Radar and Heatmap it is always "Category" unless set. **Its own entry, client-only** (import it from a `'use client'` file), not in the barrel above; replaces the Nivo charts (removed in 3.0) of `/components` ([guide](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/charts.md)) |
202
202
  | `@nxgt/material/barcode` | `Barcode` (Code 128 and Data Matrix as accessible SVG that follows the theme and dark mode, black on white in print; no runtime dependency) and `LabelSheet` / `Label` (label size, columns, rows, gaps and a start offset for a printed sheet of labels), plus `barcodeGeometry` and `BarcodeError` — **its own entry** ([barcode guide](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/barcode.md)) |
203
+ | `@nxgt/material/calculator` | `Calculator`: exact decimal arithmetic with the usual precedence, a large display, a shaped keypad, a tape of past results, a memory, the physical keyboard, copy and paste, screen-reader announcements and a variant switcher (Standard, Scientific, Point of sale, Financial, Conversion and Programmer) — **its own entry** ([calculator guide](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/calculator.md)) |
204
+ | `@nxgt/material/calculator-field` | `CalculatorField` and `CalculatorFormField`: a number field (a currency field with `currency`) whose button opens the calculator, seeded with its number, in a popover or a phone's bottom sheet; Apply writes the rounded result — **its own entry** ([calculator guide](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/calculator.md#in-a-form-calculatorfield)) |
203
205
  | `@nxgt/material/draw` | Vector drawing: a scene of plain data or JSX primitives drawn as accessible, themeable SVG that is safe under a strict CSP and identical on the server and in the browser. `Drawing` (`DrawingProps`, `NodeHandlers`; `scene` or `w`/`h` with children; a `title` (with an optional long `description`, written as a `<desc>`) or `decorative`, enforced by the type), the primitives `Rect`, `Ellipse`, `Circle`, `Line`, `Polygon`, `Path` (takes `node`), `Text`, `Group` and `Image`, and the builders of `@nxgt/material-core/draw` re-exported by name (`scene`, `rect`, `ellipse`, `circle`, `line`, `polygon`, `path`, `text`, `group`, `image`, `linear`, `radial`, `pattern`, `hatch`, `tone`, `toSVG`, `compileScene`, `ROLES`, `DRAW_PALETTE`, and the types `Scene`, `DrawNode`, `Paint`, `Role`, `ToneRef`), plus Material 3 Expressive's shapes (`shape`, `morph`, `SHAPE_NAMES`, `toCubics`) and the layout helpers (`bbox`, `stack`, `grid`, `align`, `distribute`) re-exported by name. Colours are theme roles (`primary-container`, `on-surface`...) mapped to classes in `styles.css`, so import it. Interactive nodes are focusable `button`s with a focus ring; wrapped text is re-measured by the browser once mounted. **Its own entry, client-only** (render `Drawing` from a `'use client'` file; the builders and `toSVG` run anywhere), not in the barrel above ([drawing guide](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/drawing.md)) |
204
206
  | `@nxgt/material/draw/sketch` | The sketchy, hand-drawn style for a drawing: `Sketch` (`seed`, `roughness`, `bowing`, `fill`: `hachure`, `cross-hatch`, `solid` or `none`, `hachureAngle`, `hachureGap`, `strokeWidth`) wraps a `Drawing`, or primitives inside one, and draws shapes as double wobbling strokes with hatched fills; `sketch(sceneOrNode, options)` does it to plain data for `toSVG`. Seeded, so the server and the client draw the same lines; ids, labels, focus rings and events keep working. **Its own entry, client-only** (render `Sketch` from a `'use client'` file), not in the barrel above ([drawing guide](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/drawing.md#sketch)) |
205
207
  | `@nxgt/material/map` | Leaflet maps, markers, a location field — **its own entry, not in the barrel, and browser-only** ([maps guide](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/maps.md)) |
@@ -228,6 +230,7 @@ reads `duotone.svg`, the file that exists (it used to ask for the missing
228
230
  | `@nxgt/material/types` | shared function types (`PromiseOr`, `FunctionOr`, …) |
229
231
  | `@nxgt/material/styles.css` | source Tailwind v4 tokens. **This** is the file the app imports |
230
232
  | `@nxgt/material/map.css` | leaflet's stylesheet, for the apps that use `./map`. Not part of `styles.css` |
233
+ | `@nxgt/material/calculator.css` | the calculator's stylesheet (shaped keys, display, tape, width bands), for `/calculator` and `/calculator-field`. Opt-in, not part of `styles.css`: import it once after `styles.css`; without it the keypad is unstyled |
231
234
  | `@nxgt/material/galleries.css` | the Gallery's shaped tiles (`shape`, `preset="shaped"`): `clip-path: shape()` for twelve shapes, about 9 KB gzipped. Opt-in, not part of `styles.css`; without it a shaped tile keeps a rounded corner |
232
235
  | `@nxgt/material/backgrounds.css` | every background preset's CSS, for the apps that use `./backgrounds`; `@nxgt/material/backgrounds/<preset>.css` loads one (`icons.css` for `preset="icons"`, which pulls in `icons-quiet.css` for `iconMotif.quiet`, also importable alone; `celestial.css` for the sky) (the illustrated scenes share `backgrounds/illustrated.css`). Not part of `styles.css` |
233
236
  | `@nxgt/material/theme-picker.css` | the tiles of `ThemePicker` (the mini backgrounds included), for the apps that use `@nxgt/material/theme-picker`. Import it after `styles.css`. Not part of `styles.css` |
@@ -421,6 +424,37 @@ from `@nxgt/material/print` puts it in a PDF as vectors. The
421
424
  [drawing guide](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/drawing.md)
422
425
  covers colours, accessibility, events, sketch, animation, PNG, PDF and e-mail.
423
426
 
427
+ ### Calculator
428
+
429
+ `@nxgt/material/calculator` is a calculator with exact decimal arithmetic and
430
+ the usual precedence (`2 + 3 × 4` is `14`): a large display with the expression
431
+ above the result, a shaped keypad, a tape of past results to replay and reuse,
432
+ a memory, the physical keyboard, copy and paste and a screen-reader
433
+ announcement of each result. Nothing is evaluated as code. Its own entry,
434
+ server-safe; only Standard is in it, every other variant loads on demand when it
435
+ is first shown (a skeleton and a status while it does).
436
+
437
+ ```tsx
438
+ import { Calculator } from '@nxgt/material/calculator';
439
+
440
+ <Calculator locale="fr" onResult={(value, expression) => save(value, expression)} />
441
+ ```
442
+
443
+ The [calculator guide](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/calculator.md) covers the props, the keyboard,
444
+ the tape and memory, what is stored in `localStorage` and the sizing. The
445
+ Conversion variant takes `currencyRates` (`CalculatorRatesSource`: a
446
+ `CalculatorCurrencyRates` object or a `(signal) => Promise` of one; the library
447
+ fetches nothing). `@nxgt/material/calculator-field` (its own entry) holds `CalculatorField` and `CalculatorFormField`, a number field
448
+ (a currency field with `currency`) whose button opens the calculator, seeded
449
+ with its number, in a popover or a phone's bottom sheet; Apply writes the
450
+ rounded result.
451
+
452
+ ```tsx
453
+ import { CalculatorField } from '@nxgt/material/calculator-field';
454
+
455
+ <CalculatorField label="Price" currency="EUR" value={price} onChange={setPrice} />
456
+ ```
457
+
424
458
  ### Barcodes and label sheets
425
459
 
426
460
  `@nxgt/material/barcode` draws Code 128 and Data Matrix as accessible SVG, with
@@ -463,6 +497,7 @@ Each area a consumer starts from has its own page under `docs/guides/`.
463
497
  | [Charts](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/charts.md) | drawing charts with `@nxgt/material/charts` (client-only): the twelve charts, shared props, legend, View data, `onPointClick`, reference bands, thresholds and point tones on the line chart, zoom and phone scroll, right-to-left pages, keyboard and accessibility, theming the `--chart-*` tokens, and migrating from the Nivo charts, removed in 3.0 |
464
498
  | [Drawing](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/drawing.md) | drawing diagrams, badges and illustrations from code with `@nxgt/material/draw`: a scene or JSX, theme roles and tones, strict CSP, accessibility, events, sketch, animation, PNG, PDF and e-mail |
465
499
  | [Barcodes](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/barcode.md) | Code 128 and Data Matrix with `@nxgt/material/barcode`: props, paper appearance, accessibility, `barcodeGeometry`, `LabelSheet` label sizes, offsets and `skip`, errors and printing |
500
+ | [Calculator](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/calculator.md) | `@nxgt/material/calculator`: props, keyboard, tape and memory, copy and paste, what is stored, feedback, sizing and accessibility |
466
501
  | [Backgrounds](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/backgrounds.md) | tones, intensity, the opt-in `backgrounds.css` and per-preset files, custom tone tokens, motion and CSP |
467
502
  | [Illustrations](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/illustrations.md) | `@nxgt/material/illustrations`: the twelve scenes and the health, education and game sets, icons from your sprites, `EmptyState` / `ErrorState` / `DataTable` with `illustration`, `IllustrationDefaults` for an app, sizes, motion and CSP |
468
503
  | [Icon motifs](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/icon-motifs.md) | icon backgrounds, celestial skies, illustrations and themes together: serving your own Font Awesome sprites (the package ships none), `IconSpritesProvider`, `icons` / `iconStyle` / `iconMotif`, `sky`, the health and education sets, a theme naming its motif, Free fallbacks for Pro-only names |
@@ -680,7 +715,7 @@ Not components: what the stylesheet gives any element.
680
715
  | --- | --- | --- | --- |
681
716
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-table-filter-lists-datatable.webp" width="120" alt="DataTable"> | [`DataTable`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-table-filter-and-lists.md#datatable), `DataTableColumnHeader`, `DataTablePagination`, `DataTableServerFooter`, `DataTableViewOptions` | TanStack Table v9 with sorting, filtering, selection, expandable rows, pagination or load-more, column visibility, skeleton rows while loading and your own empty state — or one server page at a time, with controlled sorting and selection, cursor Previous / Next links and row links. On a phone it keeps its header row and scrolls sideways in a keyboard-reachable region; the page does not. Or cards and tiles instead of the table (`layout`, `renderCard`, `renderTile`), and `layout={{ phone: 'tiles', wide: 'table' }}` for tiles on a phone ([cards and tiles guide](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/guides/cards-and-tiles.md)). Long lists render only the rows in view (`virtual`). | `DataTable`, `DataTableColumnHeader`, `DataTablePagination`, `DataTableServerFooter`, `DataTableViewOptions` |
682
717
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-table-filter-lists-servertable.webp" width="120" alt="ServerTable"> | [`ServerTable`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-table-filter-and-lists.md#servertable), `createSorting`, `tableFilters`, `defineFilterModel`, `parseFilterQuery`, `serializeFilterQuery`, `paramsFromQuery`, `serverPagination`… | A server-mode `DataTable` driven by the URL's search params, for any router: the Filter in its top band with the page's title (optional), description and actions, the sort, forward cursor paging, a selection reset on a new query, the empty page (a scene and an action for "nothing yet", the filters as removable chips), a compact band (`bandDensity`), icon-only Previous / Next (`pageControls`, 44px targets on a touch screen, focus kept while a page loads), actions that stay on the search's row on a phone (`bandActions`), `surface="none"` to sit in a Card with no frame of its own, a bulk bar that reserves no row until a selection, bulk actions with `appliesTo` that count and run only the selected rows they apply to (hidden at zero), an accessible `name`, a `max` rows with a notice, and `focusTrigger()` to give the focus back after a dialog, a `filterRef` to focus the Filter, a page past the last (rows deleted) that says so and links back to the first, an error state with Retry for a failed fetch (`error`, `onRetry`), and one count announced. | `ServerTable`, `createSorting`, `tableFilters`, `serverPagination` |
683
- | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-table-filter-lists-rowmenu.webp" width="120" alt="RowMenu"> | [`RowMenu`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-table-filter-and-lists.md#rowmenu), `RowMenuTrigger`, `rowMenuColumn` | A row's "..." button named after its row ("Actions for Ada"; 44px on touch, 36px with a mouse from `md`), its menu aligned to the end with the destructive item last and 44px items on touch, and a column helper for `DataTable` and `ServerTable` under a hidden but named "Actions" header; focus returns to the button, also from a dialog an item opened; `useRowMenuFocus()` / `focusRowMenu(rowId)` hands it back to one row's button after an async action, a toast or a later dialog. | — |
718
+ | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-table-filter-lists-rowmenu.webp" width="120" alt="RowMenu"> | [`RowMenu`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-table-filter-and-lists.md#rowmenu), `RowMenuTrigger`, `rowMenuColumn` | A row's "..." button named after its row ("Actions for Ada"; 44px on touch, 36px with a mouse from `md`), its menu aligned to the end with the destructive item last and 44px items on touch, and a column helper for `DataTable` and `ServerTable` under a hidden but named "Actions" header; focus returns to the button, also from a dialog an item opened; `useRowMenuFocus()` / `focusRowMenu(rowId)` hands it back to one row's button after an async action, a toast or a later dialog, and `rowFocusProps(rowId)` marks a plain row button the same way. | — |
684
719
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-table-filter-lists-recordactionsmenu.webp" width="120" alt="RecordActionsMenu"> | [`RecordActionsMenu`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-table-filter-and-lists.md#recordactionsmenu), `useRecordActions` | A record's archive, restore and delete menu over `RowMenu`: Archive runs at once with an Undo toast that stays until dismissed, Restore runs at once, Delete permanently (archived records only) always asks and keeps a refusal in its locked dialog; `can` hides what is not allowed (and the whole menu when nothing is), `send` does the action, `onDone` follows it, `items` / `children` add your own entries, `messages` renames the words; `archivePolicy="confirm"` asks before archiving (no Undo), `consequence` notes what an action entails, `successAction` adds a toast action, and `ActionRefusal` / `isActionRefusal` carry a refusal's details and action. | — |
685
720
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-table-filter-lists-listempty.webp" width="120" alt="ListEmpty"> | [`ListEmpty`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-table-filter-and-lists.md#listempty) | A list's empty page: nothing yet (a title, or a scene, a line and an action), or nothing matches with what narrows it and a way out (a button or a link); its title is an `h2` (`headingLevel`). | `ListEmpty` |
686
721
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/data-table-filter-lists-pagefooter.webp" width="120" alt="PageFooter"> | [`PageFooter`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/data-table-filter-and-lists.md#pagefooter) | The page footer of a feed that is not a table (a list of cards, a news feed) under a `FilterBar`: the range ("21–40 of 134") and Previous / Next as real links built from the URL's cursor trail (`pageInfo`, `totalCount`, `params`; `totalCount` is optional: a feed with no total shows no range, only Previous / Next; `hideOnSinglePage` renders nothing when there is no previous and no next page), the same footer `ServerTable` draws, icon-only with `pageControls="icon"` (44px targets on a touch screen); an end with no page is a disabled button, `aria-disabled`. | `PageFooter` |
@@ -716,7 +751,7 @@ Not components: what the stylesheet gives any element.
716
751
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/navigation-layout-toc.webp" width="120" alt="Toc"> | [`Toc`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/navigation-and-layout.md#toc) | On-this-page outline with a per-item active bar. Rail from `xl`, collapsible panel below. `DocToc` composes it. | `Toc` |
717
752
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/navigation-layout-stepper.webp" width="120" alt="Stepper"> | [`Stepper`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/navigation-and-layout.md#stepper), `StepperIndicator` | Clickable horizontal or vertical steps with status and progress (expressive shapes, optional steps, a phone header with Back and Next). | `Stepper` |
718
753
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/navigation-layout-steps.webp" width="120" alt="Steps"> | [`Steps`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/navigation-and-layout.md#steps), `StepsItem` | Numbered editorial steps that stay visible on every breakpoint. | `Steps`, `StepsItem` |
719
- | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/navigation-layout-hero.webp" width="120" alt="Hero"> | [`Hero`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/navigation-and-layout.md#hero) | Landing band with eyebrow, title, supporting copy and actions. | `Hero` |
754
+ | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/navigation-layout-hero.webp" width="120" alt="Hero"> | [`Hero`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/navigation-and-layout.md#hero) | Landing band with eyebrow, title, supporting copy and actions; `size="compact"` is a home-page greeting band, and `background` draws a `Background` behind it. | `Hero`, `HeroBackgroundProps` |
720
755
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/navigation-layout-doc.webp" width="120" alt="Doc"> | [`Doc`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/navigation-and-layout.md#doc), `DocPage`, `DocTopbar`, `DocSidebar`, `DocToc`, `DocPager`, `DocSearch`, `DocChildCards`, `DocSeeAlso`, `DocEmpty`, `DocProgress` | Documentation site shell: sidebar from `md`, TOC rail from `xl`. Reading bar, copy-page / markdown, child cards, see also, and a 404 slot. Storybook `UI/Doc/Api` composes an API page from `DocPage`, `AnchorHeading`, `ApiOperation`, `ParamTable` and `CodeGroup`. | `Doc` (same parts) |
721
756
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/navigation-layout-background.webp" width="120" alt="Background"> | [`Background`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/navigation-and-layout.md#background) | Full-viewport gradient with blurred colour blobs; centres its children; 52 presets on `/backgrounds`, and a `sky` overlay. | `Background` |
722
757
  | — | [`NavigationRail`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/navigation-and-layout.md#navigationrail) | Placeholder: renders an empty rail container and takes no props yet. | `NavigationRail` |
@@ -742,7 +777,7 @@ Not components: what the stylesheet gives any element.
742
777
  | --- | --- | --- | --- |
743
778
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/feedback-status-alert.webp" width="120" alt="Alert"> | [`Alert`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/feedback-and-status.md#alert) | Callout with the tone's icon (or yours, or none with `icon={null}`), title, description and `actions` (buttons or links under the text) in seven tones; it spans the row in a form grid. | `Alert` |
744
779
  | | [`Celebration`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/feedback-and-status.md#celebration) | One-shot confetti burst for a win or a reveal: plays once on mount or when `trigger` changes, never loops, theme-token colours, `aria-hidden`, nothing under reduced motion. | — (later, #2272) |
745
- | | [`Moment`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/feedback-and-status.md#moment) | Full-screen one-off announcement (a player is eliminated, a role revealed): a modal dialog named by its title, focus moved in and restored, dismissed by Escape, a tap, its action or `duration`, tone-coloured, with a fade and pop-in that stop under reduced motion. | — (later) |
780
+ | | [`Moment`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/feedback-and-status.md#moment) | Full-screen one-off announcement (a player is eliminated, a role revealed): a modal dialog named by its title, focus moved in and restored, dismissed by Escape, a tap, its action or `duration`, tone-coloured, with a fade and pop-in that stop under reduced motion; `modal={false}` for a live event keeps focus and lets taps through, announced as a polite status. | — (later) |
746
781
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/feedback-status-stalenotice.webp" width="120" alt="StaleNotice"> | [`StaleNotice`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/feedback-and-status.md#stalenotice) | Warning that another write came first: keeps what was typed, takes the focus and scrolls into view on mount, and offers one "Reload the record" action (`onReload`, `busy`, `message`), never an overwrite. | — (later) |
747
782
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/feedback-status-banner.webp" width="120" alt="Banner"> | [`Banner`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/feedback-and-status.md#banner) | Dismissible info / success / warning / error banner with an action, in the look of `Alert` (light surface, start bar); it spans the row in a form grid. | `Banner` |
748
783
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/feedback-status-alertdialog.webp" width="120" alt="AlertDialog"> | [`AlertDialog`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/feedback-and-status.md#alertdialog), `AlertDialogContent`, `AlertDialogAction`, `AlertDialogCancel`… | Parts for a blocking confirmation dialog. | `AlertDialog` (same parts) |
@@ -810,6 +845,7 @@ Not components: what the stylesheet gives any element.
810
845
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/rich-widgets-quiz.webp" width="120" alt="Quiz"> | [`Quiz`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/rich-widgets.md#quiz), `QuestionCard` · [`QuestionNavigator`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/rich-widgets.md#questionnavigator) | Exam or practice quizzes: step progress, instant feedback with explanations and hints, a time limit, keyboard shortcuts, and a results screen with a score ring, a breakdown and a retry of the misses. Container queries. | `Quiz`, `QuestionCard` (modes and results: React only for now); `QuestionNavigator` React only for now |
811
846
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/rich-widgets-drawing.webp" width="120" alt="Drawing"> | [`Drawing`, `Rect`, `Ellipse`, `Circle`, `Line`, `Polygon`, `Path`, `Text`, `Group`, `Image`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/rich-widgets.md#drawing) from `@nxgt/material/draw` | Vector drawings from a scene of plain data or from JSX: theme-role colours that follow light and dark, no inline style (strict CSP), a `title` or `decorative` enforced by the type, focusable nodes with `onClick` and a focus ring, text that wraps with Inter's metrics and is refined by the browser. Client-only entry. | React only for now |
812
847
  | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/rich-widgets-barcode.webp" width="120" alt="Barcode"> | [`Barcode`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/rich-widgets.md#barcode), `LabelSheet`, `Label`, `barcodeGeometry` | Code 128 and Data Matrix as accessible SVG that follows the theme and prints black on white, and a printed sheet of labels. Its own entry, `@nxgt/material/barcode`, server-safe. | React only for now |
848
+ | <img src="https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/previews/rich-widgets-calculator.webp" width="120" alt="Calculator"> | [`Calculator`](https://cdn.jsdelivr.net/npm/@nxgt/material@3/docs/components/rich-widgets.md#calculator) | Exact decimal calculator with the usual precedence, a shaped keypad, tape, memory, keyboard, copy and paste. Its own entry, `@nxgt/material/calculator`; `CalculatorField` and `CalculatorFormField` are in `@nxgt/material/calculator-field`. | React only for now |
813
849
 
814
850
  `RadioGroupField`, `SliderField` and `SwitchField` are aliases of the
815
851
  labelled `RadioGroup`, `Slider` and `Switch`, under the names
@@ -1,9 +1,10 @@
1
1
  import { r as e } from "./rolldown-runtime-BFFgcFxR.js";
2
2
  import { t } from "./utils-BLfntITJ.js";
3
3
  import { o as n } from "./dist-DVRQkaTK.js";
4
- import { c as r, s as i } from "./dist-lmHmz_bu.js";
5
- import { t as a } from "./in-dialog-Vwkyp-M5.js";
6
- import { a as o, c as s, d as c, i as l, l as u, n as d, o as f, r as p, s as m, t as h, u as g } from "./use-return-focus-DNQtADAR.js";
4
+ import { r } from "./dist-DWZXlCZR.js";
5
+ import { a as i } from "./dist-DHdUUM1w.js";
6
+ import { t as a } from "./in-dialog-D61Yeaol.js";
7
+ import { a as o, c as s, d as c, i as l, l as u, n as d, o as f, r as p, s as m, t as h, u as g } from "./use-return-focus-Cevw_6yq.js";
7
8
  import { i as _ } from "./escape-owner-DpaP0lm1.js";
8
9
  import * as v from "react";
9
10
  import { jsx as y, jsxs as b } from "react/jsx-runtime";
@@ -31,7 +32,7 @@ var x = /* @__PURE__ */ e({
31
32
  }), S = Object.defineProperty, C = (e, t) => S(e, "name", {
32
33
  value: t,
33
34
  configurable: !0
34
- }), [w, T] = r("AlertDialog", [c]), E = c(), D = /* @__PURE__ */ C((e) => {
35
+ }), [w, T] = i("AlertDialog", [c]), E = c(), D = /* @__PURE__ */ C((e) => {
35
36
  let { __scopeAlertDialog: t, ...n } = e;
36
37
  return /* @__PURE__ */ y(p, {
37
38
  ...E(t),
@@ -59,16 +60,16 @@ var x = /* @__PURE__ */ e({
59
60
  ref: t
60
61
  });
61
62
  }, "AlertDialogOverlay")), [j, M] = w("AlertDialogContent"), N = v.forwardRef(/* @__PURE__ */ C(function(e, t) {
62
- let { __scopeAlertDialog: r, children: a, ...s } = e, c = E(r), l = n(t, v.useRef(null)), u = v.useRef(null);
63
+ let { __scopeAlertDialog: i, children: a, ...s } = e, c = E(i), l = n(t, v.useRef(null)), u = v.useRef(null);
63
64
  return /* @__PURE__ */ y(j, {
64
- scope: r,
65
+ scope: i,
65
66
  cancelRef: u,
66
67
  children: /* @__PURE__ */ y(o, {
67
68
  role: "alertdialog",
68
69
  ...c,
69
70
  ...s,
70
71
  ref: l,
71
- onOpenAutoFocus: i(s.onOpenAutoFocus, (e) => {
72
+ onOpenAutoFocus: r(s.onOpenAutoFocus, (e) => {
72
73
  e.preventDefault(), u.current?.focus({ preventScroll: !0 });
73
74
  }),
74
75
  onPointerDownOutside: (e) => e.preventDefault(),
@@ -1,4 +1,4 @@
1
- import { l as e, r as t, s as n, u as r } from "./translator-BoYCward.js";
1
+ import { l as e, r as t, s as n, u as r } from "./translator-DJkf4J7t.js";
2
2
  import { t as i } from "./_baseIsEqual-C6ksIHya.js";
3
3
  import { useMemo as a } from "react";
4
4
  import { asyncThunkCreator as o, buildCreateSlice as s } from "@reduxjs/toolkit";
@@ -1,6 +1,7 @@
1
1
  import { o as e } from "./dist-DVRQkaTK.js";
2
- import { a as t, c as n, i as r, l as i, s as a, t as o } from "./dist-lmHmz_bu.js";
3
- import { i as s, n as c, r as l, t as u } from "./dist-C4wtXCjf.js";
2
+ import { i as t, r as n, t as r } from "./dist-DWZXlCZR.js";
3
+ import { a as i, i as a, t as o } from "./dist-DHdUUM1w.js";
4
+ import { i as s, n as c, r as l, t as u } from "./dist-DOK3zo5C.js";
4
5
  import { t as d } from "./browser-only-DQ94lWF8.js";
5
6
  import * as f from "react";
6
7
  import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
@@ -8,7 +9,7 @@ import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
8
9
  var g = Object.defineProperty, _ = (e, t) => g(e, "name", {
9
10
  value: t,
10
11
  configurable: !0
11
- }), v = "Radio", [y, b] = n(v), [x, S] = y(v);
12
+ }), v = "Radio", [y, b] = i(v), [x, S] = y(v);
12
13
  function C(e) {
13
14
  let { __scopeRadio: t, checked: n = !1, children: r, disabled: i, form: a, name: o, onCheck: s, required: c, value: l = "on", internal_do_not_use_render: u } = e, [d, p] = f.useState(null), [h, g] = f.useState(null), v = f.useRef(!1), [y, b] = f.useReducer((e) => e + 1, 0), S = {
14
15
  checked: n,
@@ -34,9 +35,9 @@ function C(e) {
34
35
  });
35
36
  }
36
37
  _(C, "RadioProvider");
37
- var w = "RadioTrigger", T = /* @__PURE__ */ f.forwardRef(/* @__PURE__ */ _(function({ __scopeRadio: t, onClick: n, ...r }, o) {
38
- let { checked: s, disabled: c, value: l, setControl: u, onCheck: d, hasConsumerStoppedPropagationRef: f, onUserInteraction: p, isFormControl: h, bubbleInput: g } = S(w, t), _ = e(o, u);
39
- return /* @__PURE__ */ m(i.button, {
38
+ var w = "RadioTrigger", T = /* @__PURE__ */ f.forwardRef(/* @__PURE__ */ _(function({ __scopeRadio: r, onClick: i, ...a }, o) {
39
+ let { checked: s, disabled: c, value: l, setControl: u, onCheck: d, hasConsumerStoppedPropagationRef: f, onUserInteraction: p, isFormControl: h, bubbleInput: g } = S(w, r), _ = e(o, u);
40
+ return /* @__PURE__ */ m(t.button, {
40
41
  type: "button",
41
42
  role: "radio",
42
43
  "aria-checked": s,
@@ -44,25 +45,25 @@ var w = "RadioTrigger", T = /* @__PURE__ */ f.forwardRef(/* @__PURE__ */ _(funct
44
45
  "data-disabled": c ? "" : void 0,
45
46
  disabled: c,
46
47
  value: l,
47
- ...r,
48
+ ...a,
48
49
  ref: _,
49
- onClick: a(n, (e) => {
50
+ onClick: n(i, (e) => {
50
51
  s || (p(), d()), g && h && (f.current = e.isPropagationStopped(), f.current || e.stopPropagation());
51
52
  })
52
53
  });
53
- }, "RadioTrigger")), E = "RadioIndicator", D = /* @__PURE__ */ f.forwardRef(/* @__PURE__ */ _(function(e, t) {
54
- let { __scopeRadio: n, forceMount: a, ...o } = e, s = S(E, n);
55
- return /* @__PURE__ */ m(r, {
56
- present: a || s.checked,
57
- children: /* @__PURE__ */ m(i.span, {
54
+ }, "RadioTrigger")), E = "RadioIndicator", D = /* @__PURE__ */ f.forwardRef(/* @__PURE__ */ _(function(e, n) {
55
+ let { __scopeRadio: r, forceMount: i, ...o } = e, s = S(E, r);
56
+ return /* @__PURE__ */ m(a, {
57
+ present: i || s.checked,
58
+ children: /* @__PURE__ */ m(t.span, {
58
59
  "data-state": j(s.checked),
59
60
  "data-disabled": s.disabled ? "" : void 0,
60
61
  ...o,
61
- ref: t
62
+ ref: n
62
63
  })
63
64
  });
64
- }, "RadioIndicator")), O = "RadioBubbleInput", k = /* @__PURE__ */ f.forwardRef(/* @__PURE__ */ _(function({ __scopeRadio: t, onClick: n, ...r }, s) {
65
- let { control: c, checked: l, required: u, disabled: d, name: p, value: h, form: g, bubbleInput: _, setBubbleInput: v, hasConsumerStoppedPropagationRef: y, userInteractionCount: b } = S(O, t), x = e(s, v), C = o(c), w = f.useRef(!1), T = f.useRef(l), E = f.useRef(b);
65
+ }, "RadioIndicator")), O = "RadioBubbleInput", k = /* @__PURE__ */ f.forwardRef(/* @__PURE__ */ _(function({ __scopeRadio: r, onClick: i, ...a }, s) {
66
+ let { control: c, checked: l, required: u, disabled: d, name: p, value: h, form: g, bubbleInput: _, setBubbleInput: v, hasConsumerStoppedPropagationRef: y, userInteractionCount: b } = S(O, r), x = e(s, v), C = o(c), w = f.useRef(!1), T = f.useRef(l), E = f.useRef(b);
66
67
  f.useEffect(() => {
67
68
  let e = _;
68
69
  if (!e) return;
@@ -83,7 +84,7 @@ var w = "RadioTrigger", T = /* @__PURE__ */ f.forwardRef(/* @__PURE__ */ _(funct
83
84
  b
84
85
  ]);
85
86
  let D = f.useRef(l);
86
- return /* @__PURE__ */ m(i.input, {
87
+ return /* @__PURE__ */ m(t.input, {
87
88
  type: "radio",
88
89
  "aria-hidden": !0,
89
90
  defaultChecked: D.current,
@@ -92,14 +93,14 @@ var w = "RadioTrigger", T = /* @__PURE__ */ f.forwardRef(/* @__PURE__ */ _(funct
92
93
  name: p,
93
94
  value: h,
94
95
  form: g,
95
- ...r,
96
+ ...a,
96
97
  tabIndex: -1,
97
98
  ref: x,
98
- onClick: a(n, (e) => {
99
+ onClick: n(i, (e) => {
99
100
  w.current && e.stopPropagation();
100
101
  }),
101
102
  style: {
102
- ...r.style,
103
+ ...a.style,
103
104
  ...C,
104
105
  position: "absolute",
105
106
  pointerEvents: "none",
@@ -122,13 +123,13 @@ var M = [
122
123
  "ArrowDown",
123
124
  "ArrowLeft",
124
125
  "ArrowRight"
125
- ], N = "RadioGroup", [P, F] = n(N, [l, b]), I = l(), L = b(), [R, z] = P(N), B = /* @__PURE__ */ f.forwardRef(/* @__PURE__ */ _(function(n, r) {
126
- let { __scopeRadioGroup: a, name: o, form: l, defaultValue: u, value: d, required: p = !1, disabled: h = !1, orientation: g, dir: v, loop: y = !0, onValueChange: b, ...x } = n, S = I(a), C = s(v), [w, T] = t({
126
+ ], N = "RadioGroup", [P, F] = i(N, [l, b]), I = l(), L = b(), [R, z] = P(N), B = /* @__PURE__ */ f.forwardRef(/* @__PURE__ */ _(function(n, i) {
127
+ let { __scopeRadioGroup: a, name: o, form: l, defaultValue: u, value: d, required: p = !1, disabled: h = !1, orientation: g, dir: v, loop: y = !0, onValueChange: b, ...x } = n, S = I(a), C = s(v), [w, T] = r({
127
128
  prop: d,
128
129
  defaultProp: u ?? null,
129
130
  onChange: b,
130
131
  caller: N
131
- }), [E, D] = f.useState(null), O = e(r, D), k = f.useRef(w);
132
+ }), [E, D] = f.useState(null), O = e(i, D), k = f.useRef(w);
132
133
  return f.useEffect(() => {
133
134
  let e = l ? E?.ownerDocument.getElementById(l) : E?.closest("form");
134
135
  if (e instanceof HTMLFormElement) {
@@ -153,7 +154,7 @@ var M = [
153
154
  orientation: g,
154
155
  dir: C,
155
156
  loop: y,
156
- children: /* @__PURE__ */ m(i.div, {
157
+ children: /* @__PURE__ */ m(t.div, {
157
158
  role: "radiogroup",
158
159
  "aria-required": p,
159
160
  "aria-orientation": g,
@@ -181,8 +182,8 @@ function U(e) {
181
182
  });
182
183
  }
183
184
  _(U, "RadioGroupItemProvider");
184
- var W = /* @__PURE__ */ f.forwardRef(/* @__PURE__ */ _(function(t, n) {
185
- let { __scopeRadioGroup: r, ...i } = t, o = I(r), s = L(r), { checked: c, disabled: l } = S(H, s.__scopeRadio), d = f.useRef(null), p = e(n, d), h = f.useRef(!1);
185
+ var W = /* @__PURE__ */ f.forwardRef(/* @__PURE__ */ _(function(t, r) {
186
+ let { __scopeRadioGroup: i, ...a } = t, o = I(i), s = L(i), { checked: c, disabled: l } = S(H, s.__scopeRadio), d = f.useRef(null), p = e(r, d), h = f.useRef(!1);
186
187
  return f.useEffect(() => {
187
188
  let e = /* @__PURE__ */ _((e) => {
188
189
  M.includes(e.key) && (h.current = !0);
@@ -197,12 +198,12 @@ var W = /* @__PURE__ */ f.forwardRef(/* @__PURE__ */ _(function(t, n) {
197
198
  active: c,
198
199
  children: /* @__PURE__ */ m(T, {
199
200
  ...s,
200
- ...i,
201
+ ...a,
201
202
  ref: p,
202
- onKeyDown: a(i.onKeyDown, (e) => {
203
+ onKeyDown: n(a.onKeyDown, (e) => {
203
204
  e.key === "Enter" && e.preventDefault();
204
205
  }),
205
- onFocus: a(i.onFocus, () => {
206
+ onFocus: n(a.onFocus, () => {
206
207
  h.current && d.current?.click();
207
208
  })
208
209
  })
@@ -1,6 +1,7 @@
1
1
  import { t as e } from "./utils-BLfntITJ.js";
2
2
  import { n as t, t as n } from "./dist-DVRQkaTK.js";
3
- import { n as r, r as i, t as a } from "./spinner-B2MubVWb.js";
3
+ import { n as r, t as i } from "./spinner-C1QIewWv.js";
4
+ import { t as a } from "./dist-DkQbkF9T.js";
4
5
  import { a as o, i as s, n as c, o as l, s as u, t as d } from "./use-click-lock-BZYtTmVt.js";
5
6
  import { t as f } from "./is-production-GLw59WU8.js";
6
7
  import { t as p } from "./button-group-context-CaP0X5p_.js";
@@ -184,7 +185,7 @@ var w = [
184
185
  color: "default",
185
186
  class: `${s.default} ${c.default} hover:bg-foreground/10 active:bg-muted focus:bg-foreground/10`
186
187
  }
187
- ], T = r("nxgt-btn nxgt-morph-fill inline-flex center gap-[var(--btn-gap,0.5rem)] h-min cursor-pointer whitespace-nowrap disabled:pointer-events-none aria-busy:cursor-progress [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-[var(--btn-ic,1rem)] shrink-0 [&_svg]:shrink-0 aria-invalid:[--btn-focus:var(--color-error)] aria-invalid:[--btn-line:var(--color-error)] px-[calc(var(--btn-px,1rem)+var(--btn-dx,0px))] py-2 has-[>svg]:px-[calc(var(--btn-px,1rem)-var(--btn-pxi,0.25rem)+var(--btn-dx,0px))]", {
188
+ ], T = a("nxgt-btn nxgt-morph-fill inline-flex center gap-[var(--btn-gap,0.5rem)] h-min cursor-pointer whitespace-nowrap disabled:pointer-events-none aria-busy:cursor-progress [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-[var(--btn-ic,1rem)] shrink-0 [&_svg]:shrink-0 aria-invalid:[--btn-focus:var(--color-error)] aria-invalid:[--btn-line:var(--color-error)] px-[calc(var(--btn-px,1rem)+var(--btn-dx,0px))] py-2 has-[>svg]:px-[calc(var(--btn-px,1rem)-var(--btn-pxi,0.25rem)+var(--btn-dx,0px))]", {
188
189
  variants: {
189
190
  variant: {
190
191
  filled: "",
@@ -243,7 +244,7 @@ function A(e) {
243
244
  }, [e]);
244
245
  }
245
246
  function j({ spinnerVariant: t, color: n }) {
246
- return /* @__PURE__ */ S(a, {
247
+ return /* @__PURE__ */ S(i, {
247
248
  variant: t,
248
249
  color: n,
249
250
  className: e("starting:scale-0 duration-500", t === "4" ? "size-7.5" : "size-4.5")
@@ -311,7 +312,7 @@ function F({ className: e, variant: r = "filled", asChild: i = !1, children: a,
311
312
  });
312
313
  }
313
314
  function I({ tooltip: e, ...t }) {
314
- return e ? /* @__PURE__ */ S(i, {
315
+ return e ? /* @__PURE__ */ S(r, {
315
316
  content: e,
316
317
  children: /* @__PURE__ */ S(F, { ...t })
317
318
  }) : /* @__PURE__ */ S(F, { ...t });