@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,7 +1,7 @@
1
1
  import type { KptColumn } from './data-table-types.ts';
2
2
  /**
3
- * Zrzuca wiersze do pliku CSV (separator `;`, końce wierszy CRLF, BOM — patrz `buildCsv`).
4
- * Tabela woła to samo z przycisku „Eksport CSV"; funkcja jest wyeksportowana, bo w Reakcie nie ma odpowiednika metody publicznej komponentu
5
- * — eksport z kodu aplikacji wywołuje się właśnie tak.
3
+ * Zrzuca wiersze do pliku CSV (separator `;`, końce wierszy CRLF, BOM - patrz `buildCsv`).
4
+ * Tabela woła to samo z przycisku "Eksport CSV"; funkcja jest wyeksportowana, bo w Reakcie nie ma odpowiednika metody publicznej komponentu
5
+ * - eksport z kodu aplikacji wywołuje się właśnie tak.
6
6
  */
7
7
  export declare function exportTableCsv(columns: readonly KptColumn[], rows: readonly Record<string, unknown>[], filename?: string): void;
@@ -1,8 +1,8 @@
1
1
  import { buildCsv } from '@konce-pt/table';
2
2
  /**
3
- * Zrzuca wiersze do pliku CSV (separator `;`, końce wierszy CRLF, BOM — patrz `buildCsv`).
4
- * Tabela woła to samo z przycisku „Eksport CSV"; funkcja jest wyeksportowana, bo w Reakcie nie ma odpowiednika metody publicznej komponentu
5
- * — eksport z kodu aplikacji wywołuje się właśnie tak.
3
+ * Zrzuca wiersze do pliku CSV (separator `;`, końce wierszy CRLF, BOM - patrz `buildCsv`).
4
+ * Tabela woła to samo z przycisku "Eksport CSV"; funkcja jest wyeksportowana, bo w Reakcie nie ma odpowiednika metody publicznej komponentu
5
+ * - eksport z kodu aplikacji wywołuje się właśnie tak.
6
6
  */
