@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
@@ -8,7 +8,7 @@ export interface KptBreadcrumbItem {
8
8
  export interface KptBreadcrumbProps extends Omit<ComponentPropsWithRef<'div'>, 'children'>, KptI18nOverrides {
9
9
  items?: readonly KptBreadcrumbItem[];
10
10
  /**
11
- * Zwykły klik w odnośnik. Aplikacja z routerem woła `event.preventDefault()` i nawiguje sama —
11
+ * Zwykły klik w odnośnik. Aplikacja z routerem woła `event.preventDefault()` i nawiguje sama -
12
12
  * bez tego `<a href>` przeładowuje stronę.
13
13
  */
14
14
  onNavigate?: (event: KptNavigateEvent<KptBreadcrumbItem>) => void;
@@ -16,7 +16,7 @@ export interface KptBreadcrumbProps extends Omit<ComponentPropsWithRef<'div'>, '
16
16
  /**
17
17
  * Ścieżka nawigacji (breadcrumbs).
18
18
  *
19
- * Ostatnia pozycja nigdy nie jest odnośnikiem, nawet gdy ma `url` — to bieżąca strona, a link
19
+ * Ostatnia pozycja nigdy nie jest odnośnikiem, nawet gdy ma `url` - to bieżąca strona, a link
20
20
  * prowadzący w to samo miejsce, w którym już jesteś, tylko myli.
21
21
  *
22
22
  * @example
@@ -7,7 +7,7 @@ import { KptIcon } from "../icon/icon.js";
7
7
  /**
8
8
  * Ścieżka nawigacji (breadcrumbs).
9
9
  *
10
- * Ostatnia pozycja nigdy nie jest odnośnikiem, nawet gdy ma `url` — to bieżąca strona, a link
10
+ * Ostatnia pozycja nigdy nie jest odnośnikiem, nawet gdy ma `url` - to bieżąca strona, a link
11
11
  * prowadzący w to samo miejsce, w którym już jesteś, tylko myli.
12
12
  *
13
13
  * @example
@@ -15,7 +15,7 @@ import { KptIcon } from "../icon/icon.js";
15
15
  */
16
16
  export function KptBreadcrumb({ items = [], onNavigate, locale, dictionary, className, ...rest }) {
17
17
  const { t } = useKptMessages({ locale, dictionary });
18
- /** Zwykły klik w odnośnik → `onNavigate` (Ctrl/⌘/Shift, środkowy przycisk i `_blank` zostają natywne). */
18
+ /** Zwykły klik w odnośnik -> `onNavigate` (Ctrl/Cmd/Shift, środkowy przycisk i `_blank` zostają natywne). */
19
19
  const linkClick = (event, item) => {
20
20
  if (item.url && onNavigate && kptIsPlainClick(event, event.currentTarget.target)) {
21
21
  onNavigate({ item, url: item.url, event: event.nativeEvent });
@@ -23,6 +23,6 @@ export function KptBreadcrumb({ items = [], onNavigate, locale, dictionary, clas
23
23
  };
24
24
  return (_jsx("div", { className: cn('kpt-breadcrumb-host', className), ...rest, children: _jsx("nav", { className: "kpt-breadcrumb", "aria-label": t('breadcrumb.label'), children: _jsx("ol", { className: "kpt-breadcrumb__list", children: items.map((item, index) => {
25
25
  const last = index === items.length - 1;
26
- return (_jsxs("li", { className: "kpt-breadcrumb__item", children: [item.url && !last ? (_jsx("a", { className: "kpt-breadcrumb__link", href: item.url, onClick: (event) => linkClick(event, item), children: item.label })) : (_jsx("span", { className: "kpt-breadcrumb__current", "aria-current": last ? 'page' : undefined, children: item.label })), last ? null : _jsx(KptIcon, { name: "chevron-right", className: "kpt-breadcrumb__sep" })] }, item.url ?? `${index}-${item.label}`));
26
+ return (_jsxs("li", { className: "kpt-breadcrumb__item", children: [item.url && !last ? (_jsx("a", { className: "kpt-breadcrumb__link", href: item.url, onClick: (event) => linkClick(event, item), children: item.label })) : (_jsx("span", { className: "kpt-breadcrumb__current", "aria-current": last ? 'page' : undefined, children: item.label })), last ? null : _jsx(KptIcon, { name: "chevron-right", className: "kpt-breadcrumb__sep" })] }, `${index}-${item.url ?? item.label}`));
27
27
  }) }) }) }));
28
28
  }
@@ -8,7 +8,7 @@ A breadcrumb trail. Import: `import { KptBreadcrumb } from '@konce-pt/react';`
8
8
  <ol class="kpt-breadcrumb__list">
9
9
  <li class="kpt-breadcrumb__item">
10
10
  <a class="kpt-breadcrumb__link" href="/">Home</a>
11
- <span class="kpt-icon-host kpt-breadcrumb__sep">…</span>
11
+ <span class="kpt-icon-host kpt-breadcrumb__sep">...</span>
12
12
  </li>
13
13
  <li class="kpt-breadcrumb__item">
14
14
  <span class="kpt-breadcrumb__current" aria-current="page">Showcase</span>
@@ -19,7 +19,7 @@ A breadcrumb trail. Import: `import { KptBreadcrumb } from '@konce-pt/react';`
19
19
 
20
20
  ## Props
21
21
  - `items`: `{ label, url? }[]`
22
- - `locale`, `dictionary` — i18n overrides for this component only
22
+ - `locale`, `dictionary` - i18n overrides for this component only
23
23
  - `className`, `ref` and every other `<div>` prop go to the host
24
24
 
25
25
  ## The last item is never a link
@@ -43,7 +43,7 @@ screen reader announces how many levels the trail has. The current page carries
43
43
 
44
44
  ## Router
45
45
  Links are plain `<a href>`, so without a router a click reloads the page. `onNavigate` fires on a plain
46
- click (left button, no Ctrl/⌘/Shift, no `target="_blank"`) with `{ item, url, event }`: call
46
+ click (left button, no Ctrl/Cmd/Shift, no `target="_blank"`) with `{ item, url, event }`: call
47
47
  `event.preventDefault()` and navigate with your router. Modified clicks stay native (a new tab, a new
48
48
  window). The library depends on no router.
49
49
 
@@ -13,7 +13,7 @@ export interface KptButtonProps extends Omit<ComponentPropsWithRef<'button'>, 'h
13
13
  fullWidth?: boolean;
14
14
  /** Nazwa ikony wiodącej z rejestru (`KptIconRegistry`). */
15
15
  icon?: string;
16
- /** Nazwa ikony zamykającej — zwykle znacznik kierunku, nie akcja. */
16
+ /** Nazwa ikony zamykającej - zwykle znacznik kierunku, nie akcja. */
17
17
  iconEnd?: string;
18
18
  /** Klasa dokładana do ikony wiodącej; obok stałego haka `.kpt-button__icon`. */
19
19
  iconClassName?: string;
@@ -27,10 +27,10 @@ export interface KptButtonProps extends Omit<ComponentPropsWithRef<'button'>, 'h
27
27
  }
28
28
  /**
29
29
  * Przycisk Koncept UI. Renderuje natywny `<button>` (semantyka + submit formularza)
30
- * albo `<a>`, gdy podasz `href` — w hoście `.kpt-button-host`, czyli dwa poziomy DOM,
30
+ * albo `<a>`, gdy podasz `href` - w hoście `.kpt-button-host`, czyli dwa poziomy DOM,
31
31
  * dokładnie jak w porcie Angulara, bo host niesie własne style.
32
32
  *
33
- * Ikonę można podać nazwą (`icon`/`iconEnd`) albo wstawić w `children` — oba sposoby
33
+ * Ikonę można podać nazwą (`icon`/`iconEnd`) albo wstawić w `children` - oba sposoby
34
34
  * dostają ten sam odstęp i tę samą skalę. Przy `loading` spinner zajmuje miejsce ikony wiodącej.
35
35
  *
36
36
  * @example
@@ -6,10 +6,10 @@ import { renderAsChild } from "../internal/slot.js";
6
6
  import { KptIcon } from "../icon/icon.js";
7
7
  /**
8
8
  * Przycisk Koncept UI. Renderuje natywny `<button>` (semantyka + submit formularza)
9
- * albo `<a>`, gdy podasz `href` — w hoście `.kpt-button-host`, czyli dwa poziomy DOM,
9
+ * albo `<a>`, gdy podasz `href` - w hoście `.kpt-button-host`, czyli dwa poziomy DOM,
10
10
  * dokładnie jak w porcie Angulara, bo host niesie własne style.
11
11
  *
12
- * Ikonę można podać nazwą (`icon`/`iconEnd`) albo wstawić w `children` — oba sposoby
12
+ * Ikonę można podać nazwą (`icon`/`iconEnd`) albo wstawić w `children` - oba sposoby
13
13
  * dostają ten sam odstęp i tę samą skalę. Przy `loading` spinner zajmuje miejsce ikony wiodącej.
14
14
  *
15
15
  * @example
@@ -22,14 +22,14 @@ import { KptIcon } from "../icon/icon.js";
22
22
  export function KptButton({ variant = 'filled', size = 'md', type = 'button', loading = false, fullWidth = false, disabled = false, asChild = false, icon, iconEnd, iconClassName, iconEndClassName, href, target, rel, hostProps, className, children, ...rest }) {
23
23
  const { className: hostClassName, ...hostRest } = hostProps ?? {};
24
24
  const isDisabled = disabled || loading;
25
- // Zawartość jest identyczna we wszystkich trybach — w `asChild` podmieniamy tylko element
25
+ // Zawartość jest identyczna we wszystkich trybach - w `asChild` podmieniamy tylko element
26
26
  // zewnętrzny, nie strukturę środka, żeby SCSS (`__spinner`, `__content`) dalej działał.
27
27
  const content = (_jsxs(_Fragment, { children: [loading ? (_jsx("span", { className: "kpt-button__spinner", "aria-hidden": "true" })) : icon ? (_jsx(KptIcon, { className: cn('kpt-button__icon', iconClassName), name: icon })) : null, _jsx("span", { className: "kpt-button__content", children: asChildContent(asChild, children) }), iconEnd ? (_jsx(KptIcon, { className: cn('kpt-button__icon', 'kpt-button__icon--end', iconEndClassName), name: iconEnd })) : null] }));
28
28
  const buttonProps = {
29
29
  className: cn('kpt-button', loading && 'kpt-button--loading', className),
30
30
  'data-variant': variant,
31
31
  'data-size': size,
32
- // React serializuje atrybuty aria-* z booleana na "true"/"false" — wynikowy DOM
32
+ // React serializuje atrybuty aria-* z booleana na "true"/"false" - wynikowy DOM
33
33
  // ma `aria-busy="true"`, tak jak port Angulara.
34
34
  'aria-busy': loading || undefined,
35
35
  ...rest,
@@ -37,7 +37,7 @@ export function KptButton({ variant = 'filled', size = 'md', type = 'button', lo
37
37
  return (_jsx("span", { className: cn('kpt-button-host', fullWidth && 'kpt-button-host--full', hostClassName), ...hostRest, children: renderInner({ asChild, children, buttonProps, content, href, target, rel, type, isDisabled }) }));
38
38
  }
39
39
  /**
40
- * Element wewnętrzny. `asChild` ma pierwszeństwo przed `href` — kto podstawia własny
40
+ * Element wewnętrzny. `asChild` ma pierwszeństwo przed `href` - kto podstawia własny
41
41
  * element, ten decyduje o znaczniku.
42
42
  */
43
43
  function renderInner(args) {
@@ -47,17 +47,17 @@ function renderInner(args) {
47
47
  }
48
48
  if (href !== undefined) {
49
49
  return (_jsx("a", {
50
- // Wyłączony odnośnik traci `href`, a nie tylko dostaje atrybut — inaczej dałoby się go
50
+ // Wyłączony odnośnik traci `href`, a nie tylko dostaje atrybut - inaczej dałoby się go
51
51
  // kliknąć i wejść na niego z klawiatury.
52
52
  href: isDisabled ? undefined : href, target: target,
53
- // `target="_blank"` bez `rel` to wektor na `window.opener` — dokładamy domyślne.
53
+ // `target="_blank"` bez `rel` to wektor na `window.opener` - dokładamy domyślne.
54
54
  rel: rel ?? (target === '_blank' ? 'noopener noreferrer' : undefined), "aria-disabled": isDisabled || undefined, tabIndex: isDisabled ? -1 : undefined, ...(buttonProps), children: content }));
55
55
  }
56
56
  return (_jsx("button", { type: type, disabled: isDisabled, ...buttonProps, children: content }));
57
57
  }
58
58
  /**
59
59
  * Stan wyłączenia dla podstawionego elementu. Natywny `<button>` dostaje `disabled`
60
- * (SCSS stylizuje `:disabled`); każdy inny element — `aria-disabled`, bo `disabled`
60
+ * (SCSS stylizuje `:disabled`); każdy inny element - `aria-disabled`, bo `disabled`
61
61
  * nie ma tam znaczenia.
62
62
  */
63
63
  function disabledProps(child, isDisabled) {
@@ -1,15 +1,15 @@
1
1
  # KptButton (@konce-pt/react)
2
2
 
3
- The Koncept UI button. It renders a native `<button>` (semantics + form submit) — or an `<a>` when
4
- you pass `href` — inside a `.kpt-button-host` wrapper: two DOM levels, exactly like the Angular port,
3
+ The Koncept UI button. It renders a native `<button>` (semantics + form submit) - or an `<a>` when
4
+ you pass `href` - inside a `.kpt-button-host` wrapper: two DOM levels, exactly like the Angular port,
5
5
  because the host carries its own styles. Import: `import { KptButton } from '@konce-pt/react';`
6
6
 
7
7
  ## DOM
8
8
  <span class="kpt-button-host">
9
9
  <button class="kpt-button" type="button" data-variant="filled" data-size="md">
10
- <span class="kpt-button__icon kpt-icon-host">…</span>
11
- <span class="kpt-button__content">…</span>
12
- <span class="kpt-button__icon kpt-button__icon--end kpt-icon-host">…</span>
10
+ <span class="kpt-button__icon kpt-icon-host">...</span>
11
+ <span class="kpt-button__content">...</span>
12
+ <span class="kpt-button__icon kpt-button__icon--end kpt-icon-host">...</span>
13
13
  </button>
14
14
  </span>
15
15
 
@@ -18,39 +18,39 @@ because the host carries its own styles. Import: `import { KptButton } from '@ko
18
18
  - `size`: 'xs' | 'sm' | 'md' | 'lg' | 'xl' (default 'md')
19
19
  - `type`: 'button' | 'submit' | 'reset' (default 'button')
20
20
  - `disabled`: boolean
21
- - `loading`: boolean — a spinner + blocked interaction, sets `aria-busy`
22
- - `fullWidth`: boolean — the full width of the container
23
- - `icon` / `iconEnd`: string — a name from the icon registry
24
- - `iconClassName` / `iconEndClassName`: string — an extra class on that icon
25
- - `href`, `target`, `rel`: string — render an `<a>` instead of a `<button>`
26
- - `asChild`: boolean — render the single child instead of `<button>`, keeping every class
21
+ - `loading`: boolean - a spinner + blocked interaction, sets `aria-busy`
22
+ - `fullWidth`: boolean - the full width of the container
23
+ - `icon` / `iconEnd`: string - a name from the icon registry
24
+ - `iconClassName` / `iconEndClassName`: string - an extra class on that icon
25
+ - `href`, `target`, `rel`: string - render an `<a>` instead of a `<button>`
26
+ - `asChild`: boolean - render the single child instead of `<button>`, keeping every class
27
27
  - `hostProps`: props for the `.kpt-button-host` wrapper
28
28
  - `className`, `ref` and every other `<button>` prop go to the INNER element
29
29
 
30
30
  ## Events
31
- No events of its own — bind `onClick` and it lands on the native `<button>`.
31
+ No events of its own - bind `onClick` and it lands on the native `<button>`.
32
32
 
33
33
  ## Icons
34
34
  Two ways in, one result. `icon` and `iconEnd` take a name from the icon registry and the component
35
35
  renders it; anything put in `children` is laid out the same way. Both get the gap from
36
- `--kpt-button-gap` and a size that follows `size` (0.875rem at `xs` up to 1.5rem at `xl`) — the
36
+ `--kpt-button-gap` and a size that follows `size` (0.875rem at `xs` up to 1.5rem at `xl`) - the
37
37
  content box is a flex container, so an icon sits on the centre line rather than on the text baseline.
38
38
 
39
39
  `loading` replaces the leading icon with the spinner instead of standing next to it, and the
40
40
  spinner takes that icon's size, so the label does not jump when loading starts. The trailing icon
41
- stays put — it usually marks direction rather than the action.
41
+ stays put - it usually marks direction rather than the action.
42
42
 
43
43
  `iconClassName` / `iconEndClassName` add a class next to the permanent `.kpt-button__icon` hook, for
44
44
  the cases where one instance needs a different colour or a rotation.
45
45
 
46
46
  ## Link and the `link` variant
47
- Two different things. `variant="link"` only changes the looks — underline, transparent background,
47
+ Two different things. `variant="link"` only changes the looks - underline, transparent background,
48
48
  no side padding, so it sits inside a sentence. `href` changes the element: the component renders
49
49
  `<a class="kpt-button">` instead of `<button>`, and the two combine freely (a filled button can be
50
50
  a link, a `link` variant can be a plain button). `asChild` wins over `href`: whoever substitutes
51
51
  their own element decides the tag.
52
52
 
53
- A disabled link loses its `href` rather than just gaining an attribute — otherwise it would stay
53
+ A disabled link loses its `href` rather than just gaining an attribute - otherwise it would stay
54
54
  clickable and reachable with the keyboard; it also gets `aria-disabled="true"` and `tabindex="-1"`.
55
55
  `target="_blank"` without an explicit `rel` gets `rel="noopener noreferrer"`.
56
56
 
@@ -68,9 +68,17 @@ clickable and reachable with the keyboard; it also gets `aria-disabled="true"` a
68
68
  ## asChild
69
69
  The wrapper is still rendered; only the inner element is swapped. The content stays wrapped in
70
70
  `.kpt-button__content`, so the spinner and the layout keep working. A disabled substituted
71
- element gets `disabled` when it is a native `<button>`, and `aria-disabled` otherwise — an
71
+ element gets `disabled` when it is a native `<button>`, and `aria-disabled` otherwise - an
72
72
  element with no `:disabled` state therefore does not get the dimmed look.
73
73
 
74
+ ## Motion
75
+ Pressed, it squeezes slightly and springs back on release (shared mixin `styles/_press.scss`). Entering `loading` pops the spinner in where the leading icon was
76
+ and dims the label. `link` does not squeeze (text in a sentence would jitter): its colour and
77
+ underline change smoothly and it dims while pressed. `elevated` lifts on hover and is pressed down
78
+ (the shadow shrinks smoothly). A pressed button uses its own variant's hover colour - only `filled` has
79
+ a separate pressed colour. Pure CSS; durations follow `--kpt-motion-scale`, so `enabled: false` turns it off, and it drops out
80
+ under "reduce motion".
81
+
74
82
  ## Tokens (styling)
75
83
  `--kpt-button-radius`, `--kpt-button-font-weight`, `--kpt-button-gap`, and one group per variant:
76
84
  `--kpt-button-filled-{bg,fg,bg-hover,bg-active}`, `--kpt-button-elevated-{bg,fg,bg-hover}`,
@@ -80,13 +88,13 @@ element with no `:disabled` state therefore does not get the dimmed look.
80
88
  The elevated variant also reaches for `--kpt-shadow-sm` and `--kpt-shadow-md`.
81
89
 
82
90
  ## The state layer (hover / active)
83
- Hover and active feedback is carried by an `::after` pseudo-element (`opacity` 0 → 1), not by
91
+ Hover and active feedback is carried by an `::after` pseudo-element (`opacity` 0 -> 1), not by
84
92
  animating the button's own `background-color`. The CSS is shared with the Angular port, where
85
93
  the pattern was introduced to stop the variant flicker on first paint; here it simply comes
86
94
  along with the stylesheet.
87
95
 
88
96
  ## Accessibility
89
- - A native `<button>` — full keyboard and screen reader support.
97
+ - A native `<button>` - full keyboard and screen reader support.
90
98
  - `loading` sets `aria-busy="true"` and disables the button.
91
99
  - An `<a>` matches no `:disabled`, so the disabled look keys off `[aria-disabled='true']` as well.
92
100
  - The focus ring comes from `@konce-pt/styles` (`--kpt-color-focus-ring`).
@@ -1,4 +1,4 @@
1
- import type { ComponentPropsWithRef } from 'react';
1
+ import { type ComponentPropsWithRef } from 'react';
2
2
  import type { KptHostProps } from '../internal/types.ts';
3
3
  import type { KptOption } from '../shared/types.ts';
4
4
  export interface KptButtonGroupProps<T> extends Omit<ComponentPropsWithRef<'div'>, 'children' | 'onChange' | 'defaultValue'> {
@@ -8,32 +8,32 @@ export interface KptButtonGroupProps<T> extends Omit<ComponentPropsWithRef<'div'
8
8
  onValueChange?: (value: T) => void;
9
9
  size?: 'sm' | 'md' | 'lg';
10
10
  disabled?: boolean;
11
- /** Tylko do odczytu — wybór widać, nie da się go zmienić (`aria-readonly`). */
11
+ /** Tylko do odczytu - wybór widać, nie da się go zmienić (`aria-readonly`). */
12
12
  readOnly?: boolean;
13
- /** Pole wymagane — `aria-required`. */
13
+ /** Pole wymagane - `aria-required`. */
14
14
  required?: boolean;
15
- /** Id grupy; bez niego generowane, w `KptFormField` — z wrappera. */
15
+ /** Id grupy; bez niego generowane, w `KptFormField` - z wrappera. */
16
16
  id?: string;
17
17
  /** Nazwa dostępna grupy, gdy nie opisuje jej etykieta (`KptFormField`). */
18
18
  ariaLabel?: string | null;
19
19
  invalid?: boolean;
20
20
  touched?: boolean;
21
- /** Wywoływane po wyborze — moment, w którym kontrolka staje się dotknięta. */
21
+ /** Wywoływane po wyborze - moment, w którym kontrolka staje się dotknięta. */
22
22
  onTouch?: () => void;
23
- /** Chowa etykiety — zostaje sama ikona, a `label` zasila `aria-label` i dymek `KptTooltip`. */
23
+ /** Chowa etykiety - zostaje sama ikona, a `label` zasila `aria-label` i dymek `KptTooltip`. */
24
24
  iconOnly?: boolean;
25
25
  /** Propsy wrappera hosta (`.kpt-button-group-host`). */
26
26
  hostProps?: KptHostProps<'span'>;
27
27
  }
28
28
  /**
29
- * Segmentowana grupa przycisków (toggle) — pojedynczy wybór z opcji.
29
+ * Segmentowana grupa przycisków (toggle) - pojedynczy wybór z opcji.
30
30
  *
31
31
  * Działa kontrolowana (`value` + `onValueChange`) i niekontrolowana (`defaultValue`).
32
32
  * Pozycja może mieć ikonę (`KptOption.icon`); `iconOnly` chowa etykietę, ale zostawia ją
33
33
  * w nazwie dostępnej, więc czytnik ekranu dalej wie, co wybiera.
34
34
  *
35
- * Wybór jest wyłączny, więc grupa to `role="radiogroup"` z pozycjami `role="radio"` (APG) —
36
- * czytnik ogłasza „2 z 3”. Jeden przystanek Tab, strzałki przenoszą wybór, `Home`/`End` na skrajne.
35
+ * Wybór jest wyłączny, więc grupa to `role="radiogroup"` z pozycjami `role="radio"` (APG) -
36
+ * czytnik ogłasza "2 z 3". Jeden przystanek Tab, strzałki przenoszą wybór, `Home`/`End` na skrajne.
37
37
  *
38
38
  * @example
39
39
  * <KptButtonGroup value={view} onValueChange={setView}
@@ -1,5 +1,8 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useLayoutEffect, useRef } from 'react';
4
+ import { playIndicatorMotion, resolveToggleMotion } from '@konce-pt/motion';
5
+ import { useKptMotion } from "../motion/motion-context.js";
3
6
  import { cn } from "../internal/cn.js";
4
7
  import { useControllableState } from "../internal/use-controllable-state.js";
5
8
  import { KptIcon } from "../icon/icon.js";
@@ -7,14 +10,14 @@ import { KptTooltip } from "../tooltip/tooltip.js";
7
10
  import { useKptFieldA11y } from "../form-field/form-field-context.js";
8
11
  import { nextRovingIndex, rovingStop } from "../internal/roving.js";
9
12
  /**
10
- * Segmentowana grupa przycisków (toggle) — pojedynczy wybór z opcji.
13
+ * Segmentowana grupa przycisków (toggle) - pojedynczy wybór z opcji.
11
14
  *
12
15
  * Działa kontrolowana (`value` + `onValueChange`) i niekontrolowana (`defaultValue`).
13
16
  * Pozycja może mieć ikonę (`KptOption.icon`); `iconOnly` chowa etykietę, ale zostawia ją
14
17
  * w nazwie dostępnej, więc czytnik ekranu dalej wie, co wybiera.
15
18
  *
16
- * Wybór jest wyłączny, więc grupa to `role="radiogroup"` z pozycjami `role="radio"` (APG) —
17
- * czytnik ogłasza „2 z 3”. Jeden przystanek Tab, strzałki przenoszą wybór, `Home`/`End` na skrajne.
19
+ * Wybór jest wyłączny, więc grupa to `role="radiogroup"` z pozycjami `role="radio"` (APG) -
20
+ * czytnik ogłasza "2 z 3". Jeden przystanek Tab, strzałki przenoszą wybór, `Home`/`End` na skrajne.
18
21
  *
19
22
  * @example
20
23
  * <KptButtonGroup value={view} onValueChange={setView}
@@ -29,19 +32,38 @@ export function KptButtonGroup({ options = [], value, defaultValue, onValueChang
29
32
  defaultValue,
30
33
  onChange: onValueChange,
31
34
  });
32
- /** Grupa nie dostaje nazwy z `label[for]` — stąd `aria-labelledby` na etykietę wrappera. */
35
+ /** Grupa nie dostaje nazwy z `label[for]` - stąd `aria-labelledby` na etykietę wrappera. */
33
36
  const field = useKptFieldA11y(id, 'kpt-button-group');
34
37
  const showInvalid = invalid && (touched ?? true);
35
38
  const disabledMap = options.map((option) => disabled || !!option.disabled);
36
39
  /** Jedyny przystanek Tab: wybrana pozycja, a bez wyboru pierwsza dozwolona. */
37
40
  const tabStop = rovingStop(disabledMap, options.findIndex((option) => option.value === current));
38
- const select = (option) => {
41
+ const toggleMotion = resolveToggleMotion(undefined, useKptMotion());
42
+ /** Tło wyboru zmierzone przed zmianą - przejeżdża z niego na nową pozycję po renderze. */
43
+ const pendingIndicator = useRef(null);
44
+ // Przed malowaniem - inaczej mignęłaby klatka z tłem już na nowej pozycji.
45
+ useLayoutEffect(() => {
46
+ const pending = pendingIndicator.current;
47
+ pendingIndicator.current = null;
48
+ const active = pending?.group.querySelector('.kpt-button-group__item.is-active');
49
+ if (pending && active)
50
+ playIndicatorMotion(pending.before, active);
51
+ });
52
+ /**
53
+ * Wybór pozycji. Tło wyboru przejeżdża z poprzedniej pozycji na nową (za `toggle` z
54
+ * `KptMotionProvider`, tylko `spring`).
55
+ */
56
+ const select = (option, from) => {
39
57
  if (option.disabled || disabled || readOnly)
40
58
  return;
59
+ const group = from.closest('.kpt-button-group');
60
+ const before = group?.querySelector('.kpt-button-group__item.is-active')?.getBoundingClientRect();
61
+ if (group && before && toggleMotion === 'spring')
62
+ pendingIndicator.current = { group, before };
41
63
  setCurrent(option.value);
42
64
  onTouch?.();
43
65
  };
44
- /** Strzałki (pion traktowany jak poziom), `Home`/`End`: fokus i wybór idą razem — wzorzec radia. */
66
+ /** Strzałki (pion traktowany jak poziom), `Home`/`End`: fokus i wybór idą razem - wzorzec radia. */
45
67
  const onKeyDown = (event) => {
46
68
  const vertical = { ArrowDown: 'ArrowRight', ArrowUp: 'ArrowLeft' };
47
69
  const rtl = getComputedStyle(event.currentTarget).direction === 'rtl';
@@ -53,10 +75,10 @@ export function KptButtonGroup({ options = [], value, defaultValue, onValueChang
53
75
  return;
54
76
  event.preventDefault();
55
77
  event.currentTarget.querySelectorAll('[role="radio"]')[next]?.focus();
56
- select(options[next]);
78
+ select(options[next], event.currentTarget);
57
79
  };
58
80
  return (_jsx("span", { className: cn('kpt-button-group-host', hostClassName), ...hostRest, children: _jsx("div", { className: cn('kpt-button-group', showInvalid && 'kpt-button-group--invalid', className), role: "radiogroup", id: field.id, "data-size": size, "data-icon-only": iconOnly ? '' : undefined, "aria-label": ariaLabel ?? undefined, "aria-labelledby": ariaLabel ? undefined : field.labelledBy, "aria-describedby": field.describedBy, "aria-required": required || undefined, "aria-readonly": readOnly || undefined, "aria-invalid": showInvalid || undefined, onKeyDown: onKeyDown, ...rest, children: options.map((option, index) => {
59
81
  const active = option.value === current;
60
- return (_jsx(KptTooltip, { text: iconOnly ? option.label : '', children: _jsxs("button", { type: "button", role: "radio", className: cn('kpt-button-group__item', active && 'is-active'), disabled: disabled || option.disabled, tabIndex: index === tabStop ? 0 : -1, "aria-checked": active, "aria-label": iconOnly ? option.label : undefined, onClick: () => select(option), children: [option.icon ? _jsx(KptIcon, { className: "kpt-button-group__icon", name: option.icon }) : null, iconOnly ? null : _jsx("span", { className: "kpt-button-group__label", children: option.label })] }) }, typeof option.value === 'object' && option.value !== null ? `#${index}` : String(option.value)));
82
+ return (_jsx(KptTooltip, { text: iconOnly ? option.label : '', children: _jsxs("button", { type: "button", role: "radio", className: cn('kpt-button-group__item', active && 'is-active'), disabled: disabled || option.disabled, tabIndex: index === tabStop ? 0 : -1, "aria-checked": active, "aria-label": iconOnly ? option.label : undefined, onClick: (event) => select(option, event.currentTarget), children: [option.icon ? _jsx(KptIcon, { className: "kpt-button-group__icon", name: option.icon }) : null, iconOnly ? null : _jsx("span", { className: "kpt-button-group__label", children: option.label })] }) }, typeof option.value === 'object' && option.value !== null ? `#${index}` : String(option.value)));
61
83
  }) }) }));
