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
@@ -35,12 +35,12 @@ Things that belong together sit closer than things that do not.
35
35
  | inline controls in a row (buttons, filters) | 8 | `--prime-space-2` |
36
36
  | switch → switch in a settings list | 20 | `--prime-space-5` |
37
37
  | group → group (fieldset, form section) | 32 | `--prime-space-8` |
38
- | tile → tile, both axes (KPI cards, charts, panels) | 16 | `--prime-space-4` — `PageContent.Grid` already does it |
39
- | block → block on a page (page header → body too) | 24 | `--prime-space-6` — `PageContent` already does it |
40
- | section → section on a page (a new topic with an `h2`) | 40 | `PageContent.Section` already does it |
38
+ | tile → tile, both axes (KPI cards, charts, panels) | 16 | `--prime-space-4` — `Page.Grid` already does it |
39
+ | block → block on a page (page header → body too) | 24 | `--prime-space-6` — `Page` already does it |
40
+ | section → section on a page (a new topic with an `h2`) | 40 | `Page.Section` already does it |
41
41
 
42
- `PageContent.Body` already spaces its direct blocks 24 apart, a `PageContent.Section` 40 from its
43
- neighbours, `PageContent.Grid` its tiles 16 on both axes, and `AppShell.Main` already carries the page
42
+ `Page.Body` already spaces its direct blocks 24 apart, a `Page.Section` 40 from its
43
+ neighbours, `Page.Grid` its tiles 16 on both axes, and `AppShell.Main` already hands the page its
44
44
  gutters — do not add your own outer padding.
45
45
 
46
46
  ## 3. Size axis
@@ -143,10 +143,10 @@ A chart color does one job, and the job picks the colors:
143
143
  | `body-m` | 14/20 | default text |
144
144
  | `body-l` | 16/24 | reading text |
145
145
  | `title-s` | 14/20 600 | card title, group heading inside a card or form |
146
- | `title-m` | 16/24 600 | page section heading (`PageContent.Section` draws it), modal title |
146
+ | `title-m` | 16/24 600 | page section heading (`Page.Section` draws it), modal title |
147
147
  | `title-l` | 18/24 600 | large block title |
148
148
  | `heading-s` | 20/28 600 | page sub-heading |
149
- | `heading-m` | 24/32 600 | the title of a document page (`PageContent.Title`); an app page titles itself in `AppHeader.Title` (`title-s`) |
149
+ | `heading-m` | 24/32 600 | the page title in the flow (`Page.Title` of a document page or an overview); in `Page.TopBar` the same `Page.Title` is `title-m` |
150
150
  | `heading-l` | 30/36 600 | marketing / auth title |
151
151
  | `display-*` | 36–60 | hero numbers only |
152
152
  | `code` | 13/20 mono | identifiers, inline code |
@@ -154,7 +154,7 @@ A chart color does one job, and the job picks the colors:
154
154
  `variant` is required on `Typography`. Weights only 400/500/600. Numbers in tables, prices, dates:
155
155
  tabular (the kit does it in DataTable `numeric` columns and `Card.Value`; your own amounts take
156
156
  `font-variant-numeric: tabular-nums`). Reading text max width `--prime-layout-reading-max-width`
157
- (`PageContent.Root maxWidth="readable"`).
157
+ (`Page.Root maxWidth="readable"`).
158
158
 
159
159
  ### Text colour
160
160
 
