prime-ui-kit 0.16.0 → 0.17.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 (315) hide show
  1. package/README.md +14 -18
  2. package/dist/chunks/{chunk-4PSQ64S4.js → chunk-7WWZYGRC.js} +3697 -3738
  3. package/dist/chunks/{chunk-6TPHKCUJ.js → chunk-A4WE3UNC.js} +27340 -26893
  4. package/dist/chunks/{chunk-A7OQWH6R.js → chunk-PRP4B6OG.js} +1 -1
  5. package/dist/chunks/{chunk-HDBQICPW.js → chunk-SVFWPLNW.js} +49 -20
  6. package/dist/color-picker.d.ts +1 -1
  7. package/dist/color-picker.js +3 -3
  8. package/dist/components/breadcrumb/Breadcrumb.d.ts +1 -1
  9. package/dist/components/chart-frame/ChartFrame.d.ts +1 -1
  10. package/dist/components/chat/ChatRows.d.ts +5 -1
  11. package/dist/components/color-picker/ColorPicker.d.ts +18 -1
  12. package/dist/components/data-table/DataTable.d.ts +1 -1
  13. package/dist/components/index.d.ts +0 -4
  14. package/dist/components/pagination/Pagination.d.ts +5 -1
  15. package/dist/components/popover/Popover.d.ts +1 -1
  16. package/dist/components/slider/Slider.d.ts +1 -1
  17. package/dist/components/smart-filter/SmartFilter.d.ts +4 -5
  18. package/dist/icon-set.js +2 -2
  19. package/dist/index.css +1 -1
  20. package/dist/index.js +5 -9
  21. package/dist/internal/barPlan.d.ts +44 -0
  22. package/dist/internal/overlay/FloatingPanel.d.ts +1 -1
  23. package/dist/internal/overlay/focus.d.ts +3 -2
  24. package/dist/internal/parts.d.ts +1 -1
  25. package/dist/internal/slot.d.ts +0 -30
  26. package/dist/layout/app-shell/AppShell.d.ts +19 -38
  27. package/dist/layout/index.d.ts +3 -3
  28. package/dist/layout/page/Page.d.ts +263 -0
  29. package/dist/layout/sidebar/Sidebar.d.ts +1 -1
  30. package/dist/skill/SKILL.md +10 -10
  31. package/dist/skill/anti-slop.md +101 -5
  32. package/dist/skill/api-contract.md +1 -1
  33. package/dist/skill/cheatsheet.md +27 -22
  34. package/dist/skill/checklist.md +7 -3
  35. package/dist/skill/choosing.md +9 -8
  36. package/dist/skill/components.md +3 -5
  37. package/dist/skill/composition.md +177 -152
  38. package/dist/skill/foundations.md +9 -9
  39. package/dist/skill/layouts.md +39 -98
  40. package/dist/skill/reference/components/avatar/COMPONENT.md +2 -2
  41. package/dist/skill/reference/components/avatar/examples/team-group.tsx +1 -1
  42. package/dist/skill/reference/components/banner/COMPONENT.md +4 -4
  43. package/dist/skill/reference/components/banner/examples/examples.module.css +6 -1
  44. package/dist/skill/reference/components/banner/examples/page-strip.tsx +24 -22
  45. package/dist/skill/reference/components/breadcrumb/COMPONENT.md +9 -8
  46. package/dist/skill/reference/components/button/COMPONENT.md +1 -0
  47. package/dist/skill/reference/components/button/examples/hold-to-confirm.tsx +1 -1
  48. package/dist/skill/reference/components/button/examples/on-colored-host.tsx +8 -8
  49. package/dist/skill/reference/components/card/COMPONENT.md +7 -7
  50. package/dist/skill/reference/components/card/examples/screen.module.css +1 -1
  51. package/dist/skill/reference/components/card/examples/screen.tsx +184 -198
  52. package/dist/skill/reference/components/chart-frame/COMPONENT.md +1 -1
  53. package/dist/skill/reference/components/chart-frame/examples/fill-height.tsx +9 -9
  54. package/dist/skill/reference/components/chat/COMPONENT.md +4 -4
  55. package/dist/skill/reference/components/chat/examples/screen.module.css +1 -1
  56. package/dist/skill/reference/components/chat/examples/screen.tsx +110 -117
  57. package/dist/skill/reference/components/chat-list/COMPONENT.md +2 -2
  58. package/dist/skill/reference/components/chat-list/examples/controlled.tsx +2 -2
  59. package/dist/skill/reference/components/chat-list/examples/examples.module.css +8 -0
  60. package/dist/skill/reference/components/checkbox/examples/examples.module.css +3 -2
  61. package/dist/skill/reference/components/code-block/COMPONENT.md +1 -1
  62. package/dist/skill/reference/components/code-block/examples/color-scheme.tsx +2 -4
  63. package/dist/skill/reference/components/code-block/examples/examples.module.css +0 -11
  64. package/dist/skill/reference/components/color-picker/COMPONENT.md +18 -7
  65. package/dist/skill/reference/components/color-picker/examples/examples.module.css +2 -5
  66. package/dist/skill/reference/components/color-picker/examples/overview.tsx +5 -10
  67. package/dist/skill/reference/components/color-picker/examples/sizes.tsx +4 -8
  68. package/dist/skill/reference/components/crossfade/COMPONENT.md +2 -2
  69. package/dist/skill/reference/components/crossfade/examples/screen.tsx +107 -112
  70. package/dist/skill/reference/components/data-table/COMPONENT.md +5 -5
  71. package/dist/skill/reference/components/data-table/examples/examples.module.css +9 -0
  72. package/dist/skill/reference/components/data-table/examples/screen.tsx +42 -52
  73. package/dist/skill/reference/components/data-table/examples/server.tsx +6 -2
  74. package/dist/skill/reference/components/datepicker/examples/examples.module.css +6 -0
  75. package/dist/skill/reference/components/datepicker/examples/inline-panel.tsx +3 -1
  76. package/dist/skill/reference/components/description-list/COMPONENT.md +1 -1
  77. package/dist/skill/reference/components/description-list/examples/screen.tsx +120 -127
  78. package/dist/skill/reference/components/digit-input/examples/grouped.tsx +4 -4
  79. package/dist/skill/reference/components/digit-input/examples/validation.tsx +1 -1
  80. package/dist/skill/reference/components/divider/COMPONENT.md +2 -2
  81. package/dist/skill/reference/components/divider/examples/examples.module.css +4 -1
  82. package/dist/skill/reference/components/divider/examples/vertical.tsx +22 -9
  83. package/dist/skill/reference/components/dnd/examples/examples.module.css +3 -1
  84. package/dist/skill/reference/components/drawer/COMPONENT.md +1 -1
  85. package/dist/skill/reference/components/drawer/examples/placement.tsx +26 -31
  86. package/dist/skill/reference/components/drawer/examples/screen.tsx +137 -160
  87. package/dist/skill/reference/components/dropdown/COMPONENT.md +1 -1
  88. package/dist/skill/reference/components/example-frame/COMPONENT.md +3 -3
  89. package/dist/skill/reference/components/field-list/examples/screen.module.css +1 -1
  90. package/dist/skill/reference/components/field-list/examples/screen.tsx +19 -19
  91. package/dist/skill/reference/components/fieldset/COMPONENT.md +1 -1
  92. package/dist/skill/reference/components/fieldset/examples/states.tsx +1 -1
  93. package/dist/skill/reference/components/file-upload/COMPONENT.md +1 -1
  94. package/dist/skill/reference/components/file-upload/examples/screen.module.css +2 -2
  95. package/dist/skill/reference/components/file-upload/examples/screen.tsx +65 -81
  96. package/dist/skill/reference/components/gallery/COMPONENT.md +1 -0
  97. package/dist/skill/reference/components/gantt/COMPONENT.md +1 -1
  98. package/dist/skill/reference/components/gantt/examples/screen.module.css +1 -1
  99. package/dist/skill/reference/components/gantt/examples/screen.tsx +55 -73
  100. package/dist/skill/reference/components/hint/examples/examples.module.css +10 -1
  101. package/dist/skill/reference/components/hint/examples/overview.tsx +1 -1
  102. package/dist/skill/reference/components/kanban/COMPONENT.md +1 -1
  103. package/dist/skill/reference/components/kanban/examples/screen.module.css +1 -1
  104. package/dist/skill/reference/components/kanban/examples/screen.tsx +50 -65
  105. package/dist/skill/reference/components/kbd/COMPONENT.md +1 -1
  106. package/dist/skill/reference/components/label/examples/examples.module.css +12 -1
  107. package/dist/skill/reference/components/label/examples/overview.tsx +1 -1
  108. package/dist/skill/reference/components/list/COMPONENT.md +3 -3
  109. package/dist/skill/reference/components/media-viewer/examples/controlled.tsx +16 -16
  110. package/dist/skill/reference/components/media-viewer/examples/examples.module.css +1 -3
  111. package/dist/skill/reference/components/pagination/COMPONENT.md +11 -3
  112. package/dist/skill/reference/components/pagination/examples/controlled.tsx +2 -1
  113. package/dist/skill/reference/components/popover/COMPONENT.md +3 -2
  114. package/dist/skill/reference/components/popover/examples/width.tsx +13 -1
  115. package/dist/skill/reference/components/slider/COMPONENT.md +3 -3
  116. package/dist/skill/reference/components/slider/examples/states.tsx +14 -10
  117. package/dist/skill/reference/components/smart-filter/COMPONENT.md +13 -13
  118. package/dist/skill/reference/components/smart-filter/examples/examples.module.css +3 -0
  119. package/dist/skill/reference/components/smart-filter/examples/many-values.tsx +12 -8
  120. package/dist/skill/reference/components/smart-filter/examples/sizes.tsx +7 -3
  121. package/dist/skill/reference/components/sparkline/COMPONENT.md +1 -0
  122. package/dist/skill/reference/components/sparkline/examples/curve.tsx +16 -11
  123. package/dist/skill/reference/components/sparkline/examples/states.tsx +14 -10
  124. package/dist/skill/reference/components/switch/COMPONENT.md +1 -1
  125. package/dist/skill/reference/components/tabs/COMPONENT.md +1 -1
  126. package/dist/skill/reference/components/typography/COMPONENT.md +2 -2
  127. package/dist/skill/reference/foundation.md +15 -11
  128. package/dist/skill/reference/layout/app-shell/COMPONENT.md +25 -38
  129. package/dist/skill/reference/layout/app-shell/examples/footer.tsx +10 -10
  130. package/dist/skill/reference/layout/app-shell/examples/overview.tsx +20 -22
  131. package/dist/skill/reference/layout/app-shell/examples/screen.module.css +2 -2
  132. package/dist/skill/reference/layout/app-shell/examples/screen.tsx +25 -30
  133. package/dist/skill/reference/layout/app-shell/examples/template.tsx +13 -17
  134. package/dist/skill/reference/layout/bottom-nav/COMPONENT.md +3 -3
  135. package/dist/skill/reference/layout/bottom-nav/examples/floating-action.tsx +10 -19
  136. package/dist/skill/reference/layout/bottom-nav/examples/floating.tsx +10 -19
  137. package/dist/skill/reference/layout/bottom-nav/examples/in-app-shell.tsx +11 -19
  138. package/dist/skill/reference/layout/page/COMPONENT.md +353 -0
  139. package/dist/skill/reference/layout/page/examples/actions-collapse.tsx +45 -0
  140. package/dist/skill/reference/layout/page/examples/collapse.tsx +68 -0
  141. package/dist/skill/reference/{components/page-content → layout/page}/examples/examples.module.css +33 -4
  142. package/{src/components/page-content → dist/skill/reference/layout/page}/examples/grid.tsx +15 -15
  143. package/dist/skill/reference/{components/page-content → layout/page}/examples/list-detail.tsx +14 -14
  144. package/dist/skill/reference/layout/page/examples/narrow.tsx +75 -0
  145. package/dist/skill/reference/layout/page/examples/overview.tsx +57 -0
  146. package/dist/skill/reference/{components/page-content → layout/page}/examples/screen.module.css +1 -1
  147. package/{src/components/page-content → dist/skill/reference/layout/page}/examples/screen.tsx +29 -19
  148. package/dist/skill/reference/{components/page-content → layout/page}/examples/sections.tsx +17 -24
  149. package/dist/skill/reference/layout/page/examples/structure.tsx +41 -0
  150. package/dist/skill/reference/{components/page-toolbar/examples/narrow.tsx → layout/page/examples/tools.tsx} +38 -35
  151. package/dist/skill/reference/layout/page/examples/top-bar.tsx +85 -0
  152. package/dist/skill/reference/{components/page-content → layout/page}/examples/variants.tsx +7 -7
  153. package/dist/skill/reference/layout/sidebar/COMPONENT.md +5 -4
  154. package/dist/skill/reference/layout/sidebar/examples/dismiss.tsx +10 -7
  155. package/dist/skill/reference/layout/sidebar/examples/narrow.tsx +11 -8
  156. package/dist/skill/responsive.md +88 -74
  157. package/dist/tokens/layers.d.ts +2 -0
  158. package/dist/tokens/primitives.d.ts +12 -2
  159. package/dist/tokens/semantic.d.ts +7 -0
  160. package/dist/tokens/themes/dark.d.ts +7 -2
  161. package/package.json +2 -2
  162. package/src/components/avatar/COMPONENT.md +2 -2
  163. package/src/components/avatar/examples/team-group.tsx +1 -1
  164. package/src/components/banner/COMPONENT.md +4 -4
  165. package/src/components/banner/examples/examples.module.css +6 -1
  166. package/src/components/banner/examples/page-strip.tsx +24 -22
  167. package/src/components/breadcrumb/COMPONENT.md +9 -8
  168. package/src/components/button/COMPONENT.md +1 -0
  169. package/src/components/button/examples/hold-to-confirm.tsx +1 -1
  170. package/src/components/button/examples/on-colored-host.tsx +8 -8
  171. package/src/components/card/COMPONENT.md +7 -7
  172. package/src/components/card/examples/screen.module.css +1 -1
  173. package/src/components/card/examples/screen.tsx +184 -198
  174. package/src/components/chart-frame/COMPONENT.md +1 -1
  175. package/src/components/chart-frame/examples/fill-height.tsx +9 -9
  176. package/src/components/chat/COMPONENT.md +4 -4
  177. package/src/components/chat/examples/screen.module.css +1 -1
  178. package/src/components/chat/examples/screen.tsx +110 -117
  179. package/src/components/chat-list/COMPONENT.md +2 -2
  180. package/src/components/chat-list/examples/controlled.tsx +2 -2
  181. package/src/components/chat-list/examples/examples.module.css +8 -0
  182. package/src/components/checkbox/examples/examples.module.css +3 -2
  183. package/src/components/code-block/COMPONENT.md +1 -1
  184. package/src/components/code-block/examples/color-scheme.tsx +2 -4
  185. package/src/components/code-block/examples/examples.module.css +0 -11
  186. package/src/components/color-picker/COMPONENT.md +18 -7
  187. package/src/components/color-picker/examples/examples.module.css +2 -5
  188. package/src/components/color-picker/examples/overview.tsx +5 -10
  189. package/src/components/color-picker/examples/sizes.tsx +4 -8
  190. package/src/components/crossfade/COMPONENT.md +2 -2
  191. package/src/components/crossfade/examples/screen.tsx +107 -112
  192. package/src/components/data-table/COMPONENT.md +5 -5
  193. package/src/components/data-table/examples/examples.module.css +9 -0
  194. package/src/components/data-table/examples/screen.tsx +42 -52
  195. package/src/components/data-table/examples/server.tsx +6 -2
  196. package/src/components/datepicker/examples/examples.module.css +6 -0
  197. package/src/components/datepicker/examples/inline-panel.tsx +3 -1
  198. package/src/components/description-list/COMPONENT.md +1 -1
  199. package/src/components/description-list/examples/screen.tsx +120 -127
  200. package/src/components/digit-input/examples/grouped.tsx +4 -4
  201. package/src/components/digit-input/examples/validation.tsx +1 -1
  202. package/src/components/divider/COMPONENT.md +2 -2
  203. package/src/components/divider/examples/examples.module.css +4 -1
  204. package/src/components/divider/examples/vertical.tsx +22 -9
  205. package/src/components/dnd/examples/examples.module.css +3 -1
  206. package/src/components/drawer/COMPONENT.md +1 -1
  207. package/src/components/drawer/examples/placement.tsx +26 -31
  208. package/src/components/drawer/examples/screen.tsx +137 -160
  209. package/src/components/dropdown/COMPONENT.md +1 -1
  210. package/src/components/example-frame/COMPONENT.md +3 -3
  211. package/src/components/field-list/examples/screen.module.css +1 -1
  212. package/src/components/field-list/examples/screen.tsx +19 -19
  213. package/src/components/fieldset/COMPONENT.md +1 -1
  214. package/src/components/fieldset/examples/states.tsx +1 -1
  215. package/src/components/file-upload/COMPONENT.md +1 -1
  216. package/src/components/file-upload/examples/screen.module.css +2 -2
  217. package/src/components/file-upload/examples/screen.tsx +65 -81
  218. package/src/components/gallery/COMPONENT.md +1 -0
  219. package/src/components/gantt/COMPONENT.md +1 -1
  220. package/src/components/gantt/examples/screen.module.css +1 -1
  221. package/src/components/gantt/examples/screen.tsx +55 -73
  222. package/src/components/hint/examples/examples.module.css +10 -1
  223. package/src/components/hint/examples/overview.tsx +1 -1
  224. package/src/components/kanban/COMPONENT.md +1 -1
  225. package/src/components/kanban/examples/screen.module.css +1 -1
  226. package/src/components/kanban/examples/screen.tsx +50 -65
  227. package/src/components/kbd/COMPONENT.md +1 -1
  228. package/src/components/label/examples/examples.module.css +12 -1
  229. package/src/components/label/examples/overview.tsx +1 -1
  230. package/src/components/list/COMPONENT.md +3 -3
  231. package/src/components/media-viewer/examples/controlled.tsx +16 -16
  232. package/src/components/media-viewer/examples/examples.module.css +1 -3
  233. package/src/components/pagination/COMPONENT.md +11 -3
  234. package/src/components/pagination/examples/controlled.tsx +2 -1
  235. package/src/components/popover/COMPONENT.md +3 -2
  236. package/src/components/popover/examples/width.tsx +13 -1
  237. package/src/components/slider/COMPONENT.md +3 -3
  238. package/src/components/slider/examples/states.tsx +14 -10
  239. package/src/components/smart-filter/COMPONENT.md +13 -13
  240. package/src/components/smart-filter/examples/examples.module.css +3 -0
  241. package/src/components/smart-filter/examples/many-values.tsx +12 -8
  242. package/src/components/smart-filter/examples/sizes.tsx +7 -3
  243. package/src/components/sparkline/COMPONENT.md +1 -0
  244. package/src/components/sparkline/examples/curve.tsx +16 -11
  245. package/src/components/sparkline/examples/states.tsx +14 -10
  246. package/src/components/switch/COMPONENT.md +1 -1
  247. package/src/components/tabs/COMPONENT.md +1 -1
  248. package/src/components/typography/COMPONENT.md +2 -2
  249. package/src/layout/app-shell/COMPONENT.md +25 -38
  250. package/src/layout/app-shell/examples/footer.tsx +10 -10
  251. package/src/layout/app-shell/examples/overview.tsx +20 -22
  252. package/src/layout/app-shell/examples/screen.module.css +2 -2
  253. package/src/layout/app-shell/examples/screen.tsx +25 -30
  254. package/src/layout/app-shell/examples/template.tsx +13 -17
  255. package/src/layout/bottom-nav/COMPONENT.md +3 -3
  256. package/src/layout/bottom-nav/examples/floating-action.tsx +10 -19
  257. package/src/layout/bottom-nav/examples/floating.tsx +10 -19
  258. package/src/layout/bottom-nav/examples/in-app-shell.tsx +11 -19
  259. package/src/layout/page/COMPONENT.md +353 -0
  260. package/src/layout/page/examples/actions-collapse.tsx +45 -0
  261. package/src/layout/page/examples/collapse.tsx +68 -0
  262. package/src/{components/page-content → layout/page}/examples/examples.module.css +33 -4
  263. package/{dist/skill/reference/components/page-content → src/layout/page}/examples/grid.tsx +15 -15
  264. package/src/{components/page-content → layout/page}/examples/list-detail.tsx +14 -14
  265. package/src/layout/page/examples/narrow.tsx +75 -0
  266. package/src/layout/page/examples/overview.tsx +57 -0
  267. package/src/{components/page-content → layout/page}/examples/screen.module.css +1 -1
  268. package/{dist/skill/reference/components/page-content → src/layout/page}/examples/screen.tsx +29 -19
  269. package/src/{components/page-content → layout/page}/examples/sections.tsx +17 -24
  270. package/src/layout/page/examples/structure.tsx +41 -0
  271. package/src/{components/page-toolbar/examples/narrow.tsx → layout/page/examples/tools.tsx} +38 -35
  272. package/src/layout/page/examples/top-bar.tsx +85 -0
  273. package/src/{components/page-content → layout/page}/examples/variants.tsx +7 -7
  274. package/src/layout/sidebar/COMPONENT.md +5 -4
  275. package/src/layout/sidebar/examples/dismiss.tsx +10 -7
  276. package/src/layout/sidebar/examples/narrow.tsx +11 -8
  277. package/src/styles/theme-dark.css +12 -10
  278. package/src/styles/theme-light.css +3 -0
  279. package/src/styles/tokens.css +3 -1
  280. package/dist/components/page-content/PageContent.d.ts +0 -192
  281. package/dist/components/page-toolbar/PageToolbar.d.ts +0 -55
  282. package/dist/layout/app-header/AppHeader.d.ts +0 -118
  283. package/dist/skill/reference/components/page-content/COMPONENT.md +0 -264
  284. package/dist/skill/reference/components/page-content/examples/narrow.tsx +0 -25
  285. package/dist/skill/reference/components/page-content/examples/overview.tsx +0 -41
  286. package/dist/skill/reference/components/page-toolbar/COMPONENT.md +0 -147
  287. package/dist/skill/reference/components/page-toolbar/examples/examples.module.css +0 -16
  288. package/dist/skill/reference/components/page-toolbar/examples/overview.tsx +0 -113
  289. package/dist/skill/reference/components/page-toolbar/examples/save-changes.tsx +0 -43
  290. package/dist/skill/reference/components/page-toolbar/examples/without-search.tsx +0 -60
  291. package/dist/skill/reference/layout/app-header/COMPONENT.md +0 -187
  292. package/dist/skill/reference/layout/app-header/examples/breadcrumbs.tsx +0 -37
  293. package/dist/skill/reference/layout/app-header/examples/examples.module.css +0 -28
  294. package/dist/skill/reference/layout/app-header/examples/in-app-shell.tsx +0 -67
  295. package/dist/skill/reference/layout/app-header/examples/narrow.tsx +0 -66
  296. package/dist/skill/reference/layout/app-header/examples/overview.tsx +0 -34
  297. package/dist/skill/reference/layout/app-header/examples/page-title.tsx +0 -78
  298. package/dist/skill/reference/layout/app-shell/examples/contained.tsx +0 -30
  299. package/src/components/page-content/COMPONENT.md +0 -264
  300. package/src/components/page-content/examples/narrow.tsx +0 -25
  301. package/src/components/page-content/examples/overview.tsx +0 -41
  302. package/src/components/page-toolbar/COMPONENT.md +0 -147
  303. package/src/components/page-toolbar/examples/examples.module.css +0 -16
  304. package/src/components/page-toolbar/examples/overview.tsx +0 -113
  305. package/src/components/page-toolbar/examples/save-changes.tsx +0 -43
  306. package/src/components/page-toolbar/examples/without-search.tsx +0 -60
  307. package/src/layout/app-header/COMPONENT.md +0 -187
  308. package/src/layout/app-header/examples/breadcrumbs.tsx +0 -37
  309. package/src/layout/app-header/examples/examples.module.css +0 -28
  310. package/src/layout/app-header/examples/in-app-shell.tsx +0 -67
  311. package/src/layout/app-header/examples/narrow.tsx +0 -66
  312. package/src/layout/app-header/examples/overview.tsx +0 -34
  313. package/src/layout/app-header/examples/page-title.tsx +0 -78
  314. package/src/layout/app-shell/examples/contained.tsx +0 -30
  315. package/dist/chunks/{chunk-U3Q2I3MY.js → chunk-2ODXLPW3.js} +2 -2
