@konce-pt/react 0.12.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (378) hide show
  1. package/README.md +122 -64
  2. package/dist/accordion/accordion.d.ts +14 -6
  3. package/dist/accordion/accordion.js +14 -7
  4. package/dist/accordion/llms.txt +22 -10
  5. package/dist/alert/alert.d.ts +2 -2
  6. package/dist/alert/alert.js +2 -2
  7. package/dist/alert/llms.txt +10 -10
  8. package/dist/app-shell/app-shell.d.ts +14 -14
  9. package/dist/app-shell/app-shell.js +11 -11
  10. package/dist/app-shell/llms.txt +13 -13
  11. package/dist/auth/auth-types.d.ts +6 -6
  12. package/dist/auth/auth.d.ts +2 -2
  13. package/dist/auth/auth.js +7 -7
  14. package/dist/auth/llms.txt +9 -9
  15. package/dist/autocomplete/autocomplete.d.ts +19 -6
  16. package/dist/autocomplete/autocomplete.js +23 -10
  17. package/dist/autocomplete/llms.txt +16 -5
  18. package/dist/avatar/avatar.d.ts +6 -6
  19. package/dist/avatar/avatar.js +5 -5
  20. package/dist/avatar/llms.txt +10 -10
  21. package/dist/avatar-group/avatar-group.d.ts +4 -4
  22. package/dist/avatar-group/avatar-group.js +3 -3
  23. package/dist/avatar-group/llms.txt +8 -8
  24. package/dist/backdrop/backdrop.d.ts +7 -7
  25. package/dist/backdrop/backdrop.js +16 -16
  26. package/dist/backdrop/llms.txt +27 -27
  27. package/dist/badge/badge.d.ts +3 -3
  28. package/dist/badge/badge.js +1 -1
  29. package/dist/badge/llms.txt +11 -11
  30. package/dist/bottom-sheet/bottom-sheet.d.ts +4 -4
  31. package/dist/bottom-sheet/bottom-sheet.js +2 -2
  32. package/dist/bottom-sheet/llms.txt +9 -9
  33. package/dist/breadcrumb/breadcrumb.d.ts +2 -2
  34. package/dist/breadcrumb/breadcrumb.js +3 -3
  35. package/dist/breadcrumb/llms.txt +3 -3
  36. package/dist/button/button.d.ts +3 -3
  37. package/dist/button/button.js +8 -8
  38. package/dist/button/llms.txt +27 -19
  39. package/dist/button-group/button-group.d.ts +9 -9
  40. package/dist/button-group/button-group.js +30 -8
  41. package/dist/button-group/llms.txt +20 -14
  42. package/dist/card/card.d.ts +8 -8
  43. package/dist/card/card.js +6 -6
  44. package/dist/card/llms.txt +20 -20
  45. package/dist/carousel/carousel.d.ts +6 -6
  46. package/dist/carousel/carousel.js +4 -4
  47. package/dist/carousel/llms.txt +10 -10
  48. package/dist/charts/chart-legend.d.ts +3 -3
  49. package/dist/charts/chart-legend.js +1 -1
  50. package/dist/charts/chart-tooltip.d.ts +3 -3
  51. package/dist/charts/chart-tooltip.js +1 -1
  52. package/dist/charts/chart.d.ts +1 -1
  53. package/dist/charts/chart.js +8 -8
  54. package/dist/charts/llms.txt +6 -6
  55. package/dist/charts-entry/public-api.js +2 -2
  56. package/dist/chat/chat.d.ts +17 -10
  57. package/dist/chat/chat.js +42 -18
  58. package/dist/chat/llms.txt +32 -17
  59. package/dist/chat-composer/chat-composer.d.ts +17 -7
  60. package/dist/chat-composer/chat-composer.js +21 -8
  61. package/dist/chat-composer/llms.txt +20 -11
  62. package/dist/chat-dock/chat-dock.d.ts +11 -4
  63. package/dist/chat-dock/chat-dock.js +9 -6
  64. package/dist/chat-dock/llms.txt +15 -14
  65. package/dist/chat-entry/public-api.js +1 -1
  66. package/dist/chat-message/chat-message.d.ts +12 -5
  67. package/dist/chat-message/chat-message.js +17 -7
  68. package/dist/chat-message/llms.txt +16 -15
  69. package/dist/chat-typing/chat-typing.d.ts +2 -2
  70. package/dist/chat-typing/chat-typing.js +3 -3
  71. package/dist/chat-typing/llms.txt +6 -6
  72. package/dist/checkbox/checkbox.d.ts +13 -6
  73. package/dist/checkbox/checkbox.js +26 -7
  74. package/dist/checkbox/llms.txt +24 -12
  75. package/dist/chip/chip.d.ts +4 -4
  76. package/dist/chip/chip.js +2 -2
  77. package/dist/chip/llms.txt +11 -11
  78. package/dist/chips-input/chips-input.d.ts +4 -4
  79. package/dist/chips-input/chips-input.js +35 -9
  80. package/dist/chips-input/llms.txt +15 -8
  81. package/dist/clock/clock.d.ts +4 -4
  82. package/dist/clock/clock.js +7 -7
  83. package/dist/clock/llms.txt +8 -8
  84. package/dist/color-picker/color-picker.d.ts +6 -6
  85. package/dist/color-picker/color-picker.js +3 -3
  86. package/dist/color-picker/llms.txt +5 -5
  87. package/dist/confirm/confirm-container.d.ts +3 -3
  88. package/dist/confirm/confirm-container.js +5 -5
  89. package/dist/confirm/confirm-store.d.ts +4 -4
  90. package/dist/confirm/confirm-store.js +7 -7
  91. package/dist/confirm/llms.txt +6 -6
  92. package/dist/context-menu/context-menu.d.ts +1 -1
  93. package/dist/context-menu/context-menu.js +5 -5
  94. package/dist/context-menu/llms.txt +7 -7
  95. package/dist/data-table/data-table-types.d.ts +5 -5
  96. package/dist/data-table/data-table.d.ts +29 -8
  97. package/dist/data-table/data-table.js +340 -95
  98. package/dist/data-table/export-csv.d.ts +3 -3
  99. package/dist/data-table/export-csv.js +4 -4
  100. package/dist/data-table/llms.txt +127 -94
  101. package/dist/data-view/data-view.d.ts +13 -5
  102. package/dist/data-view/data-view.js +67 -6
  103. package/dist/data-view/llms.txt +29 -10
  104. package/dist/date-range/date-range.d.ts +9 -9
  105. package/dist/date-range/date-range.js +24 -24
  106. package/dist/date-range/llms.txt +20 -20
  107. package/dist/datepicker/datepicker.d.ts +10 -10
  108. package/dist/datepicker/datepicker.js +29 -29
  109. package/dist/datepicker/llms.txt +24 -24
  110. package/dist/dialog/dialog.d.ts +12 -7
  111. package/dist/dialog/dialog.js +4 -4
  112. package/dist/dialog/llms.txt +14 -11
  113. package/dist/divider/divider.d.ts +1 -1
  114. package/dist/divider/llms.txt +4 -4
  115. package/dist/drawer/drawer.d.ts +5 -5
  116. package/dist/drawer/drawer.js +2 -2
  117. package/dist/drawer/llms.txt +11 -11
  118. package/dist/empty/empty.d.ts +2 -2
  119. package/dist/empty/empty.js +1 -1
  120. package/dist/empty/llms.txt +9 -9
  121. package/dist/fab/fab.d.ts +1 -1
  122. package/dist/fab/fab.js +1 -1
  123. package/dist/fab/llms.txt +10 -6
  124. package/dist/fieldset/fieldset.d.ts +18 -4
  125. package/dist/fieldset/fieldset.js +9 -6
  126. package/dist/fieldset/llms.txt +26 -9
  127. package/dist/file-upload/file-upload.d.ts +3 -3
  128. package/dist/file-upload/file-upload.js +7 -7
  129. package/dist/file-upload/llms.txt +7 -7
  130. package/dist/form-field/form-field-context.d.ts +4 -4
  131. package/dist/form-field/form-field.d.ts +12 -4
  132. package/dist/form-field/form-field.js +26 -6
  133. package/dist/form-field/llms.txt +25 -11
  134. package/dist/galleria/galleria.d.ts +3 -3
  135. package/dist/galleria/galleria.js +5 -5
  136. package/dist/galleria/llms.txt +7 -7
  137. package/dist/grid/col.d.ts +4 -4
  138. package/dist/grid/col.js +2 -2
  139. package/dist/grid/flex.d.ts +3 -3
  140. package/dist/grid/flex.js +1 -1
  141. package/dist/grid/grid.d.ts +7 -7
  142. package/dist/grid/grid.js +3 -3
  143. package/dist/grid/layout.d.ts +2 -2
  144. package/dist/grid/layout.js +2 -2
  145. package/dist/grid/llms.txt +15 -15
  146. package/dist/grid-entry/public-api.js +1 -1
  147. package/dist/i18n/i18n-context.d.ts +3 -3
  148. package/dist/i18n/i18n-context.js +7 -7
  149. package/dist/icon/icon-registry.d.ts +3 -3
  150. package/dist/icon/icon-registry.js +3 -3
  151. package/dist/icon/icon.d.ts +4 -4
  152. package/dist/icon/icon.js +6 -6
  153. package/dist/icon/llms.txt +13 -13
  154. package/dist/icon-button/icon-button.d.ts +2 -2
  155. package/dist/icon-button/icon-button.js +1 -1
  156. package/dist/icon-button/llms.txt +9 -5
  157. package/dist/icons-entry/public-api.d.ts +2 -2
  158. package/dist/icons-entry/public-api.js +3 -3
  159. package/dist/image/image.js +1 -1
  160. package/dist/image/llms.txt +13 -13
  161. package/dist/input/input.d.ts +18 -5
  162. package/dist/input/input.js +21 -6
  163. package/dist/input/llms.txt +25 -11
  164. package/dist/input-mask/input-mask.d.ts +1 -1
  165. package/dist/input-mask/input-mask.js +2 -2
  166. package/dist/input-mask/llms.txt +5 -5
  167. package/dist/input-number/input-number.d.ts +9 -9
  168. package/dist/input-number/input-number.js +11 -11
  169. package/dist/input-number/llms.txt +14 -14
  170. package/dist/input-otp/input-otp.d.ts +6 -6
  171. package/dist/input-otp/input-otp.js +10 -10
  172. package/dist/input-otp/llms.txt +9 -9
  173. package/dist/internal/calendar-focus.d.ts +1 -1
  174. package/dist/internal/calendar-focus.js +3 -3
  175. package/dist/internal/cn.d.ts +1 -1
  176. package/dist/internal/mask.d.ts +2 -2
  177. package/dist/internal/mask.js +4 -4
  178. package/dist/internal/option-key.d.ts +2 -2
  179. package/dist/internal/option-key.js +2 -2
  180. package/dist/internal/option-nav.d.ts +4 -4
  181. package/dist/internal/option-nav.js +5 -5
  182. package/dist/internal/overlay-container.js +1 -1
  183. package/dist/internal/overlay.d.ts +3 -3
  184. package/dist/internal/overlay.js +8 -8
  185. package/dist/internal/password-strength.d.ts +2 -2
  186. package/dist/internal/password-strength.js +6 -6
  187. package/dist/internal/roving.d.ts +2 -2
  188. package/dist/internal/roving.js +3 -3
  189. package/dist/internal/scroll-lock.d.ts +1 -1
  190. package/dist/internal/scroll-lock.js +2 -2
  191. package/dist/internal/slot-children.d.ts +3 -3
  192. package/dist/internal/slot-children.js +4 -4
  193. package/dist/internal/slot.d.ts +3 -3
  194. package/dist/internal/slot.js +2 -2
  195. package/dist/internal/step.d.ts +3 -3
  196. package/dist/internal/step.js +4 -4
  197. package/dist/internal/tween.d.ts +5 -5
  198. package/dist/internal/tween.js +5 -5
  199. package/dist/internal/types.d.ts +2 -2
  200. package/dist/internal/use-breakpoint.d.ts +2 -2
  201. package/dist/internal/use-breakpoint.js +4 -4
  202. package/dist/internal/use-controllable-state.d.ts +1 -1
  203. package/dist/internal/use-controllable-state.js +3 -3
  204. package/dist/internal/use-id.d.ts +2 -2
  205. package/dist/internal/use-id.js +2 -2
  206. package/dist/internal/use-modal-focus.d.ts +1 -1
  207. package/dist/internal/use-modal-focus.js +3 -3
  208. package/dist/knob/knob.d.ts +4 -4
  209. package/dist/knob/knob.js +14 -10
  210. package/dist/knob/llms.txt +17 -12
  211. package/dist/listbox/listbox.d.ts +6 -6
  212. package/dist/listbox/listbox.js +9 -9
  213. package/dist/listbox/llms.txt +10 -10
  214. package/dist/loader/llms.txt +56 -0
  215. package/dist/loader/loader.d.ts +49 -0
  216. package/dist/loader/loader.js +68 -0
  217. package/dist/map/llms.txt +25 -22
  218. package/dist/map/map-create-dialog.d.ts +4 -4
  219. package/dist/map/map-create-dialog.js +10 -10
  220. package/dist/map/map-hours-field.d.ts +4 -4
  221. package/dist/map/map-hours-field.js +7 -7
  222. package/dist/map/map-image-field.d.ts +2 -2
  223. package/dist/map/map-image-field.js +4 -4
  224. package/dist/map/map-legend.d.ts +4 -4
  225. package/dist/map/map-legend.js +2 -2
  226. package/dist/map/map-poi-card.d.ts +3 -3
  227. package/dist/map/map-poi-card.js +9 -9
  228. package/dist/map/map-search.d.ts +17 -6
  229. package/dist/map/map-search.js +21 -18
  230. package/dist/map/map.d.ts +21 -14
  231. package/dist/map/map.js +30 -29
  232. package/dist/map/ports.d.ts +9 -9
  233. package/dist/map/ports.js +6 -6
  234. package/dist/map-entry/public-api.js +2 -2
  235. package/dist/megamenu/llms.txt +9 -9
  236. package/dist/megamenu/megamenu.d.ts +6 -6
  237. package/dist/megamenu/megamenu.js +10 -10
  238. package/dist/mention/llms.txt +15 -15
  239. package/dist/mention/mention.d.ts +5 -5
  240. package/dist/mention/mention.js +2 -2
  241. package/dist/mention/mentions.d.ts +1 -1
  242. package/dist/mention/mentions.js +1 -1
  243. package/dist/menu/llms.txt +12 -12
  244. package/dist/menu/menu-item.d.ts +4 -4
  245. package/dist/menu/menu-keys.d.ts +2 -2
  246. package/dist/menu/menu-keys.js +5 -5
  247. package/dist/menu/menu.d.ts +2 -2
  248. package/dist/menu/menu.js +6 -6
  249. package/dist/menubar/llms.txt +10 -10
  250. package/dist/menubar/menubar.d.ts +5 -5
  251. package/dist/menubar/menubar.js +10 -10
  252. package/dist/meter-group/llms.txt +12 -12
  253. package/dist/meter-group/meter-group.d.ts +2 -2
  254. package/dist/meter-group/meter-group.js +1 -1
  255. package/dist/motion/motion-context.d.ts +22 -0
  256. package/dist/motion/motion-context.js +28 -0
  257. package/dist/order-list/llms.txt +22 -10
  258. package/dist/order-list/order-list.d.ts +12 -4
  259. package/dist/order-list/order-list.js +104 -21
  260. package/dist/paginator/llms.txt +8 -8
  261. package/dist/paginator/paginator.js +1 -1
  262. package/dist/panel/llms.txt +25 -13
  263. package/dist/panel/panel.d.ts +11 -3
  264. package/dist/panel/panel.js +7 -4
  265. package/dist/password/llms.txt +16 -8
  266. package/dist/password/password.d.ts +2 -2
  267. package/dist/password/password.js +24 -3
  268. package/dist/peek/llms.txt +10 -10
  269. package/dist/peek/peek.d.ts +6 -6
  270. package/dist/peek/peek.js +7 -7
  271. package/dist/pick-list/llms.txt +33 -13
  272. package/dist/pick-list/pick-list.d.ts +12 -4
  273. package/dist/pick-list/pick-list.js +111 -23
  274. package/dist/popover/llms.txt +11 -11
  275. package/dist/popover/popover.d.ts +4 -4
  276. package/dist/popover/popover.js +5 -5
  277. package/dist/progress/llms.txt +17 -17
  278. package/dist/progress/progress.d.ts +7 -7
  279. package/dist/progress/progress.js +6 -6
  280. package/dist/public-api.d.ts +15 -3
  281. package/dist/public-api.js +13 -7
  282. package/dist/radio-group/llms.txt +13 -6
  283. package/dist/radio-group/radio-group.d.ts +11 -4
  284. package/dist/radio-group/radio-group.js +15 -7
  285. package/dist/rating/llms.txt +20 -13
  286. package/dist/rating/rating-pointer.d.ts +16 -0
  287. package/dist/rating/rating-pointer.js +26 -0
  288. package/dist/rating/rating.d.ts +6 -6
  289. package/dist/rating/rating.js +76 -12
  290. package/dist/rich-text/lists.d.ts +2 -2
  291. package/dist/rich-text/lists.js +7 -7
  292. package/dist/rich-text/llms.txt +26 -17
  293. package/dist/rich-text/rich-text.d.ts +12 -7
  294. package/dist/rich-text/rich-text.js +78 -54
  295. package/dist/rich-text/sanitize.d.ts +3 -3
  296. package/dist/rich-text/sanitize.js +12 -12
  297. package/dist/rich-text/tables.d.ts +3 -3
  298. package/dist/rich-text/tables.js +3 -3
  299. package/dist/roadmap/llms.txt +15 -15
  300. package/dist/roadmap/roadmap.d.ts +6 -6
  301. package/dist/roadmap/roadmap.js +19 -19
  302. package/dist/roadmap-entry/public-api.js +2 -2
  303. package/dist/scroll-top/llms.txt +6 -6
  304. package/dist/scroll-top/scroll-top.d.ts +1 -1
  305. package/dist/scroll-top/scroll-top.js +1 -1
  306. package/dist/select/llms.txt +19 -12
  307. package/dist/select/select.d.ts +8 -8
  308. package/dist/select/select.js +47 -21
  309. package/dist/shared/types.d.ts +5 -5
  310. package/dist/shared/types.js +1 -1
  311. package/dist/sidenav/llms.txt +9 -9
  312. package/dist/sidenav/sidenav.d.ts +1 -1
  313. package/dist/sidenav/sidenav.js +1 -1
  314. package/dist/skeleton/llms.txt +3 -3
  315. package/dist/skeleton/skeleton.d.ts +1 -1
  316. package/dist/skeleton/skeleton.js +1 -1
  317. package/dist/slider/llms.txt +32 -13
  318. package/dist/slider/slider-drag.d.ts +26 -0
  319. package/dist/slider/slider-drag.js +79 -0
  320. package/dist/slider/slider.d.ts +6 -5
  321. package/dist/slider/slider.js +27 -8
  322. package/dist/speech/llms.txt +97 -0
  323. package/dist/speech/speech-button.d.ts +44 -0
  324. package/dist/speech/speech-button.js +86 -0
  325. package/dist/speech/speech-wave.d.ts +19 -0
  326. package/dist/speech/speech-wave.js +16 -0
  327. package/dist/speech/use-speech-recognition.d.ts +81 -0
  328. package/dist/speech/use-speech-recognition.js +179 -0
  329. package/dist/speed-dial/llms.txt +14 -8
  330. package/dist/speed-dial/speed-dial.d.ts +1 -1
  331. package/dist/speed-dial/speed-dial.js +1 -1
  332. package/dist/spinner/llms.txt +7 -7
  333. package/dist/spinner/spinner.d.ts +1 -1
  334. package/dist/spinner/spinner.js +1 -1
  335. package/dist/split-button/llms.txt +21 -15
  336. package/dist/split-button/split-button.d.ts +2 -2
  337. package/dist/split-button/split-button.js +4 -4
  338. package/dist/splitter/llms.txt +11 -11
  339. package/dist/splitter/splitter.d.ts +3 -3
  340. package/dist/splitter/splitter.js +5 -5
  341. package/dist/stepper/llms.txt +33 -14
  342. package/dist/stepper/stepper.d.ts +6 -6
  343. package/dist/stepper/stepper.js +53 -10
  344. package/dist/switch/llms.txt +12 -5
  345. package/dist/switch/switch.d.ts +10 -3
  346. package/dist/switch/switch.js +12 -5
  347. package/dist/switch-group/llms.txt +9 -9
  348. package/dist/switch-group/switch-group.d.ts +4 -4
  349. package/dist/switch-group/switch-group.js +4 -4
  350. package/dist/tabs/llms.txt +10 -10
  351. package/dist/tabs/tabs.d.ts +5 -5
  352. package/dist/tabs/tabs.js +8 -8
  353. package/dist/textarea/llms.txt +23 -12
  354. package/dist/textarea/textarea.d.ts +19 -6
  355. package/dist/textarea/textarea.js +21 -7
  356. package/dist/timeline/llms.txt +4 -4
  357. package/dist/timeline/timeline.d.ts +1 -1
  358. package/dist/timeline/timeline.js +1 -1
  359. package/dist/toast/llms.txt +47 -17
  360. package/dist/toast/toast-container.d.ts +9 -3
  361. package/dist/toast/toast-container.js +17 -9
  362. package/dist/toast/toast-store.d.ts +40 -4
  363. package/dist/toast/toast-store.js +36 -1
  364. package/dist/toolbar/llms.txt +7 -7
  365. package/dist/toolbar/toolbar.d.ts +3 -3
  366. package/dist/toolbar/toolbar.js +2 -2
  367. package/dist/tooltip/llms.txt +10 -10
  368. package/dist/tooltip/tooltip.d.ts +3 -3
  369. package/dist/tooltip/tooltip.js +18 -18
  370. package/dist/tree/llms.txt +25 -12
  371. package/dist/tree/tree-keys.d.ts +5 -5
  372. package/dist/tree/tree-keys.js +7 -7
  373. package/dist/tree/tree.d.ts +14 -7
  374. package/dist/tree/tree.js +53 -18
  375. package/dist/update/llms.txt +54 -0
  376. package/dist/update/update.d.ts +49 -0
  377. package/dist/update/update.js +82 -0
  378. package/package.json +15 -13
