@konce-pt/react 0.12.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +122 -64
- package/dist/accordion/accordion.d.ts +14 -6
- package/dist/accordion/accordion.js +14 -7
- package/dist/accordion/llms.txt +22 -10
- package/dist/alert/alert.d.ts +2 -2
- package/dist/alert/alert.js +2 -2
- package/dist/alert/llms.txt +10 -10
- package/dist/app-shell/app-shell.d.ts +14 -14
- package/dist/app-shell/app-shell.js +11 -11
- package/dist/app-shell/llms.txt +13 -13
- package/dist/auth/auth-types.d.ts +6 -6
- package/dist/auth/auth.d.ts +2 -2
- package/dist/auth/auth.js +7 -7
- package/dist/auth/llms.txt +9 -9
- package/dist/autocomplete/autocomplete.d.ts +19 -6
- package/dist/autocomplete/autocomplete.js +23 -10
- package/dist/autocomplete/llms.txt +16 -5
- package/dist/avatar/avatar.d.ts +6 -6
- package/dist/avatar/avatar.js +5 -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 +3 -3
- package/dist/avatar-group/llms.txt +8 -8
- package/dist/backdrop/backdrop.d.ts +7 -7
- package/dist/backdrop/backdrop.js +16 -16
- 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 +4 -4
- package/dist/bottom-sheet/bottom-sheet.js +2 -2
- package/dist/bottom-sheet/llms.txt +9 -9
- package/dist/breadcrumb/breadcrumb.d.ts +2 -2
- package/dist/breadcrumb/breadcrumb.js +3 -3
- package/dist/breadcrumb/llms.txt +3 -3
- package/dist/button/button.d.ts +3 -3
- package/dist/button/button.js +8 -8
- package/dist/button/llms.txt +27 -19
- package/dist/button-group/button-group.d.ts +9 -9
- package/dist/button-group/button-group.js +30 -8
- package/dist/button-group/llms.txt +20 -14
- package/dist/card/card.d.ts +8 -8
- package/dist/card/card.js +6 -6
- package/dist/card/llms.txt +20 -20
- package/dist/carousel/carousel.d.ts +6 -6
- package/dist/carousel/carousel.js +4 -4
- package/dist/carousel/llms.txt +10 -10
- package/dist/charts/chart-legend.d.ts +3 -3
- package/dist/charts/chart-legend.js +1 -1
- package/dist/charts/chart-tooltip.d.ts +3 -3
- package/dist/charts/chart-tooltip.js +1 -1
- package/dist/charts/chart.d.ts +1 -1
- package/dist/charts/chart.js +8 -8
- package/dist/charts/llms.txt +6 -6
- package/dist/charts-entry/public-api.js +2 -2
- package/dist/chat/chat.d.ts +17 -10
- package/dist/chat/chat.js +42 -18
- package/dist/chat/llms.txt +32 -17
- package/dist/chat-composer/chat-composer.d.ts +17 -7
- package/dist/chat-composer/chat-composer.js +21 -8
- 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 +9 -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 +17 -7
- 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 +3 -3
- package/dist/chat-typing/llms.txt +6 -6
- package/dist/checkbox/checkbox.d.ts +13 -6
- package/dist/checkbox/checkbox.js +26 -7
- package/dist/checkbox/llms.txt +24 -12
- package/dist/chip/chip.d.ts +4 -4
- package/dist/chip/chip.js +2 -2
- package/dist/chip/llms.txt +11 -11
- package/dist/chips-input/chips-input.d.ts +4 -4
- package/dist/chips-input/chips-input.js +35 -9
- package/dist/chips-input/llms.txt +15 -8
- package/dist/clock/clock.d.ts +4 -4
- package/dist/clock/clock.js +7 -7
- package/dist/clock/llms.txt +8 -8
- package/dist/color-picker/color-picker.d.ts +6 -6
- package/dist/color-picker/color-picker.js +3 -3
- package/dist/color-picker/llms.txt +5 -5
- package/dist/confirm/confirm-container.d.ts +3 -3
- package/dist/confirm/confirm-container.js +5 -5
- package/dist/confirm/confirm-store.d.ts +4 -4
- package/dist/confirm/confirm-store.js +7 -7
- package/dist/confirm/llms.txt +6 -6
- package/dist/context-menu/context-menu.d.ts +1 -1
- package/dist/context-menu/context-menu.js +5 -5
- package/dist/context-menu/llms.txt +7 -7
- package/dist/data-table/data-table-types.d.ts +5 -5
- package/dist/data-table/data-table.d.ts +29 -8
- package/dist/data-table/data-table.js +340 -95
- package/dist/data-table/export-csv.d.ts +3 -3
- package/dist/data-table/export-csv.js +4 -4
- package/dist/data-table/llms.txt +127 -94
- package/dist/data-view/data-view.d.ts +13 -5
- package/dist/data-view/data-view.js +67 -6
- package/dist/data-view/llms.txt +29 -10
- package/dist/date-range/date-range.d.ts +9 -9
- package/dist/date-range/date-range.js +24 -24
- package/dist/date-range/llms.txt +20 -20
- package/dist/datepicker/datepicker.d.ts +10 -10
- package/dist/datepicker/datepicker.js +29 -29
- package/dist/datepicker/llms.txt +24 -24
- package/dist/dialog/dialog.d.ts +12 -7
- package/dist/dialog/dialog.js +4 -4
- package/dist/dialog/llms.txt +14 -11
- package/dist/divider/divider.d.ts +1 -1
- package/dist/divider/llms.txt +4 -4
- package/dist/drawer/drawer.d.ts +5 -5
- package/dist/drawer/drawer.js +2 -2
- package/dist/drawer/llms.txt +11 -11
- 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 +9 -6
- package/dist/fieldset/llms.txt +26 -9
- package/dist/file-upload/file-upload.d.ts +3 -3
- package/dist/file-upload/file-upload.js +7 -7
- package/dist/file-upload/llms.txt +7 -7
- 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 +26 -6
- package/dist/form-field/llms.txt +25 -11
- package/dist/galleria/galleria.d.ts +3 -3
- package/dist/galleria/galleria.js +5 -5
- 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 +3 -3
- package/dist/i18n/i18n-context.js +7 -7
- 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 +6 -6
- 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 +1 -1
- package/dist/image/llms.txt +13 -13
- package/dist/input/input.d.ts +18 -5
- package/dist/input/input.js +21 -6
- package/dist/input/llms.txt +25 -11
- package/dist/input-mask/input-mask.d.ts +1 -1
- package/dist/input-mask/input-mask.js +2 -2
- package/dist/input-mask/llms.txt +5 -5
- package/dist/input-number/input-number.d.ts +9 -9
- package/dist/input-number/input-number.js +11 -11
- package/dist/input-number/llms.txt +14 -14
- package/dist/input-otp/input-otp.d.ts +6 -6
- package/dist/input-otp/input-otp.js +10 -10
- package/dist/input-otp/llms.txt +9 -9
- 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 +2 -2
- package/dist/internal/mask.js +4 -4
- package/dist/internal/option-key.d.ts +2 -2
- package/dist/internal/option-key.js +2 -2
- 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 +8 -8
- package/dist/internal/password-strength.d.ts +2 -2
- package/dist/internal/password-strength.js +6 -6
- package/dist/internal/roving.d.ts +2 -2
- package/dist/internal/roving.js +3 -3
- package/dist/internal/scroll-lock.d.ts +1 -1
- package/dist/internal/scroll-lock.js +2 -2
- package/dist/internal/slot-children.d.ts +3 -3
- package/dist/internal/slot-children.js +4 -4
- package/dist/internal/slot.d.ts +3 -3
- package/dist/internal/slot.js +2 -2
- package/dist/internal/step.d.ts +3 -3
- package/dist/internal/step.js +4 -4
- package/dist/internal/tween.d.ts +5 -5
- package/dist/internal/tween.js +5 -5
- 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 +1 -1
- package/dist/internal/use-controllable-state.js +3 -3
- 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 +1 -1
- package/dist/internal/use-modal-focus.js +3 -3
- package/dist/knob/knob.d.ts +4 -4
- package/dist/knob/knob.js +14 -10
- package/dist/knob/llms.txt +17 -12
- package/dist/listbox/listbox.d.ts +6 -6
- package/dist/listbox/listbox.js +9 -9
- package/dist/listbox/llms.txt +10 -10
- 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 +25 -22
- package/dist/map/map-create-dialog.d.ts +4 -4
- package/dist/map/map-create-dialog.js +10 -10
- package/dist/map/map-hours-field.d.ts +4 -4
- package/dist/map/map-hours-field.js +7 -7
- package/dist/map/map-image-field.d.ts +2 -2
- package/dist/map/map-image-field.js +4 -4
- package/dist/map/map-legend.d.ts +4 -4
- package/dist/map/map-legend.js +2 -2
- package/dist/map/map-poi-card.d.ts +3 -3
- package/dist/map/map-poi-card.js +9 -9
- package/dist/map/map-search.d.ts +17 -6
- package/dist/map/map-search.js +21 -18
- package/dist/map/map.d.ts +21 -14
- package/dist/map/map.js +30 -29
- 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 +9 -9
- package/dist/megamenu/megamenu.d.ts +6 -6
- package/dist/megamenu/megamenu.js +10 -10
- 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.d.ts +2 -2
- package/dist/menu/menu.js +6 -6
- package/dist/menubar/llms.txt +10 -10
- package/dist/menubar/menubar.d.ts +5 -5
- package/dist/menubar/menubar.js +10 -10
- 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 +1 -1
- package/dist/motion/motion-context.d.ts +22 -0
- package/dist/motion/motion-context.js +28 -0
- package/dist/order-list/llms.txt +22 -10
- package/dist/order-list/order-list.d.ts +12 -4
- package/dist/order-list/order-list.js +104 -21
- package/dist/paginator/llms.txt +8 -8
- package/dist/paginator/paginator.js +1 -1
- package/dist/panel/llms.txt +25 -13
- package/dist/panel/panel.d.ts +11 -3
- package/dist/panel/panel.js +7 -4
- package/dist/password/llms.txt +16 -8
- package/dist/password/password.d.ts +2 -2
- package/dist/password/password.js +24 -3
- package/dist/peek/llms.txt +10 -10
- package/dist/peek/peek.d.ts +6 -6
- package/dist/peek/peek.js +7 -7
- package/dist/pick-list/llms.txt +33 -13
- package/dist/pick-list/pick-list.d.ts +12 -4
- package/dist/pick-list/pick-list.js +111 -23
- package/dist/popover/llms.txt +11 -11
- package/dist/popover/popover.d.ts +4 -4
- package/dist/popover/popover.js +5 -5
- package/dist/progress/llms.txt +17 -17
- package/dist/progress/progress.d.ts +7 -7
- package/dist/progress/progress.js +6 -6
- package/dist/public-api.d.ts +15 -3
- package/dist/public-api.js +13 -7
- package/dist/radio-group/llms.txt +13 -6
- package/dist/radio-group/radio-group.d.ts +11 -4
- package/dist/radio-group/radio-group.js +15 -7
- 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 +76 -12
- package/dist/rich-text/lists.d.ts +2 -2
- package/dist/rich-text/lists.js +7 -7
- package/dist/rich-text/llms.txt +26 -17
- package/dist/rich-text/rich-text.d.ts +12 -7
- package/dist/rich-text/rich-text.js +78 -54
- package/dist/rich-text/sanitize.d.ts +3 -3
- package/dist/rich-text/sanitize.js +12 -12
- package/dist/rich-text/tables.d.ts +3 -3
- package/dist/rich-text/tables.js +3 -3
- package/dist/roadmap/llms.txt +15 -15
- package/dist/roadmap/roadmap.d.ts +6 -6
- package/dist/roadmap/roadmap.js +19 -19
- 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 +1 -1
- package/dist/select/llms.txt +19 -12
- package/dist/select/select.d.ts +8 -8
- package/dist/select/select.js +47 -21
- package/dist/shared/types.d.ts +5 -5
- package/dist/shared/types.js +1 -1
- package/dist/sidenav/llms.txt +9 -9
- package/dist/sidenav/sidenav.d.ts +1 -1
- package/dist/sidenav/sidenav.js +1 -1
- 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 +32 -13
- package/dist/slider/slider-drag.d.ts +26 -0
- package/dist/slider/slider-drag.js +79 -0
- package/dist/slider/slider.d.ts +6 -5
- package/dist/slider/slider.js +27 -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 +1 -1
- package/dist/spinner/llms.txt +7 -7
- package/dist/spinner/spinner.d.ts +1 -1
- package/dist/spinner/spinner.js +1 -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 +4 -4
- package/dist/splitter/llms.txt +11 -11
- package/dist/splitter/splitter.d.ts +3 -3
- package/dist/splitter/splitter.js +5 -5
- package/dist/stepper/llms.txt +33 -14
- package/dist/stepper/stepper.d.ts +6 -6
- package/dist/stepper/stepper.js +53 -10
- package/dist/switch/llms.txt +12 -5
- package/dist/switch/switch.d.ts +10 -3
- package/dist/switch/switch.js +12 -5
- package/dist/switch-group/llms.txt +9 -9
- package/dist/switch-group/switch-group.d.ts +4 -4
- package/dist/switch-group/switch-group.js +4 -4
- package/dist/tabs/llms.txt +10 -10
- package/dist/tabs/tabs.d.ts +5 -5
- package/dist/tabs/tabs.js +8 -8
- package/dist/textarea/llms.txt +23 -12
- package/dist/textarea/textarea.d.ts +19 -6
- package/dist/textarea/textarea.js +21 -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 +47 -17
- package/dist/toast/toast-container.d.ts +9 -3
- package/dist/toast/toast-container.js +17 -9
- package/dist/toast/toast-store.d.ts +40 -4
- 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 +10 -10
- package/dist/tooltip/tooltip.d.ts +3 -3
- package/dist/tooltip/tooltip.js +18 -18
- package/dist/tree/llms.txt +25 -12
- package/dist/tree/tree-keys.d.ts +5 -5
- package/dist/tree/tree-keys.js +7 -7
- package/dist/tree/tree.d.ts +14 -7
- package/dist/tree/tree.js +53 -18
- 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 +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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
/**
|
|
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
|
|
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
|
|
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
|
|
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`
|
|
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ć
|
|
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`
|
|
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
|
|
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
|
|
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`
|
|
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
|
|
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()`
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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)
|
|
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
|
|
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
|
|
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
|
|
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
|
-
*
|
|
232
|
-
* kończyłby się błędem
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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ć
|
|
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
|
|
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ć
|
|
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
|
|
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`
|
|
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(
|
|
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: "
|
|
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({
|
package/dist/map/ports.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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**
|
|
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ą
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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)
|
|
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';
|
package/dist/megamenu/llms.txt
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# KptMegamenu (@konce-pt/react)
|
|
2
2
|
|
|
3
|
-
A mega menu
|
|
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
|
|
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>[]`
|
|
23
|
-
- `onSelect(link)`
|
|
24
|
-
- `ariaLabel`: string
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
12
|
+
/** Nazwa belki dla czytników ekranu, np. "Menu główne". */
|
|
13
13
|
ariaLabel?: string;
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
* Mega-menu
|
|
17
|
-
* Struktura: pozycja górna
|
|
18
|
-
* Pozycja górna bez kolumn działa jak akcja
|
|
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
|
|
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
|