7
7
  export function exportTableCsv(columns, rows, filename = 'export.csv') {
8
8
  const blob = new Blob([buildCsv(columns, rows)], { type: 'text/csv;charset=utf-8;' });
@@ -11,7 +11,7 @@ export function exportTableCsv(columns, rows, filename = 'export.csv') {
11
11
  link.href = url;
12
12
  link.download = filename;
13
13
  link.click();
14
- // Część przeglądarek zaczyna pobieranie asynchronicznie — natychmiastowe unieważnienie
14
+ // Część przeglądarek zaczyna pobieranie asynchronicznie - natychmiastowe unieważnienie
15
15
  // adresu potrafi je przerwać.
16
16
  setTimeout(() => URL.revokeObjectURL(url), 0);
17
17
  }
@@ -1,94 +1,127 @@
1
- # KptDataTable (@konce-pt/react)
2
-
3
- The flagship data table: columns from configuration, sorting, a global filter and per-column
4
- filters, pagination, selection, frozen and reorderable columns, inline editing, a summary row,
5
- expandable rows, virtual scrolling and CSV export.
6
- Import: `import { KptDataTable, type KptColumn } from '@konce-pt/react';`
7
-
8
- ## The column model (KptColumn)
9
- `{ field, header, sortable?, align?, width?, frozen?, filter?, edit?, summary? }`
10
- `frozen` columns (leading, adjacent) stick during horizontal scrolling. Their offsets come from `width`:
11
- `px`/`rem`/`em` are computed up front, other units (`%`, `ch`) and a missing width are measured from the
12
- rendered header.
13
-
14
- - `filter`: `KptColumnFilter` from `@konce-pt/table` — `text`, `number`, `select` (with `multiple`),
15
- `numberRange`, `slider`, `dateRange`. Any column with a `filter` renders the filter row.
16
- - `edit`: `{ type: 'text' | 'number' | 'date' | 'select' | 'multiselect', options?, placeholder?, min?, max?, step? }`
17
- - `summary`: `{ fn: 'sum' | 'avg' | 'min' | 'max' | 'count' | ((rows) => unknown), format? }`
18
-
19
- ## Props
20
- - `columns` (required), `data`
21
- - `filterable`, `filterRowPosition` (`'bottom'` default), `pageSize` (0 = no pagination),
22
- `pageSizeOptions`, `selectable` (`'none' | 'single' | 'multiple'`), `loading`, `emptyMessage`,
23
- `rowKey`, `scrollHeight`, `virtualScroll`, `rowHeight` (41), `reorderable`, `exportable`,
24
- `exportFilename`, `lazy`, `totalRecords`, `expandable`, `multiExpand`, `summaryLabel`,
25
- `summaryValues`
26
- - `ariaLabel` (the table's name without a visible caption), `caption` (a visible `<caption>`),
27
- `clickableRows` (rows focusable and activated with Enter/Space; on by default when `onRowClick` is set)
28
- - Controllable state: `selection`, `expandedRows`, `hiddenFields` (each with `default*` and
29
- `on*Change`)
30
- - Events: `onRowClick`, `onLazyLoad` (also once on start, for the first page), `onCellEdit`
31
-
32
- ## Keyboard
33
- - A sortable header is a button: Tab to it, Enter/Space cycles asc → desc → none; `aria-sort` is on the `<th>`.
34
- - With `reorderable` the grip is a button: `←`/`→` move the column by one place; the new position is
35
- announced and focus follows the grip.
36
- - An editable cell is reachable with Tab and opens with Enter; its name stays its value and
37
- "Edit: {column}" is its description.
38
- - `selectable="single"` renders radios (one group per table).
39
-
40
- ## Templates are render props
41
- - `cells`: `Record<field, (row, value) => ReactNode>` — the equivalent of `kptCell`
42
- - `cellEditors`: `Record<field, (context) => ReactNode>` — the equivalent of `kptCellEdit`;
43
- the context carries `value`, `row`, `commit(value)`, `cancel()`
44
- - `renderRowDetail(row)` — the expanded row's content
45
- - `paginatorActions` — the slot to the left of the paginator (a column-toggle button, say)
46
-
47
- ## The logic lives in a package
48
- Filter matching (the global filter and the text filter ignore case and diacritics: "lodz" finds
49
- "Łódź"), sorting (`Intl.Collator` for the active language, natural numbers, empty cells last),
50
- aggregations, the CSV file (`;`, CRLF, BOM) and cell-to-text come from `@konce-pt/table` — pure
51
- functions with `node --test` coverage, shared with the Angular port. What stays here is the state
52
- and the markup.
53
-
54
- ## Export as a function, not a method
55
- Angular exposes `exportCsv()` on the component instance; React has no equivalent, so the same job is
56
- `exportTableCsv(columns, rows, filename)`, exported from the package. The `exportable` toolbar
57
- button calls exactly that, over the currently visible columns and the filtered, sorted rows.
58
-
59
- ## Inline editing never commits on blur of the control
60
- Controls with a panel (`date`, `select`, `multiselect`) open immediately and commit when the panel
61
- closes; the rest commit when focus leaves **the whole editor**. `KptInputNumber` has focusable
62
- `+`/`-` buttons beside the field, so reacting to the control's own blur would close the editor on
63
- every arrow click. `cellEdit` fires only when the value actually changed (arrays are compared by
64
- content).
65
-
66
- ## The summary covers the filtered set, not the page
67
- Aggregations run over every row after filtering — page 1 and all the rest — so paging does not move
68
- them while the search box does. With `lazy` the table only holds one page, so it computes nothing:
69
- `summaryValues` is then the only source.
70
-
71
- ## Examples
72
- <KptDataTable columns={cols} data={rows} filterable pageSize={10} selectable="multiple" rowKey="id" />
73
-
74
- <KptDataTable
75
- columns={cols}
76
- data={rows}
77
- rowKey="id"
78
- cells={{ status: (row, value) => <span className="badge">{String(value)}</span> }}
79
- onCellEdit={(event) => save(event.updatedRow)}
80
- />
81
-
82
- ## i18n
83
- The toolbar, the states and the filter labels come from the `dataTable` namespace (`search`,
84
- `exportCsv`, `loading`, `empty`, `total`, `selectAll`, `selectRow`, `expandRow`, `editCell`,
85
- `filter` / `filterMin` / `filterMax` with `{column}`, `all`, `min`, `max`, `dateRange`, `moveColumn`,
86
- `columnMoved`).
87
-
88
- ## Tokens
89
- `--kpt-table-{bg,fg,border,radius,header-bg,header-fg,row-hover,row-selected,cell-padding}`,
90
- the expanded row `--kpt-table-detail-bg`, the summary row `--kpt-table-summary-bg`.
91
-
92
- ## Not ported yet
93
- Grouped columns (absent in the Angular port too). A ready column-toggle UI is not part of either
94
- port — `hiddenFields` is the hook to build one on.
1
+ # KptDataTable (@konce-pt/react)
2
+
3
+ The flagship data table: columns from configuration, sorting, a global filter and per-column
4
+ filters, pagination, selection, frozen and reorderable columns, inline editing, a summary row,
5
+ expandable rows, virtual scrolling and CSV export.
6
+ Import: `import { KptDataTable, type KptColumn } from '@konce-pt/react';`
7
+
8
+ ## The column model (KptColumn)
9
+ `{ field, header, sortable?, align?, width?, frozen?, filter?, edit?, summary? }`
10
+ `frozen` columns (leading, adjacent) stick during horizontal scrolling. Their offsets come from `width`:
11
+ `px`/`rem`/`em` are computed up front, other units (`%`, `ch`) and a missing width are measured from the
12
+ rendered header.
13
+
14
+ - `filter`: `KptColumnFilter` from `@konce-pt/table` - `text`, `number`, `select` (with `multiple`),
15
+ `numberRange`, `slider`, `dateRange`. Any column with a `filter` renders the filter row.
16
+ - `edit`: `{ type: 'text' | 'number' | 'date' | 'select' | 'multiselect', options?, placeholder?, min?, max?, step? }`
17
+ - `summary`: `{ fn: 'sum' | 'avg' | 'min' | 'max' | 'count' | ((rows) => unknown), format? }`
18
+
19
+ ## Props
20
+ - `columns` (required), `data`
21
+ - `filterable`, `filterRowPosition` (`'bottom'` default), `pageSize` (0 = no pagination),
22
+ `pageSizeOptions`, `selectable` (`'none' | 'single' | 'multiple'`), `loading`, `emptyMessage`,
23
+ `rowKey`, `scrollHeight`, `virtualScroll` (rows **and** columns, see below), `columnWidth`
24
+ ('10rem'), `rowHeight` (41), `reorderable`, `frozenSystemColumns` (sticks the expand/select columns even
25
+ without `frozen` columns), `exportable`,
26
+ `exportFilename`, `lazy`, `totalRecords`, `expandable`, `multiExpand`, `summaryLabel`,
27
+ `summaryValues`
28
+ - `ariaLabel` (the table's name without a visible caption), `caption` (a visible `<caption>`),
29
+ `clickableRows` (rows focusable and activated with Enter/Space; on by default when `onRowClick` is set)
30
+ - Controllable state: `selection`, `expandedRows`, `hiddenFields` (each with `default*` and
31
+ `on*Change`)
32
+ - Events: `onRowClick`, `onLazyLoad` (also once on start, for the first page), `onCellEdit`
33
+
34
+ ## Keyboard
35
+ - A sortable header is a button: Tab to it, Enter/Space cycles asc -> desc -> none; `aria-sort` is on the `<th>`.
36
+ - With `reorderable` the grip is a button: `ArrowLeft`/`ArrowRight` move the column by one place; the new position is
37
+ announced and focus follows the grip.
38
+ - An editable cell is reachable with Tab and opens with Enter; its name stays its value and
39
+ "Edit: {column}" is its description.
40
+ - `selectable="single"` renders radios (one group per table).
41
+
42
+ ## Templates are render props
43
+ - `cells`: `Record<field, (row, value) => ReactNode>` - the equivalent of `kptCell`
44
+ - `cellEditors`: `Record<field, (context) => ReactNode>` - the equivalent of `kptCellEdit`;
45
+ the context carries `value`, `row`, `commit(value)`, `cancel()`
46
+ - `renderRowDetail(row)` - the expanded row's content
47
+ - `paginatorActions` - the slot to the left of the paginator (a column-toggle button, say)
48
+
49
+ ## The logic lives in a package
50
+ Filter matching (the global filter and the text filter ignore case and diacritics: "lodz" finds
51
+ "Łódź"), sorting (`Intl.Collator` for the active language, natural numbers, empty cells last),
52
+ aggregations, the CSV file (`;`, CRLF, BOM) and cell-to-text come from `@konce-pt/table` - pure
53
+ functions with `node --test` coverage, shared with the Angular port. What stays here is the state
54
+ and the markup.
55
+
56
+ ## Export as a function, not a method
57
+ Angular exposes `exportCsv()` on the component instance; React has no equivalent, so the same job is
58
+ `exportTableCsv(columns, rows, filename)`, exported from the package. The `exportable` toolbar
59
+ button calls exactly that, over the currently visible columns and the filtered, sorted rows.
60
+
61
+ ## Inline editing never commits on blur of the control
62
+ Controls with a panel (`date`, `select`, `multiselect`) open immediately and commit when the panel
63
+ closes; the rest commit when focus leaves **the whole editor**. `KptInputNumber` has focusable
64
+ `+`/`-` buttons beside the field, so reacting to the control's own blur would close the editor on
65
+ every arrow click. `cellEdit` fires only when the value actually changed (arrays are compared by
66
+ content).
67
+
68
+ ## The summary covers the filtered set, not the page
69
+ Aggregations run over every row after filtering - page 1 and all the rest - so paging does not move
70
+ them while the search box does. With `lazy` the table only holds one page, so it computes nothing:
71
+ `summaryValues` is then the only source.
72
+
73
+ ## Large data sets (virtualScroll)
74
+ Tested at 20,000 rows x 100 columns: a few hundred cells live in the DOM, scrolling, search, sorting and
75
+ "select all" stay free of long tasks.
76
+
77
+ <KptDataTable columns={cols} data={rows} virtualScroll scrollHeight="480px"
78
+ filterable selectable="multiple" rowKey="id" />
79
+
80
+ - Rows: a fixed `rowHeight` (px). Columns: the table switches to `table-layout: fixed` with a `<colgroup>`;
81
+ a column width comes from `width` in `px`/`rem`/`em`, anything else (no width, `%`, `ch`) gets
82
+ `columnWidth`. Leading `frozen` columns are always rendered, the rest is windowed horizontally.
83
+ - Scrolling is read once per animation frame and re-renders only when the row or column window
84
+ changes, not on every pixel.
85
+ - `aria-rowcount`/`aria-colcount` on the table and `aria-rowindex`/`aria-colindex` on rows and cells
86
+ give assistive technology the real size, not the window.
87
+ - Global search on sets above 2,000 rows waits ~150 ms for a pause in typing; the folded text of every
88
+ row is prepared in idle time after the data arrives, so the first keystroke does not pay for the set.
89
+ Rows are treated as immutable - replace a changed row object instead of mutating it in place.
90
+ - A new search, column filter or sort scrolls back to the top.
91
+ - Not available in this mode: pagination and expandable rows.
92
+ - Selection uses `rowKey` (or the row reference) in a `Set` - selecting 20,000 rows is O(n).
93
+
94
+ ## Examples
95
+ <KptDataTable columns={cols} data={rows} filterable pageSize={10} selectable="multiple" rowKey="id" />
96
+
97
+ <KptDataTable
98
+ columns={cols}
99
+ data={rows}
100
+ rowKey="id"
101
+ cells={{ status: (row, value) => <span className="badge">{String(value)}</span> }}
102
+ onCellEdit={(event) => save(event.updatedRow)}
103
+ />
104
+
105
+ ## i18n
106
+ The toolbar, the states and the filter labels come from the `dataTable` namespace (`search`,
107
+ `exportCsv`, `loading`, `empty`, `total`, `selectAll`, `selectRow`, `expandRow`, `editCell`,
108
+ `filter` / `filterMin` / `filterMax` with `{column}`, `all`, `min`, `max`, `dateRange`, `moveColumn`,
109
+ `columnMoved`).
110
+
111
+ ## Tokens
112
+ `--kpt-table-{bg,fg,border,radius,header-bg,header-fg,row-hover,row-selected,cell-padding}`,
113
+ the expanded row `--kpt-table-detail-bg`, the summary row `--kpt-table-summary-bg`.
114
+
115
+ ## Not ported yet
116
+ Grouped columns (absent in the Angular port too). A ready column-toggle UI is not part of either
117
+ port - `hiddenFields` is the hook to build one on.
118
+
119
+ ## Filter by voice
120
+ - `filterSpeech`: boolean = false (needs `filterable`) - a microphone in the global filter field. A click
121
+ clears the filter and one spoken phrase becomes the new filter, with the same debounce for large data
122
+ as typing. Hidden without browser support.
123
+ - `filterSpeechLang`: string - BCP 47 tag; without it from `KptI18nProvider`.
124
+ - `filterSpeechColor`: `'primary' | 'danger' | 'success' | 'warning' | 'info'` = `'primary'` - colour of "stop" and the wave while listening.
125
+ The filter field now sits in `.kpt-data-table__search` (the box that positions the microphone).
126
+
127
+ <KptDataTable columns={columns} data={rows} filterable filterSpeech />
@@ -1,4 +1,5 @@
1
1
  import { type ComponentPropsWithRef, type ReactNode } from 'react';
2
+ import { type KptLayoutMotion } from '@konce-pt/motion';
2
3
  import { type KptI18nOverrides } from '../i18n/i18n-context.tsx';
3
4
  export type KptDataViewLayout = 'list' | 'grid';
4
5
  export interface KptDataViewProps<T> extends Omit<ComponentPropsWithRef<'div'>, 'children'>, KptI18nOverrides {
@@ -6,7 +7,7 @@ export interface KptDataViewProps<T> extends Omit<ComponentPropsWithRef<'div'>,
6
7
  layout?: KptDataViewLayout;
7
8
  defaultLayout?: KptDataViewLayout;
8
9
  onLayoutChange?: (layout: KptDataViewLayout) => void;
9
- /** Rozmiar strony; 0 wyłącza stronicowanie. Sterowalny — select paginatora go zmienia. */
10
+ /** Rozmiar strony; 0 wyłącza stronicowanie. Sterowalny - select paginatora go zmienia. */
10
11
  pageSize?: number;
11
12
  defaultPageSize?: number;
12
13
  onPageSizeChange?: (pageSize: number) => void;
@@ -18,16 +19,23 @@ export interface KptDataViewProps<T> extends Omit<ComponentPropsWithRef<'div'>,
18
19
  onGridColumnsChange?: (columns: number) => void;
19
20
  /** Wartości w pasku gęstości. Mniej niż dwie = paska nie ma po co pokazywać. */
20
21
  gridColumnsOptions?: readonly number[];
21
- /** Najwęższa sensowna karta — poniżej tego siatka zdejmuje kolumnę, zamiast ściskać. */
22
+ /** Najwęższa sensowna karta - poniżej tego siatka zdejmuje kolumnę, zamiast ściskać. */
22
23
  gridMinWidth?: string;
23
24
  paginated?: boolean;
24
- /** Szablon elementu — odpowiednik `<ng-template let-item>` z Angulara. */
25
+ /**
26
+ * Ruch przy zmianie układu i gęstości z paska: `spring` - karty płyną na sprężynie,
27
+ * `arc` - unoszą się i lecą po łuku, `morph` - natywny morf przeglądarki (View Transitions),
28
+ * `none` - bez ruchu. Bez wartości bierze `layout` z `KptMotionProvider` (domyślnie
29
+ * `spring`); `<KptMotionProvider enabled={false}>` i systemowe "ogranicz ruch" wyłączają go zawsze.
30
+ */
31
+ layoutMotion?: KptLayoutMotion;
32
+ /** Szablon elementu - odpowiednik `<ng-template let-item>` z Angulara. */
25
33
  renderItem: (item: T, index: number) => ReactNode;
26
34
  }
27
35
  /**
28
- * DataView — lista elementów w układzie listy albo siatki, z opcjonalnym stronicowaniem.
36
+ * DataView - lista elementów w układzie listy albo siatki, z opcjonalnym stronicowaniem.
29
37
  *
30
38
  * @example
31
39
  * <KptDataView items={products} defaultPageSize={6} renderItem={(p) => <div>{p.name}</div>} />
32
40
  */
33
- export declare function KptDataView<T>({ items, layout, defaultLayout, onLayoutChange, pageSize, defaultPageSize, onPageSizeChange, pageSizeOptions, gridColumns, defaultGridColumns, onGridColumnsChange, gridColumnsOptions, gridMinWidth, paginated, renderItem, locale, dictionary, className, ...rest }: Readonly<KptDataViewProps<T>>): import("react").JSX.Element;
41
+ export declare function KptDataView<T>({ items, layout, defaultLayout, onLayoutChange, pageSize, defaultPageSize, onPageSizeChange, pageSizeOptions, gridColumns, defaultGridColumns, onGridColumnsChange, gridColumnsOptions, gridMinWidth, paginated, layoutMotion, renderItem, locale, dictionary, className, ...rest }: Readonly<KptDataViewProps<T>>): import("react").JSX.Element;
@@ -1,18 +1,25 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useState } from 'react';
3
+ import { useId, useLayoutEffect, useRef, useState } from 'react';
4
+ import { flushSync } from 'react-dom';
5
+ import { layoutMotionAllowed, morphLayout, playLayoutMotion, resolveLayoutMotion, snapshotLayout, stopLayoutMotion, } from '@konce-pt/motion';
4
6
  import { cn } from "../internal/cn.js";
5
7
  import { useControllableState } from "../internal/use-controllable-state.js";
6
8
  import { useKptMessages } from "../i18n/i18n-context.js";
7
9
  import { KptIcon } from "../icon/icon.js";
8
10
  import { KptPaginator } from "../paginator/paginator.js";
11
+ import { useKptMotion } from "../motion/motion-context.js";
12
+ /** Klasa elementu w locie (przycięcie treści, warstwa nad sąsiadami). */
13
+ const MOVING = 'kpt-data-view__item--moving';
14
+ /** Klasa View Transitions dla morfu - reguły `::view-transition-*` są we wspólnym CSS. */
15
+ const MORPH_CLASS = 'kpt-data-view-morph';
9
16
  /**
10
- * DataView — lista elementów w układzie listy albo siatki, z opcjonalnym stronicowaniem.
17
+ * DataView - lista elementów w układzie listy albo siatki, z opcjonalnym stronicowaniem.
11
18
  *
12
19
  * @example
13
20
  * <KptDataView items={products} defaultPageSize={6} renderItem={(p) => <div>{p.name}</div>} />
14
21
  */
15
- export function KptDataView({ items = [], layout, defaultLayout = 'grid', onLayoutChange, pageSize, defaultPageSize = 0, onPageSizeChange, pageSizeOptions = [], gridColumns, defaultGridColumns = 0, onGridColumnsChange, gridColumnsOptions = [], gridMinWidth = '10rem', paginated = true, renderItem, locale, dictionary, className, ...rest }) {
22
+ export function KptDataView({ items = [], layout, defaultLayout = 'grid', onLayoutChange, pageSize, defaultPageSize = 0, onPageSizeChange, pageSizeOptions = [], gridColumns, defaultGridColumns = 0, onGridColumnsChange, gridColumnsOptions = [], gridMinWidth = '10rem', paginated = true, layoutMotion, renderItem, locale, dictionary, className, ...rest }) {
16
23
  const { t } = useKptMessages({ locale, dictionary });
17
24
  const [currentLayout, setLayout] = useControllableState({
18
25
  value: layout,
@@ -30,14 +37,68 @@ export function KptDataView({ items = [], layout, defaultLayout = 'grid', onLayo
30
37
  onChange: onGridColumnsChange,
31
38
  });
32
39
  const [pageIndex, setPageIndex] = useState(0);
33
- // Opcje selecta: własna lista albo — gdy pusta — sam bieżący rozmiar.
40
+ const motionConfig = useKptMotion();
41
+ const contentRef = useRef(null);
42
+ const pendingRef = useRef(null);
43
+ // `view-transition-name` musi być poprawnym identyfikatorem CSS - `useId` daje dwukropki.
44
+ const morphPrefix = `kpt-data-view-${useId().replaceAll(/[^a-zA-Z0-9-]/g, '')}`;
45
+ /**
46
+ * Zmiana z paska z ruchem. Stan sprzed zmiany mierzymy tu, zanim React zmieni DOM - dlatego
47
+ * animujemy tylko zmiany z paska, a układ ustawiony z zewnątrz przełącza się od razu.
48
+ */
49
+ const changeWithMotion = (apply, origin) => {
50
+ const motion = resolveLayoutMotion(layoutMotion, motionConfig);
51
+ const content = contentRef.current;
52
+ if (motion === 'none' || !content || !layoutMotionAllowed()) {
53
+ apply();
54
+ return;
55
+ }
56
+ const nodes = itemsOf(content);
57
+ if (motion === 'morph') {
58
+ morphLayout(nodes, morphPrefix, MORPH_CLASS, () => flushSync(apply));
59
+ return;
60
+ }
61
+ pendingRef.current = { snapshot: snapshotLayout(content, nodes, origin), motion };
62
+ stopLayoutMotion(content, MOVING);
63
+ apply();
64
+ };
65
+ // Nowy układ jest już w DOM - gramy loty od zapamiętanego stanu.
66
+ useLayoutEffect(() => {
67
+ const pending = pendingRef.current;
68
+ pendingRef.current = null;
69
+ const content = contentRef.current;
70
+ if (!pending || !content)
71
+ return;
72
+ playLayoutMotion(content, itemsOf(content), pending.snapshot, {
73
+ motion: pending.motion,
74
+ movingClass: MOVING,
75
+ innerOf: bodyOf,
76
+ });
77
+ }, [currentLayout, columns]);
78
+ // Opcje selecta: własna lista albo - gdy pusta - sam bieżący rozmiar.
34
79
  const pagerSizeOptions = pageSizeOptions.length ? pageSizeOptions : [size];
35
80
  // Pager zostaje na ekranie także wtedy, gdy wszystko mieści się na jednej stronie, o ile jest
36
81
  // w czym wybierać. Bez tego wybranie największego rozmiaru chowa select, którym użytkownik
37
- // właśnie się posłużył — i nie ma jak wrócić do mniejszego.
82
+ // właśnie się posłużył - i nie ma jak wrócić do mniejszego.
38
83
  // Pasek gęstości ma sens tylko w siatce i tylko wtedy, gdy jest w czym wybierać.
39
84
  const showColumns = currentLayout === 'grid' && gridColumnsOptions.length > 1;
40
85
  const showPager = paginated && size > 0 && (items.length > size || pagerSizeOptions.length > 1);
41
86
  const pageItems = !paginated || size <= 0 ? items : items.slice(pageIndex * size, pageIndex * size + size);
42
- return (_jsx("div", { className: cn('kpt-data-view-host', className), ...rest, children: _jsxs("div", { className: "kpt-data-view", children: [_jsxs("div", { className: "kpt-data-view__toolbar", children: [_jsx("div", { className: "kpt-data-view__count", children: t('dataView.count', { count: items.length }) }), _jsxs("div", { className: "kpt-data-view__controls", children: [showColumns ? (_jsx("div", { className: "kpt-data-view__columns", role: "group", "aria-label": t('dataView.columns'), children: gridColumnsOptions.map((n) => (_jsxs("button", { type: "button", className: cn(columns === n && 'is-active'), "aria-pressed": columns === n, onClick: () => setColumns(n), children: [_jsx(KptIcon, { name: "grid-dots" }), n] }, n))) })) : null, _jsxs("div", { className: "kpt-data-view__switch", children: [_jsx("button", { type: "button", className: cn(currentLayout === 'list' && 'is-active'), "aria-label": t('dataView.list'), "aria-pressed": currentLayout === 'list', onClick: () => setLayout('list'), children: _jsx(KptIcon, { name: "list" }) }), _jsx("button", { type: "button", className: cn(currentLayout === 'grid' && 'is-active'), "aria-label": t('dataView.grid'), "aria-pressed": currentLayout === 'grid', onClick: () => setLayout('grid'), children: _jsx(KptIcon, { name: "layout-grid" }) })] })] })] }), _jsx("div", { className: "kpt-data-view__content", "data-layout": currentLayout, "data-columns": columns ? '' : undefined, style: { '--_min': gridMinWidth, '--_cols': columns || undefined }, children: pageItems.length ? (pageItems.map((item, index) => (_jsx("div", { className: "kpt-data-view__item", children: renderItem(item, index) }, index)))) : (_jsx("div", { className: "kpt-data-view__empty", children: t('dataView.empty') })) }), showPager ? (_jsx(KptPaginator, { length: items.length, pageIndex: pageIndex, onPageIndexChange: setPageIndex, pageSize: size, onPageSizeChange: setSize, pageSizeOptions: pagerSizeOptions })) : null] }) }));
87
+ return (_jsx("div", { className: cn('kpt-data-view-host', className), ...rest, children: _jsxs("div", { className: "kpt-data-view", children: [_jsxs("div", { className: "kpt-data-view__toolbar", children: [_jsx("div", { className: "kpt-data-view__count", children: t('dataView.count', { count: items.length }) }), _jsxs("div", { className: "kpt-data-view__controls", children: [showColumns ? (_jsx("div", { className: "kpt-data-view__columns", role: "group", "aria-label": t('dataView.columns'), children: gridColumnsOptions.map((n) => (_jsxs("button", { type: "button", className: cn(columns === n && 'is-active'), "aria-pressed": columns === n, onClick: (e) => {
88
+ if (n !== columns)
89
+ changeWithMotion(() => setColumns(n), e.currentTarget);
90
+ }, children: [_jsx(KptIcon, { name: "grid-dots" }), n] }, n))) })) : null, _jsxs("div", { className: "kpt-data-view__switch", children: [_jsx("button", { type: "button", className: cn(currentLayout === 'list' && 'is-active'), "aria-label": t('dataView.list'), "aria-pressed": currentLayout === 'list', onClick: (e) => {
91
+ if (currentLayout !== 'list')
92
+ changeWithMotion(() => setLayout('list'), e.currentTarget);
93
+ }, children: _jsx(KptIcon, { name: "list" }) }), _jsx("button", { type: "button", className: cn(currentLayout === 'grid' && 'is-active'), "aria-label": t('dataView.grid'), "aria-pressed": currentLayout === 'grid', onClick: (e) => {
94
+ if (currentLayout !== 'grid')
95
+ changeWithMotion(() => setLayout('grid'), e.currentTarget);
96
+ }, children: _jsx(KptIcon, { name: "layout-grid" }) })] })] })] }), _jsx("div", { ref: contentRef, className: "kpt-data-view__content", "data-layout": currentLayout, "data-columns": columns ? '' : undefined, style: { '--_min': gridMinWidth, '--_cols': columns || undefined }, children: pageItems.length ? (pageItems.map((item, index) => (_jsx("div", { className: "kpt-data-view__item", children: _jsx("div", { className: "kpt-data-view__body", children: renderItem(item, index) }) }, index)))) : (_jsx("div", { className: "kpt-data-view__empty", children: t('dataView.empty') })) }), showPager ? (_jsx(KptPaginator, { length: items.length, pageIndex: pageIndex, onPageIndexChange: setPageIndex, pageSize: size, onPageSizeChange: setSize, pageSizeOptions: pagerSizeOptions })) : null] }) }));
97
+ }
98
+ function itemsOf(content) {
99
+ return Array.from(content.children).filter((el) => el.classList.contains('kpt-data-view__item'));
100
+ }
101
+ function bodyOf(item) {
102
+ const body = item.firstElementChild;
103
+ return body instanceof HTMLElement ? body : null;
43
104
  }
@@ -8,10 +8,10 @@ Import: `import { KptDataView } from '@konce-pt/react';`
8
8
  <div class="kpt-data-view">
9
9
  <div class="kpt-data-view__toolbar">
10
10
  <div class="kpt-data-view__count">8 items</div>
11
- <div class="kpt-data-view__switch">…list, grid…</div>
11
+ <div class="kpt-data-view__switch">...list, grid...</div>
12
12
  </div>
13
13
  <div class="kpt-data-view__content" data-layout="grid">
14
- <div class="kpt-data-view__item">…</div>
14
+ <div class="kpt-data-view__item"><div class="kpt-data-view__body">...</div></div>
15
15
  </div>
16
16
  <!-- KptPaginator -->
17
17
  </div>
@@ -19,19 +19,20 @@ Import: `import { KptDataView } from '@konce-pt/react';`
19
19
 
20
20
  ## Props
21
21
  - `items`: `T[]`
22
- - `layout` / `defaultLayout` / `onLayoutChange` — `'list' | 'grid'` (default `'grid'`)
23
- - `pageSize` / `defaultPageSize` / `onPageSizeChange` — number; 0 turns pagination off
22
+ - `layout` / `defaultLayout` / `onLayoutChange` - `'list' | 'grid'` (default `'grid'`)
23
+ - `pageSize` / `defaultPageSize` / `onPageSizeChange` - number; 0 turns pagination off
24
24
  - `pageSizeOptions`: number[] (empty = the select offers the current size only)
25
- - `gridColumns` / `defaultGridColumns` / `onGridColumnsChange` — number; 0 = as many as fit
25
+ - `gridColumns` / `defaultGridColumns` / `onGridColumnsChange` - number; 0 = as many as fit
26
26
  - `gridColumnsOptions`: number[] (fewer than two = no density bar)
27
- - `gridMinWidth`: string (default `10rem`) — the narrowest card worth rendering
27
+ - `gridMinWidth`: string (default `10rem`) - the narrowest card worth rendering
28
28
  - `paginated`: boolean (default true)
29
- - `renderItem(item, index)` — required; the equivalent of `<ng-template let-item>`
29
+ - `layoutMotion`: `'spring' | 'arc' | 'morph' | 'none'` (default from `KptMotionProvider`, else `spring`) - see below
30
+ - `renderItem(item, index)` - required; the equivalent of `<ng-template let-item>`
30
31
  - `className`, `ref` and every other `<div>` prop go to the host
31
32
 
32
33
  ## The layout is an attribute
33
- `data-layout` on the content switches the grid rules; the toolbar only flips it. Everything else —
34
- the item's markup — is the caller's, which is why there are no card props here.
34
+ `data-layout` on the content switches the grid rules; the toolbar only flips it. Everything else -
35
+ the item's markup - is the caller's, which is why there are no card props here.
35
36
 
36
37
  ## The column count is a ceiling
37
38
  The density bar shows up in the grid layout when `gridColumnsOptions` holds more than one value.
@@ -41,7 +42,7 @@ below `gridMinWidth`.
41
42
 
42
43
  ## The pager appears when it is needed
43
44
  Only when `paginated`, the page size is above 0, and either the items outgrow one page or
44
- `pageSizeOptions` holds more than one size — a paginator under a single page of results is noise,
45
+ `pageSizeOptions` holds more than one size - a paginator under a single page of results is noise,
45
46
  but hiding it right after someone picks the largest size would strand them there.
46
47
 
47
48
  ## Examples
@@ -54,6 +55,24 @@ but hiding it right after someone picks the largest size would strand them there
54
55
  The count, the two switch buttons and the density group come from the `dataView` namespace
55
56
  (`count` with `{count}`, `list`, `grid`, `columns`, `empty`).
56
57
 
58
+ ## Layout motion
59
+ `layoutMotion` animates a layout or density change made from the built-in bar:
60
+ - `spring` - each card glides from its old place to the new one on a spring and resizes; the
61
+ content is counter-scaled, so it never stretches. A light cascade from the first item.
62
+ - `arc` - cards lift (shadow, slight zoom), fly along an arc tilted toward the move and land
63
+ softly; the wave starts at the clicked button.
64
+ - `morph` - the browser's own morph (View Transitions): frames morph, old and new content
65
+ cross-fade, clipped rather than stretched. Without browser support the change is instant. A view
66
+ transition covers the whole document and blocks clicks for ~0.6 s.
67
+ - `none` - no motion.
68
+
69
+ With no value it takes `layout` from `KptMotionProvider` (default `spring`); `enabled: false` there and
70
+ the system "reduce motion" setting always win. A click in the middle of a flight starts the next
71
+ one from where the cards are on screen. A layout set from outside (`layout`, `gridColumns`) switches instantly - the
72
+ old state has to be measured before the DOM changes.
73
+
74
+ <KptDataView items={products} layoutMotion="morph" renderItem={renderCard} />
75
+
57
76
  ## Tokens
58
77
  The grid gap `--kpt-space-3`, the active switch `--kpt-color-primary`.
59
78
 
@@ -7,16 +7,16 @@ export interface KptDateRangeProps extends Omit<ComponentPropsWithRef<'div'>, 'o
7
7
  defaultValue?: KptDateRangeValue;
8
8
  onValueChange?: (value: KptDateRangeValue) => void;
9
9
  mode?: KptDateRangeMode;
10
- /** Liczba miesięcy obok siebie (1–3). Ignorowana w trybie 'time'. */
10
+ /** Liczba miesięcy obok siebie (1-3). Ignorowana w trybie 'time'. */
11
11
  visibleMonths?: number;
12
12
  hourFormat?: 12 | 24;
13
13
  minuteStep?: number;
14
14
  placeholder?: string;
15
15
  /** Zapis dat: `'pl'` (domyślnie), `'iso'` albo `'locale'` (`Intl` dla aktywnego języka). */
16
16
  displayFormat?: KptDateDisplayFormat;
17
- /** Pierwszy dzień tygodnia (1 = poniedziałek … 7 = niedziela); `null` = wg aktywnego języka. */
17
+ /** Pierwszy dzień tygodnia (1 = poniedziałek ... 7 = niedziela); `null` = wg aktywnego języka. */
18
18
  firstDayOfWeek?: KptFirstDayOfWeek | null;
19
- /** Stan panelu — pozwala otworzyć go z zewnątrz i wiedzieć, kiedy wybór się skończył. */
19
+ /** Stan panelu - pozwala otworzyć go z zewnątrz i wiedzieć, kiedy wybór się skończył. */
20
20
  open?: boolean;
21
21
  onOpenChange?: (open: boolean) => void;
22
22
  /** Najwcześniejsza dozwolona data 'RRRR-MM-DD' (włącznie). */
@@ -25,12 +25,12 @@ export interface KptDateRangeProps extends Omit<ComponentPropsWithRef<'div'>, 'o
25
25
  maxDate?: string | null;
26
26
  /** Nazwa dostępna pola, gdy nie opisuje go `<label for>`. */
27
27
  ariaLabel?: string | null;
28
- /** Id pola (nie hosta); bez niego generowane, w `KptFormField` — z wrappera. */
28
+ /** Id pola (nie hosta); bez niego generowane, w `KptFormField` - z wrappera. */
29
29
  id?: string;
30
30
  disabled?: boolean;
31
- /** Tylko do odczytu — wartość widać, panel się nie otwiera (`aria-readonly`). */
31
+ /** Tylko do odczytu - wartość widać, panel się nie otwiera (`aria-readonly`). */
32
32
  readOnly?: boolean;
33
- /** Pole wymagane — `aria-required`. */
33
+ /** Pole wymagane - `aria-required`. */
34
34
  required?: boolean;
35
35
  invalid?: boolean;
36
36
  touched?: boolean;
@@ -41,10 +41,10 @@ export interface KptDateRangeProps extends Omit<ComponentPropsWithRef<'div'>, 'o
41
41
  * `visibleMonths` pokazuje kilka miesięcy obok siebie, a zakres podświetla się ciągłym pasmem
42
42
  * przez wszystkie panele.
43
43
  *
44
- * Klawiatura jak w `KptDatepicker`: `Enter`/`Spacja`/`↓` otwierają panel z fokusem na początku
45
- * zakresu (albo dziś), strzałki, `Home`/`End` i `PageUp`/`PageDown` (z `Shift` — rok) chodzą po
44
+ * Klawiatura jak w `KptDatepicker`: `Enter`/`Spacja`/`ArrowDown` otwierają panel z fokusem na początku
45
+ * zakresu (albo dziś), strzałki, `Home`/`End` i `PageUp`/`PageDown` (z `Shift` - rok) chodzą po
46
46
  * dniach przez wszystkie panele, `Tab` krąży w panelu, `Escape` i wybór końca oddają fokus polu.
47
- * Krańce i środek zakresu są w nazwie dnia („…, początek zakresu”), a wybór i przewinięcie miesiąca
47
+ * Krańce i środek zakresu są w nazwie dnia ("..., początek zakresu"), a wybór i przewinięcie miesiąca
48
48
  * ogłasza region `polite`. Pole to `role="combobox"` z `aria-haspopup="dialog"`, więc niesie
49
49
  * `aria-required`, `aria-readonly` i `aria-invalid`. Tydzień zaczyna się wg aktywnego języka.
50
50
  *