@@ -4,27 +4,31 @@ A group of fields with a legend, optionally collapsible.
4
4
  Import: `import { KptFieldset } from '@konce-pt/react';`
5
5
 
6
6
  ## DOM
7
- <div class="kpt-fieldset-host" style="--kpt-anim-duration:500ms">
7
+ <div class="kpt-fieldset-host" data-variant="outlined" style="--kpt-anim-duration:500ms">
8
8
  <fieldset class="kpt-fieldset">
9
9
  <legend class="kpt-fieldset__legend">
10
- <button class="kpt-fieldset__toggle" aria-expanded="true">…<span>Personal data</span></button>
10
+ <button class="kpt-fieldset__toggle" aria-expanded="true">...<span>Personal data</span></button>
11
11
  </legend>
12
12
  <div class="kpt-fieldset__collapse is-open">
13
- <div class="kpt-fieldset__collapse-inner"><div class="kpt-fieldset__body">…</div></div>
13
+ <div class="kpt-fieldset__collapse-inner"><div class="kpt-fieldset__body">...</div></div>
14
14
  </div>
15
15
  </fieldset>
16
16
  </div>
17
17
 
18
18
  ## Props
19
19
  - `legend`: string
20
- - `toggleable`: boolean — turns the legend into a collapse button
20
+ - `variant`: `'outlined'` (default, a frame on the parent's background) | `'filled'` (the group on
21
+ `--kpt-color-surface`, e.g. sections inside a grey panel); the legend takes the group's background
22
+ with rounded ends in both, so it never splits into two colours
23
+ - `toggleable`: boolean - turns the legend into a collapse button
21
24
  - `collapsed` / `defaultCollapsed` / `onCollapsedChange`
