prime-ui-kit 0.6.0 → 0.7.2

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 (322) hide show
  1. package/dist/components/accordion/examples/02-settings-panels.d.ts.map +1 -1
  2. package/dist/components/accordion/examples/04-api-docs-sections.d.ts.map +1 -1
  3. package/dist/components/accordion/examples/05-knowledge-base-categories.d.ts.map +1 -1
  4. package/dist/components/avatar/examples/app-header-nav.d.ts.map +1 -1
  5. package/dist/components/avatar/examples/src-from-state.d.ts.map +1 -1
  6. package/dist/components/banner/examples/cookie-consent-row.d.ts.map +1 -1
  7. package/dist/components/banner/examples/feature-promo.d.ts.map +1 -1
  8. package/dist/components/button/examples/destructive-confirm.d.ts.map +1 -1
  9. package/dist/components/checkbox/examples/bulk-select-rows.d.ts.map +1 -1
  10. package/dist/components/checkbox/examples/empty-label-form.d.ts.map +1 -1
  11. package/dist/components/checkbox/examples/feature-flags-list.d.ts.map +1 -1
  12. package/dist/components/checkbox/examples/settings-panel.d.ts.map +1 -1
  13. package/dist/components/color-picker/ColorPicker.d.ts.map +1 -1
  14. package/dist/components/color-picker/ColorPickerRac.d.ts.map +1 -1
  15. package/dist/components/color-picker/examples/controlled-form-field.d.ts.map +1 -1
  16. package/dist/components/color-picker/examples/theme-accent.d.ts.map +1 -1
  17. package/dist/components/command-menu/examples/composition-tags-footer.d.ts.map +1 -1
  18. package/dist/components/command-menu/examples/variants-density-items.d.ts.map +1 -1
  19. package/dist/components/datepicker/examples/full-width-form.d.ts.map +1 -1
  20. package/dist/components/digit-input/examples/error-state.d.ts.map +1 -1
  21. package/dist/components/digit-input/examples/resend-and-clear.d.ts.map +1 -1
  22. package/dist/components/divider/examples/section-breaks.d.ts.map +1 -1
  23. package/dist/components/dropdown/Dropdown.d.ts +0 -14
  24. package/dist/components/dropdown/Dropdown.d.ts.map +1 -1
  25. package/dist/components/dropdown/examples/account-menu.d.ts.map +1 -1
  26. package/dist/components/dropdown/examples/actions-menu.d.ts.map +1 -1
  27. package/dist/components/dropdown/examples/full-width.d.ts.map +1 -1
  28. package/dist/components/empty-page/EmptyPage.d.ts +63 -0
  29. package/dist/components/empty-page/EmptyPage.d.ts.map +1 -0
  30. package/dist/components/empty-page/examples/canonical.d.ts +3 -0
  31. package/dist/components/empty-page/examples/canonical.d.ts.map +1 -0
  32. package/dist/components/empty-page/examples/sizes.d.ts +3 -0
  33. package/dist/components/empty-page/examples/sizes.d.ts.map +1 -0
  34. package/dist/components/empty-page/examples/table-region.d.ts +6 -0
  35. package/dist/components/empty-page/examples/table-region.d.ts.map +1 -0
  36. package/dist/components/hint/examples/a11y-describedby.d.ts.map +1 -1
  37. package/dist/components/hint/examples/error-hint.d.ts.map +1 -1
  38. package/dist/components/hint/examples/field-help.d.ts.map +1 -1
  39. package/dist/components/hint/examples/field-states.d.ts.map +1 -1
  40. package/dist/components/hint/examples/inline-tip-form.d.ts.map +1 -1
  41. package/dist/components/hint/examples/success-confirmation.d.ts.map +1 -1
  42. package/dist/components/hint/examples/variants.d.ts.map +1 -1
  43. package/dist/components/index.css +259 -108
  44. package/dist/components/index.css.map +4 -4
  45. package/dist/components/index.d.ts +4 -2
  46. package/dist/components/index.d.ts.map +1 -1
  47. package/dist/components/index.js +639 -477
  48. package/dist/components/index.js.map +4 -4
  49. package/dist/components/input/examples/login-email.d.ts.map +1 -1
  50. package/dist/components/input/examples/search.d.ts.map +1 -1
  51. package/dist/components/link-button/examples/disabled.d.ts.map +1 -1
  52. package/dist/components/link-button/examples/external.d.ts.map +1 -1
  53. package/dist/components/link-button/examples/inline-text-link.d.ts.map +1 -1
  54. package/dist/components/link-button/examples/navigation-cluster.d.ts.map +1 -1
  55. package/dist/components/modal/Modal.d.ts +28 -7
  56. package/dist/components/modal/Modal.d.ts.map +1 -1
  57. package/dist/components/modal/examples/canonical-maximal.d.ts.map +1 -1
  58. package/dist/components/modal/examples/pattern-close-behavior.d.ts.map +1 -1
  59. package/dist/components/modal/examples/pattern-controlled.d.ts.map +1 -1
  60. package/dist/components/modal/examples/pattern-portal-and-scroll.d.ts.map +1 -1
  61. package/dist/components/modal/examples/scenario-confirm-delete.d.ts.map +1 -1
  62. package/dist/components/modal/examples/scenario-edit-entity.d.ts.map +1 -1
  63. package/dist/components/modal/examples/scenario-legal-consent.d.ts.map +1 -1
  64. package/dist/components/modal/examples/scenario-multi-field-form.d.ts.map +1 -1
  65. package/dist/components/notification/examples/action-toast.d.ts.map +1 -1
  66. package/dist/components/notification/examples/error-success.d.ts.map +1 -1
  67. package/dist/components/popover/Popover.d.ts +3 -3
  68. package/dist/components/popover/Popover.d.ts.map +1 -1
  69. package/dist/components/popover/examples/composition.d.ts +1 -1
  70. package/dist/components/popover/examples/date-trigger.d.ts.map +1 -1
  71. package/dist/components/popover/examples/features.d.ts.map +1 -1
  72. package/dist/components/popover/examples/form-in-popover.d.ts.map +1 -1
  73. package/dist/components/popover/examples/full-width.d.ts.map +1 -1
  74. package/dist/components/popover/examples/placement.d.ts.map +1 -1
  75. package/dist/components/popover/examples/rich-content.d.ts.map +1 -1
  76. package/dist/components/popover/examples/sizes.d.ts +1 -1
  77. package/dist/components/progress-bar/examples/step-progress.d.ts.map +1 -1
  78. package/dist/components/progress-circle/examples/dashboard-ring.d.ts.map +1 -1
  79. package/dist/components/progress-circle/examples/states.d.ts.map +1 -1
  80. package/dist/components/radio/examples/plan-picker.d.ts.map +1 -1
  81. package/dist/components/segmented-control/examples/pricing-toggle.d.ts.map +1 -1
  82. package/dist/components/segmented-control/examples/view-mode.d.ts.map +1 -1
  83. package/dist/components/select/Select.d.ts.map +1 -1
  84. package/dist/components/select/examples/01-country.d.ts.map +1 -1
  85. package/dist/components/select/examples/02-controlled.d.ts.map +1 -1
  86. package/dist/components/select/examples/03-groups.d.ts.map +1 -1
  87. package/dist/components/select/examples/04-full-width-form.d.ts.map +1 -1
  88. package/dist/components/switch/examples/composition.d.ts.map +1 -1
  89. package/dist/components/switch/examples/scenario-feature-flag.d.ts.map +1 -1
  90. package/dist/components/tabs/examples/01-settings-vertical-rail.d.ts.map +1 -1
  91. package/dist/components/tag/examples/controlled.d.ts.map +1 -1
  92. package/dist/components/textarea/examples/01-support-ticket.d.ts.map +1 -1
  93. package/dist/components/textarea/examples/02-comment.d.ts.map +1 -1
  94. package/dist/components/textarea/examples/controlled.d.ts.map +1 -1
  95. package/dist/components/textarea/examples/features.d.ts.map +1 -1
  96. package/dist/components/tooltip/examples/composition.d.ts.map +1 -1
  97. package/dist/hooks/useModalKeyboard.d.ts +14 -0
  98. package/dist/hooks/useModalKeyboard.d.ts.map +1 -0
  99. package/dist/index.css +259 -108
  100. package/dist/index.css.map +4 -4
  101. package/dist/index.js +641 -478
  102. package/dist/index.js.map +4 -4
  103. package/dist/internal/states.d.ts +2 -0
  104. package/dist/internal/states.d.ts.map +1 -1
  105. package/package.json +1 -1
  106. package/src/components/accordion/COMPONENT.md +1 -1
  107. package/src/components/accordion/examples/01-faq-marketing.tsx +1 -1
  108. package/src/components/accordion/examples/02-settings-panels.tsx +1 -6
  109. package/src/components/accordion/examples/03-checkout-order-summary.tsx +1 -1
  110. package/src/components/accordion/examples/04-api-docs-sections.tsx +0 -1
  111. package/src/components/accordion/examples/05-knowledge-base-categories.tsx +1 -7
  112. package/src/components/avatar/COMPONENT.md +2 -2
  113. package/src/components/avatar/examples/app-header-nav.tsx +5 -13
  114. package/src/components/avatar/examples/comment-thread.tsx +1 -1
  115. package/src/components/avatar/examples/src-from-state.tsx +0 -1
  116. package/src/components/badge/examples/admin-tags.tsx +6 -6
  117. package/src/components/badge/examples/ecommerce-inventory.tsx +5 -5
  118. package/src/components/badge/examples/inbox-labels.tsx +5 -5
  119. package/src/components/badge/examples/status-presence.tsx +4 -4
  120. package/src/components/banner/examples/controlled-visibility.tsx +1 -1
  121. package/src/components/banner/examples/cookie-consent-row.tsx +0 -1
  122. package/src/components/banner/examples/feature-promo.tsx +0 -1
  123. package/src/components/button/examples/canonical-composition.tsx +4 -4
  124. package/src/components/button/examples/destructive-confirm.tsx +14 -10
  125. package/src/components/button/examples/form-submit-row.tsx +2 -2
  126. package/src/components/button/examples/full-width-stack.tsx +2 -2
  127. package/src/components/button/examples/icon-composition.tsx +6 -6
  128. package/src/components/button/examples/toolbar.tsx +4 -4
  129. package/src/components/button-group/COMPONENT.md +1 -1
  130. package/src/components/button-group/examples/editor-toolbar.tsx +1 -1
  131. package/src/components/button-group/examples/form-footer.tsx +1 -1
  132. package/src/components/button-group/examples/full-width.tsx +1 -1
  133. package/src/components/button-group/examples/view-switcher.tsx +1 -1
  134. package/src/components/button-group/examples/wizard-actions.tsx +1 -1
  135. package/src/components/checkbox/examples/bulk-select-rows.tsx +0 -2
  136. package/src/components/checkbox/examples/empty-label-form.tsx +1 -2
  137. package/src/components/checkbox/examples/feature-flags-list.tsx +0 -1
  138. package/src/components/checkbox/examples/settings-panel.tsx +1 -4
  139. package/src/components/color-picker/COMPONENT.md +2 -2
  140. package/src/components/color-picker/examples/brand-kit.tsx +3 -3
  141. package/src/components/color-picker/examples/controlled-form-field.tsx +4 -6
  142. package/src/components/color-picker/examples/field-eyedropper.tsx +2 -2
  143. package/src/components/color-picker/examples/format-variants.tsx +2 -2
  144. package/src/components/color-picker/examples/full-width.tsx +2 -2
  145. package/src/components/color-picker/examples/minimal-popover.tsx +2 -2
  146. package/src/components/color-picker/examples/panel-placement.tsx +4 -4
  147. package/src/components/color-picker/examples/product-variant-swatch.tsx +2 -2
  148. package/src/components/color-picker/examples/readout-trigger.tsx +2 -2
  149. package/src/components/color-picker/examples/states.tsx +4 -4
  150. package/src/components/color-picker/examples/theme-accent.tsx +2 -7
  151. package/src/components/command-menu/examples/app-palette.tsx +1 -1
  152. package/src/components/command-menu/examples/composition-tags-footer.tsx +2 -7
  153. package/src/components/command-menu/examples/controlled-open-search.tsx +1 -1
  154. package/src/components/command-menu/examples/disabled-items.tsx +1 -1
  155. package/src/components/command-menu/examples/file-search.tsx +1 -1
  156. package/src/components/command-menu/examples/full-width-panel.tsx +1 -1
  157. package/src/components/command-menu/examples/item-icon-as.tsx +1 -1
  158. package/src/components/command-menu/examples/quick-actions.tsx +1 -1
  159. package/src/components/command-menu/examples/variants-density-items.tsx +2 -4
  160. package/src/components/data-table/COMPONENT.md +2 -0
  161. package/src/components/datepicker/examples/birthdate.tsx +2 -2
  162. package/src/components/datepicker/examples/booking.tsx +2 -2
  163. package/src/components/datepicker/examples/full-width-form.tsx +3 -10
  164. package/src/components/datepicker/examples/range-report.tsx +2 -2
  165. package/src/components/digit-input/examples/composition.tsx +3 -3
  166. package/src/components/digit-input/examples/error-state.tsx +3 -5
  167. package/src/components/digit-input/examples/otp-login.tsx +3 -3
  168. package/src/components/digit-input/examples/resend-and-clear.tsx +3 -9
  169. package/src/components/digit-input/examples/verification-step.tsx +4 -4
  170. package/src/components/divider/examples/card-splits.tsx +2 -2
  171. package/src/components/divider/examples/inset-stack.tsx +1 -1
  172. package/src/components/divider/examples/line-spacing-column.tsx +3 -3
  173. package/src/components/divider/examples/section-breaks.tsx +2 -6
  174. package/src/components/drawer/COMPONENT.md +1 -1
  175. package/src/components/drawer/examples/cart-preview.tsx +4 -4
  176. package/src/components/drawer/examples/explicit-panel.tsx +3 -3
  177. package/src/components/drawer/examples/filters-panel.tsx +7 -7
  178. package/src/components/drawer/examples/mobile-nav-sheet.tsx +3 -3
  179. package/src/components/drawer/examples/settings-side.tsx +6 -6
  180. package/src/components/dropdown/COMPONENT.md +5 -18
  181. package/src/components/dropdown/examples/account-menu.tsx +31 -33
  182. package/src/components/dropdown/examples/actions-menu.tsx +0 -1
  183. package/src/components/dropdown/examples/composition.tsx +1 -1
  184. package/src/components/dropdown/examples/controlled.tsx +1 -1
  185. package/src/components/dropdown/examples/dropdown-examples.module.css +0 -4
  186. package/src/components/dropdown/examples/full-width.tsx +0 -1
  187. package/src/components/dropdown/examples/select-like-list.tsx +1 -1
  188. package/src/components/dropdown/examples/states.tsx +1 -1
  189. package/src/components/dropdown/examples/variants.tsx +1 -1
  190. package/src/components/empty-page/COMPONENT.md +143 -0
  191. package/src/components/empty-page/examples/canonical.tsx +22 -0
  192. package/src/components/empty-page/examples/examples-demos.module.css +25 -0
  193. package/src/components/empty-page/examples/sizes.tsx +23 -0
  194. package/src/components/empty-page/examples/table-region.tsx +35 -0
  195. package/src/components/file-upload/examples/full-width.tsx +1 -1
  196. package/src/components/hint/examples/a11y-describedby.tsx +2 -4
  197. package/src/components/hint/examples/controlled-variant.tsx +1 -1
  198. package/src/components/hint/examples/error-hint.tsx +3 -5
  199. package/src/components/hint/examples/field-help.tsx +3 -5
  200. package/src/components/hint/examples/field-states.tsx +9 -19
  201. package/src/components/hint/examples/inline-tip-form.tsx +6 -10
  202. package/src/components/hint/examples/success-confirmation.tsx +3 -5
  203. package/src/components/hint/examples/variants.tsx +3 -9
  204. package/src/components/hint/examples/with-icon.tsx +1 -1
  205. package/src/components/input/examples/affix-url-and-amount.tsx +2 -2
  206. package/src/components/input/examples/checkout-full-width.tsx +2 -2
  207. package/src/components/input/examples/login-email.tsx +1 -5
  208. package/src/components/input/examples/password-with-hint.tsx +1 -1
  209. package/src/components/input/examples/search.tsx +0 -1
  210. package/src/components/kbd/examples/composition-chord-icon.tsx +1 -1
  211. package/src/components/kbd/examples/toolbar-hints.tsx +2 -2
  212. package/src/components/label/examples/with-icon.tsx +1 -1
  213. package/src/components/link-button/COMPONENT.md +1 -1
  214. package/src/components/link-button/examples/composition.tsx +3 -3
  215. package/src/components/link-button/examples/disabled.tsx +2 -4
  216. package/src/components/link-button/examples/external.tsx +1 -6
  217. package/src/components/link-button/examples/inline-text-link.tsx +2 -4
  218. package/src/components/link-button/examples/navigation-cluster.tsx +4 -12
  219. package/src/components/modal/COMPONENT.md +37 -19
  220. package/src/components/modal/examples/canonical-maximal.tsx +15 -11
  221. package/src/components/modal/examples/pattern-close-behavior.tsx +11 -7
  222. package/src/components/modal/examples/pattern-controlled.tsx +9 -7
  223. package/src/components/modal/examples/pattern-full-width-footer.tsx +3 -3
  224. package/src/components/modal/examples/pattern-portal-and-scroll.tsx +9 -7
  225. package/src/components/modal/examples/scenario-confirm-delete.tsx +14 -10
  226. package/src/components/modal/examples/scenario-edit-entity.tsx +18 -14
  227. package/src/components/modal/examples/scenario-legal-consent.tsx +10 -6
  228. package/src/components/modal/examples/scenario-multi-field-form.tsx +18 -20
  229. package/src/components/notification/examples/action-toast.tsx +0 -2
  230. package/src/components/notification/examples/error-success.tsx +0 -2
  231. package/src/components/page-content/COMPONENT.md +1 -0
  232. package/src/components/popover/COMPONENT.md +1 -1
  233. package/src/components/popover/examples/as-child.tsx +1 -1
  234. package/src/components/popover/examples/canonical-panel.tsx +2 -2
  235. package/src/components/popover/examples/composition.tsx +7 -7
  236. package/src/components/popover/examples/controlled.tsx +4 -4
  237. package/src/components/popover/examples/date-trigger.tsx +3 -10
  238. package/src/components/popover/examples/features.tsx +6 -13
  239. package/src/components/popover/examples/form-in-popover.tsx +5 -13
  240. package/src/components/popover/examples/full-width.tsx +2 -9
  241. package/src/components/popover/examples/inset-variants.tsx +6 -6
  242. package/src/components/popover/examples/placement.tsx +2 -7
  243. package/src/components/popover/examples/rich-content.tsx +6 -8
  244. package/src/components/popover/examples/sizes.tsx +5 -5
  245. package/src/components/popover/examples/states.tsx +4 -4
  246. package/src/components/progress-bar/examples/indeterminate-busy-state.tsx +1 -1
  247. package/src/components/progress-bar/examples/step-progress.tsx +0 -1
  248. package/src/components/progress-bar/examples/upload-progress.tsx +1 -1
  249. package/src/components/progress-bar/examples/wizard-composition.tsx +1 -1
  250. package/src/components/progress-circle/examples/a11y-label.tsx +1 -1
  251. package/src/components/progress-circle/examples/composition.tsx +2 -2
  252. package/src/components/progress-circle/examples/dashboard-ring.tsx +1 -6
  253. package/src/components/progress-circle/examples/max-scale.tsx +3 -3
  254. package/src/components/progress-circle/examples/states.tsx +5 -13
  255. package/src/components/radio/examples/notification-channel.tsx +3 -3
  256. package/src/components/radio/examples/plan-picker.tsx +0 -3
  257. package/src/components/radio/examples/settings-group.tsx +4 -4
  258. package/src/components/radio/examples/shipping-method.tsx +3 -3
  259. package/src/components/segmented-control/examples/canonical-composition.tsx +7 -7
  260. package/src/components/segmented-control/examples/composition.tsx +7 -7
  261. package/src/components/segmented-control/examples/features.tsx +3 -3
  262. package/src/components/segmented-control/examples/full-width.tsx +1 -1
  263. package/src/components/segmented-control/examples/pricing-toggle.tsx +0 -1
  264. package/src/components/segmented-control/examples/states.tsx +3 -3
  265. package/src/components/segmented-control/examples/view-mode.tsx +0 -1
  266. package/src/components/segmented-progress-bar/examples/size-ladder.tsx +1 -1
  267. package/src/components/select/COMPONENT.md +3 -3
  268. package/src/components/select/examples/01-country.tsx +2 -4
  269. package/src/components/select/examples/02-controlled.tsx +2 -4
  270. package/src/components/select/examples/03-groups.tsx +2 -4
  271. package/src/components/select/examples/04-full-width-form.tsx +4 -8
  272. package/src/components/select/examples/pattern-composition.tsx +1 -1
  273. package/src/components/select/examples/pattern-controlled.tsx +1 -1
  274. package/src/components/select/examples/pattern-features.tsx +1 -1
  275. package/src/components/select/examples/pattern-full-width.tsx +1 -1
  276. package/src/components/select/examples/pattern-native.tsx +1 -1
  277. package/src/components/select/examples/pattern-states.tsx +4 -4
  278. package/src/components/slider/COMPONENT.md +1 -1
  279. package/src/components/stepper/COMPONENT.md +1 -1
  280. package/src/components/stepper/examples/01-checkout-horizontal.tsx +1 -1
  281. package/src/components/stepper/examples/02-onboarding-vertical.tsx +1 -1
  282. package/src/components/stepper/examples/03-vertical-primitive-rail.tsx +1 -1
  283. package/src/components/stepper/examples/04-checkout-step-error.tsx +1 -1
  284. package/src/components/stepper/examples/05-horizontal-primitive.tsx +1 -1
  285. package/src/components/switch/COMPONENT.md +1 -1
  286. package/src/components/switch/examples/canonical-maximal.tsx +1 -1
  287. package/src/components/switch/examples/composition.tsx +1 -2
  288. package/src/components/switch/examples/controlled.tsx +1 -1
  289. package/src/components/switch/examples/full-width.tsx +1 -1
  290. package/src/components/switch/examples/scenario-billing-annual.tsx +1 -1
  291. package/src/components/switch/examples/scenario-feature-flag.tsx +1 -6
  292. package/src/components/switch/examples/scenario-settings-toggle.tsx +3 -3
  293. package/src/components/switch/examples/states.tsx +6 -6
  294. package/src/components/switch/examples/variants.tsx +2 -2
  295. package/src/components/tabs/COMPONENT.md +1 -1
  296. package/src/components/tabs/examples/01-settings-vertical-rail.tsx +1 -6
  297. package/src/components/tag/COMPONENT.md +1 -1
  298. package/src/components/tag/examples/01-filter-chips.tsx +1 -1
  299. package/src/components/tag/examples/02-removable-selected-values.tsx +1 -1
  300. package/src/components/tag/examples/03-status-metadata.tsx +3 -3
  301. package/src/components/tag/examples/controlled.tsx +1 -6
  302. package/src/components/tag/examples/removable.tsx +1 -1
  303. package/src/components/textarea/examples/01-support-ticket.tsx +0 -1
  304. package/src/components/textarea/examples/02-comment.tsx +1 -2
  305. package/src/components/textarea/examples/composition.tsx +2 -2
  306. package/src/components/textarea/examples/controlled.tsx +0 -1
  307. package/src/components/textarea/examples/features.tsx +3 -12
  308. package/src/components/textarea/examples/full-width.tsx +1 -1
  309. package/src/components/textarea/examples/states.tsx +4 -4
  310. package/src/components/textarea/examples/variants.tsx +2 -2
  311. package/src/components/tooltip/COMPONENT.md +0 -1
  312. package/src/components/tooltip/examples/canonical-icon-hint.tsx +1 -1
  313. package/src/components/tooltip/examples/composition.tsx +3 -9
  314. package/src/components/tooltip/examples/controlled.tsx +2 -2
  315. package/src/components/tooltip/examples/delay.tsx +1 -1
  316. package/src/components/tooltip/examples/long-content.tsx +2 -2
  317. package/src/components/tooltip/examples/side.tsx +4 -4
  318. package/src/components/tooltip/examples/states.tsx +2 -2
  319. package/src/components/tooltip/examples/surfaces.tsx +2 -2
  320. package/dist/components/dropdown/examples/inset.d.ts +0 -3
  321. package/dist/components/dropdown/examples/inset.d.ts.map +0 -1
  322. package/src/components/dropdown/examples/inset.tsx +0 -51