@@ -1,5 +1,5 @@
1
- /** The same page column at three caps: the whole main, a wide dashboard column, a reading column — `maxWidth`. */
2
- import { Card, PageContent, Typography } from "prime-ui-kit";
1
+ /** The same page at three caps: the whole main, a wide dashboard column, a reading column — `maxWidth`. */
2
+ import { Card, Page, Typography } from "prime-ui-kit";
3
3
 
4
4
  import styles from "./examples.module.css";
5
5
 
@@ -9,13 +9,13 @@ const WIDTHS = [
9
9
  { value: "readable", text: "Условия использования: не шире колонки для чтения, по центру." },
10
10
  ] as const;
11
11
 
12
- export default function PageContentVariantsExample() {
12
+ export default function PageVariantsExample() {
13
13
  return (
14
14
  <>
15
15
  {WIDTHS.map(({ value, text }) => (
16
16
  <div key={value} className={styles.main}>
17
- <PageContent.Root maxWidth={value}>
18
- <PageContent.Body>
17
+ <Page.Root maxWidth={value}>
18
+ <Page.Body>
19
19
  <Card.Root>
20
20
  <Card.Body>
21
21
  <Typography variant="body-s" tone="secondary">
@@ -23,8 +23,8 @@ export default function PageContentVariantsExample() {
23
23
  </Typography>
24
24
  </Card.Body>
25
25
  </Card.Root>
26
- </PageContent.Body>
27
- </PageContent.Root>
26
+ </Page.Body>
27
+ </Page.Root>
28
28
  </div>
29
29
  ))}
30
30
  </>
@@ -89,7 +89,7 @@ useSidebar() state hook for custom parts inside Root (useA
89
89
  | `onModeChange` | `(mode: SidebarMode) => void` | — | Called with the new mode (Toggle, `useSidebar().setMode`). |
90
90
  | `open` | `boolean` | — | Off-canvas panel on narrow viewports (controlled). |
91
91
  | `defaultOpen` | `boolean` | `false` | Initial off-canvas state (uncontrolled). |
92
- | `onOpenChange` | `(open: boolean) => void` | — | Off-canvas open / close: Toggle, the AppHeader menu button, scrim, Escape, an activated item, leaving the narrow viewport. |
92
+ | `onOpenChange` | `(open: boolean) => void` | — | Off-canvas open / close: Toggle, the menu button of `Page.TopBar`, scrim, Escape, an activated item, leaving the narrow viewport. |
93
93
  | `offCanvas` | `"auto" \| "always" \| "never"` | `"auto"` | When the rail becomes an off-canvas panel opened by `open`: `auto` — below 768px (viewport); `always` — at any width; `never` — always a rail. |
94
94
  | `closeOnOutsideClick` | `boolean` | `true` | A press on the scrim (outside the off-canvas panel) closes the panel. |
95
95
  | `closeOnEscape` | `boolean` | `true` | Escape closes the off-canvas panel. |
@@ -294,13 +294,14 @@ The rail width does not depend on `size`.
294
294
  | `closeOnEscape` (Root) | Escape closes the off-canvas panel | default; turn off with `closeOnOutsideClick` for a panel only its toggle closes | on |
295
295
  | `asChild` (ItemAction) | the row action is the consumer's link with the button look | the action opens a page or `mailto:` | off |
296
296
 
297
- Put `<Sidebar.Toggle variant="header" />` next to `Sidebar.Brand` in the header, or `Sidebar.Toggle` in the footer for a rail without a brand. Inside an `AppShell` the Sidebar publishes its navigation to the shell: on phones (`offCanvas="auto"`) or always (`offCanvas="always"`) the `AppHeader` draws the menu button that opens the panel by itself, a `Sidebar.Toggle` outside the rail brings back a hidden one, and other triggers (a BottomNav «Ещё») read `useAppShellNav()`. One current item at a time; give every top-level item an icon when the rail can go compact (child items need none).
297
+ Put `<Sidebar.Toggle variant="header" />` next to `Sidebar.Brand` in the header, or `Sidebar.Toggle` in the footer for a rail without a brand. Inside an `AppShell` the Sidebar publishes its navigation to the shell: on phones (`offCanvas="auto"`) or always (`offCanvas="always"`) the page's `Page.TopBar` draws the menu button that opens the panel by itself, a `Sidebar.Toggle` outside the rail brings back a hidden one, and other triggers (a BottomNav «Ещё») read `useAppShellNav()`. One current item at a time; give every top-level item an icon when the rail can go compact (child items need none).
298
298
 
299
299
  ## States
300
300
  | State | Driven by | DOM |
301
301
  |---|---|---|
302
302
  | mode | `mode` / `defaultMode` | Root `data-mode`, `data-panel-mode` (the last visible mode while hidden); `<nav inert>` while hidden |
303
303
  | off-canvas | `offCanvas="always"`, or `"auto"` + viewport < 768px | Root `data-off-canvas`, `data-state="open" \| "closed"`; `<nav inert>` while closed; the kit scrim (`role="presentation"`) while open; in an `AppShell` the shell Root `data-off-canvas` |
304
+ | placing | the viewport crossed the off-canvas breakpoint (not a person's choice) | Root `data-placing` for one painted frame: the rail lands at its new width with no motion (no growing from 0, no folding rows, no sliding panel) |
304
305
  | dismiss | `closeOnOutsideClick`, `closeOnEscape` | a press on the scrim / Escape closes the open panel, or not |
305
306
  | current | `current` or a router's `aria-current` | Item `aria-current="page"`, `data-state="active"` |
306
307
  | active path | a child of a Sub (or an item of a Group) is current | SubTrigger (or the `…` row of a folded Group) `data-active-path`; a closed Sub opens, a closed Group opens off the compact rail |
@@ -364,7 +365,7 @@ Leaving the narrow viewport closes the off-canvas panel; activating an item (a l
364
365
  - A row action is its own button next to the item (never nested), named by `label` with a tooltip.
365
366
  - The account avatar is hidden from screen readers; the name and the muted line name the button.
366
367
  - Off-canvas: a decorative scrim (a press on it is a press outside, `closeOnOutsideClick`), focus trap and Escape (`closeOnEscape`); focus returns to the opener.
367
- - Toggle, the AppHeader menu button and `useAppShellNav` triggers: `aria-expanded`, `aria-controls` → the `<nav>`, label from `labels`.
368
+ - Toggle, the menu button of `Page.TopBar` and `useAppShellNav` triggers: `aria-expanded`, `aria-controls` → the `<nav>`, label from `labels`.
368
369
 
369
370
  ### Labels
370
371
  <!-- Generated from api.ts by `bun run docs:build`. Edit api.ts, not this section. -->
@@ -392,7 +393,7 @@ Leaving the narrow viewport closes the off-canvas panel; activating an item (a l
392
393
  | [dismiss.tsx](examples/dismiss.tsx) | An off-canvas panel only its own toggle closes: a press on the scrim and Escape leave it open, a picked item still closes it — `closeOnOutsideClick`, `closeOnEscape`. |
393
394
  | [controlled.tsx](examples/controlled.tsx) | The parent owns the rail mode: expanded, an icon rail with tooltips, or hidden; every switch is one synchronous movement — `mode`, `onModeChange`. |
394
395
  | [controlled-open.tsx](examples/controlled-open.tsx) | Navigation behind a menu button at any width: the parent opens the off-canvas panel, the scrim, Escape, the header toggle or a navigation closes it — `offCanvas`, `open`, `onOpenChange`. |
395
- | [narrow.tsx](examples/narrow.tsx) | Below 768px the rail leaves the layout and slides in over the page from the menu button the header draws by itself; from 768px it is the rail again, and the button leaves — `AppShell`, `labels`. |
396
+ | [narrow.tsx](examples/narrow.tsx) | Below 768px the rail leaves the layout and slides in over the page from the menu button the page top bar draws by itself; from 768px it is the rail again, and the button leaves — `AppShell`, `labels`. |
396
397
 
397
398
  ## Mistakes
398
399
  - `icon={…}` / `badge={…}` props → use the `Sidebar.ItemIcon` and `Sidebar.ItemCount` parts.
@@ -1,5 +1,5 @@
1
1
  /** An off-canvas panel only its own toggle closes: a press on the scrim and Escape leave it open, a picked item still closes it — `closeOnOutsideClick`, `closeOnEscape`. */
2
- import { AppHeader, AppShell, Icon, Sidebar } from "prime-ui-kit";
2
+ import { AppShell, Icon, Page, Sidebar } from "prime-ui-kit";
3
3
 
4
4
  import styles from "./examples.module.css";
5
5
 
@@ -35,12 +35,15 @@ export default function SidebarDismissExample() {
35
35
  </Sidebar.Content>
36
36
  </Sidebar.Root>
37
37
  </AppShell.Nav>
38
- <AppHeader.Root>
39
- <AppHeader.Start>
40
- <AppHeader.Title>Сборка заказов</AppHeader.Title>
41
- </AppHeader.Start>
42
- </AppHeader.Root>
43
- <AppShell.Main />
38
+ <AppShell.Main>
39
+ <Page.Root>
40
+ <Page.TopBar>
41
+ <Page.Heading>
42
+ <Page.Title>Сборка заказов</Page.Title>
43
+ </Page.Heading>
44
+ </Page.TopBar>
45
+ </Page.Root>
46
+ </AppShell.Main>
44
47
  </AppShell.Root>
45
48
  </div>
46
49
  );
@@ -1,5 +1,5 @@
1
- /** Below 768px the rail leaves the layout and slides in over the page from the menu button the header draws by itself; from 768px it is the rail again, and the button leaves — `AppShell`, `labels`. */
2
- import { AppHeader, AppShell, Icon, Sidebar } from "prime-ui-kit";
1
+ /** Below 768px the rail leaves the layout and slides in over the page from the menu button the page top bar draws by itself; from 768px it is the rail again, and the button leaves — `AppShell`, `labels`. */
2
+ import { AppShell, Icon, Page, Sidebar } from "prime-ui-kit";
3
3
 
4
4
  import styles from "./examples.module.css";
5
5
 
@@ -43,12 +43,15 @@ export default function SidebarNarrowExample() {
43
43
  </Sidebar.Content>
44
44
  </Sidebar.Root>
45
45
  </AppShell.Nav>
46
- <AppHeader.Root>
47
- <AppHeader.Start>
48
- <AppHeader.Title>Сделки</AppHeader.Title>
49
- </AppHeader.Start>
50
- </AppHeader.Root>
51
- <AppShell.Main />
46
+ <AppShell.Main>
47
+ <Page.Root>
48
+ <Page.TopBar>
49
+ <Page.Heading>
50
+ <Page.Title>Сделки</Page.Title>
51
+ </Page.Heading>
52
+ </Page.TopBar>
53
+ </Page.Root>
54
+ </AppShell.Main>
52
55
  </AppShell.Root>
53
56
  </div>
54
57
  );
@@ -38,7 +38,7 @@ everything inside a page breaks by its container.
38
38
  - CSS custom properties cannot be used inside media / container conditions: write the number.
39
39
  - Inside your own blocks prefer container queries: `container-type: inline-size` on the block,
40
40
  `@container (min-width: 30rem)` inside it.
41
- - The app takes the full width; cap only text (`PageContent.Root maxWidth="readable"`).
41
+ - The app takes the full width; cap only text (`Page.Root maxWidth="readable"`).
42
42
  - Required minimum: `<meta name="viewport" content="width=device-width, initial-scale=1">`, no
43
43
  `user-scalable=no`, no horizontal page scroll at 320px.
44
44
 
@@ -46,8 +46,8 @@ everything inside a page breaks by its container.
46
46
 
47
47
  A layout inside a page needs no breakpoint: it takes its columns from the room it has.
48
48
 
49
- - The tiles of a page (KPI cards, charts, panels) are one `PageContent.Grid` with a
50
- `PageContent.Cell span` per tile: it folds by its own width (below 30rem every tile takes the row,
49
+ - The tiles of a page (KPI cards, charts, panels) are one `Page.Grid` with a
50
+ `Page.Cell span` per tile: it folds by its own width (below 30rem every tile takes the row,
51
51
  then small tiles pair up, from 64rem each its span).
52
52
  - A grid inside one block (thumbnails, short fields of one record) is the block's own
53
53
  `grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--prime-layout-tile-min-width)), 1fr))`
@@ -61,43 +61,45 @@ Use these as they are; never wrap them in your own breakpoints.
61
61
 
62
62
  | Need | Built in |
63
63
  |---|---|
64
- | app frame | AppShell gutters 16 → 24 → 32; `AppHeader` un-sticks on screens lower than 480px, respects safe areas and, below 36rem of its width, drops the title icon, the title and its line of data truncate |
65
- | app navigation | Sidebar: on-canvas from 768px, an off-canvas panel below (`offCanvas="auto"`) opened by the menu button the AppHeader draws by itself while the Sidebar is off-canvas; `BottomNav` in `AppShell.Footer` for 2–6 app sections on phones — flat or a floating glass capsule (`floating`) with an optional round `BottomNav.Action`, icons with or without labels (`iconOnly`); the shell hides it by itself while the Sidebar rail is on screen (from 768px with `offCanvas="auto"`) |
66
- | page panel | `PageToolbar` — search and filter first, one row when wide, stacked rows when narrow, the primary action on its own row when the search would get less than 18rem beside it ([below](#page-panel--pagetoolbar)) |
67
- | page header | `AppHeader`: the page's tools wrap under the title (`AppHeader.Tools`); a document page's `PageContent.Header`: actions wrap under the title |
64
+ | app frame | `AppShell.Main` hands the page its gutters 16 → 24 → 32 and top air 24 → 32; `Page.TopBar` un-sticks on screens lower than 480px and respects the top safe area; in the bar the title and its line of data truncate |
65
+ | app navigation | Sidebar: on-canvas from 768px, an off-canvas panel below (`offCanvas="auto"`) opened by the menu button `Page.TopBar` draws by itself while the Sidebar is off-canvas; `BottomNav` in `AppShell.Footer` for 2–6 app sections on phones — flat or a floating glass capsule (`floating`) with an optional round `BottomNav.Action`, icons with or without labels (`iconOnly`); the shell hides it by itself while the Sidebar rail is on screen (from 768px with `offCanvas="auto"`) |
66
+ | page top bar | `Page.TopBar` lays out its groups from their natural widths: one line while they fit, then the tools on a line of their own, then icon-only buttons, then «⋯», and the heading truncates last ([below](#the-pages-top-bar--pagetopbar)). `Page.Header` in the flow: actions wrap under the title |
68
67
  | switchers | [Switchers](#switchers) never wrap or truncate: they scroll inside themselves |
69
68
  | tables | DataTable scrolls inside itself, edge shadows show hidden columns, `stickyFirstColumn`, `DataTable.ColumnsMenu` for a column chooser, the toolbar stacks below a 30rem table, sticky head off on short screens |
70
69
  | floating layers | Popover (opened from a Trigger), Dropdown, Select (and Datepicker, ColorPresets) never wider than the viewport − 16, 8 from the edges, flip when out of room; below 640 they open as a bottom sheet — scrim, grab handle, swipe down to close, page scroll locked; Tooltip and TagSelect stay anchored |
71
70
  | dialogs | Modal is a bottom sheet with a handle below 640 (swipe down closes it while `closeOnOutsideClick` allows); footer actions stack on phones and in a dialog narrower than 360px; `Sheet` is a bottom sheet for a short task at every width (centred at 560 on a tablet or desktop) and closes with a swipe down from its handle or header; a Drawer has no swipe — buttons, Escape and the scrim close it |
72
71
  | date picking | Datepicker shows two months and side presets only when they fit; otherwise one month and presets above |
73
72
  | system messages | Banner actions move under the text in a narrow container; Notification stays within the viewport with safe-area insets |
74
- | chat | `Message` bubbles fit their content in CSS and cap at 30rem and 85% of the chat column, file / contact / location cards at 16rem and 75%, a round video at its size token × 1.15 and the row width (the Composer's recording preview at 70%), so a chat works from 320px; the message menu is a bottom sheet below 640, the reaction bar opens on a long press; `Composer` takes its container's width, keeps 16px text and 44px hit areas on touch, and the recording bar covers the field without changing the row height; `VoicePlayer` shrinks its waveform to fit; `Chat` fills its pane, a chat beside its dialogs is `PageContent.Split` (one pane at a time when narrow); `Chat.Header` keeps the avatar, a title that truncates and icon-only actions, `Chat.Search` puts its counter and arrows after a shrinking field, `Chat.Pinned` truncates its line, the «к последним» button floats inside the thread at its bottom-end, and the Composer stays one row (paperclip · field · button) from 320px with its bars above it |
73
+ | chat | `Message` bubbles fit their content in CSS and cap at 30rem and 85% of the chat column, file / contact / location cards at 16rem and 75%, a round video at its size token × 1.15 and the row width (the Composer's recording preview at 70%), so a chat works from 320px; the message menu is a bottom sheet below 640, the reaction bar opens on a long press; `Composer` takes its container's width, keeps 16px text and 44px hit areas on touch, and the recording bar covers the field without changing the row height; `VoicePlayer` shrinks its waveform to fit; `Chat` fills its pane, a chat beside its dialogs is `Page.Split` (one pane at a time when narrow); `Chat.Header` keeps the avatar, a title that truncates and icon-only actions, `Chat.Search` puts its counter and arrows after a shrinking field, `Chat.Pinned` truncates its line, the «к последним» button floats inside the thread at its bottom-end, and the Composer stays one row (paperclip · field · button) from 320px with its bars above it |
75
74
  | schedules and boards | `Gantt` scrolls inside itself with the header and the first column pinned; the first column narrows (12 → 10 → 6rem by the chart's width, or only the avatar); a long press on touch creates a one-unit bar; rows and days are virtualized. `Kanban` columns are 18rem from 40rem of board width, below that 85% of it with snapping so the next column peeks; the strip scrolls sideways inside the board |
76
75
  | cards and properties | Card templates stack and wrap in a narrow container; `DescriptionList` stacks label over value below 24rem of its width; FileUpload `layout="grid"` shows 5 · 4 · 3 · 2 tiles across by its own width |
77
76
  | fields | text ≥ 16px under a coarse pointer (no iOS zoom on focus); labels above fields; affixes in the field row |
78
77
  | codes | DigitInput cells 36–64px, `fullWidth` cells share a phone column |
79
78
  | touch | hover effects only under `(hover: hover)`; under `(pointer: coarse)` small controls get a 44px hit area; nothing is hover-only |
80
79
 
81
- ## Page panel — `PageToolbar`
80
+ ## The page's top bar — `Page.TopBar`
82
81
 
83
- One strip at the top of the page — on an app page, the page's tools row in `AppHeader.Tools` — holds
84
- up to five slots. It renders them in one fixed order whatever the JSX order (that is also the Tab
85
- order) and lays them out from its own width; how each slot moves at every width is in
86
- [PageToolbar COMPONENT.md → Layout by width](reference/components/page-toolbar/COMPONENT.md#layout-by-width).
82
+ The bar holds up to four groups ([what goes in each](composition.md#the-top-bar)) and lays them out
83
+ by one plan chosen from their natural widths. As the width runs out it gives way in five steps, always
84
+ in this order, and nothing ever overflows:
87
85
 
88
- | Slot | Holds |
89
- |---|---|
90
- | `PageToolbar.Tools` | search + filter button: `SmartFilter.Toolbar` |
91
- | `PageToolbar.Sections` | sections of the page: a `fullWidth` SegmentedControl with counts |
92
- | `PageToolbar.View` | period, table / cards, columns |
93
- | `PageToolbar.Actions` | the primary action («Создать», «Сохранить 3 изменения») |
94
- | `PageToolbar.Chips` | active filters: `SmartFilter.Chips` |
86
+ 1. **One line** — `Page.Heading`, `Page.Tools` and `Page.Actions` side by side while they fit.
87
+ 2. **Tools below** — the tools take a line of their own under the first one and fill its width: a
88
+ search (`SmartFilter.Toolbar`, `Input.Root`) grows first, the switchers share the rest and wrap
89
+ when one line is not enough. The actions stay on the first line beside the heading at every width.
90
+ 3. **Icons** — every Button with an icon shows only the icon, the secondary ones first, then the
91
+ primary; its label stays its accessible name and becomes its tooltip.
92
+ 4. **«⋯»** — the secondary Buttons fold into a menu (`labels.more`); the primary always stays.
93
+ 5. **The heading truncates** — only after every button step: the path levels first, then the title.
94
+
95
+ `Page.Chips` is always a line of its own under everything, gone while no filter is set. The heading
96
+ keeps its natural width: the bar sizes the title, so there is nothing to tune.
95
97
 
96
98
  ```tsx
97
99
  import {
98
100
  Button,
99
101
  Icon,
100
- PageToolbar,
102
+ Page,
101
103
  SegmentedControl,
102
104
  Select,
103
105
  SmartFilter,
@@ -110,7 +112,7 @@ const FIELDS: SmartFilterField[] = [
110
112
  { key: "city", label: "Город", options: [{ value: "msk", label: "Москва" }] },
111
113
  ];
112
114
 
113
- export function OrdersPanel() {
115
+ export function OrdersPage() {
114
116
  const [section, setSection] = useState("all");
115
117
  const [period, setPeriod] = useState("30d");
116
118
  const [filter, setFilter] = useState<SmartFilterValue>({});
@@ -124,63 +126,75 @@ export function OrdersPanel() {
124
126
  search={search}
125
127
  onSearchChange={setSearch}
126
128
  >
127
- <PageToolbar.Root aria-label="Заказы">
128
- <PageToolbar.Tools>
129
- <SmartFilter.Toolbar />
130
- </PageToolbar.Tools>
131
- <PageToolbar.Sections>
132
- <SegmentedControl.Root fullWidth value={section} onValueChange={setSection} aria-label="Раздел">
133
- <SegmentedControl.Item value="all">
134
- Все<SegmentedControl.Count>128</SegmentedControl.Count>
135
- </SegmentedControl.Item>
136
- <SegmentedControl.Item value="active">
137
- В работе<SegmentedControl.Count>12</SegmentedControl.Count>
138
- </SegmentedControl.Item>
139
- </SegmentedControl.Root>
140
- </PageToolbar.Sections>
141
- <PageToolbar.View>
142
- <Select.Root value={period} onValueChange={setPeriod}>
143
- <Select.Trigger aria-label="Период">
144
- <Select.Value />
145
- </Select.Trigger>
146
- <Select.Content>
147
- <Select.Item value="7d">7 дней</Select.Item>
148
- <Select.Item value="30d">30 дней</Select.Item>
149
- </Select.Content>
150
- </Select.Root>
151
- </PageToolbar.View>
152
- <PageToolbar.Actions>
153
- <Button.Root>
154
- <Button.Icon>
155
- <Icon name="action.add" />
156
- </Button.Icon>
157
- Новый заказ
158
- </Button.Root>
159
- </PageToolbar.Actions>
160
- <PageToolbar.Chips>
161
- <SmartFilter.Chips />
162
- </PageToolbar.Chips>
163
- </PageToolbar.Root>
129
+ <Page.Root>
130
+ <Page.TopBar>
131
+ <Page.Heading>
132
+ <Page.Title>Заказы</Page.Title>
133
+ <Page.Description>128 в работе · 6 ждут оплаты</Page.Description>
134
+ </Page.Heading>
135
+ <Page.Tools aria-label="Заказы">
136
+ <SegmentedControl.Root value={section} onValueChange={setSection} aria-label="Раздел">
137
+ <SegmentedControl.Item value="all">
138
+ Все<SegmentedControl.Count>128</SegmentedControl.Count>
139
+ </SegmentedControl.Item>
140
+ <SegmentedControl.Item value="active">
141
+ В работе<SegmentedControl.Count>12</SegmentedControl.Count>
142
+ </SegmentedControl.Item>
143
+ </SegmentedControl.Root>
144
+ <SmartFilter.Toolbar />
145
+ <Select.Root value={period} onValueChange={setPeriod}>
146
+ <Select.Trigger aria-label="Период">
147
+ <Select.Value />
148
+ </Select.Trigger>
149
+ <Select.Content>
150
+ <Select.Item value="7d">7 дней</Select.Item>
151
+ <Select.Item value="30d">30 дней</Select.Item>
152
+ </Select.Content>
153
+ </Select.Root>
154
+ </Page.Tools>
155
+ <Page.Actions>
156
+ <Button.Root variant="soft" tone="neutral">
157
+ <Button.Icon>
158
+ <Icon name="action.download" />
159
+ </Button.Icon>
160
+ Экспорт
161
+ </Button.Root>
162
+ <Button.Root>
163
+ <Button.Icon>
164
+ <Icon name="action.add" />
165
+ </Button.Icon>
166
+ Новый заказ
167
+ </Button.Root>
168
+ </Page.Actions>
169
+ <Page.Chips>
170
+ <SmartFilter.Chips />
171
+ </Page.Chips>
172
+ </Page.TopBar>
173
+ <Page.Body>{/* the orders table */}</Page.Body>
174
+ </Page.Root>
164
175
  </SmartFilter.Root>
165
176
  );
166
177
  }
167
178
  ```
168
179
 
169
- - One tier for the whole panel (default `m`): never `size` on one control inside — wrapped rows must
170
- stay level. A denser page wraps the toolbar in `<ControlSizeProvider value="s">`; every kit control
180
+ - One tier for the whole bar (default `m`): never `size` on one control inside — wrapped lines must
181
+ stay level. A denser page wraps the bar in `<ControlSizeProvider value="s">`; every kit control
171
182
  inside takes that tier.
172
- - The primary action is always there: on a phone it may take its own row or become icon-only with
173
- `aria-label`; it never disappears.
183
+ - A Button without an icon keeps its label at every step and leaves the bar less room before it
184
+ folds: give each one a `Button.Icon`.
185
+ - A SegmentedControl in `Page.Tools` needs no `fullWidth`: the bar sets it.
186
+ - The primary action is on screen at every width — as its icon at the narrowest; it never folds and
187
+ never disappears.
174
188
  - Section totals go into `SegmentedControl.Count`, not into stat cards above the table.
175
- - A long form saves through the panel's action with a count («Сохранить 3 изменения»), never a sticky
176
- bar at the bottom of a phone screen.
177
- - Do not duplicate search: if the panel has one, the list below filters by it.
189
+ - A long form saves through the bar's primary action with a count («Сохранить 3 изменения»), never a
190
+ sticky bar at the bottom of a phone screen.
191
+ - Do not duplicate search: if the bar has one, the list below filters by it.
178
192
 
179
193
  ## Switchers
180
194
 
181
- - **Three width modes:** by content (`fullWidth` off), full width (`fullWidth`), full width only when
182
- narrow (a `fullWidth` SegmentedControl inside `PageToolbar.Sections` — the toolbar decides).
183
- - Sections of a page → SegmentedControl in `PageToolbar.Sections`; panels inside a card or a section →
195
+ - **Three width modes:** by content (`fullWidth` off), full width (`fullWidth`), full width only on
196
+ a line of its own (a SegmentedControl in `Page.Tools` — the bar decides).
197
+ - Sections of a page → SegmentedControl in `Page.Tools`; panels inside a card or a section →
184
198
  Tabs (the folder look belongs to its panel).
185
199
  - Every switcher — Tabs, SegmentedControl, a horizontal ButtonGroup and BottomNav — scrolls inside
186
200
  itself when its items do not fit: never a second line, never a truncated item. Its hidden edges
@@ -195,9 +209,9 @@ export function OrdersPanel() {
195
209
 
196
210
  ## List + details, side panels
197
211
 
198
- - A list people work through record by record (mail, a messenger, tickets) is `PageContent.Split`:
199
- the list in a 16–20rem column with the details beside it from 48rem of the split's own width, one
200
- pane at a time with `PageContent.BackButton` below it. Details opened now and then from a table
212
+ - A list people work through record by record (mail, a messenger, tickets) is `Page.Split`:
213
+ the list (`Page.List`) in a 16–20rem column with the details (`Page.Detail`) beside it from 48rem
214
+ of the split's own width, one pane at a time with `Page.BackButton` below it. Details opened now and then from a table
201
215
  open in a Drawer.
202
216
  - A side panel of details becomes full-screen on a phone (`Drawer.Content` is full width below 640).
203
217
  - Its period / view controls stay visible on every tab of the panel.
@@ -205,7 +219,7 @@ export function OrdersPanel() {
205
219
  ## Components on narrow widths — what you still decide
206
220
 
207
221
  **Tables.** Let DataTable scroll inside itself; offer a column chooser (`DataTable.ColumnsMenu` in
208
- `toolbar`; the key column `hideable: false`); `stickyFirstColumn` for the name. On phones a table / cards switch in `PageToolbar.View` is fine — silently dropping columns
222
+ `toolbar`; the key column `hideable: false`); `stickyFirstColumn` for the name. On phones a table / cards switch in `Page.Tools` is fine — silently dropping columns
209
223
  by breakpoint is not. Never ask to rotate the phone.
210
224
 
211
225
  **Card grids.** [Intrinsic grids](#intrinsic-grids), never a breakpoint. Tiles of a row share one
@@ -257,7 +271,7 @@ Target CLS ≤ 0.1: nothing moves while loading or when a filter changes.
257
271
  Drag the window through 320, 390, 768, 1024, 1280 and 1920px — continuously, not only at these points.
258
272
 
259
273
  - [ ] No horizontal page scroll at any width (tables and switchers scroll inside themselves).
260
- - [ ] The primary action is on screen at every width — never hidden ([the page panel](#page-panel--pagetoolbar)).
274
+ - [ ] The primary action is on screen at every width — never hidden ([the page's top bar](#the-pages-top-bar--pagetopbar)).
261
275
  - [ ] Every item alone in its row stretches; items of stretched switchers are equal.
262
276
  - [ ] All controls in a row share one height; no «staircase» after a wrap.
263
277
  - [ ] Text never overlaps and is cut only at its own block's edge; cut text has a tooltip or `title`.
@@ -6,6 +6,8 @@ type LayerTheme = {
6
6
  hi: number;
7
7
  /** Direction of control fills from their host: −1 darker, +1 lighter. */
8
8
  control: 1 | -1;
9
+ /** Steps from a track up to its selected segment (thumb). */
10
+ selected: number;
9
11
  };
10
12
  export declare const LIGHT_LAYERS: LayerTheme;
11
13
  export declare const DARK_LAYERS: LayerTheme;
@@ -15,6 +15,8 @@ export declare const primitiveTokens: {
15
15
  readonly 100: "#e8eaee";
16
16
  readonly 150: "#e0e3e8";
17
17
  readonly 300: "#b9bec8";
18
+ /** Dark muted text: AA on the hovered fill of the deepest layer. */
19
+ readonly 350: "#a1a8b6";
18
20
  readonly 400: "#949bab";
19
21
  readonly 500: "#636a79";
20
22
  readonly 600: "#575e6d";
@@ -131,9 +133,12 @@ export declare const primitiveTokens: {
131
133
  readonly 700: "#be185d";
132
134
  };
133
135
  };
134
- /** 4px grid. Key = number of 4px steps (`4` → 16px). */
136
+ /**
137
+ * 4px grid. Key = number of 4px steps (`4` → 16px). `0` carries a unit: a unitless `0` is a
138
+ * number inside `calc()` / `max()`, and `calc(100% + 0)` is invalid (the declaration drops).
139
+ */
135
140
  readonly space: {
136
- readonly 0: "0";
141
+ readonly 0: "0rem";
137
142
  readonly 1: "0.25rem";
138
143
  readonly 2: "0.5rem";
139
144
  readonly 3: "0.75rem";
@@ -165,6 +170,11 @@ export declare const primitiveTokens: {
165
170
  /** `… Fallback`: the metric-matched local faces of the opt-in `fonts.css`. */
166
171
  readonly sans: "\"Golos Text\", \"Golos Text Fallback\", ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif";
167
172
  readonly mono: "\"JetBrains Mono\", \"JetBrains Mono Fallback\", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace";
173
+ /**
174
+ * Key caps: the mono faces for letters and digits, then the system UI face before the mono
175
+ * fallbacks — the mono faces have no ⇧ ⌥ ⌃ or ⌘, and Menlo draws them small and light.
176
+ */
177
+ readonly key: "\"JetBrains Mono\", \"JetBrains Mono Fallback\", ui-monospace, SFMono-Regular, system-ui, -apple-system, \"Segoe UI Symbol\", Menlo, Consolas, monospace";
168
178
  };
169
179
  /** Modular scale, ~1.2 in the body range, ~1.25 for headings. */
170
180
  readonly size: {
@@ -142,6 +142,12 @@ export declare const semanticTokens: {
142
142
  readonly control: {
143
143
  /** Switch thumb, slider thumb. */
144
144
  readonly thumb: "{color.white}";
145
+ /** A disabled switch thumb: quiet on the disabled track, like the rest of the control. */
146
+ readonly thumbDisabled: "{color.white}";
147
+ };
148
+ readonly skeleton: {
149
+ /** A loading placeholder: a wash over whatever layer it sits on, readable in both themes. */
150
+ readonly fill: "color-mix(in srgb, {color.gray.925} 6%, transparent)";
145
151
  };
146
152
  /**
147
153
  * The tooltip is an inverse chip: everything inside it (a Kbd, a secondary line) reads its
@@ -224,6 +230,7 @@ export declare const semanticTokens: {
224
230
  readonly family: {
225
231
  readonly sans: "{font.family.sans}";
226
232
  readonly mono: "{font.family.mono}";
233
+ readonly key: "{font.family.key}";
227
234
  };
228
235
  readonly weight: {
229
236
  readonly regular: "{font.weight.regular}";
@@ -25,8 +25,9 @@ export declare const darkThemeOverrides: {
25
25
  readonly text: {
26
26
  readonly primary: "{color.gray.100}";
27
27
  readonly secondary: "{color.gray.300}";
28
- readonly muted: "{color.gray.400}";
29
- readonly placeholder: "{color.gray.400}";
28
+ /** gray.350: AA on every layer, its fill and the fill's hover (a hovered field, row, chip). */
29
+ readonly muted: "{color.gray.350}";
30
+ readonly placeholder: "{color.gray.350}";
30
31
  readonly disabled: "{color.gray.600}";
31
32
  readonly inverse: "{color.gray.925}";
32
33
  };
@@ -80,6 +81,10 @@ export declare const darkThemeOverrides: {
80
81
  };
81
82
  readonly control: {
82
83
  readonly thumb: "{color.gray.100}";
84
+ readonly thumbDisabled: "{color.gray.600}";
85
+ };
86
+ readonly skeleton: {
87
+ readonly fill: "color-mix(in srgb, {color.gray.100} 10%, transparent)";
83
88
  };
84
89
  /** A light chip over the dark UI: inverse like in light, so it reads over any layer. */
85
90
  readonly tooltip: {
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "prime-ui-kit",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "packageManager": "bun@1.3.13",
5
- "description": "React 19 UI kit for product interfaces: 80 composable components on one design contract — forms, selects, tables, overlays, navigation, app shell. CSS Modules, --prime-* tokens, light and dark themes, TypeScript, a11y, Next.js App Router ready. Ships COMPONENT.md docs, copyable examples and an agent skill.",
5
+ "description": "React 19 UI kit for product interfaces: 78 composable components on one design contract — forms, selects, tables, overlays, navigation, app shell. CSS Modules, --prime-* tokens, light and dark themes, TypeScript, a11y, Next.js App Router ready. Ships COMPONENT.md docs, copyable examples and an agent skill.",
6
6
  "bin": {
7
7
  "prime-ui-kit": "bin/prime-ui-kit.js"
8
8
  },
@@ -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}
@@ -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));