@nxgt/material 3.94.0 → 3.95.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (391) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +6 -2
  3. package/dist/{alert-dialog-BaqK-rmd.js → alert-dialog-D4r0Kn9h.js} +1 -1
  4. package/dist/{async-slice-BfNpIJAH.js → async-slice-Bx438UlG.js} +1 -1
  5. package/dist/{button-CozGHXAv.js → button-Z_xcg10A.js} +1 -1
  6. package/dist/{calculator-BIx6cwgU.js → calculator-BfIBMiFX.js} +10 -10
  7. package/dist/calculator-field.js +6 -6
  8. package/dist/{calculator-segment-BsaxUtzL.js → calculator-segment-DQE1EFdw.js} +1 -1
  9. package/dist/calculator.js +1 -1
  10. package/dist/charts.js +3 -3
  11. package/dist/{chip-DMEUGYdC.js → chip-Bb9SM3Ly.js} +2 -2
  12. package/dist/{code-editor-BWfky-aN.js → code-editor-Cw-dOrn2.js} +4 -4
  13. package/dist/code-editor.js +4 -4
  14. package/dist/{code-language-items-BUaNYJuw.js → code-language-items-BVfxGKiv.js} +2 -2
  15. package/dist/components/components.css +7 -1
  16. package/dist/components/theme-tokens.css +7 -0
  17. package/dist/components/ui/dates/duration-field/duration-field-expressive.css +2 -63
  18. package/dist/components/ui/dates/picker-trigger/typed-box-expressive.css +30 -21
  19. package/dist/components/ui/fields/number-field/number-field-score.css +151 -0
  20. package/dist/components/ui/fields/quantity-field/quantity-field.css +117 -0
  21. package/dist/components/ui/primitives/field-box/field-box-parts.css +1 -2
  22. package/dist/components/ui/primitives/field-box/field-box-tokens.css +54 -36
  23. package/dist/components/ui/primitives/field-box/field-box.css +44 -86
  24. package/dist/components/ui/primitives/field-box/field-stepper.css +129 -0
  25. package/dist/{components-CZpdAQMh.js → components-DXCfO95n.js} +13787 -13699
  26. package/dist/components.js +26 -27
  27. package/dist/{conversion-variant-aIBhul_U.js → conversion-variant-Ciii9Rbh.js} +4 -4
  28. package/dist/currency-field-DipsI0Bv.js +303 -0
  29. package/dist/{dialog-H40HjqXN.js → dialog-CFuONiW5.js} +3 -3
  30. package/dist/dnd.js +1 -1
  31. package/dist/{dropdown-menu-CawkIlW8.js → dropdown-menu-BvtBDoSD.js} +1 -1
  32. package/dist/editor.js +8 -8
  33. package/dist/{empty-state-sRVjgCis.js → empty-state-n2zb23YG.js} +1 -1
  34. package/dist/{financial-variant-Bqo9-swy.js → financial-variant-CTXTLbE_.js} +7 -7
  35. package/dist/{hooks-BTj_WJm9.js → hooks-zyRsvilJ.js} +2 -2
  36. package/dist/hooks.js +2 -2
  37. package/dist/{hover-card-BZU1DWGY.js → hover-card-BJ15hu7B.js} +1 -1
  38. package/dist/i18n.js +3 -3
  39. package/dist/{icon-badge-CXgvqMsM.js → icon-badge-B2ns44Cz.js} +1 -1
  40. package/dist/{icon-button-B9WjQ3RO.js → icon-button-BG438okX.js} +1 -1
  41. package/dist/lib/components/ui/fields/contacts/placeholders.d.ts +1 -1
  42. package/dist/lib/components/ui/fields/number-field/number-control.d.ts +10 -3
  43. package/dist/lib/components/ui/fields/number-field/number-field-base.d.ts +2 -0
  44. package/dist/lib/components/ui/fields/number-field/number-field.d.ts +7 -1
  45. package/dist/lib/components/ui/fields/number-field/number-field.types.d.ts +13 -0
  46. package/dist/lib/components/ui/fields/number-field/number-score-control.d.ts +19 -0
  47. package/dist/lib/components/ui/fields/number-field/number-stepper.d.ts +16 -2
  48. package/dist/lib/components/ui/fields/quantity-field/quantity-field.d.ts +4 -3
  49. package/dist/lib/components/ui/fields/quantity-field/quantity-row.d.ts +5 -9
  50. package/dist/lib/components/ui/fields/quantity-field/quantity-unit-menu.d.ts +19 -0
  51. package/dist/lib/components/ui/fields/quantity-field/quantity-unit.d.ts +11 -4
  52. package/dist/lib/components/ui/fields/quantity-field/use-unit-chip-name.d.ts +14 -0
  53. package/dist/lib/components/ui/fields/switch/partials/switch-row.d.ts +2 -2
  54. package/dist/lib/components/ui/fields/switch/switch.d.ts +2 -2
  55. package/dist/lib/components/ui/fields/text-field/text-field-units.d.ts +24 -0
  56. package/dist/lib/components/ui/fields/text-field/text-field.d.ts +9 -0
  57. package/dist/lib/components/ui/fields/verification-code/partials/code-surface.d.ts +13 -6
  58. package/dist/lib/components/ui/fields/verification-code/partials/recovery-input.d.ts +1 -1
  59. package/dist/lib/components/ui/layout/app-shell/app-sidebar-group.d.ts +12 -0
  60. package/dist/lib/components/ui/layout/app-shell/types.d.ts +7 -0
  61. package/dist/lib/components/ui/primitives/input-group/input-group.d.ts +1 -1
  62. package/dist/lib/i18n/resources/en/en.d.ts +5 -0
  63. package/dist/lib/i18n/resources/en/material.json.d.ts +7 -2
  64. package/dist/lib/i18n/resources/fr/fr.d.ts +5 -0
  65. package/dist/lib/i18n/resources/fr/material.json.d.ts +7 -2
  66. package/dist/lib/i18n/resources/resources.d.ts +10 -0
  67. package/dist/lib/i18n/translator.d.ts +1 -1
  68. package/dist/lib.js +1 -1
  69. package/dist/main.js +32 -33
  70. package/dist/map.js +8 -8
  71. package/dist/material.css +1 -1
  72. package/dist/pdf-reader.js +1 -1
  73. package/dist/percent-field-Cjc_3pP0.js +137 -0
  74. package/dist/{picker-surface-D2aYI4v7.js → picker-surface-Cr2n42qv.js} +4 -4
  75. package/dist/{popover-QQYPWzw6.js → popover-XBAX2Shp.js} +1 -1
  76. package/dist/{pos-types-BIeZGGAs.js → pos-types-BFVWeJki.js} +1 -1
  77. package/dist/{pos-variant-Cdn1AVoA.js → pos-variant-DWB8Bc12.js} +4 -4
  78. package/dist/print.js +1 -1
  79. package/dist/{programmer-variant-CMBybkqw.js → programmer-variant-B-wPnDeX.js} +2 -2
  80. package/dist/{public-CPxFxbi4.js → public-D1bH-KPQ.js} +9 -9
  81. package/dist/{rich-code-block-DKJ8eKzL.js → rich-code-block-DP2RT7pV.js} +5 -5
  82. package/dist/{scientific-variant-CXL1ayb7.js → scientific-variant-BP08Mo0g.js} +2 -2
  83. package/dist/{sortable-provider-BYqwwyr1.js → sortable-provider-CHGZrS0f.js} +2 -2
  84. package/dist/{spinner-D7ol2n_-.js → spinner-rk8J5y9O.js} +1 -1
  85. package/dist/styles.css +2 -0
  86. package/dist/{tabs-DyiFTy5g.js → tabs-nuYLggwC.js} +1 -1
  87. package/dist/text-field-DOndWDT5.js +169 -0
  88. package/dist/theme-picker.js +2 -2
  89. package/dist/{theme-toggle-QZ0bIrg9.js → theme-toggle-5waw9Wk8.js} +1 -1
  90. package/dist/{toolbar-items-BpOEBsSt.js → toolbar-items-Bo-nMzKJ.js} +4 -4
  91. package/dist/{translate-material-DlMetRSJ.js → translate-material-H5GMStyF.js} +1 -1
  92. package/dist/{translator-VtzVrnLm.js → translator-gdpQeToI.js} +14 -4
  93. package/dist/{use-chat-composer-DQ2rTD_q.js → use-chat-composer-DEd6GM2N.js} +23 -24
  94. package/dist/{use-heading-spy-17B5xa7B.js → use-heading-spy-n_wPa5jC.js} +4 -4
  95. package/dist/{use-material-translation-Cx5u36V5.js → use-material-translation-BW5HZMwt.js} +1 -1
  96. package/dist/{use-return-focus-S7g7q_Yn.js → use-return-focus-BC4sGh1b.js} +1 -1
  97. package/docs/README.md +1 -0
  98. package/docs/components/date-and-time.md +25 -23
  99. package/docs/components/form-fields.md +80 -26
  100. package/docs/components/navigation-and-layout.md +1 -1
  101. package/docs/guides/app-shell.md +15 -0
  102. package/docs/guides/field-look-2-x.md +10 -4
  103. package/docs/guides/field-look-refined.md +130 -0
  104. package/docs/guides/layouts.md +2 -1
  105. package/docs/guides/theming.md +39 -31
  106. package/docs/previews/backgrounds-icons-quiet-band.webp +0 -0
  107. package/docs/previews/backgrounds-icons.webp +0 -0
  108. package/docs/previews/backgrounds-matrix.webp +0 -0
  109. package/docs/previews/buttons-actions-actioncard.webp +0 -0
  110. package/docs/previews/buttons-actions-backlink.webp +0 -0
  111. package/docs/previews/buttons-actions-button.webp +0 -0
  112. package/docs/previews/buttons-actions-buttongroup.webp +0 -0
  113. package/docs/previews/buttons-actions-fab.webp +0 -0
  114. package/docs/previews/buttons-actions-fabmenu.webp +0 -0
  115. package/docs/previews/buttons-actions-iconbutton.webp +0 -0
  116. package/docs/previews/buttons-actions-languageswitcher.webp +0 -0
  117. package/docs/previews/buttons-actions-linkbutton.webp +0 -0
  118. package/docs/previews/buttons-actions-loadmorebutton.webp +0 -0
  119. package/docs/previews/buttons-actions-loadmorefooter.webp +0 -0
  120. package/docs/previews/buttons-actions-responsivebutton.webp +0 -0
  121. package/docs/previews/buttons-actions-scrolltolatestbutton.webp +0 -0
  122. package/docs/previews/buttons-actions-scrolltotop.webp +0 -0
  123. package/docs/previews/buttons-actions-splitbutton.webp +0 -0
  124. package/docs/previews/buttons-actions-themetoggle.webp +0 -0
  125. package/docs/previews/buttons-actions-toolbar-density-and-keyboard.webp +0 -0
  126. package/docs/previews/buttons-actions-toolbar.webp +0 -0
  127. package/docs/previews/data-display-accordioncard.webp +0 -0
  128. package/docs/previews/data-display-apiendpoint.webp +0 -0
  129. package/docs/previews/data-display-apioperation.webp +0 -0
  130. package/docs/previews/data-display-avatar.webp +0 -0
  131. package/docs/previews/data-display-badge.webp +0 -0
  132. package/docs/previews/data-display-card-presets.webp +0 -0
  133. package/docs/previews/data-display-changehistory.webp +0 -0
  134. package/docs/previews/data-display-chip.webp +0 -0
  135. package/docs/previews/data-display-codegroup.webp +0 -0
  136. package/docs/previews/data-display-description.webp +0 -0
  137. package/docs/previews/data-display-enrolmentcard.webp +0 -0
  138. package/docs/previews/data-display-enrolmentsecret.webp +0 -0
  139. package/docs/previews/data-display-metric-cards.webp +0 -0
  140. package/docs/previews/data-display-periodcards.webp +0 -0
  141. package/docs/previews/data-display-recoverycodes.webp +0 -0
  142. package/docs/previews/data-display-recoverycodesstatus.webp +0 -0
  143. package/docs/previews/data-display-secretcard.webp +0 -0
  144. package/docs/previews/data-display-terminal.webp +0 -0
  145. package/docs/previews/data-display-timeline.webp +0 -0
  146. package/docs/previews/data-display-tonevalue.webp +0 -0
  147. package/docs/previews/data-display-votetally.webp +0 -0
  148. package/docs/previews/data-table-filter-lists-datagrid.webp +0 -0
  149. package/docs/previews/data-table-filter-lists-datatable.webp +0 -0
  150. package/docs/previews/data-table-filter-lists-daygroupedlist.webp +0 -0
  151. package/docs/previews/data-table-filter-lists-drag-and-drop.webp +0 -0
  152. package/docs/previews/data-table-filter-lists-facetgroup.webp +0 -0
  153. package/docs/previews/data-table-filter-lists-filter.webp +0 -0
  154. package/docs/previews/data-table-filter-lists-listempty.webp +0 -0
  155. package/docs/previews/data-table-filter-lists-listpane.webp +0 -0
  156. package/docs/previews/data-table-filter-lists-markinglist.webp +0 -0
  157. package/docs/previews/data-table-filter-lists-pagination.webp +0 -0
  158. package/docs/previews/data-table-filter-lists-servertable.webp +0 -0
  159. package/docs/previews/data-table-filter-lists-tree.webp +0 -0
  160. package/docs/previews/date-time-agefield.webp +0 -0
  161. package/docs/previews/date-time-calendar-expressive.webp +0 -0
  162. package/docs/previews/date-time-calendar.webp +0 -0
  163. package/docs/previews/date-time-datefield.webp +0 -0
  164. package/docs/previews/date-time-daterangefield.webp +0 -0
  165. package/docs/previews/date-time-durationfield.webp +0 -0
  166. package/docs/previews/date-time-fields-expressive.webp +0 -0
  167. package/docs/previews/date-time-halfdayrangefield.webp +0 -0
  168. package/docs/previews/date-time-nowindicator.webp +0 -0
  169. package/docs/previews/date-time-timefield.webp +0 -0
  170. package/docs/previews/date-time-timepicker-tiles.webp +0 -0
  171. package/docs/previews/date-time-timepicker.webp +0 -0
  172. package/docs/previews/feedback-status-alert.webp +0 -0
  173. package/docs/previews/feedback-status-alertdialog.webp +0 -0
  174. package/docs/previews/feedback-status-celebration.webp +0 -0
  175. package/docs/previews/feedback-status-circularprogress.webp +0 -0
  176. package/docs/previews/feedback-status-confirmationdialog.webp +0 -0
  177. package/docs/previews/feedback-status-confirmdialog.webp +0 -0
  178. package/docs/previews/feedback-status-countdowntimer.webp +0 -0
  179. package/docs/previews/feedback-status-customalertdialog.webp +0 -0
  180. package/docs/previews/feedback-status-customdialog.webp +0 -0
  181. package/docs/previews/feedback-status-emptystate.webp +0 -0
  182. package/docs/previews/feedback-status-errorstate.webp +0 -0
  183. package/docs/previews/feedback-status-hydrateloading.webp +0 -0
  184. package/docs/previews/feedback-status-illustration-education.webp +0 -0
  185. package/docs/previews/feedback-status-illustration-game.webp +0 -0
  186. package/docs/previews/feedback-status-illustration-health.webp +0 -0
  187. package/docs/previews/feedback-status-illustration.webp +0 -0
  188. package/docs/previews/feedback-status-notificationrow.webp +0 -0
  189. package/docs/previews/feedback-status-notifications.webp +0 -0
  190. package/docs/previews/feedback-status-pageloadfailed.webp +0 -0
  191. package/docs/previews/feedback-status-progress.webp +0 -0
  192. package/docs/previews/feedback-status-skeleton.webp +0 -0
  193. package/docs/previews/feedback-status-spinner.webp +0 -0
  194. package/docs/previews/feedback-status-stalenotice.webp +0 -0
  195. package/docs/previews/feedback-status-stepupdialog-retry.webp +0 -0
  196. package/docs/previews/feedback-status-stepupdialog.webp +0 -0
  197. package/docs/previews/feedback-status-toast.webp +0 -0
  198. package/docs/previews/feedback-status-typingindicator.webp +0 -0
  199. package/docs/previews/feedback-status-unsaveddialog.webp +0 -0
  200. package/docs/previews/form-fields-attributes.webp +0 -0
  201. package/docs/previews/form-fields-choicelistfield.webp +0 -0
  202. package/docs/previews/form-fields-colorfield.webp +0 -0
  203. package/docs/previews/form-fields-contacts.webp +0 -0
  204. package/docs/previews/form-fields-countryfield.webp +0 -0
  205. package/docs/previews/form-fields-currencyfield.webp +0 -0
  206. package/docs/previews/form-fields-emailfield.webp +0 -0
  207. package/docs/previews/form-fields-field.webp +0 -0
  208. package/docs/previews/form-fields-formsection.webp +0 -0
  209. package/docs/previews/form-fields-inlineedit.webp +0 -0
  210. package/docs/previews/form-fields-inputgroupfield.webp +0 -0
  211. package/docs/previews/form-fields-localizedtextfields.webp +0 -0
  212. package/docs/previews/form-fields-markdowntextareafield.webp +0 -0
  213. package/docs/previews/form-fields-numberfield.webp +0 -0
  214. package/docs/previews/form-fields-openinghours.webp +0 -0
  215. package/docs/previews/form-fields-otpfield.webp +0 -0
  216. package/docs/previews/form-fields-passwordfield.webp +0 -0
  217. package/docs/previews/form-fields-percentfield.webp +0 -0
  218. package/docs/previews/form-fields-phonefield.webp +0 -0
  219. package/docs/previews/form-fields-postaladdress.webp +0 -0
  220. package/docs/previews/form-fields-repeatablegroup.webp +0 -0
  221. package/docs/previews/form-fields-searchfield.webp +0 -0
  222. package/docs/previews/form-fields-slider.webp +0 -0
  223. package/docs/previews/form-fields-switch.webp +0 -0
  224. package/docs/previews/form-fields-textareafield.webp +0 -0
  225. package/docs/previews/form-fields-textfield.webp +0 -0
  226. package/docs/previews/form-fields-timezonefield.webp +0 -0
  227. package/docs/previews/form-fields-urlfield.webp +0 -0
  228. package/docs/previews/form-fields-verificationcode.webp +0 -0
  229. package/docs/previews/foundations-themes-gallery.webp +0 -0
  230. package/docs/previews/foundations-themes-icon-motifs.webp +0 -0
  231. package/docs/previews/foundations-themes-nesting.webp +0 -0
  232. package/docs/previews/foundations-themes-provider.webp +0 -0
  233. package/docs/previews/foundations-themes-themepicker.webp +0 -0
  234. package/docs/previews/guides-i18n-i18nprovider.webp +0 -0
  235. package/docs/previews/guides-i18n-translated-components.webp +0 -0
  236. package/docs/previews/media-files-audioplayer.webp +0 -0
  237. package/docs/previews/media-files-camera.webp +0 -0
  238. package/docs/previews/media-files-carousel.webp +0 -0
  239. package/docs/previews/media-files-filelist.webp +0 -0
  240. package/docs/previews/media-files-filelistfield.webp +0 -0
  241. package/docs/previews/media-files-filepreview.webp +0 -0
  242. package/docs/previews/media-files-gallery-image-lists.webp +0 -0
  243. package/docs/previews/media-files-gallery-video.webp +0 -0
  244. package/docs/previews/media-files-gallery-viewer.webp +0 -0
  245. package/docs/previews/media-files-gallery.webp +0 -0
  246. package/docs/previews/media-files-imagecropper.webp +0 -0
  247. package/docs/previews/media-files-imageeditor.webp +0 -0
  248. package/docs/previews/media-files-imagefield.webp +0 -0
  249. package/docs/previews/media-files-lightboxgallery.webp +0 -0
  250. package/docs/previews/media-files-map.webp +0 -0
  251. package/docs/previews/media-files-mediaplayer.webp +0 -0
  252. package/docs/previews/media-files-mediaplayerhost.webp +0 -0
  253. package/docs/previews/media-files-mediaplayerlightbox.webp +0 -0
  254. package/docs/previews/media-files-mediaplayermini.webp +0 -0
  255. package/docs/previews/media-files-minigallery.webp +0 -0
  256. package/docs/previews/media-files-pdfreader.webp +0 -0
  257. package/docs/previews/media-files-uploadfield.webp +0 -0
  258. package/docs/previews/navigation-layout-appshell-blue-moon.webp +0 -0
  259. package/docs/previews/navigation-layout-appshell-footer-icon.webp +0 -0
  260. package/docs/previews/navigation-layout-appshell-menu-badge.webp +0 -0
  261. package/docs/previews/navigation-layout-appshell-page-ground.webp +0 -0
  262. package/docs/previews/navigation-layout-appshell-themes.webp +0 -0
  263. package/docs/previews/navigation-layout-appshell.webp +0 -0
  264. package/docs/previews/navigation-layout-authcard-split.webp +0 -0
  265. package/docs/previews/navigation-layout-authcard.webp +0 -0
  266. package/docs/previews/navigation-layout-background.webp +0 -0
  267. package/docs/previews/navigation-layout-breadcrumb.webp +0 -0
  268. package/docs/previews/navigation-layout-doc-api.webp +0 -0
  269. package/docs/previews/navigation-layout-doc-blocks.webp +0 -0
  270. package/docs/previews/navigation-layout-doc.webp +0 -0
  271. package/docs/previews/navigation-layout-editorlayout.webp +0 -0
  272. package/docs/previews/navigation-layout-hero.webp +0 -0
  273. package/docs/previews/navigation-layout-landinglayout.webp +0 -0
  274. package/docs/previews/navigation-layout-listdetailslayout.webp +0 -0
  275. package/docs/previews/navigation-layout-pager.webp +0 -0
  276. package/docs/previews/navigation-layout-recordpage.webp +0 -0
  277. package/docs/previews/navigation-layout-settingslayout.webp +0 -0
  278. package/docs/previews/navigation-layout-sidebar.webp +0 -0
  279. package/docs/previews/navigation-layout-steps.webp +0 -0
  280. package/docs/previews/navigation-layout-stickyactionbar.webp +0 -0
  281. package/docs/previews/navigation-layout-threadlayout-pages.webp +0 -0
  282. package/docs/previews/navigation-layout-toc.webp +0 -0
  283. package/docs/previews/overlays-menus-contextmenu.webp +0 -0
  284. package/docs/previews/overlays-menus-dialog.webp +0 -0
  285. package/docs/previews/overlays-menus-drawer.webp +0 -0
  286. package/docs/previews/overlays-menus-dropdownmenu.webp +0 -0
  287. package/docs/previews/overlays-menus-hovercard.webp +0 -0
  288. package/docs/previews/overlays-menus-popover.webp +0 -0
  289. package/docs/previews/overlays-menus-sheet.webp +0 -0
  290. package/docs/previews/overlays-menus-tooltip.webp +0 -0
  291. package/docs/previews/primitives-accordion.webp +0 -0
  292. package/docs/previews/primitives-card.webp +0 -0
  293. package/docs/previews/primitives-collapsible.webp +0 -0
  294. package/docs/previews/primitives-extendedlabel.webp +0 -0
  295. package/docs/previews/primitives-helpertext.webp +0 -0
  296. package/docs/previews/primitives-input.webp +0 -0
  297. package/docs/previews/primitives-inputgroup.webp +0 -0
  298. package/docs/previews/primitives-label.webp +0 -0
  299. package/docs/previews/primitives-scrollarea.webp +0 -0
  300. package/docs/previews/primitives-segmentednav.webp +0 -0
  301. package/docs/previews/primitives-tabs.webp +0 -0
  302. package/docs/previews/primitives-tabsnav.webp +0 -0
  303. package/docs/previews/primitives-textarea.webp +0 -0
  304. package/docs/previews/primitives-toggle.webp +0 -0
  305. package/docs/previews/primitives-togglegroup.webp +0 -0
  306. package/docs/previews/primitives-typography.webp +0 -0
  307. package/docs/previews/rich-widgets-calculator-conversion.webp +0 -0
  308. package/docs/previews/rich-widgets-chat-action-proposal.webp +0 -0
  309. package/docs/previews/rich-widgets-chat-advanced.webp +0 -0
  310. package/docs/previews/rich-widgets-chat-composer.webp +0 -0
  311. package/docs/previews/rich-widgets-chat-inbox.webp +0 -0
  312. package/docs/previews/rich-widgets-chat-overview.webp +0 -0
  313. package/docs/previews/rich-widgets-chat-thread.webp +0 -0
  314. package/docs/previews/rich-widgets-chat-widget.webp +0 -0
  315. package/docs/previews/rich-widgets-codeeditor.webp +0 -0
  316. package/docs/previews/rich-widgets-compacteditor.webp +0 -0
  317. package/docs/previews/rich-widgets-documenteditor.webp +0 -0
  318. package/docs/previews/rich-widgets-drawing.webp +0 -0
  319. package/docs/previews/rich-widgets-emojipicker.webp +0 -0
  320. package/docs/previews/rich-widgets-eventcalendar.webp +0 -0
  321. package/docs/previews/rich-widgets-kanban-phone-layout.webp +0 -0
  322. package/docs/previews/rich-widgets-kanban.webp +0 -0
  323. package/docs/previews/rich-widgets-mentionlist.webp +0 -0
  324. package/docs/previews/rich-widgets-native-charts-areachart.webp +0 -0
  325. package/docs/previews/rich-widgets-native-charts-barchart.webp +0 -0
  326. package/docs/previews/rich-widgets-native-charts-combochart.webp +0 -0
  327. package/docs/previews/rich-widgets-native-charts-donutchart.webp +0 -0
  328. package/docs/previews/rich-widgets-native-charts-funnelchart.webp +0 -0
  329. package/docs/previews/rich-widgets-native-charts-heatmapchart.webp +0 -0
  330. package/docs/previews/rich-widgets-native-charts-linechart-reference.webp +0 -0
  331. package/docs/previews/rich-widgets-native-charts-linechart.webp +0 -0
  332. package/docs/previews/rich-widgets-native-charts-palette.webp +0 -0
  333. package/docs/previews/rich-widgets-native-charts-piechart.webp +0 -0
  334. package/docs/previews/rich-widgets-native-charts-radarchart.webp +0 -0
  335. package/docs/previews/rich-widgets-native-charts-radialbarchart.webp +0 -0
  336. package/docs/previews/rich-widgets-native-charts-scatterchart.webp +0 -0
  337. package/docs/previews/rich-widgets-questioncard-rich-content.webp +0 -0
  338. package/docs/previews/rich-widgets-questionmediaview.webp +0 -0
  339. package/docs/previews/rich-widgets-questionnavigator.webp +0 -0
  340. package/docs/previews/rich-widgets-quiz.webp +0 -0
  341. package/docs/previews/rich-widgets-richchatcomposer.webp +0 -0
  342. package/docs/previews/rich-widgets-richtexteditor.webp +0 -0
  343. package/docs/previews/rich-widgets-richtextviewer.webp +0 -0
  344. package/docs/previews/selection-choice-autocomplete.webp +0 -0
  345. package/docs/previews/selection-choice-checkbox.webp +0 -0
  346. package/docs/previews/selection-choice-checkboxgroup.webp +0 -0
  347. package/docs/previews/selection-choice-checkcardfield.webp +0 -0
  348. package/docs/previews/selection-choice-chipgroupfield.webp +0 -0
  349. package/docs/previews/selection-choice-choicecardgroup.webp +0 -0
  350. package/docs/previews/selection-choice-combobox.webp +0 -0
  351. package/docs/previews/selection-choice-comboboxfield.webp +0 -0
  352. package/docs/previews/selection-choice-optiontile.webp +0 -0
  353. package/docs/previews/selection-choice-radiogroup.webp +0 -0
  354. package/docs/previews/selection-choice-select.webp +0 -0
  355. package/docs/previews/selection-choice-selectfield.webp +0 -0
  356. package/docs/previews/selection-choice-sortablelist.webp +0 -0
  357. package/docs/previews/selection-choice-switcher.webp +0 -0
  358. package/docs/previews/selection-choice-transferlist.webp +0 -0
  359. package/docs/previews/selection-choice-treeselectfield.webp +0 -0
  360. package/docs/roadmap.md +13 -10
  361. package/docs/troubleshooting.md +44 -0
  362. package/lib/components/components.css +7 -1
  363. package/lib/components/theme-tokens.css +7 -0
  364. package/lib/components/ui/dates/duration-field/duration-field-expressive.css +2 -63
  365. package/lib/components/ui/dates/picker-trigger/typed-box-expressive.css +30 -21
  366. package/lib/components/ui/fields/number-field/number-field-score.css +151 -0
  367. package/lib/components/ui/fields/quantity-field/quantity-field.css +117 -0
  368. package/lib/components/ui/primitives/field-box/field-box-parts.css +1 -2
  369. package/lib/components/ui/primitives/field-box/field-box-tokens.css +54 -36
  370. package/lib/components/ui/primitives/field-box/field-box.css +44 -86
  371. package/lib/components/ui/primitives/field-box/field-stepper.css +129 -0
  372. package/lib/styles.css +2 -0
  373. package/lib/themes/ambre.css +5 -1
  374. package/lib/themes/ardoise.css +5 -1
  375. package/lib/themes/bleumono.css +5 -1
  376. package/lib/themes/bluemoon.css +5 -1
  377. package/lib/themes/corail.css +5 -1
  378. package/lib/themes/foret.css +5 -1
  379. package/lib/themes/lavande.css +5 -1
  380. package/lib/themes/menthe.css +5 -1
  381. package/lib/themes/ocean.css +5 -1
  382. package/lib/themes/pink.css +5 -1
  383. package/lib/themes/prune.css +5 -1
  384. package/lib/themes/sable.css +5 -1
  385. package/lib/themes/slate.css +5 -1
  386. package/lib/themes/teal.css +5 -1
  387. package/package.json +2 -2
  388. package/dist/currency-field-IcEMAcAw.js +0 -289
  389. package/dist/input-group-Df9vp2EZ.js +0 -70
  390. package/dist/percent-field-DrI4_J7x.js +0 -14
  391. package/dist/text-field-BAdY-kpO.js +0 -59