62
84
  }
@@ -1,13 +1,13 @@
1
1
  # KptButtonGroup (@konce-pt/react)
2
2
 
3
- A segmented button group (toggle) — a single choice out of the options.
3
+ A segmented button group (toggle) - a single choice out of the options.
4
4
  Import: `import { KptButtonGroup } from '@konce-pt/react';`
5
5
 
6
6
  ## DOM
7
7
  <span class="kpt-button-group-host">
8
8
  <div class="kpt-button-group" role="radiogroup" data-size="md">
9
9
  <button type="button" role="radio" class="kpt-button-group__item is-active" aria-checked="true" tabindex="0">
10
- <span class="kpt-button-group__icon kpt-icon-host">…</span>
10
+ <span class="kpt-button-group__icon kpt-icon-host">...</span>
11
11
  <span class="kpt-button-group__label">List</span>
12
12
  </button>
13
13
  <button type="button" role="radio" class="kpt-button-group__item" aria-checked="false" tabindex="-1">
@@ -17,31 +17,31 @@ Import: `import { KptButtonGroup } from '@konce-pt/react';`
17
17
  </span>
18
18
 
19
19
  ## Props
20
- - `options`: `KptOption<T>[]` — `{ label, value, disabled?, icon? }`
21
- - `value` / `defaultValue` / `onValueChange` — controlled or uncontrolled
20
+ - `options`: `KptOption<T>[]` - `{ label, value, disabled?, icon? }`
21
+ - `value` / `defaultValue` / `onValueChange` - controlled or uncontrolled
22
22
  - `size`: 'sm' | 'md' | 'lg' (default 'md')
