@konce-pt/react 0.11.2 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +128 -64
- package/dist/accordion/accordion.d.ts +14 -6
- package/dist/accordion/accordion.js +25 -17
- package/dist/accordion/llms.txt +22 -10
- package/dist/alert/alert.d.ts +2 -2
- package/dist/alert/alert.js +3 -2
- package/dist/alert/llms.txt +10 -9
- package/dist/app-shell/app-shell.d.ts +14 -14
- package/dist/app-shell/app-shell.js +22 -15
- package/dist/app-shell/llms.txt +16 -15
- package/dist/auth/auth-types.d.ts +6 -6
- package/dist/auth/auth.d.ts +2 -2
- package/dist/auth/auth.js +24 -15
- package/dist/auth/llms.txt +12 -11
- package/dist/autocomplete/autocomplete.d.ts +19 -6
- package/dist/autocomplete/autocomplete.js +32 -11
- package/dist/autocomplete/llms.txt +19 -5
- package/dist/avatar/avatar.d.ts +6 -6
- package/dist/avatar/avatar.js +6 -5
- package/dist/avatar/llms.txt +10 -10
- package/dist/avatar-group/avatar-group.d.ts +4 -4
- package/dist/avatar-group/avatar-group.js +4 -3
- package/dist/avatar-group/llms.txt +8 -8
- package/dist/backdrop/backdrop.d.ts +7 -26
- package/dist/backdrop/backdrop.js +32 -27
- package/dist/backdrop/llms.txt +27 -27
- package/dist/badge/badge.d.ts +3 -3
- package/dist/badge/badge.js +1 -1
- package/dist/badge/llms.txt +11 -11
- package/dist/bottom-sheet/bottom-sheet.d.ts +8 -3
- package/dist/bottom-sheet/bottom-sheet.js +5 -4
- package/dist/bottom-sheet/llms.txt +11 -8
- package/dist/breadcrumb/breadcrumb.d.ts +8 -2
- package/dist/breadcrumb/breadcrumb.js +11 -3
- package/dist/breadcrumb/llms.txt +10 -2
- package/dist/button/button.d.ts +3 -3
- package/dist/button/button.js +10 -9
- package/dist/button/llms.txt +27 -19
- package/dist/button-group/button-group.d.ts +18 -5
- package/dist/button-group/button-group.js +54 -6
- package/dist/button-group/llms.txt +27 -18
- package/dist/card/card.d.ts +8 -8
- package/dist/card/card.js +10 -9
- package/dist/card/llms.txt +20 -20
- package/dist/carousel/carousel.d.ts +6 -6
- package/dist/carousel/carousel.js +8 -5
- package/dist/carousel/llms.txt +10 -10
- package/dist/charts/chart-legend.d.ts +3 -3
- package/dist/charts/chart-legend.js +2 -1
- package/dist/charts/chart-tooltip.d.ts +3 -3
- package/dist/charts/chart-tooltip.js +1 -1
- package/dist/charts/chart.d.ts +4 -3
- package/dist/charts/chart.js +18 -10
- package/dist/charts/llms.txt +10 -7
- package/dist/charts-entry/public-api.js +2 -2
- package/dist/chat/chat.d.ts +17 -10
- package/dist/chat/chat.js +77 -23
- package/dist/chat/llms.txt +39 -15
- package/dist/chat-composer/chat-composer.d.ts +20 -7
- package/dist/chat-composer/chat-composer.js +29 -7
- package/dist/chat-composer/llms.txt +20 -11
- package/dist/chat-dock/chat-dock.d.ts +11 -4
- package/dist/chat-dock/chat-dock.js +10 -6
- package/dist/chat-dock/llms.txt +15 -14
- package/dist/chat-entry/public-api.js +1 -1
- package/dist/chat-message/chat-message.d.ts +12 -5
- package/dist/chat-message/chat-message.js +19 -8
- package/dist/chat-message/llms.txt +16 -15
- package/dist/chat-typing/chat-typing.d.ts +2 -2
- package/dist/chat-typing/chat-typing.js +4 -3
- package/dist/chat-typing/llms.txt +6 -6
- package/dist/checkbox/checkbox.d.ts +13 -6
- package/dist/checkbox/checkbox.js +31 -5
- package/dist/checkbox/llms.txt +26 -11
- package/dist/chip/chip.d.ts +4 -4
- package/dist/chip/chip.js +3 -2
- package/dist/chip/llms.txt +11 -11
- package/dist/chips-input/chips-input.d.ts +6 -4
- package/dist/chips-input/chips-input.js +47 -12
- package/dist/chips-input/llms.txt +18 -8
- package/dist/clock/clock.d.ts +11 -6
- package/dist/clock/clock.js +38 -8
- package/dist/clock/llms.txt +12 -8
- package/dist/color-picker/color-picker.d.ts +9 -5
- package/dist/color-picker/color-picker.js +37 -18
- package/dist/color-picker/llms.txt +8 -5
- package/dist/confirm/confirm-container.d.ts +3 -3
- package/dist/confirm/confirm-container.js +6 -5
- package/dist/confirm/confirm-store.d.ts +4 -4
- package/dist/confirm/confirm-store.js +11 -5
- package/dist/confirm/llms.txt +8 -7
- package/dist/context-menu/context-menu.d.ts +1 -1
- package/dist/context-menu/context-menu.js +37 -14
- package/dist/context-menu/llms.txt +10 -7
- package/dist/data-table/data-table-types.d.ts +5 -5
- package/dist/data-table/data-table.d.ts +37 -5
- package/dist/data-table/data-table.js +426 -119
- package/dist/data-table/export-csv.d.ts +3 -3
- package/dist/data-table/export-csv.js +8 -10
- package/dist/data-table/llms.txt +127 -79
- package/dist/data-view/data-view.d.ts +13 -5
- package/dist/data-view/data-view.js +68 -6
- package/dist/data-view/llms.txt +29 -10
- package/dist/date-range/date-range.d.ts +20 -8
- package/dist/date-range/date-range.js +86 -63
- package/dist/date-range/llms.txt +32 -18
- package/dist/datepicker/datepicker.d.ts +22 -8
- package/dist/datepicker/datepicker.js +103 -71
- package/dist/datepicker/llms.txt +36 -22
- package/dist/dialog/dialog.d.ts +4 -4
- package/dist/dialog/dialog.js +32 -11
- package/dist/dialog/llms.txt +13 -10
- package/dist/divider/divider.d.ts +7 -1
- package/dist/divider/divider.js +3 -2
- package/dist/divider/llms.txt +4 -3
- package/dist/drawer/drawer.d.ts +9 -4
- package/dist/drawer/drawer.js +5 -4
- package/dist/drawer/llms.txt +13 -10
- package/dist/empty/empty.d.ts +2 -2
- package/dist/empty/empty.js +1 -1
- package/dist/empty/llms.txt +9 -9
- package/dist/fab/fab.d.ts +1 -1
- package/dist/fab/fab.js +1 -1
- package/dist/fab/llms.txt +10 -6
- package/dist/fieldset/fieldset.d.ts +18 -4
- package/dist/fieldset/fieldset.js +12 -6
- package/dist/fieldset/llms.txt +26 -9
- package/dist/file-upload/file-upload.d.ts +8 -2
- package/dist/file-upload/file-upload.js +22 -11
- package/dist/file-upload/llms.txt +12 -9
- package/dist/form-field/form-field-context.d.ts +4 -4
- package/dist/form-field/form-field.d.ts +12 -4
- package/dist/form-field/form-field.js +27 -6
- package/dist/form-field/llms.txt +25 -11
- package/dist/galleria/galleria.d.ts +3 -3
- package/dist/galleria/galleria.js +9 -6
- package/dist/galleria/llms.txt +7 -7
- package/dist/grid/col.d.ts +4 -4
- package/dist/grid/col.js +2 -2
- package/dist/grid/flex.d.ts +3 -3
- package/dist/grid/flex.js +1 -1
- package/dist/grid/grid.d.ts +7 -7
- package/dist/grid/grid.js +3 -3
- package/dist/grid/layout.d.ts +2 -2
- package/dist/grid/layout.js +2 -2
- package/dist/grid/llms.txt +15 -15
- package/dist/grid-entry/public-api.js +1 -1
- package/dist/i18n/i18n-context.d.ts +6 -6
- package/dist/i18n/i18n-context.js +27 -5
- package/dist/icon/icon-registry.d.ts +3 -3
- package/dist/icon/icon-registry.js +3 -3
- package/dist/icon/icon.d.ts +4 -4
- package/dist/icon/icon.js +10 -7
- package/dist/icon/llms.txt +13 -13
- package/dist/icon-button/icon-button.d.ts +2 -2
- package/dist/icon-button/icon-button.js +1 -1
- package/dist/icon-button/llms.txt +9 -5
- package/dist/icons-entry/public-api.d.ts +2 -2
- package/dist/icons-entry/public-api.js +3 -3
- package/dist/image/image.js +5 -5
- package/dist/image/llms.txt +13 -13
- package/dist/input/input.d.ts +18 -5
- package/dist/input/input.js +22 -6
- package/dist/input/llms.txt +25 -11
- package/dist/input-mask/input-mask.d.ts +7 -2
- package/dist/input-mask/input-mask.js +17 -43
- package/dist/input-mask/llms.txt +8 -5
- package/dist/input-number/input-number.d.ts +11 -9
- package/dist/input-number/input-number.js +25 -21
- package/dist/input-number/llms.txt +17 -14
- package/dist/input-otp/input-otp.d.ts +18 -5
- package/dist/input-otp/input-otp.js +48 -24
- package/dist/input-otp/llms.txt +18 -7
- package/dist/internal/calendar-focus.d.ts +1 -1
- package/dist/internal/calendar-focus.js +3 -3
- package/dist/internal/cn.d.ts +1 -1
- package/dist/internal/mask.d.ts +14 -0
- package/dist/internal/mask.js +62 -0
- package/dist/internal/number-group.d.ts +22 -0
- package/dist/internal/number-group.js +53 -0
- package/dist/internal/option-key.d.ts +6 -0
- package/dist/internal/option-key.js +8 -0
- package/dist/internal/option-nav.d.ts +4 -4
- package/dist/internal/option-nav.js +5 -5
- package/dist/internal/overlay-container.js +1 -1
- package/dist/internal/overlay.d.ts +3 -3
- package/dist/internal/overlay.js +40 -10
- package/dist/internal/password-strength.d.ts +6 -0
- package/dist/internal/password-strength.js +74 -0
- package/dist/internal/roving.d.ts +2 -2
- package/dist/internal/roving.js +3 -3
- package/dist/internal/scroll-lock.d.ts +6 -0
- package/dist/internal/scroll-lock.js +35 -0
- package/dist/internal/slot-children.d.ts +13 -0
- package/dist/internal/slot-children.js +31 -0
- package/dist/internal/slot.d.ts +3 -3
- package/dist/internal/slot.js +2 -2
- package/dist/internal/step.d.ts +12 -0
- package/dist/internal/step.js +31 -0
- package/dist/internal/tween.d.ts +5 -5
- package/dist/internal/tween.js +7 -8
- package/dist/internal/types.d.ts +2 -2
- package/dist/internal/use-breakpoint.d.ts +2 -2
- package/dist/internal/use-breakpoint.js +4 -4
- package/dist/internal/use-controllable-state.d.ts +5 -0
- package/dist/internal/use-controllable-state.js +25 -4
- package/dist/internal/use-id.d.ts +2 -2
- package/dist/internal/use-id.js +2 -2
- package/dist/internal/use-modal-focus.d.ts +2 -1
- package/dist/internal/use-modal-focus.js +14 -3
- package/dist/knob/knob.d.ts +7 -4
- package/dist/knob/knob.js +27 -22
- package/dist/knob/llms.txt +18 -11
- package/dist/listbox/listbox.d.ts +8 -6
- package/dist/listbox/listbox.js +37 -17
- package/dist/listbox/llms.txt +12 -9
- package/dist/loader/llms.txt +56 -0
- package/dist/loader/loader.d.ts +49 -0
- package/dist/loader/loader.js +68 -0
- package/dist/map/llms.txt +30 -23
- package/dist/map/map-create-dialog.d.ts +4 -4
- package/dist/map/map-create-dialog.js +36 -28
- package/dist/map/map-hours-field.d.ts +4 -4
- package/dist/map/map-hours-field.js +8 -7
- package/dist/map/map-image-field.d.ts +2 -2
- package/dist/map/map-image-field.js +6 -5
- package/dist/map/map-legend.d.ts +4 -4
- package/dist/map/map-legend.js +3 -2
- package/dist/map/map-poi-card.d.ts +3 -3
- package/dist/map/map-poi-card.js +10 -9
- package/dist/map/map-search.d.ts +17 -6
- package/dist/map/map-search.js +70 -43
- package/dist/map/map.d.ts +25 -13
- package/dist/map/map.js +86 -57
- package/dist/map/ports.d.ts +9 -9
- package/dist/map/ports.js +6 -6
- package/dist/map-entry/public-api.js +2 -2
- package/dist/megamenu/llms.txt +18 -7
- package/dist/megamenu/megamenu.d.ts +12 -6
- package/dist/megamenu/megamenu.js +23 -14
- package/dist/mention/llms.txt +15 -15
- package/dist/mention/mention.d.ts +5 -5
- package/dist/mention/mention.js +2 -2
- package/dist/mention/mentions.d.ts +1 -1
- package/dist/mention/mentions.js +1 -1
- package/dist/menu/llms.txt +12 -12
- package/dist/menu/menu-item.d.ts +4 -4
- package/dist/menu/menu-keys.d.ts +2 -2
- package/dist/menu/menu-keys.js +5 -5
- package/dist/menu/menu-rows.js +1 -0
- package/dist/menu/menu.d.ts +2 -2
- package/dist/menu/menu.js +15 -8
- package/dist/menubar/llms.txt +19 -8
- package/dist/menubar/menubar.d.ts +11 -5
- package/dist/menubar/menubar.js +23 -11
- package/dist/meter-group/llms.txt +12 -12
- package/dist/meter-group/meter-group.d.ts +2 -2
- package/dist/meter-group/meter-group.js +2 -1
- package/dist/motion/motion-context.d.ts +22 -0
- package/dist/motion/motion-context.js +28 -0
- package/dist/order-list/llms.txt +24 -9
- package/dist/order-list/order-list.d.ts +12 -4
- package/dist/order-list/order-list.js +123 -25
- package/dist/paginator/llms.txt +8 -8
- package/dist/paginator/paginator.js +7 -4
- package/dist/panel/llms.txt +25 -13
- package/dist/panel/panel.d.ts +11 -3
- package/dist/panel/panel.js +12 -7
- package/dist/password/llms.txt +19 -7
- package/dist/password/password.d.ts +2 -2
- package/dist/password/password.js +27 -16
- package/dist/peek/llms.txt +11 -11
- package/dist/peek/peek.d.ts +6 -6
- package/dist/peek/peek.js +41 -19
- package/dist/pick-list/llms.txt +35 -12
- package/dist/pick-list/pick-list.d.ts +12 -4
- package/dist/pick-list/pick-list.js +128 -24
- package/dist/popover/llms.txt +13 -10
- package/dist/popover/popover.d.ts +6 -4
- package/dist/popover/popover.js +14 -7
- package/dist/progress/llms.txt +17 -17
- package/dist/progress/progress.d.ts +7 -7
- package/dist/progress/progress.js +7 -6
- package/dist/public-api.d.ts +16 -4
- package/dist/public-api.js +13 -7
- package/dist/radio-group/llms.txt +16 -6
- package/dist/radio-group/radio-group.d.ts +12 -3
- package/dist/radio-group/radio-group.js +23 -4
- package/dist/rating/llms.txt +20 -13
- package/dist/rating/rating-pointer.d.ts +16 -0
- package/dist/rating/rating-pointer.js +26 -0
- package/dist/rating/rating.d.ts +6 -6
- package/dist/rating/rating.js +77 -12
- package/dist/rich-text/lists.d.ts +2 -2
- package/dist/rich-text/lists.js +7 -7
- package/dist/rich-text/llms.txt +35 -12
- package/dist/rich-text/rich-text.d.ts +13 -14
- package/dist/rich-text/rich-text.js +311 -142
- package/dist/rich-text/sanitize.d.ts +11 -2
- package/dist/rich-text/sanitize.js +80 -32
- package/dist/rich-text/tables.d.ts +3 -3
- package/dist/rich-text/tables.js +3 -3
- package/dist/roadmap/llms.txt +23 -17
- package/dist/roadmap/roadmap.d.ts +6 -6
- package/dist/roadmap/roadmap.js +102 -25
- package/dist/roadmap-entry/public-api.js +2 -2
- package/dist/scroll-top/llms.txt +6 -6
- package/dist/scroll-top/scroll-top.d.ts +1 -1
- package/dist/scroll-top/scroll-top.js +2 -1
- package/dist/select/llms.txt +22 -12
- package/dist/select/select.d.ts +10 -8
- package/dist/select/select.js +87 -47
- package/dist/shared/types.d.ts +22 -1
- package/dist/shared/types.js +9 -1
- package/dist/sidenav/llms.txt +9 -9
- package/dist/sidenav/sidenav.d.ts +2 -3
- package/dist/sidenav/sidenav.js +5 -4
- package/dist/skeleton/llms.txt +3 -3
- package/dist/skeleton/skeleton.d.ts +1 -1
- package/dist/skeleton/skeleton.js +1 -1
- package/dist/slider/llms.txt +34 -12
- package/dist/slider/slider-drag.d.ts +26 -0
- package/dist/slider/slider-drag.js +79 -0
- package/dist/slider/slider.d.ts +8 -5
- package/dist/slider/slider.js +38 -8
- package/dist/speech/llms.txt +97 -0
- package/dist/speech/speech-button.d.ts +44 -0
- package/dist/speech/speech-button.js +86 -0
- package/dist/speech/speech-wave.d.ts +19 -0
- package/dist/speech/speech-wave.js +16 -0
- package/dist/speech/use-speech-recognition.d.ts +81 -0
- package/dist/speech/use-speech-recognition.js +179 -0
- package/dist/speed-dial/llms.txt +14 -8
- package/dist/speed-dial/speed-dial.d.ts +1 -1
- package/dist/speed-dial/speed-dial.js +3 -2
- package/dist/spinner/llms.txt +7 -7
- package/dist/spinner/spinner.d.ts +1 -1
- package/dist/spinner/spinner.js +2 -1
- package/dist/split-button/llms.txt +21 -15
- package/dist/split-button/split-button.d.ts +2 -2
- package/dist/split-button/split-button.js +13 -6
- package/dist/splitter/llms.txt +11 -11
- package/dist/splitter/splitter.d.ts +3 -3
- package/dist/splitter/splitter.js +25 -10
- package/dist/stepper/llms.txt +35 -13
- package/dist/stepper/stepper.d.ts +6 -6
- package/dist/stepper/stepper.js +60 -13
- package/dist/switch/llms.txt +15 -5
- package/dist/switch/switch.d.ts +10 -3
- package/dist/switch/switch.js +18 -4
- package/dist/switch-group/llms.txt +11 -8
- package/dist/switch-group/switch-group.d.ts +6 -4
- package/dist/switch-group/switch-group.js +9 -7
- package/dist/tabs/llms.txt +12 -9
- package/dist/tabs/tabs.d.ts +5 -5
- package/dist/tabs/tabs.js +36 -20
- package/dist/textarea/llms.txt +23 -12
- package/dist/textarea/textarea.d.ts +19 -6
- package/dist/textarea/textarea.js +22 -7
- package/dist/timeline/llms.txt +4 -4
- package/dist/timeline/timeline.d.ts +1 -1
- package/dist/timeline/timeline.js +1 -1
- package/dist/toast/llms.txt +50 -17
- package/dist/toast/toast-container.d.ts +9 -3
- package/dist/toast/toast-container.js +18 -9
- package/dist/toast/toast-store.d.ts +42 -2
- package/dist/toast/toast-store.js +36 -1
- package/dist/toolbar/llms.txt +7 -7
- package/dist/toolbar/toolbar.d.ts +3 -3
- package/dist/toolbar/toolbar.js +2 -2
- package/dist/tooltip/llms.txt +14 -12
- package/dist/tooltip/tooltip.d.ts +5 -4
- package/dist/tooltip/tooltip.js +100 -41
- package/dist/tree/llms.txt +25 -11
- package/dist/tree/tree-keys.d.ts +5 -5
- package/dist/tree/tree-keys.js +7 -7
- package/dist/tree/tree.d.ts +17 -5
- package/dist/tree/tree.js +62 -20
- package/dist/update/llms.txt +54 -0
- package/dist/update/update.d.ts +49 -0
- package/dist/update/update.js +82 -0
- package/package.json +18 -15
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# KptChatTyping (@konce-pt/react/chat)
|
|
2
2
|
|
|
3
|
-
The typing indicator
|
|
3
|
+
The typing indicator - three dots and a line saying who is typing.
|
|
4
4
|
Import: `import { KptChatTyping } from '@konce-pt/react/chat';`
|
|
5
5
|
|
|
6
6
|
## DOM
|
|
@@ -11,13 +11,13 @@ Import: `import { KptChatTyping } from '@konce-pt/react/chat';`
|
|
|
11
11
|
<span class="kpt-chat-typing__dot"></span>
|
|
12
12
|
<span class="kpt-chat-typing__dot"></span>
|
|
13
13
|
</span>
|
|
14
|
-
<span class="kpt-chat-typing__label">Anna is typing
|
|
14
|
+
<span class="kpt-chat-typing__label">Anna is typing...</span>
|
|
15
15
|
</div>
|
|
16
16
|
</div>
|
|
17
17
|
|
|
18
18
|
## Props
|
|
19
|
-
- `authors`: `KptChatAuthor[]`
|
|
20
|
-
- `label`: string
|
|
19
|
+
- `authors`: `KptChatAuthor[]` - an empty list renders nothing at all
|
|
20
|
+
- `label`: string - your own wording instead of the dictionary's
|
|
21
21
|
- `className`, `ref` and every other `<div>` prop go to the host
|
|
22
22
|
|
|
23
23
|
## One name, then a headcount
|
|
@@ -27,7 +27,7 @@ nobody reads it anyway.
|
|
|
27
27
|
## Examples
|
|
28
28
|
<KptChatTyping authors={[anna]} />
|
|
29
29
|
<KptChatTyping authors={typing} />
|
|
30
|
-
<KptChatTyping label="The assistant is thinking
|
|
30
|
+
<KptChatTyping label="The assistant is thinking..." />
|
|
31
31
|
|
|
32
32
|
## i18n
|
|
33
33
|
`typing` (`{name}`) and `typingMany` (`{count}`) from the `chat` namespace.
|
|
@@ -37,5 +37,5 @@ The bubble `--kpt-color-surface-variant`, the dots `--kpt-color-text-muted`.
|
|
|
37
37
|
|
|
38
38
|
## Accessibility
|
|
39
39
|
`role="status"` with `aria-live="polite"` announces the indicator without interrupting a message
|
|
40
|
-
being read. Under `prefers-reduced-motion` the dots stop bouncing and pulse instead
|
|
40
|
+
being read. Under `prefers-reduced-motion` the dots stop bouncing and pulse instead - they are the
|
|
41
41
|
only carrier of "someone is typing", so switching them off entirely would remove the message.
|
|
@@ -1,20 +1,27 @@
|
|
|
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 KptCheckboxProps extends Omit<ComponentPropsWithRef<'input'>, 'type' | 'required'> {
|
|
5
|
+
/**
|
|
6
|
+
* Ruch przełączania: `spring` - pole wskakuje, a ptaszek rysuje się kreską; `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 pola. Bogatszą treść podaj jako `children`. */
|
|
5
12
|
label?: string;
|
|
6
13
|
/** Oznacza pole jako wymagane atrybutem `aria-required`, a NIE natywnym `required`. */
|
|
7
14
|
required?: boolean;
|
|
8
15
|
/**
|
|
9
|
-
* Stan pośredni (
|
|
10
|
-
* nie atrybut, więc ustawia ją komponent; czytnik ogłasza
|
|
16
|
+
* Stan pośredni ("część zaznaczona") - dla pola "zaznacz wszystko" nad listą. To właściwość DOM,
|
|
17
|
+
* nie atrybut, więc ustawia ją komponent; czytnik ogłasza "częściowo zaznaczone".
|
|
11
18
|
*/
|
|
12
19
|
indeterminate?: boolean;
|
|
13
20
|
/** Pole jest nieprawidłowe. Widoczne dopiero, gdy `touched` też jest prawdziwe. */
|
|
14
21
|
invalid?: boolean;
|
|
15
22
|
/** Czy pole było dotknięte; pominięty = stan błędu pokazuje się od razu po `invalid`. */
|
|
16
23
|
touched?: boolean;
|
|
17
|
-
/** Wygodniejszy odpowiednik `onChange`
|
|
24
|
+
/** Wygodniejszy odpowiednik `onChange` - dostaje samo zaznaczenie. */
|
|
18
25
|
onCheckedChange?: (checked: boolean) => void;
|
|
19
26
|
/** Wywoływane na `blur`. */
|
|
20
27
|
onTouch?: () => void;
|
|
@@ -24,15 +31,15 @@ export interface KptCheckboxProps extends Omit<ComponentPropsWithRef<'input'>, '
|
|
|
24
31
|
}
|
|
25
32
|
/**
|
|
26
33
|
* Pole wyboru (checkbox). Cały układ niesie `<label>`, więc kliknięcie w etykietę przełącza pole
|
|
27
|
-
* bez `htmlFor`
|
|
34
|
+
* bez `htmlFor` - natywny `<input>` w środku odpowiada za semantykę i klawiaturę.
|
|
28
35
|
*
|
|
29
36
|
* Działa kontrolowane (`checked` + `onCheckedChange`) i niekontrolowane (`defaultChecked`).
|
|
30
37
|
*
|
|
31
38
|
* `className` trafia na blok `.kpt-checkbox`, a pozostałe propsy (`name`, `value`, `ref`,
|
|
32
|
-
* handlery) na natywny `<input>`
|
|
39
|
+
* handlery) na natywny `<input>` - tam, gdzie oczekuje ich formularz.
|
|
33
40
|
*
|
|
34
41
|
* @example
|
|
35
42
|
* <KptCheckbox name="terms" label="Akceptuję regulamin" />
|
|
36
43
|
* <KptCheckbox checked={on} onCheckedChange={setOn} />
|
|
37
44
|
*/
|
|
38
|
-
export declare function KptCheckbox({ label, required, invalid, touched, onCheckedChange, onTouch, hostProps, className, disabled, onChange, onBlur, children, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, id, indeterminate, ref, ...rest }: Readonly<KptCheckboxProps>): import("react").JSX.Element;
|
|
45
|
+
export declare function KptCheckbox({ label, required, invalid, touched, onCheckedChange, onTouch, hostProps, className, disabled, readOnly, onClick, onChange, onBlur, children, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, id, indeterminate, toggleMotion, ref, ...rest }: Readonly<KptCheckboxProps>): import("react").JSX.Element;
|
|
@@ -1,22 +1,25 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
3
|
import { useCallback, useEffect, useRef } from 'react';
|
|
3
4
|
import { composeRefs } from "../internal/compose-refs.js";
|
|
4
5
|
import { cn } from "../internal/cn.js";
|
|
5
6
|
import { joinIds, useKptFieldA11y } from "../form-field/form-field-context.js";
|
|
7
|
+
import { playInvalidMotion, playPopMotion, resolveToggleMotion } from '@konce-pt/motion';
|
|
8
|
+
import { useKptMotion } from "../motion/motion-context.js";
|
|
6
9
|
/**
|
|
7
10
|
* Pole wyboru (checkbox). Cały układ niesie `<label>`, więc kliknięcie w etykietę przełącza pole
|
|
8
|
-
* bez `htmlFor`
|
|
11
|
+
* bez `htmlFor` - natywny `<input>` w środku odpowiada za semantykę i klawiaturę.
|
|
9
12
|
*
|
|
10
13
|
* Działa kontrolowane (`checked` + `onCheckedChange`) i niekontrolowane (`defaultChecked`).
|
|
11
14
|
*
|
|
12
15
|
* `className` trafia na blok `.kpt-checkbox`, a pozostałe propsy (`name`, `value`, `ref`,
|
|
13
|
-
* handlery) na natywny `<input>`
|
|
16
|
+
* handlery) na natywny `<input>` - tam, gdzie oczekuje ich formularz.
|
|
14
17
|
*
|
|
15
18
|
* @example
|
|
16
19
|
* <KptCheckbox name="terms" label="Akceptuję regulamin" />
|
|
17
20
|
* <KptCheckbox checked={on} onCheckedChange={setOn} />
|
|
18
21
|
*/
|
|
19
|
-
export function KptCheckbox({ label = '', required = false, invalid = false, touched, onCheckedChange, onTouch, hostProps, className, disabled = false, onChange, onBlur, children, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, id, indeterminate = false, ref, ...rest }) {
|
|
22
|
+
export function KptCheckbox({ label = '', required = false, invalid = false, touched, onCheckedChange, onTouch, hostProps, className, disabled = false, readOnly = false, onClick, onChange, onBlur, children, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, id, indeterminate = false, toggleMotion, ref, ...rest }) {
|
|
20
23
|
const inputRef = useRef(null);
|
|
21
24
|
useEffect(() => {
|
|
22
25
|
if (inputRef.current)
|
|
@@ -25,13 +28,36 @@ export function KptCheckbox({ label = '', required = false, invalid = false, tou
|
|
|
25
28
|
const field = useKptFieldA11y(id, 'kpt-checkbox');
|
|
26
29
|
const { className: hostClassName, ...hostRest } = hostProps ?? {};
|
|
27
30
|
const showInvalid = invalid && (touched ?? true);
|
|
31
|
+
const motion = resolveToggleMotion(toggleMotion, useKptMotion());
|
|
32
|
+
const markRef = useRef(null);
|
|
33
|
+
const wasInvalid = useRef(null);
|
|
34
|
+
// Sygnał błędu przy przejściu "poprawne -> błędne" (nie przy błędzie obecnym od startu): pierścień
|
|
35
|
+
// w kolorze błędu i krótkie potrząśnięcie. W błędnym `KptFormField` potrząsa już on - tu sam pierścień.
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
const before = wasInvalid.current;
|
|
38
|
+
wasInvalid.current = showInvalid;
|
|
39
|
+
const el = markRef.current;
|
|
40
|
+
if (!showInvalid || before !== false || motion !== 'spring' || !el)
|
|
41
|
+
return;
|
|
42
|
+
playInvalidMotion(el, { shake: !el.closest('.kpt-form-field--invalid') });
|
|
43
|
+
}, [showInvalid, motion]);
|
|
28
44
|
const handleChange = useCallback((event) => {
|
|
29
45
|
onChange?.(event);
|
|
30
46
|
onCheckedChange?.(event.target.checked);
|
|
31
|
-
|
|
47
|
+
// Wskoczenie po zmianie z ręki - z handlera, nie z CSS, bo reguła na `:checked` grałaby przy starcie.
|
|
48
|
+
const mark = event.currentTarget.nextElementSibling;
|
|
49
|
+
if (motion === 'spring' && mark instanceof HTMLElement)
|
|
50
|
+
playPopMotion(mark);
|
|
51
|
+
}, [onChange, onCheckedChange, motion]);
|
|
32
52
|
const handleBlur = useCallback((event) => {
|
|
33
53
|
onBlur?.(event);
|
|
34
54
|
onTouch?.();
|
|
35
55
|
}, [onBlur, onTouch]);
|
|
36
|
-
return (_jsx("span", { className: cn('kpt-checkbox-host', hostClassName), ...hostRest, children: _jsxs("label", { className: cn('kpt-checkbox', disabled && 'kpt-checkbox--disabled', className), children: [_jsx("input", { type: "checkbox", className: "kpt-checkbox__input", ref: composeRefs(inputRef, ref), id: field.id, "aria-describedby": joinIds(ariaDescribedBy, field.describedBy), disabled: disabled, "aria-required": required || undefined, "aria-
|
|
56
|
+
return (_jsx("span", { className: cn('kpt-checkbox-host', hostClassName), ...hostRest, children: _jsxs("label", { className: cn('kpt-checkbox', disabled && 'kpt-checkbox--disabled', className), "data-motion": motion, children: [_jsx("input", { type: "checkbox", className: "kpt-checkbox__input", ref: composeRefs(inputRef, ref), id: field.id, "aria-describedby": joinIds(ariaDescribedBy, field.describedBy), disabled: disabled, "aria-required": required || undefined, "aria-readonly": readOnly || undefined,
|
|
57
|
+
// Natywne `readonly` nie działa na polach wyboru - klik (i Spacja) jest blokowany ręcznie.
|
|
58
|
+
onClick: (event) => {
|
|
59
|
+
if (readOnly)
|
|
60
|
+
event.preventDefault();
|
|
61
|
+
onClick?.(event);
|
|
62
|
+
}, "aria-invalid": ariaInvalid ?? (showInvalid || undefined), onChange: handleChange, onBlur: handleBlur, ...rest }), _jsxs("span", { ref: markRef, className: "kpt-checkbox__box", "aria-hidden": "true", children: [_jsx("svg", { viewBox: "0 0 16 16", className: "kpt-checkbox__check", children: _jsx("path", { d: "M13 4.5 6.5 11 3 7.5", pathLength: 1 }) }), _jsx("svg", { viewBox: "0 0 16 16", className: "kpt-checkbox__dash", children: _jsx("path", { d: "M4 8h8" }) })] }), label ? _jsx("span", { className: "kpt-checkbox__label", children: label }) : null, children] }) }));
|
|
37
63
|
}
|
package/dist/checkbox/llms.txt
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
# KptCheckbox (@konce-pt/react)
|
|
2
2
|
|
|
3
3
|
A checkbox. The whole layout is a `<label>`, so clicking the text toggles the field with no
|
|
4
|
-
`htmlFor`
|
|
4
|
+
`htmlFor` - the native `<input>` inside carries the semantics and the keyboard.
|
|
5
5
|
Import: `import { KptCheckbox } from '@konce-pt/react';`
|
|
6
6
|
|
|
7
7
|
## DOM
|
|
8
8
|
<span class="kpt-checkbox-host">
|
|
9
9
|
<label class="kpt-checkbox">
|
|
10
10
|
<input type="checkbox" class="kpt-checkbox__input">
|
|
11
|
-
<span class="kpt-checkbox__box" aria-hidden="true"><svg class="kpt-checkbox__check"
|
|
11
|
+
<span class="kpt-checkbox__box" aria-hidden="true"><svg class="kpt-checkbox__check">...</svg></span>
|
|
12
12
|
<span class="kpt-checkbox__label">I accept the terms</span>
|
|
13
13
|
</label>
|
|
14
14
|
</span>
|
|
15
15
|
|
|
16
16
|
## Props
|
|
17
|
-
- `label`: string
|
|
18
|
-
- `checked` / `defaultChecked`
|
|
19
|
-
- `onCheckedChange(checked)`
|
|
20
|
-
- `onTouch()`
|
|
21
|
-
- `required`: boolean
|
|
22
|
-
- `invalid`, `touched`
|
|
23
|
-
- `
|
|
17
|
+
- `label`: string - the text next to the field; richer content goes in `children`
|
|
18
|
+
- `checked` / `defaultChecked` - controlled or uncontrolled, like a native checkbox
|
|
19
|
+
- `onCheckedChange(checked)` - the boolean alone; `onChange` still fires with the full event
|
|
20
|
+
- `onTouch()` - fires on blur
|
|
21
|
+
- `required`: boolean - set as `aria-required`, not as the native attribute
|
|
22
|
+
- `invalid`, `touched` - the error state, gated the same way as in `KptInput`
|
|
23
|
+
- `toggleMotion`: 'spring' | 'fade' | 'none' (default from `KptMotionProvider`, else `spring`) - see "Toggle motion"
|
|
24
|
+
- `hostProps` - props for the `.kpt-checkbox-host` wrapper
|
|
24
25
|
- `className` goes to the `.kpt-checkbox` block; `name`, `value`, `ref` and the handlers go to the
|
|
25
26
|
native `<input>`, which is where a form expects them
|
|
26
27
|
|
|
@@ -30,7 +31,7 @@ Import: `import { KptCheckbox } from '@konce-pt/react';`
|
|
|
30
31
|
<KptCheckbox label="Newsletter" invalid={!!err} touched={blurred} />
|
|
31
32
|
|
|
32
33
|
## Screen reader and keyboard
|
|
33
|
-
`indeterminate`: boolean
|
|
34
|
+
`indeterminate`: boolean - the "some selected" state for a "select all" box (a dash in the box;
|
|
34
35
|
screen readers say "partially checked"). It is a DOM property, so the component sets it; the browser
|
|
35
36
|
clears it on click, so set it to `false` in `onCheckedChange`.
|
|
36
37
|
|
|
@@ -40,11 +41,25 @@ generated. Inside `KptFormField` the wrapper's `label[for]` points at it and the
|
|
|
40
41
|
added to `aria-describedby` (merged with your own). Without a wrapper, name it with `aria-label`.
|
|
41
42
|
Inside `kpt-form-field` the box gets both names: the wrapper label and its own `label`.
|
|
42
43
|
|
|
44
|
+
## Toggle motion
|
|
45
|
+
`toggleMotion`: `spring` - the box pops and the check mark draws itself as a stroke; `fade` - a calm colour and mark transition; `none` - no
|
|
46
|
+
motion. The bounce is started by the change handler, so a control that is checked on load does not
|
|
47
|
+
move. With no value it takes `toggle` from `KptMotionProvider` (default `spring`); `enabled: false` and the
|
|
48
|
+
system "reduce motion" setting always win.
|
|
49
|
+
|
|
50
|
+
With `spring` the error gets a signal too: when the field turns invalid (`invalid` and `touched`),
|
|
51
|
+
an error-coloured ring spreads from the box and fades, and the box shakes briefly. An error present on
|
|
52
|
+
load stays still, and a repeated submit with the field still invalid does not replay it. Inside an
|
|
53
|
+
invalid form field the field already shakes, so the checkbox adds only the ring.
|
|
54
|
+
|
|
43
55
|
## Tokens
|
|
44
56
|
`--kpt-form-field-border`, `--kpt-color-primary` (the checked box), `--kpt-color-on-primary`
|
|
45
57
|
(the tick), `--kpt-form-field-border-error`.
|
|
46
58
|
|
|
47
59
|
## Accessibility
|
|
48
|
-
A native `<input type="checkbox">` inside a `<label>`
|
|
60
|
+
A native `<input type="checkbox">` inside a `<label>` - the label is the accessible name and the
|
|
49
61
|
whole row is clickable. The box and the tick are `aria-hidden`, being pure decoration over the real
|
|
50
62
|
control.
|
|
63
|
+
|
|
64
|
+
## Read-only and required
|
|
65
|
+
`readOnly` keeps the box focusable but blocks the click and Space (`aria-readonly`) - the native attribute does not work on checkboxes.
|
package/dist/chip/chip.d.ts
CHANGED
|
@@ -7,8 +7,8 @@ export type KptChipTextTransform = 'none' | 'capitalize' | 'uppercase' | 'lowerc
|
|
|
7
7
|
export interface KptChipProps extends ComponentPropsWithRef<'span'>, KptI18nOverrides {
|
|
8
8
|
variant?: KptChipVariant;
|
|
9
9
|
/**
|
|
10
|
-
* Wielkość liter etykiety. `capitalize` podnosi pierwszą literę każdego słowa
|
|
11
|
-
* dywizie (
|
|
10
|
+
* Wielkość liter etykiety. `capitalize` podnosi pierwszą literę każdego słowa - także po
|
|
11
|
+
* dywizie ("Agent-Ready"), bo CSS nie wie, gdzie kończy się wyraz złożony; przy takich
|
|
12
12
|
* napisach pewniejszy jest zapis wprost w treści.
|
|
13
13
|
*/
|
|
14
14
|
textTransform?: KptChipTextTransform;
|
|
@@ -21,11 +21,11 @@ export interface KptChipProps extends ComponentPropsWithRef<'span'>, KptI18nOver
|
|
|
21
21
|
hostProps?: KptHostProps<'span'>;
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
|
-
* Chip / tag
|
|
24
|
+
* Chip / tag - etykieta, opcjonalnie usuwalna.
|
|
25
25
|
*
|
|
26
26
|
* @example
|
|
27
27
|
* <KptChip>Angular</KptChip>
|
|
28
28
|
* <KptChip variant="success" removable onRemove={remove}>UI</KptChip>
|
|
29
|
-
* <KptChip textTransform="capitalize">
|
|
29
|
+
* <KptChip textTransform="capitalize">nowość, zestaw startowy</KptChip>
|
|
30
30
|
*/
|
|
31
31
|
export declare function KptChip({ variant, textTransform, removable, disabled, onRemove, locale, dictionary, hostProps, className, children, ...rest }: Readonly<KptChipProps>): import("react").JSX.Element;
|
package/dist/chip/chip.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
3
|
import { cn } from "../internal/cn.js";
|
|
3
4
|
import { useKptId } from "../internal/use-id.js";
|
|
4
5
|
import { KptIcon } from "../icon/icon.js";
|
|
5
6
|
import { useKptMessages } from "../i18n/i18n-context.js";
|
|
6
7
|
/**
|
|
7
|
-
* Chip / tag
|
|
8
|
+
* Chip / tag - etykieta, opcjonalnie usuwalna.
|
|
8
9
|
*
|
|
9
10
|
* @example
|
|
10
11
|
* <KptChip>Angular</KptChip>
|
|
11
12
|
* <KptChip variant="success" removable onRemove={remove}>UI</KptChip>
|
|
12
|
-
* <KptChip textTransform="capitalize">
|
|
13
|
+
* <KptChip textTransform="capitalize">nowość, zestaw startowy</KptChip>
|
|
13
14
|
*/
|
|
14
15
|
export function KptChip({ variant = 'neutral', textTransform = 'none', removable = false, disabled = false, onRemove, locale, dictionary, hostProps, className, children, ...rest }) {
|
|
15
16
|
const { t } = useKptMessages({ locale, dictionary });
|
package/dist/chip/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# KptChip (@konce-pt/react)
|
|
2
2
|
|
|
3
|
-
A chip / tag
|
|
3
|
+
A chip / tag - a label, optionally removable.
|
|
4
4
|
Import: `import { KptChip } from '@konce-pt/react';`
|
|
5
5
|
|
|
6
6
|
## DOM
|
|
@@ -8,23 +8,23 @@ Import: `import { KptChip } from '@konce-pt/react';`
|
|
|
8
8
|
<span class="kpt-chip" data-variant="primary">
|
|
9
9
|
<span class="kpt-chip__label" id="kpt-chip-r1-label">React</span>
|
|
10
10
|
<button type="button" class="kpt-chip__remove" id="kpt-chip-r1-remove" aria-label="Remove"
|
|
11
|
-
aria-labelledby="kpt-chip-r1-remove kpt-chip-r1-label"
|
|
11
|
+
aria-labelledby="kpt-chip-r1-remove kpt-chip-r1-label">...icon...</button>
|
|
12
12
|
</span>
|
|
13
13
|
</span>
|
|
14
14
|
|
|
15
15
|
## Props
|
|
16
16
|
- `variant`: 'neutral' | 'primary' | 'success' | 'danger' | 'warning' | 'info' (default 'neutral')
|
|
17
|
-
- `textTransform`: 'none' | 'capitalize' | 'uppercase' | 'lowercase' (default 'none')
|
|
18
|
-
- `removable`: boolean
|
|
17
|
+
- `textTransform`: 'none' | 'capitalize' | 'uppercase' | 'lowercase' (default 'none') - the label's letter case
|
|
18
|
+
- `removable`: boolean - adds the remove button
|
|
19
19
|
- `disabled`: boolean
|
|
20
|
-
- `onRemove()`
|
|
21
|
-
- `locale`, `dictionary`
|
|
22
|
-
- `hostProps`
|
|
20
|
+
- `onRemove()` - fired by the remove button
|
|
21
|
+
- `locale`, `dictionary` - i18n overrides for this component only
|
|
22
|
+
- `hostProps` - props for the `.kpt-chip-host` wrapper
|
|
23
23
|
- `className`, `ref` and every other `<span>` prop go to the inner `.kpt-chip`
|
|
24
24
|
|
|
25
25
|
## Removing is your decision
|
|
26
26
|
`onRemove` reports the intent; the chip does not remove itself from anything. Drop it from your own
|
|
27
|
-
list
|
|
27
|
+
list - that keeps the chip usable both in a controlled collection and as a standalone label.
|
|
28
28
|
|
|
29
29
|
## i18n
|
|
30
30
|
The remove button's label comes from `common.remove` in the dictionary.
|
|
@@ -33,12 +33,12 @@ The remove button's label comes from `common.remove` in the dictionary.
|
|
|
33
33
|
<KptChip>React</KptChip>
|
|
34
34
|
<KptChip variant="success" removable onRemove={() => drop(tag)}>UI</KptChip>
|
|
35
35
|
<KptCard.Tags><KptChip variant="info">Daily</KptChip></KptCard.Tags>
|
|
36
|
-
<KptChip textTransform="capitalize">new
|
|
36
|
+
<KptChip textTransform="capitalize">new, starter kit</KptChip>
|
|
37
37
|
|
|
38
38
|
## Letter case
|
|
39
39
|
`textTransform` lands as `data-text-transform` on `.kpt-chip` and sets `text-transform` there, so
|
|
40
40
|
the label can stay in the application's own wording while the chip decides how it is displayed.
|
|
41
|
-
`capitalize` raises the first letter of every word
|
|
41
|
+
`capitalize` raises the first letter of every word - **including after a hyphen**
|
|
42
42
|
("Agent-Ready"), because CSS does not know where a compound word ends. For labels with a hyphen,
|
|
43
43
|
spelling it out in the content is the exact route.
|
|
44
44
|
|
|
@@ -48,6 +48,6 @@ spelling it out in the content is the exact route.
|
|
|
48
48
|
|
|
49
49
|
## Accessibility
|
|
50
50
|
The label sits in `.kpt-chip__label`, and the remove button is named by `aria-labelledby` from
|
|
51
|
-
itself plus that label
|
|
51
|
+
itself plus that label - "Remove Angular" - so with several chips a screen reader user hears which
|
|
52
52
|
one goes. `Backspace` and `Delete` on the button work like a click. After removal focus falls back
|
|
53
53
|
to the page; move it to the next chip yourself.
|
|
@@ -7,25 +7,27 @@ export interface KptChipsInputProps extends Omit<ComponentPropsWithRef<'div'>, '
|
|
|
7
7
|
/** Placeholder; pominięty = `chipsInput.placeholder` ze słownika. */
|
|
8
8
|
placeholder?: string;
|
|
9
9
|
allowDuplicates?: boolean;
|
|
10
|
-
/** Id elementu fokusowalnego (nie hosta); bez niego generowane, w `KptFormField`
|
|
10
|
+
/** Id elementu fokusowalnego (nie hosta); bez niego generowane, w `KptFormField` - z wrappera. */
|
|
11
11
|
id?: string;
|
|
12
12
|
/** Nazwa dostępna, gdy kontrolki nie opisuje etykieta (`<label for>` albo `KptFormField`). */
|
|
13
13
|
ariaLabel?: string | null;
|
|
14
14
|
/** Oznacza pole jako wymagane atrybutem `aria-required`. */
|
|
15
15
|
required?: boolean;
|
|
16
16
|
disabled?: boolean;
|
|
17
|
+
/** Tylko do odczytu - tagi widać, nie da się ich dodać ani usunąć. */
|
|
18
|
+
readOnly?: boolean;
|
|
17
19
|
invalid?: boolean;
|
|
18
20
|
touched?: boolean;
|
|
19
21
|
onTouch?: () => void;
|
|
20
22
|
}
|
|
21
23
|
/**
|
|
22
|
-
* Pole tagów
|
|
24
|
+
* Pole tagów - dodawanie Enterem albo przecinkiem, usuwanie Backspace lub x.
|
|
23
25
|
*
|
|
24
26
|
* Tekst w trakcie pisania żyje w DOM, nie w stanie Reacta: wartością komponentu jest lista
|
|
25
27
|
* zatwierdzonych tagów, a bufor wpisywania to prywatna sprawa pola. Dzięki temu każde naciśnięcie
|
|
26
28
|
* klawisza nie przerysowuje listy chipów.
|
|
27
29
|
*
|
|
28
30
|
* @example
|
|
29
|
-
* <KptChipsInput value={tags} onValueChange={setTags} placeholder="Dodaj tag
|
|
31
|
+
* <KptChipsInput value={tags} onValueChange={setTags} placeholder="Dodaj tag..." />
|
|
30
32
|
*/
|
|
31
|
-
export declare function KptChipsInput({ value, defaultValue, onValueChange, placeholder, allowDuplicates, id, ariaLabel, required, disabled, invalid, touched, onTouch, locale, dictionary, className, ...rest }: Readonly<KptChipsInputProps>): import("react").JSX.Element;
|
|
33
|
+
export declare function KptChipsInput({ value, defaultValue, onValueChange, placeholder, allowDuplicates, id, ariaLabel, required, disabled, readOnly, invalid, touched, onTouch, locale, dictionary, className, ...rest }: Readonly<KptChipsInputProps>): import("react").JSX.Element;
|
|
@@ -1,21 +1,24 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useRef, useState } from 'react';
|
|
3
|
+
import { useLayoutEffect, useRef, useState } from 'react';
|
|
4
|
+
import { prepareFlowMotion, resolveEnterMotion } from '@konce-pt/motion';
|
|
5
|
+
import { useKptMotion } from "../motion/motion-context.js";
|
|
3
6
|
import { cn } from "../internal/cn.js";
|
|
4
7
|
import { useControllableState } from "../internal/use-controllable-state.js";
|
|
5
8
|
import { useKptMessages } from "../i18n/i18n-context.js";
|
|
6
9
|
import { KptChip } from "../chip/chip.js";
|
|
7
10
|
import { useKptFieldA11y } from "../form-field/form-field-context.js";
|
|
8
11
|
/**
|
|
9
|
-
* Pole tagów
|
|
12
|
+
* Pole tagów - dodawanie Enterem albo przecinkiem, usuwanie Backspace lub x.
|
|
10
13
|
*
|
|
11
14
|
* Tekst w trakcie pisania żyje w DOM, nie w stanie Reacta: wartością komponentu jest lista
|
|
12
15
|
* zatwierdzonych tagów, a bufor wpisywania to prywatna sprawa pola. Dzięki temu każde naciśnięcie
|
|
13
16
|
* klawisza nie przerysowuje listy chipów.
|
|
14
17
|
*
|
|
15
18
|
* @example
|
|
16
|
-
* <KptChipsInput value={tags} onValueChange={setTags} placeholder="Dodaj tag
|
|
19
|
+
* <KptChipsInput value={tags} onValueChange={setTags} placeholder="Dodaj tag..." />
|
|
17
20
|
*/
|
|
18
|
-
export function KptChipsInput({ value, defaultValue = [], onValueChange, placeholder, allowDuplicates = false, id, ariaLabel = null, required = false, disabled = false, invalid = false, touched, onTouch, locale, dictionary, className, ...rest }) {
|
|
21
|
+
export function KptChipsInput({ value, defaultValue = [], onValueChange, placeholder, allowDuplicates = false, id, ariaLabel = null, required = false, disabled = false, readOnly = false, invalid = false, touched, onTouch, locale, dictionary, className, ...rest }) {
|
|
19
22
|
const { t } = useKptMessages({ locale, dictionary });
|
|
20
23
|
const field = useKptFieldA11y(id, 'kpt-chips-input');
|
|
21
24
|
const inputRef = useRef(null);
|
|
@@ -25,36 +28,68 @@ export function KptChipsInput({ value, defaultValue = [], onValueChange, placeho
|
|
|
25
28
|
onChange: onValueChange,
|
|
26
29
|
});
|
|
27
30
|
const showInvalid = invalid && (touched ?? true);
|
|
31
|
+
/** Wejście i wyjście tagu idą za `enter` z `KptMotionProvider` (domyślnie `spring`). */
|
|
32
|
+
const motion = resolveEnterMotion(undefined, useKptMotion());
|
|
33
|
+
const boxRef = useRef(null);
|
|
34
|
+
/** Ruch przygotowany przed zmianą listy, odtwarzany po jej wyrenderowaniu. */
|
|
35
|
+
const pendingFlow = useRef(null);
|
|
36
|
+
/** Sam chip, nie `__item` - ten ma `display: contents` (semantyka listy) i nie ma pudełka do animacji. */
|
|
37
|
+
const flowItems = () => Array.from(boxRef.current?.querySelectorAll('.kpt-chips-input__item > *, .kpt-chips-input__field') ?? []);
|
|
38
|
+
// Przed malowaniem - inaczej mignęłaby klatka z nowym układem, zanim FLIP cofnie elementy.
|
|
39
|
+
useLayoutEffect(() => {
|
|
40
|
+
const play = pendingFlow.current;
|
|
41
|
+
pendingFlow.current = null;
|
|
42
|
+
play?.(flowItems());
|
|
43
|
+
});
|
|
44
|
+
/**
|
|
45
|
+
* Zmienia listę z ruchem: nowy tag wskakuje, usunięty gaśnie jako duch, a reszta i pole dosuwają
|
|
46
|
+
* się FLIP-em. Tagi są śledzone po indeksie, więc ruch liczy się z pozycji danych, nie węzłów -
|
|
47
|
+
* szczegóły w `prepareFlowMotion`. Stan zmienia się od razu; ruch tylko go ilustruje.
|
|
48
|
+
*/
|
|
49
|
+
const change = (next, flow) => {
|
|
50
|
+
const box = boxRef.current;
|
|
51
|
+
if (motion !== 'none' && box)
|
|
52
|
+
pendingFlow.current = prepareFlowMotion(box, flowItems(), flow, motion);
|
|
53
|
+
setChips(next);
|
|
54
|
+
};
|
|
28
55
|
/** Komunikat regionu `polite`: dodanie, usunięcie albo odrzucony duplikat. */
|
|
29
|
-
const [announcement,
|
|
56
|
+
const [announcement, setAnnouncementState] = useState('');
|
|
57
|
+
/**
|
|
58
|
+
* Ten sam komunikat dwa razy z rzędu (drugi odrzucony duplikat) nie zmieniłby treści regionu
|
|
59
|
+
* i czytnik by go nie ogłosił - doklejamy niewidoczną spację, żeby tekst się różnił.
|
|
60
|
+
*/
|
|
61
|
+
const setAnnouncement = (message) => setAnnouncementState((current) => (current === message ? `${message}\u00A0` : message));
|
|
30
62
|
const commit = (el) => {
|
|
31
63
|
const text = el.value.trim();
|
|
32
|
-
if (!text)
|
|
64
|
+
if (!text || readOnly)
|
|
33
65
|
return;
|
|
34
66
|
if (!allowDuplicates && chips.includes(text)) {
|
|
35
67
|
// Duplikat zostaje w polu (do poprawy), a czytnik słyszy, dlaczego nic nie przybyło.
|
|
36
68
|
setAnnouncement(t('chipsInput.duplicate', { value: text }));
|
|
37
69
|
return;
|
|
38
70
|
}
|
|
39
|
-
|
|
71
|
+
change([...chips, text], { added: chips.length });
|
|
40
72
|
setAnnouncement(t('chipsInput.added', { value: text }));
|
|
41
73
|
el.value = '';
|
|
42
74
|
};
|
|
43
75
|
const removeAt = (index) => {
|
|
44
76
|
const removed = chips[index];
|
|
45
|
-
|
|
77
|
+
change(chips.filter((_, i) => i !== index), { removed: index });
|
|
46
78
|
if (removed !== undefined)
|
|
47
79
|
setAnnouncement(t('chipsInput.removed', { value: removed }));
|
|
48
80
|
onTouch?.();
|
|
49
81
|
};
|
|
50
82
|
const onKeyDown = (event) => {
|
|
51
83
|
const el = event.currentTarget;
|
|
84
|
+
// W trakcie kompozycji IME (CJK) Enter zatwierdza znak, nie tag.
|
|
85
|
+
if (readOnly || event.nativeEvent.isComposing)
|
|
86
|
+
return;
|
|
52
87
|
if (event.key === 'Enter' || event.key === ',') {
|
|
53
88
|
event.preventDefault();
|
|
54
89
|
commit(el);
|
|
55
90
|
}
|
|
56
91
|
else if (event.key === 'Backspace' && el.value === '' && chips.length) {
|
|
57
|
-
// Backspace w pustym polu zjada ostatni chip
|
|
92
|
+
// Backspace w pustym polu zjada ostatni chip - to samo, czego uczy każdy klient poczty.
|
|
58
93
|
removeAt(chips.length - 1);
|
|
59
94
|
}
|
|
60
95
|
};
|
|
@@ -62,9 +97,9 @@ export function KptChipsInput({ value, defaultValue = [], onValueChange, placeho
|
|
|
62
97
|
commit(event.currentTarget);
|
|
63
98
|
onTouch?.();
|
|
64
99
|
};
|
|
65
|
-
return (_jsx("div", { className: cn('kpt-chips-input-host', className), ...rest, children: _jsxs("div", { className: cn('kpt-chips-input', disabled && 'kpt-chips-input--disabled', showInvalid && 'kpt-chips-input--invalid'), children: [_jsx("span", { className: "kpt-chips-input__list", role: "list", children: chips.map((chip, index) => (_jsx("span", { className: "kpt-chips-input__item", role: "listitem", children: _jsx(KptChip, { variant: "primary", removable: !disabled, onRemove: () => {
|
|
100
|
+
return (_jsx("div", { className: cn('kpt-chips-input-host', className), "data-motion": motion, ...rest, children: _jsxs("div", { ref: boxRef, className: cn('kpt-chips-input', disabled && 'kpt-chips-input--disabled', showInvalid && 'kpt-chips-input--invalid'), children: [_jsx("span", { className: "kpt-chips-input__list", role: "list", children: chips.map((chip, index) => (_jsx("span", { className: "kpt-chips-input__item", role: "listitem", children: _jsx(KptChip, { variant: "primary", removable: !disabled && !readOnly, onRemove: () => {
|
|
66
101
|
removeAt(index);
|
|
67
|
-
// Przycisk usuwania znika razem z tagiem
|
|
102
|
+
// Przycisk usuwania znika razem z tagiem - fokus wraca do pola, nie na <body>.
|
|
68
103
|
inputRef.current?.focus();
|
|
69
|
-
}, children: chip }) }, index))) }), _jsx("input", { ref: inputRef, className: "kpt-chips-input__field", id: field.id, "aria-label": ariaLabel ?? undefined, "aria-required": required || undefined, "aria-invalid": showInvalid || undefined, "aria-describedby": field.describedBy, type: "text", placeholder: chips.length ? '' : (placeholder ?? t('chipsInput.placeholder')), disabled: disabled, onKeyDown: onKeyDown, onBlur: onBlur }), _jsx("span", { className: "kpt-chips-input__live", "aria-live": "polite", children: announcement })] }) }));
|
|
104
|
+
}, children: chip }) }, index))) }), _jsx("input", { ref: inputRef, className: "kpt-chips-input__field", id: field.id, "aria-label": ariaLabel ?? undefined, "aria-required": required || undefined, "aria-invalid": showInvalid || undefined, "aria-describedby": field.describedBy, type: "text", placeholder: chips.length ? '' : (placeholder ?? t('chipsInput.placeholder')), disabled: disabled, readOnly: readOnly, onKeyDown: onKeyDown, onBlur: onBlur }), _jsx("span", { className: "kpt-chips-input__live", "aria-live": "polite", children: announcement })] }) }));
|
|
70
105
|
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
# KptChipsInput (@konce-pt/react)
|
|
2
2
|
|
|
3
|
-
A tag field
|
|
3
|
+
A tag field - add with Enter or a comma, remove with Backspace or x.
|
|
4
4
|
Import: `import { KptChipsInput } from '@konce-pt/react';`
|
|
5
5
|
|
|
6
6
|
## DOM
|
|
7
7
|
<div class="kpt-chips-input-host">
|
|
8
8
|
<div class="kpt-chips-input">
|
|
9
|
-
|
|
9
|
+
...KptChip per tag...
|
|
10
10
|
<input class="kpt-chips-input__field" type="text">
|
|
11
11
|
</div>
|
|
12
12
|
</div>
|
|
13
13
|
|
|
14
14
|
## Props
|
|
15
|
-
- `value` / `defaultValue` / `onValueChange`
|
|
16
|
-
- `placeholder`: string
|
|
15
|
+
- `value` / `defaultValue` / `onValueChange` - `string[]`
|
|
16
|
+
- `placeholder`: string - omitted falls back to `chipsInput.placeholder`
|
|
17
17
|
- `allowDuplicates`: boolean (default false)
|
|
18
18
|
- `disabled`, `invalid`, `touched`, `onTouch()`
|
|
19
|
-
- `locale`, `dictionary`
|
|
19
|
+
- `locale`, `dictionary` - i18n overrides for this component only
|
|
20
20
|
|
|
21
21
|
## The buffer is not state
|
|
22
22
|
The text being typed lives in the DOM, not in React state: the component's value is the list of
|
|
@@ -24,19 +24,19 @@ committed tags, and the typing buffer is the field's own business. Every keystro
|
|
|
24
24
|
not re-render the chips.
|
|
25
25
|
|
|
26
26
|
## Keyboard
|
|
27
|
-
Enter and a comma commit the tag. Backspace in an empty field eats the last chip
|
|
27
|
+
Enter and a comma commit the tag. Backspace in an empty field eats the last chip - the behaviour
|
|
28
28
|
every mail client teaches. Blur commits whatever is left in the field, so a half-typed tag is not
|
|
29
29
|
lost by clicking away.
|
|
30
30
|
|
|
31
31
|
## Examples
|
|
32
|
-
<KptChipsInput value={tags} onValueChange={setTags} placeholder="Add a tag
|
|
32
|
+
<KptChipsInput value={tags} onValueChange={setTags} placeholder="Add a tag..." />
|
|
33
33
|
<KptChipsInput value={tags} onValueChange={setTags} allowDuplicates />
|
|
34
34
|
|
|
35
35
|
## Screen reader and keyboard
|
|
36
36
|
The tags are a list (`role="list"`/`listitem`), so a screen reader hears how many there are. Adding,
|
|
37
37
|
removing (also with `Backspace`) and a rejected duplicate are announced by a polite live region
|
|
38
38
|
(`chipsInput.added`/`removed`/`duplicate`); a duplicate stays in the field to be corrected instead
|
|
39
|
-
of vanishing. After removing a tag with its
|
|
39
|
+
of vanishing. After removing a tag with its `x`, focus returns to the text field.
|
|
40
40
|
|
|
41
41
|
## Label and description
|
|
42
42
|
`id` goes to the native field, not the host; without one it comes from `KptFormField` or is
|
|
@@ -44,9 +44,19 @@ generated. Inside `KptFormField` the wrapper's `label[for]` points at it and the
|
|
|
44
44
|
added to `aria-describedby` (merged with your own). Without a wrapper, name it with `ariaLabel`.
|
|
45
45
|
New: `id`, `ariaLabel`, `required` and `aria-invalid` on the text field.
|
|
46
46
|
|
|
47
|
+
## Motion
|
|
48
|
+
An added tag pops in (grows from a smaller size and sharpens out of a blur); a removed one - by its "x"
|
|
49
|
+
or by `Backspace` - fades and shrinks in place while the following tags and the text field slide over on
|
|
50
|
+
a spring. The value changes at once; the motion only illustrates it. Follows `enter` from `KptMotionProvider`
|
|
51
|
+
(`spring` / `fade` - only fades, the neighbours slide without the spring / `none`); `enabled: false`
|
|
52
|
+
and the system "reduce motion" setting always win.
|
|
53
|
+
|
|
47
54
|
## Tokens
|
|
48
55
|
`--kpt-form-field-{bg,border,border-focus,border-error,radius}` plus the chip tokens.
|
|
49
56
|
|
|
50
57
|
## Accessibility
|
|
51
58
|
Each chip is a `KptChip` with a labelled remove button, and the field itself is a native input, so
|
|
52
59
|
tags are reachable and removable from the keyboard alone.
|
|
60
|
+
|
|
61
|
+
## Read-only and required
|
|
62
|
+
`readOnly` shows the tags without the remove buttons and ignores Enter, comma and Backspace. Enter during IME composition (CJK) confirms the character, not a tag. A repeated message (a second rejected duplicate) is announced again.
|
package/dist/clock/clock.d.ts
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import { type ComponentPropsWithRef } from 'react';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import { type KptI18nOverrides } from '../i18n/i18n-context.tsx';
|
|
3
|
+
export interface KptClockProps extends Omit<ComponentPropsWithRef<'div'>, 'onChange'>, KptI18nOverrides {
|
|
4
|
+
/** Godzina jako 'HH:mm' - zawsze 24h, niezależnie od `hourFormat`. */
|
|
4
5
|
value?: string;
|
|
5
6
|
onValueChange?: (value: string) => void;
|
|
6
7
|
hourFormat?: 12 | 24;
|
|
7
8
|
minuteStep?: number;
|
|
8
9
|
}
|
|
9
10
|
/**
|
|
10
|
-
* Tarcza zegara
|
|
11
|
-
* wewnętrzny pierścień 13
|
|
12
|
-
* i `KptDateRange`.
|
|
11
|
+
* Tarcza zegara - dwa etapy: godziny -> minuty, klikiem albo przeciąganiem. W trybie 24h dochodzi
|
|
12
|
+
* wewnętrzny pierścień 13-00; w 12h przełącznik AM/PM z etykietami pory dnia z `Intl`. Używana
|
|
13
|
+
* przez `KptDatepicker` i `KptDateRange`.
|
|
14
|
+
*
|
|
15
|
+
* Klawiatura: segmenty godzin i minut to `role="spinbutton"` - `ArrowUp`/`ArrowDown` o jeden krok (minuty
|
|
16
|
+
* o `minuteStep`), `PageUp`/`PageDown` o pięć, `Home`/`End` do granic. Tak da się ustawić każdą
|
|
17
|
+
* minutę, także spoza znaczników tarczy co pięć.
|
|
13
18
|
*
|
|
14
19
|
* @example
|
|
15
20
|
* <KptClock value={time} onValueChange={setTime} hourFormat={12} minuteStep={5} />
|
|
16
21
|
*/
|
|
17
|
-
export declare function KptClock({ value, onValueChange, hourFormat, minuteStep, className, ...rest }: Readonly<KptClockProps>): import("react").JSX.Element;
|
|
22
|
+
export declare function KptClock({ value, onValueChange, hourFormat, minuteStep, locale, dictionary, className, ...rest }: Readonly<KptClockProps>): import("react").JSX.Element;
|