@konce-pt/react 0.12.0 → 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 (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 +4 -4
  111. package/dist/dialog/dialog.js +4 -4
  112. package/dist/dialog/llms.txt +11 -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,17 +1,32 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useEffect, useRef, useState } from 'react';
3
+ import { useEffect, useEffectEvent, useId, useLayoutEffect, useRef, useState, } from 'react';
4
+ import { flushSync } from 'react-dom';
5
+ import { isVisibleInScroller, layoutMotionAllowed, morphKeyed, playKeyedMotion, resolveLayoutMotion, revealInScroller, snapshotKeyed, stopKeyedMotion, } from '@konce-pt/motion';
4
6
  import { cn } from "../internal/cn.js";
5
7
  import { composeRefs } from "../internal/compose-refs.js";
6
8
  import { useControllableState } from "../internal/use-controllable-state.js";
7
9
  import { useKptMessages } from "../i18n/i18n-context.js";
8
10
  import { KptIcon } from "../icon/icon.js";
9
11
  import { nextMenuIndex } from "../menu/menu-keys.js";
12
+ import { useKptMotion } from "../motion/motion-context.js";
10
13
  const EMPTY = [];
14
+ /** Klasy ruchu przenoszenia - reguły we wspólnym CSS komponentu. */
15
+ const MOTION_CLASSES = {
16
+ ghostClass: 'kpt-pick-list__ghost',
17
+ hiddenClass: 'kpt-pick-list__item--waiting',
18
+ movingClass: 'kpt-pick-list__item--moving',
19
+ };
20
+ /** Klasa View Transitions dla morfu. */
21
+ const MORPH_CLASS = 'kpt-pick-list-morph';
22
+ /** Przewijany pojemnik wiersza - lista panelu. */
23
+ function scrollerOf(element) {
24
+ return element.closest('.kpt-pick-list__items');
25
+ }
11
26
  /**
12
- * PickList — transfer elementów między dwiema listami. Klik zaznacza, przyciski pośrodku
27
+ * PickList - transfer elementów między dwiema listami. Klik zaznacza, przyciski pośrodku
13
28
  * przenoszą zaznaczone albo wszystko, dwuklik przerzuca pojedynczy element na drugą stronę.
14
- * Z `dragdrop` dochodzi przeciąganie — porządkowanie wewnątrz panelu i przenoszenie na
29
+ * Z `dragdrop` dochodzi przeciąganie - porządkowanie wewnątrz panelu i przenoszenie na
15
30
  * konkretną pozycję drugiego panelu.
16
31
  *
17
32
  * Każda lista to `listbox` z wielokrotnym wyborem i jednym przystankiem Tab (roving tabindex):
@@ -26,7 +41,7 @@ const EMPTY = [];
26
41
  * renderItem={(item) => item.name}
27
42
  * />
28
43
  */