@@ -0,0 +1,35 @@
1
+ import { PackagePlus } from "lucide-react";
2
+ import { Button, EmptyPage } from "prime-ui-kit";
3
+
4
+ import styles from "./examples-demos.module.css";
5
+
6
+ /**
7
+ * Пустое состояние в «области таблицы»: родитель с фиксированной минимальной высотой,
8
+ * `layout="fill"` растягивает блок и центрирует содержимое.
9
+ */
10
+ export function EmptyPageTableRegion() {
11
+ return (
12
+ <div>
13
+ <p className={styles.lead}>
14
+ Имитация тела таблицы или карточки со списком: обводка задаёт границу области данных.
15
+ </p>
16
+ <div className={styles.tableRegion}>
17
+ <EmptyPage.Root layout="fill" aria-labelledby="empty-table-heading">
18
+ <EmptyPage.Icon aria-hidden>
19
+ <PackagePlus strokeWidth={2} aria-hidden />
20
+ </EmptyPage.Icon>
21
+ <EmptyPage.Title id="empty-table-heading">Пока нет позиций</EmptyPage.Title>
22
+ <EmptyPage.Description>
23
+ Импортируйте каталог или создайте первую строку вручную — таблица заполнится
24
+ автоматически.
25
+ </EmptyPage.Description>
26
+ <EmptyPage.Actions>
27
+ <Button.Root type="button" variant="primary">
28
+ Добавить позицию
29
+ </Button.Root>
30
+ </EmptyPage.Actions>
31
+ </EmptyPage.Root>
32
+ </div>
33
+ </div>
34
+ );
35
+ }
@@ -26,7 +26,7 @@ export function FileUploadFullWidthExample() {
26
26
  >
27
27
  Родитель на всю колонку: зона тянется вместе с формой или панелью.
28
28
  </p>
29
- <FileUpload.Root size="m" appearance="solid" />
29
+ <FileUpload.Root appearance="solid" />
30
30
  </div>
31
31
  );
