@konce-pt/react 0.11.2 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +128 -64
- package/dist/accordion/accordion.d.ts +14 -6
- package/dist/accordion/accordion.js +25 -17
- package/dist/accordion/llms.txt +22 -10
- package/dist/alert/alert.d.ts +2 -2
- package/dist/alert/alert.js +3 -2
- package/dist/alert/llms.txt +10 -9
- package/dist/app-shell/app-shell.d.ts +14 -14
- package/dist/app-shell/app-shell.js +22 -15
- package/dist/app-shell/llms.txt +16 -15
- package/dist/auth/auth-types.d.ts +6 -6
- package/dist/auth/auth.d.ts +2 -2
- package/dist/auth/auth.js +24 -15
- package/dist/auth/llms.txt +12 -11
- package/dist/autocomplete/autocomplete.d.ts +19 -6
- package/dist/autocomplete/autocomplete.js +32 -11
- package/dist/autocomplete/llms.txt +19 -5
- package/dist/avatar/avatar.d.ts +6 -6
- package/dist/avatar/avatar.js +6 -5
- package/dist/avatar/llms.txt +10 -10
- package/dist/avatar-group/avatar-group.d.ts +4 -4
- package/dist/avatar-group/avatar-group.js +4 -3
- package/dist/avatar-group/llms.txt +8 -8
- package/dist/backdrop/backdrop.d.ts +7 -26
- package/dist/backdrop/backdrop.js +32 -27
- package/dist/backdrop/llms.txt +27 -27
- package/dist/badge/badge.d.ts +3 -3
- package/dist/badge/badge.js +1 -1
- package/dist/badge/llms.txt +11 -11
- package/dist/bottom-sheet/bottom-sheet.d.ts +8 -3
- package/dist/bottom-sheet/bottom-sheet.js +5 -4
- package/dist/bottom-sheet/llms.txt +11 -8
- package/dist/breadcrumb/breadcrumb.d.ts +8 -2
- package/dist/breadcrumb/breadcrumb.js +11 -3
- package/dist/breadcrumb/llms.txt +10 -2
- package/dist/button/button.d.ts +3 -3
- package/dist/button/button.js +10 -9
- package/dist/button/llms.txt +27 -19
- package/dist/button-group/button-group.d.ts +18 -5
- package/dist/button-group/button-group.js +54 -6
- package/dist/button-group/llms.txt +27 -18
- package/dist/card/card.d.ts +8 -8
- package/dist/card/card.js +10 -9
- package/dist/card/llms.txt +20 -20
- package/dist/carousel/carousel.d.ts +6 -6
- package/dist/carousel/carousel.js +8 -5
- package/dist/carousel/llms.txt +10 -10
- package/dist/charts/chart-legend.d.ts +3 -3
- package/dist/charts/chart-legend.js +2 -1
- package/dist/charts/chart-tooltip.d.ts +3 -3
- package/dist/charts/chart-tooltip.js +1 -1
- package/dist/charts/chart.d.ts +4 -3
- package/dist/charts/chart.js +18 -10
- package/dist/charts/llms.txt +10 -7
- package/dist/charts-entry/public-api.js +2 -2
- package/dist/chat/chat.d.ts +17 -10
- package/dist/chat/chat.js +77 -23
- package/dist/chat/llms.txt +39 -15
- package/dist/chat-composer/chat-composer.d.ts +20 -7
- package/dist/chat-composer/chat-composer.js +29 -7
- package/dist/chat-composer/llms.txt +20 -11
- package/dist/chat-dock/chat-dock.d.ts +11 -4
- package/dist/chat-dock/chat-dock.js +10 -6
- package/dist/chat-dock/llms.txt +15 -14
- package/dist/chat-entry/public-api.js +1 -1
- package/dist/chat-message/chat-message.d.ts +12 -5
- package/dist/chat-message/chat-message.js +19 -8
- package/dist/chat-message/llms.txt +16 -15
- package/dist/chat-typing/chat-typing.d.ts +2 -2
- package/dist/chat-typing/chat-typing.js +4 -3
- package/dist/chat-typing/llms.txt +6 -6
- package/dist/checkbox/checkbox.d.ts +13 -6
- package/dist/checkbox/checkbox.js +31 -5
- package/dist/checkbox/llms.txt +26 -11
- package/dist/chip/chip.d.ts +4 -4
- package/dist/chip/chip.js +3 -2
- package/dist/chip/llms.txt +11 -11
- package/dist/chips-input/chips-input.d.ts +6 -4
- package/dist/chips-input/chips-input.js +47 -12
- package/dist/chips-input/llms.txt +18 -8
- package/dist/clock/clock.d.ts +11 -6
- package/dist/clock/clock.js +38 -8
- package/dist/clock/llms.txt +12 -8
- package/dist/color-picker/color-picker.d.ts +9 -5
- package/dist/color-picker/color-picker.js +37 -18
- package/dist/color-picker/llms.txt +8 -5
- package/dist/confirm/confirm-container.d.ts +3 -3
- package/dist/confirm/confirm-container.js +6 -5
- package/dist/confirm/confirm-store.d.ts +4 -4
- package/dist/confirm/confirm-store.js +11 -5
- package/dist/confirm/llms.txt +8 -7
- package/dist/context-menu/context-menu.d.ts +1 -1
- package/dist/context-menu/context-menu.js +37 -14
- package/dist/context-menu/llms.txt +10 -7
- package/dist/data-table/data-table-types.d.ts +5 -5
- package/dist/data-table/data-table.d.ts +37 -5
- package/dist/data-table/data-table.js +426 -119
- package/dist/data-table/export-csv.d.ts +3 -3
- package/dist/data-table/export-csv.js +8 -10
- package/dist/data-table/llms.txt +127 -79
- package/dist/data-view/data-view.d.ts +13 -5
- package/dist/data-view/data-view.js +68 -6
- package/dist/data-view/llms.txt +29 -10
- package/dist/date-range/date-range.d.ts +20 -8
- package/dist/date-range/date-range.js +86 -63
- package/dist/date-range/llms.txt +32 -18
- package/dist/datepicker/datepicker.d.ts +22 -8
- package/dist/datepicker/datepicker.js +103 -71
- package/dist/datepicker/llms.txt +36 -22
- package/dist/dialog/dialog.d.ts +4 -4
- package/dist/dialog/dialog.js +32 -11
- package/dist/dialog/llms.txt +13 -10
- package/dist/divider/divider.d.ts +7 -1
- package/dist/divider/divider.js +3 -2
- package/dist/divider/llms.txt +4 -3
- package/dist/drawer/drawer.d.ts +9 -4
- package/dist/drawer/drawer.js +5 -4
- package/dist/drawer/llms.txt +13 -10
- package/dist/empty/empty.d.ts +2 -2
- package/dist/empty/empty.js +1 -1
- package/dist/empty/llms.txt +9 -9
- package/dist/fab/fab.d.ts +1 -1
- package/dist/fab/fab.js +1 -1
- package/dist/fab/llms.txt +10 -6
- package/dist/fieldset/fieldset.d.ts +18 -4
- package/dist/fieldset/fieldset.js +12 -6
- package/dist/fieldset/llms.txt +26 -9
- package/dist/file-upload/file-upload.d.ts +8 -2
- package/dist/file-upload/file-upload.js +22 -11
- package/dist/file-upload/llms.txt +12 -9
- package/dist/form-field/form-field-context.d.ts +4 -4
- package/dist/form-field/form-field.d.ts +12 -4
- package/dist/form-field/form-field.js +27 -6
- package/dist/form-field/llms.txt +25 -11
- package/dist/galleria/galleria.d.ts +3 -3
- package/dist/galleria/galleria.js +9 -6
- package/dist/galleria/llms.txt +7 -7
- package/dist/grid/col.d.ts +4 -4
- package/dist/grid/col.js +2 -2
- package/dist/grid/flex.d.ts +3 -3
- package/dist/grid/flex.js +1 -1
- package/dist/grid/grid.d.ts +7 -7
- package/dist/grid/grid.js +3 -3
- package/dist/grid/layout.d.ts +2 -2
- package/dist/grid/layout.js +2 -2
- package/dist/grid/llms.txt +15 -15
- package/dist/grid-entry/public-api.js +1 -1
- package/dist/i18n/i18n-context.d.ts +6 -6
- package/dist/i18n/i18n-context.js +27 -5
- package/dist/icon/icon-registry.d.ts +3 -3
- package/dist/icon/icon-registry.js +3 -3
- package/dist/icon/icon.d.ts +4 -4
- package/dist/icon/icon.js +10 -7
- package/dist/icon/llms.txt +13 -13
- package/dist/icon-button/icon-button.d.ts +2 -2
- package/dist/icon-button/icon-button.js +1 -1
- package/dist/icon-button/llms.txt +9 -5
- package/dist/icons-entry/public-api.d.ts +2 -2
- package/dist/icons-entry/public-api.js +3 -3
- package/dist/image/image.js +5 -5
- package/dist/image/llms.txt +13 -13
- package/dist/input/input.d.ts +18 -5
- package/dist/input/input.js +22 -6
- package/dist/input/llms.txt +25 -11
- package/dist/input-mask/input-mask.d.ts +7 -2
- package/dist/input-mask/input-mask.js +17 -43
- package/dist/input-mask/llms.txt +8 -5
- package/dist/input-number/input-number.d.ts +11 -9
- package/dist/input-number/input-number.js +25 -21
- package/dist/input-number/llms.txt +17 -14
- package/dist/input-otp/input-otp.d.ts +18 -5
- package/dist/input-otp/input-otp.js +48 -24
- package/dist/input-otp/llms.txt +18 -7
- package/dist/internal/calendar-focus.d.ts +1 -1
- package/dist/internal/calendar-focus.js +3 -3
- package/dist/internal/cn.d.ts +1 -1
- package/dist/internal/mask.d.ts +14 -0
- package/dist/internal/mask.js +62 -0
- package/dist/internal/number-group.d.ts +22 -0
- package/dist/internal/number-group.js +53 -0
- package/dist/internal/option-key.d.ts +6 -0
- package/dist/internal/option-key.js +8 -0
- package/dist/internal/option-nav.d.ts +4 -4
- package/dist/internal/option-nav.js +5 -5
- package/dist/internal/overlay-container.js +1 -1
- package/dist/internal/overlay.d.ts +3 -3
- package/dist/internal/overlay.js +40 -10
- package/dist/internal/password-strength.d.ts +6 -0
- package/dist/internal/password-strength.js +74 -0
- package/dist/internal/roving.d.ts +2 -2
- package/dist/internal/roving.js +3 -3
- package/dist/internal/scroll-lock.d.ts +6 -0
- package/dist/internal/scroll-lock.js +35 -0
- package/dist/internal/slot-children.d.ts +13 -0
- package/dist/internal/slot-children.js +31 -0
- package/dist/internal/slot.d.ts +3 -3
- package/dist/internal/slot.js +2 -2
- package/dist/internal/step.d.ts +12 -0
- package/dist/internal/step.js +31 -0
- package/dist/internal/tween.d.ts +5 -5
- package/dist/internal/tween.js +7 -8
- package/dist/internal/types.d.ts +2 -2
- package/dist/internal/use-breakpoint.d.ts +2 -2
- package/dist/internal/use-breakpoint.js +4 -4
- package/dist/internal/use-controllable-state.d.ts +5 -0
- package/dist/internal/use-controllable-state.js +25 -4
- package/dist/internal/use-id.d.ts +2 -2
- package/dist/internal/use-id.js +2 -2
- package/dist/internal/use-modal-focus.d.ts +2 -1
- package/dist/internal/use-modal-focus.js +14 -3
- package/dist/knob/knob.d.ts +7 -4
- package/dist/knob/knob.js +27 -22
- package/dist/knob/llms.txt +18 -11
- package/dist/listbox/listbox.d.ts +8 -6
- package/dist/listbox/listbox.js +37 -17
- package/dist/listbox/llms.txt +12 -9
- package/dist/loader/llms.txt +56 -0
- package/dist/loader/loader.d.ts +49 -0
- package/dist/loader/loader.js +68 -0
- package/dist/map/llms.txt +30 -23
- package/dist/map/map-create-dialog.d.ts +4 -4
- package/dist/map/map-create-dialog.js +36 -28
- package/dist/map/map-hours-field.d.ts +4 -4
- package/dist/map/map-hours-field.js +8 -7
- package/dist/map/map-image-field.d.ts +2 -2
- package/dist/map/map-image-field.js +6 -5
- package/dist/map/map-legend.d.ts +4 -4
- package/dist/map/map-legend.js +3 -2
- package/dist/map/map-poi-card.d.ts +3 -3
- package/dist/map/map-poi-card.js +10 -9
- package/dist/map/map-search.d.ts +17 -6
- package/dist/map/map-search.js +70 -43
- package/dist/map/map.d.ts +25 -13
- package/dist/map/map.js +86 -57
- package/dist/map/ports.d.ts +9 -9
- package/dist/map/ports.js +6 -6
- package/dist/map-entry/public-api.js +2 -2
- package/dist/megamenu/llms.txt +18 -7
- package/dist/megamenu/megamenu.d.ts +12 -6
- package/dist/megamenu/megamenu.js +23 -14
- package/dist/mention/llms.txt +15 -15
- package/dist/mention/mention.d.ts +5 -5
- package/dist/mention/mention.js +2 -2
- package/dist/mention/mentions.d.ts +1 -1
- package/dist/mention/mentions.js +1 -1
- package/dist/menu/llms.txt +12 -12
- package/dist/menu/menu-item.d.ts +4 -4
- package/dist/menu/menu-keys.d.ts +2 -2
- package/dist/menu/menu-keys.js +5 -5
- package/dist/menu/menu-rows.js +1 -0
- package/dist/menu/menu.d.ts +2 -2
- package/dist/menu/menu.js +15 -8
- package/dist/menubar/llms.txt +19 -8
- package/dist/menubar/menubar.d.ts +11 -5
- package/dist/menubar/menubar.js +23 -11
- package/dist/meter-group/llms.txt +12 -12
- package/dist/meter-group/meter-group.d.ts +2 -2
- package/dist/meter-group/meter-group.js +2 -1
- package/dist/motion/motion-context.d.ts +22 -0
- package/dist/motion/motion-context.js +28 -0
- package/dist/order-list/llms.txt +24 -9
- package/dist/order-list/order-list.d.ts +12 -4
- package/dist/order-list/order-list.js +123 -25
- package/dist/paginator/llms.txt +8 -8
- package/dist/paginator/paginator.js +7 -4
- package/dist/panel/llms.txt +25 -13
- package/dist/panel/panel.d.ts +11 -3
- package/dist/panel/panel.js +12 -7
- package/dist/password/llms.txt +19 -7
- package/dist/password/password.d.ts +2 -2
- package/dist/password/password.js +27 -16
- package/dist/peek/llms.txt +11 -11
- package/dist/peek/peek.d.ts +6 -6
- package/dist/peek/peek.js +41 -19
- package/dist/pick-list/llms.txt +35 -12
- package/dist/pick-list/pick-list.d.ts +12 -4
- package/dist/pick-list/pick-list.js +128 -24
- package/dist/popover/llms.txt +13 -10
- package/dist/popover/popover.d.ts +6 -4
- package/dist/popover/popover.js +14 -7
- package/dist/progress/llms.txt +17 -17
- package/dist/progress/progress.d.ts +7 -7
- package/dist/progress/progress.js +7 -6
- package/dist/public-api.d.ts +16 -4
- package/dist/public-api.js +13 -7
- package/dist/radio-group/llms.txt +16 -6
- package/dist/radio-group/radio-group.d.ts +12 -3
- package/dist/radio-group/radio-group.js +23 -4
- package/dist/rating/llms.txt +20 -13
- package/dist/rating/rating-pointer.d.ts +16 -0
- package/dist/rating/rating-pointer.js +26 -0
- package/dist/rating/rating.d.ts +6 -6
- package/dist/rating/rating.js +77 -12
- package/dist/rich-text/lists.d.ts +2 -2
- package/dist/rich-text/lists.js +7 -7
- package/dist/rich-text/llms.txt +35 -12
- package/dist/rich-text/rich-text.d.ts +13 -14
- package/dist/rich-text/rich-text.js +311 -142
- package/dist/rich-text/sanitize.d.ts +11 -2
- package/dist/rich-text/sanitize.js +80 -32
- package/dist/rich-text/tables.d.ts +3 -3
- package/dist/rich-text/tables.js +3 -3
- package/dist/roadmap/llms.txt +23 -17
- package/dist/roadmap/roadmap.d.ts +6 -6
- package/dist/roadmap/roadmap.js +102 -25
- package/dist/roadmap-entry/public-api.js +2 -2
- package/dist/scroll-top/llms.txt +6 -6
- package/dist/scroll-top/scroll-top.d.ts +1 -1
- package/dist/scroll-top/scroll-top.js +2 -1
- package/dist/select/llms.txt +22 -12
- package/dist/select/select.d.ts +10 -8
- package/dist/select/select.js +87 -47
- package/dist/shared/types.d.ts +22 -1
- package/dist/shared/types.js +9 -1
- package/dist/sidenav/llms.txt +9 -9
- package/dist/sidenav/sidenav.d.ts +2 -3
- package/dist/sidenav/sidenav.js +5 -4
- package/dist/skeleton/llms.txt +3 -3
- package/dist/skeleton/skeleton.d.ts +1 -1
- package/dist/skeleton/skeleton.js +1 -1
- package/dist/slider/llms.txt +34 -12
- package/dist/slider/slider-drag.d.ts +26 -0
- package/dist/slider/slider-drag.js +79 -0
- package/dist/slider/slider.d.ts +8 -5
- package/dist/slider/slider.js +38 -8
- package/dist/speech/llms.txt +97 -0
- package/dist/speech/speech-button.d.ts +44 -0
- package/dist/speech/speech-button.js +86 -0
- package/dist/speech/speech-wave.d.ts +19 -0
- package/dist/speech/speech-wave.js +16 -0
- package/dist/speech/use-speech-recognition.d.ts +81 -0
- package/dist/speech/use-speech-recognition.js +179 -0
- package/dist/speed-dial/llms.txt +14 -8
- package/dist/speed-dial/speed-dial.d.ts +1 -1
- package/dist/speed-dial/speed-dial.js +3 -2
- package/dist/spinner/llms.txt +7 -7
- package/dist/spinner/spinner.d.ts +1 -1
- package/dist/spinner/spinner.js +2 -1
- package/dist/split-button/llms.txt +21 -15
- package/dist/split-button/split-button.d.ts +2 -2
- package/dist/split-button/split-button.js +13 -6
- package/dist/splitter/llms.txt +11 -11
- package/dist/splitter/splitter.d.ts +3 -3
- package/dist/splitter/splitter.js +25 -10
- package/dist/stepper/llms.txt +35 -13
- package/dist/stepper/stepper.d.ts +6 -6
- package/dist/stepper/stepper.js +60 -13
- package/dist/switch/llms.txt +15 -5
- package/dist/switch/switch.d.ts +10 -3
- package/dist/switch/switch.js +18 -4
- package/dist/switch-group/llms.txt +11 -8
- package/dist/switch-group/switch-group.d.ts +6 -4
- package/dist/switch-group/switch-group.js +9 -7
- package/dist/tabs/llms.txt +12 -9
- package/dist/tabs/tabs.d.ts +5 -5
- package/dist/tabs/tabs.js +36 -20
- package/dist/textarea/llms.txt +23 -12
- package/dist/textarea/textarea.d.ts +19 -6
- package/dist/textarea/textarea.js +22 -7
- package/dist/timeline/llms.txt +4 -4
- package/dist/timeline/timeline.d.ts +1 -1
- package/dist/timeline/timeline.js +1 -1
- package/dist/toast/llms.txt +50 -17
- package/dist/toast/toast-container.d.ts +9 -3
- package/dist/toast/toast-container.js +18 -9
- package/dist/toast/toast-store.d.ts +42 -2
- package/dist/toast/toast-store.js +36 -1
- package/dist/toolbar/llms.txt +7 -7
- package/dist/toolbar/toolbar.d.ts +3 -3
- package/dist/toolbar/toolbar.js +2 -2
- package/dist/tooltip/llms.txt +14 -12
- package/dist/tooltip/tooltip.d.ts +5 -4
- package/dist/tooltip/tooltip.js +100 -41
- package/dist/tree/llms.txt +25 -11
- package/dist/tree/tree-keys.d.ts +5 -5
- package/dist/tree/tree-keys.js +7 -7
- package/dist/tree/tree.d.ts +17 -5
- package/dist/tree/tree.js +62 -20
- package/dist/update/llms.txt +54 -0
- package/dist/update/update.d.ts +49 -0
- package/dist/update/update.js +82 -0
- package/package.json +18 -15
package/dist/map/llms.txt
CHANGED
|
@@ -9,46 +9,53 @@ interface.
|
|
|
9
9
|
Import: `import { KptMap, createLeafletEngine } from '@konce-pt/react/map';`
|
|
10
10
|
|
|
11
11
|
## Requirements
|
|
12
|
-
1. The **optional** `leaflet` dependency
|
|
12
|
+
1. The **optional** `leaflet` dependency - the library does not install it: `pnpm add leaflet`
|
|
13
13
|
2. Its stylesheet: `import 'leaflet/dist/leaflet.css';`
|
|
14
14
|
3. An engine factory on the `engine` prop: `engine={() => createLeafletEngine()}`
|
|
15
15
|
|
|
16
16
|
Leaflet is loaded with a dynamic `import()`, so an app that never renders a map does not download
|
|
17
|
-
it. Without the package the component still imports and compiles
|
|
17
|
+
it. Without the package the component still imports and compiles - only rendering the map ends with
|
|
18
18
|
a readable message.
|
|
19
19
|
|
|
20
20
|
## Props
|
|
21
|
-
- `locations`: `readonly KptMapLocation<T>[]`
|
|
22
|
-
- `categories`: `readonly KptMapCategory[]`
|
|
23
|
-
- `engine`: `KptMapEngineFactory`
|
|
21
|
+
- `locations`: `readonly KptMapLocation<T>[]` - **required**
|
|
22
|
+
- `categories`: `readonly KptMapCategory[]` - **required**
|
|
23
|
+
- `engine`: `KptMapEngineFactory` - **required**; a factory, not an instance, because every map
|
|
24
24
|
needs its own object. Read once, at mount.
|
|
25
|
-
- `country`: string = `'PL'`
|
|
26
|
-
- `view`, `bounds`
|
|
27
|
-
- `restrictToCountry`: boolean
|
|
25
|
+
- `country`: string = `'PL'` - the initial view preset; an unknown code falls back to Poland
|
|
26
|
+
- `view`, `bounds` - an explicit view or extent; they override `country`
|
|
27
|
+
- `restrictToCountry`: boolean - blocks panning outside the country's bounds
|
|
28
28
|
- `cluster`: boolean = true, `clusterOptions`, `clusterColorBy`: `'dominant' | 'none'`
|
|
29
29
|
- `legend`, `legendCounts`: boolean = true
|
|
30
|
-
- `hiddenCategories` / `defaultHiddenCategories` / `onHiddenCategoriesChange`
|
|
30
|
+
- `hiddenCategories` / `defaultHiddenCategories` / `onHiddenCategoriesChange` - the ids hidden in
|
|
31
31
|
the legend, controlled or uncontrolled
|
|
32
32
|
- `showUserLocation`, `followUser`: boolean; `geolocation`: `KptMapGeolocationPort | null`
|
|
33
|
-
- `allowCreate`: boolean
|
|
33
|
+
- `allowCreate`: boolean - the "Add location" menu under the right mouse button
|
|
34
34
|
- `search`: boolean, `searchPlaceholder`, `searchOptions`, `searchZoom`, `searchMarker`
|
|
35
|
-
- `
|
|
35
|
+
- `searchSpeech`: boolean = false - a microphone in the search field: a click clears the phrase and one
|
|
36
|
+
spoken utterance becomes the query (same `debounce`/`minLength` as typing); `searchSpeechLang`: string -
|
|
37
|
+
its language (BCP 47); `searchSpeechColor` - listening colour (theme colour by default). Hidden without browser support. `KptMapSearch` on its own takes `speech` / `speechLang` / `speechColor`
|
|
38
|
+
- `geocoder`: `KptMapGeocoderPort | null` - this map's geocoder; it feeds both the search and the
|
|
36
39
|
address suggestions in the create form
|
|
37
40
|
- `popupLayout`: `'plain' | 'card'`; `distanceFrom`: `KptLatLng | null`
|
|
38
41
|
- `height`: string = `'480px'`; `tileUrl`, `attribution` (ignored by the Google engine)
|
|
39
|
-
- `renderPopup`, `renderCreateForm`
|
|
42
|
+
- `renderPopup`, `renderCreateForm` - see below
|
|
40
43
|
- `className`, `ref` and every other `<div>` prop go to the host
|
|
41
44
|
|
|
42
45
|
## Events
|
|
43
46
|
`onLocationClick`, `onClusterClick`, `onLocationCreate`, `onSearchSelect`, `onViewChange`,
|
|
44
|
-
`onUserPositionChange`, `onUserLocationError`.
|
|
47
|
+
`onUserPositionChange`, `onUserLocationError`, `onEngineError`.
|
|
45
48
|
|
|
46
|
-
`
|
|
49
|
+
`onEngineError(error)` fires when the engine fails to start (no `leaflet` package, a rejected Google key);
|
|
50
|
+
the error is also logged to the console. `followUser` and the position callbacks are read fresh on every
|
|
51
|
+
fix, so changing them does not restart the geolocation watch.
|
|
52
|
+
|
|
53
|
+
`onLocationCreate` gives `{ at, categoryId, value }` - the component appends **nothing** to
|
|
47
54
|
`locations`; the application is the source of truth.
|
|
48
55
|
|
|
49
56
|
## Render props instead of templates
|
|
50
|
-
The Angular port picks a popup template per category (`kptMapPopup category="
|
|
51
|
-
prop and a `switch`: `renderPopup({ location, data, category, distance, close })`
|
|
57
|
+
The Angular port picks a popup template per category (`kptMapPopup category="..."`). React has one
|
|
58
|
+
prop and a `switch`: `renderPopup({ location, data, category, distance, close })` - the category
|
|
52
59
|
travels in the context, and the type of `data` follows the map's generic without an extra input.
|
|
53
60
|
|
|
54
61
|
<KptMap
|
|
@@ -64,7 +71,7 @@ travels in the context, and the type of `data` follows the map's generic without
|
|
|
64
71
|
|
|
65
72
|
## Ports are props, not DI
|
|
66
73
|
Angular injects `KPT_MAP_ENGINE`, `KPT_MAP_GEOCODER` and `KPT_MAP_GEOLOCATION`. React has no
|
|
67
|
-
injector, so all three arrive as props
|
|
74
|
+
injector, so all three arrive as props - and the geocoder was already per-map in Angular for a
|
|
68
75
|
licensing reason (a Google geocoder may only be paired with a Google map), so nothing is lost.
|
|
69
76
|
|
|
70
77
|
The ports themselves are promise-shaped rather than `Observable`-shaped: `reverse()`, `search()`
|
|
@@ -72,7 +79,7 @@ and `resolve()` return promises and take an `AbortSignal`, which is what `fetch`
|
|
|
72
79
|
|
|
73
80
|
import { createNominatimGeocoder, browserGeolocation } from '@konce-pt/react/map';
|
|
74
81
|
|
|
75
|
-
<KptMap geocoder={createNominatimGeocoder()} geolocation={browserGeolocation()}
|
|
82
|
+
<KptMap geocoder={createNominatimGeocoder()} geolocation={browserGeolocation()} ... />
|
|
76
83
|
|
|
77
84
|
`createGeocoderStub()` and `geolocationStub(at)` cover demos and tests.
|
|
78
85
|
|
|
@@ -83,18 +90,18 @@ second mount waits for the first teardown to finish, instead of failing with "Ma
|
|
|
83
90
|
already initialized".
|
|
84
91
|
|
|
85
92
|
## Sub-components
|
|
86
|
-
- `KptMapLegend`
|
|
93
|
+
- `KptMapLegend` - the legend on its own, when you want it somewhere other than under the map
|
|
87
94
|
(`hiddenCategories` instead of Angular's `hidden`: `hidden` on a DOM element is a boolean and
|
|
88
95
|
would clash with the `<div>` prop)
|
|
89
|
-
- `KptMapPoiCard`
|
|
90
|
-
- `KptMapSearch`
|
|
91
|
-
- `KptMapCreateDialog`, `KptMapHoursField`, `KptMapImageField`
|
|
96
|
+
- `KptMapPoiCard` - the ready-made place card for `popupLayout="card"`
|
|
97
|
+
- `KptMapSearch` - the address field alone
|
|
98
|
+
- `KptMapCreateDialog`, `KptMapHoursField`, `KptMapImageField` - the schema-built form and its two
|
|
92
99
|
non-trivial field types
|
|
93
100
|
|
|
94
101
|
## Validation without a form framework
|
|
95
102
|
The create dialog is built from `category.fields`. The Angular port stands on Signal Forms; here the
|
|
96
103
|
model is plain state and the rules are a map of functions beside it. The contract is the same:
|
|
97
|
-
declared once with the schema, and the "do not shout in red" gate lives in presentation
|
|
104
|
+
declared once with the schema, and the "do not shout in red" gate lives in presentation - an error
|
|
98
105
|
shows after the field is touched or after a failed submit.
|
|
99
106
|
|
|
100
107
|
## Tokens
|
|
@@ -5,17 +5,17 @@ import type { KptMapGeocoderPort } from './ports.ts';
|
|
|
5
5
|
export interface KptMapCreateDialogProps extends Omit<ComponentPropsWithRef<'div'>, 'children' | 'onSubmit'>, KptI18nOverrides {
|
|
6
6
|
category: KptMapCategory;
|
|
7
7
|
at: KptLatLng;
|
|
8
|
-
/** Geokoder tego formularza
|
|
8
|
+
/** Geokoder tego formularza - źródło podpowiedzi adresowych dla pól z `autofill`. */
|
|
9
9
|
geocoder?: KptMapGeocoderPort | null;
|
|
10
10
|
onSave: (value: Record<string, unknown>) => void;
|
|
11
11
|
onCancel: () => void;
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
|
-
* Treść dialogu
|
|
14
|
+
* Treść dialogu "dodaj lokalizację" budowana ze schemy kategorii (`category.fields`).
|
|
15
15
|
*
|
|
16
16
|
* Port Angulara stoi tu na Signal Forms; w Reakcie formularza-frameworka nie ma, więc model to
|
|
17
17
|
* zwykły stan, a reguły walidacji są mapą funkcji obok niego. Kontrakt zostaje ten sam:
|
|
18
|
-
* walidacja deklarowana raz przy schemie, a bramka
|
|
19
|
-
*
|
|
18
|
+
* walidacja deklarowana raz przy schemie, a bramka "nie strasz czerwienią" siedzi w prezentacji
|
|
19
|
+
* - błąd pokazuje się po dotknięciu pola albo po próbie zapisu.
|
|
20
20
|
*/
|
|
21
21
|
export declare function KptMapCreateDialog({ category, at, geocoder, onSave, onCancel, locale: localeOverride, dictionary, className, ...rest }: Readonly<KptMapCreateDialogProps>): import("react").JSX.Element;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
3
|
import { emptyWeek, parseTime, weekdayName } from '@konce-pt/map';
|
|
3
4
|
import { useEffect, useMemo, useState } from 'react';
|
|
@@ -15,7 +16,7 @@ import { KptMapHoursField } from "./map-hours-field.js";
|
|
|
15
16
|
import { KptMapImageField } from "./map-image-field.js";
|
|
16
17
|
/** Typy pól, które przyjmą fragment adresu. Data czy liczba nie mają z nim nic wspólnego. */
|
|
17
18
|
const TEXTUAL = new Set(['text', 'textarea']);
|
|
18
|
-
/** Pusta wartość właściwa dla typu pola
|
|
19
|
+
/** Pusta wartość właściwa dla typu pola - formularz startuje bez `undefined`. */
|
|
19
20
|
function initialValue(def) {
|
|
20
21
|
if (def.initial !== undefined)
|
|
21
22
|
return def.initial;
|
|
@@ -40,13 +41,17 @@ function initialModel(fields) {
|
|
|
40
41
|
out[def.key] = initialValue(def);
|
|
41
42
|
return out;
|
|
42
43
|
}
|
|
44
|
+
/** Wartość pola tekstowego z modelu `unknown` - liczba zostaje liczbą zapisaną tekstem, reszta pustym napisem. */
|
|
45
|
+
function asText(value) {
|
|
46
|
+
return typeof value === 'string' || typeof value === 'number' ? String(value) : '';
|
|
47
|
+
}
|
|
43
48
|
/**
|
|
44
|
-
* Treść dialogu
|
|
49
|
+
* Treść dialogu "dodaj lokalizację" budowana ze schemy kategorii (`category.fields`).
|
|
45
50
|
*
|
|
46
51
|
* Port Angulara stoi tu na Signal Forms; w Reakcie formularza-frameworka nie ma, więc model to
|
|
47
52
|
* zwykły stan, a reguły walidacji są mapą funkcji obok niego. Kontrakt zostaje ten sam:
|
|
48
|
-
* walidacja deklarowana raz przy schemie, a bramka
|
|
49
|
-
*
|
|
53
|
+
* walidacja deklarowana raz przy schemie, a bramka "nie strasz czerwienią" siedzi w prezentacji
|
|
54
|
+
* - błąd pokazuje się po dotknięciu pola albo po próbie zapisu.
|
|
50
55
|
*/
|
|
51
56
|
export function KptMapCreateDialog({ category, at, geocoder = null, onSave, onCancel, locale: localeOverride, dictionary, className, ...rest }) {
|
|
52
57
|
const { t, locale } = useKptMessages({ locale: localeOverride, dictionary });
|
|
@@ -55,42 +60,48 @@ export function KptMapCreateDialog({ category, at, geocoder = null, onSave, onCa
|
|
|
55
60
|
const [touched, setTouched] = useState({});
|
|
56
61
|
/** Po nieudanej próbie zapisu pokazujemy błędy wszystkich pól, nie tylko dotkniętych. */
|
|
57
62
|
const [submitted, setSubmitted] = useState(false);
|
|
58
|
-
/** Trwa zapytanie do geokodera — pokazujemy notkę zamiast ciszy. */
|
|
59
|
-
const [geocoding, setGeocoding] = useState(false);
|
|
60
63
|
/** Ostatnio ustalony adres; `address` bywa czytelniejszy niż suma pól. */
|
|
61
64
|
const [address, setAddress] = useState(null);
|
|
62
|
-
// Inna kategoria to inny formularz
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
// Inna kategoria to inny formularz - model wraca do wartości początkowych. Liczone w renderze
|
|
66
|
+
// (wzorzec poprzedniej wartości): efekt pokazałby jedną klatkę pól starej kategorii.
|
|
67
|
+
const [modelFields, setModelFields] = useState(fields);
|
|
68
|
+
if (modelFields !== fields) {
|
|
69
|
+
setModelFields(fields);
|
|
70
|
+
setModel(initialModel(fields));
|
|
66
71
|
setTouched({});
|
|
67
72
|
setSubmitted(false);
|
|
68
|
-
}
|
|
73
|
+
}
|
|
69
74
|
/** Czy kategoria ma pola do podpowiedzenia i jest czym je podpowiedzieć. */
|
|
70
75
|
const autofillFields = useMemo(() => fields.filter((def) => def.autofill && TEXTUAL.has(def.type)), [fields]);
|
|
71
76
|
const hasAutofill = !!geocoder && autofillFields.length > 0;
|
|
77
|
+
/** Tożsamość bieżącego zapytania do geokodera - nowa przy każdej zmianie jego wejść. */
|
|
78
|
+
const geocodeRequest = useMemo(() => (geocoder && autofillFields.length > 0 ? { geocoder, at, locale, autofillFields } : null), [geocoder, at, locale, autofillFields]);
|
|
79
|
+
/** Zapytanie, na które przyszła już odpowiedź (albo błąd). */
|
|
80
|
+
const [settledRequest, setSettledRequest] = useState(null);
|
|
81
|
+
/** Trwa zapytanie do geokodera - pokazujemy notkę zamiast ciszy. */
|
|
82
|
+
const geocoding = geocodeRequest !== null && settledRequest !== geocodeRequest;
|
|
72
83
|
/**
|
|
73
84
|
* Podpowiada adres z geokodowania wstecznego współrzędnych kliknięcia. Wypełnia wyłącznie
|
|
74
|
-
* pola z `autofill` i wyłącznie te, które są jeszcze puste
|
|
85
|
+
* pola z `autofill` i wyłącznie te, które są jeszcze puste - podpowiedź nigdy nie kasuje
|
|
75
86
|
* tego, co użytkownik zdążył wpisać.
|
|
76
87
|
*/
|
|
77
88
|
useEffect(() => {
|
|
78
|
-
if (!
|
|
89
|
+
if (!geocodeRequest)
|
|
79
90
|
return;
|
|
91
|
+
const request = geocodeRequest;
|
|
80
92
|
const controller = new AbortController();
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
.reverse(at, { language: locale, signal: controller.signal })
|
|
93
|
+
request.geocoder
|
|
94
|
+
.reverse(request.at, { language: request.locale, signal: controller.signal })
|
|
84
95
|
.then((found) => {
|
|
85
96
|
if (controller.signal.aborted)
|
|
86
97
|
return;
|
|
87
|
-
|
|
98
|
+
setSettledRequest(request);
|
|
88
99
|
setAddress(found);
|
|
89
100
|
if (!found)
|
|
90
101
|
return;
|
|
91
102
|
setModel((current) => {
|
|
92
103
|
const next = { ...current };
|
|
93
|
-
for (const def of autofillFields) {
|
|
104
|
+
for (const def of request.autofillFields) {
|
|
94
105
|
const value = found[def.autofill];
|
|
95
106
|
// Puste pole = to, czego użytkownik nie tknął.
|
|
96
107
|
if (typeof value === 'string' && value && !next[def.key])
|
|
@@ -101,16 +112,13 @@ export function KptMapCreateDialog({ category, at, geocoder = null, onSave, onCa
|
|
|
101
112
|
})
|
|
102
113
|
.catch(() => {
|
|
103
114
|
if (!controller.signal.aborted)
|
|
104
|
-
|
|
115
|
+
setSettledRequest(request);
|
|
105
116
|
});
|
|
106
|
-
return () =>
|
|
107
|
-
|
|
108
|
-
setGeocoding(false);
|
|
109
|
-
};
|
|
110
|
-
}, [geocoder, at, locale, autofillFields]);
|
|
117
|
+
return () => controller.abort();
|
|
118
|
+
}, [geocodeRequest]);
|
|
111
119
|
/**
|
|
112
120
|
* Komunikat błędu pola albo `null`. Dzień otwarty musi mieć obie godziny i różne od siebie;
|
|
113
|
-
* dzień oznaczony jako zamknięty przechodzi bez zastrzeżeń
|
|
121
|
+
* dzień oznaczony jako zamknięty przechodzi bez zastrzeżeń - to prawidłowa odpowiedź,
|
|
114
122
|
* a nie brak danych.
|
|
115
123
|
*/
|
|
116
124
|
const errorFor = (def) => {
|
|
@@ -174,7 +182,7 @@ export function KptMapCreateDialog({ category, at, geocoder = null, onSave, onCa
|
|
|
174
182
|
const common = { onTouch: touch(def.key), invalid: !!visibleError(def), touched: !!touched[def.key] };
|
|
175
183
|
switch (def.type) {
|
|
176
184
|
case 'textarea':
|
|
177
|
-
return (_jsx(KptTextarea, { value:
|
|
185
|
+
return (_jsx(KptTextarea, { value: asText(value), onValueChange: (next) => set(def.key, next), placeholder: def.placeholder ?? '', ...common }));
|
|
178
186
|
case 'number':
|
|
179
187
|
return (_jsx(KptInputNumber, { value: value, onValueChange: (next) => set(def.key, next), min: typeof def.min === 'number' ? def.min : undefined, max: typeof def.max === 'number' ? def.max : undefined, placeholder: def.placeholder ?? '', ...common }));
|
|
180
188
|
case 'date':
|
|
@@ -186,11 +194,11 @@ export function KptMapCreateDialog({ category, at, geocoder = null, onSave, onCa
|
|
|
186
194
|
case 'checkbox':
|
|
187
195
|
return (_jsx(KptCheckbox, { checked: !!value, onCheckedChange: (next) => set(def.key, next), label: def.placeholder ?? '', onTouch: touch(def.key) }));
|
|
188
196
|
case 'image':
|
|
189
|
-
return (_jsx(KptMapImageField, { value:
|
|
197
|
+
return (_jsx(KptMapImageField, { value: asText(value), onValueChange: (next) => set(def.key, next), invalid: !!visibleError(def), touched: !!touched[def.key], onTouch: touch(def.key) }));
|
|
190
198
|
case 'hours':
|
|
191
199
|
return (_jsx(KptMapHoursField, { value: value ?? emptyWeek(), onValueChange: (next) => set(def.key, next), onTouch: touch(def.key) }));
|
|
192
200
|
default:
|
|
193
|
-
return (_jsx(KptInput, { id: controlId(def), type: def.type === 'tel' || def.type === 'email' || def.type === 'url' ? def.type : 'text', value:
|
|
201
|
+
return (_jsx(KptInput, { id: controlId(def), type: def.type === 'tel' || def.type === 'email' || def.type === 'url' ? def.type : 'text', value: asText(value), onValueChange: (next) => set(def.key, next), placeholder: def.placeholder ?? (def.type === 'url' ? 'https://' : ''), ...common }));
|
|
194
202
|
}
|
|
195
203
|
}
|
|
196
204
|
}
|
|
@@ -6,14 +6,14 @@ export interface KptMapHoursFieldProps extends Omit<ComponentPropsWithRef<'div'>
|
|
|
6
6
|
onValueChange: (value: KptMapOpeningHours) => void;
|
|
7
7
|
disabled?: boolean;
|
|
8
8
|
readOnly?: boolean;
|
|
9
|
-
/** Wywoływane po każdej zmianie
|
|
9
|
+
/** Wywoływane po każdej zmianie - moment, w którym pole staje się dotknięte. */
|
|
10
10
|
onTouch?: () => void;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
* Pole
|
|
13
|
+
* Pole "godziny otwarcia" formularza dodawania lokalizacji (`type: 'hours'` w schemie).
|
|
14
14
|
*
|
|
15
|
-
* Siedem wierszy od poniedziałku, każdy z parą godzin i znacznikiem
|
|
16
|
-
*
|
|
15
|
+
* Siedem wierszy od poniedziałku, każdy z parą godzin i znacznikiem "zamknięte". Skrót
|
|
16
|
+
* "tak samo przez cały tydzień" kopiuje poniedziałek na pozostałe dni - bez niego wypełnienie
|
|
17
17
|
* formularza to czternaście pól.
|
|
18
18
|
*
|
|
19
19
|
* Nazwy dni idą z `Intl`, nie ze słownika: rozkład tygodnia jest uniwersalny, a tłumaczenie
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
3
|
import { emptyWeek, weekdayName } from '@konce-pt/map';
|
|
3
4
|
import { useState } from 'react';
|
|
@@ -10,15 +11,15 @@ import { KptIconButton } from "../icon-button/icon-button.js";
|
|
|
10
11
|
/** Ile przedziałów na dobę dopuszczamy. Dwa pokrywają przerwę i dobę przez północ. */
|
|
11
12
|
const MAX_RANGES = 2;
|
|
12
13
|
/**
|
|
13
|
-
* Snap minut na tarczy zegara. Godziny otwarcia chodzą co kwadrans, a nie co minutę
|
|
14
|
+
* Snap minut na tarczy zegara. Godziny otwarcia chodzą co kwadrans, a nie co minutę -
|
|
14
15
|
* krok 5 daje trafienie w 07:30 czy 22:45 bez celowania w pojedynczą minutę.
|
|
15
16
|
*/
|
|
16
17
|
const MINUTE_STEP = 5;
|
|
17
18
|
/**
|
|
18
|
-
* Pole
|
|
19
|
+
* Pole "godziny otwarcia" formularza dodawania lokalizacji (`type: 'hours'` w schemie).
|
|
19
20
|
*
|
|
20
|
-
* Siedem wierszy od poniedziałku, każdy z parą godzin i znacznikiem
|
|
21
|
-
*
|
|
21
|
+
* Siedem wierszy od poniedziałku, każdy z parą godzin i znacznikiem "zamknięte". Skrót
|
|
22
|
+
* "tak samo przez cały tydzień" kopiuje poniedziałek na pozostałe dni - bez niego wypełnienie
|
|
22
23
|
* formularza to czternaście pól.
|
|
23
24
|
*
|
|
24
25
|
* Nazwy dni idą z `Intl`, nie ze słownika: rozkład tygodnia jest uniwersalny, a tłumaczenie
|
|
@@ -26,7 +27,7 @@ const MINUTE_STEP = 5;
|
|
|
26
27
|
*/
|
|
27
28
|
export function KptMapHoursField({ value, onValueChange, disabled = false, readOnly = false, onTouch, locale: localeOverride, dictionary, className, ...rest }) {
|
|
28
29
|
const { t, locale } = useKptMessages({ locale: localeOverride, dictionary });
|
|
29
|
-
/** Skrót
|
|
30
|
+
/** Skrót "tak samo przez cały tydzień" - stan pola, nie część wartości. */
|
|
30
31
|
const [sameAllWeek, setSameAllWeek] = useState(false);
|
|
31
32
|
const rows = Array.from({ length: 7 }, (_, index) => {
|
|
32
33
|
const day = (index + 1);
|
|
@@ -38,7 +39,7 @@ export function KptMapHoursField({ value, onValueChange, disabled = false, readO
|
|
|
38
39
|
ranges: (entry?.ranges ?? []).map((range) => ({ from: range.from, to: range.to })),
|
|
39
40
|
};
|
|
40
41
|
});
|
|
41
|
-
/** Zapis zawsze przez pełny, uporządkowany tydzień
|
|
42
|
+
/** Zapis zawsze przez pełny, uporządkowany tydzień - model nie ma dziur. */
|
|
42
43
|
const write = (change) => {
|
|
43
44
|
const base = emptyWeek().map((day) => value.find((entry) => entry.day === day.day) ?? day);
|
|
44
45
|
onValueChange(change(base));
|
|
@@ -79,7 +80,7 @@ export function KptMapHoursField({ value, onValueChange, disabled = false, readO
|
|
|
79
80
|
ranges[index][edge] = time;
|
|
80
81
|
return { ...day, closed: false, ranges };
|
|
81
82
|
});
|
|
82
|
-
return (_jsxs("div", { className: cn('kpt-map-hours-field', className), ...rest, children: [_jsx(KptCheckbox, { className: "kpt-map-hours-field__same", checked: sameAllWeek, onCheckedChange: onSameAllWeek, disabled: disabled || readOnly, label: t('map.field.hoursSameAllWeek') }), _jsx("ul", { className: "kpt-map-hours-field__week", children: rows.map((row) => (_jsxs("li", { className: "kpt-map-hours-field__day", "data-locked": locked(row) ? '' : undefined, children: [_jsx("span", { className: "kpt-map-hours-field__name", children: row.name }), _jsx("div", { className: "kpt-map-hours-field__ranges", children: !row.closed ? (_jsxs(_Fragment, { children: [row.ranges.map((range, index) => (_jsxs("div", { className: "kpt-map-hours-field__range", children: [_jsx(KptDatepicker, { selectionMode: "time", minuteStep: MINUTE_STEP, value: range.from, onValueChange: (time) => setTime(row, index, 'from', String(time ?? '')), disabled: locked(row), "aria-label": `${t('map.field.hoursFrom')}
|
|
83
|
+
return (_jsxs("div", { className: cn('kpt-map-hours-field', className), ...rest, children: [_jsx(KptCheckbox, { className: "kpt-map-hours-field__same", checked: sameAllWeek, onCheckedChange: onSameAllWeek, disabled: disabled || readOnly, label: t('map.field.hoursSameAllWeek') }), _jsx("ul", { className: "kpt-map-hours-field__week", children: rows.map((row) => (_jsxs("li", { className: "kpt-map-hours-field__day", "data-locked": locked(row) ? '' : undefined, children: [_jsx("span", { className: "kpt-map-hours-field__name", children: row.name }), _jsx("div", { className: "kpt-map-hours-field__ranges", children: !row.closed ? (_jsxs(_Fragment, { children: [row.ranges.map((range, index) => (_jsxs("div", { className: "kpt-map-hours-field__range", children: [_jsx(KptDatepicker, { selectionMode: "time", minuteStep: MINUTE_STEP, value: range.from, onValueChange: (time) => setTime(row, index, 'from', String(time ?? '')), disabled: locked(row), "aria-label": `${t('map.field.hoursFrom')} - ${row.name}`, onTouch: onTouch }), _jsx("span", { className: "kpt-map-hours-field__dash", "aria-hidden": "true", children: "-" }), _jsx(KptDatepicker, { selectionMode: "time", minuteStep: MINUTE_STEP, value: range.to, onValueChange: (time) => setTime(row, index, 'to', String(time ?? '')), disabled: locked(row), "aria-label": `${t('map.field.hoursTo')} - ${row.name}`, onTouch: onTouch }), row.ranges.length > 1 ? (_jsx(KptIconButton, { variant: "text", size: "sm", disabled: locked(row), "aria-label": t('map.field.hoursRemoveRange'), onClick: () => patch(row.day, (day) => ({
|
|
83
84
|
...day,
|
|
84
85
|
ranges: day.ranges.filter((_, i) => i !== index).map((r) => ({ ...r })),
|
|
85
86
|
})), children: _jsx(KptIcon, { name: "minus" }) })) : null] }, index))), row.ranges.length < MAX_RANGES ? (_jsxs("button", { className: "kpt-map-hours-field__add", type: "button", disabled: locked(row), onClick: () => patch(row.day, (day) => ({
|
|
@@ -12,13 +12,13 @@ export interface KptMapImageFieldProps extends Omit<ComponentPropsWithRef<'div'>
|
|
|
12
12
|
onTouch?: () => void;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
-
* Pole
|
|
15
|
+
* Pole "zdjęcie" formularza dodawania lokalizacji (`type: 'image'` w schemie kategorii).
|
|
16
16
|
*
|
|
17
17
|
* Wartością jest zawsze **string**: albo `data:` z wybranego pliku, albo adres wklejony przez
|
|
18
18
|
* użytkownika. Karta miejsca nie rozróżnia jednego od drugiego, więc formularz nie musi
|
|
19
19
|
* decydować za aplikację, gdzie zdjęcia mieszkają.
|
|
20
20
|
*
|
|
21
|
-
* Plik czytamy w przeglądarce i nigdzie nie wysyłamy
|
|
21
|
+
* Plik czytamy w przeglądarce i nigdzie nie wysyłamy - biblioteka nie ma i nie chce mieć
|
|
22
22
|
* wiedzy o storage'u aplikacji.
|
|
23
23
|
*/
|
|
24
24
|
export declare function KptMapImageField({ value, onValueChange, disabled, readOnly, invalid, touched, maxBytes, onTouch, locale, dictionary, className, ...rest }: Readonly<KptMapImageFieldProps>): import("react").JSX.Element;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
3
|
import { useState } from 'react';
|
|
3
4
|
import { cn } from "../internal/cn.js";
|
|
@@ -5,16 +6,16 @@ import { useKptMessages } from "../i18n/i18n-context.js";
|
|
|
5
6
|
import { KptFileUpload } from "../file-upload/file-upload.js";
|
|
6
7
|
import { KptIcon } from "../icon/icon.js";
|
|
7
8
|
import { KptInput } from "../input/input.js";
|
|
8
|
-
/** Domyślny limit pliku. Data URL puchnie o
|
|
9
|
+
/** Domyślny limit pliku. Data URL puchnie o ~1/3, a wartość leci w `onLocationCreate`. */
|
|
9
10
|
const DEFAULT_MAX_BYTES = 2 * 1024 * 1024;
|
|
10
11
|
/**
|
|
11
|
-
* Pole
|
|
12
|
+
* Pole "zdjęcie" formularza dodawania lokalizacji (`type: 'image'` w schemie kategorii).
|
|
12
13
|
*
|
|
13
14
|
* Wartością jest zawsze **string**: albo `data:` z wybranego pliku, albo adres wklejony przez
|
|
14
15
|
* użytkownika. Karta miejsca nie rozróżnia jednego od drugiego, więc formularz nie musi
|
|
15
16
|
* decydować za aplikację, gdzie zdjęcia mieszkają.
|
|
16
17
|
*
|
|
17
|
-
* Plik czytamy w przeglądarce i nigdzie nie wysyłamy
|
|
18
|
+
* Plik czytamy w przeglądarce i nigdzie nie wysyłamy - biblioteka nie ma i nie chce mieć
|
|
18
19
|
* wiedzy o storage'u aplikacji.
|
|
19
20
|
*/
|
|
20
21
|
export function KptMapImageField({ value, onValueChange, disabled = false, readOnly = false, invalid = false, touched = false, maxBytes = DEFAULT_MAX_BYTES, onTouch, locale, dictionary, className, ...rest }) {
|
|
@@ -42,12 +43,12 @@ export function KptMapImageField({ value, onValueChange, disabled = false, readO
|
|
|
42
43
|
return;
|
|
43
44
|
}
|
|
44
45
|
const reader = new FileReader();
|
|
45
|
-
reader.onload = () => onValueChange(
|
|
46
|
+
reader.onload = () => onValueChange((typeof reader.result === 'string' ? reader.result : ''));
|
|
46
47
|
reader.onerror = () => setSizeError(t('map.field.imageTooLarge', { max: maxLabel }));
|
|
47
48
|
reader.readAsDataURL(file);
|
|
48
49
|
};
|
|
49
50
|
return (_jsxs("div", { className: cn('kpt-map-image-field', className), ...rest, children: [_jsx(KptFileUpload, { accept: "image/*", value: files, onValueChange: onFiles, disabled: disabled || readOnly, invalid: invalid, touched: touched }), _jsxs("label", { className: "kpt-map-image-field__url", children: [_jsx("span", { className: "kpt-map-image-field__url-label", children: t('map.field.orPasteUrl') }), _jsx(KptInput, { type: "url", value: urlValue, onValueChange: (url) => {
|
|
50
|
-
// Adres i plik wykluczają się
|
|
51
|
+
// Adres i plik wykluczają się - dwa źródła jednej wartości myliłyby użytkownika.
|
|
51
52
|
if (url)
|
|
52
53
|
setFiles([]);
|
|
53
54
|
setSizeError(null);
|
package/dist/map/map-legend.d.ts
CHANGED
|
@@ -4,20 +4,20 @@ import { type KptI18nOverrides } from '../i18n/i18n-context.tsx';
|
|
|
4
4
|
export interface KptMapLegendProps extends Omit<ComponentPropsWithRef<'div'>, 'children'>, KptI18nOverrides {
|
|
5
5
|
categories: readonly KptMapCategory[];
|
|
6
6
|
/**
|
|
7
|
-
* Identyfikatory ukrytych kategorii
|
|
7
|
+
* Identyfikatory ukrytych kategorii - kontrolowane. Nazwa dłuższa niż `hidden` z portu
|
|
8
8
|
* Angulara, bo `hidden` na elemencie DOM jest booleanem i kolidowałoby z propsem `<div>`.
|
|
9
9
|
*/
|
|
10
10
|
hiddenCategories?: string[];
|
|
11
11
|
defaultHiddenCategories?: string[];
|
|
12
12
|
onHiddenCategoriesChange?: (hidden: string[]) => void;
|
|
13
|
-
/** Opcjonalne liczniki `{ categoryId: liczba }`
|
|
13
|
+
/** Opcjonalne liczniki `{ categoryId: liczba }` - pokazywane przy etykiecie. */
|
|
14
14
|
counts?: Record<string, number> | null;
|
|
15
15
|
orientation?: 'horizontal' | 'vertical';
|
|
16
|
-
/** Wyłącza chowanie kategorii
|
|
16
|
+
/** Wyłącza chowanie kategorii - legenda staje się czysto informacyjna. */
|
|
17
17
|
interactive?: boolean;
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
|
-
* Legenda mapy
|
|
20
|
+
* Legenda mapy - lista kategorii ze znacznikiem koloru i ikoną. Pozycje są przyciskami:
|
|
21
21
|
* kliknięcie chowa i pokazuje kategorię.
|
|
22
22
|
*
|
|
23
23
|
* `KptMap` renderuje ją sam pod mapą przy `legend`; kto chce ją gdzie indziej, wyłącza tamto
|
package/dist/map/map-legend.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
3
|
import { colorVarOf, contrastVarOf } from '@konce-pt/map';
|
|
3
4
|
import { cn } from "../internal/cn.js";
|
|
@@ -5,7 +6,7 @@ import { useControllableState } from "../internal/use-controllable-state.js";
|
|
|
5
6
|
import { useKptMessages } from "../i18n/i18n-context.js";
|
|
6
7
|
import { KptIcon } from "../icon/icon.js";
|
|
7
8
|
/**
|
|
8
|
-
* Legenda mapy
|
|
9
|
+
* Legenda mapy - lista kategorii ze znacznikiem koloru i ikoną. Pozycje są przyciskami:
|
|
9
10
|
* kliknięcie chowa i pokazuje kategorię.
|
|
10
11
|
*
|
|
11
12
|
* `KptMap` renderuje ją sam pod mapą przy `legend`; kto chce ją gdzie indziej, wyłącza tamto
|
|
@@ -33,7 +34,7 @@ export function KptMapLegend({ categories, hiddenCategories, defaultHiddenCatego
|
|
|
33
34
|
const isHidden = hiddenSet.has(category.id);
|
|
34
35
|
const label = t(isHidden ? 'map.showCategory' : 'map.hideCategory', { category: category.label });
|
|
35
36
|
return (_jsxs("button", { type: "button", className: cn('kpt-map-legend__item', isHidden && 'kpt-map-legend__item--off'), style: {
|
|
36
|
-
// Glif dostaje kolor kontrastowy
|
|
37
|
+
// Glif dostaje kolor kontrastowy - zaszyta biel gubi się na jasnych rolach.
|
|
37
38
|
'--_kpt-legend-color': colorVarOf(category.color),
|
|
38
39
|
'--_kpt-legend-fg': contrastVarOf(category.color),
|
|
39
40
|
}, "aria-pressed": interactive ? !isHidden : undefined, "aria-label": interactive ? label : undefined, disabled: !interactive, onClick: () => toggle(category.id), children: [_jsx("span", { className: "kpt-map-legend__swatch", "aria-hidden": "true", children: category.icon ? _jsx(KptIcon, { name: category.icon }) : null }), _jsx("span", { className: "kpt-map-legend__label", children: category.label }), counts ? _jsx("span", { className: "kpt-map-legend__count", children: counts[category.id] ?? 0 }) : null] }, category.id));
|
|
@@ -24,14 +24,14 @@ export interface KptMapPoiCardProps extends Omit<ComponentPropsWithRef<'div'>, '
|
|
|
24
24
|
onShare?: (poi: KptMapPoi) => void;
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
|
-
* Karta miejsca do popupu mapy
|
|
27
|
+
* Karta miejsca do popupu mapy - dystans, zdjęcie, akcje, kategoria, rozwijane godziny
|
|
28
28
|
* otwarcia i wiersze kontaktowe z kopiowaniem.
|
|
29
29
|
*
|
|
30
30
|
* Komponent jest sterowany danymi: bierze `KptMapPoi`, a nie model domenowy aplikacji.
|
|
31
|
-
* Mapowanie `KptMapLocation.data`
|
|
31
|
+
* Mapowanie `KptMapLocation.data` -> `KptMapPoi` robi aplikacja, dzięki czemu karta nie wie,
|
|
32
32
|
* czy pokazuje ładowarkę, restaurację, czy punkt serwisowy.
|
|
33
33
|
*
|
|
34
|
-
* Sam popup trzeba przełączyć na `popupLayout="card"`
|
|
34
|
+
* Sam popup trzeba przełączyć na `popupLayout="card"` - inaczej karta dostanie szerokość
|
|
35
35
|
* i padding przeznaczone dla treści tekstowej.
|
|
36
36
|
*
|
|
37
37
|
* @example
|
package/dist/map/map-poi-card.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
3
|
import { foregroundVarOf, formatDistance, formatLatLng, groupWeek, isAlwaysOpen, isOpenAt, nextChange, normalizeUrl, prettyUrl, } from '@konce-pt/map';
|
|
3
4
|
import { useId, useRef, useState } from 'react';
|
|
@@ -8,14 +9,14 @@ import { KptButton } from "../button/button.js";
|
|
|
8
9
|
import { KptIcon } from "../icon/icon.js";
|
|
9
10
|
import { KptIconButton } from "../icon-button/icon-button.js";
|
|
10
11
|
/**
|
|
11
|
-
* Karta miejsca do popupu mapy
|
|
12
|
+
* Karta miejsca do popupu mapy - dystans, zdjęcie, akcje, kategoria, rozwijane godziny
|
|
12
13
|
* otwarcia i wiersze kontaktowe z kopiowaniem.
|
|
13
14
|
*
|
|
14
15
|
* Komponent jest sterowany danymi: bierze `KptMapPoi`, a nie model domenowy aplikacji.
|
|
15
|
-
* Mapowanie `KptMapLocation.data`
|
|
16
|
+
* Mapowanie `KptMapLocation.data` -> `KptMapPoi` robi aplikacja, dzięki czemu karta nie wie,
|
|
16
17
|
* czy pokazuje ładowarkę, restaurację, czy punkt serwisowy.
|
|
17
18
|
*
|
|
18
|
-
* Sam popup trzeba przełączyć na `popupLayout="card"`
|
|
19
|
+
* Sam popup trzeba przełączyć na `popupLayout="card"` - inaczej karta dostanie szerokość
|
|
19
20
|
* i padding przeznaczone dla treści tekstowej.
|
|
20
21
|
*
|
|
21
22
|
* @example
|
|
@@ -37,9 +38,9 @@ export function KptMapPoiCard({ poi, distance = null, category = null, primaryLa
|
|
|
37
38
|
defaultValue: defaultHoursExpanded,
|
|
38
39
|
onChange: onHoursExpandedChange,
|
|
39
40
|
});
|
|
40
|
-
/** Rośnie przy każdym rozwinięciu godzin
|
|
41
|
+
/** Rośnie przy każdym rozwinięciu godzin - karta bywa otwarta dłużej niż minutę. */
|
|
41
42
|
const [now, setNow] = useState(() => Date.now());
|
|
42
|
-
/** Klucz wiersza, którego wartość właśnie skopiowano
|
|
43
|
+
/** Klucz wiersza, którego wartość właśnie skopiowano - przełącza ikonę na "check". */
|
|
43
44
|
const [justCopied, setJustCopied] = useState(null);
|
|
44
45
|
const copyTimer = useRef(null);
|
|
45
46
|
/** Bez API schowka przycisk kopiowania w ogóle się nie renderuje. */
|
|
@@ -50,7 +51,7 @@ export function KptMapPoiCard({ poi, distance = null, category = null, primaryLa
|
|
|
50
51
|
const open = isOpenAt(poi.hours, new Date(now));
|
|
51
52
|
const hoursGroups = groupWeek(poi.hours, locale);
|
|
52
53
|
const statusLabel = alwaysOpen ? t('map.poi.alwaysOpen') : t(open ? 'map.poi.openNow' : 'map.poi.closedNow');
|
|
53
|
-
/** Dopisek
|
|
54
|
+
/** Dopisek "otwarcie o 11:00" - nie ma go dla 24/7 ani gdy zmiana jest dalej niż doba. */
|
|
54
55
|
const statusHint = (() => {
|
|
55
56
|
if (alwaysOpen || !hasHours)
|
|
56
57
|
return null;
|
|
@@ -110,7 +111,7 @@ export function KptMapPoiCard({ poi, distance = null, category = null, primaryLa
|
|
|
110
111
|
await navigator.clipboard.writeText(row.copyValue);
|
|
111
112
|
}
|
|
112
113
|
catch {
|
|
113
|
-
// Odmowa zgody albo brak bezpiecznego kontekstu
|
|
114
|
+
// Odmowa zgody albo brak bezpiecznego kontekstu - nie ma czego zgłaszać użytkownikowi.
|
|
114
115
|
return;
|
|
115
116
|
}
|
|
116
117
|
setJustCopied(row.kind);
|
|
@@ -145,8 +146,8 @@ export function KptMapPoiCard({ poi, distance = null, category = null, primaryLa
|
|
|
145
146
|
};
|
|
146
147
|
const distanceLabel = formatDistance(distance, locale);
|
|
147
148
|
return (_jsxs("div", { className: cn('kpt-map-poi', className), ...rest, children: [_jsxs("header", { className: "kpt-map-poi__head", children: [_jsx("p", { className: "kpt-map-poi__title", role: "heading", "aria-level": 3, children: poi.title }), closable ? (_jsx(KptIconButton, { hostProps: { className: 'kpt-map-poi__close' }, variant: "text", size: "sm", "aria-label": t('common.close'), onClick: onClose, children: _jsx(KptIcon, { name: "x" }) })) : null] }), _jsxs("p", { className: "kpt-map-poi__meta", children: [distanceLabel ? _jsx("strong", { className: "kpt-map-poi__distance", children: distanceLabel }) : null, poi.address ? _jsx("span", { className: "kpt-map-poi__address", children: poi.address }) : null] }), _jsxs("div", { className: "kpt-map-poi__scroll", children: [_jsx("div", { className: "kpt-map-poi__media", children: poi.photo ? (_jsx("img", { className: "kpt-map-poi__photo", src: poi.photo, alt: poi.photoAlt ?? poi.title, loading: "lazy", decoding: "async" })) : (_jsx("div", { className: "kpt-map-poi__photo-empty", "aria-label": t('map.poi.noPhoto'), role: "img", children: _jsx(KptIcon, { name: "photo", size: "1.75rem" }) })) }), _jsxs("div", { className: "kpt-map-poi__actions", children: [primaryLabel ? (_jsx(KptButton, { hostProps: { className: 'kpt-map-poi__cta' }, size: "sm", fullWidth: true, onClick: () => onPrimaryAction?.(poi), children: primaryLabel })) : null, showShare ? (_jsx(KptIconButton, { variant: "outline", size: "sm", "aria-label": t('map.poi.share'), onClick: share, children: _jsx(KptIcon, { name: "share" }) })) : null, showFavourite ? (_jsx(KptIconButton, { hostProps: { className: 'kpt-map-poi__fav', 'data-on': isFavourite ? '' : undefined }, variant: "outline", size: "sm", "aria-pressed": isFavourite, "aria-label": t(isFavourite ? 'map.poi.removeFavourite' : 'map.poi.addFavourite'), onClick: () => setFavourite(!isFavourite), children: _jsx(KptIcon, { name: "star" }) })) : null] }), category ? (_jsxs("p", { className: "kpt-map-poi__category", style: { '--_kpt-poi-color': foregroundVarOf(category.color) }, children: [category.icon ? _jsx(KptIcon, { className: "kpt-map-poi__category-icon", name: category.icon }) : null, category.label] })) : null, hasHours ? (_jsxs("div", { className: "kpt-map-poi__hours", children: [_jsxs("button", { className: "kpt-map-poi__hours-toggle", type: "button", "aria-expanded": expanded, "aria-controls": hoursId, onClick: () => {
|
|
148
|
-
// Odświeżamy zegar przy rozwinięciu
|
|
149
|
+
// Odświeżamy zegar przy rozwinięciu - karta bywa otwarta dłużej niż minutę.
|
|
149
150
|
setNow(Date.now());
|
|
150
151
|
setExpanded(!expanded);
|
|
151
|
-
}, children: [_jsx(KptIcon, { className: "kpt-map-poi__row-icon", name: "clock" }), _jsx("span", { className: "kpt-map-poi__status", "data-open": open || alwaysOpen, children: statusLabel }), statusHint ? _jsxs("span", { className: "kpt-map-poi__status-hint", children: ["
|
|
152
|
+
}, children: [_jsx(KptIcon, { className: "kpt-map-poi__row-icon", name: "clock" }), _jsx("span", { className: "kpt-map-poi__status", "data-open": open || alwaysOpen, children: statusLabel }), statusHint ? _jsxs("span", { className: "kpt-map-poi__status-hint", children: [", ", statusHint] }) : null, _jsx(KptIcon, { className: "kpt-map-poi__chevron", name: "chevron-down" })] }), expanded ? (_jsx("dl", { className: "kpt-map-poi__week", id: hoursId, children: hoursGroups.map((group) => (_jsxs("div", { style: { display: 'contents' }, children: [_jsx("dt", { className: "kpt-map-poi__week-day", children: group.label }), _jsx("dd", { className: "kpt-map-poi__week-hours", children: group.closed ? (_jsx("span", { className: "kpt-map-poi__week-closed", children: t('map.poi.closedDay') })) : (group.ranges.map((range) => (_jsx("span", { className: "kpt-map-poi__week-range", children: range }, range)))) })] }, group.label))) })) : null] })) : null, rows.length || poi.facts?.length ? (_jsxs("ul", { className: "kpt-map-poi__rows", children: [rows.map((row) => (_jsxs("li", { className: "kpt-map-poi__row", children: [_jsx(KptIcon, { className: "kpt-map-poi__row-icon", name: row.icon }), row.href ? (_jsx("a", { className: "kpt-map-poi__row-value kpt-map-poi__row-link", href: row.href, target: row.external ? '_blank' : undefined, rel: row.external ? 'noopener noreferrer' : undefined, children: row.text })) : (_jsx("span", { className: "kpt-map-poi__row-value", children: row.text })), _jsxs("span", { className: "kpt-map-poi__row-actions", children: [row.href ? (_jsx("a", { className: "kpt-map-poi__row-action", href: row.href, target: row.external ? '_blank' : undefined, rel: row.external ? 'noopener noreferrer' : undefined, "aria-label": row.actionLabel, title: row.actionLabel, children: _jsx(KptIcon, { name: row.actionIcon }) })) : null, canCopy ? (_jsx("button", { className: "kpt-map-poi__row-action", type: "button", "aria-label": t('map.poi.copy'), title: t('map.poi.copy'), onClick: () => void copy(row), children: _jsx(KptIcon, { name: justCopied === row.kind ? 'check' : 'copy' }) })) : null] })] }, row.kind))), (poi.facts ?? []).map((fact) => (_jsxs("li", { className: "kpt-map-poi__row kpt-map-poi__row--fact", children: [fact.icon ? (_jsx(KptIcon, { className: "kpt-map-poi__row-icon", name: fact.icon })) : (_jsx("span", { className: "kpt-map-poi__row-icon", "aria-hidden": "true" })), _jsxs("span", { className: "kpt-map-poi__row-value", children: [_jsx("span", { className: "kpt-map-poi__fact-label", children: fact.label }), " ", fact.value] })] }, fact.label)))] })) : null, _jsx("p", { className: "kpt-map-poi__live", "aria-live": "polite", children: justCopied ? t('map.poi.copied') : '' })] })] }));
|
|
152
153
|
}
|
package/dist/map/map-search.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { KptMapBounds, KptMapSearchResult } from '@konce-pt/map';
|
|
2
2
|
import { type ComponentPropsWithRef } from 'react';
|
|
3
3
|
import { type KptI18nOverrides } from '../i18n/i18n-context.tsx';
|
|
4
|
+
import { type KptSpeechColor } from '../speech/speech-button.tsx';
|
|
4
5
|
import type { KptMapGeocoderPort } from './ports.ts';
|
|
5
6
|
export interface KptMapSearchProps extends Omit<ComponentPropsWithRef<'div'>, 'children' | 'onSelect'>, KptI18nOverrides {
|
|
6
7
|
/** Geokoder tego pola. Bez metody `search()` pole renderuje się wyłączone. */
|
|
@@ -13,25 +14,35 @@ export interface KptMapSearchProps extends Omit<ComponentPropsWithRef<'div'>, 'c
|
|
|
13
14
|
debounce?: number;
|
|
14
15
|
/** Ile podpowiedzi najwyżej. */
|
|
15
16
|
limit?: number;
|
|
16
|
-
/** Zawężenie twarde do krajów (ISO 3166-1 alpha-2)
|
|
17
|
+
/** Zawężenie twarde do krajów (ISO 3166-1 alpha-2) - wyniki spoza nich nie wrócą. */
|
|
17
18
|
countryCodes?: readonly string[] | null;
|
|
18
19
|
/** Preferowany prostokąt wyników. Nie odcina reszty świata, tylko przesuwa ją niżej. */
|
|
19
20
|
viewbox?: KptMapBounds | null;
|
|
20
21
|
disabled?: boolean;
|
|
21
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Mikrofon w polu (Web Speech API): kliknięcie czyści frazę, a jedna podyktowana wypowiedź
|
|
24
|
+
* staje się zapytaniem - z tym samym `debounce` i `minLength` co pisanie. Bez wsparcia
|
|
25
|
+
* przeglądarki się nie pokazuje.
|
|
26
|
+
*/
|
|
27
|
+
speech?: boolean;
|
|
28
|
+
/** Język dyktowania (BCP 47); bez niego z `KptI18nProvider`. */
|
|
29
|
+
speechLang?: string;
|
|
30
|
+
/** Kolor "stop" i fali w trakcie nasłuchu; domyślnie kolor motywu. */
|
|
31
|
+
speechColor?: KptSpeechColor;
|
|
32
|
+
/** Wybrano miejsce - **zawsze ze współrzędnymi**. */
|
|
22
33
|
onSelect?: (result: KptMapSearchResult) => void;
|
|
23
|
-
/** Pole wyczyszczone
|
|
34
|
+
/** Pole wyczyszczone - rodzic sprząta po sobie (np. chowa tymczasową pinezkę). */
|
|
24
35
|
onClear?: () => void;
|
|
25
36
|
}
|
|
26
37
|
/**
|
|
27
38
|
* Wyszukiwarka adresów: pole z podpowiedziami z geokodera. Wynik wyboru leci w `onSelect`,
|
|
28
|
-
* a co z nim zrobić
|
|
39
|
+
* a co z nim zrobić - decyduje rodzic (`KptMap` przenosi na niego widok).
|
|
29
40
|
*
|
|
30
41
|
* Świadomie **nie** stoi na `KptAutocomplete`: tamten filtruje opcje po stronie klienta (wyniki
|
|
31
42
|
* geokodera, tolerancyjne na literówki, wypadałyby z listy), a jego wartością jest sam `string`
|
|
32
|
-
*
|
|
43
|
+
* - nie ma czym przewieźć współrzędnych.
|
|
33
44
|
*
|
|
34
45
|
* @example
|
|
35
46
|
* <KptMapSearch geocoder={geocoder} viewbox={bounds} onSelect={goTo} />
|
|
36
47
|
*/
|
|
37
|
-
export declare function KptMapSearch({ geocoder, placeholder, minLength, debounce, limit, countryCodes, viewbox, disabled, onSelect, onClear, locale: localeOverride, dictionary, className, ...rest }: Readonly<KptMapSearchProps>): import("react").JSX.Element;
|
|
48
|
+
export declare function KptMapSearch({ geocoder, placeholder, minLength, debounce, limit, countryCodes, viewbox, disabled, speech, speechLang, speechColor, onSelect, onClear, locale: localeOverride, dictionary, className, ...rest }: Readonly<KptMapSearchProps>): import("react").JSX.Element;
|