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
@@ -1,4 +1,4 @@
1
- /** Search and pinned messages: the search bar marks every match in the texts and transcripts, counts them and steps between them while the others step back; a pinned message's press jumps to it and blinks the others — `Chat.SearchButton`, `Chat.Search`, `defaultSearch`, `Chat.Pinned`. */
1
+ /** Search and pinned messages: the search bar marks every match in the texts and transcripts, counts them and steps between them while the others step back; a pinned message's press jumps to it and blinks it — `Chat.SearchButton`, `Chat.Search`, `defaultSearch`, `Chat.Pinned`. */
2
2
  import { Card, Chat, Message, VoicePlayer } from "prime-ui-kit";
3
3
 
4
4
  import styles from "./examples.module.css";
@@ -170,7 +170,7 @@ Root attribute: `data-size`. Every motion honours reduced motion (durations coll
170
170
 
171
171
  ## Layout & spacing
172
172
  - The root is a flex column that fills its host's height: put it straight into a `Card.Root` or a `PageContent.List` pane with a height; the scroller takes the rest under the search field.
173
- - The search field stands on 8px sides; the rows on 8px sides and 4px between them (a margin inside each `<li>`, so the virtual window measures rows with their space).
173
+ - One inset all round, the panel's 4px: the search field and the rows stand 4px from every edge of the host, so in a card (radius 12) their 8px corners follow the card's (nested radius = outer − padding). Rows stand 4px apart (a margin inside each `<li>`, so the virtual window measures rows with their space); the last row's margin is the inset below it.
174
174
  - A row: avatar · name and preview · time over the counts. The name and the preview truncate; glyphs, the time and the counts never do.
175
175
  - From 100 dialogs only the rows around the view render; spacers hold the rest of the height. The row with the Tab stop and the row with an open menu stay rendered.
176
176
  - The root is the `chat-list` container: below 240px the preview line and the time step out, the names and counts stay. At 320px (a phone) everything shows.
@@ -238,6 +238,7 @@ Root attribute: `data-size`. Every motion honours reduced motion (durations coll
238
238
  | [search.tsx](examples/search.tsx) | The search field filters dialogs by name and by the last message, marks the match in both, says how many were found and shows a quiet state when none match — `defaultSearch`, `onSearchChange`. |
239
239
  | [live.tsx](examples/live.tsx) | A live inbox: a client types, then writes — the preview turns into the typing line and back, the count rolls up and the dialog glides to the top; opening it clears the count — `typing`, `unread`, `items`. |
240
240
  | [long-list.tsx](examples/long-list.tsx) | A sales inbox of a thousand dialogs: only the rows around the view render, arrows walk through all of them, and the next page loads as the end comes near — `hasMore`, `onLoadMore`. |
241
+ | [links.tsx](examples/links.tsx) | Dialogs with their own address: every row is a link the router opens, the time reads as how long ago, and the list is named for its queue — `href`, `formatTime`, `labels`. |
241
242
  | [states.tsx](examples/states.tsx) | Loading and empty: placeholder rows in the rows' geometry cross-fade into the dialogs; a new workspace without dialogs shows its own empty state with an action — `loading`, `empty`. |
242
243
  | [controlled.tsx](examples/controlled.tsx) | The open dialog lives in the screen: a row opens it beside the list, and a next-unread button opens the next one from outside — `value`, `onValueChange`. |
243
244
  | [narrow.tsx](examples/narrow.tsx) | At phone width long names and previews truncate while the time and counts stay whole; a pane squeezed under 240px keeps only the names and the counts — `ChatList.Root`, `search`. |
@@ -0,0 +1,72 @@
1
+ /** Dialogs with their own address: every row is a link the router opens, the time reads as how long ago, and the list is named for its queue — `href`, `formatTime`, `labels`. */
2
+ import { Avatar, Card, ChatList, hueOf } from "prime-ui-kit";
3
+
4
+ import styles from "./examples.module.css";
5
+
6
+ const NOW = new Date(2026, 9, 14, 15, 0);
7
+ const at = (day: number, hour: number, minute: number) => new Date(2026, 9, day, hour, minute);
8
+
9
+ const DIALOGS = [
10
+ {
11
+ id: "t-1042",
12
+ name: "ООО «Вектор»",
13
+ initials: "ВК",
14
+ preview: "Не можем выгрузить счёт в 1С",
15
+ at: at(14, 14, 52),
16
+ unread: 2,
17
+ },
18
+ {
19
+ id: "t-1039",
20
+ name: "ООО «Гранит»",
21
+ initials: "ГР",
22
+ preview: "Акт сверки подписан",
23
+ at: at(14, 12, 5),
24
+ unread: 0,
25
+ },
26
+ {
27
+ id: "t-1031",
28
+ name: "ИП Козлов",
29
+ initials: "ИК",
30
+ preview: "Подключите, пожалуйста, ЭДО",
31
+ at: at(12, 11, 40),
32
+ unread: 0,
33
+ },
34
+ ];
35
+
36
+ const MINUTE = 60_000;
37
+ const HOUR = 60 * MINUTE;
38
+ const DAY = 24 * HOUR;
39
+
40
+ /** A support queue reads waiting time: «8 мин», «3 ч», «2 дн». */
41
+ const formatAgo = (date: Date, now: Date) => {
42
+ const passed = now.getTime() - date.getTime();
43
+ if (passed < HOUR) return `${Math.max(1, Math.round(passed / MINUTE))} мин`;
44
+ if (passed < DAY) return `${Math.round(passed / HOUR)} ч`;
45
+ return `${Math.round(passed / DAY)} дн`;
46
+ };
47
+
48
+ export default function ChatListLinksExample() {
49
+ return (
50
+ <Card.Root className={styles.short}>
51
+ <ChatList.Root
52
+ labels={{ list: "Обращения" }}
53
+ items={DIALOGS}
54
+ getKey={(item) => item.id}
55
+ value="t-1042"
56
+ now={NOW}
57
+ formatTime={formatAgo}
58
+ renderItem={(item) => (
59
+ <ChatList.Item href={`/support/tickets/${item.id}`} time={item.at} unread={item.unread}>
60
+ <ChatList.ItemIcon>
61
+ <Avatar.Root color={hueOf(item.id)}>
62
+ <Avatar.Fallback>{item.initials}</Avatar.Fallback>
63
+ </Avatar.Root>
64
+ </ChatList.ItemIcon>
65
+ <ChatList.ItemText>{item.name}</ChatList.ItemText>
66
+ <ChatList.ItemDescription>{item.preview}</ChatList.ItemDescription>
67
+ </ChatList.Item>
68
+ )}
69
+ />
70
+ </Card.Root>
71
+ );
72
+ }
@@ -152,7 +152,7 @@ No `labels`.
152
152
  | [overview.tsx](examples/overview.tsx) | A checkbox with its label; a click anywhere on the row toggles it. |
153
153
  | [variants.tsx](examples/variants.tsx) | The rounded square next to the circle, in three states — `shape`. |
154
154
  | [sizes.tsx](examples/sizes.tsx) | Every size; the box and the text follow the control tier — `size`. |
155
- | [states.tsx](examples/states.tsx) | Every state side by side, each labelled by its prop — `checked`, `indeterminate`, `invalid`, `disabled`. |
155
+ | [states.tsx](examples/states.tsx) | Every state side by side, each labelled by its prop — `checked`, `indeterminate`, `readOnly`, `invalid`, `disabled`. |
156
156
  | [without-label.tsx](examples/without-label.tsx) | Bare boxes in table rows, named by `aria-label` and submitted with `name` and `value`. |
157
157
  | [indicator.tsx](examples/indicator.tsx) | The box alone in a multi-select list: the option row carries `aria-selected`, the box only shows it — `Checkbox.Indicator`. |
158
158
  | [controlled.tsx](examples/controlled.tsx) | The parent owns the selection; «select all» turns indeterminate on a partial one — `checked`, `onCheckedChange`, `indeterminate`. |
@@ -57,8 +57,12 @@
57
57
  var(--prime-motion-easing-standard);
58
58
  }
59
59
 
60
+ .option[aria-disabled="true"] {
61
+ cursor: default;
62
+ }
63
+
60
64
  @media (hover: hover) {
61
- .option:hover {
65
+ .option:not([aria-disabled="true"]):hover {
62
66
  background: var(--prime-color-fill-subtle);
63
67
  }
64
68
  }
@@ -4,19 +4,35 @@ import * as React from "react";
4
4
 
5
5
  import styles from "./examples.module.css";
6
6
 
7
- const CITIES = [
7
+ const CITIES: { value: string; label: string; disabled?: boolean }[] = [
8
8
  { value: "msk", label: "Москва" },
9
9
  { value: "spb", label: "Санкт-Петербург" },
10
10
  { value: "kzn", label: "Казань" },
11
+ { value: "tver", label: "Тверь · закрыт", disabled: true },
11
12
  ];
12
13
 
14
+ /** One tab stop: arrows move the focused row (wrapping), Home / End jump to the ends. */
15
+ function nextIndex(key: string, index: number, count: number): number | null {
16
+ if (key === "ArrowDown") return (index + 1) % count;
17
+ if (key === "ArrowUp") return (index - 1 + count) % count;
18
+ if (key === "Home") return 0;
19
+ if (key === "End") return count - 1;
20
+ return null;
21
+ }
22
+
13
23
  export default function CheckboxIndicatorExample() {
14
24
  const [selected, setSelected] = React.useState<string[]>(["msk"]);
25
+ const [active, setActive] = React.useState(0);
26
+ const optionRefs = React.useRef<(HTMLDivElement | null)[]>([]);
15
27
 
16
- const toggle = (value: string) =>
28
+ const toggle = (city: (typeof CITIES)[number]) => {
29
+ if (city.disabled) return;
17
30
  setSelected((current) =>
18
- current.includes(value) ? current.filter((item) => item !== value) : [...current, value],
31
+ current.includes(city.value)
32
+ ? current.filter((item) => item !== city.value)
33
+ : [...current, city.value],
19
34
  );
35
+ };
20
36
 
21
37
  return (
22
38
  <div
@@ -24,26 +40,38 @@ export default function CheckboxIndicatorExample() {
24
40
  aria-label="Города доставки"
25
41
  aria-multiselectable
26
42
  className={styles.optionList}
43
+ onKeyDown={(event) => {
44
+ const next = nextIndex(event.key, active, CITIES.length);
45
+ if (next === null) return;
46
+ event.preventDefault();
47
+ setActive(next);
48
+ optionRefs.current[next]?.focus();
49
+ }}
27
50
  >
28
- {CITIES.map((city) => {
51
+ {CITIES.map((city, index) => {
29
52
  const isSelected = selected.includes(city.value);
30
53
  return (
31
54
  <div
32
55
  key={city.value}
56
+ ref={(node) => {
57
+ optionRefs.current[index] = node;
58
+ }}
33
59
  role="option"
34
60
  aria-selected={isSelected}
35
- tabIndex={0}
61
+ aria-disabled={city.disabled || undefined}
62
+ tabIndex={index === active ? 0 : -1}
36
63
  className={styles.option}
37
- onClick={() => toggle(city.value)}
64
+ onFocus={() => setActive(index)}
65
+ onClick={() => toggle(city)}
38
66
  onKeyDown={(event) => {
39
67
  if (event.key === " " || event.key === "Enter") {
40
68
  event.preventDefault();
41
- toggle(city.value);
69
+ toggle(city);
42
70
  }
43
71
  }}
44
72
  >
45
- <Checkbox.Indicator checked={isSelected} />
46
- <Typography as="span" variant="body-m">
73
+ <Checkbox.Indicator checked={isSelected} disabled={city.disabled} />
74
+ <Typography as="span" variant="body-m" tone={city.disabled ? "muted" : undefined}>
47
75
  {city.label}
48
76
  </Typography>
49
77
  </div>
@@ -1,4 +1,4 @@
1
- /** Every state side by side, each labelled by its prop — `checked`, `indeterminate`, `invalid`, `disabled`. */
1
+ /** Every state side by side, each labelled by its prop — `checked`, `indeterminate`, `readOnly`, `invalid`, `disabled`. */
2
2
  import { Checkbox } from "prime-ui-kit";
3
3
 
4
4
  export default function CheckboxStatesExample() {
@@ -20,6 +20,11 @@ export default function CheckboxStatesExample() {
20
20
  <Checkbox.Label>indeterminate</Checkbox.Label>
21
21
  </Checkbox.Root>
22
22
  </div>
23
+ <div>
24
+ <Checkbox.Root defaultChecked readOnly>
25
+ <Checkbox.Label>readOnly</Checkbox.Label>
26
+ </Checkbox.Root>
27
+ </div>
23
28
  <div>
24
29
  <Checkbox.Root invalid>
25
30
  <Checkbox.Label>invalid</Checkbox.Label>
@@ -93,7 +93,7 @@ ColorField field frame: label · field button · hint | er
93
93
  ## States
94
94
  | State | Driven by | DOM |
95
95
  |---|---|---|
96
- | closed / open | click, `Enter` · `Space`, `Escape`, an outside press | `aria-expanded` and `data-state` on the button; the chevron turns; the button keeps the focus fill while open |
96
+ | closed / open | click, `Enter` · `Space`, `Escape`, an outside press | `aria-expanded` and `data-state` on the button; the chevron turns; the button holds the hover fill while open |
97
97
  | value | `value` / `defaultValue`, the panel | the chip and the hex follow the color as it is dragged; `onValueChange` gets every change as hex |
98
98
  | invalid | `invalid` or `error` | `data-invalid="true"`, `aria-invalid` on the button; the field shakes once when an error arrives (`data-shake` on the frame) |
99
99
  | disabled | `disabled` | native `disabled` on the button, `data-disabled` on the frame; the hidden `name` input is disabled too, so the form does not submit the value |
@@ -163,7 +163,7 @@ No DOM. Holds the color (React Aria `ColorPicker`) and the value format for ever
163
163
  | `…rest` | `Omit<ButtonRootProps, "variant" \| "tone" \| "size" \| "aria-label">` | — | The other Button props. |
164
164
 
165
165
  ### ColorPresets.Root
166
- No DOM. A quick color from a fixed palette: a square trigger and a popover grid of presets (Popover overlay contract).
166
+ A quick color from a fixed palette: a square trigger and a popover grid of presets. No DOM, except a field frame in a FieldList cell (the column heading as its label).
167
167
 
168
168
  | Prop | Type | Default | Description |
169
169
  |---|---|---|---|
@@ -270,7 +270,7 @@ There is no `disabled` on `ColorPicker.Root` — disable parts individually. Con
270
270
  - Field + trigger row: gap `--prime-space-2`, `align-items: flex-end` so the trigger aligns with the field box under a label.
271
271
  - Panel parts gap: 12px (`--prime-space-3`) from `ColorPicker.Panel`.
272
272
  - ColorPresets.Content `align="auto"`: a trigger near the end of the screen lines up the panel's end edge and the panel grows toward the start, and the other way near the start; a fixed `align` still flips at the screen edge.
273
- - ColorPresets grid: one row for up to 8 presets (+ «no color»), else rows of 8 (`columns` overrides); below 480px viewport width the `l` / `xl` grids wrap to half the columns.
273
+ - ColorPresets grid: one row for up to 8 presets (+ «no color»), else rows of 8 (`columns` overrides); below 480px viewport width the `l` / `xl` grids wrap to half the columns. On a coarse pointer every swatch grows to the 44 px touch target and the grid takes at most 5 columns, so it still fits a 320px panel; the arrow keys walk the same columns.
274
274
 
275
275
  ## Accessibility
276
276
 
@@ -306,7 +306,7 @@ There is no `disabled` on `ColorPicker.Root` — disable parts individually. Con
306
306
  | `red` | `"Красный, 0–255"` | Red channel field. |
307
307
  | `green` | `"Зелёный, 0–255"` | Green channel field. |
308
308
  | `blue` | `"Синий, 0–255"` | Blue channel field. |
309
- | `trigger` | `"Цвет"` | ColorPresets trigger name prefix: «<trigger>: <color name>». |
309
+ | `trigger` | `"Цвет"` | ColorPresets trigger name prefix: «<trigger>: <color name>»; in a FieldList cell the column heading. |
310
310
  | `list` | `"Цвета"` | ColorPresets swatch list name when `Content` has no `label`. |
311
311
  | `empty` | `"Без цвета"` | ColorPresets «no color» swatch and the trigger name for an empty value. |
312
312
 
@@ -315,13 +315,14 @@ There is no `disabled` on `ColorPicker.Root` — disable parts individually. Con
315
315
  |---|---|
316
316
  | [overview.tsx](examples/overview.tsx) | A color field: a hex value and a swatch button that opens the picker panel — `ColorPicker.HexInput`, `ColorPicker.TriggerSwatch`. |
317
317
  | [sizes.tsx](examples/sizes.tsx) | Every size of the hex field with a swatch button of the same tier — `size`. |
318
- | [states.tsx](examples/states.tsx) | A disabled area and hue slider keep showing the color but take no input — `disabled`. |
318
+ | [states.tsx](examples/states.tsx) | A disabled area, hue slider and preset trigger keep showing the color but take no input — `disabled`. |
319
319
  | [validation.tsx](examples/validation.tsx) | A button color checked live: a too light color shakes in an error that leaves once the color is darker; a hint under the other field, invalid text reverts on blur — `hint`, `error`. |
320
320
  | [panel.tsx](examples/panel.tsx) | The full raised panel and its part order: format, area, hue and alpha sliders, channels, brand swatches — `ColorPicker.Panel`, `surface`, `ColorPicker.Swatches`. |
321
321
  | [formats.tsx](examples/formats.tsx) | The channel strip in each value format; three pickers edit one color — `defaultFormat`, `ColorPicker.ChannelStrip`. |
322
- | [presets.tsx](examples/presets.tsx) | A quick color from the palette: a square trigger next to a field and a Button trigger; «no color» allowed — `ColorPresets`, `allowEmpty`, `ColorPresets.Trigger`. |
322
+ | [presets.tsx](examples/presets.tsx) | A quick color from the palette: a square trigger with «no color» and a Button trigger whose grid of four columns stays open after a pick — `ColorPresets`, `allowEmpty`, `ColorPresets.Trigger`, `columns`, `closeOnSelect`. |
323
323
  | [presets-sizes.tsx](examples/presets-sizes.tsx) | The preset trigger in every size, a square of the control height next to an input of the same tier — `ColorPresets`, `size`. |
324
324
  | [controlled.tsx](examples/controlled.tsx) | The parent owns the color: brand swatches and the hex field edit it, a button resets it — `value`, `onValueChange`. |
325
+ | [controlled-open.tsx](examples/controlled-open.tsx) | The parent opens the preset palette from its own button and keeps the chosen color — `open`, `onOpenChange`, `value`, `onValueChange`. |
325
326
  | [in-form.tsx](examples/in-form.tsx) | Theme settings: the color goes with the form, a too light color shakes in an error on save that leaves once the color changes — `value`, `error`. |
326
327
 
327
328
  ## Mistakes
@@ -0,0 +1,37 @@
1
+ /** The parent opens the preset palette from its own button and keeps the chosen color — `open`, `onOpenChange`, `value`, `onValueChange`. */
2
+ import { Button, COLOR_PRESETS, ColorPresets, Typography } from "prime-ui-kit";
3
+ import * as React from "react";
4
+
5
+ import styles from "./examples.module.css";
6
+
7
+ const PRESETS = COLOR_PRESETS.slice(0, 8);
8
+
9
+ export default function ColorPickerControlledOpenExample() {
10
+ const [open, setOpen] = React.useState(false);
11
+ const [color, setColor] = React.useState<string | null>("#ef4444");
12
+ const name = PRESETS.find((preset) => preset.value === color)?.label ?? "без цвета";
13
+
14
+ return (
15
+ <div className={styles.inlineRow}>
16
+ <ColorPresets.Root
17
+ presets={PRESETS}
18
+ value={color}
19
+ onValueChange={setColor}
20
+ open={open}
21
+ onOpenChange={setOpen}
22
+ labels={{ trigger: "Цвет метки «Срочно»" }}
23
+ >
24
+ <ColorPresets.Trigger>
25
+ <ColorPresets.SwatchButton />
26
+ </ColorPresets.Trigger>
27
+ <ColorPresets.Content label="Цвет метки «Срочно»" />
28
+ </ColorPresets.Root>
29
+ <Typography as="span" variant="body-s" tone="secondary">
30
+ Метка «Срочно»: {name}
31
+ </Typography>
32
+ <Button.Root variant="soft" tone="neutral" onClick={() => setOpen(true)}>
33
+ Сменить цвет
34
+ </Button.Root>
35
+ </div>
36
+ );
37
+ }
@@ -1,4 +1,4 @@
1
- /** A quick color from the palette: a square trigger next to a field and a Button trigger; «no color» allowed — `ColorPresets`, `allowEmpty`, `ColorPresets.Trigger`. */
1
+ /** A quick color from the palette: a square trigger with «no color» and a Button trigger whose grid of four columns stays open after a pick — `ColorPresets`, `allowEmpty`, `ColorPresets.Trigger`, `columns`, `closeOnSelect`. */
2
2
  import { Button, COLOR_PRESETS, ColorPresets } from "prime-ui-kit";
3
3
 
4
4
  import styles from "./examples.module.css";
@@ -19,7 +19,7 @@ export default function ColorPickerPresetsExample() {
19
19
  </ColorPresets.Trigger>
20
20
  <ColorPresets.Content />
21
21
  </ColorPresets.Root>
22
- <ColorPresets.Root defaultValue="#22c55e">
22
+ <ColorPresets.Root presets={ONE_ROW} columns={4} closeOnSelect={false} defaultValue="#22c55e">
23
23
  <ColorPresets.Trigger>
24
24
  <Button.Root variant="soft" tone="neutral">
25
25
  <Button.Icon>
@@ -1,22 +1,31 @@
1
- /** A disabled area and hue slider keep showing the color but take no input — `disabled`. */
1
+ /** A disabled area, hue slider and preset trigger keep showing the color but take no input — `disabled`. */
2
+ import { ColorPresets } from "prime-ui-kit";
2
3
  import { ColorPicker } from "prime-ui-kit/color-picker";
3
4
 
4
5
  import styles from "./examples.module.css";
5
6
 
6
7
  export default function ColorPickerStatesExample() {
7
8
  return (
8
- <ColorPicker.Root defaultValue="#30a46c">
9
- <ColorPicker.Panel className={styles.panel}>
10
- <ColorPicker.Area colorSpace="hsl" xChannel="saturation" yChannel="lightness" disabled>
11
- <ColorPicker.AreaThumb />
12
- </ColorPicker.Area>
13
- <ColorPicker.Slider channel="hue" colorSpace="hsl" disabled>
14
- <ColorPicker.SliderMeta label="disabled" />
15
- <ColorPicker.SliderTrack>
16
- <ColorPicker.Thumb />
17
- </ColorPicker.SliderTrack>
18
- </ColorPicker.Slider>
19
- </ColorPicker.Panel>
20
- </ColorPicker.Root>
9
+ <>
10
+ <ColorPicker.Root defaultValue="#30a46c">
11
+ <ColorPicker.Panel className={styles.panel}>
12
+ <ColorPicker.Area colorSpace="hsl" xChannel="saturation" yChannel="lightness" disabled>
13
+ <ColorPicker.AreaThumb />
14
+ </ColorPicker.Area>
15
+ <ColorPicker.Slider channel="hue" colorSpace="hsl" disabled>
16
+ <ColorPicker.SliderMeta label="disabled" />
17
+ <ColorPicker.SliderTrack>
18
+ <ColorPicker.Thumb />
19
+ </ColorPicker.SliderTrack>
20
+ </ColorPicker.Slider>
21
+ </ColorPicker.Panel>
22
+ </ColorPicker.Root>
23
+ <ColorPresets.Root disabled defaultValue="#22c55e" labels={{ trigger: "Цвет метки" }}>
24
+ <ColorPresets.Trigger>
25
+ <ColorPresets.SwatchButton />
26
+ </ColorPresets.Trigger>
27
+ <ColorPresets.Content />
28
+ </ColorPresets.Root>
29
+ </>
21
30
  );
22
31
  }
@@ -97,6 +97,7 @@ Controlled with `value` + `onValueChange`; uncontrolled with `defaultValue`.
97
97
 
98
98
  ## Layout & spacing
99
99
  - The swatches take the container width in equal columns: each one stretches across its column (the height stays the tier's). A row wraps only when they no longer fit, and then the swatches split evenly over the rows (16 → 8 + 8, never 14 + 2); no column count to set. In a content-sized container they stand in one row at the tier size.
100
+ - On a coarse pointer the swatches grow to the 44 px touch target (a dense grid cannot grow an invisible hit area past its neighbours) and wrap into more rows.
100
101
  - The keyboard focus ring sits outside the swatches; kit hosts (Modal / Drawer body, panels, cards) already keep `--prime-focus-space` padding, so the ring is never clipped. In your own `overflow` container, keep that padding.
101
102
  - Label → swatches and swatches → hint use the tier `label-gap` / `hint-gap`; field → field 20.
102
103
 
@@ -283,7 +283,8 @@ Motion: the tray opens and closes as a Crossfade (fade and height glide, the row
283
283
  |---|---|
284
284
  | [overview.tsx](examples/overview.tsx) | A reply to a client in a support chat: Enter sends, Shift+Enter breaks the line, the paperclip attaches files and an empty field records a voice message — `onSend`, `onSendVoice`, `queue`, `Composer.Attach`. |
285
285
  | [sizes.tsx](examples/sizes.tsx) | One composer in every tier: field, buttons and the paperclip follow it — `size`. |
286
- | [attachments.tsx](examples/attachments.tsx) | Warehouse photos and documents for a client go through an upload queue: the paperclip opens the file picker, a paste or a drop adds files too, every attachment is a tile of one strip that drags into its order, and send waits until the uploads finish — `queue`, `Composer.Attach`, `useUploadQueue`. |
286
+ | [attachments.tsx](examples/attachments.tsx) | Warehouse photos and documents for a client go through an upload queue: the paperclip opens the file picker for photos, videos and office documents, a paste or a drop adds files too, every attachment is a tile of one strip that drags into its order, and send waits until the uploads finish — `queue`, `Composer.Attach`, `accept`, `useUploadQueue`. |
287
+ | [attach-menu.tsx](examples/attach-menu.tsx) | The paperclip as a menu of attachment kinds: photos and videos, documents, any file, and an invoice from the system that puts its link into the message and returns the focus to the field — `Composer.Item`, `Composer.ItemIcon`, `accept`, `onSelect`, `inputRef`. |
287
288
  | [reply-edit.tsx](examples/reply-edit.tsx) | Answering a client's message and correcting your own: the bar above the field quotes the message, Escape or the cross cancels, ↑ in an empty field opens your last message, send becomes save and hands over the message id — `Composer.Context`, `mode`, `value`, `onDismiss`, `onEditLast`. |
288
289
  | [typing.tsx](examples/typing.tsx) | The other side's status line follows what you do: typing, recording a voice or a video message, then nothing — `onActivityChange`. |
289
290
  | [formatting.tsx](examples/formatting.tsx) | Selected text gets a toolbar of bold, italic, strikethrough, code, spoiler, link and quote, each with its shortcut, written as Markdown around the selection — `formatting`. |
@@ -0,0 +1,78 @@
1
+ /** The paperclip as a menu of attachment kinds: photos and videos, documents, any file, and an invoice from the system that puts its link into the message and returns the focus to the field — `Composer.Item`, `Composer.ItemIcon`, `accept`, `onSelect`, `inputRef`. */
2
+ import { Composer, Icon, type UploadContext, useUploadQueue } from "prime-ui-kit";
3
+ import * as React from "react";
4
+
5
+ import styles from "./examples.module.css";
6
+
7
+ const TICK_MS = 300;
8
+
9
+ const INVOICE_LINK = "Счёт INV-2051 на 184 000 ₽: https://prime.app/invoices/2051";
10
+
11
+ /** A stand-in for the file server: sends a file in a few steps. */
12
+ function sendFile(file: File, { signal, onProgress }: UploadContext): Promise<string> {
13
+ return new Promise((resolve, reject) => {
14
+ let sent = 0;
15
+ const timer = window.setInterval(() => {
16
+ sent = Math.min(1, sent + 0.25);
17
+ onProgress(sent);
18
+ if (sent < 1) return;
19
+ window.clearInterval(timer);
20
+ resolve(`https://files.example.com/chat/${encodeURIComponent(file.name)}`);
21
+ }, TICK_MS);
22
+ signal.addEventListener("abort", () => {
23
+ window.clearInterval(timer);
24
+ reject(signal.reason);
25
+ });
26
+ });
27
+ }
28
+
29
+ export default function ComposerAttachMenuExample() {
30
+ const queue = useUploadQueue({ upload: sendFile });
31
+ const [draft, setDraft] = React.useState("");
32
+ const inputRef = React.useRef<HTMLTextAreaElement>(null);
33
+
34
+ const attachInvoice = () => {
35
+ setDraft((current) => (current ? `${current}\n${INVOICE_LINK}` : INVOICE_LINK));
36
+ // The menu returns the focus to the paperclip; the reader goes on typing in the field.
37
+ window.requestAnimationFrame(() => inputRef.current?.focus());
38
+ };
39
+
40
+ return (
41
+ <div className={styles.chat}>
42
+ <Composer.Root
43
+ value={draft}
44
+ onValueChange={setDraft}
45
+ inputRef={inputRef}
46
+ queue={queue}
47
+ onSend={() => setDraft("")}
48
+ >
49
+ <Composer.Attach>
50
+ <Composer.Item accept="image/*,video/*">
51
+ <Composer.ItemIcon>
52
+ <Icon name="object.image" />
53
+ </Composer.ItemIcon>
54
+ Фото и видео
55
+ </Composer.Item>
56
+ <Composer.Item accept=".pdf,.docx,.xlsx">
57
+ <Composer.ItemIcon>
58
+ <Icon name="object.document" />
59
+ </Composer.ItemIcon>
60
+ Документ
61
+ </Composer.Item>
62
+ <Composer.Item accept="">
63
+ <Composer.ItemIcon>
64
+ <Icon name="object.file" />
65
+ </Composer.ItemIcon>
66
+ Любой файл
67
+ </Composer.Item>
68
+ <Composer.Item onSelect={attachInvoice}>
69
+ <Composer.ItemIcon>
70
+ <Icon name="object.receipt" />
71
+ </Composer.ItemIcon>
72
+ Счёт из системы
73
+ </Composer.Item>
74
+ </Composer.Attach>
75
+ </Composer.Root>
76
+ </div>
77
+ );
78
+ }
@@ -1,4 +1,4 @@
1
- /** Warehouse photos and documents for a client go through an upload queue: the paperclip opens the file picker, a paste or a drop adds files too, every attachment is a tile of one strip that drags into its order, and send waits until the uploads finish — `queue`, `Composer.Attach`, `useUploadQueue`. */
1
+ /** Warehouse photos and documents for a client go through an upload queue: the paperclip opens the file picker for photos, videos and office documents, a paste or a drop adds files too, every attachment is a tile of one strip that drags into its order, and send waits until the uploads finish — `queue`, `Composer.Attach`, `accept`, `useUploadQueue`. */
2
2
  import { Composer, type UploadContext, useUploadQueue } from "prime-ui-kit";
3
3
 
4
4
  import styles from "./examples.module.css";
@@ -29,7 +29,7 @@ export default function ComposerAttachmentsExample() {
29
29
  return (
30
30
  <div className={styles.chat}>
31
31
  <Composer.Root queue={queue} onSend={() => {}}>
32
- <Composer.Attach />
32
+ <Composer.Attach accept="image/*,video/*,.pdf,.docx,.xlsx" />
33
33
  </Composer.Root>
34
34
  </div>
35
35
  );
@@ -103,6 +103,7 @@ No `labels`.
103
103
  | [overview.tsx](examples/overview.tsx) | A card region that cross-fades between loading, data, empty and error and glides to the new height — `state`. |
104
104
  | [record-switch.tsx](examples/record-switch.tsx) | A detail panel keyed by the record id: picking another client cross-fades the details of a different height — `state`. |
105
105
  | [fill.tsx](examples/fill.tsx) | A deal board that fills its panel's height while it swaps between loading and data, and a notice slot above it that takes no room while empty — `fill`, `state`. |
106
+ | [screen.tsx](examples/screen.tsx) | Screen states: the title and the date of the statement in the app header, a page-level error in a Banner with a retry, a region loading with a Skeleton of its rows and a table skeleton, the table error in place and a first-run EmptyPage; regions cross-fade between states — `state`. |
106
107
 
107
108
  ## Mistakes
108
109
  - A new `state` on every data refresh (`state={Date.now()}`) → key by what the region shows, not by when it was fetched.
@@ -0,0 +1,40 @@
1
+ /* Screen states: the layout keeps its shape in every state, only the content of a region changes. */
2
+
3
+ /* The banner and the panels as one block with no gap of its own: the 24 under the banner (the body's
4
+ block gap) lives in its slot inside the Crossfade, so it arrives and leaves with the banner. */
5
+ .lead {
6
+ display: grid;
7
+ min-width: 0;
8
+ }
9
+
10
+ .bannerSlot {
11
+ padding-block-end: var(--prime-space-6);
12
+ }
13
+
14
+ /* Skeleton rows mirror the account rows, so the card keeps its height when data arrives. */
15
+ .nameBar {
16
+ width: 50%;
17
+ }
18
+
19
+ .balanceBar {
20
+ width: 35%;
21
+ }
22
+
23
+ /* The card stretches to its neighbour's height: rows stay at the top. */
24
+ .accounts {
25
+ display: grid;
26
+ align-content: start;
27
+ gap: var(--prime-space-4);
28
+ margin: 0;
29
+ padding: 0;
30
+ list-style: none;
31
+ }
32
+
33
+ .account {
34
+ display: grid;
35
+ gap: var(--prime-space-1);
36
+ }
37
+
38
+ .amount {
39
+ font-variant-numeric: tabular-nums;
40
+ }