22
25
  - `animated`: boolean (default true), `animationDuration`: ms (default 500)
26
+ - `collapseMotion`: `'spring' | 'fade' | 'none'` (default from `KptMotionProvider`, else `spring`) - see "Collapse motion"
23
27
  - `className`, `ref` and every other `<div>` prop go to the host
24
28
 
25
29
  ## Collapsing without measuring
26
- The transition runs on `grid-template-rows: 0fr → 1fr`, so it animates to the content's natural
27
- height with no JS measurement and no height cached at mount — content that grows later still
30
+ The transition runs on `grid-template-rows: 0fr -> 1fr`, so it animates to the content's natural
31
+ height with no JS measurement and no height cached at mount - content that grows later still
28
32
  collapses correctly.
29
33
 
30
34
  ## The real fieldset stays
@@ -32,11 +36,24 @@ The markup is a native `<fieldset>` + `<legend>`, so the grouping is real for as
32
36
  the collapse only wraps the body, never the legend.
33
37
 
34
38
  ## Examples
35
- <KptFieldset legend="Personal data" toggleable>…</KptFieldset>
36
- <KptFieldset legend="Advanced" toggleable collapsed={closed} onCollapsedChange={setClosed}>…</KptFieldset>
39
+ <KptFieldset legend="Personal data" toggleable>...</KptFieldset>
40
+ <KptFieldset legend="Scrolling" variant="filled">...</KptFieldset>
41
+ <KptFieldset legend="Advanced" toggleable collapsed={closed} onCollapsedChange={setClosed}>...</KptFieldset>
42
+
43
+ ## Collapse motion
44
+ - `spring` - the height opens on a soft spring, the content slides in from above and sharpens out
45
+ of a blur; when collapsing, the content fades first and only then the section closes. The chevron
46
+ turns on a spring.
47
+ - `fade` - the height on the standard curve, the content cross-fades.
48
+ - `none` - the state changes without motion.
49
+
50
+ With no value it takes `collapse` from `KptMotionProvider` (default `spring`). `animated={false}`, `enabled: false`
51
+ in the config and the system "reduce motion" setting always turn it off. `animationDuration` sets
52
+ the time of every kind. Pure CSS: the kind sits in `data-motion` on the component root.
37
53
 
