prime-ui-kit 0.16.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (477) hide show
  1. package/README.md +15 -18
  2. package/dist/chunks/{chunk-A7OQWH6R.js → chunk-IVS3J7AS.js} +1 -1
  3. package/dist/chunks/{chunk-6TPHKCUJ.js → chunk-MB4CXSLL.js} +27732 -26723
  4. package/dist/chunks/{chunk-4PSQ64S4.js → chunk-OAXJWF3L.js} +6818 -6264
  5. package/dist/chunks/{chunk-U3Q2I3MY.js → chunk-QFHE5GKW.js} +3 -2
  6. package/dist/chunks/{chunk-HDBQICPW.js → chunk-X3JT5CLR.js} +60 -20
  7. package/dist/color-picker.d.ts +1 -1
  8. package/dist/color-picker.js +3 -3
  9. package/dist/components/badge/Badge.d.ts +17 -0
  10. package/dist/components/breadcrumb/Breadcrumb.d.ts +12 -3
  11. package/dist/components/button/Button.d.ts +1 -1
  12. package/dist/components/button-group/ButtonGroup.d.ts +1 -1
  13. package/dist/components/card/Card.d.ts +8 -4
  14. package/dist/components/chart-frame/ChartFrame.d.ts +1 -1
  15. package/dist/components/chat/Chat.d.ts +3 -3
  16. package/dist/components/chat/ChatRows.d.ts +5 -1
  17. package/dist/components/chat/MessageList.d.ts +5 -1
  18. package/dist/components/chat/groupMessages.d.ts +12 -4
  19. package/dist/components/chat-list/ChatList.d.ts +18 -9
  20. package/dist/components/chat-list/formatChatTime.d.ts +3 -3
  21. package/dist/components/checkbox/Checkbox.d.ts +6 -1
  22. package/dist/components/color-field/ColorField.d.ts +1 -1
  23. package/dist/components/color-picker/ColorPicker.d.ts +23 -1
  24. package/dist/components/color-picker/ColorPresets.d.ts +9 -1
  25. package/dist/components/crossfade/Crossfade.d.ts +1 -1
  26. package/dist/components/data-table/DataTable.d.ts +3 -1
  27. package/dist/components/data-table/Head.d.ts +3 -1
  28. package/dist/components/data-table/types.d.ts +5 -0
  29. package/dist/components/digit-input/DigitInput.d.ts +1 -1
  30. package/dist/components/drawer/Drawer.d.ts +3 -2
  31. package/dist/components/field-list/FieldList.d.ts +18 -6
  32. package/dist/components/hint/Hint.d.ts +8 -2
  33. package/dist/components/index.d.ts +6 -7
  34. package/dist/components/input/Input.d.ts +27 -5
  35. package/dist/components/input/inputSuggestions.d.ts +39 -0
  36. package/dist/components/kanban/Kanban.d.ts +4 -9
  37. package/dist/components/list/List.d.ts +19 -5
  38. package/dist/components/message/Message.d.ts +15 -3
  39. package/dist/components/message/MessageSticker.d.ts +27 -0
  40. package/dist/components/message/formatMessageTime.d.ts +5 -2
  41. package/dist/components/modal/Modal.d.ts +3 -2
  42. package/dist/components/native-select/NativeSelect.d.ts +1 -1
  43. package/dist/components/pagination/Pagination.d.ts +5 -1
  44. package/dist/components/popover/Popover.d.ts +1 -1
  45. package/dist/components/radio/Radio.d.ts +11 -2
  46. package/dist/components/rich-text/RichText.d.ts +23 -0
  47. package/dist/components/scroll-container/ScrollContainer.d.ts +1 -1
  48. package/dist/components/scroll-container/scrollGlide.d.ts +26 -0
  49. package/dist/components/scroll-container/useScrollMotion.d.ts +25 -0
  50. package/dist/components/segmented-control/SegmentedControl.d.ts +1 -1
  51. package/dist/components/select/selectContext.d.ts +7 -0
  52. package/dist/components/slider/Slider.d.ts +2 -2
  53. package/dist/components/smart-filter/SmartFilter.d.ts +4 -5
  54. package/dist/components/switch/Switch.d.ts +6 -1
  55. package/dist/components/tag-select/TagSelect.d.ts +1 -1
  56. package/dist/components/textarea/Textarea.d.ts +6 -1
  57. package/dist/components/timeline/Timeline.d.ts +1 -1
  58. package/dist/icon-set.js +2 -2
  59. package/dist/index.css +1 -1
  60. package/dist/index.js +7 -9
  61. package/dist/internal/ChoiceField.d.ts +3 -1
  62. package/dist/internal/FieldFrame.d.ts +8 -2
  63. package/dist/internal/barPlan.d.ts +44 -0
  64. package/dist/internal/fieldCell.d.ts +1 -1
  65. package/dist/internal/formatClock.d.ts +23 -2
  66. package/dist/internal/leaveGuard.d.ts +21 -0
  67. package/dist/internal/messageList.d.ts +2 -0
  68. package/dist/internal/overlay/DialogParts.d.ts +27 -2
  69. package/dist/internal/overlay/FloatingPanel.d.ts +1 -1
  70. package/dist/internal/overlay/focus.d.ts +3 -2
  71. package/dist/internal/parts.d.ts +1 -1
  72. package/dist/internal/slot.d.ts +0 -30
  73. package/dist/internal/swatch.d.ts +5 -0
  74. package/dist/internal/tokenDefaults.d.ts +1 -0
  75. package/dist/layout/app-shell/AppShell.d.ts +19 -38
  76. package/dist/layout/index.d.ts +3 -3
  77. package/dist/layout/page/Page.d.ts +302 -0
  78. package/dist/layout/sidebar/Sidebar.d.ts +1 -1
  79. package/dist/skill/SKILL.md +10 -10
  80. package/dist/skill/anti-slop.md +106 -5
  81. package/dist/skill/api-contract.md +15 -8
  82. package/dist/skill/cheatsheet.md +46 -26
  83. package/dist/skill/checklist.md +12 -3
  84. package/dist/skill/choosing.md +34 -20
  85. package/dist/skill/components.md +4 -5
  86. package/dist/skill/composition.md +193 -154
  87. package/dist/skill/foundations.md +9 -9
  88. package/dist/skill/layouts.md +42 -99
  89. package/dist/skill/reference/components/avatar/COMPONENT.md +2 -2
  90. package/dist/skill/reference/components/avatar/examples/team-group.tsx +1 -1
  91. package/dist/skill/reference/components/badge/COMPONENT.md +14 -1
  92. package/dist/skill/reference/components/badge/examples/examples.module.css +7 -0
  93. package/dist/skill/reference/components/badge/examples/tag-row.tsx +34 -0
  94. package/dist/skill/reference/components/banner/COMPONENT.md +4 -4
  95. package/dist/skill/reference/components/banner/examples/examples.module.css +6 -1
  96. package/dist/skill/reference/components/banner/examples/page-strip.tsx +24 -22
  97. package/dist/skill/reference/components/breadcrumb/COMPONENT.md +18 -12
  98. package/dist/skill/reference/components/breadcrumb/examples/router.tsx +17 -0
  99. package/dist/skill/reference/components/button/COMPONENT.md +2 -1
  100. package/dist/skill/reference/components/button/examples/hold-to-confirm.tsx +1 -1
  101. package/dist/skill/reference/components/button/examples/on-colored-host.tsx +8 -8
  102. package/dist/skill/reference/components/button-group/COMPONENT.md +1 -0
  103. package/dist/skill/reference/components/card/COMPONENT.md +14 -8
  104. package/dist/skill/reference/components/card/examples/screen.module.css +1 -1
  105. package/dist/skill/reference/components/card/examples/screen.tsx +184 -198
  106. package/dist/skill/reference/components/card/examples/states.tsx +59 -0
  107. package/dist/skill/reference/components/chart-frame/COMPONENT.md +1 -1
  108. package/dist/skill/reference/components/chart-frame/examples/fill-height.tsx +9 -9
  109. package/dist/skill/reference/components/chat/COMPONENT.md +8 -5
  110. package/dist/skill/reference/components/chat/examples/screen.module.css +1 -1
  111. package/dist/skill/reference/components/chat/examples/screen.tsx +110 -117
  112. package/dist/skill/reference/components/chat/examples/time-zone.tsx +83 -0
  113. package/dist/skill/reference/components/chat-list/COMPONENT.md +14 -8
  114. package/dist/skill/reference/components/chat-list/examples/controlled.tsx +2 -2
  115. package/dist/skill/reference/components/chat-list/examples/examples.module.css +8 -0
  116. package/dist/skill/reference/components/chat-list/examples/links.tsx +1 -1
  117. package/dist/skill/reference/components/chat-list/examples/router.tsx +63 -0
  118. package/dist/skill/reference/components/checkbox/COMPONENT.md +1 -0
  119. package/dist/skill/reference/components/checkbox/examples/examples.module.css +3 -2
  120. package/dist/skill/reference/components/code-block/COMPONENT.md +1 -1
  121. package/dist/skill/reference/components/code-block/examples/color-scheme.tsx +2 -4
  122. package/dist/skill/reference/components/code-block/examples/examples.module.css +0 -11
  123. package/dist/skill/reference/components/color-field/COMPONENT.md +2 -1
  124. package/dist/skill/reference/components/color-picker/COMPONENT.md +31 -11
  125. package/dist/skill/reference/components/color-picker/examples/examples.module.css +2 -5
  126. package/dist/skill/reference/components/color-picker/examples/overview.tsx +5 -10
  127. package/dist/skill/reference/components/color-picker/examples/presets-custom.tsx +31 -0
  128. package/dist/skill/reference/components/color-picker/examples/sizes.tsx +4 -8
  129. package/dist/skill/reference/components/color-swatches/COMPONENT.md +1 -0
  130. package/dist/skill/reference/components/crossfade/COMPONENT.md +3 -3
  131. package/dist/skill/reference/components/crossfade/examples/screen.tsx +107 -112
  132. package/dist/skill/reference/components/data-table/COMPONENT.md +12 -7
  133. package/dist/skill/reference/components/data-table/examples/examples.module.css +9 -0
  134. package/dist/skill/reference/components/data-table/examples/numeric.tsx +9 -2
  135. package/dist/skill/reference/components/data-table/examples/screen.tsx +42 -52
  136. package/dist/skill/reference/components/data-table/examples/server.tsx +6 -2
  137. package/dist/skill/reference/components/datepicker/COMPONENT.md +3 -1
  138. package/dist/skill/reference/components/datepicker/examples/deadline.tsx +33 -0
  139. package/dist/skill/reference/components/datepicker/examples/examples.module.css +6 -0
  140. package/dist/skill/reference/components/datepicker/examples/inline-panel.tsx +3 -1
  141. package/dist/skill/reference/components/description-list/COMPONENT.md +1 -1
  142. package/dist/skill/reference/components/description-list/examples/screen.tsx +120 -127
  143. package/dist/skill/reference/components/digit-input/COMPONENT.md +1 -0
  144. package/dist/skill/reference/components/digit-input/examples/grouped.tsx +4 -4
  145. package/dist/skill/reference/components/digit-input/examples/validation.tsx +1 -1
  146. package/dist/skill/reference/components/divider/COMPONENT.md +2 -2
  147. package/dist/skill/reference/components/divider/examples/examples.module.css +4 -1
  148. package/dist/skill/reference/components/divider/examples/vertical.tsx +22 -9
  149. package/dist/skill/reference/components/dnd/examples/examples.module.css +3 -1
  150. package/dist/skill/reference/components/drawer/COMPONENT.md +16 -3
  151. package/dist/skill/reference/components/drawer/examples/client-card.tsx +32 -8
  152. package/dist/skill/reference/components/drawer/examples/placement.tsx +26 -31
  153. package/dist/skill/reference/components/drawer/examples/screen.tsx +137 -160
  154. package/dist/skill/reference/components/dropdown/COMPONENT.md +1 -1
  155. package/dist/skill/reference/components/example-frame/COMPONENT.md +3 -3
  156. package/dist/skill/reference/components/field-list/COMPONENT.md +15 -3
  157. package/dist/skill/reference/components/field-list/examples/saving.tsx +83 -0
  158. package/dist/skill/reference/components/field-list/examples/screen.module.css +1 -1
  159. package/dist/skill/reference/components/field-list/examples/screen.tsx +19 -19
  160. package/dist/skill/reference/components/field-list/examples/totals.tsx +82 -0
  161. package/dist/skill/reference/components/fieldset/COMPONENT.md +1 -1
  162. package/dist/skill/reference/components/fieldset/examples/states.tsx +1 -1
  163. package/dist/skill/reference/components/file-upload/COMPONENT.md +2 -1
  164. package/dist/skill/reference/components/file-upload/examples/screen.module.css +2 -2
  165. package/dist/skill/reference/components/file-upload/examples/screen.tsx +65 -81
  166. package/dist/skill/reference/components/gallery/COMPONENT.md +1 -0
  167. package/dist/skill/reference/components/gantt/COMPONENT.md +1 -1
  168. package/dist/skill/reference/components/gantt/examples/screen.module.css +1 -1
  169. package/dist/skill/reference/components/gantt/examples/screen.tsx +55 -73
  170. package/dist/skill/reference/components/hint/COMPONENT.md +16 -2
  171. package/dist/skill/reference/components/hint/examples/examples.module.css +10 -1
  172. package/dist/skill/reference/components/hint/examples/overview.tsx +1 -1
  173. package/dist/skill/reference/components/hint/examples/variants.tsx +48 -0
  174. package/dist/skill/reference/components/input/COMPONENT.md +39 -9
  175. package/dist/skill/reference/components/input/examples/affixes.tsx +4 -2
  176. package/dist/skill/reference/components/input/examples/dismiss.tsx +29 -0
  177. package/dist/skill/reference/components/input/examples/suggestions.tsx +26 -0
  178. package/dist/skill/reference/components/input/examples/time.tsx +24 -0
  179. package/dist/skill/reference/components/input/examples/with-select.tsx +44 -0
  180. package/dist/skill/reference/components/kanban/COMPONENT.md +7 -7
  181. package/dist/skill/reference/components/kanban/examples/columns.tsx +4 -2
  182. package/dist/skill/reference/components/kanban/examples/screen.module.css +1 -1
  183. package/dist/skill/reference/components/kanban/examples/screen.tsx +50 -65
  184. package/dist/skill/reference/components/kbd/COMPONENT.md +1 -1
  185. package/dist/skill/reference/components/label/examples/examples.module.css +12 -1
  186. package/dist/skill/reference/components/label/examples/overview.tsx +1 -1
  187. package/dist/skill/reference/components/list/COMPONENT.md +26 -10
  188. package/dist/skill/reference/components/list/examples/row-controls.tsx +80 -0
  189. package/dist/skill/reference/components/list/examples/with-icon.tsx +23 -2
  190. package/dist/skill/reference/components/login-form/COMPONENT.md +8 -7
  191. package/dist/skill/reference/components/login-form/examples/states.tsx +12 -14
  192. package/dist/skill/reference/components/media-viewer/examples/controlled.tsx +16 -16
  193. package/dist/skill/reference/components/media-viewer/examples/examples.module.css +1 -3
  194. package/dist/skill/reference/components/message/COMPONENT.md +30 -9
  195. package/dist/skill/reference/components/message/examples/preview.tsx +28 -0
  196. package/dist/skill/reference/components/message/examples/sticker.tsx +35 -0
  197. package/dist/skill/reference/components/modal/COMPONENT.md +15 -3
  198. package/dist/skill/reference/components/modal/examples/long-content.tsx +37 -18
  199. package/dist/skill/reference/components/native-select/COMPONENT.md +1 -0
  200. package/dist/skill/reference/components/notification/COMPONENT.md +1 -1
  201. package/dist/skill/reference/components/pagination/COMPONENT.md +11 -3
  202. package/dist/skill/reference/components/pagination/examples/controlled.tsx +2 -1
  203. package/dist/skill/reference/components/popover/COMPONENT.md +3 -2
  204. package/dist/skill/reference/components/popover/examples/width.tsx +13 -1
  205. package/dist/skill/reference/components/radio/COMPONENT.md +2 -0
  206. package/dist/skill/reference/components/rich-text/COMPONENT.md +93 -0
  207. package/dist/skill/reference/components/rich-text/examples/overview.tsx +19 -0
  208. package/dist/skill/reference/components/scroll-container/COMPONENT.md +8 -5
  209. package/dist/skill/reference/components/segmented-control/COMPONENT.md +1 -0
  210. package/dist/skill/reference/components/segmented-control/examples/in-form.tsx +1 -1
  211. package/dist/skill/reference/components/select/COMPONENT.md +7 -3
  212. package/dist/skill/reference/components/slider/COMPONENT.md +4 -3
  213. package/dist/skill/reference/components/slider/examples/controlled.tsx +1 -1
  214. package/dist/skill/reference/components/slider/examples/states.tsx +14 -10
  215. package/dist/skill/reference/components/smart-filter/COMPONENT.md +13 -13
  216. package/dist/skill/reference/components/smart-filter/examples/examples.module.css +3 -0
  217. package/dist/skill/reference/components/smart-filter/examples/many-values.tsx +12 -8
  218. package/dist/skill/reference/components/smart-filter/examples/sizes.tsx +7 -3
  219. package/dist/skill/reference/components/sparkline/COMPONENT.md +1 -0
  220. package/dist/skill/reference/components/sparkline/examples/curve.tsx +16 -11
  221. package/dist/skill/reference/components/sparkline/examples/states.tsx +14 -10
  222. package/dist/skill/reference/components/switch/COMPONENT.md +2 -1
  223. package/dist/skill/reference/components/tabs/COMPONENT.md +1 -1
  224. package/dist/skill/reference/components/tag-select/COMPONENT.md +1 -0
  225. package/dist/skill/reference/components/textarea/COMPONENT.md +1 -0
  226. package/dist/skill/reference/components/timeline/COMPONENT.md +3 -3
  227. package/dist/skill/reference/components/timeline/examples/structure.tsx +2 -1
  228. package/dist/skill/reference/components/typography/COMPONENT.md +2 -2
  229. package/dist/skill/reference/foundation.md +15 -11
  230. package/dist/skill/reference/layout/app-shell/COMPONENT.md +25 -38
  231. package/dist/skill/reference/layout/app-shell/examples/footer.tsx +10 -10
  232. package/dist/skill/reference/layout/app-shell/examples/overview.tsx +20 -22
  233. package/dist/skill/reference/layout/app-shell/examples/screen.module.css +2 -2
  234. package/dist/skill/reference/layout/app-shell/examples/screen.tsx +25 -30
  235. package/dist/skill/reference/layout/app-shell/examples/template.tsx +13 -17
  236. package/dist/skill/reference/layout/bottom-nav/COMPONENT.md +4 -3
  237. package/dist/skill/reference/layout/bottom-nav/examples/floating-action.tsx +10 -19
  238. package/dist/skill/reference/layout/bottom-nav/examples/floating.tsx +10 -19
  239. package/dist/skill/reference/layout/bottom-nav/examples/in-app-shell.tsx +11 -19
  240. package/dist/skill/reference/layout/page/COMPONENT.md +382 -0
  241. package/dist/skill/reference/layout/page/examples/actions-collapse.tsx +45 -0
  242. package/dist/skill/reference/layout/page/examples/collapse.tsx +68 -0
  243. package/dist/skill/reference/layout/page/examples/examples.module.css +92 -0
  244. package/{src/components/page-content → dist/skill/reference/layout/page}/examples/grid.tsx +15 -15
  245. package/dist/skill/reference/layout/page/examples/guard.tsx +87 -0
  246. package/dist/skill/reference/{components/page-content → layout/page}/examples/list-detail.tsx +14 -14
  247. package/dist/skill/reference/layout/page/examples/loading.tsx +57 -0
  248. package/dist/skill/reference/layout/page/examples/narrow.tsx +75 -0
  249. package/dist/skill/reference/layout/page/examples/overview.tsx +57 -0
  250. package/dist/skill/reference/{components/page-content → layout/page}/examples/screen.module.css +1 -1
  251. package/{src/components/page-content → dist/skill/reference/layout/page}/examples/screen.tsx +29 -19
  252. package/dist/skill/reference/{components/page-content → layout/page}/examples/sections.tsx +17 -24
  253. package/dist/skill/reference/layout/page/examples/structure.tsx +41 -0
  254. package/dist/skill/reference/{components/page-toolbar/examples/narrow.tsx → layout/page/examples/tools.tsx} +38 -35
  255. package/dist/skill/reference/layout/page/examples/top-bar.tsx +85 -0
  256. package/dist/skill/reference/{components/page-content → layout/page}/examples/variants.tsx +7 -7
  257. package/dist/skill/reference/layout/sidebar/COMPONENT.md +6 -4
  258. package/dist/skill/reference/layout/sidebar/examples/dismiss.tsx +10 -7
  259. package/dist/skill/reference/layout/sidebar/examples/narrow.tsx +11 -8
  260. package/dist/skill/responsive.md +94 -75
  261. package/dist/skill/ux.md +5 -3
  262. package/dist/tokens/layers.d.ts +2 -0
  263. package/dist/tokens/primitives.d.ts +12 -2
  264. package/dist/tokens/semantic.d.ts +9 -0
  265. package/dist/tokens/themes/dark.d.ts +7 -2
  266. package/package.json +2 -2
  267. package/src/components/avatar/COMPONENT.md +2 -2
  268. package/src/components/avatar/examples/team-group.tsx +1 -1
  269. package/src/components/badge/COMPONENT.md +14 -1
  270. package/src/components/badge/examples/examples.module.css +7 -0
  271. package/src/components/badge/examples/tag-row.tsx +34 -0
  272. package/src/components/banner/COMPONENT.md +4 -4
  273. package/src/components/banner/examples/examples.module.css +6 -1
  274. package/src/components/banner/examples/page-strip.tsx +24 -22
  275. package/src/components/breadcrumb/COMPONENT.md +18 -12
  276. package/src/components/breadcrumb/examples/router.tsx +17 -0
  277. package/src/components/button/COMPONENT.md +2 -1
  278. package/src/components/button/examples/hold-to-confirm.tsx +1 -1
  279. package/src/components/button/examples/on-colored-host.tsx +8 -8
  280. package/src/components/button-group/COMPONENT.md +1 -0
  281. package/src/components/card/COMPONENT.md +14 -8
  282. package/src/components/card/examples/screen.module.css +1 -1
  283. package/src/components/card/examples/screen.tsx +184 -198
  284. package/src/components/card/examples/states.tsx +59 -0
  285. package/src/components/chart-frame/COMPONENT.md +1 -1
  286. package/src/components/chart-frame/examples/fill-height.tsx +9 -9
  287. package/src/components/chat/COMPONENT.md +8 -5
  288. package/src/components/chat/examples/screen.module.css +1 -1
  289. package/src/components/chat/examples/screen.tsx +110 -117
  290. package/src/components/chat/examples/time-zone.tsx +83 -0
  291. package/src/components/chat-list/COMPONENT.md +14 -8
  292. package/src/components/chat-list/examples/controlled.tsx +2 -2
  293. package/src/components/chat-list/examples/examples.module.css +8 -0
  294. package/src/components/chat-list/examples/links.tsx +1 -1
  295. package/src/components/chat-list/examples/router.tsx +63 -0
  296. package/src/components/checkbox/COMPONENT.md +1 -0
  297. package/src/components/checkbox/examples/examples.module.css +3 -2
  298. package/src/components/code-block/COMPONENT.md +1 -1
  299. package/src/components/code-block/examples/color-scheme.tsx +2 -4
  300. package/src/components/code-block/examples/examples.module.css +0 -11
  301. package/src/components/color-field/COMPONENT.md +2 -1
  302. package/src/components/color-picker/COMPONENT.md +31 -11
  303. package/src/components/color-picker/examples/examples.module.css +2 -5
  304. package/src/components/color-picker/examples/overview.tsx +5 -10
  305. package/src/components/color-picker/examples/presets-custom.tsx +31 -0
  306. package/src/components/color-picker/examples/sizes.tsx +4 -8
  307. package/src/components/color-swatches/COMPONENT.md +1 -0
  308. package/src/components/crossfade/COMPONENT.md +3 -3
  309. package/src/components/crossfade/examples/screen.tsx +107 -112
  310. package/src/components/data-table/COMPONENT.md +12 -7
  311. package/src/components/data-table/examples/examples.module.css +9 -0
  312. package/src/components/data-table/examples/numeric.tsx +9 -2
  313. package/src/components/data-table/examples/screen.tsx +42 -52
  314. package/src/components/data-table/examples/server.tsx +6 -2
  315. package/src/components/datepicker/COMPONENT.md +3 -1
  316. package/src/components/datepicker/examples/deadline.tsx +33 -0
  317. package/src/components/datepicker/examples/examples.module.css +6 -0
  318. package/src/components/datepicker/examples/inline-panel.tsx +3 -1
  319. package/src/components/description-list/COMPONENT.md +1 -1
  320. package/src/components/description-list/examples/screen.tsx +120 -127
  321. package/src/components/digit-input/COMPONENT.md +1 -0
  322. package/src/components/digit-input/examples/grouped.tsx +4 -4
  323. package/src/components/digit-input/examples/validation.tsx +1 -1
  324. package/src/components/divider/COMPONENT.md +2 -2
  325. package/src/components/divider/examples/examples.module.css +4 -1
  326. package/src/components/divider/examples/vertical.tsx +22 -9
  327. package/src/components/dnd/examples/examples.module.css +3 -1
  328. package/src/components/drawer/COMPONENT.md +16 -3
  329. package/src/components/drawer/examples/client-card.tsx +32 -8
  330. package/src/components/drawer/examples/placement.tsx +26 -31
  331. package/src/components/drawer/examples/screen.tsx +137 -160
  332. package/src/components/dropdown/COMPONENT.md +1 -1
  333. package/src/components/example-frame/COMPONENT.md +3 -3
  334. package/src/components/field-list/COMPONENT.md +15 -3
  335. package/src/components/field-list/examples/saving.tsx +83 -0
  336. package/src/components/field-list/examples/screen.module.css +1 -1
  337. package/src/components/field-list/examples/screen.tsx +19 -19
  338. package/src/components/field-list/examples/totals.tsx +82 -0
  339. package/src/components/fieldset/COMPONENT.md +1 -1
  340. package/src/components/fieldset/examples/states.tsx +1 -1
  341. package/src/components/file-upload/COMPONENT.md +2 -1
  342. package/src/components/file-upload/examples/screen.module.css +2 -2
  343. package/src/components/file-upload/examples/screen.tsx +65 -81
  344. package/src/components/gallery/COMPONENT.md +1 -0
  345. package/src/components/gantt/COMPONENT.md +1 -1
  346. package/src/components/gantt/examples/screen.module.css +1 -1
  347. package/src/components/gantt/examples/screen.tsx +55 -73
  348. package/src/components/hint/COMPONENT.md +16 -2
  349. package/src/components/hint/examples/examples.module.css +10 -1
  350. package/src/components/hint/examples/overview.tsx +1 -1
  351. package/src/components/hint/examples/variants.tsx +48 -0
  352. package/src/components/input/COMPONENT.md +39 -9
  353. package/src/components/input/examples/affixes.tsx +4 -2
  354. package/src/components/input/examples/dismiss.tsx +29 -0
  355. package/src/components/input/examples/suggestions.tsx +26 -0
  356. package/src/components/input/examples/time.tsx +24 -0
  357. package/src/components/input/examples/with-select.tsx +44 -0
  358. package/src/components/kanban/COMPONENT.md +7 -7
  359. package/src/components/kanban/examples/columns.tsx +4 -2
  360. package/src/components/kanban/examples/screen.module.css +1 -1
  361. package/src/components/kanban/examples/screen.tsx +50 -65
  362. package/src/components/kbd/COMPONENT.md +1 -1
  363. package/src/components/label/examples/examples.module.css +12 -1
  364. package/src/components/label/examples/overview.tsx +1 -1
  365. package/src/components/list/COMPONENT.md +26 -10
  366. package/src/components/list/examples/row-controls.tsx +80 -0
  367. package/src/components/list/examples/with-icon.tsx +23 -2
  368. package/src/components/login-form/COMPONENT.md +8 -7
  369. package/src/components/login-form/examples/states.tsx +12 -14
  370. package/src/components/media-viewer/examples/controlled.tsx +16 -16
  371. package/src/components/media-viewer/examples/examples.module.css +1 -3
  372. package/src/components/message/COMPONENT.md +30 -9
  373. package/src/components/message/examples/preview.tsx +28 -0
  374. package/src/components/message/examples/sticker.tsx +35 -0
  375. package/src/components/modal/COMPONENT.md +15 -3
  376. package/src/components/modal/examples/long-content.tsx +37 -18
  377. package/src/components/native-select/COMPONENT.md +1 -0
  378. package/src/components/notification/COMPONENT.md +1 -1
  379. package/src/components/pagination/COMPONENT.md +11 -3
  380. package/src/components/pagination/examples/controlled.tsx +2 -1
  381. package/src/components/popover/COMPONENT.md +3 -2
  382. package/src/components/popover/examples/width.tsx +13 -1
  383. package/src/components/radio/COMPONENT.md +2 -0
  384. package/src/components/rich-text/COMPONENT.md +93 -0
  385. package/src/components/rich-text/examples/overview.tsx +19 -0
  386. package/src/components/scroll-container/COMPONENT.md +8 -5
  387. package/src/components/segmented-control/COMPONENT.md +1 -0
  388. package/src/components/segmented-control/examples/in-form.tsx +1 -1
  389. package/src/components/select/COMPONENT.md +7 -3
  390. package/src/components/slider/COMPONENT.md +4 -3
  391. package/src/components/slider/examples/controlled.tsx +1 -1
  392. package/src/components/slider/examples/states.tsx +14 -10
  393. package/src/components/smart-filter/COMPONENT.md +13 -13
  394. package/src/components/smart-filter/examples/examples.module.css +3 -0
  395. package/src/components/smart-filter/examples/many-values.tsx +12 -8
  396. package/src/components/smart-filter/examples/sizes.tsx +7 -3
  397. package/src/components/sparkline/COMPONENT.md +1 -0
  398. package/src/components/sparkline/examples/curve.tsx +16 -11
  399. package/src/components/sparkline/examples/states.tsx +14 -10
  400. package/src/components/switch/COMPONENT.md +2 -1
  401. package/src/components/tabs/COMPONENT.md +1 -1
  402. package/src/components/tag-select/COMPONENT.md +1 -0
  403. package/src/components/textarea/COMPONENT.md +1 -0
  404. package/src/components/timeline/COMPONENT.md +3 -3
  405. package/src/components/timeline/examples/structure.tsx +2 -1
  406. package/src/components/typography/COMPONENT.md +2 -2
  407. package/src/layout/app-shell/COMPONENT.md +25 -38
  408. package/src/layout/app-shell/examples/footer.tsx +10 -10
  409. package/src/layout/app-shell/examples/overview.tsx +20 -22
  410. package/src/layout/app-shell/examples/screen.module.css +2 -2
  411. package/src/layout/app-shell/examples/screen.tsx +25 -30
  412. package/src/layout/app-shell/examples/template.tsx +13 -17
  413. package/src/layout/bottom-nav/COMPONENT.md +4 -3
  414. package/src/layout/bottom-nav/examples/floating-action.tsx +10 -19
  415. package/src/layout/bottom-nav/examples/floating.tsx +10 -19
  416. package/src/layout/bottom-nav/examples/in-app-shell.tsx +11 -19
  417. package/src/layout/page/COMPONENT.md +382 -0
  418. package/src/layout/page/examples/actions-collapse.tsx +45 -0
  419. package/src/layout/page/examples/collapse.tsx +68 -0
  420. package/src/layout/page/examples/examples.module.css +92 -0
  421. package/{dist/skill/reference/components/page-content → src/layout/page}/examples/grid.tsx +15 -15
  422. package/src/layout/page/examples/guard.tsx +87 -0
  423. package/src/{components/page-content → layout/page}/examples/list-detail.tsx +14 -14
  424. package/src/layout/page/examples/loading.tsx +57 -0
  425. package/src/layout/page/examples/narrow.tsx +75 -0
  426. package/src/layout/page/examples/overview.tsx +57 -0
  427. package/src/{components/page-content → layout/page}/examples/screen.module.css +1 -1
  428. package/{dist/skill/reference/components/page-content → src/layout/page}/examples/screen.tsx +29 -19
  429. package/src/{components/page-content → layout/page}/examples/sections.tsx +17 -24
  430. package/src/layout/page/examples/structure.tsx +41 -0
  431. package/src/{components/page-toolbar/examples/narrow.tsx → layout/page/examples/tools.tsx} +38 -35
  432. package/src/layout/page/examples/top-bar.tsx +85 -0
  433. package/src/{components/page-content → layout/page}/examples/variants.tsx +7 -7
  434. package/src/layout/sidebar/COMPONENT.md +6 -4
  435. package/src/layout/sidebar/examples/dismiss.tsx +10 -7
  436. package/src/layout/sidebar/examples/narrow.tsx +11 -8
  437. package/src/styles/theme-dark.css +12 -10
  438. package/src/styles/theme-light.css +4 -0
  439. package/src/styles/tokens.css +3 -1
  440. package/dist/components/page-content/PageContent.d.ts +0 -192
  441. package/dist/components/page-toolbar/PageToolbar.d.ts +0 -55
  442. package/dist/components/scroll-container/useWheelToInline.d.ts +0 -10
  443. package/dist/layout/app-header/AppHeader.d.ts +0 -118
  444. package/dist/skill/reference/components/page-content/COMPONENT.md +0 -264
  445. package/dist/skill/reference/components/page-content/examples/examples.module.css +0 -56
  446. package/dist/skill/reference/components/page-content/examples/narrow.tsx +0 -25
  447. package/dist/skill/reference/components/page-content/examples/overview.tsx +0 -41
  448. package/dist/skill/reference/components/page-toolbar/COMPONENT.md +0 -147
  449. package/dist/skill/reference/components/page-toolbar/examples/examples.module.css +0 -16
  450. package/dist/skill/reference/components/page-toolbar/examples/overview.tsx +0 -113
  451. package/dist/skill/reference/components/page-toolbar/examples/save-changes.tsx +0 -43
  452. package/dist/skill/reference/components/page-toolbar/examples/without-search.tsx +0 -60
  453. package/dist/skill/reference/layout/app-header/COMPONENT.md +0 -187
  454. package/dist/skill/reference/layout/app-header/examples/breadcrumbs.tsx +0 -37
  455. package/dist/skill/reference/layout/app-header/examples/examples.module.css +0 -28
  456. package/dist/skill/reference/layout/app-header/examples/in-app-shell.tsx +0 -67
  457. package/dist/skill/reference/layout/app-header/examples/narrow.tsx +0 -66
  458. package/dist/skill/reference/layout/app-header/examples/overview.tsx +0 -34
  459. package/dist/skill/reference/layout/app-header/examples/page-title.tsx +0 -78
  460. package/dist/skill/reference/layout/app-shell/examples/contained.tsx +0 -30
  461. package/src/components/page-content/COMPONENT.md +0 -264
  462. package/src/components/page-content/examples/examples.module.css +0 -56
  463. package/src/components/page-content/examples/narrow.tsx +0 -25
  464. package/src/components/page-content/examples/overview.tsx +0 -41
  465. package/src/components/page-toolbar/COMPONENT.md +0 -147
  466. package/src/components/page-toolbar/examples/examples.module.css +0 -16
  467. package/src/components/page-toolbar/examples/overview.tsx +0 -113
  468. package/src/components/page-toolbar/examples/save-changes.tsx +0 -43
  469. package/src/components/page-toolbar/examples/without-search.tsx +0 -60
  470. package/src/layout/app-header/COMPONENT.md +0 -187
  471. package/src/layout/app-header/examples/breadcrumbs.tsx +0 -37
  472. package/src/layout/app-header/examples/examples.module.css +0 -28
  473. package/src/layout/app-header/examples/in-app-shell.tsx +0 -67
  474. package/src/layout/app-header/examples/narrow.tsx +0 -66
  475. package/src/layout/app-header/examples/overview.tsx +0 -34
  476. package/src/layout/app-header/examples/page-title.tsx +0 -78
  477. package/src/layout/app-shell/examples/contained.tsx +0 -30