23
- - `disabled`: boolean — disables the whole group; a single option disables itself
24
- - `iconOnly`: boolean — hides the labels and leaves the icons alone
25
- - `onTouch()` — fires on a pick, the moment the control becomes touched
26
- - `hostProps` — props for the `.kpt-button-group-host` wrapper
23
+ - `disabled`: boolean - disables the whole group; a single option disables itself
24
+ - `iconOnly`: boolean - hides the labels and leaves the icons alone
25
+ - `onTouch()` - fires on a pick, the moment the control becomes touched
26
+ - `hostProps` - props for the `.kpt-button-group-host` wrapper
27
27
  - `className`, `ref` and every other `<div>` prop go to `.kpt-button-group`
28
28
 
29
29
  ## Icons
30
30
  An option carries its icon by name: `KptOption.icon` is a key from the icon registry, and the group
31
31
  renders it before the label. The item is a flex box, so the icon gets the `--kpt-button-gap` spacing
32
- and a size that follows `size` (1rem at `sm` up to 1.25rem at `lg`) — the same scale as `KptButton`,
32
+ and a size that follows `size` (1rem at `sm` up to 1.25rem at `lg`) - the same scale as `KptButton`,
33
33
  so a group standing next to a button matches it.
34
34
 
35
35
  `iconOnly` drops the label from the page but keeps it as the accessible name: the item gets both
