prime-ui-kit 0.9.3 → 0.10.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 (567) hide show
  1. package/README.md +9 -4
  2. package/THIRD_PARTY_NOTICES +76 -0
  3. package/dist/chunks/{chunk-6JTZOA5I.js → chunk-4TRNUP45.js} +534 -522
  4. package/dist/chunks/chunk-EJ2ZVQYL.js +5805 -0
  5. package/dist/chunks/chunk-GFKDZFQR.js +1208 -0
  6. package/dist/chunks/{chunk-OAE4IQX2.js → chunk-K4FACFQ2.js} +8 -6
  7. package/dist/chunks/{chunk-U5SR2LZR.js → chunk-T7CLQXGB.js} +4 -2
  8. package/dist/color-picker.js +3 -2
  9. package/dist/components/button/Button.d.ts +5 -2
  10. package/dist/icon-set.d.ts +501 -0
  11. package/dist/icons/Icon.d.ts +10 -18
  12. package/dist/icons/glyph.d.ts +40 -0
  13. package/dist/icons/glyphs/a-arrow-down.d.ts +2 -0
  14. package/dist/icons/glyphs/a-arrow-up.d.ts +2 -0
  15. package/dist/icons/glyphs/accessibility.d.ts +2 -0
  16. package/dist/icons/glyphs/activity.d.ts +2 -0
  17. package/dist/icons/glyphs/air-vent.d.ts +2 -0
  18. package/dist/icons/glyphs/airplay.d.ts +2 -0
  19. package/dist/icons/glyphs/alarm-clock-check.d.ts +2 -0
  20. package/dist/icons/glyphs/alarm-clock-minus.d.ts +2 -0
  21. package/dist/icons/glyphs/alarm-clock-plus.d.ts +2 -0
  22. package/dist/icons/glyphs/alarm-clock.d.ts +2 -0
  23. package/dist/icons/glyphs/alarm-smoke.d.ts +2 -0
  24. package/dist/icons/glyphs/align-horizontal-space-around.d.ts +2 -0
  25. package/dist/icons/glyphs/align-vertical-space-around.d.ts +2 -0
  26. package/dist/icons/glyphs/ambulance.d.ts +2 -0
  27. package/dist/icons/glyphs/angry.d.ts +2 -0
  28. package/dist/icons/glyphs/annoyed.d.ts +2 -0
  29. package/dist/icons/glyphs/archive.d.ts +2 -0
  30. package/dist/icons/glyphs/arrow-big-down-dash.d.ts +2 -0
  31. package/dist/icons/glyphs/arrow-big-down.d.ts +2 -0
  32. package/dist/icons/glyphs/arrow-big-left-dash.d.ts +2 -0
  33. package/dist/icons/glyphs/arrow-big-left.d.ts +2 -0
  34. package/dist/icons/glyphs/arrow-big-right-dash.d.ts +2 -0
  35. package/dist/icons/glyphs/arrow-big-right.d.ts +2 -0
  36. package/dist/icons/glyphs/arrow-big-up-dash.d.ts +2 -0
  37. package/dist/icons/glyphs/arrow-big-up.d.ts +2 -0
  38. package/dist/icons/glyphs/arrow-down-0-1.d.ts +2 -0
  39. package/dist/icons/glyphs/arrow-down-1-0.d.ts +2 -0
  40. package/dist/icons/glyphs/arrow-down-a-z.d.ts +2 -0
  41. package/dist/icons/glyphs/arrow-down-left.d.ts +2 -0
  42. package/dist/icons/glyphs/arrow-down-right.d.ts +2 -0
  43. package/dist/icons/glyphs/arrow-down-z-a.d.ts +2 -0
  44. package/dist/icons/glyphs/arrow-down.d.ts +2 -0
  45. package/dist/icons/glyphs/arrow-left.d.ts +2 -0
  46. package/dist/icons/glyphs/arrow-right.d.ts +2 -0
  47. package/dist/icons/glyphs/arrow-up-down.d.ts +2 -0
  48. package/dist/icons/glyphs/arrow-up-left.d.ts +2 -0
  49. package/dist/icons/glyphs/arrow-up-right.d.ts +2 -0
  50. package/dist/icons/glyphs/arrow-up.d.ts +2 -0
  51. package/dist/icons/glyphs/at-sign.d.ts +2 -0
  52. package/dist/icons/glyphs/atom.d.ts +2 -0
  53. package/dist/icons/glyphs/audio-lines.d.ts +2 -0
  54. package/dist/icons/glyphs/axe.d.ts +2 -0
  55. package/dist/icons/glyphs/badge-alert.d.ts +2 -0
  56. package/dist/icons/glyphs/badge-percent.d.ts +2 -0
  57. package/dist/icons/glyphs/ban.d.ts +2 -0
  58. package/dist/icons/glyphs/banana.d.ts +2 -0
  59. package/dist/icons/glyphs/battery-charging.d.ts +2 -0
  60. package/dist/icons/glyphs/battery-full.d.ts +2 -0
  61. package/dist/icons/glyphs/battery-low.d.ts +2 -0
  62. package/dist/icons/glyphs/battery-medium.d.ts +2 -0
  63. package/dist/icons/glyphs/battery-plus.d.ts +2 -0
  64. package/dist/icons/glyphs/battery-warning.d.ts +2 -0
  65. package/dist/icons/glyphs/battery.d.ts +2 -0
  66. package/dist/icons/glyphs/bell-electric.d.ts +2 -0
  67. package/dist/icons/glyphs/bell.d.ts +2 -0
  68. package/dist/icons/glyphs/biceps-flexed.d.ts +2 -0
  69. package/dist/icons/glyphs/binary.d.ts +2 -0
  70. package/dist/icons/glyphs/blocks.d.ts +2 -0
  71. package/dist/icons/glyphs/bluetooth-connected.d.ts +2 -0
  72. package/dist/icons/glyphs/bluetooth-off.d.ts +2 -0
  73. package/dist/icons/glyphs/bluetooth-searching.d.ts +2 -0
  74. package/dist/icons/glyphs/bluetooth.d.ts +2 -0
  75. package/dist/icons/glyphs/bold.d.ts +2 -0
  76. package/dist/icons/glyphs/bone.d.ts +2 -0
  77. package/dist/icons/glyphs/book-open.d.ts +2 -0
  78. package/dist/icons/glyphs/book-text.d.ts +2 -0
  79. package/dist/icons/glyphs/bookmark-check.d.ts +2 -0
  80. package/dist/icons/glyphs/bookmark-minus.d.ts +2 -0
  81. package/dist/icons/glyphs/bookmark-plus.d.ts +2 -0
  82. package/dist/icons/glyphs/bookmark-x.d.ts +2 -0
  83. package/dist/icons/glyphs/bookmark.d.ts +2 -0
  84. package/dist/icons/glyphs/bot-message-square.d.ts +2 -0
  85. package/dist/icons/glyphs/bot.d.ts +2 -0
  86. package/dist/icons/glyphs/box.d.ts +2 -0
  87. package/dist/icons/glyphs/boxes.d.ts +2 -0
  88. package/dist/icons/glyphs/brain.d.ts +2 -0
  89. package/dist/icons/glyphs/briefcase-business.d.ts +2 -0
  90. package/dist/icons/glyphs/calendar-check-2.d.ts +2 -0
  91. package/dist/icons/glyphs/calendar-check.d.ts +2 -0
  92. package/dist/icons/glyphs/calendar-cog.d.ts +2 -0
  93. package/dist/icons/glyphs/calendar-days.d.ts +2 -0
  94. package/dist/icons/glyphs/calendar.d.ts +2 -0
  95. package/dist/icons/glyphs/car.d.ts +2 -0
  96. package/dist/icons/glyphs/cast.d.ts +2 -0
  97. package/dist/icons/glyphs/cctv.d.ts +2 -0
  98. package/dist/icons/glyphs/chart-bar-decreasing.d.ts +2 -0
  99. package/dist/icons/glyphs/chart-bar-increasing.d.ts +2 -0
  100. package/dist/icons/glyphs/chart-column-decreasing.d.ts +2 -0
  101. package/dist/icons/glyphs/chart-column-increasing.d.ts +2 -0
  102. package/dist/icons/glyphs/chart-column.d.ts +2 -0
  103. package/dist/icons/glyphs/chart-line.d.ts +2 -0
  104. package/dist/icons/glyphs/chart-no-axes-column-decreasing.d.ts +2 -0
  105. package/dist/icons/glyphs/chart-no-axes-column-increasing.d.ts +2 -0
  106. package/dist/icons/glyphs/chart-pie.d.ts +2 -0
  107. package/dist/icons/glyphs/chart-scatter.d.ts +2 -0
  108. package/dist/icons/glyphs/chart-spline.d.ts +2 -0
  109. package/dist/icons/glyphs/check-check.d.ts +2 -0
  110. package/dist/icons/glyphs/check.d.ts +2 -0
  111. package/dist/icons/glyphs/chess-bishop.d.ts +2 -0
  112. package/dist/icons/glyphs/chess-king.d.ts +2 -0
  113. package/dist/icons/glyphs/chess-knight.d.ts +2 -0
  114. package/dist/icons/glyphs/chess-pawn.d.ts +2 -0
  115. package/dist/icons/glyphs/chevron-down.d.ts +2 -0
  116. package/dist/icons/glyphs/chevron-first.d.ts +2 -0
  117. package/dist/icons/glyphs/chevron-left.d.ts +2 -0
  118. package/dist/icons/glyphs/chevron-right.d.ts +2 -0
  119. package/dist/icons/glyphs/chevron-up.d.ts +2 -0
  120. package/dist/icons/glyphs/chevrons-down-up.d.ts +2 -0
  121. package/dist/icons/glyphs/chevrons-left-right.d.ts +2 -0
  122. package/dist/icons/glyphs/chevrons-left.d.ts +2 -0
  123. package/dist/icons/glyphs/chevrons-right-left.d.ts +2 -0
  124. package/dist/icons/glyphs/chevrons-up-down.d.ts +2 -0
  125. package/dist/icons/glyphs/chromium.d.ts +2 -0
  126. package/dist/icons/glyphs/cigarette-off.d.ts +2 -0
  127. package/dist/icons/glyphs/cigarette.d.ts +2 -0
  128. package/dist/icons/glyphs/circle-check.d.ts +2 -0
  129. package/dist/icons/glyphs/circle-chevron-down.d.ts +2 -0
  130. package/dist/icons/glyphs/circle-chevron-left.d.ts +2 -0
  131. package/dist/icons/glyphs/circle-chevron-right.d.ts +2 -0
  132. package/dist/icons/glyphs/circle-chevron-up.d.ts +2 -0
  133. package/dist/icons/glyphs/circle-dashed.d.ts +2 -0
  134. package/dist/icons/glyphs/circle-dollar-sign.d.ts +2 -0
  135. package/dist/icons/glyphs/circle-gauge.d.ts +2 -0
  136. package/dist/icons/glyphs/circle-question-mark.d.ts +2 -0
  137. package/dist/icons/glyphs/circle-x.d.ts +2 -0
  138. package/dist/icons/glyphs/circle.d.ts +2 -0
  139. package/dist/icons/glyphs/clapperboard.d.ts +2 -0
  140. package/dist/icons/glyphs/clipboard-check.d.ts +2 -0
  141. package/dist/icons/glyphs/clock.d.ts +2 -0
  142. package/dist/icons/glyphs/cloud-backup.d.ts +2 -0
  143. package/dist/icons/glyphs/cloud-cog.d.ts +2 -0
  144. package/dist/icons/glyphs/cloud-download.d.ts +2 -0
  145. package/dist/icons/glyphs/cloud-lightning.d.ts +2 -0
  146. package/dist/icons/glyphs/cloud-off.d.ts +2 -0
  147. package/dist/icons/glyphs/cloud-rain-wind.d.ts +2 -0
  148. package/dist/icons/glyphs/cloud-rain.d.ts +2 -0
  149. package/dist/icons/glyphs/cloud-snow.d.ts +2 -0
  150. package/dist/icons/glyphs/cloud-sun.d.ts +2 -0
  151. package/dist/icons/glyphs/cloud-sync.d.ts +2 -0
  152. package/dist/icons/glyphs/cloud-upload.d.ts +2 -0
  153. package/dist/icons/glyphs/code-xml.d.ts +2 -0
  154. package/dist/icons/glyphs/coffee.d.ts +2 -0
  155. package/dist/icons/glyphs/cog.d.ts +2 -0
  156. package/dist/icons/glyphs/compass.d.ts +2 -0
  157. package/dist/icons/glyphs/concierge-bell.d.ts +2 -0
  158. package/dist/icons/glyphs/construction.d.ts +2 -0
  159. package/dist/icons/glyphs/contrast.d.ts +2 -0
  160. package/dist/icons/glyphs/cooking-pot.d.ts +2 -0
  161. package/dist/icons/glyphs/copy.d.ts +2 -0
  162. package/dist/icons/glyphs/corner-down-left.d.ts +2 -0
  163. package/dist/icons/glyphs/corner-down-right.d.ts +2 -0
  164. package/dist/icons/glyphs/corner-left-down.d.ts +2 -0
  165. package/dist/icons/glyphs/corner-left-up.d.ts +2 -0
  166. package/dist/icons/glyphs/corner-right-down.d.ts +2 -0
  167. package/dist/icons/glyphs/corner-right-up.d.ts +2 -0
  168. package/dist/icons/glyphs/corner-up-left.d.ts +2 -0
  169. package/dist/icons/glyphs/corner-up-right.d.ts +2 -0
  170. package/dist/icons/glyphs/cpu.d.ts +2 -0
  171. package/dist/icons/glyphs/credit-card.d.ts +2 -0
  172. package/dist/icons/glyphs/cup-soda.d.ts +2 -0
  173. package/dist/icons/glyphs/database-backup.d.ts +2 -0
  174. package/dist/icons/glyphs/delete.d.ts +2 -0
  175. package/dist/icons/glyphs/disc-3.d.ts +2 -0
  176. package/dist/icons/glyphs/dollar-sign.d.ts +2 -0
  177. package/dist/icons/glyphs/download.d.ts +2 -0
  178. package/dist/icons/glyphs/dribbble.d.ts +2 -0
  179. package/dist/icons/glyphs/droplet.d.ts +2 -0
  180. package/dist/icons/glyphs/drum.d.ts +2 -0
  181. package/dist/icons/glyphs/earth.d.ts +2 -0
  182. package/dist/icons/glyphs/ellipsis.d.ts +2 -0
  183. package/dist/icons/glyphs/euro.d.ts +2 -0
  184. package/dist/icons/glyphs/ev-charger.d.ts +2 -0
  185. package/dist/icons/glyphs/expand.d.ts +2 -0
  186. package/dist/icons/glyphs/external-link.d.ts +2 -0
  187. package/dist/icons/glyphs/eye-off.d.ts +2 -0
  188. package/dist/icons/glyphs/eye.d.ts +2 -0
  189. package/dist/icons/glyphs/facebook.d.ts +2 -0
  190. package/dist/icons/glyphs/fan.d.ts +2 -0
  191. package/dist/icons/glyphs/feather.d.ts +2 -0
  192. package/dist/icons/glyphs/figma.d.ts +2 -0
  193. package/dist/icons/glyphs/file-chart-line.d.ts +2 -0
  194. package/dist/icons/glyphs/file-check-corner.d.ts +2 -0
  195. package/dist/icons/glyphs/file-check.d.ts +2 -0
  196. package/dist/icons/glyphs/file-cog.d.ts +2 -0
  197. package/dist/icons/glyphs/file-pen-line.d.ts +2 -0
  198. package/dist/icons/glyphs/file-stack.d.ts +2 -0
  199. package/dist/icons/glyphs/file-text.d.ts +2 -0
  200. package/dist/icons/glyphs/fingerprint-pattern.d.ts +2 -0
  201. package/dist/icons/glyphs/fish-symbol.d.ts +2 -0
  202. package/dist/icons/glyphs/flame.d.ts +2 -0
  203. package/dist/icons/glyphs/flask-conical.d.ts +2 -0
  204. package/dist/icons/glyphs/folder-archive.d.ts +2 -0
  205. package/dist/icons/glyphs/folder-check.d.ts +2 -0
  206. package/dist/icons/glyphs/folder-clock.d.ts +2 -0
  207. package/dist/icons/glyphs/folder-code.d.ts +2 -0
  208. package/dist/icons/glyphs/folder-cog.d.ts +2 -0
  209. package/dist/icons/glyphs/folder-dot.d.ts +2 -0
  210. package/dist/icons/glyphs/folder-down.d.ts +2 -0
  211. package/dist/icons/glyphs/folder-git-2.d.ts +2 -0
  212. package/dist/icons/glyphs/folder-git.d.ts +2 -0
  213. package/dist/icons/glyphs/folder-heart.d.ts +2 -0
  214. package/dist/icons/glyphs/folder-input.d.ts +2 -0
  215. package/dist/icons/glyphs/folder-kanban.d.ts +2 -0
  216. package/dist/icons/glyphs/folder-key.d.ts +2 -0
  217. package/dist/icons/glyphs/folder-lock.d.ts +2 -0
  218. package/dist/icons/glyphs/folder-minus.d.ts +2 -0
  219. package/dist/icons/glyphs/folder-open.d.ts +2 -0
  220. package/dist/icons/glyphs/folder-output.d.ts +2 -0
  221. package/dist/icons/glyphs/folder-plus.d.ts +2 -0
  222. package/dist/icons/glyphs/folder-root.d.ts +2 -0
  223. package/dist/icons/glyphs/folder-sync.d.ts +2 -0
  224. package/dist/icons/glyphs/folder-tree.d.ts +2 -0
  225. package/dist/icons/glyphs/folder-up.d.ts +2 -0
  226. package/dist/icons/glyphs/folder-x.d.ts +2 -0
  227. package/dist/icons/glyphs/folders.d.ts +2 -0
  228. package/dist/icons/glyphs/frame.d.ts +2 -0
  229. package/dist/icons/glyphs/frown.d.ts +2 -0
  230. package/dist/icons/glyphs/gallery-horizontal-end.d.ts +2 -0
  231. package/dist/icons/glyphs/gallery-thumbnails.d.ts +2 -0
  232. package/dist/icons/glyphs/gallery-vertical-end.d.ts +2 -0
  233. package/dist/icons/glyphs/gauge.d.ts +2 -0
  234. package/dist/icons/glyphs/gavel.d.ts +2 -0
  235. package/dist/icons/glyphs/georgian-lari.d.ts +2 -0
  236. package/dist/icons/glyphs/git-branch.d.ts +2 -0
  237. package/dist/icons/glyphs/git-commit-horizontal.d.ts +2 -0
  238. package/dist/icons/glyphs/git-commit-vertical.d.ts +2 -0
  239. package/dist/icons/glyphs/git-compare-arrows.d.ts +2 -0
  240. package/dist/icons/glyphs/git-compare.d.ts +2 -0
  241. package/dist/icons/glyphs/git-fork.d.ts +2 -0
  242. package/dist/icons/glyphs/git-graph.d.ts +2 -0
  243. package/dist/icons/glyphs/git-merge.d.ts +2 -0
  244. package/dist/icons/glyphs/git-pull-request-closed.d.ts +2 -0
  245. package/dist/icons/glyphs/git-pull-request-create.d.ts +2 -0
  246. package/dist/icons/glyphs/git-pull-request.d.ts +2 -0
  247. package/dist/icons/glyphs/github.d.ts +2 -0
  248. package/dist/icons/glyphs/gitlab.d.ts +2 -0
  249. package/dist/icons/glyphs/graduation-cap.d.ts +2 -0
  250. package/dist/icons/glyphs/grip-horizontal.d.ts +2 -0
  251. package/dist/icons/glyphs/grip-vertical.d.ts +2 -0
  252. package/dist/icons/glyphs/grip.d.ts +2 -0
  253. package/dist/icons/glyphs/hammer.d.ts +2 -0
  254. package/dist/icons/glyphs/hand-coins.d.ts +2 -0
  255. package/dist/icons/glyphs/hand-fist.d.ts +2 -0
  256. package/dist/icons/glyphs/hand-grab.d.ts +2 -0
  257. package/dist/icons/glyphs/hand-heart.d.ts +2 -0
  258. package/dist/icons/glyphs/hand-helping.d.ts +2 -0
  259. package/dist/icons/glyphs/hand-metal.d.ts +2 -0
  260. package/dist/icons/glyphs/hand.d.ts +2 -0
  261. package/dist/icons/glyphs/hard-drive-download.d.ts +2 -0
  262. package/dist/icons/glyphs/hard-drive-upload.d.ts +2 -0
  263. package/dist/icons/glyphs/hard-drive.d.ts +2 -0
  264. package/dist/icons/glyphs/hat-glasses.d.ts +2 -0
  265. package/dist/icons/glyphs/heart-handshake.d.ts +2 -0
  266. package/dist/icons/glyphs/heart-pulse.d.ts +2 -0
  267. package/dist/icons/glyphs/heart.d.ts +2 -0
  268. package/dist/icons/glyphs/history.d.ts +2 -0
  269. package/dist/icons/glyphs/hourglass.d.ts +2 -0
  270. package/dist/icons/glyphs/house.d.ts +2 -0
  271. package/dist/icons/glyphs/id-card.d.ts +2 -0
  272. package/dist/icons/glyphs/image.d.ts +2 -0
  273. package/dist/icons/glyphs/inbox.d.ts +2 -0
  274. package/dist/icons/glyphs/indian-rupee.d.ts +2 -0
  275. package/dist/icons/glyphs/info.d.ts +2 -0
  276. package/dist/icons/glyphs/instagram.d.ts +2 -0
  277. package/dist/icons/glyphs/italic.d.ts +2 -0
  278. package/dist/icons/glyphs/japanese-yen.d.ts +2 -0
  279. package/dist/icons/glyphs/key-round.d.ts +2 -0
  280. package/dist/icons/glyphs/key-square.d.ts +2 -0
  281. package/dist/icons/glyphs/key.d.ts +2 -0
  282. package/dist/icons/glyphs/keyboard.d.ts +2 -0
  283. package/dist/icons/glyphs/languages.d.ts +2 -0
  284. package/dist/icons/glyphs/laptop-minimal-check.d.ts +2 -0
  285. package/dist/icons/glyphs/laugh.d.ts +2 -0
  286. package/dist/icons/glyphs/layers.d.ts +2 -0
  287. package/dist/icons/glyphs/layout-dashboard.d.ts +2 -0
  288. package/dist/icons/glyphs/layout-grid.d.ts +2 -0
  289. package/dist/icons/glyphs/layout-panel-top.d.ts +2 -0
  290. package/dist/icons/glyphs/leaf.d.ts +2 -0
  291. package/dist/icons/glyphs/leafy-green.d.ts +2 -0
  292. package/dist/icons/glyphs/link-2.d.ts +2 -0
  293. package/dist/icons/glyphs/link.d.ts +2 -0
  294. package/dist/icons/glyphs/linkedin.d.ts +2 -0
  295. package/dist/icons/glyphs/list-filter.d.ts +2 -0
  296. package/dist/icons/glyphs/list-todo.d.ts +2 -0
  297. package/dist/icons/glyphs/list.d.ts +2 -0
  298. package/dist/icons/glyphs/loader-circle.d.ts +2 -0
  299. package/dist/icons/glyphs/loader-pinwheel.d.ts +2 -0
  300. package/dist/icons/glyphs/loader.d.ts +2 -0
  301. package/dist/icons/glyphs/lock-keyhole-open.d.ts +2 -0
  302. package/dist/icons/glyphs/lock-keyhole.d.ts +2 -0
  303. package/dist/icons/glyphs/lock-open.d.ts +2 -0
  304. package/dist/icons/glyphs/lock.d.ts +2 -0
  305. package/dist/icons/glyphs/log-in.d.ts +2 -0
  306. package/dist/icons/glyphs/log-out.d.ts +2 -0
  307. package/dist/icons/glyphs/mail-check.d.ts +2 -0
  308. package/dist/icons/glyphs/mail.d.ts +2 -0
  309. package/dist/icons/glyphs/mailbox.d.ts +2 -0
  310. package/dist/icons/glyphs/map-pin-check-inside.d.ts +2 -0
  311. package/dist/icons/glyphs/map-pin-check.d.ts +2 -0
  312. package/dist/icons/glyphs/map-pin-house.d.ts +2 -0
  313. package/dist/icons/glyphs/map-pin-minus-inside.d.ts +2 -0
  314. package/dist/icons/glyphs/map-pin-minus.d.ts +2 -0
  315. package/dist/icons/glyphs/map-pin-off.d.ts +2 -0
  316. package/dist/icons/glyphs/map-pin-plus-inside.d.ts +2 -0
  317. package/dist/icons/glyphs/map-pin-plus.d.ts +2 -0
  318. package/dist/icons/glyphs/map-pin-x-inside.d.ts +2 -0
  319. package/dist/icons/glyphs/map-pin.d.ts +2 -0
  320. package/dist/icons/glyphs/maximize-2.d.ts +2 -0
  321. package/dist/icons/glyphs/maximize.d.ts +2 -0
  322. package/dist/icons/glyphs/meh.d.ts +2 -0
  323. package/dist/icons/glyphs/menu.d.ts +2 -0
  324. package/dist/icons/glyphs/message-circle-check.d.ts +2 -0
  325. package/dist/icons/glyphs/message-circle-dashed.d.ts +2 -0
  326. package/dist/icons/glyphs/message-circle-more.d.ts +2 -0
  327. package/dist/icons/glyphs/message-circle-plus.d.ts +2 -0
  328. package/dist/icons/glyphs/message-circle-x.d.ts +2 -0
  329. package/dist/icons/glyphs/message-circle.d.ts +2 -0
  330. package/dist/icons/glyphs/message-square-check.d.ts +2 -0
  331. package/dist/icons/glyphs/message-square-dashed.d.ts +2 -0
  332. package/dist/icons/glyphs/message-square-more.d.ts +2 -0
  333. package/dist/icons/glyphs/message-square-plus.d.ts +2 -0
  334. package/dist/icons/glyphs/message-square-x.d.ts +2 -0
  335. package/dist/icons/glyphs/message-square.d.ts +2 -0
  336. package/dist/icons/glyphs/mic-off.d.ts +2 -0
  337. package/dist/icons/glyphs/mic.d.ts +2 -0
  338. package/dist/icons/glyphs/minimize.d.ts +2 -0
  339. package/dist/icons/glyphs/minus.d.ts +2 -0
  340. package/dist/icons/glyphs/monitor-check.d.ts +2 -0
  341. package/dist/icons/glyphs/monitor-cog.d.ts +2 -0
  342. package/dist/icons/glyphs/monitor.d.ts +2 -0
  343. package/dist/icons/glyphs/moon.d.ts +2 -0
  344. package/dist/icons/glyphs/mouse-pointer-click.d.ts +2 -0
  345. package/dist/icons/glyphs/nfc.d.ts +2 -0
  346. package/dist/icons/glyphs/package.d.ts +2 -0
  347. package/dist/icons/glyphs/palette.d.ts +2 -0
  348. package/dist/icons/glyphs/panel-left-close.d.ts +2 -0
  349. package/dist/icons/glyphs/panel-left-open.d.ts +2 -0
  350. package/dist/icons/glyphs/panel-right-open.d.ts +2 -0
  351. package/dist/icons/glyphs/paperclip.d.ts +2 -0
  352. package/dist/icons/glyphs/party-popper.d.ts +2 -0
  353. package/dist/icons/glyphs/pause.d.ts +2 -0
  354. package/dist/icons/glyphs/pen-tool.d.ts +2 -0
  355. package/dist/icons/glyphs/philippine-peso.d.ts +2 -0
  356. package/dist/icons/glyphs/phone-call.d.ts +2 -0
  357. package/dist/icons/glyphs/phone-forwarded.d.ts +2 -0
  358. package/dist/icons/glyphs/phone-incoming.d.ts +2 -0
  359. package/dist/icons/glyphs/phone-missed.d.ts +2 -0
  360. package/dist/icons/glyphs/phone-off.d.ts +2 -0
  361. package/dist/icons/glyphs/phone.d.ts +2 -0
  362. package/dist/icons/glyphs/pickaxe.d.ts +2 -0
  363. package/dist/icons/glyphs/pipette.d.ts +2 -0
  364. package/dist/icons/glyphs/plane-landing.d.ts +2 -0
  365. package/dist/icons/glyphs/plane-takeoff.d.ts +2 -0
  366. package/dist/icons/glyphs/plane.d.ts +2 -0
  367. package/dist/icons/glyphs/play.d.ts +2 -0
  368. package/dist/icons/glyphs/plug-zap.d.ts +2 -0
  369. package/dist/icons/glyphs/plus.d.ts +2 -0
  370. package/dist/icons/glyphs/pound-sterling.d.ts +2 -0
  371. package/dist/icons/glyphs/projector.d.ts +2 -0
  372. package/dist/icons/glyphs/rabbit.d.ts +2 -0
  373. package/dist/icons/glyphs/radio-tower.d.ts +2 -0
  374. package/dist/icons/glyphs/radio.d.ts +2 -0
  375. package/dist/icons/glyphs/receipt-cent.d.ts +2 -0
  376. package/dist/icons/glyphs/receipt-euro.d.ts +2 -0
  377. package/dist/icons/glyphs/receipt-indian-rupee.d.ts +2 -0
  378. package/dist/icons/glyphs/receipt-japanese-yen.d.ts +2 -0
  379. package/dist/icons/glyphs/receipt-pound-sterling.d.ts +2 -0
  380. package/dist/icons/glyphs/receipt-russian-ruble.d.ts +2 -0
  381. package/dist/icons/glyphs/receipt-swiss-franc.d.ts +2 -0
  382. package/dist/icons/glyphs/receipt-text.d.ts +2 -0
  383. package/dist/icons/glyphs/receipt-turkish-lira.d.ts +2 -0
  384. package/dist/icons/glyphs/receipt.d.ts +2 -0
  385. package/dist/icons/glyphs/redo-dot.d.ts +2 -0
  386. package/dist/icons/glyphs/redo.d.ts +2 -0
  387. package/dist/icons/glyphs/refresh-ccw-dot.d.ts +2 -0
  388. package/dist/icons/glyphs/refresh-ccw.d.ts +2 -0
  389. package/dist/icons/glyphs/refresh-cw-off.d.ts +2 -0
  390. package/dist/icons/glyphs/refresh-cw.d.ts +2 -0
  391. package/dist/icons/glyphs/rocket.d.ts +2 -0
  392. package/dist/icons/glyphs/rocking-chair.d.ts +2 -0
  393. package/dist/icons/glyphs/roller-coaster.d.ts +2 -0
  394. package/dist/icons/glyphs/rotate-ccw.d.ts +2 -0
  395. package/dist/icons/glyphs/rotate-cw.d.ts +2 -0
  396. package/dist/icons/glyphs/route.d.ts +2 -0
  397. package/dist/icons/glyphs/router.d.ts +2 -0
  398. package/dist/icons/glyphs/russian-ruble.d.ts +2 -0
  399. package/dist/icons/glyphs/satellite-dish.d.ts +2 -0
  400. package/dist/icons/glyphs/saudi-riyal.d.ts +2 -0
  401. package/dist/icons/glyphs/scan-face.d.ts +2 -0
  402. package/dist/icons/glyphs/scan-text.d.ts +2 -0
  403. package/dist/icons/glyphs/search.d.ts +2 -0
  404. package/dist/icons/glyphs/send.d.ts +2 -0
  405. package/dist/icons/glyphs/server-cog.d.ts +2 -0
  406. package/dist/icons/glyphs/server-crash.d.ts +2 -0
  407. package/dist/icons/glyphs/server.d.ts +2 -0
  408. package/dist/icons/glyphs/settings.d.ts +2 -0
  409. package/dist/icons/glyphs/shield-check.d.ts +2 -0
  410. package/dist/icons/glyphs/ship-wheel.d.ts +2 -0
  411. package/dist/icons/glyphs/ship.d.ts +2 -0
  412. package/dist/icons/glyphs/shopping-cart.d.ts +2 -0
  413. package/dist/icons/glyphs/shower-head.d.ts +2 -0
  414. package/dist/icons/glyphs/shredder.d.ts +2 -0
  415. package/dist/icons/glyphs/shrink.d.ts +2 -0
  416. package/dist/icons/glyphs/sliders-horizontal.d.ts +2 -0
  417. package/dist/icons/glyphs/smartphone-charging.d.ts +2 -0
  418. package/dist/icons/glyphs/smartphone-nfc.d.ts +2 -0
  419. package/dist/icons/glyphs/smartphone.d.ts +2 -0
  420. package/dist/icons/glyphs/smile-plus.d.ts +2 -0
  421. package/dist/icons/glyphs/smile.d.ts +2 -0
  422. package/dist/icons/glyphs/snowflake.d.ts +2 -0
  423. package/dist/icons/glyphs/soup.d.ts +2 -0
  424. package/dist/icons/glyphs/sparkles.d.ts +2 -0
  425. package/dist/icons/glyphs/spray-can.d.ts +2 -0
  426. package/dist/icons/glyphs/square-activity.d.ts +2 -0
  427. package/dist/icons/glyphs/square-arrow-down.d.ts +2 -0
  428. package/dist/icons/glyphs/square-arrow-left.d.ts +2 -0
  429. package/dist/icons/glyphs/square-arrow-right.d.ts +2 -0
  430. package/dist/icons/glyphs/square-arrow-up.d.ts +2 -0
  431. package/dist/icons/glyphs/square-chevron-down.d.ts +2 -0
  432. package/dist/icons/glyphs/square-chevron-left.d.ts +2 -0
  433. package/dist/icons/glyphs/square-chevron-right.d.ts +2 -0
  434. package/dist/icons/glyphs/square-chevron-up.d.ts +2 -0
  435. package/dist/icons/glyphs/square-pen.d.ts +2 -0
  436. package/dist/icons/glyphs/square-stack.d.ts +2 -0
  437. package/dist/icons/glyphs/stamp.d.ts +2 -0
  438. package/dist/icons/glyphs/stethoscope.d.ts +2 -0
  439. package/dist/icons/glyphs/sun-dim.d.ts +2 -0
  440. package/dist/icons/glyphs/sun-medium.d.ts +2 -0
  441. package/dist/icons/glyphs/sun-moon.d.ts +2 -0
  442. package/dist/icons/glyphs/sun.d.ts +2 -0
  443. package/dist/icons/glyphs/sunset.d.ts +2 -0
  444. package/dist/icons/glyphs/swiss-franc.d.ts +2 -0
  445. package/dist/icons/glyphs/switch-camera.d.ts +2 -0
  446. package/dist/icons/glyphs/syringe.d.ts +2 -0
  447. package/dist/icons/glyphs/tablet.d.ts +2 -0
  448. package/dist/icons/glyphs/telescope.d.ts +2 -0
  449. package/dist/icons/glyphs/terminal.d.ts +2 -0
  450. package/dist/icons/glyphs/text-align-center.d.ts +2 -0
  451. package/dist/icons/glyphs/text-align-end.d.ts +2 -0
  452. package/dist/icons/glyphs/text-align-start.d.ts +2 -0
  453. package/dist/icons/glyphs/thermometer.d.ts +2 -0
  454. package/dist/icons/glyphs/thumbs-down.d.ts +2 -0
  455. package/dist/icons/glyphs/thumbs-up.d.ts +2 -0
  456. package/dist/icons/glyphs/ticket.d.ts +2 -0
  457. package/dist/icons/glyphs/timer.d.ts +2 -0
  458. package/dist/icons/glyphs/tornado.d.ts +2 -0
  459. package/dist/icons/glyphs/train-track.d.ts +2 -0
  460. package/dist/icons/glyphs/trash-2.d.ts +2 -0
  461. package/dist/icons/glyphs/tree-deciduous.d.ts +2 -0
  462. package/dist/icons/glyphs/tree-pine.d.ts +2 -0
  463. package/dist/icons/glyphs/trending-down.d.ts +2 -0
  464. package/dist/icons/glyphs/trending-up-down.d.ts +2 -0
  465. package/dist/icons/glyphs/trending-up.d.ts +2 -0
  466. package/dist/icons/glyphs/triangle-alert.d.ts +2 -0
  467. package/dist/icons/glyphs/truck.d.ts +2 -0
  468. package/dist/icons/glyphs/turkish-lira.d.ts +2 -0
  469. package/dist/icons/glyphs/twitch.d.ts +2 -0
  470. package/dist/icons/glyphs/twitter.d.ts +2 -0
  471. package/dist/icons/glyphs/underline.d.ts +2 -0
  472. package/dist/icons/glyphs/undo-dot.d.ts +2 -0
  473. package/dist/icons/glyphs/undo.d.ts +2 -0
  474. package/dist/icons/glyphs/unplug.d.ts +2 -0
  475. package/dist/icons/glyphs/upload.d.ts +2 -0
  476. package/dist/icons/glyphs/user-check.d.ts +2 -0
  477. package/dist/icons/glyphs/user-plus.d.ts +2 -0
  478. package/dist/icons/glyphs/user-round-check.d.ts +2 -0
  479. package/dist/icons/glyphs/user-round-cog.d.ts +2 -0
  480. package/dist/icons/glyphs/user-round-plus.d.ts +2 -0
  481. package/dist/icons/glyphs/user-round.d.ts +2 -0
  482. package/dist/icons/glyphs/user.d.ts +2 -0
  483. package/dist/icons/glyphs/users-round.d.ts +2 -0
  484. package/dist/icons/glyphs/users.d.ts +2 -0
  485. package/dist/icons/glyphs/vibrate.d.ts +2 -0
  486. package/dist/icons/glyphs/volume.d.ts +2 -0
  487. package/dist/icons/glyphs/wallet.d.ts +2 -0
  488. package/dist/icons/glyphs/washing-machine.d.ts +2 -0
  489. package/dist/icons/glyphs/waves-arrow-down.d.ts +2 -0
  490. package/dist/icons/glyphs/waves-arrow-up.d.ts +2 -0
  491. package/dist/icons/glyphs/waves-ladder.d.ts +2 -0
  492. package/dist/icons/glyphs/waves.d.ts +2 -0
  493. package/dist/icons/glyphs/waypoints.d.ts +2 -0
  494. package/dist/icons/glyphs/webhook.d.ts +2 -0
  495. package/dist/icons/glyphs/wifi-cog.d.ts +2 -0
  496. package/dist/icons/glyphs/wifi-low.d.ts +2 -0
  497. package/dist/icons/glyphs/wifi-pen.d.ts +2 -0
  498. package/dist/icons/glyphs/wifi-sync.d.ts +2 -0
  499. package/dist/icons/glyphs/wifi.d.ts +2 -0
  500. package/dist/icons/glyphs/wind-arrow-down.d.ts +2 -0
  501. package/dist/icons/glyphs/wind.d.ts +2 -0
  502. package/dist/icons/glyphs/workflow.d.ts +2 -0
  503. package/dist/icons/glyphs/wrench.d.ts +2 -0
  504. package/dist/icons/glyphs/x.d.ts +2 -0
  505. package/dist/icons/glyphs/youtube.d.ts +2 -0
  506. package/dist/icons/glyphs/zap-off.d.ts +2 -0
  507. package/dist/icons/glyphs/zap.d.ts +2 -0
  508. package/dist/icons/iconPlay.d.ts +2 -0
  509. package/dist/icons/registry.d.ts +80 -79
  510. package/dist/icons.js +996 -0
  511. package/dist/index.css +427 -132
  512. package/dist/index.js +6 -4
  513. package/dist/internal/ChoiceField.d.ts +1 -1
  514. package/dist/internal/FieldFrame.d.ts +17 -0
  515. package/dist/tokens/primitives.d.ts +1 -0
  516. package/dist/tokens/semantic.d.ts +1 -0
  517. package/dist/tokens/themes/dark.d.ts +1 -0
  518. package/package.json +11 -4
  519. package/src/components/button/COMPONENT.md +5 -3
  520. package/src/components/button/examples/in-form.tsx +15 -3
  521. package/src/components/button/examples/label-morph.tsx +7 -2
  522. package/src/components/button/examples/variants.tsx +1 -0
  523. package/src/components/checkbox/COMPONENT.md +1 -1
  524. package/src/components/color-picker/COMPONENT.md +2 -2
  525. package/src/components/color-picker/examples/in-form.tsx +13 -5
  526. package/src/components/color-picker/examples/validation.tsx +10 -4
  527. package/src/components/color-swatches/COMPONENT.md +2 -2
  528. package/src/components/color-swatches/examples/in-form.tsx +11 -5
  529. package/src/components/datepicker/COMPONENT.md +3 -3
  530. package/src/components/datepicker/examples/in-form.tsx +30 -9
  531. package/src/components/datepicker/examples/validation.tsx +20 -10
  532. package/src/components/digit-input/COMPONENT.md +3 -3
  533. package/src/components/digit-input/examples/in-form.tsx +22 -4
  534. package/src/components/digit-input/examples/validation.tsx +12 -5
  535. package/src/components/drawer/COMPONENT.md +1 -1
  536. package/src/components/drawer/examples/in-form.tsx +7 -2
  537. package/src/components/file-upload/COMPONENT.md +3 -3
  538. package/src/components/file-upload/examples/in-form.tsx +28 -4
  539. package/src/components/file-upload/examples/validation.tsx +37 -6
  540. package/src/components/input/COMPONENT.md +3 -3
  541. package/src/components/input/examples/in-form.tsx +42 -7
  542. package/src/components/input/examples/validation.tsx +38 -13
  543. package/src/components/modal/COMPONENT.md +1 -1
  544. package/src/components/modal/examples/in-form.tsx +7 -2
  545. package/src/components/native-select/COMPONENT.md +3 -3
  546. package/src/components/native-select/examples/examples.module.css +2 -0
  547. package/src/components/native-select/examples/in-form.tsx +18 -3
  548. package/src/components/native-select/examples/validation.tsx +8 -3
  549. package/src/components/popover/COMPONENT.md +1 -1
  550. package/src/components/popover/examples/in-form.tsx +27 -5
  551. package/src/components/radio/COMPONENT.md +1 -1
  552. package/src/components/select/COMPONENT.md +3 -3
  553. package/src/components/select/examples/examples.module.css +1 -0
  554. package/src/components/select/examples/in-form.tsx +25 -3
  555. package/src/components/select/examples/validation.tsx +8 -3
  556. package/src/components/slider/COMPONENT.md +1 -1
  557. package/src/components/switch/COMPONENT.md +1 -1
  558. package/src/components/tag-select/COMPONENT.md +3 -3
  559. package/src/components/tag-select/examples/examples.module.css +1 -0
  560. package/src/components/tag-select/examples/in-form.tsx +19 -2
  561. package/src/components/tag-select/examples/validation.tsx +7 -2
  562. package/src/components/textarea/COMPONENT.md +3 -3
  563. package/src/components/textarea/examples/in-form.tsx +20 -8
  564. package/src/components/textarea/examples/validation.tsx +24 -8
  565. package/src/styles/theme-dark.css +1 -0
  566. package/src/styles/theme-light.css +1 -0
  567. package/src/styles/tokens.css +1 -0