@@ -4,28 +4,28 @@ import { t as n } from "./utils-BLfntITJ.js";
4
4
  import { n as r } from "./use-shape-morph-BKA_R5P5.js";
5
5
  import { n as i, o as a, t as o } from "./dist-DVRQkaTK.js";
6
6
  import { i as s, n as c, r as l, t as u } from "./dist-DWZXlCZR.js";
7
- import { _ as d, a as f, b as p, g as m, h, i as g, m as _, n as v, o as y, r as b, s as x, t as S, v as C, y as w } from "./spinner-D7ol2n_-.js";
7
+ import { _ as d, a as f, b as p, g as m, h, i as g, m as _, n as v, o as y, r as b, s as x, t as S, v as C, y as w } from "./spinner-rk8J5y9O.js";
8
8
  import { a as T, i as E, n as D, r as O, t as k } from "./dist-DHdUUM1w.js";
9
9
  import { a as A, i as ee } from "./dist-DOK3zo5C.js";
10
10
  import { i as j, n as M } from "./in-dialog-D61Yeaol.js";
11
- import { c as N, l as P, n as te, r as F, t as ne } from "./alert-dialog-BaqK-rmd.js";
11
+ import { c as N, l as P, n as te, r as F, t as ne } from "./alert-dialog-D4r0Kn9h.js";
12
12
  import { A as re, C as ie, D as ae, E as oe, O as se, S as I, T as ce, _ as le, a as ue, b as de, d as fe, f as pe, g as me, h as he, i as ge, k as _e, l as ve, m as ye, n as be, o as xe, p as Se, r as Ce, s as we, t as Te, u as Ee, v as De, w as Oe, x as ke, y as Ae } from "./floating-ui.dom-KkZSW8_E.js";
