@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/alert/llms.txt
CHANGED
|
@@ -6,22 +6,22 @@ Import: `import { KptAlert } from '@konce-pt/react';`
|
|
|
6
6
|
## DOM
|
|
7
7
|
<div class="kpt-alert-host">
|
|
8
8
|
<div class="kpt-alert" data-variant="success" role="status">
|
|
9
|
-
<span class="kpt-icon-host kpt-alert__icon"
|
|
9
|
+
<span class="kpt-icon-host kpt-alert__icon">...</span>
|
|
10
10
|
<div class="kpt-alert__content">
|
|
11
11
|
<div class="kpt-alert__title">Saved</div>
|
|
12
|
-
<div class="kpt-alert__message"
|
|
12
|
+
<div class="kpt-alert__message">...children...</div>
|
|
13
13
|
</div>
|
|
14
|
-
<button class="kpt-alert__close" type="button" aria-label="Close"
|
|
14
|
+
<button class="kpt-alert__close" type="button" aria-label="Close">...</button>
|
|
15
15
|
</div>
|
|
16
16
|
</div>
|
|
17
17
|
|
|
18
18
|
## Props
|
|
19
19
|
- `variant`: 'info' | 'success' | 'warning' | 'danger' (default 'info')
|
|
20
20
|
- `title`: string
|
|
21
|
-
- `dismissible`: boolean
|
|
22
|
-
- `visible` / `defaultVisible` / `onVisibleChange`
|
|
23
|
-
- `onClosed()`
|
|
24
|
-
- `locale`, `dictionary`
|
|
21
|
+
- `dismissible`: boolean - adds the close button
|
|
22
|
+
- `visible` / `defaultVisible` / `onVisibleChange` - controlled or uncontrolled visibility
|
|
23
|
+
- `onClosed()` - fires after the user dismisses it
|
|
24
|
+
- `locale`, `dictionary` - i18n overrides for this component only
|
|
25
25
|
- `className`, `ref` and every other `<div>` prop go to the host
|
|
26
26
|
|
|
27
27
|
## Dismissal hides, it does not unmount
|
|
@@ -43,6 +43,6 @@ The semantic colour pairs of each variant (`--kpt-color-info` / `-success` / `-w
|
|
|
43
43
|
## Accessibility
|
|
44
44
|
The role follows the weight of the message: `info` and `success` are `role="status"` (read
|
|
45
45
|
politely, without interrupting), `warning` and `danger` are `role="alert"` (read at once). The icon
|
|
46
|
-
is decorative; the
|
|
47
|
-
page
|
|
48
|
-
A live region announces **changes**: an alert rendered together with the page (or revealed by toggling `hidden`) is not announced reliably. To have it read, add it after the action (`@if` / conditional render)
|
|
46
|
+
is decorative; the x button is labelled from `common.close`. After closing, focus falls back to the
|
|
47
|
+
page - move it yourself in the close handler when the alert was reached with the keyboard.
|
|
48
|
+
A live region announces **changes**: an alert rendered together with the page (or revealed by toggling `hidden`) is not announced reliably. To have it read, add it after the action (`@if` / conditional render) - the inserted element is announced.
|
|
@@ -3,13 +3,13 @@ import { type KptBreakpoint } from '../internal/use-breakpoint.ts';
|
|
|
3
3
|
import { type KptI18nOverrides } from '../i18n/i18n-context.tsx';
|
|
4
4
|
/**
|
|
5
5
|
* Zachowanie panelu bocznego:
|
|
6
|
-
* - `auto`
|
|
7
|
-
* - `side`
|
|
8
|
-
* - `over`
|
|
6
|
+
* - `auto` - zależne od szerokości okna (domyślne),
|
|
7
|
+
* - `side` - zawsze zadokowany, rozpycha treść,
|
|
8
|
+
* - `over` - zawsze nakładka nad treścią.
|
|
9
9
|
*/
|
|
10
10
|
export type KptSidenavMode = 'side' | 'over' | 'auto';
|
|
11
11
|
export interface KptAppShellProps extends Omit<ComponentPropsWithRef<'div'>, 'children'>, KptI18nOverrides {
|
|
12
|
-
/** Slot górnego paska
|
|
12
|
+
/** Slot górnego paska - renderowany nad obszarem treści (zwykle `<KptToolbar>`). */
|
|
13
13
|
toolbar?: ReactNode;
|
|
14
14
|
/** Slot panelu bocznego (zwykle `<KptSidenav>`). */
|
|
15
15
|
sidenav?: ReactNode;
|
|
@@ -41,9 +41,9 @@ export interface KptAppShellProps extends Omit<ComponentPropsWithRef<'div'>, 'ch
|
|
|
41
41
|
/** Etykieta dostępności panelu; puste = `appShell.navigation` ze słownika. */
|
|
42
42
|
sidenavLabel?: string;
|
|
43
43
|
}
|
|
44
|
-
/** Kontrakt kontekstu shella
|
|
44
|
+
/** Kontrakt kontekstu shella - czytany przez `useKptAppShell()` i przełącznik panelu. */
|
|
45
45
|
export interface KptAppShellContextValue {
|
|
46
|
-
/** Efektywny stan otwarcia
|
|
46
|
+
/** Efektywny stan otwarcia - ten, który obowiązuje w bieżącym układzie. */
|
|
47
47
|
isSidenavOpen: boolean;
|
|
48
48
|
/** Czy panel zachowuje się TERAZ jak nakładka nad treścią. */
|
|
49
49
|
isOverlay: boolean;
|
|
@@ -59,23 +59,23 @@ export interface KptAppShellContextValue {
|
|
|
59
59
|
* Domyślny tryb `auto` jest responsywny bez konfiguracji: od `sidenavBreakpoint` w górę panel
|
|
60
60
|
* jest zadokowany, poniżej zachowuje się jak nakładka ze scrimem i startuje zamknięty.
|
|
61
61
|
*
|
|
62
|
-
* O układzie decyduje wyłącznie CSS
|
|
62
|
+
* O układzie decyduje wyłącznie CSS - nic nie migocze przed hydracją i nic nie zależy od
|
|
63
63
|
* `matchMedia`. JavaScript odpowiada tylko za to, KTÓRY stan przełącza przycisk.
|
|
64
64
|
*
|
|
65
65
|
* @example
|
|
66
66
|
* <KptAppShell
|
|
67
|
-
* toolbar={<KptToolbar
|
|
68
|
-
* sidenav={<KptSidenav
|
|
67
|
+
* toolbar={<KptToolbar>...</KptToolbar>}
|
|
68
|
+
* sidenav={<KptSidenav>...</KptSidenav>}
|
|
69
69
|
* >
|
|
70
70
|
* <Routes />
|
|
71
71
|
* </KptAppShell>
|
|
72
72
|
*/
|
|
73
73
|
export declare function KptAppShell({ toolbar, sidenav, children, sidenavOpen, defaultSidenavOpen, onSidenavOpenChange, sidenavCompactOpen, defaultSidenavCompactOpen, onSidenavCompactOpenChange, sidenavMode, sidenavBreakpoint, sidenavRailBreakpoint, sidenavLabel, locale, dictionary, className, ...rest }: Readonly<KptAppShellProps>): import("react").JSX.Element;
|
|
74
|
-
/** Dostęp do stanu shella. Poza `KptAppShell` rzuca
|
|
74
|
+
/** Dostęp do stanu shella. Poza `KptAppShell` rzuca - to zawsze błąd użycia. */
|
|
75
75
|
export declare function useKptAppShell(): KptAppShellContextValue;
|
|
76
76
|
/**
|
|
77
77
|
* Propsy przycisku przełączającego panel boczny. Rozłóż je na natywnym `<button>`
|
|
78
|
-
* (albo na `<KptButton>`, który przekazuje je do swojego wewnętrznego `<button>`)
|
|
78
|
+
* (albo na `<KptButton>`, który przekazuje je do swojego wewnętrznego `<button>`) -
|
|
79
79
|
* atrybuty ARIA muszą wylądować na elemencie z rolą, nie na opakowaniu.
|
|
80
80
|
*
|
|
81
81
|
* Trafia w stan właściwy dla bieżącego układu, więc jeden przycisk obsługuje desktop
|
|
@@ -93,11 +93,11 @@ export declare function useKptShellNavToggle(options?: {
|
|
|
93
93
|
readonly onClick: () => void;
|
|
94
94
|
};
|
|
95
95
|
/**
|
|
96
|
-
* Etykieta pozycji nawigacji. W szynie ikon (układ md
|
|
97
|
-
*
|
|
96
|
+
* Etykieta pozycji nawigacji. W szynie ikon (układ md-xl) shell chowa ją techniką
|
|
97
|
+
* "visually hidden", więc pozycja zwęża się do samego znaku, a czytnik ekranu wciąż
|
|
98
98
|
* odczytuje pełny tekst.
|
|
99
99
|
*
|
|
100
|
-
* Nosi atrybut `kptnavlabel`
|
|
100
|
+
* Nosi atrybut `kptnavlabel` - to po nim celuje wspólny SCSS. Nazwy atrybutów w selektorach
|
|
101
101
|
* CSS są w HTML case-insensitive, więc jedna reguła obsługuje oba porty; zapis małymi literami
|
|
102
102
|
* omija przy okazji ostrzeżenie React o nieznanym propie.
|
|
103
103
|
*
|
|
@@ -15,13 +15,13 @@ const KptAppShellContext = createContext(null);
|
|
|
15
15
|
* Domyślny tryb `auto` jest responsywny bez konfiguracji: od `sidenavBreakpoint` w górę panel
|
|
16
16
|
* jest zadokowany, poniżej zachowuje się jak nakładka ze scrimem i startuje zamknięty.
|
|
17
17
|
*
|
|
18
|
-
* O układzie decyduje wyłącznie CSS
|
|
18
|
+
* O układzie decyduje wyłącznie CSS - nic nie migocze przed hydracją i nic nie zależy od
|
|
19
19
|
* `matchMedia`. JavaScript odpowiada tylko za to, KTÓRY stan przełącza przycisk.
|
|
20
20
|
*
|
|
21
21
|
* @example
|
|
22
22
|
* <KptAppShell
|
|
23
|
-
* toolbar={<KptToolbar
|
|
24
|
-
* sidenav={<KptSidenav
|
|
23
|
+
* toolbar={<KptToolbar>...</KptToolbar>}
|
|
24
|
+
* sidenav={<KptSidenav>...</KptSidenav>}
|
|
25
25
|
* >
|
|
26
26
|
* <Routes />
|
|
27
27
|
* </KptAppShell>
|
|
@@ -59,7 +59,7 @@ export function KptAppShell({ toolbar, sidenav, children, sidenavOpen, defaultSi
|
|
|
59
59
|
useEffect(() => {
|
|
60
60
|
if (!isOverlay || !isSidenavOpen)
|
|
61
61
|
return;
|
|
62
|
-
// Escape zamyka nakładkę nawigacji
|
|
62
|
+
// Escape zamyka nakładkę nawigacji - ale nie wtedy, gdy zamyka nim coś otwartego nad shellem
|
|
63
63
|
// (okno, menu, popover): te wołają `preventDefault()` albo trzymają fokus w sobie.
|
|
64
64
|
const onKeyDown = (event) => {
|
|
65
65
|
if (event.key !== 'Escape' || event.defaultPrevented)
|
|
@@ -80,11 +80,11 @@ export function KptAppShell({ toolbar, sidenav, children, sidenavOpen, defaultSi
|
|
|
80
80
|
openSidenav: () => setSidenavOpen(true),
|
|
81
81
|
closeSidenav,
|
|
82
82
|
}), [isSidenavOpen, isOverlay, sidenavId, setSidenavOpen, closeSidenav]);
|
|
83
|
-
// Scrim blokuje wskaźnik, ale nie klawiaturę
|
|
83
|
+
// Scrim blokuje wskaźnik, ale nie klawiaturę - treść pod nakładką nie może łapać fokusu.
|
|
84
84
|
const contentInert = isOverlay && isSidenavOpen;
|
|
85
85
|
// Otwarta nakładka robi treść `inert`, więc fokus zostawiony w niej (albo na przycisku menu)
|
|
86
86
|
// nie miałby dokąd pójść. Po otwarciu przenosimy go do panelu, po zamknięciu oddajemy tam,
|
|
87
|
-
// skąd przyszedł
|
|
87
|
+
// skąd przyszedł - chyba że użytkownik zdążył go przenieść gdzie indziej. Stan `null` przed
|
|
88
88
|
// pierwszym renderem: nakładka otwarta już przy starcie nie zabiera fokusu.
|
|
89
89
|
const navRef = useRef(null);
|
|
90
90
|
const overlayWasOpen = useRef(null);
|
|
@@ -108,7 +108,7 @@ export function KptAppShell({ toolbar, sidenav, children, sidenavOpen, defaultSi
|
|
|
108
108
|
}, [contentInert]);
|
|
109
109
|
return (_jsx(KptAppShellContext.Provider, { value: context, children: _jsxs("div", { className: cn('kpt-app-shell', dockedOpen && 'kpt-app-shell--nav-open', compactOpen && 'kpt-app-shell--nav-compact-open', className), "data-sidenav-mode": sidenavMode, "data-sidenav-breakpoint": sidenavBreakpoint, "data-sidenav-rail": sidenavRailBreakpoint ?? undefined, ...rest, children: [toolbar, _jsxs("div", { className: "kpt-app-shell__body", children: [_jsx("nav", { ref: navRef, className: "kpt-app-shell__sidenav", tabIndex: -1, id: sidenavId, "aria-label": sidenavLabel || t('appShell.navigation'), children: sidenav }), _jsx("div", { className: "kpt-app-shell__scrim", "aria-hidden": "true", onClick: closeSidenav }), _jsx("main", { className: "kpt-app-shell__content", inert: contentInert, children: children })] })] }) }));
|
|
110
110
|
}
|
|
111
|
-
/** Dostęp do stanu shella. Poza `KptAppShell` rzuca
|
|
111
|
+
/** Dostęp do stanu shella. Poza `KptAppShell` rzuca - to zawsze błąd użycia. */
|
|
112
112
|
export function useKptAppShell() {
|
|
113
113
|
const context = useContext(KptAppShellContext);
|
|
114
114
|
if (!context)
|
|
@@ -117,7 +117,7 @@ export function useKptAppShell() {
|
|
|
117
117
|
}
|
|
118
118
|
/**
|
|
119
119
|
* Propsy przycisku przełączającego panel boczny. Rozłóż je na natywnym `<button>`
|
|
120
|
-
* (albo na `<KptButton>`, który przekazuje je do swojego wewnętrznego `<button>`)
|
|
120
|
+
* (albo na `<KptButton>`, który przekazuje je do swojego wewnętrznego `<button>`) -
|
|
121
121
|
* atrybuty ARIA muszą wylądować na elemencie z rolą, nie na opakowaniu.
|
|
122
122
|
*
|
|
123
123
|
* Trafia w stan właściwy dla bieżącego układu, więc jeden przycisk obsługuje desktop
|
|
@@ -137,11 +137,11 @@ export function useKptShellNavToggle(options) {
|
|
|
137
137
|
};
|
|
138
138
|
}
|
|
139
139
|
/**
|
|
140
|
-
* Etykieta pozycji nawigacji. W szynie ikon (układ md
|
|
141
|
-
*
|
|
140
|
+
* Etykieta pozycji nawigacji. W szynie ikon (układ md-xl) shell chowa ją techniką
|
|
141
|
+
* "visually hidden", więc pozycja zwęża się do samego znaku, a czytnik ekranu wciąż
|
|
142
142
|
* odczytuje pełny tekst.
|
|
143
143
|
*
|
|
144
|
-
* Nosi atrybut `kptnavlabel`
|
|
144
|
+
* Nosi atrybut `kptnavlabel` - to po nim celuje wspólny SCSS. Nazwy atrybutów w selektorach
|
|
145
145
|
* CSS są w HTML case-insensitive, więc jedna reguła obsługuje oba porty; zapis małymi literami
|
|
146
146
|
* omija przy okazji ostrzeżenie React o nieznanym propie.
|
|
147
147
|
*
|
package/dist/app-shell/llms.txt
CHANGED
|
@@ -6,27 +6,27 @@ Import: `import { KptAppShell, useKptShellNavToggle } from '@konce-pt/react';`
|
|
|
6
6
|
## DOM
|
|
7
7
|
<div class="kpt-app-shell kpt-app-shell--nav-open"
|
|
8
8
|
data-sidenav-mode="auto" data-sidenav-breakpoint="lg">
|
|
9
|
-
|
|
9
|
+
...toolbar...
|
|
10
10
|
<div class="kpt-app-shell__body">
|
|
11
|
-
<nav class="kpt-app-shell__sidenav" tabindex="-1" id="
|
|
11
|
+
<nav class="kpt-app-shell__sidenav" tabindex="-1" id="...">...sidenav...</nav>
|
|
12
12
|
<div class="kpt-app-shell__scrim" aria-hidden="true"></div>
|
|
13
|
-
<main class="kpt-app-shell__content"
|
|
13
|
+
<main class="kpt-app-shell__content">...children...</main>
|
|
14
14
|
</div>
|
|
15
15
|
</div>
|
|
16
16
|
|
|
17
17
|
## Props
|
|
18
|
-
- `toolbar`: ReactNode
|
|
19
|
-
- `sidenav`: ReactNode
|
|
20
|
-
- `children`: ReactNode
|
|
21
|
-
- `sidenavOpen` / `defaultSidenavOpen` / `onSidenavOpenChange`
|
|
18
|
+
- `toolbar`: ReactNode - the slot above the content area (usually `<KptToolbar>`)
|
|
19
|
+
- `sidenav`: ReactNode - the side panel slot (usually `<KptSidenav>`)
|
|
20
|
+
- `children`: ReactNode - the application content
|
|
21
|
+
- `sidenavOpen` / `defaultSidenavOpen` / `onSidenavOpenChange` - the docked layout's open state
|
|
22
22
|
(default open)
|
|
23
|
-
- `sidenavCompactOpen` / `defaultSidenavCompactOpen` / `onSidenavCompactOpenChange`
|
|
23
|
+
- `sidenavCompactOpen` / `defaultSidenavCompactOpen` / `onSidenavCompactOpenChange` - the overlay's
|
|
24
24
|
open state (default closed)
|
|
25
25
|
- `sidenavMode`: 'auto' | 'side' | 'over' (default 'auto')
|
|
26
26
|
- `sidenavBreakpoint`: 'sm' | 'md' | 'lg' | 'xl' | '2xl' (default 'lg')
|
|
27
27
|
- `sidenavRailBreakpoint`: the same union or null (default null)
|
|
28
|
-
- `sidenavLabel`: string
|
|
29
|
-
- `locale`, `dictionary`
|
|
28
|
+
- `sidenavLabel`: string - empty falls back to `appShell.navigation` from the dictionary
|
|
29
|
+
- `locale`, `dictionary` - i18n overrides for this component only
|
|
30
30
|
|
|
31
31
|
## Two open states, on purpose
|
|
32
32
|
The docked layout and the overlay keep separate state. If they shared one, narrowing the window
|
|
@@ -38,7 +38,7 @@ would have to overwrite the consumer's state, and widening it back would have no
|
|
|
38
38
|
<KptButton variant="text" {...toggle}>Menu</KptButton>
|
|
39
39
|
|
|
40
40
|
It returns `aria-expanded`, `aria-controls`, `aria-label` and `onClick`. Spread them on a native
|
|
41
|
-
`<button>` or on `<KptButton>` (which forwards them to its inner `<button>`)
|
|
41
|
+
`<button>` or on `<KptButton>` (which forwards them to its inner `<button>`) - ARIA attributes must
|
|
42
42
|
land on the element that carries the role, never on a wrapper.
|
|
43
43
|
|
|
44
44
|
`useKptAppShell()` exposes the same state directly: `{ isSidenavOpen, isOverlay, sidenavId,
|
|
@@ -56,8 +56,8 @@ decides WHICH state the button flips. The scrim is always in the DOM; CSS contro
|
|
|
56
56
|
## Accessibility
|
|
57
57
|
- The panel is a `<nav>` with a label and an `id` for `aria-controls`.
|
|
58
58
|
- A closed docked panel leaves the tab order through `visibility`, correct on the first frame.
|
|
59
|
-
- While the overlay is open the content gets `inert`, and Escape closes the panel
|
|
59
|
+
- While the overlay is open the content gets `inert`, and Escape closes the panel - unless something
|
|
60
60
|
opened above the shell (a dialog, menu or popover) already handled it.
|
|
61
61
|
- Opening the overlay moves focus into the panel (its first focusable element, or the `<nav>`
|
|
62
|
-
itself); closing it returns focus to where it came from
|
|
62
|
+
itself); closing it returns focus to where it came from - usually the menu button - unless the user
|
|
63
63
|
has already moved it elsewhere. An overlay that is open when the page loads does not take focus.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
/** Tryb ekranu
|
|
1
|
+
/** Tryb ekranu - logowanie, rejestracja, odzyskiwanie hasła. */
|
|
2
2
|
export type KptAuthMode = 'signIn' | 'signUp' | 'forgot';
|
|
3
3
|
/**
|
|
4
4
|
* Układ ekranu:
|
|
5
|
-
* - `slider`
|
|
6
|
-
* - `split`
|
|
5
|
+
* - `slider` - panel promo przesuwa się nad formularzami przy zmianie trybu,
|
|
6
|
+
* - `split` - panel promo stoi w miejscu, zmienia się tylko formularz.
|
|
7
7
|
*/
|
|
8
8
|
export type KptAuthLayout = 'slider' | 'split';
|
|
9
9
|
/** Układ przycisków dostawców: pełnowymiarowa lista albo siatka ikon z podpisami. */
|
|
@@ -12,13 +12,13 @@ export type KptAuthProviderLayout = 'list' | 'grid';
|
|
|
12
12
|
export interface KptAuthProvider {
|
|
13
13
|
/** Identyfikator zwracany w `onProviderSelect`. */
|
|
14
14
|
id: string;
|
|
15
|
-
/** Widoczna etykieta
|
|
15
|
+
/** Widoczna etykieta - jednocześnie nazwa dostępna przycisku. */
|
|
16
16
|
label: string;
|
|
17
17
|
/** Nazwa ikony z rejestru `KptIcon` (np. `brand-google` z pełnego zestawu Tabler). */
|
|
18
18
|
icon?: string;
|
|
19
19
|
/** Alternatywa dla `icon`: adres obrazka (wierne, wielokolorowe logo marki). */
|
|
20
20
|
iconUrl?: string;
|
|
21
|
-
/** Drugi wiersz opisu
|
|
21
|
+
/** Drugi wiersz opisu - tylko w układzie `list`. */
|
|
22
22
|
description?: string;
|
|
23
23
|
}
|
|
24
24
|
/** Wartość formularza logowania. */
|
|
@@ -38,7 +38,7 @@ export interface KptAuthSignUpValue {
|
|
|
38
38
|
export interface KptAuthResetValue {
|
|
39
39
|
email: string;
|
|
40
40
|
}
|
|
41
|
-
/** Rodzaj błędu pola
|
|
41
|
+
/** Rodzaj błędu pola - komunikat składamy z niego dopiero przy renderowaniu. */
|
|
42
42
|
export type KptAuthErrorKind = 'required' | 'email' | 'minLength' | 'mismatch';
|
|
43
43
|
/** Minimalna długość hasła w rejestracji. */
|
|
44
44
|
export declare const KPT_AUTH_MIN_PASSWORD = 8;
|
package/dist/auth/auth.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export interface KptAuthProps extends Omit<ComponentPropsWithRef<'div'>, 'onSubm
|
|
|
15
15
|
showName?: boolean;
|
|
16
16
|
requireTerms?: boolean;
|
|
17
17
|
showRemember?: boolean;
|
|
18
|
-
/** Operacja w toku
|
|
18
|
+
/** Operacja w toku - przyciski w stanie ładowania, dostawcy zablokowani. */
|
|
19
19
|
busy?: boolean;
|
|
20
20
|
error?: string | null;
|
|
21
21
|
notice?: string | null;
|
|
@@ -36,7 +36,7 @@ export interface KptAuthProps extends Omit<ComponentPropsWithRef<'div'>, 'onSubm
|
|
|
36
36
|
* Ekran uwierzytelniania: logowanie, rejestracja i odzyskiwanie hasła w jednym komponencie,
|
|
37
37
|
* z panelem promocyjnym i listą dostawców zewnętrznych.
|
|
38
38
|
*
|
|
39
|
-
* Komponent jest prezentacyjny
|
|
39
|
+
* Komponent jest prezentacyjny - nie woła API ani nie nawiguje. Wywołania backendu podpina
|
|
40
40
|
* aplikacja pod `onSignIn` / `onSignUp` / `onResetPassword` / `onProviderSelect`, a stan
|
|
41
41
|
* operacji podaje z powrotem przez `busy`, `error` i `notice`.
|
|
42
42
|
*
|
package/dist/auth/auth.js
CHANGED
|
@@ -29,7 +29,7 @@ const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
|
29
29
|
* Ekran uwierzytelniania: logowanie, rejestracja i odzyskiwanie hasła w jednym komponencie,
|
|
30
30
|
* z panelem promocyjnym i listą dostawców zewnętrznych.
|
|
31
31
|
*
|
|
32
|
-
* Komponent jest prezentacyjny
|
|
32
|
+
* Komponent jest prezentacyjny - nie woła API ani nie nawiguje. Wywołania backendu podpina
|
|
33
33
|
* aplikacja pod `onSignIn` / `onSignUp` / `onResetPassword` / `onProviderSelect`, a stan
|
|
34
34
|
* operacji podaje z powrotem przez `busy`, `error` i `notice`.
|
|
35
35
|
*
|
|
@@ -59,7 +59,7 @@ export function KptAuth({ mode, defaultMode = 'signIn', onModeChange, layout = '
|
|
|
59
59
|
resetEmail: `${uid}-reset-email`,
|
|
60
60
|
};
|
|
61
61
|
const headingRef = useRef(null);
|
|
62
|
-
//
|
|
62
|
+
// -- Sloty --
|
|
63
63
|
const slots = {};
|
|
64
64
|
for (const child of slotChildren(children)) {
|
|
65
65
|
if (!isValidElement(child))
|
|
@@ -68,7 +68,7 @@ export function KptAuth({ mode, defaultMode = 'signIn', onModeChange, layout = '
|
|
|
68
68
|
if (name)
|
|
69
69
|
slots[name] = child.props.children;
|
|
70
70
|
}
|
|
71
|
-
//
|
|
71
|
+
// -- Modele formularzy --
|
|
72
72
|
const [signInModel, setSignInModel] = useState({
|
|
73
73
|
email: '',
|
|
74
74
|
password: '',
|
|
@@ -85,9 +85,9 @@ export function KptAuth({ mode, defaultMode = 'signIn', onModeChange, layout = '
|
|
|
85
85
|
const [touched, setTouched] = useState(new Set());
|
|
86
86
|
const touch = (field) => setTouched((prev) => new Set(prev).add(field));
|
|
87
87
|
/*
|
|
88
|
-
* Walidacja jest bezwarunkowa i zwraca sam `kind`
|
|
88
|
+
* Walidacja jest bezwarunkowa i zwraca sam `kind` - komunikat składamy dopiero przy
|
|
89
89
|
* renderowaniu, dzięki czemu zmiana języka w runtime przerysowuje błędy. Bramka
|
|
90
|
-
*
|
|
90
|
+
* "nie strasz czerwienią świeżego pola" (`touched`) żyje w prezentacji, nie w walidatorze,
|
|
91
91
|
* więc `invalid` mówi prawdę także wtedy, gdy pola nikt jeszcze nie dotknął.
|
|
92
92
|
*/
|
|
93
93
|
const signInErrors = {
|
|
@@ -102,7 +102,7 @@ export function KptAuth({ mode, defaultMode = 'signIn', onModeChange, layout = '
|
|
|
102
102
|
: signUpModel.password.length < KPT_AUTH_MIN_PASSWORD
|
|
103
103
|
? 'minLength'
|
|
104
104
|
: null,
|
|
105
|
-
// Puste
|
|
105
|
+
// Puste "powtórz hasło" nie jest jeszcze niezgodnością - dopiero wpisana, inna wartość.
|
|
106
106
|
confirm: signUpModel.confirm && signUpModel.confirm !== signUpModel.password ? 'mismatch' : null,
|
|
107
107
|
terms: requireTerms && !signUpModel.terms ? 'required' : null,
|
|
108
108
|
};
|
|
@@ -126,7 +126,7 @@ export function KptAuth({ mode, defaultMode = 'signIn', onModeChange, layout = '
|
|
|
126
126
|
const errorFor = (form, field, kinds) => touched.has(`${form}.${field}`) ? message(kinds[field] ?? null) : null;
|
|
127
127
|
const anyError = (kinds) => Object.values(kinds).some((kind) => kind !== null);
|
|
128
128
|
const submitAll = (form, fields) => {
|
|
129
|
-
// Submit dotyka całego formularza
|
|
129
|
+
// Submit dotyka całego formularza - inaczej pola, których użytkownik nie ruszył, nie
|
|
130
130
|
// pokazałyby błędu. Dlatego przycisk wysyłki nie jest wyłączany przy błędach: pokazuje,
|
|
131
131
|
// czego brakuje, zamiast stać martwy (WCAG 3.3.1).
|
|
132
132
|
setTouched((prev) => {
|
package/dist/auth/llms.txt
CHANGED
|
@@ -4,27 +4,27 @@ An authentication screen: sign in, sign up and password recovery in one componen
|
|
|
4
4
|
panel and a list of external providers.
|
|
5
5
|
Import: `import { KptAuth, type KptAuthProvider } from '@konce-pt/react';`
|
|
6
6
|
|
|
7
|
-
The component is **presentational**
|
|
7
|
+
The component is **presentational** - it calls no API and does not navigate; the app does that in
|
|
8
8
|
the handlers.
|
|
9
9
|
|
|
10
10
|
## Props
|
|
11
|
-
- `mode` / `defaultMode` / `onModeChange`
|
|
12
|
-
- `layout`: `'slider'` (default) | `'split'`
|
|
13
|
-
- `providers`: `KptAuthProvider[]`
|
|
11
|
+
- `mode` / `defaultMode` / `onModeChange` - `'signIn' | 'signUp' | 'forgot'`
|
|
12
|
+
- `layout`: `'slider'` (default) | `'split'` - the promo panel slides to the other side, or stays put
|
|
13
|
+
- `providers`: `KptAuthProvider[]` - `{ id, label, icon?, iconUrl?, description? }`
|
|
14
14
|
- `providerLayout`: `'list'` (default) | `'grid'`
|
|
15
15
|
- `showName`, `requireTerms`, `showRemember`: boolean (default true)
|
|
16
|
-
- `busy`: boolean
|
|
17
|
-
- `error` / `notice`: string | null
|
|
16
|
+
- `busy`: boolean - the buttons show a loading state, providers are blocked
|
|
17
|
+
- `error` / `notice`: string | null - a server message (a `danger` / `success` alert)
|
|
18
18
|
- `promoTitle` / `promoText`: `null` = mode-dependent text from i18n, `''` = hidden
|
|
19
19
|
- `animated` (true), `animationDuration` (320 ms)
|
|
20
20
|
- `onSignIn`, `onSignUp`, `onResetPassword`, `onProviderSelect`
|
|
21
|
-
- `renderProvider(provider, select)`
|
|
21
|
+
- `renderProvider(provider, select)` - custom markup for one provider; return `null` for the rest
|
|
22
22
|
|
|
23
23
|
## Slots
|
|
24
|
-
`KptAuth.Brand`, `KptAuth.Promo`, `KptAuth.Sso`, `KptAuth.Fields`, `KptAuth.Footer`
|
|
24
|
+
`KptAuth.Brand`, `KptAuth.Promo`, `KptAuth.Sso`, `KptAuth.Fields`, `KptAuth.Footer` - the
|
|
25
25
|
equivalents of the `[kptAuthBrand]`, `[kptAuthPromo]`, `[kptAuthSso]`, `[kptAuthFields]` and
|
|
26
26
|
`[kptAuthFooter]` projections. **Fields from the `Fields` slot are not part of the component's
|
|
27
|
-
model**
|
|
27
|
+
model** - bind them to your own state and read them in the handler.
|
|
28
28
|
|
|
29
29
|
## Validation without a form library
|
|
30
30
|
Three independent forms, one per mode, validated on every render: e-mail required and valid,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type ComponentPropsWithRef } from 'react';
|
|
2
2
|
import { type KptI18nOverrides } from '../i18n/i18n-context.tsx';
|
|
3
|
+
import type { KptSpeechMode } from '@konce-pt/speech';
|
|
4
|
+
import { type KptSpeechColor } from '../speech/speech-button.tsx';
|
|
3
5
|
export interface KptAutocompleteProps extends Omit<ComponentPropsWithRef<'input'>, 'value' | 'defaultValue' | 'onChange'>, KptI18nOverrides {
|
|
4
6
|
options?: readonly string[];
|
|
5
7
|
value?: string;
|
|
@@ -8,16 +10,27 @@ export interface KptAutocompleteProps extends Omit<ComponentPropsWithRef<'input'
|
|
|
8
10
|
invalid?: boolean;
|
|
9
11
|
touched?: boolean;
|
|
10
12
|
onTouch?: () => void;
|
|
13
|
+
/** Mikrofon w polu (Web Speech API). Bez wsparcia przeglądarki się nie pokazuje. */
|
|
14
|
+
speech?: boolean;
|
|
15
|
+
/** Język dyktowania (BCP 47); bez niego z `KptI18nProvider`. */
|
|
16
|
+
speechLang?: string;
|
|
17
|
+
/** Kolor "stop" i fali w trakcie nasłuchu; domyślnie kolor motywu. */
|
|
18
|
+
speechColor?: KptSpeechColor;
|
|
19
|
+
/**
|
|
20
|
+
* Domyślnie `replace`: podyktowana wartość zastępuje poprzednią, a nasłuch kończy się po jednej
|
|
21
|
+
* wypowiedzi - to pole wybiera jedną wartość, nie zbiera tekstu.
|
|
22
|
+
*/
|
|
23
|
+
speechMode?: KptSpeechMode;
|
|
11
24
|
}
|
|
12
25
|
/**
|
|
13
|
-
* Pole z podpowiedziami. Wartością jest wpisany tekst, nie wybrana opcja
|
|
26
|
+
* Pole z podpowiedziami. Wartością jest wpisany tekst, nie wybrana opcja - podpowiedzi
|
|
14
27
|
* skracają pisanie, ale nie ograniczają wpisu, więc pole nadaje się też do wartości spoza listy.
|
|
15
28
|
*
|
|
16
|
-
* Wzorzec WAI-ARIA
|
|
17
|
-
* `aria-activedescendant`, a liczbę podpowiedzi (albo ich brak)
|
|
18
|
-
* pomija wielkość liter i diakrytyki (
|
|
29
|
+
* Wzorzec WAI-ARIA "combobox z listą": fokus zostaje w polu, aktywną podpowiedź ogłasza
|
|
30
|
+
* `aria-activedescendant`, a liczbę podpowiedzi (albo ich brak) - region `polite`. Dopasowanie
|
|
31
|
+
* pomija wielkość liter i diakrytyki ("lodz" znajduje "Łódź").
|
|
19
32
|
*
|
|
20
33
|
* @example
|
|
21
|
-
* <KptAutocomplete options={cities} value={city} onValueChange={setCity} placeholder="Miasto
|
|
34
|
+
* <KptAutocomplete options={cities} value={city} onValueChange={setCity} placeholder="Miasto..." />
|
|
22
35
|
*/
|
|
23
|
-
export declare function KptAutocomplete({ options, value, defaultValue, onValueChange, invalid, touched, onTouch, disabled, readOnly, className, onBlur, onFocus, onKeyDown, ref, id, 'aria-describedby': ariaDescribedBy, locale, dictionary, ...rest }: Readonly<KptAutocompleteProps>): import("react").JSX.Element;
|
|
36
|
+
export declare function KptAutocomplete({ options, value, defaultValue, onValueChange, invalid, touched, onTouch, disabled, readOnly, className, onBlur, onFocus, onKeyDown, ref, id, 'aria-describedby': ariaDescribedBy, locale, dictionary, speech, speechLang, speechColor, speechMode, ...rest }: Readonly<KptAutocompleteProps>): import("react").JSX.Element;
|
|
@@ -8,24 +8,37 @@ import { useControllableState } from "../internal/use-controllable-state.js";
|
|
|
8
8
|
import { foldMentionText } from '@konce-pt/mention';
|
|
9
9
|
import { joinIds, useKptFieldA11y } from "../form-field/form-field-context.js";
|
|
10
10
|
import { useKptMessages } from "../i18n/i18n-context.js";
|
|
11
|
+
import { KptSpeechButton } from "../speech/speech-button.js";
|
|
12
|
+
import { useKptSpeechRecognition } from "../speech/use-speech-recognition.js";
|
|
11
13
|
/**
|
|
12
|
-
* Pole z podpowiedziami. Wartością jest wpisany tekst, nie wybrana opcja
|
|
14
|
+
* Pole z podpowiedziami. Wartością jest wpisany tekst, nie wybrana opcja - podpowiedzi
|
|
13
15
|
* skracają pisanie, ale nie ograniczają wpisu, więc pole nadaje się też do wartości spoza listy.
|
|
14
16
|
*
|
|
15
|
-
* Wzorzec WAI-ARIA
|
|
16
|
-
* `aria-activedescendant`, a liczbę podpowiedzi (albo ich brak)
|
|
17
|
-
* pomija wielkość liter i diakrytyki (
|
|
17
|
+
* Wzorzec WAI-ARIA "combobox z listą": fokus zostaje w polu, aktywną podpowiedź ogłasza
|
|
18
|
+
* `aria-activedescendant`, a liczbę podpowiedzi (albo ich brak) - region `polite`. Dopasowanie
|
|
19
|
+
* pomija wielkość liter i diakrytyki ("lodz" znajduje "Łódź").
|
|
18
20
|
*
|
|
19
21
|
* @example
|
|
20
|
-
* <KptAutocomplete options={cities} value={city} onValueChange={setCity} placeholder="Miasto
|
|
22
|
+
* <KptAutocomplete options={cities} value={city} onValueChange={setCity} placeholder="Miasto..." />
|
|
21
23
|
*/
|
|
22
|
-
export function KptAutocomplete({ options = [], value, defaultValue = '', onValueChange, invalid = false, touched, onTouch, disabled = false, readOnly = false, className, onBlur, onFocus, onKeyDown, ref, id, 'aria-describedby': ariaDescribedBy, locale, dictionary, ...rest }) {
|
|
24
|
+
export function KptAutocomplete({ options = [], value, defaultValue = '', onValueChange, invalid = false, touched, onTouch, disabled = false, readOnly = false, className, onBlur, onFocus, onKeyDown, ref, id, 'aria-describedby': ariaDescribedBy, locale, dictionary, speech = false, speechLang, speechColor, speechMode = 'replace', ...rest }) {
|
|
23
25
|
const { t } = useKptMessages({ locale, dictionary });
|
|
24
26
|
const field = useKptFieldA11y(id, 'kpt-autocomplete');
|
|
25
27
|
const inputRef = useRef(null);
|
|
26
28
|
/** Kotwica nakładki w stanie (callback ref), nie `inputRef.current` czytane w renderze. */
|
|
27
29
|
const [anchor, setAnchor] = useState(null);
|
|
28
30
|
const setRefs = useMemo(() => composeRefs(inputRef, ref, setAnchor), [ref]);
|
|
31
|
+
// Podyktowana wartość wchodzi przez `onChange` pola, więc lista otwiera się jak po wpisaniu;
|
|
32
|
+
// słowa tymczasowe nie filtrują - nie ma ich w stanie. Bez `speech` kontroler nie tworzy sesji.
|
|
33
|
+
const mic = useKptSpeechRecognition({
|
|
34
|
+
enabled: speech,
|
|
35
|
+
target: inputRef,
|
|
36
|
+
lang: speechLang,
|
|
37
|
+
mode: speechMode,
|
|
38
|
+
continuous: speechMode !== 'replace',
|
|
39
|
+
disabled: disabled || readOnly,
|
|
40
|
+
});
|
|
41
|
+
const speechState = speech && mic.available ? (mic.listening ? 'listening' : 'idle') : undefined;
|
|
29
42
|
const [current, setCurrent] = useControllableState({
|
|
30
43
|
value,
|
|
31
44
|
defaultValue,
|
|
@@ -33,7 +46,7 @@ export function KptAutocomplete({ options = [], value, defaultValue = '', onValu
|
|
|
33
46
|
});
|
|
34
47
|
const [open, setOpen] = useState(false);
|
|
35
48
|
const [activeIndex, setActiveIndex] = useState(-1);
|
|
36
|
-
/** Wpisano coś od ostatniego otwarcia
|
|
49
|
+
/** Wpisano coś od ostatniego otwarcia - dopiero wtedy ogłaszamy liczbę podpowiedzi. */
|
|
37
50
|
const [typed, setTyped] = useState(false);
|
|
38
51
|
const showInvalid = invalid && (touched ?? true);
|
|
39
52
|
const filtered = useMemo(() => {
|
|
@@ -70,7 +83,7 @@ export function KptAutocomplete({ options = [], value, defaultValue = '', onValu
|
|
|
70
83
|
else if (event.key === 'ArrowUp') {
|
|
71
84
|
event.preventDefault();
|
|
72
85
|
setOpen(true);
|
|
73
|
-
// Z pola (bez aktywnej)
|
|
86
|
+
// Z pola (bez aktywnej) `ArrowUp` idzie na ostatnią podpowiedź.
|
|
74
87
|
setActiveIndex((index) => (index <= 0 ? filtered.length - 1 : index - 1));
|
|
75
88
|
}
|
|
76
89
|
else if (event.key === 'Enter') {
|
|
@@ -93,7 +106,7 @@ export function KptAutocomplete({ options = [], value, defaultValue = '', onValu
|
|
|
93
106
|
}
|
|
94
107
|
}
|
|
95
108
|
};
|
|
96
|
-
return (_jsxs("span", { className: "kpt-autocomplete-host", children: [_jsx("input", { ref: setRefs, className: cn('kpt-autocomplete__input', className), type: "text", id: field.id, "aria-describedby": joinIds(ariaDescribedBy, field.describedBy), role: "combobox", "aria-autocomplete": "list", autoComplete: "off", "aria-expanded": panelOpen, "aria-controls": panelOpen ? listId : undefined, "aria-activedescendant": activeOptionId, "aria-invalid": showInvalid || undefined, "aria-readonly": readOnly || undefined, disabled: disabled, readOnly: readOnly, value: current, onChange: (event) => {
|
|
109
|
+
return (_jsxs("span", { className: "kpt-autocomplete-host", "data-speech": speechState, children: [_jsx("input", { ref: setRefs, className: cn('kpt-autocomplete__input', className), type: "text", id: field.id, "aria-describedby": joinIds(ariaDescribedBy, field.describedBy), role: "combobox", "aria-autocomplete": "list", autoComplete: "off", "aria-expanded": panelOpen, "aria-controls": panelOpen ? listId : undefined, "aria-activedescendant": activeOptionId, "aria-invalid": showInvalid || undefined, "aria-readonly": readOnly || undefined, disabled: disabled, readOnly: readOnly, value: current, onChange: (event) => {
|
|
97
110
|
setCurrent(event.target.value);
|
|
98
111
|
setOpen(true);
|
|
99
112
|
setTyped(true);
|
|
@@ -107,7 +120,7 @@ export function KptAutocomplete({ options = [], value, defaultValue = '', onValu
|
|
|
107
120
|
setOpen(false);
|
|
108
121
|
setTyped(false);
|
|
109
122
|
onTouch?.();
|
|
110
|
-
}, onKeyDown: handleKeyDown, ...rest }), _jsx(KptOverlay, { open: panelOpen, anchor: anchor, onClose: () => setOpen(false), matchAnchorWidth: true, withBackdrop: false, children: _jsx("ul", { className: "kpt-autocomplete__panel", role: "listbox", id: listId, "aria-label": rest['aria-label'], children: filtered.map((option, index) => (_jsx("li", { id: optionId(index), className: cn('kpt-autocomplete__option', index === activeIndex && 'is-active'), role: "option", "aria-selected": index === activeIndex,
|
|
123
|
+
}, onKeyDown: handleKeyDown, ...rest }), speech ? (_jsx(KptSpeechButton, { listeningColor: speechColor, speech: mic, size: "sm", unsupported: "hide", disabled: disabled || readOnly, hostProps: { className: 'kpt-autocomplete__speech' } })) : null, _jsx(KptOverlay, { open: panelOpen, anchor: anchor, onClose: () => setOpen(false), matchAnchorWidth: true, withBackdrop: false, children: _jsx("ul", { className: "kpt-autocomplete__panel", role: "listbox", id: listId, "aria-label": rest['aria-label'], children: filtered.map((option, index) => (_jsx("li", { id: optionId(index), className: cn('kpt-autocomplete__option', index === activeIndex && 'is-active'), role: "option", "aria-selected": index === activeIndex,
|
|
111
124
|
// `mousedown` z zablokowanym domyślnym zachowaniem: klik w opcję nie może
|
|
112
125
|
// zabrać fokusu polu, bo `blur` zamknąłby panel przed wyborem.
|
|
113
126
|
onMouseDown: (event) => {
|
|
@@ -12,14 +12,14 @@ A text field with suggestions. Import: `import { KptAutocomplete } from '@konce-
|
|
|
12
12
|
</ul>
|
|
13
13
|
|
|
14
14
|
## Props
|
|
15
|
-
- `options`: string[]
|
|
16
|
-
- `value` / `defaultValue` / `onValueChange`
|
|
15
|
+
- `options`: string[] - the suggestions
|
|
16
|
+
- `value` / `defaultValue` / `onValueChange` - the typed text
|
|
17
17
|
- `invalid`, `touched`, `onTouch()`
|
|
18
18
|
- `className`, `ref` and every other `<input>` prop go to the input
|
|
19
19
|
|
|
20
20
|
## The value is the text, not the option
|
|
21
21
|
Whatever is typed becomes the value; the suggestions only shorten the typing. That makes the field
|
|
22
|
-
usable for values outside the list
|
|
22
|
+
usable for values outside the list - a city nobody put in `options` still submits. When the value
|
|
23
23
|
must come from the list, reach for `KptSelect` instead.
|
|
24
24
|
|
|
25
25
|
## No backdrop
|
|
@@ -33,13 +33,13 @@ ArrowDown opens the list and moves the active option, ArrowUp moves back, Enter
|
|
|
33
33
|
one, Escape closes.
|
|
34
34
|
|
|
35
35
|
## Examples
|
|
36
|
-
<KptAutocomplete options={cities} value={city} onValueChange={setCity} placeholder="City
|
|
36
|
+
<KptAutocomplete options={cities} value={city} onValueChange={setCity} placeholder="City..." />
|
|
37
37
|
|
|
38
38
|
## Screen reader and keyboard
|
|
39
39
|
The WAI-ARIA combobox-with-list pattern: focus stays in the field, `aria-autocomplete="list"`,
|
|
40
40
|
`aria-controls` and `aria-activedescendant` point at the active suggestion, and a polite live region
|
|
41
41
|
says how many suggestions there are (`autocomplete.results`) or that there are none
|
|
42
|
-
(`autocomplete.noResults`). Matching ignores case and diacritics ("lodz" finds "Łódź").
|
|
42
|
+
(`autocomplete.noResults`). Matching ignores case and diacritics ("lodz" finds "Łódź"). `ArrowUp` from the
|
|
43
43
|
field goes to the last suggestion; the first `Escape` closes the list, the second clears the field.
|
|
44
44
|
|
|
45
45
|
## Label and description
|
|
@@ -57,3 +57,14 @@ The input is `role="combobox"` with `aria-expanded`; the panel is `role="listbox
|
|
|
57
57
|
|
|
58
58
|
## Read-only and required
|
|
59
59
|
`readOnly` is the native read-only field with `aria-readonly`; the suggestions do not open and Escape does not clear the value.
|
|
60
|
+
|
|
61
|
+
## Dictation
|
|
62
|
+
- `speech`: boolean = false - a microphone at the end of the field (`KptSpeechButton`). Hidden without
|
|
63
|
+
browser support.
|
|
64
|
+
- `speechLang`: string - BCP 47 tag; without it from `KptI18nProvider`.
|
|
65
|
+
- `speechColor`: `'primary' | 'danger' | 'success' | 'warning' | 'info'` = `'primary'` - colour of "stop" and the wave while listening.
|
|
66
|
+
- `speechMode`: `'insert' | 'append' | 'replace'` = `'replace'` - the field picks one value, so a click
|
|
67
|
+
clears it and one utterance replaces it; the suggestion list opens for the spoken text like for typed
|
|
68
|
+
text. Interim words are visible but do not filter the list - only final text reaches the state.
|
|
69
|
+
|
|
70
|
+
<KptAutocomplete options={cities} value={city} onValueChange={setCity} speech />
|
package/dist/avatar/avatar.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export type KptAvatarShape = 'circle' | 'square';
|
|
|
5
5
|
export interface KptAvatarProps extends Omit<ComponentPropsWithRef<'span'>, 'children'> {
|
|
6
6
|
/** Adres obrazu; ma pierwszeństwo przed inicjałami i ikoną. */
|
|
7
7
|
src?: string | null;
|
|
8
|
-
/** Imię i nazwisko
|
|
8
|
+
/** Imię i nazwisko - źródło inicjałów, `title` oraz etykiety dostępności. */
|
|
9
9
|
name?: string;
|
|
10
10
|
/** Nazwa ikony z rejestru, gdy nie ma obrazu ani nazwy. */
|
|
11
11
|
icon?: string | null;
|
|
@@ -15,17 +15,17 @@ export interface KptAvatarProps extends Omit<ComponentPropsWithRef<'span'>, 'chi
|
|
|
15
15
|
decorative?: boolean;
|
|
16
16
|
/**
|
|
17
17
|
* Propsy wrappera hosta (`.kpt-avatar-host`). To on jest elementem układu, więc klasy
|
|
18
|
-
* pozycjonujące awatar w rodzicu
|
|
18
|
+
* pozycjonujące awatar w rodzicu - jak `kpt-card__avatar` - idą właśnie tutaj.
|
|
19
19
|
*/
|
|
20
20
|
hostProps?: KptHostProps<'span'>;
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
|
-
* Awatar
|
|
23
|
+
* Awatar - obraz, inicjały (z `name`) lub ikona.
|
|
24
24
|
*
|
|
25
|
-
* `name` trafia do natywnego `title` (podpowiedź spod kursora
|
|
25
|
+
* `name` trafia do natywnego `title` (podpowiedź spod kursora - inicjały same w sobie nie mówią,
|
|
26
26
|
* kto to jest). Bez `src` awatar dostaje dodatkowo `role="img"` i `aria-label`, a same inicjały
|
|
27
|
-
* są `aria-hidden`, żeby czytnik nie przeczytał
|
|
28
|
-
* niesie już `alt` obrazu
|
|
27
|
+
* są `aria-hidden`, żeby czytnik nie przeczytał "AK" litera po literze. Przy `src` etykietę
|
|
28
|
+
* niesie już `alt` obrazu - nie dublujemy jej.
|
|
29
29
|
*
|
|
30
30
|
* @example
|
|
31
31
|
* <KptAvatar src="/u/anna.jpg" />
|