38
54
  ## Tokens
39
- Border `--kpt-color-border`, radius `--kpt-radius-md`, padding `--kpt-space-4`.
55
+ Border `--kpt-color-border`, radius `--kpt-radius-md`, padding `--kpt-space-4`; `filled` background
56
+ `--kpt-color-surface`, legend corners `--kpt-radius-full`.
40
57
 
41
58
  ## Accessibility
42
59
  The toggle carries `aria-expanded`; the collapsed body gets `inert` and `aria-hidden`, so it is
@@ -8,9 +8,9 @@ export interface KptFileUploadProps extends Omit<ComponentPropsWithRef<'div'>, '
8
8
  accept?: string;
9
9
  multiple?: boolean;
10
10
  disabled?: boolean;
11
- /** Tylko do odczytu — listę plików widać, nie da się jej zmienić. */
11
+ /** Tylko do odczytu - listę plików widać, nie da się jej zmienić. */
12
12
  readOnly?: boolean;
13
- /** Id strefy; bez niego generowane, w `KptFormField` — z wrappera. */
13
+ /** Id strefy; bez niego generowane, w `KptFormField` - z wrappera. */
14
14
  id?: string;
15
15
  /** Nazwa dostępna, gdy strefy nie opisuje etykieta (`KptFormField`). */
16
16
  ariaLabel?: string | null;
@@ -23,7 +23,7 @@ export interface KptFileUploadProps extends Omit<ComponentPropsWithRef<'div'>, '
23
23
  * Wartością jest tablica `File`.
24
24
  *
25
25
  * Strefa to `role="button"` z jednym przystankiem Tab: `Enter` i spacja otwierają okno wyboru,
26
- * tak jak kliknięcie — natywne pole pliku jest ukryte, więc bez tego klawiatura nie miałaby
26
+ * tak jak kliknięcie - natywne pole pliku jest ukryte, więc bez tego klawiatura nie miałaby
27
27
  * jak wybrać pliku. `disabled` wyjmuje strefę z kolejności Tab. Stan błędu: `invalid`
28
28
  * i `touched` (pominięty `touched` = błąd widać od razu, jak w `KptInput`).
29
29
  *
@@ -7,7 +7,7 @@ import { useKptMessages } from "../i18n/i18n-context.js";
7
7
  import { KptIcon } from "../icon/icon.js";
8
8
  import { useKptFieldA11y } from "../form-field/form-field-context.js";
9
9
  const EMPTY = [];
10
- /** Rozmiar pliku w KB albo MB — bez bibliotek, bo to jedna reguła. */
10
+ /** Rozmiar pliku w KB albo MB - bez bibliotek, bo to jedna reguła. */
11
11
  function formatSize(file) {
12
12
  const kb = file.size / 1024;
13
13
  return kb < 1024 ? `${kb.toFixed(0)} KB` : `${(kb / 1024).toFixed(1)} MB`;
@@ -21,7 +21,7 @@ function fileIcon(file) {
21
21
  * Wartością jest tablica `File`.
22
22
  *
23
23
  * Strefa to `role="button"` z jednym przystankiem Tab: `Enter` i spacja otwierają okno wyboru,
24
- * tak jak kliknięcie — natywne pole pliku jest ukryte, więc bez tego klawiatura nie miałaby
24
+ * tak jak kliknięcie - natywne pole pliku jest ukryte, więc bez tego klawiatura nie miałaby
25
25
  * jak wybrać pliku. `disabled` wyjmuje strefę z kolejności Tab. Stan błędu: `invalid`
26
26
  * i `touched` (pominięty `touched` = błąd widać od razu, jak w `KptInput`).
27
27
  *
@@ -32,9 +32,9 @@ export function KptFileUpload({ value, defaultValue = EMPTY, onValueChange, acce
32
32
  const { t } = useKptMessages({ locale, dictionary });
33
33
  const inputRef = useRef(null);
34
34
  const zoneRef = useRef(null);
35
- /** `div` z rolą nie dostaje nazwy z `label[for]` — stąd `aria-labelledby` na etykietę wrappera. */
35
+ /** `div` z rolą nie dostaje nazwy z `label[for]` - stąd `aria-labelledby` na etykietę wrappera. */
36
36
  const field = useKptFieldA11y(id, 'kpt-file-upload');
37
- // Podpowiedź rozcięta w miejscu `{action}` — pogrubienie robi JSX, nie HTML ze słownika.
37
+ // Podpowiedź rozcięta w miejscu `{action}` - pogrubienie robi JSX, nie HTML ze słownika.
38
38
  const [hintBefore = '', hintAfter = ''] = t('fileUpload.hint').split('{action}');
39
39
  const locked = disabled || readOnly;
40
40
  const [current, setCurrent] = useControllableState({ value, defaultValue, onChange: onValueChange });
@@ -44,7 +44,7 @@ export function KptFileUpload({ value, defaultValue = EMPTY, onValueChange, acce
44
44
  if (!locked)
45
45
  inputRef.current?.click();
46
46
  };
47
- /** `Enter` / spacja na strefie — spacja bez `preventDefault` przewinęłaby stronę. */
47
+ /** `Enter` / spacja na strefie - spacja bez `preventDefault` przewinęłaby stronę. */
48
48
  const onZoneKeyDown = (event) => {
49
49
  if (event.key !== 'Enter' && event.key !== ' ')
50
50
  return;
@@ -60,7 +60,7 @@ export function KptFileUpload({ value, defaultValue = EMPTY, onValueChange, acce
60
60
  };
61
61
  const onSelect = (event) => {
62
62
  addFiles(event.target.files);
63
- // Czyszczenie pola pozwala wybrać ten sam plik drugi raz — inaczej `change` by nie poleciał.
63
+ // Czyszczenie pola pozwala wybrać ten sam plik drugi raz - inaczej `change` by nie poleciał.
64
64
  event.target.value = '';
65
65
  };
66
66
  return (_jsxs("div", { className: cn('kpt-file-upload-host', className), ...rest, children: [_jsxs("div", { className: cn('kpt-file-upload__zone', dragover && 'is-dragover', disabled && 'is-disabled'), ref: zoneRef, role: "button", id: field.id, tabIndex: disabled ? -1 : 0, "aria-disabled": locked || undefined, "aria-label": ariaLabel ?? undefined, "aria-labelledby": ariaLabel ? undefined : field.labelledBy, "aria-describedby": field.describedBy, "data-invalid": showError ? '' : undefined, onClick: openPicker, onKeyDown: onZoneKeyDown, onDragOver: (event) => {
@@ -76,7 +76,7 @@ export function KptFileUpload({ value, defaultValue = EMPTY, onValueChange, acce
76
76
  event.stopPropagation();
77
77
  setCurrent(current.filter((item) => item !== file));
78
78
  onTouch?.();
79
- // Przycisk znika razem z pozycją — fokus wraca na strefę, a nie spada na <body>.
79
+ // Przycisk znika razem z pozycją - fokus wraca na strefę, a nie spada na <body>.
80
80
  zoneRef.current?.focus();
81
81
  }, children: _jsx(KptIcon, { name: "trash" }) }))] }, `${index}-${file.name}`))) })) : null] }));
82
82
  }
@@ -8,19 +8,19 @@ Import: `import { KptFileUpload } from '@konce-pt/react';`
8
8
  <div class="kpt-file-upload-host">
9
9
  <div class="kpt-file-upload__zone is-dragover" role="button" tabindex="0">
10
10
  <input type="file" hidden>
11
- <span class="kpt-icon-host kpt-file-upload__icon">…</span>
11
+ <span class="kpt-icon-host kpt-file-upload__icon">...</span>
12
12
  <div class="kpt-file-upload__text"><strong>Click</strong> or drag files here</div>