36
36
  `aria-label` and `title`, so a screen reader still says "Grid" and a mouse user gets a tooltip.
37
37
  Each item also becomes a square, because a lone icon inside a 1rem side padding looks adrift.
38
38
 
39
- The icon takes its colour from `currentColor`, so the active item — filled with
40
- `--kpt-color-primary` — flips the icon to `--kpt-color-on-primary` with no extra rule.
39
+ The icon takes its colour from `currentColor`, so the active item - filled with
40
+ `--kpt-color-primary` - flips the icon to `--kpt-color-on-primary` with no extra rule.
41
41
 
42
42
  ## Values of any type
43
43
  The value is generic, so options can carry objects, not just strings. Keys come from
44
- `String(option.value)`, so distinct options need distinct string forms — for object values give
44
+ `String(option.value)`, so distinct options need distinct string forms - for object values give
45
45
  each one a stable id and map back to the object yourself.
46
46
 
47
47
  ## Examples
@@ -55,14 +55,20 @@ each one a stable id and map back to the object yourself.
55
55
 
56
56
  <KptButtonGroup size="sm" defaultValue="M" options={sizeOptions} />
57
57
 
58
+ ## Motion
59
+ The selection background slides from the previously selected option to the new one on a spring (a FLIP
60
+ of the `::before` layer, `playIndicatorMotion` from `@konce-pt/motion`), the label colour crossfades,
61
+ and a pressed option squeezes slightly. The slide follows `toggle` from `KptMotionProvider` (`spring` only);
62
+ `enabled: false` and the system "reduce motion" setting always win.
63
+
58
64
  ## Tokens