13
- import { D as je, E as Me, N as Ne, O as Pe, c as Fe, d as Ie, f as Le, i as Re, k as ze, m as Be, n as Ve, o as He, p as Ue, t as We, u as Ge } from "./dropdown-menu-CawkIlW8.js";
13
+ import { D as je, E as Me, N as Ne, O as Pe, c as Fe, d as Ie, f as Le, i as Re, k as ze, m as Be, n as Ve, o as He, p as Ue, t as We, u as Ge } from "./dropdown-menu-BvtBDoSD.js";
14
14
  import { a as Ke, i as qe, n as Je } from "./field-blur-context-BLGgf_3z.js";
15
- import { i as Ye, n as Xe, r as Ze, t as Qe } from "./popover-QQYPWzw6.js";
15
+ import { i as Ye, n as Xe, r as Ze, t as Qe } from "./popover-XBAX2Shp.js";
16
16
  import { a as $e, i as et, n as tt, o as nt, t as rt } from "./bubble-input-CQwVSoU3.js";
17
- import { d as it, n as at, r as ot, t as st } from "./tabs-DyiFTy5g.js";
18
- import { a as ct, n as lt, o as ut, s as dt, v as ft, y as pt } from "./toolbar-items-BpOEBsSt.js";
17
+ import { d as it, n as at, r as ot, t as st } from "./tabs-nuYLggwC.js";
18
+ import { a as ct, n as lt, o as ut, s as dt, v as ft, y as pt } from "./toolbar-items-Bo-nMzKJ.js";
19
19
  import { t as mt } from "./dist-DkQbkF9T.js";