13
13
  <div class="kpt-file-upload__hint">image/*</div>
14
14
  </div>
15
15
  <ul class="kpt-file-upload__list">
16
- <li class="kpt-file-upload__file">…name, size, remove…</li>
16
+ <li class="kpt-file-upload__file">...name, size, remove...</li>
17
17
  </ul>
18
18
  </div>
19
19
 
20
20
  ## Props
21
- - `value` / `defaultValue` / `onValueChange` — the `File[]`
22
- - `accept`: string (e.g. `'image/*'`) — the native picker filter, also shown under the zone
23
- - `multiple`: boolean — off, only the first file is kept
21
+ - `value` / `defaultValue` / `onValueChange` - the `File[]`
22
+ - `accept`: string (e.g. `'image/*'`) - the native picker filter, also shown under the zone
23
+ - `multiple`: boolean - off, only the first file is kept
24
24
  - `disabled`, `invalid`, `touched`, `onTouch()`
25
25
  - `className`, `ref` and every other `<div>` prop go to the host
26
26
 
@@ -56,7 +56,7 @@ focus ring `--kpt-color-focus-ring`.
56
56
 
57
57
  ## Accessibility
58
58
  The remove button is labelled from the dictionary. The zone itself is the keyboard path to the
59
- system picker — see "Keyboard and states" above.
59
+ system picker - see "Keyboard and states" above.
60
60
 
61
61
  ## Read-only and required
62
- `readOnly` shows the list without the remove buttons and does not open the picker nor accept a drop. The zone takes `id` and `ariaLabel` and is linked to `kpt-form-field` (label and description); `button` accepts neither `aria-invalid` nor `aria-required`, so the error is the linked message. The hint is plain text: `fileUpload.hint` with `{action}` and `fileUpload.hintAction` (bold) — dictionaries no longer carry HTML. The remove button names the file.
62
+ `readOnly` shows the list without the remove buttons and does not open the picker nor accept a drop. The zone takes `id` and `ariaLabel` and is linked to `kpt-form-field` (label and description); `button` accepts neither `aria-invalid` nor `aria-required`, so the error is the linked message. The hint is plain text: `fileUpload.hint` with `{action}` and `fileUpload.hintAction` (bold) - dictionaries no longer carry HTML. The remove button names the file.
@@ -6,13 +6,13 @@
6
6
  * zbudowany na liście) zgłaszają je przez `useKptFormFieldFilled`.
7
7
  */
8
8
  export interface KptFormFieldContextValue {
9
- /** Id, którym wrapper wiąże `label[for]` — kontrolka bez własnego `id` nadaje je swojemu elementowi. */
9
+ /** Id, którym wrapper wiąże `label[for]` - kontrolka bez własnego `id` nadaje je swojemu elementowi. */
10
10
  controlId: string;
11
11
  /** Id elementu etykiety albo `undefined`, gdy wrapper jej nie pokazuje. */
12
12
  labelId: string | undefined;
13
13
  /** Id widocznego komunikatu (błąd albo podpowiedź) albo `undefined`. */
14
14
  describedBy: string | undefined;
15
- /** Kontrolka z własnym `id` zgłasza je wrapperowi — na nie wskaże `label[for]`. */
15
+ /** Kontrolka z własnym `id` zgłasza je wrapperowi - na nie wskaże `label[for]`. */
16
16
  reportControlId: (id: string | null) => void;
17
17
  /** Czy pole jest oznaczone jako nieprawidłowe (niepusty `error` na wrapperze). */
18
18
  invalid: boolean;
@@ -32,11 +32,11 @@ export interface KptFieldA11y {
32
32
  /** Id elementu fokusowalnego: własne `id`, potem `controlId` wrappera, potem wygenerowane. */
33
33
  id: string;
34
34
  /**
35
- * Id etykiety wrappera — dla kontrolek na elemencie, którego `label[for]` nie nazywa
35
+ * Id etykiety wrappera - dla kontrolek na elemencie, którego `label[for]` nie nazywa
36
36
  * (`div` z rolą, `contenteditable`). Natywne `input`/`textarea` nazywa już samo `htmlFor`.
37
37
  */
38
38
  labelledBy: string | undefined;
39
- /** Id podpowiedzi albo błędu wrappera — do `aria-describedby`. */
39
+ /** Id podpowiedzi albo błędu wrappera - do `aria-describedby`. */
40
40
  describedBy: string | undefined;
41
41
  }
42
42
  /**
@@ -1,6 +1,7 @@
1
1
  import { type ComponentPropsWithRef, type ReactNode } from 'react';
2
+ import { type KptEnterMotion } from '@konce-pt/motion';
2
3
  /**
3
- * Wariant etykiety: `fixed` (statyczna nad kontrolką) albo Float Label — `over`
4
+ * Wariant etykiety: `fixed` (statyczna nad kontrolką) albo Float Label - `over`
4
5
  * (nad obramowaniem), `in` (u góry wewnątrz pola), `on` (na obramowaniu, notch).
5
6
  */
6
7
  export type KptFormFieldLabelType = 'fixed' | 'over' | 'in' | 'on';
@@ -9,7 +10,7 @@ export interface KptFormFieldProps extends Omit<ComponentPropsWithRef<'div'>, 'c
9
10
  label?: string;
10
11
  /** Podpowiedź pod kontrolką (ukrywana, gdy jest błąd). */
11
12
  hint?: string;
12
- /** Komunikat błędu — gdy niepusty, pole jest oznaczone jako nieprawidłowe. */
13
+ /** Komunikat błędu - gdy niepusty, pole jest oznaczone jako nieprawidłowe. */
13
14
  error?: string | null;
14
15
  /** Oznacz pole jako wymagane (gwiazdka przy etykiecie). */
15
16
  required?: boolean;
@@ -20,11 +21,18 @@ export interface KptFormFieldProps extends Omit<ComponentPropsWithRef<'div'>, 'c
20
21
  controlId?: string;
21
22
  /** Wariant etykiety; uniesienie następuje przy focusie lub wypełnieniu pola. */
22
23
  labelType?: KptFormFieldLabelType;
24
+ /**
25
+ * Ruch: `spring` - komunikat wjeżdża z rozmycia, pole potrząsa się, gdy staje się błędne, etykieta
26
+ * float unosi się na sprężynie; `fade` - komunikat się przenika; `none` - bez ruchu. Bez wartości
27
+ * bierze `enter` z `KptMotionProvider` (domyślnie `spring`); `enabled={false}` i systemowe
28
+ * "ogranicz ruch" wyłączają go zawsze.
29
+ */
30
+ enterMotion?: KptEnterMotion;
23
31
  children?: ReactNode;
24
32
  }
25
33
  /**
26
34
  * Wrapper pola formularza: etykieta, podpowiedź i komunikat błędu wokół dowolnej kontrolki.
27
- * Prezentacyjny — stan błędu przekazuje się przez `error`.
35
+ * Prezentacyjny - stan błędu przekazuje się przez `error`.
28
36
  *
29
37
  * Wypełnienie (sterujące uniesieniem etykiety) wrapper odczytuje z natywnego `input`/`textarea`
30
38
  * w środku, po zdarzeniach `input`/`change` oraz z wartości początkowej. Działa więc tak samo
@@ -36,4 +44,4 @@ export interface KptFormFieldProps extends Omit<ComponentPropsWithRef<'div'>, 'c
36
44
  * <KptInput type="email" name="email" />
37
45
  * </KptFormField>
38
46
  */
39
- export declare function KptFormField({ label, hint, error, required, controlId, labelType, className, children, ref, ...rest }: Readonly<KptFormFieldProps>): import("react").JSX.Element;
47
+ export declare function KptFormField({ label, hint, error, required, controlId, labelType, enterMotion, className, children, ref, ...rest }: Readonly<KptFormFieldProps>): import("react").JSX.Element;
@@ -5,9 +5,11 @@ import { cn } from "../internal/cn.js";
5
5
  import { composeRefs } from "../internal/compose-refs.js";
6
6
  import { useKptId } from "../internal/use-id.js";
7
7
  import { KptFormFieldContext } from "./form-field-context.js";
8
+ import { playShakeMotion, resolveEnterMotion } from '@konce-pt/motion';
9
+ import { useKptMotion } from "../motion/motion-context.js";
8
10
  /**
9
11
  * Wrapper pola formularza: etykieta, podpowiedź i komunikat błędu wokół dowolnej kontrolki.
10
- * Prezentacyjny — stan błędu przekazuje się przez `error`.
12
+ * Prezentacyjny - stan błędu przekazuje się przez `error`.
11
13
  *
12
14
  * Wypełnienie (sterujące uniesieniem etykiety) wrapper odczytuje z natywnego `input`/`textarea`
13
15
  * w środku, po zdarzeniach `input`/`change` oraz z wartości początkowej. Działa więc tak samo
@@ -19,14 +21,32 @@ import { KptFormFieldContext } from "./form-field-context.js";
19
21
  * <KptInput type="email" name="email" />
20
22
  * </KptFormField>
21
23
  */