59
65
  `--kpt-color-surface`, `--kpt-color-muted`, `--kpt-color-primary` (the active segment),
60
66
  `--kpt-color-border-strong`, `--kpt-radius-md`, `--kpt-button-gap`.
61
67
 
62
68
  ## Accessibility
63
- A `role="radiogroup"` of native buttons with `role="radio"` and `aria-checked` — a screen reader
69
+ A `role="radiogroup"` of native buttons with `role="radio"` and `aria-checked` - a screen reader
64
70
  announces which segment is on and "2 of 3"; one Tab stop, arrows move the choice. With `iconOnly`
65
71
  the name comes from `aria-label`, so the announcement does not degrade to a bare "radio button".
66
72
 
67
73
  ## Read-only and required
68
- The group is `role="radiogroup"` with `role="radio"` items (`aria-checked`) instead of `aria-pressed` buttons — the choice is exclusive, so a screen reader announces "2 of 3". One Tab stop, arrows move the selection, `Home`/`End` jump to the ends. New: `id`, `ariaLabel`, `readOnly`, `required`, and the error state (`invalid` + `touched`) visible on the group itself.
74
+ The group is `role="radiogroup"` with `role="radio"` items (`aria-checked`) instead of `aria-pressed` buttons - the choice is exclusive, so a screen reader announces "2 of 3". One Tab stop, arrows move the selection, `Home`/`End` jump to the ends. New: `id`, `ariaLabel`, `readOnly`, `required`, and the error state (`invalid` + `touched`) visible on the group itself.
@@ -9,15 +9,15 @@ export interface KptCardProps extends ComponentPropsWithRef<'div'> {
9
9
  header?: string;
10
10
  /**
11
11
  * Robi z `header` nagłówek strony (`role="heading"` z `aria-level`), żeby karta pojawiła się
12
- * w strukturze dokumentu. Bez tego `header` to sam tekst — część kart (np. kafelki statystyk)
12
+ * w strukturze dokumentu. Bez tego `header` to sam tekst - część kart (np. kafelki statystyk)
13
13
  * nie powinna zaśmiecać spisu nagłówków.
14
14
  */
15
15
  headingLevel?: KptCardHeadingLevel;
16
- /** Body bez wewnętrznego paddingu — dla układów zarządzających własnymi sekcjami. */
16
+ /** Body bez wewnętrznego paddingu - dla układów zarządzających własnymi sekcjami. */
17
17
  flush?: boolean;
18
18
  }