32
32
  }
@@ -4,9 +4,7 @@ import { Hint, Label } from "prime-ui-kit";
4
4
  export default function HintA11yDescribedbyExample() {
5
5
  return (
6
6
  <>
7
- <Label.Root htmlFor="hint-ex-a11y-volume" size="m">
8
- Notification volume
9
- </Label.Root>
7
+ <Label.Root htmlFor="hint-ex-a11y-volume">Notification volume</Label.Root>
10
8
  <input
11
9
  id="hint-ex-a11y-volume"
12
10
  type="range"
@@ -15,7 +13,7 @@ export default function HintA11yDescribedbyExample() {
15
13
  defaultValue={40}
16
14
  aria-describedby="hint-ex-a11y-volume-help"
17
15
  />
18
- <Hint.Root id="hint-ex-a11y-volume-help" size="m" variant="default">
16
+ <Hint.Root id="hint-ex-a11y-volume-help" variant="default">
19
17
  Does not affect calls and alarms in the mobile app.
20
18
  </Hint.Root>
21
19
  </>
@@ -13,7 +13,7 @@ export default function HintControlledVariantExample() {
13
13
  <Button.Root size="s" variant="error" mode="lighter" onClick={() => setVariant("error")}>
14
14
  Show error
15
15
  </Button.Root>
16
- <Hint.Root size="m" variant={variant}>
16
+ <Hint.Root variant={variant}>
17
17
  {variant === "error"
18
18
  ? "Fill the field before saving the draft."
19
19
  : "You can save the draft without required fields."}
@@ -6,15 +6,13 @@ export default function ErrorHintExample() {
6
6
 
7
7
  return (
8
8
  <>
9
- <Label.Root htmlFor="hint-example-error" size="m">
10
- Tax ID
11
- </Label.Root>
12
- <Input.Root size="m" id="hint-example-error" hasError>
9
+ <Label.Root htmlFor="hint-example-error">Tax ID</Label.Root>
10
+ <Input.Root id="hint-example-error" hasError>
13
11
  <Input.Wrapper>
14
12
  <Input.Field type="text" defaultValue="12" aria-describedby={hintId} />
15
13
  </Input.Wrapper>
16
14
  </Input.Root>
17
- <Hint.Root id={hintId} size="m" variant="error" role="alert">
15
+ <Hint.Root id={hintId} variant="error" role="alert">
18
16
  Enter 10 or 12 digits.
19
17
  </Hint.Root>
20
18
  </>
@@ -6,10 +6,8 @@ export default function FieldHelpExample() {
6
6
 
7
7
  return (
8
8
  <>
9
- <Label.Root htmlFor="hint-example-field-help" size="m">
10
- Project name
11
- </Label.Root>
12
- <Input.Root size="m" id="hint-example-field-help">
9
+ <Label.Root htmlFor="hint-example-field-help">Project name</Label.Root>
10
+ <Input.Root id="hint-example-field-help">
13
11
  <Input.Wrapper>
14
12
  <Input.Field
15
13
  type="text"
@@ -19,7 +17,7 @@ export default function FieldHelpExample() {
19
17
  />
20
18
  </Input.Wrapper>
21
19
  </Input.Root>
22
- <Hint.Root id={hintId} size="m" variant="default">
20
+ <Hint.Root id={hintId} variant="default">
23
21
  Visible to everyone in this workspace.
24
22
  </Hint.Root>
25
23
  </>
@@ -4,41 +4,31 @@ import { Hint, Input, Label } from "prime-ui-kit";
4
4
  export default function HintFieldStatesExample() {
5
5
  return (
6
6
  <>
7
- <Label.Root htmlFor="hint-ex-st-ok" size="m">
8
- Project name
9
- </Label.Root>
10
- <Input.Root size="m" id="hint-ex-st-ok">
7
+ <Label.Root htmlFor="hint-ex-st-ok">Project name</Label.Root>
8
+ <Input.Root id="hint-ex-st-ok">
11
9
  <Input.Wrapper>
12
10
  <Input.Field type="text" defaultValue="Alpha" />
13
11
  </Input.Wrapper>
14
12
  </Input.Root>
15
- <Hint.Root size="m" variant="default">
16
- Visible to everyone in this workspace.
17
- </Hint.Root>
13
+ <Hint.Root variant="default">Visible to everyone in this workspace.</Hint.Root>
18
14
 
19
- <Label.Root htmlFor="hint-ex-st-err" size="m">
20
- Tax ID
21
- </Label.Root>
22
- <Input.Root size="m" id="hint-ex-st-err" hasError>
15
+ <Label.Root htmlFor="hint-ex-st-err">Tax ID</Label.Root>
16
+ <Input.Root id="hint-ex-st-err" hasError>
23
17
  <Input.Wrapper>
24
18
  <Input.Field type="text" defaultValue="12" />
25
19
  </Input.Wrapper>
26
20
  </Input.Root>
27
- <Hint.Root size="m" variant="error">
28
- Enter 10 or 12 digits.
29
- </Hint.Root>
21
+ <Hint.Root variant="error">Enter 10 or 12 digits.</Hint.Root>
30
22
 
31
- <Label.Root htmlFor="hint-ex-st-dis" size="m" disabled>
23
+ <Label.Root htmlFor="hint-ex-st-dis" disabled>
32
24
  Request limit
33
25
  </Label.Root>
34
- <Input.Root size="m" id="hint-ex-st-dis">
26
+ <Input.Root id="hint-ex-st-dis">
35
27
  <Input.Wrapper>
36
28
  <Input.Field type="text" disabled defaultValue="read only" />
37
29
  </Input.Wrapper>
38
30
  </Input.Root>
39
- <Hint.Root size="m" variant="disabled">
40
- Value comes from the plan and cannot be edited.
41
- </Hint.Root>
31
+ <Hint.Root variant="disabled">Value comes from the plan and cannot be edited.</Hint.Root>
42
32
  </>
43
33
  );
44
34
  }
@@ -7,10 +7,8 @@ export default function InlineTipFormExample() {
7
7
 
8
8
  return (
9
9
  <>
10
- <Label.Root htmlFor="hint-example-form-email" size="m">
11
- Billing email
12
- </Label.Root>
13
- <Input.Root size="m" id="hint-example-form-email">
10
+ <Label.Root htmlFor="hint-example-form-email">Billing email</Label.Root>
11
+ <Input.Root id="hint-example-form-email">
14
12
  <Input.Wrapper>
15
13
  <Input.Field
16
14
  type="email"
@@ -19,14 +17,12 @@ export default function InlineTipFormExample() {
19
17
  />
20
18
  </Input.Wrapper>
21
19
  </Input.Root>
22
- <Hint.Root id={emailHintId} size="m" variant="default">
20
+ <Hint.Root id={emailHintId} variant="default">
23
21
  Invoices and receipts go here; not the same as your login email.
24
22
  </Hint.Root>
25
23
 
26
- <Label.Root htmlFor="hint-example-form-budget" size="m">
27
- Monthly budget
28
- </Label.Root>
29
- <Input.Root size="m" id="hint-example-form-budget">
24
+ <Label.Root htmlFor="hint-example-form-budget">Monthly budget</Label.Root>
25
+ <Input.Root id="hint-example-form-budget">
30
26
  <Input.Wrapper>
31
27
  <Input.Field
32
28
  type="text"
@@ -36,7 +32,7 @@ export default function InlineTipFormExample() {
36
32
  />
37
33
  </Input.Wrapper>
38
34
  </Input.Root>
39
- <Hint.Root id={budgetHintId} size="m" variant="disabled">
35
+ <Hint.Root id={budgetHintId} variant="disabled">
40
36
  Optional — leave empty to use the workspace default.
41
37
  </Hint.Root>
42
38
  </>
@@ -9,10 +9,8 @@ export default function SuccessConfirmationExample() {
9
9
 
10
10
  return (
11
11
  <>
12
- <Label.Root htmlFor="hint-example-success" size="m">
13
- API token
14
- </Label.Root>
15
- <Input.Root size="m" id="hint-example-success">
12
+ <Label.Root htmlFor="hint-example-success">API token</Label.Root>
13
+ <Input.Root id="hint-example-success">
16
14
  <Input.Wrapper>
17
15
  <Input.Field
18
16
  type="text"
@@ -22,7 +20,7 @@ export default function SuccessConfirmationExample() {
22
20
  />
23
21
  </Input.Wrapper>
24
22
  </Input.Root>
25
- <Hint.Root id={hintId} size="m" variant="default">
23
+ <Hint.Root id={hintId} variant="default">
26
24
  Token saved. Rotate it from settings anytime.
27
25
  </Hint.Root>
28
26
  </>
@@ -4,15 +4,9 @@ import { Hint } from "prime-ui-kit";
4
4
  export default function HintVariantsExample() {
5
5
  return (
6
6
  <>
7
- <Hint.Root size="m" variant="default">
8
- Neutral helper or format guidance.
9
- </Hint.Root>
10
- <Hint.Root size="m" variant="error">
11
- Value does not meet password policy requirements.
12
- </Hint.Root>
13
- <Hint.Root size="m" variant="disabled">
14
- Editing is not available for the selected role.
15
- </Hint.Root>
7
+ <Hint.Root variant="default">Neutral helper or format guidance.</Hint.Root>
8
+ <Hint.Root variant="error">Value does not meet password policy requirements.</Hint.Root>
9
+ <Hint.Root variant="disabled">Editing is not available for the selected role.</Hint.Root>
16
10
  </>
17
11
  );
18
12
  }
@@ -3,7 +3,7 @@ import { Hint, Icon } from "prime-ui-kit";
3
3
  /** Decorative leading icon; meaning must be repeated in text (`Hint.Icon` is `aria-hidden`). */
4
4
  export default function HintWithIconExample() {
5
5
  return (
6
- <Hint.Root size="m" variant="default">
6
+ <Hint.Root variant="default">
7
7
  <Hint.Icon>
8
8
  <Icon name="field.email" tone="subtle" />
9
9
  </Hint.Icon>
@@ -6,14 +6,14 @@ import { Input } from "prime-ui-kit";
6
6
  export default function AffixUrlAndAmountExample() {
7
7
  return (
8
8
  <>
9
- <Input.Root size="m" label="Сайт" hint="Поддомен без схемы">
9
+ <Input.Root label="Сайт" hint="Поддомен без схемы">
10
10
  <Input.Wrapper>
11
11
  <Input.Affix side="start">https://</Input.Affix>
12
12
  <Input.Field placeholder="поддомен" />
13
13
  <Input.Affix side="end">.example</Input.Affix>
14
14
  </Input.Wrapper>
15
15
  </Input.Root>
16
- <Input.Root size="m" label="Сумма" hint="Дробная часть через запятую">
16
+ <Input.Root label="Сумма" hint="Дробная часть через запятую">
17
17
  <Input.Wrapper>
18
18
  <Input.InlineAffix side="start">₽</Input.InlineAffix>
19
19
  <Input.Field placeholder="0,00" inputMode="decimal" />
@@ -12,7 +12,7 @@ export default function CheckoutFullWidthExample() {
12
12
 
13
13
  return (
14
14
  <div className={styles.column}>
15
- <Input.Root size="m" label="ФИО получателя" hint="Как в паспорте — для доставки">
15
+ <Input.Root label="ФИО получателя" hint="Как в паспорте — для доставки">
16
16
  <Input.Wrapper>
17
17
  <Input.Field
18
18
  name="fullName"
@@ -23,7 +23,7 @@ export default function CheckoutFullWidthExample() {
23
23
  />
24
24
  </Input.Wrapper>
25
25
  </Input.Root>
26
- <Input.Root size="m" label="Адрес доставки" optionalLabel="квартира, подъезд">
26
+ <Input.Root label="Адрес доставки" optionalLabel="квартира, подъезд">
27
27
  <Input.Wrapper>
28
28
  <Input.Field
29
29
  name="address"
@@ -8,11 +8,7 @@ export default function LoginEmailExample() {
8
8
  const [email, setEmail] = React.useState("");
9
9
 
10
10
  return (
11
- <Input.Root
12
- size="m"
13
- label="Электронная почта"
14
- hint="Мы отправим код подтверждения на этот адрес"
15
- >
11
+ <Input.Root label="Электронная почта" hint="Мы отправим код подтверждения на этот адрес">
16
12
  <Input.Wrapper>
17
13
  <Input.Icon side="start">
18
14
  <Icon name="field.email" size="s" tone="subtle" />
@@ -8,7 +8,7 @@ export default function PasswordWithHintExample() {
8
8
  const [password, setPassword] = React.useState("");
9
9
 
10
10
  return (
11
- <Input.Root size="m" label="Пароль" hint="Не менее 8 символов, буквы и цифры">
11
+ <Input.Root label="Пароль" hint="Не менее 8 символов, буквы и цифры">
12
12
  <Input.Wrapper>
13
13
  <Input.Field
14
14
  type="password"
@@ -9,7 +9,6 @@ export default function SearchExample() {
9
9
 
10
10
  return (
11
11
  <Input.Root
12
- size="m"
13
12
  label="Поиск по каталогу"
14
13
  hint={query ? `Запрос: «${query}»` : "Введите название или артикул"}
15
14
  >
@@ -24,7 +24,7 @@ export default function KbdCompositionChordIconExample() {
24
24
  <Kbd.Root>K</Kbd.Root>
25
25
  </div>
26
26
  <div style={row}>
27
- <Kbd.Root size="m">
27
+ <Kbd.Root>
28
28
  <Icon name="action.close" aria-hidden />
29
29
  <span>Esc</span>
30
30
  </Kbd.Root>
@@ -19,11 +19,11 @@ export default function ToolbarHintsExample() {
19
19
  return (
20
20
  <div role="toolbar" aria-label="Formatting" style={toolbar}>
21
21
  <div style={hintCluster}>
22
- <Button.Root size="m">Bold</Button.Root>
22
+ <Button.Root>Bold</Button.Root>
23
23
  <Kbd.Root size="s">⌘B</Kbd.Root>
24
24
  </div>
25
25
  <div style={hintCluster}>
26
- <Button.Root size="m">Italic</Button.Root>
26
+ <Button.Root>Italic</Button.Root>
27
27
  <Kbd.Root size="s">⌘I</Kbd.Root>
28
28
  </div>
29
29
  </div>
@@ -4,7 +4,7 @@ import { Icon, Label } from "prime-ui-kit";
4
4
  export function WithIconExample() {
5
5
  return (
6
6
  <>
7
- <Label.Root size="m" htmlFor="example-label-icon-upload">
7
+ <Label.Root htmlFor="example-label-icon-upload">
8
8
  <Label.Icon>
9
9
  <Icon aria-hidden name="action.upload" />
10
10
  </Label.Icon>
@@ -9,7 +9,7 @@ Text-style **navigation** control: **`LinkButton.Root`** only — control typogr
9
9
  ```tsx
10
10
  import { LinkButton } from "prime-ui-kit";
11
11
 
12
- <LinkButton.Root href="/settings" size="m">
12
+ <LinkButton.Root href="/settings">
13
13
  Settings
14
14
  </LinkButton.Root>
15
15
  ```
@@ -11,15 +11,15 @@ export default function LinkButtonCompositionExample() {
11
11
 
12
12
  return (
13
13
  <div style={rowStyle}>
14
- <LinkButton.Root href="#" size="m">
14
+ <LinkButton.Root href="#">
15
15
  <Icon name="field.email" size="s" />
16
16
  Link with icon on the left
17
17
  </LinkButton.Root>
18
- <LinkButton.Root href="#" size="m">
18
+ <LinkButton.Root href="#">
19
19
  Icon on the right
20
20
  <Icon name="action.close" size="s" />
21
21
  </LinkButton.Root>
22
- <LinkButton.Root href="#" size="m" aria-label="Open profile">
22
+ <LinkButton.Root href="#" aria-label="Open profile">
23
23
  <Icon name="field.email" size="s" />
24
24
  </LinkButton.Root>
25
25
  </div>
@@ -8,10 +8,8 @@ import { LinkButton } from "prime-ui-kit";
8
8
  export default function LinkButtonDisabledExample() {
9
9
  return (
10
10
  <div>
11
- <LinkButton.Root href="/available" size="m">
12
- Available route
13
- </LinkButton.Root>
14
- <LinkButton.Root href="/ignored-when-disabled" size="m" disabled>
11
+ <LinkButton.Root href="/available">Available route</LinkButton.Root>
12
+ <LinkButton.Root href="/ignored-when-disabled" disabled>
15
13
  Coming soon
16
14
  </LinkButton.Root>
17
15
  </div>
@@ -5,12 +5,7 @@ export default function LinkButtonExternalExample() {
5
5
  return (
6
6
  <p>
7
7
  Documentation in a separate tab:{" "}
8
- <LinkButton.Root
9
- href="https://example.com/docs"
10
- target="_blank"
11
- rel="noopener noreferrer"
12
- size="m"
13
- >
8
+ <LinkButton.Root href="https://example.com/docs" target="_blank" rel="noopener noreferrer">
14
9
  Open help
15
10
  </LinkButton.Root>
16
11
  </p>
@@ -5,10 +5,8 @@ export default function LinkButtonInlineTextLinkExample() {
5
5
  return (
6
6
  <p>
7
7
  Need more detail? See{" "}
8
- <LinkButton.Root href="/docs/billing" size="m">
9
- billing documentation
10
- </LinkButton.Root>{" "}
11
- for proration rules.
8
+ <LinkButton.Root href="/docs/billing">billing documentation</LinkButton.Root> for proration
9
+ rules.
12
10
  </p>
13
11
  );
14
12
  }
@@ -4,21 +4,13 @@ import { LinkButton } from "prime-ui-kit";
4
4
  export default function LinkButtonNavigationClusterExample() {
5
5
  return (
6
6
  <nav aria-label="Product sections">
7
- <LinkButton.Root href="/product/overview" size="m">
8
- Overview
9
- </LinkButton.Root>
7
+ <LinkButton.Root href="/product/overview">Overview</LinkButton.Root>
10
8
  <span aria-hidden> · </span>
11
- <LinkButton.Root href="/product/pricing" size="m">
12
- Pricing
13
- </LinkButton.Root>
9
+ <LinkButton.Root href="/product/pricing">Pricing</LinkButton.Root>
14
10
  <span aria-hidden> · </span>
15
- <LinkButton.Root href="/product/security" size="m">
16
- Security
17
- </LinkButton.Root>
11
+ <LinkButton.Root href="/product/security">Security</LinkButton.Root>
18
12
  <span aria-hidden> · </span>
19
- <LinkButton.Root href="/product/changelog" size="m">
20
- Changelog
21
- </LinkButton.Root>
13
+ <LinkButton.Root href="/product/changelog">Changelog</LinkButton.Root>
22
14
  </nav>
23
15
  );
24
16
  }
@@ -12,10 +12,11 @@ Centered overlay dialog with a portal, backdrop, focus trap, scroll lock, and op
12
12
 
13
13
  ## Composition
14
14
 
15
- - **`Modal.Root`** — holds open state (controlled via **`open`** / **`onOpenChange`** or uncontrolled via **`defaultOpen`**), and options **`closeOnEscape`** / **`closeOnOverlayClick`**. Renders **`children`** only (no DOM wrapper).
15
+ - **`Modal.Root`** — holds open state (controlled via **`open`** / **`onOpenChange`** or uncontrolled via **`defaultOpen`**), and options **`closeOnEscape`** / **`closeOnOverlayClick`**, **`confirmOnEnter`** / **`onEnterConfirm`** (подтверждение по Enter). Renders **`children`** only (no DOM wrapper).
16
16
  - **`Modal.Trigger`** — optional; **`React.Children.only`**: pass **exactly one** React element; its **`onClick`** is merged to call **`onOpen`** when the event is not **`defaultPrevented`**.
17
17
  - **`Modal.Panel`** — when open: **`createPortal`** (default container `document.body`), fullscreen **`role="presentation"`** overlay, then **`role="dialog"`** with **`aria-modal="true"`**. If **`title`** is set, renders an internal header (**`h2`**, optional description, optional built-in close icon button), wraps **`children`** in an internal body, and optional **`footer`**. Without **`title`**, **`children`** render directly inside the dialog surface—supply **`aria-label`** or **`aria-labelledby`** (and **`aria-describedby`** when needed).
18
- - **`Modal.Close`** — same single-child contract as **`Trigger`**; merges **`onClick`** to **`onClose`** when not **`defaultPrevented`**. Typical placement: a control inside **`footer`** (for example **Cancel** or **Save** when saving should dismiss the dialog).
18
+ - **`Modal.Close`** — same single-child contract as **`Trigger`**; merges **`onClick`** and **`ref`** to the child so **`Modal.Footer`** **`primary`** can register the DOM node for Enter. Typical placement: a control inside **`Modal.Footer`** (for example **Cancel** or **Save** when saving should dismiss the dialog).
19
+ - **`Modal.Footer`** — **`footer`** prop on **`Modal.Panel`**: предпочтительно **`Modal.Footer`** со слотами **`secondary`** (отмена, слева/раньше в разметке), **`extra`** (дополнительные кнопки между отменой и подтверждением), **`primary`** (основное действие и цель **Enter** при **`confirmOnEnter`**). Порядок в DOM: **`secondary` → `extra` → `primary`** (в LTR с **`justify-content: flex-end`** основная кнопка справа). **`primary`** — один **`React.ReactElement`** (например **`Button.Root`** или **`Modal.Close`** с кнопкой). Произвольная разметка без **`Modal.Footer`** — допустима как **`footer`**, но подтверждение по Enter к целевой кнопке не привязывается.
19
20
  - **Order:** **`Modal.Root`** → **`Modal.Trigger`** (if any) and **`Modal.Panel`** as siblings (or only **`Modal.Panel`** in controlled flows).
20
21
 
21
22
  ### Minimal example
@@ -39,7 +40,7 @@ export function Example() {
39
40
 
40
41
  ### Canonical example (full shell)
41
42
 
42
- Use this when you want the complete header row (**`title`**, **`description`**, **`icon`**), a form field in the body, and a **`footer`** where at least one control is wrapped in **`Modal.Close`** (here: **Cancel**). The header still shows the built-in icon close button by default (`showClose`).
43
+ Use this when you want the complete header row (**`title`**, **`description`**, **`icon`**), a form field in the body, and a **`Modal.Footer`** with **`secondary`** (**Cancel** via **`Modal.Close`**) and **`primary`**. The header still shows the built-in icon close button by default (`showClose`).
43
44
 
44
45
  ```tsx
45
46
  import { Button, Icon, Input, Modal } from "prime-ui-kit";
@@ -48,7 +49,7 @@ export function InviteTeammateModal() {
48
49
  return (
49
50
  <Modal.Root>
50
51
  <Modal.Trigger>
51
- <Button.Root size="m" variant="neutral" mode="stroke">
52
+ <Button.Root variant="neutral" mode="stroke">
52
53
  Open workspace invite
53
54
  </Button.Root>
54
55
  </Modal.Trigger>
@@ -57,19 +58,23 @@ export function InviteTeammateModal() {
57
58
  description="We will send one invitation email. The recipient can accept or decline."
58
59
  icon={<Icon name="field.email" tone="subtle" />}
59
60
  footer={
60
- <>
61
- <Modal.Close>
62
- <Button.Root size="m" variant="neutral" mode="stroke">
63
- Cancel
61
+ <Modal.Footer
62
+ primary={
63
+ <Button.Root variant="primary" type="button">
64
+ Send invite
64
65
  </Button.Root>
65
- </Modal.Close>
66
- <Button.Root size="m" variant="primary" type="button">
67
- Send invite
68
- </Button.Root>
69
- </>
66
+ }
67
+ secondary={
68
+ <Modal.Close>
69
+ <Button.Root variant="neutral" mode="stroke">
70
+ Cancel
71
+ </Button.Root>
72
+ </Modal.Close>
73
+ }
74
+ />
70
75
  }
71
76
  >
72
- <Input.Root label="Email address" size="m" hint="Work email preferred">
77
+ <Input.Root label="Email address" hint="Work email preferred">
73
78
  <Input.Wrapper>
74
79
  <Input.Field autoComplete="email" placeholder="name@company.com" type="email" />
75
80
  </Input.Wrapper>
@@ -116,11 +121,12 @@ Runnable examples use `@/` in the workspace; published consumers import **`prime
116
121
  - **Dismiss on primary action:** wrap the confirming button in **`Modal.Close`** when the action should close the dialog immediately (see **edit entity** example). If you must await an API call, keep the dialog open until success, then call **`onOpenChange(false)`** from the parent.
117
122
  - **Consent / wizard steps:** set **`closeOnOverlayClick={false}`** (and optionally **`closeOnEscape={false}`**) when accidental dismiss would lose legal or multi-step state; still provide an explicit **`Modal.Close`** (or header close) path where appropriate.
118
123
  - **Long body content:** constrain scroll to the body via **`bodyStyle`** / **`bodyClassName`** (see `playground/snippets/modal/features.tsx`); overlay scroll lock remains active.
124
+ - **Enter to confirm:** при **`confirmOnEnter={true}`** (по умолчанию) **Enter** внутри диалога имитирует **`click()`** по элементу из слота **`Modal.Footer`** **`primary`** (логика в **`useModalKeyboard`** вместе с Escape). В шапке (**`header`**) нативное поведение **Enter** на кнопке закрытия сохраняется; в **`textarea`** / **`select`** и ряде типов **`input`** подтверждение по Enter не срабатывает. Полностью своё поведение — **`onEnterConfirm`** на **`Modal.Root`**; отключить — **`confirmOnEnter={false}`**.
119
125
  - **Headless dialog surface:** omit **`title`** on **`Modal.Panel`** and supply **`aria-label`** or **`aria-labelledby`** / **`aria-describedby`** yourself; inner body wrapper is not used, so **`bodyClassName`** / **`bodyStyle`** do not apply.
120
126
 
121
127
  ### Note for LLMs
122
128
 
123
- When generating **Modal** markup for this library: (1) **`Modal.Trigger`** and **`Modal.Close`** each require **exactly one** child element—no fragments or multiple nodes. (2) Prefer **`Modal.Panel`** with **`title`** (and usually **`description`**) so **`aria-labelledby`** / **`aria-describedby`** are wired automatically. (3) Put **Cancel** / **Dismiss** in **`footer`** inside **`Modal.Close`** unless the design relies only on the header icon. (4) Do not wrap kit components to restyle them; use **`size`**, **`variant`**, **`mode`**, and documented props only. (5) For copy-paste starting points, mirror **`examples/canonical-maximal.tsx`** first, then **`examples/pattern-*`** or scenario files; playground **`playground/snippets/modal/*.tsx`** are the live-demo source of truth.
129
+ When generating **Modal** markup for this library: (1) **`Modal.Trigger`** and **`Modal.Close`** each require **exactly one** child element—no fragments or multiple nodes. (2) Prefer **`Modal.Panel`** with **`title`** (and usually **`description`**) so **`aria-labelledby`** / **`aria-describedby`** are wired automatically. (3) Use **`Modal.Footer`** with **`secondary`** (**`Modal.Close`** + cancel) and **`primary`** (main action) unless the design relies only on the header icon. (4) Do not wrap kit components to restyle them; use **`size`**, **`variant`**, **`mode`**, and documented props only. (5) For copy-paste starting points, mirror **`examples/canonical-maximal.tsx`** first, then **`examples/pattern-*`** or scenario files; playground **`playground/snippets/modal/*.tsx`** are the live-demo source of truth.
124
130
 
125
131
  ## Rules
126
132
 
@@ -133,7 +139,7 @@ When generating **Modal** markup for this library: (1) **`Modal.Trigger`** and *
133
139
  - **Focus:** focus is trapped inside the dialog while open; initial focus follows browser / trap behavior—ensure a focusable control or manage focus if the first paint is static text only.
134
140
  - **`showClose`** (default **`true`** when a header is shown) controls the header icon button; **`closeAriaLabel`** defaults to **`"Close"`**.
135
141
  - **`container`** on **`Modal.Panel`** overrides the portal target (for tests or custom stacking); default is **`document.body`**.
136
- - **`overlayClassName`**, **`footerClassName`**, **`bodyClassName`**, and **`bodyStyle`** target the overlay, **`<footer>`**, and body wrapper respectively; without **`title`**, **`bodyClassName`** / **`bodyStyle`** do not apply (no inner body wrapper).
142
+ - **`overlayClassName`**, **`footerClassName`**, **`bodyClassName`**, and **`bodyStyle`** target the overlay, the **`footer`** element (merged into **`Modal.Footer`** when **`footer`** is **`Modal.Footer`**, else a wrapper **`<footer>`** for arbitrary content), and body wrapper respectively; without **`title`**, **`bodyClassName`** / **`bodyStyle`** do not apply (no inner body wrapper).
137
143
 
138
144
  ## API
139
145
 
@@ -146,6 +152,8 @@ When generating **Modal** markup for this library: (1) **`Modal.Trigger`** and *
146
152
  | onOpenChange | `(open: boolean) => void` | — | No | Fires when open state changes |
147
153
  | closeOnEscape | `boolean` | `true` | No | Whether Escape closes the dialog |
148
154
  | closeOnOverlayClick | `boolean` | `true` | No | Whether a direct backdrop click closes |
155
+ | confirmOnEnter | `boolean` | `true` | No | Whether Enter triggers the default confirmation action (primary button) |
156
+ | onEnterConfirm | `(event: KeyboardEvent) => void` | — | No | Replaces default Enter confirmation; call `event.preventDefault()` if needed to suppress native control behavior |
149
157
  | children | `React.ReactNode` | — | No | e.g. `Modal.Trigger` and `Modal.Panel` |
150
158
 
151
159
  ### Modal.Trigger
@@ -158,7 +166,17 @@ When generating **Modal** markup for this library: (1) **`Modal.Trigger`** and *
158
166
 
159
167
  | Prop | Type | Default | Required | Description |
160
168
  |------|------|---------|----------|-------------|
161
- | children | `React.ReactElement<{ onClick?: React.MouseEventHandler; className?: string; size?: "s" \| "m" \| "l" \| "xl" }>` | — | Yes | Single element whose `onClick` is composed with close |
169
+ | children | `React.ReactElement<{ onClick?: React.MouseEventHandler; ref?: React.Ref<HTMLElement>; className?: string; size?: "s" \| "m" \| "l" \| "xl" }>` | — | Yes | Single element whose `onClick` and `ref` are composed with close |
170
+
171
+ ### Modal.Footer
172
+
173
+ | Prop | Type | Default | Required | Description |
174
+ |------|------|---------|----------|-------------|
175
+ | primary | `React.ReactElement` (e.g. `Button.Root`) | — | No | Main action; target for Enter when `confirmOnEnter` and no `onEnterConfirm` |
176
+ | secondary | `React.ReactNode` | — | No | Usually cancel / `Modal.Close` |
177
+ | extra | `React.ReactNode` | — | No | Additional buttons between `secondary` and `primary` |
178
+ | className | `string` | — | No | Class on the `<footer>` |
179
+ | …rest | `Omit<React.HTMLAttributes<HTMLElement>, "children">` | — | No | Other attributes on `<footer>` |
162
180
 
163
181
  ### Modal.Panel
164
182
 
@@ -170,10 +188,10 @@ When generating **Modal** markup for this library: (1) **`Modal.Trigger`** and *
170
188
  | showClose | `boolean` | `true` | No | Header close icon button when `title` is set |
171
189
  | closeAriaLabel | `string` | `"Close"` | No | `aria-label` for the header close control |
172
190
  | children | `React.ReactNode` | — | No | Main content; wrapped in internal body when `title` is set |
173
- | footer | `React.ReactNode` | — | No | Rendered in an internal `footer` |
191
+ | footer | `React.ReactNode` | — | No | Prefer **`Modal.Footer`**; arbitrary nodes are wrapped in **`<footer>`** without Enter binding |
174
192
  | container | `HTMLElement \| null` | `document.body` | No | Portal mount node |
175
193
  | overlayClassName | `string` | — | No | Class on the fullscreen backdrop |
176
- | footerClassName | `string` | — | No | Class on the `footer` element |
194
+ | footerClassName | `string` | — | No | Merged into **`Modal.Footer`** `className` when **`footer`** is **`Modal.Footer`**; else on wrapper **`<footer>`** |
177
195
  | bodyClassName | `string` | — | No | Class on the internal body when `title` is set |
178
196
  | bodyStyle | `React.CSSProperties` | — | No | Inline style on the internal body when `title` is set |
179
197
  | aria-label | `string` | — | No | Dialog name when there is no `title`-driven label |