@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
package/dist/map/map.d.ts CHANGED
@@ -2,7 +2,8 @@ import type { KptClusterOptions, KptLatLng, KptMapBounds, KptMapCategory, KptMap
2
2
  import { type ComponentPropsWithRef, type ReactNode } from 'react';
3
3
  import { type KptI18nOverrides } from '../i18n/i18n-context.tsx';
4
4
  import type { KptMapGeocoderPort, KptMapGeolocationPort } from './ports.ts';
5
- /** Kontekst treści popupu — odpowiednik kontekstu szablonu `kptMapPopup` z portu Angulara. */
5
+ import type { KptSpeechColor } from '../speech/speech-button.tsx';
6
+ /** Kontekst treści popupu - odpowiednik kontekstu szablonu `kptMapPopup` z portu Angulara. */
6
7
  export interface KptMapPopupContext<T> {
7
8
  location: KptMapLocation<T>;
8
9
  data: T | undefined;
@@ -11,7 +12,7 @@ export interface KptMapPopupContext<T> {
11
12
  distance: number | null;
12
13
  close: () => void;
13
14
  }
14
- /** Kontekst własnego formularza „dodaj lokalizację". */
15
+ /** Kontekst własnego formularza "dodaj lokalizację". */
15
16
  export interface KptMapCreateFormApi {
16
17
  at: KptLatLng;
17
18
  category: KptMapCategory;
@@ -21,7 +22,7 @@ export interface KptMapCreateFormApi {
21
22
  export interface KptMapProps<T = unknown> extends Omit<ComponentPropsWithRef<'div'>, 'children' | 'onSelect'>, KptI18nOverrides {
22
23
  locations: readonly KptMapLocation<T>[];
23
24
  categories: readonly KptMapCategory[];
24
- /** Kod kraju z presetów (`PL`, `DE`, `EU`…). Nieznany kod cofa się do Polski. */
25
+ /** Kod kraju z presetów (`PL`, `DE`, `EU`...). Nieznany kod cofa się do Polski. */
25
26
  country?: string;
26
27
  /** Jawny widok startowy; nadpisuje `country`. */
27
28
  view?: KptMapView | null;
@@ -36,16 +37,16 @@ export interface KptMapProps<T = unknown> extends Omit<ComponentPropsWithRef<'di
36
37
  /** Renderuje legendę pod mapą. */
37
38
  legend?: boolean;
38
39
  legendCounts?: boolean;
39
- /** Identyfikatory ukrytych kategorii — kontrolowane albo niekontrolowane. */
40
+ /** Identyfikatory ukrytych kategorii - kontrolowane albo niekontrolowane. */
40
41
  hiddenCategories?: string[];
41
42
  defaultHiddenCategories?: string[];
42
43
  onHiddenCategoriesChange?: (hidden: string[]) => void;
43
44
  showUserLocation?: boolean;
44
45
  /** Przy każdej nowej pozycji centruje mapę na użytkowniku. */
45
46
  followUser?: boolean;
46
- /** Źródło pozycji użytkownika. Bez niego kontrolka „moje położenie" nie ma czego pokazać. */
47
+ /** Źródło pozycji użytkownika. Bez niego kontrolka "moje położenie" nie ma czego pokazać. */
47
48
  geolocation?: KptMapGeolocationPort | null;
48
- /** Włącza menu „Dodaj lokalizację" pod prawym przyciskiem myszy. */
49
+ /** Włącza menu "Dodaj lokalizację" pod prawym przyciskiem myszy. */
49
50
  allowCreate?: boolean;
50
51
  /** Pokazuje wyszukiwarkę adresów. Wymaga geokodera **z metodą `search()`**. */
51
52
  search?: boolean;
@@ -60,29 +61,35 @@ export interface KptMapProps<T = unknown> extends Omit<ComponentPropsWithRef<'di
60
61
  searchZoom?: number;
61
62
  /** Zostawia tymczasową pinezkę w znalezionym punkcie. */
62
63
  searchMarker?: boolean;
63
- /** Geokoder tej mapy — obsługuje i wyszukiwarkę, i podpowiedzi adresu w formularzu. */
64
+ /** Mikrofon w wyszukiwarce - adres podyktowany zamiast wpisanego (patrz `KptMapSearch`). */
65
+ searchSpeech?: boolean;
66
+ /** Język dyktowania adresu (BCP 47); bez niego z `KptI18nProvider`. */
67
+ searchSpeechLang?: string;
68
+ /** Kolor "stop" i fali w trakcie nasłuchu; domyślnie kolor motywu. */
69
+ searchSpeechColor?: KptSpeechColor;
70
+ /** Geokoder tej mapy - obsługuje i wyszukiwarkę, i podpowiedzi adresu w formularzu. */
64
71
  geocoder?: KptMapGeocoderPort | null;
65
72
  /** `card` oddaje popup w całości treści: bez paddingu, szerszy, z przewijaniem. */
66
73
  popupLayout?: 'plain' | 'card';
67
74
  /** Punkt odniesienia dystansu w popupie; `null` = pozycja użytkownika. */
68
75
  distanceFrom?: KptLatLng | null;
69
76
  height?: string;
70
- /** Bez znaczenia dla silnika Google — kafle i atrybucję dostarcza tam Google. */
77
+ /** Bez znaczenia dla silnika Google - kafle i atrybucję dostarcza tam Google. */
71
78
  tileUrl?: string | null;
72
79
  attribution?: string | null;
73
80
  /**
74
- * Fabryka silnika tej mapy. W Reakcie nie ma DI, więc to jedyna droga — i dobrze:
81
+ * Fabryka silnika tej mapy. W Reakcie nie ma DI, więc to jedyna droga - i dobrze:
75
82
  * dwie mapy o różnych silnikach mieszczą się na stronie bez żadnych opakowań.
76
83
  * Czytana raz, przy inicjalizacji.
77
84
  */
78
85
  engine: KptMapEngineFactory;
79
86
  /** Treść popupu. Bez niej popup pokazuje tytuł i nazwę kategorii. */
80
87
  renderPopup?: (context: KptMapPopupContext<T>) => ReactNode;
81
- /** Własny formularz „dodaj lokalizację"; jego obecność wyłącza formularz ze schemy. */
88
+ /** Własny formularz "dodaj lokalizację"; jego obecność wyłącza formularz ze schemy. */
82
89
  renderCreateForm?: (api: KptMapCreateFormApi) => ReactNode;
83
90
  onLocationClick?: (location: KptMapLocation<T>) => void;
84
91
  onClusterClick?: (cluster: KptMapCluster<T>) => void;
85
- /** Komponent **nie dopisuje** nic do `locations` — źródłem prawdy jest aplikacja. */
92
+ /** Komponent **nie dopisuje** nic do `locations` - źródłem prawdy jest aplikacja. */
86
93
  onLocationCreate?: (event: KptMapCreateEvent) => void;
87
94
  /** Wybrano podpowiedź wyszukiwarki; mapa już przeniosła widok. */
88
95
  onSearchSelect?: (result: KptMapSearchResult) => void;
@@ -94,7 +101,7 @@ export interface KptMapProps<T = unknown> extends Omit<ComponentPropsWithRef<'di
94
101
  onUserPositionChange?: (position: KptMapUserPosition | null) => void;
95
102
  onUserLocationError?: (error: KptMapGeolocationError) => void;
96
103
  /**
97
- * Silnika nie udało się uruchomić — brak paczki `leaflet`, odrzucony klucz Google. Błąd i tak
104
+ * Silnika nie udało się uruchomić - brak paczki `leaflet`, odrzucony klucz Google. Błąd i tak
98
105
  * trafia do konsoli; callback pozwala aplikacji pokazać własny komunikat zamiast szarego prostokąta.
99
106
  */
100
107
  onEngineError?: (error: unknown) => void;
@@ -103,7 +110,7 @@ export interface KptMapProps<T = unknown> extends Omit<ComponentPropsWithRef<'di
103
110
  * Mapa z konfigurowalnymi znacznikami: kategorie z kolorem i ikoną, grupowanie z licznikiem,
104
111
  * popup szczegółów, legenda, wyszukiwarka adresów i dodawanie lokalizacji prawym przyciskiem.
105
112
  *
106
- * Silnik (Leaflet albo Google) przychodzi propem `engine` z `@konce-pt/map` — ta sama warstwa,
113
+ * Silnik (Leaflet albo Google) przychodzi propem `engine` z `@konce-pt/map` - ta sama warstwa,
107
114
  * na której stoi port Angulara. Leaflet ładuje się dynamicznym `import()`, więc aplikacja bez
108
115
  * mapy go nie pobiera; wymaga też arkusza `leaflet/dist/leaflet.css`.
109
116
  *
@@ -115,4 +122,4 @@ export interface KptMapProps<T = unknown> extends Omit<ComponentPropsWithRef<'di
115
122
  * renderPopup={({ location, data }) => <strong>{location.title}</strong>}
116
123
  * />
117
124
  */
118
- export declare function KptMap<T = unknown>({ locations, categories, country, view, bounds, restrictToCountry, cluster, clusterOptions, clusterColorBy, legend, legendCounts, hiddenCategories, defaultHiddenCategories, onHiddenCategoriesChange, showUserLocation, followUser, geolocation, allowCreate, search, searchPlaceholder, searchOptions, searchZoom, searchMarker, geocoder, popupLayout, distanceFrom, height, tileUrl, attribution, engine, renderPopup, renderCreateForm, onLocationClick, onClusterClick, onLocationCreate, onSearchSelect, onViewChange, onUserPositionChange, onUserLocationError, onEngineError, locale: localeOverride, dictionary, className, style, ...rest }: Readonly<KptMapProps<T>>): import("react").JSX.Element;
125
+ export declare function KptMap<T = unknown>({ locations, categories, country, view, bounds, restrictToCountry, cluster, clusterOptions, clusterColorBy, legend, legendCounts, hiddenCategories, defaultHiddenCategories, onHiddenCategoriesChange, showUserLocation, followUser, geolocation, allowCreate, search, searchPlaceholder, searchOptions, searchZoom, searchMarker, searchSpeech, searchSpeechLang, searchSpeechColor, geocoder, popupLayout, distanceFrom, height, tileUrl, attribution, engine, renderPopup, renderCreateForm, onLocationClick, onClusterClick, onLocationCreate, onSearchSelect, onViewChange, onUserPositionChange, onUserLocationError, onEngineError, locale: localeOverride, dictionary, className, style, ...rest }: Readonly<KptMapProps<T>>): import("react").JSX.Element;
package/dist/map/map.js CHANGED
@@ -6,11 +6,12 @@ import { cn } from "../internal/cn.js";
6
6
  import { useControllableState } from "../internal/use-controllable-state.js";
7
7
  import { useKptMessages } from "../i18n/i18n-context.js";
8
8
  import { getKptIcon } from "../icon/icon-registry.js";
9
+ import { KptIcon } from "../icon/icon.js";
9
10
  import { KptDialog } from "../dialog/dialog.js";
10
11
  import { KptMapCreateDialog } from "./map-create-dialog.js";
11
12
  import { KptMapLegend } from "./map-legend.js";
12
13
  import { KptMapSearch } from "./map-search.js";
13
- /** Rozmiary ikon w pikselach — silnik potrzebuje ich do zakotwiczenia znacznika. */
14
+ /** Rozmiary ikon w pikselach - silnik potrzebuje ich do zakotwiczenia znacznika. */
14
15
  const MARKER_SIZE = { width: 32, height: 42 };
15
16
  const DOT_SIZE = { width: 24, height: 24 };
16
17
  const CLUSTER_SIZE = { width: 44, height: 44 };
@@ -23,15 +24,15 @@ const POPUP_MARGIN = 16;
23
24
  * w nią niczego nie otwiera.
24
25
  */
25
26
  const SEARCH_MARKER_ID = 'kpt-map:search';
26
- /** Brak silnika to najczęstsza pomyłka przy pierwszym użyciu — komunikat niesie instrukcję. */
27
- const NO_ENGINE_ERROR = 'KptMap: brak silnika mapy. Podaj fabrykę przez prop `engine` — ' +
27
+ /** Brak silnika to najczęstsza pomyłka przy pierwszym użyciu - komunikat niesie instrukcję. */
28
+ const NO_ENGINE_ERROR = 'KptMap: brak silnika mapy. Podaj fabrykę przez prop `engine` - ' +
28
29
  '`engine={() => createLeafletEngine()}` albo ' +
29
30
  '`engine={() => createGoogleEngine({ apiKey, mapId })}` z `@konce-pt/react/map`.';
30
31
  /**
31
32
  * Mapa z konfigurowalnymi znacznikami: kategorie z kolorem i ikoną, grupowanie z licznikiem,
32
33
  * popup szczegółów, legenda, wyszukiwarka adresów i dodawanie lokalizacji prawym przyciskiem.
33
34
  *
34
- * Silnik (Leaflet albo Google) przychodzi propem `engine` z `@konce-pt/map` — ta sama warstwa,
35
+ * Silnik (Leaflet albo Google) przychodzi propem `engine` z `@konce-pt/map` - ta sama warstwa,
35
36
  * na której stoi port Angulara. Leaflet ładuje się dynamicznym `import()`, więc aplikacja bez
36
37
  * mapy go nie pobiera; wymaga też arkusza `leaflet/dist/leaflet.css`.
37
38
  *
@@ -43,26 +44,26 @@ const NO_ENGINE_ERROR = 'KptMap: brak silnika mapy. Podaj fabrykę przez prop `e
43
44
  * renderPopup={({ location, data }) => <strong>{location.title}</strong>}
44
45
  * />
45
46
  */
46
- export function KptMap({ locations, categories, country = 'PL', view = null, bounds = null, restrictToCountry = false, cluster = true, clusterOptions, clusterColorBy = 'none', legend = true, legendCounts = true, hiddenCategories, defaultHiddenCategories = [], onHiddenCategoriesChange, showUserLocation = false, followUser = false, geolocation = null, allowCreate = false, search = false, searchPlaceholder = '', searchOptions, searchZoom = 16, searchMarker = true, geocoder = null, popupLayout = 'plain', distanceFrom = null, height = '480px', tileUrl = null, attribution = null, engine, renderPopup, renderCreateForm, onLocationClick, onClusterClick, onLocationCreate, onSearchSelect, onViewChange, onUserPositionChange, onUserLocationError, onEngineError, locale: localeOverride, dictionary, className, style, ...rest }) {
47
+ export function KptMap({ locations, categories, country = 'PL', view = null, bounds = null, restrictToCountry = false, cluster = true, clusterOptions, clusterColorBy = 'none', legend = true, legendCounts = true, hiddenCategories, defaultHiddenCategories = [], onHiddenCategoriesChange, showUserLocation = false, followUser = false, geolocation = null, allowCreate = false, search = false, searchPlaceholder = '', searchOptions, searchZoom = 16, searchMarker = true, searchSpeech = false, searchSpeechLang, searchSpeechColor, geocoder = null, popupLayout = 'plain', distanceFrom = null, height = '480px', tileUrl = null, attribution = null, engine, renderPopup, renderCreateForm, onLocationClick, onClusterClick, onLocationCreate, onSearchSelect, onViewChange, onUserPositionChange, onUserLocationError, onEngineError, locale: localeOverride, dictionary, className, style, ...rest }) {
47
48
  const { t } = useKptMessages({ locale: localeOverride, dictionary });
48
49
  const canvasRef = useRef(null);
49
50
  const popupRef = useRef(null);
50
51
  const engineRef = useRef(null);
51
52
  /**
52
53
  * Łańcuch montażu i demontażu tego kontenera. Silnik mapowy oznacza element jako zajęty
53
- * na czas życia mapy, a w trybie ścisłym React montuje efekt dwa razy pod rząd — drugi
54
+ * na czas życia mapy, a w trybie ścisłym React montuje efekt dwa razy pod rząd - drugi
54
55
  * montaż musi więc poczekać, aż pierwszy skończy sprzątać.
55
56
  */
56
57
  const mountChain = useRef(Promise.resolve());
57
58
  /**
58
- * Silnik po udanym `init()` — w stanie, nie tylko w refie, bo render czyta z niego pozycje
59
+ * Silnik po udanym `init()` - w stanie, nie tylko w refie, bo render czyta z niego pozycje
59
60
  * nakładek (`project`). Ref zostaje dla handlerów zdarzeń, które żyją dłużej niż render.
60
61
  */
61
62
  const [liveEngine, setLiveEngine] = useState(null);
62
63
  const ready = liveEngine !== null;
63
64
  /** Zoom trzymamy w stanie, bo od niego zależy wynik grupowania. */
64
65
  const [zoom, setZoom] = useState(6);
65
- /** Rośnie przy każdym ruchu mapy — wymusza przeliczenie pozycji nakładek. */
66
+ /** Rośnie przy każdym ruchu mapy - wymusza przeliczenie pozycji nakładek. */
66
67
  const [viewportTick, setViewportTick] = useState(0);
67
68
  const [popup, setPopup] = useState(null);
68
69
  const [contextTarget, setContextTarget] = useState(null);
@@ -70,7 +71,7 @@ export function KptMap({ locations, categories, country = 'PL', view = null, bou
70
71
  const [createOpen, setCreateOpen] = useState(false);
71
72
  const [userPosition, setUserPosition] = useState(null);
72
73
  const [locationBlocked, setLocationBlocked] = useState(false);
73
- /** Ostatni wybrany wynik wyszukiwania — źródło tymczasowej pinezki. */
74
+ /** Ostatni wybrany wynik wyszukiwania - źródło tymczasowej pinezki. */
74
75
  const [searchPin, setSearchPin] = useState(null);
75
76
  const [hidden, setHidden] = useControllableState({
76
77
  value: hiddenCategories,
@@ -84,7 +85,7 @@ export function KptMap({ locations, categories, country = 'PL', view = null, bou
84
85
  return hiddenSet.size === 0 ? locations : locations.filter((l) => !hiddenSet.has(l.categoryId));
85
86
  }, [locations, hidden]);
86
87
  const counts = useMemo(() => (legendCounts ? countByCategory(locations) : null), [legendCounts, locations]);
87
- /** Wynik grupowania dla aktualnego zoomu — grupy i punkty pojedyncze. */
88
+ /** Wynik grupowania dla aktualnego zoomu - grupy i punkty pojedyncze. */
88
89
  const entries = useMemo(() => {
89
90
  if (!cluster)
90
91
  return [...visibleLocations];
@@ -111,7 +112,7 @@ export function KptMap({ locations, categories, country = 'PL', view = null, bou
111
112
  }),
112
113
  size: CLUSTER_SIZE,
113
114
  anchor: { x: CLUSTER_SIZE.width / 2, y: CLUSTER_SIZE.height / 2 },
114
- // Grupy nad pojedynczymi punktami — licznik ma być czytelny.
115
+ // Grupy nad pojedynczymi punktami - licznik ma być czytelny.
115
116
  zIndex: 500,
116
117
  };
117
118
  }
@@ -149,7 +150,7 @@ export function KptMap({ locations, categories, country = 'PL', view = null, bou
149
150
  }),
150
151
  size: MARKER_SIZE,
151
152
  anchor: { x: MARKER_SIZE.width / 2, y: MARKER_SIZE.height },
152
- // Nad grupami (500) — to na nią użytkownik właśnie kazał mapie polecieć.
153
+ // Nad grupami (500) - to na nią użytkownik właśnie kazał mapie polecieć.
153
154
  zIndex: 600,
154
155
  });
155
156
  }
@@ -189,7 +190,7 @@ export function KptMap({ locations, categories, country = 'PL', view = null, bou
189
190
  * a jego callbacki żyją dłużej niż render, w którym powstały.
190
191
  */
191
192
  const latest = useRef({ entries, allowCreate, popup, contextTarget, onLocationClick, onClusterClick, onViewChange });
192
- // Odświeżane po zatwierdzeniu renderu, nie w jego trakcie — przerwany render nie zostawi w refie danych,
193
+ // Odświeżane po zatwierdzeniu renderu, nie w jego trakcie - przerwany render nie zostawi w refie danych,
193
194
  // których nigdy nie było na ekranie.
194
195
  useLayoutEffect(() => {
195
196
  latest.current = { entries, allowCreate, popup, contextTarget, onLocationClick, onClusterClick, onViewChange };
@@ -208,7 +209,7 @@ export function KptMap({ locations, categories, country = 'PL', view = null, bou
208
209
  return;
209
210
  if (isCluster(entry)) {
210
211
  latest.current.onClusterClick?.(entry);
211
- // Grupa punktów o tej samej współrzędnej nie da się rozbić zoomem — pokaż listę.
212
+ // Grupa punktów o tej samej współrzędnej nie da się rozbić zoomem - pokaż listę.
212
213
  if (isSplittable(entry)) {
213
214
  engineRef.current?.fitBounds(entry.bounds, FIT_PADDING);
214
215
  return;
@@ -224,12 +225,12 @@ export function KptMap({ locations, categories, country = 'PL', view = null, bou
224
225
  latest.current.onLocationClick?.(entry);
225
226
  }, [autoPanToPopup]);
226
227
  /*
227
- * Montaż silnika — raz na życie komponentu.
228
+ * Montaż silnika - raz na życie komponentu.
228
229
  *
229
230
  * Sprzątanie czeka na zakończenie `init()`: w trybie ścisłym React montuje efekt dwa razy,
230
231
  * a silnik mapowy oznacza kontener jako zajęty już przy pierwszym wywołaniu. Zniszczenie
231
- * „w locie", przed rozwiązaniem obietnicy, zostawiłoby oznaczony kontener i drugi montaż
232
- * kończyłby się błędem „Map container is already initialized".
232
+ * "w locie", przed rozwiązaniem obietnicy, zostawiłoby oznaczony kontener i drugi montaż
233
+ * kończyłby się błędem "Map container is already initialized".
233
234
  */
234
235
  const reportEngineError = useEffectEvent((error) => {
235
236
  console.error(error);
@@ -280,7 +281,7 @@ export function KptMap({ locations, categories, country = 'PL', view = null, bou
280
281
  setLiveEngine(map);
281
282
  emitViewChange();
282
283
  })
283
- // Bez tego odrzucony `init()` to „Uncaught (in promise)” i mapa bez słowa wyjaśnienia.
284
+ // Bez tego odrzucony `init()` to "Uncaught (in promise)" i mapa bez słowa wyjaśnienia.
284
285
  .catch((error) => {
285
286
  if (!disposed)
286
287
  reportEngineError(error);
@@ -293,7 +294,7 @@ export function KptMap({ locations, categories, country = 'PL', view = null, bou
293
294
  // w mapę, której jeszcze nie ma, a kontener zostałby oznaczony jako zajęty na zawsze.
294
295
  mountChain.current = mountChain.current.finally(() => map.destroy());
295
296
  };
296
- // Silnik i widok startowy czytamy raz — podmiana po starcie nie przeładowuje mapy.
297
+ // Silnik i widok startowy czytamy raz - podmiana po starcie nie przeładowuje mapy.
297
298
  // eslint-disable-next-line react-hooks/exhaustive-deps -- montaż raz na życie komponentu (patrz wyżej)
298
299
  }, []);
299
300
  // Bez tego Leaflet zostawia szare pola po każdej zmianie układu strony.
@@ -305,12 +306,12 @@ export function KptMap({ locations, categories, country = 'PL', view = null, bou
305
306
  observer.observe(canvas);
306
307
  return () => observer.disconnect();
307
308
  }, []);
308
- // Wypychanie znaczników do silnika — jedyne miejsce, które je rysuje.
309
+ // Wypychanie znaczników do silnika - jedyne miejsce, które je rysuje.
309
310
  useEffect(() => {
310
311
  if (ready)
311
312
  engineRef.current?.setMarkers(markers);
312
313
  }, [ready, markers]);
313
- // Zmiana źródła kafli w locie — bez przeładowania mapy.
314
+ // Zmiana źródła kafli w locie - bez przeładowania mapy.
314
315
  useEffect(() => {
315
316
  if (ready) {
316
317
  engineRef.current?.setTileSource(tileUrl ?? KPT_MAP_DEFAULT_TILE_URL, attribution ?? KPT_MAP_DEFAULT_ATTRIBUTION);
@@ -326,7 +327,7 @@ export function KptMap({ locations, categories, country = 'PL', view = null, bou
326
327
  engineRef.current?.setUserPosition(userPosition, renderUserMarkerHtml({ label: t('map.myLocation'), iconSvgInner: getKptIcon('user') }));
327
328
  }, [ready, userPosition, t]);
328
329
  /*
329
- * Włączenie albo podmiana nasłuchu pozycji zeruje jego stan — liczone w renderze (wzorzec
330
+ * Włączenie albo podmiana nasłuchu pozycji zeruje jego stan - liczone w renderze (wzorzec
330
331
  * poprzedniej wartości), a nie w efekcie, który pokazałby jedną klatkę starej pozycji.
331
332
  */
332
333
  const watching = showUserLocation && !!geolocation;
@@ -360,7 +361,7 @@ export function KptMap({ locations, categories, country = 'PL', view = null, bou
360
361
  const popupCategory = popup ? categoryById.get(popup.location.categoryId) : undefined;
361
362
  /**
362
363
  * Odległość otwartego punktu od `distanceFrom` (albo od użytkownika) w metrach. `null`, gdy
363
- * nie ma od czego liczyć — treść popupu chowa wtedy wiersz dystansu zamiast pokazywać zero.
364
+ * nie ma od czego liczyć - treść popupu chowa wtedy wiersz dystansu zamiast pokazywać zero.
364
365
  */
365
366
  const popupDistance = useMemo(() => {
366
367
  if (!popup)
@@ -381,21 +382,21 @@ export function KptMap({ locations, categories, country = 'PL', view = null, bou
381
382
  return null;
382
383
  return liveEngine.project(contextTarget.at);
383
384
  }, [viewportTick, contextTarget, liveEngine]);
384
- /** Kategorie oferowane w menu „dodaj" — ukryte w legendzie odpadają. */
385
+ /** Kategorie oferowane w menu "dodaj" - ukryte w legendzie odpadają. */
385
386
  const creatableCategories = useMemo(() => {
386
387
  const hiddenSet = new Set(hidden);
387
388
  return categories.filter((category) => !hiddenSet.has(category.id) && (category.fields?.length || renderCreateForm));
388
389
  }, [categories, hidden, renderCreateForm]);
389
- /** Czy jest czym szukać — port bez `search()` nie zasługuje na pole, które nic nie robi. */
390
+ /** Czy jest czym szukać - port bez `search()` nie zasługuje na pole, które nic nie robi. */
390
391
  const searchEnabled = search && !!geocoder?.search;
391
392
  /**
392
- * Prostokąt preferowanych wyników: zasięg jawny, a bez niego preset kraju — „Kwiatowa" ma
393
+ * Prostokąt preferowanych wyników: zasięg jawny, a bez niego preset kraju - "Kwiatowa" ma
393
394
  * trafiać w tę pod nosem. To sam bias: adresu z zagranicy dalej da się poszukać.
394
395
  */
395
396
  const searchViewbox = bounds ?? resolveCountryView(country).bounds;
396
397
  /**
397
398
  * Twarde zawężenie do krajów. Jawne `searchOptions.countryCodes` wygrywa; bez niego odcinamy
398
- * zagranicę dopiero przy `restrictToCountry` — tam mapa i tak nie pozwoli tam przesunąć widoku.
399
+ * zagranicę dopiero przy `restrictToCountry` - tam mapa i tak nie pozwoli tam przesunąć widoku.
399
400
  */
400
401
  const searchCountryCodes = searchOptions?.countryCodes ?? (restrictToCountry ? [country] : null);
401
402
  const closeCreate = () => {
@@ -431,11 +432,11 @@ export function KptMap({ locations, categories, country = 'PL', view = null, bou
431
432
  map?.setView(result.at, searchZoom);
432
433
  onSearchSelect?.(result);
433
434
  };
434
- return (_jsxs("div", { className: cn('kpt-map', className), "data-engine": liveEngine?.kind, style: { ...style, '--kpt-map-height': height }, ...rest, children: [_jsxs("div", { className: "kpt-map__viewport", children: [_jsx("div", { ref: canvasRef, className: "kpt-map__canvas" }), _jsxs("div", { className: "kpt-map__controls", role: "group", "aria-label": t('map.legend'), children: [_jsx("button", { className: "kpt-map__control", type: "button", "aria-label": t('map.zoomIn'), title: t('map.zoomIn'), disabled: !ready, onClick: () => zoomBy(1), children: _jsx("span", { "aria-hidden": "true", children: "+" }) }), _jsx("button", { className: "kpt-map__control", type: "button", "aria-label": t('map.zoomOut'), title: t('map.zoomOut'), disabled: !ready, onClick: () => zoomBy(-1), children: _jsx("span", { "aria-hidden": "true", children: "\u2212" }) }), showUserLocation ? (_jsx("button", { className: "kpt-map__control kpt-map__control--locate", type: "button", "aria-label": locationBlocked ? t('map.locationDenied') : t('map.locateMe'), title: locationBlocked ? t('map.locationDenied') : t('map.locateMe'), disabled: !userPosition, onClick: centreOnUser, children: _jsx("span", { className: "kpt-map__crosshair", "aria-hidden": "true" }) })) : null] }), searchEnabled ? (_jsx("div", { className: "kpt-map__search", children: _jsx(KptMapSearch, { geocoder: geocoder, placeholder: searchPlaceholder, minLength: searchOptions?.minLength ?? 3, debounce: searchOptions?.debounce ?? 300, limit: searchOptions?.limit ?? 5, viewbox: searchViewbox, countryCodes: searchCountryCodes, onSelect: handleSearchSelect, onClear: () => setSearchPin(null) }) })) : null, allowCreate && contextTarget && contextPosition ? (_jsxs("div", { className: "kpt-map__context", role: "menu", "aria-label": t('map.addLocation'), style: { '--_kpt-map-x': `${contextPosition.x}px`, '--_kpt-map-y': `${contextPosition.y}px` }, children: [_jsx("p", { className: "kpt-map__context-title", children: t('map.chooseCategory') }), creatableCategories.length === 0 ? (_jsx("p", { className: "kpt-map__context-empty", children: t('map.empty') })) : (creatableCategories.map((category) => (_jsxs("button", { className: "kpt-map__context-item", type: "button", role: "menuitem", onClick: () => {
435
+ return (_jsxs("div", { className: cn('kpt-map', className), "data-engine": liveEngine?.kind, style: { ...style, '--kpt-map-height': height }, ...rest, children: [_jsxs("div", { className: "kpt-map__viewport", children: [_jsx("div", { ref: canvasRef, className: "kpt-map__canvas" }), _jsxs("div", { className: "kpt-map__controls", role: "group", "aria-label": t('map.legend'), children: [_jsx("button", { className: "kpt-map__control", type: "button", "aria-label": t('map.zoomIn'), title: t('map.zoomIn'), disabled: !ready, onClick: () => zoomBy(1), children: _jsx(KptIcon, { name: "plus" }) }), _jsx("button", { className: "kpt-map__control", type: "button", "aria-label": t('map.zoomOut'), title: t('map.zoomOut'), disabled: !ready, onClick: () => zoomBy(-1), children: _jsx(KptIcon, { name: "minus" }) }), showUserLocation ? (_jsx("button", { className: "kpt-map__control kpt-map__control--locate", type: "button", "aria-label": locationBlocked ? t('map.locationDenied') : t('map.locateMe'), title: locationBlocked ? t('map.locationDenied') : t('map.locateMe'), disabled: !userPosition, onClick: centreOnUser, children: _jsx("span", { className: "kpt-map__crosshair", "aria-hidden": "true" }) })) : null] }), searchEnabled ? (_jsx("div", { className: "kpt-map__search", children: _jsx(KptMapSearch, { geocoder: geocoder, placeholder: searchPlaceholder, minLength: searchOptions?.minLength ?? 3, debounce: searchOptions?.debounce ?? 300, limit: searchOptions?.limit ?? 5, viewbox: searchViewbox, countryCodes: searchCountryCodes, speech: searchSpeech, speechLang: searchSpeechLang, speechColor: searchSpeechColor, onSelect: handleSearchSelect, onClear: () => setSearchPin(null) }) })) : null, allowCreate && contextTarget && contextPosition ? (_jsxs("div", { className: "kpt-map__context", role: "menu", "aria-label": t('map.addLocation'), style: { '--_kpt-map-x': `${contextPosition.x}px`, '--_kpt-map-y': `${contextPosition.y}px` }, children: [_jsx("p", { className: "kpt-map__context-title", children: t('map.chooseCategory') }), creatableCategories.length === 0 ? (_jsx("p", { className: "kpt-map__context-empty", children: t('map.empty') })) : (creatableCategories.map((category) => (_jsxs("button", { className: "kpt-map__context-item", type: "button", role: "menuitem", onClick: () => {
435
436
  setContextTarget(null);
436
437
  setCreateFor({ at: contextTarget.at, category });
437
438
  setCreateOpen(true);
438
- }, children: [_jsx("span", { className: "kpt-map__context-dot", "aria-hidden": "true" }), category.label] }, category.id))))] })) : null, popup && popupPosition ? (_jsxs("div", { ref: popupRef, className: "kpt-map__popup", role: "dialog", "data-layout": popupLayout, "aria-label": popup.location.title, style: { '--_kpt-map-x': `${popupPosition.x}px`, '--_kpt-map-y': `${popupPosition.y}px` }, children: [popupLayout === 'plain' ? (_jsx("button", { className: "kpt-map__popup-close", type: "button", "aria-label": t('common.close'), onClick: () => setPopup(null), children: _jsx("span", { "aria-hidden": "true", children: "\u00D7" }) })) : null, popup.group ? (_jsxs(_Fragment, { children: [_jsx("p", { className: "kpt-map__popup-group", children: t('map.clusterItems') }), _jsx("div", { className: "kpt-map__popup-tabs", role: "tablist", children: popup.group.items.map((item) => (_jsx("button", { className: "kpt-map__popup-tab", type: "button", role: "tab", "aria-selected": item.id === popup.location.id, onClick: () => {
439
+ }, children: [_jsx("span", { className: "kpt-map__context-dot", "aria-hidden": "true" }), category.label] }, category.id))))] })) : null, popup && popupPosition ? (_jsxs("div", { ref: popupRef, className: "kpt-map__popup", role: "dialog", "data-layout": popupLayout, "aria-label": popup.location.title, style: { '--_kpt-map-x': `${popupPosition.x}px`, '--_kpt-map-y': `${popupPosition.y}px` }, children: [popupLayout === 'plain' ? (_jsx("button", { className: "kpt-map__popup-close", type: "button", "aria-label": t('common.close'), onClick: () => setPopup(null), children: _jsx("span", { "aria-hidden": "true", children: "x" }) })) : null, popup.group ? (_jsxs(_Fragment, { children: [_jsx("p", { className: "kpt-map__popup-group", children: t('map.clusterItems') }), _jsx("div", { className: "kpt-map__popup-tabs", role: "tablist", children: popup.group.items.map((item) => (_jsx("button", { className: "kpt-map__popup-tab", type: "button", role: "tab", "aria-selected": item.id === popup.location.id, onClick: () => {
439
440
  setPopup({ location: item, group: popup.group });
440
441
  onLocationClick?.(item);
441
442
  }, children: item.title }, item.id))) })] })) : null, _jsx("div", { className: "kpt-map__popup-body", children: renderPopup ? (renderPopup({
@@ -3,10 +3,10 @@ export interface KptMapSearchOptions {
3
3
  /** Język odpowiedzi. Domyślnie to, co ustawi dostawca. */
4
4
  language?: string;
5
5
  signal?: AbortSignal;
6
- /** Ile wyników najwyżej. Domyślnie 5 — to lista podpowiedzi, nie wyszukiwarka pełnotekstowa. */
6
+ /** Ile wyników najwyżej. Domyślnie 5 - to lista podpowiedzi, nie wyszukiwarka pełnotekstowa. */
7
7
  limit?: number;
8
8
  /**
9
- * Preferuj wyniki z tego prostokąta. **Nie odcina** reszty świata — adres z zagranicy
9
+ * Preferuj wyniki z tego prostokąta. **Nie odcina** reszty świata - adres z zagranicy
10
10
  * dalej da się znaleźć, tylko wypada niżej na liście.
11
11
  */
12
12
  viewbox?: KptMapBounds;
@@ -20,12 +20,12 @@ export interface KptMapGeocoderPort {
20
20
  signal?: AbortSignal;
21
21
  }): Promise<KptMapAddress | null>;
22
22
  /**
23
- * Geokodowanie wprost: tekst → miejsca. Metoda jest **opcjonalna** — port bez niej po prostu
23
+ * Geokodowanie wprost: tekst -> miejsca. Metoda jest **opcjonalna** - port bez niej po prostu
24
24
  * nie dostaje pola wyszukiwania (komponent go wtedy nie renderuje).
25
25
  */
26
26
  search?(query: string, options?: KptMapSearchOptions): Promise<readonly KptMapSuggestion[]>;
27
27
  /**
28
- * Uzupełnia podpowiedź o współrzędne. Wołane **raz, po wybraniu pozycji z listy** — nigdy
28
+ * Uzupełnia podpowiedź o współrzędne. Wołane **raz, po wybraniu pozycji z listy** - nigdy
29
29
  * w trakcie pisania. Potrzebne tylko dostawcom, których `search()` nie zwraca `at`.
30
30
  */
31
31
  resolve?(suggestion: KptMapSuggestion, options?: {
@@ -35,17 +35,17 @@ export interface KptMapGeocoderPort {
35
35
  }
36
36
  export interface KptMapGeolocationPort {
37
37
  /**
38
- * Śledzi pozycję użytkownika. Zwraca funkcję sprzątającą — tak samo jak efekt Reacta,
38
+ * Śledzi pozycję użytkownika. Zwraca funkcję sprzątającą - tak samo jak efekt Reacta,
39
39
  * więc wpina się bez adaptera.
40
40
  */
41
41
  watch(onPosition: (position: KptMapUserPosition | null) => void, onError: (error: KptMapGeolocationError) => void): () => void;
42
42
  }
43
43
  /** Geolokalizacja przeglądarki. Brak zgody czy brak API nie wywraca komponentu. */
44
44
  export declare function browserGeolocation(options?: PositionOptions): KptMapGeolocationPort;
45
- /** Stała pozycja — do dem, testów i SSR, gdzie prawdziwej geolokalizacji nie ma. */
45
+ /** Stała pozycja - do dem, testów i SSR, gdzie prawdziwej geolokalizacji nie ma. */
46
46
  export declare function geolocationStub(at: KptLatLng, accuracy?: number): KptMapGeolocationPort;
47
47
  export interface KptNominatimOptions {
48
- /** Adres instancji Nominatim. Domyślnie publiczna instancja OSM — patrz ostrzeżenie niżej. */
48
+ /** Adres instancji Nominatim. Domyślnie publiczna instancja OSM - patrz ostrzeżenie niżej. */
49
49
  baseUrl?: string;
50
50
  /** Język odpowiedzi (`Accept-Language`). Domyślnie język przeglądarki. */
51
51
  language?: string;
@@ -54,7 +54,7 @@ export interface KptNominatimOptions {
54
54
  /**
55
55
  * Najmniejszy odstęp między zapytaniami w milisekundach.
56
56
  *
57
- * Sekunda nie jest cechą Nominatima, tylko wymogiem regulaminu **publicznej instancji OSM** —
57
+ * Sekunda nie jest cechą Nominatima, tylko wymogiem regulaminu **publicznej instancji OSM** -
58
58
  * dlatego domyślna zależy od `baseUrl`: bez niego 1000 ms, z własnym adresem 0.
59
59
  */
60
60
  minIntervalMs?: number;
@@ -63,7 +63,7 @@ export interface KptNominatimOptions {
63
63
  * Adapter Nominatim (OpenStreetMap): geokodowanie wsteczne i podpowiedzi adresowe.
64
64
  *
65
65
  * Kolejkuje zapytania z odstępem sekundy, bo tego wymaga regulamin publicznej instancji.
66
- * Odstęp liczony od zegara, a nie stałym opóźnieniem przed każdym zapytaniem — inaczej
66
+ * Odstęp liczony od zegara, a nie stałym opóźnieniem przed każdym zapytaniem - inaczej
67
67
  * pierwsza podpowiedź po minucie bezczynności też płaciłaby sekundę.
68
68
  *
69
69
  * **Nie rejestruj publicznej instancji w produkcji bez przeczytania jej polityki użycia.**
package/dist/map/ports.js CHANGED
@@ -26,7 +26,7 @@ function kindOf(error) {
26
26
  return 'unavailable';
27
27
  return 'timeout';
28
28
  }
29
- /** Stała pozycja — do dem, testów i SSR, gdzie prawdziwej geolokalizacji nie ma. */
29
+ /** Stała pozycja - do dem, testów i SSR, gdzie prawdziwej geolokalizacji nie ma. */
30
30
  export function geolocationStub(at, accuracy = 30) {
31
31
  return {
32
32
  watch(onPosition) {
@@ -42,7 +42,7 @@ const NOMINATIM_MIN_INTERVAL_MS = 1000;
42
42
  * Adapter Nominatim (OpenStreetMap): geokodowanie wsteczne i podpowiedzi adresowe.
43
43
  *
44
44
  * Kolejkuje zapytania z odstępem sekundy, bo tego wymaga regulamin publicznej instancji.
45
- * Odstęp liczony od zegara, a nie stałym opóźnieniem przed każdym zapytaniem — inaczej
45
+ * Odstęp liczony od zegara, a nie stałym opóźnieniem przed każdym zapytaniem - inaczej
46
46
  * pierwsza podpowiedź po minucie bezczynności też płaciłaby sekundę.
47
47
  *
48
48
  * **Nie rejestruj publicznej instancji w produkcji bez przeczytania jej polityki użycia.**
@@ -50,7 +50,7 @@ const NOMINATIM_MIN_INTERVAL_MS = 1000;
50
50
  export function createNominatimGeocoder(options = {}) {
51
51
  const baseUrl = options.baseUrl ?? NOMINATIM_URL;
52
52
  const minInterval = options.minIntervalMs ?? (options.baseUrl ? 0 : NOMINATIM_MIN_INTERVAL_MS);
53
- /** Ogon kolejki — każde kolejne zapytanie czeka na swoją kolej. */
53
+ /** Ogon kolejki - każde kolejne zapytanie czeka na swoją kolej. */
54
54
  let next = Promise.resolve();
55
55
  let lastAt = 0;
56
56
  const slot = () => {
@@ -89,7 +89,7 @@ export function createNominatimGeocoder(options = {}) {
89
89
  return toAddress((await response.json()));
90
90
  }
91
91
  catch {
92
- // Brak adresu to nie awaria formularza — pole zostaje puste.
92
+ // Brak adresu to nie awaria formularza - pole zostaje puste.
93
93
  return null;
94
94
  }
95
95
  },
@@ -147,7 +147,7 @@ function toAddress(place) {
147
147
  return {
148
148
  street,
149
149
  houseNumber,
150
- // Jedno pole „Adres" — ulica z numerem, bo tak wypełnia się formularz.
150
+ // Jedno pole "Adres" - ulica z numerem, bo tak wypełnia się formularz.
151
151
  address: [street, houseNumber].filter(Boolean).join(' '),
152
152
  city: address.city ?? address.town ?? address.village ?? address.municipality ?? address.hamlet ?? '',
153
153
  postcode: address.postcode ?? '',
@@ -167,7 +167,7 @@ function toSuggestion(place) {
167
167
  id: String(place.place_id ?? place.display_name ?? at.lat + ':' + at.lng),
168
168
  label: place.display_name ?? '',
169
169
  at,
170
- // Punktowy „prostokąt" pojedynczego budynku nie nadaje się do wpasowania w kadr.
170
+ // Punktowy "prostokąt" pojedynczego budynku nie nadaje się do wpasowania w kadr.
171
171
  bounds: bounds && isFittableBounds(bounds) ? bounds : undefined,
172
172
  address: toAddress(place) ?? undefined,
173
173
  };
@@ -1,5 +1,5 @@
1
1
  /*
2
- * @konce-pt/react/map — mapa z konfigurowalnymi znacznikami. Osobny subpath, bo silnik mapowy
2
+ * @konce-pt/react/map - mapa z konfigurowalnymi znacznikami. Osobny subpath, bo silnik mapowy
3
3
  * i style mapy są ciężkie względem rdzenia biblioteki i nie każda aplikacja ich potrzebuje.
4
4
  *
5
5
  * Silnik Leaflet wymaga zainstalowanej paczki `leaflet` (peer opcjonalny) i arkusza
@@ -14,6 +14,6 @@ export { KptMapHoursField } from "../map/map-hours-field.js";
14
14
  export { KptMapImageField } from "../map/map-image-field.js";
15
15
  // Porty: geokoder i geolokalizacja. W Reakcie podaje się je propem, nie przez DI.
16
16
  export { browserGeolocation, geolocationStub, createNominatimGeocoder, createGeocoderStub } from "../map/ports.js";
17
- // Silniki i rdzeń (pure TS) — wspólne z portem Angulara.
17
+ // Silniki i rdzeń (pure TS) - wspólne z portem Angulara.
18
18
  export { createLeafletEngine, createGoogleEngine, loadGoogleMapsApi } from '@konce-pt/map';
19
19
  export { isCluster, clusterLocations, dominantCategory, countByCategory, isSplittable, KPT_CLUSTER_DEFAULTS, KPT_MAP_COUNTRIES, KPT_MAP_DEFAULT_COUNTRY, countryPreset, countryCodes, resolveCountryView, centerOfBounds, project, unproject, boundsOf, boundsCenter, isFittableBounds, KPT_MIN_FIT_SPAN, boundsContain, padBounds, haversine, metersPerPixel, zoomForBounds, clampLat, normalizeLng, worldSize, KPT_TILE_SIZE, KPT_MAX_LATITUDE, KPT_EARTH_RADIUS, renderMarkerHtml, renderClusterHtml, renderUserMarkerHtml, colorVarOf, contrastVarOf, foregroundVarOf, clusterTier, KPT_MAP_DEFAULT_TILE_URL, KPT_MAP_DEFAULT_ATTRIBUTION, parseTime, formatTime, isoWeekday, isOpenAt, isAlwaysOpen, nextChange, weekdayName, groupWeek, emptyWeek, formatDistance, formatLatLng, } from '@konce-pt/map';
@@ -1,13 +1,13 @@
1
1
  # KptMegamenu (@konce-pt/react)
2
2
 
3
- A mega menu — a horizontal bar with a wide, multi-column panel.
3
+ A mega menu - a horizontal bar with a wide, multi-column panel.
4
4
  Import: `import { KptMegamenu } from '@konce-pt/react';`
5
5
 
6
6
  ## DOM
7
7
  <div class="kpt-megamenu-host">
8
8
  <div class="kpt-megamenu" role="menubar" aria-orientation="horizontal" aria-label="Main menu">
9
9
  <button class="kpt-megamenu__top is-open" role="menuitem" tabindex="0"
10
- aria-haspopup="menu" aria-expanded="true" aria-controls="kpt-megamenu-r1">Products …caret…</button>
10
+ aria-haspopup="menu" aria-expanded="true" aria-controls="kpt-megamenu-r1">Products ...caret...</button>
11
11
  </div>
12
12
  </div>
13
13
  <!-- while open, in a portal: -->
@@ -19,9 +19,9 @@ Import: `import { KptMegamenu } from '@konce-pt/react';`
19
19
  </div>
20
20
 
21
21
  ## Props
22
- - `items`: `KptMenuItem<T>[]` — three levels: top item → `items` (columns) → column `items` (links)
23
- - `onSelect(link)` — a picked link from a column, or a top item without columns
24
- - `ariaLabel`: string — the bar's name for screen readers, e.g. "Main menu"
22
+ - `items`: `KptMenuItem<T>[]` - three levels: top item -> `items` (columns) -> column `items` (links)
23
+ - `onSelect(link)` - a picked link from a column, or a top item without columns
24
+ - `ariaLabel`: string - the bar's name for screen readers, e.g. "Main menu"
25
25
  - `className`, `ref` and every other `<div>` prop go to the host
26
26
 
27
27
  ## The panel is anchored to the whole bar
@@ -32,7 +32,7 @@ without closing the panel, so browsing across sections costs one click each.
32
32
  ## Examples
33
33
  <KptMegamenu items={items} onSelect={onSelect} />
34
34
 
35
- // top → columns → links
35
+ // top -> columns -> links
36
36
  const items: KptMenuItem[] = [{
37
37
  label: 'Products',
38
38
  items: [
@@ -43,7 +43,7 @@ without closing the panel, so browsing across sections costs one click each.
43
43
 
44
44
  ## Links (`url`)
45
45
  An entry with `url` and no children (and not disabled) renders as a real `<a href>` with the same
46
- look, so the browser handles navigation — opening in a new tab, the status-bar preview. `onSelect`
46
+ look, so the browser handles navigation - opening in a new tab, the status-bar preview. `onSelect`
47
47
  still fires before the browser follows the link.
48
48
 
49
49
  ## Tokens
@@ -67,11 +67,11 @@ focus to the top item.
67
67
 
68
68
  ## Router
69
69
  Links are plain `<a href>`, so without a router a click reloads the page. `onNavigate` fires on a plain
70
- click (left button, no Ctrl/⌘/Shift, no `target="_blank"`) with `{ item, url, event }`: call
70
+ click (left button, no Ctrl/Cmd/Shift, no `target="_blank"`) with `{ item, url, event }`: call
71
71
  `event.preventDefault()` and navigate with your router. Modified clicks stay native (a new tab, a new
72
72
  window). The library depends on no router.
73
73
 
74
74
  <KptMegamenu items={items} onNavigate={({ event, url }) => { event.preventDefault(); navigate(url); }} />
75
75
 
76
76
  ## When to use it
77
- The `menubar`/`menu` roles switch a screen reader into application mode: page navigation by headings and links stops, and arrow keys are expected. That fits an application menu (File, Edit, View) or a large product menu. For plain site navigation (a few links in a header) the WAI-ARIA APG recommends the disclosure pattern instead — a `<nav>` with buttons carrying `aria-expanded` and ordinary link lists — which you can build from `kpt-button` and lists. The menu does not render a third level: nested `items` of a submenu item are ignored.
77
+ The `menubar`/`menu` roles switch a screen reader into application mode: page navigation by headings and links stops, and arrow keys are expected. That fits an application menu (File, Edit, View) or a large product menu. For plain site navigation (a few links in a header) the WAI-ARIA APG recommends the disclosure pattern instead - a `<nav>` with buttons carrying `aria-expanded` and ordinary link lists - which you can build from `kpt-button` and lists. The menu does not render a third level: nested `items` of a submenu item are ignored.
@@ -6,16 +6,16 @@ export interface KptMegamenuProps<T> extends Omit<ComponentPropsWithRef<'div'>,
6
6
  onSelect?: (item: KptMenuItem<T>) => void;
7
7
  /**
8
8
  * Zwykły klik w pozycję z `url`. Aplikacja z routerem woła `event.preventDefault()` i nawiguje
9
- * sama — bez tego `<a href>` przeładowuje stronę.
9
+ * sama - bez tego `<a href>` przeładowuje stronę.
10
10
  */
11
11
  onNavigate?: (event: KptNavigateEvent<KptMenuItem<T>>) => void;
12
- /** Nazwa belki dla czytników ekranu, np. „Menu główne”. */
12
+ /** Nazwa belki dla czytników ekranu, np. "Menu główne". */
13
13
  ariaLabel?: string;
14
14
  }
15
15
  /**
16
- * Mega-menu — pozioma belka z szerokim, wielokolumnowym panelem.
17
- * Struktura: pozycja górna → `items` (kolumny) → `items` kolumny (odnośniki).
18
- * Pozycja górna bez kolumn działa jak akcja — wywołuje `onSelect` zamiast otwierać pusty panel.
16
+ * Mega-menu - pozioma belka z szerokim, wielokolumnowym panelem.
17
+ * Struktura: pozycja górna -> `items` (kolumny) -> `items` kolumny (odnośniki).
18
+ * Pozycja górna bez kolumn działa jak akcja - wywołuje `onSelect` zamiast otwierać pusty panel.
19
19
  *
20
20
  * Panel kotwiczy się do CAŁEJ belki, nie do pojedynczego przycisku: jest szeroki, więc ma
21
21
  * zaczynać się przy krawędzi menu, a nie przy przypadkowej pozycji, w którą kliknięto.
@@ -23,7 +23,7 @@ export interface KptMegamenuProps<T> extends Omit<ComponentPropsWithRef<'div'>,
23
23
  * Klawiatura jak w `KptMenubar`: belka to jeden przystanek Tab, strzałki w lewo/prawo
24
24
  * i `Home`/`End` chodzą po pozycjach górnych, strzałka w dół (albo `Enter`/spacja) otwiera panel
25
25
  * z fokusem na pierwszym odnośniku. W panelu strzałki w górę/dół przechodzą po wszystkich
26
- * odnośnikach kolumna po kolumnie, w lewo/prawo — do panelu sąsiedniej pozycji, a `Escape`
26
+ * odnośnikach kolumna po kolumnie, w lewo/prawo - do panelu sąsiedniej pozycji, a `Escape`
27
27
  * zamyka panel i oddaje fokus belce.
28
28
  *
29
29
  * @example