20
20
  import { o as ht, s as gt, t as _t } from "./use-click-lock-Bwg_caHO.js";
21
21
  import { a as vt, r as yt } from "./icon-sprites-CaYXzOL4.js";
22
22
  import { t as bt } from "./warn-once-C_e47JM8.js";
23
- import { r as xt, t as St } from "./button-CozGHXAv.js";
24
- import { a as Ct } from "./translator-VtzVrnLm.js";
23
+ import { r as xt, t as St } from "./button-Z_xcg10A.js";
24
+ import { a as Ct } from "./translator-gdpQeToI.js";
25
25
  import { h as wt } from "./get-CTzJAwfc.js";
26
26
  import { t as Tt } from "./isEmpty-F_g3jLf8.js";
27
- import { t as L } from "./use-material-translation-Cx5u36V5.js";
28
- import { t as R } from "./icon-button-B9WjQ3RO.js";
27
+ import { t as L } from "./use-material-translation-BW5HZMwt.js";
28
+ import { t as R } from "./icon-button-BG438okX.js";
29
29
  import { t as Et } from "./use-ssr-media-query-C6M5m8sf.js";
30
30
  import { n as Dt, t as Ot } from "./typography-CYEquVeb.js";
31
31
  import { n as kt, t as At } from "./util-4heV2LPI.js";
@@ -36,15 +36,14 @@ import { a as Bt } from "./toggle-group-CVMxEpWi.js";
36
36
  import { n as Vt } from "./use-slice-reducer-BGkeGtML.js";
37
37
  import { t as Ht } from "./browser-only-DQ94lWF8.js";
38
38
  import { t as Ut } from "./compose-refs-G4J4kaUA.js";
39
- import { n as Wt, r as Gt, t as Kt } from "./chip-DMEUGYdC.js";
39
+ import { n as Wt, r as Gt, t as Kt } from "./chip-Bb9SM3Ly.js";
40
40
  import { c as qt, o as Jt, r as Yt, s as Xt, t as Zt } from "./input-CC2joTjB.js";
