@konce-pt/react 0.11.2 → 0.14.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 (382) hide show
  1. package/README.md +128 -64
  2. package/dist/accordion/accordion.d.ts +14 -6
  3. package/dist/accordion/accordion.js +25 -17
  4. package/dist/accordion/llms.txt +22 -10
  5. package/dist/alert/alert.d.ts +2 -2
  6. package/dist/alert/alert.js +3 -2
  7. package/dist/alert/llms.txt +10 -9
  8. package/dist/app-shell/app-shell.d.ts +14 -14
  9. package/dist/app-shell/app-shell.js +22 -15
  10. package/dist/app-shell/llms.txt +16 -15
  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 +24 -15
  14. package/dist/auth/llms.txt +12 -11
  15. package/dist/autocomplete/autocomplete.d.ts +19 -6
  16. package/dist/autocomplete/autocomplete.js +32 -11
  17. package/dist/autocomplete/llms.txt +19 -5
  18. package/dist/avatar/avatar.d.ts +6 -6
  19. package/dist/avatar/avatar.js +6 -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 +4 -3
  23. package/dist/avatar-group/llms.txt +8 -8
  24. package/dist/backdrop/backdrop.d.ts +7 -26
  25. package/dist/backdrop/backdrop.js +32 -27
  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 +8 -3
  31. package/dist/bottom-sheet/bottom-sheet.js +5 -4
  32. package/dist/bottom-sheet/llms.txt +11 -8
  33. package/dist/breadcrumb/breadcrumb.d.ts +8 -2
  34. package/dist/breadcrumb/breadcrumb.js +11 -3
  35. package/dist/breadcrumb/llms.txt +10 -2
  36. package/dist/button/button.d.ts +3 -3
  37. package/dist/button/button.js +10 -9
  38. package/dist/button/llms.txt +27 -19
  39. package/dist/button-group/button-group.d.ts +18 -5
  40. package/dist/button-group/button-group.js +54 -6
  41. package/dist/button-group/llms.txt +27 -18
  42. package/dist/card/card.d.ts +8 -8
  43. package/dist/card/card.js +10 -9
  44. package/dist/card/llms.txt +20 -20
  45. package/dist/carousel/carousel.d.ts +6 -6
  46. package/dist/carousel/carousel.js +8 -5
  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 +2 -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 +4 -3
  53. package/dist/charts/chart.js +18 -10
  54. package/dist/charts/llms.txt +10 -7
  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 +77 -23
  58. package/dist/chat/llms.txt +39 -15
  59. package/dist/chat-composer/chat-composer.d.ts +20 -7
  60. package/dist/chat-composer/chat-composer.js +29 -7
  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 +10 -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 +19 -8
  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 +4 -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 +31 -5
  74. package/dist/checkbox/llms.txt +26 -11
  75. package/dist/chip/chip.d.ts +4 -4
  76. package/dist/chip/chip.js +3 -2
  77. package/dist/chip/llms.txt +11 -11
  78. package/dist/chips-input/chips-input.d.ts +6 -4
  79. package/dist/chips-input/chips-input.js +47 -12
  80. package/dist/chips-input/llms.txt +18 -8
  81. package/dist/clock/clock.d.ts +11 -6
  82. package/dist/clock/clock.js +38 -8
  83. package/dist/clock/llms.txt +12 -8
  84. package/dist/color-picker/color-picker.d.ts +9 -5
  85. package/dist/color-picker/color-picker.js +37 -18
  86. package/dist/color-picker/llms.txt +8 -5
  87. package/dist/confirm/confirm-container.d.ts +3 -3
  88. package/dist/confirm/confirm-container.js +6 -5
  89. package/dist/confirm/confirm-store.d.ts +4 -4
  90. package/dist/confirm/confirm-store.js +11 -5
  91. package/dist/confirm/llms.txt +8 -7
  92. package/dist/context-menu/context-menu.d.ts +1 -1
  93. package/dist/context-menu/context-menu.js +37 -14
  94. package/dist/context-menu/llms.txt +10 -7
  95. package/dist/data-table/data-table-types.d.ts +5 -5
  96. package/dist/data-table/data-table.d.ts +37 -5
  97. package/dist/data-table/data-table.js +426 -119
  98. package/dist/data-table/export-csv.d.ts +3 -3
  99. package/dist/data-table/export-csv.js +8 -10
  100. package/dist/data-table/llms.txt +127 -79
  101. package/dist/data-view/data-view.d.ts +13 -5
  102. package/dist/data-view/data-view.js +68 -6
  103. package/dist/data-view/llms.txt +29 -10
  104. package/dist/date-range/date-range.d.ts +20 -8
  105. package/dist/date-range/date-range.js +86 -63
  106. package/dist/date-range/llms.txt +32 -18
  107. package/dist/datepicker/datepicker.d.ts +22 -8
  108. package/dist/datepicker/datepicker.js +103 -71
  109. package/dist/datepicker/llms.txt +36 -22
  110. package/dist/dialog/dialog.d.ts +4 -4
  111. package/dist/dialog/dialog.js +32 -11
  112. package/dist/dialog/llms.txt +13 -10
  113. package/dist/divider/divider.d.ts +7 -1
  114. package/dist/divider/divider.js +3 -2
  115. package/dist/divider/llms.txt +4 -3
  116. package/dist/drawer/drawer.d.ts +9 -4
  117. package/dist/drawer/drawer.js +5 -4
  118. package/dist/drawer/llms.txt +13 -10
  119. package/dist/empty/empty.d.ts +2 -2
  120. package/dist/empty/empty.js +1 -1
  121. package/dist/empty/llms.txt +9 -9
  122. package/dist/fab/fab.d.ts +1 -1
  123. package/dist/fab/fab.js +1 -1
  124. package/dist/fab/llms.txt +10 -6
  125. package/dist/fieldset/fieldset.d.ts +18 -4
  126. package/dist/fieldset/fieldset.js +12 -6
  127. package/dist/fieldset/llms.txt +26 -9
  128. package/dist/file-upload/file-upload.d.ts +8 -2
  129. package/dist/file-upload/file-upload.js +22 -11
  130. package/dist/file-upload/llms.txt +12 -9
  131. package/dist/form-field/form-field-context.d.ts +4 -4
  132. package/dist/form-field/form-field.d.ts +12 -4
  133. package/dist/form-field/form-field.js +27 -6
  134. package/dist/form-field/llms.txt +25 -11
  135. package/dist/galleria/galleria.d.ts +3 -3
  136. package/dist/galleria/galleria.js +9 -6
  137. package/dist/galleria/llms.txt +7 -7
  138. package/dist/grid/col.d.ts +4 -4
  139. package/dist/grid/col.js +2 -2
  140. package/dist/grid/flex.d.ts +3 -3
  141. package/dist/grid/flex.js +1 -1
  142. package/dist/grid/grid.d.ts +7 -7
  143. package/dist/grid/grid.js +3 -3
  144. package/dist/grid/layout.d.ts +2 -2
  145. package/dist/grid/layout.js +2 -2
  146. package/dist/grid/llms.txt +15 -15
  147. package/dist/grid-entry/public-api.js +1 -1
  148. package/dist/i18n/i18n-context.d.ts +6 -6
  149. package/dist/i18n/i18n-context.js +27 -5
  150. package/dist/icon/icon-registry.d.ts +3 -3
  151. package/dist/icon/icon-registry.js +3 -3
  152. package/dist/icon/icon.d.ts +4 -4
  153. package/dist/icon/icon.js +10 -7
  154. package/dist/icon/llms.txt +13 -13
  155. package/dist/icon-button/icon-button.d.ts +2 -2
  156. package/dist/icon-button/icon-button.js +1 -1
  157. package/dist/icon-button/llms.txt +9 -5
  158. package/dist/icons-entry/public-api.d.ts +2 -2
  159. package/dist/icons-entry/public-api.js +3 -3
  160. package/dist/image/image.js +5 -5
  161. package/dist/image/llms.txt +13 -13
  162. package/dist/input/input.d.ts +18 -5
  163. package/dist/input/input.js +22 -6
  164. package/dist/input/llms.txt +25 -11
  165. package/dist/input-mask/input-mask.d.ts +7 -2
  166. package/dist/input-mask/input-mask.js +17 -43
  167. package/dist/input-mask/llms.txt +8 -5
  168. package/dist/input-number/input-number.d.ts +11 -9
  169. package/dist/input-number/input-number.js +25 -21
  170. package/dist/input-number/llms.txt +17 -14
  171. package/dist/input-otp/input-otp.d.ts +18 -5
  172. package/dist/input-otp/input-otp.js +48 -24
  173. package/dist/input-otp/llms.txt +18 -7
  174. package/dist/internal/calendar-focus.d.ts +1 -1
  175. package/dist/internal/calendar-focus.js +3 -3
  176. package/dist/internal/cn.d.ts +1 -1
  177. package/dist/internal/mask.d.ts +14 -0
  178. package/dist/internal/mask.js +62 -0
  179. package/dist/internal/number-group.d.ts +22 -0
  180. package/dist/internal/number-group.js +53 -0
  181. package/dist/internal/option-key.d.ts +6 -0
  182. package/dist/internal/option-key.js +8 -0
  183. package/dist/internal/option-nav.d.ts +4 -4
  184. package/dist/internal/option-nav.js +5 -5
  185. package/dist/internal/overlay-container.js +1 -1
  186. package/dist/internal/overlay.d.ts +3 -3
  187. package/dist/internal/overlay.js +40 -10
  188. package/dist/internal/password-strength.d.ts +6 -0
  189. package/dist/internal/password-strength.js +74 -0
  190. package/dist/internal/roving.d.ts +2 -2
  191. package/dist/internal/roving.js +3 -3
  192. package/dist/internal/scroll-lock.d.ts +6 -0
  193. package/dist/internal/scroll-lock.js +35 -0
  194. package/dist/internal/slot-children.d.ts +13 -0
  195. package/dist/internal/slot-children.js +31 -0
  196. package/dist/internal/slot.d.ts +3 -3
  197. package/dist/internal/slot.js +2 -2
  198. package/dist/internal/step.d.ts +12 -0
  199. package/dist/internal/step.js +31 -0
  200. package/dist/internal/tween.d.ts +5 -5
  201. package/dist/internal/tween.js +7 -8
  202. package/dist/internal/types.d.ts +2 -2
  203. package/dist/internal/use-breakpoint.d.ts +2 -2
  204. package/dist/internal/use-breakpoint.js +4 -4
  205. package/dist/internal/use-controllable-state.d.ts +5 -0
  206. package/dist/internal/use-controllable-state.js +25 -4
  207. package/dist/internal/use-id.d.ts +2 -2
  208. package/dist/internal/use-id.js +2 -2
  209. package/dist/internal/use-modal-focus.d.ts +2 -1
  210. package/dist/internal/use-modal-focus.js +14 -3
  211. package/dist/knob/knob.d.ts +7 -4
  212. package/dist/knob/knob.js +27 -22
  213. package/dist/knob/llms.txt +18 -11
  214. package/dist/listbox/listbox.d.ts +8 -6
  215. package/dist/listbox/listbox.js +37 -17
  216. package/dist/listbox/llms.txt +12 -9
  217. package/dist/loader/llms.txt +56 -0
  218. package/dist/loader/loader.d.ts +49 -0
  219. package/dist/loader/loader.js +68 -0
  220. package/dist/map/llms.txt +30 -23
  221. package/dist/map/map-create-dialog.d.ts +4 -4
  222. package/dist/map/map-create-dialog.js +36 -28
  223. package/dist/map/map-hours-field.d.ts +4 -4
  224. package/dist/map/map-hours-field.js +8 -7
  225. package/dist/map/map-image-field.d.ts +2 -2
  226. package/dist/map/map-image-field.js +6 -5
  227. package/dist/map/map-legend.d.ts +4 -4
  228. package/dist/map/map-legend.js +3 -2
  229. package/dist/map/map-poi-card.d.ts +3 -3
  230. package/dist/map/map-poi-card.js +10 -9
  231. package/dist/map/map-search.d.ts +17 -6
  232. package/dist/map/map-search.js +70 -43
  233. package/dist/map/map.d.ts +25 -13
  234. package/dist/map/map.js +86 -57
  235. package/dist/map/ports.d.ts +9 -9
  236. package/dist/map/ports.js +6 -6
  237. package/dist/map-entry/public-api.js +2 -2
  238. package/dist/megamenu/llms.txt +18 -7
  239. package/dist/megamenu/megamenu.d.ts +12 -6
  240. package/dist/megamenu/megamenu.js +23 -14
  241. package/dist/mention/llms.txt +15 -15
  242. package/dist/mention/mention.d.ts +5 -5
  243. package/dist/mention/mention.js +2 -2
  244. package/dist/mention/mentions.d.ts +1 -1
  245. package/dist/mention/mentions.js +1 -1
  246. package/dist/menu/llms.txt +12 -12
  247. package/dist/menu/menu-item.d.ts +4 -4
  248. package/dist/menu/menu-keys.d.ts +2 -2
  249. package/dist/menu/menu-keys.js +5 -5
  250. package/dist/menu/menu-rows.js +1 -0
  251. package/dist/menu/menu.d.ts +2 -2
  252. package/dist/menu/menu.js +15 -8
  253. package/dist/menubar/llms.txt +19 -8
  254. package/dist/menubar/menubar.d.ts +11 -5
  255. package/dist/menubar/menubar.js +23 -11
  256. package/dist/meter-group/llms.txt +12 -12
  257. package/dist/meter-group/meter-group.d.ts +2 -2
  258. package/dist/meter-group/meter-group.js +2 -1
  259. package/dist/motion/motion-context.d.ts +22 -0
  260. package/dist/motion/motion-context.js +28 -0
  261. package/dist/order-list/llms.txt +24 -9
  262. package/dist/order-list/order-list.d.ts +12 -4
  263. package/dist/order-list/order-list.js +123 -25
  264. package/dist/paginator/llms.txt +8 -8
  265. package/dist/paginator/paginator.js +7 -4
  266. package/dist/panel/llms.txt +25 -13
  267. package/dist/panel/panel.d.ts +11 -3
  268. package/dist/panel/panel.js +12 -7
  269. package/dist/password/llms.txt +19 -7
  270. package/dist/password/password.d.ts +2 -2
  271. package/dist/password/password.js +27 -16
  272. package/dist/peek/llms.txt +11 -11
  273. package/dist/peek/peek.d.ts +6 -6
  274. package/dist/peek/peek.js +41 -19
  275. package/dist/pick-list/llms.txt +35 -12
  276. package/dist/pick-list/pick-list.d.ts +12 -4
  277. package/dist/pick-list/pick-list.js +128 -24
  278. package/dist/popover/llms.txt +13 -10
  279. package/dist/popover/popover.d.ts +6 -4
  280. package/dist/popover/popover.js +14 -7
  281. package/dist/progress/llms.txt +17 -17
  282. package/dist/progress/progress.d.ts +7 -7
  283. package/dist/progress/progress.js +7 -6
  284. package/dist/public-api.d.ts +16 -4
  285. package/dist/public-api.js +13 -7
  286. package/dist/radio-group/llms.txt +16 -6
  287. package/dist/radio-group/radio-group.d.ts +12 -3
  288. package/dist/radio-group/radio-group.js +23 -4
  289. package/dist/rating/llms.txt +20 -13
  290. package/dist/rating/rating-pointer.d.ts +16 -0
  291. package/dist/rating/rating-pointer.js +26 -0
  292. package/dist/rating/rating.d.ts +6 -6
  293. package/dist/rating/rating.js +77 -12
  294. package/dist/rich-text/lists.d.ts +2 -2
  295. package/dist/rich-text/lists.js +7 -7
  296. package/dist/rich-text/llms.txt +35 -12
  297. package/dist/rich-text/rich-text.d.ts +13 -14
  298. package/dist/rich-text/rich-text.js +311 -142
  299. package/dist/rich-text/sanitize.d.ts +11 -2
  300. package/dist/rich-text/sanitize.js +80 -32
  301. package/dist/rich-text/tables.d.ts +3 -3
  302. package/dist/rich-text/tables.js +3 -3
  303. package/dist/roadmap/llms.txt +23 -17
  304. package/dist/roadmap/roadmap.d.ts +6 -6
  305. package/dist/roadmap/roadmap.js +102 -25
  306. package/dist/roadmap-entry/public-api.js +2 -2
  307. package/dist/scroll-top/llms.txt +6 -6
  308. package/dist/scroll-top/scroll-top.d.ts +1 -1
  309. package/dist/scroll-top/scroll-top.js +2 -1
  310. package/dist/select/llms.txt +22 -12
  311. package/dist/select/select.d.ts +10 -8
  312. package/dist/select/select.js +87 -47
  313. package/dist/shared/types.d.ts +22 -1
  314. package/dist/shared/types.js +9 -1
  315. package/dist/sidenav/llms.txt +9 -9
  316. package/dist/sidenav/sidenav.d.ts +2 -3
  317. package/dist/sidenav/sidenav.js +5 -4
  318. package/dist/skeleton/llms.txt +3 -3
  319. package/dist/skeleton/skeleton.d.ts +1 -1
  320. package/dist/skeleton/skeleton.js +1 -1
  321. package/dist/slider/llms.txt +34 -12
  322. package/dist/slider/slider-drag.d.ts +26 -0
  323. package/dist/slider/slider-drag.js +79 -0
  324. package/dist/slider/slider.d.ts +8 -5
  325. package/dist/slider/slider.js +38 -8
  326. package/dist/speech/llms.txt +97 -0
  327. package/dist/speech/speech-button.d.ts +44 -0
  328. package/dist/speech/speech-button.js +86 -0
  329. package/dist/speech/speech-wave.d.ts +19 -0
  330. package/dist/speech/speech-wave.js +16 -0
  331. package/dist/speech/use-speech-recognition.d.ts +81 -0
  332. package/dist/speech/use-speech-recognition.js +179 -0
  333. package/dist/speed-dial/llms.txt +14 -8
  334. package/dist/speed-dial/speed-dial.d.ts +1 -1
  335. package/dist/speed-dial/speed-dial.js +3 -2
  336. package/dist/spinner/llms.txt +7 -7
  337. package/dist/spinner/spinner.d.ts +1 -1
  338. package/dist/spinner/spinner.js +2 -1
  339. package/dist/split-button/llms.txt +21 -15
  340. package/dist/split-button/split-button.d.ts +2 -2
  341. package/dist/split-button/split-button.js +13 -6
  342. package/dist/splitter/llms.txt +11 -11
  343. package/dist/splitter/splitter.d.ts +3 -3
  344. package/dist/splitter/splitter.js +25 -10
  345. package/dist/stepper/llms.txt +35 -13
  346. package/dist/stepper/stepper.d.ts +6 -6
  347. package/dist/stepper/stepper.js +60 -13
  348. package/dist/switch/llms.txt +15 -5
  349. package/dist/switch/switch.d.ts +10 -3
  350. package/dist/switch/switch.js +18 -4
  351. package/dist/switch-group/llms.txt +11 -8
  352. package/dist/switch-group/switch-group.d.ts +6 -4
  353. package/dist/switch-group/switch-group.js +9 -7
  354. package/dist/tabs/llms.txt +12 -9
  355. package/dist/tabs/tabs.d.ts +5 -5
  356. package/dist/tabs/tabs.js +36 -20
  357. package/dist/textarea/llms.txt +23 -12
  358. package/dist/textarea/textarea.d.ts +19 -6
  359. package/dist/textarea/textarea.js +22 -7
  360. package/dist/timeline/llms.txt +4 -4
  361. package/dist/timeline/timeline.d.ts +1 -1
  362. package/dist/timeline/timeline.js +1 -1
  363. package/dist/toast/llms.txt +50 -17
  364. package/dist/toast/toast-container.d.ts +9 -3
  365. package/dist/toast/toast-container.js +18 -9
  366. package/dist/toast/toast-store.d.ts +42 -2
  367. package/dist/toast/toast-store.js +36 -1
  368. package/dist/toolbar/llms.txt +7 -7
  369. package/dist/toolbar/toolbar.d.ts +3 -3
  370. package/dist/toolbar/toolbar.js +2 -2
  371. package/dist/tooltip/llms.txt +14 -12
  372. package/dist/tooltip/tooltip.d.ts +5 -4
  373. package/dist/tooltip/tooltip.js +100 -41
  374. package/dist/tree/llms.txt +25 -11
  375. package/dist/tree/tree-keys.d.ts +5 -5
  376. package/dist/tree/tree-keys.js +7 -7
  377. package/dist/tree/tree.d.ts +17 -5
  378. package/dist/tree/tree.js +62 -20
  379. package/dist/update/llms.txt +54 -0
  380. package/dist/update/update.d.ts +49 -0
  381. package/dist/update/update.js +82 -0
  382. package/package.json +18 -15
