@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
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useRef, useState, } from 'react';
|
|
3
|
-
import { KPT_CALENDAR_LEVELS, buildDayGrid, buildDecadeCells, buildMonthCells, buildYearCells, canPageBack, canPageForward, centuryStart, commitLevelFor, decadeStart,
|
|
3
|
+
import { useEffect, useEffectEvent, useRef, useState, } from 'react';
|
|
4
|
+
import { KPT_CALENDAR_LEVELS, buildDayGrid, buildDecadeCells, buildMonthCells, buildYearCells, canPageBack, canPageForward, centuryStart, commitLevelFor, datePlaceholder, dayPeriodLabels, decadeStart, displayDate, displayMonthYear, formatTime, initialFocusDate, kptFirstDayOfWeek, orderWeekdays, initialPage, moveCellIndex, moveFocusDate, pad, pageBy, parseDate, parseDateTime, parseTime, resolveStartView, selectedYearMonth, toIso, } from '@konce-pt/datetime';
|
|
4
5
|
import { monthNames, weekdayNames } from '@konce-pt/i18n';
|
|
5
6
|
import { cn } from "../internal/cn.js";
|
|
6
7
|
import { useControllableState } from "../internal/use-controllable-state.js";
|
|
@@ -14,52 +15,74 @@ import { useKptId } from "../internal/use-id.js";
|
|
|
14
15
|
import { focusCalendarActive, trapTab } from "../internal/calendar-focus.js";
|
|
15
16
|
/**
|
|
16
17
|
* Wybór daty i godziny z własnym kalendarzem. Panel jest stosem widoków
|
|
17
|
-
* dekady
|
|
18
|
+
* dekady -> lata -> miesiące -> dni: klik w komórkę schodzi poziom niżej, klik w tytuł wchodzi wyżej.
|
|
18
19
|
*
|
|
19
|
-
* Klawiatura według wzorca WAI-ARIA
|
|
20
|
+
* Klawiatura według wzorca WAI-ARIA "date picker dialog": `Enter`/`Spacja`/`ArrowDown` na polu otwierają
|
|
20
21
|
* kalendarz i przenoszą fokus na wybrany (albo dzisiejszy) dzień. W siatce dni strzałki chodzą
|
|
21
22
|
* o dzień i tydzień, `Home`/`End` na początek i koniec tygodnia, `PageUp`/`PageDown` o miesiąc
|
|
22
|
-
* (z `Shift`
|
|
23
|
+
* (z `Shift` - o rok); w siatkach miesięcy, lat i dekad strzałki chodzą po komórkach. `Tab` krąży
|
|
23
24
|
* w panelu, `Escape` zamyka go, a wybór i zamknięcie oddają fokus polu. `Delete`/`Backspace` na polu
|
|
24
25
|
* czyści wartość.
|
|
25
26
|
*
|
|
27
|
+
* Pole to `role="combobox"` z `aria-haspopup="dialog"`, więc niesie `aria-required`,
|
|
28
|
+
* `aria-readonly` i `aria-invalid`. Tydzień zaczyna się wg aktywnego języka, chyba że podano
|
|
29
|
+
* `firstDayOfWeek`; przewinięcie strony strzałką < > jest ogłaszane.
|
|
30
|
+
*
|
|
26
31
|
* @example
|
|
27
32
|
* <KptDatepicker value={date} onValueChange={setDate} startView="decade" minDate="1920-01-01" />
|
|
28
33
|
* <KptDatepicker selectionMode="datetime" hourFormat={12} value={at} onValueChange={setAt} />
|
|
29
34
|
*/
|
|
30
|
-
export function KptDatepicker({ value, defaultValue = '', onValueChange, selectionMode = 'date', startView = null, minDate = null, maxDate = null, placeholder = '', monthDisplay = 'long', displayFormat = 'pl', hourFormat = 24, minuteStep = 1, open, onOpenChange, ariaLabel = null, id, disabled = false, invalid = false, touched, onTouch, locale, dictionary, className, ...rest }) {
|
|
35
|
+
export function KptDatepicker({ value, defaultValue = '', onValueChange, selectionMode = 'date', startView = null, minDate = null, maxDate = null, placeholder = '', monthDisplay = 'long', displayFormat = 'pl', firstDayOfWeek = null, hourFormat = 24, minuteStep = 1, open, onOpenChange, ariaLabel = null, id, disabled = false, readOnly = false, required = false, invalid = false, touched, onTouch, locale, dictionary, className, ...rest }) {
|
|
31
36
|
const { t, locale: activeLocale } = useKptMessages({ locale, dictionary });
|
|
32
|
-
/** `div` z rolą nie dostaje nazwy z `label[for]`
|
|
37
|
+
/** `div` z rolą nie dostaje nazwy z `label[for]` - stąd `aria-labelledby` na etykietę wrappera. */
|
|
33
38
|
const field = useKptFieldA11y(id, 'kpt-datepicker');
|
|
34
39
|
const [current, setCurrent] = useControllableState({ value, defaultValue, onChange: onValueChange });
|
|
35
40
|
const [isOpen, setOpen] = useControllableState({ value: open, defaultValue: false, onChange: onOpenChange });
|
|
36
41
|
const [anchor, setAnchor] = useState(null);
|
|
37
42
|
const triggerRef = useRef(null);
|
|
38
|
-
|
|
43
|
+
/** "Dziś" liczone przy każdym otwarciu - panel otwarty po północy nie pokazuje wczorajszego dnia. */
|
|
44
|
+
const [today, setToday] = useState(() => new Date());
|
|
39
45
|
const todayIso = toIso(today);
|
|
46
|
+
const firstDay = firstDayOfWeek ?? kptFirstDayOfWeek(activeLocale);
|
|
47
|
+
const periods = dayPeriodLabels(activeLocale);
|
|
48
|
+
/** Ogłoszenie strony kalendarza po przewinięciu strzałką < >. */
|
|
49
|
+
const [pageAnnouncement, setPageAnnouncement] = useState('');
|
|
40
50
|
const showInvalid = invalid && (touched ?? true);
|
|
41
51
|
const [page, setPage] = useState(() => initialPage(current, selectionMode, today));
|
|
42
52
|
const [panelView, setPanelView] = useState(() => resolveStartView(selectionMode, startView));
|
|
43
53
|
const [timeStr, setTimeStr] = useState('');
|
|
44
54
|
const [pendingDate, setPendingDate] = useState('');
|
|
45
55
|
const [dtView, setDtView] = useState('calendar');
|
|
46
|
-
/** Dzień z fokusem w siatce dni
|
|
56
|
+
/** Dzień z fokusem w siatce dni - jedyny przystanek Tab siatki (roving tabindex). */
|
|
47
57
|
const [focusIso, setFocusIso] = useState('');
|
|
48
58
|
/** Komórka z fokusem w siatkach miesięcy, lat i dekad. */
|
|
49
59
|
const [focusCell, setFocusCell] = useState(0);
|
|
50
60
|
const panelId = useKptId(undefined, 'kpt-datepicker-panel');
|
|
51
61
|
const panelRef = useRef(null);
|
|
52
|
-
/**
|
|
53
|
-
|
|
62
|
+
/**
|
|
63
|
+
* Prośba o przeniesienie fokusu po najbliższym renderze (otwarcie, ruch klawiszem, zmiana
|
|
64
|
+
* poziomu) - licznik w stanie, nie ref zapisywany w renderze.
|
|
65
|
+
*/
|
|
66
|
+
const [focusRequest, setFocusRequest] = useState(0);
|
|
67
|
+
const requestFocus = () => setFocusRequest((n) => n + 1);
|
|
54
68
|
const months = monthNames(activeLocale);
|
|
55
|
-
const weekdays = weekdayNames(activeLocale);
|
|
69
|
+
const weekdays = orderWeekdays(weekdayNames(activeLocale), firstDay);
|
|
56
70
|
const commitLevel = commitLevelFor(selectionMode);
|
|
57
|
-
// Panel można otworzyć także z zewnątrz (`open`), nie tylko klikiem w trigger
|
|
58
|
-
//
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
71
|
+
// Panel można otworzyć także z zewnątrz (`open`), nie tylko klikiem w trigger - widok i bufor
|
|
72
|
+
// czasu ustawiamy więc przy każdym przejściu w stan otwarty. Wzorzec "poprzednia wartość
|
|
73
|
+
// w stanie" z react.dev: stan liczy się w tym samym renderze, bez efektu i bez klatki ze starym
|
|
74
|
+
// widokiem. Późniejsze zmiany wartości w otwartym panelu go nie resetują.
|
|
75
|
+
const [wasOpen, setWasOpen] = useState(isOpen);
|
|
76
|
+
if (wasOpen !== isOpen) {
|
|
77
|
+
setWasOpen(isOpen);
|
|
78
|
+
if (isOpen)
|
|
79
|
+
prepareOpen();
|
|
80
|
+
}
|
|
81
|
+
function prepareOpen() {
|
|
82
|
+
const now = new Date();
|
|
83
|
+
setToday(now);
|
|
84
|
+
setPageAnnouncement('');
|
|
85
|
+
setPage(initialPage(current, selectionMode, now));
|
|
63
86
|
setPanelView(resolveStartView(selectionMode, startView));
|
|
64
87
|
setDtView(selectionMode === 'time' ? 'clock' : 'calendar');
|
|
65
88
|
if (selectionMode === 'time') {
|
|
@@ -73,18 +96,15 @@ export function KptDatepicker({ value, defaultValue = '', onValueChange, selecti
|
|
|
73
96
|
}
|
|
74
97
|
const startLevel = resolveStartView(selectionMode, startView);
|
|
75
98
|
const selected = selectionMode === 'datetime' ? (parseDateTime(current)?.date ?? '') : current;
|
|
76
|
-
const focus = initialFocusDate(selected,
|
|
99
|
+
const focus = initialFocusDate(selected, toIso(now), minDate, maxDate);
|
|
77
100
|
setFocusIso(focus);
|
|
78
101
|
if (startLevel === 'day' && selectionMode !== 'time') {
|
|
79
102
|
const date = parseDate(focus);
|
|
80
103
|
setPage({ y: date.getFullYear(), m: date.getMonth() });
|
|
81
104
|
}
|
|
82
105
|
setFocusCell(-1); // -1 = domyślna komórka nowej siatki, wyliczana przy renderze
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
// zmiany wartości w otwartym panelu nie mogą go zresetować pod palcami użytkownika.
|
|
86
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
87
|
-
}, [isOpen]);
|
|
106
|
+
requestFocus();
|
|
107
|
+
}
|
|
88
108
|
const showClock = selectionMode === 'time' || (selectionMode === 'datetime' && dtView === 'clock');
|
|
89
109
|
const hasFooter = selectionMode === 'time' || selectionMode === 'datetime';
|
|
90
110
|
const hasNav = selectionMode !== 'month';
|
|
@@ -94,54 +114,48 @@ export function KptDatepicker({ value, defaultValue = '', onValueChange, selecti
|
|
|
94
114
|
setOpen(false);
|
|
95
115
|
onTouch?.();
|
|
96
116
|
};
|
|
97
|
-
/** Zamknięcie z powrotem fokusu na pole
|
|
117
|
+
/** Zamknięcie z powrotem fokusu na pole - po wyborze z klawiatury, `Escape`. */
|
|
98
118
|
const closeAndFocus = () => {
|
|
99
119
|
close();
|
|
100
120
|
triggerRef.current?.focus();
|
|
101
121
|
};
|
|
102
|
-
// Fokus po renderze. Panel w nakładce jest niewidoczny do pierwszego pomiaru
|
|
122
|
+
// Fokus po renderze. Panel w nakładce jest niewidoczny do pierwszego pomiaru - stąd rAF.
|
|
123
|
+
// `focusIso` czytamy przez zdarzenie efektu: liczy się prośba, nie każda zmiana dnia.
|
|
124
|
+
const focusActive = useEffectEvent(() => focusCalendarActive(panelRef.current, focusIso));
|
|
103
125
|
useEffect(() => {
|
|
104
|
-
if (!isOpen ||
|
|
126
|
+
if (!isOpen || focusRequest === 0)
|
|
105
127
|
return;
|
|
106
|
-
const frame = requestAnimationFrame(() =>
|
|
107
|
-
wantFocus.current = false;
|
|
108
|
-
focusCalendarActive(panelRef.current, focusIso);
|
|
109
|
-
});
|
|
128
|
+
const frame = requestAnimationFrame(() => focusActive());
|
|
110
129
|
return () => cancelAnimationFrame(frame);
|
|
111
|
-
});
|
|
112
|
-
//
|
|
130
|
+
}, [focusRequest, isOpen]);
|
|
131
|
+
// -- Prezentacja w triggerze --
|
|
113
132
|
const effectivePlaceholder = (() => {
|
|
114
133
|
if (placeholder)
|
|
115
134
|
return placeholder;
|
|
116
|
-
const
|
|
135
|
+
const tokens = { year: t('datepicker.yearToken'), month: t('datepicker.monthToken'), day: t('datepicker.dayToken') };
|
|
117
136
|
const time = hourFormat === 12 ? '--:-- --' : '--:--';
|
|
118
137
|
switch (selectionMode) {
|
|
119
138
|
case 'monthYear':
|
|
120
|
-
return
|
|
139
|
+
return datePlaceholder(displayFormat, tokens, 'monthYear', activeLocale);
|
|
121
140
|
case 'year':
|
|
122
|
-
return
|
|
141
|
+
return tokens.year;
|
|
123
142
|
case 'month':
|
|
124
|
-
return monthDisplay === 'number' ?
|
|
143
|
+
return monthDisplay === 'number' ? tokens.month : t('datepicker.month');
|
|
125
144
|
case 'time':
|
|
126
145
|
return time;
|
|
127
146
|
case 'datetime':
|
|
128
|
-
return `${
|
|
147
|
+
return `${datePlaceholder(displayFormat, tokens, 'date', activeLocale)} ${time}`;
|
|
129
148
|
default:
|
|
130
|
-
return
|
|
149
|
+
return datePlaceholder(displayFormat, tokens, 'date', activeLocale);
|
|
131
150
|
}
|
|
132
151
|
})();
|
|
133
|
-
/** Wartość niepasująca do formatu trybu daje pusty tekst
|
|
152
|
+
/** Wartość niepasująca do formatu trybu daje pusty tekst - trigger nie pokazuje śmieci. */
|
|
134
153
|
const display = (() => {
|
|
135
154
|
if (!current)
|
|
136
155
|
return '';
|
|
137
|
-
const iso = displayFormat === 'iso';
|
|
138
156
|
switch (selectionMode) {
|
|
139
|
-
case 'monthYear':
|
|
140
|
-
|
|
141
|
-
if (!match)
|
|
142
|
-
return '';
|
|
143
|
-
return iso ? current : `${match[2]}.${match[1]}`;
|
|
144
|
-
}
|
|
157
|
+
case 'monthYear':
|
|
158
|
+
return displayMonthYear(current, displayFormat, activeLocale);
|
|
145
159
|
case 'year':
|
|
146
160
|
return /^\d{4}$/.test(current) ? current : '';
|
|
147
161
|
case 'month': {
|
|
@@ -152,22 +166,22 @@ export function KptDatepicker({ value, defaultValue = '', onValueChange, selecti
|
|
|
152
166
|
}
|
|
153
167
|
case 'time': {
|
|
154
168
|
const parsed = parseTime(current);
|
|
155
|
-
return parsed ? formatTime(parsed.h, parsed.m, hourFormat) : '';
|
|
169
|
+
return parsed ? formatTime(parsed.h, parsed.m, hourFormat, periods) : '';
|
|
156
170
|
}
|
|
157
171
|
case 'datetime': {
|
|
158
172
|
const parsed = parseDateTime(current);
|
|
159
173
|
if (!parsed)
|
|
160
174
|
return '';
|
|
161
|
-
const sep = iso ? 'T' : ' ';
|
|
162
|
-
return `${
|
|
175
|
+
const sep = displayFormat === 'iso' ? 'T' : ' ';
|
|
176
|
+
return `${displayDate(parsed.date, displayFormat, activeLocale)}${sep}${formatTime(parsed.h, parsed.m, hourFormat, periods)}`;
|
|
163
177
|
}
|
|
164
178
|
default:
|
|
165
|
-
return
|
|
179
|
+
return displayDate(current, displayFormat, activeLocale);
|
|
166
180
|
}
|
|
167
181
|
})();
|
|
168
|
-
//
|
|
182
|
+
// -- Siatki --
|
|
169
183
|
const selectedDateIso = selectionMode === 'datetime' ? pendingDate : current;
|
|
170
|
-
const weeks = buildDayGrid({ page, selectedIso: selectedDateIso, todayIso, minDate, maxDate });
|
|
184
|
+
const weeks = buildDayGrid({ page, selectedIso: selectedDateIso, todayIso, minDate, maxDate, firstDay });
|
|
171
185
|
const selectedYM = selectedYearMonth(selectionMode === 'datetime' ? pendingDate : current, selectionMode);
|
|
172
186
|
const levelCells = panelView === 'year'
|
|
173
187
|
? buildYearCells({ year: page.y, selected: selectedYM, today, minDate, maxDate })
|
|
@@ -191,7 +205,7 @@ export function KptDatepicker({ value, defaultValue = '', onValueChange, selecti
|
|
|
191
205
|
return now >= 0 ? now : Math.max(0, levelCells.findIndex((c) => !c.disabled));
|
|
192
206
|
})();
|
|
193
207
|
const activeCell = focusCell >= 0 && focusCell < levelCells.length ? focusCell : defaultCell;
|
|
194
|
-
/** Pełna nazwa dnia dla czytnika (
|
|
208
|
+
/** Pełna nazwa dnia dla czytnika ("czwartek, 8 października 2026") - sama liczba nic nie mówi. */
|
|
195
209
|
const dayFormat = new Intl.DateTimeFormat(activeLocale, { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' });
|
|
196
210
|
const dayName = (iso) => {
|
|
197
211
|
const date = parseDate(iso);
|
|
@@ -199,7 +213,7 @@ export function KptDatepicker({ value, defaultValue = '', onValueChange, selecti
|
|
|
199
213
|
};
|
|
200
214
|
const isRtl = () => !!panelRef.current && getComputedStyle(panelRef.current).direction === 'rtl';
|
|
201
215
|
const onDayKeyDown = (event) => {
|
|
202
|
-
const next = moveFocusDate(focusIso, event.key, { shift: event.shiftKey, rtl: isRtl(), minDate, maxDate });
|
|
216
|
+
const next = moveFocusDate(focusIso, event.key, { shift: event.shiftKey, rtl: isRtl(), minDate, maxDate, firstDay });
|
|
203
217
|
if (next === null)
|
|
204
218
|
return;
|
|
205
219
|
event.preventDefault();
|
|
@@ -207,7 +221,7 @@ export function KptDatepicker({ value, defaultValue = '', onValueChange, selecti
|
|
|
207
221
|
const date = parseDate(next);
|
|
208
222
|
if (date.getFullYear() !== page.y || date.getMonth() !== page.m)
|
|
209
223
|
setPage({ y: date.getFullYear(), m: date.getMonth() });
|
|
210
|
-
|
|
224
|
+
requestFocus();
|
|
211
225
|
};
|
|
212
226
|
const onCellKeyDown = (event) => {
|
|
213
227
|
const next = moveCellIndex(levelCells.map((c) => c.disabled), activeCell, event.key, 3, isRtl());
|
|
@@ -215,23 +229,24 @@ export function KptDatepicker({ value, defaultValue = '', onValueChange, selecti
|
|
|
215
229
|
return;
|
|
216
230
|
event.preventDefault();
|
|
217
231
|
setFocusCell(next);
|
|
218
|
-
|
|
232
|
+
requestFocus();
|
|
219
233
|
};
|
|
220
|
-
/** Tytuł, który kliknięto, znika razem z poziomem
|
|
234
|
+
/** Tytuł, który kliknięto, znika razem z poziomem - fokus idzie do nowej siatki. */
|
|
221
235
|
const goTo = (level) => {
|
|
222
236
|
setPanelView(level);
|
|
223
237
|
setFocusCell(-1);
|
|
224
|
-
|
|
238
|
+
requestFocus();
|
|
225
239
|
};
|
|
226
|
-
/** Strzałki
|
|
240
|
+
/** Strzałki < >: fokus zostaje na strzałce, ale przystanek siatki dni idzie za stroną. */
|
|
227
241
|
const turnPage = (dir) => {
|
|
228
242
|
const next = pageBy(page, panelView, dir);
|
|
229
243
|
setPage(next);
|
|
244
|
+
setPageAnnouncement(pageTitle(next));
|
|
230
245
|
if (panelView === 'day') {
|
|
231
|
-
const moved = moveFocusDate(focusIso, dir === 1 ? 'PageDown' : 'PageUp', { minDate, maxDate });
|
|
232
|
-
// Dzień przycięty do granicy może leżeć poza nową stroną
|
|
246
|
+
const moved = moveFocusDate(focusIso, dir === 1 ? 'PageDown' : 'PageUp', { minDate, maxDate, firstDay });
|
|
247
|
+
// Dzień przycięty do granicy może leżeć poza nową stroną - wtedy pierwszy dozwolony dzień miesiąca.
|
|
233
248
|
const inPage = moved?.startsWith(`${next.y}-${pad(next.m + 1)}`);
|
|
234
|
-
const fallback = buildDayGrid({ page: next, selectedIso: selectedDateIso, todayIso, minDate, maxDate })
|
|
249
|
+
const fallback = buildDayGrid({ page: next, selectedIso: selectedDateIso, todayIso, minDate, maxDate, firstDay })
|
|
235
250
|
.flat()
|
|
236
251
|
.find((c) => c.inMonth && !c.disabled)?.iso;
|
|
237
252
|
const target = inPage ? moved : fallback;
|
|
@@ -242,6 +257,19 @@ export function KptDatepicker({ value, defaultValue = '', onValueChange, selecti
|
|
|
242
257
|
setFocusCell(-1);
|
|
243
258
|
}
|
|
244
259
|
};
|
|
260
|
+
/** Tytuł strony do ogłoszenia - miesiąc z rokiem, rok albo zakres lat. */
|
|
261
|
+
const pageTitle = (target) => {
|
|
262
|
+
switch (panelView) {
|
|
263
|
+
case 'day':
|
|
264
|
+
return `${months[target.m]} ${target.y}`;
|
|
265
|
+
case 'month':
|
|
266
|
+
return String(target.y);
|
|
267
|
+
case 'year':
|
|
268
|
+
return `${decadeStart(target.y)} - ${decadeStart(target.y) + 9}`;
|
|
269
|
+
default:
|
|
270
|
+
return `${centuryStart(target.y)} - ${centuryStart(target.y) + 119}`;
|
|
271
|
+
}
|
|
272
|
+
};
|
|
245
273
|
const navLabel = (dir) => {
|
|
246
274
|
switch (panelView) {
|
|
247
275
|
case 'month':
|
|
@@ -254,12 +282,12 @@ export function KptDatepicker({ value, defaultValue = '', onValueChange, selecti
|
|
|
254
282
|
return t(dir === 'prev' ? 'datepicker.prevMonth' : 'datepicker.nextMonth');
|
|
255
283
|
}
|
|
256
284
|
};
|
|
257
|
-
//
|
|
285
|
+
// -- Wybór --
|
|
258
286
|
const selectDay = (iso, cellDisabled) => {
|
|
259
287
|
if (cellDisabled)
|
|
260
288
|
return;
|
|
261
289
|
if (selectionMode === 'datetime') {
|
|
262
|
-
setPendingDate(iso); // czas jeszcze do wyboru
|
|
290
|
+
setPendingDate(iso); // czas jeszcze do wyboru - zamyka dopiero "Gotowe"
|
|
263
291
|
return;
|
|
264
292
|
}
|
|
265
293
|
setCurrent(iso);
|
|
@@ -286,7 +314,7 @@ export function KptDatepicker({ value, defaultValue = '', onValueChange, selecti
|
|
|
286
314
|
else {
|
|
287
315
|
setFocusCell(-1);
|
|
288
316
|
}
|
|
289
|
-
|
|
317
|
+
requestFocus();
|
|
290
318
|
};
|
|
291
319
|
const commit = () => {
|
|
292
320
|
const time = timeStr || '00:00';
|
|
@@ -301,15 +329,19 @@ export function KptDatepicker({ value, defaultValue = '', onValueChange, selecti
|
|
|
301
329
|
};
|
|
302
330
|
const clear = (event) => {
|
|
303
331
|
event.stopPropagation();
|
|
332
|
+
if (readOnly)
|
|
333
|
+
return;
|
|
304
334
|
setCurrent('');
|
|
305
335
|
setPendingDate('');
|
|
336
|
+
// Wyczyszczenie to interakcja z polem - błąd "wymagane" ma się pokazać od razu.
|
|
337
|
+
onTouch?.();
|
|
306
338
|
};
|
|
307
339
|
const timeParts = parseTime(timeStr);
|
|
308
340
|
return (_jsxs("div", { className: cn('kpt-datepicker-host', className), ...rest, children: [_jsxs("div", { ref: (el) => {
|
|
309
341
|
triggerRef.current = el;
|
|
310
342
|
setAnchor(el);
|
|
311
|
-
}, className: cn('kpt-datepicker', isOpen && 'kpt-datepicker--open', disabled && 'kpt-datepicker--disabled', showInvalid && 'kpt-datepicker--invalid'), role: "
|
|
312
|
-
if (disabled)
|
|
343
|
+
}, className: cn('kpt-datepicker', isOpen && 'kpt-datepicker--open', disabled && 'kpt-datepicker--disabled', readOnly && 'kpt-datepicker--readonly', showInvalid && 'kpt-datepicker--invalid'), role: "combobox", tabIndex: 0, "aria-haspopup": "dialog", "aria-keyshortcuts": "Delete Backspace", "aria-required": required || undefined, "aria-readonly": readOnly || undefined, "aria-invalid": showInvalid || undefined, "aria-expanded": isOpen, "aria-controls": isOpen ? panelId : undefined, id: field.id, "aria-labelledby": ariaLabel ? undefined : field.labelledBy, "aria-describedby": field.describedBy, "aria-disabled": disabled || undefined, "aria-label": ariaLabel ?? undefined, onClick: () => !disabled && !readOnly && setOpen(!isOpen), onKeyDown: (event) => {
|
|
344
|
+
if (disabled || readOnly)
|
|
313
345
|
return;
|
|
314
346
|
if (event.key === 'Enter' || event.key === ' ' || event.key === 'ArrowDown') {
|
|
315
347
|
event.preventDefault();
|
|
@@ -321,8 +353,8 @@ export function KptDatepicker({ value, defaultValue = '', onValueChange, selecti
|
|
|
321
353
|
clear(event);
|
|
322
354
|
}
|
|
323
355
|
},
|
|
324
|
-
// Przy otwartym panelu fokus idzie do kalendarza
|
|
325
|
-
onBlur: () => !isOpen && onTouch?.(), children: [display ? (_jsx("span", { className: "kpt-datepicker__value", children: display })) : (_jsx("span", { className: "kpt-datepicker__placeholder", children: effectivePlaceholder })), _jsx("span", { className: "kpt-datepicker__spacer" }), display ? (_jsx("button", { type: "button", className: "kpt-datepicker__clear", tabIndex: -1, onClick: clear, "aria-label": t('common.clear'), children: _jsx(KptIcon, { name: "x" }) })) : null, _jsx(KptIcon, { className: "kpt-datepicker__icon", name: selectionMode === 'time' ? 'clock' : 'calendar' })] }), _jsx(KptOverlay, { open: isOpen, anchor: anchor, onClose: close, offset: 4, children: _jsxs("div", { ref: panelRef, id: panelId, role: "dialog", "aria-label": t('datepicker.dialog'), className: cn('kpt-calendar', showClock && 'kpt-calendar--clock'), onKeyDown: (event) => {
|
|
356
|
+
// Przy otwartym panelu fokus idzie do kalendarza - "dotknięcie" wyśle dopiero zamknięcie.
|
|
357
|
+
onBlur: () => !isOpen && onTouch?.(), children: [display ? (_jsx("span", { className: "kpt-datepicker__value", children: display })) : (_jsx("span", { className: "kpt-datepicker__placeholder", children: effectivePlaceholder })), _jsx("span", { className: "kpt-datepicker__spacer" }), display && !readOnly ? (_jsx("button", { type: "button", className: "kpt-datepicker__clear", tabIndex: -1, onClick: clear, "aria-label": t('common.clear'), children: _jsx(KptIcon, { name: "x" }) })) : null, _jsx(KptIcon, { className: "kpt-datepicker__icon", name: selectionMode === 'time' ? 'clock' : 'calendar' })] }), _jsx(KptOverlay, { open: isOpen, anchor: anchor, onClose: close, offset: 4, children: _jsxs("div", { ref: panelRef, id: panelId, role: "dialog", "aria-label": t('datepicker.dialog'), className: cn('kpt-calendar', showClock && 'kpt-calendar--clock'), onKeyDown: (event) => {
|
|
326
358
|
if (event.key === 'Escape') {
|
|
327
359
|
event.preventDefault();
|
|
328
360
|
event.stopPropagation();
|
|
@@ -331,5 +363,5 @@ export function KptDatepicker({ value, defaultValue = '', onValueChange, selecti
|
|
|
331
363
|
else if (event.key === 'Tab') {
|
|
332
364
|
trapTab(event.currentTarget, event.nativeEvent);
|
|
333
365
|
}
|
|
334
|
-
}, children: [showClock ? (_jsxs(_Fragment, { children: [selectionMode === 'datetime' ? (_jsxs("div", { className: "kpt-calendar__header", children: [_jsx("button", { type: "button", className: "kpt-calendar__nav", onClick: () => setDtView('calendar'), "aria-label": t('datepicker.calendar'), children: _jsx(KptIcon, { name: "chevron-left" }) }), _jsx("span", { className: "kpt-calendar__title", children: t('datepicker.time') })] })) : null, _jsx(KptClock, { value: timeStr, onValueChange: setTimeStr, hourFormat: hourFormat, minuteStep: minuteStep })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "kpt-calendar__header", children: [hasNav ? (_jsx("button", { type: "button", className: "kpt-calendar__nav", disabled: !canPageBack(page, panelView, minDate), onClick: () => turnPage(-1), "aria-label": navLabel('prev'), children: _jsx(KptIcon, { name: "chevron-left" }) })) : null, _jsxs("span", { className: "kpt-calendar__titles", children: [panelView === 'day' ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "kpt-calendar__title-btn", onClick: () => goTo('month'), "aria-label": t('datepicker.chooseMonth')
|
|
366
|
+
}, children: [showClock ? (_jsxs(_Fragment, { children: [selectionMode === 'datetime' ? (_jsxs("div", { className: "kpt-calendar__header", children: [_jsx("button", { type: "button", className: "kpt-calendar__nav", onClick: () => setDtView('calendar'), "aria-label": t('datepicker.calendar'), children: _jsx(KptIcon, { name: "chevron-left" }) }), _jsx("span", { className: "kpt-calendar__title", children: t('datepicker.time') })] })) : null, _jsx(KptClock, { value: timeStr, onValueChange: setTimeStr, hourFormat: hourFormat, minuteStep: minuteStep })] })) : (_jsxs(_Fragment, { children: [_jsx("span", { className: "kpt-calendar__live", "aria-live": "polite", children: pageAnnouncement }), _jsxs("div", { className: "kpt-calendar__header", children: [hasNav ? (_jsx("button", { type: "button", className: "kpt-calendar__nav", disabled: !canPageBack(page, panelView, minDate), onClick: () => turnPage(-1), "aria-label": navLabel('prev'), children: _jsx(KptIcon, { name: "chevron-left" }) })) : null, _jsxs("span", { className: "kpt-calendar__titles", children: [panelView === 'day' ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "kpt-calendar__title-btn", onClick: () => goTo('month'), "aria-label": `${months[page.m]}, ${t('datepicker.chooseMonth')}`, children: months[page.m] }), _jsx("button", { type: "button", className: "kpt-calendar__title-btn", onClick: () => goTo('year'), "aria-label": `${page.y}, ${t('datepicker.chooseYear')}`, children: page.y })] })) : null, panelView === 'month' ? (selectionMode === 'month' ? (_jsx("span", { className: "kpt-calendar__title", children: t('datepicker.month') })) : (_jsx("button", { type: "button", className: "kpt-calendar__title-btn", onClick: () => goTo('year'), "aria-label": `${page.y}, ${t('datepicker.chooseYear')}`, children: page.y }))) : null, panelView === 'year' ? (_jsx("button", { type: "button", className: "kpt-calendar__title-btn", onClick: () => goTo('decade'), "aria-label": `${decadeStart(page.y)} - ${decadeStart(page.y) + 9}, ${t('datepicker.chooseDecade')}`, children: `${decadeStart(page.y)} - ${decadeStart(page.y) + 9}` })) : null, panelView === 'decade' ? (_jsx("span", { className: "kpt-calendar__title", children: `${centuryStart(page.y)} - ${centuryStart(page.y) + 119}` })) : null] }), hasNav ? (_jsx("button", { type: "button", className: "kpt-calendar__nav", disabled: !canPageForward(page, panelView, maxDate), onClick: () => turnPage(1), "aria-label": navLabel('next'), children: _jsx(KptIcon, { name: "chevron-right" }) })) : null] }), panelView === 'day' ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "kpt-calendar__weekdays", children: weekdays.map((weekday) => (_jsx("span", { className: "kpt-calendar__weekday", children: weekday }, weekday))) }), _jsx("div", { className: "kpt-calendar__grid", onKeyDown: onDayKeyDown, children: weeks.flat().map((cell) => (_jsx("button", { type: "button", className: cn('kpt-calendar__day', !cell.inMonth && 'kpt-calendar__day--muted', cell.today && 'kpt-calendar__day--today', cell.selected && 'kpt-calendar__day--selected'), "data-iso": cell.iso, tabIndex: cell.iso === focusIso ? 0 : -1, "aria-label": dayName(cell.iso), "aria-current": cell.today ? 'date' : undefined, disabled: cell.disabled, "aria-pressed": cell.selected, onClick: () => selectDay(cell.iso, cell.disabled), children: cell.day }, cell.iso))) })] })) : (_jsx("div", { className: cn('kpt-calendar__grid kpt-calendar__grid--cells', panelView === 'decade' && 'kpt-calendar__grid--decades'), onKeyDown: onCellKeyDown, children: levelCells.map((cell, index) => (_jsx("button", { type: "button", className: cn('kpt-calendar__cell', cell.selected && 'kpt-calendar__cell--selected', cell.current && 'kpt-calendar__cell--current'), tabIndex: index === activeCell ? 0 : -1, disabled: cell.disabled, "aria-pressed": cell.selected, onClick: () => selectCell(cell), children: cell.label }, cell.label))) })), selectionMode === 'datetime' ? (_jsxs("button", { type: "button", className: "kpt-calendar__timebar", onClick: () => setDtView('clock'), children: [_jsx(KptIcon, { name: "clock" }), _jsx("span", { children: formatTime(timeParts?.h ?? 0, timeParts?.m ?? 0, hourFormat, periods) })] })) : null] })), hasFooter ? (_jsx("div", { className: "kpt-calendar__footer", children: _jsx(KptButton, { size: "sm", onClick: commit, children: t('common.done') }) })) : null] }) })] }));
|
|
335
367
|
}
|
package/dist/datepicker/llms.txt
CHANGED
|
@@ -5,36 +5,36 @@ Import: `import { KptDatepicker } from '@konce-pt/react';`
|
|
|
5
5
|
|
|
6
6
|
## DOM
|
|
7
7
|
<div class="kpt-datepicker-host">
|
|
8
|
-
<div class="kpt-datepicker" role="
|
|
8
|
+
<div class="kpt-datepicker" role="combobox" tabindex="0" aria-haspopup="dialog">
|
|
9
9
|
<span class="kpt-datepicker__value">06.09.2026</span>
|
|
10
10
|
<span class="kpt-datepicker__spacer"></span>
|
|
11
|
-
<button class="kpt-datepicker__clear"
|
|
12
|
-
<span class="kpt-icon-host kpt-datepicker__icon"
|
|
11
|
+
<button class="kpt-datepicker__clear">...</button>
|
|
12
|
+
<span class="kpt-icon-host kpt-datepicker__icon">...</span>
|
|
13
13
|
</div>
|
|
14
14
|
</div>
|
|
15
|
-
<!-- in a portal: <div class="kpt-calendar"
|
|
15
|
+
<!-- in a portal: <div class="kpt-calendar">...</div> -->
|
|
16
16
|
|
|
17
17
|
## Props
|
|
18
|
-
- `value` / `defaultValue` / `onValueChange`
|
|
18
|
+
- `value` / `defaultValue` / `onValueChange` - the value as a string; its format follows the mode:
|
|
19
19
|
'YYYY-MM-DD' / 'YYYY-MM' / 'YYYY' / 'MM' / 'YYYY-MM-DDTHH:mm' / 'HH:mm'
|
|
20
20
|
- `selectionMode`: `'date'` (default) | `'monthYear'` | `'year'` | `'month'` | `'datetime'` | `'time'`
|
|
21
|
-
- `startView`: `'day' | 'month' | 'year' | 'decade' | null`
|
|
21
|
+
- `startView`: `'day' | 'month' | 'year' | 'decade' | null` - the level the panel opens at; `null`
|
|
22
22
|
means the level where the mode commits. It is never lowered below that level, so
|
|
23
23
|
`startView="day"` in 'year' mode is raised to 'year'.
|
|
24
24
|
- `minDate`, `maxDate`: 'YYYY-MM-DD' strings
|
|
25
|
-
- `monthDisplay`: `'long'` (default) | `'number'`; `displayFormat`: `'pl'` (default) | `'iso'`
|
|
26
|
-
- `hourFormat`: 12 | 24 (default 24)
|
|
27
|
-
- `minuteStep`: number (default 1)
|
|
28
|
-
- `open` / `onOpenChange`
|
|
25
|
+
- `monthDisplay`: `'long'` (default) | `'number'`; `displayFormat`: `'pl'` (default) | `'iso'` | `'locale'`
|
|
26
|
+
- `hourFormat`: 12 | 24 (default 24) - the dial; the stored value is always 24h
|
|
27
|
+
- `minuteStep`: number (default 1) - minute snapping on the dial
|
|
28
|
+
- `open` / `onOpenChange` - the panel state, so it can be opened from outside
|
|
29
29
|
- `placeholder`, `ariaLabel`, `disabled`, `invalid`, `touched`
|
|
30
|
-
- `onTouch()`
|
|
30
|
+
- `onTouch()` - fires when the panel closes or focus leaves the closed trigger
|
|
31
31
|
- `className`, `ref` and every other `<div>` prop go to the host
|
|
32
32
|
|
|
33
33
|
## Keyboard
|
|
34
34
|
The date picker dialog pattern. The trigger has `aria-haspopup="dialog"` and `aria-expanded`;
|
|
35
|
-
`Enter`, `Space` and
|
|
35
|
+
`Enter`, `Space` and `ArrowDown` open the panel - a `role="dialog"` named "Choose a date" - and move focus to
|
|
36
36
|
the selected day, or today, clamped to `minDate`/`maxDate`.
|
|
37
|
-
- Day grid:
|
|
37
|
+
- Day grid: `ArrowLeft`/`ArrowRight` one day, `ArrowUp`/`ArrowDown` one week, `Home`/`End` Monday and Sunday of the week,
|
|
38
38
|
`PageUp`/`PageDown` one month, with `Shift` one year (the day is clamped to the month length).
|
|
39
39
|
Crossing a month edge turns the page. Each day is named with the full date from `Intl`
|
|
40
40
|
("Thursday, October 8, 2026"), today has `aria-current="date"`, and only the focused day is
|
|
@@ -42,22 +42,22 @@ the selected day, or today, clamped to `minDate`/`maxDate`.
|
|
|
42
42
|
- Month, year and decade grids: the arrows move between cells (three columns), `Home`/`End` to the ends.
|
|
43
43
|
Clicking a title moves focus to the new grid.
|
|
44
44
|
- `Tab` cycles inside the panel; `Escape` closes it. Picking a value (or "Done") closes the panel
|
|
45
|
-
and returns focus to the trigger. `Delete`/`Backspace` on the trigger clears the value; the "
|
|
45
|
+
and returns focus to the trigger. `Delete`/`Backspace` on the trigger clears the value; the "x" button
|
|
46
46
|
sits outside the Tab order.
|
|
47
47
|
|
|
48
48
|
## The view stack
|
|
49
|
-
The header is always
|
|
49
|
+
The header is always `< title >`: the arrows page the current level, the title goes one level up.
|
|
50
50
|
|
|
51
|
-
day
|
|
52
|
-
month
|
|
53
|
-
year
|
|
54
|
-
decade
|
|
51
|
+
day < [June] [1979] > arrows +/-1 month; the chips -> months / years
|
|
52
|
+
month < [1979] > arrows +/-1 year; the chip -> years
|
|
53
|
+
year < [1970 - 1979] > arrows +/-10 years; the chip -> decades
|
|
54
|
+
decade < 1920 - 2039 > arrows +/-120 years; the top of the stack
|
|
55
55
|
|
|
56
56
|
Clicking a cell above the committing level drills down; on that level it sets the value and closes
|
|
57
57
|
the panel. An arrow dims when the whole neighbouring page falls outside `minDate`/`maxDate`.
|
|
58
58
|
|
|
59
59
|
## The logic lives in a package, the component only renders
|
|
60
|
-
Every grid, bound and format comes from `@konce-pt/datetime`
|
|
60
|
+
Every grid, bound and format comes from `@konce-pt/datetime` - pure functions with their own tests.
|
|
61
61
|
The component holds nothing but React state: the page, the level, the time buffer.
|
|
62
62
|
|
|
63
63
|
## The panel is set up on open, not on click
|
|
@@ -66,7 +66,7 @@ outside through the `open` prop. The effect deliberately depends on `open` alone
|
|
|
66
66
|
while the panel is open must not reset the view under the user's fingers.
|
|
67
67
|
|
|
68
68
|
## Requires
|
|
69
|
-
`@konce-pt/styles/components` for the calendar styles. No CDK
|
|
69
|
+
`@konce-pt/styles/components` for the calendar styles. No CDK - the panel rides the internal
|
|
70
70
|
overlay primitive.
|
|
71
71
|
|
|
72
72
|
## Examples
|
|
@@ -81,6 +81,20 @@ Weekday and month names come from `Intl` for the active locale, not from the dic
|
|
|
81
81
|
navigation labels and "Done" come from the `datepicker` and `common` namespaces; `locale` and
|
|
82
82
|
`dictionary` override them per instance.
|
|
83
83
|
|
|
84
|
+
## Week start, display format and field state
|
|
85
|
+
- The week starts by the active language (`Intl.Locale#getWeekInfo`, with a fallback list of regions):
|
|
86
|
+
en / en-US on Sunday, pl, de, en-GB on Monday. `firstDayOfWeek` (1 = Monday ... 7 = Sunday) overrides it;
|
|
87
|
+
the headers, the grid and `Home`/`End` follow it.
|
|
88
|
+
- `displayFormat`: `'pl'` (DD.MM.YYYY, default), `'iso'` (YYYY-MM-DD) or `'locale'` - order and separators
|
|
89
|
+
from `Intl` (en-US: MM/DD/YYYY). The placeholder follows the format and its letters follow the language
|
|
90
|
+
(EN `YYYY`, PL `RRRR`, the `datepicker.yearToken`/`monthToken`/`dayToken` keys). AM/PM come from `Intl`.
|
|
91
|
+
- The field is `role="combobox"` with `aria-haspopup="dialog"` (the APG select-only combobox), so it carries
|
|
92
|
+
`aria-required` (`required`), `aria-readonly` (`readOnly` - the value shows, the panel does not open,
|
|
93
|
+
there is no clear button) and `aria-invalid`.
|
|
94
|
+
- Turning the page with < > is announced (`aria-live="polite"`); the title buttons are named
|
|
95
|
+
"October, Choose month" - the visible text first (WCAG 2.5.3). Clearing the value counts as a touch.
|
|
96
|
+
- "Today" is computed on every open, so a panel opened after midnight marks the right day.
|
|
97
|
+
|
|
84
98
|
## Label and description
|
|
85
99
|
`id` goes to the focusable element, not the host; without one it comes from `KptFormField` or is
|
|
86
100
|
generated. A `div` with a role is not named by `label[for]`, so inside `KptFormField` it gets
|
|
@@ -92,7 +106,7 @@ is added to `aria-describedby`. New: `id`; the trigger is the element that carri
|
|
|
92
106
|
`--kpt-color-surface-raised`, the selection `--kpt-color-primary`.
|
|
93
107
|
|
|
94
108
|
## Accessibility
|
|
95
|
-
The trigger is `role="
|
|
109
|
+
The trigger is `role="combobox"` with `aria-haspopup="dialog"`, `aria-expanded` and `aria-controls`;
|
|
96
110
|
the panel is a named `role="dialog"`; every cell is a real `<button>` with `aria-pressed`, days carry
|
|
97
111
|
the full date and `aria-current="date"`; `ariaLabel` names the field when no `<label for>` describes
|
|
98
112
|
it. The keyboard is described above.
|
package/dist/dialog/dialog.d.ts
CHANGED
|
@@ -7,22 +7,22 @@ export interface KptDialogProps extends Omit<ComponentPropsWithRef<'dialog'>, 'o
|
|
|
7
7
|
onOpenChange: (open: boolean) => void;
|
|
8
8
|
header?: string;
|
|
9
9
|
/**
|
|
10
|
-
* Szerokość okna: `sm` 24rem, `md` 32rem (domyślna), `lg` 48rem
|
|
10
|
+
* Szerokość okna: `sm` 24rem, `md` 32rem (domyślna), `lg` 48rem - zawsze przycięta do szerokości
|
|
11
11
|
* okna przeglądarki. `lg` jest dla treści, której nie da się sensownie zwęzić: kodu, tabeli,
|
|
12
12
|
* porównania dwóch kolumn.
|
|
13
13
|
*/
|
|
14
14
|
size?: KptDialogSize;
|
|
15
|
-
/** Pozwala zamknąć klawiszem Esc i przyciskiem
|
|
15
|
+
/** Pozwala zamknąć klawiszem Esc i przyciskiem x. */
|
|
16
16
|
dismissible?: boolean;
|
|
17
17
|
children?: ReactNode;
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
|
-
* Okno modalne na natywnym `<dialog>`
|
|
20
|
+
* Okno modalne na natywnym `<dialog>` - pułapka fokusu, Escape i backdrop pochodzą z platformy,
|
|
21
21
|
* nie z naszego kodu. Stopkę wstaw przez `<KptDialog.Footer>`.
|
|
22
22
|
*
|
|
23
23
|
* Z `header` okno bierze nazwę z nagłówka (`aria-labelledby`); bez niego podaj `aria-label`.
|
|
24
24
|
* Okno wymagające odpowiedzi dostaje `role="alertdialog"` i `aria-describedby` wprost z propsów
|
|
25
|
-
* `<dialog>`
|
|
25
|
+
* `<dialog>` - tak robi `KptConfirmContainer`.
|
|
26
26
|
*
|
|
27
27
|
* @example
|
|
28
28
|
* <KptDialog open={open} onOpenChange={setOpen} header="Usunąć?">
|
package/dist/dialog/dialog.js
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
+
import { isValidElement, useEffect, useRef, useState, } from 'react';
|
|
3
4
|
import { cn } from "../internal/cn.js";
|
|
5
|
+
import { slotChildren } from "../internal/slot-children.js";
|
|
6
|
+
import { kptLockScroll } from "../internal/scroll-lock.js";
|
|
4
7
|
import { composeRefs } from "../internal/compose-refs.js";
|
|
5
8
|
import { useKptId } from "../internal/use-id.js";
|
|
6
9
|
import { KptOverlayContainerContext } from "../internal/overlay-container.js";
|
|
7
10
|
import { useKptMessages } from "../i18n/i18n-context.js";
|
|
8
11
|
import { KptIcon } from "../icon/icon.js";
|
|
9
12
|
/**
|
|
10
|
-
* Okno modalne na natywnym `<dialog>`
|
|
13
|
+
* Okno modalne na natywnym `<dialog>` - pułapka fokusu, Escape i backdrop pochodzą z platformy,
|
|
11
14
|
* nie z naszego kodu. Stopkę wstaw przez `<KptDialog.Footer>`.
|
|
12
15
|
*
|
|
13
16
|
* Z `header` okno bierze nazwę z nagłówka (`aria-labelledby`); bez niego podaj `aria-label`.
|
|
14
17
|
* Okno wymagające odpowiedzi dostaje `role="alertdialog"` i `aria-describedby` wprost z propsów
|
|
15
|
-
* `<dialog>`
|
|
18
|
+
* `<dialog>` - tak robi `KptConfirmContainer`.
|
|
16
19
|
*
|
|
17
20
|
* @example
|
|
18
21
|
* <KptDialog open={open} onOpenChange={setOpen} header="Usunąć?">
|
|
@@ -27,23 +30,41 @@ export function KptDialog({ open, onOpenChange, header = '', size = 'md', dismis
|
|
|
27
30
|
const { t } = useKptMessages({ locale, dictionary });
|
|
28
31
|
const dialogRef = useRef(null);
|
|
29
32
|
const titleId = useKptId(undefined, 'kpt-dialog-title');
|
|
30
|
-
// Element trafia do kontekstu, więc musi wywołać render
|
|
33
|
+
// Element trafia do kontekstu, więc musi wywołać render - sam `ref` by nie wystarczył.
|
|
31
34
|
const [dialogEl, setDialogEl] = useState(null);
|
|
32
35
|
useEffect(() => {
|
|
33
36
|
const el = dialogRef.current;
|
|
34
|
-
if (!el)
|
|
37
|
+
if (!el || !open)
|
|
35
38
|
return;
|
|
36
|
-
if (
|
|
39
|
+
if (!el.open)
|
|
37
40
|
el.showModal();
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
// `showModal()` blokuje interakcję z tłem, ale nie jego przewijanie kółkiem.
|
|
42
|
+
const releaseScroll = kptLockScroll();
|
|
43
|
+
return () => {
|
|
44
|
+
releaseScroll();
|
|
45
|
+
if (el.open)
|
|
46
|
+
el.close();
|
|
47
|
+
};
|
|
40
48
|
}, [open]);
|
|
49
|
+
/**
|
|
50
|
+
* `close` przychodzi z każdej drogi. Przy `dismissible=false` zamknąć wolno tylko z kodu:
|
|
51
|
+
* Chromium z CloseWatcherem pozwala anulować `cancel` jedynie po aktywacji użytkownika, więc drugi
|
|
52
|
+
* Escape z rzędu zamyka okno mimo `preventDefault` - wtedy otwieramy je z powrotem.
|
|
53
|
+
*/
|
|
54
|
+
const onClose = () => {
|
|
55
|
+
const el = dialogRef.current;
|
|
56
|
+
if (!dismissible && open && el && !el.open) {
|
|
57
|
+
el.showModal();
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
onOpenChange(false);
|
|
61
|
+
};
|
|
41
62
|
const footers = [];
|
|
42
63
|
const body = [];
|
|
43
|
-
|
|
64
|
+
for (const child of slotChildren(children)) {
|
|
44
65
|
const isFooter = isValidElement(child) && child.type?.kptDialogSlot === 'footer';
|
|
45
66
|
(isFooter ? footers : body).push(child);
|
|
46
|
-
}
|
|
67
|
+
}
|
|
47
68
|
const onCancel = (event) => {
|
|
48
69
|
// Esc idzie przez `cancel`; blokujemy go, gdy okna nie wolno zamknąć.
|
|
49
70
|
if (!dismissible) {
|
|
@@ -52,7 +73,7 @@ export function KptDialog({ open, onOpenChange, header = '', size = 'md', dismis
|
|
|
52
73
|
}
|
|
53
74
|
onOpenChange(false);
|
|
54
75
|
};
|
|
55
|
-
return (_jsx(KptOverlayContainerContext.Provider, { value: open ? dialogEl : null, children: _jsxs("dialog", { ref: composeRefs(dialogRef, setDialogEl, ref), className: cn('kpt-dialog', className), "data-size": size, "aria-labelledby": header ? titleId : undefined,
|
|
76
|
+
return (_jsx(KptOverlayContainerContext.Provider, { value: open ? dialogEl : null, children: _jsxs("dialog", { ref: composeRefs(dialogRef, setDialogEl, ref), className: cn('kpt-dialog', className), "data-size": size, "aria-labelledby": header ? titleId : undefined, closedby: dismissible ? undefined : 'none', onClose: onClose, onCancel: onCancel, ...rest, children: [header ? (_jsxs("div", { className: "kpt-dialog__header", children: [_jsx("h2", { className: "kpt-dialog__title", id: titleId, children: header }), dismissible ? (_jsx("button", { className: "kpt-dialog__close", type: "button", onClick: () => onOpenChange(false), "aria-label": t('common.close'), children: _jsx(KptIcon, { name: "x" }) })) : null] })) : null, _jsx("div", { className: "kpt-dialog__body", children: body }), footers] }) }));
|
|
56
77
|
}
|
|
57
78
|
/**
|
|
58
79
|
* Stopka okna. Nosi atrybut `kptdialogfooter`, w który celuje wspólny SCSS (nazwy atrybutów
|