@konce-pt/react 0.12.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +4 -4
- package/dist/dialog/dialog.js +4 -4
- package/dist/dialog/llms.txt +11 -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/stepper/stepper.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { createContext, isValidElement, useContext, useState, } from 'react';
|
|
3
|
+
import { createContext, isValidElement, useContext, useLayoutEffect, useRef, useState, } from 'react';
|
|
4
4
|
import { cn } from "../internal/cn.js";
|
|
5
5
|
import { slotChildren, warnUnslottedChild } from "../internal/slot-children.js";
|
|
6
6
|
import { useControllableState } from "../internal/use-controllable-state.js";
|
|
7
7
|
import { useKptMessages } from "../i18n/i18n-context.js";
|
|
8
8
|
import { KptIcon } from "../icon/icon.js";
|
|
9
|
+
import { playStepperLight, preparePanelSwap, resolveEnterMotion, stepperSchedule, stepperScheduleOptions } from '@konce-pt/motion';
|
|
10
|
+
import { useKptMotion } from "../motion/motion-context.js";
|
|
9
11
|
const StepperContext = createContext(null);
|
|
10
12
|
/**
|
|
11
|
-
* Sterowanie kreatorem z wnętrza kroku
|
|
13
|
+
* Sterowanie kreatorem z wnętrza kroku - odpowiednik `#s` + `s.next()` z portu Angulara.
|
|
12
14
|
* Poza `<KptStepper>` rzuca błąd, bo bez kreatora nie ma czym sterować.
|
|
13
15
|
*
|
|
14
16
|
* @example
|
|
@@ -21,7 +23,7 @@ export function useKptStepper() {
|
|
|
21
23
|
return context;
|
|
22
24
|
}
|
|
23
25
|
/**
|
|
24
|
-
* Pojedynczy krok. Umieszczaj w `<KptStepper>`. Treść renderuje się leniwie
|
|
26
|
+
* Pojedynczy krok. Umieszczaj w `<KptStepper>`. Treść renderuje się leniwie - dopiero gdy krok
|
|
25
27
|
* jest aktywny, tak samo jak szablon `kpt-step` w porcie Angulara.
|
|
26
28
|
*/
|
|
27
29
|
export function KptStep(_props) {
|
|
@@ -30,13 +32,13 @@ export function KptStep(_props) {
|
|
|
30
32
|
}
|
|
31
33
|
KptStep.kptStepperSlot = 'step';
|
|
32
34
|
/**
|
|
33
|
-
* Kreator kroków
|
|
35
|
+
* Kreator kroków - nagłówek z numerowanymi krokami i treść aktywnego kroku.
|
|
34
36
|
* Treścią sterują `next()`/`prev()`/`goTo()` z hooka `useKptStepper()`.
|
|
35
37
|
*
|
|
36
38
|
* @example
|
|
37
39
|
* <KptStepper>
|
|
38
|
-
* <KptStepper.Step label="Konto"
|
|
39
|
-
* <KptStepper.Step label="Profil"
|
|
40
|
+
* <KptStepper.Step label="Konto">...</KptStepper.Step>
|
|
41
|
+
* <KptStepper.Step label="Profil">...</KptStepper.Step>
|
|
40
42
|
* </KptStepper>
|
|
41
43
|
*/
|
|
42
44
|
export function KptStepper({ activeIndex, defaultActiveIndex = 0, onActiveIndexChange, animated = true, animationDuration = 500, locale, dictionary, className, style, children, ...rest }) {
|
|
@@ -47,6 +49,18 @@ export function KptStepper({ activeIndex, defaultActiveIndex = 0, onActiveIndexC
|
|
|
47
49
|
onChange: onActiveIndexChange,
|
|
48
50
|
});
|
|
49
51
|
const [direction, setDirection] = useState(1);
|
|
52
|
+
/** Ruch przełączania idzie za `animated` i za `enter` z `KptMotionProvider` (`none` go wyłącza). */
|
|
53
|
+
const motionConfig = useKptMotion();
|
|
54
|
+
const motion = animated ? resolveEnterMotion(undefined, motionConfig) : 'none';
|
|
55
|
+
// Krok sprzed ostatniej zmiany - także przy zmianie z zewnątrz (`activeIndex`). Zapamiętany
|
|
56
|
+
// w stanie w trakcie renderu (wzorzec "informacja z poprzedniego renderu"), nie w efekcie.
|
|
57
|
+
const [transition, setTransition] = useState({ from: active, to: active });
|
|
58
|
+
if (transition.to !== active)
|
|
59
|
+
setTransition({ from: transition.to, to: active });
|
|
60
|
+
const rootRef = useRef(null);
|
|
61
|
+
const bodyRef = useRef(null);
|
|
62
|
+
/** Duch starej treści przygotowany przed zmianą kroku, odtwarzany po jej wyrenderowaniu. */
|
|
63
|
+
const pendingSwap = useRef(null);
|
|
50
64
|
const steps = [];
|
|
51
65
|
for (const child of slotChildren(children)) {
|
|
52
66
|
if (!isValidElement(child) || child.type?.kptStepperSlot !== 'step') {
|
|
@@ -55,10 +69,36 @@ export function KptStepper({ activeIndex, defaultActiveIndex = 0, onActiveIndexC
|
|
|
55
69
|
}
|
|
56
70
|
steps.push(child.props);
|
|
57
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Kiedy widać zmianę każdego znacznika i odcinka linii (`stepperSchedule` z @konce-pt/motion):
|
|
74
|
+
* kolor płynie po linii i zapala znacznik dopiero, gdy do niego dotrze. Bez ruchu - same zera.
|
|
75
|
+
*/
|
|
76
|
+
// Tempo linii idzie za `animationDuration` - ten sam czas steruje całym ruchem, nie tylko treścią.
|
|
77
|
+
const schedule = stepperSchedule(steps.length, motion === 'none' ? active : transition.from, active, stepperScheduleOptions(animationDuration));
|
|
78
|
+
// Kometa po linii i fala w znaczniku, do którego dociera kolor; duch starej treści - przed malowaniem.
|
|
79
|
+
useLayoutEffect(() => {
|
|
80
|
+
const play = pendingSwap.current;
|
|
81
|
+
pendingSwap.current = null;
|
|
82
|
+
play?.();
|
|
83
|
+
});
|
|
84
|
+
useLayoutEffect(() => {
|
|
85
|
+
const root = rootRef.current;
|
|
86
|
+
if (!root || motion !== 'spring' || !schedule.direction)
|
|
87
|
+
return;
|
|
88
|
+
playStepperLight(schedule, root.querySelector('.kpt-stepper__comet'), Array.from(root.querySelectorAll('.kpt-stepper__connector')), Array.from(root.querySelectorAll('.kpt-stepper__marker')));
|
|
89
|
+
// Harmonogram liczy się z `transition` - gra raz na zmianę kroku, nie na każdy render.
|
|
90
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- schedule to pochodna transition i liczby kroków
|
|
91
|
+
}, [transition, motion]);
|
|
58
92
|
const goTo = (index) => {
|
|
59
93
|
const next = Math.max(0, Math.min(index, steps.length - 1));
|
|
94
|
+
if (next === active)
|
|
95
|
+
return;
|
|
60
96
|
// Kierunek karmi `--kpt-anim-dir`, więc panel wjeżdża z tej strony, z której się cofnąłeś.
|
|
61
|
-
|
|
97
|
+
const dir = next > active ? 1 : -1;
|
|
98
|
+
setDirection(dir);
|
|
99
|
+
// Stara treść wychodzi jako duch, a pojemnik płynnie zmienia wysokość - mierzone przed zmianą.
|
|
100
|
+
if (motion !== 'none' && bodyRef.current)
|
|
101
|
+
pendingSwap.current = preparePanelSwap(bodyRef.current, dir);
|
|
62
102
|
setActive(next);
|
|
63
103
|
};
|
|
64
104
|
const context = {
|
|
@@ -68,13 +108,16 @@ export function KptStepper({ activeIndex, defaultActiveIndex = 0, onActiveIndexC
|
|
|
68
108
|
prev: () => goTo(active - 1),
|
|
69
109
|
goTo,
|
|
70
110
|
};
|
|
71
|
-
return (_jsxs("div", { className: cn('kpt-stepper-host', className), style: {
|
|
111
|
+
return (_jsxs("div", { ref: rootRef, className: cn('kpt-stepper-host', className), style: {
|
|
72
112
|
['--kpt-anim-duration']: `${animated ? animationDuration : 0}ms`,
|
|
73
113
|
['--kpt-anim-dir']: direction,
|
|
74
114
|
...style,
|
|
75
|
-
}, ...rest, children: [_jsx("ol", { className: "kpt-stepper__header", children: steps.map((step, index) => (_jsxs("li", { className: cn('kpt-stepper__step', index === active && 'is-active', index < active && 'is-done'), children: [
|
|
115
|
+
}, ...rest, children: [_jsx("ol", { className: "kpt-stepper__header", children: steps.map((step, index) => (_jsxs("li", { className: cn('kpt-stepper__step', index === active && 'is-active', index < active && 'is-done'), style: { ['--kpt-stepper-mark-delay']: `${schedule.markers[index] ?? 0}ms` }, children: [_jsxs("button", { type: "button", className: "kpt-stepper__marker", "aria-current": index === active ? 'step' : undefined, "aria-label": t(index < active ? 'stepper.stepDone' : 'stepper.step', {
|
|
76
116
|
index: index + 1,
|
|
77
117
|
label: step.label,
|
|
78
|
-
}), onClick: () => goTo(index), children: index
|
|
118
|
+
}), onClick: () => goTo(index), children: [_jsx("span", { className: "kpt-stepper__num", children: index + 1 }), _jsx(KptIcon, { className: "kpt-stepper__check", name: "check" })] }), _jsx("span", { className: "kpt-stepper__label", "aria-hidden": "true", children: step.label }), index < steps.length - 1 ? (_jsx("span", { className: "kpt-stepper__connector", style: {
|
|
119
|
+
['--kpt-stepper-line-delay']: `${schedule.lines[index]?.delay ?? 0}ms`,
|
|
120
|
+
['--kpt-stepper-line-dur']: `${schedule.lines[index]?.duration ?? 0}ms`,
|
|
121
|
+
} })) : null] }, index))) }), _jsx("span", { className: "kpt-stepper__comet", "aria-hidden": "true" }), _jsx(StepperContext.Provider, { value: context, children: _jsx("div", { className: "kpt-stepper__body", ref: bodyRef, children: steps[active] ? (_jsx("div", { className: "kpt-stepper__panel", children: steps[active].children }, active)) : null }) })] }));
|
|
79
122
|
}
|
|
80
123
|
KptStepper.Step = KptStep;
|
package/dist/switch/llms.txt
CHANGED
|
@@ -16,16 +16,17 @@ Import: `import { KptSwitch } from '@konce-pt/react';`
|
|
|
16
16
|
|
|
17
17
|
## Props
|
|
18
18
|
- `label`: string, `labelPosition`: 'start' | 'end' (default 'end')
|
|
19
|
-
- `onLabel`, `offLabel`: string
|
|
19
|
+
- `onLabel`, `offLabel`: string - the state text, swapped on toggle
|
|
20
20
|
- `checked` / `defaultChecked`, `onCheckedChange(checked)`, `onTouch()`
|
|
21
|
-
- `required`, `invalid`, `touched`
|
|
22
|
-
- `
|
|
21
|
+
- `required`, `invalid`, `touched` - as in `KptCheckbox`
|
|
22
|
+
- `toggleMotion`: 'spring' | 'fade' | 'none' (default from `KptMotionProvider`, else `spring`) - see "Toggle motion"
|
|
23
|
+
- `hostProps` - props for the `.kpt-switch-host` wrapper
|
|
23
24
|
- `className` goes to the `.kpt-switch` block; the rest to the native `<input>`
|
|
24
25
|
|
|
25
26
|
## The state text needs a controlled value
|
|
26
27
|
`onLabel` and `offLabel` read `checked`, so they only follow the switch in controlled mode.
|
|
27
28
|
Uncontrolled, the value belongs to the DOM and React never learns about a toggle, which would
|
|
28
|
-
freeze the state text on its initial value
|
|
29
|
+
freeze the state text on its initial value - use `checked` with `onCheckedChange` whenever you
|
|
29
30
|
show one.
|
|
30
31
|
|
|
31
32
|
## Examples
|
|
@@ -43,12 +44,18 @@ generated. Inside `KptFormField` the wrapper's `label[for]` points at it and the
|
|
|
43
44
|
added to `aria-describedby` (merged with your own). Without a wrapper, name it with `aria-label`.
|
|
44
45
|
Inside `kpt-form-field` the switch gets both names: the wrapper label and its own `label`.
|
|
45
46
|
|
|
47
|
+
## Toggle motion
|
|
48
|
+
`toggleMotion`: `spring` - the thumb travels on a spring and stretches while moving; `fade` - a calm colour and mark transition; `none` - no
|
|
49
|
+
motion. The bounce is started by the change handler, so a control that is checked on load does not
|
|
50
|
+
move. With no value it takes `toggle` from `KptMotionProvider` (default `spring`); `enabled: false` and the
|
|
51
|
+
system "reduce motion" setting always win.
|
|
52
|
+
|
|
46
53
|
## Tokens
|
|
47
54
|
`--kpt-color-primary` (the on track), `--kpt-color-muted` (the off track), `--kpt-color-surface`
|
|
48
55
|
(the thumb), `--kpt-motion-duration-fast`.
|
|
49
56
|
|
|
50
57
|
## Accessibility
|
|
51
|
-
`role="switch"` on a native checkbox
|
|
58
|
+
`role="switch"` on a native checkbox - a screen reader announces on/off instead of
|
|
52
59
|
checked/unchecked. The track and the thumb are `aria-hidden`.
|
|
53
60
|
|
|
54
61
|
## Read-only and required
|
package/dist/switch/switch.d.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { type ComponentPropsWithRef, type ReactNode } from 'react';
|
|
2
2
|
import type { KptHostProps } from '../internal/types.ts';
|
|
3
|
+
import { type KptToggleMotion } from '@konce-pt/motion';
|
|
3
4
|
export interface KptSwitchProps extends Omit<ComponentPropsWithRef<'input'>, 'type' | 'required'> {
|
|
5
|
+
/**
|
|
6
|
+
* Ruch przełączania: `spring` - kciuk jedzie na sprężynie i rozciąga się w ruchu; `fade` - spokojne przejście koloru i znaku; `none` - bez ruchu.
|
|
7
|
+
* Bez wartości bierze `toggle` z `KptMotionProvider` (domyślnie `spring`); `enabled={false}` i systemowe
|
|
8
|
+
* "ogranicz ruch" wyłączają go zawsze.
|
|
9
|
+
*/
|
|
10
|
+
toggleMotion?: KptToggleMotion;
|
|
4
11
|
/** Etykieta obok przełącznika. */
|
|
5
12
|
label?: string;
|
|
6
13
|
/** Pozycja etykiety względem przełącznika. */
|
|
@@ -15,7 +22,7 @@ export interface KptSwitchProps extends Omit<ComponentPropsWithRef<'input'>, 'ty
|
|
|
15
22
|
invalid?: boolean;
|
|
16
23
|
/** Czy pole było dotknięte; pominięty = stan błędu pokazuje się od razu po `invalid`. */
|
|
17
24
|
touched?: boolean;
|
|
18
|
-
/** Wygodniejszy odpowiednik `onChange`
|
|
25
|
+
/** Wygodniejszy odpowiednik `onChange` - dostaje samo zaznaczenie. */
|
|
19
26
|
onCheckedChange?: (checked: boolean) => void;
|
|
20
27
|
/** Wywoływane na `blur`. */
|
|
21
28
|
onTouch?: () => void;
|
|
@@ -27,7 +34,7 @@ export interface KptSwitchProps extends Omit<ComponentPropsWithRef<'input'>, 'ty
|
|
|
27
34
|
* Przełącznik (switch/toggle). Pod spodem natywny `<input type="checkbox" role="switch">`,
|
|
28
35
|
* więc klawiatura i czytniki ekranu działają bez dodatkowej obsługi.
|
|
29
36
|
*
|
|
30
|
-
* Wariant z tekstem stanu: `onLabel`/`offLabel`
|
|
37
|
+
* Wariant z tekstem stanu: `onLabel`/`offLabel` - wyświetlany tekst zmienia się przy przełączaniu.
|
|
31
38
|
*
|
|
32
39
|
* Tekst stanu wymaga `checked` (tryb kontrolowany), bo w trybie niekontrolowanym wartość należy
|
|
33
40
|
* do DOM i React o niej nie wie; bez tego etykieta stanu zamarłaby na wartości początkowej.
|
|
@@ -36,4 +43,4 @@ export interface KptSwitchProps extends Omit<ComponentPropsWithRef<'input'>, 'ty
|
|
|
36
43
|
* <KptSwitch name="notifications" label="Powiadomienia" />
|
|
37
44
|
* <KptSwitch checked={on} onCheckedChange={setOn} onLabel="Włączony" offLabel="Wyłączony" />
|
|
38
45
|
*/
|
|
39
|
-
export declare function KptSwitch({ label, labelPosition, onLabel, offLabel, required, invalid, touched, onCheckedChange, onTouch, hostProps, className, disabled, readOnly, onClick, checked, onChange, onBlur, children, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, id, ...rest }: Readonly<KptSwitchProps>): import("react").JSX.Element;
|
|
46
|
+
export declare function KptSwitch({ label, labelPosition, onLabel, offLabel, required, invalid, touched, onCheckedChange, onTouch, hostProps, className, disabled, readOnly, onClick, checked, onChange, onBlur, children, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, id, toggleMotion, ...rest }: Readonly<KptSwitchProps>): import("react").JSX.Element;
|
package/dist/switch/switch.js
CHANGED
|
@@ -3,11 +3,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useCallback } from 'react';
|
|
4
4
|
import { cn } from "../internal/cn.js";
|
|
5
5
|
import { joinIds, useKptFieldA11y } from "../form-field/form-field-context.js";
|
|
6
|
+
import { playPopMotion, resolveToggleMotion } from '@konce-pt/motion';
|
|
7
|
+
import { useKptMotion } from "../motion/motion-context.js";
|
|
6
8
|
/**
|
|
7
9
|
* Przełącznik (switch/toggle). Pod spodem natywny `<input type="checkbox" role="switch">`,
|
|
8
10
|
* więc klawiatura i czytniki ekranu działają bez dodatkowej obsługi.
|
|
9
11
|
*
|
|
10
|
-
* Wariant z tekstem stanu: `onLabel`/`offLabel`
|
|
12
|
+
* Wariant z tekstem stanu: `onLabel`/`offLabel` - wyświetlany tekst zmienia się przy przełączaniu.
|
|
11
13
|
*
|
|
12
14
|
* Tekst stanu wymaga `checked` (tryb kontrolowany), bo w trybie niekontrolowanym wartość należy
|
|
13
15
|
* do DOM i React o niej nie wie; bez tego etykieta stanu zamarłaby na wartości początkowej.
|
|
@@ -16,21 +18,26 @@ import { joinIds, useKptFieldA11y } from "../form-field/form-field-context.js";
|
|
|
16
18
|
* <KptSwitch name="notifications" label="Powiadomienia" />
|
|
17
19
|
* <KptSwitch checked={on} onCheckedChange={setOn} onLabel="Włączony" offLabel="Wyłączony" />
|
|
18
20
|
*/
|
|
19
|
-
export function KptSwitch({ label = '', labelPosition = 'end', onLabel = '', offLabel = '', required = false, invalid = false, touched, onCheckedChange, onTouch, hostProps, className, disabled = false, readOnly = false, onClick, checked, onChange, onBlur, children, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, id, ...rest }) {
|
|
21
|
+
export function KptSwitch({ label = '', labelPosition = 'end', onLabel = '', offLabel = '', required = false, invalid = false, touched, onCheckedChange, onTouch, hostProps, className, disabled = false, readOnly = false, onClick, checked, onChange, onBlur, children, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, id, toggleMotion, ...rest }) {
|
|
20
22
|
const field = useKptFieldA11y(id, 'kpt-switch');
|
|
21
23
|
const { className: hostClassName, ...hostRest } = hostProps ?? {};
|
|
22
24
|
const showInvalid = invalid && (touched ?? true);
|
|
23
25
|
const hasStateLabels = !!(onLabel || offLabel);
|
|
26
|
+
const motion = resolveToggleMotion(toggleMotion, useKptMotion());
|
|
24
27
|
const handleChange = useCallback((event) => {
|
|
25
28
|
onChange?.(event);
|
|
26
29
|
onCheckedChange?.(event.target.checked);
|
|
27
|
-
|
|
30
|
+
// Kciuk rozciąga się w ruchu - z handlera, nie z CSS, bo reguła na `:checked` grałaby przy starcie.
|
|
31
|
+
const thumb = event.currentTarget.nextElementSibling?.firstElementChild;
|
|
32
|
+
if (motion === 'spring' && thumb instanceof HTMLElement)
|
|
33
|
+
playPopMotion(thumb, 'squash');
|
|
34
|
+
}, [onChange, onCheckedChange, motion]);
|
|
28
35
|
const handleBlur = useCallback((event) => {
|
|
29
36
|
onBlur?.(event);
|
|
30
37
|
onTouch?.();
|
|
31
38
|
}, [onBlur, onTouch]);
|
|
32
|
-
return (_jsx("span", { className: cn('kpt-switch-host', hostClassName), ...hostRest, children: _jsxs("label", { className: cn('kpt-switch', disabled && 'kpt-switch--disabled', className), children: [label && labelPosition === 'start' ? (_jsx("span", { className: "kpt-switch__label kpt-switch__label--start", children: label })) : null, _jsx("input", { type: "checkbox", role: "switch", className: "kpt-switch__input", id: field.id, "aria-describedby": joinIds(ariaDescribedBy, field.describedBy), checked: checked, disabled: disabled, "aria-required": required || undefined, "aria-readonly": readOnly || undefined,
|
|
33
|
-
// Natywne `readonly` nie działa na polach wyboru
|
|
39
|
+
return (_jsx("span", { className: cn('kpt-switch-host', hostClassName), ...hostRest, children: _jsxs("label", { className: cn('kpt-switch', disabled && 'kpt-switch--disabled', className), "data-motion": motion, children: [label && labelPosition === 'start' ? (_jsx("span", { className: "kpt-switch__label kpt-switch__label--start", children: label })) : null, _jsx("input", { type: "checkbox", role: "switch", className: "kpt-switch__input", id: field.id, "aria-describedby": joinIds(ariaDescribedBy, field.describedBy), checked: checked, disabled: disabled, "aria-required": required || undefined, "aria-readonly": readOnly || undefined,
|
|
40
|
+
// Natywne `readonly` nie działa na polach wyboru - klik (i Spacja) jest blokowany ręcznie.
|
|
34
41
|
onClick: (event) => {
|
|
35
42
|
if (readOnly)
|
|
36
43
|
event.preventDefault();
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
# KptSwitchGroup (@konce-pt/react)
|
|
2
2
|
|
|
3
|
-
A group of switches
|
|
3
|
+
A group of switches - mutually exclusive by default, multi-select with `multiple`.
|
|
4
4
|
Import: `import { KptSwitchGroup } from '@konce-pt/react';`
|
|
5
5
|
|
|
6
6
|
## DOM
|
|
7
7
|
<div class="kpt-switch-group-host">
|
|
8
8
|
<div class="kpt-switch-group" role="group">
|
|
9
|
-
<span class="kpt-switch-host kpt-switch-group__item"
|
|
10
|
-
|
|
9
|
+
<span class="kpt-switch-host kpt-switch-group__item">...KptSwitch...</span>
|
|
10
|
+
...one per option...
|
|
11
11
|
</div>
|
|
12
12
|
</div>
|
|
13
13
|
|
|
14
14
|
## Props
|
|
15
|
-
- `options`: `KptOption<T>[]`
|
|
16
|
-
- `value` / `defaultValue` / `onValueChange`
|
|
15
|
+
- `options`: `KptOption<T>[]` - `{ label, value, disabled? }`
|
|
16
|
+
- `value` / `defaultValue` / `onValueChange` - single select: the option's value or `null`;
|
|
17
17
|
with `multiple`: an array of the selected values
|
|
18
18
|
- `multiple`: boolean (default false)
|
|
19
19
|
- `orientation`: `'vertical'` (default) | `'horizontal'`
|
|
20
|
-
- `allowDeselect`: boolean (default true)
|
|
20
|
+
- `allowDeselect`: boolean (default true) - single select only; in `multiple` mode turning an
|
|
21
21
|
option off is always allowed
|
|
22
22
|
- `disabled`, `invalid`, `touched`, `onTouch()`
|
|
23
23
|
- `className`, `ref` and every other `<div>` prop go to the host
|
|
24
24
|
|
|
25
25
|
## Single select comes out of the value, not out of the switches
|
|
26
26
|
Every entry is a `KptSwitch` whose `checked` is derived from the group value, so turning one on
|
|
27
|
-
turns the rest off by itself
|
|
27
|
+
turns the rest off by itself - there is no per-switch state to keep in sync.
|
|
28
28
|
|
|
29
29
|
That is also why `allowDeselect={false}` needs no code: the handler writes nothing, so React
|
|
30
30
|
re-applies the controlled `checked` and the switch snaps back on.
|
|
@@ -37,7 +37,7 @@ re-applies the controlled `checked` and the switch snaps back on.
|
|
|
37
37
|
## Screen reader and keyboard
|
|
38
38
|
`aria-invalid` is not supported on `role="group"`, so the error state is carried by each switch. In
|
|
39
39
|
single mode the switches are mutually exclusive and nothing announces that turning one on turned
|
|
40
|
-
another off
|
|
40
|
+
another off - for a single choice prefer `KptRadioGroup`.
|
|
41
41
|
|
|
42
42
|
## Label and description
|
|
43
43
|
`id` goes to the focusable element, not the host; without one it comes from `KptFormField` or is
|
|
@@ -54,4 +54,4 @@ Layout only: `--kpt-space-2` (vertical gap) and `--kpt-space-4` (horizontal). Th
|
|
|
54
54
|
checkbox of `KptSwitch`, so keyboard and screen readers work with no extra handling.
|
|
55
55
|
|
|
56
56
|
## Read-only and required
|
|
57
|
-
`readOnly` is passed to every switch. With `allowDeselect=false` turning the active switch off puts it back on
|
|
57
|
+
`readOnly` is passed to every switch. With `allowDeselect=false` turning the active switch off puts it back on - before, the switch looked off while the group value said it was on.
|
|
@@ -6,24 +6,24 @@ export interface KptSwitchGroupProps<T> extends Omit<ComponentPropsWithRef<'div'
|
|
|
6
6
|
value?: T | T[] | null;
|
|
7
7
|
defaultValue?: T | T[] | null;
|
|
8
8
|
onValueChange?: (value: T | T[] | null) => void;
|
|
9
|
-
/** Wielokrotny wybór
|
|
9
|
+
/** Wielokrotny wybór - wartością staje się tablica `T[]`. */
|
|
10
10
|
multiple?: boolean;
|
|
11
11
|
orientation?: 'vertical' | 'horizontal';
|
|
12
12
|
/** Czy wyłączenie aktywnej opcji zeruje wartość. Dotyczy tylko trybu pojedynczego. */
|
|
13
13
|
allowDeselect?: boolean;
|
|
14
|
-
/** Id elementu fokusowalnego (nie hosta); bez niego generowane, w `KptFormField`
|
|
14
|
+
/** Id elementu fokusowalnego (nie hosta); bez niego generowane, w `KptFormField` - z wrappera. */
|
|
15
15
|
id?: string;
|
|
16
16
|
/** Nazwa dostępna, gdy kontrolki nie opisuje etykieta (`<label for>` albo `KptFormField`). */
|
|
17
17
|
ariaLabel?: string | null;
|
|
18
18
|
disabled?: boolean;
|
|
19
|
-
/** Tylko do odczytu
|
|
19
|
+
/** Tylko do odczytu - przełączniki widać, nie da się ich zmienić. */
|
|
20
20
|
readOnly?: boolean;
|
|
21
21
|
invalid?: boolean;
|
|
22
22
|
touched?: boolean;
|
|
23
23
|
onTouch?: () => void;
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
|
-
* Grupa przełączników. Domyślnie wzajemnie wykluczających się
|
|
26
|
+
* Grupa przełączników. Domyślnie wzajemnie wykluczających się - włączenie jednego wyłącza
|
|
27
27
|
* pozostałe; z `multiple` wartością jest tablica zaznaczonych opcji.
|
|
28
28
|
*
|
|
29
29
|
* Renderuje `KptSwitch`, więc dziedziczy jego wygląd, tokeny i obsługę klawiatury.
|
|
@@ -6,7 +6,7 @@ import { useControllableState } from "../internal/use-controllable-state.js";
|
|
|
6
6
|
import { KptSwitch } from "../switch/switch.js";
|
|
7
7
|
import { useKptFieldA11y } from "../form-field/form-field-context.js";
|
|
8
8
|
/**
|
|
9
|
-
* Grupa przełączników. Domyślnie wzajemnie wykluczających się
|
|
9
|
+
* Grupa przełączników. Domyślnie wzajemnie wykluczających się - włączenie jednego wyłącza
|
|
10
10
|
* pozostałe; z `multiple` wartością jest tablica zaznaczonych opcji.
|
|
11
11
|
*
|
|
12
12
|
* Renderuje `KptSwitch`, więc dziedziczy jego wygląd, tokeny i obsługę klawiatury.
|
|
@@ -16,7 +16,7 @@ import { useKptFieldA11y } from "../form-field/form-field-context.js";
|
|
|
16
16
|
* <KptSwitchGroup multiple options={tags} value={selected} onValueChange={setSelected} />
|
|
17
17
|
*/
|
|
18
18
|
export function KptSwitchGroup({ options = [], value, defaultValue = null, onValueChange, multiple = false, orientation = 'vertical', allowDeselect = true, id, ariaLabel = null, disabled = false, readOnly = false, invalid = false, touched, onTouch, className, ...rest }) {
|
|
19
|
-
/** Grupa nie dostaje nazwy z `label[for]`
|
|
19
|
+
/** Grupa nie dostaje nazwy z `label[for]` - stąd `aria-labelledby` na etykietę wrappera. */
|
|
20
20
|
const field = useKptFieldA11y(id, 'kpt-switch-group');
|
|
21
21
|
const [current, setCurrent] = useControllableState({
|
|
22
22
|
value,
|
|
@@ -24,7 +24,7 @@ export function KptSwitchGroup({ options = [], value, defaultValue = null, onVal
|
|
|
24
24
|
onChange: onValueChange,
|
|
25
25
|
});
|
|
26
26
|
const showInvalid = invalid && (touched ?? true);
|
|
27
|
-
// Wartość normalizujemy do tablicy tylko na potrzeby odczytu w trybie multiple
|
|
27
|
+
// Wartość normalizujemy do tablicy tylko na potrzeby odczytu w trybie multiple -
|
|
28
28
|
// `null` i wartość pojedyncza są równie poprawnym wejściem.
|
|
29
29
|
const selected = Array.isArray(current) ? current : current == null ? [] : [current];
|
|
30
30
|
const isChecked = (optionValue) => multiple ? selected.includes(optionValue) : optionValue === current;
|
|
@@ -49,6 +49,6 @@ export function KptSwitchGroup({ options = [], value, defaultValue = null, onVal
|
|
|
49
49
|
// zmieniła, więc przełącznik sam wraca do włączonego przy najbliższym renderze.
|
|
50
50
|
};
|
|
51
51
|
return (_jsx("div", { className: cn('kpt-switch-group-host', className), ...rest, children: _jsx("div", { className: cn('kpt-switch-group', orientation === 'horizontal' && 'kpt-switch-group--horizontal'), role: "group", id: field.id, "aria-label": ariaLabel ?? undefined, "aria-labelledby": ariaLabel ? undefined : field.labelledBy, "aria-describedby": field.describedBy, children: options.map((option, index) => (_jsx(KptSwitch, { hostProps: { className: 'kpt-switch-group__item' }, checked: isChecked(option.value), label: option.label, disabled: disabled || option.disabled, readOnly: readOnly,
|
|
52
|
-
// `aria-invalid` nie działa na `role="group"`
|
|
52
|
+
// `aria-invalid` nie działa na `role="group"` - stan błędu niesie każdy przełącznik.
|
|
53
53
|
invalid: showInvalid, onCheckedChange: (checked) => toggle(option, checked), onTouch: onTouch }, optionKey(option.value, index)))) }) }));
|
|
54
54
|
}
|
package/dist/tabs/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# KptTabs (@konce-pt/react)
|
|
2
2
|
|
|
3
|
-
Tabs
|
|
3
|
+
Tabs - switching views, with the content rendered lazily.
|
|
4
4
|
Import: `import { KptTabs } from '@konce-pt/react';`
|
|
5
5
|
|
|
6
6
|
## DOM
|
|
@@ -14,33 +14,33 @@ Import: `import { KptTabs } from '@konce-pt/react';`
|
|
|
14
14
|
</div>
|
|
15
15
|
<div class="kpt-tabs__body" role="tabpanel" tabindex="0" id="kpt-tabs-r1-panel"
|
|
16
16
|
aria-labelledby="kpt-tabs-r1-tab-0">
|
|
17
|
-
<div class="kpt-tabs__panel"
|
|
17
|
+
<div class="kpt-tabs__panel">...active tab content...</div>
|
|
18
18
|
</div>
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
21
|
## Props
|
|
22
|
-
- `activeIndex` / `defaultActiveIndex` / `onActiveIndexChange`
|
|
22
|
+
- `activeIndex` / `defaultActiveIndex` / `onActiveIndexChange` - controlled or uncontrolled
|
|
23
23
|
- `animated`: boolean (default true), `animationDuration`: number (ms, default 500)
|
|
24
|
-
- `children`
|
|
24
|
+
- `children` - `<KptTabs.Tab>` elements
|
|
25
25
|
|
|
26
26
|
## KptTabs.Tab
|
|
27
|
-
`label` (required), `disabled`, `children`. The tab component never renders itself
|
|
27
|
+
`label` (required), `disabled`, `children`. The tab component never renders itself - `KptTabs`
|
|
28
28
|
reads its props and decides what to show, exactly as the Angular version reads the `kpt-tab`
|
|
29
29
|
template. Only the active tab's content is in the DOM.
|
|
30
30
|
|
|
31
31
|
## The underline is measured, not computed
|
|
32
32
|
`__ink` takes its width and offset from the active button in the DOM, not from the index: tabs have
|
|
33
33
|
different widths and the labels change with the language. The measurement runs after every render,
|
|
34
|
-
and the state is only replaced when the numbers actually change
|
|
34
|
+
and the state is only replaced when the numbers actually change - otherwise each measurement would
|
|
35
35
|
schedule another render and the component would loop.
|
|
36
36
|
|
|
37
37
|
## Examples
|
|
38
38
|
<KptTabs>
|
|
39
|
-
<KptTabs.Tab label="General"
|
|
40
|
-
<KptTabs.Tab label="Advanced"
|
|
39
|
+
<KptTabs.Tab label="General">...</KptTabs.Tab>
|
|
40
|
+
<KptTabs.Tab label="Advanced">...</KptTabs.Tab>
|
|
41
41
|
</KptTabs>
|
|
42
42
|
|
|
43
|
-
<KptTabs activeIndex={tab} onActiveIndexChange={setTab} animated={false}
|
|
43
|
+
<KptTabs activeIndex={tab} onActiveIndexChange={setTab} animated={false}>...</KptTabs>
|
|
44
44
|
|
|
45
45
|
## Tokens
|
|
46
46
|
`--kpt-color-primary` (the active tab and the ink), `--kpt-color-on-surface-muted`,
|
|
@@ -54,4 +54,4 @@ move between tabs, wrapping at the ends, `Home`/`End` jump to the first/last one
|
|
|
54
54
|
are skipped. Moving activates the tab straight away; the next `Tab` goes to the panel.
|
|
55
55
|
|
|
56
56
|
## Inactive content is destroyed
|
|
57
|
-
Switching renders the new panel from scratch (that is what the enter animation starts from), so local state inside the previous one
|
|
57
|
+
Switching renders the new panel from scratch (that is what the enter animation starts from), so local state inside the previous one - an unsent file upload, expanded sections, scroll position - is lost. Keep such state in your own model, outside the panel.
|
package/dist/tabs/tabs.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export interface KptTabProps {
|
|
|
5
5
|
children?: ReactNode;
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
|
-
* Pojedyncza zakładka. Umieszczaj w `<KptTabs>`. Treść renderuje się leniwie
|
|
8
|
+
* Pojedyncza zakładka. Umieszczaj w `<KptTabs>`. Treść renderuje się leniwie - dopiero gdy
|
|
9
9
|
* zakładka jest aktywna, tak samo jak szablon `kpt-tab` w porcie Angulara.
|
|
10
10
|
*/
|
|
11
11
|
export declare function KptTab(_props: Readonly<KptTabProps>): ReactNode;
|
|
@@ -21,9 +21,9 @@ export interface KptTabsProps extends Omit<ComponentPropsWithRef<'div'>, 'onChan
|
|
|
21
21
|
children?: ReactNode;
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
|
-
* Zakładki
|
|
24
|
+
* Zakładki - przełączanie widoków, treść renderowana leniwie.
|
|
25
25
|
*
|
|
26
|
-
* Klawiatura według wzorca WAI-ARIA
|
|
26
|
+
* Klawiatura według wzorca WAI-ARIA "tabs": rząd zakładek to jeden przystanek Tab, strzałki
|
|
27
27
|
* w lewo/prawo oraz `Home`/`End` przechodzą po zakładkach (z pominięciem wyłączonych) i od razu je
|
|
28
28
|
* aktywują, a kolejny `Tab` prowadzi do panelu.
|
|
29
29
|
*
|
|
@@ -32,8 +32,8 @@ export interface KptTabsProps extends Omit<ComponentPropsWithRef<'div'>, 'onChan
|
|
|
32
32
|
*
|
|
33
33
|
* @example
|
|
34
34
|
* <KptTabs>
|
|
35
|
-
* <KptTabs.Tab label="Ogólne"
|
|
36
|
-
* <KptTabs.Tab label="Zaawansowane"
|
|
35
|
+
* <KptTabs.Tab label="Ogólne">...</KptTabs.Tab>
|
|
36
|
+
* <KptTabs.Tab label="Zaawansowane">...</KptTabs.Tab>
|
|
37
37
|
* </KptTabs>
|
|
38
38
|
*/
|
|
39
39
|
export declare function KptTabs({ activeIndex, defaultActiveIndex, onActiveIndexChange, animated, animationDuration, className, style, children, ...rest }: Readonly<KptTabsProps>): import("react").JSX.Element;
|
package/dist/tabs/tabs.js
CHANGED
|
@@ -7,7 +7,7 @@ import { nextRovingIndex, rovingStop } from "../internal/roving.js";
|
|
|
7
7
|
import { useControllableState } from "../internal/use-controllable-state.js";
|
|
8
8
|
import { useKptId } from "../internal/use-id.js";
|
|
9
9
|
/**
|
|
10
|
-
* Pojedyncza zakładka. Umieszczaj w `<KptTabs>`. Treść renderuje się leniwie
|
|
10
|
+
* Pojedyncza zakładka. Umieszczaj w `<KptTabs>`. Treść renderuje się leniwie - dopiero gdy
|
|
11
11
|
* zakładka jest aktywna, tak samo jak szablon `kpt-tab` w porcie Angulara.
|
|
12
12
|
*/
|
|
13
13
|
export function KptTab(_props) {
|
|
@@ -17,9 +17,9 @@ export function KptTab(_props) {
|
|
|
17
17
|
}
|
|
18
18
|
KptTab.kptTabsSlot = 'tab';
|
|
19
19
|
/**
|
|
20
|
-
* Zakładki
|
|
20
|
+
* Zakładki - przełączanie widoków, treść renderowana leniwie.
|
|
21
21
|
*
|
|
22
|
-
* Klawiatura według wzorca WAI-ARIA
|
|
22
|
+
* Klawiatura według wzorca WAI-ARIA "tabs": rząd zakładek to jeden przystanek Tab, strzałki
|
|
23
23
|
* w lewo/prawo oraz `Home`/`End` przechodzą po zakładkach (z pominięciem wyłączonych) i od razu je
|
|
24
24
|
* aktywują, a kolejny `Tab` prowadzi do panelu.
|
|
25
25
|
*
|
|
@@ -28,8 +28,8 @@ KptTab.kptTabsSlot = 'tab';
|
|
|
28
28
|
*
|
|
29
29
|
* @example
|
|
30
30
|
* <KptTabs>
|
|
31
|
-
* <KptTabs.Tab label="Ogólne"
|
|
32
|
-
* <KptTabs.Tab label="Zaawansowane"
|
|
31
|
+
* <KptTabs.Tab label="Ogólne">...</KptTabs.Tab>
|
|
32
|
+
* <KptTabs.Tab label="Zaawansowane">...</KptTabs.Tab>
|
|
33
33
|
* </KptTabs>
|
|
34
34
|
*/
|
|
35
35
|
export function KptTabs({ activeIndex, defaultActiveIndex = 0, onActiveIndexChange, animated = true, animationDuration = 500, className, style, children, ...rest }) {
|
|
@@ -55,7 +55,7 @@ export function KptTabs({ activeIndex, defaultActiveIndex = 0, onActiveIndexChan
|
|
|
55
55
|
}
|
|
56
56
|
const disabled = tabs.map((tab) => !!tab.disabled);
|
|
57
57
|
/**
|
|
58
|
-
* Zakładka pokazywana i jedyna w kolejności Tab: aktywna, a gdy ta jest wyłączona
|
|
58
|
+
* Zakładka pokazywana i jedyna w kolejności Tab: aktywna, a gdy ta jest wyłączona - pierwsza
|
|
59
59
|
* dostępna. Wyłączona zakładka nie może wyglądać na wybraną (ani mieć swojego panelu).
|
|
60
60
|
*/
|
|
61
61
|
const shown = rovingStop(disabled, active);
|
|
@@ -65,12 +65,12 @@ export function KptTabs({ activeIndex, defaultActiveIndex = 0, onActiveIndexChan
|
|
|
65
65
|
return;
|
|
66
66
|
const next = { x: button.offsetLeft, w: button.offsetWidth };
|
|
67
67
|
// Pomiar biegnie po KAŻDYM renderze (etykiety zmieniają się z językiem, a przycisków nie da
|
|
68
|
-
// się zmierzyć przed montażem). Bez porównania `setInk` wywoływałby kolejny render w kółko
|
|
68
|
+
// się zmierzyć przed montażem). Bez porównania `setInk` wywoływałby kolejny render w kółko -
|
|
69
69
|
// React przerywa aktualizację dopiero wtedy, gdy dostanie ten sam obiekt stanu.
|
|
70
70
|
setInk((prev) => (prev.x === next.x && prev.w === next.w ? prev : next));
|
|
71
71
|
}, [shown]);
|
|
72
72
|
useLayoutEffect(measureInk);
|
|
73
|
-
// Szerokość paska zakładek zmienia się też bez zmiany okna (panel boczny, splitter)
|
|
73
|
+
// Szerokość paska zakładek zmienia się też bez zmiany okna (panel boczny, splitter) - mierzymy
|
|
74
74
|
// kontener, a `resize` okna zostaje tylko tam, gdzie nie ma ResizeObservera.
|
|
75
75
|
const headerRef = useRef(null);
|
|
76
76
|
useLayoutEffect(() => {
|
package/dist/textarea/llms.txt
CHANGED
|
@@ -9,42 +9,53 @@ A multi-line field, with optional auto-resize. It renders a native `<textarea>`
|
|
|
9
9
|
</span>
|
|
10
10
|
|
|
11
11
|
## Props
|
|
12
|
-
- `autoResize`: boolean
|
|
13
|
-
- `rows`: number (default 3)
|
|
14
|
-
- `value` / `defaultValue`
|
|
15
|
-
- `onValueChange(value)`, `onTouch()`
|
|
16
|
-
- `required`: boolean
|
|
17
|
-
- `invalid`, `touched`
|
|
18
|
-
- `hostProps`
|
|
12
|
+
- `autoResize`: boolean - matches the height to the content on every change
|
|
13
|
+
- `rows`: number (default 3) - the starting height
|
|
14
|
+
- `value` / `defaultValue` - controlled or uncontrolled, like a native textarea
|
|
15
|
+
- `onValueChange(value)`, `onTouch()` - the value alone, and the blur moment
|
|
16
|
+
- `required`: boolean - set as `aria-required`, not as the native attribute
|
|
17
|
+
- `invalid`, `touched` - the error state, gated the same way as in `KptInput`
|
|
18
|
+
- `hostProps` - props for the wrapper
|
|
19
19
|
- `className`, `ref`, `name`, `placeholder` and every other `<textarea>` prop go to the textarea
|
|
20
20
|
|
|
21
21
|
## Auto-resize
|
|
22
22
|
The height is read straight from the DOM (`scrollHeight`), so it is right for a controlled field, an
|
|
23
23
|
uncontrolled one, and a prefilled initial value alike. The measurement resets the height to `auto`
|
|
24
|
-
first
|
|
24
|
+
first - without that a field can only ever grow, since `scrollHeight` never drops below the current
|
|
25
25
|
height.
|
|
26
26
|
|
|
27
27
|
## Examples
|
|
28
|
-
<KptTextarea name="notes" placeholder="Notes
|
|
28
|
+
<KptTextarea name="notes" placeholder="Notes..." autoResize />
|
|
29
29
|
<KptTextarea value={note} onValueChange={setNote} rows={6} />
|
|
30
30
|
<KptFormField label="Notes" error={err}>
|
|
31
31
|
<KptTextarea invalid={!!err} onTouch={markTouched} />
|
|
32
32
|
</KptFormField>
|
|
33
33
|
|
|
34
34
|
## Screen reader and keyboard
|
|
35
|
-
`counter`: boolean
|
|
35
|
+
`counter`: boolean - a "12 / 280" counter under the field (requires the native `maxLength`), read
|
|
36
36
|
together with it through `aria-describedby`.
|
|
37
37
|
|
|
38
38
|
## Label and description
|
|
39
39
|
`id` goes to the native field, not the host; without one it comes from `KptFormField` or is
|
|
40
40
|
generated. Inside `KptFormField` the wrapper's `label[for]` points at it and the hint or error is
|
|
41
41
|
added to `aria-describedby` (merged with your own). Without a wrapper, name it with `aria-label`.
|
|
42
|
-
New: `id`, `ariaLabel` and `required` (
|
|
42
|
+
New: `id`, `ariaLabel` and `required` (-> `aria-required`); `[formField]` binds `required`.
|
|
43
43
|
|
|
44
44
|
## Tokens
|
|
45
|
-
`--kpt-form-field-{bg,text,placeholder,border,border-hover,border-focus,border-error,radius}`
|
|
45
|
+
`--kpt-form-field-{bg,text,placeholder,border,border-hover,border-focus,border-error,radius}` -
|
|
46
46
|
the same set as the text field, so both controls stay in step.
|
|
47
47
|
|
|
48
48
|
## Accessibility
|
|
49
49
|
A native `<textarea>`. Inside `KptFormField` it takes its `id` from the wrapper, so `label[for]`
|
|
50
50
|
is wired with no configuration.
|
|
51
|
+
|
|
52
|
+
## Dictation
|
|
53
|
+
- `speech`: boolean = false - a microphone in the top corner of the field (the bottom corner belongs
|
|
54
|
+
to the resize handle); the wave appears under it. The field then sits in `.kpt-textarea__box`.
|
|
55
|
+
Without browser support it is not shown.
|
|
56
|
+
- `speechLang`: string; `speechMode`: `'insert' | 'append' | 'replace'` = `'insert'`.
|
|
57
|
+
- `speechColor`: `'primary' | 'danger' | 'success' | 'warning' | 'info'` = `'primary'` - colour of "stop" and the wave while listening.
|
|
58
|
+
|
|
59
|
+
Interim words are visible but never reach your state; `autoResize` follows the dictated text.
|
|
60
|
+
|
|
61
|
+
<KptTextarea value={notes} onValueChange={setNotes} speech autoResize />
|