29
- export function KptPickList({ source, defaultSource = EMPTY, onSourceChange, target, defaultTarget = EMPTY, onTargetChange, sourceHeader, targetHeader, dragdrop = false, renderItem, locale, dictionary, className, ref, ...rest }) {
44
+ export function KptPickList({ source, defaultSource = EMPTY, onSourceChange, target, defaultTarget = EMPTY, onTargetChange, sourceHeader, targetHeader, dragdrop = false, layoutMotion, renderItem, locale, dictionary, className, ref, ...rest }) {
30
45
  const { t } = useKptMessages({ locale, dictionary });
31
46
  const [left, setLeft] = useControllableState({
32
47
  value: source,
@@ -42,18 +57,80 @@ export function KptPickList({ source, defaultSource = EMPTY, onSourceChange, tar
42
57
  // po obu stronach się przesuwają, a referencja zostaje ta sama.
43
58
  const [selLeft, setSelLeft] = useState(new Set());
44
59
  const [selRight, setSelRight] = useState(new Set());
45
- /** Przeciągany element — strona i pozycja w jej tablicy. */
60
+ /** Przeciągany element - strona i pozycja w jej tablicy. */
46
61
  const [drag, setDrag] = useState(null);
47
- /** Element pod kursorem — rysuje wskaźnik miejsca upuszczenia. */
62
+ /** Element pod kursorem - rysuje wskaźnik miejsca upuszczenia. */
48
63
  const [over, setOver] = useState(null);
49
- /** Panel, nad którego pustym obszarem jest kursor — upuszczenie tam dopina na koniec. */
64
+ /** Panel, nad którego pustym obszarem jest kursor - upuszczenie tam dopina na koniec. */
50
65
  const [listOver, setListOver] = useState(null);
51
- /** Pozycja, która ostatnio miała fokus w każdej liście — ona jest przystankiem Tab. */
66
+ /** Pozycja, która ostatnio miała fokus w każdej liście - ona jest przystankiem Tab. */
52
67
  const [focusLeft, setFocusLeft] = useState(0);
53
68
  const [focusRight, setFocusRight] = useState(0);
54
69
  /** Pozycja, na którą po renderze trzeba przenieść fokus DOM (klawiatura). */
55
70
  const [focusRequest, setFocusRequest] = useState(null);
56
71
  const rootRef = useRef(null);
72
+ const motionConfig = useKptMotion();
73
+ // `view-transition-name` musi być poprawnym identyfikatorem CSS - `useId` daje dwukropki.
74
+ const morphPrefix = `kpt-pick-list-${useId().replaceAll(/[^a-zA-Z0-9-]/g, '')}`;
75
+ /** Który element danych pokazuje każdy wiersz - wiersze mają klucz po indeksie, więc go zmieniają. */
76
+ const keyOf = useRef(new WeakMap());
77
+ /** Stan sprzed zmiany, czekający na commit nowego układu. */
78
+ const pending = useRef(null);
79
+ /** Elementy, które przy ostatniej zmianie przeszły na drugą stronę - lista przewija się do nich. */
80
+ const crossed = useRef([]);
81
+ const stage = () => rootRef.current?.querySelector('.kpt-pick-list') ?? null;
82
+ const nodes = () => {
83
+ const root = stage();
84
+ if (!root)
85
+ return [];
86
+ return Array.from(root.querySelectorAll('.kpt-pick-list__items > .kpt-pick-list__item')).flatMap((element) => keyOf.current.has(element) ? [{ key: keyOf.current.get(element), element }] : []);
87
+ };
88
+ /** Przewija listę docelową do ostatniego przeniesionego elementu - ląduje tam, gdzie go widać. */
89
+ const revealCrossed = () => {
90
+ const last = crossed.current.at(-1);
91
+ if (last === undefined)
92
+ return;
93
+ const node = nodes().find((n) => n.key === last);
94
+ if (node)
95
+ revealInScroller(node.element, scrollerOf(node.element));
96
+ };
97
+ /**
98
+ * Zmiana list z ruchem. Stan sprzed zmiany mierzymy, zanim React zmieni DOM - dlatego animujemy
99
+ * zmiany z interakcji (przyciski, dwuklik, Enter, przeciąganie), a listy podmienione z zewnątrz
100
+ * przełączają się od razu.
101
+ */
102
+ const withMotion = (apply, origin) => {
103
+ const motion = resolveLayoutMotion(layoutMotion, motionConfig);
104
+ crossed.current = [];
105
+ const root = stage();
106
+ if (motion === 'none' || !root || !layoutMotionAllowed()) {
107
+ apply();
108
+ return;
109
+ }
110
+ if (motion === 'morph') {
111
+ morphKeyed(nodes(), nodes, morphPrefix, MORPH_CLASS, () => {
112
+ flushSync(apply);
113
+ revealCrossed();
114
+ }, (el) => isVisibleInScroller(el, scrollerOf(el)));
115
+ return;
116
+ }
117
+ pending.current = { first: snapshotKeyed(root, nodes(), scrollerOf), motion, origin };
118
+ stopKeyedMotion(root, MOTION_CLASSES);
119
+ apply();
120
+ };
121
+ // Nowy układ jest już w DOM (a `keyOf` zaktualizowany refami) - gramy loty od zapamiętanego stanu.
122
+ const playPending = useEffectEvent(() => {
123
+ const job = pending.current;
124
+ pending.current = null;
125
+ const root = stage();
126
+ if (!job || !root)
127
+ return;
128
+ revealCrossed();
129
+ playKeyedMotion(root, job.first, nodes(), { motion: job.motion, scrollerOf, ...MOTION_CLASSES }, job.origin);
130
+ });
131
+ useLayoutEffect(() => {
132
+ playPending();
133
+ }, [left, right]);
57
134
  const listOf = (side) => (side === 'source' ? left : right);
58
135
  const setListOf = (side) => (side === 'source' ? setLeft : setRight);
59
136
  const selectionOf = (side) => (side === 'source' ? selLeft : selRight);
@@ -61,7 +138,7 @@ export function KptPickList({ source, defaultSource = EMPTY, onSourceChange, tar
61
138
  const other = (side) => (side === 'source' ? 'target' : 'source');
62
139
  const focusOf = (side) => (side === 'source' ? focusLeft : focusRight);
63
140
  const setFocusOf = (side) => (side === 'source' ? setFocusLeft : setFocusRight);
64
- /** Przystanek Tab listy — ostatnio skupiona pozycja, przycięta do długości listy. */
141
+ /** Przystanek Tab listy - ostatnio skupiona pozycja, przycięta do długości listy. */
65
142
  const tabIndexOf = (side) => Math.min(focusOf(side), listOf(side).length - 1);
66
143
  // Żądanie nie jest zerowane w efekcie (setState w efekcie = dodatkowy przebieg renderu): każde jest
67
144
  // nowym obiektem, więc efekt rusza raz na żądanie, także o ten sam indeks.
@@ -95,7 +172,10 @@ export function KptPickList({ source, defaultSource = EMPTY, onSourceChange, tar
95
172
  const text = t('pickList.moved', { count, list: headerOf(to) });
96
173
  setAnnouncement((current) => (current === text ? text + '\u00a0' : text));
97
174
  };
98
- const move = (from, all) => {
175
+ const move = (from, all, origin) => {
176
+ withMotion(() => moveNow(from, all), origin);
177
+ };
178
+ const moveNow = (from, all) => {
99
179
  const to = other(from);
100
180
  const fromItems = listOf(from);
101
181
  const selection = selectionOf(from);
@@ -104,6 +184,7 @@ export function KptPickList({ source, defaultSource = EMPTY, onSourceChange, tar
104
184
  return;
105
185
  setListOf(from)(fromItems.filter((item) => !moving.includes(item)));
106
186
  setListOf(to)([...listOf(to), ...moving]);
187
+ crossed.current = moving;
107
188
  setSelectionOf(from)(new Set());
108
189
  announce(moving.length, to);
109
190
  };
@@ -117,9 +198,11 @@ export function KptPickList({ source, defaultSource = EMPTY, onSourceChange, tar
117
198
  toItems.splice(toIndex, 0, moved);
118
199
  setListOf(fromSide)(fromItems);
119
200
  setListOf(toSide)(toItems);
120
- if (fromSide !== toSide)
201
+ if (fromSide !== toSide) {
202
+ crossed.current = [moved];
121
203
  announce(1, toSide);
122
- // Element opuszcza panel — jego zaznaczenie po tamtej stronie przestaje cokolwiek znaczyć.
204
+ }
205
+ // Element opuszcza panel - jego zaznaczenie po tamtej stronie przestaje cokolwiek znaczyć.
123
206
  const selection = selectionOf(fromSide);
124
207
  if (selection.has(moved)) {
125
208
  const next = new Set(selection);
@@ -128,12 +211,12 @@ export function KptPickList({ source, defaultSource = EMPTY, onSourceChange, tar
128
211
  }
129
212
  };
130
213
  /** Dwuklik: przenosi wyłącznie klikniętą pozycję, niezależnie od zaznaczenia. */
131
- const moveOne = (from, item) => {
214
+ const moveOne = (from, item, origin) => {
132
215
  const index = listOf(from).indexOf(item);
133
216
  if (index === -1)
134
217
  return;
135
218
  const to = other(from);
136
- transfer(from, index, to, listOf(to).length);
219
+ withMotion(() => transfer(from, index, to, listOf(to).length), origin);
137
220
  };
138
221
  const onItemKeyDown = (side, index, item, event) => {
139
222
  if (event.key === ' ') {
@@ -143,8 +226,8 @@ export function KptPickList({ source, defaultSource = EMPTY, onSourceChange, tar
143
226
  }
144
227
  if (event.key === 'Enter') {
145
228
  event.preventDefault();
146
- moveOne(side, item);
147
- // Pozycja zniknęła z listy — fokus zostaje w tym samym miejscu listy, na następnej.
229
+ moveOne(side, item, event.currentTarget);
230
+ // Pozycja zniknęła z listy - fokus zostaje w tym samym miejscu listy, na następnej.
148
231
  focusItem(side, index);
149
232
  return;
150
233
  }
@@ -182,20 +265,21 @@ export function KptPickList({ source, defaultSource = EMPTY, onSourceChange, tar
182
265
  clearDrag();
183
266
  if (from === null)
184
267
  return;
268
+ const origin = event.currentTarget;
185
269
  if (from.side !== side) {
186
- transfer(from.side, from.index, side, index);
270
+ withMotion(() => transfer(from.side, from.index, side, index), origin);
187
271
  return;
188
272
  }
189
273
  if (from.index === index)
190
274
  return;
191
- // Indeks celu liczony na tablicy sprzed usunięcia — element ląduje na pozycji tego,
275
+ // Indeks celu liczony na tablicy sprzed usunięcia - element ląduje na pozycji tego,
192
276
  // na który go upuszczono (ten sam wzór co przestawianie kolumn w KptDataTable).
193
277
  const next = [...listOf(side)];
194
278
  const [moved] = next.splice(from.index, 1);
195
279
  if (moved === undefined)
196
280
  return;
197
281
  next.splice(index, 0, moved);
198
- setListOf(side)(next);
282
+ withMotion(() => setListOf(side)(next), origin);
199
283
  };
200
284
  const onListDragOver = (side, event) => {
201
285
  if (drag === null)
@@ -210,8 +294,9 @@ export function KptPickList({ source, defaultSource = EMPTY, onSourceChange, tar
210
294
  clearDrag();
211
295
  if (from === null)
212
296
  return;
297
+ const origin = event.currentTarget;
213
298
  if (from.side !== side) {
214
- transfer(from.side, from.index, side, listOf(side).length);
299
+ withMotion(() => transfer(from.side, from.index, side, listOf(side).length), origin);
215
300
  return;
216
301
  }
217
302
  const next = [...listOf(side)];
@@ -219,7 +304,7 @@ export function KptPickList({ source, defaultSource = EMPTY, onSourceChange, tar
219
304
  if (moved === undefined)
220
305
  return;
221
306
  next.push(moved);
222
- setListOf(side)(next);
307
+ withMotion(() => setListOf(side)(next), origin);
223
308
  };
224
309
  const column = (side) => {
225
310
  const items = listOf(side);
@@ -227,8 +312,11 @@ export function KptPickList({ source, defaultSource = EMPTY, onSourceChange, tar
227
312
  const header = headerOf(side);
228
313
  return (_jsxs("div", { className: "kpt-pick-list__col", children: [_jsx("div", { className: "kpt-pick-list__header", children: header }), _jsx("ul", { className: cn('kpt-pick-list__items', listOver === side && 'is-dragover'), role: "listbox", "aria-multiselectable": "true", "aria-label": header, onDragOver: (event) => onListDragOver(side, event), onDragLeave: () => setListOver(null), onDrop: (event) => onListDrop(side, event), children: items.map((item, index) => {
229
314
  const dragging = drag?.side === side && drag.index === index;
230
- return (_jsx("li", { className: cn('kpt-pick-list__item', selection.has(item) && 'is-selected', dragging && 'is-dragging', dragdrop && 'kpt-pick-list__item--draggable', over?.side === side && over.index === index && !dragging && 'kpt-pick-list__item--dragover'), role: "option", "aria-selected": selection.has(item), tabIndex: index === tabIndexOf(side) ? 0 : -1, onFocus: () => setFocusOf(side)(index), onKeyDown: (event) => onItemKeyDown(side, index, item, event), draggable: dragdrop || undefined, onClick: () => toggle(side, item), onDoubleClick: () => moveOne(side, item), onDragStart: (event) => onDragStart(side, index, event), onDragOver: (event) => onDragOver(side, index, event), onDragLeave: () => setOver(null), onDrop: (event) => onDrop(side, index, event), onDragEnd: clearDrag, children: renderItem(item, index) }, index));
315
+ return (_jsx("li", { ref: (element) => {
316
+ if (element)
317
+ keyOf.current.set(element, item);
318
+ }, className: cn('kpt-pick-list__item', selection.has(item) && 'is-selected', dragging && 'is-dragging', dragdrop && 'kpt-pick-list__item--draggable', over?.side === side && over.index === index && !dragging && 'kpt-pick-list__item--dragover'), role: "option", "aria-selected": selection.has(item), tabIndex: index === tabIndexOf(side) ? 0 : -1, onFocus: () => setFocusOf(side)(index), onKeyDown: (event) => onItemKeyDown(side, index, item, event), draggable: dragdrop || undefined, onClick: () => toggle(side, item), onDoubleClick: (event) => moveOne(side, item, event.currentTarget), onDragStart: (event) => onDragStart(side, index, event), onDragOver: (event) => onDragOver(side, index, event), onDragLeave: () => setOver(null), onDrop: (event) => onDrop(side, index, event), onDragEnd: clearDrag, children: renderItem(item, index) }, index));
231
319
  }) })] }));
232
320
  };
233
- return (_jsxs("div", { ref: composeRefs(rootRef, ref), className: cn('kpt-pick-list-host', className), ...rest, children: [_jsxs("div", { className: "kpt-pick-list", children: [column('source'), _jsxs("div", { className: "kpt-pick-list__controls", children: [_jsxs("button", { type: "button", "aria-label": t('pickList.moveAllRight'), "aria-disabled": !left.length || undefined, onClick: () => move('source', true), children: [_jsx(KptIcon, { name: "chevron-right" }), _jsx(KptIcon, { name: "chevron-right" })] }), _jsx("button", { type: "button", "aria-label": t('pickList.moveRight'), "aria-disabled": !selLeft.size || undefined, onClick: () => move('source', false), children: _jsx(KptIcon, { name: "chevron-right" }) }), _jsx("button", { type: "button", "aria-label": t('pickList.moveLeft'), "aria-disabled": !selRight.size || undefined, onClick: () => move('target', false), children: _jsx(KptIcon, { name: "chevron-left" }) }), _jsxs("button", { type: "button", "aria-label": t('pickList.moveAllLeft'), "aria-disabled": !right.length || undefined, onClick: () => move('target', true), children: [_jsx(KptIcon, { name: "chevron-left" }), _jsx(KptIcon, { name: "chevron-left" })] })] }), column('target')] }), _jsx("p", { className: "kpt-visually-hidden", "aria-live": "polite", children: announcement })] }));
321
+ return (_jsxs("div", { ref: composeRefs(rootRef, ref), className: cn('kpt-pick-list-host', className), ...rest, children: [_jsxs("div", { className: "kpt-pick-list", children: [column('source'), _jsxs("div", { className: "kpt-pick-list__controls", children: [_jsxs("button", { type: "button", "aria-label": t('pickList.moveAllRight'), "aria-disabled": !left.length || undefined, onClick: (event) => move('source', true, event.currentTarget), children: [_jsx(KptIcon, { name: "chevron-right" }), _jsx(KptIcon, { name: "chevron-right" })] }), _jsx("button", { type: "button", "aria-label": t('pickList.moveRight'), "aria-disabled": !selLeft.size || undefined, onClick: (event) => move('source', false, event.currentTarget), children: _jsx(KptIcon, { name: "chevron-right" }) }), _jsx("button", { type: "button", "aria-label": t('pickList.moveLeft'), "aria-disabled": !selRight.size || undefined, onClick: (event) => move('target', false, event.currentTarget), children: _jsx(KptIcon, { name: "chevron-left" }) }), _jsxs("button", { type: "button", "aria-label": t('pickList.moveAllLeft'), "aria-disabled": !right.length || undefined, onClick: (event) => move('target', true, event.currentTarget), children: [_jsx(KptIcon, { name: "chevron-left" }), _jsx(KptIcon, { name: "chevron-left" })] })] }), column('target')] }), _jsx("p", { className: "kpt-visually-hidden", "aria-live": "polite", children: announcement })] }));
234
322
  }
@@ -1,20 +1,20 @@
1
1
  # KptPopover (@konce-pt/react)
2
2
 
3
- Any content in a bubble pinned to its trigger — richer than a tooltip.
3
+ Any content in a bubble pinned to its trigger - richer than a tooltip.
4
4
  Import: `import { KptPopover } from '@konce-pt/react';`
5
5
 
6
6
  ## DOM
7
7
  <span class="kpt-popover-host">
8
- <span class="kpt-popover__trigger">…trigger…</span>
8
+ <span class="kpt-popover__trigger">...trigger...</span>
9
9
  </span>
10
10
  <!-- while open, in a portal on document.body: -->
11
- <div class="kpt-popover__panel" role="dialog">…children…</div>
11
+ <div class="kpt-popover__panel" role="dialog">...children...</div>
12
12
 
13
13
  ## Props
14
- - `trigger`: ReactNode — the element that opens the bubble, rendered in place
15
- - `children`: ReactNode — the panel content
16
- - `open` / `defaultOpen` / `onOpenChange` — controlled or uncontrolled
17
- - `placement`: 'bottom' (default) | 'top' — the preferred side; it flips when there is no room
14
+ - `trigger`: ReactNode - the element that opens the bubble, rendered in place
15
+ - `children`: ReactNode - the panel content
16
+ - `open` / `defaultOpen` / `onOpenChange` - controlled or uncontrolled
17
+ - `placement`: 'bottom' (default) | 'top' - the preferred side; it flips when there is no room
18
18
  - `className`, `ref` and every other `<span>` prop go to the host
19
19
 
20
20
  ## The panel is a portal
@@ -22,7 +22,7 @@ The Angular port stands on CDK Overlay. Here the panel renders into a portal on
22
22
  with the same behaviour: positioned below the trigger, flipping above when there is no room, closed
23
23
  by a click outside or by Escape, and following scroll and resize.
24
24
 
25
- Clicking the trigger while the bubble is open closes it and does not reopen it — the transparent
25
+ Clicking the trigger while the bubble is open closes it and does not reopen it - the transparent
26
26
  backdrop takes that click, exactly as the CDK backdrop does.
27
27
 
28
28
  ## Examples
@@ -43,10 +43,10 @@ The panel is `role="dialog"` with an `id` the trigger points to.
43
43
 
44
44
  ## Focus and keyboard
45
45
  The control inside the trigger slot gets `aria-haspopup="dialog"`, a live `aria-expanded` and, while
46
- open, `aria-controls` — on the real `<button>`, not on the wrapper. Opening moves focus to the first
46
+ open, `aria-controls` - on the real `<button>`, not on the wrapper. Opening moves focus to the first
47
47
  interactive element of the bubble; `Escape` or a click outside closes it, and focus returns to the
48
- trigger when it was inside the bubble. Focus is not trapped — the popover is supporting content, not
48
+ trigger when it was inside the bubble. Focus is not trapped - the popover is supporting content, not
49
49
  a modal.
50
50
 
51
51
  ## Name and Escape
52
- Give the panel `ariaLabel` — it is a `role="dialog"`. Escape closes only the top-most panel and does not reach an enclosing `<dialog>`, so a popover inside a dialog closes alone.
52
+ Give the panel `ariaLabel` - it is a `role="dialog"`. Escape closes only the top-most panel and does not reach an enclosing `<dialog>`, so a popover inside a dialog closes alone.
@@ -1,6 +1,6 @@
1
1
  import { type ComponentPropsWithRef, type ReactNode } from 'react';
2
2
  export interface KptPopoverProps extends Omit<ComponentPropsWithRef<'span'>, 'content'> {
3
- /** Element otwierający dymek — renderowany w miejscu popovera. */
3
+ /** Element otwierający dymek - renderowany w miejscu popovera. */
4
4
  trigger: ReactNode;
5
5
  /** Treść panelu. */
6
6
  children?: ReactNode;
@@ -9,11 +9,11 @@ export interface KptPopoverProps extends Omit<ComponentPropsWithRef<'span'>, 'co
9
9
  onOpenChange?: (open: boolean) => void;
10
10
  /** Preferowana strona dymka; gdy brakuje miejsca, przechodzi na drugą. */
11
11
  placement?: 'bottom' | 'top';
12
- /** Nazwa panelu (`role="dialog"`) — okno bez nazwy czytnik ogłasza jako samo „okno dialogowe”. */
12
+ /** Nazwa panelu (`role="dialog"`) - okno bez nazwy czytnik ogłasza jako samo "okno dialogowe". */
13
13
  ariaLabel?: string;
14
14
  }
15
15
  /**
16
- * Popover — dowolna treść w dymku przypiętym do wyzwalacza (bogatszy niż tooltip).
16
+ * Popover - dowolna treść w dymku przypiętym do wyzwalacza (bogatszy niż tooltip).
17
17
  *
18
18
  * Port Angulara stoi na CDK Overlay; tutaj panel renderuje się w portalu do `document.body`,
19
19
  * z tym samym zachowaniem: pozycja pod wyzwalaczem (albo nad nim przy `placement="top"`)
@@ -25,7 +25,7 @@ export interface KptPopoverProps extends Omit<ComponentPropsWithRef<'span'>, 'co
25
25
  *
26
26
  * @example
27
27
  * <KptPopover trigger={<KptButton variant="outline">Szczegóły</KptButton>}>
28
- * <div>Bogata treść popovera…</div>
28
+ * <div>Bogata treść popovera...</div>
29
29
  * </KptPopover>
30
30
  */
31
31
  export declare function KptPopover({ trigger, children, open, defaultOpen, onOpenChange, placement, ariaLabel, className, ...rest }: Readonly<KptPopoverProps>): import("react").JSX.Element;
@@ -5,10 +5,10 @@ import { cn } from "../internal/cn.js";
5
5
  import { KptOverlay } from "../internal/overlay.js";
6
6
  import { useControllableState } from "../internal/use-controllable-state.js";
7
7
  import { useKptId } from "../internal/use-id.js";
8
- /** Elementy, które same przyjmują fokus — pierwszy z nich dostaje fokus po otwarciu dymka. */
8
+ /** Elementy, które same przyjmują fokus - pierwszy z nich dostaje fokus po otwarciu dymka. */
9
9
  const FOCUSABLE = 'a[href], button:not(:disabled), input:not(:disabled), select, textarea, [tabindex]:not([tabindex="-1"])';
10
10
  /**
11
- * Popover — dowolna treść w dymku przypiętym do wyzwalacza (bogatszy niż tooltip).
11
+ * Popover - dowolna treść w dymku przypiętym do wyzwalacza (bogatszy niż tooltip).
12
12
  *
13
13
  * Port Angulara stoi na CDK Overlay; tutaj panel renderuje się w portalu do `document.body`,
14
14
  * z tym samym zachowaniem: pozycja pod wyzwalaczem (albo nad nim przy `placement="top"`)
@@ -20,12 +20,12 @@ const FOCUSABLE = 'a[href], button:not(:disabled), input:not(:disabled), select,
20
20
  *
21
21
  * @example
22
22
  * <KptPopover trigger={<KptButton variant="outline">Szczegóły</KptButton>}>
23
- * <div>Bogata treść popovera…</div>
23
+ * <div>Bogata treść popovera...</div>
24
24
  * </KptPopover>
25
25
  */
26
26
  export function KptPopover({ trigger, children, open, defaultOpen = false, onOpenChange, placement = 'bottom', ariaLabel = '', className, ...rest }) {
27
27
  const triggerRef = useRef(null);
28
- /** Kotwica panelu — w stanie, bo czyta ją render; ref zostaje dla handlerów. */
28
+ /** Kotwica panelu - w stanie, bo czyta ją render; ref zostaje dla handlerów. */
29
29
  const [anchor, setAnchor] = useState(null);
30
30
  const setTrigger = useCallback((element) => {
31
31
  triggerRef.current = element;
@@ -51,7 +51,7 @@ export function KptPopover({ trigger, children, open, defaultOpen = false, onOpe
51
51
  else
52
52
  control.removeAttribute('aria-controls');
53
53
  }, [isOpen, trigger, panelId]);
54
- // Fokus do dymka klatkę później — `KptOverlay` trzyma panel niewidoczny, dopóki go nie zmierzy.
54
+ // Fokus do dymka klatkę później - `KptOverlay` trzyma panel niewidoczny, dopóki go nie zmierzy.
55
55
  useEffect(() => {
56
56
  if (!isOpen)
57
57
  return;
@@ -1,12 +1,12 @@
1
1
  # KptProgress (@konce-pt/react)
2
2
 
3
- A progress indicator — linear or circular, determinate (`min`–`max`) or indeterminate (`value` = null).
3
+ A progress indicator - linear or circular, determinate (`min`-`max`) or indeterminate (`value` = null).
4
4
  Import: `import { KptProgress } from '@konce-pt/react';`
5
5
 
6
6
  ## DOM
7
7
  <!-- linear, with a label, a buffer and a value -->
8
8
  <div class="kpt-progress-host" data-type="linear" data-size="md" data-variant="primary" data-label-position="top">
9
- <span class="kpt-progress__label">Loading…</span>
9
+ <span class="kpt-progress__label">Loading...</span>
10
10
  <div class="kpt-progress__linear" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="80">
11
11
  <div class="kpt-progress__buffer" style="width: 92%"></div>
12
12
  <div class="kpt-progress__bar" style="width: 80%"></div>
@@ -23,28 +23,28 @@ Import: `import { KptProgress } from '@konce-pt/react';`
23
23
  <span class="kpt-progress__value" aria-hidden="true">75%</span>
24
24
  </div>
25
25
 
26
- The label, the track and the value are siblings straight under the host — there is no wrapper element.
26
+ The label, the track and the value are siblings straight under the host - there is no wrapper element.
27
27
  `data-variant`, `data-type`, `data-size` and `data-label-position` all sit on the host, which is also
28
28
  where the private `--_color` and `--_thickness` are resolved. This markup matches the Angular port
29
29
  element for element, so both share one stylesheet.
30
30
 
31
31
  ## Props
32
- - `value`: number | null (default null) — a value on the `min`–`max` scale, or null for indeterminate
32
+ - `value`: number | null (default null) - a value on the `min`-`max` scale, or null for indeterminate
33
33
  - `min`: number (default 0); `max`: number (default 100)
34
34
  - `variant`: 'primary' | 'success' | 'danger' | 'warning' | 'info' (default 'primary')
35
35
  - `type`: 'linear' | 'circular' (default 'linear')
36
- - `size`: 'sm' | 'md' | 'lg' (default 'md') — track thickness, and arc width on the circular variant
37
- - `diameter`: number (default 40) — the circular variant's size in pixels
38
- - `bufferValue`: number | null (default null) — a second, dimmed bar behind the main one; linear only
39
- - `showValue`: boolean (default false) — turns the value area on; `children` needs it too
36
+ - `size`: 'sm' | 'md' | 'lg' (default 'md') - track thickness, and arc width on the circular variant
37
+ - `diameter`: number (default 40) - the circular variant's size in pixels
38
+ - `bufferValue`: number | null (default null) - a second, dimmed bar behind the main one; linear only
39
+ - `showValue`: boolean (default false) - turns the value area on; `children` needs it too
40
40
  - `valueFormat`: 'percent' | 'fraction' | 'none' (default 'percent')
41
- - `label`: string — descriptive text next to the bar; it also becomes the `aria-label`
42
- - `labelPosition`: 'top' | 'bottom' | 'end' (default 'top') — ignored by the circular variant
43
- - `locale`, `dictionary` — per-instance dictionary overrides
41
+ - `label`: string - descriptive text next to the bar; it also becomes the `aria-label`
42
+ - `labelPosition`: 'top' | 'bottom' | 'end' (default 'top') - ignored by the circular variant
43
+ - `locale`, `dictionary` - per-instance dictionary overrides
44
44
  - `className`, `ref` and every other `<div>` prop go to the host
45
45
 
46
46
  ## Value label
47
- `showValue` opens the value area; `valueFormat` decides what goes in it — `percent` renders `80%`,
47
+ `showValue` opens the value area; `valueFormat` decides what goes in it - `percent` renders `80%`,
48
48
  `fraction` renders `152 / 160` from `value` and `max`, `none` leaves it empty. Both strings come from
49
49
  the `KptMessages` dictionary (`progress.percent`, `progress.fraction`), so a new locale can reshape them.
50
50
 
@@ -57,17 +57,17 @@ the accessible name.
57
57
 
58
58
  ## How the arc is drawn
59
59
  The circle lives in a fixed `viewBox="0 0 40 40"` with `r=16`, so the circumference is computed from
60
- that radius, not from `diameter` — the SVG scales, the maths does not change. The arc is the dash
60
+ that radius, not from `diameter` - the SVG scales, the maths does not change. The arc is the dash
61
61
  offset: full circumference means empty, zero means complete. `size` only changes `stroke-width`, and
62
62
  the widest step still fits inside the box, so no arc is ever clipped.
63
63
 
64
- Values outside the range are clamped rather than rejected, `max` ≤ `min` collapses to zero, and the
65
- buffer is never allowed behind the main bar — a computed percentage that briefly overshoots cannot
64
+ Values outside the range are clamped rather than rejected, `max` <= `min` collapses to zero, and the
65
+ buffer is never allowed behind the main bar - a computed percentage that briefly overshoots cannot
66
66
  break the drawing.
67
67
 
68
68
  ## Examples
69
69
  <KptProgress value={60} />
70
- <KptProgress value={80} label="Loading…" showValue />
70
+ <KptProgress value={80} label="Loading..." showValue />
71
71
  <KptProgress value={152} max={160} size="lg" showValue valueFormat="fraction" labelPosition="bottom" />
72
72
  <KptProgress value={65} showValue labelPosition="end" />
73
73
  <KptProgress value={38} bufferValue={62} />
@@ -91,5 +91,5 @@ leaves the value out, which is how a screen reader learns the progress is unknow
91
91
  announcing the raw number as a percentage. The visible value is `aria-hidden`, so it is never read
92
92
  twice. The accessible name comes from `label`, or from the dictionary when there is none.
93
93
 
94
- Under `prefers-reduced-motion: reduce` the indeterminate animation slows down instead of stopping —
94
+ Under `prefers-reduced-motion: reduce` the indeterminate animation slows down instead of stopping -
95
95
  a frozen progress indicator reads as a hung application.
@@ -3,12 +3,12 @@ import { type KptI18nOverrides } from '../i18n/i18n-context.tsx';
3
3
  export type KptProgressVariant = 'primary' | 'success' | 'danger' | 'warning' | 'info';
4
4
  export type KptProgressType = 'linear' | 'circular';
5
5
  export type KptProgressSize = 'sm' | 'md' | 'lg';
6
- /** Postać etykiety wartości: procent, „ile z ilu" albo brak. */
6
+ /** Postać etykiety wartości: procent, "ile z ilu" albo brak. */
7
7
  export type KptProgressValueFormat = 'percent' | 'fraction' | 'none';
8
8
  /** Gdzie siada wiersz etykiety względem paska (tylko `type="linear"`). */
9
9
  export type KptProgressLabelPosition = 'top' | 'bottom' | 'end';
10
10
  export interface KptProgressProps extends ComponentPropsWithRef<'div'>, KptI18nOverrides {
11
- /** Wartość w skali `min`–`max` albo `null` = postęp nieokreślony. */
11
+ /** Wartość w skali `min`-`max` albo `null` = postęp nieokreślony. */
12
12
  value?: number | null;
13
13
  min?: number;
14
14
  max?: number;
@@ -18,26 +18,26 @@ export interface KptProgressProps extends ComponentPropsWithRef<'div'>, KptI18nO
18
18
  size?: KptProgressSize;
19
19
  /** Średnica wariantu kołowego w pikselach. */
20
20
  diameter?: number;
21
- /** Postęp buforowania — drugi, przygaszony pasek pod głównym (tylko liniowy). */
21
+ /** Postęp buforowania - drugi, przygaszony pasek pod głównym (tylko liniowy). */
22
22
  bufferValue?: number | null;
23
- /** Włącza obszar etykiety wartości — razem z nim renderuje się `children`. */
23
+ /** Włącza obszar etykiety wartości - razem z nim renderuje się `children`. */
24
24
  showValue?: boolean;
25
25
  valueFormat?: KptProgressValueFormat;
26
26
  /** Tekst opisowy obok paska; służy też za `aria-label`. */
27
27
  label?: string;
28
28
  labelPosition?: KptProgressLabelPosition;
29
- /** Zastępuje sformatowaną wartość — wymaga `showValue`. */
29
+ /** Zastępuje sformatowaną wartość - wymaga `showValue`. */
30
30
  children?: ReactNode;
31
31
  }
32
32
  /**
33
- * Wskaźnik postępu — liniowy lub kołowy, określony (`min`–`max`) albo nieokreślony (`value` = null).
33
+ * Wskaźnik postępu - liniowy lub kołowy, określony (`min`-`max`) albo nieokreślony (`value` = null).
34
34
  *
35
35
  * Etykietę wartości włącza `showValue`; `children` zastępuje sformatowaną wartość,
36
36
  * więc w środku koła można pokazać cokolwiek.
37
37
  *
38
38
  * @example
39
39
  * <KptProgress value={60} />
40
- * <KptProgress value={80} label="Ładowanie…" showValue />
40
+ * <KptProgress value={80} label="Ładowanie..." showValue />
41
41
  * <KptProgress value={152} max={160} showValue valueFormat="fraction" labelPosition="bottom" />
42
42
  * <KptProgress value={38} bufferValue={62} />
43
43
  * <KptProgress type="circular" value={75} variant="success" showValue />
@@ -2,18 +2,18 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { cn } from "../internal/cn.js";
4
4
  import { useKptMessages } from "../i18n/i18n-context.js";
5
- /** Promień okręgu w viewBox 0 0 40 40 — obwód liczymy z niego, nie ze średnicy w pikselach. */
5
+ /** Promień okręgu w viewBox 0 0 40 40 - obwód liczymy z niego, nie ze średnicy w pikselach. */
6
6
  const RADIUS = 16;
7
7
  const CIRCUMFERENCE = 2 * Math.PI * RADIUS;
8
8
  /**
9
- * Wskaźnik postępu — liniowy lub kołowy, określony (`min`–`max`) albo nieokreślony (`value` = null).
9
+ * Wskaźnik postępu - liniowy lub kołowy, określony (`min`-`max`) albo nieokreślony (`value` = null).
10
10
  *
11
11
  * Etykietę wartości włącza `showValue`; `children` zastępuje sformatowaną wartość,
12
12
  * więc w środku koła można pokazać cokolwiek.
13
13
  *
14
14
  * @example
15
15
  * <KptProgress value={60} />
16
- * <KptProgress value={80} label="Ładowanie…" showValue />
16
+ * <KptProgress value={80} label="Ładowanie..." showValue />
17
17
  * <KptProgress value={152} max={160} showValue valueFormat="fraction" labelPosition="bottom" />
18
18
  * <KptProgress value={38} bufferValue={62} />
19
19
  * <KptProgress type="circular" value={75} variant="success" showValue />
@@ -22,7 +22,7 @@ const CIRCUMFERENCE = 2 * Math.PI * RADIUS;
22
22
  export function KptProgress({ value = null, min = 0, max = 100, variant = 'primary', type = 'linear', size = 'md', diameter = 40, bufferValue = null, showValue = false, valueFormat = 'percent', label, labelPosition = 'top', locale, dictionary, className, children, ...rest }) {
23
23
  const { t } = useKptMessages({ locale, dictionary });
24
24
  const indeterminate = value == null;
25
- /** Ułamek 0–1. Odporny na `max` ≤ `min` i na wartości spoza zakresu. */
25
+ /** Ułamek 0-1. Odporny na `max` <= `min` i na wartości spoza zakresu. */
26
26
  const toRatio = (v) => {
27
27
  if (v == null)
28
28
  return 0;
@@ -33,7 +33,7 @@ export function KptProgress({ value = null, min = 0, max = 100, variant = 'prima
33
33
  };
34
34
  const ratio = toRatio(value);
35
35
  const percent = Math.round(ratio * 100);
36
- // Bufor nigdy nie cofa się za pasek główny — inaczej wyglądałby jak błąd renderowania.
36
+ // Bufor nigdy nie cofa się za pasek główny - inaczej wyglądałby jak błąd renderowania.
37
37
  const bufferRatio = Math.max(ratio, toRatio(bufferValue));
38
38
  const offset = CIRCUMFERENCE * (1 - ratio);
39
39
  const fractionText = () => t('progress.fraction', { value: value ?? 0, max });
@@ -42,7 +42,7 @@ export function KptProgress({ value = null, min = 0, max = 100, variant = 'prima
42
42
  valueText = valueFormat === 'fraction' ? fractionText() : t('progress.percent', { value: percent });
43
43
  }
44
44
  /**
45
- * Czytnik ekranu domyślnie odczytuje `aria-valuenow` jako procent, więc przy formacie „ile z ilu"
45
+ * Czytnik ekranu domyślnie odczytuje `aria-valuenow` jako procent, więc przy formacie "ile z ilu"
46
46
  * podajemy mu ten sam napis, który widzi użytkownik.
47
47
  */
48
48
  const ariaValueText = indeterminate || valueFormat !== 'fraction' ? undefined : fractionText();
@@ -13,7 +13,7 @@ export type { KptPanelProps } from './panel/panel.tsx';
13
13
  export { KptStepper, KptStep, useKptStepper } from './stepper/stepper.tsx';
14
14
  export type { KptStepProps, KptStepperContextValue, KptStepperProps } from './stepper/stepper.tsx';
15
15
  export { KptFieldset } from './fieldset/fieldset.tsx';
16
- export type { KptFieldsetProps } from './fieldset/fieldset.tsx';
16
+ export type { KptFieldsetProps, KptFieldsetVariant } from './fieldset/fieldset.tsx';
17
17
  export { KptTimeline } from './timeline/timeline.tsx';
18
18
  export type { KptTimelineItem, KptTimelineProps } from './timeline/timeline.tsx';
19
19
  export { KptAlert } from './alert/alert.tsx';
@@ -26,6 +26,10 @@ export { KptProgress } from './progress/progress.tsx';
26
26
  export type { KptProgressProps, KptProgressVariant, KptProgressType, KptProgressSize, KptProgressValueFormat, KptProgressLabelPosition, } from './progress/progress.tsx';
27
27
  export { KptSpinner } from './spinner/spinner.tsx';
28
28
  export type { KptSpinnerProps } from './spinner/spinner.tsx';
29
+ export { KptLoader } from './loader/loader.tsx';
30
+ export type { KptLoaderProps, KptLoaderColor, KptLoaderResult, KptLoaderStatus, KptLoaderVariant } from './loader/loader.tsx';
31
+ export { KptUpdate } from './update/update.tsx';
32
+ export type { KptUpdateProps, KptUpdateAction, KptUpdateStatus } from './update/update.tsx';
29
33
  export { KptSkeleton } from './skeleton/skeleton.tsx';
30
34
  export type { KptSkeletonProps, KptSkeletonVariant } from './skeleton/skeleton.tsx';
31
35
  export { KptIcon } from './icon/icon.tsx';
@@ -89,8 +93,8 @@ export { kptConfirm, useKptConfirmRequest } from './confirm/confirm-store.ts';
89
93
  export type { KptConfirmOptions, KptConfirmRequest } from './confirm/confirm-store.ts';
90
94
  export { KptToastContainer } from './toast/toast-container.tsx';
91
95
  export type { KptToastContainerProps } from './toast/toast-container.tsx';
92
- export { kptToast, useKptToasts } from './toast/toast-store.ts';
93
- export type { KptToast, KptToastAction, KptToastOptions } from './toast/toast-store.ts';
96
+ export { kptToast, useKptToasts, useKptToastsPaused, resolveKptToast, KPT_TOAST_FALLBACK_DURATION } from './toast/toast-store.ts';
97
+ export type { KptToast, KptToastAction, KptToastAppearance, KptToastConfig, KptToastOptions, KptToastPosition, } from './toast/toast-store.ts';
94
98
  export { KptMenu } from './menu/menu.tsx';
95
99
  export { KptMenubar } from './menubar/menubar.tsx';
96
100
  export type { KptMenubarProps } from './menubar/menubar.tsx';
@@ -172,6 +176,14 @@ export type { KptPaginatorProps } from './paginator/paginator.tsx';
172
176
  export { KptButton } from './button/button.tsx';
173
177
  export { KptIconButton } from './icon-button/icon-button.tsx';
174
178
  export type { KptIconButtonProps } from './icon-button/icon-button.tsx';
179
+ export { KptSpeechButton } from './speech/speech-button.tsx';
180
+ export type { KptSpeechButtonProps, KptSpeechColor, KptSpeechUnsupported } from './speech/speech-button.tsx';
181
+ export { KptSpeechWave } from './speech/speech-wave.tsx';
182
+ export type { KptSpeechWaveProps } from './speech/speech-wave.tsx';
183
+ export { useKptSpeechRecognition } from './speech/use-speech-recognition.ts';
184
+ export type { KptSpeechRecognition, KptSpeechRecognitionOptions, KptSpeechTargetRef, } from './speech/use-speech-recognition.ts';
185
+ export type { KptSpeechEndReason, KptSpeechErrorCode, KptSpeechInterimDisplay, KptSpeechMode, KptSpeechSnapshot, KptSpeechStatus, KptSpeechSupport, KptSpeechTarget, KptSpeechTargetInput, KptSpeechWaveMode, } from '@konce-pt/speech';
186
+ export { defaultSpeechLang, resolveSpeechTarget, speechSupport } from '@konce-pt/speech';
175
187
  export { KptFab } from './fab/fab.tsx';
176
188
  export type { KptFabProps } from './fab/fab.tsx';
177
189
  export { KptSplitButton } from './split-button/split-button.tsx';