@@ -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,24 +8,37 @@ 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
- /** Wywoływane po wyborze — moment, w którym kontrolka staje się dotknięta. */
11
+ /** Tylko do odczytu - wybór widać, nie da się go zmienić (`aria-readonly`). */
12
+ readOnly?: boolean;
13
+ /** Pole wymagane - `aria-required`. */
14
+ required?: boolean;
15
+ /** Id grupy; bez niego generowane, w `KptFormField` - z wrappera. */
16
+ id?: string;
17
+ /** Nazwa dostępna grupy, gdy nie opisuje jej etykieta (`KptFormField`). */
18
+ ariaLabel?: string | null;
19
+ invalid?: boolean;
20
+ touched?: boolean;
21
+ /** Wywoływane po wyborze - moment, w którym kontrolka staje się dotknięta. */
12
22
  onTouch?: () => void;
13
- /** 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`. */
14
24
  iconOnly?: boolean;
15
25
  /** Propsy wrappera hosta (`.kpt-button-group-host`). */
16
26
  hostProps?: KptHostProps<'span'>;
17
27
  }
18
28
  /**
19
- * Segmentowana grupa przycisków (toggle) — pojedynczy wybór z opcji.
29
+ * Segmentowana grupa przycisków (toggle) - pojedynczy wybór z opcji.
20
30
  *
21
31
  * Działa kontrolowana (`value` + `onValueChange`) i niekontrolowana (`defaultValue`).
22
32
  * Pozycja może mieć ikonę (`KptOption.icon`); `iconOnly` chowa etykietę, ale zostawia ją
23
33
  * w nazwie dostępnej, więc czytnik ekranu dalej wie, co wybiera.
24
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.
37
+ *
25
38
  * @example
26
39
  * <KptButtonGroup value={view} onValueChange={setView}
27
40
  * options={[{ label: 'Lista', value: 'list' }, { label: 'Siatka', value: 'grid' }]} />
28
41
  * <KptButtonGroup value={view} onValueChange={setView} iconOnly
29
42
  * options={[{ icon: 'list', label: 'Lista', value: 'list' }]} />
30
43
  */