22
- export function KptFormField({ label = '', hint = '', error = null, required = false, controlId = '', labelType = 'fixed', className, children, ref, ...rest }) {
24
+ export function KptFormField({ label = '', hint = '', error = null, required = false, controlId = '', labelType = 'fixed', enterMotion, className, children, ref, ...rest }) {
23
25
  const hostRef = useRef(null);
26
+ const motion = resolveEnterMotion(enterMotion, useKptMotion());
27
+ const rootRef = useRef(null);
28
+ const controlRef = useRef(null);
29
+ const wasInvalid = useRef(null);
30
+ // Wejścia komunikatów dopiero po pierwszym renderze - błędy obecne od startu stoją. Atrybut idzie
31
+ // wprost na element: React nim nie zarządza, więc go nie nadpisze (klasę nadpisałby przy zmianie `error`).
32
+ useEffect(() => {
33
+ if (rootRef.current)
34
+ rootRef.current.dataset['live'] = '';
35
+ }, []);
36
+ // Potrząśnięcie tylko przy przejściu "poprawne -> błędne", nie przy każdej zmianie treści błędu.
37
+ const invalid = !!error;
38
+ useEffect(() => {
39
+ const before = wasInvalid.current;
40
+ wasInvalid.current = invalid;
41
+ if (before === false && invalid && motion === 'spring' && controlRef.current)
42
+ playShakeMotion(controlRef.current);
43
+ }, [invalid, motion]);
24
44
  const [nativeFilled, setNativeFilled] = useState(false);
25
45
  const [reportedFilled, setReportedFilled] = useState(null);
26
46
  const generatedId = useKptId(undefined, 'kpt-form-field-control');
27
47
  const baseId = useKptId(undefined, 'kpt-form-field');
28
48
  const id = controlId || generatedId;
29
- // Kontrolka z własnym `id` zgłasza je przez kontekst — wtedy `label[for]` wskazuje właśnie je.
49
+ // Kontrolka z własnym `id` zgłasza je przez kontekst - wtedy `label[for]` wskazuje właśnie je.
30
50
  const [reportedId, setReportedId] = useState(null);
31
51
  const labelFor = controlId || reportedId || generatedId;
32
52
  const labelId = label ? `${baseId}-label` : undefined;
@@ -37,11 +57,11 @@ export function KptFormField({ label = '', hint = '', error = null, required = f
37
57
  const el = hostRef.current?.querySelector('.kpt-form-field__control input, .kpt-form-field__control textarea');
38
58
  setNativeFilled(!!el && el.value !== '');
39
59
  }, []);
40
- // Wartość początkowa (np. pole prefill) — po pierwszym renderze projekcji, przed malowaniem,
60
+ // Wartość początkowa (np. pole prefill) - po pierwszym renderze projekcji, przed malowaniem,
41
61
  // żeby uniesiona etykieta nie przeskoczyła na oczach użytkownika.
42
62
  useLayoutEffect(updateFilled, [updateFilled]);
43
63
  // Kontrolowana wartość zmieniana z zewnątrz nie emituje zdarzenia `input`, więc odczyt
44
- // powtarzamy po każdym renderze — to jeden `querySelector`, nie warto tu optymalizować.
64
+ // powtarzamy po każdym renderze - to jeden `querySelector`, nie warto tu optymalizować.
45
65
  useEffect(updateFilled);
46
66
  const filled = reportedFilled ?? nativeFilled;
47
67
  const context = useMemo(() => ({
@@ -52,5 +72,5 @@ export function KptFormField({ label = '', hint = '', error = null, required = f
52
72
  reportFilled: setReportedFilled,
53
73
  reportControlId: setReportedId,
54
74
  }), [id, labelId, describedBy, error]);
55
- return (_jsx(KptFormFieldContext.Provider, { value: context, children: _jsx("div", { className: cn('kpt-form-field-host', className), ref: composeRefs(hostRef, ref), onInput: updateFilled, onChange: updateFilled, ...rest, children: _jsxs("div", { className: cn('kpt-form-field', `kpt-form-field--${labelType}`, labelType !== 'fixed' && 'kpt-form-field--float', error && 'kpt-form-field--invalid'), children: [_jsxs("div", { className: cn('kpt-form-field__box', filled && 'is-filled'), children: [label ? (_jsxs("label", { className: "kpt-form-field__label", id: labelId, htmlFor: labelFor, children: [label, required ? (_jsx("span", { className: "kpt-form-field__required", "aria-hidden": "true", children: "*" })) : null] })) : null, _jsx("div", { className: "kpt-form-field__control", children: children })] }), error ? (_jsx("p", { className: "kpt-form-field__message kpt-form-field__message--error", role: "alert", id: messageId, children: error })) : hint ? (_jsx("p", { className: "kpt-form-field__message kpt-form-field__message--hint", id: messageId, children: hint })) : null] }) }) }));
75
+ return (_jsx(KptFormFieldContext.Provider, { value: context, children: _jsx("div", { className: cn('kpt-form-field-host', className), ref: composeRefs(hostRef, ref), onInput: updateFilled, onChange: updateFilled, ...rest, children: _jsxs("div", { ref: rootRef, "data-motion": motion, className: cn('kpt-form-field', `kpt-form-field--${labelType}`, labelType !== 'fixed' && 'kpt-form-field--float', error && 'kpt-form-field--invalid'), children: [_jsxs("div", { className: cn('kpt-form-field__box', filled && 'is-filled'), children: [label ? (_jsxs("label", { className: "kpt-form-field__label", id: labelId, htmlFor: labelFor, children: [label, required ? (_jsx("span", { className: "kpt-form-field__required", "aria-hidden": "true", children: "*" })) : null] })) : null, _jsx("div", { ref: controlRef, className: "kpt-form-field__control", children: children })] }), error ? (_jsx("p", { className: "kpt-form-field__message kpt-form-field__message--error", role: "alert", id: messageId, children: error }, error)) : hint ? (_jsx("p", { className: "kpt-form-field__message kpt-form-field__message--hint", id: messageId, children: hint })) : null] }) }) }));
56
76
  }
@@ -7,30 +7,31 @@ Import: `import { KptFormField } from '@konce-pt/react';`
7
7
  <div class="kpt-form-field-host">
8
8
  <div class="kpt-form-field kpt-form-field--fixed">
9
9
  <div class="kpt-form-field__box is-filled">
10
- <label class="kpt-form-field__label" for="…">E-mail<span class="kpt-form-field__required">*</span></label>
11
- <div class="kpt-form-field__control">…control…</div>
10
+ <label class="kpt-form-field__label" for="...">E-mail<span class="kpt-form-field__required">*</span></label>
11
+ <div class="kpt-form-field__control">...control...</div>
12
12
  </div>
13
13
  <p class="kpt-form-field__message kpt-form-field__message--hint">Company e-mail</p>
14
14
  </div>
15
15
  </div>
16
16
 
17
17
  ## Props
18
- - `label`: string — the label text
19
- - `hint`: string — a hint under the control, hidden while there is an error
20
- - `error`: string | null — when non-empty the field is marked invalid
21
- - `required`: boolean — an asterisk next to the label
22
- - `controlId`: string — empty means the wrapper generates one and hands it to the control
18
+ - `label`: string - the label text
19
+ - `hint`: string - a hint under the control, hidden while there is an error
20
+ - `error`: string | null - when non-empty the field is marked invalid
21
+ - `required`: boolean - an asterisk next to the label
22
+ - `controlId`: string - empty means the wrapper generates one and hands it to the control
23
23
  - `labelType`: 'fixed' | 'over' | 'in' | 'on' (default 'fixed')
24
+ - `enterMotion`: 'spring' | 'fade' | 'none' - how the message and the error appear (default from `KptMotionProvider`, else `spring`)
24
25
  - `className`, `ref` and every other `<div>` prop go to the host
25
26
 
26
27
  ## Label wiring
27
28
  The wrapper generates a control id and publishes it through context, so `<KptInput>` inside needs
28
- no configuration — `label[for]` and `input[id]` always match. Pass `controlId` to take over; a control
29
+ no configuration - `label[for]` and `input[id]` always match. Pass `controlId` to take over; a control
29
30
  with its own `id` reports it, and the label follows.
30
31
 
31
32
  The context also carries the label's id and the id of the visible hint or error. Every library
32
33
  control uses them through `useKptFieldA11y`: the hint or error lands in `aria-describedby`, and a
33
- control on a `div` with a role (`KptSelect`, `KptDatepicker`, `KptRadioGroup`, `KptRichText`…) gets
34
+ control on a `div` with a role (`KptSelect`, `KptDatepicker`, `KptRadioGroup`, `KptRichText`...) gets
34
35
  `aria-labelledby` pointing at the label, because `label[for]` does not name it. A custom control:
35
36
 
36
37
  const field = useKptFieldA11y(id, 'my-control');
@@ -39,7 +40,7 @@ control on a `div` with a role (`KptSelect`, `KptDatepicker`, `KptRadioGroup`, `
39
40
  ## Float labels
40
41
  `labelType` other than `fixed` turns on the floating label with an animated transition: `over`
41
42
  (above the border), `in` (top inside the field), `on` (on the border, notch). The label floats on
42
- focus (CSS `:focus-within`) or when the field is filled — no placeholder required.
43
+ focus (CSS `:focus-within`) or when the field is filled - no placeholder required.
43
44
 
44
45
  Filled state is read from the projected `input`/`textarea` on `input`/`change` and from the initial
45
46
  value, so it works for controlled and uncontrolled fields alike. A control with no native field
@@ -54,11 +55,24 @@ reports it with `useKptFormFieldFilled(filled)`.
54
55
  <KptInput value={over} onValueChange={setOver} />
55
56
  </KptFormField>
56
57
 
58
+ ## Motion
59
+ `enterMotion` (`spring | fade | none`):
60
+ - the message under the field enters on every change - hint -> error, error A -> error B - sliding in
61
+ from above and sharpening out of a blur (`fade`: only fades); each new error is a new element, so it
62
+ is also announced again;
63
+ - `spring` only: the control shakes briefly when the field turns invalid - not when the error text
64
+ changes and not for an error present on load; the floating label rises on a spring.
65
+
66
+ Messages present on the first render do not animate. With no value it takes `enter` from `KptMotionProvider`
67
+ (default `spring`); `enabled: false` and the system "reduce motion" setting always win. Every form
68
+ control's surface (border, focus ring, background) changes smoothly on hover, focus and error - a shared
69
+ rule, independent of this input.
70
+
57
71
  ## Tokens
58
72
  `--kpt-form-field-{label,hint,error,border,border-focus,border-error,radius}` and
59
73
  `--kpt-color-danger` for the required asterisk.
60
74
 
61
75
  ## Accessibility
62
76
  The error message carries `role="alert"`, so a screen reader announces it as it appears. The
63
- asterisk is `aria-hidden` — the required state belongs on the control (`aria-required`), not on
77
+ asterisk is `aria-hidden` - the required state belongs on the control (`aria-required`), not on
64
78
  decoration.
@@ -14,12 +14,12 @@ export interface KptGalleriaProps extends Omit<ComponentPropsWithRef<'div'>, 'on
14
14
  showThumbnails?: boolean;
15
15
  }
16
16
  /**
17
- * Galleria — duży podgląd obrazu z paskiem miniatur i nawigacją.
17
+ * Galleria - duży podgląd obrazu z paskiem miniatur i nawigacją.
18
18
  *
19
19
  * Klawiatura: na całej galerii strzałki w lewo/prawo przechodzą do sąsiedniego obrazu (w RTL
20
- * odwrotnie), `Home`/`End` — do pierwszego/ostatniego; gdy fokus stoi na miniaturze, idzie za
20
+ * odwrotnie), `Home`/`End` - do pierwszego/ostatniego; gdy fokus stoi na miniaturze, idzie za
21
21
  * aktywną. Miniatura ma nazwę z `alt` obrazu i `aria-current` na aktywnej, a zmiana obrazu jest
22
- * ogłaszana uprzejmie („Obraz 2 z 4: …”) — dopiero po działaniu użytkownika, nie przy starcie.
22
+ * ogłaszana uprzejmie ("Obraz 2 z 4: ...") - dopiero po działaniu użytkownika, nie przy starcie.
23
23
  *
24
24
  * @example
25
25
  * <KptGalleria items={photos} activeIndex={index} onActiveIndexChange={setIndex} />
@@ -8,12 +8,12 @@ import { KptIcon } from "../icon/icon.js";
8
8
  /** Klawisze przechodzące między obrazami: kierunek względem bieżącego albo skrajny indeks. */
9
9
  const NAV_KEYS = new Set(['ArrowLeft', 'ArrowRight', 'Home', 'End']);
10
10
  /**
11
- * Galleria — duży podgląd obrazu z paskiem miniatur i nawigacją.
11
+ * Galleria - duży podgląd obrazu z paskiem miniatur i nawigacją.
12
12
  *
13
13
  * Klawiatura: na całej galerii strzałki w lewo/prawo przechodzą do sąsiedniego obrazu (w RTL
14
- * odwrotnie), `Home`/`End` — do pierwszego/ostatniego; gdy fokus stoi na miniaturze, idzie za
14
+ * odwrotnie), `Home`/`End` - do pierwszego/ostatniego; gdy fokus stoi na miniaturze, idzie za
15
15
  * aktywną. Miniatura ma nazwę z `alt` obrazu i `aria-current` na aktywnej, a zmiana obrazu jest
16
- * ogłaszana uprzejmie („Obraz 2 z 4: …”) — dopiero po działaniu użytkownika, nie przy starcie.
16
+ * ogłaszana uprzejmie ("Obraz 2 z 4: ...") - dopiero po działaniu użytkownika, nie przy starcie.
17
17
  *
18
18
  * @example
19
19
  * <KptGalleria items={photos} activeIndex={index} onActiveIndexChange={setIndex} />
@@ -27,7 +27,7 @@ export function KptGalleria({ items = [], activeIndex, defaultActiveIndex = 0, o
27
27
  });
28
28
  // Indeks przycięty do listy: po skróceniu `items` (filtr) widok nie zostaje pusty.
29
29
  const active = Math.min(Math.max(requested, 0), Math.max(items.length - 1, 0));
30
- // Ogłoszenie dopiero po działaniu użytkownika — przy starcie region ma milczeć.
30
+ // Ogłoszenie dopiero po działaniu użytkownika - przy starcie region ma milczeć.
31
31
  const [userMoved, setUserMoved] = useState(false);
32
32
  const thumbsRef = useRef([]);
33
33
  const rootRef = useRef(null);
@@ -50,7 +50,7 @@ export function KptGalleria({ items = [], activeIndex, defaultActiveIndex = 0, o
50
50
  const target = event.key === 'Home' ? 0 : event.key === 'End' ? last : active + (rtl ? -step : step);
51
51
  const focusOnThumb = thumbsRef.current.some((thumb) => thumb === document.activeElement);
52
52
  const next = select(target);
53
- // Fokus na miniaturze idzie za aktywnym obrazem — inaczej strzałka zmieniałaby obraz,
53
+ // Fokus na miniaturze idzie za aktywnym obrazem - inaczej strzałka zmieniałaby obraz,
54
54
  // a fokus zostawał na poprzedniej miniaturze.
55
55
  if (focusOnThumb)
56
56
  thumbsRef.current[next]?.focus();
@@ -7,19 +7,19 @@ Import: `import { KptGalleria, type KptGalleriaItem } from '@konce-pt/react';`
7
7
  <div class="kpt-galleria-host">
8
8
  <div class="kpt-galleria">
9
9
  <div class="kpt-galleria__stage">
10
- <button class="kpt-galleria__nav kpt-galleria__nav--prev" aria-disabled="true" aria-label="Previous">…</button>
11
- <img class="kpt-galleria__image" src="…" alt="Mountain lake">
12
- <button class="kpt-galleria__nav kpt-galleria__nav--next" aria-label="Next">…</button>
10
+ <button class="kpt-galleria__nav kpt-galleria__nav--prev" aria-disabled="true" aria-label="Previous">...</button>
11
+ <img class="kpt-galleria__image" src="..." alt="Mountain lake">
12
+ <button class="kpt-galleria__nav kpt-galleria__nav--next" aria-label="Next">...</button>
13
13
  </div>
14
14
  <div class="kpt-galleria__thumbs">
15
- <button class="kpt-galleria__thumb is-active" aria-current="true" aria-label="Mountain lake"><img src="…" alt=""></button>…
15
+ <button class="kpt-galleria__thumb is-active" aria-current="true" aria-label="Mountain lake"><img src="..." alt=""></button>...
16
16
  </div>
17
17
  <span class="kpt-galleria__live" aria-live="polite">Image 2 of 4: Pine forest</span>
18
18
  </div>
19
19
  </div>
20
20
 
21
21
  ## Props
22
- - `items`: `KptGalleriaItem[]` — `{ src, thumbnail?, alt? }`
22
+ - `items`: `KptGalleriaItem[]` - `{ src, thumbnail?, alt? }`
23
23
  - `activeIndex` / `defaultActiveIndex` / `onActiveIndexChange`
24
24
  - `showThumbnails`: boolean (default true)
25
25
  - `className`, `ref` and every other `<div>` prop go to the host
@@ -48,8 +48,8 @@ The stage `--kpt-color-muted`; the active thumbnail `--kpt-color-primary`; the a
48
48
 
49
49
  ## Accessibility
50
50
  The large image carries its `alt`. Each thumbnail is a button named by the item's `alt` (or
51
- `galleria.image` — “Image 3” — when there is none), with `alt=""` on the thumbnail image so the
51
+ `galleria.image` - "Image 3" - when there is none), with `alt=""` on the thumbnail image so the
52
52
  name is not read twice; the active one carries `aria-current`. The arrows use `aria-disabled` at
53
53
  the ends instead of `disabled`, so they keep the focus. A change of image is announced politely
54
- through a hidden live region — `galleria.position` (“Image 2 of 4”) plus the `alt` — only after the
54
+ through a hidden live region - `galleria.position` ("Image 2 of 4") plus the `alt` - only after the
55
55
  user acts, never on first render.
@@ -3,7 +3,7 @@ import type { AsChildProps } from '../internal/types.ts';
3
3
  /** Rozpiętość kolumny: liczba, `'full'` (cała szerokość) albo dowolna wartość CSS. */
4
4
  export type KptColSpan = number | string;
5
5
  export interface KptColProps extends ComponentPropsWithRef<'div'>, AsChildProps {
6
- /** Rozpiętość kolumny — baza mobile-first. */
6
+ /** Rozpiętość kolumny - baza mobile-first. */
7
7
  span?: KptColSpan;
8
8
  /** Rozpiętość od breakpointa SM (>= 640px). */
9
9
  spanSm?: KptColSpan;
@@ -15,7 +15,7 @@ export interface KptColProps extends ComponentPropsWithRef<'div'>, AsChildProps
15
15
  spanXl?: KptColSpan;
16
16
  /** Rozpiętość od breakpointa 2XL (>= 1536px). */
17
17
  span2xl?: KptColSpan;
18
- /** Numer linii, od której zaczyna się kolumna (1-based) — pozwala robić offsety. */
18
+ /** Numer linii, od której zaczyna się kolumna (1-based) - pozwala robić offsety. */
19
19
  start?: number | string;
20
20
  /** Kolejność wizualna (`order`). Nie zmienia kolejności w DOM ani dla czytników ekranu. */
21
21
  order?: number | string;
@@ -23,10 +23,10 @@ export interface KptColProps extends ComponentPropsWithRef<'div'>, AsChildProps
23
23
  self?: string;
24
24
  }
25
25
  /**
26
- * Kolumna siatki `KptGrid` — rozpiętość mobile-first z nadpisaniami per breakpoint.
26
+ * Kolumna siatki `KptGrid` - rozpiętość mobile-first z nadpisaniami per breakpoint.
27
27
  *
28
28
  * Wartość podana dla mniejszego breakpointa obowiązuje aż do następnego, który ją nadpisze:
29
- * `span={12} spanLg={5}` daje 12 na mobile, tablecie i `md`, a dopiero od `lg` — 5.
29
+ * `span={12} spanLg={5}` daje 12 na mobile, tablecie i `md`, a dopiero od `lg` - 5.
30
30
  *
31
31
  * Ustawia wyłącznie custom properties inline; nie dodaje ani nie usuwa klas. Z `asChild`
32
32
  * przejmuje Twój element, więc kolumną może być `<li>`, `<article>` czy komponent biblioteki.
package/dist/grid/col.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { layoutStyle, renderLayout } from "./layout.js";
2
2
  /**
3
- * Kolumna siatki `KptGrid` — rozpiętość mobile-first z nadpisaniami per breakpoint.
3
+ * Kolumna siatki `KptGrid` - rozpiętość mobile-first z nadpisaniami per breakpoint.
4
4
  *
5
5
  * Wartość podana dla mniejszego breakpointa obowiązuje aż do następnego, który ją nadpisze:
6
- * `span={12} spanLg={5}` daje 12 na mobile, tablecie i `md`, a dopiero od `lg` — 5.
6
+ * `span={12} spanLg={5}` daje 12 na mobile, tablecie i `md`, a dopiero od `lg` - 5.
7
7
  *
8
8
  * Ustawia wyłącznie custom properties inline; nie dodaje ani nie usuwa klas. Z `asChild`
9
9
  * przejmuje Twój element, więc kolumną może być `<li>`, `<article>` czy komponent biblioteki.
@@ -4,7 +4,7 @@ export type KptFlexDirection = 'row' | 'row-reverse' | 'column' | 'column-revers
4
4
  export type KptFlexWrap = 'wrap' | 'nowrap' | 'wrap-reverse';
5
5
  export type KptAlignment = 'start' | 'end' | 'center' | 'stretch' | 'baseline' | 'space-between' | 'space-around' | 'space-evenly';
6
6
  export interface KptFlexProps extends ComponentPropsWithRef<'div'>, AsChildProps {
7
- /** Kierunek osi głównej — baza mobile-first. */
7
+ /** Kierunek osi głównej - baza mobile-first. */
8
8
  direction?: KptFlexDirection;
9
9
  /** Kierunek od breakpointa MD (>= 768px). */
10
10
  directionMd?: KptFlexDirection;
@@ -26,11 +26,11 @@ export interface KptFlexProps extends ComponentPropsWithRef<'div'>, AsChildProps
26
26
  gapX?: string;
27
27
  /** Odstęp w pionie. */
28
28
  gapY?: string;
29
- /** Tryb kontenerowy — zmienne dzieci reagują na szerokość tego kontenera. */
29
+ /** Tryb kontenerowy - zmienne dzieci reagują na szerokość tego kontenera. */
30
30
  container?: boolean;
31
31
  }
32
32
  /**
33
- * Kontener flexbox Koncept UI — te same zmienne i breakpointy co `KptGrid`.
33
+ * Kontener flexbox Koncept UI - te same zmienne i breakpointy co `KptGrid`.
34
34
  * Dla wartości bez odpowiednika w propsach (`grow`, `shrink`, `order` na dziecku)
35
35
  * używa się klas utility: `kpt-grow-1`, `kpt-order-first`, `kpt-self-end`.
36
36
  *
package/dist/grid/flex.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { cn } from "../internal/cn.js";
2
2
  import { layoutStyle, renderLayout } from "./layout.js";
3
3
  /**
4
- * Kontener flexbox Koncept UI — te same zmienne i breakpointy co `KptGrid`.
4
+ * Kontener flexbox Koncept UI - te same zmienne i breakpointy co `KptGrid`.
5
5
  * Dla wartości bez odpowiednika w propsach (`grow`, `shrink`, `order` na dziecku)
6
6
  * używa się klas utility: `kpt-grow-1`, `kpt-order-first`, `kpt-self-end`.
7
7
  *
@@ -1,7 +1,7 @@
1
1
  import type { ComponentPropsWithRef } from 'react';
2
2
  import type { AsChildProps } from '../internal/types.ts';
3
3
  export interface KptGridProps extends ComponentPropsWithRef<'div'>, AsChildProps {
4
- /** Liczba kolumn — baza mobile-first. Domyślnie 12 (z CSS). */
4
+ /** Liczba kolumn - baza mobile-first. Domyślnie 12 (z CSS). */
5
5
  columns?: number;
6
6
  /** Liczba kolumn od breakpointa SM (>= 640px). */
7
7
  columnsSm?: number;
@@ -15,25 +15,25 @@ export interface KptGridProps extends ComponentPropsWithRef<'div'>, AsChildProps
15
15
  columns2xl?: number;
16
16
  /** Odstęp w obu osiach, np. `'1.5rem'` albo `'var(--kpt-space-6)'`. */
17
17
  gap?: string;
18
- /** Odstęp między kolumnami — nadpisuje `gap` w poziomie. */
18
+ /** Odstęp między kolumnami - nadpisuje `gap` w poziomie. */
19
19
  gapX?: string;
20
- /** Odstęp między wierszami — nadpisuje `gap` w pionie. */
20
+ /** Odstęp między wierszami - nadpisuje `gap` w pionie. */
21
21
  gapY?: string;
22
22
  /**
23
23
  * Tryb kontenerowy: spany dzieci reagują na szerokość TEJ siatki, nie okna.
24
- * Liczba kolumn i odstępy nadal idą za viewportem — `@container` nie potrafi
24
+ * Liczba kolumn i odstępy nadal idą za viewportem - `@container` nie potrafi
25
25
  * odpytać elementu o jego własny kontener.
26
26
  */
27
27
  container?: boolean;
28
28
  }
29
29
  /**
30
- * Siatka Koncept UI — CSS Grid sterowany custom properties z `@konce-pt/grid`.
30
+ * Siatka Koncept UI - CSS Grid sterowany custom properties z `@konce-pt/grid`.
31
31
  *
32
32
  * Odpowiednik dyrektywy `kptGrid` z portu Angulara. Dyrektyw w Reakcie nie ma, więc siatka jest
33
- * komponentem — ale takim, który w trybie `asChild` niczego nie dokłada do DOM: przejmuje element,
33
+ * komponentem - ale takim, który w trybie `asChild` niczego nie dokłada do DOM: przejmuje element,
34
34
  * który i tak renderujesz (`<section>`, `<ul>`, `<main>`).
35
35
  *
36
- * Zmiana `columns` nie manipuluje klasami — ustawia zmienną inline, a układ przelicza
36
+ * Zmiana `columns` nie manipuluje klasami - ustawia zmienną inline, a układ przelicza
37
37
  * natywny silnik CSS.
38
38
  *
39
39
  * Wymaga arkusza `@konce-pt/grid` (`import '@konce-pt/grid';`).