@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
@@ -1,14 +1,16 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { createContext, isValidElement, useContext, useState, } from 'react';
3
+ import { createContext, isValidElement, useContext, useLayoutEffect, useRef, useState, } from 'react';
4
4
  import { cn } from "../internal/cn.js";
5
5
  import { slotChildren, warnUnslottedChild } from "../internal/slot-children.js";
6
6
  import { useControllableState } from "../internal/use-controllable-state.js";
7
7
  import { useKptMessages } from "../i18n/i18n-context.js";
8
8
  import { KptIcon } from "../icon/icon.js";
9
+ import { playStepperLight, preparePanelSwap, resolveEnterMotion, stepperSchedule, stepperScheduleOptions } from '@konce-pt/motion';
10
+ import { useKptMotion } from "../motion/motion-context.js";
9
11
  const StepperContext = createContext(null);
10
12
  /**
11
- * Sterowanie kreatorem z wnętrza kroku — odpowiednik `#s` + `s.next()` z portu Angulara.
13
+ * Sterowanie kreatorem z wnętrza kroku - odpowiednik `#s` + `s.next()` z portu Angulara.
12
14
  * Poza `<KptStepper>` rzuca błąd, bo bez kreatora nie ma czym sterować.
13
15
  *
14
16
  * @example
@@ -21,7 +23,7 @@ export function useKptStepper() {
21
23
  return context;
22
24
  }
23
25
  /**
24
- * Pojedynczy krok. Umieszczaj w `<KptStepper>`. Treść renderuje się leniwie — dopiero gdy krok
26
+ * Pojedynczy krok. Umieszczaj w `<KptStepper>`. Treść renderuje się leniwie - dopiero gdy krok
25
27
  * jest aktywny, tak samo jak szablon `kpt-step` w porcie Angulara.
26
28
  */
