prime-ui-kit 0.13.1 → 0.15.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 (609) hide show
  1. package/README.md +20 -20
  2. package/dist/chunks/{chunk-XNOJEX55.js → chunk-2IKH55MI.js} +1 -1
  3. package/dist/chunks/{chunk-JV2KB5JZ.js → chunk-THFZIHKU.js} +3761 -3041
  4. package/dist/chunks/{chunk-PK2GC77E.js → chunk-XJAVS6FH.js} +213 -188
  5. package/dist/color-picker.js +2 -2
  6. package/dist/components/banner/Banner.d.ts +5 -2
  7. package/dist/components/chart-frame/ChartFrame.d.ts +19 -6
  8. package/dist/components/chat/Chat.d.ts +2 -2
  9. package/dist/components/chat/ChatPinned.d.ts +2 -2
  10. package/dist/components/chat/MessageList.d.ts +1 -1
  11. package/dist/components/chat/chatContext.d.ts +1 -1
  12. package/dist/components/dnd/Dnd.d.ts +1 -1
  13. package/dist/components/field-list/FieldList.d.ts +90 -0
  14. package/dist/components/index.d.ts +3 -1
  15. package/dist/components/input/Input.d.ts +2 -2
  16. package/dist/components/kanban/Kanban.d.ts +6 -3
  17. package/dist/components/login-form/LoginForm.d.ts +5 -1
  18. package/dist/components/page-content/PageContent.d.ts +55 -4
  19. package/dist/components/sparkline/Sparkline.d.ts +64 -15
  20. package/dist/components/sparkline/geometry.d.ts +26 -0
  21. package/dist/components/tooltip/Tooltip.d.ts +5 -2
  22. package/dist/hooks/usePosition.d.ts +15 -4
  23. package/dist/index.css +1 -1
  24. package/dist/index.js +4 -2
  25. package/dist/internal/ChartTooltip.d.ts +26 -0
  26. package/dist/internal/FieldAction.d.ts +6 -7
  27. package/dist/internal/fieldCell.d.ts +21 -0
  28. package/dist/internal/messageList.d.ts +2 -2
  29. package/dist/internal/palette.d.ts +7 -0
  30. package/dist/internal/swatch.d.ts +6 -2
  31. package/dist/layout/app-header/AppHeader.d.ts +9 -28
  32. package/dist/layout/index.d.ts +1 -1
  33. package/dist/skill/SKILL.md +32 -20
  34. package/dist/skill/anti-slop.md +77 -4
  35. package/dist/skill/api-contract.md +2 -2
  36. package/dist/skill/cheatsheet.md +33 -7
  37. package/dist/skill/checklist.md +28 -6
  38. package/dist/skill/choosing.md +17 -14
  39. package/dist/skill/components.md +9 -15
  40. package/dist/skill/composition.md +301 -61
  41. package/dist/skill/foundations.md +9 -7
  42. package/dist/skill/layouts.md +70 -37
  43. package/dist/skill/reference/components/avatar/COMPONENT.md +4 -4
  44. package/dist/skill/reference/components/avatar/examples/presence.tsx +1 -1
  45. package/dist/skill/reference/components/avatar/examples/states.tsx +5 -5
  46. package/dist/skill/reference/components/badge/examples/applied-filters.tsx +13 -19
  47. package/dist/skill/reference/components/badge/examples/examples.module.css +1 -8
  48. package/dist/skill/reference/components/badge/examples/server-tags.tsx +2 -6
  49. package/dist/skill/reference/components/banner/COMPONENT.md +6 -6
  50. package/dist/skill/reference/components/banner/examples/dismissible.tsx +22 -11
  51. package/dist/skill/reference/components/banner/examples/examples.module.css +4 -8
  52. package/dist/skill/reference/components/banner/examples/narrow.tsx +1 -1
  53. package/dist/skill/reference/components/banner/examples/page-strip.tsx +16 -22
  54. package/dist/skill/reference/components/breadcrumb/COMPONENT.md +5 -4
  55. package/dist/skill/reference/components/breadcrumb/examples/ellipsis.tsx +2 -2
  56. package/dist/skill/reference/components/breadcrumb/examples/overflow.tsx +1 -1
  57. package/dist/skill/reference/components/button-group/COMPONENT.md +2 -2
  58. package/dist/skill/reference/components/button-group/examples/in-form.tsx +22 -2
  59. package/dist/skill/reference/components/button-group/examples/states.tsx +10 -1
  60. package/dist/skill/reference/components/card/COMPONENT.md +7 -5
  61. package/dist/skill/reference/components/card/examples/examples.module.css +0 -28
  62. package/dist/skill/reference/components/card/examples/kpi-media.tsx +13 -11
  63. package/dist/skill/reference/components/card/examples/narrow.tsx +1 -1
  64. package/dist/skill/reference/components/card/examples/panel-chart.tsx +45 -22
  65. package/dist/skill/reference/components/card/examples/screen.module.css +14 -0
  66. package/dist/skill/reference/components/card/examples/screen.tsx +362 -0
  67. package/dist/skill/reference/components/card/examples/variants.tsx +15 -1
  68. package/dist/skill/reference/components/chart-frame/COMPONENT.md +12 -8
  69. package/dist/skill/reference/components/chart-frame/examples/fill-height.tsx +119 -0
  70. package/dist/skill/reference/components/chart-frame/examples/states.tsx +3 -1
  71. package/dist/skill/reference/components/chart-frame/examples/tooltip.tsx +20 -24
  72. package/dist/skill/reference/components/chat/COMPONENT.md +6 -4
  73. package/dist/skill/reference/components/chat/examples/group-chat.tsx +15 -2
  74. package/dist/skill/reference/components/chat/examples/reactions.tsx +121 -0
  75. package/dist/skill/reference/components/chat/examples/screen.module.css +9 -0
  76. package/dist/skill/{patterns/chat.tsx → reference/components/chat/examples/screen.tsx} +187 -350
  77. package/dist/skill/reference/components/chat/examples/search.tsx +1 -1
  78. package/dist/skill/reference/components/chat-list/COMPONENT.md +2 -1
  79. package/dist/skill/reference/components/chat-list/examples/links.tsx +72 -0
  80. package/dist/skill/reference/components/checkbox/COMPONENT.md +1 -1
  81. package/dist/skill/reference/components/checkbox/examples/examples.module.css +5 -1
  82. package/dist/skill/reference/components/checkbox/examples/indicator.tsx +37 -9
  83. package/dist/skill/reference/components/checkbox/examples/states.tsx +6 -1
  84. package/dist/skill/reference/components/color-field/COMPONENT.md +1 -1
  85. package/dist/skill/reference/components/color-picker/COMPONENT.md +6 -5
  86. package/dist/skill/reference/components/color-picker/examples/controlled-open.tsx +37 -0
  87. package/dist/skill/reference/components/color-picker/examples/presets.tsx +2 -2
  88. package/dist/skill/reference/components/color-picker/examples/states.tsx +23 -14
  89. package/dist/skill/reference/components/color-swatches/COMPONENT.md +1 -0
  90. package/dist/skill/reference/components/composer/COMPONENT.md +2 -1
  91. package/dist/skill/reference/components/composer/examples/attach-menu.tsx +78 -0
  92. package/dist/skill/reference/components/composer/examples/attachments.tsx +2 -2
  93. package/dist/skill/reference/components/crossfade/COMPONENT.md +1 -0
  94. package/dist/skill/{patterns/screen-states.module.css → reference/components/crossfade/examples/screen.module.css} +3 -17
  95. package/dist/skill/reference/components/crossfade/examples/screen.tsx +197 -0
  96. package/dist/skill/reference/components/data-table/COMPONENT.md +3 -2
  97. package/dist/skill/reference/components/data-table/examples/detail-panel.tsx +36 -37
  98. package/dist/skill/reference/components/data-table/examples/examples.module.css +0 -12
  99. package/dist/skill/reference/components/data-table/examples/numeric.tsx +36 -4
  100. package/dist/skill/reference/components/data-table/examples/overview.tsx +1 -0
  101. package/dist/skill/reference/components/data-table/examples/row-open.tsx +7 -36
  102. package/dist/skill/{patterns/list-page.module.css → reference/components/data-table/examples/screen.module.css} +1 -7
  103. package/dist/skill/{patterns/list-page.tsx → reference/components/data-table/examples/screen.tsx} +84 -64
  104. package/dist/skill/reference/components/datepicker/COMPONENT.md +6 -4
  105. package/dist/skill/reference/components/datepicker/examples/examples.module.css +2 -6
  106. package/dist/skill/reference/components/datepicker/examples/in-form.tsx +47 -55
  107. package/dist/skill/reference/components/datepicker/examples/locale.tsx +35 -0
  108. package/dist/skill/reference/components/datepicker/examples/range-presets.tsx +11 -2
  109. package/dist/skill/reference/components/datepicker/examples/states.tsx +9 -1
  110. package/dist/skill/reference/components/description-list/COMPONENT.md +1 -0
  111. package/dist/skill/{patterns/detail-page.module.css → reference/components/description-list/examples/screen.module.css} +2 -12
  112. package/dist/skill/reference/components/description-list/examples/screen.tsx +214 -0
  113. package/dist/skill/reference/components/description-list/examples/structure.tsx +1 -1
  114. package/dist/skill/reference/components/digit-input/COMPONENT.md +3 -1
  115. package/dist/skill/reference/components/digit-input/examples/states.tsx +3 -1
  116. package/dist/skill/reference/components/digit-input/examples/without-focus-ring.tsx +13 -0
  117. package/dist/skill/reference/components/divider/examples/with-icon.tsx +2 -2
  118. package/dist/skill/reference/components/dnd/COMPONENT.md +7 -5
  119. package/dist/skill/reference/components/dnd/examples/drop-zones.tsx +82 -49
  120. package/dist/skill/reference/components/dnd/examples/examples.module.css +50 -0
  121. package/dist/skill/reference/components/dnd/examples/states.tsx +54 -0
  122. package/dist/skill/reference/components/dnd/examples/table.tsx +113 -0
  123. package/dist/skill/reference/components/drawer/COMPONENT.md +1 -0
  124. package/dist/skill/reference/components/drawer/examples/dismiss.tsx +5 -3
  125. package/dist/skill/reference/components/drawer/examples/examples.module.css +0 -13
  126. package/dist/skill/reference/components/drawer/examples/header-actions.tsx +5 -9
  127. package/dist/skill/reference/components/drawer/examples/overview.tsx +6 -18
  128. package/dist/skill/reference/components/drawer/examples/screen.tsx +298 -0
  129. package/dist/skill/reference/components/dropdown/examples/examples.module.css +1 -5
  130. package/dist/skill/reference/components/empty-page/COMPONENT.md +1 -1
  131. package/dist/skill/reference/components/empty-page/examples/region-error.tsx +8 -2
  132. package/dist/skill/reference/components/example-frame/COMPONENT.md +3 -2
  133. package/dist/skill/reference/components/example-frame/examples/initial-view.tsx +44 -0
  134. package/dist/skill/reference/components/field-list/COMPONENT.md +165 -0
  135. package/dist/skill/reference/components/field-list/examples/base-row.tsx +76 -0
  136. package/dist/skill/reference/components/field-list/examples/controlled.tsx +72 -0
  137. package/dist/skill/reference/components/field-list/examples/errors.tsx +88 -0
  138. package/dist/skill/reference/components/field-list/examples/examples.module.css +34 -0
  139. package/dist/skill/reference/components/field-list/examples/limits.tsx +55 -0
  140. package/dist/skill/reference/components/field-list/examples/locked.tsx +139 -0
  141. package/dist/skill/reference/components/field-list/examples/narrow.tsx +68 -0
  142. package/dist/skill/reference/components/field-list/examples/overview.tsx +66 -0
  143. package/dist/skill/reference/components/field-list/examples/reorder.tsx +42 -0
  144. package/dist/skill/reference/components/field-list/examples/screen.module.css +18 -0
  145. package/dist/skill/reference/components/field-list/examples/screen.tsx +316 -0
  146. package/dist/skill/reference/components/field-list/examples/sizes.tsx +42 -0
  147. package/dist/skill/reference/components/field-list/examples/states.tsx +51 -0
  148. package/dist/skill/reference/components/file-upload/COMPONENT.md +7 -6
  149. package/dist/skill/reference/components/file-upload/examples/custom-body.tsx +2 -1
  150. package/dist/skill/reference/components/file-upload/examples/examples.module.css +1 -7
  151. package/dist/skill/reference/components/file-upload/examples/file-cards.tsx +10 -1
  152. package/dist/skill/reference/components/file-upload/examples/gallery.tsx +2 -2
  153. package/dist/skill/reference/components/file-upload/examples/in-form.tsx +4 -9
  154. package/dist/skill/reference/components/file-upload/examples/overview.tsx +5 -1
  155. package/dist/skill/reference/components/file-upload/examples/row-parts.tsx +24 -1
  156. package/dist/skill/{patterns/media-library.module.css → reference/components/file-upload/examples/screen.module.css} +2 -23
  157. package/dist/skill/reference/components/file-upload/examples/screen.tsx +646 -0
  158. package/dist/skill/reference/components/file-upload/examples/states.tsx +6 -2
  159. package/dist/skill/reference/components/file-upload/examples/validation.tsx +11 -2
  160. package/dist/skill/reference/components/file-upload/examples/variants.tsx +3 -20
  161. package/dist/skill/reference/components/gantt/COMPONENT.md +2 -1
  162. package/dist/skill/reference/components/gantt/examples/screen.module.css +14 -0
  163. package/dist/skill/{patterns/schedule.tsx → reference/components/gantt/examples/screen.tsx} +174 -170
  164. package/dist/skill/reference/components/gantt/examples/states.tsx +6 -2
  165. package/dist/skill/reference/components/input/COMPONENT.md +2 -2
  166. package/dist/skill/reference/components/input/examples/examples.module.css +2 -13
  167. package/dist/skill/reference/components/input/examples/in-form.tsx +1 -9
  168. package/dist/skill/reference/components/input/examples/password-strength.tsx +34 -8
  169. package/dist/skill/reference/components/input/examples/states.tsx +6 -1
  170. package/dist/skill/reference/components/kanban/COMPONENT.md +16 -11
  171. package/dist/skill/reference/components/kanban/examples/columns.tsx +8 -5
  172. package/dist/skill/reference/components/kanban/examples/limits.tsx +2 -1
  173. package/dist/skill/reference/components/kanban/examples/screen.module.css +17 -0
  174. package/dist/skill/{patterns/kanban-board.tsx → reference/components/kanban/examples/screen.tsx} +132 -172
  175. package/dist/skill/reference/components/kanban/examples/states.tsx +17 -6
  176. package/dist/skill/reference/components/kanban/examples/variants.tsx +16 -8
  177. package/dist/skill/reference/components/list/COMPONENT.md +1 -1
  178. package/dist/skill/reference/components/login-form/COMPONENT.md +6 -5
  179. package/dist/skill/reference/components/login-form/examples/examples.module.css +2 -21
  180. package/dist/skill/reference/components/login-form/examples/forgot-password.tsx +28 -32
  181. package/dist/skill/reference/components/login-form/examples/narrow.tsx +1 -1
  182. package/dist/skill/reference/components/login-form/examples/overview.tsx +45 -47
  183. package/dist/skill/reference/components/login-form/examples/register.tsx +64 -68
  184. package/dist/skill/reference/components/login-form/examples/reset-password.tsx +50 -47
  185. package/dist/skill/reference/components/login-form/examples/sizes.tsx +4 -6
  186. package/dist/skill/reference/components/login-form/examples/states.tsx +53 -57
  187. package/dist/skill/reference/components/login-form/examples/structure.tsx +18 -22
  188. package/dist/skill/reference/components/login-form/examples/verification-code.tsx +41 -45
  189. package/dist/skill/reference/components/media-viewer/COMPONENT.md +3 -3
  190. package/dist/skill/reference/components/media-viewer/examples/dismiss.tsx +5 -1
  191. package/dist/skill/reference/components/message/COMPONENT.md +6 -5
  192. package/dist/skill/reference/components/message/examples/file.tsx +5 -1
  193. package/dist/skill/reference/components/message/examples/media-open.tsx +48 -0
  194. package/dist/skill/reference/components/message/examples/status.tsx +21 -3
  195. package/dist/skill/reference/components/message/examples/text-formatting.tsx +7 -1
  196. package/dist/skill/reference/components/modal/COMPONENT.md +2 -1
  197. package/dist/skill/reference/components/modal/examples/custom-container.tsx +20 -20
  198. package/dist/skill/reference/components/modal/examples/dismiss.tsx +5 -3
  199. package/dist/skill/reference/components/modal/examples/enter-key.tsx +116 -0
  200. package/dist/skill/reference/components/modal/examples/examples.module.css +7 -13
  201. package/dist/skill/reference/components/modal/examples/structure.tsx +5 -2
  202. package/dist/skill/reference/components/native-select/COMPONENT.md +1 -1
  203. package/dist/skill/reference/components/native-select/examples/states.tsx +5 -1
  204. package/dist/skill/reference/components/notification/COMPONENT.md +2 -1
  205. package/dist/skill/reference/components/notification/examples/dismiss.tsx +2 -2
  206. package/dist/skill/reference/components/page-content/COMPONENT.md +71 -14
  207. package/dist/skill/reference/components/page-content/examples/grid.tsx +107 -0
  208. package/dist/skill/reference/components/page-content/examples/list-detail.tsx +0 -3
  209. package/dist/skill/reference/components/page-content/examples/overview.tsx +2 -2
  210. package/dist/skill/{patterns/settings-page.module.css → reference/components/page-content/examples/screen.module.css} +1 -21
  211. package/dist/skill/{patterns/settings-page.tsx → reference/components/page-content/examples/screen.tsx} +61 -82
  212. package/dist/skill/reference/components/page-content/examples/sections.tsx +81 -0
  213. package/dist/skill/reference/components/page-content/examples/variants.tsx +4 -11
  214. package/dist/skill/reference/components/page-toolbar/COMPONENT.md +18 -16
  215. package/dist/skill/reference/components/page-toolbar/examples/narrow.tsx +6 -3
  216. package/dist/skill/reference/components/pagination/examples/controlled.tsx +29 -29
  217. package/dist/skill/reference/components/pagination/examples/examples.module.css +0 -2
  218. package/dist/skill/reference/components/progress-bar/COMPONENT.md +1 -1
  219. package/dist/skill/reference/components/progress-bar/examples/segments.tsx +2 -2
  220. package/dist/skill/reference/components/progress-circle/COMPONENT.md +1 -1
  221. package/dist/skill/reference/components/progress-circle/examples/segments.tsx +8 -3
  222. package/dist/skill/reference/components/radio/COMPONENT.md +1 -0
  223. package/dist/skill/reference/components/radio/examples/examples.module.css +14 -0
  224. package/dist/skill/reference/components/radio/examples/in-form.tsx +45 -0
  225. package/dist/skill/reference/components/scroll-container/COMPONENT.md +1 -0
  226. package/dist/skill/reference/components/scroll-container/examples/auto-scroll.tsx +3 -3
  227. package/dist/skill/reference/components/scroll-container/examples/chat.tsx +3 -3
  228. package/dist/skill/reference/components/scroll-container/examples/edges.tsx +6 -3
  229. package/dist/skill/reference/components/scroll-container/examples/examples.module.css +4 -17
  230. package/dist/skill/reference/components/scroll-container/examples/load-more.tsx +51 -0
  231. package/dist/skill/reference/components/scroll-container/examples/lock.tsx +3 -5
  232. package/dist/skill/reference/components/scroll-container/examples/overscroll.tsx +3 -3
  233. package/dist/skill/reference/components/scroll-container/examples/overview.tsx +3 -3
  234. package/dist/skill/reference/components/scroll-container/examples/scrollbar.tsx +13 -7
  235. package/dist/skill/reference/components/scroll-container/examples/variants.tsx +13 -7
  236. package/dist/skill/reference/components/segmented-control/COMPONENT.md +3 -2
  237. package/dist/skill/reference/components/segmented-control/examples/in-form.tsx +5 -1
  238. package/dist/skill/reference/components/segmented-control/examples/states.tsx +10 -1
  239. package/dist/skill/reference/components/select/COMPONENT.md +5 -3
  240. package/dist/skill/reference/components/select/examples/examples.module.css +2 -7
  241. package/dist/skill/reference/components/select/examples/icon-only.tsx +38 -0
  242. package/dist/skill/reference/components/select/examples/states.tsx +13 -1
  243. package/dist/skill/reference/components/sheet/COMPONENT.md +2 -0
  244. package/dist/skill/reference/components/sheet/examples/guard.tsx +72 -0
  245. package/dist/skill/reference/components/sheet/examples/header-actions.tsx +56 -0
  246. package/dist/skill/reference/components/slider/COMPONENT.md +2 -1
  247. package/dist/skill/reference/components/slider/examples/examples.module.css +8 -0
  248. package/dist/skill/reference/components/slider/examples/in-form.tsx +47 -0
  249. package/dist/skill/reference/components/slider/examples/states.tsx +4 -1
  250. package/dist/skill/reference/components/smart-filter/COMPONENT.md +1 -1
  251. package/dist/skill/reference/components/smart-filter/examples/controlled.tsx +3 -3
  252. package/dist/skill/reference/components/smart-filter/examples/ranges.tsx +44 -10
  253. package/dist/skill/reference/components/sparkline/COMPONENT.md +83 -30
  254. package/dist/skill/reference/components/sparkline/examples/compact.tsx +1 -1
  255. package/dist/skill/reference/components/sparkline/examples/curve.tsx +28 -0
  256. package/dist/skill/reference/components/sparkline/examples/gaps.tsx +33 -0
  257. package/dist/skill/reference/components/sparkline/examples/overview.tsx +11 -2
  258. package/dist/skill/reference/components/sparkline/examples/period.tsx +7 -2
  259. package/dist/skill/reference/components/sparkline/examples/reference.tsx +38 -0
  260. package/dist/skill/reference/components/sparkline/examples/variants.tsx +2 -2
  261. package/dist/skill/reference/components/tabs/COMPONENT.md +1 -1
  262. package/dist/skill/reference/components/tabs/examples/examples.module.css +0 -6
  263. package/dist/skill/reference/components/tabs/examples/in-drawer.tsx +11 -13
  264. package/dist/skill/reference/components/tabs/examples/sizes.tsx +1 -1
  265. package/dist/skill/reference/components/tag-select/COMPONENT.md +1 -1
  266. package/dist/skill/reference/components/tag-select/examples/states.tsx +8 -1
  267. package/dist/skill/reference/components/textarea/COMPONENT.md +1 -1
  268. package/dist/skill/reference/components/textarea/examples/examples.module.css +0 -6
  269. package/dist/skill/reference/components/textarea/examples/in-form.tsx +1 -9
  270. package/dist/skill/reference/components/textarea/examples/states.tsx +2 -1
  271. package/dist/skill/reference/components/thumbnail/COMPONENT.md +2 -1
  272. package/dist/skill/reference/components/thumbnail/examples/examples.module.css +1 -1
  273. package/dist/skill/reference/components/thumbnail/examples/fit.tsx +24 -0
  274. package/dist/skill/reference/components/thumbnail/examples/video.tsx +20 -1
  275. package/dist/skill/reference/components/timeline/COMPONENT.md +1 -1
  276. package/dist/skill/reference/components/timeline/examples/examples.module.css +0 -8
  277. package/dist/skill/reference/components/timeline/examples/links.tsx +55 -14
  278. package/dist/skill/reference/components/timeline/examples/narrow.tsx +2 -2
  279. package/dist/skill/reference/components/timeline/examples/sizes.tsx +3 -3
  280. package/dist/skill/reference/components/timeline/examples/variants.tsx +4 -4
  281. package/dist/skill/reference/components/tooltip/COMPONENT.md +7 -5
  282. package/dist/skill/reference/components/tooltip/examples/placement.tsx +2 -1
  283. package/dist/skill/reference/components/tooltip/examples/toolbar.tsx +2 -2
  284. package/dist/skill/reference/components/typography/examples/weights.tsx +3 -0
  285. package/dist/skill/reference/components/video-note/COMPONENT.md +3 -3
  286. package/dist/skill/reference/components/video-note/examples/controlled.tsx +19 -2
  287. package/dist/skill/reference/components/video-note/examples/in-message.tsx +5 -2
  288. package/dist/skill/reference/components/visually-hidden/COMPONENT.md +2 -1
  289. package/dist/skill/reference/components/visually-hidden/examples/assertive.tsx +39 -0
  290. package/dist/skill/reference/components/voice-player/COMPONENT.md +3 -3
  291. package/dist/skill/reference/components/voice-player/examples/call-recording.tsx +19 -9
  292. package/dist/skill/reference/components/voice-player/examples/controlled.tsx +20 -3
  293. package/dist/skill/reference/layout/app-header/COMPONENT.md +46 -63
  294. package/dist/skill/reference/layout/app-header/examples/breadcrumbs.tsx +10 -9
  295. package/dist/skill/reference/layout/app-header/examples/examples.module.css +1 -1
  296. package/dist/skill/reference/layout/app-header/examples/in-app-shell.tsx +2 -3
  297. package/dist/skill/reference/layout/app-header/examples/narrow.tsx +4 -5
  298. package/dist/skill/reference/layout/app-header/examples/overview.tsx +8 -10
  299. package/dist/skill/reference/layout/app-header/examples/page-title.tsx +3 -10
  300. package/dist/skill/reference/layout/app-shell/COMPONENT.md +5 -4
  301. package/dist/skill/reference/layout/app-shell/examples/footer.tsx +2 -2
  302. package/dist/skill/reference/layout/app-shell/examples/overview.tsx +17 -32
  303. package/dist/skill/{patterns/app-shell.module.css → reference/layout/app-shell/examples/screen.module.css} +1 -8
  304. package/dist/skill/reference/layout/app-shell/examples/screen.tsx +262 -0
  305. package/dist/skill/reference/layout/app-shell/examples/template.tsx +31 -11
  306. package/dist/skill/reference/layout/bottom-nav/examples/floating-action.tsx +2 -2
  307. package/dist/skill/reference/layout/bottom-nav/examples/floating.tsx +2 -2
  308. package/dist/skill/reference/layout/bottom-nav/examples/in-app-shell.tsx +2 -2
  309. package/dist/skill/reference/layout/sidebar/COMPONENT.md +7 -4
  310. package/dist/skill/reference/layout/sidebar/examples/account.tsx +2 -2
  311. package/dist/skill/reference/layout/sidebar/examples/collapsible-groups.tsx +12 -4
  312. package/dist/skill/reference/layout/sidebar/examples/custom-part.tsx +53 -0
  313. package/dist/skill/reference/layout/sidebar/examples/examples.module.css +5 -0
  314. package/dist/skill/reference/layout/sidebar/examples/narrow.tsx +53 -0
  315. package/dist/skill/reference/layout/sidebar/examples/persist.tsx +57 -0
  316. package/dist/skill/reference/layout/sidebar/examples/router.tsx +14 -2
  317. package/dist/skill/reference/layout/sidebar/examples/structure.tsx +7 -2
  318. package/dist/skill/responsive.md +7 -5
  319. package/dist/skill/ux.md +145 -0
  320. package/dist/tokens/semantic.d.ts +2 -0
  321. package/package.json +1 -1
  322. package/src/components/avatar/COMPONENT.md +4 -4
  323. package/src/components/avatar/examples/presence.tsx +1 -1
  324. package/src/components/avatar/examples/states.tsx +5 -5
  325. package/src/components/badge/examples/applied-filters.tsx +13 -19
  326. package/src/components/badge/examples/examples.module.css +1 -8
  327. package/src/components/badge/examples/server-tags.tsx +2 -6
  328. package/src/components/banner/COMPONENT.md +6 -6
  329. package/src/components/banner/examples/dismissible.tsx +22 -11
  330. package/src/components/banner/examples/examples.module.css +4 -8
  331. package/src/components/banner/examples/narrow.tsx +1 -1
  332. package/src/components/banner/examples/page-strip.tsx +16 -22
  333. package/src/components/breadcrumb/COMPONENT.md +5 -4
  334. package/src/components/breadcrumb/examples/ellipsis.tsx +2 -2
  335. package/src/components/breadcrumb/examples/overflow.tsx +1 -1
  336. package/src/components/button-group/COMPONENT.md +2 -2
  337. package/src/components/button-group/examples/in-form.tsx +22 -2
  338. package/src/components/button-group/examples/states.tsx +10 -1
  339. package/src/components/card/COMPONENT.md +7 -5
  340. package/src/components/card/examples/examples.module.css +0 -28
  341. package/src/components/card/examples/kpi-media.tsx +13 -11
  342. package/src/components/card/examples/narrow.tsx +1 -1
  343. package/src/components/card/examples/panel-chart.tsx +45 -22
  344. package/src/components/card/examples/screen.module.css +14 -0
  345. package/src/components/card/examples/screen.tsx +362 -0
  346. package/src/components/card/examples/variants.tsx +15 -1
  347. package/src/components/chart-frame/COMPONENT.md +12 -8
  348. package/src/components/chart-frame/examples/fill-height.tsx +119 -0
  349. package/src/components/chart-frame/examples/states.tsx +3 -1
  350. package/src/components/chart-frame/examples/tooltip.tsx +20 -24
  351. package/src/components/chat/COMPONENT.md +6 -4
  352. package/src/components/chat/examples/group-chat.tsx +15 -2
  353. package/src/components/chat/examples/reactions.tsx +121 -0
  354. package/src/components/chat/examples/screen.module.css +9 -0
  355. package/src/components/chat/examples/screen.tsx +718 -0
  356. package/src/components/chat/examples/search.tsx +1 -1
  357. package/src/components/chat-list/COMPONENT.md +2 -1
  358. package/src/components/chat-list/examples/links.tsx +72 -0
  359. package/src/components/checkbox/COMPONENT.md +1 -1
  360. package/src/components/checkbox/examples/examples.module.css +5 -1
  361. package/src/components/checkbox/examples/indicator.tsx +37 -9
  362. package/src/components/checkbox/examples/states.tsx +6 -1
  363. package/src/components/color-field/COMPONENT.md +1 -1
  364. package/src/components/color-picker/COMPONENT.md +6 -5
  365. package/src/components/color-picker/examples/controlled-open.tsx +37 -0
  366. package/src/components/color-picker/examples/presets.tsx +2 -2
  367. package/src/components/color-picker/examples/states.tsx +23 -14
  368. package/src/components/color-swatches/COMPONENT.md +1 -0
  369. package/src/components/composer/COMPONENT.md +2 -1
  370. package/src/components/composer/examples/attach-menu.tsx +78 -0
  371. package/src/components/composer/examples/attachments.tsx +2 -2
  372. package/src/components/crossfade/COMPONENT.md +1 -0
  373. package/src/components/crossfade/examples/screen.module.css +40 -0
  374. package/src/components/crossfade/examples/screen.tsx +197 -0
  375. package/src/components/data-table/COMPONENT.md +3 -2
  376. package/src/components/data-table/examples/detail-panel.tsx +36 -37
  377. package/src/components/data-table/examples/examples.module.css +0 -12
  378. package/src/components/data-table/examples/numeric.tsx +36 -4
  379. package/src/components/data-table/examples/overview.tsx +1 -0
  380. package/src/components/data-table/examples/row-open.tsx +7 -36
  381. package/src/components/data-table/examples/screen.module.css +13 -0
  382. package/src/components/data-table/examples/screen.tsx +354 -0
  383. package/src/components/datepicker/COMPONENT.md +6 -4
  384. package/src/components/datepicker/examples/examples.module.css +2 -6
  385. package/src/components/datepicker/examples/in-form.tsx +47 -55
  386. package/src/components/datepicker/examples/locale.tsx +35 -0
  387. package/src/components/datepicker/examples/range-presets.tsx +11 -2
  388. package/src/components/datepicker/examples/states.tsx +9 -1
  389. package/src/components/description-list/COMPONENT.md +1 -0
  390. package/src/components/description-list/examples/screen.module.css +64 -0
  391. package/src/components/description-list/examples/screen.tsx +214 -0
  392. package/src/components/description-list/examples/structure.tsx +1 -1
  393. package/src/components/digit-input/COMPONENT.md +3 -1
  394. package/src/components/digit-input/examples/states.tsx +3 -1
  395. package/src/components/digit-input/examples/without-focus-ring.tsx +13 -0
  396. package/src/components/divider/examples/with-icon.tsx +2 -2
  397. package/src/components/dnd/COMPONENT.md +7 -5
  398. package/src/components/dnd/examples/drop-zones.tsx +82 -49
  399. package/src/components/dnd/examples/examples.module.css +50 -0
  400. package/src/components/dnd/examples/states.tsx +54 -0
  401. package/src/components/dnd/examples/table.tsx +113 -0
  402. package/src/components/drawer/COMPONENT.md +1 -0
  403. package/src/components/drawer/examples/dismiss.tsx +5 -3
  404. package/src/components/drawer/examples/examples.module.css +0 -13
  405. package/src/components/drawer/examples/header-actions.tsx +5 -9
  406. package/src/components/drawer/examples/overview.tsx +6 -18
  407. package/src/components/drawer/examples/screen.module.css +14 -0
  408. package/src/components/drawer/examples/screen.tsx +298 -0
  409. package/src/components/dropdown/examples/examples.module.css +1 -5
  410. package/src/components/empty-page/COMPONENT.md +1 -1
  411. package/src/components/empty-page/examples/region-error.tsx +8 -2
  412. package/src/components/example-frame/COMPONENT.md +3 -2
  413. package/src/components/example-frame/examples/initial-view.tsx +44 -0
  414. package/src/components/field-list/COMPONENT.md +165 -0
  415. package/src/components/field-list/examples/base-row.tsx +76 -0
  416. package/src/components/field-list/examples/controlled.tsx +72 -0
  417. package/src/components/field-list/examples/errors.tsx +88 -0
  418. package/src/components/field-list/examples/examples.module.css +34 -0
  419. package/src/components/field-list/examples/limits.tsx +55 -0
  420. package/src/components/field-list/examples/locked.tsx +139 -0
  421. package/src/components/field-list/examples/narrow.tsx +68 -0
  422. package/src/components/field-list/examples/overview.tsx +66 -0
  423. package/src/components/field-list/examples/reorder.tsx +42 -0
  424. package/src/components/field-list/examples/screen.module.css +18 -0
  425. package/src/components/field-list/examples/screen.tsx +316 -0
  426. package/src/components/field-list/examples/sizes.tsx +42 -0
  427. package/src/components/field-list/examples/states.tsx +51 -0
  428. package/src/components/file-upload/COMPONENT.md +7 -6
  429. package/src/components/file-upload/examples/custom-body.tsx +2 -1
  430. package/src/components/file-upload/examples/examples.module.css +1 -7
  431. package/src/components/file-upload/examples/file-cards.tsx +10 -1
  432. package/src/components/file-upload/examples/gallery.tsx +2 -2
  433. package/src/components/file-upload/examples/in-form.tsx +4 -9
  434. package/src/components/file-upload/examples/overview.tsx +5 -1
  435. package/src/components/file-upload/examples/row-parts.tsx +24 -1
  436. package/src/components/file-upload/examples/screen.module.css +45 -0
  437. package/src/components/file-upload/examples/screen.tsx +646 -0
  438. package/src/components/file-upload/examples/states.tsx +6 -2
  439. package/src/components/file-upload/examples/validation.tsx +11 -2
  440. package/src/components/file-upload/examples/variants.tsx +3 -20
  441. package/src/components/gantt/COMPONENT.md +2 -1
  442. package/src/components/gantt/examples/screen.module.css +14 -0
  443. package/src/components/gantt/examples/screen.tsx +726 -0
  444. package/src/components/gantt/examples/states.tsx +6 -2
  445. package/src/components/input/COMPONENT.md +2 -2
  446. package/src/components/input/examples/examples.module.css +2 -13
  447. package/src/components/input/examples/in-form.tsx +1 -9
  448. package/src/components/input/examples/password-strength.tsx +34 -8
  449. package/src/components/input/examples/states.tsx +6 -1
  450. package/src/components/kanban/COMPONENT.md +16 -11
  451. package/src/components/kanban/examples/columns.tsx +8 -5
  452. package/src/components/kanban/examples/limits.tsx +2 -1
  453. package/src/components/kanban/examples/screen.module.css +17 -0
  454. package/src/components/kanban/examples/screen.tsx +572 -0
  455. package/src/components/kanban/examples/states.tsx +17 -6
  456. package/src/components/kanban/examples/variants.tsx +16 -8
  457. package/src/components/list/COMPONENT.md +1 -1
  458. package/src/components/login-form/COMPONENT.md +6 -5
  459. package/src/components/login-form/examples/examples.module.css +2 -21
  460. package/src/components/login-form/examples/forgot-password.tsx +28 -32
  461. package/src/components/login-form/examples/narrow.tsx +1 -1
  462. package/src/components/login-form/examples/overview.tsx +45 -47
  463. package/src/components/login-form/examples/register.tsx +64 -68
  464. package/src/components/login-form/examples/reset-password.tsx +50 -47
  465. package/src/components/login-form/examples/sizes.tsx +4 -6
  466. package/src/components/login-form/examples/states.tsx +53 -57
  467. package/src/components/login-form/examples/structure.tsx +18 -22
  468. package/src/components/login-form/examples/verification-code.tsx +41 -45
  469. package/src/components/media-viewer/COMPONENT.md +3 -3
  470. package/src/components/media-viewer/examples/dismiss.tsx +5 -1
  471. package/src/components/message/COMPONENT.md +6 -5
  472. package/src/components/message/examples/file.tsx +5 -1
  473. package/src/components/message/examples/media-open.tsx +48 -0
  474. package/src/components/message/examples/status.tsx +21 -3
  475. package/src/components/message/examples/text-formatting.tsx +7 -1
  476. package/src/components/modal/COMPONENT.md +2 -1
  477. package/src/components/modal/examples/custom-container.tsx +20 -20
  478. package/src/components/modal/examples/dismiss.tsx +5 -3
  479. package/src/components/modal/examples/enter-key.tsx +116 -0
  480. package/src/components/modal/examples/examples.module.css +7 -13
  481. package/src/components/modal/examples/structure.tsx +5 -2
  482. package/src/components/native-select/COMPONENT.md +1 -1
  483. package/src/components/native-select/examples/states.tsx +5 -1
  484. package/src/components/notification/COMPONENT.md +2 -1
  485. package/src/components/notification/examples/dismiss.tsx +2 -2
  486. package/src/components/page-content/COMPONENT.md +71 -14
  487. package/src/components/page-content/examples/grid.tsx +107 -0
  488. package/src/components/page-content/examples/list-detail.tsx +0 -3
  489. package/src/components/page-content/examples/overview.tsx +2 -2
  490. package/src/components/page-content/examples/screen.module.css +27 -0
  491. package/src/components/page-content/examples/screen.tsx +196 -0
  492. package/src/components/page-content/examples/sections.tsx +81 -0
  493. package/src/components/page-content/examples/variants.tsx +4 -11
  494. package/src/components/page-toolbar/COMPONENT.md +18 -16
  495. package/src/components/page-toolbar/examples/narrow.tsx +6 -3
  496. package/src/components/pagination/examples/controlled.tsx +29 -29
  497. package/src/components/pagination/examples/examples.module.css +0 -2
  498. package/src/components/progress-bar/COMPONENT.md +1 -1
  499. package/src/components/progress-bar/examples/segments.tsx +2 -2
  500. package/src/components/progress-circle/COMPONENT.md +1 -1
  501. package/src/components/progress-circle/examples/segments.tsx +8 -3
  502. package/src/components/radio/COMPONENT.md +1 -0
  503. package/src/components/radio/examples/examples.module.css +14 -0
  504. package/src/components/radio/examples/in-form.tsx +45 -0
  505. package/src/components/scroll-container/COMPONENT.md +1 -0
  506. package/src/components/scroll-container/examples/auto-scroll.tsx +3 -3
  507. package/src/components/scroll-container/examples/chat.tsx +3 -3
  508. package/src/components/scroll-container/examples/edges.tsx +6 -3
  509. package/src/components/scroll-container/examples/examples.module.css +4 -17
  510. package/src/components/scroll-container/examples/load-more.tsx +51 -0
  511. package/src/components/scroll-container/examples/lock.tsx +3 -5
  512. package/src/components/scroll-container/examples/overscroll.tsx +3 -3
  513. package/src/components/scroll-container/examples/overview.tsx +3 -3
  514. package/src/components/scroll-container/examples/scrollbar.tsx +13 -7
  515. package/src/components/scroll-container/examples/variants.tsx +13 -7
  516. package/src/components/segmented-control/COMPONENT.md +3 -2
  517. package/src/components/segmented-control/examples/in-form.tsx +5 -1
  518. package/src/components/segmented-control/examples/states.tsx +10 -1
  519. package/src/components/select/COMPONENT.md +5 -3
  520. package/src/components/select/examples/examples.module.css +2 -7
  521. package/src/components/select/examples/icon-only.tsx +38 -0
  522. package/src/components/select/examples/states.tsx +13 -1
  523. package/src/components/sheet/COMPONENT.md +2 -0
  524. package/src/components/sheet/examples/guard.tsx +72 -0
  525. package/src/components/sheet/examples/header-actions.tsx +56 -0
  526. package/src/components/slider/COMPONENT.md +2 -1
  527. package/src/components/slider/examples/examples.module.css +8 -0
  528. package/src/components/slider/examples/in-form.tsx +47 -0
  529. package/src/components/slider/examples/states.tsx +4 -1
  530. package/src/components/smart-filter/COMPONENT.md +1 -1
  531. package/src/components/smart-filter/examples/controlled.tsx +3 -3
  532. package/src/components/smart-filter/examples/ranges.tsx +44 -10
  533. package/src/components/sparkline/COMPONENT.md +83 -30
  534. package/src/components/sparkline/examples/compact.tsx +1 -1
  535. package/src/components/sparkline/examples/curve.tsx +28 -0
  536. package/src/components/sparkline/examples/gaps.tsx +33 -0
  537. package/src/components/sparkline/examples/overview.tsx +11 -2
  538. package/src/components/sparkline/examples/period.tsx +7 -2
  539. package/src/components/sparkline/examples/reference.tsx +38 -0
  540. package/src/components/sparkline/examples/variants.tsx +2 -2
  541. package/src/components/tabs/COMPONENT.md +1 -1
  542. package/src/components/tabs/examples/examples.module.css +0 -6
  543. package/src/components/tabs/examples/in-drawer.tsx +11 -13
  544. package/src/components/tabs/examples/sizes.tsx +1 -1
  545. package/src/components/tag-select/COMPONENT.md +1 -1
  546. package/src/components/tag-select/examples/states.tsx +8 -1
  547. package/src/components/textarea/COMPONENT.md +1 -1
  548. package/src/components/textarea/examples/examples.module.css +0 -6
  549. package/src/components/textarea/examples/in-form.tsx +1 -9
  550. package/src/components/textarea/examples/states.tsx +2 -1
  551. package/src/components/thumbnail/COMPONENT.md +2 -1
  552. package/src/components/thumbnail/examples/examples.module.css +1 -1
  553. package/src/components/thumbnail/examples/fit.tsx +24 -0
  554. package/src/components/thumbnail/examples/video.tsx +20 -1
  555. package/src/components/timeline/COMPONENT.md +1 -1
  556. package/src/components/timeline/examples/examples.module.css +0 -8
  557. package/src/components/timeline/examples/links.tsx +55 -14
  558. package/src/components/timeline/examples/narrow.tsx +2 -2
  559. package/src/components/timeline/examples/sizes.tsx +3 -3
  560. package/src/components/timeline/examples/variants.tsx +4 -4
  561. package/src/components/tooltip/COMPONENT.md +7 -5
  562. package/src/components/tooltip/examples/placement.tsx +2 -1
  563. package/src/components/tooltip/examples/toolbar.tsx +2 -2
  564. package/src/components/typography/examples/weights.tsx +3 -0
  565. package/src/components/video-note/COMPONENT.md +3 -3
  566. package/src/components/video-note/examples/controlled.tsx +19 -2
  567. package/src/components/video-note/examples/in-message.tsx +5 -2
  568. package/src/components/visually-hidden/COMPONENT.md +2 -1
  569. package/src/components/visually-hidden/examples/assertive.tsx +39 -0
  570. package/src/components/voice-player/COMPONENT.md +3 -3
  571. package/src/components/voice-player/examples/call-recording.tsx +19 -9
  572. package/src/components/voice-player/examples/controlled.tsx +20 -3
  573. package/src/layout/app-header/COMPONENT.md +46 -63
  574. package/src/layout/app-header/examples/breadcrumbs.tsx +10 -9
  575. package/src/layout/app-header/examples/examples.module.css +1 -1
  576. package/src/layout/app-header/examples/in-app-shell.tsx +2 -3
  577. package/src/layout/app-header/examples/narrow.tsx +4 -5
  578. package/src/layout/app-header/examples/overview.tsx +8 -10
  579. package/src/layout/app-header/examples/page-title.tsx +3 -10
  580. package/src/layout/app-shell/COMPONENT.md +5 -4
  581. package/src/layout/app-shell/examples/footer.tsx +2 -2
  582. package/src/layout/app-shell/examples/overview.tsx +17 -32
  583. package/src/layout/app-shell/examples/screen.module.css +11 -0
  584. package/src/layout/app-shell/examples/screen.tsx +262 -0
  585. package/src/layout/app-shell/examples/template.tsx +31 -11
  586. package/src/layout/bottom-nav/examples/floating-action.tsx +2 -2
  587. package/src/layout/bottom-nav/examples/floating.tsx +2 -2
  588. package/src/layout/bottom-nav/examples/in-app-shell.tsx +2 -2
  589. package/src/layout/sidebar/COMPONENT.md +7 -4
  590. package/src/layout/sidebar/examples/account.tsx +2 -2
  591. package/src/layout/sidebar/examples/collapsible-groups.tsx +12 -4
  592. package/src/layout/sidebar/examples/custom-part.tsx +53 -0
  593. package/src/layout/sidebar/examples/examples.module.css +5 -0
  594. package/src/layout/sidebar/examples/narrow.tsx +53 -0
  595. package/src/layout/sidebar/examples/persist.tsx +57 -0
  596. package/src/layout/sidebar/examples/router.tsx +14 -2
  597. package/src/layout/sidebar/examples/structure.tsx +7 -2
  598. package/src/styles/theme-light.css +1 -0
  599. package/dist/skill/patterns/app-shell.tsx +0 -301
  600. package/dist/skill/patterns/chat.module.css +0 -8
  601. package/dist/skill/patterns/dashboard.module.css +0 -44
  602. package/dist/skill/patterns/dashboard.tsx +0 -326
  603. package/dist/skill/patterns/detail-page.tsx +0 -209
  604. package/dist/skill/patterns/form-drawer.tsx +0 -240
  605. package/dist/skill/patterns/kanban-board.module.css +0 -28
  606. package/dist/skill/patterns/media-library.tsx +0 -638
  607. package/dist/skill/patterns/schedule.module.css +0 -22
  608. package/dist/skill/patterns/screen-states.tsx +0 -186
  609. /package/dist/skill/{patterns/form-drawer.module.css → reference/components/drawer/examples/screen.module.css} +0 -0