19
19
  /**
20
- * Karta Koncept UI — powierzchnia z wyniesieniem (`elevated`) albo obramowaniem (`outlined`).
20
+ * Karta Koncept UI - powierzchnia z wyniesieniem (`elevated`) albo obramowaniem (`outlined`).
21
21
  *
22
22
  * Ciało karty renderuje sama karta; `flush` zdejmuje jego padding. Do bogatych układów
23
23
  * służą komponenty składane: `KptCard.Media`, `.Lead`, `.Title`, `.Subtitle`, `.Section`,
@@ -25,7 +25,7 @@ export interface KptCardProps extends ComponentPropsWithRef<'div'> {
25
25
  *
26
26
  * @example
27
27
  * <KptCard header="Ustawienia" variant="outlined">
28
- * <p>Treść…</p>
28
+ * <p>Treść...</p>
29
29
  * <KptCard.Footer><KptButton>Zapisz</KptButton></KptCard.Footer>
30
30
  * </KptCard>
31
31
  */
@@ -42,13 +42,13 @@ export declare namespace KptCard {
42
42
  var Meta: typeof KptCardMeta;
43
43
  var Actions: typeof KptCardActions;
44
44
  }
45
- /** Nagłówek karty — alternatywa dla propa `header`, gdy potrzebna jest bogatsza treść. */
45
+ /** Nagłówek karty - alternatywa dla propa `header`, gdy potrzebna jest bogatsza treść. */
46
46
  export declare function KptCardHeader({ className, ...rest }: Readonly<ComponentPropsWithRef<'div'>>): import("react").JSX.Element;