31
- export declare function KptButtonGroup<T>({ options, value, defaultValue, onValueChange, size, disabled, onTouch, iconOnly, hostProps, className, ...rest }: Readonly<KptButtonGroupProps<T>>): import("react").JSX.Element;
44
+ export declare function KptButtonGroup<T>({ options, value, defaultValue, onValueChange, size, disabled, readOnly, required, id, ariaLabel, invalid, touched, onTouch, iconOnly, hostProps, className, ...rest }: Readonly<KptButtonGroupProps<T>>): import("react").JSX.Element;
@@ -1,36 +1,84 @@
1
+ 'use client';
1
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";
2
6
  import { cn } from "../internal/cn.js";
3
7
  import { useControllableState } from "../internal/use-controllable-state.js";
4
8
  import { KptIcon } from "../icon/icon.js";
5
9
  import { KptTooltip } from "../tooltip/tooltip.js";
10
+ import { useKptFieldA11y } from "../form-field/form-field-context.js";
11
+ import { nextRovingIndex, rovingStop } from "../internal/roving.js";
6
12
  /**
7
- * Segmentowana grupa przycisków (toggle) — pojedynczy wybór z opcji.
13
+ * Segmentowana grupa przycisków (toggle) - pojedynczy wybór z opcji.
8
14
  *
9
15
  * Działa kontrolowana (`value` + `onValueChange`) i niekontrolowana (`defaultValue`).
10
16
  * Pozycja może mieć ikonę (`KptOption.icon`); `iconOnly` chowa etykietę, ale zostawia ją
11
17
  * w nazwie dostępnej, więc czytnik ekranu dalej wie, co wybiera.
12
18
  *
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.
21
+ *
13
22
  * @example
14
23
  * <KptButtonGroup value={view} onValueChange={setView}
15
24
  * options={[{ label: 'Lista', value: 'list' }, { label: 'Siatka', value: 'grid' }]} />
16
25
  * <KptButtonGroup value={view} onValueChange={setView} iconOnly
17
26
  * options={[{ icon: 'list', label: 'Lista', value: 'list' }]} />
18
27
  */