41
- import { i as Qt, n as $t, t as en } from "./input-group-Df9vp2EZ.js";
42
- import { t as tn } from "./text-field-BAdY-kpO.js";
41
+ import { a as Qt, n as $t, r as en, t as tn } from "./text-field-DOndWDT5.js";
43
42
  import { r as nn } from "./use-csp-nonce-ZKs9k-ov.js";
44
- import { t as rn } from "./empty-state-sRVjgCis.js";
43
+ import { t as rn } from "./empty-state-n2zb23YG.js";
45
44
  import { t as an } from "./skeleton-DSdtr2qc.js";
46
- import { l as on, n as sn, o as cn, r as ln, s as un, t as dn, u as fn } from "./dialog-H40HjqXN.js";
47
- import { t as pn } from "./icon-badge-CXgvqMsM.js";
45
+ import { l as on, n as sn, o as cn, r as ln, s as un, t as dn, u as fn } from "./dialog-CFuONiW5.js";
46
+ import { t as pn } from "./icon-badge-B2ns44Cz.js";
48
47
  import { H as mn, V as hn, X as gn, bt as _n, it as vn, lt as yn, n as bn, t as xn, xt as Sn, yt as Cn } from "./dist-moutbfbd.js";
49
48
  import { t as wn } from "./markdown-Dw_uH7j7.js";
50
49
  import { r as Tn, t as En } from "./create-store-Dqp-PLLn.js";
@@ -7094,7 +7093,7 @@ function j_({ className: e, children: t, ...r }) {
7094
7093
  }
