@konce-pt/react 0.12.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +122 -64
- package/dist/accordion/accordion.d.ts +14 -6
- package/dist/accordion/accordion.js +14 -7
- package/dist/accordion/llms.txt +22 -10
- package/dist/alert/alert.d.ts +2 -2
- package/dist/alert/alert.js +2 -2
- package/dist/alert/llms.txt +10 -10
- package/dist/app-shell/app-shell.d.ts +14 -14
- package/dist/app-shell/app-shell.js +11 -11
- package/dist/app-shell/llms.txt +13 -13
- package/dist/auth/auth-types.d.ts +6 -6
- package/dist/auth/auth.d.ts +2 -2
- package/dist/auth/auth.js +7 -7
- package/dist/auth/llms.txt +9 -9
- package/dist/autocomplete/autocomplete.d.ts +19 -6
- package/dist/autocomplete/autocomplete.js +23 -10
- package/dist/autocomplete/llms.txt +16 -5
- package/dist/avatar/avatar.d.ts +6 -6
- package/dist/avatar/avatar.js +5 -5
- package/dist/avatar/llms.txt +10 -10
- package/dist/avatar-group/avatar-group.d.ts +4 -4
- package/dist/avatar-group/avatar-group.js +3 -3
- package/dist/avatar-group/llms.txt +8 -8
- package/dist/backdrop/backdrop.d.ts +7 -7
- package/dist/backdrop/backdrop.js +16 -16
- package/dist/backdrop/llms.txt +27 -27
- package/dist/badge/badge.d.ts +3 -3
- package/dist/badge/badge.js +1 -1
- package/dist/badge/llms.txt +11 -11
- package/dist/bottom-sheet/bottom-sheet.d.ts +4 -4
- package/dist/bottom-sheet/bottom-sheet.js +2 -2
- package/dist/bottom-sheet/llms.txt +9 -9
- package/dist/breadcrumb/breadcrumb.d.ts +2 -2
- package/dist/breadcrumb/breadcrumb.js +3 -3
- package/dist/breadcrumb/llms.txt +3 -3
- package/dist/button/button.d.ts +3 -3
- package/dist/button/button.js +8 -8
- package/dist/button/llms.txt +27 -19
- package/dist/button-group/button-group.d.ts +9 -9
- package/dist/button-group/button-group.js +30 -8
- package/dist/button-group/llms.txt +20 -14
- package/dist/card/card.d.ts +8 -8
- package/dist/card/card.js +6 -6
- package/dist/card/llms.txt +20 -20
- package/dist/carousel/carousel.d.ts +6 -6
- package/dist/carousel/carousel.js +4 -4
- package/dist/carousel/llms.txt +10 -10
- package/dist/charts/chart-legend.d.ts +3 -3
- package/dist/charts/chart-legend.js +1 -1
- package/dist/charts/chart-tooltip.d.ts +3 -3
- package/dist/charts/chart-tooltip.js +1 -1
- package/dist/charts/chart.d.ts +1 -1
- package/dist/charts/chart.js +8 -8
- package/dist/charts/llms.txt +6 -6
- package/dist/charts-entry/public-api.js +2 -2
- package/dist/chat/chat.d.ts +17 -10
- package/dist/chat/chat.js +42 -18
- package/dist/chat/llms.txt +32 -17
- package/dist/chat-composer/chat-composer.d.ts +17 -7
- package/dist/chat-composer/chat-composer.js +21 -8
- package/dist/chat-composer/llms.txt +20 -11
- package/dist/chat-dock/chat-dock.d.ts +11 -4
- package/dist/chat-dock/chat-dock.js +9 -6
- package/dist/chat-dock/llms.txt +15 -14
- package/dist/chat-entry/public-api.js +1 -1
- package/dist/chat-message/chat-message.d.ts +12 -5
- package/dist/chat-message/chat-message.js +17 -7
- package/dist/chat-message/llms.txt +16 -15
- package/dist/chat-typing/chat-typing.d.ts +2 -2
- package/dist/chat-typing/chat-typing.js +3 -3
- package/dist/chat-typing/llms.txt +6 -6
- package/dist/checkbox/checkbox.d.ts +13 -6
- package/dist/checkbox/checkbox.js +26 -7
- package/dist/checkbox/llms.txt +24 -12
- package/dist/chip/chip.d.ts +4 -4
- package/dist/chip/chip.js +2 -2
- package/dist/chip/llms.txt +11 -11
- package/dist/chips-input/chips-input.d.ts +4 -4
- package/dist/chips-input/chips-input.js +35 -9
- package/dist/chips-input/llms.txt +15 -8
- package/dist/clock/clock.d.ts +4 -4
- package/dist/clock/clock.js +7 -7
- package/dist/clock/llms.txt +8 -8
- package/dist/color-picker/color-picker.d.ts +6 -6
- package/dist/color-picker/color-picker.js +3 -3
- package/dist/color-picker/llms.txt +5 -5
- package/dist/confirm/confirm-container.d.ts +3 -3
- package/dist/confirm/confirm-container.js +5 -5
- package/dist/confirm/confirm-store.d.ts +4 -4
- package/dist/confirm/confirm-store.js +7 -7
- package/dist/confirm/llms.txt +6 -6
- package/dist/context-menu/context-menu.d.ts +1 -1
- package/dist/context-menu/context-menu.js +5 -5
- package/dist/context-menu/llms.txt +7 -7
- package/dist/data-table/data-table-types.d.ts +5 -5
- package/dist/data-table/data-table.d.ts +29 -8
- package/dist/data-table/data-table.js +340 -95
- package/dist/data-table/export-csv.d.ts +3 -3
- package/dist/data-table/export-csv.js +4 -4
- package/dist/data-table/llms.txt +127 -94
- package/dist/data-view/data-view.d.ts +13 -5
- package/dist/data-view/data-view.js +67 -6
- package/dist/data-view/llms.txt +29 -10
- package/dist/date-range/date-range.d.ts +9 -9
- package/dist/date-range/date-range.js +24 -24
- package/dist/date-range/llms.txt +20 -20
- package/dist/datepicker/datepicker.d.ts +10 -10
- package/dist/datepicker/datepicker.js +29 -29
- package/dist/datepicker/llms.txt +24 -24
- package/dist/dialog/dialog.d.ts +12 -7
- package/dist/dialog/dialog.js +4 -4
- package/dist/dialog/llms.txt +14 -11
- package/dist/divider/divider.d.ts +1 -1
- package/dist/divider/llms.txt +4 -4
- package/dist/drawer/drawer.d.ts +5 -5
- package/dist/drawer/drawer.js +2 -2
- package/dist/drawer/llms.txt +11 -11
- package/dist/empty/empty.d.ts +2 -2
- package/dist/empty/empty.js +1 -1
- package/dist/empty/llms.txt +9 -9
- package/dist/fab/fab.d.ts +1 -1
- package/dist/fab/fab.js +1 -1
- package/dist/fab/llms.txt +10 -6
- package/dist/fieldset/fieldset.d.ts +18 -4
- package/dist/fieldset/fieldset.js +9 -6
- package/dist/fieldset/llms.txt +26 -9
- package/dist/file-upload/file-upload.d.ts +3 -3
- package/dist/file-upload/file-upload.js +7 -7
- package/dist/file-upload/llms.txt +7 -7
- package/dist/form-field/form-field-context.d.ts +4 -4
- package/dist/form-field/form-field.d.ts +12 -4
- package/dist/form-field/form-field.js +26 -6
- package/dist/form-field/llms.txt +25 -11
- package/dist/galleria/galleria.d.ts +3 -3
- package/dist/galleria/galleria.js +5 -5
- package/dist/galleria/llms.txt +7 -7
- package/dist/grid/col.d.ts +4 -4
- package/dist/grid/col.js +2 -2
- package/dist/grid/flex.d.ts +3 -3
- package/dist/grid/flex.js +1 -1
- package/dist/grid/grid.d.ts +7 -7
- package/dist/grid/grid.js +3 -3
- package/dist/grid/layout.d.ts +2 -2
- package/dist/grid/layout.js +2 -2
- package/dist/grid/llms.txt +15 -15
- package/dist/grid-entry/public-api.js +1 -1
- package/dist/i18n/i18n-context.d.ts +3 -3
- package/dist/i18n/i18n-context.js +7 -7
- package/dist/icon/icon-registry.d.ts +3 -3
- package/dist/icon/icon-registry.js +3 -3
- package/dist/icon/icon.d.ts +4 -4
- package/dist/icon/icon.js +6 -6
- package/dist/icon/llms.txt +13 -13
- package/dist/icon-button/icon-button.d.ts +2 -2
- package/dist/icon-button/icon-button.js +1 -1
- package/dist/icon-button/llms.txt +9 -5
- package/dist/icons-entry/public-api.d.ts +2 -2
- package/dist/icons-entry/public-api.js +3 -3
- package/dist/image/image.js +1 -1
- package/dist/image/llms.txt +13 -13
- package/dist/input/input.d.ts +18 -5
- package/dist/input/input.js +21 -6
- package/dist/input/llms.txt +25 -11
- package/dist/input-mask/input-mask.d.ts +1 -1
- package/dist/input-mask/input-mask.js +2 -2
- package/dist/input-mask/llms.txt +5 -5
- package/dist/input-number/input-number.d.ts +9 -9
- package/dist/input-number/input-number.js +11 -11
- package/dist/input-number/llms.txt +14 -14
- package/dist/input-otp/input-otp.d.ts +6 -6
- package/dist/input-otp/input-otp.js +10 -10
- package/dist/input-otp/llms.txt +9 -9
- package/dist/internal/calendar-focus.d.ts +1 -1
- package/dist/internal/calendar-focus.js +3 -3
- package/dist/internal/cn.d.ts +1 -1
- package/dist/internal/mask.d.ts +2 -2
- package/dist/internal/mask.js +4 -4
- package/dist/internal/option-key.d.ts +2 -2
- package/dist/internal/option-key.js +2 -2
- package/dist/internal/option-nav.d.ts +4 -4
- package/dist/internal/option-nav.js +5 -5
- package/dist/internal/overlay-container.js +1 -1
- package/dist/internal/overlay.d.ts +3 -3
- package/dist/internal/overlay.js +8 -8
- package/dist/internal/password-strength.d.ts +2 -2
- package/dist/internal/password-strength.js +6 -6
- package/dist/internal/roving.d.ts +2 -2
- package/dist/internal/roving.js +3 -3
- package/dist/internal/scroll-lock.d.ts +1 -1
- package/dist/internal/scroll-lock.js +2 -2
- package/dist/internal/slot-children.d.ts +3 -3
- package/dist/internal/slot-children.js +4 -4
- package/dist/internal/slot.d.ts +3 -3
- package/dist/internal/slot.js +2 -2
- package/dist/internal/step.d.ts +3 -3
- package/dist/internal/step.js +4 -4
- package/dist/internal/tween.d.ts +5 -5
- package/dist/internal/tween.js +5 -5
- package/dist/internal/types.d.ts +2 -2
- package/dist/internal/use-breakpoint.d.ts +2 -2
- package/dist/internal/use-breakpoint.js +4 -4
- package/dist/internal/use-controllable-state.d.ts +1 -1
- package/dist/internal/use-controllable-state.js +3 -3
- package/dist/internal/use-id.d.ts +2 -2
- package/dist/internal/use-id.js +2 -2
- package/dist/internal/use-modal-focus.d.ts +1 -1
- package/dist/internal/use-modal-focus.js +3 -3
- package/dist/knob/knob.d.ts +4 -4
- package/dist/knob/knob.js +14 -10
- package/dist/knob/llms.txt +17 -12
- package/dist/listbox/listbox.d.ts +6 -6
- package/dist/listbox/listbox.js +9 -9
- package/dist/listbox/llms.txt +10 -10
- package/dist/loader/llms.txt +56 -0
- package/dist/loader/loader.d.ts +49 -0
- package/dist/loader/loader.js +68 -0
- package/dist/map/llms.txt +25 -22
- package/dist/map/map-create-dialog.d.ts +4 -4
- package/dist/map/map-create-dialog.js +10 -10
- package/dist/map/map-hours-field.d.ts +4 -4
- package/dist/map/map-hours-field.js +7 -7
- package/dist/map/map-image-field.d.ts +2 -2
- package/dist/map/map-image-field.js +4 -4
- package/dist/map/map-legend.d.ts +4 -4
- package/dist/map/map-legend.js +2 -2
- package/dist/map/map-poi-card.d.ts +3 -3
- package/dist/map/map-poi-card.js +9 -9
- package/dist/map/map-search.d.ts +17 -6
- package/dist/map/map-search.js +21 -18
- package/dist/map/map.d.ts +21 -14
- package/dist/map/map.js +30 -29
- package/dist/map/ports.d.ts +9 -9
- package/dist/map/ports.js +6 -6
- package/dist/map-entry/public-api.js +2 -2
- package/dist/megamenu/llms.txt +9 -9
- package/dist/megamenu/megamenu.d.ts +6 -6
- package/dist/megamenu/megamenu.js +10 -10
- package/dist/mention/llms.txt +15 -15
- package/dist/mention/mention.d.ts +5 -5
- package/dist/mention/mention.js +2 -2
- package/dist/mention/mentions.d.ts +1 -1
- package/dist/mention/mentions.js +1 -1
- package/dist/menu/llms.txt +12 -12
- package/dist/menu/menu-item.d.ts +4 -4
- package/dist/menu/menu-keys.d.ts +2 -2
- package/dist/menu/menu-keys.js +5 -5
- package/dist/menu/menu.d.ts +2 -2
- package/dist/menu/menu.js +6 -6
- package/dist/menubar/llms.txt +10 -10
- package/dist/menubar/menubar.d.ts +5 -5
- package/dist/menubar/menubar.js +10 -10
- package/dist/meter-group/llms.txt +12 -12
- package/dist/meter-group/meter-group.d.ts +2 -2
- package/dist/meter-group/meter-group.js +1 -1
- package/dist/motion/motion-context.d.ts +22 -0
- package/dist/motion/motion-context.js +28 -0
- package/dist/order-list/llms.txt +22 -10
- package/dist/order-list/order-list.d.ts +12 -4
- package/dist/order-list/order-list.js +104 -21
- package/dist/paginator/llms.txt +8 -8
- package/dist/paginator/paginator.js +1 -1
- package/dist/panel/llms.txt +25 -13
- package/dist/panel/panel.d.ts +11 -3
- package/dist/panel/panel.js +7 -4
- package/dist/password/llms.txt +16 -8
- package/dist/password/password.d.ts +2 -2
- package/dist/password/password.js +24 -3
- package/dist/peek/llms.txt +10 -10
- package/dist/peek/peek.d.ts +6 -6
- package/dist/peek/peek.js +7 -7
- package/dist/pick-list/llms.txt +33 -13
- package/dist/pick-list/pick-list.d.ts +12 -4
- package/dist/pick-list/pick-list.js +111 -23
- package/dist/popover/llms.txt +11 -11
- package/dist/popover/popover.d.ts +4 -4
- package/dist/popover/popover.js +5 -5
- package/dist/progress/llms.txt +17 -17
- package/dist/progress/progress.d.ts +7 -7
- package/dist/progress/progress.js +6 -6
- package/dist/public-api.d.ts +15 -3
- package/dist/public-api.js +13 -7
- package/dist/radio-group/llms.txt +13 -6
- package/dist/radio-group/radio-group.d.ts +11 -4
- package/dist/radio-group/radio-group.js +15 -7
- package/dist/rating/llms.txt +20 -13
- package/dist/rating/rating-pointer.d.ts +16 -0
- package/dist/rating/rating-pointer.js +26 -0
- package/dist/rating/rating.d.ts +6 -6
- package/dist/rating/rating.js +76 -12
- package/dist/rich-text/lists.d.ts +2 -2
- package/dist/rich-text/lists.js +7 -7
- package/dist/rich-text/llms.txt +26 -17
- package/dist/rich-text/rich-text.d.ts +12 -7
- package/dist/rich-text/rich-text.js +78 -54
- package/dist/rich-text/sanitize.d.ts +3 -3
- package/dist/rich-text/sanitize.js +12 -12
- package/dist/rich-text/tables.d.ts +3 -3
- package/dist/rich-text/tables.js +3 -3
- package/dist/roadmap/llms.txt +15 -15
- package/dist/roadmap/roadmap.d.ts +6 -6
- package/dist/roadmap/roadmap.js +19 -19
- package/dist/roadmap-entry/public-api.js +2 -2
- package/dist/scroll-top/llms.txt +6 -6
- package/dist/scroll-top/scroll-top.d.ts +1 -1
- package/dist/scroll-top/scroll-top.js +1 -1
- package/dist/select/llms.txt +19 -12
- package/dist/select/select.d.ts +8 -8
- package/dist/select/select.js +47 -21
- package/dist/shared/types.d.ts +5 -5
- package/dist/shared/types.js +1 -1
- package/dist/sidenav/llms.txt +9 -9
- package/dist/sidenav/sidenav.d.ts +1 -1
- package/dist/sidenav/sidenav.js +1 -1
- package/dist/skeleton/llms.txt +3 -3
- package/dist/skeleton/skeleton.d.ts +1 -1
- package/dist/skeleton/skeleton.js +1 -1
- package/dist/slider/llms.txt +32 -13
- package/dist/slider/slider-drag.d.ts +26 -0
- package/dist/slider/slider-drag.js +79 -0
- package/dist/slider/slider.d.ts +6 -5
- package/dist/slider/slider.js +27 -8
- package/dist/speech/llms.txt +97 -0
- package/dist/speech/speech-button.d.ts +44 -0
- package/dist/speech/speech-button.js +86 -0
- package/dist/speech/speech-wave.d.ts +19 -0
- package/dist/speech/speech-wave.js +16 -0
- package/dist/speech/use-speech-recognition.d.ts +81 -0
- package/dist/speech/use-speech-recognition.js +179 -0
- package/dist/speed-dial/llms.txt +14 -8
- package/dist/speed-dial/speed-dial.d.ts +1 -1
- package/dist/speed-dial/speed-dial.js +1 -1
- package/dist/spinner/llms.txt +7 -7
- package/dist/spinner/spinner.d.ts +1 -1
- package/dist/spinner/spinner.js +1 -1
- package/dist/split-button/llms.txt +21 -15
- package/dist/split-button/split-button.d.ts +2 -2
- package/dist/split-button/split-button.js +4 -4
- package/dist/splitter/llms.txt +11 -11
- package/dist/splitter/splitter.d.ts +3 -3
- package/dist/splitter/splitter.js +5 -5
- package/dist/stepper/llms.txt +33 -14
- package/dist/stepper/stepper.d.ts +6 -6
- package/dist/stepper/stepper.js +53 -10
- package/dist/switch/llms.txt +12 -5
- package/dist/switch/switch.d.ts +10 -3
- package/dist/switch/switch.js +12 -5
- package/dist/switch-group/llms.txt +9 -9
- package/dist/switch-group/switch-group.d.ts +4 -4
- package/dist/switch-group/switch-group.js +4 -4
- package/dist/tabs/llms.txt +10 -10
- package/dist/tabs/tabs.d.ts +5 -5
- package/dist/tabs/tabs.js +8 -8
- package/dist/textarea/llms.txt +23 -12
- package/dist/textarea/textarea.d.ts +19 -6
- package/dist/textarea/textarea.js +21 -7
- package/dist/timeline/llms.txt +4 -4
- package/dist/timeline/timeline.d.ts +1 -1
- package/dist/timeline/timeline.js +1 -1
- package/dist/toast/llms.txt +47 -17
- package/dist/toast/toast-container.d.ts +9 -3
- package/dist/toast/toast-container.js +17 -9
- package/dist/toast/toast-store.d.ts +40 -4
- package/dist/toast/toast-store.js +36 -1
- package/dist/toolbar/llms.txt +7 -7
- package/dist/toolbar/toolbar.d.ts +3 -3
- package/dist/toolbar/toolbar.js +2 -2
- package/dist/tooltip/llms.txt +10 -10
- package/dist/tooltip/tooltip.d.ts +3 -3
- package/dist/tooltip/tooltip.js +18 -18
- package/dist/tree/llms.txt +25 -12
- package/dist/tree/tree-keys.d.ts +5 -5
- package/dist/tree/tree-keys.js +7 -7
- package/dist/tree/tree.d.ts +14 -7
- package/dist/tree/tree.js +53 -18
- package/dist/update/llms.txt +54 -0
- package/dist/update/update.d.ts +49 -0
- package/dist/update/update.js +82 -0
- package/package.json +15 -13
|
@@ -7,41 +7,42 @@ Import: `import { KptChatMessage } from '@konce-pt/react/chat';`
|
|
|
7
7
|
## DOM
|
|
8
8
|
<div class="kpt-chat-message-host" role="article" aria-label="Anna, 09:22, Read">
|
|
9
9
|
<div class="kpt-chat-message__row" data-align="start">
|
|
10
|
-
<span class="kpt-chat-message__avatar"
|
|
10
|
+
<span class="kpt-chat-message__avatar">...KptAvatar...</span>
|
|
11
11
|
<div class="kpt-chat-message__stack">
|
|
12
12
|
<span class="kpt-chat-message__author">Anna Kowalska</span>
|
|
13
13
|
<div class="kpt-chat-message__bubble"
|
|
14
14
|
data-variant="neutral" data-align="start" data-position="last" data-tail>
|
|
15
|
-
<button class="kpt-chat-message__quote"
|
|
16
|
-
<p class="kpt-chat-message__text"
|
|
17
|
-
<ul class="kpt-chat-message__files"
|
|
18
|
-
<span class="kpt-chat-message__meta"><time>09:22</time
|
|
19
|
-
<ul class="kpt-chat-message__reactions"
|
|
15
|
+
<button class="kpt-chat-message__quote">...</button>
|
|
16
|
+
<p class="kpt-chat-message__text">...</p>
|
|
17
|
+
<ul class="kpt-chat-message__files">...</ul>
|
|
18
|
+
<span class="kpt-chat-message__meta"><time>09:22</time>...</span>
|
|
19
|
+
<ul class="kpt-chat-message__reactions">...</ul>
|
|
20
20
|
</div>
|
|
21
21
|
</div>
|
|
22
|
-
<span class="kpt-chat-message__actions"
|
|
22
|
+
<span class="kpt-chat-message__actions">...KptIconButton, .kpt-chat-message__picker...</span>
|
|
23
23
|
</div>
|
|
24
24
|
</div>
|
|
25
25
|
|
|
26
26
|
## Props
|
|
27
|
-
- `message`: `KptChatMessage`
|
|
27
|
+
- `message`: `KptChatMessage` - the whole object; the single props below win over it
|
|
28
28
|
- `author`, `text`, `time`, `status`, `attachments`, `reactions`, `replyTo`
|
|
29
29
|
- `align`: `'start' | 'end'`; `variant`: `'neutral' | 'primary' | 'solid' | 'ghost' | 'system'`
|
|
30
30
|
- `position`: `'single' | 'first' | 'middle' | 'last'`; `system`: boolean
|
|
31
31
|
- `showAuthor`, `showAvatar`, `showMeta` (default true), `tail` (default true), `actions`
|
|
32
|
-
- `reactionOptions`: `readonly KptChatReactionOption[]` (default `KPT_CHAT_REACTIONS`)
|
|
32
|
+
- `reactionOptions`: `readonly KptChatReactionOption[]` (default `KPT_CHAT_REACTIONS`) - the picker set
|
|
33
|
+
- `enterMotion`: `'spring' | 'fade' | 'none'` - how a new reaction and a status change appear (`KptChat` passes its own; see its doc)
|
|
33
34
|
- `onRetry`, `onReply`: `() => void`; `onReact`: `(emoji: string) => void`; `onQuoted`: `(quote) => void`
|
|
34
|
-
- `children`
|
|
35
|
+
- `children` - bubble content; it renders next to `text`, so the bubble takes anything
|
|
35
36
|
- `className`, `ref` and every other `<div>` prop go to the host
|
|
36
37
|
|
|
37
38
|
## The default variant follows the alignment
|
|
38
39
|
Your own message gets the full `solid`, someone else's gets `neutral`. The theme is monochrome, so
|
|
39
|
-
the difference between bubbles is lightness, not hue
|
|
40
|
+
the difference between bubbles is lightness, not hue - `--kpt-color-primary-subtle` has exactly the
|
|
40
41
|
lightness of `--kpt-color-muted`, which would make the two sides indistinguishable. For a quieter
|
|
41
42
|
list set `variant="primary"` by hand.
|
|
42
43
|
|
|
43
44
|
## Grouping is what the shape is made of
|
|
44
|
-
`position` decides which corner collapses and which bubble wears the tail
|
|
45
|
+
`position` decides which corner collapses and which bubble wears the tail - inside a group the
|
|
45
46
|
corner on the sender's side drops to `--kpt-radius-sm`. `KptChat` gets all of it from
|
|
46
47
|
`buildChatRows()`; set it by hand only when you build the list yourself. The tail is skipped for
|
|
47
48
|
`ghost` and `system`, which have no background to cut it out of.
|
|
@@ -49,7 +50,7 @@ corner on the sender's side drops to `--kpt-radius-sm`. `KptChat` gets all of it
|
|
|
49
50
|
## An unsent message must be able to say so
|
|
50
51
|
`status="failed"` outlines the bubble and puts a retry arrow **outside** it, in the action column
|
|
51
52
|
on the outer side of the list. `KptChat` also keeps the meta row visible on such a bubble even in
|
|
52
|
-
the middle of a group
|
|
53
|
+
the middle of a group - the arrow with nothing to explain it would be a mystery.
|
|
53
54
|
Statuses: `sending` (clock), `sent` (check), `delivered` (double check), `read` (the same icon in
|
|
54
55
|
the accent colour) and `failed`.
|
|
55
56
|
|
|
@@ -64,10 +65,10 @@ is formatted by `Intl` in the active locale.
|
|
|
64
65
|
|
|
65
66
|
## Tokens
|
|
66
67
|
`--kpt-color-muted` (incoming) / `--kpt-color-primary` + `--kpt-color-on-primary` (own),
|
|
67
|
-
failed `--kpt-color-danger-subtle` + `--kpt-color-danger-border`
|
|
68
|
+
failed `--kpt-color-danger-subtle` + `--kpt-color-danger-border` - the failed rule also resets the
|
|
68
69
|
text colour, or a white `solid` label would land on pale pink.
|
|
69
70
|
|
|
70
71
|
## Accessibility
|
|
71
|
-
The host is an `article` labelled with author, time and status
|
|
72
|
+
The host is an `article` labelled with author, time and status - content alone would say nothing
|
|
72
73
|
about who wrote it or whether it was sent. The status icon is `aria-hidden`; the meaning travels in
|
|
73
74
|
the label. A system notice is a `note`, never an `article`.
|
|
@@ -8,13 +8,13 @@ export interface KptChatTypingProps extends Omit<ComponentPropsWithRef<'div'>, '
|
|
|
8
8
|
label?: string;
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
|
-
* Wskaźnik pisania
|
|
11
|
+
* Wskaźnik pisania - trzy kropki i informacja, kto pisze.
|
|
12
12
|
*
|
|
13
13
|
* Pusta lista autorów nie renderuje niczego, więc można go trzymać w drzewie na stałe
|
|
14
14
|
* i sterować wyłącznie danymi.
|
|
15
15
|
*
|
|
16
16
|
* Element jest `role="status"` z `aria-live="polite"`: czytnik ogłasza wejście i zniknięcie
|
|
17
|
-
* wskaźnika, ale nie przerywa czytania wiadomości. Sama animacja kropek nic nie mówi
|
|
17
|
+
* wskaźnika, ale nie przerywa czytania wiadomości. Sama animacja kropek nic nie mówi -
|
|
18
18
|
* informację niesie etykieta.
|
|
19
19
|
*
|
|
20
20
|
* @example
|
|
@@ -3,13 +3,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { cn } from "../internal/cn.js";
|
|
4
4
|
import { useKptMessages } from "../i18n/i18n-context.js";
|
|
5
5
|
/**
|
|
6
|
-
* Wskaźnik pisania
|
|
6
|
+
* Wskaźnik pisania - trzy kropki i informacja, kto pisze.
|
|
7
7
|
*
|
|
8
8
|
* Pusta lista autorów nie renderuje niczego, więc można go trzymać w drzewie na stałe
|
|
9
9
|
* i sterować wyłącznie danymi.
|
|
10
10
|
*
|
|
11
11
|
* Element jest `role="status"` z `aria-live="polite"`: czytnik ogłasza wejście i zniknięcie
|
|
12
|
-
* wskaźnika, ale nie przerywa czytania wiadomości. Sama animacja kropek nic nie mówi
|
|
12
|
+
* wskaźnika, ale nie przerywa czytania wiadomości. Sama animacja kropek nic nie mówi -
|
|
13
13
|
* informację niesie etykieta.
|
|
14
14
|
*
|
|
15
15
|
* @example
|
|
@@ -20,7 +20,7 @@ export function KptChatTyping({ authors = [], label = '', locale, dictionary, cl
|
|
|
20
20
|
if (authors.length === 0 && !label)
|
|
21
21
|
return null;
|
|
22
22
|
/*
|
|
23
|
-
* Jedna osoba jest wymieniona z imienia, przy większej liczbie liczy się głowy
|
|
23
|
+
* Jedna osoba jest wymieniona z imienia, przy większej liczbie liczy się głowy -
|
|
24
24
|
* lista nazwisk rozjeżdża wiersz i i tak nikt jej nie czyta.
|
|
25
25
|
*/
|
|
26
26
|
const text = label ||
|
|
@@ -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, readOnly, onClick, 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;
|
|
@@ -4,20 +4,22 @@ import { useCallback, useEffect, useRef } from 'react';
|
|
|
4
4
|
import { composeRefs } from "../internal/compose-refs.js";
|
|
5
5
|
import { cn } from "../internal/cn.js";
|
|
6
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";
|
|
7
9
|
/**
|
|
8
10
|
* Pole wyboru (checkbox). Cały układ niesie `<label>`, więc kliknięcie w etykietę przełącza pole
|
|
9
|
-
* bez `htmlFor`
|
|
11
|
+
* bez `htmlFor` - natywny `<input>` w środku odpowiada za semantykę i klawiaturę.
|
|
10
12
|
*
|
|
11
13
|
* Działa kontrolowane (`checked` + `onCheckedChange`) i niekontrolowane (`defaultChecked`).
|
|
12
14
|
*
|
|
13
15
|
* `className` trafia na blok `.kpt-checkbox`, a pozostałe propsy (`name`, `value`, `ref`,
|
|
14
|
-
* handlery) na natywny `<input>`
|
|
16
|
+
* handlery) na natywny `<input>` - tam, gdzie oczekuje ich formularz.
|
|
15
17
|
*
|
|
16
18
|
* @example
|
|
17
19
|
* <KptCheckbox name="terms" label="Akceptuję regulamin" />
|
|
18
20
|
* <KptCheckbox checked={on} onCheckedChange={setOn} />
|
|
19
21
|
*/
|
|
20
|
-
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, 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 }) {
|
|
21
23
|
const inputRef = useRef(null);
|
|
22
24
|
useEffect(() => {
|
|
23
25
|
if (inputRef.current)
|
|
@@ -26,19 +28,36 @@ export function KptCheckbox({ label = '', required = false, invalid = false, tou
|
|
|
26
28
|
const field = useKptFieldA11y(id, 'kpt-checkbox');
|
|
27
29
|
const { className: hostClassName, ...hostRest } = hostProps ?? {};
|
|
28
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]);
|
|
29
44
|
const handleChange = useCallback((event) => {
|
|
30
45
|
onChange?.(event);
|
|
31
46
|
onCheckedChange?.(event.target.checked);
|
|
32
|
-
|
|
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]);
|
|
33
52
|
const handleBlur = useCallback((event) => {
|
|
34
53
|
onBlur?.(event);
|
|
35
54
|
onTouch?.();
|
|
36
55
|
}, [onBlur, onTouch]);
|
|
37
|
-
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-readonly": readOnly || undefined,
|
|
38
|
-
// Natywne `readonly` nie działa na polach wyboru
|
|
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.
|
|
39
58
|
onClick: (event) => {
|
|
40
59
|
if (readOnly)
|
|
41
60
|
event.preventDefault();
|
|
42
61
|
onClick?.(event);
|
|
43
|
-
}, "aria-invalid": ariaInvalid ?? (showInvalid || undefined), onChange: handleChange, onBlur: handleBlur, ...rest }), _jsxs("span", { 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" }) }), _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] }) }));
|
|
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] }) }));
|
|
44
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,14 +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.
|
|
51
63
|
|
|
52
64
|
## Read-only and required
|
|
53
|
-
`readOnly` keeps the box focusable but blocks the click and Space (`aria-readonly`)
|
|
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
|
@@ -5,12 +5,12 @@ import { useKptId } from "../internal/use-id.js";
|
|
|
5
5
|
import { KptIcon } from "../icon/icon.js";
|
|
6
6
|
import { useKptMessages } from "../i18n/i18n-context.js";
|
|
7
7
|
/**
|
|
8
|
-
* Chip / tag
|
|
8
|
+
* Chip / tag - etykieta, opcjonalnie usuwalna.
|
|
9
9
|
*
|
|
10
10
|
* @example
|
|
11
11
|
* <KptChip>Angular</KptChip>
|
|
12
12
|
* <KptChip variant="success" removable onRemove={remove}>UI</KptChip>
|
|
13
|
-
* <KptChip textTransform="capitalize">
|
|
13
|
+
* <KptChip textTransform="capitalize">nowość, zestaw startowy</KptChip>
|
|
14
14
|
*/
|
|
15
15
|
export function KptChip({ variant = 'neutral', textTransform = 'none', removable = false, disabled = false, onRemove, locale, dictionary, hostProps, className, children, ...rest }) {
|
|
16
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,27 +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
|
|
17
|
+
/** Tylko do odczytu - tagi widać, nie da się ich dodać ani usunąć. */
|
|
18
18
|
readOnly?: boolean;
|
|
19
19
|
invalid?: boolean;
|
|
20
20
|
touched?: boolean;
|
|
21
21
|
onTouch?: () => void;
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
|
-
* Pole tagów
|
|
24
|
+
* Pole tagów - dodawanie Enterem albo przecinkiem, usuwanie Backspace lub x.
|
|
25
25
|
*
|
|
26
26
|
* Tekst w trakcie pisania żyje w DOM, nie w stanie Reacta: wartością komponentu jest lista
|
|
27
27
|
* zatwierdzonych tagów, a bufor wpisywania to prywatna sprawa pola. Dzięki temu każde naciśnięcie
|
|
28
28
|
* klawisza nie przerysowuje listy chipów.
|
|
29
29
|
*
|
|
30
30
|
* @example
|
|
31
|
-
* <KptChipsInput value={tags} onValueChange={setTags} placeholder="Dodaj tag
|
|
31
|
+
* <KptChipsInput value={tags} onValueChange={setTags} placeholder="Dodaj tag..." />
|
|
32
32
|
*/
|
|
33
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,20 +1,22 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
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";
|
|
4
6
|
import { cn } from "../internal/cn.js";
|
|
5
7
|
import { useControllableState } from "../internal/use-controllable-state.js";
|
|
6
8
|
import { useKptMessages } from "../i18n/i18n-context.js";
|
|
7
9
|
import { KptChip } from "../chip/chip.js";
|
|
8
10
|
import { useKptFieldA11y } from "../form-field/form-field-context.js";
|
|
9
11
|
/**
|
|
10
|
-
* Pole tagów
|
|
12
|
+
* Pole tagów - dodawanie Enterem albo przecinkiem, usuwanie Backspace lub x.
|
|
11
13
|
*
|
|
12
14
|
* Tekst w trakcie pisania żyje w DOM, nie w stanie Reacta: wartością komponentu jest lista
|
|
13
15
|
* zatwierdzonych tagów, a bufor wpisywania to prywatna sprawa pola. Dzięki temu każde naciśnięcie
|
|
14
16
|
* klawisza nie przerysowuje listy chipów.
|
|
15
17
|
*
|
|
16
18
|
* @example
|
|
17
|
-
* <KptChipsInput value={tags} onValueChange={setTags} placeholder="Dodaj tag
|
|
19
|
+
* <KptChipsInput value={tags} onValueChange={setTags} placeholder="Dodaj tag..." />
|
|
18
20
|
*/
|
|
19
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 }) {
|
|
20
22
|
const { t } = useKptMessages({ locale, dictionary });
|
|
@@ -26,11 +28,35 @@ export function KptChipsInput({ value, defaultValue = [], onValueChange, placeho
|
|
|
26
28
|
onChange: onValueChange,
|
|
27
29
|
});
|
|
28
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
|
+
};
|
|
29
55
|
/** Komunikat regionu `polite`: dodanie, usunięcie albo odrzucony duplikat. */
|
|
30
56
|
const [announcement, setAnnouncementState] = useState('');
|
|
31
57
|
/**
|
|
32
58
|
* Ten sam komunikat dwa razy z rzędu (drugi odrzucony duplikat) nie zmieniłby treści regionu
|
|
33
|
-
* i czytnik by go nie ogłosił
|
|
59
|
+
* i czytnik by go nie ogłosił - doklejamy niewidoczną spację, żeby tekst się różnił.
|
|
34
60
|
*/
|
|
35
61
|
const setAnnouncement = (message) => setAnnouncementState((current) => (current === message ? `${message}\u00A0` : message));
|
|
36
62
|
const commit = (el) => {
|
|
@@ -42,13 +68,13 @@ export function KptChipsInput({ value, defaultValue = [], onValueChange, placeho
|
|
|
42
68
|
setAnnouncement(t('chipsInput.duplicate', { value: text }));
|
|
43
69
|
return;
|
|
44
70
|
}
|
|
45
|
-
|
|
71
|
+
change([...chips, text], { added: chips.length });
|
|
46
72
|
setAnnouncement(t('chipsInput.added', { value: text }));
|
|
47
73
|
el.value = '';
|
|
48
74
|
};
|
|
49
75
|
const removeAt = (index) => {
|
|
50
76
|
const removed = chips[index];
|
|
51
|
-
|
|
77
|
+
change(chips.filter((_, i) => i !== index), { removed: index });
|
|
52
78
|
if (removed !== undefined)
|
|
53
79
|
setAnnouncement(t('chipsInput.removed', { value: removed }));
|
|
54
80
|
onTouch?.();
|
|
@@ -63,7 +89,7 @@ export function KptChipsInput({ value, defaultValue = [], onValueChange, placeho
|
|
|
63
89
|
commit(el);
|
|
64
90
|
}
|
|
65
91
|
else if (event.key === 'Backspace' && el.value === '' && chips.length) {
|
|
66
|
-
// Backspace w pustym polu zjada ostatni chip
|
|
92
|
+
// Backspace w pustym polu zjada ostatni chip - to samo, czego uczy każdy klient poczty.
|
|
67
93
|
removeAt(chips.length - 1);
|
|
68
94
|
}
|
|
69
95
|
};
|
|
@@ -71,9 +97,9 @@ export function KptChipsInput({ value, defaultValue = [], onValueChange, placeho
|
|
|
71
97
|
commit(event.currentTarget);
|
|
72
98
|
onTouch?.();
|
|
73
99
|
};
|
|
74
|
-
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 && !readOnly, 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: () => {
|
|
75
101
|
removeAt(index);
|
|
76
|
-
// Przycisk usuwania znika razem z tagiem
|
|
102
|
+
// Przycisk usuwania znika razem z tagiem - fokus wraca do pola, nie na <body>.
|
|
77
103
|
inputRef.current?.focus();
|
|
78
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 })] }) }));
|
|
79
105
|
}
|