@@ -174,7 +174,7 @@ level of air: a page with uniform 16px gaps everywhere reads as a list of unrela
174
174
  the [breakpoints and their scope](responsive.md#breakpoints), the
175
175
  [intrinsic grids](responsive.md#intrinsic-grids), what the kit adapts by itself and touch.
176
176
  - Flex children with text: `min-width: 0` + ellipsis or `overflow-wrap: anywhere`.
177
- - Sticky parts come from the kit: `AppHeader` (with the `PageToolbar` in `AppHeader.Tools`), the
177
+ - Sticky parts come from the kit: `Page.TopBar` (with all its groups), the
178
178
  DataTable head and `stickyFirstColumn`, the Gantt header and first column — each sticks inside its
179
179
  own scroller, and the top ones let go on screens lower than 480px. Never a `position: sticky` bar of your own.
180
180
 
@@ -1,14 +1,16 @@
1
1
  # Layouts — app frame, page wrappers, auth
2
2
 
3
- Every screen sits in one frame: `AppShell.Root` with the Sidebar in `AppShell.Nav`, a header row and
3
+ The app is navigation and the page: `AppShell.Root` with the Sidebar in `AppShell.Nav` and
4
4
  `AppShell.Main` (the content panel is the page, the nav rail one layer above it). The frame is the
5
- app's; the header row and the body are the page's — a screen renders its own `AppHeader.Root` (the
6
- page title and the page's tools, [composition.md](composition.md#1-page-skeleton)) and its body in
7
- `PageContent`.
8
- `AppShell.Main` carries the page gutters and `PageContent` spaces the page — blocks 24, a titled
9
- `PageContent.Section` 40, tiles in a `PageContent.Grid` 16 on both axes — so your code adds **no outer padding and no margins**. Your CSS only lays out the inside of a block (grids, rows) with `gap` on `--prime-space-*`.
10
- Main's top air under the header is part of the frame — 24, then 32 from 1024px: the page's first block
11
- starts there; never cancel it with a negative margin or a padding override.
5
+ app's; everything inside Main is the page's — a screen renders one `Page.Root` with its own top
6
+ (`Page.TopBar`: the page title and the page's tools, [composition.md](composition.md#1-page-skeleton))
7
+ and its body in `Page.Body`.
8
+ `AppShell.Main` hands the page its gutters and its edge air and `Page` spaces it — blocks 24, a titled
9
+ `Page.Section` 40, tiles in a `Page.Grid` 16 on both axes — so your code adds **no outer padding and no margins**. Your CSS only lays out the inside of a block (grids, rows) with `gap` on `--prime-space-*`.
10
+ The edge air is part of the frame. On top: 24, then 32 from 1024px, where a page without a bar
11
+ starts; under a `Page.TopBar` the body starts 24 below the bar's controls. At the bottom: a long
12
+ page keeps a 64 scroll tail, a `Page.Root fill` page only the side gutter, beside the Sidebar rail
13
+ as well. Never cancel it with a negative margin or a padding override.
12
14
 
13
15
  The page recipes are whole, working screens — the `screen.tsx` example of their main component
14
16
  ([the list](composition.md#screens)): start from the closest one and keep its skeleton. The rules behind them are in [composition.md](composition.md).
@@ -16,14 +18,13 @@ The page recipes are whole, working screens — the `screen.tsx` example of thei
16
18
  ## App frame (once per app)
17
19
 
18
20
  The frame is the root layout and nothing else: the providers, `AppShell.Root`, the Sidebar in
19
- `AppShell.Nav` and `AppShell.Main` around the page. It holds no header content and no menu state:
21
+ `AppShell.Nav` and `AppShell.Main` around the page. It holds no header and no menu state:
20
22
 
21
- - **The header row belongs to the page.** An `AppHeader.Root` anywhere inside the shell — the page's
22
- own one, rendered at the top of its body — shows in the shell's header row; the latest one on
23
- screen wins, so every page brings its own. Its row is as high as the Sidebar brand row, so the brand
24
- and the title read as one line. Nothing app-wide goes into it — no global search, no notifications.
23
+ - **Everything at the top belongs to the page.** There is no app-wide header and no global search:
24
+ every page renders its own `Page.TopBar` with only what it needs. Its title row is as high as the
25
+ Sidebar brand row, so the brand and the title read as one line.
25
26
  - **The phone menu comes with the frame.** Below 768px the Sidebar becomes an off-canvas panel
26
- (`offCanvas="auto"`) and the AppHeader leads with the menu button that opens it by itself — never a
27
+ (`offCanvas="auto"`) and `Page.TopBar` leads with the menu button that opens it by itself — never a
27
28
  menu state or a menu button wired by hand. A trigger outside the rail (a BottomNav «Ещё», your own
28
29
  button) reads the shell's navigation with `useAppShellNav()` (`open`, `setOpen`, `navId`; see
29
30
  [the app frame screen](reference/layout/app-shell/examples/screen.tsx)).
@@ -90,37 +91,33 @@ export function AppFrame({ children }: { children: ReactNode }) {
90
91
  }
91
92
  ```
92
93
 
93
- Every page renders its header and its body; the header shows in the frame's header row:
94
+ Every page renders its top and its body in one `Page.Root`:
94
95
 
95
96
  ```tsx
96
- import { AppHeader, PageContent } from "prime-ui-kit";
97
+ import { Page } from "prime-ui-kit";
97
98
 
98
99
  export function OrdersPage() {
99
100
  return (
100
- <>
101
- <AppHeader.Root>
102
- <AppHeader.Start>
103
- <AppHeader.Title>
104
- Заказы
105
- <AppHeader.Description>128 в работе · 6 ждут оплаты</AppHeader.Description>
106
- </AppHeader.Title>
107
- </AppHeader.Start>
108
- </AppHeader.Root>
109
- <PageContent.Root as="section">
110
- <PageContent.Body>{/* the page's blocks */}</PageContent.Body>
111
- </PageContent.Root>
112
- </>
101
+ <Page.Root>
102
+ <Page.TopBar>
103
+ <Page.Heading>
104
+ <Page.Title>Заказы</Page.Title>
105
+ <Page.Description>128 в работе · 6 ждут оплаты</Page.Description>
106
+ </Page.Heading>
107
+ </Page.TopBar>
108
+ <Page.Body>{/* the page's blocks */}</Page.Body>
109
+ </Page.Root>
113
110
  );
114
111
  }
115
112
  ```
116
113
 
117
- A document page (settings, a long form, help) renders an `AppHeader.Root` without a title — only
118
- its own buttons, and on a phone the menu button the header draws — and opens its body with
119
- `PageContent.Header`.
114
+ What stands in the bar — the path ending in the title, the tools, every button, the active filters —
115
+ is [the top bar](composition.md#the-top-bar); where the title stands on a document page or an
116
+ overview is [the page skeleton](composition.md#1-page-skeleton).
120
117
 
121
118
  With React Router the frame's `children` is `<Outlet />` and every item is `Sidebar.Item asChild`
122
119
  around a `NavLink` ([the router example](reference/layout/sidebar/examples/router.tsx)). The same frame
123
- as one component is `AppShell.Template` (`nav`, `footer`, the page as children); give it the
120
+ as one component is `AppShell.Template` (`nav`, `footer`, `mainProps`, the page as children); give it the
124
121
  pathname as `scrollResetKey`, so a new page opens at the top.
125
122
 
126
123
  Phone navigation for 2–6 main sections is a `BottomNav.Root` in `AppShell.Footer` (the last child of
@@ -133,60 +130,6 @@ Next.js App Router: the package is marked `"use client"`, but a server component
133
130
  `"use client"` and render them from `app/layout.tsx` and the pages; import `bundle.css` in the root
134
131
  layout and put `data-theme` on `<html>` there.
135
132
 
136
- A nested record page puts the path up before its title in the header — `Breadcrumb` (the list it
137
- belongs to), `AppHeader.Separator`, `AppHeader.Title` with the record's name and its status as
138
- the description ([the detail page](reference/components/description-list/examples/screen.tsx)).
139
-
140
- ### The page's tools in the header
141
-
142
- The page's tools — its own search and filters, sections, the period or view, the primary action —
143
- go into `AppHeader.Tools` as a `PageToolbar.Root`: the header's second row, full width, sticky with
144
- it. The toolbar lays itself out from that width ([the page panel](responsive.md#page-panel--pagetoolbar)),
145
- so the tools wrap under the title instead of squeezing it. `AppHeader.Actions` keeps the page's
146
- other buttons (export, a more menu) in the title row.
147
-
148
- ```tsx
149
- import { AppHeader, Button, Icon, PageToolbar, SegmentedControl } from "prime-ui-kit";
150
-
151
- type DealsHeaderProps = { view: string; onViewChange: (view: string) => void };
152
-
153
- export function DealsHeader({ view, onViewChange }: DealsHeaderProps) {
154
- return (
155
- <AppHeader.Root>
156
- <AppHeader.Start>
157
- <AppHeader.Title>
158
- Сделки
159
- <AppHeader.Description>7 сделок в работе · 6 461 750 ₽</AppHeader.Description>
160
- </AppHeader.Title>
161
- </AppHeader.Start>
162
- <AppHeader.Tools>
163
- <PageToolbar.Root aria-label="Сделки">
164
- <PageToolbar.Sections>
165
- <SegmentedControl.Root
166
- fullWidth
167
- value={view}
168
- onValueChange={onViewChange}
169
- aria-label="Вид"
170
- >
171
- <SegmentedControl.Item value="board">Доска</SegmentedControl.Item>
172
- <SegmentedControl.Item value="list">Список</SegmentedControl.Item>
173
- </SegmentedControl.Root>
174
- </PageToolbar.Sections>
175
- <PageToolbar.Actions>
176
- <Button.Root>
177
- <Button.Icon>
178
- <Icon name="action.add" />
179
- </Button.Icon>
180
- Новая сделка
181
- </Button.Root>
182
- </PageToolbar.Actions>
183
- </PageToolbar.Root>
184
- </AppHeader.Tools>
185
- </AppHeader.Root>
186
- );
187
- }
188
- ```
189
-
190
133
  ## Navigation structure (the sidebar's content)
191
134
 
192
135
  The sidebar is the product's map: people scan it, remember where things are and come back. Build it
@@ -208,20 +151,20 @@ shows only icons); none on the children of a sub-list.
208
151
 
209
152
  ## Page wrapper
210
153
 
211
- - App pages (dashboard, list, detail, a board): `PageContent.Root as="section"` — the full width of
212
- the panel; the page's title and tools are in its `AppHeader`, its blocks go into
213
- `PageContent.Body` ([the page skeleton](composition.md#1-page-skeleton)).
214
- - Document pages — settings and long forms: `PageContent.Root maxWidth="wide"` with `PageContent.Header`
215
- (the page's h1) and a `PageContent.Section layout="aside"`
216
- (heading column + panel) per section ([the settings page](reference/components/page-content/examples/screen.tsx)), or `maxWidth="readable"` for a single
154
+ - App pages (dashboard, list, detail, a board): `Page.Root` — the full width of the panel; the
155
+ page's title and tools are in its `Page.TopBar`, its blocks go into `Page.Body`
156
+ ([the page skeleton](composition.md#1-page-skeleton)).
157
+ - Document pages — settings and long forms: `Page.Root maxWidth="wide"` with `Page.Header` in the
158
+ flow (the page's h1) and a `Page.Section layout="aside"` (heading column + panel) per section
159
+ ([the settings page](reference/layout/page/examples/screen.tsx)), or `maxWidth="readable"` for a single
217
160
  narrow column of fields.
218
- - Long reading text (terms, help): `PageContent.Root maxWidth="readable"` with `PageContent.Header`.
161
+ - Long reading text (terms, help): `Page.Root maxWidth="readable"` with `Page.Header` in the flow.
219
162
  - A page as high as the panel (a log, a board, a chat): `AppShell.Root fillViewport` +
220
- `PageContent.Root fill`; the body passes its free height to a filling child — DataTable
221
- `scrollHeight="fill"`, Crossfade `fill`, `PageContent.Split`. Never compute heights from `100vh`.
222
- - List + detail (mail, a messenger, a ticket queue): `PageContent.Split` with `PageContent.Panel kind="list"` and
223
- `PageContent.Panel kind="detail"` in a filling page. Side by side from 48rem of the split's own width, one pane
224
- at a time below it with `PageContent.BackButton` first in the detail's header; `open` is «a record
163
+ `Page.Root fill`; the body passes its free height to a filling child — DataTable
164
+ `scrollHeight="fill"`, Crossfade `fill`, `Page.Split`. Never compute heights from `100vh`.
165
+ - List + detail (mail, a messenger, a ticket queue): `Page.Split` with `Page.List` and
166
+ `Page.Detail` in a filling page. Side by side from 48rem of the split's own width, one pane
167
+ at a time below it with `Page.BackButton` first in the detail's header; `open` is «a record
225
168
  is chosen». Each pane gives its last child the free height: a Card with its own `ScrollContainer`
226
169
  (`anchor="end"` for a thread). The records in the list pane are a `List` (`current` on the open
227
170
  one), the conversations of a messenger a `ChatList`. Details that open over a table and close
@@ -72,7 +72,7 @@ Avatar.Group overlapping row, gives its size to members
72
72
  | `…rest` | `Omit<HTMLAttributes<HTMLSpanElement>, "children">` | — | `className` and the other span attributes. |
73
73
 
74
74
  ### Avatar.Group
75
- `ref` → `HTMLDivElement`. An overlapping row (`role="group"`); members overlap by 25% with a ring in `--avatar-ring`.
75
+ `ref` → `HTMLDivElement`. An overlapping row (`role="group"`); members overlap by an eighth of the diameter with a ring in `--avatar-ring`.
76
76
 
77
77
  | Prop | Type | Default | Description |
78
78
  |---|---|---|---|
@@ -119,7 +119,7 @@ The soft fill is opaque: the soft hue is composited over the ground the avatar s
119
119
  ## Layout & spacing
120
120
  - Inline-flex, never shrinks, `vertical-align: middle`.
121
121
  - Avatar → name: space step 3 (12px) in lists and cards, step 2 (8px) in table cells.
122
- - Group: members overlap by 25% of the diameter with a 2px ring in the ground they stand on: the current layer of the surface around them (no surface sets anything), or `--avatar-ring` from a host whose ground is not a layer (a reaction chip sets its own fill); the fills of initials and «+N» are composited over the same ground.
122
+ - Group: members overlap by an eighth of the diameter (initials are never cut) with a 2px ring in the ground they stand on: the current layer of the surface around them (no surface sets anything), or `--avatar-ring` from a host whose ground is not a layer (a reaction chip sets its own fill); the fills of initials and «+N» are composited over the same ground.
123
123
  - An icon fallback is half the diameter: a kit `Icon` reads `--prime-icon-size`, a raw svg too.
124
124
 
125
125
  ## Accessibility
@@ -28,7 +28,7 @@ const MEMBERS: { name: string; initials: string; color: PaletteColor; src?: stri
28
28
 
29
29
  export default function AvatarTeamGroupExample() {
30
30
  return (
31
- <Avatar.Group size="s" aria-label="Участники проекта: 7">
31
+ <Avatar.Group size="l" aria-label="Участники проекта: 7">
32
32
  {MEMBERS.map((member) => (
33
33
  <Avatar.Root key={member.initials} color={member.color} aria-label={member.name}>
34
34
  {member.src ? <Avatar.Image src={member.src} /> : null}
@@ -12,6 +12,7 @@
12
12
  - A selected value, keyword or applied filter the user can remove (`onRemove`).
13
13
  - Values in a filter panel that toggle on press and hide with a hover action (the `pressed` triad, `Badge.Action`).
14
14
  - A short code as a square tile (a file format «PDF») — `shape="square"`.
15
+ - Several badges as one value (the tags of a client, a record's labels) — `Badge.Group`: it wraps and keeps one gap.
15
16
 
16
17
  ## When not to use
17
18
  - A multi-select field with chips → use [TagSelect](../tag-select/COMPONENT.md) (it renders badges itself).
@@ -33,6 +34,8 @@ Badge.Root <span>: fill, tier dimensions
33
34
  │ (a toggle <button> with the pressed triad; a <span> with a trailing segment; none when read-only)
34
35
  ├─ Badge.Action optional end segment revealed on hover / focus (always shown on touch screens)
35
36
  └─ remove segment with onRemove: full height, the whole end is the hit area (Icon action.close)
37
+
38
+ Badge.Group <div>: a wrapping row of Badge.Root, one value; `size` sets every badge's tier
36
39
  ```
37
40
 
38
41
  ## API
@@ -60,6 +63,14 @@ Badge.Root <span>: fill, tier dimensions
60
63
  | `children` | `ReactNode` | — | Text, `Badge.Dot`, `Badge.Icon`, one `Badge.Action`. Only `Badge.Icon` children (no remove or action) make a square icon-only badge. |
61
64
  | `…rest` | `Omit<HTMLAttributes<HTMLSpanElement>, "onClick" \| "color">` | — | `aria-label` (an icon-only badge named by it is an image) and the other span attributes; no `onClick` — a pressable chip is the toggle. |
62
65
 
66
+ ### Badge.Group
67
+ `ref` → `HTMLDivElement`. A row of badges as one value (the tags of a record): it wraps onto more lines, the badges a chip gap apart.
68
+
69
+ | Prop | Type | Default | Description |
70
+ |---|---|---|---|
71
+ | `size` | `"xs" \| "s" \| "m" \| "l" \| "xl"` | the host tier, one step down | Tier of every badge in the group; a badge's own `size` wins. Small tiers stand closer. |
72
+ | `…rest` | `HTMLAttributes<HTMLDivElement>` | — | `children` (the `Badge.Root`s), `className`, `aria-label` (a named group is `role="group"`) and the other div attributes. |
73
+
63
74
  ### Badge.Icon
64
75
  `ref` → `HTMLSpanElement`. A `<span>` holding one icon at the tier icon size. At the first or last position it becomes a full-height edge segment.
65
76
 
@@ -163,7 +174,7 @@ A status takes `tone`; a category takes `color`. The two never go together (the
163
174
  - `Badge.Dot` is 6px, 8px from `l`; alone it takes the tier of the surrounding control; `color` paints it in the solid step of that hue.
164
175
  - The root never clips: the text ellipsizes in its own box, so the segments' touch areas reach past the chip.
165
176
  - `Badge.Action` room is reserved, so revealing it never changes the badge width.
166
- - Several badges in a row: `gap: var(--prime-space-2)`.
177
+ - Several badges in a row: `Badge.Group` — it wraps, badges 8 apart (4 at the `xs` and `s` tiers).
167
178
  - In a list row the badge is the trailing column; the title column gets `min-width: 0` and an ellipsis.
168
179
 
169
180
  ## Accessibility
@@ -206,6 +217,7 @@ A status takes `tone`; a category takes `color`. The two never go together (the
206
217
  | [server-tags.tsx](examples/server-tags.tsx) | Order tags removed on the server: a badge waits dimmed with a spinner, leaves once the server agrees and stays with an announcement when it refuses — `onRemove`, `labels`. |
207
218
  | [filter-values.tsx](examples/filter-values.tsx) | Filter values as toggles with a hide action that slides in without changing the width — `pressed`, `onPressedChange`, `Badge.Action`, `persistent`. |
208
219
  | [square.tsx](examples/square.tsx) | File formats as square tiles of text, large enough for three letters; the hue sorts them by kind — `shape`, `size`, `color`. |
220
+ | [tag-row.tsx](examples/tag-row.tsx) | The tags of a client as one value: the row wraps in a narrow column and keeps one gap between badges — `Badge.Group`, `size`. |
209
221
  | [controlled.tsx](examples/controlled.tsx) | Delivery cities as toggle chips whose state the screen owns: the summary counts the chosen ones — `pressed`, `onPressedChange`. |
210
222
 
211
223
  ## Mistakes
@@ -217,6 +229,7 @@ A status takes `tone`; a category takes `color`. The two never go together (the
217
229
  - Several removable badges with the default «Удалить» → pass `labels.remove` with the badge text.
218
230
  - A colored badge with no text → keep a word; color alone is not a signal.
219
231
  - An explicit `size` inside a control → drop it; the badge takes the tier one step down.
232
+ - A row of badges in a hand-made flex wrapper with its own gap → `Badge.Group`.
220
233
  - `onRemove` together with `Badge.Action` → one end segment per badge.
221
234
  - Removing the badge from your list first and putting it back when the request fails → return the request's promise and remove it after it succeeds; the badge waits meanwhile.
222
235
 
@@ -23,3 +23,10 @@
23
23
  align-items: center;
24
24
  gap: var(--prime-space-2);
25
25
  }
26
+
27
+ /* tag-row.tsx: a 320 px column, narrow enough for the row of badges to wrap. */
28
+ .column {
29
+ display: grid;
30
+ gap: var(--prime-space-6);
31
+ inline-size: min(100%, calc(var(--prime-space-20) * 4));
32
+ }
@@ -0,0 +1,34 @@
1
+ /** The tags of a client as one value: the row wraps in a narrow column and keeps one gap between badges — `Badge.Group`, `size`. */
2
+ import { Badge } from "prime-ui-kit";
3
+
4
+ import styles from "./examples.module.css";
5
+
6
+ const TAGS = [
7
+ { label: "Ключевой клиент", color: "purple" },
8
+ { label: "Оптовые закупки", color: "blue" },
9
+ { label: "Отсрочка 30 дней", color: "orange" },
10
+ { label: "ЭДО", color: "teal" },
11
+ { label: "Москва", color: "gray" },
12
+ { label: "Новый договор", color: "green" },
13
+ ] as const;
14
+
15
+ export default function BadgeTagRowExample() {
16
+ return (
17
+ <div className={styles.column}>
18
+ <Badge.Group aria-label="Теги клиента">
19
+ {TAGS.map((tag) => (
20
+ <Badge.Root key={tag.label} color={tag.color}>
21
+ {tag.label}
22
+ </Badge.Root>
23
+ ))}
24
+ </Badge.Group>
25
+ <Badge.Group size="s" aria-label="Теги заказа">
26
+ {TAGS.slice(0, 4).map((tag) => (
27
+ <Badge.Root key={tag.label} color={tag.color}>
28
+ {tag.label}
29
+ </Badge.Root>
30
+ ))}
31
+ </Badge.Group>
32
+ </div>
33
+ );
34
+ }
@@ -29,8 +29,8 @@ Banner.Root <div>; variant, tone, size, placement
29
29
  │ ├─ Banner.Icon one Icon on the first line (aria-hidden)
30
30
  │ ├─ Banner.Title
31
31
  │ ├─ Banner.Description
32
- │ └─ Banner.Actions buttons; with onDismiss the close button is last here
33
- └─ close button with onDismiss and no Actions: ghost icon Button (tone="inherit"), top-right
32
+ │ └─ Banner.Actions buttons; with onDismiss the close button is last here (wide banner)
33
+ └─ close button with onDismiss and no Actions, or Actions under the text: ghost icon Button (tone="inherit"), top-right
34
34
  ```
35
35
 
36
36
  ## API
@@ -72,7 +72,7 @@ Banner.Root <div>; variant, tone, size, placement
72
72
  | `…rest` | `HTMLAttributes<HTMLSpanElement>` | — | `children`, `className` and the other span attributes. |
73
73
 
74
74
  ### Banner.Actions
75
- `ref` → `HTMLDivElement`. A `<div>` row of buttons; with `onDismiss` the close button becomes its last square button.
75
+ `ref` → `HTMLDivElement`. A `<div>` row of buttons; with `onDismiss` the close button becomes its last square button (in the corner below 36rem).
76
76
 
77
77
  | Prop | Type | Default | Description |
78
78
  |---|---|---|---|
@@ -115,7 +115,7 @@ Banner.Root <div>; variant, tone, size, placement
115
115
  |---|---|---|
116
116
  | look | `variant`, `tone`, `size`, `placement` | `data-variant`, `data-tone`, `data-size`, `data-placement` |
117
117
  | dismissible | `onDismiss` | corner ghost Button (`xs`, `s` on `l` / `xl`), or the last outline Button in `Banner.Actions` |
118
- | narrow | own width < 36rem (a banner with `Banner.Actions` is a size container) | actions move under the text |
118
+ | narrow | own width < 36rem (a banner with `Banner.Actions` is a size container) | actions move under the text; the close button returns to the corner |
119
119
 
120
120
  No `open` prop: the parent mounts and unmounts the banner. A mounted banner enters (a short fade and rise); an unmounted one closes up in place, so the content below glides up instead of jumping. To swap the banner for another block in the same spot (a «restore» button), wrap both in [Crossfade](../crossfade/COMPONENT.md).
121
121
 
@@ -8,7 +8,8 @@
8
8
  min-width: 0;
9
9
  }
10
10
 
11
- /* page-strip.tsx: the page strip above a card with an inset banner. */
11
+ /* page-strip.tsx: a page — the strip spans its whole width, the content below keeps the page's
12
+ side padding, so the strip reads wider than the card with the inset banner. */
12
13
  .sections {
13
14
  display: flex;
14
15
  flex-direction: column;
@@ -17,6 +18,10 @@
17
18
  min-width: 0;
18
19
  }
19
20
 
21
+ .pageBody {
22
+ padding-inline: var(--prime-layout-gutter);
23
+ }
24
+
20
25
  /* narrow.tsx: a 320px column; the banner's container query moves actions under the text. */
21
26
  .narrow {
22
27
  width: min(100%, calc(var(--prime-space-20) * 4));
@@ -6,7 +6,7 @@ import styles from "./examples.module.css";
6
6
  export default function BannerPageStripExample() {
7
7
  return (
8
8
  <div className={styles.sections}>
9
- {/* In an app the strip stands first in the page, edge to edge above its content. */}
9
+ {/* In an app the strip stands first in the page, edge to edge above its padded content. */}
10
10
  <Banner.Root
11
11
  tone="warning"
12
12
  placement="page"
@@ -21,27 +21,29 @@ export default function BannerPageStripExample() {
21
21
  <Banner.Title>Пробный период закончится 12 октября</Banner.Title>
22
22
  </Banner.Content>
23
23
  </Banner.Root>
24
- <Card.Root variant="panel">
25
- <Card.Header>
26
- <Card.Title>Оплата</Card.Title>
27
- </Card.Header>
28
- <Card.Body>
29
- <Banner.Root tone="danger">
30
- <Banner.Content>
31
- <Banner.Icon>
32
- <Icon name="status.danger" />
33
- </Banner.Icon>
34
- <Banner.Title>Не удалось списать оплату</Banner.Title>
35
- <Banner.Description>
36
- Карта •••• 4242 отклонена банком. Обновите способ оплаты до 15 октября.
37
- </Banner.Description>
38
- <Banner.Actions>
39
- <Button.Root tone="danger">Обновить карту</Button.Root>
40
- </Banner.Actions>
41
- </Banner.Content>
42
- </Banner.Root>
43
- </Card.Body>
44
- </Card.Root>
24
+ <div className={styles.pageBody}>
25
+ <Card.Root variant="panel">
26
+ <Card.Header>
27
+ <Card.Title>Оплата</Card.Title>
28
+ </Card.Header>
29
+ <Card.Body>
30
+ <Banner.Root tone="danger">
31
+ <Banner.Content>
32
+ <Banner.Icon>
33
+ <Icon name="status.danger" />
34
+ </Banner.Icon>
35
+ <Banner.Title>Не удалось списать оплату</Banner.Title>
36
+ <Banner.Description>
37
+ Карта •••• 4242 отклонена банком. Обновите способ оплаты до 15 октября.
38
+ </Banner.Description>
39
+ <Banner.Actions>
40
+ <Button.Root tone="danger">Обновить карту</Button.Root>
41
+ </Banner.Actions>
42
+ </Banner.Content>
43
+ </Banner.Root>
44
+ </Card.Body>
45
+ </Card.Root>
46
+ </div>
45
47
  </div>
46
48
  );
47
49
  }
@@ -23,7 +23,7 @@ import { Breadcrumb } from "prime-ui-kit";
23
23
  ## Anatomy
24
24
  ```
25
25
  Breadcrumb.Root <nav aria-label> + <ol>; size; chevrons between levels; auto-collapse into a «…» menu
26
- ├─ Breadcrumb.Item <li>: a link (href → LinkButton), text, or the current page (current)
26
+ ├─ Breadcrumb.Item <li>: a link (href → LinkButton, or a router link with asChild), text, or the current page (current)
27
27
  └─ Breadcrumb.Ellipsis <li> with «…» for levels skipped on purpose
28
28
  ```
29
29
 
@@ -32,7 +32,7 @@ Breadcrumb.Root <nav aria-label> + <ol>; size; chevrons between levels
32
32
  <!-- Generated from api.ts by `bun run docs:build`. Edit api.ts, not this section. -->
33
33
 
34
34
  ### Breadcrumb.Root
35
- `ref` → `HTMLElement` (the `<nav>`). `<nav aria-label>` with an `<ol>`; draws the chevrons between levels, sets the size and, on narrow containers, collapses the middle levels into a «…» menu button that lists them.
35
+ `ref` → `HTMLElement` (the `<nav>`). `<nav aria-label>` with an `<ol>`; draws the chevrons between levels, sets the size and folds levels that do not fit into a «…» menu button that lists them: the middle ones, then the first one too.
36
36
 
37
37
  | Prop | Type | Default | Description |
38
38
  |---|---|---|---|
@@ -42,14 +42,15 @@ Breadcrumb.Root <nav aria-label> + <ol>; size; chevrons between levels
42
42
  | `…rest` | `HTMLAttributes<HTMLElement>` | — | `className` and the other `nav` attributes; an `aria-label` here overrides `labels.nav`. |
43
43
 
44
44
  ### Breadcrumb.Item
45
- `ref` → `HTMLLIElement`. `<li>`: a muted `LinkButton` (`href`), plain text, or the current page (`current`).
45
+ `ref` → `HTMLLIElement`. `<li>`: a muted `LinkButton` (`href`, or the consumer's router link with `asChild`), plain text, or the current page (`current`). A press on the link goes through `Page.Guard`.
46
46
 
47
47
  | Prop | Type | Default | Description |
48
48
  |---|---|---|---|
49
- | `href` | `string` | — | Renders a link; without it the item is text. |
49
+ | `href` | `string` | — | Renders a link; without it (and without `asChild`) the item is text. |
50
+ | `asChild` | `boolean` | `false` | The single child (a router `Link`) is the level's link with the same look; its own text is the level. In the «…» menu of a folded path it is the menu item. |
50
51
  | `current` | `boolean` | — | Current page: `aria-current="page"` (on the link when `href` is set), primary text, medium weight. Usually the last item, without `href`. |
51
52
  | `aria-label` | `string` | — | Name of a link without visible text (e.g. a home icon); set on the link, not the `li`. |
52
- | `children` | `ReactNode` | — | Text or an `Icon`. A string also becomes the `title` of a text item (full text when truncated). |
53
+ | `children` | `ReactNode` | — | Text or an `Icon`; with `asChild` one element. A string also becomes the `title` of a text item (full text when truncated). |
53
54
  | `…rest` | `Omit<LiHTMLAttributes<HTMLLIElement>, "aria-label">` | — | `className` and the other `li` attributes. |
54
55
 
55
56
  ### Breadcrumb.Ellipsis
@@ -77,6 +78,7 @@ Breadcrumb.Root <nav aria-label> + <ol>; size; chevrons between levels
77
78
  | text (no `href`, no `current`) | muted text | a level without its own page | yes |
78
79
  | current (`current`) | primary text, medium weight | the last item — this page | |
79
80
  | icon link (`href` + `aria-label`, `Icon` child) | icon at the tier icon size | a «home» root | |
81
+ | router link (`asChild`, one `Link` child) | the same muted link, the consumer's element | an app with a client router: the path moves without a reload | |
80
82
 
81
83
  Use links for every ancestor and `current` on the last item; `s` above a `heading-m` page title. Avoid `href` on the current item and two `current` items.
82
84
 
@@ -85,15 +87,17 @@ Use links for every ancestor and `current` on the last item; `s` above a `headin
85
87
  |---|---|---|
86
88
  | current | `current` | `aria-current="page"` on the text span, or on the link when the item has `href` |
87
89
  | hover / focus-visible on links | pointer / keyboard | text → primary; focus ring from LinkButton |
88
- | truncation | width | each level truncates with an ellipsis, max width `2 × --prime-space-24` (192; `--prime-space-24 + --prime-space-6`, 120, when its container is below 30rem — its own for 3+ levels, the nearest one above for 1–2); the last item shrinks last |
89
- | auto-collapse | 3+ levels and a container `< 30rem` | `data-collapsible="true"`; middle levels are `display: none` and replaced by «… ›»: a ghost menu button (`Dropdown.Trigger`, named by `labels.ellipsis`) whose menu lists them — links stay links, a level without `href` is a disabled row |
90
+ | truncation | width | each level truncates with an ellipsis, max width `2 × --prime-space-24` (192); the current page shrinks at half the rate of the others |
91
+ | auto-collapse | 2+ levels whose whole path does not fit the width uncut (measured on every resize) | `data-collapsible="true"`, `data-collapsed="true"`; middle levels are `display: none` and replaced by «… ›»: a ghost menu button (`Dropdown.Trigger`, named by `labels.ellipsis`) whose menu lists them — links stay links, a level without `href` is a disabled row |
92
+ | deep collapse | the path folded as above still does not fit | `data-collapsed="deep"`; the first level folds too: «…» › current page, the menu lists every level before it |
90
93
  | collapse menu open | a press, `Enter` or `ArrowDown` on the «…» | `aria-expanded="true"` on the button; a `role="menu"` panel at the tier size |
94
+ | held | a `Page.Guard` that is `busy` or `dirty` on the page | a press on a level's link (in the path or the «…» menu) stops before it navigates; `dirty` asks first, then repeats it |
91
95
 
92
- Root attributes: `data-size`, `data-collapsible` (`"true"` / `"false"`).
96
+ Root attributes: `data-size`, `data-collapsible` (`"true"` / `"false"`), `data-collapsed` (`"true"` / `"deep"`).
93
97
 
94
98
  ## Layout & spacing
95
- - A path of 1–2 levels takes its content width (at most the row), so in a flex row — the `AppHeader` start, before `AppHeader.Separator` and the title — what follows stands right after it. A path of 3+ levels is a size container (`container-type: inline-size`, `inline-size: 100%`) that folds its middle levels by its own width: inside a flex row give it `flex: 1 1 auto; min-width: 0`.
96
- - In an `AppHeader` the path up holds the list a record belongs to (1–2 levels); the record itself is the `AppHeader.Title` after the separator, not the breadcrumb's `current` item.
99
+ - A single level takes its content width (at most the row). A path of 2+ levels fills the row (`inline-size: 100%`) and folds by that width, so a wider row unfolds it again; its intrinsic width stays the whole path, so a host that measures natural widths (the `Page.TopBar` plan) reads it uncut. Inside a flex row give it a box that takes the room it may use (`flex: 1 1 auto; min-width: 0`).
100
+ - In a `Page.Heading` the path up holds the list a record belongs to (1–2 levels); the record itself is the `Page.Title` (in a top bar the path's last level, after the chevron), not the breadcrumb's `current` item.
97
101
  - Above a page title: `gap: var(--prime-space-2)` between the trail and the title row.
98
102
  - The list never wraps. Chevrons sit inside each level after the first, in the placeholder text color, at the tier icon size.
99
103
 
@@ -113,7 +117,7 @@ Root attributes: `data-size`, `data-collapsible` (`"true"` / `"false"`).
113
117
 
114
118
  - `nav` landmark with `aria-label` from `labels.nav`; an ordered list.
115
119
  - The current page has `aria-current="page"`; the chevrons are `aria-hidden` spans inside the levels, so every list item is a level.
116
- - Collapsed middle levels leave the layout and the tab order (no invisible focus stops); the automatic «…» is a menu button (`aria-haspopup="menu"`) named by `labels.ellipsis`, and its menu lists them as links.
120
+ - Collapsed levels leave the layout and the tab order (no invisible focus stops); the automatic «…» is a menu button (`aria-haspopup="menu"`) named by `labels.ellipsis`, and its menu lists them as links.
117
121
  - Icon-only links need `aria-label` on the Item.
118
122
 
119
123
  ### Labels
@@ -132,13 +136,15 @@ Root attributes: `data-size`, `data-collapsible` (`"true"` / `"false"`).
132
136
  | [with-icon.tsx](examples/with-icon.tsx) | The root level as a home icon; a link without text is named for screen readers — `aria-label`. |
133
137
  | [overflow.tsx](examples/overflow.tsx) | A long path: levels truncate, and in a 320px container the middle ones collapse into a «…» menu that lists them — `Breadcrumb.Item`, `current`. |
134
138
  | [ellipsis.tsx](examples/ellipsis.tsx) | Levels skipped on purpose shown as «…» whose hidden text names them for screen readers — `Breadcrumb.Ellipsis`, `labels`. |
139
+ | [router.tsx](examples/router.tsx) | Router links as the levels above: the path moves without a reload; render it inside a router — `asChild`, `current`. |
135
140
 
136
141
  ## Mistakes
137
142
  - Separators by hand between items → the root draws the chevrons.
138
143
  - `<Breadcrumb.Item href="…" current>` → the current page has no `href`.
139
144
  - Breadcrumb inside a flex row collapsing to zero width → give it `flex: 1 1 auto; min-width: 0`.
140
145
  - Home icon link without `aria-label` → add `aria-label="Главная"`.
146
+ - `href` + `onClick` with `preventDefault()` and `navigate()` for a router → `asChild` with the router's `Link`.
141
147
 
142
148
  ## Related
143
149
  - **Built from:** [LinkButton](../link-button/COMPONENT.md) (`tone="muted"`), [Button](../button/COMPONENT.md) and [Dropdown](../dropdown/COMPONENT.md) (the collapse menu), Icon (`nav.chevronRight`), [VisuallyHidden](../visually-hidden/COMPONENT.md)
144
- - **See also:** [Tabs](../tabs/COMPONENT.md), [PageContent](../page-content/COMPONENT.md), [Stepper](../stepper/COMPONENT.md)
150
+ - **See also:** [Tabs](../tabs/COMPONENT.md), [Page](../../layout/page/COMPONENT.md), [Stepper](../stepper/COMPONENT.md)
@@ -0,0 +1,17 @@
1
+ /** Router links as the levels above: the path moves without a reload; render it inside a router — `asChild`, `current`. */
2
+ import { Breadcrumb } from "prime-ui-kit";
3
+ import { Link } from "react-router-dom";
4
+
5
+ export default function BreadcrumbRouterExample() {
6
+ return (
7
+ <Breadcrumb.Root>
8
+ <Breadcrumb.Item asChild>
9
+ <Link to="/crm">CRM</Link>
10
+ </Breadcrumb.Item>
11
+ <Breadcrumb.Item asChild>
12
+ <Link to="/crm/clients">Клиенты</Link>
13
+ </Breadcrumb.Item>
14
+ <Breadcrumb.Item current>ООО «Северный ветер»</Breadcrumb.Item>
15
+ </Breadcrumb.Root>
16
+ );
17
+ }