@@ -1,6 +1,5 @@
1
- /** A create form in a Drawer opened from the primary action in the app header: grouped fields, errors on submit with focus on the first invalid field, a loading submit, a toast and the new row in the list — `Drawer.Trigger`, `Drawer.Guard`. */
1
+ /** A create form in a Drawer opened from the primary action in its top bar: grouped fields, errors on submit with focus on the first invalid field, a loading submit, a toast and the new row in the list — `Drawer.Trigger`, `Drawer.Guard`. */
2
2
  import {
3
- AppHeader,
4
3
  Badge,
5
4
  Button,
6
5
  Checkbox,
@@ -10,8 +9,7 @@ import {
10
9
  Fieldset,
11
10
  Icon,
12
11
  Input,
13
- PageContent,
14
- PageToolbar,
12
+ Page,
15
13
  Radio,
16
14
  Select,
17
15
  SmartFilter,
@@ -128,162 +126,141 @@ export default function DrawerScreenExample() {
128
126
  const people = clients.filter((client) => client.kind === "person").length;
129
127
 
130
128
  return (
131
- <>
132
- {/* The page lives in the app header: the only h1, the counts under it, search and the one
133
- primary action — the Drawer trigger — in the tools row; main has no PageContent.Header. */}
134
- <AppHeader.Root>
135
- <AppHeader.Start>
136
- <AppHeader.Title>
137
- Клиенты
138
- <AppHeader.Description>
129
+ <SmartFilter.Root fields={[]} search={search} onSearchChange={setSearch}>
130
+ <Page.Root>
131
+ {/* A work screen titles itself in its top bar: the only h1, the counts under it, the search
132
+ and the one primary action — the Drawer trigger. */}
133
+ <Page.TopBar>
134
+ <Page.Heading>
135
+ <Page.Title>Клиенты</Page.Title>
136
+ <Page.Description>
139
137
  {plural(clients.length, CLIENT_WORDS)} ·{" "}
140
138
  {plural(clients.length - people, COMPANY_WORDS)} и {people} ИП
141
- </AppHeader.Description>
142
- </AppHeader.Title>
143
- </AppHeader.Start>
144
- <AppHeader.Tools>
145
- <SmartFilter.Root fields={[]} search={search} onSearchChange={setSearch}>
146
- <PageToolbar.Root aria-label="Клиенты">
147
- <PageToolbar.Tools>
148
- <SmartFilter.Toolbar />
149
- </PageToolbar.Tools>
150
- <PageToolbar.Actions>
151
- <Drawer.Root open={open} onOpenChange={changeOpen}>
152
- <Drawer.Trigger>
153
- <Button.Root>
154
- <Button.Icon>
155
- <Icon name="action.add" />
156
- </Button.Icon>
157
- Новый клиент
158
- </Button.Root>
159
- </Drawer.Trigger>
160
- <Drawer.Content>
161
- <Drawer.Header>
162
- <Drawer.Title>Новый клиент</Drawer.Title>
163
- <Drawer.Description>
164
- Появится в списке и в выборе клиента при выставлении счёта.
165
- </Drawer.Description>
166
- </Drawer.Header>
167
- <Drawer.Body>
168
- <Drawer.Guard busy={saving} dirty={dirty} />
169
- <form
170
- id={formId}
171
- className={styles.form}
172
- noValidate
173
- onSubmit={submit}
174
- onChange={() => setDirty(true)}
139
+ </Page.Description>
140
+ </Page.Heading>
141
+ <Page.Tools aria-label="Клиенты">
142
+ <SmartFilter.Toolbar />
143
+ </Page.Tools>
144
+ <Page.Actions>
145
+ <Drawer.Root open={open} onOpenChange={changeOpen}>
146
+ <Drawer.Trigger>
147
+ <Button.Root>
148
+ <Button.Icon>
149
+ <Icon name="action.add" />
150
+ </Button.Icon>
151
+ Новый клиент
152
+ </Button.Root>
153
+ </Drawer.Trigger>
154
+ <Drawer.Content>
155
+ <Drawer.Header>
156
+ <Drawer.Title>Новый клиент</Drawer.Title>
157
+ <Drawer.Description>
158
+ Появится в списке и в выборе клиента при выставлении счёта.
159
+ </Drawer.Description>
160
+ </Drawer.Header>
161
+ <Drawer.Body>
162
+ <Drawer.Guard busy={saving} dirty={dirty} />
163
+ <form
164
+ id={formId}
165
+ className={styles.form}
166
+ noValidate
167
+ onSubmit={submit}
168
+ onChange={() => setDirty(true)}
169
+ >
170
+ <Fieldset label="Реквизиты" disabled={saving}>
171
+ <Radio.Group
172
+ name="kind"
173
+ label="Тип клиента"
174
+ defaultValue="company"
175
+ orientation="horizontal"
175
176
  >
176
- <Fieldset label="Реквизиты" disabled={saving}>
177
- <Radio.Group
178
- name="kind"
179
- label="Тип клиента"
180
- defaultValue="company"
181
- orientation="horizontal"
182
- >
183
- <Radio.Root value="company">
184
- <Radio.Label>Компания</Radio.Label>
185
- </Radio.Root>
186
- <Radio.Root value="person">
187
- <Radio.Label>ИП</Radio.Label>
188
- </Radio.Root>
189
- </Radio.Group>
190
- <Input.Root label="Название" error={errors.name}>
191
- <Input.Wrapper>
192
- <Input.Field
193
- name="name"
194
- placeholder="ООО «Ромашка»"
195
- autoComplete="organization"
196
- />
197
- </Input.Wrapper>
198
- </Input.Root>
199
- <div className={styles.pair}>
200
- <Input.Root label="ИНН" error={errors.inn} reserveSupportRow>
201
- <Input.Wrapper>
202
- <Input.Field
203
- name="inn"
204
- inputMode="numeric"
205
- placeholder="7704512908"
206
- />
207
- </Input.Wrapper>
208
- </Input.Root>
209
- <Input.Root label="КПП" optional reserveSupportRow>
210
- <Input.Wrapper>
211
- <Input.Field
212
- name="kpp"
213
- inputMode="numeric"
214
- placeholder="770401001"
215
- />
216
- </Input.Wrapper>
217
- </Input.Root>
218
- </div>
219
- </Fieldset>
220
- <Fieldset label="Контакты" disabled={saving}>
221
- <Input.Root
222
- label="Почта для счетов"
223
- error={errors.email}
224
- hint="На неё уйдут счета и акты"
225
- >
226
- <Input.Wrapper>
227
- <Input.Icon side="start">
228
- <Icon name="field.email" />
229
- </Input.Icon>
230
- <Input.Field
231
- name="email"
232
- type="email"
233
- placeholder="billing@company.ru"
234
- />
235
- </Input.Wrapper>
236
- </Input.Root>
237
- <Select.Root
238
- label="Менеджер"
239
- value={manager}
240
- onValueChange={(next) => {
241
- setManager(next);
242
- setDirty(true);
243
- }}
244
- >
245
- <Select.Trigger>
246
- <Select.Value />
247
- </Select.Trigger>
248
- <Select.Content>
249
- {MANAGERS.map((name) => (
250
- <Select.Item key={name} value={name}>
251
- {name}
252
- </Select.Item>
253
- ))}
254
- </Select.Content>
255
- </Select.Root>
256
- <Textarea.Root name="note" label="Комментарий" optional rows={2} />
257
- <Checkbox.Root
258
- name="invite"
259
- defaultChecked
260
- hint="Клиент увидит свои счета и акты онлайн"
261
- >
262
- <Checkbox.Label>Пригласить в личный кабинет</Checkbox.Label>
263
- </Checkbox.Root>
264
- </Fieldset>
265
- </form>
266
- </Drawer.Body>
267
- <Drawer.Footer>
268
- <Drawer.Close>
269
- <Button.Root variant="outline" tone="neutral">
270
- Отмена
271
- </Button.Root>
272
- </Drawer.Close>
273
- <Button.Root type="submit" form={formId} loading={saving}>
274
- Добавить клиента
275
- </Button.Root>
276
- </Drawer.Footer>
277
- </Drawer.Content>
278
- </Drawer.Root>
279
- </PageToolbar.Actions>
280
- </PageToolbar.Root>
281
- </SmartFilter.Root>
282
- </AppHeader.Tools>
283
- </AppHeader.Root>
284
-
285
- <PageContent.Root>
286
- <PageContent.Body>
177
+ <Radio.Root value="company">
178
+ <Radio.Label>Компания</Radio.Label>
179
+ </Radio.Root>
180
+ <Radio.Root value="person">
181
+ <Radio.Label>ИП</Radio.Label>
182
+ </Radio.Root>
183
+ </Radio.Group>
184
+ <Input.Root label="Название" error={errors.name}>
185
+ <Input.Wrapper>
186
+ <Input.Field
187
+ name="name"
188
+ placeholder="ООО «Ромашка»"
189
+ autoComplete="organization"
190
+ />
191
+ </Input.Wrapper>
192
+ </Input.Root>
193
+ <div className={styles.pair}>
194
+ <Input.Root label="ИНН" error={errors.inn} reserveSupportRow>
195
+ <Input.Wrapper>
196
+ <Input.Field name="inn" inputMode="numeric" placeholder="7704512908" />
197
+ </Input.Wrapper>
198
+ </Input.Root>
199
+ <Input.Root label="КПП" optional reserveSupportRow>
200
+ <Input.Wrapper>
201
+ <Input.Field name="kpp" inputMode="numeric" placeholder="770401001" />
202
+ </Input.Wrapper>
203
+ </Input.Root>
204
+ </div>
205
+ </Fieldset>
206
+ <Fieldset label="Контакты" disabled={saving}>
207
+ <Input.Root
208
+ label="Почта для счетов"
209
+ error={errors.email}
210
+ hint="На неё уйдут счета и акты"
211
+ >
212
+ <Input.Wrapper>
213
+ <Input.Icon side="start">
214
+ <Icon name="field.email" />
215
+ </Input.Icon>
216
+ <Input.Field name="email" type="email" placeholder="billing@company.ru" />
217
+ </Input.Wrapper>
218
+ </Input.Root>
219
+ <Select.Root
220
+ label="Менеджер"
221
+ value={manager}
222
+ onValueChange={(next) => {
223
+ setManager(next);
224
+ setDirty(true);
225
+ }}
226
+ >
227
+ <Select.Trigger>
228
+ <Select.Value />
229
+ </Select.Trigger>
230
+ <Select.Content>
231
+ {MANAGERS.map((name) => (
232
+ <Select.Item key={name} value={name}>
233
+ {name}
234
+ </Select.Item>
235
+ ))}
236
+ </Select.Content>
237
+ </Select.Root>
238
+ <Textarea.Root name="note" label="Комментарий" optional rows={2} />
239
+ <Checkbox.Root
240
+ name="invite"
241
+ defaultChecked
242
+ hint="Клиент увидит свои счета и акты онлайн"
243
+ >
244
+ <Checkbox.Label>Пригласить в личный кабинет</Checkbox.Label>
245
+ </Checkbox.Root>
246
+ </Fieldset>
247
+ </form>
248
+ </Drawer.Body>
249
+ <Drawer.Footer>
250
+ <Drawer.Close>
251
+ <Button.Root variant="outline" tone="neutral">
252
+ Отмена
253
+ </Button.Root>
254
+ </Drawer.Close>
255
+ <Button.Root type="submit" form={formId} loading={saving}>
256
+ Добавить клиента
257
+ </Button.Root>
258
+ </Drawer.Footer>
259
+ </Drawer.Content>
260
+ </Drawer.Root>
261
+ </Page.Actions>
262
+ </Page.TopBar>
263
+ <Page.Body>
287
264
  <DataTable
288
265
  columns={COLUMNS}
289
266
  rows={shown}
@@ -291,8 +268,8 @@ export default function DrawerScreenExample() {
291
268
  paging="none"
292
269
  empty="Клиентов не найдено"
293
270
  />
294
- </PageContent.Body>
295
- </PageContent.Root>
296
- </>
271
+ </Page.Body>
272
+ </Page.Root>
273
+ </SmartFilter.Root>
297
274
  );
298
275
  }
@@ -7,7 +7,7 @@
7
7
 
8
8
  ## When to use
9
9
  - Secondary actions of a card, row or document behind a «⋯» or labelled button.
10
- - An account / user menu in the app header.
10
+ - An account / user menu behind the Sidebar account row (`Sidebar.Account`).
11
11
  - A short list of commands (export formats, move to project) where picking one runs an action.
12
12
 
13
13
  ## When not to use
@@ -57,11 +57,11 @@ ExampleFrame frame: toolbar + the pane (a region swap between prev
57
57
  | Value | Looks like | Use when | Default |
58
58
  |---|---|---|---|
59
59
  | `default` | single block centered in the stage | one component | yes |
60
- | `stack` | centered column, gap 16, children capped at the stack measure (`10 × --prime-space-16`) so `width: 100%` blocks stay centered; a child with `fullWidth` or a table stretches | several blocks one under another | |
61
- | `stack-narrow` | column, children capped at `7 × --prime-space-16` and centered | forms and narrow columns | |
60
+ | `stack` | centered column, gap 16, children capped at the stack measure (`10 × --prime-space-16`) so `width: 100%` blocks stay centered; a child with `fullWidth` or a table stretches, never past the stage, and a horizontal separator beside it stretches with it | several blocks one under another | |
61
+ | `stack-narrow` | column, children capped at `7 × --prime-space-16` and centered, full width unless a child sets its own (a cascade-layer default, so a fit-content SegmentedControl keeps hugging its segments); a child with a table may take the stage | forms and narrow columns | |
62
62
  | `full` | column, gap 16, every child takes the whole stage width | page structure: app shells, page regions | |
63
63
  | `row` | centered wrapping row, gap 12, extra vertical padding | a few buttons or controls side by side | |
64
- | `matrix` | centered grid of labelled cells: each direct child is a row, its children are cells (specimen above its caption); columns (up to 12) line up across rows, are never narrower than their content and grow to 320 / 160 / 128px for 1 / 2 / 3+ columns, so width-less specimens (Slider, `width: 100%` blocks) get a real cell; centered vertically too; when the grid is wider than the stage (a phone frame) each row wraps its cells, centered (`data-matrix-wrap` on the stage) | variant, size and state matrices | |
64
+ | `matrix` | centered grid of labelled cells: each direct child is a row, its children are cells (specimen above its caption); columns (up to 12) line up across rows, are never narrower than their content and grow to 320 / 160 / 128px for 1 / 2 / 3+ columns, so width-less specimens (Slider, `width: 100%` blocks) get a real cell; centered vertically too; when the grid is wider than the stage (a phone frame) each row wraps its cells, centered (`data-matrix-wrap` on the stage), and a one-column matrix keeps its cells at the one-column measure (or the stage, when narrower) | variant, size and state matrices | |
65
65
  | `matrix-wide` | the same rows of labelled cells, one cell under another, each as wide as the stage up to the stack measure (`10 × --prime-space-16`), the caption under the specimen | matrices of specimens as wide as their container: tabs, toolbars, tables | |
66
66
 
67
67
  ### viewport
@@ -30,6 +30,7 @@ FieldList field frame: label · the list · hint / error
30
30
  ├─ <ol> the rows (Dnd.Sortable with `reorderable`)
31
31
  │ └─ <li> row [lead: handle | lock] [a cell per column] [end: remove]
32
32
  │ └─ cell one kit field without `label`, named by its column heading
33
+ ├─ totals row `renderTotals`: a group «Итого», a total per column on the same tracks
33
34
  └─ add row Button «addLabel» (+ `labels.maxReached` at `max`)
34
35
  ```
35
36
  A leaf: rows come from `value` through `renderItem`, which returns one element per column (a fragment). Every framed kit field (Input, Select, Datepicker, NativeSelect, ColorField…) in a cell takes its column heading as its label: read by screen readers, not shown while the heading row is on screen, shown above the field once the rows stack in a narrow container. `ColorPresets` takes it as the name of its trigger.
@@ -43,12 +44,13 @@ Generic `FieldList<T>`; `ref` → `HTMLDivElement` (the field frame). An editabl
43
44
 
44
45
  | Prop | Type | Default | Description |
45
46
  |---|---|---|---|
46
- | `columns` | `readonly FieldListColumn[]` | — (required) | The columns in cell order: `label` (the heading; it names the field of the column in every row), `width` (`fill` \| `compact` \| `s` \| `m`), `required` (a `*` after the heading). |
47
+ | `columns` | `readonly FieldListColumn[]` | — (required) | The columns in cell order: `label` (the heading; it names the field of the column in every row), `width` (`fill` \| `compact` \| `xs` \| `s` \| `m`), `required` (a `*` after the heading). |
47
48
  | `renderItem` | `(item: T, row: FieldListRow<T>) => ReactNode` | — (required) | The cells of a row, one element per column (a fragment): kit fields without `label`. `row` has `index`, `update(patch)` and `remove()`. |
49
+ | `renderTotals` | `(items: readonly T[]) => ReactNode` | — | The totals row under the rows: one node per column (a fragment), `null` where a column has none. The first cell without a total reads `labels.totals`, the row's group name. |
48
50
  | `getId` | `(item: T) => string` | — (required) | Stable unique id of an item: the row key and the drag id. |
49
51
  | `value` | `readonly T[]` | — | The rows (controlled). |
50
52
  | `defaultValue` | `readonly T[]` | `[]` | The first rows (uncontrolled). |
51
- | `onValueChange` | `(value: T[]) => void` | — | The new list after an edit (`row.update`), an added, removed or moved row. |
53
+ | `onValueChange` | `(value: T[]) => void \| Promise<void>` | — | The new list after an edit (`row.update`), an add, a remove or a move. Return the save's promise: the new list shows while it is pending, the owner's again on a reject (say why with `error`). |
52
54
  | `createItem` | `() => T` | — | A new empty item; with it the add button shows under the rows and focus goes to the new row's first field. |
53
55
  | `addLabel` | `string` | — | Text of the add button: what is added («Добавить позицию»). |
54
56
  | `getLabel` | `(item: T) => string` | — | The row's own text (its title field) for the remove button, the handle and drag announcements; else the row number. |
@@ -59,6 +61,7 @@ Generic `FieldList<T>`; `ref` → `HTMLDivElement` (the field frame). An editabl
59
61
  | `label` | `ReactNode` | — | Heading of the list; names the `<ol>`. Omit it inside a `Fieldset` whose legend names the list. |
60
62
  | `aria-label` | `string` | — | Name of the `<ol>` when no visible `label` names it (a section heading above the list). |
61
63
  | `hint` | `ReactNode` | — | Help text under the list; hidden while `error` shows. |
64
+ | `hintTone` | `"neutral" \| "success" \| "warning" \| "danger"` | `"neutral"` | Status color of `hint` («Осталось 12 дней» in `warning`). The words carry the status, the color repeats it; an `error` replaces the hint and its tone. A validation error is `error`, never a `danger` hint. |
62
65
  | `error` | `ReactNode` | — | A problem of the list as a whole («Добавьте хотя бы одну позицию»); a field's own error goes on that field. |
63
66
  | `disabled` | `boolean` | `false` | Disables every field, handle and button; a disabled `Fieldset` around it sets it too. |
64
67
  | `size` | `"xs" \| "s" \| "m" \| "l" \| "xl"` | host tier, else `"m"` | Tier of the headings, buttons and the kit fields that read the host tier. Without it the host tier, else `m`. |
@@ -72,6 +75,7 @@ Generic `FieldList<T>`; `ref` → `HTMLDivElement` (the field frame). An editabl
72
75
  |---|---|---|---|
73
76
  | `fill` | shares the free width with the other `fill` columns | names, descriptions, any text | yes |
74
77
  | `compact` | two control heights wide | an icon-only `Select`, a `ColorPresets` swatch, a checkbox | |
78
+ | `xs` | 96 px | a number of a few digits: a share, a percent, a count | |
75
79
  | `s` | 144 px | a quantity, a code, a number of days | |
76
80
  | `m` | 192 px | an amount with its unit, a date, a phone | |
77
81
 
@@ -82,6 +86,7 @@ Generic `FieldList<T>`; `ref` → `HTMLDivElement` (the field frame). An editabl
82
86
  | `getLocked` | a lock where the grip is, no remove button; the row holds its place | a base value, system records a person cannot drop | — |
83
87
  | `createItem` | the add button under the rows, aligned with the first column | the person grows the list | — |
84
88
  | `min` · `max` | remove buttons off at `min`; the add button off with «Не больше {max}» at `max` | the record count is bounded | `0` · — |
89
+ | `renderTotals` | a row of totals under the rows over a faint line, each on its column; «Итого» in the first cell without a total | the rows add up (shares, amounts, hours) | — |
85
90
 
86
91
  **Combinations**
87
92
  - Recommended: `label` on the list (or a `Fieldset` legend around it), one heading per column, a `getLabel` from the title field, an `addLabel` that says what is added.
@@ -98,13 +103,15 @@ Generic `FieldList<T>`; `ref` → `HTMLDivElement` (the field frame). An editabl
98
103
  | pinned row | `getLocked(item)` | `data-locked="true"` on the `<li>`; a lock, no remove button |
99
104
  | invalid | `error` (the list), a field's own `error` | the list's message under the add row; a field's under the field in its row |
100
105
  | disabled | `disabled` (or a disabled Fieldset) | `data-disabled="true"` on the frame; fields, handles and buttons disabled through the kit's disabled context |
101
- | stacked | container narrower than 30rem | heading row hidden, each row's fields in one column with their labels shown |
106
+ | stacked | container narrower than 30rem | heading row hidden, each row's fields in one column with their labels shown; each total on its own line after its column name |
107
+ | saving | a promise from `onValueChange` | the rows show the new list, `aria-busy="true"` on the `<ol>`; a reject brings the owner's list back |
102
108
  | rows come and go | the add button, a remove button, a new `value` | a row the data adds rises in once (`enterMotion`), a removed one closes up in place and the rows below glide up (`listPresence`); the heading row rises in with the first row and closes up with the last (`partPresence`); the first render stays still |
103
109
 
104
110
  ## Layout & spacing
105
111
  - Rows 12 apart (`--prime-space-3`); columns 12 apart; the heading row sits at the tier's label gap above the first row.
106
112
  - Every row and the heading row share one track list: `[lead] [columns] [end]`; the lead is one `xs` control wide (the grip or the lock), the end fits a remove button of the tier.
107
113
  - The handle, the lock and the remove button stand on the middle of the first line of fields, so a field's error under it grows the row downwards only.
114
+ - The totals row stands 12 under the last row over a faint line, 12 more above its totals; a total's text starts where its column's field text does.
108
115
  - The add button lines up with the first column of fields, 12 under the last row.
109
116
  - Under 30rem of its own width (a container query): rows stack, fields 16 apart inside a row, rows 24 apart.
110
117
 
@@ -126,6 +133,7 @@ Generic `FieldList<T>`; `ref` → `HTMLDivElement` (the field frame). An editabl
126
133
  - The heading row is `aria-hidden`: each field in a cell carries its column heading as its own label, read but not shown on wide rows.
127
134
  - The `<ol>` is described by the list's `hint` and `error` (`aria-describedby`), which speak for every row.
128
135
  - In a narrow container the heading row goes and each field's label shows above it.
136
+ - The totals row (`renderTotals`) is a `group` named by `labels.totals`; each total is read after its column heading.
129
137
  - The remove button is «Удалить {row}», the handle «Переместить {row}»: the row's name from `getLabel`, else its number.
130
138
  - A pinned row has a lock in place of the handle and no remove button; without `reorderable` the lock is Dnd's lock (an image named «Закреплена»).
131
139
 
@@ -140,6 +148,7 @@ Generic `FieldList<T>`; `ref` → `HTMLDivElement` (the field frame). An editabl
140
148
  | `namedRow` | `"«{label}»"` | Name of a row with `getLabel` text; `{label}` is that text. |
141
149
  | `locked` | `"Закреплена"` | Spoken name of the lock of a pinned row in a list without `reorderable`. |
142
150
  | `maxReached` | `"Не больше {max}"` | Text beside the disabled add button once the list holds `max` rows. |
151
+ | `totals` | `"Итого"` | Name of the totals row (`renderTotals`), shown in its first cell when that has no total. |
143
152
 
144
153
  ## Examples
145
154
  | Example | Shows |
@@ -151,6 +160,8 @@ Generic `FieldList<T>`; `ref` → `HTMLDivElement` (the field frame). An editabl
151
160
  | [base-row.tsx](examples/base-row.tsx) | A plan price and its changes by month in one table: the base price is the first, pinned row, each change is a row with its month and its price, and the unit sits in the field, not in a heading — `getLocked`, `width`. |
152
161
  | [limits.tsx](examples/limits.tsx) | Recipients of invoice reminders, from one to three: the last row cannot be removed and the add button says why it is off once the list is full — `min`, `max`, `hint`. |
153
162
  | [errors.tsx](examples/errors.tsx) | Contacts of a client checked on save: a field's problem shows under that field in its row, a problem of the whole list under the list, and focus goes to the first wrong field; a `*` after a heading marks a required column — `error`, `required`. |
163
+ | [totals.tsx](examples/totals.tsx) | A deal bonus split between the team: the share takes a narrow column, and the totals row under the lines sums the shares and the amounts — `renderTotals`, `width`. |
164
+ | [saving.tsx](examples/saving.tsx) | Removing a recipient is saved on the server: the row leaves at once and comes back with the reason if the server refuses — `onValueChange`, `error`. |
154
165
  | [states.tsx](examples/states.tsx) | The same list editable and disabled while the request saves it: fields, handles and buttons turn off together — `disabled`. |
155
166
  | [controlled.tsx](examples/controlled.tsx) | The parent owns the lines: it sums them under the list and puts the saved lines back on reset — `value`, `onValueChange`. |
156
167
  | [narrow.tsx](examples/narrow.tsx) | The invoice lines in a 320 px column: the headings give way, each row stacks its fields with their own labels and rows stand a group apart — `columns`. |
@@ -165,6 +176,7 @@ Generic `FieldList<T>`; `ref` → `HTMLDivElement` (the field frame). An editabl
165
176
  - A hint that explains what the lock already shows («Первые три всегда первыми») → no hint; the lock says it.
166
177
  - `aria-label` written on every field in a cell → none: the column heading names the field.
167
178
  - A grip, a remove button and an add button drawn by hand around a `.map()` of fields → FieldList.
179
+ - A total under the list typed by hand in a line of text, or a DataTable of fields to get a totals row → `renderTotals`.
168
180
 
169
181
  ## Related
170
182
  - **Built from:** [Button](../button/COMPONENT.md) (add, remove), [Dnd](../dnd/COMPONENT.md) (`reorderable`: `Dnd.Sortable`, `Dnd.Handle`; the lock of a pinned row), [Label](../label/COMPONENT.md) (headings), the field frame (label, [Hint](../hint/COMPONENT.md) for the hint and error), [VisuallyHidden](../visually-hidden/COMPONENT.md)
@@ -0,0 +1,83 @@
1
+ /** Removing a recipient is saved on the server: the row leaves at once and comes back with the reason if the server refuses — `onValueChange`, `error`. */
2
+ import { FieldList, type FieldListColumn, Input } from "prime-ui-kit";
3
+ import * as React from "react";
4
+
5
+ type Recipient = { id: string; name: string; email: string; billing: boolean };
6
+
7
+ const COLUMNS: FieldListColumn[] = [{ label: "Имя" }, { label: "Почта" }];
8
+
9
+ const RECIPIENTS: Recipient[] = [
10
+ { id: "accounting", name: "Бухгалтерия", email: "buh@severstroy.ru", billing: true },
11
+ { id: "director", name: "Ирина Котова", email: "kotova@severstroy.ru", billing: false },
12
+ { id: "manager", name: "Олег Демин", email: "demin@severstroy.ru", billing: false },
13
+ ];
14
+
15
+ /** The server's answer to a removal, a beat later: the billing contact stays. */
16
+ function saveRemoval(removed: Recipient[]) {
17
+ return new Promise<void>((resolve, reject) => {
18
+ setTimeout(() => {
19
+ if (removed.some((recipient) => recipient.billing)) {
20
+ reject(new Error("Бухгалтерию нельзя убрать: на неё уходят счета"));
21
+ } else {
22
+ resolve();
23
+ }
24
+ }, 900);
25
+ });
26
+ }
27
+
28
+ export default function FieldListSavingExample() {
29
+ const [recipients, setRecipients] = React.useState(RECIPIENTS);
30
+ const [failure, setFailure] = React.useState<string | null>(null);
31
+
32
+ return (
33
+ <FieldList
34
+ label="Кому отправлять счета"
35
+ error={failure}
36
+ columns={COLUMNS}
37
+ value={recipients}
38
+ onValueChange={(next) => {
39
+ setFailure(null);
40
+ const removed = recipients.filter(
41
+ (recipient) => !next.some((item) => item.id === recipient.id),
42
+ );
43
+ if (removed.length === 0) {
44
+ setRecipients(next);
45
+ return;
46
+ }
47
+ return saveRemoval(removed).then(
48
+ () => setRecipients(next),
49
+ (reason: Error) => {
50
+ setFailure(reason.message);
51
+ throw reason;
52
+ },
53
+ );
54
+ }}
55
+ getId={(recipient) => recipient.id}
56
+ getLabel={(recipient) => recipient.name}
57
+ createItem={() => ({ id: crypto.randomUUID(), name: "", email: "", billing: false })}
58
+ addLabel="Добавить получателя"
59
+ renderItem={(recipient, row) => (
60
+ <>
61
+ <Input.Root>
62
+ <Input.Wrapper>
63
+ <Input.Field
64
+ value={recipient.name}
65
+ onChange={(event) => row.update({ name: event.target.value })}
66
+ />
67
+ </Input.Wrapper>
68
+ </Input.Root>
69
+ <Input.Root>
70
+ <Input.Wrapper>
71
+ <Input.Field
72
+ type="email"
73
+ value={recipient.email}
74
+ placeholder="name@company.ru"
75
+ onChange={(event) => row.update({ email: event.target.value })}
76
+ />
77
+ </Input.Wrapper>
78
+ </Input.Root>
79
+ </>
80
+ )}
81
+ />
82
+ );
83
+ }
@@ -1,4 +1,4 @@
1
- /* Record editor: the sections are PageContent.Section layout="aside"; here only the panels' insides. */
1
+ /* Record editor: the sections are Page.Section layout="aside"; here only the panels' insides. */
2
2
 
3
3
  /* Two groups in one panel, a group apart. */
4
4
  .groups {
@@ -9,7 +9,7 @@ import {
9
9
  Icon,
10
10
  type IconName,
11
11
  Input,
12
- PageContent,
12
+ Page,
13
13
  Select,
14
14
  Textarea,
15
15
  } from "prime-ui-kit";
@@ -121,20 +121,20 @@ export default function FieldListScreenExample() {
121
121
  };
122
122
 
123
123
  return (
124
- <PageContent.Root maxWidth="wide" aria-labelledby="plan-title">
125
- <PageContent.Header>
126
- <PageContent.Title id="plan-title">Тариф «Команда»</PageContent.Title>
127
- <PageContent.Description>
128
- Так тариф выглядит на странице цен и в счетах.
129
- </PageContent.Description>
130
- <PageContent.Actions>
124
+ <Page.Root maxWidth="wide" aria-labelledby="plan-title">
125
+ <Page.Header>
126
+ <Page.Heading>
127
+ <Page.Title id="plan-title">Тариф «Команда»</Page.Title>
128
+ <Page.Description>Так тариф выглядит на странице цен и в счетах.</Page.Description>
129
+ </Page.Heading>
130
+ <Page.Actions>
131
131
  <Button.Root type="submit" form={formId} loading={saving}>
132
132
  {saved ? "Сохранено" : "Сохранить тариф"}
133
133
  </Button.Root>
134
- </PageContent.Actions>
135
- </PageContent.Header>
136
- <PageContent.Body>
137
- <PageContent.Section layout="aside" label="Основное">
134
+ </Page.Actions>
135
+ </Page.Header>
136
+ <Page.Body>
137
+ <Page.Section layout="aside" label="Основное">
138
138
  <form id={formId} noValidate onSubmit={save}>
139
139
  <Card.Root variant="panel">
140
140
  <Card.Body>
@@ -155,9 +155,9 @@ export default function FieldListScreenExample() {
155
155
  </Card.Body>
156
156
  </Card.Root>
157
157
  </form>
158
- </PageContent.Section>
158
+ </Page.Section>
159
159
 
160
- <PageContent.Section layout="aside" label="Характеристики">
160
+ <Page.Section layout="aside" label="Характеристики">
161
161
  <Card.Root variant="panel">
162
162
  <Card.Body>
163
163
  <FieldList
@@ -230,9 +230,9 @@ export default function FieldListScreenExample() {
230
230
  />
231
231
  </Card.Body>
232
232
  </Card.Root>
233
- </PageContent.Section>
233
+ </Page.Section>
234
234
 
235
- <PageContent.Section layout="aside" label="Стоимость">
235
+ <Page.Section layout="aside" label="Стоимость">
236
236
  <Card.Root variant="panel">
237
237
  <Card.Body className={styles.groups}>
238
238
  <Fieldset label="За месяц" disabled={saving}>
@@ -309,8 +309,8 @@ export default function FieldListScreenExample() {
309
309
  </Fieldset>
310
310
  </Card.Body>
311
311
  </Card.Root>
312
- </PageContent.Section>
313
- </PageContent.Body>
314
- </PageContent.Root>
312
+ </Page.Section>
313
+ </Page.Body>
314
+ </Page.Root>
315
315
  );
316
316
  }