@@ -2,62 +2,110 @@
2
2
 
3
3
  A screen made from the kit looks finished when every block sits on the same few rules: one skeleton,
4
4
  one rhythm, one size, one primary action, fill instead of lines, and a state for every region. This
5
- file is those rules; [patterns/](patterns/) are the same rules as working screens.
6
-
7
- ## Patterns
8
-
9
- **Start from a pattern.** Each one is a complete page (React + one CSS module on tokens), copyable as
10
- is, and is shown live with its code in the playground (category «Композиция»):
11
-
12
- | Screen | Pattern | Shows |
13
- |---|---|---|
14
- | List / registry | [list-page.tsx](patterns/list-page.tsx) | header with one primary action, SmartFilter in the DataTable toolbar, statuses, row menu, pages, filtered empty state |
15
- | One record | [detail-page.tsx](patterns/detail-page.tsx) | Breadcrumb + status in the header, actions by weight, main column + side column of Cards, Timeline |
16
- | Settings | [settings-page.tsx](patterns/settings-page.tsx) | heading column + panel per section, form with its own save, Switches that apply at once, danger zone with a confirm |
17
- | Create in a side panel | [form-drawer.tsx](patterns/form-drawer.tsx) | Drawer form: groups, errors on submit, focus on the first invalid field, loading, toast |
18
- | Dashboard | [dashboard.tsx](patterns/dashboard.tsx) | period switch, KPI row that cross-fades to the new period, a Sparkline revenue trend, invoiced vs paid in a ChartFrame, panels with progress and a split, short table + link to the list |
19
- | Screen states | [screen-states.tsx](patterns/screen-states.tsx) | page error in a Banner with retry, region loading with a Skeleton, Crossfade between states, table error in place, first-run EmptyPage |
20
- | Messenger | [chat.tsx](patterns/chat.tsx) | PageContent.Split of a `ChatList` (live last message, ticks, unread counts, «печатает…») and a `Chat`: `Chat.Header` with the back button, avatar, title, the status that turns into «печатает…» (`typing`) and the search button, `Chat.Search`, `Chat.Pinned`, `Chat.Messages` from `items` + a stable `renderMessage` (dates, runs, the unread band and service events from the data, history loaded above with `hasOlder` / `onLoadOlder`), every kind of Message (photos, file, contact, voice in a VoicePlayer with a transcript, round video), reactions, reply and edit from the menu through `Composer.Context value` (`replyTo` / `editOf`), the jump to the quoted message (`Message.Reply target`), optimistic sends whose messages rise from the composer while the client's answer slides in, «печатает…» both ways (`onActivityChange` → `Chat.Root typing`), unread counts from `onNewMessage` and `onRead`, selection with `Chat.SelectionBar`, delivery ticks, the Composer in `Chat.Footer` |
21
- | Sales pipeline board | [kanban-board.tsx](patterns/kanban-board.tsx) | header with one primary action, PageToolbar with SmartFilter search and a board / list SegmentedControl, Crossfade between a Kanban and a DataTable of the same deals, column totals in `renderColumnMeta`, moves saved through an `onValueChange` promise that the server can refuse, movable stages with locked first and last, the deal in a Drawer with a DescriptionList and stage actions, skeleton first load |
22
- | App frame for desktop and phone (root layout) | [app-shell.tsx](patterns/app-shell.tsx) | Sidebar rail on a wide screen, floating BottomNav in `AppShell.Footer` on a phone («Ещё» opens the Sidebar panel), AppHeader with the menu button, title and search to CommandMenu, counts on items, a home page that cross-fades between sections |
23
- | Media library | [media-library.tsx](patterns/media-library.tsx) | PageToolbar with sections and counts, search (`SmartFilter` with `fields={[]}`), order and «Загрузить»; uploads through `useUploadQueue` in `FileUpload` tiles (`trigger="tile"`, `layout="grid"`) with progress, a failure and retry, a done file moving into the library; a grid of `Thumbnail` / `Thumbnail.Video` tiles that open `MediaViewer` out of the tile (`getOrigin`, `thumbnails`, `renderActions`) or, in selection mode, are picked (`checked`) for bulk download and a `ConfirmDialog` delete; a Skeleton first load and a filtered `EmptyPage` in a `Crossfade` |
24
- | Resource schedule | [schedule.tsx](patterns/schedule.tsx) | full-height `Gantt` (`scrollHeight="fill"`) under a `PageToolbar` with search, role / client filters and team sections; people with avatars, client hues, lanes for overlaps, locked absences and milestones; moves saved through an async `onBarChange` or refused and glided back, new work drawn with `onBarCreate` and named in a Modal (cancel fades the ghost), `onSelect` details in a Drawer with a `DescriptionList` and a confirmed removal, `loading` and filtered `empty` |
5
+ file is those rules; the [screens](#screens) are the same rules as working pages.
6
+
7
+ ## Screens
8
+
9
+ **Start from a screen.** Each one is a complete page (React + one CSS module on tokens), copyable as
10
+ is: the `screen.tsx` example of the component it is built around (`examples/screen.tsx` next to
11
+ `examples/screen.module.css`), shown live with its code as the «Экран» example on that component's
12
+ playground page. What each screen teaches is in [Screen rules](#screen-rules) at the end.
13
+
14
+ | Screen | Main component | File | Shows |
15
+ |---|---|---|---|
16
+ | [List page](#list-page) | data-table | [screen.tsx](reference/components/data-table/examples/screen.tsx) | the title, a line of figures, SmartFilter search and filters, export and one primary action in the AppHeader; statuses, row menu, pages, filtered empty state |
17
+ | [Detail page](#detail-page) | description-list | [screen.tsx](reference/components/description-list/examples/screen.tsx) | a nested record: Breadcrumb, the title with status and due date and the record's actions by weight in the AppHeader; main column + side column of Cards, Timeline |
18
+ | [Settings page](#settings-page) | page-content | [screen.tsx](reference/components/page-content/examples/screen.tsx) | heading column + panel per section, form with its own save, Switches that apply at once, danger zone with a confirm |
19
+ | [Form in a Drawer](#form-in-a-drawer) | drawer | [screen.tsx](reference/components/drawer/examples/screen.tsx) | the title, counts, search and the Drawer trigger in the AppHeader; Drawer form: groups, errors on submit, focus on the first invalid field, loading, toast |
20
+ | [Record editor](#record-editor) | field-list | [screen.tsx](reference/components/field-list/examples/screen.tsx) | a document page (a long form): the title, a line of description and «Сохранить тариф» in `PageContent.Header`; a plan card edited in aside sections: name and description, specs in a `FieldList` (icon-only `Select` and `ColorPresets` in compact columns, pinned rows, reorder), the price and its changes by month in one list with the base row pinned, a setup fee in three currencies in one row under one heading, save with «Сохранено» on the button |
21
+ | [Dashboard](#dashboard) | card | [screen.tsx](reference/components/card/examples/screen.tsx) | title + a line of data in `AppHeader`, period switch and report in its `PageToolbar`; KPI row that cross-fades to the new period, a Sparkline revenue trend, invoiced vs paid in a ChartFrame, panels with progress and a split, short table + link to the list |
22
+ | [Screen states](#screen-states) | crossfade | [screen.tsx](reference/components/crossfade/examples/screen.tsx) | title + the statement date in `AppHeader`, page error in a Banner with retry, region loading with a Skeleton, Crossfade between states, table error in place, first-run EmptyPage |
23
+ | [Messenger](#messenger) | chat | [screen.tsx](reference/components/chat/examples/screen.tsx) | title + the unread count in `AppHeader`; a full-height PageContent.Split of a `ChatList` with its search (live last message, ticks, unread counts, «печатает…») and a `Chat`: `Chat.Header` with the back button, avatar, title, the status that turns into «печатает…» (`typing`) and the search button, `Chat.Search`, `Chat.Messages` from `items` + a stable `renderMessage` (dates, runs and the unread band from the data, history loaded above with `hasOlder` / `onLoadOlder`, a first load in skeletons), text, a photo, a file and sent voice, reply and edit from the menu through `Composer.Context value` (`replyTo` / `editOf`), the jump to the quoted message (`Message.Reply target`), optimistic sends whose messages rise from the composer while the client's answer slides in, «печатает…» both ways (`onActivityChange` → `Chat.Root typing`), unread counts from `onNewMessage` and `onRead`, the Composer with attachments in `Chat.Footer` |
24
+ | [Sales pipeline board](#sales-pipeline-board) | kanban | [screen.tsx](reference/components/kanban/examples/screen.tsx) | AppHeader titles the page (`h1` + a Description with the open deals and their sum) and carries a PageToolbar with SmartFilter search, a board / list SegmentedControl and the one primary action; Crossfade between a `plain` Kanban (stages without wells, deal cards on the page) and a DataTable of the same deals, column totals in `renderColumnMeta`, moves saved through an `onValueChange` promise that the server can refuse, the deal in a Drawer with a DescriptionList and stage actions, skeleton first load |
25
+ | [App frame](#app-frame) | app-shell | [screen.tsx](reference/layout/app-shell/examples/screen.tsx) | Sidebar rail on a wide screen, floating BottomNav in `AppShell.Footer` on a phone («Ещё» opens the Sidebar panel), AppHeader with the menu button and the page title (`h1`) with a line of data, counts on items, a home page that cross-fades between sections |
26
+ | [Media library](#media-library) | file-upload | [screen.tsx](reference/components/file-upload/examples/screen.tsx) | AppHeader titles the page (`h1` + a Description with the object) and carries a PageToolbar with sections and counts, search (`SmartFilter` with `fields={[]}`), order and «Загрузить»; uploads through `useUploadQueue` in `FileUpload` tiles (`trigger="tile"`, `layout="grid"`) with progress, a failure and retry, a done file moving into the library; a grid of `Thumbnail` / `Thumbnail.Video` tiles that open `MediaViewer` out of the tile (`getOrigin`, `thumbnails`, `renderActions`) or, in selection mode, are picked (`checked`) for bulk download and a `ConfirmDialog` delete; a Skeleton first load and a filtered `EmptyPage` in a `Crossfade` |
27
+ | [Resource schedule](#resource-schedule) | gantt | [screen.tsx](reference/components/gantt/examples/screen.tsx) | AppHeader titles the page (`h1` + a Description with the people shown) and carries a `PageToolbar` with search, role / client filters, team sections and «Назначить» over a full-height `Gantt` (`scrollHeight="fill"`); people with avatars, client hues, lanes for overlaps, locked absences and milestones; moves saved through an async `onBarChange` or refused and glided back, new work drawn with `onBarCreate` and named in a Modal (cancel fades the ghost), `onSelect` details in a Drawer with a `DescriptionList` and a confirmed removal, `loading` and filtered `empty` |
25
28
 
26
29
  Pick the closest one, rename the domain, keep the skeleton. Change structure only when the task needs
27
30
  it, and then by the rules below.
28
31
 
29
32
  ## 1. Page skeleton
30
33
 
34
+ **One title per page, and it lives in the page's header.** Every app page titles itself in the
35
+ app header: `AppHeader.Title` is the page's only `<h1>`, an `AppHeader.Description` under it
36
+ is one line that carries data («Среда, 14 октября · 3 задачи», «Отправлен · оплатить до 14 октября»),
37
+ and a nested record puts the path up (`Breadcrumb` + `AppHeader.Separator`) before it. The header row
38
+ belongs to the page: it holds only what the current page needs — its title, its own buttons in
39
+ `AppHeader.Actions`, and its tools as a `PageToolbar.Root` in `AppHeader.Tools` (the page's own
40
+ search and filters, sections, the view, the primary action). Main has no `PageContent.Header`.
41
+
42
+ **A document page** — settings, a long form, an article or help text — is the one exception: its big
43
+ title is `PageContent.Header` in main (`PageContent.Title` is the `<h1>`, one sentence of
44
+ `PageContent.Description`, the page's save action in `PageContent.Actions`), and the header carries
45
+ no title. Never two titles; never no `<h1>`.
46
+
31
47
  ```
32
48
  AppShell.Root once per app (layouts.md#app-frame-once-per-app)
33
49
  ├─ AppShell.Nav → Sidebar navigation rail, one layer above the page
34
- ├─ AppHeader.Root menu button / title or path / ⌘K search / app actions
35
- └─ AppShell.Main gutters; the page renders here
36
- └─ PageContent.Section | Root the page you deliver
37
- ├─ PageContent.Header
38
- │ ├─ Breadcrumb only below a top-level section; first child → 8 above the title
39
- │ ├─ PageContent.Title the one h1
40
- │ ├─ PageContent.Description one sentence of context (or a status Badge + the key fact)
41
- │ └─ PageContent.Actions page buttons; wrap under the title on narrow screens
42
- └─ PageContent.Body blocks 40 apart: Banner, KPI grid, table, sections, Cards
50
+ ├─ AppHeader.Root the page's header: only what this page needs
51
+ │ ├─ AppHeader.Start
52
+ │ │ ├─ AppHeader.MenuButton opens the Sidebar below 768px
53
+ │ │ ├─ Breadcrumb + Separator only on a nested record: the path up
54
+ │ │ └─ AppHeader.Title the one h1 + AppHeader.Description: a line of data
55
+ │ ├─ AppHeader.Actions the page's own buttons (export, a more menu)
56
+ │ └─ AppHeader.Tools second row → PageToolbar.Root: search and filter, sections,
57
+ │ view, the primary action; Chips under them
58
+ └─ AppShell.Main gutters + top air (24, 32 from 1024px); the page renders here
59
+ └─ PageContent.Page | Root the page you deliver
60
+ └─ PageContent.Body blocks 24 apart, starting at main's top air
61
+ ├─ PageContent.Grid every tile of the screen, 16 on both axes
62
+ │ └─ PageContent.Cell span (of 12), rows; the tile fills it
63
+ └─ PageContent.Section a new topic: h2 label (+ Actions), 40 from its neighbours
64
+
65
+ Document page: the header without a title, and in main
66
+ └─ PageContent.Root maxWidth="wide" | "readable"
67
+ ├─ PageContent.Header the one h1, a sentence of description, the page's save action; 24 above the body
68
+ └─ PageContent.Body
43
69
  ```
44
70
 
45
- - A screen component renders only its page. Styles, `applyTheme`, `NotificationProvider` and
46
- `AppShell` live at the app root.
47
- - `PageContent.Section` for app pages (full panel width); `PageContent.Root maxWidth="wide"` for
71
+ - A screen component renders its page: its `AppHeader.Root` (through the shell's `header`) and its
72
+ body. Styles, `applyTheme`, `NotificationProvider` and `AppShell` live at the app root.
73
+ - `PageContent.Page` for app pages (full panel width); `PageContent.Root maxWidth="wide"` for
48
74
  settings, `maxWidth="readable"` for one narrow column of text or fields.
49
- - No outer padding, no margins: `AppShell.Main` has the gutters, `PageContent` has header → body 32 and
50
- block → block 40. Your CSS lays out only the inside of a block.
75
+ - No outer padding, no margins: `AppShell.Main` has the gutters and the top air under the header,
76
+ `PageContent` has block → block 24, section → section 40, tile → tile 16 (and header → body 24 on
77
+ a document page). Your CSS lays out only the inside of a block.
51
78
 
52
79
  ```tsx
53
- import { Button, Dropdown, Icon, PageContent } from "prime-ui-kit";
54
-
55
- export function OrdersHeader() {
80
+ import {
81
+ AppHeader,
82
+ Button,
83
+ Dropdown,
84
+ Icon,
85
+ PageToolbar,
86
+ SmartFilter,
87
+ type SmartFilterField,
88
+ type SmartFilterValue,
89
+ } from "prime-ui-kit";
90
+
91
+ type OrdersHeaderProps = {
92
+ fields: SmartFilterField[];
93
+ filter: SmartFilterValue;
94
+ onFilterChange: (value: SmartFilterValue) => void;
95
+ search: string;
96
+ onSearchChange: (search: string) => void;
97
+ };
98
+
99
+ export function OrdersHeader({ fields, filter, onFilterChange, search, onSearchChange }: OrdersHeaderProps) {
56
100
  return (
57
- <PageContent.Header>
58
- <PageContent.Title>Заказы</PageContent.Title>
59
- <PageContent.Description>Все заказы магазина за выбранный период.</PageContent.Description>
60
- <PageContent.Actions>
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.Actions>
61
109
  <Dropdown.Root>
62
110
  <Dropdown.Trigger>
63
111
  <Button.Root variant="soft" tone="neutral" aria-label="Другие действия">
@@ -71,12 +119,34 @@ export function OrdersHeader() {
71
119
  <Dropdown.Item>Импорт из CSV</Dropdown.Item>
72
120
  </Dropdown.Content>
73
121
  </Dropdown.Root>
74
- <Button.Root variant="soft" tone="neutral">
75
- Экспорт
76
- </Button.Root>
77
- <Button.Root>Создать заказ</Button.Root>
78
- </PageContent.Actions>
79
- </PageContent.Header>
122
+ </AppHeader.Actions>
123
+ <AppHeader.Tools>
124
+ <SmartFilter.Root
125
+ fields={fields}
126
+ value={filter}
127
+ onValueChange={onFilterChange}
128
+ search={search}
129
+ onSearchChange={onSearchChange}
130
+ >
131
+ <PageToolbar.Root aria-label="Заказы">
132
+ <PageToolbar.Tools>
133
+ <SmartFilter.Toolbar />
134
+ </PageToolbar.Tools>
135
+ <PageToolbar.Actions>
136
+ <Button.Root>
137
+ <Button.Icon>
138
+ <Icon name="action.add" />
139
+ </Button.Icon>
140
+ Создать заказ
141
+ </Button.Root>
142
+ </PageToolbar.Actions>
143
+ <PageToolbar.Chips>
144
+ <SmartFilter.Chips />
145
+ </PageToolbar.Chips>
146
+ </PageToolbar.Root>
147
+ </SmartFilter.Root>
148
+ </AppHeader.Tools>
149
+ </AppHeader.Root>
80
150
  );
81
151
  }
82
152
  ```
@@ -90,16 +160,20 @@ Every gap is a `--prime-space-N` token (N × 4px) set as `gap` on the parent. Cl
90
160
  | label → field, field → hint | 4–8 | built into fields — never add |
91
161
  | buttons, chips, filters in a row | 8 | `--prime-space-2` |
92
162
  | text lines of one item (name over meta) | 0–4 | `--prime-space-1` |
93
- | heading → its content (group, section without a card) | 16 | `--prime-space-4` |
94
- | tile → tile in a grid (KPI, panels) | 16 | `--prime-space-4` |
163
+ | heading → its content (group, section) | 16 | `--prime-space-4` (`PageContent.Section` does it) |
164
+ | tile → tile, both axes (KPI, charts, panels) | 16 | `PageContent.Grid` |
95
165
  | field → field, switch → switch | 20 | `--prime-space-5` |
96
166
  | main column → side column | 24 | `--prime-space-6` |
167
+ | app header → the page's first block | 12 + 24, 12 + 32 from 1024px | the header's bottom air + `AppShell.Main` top air |
168
+ | page header → body (a document page) | 24 | `PageContent.Header` |
169
+ | block → block on a page | 24 | `PageContent.Body` |
97
170
  | group → group in a form | 32 | `--prime-space-8` |
98
- | page header → body | 32 | `PageContent` |
99
- | block → block on a page | 40 | `PageContent.Body` |
171
+ | section → section (a new topic with an `h2`) | 40 | `PageContent.Section` |
100
172
 
101
173
  A screen with one gap everywhere reads as a list of unrelated things. Use at least three levels: inside
102
- an item, between items, between blocks.
174
+ an item, between items, between blocks. The tiles of one screen are one board: put them all in one
175
+ `PageContent.Grid` (one gap on both axes), never a grid per row — and keep the large air for a new topic
176
+ with its own heading (`PageContent.Section`).
103
177
 
104
178
  ## 3. Hierarchy — air first, then type
105
179
 
@@ -107,8 +181,8 @@ Hierarchy comes from space and a handful of type roles, not from size jumps, col
107
181
 
108
182
  | Text | Use |
109
183
  |---|---|
110
- | page title | `PageContent.Title` (`heading-m`, the only `h1`) |
111
- | section heading without a card | `Typography as="h2" variant="title-m"` |
184
+ | page title | `AppHeader.Title` (the only `h1`); on a document page `PageContent.Title` (`heading-m`) instead |
185
+ | section heading without a card | `PageContent.Section label` (an `h2` in `title-m`) |
112
186
  | card / panel title | `Card.Title as="h2"` (under the page title) |
113
187
  | heading of a group of fields | `Fieldset label` (`title-s` in the `<legend>`) |
114
188
  | other group heading inside a card | `Typography as="h3" variant="title-s"` |
@@ -145,12 +219,12 @@ Hierarchy comes from space and a handful of type roles, not from size jumps, col
145
219
 
146
220
  ## 6. Actions
147
221
 
148
- - **One primary per area** (page header, card, dialog, form): `solid`, last in its row. Secondary:
222
+ - **One primary per area** (the page, card, dialog, form): `solid`, last in its row. Secondary:
149
223
  `soft` + `tone="neutral"`. Dismiss / revert: `ghost` + `neutral` in pages and cards, `outline` +
150
224
  `neutral` in Modal / Drawer footers. Rare actions: a `Dropdown` behind an `action.more` icon button —
151
225
  `soft` + `neutral` in a header row (it has a shape beside the other buttons), `ghost` size `s` in a
152
226
  table cell.
153
- - Placement: page actions in `PageContent.Actions`; card actions in `Card.Footer`; dialog actions in
227
+ - Placement: the page's primary action in `PageToolbar.Actions` in `AppHeader.Tools`, its other buttons in `AppHeader.Actions` (a document page: `PageContent.Actions`); card actions in `Card.Footer`; dialog actions in
154
228
  `Modal.Footer` / `Drawer.Footer`; row actions in the last column; bulk actions in the table toolbar.
155
229
  - An empty state's action replaces the header's primary, it does not duplicate it.
156
230
  - Destructive: `tone="danger"`; a standalone trigger is `outline`, in a menu it is the last item, the
@@ -162,6 +236,12 @@ Hierarchy comes from space and a handful of type roles, not from size jumps, col
162
236
 
163
237
  - Labels above every field (`label`), placeholder is an example value, help in `hint`, problems in
164
238
  `error` — after blur or on submit. Mark the minority (`required` or `optional`).
239
+ - Records of one shape that a person adds, edits and removes are a `FieldList`: one row per record,
240
+ the column headings once above the rows, small attributes (an icon, a color) in `compact`
241
+ columns. Never a label in every row, never numbered labels, never one record split over lines.
242
+ - One value in several units is one row of fields under one heading, each unit in its field's
243
+ `Input.InlineAffix`; a base value with overrides is one `FieldList` with the base pinned first.
244
+ The shape of the data decides the layout: [ux.md](ux.md#2-the-shape-of-the-data-decides-the-layout).
165
245
  - Fields 20 apart; related short fields side by side in an `auto-fit` grid with `align-items: start`
166
246
  (`reserveSupportRow` on Input / Textarea keeps neighbours aligned); groups 32 apart, each a
167
247
  `Fieldset label` (its `title-s` heading 16 above the fields, no frame); no dividers between groups.
@@ -241,11 +321,11 @@ turns them off itself; a form in a Modal or Drawer holds closing with `Modal.Gua
241
321
  - Layouts are intrinsic: `repeat(auto-fit, minmax(min(100%, …), 1fr))` grids and flex-wrap with a large
242
322
  `flex-grow` on the main column — no breakpoints needed, and they work in any container. Media queries
243
323
  only for app-frame decisions (the phone menu header) at 640 · 768 · 1024 · 1280.
244
- - From 320px: header actions wrap under the title (built in), side columns drop below the main one,
324
+ - From 320px: the page's tools wrap under the header title and the primary action takes its own row when the search would be squeezed (built in), side columns drop below the main one,
245
325
  pairs of fields stack, tables scroll inside themselves, dialogs stack their footers (built in).
246
326
  - A page with search and filter, sections, a view switch and the primary action gets `PageToolbar`:
247
- search and filter first with the active filters right under them, one row when wide, stacked rows
248
- 12 apart when narrow, the primary action always top right.
327
+ search and filter first with the active filters under the top row, one row when wide, stacked rows
328
+ 12 apart when narrow; the primary action at the top row's end, on its own row on a phone.
249
329
  - Rearrange, never hide: every function of the desktop screen is on the phone — in another place or a
250
330
  menu. App sections on phones: `BottomNav` in `AppShell.Footer`; a short task from the bottom
251
331
  edge: `Sheet`.
@@ -315,6 +395,166 @@ export function RevenuePanel() {
315
395
  }
316
396
  ```
317
397
 
318
- For a plain KPI row use `Card.Root variant="stat-trend"` (Label · Value · Delta) in an `auto-fit` grid —
319
- see [patterns/dashboard.tsx](patterns/dashboard.tsx). When the trend over days matters, put a
398
+ For a plain KPI row use `Card.Root variant="stat-trend"` (Label · Value · Delta), each in a
399
+ `PageContent.Cell span={3}` of the page's `PageContent.Grid` — see [the dashboard screen](reference/components/card/examples/screen.tsx). When the trend over days matters, put a
320
400
  `Sparkline` in the `Card.Body` instead: it brings the value, the change and a line to scrub.
401
+
402
+ ## Screen rules
403
+
404
+ What each screen in [the index](#screens) demonstrates — keep these when you start from it.
405
+
406
+ ### List page
407
+
408
+ [data-table/examples/screen.tsx](reference/components/data-table/examples/screen.tsx)
409
+
410
+ - The page lives in the `AppHeader`: `AppHeader.Title` is the only heading, its `AppHeader.Description` is one line of figures («10 счетов · просрочено 2 на …»), not a sentence about the page; main has no `PageContent.Header`.
411
+ - The tools are `AppHeader.Tools` → `SmartFilter.Root` around a `PageToolbar.Root`: `SmartFilter.Toolbar` in `PageToolbar.Tools`, `SmartFilter.Chips` in `PageToolbar.Chips`, export (an icon-only `soft` + `neutral` button) and the one primary action (`solid`, last) in `PageToolbar.Actions`. The table itself has no `toolbar`.
412
+ - A status is a `Badge` with one color per meaning across the product (`STATUS` is one map); the text carries the meaning, the color repeats it.
413
+ - Numbers and dates are `numeric` columns with `headerAlign="end"` (tabular figures, values and heading on the end edge). On a phone the table scrolls inside itself and `stickyFirstColumn` keeps the number in place — the page never scrolls sideways.
414
+ - Row actions are a `Dropdown` behind an `action.more` icon of size `s`: controls in cells are one tier below the table. Delete is `tone="danger"` at the end of the menu.
415
+ - Empty after a filter is the table's `empty` with `EmptyPage size="s"` and a «Сбросить фильтры» action; the header and the filters stay in place.
416
+
417
+ ### Detail page
418
+
419
+ [description-list/examples/screen.tsx](reference/components/description-list/examples/screen.tsx)
420
+
421
+ - A nested record titles itself in the `AppHeader`: `AppHeader.Start` holds the path up (`Breadcrumb` with the list, «Счета»), an `AppHeader.Separator` and `AppHeader.Title` with the record's name; main has no `PageContent.Header`. Top-level pages have no breadcrumb.
422
+ - The status is words next to the fact that matters now, in `AppHeader.Description` («Отправлен · оплатить до 14 октября»), not a separate plate.
423
+ - The record's actions are the header's tools row: `AppHeader.Tools` → `PageToolbar.Root` → `PageToolbar.Actions`, by weight: one primary (`solid`, last), the secondary `soft` + `tone="neutral"`, rare and destructive ones in a `Dropdown` behind an `action.more` icon (also `soft`, so the button has a shape beside its neighbours); voiding is `tone="danger"` at the bottom of the menu.
424
+ - Columns are a CSS module on flex-wrap without breakpoints: the main one grows, the side one holds ~18rem and drops below when the main one runs out of room.
425
+ - A section without a frame is `PageContent.Section label`: an h2 heading 16 px above the table; `Card variant="panel"` only for standalone blocks of the side column. A table is already a filled block — never put it in a card.
426
+ - «Label → value» pairs about the client are `DescriptionList.Root orientation="vertical"` with `DescriptionList.Item label`; amounts are tabular figures, the total is larger (`title-m`) and ends where the «Сумма» column ends (the table cell inset).
427
+ - History is a `Timeline`: events top-down from the latest, dates in `Timeline.Meta`; a row highlights on hover.
428
+
429
+ ### Settings page
430
+
431
+ [page-content/examples/screen.tsx](reference/components/page-content/examples/screen.tsx)
432
+
433
+ - A section is `PageContent.Section layout="aside"`: a heading column (`label` + a line of `description`) and a `Card variant="panel"` panel; sections are 40 px apart; on a narrow screen the column moves above the panel by itself (flex-wrap, no breakpoints).
434
+ - The form wraps the whole `Card.Root` in `<form noValidate>`; the buttons are in `Card.Footer`: «Отменить изменения» `ghost` + `neutral`, then the primary «Сохранить». While the request runs — `loading` on the button, and one `Fieldset disabled` turns the fields off; the form stays on screen, so success is the button text «Сохранено» for two seconds, without a notification.
435
+ - Fields are 20 px apart; two short related fields side by side while there is width, with `align-items: start` and `reserveSupportRow`, so an error does not shift the neighbour.
436
+ - An error comes through the field's `error` after submit, not while typing; a format hint goes in `hint`.
437
+ - A `Switch` applies at once — its section has no «Сохранить» button; the explanation is in the switch's own `hint`.
438
+ - The danger zone is the last section: an `outline` + `tone="danger"` button in `ConfirmDialog.Trigger`; `onConfirm` returns the delete Promise — the dialog holds `loading` itself, disables cancel and does not close while the request runs.
439
+
440
+ ### Form in a Drawer
441
+
442
+ [drawer/examples/screen.tsx](reference/components/drawer/examples/screen.tsx)
443
+
444
+ - The page lives in the `AppHeader`: `AppHeader.Title` with the counts in `AppHeader.Description`, the search (`SmartFilter` with `fields={[]}`) in `PageToolbar.Tools`; main has no `PageContent.Header`.
445
+ - The opening button is the page's primary action in `PageToolbar.Actions`; `Drawer.Trigger` wraps it as a slot.
446
+ - The form is tied to the footer button through `form={formId}`: `Drawer.Footer` is outside the `<form>`, and submitting still works, by Enter too.
447
+ - Groups are a `Fieldset` without a frame with a `title-s` heading 16 px above the fields; 32 px of air between groups, no dividers. `Fieldset disabled` turns all the fields off while the request runs.
448
+ - Validation on submit: errors in each field's `error`, focus on the first invalid field; mark the minority: required fields are the majority, so `optional` stands only on the optional ones.
449
+ - The client type is a `Radio.Group` with `label` (two visible options), the manager a `Select`, consent a `Checkbox` with `hint`: the value goes with the form, it does not apply at once.
450
+ - Footer: «Отмена» `outline` + `neutral`, the primary action last, in `loading` during the request; closing is held by `Drawer.Guard` (`busy` — while saving, neither Escape nor the close button closes; `dirty` — after an edit it asks whether to discard the changes).
451
+ - The result is a `Notification` and a new row in the table; the panel closes by itself.
452
+
453
+ ### Record editor
454
+
455
+ [field-list/examples/screen.tsx](reference/components/field-list/examples/screen.tsx)
456
+
457
+ - A record editor is a document page — a long form read top to bottom in aside sections, like Settings — so its title stays in content: `PageContent.Header` with the title, one line of description and the primary action; the app header only says where you are and holds no second title.
458
+ - The shape of the data decides the layout: records a person adds and removes are a `FieldList`, one row per record; the column headings stand once above the rows, and the fields in the cells take them as their labels.
459
+ - No label in every row and no numbered one («Преимущество 1»): a one-column list has no headings at all — its section names it ([reorder.tsx](reference/components/field-list/examples/reorder.tsx)).
460
+ - Small attributes of a record go in compact columns of its row: the icon is a `Select` with only `Select.TriggerIcon`, the color `ColorPresets`; the first specs are pinned (`getLocked`) — the lock says so itself, without explanatory text.
461
+ - The base price and its changes are one list: the base row is pinned first and shows when it applies, the changes are rows with a month and a price; the ruble sign is in the field (`Input.InlineAffix`), not in every heading.
462
+ - One value in three currencies is three fields in one row under one group heading, each with its own name for screen readers and the currency inside the field.
463
+ - The lists live in the page state, the name and description fields in the `<form>` of the first section; the primary «Сохранить тариф» in the header is tied to it through `form={formId}` and saves everything. While the request runs the fields and the lists are off (`Fieldset disabled`, `disabled`), afterwards «Сохранено» on the button.
464
+
465
+ ### Dashboard
466
+
467
+ [card/examples/screen.tsx](reference/components/card/examples/screen.tsx)
468
+
469
+ - The header carries the page: `AppHeader.Title` «Обзор» with an `AppHeader.Description` line of data (what and as of when), the page's tools in `AppHeader.Tools` as a `PageToolbar.Root`; main has no `PageContent.Header`, its body starts with the tiles.
470
+ - The period is a `SegmentedControl` in `PageToolbar.View`, the report a `soft` + `neutral` button in `PageToolbar.Actions`: the period changes the values on this same screen. Tabs (`Tabs`) are for different content, not for a period.
471
+ - Every tile of the screen is one `PageContent.Grid`: KPI `Card variant="stat-trend"` in `PageContent.Cell span={3}`, 16 px on both axes; `Card.Delta` with a `tone` by the meaning of the change: overdue growing is `danger`, its decline `success`.
472
+ - Another period — other values: each KPI tile is wrapped in `Crossfade state={period}` and flows instead of blinking.
473
+ - A trend over days is a `Sparkline` in a `Card` in a full-width cell: the last value, the change and a line you can scrub with a finger; a new series appears by itself.
474
+ - A chart with axes and several series is a `ChartFrame` in `PageContent.Cell span={8} rows={2}` beside two panels; `ChartFrame.Plot height="fill"` takes their height. A sized plot area (`renderPlot`), a legend that turns series off and a table for screen readers; series colors come from `series`, never your own.
475
+ - Panels are `Card variant="panel"` with `Card.Title as="h2"` in `Card.Header` and quiet context on the right after the title (`caption` + `muted`).
476
+ - Progress of one value is a `ProgressBar` with `label` and `showValue`; parts of a whole are `ProgressBar segments` with `legend` and `formatValue`: statuses are colored by `tone`, categories by `color`.
477
+ - Tiles of one screen are 16 px apart (`PageContent.Grid`), page blocks 24 px (`PageContent.Body`), a new topic with a heading 40 px (`PageContent.Section`): proximity shows what is related.
478
+ - A short list is a `DataTable paging="none"` in `PageContent.Section label` without a card; «Все счета» is a `LinkButton` in the section's `PageContent.Actions`: it is a way somewhere, not an action.
479
+
480
+ ### Screen states
481
+
482
+ [crossfade/examples/screen.tsx](reference/components/crossfade/examples/screen.tsx)
483
+
484
+ - The header carries the page: `AppHeader.Title` with an `AppHeader.Description` line of data — the accounts and the date of the statement the screen stands on; main has no `PageContent.Header`.
485
+ - An error that concerns the whole page is a `Banner tone="danger"` as the first block of `PageContent.Body` with a «Повторить» action; the action's result is a `Notification`.
486
+ - A region's error is in the region's place: `error` on the `DataTable` (the table head stays), not a pop-up.
487
+ - Table loading is `loading` + `loadingRows` (a skeleton of rows); card loading is a `Skeleton` in the shape of its rows and `aria-busy` on the card, and the block's height does not change. The state change is smooth: the card's region is in `Crossfade state={status}`, the table body changes by itself.
488
+ - Stale data beats emptiness: the balances are shown as of the previous date, and that is said on the right in `Card.Header`.
489
+ - Empty on the first run is `EmptyPage size="s"` inside the panel: an icon with `tone="accent"`, what it is and why, one action. An empty filter result is the table's `empty`.
490
+ - No home-made spinners, shimmers, grey placeholders or error modals: the kit already has a component for every state.
491
+
492
+ ### Messenger
493
+
494
+ [chat/examples/screen.tsx](reference/components/chat/examples/screen.tsx)
495
+
496
+ - A work screen: the title «Поддержка» is `AppHeader.Title` with the unread count in `AppHeader.Description`; main has no `PageContent.Header`.
497
+ - Layout: `PageContent.Split` in a `fill` page: the dialog list `ChatList` (last message, ticks, unread, «печатает…») and the conversation beside it; on a narrow panel one pane at a time with `PageContent.BackButton` in `Chat.Header`.
498
+ - Search over the dialogs is the field of `ChatList` itself: `search` and `onSearchChange`; you filter the list (by name and last message), and the list shows the match in rows, the number found and an empty result itself. Never put a field of your own above the list.
499
+ - The conversation is `Chat.Root` in the pane's card: the header, `Chat.Search`, `Chat.Messages` and `Chat.Footer` with the Composer. Never assemble your own header, `ScrollContainer` and feed — the chat links search, jumps, selection and «печатает…» itself.
500
+ - Messages are data: `items` with `getKey`, `getAuthor`, `getDate` (service events through `isService`), the first unread is `unread`; the feed computes dates, runs, tails and the avatar place. `renderMessage` in `useCallback`: only the changed message re-renders.
501
+ - History is `hasOlder` and `onLoadOlder` with a promise: while it runs, a bubble-shaped `Skeleton` placeholder stands on top, and the view does not jump.
502
+ - Each kind of message is its own part of `Message`: text with markup, photos and albums, a file, a `VoicePlayer`; the screen renders the kinds its domain has. The others (`VideoNote`, a location, a contact, a link preview, reactions, a forwarded header) are shown on the Message, VoicePlayer and VideoNote pages; pinned messages and selection on the Chat page.
503
+ - Sending is a `Composer` with `onSend` without waiting: the message is in the feed at once with a clock under a stable id, then one tick, then two. Your own message rises from the input, the client's answer slides in from the side — the feed animates new messages itself; history and status changes are not animated.
504
+ - Reply and edit from `Message.Menu` open `Composer.Context` with `value`: `onSend` gets `replyTo` / `editOf`, the plate closes itself after sending; ↑ in an empty field is `onEditLast`. A quote in a bubble is `Message.Reply target`: a scroll to the original with a flash.
505
+ - «Печатает…»: your own signal is `Composer onActivityChange` into the socket, the other side's is `Chat.Root typing`: the line in the header and the bubble at the end of the feed together.
506
+ - Unread: `onNewMessage` adds an incoming message to the dialog's count, `onRead` subtracts what the reader really saw. Scrolled up — the round «to the latest» button counts the new ones itself.
507
+ - Search in the conversation is `Chat.SearchButton` and `Chat.Search`; pinned messages, when the domain has them, are `Chat.Pinned` between them and the feed.
508
+
509
+ ### Sales pipeline board
510
+
511
+ [kanban/examples/screen.tsx](reference/components/kanban/examples/screen.tsx)
512
+
513
+ - The page titles itself in the app header: `AppHeader.Title` with an `AppHeader.Description` that carries data («7 сделок в работе · 6 461 750 ₽», counted over the filtered deals); main has no `PageContent.Header`.
514
+ - Search, filters, the view switch and the one primary action «Новая сделка» are one `PageToolbar` inside `SmartFilter.Root`, in `AppHeader.Tools`.
515
+ - The board and the list are the same data: `Kanban` and `DataTable` replace each other through `Crossfade`, the filter is `matchesSmartFilter`.
516
+ - The board is the main area of the page, so its `variant` is the default, `plain`: stages without wells, headers and deal cards stand right on the page — one level of nesting, no frames of your own around the columns.
517
+ - The placement of deals is `value` as `{ [stage]: id[] }`; `onValueChange` returns the request's promise and applies `value` only after the answer; a server refusal returns the card to its place.
518
+ - Stage totals are in `renderColumnMeta` («2 сделки · 3 575 000 ₽»), the stage color is the column's `color`.
519
+ - A deal opens through `onItemClick` of `Kanban.Root` (click, Enter, Space; never after a drag) in a `Drawer` with a `DescriptionList`; no `onClick` / `onKeyDown` of your own on the card; a deal with its own page — `getItemHref`. The stage change is available in the panel too — dragging is not the only way; `Drawer.Guard busy` holds the panel while saving.
520
+ - The first load is `loading` on `Kanban` and `DataTable`: skeletons in the geometry of cards and rows.
521
+
522
+ ### App frame
523
+
524
+ [app-shell/examples/screen.tsx](reference/layout/app-shell/examples/screen.tsx)
525
+
526
+ - The frame is `AppShell.Template` (or `AppShell.Root`): `nav` is `Sidebar.Root`, `header` is `AppHeader.Root`, `footer` is `BottomNav.Root`; the page is the children. `scrollResetKey` is the current section (in a router, the pathname), so a new page opens at the top.
527
+ - The kit decides the switch itself: below 768 px the `Sidebar` goes off the edge, `AppHeader.MenuButton` appears and `AppShell.Footer` shows the `BottomNav`; while the rail is on screen the footer is hidden. No media queries or `position: fixed` of your own.
528
+ - `BottomNav` holds 2–6 main sections, one word each; the rest lives in the `Sidebar`, and «Ещё» opens it as a panel (`aria-expanded`). `floating` is a glass capsule; `AppShell.Main` leaves room under it itself.
529
+ - Every page titles itself in the header: `AppHeader.Title` with the section's name and an `AppHeader.Description` that carries data («Среда, 14 октября · открытых задач: 3»); main has no `PageContent.Header`, its body starts with the page's blocks.
530
+ - Counts: `Sidebar.ItemCount` (a plain number for information, `color="red"` when it needs action) and `BottomNav.ItemCount` only for what needs attention; the number is the same in both navigations.
531
+ - Choosing a section in either navigation goes through one handler that also closes the Sidebar panel.
532
+ - A section change is a `Crossfade` by `state`: the page changes smoothly instead of jumping. Menu items in an app with a router are `asChild` + `NavLink`.
533
+
534
+ ### Media library
535
+
536
+ [file-upload/examples/screen.tsx](reference/components/file-upload/examples/screen.tsx)
537
+
538
+ - A work screen titles itself in the app header: `AppHeader.Title` «Медиатека» with an `AppHeader.Description` naming the object; main has no `PageContent.Header`.
539
+ - Sections, search, order and «Загрузить» are one `PageToolbar` panel in `AppHeader.Tools`: search is a `SmartFilter.Toolbar` with `fields={[]}`, sections a `SegmentedControl` with `SegmentedControl.Count`.
540
+ - Uploads are `useUploadQueue` + `FileUpload.Root trigger="tile" layout="grid"`: progress, «В очереди», the failure reason and retry are built in, the add tile is also the drop zone; «Загрузить» opens the same `inputRef`.
541
+ - A finished file leaves the queue for the library: its address is `item.result` of the server's answer, not the queue's `preview`.
542
+ - The library grid is a CSS grid of `Thumbnail` with `fullWidth` and one `ratio`; a video is `Thumbnail.Video`, which draws the duration and the play mark itself. `Gallery` does not fit here: it is an album of up to 10.
543
+ - A tile either opens or selects: when browsing it is `Thumbnail.Root asChild` with a button, when selecting — `checked` / `onCheckedChange`; «Выбрать» turns the mode on.
544
+ - Viewing is `MediaViewer` with `open` and `index` in two states and `getOrigin` by refs to the tiles, so a photo flies out of its tile and returns into it.
545
+ - Bulk delete is a `ConfirmDialog` with an `onConfirm` that returns a Promise; the result is a notification through `notify()`.
546
+ - The first load is a `Skeleton` in the geometry of the tiles, and a change of section, order or an empty result goes through `Crossfade`; an empty filter is `EmptyPage size="s"` with a reset.
547
+
548
+ ### Resource schedule
549
+
550
+ [gantt/examples/screen.tsx](reference/components/gantt/examples/screen.tsx)
551
+
552
+ - The page titles itself in the app header: `AppHeader.Title` with an `AppHeader.Description` that carries data («Сотрудников: 9 из 9»); main has no `PageContent.Header`.
553
+ - A `fill` page: `Gantt scrollHeight="fill"` takes the free height — the header and the first column stick inside the chart, the page never scrolls sideways.
554
+ - The panel is a `PageToolbar` inside `SmartFilter.Root`, in `AppHeader.Tools`: search and the role and client filter first, teams a `SegmentedControl` with counts in `PageToolbar.Sections`, the primary action «Назначить» in `PageToolbar.Actions`, the active filters `SmartFilter.Chips` right under the search. Zoom and «Сегодня» are built into `Gantt` — never add your own.
555
+ - A row is a person: `renderRowAvatar` with an `Avatar`, `renderRow` with the name and role; on a narrow chart the column keeps only the avatar. Overlapping works lay themselves out in lanes, an absence is a `readOnly` bar, a milestone has `start` equal to `end`.
556
+ - `onBarChange` returns a promise and changes the data only after the service answers: while it runs the bar is busy; a refusal (work on an absence) is `notify` and `throw`, and the bar returns to its previous dates by itself.
557
+ - `onBarCreate`: a range drawn on an empty place holds a busy draft while a `Modal` with `Modal.Guard busy` asks for the name and the client; saving adds the bar and resolves the promise, cancel rejects it — the draft dissolves. Work over an absence is refused at once.
558
+ - The legend of client hues is a row of `Badge.Root color` with `Badge.Dot` in the chart's `toolbar`; `renderBarTooltip` names the client in the tooltip under the dates, so the client reads not only by color.
559
+ - `onSelect` opens a `Drawer` with a `DescriptionList` (the person, the client `Badge`, the period and duration, `ProgressBar`); removing a task is a `ConfirmDialog` with an async `onConfirm`.
560
+ - States are on the chart itself: `loading` draws `Skeleton` placeholder rows in its geometry, `empty` an `EmptyPage size="s"` with «Сбросить фильтры»; the panel stays in place.
@@ -35,11 +35,13 @@ 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
- | card → card in a grid | 16 | `--prime-space-4` |
39
- | section → section on a page | 40 | `--prime-space-10` — `PageContent.Body` already does it |
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 |
40
41
 
41
- `PageContent.Body` already spaces its direct blocks (cards, tables, sections) 40 apart and `AppShell.Main`
42
- already carries the page gutters — do not add your own outer padding.
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
44
+ gutters — do not add your own outer padding.
43
45
 
44
46
  ## 3. Size axis
45
47
 
@@ -132,10 +134,10 @@ A chart color does one job, and the job picks the colors:
132
134
  | `body-m` | 14/20 | default text |
133
135
  | `body-l` | 16/24 | reading text |
134
136
  | `title-s` | 14/20 600 | card title, group heading inside a card or form |
135
- | `title-m` | 16/24 600 | page section heading without a card, modal title |
137
+ | `title-m` | 16/24 600 | page section heading (`PageContent.Section` draws it), modal title |
136
138
  | `title-l` | 18/24 600 | large block title |
137
139
  | `heading-s` | 20/28 600 | page sub-heading |
138
- | `heading-m` | 24/32 600 | page title (`PageContent.Title`) |
140
+ | `heading-m` | 24/32 600 | the title of a document page (`PageContent.Title`); an app page titles itself in `AppHeader.Title` (`title-s`) |
139
141
  | `heading-l` | 30/36 600 | marketing / auth title |
140
142
  | `display-*` | 36–60 | hero numbers only |
141
143
  | `code` | 13/20 mono | identifiers, inline code |
@@ -163,7 +165,7 @@ level of air: a page with uniform 16px gaps everywhere reads as a list of unrela
163
165
  - Flex children with text: `min-width: 0` + ellipsis or `overflow-wrap: anywhere`.
164
166
  - Wide tables on phones: they scroll inside themselves with edge shadows; `stickyFirstColumn`, a column
165
167
  chooser through `hiddenColumns`; never let the page scroll sideways.
166
- - Card grids: `grid-template-columns: repeat(auto-fill, minmax(min(100%, calc(var(--prime-space-16) * 4)), 1fr))`.
168
+ - Card grids on a page: `PageContent.Grid` + `PageContent.Cell span` (folds by its own width); inside one block: `repeat(auto-fill, minmax(min(100%, …), 1fr))`.
167
169
  - A page panel with sections, filter and search, view and the primary action is `PageToolbar`.
168
170
  - Sticky parts come from the kit: `AppHeader` (with the `PageToolbar` in `AppHeader.Tools`), the
169
171
  DataTable head and `stickyFirstColumn`, the Gantt header and first column — each sticks inside its