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
@@ -0,0 +1,646 @@
1
+ /** A media library of a catalog object as a work screen: the title, the object and a PageToolbar with sections, search, order and upload in the app header; uploads in FileUpload tiles through a queue; a grid of Thumbnails that open MediaViewer out of the tile or are picked for bulk download and delete; a Skeleton first load and a filtered empty state in a Crossfade — `trigger`, `layout`. */
2
+ import {
3
+ AppHeader,
4
+ Button,
5
+ ConfirmDialog,
6
+ Crossfade,
7
+ EmptyPage,
8
+ FileUpload,
9
+ formatFileSize,
10
+ Icon,
11
+ MediaViewer,
12
+ type MediaViewerItem,
13
+ PageContent,
14
+ PageToolbar,
15
+ SegmentedControl,
16
+ Select,
17
+ Skeleton,
18
+ SmartFilter,
19
+ Thumbnail,
20
+ Typography,
21
+ type UploadContext,
22
+ type UploadItem,
23
+ useNotifications,
24
+ useUploadQueue,
25
+ } from "prime-ui-kit";
26
+ import * as React from "react";
27
+
28
+ import styles from "./screen.module.css";
29
+
30
+ type Kind = "photo" | "video" | "document";
31
+ type Section = "all" | Kind;
32
+ type Order = "new" | "old" | "name";
33
+
34
+ type Media = {
35
+ id: string;
36
+ kind: Kind;
37
+ name: string;
38
+ /** The full file: the picture, the video or the scan the viewer shows. */
39
+ src: string;
40
+ /** A small copy for the grid; the viewer shows it at once while `src` loads. */
41
+ thumbnail?: string;
42
+ width?: number;
43
+ height?: number;
44
+ size: number;
45
+ added: string;
46
+ };
47
+
48
+ const CLIP = "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4";
49
+
50
+ const photo = (seed: string): Pick<Media, "src" | "thumbnail" | "width" | "height"> => ({
51
+ src: `https://picsum.photos/seed/tower-${seed}/1600/1200`,
52
+ thumbnail: `https://picsum.photos/seed/tower-${seed}/480/360`,
53
+ width: 1600,
54
+ height: 1200,
55
+ });
56
+
57
+ const scan = (seed: string): Pick<Media, "src" | "thumbnail" | "width" | "height"> => ({
58
+ src: `https://picsum.photos/seed/tower-${seed}/1240/1754`,
59
+ thumbnail: `https://picsum.photos/seed/tower-${seed}/360/510`,
60
+ width: 1240,
61
+ height: 1754,
62
+ });
63
+
64
+ /** What the server returns for the object's library. */
65
+ const LIBRARY: Media[] = [
66
+ {
67
+ id: "m01",
68
+ kind: "photo",
69
+ name: "Фасад с Невского.jpg",
70
+ size: 2_480_000,
71
+ added: "2026-10-09",
72
+ ...photo("facade"),
73
+ },
74
+ {
75
+ id: "m02",
76
+ kind: "photo",
77
+ name: "Входная группа.jpg",
78
+ size: 1_960_000,
79
+ added: "2026-10-09",
80
+ ...photo("entrance"),
81
+ },
82
+ {
83
+ id: "m03",
84
+ kind: "video",
85
+ name: "Обход этажа 7.mp4",
86
+ size: 48_200_000,
87
+ added: "2026-10-08",
88
+ src: CLIP,
89
+ width: 1280,
90
+ height: 720,
91
+ },
92
+ {
93
+ id: "m04",
94
+ kind: "photo",
95
+ name: "Лобби и ресепшен.jpg",
96
+ size: 2_120_000,
97
+ added: "2026-10-07",
98
+ ...photo("lobby"),
99
+ },
100
+ {
101
+ id: "m05",
102
+ kind: "photo",
103
+ name: "Опенспейс, этаж 7.jpg",
104
+ size: 2_730_000,
105
+ added: "2026-10-07",
106
+ ...photo("openspace"),
107
+ },
108
+ {
109
+ id: "m06",
110
+ kind: "document",
111
+ name: "Поэтажный план.jpg",
112
+ size: 860_000,
113
+ added: "2026-10-06",
114
+ ...scan("plan"),
115
+ },
116
+ {
117
+ id: "m07",
118
+ kind: "photo",
119
+ name: "Переговорная «Нева».jpg",
120
+ size: 1_840_000,
121
+ added: "2026-10-05",
122
+ ...photo("meeting"),
123
+ },
124
+ {
125
+ id: "m08",
126
+ kind: "video",
127
+ name: "Подъезд к парковке.mp4",
128
+ size: 31_500_000,
129
+ added: "2026-10-04",
130
+ src: CLIP,
131
+ width: 1280,
132
+ height: 720,
133
+ },
134
+ {
135
+ id: "m09",
136
+ kind: "photo",
137
+ name: "Терраса на крыше.jpg",
138
+ size: 3_050_000,
139
+ added: "2026-10-03",
140
+ ...photo("terrace"),
141
+ },
142
+ {
143
+ id: "m10",
144
+ kind: "document",
145
+ name: "Выписка из ЕГРН.jpg",
146
+ size: 640_000,
147
+ added: "2026-10-02",
148
+ ...scan("egrn"),
149
+ },
150
+ {
151
+ id: "m11",
152
+ kind: "photo",
153
+ name: "Паркинг, уровень −1.jpg",
154
+ size: 1_720_000,
155
+ added: "2026-09-30",
156
+ ...photo("parking"),
157
+ },
158
+ {
159
+ id: "m12",
160
+ kind: "document",
161
+ name: "Техпаспорт, стр. 1.jpg",
162
+ size: 720_000,
163
+ added: "2026-09-28",
164
+ ...scan("passport"),
165
+ },
166
+ ];
167
+
168
+ const SECTIONS: { value: Section; label: string }[] = [
169
+ { value: "all", label: "Все" },
170
+ { value: "photo", label: "Фото" },
171
+ { value: "video", label: "Видео" },
172
+ { value: "document", label: "Документы" },
173
+ ];
174
+
175
+ const ORDERS: { value: Order; label: string }[] = [
176
+ { value: "new", label: "Сначала новые" },
177
+ { value: "old", label: "Сначала старые" },
178
+ { value: "name", label: "По названию" },
179
+ ];
180
+
181
+ const FALLBACK_ICON = {
182
+ photo: "object.image",
183
+ video: "action.video",
184
+ document: "object.document",
185
+ } as const;
186
+
187
+ /** Placeholder tiles of the first load: the grid's own geometry. */
188
+ const PLACEHOLDER_TILES = ["p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8"];
189
+
190
+ /** How long a finished upload keeps its tile, so its ring fills and the disk fades before it moves. */
191
+ const DONE_HOLD_MS = 900;
192
+
193
+ const DAY = new Intl.DateTimeFormat("ru-RU", { day: "numeric", month: "short" });
194
+
195
+ const filesWord = (count: number) => {
196
+ const tens = count % 100;
197
+ const units = count % 10;
198
+ if (tens >= 11 && tens <= 14) return "файлов";
199
+ if (units === 1) return "файл";
200
+ if (units >= 2 && units <= 4) return "файла";
201
+ return "файлов";
202
+ };
203
+
204
+ const today = () => new Date().toISOString().slice(0, 10);
205
+
206
+ /** Upload attempts per file, and how many files have started: the stand-in drops every third one once. */
207
+ const attempts = new WeakMap<File, number>();
208
+ let started = 0;
209
+
210
+ /** A stand-in for the server: sends the file in steps and answers with its address (a local URL here). */
211
+ function sendFile(file: File, { signal, onProgress }: UploadContext): Promise<string> {
212
+ const attempt = (attempts.get(file) ?? 0) + 1;
213
+ attempts.set(file, attempt);
214
+ if (attempt === 1) started += 1;
215
+ const flaky = attempt === 1 && started % 3 === 0;
216
+ return new Promise((resolve, reject) => {
217
+ let sent = 0;
218
+ const timer = window.setInterval(() => {
219
+ sent = Math.min(1, sent + 0.08 + Math.random() * 0.1);
220
+ if (flaky && sent > 0.5) {
221
+ window.clearInterval(timer);
222
+ reject(new Error("Нет связи с сервером"));
223
+ return;
224
+ }
225
+ onProgress(sent);
226
+ if (sent < 1) return;
227
+ window.clearInterval(timer);
228
+ resolve(URL.createObjectURL(file));
229
+ }, 350);
230
+ signal.addEventListener("abort", () => {
231
+ window.clearInterval(timer);
232
+ reject(signal.reason);
233
+ });
234
+ });
235
+ }
236
+
237
+ /** A finished upload as a file of the library. */
238
+ const toMedia = (item: UploadItem<string>): Media => ({
239
+ id: item.id,
240
+ kind: item.file.type.startsWith("video/") ? "video" : "photo",
241
+ name: item.file.name,
242
+ src: item.result ?? "",
243
+ size: item.file.size,
244
+ added: today(),
245
+ });
246
+
247
+ const toViewerItem = (media: Media): MediaViewerItem => ({
248
+ type: media.kind === "video" ? "video" : "image",
249
+ src: media.src,
250
+ thumbnail: media.thumbnail,
251
+ width: media.width,
252
+ height: media.height,
253
+ alt: media.name,
254
+ caption: `${media.name} · ${formatFileSize(media.size)} · ${DAY.format(new Date(media.added))}`,
255
+ });
256
+
257
+ export default function FileUploadScreenExample() {
258
+ const { notify } = useNotifications();
259
+ const [loading, setLoading] = React.useState(true);
260
+ const [library, setLibrary] = React.useState<Media[]>([]);
261
+ const [section, setSection] = React.useState<Section>("all");
262
+ const [search, setSearch] = React.useState("");
263
+ const [order, setOrder] = React.useState<Order>("new");
264
+ const [selecting, setSelecting] = React.useState(false);
265
+ const [selected, setSelected] = React.useState<ReadonlySet<string>>(new Set());
266
+ const [open, setOpen] = React.useState(false);
267
+ const [index, setIndex] = React.useState(0);
268
+
269
+ const queue = useUploadQueue({ upload: sendFile, concurrency: 2 });
270
+ const inputRef = React.useRef<HTMLInputElement>(null);
271
+ const tiles = React.useRef(new Map<string, HTMLElement>());
272
+ const moving = React.useRef(new Set<string>());
273
+
274
+ // First load: the server answers after a moment; the grid holds its shape meanwhile.
275
+ React.useEffect(() => {
276
+ const timer = window.setTimeout(() => {
277
+ setLibrary(LIBRARY);
278
+ setLoading(false);
279
+ }, 1200);
280
+ return () => window.clearTimeout(timer);
281
+ }, []);
282
+
283
+ // A finished upload leaves its tile for the library, first in it.
284
+ const { items: uploads, remove: removeUpload } = queue;
285
+ React.useEffect(() => {
286
+ for (const item of uploads) {
287
+ if (item.status !== "done" || moving.current.has(item.id)) continue;
288
+ moving.current.add(item.id);
289
+ window.setTimeout(() => {
290
+ setLibrary((current) => [toMedia(item), ...current]);
291
+ removeUpload(item.id);
292
+ }, DONE_HOLD_MS);
293
+ }
294
+ }, [uploads, removeUpload]);
295
+
296
+ const query = search.trim().toLowerCase();
297
+ const visible = library
298
+ .filter(
299
+ (media) =>
300
+ (section === "all" || media.kind === section) && media.name.toLowerCase().includes(query),
301
+ )
302
+ .sort((a, b) => {
303
+ if (order === "name") return a.name.localeCompare(b.name, "ru");
304
+ const byDate = a.added.localeCompare(b.added);
305
+ return order === "new" ? -byDate : byDate;
306
+ });
307
+ const viewerItems = visible.map(toViewerItem);
308
+ const count = (value: Section) =>
309
+ value === "all" ? library.length : library.filter((media) => media.kind === value).length;
310
+
311
+ const state = loading
312
+ ? "loading"
313
+ : visible.length > 0
314
+ ? `ready:${section}:${order}`
315
+ : library.length > 0
316
+ ? "nothing"
317
+ : "empty";
318
+
319
+ const toggle = (id: string, checked: boolean) =>
320
+ setSelected((current) => {
321
+ const next = new Set(current);
322
+ if (checked) next.add(id);
323
+ else next.delete(id);
324
+ return next;
325
+ });
326
+
327
+ const stopSelecting = () => {
328
+ setSelecting(false);
329
+ setSelected(new Set());
330
+ };
331
+
332
+ const resetFilters = () => {
333
+ setSection("all");
334
+ setSearch("");
335
+ };
336
+
337
+ const download = () => {
338
+ notify({
339
+ tone: "success",
340
+ title: `Скачиваем ${selected.size} ${filesWord(selected.size)}`,
341
+ description: "Архив сохранится в папку загрузок.",
342
+ });
343
+ stopSelecting();
344
+ };
345
+
346
+ // A stand-in for the delete request: the dialog stays busy until it answers.
347
+ const removeSelected = () =>
348
+ new Promise<void>((resolve) => window.setTimeout(resolve, 800)).then(() => {
349
+ const removed = selected.size;
350
+ for (const media of library) {
351
+ if (selected.has(media.id) && media.src.startsWith("blob:")) URL.revokeObjectURL(media.src);
352
+ }
353
+ setLibrary((current) => current.filter((media) => !selected.has(media.id)));
354
+ stopSelecting();
355
+ notify({ tone: "success", title: `Удалено: ${removed} ${filesWord(removed)}` });
356
+ });
357
+
358
+ const openAt = (at: number) => {
359
+ setIndex(at);
360
+ setOpen(true);
361
+ };
362
+
363
+ const totalSize = visible.reduce((sum, media) => sum + media.size, 0);
364
+
365
+ return (
366
+ <>
367
+ {/* A work screen: in an app this header fills the shell's `header` slot and carries the page —
368
+ the only h1, the object it belongs to and the page's tools; main has no PageContent.Header. */}
369
+ <AppHeader.Root>
370
+ <AppHeader.Start>
371
+ <AppHeader.Title>
372
+ Медиатека
373
+ <AppHeader.Description>БЦ «Северная башня», Невский пр., 112</AppHeader.Description>
374
+ </AppHeader.Title>
375
+ </AppHeader.Start>
376
+ <AppHeader.Tools>
377
+ <SmartFilter.Root
378
+ fields={[]}
379
+ search={search}
380
+ onSearchChange={setSearch}
381
+ labels={{ searchPlaceholder: "Поиск по названию" }}
382
+ >
383
+ <PageToolbar.Root aria-label="Медиатека">
384
+ <PageToolbar.Tools>
385
+ <SmartFilter.Toolbar />
386
+ </PageToolbar.Tools>
387
+ <PageToolbar.Sections>
388
+ <SegmentedControl.Root
389
+ fullWidth
390
+ value={section}
391
+ onValueChange={(value) => setSection(value as Section)}
392
+ aria-label="Раздел"
393
+ >
394
+ {SECTIONS.map((item) => (
395
+ <SegmentedControl.Item key={item.value} value={item.value}>
396
+ {item.label}
397
+ {loading ? null : (
398
+ <SegmentedControl.Count>{count(item.value)}</SegmentedControl.Count>
399
+ )}
400
+ </SegmentedControl.Item>
401
+ ))}
402
+ </SegmentedControl.Root>
403
+ </PageToolbar.Sections>
404
+ <PageToolbar.View>
405
+ <Select.Root value={order} onValueChange={(value) => setOrder(value as Order)}>
406
+ <Select.Trigger aria-label="Порядок">
407
+ <Select.TriggerIcon>
408
+ <Icon name="sort.descending" />
409
+ </Select.TriggerIcon>
410
+ <Select.Value />
411
+ </Select.Trigger>
412
+ <Select.Content>
413
+ {ORDERS.map((item) => (
414
+ <Select.Item key={item.value} value={item.value}>
415
+ {item.label}
416
+ </Select.Item>
417
+ ))}
418
+ </Select.Content>
419
+ </Select.Root>
420
+ </PageToolbar.View>
421
+ <PageToolbar.Actions>
422
+ <Button.Root onClick={() => inputRef.current?.click()}>
423
+ <Button.Icon>
424
+ <Icon name="action.upload" />
425
+ </Button.Icon>
426
+ Загрузить
427
+ </Button.Root>
428
+ </PageToolbar.Actions>
429
+ </PageToolbar.Root>
430
+ </SmartFilter.Root>
431
+ </AppHeader.Tools>
432
+ </AppHeader.Root>
433
+
434
+ <PageContent.Root>
435
+ <PageContent.Body>
436
+ {/* Uploads in flight: the add tile is also the drop zone; a done file moves into the grid. */}
437
+ <FileUpload.Root
438
+ label="Новые файлы"
439
+ hint="Фото и видео до 200 МБ. Загруженные появятся в медиатеке первыми."
440
+ trigger="tile"
441
+ layout="grid"
442
+ accept="image/*,video/*"
443
+ multiple
444
+ queue={queue}
445
+ inputRef={inputRef}
446
+ />
447
+
448
+ <PageContent.Section
449
+ label="Файлы"
450
+ description={
451
+ <span aria-live="polite">
452
+ {selecting
453
+ ? `Выбрано: ${selected.size}`
454
+ : loading
455
+ ? "Загружаем…"
456
+ : `${visible.length} ${filesWord(visible.length)} · ${formatFileSize(totalSize)}`}
457
+ </span>
458
+ }
459
+ >
460
+ <PageContent.Actions>
461
+ <Crossfade state={selecting ? "select" : "browse"}>
462
+ {selecting ? (
463
+ <div className={styles.bar}>
464
+ <Button.Root
465
+ variant="soft"
466
+ tone="neutral"
467
+ disabled={selected.size === 0}
468
+ onClick={download}
469
+ >
470
+ <Button.Icon>
471
+ <Icon name="action.download" />
472
+ </Button.Icon>
473
+ Скачать
474
+ </Button.Root>
475
+ <ConfirmDialog.Root
476
+ title={`Удалить ${selected.size} ${filesWord(selected.size)}?`}
477
+ description="Файлы пропадут из карточки объекта в каталоге. Восстановить их будет нельзя."
478
+ confirmLabel="Удалить"
479
+ onConfirm={removeSelected}
480
+ >
481
+ <ConfirmDialog.Trigger>
482
+ <Button.Root variant="outline" tone="danger" disabled={selected.size === 0}>
483
+ <Button.Icon>
484
+ <Icon name="action.delete" />
485
+ </Button.Icon>
486
+ Удалить
487
+ </Button.Root>
488
+ </ConfirmDialog.Trigger>
489
+ </ConfirmDialog.Root>
490
+ <Button.Root variant="ghost" tone="neutral" onClick={stopSelecting}>
491
+ Отмена
492
+ </Button.Root>
493
+ </div>
494
+ ) : (
495
+ <div className={styles.bar}>
496
+ <Button.Root
497
+ variant="soft"
498
+ tone="neutral"
499
+ disabled={loading || visible.length === 0}
500
+ onClick={() => setSelecting(true)}
501
+ >
502
+ <Button.Icon>
503
+ <Icon name="action.check" />
504
+ </Button.Icon>
505
+ Выбрать
506
+ </Button.Root>
507
+ </div>
508
+ )}
509
+ </Crossfade>
510
+ </PageContent.Actions>
511
+
512
+ <Crossfade state={state} aria-busy={loading}>
513
+ {loading ? (
514
+ <ul className={styles.grid}>
515
+ {PLACEHOLDER_TILES.map((key) => (
516
+ <li key={key} className={styles.tile}>
517
+ <Skeleton shape="block" className={styles.picture} />
518
+ <div className={styles.tileText}>
519
+ <Skeleton size="s" className={styles.nameBar} />
520
+ <Skeleton size="xs" className={styles.metaBar} />
521
+ </div>
522
+ </li>
523
+ ))}
524
+ </ul>
525
+ ) : null}
526
+
527
+ {state.startsWith("ready") ? (
528
+ <ul className={styles.grid}>
529
+ {visible.map((media, at) => {
530
+ const picture =
531
+ media.kind === "video" ? (
532
+ <Thumbnail.Video src={media.src} aria-label={media.name} />
533
+ ) : (
534
+ <Thumbnail.Image
535
+ src={media.thumbnail ?? media.src}
536
+ fit={media.kind === "document" ? "contain" : "cover"}
537
+ />
538
+ );
539
+ const fallback = (
540
+ <Thumbnail.Fallback>
541
+ <Icon name={FALLBACK_ICON[media.kind]} />
542
+ </Thumbnail.Fallback>
543
+ );
544
+ return (
545
+ <li key={media.id} className={styles.tile}>
546
+ {/* Browsing, a press opens the viewer out of the tile; selecting, it picks the file. */}
547
+ {selecting ? (
548
+ <Thumbnail.Root
549
+ fullWidth
550
+ ratio="4:3"
551
+ aria-label={media.name}
552
+ checked={selected.has(media.id)}
553
+ onCheckedChange={(checked) => toggle(media.id, checked)}
554
+ >
555
+ {picture}
556
+ {fallback}
557
+ </Thumbnail.Root>
558
+ ) : (
559
+ <Thumbnail.Root asChild fullWidth ratio="4:3">
560
+ <button
561
+ ref={(node) => {
562
+ if (node) tiles.current.set(media.id, node);
563
+ else tiles.current.delete(media.id);
564
+ }}
565
+ type="button"
566
+ aria-label={`Открыть: ${media.name}`}
567
+ aria-haspopup="dialog"
568
+ onClick={() => openAt(at)}
569
+ >
570
+ {picture}
571
+ {fallback}
572
+ </button>
573
+ </Thumbnail.Root>
574
+ )}
575
+ <div className={styles.tileText}>
576
+ <Typography as="span" variant="body-s" truncate title={media.name}>
577
+ {media.name}
578
+ </Typography>
579
+ <Typography as="span" variant="caption" tone="muted">
580
+ {formatFileSize(media.size)} · {DAY.format(new Date(media.added))}
581
+ </Typography>
582
+ </div>
583
+ </li>
584
+ );
585
+ })}
586
+ </ul>
587
+ ) : null}
588
+
589
+ {state === "nothing" ? (
590
+ <EmptyPage.Root size="s" role="status" aria-labelledby="media-nothing">
591
+ <EmptyPage.Icon>
592
+ <Icon name="action.search" />
593
+ </EmptyPage.Icon>
594
+ <EmptyPage.Title as="h3" id="media-nothing">
595
+ Ничего не найдено
596
+ </EmptyPage.Title>
597
+ <EmptyPage.Description>
598
+ В этом разделе нет файлов с таким названием.
599
+ </EmptyPage.Description>
600
+ <EmptyPage.Actions>
601
+ <Button.Root variant="soft" tone="neutral" onClick={resetFilters}>
602
+ Показать все файлы
603
+ </Button.Root>
604
+ </EmptyPage.Actions>
605
+ </EmptyPage.Root>
606
+ ) : null}
607
+
608
+ {state === "empty" ? (
609
+ <EmptyPage.Root size="s" aria-labelledby="media-empty">
610
+ <EmptyPage.Icon tone="accent">
611
+ <Icon name="object.image" />
612
+ </EmptyPage.Icon>
613
+ <EmptyPage.Title as="h3" id="media-empty">
614
+ Файлов пока нет
615
+ </EmptyPage.Title>
616
+ <EmptyPage.Description>
617
+ Перетащите фото и видео объекта в поле выше или нажмите «Загрузить».
618
+ </EmptyPage.Description>
619
+ </EmptyPage.Root>
620
+ ) : null}
621
+ </Crossfade>
622
+ </PageContent.Section>
623
+
624
+ <MediaViewer
625
+ items={viewerItems}
626
+ open={open}
627
+ onOpenChange={setOpen}
628
+ index={index}
629
+ onIndexChange={setIndex}
630
+ getOrigin={(at) => tiles.current.get(visible[at]?.id ?? "") ?? null}
631
+ thumbnails
632
+ renderActions={(item) => (
633
+ <Button.Root shape="circle" variant="shade" aria-label="Скачать файл" asChild>
634
+ <a href={item.src} download>
635
+ <Button.Icon>
636
+ <Icon name="action.download" />
637
+ </Button.Icon>
638
+ </a>
639
+ </Button.Root>
640
+ )}
641
+ />
642
+ </PageContent.Body>
643
+ </PageContent.Root>
644
+ </>
645
+ );
646
+ }
@@ -3,6 +3,9 @@ import { FileUpload, type FileUploadFile } from "prime-ui-kit";
3
3
 