47
47
  export declare namespace KptCardHeader {
48
48
  var kptCardSlot: "header";
49
49
  }
50
50
  /**
51
- * Stopka karty. Nosi atrybut `kptcardfooter` — to po nim celuje wspólny SCSS
51
+ * Stopka karty. Nosi atrybut `kptcardfooter` - to po nim celuje wspólny SCSS
52
52
  * (nazwy atrybutów w selektorach CSS są w HTML case-insensitive, więc ta sama
53
53
  * reguła `[kptCardFooter]` obsługuje oba porty).
54
54
  */
@@ -64,11 +64,11 @@ export declare function KptCardLead({ className, ...rest }: Readonly<ComponentPr
64
64
  export declare function KptCardTitle({ className, ...rest }: Readonly<ComponentPropsWithRef<'div'>>): import("react").JSX.Element;
65
65
  /** Typografia podtytułu (kolor przygaszony). */
66
66
  export declare function KptCardSubtitle({ className, ...rest }: Readonly<ComponentPropsWithRef<'div'>>): import("react").JSX.Element;
67
- /** Sekcja z paddingiem — kolumna z odstępami. */
67
+ /** Sekcja z paddingiem - kolumna z odstępami. */
68
68
  export declare function KptCardSection({ className, ...rest }: Readonly<ComponentPropsWithRef<'div'>>): import("react").JSX.Element;
69
69
  /** Wiersz chipów/tagów. */
70
70
  export declare function KptCardTags({ className, ...rest }: Readonly<ComponentPropsWithRef<'div'>>): import("react").JSX.Element;
71
- /** Wiersz „ikona + tekst" (ocena, lokalizacja) w przygaszonym kolorze. */
71
+ /** Wiersz "ikona + tekst" (ocena, lokalizacja) w przygaszonym kolorze. */
72
72
  export declare function KptCardMeta({ className, ...rest }: Readonly<ComponentPropsWithRef<'div'>>): import("react").JSX.Element;
73
73
  /** Wiersz przycisków o równych szerokościach. */
74
74
  export declare function KptCardActions({ className, ...rest }: Readonly<ComponentPropsWithRef<'div'>>): import("react").JSX.Element;
package/dist/card/card.js CHANGED
@@ -9,7 +9,7 @@ import { slotChildren } from "../internal/slot-children.js";
9
9
  * (`[kptCardFooter]` poza body) trafia we właściwe węzły.
10
10
  */
11
11
  /**
12
- * Karta Koncept UI — powierzchnia z wyniesieniem (`elevated`) albo obramowaniem (`outlined`).
12
+ * Karta Koncept UI - powierzchnia z wyniesieniem (`elevated`) albo obramowaniem (`outlined`).
13
13
  *
14
14
  * Ciało karty renderuje sama karta; `flush` zdejmuje jego padding. Do bogatych układów
15
15
  * służą komponenty składane: `KptCard.Media`, `.Lead`, `.Title`, `.Subtitle`, `.Section`,
@@ -17,7 +17,7 @@ import { slotChildren } from "../internal/slot-children.js";
17
17
  *
18
18
  * @example
19
19
  * <KptCard header="Ustawienia" variant="outlined">
20
- * <p>Treść…</p>
20
+ * <p>Treść...</p>
21
21
  * <KptCard.Footer><KptButton>Zapisz</KptButton></KptCard.Footer>
22
22
  * </KptCard>
23
23
  */
@@ -39,13 +39,13 @@ export function KptCard({ variant = 'elevated', header, headingLevel, flush = fa
39
39
  function slotOf(child) {
40
40
  return child.type?.kptCardSlot ?? 'body';
41
41
  }
42
- /** Nagłówek karty — alternatywa dla propa `header`, gdy potrzebna jest bogatsza treść. */
42
+ /** Nagłówek karty - alternatywa dla propa `header`, gdy potrzebna jest bogatsza treść. */
43
43
  export function KptCardHeader({ className, ...rest }) {
44
44
  return _jsx("div", { className: cn('kpt-card__header', className), ...rest });
45
45
  }
46
46
  KptCardHeader.kptCardSlot = 'header';
47
47
  /**
48
- * Stopka karty. Nosi atrybut `kptcardfooter` — to po nim celuje wspólny SCSS
48
+ * Stopka karty. Nosi atrybut `kptcardfooter` - to po nim celuje wspólny SCSS
49
49
  * (nazwy atrybutów w selektorach CSS są w HTML case-insensitive, więc ta sama
50
50
  * reguła `[kptCardFooter]` obsługuje oba porty).
51
51
  */
@@ -69,7 +69,7 @@ export function KptCardTitle({ className, ...rest }) {
69
69
  export function KptCardSubtitle({ className, ...rest }) {
70
70
  return _jsx("div", { className: cn('kpt-card__subtitle', className), ...rest });
71
71
  }
72
- /** Sekcja z paddingiem — kolumna z odstępami. */
72
+ /** Sekcja z paddingiem - kolumna z odstępami. */
73
73
  export function KptCardSection({ className, ...rest }) {
74
74
  return _jsx("div", { className: cn('kpt-card__section', className), ...rest });
75
75
  }
@@ -77,7 +77,7 @@ export function KptCardSection({ className, ...rest }) {
77
77
  export function KptCardTags({ className, ...rest }) {
78
78
  return _jsx("div", { className: cn('kpt-card__tags', className), ...rest });
79
79
  }
80
- /** Wiersz „ikona + tekst" (ocena, lokalizacja) w przygaszonym kolorze. */
80
+ /** Wiersz "ikona + tekst" (ocena, lokalizacja) w przygaszonym kolorze. */
81
81
  export function KptCardMeta({ className, ...rest }) {
82
82
  return _jsx("div", { className: cn('kpt-card__meta', className), ...rest });
83
83
  }