19
- export function KptButtonGroup({ options = [], value, defaultValue, onValueChange, size = 'md', disabled = false, onTouch, iconOnly = false, hostProps, className, ...rest }) {
28
+ export function KptButtonGroup({ options = [], value, defaultValue, onValueChange, size = 'md', disabled = false, readOnly = false, required = false, id, ariaLabel = null, invalid = false, touched, onTouch, iconOnly = false, hostProps, className, ...rest }) {
20
29
  const { className: hostClassName, ...hostRest } = hostProps ?? {};
21
30
  const [current, setCurrent] = useControllableState({
22
31
  value,
23
32
  defaultValue,
24
33
  onChange: onValueChange,
25
34
  });
26
- const select = (option) => {
27
- if (option.disabled || disabled)
35
+ /** Grupa nie dostaje nazwy z `label[for]` - stąd `aria-labelledby` na etykietę wrappera. */
36
+ const field = useKptFieldA11y(id, 'kpt-button-group');
37
+ const showInvalid = invalid && (touched ?? true);
38
+ const disabledMap = options.map((option) => disabled || !!option.disabled);
39
+ /** Jedyny przystanek Tab: wybrana pozycja, a bez wyboru pierwsza dozwolona. */
40
+ const tabStop = rovingStop(disabledMap, options.findIndex((option) => option.value === current));
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) => {
57
+ if (option.disabled || disabled || readOnly)
28
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 };
29
63
  setCurrent(option.value);
30
64
  onTouch?.();
31
65
  };
32
- return (_jsx("span", { className: cn('kpt-button-group-host', hostClassName), ...hostRest, children: _jsx("div", { className: cn('kpt-button-group', className), role: "group", "data-size": size, "data-icon-only": iconOnly ? '' : undefined, ...rest, children: options.map((option) => {
66
+ /** Strzałki (pion traktowany jak poziom), `Home`/`End`: fokus i wybór idą razem - wzorzec radia. */
67
+ const onKeyDown = (event) => {
68
+ const vertical = { ArrowDown: 'ArrowRight', ArrowUp: 'ArrowLeft' };
69
+ const rtl = getComputedStyle(event.currentTarget).direction === 'rtl';
70
+ let key = vertical[event.key] ?? event.key;
71
+ if (rtl && (key === 'ArrowLeft' || key === 'ArrowRight'))
72
+ key = key === 'ArrowLeft' ? 'ArrowRight' : 'ArrowLeft';
73
+ const next = nextRovingIndex(disabledMap, tabStop, key);
74
+ if (next === null)
75
+ return;
76
+ event.preventDefault();
77
+ event.currentTarget.querySelectorAll('[role="radio"]')[next]?.focus();
78
+ select(options[next], event.currentTarget);
79
+ };
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) => {
33
81
  const active = option.value === current;
34
- return (_jsx(KptTooltip, { text: iconOnly ? option.label : '', children: _jsxs("button", { type: "button", className: cn('kpt-button-group__item', active && 'is-active'), disabled: disabled || option.disabled, "aria-pressed": 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 })] }) }, 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)));
35
83
  }) }) }));