27
29
  export function KptStep(_props) {
@@ -30,13 +32,13 @@ export function KptStep(_props) {
30
32
  }
31
33
  KptStep.kptStepperSlot = 'step';
32
34
  /**
33
- * Kreator kroków — nagłówek z numerowanymi krokami i treść aktywnego kroku.
35
+ * Kreator kroków - nagłówek z numerowanymi krokami i treść aktywnego kroku.
34
36
  * Treścią sterują `next()`/`prev()`/`goTo()` z hooka `useKptStepper()`.
35
37
  *
36
38
  * @example
37
39
  * <KptStepper>
38
- * <KptStepper.Step label="Konto">…</KptStepper.Step>
39
- * <KptStepper.Step label="Profil">…</KptStepper.Step>
40
+ * <KptStepper.Step label="Konto">...</KptStepper.Step>
41
+ * <KptStepper.Step label="Profil">...</KptStepper.Step>
40
42
  * </KptStepper>
41
43
  */
42
44
  export function KptStepper({ activeIndex, defaultActiveIndex = 0, onActiveIndexChange, animated = true, animationDuration = 500, locale, dictionary, className, style, children, ...rest }) {
@@ -47,6 +49,18 @@ export function KptStepper({ activeIndex, defaultActiveIndex = 0, onActiveIndexC
47
49
  onChange: onActiveIndexChange,
48
50
  });
49
51
  const [direction, setDirection] = useState(1);
52
+ /** Ruch przełączania idzie za `animated` i za `enter` z `KptMotionProvider` (`none` go wyłącza). */
53
+ const motionConfig = useKptMotion();
54
+ const motion = animated ? resolveEnterMotion(undefined, motionConfig) : 'none';
55
+ // Krok sprzed ostatniej zmiany - także przy zmianie z zewnątrz (`activeIndex`). Zapamiętany
56
+ // w stanie w trakcie renderu (wzorzec "informacja z poprzedniego renderu"), nie w efekcie.
57
+ const [transition, setTransition] = useState({ from: active, to: active });
58
+ if (transition.to !== active)
59
+ setTransition({ from: transition.to, to: active });
60
+ const rootRef = useRef(null);
61
+ const bodyRef = useRef(null);
62
+ /** Duch starej treści przygotowany przed zmianą kroku, odtwarzany po jej wyrenderowaniu. */
63
+ const pendingSwap = useRef(null);
50
64
  const steps = [];
51
65
  for (const child of slotChildren(children)) {
52
66
  if (!isValidElement(child) || child.type?.kptStepperSlot !== 'step') {
@@ -55,10 +69,36 @@ export function KptStepper({ activeIndex, defaultActiveIndex = 0, onActiveIndexC
55
69
  }
56
70
  steps.push(child.props);
57
71
  }
72
+ /**
73
+ * Kiedy widać zmianę każdego znacznika i odcinka linii (`stepperSchedule` z @konce-pt/motion):
74
+ * kolor płynie po linii i zapala znacznik dopiero, gdy do niego dotrze. Bez ruchu - same zera.
75
+ */
76
+ // Tempo linii idzie za `animationDuration` - ten sam czas steruje całym ruchem, nie tylko treścią.
77
+ const schedule = stepperSchedule(steps.length, motion === 'none' ? active : transition.from, active, stepperScheduleOptions(animationDuration));
78
+ // Kometa po linii i fala w znaczniku, do którego dociera kolor; duch starej treści - przed malowaniem.
79
+ useLayoutEffect(() => {
80
+ const play = pendingSwap.current;
81
+ pendingSwap.current = null;
82
+ play?.();
83
+ });
84
+ useLayoutEffect(() => {
85
+ const root = rootRef.current;
86
+ if (!root || motion !== 'spring' || !schedule.direction)
87
+ return;
88
+ playStepperLight(schedule, root.querySelector('.kpt-stepper__comet'), Array.from(root.querySelectorAll('.kpt-stepper__connector')), Array.from(root.querySelectorAll('.kpt-stepper__marker')));
89
+ // Harmonogram liczy się z `transition` - gra raz na zmianę kroku, nie na każdy render.
90
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- schedule to pochodna transition i liczby kroków
91
+ }, [transition, motion]);
58
92
  const goTo = (index) => {
59
93
  const next = Math.max(0, Math.min(index, steps.length - 1));
94
+ if (next === active)
95
+ return;
60
96
  // Kierunek karmi `--kpt-anim-dir`, więc panel wjeżdża z tej strony, z której się cofnąłeś.
61
- setDirection(next >= active ? 1 : -1);
97
+ const dir = next > active ? 1 : -1;
98
+ setDirection(dir);
99
+ // Stara treść wychodzi jako duch, a pojemnik płynnie zmienia wysokość - mierzone przed zmianą.
100
+ if (motion !== 'none' && bodyRef.current)
101
+ pendingSwap.current = preparePanelSwap(bodyRef.current, dir);
62
102
  setActive(next);
63
103
  };
64
104
  const context = {
@@ -68,13 +108,16 @@ export function KptStepper({ activeIndex, defaultActiveIndex = 0, onActiveIndexC
68
108
  prev: () => goTo(active - 1),
69
109
  goTo,
70
110
  };
71
- return (_jsxs("div", { className: cn('kpt-stepper-host', className), style: {
111
+ return (_jsxs("div", { ref: rootRef, className: cn('kpt-stepper-host', className), style: {
72
112
  ['--kpt-anim-duration']: `${animated ? animationDuration : 0}ms`,
73
113
  ['--kpt-anim-dir']: direction,
74
114
  ...style,
75
- }, ...rest, children: [_jsx("ol", { className: "kpt-stepper__header", children: steps.map((step, index) => (_jsxs("li", { className: cn('kpt-stepper__step', index === active && 'is-active', index < active && 'is-done'), children: [_jsx("button", { type: "button", className: "kpt-stepper__marker", "aria-current": index === active ? 'step' : undefined, "aria-label": t(index < active ? 'stepper.stepDone' : 'stepper.step', {
115
+ }, ...rest, children: [_jsx("ol", { className: "kpt-stepper__header", children: steps.map((step, index) => (_jsxs("li", { className: cn('kpt-stepper__step', index === active && 'is-active', index < active && 'is-done'), style: { ['--kpt-stepper-mark-delay']: `${schedule.markers[index] ?? 0}ms` }, children: [_jsxs("button", { type: "button", className: "kpt-stepper__marker", "aria-current": index === active ? 'step' : undefined, "aria-label": t(index < active ? 'stepper.stepDone' : 'stepper.step', {
76
116
  index: index + 1,
77
117
  label: step.label,
78
- }), onClick: () => goTo(index), children: index < active ? _jsx(KptIcon, { name: "check" }) : index + 1 }), _jsx("span", { className: "kpt-stepper__label", "aria-hidden": "true", children: step.label }), index < steps.length - 1 ? _jsx("span", { className: "kpt-stepper__connector" }) : null] }, index))) }), _jsx(StepperContext.Provider, { value: context, children: _jsx("div", { className: "kpt-stepper__body", children: steps[active] ? (_jsx("div", { className: "kpt-stepper__panel", children: steps[active].children }, active)) : null }) })] }));
118
+ }), onClick: () => goTo(index), children: [_jsx("span", { className: "kpt-stepper__num", children: index + 1 }), _jsx(KptIcon, { className: "kpt-stepper__check", name: "check" })] }), _jsx("span", { className: "kpt-stepper__label", "aria-hidden": "true", children: step.label }), index < steps.length - 1 ? (_jsx("span", { className: "kpt-stepper__connector", style: {
119
+ ['--kpt-stepper-line-delay']: `${schedule.lines[index]?.delay ?? 0}ms`,
120
+ ['--kpt-stepper-line-dur']: `${schedule.lines[index]?.duration ?? 0}ms`,
121
+ } })) : null] }, index))) }), _jsx("span", { className: "kpt-stepper__comet", "aria-hidden": "true" }), _jsx(StepperContext.Provider, { value: context, children: _jsx("div", { className: "kpt-stepper__body", ref: bodyRef, children: steps[active] ? (_jsx("div", { className: "kpt-stepper__panel", children: steps[active].children }, active)) : null }) })] }));
79
122
  }
80
123
  KptStepper.Step = KptStep;
@@ -16,16 +16,17 @@ Import: `import { KptSwitch } from '@konce-pt/react';`
16
16
 
17
17
  ## Props
18
18
  - `label`: string, `labelPosition`: 'start' | 'end' (default 'end')
19
- - `onLabel`, `offLabel`: string — the state text, swapped on toggle
19
+ - `onLabel`, `offLabel`: string - the state text, swapped on toggle
20
20
  - `checked` / `defaultChecked`, `onCheckedChange(checked)`, `onTouch()`
21
- - `required`, `invalid`, `touched` — as in `KptCheckbox`
22
- - `hostProps` — props for the `.kpt-switch-host` wrapper
21
+ - `required`, `invalid`, `touched` - as in `KptCheckbox`
22
+ - `toggleMotion`: 'spring' | 'fade' | 'none' (default from `KptMotionProvider`, else `spring`) - see "Toggle motion"
23
+ - `hostProps` - props for the `.kpt-switch-host` wrapper
23
24
  - `className` goes to the `.kpt-switch` block; the rest to the native `<input>`
24
25
 
25
26
  ## The state text needs a controlled value
26
27
  `onLabel` and `offLabel` read `checked`, so they only follow the switch in controlled mode.
27
28
  Uncontrolled, the value belongs to the DOM and React never learns about a toggle, which would
28
- freeze the state text on its initial value — use `checked` with `onCheckedChange` whenever you
29
+ freeze the state text on its initial value - use `checked` with `onCheckedChange` whenever you
29
30
  show one.
30
31
 
31
32
  ## Examples
@@ -43,12 +44,18 @@ generated. Inside `KptFormField` the wrapper's `label[for]` points at it and the
43
44
  added to `aria-describedby` (merged with your own). Without a wrapper, name it with `aria-label`.
44
45
  Inside `kpt-form-field` the switch gets both names: the wrapper label and its own `label`.
45
46
 
47
+ ## Toggle motion
48
+ `toggleMotion`: `spring` - the thumb travels on a spring and stretches while moving; `fade` - a calm colour and mark transition; `none` - no
49
+ motion. The bounce is started by the change handler, so a control that is checked on load does not
50
+ move. With no value it takes `toggle` from `KptMotionProvider` (default `spring`); `enabled: false` and the
51
+ system "reduce motion" setting always win.
52
+
46
53
  ## Tokens
47
54
  `--kpt-color-primary` (the on track), `--kpt-color-muted` (the off track), `--kpt-color-surface`
48
55
  (the thumb), `--kpt-motion-duration-fast`.
49
56
 
50
57
  ## Accessibility
51
- `role="switch"` on a native checkbox — a screen reader announces on/off instead of
58
+ `role="switch"` on a native checkbox - a screen reader announces on/off instead of
52
59
  checked/unchecked. The track and the thumb are `aria-hidden`.
53
60
 
54
61
  ## Read-only and required
@@ -1,6 +1,13 @@
1
1
  import { type ComponentPropsWithRef, type ReactNode } from 'react';
2
2
  import type { KptHostProps } from '../internal/types.ts';
3
+ import { type KptToggleMotion } from '@konce-pt/motion';
3
4
  export interface KptSwitchProps extends Omit<ComponentPropsWithRef<'input'>, 'type' | 'required'> {
5
+ /**
6
+ * Ruch przełączania: `spring` - kciuk jedzie na sprężynie i rozciąga się w ruchu; `fade` - spokojne przejście koloru i znaku; `none` - bez ruchu.
7
+ * Bez wartości bierze `toggle` z `KptMotionProvider` (domyślnie `spring`); `enabled={false}` i systemowe
8
+ * "ogranicz ruch" wyłączają go zawsze.
9
+ */
10
+ toggleMotion?: KptToggleMotion;
4
11
  /** Etykieta obok przełącznika. */
5
12
  label?: string;
6
13
  /** Pozycja etykiety względem przełącznika. */
@@ -15,7 +22,7 @@ export interface KptSwitchProps extends Omit<ComponentPropsWithRef<'input'>, 'ty
15
22
  invalid?: boolean;
16
23
  /** Czy pole było dotknięte; pominięty = stan błędu pokazuje się od razu po `invalid`. */
17
24
  touched?: boolean;
18
- /** Wygodniejszy odpowiednik `onChange` — dostaje samo zaznaczenie. */
25
+ /** Wygodniejszy odpowiednik `onChange` - dostaje samo zaznaczenie. */
19
26
  onCheckedChange?: (checked: boolean) => void;
20
27
  /** Wywoływane na `blur`. */
21
28
  onTouch?: () => void;
@@ -27,7 +34,7 @@ export interface KptSwitchProps extends Omit<ComponentPropsWithRef<'input'>, 'ty
27
34
  * Przełącznik (switch/toggle). Pod spodem natywny `<input type="checkbox" role="switch">`,
28
35
  * więc klawiatura i czytniki ekranu działają bez dodatkowej obsługi.
29
36
  *
30
- * Wariant z tekstem stanu: `onLabel`/`offLabel` — wyświetlany tekst zmienia się przy przełączaniu.
37
+ * Wariant z tekstem stanu: `onLabel`/`offLabel` - wyświetlany tekst zmienia się przy przełączaniu.
31
38
  *
32
39
  * Tekst stanu wymaga `checked` (tryb kontrolowany), bo w trybie niekontrolowanym wartość należy
33
40
  * do DOM i React o niej nie wie; bez tego etykieta stanu zamarłaby na wartości początkowej.
@@ -36,4 +43,4 @@ export interface KptSwitchProps extends Omit<ComponentPropsWithRef<'input'>, 'ty
36
43
  * <KptSwitch name="notifications" label="Powiadomienia" />
37
44
  * <KptSwitch checked={on} onCheckedChange={setOn} onLabel="Włączony" offLabel="Wyłączony" />
38
45
  */
39
- export declare function KptSwitch({ label, labelPosition, onLabel, offLabel, required, invalid, touched, onCheckedChange, onTouch, hostProps, className, disabled, readOnly, onClick, checked, onChange, onBlur, children, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, id, ...rest }: Readonly<KptSwitchProps>): import("react").JSX.Element;
46
+ export declare function KptSwitch({ label, labelPosition, onLabel, offLabel, required, invalid, touched, onCheckedChange, onTouch, hostProps, className, disabled, readOnly, onClick, checked, onChange, onBlur, children, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, id, toggleMotion, ...rest }: Readonly<KptSwitchProps>): import("react").JSX.Element;
@@ -3,11 +3,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useCallback } from 'react';
4
4
  import { cn } from "../internal/cn.js";
5
5
  import { joinIds, useKptFieldA11y } from "../form-field/form-field-context.js";
6
+ import { playPopMotion, resolveToggleMotion } from '@konce-pt/motion';
7
+ import { useKptMotion } from "../motion/motion-context.js";
6
8
  /**
7
9
  * Przełącznik (switch/toggle). Pod spodem natywny `<input type="checkbox" role="switch">`,
8
10
  * więc klawiatura i czytniki ekranu działają bez dodatkowej obsługi.
9
11
  *
10
- * Wariant z tekstem stanu: `onLabel`/`offLabel` — wyświetlany tekst zmienia się przy przełączaniu.
12
+ * Wariant z tekstem stanu: `onLabel`/`offLabel` - wyświetlany tekst zmienia się przy przełączaniu.
11
13
  *
12
14
  * Tekst stanu wymaga `checked` (tryb kontrolowany), bo w trybie niekontrolowanym wartość należy
13
15
  * do DOM i React o niej nie wie; bez tego etykieta stanu zamarłaby na wartości początkowej.
@@ -16,21 +18,26 @@ import { joinIds, useKptFieldA11y } from "../form-field/form-field-context.js";
16
18
  * <KptSwitch name="notifications" label="Powiadomienia" />
17
19
  * <KptSwitch checked={on} onCheckedChange={setOn} onLabel="Włączony" offLabel="Wyłączony" />
18
20
  */
19
- export function KptSwitch({ label = '', labelPosition = 'end', onLabel = '', offLabel = '', required = false, invalid = false, touched, onCheckedChange, onTouch, hostProps, className, disabled = false, readOnly = false, onClick, checked, onChange, onBlur, children, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, id, ...rest }) {
21
+ export function KptSwitch({ label = '', labelPosition = 'end', onLabel = '', offLabel = '', required = false, invalid = false, touched, onCheckedChange, onTouch, hostProps, className, disabled = false, readOnly = false, onClick, checked, onChange, onBlur, children, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, id, toggleMotion, ...rest }) {
20
22
  const field = useKptFieldA11y(id, 'kpt-switch');
21
23
  const { className: hostClassName, ...hostRest } = hostProps ?? {};
22
24
  const showInvalid = invalid && (touched ?? true);
23
25
  const hasStateLabels = !!(onLabel || offLabel);
26
+ const motion = resolveToggleMotion(toggleMotion, useKptMotion());
24
27
  const handleChange = useCallback((event) => {
25
28
  onChange?.(event);
26
29
  onCheckedChange?.(event.target.checked);
27
- }, [onChange, onCheckedChange]);
30
+ // Kciuk rozciąga się w ruchu - z handlera, nie z CSS, bo reguła na `:checked` grałaby przy starcie.
31
+ const thumb = event.currentTarget.nextElementSibling?.firstElementChild;
32
+ if (motion === 'spring' && thumb instanceof HTMLElement)
33
+ playPopMotion(thumb, 'squash');
34
+ }, [onChange, onCheckedChange, motion]);
28
35
  const handleBlur = useCallback((event) => {
29
36
  onBlur?.(event);
30
37
  onTouch?.();
31
38
  }, [onBlur, onTouch]);
32
- return (_jsx("span", { className: cn('kpt-switch-host', hostClassName), ...hostRest, children: _jsxs("label", { className: cn('kpt-switch', disabled && 'kpt-switch--disabled', className), children: [label && labelPosition === 'start' ? (_jsx("span", { className: "kpt-switch__label kpt-switch__label--start", children: label })) : null, _jsx("input", { type: "checkbox", role: "switch", className: "kpt-switch__input", id: field.id, "aria-describedby": joinIds(ariaDescribedBy, field.describedBy), checked: checked, disabled: disabled, "aria-required": required || undefined, "aria-readonly": readOnly || undefined,
33
- // Natywne `readonly` nie działa na polach wyboru — klik (i Spacja) jest blokowany ręcznie.
39
+ return (_jsx("span", { className: cn('kpt-switch-host', hostClassName), ...hostRest, children: _jsxs("label", { className: cn('kpt-switch', disabled && 'kpt-switch--disabled', className), "data-motion": motion, children: [label && labelPosition === 'start' ? (_jsx("span", { className: "kpt-switch__label kpt-switch__label--start", children: label })) : null, _jsx("input", { type: "checkbox", role: "switch", className: "kpt-switch__input", id: field.id, "aria-describedby": joinIds(ariaDescribedBy, field.describedBy), checked: checked, disabled: disabled, "aria-required": required || undefined, "aria-readonly": readOnly || undefined,
40
+ // Natywne `readonly` nie działa na polach wyboru - klik (i Spacja) jest blokowany ręcznie.
34
41
  onClick: (event) => {
35
42
  if (readOnly)
36
43
  event.preventDefault();
@@ -1,30 +1,30 @@
1
1
  # KptSwitchGroup (@konce-pt/react)
2
2
 
3
- A group of switches — mutually exclusive by default, multi-select with `multiple`.
3
+ A group of switches - mutually exclusive by default, multi-select with `multiple`.
4
4
  Import: `import { KptSwitchGroup } from '@konce-pt/react';`
5
5
 
6
6
  ## DOM
7
7
  <div class="kpt-switch-group-host">
8
8
  <div class="kpt-switch-group" role="group">
9
- <span class="kpt-switch-host kpt-switch-group__item">…KptSwitch…</span>
10
- …one per option…
9
+ <span class="kpt-switch-host kpt-switch-group__item">...KptSwitch...</span>
10
+ ...one per option...
11
11
  </div>
12
12
  </div>
13
13
 
14
14
  ## Props
15
- - `options`: `KptOption<T>[]` — `{ label, value, disabled? }`
16
- - `value` / `defaultValue` / `onValueChange` — single select: the option's value or `null`;
15
+ - `options`: `KptOption<T>[]` - `{ label, value, disabled? }`
16
+ - `value` / `defaultValue` / `onValueChange` - single select: the option's value or `null`;
17
17
  with `multiple`: an array of the selected values
18
18
  - `multiple`: boolean (default false)
19
19
  - `orientation`: `'vertical'` (default) | `'horizontal'`
20
- - `allowDeselect`: boolean (default true) — single select only; in `multiple` mode turning an
20
+ - `allowDeselect`: boolean (default true) - single select only; in `multiple` mode turning an
21
21
  option off is always allowed
22
22
  - `disabled`, `invalid`, `touched`, `onTouch()`
23
23
  - `className`, `ref` and every other `<div>` prop go to the host
24
24
 
25
25
  ## Single select comes out of the value, not out of the switches
26
26
  Every entry is a `KptSwitch` whose `checked` is derived from the group value, so turning one on
27
- turns the rest off by itself — there is no per-switch state to keep in sync.
27
+ turns the rest off by itself - there is no per-switch state to keep in sync.
28
28
 
29
29
  That is also why `allowDeselect={false}` needs no code: the handler writes nothing, so React
30
30
  re-applies the controlled `checked` and the switch snaps back on.
@@ -37,7 +37,7 @@ re-applies the controlled `checked` and the switch snaps back on.
37
37
  ## Screen reader and keyboard
38
38
  `aria-invalid` is not supported on `role="group"`, so the error state is carried by each switch. In
39
39
  single mode the switches are mutually exclusive and nothing announces that turning one on turned
40
- another off — for a single choice prefer `KptRadioGroup`.
40
+ another off - for a single choice prefer `KptRadioGroup`.
41
41
 
42
42
  ## Label and description
43
43
  `id` goes to the focusable element, not the host; without one it comes from `KptFormField` or is
@@ -54,4 +54,4 @@ Layout only: `--kpt-space-2` (vertical gap) and `--kpt-space-4` (horizontal). Th
54
54
  checkbox of `KptSwitch`, so keyboard and screen readers work with no extra handling.
55
55
 
56
56
  ## Read-only and required
57
- `readOnly` is passed to every switch. With `allowDeselect=false` turning the active switch off puts it back on — before, the switch looked off while the group value said it was on.
57
+ `readOnly` is passed to every switch. With `allowDeselect=false` turning the active switch off puts it back on - before, the switch looked off while the group value said it was on.
@@ -6,24 +6,24 @@ export interface KptSwitchGroupProps<T> extends Omit<ComponentPropsWithRef<'div'
6
6
  value?: T | T[] | null;
7
7
  defaultValue?: T | T[] | null;
8
8
  onValueChange?: (value: T | T[] | null) => void;
9
- /** Wielokrotny wybór — wartością staje się tablica `T[]`. */
9
+ /** Wielokrotny wybór - wartością staje się tablica `T[]`. */
10
10
  multiple?: boolean;
11
11
  orientation?: 'vertical' | 'horizontal';
12
12
  /** Czy wyłączenie aktywnej opcji zeruje wartość. Dotyczy tylko trybu pojedynczego. */
13
13
  allowDeselect?: boolean;
14
- /** Id elementu fokusowalnego (nie hosta); bez niego generowane, w `KptFormField` — z wrappera. */
14
+ /** Id elementu fokusowalnego (nie hosta); bez niego generowane, w `KptFormField` - z wrappera. */
15
15
  id?: string;
16
16
  /** Nazwa dostępna, gdy kontrolki nie opisuje etykieta (`<label for>` albo `KptFormField`). */
17
17
  ariaLabel?: string | null;
18
18
  disabled?: boolean;
19
- /** Tylko do odczytu — przełączniki widać, nie da się ich zmienić. */
19
+ /** Tylko do odczytu - przełączniki widać, nie da się ich zmienić. */
20
20
  readOnly?: boolean;
21
21
  invalid?: boolean;
22
22
  touched?: boolean;
23
23
  onTouch?: () => void;
24
24
  }
25
25
  /**
26
- * Grupa przełączników. Domyślnie wzajemnie wykluczających się — włączenie jednego wyłącza
26
+ * Grupa przełączników. Domyślnie wzajemnie wykluczających się - włączenie jednego wyłącza
27
27
  * pozostałe; z `multiple` wartością jest tablica zaznaczonych opcji.
28
28
  *
29
29
  * Renderuje `KptSwitch`, więc dziedziczy jego wygląd, tokeny i obsługę klawiatury.
@@ -6,7 +6,7 @@ import { useControllableState } from "../internal/use-controllable-state.js";
6
6
  import { KptSwitch } from "../switch/switch.js";
7
7
  import { useKptFieldA11y } from "../form-field/form-field-context.js";
8
8
  /**
9
- * Grupa przełączników. Domyślnie wzajemnie wykluczających się — włączenie jednego wyłącza
9
+ * Grupa przełączników. Domyślnie wzajemnie wykluczających się - włączenie jednego wyłącza
10
10
  * pozostałe; z `multiple` wartością jest tablica zaznaczonych opcji.
11
11
  *
12
12
  * Renderuje `KptSwitch`, więc dziedziczy jego wygląd, tokeny i obsługę klawiatury.
@@ -16,7 +16,7 @@ import { useKptFieldA11y } from "../form-field/form-field-context.js";
16
16
  * <KptSwitchGroup multiple options={tags} value={selected} onValueChange={setSelected} />
17
17
  */
18
18
  export function KptSwitchGroup({ options = [], value, defaultValue = null, onValueChange, multiple = false, orientation = 'vertical', allowDeselect = true, id, ariaLabel = null, disabled = false, readOnly = false, invalid = false, touched, onTouch, className, ...rest }) {
19
- /** Grupa nie dostaje nazwy z `label[for]` — stąd `aria-labelledby` na etykietę wrappera. */
19
+ /** Grupa nie dostaje nazwy z `label[for]` - stąd `aria-labelledby` na etykietę wrappera. */
20
20
  const field = useKptFieldA11y(id, 'kpt-switch-group');
21
21
  const [current, setCurrent] = useControllableState({
22
22
  value,
@@ -24,7 +24,7 @@ export function KptSwitchGroup({ options = [], value, defaultValue = null, onVal
24
24
  onChange: onValueChange,
25
25
  });
26
26
  const showInvalid = invalid && (touched ?? true);
27
- // Wartość normalizujemy do tablicy tylko na potrzeby odczytu w trybie multiple —
27
+ // Wartość normalizujemy do tablicy tylko na potrzeby odczytu w trybie multiple -
28
28
  // `null` i wartość pojedyncza są równie poprawnym wejściem.
29
29
  const selected = Array.isArray(current) ? current : current == null ? [] : [current];
30
30
  const isChecked = (optionValue) => multiple ? selected.includes(optionValue) : optionValue === current;
@@ -49,6 +49,6 @@ export function KptSwitchGroup({ options = [], value, defaultValue = null, onVal
49
49
  // zmieniła, więc przełącznik sam wraca do włączonego przy najbliższym renderze.
50
50
  };
51
51
  return (_jsx("div", { className: cn('kpt-switch-group-host', className), ...rest, children: _jsx("div", { className: cn('kpt-switch-group', orientation === 'horizontal' && 'kpt-switch-group--horizontal'), role: "group", id: field.id, "aria-label": ariaLabel ?? undefined, "aria-labelledby": ariaLabel ? undefined : field.labelledBy, "aria-describedby": field.describedBy, children: options.map((option, index) => (_jsx(KptSwitch, { hostProps: { className: 'kpt-switch-group__item' }, checked: isChecked(option.value), label: option.label, disabled: disabled || option.disabled, readOnly: readOnly,
52
- // `aria-invalid` nie działa na `role="group"` — stan błędu niesie każdy przełącznik.
52
+ // `aria-invalid` nie działa na `role="group"` - stan błędu niesie każdy przełącznik.
53
53
  invalid: showInvalid, onCheckedChange: (checked) => toggle(option, checked), onTouch: onTouch }, optionKey(option.value, index)))) }) }));
54
54
  }
@@ -1,6 +1,6 @@
1
1
  # KptTabs (@konce-pt/react)
2
2
 
3
- Tabs — switching views, with the content rendered lazily.
3
+ Tabs - switching views, with the content rendered lazily.
4
4
  Import: `import { KptTabs } from '@konce-pt/react';`
5
5
 
6
6
  ## DOM
@@ -14,33 +14,33 @@ Import: `import { KptTabs } from '@konce-pt/react';`
14
14
  </div>
15
15
  <div class="kpt-tabs__body" role="tabpanel" tabindex="0" id="kpt-tabs-r1-panel"
16
16
  aria-labelledby="kpt-tabs-r1-tab-0">
17
- <div class="kpt-tabs__panel">…active tab content…</div>
17
+ <div class="kpt-tabs__panel">...active tab content...</div>
18
18
  </div>
19
19
  </div>
20
20
 
21
21
  ## Props
22
- - `activeIndex` / `defaultActiveIndex` / `onActiveIndexChange` — controlled or uncontrolled
22
+ - `activeIndex` / `defaultActiveIndex` / `onActiveIndexChange` - controlled or uncontrolled
23
23
  - `animated`: boolean (default true), `animationDuration`: number (ms, default 500)
24
- - `children` — `<KptTabs.Tab>` elements
24
+ - `children` - `<KptTabs.Tab>` elements
25
25
 
26
26
  ## KptTabs.Tab
27
- `label` (required), `disabled`, `children`. The tab component never renders itself — `KptTabs`
27
+ `label` (required), `disabled`, `children`. The tab component never renders itself - `KptTabs`
28
28
  reads its props and decides what to show, exactly as the Angular version reads the `kpt-tab`
29
29
  template. Only the active tab's content is in the DOM.
30
30
 
31
31
  ## The underline is measured, not computed
32
32
  `__ink` takes its width and offset from the active button in the DOM, not from the index: tabs have
33
33
  different widths and the labels change with the language. The measurement runs after every render,
34
- and the state is only replaced when the numbers actually change — otherwise each measurement would
34
+ and the state is only replaced when the numbers actually change - otherwise each measurement would
35
35
  schedule another render and the component would loop.
36
36
 
37
37
  ## Examples
38
38
  <KptTabs>
39
- <KptTabs.Tab label="General">…</KptTabs.Tab>
40
- <KptTabs.Tab label="Advanced">…</KptTabs.Tab>
39
+ <KptTabs.Tab label="General">...</KptTabs.Tab>
40
+ <KptTabs.Tab label="Advanced">...</KptTabs.Tab>
41
41
  </KptTabs>
42
42
 
43
- <KptTabs activeIndex={tab} onActiveIndexChange={setTab} animated={false}>…</KptTabs>
43
+ <KptTabs activeIndex={tab} onActiveIndexChange={setTab} animated={false}>...</KptTabs>
44
44
 
45
45
  ## Tokens
46
46
  `--kpt-color-primary` (the active tab and the ink), `--kpt-color-on-surface-muted`,
@@ -54,4 +54,4 @@ move between tabs, wrapping at the ends, `Home`/`End` jump to the first/last one
54
54
  are skipped. Moving activates the tab straight away; the next `Tab` goes to the panel.
55
55
 
56
56
  ## Inactive content is destroyed
57
- Switching renders the new panel from scratch (that is what the enter animation starts from), so local state inside the previous one — an unsent file upload, expanded sections, scroll position — is lost. Keep such state in your own model, outside the panel.
57
+ Switching renders the new panel from scratch (that is what the enter animation starts from), so local state inside the previous one - an unsent file upload, expanded sections, scroll position - is lost. Keep such state in your own model, outside the panel.
@@ -5,7 +5,7 @@ export interface KptTabProps {
5
5
  children?: ReactNode;
6
6
  }
7
7
  /**
8
- * Pojedyncza zakładka. Umieszczaj w `<KptTabs>`. Treść renderuje się leniwie — dopiero gdy
8
+ * Pojedyncza zakładka. Umieszczaj w `<KptTabs>`. Treść renderuje się leniwie - dopiero gdy
9
9
  * zakładka jest aktywna, tak samo jak szablon `kpt-tab` w porcie Angulara.
10
10
  */
11
11
  export declare function KptTab(_props: Readonly<KptTabProps>): ReactNode;
@@ -21,9 +21,9 @@ export interface KptTabsProps extends Omit<ComponentPropsWithRef<'div'>, 'onChan
21
21
  children?: ReactNode;
22
22
  }
23
23
  /**
24
- * Zakładki — przełączanie widoków, treść renderowana leniwie.
24
+ * Zakładki - przełączanie widoków, treść renderowana leniwie.
25
25
  *
26
- * Klawiatura według wzorca WAI-ARIA „tabs”: rząd zakładek to jeden przystanek Tab, strzałki
26
+ * Klawiatura według wzorca WAI-ARIA "tabs": rząd zakładek to jeden przystanek Tab, strzałki
27
27
  * w lewo/prawo oraz `Home`/`End` przechodzą po zakładkach (z pominięciem wyłączonych) i od razu je
28
28
  * aktywują, a kolejny `Tab` prowadzi do panelu.
29
29
  *
@@ -32,8 +32,8 @@ export interface KptTabsProps extends Omit<ComponentPropsWithRef<'div'>, 'onChan
32
32
  *
33
33
  * @example
34
34
  * <KptTabs>
35
- * <KptTabs.Tab label="Ogólne">…</KptTabs.Tab>
36
- * <KptTabs.Tab label="Zaawansowane">…</KptTabs.Tab>
35
+ * <KptTabs.Tab label="Ogólne">...</KptTabs.Tab>
36
+ * <KptTabs.Tab label="Zaawansowane">...</KptTabs.Tab>
37
37
  * </KptTabs>
38
38
  */
39
39
  export declare function KptTabs({ activeIndex, defaultActiveIndex, onActiveIndexChange, animated, animationDuration, className, style, children, ...rest }: Readonly<KptTabsProps>): import("react").JSX.Element;
package/dist/tabs/tabs.js CHANGED
@@ -7,7 +7,7 @@ import { nextRovingIndex, rovingStop } from "../internal/roving.js";
7
7
  import { useControllableState } from "../internal/use-controllable-state.js";
8
8
  import { useKptId } from "../internal/use-id.js";
9
9
  /**
10
- * Pojedyncza zakładka. Umieszczaj w `<KptTabs>`. Treść renderuje się leniwie — dopiero gdy
10
+ * Pojedyncza zakładka. Umieszczaj w `<KptTabs>`. Treść renderuje się leniwie - dopiero gdy
11
11
  * zakładka jest aktywna, tak samo jak szablon `kpt-tab` w porcie Angulara.
12
12
  */
13
13
  export function KptTab(_props) {
@@ -17,9 +17,9 @@ export function KptTab(_props) {
17
17
  }
18
18
  KptTab.kptTabsSlot = 'tab';
19
19
  /**
20
- * Zakładki — przełączanie widoków, treść renderowana leniwie.
20
+ * Zakładki - przełączanie widoków, treść renderowana leniwie.
21
21
  *
22
- * Klawiatura według wzorca WAI-ARIA „tabs”: rząd zakładek to jeden przystanek Tab, strzałki
22
+ * Klawiatura według wzorca WAI-ARIA "tabs": rząd zakładek to jeden przystanek Tab, strzałki
23
23
  * w lewo/prawo oraz `Home`/`End` przechodzą po zakładkach (z pominięciem wyłączonych) i od razu je
24
24
  * aktywują, a kolejny `Tab` prowadzi do panelu.
25
25
  *
@@ -28,8 +28,8 @@ KptTab.kptTabsSlot = 'tab';
28
28
  *
29
29
  * @example
30
30
  * <KptTabs>
31
- * <KptTabs.Tab label="Ogólne">…</KptTabs.Tab>
32
- * <KptTabs.Tab label="Zaawansowane">…</KptTabs.Tab>
31
+ * <KptTabs.Tab label="Ogólne">...</KptTabs.Tab>
32
+ * <KptTabs.Tab label="Zaawansowane">...</KptTabs.Tab>
33
33
  * </KptTabs>
34
34
  */
35
35
  export function KptTabs({ activeIndex, defaultActiveIndex = 0, onActiveIndexChange, animated = true, animationDuration = 500, className, style, children, ...rest }) {
@@ -55,7 +55,7 @@ export function KptTabs({ activeIndex, defaultActiveIndex = 0, onActiveIndexChan
55
55
  }
56
56
  const disabled = tabs.map((tab) => !!tab.disabled);
57
57
  /**
58
- * Zakładka pokazywana i jedyna w kolejności Tab: aktywna, a gdy ta jest wyłączona — pierwsza
58
+ * Zakładka pokazywana i jedyna w kolejności Tab: aktywna, a gdy ta jest wyłączona - pierwsza
59
59
  * dostępna. Wyłączona zakładka nie może wyglądać na wybraną (ani mieć swojego panelu).
60
60
  */
61
61
  const shown = rovingStop(disabled, active);
@@ -65,12 +65,12 @@ export function KptTabs({ activeIndex, defaultActiveIndex = 0, onActiveIndexChan
65
65
  return;
66
66
  const next = { x: button.offsetLeft, w: button.offsetWidth };
67
67
  // Pomiar biegnie po KAŻDYM renderze (etykiety zmieniają się z językiem, a przycisków nie da
68
- // się zmierzyć przed montażem). Bez porównania `setInk` wywoływałby kolejny render w kółko —
68
+ // się zmierzyć przed montażem). Bez porównania `setInk` wywoływałby kolejny render w kółko -
69
69
  // React przerywa aktualizację dopiero wtedy, gdy dostanie ten sam obiekt stanu.
70
70
  setInk((prev) => (prev.x === next.x && prev.w === next.w ? prev : next));
71
71
  }, [shown]);
72
72
  useLayoutEffect(measureInk);
73
- // Szerokość paska zakładek zmienia się też bez zmiany okna (panel boczny, splitter) — mierzymy
73
+ // Szerokość paska zakładek zmienia się też bez zmiany okna (panel boczny, splitter) - mierzymy
74
74
  // kontener, a `resize` okna zostaje tylko tam, gdzie nie ma ResizeObservera.
75
75
  const headerRef = useRef(null);
76
76
  useLayoutEffect(() => {
@@ -9,42 +9,53 @@ A multi-line field, with optional auto-resize. It renders a native `<textarea>`
9
9
  </span>
10
10
 
11
11
  ## Props
12
- - `autoResize`: boolean — matches the height to the content on every change
13
- - `rows`: number (default 3) — the starting height
14
- - `value` / `defaultValue` — controlled or uncontrolled, like a native textarea
15
- - `onValueChange(value)`, `onTouch()` — the value alone, and the blur moment
16
- - `required`: boolean — set as `aria-required`, not as the native attribute
17
- - `invalid`, `touched` — the error state, gated the same way as in `KptInput`
18
- - `hostProps` — props for the wrapper
12
+ - `autoResize`: boolean - matches the height to the content on every change
13
+ - `rows`: number (default 3) - the starting height
14
+ - `value` / `defaultValue` - controlled or uncontrolled, like a native textarea
15
+ - `onValueChange(value)`, `onTouch()` - the value alone, and the blur moment
16
+ - `required`: boolean - set as `aria-required`, not as the native attribute
17
+ - `invalid`, `touched` - the error state, gated the same way as in `KptInput`
18
+ - `hostProps` - props for the wrapper
19
19
  - `className`, `ref`, `name`, `placeholder` and every other `<textarea>` prop go to the textarea
20
20
 
21
21
  ## Auto-resize
22
22
  The height is read straight from the DOM (`scrollHeight`), so it is right for a controlled field, an
23
23
  uncontrolled one, and a prefilled initial value alike. The measurement resets the height to `auto`
24
- first — without that a field can only ever grow, since `scrollHeight` never drops below the current
24
+ first - without that a field can only ever grow, since `scrollHeight` never drops below the current
25
25
  height.
26
26
 
27
27
  ## Examples
28
- <KptTextarea name="notes" placeholder="Notes…" autoResize />
28
+ <KptTextarea name="notes" placeholder="Notes..." autoResize />
29
29
  <KptTextarea value={note} onValueChange={setNote} rows={6} />
30
30
  <KptFormField label="Notes" error={err}>
31
31
  <KptTextarea invalid={!!err} onTouch={markTouched} />
32
32
  </KptFormField>
33
33
 
34
34
  ## Screen reader and keyboard
35
- `counter`: boolean — a "12 / 280" counter under the field (requires the native `maxLength`), read
35
+ `counter`: boolean - a "12 / 280" counter under the field (requires the native `maxLength`), read
36
36
  together with it through `aria-describedby`.
37
37
 
38
38
  ## Label and description
39
39
  `id` goes to the native field, not the host; without one it comes from `KptFormField` or is
40
40
  generated. Inside `KptFormField` the wrapper's `label[for]` points at it and the hint or error is
41
41
  added to `aria-describedby` (merged with your own). Without a wrapper, name it with `aria-label`.
42
- New: `id`, `ariaLabel` and `required` (→ `aria-required`); `[formField]` binds `required`.
42
+ New: `id`, `ariaLabel` and `required` (-> `aria-required`); `[formField]` binds `required`.
43
43
 
44
44
  ## Tokens
45
- `--kpt-form-field-{bg,text,placeholder,border,border-hover,border-focus,border-error,radius}` —
45
+ `--kpt-form-field-{bg,text,placeholder,border,border-hover,border-focus,border-error,radius}` -
46
46
  the same set as the text field, so both controls stay in step.
47
47
 
48
48
  ## Accessibility
49
49
  A native `<textarea>`. Inside `KptFormField` it takes its `id` from the wrapper, so `label[for]`
50
50
  is wired with no configuration.
51
+
52
+ ## Dictation
53
+ - `speech`: boolean = false - a microphone in the top corner of the field (the bottom corner belongs
54
+ to the resize handle); the wave appears under it. The field then sits in `.kpt-textarea__box`.
55
+ Without browser support it is not shown.
56
+ - `speechLang`: string; `speechMode`: `'insert' | 'append' | 'replace'` = `'insert'`.
57
+ - `speechColor`: `'primary' | 'danger' | 'success' | 'warning' | 'info'` = `'primary'` - colour of "stop" and the wave while listening.
58
+
59
+ Interim words are visible but never reach your state; `autoResize` follows the dictated text.
60
+
61
+ <KptTextarea value={notes} onValueChange={setNotes} speech autoResize />