prime-ui-kit 0.16.0 → 0.18.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 (477) hide show
  1. package/README.md +15 -18
  2. package/dist/chunks/{chunk-A7OQWH6R.js → chunk-IVS3J7AS.js} +1 -1
  3. package/dist/chunks/{chunk-6TPHKCUJ.js → chunk-MB4CXSLL.js} +27732 -26723
  4. package/dist/chunks/{chunk-4PSQ64S4.js → chunk-OAXJWF3L.js} +6818 -6264
  5. package/dist/chunks/{chunk-U3Q2I3MY.js → chunk-QFHE5GKW.js} +3 -2
  6. package/dist/chunks/{chunk-HDBQICPW.js → chunk-X3JT5CLR.js} +60 -20
  7. package/dist/color-picker.d.ts +1 -1
  8. package/dist/color-picker.js +3 -3
  9. package/dist/components/badge/Badge.d.ts +17 -0
  10. package/dist/components/breadcrumb/Breadcrumb.d.ts +12 -3
  11. package/dist/components/button/Button.d.ts +1 -1
  12. package/dist/components/button-group/ButtonGroup.d.ts +1 -1
  13. package/dist/components/card/Card.d.ts +8 -4
  14. package/dist/components/chart-frame/ChartFrame.d.ts +1 -1
  15. package/dist/components/chat/Chat.d.ts +3 -3
  16. package/dist/components/chat/ChatRows.d.ts +5 -1
  17. package/dist/components/chat/MessageList.d.ts +5 -1
  18. package/dist/components/chat/groupMessages.d.ts +12 -4
  19. package/dist/components/chat-list/ChatList.d.ts +18 -9
  20. package/dist/components/chat-list/formatChatTime.d.ts +3 -3
  21. package/dist/components/checkbox/Checkbox.d.ts +6 -1
  22. package/dist/components/color-field/ColorField.d.ts +1 -1
  23. package/dist/components/color-picker/ColorPicker.d.ts +23 -1
  24. package/dist/components/color-picker/ColorPresets.d.ts +9 -1
  25. package/dist/components/crossfade/Crossfade.d.ts +1 -1
  26. package/dist/components/data-table/DataTable.d.ts +3 -1
  27. package/dist/components/data-table/Head.d.ts +3 -1
  28. package/dist/components/data-table/types.d.ts +5 -0
  29. package/dist/components/digit-input/DigitInput.d.ts +1 -1
  30. package/dist/components/drawer/Drawer.d.ts +3 -2
  31. package/dist/components/field-list/FieldList.d.ts +18 -6
  32. package/dist/components/hint/Hint.d.ts +8 -2
  33. package/dist/components/index.d.ts +6 -7
  34. package/dist/components/input/Input.d.ts +27 -5
  35. package/dist/components/input/inputSuggestions.d.ts +39 -0
  36. package/dist/components/kanban/Kanban.d.ts +4 -9
  37. package/dist/components/list/List.d.ts +19 -5
  38. package/dist/components/message/Message.d.ts +15 -3
  39. package/dist/components/message/MessageSticker.d.ts +27 -0
  40. package/dist/components/message/formatMessageTime.d.ts +5 -2
  41. package/dist/components/modal/Modal.d.ts +3 -2
  42. package/dist/components/native-select/NativeSelect.d.ts +1 -1
  43. package/dist/components/pagination/Pagination.d.ts +5 -1
  44. package/dist/components/popover/Popover.d.ts +1 -1
  45. package/dist/components/radio/Radio.d.ts +11 -2
  46. package/dist/components/rich-text/RichText.d.ts +23 -0
  47. package/dist/components/scroll-container/ScrollContainer.d.ts +1 -1
  48. package/dist/components/scroll-container/scrollGlide.d.ts +26 -0
  49. package/dist/components/scroll-container/useScrollMotion.d.ts +25 -0
  50. package/dist/components/segmented-control/SegmentedControl.d.ts +1 -1
  51. package/dist/components/select/selectContext.d.ts +7 -0
  52. package/dist/components/slider/Slider.d.ts +2 -2
  53. package/dist/components/smart-filter/SmartFilter.d.ts +4 -5
  54. package/dist/components/switch/Switch.d.ts +6 -1
  55. package/dist/components/tag-select/TagSelect.d.ts +1 -1
  56. package/dist/components/textarea/Textarea.d.ts +6 -1
  57. package/dist/components/timeline/Timeline.d.ts +1 -1
  58. package/dist/icon-set.js +2 -2
  59. package/dist/index.css +1 -1
  60. package/dist/index.js +7 -9
  61. package/dist/internal/ChoiceField.d.ts +3 -1
  62. package/dist/internal/FieldFrame.d.ts +8 -2
  63. package/dist/internal/barPlan.d.ts +44 -0
  64. package/dist/internal/fieldCell.d.ts +1 -1
  65. package/dist/internal/formatClock.d.ts +23 -2
  66. package/dist/internal/leaveGuard.d.ts +21 -0
  67. package/dist/internal/messageList.d.ts +2 -0
  68. package/dist/internal/overlay/DialogParts.d.ts +27 -2
  69. package/dist/internal/overlay/FloatingPanel.d.ts +1 -1
  70. package/dist/internal/overlay/focus.d.ts +3 -2
  71. package/dist/internal/parts.d.ts +1 -1
  72. package/dist/internal/slot.d.ts +0 -30
  73. package/dist/internal/swatch.d.ts +5 -0
  74. package/dist/internal/tokenDefaults.d.ts +1 -0
  75. package/dist/layout/app-shell/AppShell.d.ts +19 -38
  76. package/dist/layout/index.d.ts +3 -3
  77. package/dist/layout/page/Page.d.ts +302 -0
  78. package/dist/layout/sidebar/Sidebar.d.ts +1 -1
  79. package/dist/skill/SKILL.md +10 -10
  80. package/dist/skill/anti-slop.md +106 -5
  81. package/dist/skill/api-contract.md +15 -8
  82. package/dist/skill/cheatsheet.md +46 -26
  83. package/dist/skill/checklist.md +12 -3
  84. package/dist/skill/choosing.md +34 -20
  85. package/dist/skill/components.md +4 -5
  86. package/dist/skill/composition.md +193 -154
  87. package/dist/skill/foundations.md +9 -9
  88. package/dist/skill/layouts.md +42 -99
  89. package/dist/skill/reference/components/avatar/COMPONENT.md +2 -2
  90. package/dist/skill/reference/components/avatar/examples/team-group.tsx +1 -1
  91. package/dist/skill/reference/components/badge/COMPONENT.md +14 -1
  92. package/dist/skill/reference/components/badge/examples/examples.module.css +7 -0
  93. package/dist/skill/reference/components/badge/examples/tag-row.tsx +34 -0
  94. package/dist/skill/reference/components/banner/COMPONENT.md +4 -4
  95. package/dist/skill/reference/components/banner/examples/examples.module.css +6 -1
  96. package/dist/skill/reference/components/banner/examples/page-strip.tsx +24 -22
  97. package/dist/skill/reference/components/breadcrumb/COMPONENT.md +18 -12
  98. package/dist/skill/reference/components/breadcrumb/examples/router.tsx +17 -0
  99. package/dist/skill/reference/components/button/COMPONENT.md +2 -1
  100. package/dist/skill/reference/components/button/examples/hold-to-confirm.tsx +1 -1
  101. package/dist/skill/reference/components/button/examples/on-colored-host.tsx +8 -8
  102. package/dist/skill/reference/components/button-group/COMPONENT.md +1 -0
  103. package/dist/skill/reference/components/card/COMPONENT.md +14 -8
  104. package/dist/skill/reference/components/card/examples/screen.module.css +1 -1
  105. package/dist/skill/reference/components/card/examples/screen.tsx +184 -198
  106. package/dist/skill/reference/components/card/examples/states.tsx +59 -0
  107. package/dist/skill/reference/components/chart-frame/COMPONENT.md +1 -1
  108. package/dist/skill/reference/components/chart-frame/examples/fill-height.tsx +9 -9
  109. package/dist/skill/reference/components/chat/COMPONENT.md +8 -5
  110. package/dist/skill/reference/components/chat/examples/screen.module.css +1 -1
  111. package/dist/skill/reference/components/chat/examples/screen.tsx +110 -117
  112. package/dist/skill/reference/components/chat/examples/time-zone.tsx +83 -0
  113. package/dist/skill/reference/components/chat-list/COMPONENT.md +14 -8
  114. package/dist/skill/reference/components/chat-list/examples/controlled.tsx +2 -2
  115. package/dist/skill/reference/components/chat-list/examples/examples.module.css +8 -0
  116. package/dist/skill/reference/components/chat-list/examples/links.tsx +1 -1
  117. package/dist/skill/reference/components/chat-list/examples/router.tsx +63 -0
  118. package/dist/skill/reference/components/checkbox/COMPONENT.md +1 -0
  119. package/dist/skill/reference/components/checkbox/examples/examples.module.css +3 -2
  120. package/dist/skill/reference/components/code-block/COMPONENT.md +1 -1
  121. package/dist/skill/reference/components/code-block/examples/color-scheme.tsx +2 -4
  122. package/dist/skill/reference/components/code-block/examples/examples.module.css +0 -11
  123. package/dist/skill/reference/components/color-field/COMPONENT.md +2 -1
  124. package/dist/skill/reference/components/color-picker/COMPONENT.md +31 -11
  125. package/dist/skill/reference/components/color-picker/examples/examples.module.css +2 -5
  126. package/dist/skill/reference/components/color-picker/examples/overview.tsx +5 -10
  127. package/dist/skill/reference/components/color-picker/examples/presets-custom.tsx +31 -0
  128. package/dist/skill/reference/components/color-picker/examples/sizes.tsx +4 -8
  129. package/dist/skill/reference/components/color-swatches/COMPONENT.md +1 -0
  130. package/dist/skill/reference/components/crossfade/COMPONENT.md +3 -3
  131. package/dist/skill/reference/components/crossfade/examples/screen.tsx +107 -112
  132. package/dist/skill/reference/components/data-table/COMPONENT.md +12 -7
  133. package/dist/skill/reference/components/data-table/examples/examples.module.css +9 -0
  134. package/dist/skill/reference/components/data-table/examples/numeric.tsx +9 -2
  135. package/dist/skill/reference/components/data-table/examples/screen.tsx +42 -52
  136. package/dist/skill/reference/components/data-table/examples/server.tsx +6 -2
  137. package/dist/skill/reference/components/datepicker/COMPONENT.md +3 -1
  138. package/dist/skill/reference/components/datepicker/examples/deadline.tsx +33 -0
  139. package/dist/skill/reference/components/datepicker/examples/examples.module.css +6 -0
  140. package/dist/skill/reference/components/datepicker/examples/inline-panel.tsx +3 -1
  141. package/dist/skill/reference/components/description-list/COMPONENT.md +1 -1
  142. package/dist/skill/reference/components/description-list/examples/screen.tsx +120 -127
  143. package/dist/skill/reference/components/digit-input/COMPONENT.md +1 -0
  144. package/dist/skill/reference/components/digit-input/examples/grouped.tsx +4 -4
  145. package/dist/skill/reference/components/digit-input/examples/validation.tsx +1 -1
  146. package/dist/skill/reference/components/divider/COMPONENT.md +2 -2
  147. package/dist/skill/reference/components/divider/examples/examples.module.css +4 -1
  148. package/dist/skill/reference/components/divider/examples/vertical.tsx +22 -9
  149. package/dist/skill/reference/components/dnd/examples/examples.module.css +3 -1
  150. package/dist/skill/reference/components/drawer/COMPONENT.md +16 -3
  151. package/dist/skill/reference/components/drawer/examples/client-card.tsx +32 -8
  152. package/dist/skill/reference/components/drawer/examples/placement.tsx +26 -31
  153. package/dist/skill/reference/components/drawer/examples/screen.tsx +137 -160
  154. package/dist/skill/reference/components/dropdown/COMPONENT.md +1 -1
  155. package/dist/skill/reference/components/example-frame/COMPONENT.md +3 -3
  156. package/dist/skill/reference/components/field-list/COMPONENT.md +15 -3
  157. package/dist/skill/reference/components/field-list/examples/saving.tsx +83 -0
  158. package/dist/skill/reference/components/field-list/examples/screen.module.css +1 -1
  159. package/dist/skill/reference/components/field-list/examples/screen.tsx +19 -19
  160. package/dist/skill/reference/components/field-list/examples/totals.tsx +82 -0
  161. package/dist/skill/reference/components/fieldset/COMPONENT.md +1 -1
  162. package/dist/skill/reference/components/fieldset/examples/states.tsx +1 -1
  163. package/dist/skill/reference/components/file-upload/COMPONENT.md +2 -1
  164. package/dist/skill/reference/components/file-upload/examples/screen.module.css +2 -2
  165. package/dist/skill/reference/components/file-upload/examples/screen.tsx +65 -81
  166. package/dist/skill/reference/components/gallery/COMPONENT.md +1 -0
  167. package/dist/skill/reference/components/gantt/COMPONENT.md +1 -1
  168. package/dist/skill/reference/components/gantt/examples/screen.module.css +1 -1
  169. package/dist/skill/reference/components/gantt/examples/screen.tsx +55 -73
  170. package/dist/skill/reference/components/hint/COMPONENT.md +16 -2
  171. package/dist/skill/reference/components/hint/examples/examples.module.css +10 -1
  172. package/dist/skill/reference/components/hint/examples/overview.tsx +1 -1
  173. package/dist/skill/reference/components/hint/examples/variants.tsx +48 -0
  174. package/dist/skill/reference/components/input/COMPONENT.md +39 -9
  175. package/dist/skill/reference/components/input/examples/affixes.tsx +4 -2
  176. package/dist/skill/reference/components/input/examples/dismiss.tsx +29 -0
  177. package/dist/skill/reference/components/input/examples/suggestions.tsx +26 -0
  178. package/dist/skill/reference/components/input/examples/time.tsx +24 -0
  179. package/dist/skill/reference/components/input/examples/with-select.tsx +44 -0
  180. package/dist/skill/reference/components/kanban/COMPONENT.md +7 -7
  181. package/dist/skill/reference/components/kanban/examples/columns.tsx +4 -2
  182. package/dist/skill/reference/components/kanban/examples/screen.module.css +1 -1
  183. package/dist/skill/reference/components/kanban/examples/screen.tsx +50 -65
  184. package/dist/skill/reference/components/kbd/COMPONENT.md +1 -1
  185. package/dist/skill/reference/components/label/examples/examples.module.css +12 -1
  186. package/dist/skill/reference/components/label/examples/overview.tsx +1 -1
  187. package/dist/skill/reference/components/list/COMPONENT.md +26 -10
  188. package/dist/skill/reference/components/list/examples/row-controls.tsx +80 -0
  189. package/dist/skill/reference/components/list/examples/with-icon.tsx +23 -2
  190. package/dist/skill/reference/components/login-form/COMPONENT.md +8 -7
  191. package/dist/skill/reference/components/login-form/examples/states.tsx +12 -14
  192. package/dist/skill/reference/components/media-viewer/examples/controlled.tsx +16 -16
  193. package/dist/skill/reference/components/media-viewer/examples/examples.module.css +1 -3
  194. package/dist/skill/reference/components/message/COMPONENT.md +30 -9
  195. package/dist/skill/reference/components/message/examples/preview.tsx +28 -0
  196. package/dist/skill/reference/components/message/examples/sticker.tsx +35 -0
  197. package/dist/skill/reference/components/modal/COMPONENT.md +15 -3
  198. package/dist/skill/reference/components/modal/examples/long-content.tsx +37 -18
  199. package/dist/skill/reference/components/native-select/COMPONENT.md +1 -0
  200. package/dist/skill/reference/components/notification/COMPONENT.md +1 -1
  201. package/dist/skill/reference/components/pagination/COMPONENT.md +11 -3
  202. package/dist/skill/reference/components/pagination/examples/controlled.tsx +2 -1
  203. package/dist/skill/reference/components/popover/COMPONENT.md +3 -2
  204. package/dist/skill/reference/components/popover/examples/width.tsx +13 -1
  205. package/dist/skill/reference/components/radio/COMPONENT.md +2 -0
  206. package/dist/skill/reference/components/rich-text/COMPONENT.md +93 -0
  207. package/dist/skill/reference/components/rich-text/examples/overview.tsx +19 -0
  208. package/dist/skill/reference/components/scroll-container/COMPONENT.md +8 -5
  209. package/dist/skill/reference/components/segmented-control/COMPONENT.md +1 -0
  210. package/dist/skill/reference/components/segmented-control/examples/in-form.tsx +1 -1
  211. package/dist/skill/reference/components/select/COMPONENT.md +7 -3
  212. package/dist/skill/reference/components/slider/COMPONENT.md +4 -3
  213. package/dist/skill/reference/components/slider/examples/controlled.tsx +1 -1
  214. package/dist/skill/reference/components/slider/examples/states.tsx +14 -10
  215. package/dist/skill/reference/components/smart-filter/COMPONENT.md +13 -13
  216. package/dist/skill/reference/components/smart-filter/examples/examples.module.css +3 -0
  217. package/dist/skill/reference/components/smart-filter/examples/many-values.tsx +12 -8
  218. package/dist/skill/reference/components/smart-filter/examples/sizes.tsx +7 -3
  219. package/dist/skill/reference/components/sparkline/COMPONENT.md +1 -0
  220. package/dist/skill/reference/components/sparkline/examples/curve.tsx +16 -11
  221. package/dist/skill/reference/components/sparkline/examples/states.tsx +14 -10
  222. package/dist/skill/reference/components/switch/COMPONENT.md +2 -1
  223. package/dist/skill/reference/components/tabs/COMPONENT.md +1 -1
  224. package/dist/skill/reference/components/tag-select/COMPONENT.md +1 -0
  225. package/dist/skill/reference/components/textarea/COMPONENT.md +1 -0
  226. package/dist/skill/reference/components/timeline/COMPONENT.md +3 -3
  227. package/dist/skill/reference/components/timeline/examples/structure.tsx +2 -1
  228. package/dist/skill/reference/components/typography/COMPONENT.md +2 -2
  229. package/dist/skill/reference/foundation.md +15 -11
  230. package/dist/skill/reference/layout/app-shell/COMPONENT.md +25 -38
  231. package/dist/skill/reference/layout/app-shell/examples/footer.tsx +10 -10
  232. package/dist/skill/reference/layout/app-shell/examples/overview.tsx +20 -22
  233. package/dist/skill/reference/layout/app-shell/examples/screen.module.css +2 -2
  234. package/dist/skill/reference/layout/app-shell/examples/screen.tsx +25 -30
  235. package/dist/skill/reference/layout/app-shell/examples/template.tsx +13 -17
  236. package/dist/skill/reference/layout/bottom-nav/COMPONENT.md +4 -3
  237. package/dist/skill/reference/layout/bottom-nav/examples/floating-action.tsx +10 -19
  238. package/dist/skill/reference/layout/bottom-nav/examples/floating.tsx +10 -19
  239. package/dist/skill/reference/layout/bottom-nav/examples/in-app-shell.tsx +11 -19
  240. package/dist/skill/reference/layout/page/COMPONENT.md +382 -0
  241. package/dist/skill/reference/layout/page/examples/actions-collapse.tsx +45 -0
  242. package/dist/skill/reference/layout/page/examples/collapse.tsx +68 -0
  243. package/dist/skill/reference/layout/page/examples/examples.module.css +92 -0
  244. package/{src/components/page-content → dist/skill/reference/layout/page}/examples/grid.tsx +15 -15
  245. package/dist/skill/reference/layout/page/examples/guard.tsx +87 -0
  246. package/dist/skill/reference/{components/page-content → layout/page}/examples/list-detail.tsx +14 -14
  247. package/dist/skill/reference/layout/page/examples/loading.tsx +57 -0
  248. package/dist/skill/reference/layout/page/examples/narrow.tsx +75 -0
  249. package/dist/skill/reference/layout/page/examples/overview.tsx +57 -0
  250. package/dist/skill/reference/{components/page-content → layout/page}/examples/screen.module.css +1 -1
  251. package/{src/components/page-content → dist/skill/reference/layout/page}/examples/screen.tsx +29 -19
  252. package/dist/skill/reference/{components/page-content → layout/page}/examples/sections.tsx +17 -24
  253. package/dist/skill/reference/layout/page/examples/structure.tsx +41 -0
  254. package/dist/skill/reference/{components/page-toolbar/examples/narrow.tsx → layout/page/examples/tools.tsx} +38 -35
  255. package/dist/skill/reference/layout/page/examples/top-bar.tsx +85 -0
  256. package/dist/skill/reference/{components/page-content → layout/page}/examples/variants.tsx +7 -7
  257. package/dist/skill/reference/layout/sidebar/COMPONENT.md +6 -4
  258. package/dist/skill/reference/layout/sidebar/examples/dismiss.tsx +10 -7
  259. package/dist/skill/reference/layout/sidebar/examples/narrow.tsx +11 -8
  260. package/dist/skill/responsive.md +94 -75
  261. package/dist/skill/ux.md +5 -3
  262. package/dist/tokens/layers.d.ts +2 -0
  263. package/dist/tokens/primitives.d.ts +12 -2
  264. package/dist/tokens/semantic.d.ts +9 -0
  265. package/dist/tokens/themes/dark.d.ts +7 -2
  266. package/package.json +2 -2
  267. package/src/components/avatar/COMPONENT.md +2 -2
  268. package/src/components/avatar/examples/team-group.tsx +1 -1
  269. package/src/components/badge/COMPONENT.md +14 -1
  270. package/src/components/badge/examples/examples.module.css +7 -0
  271. package/src/components/badge/examples/tag-row.tsx +34 -0
  272. package/src/components/banner/COMPONENT.md +4 -4
  273. package/src/components/banner/examples/examples.module.css +6 -1
  274. package/src/components/banner/examples/page-strip.tsx +24 -22
  275. package/src/components/breadcrumb/COMPONENT.md +18 -12
  276. package/src/components/breadcrumb/examples/router.tsx +17 -0
  277. package/src/components/button/COMPONENT.md +2 -1
  278. package/src/components/button/examples/hold-to-confirm.tsx +1 -1
  279. package/src/components/button/examples/on-colored-host.tsx +8 -8
  280. package/src/components/button-group/COMPONENT.md +1 -0
  281. package/src/components/card/COMPONENT.md +14 -8
  282. package/src/components/card/examples/screen.module.css +1 -1
  283. package/src/components/card/examples/screen.tsx +184 -198
  284. package/src/components/card/examples/states.tsx +59 -0
  285. package/src/components/chart-frame/COMPONENT.md +1 -1
  286. package/src/components/chart-frame/examples/fill-height.tsx +9 -9
  287. package/src/components/chat/COMPONENT.md +8 -5
  288. package/src/components/chat/examples/screen.module.css +1 -1
  289. package/src/components/chat/examples/screen.tsx +110 -117
  290. package/src/components/chat/examples/time-zone.tsx +83 -0
  291. package/src/components/chat-list/COMPONENT.md +14 -8
  292. package/src/components/chat-list/examples/controlled.tsx +2 -2
  293. package/src/components/chat-list/examples/examples.module.css +8 -0
  294. package/src/components/chat-list/examples/links.tsx +1 -1
  295. package/src/components/chat-list/examples/router.tsx +63 -0
  296. package/src/components/checkbox/COMPONENT.md +1 -0
  297. package/src/components/checkbox/examples/examples.module.css +3 -2
  298. package/src/components/code-block/COMPONENT.md +1 -1
  299. package/src/components/code-block/examples/color-scheme.tsx +2 -4
  300. package/src/components/code-block/examples/examples.module.css +0 -11
  301. package/src/components/color-field/COMPONENT.md +2 -1
  302. package/src/components/color-picker/COMPONENT.md +31 -11
  303. package/src/components/color-picker/examples/examples.module.css +2 -5
  304. package/src/components/color-picker/examples/overview.tsx +5 -10
  305. package/src/components/color-picker/examples/presets-custom.tsx +31 -0
  306. package/src/components/color-picker/examples/sizes.tsx +4 -8
  307. package/src/components/color-swatches/COMPONENT.md +1 -0
  308. package/src/components/crossfade/COMPONENT.md +3 -3
  309. package/src/components/crossfade/examples/screen.tsx +107 -112
  310. package/src/components/data-table/COMPONENT.md +12 -7
  311. package/src/components/data-table/examples/examples.module.css +9 -0
  312. package/src/components/data-table/examples/numeric.tsx +9 -2
  313. package/src/components/data-table/examples/screen.tsx +42 -52
  314. package/src/components/data-table/examples/server.tsx +6 -2
  315. package/src/components/datepicker/COMPONENT.md +3 -1
  316. package/src/components/datepicker/examples/deadline.tsx +33 -0
  317. package/src/components/datepicker/examples/examples.module.css +6 -0
  318. package/src/components/datepicker/examples/inline-panel.tsx +3 -1
  319. package/src/components/description-list/COMPONENT.md +1 -1
  320. package/src/components/description-list/examples/screen.tsx +120 -127
  321. package/src/components/digit-input/COMPONENT.md +1 -0
  322. package/src/components/digit-input/examples/grouped.tsx +4 -4
  323. package/src/components/digit-input/examples/validation.tsx +1 -1
  324. package/src/components/divider/COMPONENT.md +2 -2
  325. package/src/components/divider/examples/examples.module.css +4 -1
  326. package/src/components/divider/examples/vertical.tsx +22 -9
  327. package/src/components/dnd/examples/examples.module.css +3 -1
  328. package/src/components/drawer/COMPONENT.md +16 -3
  329. package/src/components/drawer/examples/client-card.tsx +32 -8
  330. package/src/components/drawer/examples/placement.tsx +26 -31
  331. package/src/components/drawer/examples/screen.tsx +137 -160
  332. package/src/components/dropdown/COMPONENT.md +1 -1
  333. package/src/components/example-frame/COMPONENT.md +3 -3
  334. package/src/components/field-list/COMPONENT.md +15 -3
  335. package/src/components/field-list/examples/saving.tsx +83 -0
  336. package/src/components/field-list/examples/screen.module.css +1 -1
  337. package/src/components/field-list/examples/screen.tsx +19 -19
  338. package/src/components/field-list/examples/totals.tsx +82 -0
  339. package/src/components/fieldset/COMPONENT.md +1 -1
  340. package/src/components/fieldset/examples/states.tsx +1 -1
  341. package/src/components/file-upload/COMPONENT.md +2 -1
  342. package/src/components/file-upload/examples/screen.module.css +2 -2
  343. package/src/components/file-upload/examples/screen.tsx +65 -81
  344. package/src/components/gallery/COMPONENT.md +1 -0
  345. package/src/components/gantt/COMPONENT.md +1 -1
  346. package/src/components/gantt/examples/screen.module.css +1 -1
  347. package/src/components/gantt/examples/screen.tsx +55 -73
  348. package/src/components/hint/COMPONENT.md +16 -2
  349. package/src/components/hint/examples/examples.module.css +10 -1
  350. package/src/components/hint/examples/overview.tsx +1 -1
  351. package/src/components/hint/examples/variants.tsx +48 -0
  352. package/src/components/input/COMPONENT.md +39 -9
  353. package/src/components/input/examples/affixes.tsx +4 -2
  354. package/src/components/input/examples/dismiss.tsx +29 -0
  355. package/src/components/input/examples/suggestions.tsx +26 -0
  356. package/src/components/input/examples/time.tsx +24 -0
  357. package/src/components/input/examples/with-select.tsx +44 -0
  358. package/src/components/kanban/COMPONENT.md +7 -7
  359. package/src/components/kanban/examples/columns.tsx +4 -2
  360. package/src/components/kanban/examples/screen.module.css +1 -1
  361. package/src/components/kanban/examples/screen.tsx +50 -65
  362. package/src/components/kbd/COMPONENT.md +1 -1
  363. package/src/components/label/examples/examples.module.css +12 -1
  364. package/src/components/label/examples/overview.tsx +1 -1
  365. package/src/components/list/COMPONENT.md +26 -10
  366. package/src/components/list/examples/row-controls.tsx +80 -0
  367. package/src/components/list/examples/with-icon.tsx +23 -2
  368. package/src/components/login-form/COMPONENT.md +8 -7
  369. package/src/components/login-form/examples/states.tsx +12 -14
  370. package/src/components/media-viewer/examples/controlled.tsx +16 -16
  371. package/src/components/media-viewer/examples/examples.module.css +1 -3
  372. package/src/components/message/COMPONENT.md +30 -9
  373. package/src/components/message/examples/preview.tsx +28 -0
  374. package/src/components/message/examples/sticker.tsx +35 -0
  375. package/src/components/modal/COMPONENT.md +15 -3
  376. package/src/components/modal/examples/long-content.tsx +37 -18
  377. package/src/components/native-select/COMPONENT.md +1 -0
  378. package/src/components/notification/COMPONENT.md +1 -1
  379. package/src/components/pagination/COMPONENT.md +11 -3
  380. package/src/components/pagination/examples/controlled.tsx +2 -1
  381. package/src/components/popover/COMPONENT.md +3 -2
  382. package/src/components/popover/examples/width.tsx +13 -1
  383. package/src/components/radio/COMPONENT.md +2 -0
  384. package/src/components/rich-text/COMPONENT.md +93 -0
  385. package/src/components/rich-text/examples/overview.tsx +19 -0
  386. package/src/components/scroll-container/COMPONENT.md +8 -5
  387. package/src/components/segmented-control/COMPONENT.md +1 -0
  388. package/src/components/segmented-control/examples/in-form.tsx +1 -1
  389. package/src/components/select/COMPONENT.md +7 -3
  390. package/src/components/slider/COMPONENT.md +4 -3
  391. package/src/components/slider/examples/controlled.tsx +1 -1
  392. package/src/components/slider/examples/states.tsx +14 -10
  393. package/src/components/smart-filter/COMPONENT.md +13 -13
  394. package/src/components/smart-filter/examples/examples.module.css +3 -0
  395. package/src/components/smart-filter/examples/many-values.tsx +12 -8
  396. package/src/components/smart-filter/examples/sizes.tsx +7 -3
  397. package/src/components/sparkline/COMPONENT.md +1 -0
  398. package/src/components/sparkline/examples/curve.tsx +16 -11
  399. package/src/components/sparkline/examples/states.tsx +14 -10
  400. package/src/components/switch/COMPONENT.md +2 -1
  401. package/src/components/tabs/COMPONENT.md +1 -1
  402. package/src/components/tag-select/COMPONENT.md +1 -0
  403. package/src/components/textarea/COMPONENT.md +1 -0
  404. package/src/components/timeline/COMPONENT.md +3 -3
  405. package/src/components/timeline/examples/structure.tsx +2 -1
  406. package/src/components/typography/COMPONENT.md +2 -2
  407. package/src/layout/app-shell/COMPONENT.md +25 -38
  408. package/src/layout/app-shell/examples/footer.tsx +10 -10
  409. package/src/layout/app-shell/examples/overview.tsx +20 -22
  410. package/src/layout/app-shell/examples/screen.module.css +2 -2
  411. package/src/layout/app-shell/examples/screen.tsx +25 -30
  412. package/src/layout/app-shell/examples/template.tsx +13 -17
  413. package/src/layout/bottom-nav/COMPONENT.md +4 -3
  414. package/src/layout/bottom-nav/examples/floating-action.tsx +10 -19
  415. package/src/layout/bottom-nav/examples/floating.tsx +10 -19
  416. package/src/layout/bottom-nav/examples/in-app-shell.tsx +11 -19
  417. package/src/layout/page/COMPONENT.md +382 -0
  418. package/src/layout/page/examples/actions-collapse.tsx +45 -0
  419. package/src/layout/page/examples/collapse.tsx +68 -0
  420. package/src/layout/page/examples/examples.module.css +92 -0
  421. package/{dist/skill/reference/components/page-content → src/layout/page}/examples/grid.tsx +15 -15
  422. package/src/layout/page/examples/guard.tsx +87 -0
  423. package/src/{components/page-content → layout/page}/examples/list-detail.tsx +14 -14
  424. package/src/layout/page/examples/loading.tsx +57 -0
  425. package/src/layout/page/examples/narrow.tsx +75 -0
  426. package/src/layout/page/examples/overview.tsx +57 -0
  427. package/src/{components/page-content → layout/page}/examples/screen.module.css +1 -1
  428. package/{dist/skill/reference/components/page-content → src/layout/page}/examples/screen.tsx +29 -19
  429. package/src/{components/page-content → layout/page}/examples/sections.tsx +17 -24
  430. package/src/layout/page/examples/structure.tsx +41 -0
  431. package/src/{components/page-toolbar/examples/narrow.tsx → layout/page/examples/tools.tsx} +38 -35
  432. package/src/layout/page/examples/top-bar.tsx +85 -0
  433. package/src/{components/page-content → layout/page}/examples/variants.tsx +7 -7
  434. package/src/layout/sidebar/COMPONENT.md +6 -4
  435. package/src/layout/sidebar/examples/dismiss.tsx +10 -7
  436. package/src/layout/sidebar/examples/narrow.tsx +11 -8
  437. package/src/styles/theme-dark.css +12 -10
  438. package/src/styles/theme-light.css +4 -0
  439. package/src/styles/tokens.css +3 -1
  440. package/dist/components/page-content/PageContent.d.ts +0 -192
  441. package/dist/components/page-toolbar/PageToolbar.d.ts +0 -55
  442. package/dist/components/scroll-container/useWheelToInline.d.ts +0 -10
  443. package/dist/layout/app-header/AppHeader.d.ts +0 -118
  444. package/dist/skill/reference/components/page-content/COMPONENT.md +0 -264
  445. package/dist/skill/reference/components/page-content/examples/examples.module.css +0 -56
  446. package/dist/skill/reference/components/page-content/examples/narrow.tsx +0 -25
  447. package/dist/skill/reference/components/page-content/examples/overview.tsx +0 -41
  448. package/dist/skill/reference/components/page-toolbar/COMPONENT.md +0 -147
  449. package/dist/skill/reference/components/page-toolbar/examples/examples.module.css +0 -16
  450. package/dist/skill/reference/components/page-toolbar/examples/overview.tsx +0 -113
  451. package/dist/skill/reference/components/page-toolbar/examples/save-changes.tsx +0 -43
  452. package/dist/skill/reference/components/page-toolbar/examples/without-search.tsx +0 -60
  453. package/dist/skill/reference/layout/app-header/COMPONENT.md +0 -187
  454. package/dist/skill/reference/layout/app-header/examples/breadcrumbs.tsx +0 -37
  455. package/dist/skill/reference/layout/app-header/examples/examples.module.css +0 -28
  456. package/dist/skill/reference/layout/app-header/examples/in-app-shell.tsx +0 -67
  457. package/dist/skill/reference/layout/app-header/examples/narrow.tsx +0 -66
  458. package/dist/skill/reference/layout/app-header/examples/overview.tsx +0 -34
  459. package/dist/skill/reference/layout/app-header/examples/page-title.tsx +0 -78
  460. package/dist/skill/reference/layout/app-shell/examples/contained.tsx +0 -30
  461. package/src/components/page-content/COMPONENT.md +0 -264
  462. package/src/components/page-content/examples/examples.module.css +0 -56
  463. package/src/components/page-content/examples/narrow.tsx +0 -25
  464. package/src/components/page-content/examples/overview.tsx +0 -41
  465. package/src/components/page-toolbar/COMPONENT.md +0 -147
  466. package/src/components/page-toolbar/examples/examples.module.css +0 -16
  467. package/src/components/page-toolbar/examples/overview.tsx +0 -113
  468. package/src/components/page-toolbar/examples/save-changes.tsx +0 -43
  469. package/src/components/page-toolbar/examples/without-search.tsx +0 -60
  470. package/src/layout/app-header/COMPONENT.md +0 -187
  471. package/src/layout/app-header/examples/breadcrumbs.tsx +0 -37
  472. package/src/layout/app-header/examples/examples.module.css +0 -28
  473. package/src/layout/app-header/examples/in-app-shell.tsx +0 -67
  474. package/src/layout/app-header/examples/narrow.tsx +0 -66
  475. package/src/layout/app-header/examples/overview.tsx +0 -34
  476. package/src/layout/app-header/examples/page-title.tsx +0 -78
  477. package/src/layout/app-shell/examples/contained.tsx +0 -30