36
84
  }
@@ -1,47 +1,47 @@
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
- <div class="kpt-button-group" role="group" data-size="md">
9
- <button type="button" class="kpt-button-group__item is-active" aria-pressed="true">
10
- <span class="kpt-button-group__icon kpt-icon-host">…</span>
8
+ <div class="kpt-button-group" role="radiogroup" data-size="md">
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>
11
11
  <span class="kpt-button-group__label">List</span>
12
12
  </button>
13
- <button type="button" class="kpt-button-group__item" aria-pressed="false">
13
+ <button type="button" role="radio" class="kpt-button-group__item" aria-checked="false" tabindex="-1">
14
14
  <span class="kpt-button-group__label">Grid</span>
15
15
  </button>
16
16
  </div>
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,11 +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="group"` of native buttons, each with `aria-pressed` — a screen reader announces which
64
- segment is on, and the keyboard walks them like any other buttons. With `iconOnly` the name comes
65
- from `aria-label`, so the announcement does not degrade to a bare "button".
69
+ A `role="radiogroup"` of native buttons with `role="radio"` and `aria-checked` - a screen reader
70
+ announces which segment is on and "2 of 3"; one Tab stop, arrows move the choice. With `iconOnly`
71
+ the name comes from `aria-label`, so the announcement does not degrade to a bare "radio button".
72
+
73
+ ## Read-only and required
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
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Children, isValidElement } from 'react';
2
+ import { isValidElement } from 'react';
3
3
  import { cn } from "../internal/cn.js";
4
+ import { slotChildren } from "../internal/slot-children.js";
4
5
  /*
5
6
  * Karta odtwarza projekcję treści z Angulara: nagłówek i stopka są wyjmowane
6
7
  * z dzieci i renderowane poza `.kpt-card__body`, dokładnie tam, gdzie stawia je
@@ -8,7 +9,7 @@ import { cn } from "../internal/cn.js";
8
9
  * (`[kptCardFooter]` poza body) trafia we właściwe węzły.
9
10
  */
10
11
  /**
11
- * Karta Koncept UI — powierzchnia z wyniesieniem (`elevated`) albo obramowaniem (`outlined`).
12
+ * Karta Koncept UI - powierzchnia z wyniesieniem (`elevated`) albo obramowaniem (`outlined`).
12
13
  *
13
14
  * Ciało karty renderuje sama karta; `flush` zdejmuje jego padding. Do bogatych układów
14
15
  * służą komponenty składane: `KptCard.Media`, `.Lead`, `.Title`, `.Subtitle`, `.Section`,
@@ -16,7 +17,7 @@ import { cn } from "../internal/cn.js";
16
17
  *
17
18
  * @example
18
19
  * <KptCard header="Ustawienia" variant="outlined">
19
- * <p>Treść…</p>
20
+ * <p>Treść...</p>
20
21
  * <KptCard.Footer><KptButton>Zapisz</KptButton></KptCard.Footer>
21
22
  * </KptCard>
22
23
  */
@@ -24,7 +25,7 @@ export function KptCard({ variant = 'elevated', header, headingLevel, flush = fa
24
25
  const headers = [];
25
26
  const footers = [];
26
27
  const body = [];
27
- Children.forEach(children, (child) => {
28
+ for (const child of slotChildren(children)) {
28
29
  const bucket = isValidElement(child) ? slotOf(child) : 'body';
29
30
  if (bucket === 'header')
30
31
  headers.push(child);
@@ -32,19 +33,19 @@ export function KptCard({ variant = 'elevated', header, headingLevel, flush = fa
32
33
  footers.push(child);
33
34
  else
34
35
  body.push(child);
35
- });
36
+ }
36
37
  return (_jsxs("div", { className: cn('kpt-card', className), "data-variant": variant, ...rest, children: [header ? (_jsx("div", { className: "kpt-card__header", role: headingLevel ? 'heading' : undefined, "aria-level": headingLevel, children: header })) : null, headers, _jsx("div", { className: cn('kpt-card__body', flush && 'kpt-card__body--flush'), children: body }), footers] }));
37
38
  }
38
39
  function slotOf(child) {
39
40
  return child.type?.kptCardSlot ?? 'body';
40
41
  }
41
- /** 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ść. */
42
43
  export function KptCardHeader({ className, ...rest }) {
43
44
  return _jsx("div", { className: cn('kpt-card__header', className), ...rest });
44
45
  }
45
46
  KptCardHeader.kptCardSlot = 'header';
46
47
  /**
47
- * 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
48
49
  * (nazwy atrybutów w selektorach CSS są w HTML case-insensitive, więc ta sama
49
50
  * reguła `[kptCardFooter]` obsługuje oba porty).
50
51
  */
@@ -68,7 +69,7 @@ export function KptCardTitle({ className, ...rest }) {
68
69
  export function KptCardSubtitle({ className, ...rest }) {
69
70
  return _jsx("div", { className: cn('kpt-card__subtitle', className), ...rest });
70
71
  }
71
- /** Sekcja z paddingiem — kolumna z odstępami. */
72
+ /** Sekcja z paddingiem - kolumna z odstępami. */
72
73
  export function KptCardSection({ className, ...rest }) {
73
74
  return _jsx("div", { className: cn('kpt-card__section', className), ...rest });
74
75
  }
@@ -76,7 +77,7 @@ export function KptCardSection({ className, ...rest }) {
76
77
  export function KptCardTags({ className, ...rest }) {
77
78
  return _jsx("div", { className: cn('kpt-card__tags', className), ...rest });
78
79
  }
79
- /** Wiersz „ikona + tekst" (ocena, lokalizacja) w przygaszonym kolorze. */
80
+ /** Wiersz "ikona + tekst" (ocena, lokalizacja) w przygaszonym kolorze. */
80
81
  export function KptCardMeta({ className, ...rest }) {
81
82
  return _jsx("div", { className: cn('kpt-card__meta', className), ...rest });
82
83
  }
@@ -1,43 +1,43 @@
1
1
  # KptCard (@konce-pt/react)
2
2
 
3
- A card — a surface with elevation (`elevated`) or a border (`outlined`). The card renders its own
3
+ A card - a surface with elevation (`elevated`) or a border (`outlined`). The card renders its own
4
4
  body; the header and the footer are lifted out of the children and placed outside that body,
5
5
  exactly where the Angular template puts them, so the DOM tree matches node for node.
6
6
  Import: `import { KptCard } from '@konce-pt/react';`
7
7
 
8
8
  ## DOM
9
9
  <div class="kpt-card" data-variant="elevated">
10
- <div class="kpt-card__header">…</div>
11
- <div class="kpt-card__body">…</div>
12
- <div kptcardfooter="">…</div>
10
+ <div class="kpt-card__header">...</div>
11
+ <div class="kpt-card__body">...</div>
12
+ <div kptcardfooter="">...</div>
13
13
  </div>
14
14
 
15
15
  ## Props
16
16
  - `variant`: 'elevated' | 'outlined' (default 'elevated')
17
- - `header`: string — optional header text; use `<KptCard.Header>` for richer content
18
- - `headingLevel`: 1–6 — makes `header` a heading of that level (`role="heading"` + `aria-level`)
19
- - `headingLevel`: 1–6 — makes `header` a heading of that level (`role="heading"` + `aria-level`)
20
- - `flush`: boolean — a body with no padding (for rich layouts that manage their own sections)
17
+ - `header`: string - optional header text; use `<KptCard.Header>` for richer content
18
+ - `headingLevel`: 1-6 - makes `header` a heading of that level (`role="heading"` + `aria-level`)
19
+ - `headingLevel`: 1-6 - makes `header` a heading of that level (`role="heading"` + `aria-level`)
20
+ - `flush`: boolean - a body with no padding (for rich layouts that manage their own sections)
21
21
  - `className`, `ref` and every other `<div>` prop go to the card root
22
22
 
23
23
  ## Sub-components
24
- - `KptCard.Header` — lifted above the body, `.kpt-card__header`
25
- - `KptCard.Footer` — lifted below the body; carries the `kptcardfooter` attribute the shared
24
+ - `KptCard.Header` - lifted above the body, `.kpt-card__header`
25
+ - `KptCard.Footer` - lifted below the body; carries the `kptcardfooter` attribute the shared
26
26
  SCSS targets (attribute names in CSS selectors are case-insensitive in HTML, so one rule
27
27
  serves both ports)
28
- - `KptCard.Media` — an `<img>` on the full width, clipped to the radius; set `aspect-ratio`/`height`
29
- - `KptCard.Lead` — the header row (avatar + titles), with padding
30
- - `KptCard.Title`, `KptCard.Subtitle` — title/subtitle typography
31
- - `KptCard.Section` — a padded section (a column with gaps)
32
- - `KptCard.Tags` — a row of chips; `KptCard.Meta` — an icon+text row (rating/location)
33
- - `KptCard.Actions` — a row of buttons (equal widths)
28
+ - `KptCard.Media` - an `<img>` on the full width, clipped to the radius; set `aspect-ratio`/`height`
29
+ - `KptCard.Lead` - the header row (avatar + titles), with padding
30
+ - `KptCard.Title`, `KptCard.Subtitle` - title/subtitle typography
31
+ - `KptCard.Section` - a padded section (a column with gaps)
32
+ - `KptCard.Tags` - a row of chips; `KptCard.Meta` - an icon+text row (rating/location)
33
+ - `KptCard.Actions` - a row of buttons (equal widths)
34
34
 
35
35
  There is no `KptCard.Body`: the body belongs to the card itself, and `flush` removes its padding.
36
36
  An overlapping avatar is a class you apply to your own element: `className="kpt-card__avatar"`.
37
37
 
38
38
  ## Examples
39
39
  <KptCard header="Settings" variant="outlined">
40
- <p>Content…</p>
40
+ <p>Content...</p>
41
41
  <KptCard.Footer><KptButton>Save</KptButton></KptCard.Footer>
42
42
  </KptCard>
43
43
 
@@ -50,7 +50,7 @@ An overlapping avatar is a class you apply to your own element: `className="kpt-
50
50
  </div>
