@nxgt/material 3.79.0 → 3.80.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 (279) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/README.md +45 -6
  3. package/dist/{alert-dialog-653apk3f.js → alert-dialog-DgHtXZuB.js} +1 -1
  4. package/dist/{async-slice-CXLbQuOc.js → async-slice-YBQsGtQT.js} +1 -1
  5. package/dist/{button-3op3rtZh.js → button-_vm-xSBU.js} +1 -1
  6. package/dist/{calculator-KqIMBXSh.js → calculator-CTd_S23A.js} +10 -10
  7. package/dist/calculator-field.js +6 -6
  8. package/dist/{calculator-segment-BlJE1LaS.js → calculator-segment-OI1BT3bA.js} +1 -1
  9. package/dist/calculator.js +1 -1
  10. package/dist/charts.js +3 -3
  11. package/dist/{chip-MuKDwtkG.js → chip-DumcVzUO.js} +2 -2
  12. package/dist/{code-editor-Bp2RrdNx.js → code-editor-CiwgfSOK.js} +4 -4
  13. package/dist/code-editor.js +4 -4
  14. package/dist/{code-language-items-B7WR5ua_.js → code-language-items-Dip0xnmc.js} +2 -2
  15. package/dist/components/components.css +3 -0
  16. package/dist/components/ui/actions/fab/fab-dock.css +19 -6
  17. package/dist/components/ui/layout/app-search/app-search.css +62 -0
  18. package/dist/components/ui/layout/app-shell/activity-backdrop.css +10 -2
  19. package/dist/components/ui/layout/app-shell/app-header.css +108 -0
  20. package/dist/components/ui/layout/navigation-toolbar/navigation-toolbar.css +43 -0
  21. package/dist/{components-ConMf2w-.js → components-CJFHhkZv.js} +21800 -17785
  22. package/dist/components.js +37 -37
  23. package/dist/{conversion-variant-BDFAxqe9.js → conversion-variant-CqrPwPjC.js} +3 -3
  24. package/dist/{currency-field-DWHB5oms.js → currency-field-CMFvctye.js} +4 -4
  25. package/dist/{dialog-Bm5LvVlB.js → dialog-B0iU3fmh.js} +3 -3
  26. package/dist/dnd.js +2 -2
  27. package/dist/{dropdown-menu-xlZ6NYUA.js → dropdown-menu-CPOgcajv.js} +1 -1
  28. package/dist/editor.js +7 -7
  29. package/dist/{empty-state-C0kviQdW.js → empty-state-D3Jggupu.js} +1 -1
  30. package/dist/{financial-variant-CggTpad2.js → financial-variant-BdyfYhnp.js} +5 -5
  31. package/dist/{hooks-Dg94jPRq.js → hooks-Z7KKbv4G.js} +2 -2
  32. package/dist/hooks.js +2 -2
  33. package/dist/{hover-card-B1g55Hi6.js → hover-card-CFGIX6kg.js} +1 -1
  34. package/dist/i18n.js +3 -3
  35. package/dist/{icon-badge-BcW66bRk.js → icon-badge-kxGWUvcO.js} +1 -1
  36. package/dist/{icon-button-Cogxy1cy.js → icon-button-BamxMwZs.js} +1 -1
  37. package/dist/lib/components/ui/collections/server-table/partials/server-table-band-classes.d.ts +13 -0
  38. package/dist/lib/components/ui/fields/contacts/placeholders.d.ts +1 -1
  39. package/dist/lib/components/ui/layout/app-bar/top-app-bar.d.ts +18 -3
  40. package/dist/lib/components/ui/layout/app-search/app-search-bar.d.ts +11 -0
  41. package/dist/lib/components/ui/layout/app-search/app-search.types.d.ts +47 -0
  42. package/dist/lib/components/ui/layout/app-search/index.d.ts +3 -0
  43. package/dist/lib/components/ui/layout/app-search/partials/on-phone.d.ts +2 -0
  44. package/dist/lib/components/ui/layout/app-search/partials/phone-search.d.ts +3 -0
  45. package/dist/lib/components/ui/layout/app-search/partials/pill-search.d.ts +3 -0
  46. package/dist/lib/components/ui/layout/app-search/pill-form.d.ts +18 -0
  47. package/dist/lib/components/ui/layout/app-search/search-panel.d.ts +24 -0
  48. package/dist/lib/components/ui/layout/app-search/search-results.d.ts +14 -0
  49. package/dist/lib/components/ui/layout/app-search/search-shortcut.d.ts +15 -0
  50. package/dist/lib/components/ui/layout/app-search/search-view.d.ts +22 -0
  51. package/dist/lib/components/ui/layout/app-search/use-pill-panel.d.ts +22 -0
  52. package/dist/lib/components/ui/layout/app-search/use-search-text.d.ts +8 -0
  53. package/dist/lib/components/ui/layout/app-shell/activity-app-bar.d.ts +35 -0
  54. package/dist/lib/components/ui/layout/app-shell/activity-chrome.d.ts +26 -3
  55. package/dist/lib/components/ui/layout/app-shell/activity-column-props.d.ts +22 -0
  56. package/dist/lib/components/ui/layout/app-shell/activity-column.d.ts +10 -2
  57. package/dist/lib/components/ui/layout/app-shell/activity-layout-navigation.types.d.ts +94 -0
  58. package/dist/lib/components/ui/layout/app-shell/activity-layout.d.ts +8 -1
  59. package/dist/lib/components/ui/layout/app-shell/activity-layout.types.d.ts +2 -1
  60. package/dist/lib/components/ui/layout/app-shell/activity-rails.d.ts +16 -0
  61. package/dist/lib/components/ui/layout/app-shell/activity-sidebar-lane.d.ts +22 -0
  62. package/dist/lib/components/ui/layout/app-shell/activity-top-nav.d.ts +11 -0
  63. package/dist/lib/components/ui/layout/app-shell/activity-two-level-lane.d.ts +14 -0
  64. package/dist/lib/components/ui/layout/app-shell/app-back.d.ts +22 -0
  65. package/dist/lib/components/ui/layout/app-shell/app-header-row.d.ts +3 -0
  66. package/dist/lib/components/ui/layout/app-shell/app-header.d.ts +33 -1
  67. package/dist/lib/components/ui/layout/app-shell/app-shell.utils.d.ts +8 -0
  68. package/dist/lib/components/ui/layout/app-shell/app-sidebar-entries.d.ts +13 -0
  69. package/dist/lib/components/ui/layout/app-shell/app-sidebar-label-item.d.ts +3 -1
  70. package/dist/lib/components/ui/layout/app-shell/bottom-chrome.d.ts +13 -0
  71. package/dist/lib/components/ui/layout/app-shell/header-title.d.ts +18 -2
  72. package/dist/lib/components/ui/layout/app-shell/header.utils.d.ts +37 -0
  73. package/dist/lib/components/ui/layout/app-shell/index.d.ts +3 -0
  74. package/dist/lib/components/ui/layout/app-shell/navigation-parts.d.ts +38 -0
  75. package/dist/lib/components/ui/layout/app-shell/navigation.utils.d.ts +36 -0
  76. package/dist/lib/components/ui/layout/app-shell/page-title-scope.d.ts +14 -0
  77. package/dist/lib/components/ui/layout/app-shell/page-title.d.ts +12 -1
  78. package/dist/lib/components/ui/layout/app-shell/shell-scroll.d.ts +32 -0
  79. package/dist/lib/components/ui/layout/app-shell/sticky-offset.d.ts +8 -0
  80. package/dist/lib/components/ui/layout/app-shell/types.d.ts +14 -0
  81. package/dist/lib/components/ui/layout/app-shell/use-focus-while-hidden.d.ts +9 -0
  82. package/dist/lib/components/ui/layout/app-shell/use-header-height.d.ts +12 -0
  83. package/dist/lib/components/ui/layout/app-shell/use-header-scroll.d.ts +19 -0
  84. package/dist/lib/components/ui/layout/app-shell/use-shell-header.d.ts +20 -0
  85. package/dist/lib/components/ui/layout/auth-card/auth-card-split.d.ts +14 -0
  86. package/dist/lib/components/ui/layout/auth-card/auth-card.d.ts +13 -1
  87. package/dist/lib/components/ui/layout/dashboard-grid/dashboard-grid-context.d.ts +21 -0
  88. package/dist/lib/components/ui/layout/dashboard-grid/dashboard-grid.d.ts +9 -0
  89. package/dist/lib/components/ui/layout/dashboard-grid/dashboard-grid.state.d.ts +30 -0
  90. package/dist/lib/components/ui/layout/dashboard-grid/dashboard-grid.tiles.d.ts +8 -0
  91. package/dist/lib/components/ui/layout/dashboard-grid/dashboard-grid.types.d.ts +50 -0
  92. package/dist/lib/components/ui/layout/dashboard-grid/dashboard-grid.utils.d.ts +70 -0
  93. package/dist/lib/components/ui/layout/dashboard-grid/dashboard-tile.d.ts +7 -0
  94. package/dist/lib/components/ui/layout/dashboard-grid/index.d.ts +4 -0
  95. package/dist/lib/components/ui/layout/dashboard-grid/partials/dashboard-announcer.d.ts +6 -0
  96. package/dist/lib/components/ui/layout/dashboard-grid/partials/dashboard-edit-bar.d.ts +11 -0
  97. package/dist/lib/components/ui/layout/dashboard-grid/partials/dashboard-move-buttons.d.ts +9 -0
  98. package/dist/lib/components/ui/layout/dashboard-grid/partials/dashboard-toolbar.d.ts +7 -0
  99. package/dist/lib/components/ui/layout/dashboard-grid/use-dashboard-grid.d.ts +21 -0
  100. package/dist/lib/components/ui/layout/dashboard-grid/use-dashboard-moves.d.ts +22 -0
  101. package/dist/lib/components/ui/layout/doc/doc-context.d.ts +2 -0
  102. package/dist/lib/components/ui/layout/doc/doc.d.ts +5 -0
  103. package/dist/lib/components/ui/layout/doc/index.d.ts +1 -1
  104. package/dist/lib/components/ui/layout/doc/partials/doc-embedded-bar.d.ts +9 -0
  105. package/dist/lib/components/ui/layout/doc/partials/doc-embedded.d.ts +8 -0
  106. package/dist/lib/components/ui/layout/doc/use-doc.d.ts +9 -1
  107. package/dist/lib/components/ui/layout/editor-layout/editor-layout.d.ts +14 -0
  108. package/dist/lib/components/ui/layout/editor-layout/editor-layout.types.d.ts +31 -0
  109. package/dist/lib/components/ui/layout/editor-layout/index.d.ts +4 -0
  110. package/dist/lib/components/ui/layout/editor-layout/partials/editor-layout-body.d.ts +11 -0
  111. package/dist/lib/components/ui/layout/editor-layout/partials/editor-layout-canvas.d.ts +8 -0
  112. package/dist/lib/components/ui/layout/editor-layout/partials/editor-layout-context.d.ts +12 -0
  113. package/dist/lib/components/ui/layout/editor-layout/partials/editor-layout-start.d.ts +8 -0
  114. package/dist/lib/components/ui/layout/editor-layout/partials/editor-layout-triggers.d.ts +10 -0
  115. package/dist/lib/components/ui/layout/editor-layout/partials/use-editor-layout-names.d.ts +8 -0
  116. package/dist/lib/components/ui/layout/editor-layout/partials/use-editor-layout-state.d.ts +21 -0
  117. package/dist/lib/components/ui/layout/index.d.ts +9 -0
  118. package/dist/lib/components/ui/layout/landing/index.d.ts +6 -0
  119. package/dist/lib/components/ui/layout/landing/landing-layout.d.ts +15 -0
  120. package/dist/lib/components/ui/layout/landing/landing-layout.types.d.ts +27 -0
  121. package/dist/lib/components/ui/layout/landing/landing-section.d.ts +12 -0
  122. package/dist/lib/components/ui/layout/landing/landing-section.types.d.ts +32 -0
  123. package/dist/lib/components/ui/layout/landing/landing.classes.d.ts +20 -0
  124. package/dist/lib/components/ui/layout/landing/partials/landing-header.d.ts +11 -0
  125. package/dist/lib/components/ui/layout/landing/partials/landing-section-intro.d.ts +13 -0
  126. package/dist/lib/components/ui/layout/landing/partials/site-footer-group.d.ts +8 -0
  127. package/dist/lib/components/ui/layout/landing/site-footer.d.ts +13 -0
  128. package/dist/lib/components/ui/layout/landing/site-footer.types.d.ts +29 -0
  129. package/dist/lib/components/ui/layout/list-details-layout/internal.d.ts +2 -0
  130. package/dist/lib/components/ui/layout/list-details-layout/list-details-layout.d.ts +9 -17
  131. package/dist/lib/components/ui/layout/list-details-layout/partials/history-mark.d.ts +2 -0
  132. package/dist/lib/components/ui/layout/list-details-layout/partials/list-details-context.d.ts +17 -1
  133. package/dist/lib/components/ui/layout/list-details-layout/partials/list-details-history.d.ts +8 -0
  134. package/dist/lib/components/ui/layout/list-details-layout/partials/list-details-inspector.d.ts +21 -0
  135. package/dist/lib/components/ui/layout/list-details-layout/partials/list-details-layout.types.d.ts +47 -0
  136. package/dist/lib/components/ui/layout/list-details-layout/partials/list-details-resizer.d.ts +9 -0
  137. package/dist/lib/components/ui/layout/list-details-layout/partials/list-details-root.d.ts +3 -0
  138. package/dist/lib/components/ui/layout/list-details-layout/partials/list-details-trigger.d.ts +13 -4
  139. package/dist/lib/components/ui/layout/list-details-layout/partials/use-inspector-focus.d.ts +8 -0
  140. package/dist/lib/components/ui/layout/list-details-layout/partials/use-list-details-param.d.ts +26 -0
  141. package/dist/lib/components/ui/layout/list-details-layout/partials/use-list-details-state.d.ts +15 -0
  142. package/dist/lib/components/ui/layout/list-details-layout/partials/use-list-width.d.ts +16 -0
  143. package/dist/lib/components/ui/layout/list-details-layout/partials/use-pane-focus.d.ts +6 -4
  144. package/dist/lib/components/ui/layout/navigation-bar/index.d.ts +3 -0
  145. package/dist/lib/components/ui/layout/navigation-bar/internal.d.ts +4 -0
  146. package/dist/lib/components/ui/layout/navigation-bar/navigation-bar.classes.d.ts +14 -0
  147. package/dist/lib/components/ui/layout/navigation-bar/navigation-bar.d.ts +35 -0
  148. package/dist/lib/components/ui/layout/navigation-bar/navigation-bar.utils.d.ts +19 -0
  149. package/dist/lib/components/ui/layout/navigation-bar/partials/bar-badge.d.ts +5 -0
  150. package/dist/lib/components/ui/layout/navigation-bar/partials/bar-entry.d.ts +12 -0
  151. package/dist/lib/components/ui/layout/navigation-bar/partials/navigation-bar-item.d.ts +22 -0
  152. package/dist/lib/components/ui/layout/navigation-bar/partials/navigation-bar-more.d.ts +24 -0
  153. package/dist/lib/components/ui/layout/navigation-bar/use-nav-bar-inset.d.ts +12 -0
  154. package/dist/lib/components/ui/layout/navigation-drawer/index.d.ts +5 -0
  155. package/dist/lib/components/ui/layout/navigation-drawer/navigation-drawer.classes.d.ts +9 -0
  156. package/dist/lib/components/ui/layout/navigation-drawer/navigation-drawer.d.ts +45 -0
  157. package/dist/lib/components/ui/layout/navigation-drawer/navigation-drawer.utils.d.ts +14 -0
  158. package/dist/lib/components/ui/layout/navigation-drawer/partials/navigation-drawer-body.d.ts +3 -0
  159. package/dist/lib/components/ui/layout/navigation-drawer/partials/navigation-drawer-item.d.ts +20 -0
  160. package/dist/lib/components/ui/layout/navigation-drawer/partials/navigation-drawer-modal.d.ts +17 -0
  161. package/dist/lib/components/ui/layout/navigation-drawer/partials/navigation-drawer-section.d.ts +15 -0
  162. package/dist/lib/components/ui/layout/navigation-rail/index.d.ts +3 -0
  163. package/dist/lib/components/ui/layout/navigation-rail/navigation-rail-panel.d.ts +26 -0
  164. package/dist/lib/components/ui/layout/navigation-rail/navigation-rail.classes.d.ts +23 -0
  165. package/dist/lib/components/ui/layout/navigation-rail/navigation-rail.d.ts +42 -1
  166. package/dist/lib/components/ui/layout/navigation-rail/navigation-rail.utils.d.ts +4 -0
  167. package/dist/lib/components/ui/layout/navigation-rail/partials/navigation-rail-body.d.ts +3 -0
  168. package/dist/lib/components/ui/layout/navigation-rail/partials/navigation-rail-item.d.ts +20 -0
  169. package/dist/lib/components/ui/layout/navigation-rail/partials/navigation-rail-panel-item.d.ts +7 -0
  170. package/dist/lib/components/ui/layout/navigation-rail/partials/navigation-rail-toggle.d.ts +7 -0
  171. package/dist/lib/components/ui/layout/navigation-rail/use-rail-expanded.d.ts +13 -0
  172. package/dist/lib/components/ui/layout/navigation-toolbar/index.d.ts +2 -0
  173. package/dist/lib/components/ui/layout/navigation-toolbar/navigation-toolbar.classes.d.ts +20 -0
  174. package/dist/lib/components/ui/layout/navigation-toolbar/navigation-toolbar.d.ts +51 -0
  175. package/dist/lib/components/ui/layout/navigation-toolbar/partials/navigation-toolbar-item.d.ts +25 -0
  176. package/dist/lib/components/ui/layout/navigation-toolbar/partials/navigation-toolbar-more.d.ts +3 -0
  177. package/dist/lib/components/ui/layout/pane-layout/internal.d.ts +3 -0
  178. package/dist/lib/components/ui/layout/pane-layout/pane-layout.d.ts +16 -2
  179. package/dist/lib/components/ui/layout/pane-layout/partials/pane-layout-classes.d.ts +7 -0
  180. package/dist/lib/components/ui/layout/pane-layout/partials/pane-layout-context.d.ts +13 -0
  181. package/dist/lib/components/ui/layout/pane-layout/partials/use-pane-layout-state.d.ts +16 -0
  182. package/dist/lib/components/ui/layout/pane-layout/partials/use-pane-narrow.d.ts +6 -0
  183. package/dist/lib/components/ui/layout/responsive-grid/index.d.ts +4 -1
  184. package/dist/lib/components/ui/layout/responsive-grid/responsive-grid-item.d.ts +19 -0
  185. package/dist/lib/components/ui/layout/responsive-grid/responsive-grid-spans.d.ts +19 -0
  186. package/dist/lib/components/ui/layout/responsive-grid/responsive-grid.d.ts +24 -2
  187. package/dist/lib/components/ui/layout/responsive-grid/responsive-grid.utils.d.ts +12 -0
  188. package/dist/lib/components/ui/layout/settings-layout/index.d.ts +2 -0
  189. package/dist/lib/components/ui/layout/settings-layout/partials/settings-link.d.ts +7 -0
  190. package/dist/lib/components/ui/layout/settings-layout/partials/settings-list.d.ts +11 -0
  191. package/dist/lib/components/ui/layout/settings-layout/partials/settings-page.d.ts +5 -0
  192. package/dist/lib/components/ui/layout/settings-layout/settings-layout.d.ts +10 -0
  193. package/dist/lib/components/ui/layout/settings-layout/settings-layout.types.d.ts +33 -0
  194. package/dist/lib/components/ui/layout/settings-layout/settings-layout.utils.d.ts +13 -0
  195. package/dist/lib/components/ui/layout/thread-layout/thread-layout-classes.d.ts +17 -0
  196. package/dist/lib/components/ui/layout/thread-layout/thread-layout-parts.d.ts +14 -0
  197. package/dist/lib/components/ui/layout/thread-layout/thread-layout-stepper.d.ts +11 -0
  198. package/dist/lib/components/ui/layout/thread-layout/thread-layout.d.ts +30 -3
  199. package/dist/lib/components/ui/layout/top-nav/index.d.ts +5 -0
  200. package/dist/lib/components/ui/layout/top-nav/partials/top-nav-item.d.ts +23 -0
  201. package/dist/lib/components/ui/layout/top-nav/partials/top-nav-menu.d.ts +22 -0
  202. package/dist/lib/components/ui/layout/top-nav/top-nav.classes.d.ts +10 -0
  203. package/dist/lib/components/ui/layout/top-nav/top-nav.d.ts +34 -0
  204. package/dist/lib/components/ui/layout/top-nav/top-nav.utils.d.ts +10 -0
  205. package/dist/lib/components/ui/widgets/kanban/index.d.ts +1 -1
  206. package/dist/lib/components/ui/widgets/kanban/kanban-context.d.ts +5 -2
  207. package/dist/lib/components/ui/widgets/kanban/kanban.d.ts +11 -2
  208. package/dist/lib/components/ui/widgets/kanban/kanban.slice.d.ts +32 -0
  209. package/dist/lib/components/ui/widgets/kanban/kanban.utils.d.ts +9 -0
  210. package/dist/lib/components/ui/widgets/kanban/partials/kanban-card-preview.d.ts +3 -1
  211. package/dist/lib/components/ui/widgets/kanban/partials/kanban-column.d.ts +6 -0
  212. package/dist/lib/components/ui/widgets/kanban/partials/kanban-move-to.d.ts +13 -0
  213. package/dist/lib/components/ui/widgets/kanban/partials/kanban-phone-tabs.d.ts +10 -0
  214. package/dist/lib/components/ui/widgets/kanban/types.d.ts +7 -0
  215. package/dist/lib/components/ui/widgets/kanban/use-kanban-board-keys.d.ts +7 -0
  216. package/dist/lib/components/ui/widgets/kanban/use-kanban-item-actions.d.ts +5 -0
  217. package/dist/lib/components/ui/widgets/kanban/use-kanban-phone-column.d.ts +18 -0
  218. package/dist/lib/components/ui/widgets/kanban/use-kanban.d.ts +6 -1
  219. package/dist/lib/i18n/resources/en/en.d.ts +50 -0
  220. package/dist/lib/i18n/resources/en/material.json.d.ts +52 -2
  221. package/dist/lib/i18n/resources/fr/fr.d.ts +50 -0
  222. package/dist/lib/i18n/resources/fr/material.json.d.ts +52 -2
  223. package/dist/lib/i18n/resources/resources.d.ts +100 -0
  224. package/dist/lib/i18n/translator.d.ts +1 -1
  225. package/dist/lib.js +1 -1
  226. package/dist/main.js +52 -52
  227. package/dist/map.js +7 -7
  228. package/dist/material.css +1 -1
  229. package/dist/pdf-reader.js +1 -1
  230. package/dist/{percent-field--WIXV5dX.js → percent-field-C2LNr8NA.js} +1 -1
  231. package/dist/{picker-surface-CV09H7Nb.js → picker-surface-BUCFMoAZ.js} +4 -4
  232. package/dist/{popover-Cd7DkND4.js → popover-DFRwQF12.js} +1 -1
  233. package/dist/{pos-types-DKCkOTYy.js → pos-types-CXnEdjdy.js} +1 -1
  234. package/dist/{pos-variant-GrUfbTTP.js → pos-variant-DMwn_7is.js} +4 -4
  235. package/dist/print.js +1 -1
  236. package/dist/{programmer-variant-eKJNKENL.js → programmer-variant-Bo4eiDFi.js} +2 -2
  237. package/dist/{public-y6g4ddxd.js → public-CyQPkkSR.js} +9 -9
  238. package/dist/{rich-code-block-CRQ0iyLb.js → rich-code-block-iK7UcZdc.js} +5 -5
  239. package/dist/{scientific-variant-2y3UxAAU.js → scientific-variant-B9ScTgfx.js} +2 -2
  240. package/dist/{sortable-provider-DdiI3Fwk.js → sortable-provider-BZwVjSVU.js} +3 -3
  241. package/dist/{spinner-C1QIewWv.js → spinner-RITOxvpH.js} +2 -2
  242. package/dist/{tabs-KGKvve3y.js → tabs-DSo4eCUn.js} +1 -1
  243. package/dist/theme-picker.js +2 -2
  244. package/dist/{theme-toggle-C_VeiiCm.js → theme-toggle-3gbzQX0x.js} +1 -1
  245. package/dist/{toolbar-items-D310xDuM.js → toolbar-items-Bt5RK-Nx.js} +4 -4
  246. package/dist/{translate-material-BypJJ1l5.js → translate-material-CZTGqgen.js} +1 -1
  247. package/dist/{translator-DJkf4J7t.js → translator-DTlOlIoq.js} +108 -4
  248. package/dist/{use-chat-composer-BFhRMHcX.js → use-chat-composer-DBY01IpX.js} +16 -16
  249. package/dist/{use-heading-spy-DJR8YYm6.js → use-heading-spy-Dt48bBts.js} +4 -4
  250. package/dist/{use-material-translation-CD6QoVal.js → use-material-translation-BJucC_xe.js} +1 -1
  251. package/dist/{use-return-focus-Cevw_6yq.js → use-return-focus-BS1JLcnq.js} +1 -1
  252. package/docs/README.md +1 -0
  253. package/docs/components/data-display.md +4 -0
  254. package/docs/components/data-table-filter-and-lists.md +2 -0
  255. package/docs/components/navigation-and-layout.md +944 -27
  256. package/docs/components/rich-widgets.md +26 -0
  257. package/docs/guides/app-shell.md +641 -2
  258. package/docs/guides/i18n.md +13 -1
  259. package/docs/guides/layouts.md +215 -0
  260. package/docs/guides/ssr.md +1 -1
  261. package/docs/previews/navigation-layout-appshell-page-ground.webp +0 -0
  262. package/docs/previews/navigation-layout-appshell.webp +0 -0
  263. package/docs/previews/navigation-layout-authcard-split.webp +0 -0
  264. package/docs/previews/navigation-layout-authcard.webp +0 -0
  265. package/docs/previews/navigation-layout-dashboardgrid.webp +0 -0
  266. package/docs/previews/navigation-layout-editorlayout.webp +0 -0
  267. package/docs/previews/navigation-layout-landinglayout.webp +0 -0
  268. package/docs/previews/navigation-layout-panelayout.webp +0 -0
  269. package/docs/previews/navigation-layout-settingslayout.webp +0 -0
  270. package/docs/previews/navigation-layout-threadlayout-pages.webp +0 -0
  271. package/docs/previews/navigation-layout-threadlayout.webp +0 -0
  272. package/docs/roadmap.md +10 -2
  273. package/lib/components/components.css +3 -0
  274. package/lib/components/ui/actions/fab/fab-dock.css +19 -6
  275. package/lib/components/ui/layout/app-search/app-search.css +62 -0
  276. package/lib/components/ui/layout/app-shell/activity-backdrop.css +10 -2
  277. package/lib/components/ui/layout/app-shell/app-header.css +108 -0
  278. package/lib/components/ui/layout/navigation-toolbar/navigation-toolbar.css +43 -0
  279. package/package.json +1 -1