7095
7094
  function M_({ className: e, children: t, disabled: r = !1, showTrigger: i = !0, showClear: a = !1, size: o = "default", leading: s, suffix: c, labelId: l, anchorRef: u, ...d }) {
7096
7095
  let f = z.useContext(f_), p = __();
7097
- return /* @__PURE__ */ K(en, {
7096
+ return /* @__PURE__ */ K($t, {
7098
7097
  ref: Ut(u, f ?? void 0),
7099
7098
  ...qt({
7100
7099
  size: o,
@@ -7102,7 +7101,7 @@ function M_({ className: e, children: t, disabled: r = !1, showTrigger: i = !0,
7102
7101
  }),
7103
7102
  className: n("w-full", o === "sm" && "h-9 pointer-coarse:h-11", o === "lg" && "h-13 md:*:data-[slot=input-group-control]:text-base", e),
7104
7103
  children: [
7105
- s ? /* @__PURE__ */ G($t, {
7104
+ s ? /* @__PURE__ */ G(en, {
7106
7105
  align: "inline-start",
7107
7106
  className: "ps-2.5",
7108
7107
  children: /* @__PURE__ */ G("span", {
@@ -7116,12 +7115,12 @@ function M_({ className: e, children: t, disabled: r = !1, showTrigger: i = !0,
7116
7115
  className: n("h-full", !s && "ps-3"),
7117
7116
  ...d
7118
7117
  }),
7119
- c ? /* @__PURE__ */ G($t, {
7118
+ c ? /* @__PURE__ */ G(en, {
7120
7119
  align: "inline-end",
7121
7120
  className: "pe-1",
7122
7121
  children: c
7123
7122
  }) : null,
7124
- i || a ? /* @__PURE__ */ G($t, {
7123
+ i || a ? /* @__PURE__ */ G(en, {
7125
7124
  align: "inline-end",
7126
7125
  className: "gap-0.5 pe-1.5 has-[>button]:pe-1.5",
7127
7126
  children: /* @__PURE__ */ G(m_, {
@@ -11180,7 +11179,7 @@ var eS = (e = {}) => Tn({
11180
11179
  let [{ default: t }, { lowlight: n }, { richCodeBlock: r }] = await Promise.all([
11181
11180
  import("./dist-CRMFGjng.js"),
11182
11181
  import("./lowlight-OtcjU2Sa.js"),
11183
- import("./rich-code-block-DKJ8eKzL.js")
11182
+ import("./rich-code-block-DP2RT7pV.js")
11184
11183
  ]);
11185
11184
  return [r(t, {
11186
11185
  lowlight: n,
@@ -12417,7 +12416,7 @@ var gC = () => Tn({
12417
12416
  //#region lib/components/ui/fields/search-field/search-field-end.tsx
12418
12417
  function xC({ shortcut: e, loading: t, filled: n, disabled: r, onClear: i }) {
12419
12418
  let { t: a } = L(), o = e && !n && !t && !r, s = n && !t && !r;
12420
- return !o && !s && !t ? null : /* @__PURE__ */ K($t, {
12419
+ return !o && !s && !t ? null : /* @__PURE__ */ K(en, {
12421
12420
  align: "inline-end",
12422
12421
  className: "pe-2.5 has-[>button]:pe-2.5 has-[>kbd]:pe-[0.275rem]",
12423
12422
  children: [
@@ -12453,10 +12452,10 @@ function xC({ shortcut: e, loading: t, filled: n, disabled: r, onClear: i }) {
12453
12452
  //#region lib/components/ui/fields/search-field/search-box.tsx
12454
12453
  function SC({ search: e, error: t, loading: n, shortcut: r, placeholder: i, disabled: a, ...o }) {
12455
12454
  let { t: s } = L();
12456
- return /* @__PURE__ */ K(en, {
12455
+ return /* @__PURE__ */ K($t, {
12457
12456
  "data-disabled": a || void 0,
12458
12457
  children: [
12459
- /* @__PURE__ */ G($t, {
12458
+ /* @__PURE__ */ G(en, {
12460
12459
  align: "inline-start",
12461
12460
  className: "ps-2.5",
12462
12461
  children: /* @__PURE__ */ G("span", {
@@ -1,8 +1,8 @@
1
1
  import { t as e } from "./utils-BLfntITJ.js";
2
- import { a as t, c as n, d as r, i, n as a, r as o, t as s, u as c } from "./alert-dialog-BaqK-rmd.js";
3
- import { a as l } from "./button-CozGHXAv.js";
4
- import { i as u } from "./translate-material-DlMetRSJ.js";
5
- import { t as d } from "./use-material-translation-Cx5u36V5.js";
2
+ import { a as t, c as n, d as r, i, n as a, r as o, t as s, u as c } from "./alert-dialog-D4r0Kn9h.js";
3
+ import { a as l } from "./button-Z_xcg10A.js";
4
+ import { i as u } from "./translate-material-H5GMStyF.js";
5
+ import { t as d } from "./use-material-translation-BW5HZMwt.js";
6
6
  import { _ as f, g as p, h as m, t as h, v as g, y as _ } from "./date.utils-JTEIo3mM.js";
7
7
  import { useCallback as v, useEffect as y, useMemo as b, useRef as x, useState as S } from "react";
8
8
  import { Fragment as C, jsx as w, jsxs as T } from "react/jsx-runtime";
@@ -1,4 +1,4 @@
1
- import { i as e, t } from "./translate-material-DlMetRSJ.js";
1
+ import { i as e, t } from "./translate-material-H5GMStyF.js";
2
2
  import { useCallback as n } from "react";
3
3
  //#region lib/i18n/use-material-translation.ts
4
4
  function r() {
@@ -1,6 +1,6 @@
1
1
  import { o as e, r as t } from "./dist-DVRQkaTK.js";
2
2
  import { i as n, n as r, r as i, t as a } from "./dist-DWZXlCZR.js";
3
- import { C as o, S as s, x as c } from "./spinner-D7ol2n_-.js";
3
+ import { C as o, S as s, x as c } from "./spinner-rk8J5y9O.js";
4
4
  import { a as l, i as u, r as d } from "./dist-DHdUUM1w.js";
5
5
  import { c as f, i as p, l as m, o as h, r as g, s as ee } from "./in-dialog-D61Yeaol.js";
6
6
  import { r as te } from "./escape-owner-DpaP0lm1.js";
package/docs/README.md CHANGED
@@ -36,6 +36,7 @@ detail: every option, the second example, and the traps.
36
36
  | [Moving to TopAppBar](guides/migrating-to-top-app-bar.md) | Your app uses `AppHeader`, `TopAppBar`'s `variant` / `headline`, the shell's `'center'` / `'medium'` / `'large'` header values or the `app-header*` slots: each old spelling and its replacement, the visual changes, the slot rename planned for the next major |
37
37
  | [Migrating to 3.0](guides/migrating-to-3.md) | You are upgrading from 2.x: the React 19.3 and React Router 8.5 peers, `ActivityLayout`'s default route transition, `use(browser())` in server HTML, and each API removed in 3.0 with what replaces it |
38
38
  | [Date and time fields: from 2.x](guides/date-time-fields-2-x.md) | Your app used `DateField`, `DateRangeField`, `TimeField` or `TimePicker` before their redesign: each change in look and behaviour, the 2.x ways back that 3.0 removed, and what to change in tests |
39
+ | [The Refined field look](guides/field-look-refined.md) | Your fields look different after the Refined release (card surface, 3:1 border, 4px focus ring, no filled tint, `NumberField` steppers inside the box, `QuantityField` in one box) and you want the states, the test changes, the tokens, or a detail of the earlier look back |
39
40
  | [The field look (2.x)](guides/field-look-2-x.md) | Your fields or pickers look different after an upgrade (8px corners, the focus halo, a dashed read-only, a 44px `NativeSelect`, a list connected to its trigger, a `CountryField` with no chip, new group headers, the date and time fields' boxes) and you want to know what changed or get the earlier look back |
40
41
  | [Migrating to the Vite plugin](guides/migrate-to-vite-plugin.md) | Your app has its own CSP header, nonce, `zod-config`, Inter import or PDF bundling, and you move it to `nxgtMaterial()`: search → replace pairs, each with how to verify |
41
42
  | [Server lists in the URL](guides/server-lists-url.md) | A list's filter lives in the URL: parse it in a React Router loader with the codec in `@nxgt/material-core/filter`, feed the `Filter` bar's `query`, write it back on `onQueryChange` |
@@ -359,21 +359,21 @@ Storybook: `Date & time/Pickers surfaces/Phone sheet`, `/Popover` and `/Cancel`.
359
359
  ### The tonal field
360
360
 
361
361
  `DateField`, `DateRangeField` and `TimeField` (and their `*FormField`
362
- wrappers) share one style: a box tinted with the primary colour, no
363
- border at rest, and a 2px primary boundary while a segment has focus or the
364
- picker is open. While the box has focus every segment is a tint chip, and the
365
- focused one a primary pill (bold, a little larger, on a spring; none of it
366
- with `prefers-reduced-motion`). The open button is a tint circle, primary
367
- while the picker is open. An invalid field gets an error boundary and tint, a
368
- disabled one the plain disabled box. On a phone the chips are drawn text-wide inside the 44px segments.
369
- In forced colours the box keeps a 1px system border and the pill is
370
- `Highlight`.
371
-
372
- At rest the box has no boundary, which WCAG 1.4.11 allows because the field is
373
- identified by its label, its text (the placeholder reaches 4.5:1 against the
374
- fill) and its open button (the icon reaches 3:1). The focus boundary reaches 3:1
375
- against the page, and the pill 3:1 against the fill (`Date & time/Fields
376
- expressive` → Contrast).
362
+ wrappers) share one style, the field box of the text fields: the card as
363
+ surface, a 1px border at rest, and the primary border with a 4px ring while a
364
+ segment has focus or the picker is open (an error takes the error border and
365
+ ring, read-only is dashed, disabled recessed). While the box has focus every
366
+ segment is a tint chip, and the focused one a primary pill (bold, a little
367
+ larger, on a spring; none of it with `prefers-reduced-motion`). The open button
368
+ is a tint circle, primary while the picker is open. An invalid field gets the
369
+ error border and ring, a disabled one the plain disabled box. On a phone the
370
+ chips are drawn text-wide inside the 44px segments. In forced colours the box
371
+ keeps a system border and the pill is `Highlight`.
372
+
373
+ At rest the box has a 1px border that reaches 3:1 against the card (WCAG
374
+ 1.4.11), and the placeholder reaches 4.5:1 against the fill and the open
375
+ button's icon 3:1. The focus ring reaches 3:1 against the page, and the pill
376
+ 3:1 against the fill (`Date & time/Fields expressive` → Contrast).
377
377
 
378
378
  The field's calendar and picker share it.
379
379
 
@@ -686,8 +686,9 @@ value shows the segments' placeholders. The box is the shared field box
686
686
  `data-focused` (while a segment has focus), `data-invalid` and
687
687
  `data-disabled`, set only when true, and the field box draws the filled
688
688
  tint, the open and focus looks and the red border of an invalid field from
689
- them; the field draws its own tonal box over it (see [The tonal
690
- field](#the-tonal-field)). With no value, the first pick in a column
689
+ them. The typed box only adds the ring while the picker is open and while a
690
+ trigger button around it has keyboard focus; the error look is the shared
691
+ field box's (see [The tonal field](#the-tonal-field)). With no value, the first pick in a column
691
692
  (`variant="columns"`) starts from midnight today. In the tiles, a tile with no value starts from its lowest
692
693
  value on an increase and its highest on a decrease.
693
694
 
@@ -841,13 +842,14 @@ export function DueAt() {
841
842
  (`material.age-field.unit-day`, `unit-week`, `unit-month`, `unit-year`: "1 month",
842
843
  "2 months", « 2 mois »), and a polite status says the whole age when it changes
843
844
  (`material.age-field.reading`). `ageReading(t, 2, 'month')` gives the same text
844
- for your own use. The unit picker is named "Age unit" (`material.age-field.unit`).
845
+ for your own use. The unit chip reads "Age unit: months" and the menu it opens
846
+ is named "Age unit" (`material.age-field.unit`).
845
847
 
846
848
  **In tests.** One `group` named by the label, a `spinbutton` for the number
847
- and a `combobox` named "Age unit":
849
+ and a `button` named "Age unit: months" (the chip) that opens a menu of options:
848
850
 
849
851
  ```ts
850
- await user.click(screen.getByRole('combobox', { name: 'Age unit' }));
852
+ await user.click(screen.getByRole('button', { name: /^Age unit/ }));
851
853
  await user.click(await screen.findByRole('option', { name: 'years' }));
852
854
  ```
853
855
 
@@ -919,9 +921,9 @@ its number pad). A button at its limit is `aria-disabled`, not `disabled`, so
919
921
  a focused one keeps the focus.
920
922
 
921
923
  **Look.** The tonal box of the date fields, a leading timer icon
922
- (decorative), then the amounts and the pair: no border at rest, a 2px primary
923
- boundary while anything inside has focus, an error boundary and tint when
924
- invalid, the disabled box as the other fields. Every focus ring is drawn
924
+ (decorative), then the amounts and the pair: the field box's border at rest,
925
+ the primary border and 4px ring while anything inside has focus, the error
926
+ border and ring when invalid, the disabled box as the other fields. Every focus ring is drawn
925
927
  inside the field. The buttons are 32px (44px on a coarse pointer, where the
926
928
  field grows to 52px so they keep 4px around them); every segment has a 44px
927
929
  hit area on a phone. The segments read left to right in every direction, as
@@ -7,6 +7,12 @@ them into a form, and [what each field emits](../guides/forms.md#what-each-field
7
7
  for the value type each one writes. Everything is imported from
8
8
  `@nxgt/material/components`.
9
9
 
10
+ The text-like fields share one box, drawn in the Refined look (the card
11
+ surface, a 3:1 border, a 1px primary border with a 4px ring on focus, no tint
12
+ once filled). [The Refined field look](../guides/field-look-refined.md) has
13
+ its states, what moved for tests (the `NumberField` and `QuantityField` tab
14
+ order and roles) and the tokens that tune it.
15
+
10
16
  | | Component | What it does |
11
17
  | --- | --- | --- |
12
18
  | <img src="../previews/form-fields-field.webp" width="96" alt=""> | [Field](#field) | Renders the field matching a config `type` |
@@ -485,7 +491,7 @@ import { User } from 'lucide-react';
485
491
  | `label` | `ReactNode` | — | shown above the input |
486
492
  | `helperText` | `ReactNode` | — | hint under the input; the error message when `error` |
487
493
  | `error` | `boolean` | — | error outline and helper colour |
488
- | `leading`, `trailing` | `ReactNode` | — | adornments inside the input: an element (icon, button) is its own 32px well; text (`"/ 20"`) goes in a well as tall as the field, centred on the value |
494
+ | `leading`, `trailing` | `ReactNode` | — | adornments inside the input: an element (icon, button) is muted with no well fill, 32px (44px on touch); text (`"/ 20"`) is a muted unit in the same box that hugs the value (the input is sized to it) |
489
495
 
490
496
  Every other prop is the native `<input>`'s.
491
497
 
@@ -636,13 +642,47 @@ export function Quantity() {
636
642
  | `min`, `max` | `number` | — | clamps typed and stepped values |
637
643
  | `step` | `number` | `1` | the +/− increment |
638
644
  | `hideSteppers` | `boolean` | `false` | hides the +/− buttons |
639
- | `suffix` | `ReactNode` | — | unit shown inside the input box, at its end |
645
+ | `suffix` | `ReactNode` | — | unit shown inside the input box, at its end (the max of a `score`) |
646
+ | `variant` | `'default' \| 'score'` | `'default'` | `score` is a big tabular value with its max, no box at rest and no steppers (see below) |
647
+ | `tone` | `Tone` | none (neutral band) | `score` only: one of the eight named tones or an [app tone](../guides/theming.md#app-tones-on-shape-fab-avatar-statcard-and-the-metric-cards), drawn as text colour plus a shape marker |
648
+ | `locked` | `boolean` | `false` | `score` only: read-only, muted, dashed frame and a lock |
649
+ | `lockedReason` | `ReactNode` | — | `score` only: why it is locked; shown under the value and wired by `aria-describedby` |
640
650
  | `aria-label` | `string` | — | names the input when it has no `label` (a part of a larger field) |
641
651
  | `aria-labelledby` | `string` | — | names the input by another element's id (a part of a larger field) |
642
652
  | `aria-describedby` | `string` | — | more ids describing the input, after its `helperText` (an error the larger field shows) |
643
653
  | `onBlur` | `FocusEventHandler` | — | after the typed text is read and `onChange` called |
644
654
  | `ref` | `Ref<HTMLInputElement>` | — | reaches the text input (React Hook Form's `field.ref`) |
645
655
 
656
+ **Score variant.** `variant="score"` draws a result the user types, such as
657
+ a mark out of 20, a rating or a points total: a big value in tabular figures
658
+ with the maximum (`suffix`, "/ 20") hugging it on the baseline. There is no box
659
+ at rest (a quiet band, about 6% of the tone), a 1px frame on hover and the field
660
+ focus ring on focus; it has no steppers (`hideSteppers` is implied). The tone is
661
+ yours (`tone="success"`, `"warning"`, an app tone...) and is never colour alone:
662
+ the text takes the tone's text colour and a small shape marker precedes the value
663
+ (success a circle, warning a triangle, error a diamond, every other tone a
664
+ square; the marker is `aria-hidden`, so say what the tone means in the label or
665
+ the helper text). An `error` draws the error tone with a border and its
666
+ `helperText` describes the input. `locked` makes the input read-only with a muted
667
+ value, a dashed frame and a lock icon; `lockedReason` shows under the value and
668
+ is added to the input's `aria-describedby`. A locked score keeps a visible focus frame, and a locked score in `error` keeps the error colour on its dashed frame. The styles ship in `styles.css`
669
+ (`number-field-score.css`); `NumberFormField` forwards all of them.
670
+
671
+ ```tsx
672
+ <NumberField
673
+ variant="score"
674
+ label="Result"
675
+ suffix="/ 20"
676
+ min={0}
677
+ max={20}
678
+ step={0.5}
679
+ tone={mark >= 10 ? 'success' : 'warning'}
680
+ value={mark}
681
+ onChange={setMark}
682
+ />
683
+ <NumberField variant="score" label="Result" suffix="/ 20" value={16} locked lockedReason="Closed on 3 June." />
684
+ ```
685
+
646
686
  **Stepper names.** Each +/− button is named after its field: "Increase
647
687
  Quantity" / "Decrease Quantity" (`material.number-field.increase-named` and
648
688
  `decrease-named`, with the `label` interpolated), so a form with several number
@@ -651,11 +691,21 @@ plain-text `label`, else from `aria-label`; with neither (a field named only
651
691
  through `aria-labelledby` included), the buttons keep the bare "Increase" /
652
692
  "Decrease".
653
693
 
694
+ **Layout and focus.** The box is one `role="group"` with the input and, at its
695
+ end, the Decrease and Increase buttons as a tinted round pair, no dividers
696
+ (32px circles, a 44px target on a coarse pointer; the look is shared with
697
+ `DurationField` through `field-stepper.css`). At `min` or `max` a button is
698
+ `aria-disabled`, so it keeps focus. The value is end-aligned in tabular figures, and a
699
+ `suffix` sits right after it. The input never gets narrower than about 7
700
+ digits. Tab goes input, Decrease, Increase (with a `CalculatorField`: input,
701
+ Open calculator, Decrease, Increase). A test that queries an unnamed
702
+ `getByRole('group')` now also matches the number box: name the group you mean.
703
+
654
704
  **Stepper tooltips.** Each +/− button shows its name in a tooltip on hover and
655
705
  on keyboard focus (`:focus-visible`). Focus that a script moves onto it, such
656
706
  as a `Sheet` or `Dialog` putting its initial focus on the first tabbable
657
707
  control, does not open the tooltip once the user has used the pointer (the browser does not treat that focus as `:focus-visible`), so it does not cover the field's label. The
658
- buttons stay in the tab order and keep their accessible names. `QuantityField`
708
+ buttons stay in the tab order (input, Decrease, Increase) and keep their accessible names. `QuantityField`
659
709
  shares this (React only; the Vue steppers are unchanged, #2264).
660
710
 
661
711
  **Decimal separator.** After blur (and after +/−) the value is shown with the
@@ -671,7 +721,7 @@ Form's `field.ref` the input itself: `setFocus('amount')` and
671
721
  **Emits:** `number | null`.
672
722
  **Form wrapper:** `NumberFormField` — `control` and `name`, see
673
723
  [forms](../guides/forms.md#the-pair) and [what each field emits](../guides/forms.md#what-each-field-emits).
674
- **Storybook:** `Form fields/NumberField` · **Vue:** `NumberField`, `NumberFormField` (the language separator is React only for now, #763; the stepper names, #2060)
724
+ **Storybook:** `Form fields/NumberField` (`Score`) · **Vue:** `NumberField`, `NumberFormField` (the language separator is React only for now, #763; the stepper names, #2060; the `score` variant is React only)
675
725
 
676
726
  ---
677
727
 
@@ -703,8 +753,9 @@ ratio (`0.15`).
703
753
  ![QuantityField](../previews/form-fields-quantityfield.webp)
704
754
 
705
755
  One labelled field holding an amount and its unit ("2 capsule", "500 mg"): a
706
- [`NumberField`](#numberfield)'s number beside a unit picker, under one label
707
- and one error message. The value is `{ value: number | null, unit: string }`.
756
+ [`NumberField`](#numberfield)'s number and a unit chip in ONE field box (value
757
+ at the start, the unit as a soft chip with a ⇅ icon, then the round −/+ pair),
758
+ under one label and one error message. The value is `{ value: number | null, unit: string }`.
708
759
  `QuantityFormField` wires it to react-hook-form.
709
760
 
710
761
  ```tsx
@@ -741,8 +792,7 @@ Without a form library, `QuantityField` takes `value` and `onChange` (or
741
792
  `defaultValue`). The number is the one `NumberField` has: the language's
742
793
  decimal separator, `min`, `max` and `step` (clamped on blur), and steppers
743
794
  named after the field ("Increase Dose"). Both parts stay on one line on a
744
- phone: the unit is sized to its longest label and shrinks first, the
745
- number keeps 9rem (see Unit width below).
795
+ phone: the chip truncates before the value does (see The unit chip below).
746
796
 
747
797
  | Prop | Type | Default | What it does |
748
798
  | --- | --- | --- | --- |
@@ -750,27 +800,31 @@ number keeps 9rem (see Unit width below).
750
800
  | `value`, `defaultValue`, `onChange` | `QuantityValue`, `(value) => void` | empty | the amount and its unit; `onChange` gets both on each change |
751
801
  | `label` | `ReactNode` | none | the one label; it names the group |
752
802
  | `units` | `{ value, label }[]` | none | the units offered |
753
- | `allowCustomUnit` | `boolean` | `false` | the unit is typed in a text input and `units` are suggestions; otherwise it is picked from `units` |
803
+ | `allowCustomUnit` | `boolean` | `false` | the unit menu gets a "Search or type a unit" input and a "Use “x”" item, so a unit outside `units` can be typed; otherwise it is a plain listbox of `units` |
754
804
  | `min`, `max`, `step`, `hideSteppers` | | `step` 1 | as `NumberField` |
755
- | `unitLabel`, `unitPlaceholder` | `string` | "<label> unit" | the unit part's accessible name and its placeholder |
805
+ | `unitLabel`, `unitPlaceholder` | `string` | "<label> unit" | `unitLabel` names the unit part (the menu's name; the chip reads "<unitLabel>: mg"); `unitPlaceholder` shows while no unit is chosen |
756
806
  | `helperText`, `error` | `ReactNode`, `boolean` | none | the one message under the pair; in a form, an error on `name`, `name.value` or `name.unit` shows there |
757
807
  | `className`, `aria-label` | `string` | none | `className` goes on the group; `aria-label` names it when `label` is not plain text |
758
808
  | `name`, `onBlur` | | none | `QuantityField` only (the form field takes them from the form): `name` names the parts `<name>.value` and `<name>.unit`; `onBlur` fires when the number input loses focus |
759
- | `required`, `disabled`, `placeholder`, `id`, `ref` | | | `placeholder`, `id` and `ref` reach the number input (React Hook Form's `field.ref` focuses it on an error) |
809
+ | `required`, `disabled`, `placeholder`, `id`, `ref` | | | `required` applies to the number only; to require a unit, validate `unit` in the form schema. `placeholder`, `id` and `ref` reach the number input (React Hook Form's `field.ref` focuses it on an error) |
760
810
 
761
811
  - **Semantics:** a `<fieldset>` (role `group`) named by the label; the number
762
- is a textbox named after the label, the unit a combobox (or, with
763
- `allowCustomUnit`, a text input) named "Dose unit". The message describes
764
- the group, the number and the unit, and both are `aria-invalid` on an error.
765
- - **Unit width:** the unit part is sized to the longest label of `units`
766
- (never under 7rem, never over 55% of the row). It shrinks before the number
767
- does: the number's cell keeps 9rem (two 44px steppers and a 44px input), so
768
- the input stays a tap target at 375px, also in a padded side sheet. Beyond
769
- the cap the label is cut with an ellipsis and the full label
770
- is the select's `title` (the `units` select only; a free unit typed past
771
- the cap scrolls in its input). No inline style is used for it.
772
- - **Translations:** `material.quantity-field.unit` and `.unit-named` (English
773
- and French) name the unit part.
812
+ is a textbox named after the label, the unit chip a button named "Unit: mg"
813
+ (`aria-expanded`; it opens a popover), the menu a listbox named
814
+ "Dose unit". The message describes the group, the number and the chip, and
815
+ the number is `aria-invalid` on an error.
816
+ - **Keyboard:** Tab goes value, unit chip, Decrease, Increase. Enter, Space or
817
+ ArrowDown on the chip opens the menu (focus lands on the list, or on the
818
+ search with `allowCustomUnit`); the arrows move, Enter picks, Esc closes and
819
+ returns focus to the chip.
820
+ - **The unit chip:** one focus ring for the whole box, whichever part has
821
+ focus. The chip is capped at 52% of the box and truncates a long label with
822
+ an ellipsis (the full label is its `title`); the value keeps room for about
823
+ 4 digits at 360px. A coarse pointer gets 44px targets. Disabled, the chip
824
+ and the steppers lose their tint. A unit outside `units` shows as typed.
825
+ The unit still posts as `<name>.unit` (a hidden input) in a native form.
826
+ - **Translations:** `material.quantity-field.unit`, `.unit-named`, `.unit-chip`
827
+ ("Unit: {label}"), `.search` and `.use-typed` (English and French).
774
828
 
775
829
  **Emits:** `{ value: number | null, unit: string }`.
776
830
  **Form wrapper:** `QuantityFormField` — `control` and `name`, see
@@ -1762,9 +1816,9 @@ describes the switch too, and an `aria-describedby` you pass is kept beside
1762
1816
  these. With `required`, the switch has `aria-required` and the label's asterisk
1763
1817
  is drawn by CSS, so the name and the label text stay "Terms", not "Terms*".
1764
1818
  Without an `id` one is generated, under `SwitchFormField` too (it used to be
1765
- the field's `name`, which two forms on one page shared). The row is tinted
1766
- while the switch is on, from `checked` or, uncontrolled, from `defaultChecked` and each toggle, and carries
1767
- `data-checked="true"` / `"false"`, so select rows that are on with
1819
+ the field's `name`, which two forms on one page shared). The row carries
1820
+ `data-checked="true"` / `"false"` (the checked state is the track, the thumb
1821
+ and the primary label, with no row tint), so select rows that are on with
1768
1822
  `[data-checked="true"]` (a bare `[data-checked]` also matches rows that are
1769
1823
  off).
1770
1824
 
@@ -81,7 +81,7 @@ phone's menu sheet pad clear of `env(safe-area-inset-*)`, as classes; see the
81
81
 
82
82
  | Prop | Type | Default | Effect |
83
83
  | --- | --- | --- | --- |
84
- | `items` | `MenuItem[]` | — | `label` (already translated), `url`, `icon`, `footer`, `display` (`'icon'`: a round icon-only button, the label as tooltip and name, in the rail and the expanded sidebar; the phone's menu sheet always shows icon and label; see the [app shell guide](../guides/app-shell.md)), `badge` (`true` a dot, a number a count up to "99+"), `badgeLabel` (see [Badges](../guides/app-shell.md#badges)), and `children` (read by `navigation="top"`, which opens them in a dropdown under a parent that is then only a trigger; by `navigation="two-level"`, which lists them in the panel beside the rail, one level deep; by the phone's menu sheet and the expanded sidebar, which nest them under the parent's own link, unless the entry sets `childrenIn: 'sidebar'`, which keeps them to the sidebar and the top dropdown), `childrenIn`, `group`, `bar`, `priority` for the navigation presets that read them (the drawer reads `group`, the bar `bar` and `priority`; the floating toolbar, not drawn yet, is the only preset still to read them) |
84
+ | `items` | `MenuItem[]` | — | `label` (already translated), `url`, `icon`, `footer`, `display` (`'icon'`: a round icon-only button, the label as tooltip and name, in the rail and the expanded sidebar; the phone's menu sheet always shows icon and label; see the [app shell guide](../guides/app-shell.md)), `badge` (`true` a dot, a number a count up to "99+"), `badgeLabel` (see [Badges](../guides/app-shell.md#badges)), and `children` (read by `navigation="top"`, which opens them in a dropdown under a parent that is then only a trigger; by `navigation="two-level"`, which lists them in the panel beside the rail, one level deep; by the phone's menu sheet and the expanded sidebar, which nest them under the parent's own link, unless the entry sets `childrenIn: 'sidebar'`, which keeps them to the sidebar and the top dropdown), `childrenIn`, `defaultExpanded` (the expanded sidebar folds the entry's children from a chevron button, open at first when `true`, folded when `false`; unset, they are always listed), `group`, `bar`, `priority` for the navigation presets that read them (the drawer reads `group`, the bar `bar` and `priority`; the floating toolbar, not drawn yet, is the only preset still to read them) |
85
85
  | `linkComponent` | `AppShellLinkComponent` | React Router `Link` | The link each menu entry renders, given `href`; see the [app shell guide](../guides/app-shell.md). Defaults to the [`LinkComponentProvider`](./primitives.md#linkcomponentprovider)'s link when one is set. |
86
86
  | `logo`, `name` | `AppLogo` (`ReactNode \| string \| AppLogoImage`, `AppLogoImage` = `{ src, alt? }`), `string` | — | the app's logo alone in the collapsed rail, named by `name` (also its tooltip); logo and name side by side in the phone's menu sheet |
87
87
  | `context` | `ReactNode` | — | a line at the top of the phone's menu sheet, above the brand: the current tenant's name; `name` stays the app's brand; `AppHeader` and `AppSidebar` take it too (see the [app shell guide](../guides/app-shell.md#the-brand-logo-and-name)) |
@@ -414,6 +414,21 @@ its `url`, with its badge, for a parent page that already lists them. Unset
414
414
  }
415
415
  ```
416
416
 
417
+ `defaultExpanded` makes an entry's `children` fold in the expanded sidebar: a
418
+ chevron button after the entry (named "Collapse the group" / "Expand the group",
419
+ `material.navigation.group-collapse` and `group-expand`) shows and hides them,
420
+ `true` opening them at first and `false` folding them (a folded group still opens at first when the current page is one of its children). It is ignored with `display: 'icon'`. Unset, they are always
421
+ listed, as before. The entry stays a link to its `url`; the state is local (not
422
+ remembered), and the phone's menu sheet and the other presets ignore it.
423
+
424
+ ```tsx
425
+ {
426
+ label: 'Services', url: '/services', icon: 'grid-2',
427
+ children: [{ label: 'Lab', url: '/lab', icon: 'flask' }],
428
+ defaultExpanded: true, // open at first, foldable
429
+ }
430
+ ```
431
+
417
432
  `MenuItem` also accepts `children`, `group`, `bar` and `priority`. Each is read
418
433
  by the presets that use it, and ignored by the others: `bar` and `priority`
419
434
  choose the entries of the bottom bar **and** of the floating toolbar (the rest go
@@ -1,5 +1,7 @@
1
1
  # The field look (2.x)
2
2
 
3
+ > The Refined release later replaced this look (no filled tint, the card surface, a 4px ring): see [The Refined field look](field-look-refined.md). This page keeps the 2.x steps and their ways back.
4
+
3
5
  Every text field and picker trigger shares one look, the **field box**: a
4
6
  soft neutral surface, the primary tint once it holds a value, a hairline that
5
7
  firms on hover, and the border in primary with a 3px halo on focus. It lives
@@ -411,10 +413,14 @@ the corners and colours are the `--nxgt-field-*` tokens (set them under
411
413
 
412
414
  ### `NumberField` and `OtpField`
413
415
 
414
- The steppers of a `NumberField` and the slots of an `OtpField` take the
415
- field radius (`--nxgt-field-radius`, 8px) instead of 6px, so they read as
416
- parts of the same family as the field beside them. There is no prop for
417
- it: override the token to round them less, as every field.
416
+ The Refined release moved the `NumberField` steppers inside the box and changed its tab order: see [The Refined field look](field-look-refined.md#tab-order-and-roles-for-tests).
417
+
418
+ The slots of an `OtpField` take the field radius (`--nxgt-field-radius`, 8px)
419
+ instead of 6px, so they read as parts of the same family as the field beside
420
+ them. A `NumberField` is one field box: its Decrease and Increase buttons are
421
+ tinted round circles inside it (DurationField's look), so there is no
422
+ separate radius for them. There is no prop for either: override the token to
423
+ round them less, as every field.
418
424
 
419
425
  ```css
420
426
  :root {