@@ -157,7 +157,7 @@ The built-in body (icon, `labels.title`, `labels.description` and a decorative s
157
157
  | hover | — | zone fill and dashed line darken |
158
158
  | focus | keyboard focus on the hidden input | inset focus ring on the zone (danger when invalid); Enter / Space opens the dialog |
159
159
  | drag-over | a file dragged over the zone | `data-state="active"` on the zone: accent line, accent soft fill, accent icon |
160
- | invalid | `invalid` or a non-empty `error` | `data-invalid="true"` on the zone, `aria-invalid` on the input; `data-invalid="true"` on Item |
160
+ | invalid | `invalid` or a non-empty `error` | `data-invalid="true"` on the zone, `aria-invalid` on the input; `data-invalid="true"` on Item; the control shakes once when an error arrives (`data-shake` on the frame) |
161
161
  | disabled | `disabled` | `data-disabled="true"`, disabled input, disabled fill and text, drops ignored |
162
162
 
163
163
  Also `data-size`, `data-variant` on the zone and `data-size` on Item. Files are not kept by the component: keep the list in your state and update it in `onFilesChange`.
@@ -197,11 +197,11 @@ Also `data-size`, `data-variant` on the zone and `data-size` on Item. Files are
197
197
  | [variants.tsx](examples/variants.tsx) | The dashed drop line next to a zone with only the fill, for cards and modals — `variant`. |
198
198
  | [sizes.tsx](examples/sizes.tsx) | Every size of the zone and of a file row: padding, icon, button and text follow the tier — `size`. |
199
199
  | [states.tsx](examples/states.tsx) | A default zone, a disabled one and an invalid one without a message — `disabled`, `invalid`. |
200
- | [validation.tsx](examples/validation.tsx) | A required zone with a hint, a rejected file whose error replaces the hint and an optional zone — `required`, `hint`, `error`, `optional`. |
200
+ | [validation.tsx](examples/validation.tsx) | A required scan checked as soon as it is picked: a wrong type or a large file shakes in an error that leaves when the file is removed; a hint and an optional zone — `required`, `hint`, `error`, `optional`. |
201
201
  | [custom-body.tsx](examples/custom-body.tsx) | A custom body: a muted title with a browse link and source buttons instead of the built-in one — `FileUpload.Body`, `FileUpload.Title`. |
202
202
  | [upload-progress.tsx](examples/upload-progress.tsx) | File rows while uploading, uploaded and failed with a retry — `FileUpload.ItemProgress`, `invalid`, `FileUpload.ItemActions`. |
203
203
  | [avatar-upload.tsx](examples/avatar-upload.tsx) | A round zone around an Avatar that takes images and shows a preview; buttons open the same input — `inputRef`, `accept`, `className`. |
204
- | [in-form.tsx](examples/in-form.tsx) | A contract upload form: the required scan is checked on submit and its error replaces the hint — `required`, `error`, `name`. |
204
+ | [in-form.tsx](examples/in-form.tsx) | A contract upload form: submit checks the required scan, its error shakes in and leaves once a valid file is picked or removed — `required`, `error`, `name`. |
205
205
  | [narrow.tsx](examples/narrow.tsx) | In a phone-width column the zone text wraps and a long file name truncates. |
206
206
 
207
207
  ## Mistakes
@@ -1,18 +1,31 @@
1
- /** A contract upload form: the required scan is checked on submit and its error replaces the hint — `required`, `error`, `name`. */
1
+ /** A contract upload form: submit checks the required scan, its error shakes in and leaves once a valid file is picked or removed — `required`, `error`, `name`. */
2
2
  import { Button, FileUpload, Icon, Typography } from "prime-ui-kit";
3
3
  import * as React from "react";
4
4
 
5
5
  import styles from "./examples.module.css";
6
6
 
7
7
  const HINT = "PDF до 20 МБ, все страницы";
8
+ const MAX_SIZE = 20 * 1024 * 1024;
9
+
10
+ /** The scan error on submit, or nothing when exactly a PDF within the limit is attached. */
11
+ function scanError(files: File[]) {
12
+ if (files.length === 0) return "Приложите скан договора";
13
+ if (files.some((file) => !file.name.toLowerCase().endsWith(".pdf")))
14
+ return "Нужен файл в формате PDF";
15
+ if (files.some((file) => file.size > MAX_SIZE)) return "Файл больше 20 МБ";
16
+ return undefined;
17
+ }
8
18
 
9
19
  export default function FileUploadInFormExample() {
10
20
  const [files, setFiles] = React.useState<File[]>([]);
11
21
  const [error, setError] = React.useState<string>();
22
+ const [sent, setSent] = React.useState(false);
12
23
 
13
24
  const submit = (event: React.FormEvent<HTMLFormElement>) => {
14
25
  event.preventDefault();
15
- setError(files.length === 0 ? "Приложите скан договора" : undefined);
26
+ const next = scanError(files);
27
+ setError(next);
28
+ setSent(next === undefined);
16
29
  };
17
30
 
18
31
  return (
@@ -36,18 +49,23 @@ export default function FileUploadInFormExample() {
36
49
  onFilesChange={(next) => {
37
50
  setFiles(next);
38
51
  setError(undefined);
52
+ setSent(false);
39
53
  }}
40
54
  />
41
55
  {files.map((file) => (
42
56
  <FileUpload.Item key={file.name}>
43
- <FileUpload.FormatBadge format="pdf" color="red" />
57
+ <FileUpload.FormatBadge format={file.name.split(".").pop() ?? ""} color="red" />
44
58
  <FileUpload.ItemName>{file.name}</FileUpload.ItemName>
45
59
  <FileUpload.ItemActions>
46
60
  <Button.Root
47
61
  variant="ghost"
48
62
  tone="neutral"
49
63
  aria-label={`Удалить ${file.name}`}
50
- onClick={() => setFiles([])}
64
+ onClick={() => {
65
+ setFiles([]);
66
+ setError(undefined);
67
+ setSent(false);
68
+ }}
51
69
  >
52
70
  <Button.Icon>
53
71
  <Icon name="action.close" />
@@ -57,6 +75,11 @@ export default function FileUploadInFormExample() {
57
75
  </FileUpload.Item>
58
76
  ))}
59
77
  </div>
78
+ {sent ? (
79
+ <Typography as="p" variant="body-s" tone="secondary" role="status">
80
+ Договор отправлен на проверку.
81
+ </Typography>
82
+ ) : null}
60
83
  <div className={styles.formActions}>
61
84
  <Button.Root
62
85
  variant="ghost"
@@ -65,6 +88,7 @@ export default function FileUploadInFormExample() {
65
88
  onClick={() => {
66
89
  setFiles([]);
67
90
  setError(undefined);
91
+ setSent(false);
68
92
  }}
69
93
  >
70
94
  Отменить
@@ -1,18 +1,49 @@
1
- /** A required zone with a hint, a rejected file whose error replaces the hint and an optional zone — `required`, `hint`, `error`, `optional`. */
2
- import { FileUpload } from "prime-ui-kit";
1
+ /** A required scan checked as soon as it is picked: a wrong type or a large file shakes in an error that leaves when the file is removed; a hint and an optional zone — `required`, `hint`, `error`, `optional`. */
2
+ import { Button, FileUpload, Icon } from "prime-ui-kit";
3
+ import * as React from "react";
3
4
 
4
5
  import styles from "./examples.module.css";
5
6
 
7
+ const MAX_SIZE = 20 * 1024 * 1024;
8
+
9
+ /** The scan error, or nothing when every picked file is a PDF within the limit. */
10
+ function scanError(files: File[]) {
11
+ if (files.some((file) => !file.name.toLowerCase().endsWith(".pdf")))
12
+ return "Нужен файл в формате PDF";
13
+ if (files.some((file) => file.size > MAX_SIZE)) return "Файл больше 20 МБ";
14
+ return undefined;
15
+ }
16
+
6
17
  export default function FileUploadValidationExample() {
18
+ const [files, setFiles] = React.useState<File[]>([]);
19
+
7
20
  return (
8
21
  <div className={styles.column}>
9
- <FileUpload.Root label="Скан договора" required hint="PDF до 20 МБ, все страницы" />
10
22
  <FileUpload.Root
11
- label="Счёт на оплату"
23
+ label="Скан договора"
12
24
  required
13
- error="Файл не подошёл: нужен PDF до 20 МБ"
14
- labels={{ title: "Выберите другой файл" }}
25
+ hint="PDF до 20 МБ, все страницы"
26
+ error={scanError(files)}
27
+ onFilesChange={setFiles}
15
28
  />
29
+ {files.map((file) => (
30
+ <FileUpload.Item key={file.name}>
31
+ <FileUpload.FormatBadge format={file.name.split(".").pop() ?? ""} color="red" />
32
+ <FileUpload.ItemName>{file.name}</FileUpload.ItemName>
33
+ <FileUpload.ItemActions>
34
+ <Button.Root
35
+ variant="ghost"
36
+ tone="neutral"
37
+ aria-label={`Удалить ${file.name}`}
38
+ onClick={() => setFiles([])}
39
+ >
40
+ <Button.Icon>
41
+ <Icon name="action.close" />
42
+ </Button.Icon>
43
+ </Button.Root>
44
+ </FileUpload.ItemActions>
45
+ </FileUpload.Item>
46
+ ))}
16
47
  <FileUpload.Root label="Доверенность" optional hint="Если подписывает не директор" />
17
48
  </div>
18
49
  );
@@ -166,7 +166,7 @@ Input has no `variant` or `tone`: there is one field treatment (fill, no visible
166
166
  | default / hover | — | hover darkens the fill (not when disabled, read-only or focused) |
167
167
  | focus | keyboard focus on the input | wrapper gets the focus fill and an inset focus ring (`:has(input:focus-visible)`) |
168
168
  | no focus ring | `focusRing={false}` | `data-focus-ring="false"` on the wrapper |
169
- | invalid | `invalid` or non-empty `error` | `data-invalid="true"` on root and wrapper, `aria-invalid="true"` on the input, danger inset ring, danger focus ring |
169
+ | invalid | `invalid` or non-empty `error` | `data-invalid="true"` on root and wrapper, `aria-invalid="true"` on the input, danger inset ring, danger focus ring; the control shakes once when an error arrives (`data-shake` on the frame) |
170
170
  | disabled | native `disabled` on `Input.Field` | disabled fill, disabled text and icons, `cursor: not-allowed`, clear button disabled look |
171
171
  | read-only | native `readOnly` on `Input.Field` | no hover, default cursor |
172
172
  | reserved support row | `reserveSupportRow` | `data-reserve="true"` on the support row |
@@ -219,13 +219,13 @@ Controlled: `value` + `onChange` (or `onValueChange`) on `Input.Field`. Uncontro
219
219
  | [overview.tsx](examples/overview.tsx) | A labelled field with a hint under it — `label`, `hint`. |
220
220
  | [sizes.tsx](examples/sizes.tsx) | Every size tier; the label and the hint follow the field tier — `size`. |
221
221
  | [states.tsx](examples/states.tsx) | A default field next to a disabled and a read-only one — `disabled`, `readOnly`. |
222
- | [validation.tsx](examples/validation.tsx) | Required and optional markers, a hint, an error and a support row that does not shift — `required`, `optional`, `hint`, `error`, `reserveSupportRow`. |
222
+ | [validation.tsx](examples/validation.tsx) | Live validation: an error shakes the field as it arrives, drops in and leaves as soon as the value is fixed; required and optional markers, a hint and a support row that does not shift — `required`, `optional`, `hint`, `error`, `reserveSupportRow`. |
223
223
  | [with-icon.tsx](examples/with-icon.tsx) | A decorative icon at either end of the value — `Input.Icon`, `side`. |
224
224
  | [affixes.tsx](examples/affixes.tsx) | A fixed prefix and suffix flush with the edges and a unit next to the value — `Input.Affix`, `Input.InlineAffix`. |
225
225
  | [without-focus-ring.tsx](examples/without-focus-ring.tsx) | A single search field where the caret and the lighter fill show focus — `focusRing`. |
226
226
  | [password-strength.tsx](examples/password-strength.tsx) | A new password with a meter that fills step by step and names the level beside the hint — `strength`. |
227
227
  | [controlled.tsx](examples/controlled.tsx) | The parent owns the value: a clear button and a character counter follow it — `value`, `onValueChange`, `Input.ClearButton`, `Input.Counter`. |
228
- | [in-form.tsx](examples/in-form.tsx) | Company details form: required fields checked on submit, neighbours keep their bottoms aligned — `required`, `error`, `reserveSupportRow`. |
228
+ | [in-form.tsx](examples/in-form.tsx) | Company details form: required fields checked on submit, each error leaves as its field is fixed and a saved form turns the button green; neighbours keep their bottoms aligned — `required`, `error`, `reserveSupportRow`. |
229
229
 
230
230
  ## Mistakes
231
231
  - `<Input.Field placeholder="Email" />` without a label → add `label` on `Input.Root` or `aria-label` on the field.
@@ -1,4 +1,4 @@
1
- /** Company details form: required fields checked on submit, neighbours keep their bottoms aligned — `required`, `error`, `reserveSupportRow`. */
1
+ /** Company details form: required fields checked on submit, each error leaves as its field is fixed and a saved form turns the button green; neighbours keep their bottoms aligned — `required`, `error`, `reserveSupportRow`. */
2
2
  import { Button, Input, Typography } from "prime-ui-kit";
3
3
  import * as React from "react";
4
4
 
@@ -15,10 +15,19 @@ function validate(form: FormData): Errors {
15
15
 
16
16
  export default function InputInFormExample() {
17
17
  const [errors, setErrors] = React.useState<Errors>({});
18
+ const [saved, setSaved] = React.useState(false);
18
19
 
19
20
  const submit = (event: React.FormEvent<HTMLFormElement>) => {
20
21
  event.preventDefault();
21
- setErrors(validate(new FormData(event.currentTarget)));
22
+ const next = validate(new FormData(event.currentTarget));
23
+ setErrors(next);
24
+ setSaved(Object.keys(next).length === 0);
25
+ };
26
+
27
+ /** Editing a field takes its error away and makes the form unsaved again. */
28
+ const edit = (field?: keyof Errors) => {
29
+ setSaved(false);
30
+ if (field) setErrors((current) => ({ ...current, [field]: undefined }));
22
31
  };
23
32
 
24
33
  return (
@@ -37,6 +46,7 @@ export default function InputInFormExample() {
37
46
  <Input.Wrapper>
38
47
  <Input.Field
39
48
  name="name"
49
+ onValueChange={() => edit("name")}
40
50
  defaultValue="ООО «Северный ветер»"
41
51
  autoComplete="organization"
42
52
  />
@@ -45,27 +55,52 @@ export default function InputInFormExample() {
45
55
  </div>
46
56
  <Input.Root label="ИНН" required error={errors.inn} reserveSupportRow>
47
57
  <Input.Wrapper>
48
- <Input.Field name="inn" defaultValue="78123" inputMode="numeric" />
58
+ <Input.Field
59
+ name="inn"
60
+ defaultValue="78123"
61
+ inputMode="numeric"
62
+ onValueChange={() => edit("inn")}
63
+ />
49
64
  </Input.Wrapper>
50
65
  </Input.Root>
51
66
  <Input.Root label="КПП" optional reserveSupportRow>
52
67
  <Input.Wrapper>
53
- <Input.Field name="kpp" placeholder="9 цифр" inputMode="numeric" />
68
+ <Input.Field
69
+ name="kpp"
70
+ placeholder="9 цифр"
71
+ inputMode="numeric"
72
+ onValueChange={() => edit()}
73
+ />
54
74
  </Input.Wrapper>
55
75
  </Input.Root>
56
76
  <div className={styles.formWide}>
57
77
  <Input.Root label="Почта для счетов" hint="Сюда придут счета и акты">
58
78
  <Input.Wrapper>
59
- <Input.Field name="email" type="email" placeholder="buh@company.ru" />
79
+ <Input.Field
80
+ name="email"
81
+ type="email"
82
+ placeholder="buh@company.ru"
83
+ onValueChange={() => edit()}
84
+ />
60
85
  </Input.Wrapper>
61
86
  </Input.Root>
62
87
  </div>
63
88
  </div>
64
89
  <div className={styles.formActions}>
65
- <Button.Root variant="ghost" tone="neutral" type="reset" onClick={() => setErrors({})}>
90
+ <Button.Root
91
+ variant="ghost"
92
+ tone="neutral"
93
+ type="reset"
94
+ onClick={() => {
95
+ setErrors({});
96
+ setSaved(false);
97
+ }}
98
+ >
66
99
  Отменить
67
100
  </Button.Root>
68
- <Button.Root type="submit">Сохранить</Button.Root>
101
+ <Button.Root type="submit" tone={saved ? "success" : "accent"}>
102
+ {saved ? "Сохранено" : "Сохранить"}
103
+ </Button.Root>
69
104
  </div>
70
105
  </form>
71
106
  );
@@ -1,9 +1,28 @@
1
- /** Required and optional markers, a hint, an error and a support row that does not shift — `required`, `optional`, `hint`, `error`, `reserveSupportRow`. */
1
+ /** Live validation: an error shakes the field as it arrives, drops in and leaves as soon as the value is fixed; required and optional markers, a hint and a support row that does not shift — `required`, `optional`, `hint`, `error`, `reserveSupportRow`. */
2
2
  import { Button, Input } from "prime-ui-kit";
3
3
  import * as React from "react";
4
4
 
5
+ const PROMO_CODES = ["SPRING25", "TEAM10"];
6
+
7
+ /** The INN error, or nothing when the value is a valid INN. */
8
+ function innError(value: string) {
9
+ if (value === "") return "Введите ИНН";
10
+ if (/\D/.test(value)) return "Только цифры, без пробелов и букв";
11
+ if (value.length !== 10 && value.length !== 12) return "ИНН состоит из 10 или 12 цифр";
12
+ return undefined;
13
+ }
14
+
5
15
  export default function InputValidationExample() {
6
- const [checked, setChecked] = React.useState(false);
16
+ const [inn, setInn] = React.useState("77010");
17
+ const [promo, setPromo] = React.useState("SPRING");
18
+ const [promoError, setPromoError] = React.useState<string>();
19
+
20
+ const applyPromo = () =>
21
+ setPromoError(
22
+ PROMO_CODES.includes(promo.trim().toUpperCase())
23
+ ? undefined
24
+ : "Промокод недействителен или истёк",
25
+ );
7
26
 
8
27
  return (
9
28
  <>
@@ -12,23 +31,29 @@ export default function InputValidationExample() {
12
31
  <Input.Field defaultValue="ООО «Северный ветер»" autoComplete="organization" />
13
32
  </Input.Wrapper>
14
33
  </Input.Root>
15
- <Input.Root label="ИНН" required error="ИНН состоит из 10 или 12 цифр">
34
+ <Input.Root
35
+ label="ИНН"
36
+ required
37
+ hint="10 цифр для организации, 12 — для ИП"
38
+ error={innError(inn)}
39
+ >
16
40
  <Input.Wrapper>
17
- <Input.Field defaultValue="77010" inputMode="numeric" />
41
+ <Input.Field value={inn} onValueChange={setInn} inputMode="numeric" />
18
42
  </Input.Wrapper>
19
43
  </Input.Root>
20
- <Input.Root
21
- label="Промокод"
22
- optional
23
- reserveSupportRow
24
- error={checked ? "Промокод недействителен или истёк" : undefined}
25
- >
44
+ <Input.Root label="Промокод" optional reserveSupportRow error={promoError}>
26
45
  <Input.Wrapper>
27
- <Input.Field defaultValue="SPRING25" />
46
+ <Input.Field
47
+ value={promo}
48
+ onValueChange={(value) => {
49
+ setPromo(value);
50
+ setPromoError(undefined);
51
+ }}
52
+ />
28
53
  </Input.Wrapper>
29
54
  </Input.Root>
30
- <Button.Root variant="soft" tone="neutral" onClick={() => setChecked((value) => !value)}>
31
- {checked ? "Сбросить проверку" : "Проверить промокод"}
55
+ <Button.Root variant="soft" tone="neutral" onClick={applyPromo}>
56
+ Применить промокод
32
57
  </Button.Root>
33
58
  </>
34
59
  );
@@ -201,7 +201,7 @@ Loading or disabled actions use the Button props (`loading`, `disabled`) inside
201
201
  | [custom-container.tsx](examples/custom-container.tsx) | The dialog portals into a given node instead of the document body — `container`. |
202
202
  | [dismiss.tsx](examples/dismiss.tsx) | A destructive confirm closes only from its buttons, and not at all while the request runs — `closeOnOutsideClick`, `closeOnEscape`. |
203
203
  | [controlled-open.tsx](examples/controlled-open.tsx) | The parent owns the open state and opens the dialog from code, without a trigger — `open`, `onOpenChange`. |
204
- | [in-form.tsx](examples/in-form.tsx) | A settings form in a dialog: the footer button submits the form and an empty name keeps it open — `Modal.Body`, `Modal.Footer`, `error`. |
204
+ | [in-form.tsx](examples/in-form.tsx) | A settings form in a dialog: the footer button submits the form and an empty name shakes the field and keeps it open until it is filled — `Modal.Body`, `Modal.Footer`, `error`. |
205
205
 
206
206
  ## Mistakes
207
207
  - Destructive confirm that closes on a stray scrim click → `closeOnOutsideClick={false}`.
@@ -1,4 +1,4 @@
1
- /** A settings form in a dialog: the footer button submits the form and an empty name keeps it open — `Modal.Body`, `Modal.Footer`, `error`. */
1
+ /** A settings form in a dialog: the footer button submits the form and an empty name shakes the field and keeps it open until it is filled — `Modal.Body`, `Modal.Footer`, `error`. */
2
2
  import { Button, Icon, Input, Modal, Select, Switch } from "prime-ui-kit";
3
3
  import * as React from "react";
4
4
 
@@ -44,7 +44,12 @@ export default function ModalInFormExample() {
44
44
  <form id={formId} className={styles.form} noValidate onSubmit={submit}>
45
45
  <Input.Root label="Название" required error={error} reserveSupportRow>
46
46
  <Input.Wrapper>
47
- <Input.Field name="name" defaultValue="Сайт компании" autoFocus />
47
+ <Input.Field
48
+ name="name"
49
+ defaultValue="Сайт компании"
50
+ autoFocus
51
+ onValueChange={() => setError(undefined)}
52
+ />
48
53
  </Input.Wrapper>
49
54
  </Input.Root>
50
55
  <Select.Root label="Ответственный" defaultValue="anna">
@@ -81,7 +81,7 @@ One look, the Select trigger's: field fill, inset control border, tier radius; t
81
81
  | State | Driven by | DOM |
82
82
  |---|---|---|
83
83
  | placeholder shown | `placeholder` and no value | the empty first option is selected; placeholder text color |
84
- | invalid | `invalid` or `error` | `aria-invalid="true"`, `data-invalid="true"` |
84
+ | invalid | `invalid` or `error` | `aria-invalid="true"`, `data-invalid="true"`; the control shakes once when an error arrives (`data-shake` on the frame) |
85
85
  | disabled | `disabled` | native `disabled` |
86
86
  | size | `size` | `data-size` |
87
87
  | focus ring off | `focusRing={false}` | `data-focus-ring="false"` |
@@ -116,10 +116,10 @@ One look, the Select trigger's: field fill, inset control border, tier radius; t
116
116
  | [overview.tsx](examples/overview.tsx) | A labelled system select with a hint; the OS picker opens on phones — `label`, `hint`. |
117
117
  | [sizes.tsx](examples/sizes.tsx) | Every size tier; the label and the hint follow the field tier — `size`. |
118
118
  | [states.tsx](examples/states.tsx) | A default field next to a disabled and an invalid one — `disabled`, `invalid`. |
119
- | [validation.tsx](examples/validation.tsx) | Required and optional markers, a hint, and an error that replaces the hint in the same row — `required`, `optional`, `hint`, `error`. |
119
+ | [validation.tsx](examples/validation.tsx) | Live validation: unassigning the owner shakes the field and drops the error in, picking someone clears it; required and optional markers and a hint — `required`, `optional`, `hint`, `error`. |
120
120
  | [option-groups.tsx](examples/option-groups.tsx) | Options under group headings with the native optgroup, and a placeholder while nothing is picked — `placeholder`. |
121
121
  | [controlled.tsx](examples/controlled.tsx) | The parent owns the value: the plan drives the price under the field — `value`, `onValueChange`. |
122
- | [in-form.tsx](examples/in-form.tsx) | A delivery form for phones: the native value goes into FormData, the required city is checked on submit — `name`, `required`, `error`. |
122
+ | [in-form.tsx](examples/in-form.tsx) | A delivery form for phones: the native value goes into FormData, the required city is checked on submit, the error shakes the field and leaves once a city is picked, a calm note confirms the order — `name`, `required`, `error`. |
123
123
 
124
124
  ## Mistakes
125
125
  - `Select.Item` parts as children → NativeSelect takes plain `<option>` / `<optgroup>`.
@@ -10,5 +10,7 @@
10
10
 
11
11
  .actions {
12
12
  display: flex;
13
+ align-items: center;
13
14
  justify-content: flex-end;
15
+ gap: var(--prime-space-2);
14
16
  }
@@ -1,4 +1,4 @@
1
- /** A delivery form for phones: the native value goes into FormData, the required city is checked on submit — `name`, `required`, `error`. */
1
+ /** A delivery form for phones: the native value goes into FormData, the required city is checked on submit, the error shakes the field and leaves once a city is picked, a calm note confirms the order — `name`, `required`, `error`. */
2
2
  import { Button, NativeSelect, Typography } from "prime-ui-kit";
3
3
  import * as React from "react";
4
4
 
@@ -6,11 +6,13 @@ import styles from "./examples.module.css";
6
6
 
7
7
  export default function NativeSelectInFormExample() {
8
8
  const [error, setError] = React.useState<string>();
9
+ const [saved, setSaved] = React.useState(false);
9
10
 
10
11
  const submit = (event: React.FormEvent<HTMLFormElement>) => {
11
12
  event.preventDefault();
12
13
  const city = String(new FormData(event.currentTarget).get("city") ?? "");
13
14
  setError(city ? undefined : "Выберите город доставки");
15
+ setSaved(Boolean(city));
14
16
  };
15
17
 
16
18
  return (
@@ -24,18 +26,31 @@ export default function NativeSelectInFormExample() {
24
26
  required
25
27
  error={error}
26
28
  placeholder="Выберите город"
27
- onValueChange={() => setError(undefined)}
29
+ onValueChange={() => {
30
+ setError(undefined);
31
+ setSaved(false);
32
+ }}
28
33
  >
29
34
  <option value="msk">Москва</option>
30
35
  <option value="spb">Санкт-Петербург</option>
31
36
  <option value="kzn">Казань</option>
32
37
  </NativeSelect>
33
- <NativeSelect name="slot" label="Время" defaultValue="day">
38
+ <NativeSelect
39
+ name="slot"
40
+ label="Время"
41
+ defaultValue="day"
42
+ onValueChange={() => setSaved(false)}
43
+ >
34
44
  <option value="morning">09:00–12:00</option>
35
45
  <option value="day">12:00–18:00</option>
36
46
  <option value="evening">18:00–21:00</option>
37
47
  </NativeSelect>
38
48
  <div className={styles.actions}>
49
+ {saved ? (
50
+ <Typography as="p" variant="body-s" tone="secondary">
51
+ Доставка оформлена
52
+ </Typography>
53
+ ) : null}
39
54
  <Button.Root type="submit">Продолжить</Button.Root>
40
55
  </div>
41
56
  </form>
@@ -1,7 +1,10 @@
1
- /** Required and optional markers, a hint, and an error that replaces the hint in the same row — `required`, `optional`, `hint`, `error`. */
1
+ /** Live validation: unassigning the owner shakes the field and drops the error in, picking someone clears it; required and optional markers and a hint — `required`, `optional`, `hint`, `error`. */
2
2
  import { NativeSelect } from "prime-ui-kit";
3
+ import * as React from "react";
3
4
 
4
5
  export default function NativeSelectValidationExample() {
6
+ const [owner, setOwner] = React.useState("anna");
7
+
5
8
  return (
6
9
  <>
7
10
  <NativeSelect label="Страна" required hint="Определяет валюту счетов" defaultValue="ru">
@@ -11,9 +14,11 @@ export default function NativeSelectValidationExample() {
11
14
  <NativeSelect
12
15
  label="Ответственный"
13
16
  required
14
- error="Назначьте ответственного"
15
- placeholder="Не выбран"
17
+ error={owner === "none" ? "Назначьте ответственного" : undefined}
18
+ value={owner}
19
+ onValueChange={setOwner}
16
20
  >
21
+ <option value="none">Не назначен</option>
17
22
  <option value="anna">Анна Петрова</option>
18
23
  <option value="ivan">Иван Смирнов</option>
19
24
  </NativeSelect>
@@ -162,7 +162,7 @@ No `labels`.
162
162
  | [flush.tsx](examples/flush.tsx) | A notification list whose rows and dividers reach the panel edges; each row brings its own padding — `flush`. |
163
163
  | [dismiss.tsx](examples/dismiss.tsx) | A destructive confirm that closes only from its buttons, and not at all while the request runs — `closeOnOutsideClick`, `closeOnEscape`. |
164
164
  | [controlled-open.tsx](examples/controlled-open.tsx) | The parent owns the open state: another button opens the panel from code and its own button closes it — `open`, `onOpenChange`. |
165
- | [in-form.tsx](examples/in-form.tsx) | An invite form in a panel: Tab stays inside, the role list does not count as an outside click, and submit closes the panel — `trapFocus`. |
165
+ | [in-form.tsx](examples/in-form.tsx) | An invite form in a panel: Tab stays inside, the role list does not count as an outside click, an invalid email shakes the field and keeps the panel open until it is fixed — `trapFocus`, `error`. |
166
166
 
167
167
  ## Mistakes
168
168
  - A hint of a few words in a Popover → use Tooltip (hover / focus, no interactive content).
@@ -1,14 +1,28 @@
1
- /** An invite form in a panel: Tab stays inside, the role list does not count as an outside click, and submit closes the panel — `trapFocus`. */
1
+ /** An invite form in a panel: Tab stays inside, the role list does not count as an outside click, an invalid email shakes the field and keeps the panel open until it is fixed — `trapFocus`, `error`. */
2
2
  import { Button, Input, Popover, Select } from "prime-ui-kit";
3
3
  import * as React from "react";
4
4
 
5
5
  import styles from "./examples.module.css";
6
6
 
7
+ /** The email error, or nothing when the address is valid. */
8
+ function emailError(value: string) {
9
+ if (!value.trim()) return "Введите почту";
10
+ if (!/^\S+@\S+\.\S+$/.test(value.trim())) return "Проверьте адрес: нужен вид name@company.ru";
11
+ return undefined;
12
+ }
13
+
7
14
  export default function PopoverInFormExample() {
8
15
  const [open, setOpen] = React.useState(false);
16
+ const [error, setError] = React.useState<string>();
9
17
 
10
18
  return (
11
- <Popover.Root open={open} onOpenChange={setOpen}>
19
+ <Popover.Root
20
+ open={open}
21
+ onOpenChange={(next) => {
22
+ setOpen(next);
23
+ if (!next) setError(undefined);
24
+ }}
25
+ >
12
26
  <Popover.Trigger>
13
27
  <Button.Root>Пригласить</Button.Root>
14
28
  </Popover.Trigger>
@@ -19,14 +33,22 @@ export default function PopoverInFormExample() {
19
33
  </Popover.Header>
20
34
  <form
21
35
  className={styles.stack}
36
+ noValidate
22
37
  onSubmit={(event) => {
23
38
  event.preventDefault();
24
- setOpen(false);
39
+ const next = emailError(String(new FormData(event.currentTarget).get("email") ?? ""));
40
+ setError(next);
41
+ if (!next) setOpen(false);
25
42
  }}
26
43
  >
27
- <Input.Root label="Почта" required>
44
+ <Input.Root label="Почта" required error={error} reserveSupportRow>
28
45
  <Input.Wrapper>
29
- <Input.Field type="email" name="email" placeholder="name@company.ru" />
46
+ <Input.Field
47
+ type="email"
48
+ name="email"
49
+ placeholder="name@company.ru"
50
+ onValueChange={() => setError(undefined)}
51
+ />
30
52
  </Input.Wrapper>
31
53
  </Input.Root>
32
54
  <Select.Root label="Роль" defaultValue="editor">
@@ -109,7 +109,7 @@ No `variant` / `tone` / `color`.
109
109
  |---|---|---|
110
110
  | unselected | group `value` ≠ option `value` | `data-state="unchecked"` on the option; circle `fill-strong`, hover `fill-strong-hover` |
111
111
  | selected | group `value` = option `value` | `data-state="checked"`; accent circle with a thumb-coloured dot that grows in |
112
- | invalid | `invalid` or a non-empty `error` on the group | `data-invalid="true"`, `aria-invalid` on the group and the inputs; danger ring on unselected circles |
112
+ | invalid | `invalid` or a non-empty `error` on the group | `data-invalid="true"`, `aria-invalid` on the group and the inputs; danger ring on unselected circles; the control shakes once when an error arrives (`data-shake` on the frame) |
113
113
  | disabled | group or option `disabled` | `data-disabled="true"`, native `disabled` on every radio; `fill-muted` circle, `cursor: not-allowed` |
114
114
  | pressed | pointer press | the circle scales to the compact press scale |
115
115
  | focus-visible | keyboard | outer focus ring around the circle |
@@ -159,7 +159,7 @@ No `variant` or `tone`. The trigger is the field look (fill, inset control borde
159
159
  |---|---|---|
160
160
  | empty | no value | `data-placeholder="true"` on Value, placeholder color |
161
161
  | open | `open` / click / arrows | trigger `data-state="open"`, `aria-expanded`; panel `data-state`, `data-side`; chevron turns 180° |
162
- | invalid | `invalid` or `error` | `data-invalid="true"`, `aria-invalid` on the trigger; error text below |
162
+ | invalid | `invalid` or `error` | `data-invalid="true"`, `aria-invalid` on the trigger; error text below; the control shakes once when an error arrives (`data-shake` on the frame) |
163
163
  | disabled | `disabled` | native `disabled`, `data-disabled="true"` |
164
164
  | loading | `loading` | `data-loading="true"`, `aria-busy`; status row in the list |
165
165
  | searching | typing in the search | panel `data-searching="true"`; groups without matches and separators hide; the match in an option's title, description and plain text is a `<mark>` in `accent-text` (not in the trigger) |
@@ -209,7 +209,7 @@ No `variant` or `tone`. The trigger is the field look (fill, inset control borde
209
209
  | [overview.tsx](examples/overview.tsx) | A labelled field with a placeholder; picking an option closes the list and shows its label — `label`, `placeholder`. |
210
210
  | [sizes.tsx](examples/sizes.tsx) | Every size tier; the label, the list rows and the hint take the tier of the field — `size`. |
211
211
  | [states.tsx](examples/states.tsx) | A default field next to a disabled, a loading, an invalid one and a list with nothing in it — `disabled`, `loading`, `invalid`, `labels`. |
212
- | [validation.tsx](examples/validation.tsx) | Required and optional markers, a hint, and an error that replaces the hint in the same row — `required`, `optional`, `hint`, `error`. |
212
+ | [validation.tsx](examples/validation.tsx) | Live validation: unassigning the owner shakes the field and drops the error in, picking someone clears it; required and optional markers and a hint — `required`, `optional`, `hint`, `error`. |
213
213
  | [with-icon.tsx](examples/with-icon.tsx) | A leading icon in the trigger and an icon before every option label — `Select.TriggerIcon`, `Select.ItemIcon`. |
214
214
  | [multiple.tsx](examples/multiple.tsx) | Several values: checkboxes in the list, the list stays open on a pick, labels joined in the trigger — `multiple`. |
215
215
  | [searchable.tsx](examples/searchable.tsx) | A long list with a search field: options match their label and keywords, groups and the separator hide while searching — `searchable`, `keywords`, `Select.Group`. |
@@ -217,7 +217,7 @@ No `variant` or `tone`. The trigger is the field look (fill, inset control borde
217
217
  | [rich-options.tsx](examples/rich-options.tsx) | Options with a picture, a second line and a price; the trigger draws the picked option with the same parts — `renderValue`, `Select.ItemText`, `Select.ItemDescription`, `Select.ItemMeta`. |
218
218
  | [controlled.tsx](examples/controlled.tsx) | The parent owns the value: the plan drives the price under the field and a button resets it — `value`, `onValueChange`. |
219
219
  | [controlled-open.tsx](examples/controlled-open.tsx) | The parent owns the list: a button opens it from code, a pick or Escape closes it — `open`, `onOpenChange`. |
220
- | [in-form.tsx](examples/in-form.tsx) | Regional settings form: the required country is checked on submit, the error replaces the hint — `required`, `error`, `hint`. |
220
+ | [in-form.tsx](examples/in-form.tsx) | Regional settings form: the required country is checked on submit, the error shakes the field and leaves once a country is picked, a calm note confirms the save — `required`, `error`, `hint`. |
221
221
 
222
222
  ## Mistakes
223
223
  - A Label + `aria-labelledby` next to the field → pass `label`, `hint`, `error` to `Select.Root`.
@@ -23,6 +23,7 @@
23
23
 
24
24
  .formActions {
25
25
  display: flex;
26
+ align-items: center;
26
27
  justify-content: flex-end;
27
28
  gap: var(--prime-space-2);
28
29
  }