51
51
  </KptCard.Lead>
52
52
  <KptCard.Media src="/photo.jpg" style={{ aspectRatio: '4 / 3' }} />
53
- <KptCard.Section>Description…</KptCard.Section>
53
+ <KptCard.Section>Description...</KptCard.Section>
54
54
  <KptCard.Footer><KptButton variant="text" size="sm">LIKE</KptButton></KptCard.Footer>
55
55
  </KptCard>
56
56
 
@@ -58,7 +58,7 @@ An overlapping avatar is a class you apply to your own element: `className="kpt-
58
58
  `--kpt-card-{bg,fg,border,radius,padding,shadow}`.
59
59
 
60
60
  ## Accessibility
61
- The card is a plain container with no role of its own. `header` is styled text by default — set
62
- `headingLevel` (1–6) to make it a heading (`role="heading"` + `aria-level`) when the card should
61
+ The card is a plain container with no role of its own. `header` is styled text by default - set
62
+ `headingLevel` (1-6) to make it a heading (`role="heading"` + `aria-level`) when the card should
63
63
  appear in the page outline; leave it off for tiles that would only clutter it. Give media images a
64
64
  meaningful `alt`, or `alt=""` when decorative.
@@ -5,20 +5,20 @@ export interface KptCarouselProps<T> extends Omit<ComponentPropsWithRef<'div'>,
5
5
  activeIndex?: number;
6
6
  defaultActiveIndex?: number;
7
7
  onActiveIndexChange?: (index: number) => void;
8
- /** Szablon slajdu — odpowiednik `<ng-template let-item let-i="index">` z Angulara. */
8
+ /** Szablon slajdu - odpowiednik `<ng-template let-item let-i="index">` z Angulara. */
9
9
  renderSlide: (item: T, index: number) => ReactNode;
10
- /** Nazwa regionu dla czytników ekranu, np. „Nowości”; domyślnie `carousel.label`. */
10
+ /** Nazwa regionu dla czytników ekranu, np. "Nowości"; domyślnie `carousel.label`. */
11
11
  label?: string;
12
12
  }
13
13
  /**
14
14
  * Karuzela slajdów. Dane przez `items`, wygląd slajdu przez `renderSlide`.
15
15
  *
16
16
  * Tor przesuwa się jednym `translateX` o wielokrotność 100%, więc slajdy jadą płynnie, a każdy
17
- * zostaje zamontowany — przewijanie nie gubi stanu treści.
17
+ * zostaje zamontowany - przewijanie nie gubi stanu treści.
18
18
  *
19
- * Semantyka według wzorca WAI-ARIA „carousel” (bez autoodtwarzania): region z
20
- * `aria-roledescription="karuzela"`, każdy slajd to grupa „Slajd 2 z 4”, a slajdy poza widokiem są
21
- * `inert` — `Tab` i czytnik ich nie widzą. Zmiana slajdu jest ogłaszana uprzejmie (`aria-live`
19
+ * Semantyka według wzorca WAI-ARIA "carousel" (bez autoodtwarzania): region z
20
+ * `aria-roledescription="karuzela"`, każdy slajd to grupa "Slajd 2 z 4", a slajdy poza widokiem są
21
+ * `inert` - `Tab` i czytnik ich nie widzą. Zmiana slajdu jest ogłaszana uprzejmie (`aria-live`
22
22
  * na torze). Strzałki na końcach dostają `aria-disabled` zamiast `disabled`, żeby nie zgubić fokusu.
23
23
  *
24
24
  * @example
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
3
  import { cn } from "../internal/cn.js";
3
4
  import { useControllableState } from "../internal/use-controllable-state.js";
@@ -7,11 +8,11 @@ import { KptIcon } from "../icon/icon.js";
7
8
  * Karuzela slajdów. Dane przez `items`, wygląd slajdu przez `renderSlide`.
8
9
  *
9
10
  * Tor przesuwa się jednym `translateX` o wielokrotność 100%, więc slajdy jadą płynnie, a każdy
10
- * zostaje zamontowany — przewijanie nie gubi stanu treści.
11
+ * zostaje zamontowany - przewijanie nie gubi stanu treści.
11
12
  *
12
- * Semantyka według wzorca WAI-ARIA „carousel” (bez autoodtwarzania): region z
13
- * `aria-roledescription="karuzela"`, każdy slajd to grupa „Slajd 2 z 4”, a slajdy poza widokiem są
14
- * `inert` — `Tab` i czytnik ich nie widzą. Zmiana slajdu jest ogłaszana uprzejmie (`aria-live`
13
+ * Semantyka według wzorca WAI-ARIA "carousel" (bez autoodtwarzania): region z
14
+ * `aria-roledescription="karuzela"`, każdy slajd to grupa "Slajd 2 z 4", a slajdy poza widokiem są
15
+ * `inert` - `Tab` i czytnik ich nie widzą. Zmiana slajdu jest ogłaszana uprzejmie (`aria-live`
15
16
  * na torze). Strzałki na końcach dostają `aria-disabled` zamiast `disabled`, żeby nie zgubić fokusu.
16
17
  *
17
18
  * @example
@@ -19,11 +20,13 @@ import { KptIcon } from "../icon/icon.js";
19
20
  */
20
21
  export function KptCarousel({ items = [], activeIndex, defaultActiveIndex = 0, onActiveIndexChange, renderSlide, label, locale, dictionary, className, ...rest }) {
21
22
  const { t } = useKptMessages({ locale, dictionary });
22
- const [active, setActive] = useControllableState({
23
+ const [requested, setActive] = useControllableState({
23
24
  value: activeIndex,
24
25
  defaultValue: defaultActiveIndex,
25
26
  onChange: onActiveIndexChange,
26
27
  });
28
+ // Indeks przycięty do listy: po skróceniu `items` (filtr) widok nie zostaje pusty.
29
+ const active = Math.min(Math.max(requested, 0), Math.max(items.length - 1, 0));
27
30
  const goTo = (index) => setActive(Math.min(Math.max(index, 0), items.length - 1));
28
31
  const atStart = active <= 0;
29
32
  const atEnd = active >= items.length - 1;
@@ -10,15 +10,15 @@ Import: `import { KptCarousel } from '@konce-pt/react';`
10
10
  <div class="kpt-carousel__track" aria-live="polite"
11
11
  style="transform:translateX(calc(var(--_kpt-carousel-dir, 1) * -100%))">
12
12
  <div class="kpt-carousel__slide" role="group" aria-roledescription="slide"
13
- aria-label="Slide 1 of 3" inert aria-hidden="true">…</div>
13
+ aria-label="Slide 1 of 3" inert aria-hidden="true">...</div>
14
14
  <div class="kpt-carousel__slide" role="group" aria-roledescription="slide"
15
- aria-label="Slide 2 of 3">…</div>…
15
+ aria-label="Slide 2 of 3">...</div>...
16
16
  </div>
17
17
  </div>
18
- <button class="kpt-carousel__nav kpt-carousel__nav--prev" aria-label="Previous">…</button>
19
- <button class="kpt-carousel__nav kpt-carousel__nav--next" aria-label="Next">…</button>
18
+ <button class="kpt-carousel__nav kpt-carousel__nav--prev" aria-label="Previous">...</button>
19
+ <button class="kpt-carousel__nav kpt-carousel__nav--next" aria-label="Next">...</button>
20
20
  <div class="kpt-carousel__dots">
21
- <button class="kpt-carousel__dot is-active" aria-current="true" aria-label="Slide 2"></button>…
21
+ <button class="kpt-carousel__dot is-active" aria-current="true" aria-label="Slide 2"></button>...
22
22
  </div>
23
23
  </div>
24
24
  </div>
@@ -26,8 +26,8 @@ Import: `import { KptCarousel } from '@konce-pt/react';`
26
26
  ## Props
27
27
  - `items`: `T[]`
28
28
  - `activeIndex` / `defaultActiveIndex` / `onActiveIndexChange`
29
- - `renderSlide(item, index)` — required
30
- - `label`: string — the region name; empty = `carousel.label`
29
+ - `renderSlide(item, index)` - required
30
+ - `label`: string - the region name; empty = `carousel.label`
31
31
  - `className`, `ref` and every other `<div>` prop go to the host
32
32
 
33
33
  ## The render prop replaces the template
@@ -36,7 +36,7 @@ carousel owns the layout and the navigation, the caller owns what a slide looks
36
36
  guessed about the item's shape, so the component stays generic in `T`.
37
37
 
38
38
  ## One transform, every slide mounted
39
- The track slides with a single `translateX` of a multiple of 100%, so every slide stays mounted —
39
+ The track slides with a single `translateX` of a multiple of 100%, so every slide stays mounted -
40
40
  paging does not lose state inside a slide (a form, a playing video, a scroll position).
41
41
 
42
42
  ## Examples
@@ -51,9 +51,9 @@ The active dot `--kpt-color-primary`; the arrows `--kpt-color-surface` (80% via
51
51
 
52
52
  ## Accessibility
53
53
  The WAI-ARIA carousel pattern without autoplay. The root is `role="region"` with
54
- `aria-roledescription` from `carousel.roleCarousel` (“carousel”) and a name from `label` or
54
+ `aria-roledescription` from `carousel.roleCarousel` ("carousel") and a name from `label` or
55
55
  `carousel.label`. Each slide is `role="group"` with `aria-roledescription` from `carousel.roleSlide`
56
- and a name from `carousel.slideOf` (“Slide 2 of 4”); slides outside the view are `inert` and
56
+ and a name from `carousel.slideOf` ("Slide 2 of 4"); slides outside the view are `inert` and
57
57
  `aria-hidden`, so Tab never lands on an invisible link. The track is `aria-live="polite"`, so the
58
58
  slide that comes in is announced. The arrows use `aria-disabled` at the ends instead of `disabled`,
59
59
  so they keep the focus; the active dot carries `aria-current`, and every dot has a 24 px target
@@ -11,13 +11,13 @@ export interface KptChartLegendProps {
11
11
  align?: KptAlign;
12
12
  pointStyle?: KptPointStyle;
13
13
  title?: KptLegendTitle;
14
- /** Kliknięcie elementu — przełącz widoczność serii albo wycinka. */
14
+ /** Kliknięcie elementu - przełącz widoczność serii albo wycinka. */
15
15
  onToggle?: (key: string) => void;
16
- /** Wejście i wyjście kursora — podświetl serię albo wyczyść podświetlenie. */
16
+ /** Wejście i wyjście kursora - podświetl serię albo wyczyść podświetlenie. */
17
17
  onHighlight?: (key: string | null) => void;
18
18
  }
19
19
  /**
20
- * Legenda wykresu — klikalne elementy, podświetlanie pod kursorem, pozycja, wyrównanie i styl
20
+ * Legenda wykresu - klikalne elementy, podświetlanie pod kursorem, pozycja, wyrównanie i styl
21
21
  * punktu. Element wewnętrzny biblioteki, nie część publicznego API.
22
22
  */
23
23
  export declare function KptChartLegend({ items, position, align, pointStyle, title, onToggle, onHighlight, }: Readonly<KptChartLegendProps>): import("react").JSX.Element;
@@ -1,7 +1,8 @@
1
+ 'use client';
1
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
3
  import { cn } from "../internal/cn.js";
3
4
  /**
4
- * Legenda wykresu — klikalne elementy, podświetlanie pod kursorem, pozycja, wyrównanie i styl
5
+ * Legenda wykresu - klikalne elementy, podświetlanie pod kursorem, pozycja, wyrównanie i styl
5
6
  * punktu. Element wewnętrzny biblioteki, nie część publicznego API.
6
7
  */
7
8
  export function KptChartLegend({ items = [], position = 'bottom', align = 'center', pointStyle = 'circle', title, onToggle, onHighlight, }) {
@@ -4,9 +4,9 @@ export interface KptChartTooltipRow {
4
4
  color: string;
5
5
  }
6
6
  export interface KptChartTooltipState {
7
- /** Pozycja pozioma w % szerokości kontenera (0–100). */
7
+ /** Pozycja pozioma w % szerokości kontenera (0-100). */
8
8
  x: number;
9
- /** Pozycja pionowa w % wysokości kontenera (0–100). */
9
+ /** Pozycja pionowa w % wysokości kontenera (0-100). */
10
10
  y: number;
11
11
  label: string;
12
12
  rows: KptChartTooltipRow[];
@@ -15,7 +15,7 @@ export interface KptChartTooltipProps {
15
15
  state: KptChartTooltipState | null;
16
16
  }
17
17
  /**
18
- * Dymek wykresu — pozycjonowany procentowo względem kontenera, niezależnie od skali SVG, więc
18
+ * Dymek wykresu - pozycjonowany procentowo względem kontenera, niezależnie od skali SVG, więc
19
19
  * nie trzeba przeliczać jednostek viewBoxa na piksele. Element wewnętrzny biblioteki.
20
20
  */
21
21
  export declare function KptChartTooltip({ state }: Readonly<KptChartTooltipProps>): import("react").JSX.Element | null;
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { cn } from "../internal/cn.js";
3
3
  /**
4
- * Dymek wykresu — pozycjonowany procentowo względem kontenera, niezależnie od skali SVG, więc
4
+ * Dymek wykresu - pozycjonowany procentowo względem kontenera, niezależnie od skali SVG, więc
5
5
  * nie trzeba przeliczać jednostek viewBoxa na piksele. Element wewnętrzny biblioteki.
6
6
  */
7
7
  export function KptChartTooltip({ state }) {