@@ -211,6 +211,8 @@ partitionMenu(items); // { content, footer }
211
211
  | `align` | `'start' \| 'center'` | `'start'` | Where the collapsed rail's entries sit: right under the brand, or centred in the height below it |
212
212
  | `menuOpen` | `boolean` | — | Controls the phone's menu sheet: open while `true`. Leave it out and the layout manages the sheet. Only a phone shows the sheet |
213
213
  | `onMenuOpenChange` | `(open: boolean) => void` | — | Called for every change of the sheet: the menu button, Escape, the close button, a followed link, a new location |
214
+ | `navigation` | `ShellNavigation \| { phone?, tablet?, desktop?, hideOnScroll?, persistKey? }` | `modal-drawer` / `rail` / `rail` | The navigation per window size; see [`navigation` and `header`](#navigation-and-header) |
215
+ | `header` | `'small' \| 'center' \| 'medium' \| 'large' \| 'none' \| { variant, collapse?, hideOnScroll?, tabs?, search? }` | `'small'` | The app bar's size, overridable per route with `handle.header`; see [The app bar variants](#the-app-bar-variants) |
214
216
  | `backdrop` | `ReactNode \| false` | — | An exception to the theme's background (the page ground, [`--ground`](#the-page-ground), is painted either way), which the layout draws by default (Lavande's: the built-in gradient and blobs). A node replaces it for this screen: usually a `Background` preset from `@nxgt/material/backgrounds` (see [Use a background preset behind the shell](#use-a-background-preset-behind-the-shell)); `false` draws no background, a plain page |
215
217
  | `keepClear` | `boolean \| 'gaps'` | `true` | how the backdrop's glyphs keep clear of the page: `true` drops every glyph within 8px of a surface, a text or a control; `'gaps'` also keeps a glyph that fits in a gap of 24px or more between two surfaces; `false` keeps nothing clear (the edge and the header band still are). See [Keep the backdrop clear of the content](#keep-the-backdrop-clear-of-the-content) |
216
218
 
@@ -311,9 +313,573 @@ confirmation inside the menu) is the top layer: it takes the first Escape alone,
311
313
  and the second closes the sheet. A leave confirmation raised by a followed link
312
314
  comes after the sheet has closed: the sheet stays closed, "Stay" included.
313
315
 
316
+ ### `navigation` and `header`
317
+
318
+ `ActivityLayout` takes two props that choose how the shell's navigation and
319
+ header are drawn. Both are optional, and unset they are what the shell draws
320
+ today: the menu sheet on a phone, the rail from `md`, a small header.
321
+
322
+ ```tsx
323
+ <ActivityLayout items={items} navigation="rail" header="small">
324
+ <Outlet />
325
+ </ActivityLayout>
326
+
327
+ // one preset per window size
328
+ <ActivityLayout
329
+ items={items}
330
+ navigation={{ phone: 'modal-drawer', tablet: 'rail', desktop: 'rail' }}
331
+ header={{ variant: 'small' }}
332
+ >
333
+ <Outlet />
334
+ </ActivityLayout>
335
+ ```
336
+
337
+ - `navigation`: a `ShellNavigation` name for every size, or an object
338
+ `{ phone, tablet, desktop, hideOnScroll, persistKey }`; `persistKey` is a
339
+ field of that object (it keeps the `'rail-expanded'` rail's, the
340
+ `'sidebar'`'s and the `'two-level'` panel's state); `hideOnScroll` is another
341
+ (`false` by default; it slides the `'floating'` toolbar away on scroll). The sizes are a phone below `md` (768px), a tablet from
342
+ 768px to 1279px and a desktop from `xl` (1280px). A name alone applies to
343
+ every size, except `'sidebar'`, `'drawer'`, `'top'` and `'two-level'`, which it draws from the
344
+ tablet size only: the phone keeps its default navigation unless the object asks for
345
+ it (`{ phone: 'sidebar' }`). `'bar'` and `'floating'` are phone navigations: a
346
+ name alone draws them at every size, the phone included. Every name is drawn:
347
+ `'modal-drawer'`, `'rail'`, `'rail-expanded'`, `'drawer'`, `'sidebar'`, `'top'`,
348
+ `'two-level'`, `'floating'`, `'bar'` and `'none'`.
349
+ - `header`: `'small'`, `'center'`, `'medium'`, `'large'` or `'none'`, or
350
+ `{ variant, collapse, hideOnScroll, tabs, search }`. The five variants and
351
+ `hideOnScroll` are drawn (see [The app bar variants](#the-app-bar-variants));
352
+ `search` and `tabs` are drawn (see [The app bar's search](#the-app-bars-search) and
353
+ [Tabs under the app bar](#tabs-under-the-app-bar)). A route's `handle.back` draws a
354
+ back arrow ([The back arrow](#the-back-arrow)).
355
+
356
+ An object's `phone` that names a preset never drawn on a phone (`rail`, `rail-expanded`, `top`, `two-level`) resolves to the default, as a name alone does.
357
+
358
+ `resolveNavigation()` and `resolveHeader()` return the full settings for a
359
+ value (what the props resolve to), and `navigationClasses()` the classes that
360
+ show each preset only at the sizes it is configured for. `DEFAULT_NAVIGATION` is
361
+ the default value (`modal-drawer`, `rail`, `rail`).
362
+
363
+ `MenuItem` also accepts `children`, `group`, `bar` and `priority`. Each is read
364
+ by the presets that use it, and ignored by the others: `bar` and `priority`
365
+ choose the entries of the bottom bar **and** of the floating toolbar (the rest go
366
+ under « More »), `group` is read by the drawer, and `children` by the top
367
+ navigation, the two-level panel, the sidebar and the phone's menu sheet.
368
+ `footer` is read by the rail, the sidebar and the drawer (its footer), `display`
369
+ by the rail, the sidebar and the phone's menu sheet, and `badge` and `badgeLabel`
370
+ by every preset that draws entries, except on a `display: 'icon'` entry.
371
+
372
+ ### The bottom bar (`navigation="bar"`)
373
+
374
+ `navigation="bar"` alone is phone-only: the bar is hidden from 768px, where the
375
+ default rail shows (`{ tablet: 'bar' }` keeps it there).
376
+
377
+ ```tsx
378
+ // a bar on the phone, the rail from 768px
379
+ <ActivityLayout
380
+ items={[
381
+ { label: 'Home', url: '/', icon: 'house' },
382
+ { label: 'Inbox', url: '/inbox', icon: 'envelope', badge: 3 },
383
+ { label: 'Tasks', url: '/tasks', icon: 'check', badge: true },
384
+ { label: 'Files', url: '/files', icon: 'folder' },
385
+ { label: 'Settings', url: '/settings', icon: 'gear', priority: -1 },
386
+ ]}
387
+ navigation={{ phone: 'bar' }}
388
+ >
389
+ <Outlet />
390
+ </ActivityLayout>
391
+ ```
392
+
393
+ The bar is a `nav` named "Navigation" (`material.app-shell.navigation`) pinned
394
+ to the bottom edge, clear of the home indicator. It shows 3 to 5 destinations,
395
+ each an icon in an indicator pill with its label always visible, `aria-current="page"`
396
+ on the current one and a target of 48px or more. A `badge` shows as a dot or a
397
+ count on the icon and is read in the link's name ("Inbox, 3 new").
398
+
399
+ - **Which entries.** Up to five fit when they all do; with more, the bar keeps
400
+ four and "More" takes the fifth slot. `bar: true` on some entries limits the bar to
401
+ them, `bar: false` keeps one off it, and `priority` (higher stays, unset is 0)
402
+ chooses among the rest; ties keep the menu's order. `splitBarItems(items, max)`
403
+ returns `{ bar, more }`.
404
+ - **More.** A button that opens a sheet from the bottom with the other entries
405
+ (`material.navigation.more`, closed by Escape, the "Close" button
406
+ (`material.navigation.close`) or a followed link). Focus returns to the button;
407
+ after a followed link it goes to the page's title as for the menu sheet. It
408
+ lights up when the current page is one of its entries.
409
+ - **Breakpoints.** The bar and the rail are both in the markup and CSS classes
410
+ show one per size, so a server render matches the client. A hidden bar is
411
+ `display: none`: out of the tab order and the accessibility tree. With the
412
+ bar on the phone the app bar has no menu button.
413
+ - **Room.** While it shows, the bar sets `--nxgt-nav-bar` (`calc(4rem + env(safe-area-inset-bottom))`,
414
+ the safe area included) on the document root as long as any bar shows (it stays while a second
415
+ bar remains), and the shell's frame clears
416
+ `--nxgt-bottom-chrome`; with no bar the shell's markup is unchanged.
417
+
418
+ Use it by hand with `<NavigationBar items={items} />` (needs a router context)
419
+ and hide it with a breakpoint class such as `md:hidden`; compose entries with
420
+ `<NavigationBar.Item href icon badge>Label</NavigationBar.Item>`. The variable
421
+ is set after mount: a server render and the first paint get the room from the
422
+ layout root's breakpoint class, and portals (the toaster) read the variable on
423
+ the document root once the effect has run. A layout without `items` draws no bar.
424
+
425
+ ### The wide rail (`navigation="rail-expanded"`)
426
+
427
+ ```tsx
428
+ import { ActivityLayout, Fab, Icon } from '@nxgt/material/components';
429
+
430
+ // the wide rail from 768px, a bar on the phone
431
+ <ActivityLayout
432
+ items={items}
433
+ navigation={{ phone: 'bar', tablet: 'rail-expanded', persistKey: 'app-rail' }}
434
+ navigationFab={({ expanded }) => (
435
+ <Fab extended collapsed={!expanded} icon={<Icon name="plus" />} label="Compose" />
436
+ )}
437
+ >
438
+ <Outlet />
439
+ </ActivityLayout>
440
+ ```
441
+
442
+ `'rail'` stays the collapsed sidebar rail the shell has always drawn (it is
443
+ the default, so its markup does not change). `'rail-expanded'` draws
444
+ [`NavigationRail`](../components/navigation-and-layout.md#navigationrail)
445
+ instead: a `nav` named "Navigation" with the menu button, the optional FAB, a
446
+ link per entry (icon in an indicator pill, label, badge read in the link's
447
+ name) and the `footer` entries at the bottom. It starts expanded (15rem) and the
448
+ menu button narrows it to 5rem, labels under the icons.
449
+
450
+ - **FAB.** `navigationFab` is the screen's primary action, a node or a function
451
+ of `{ expanded }` to pass an extended `Fab` that folds to its icon. The other
452
+ presets do not draw it. `navigationFab` is drawn only by `'rail-expanded'`; the other presets ignore it.
453
+ - **Remembering the choice.** With `navigation.persistKey` the state is kept in
454
+ the browser's local storage and read after hydration, so a server render and
455
+ the first client render agree; without it the rail starts expanded each time.
456
+ - **On a phone.** A phone never draws `'rail-expanded'` (or `'rail'`): it keeps
457
+ its menu sheet, or `'bar'`.
458
+ - **Breakpoints.** Both rails and the bar are in the markup and CSS classes show
459
+ one per size (`display: none` elsewhere, so a hidden rail is out of the tab order
460
+ and the accessibility tree). A layout without `items` draws no wide rail.
461
+ - **Motion.** The width and the indicator ease unless the user prefers reduced
462
+ motion.
463
+
464
+ ### The drawer and the collapsible sidebar
465
+
466
+ ```tsx
467
+ // the phone's menu sheet, the collapsible sidebar from 768px, remembered
468
+ <ActivityLayout
469
+ items={items}
470
+ navigation={{ tablet: 'sidebar', desktop: 'sidebar', persistKey: 'app-nav' }}
471
+ >
472
+ <Outlet />
473
+ </ActivityLayout>
474
+
475
+ // the permanent drawer on a wide desktop
476
+ <ActivityLayout items={items} navigation={{ desktop: 'drawer' }}>
477
+ <Outlet />
478
+ </ActivityLayout>
479
+ ```
480
+
481
+ - **`'drawer'`** draws the standard (permanent) drawer,
482
+ [`NavigationDrawer`](../components/navigation-and-layout.md#navigationdrawer),
483
+ 20rem wide, instead of the rail at that size: a `nav` named "Navigation"
484
+ with the entries in sections by their `group`, the `footer` entries at the
485
+ bottom, the brand above. The modal variant is the phone's menu sheet
486
+ (`'modal-drawer'`, unchanged).
487
+ - **`'sidebar'`** draws the shell's sidebar, collapsed to the rail of icons at
488
+ first. A small chevron button on its end edge, level with the brand and with
489
+ no row of its own, expands it (logo and name, labels beside the icons) and
490
+ collapses it again; it is named "Toggle sidebar", carries `aria-expanded` and
491
+ `aria-controls`, has a 48px hit area, and the chevron turns (unless the user
492
+ prefers reduced motion). The state is `sidebarExpanded` (controlled) or
493
+ `defaultSidebarExpanded` (`false`), reported by `onSidebarExpandedChange`.
494
+ With `navigation.persistKey` the user's last choice is kept in the browser's
495
+ local storage and read after hydration, so a server render and the first
496
+ client render agree; a blocked storage is ignored.
497
+ - Both are in the markup with the other presets and CSS classes show one per
498
+ size (`display: none` elsewhere, out of the tab order and the accessibility
499
+ tree). They need `items`; a layout without any draws no drawer. The unset
500
+ `navigation` still draws the collapsed rail, so existing apps are unchanged.
501
+ On a phone they are drawn only when asked by size (`{ phone: 'drawer' }`),
502
+ taking 16 to 20rem beside the content: keep the menu sheet or a bar there.
503
+
504
+ ### The top navigation
505
+
506
+ ```tsx
507
+ // the brand and a bar of destinations in the app header from 768px;
508
+ // the phone keeps its menu sheet, with the children nested
509
+ <ActivityLayout
510
+ items={[
511
+ { label: 'Home', url: '/', icon: 'house' },
512
+ {
513
+ label: 'Projects',
514
+ url: '/projects',
515
+ icon: 'folder',
516
+ children: [
517
+ { label: 'All projects', url: '/projects/all', icon: 'folder' },
518
+ { label: 'Archived', url: '/projects/archived', icon: 'box-archive' },
519
+ ],
520
+ },
521
+ ]}
522
+ name="Acme"
523
+ navigation="top"
524
+ >
525
+ <Outlet />
526
+ </ActivityLayout>
527
+ ```
528
+
529
+ - **`'top'`** draws [`TopNav`](../components/navigation-and-layout.md#topnav)
530
+ in the app header, after the brand (`brand`, else `logo` and `name`: no rail
531
+ carries it then): a `nav` named "Navigation" of 48px pills, the current one
532
+ tinted with `aria-current="page"`. An entry with `children` is a button that
533
+ opens a dropdown of its child links; when the current page is one of them,
534
+ the button reads as active and the child carries `aria-current`. Arrow keys,
535
+ Escape and focus return follow Radix's navigation menu, and the dropdown's
536
+ motion is off for users who prefer reduced motion. A badge is read in the
537
+ link's name.
538
+ - On a phone the bar is not drawn, whatever the object says
539
+ (`{ phone: 'top' }` keeps the menu sheet): the sheet lists the entries and
540
+ nests each entry's `children` under it, indented. The expanded sidebar nests
541
+ them the same way.
542
+ - An entry with `children` is only a trigger: its `url` is never a link, so put an "all" link as the first child. (The phone's menu sheet and the expanded sidebar do list the
543
+ parent's own `url` as a link, with its children nested under it.)
544
+ - Past about 5 entries the bar does not fit at 768px beside the brand and the title and pushes the header's actions out; it does not scroll (that would clip the dropdowns). Use `{ tablet: 'rail', desktop: 'top' }` for a longer menu.
545
+ - It shows per size with CSS classes like the other presets, so the server and
546
+ the browser agree. It needs `items`; the `footer`, `group` and `display`
547
+ options are not used. The unset `navigation` is unchanged.
548
+
549
+ ### The two-level navigation
550
+
551
+ ```tsx
552
+ // a rail of the top-level entries and, beside it, a panel of the current
553
+ // entry's children, from 768px; the phone keeps its menu sheet
554
+ <ActivityLayout
555
+ items={[
556
+ { label: 'Home', url: '/', icon: 'house' },
557
+ {
558
+ label: 'Projects',
559
+ url: '/projects',
560
+ icon: 'folder',
561
+ children: [
562
+ { label: 'Overview', url: '/projects', icon: 'folder' },
563
+ { label: 'Active', url: '/projects/active', icon: 'folder' },
564
+ { label: 'Archived', url: '/projects/archived', icon: 'box-archive' },
565
+ ],
566
+ },
567
+ ]}
568
+ navigation={{ tablet: 'two-level', desktop: 'two-level', persistKey: 'app-nav' }}
569
+ >
570
+ <Outlet />
571
+ </ActivityLayout>
572
+ ```
573
+
574
+ - **`'two-level'`** draws [`NavigationRail`](../components/navigation-and-layout.md#navigationrail)
575
+ (the top-level entries, 5rem wide, no menu button of its own) and
576
+ [`NavigationRailPanel`](../components/navigation-and-layout.md#navigationrailpanel)
577
+ (14rem) side by side in one lane, bled to the frame's edges like the other
578
+ lanes. The app's brand tops the rail's column: `brand`, else `logo` alone (named by
579
+ `name`).
580
+ - **A rail entry always links to its own `url`**, with or without `children`:
581
+ following it navigates there, and the panel shows that entry's children
582
+ (an entry is the section the location belongs to when its `url` or one of its
583
+ children's matches; the most specific match wins, so a child outside the
584
+ parent's `url` still lights its parent). Put the section's overview at the
585
+ parent's `url`, and as a first child with the same `url` if you want it listed:
586
+ that child is marked current there.
587
+ - **The panel is open by default and collapsible.** Its button folds it to a
588
+ narrow strip and back; nothing opens it on hover, and a rail entry does not
589
+ reopen it. With `navigation.persistKey` the choice is remembered under
590
+ `nxgt-panel:<persistKey>` (the rail's `'rail-expanded'` state and the sidebar's
591
+ keep their own prefixes), read after hydration: the server render and the first
592
+ client render are open.
593
+ - **An entry without `children`** just navigates; the panel is hidden by CSS for
594
+ it (its markup stays, so the tree does not change between routes). Only one
595
+ level of `children` is listed.
596
+ - **On a phone** neither is drawn, whatever the object says
597
+ (`{ phone: 'two-level' }` keeps the menu sheet, as `'top'` does): the sheet lists
598
+ the entries and nests each one's `children`. A name alone leaves the phone its
599
+ default.
600
+ - At 768px the rail and the open panel take 19rem beside the content; fold the
601
+ panel or use `{ tablet: 'rail', desktop: 'two-level' }` when that is too much.
602
+ It needs `items` (none draws nothing); `footer` entries sit at the rail's
603
+ bottom, `group` and `display` are not used. The unset `navigation` is unchanged.
604
+
605
+ ### The floating navigation toolbar
606
+
607
+ ```tsx
608
+ import { ActivityLayout } from '@nxgt/material/components';
609
+ import { Outlet } from 'react-router';
610
+
611
+ // a floating pill on the phone, the rail from 768px, hiding while the page scrolls down
612
+ <ActivityLayout
613
+ items={[
614
+ { label: 'Home', url: '/', icon: 'house' },
615
+ { label: 'Inbox', url: '/inbox', icon: 'envelope', badge: 3 },
616
+ { label: 'Tasks', url: '/tasks', icon: 'check' },
617
+ { label: 'Files', url: '/files', icon: 'folder' },
618
+ { label: 'Settings', url: '/settings', icon: 'gear', priority: -1 },
619
+ ]}
620
+ navigation={{ phone: 'floating', hideOnScroll: true }}
621
+ >
622
+ <Outlet />
623
+ </ActivityLayout>
624
+ ```
625
+
626
+ [`NavigationToolbar`](../components/navigation-and-layout.md#navigationtoolbar) is
627
+ a pill of round icon links at the bottom centre, over the content. It is a `nav`
628
+ named "Navigation" (`material.app-shell.navigation`) of links, each named by a
629
+ visually hidden label (and a tooltip), with `aria-current="page"` on the
630
+ current one: it is not a `role="toolbar"`, which is for actions (use
631
+ `Toolbar variant="floating"` for those). It wears the same pill as that toolbar
632
+ (its tokens, shadow and slide away), so a themed toolbar gives a themed pill.
633
+
634
+ - **Where it shows.** A name alone (`navigation="floating"`) draws it at every
635
+ size, the phone included, like `'bar'`: the pill is a bar-like phone
636
+ navigation, and on a phone it replaces the menu sheet, so the app bar has no
637
+ menu button. `{ phone: 'floating' }` limits it to the phone, `{ desktop: 'floating' }`
638
+ to the desktop. Pill and rail are both in the markup and breakpoint classes show
639
+ one per size, so a server render matches the client.
640
+ - **Which entries.** The same rules as the bottom bar: 3 to 5 destinations,
641
+ `bar`, `priority` and `splitBarItems` choose them, and with more the last slot
642
+ is « More » (the bar's bottom sheet, lit when the current page is under it).
643
+ Keep to 3-5 destinations; without a fifth slot to spare, mark the secondary
644
+ ones `priority: -1` so they live under « More ». No entry is lost: nothing is
645
+ reachable only from a hidden place.
646
+ - **Hide on scroll is off by default.** `navigation.hideOnScroll: true` slides the
647
+ pill away on the way down (past 64px, after 8px of movement) and back on the
648
+ way up, reading the shell's scroll ([Scroll direction](#scroll-direction)). While away it is
649
+ `inert` (out of the tab order and the accessibility tree), and a focus inside
650
+ it moves to the content region and returns to its link when the pill is back,
651
+ unless the user went elsewhere meanwhile. With reduced motion it snaps instead
652
+ of sliding. `hideOnScroll` reads no other preset; the header's own
653
+ `hideOnScroll` is separate. The server draws it shown.
654
+ - **Room.** The pill is `1rem` above the safe area; a docked media bar sits above it (the dock rests at `var(--nxgt-nav-bar)`). While
655
+ it shows it sets `--nxgt-nav-bar` to `calc(5rem + env(safe-area-inset-bottom))` (4rem of pill, the gap and the safe area), also
656
+ while slid away, so `FabDock`, the toaster, the mini player and a sticky
657
+ `StickyActionBar` stay above it and nothing jumps when it returns; the shell's
658
+ frame clears `--nxgt-bottom-chrome` as for the bar. The first paint gets the
659
+ value from a class on the layout root, as the bar does. The pill does not rise
660
+ with the on-screen keyboard: it stays at the bottom of the layout viewport.
661
+ - It needs `items` (none draws nothing) and a router context. Use it by hand with
662
+ `<NavigationToolbar items={items} />` (hide it with a breakpoint class such as
663
+ `md:hidden`) or compose entries with `<NavigationToolbar.Item href icon>Label</NavigationToolbar.Item>`.
664
+
665
+ ### Scroll direction
666
+
667
+ `useShellScroll()` returns `{ direction, offset, reducedMotion }` for a bar
668
+ that hides while scrolling down: `direction` is `'down'`, `'up'` or `'none'`
669
+ (at the top), and flips only after 8px of movement the other way. Wrap the part
670
+ that reads it in `ShellScrollProvider` (it is `useScrollTracker()`, the hook
671
+ behind it, in a context; use `ShellScrollContext` to provide your own state); give it `container` (a ref to the
672
+ scrolling box) when the content region scrolls (`scroll="container"`), none for
673
+ the window. Outside a provider the hook is idle. `reducedMotion` is true when
674
+ the user asked for less motion: skip the slide and snap. The header
675
+ (`header.hideOnScroll`) and the floating navigation toolbar
676
+ (`navigation.hideOnScroll`) read it; the shell tracks the scroll only when one of
677
+ them asks, and `NavigationToolbar` reads it by hand too.
678
+
679
+ ### The app bar variants
680
+
681
+ `header` chooses the bar's size, the way Material 3 does. Unset is `'small'`:
682
+ today's one row, byte for byte.
683
+
684
+ ```tsx
685
+ import { ActivityLayout, type AppShellHandle } from '@nxgt/material/components';
686
+
687
+ <ActivityLayout items={items} header="large">
688
+ <Outlet />
689
+ </ActivityLayout>
690
+
691
+ // a route opts in, whatever the layout says
692
+ export const handle = { title: 'Projects', header: 'large' } satisfies AppShellHandle;
693
+
694
+ // a bar that goes away on the way down
695
+ <ActivityLayout items={items} header={{ variant: 'small', hideOnScroll: true }} />
696
+ ```
697
+
698
+ Defaults: `variant` is `'small'`; `collapse` is `true` for `'medium'` and
699
+ `'large'`; `hideOnScroll` is `false`. Nothing to import beyond `styles.css`: the
700
+ bar's CSS ships with it.
701
+
702
+ - `'small'`: one row, the title beside the actions.
703
+ - `'center'`: the title centred in the room between the menu button and the
704
+ actions.
705
+ - `'medium'` and `'large'`: the page's title on a second row, in display type
706
+ (`large` is taller and bigger, up to two lines), under the small row. As the
707
+ page scrolls the headline fades and the bar shrinks into the small row, which
708
+ then shows the title (a copy hidden from assistive technology). `collapse:
709
+ false` keeps the headline however far the page scrolls.
710
+ - `'none'`: no bar. The screen's own `ActivityContent` title is then the page's
711
+ `h1`; the phone's menu button goes with the bar, so pair it with a navigation
712
+ that has one on its own (`navigation="bar"`).
713
+ - `hideOnScroll`: the bar slides away while the page scrolls down (past 64px) and
714
+ comes back on the way up. While away it is `inert` and out of the tab order; if
715
+ the focus was inside it, the focus moves to the content region.
716
+
717
+ A route gives its own through `handle.header` (a variant or the options, like
718
+ the prop). The deepest route that declares one wins, and its options win over
719
+ the layout's one by one: a route that only names a variant keeps the layout's
720
+ `hideOnScroll`. It is read from the matched routes, so the server and the
721
+ browser draw the same bar.
722
+
723
+ The headline **is** the page's one `h1` (the small row's copy is `aria-hidden`).
724
+ A medium or large header needs a title in the bar, a route's `handle.title`;
725
+ without one the bar stays small, so nothing changes for a screen that titles
726
+ itself with `ActivityContent`. The server always renders the bar expanded and
727
+ shown; the browser then follows the scroll.
728
+
729
+ The scroll is the shell's ([Scroll direction](#scroll-direction)): the window,
730
+ or the content region with `scroll="container"` (a hidden bar then gives its
731
+ room back). Once per animation frame the bar sets one CSS variable on itself,
732
+ `--nxgt-header-progress` (0 expanded, 1 collapsed), through `setProperty`, so
733
+ no inline style reaches the markup; the sizes are CSS in `app-header.css`.
734
+ Under reduced motion the bar snaps between the two states halfway, with no slide.
735
+ A plain shell, with no collapsing or hiding bar, tracks no scroll at all.
736
+
737
+ `AppHeader` takes the same as props (`variant`, `collapse`, `hideOnScroll`, the
738
+ `headline` node, `tabs` (a node, default none) and `back` (a `ShellBack`,
739
+ default none); see [Using the parts](#using-the-parts)), and so does `TopAppBar` (`variant`, `headline`) for a bar
740
+ of your own. Known limits: a hidden bar in a `scroll="container"` shell that is
741
+ barely taller than its container can flicker at the very bottom (the region
742
+ grows, so the scroll clamps); the scroll-driven CSS animation enhancement is not
743
+ used, the JavaScript path drives every browser.
744
+
745
+ ### The app bar's search
746
+
747
+ `header.search` puts an `AppSearchBar` after the title: `true` for a bare one,
748
+ or its props. From 768px it is a pill with the results in a docked panel; on a
749
+ phone a search button opens a full-screen dialog (`SearchView`). Unset (the
750
+ default) there is no search, and the bar is the same markup as before.
751
+
752
+ ```tsx
753
+ import { ActivityLayout } from '@nxgt/material/components';
754
+
755
+ <ActivityLayout
756
+ items={items}
757
+ header={{
758
+ variant: 'small',
759
+ search: { placeholder: 'Search projects', shortcut: '/', onSubmit: (q) => navigate(`/search?q=${q}`) },
760
+ }}
761
+ />
762
+
763
+ // a route turns it off, or changes it, like the other options
764
+ export const handle = { title: 'Settings', header: { variant: 'small', search: false } };
765
+ ```
766
+
767
+ The search never changes the shape of the page: the content stays mounted when
768
+ a route adds or drops it. A route's `search` replaces the layout's whole object
769
+ (its props are not merged). The props, the keyboard and the focus rules are in
770
+ [`AppSearchBar`](../components/navigation-and-layout.md#appsearchbar).
771
+
772
+ ### Tabs under the app bar
773
+
774
+ `header.tabs` is a node, normally a `TabsNav` (route links), drawn as a 48px row
775
+ at the foot of the bar. It is part of the bar: under a `medium` or `large` header
776
+ it stays under the small row as the headline collapses, and with `hideOnScroll`
777
+ the bar slides away **but the tabs stay pinned at the top of the window**
778
+ (Material 3's behaviour for a bar with tabs: the title row goes, the tabs stay
779
+ within reach). Only the bar's rows are `inert` while they are away; the tabs keep
780
+ the focus if they had it. The default is none: no row, and the bar is the same
781
+ markup as before. A `'none'` header draws none.
782
+
783
+ ```tsx
784
+ // layout.tsx: tabs on every route
785
+ import { ActivityLayout, type MenuItem, TabsNav, TabsNavLink } from '@nxgt/material/components';
786
+
787
+ const tabs = (
788
+ <TabsNav aria-label="Project sections" value="activity">
789
+ <TabsNavLink to="/projects/overview" value="overview">Overview</TabsNavLink>
790
+ <TabsNavLink to="/projects/activity" value="activity">Activity</TabsNavLink>
791
+ </TabsNav>
792
+ );
793
+
794
+ export function Layout({ items }: { items: MenuItem[] }) {
795
+ return <ActivityLayout items={items} header={{ variant: 'small', tabs }} />;
796
+ }
797
+ ```
798
+
799
+ ```tsx
800
+ // routes/project.tsx: tabs on this route only, or none
801
+ import { type AppShellHandle, TabsNav, TabsNavLink } from '@nxgt/material/components';
802
+
803
+ const projectTabs = (
804
+ <TabsNav aria-label="Atlas sections" value="board">
805
+ <TabsNavLink to="/projects/atlas/board" value="board">Board</TabsNavLink>
806
+ <TabsNavLink to="/projects/atlas/files" value="files">Files</TabsNavLink>
807
+ </TabsNav>
808
+ );
809
+
810
+ export const handle = {
811
+ title: 'Atlas',
812
+ header: { variant: 'small', tabs: projectTabs }, // tabs: null drops the layout's
813
+ } satisfies AppShellHandle;
814
+ ```
815
+
816
+ The option is `header.tabs` (there is no `handle.headerTabs`): a route's `tabs`
817
+ replaces the layout's whole, `tabs: null` drops them for that route, and a route
818
+ that only names a variant keeps the layout's. The row's height is one CSS
819
+ variable, `--nxgt-header-tabs` (3rem, in `app-header.css`). The bar's whole
820
+ height (the row, a headline row and the tabs) is `--nxgt-header-total` on the
821
+ `ActivityLayout` root, measured with a `ResizeObserver` (worked out in CSS from
822
+ the variant and tabs before script runs, from `data-header="medium|large"`, set only when the bar has a headline, and `data-header-tabs` on that root); the sticky aside and `Doc` stick below it. Give the `TabsNav` an
823
+ `aria-label` and its `value`, as it asks; a long list scrolls sideways in its
824
+ own row, never the page. The content stays mounted when a route adds or drops
825
+ the tabs; the bar's own row is drawn again then (as it is when a route moves to or
826
+ from a `medium` or `large` header), so an uncontrolled search loses its text.
827
+
828
+ ### The back arrow
829
+
830
+ A route's `handle.back` draws an arrow at the start of the app bar, 48px, named
831
+ `Back` or `Back to <label>` (`material.app-header.back`, default text "Back", and
832
+ `back-to`, default "Back to {label}"). It is read from the matched routes like
833
+ `handle.header`: the deepest route that declares one wins, and a route without it
834
+ has none. The type is `ShellBack`, which `AppShellHandle['back']` uses:
835
+ `import type { ShellBack } from '@nxgt/material/components'`.
836
+
837
+ ```tsx
838
+ // routes/project.tsx
839
+ import type { AppShellHandle } from '@nxgt/material/components';
840
+
841
+ export const handle = {
842
+ title: 'Atlas redesign',
843
+ back: { to: '/projects', label: 'Projects' },
844
+ } satisfies AppShellHandle;
845
+ ```
846
+
847
+ ```tsx
848
+ // routes/file.tsx: history back; the page above when the visit started here
849
+ import type { AppShellHandle } from '@nxgt/material/components';
850
+
851
+ export const handle = { title: 'File', back: true } satisfies AppShellHandle;
852
+ ```
853
+
854
+ - `{ to, label? }` is a link drawn with the shell's `linkComponent` (React
855
+ Router's `Link` by default), so it opens in a new tab and shows its address.
856
+ - `true` is a button: it goes back in the history when the visit has a previous
857
+ entry, and otherwise (a deep link, a reload) goes up one level of the URL, so the
858
+ arrow never leaves the app. It works under a router `basename`.
859
+ - The arrow comes first in the bar, before the top navigation and the title. On a
860
+ phone that has the menu sheet (the default) the menu button follows the arrow,
861
+ so the route is never a dead end; a phone with the bottom bar
862
+ (`navigation={{ phone: 'bar' }}`) has no menu button, so the arrow is first
863
+ and the bar navigates. From 768px the rail or sidebar stays.
864
+ - The arrow mirrors in right-to-left. The content stays mounted when a route adds
865
+ or drops it, and so does the bar's row (the menu button and the search keep their
866
+ state).
867
+
868
+ ### Room at the bottom
869
+
870
+ `--nxgt-nav-bar` is the room of a bottom navigation bar (4rem plus the bottom
871
+ safe-area inset) or of the floating navigation toolbar with its gap (5rem plus
872
+ the inset); 0 when there is none. It already holds the safe area: a consumer
873
+ clears `max(env(safe-area-inset-bottom), var(--nxgt-nav-bar, 0px))` once and
874
+ never adds the inset again. `--nxgt-media-dock` is that of a `MediaPlayerHost`'s
875
+ docked bar, and `--nxgt-bottom-chrome` is the two added together (it falls back to that sum
876
+ when unset). `FabDock`, `Toaster`, the mini player and a sticky
877
+ `StickyActionBar` keep clear of them, so a bar added at the bottom never
878
+ covers a button.
879
+
314
880
  ### The app bar: a title, the actions, the account
315
881
 
316
- The header reads, from the start: the phone's menu button, `headerTitle`
882
+ The header reads, from the start: a route's back arrow (`handle.back`), the phone's menu button, `headerTitle`
317
883
  (the context the app is in, the active school or organisation), then
318
884
  `headerActions` (language, notifications) and `avatar` at the end. The title
319
885
  takes the room left and ends in an ellipsis when it does not fit, so the
@@ -1037,6 +1603,44 @@ import { ActivityContent, Alert } from '@nxgt/material/components';
1037
1603
  - **Width token.** `--nxgt-aside-width` changes `asideWidth="md"` (20rem) app-wide;
1038
1604
  any CSS length goes in `asideWidth` for one screen.
1039
1605
 
1606
+ ## A docs page inside the shell
1607
+
1608
+ A documentation section of an app (the help, the API reference) is a `Doc`
1609
+ under a route of the shell, not a second page with its own top bar. Pass
1610
+ `chrome="embedded"`:
1611
+
1612
+ ```tsx
1613
+ import { ActivityLayout, Doc, DocPage } from '@nxgt/material/components';
1614
+
1615
+ <ActivityLayout items={items} navigation={{ phone: 'bar' }}>
1616
+ <Doc chrome="embedded" items={docItems} pathname={pathname} toc={toc}>
1617
+ <DocPage title="Install">…</DocPage>
1618
+ </Doc>
1619
+ </ActivityLayout>
1620
+ ```
1621
+
1622
+ - The shell's header stays the page's only bar: `Doc` draws no top bar and no
1623
+ reading bar, and does not take the viewport's height.
1624
+ - The page tree (from `md`) and the outline (from `xl`) stick under the header,
1625
+ at the offset `ActivityContent`'s `aside` uses, and scroll with the shell:
1626
+ its window, or the region of a `scroll="container"` shell.
1627
+ - On a phone the tree is a sheet, opened by « Browse docs » under the header
1628
+ (not the shell's « Menu »), together with the search and `actions`. Its list
1629
+ and the page clear a bottom bar or the floating toolbar (`--nxgt-bottom-chrome`).
1630
+ - Without `chrome` (or `chrome="standalone"`) `Doc` is what it was: it owns the
1631
+ page.
1632
+
1633
+ See [Doc](../components/navigation-and-layout.md#doc).
1634
+
1635
+ ## A public page outside the shell
1636
+
1637
+ A landing or marketing page is not inside the app shell: it has no rail or
1638
+ sidebar and is read by people who are not signed in. `LandingLayout` is its
1639
+ frame (a top bar on `TopNav`, a drawer on a phone, `LandingSection` bands, a
1640
+ `SiteFooter`), and it takes the same `items` as the shell, so the links are
1641
+ declared once. See
1642
+ [LandingLayout](../components/navigation-and-layout.md#landinglayout).
1643
+
1040
1644
  ## Dense pages on large screens
1041
1645
 
1042
1646
  On a 1440 or 1920 px screen a page should show more, not stretch the same four
@@ -1192,7 +1796,9 @@ export function InvoiceTrail() {
1192
1796
  `AppSidebar`, `AppHeader` and `AppBreadcrumb` are exported for a layout of your
1193
1797
  own. They take the same `items`; `AppHeader` takes `actions`, `avatar`,
1194
1798
  `showMenuIcon` (default `true`), and `menuOpen` / `onMenuOpenChange` to control
1195
- its phone menu sheet. The lower-level `Sidebar`, `TopAppBar` and
1799
+ its phone menu sheet, `tabs` (a node, default none: a `TabsNav` drawn as a row
1800
+ at the foot of the bar) and `back` (a `ShellBack`, default none: the back arrow,
1801
+ before the menu button). The lower-level `Sidebar`, `TopAppBar` and
1196
1802
  `Breadcrumb` primitives are on the
1197
1803
  [navigation & layout](../components/navigation-and-layout.md) page.
1198
1804
 
@@ -1211,3 +1817,36 @@ render(
1211
1817
  </MemoryRouter>,
1212
1818
  );
1213
1819
  ```
1820
+
1821
+ A bar of your own with a back arrow and tabs, complete:
1822
+
1823
+ ```tsx
1824
+ import { MemoryRouter } from 'react-router';
1825
+ import {
1826
+ AppHeader,
1827
+ TabsNav,
1828
+ TabsNavLink,
1829
+ type MenuItem,
1830
+ } from '@nxgt/material/components';
1831
+
1832
+ const items: MenuItem[] = [{ label: 'Home', url: '/', icon: 'house' }];
1833
+
1834
+ export function ProjectBar() {
1835
+ return (
1836
+ <MemoryRouter initialEntries={['/projects/activity']}>
1837
+ <AppHeader
1838
+ items={items}
1839
+ back={{ to: '/projects', label: 'Projects' }}
1840
+ tabs={
1841
+ <TabsNav aria-label="Project sections" value="activity">
1842
+ <TabsNavLink to="/projects/overview" value="overview">Overview</TabsNavLink>
1843
+ <TabsNavLink to="/projects/activity" value="activity">Activity</TabsNavLink>
1844
+ </TabsNav>
1845
+ }
1846
+ >
1847
+ <h1>Atlas redesign</h1>
1848
+ </AppHeader>
1849
+ </MemoryRouter>
1850
+ );
1851
+ }
1852
+ ```