@@ -24,7 +24,7 @@ export default function SliderControlledExample() {
24
24
  type="number"
25
25
  min={0}
26
26
  max={MAX_DISCOUNT}
27
- aria-label="Скидка для клиента, %"
27
+ aria-label="Скидка для клиента"
28
28
  value={discount}
29
29
  onValueChange={(text) => {
30
30
  const next = Number(text);
@@ -3,19 +3,23 @@ import { Slider } from "prime-ui-kit";
3
3
 
4
4
  export default function SliderStatesExample() {
5
5
  return (
6
- <div>
6
+ <>
7
7
  <div>
8
- <Slider label="min" showValue defaultValue={0} />
8
+ <div>
9
+ <Slider label="min" showValue defaultValue={0} />
10
+ </div>
11
+ <div>
12
+ <Slider label="max" showValue defaultValue={100} />
13
+ </div>
9
14
  </div>
10
15
  <div>
11
- <Slider label="max" showValue defaultValue={100} />
16
+ <div>
17
+ <Slider label="invalid" showValue defaultValue={90} invalid />
18
+ </div>
19
+ <div>
20
+ <Slider label="disabled" showValue defaultValue={35} disabled />
21
+ </div>
12
22
  </div>
13
- <div>
14
- <Slider label="invalid" showValue defaultValue={90} invalid />
15
- </div>
16
- <div>
17
- <Slider label="disabled" showValue defaultValue={35} disabled />
18
- </div>
19
- </div>
23
+ </>
20
24
  );
21
25
  }
@@ -13,10 +13,10 @@
13
13
  - An API that takes one value per field (`multiple: false`), a screen whose text search lives elsewhere (`searchable={false}`), values of different kinds in one field (`group`).
14
14
 
15
15
  ## When not to use
16
- - One field with a few options → use [SegmentedControl](../segmented-control/COMPONENT.md), [Select](../select/COMPONENT.md) or [TagSelect](../tag-select/COMPONENT.md) in the toolbar.
16
+ - One field with a few options → use [SegmentedControl](../segmented-control/COMPONENT.md), [Select](../select/COMPONENT.md) or [TagSelect](../tag-select/COMPONENT.md) in the page's `Page.Tools`.
17
17
  - A search outside a table or list page (inside a picker, a settings section, a panel) → [Input](../input/COMPONENT.md) with a search icon. Over a table or list page the search is SmartFilter even with no fields yet (`fields={[]}`): it grows into filters without a rebuild.
18
18
  - Choosing values for a form field → use [TagSelect](../tag-select/COMPONENT.md).
19
- - One period that drives a whole dashboard → [Datepicker](../datepicker/COMPONENT.md) in the page toolbar; SmartFilter ranges filter rows of a list.
19
+ - One period that drives a whole dashboard → [Datepicker](../datepicker/COMPONENT.md) in the page's `Page.Tools`; SmartFilter ranges filter rows of a list.
20
20
 
21
21
  ## Import
22
22
  ```tsx
@@ -30,7 +30,7 @@ import {
30
30
 
31
31
  ## Anatomy
32
32
  ```
33
- SmartFilter.Root state + context (flex column)
33
+ SmartFilter.Root state + context, no DOM
34
34
  ├─ SmartFilter.Toolbar [search Input (searchable)] [filter Button (count Badge)] — the anchor of the panel
35
35
  │ └─ panel flush Popover as wide as the toolbar; sections split by Dividers
36
36
  │ ├─ query row ghost Button «Искать «text»» + Kbd ↵, while typing
@@ -41,14 +41,14 @@ SmartFilter.Root state + context (flex column)
41
41
  │ └─ footer hint · count · Reset Button
42
42
  └─ SmartFilter.Chips applied filters as removable Badges · add / clear all Buttons
43
43
  ```
44
- The toolbar and the chips are separate parts so a page can put them in different places; both only need to be inside `Root`.
44
+ The toolbar and the chips are separate parts so a page can put them in different places; both only need to be inside `Root`, which draws nothing of its own.
45
45
 
46
46
  ## API
47
47
 
48
48
  <!-- Generated from api.ts by `bun run docs:build`. Edit api.ts, not this section. -->
49
49
 
50
50
  ### SmartFilter.Root
51
- `ref` → `HTMLDivElement`. A `<div>` (flex column) with the state and the context; sets `data-size`.
51
+ No DOM, no ref. The value, the search and the panel state shared by its parts; the host places the parts.
52
52
 
53
53
  | Prop | Type | Default | Description |
54
54
  |---|---|---|---|
@@ -62,11 +62,10 @@ The toolbar and the chips are separate parts so a page can put them in different
62
62
  | `size` | `"xs" \| "s" \| "m" \| "l" \| "xl"` | host tier, else `"m"` | Tier of the filter button, the search, the tags and the panel. Without it the tier of its host, else `m`. |
63
63
  | `collapsedLimit` | `number` | `12` | Values of one field shown before «Ещё N» (not while searching). |
64
64
  | `labels` | `Partial<SmartFilterLabels>` | — | Built-in strings, see Labels. |
65
- | `children` | `ReactNode` | — (required) | `SmartFilter.Toolbar` and `SmartFilter.Chips`, anywhere inside. |
66
- | `…rest` | `Omit<HTMLAttributes<HTMLDivElement>, "children" \| "defaultValue" \| "onChange">` | — | `className` and the other div attributes. |
65
+ | `children` | `ReactNode` | — (required) | `SmartFilter.Toolbar` and `SmartFilter.Chips`, anywhere inside — in a page bar the Root wraps `Page.Root`. |
67
66
 
68
67
  ### SmartFilter.Toolbar
69
- `ref` → `HTMLDivElement`. A `<div>`: the search Input first, then the filter Button (a count Badge while filters apply); the anchor of the panel, a flush Popover.
68
+ `ref` → `HTMLDivElement`. A `<div>`: the search Input first, then the filter Button (a count Badge while filters apply), which shows only its icon and count when the search would get too little room; the anchor of the panel, a flush Popover.
70
69
 
71
70
  | Prop | Type | Default | Description |
72
71
  |---|---|---|---|
@@ -165,15 +164,16 @@ same height and type.
165
164
  | range inverted | `from` above `to` | both bound inputs `aria-invalid` with the danger ring; nothing matches |
166
165
  | single value | `multiple: false` | at most one value `aria-pressed`; no «−» |
167
166
  | no filters | empty value | no count on the button, no Chips |
167
+ | compact button | the toolbar narrower than the search's 9rem plus the labelled button (search and fields both present) | the button shows its icon and the count Badge; its name stays «Фильтр» (`aria-label` without filters, a visually hidden label with them) |
168
168
 
169
169
  ## Layout & spacing
170
- - The panel is a flush Popover as wide as the toolbar; every section is a full-width row with its own padding (`--prime-space-3` × `--prime-space-4`, footer `--prime-space-2` × `--prime-space-4`), Dividers run edge to edge, the field label column is `--prime-space-24`; a row narrower than 24rem stacks the label over the values (an intrinsic wrap, no breakpoint).
171
- - The toolbar is one row of controls (`--prime-space-2` gap): the search first, growing from 9rem (`--prime-space-24` × 1.5), then the filter button at its own width. When less than 9rem is left beside the button, the button moves under the search; every row stays one control high. Search first, filter second — the active filters (`SmartFilter.Chips`) sit under them.
170
+ - The panel is a flush Popover at least as wide as the toolbar (`width="min-trigger"`), by its content up to twice the panel minimum when the toolbar is narrow; every section is a full-width row with its own padding (`--prime-space-3` × `--prime-space-4`, footer `--prime-space-2` × `--prime-space-4`), Dividers run edge to edge, the field label column is at least `--prime-space-24` (a longer name takes its own width, never breaking inside a word); a row narrower than 24rem stacks the label over the values (an intrinsic wrap, no breakpoint).
171
+ - The toolbar is one row of controls (`--prime-space-2` gap): the search first, growing from 9rem (`--prime-space-24` × 1.5), then the filter button at its own width. When less than 9rem is left beside the labelled button, the button shows only its icon and count and stays beside the search, which gives its width instead of wrapping. Every row stays one control high. The search and the button also stand alone: `searchable={false}` keeps the button, empty `fields` keep the search. Search first, filter second — the active filters (`SmartFilter.Chips`) sit under them.
172
172
  - Chips are Badges of the toolbar tier on the badge scale (`xs` → `s`), so a tag sits lower than the controls above it; «Добавить фильтр» is a tag of the same tier and «Сбросить все» a LinkButton with the tag's text size.
173
173
  - Values and chips wrap with `--prime-space-2` gaps; «Сбросить все» is pushed to the end. The chips row rises in with the first filter and closes up in place with the last (`partPresence`).
174
174
  - Option groups stack `--prime-space-3` apart, a caption `--prime-space-1` above each group's values. A range row holds two equal Inputs with a dash between them, centred on the field label.
175
175
  - While typing a search a range row stays only when its field name matches.
176
- - The root is a flex column (`--prime-space-3`): Toolbar, then Chips.
176
+ - The root draws nothing: its host places Toolbar and Chips. In a page bar the Toolbar goes in `Page.Tools` and the Chips in `Page.Chips`, with `SmartFilter.Root` around `Page.Root`; outside a page a host stacks them (a `Card.Body`, a form column).
177
177
 
178
178
  ## Accessibility
179
179
 
@@ -244,7 +244,7 @@ same height and type.
244
244
  - A fixed field marked `finite: false` → the user can hide every value and get an empty list.
245
245
  - Filtering the list with `includes` → use `matchesSmartFilter` (empty `include` is "any", `exclude` rejects; range bounds are inclusive, dates by whole days; an item with no value passes only an empty filter).
246
246
  - Sending `include` to a server for a hidden value of a fixed field → use `resolveSmartFilterValues` («hide» becomes «all except», `[]` means no filter).
247
- - Putting `Chips` outside `SmartFilter.Root` → every part needs the root.
247
+ - Putting `Chips` outside `SmartFilter.Root` → every part needs the root; when Toolbar and Chips stand in different groups of a page bar, wrap `Page.Root` in it.
248
248
  - A second row of filter buttons next to the toolbar → fields belong in `fields`.
249
249
  - An amount or a period in its own Popover beside the toolbar → a `range` / `date-range` field; it gets a chip and the count.
250
250
  - One field split in two because its values are of different kinds → one field with `group` on the options.
@@ -252,4 +252,4 @@ same height and type.
252
252
 
253
253
  ## Related
254
254
  - **Built from:** [Button](../button/COMPONENT.md), [Badge](../badge/COMPONENT.md), [Input](../input/COMPONENT.md), [Datepicker](../datepicker/COMPONENT.md), [Popover](../popover/COMPONENT.md), [Divider](../divider/COMPONENT.md), [Kbd](../kbd/COMPONENT.md), [EmptyPage](../empty-page/COMPONENT.md), [LinkButton](../link-button/COMPONENT.md), [Typography](../typography/COMPONENT.md), Icon (`action.search`, `action.filter`, `action.add`, `nav.chevronDown`), [VisuallyHidden](../visually-hidden/COMPONENT.md)
255
- - **See also:** [PageToolbar](../page-toolbar/COMPONENT.md), [TagSelect](../tag-select/COMPONENT.md), [DataTable](../data-table/COMPONENT.md)
255
+ - **See also:** [Page](../../layout/page/COMPONENT.md) (`Page.Tools`, `Page.Chips`), [TagSelect](../tag-select/COMPONENT.md), [DataTable](../data-table/COMPONENT.md)
@@ -30,6 +30,9 @@
30
30
 
31
31
  /* 320 px: the smallest supported viewport. */
32
32
  .narrow {
33
+ display: flex;
34
+ flex-direction: column;
35
+ gap: var(--prime-space-3);
33
36
  width: min(100%, calc(var(--prime-space-20) * 4));
34
37
  min-width: 0;
35
38
  }
@@ -1,6 +1,8 @@
1
1
  /** An open set of twenty services, degraded ones marked with an icon, collapsed after eight; typing narrows the panel and marks the match in accent — `finite`, `icon`, `collapsedLimit`. */
2
2
  import { Icon, SmartFilter, type SmartFilterField } from "prime-ui-kit";
3
3
 
4
+ import styles from "./examples.module.css";
5
+
4
6
  const SERVICES = [
5
7
  "access-policy",
6
8
  "billing",
@@ -41,13 +43,15 @@ const FIELDS: SmartFilterField[] = [
41
43
 
42
44
  export default function SmartFilterManyValuesExample() {
43
45
  return (
44
- <SmartFilter.Root
45
- fields={FIELDS}
46
- collapsedLimit={8}
47
- defaultValue={{ service: { include: [], exclude: ["events"] } }}
48
- >
49
- <SmartFilter.Toolbar />
50
- <SmartFilter.Chips />
51
- </SmartFilter.Root>
46
+ <div className={styles.stack}>
47
+ <SmartFilter.Root
48
+ fields={FIELDS}
49
+ collapsedLimit={8}
50
+ defaultValue={{ service: { include: [], exclude: ["events"] } }}
51
+ >
52
+ <SmartFilter.Toolbar />
53
+ <SmartFilter.Chips />
54
+ </SmartFilter.Root>
55
+ </div>
52
56
  );
53
57
  }
@@ -1,5 +1,5 @@
1
1
  /** Every size tier: the filter button, the search, the tags and the panel follow one tier — `size`. */
2
- import { SmartFilter, type SmartFilterField, Typography } from "prime-ui-kit";
2
+ import { Card, SmartFilter, type SmartFilterField, Typography } from "prime-ui-kit";
3
3
 
4
4
  const FIELDS: SmartFilterField[] = [
5
5
  {
@@ -18,8 +18,12 @@ export default function SmartFilterSizesExample() {
18
18
  {SIZES.map((size) => (
19
19
  <div key={size}>
20
20
  <SmartFilter.Root fields={FIELDS} size={size} defaultValue={ONLY_GET}>
21
- <SmartFilter.Toolbar />
22
- <SmartFilter.Chips />
21
+ <Card.Root>
22
+ <Card.Body>
23
+ <SmartFilter.Toolbar />
24
+ <SmartFilter.Chips />
25
+ </Card.Body>
26
+ </Card.Root>
23
27
  </SmartFilter.Root>
24
28
  <Typography as="span" variant="caption" tone="muted">
25
29
  {size}
@@ -133,6 +133,7 @@ Put it in a `Card` for a dashboard tile.
133
133
  - Bars share the width equally, 4 px apart; the zero line sits where 0 falls on the scale (the bottom when every value is positive).
134
134
  - In a dashboard, wrap it in `Card.Root` + `Card.Body`; several cards go in a grid.
135
135
  - When the value row does not fit (a narrow card), the change badge wraps under the value.
136
+ - On a head narrower than 20rem (a phone card) the date takes its own line under the title, which wraps instead of being cut; the break follows the width only, so a date that changes while scrubbing never moves it.
136
137
  - `layout="compact"` fits a DataTable row of any tier (plot and dot within an `xs` control height) and takes the cell width, at least `--prime-space-24`; give the column a `width` for an even plot per row. Put the number next to it in its own column: the compact plot shows a value only in its tooltip while scrubbed.
137
138
  - The tooltip is the kit's chart tooltip, placed like every anchored layer (`usePosition`): right of the pointer at its height, on the left only where the right has no room in the viewport — crossing the middle never moves it; from the keyboard right of the point at mid-height. Portaled, so a card or a table scroller never clips it.
138
139
 
@@ -1,5 +1,7 @@
1
1
  /** The same month of active users as a smooth curve, straight segments and steps — `curve`. */
2
- import { Sparkline, type SparklinePoint, Typography } from "prime-ui-kit";
2
+ import { Card, Sparkline, type SparklinePoint } from "prime-ui-kit";
3
+
4
+ import styles from "./examples.module.css";
3
5
 
4
6
  const USERS: SparklinePoint[] = [
5
7
  { label: "сен, 1 нед.", value: 1240 },
@@ -10,19 +12,22 @@ const USERS: SparklinePoint[] = [
10
12
  { label: "окт, 2 нед.", value: 1840 },
11
13
  ];
12
14
 
13
- const CURVES = ["smooth", "linear", "step"] as const;
15
+ const CURVES = [
16
+ { curve: "smooth", title: "Плавная кривая" },
17
+ { curve: "linear", title: "Прямые отрезки" },
18
+ { curve: "step", title: "Ступени" },
19
+ ] as const;
14
20
 
15
21
  export default function SparklineCurveExample() {
16
22
  return (
17
- <div>
18
- {CURVES.map((curve) => (
19
- <div key={curve}>
20
- <Sparkline data={USERS} label="Активные пользователи" curve={curve} />
21
- <Typography as="span" variant="caption" tone="muted">
22
- {curve}
23
- </Typography>
24
- </div>
23
+ <>
24
+ {CURVES.map(({ curve, title }) => (
25
+ <Card.Root key={curve} className={styles.card}>
26
+ <Card.Body>
27
+ <Sparkline data={USERS} label={title} curve={curve} />
28
+ </Card.Body>
29
+ </Card.Root>
25
30
  ))}
26
- </div>
31
+ </>
27
32
  );
28
33
  }
@@ -12,19 +12,23 @@ const formatRubles = (value: number) => `${value.toLocaleString("ru-RU")} ₽`;
12
12
 
13
13
  export default function SparklineStatesExample() {
14
14
  return (
15
- <div>
15
+ <>
16
16
  <div>
17
- <Sparkline data={REVENUE} label="Выручка" formatValue={formatRubles} />
18
- <Typography as="span" variant="caption" tone="muted">
19
- data
20
- </Typography>
17
+ <div>
18
+ <Sparkline data={REVENUE} label="Выручка" formatValue={formatRubles} />
19
+ <Typography as="span" variant="caption" tone="muted">
20
+ data
21
+ </Typography>
22
+ </div>
21
23
  </div>
22
24
  <div>
23
- <Sparkline data={[]} label="Выручка" loading />
24
- <Typography as="span" variant="caption" tone="muted">
25
- loading
26
- </Typography>
25
+ <div>
26
+ <Sparkline data={[]} label="Выручка" loading />
27
+ <Typography as="span" variant="caption" tone="muted">
28
+ loading
29
+ </Typography>
30
+ </div>
27
31
  </div>
28
- </div>
32
+ </>
29
33
  );
30
34
  }
@@ -46,6 +46,7 @@ Switch.Root field grid; ref and input props go to the native input (rol
46
46
  | `optional` | `boolean` | `false` | Muted `labels.optional` after the label text; the field may stay off. |
47
47
  | `labels` | `Partial<SwitchLabels>` | — | Built-in strings, see Labels. |
48
48
  | `hint` | `ReactNode` | — | Help text under the label text. Hidden while `error` is shown. |
49
+ | `hintTone` | `"neutral" \| "success" \| "warning" \| "danger"` | `"neutral"` | Status color of `hint` («Осталось 12 дней» in `warning`). The words carry the status, the color repeats it; an `error` replaces the hint and its tone. A validation error is `error`, never a `danger` hint. |
49
50
  | `error` | `ReactNode` | — | Error message in the hint slot; implies `invalid`. |
50
51
  | `invalid` | `boolean` | `false` | Danger ring on the off track and `aria-invalid`. A non-empty `error` implies it. |
51
52
  | `disabled` | `boolean` | `false` | No toggling; muted track (on = `accent-soft`), dimmed text and hint. |
@@ -97,7 +98,7 @@ No `variant` / `tone` / `color`.
97
98
  | off | `checked={false}` / default | `data-state="unchecked"`; track `fill-strong` (hover `fill-strong-hover`), thumb at the start |
98
99
  | on | `checked` / `defaultChecked` | `data-state="checked"`; accent track, the thumb glides to the end |
99
100
  | invalid | `invalid` or a non-empty `error` | `data-invalid="true"`, `aria-invalid`; danger ring on the off track and on focus; the row shakes once when an error arrives (`data-shake`) |
100
- | disabled | `disabled` | `data-disabled="true"`; off track `fill-muted`, on track `accent-soft`, `cursor: not-allowed` |
101
+ | disabled | `disabled` | `data-disabled="true"`; off track `fill-muted`, on track `accent-soft`, thumb `control-thumb-disabled` without shadow, `cursor: not-allowed` |
101
102
  | read-only | `readOnly` | `aria-readonly="true"` on the input, `data-readonly="true"` on the field; no hover or press, default cursor |
102
103
  | saving | `loading`, or `onCheckedChange` returned a pending promise | the thumb stands in the new position with a `Spinner` inside (accent when on, muted when off; it fades in by itself), `aria-busy` on the input, `data-loading` on the track, presses ignored; a rejection glides the thumb back (`base`, emphasized) |
103
104
  | pressed | pointer press | the track scales to the compact press scale (not when disabled or read-only) |
@@ -189,7 +189,7 @@ Avoid icons or descriptions on only some tabs (uneven rows; without an icon on e
189
189
  | closing, confirm pending | `onRemove` returned a promise that has not settled | the close button is `loading` (`aria-busy`); the tab, its selection and focus stay; resolved → the neighbour takes over, rejected → nothing changes |
190
190
  | two-line | `Tabs.Description` child | `data-two-line="true"` |
191
191
  | collapsed | tabs wider than the list, or a label that would be cut (horizontal) | list `data-collapse="full" \| "compact" \| "icon"`: `compact` hides icons and descriptions; `icon` takes labels, counts and close buttons out of the row — a `VisuallyHidden` copy of the label names the tab and a `Tooltip` shows it — only when every tab has an icon |
192
- | overflow | tabs at their narrowest (content width, `minItemWidth` or icon squares) still wider than the list | `data-overflow-start` / `data-overflow-end` on the list (the switcher row, a ScrollContainer), faded edges as deep as the hidden part at most (they grow and melt with the scroll, never switch); the active tab is kept in view and clear of the fades on mount and on every value change, the first and the last tab scroll all the way to the end — only the list scrolls, never the page. A column (a wide vertical list) has plain edges |
192
+ | overflow | tabs at their narrowest (content width, `minItemWidth` or icon squares) still wider than the list | `data-overflow-start` / `data-overflow-end` on the list (the switcher row, a ScrollContainer), faded edges as deep as the hidden part at most (they grow and melt with the scroll, never switch); when the end edge would cut only a tab's empty side, the tabs at `minItemWidth` widen a little (`--tabs-peek`, up to 30%) so a label fades out at the edge and shows that more tabs follow; the active tab is kept in view and clear of the fades on mount and on every value change, the first and the last tab scroll all the way to the end — only the list scrolls, never the page. A column (a wide vertical list) has plain edges |
193
193
 
194
194
  The indicator glides (`emphasized` + `base`, `data-animate="true"`) only into a choice by click, arrow keys or closing the active tab; on mount, a value set from outside, a resize, font loading, tabs added or removed and collapse it is placed without motion, and it stays still under `prefers-reduced-motion`. The list scrolls smoothly to the active tab only after such a choice too.
195
195
 
@@ -60,6 +60,7 @@ TagSelect field frame: label · control · hint/error (sin
60
60
  | `onOptionDelete` | `(value: string) => void \| Promise<void>` | — | Enables «Удалить» in the row menu; the value also leaves the selection. A returned Promise defers it: resolve deletes, reject keeps everything (e.g. after a confirmation). |
61
61
  | `label` | `ReactNode` | — | Field label above; names the input. |
62
62
  | `hint` | `ReactNode` | — | Support text under the field; linked by `aria-describedby`. |
63
+ | `hintTone` | `"neutral" \| "success" \| "warning" \| "danger"` | `"neutral"` | Status color of `hint` («Осталось 12 дней» in `warning`). The words carry the status, the color repeats it; an `error` replaces the hint and its tone. A validation error is `error`, never a `danger` hint. |
63
64
  | `error` | `ReactNode` | — | Error message; replaces the hint and implies `invalid`. |
64
65
  | `required` | `boolean` | `false` | Red `*` after the label and `aria-required` on the input. |
65
66
  | `optional` | `boolean` | — | Muted `labels.optional` after the label. |
@@ -46,6 +46,7 @@ Unlike Input, Textarea has no Wrapper / Field parts: `Textarea.Root` renders the
46
46
  | `required` | `boolean` | — | Native `required` on the textarea and a red `*` after the label (`aria-hidden`). |
47
47
  | `optional` | `boolean` | `false` | Muted marker right after the label text (`labels.optional`). |
48
48
  | `hint` | `ReactNode` | — | Help text under the field. Hidden while `error` is shown. |
49
+ | `hintTone` | `"neutral" \| "success" \| "warning" \| "danger"` | `"neutral"` | Status color of `hint` («Осталось 12 дней» in `warning`). The words carry the status, the color repeats it; an `error` replaces the hint and its tone. A validation error is `error`, never a `danger` hint. |
49
50
  | `error` | `ReactNode` | — | Error message in the hint slot; implies `invalid`. |
50
51
  | `invalid` | `boolean` | `false` | Danger inset ring on the field box, `aria-invalid` on the textarea. A non-empty `error` implies it. |
51
52
  | `focusRing` | `boolean` | `true` | `false` hides only the visual focus ring on the field box (`data-focus-ring="false"`); focus, keyboard, ARIA and the invalid ring stay. |
@@ -27,7 +27,7 @@ Timeline.Root size container, sets the tier (size, else the h
27
27
  └─ Timeline.Group label labelled <ol role="list">; the line runs from its first dot to its last
28
28
  ├─ Timeline.Item <li> + row (div | button | a | asChild element) with the dot
29
29
  │ ├─ Timeline.ItemTitle first line
30
- │ ├─ Timeline.ItemMeta second line (date); <strong> emphasizes a part
30
+ │ ├─ Timeline.ItemMeta second line (date); <strong> emphasizes a part; repeats, lines stack
31
31
  │ └─ Timeline.ItemValue trailing amount
32
32
  │ └─ Timeline.ItemMeta second line under the amount
33
33
  └─ Timeline.Gap <li>: interval between events (dashed segment, hollow dot)
@@ -73,7 +73,7 @@ Timeline.Root size container, sets the tier (size, else the h
73
73
  | `…rest` | `Omit<HTMLAttributes<HTMLElement>, "children" \| "color" \| "onClick">` | — | The other row attributes (`target`, `rel`, `download` with `href`). |
74
74
 
75
75
  ### Timeline.ItemTitle · Timeline.ItemMeta
76
- `ref` → `HTMLSpanElement`. `<span>` lines: the event (medium, accent on the highlighted row, wraps) and the muted secondary line with tabular numbers — under the title the date (emphasize a part with `<strong>`), inside `Timeline.ItemValue` the value's second line.
76
+ `ref` → `HTMLSpanElement`. `<span>` lines: the event (medium, wraps) and the muted secondary line, tabular — under the title the date (`<strong>` emphasizes a part; several `Timeline.ItemMeta` stack), inside `Timeline.ItemValue` the value's second line.
77
77
 
78
78
  | Prop | Type | Default | Description |
79
79
  |---|---|---|---|
@@ -180,7 +180,7 @@ No `labels`.
180
180
  | [overview.tsx](examples/overview.tsx) | An operations feed: one labelled group, a line through the dots, the row under the pointer highlighted — `Timeline.Group`, `Timeline.ItemValue`. |
181
181
  | [variants.tsx](examples/variants.tsx) | Dot hues for categories at reduced emphasis, and status tones on items, values and gaps at full emphasis — `color`, `tone`. |
182
182
  | [sizes.tsx](examples/sizes.tsx) | Every tier scales text, dot and row rhythm, rows 40 to 76 px — `size`. |
183
- | [structure.tsx](examples/structure.tsx) | A service history with intervals between events, a caption on the right of a gap and a second value line — `Timeline.Gap`, `Timeline.Description`, `Timeline.ItemMeta`. |
183
+ | [structure.tsx](examples/structure.tsx) | A service history with intervals between events, a caption on the right of a gap, two meta lines under a repair and a second value line — `Timeline.Gap`, `Timeline.Description`, `Timeline.ItemMeta`. |
184
184
  | [links.tsx](examples/links.tsx) | Rows that open something: an operation page by a link or by your router link through the slot, a receipt in place by a button; one Tab stop each with a focus ring — `href`, `asChild`, `onClick`. |
185
185
  | [narrow.tsx](examples/narrow.tsx) | At 375 px the title wraps and the amount stays right; below 20rem of its own width the amount moves under the meta line — `Timeline.ItemValue`. |
186
186
 
@@ -1,4 +1,4 @@
1
- /** A service history with intervals between events, a caption on the right of a gap and a second value line — `Timeline.Gap`, `Timeline.Description`, `Timeline.ItemMeta`. */
1
+ /** A service history with intervals between events, a caption on the right of a gap, two meta lines under a repair and a second value line — `Timeline.Gap`, `Timeline.Description`, `Timeline.ItemMeta`. */
2
2
  import { Timeline } from "prime-ui-kit";
3
3
 
4
4
  import styles from "./examples.module.css";
@@ -36,6 +36,7 @@ export default function TimelineStructureExample() {
36
36
  <Timeline.ItemMeta>
37
37
  <strong>07.06.26</strong> · 12 100 км
38
38
  </Timeline.ItemMeta>
39
+ <Timeline.ItemMeta>Мастер Олег Смирнов · гарантия 6 месяцев</Timeline.ItemMeta>
39
40
  <Timeline.ItemValue>
40
41
  2 800 ₽<Timeline.ItemMeta>Ремонт</Timeline.ItemMeta>
41
42
  </Timeline.ItemValue>
@@ -94,7 +94,7 @@ Text has no interactive states.
94
94
  - No outer margins: spacing comes from the parent's `gap`.
95
95
  - Title, heading and display roles balance their lines (`text-wrap-style: balance`); body and caption avoid a lone last word (`pretty`). Long words break (`overflow-wrap: break-word`).
96
96
  - `code` uses the mono family (JetBrains Mono); every other role the sans family (Golos Text).
97
- - Reading text: cap the column at the reading measure (PageContent `maxWidth="readable"`, 60–75 characters).
97
+ - Reading text: cap the column at the reading measure (`Page.Root maxWidth="readable"`, 60–75 characters).
98
98
  - `truncate` needs a block element and a shrinking parent (`min-width: 0` in flex rows).
99
99
 
100
100
  ## Accessibility
@@ -138,4 +138,4 @@ No `labels`.
138
138
 
139
139
  ## Related
140
140
  - **Built from:** —
141
- - **See also:** [LinkButton](../link-button/COMPONENT.md), [CodeBlock](../code-block/COMPONENT.md), [Label](../label/COMPONENT.md), [PageContent](../page-content/COMPONENT.md)
141
+ - **See also:** [LinkButton](../link-button/COMPONENT.md), [CodeBlock](../code-block/COMPONENT.md), [Label](../label/COMPONENT.md), [Page](../../layout/page/COMPONENT.md)
@@ -3,16 +3,16 @@
3
3
  **Category:** page
4
4
  **Kind:** layout
5
5
 
6
- > The app frame: a content panel that is the page itself and a navigation rail one layer above it.
6
+ > The app frame — navigation and the page: a content panel that is the page itself and a navigation rail one layer above it.
7
7
 
8
8
  ## When to use
9
- - The root layout of an application: navigation column, an optional AppHeader, scrolling main column, a bottom bar for phone navigation.
9
+ - The root layout of an application: navigation column, the scrolling main where the page renders, a bottom bar for phone navigation.
10
10
  - Any page that needs the kit's responsive gutters and the surface ladder for cards and fields.
11
11
 
12
12
  ## When not to use
13
13
  - The navigation itself → use [Sidebar](../sidebar/COMPONENT.md) inside `AppShell.Nav`, [BottomNav](../bottom-nav/COMPONENT.md) inside `AppShell.Footer`.
14
- - The page's top bar (the page title, its tools, the menu button) → use [AppHeader](../app-header/COMPONENT.md) anywhere in the shell: it renders in the shell's header row.
15
- - Page heading, actions and sections inside main → use [PageContent](../../components/page-content/COMPONENT.md).
14
+ - Anything at the top of the page — the title, its actions and tools, the phone menu button → the page's own top bar, [Page](../page/COMPONENT.md) `Page.TopBar`; the shell has no header.
15
+ - Page heading, actions and sections inside main → use [Page](../page/COMPONENT.md).
16
16
  - A temporary side panel over the page → use [Drawer](../../components/drawer/COMPONENT.md).
17
17
  - A scroll region inside a page → use [ScrollContainer](../../components/scroll-container/COMPONENT.md).
18
18
 
@@ -25,25 +25,24 @@ import { AppShell } from "prime-ui-kit";
25
25
  ```
26
26
  AppShell.Root grid: nav column | content panel (the page, layer 0)
27
27
  ├─ AppShell.Nav navigation column (usually Sidebar.Root, a surface one layer above the page)
28
- ├─ (header row) the panel's top: the latest AppHeader.Root in the shell renders here
29
- ├─ AppShell.Main <main>, scrolls, carries the gutters
28
+ ├─ AppShell.Main <main>, scrolls; hands the page (Page.Root) its gutters and top air
30
29
  └─ AppShell.Footer sticky bottom bar of the panel (usually BottomNav.Root)
31
- AppShell.Template Root + Nav + the header + Main + Footer in one component
30
+ AppShell.Template Root + Nav + Main + Footer in one component
32
31
  useAppShellNav() the navigation the Sidebar publishes, for triggers outside the rail
33
32
  ```
34
- Every child of Root that is not `AppShell.Nav` is placed into the content panel. An `AppHeader.Root` anywhere in the shell — a child of Root, `Template.header`, a page's own one in main — renders in the header row; the latest one on screen wins, so a page's header replaces the default while that page is shown.
33
+ Every child of Root that is not `AppShell.Nav` is placed into the content panel. Everything at the top of the panel belongs to the page: its `Page.TopBar` sticks to the top of main.
35
34
 
36
35
  ## API
37
36
 
38
37
  <!-- Generated from api.ts by `bun run docs:build`. Edit api.ts, not this section. -->
39
38
 
40
39
  ### AppShell.Root
41
- `ref` → `HTMLDivElement`. Grid of the nav column and the content panel (the page itself); every child but `AppShell.Nav` goes into the panel. Owns the navigation its Sidebar publishes (`useAppShellNav`) and the header row an `AppHeader.Root` anywhere in it renders in.
40
+ `ref` → `HTMLDivElement`. Grid of the nav column and the content panel (the page itself); every child but `AppShell.Nav` goes into the panel. Owns the navigation its Sidebar publishes (`useAppShellNav`).
42
41
 
43
42
  | Prop | Type | Default | Description |
44
43
  |---|---|---|---|
45
44
  | `fillViewport` | `boolean` | `false` | The shell is exactly the viewport high and only `AppShell.Main` scrolls; otherwise the document scrolls and the nav is sticky. |
46
- | `…rest` | `HTMLAttributes<HTMLDivElement>` | — | `children` (Nav, `AppHeader.Root`, Main, Footer), `className` and the other div attributes. |
45
+ | `…rest` | `HTMLAttributes<HTMLDivElement>` | — | `children` (Nav, Main, Footer), `className` and the other div attributes. |
47
46
 
48
47
  ### AppShell.Nav
49
48
  `ref` → `HTMLDivElement`. The navigation column slot (not a landmark: Sidebar renders the `<nav>`).
@@ -53,11 +52,10 @@ Every child of Root that is not `AppShell.Nav` is placed into the content panel.
53
52
  | `…rest` | `HTMLAttributes<HTMLDivElement>` | — | `children` (usually `Sidebar.Root`), `className` and the other div attributes. |
54
53
 
55
54
  ### AppShell.Main
56
- `ref` → `HTMLElement`. The `<main>` with the canonical gutters: a vertical `ScrollContainer`.
55
+ `ref` → `HTMLElement`. The `<main>` where the page renders: a vertical `ScrollContainer` that hands `Page.Root` the gutters and top air (`--page-gutter`, `--page-top`).
57
56
 
58
57
  | Prop | Type | Default | Description |
59
58
  |---|---|---|---|
60
- | `contentWidth` | `"contained" \| "full"` | `"full"` | `full` — the whole panel with gutters; `contained` — a centred column up to `--prime-layout-content-max-width`. |
61
59
  | `…rest` | `HTMLAttributes<HTMLElement>` | — | `children`, `className` and the other attributes. |
62
60
 
63
61
  ### AppShell.Footer
@@ -68,17 +66,16 @@ Every child of Root that is not `AppShell.Nav` is placed into the content panel.
68
66
  | `…rest` | `HTMLAttributes<HTMLDivElement>` | — | `children` (usually `BottomNav.Root`), `className` and the other div attributes. |
69
67
 
70
68
  ### AppShell.Template
71
- `ref` → the `<main>`. Root + Nav + the header + Main + Footer in one; main scrolls to the top when `scrollResetKey` changes.
69
+ `ref` → the `<main>`. Root + Nav + Main + Footer in one; main scrolls to the top when `scrollResetKey` changes.
72
70
 
73
71
  | Prop | Type | Default | Description |
74
72
  |---|---|---|---|
75
73
  | `fillViewport` | `boolean` | `false` | As on `AppShell.Root`: only `<main>` scrolls. |
76
74
  | `nav` | `ReactNode` | — | Navigation column content; without it the panel takes the full width. |
77
- | `header` | `ReactNode` | — | The default header row, an `AppHeader.Root`: a page that renders its own header replaces it while that page is on screen. |
78
75
  | `footer` | `ReactNode` | — | Footer content (`BottomNav`); no footer when omitted. |
79
- | `mainProps` | `Omit<AppShellMainProps, "children">` | — | Props for Main (e.g. `contentWidth`). |
76
+ | `mainProps` | `Omit<AppShellMainProps, "children">` | — | Props for Main (`id`, `tabIndex` for a skip link). |
80
77
  | `scrollResetKey` | `unknown` | — | Main scrolls back to the top whenever this value changes; pass the router pathname. |
81
- | `children` | `ReactNode` | — | Page content inside Main. |
78
+ | `children` | `ReactNode` | — | The page inside Main (`Page.Root`). |
82
79
  | `…rest` | `Omit<AppShellRootProps, "children">` | — | Root props: `fillViewport`, `className` and the div attributes. |
83
80
 
84
81
  ### Types
@@ -108,38 +105,29 @@ The navigation of the nearest `AppShell.Root` for a trigger outside the rail (a
108
105
  | Value | Looks like | Use when | Default |
109
106
  |---|---|---|---|
110
107
  | `false` | Shell at least viewport high; the document scrolls; nav sticks to the top | Content sites, simple apps | yes |
111
- | `true` | Shell exactly viewport high; only Main scrolls; header and nav stay put | Dense apps with a fixed frame | |
112
-
113
- ### contentWidth (Main)
114
- | Value | Looks like | Use when | Default |
115
- |---|---|---|---|
116
- | `full` | Content spans the panel with responsive gutters | Tables, dashboards | yes |
117
- | `contained` | Centred column up to the content max width | Long-read pages | |
108
+ | `true` | Shell exactly viewport high; only Main scrolls; nav and the page's sticky top bar stay put | Dense apps with a fixed frame | |
118
109
 
119
110
  ### Structure
120
111
  | Value | Looks like | Use when | Default |
121
112
  |---|---|---|---|
122
113
  | with `AppShell.Nav` | Two columns: a rail one layer above the page + the panel that is the page | Apps with navigation | |
123
114
  | without Nav | Panel takes the full width | Single-page tools, auth screens | |
124
- | with `AppHeader.Root` | Sticky bar in the header row at the top of the panel, from anywhere in the shell | The page title (or the path and the record), the page's tools and buttons; on a phone it leads with the menu button | |
125
115
  | with `AppShell.Footer` | Sticky bar at the bottom of the panel, shown while no navigation column is on screen | BottomNav on a phone | |
126
116
 
127
- `AppShell.Template` with `nav={<Sidebar.Root …/>}` and `PageContent` inside is the standard app; `contentWidth="contained"` + `PageContent.Root maxWidth="readable"` for docs and articles.
117
+ `AppShell.Template` with `nav={<Sidebar.Root …/>}` and a `Page.Root` inside is the standard app; `Page.Root maxWidth="readable"` for docs and articles.
128
118
 
129
119
  ## States
130
120
  | State | Driven by | DOM |
131
121
  |---|---|---|
132
122
  | fixed frame | `fillViewport` | `data-fill-viewport="true"` on Root |
133
123
  | navigation column | an `AppShell.Nav` child | `data-nav="true"` on Root (two grid columns) |
134
- | content width | `contentWidth` | `data-content-width` on Main |
135
124
  | off-canvas navigation | the Sidebar publishes that it is an off-canvas panel (`offCanvas="auto"` on a phone, `"always"`) | `data-off-canvas="true"` on Root; `useAppShellNav()` reports `offCanvas`, `open`, `navId` |
136
125
  | footer bar | the navigation column: `AppShell.Nav` with a Sidebar that is not off-canvas | the footer is `display: none` while the rail is on screen; without Nav or with an off-canvas Sidebar it stays at any width |
137
- | header row | an `AppHeader.Root` in the shell | the latest one on screen renders at the top of the panel, before main |
138
126
 
139
127
  ## Layout & spacing
140
128
  - Two full-height planes edge to edge: no inset, radius, shadow or border — the boundary is the fill change (the Sidebar rail is layer 1, the panel the page: white rail beside a gray page in light, a rail one step lighter than the near-black page in dark).
141
- - Gutters in Main (and in the header row): the page gutter `--prime-layout-gutter` — `--prime-layout-gutter-s` (16) → `-m` (24) from 640px → `-l` (32) from 1024px. Main top padding `--prime-space-6` (24) → `--prime-space-8` (32) from 1024px; bottom `--prime-space-16`. Inside Main the page gutter is the small one again, so a frame nested in the page starts from its own gutter, not the shell's.
142
- - A page that fills the panel height (`PageContent.Root fill`): Main's bottom padding drops to the side gutter, so no long scroll tail stays under it.
129
+ - Main hands the page its edge air: `--page-gutter` is the page gutter `--prime-layout-gutter` — `--prime-layout-gutter-s` (16) → `-m` (24) from 640px → `-l` (32) from 1024px; `--page-top` is `--prime-space-6` (24) → `--prime-space-8` (32) from 1024px. `Page.Root` pads itself with them (its top bar steps out to the panel's edges). Main itself pads only the bottom: `--prime-space-16`, the scroll tail of a long page. Inside Main the page gutter is the small one again, so a frame nested in the page starts from its own gutter, not the shell's.
130
+ - A page that fills the panel height (`Page.Root fill`): Main's bottom padding drops to the side gutter, so no long scroll tail stays under it — beside the Sidebar rail too.
143
131
  - Main scrolls with `overscroll-behavior: contain`, so its scroll never chains to the document.
144
132
  - Nav column: sticky at the top, viewport high, `z-index: --prime-z-sticky` (above the panel, so the compact Sidebar toggle can ride the rail edge); with `fillViewport` it fills the shell height instead.
145
133
  - Footer: no padding of its own (BottomNav keeps the bottom safe-area inset), sticky at the bottom, `z-index: --prime-z-sticky`.
@@ -156,8 +144,8 @@ No keyboard interaction.
156
144
  ### ARIA
157
145
  <!-- Generated from api.ts by `bun run docs:build`. Edit api.ts, not this section. -->
158
146
 
159
- - Main is the `<main>` landmark; the banner comes from AppHeader (`<header>`), the navigation landmarks from Sidebar and BottomNav (`<nav>`).
160
- - One `<h1>` per page: `AppHeader.Title` on app pages, `PageContent.Title` on a document page (whose header then has no title).
147
+ - Main is the `<main>` landmark; the navigation landmarks come from Sidebar and BottomNav (`<nav>`). The page's top bar is a `<header>` inside main, not a banner.
148
+ - One `<h1>` per page: its `Page.Title`, in the top bar or in the flow.
161
149
 
162
150
  ### Labels
163
151
  <!-- Generated from api.ts by `bun run docs:build`. Edit api.ts, not this section. -->
@@ -167,21 +155,20 @@ No `labels`.
167
155
  ## Examples
168
156
  | Example | Shows |
169
157
  |---|---|
170
- | [overview.tsx](examples/overview.tsx) | The app frame: Sidebar in the nav column, the page title and its action in the AppHeader, the page in main; only main scrolls — `fillViewport`. |
171
- | [contained.tsx](examples/contained.tsx) | A shell without navigation whose main column is centred and capped for long reads — `contentWidth`. |
158
+ | [overview.tsx](examples/overview.tsx) | The app frame: Sidebar in the nav column, the page in main with its title and action in its top bar; only main scrolls — `fillViewport`. |
172
159
  | [footer.tsx](examples/footer.tsx) | A phone app without a Sidebar: the bar in the footer stays at the bottom while main scrolls under it — `AppShell.Footer`. |
173
- | [template.tsx](examples/template.tsx) | Root, nav, header and main in one component; main scrolls back to the top whenever the page changes — `AppShell.Template`, `scrollResetKey`. |
174
- | [screen.tsx](examples/screen.tsx) | The app frame for desktop and phone: the Sidebar rail on a wide screen, the floating BottomNav in the footer on a phone whose More item opens the Sidebar, the AppHeader with the menu button it draws by itself, the page title with a line of data, and a simple home page that swaps with the current section — `fillViewport`, `scrollResetKey`, `useAppShellNav`. |
160
+ | [template.tsx](examples/template.tsx) | Root, nav, main and footer in one component; main scrolls back to the top whenever the page changes — `AppShell.Template`, `scrollResetKey`. |
161
+ | [screen.tsx](examples/screen.tsx) | The app frame for desktop and phone: the Sidebar rail on a wide screen, the floating BottomNav in the footer on a phone whose More item opens the Sidebar, the page top bar with the menu button it draws by itself, the page title with a line of data, and a simple home page that swaps with the current section — `fillViewport`, `scrollResetKey`, `useAppShellNav`. |
175
162
 
176
163
  ## Mistakes
177
- - Adding padding around the page content → Main already has the gutters.
164
+ - Adding padding around the page content → `Page.Root` takes the gutters Main hands it.
178
165
  - Wrapping Main content in another scroll container → Main scrolls (with `fillViewport`) or the document does.
179
166
  - A border or shadow between nav and panel → the fill change is the boundary.
180
167
  - Putting the Sidebar directly in Root without `AppShell.Nav` → it lands inside the content panel.
181
168
  - BottomNav anywhere but `AppShell.Footer` → it stays next to the Sidebar rail on a desktop; the footer is what leaves while the rail is on screen.
182
169
  - `AppShell.Template` in a router app without `scrollResetKey` → a new page opens at the old scroll position; pass the pathname.
183
- - A hand-wired menu state shared by the Sidebar, a menu button and a BottomNav «Ещё» → the Sidebar publishes it to the shell: the AppHeader draws the menu button, other triggers read `useAppShellNav()`.
170
+ - A hand-wired menu state shared by the Sidebar, a menu button and a BottomNav «Ещё» → the Sidebar publishes it to the shell: the page's `Page.TopBar` draws the menu button, other triggers read `useAppShellNav()`.
184
171
 
185
172
  ## Related
186
173
  - **Built from:** [ScrollContainer](../../components/scroll-container/COMPONENT.md)
187
- - **See also:** [AppHeader](../app-header/COMPONENT.md), [Sidebar](../sidebar/COMPONENT.md), [BottomNav](../bottom-nav/COMPONENT.md), [PageContent](../../components/page-content/COMPONENT.md), [Breadcrumb](../../components/breadcrumb/COMPONENT.md)
174
+ - **See also:** [Page](../page/COMPONENT.md), [Sidebar](../sidebar/COMPONENT.md), [BottomNav](../bottom-nav/COMPONENT.md), [Breadcrumb](../../components/breadcrumb/COMPONENT.md)