4
4
  import styles from "./examples.module.css";
5
5
 
6
+ /** The zone names the formats the order takes. */
7
+ const ZONE_LABELS = { description: "PDF или PNG до 20 МБ" };
8
+
6
9
  const ACT: readonly FileUploadFile[] = [
7
10
  { id: "act", name: "Акт сверки.pdf", size: 310_000, type: "application/pdf" },
8
11
  ];
@@ -10,14 +13,15 @@ const ACT: readonly FileUploadFile[] = [
10
13
  export default function FileUploadStatesExample() {
11
14
  return (
12
15
  <div className={styles.column}>
13
- <FileUpload.Root label="default" hint="PDF или PNG до 20 МБ" />
16
+ <FileUpload.Root label="default" labels={ZONE_LABELS} />
14
17
  <FileUpload.Root
15
18
  label="disabled"
16
19
  disabled
20
+ labels={ZONE_LABELS}
17
21
  defaultValue={ACT}
18
22
  hint="Заказ закрыт, документы только для просмотра"
19
23
  />
20
- <FileUpload.Root label="invalid" invalid hint="PDF или PNG до 20 МБ" />
24
+ <FileUpload.Root label="invalid" invalid labels={ZONE_LABELS} />
21
25
  </div>
22
26
  );
23
27
  }