@konce-pt/react 0.12.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +122 -64
- package/dist/accordion/accordion.d.ts +14 -6
- package/dist/accordion/accordion.js +14 -7
- package/dist/accordion/llms.txt +22 -10
- package/dist/alert/alert.d.ts +2 -2
- package/dist/alert/alert.js +2 -2
- package/dist/alert/llms.txt +10 -10
- package/dist/app-shell/app-shell.d.ts +14 -14
- package/dist/app-shell/app-shell.js +11 -11
- package/dist/app-shell/llms.txt +13 -13
- package/dist/auth/auth-types.d.ts +6 -6
- package/dist/auth/auth.d.ts +2 -2
- package/dist/auth/auth.js +7 -7
- package/dist/auth/llms.txt +9 -9
- package/dist/autocomplete/autocomplete.d.ts +19 -6
- package/dist/autocomplete/autocomplete.js +23 -10
- package/dist/autocomplete/llms.txt +16 -5
- package/dist/avatar/avatar.d.ts +6 -6
- package/dist/avatar/avatar.js +5 -5
- package/dist/avatar/llms.txt +10 -10
- package/dist/avatar-group/avatar-group.d.ts +4 -4
- package/dist/avatar-group/avatar-group.js +3 -3
- package/dist/avatar-group/llms.txt +8 -8
- package/dist/backdrop/backdrop.d.ts +7 -7
- package/dist/backdrop/backdrop.js +16 -16
- package/dist/backdrop/llms.txt +27 -27
- package/dist/badge/badge.d.ts +3 -3
- package/dist/badge/badge.js +1 -1
- package/dist/badge/llms.txt +11 -11
- package/dist/bottom-sheet/bottom-sheet.d.ts +4 -4
- package/dist/bottom-sheet/bottom-sheet.js +2 -2
- package/dist/bottom-sheet/llms.txt +9 -9
- package/dist/breadcrumb/breadcrumb.d.ts +2 -2
- package/dist/breadcrumb/breadcrumb.js +3 -3
- package/dist/breadcrumb/llms.txt +3 -3
- package/dist/button/button.d.ts +3 -3
- package/dist/button/button.js +8 -8
- package/dist/button/llms.txt +27 -19
- package/dist/button-group/button-group.d.ts +9 -9
- package/dist/button-group/button-group.js +30 -8
- package/dist/button-group/llms.txt +20 -14
- package/dist/card/card.d.ts +8 -8
- package/dist/card/card.js +6 -6
- package/dist/card/llms.txt +20 -20
- package/dist/carousel/carousel.d.ts +6 -6
- package/dist/carousel/carousel.js +4 -4
- package/dist/carousel/llms.txt +10 -10
- package/dist/charts/chart-legend.d.ts +3 -3
- package/dist/charts/chart-legend.js +1 -1
- package/dist/charts/chart-tooltip.d.ts +3 -3
- package/dist/charts/chart-tooltip.js +1 -1
- package/dist/charts/chart.d.ts +1 -1
- package/dist/charts/chart.js +8 -8
- package/dist/charts/llms.txt +6 -6
- package/dist/charts-entry/public-api.js +2 -2
- package/dist/chat/chat.d.ts +17 -10
- package/dist/chat/chat.js +42 -18
- package/dist/chat/llms.txt +32 -17
- package/dist/chat-composer/chat-composer.d.ts +17 -7
- package/dist/chat-composer/chat-composer.js +21 -8
- package/dist/chat-composer/llms.txt +20 -11
- package/dist/chat-dock/chat-dock.d.ts +11 -4
- package/dist/chat-dock/chat-dock.js +9 -6
- package/dist/chat-dock/llms.txt +15 -14
- package/dist/chat-entry/public-api.js +1 -1
- package/dist/chat-message/chat-message.d.ts +12 -5
- package/dist/chat-message/chat-message.js +17 -7
- package/dist/chat-message/llms.txt +16 -15
- package/dist/chat-typing/chat-typing.d.ts +2 -2
- package/dist/chat-typing/chat-typing.js +3 -3
- package/dist/chat-typing/llms.txt +6 -6
- package/dist/checkbox/checkbox.d.ts +13 -6
- package/dist/checkbox/checkbox.js +26 -7
- package/dist/checkbox/llms.txt +24 -12
- package/dist/chip/chip.d.ts +4 -4
- package/dist/chip/chip.js +2 -2
- package/dist/chip/llms.txt +11 -11
- package/dist/chips-input/chips-input.d.ts +4 -4
- package/dist/chips-input/chips-input.js +35 -9
- package/dist/chips-input/llms.txt +15 -8
- package/dist/clock/clock.d.ts +4 -4
- package/dist/clock/clock.js +7 -7
- package/dist/clock/llms.txt +8 -8
- package/dist/color-picker/color-picker.d.ts +6 -6
- package/dist/color-picker/color-picker.js +3 -3
- package/dist/color-picker/llms.txt +5 -5
- package/dist/confirm/confirm-container.d.ts +3 -3
- package/dist/confirm/confirm-container.js +5 -5
- package/dist/confirm/confirm-store.d.ts +4 -4
- package/dist/confirm/confirm-store.js +7 -7
- package/dist/confirm/llms.txt +6 -6
- package/dist/context-menu/context-menu.d.ts +1 -1
- package/dist/context-menu/context-menu.js +5 -5
- package/dist/context-menu/llms.txt +7 -7
- package/dist/data-table/data-table-types.d.ts +5 -5
- package/dist/data-table/data-table.d.ts +29 -8
- package/dist/data-table/data-table.js +340 -95
- package/dist/data-table/export-csv.d.ts +3 -3
- package/dist/data-table/export-csv.js +4 -4
- package/dist/data-table/llms.txt +127 -94
- package/dist/data-view/data-view.d.ts +13 -5
- package/dist/data-view/data-view.js +67 -6
- package/dist/data-view/llms.txt +29 -10
- package/dist/date-range/date-range.d.ts +9 -9
- package/dist/date-range/date-range.js +24 -24
- package/dist/date-range/llms.txt +20 -20
- package/dist/datepicker/datepicker.d.ts +10 -10
- package/dist/datepicker/datepicker.js +29 -29
- package/dist/datepicker/llms.txt +24 -24
- package/dist/dialog/dialog.d.ts +12 -7
- package/dist/dialog/dialog.js +4 -4
- package/dist/dialog/llms.txt +14 -11
- package/dist/divider/divider.d.ts +1 -1
- package/dist/divider/llms.txt +4 -4
- package/dist/drawer/drawer.d.ts +5 -5
- package/dist/drawer/drawer.js +2 -2
- package/dist/drawer/llms.txt +11 -11
- package/dist/empty/empty.d.ts +2 -2
- package/dist/empty/empty.js +1 -1
- package/dist/empty/llms.txt +9 -9
- package/dist/fab/fab.d.ts +1 -1
- package/dist/fab/fab.js +1 -1
- package/dist/fab/llms.txt +10 -6
- package/dist/fieldset/fieldset.d.ts +18 -4
- package/dist/fieldset/fieldset.js +9 -6
- package/dist/fieldset/llms.txt +26 -9
- package/dist/file-upload/file-upload.d.ts +3 -3
- package/dist/file-upload/file-upload.js +7 -7
- package/dist/file-upload/llms.txt +7 -7
- package/dist/form-field/form-field-context.d.ts +4 -4
- package/dist/form-field/form-field.d.ts +12 -4
- package/dist/form-field/form-field.js +26 -6
- package/dist/form-field/llms.txt +25 -11
- package/dist/galleria/galleria.d.ts +3 -3
- package/dist/galleria/galleria.js +5 -5
- package/dist/galleria/llms.txt +7 -7
- package/dist/grid/col.d.ts +4 -4
- package/dist/grid/col.js +2 -2
- package/dist/grid/flex.d.ts +3 -3
- package/dist/grid/flex.js +1 -1
- package/dist/grid/grid.d.ts +7 -7
- package/dist/grid/grid.js +3 -3
- package/dist/grid/layout.d.ts +2 -2
- package/dist/grid/layout.js +2 -2
- package/dist/grid/llms.txt +15 -15
- package/dist/grid-entry/public-api.js +1 -1
- package/dist/i18n/i18n-context.d.ts +3 -3
- package/dist/i18n/i18n-context.js +7 -7
- package/dist/icon/icon-registry.d.ts +3 -3
- package/dist/icon/icon-registry.js +3 -3
- package/dist/icon/icon.d.ts +4 -4
- package/dist/icon/icon.js +6 -6
- package/dist/icon/llms.txt +13 -13
- package/dist/icon-button/icon-button.d.ts +2 -2
- package/dist/icon-button/icon-button.js +1 -1
- package/dist/icon-button/llms.txt +9 -5
- package/dist/icons-entry/public-api.d.ts +2 -2
- package/dist/icons-entry/public-api.js +3 -3
- package/dist/image/image.js +1 -1
- package/dist/image/llms.txt +13 -13
- package/dist/input/input.d.ts +18 -5
- package/dist/input/input.js +21 -6
- package/dist/input/llms.txt +25 -11
- package/dist/input-mask/input-mask.d.ts +1 -1
- package/dist/input-mask/input-mask.js +2 -2
- package/dist/input-mask/llms.txt +5 -5
- package/dist/input-number/input-number.d.ts +9 -9
- package/dist/input-number/input-number.js +11 -11
- package/dist/input-number/llms.txt +14 -14
- package/dist/input-otp/input-otp.d.ts +6 -6
- package/dist/input-otp/input-otp.js +10 -10
- package/dist/input-otp/llms.txt +9 -9
- package/dist/internal/calendar-focus.d.ts +1 -1
- package/dist/internal/calendar-focus.js +3 -3
- package/dist/internal/cn.d.ts +1 -1
- package/dist/internal/mask.d.ts +2 -2
- package/dist/internal/mask.js +4 -4
- package/dist/internal/option-key.d.ts +2 -2
- package/dist/internal/option-key.js +2 -2
- package/dist/internal/option-nav.d.ts +4 -4
- package/dist/internal/option-nav.js +5 -5
- package/dist/internal/overlay-container.js +1 -1
- package/dist/internal/overlay.d.ts +3 -3
- package/dist/internal/overlay.js +8 -8
- package/dist/internal/password-strength.d.ts +2 -2
- package/dist/internal/password-strength.js +6 -6
- package/dist/internal/roving.d.ts +2 -2
- package/dist/internal/roving.js +3 -3
- package/dist/internal/scroll-lock.d.ts +1 -1
- package/dist/internal/scroll-lock.js +2 -2
- package/dist/internal/slot-children.d.ts +3 -3
- package/dist/internal/slot-children.js +4 -4
- package/dist/internal/slot.d.ts +3 -3
- package/dist/internal/slot.js +2 -2
- package/dist/internal/step.d.ts +3 -3
- package/dist/internal/step.js +4 -4
- package/dist/internal/tween.d.ts +5 -5
- package/dist/internal/tween.js +5 -5
- package/dist/internal/types.d.ts +2 -2
- package/dist/internal/use-breakpoint.d.ts +2 -2
- package/dist/internal/use-breakpoint.js +4 -4
- package/dist/internal/use-controllable-state.d.ts +1 -1
- package/dist/internal/use-controllable-state.js +3 -3
- package/dist/internal/use-id.d.ts +2 -2
- package/dist/internal/use-id.js +2 -2
- package/dist/internal/use-modal-focus.d.ts +1 -1
- package/dist/internal/use-modal-focus.js +3 -3
- package/dist/knob/knob.d.ts +4 -4
- package/dist/knob/knob.js +14 -10
- package/dist/knob/llms.txt +17 -12
- package/dist/listbox/listbox.d.ts +6 -6
- package/dist/listbox/listbox.js +9 -9
- package/dist/listbox/llms.txt +10 -10
- package/dist/loader/llms.txt +56 -0
- package/dist/loader/loader.d.ts +49 -0
- package/dist/loader/loader.js +68 -0
- package/dist/map/llms.txt +25 -22
- package/dist/map/map-create-dialog.d.ts +4 -4
- package/dist/map/map-create-dialog.js +10 -10
- package/dist/map/map-hours-field.d.ts +4 -4
- package/dist/map/map-hours-field.js +7 -7
- package/dist/map/map-image-field.d.ts +2 -2
- package/dist/map/map-image-field.js +4 -4
- package/dist/map/map-legend.d.ts +4 -4
- package/dist/map/map-legend.js +2 -2
- package/dist/map/map-poi-card.d.ts +3 -3
- package/dist/map/map-poi-card.js +9 -9
- package/dist/map/map-search.d.ts +17 -6
- package/dist/map/map-search.js +21 -18
- package/dist/map/map.d.ts +21 -14
- package/dist/map/map.js +30 -29
- package/dist/map/ports.d.ts +9 -9
- package/dist/map/ports.js +6 -6
- package/dist/map-entry/public-api.js +2 -2
- package/dist/megamenu/llms.txt +9 -9
- package/dist/megamenu/megamenu.d.ts +6 -6
- package/dist/megamenu/megamenu.js +10 -10
- package/dist/mention/llms.txt +15 -15
- package/dist/mention/mention.d.ts +5 -5
- package/dist/mention/mention.js +2 -2
- package/dist/mention/mentions.d.ts +1 -1
- package/dist/mention/mentions.js +1 -1
- package/dist/menu/llms.txt +12 -12
- package/dist/menu/menu-item.d.ts +4 -4
- package/dist/menu/menu-keys.d.ts +2 -2
- package/dist/menu/menu-keys.js +5 -5
- package/dist/menu/menu.d.ts +2 -2
- package/dist/menu/menu.js +6 -6
- package/dist/menubar/llms.txt +10 -10
- package/dist/menubar/menubar.d.ts +5 -5
- package/dist/menubar/menubar.js +10 -10
- package/dist/meter-group/llms.txt +12 -12
- package/dist/meter-group/meter-group.d.ts +2 -2
- package/dist/meter-group/meter-group.js +1 -1
- package/dist/motion/motion-context.d.ts +22 -0
- package/dist/motion/motion-context.js +28 -0
- package/dist/order-list/llms.txt +22 -10
- package/dist/order-list/order-list.d.ts +12 -4
- package/dist/order-list/order-list.js +104 -21
- package/dist/paginator/llms.txt +8 -8
- package/dist/paginator/paginator.js +1 -1
- package/dist/panel/llms.txt +25 -13
- package/dist/panel/panel.d.ts +11 -3
- package/dist/panel/panel.js +7 -4
- package/dist/password/llms.txt +16 -8
- package/dist/password/password.d.ts +2 -2
- package/dist/password/password.js +24 -3
- package/dist/peek/llms.txt +10 -10
- package/dist/peek/peek.d.ts +6 -6
- package/dist/peek/peek.js +7 -7
- package/dist/pick-list/llms.txt +33 -13
- package/dist/pick-list/pick-list.d.ts +12 -4
- package/dist/pick-list/pick-list.js +111 -23
- package/dist/popover/llms.txt +11 -11
- package/dist/popover/popover.d.ts +4 -4
- package/dist/popover/popover.js +5 -5
- package/dist/progress/llms.txt +17 -17
- package/dist/progress/progress.d.ts +7 -7
- package/dist/progress/progress.js +6 -6
- package/dist/public-api.d.ts +15 -3
- package/dist/public-api.js +13 -7
- package/dist/radio-group/llms.txt +13 -6
- package/dist/radio-group/radio-group.d.ts +11 -4
- package/dist/radio-group/radio-group.js +15 -7
- package/dist/rating/llms.txt +20 -13
- package/dist/rating/rating-pointer.d.ts +16 -0
- package/dist/rating/rating-pointer.js +26 -0
- package/dist/rating/rating.d.ts +6 -6
- package/dist/rating/rating.js +76 -12
- package/dist/rich-text/lists.d.ts +2 -2
- package/dist/rich-text/lists.js +7 -7
- package/dist/rich-text/llms.txt +26 -17
- package/dist/rich-text/rich-text.d.ts +12 -7
- package/dist/rich-text/rich-text.js +78 -54
- package/dist/rich-text/sanitize.d.ts +3 -3
- package/dist/rich-text/sanitize.js +12 -12
- package/dist/rich-text/tables.d.ts +3 -3
- package/dist/rich-text/tables.js +3 -3
- package/dist/roadmap/llms.txt +15 -15
- package/dist/roadmap/roadmap.d.ts +6 -6
- package/dist/roadmap/roadmap.js +19 -19
- package/dist/roadmap-entry/public-api.js +2 -2
- package/dist/scroll-top/llms.txt +6 -6
- package/dist/scroll-top/scroll-top.d.ts +1 -1
- package/dist/scroll-top/scroll-top.js +1 -1
- package/dist/select/llms.txt +19 -12
- package/dist/select/select.d.ts +8 -8
- package/dist/select/select.js +47 -21
- package/dist/shared/types.d.ts +5 -5
- package/dist/shared/types.js +1 -1
- package/dist/sidenav/llms.txt +9 -9
- package/dist/sidenav/sidenav.d.ts +1 -1
- package/dist/sidenav/sidenav.js +1 -1
- package/dist/skeleton/llms.txt +3 -3
- package/dist/skeleton/skeleton.d.ts +1 -1
- package/dist/skeleton/skeleton.js +1 -1
- package/dist/slider/llms.txt +32 -13
- package/dist/slider/slider-drag.d.ts +26 -0
- package/dist/slider/slider-drag.js +79 -0
- package/dist/slider/slider.d.ts +6 -5
- package/dist/slider/slider.js +27 -8
- package/dist/speech/llms.txt +97 -0
- package/dist/speech/speech-button.d.ts +44 -0
- package/dist/speech/speech-button.js +86 -0
- package/dist/speech/speech-wave.d.ts +19 -0
- package/dist/speech/speech-wave.js +16 -0
- package/dist/speech/use-speech-recognition.d.ts +81 -0
- package/dist/speech/use-speech-recognition.js +179 -0
- package/dist/speed-dial/llms.txt +14 -8
- package/dist/speed-dial/speed-dial.d.ts +1 -1
- package/dist/speed-dial/speed-dial.js +1 -1
- package/dist/spinner/llms.txt +7 -7
- package/dist/spinner/spinner.d.ts +1 -1
- package/dist/spinner/spinner.js +1 -1
- package/dist/split-button/llms.txt +21 -15
- package/dist/split-button/split-button.d.ts +2 -2
- package/dist/split-button/split-button.js +4 -4
- package/dist/splitter/llms.txt +11 -11
- package/dist/splitter/splitter.d.ts +3 -3
- package/dist/splitter/splitter.js +5 -5
- package/dist/stepper/llms.txt +33 -14
- package/dist/stepper/stepper.d.ts +6 -6
- package/dist/stepper/stepper.js +53 -10
- package/dist/switch/llms.txt +12 -5
- package/dist/switch/switch.d.ts +10 -3
- package/dist/switch/switch.js +12 -5
- package/dist/switch-group/llms.txt +9 -9
- package/dist/switch-group/switch-group.d.ts +4 -4
- package/dist/switch-group/switch-group.js +4 -4
- package/dist/tabs/llms.txt +10 -10
- package/dist/tabs/tabs.d.ts +5 -5
- package/dist/tabs/tabs.js +8 -8
- package/dist/textarea/llms.txt +23 -12
- package/dist/textarea/textarea.d.ts +19 -6
- package/dist/textarea/textarea.js +21 -7
- package/dist/timeline/llms.txt +4 -4
- package/dist/timeline/timeline.d.ts +1 -1
- package/dist/timeline/timeline.js +1 -1
- package/dist/toast/llms.txt +47 -17
- package/dist/toast/toast-container.d.ts +9 -3
- package/dist/toast/toast-container.js +17 -9
- package/dist/toast/toast-store.d.ts +40 -4
- package/dist/toast/toast-store.js +36 -1
- package/dist/toolbar/llms.txt +7 -7
- package/dist/toolbar/toolbar.d.ts +3 -3
- package/dist/toolbar/toolbar.js +2 -2
- package/dist/tooltip/llms.txt +10 -10
- package/dist/tooltip/tooltip.d.ts +3 -3
- package/dist/tooltip/tooltip.js +18 -18
- package/dist/tree/llms.txt +25 -12
- package/dist/tree/tree-keys.d.ts +5 -5
- package/dist/tree/tree-keys.js +7 -7
- package/dist/tree/tree.d.ts +14 -7
- package/dist/tree/tree.js +53 -18
- package/dist/update/llms.txt +54 -0
- package/dist/update/update.d.ts +49 -0
- package/dist/update/update.js +82 -0
- package/package.json +15 -13
package/dist/card/llms.txt
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
1
|
# KptCard (@konce-pt/react)
|
|
2
2
|
|
|
3
|
-
A card
|
|
3
|
+
A card - a surface with elevation (`elevated`) or a border (`outlined`). The card renders its own
|
|
4
4
|
body; the header and the footer are lifted out of the children and placed outside that body,
|
|
5
5
|
exactly where the Angular template puts them, so the DOM tree matches node for node.
|
|
6
6
|
Import: `import { KptCard } from '@konce-pt/react';`
|
|
7
7
|
|
|
8
8
|
## DOM
|
|
9
9
|
<div class="kpt-card" data-variant="elevated">
|
|
10
|
-
<div class="kpt-card__header"
|
|
11
|
-
<div class="kpt-card__body"
|
|
12
|
-
<div kptcardfooter=""
|
|
10
|
+
<div class="kpt-card__header">...</div>
|
|
11
|
+
<div class="kpt-card__body">...</div>
|
|
12
|
+
<div kptcardfooter="">...</div>
|
|
13
13
|
</div>
|
|
14
14
|
|
|
15
15
|
## Props
|
|
16
16
|
- `variant`: 'elevated' | 'outlined' (default 'elevated')
|
|
17
|
-
- `header`: string
|
|
18
|
-
- `headingLevel`: 1
|
|
19
|
-
- `headingLevel`: 1
|
|
20
|
-
- `flush`: boolean
|
|
17
|
+
- `header`: string - optional header text; use `<KptCard.Header>` for richer content
|
|
18
|
+
- `headingLevel`: 1-6 - makes `header` a heading of that level (`role="heading"` + `aria-level`)
|
|
19
|
+
- `headingLevel`: 1-6 - makes `header` a heading of that level (`role="heading"` + `aria-level`)
|
|
20
|
+
- `flush`: boolean - a body with no padding (for rich layouts that manage their own sections)
|
|
21
21
|
- `className`, `ref` and every other `<div>` prop go to the card root
|
|
22
22
|
|
|
23
23
|
## Sub-components
|
|
24
|
-
- `KptCard.Header`
|
|
25
|
-
- `KptCard.Footer`
|
|
24
|
+
- `KptCard.Header` - lifted above the body, `.kpt-card__header`
|
|
25
|
+
- `KptCard.Footer` - lifted below the body; carries the `kptcardfooter` attribute the shared
|
|
26
26
|
SCSS targets (attribute names in CSS selectors are case-insensitive in HTML, so one rule
|
|
27
27
|
serves both ports)
|
|
28
|
-
- `KptCard.Media`
|
|
29
|
-
- `KptCard.Lead`
|
|
30
|
-
- `KptCard.Title`, `KptCard.Subtitle`
|
|
31
|
-
- `KptCard.Section`
|
|
32
|
-
- `KptCard.Tags`
|
|
33
|
-
- `KptCard.Actions`
|
|
28
|
+
- `KptCard.Media` - an `<img>` on the full width, clipped to the radius; set `aspect-ratio`/`height`
|
|
29
|
+
- `KptCard.Lead` - the header row (avatar + titles), with padding
|
|
30
|
+
- `KptCard.Title`, `KptCard.Subtitle` - title/subtitle typography
|
|
31
|
+
- `KptCard.Section` - a padded section (a column with gaps)
|
|
32
|
+
- `KptCard.Tags` - a row of chips; `KptCard.Meta` - an icon+text row (rating/location)
|
|
33
|
+
- `KptCard.Actions` - a row of buttons (equal widths)
|
|
34
34
|
|
|
35
35
|
There is no `KptCard.Body`: the body belongs to the card itself, and `flush` removes its padding.
|
|
36
36
|
An overlapping avatar is a class you apply to your own element: `className="kpt-card__avatar"`.
|
|
37
37
|
|
|
38
38
|
## Examples
|
|
39
39
|
<KptCard header="Settings" variant="outlined">
|
|
40
|
-
<p>Content
|
|
40
|
+
<p>Content...</p>
|
|
41
41
|
<KptCard.Footer><KptButton>Save</KptButton></KptCard.Footer>
|
|
42
42
|
</KptCard>
|
|
43
43
|
|
|
@@ -50,7 +50,7 @@ An overlapping avatar is a class you apply to your own element: `className="kpt-
|
|
|
50
50
|
</div>
|
|
51
51
|
</KptCard.Lead>
|
|
52
52
|
<KptCard.Media src="/photo.jpg" style={{ aspectRatio: '4 / 3' }} />
|
|
53
|
-
<KptCard.Section>Description
|
|
53
|
+
<KptCard.Section>Description...</KptCard.Section>
|
|
54
54
|
<KptCard.Footer><KptButton variant="text" size="sm">LIKE</KptButton></KptCard.Footer>
|
|
55
55
|
</KptCard>
|
|
56
56
|
|
|
@@ -58,7 +58,7 @@ An overlapping avatar is a class you apply to your own element: `className="kpt-
|
|
|
58
58
|
`--kpt-card-{bg,fg,border,radius,padding,shadow}`.
|
|
59
59
|
|
|
60
60
|
## Accessibility
|
|
61
|
-
The card is a plain container with no role of its own. `header` is styled text by default
|
|
62
|
-
`headingLevel` (1
|
|
61
|
+
The card is a plain container with no role of its own. `header` is styled text by default - set
|
|
62
|
+
`headingLevel` (1-6) to make it a heading (`role="heading"` + `aria-level`) when the card should
|
|
63
63
|
appear in the page outline; leave it off for tiles that would only clutter it. Give media images a
|
|
64
64
|
meaningful `alt`, or `alt=""` when decorative.
|
|
@@ -5,20 +5,20 @@ export interface KptCarouselProps<T> extends Omit<ComponentPropsWithRef<'div'>,
|
|
|
5
5
|
activeIndex?: number;
|
|
6
6
|
defaultActiveIndex?: number;
|
|
7
7
|
onActiveIndexChange?: (index: number) => void;
|
|
8
|
-
/** Szablon slajdu
|
|
8
|
+
/** Szablon slajdu - odpowiednik `<ng-template let-item let-i="index">` z Angulara. */
|
|
9
9
|
renderSlide: (item: T, index: number) => ReactNode;
|
|
10
|
-
/** Nazwa regionu dla czytników ekranu, np.
|
|
10
|
+
/** Nazwa regionu dla czytników ekranu, np. "Nowości"; domyślnie `carousel.label`. */
|
|
11
11
|
label?: string;
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
14
|
* Karuzela slajdów. Dane przez `items`, wygląd slajdu przez `renderSlide`.
|
|
15
15
|
*
|
|
16
16
|
* Tor przesuwa się jednym `translateX` o wielokrotność 100%, więc slajdy jadą płynnie, a każdy
|
|
17
|
-
* zostaje zamontowany
|
|
17
|
+
* zostaje zamontowany - przewijanie nie gubi stanu treści.
|
|
18
18
|
*
|
|
19
|
-
* Semantyka według wzorca WAI-ARIA
|
|
20
|
-
* `aria-roledescription="karuzela"`, każdy slajd to grupa
|
|
21
|
-
* `inert`
|
|
19
|
+
* Semantyka według wzorca WAI-ARIA "carousel" (bez autoodtwarzania): region z
|
|
20
|
+
* `aria-roledescription="karuzela"`, każdy slajd to grupa "Slajd 2 z 4", a slajdy poza widokiem są
|
|
21
|
+
* `inert` - `Tab` i czytnik ich nie widzą. Zmiana slajdu jest ogłaszana uprzejmie (`aria-live`
|
|
22
22
|
* na torze). Strzałki na końcach dostają `aria-disabled` zamiast `disabled`, żeby nie zgubić fokusu.
|
|
23
23
|
*
|
|
24
24
|
* @example
|
|
@@ -8,11 +8,11 @@ import { KptIcon } from "../icon/icon.js";
|
|
|
8
8
|
* Karuzela slajdów. Dane przez `items`, wygląd slajdu przez `renderSlide`.
|
|
9
9
|
*
|
|
10
10
|
* Tor przesuwa się jednym `translateX` o wielokrotność 100%, więc slajdy jadą płynnie, a każdy
|
|
11
|
-
* zostaje zamontowany
|
|
11
|
+
* zostaje zamontowany - przewijanie nie gubi stanu treści.
|
|
12
12
|
*
|
|
13
|
-
* Semantyka według wzorca WAI-ARIA
|
|
14
|
-
* `aria-roledescription="karuzela"`, każdy slajd to grupa
|
|
15
|
-
* `inert`
|
|
13
|
+
* Semantyka według wzorca WAI-ARIA "carousel" (bez autoodtwarzania): region z
|
|
14
|
+
* `aria-roledescription="karuzela"`, każdy slajd to grupa "Slajd 2 z 4", a slajdy poza widokiem są
|
|
15
|
+
* `inert` - `Tab` i czytnik ich nie widzą. Zmiana slajdu jest ogłaszana uprzejmie (`aria-live`
|
|
16
16
|
* na torze). Strzałki na końcach dostają `aria-disabled` zamiast `disabled`, żeby nie zgubić fokusu.
|
|
17
17
|
*
|
|
18
18
|
* @example
|
package/dist/carousel/llms.txt
CHANGED
|
@@ -10,15 +10,15 @@ Import: `import { KptCarousel } from '@konce-pt/react';`
|
|
|
10
10
|
<div class="kpt-carousel__track" aria-live="polite"
|
|
11
11
|
style="transform:translateX(calc(var(--_kpt-carousel-dir, 1) * -100%))">
|
|
12
12
|
<div class="kpt-carousel__slide" role="group" aria-roledescription="slide"
|
|
13
|
-
aria-label="Slide 1 of 3" inert aria-hidden="true"
|
|
13
|
+
aria-label="Slide 1 of 3" inert aria-hidden="true">...</div>
|
|
14
14
|
<div class="kpt-carousel__slide" role="group" aria-roledescription="slide"
|
|
15
|
-
aria-label="Slide 2 of 3"
|
|
15
|
+
aria-label="Slide 2 of 3">...</div>...
|
|
16
16
|
</div>
|
|
17
17
|
</div>
|
|
18
|
-
<button class="kpt-carousel__nav kpt-carousel__nav--prev" aria-label="Previous"
|
|
19
|
-
<button class="kpt-carousel__nav kpt-carousel__nav--next" aria-label="Next"
|
|
18
|
+
<button class="kpt-carousel__nav kpt-carousel__nav--prev" aria-label="Previous">...</button>
|
|
19
|
+
<button class="kpt-carousel__nav kpt-carousel__nav--next" aria-label="Next">...</button>
|
|
20
20
|
<div class="kpt-carousel__dots">
|
|
21
|
-
<button class="kpt-carousel__dot is-active" aria-current="true" aria-label="Slide 2"></button
|
|
21
|
+
<button class="kpt-carousel__dot is-active" aria-current="true" aria-label="Slide 2"></button>...
|
|
22
22
|
</div>
|
|
23
23
|
</div>
|
|
24
24
|
</div>
|
|
@@ -26,8 +26,8 @@ Import: `import { KptCarousel } from '@konce-pt/react';`
|
|
|
26
26
|
## Props
|
|
27
27
|
- `items`: `T[]`
|
|
28
28
|
- `activeIndex` / `defaultActiveIndex` / `onActiveIndexChange`
|
|
29
|
-
- `renderSlide(item, index)`
|
|
30
|
-
- `label`: string
|
|
29
|
+
- `renderSlide(item, index)` - required
|
|
30
|
+
- `label`: string - the region name; empty = `carousel.label`
|
|
31
31
|
- `className`, `ref` and every other `<div>` prop go to the host
|
|
32
32
|
|
|
33
33
|
## The render prop replaces the template
|
|
@@ -36,7 +36,7 @@ carousel owns the layout and the navigation, the caller owns what a slide looks
|
|
|
36
36
|
guessed about the item's shape, so the component stays generic in `T`.
|
|
37
37
|
|
|
38
38
|
## One transform, every slide mounted
|
|
39
|
-
The track slides with a single `translateX` of a multiple of 100%, so every slide stays mounted
|
|
39
|
+
The track slides with a single `translateX` of a multiple of 100%, so every slide stays mounted -
|
|
40
40
|
paging does not lose state inside a slide (a form, a playing video, a scroll position).
|
|
41
41
|
|
|
42
42
|
## Examples
|
|
@@ -51,9 +51,9 @@ The active dot `--kpt-color-primary`; the arrows `--kpt-color-surface` (80% via
|
|
|
51
51
|
|
|
52
52
|
## Accessibility
|
|
53
53
|
The WAI-ARIA carousel pattern without autoplay. The root is `role="region"` with
|
|
54
|
-
`aria-roledescription` from `carousel.roleCarousel` (
|
|
54
|
+
`aria-roledescription` from `carousel.roleCarousel` ("carousel") and a name from `label` or
|
|
55
55
|
`carousel.label`. Each slide is `role="group"` with `aria-roledescription` from `carousel.roleSlide`
|
|
56
|
-
and a name from `carousel.slideOf` (
|
|
56
|
+
and a name from `carousel.slideOf` ("Slide 2 of 4"); slides outside the view are `inert` and
|
|
57
57
|
`aria-hidden`, so Tab never lands on an invisible link. The track is `aria-live="polite"`, so the
|
|
58
58
|
slide that comes in is announced. The arrows use `aria-disabled` at the ends instead of `disabled`,
|
|
59
59
|
so they keep the focus; the active dot carries `aria-current`, and every dot has a 24 px target
|
|
@@ -11,13 +11,13 @@ export interface KptChartLegendProps {
|
|
|
11
11
|
align?: KptAlign;
|
|
12
12
|
pointStyle?: KptPointStyle;
|
|
13
13
|
title?: KptLegendTitle;
|
|
14
|
-
/** Kliknięcie elementu
|
|
14
|
+
/** Kliknięcie elementu - przełącz widoczność serii albo wycinka. */
|
|
15
15
|
onToggle?: (key: string) => void;
|
|
16
|
-
/** Wejście i wyjście kursora
|
|
16
|
+
/** Wejście i wyjście kursora - podświetl serię albo wyczyść podświetlenie. */
|
|
17
17
|
onHighlight?: (key: string | null) => void;
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
|
-
* Legenda wykresu
|
|
20
|
+
* Legenda wykresu - klikalne elementy, podświetlanie pod kursorem, pozycja, wyrównanie i styl
|
|
21
21
|
* punktu. Element wewnętrzny biblioteki, nie część publicznego API.
|
|
22
22
|
*/
|
|
23
23
|
export declare function KptChartLegend({ items, position, align, pointStyle, title, onToggle, onHighlight, }: Readonly<KptChartLegendProps>): import("react").JSX.Element;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { cn } from "../internal/cn.js";
|
|
4
4
|
/**
|
|
5
|
-
* Legenda wykresu
|
|
5
|
+
* Legenda wykresu - klikalne elementy, podświetlanie pod kursorem, pozycja, wyrównanie i styl
|
|
6
6
|
* punktu. Element wewnętrzny biblioteki, nie część publicznego API.
|
|
7
7
|
*/
|
|
8
8
|
export function KptChartLegend({ items = [], position = 'bottom', align = 'center', pointStyle = 'circle', title, onToggle, onHighlight, }) {
|
|
@@ -4,9 +4,9 @@ export interface KptChartTooltipRow {
|
|
|
4
4
|
color: string;
|
|
5
5
|
}
|
|
6
6
|
export interface KptChartTooltipState {
|
|
7
|
-
/** Pozycja pozioma w % szerokości kontenera (0
|
|
7
|
+
/** Pozycja pozioma w % szerokości kontenera (0-100). */
|
|
8
8
|
x: number;
|
|
9
|
-
/** Pozycja pionowa w % wysokości kontenera (0
|
|
9
|
+
/** Pozycja pionowa w % wysokości kontenera (0-100). */
|
|
10
10
|
y: number;
|
|
11
11
|
label: string;
|
|
12
12
|
rows: KptChartTooltipRow[];
|
|
@@ -15,7 +15,7 @@ export interface KptChartTooltipProps {
|
|
|
15
15
|
state: KptChartTooltipState | null;
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
|
-
* Dymek wykresu
|
|
18
|
+
* Dymek wykresu - pozycjonowany procentowo względem kontenera, niezależnie od skali SVG, więc
|
|
19
19
|
* nie trzeba przeliczać jednostek viewBoxa na piksele. Element wewnętrzny biblioteki.
|
|
20
20
|
*/
|
|
21
21
|
export declare function KptChartTooltip({ state }: Readonly<KptChartTooltipProps>): import("react").JSX.Element | null;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { cn } from "../internal/cn.js";
|
|
3
3
|
/**
|
|
4
|
-
* Dymek wykresu
|
|
4
|
+
* Dymek wykresu - pozycjonowany procentowo względem kontenera, niezależnie od skali SVG, więc
|
|
5
5
|
* nie trzeba przeliczać jednostek viewBoxa na piksele. Element wewnętrzny biblioteki.
|
|
6
6
|
*/
|
|
7
7
|
export function KptChartTooltip({ state }) {
|
package/dist/charts/chart.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export interface KptChartProps extends Omit<ComponentPropsWithRef<'div'>, 'child
|
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
12
|
* Wykres SVG sterowany jednym obiektem `config`: line, bar, pie, doughnut, polarArea, radar.
|
|
13
|
-
* Cała geometria pochodzi z `@konce-pt/chart`
|
|
13
|
+
* Cała geometria pochodzi z `@konce-pt/chart` - paczki bez frameworka, wspólnej z portem
|
|
14
14
|
* Angulara; komponent renderuje wyłącznie SVG, bez manipulacji DOM.
|
|
15
15
|
*
|
|
16
16
|
* @example
|
package/dist/charts/chart.js
CHANGED
|
@@ -17,7 +17,7 @@ function styleFor(align) {
|
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
19
|
* Wykres SVG sterowany jednym obiektem `config`: line, bar, pie, doughnut, polarArea, radar.
|
|
20
|
-
* Cała geometria pochodzi z `@konce-pt/chart`
|
|
20
|
+
* Cała geometria pochodzi z `@konce-pt/chart` - paczki bez frameworka, wspólnej z portem
|
|
21
21
|
* Angulara; komponent renderuje wyłącznie SVG, bez manipulacji DOM.
|
|
22
22
|
*
|
|
23
23
|
* @example
|
|
@@ -26,14 +26,14 @@ function styleFor(align) {
|
|
|
26
26
|
export function KptChart({ config, width = 600, height = 360, locale, dictionary, className, style, ...rest }) {
|
|
27
27
|
const { t, locale: activeLocale } = useKptMessages({ locale, dictionary });
|
|
28
28
|
const descId = `${useId()}-desc`;
|
|
29
|
-
// Alternatywa tekstowa (WCAG 1.1.1): nazwa SVG (`ariaLabel`
|
|
30
|
-
// wizualnie tabeli
|
|
29
|
+
// Alternatywa tekstowa (WCAG 1.1.1): nazwa SVG (`ariaLabel` -> tytuł -> i18n) i dane w ukrytej
|
|
30
|
+
// wizualnie tabeli - dymek na najechanie jest dostępny tylko myszą.
|
|
31
31
|
const accessibleName = chartAccessibleName(config, t('chart.label'));
|
|
32
32
|
const dataTable = chartDataTable(config, activeLocale);
|
|
33
33
|
const [hidden, setHidden] = useState(new Set());
|
|
34
34
|
const [highlighted, setHighlighted] = useState(null);
|
|
35
35
|
const [tooltip, setTooltip] = useState(null);
|
|
36
|
-
/** Indeks kategorii pod kursorem
|
|
36
|
+
/** Indeks kategorii pod kursorem - prowadnica crosshair w wykresie liniowym. */
|
|
37
37
|
const [activeIndex, setActiveIndex] = useState(null);
|
|
38
38
|
const anim = {
|
|
39
39
|
enabled: config.animation?.enabled ?? true,
|
|
@@ -79,7 +79,7 @@ export function KptChart({ config, width = 600, height = 360, locale, dictionary
|
|
|
79
79
|
next.add(key);
|
|
80
80
|
setHidden(next);
|
|
81
81
|
};
|
|
82
|
-
//
|
|
82
|
+
// -- Wykres liniowy --
|
|
83
83
|
const lineVm = (() => {
|
|
84
84
|
if (config.type !== 'line')
|
|
85
85
|
return null;
|
|
@@ -132,7 +132,7 @@ export function KptChart({ config, width = 600, height = 360, locale, dictionary
|
|
|
132
132
|
} })] }, idx)))] }, key));
|
|
133
133
|
})] }));
|
|
134
134
|
})();
|
|
135
|
-
//
|
|
135
|
+
// -- Wykres słupkowy --
|
|
136
136
|
const barVm = (() => {
|
|
137
137
|
if (config.type !== 'bar')
|
|
138
138
|
return null;
|
|
@@ -167,7 +167,7 @@ export function KptChart({ config, width = 600, height = 360, locale, dictionary
|
|
|
167
167
|
return (_jsx("path", { className: cn('kpt-chart__bar', dim(key) && 'kpt-chart__series--dim'), d: b.path, style: { fill: color, ['--kpt-chart-i']: order }, onPointerEnter: () => showTip(tipX, tipY, names[b.seriesIndex], config.labels[b.categoryIndex] ?? '', b.value, color), onPointerLeave: hideTip }, `${key}#${order}`));
|
|
168
168
|
}) })] }));
|
|
169
169
|
})();
|
|
170
|
-
//
|
|
170
|
+
// -- Pie / doughnut / polar area --
|
|
171
171
|
const pieVm = (() => {
|
|
172
172
|
if (!isPieLike)
|
|
173
173
|
return null;
|
|
@@ -192,7 +192,7 @@ export function KptChart({ config, width = 600, height = 360, locale, dictionary
|
|
|
192
192
|
return (_jsx("path", { className: cn('kpt-chart__slice', dim(key) && 'kpt-chart__series--dim'), d: slice.path, style: { fill: entry.color, ['--kpt-chart-i']: k }, onPointerEnter: () => showTip(tip.x, tip.y, entry.label, '', entry.value, entry.color), onPointerLeave: hideTip }, key));
|
|
193
193
|
}) }));
|
|
194
194
|
})();
|
|
195
|
-
//
|
|
195
|
+
// -- Radar --
|
|
196
196
|
const radarVm = (() => {
|
|
197
197
|
if (config.type !== 'radar')
|
|
198
198
|
return null;
|
package/dist/charts/llms.txt
CHANGED
|
@@ -8,22 +8,22 @@ and not every app needs them.
|
|
|
8
8
|
|
|
9
9
|
## Props
|
|
10
10
|
- `config`: `KptChartConfig` (required)
|
|
11
|
-
- `width`, `height`
|
|
11
|
+
- `width`, `height` - the viewBox in SVG units (600 x 360); the chart scales to its container
|
|
12
12
|
|
|
13
13
|
The whole drawing lives in that coordinate system, TYPOGRAPHY INCLUDED: the axis labels are set in
|
|
14
14
|
`font-size: 11px`, but inside an SVG that means 11 user units, not 11 device pixels. Render a
|
|
15
15
|
600-unit chart in a 300px column and the labels come out at roughly half size. `width`/`height` are
|
|
16
|
-
therefore not just an aspect ratio
|
|
16
|
+
therefore not just an aspect ratio - they are the text scale. In a narrow container shrink them
|
|
17
17
|
proportionally (`width={300} height={180}`) instead of letting a 600-unit chart squeeze itself.
|
|
18
18
|
- `className`, `ref` and every other `<div>` prop go to the host
|
|
19
19
|
|
|
20
20
|
## The config is the API
|
|
21
21
|
`{ type, labels, series, points?, area?, interpolation?, orientation?, borderRadius?, innerRadius?,
|
|
22
|
-
crosshair?, tooltip?, legend?, title?, subtitle?, animation?, ariaLabel?, description? }`
|
|
22
|
+
crosshair?, tooltip?, legend?, title?, subtitle?, animation?, ariaLabel?, description? }` - the same shape the Angular port
|
|
23
23
|
takes, because both read it from `@konce-pt/chart`.
|
|
24
24
|
|
|
25
25
|
## The geometry lives in a package
|
|
26
|
-
Scales, paths, bar layout and arcs come from `@konce-pt/chart`
|
|
26
|
+
Scales, paths, bar layout and arcs come from `@konce-pt/chart` - pure functions with `node --test`
|
|
27
27
|
coverage, shared with the Angular port. The component only turns them into SVG elements; there is
|
|
28
28
|
no DOM manipulation and no canvas.
|
|
29
29
|
|
|
@@ -32,7 +32,7 @@ A 4px point is not something a pointer can reliably hit, so each one is paired w
|
|
|
32
32
|
12px circle that carries the events. The visible point only reacts to the state.
|
|
33
33
|
|
|
34
34
|
## Interaction is local state
|
|
35
|
-
Hidden series, the highlighted one, the tooltip and the active category are `useState`
|
|
35
|
+
Hidden series, the highlighted one, the tooltip and the active category are `useState` - the config
|
|
36
36
|
stays a plain object the caller owns, and nothing is written back into it.
|
|
37
37
|
|
|
38
38
|
## Examples
|
|
@@ -56,5 +56,5 @@ stays a plain object the caller owns, and nothing is written back into it.
|
|
|
56
56
|
The `<svg>` is `role="img"` with a name: `config.ariaLabel`, else the title text, else `chart.label`
|
|
57
57
|
from i18n. `config.description` (one sentence with the takeaway) is tied to it through
|
|
58
58
|
`aria-describedby`. The data itself sits in a visually hidden `<table>` (categories in rows, series in
|
|
59
|
-
columns, numbers in the active language), so a screen reader can walk the values
|
|
59
|
+
columns, numbers in the active language), so a screen reader can walk the values - the tooltip is
|
|
60
60
|
pointer-only. The legend is a list of real buttons, so series can be toggled from the keyboard.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* @konce-pt/react/charts
|
|
2
|
+
* @konce-pt/react/charts - wykresy SVG. Osobny subpath, bo geometria i style wykresów są
|
|
3
3
|
* ciężkie względem rdzenia biblioteki i nie każda aplikacja ich potrzebuje.
|
|
4
4
|
*/
|
|
5
5
|
export { KptChart } from "../charts/chart.js";
|
|
6
|
-
// Rdzeń obliczeniowy
|
|
6
|
+
// Rdzeń obliczeniowy - przydatny do własnych rozszerzeń i renderowania po stronie serwera.
|
|
7
7
|
export { KPT_CHART_PALETTE, seriesColor, linePath, areaPath, pieSlices, polarSlices, barLayout, radarGrid, radarPoints, niceScale, } from '@konce-pt/chart';
|
package/dist/chat/chat.d.ts
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
import { type ComponentPropsWithRef, type ReactNode } from 'react';
|
|
2
|
+
import { type KptEnterMotion } from '@konce-pt/motion';
|
|
2
3
|
import type { KptChatAuthor, KptChatMessage as KptChatMessageModel, KptChatMessageRow, KptChatReactionOption, KptChatReplyRef } from '@konce-pt/chat';
|
|
3
4
|
import { type KptI18nOverrides } from '../i18n/i18n-context.tsx';
|
|
4
|
-
/** Wybór reakcji na wiadomości
|
|
5
|
+
/** Wybór reakcji na wiadomości - komponent mówi, w co kliknięto, dopisanie należy do aplikacji. */
|
|
5
6
|
export interface KptChatReactEvent<T = unknown> {
|
|
6
7
|
message: KptChatMessageModel<T>;
|
|
7
8
|
emoji: string;
|
|
8
9
|
}
|
|
9
10
|
export interface KptChatProps<T = unknown> extends Omit<ComponentPropsWithRef<'div'>, 'children'>, KptI18nOverrides {
|
|
10
|
-
/** Wiadomości w kolejności chronologicznej
|
|
11
|
+
/** Wiadomości w kolejności chronologicznej - komponent ich nie sortuje. */
|
|
11
12
|
messages?: readonly KptChatMessageModel<T>[];
|
|
12
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Ruch pojawiania się (nowe wiadomości, reakcje, status): `spring` - wyrasta z miejsca, z którego przychodzi, na sprężynie;
|
|
15
|
+
* `fade` - tylko się przenika; `none` - bez ruchu. Bez wartości bierze `enter` z `KptMotionProvider`
|
|
16
|
+
* (domyślnie `spring`); `enabled={false}` i systemowe "ogranicz ruch" wyłączają go zawsze.
|
|
17
|
+
*/
|
|
18
|
+
enterMotion?: KptEnterMotion;
|
|
19
|
+
/** `id` nadawcy uznawanego za "mnie": jego wiadomości idą na prawo i mają status. */
|
|
13
20
|
currentUser?: string;
|
|
14
21
|
/** Przerwa łamiąca grupę wiadomości jednego nadawcy. */
|
|
15
22
|
groupGapMs?: number;
|
|
16
|
-
/** `id` pierwszej nieprzeczytanej wiadomości
|
|
23
|
+
/** `id` pierwszej nieprzeczytanej wiadomości - nad nią stanie dzielnik. */
|
|
17
24
|
unreadFrom?: string | null;
|
|
18
25
|
/** Brak połączenia: pasek u góry listy z liczbą wiadomości czekających na wysłanie. */
|
|
19
26
|
offline?: boolean;
|
|
@@ -31,23 +38,23 @@ export interface KptChatProps<T = unknown> extends Omit<ComponentPropsWithRef<'d
|
|
|
31
38
|
onReply?: (message: KptChatMessageModel<T>) => void;
|
|
32
39
|
onReact?: (event: KptChatReactEvent<T>) => void;
|
|
33
40
|
onQuoted?: (quote: KptChatReplyRef) => void;
|
|
34
|
-
/** Przewinięcie na sam szczyt
|
|
41
|
+
/** Przewinięcie na sam szczyt - moment na dociągnięcie starszych wiadomości. */
|
|
35
42
|
onLoadMore?: () => void;
|
|
36
|
-
/** Szablon treści bąbla
|
|
43
|
+
/** Szablon treści bąbla - odpowiednik `<ng-template let-message>` z Angulara. */
|
|
37
44
|
renderMessage?: (message: KptChatMessageModel<T>, row: KptChatMessageRow<T>) => ReactNode;
|
|
38
45
|
}
|
|
39
46
|
/**
|
|
40
|
-
* Lista rozmowy
|
|
47
|
+
* Lista rozmowy - grupuje wiadomości, wstawia separatory dni i dzielnik nieprzeczytanych,
|
|
41
48
|
* trzyma widok przy dole i pokazuje pasek offline z liczbą wiadomości czekających na wysłanie.
|
|
42
49
|
*
|
|
43
50
|
* Sama logika wierszy mieszka w `@konce-pt/chat` (`buildChatRows`), więc port Angulara liczy ją
|
|
44
51
|
* tak samo. Komponent nie ma nic wspólnego z transportem: wiadomości dostaje, a `onRetry`
|
|
45
|
-
* i `onLoadMore` tylko zgłasza
|
|
52
|
+
* i `onLoadMore` tylko zgłasza - ponowieniem wysyłki i dociąganiem historii zajmuje się aplikacja.
|
|
46
53
|
*
|
|
47
|
-
* Kompozytor (`KptChatComposer`) jest osobnym komponentem i stoi obok listy
|
|
54
|
+
* Kompozytor (`KptChatComposer`) jest osobnym komponentem i stoi obok listy - dzięki temu
|
|
48
55
|
* czat bez pola wpisywania (podgląd, archiwum) nie wozi go ze sobą.
|
|
49
56
|
*
|
|
50
57
|
* @example
|
|
51
58
|
* <KptChat messages={messages} currentUser="me" typing={typing} onRetry={resend} />
|
|
52
59
|
*/
|
|
53
|
-
export declare function KptChat<T = unknown>({ messages, currentUser, groupGapMs, unreadFrom, offline, typing, autoScroll, actions, reactionOptions, emptyLabel, onRetry, onReply, onReact, onQuoted, onLoadMore, renderMessage, locale, dictionary, className, ...rest }: Readonly<KptChatProps<T>>): import("react").JSX.Element;
|
|
60
|
+
export declare function KptChat<T = unknown>({ messages, currentUser, groupGapMs, unreadFrom, offline, typing, autoScroll, actions, reactionOptions, emptyLabel, enterMotion, onRetry, onReply, onReact, onQuoted, onLoadMore, renderMessage, locale, dictionary, className, ...rest }: Readonly<KptChatProps<T>>): import("react").JSX.Element;
|
package/dist/chat/chat.js
CHANGED
|
@@ -2,34 +2,36 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useCallback, useEffect, useEffectEvent, useLayoutEffect, useRef, useState } from 'react';
|
|
4
4
|
import { KPT_CHAT_GROUP_GAP_MS, KPT_CHAT_REACTIONS, buildChatRows, chatDayIndicator, pendingCount } from '@konce-pt/chat';
|
|
5
|
+
import { playEnterMotion, resolveEnterMotion } from '@konce-pt/motion';
|
|
5
6
|
import { cn } from "../internal/cn.js";
|
|
6
7
|
import { useKptMessages } from "../i18n/i18n-context.js";
|
|
7
8
|
import { KptIcon } from "../icon/icon.js";
|
|
8
9
|
import { KptChatMessage } from "../chat-message/chat-message.js";
|
|
9
10
|
import { KptChatTyping } from "../chat-typing/chat-typing.js";
|
|
11
|
+
import { useKptMotion } from "../motion/motion-context.js";
|
|
10
12
|
/** Odległość od dołu (px), przy której listę uznajemy jeszcze za przypiętą. */
|
|
11
13
|
const PIN_THRESHOLD = 48;
|
|
12
14
|
/**
|
|
13
15
|
* Wiersze, które nie mogą znaleźć się pod pływającą pigułką dnia: separatory i komunikaty
|
|
14
|
-
* systemowe, czyli wszystko wyśrodkowane, co czyta się jak jej bliźniak. Bąble są poza listą
|
|
16
|
+
* systemowe, czyli wszystko wyśrodkowane, co czyta się jak jej bliźniak. Bąble są poza listą -
|
|
15
17
|
* pigułka nad wypowiedzią to normalny obrazek czatu.
|
|
16
18
|
*/
|
|
17
19
|
const BLOCKING_ROWS = '.kpt-chat__date, .kpt-chat__unread, .kpt-chat-message__system';
|
|
18
20
|
/**
|
|
19
|
-
* Lista rozmowy
|
|
21
|
+
* Lista rozmowy - grupuje wiadomości, wstawia separatory dni i dzielnik nieprzeczytanych,
|
|
20
22
|
* trzyma widok przy dole i pokazuje pasek offline z liczbą wiadomości czekających na wysłanie.
|
|
21
23
|
*
|
|
22
24
|
* Sama logika wierszy mieszka w `@konce-pt/chat` (`buildChatRows`), więc port Angulara liczy ją
|
|
23
25
|
* tak samo. Komponent nie ma nic wspólnego z transportem: wiadomości dostaje, a `onRetry`
|
|
24
|
-
* i `onLoadMore` tylko zgłasza
|
|
26
|
+
* i `onLoadMore` tylko zgłasza - ponowieniem wysyłki i dociąganiem historii zajmuje się aplikacja.
|
|
25
27
|
*
|
|
26
|
-
* Kompozytor (`KptChatComposer`) jest osobnym komponentem i stoi obok listy
|
|
28
|
+
* Kompozytor (`KptChatComposer`) jest osobnym komponentem i stoi obok listy - dzięki temu
|
|
27
29
|
* czat bez pola wpisywania (podgląd, archiwum) nie wozi go ze sobą.
|
|
28
30
|
*
|
|
29
31
|
* @example
|
|
30
32
|
* <KptChat messages={messages} currentUser="me" typing={typing} onRetry={resend} />
|
|
31
33
|
*/
|
|
32
|
-
export function KptChat({ messages = [], currentUser = '', groupGapMs = KPT_CHAT_GROUP_GAP_MS, unreadFrom = null, offline = false, typing = [], autoScroll = true, actions = false, reactionOptions = KPT_CHAT_REACTIONS, emptyLabel = '', onRetry, onReply, onReact, onQuoted, onLoadMore, renderMessage, locale, dictionary, className, ...rest }) {
|
|
34
|
+
export function KptChat({ messages = [], currentUser = '', groupGapMs = KPT_CHAT_GROUP_GAP_MS, unreadFrom = null, offline = false, typing = [], autoScroll = true, actions = false, reactionOptions = KPT_CHAT_REACTIONS, emptyLabel = '', enterMotion, onRetry, onReply, onReact, onQuoted, onLoadMore, renderMessage, locale, dictionary, className, ...rest }) {
|
|
33
35
|
const { t, locale: activeLocale } = useKptMessages({ locale, dictionary });
|
|
34
36
|
const viewportRef = useRef(null);
|
|
35
37
|
const dayRef = useRef(null);
|
|
@@ -37,16 +39,17 @@ export function KptChat({ messages = [], currentUser = '', groupGapMs = KPT_CHAT
|
|
|
37
39
|
const [pinned, setPinned] = useState(true);
|
|
38
40
|
/** Ile wiadomości przyszło, odkąd użytkownik odjechał w górę. */
|
|
39
41
|
const [newCount, setNewCount] = useState(0);
|
|
40
|
-
/** Tekst pływającej pigułki dnia
|
|
42
|
+
/** Tekst pływającej pigułki dnia - zostaje po zgaszeniu, żeby jej pas nie zmieniał wysokości. */
|
|
41
43
|
const [dayLabel, setDayLabel] = useState('');
|
|
42
44
|
/** Czy pigułka dnia jest widoczna. */
|
|
43
45
|
const [dayVisible, setDayVisible] = useState(false);
|
|
44
46
|
const lastCount = useRef(0);
|
|
45
47
|
const wasAtTop = useRef(false);
|
|
46
48
|
const rows = buildChatRows(messages, { currentUserId: currentUser, gapMs: groupGapMs, unreadFrom });
|
|
49
|
+
const motion = resolveEnterMotion(enterMotion, useKptMotion());
|
|
47
50
|
const pending = pendingCount(messages);
|
|
48
51
|
/**
|
|
49
|
-
* Ustawia tekst pływającej pigułki dnia
|
|
52
|
+
* Ustawia tekst pływającej pigułki dnia - co ma na niej być, liczy `chatDayIndicator`
|
|
50
53
|
* z `@konce-pt/chat`, tutaj zostaje czytanie prostokątów i przepisanie etykiety.
|
|
51
54
|
*
|
|
52
55
|
* Wszystkie pomiary idą przed zapisem stanu, więc przeglądarka przelicza układ raz
|
|
@@ -81,11 +84,30 @@ export function KptChat({ messages = [], currentUser = '', groupGapMs = KPT_CHAT
|
|
|
81
84
|
const firstIdRef = useRef(null);
|
|
82
85
|
const prevScrollHeight = useRef(0);
|
|
83
86
|
const dayFrame = useRef(0);
|
|
84
|
-
// Wartości czytane w efekcie listy, ale nieuruchamiające go
|
|
87
|
+
// Wartości czytane w efekcie listy, ale nieuruchamiające go - przez zdarzenia efektu.
|
|
85
88
|
const autoScrollOnNew = useEffectEvent(() => autoScroll);
|
|
86
89
|
const pinnedNow = useEffectEvent(() => pinned);
|
|
87
90
|
const bumpNewCount = useEffectEvent((added) => setNewCount((value) => value + added));
|
|
88
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Wejście wiadomości doklejonych na dole: własna wyrasta od pola pisania, cudza wchodzi od strony
|
|
93
|
+
* nadawcy. Pierwsze wejście i starsze doczytane na górze się nie ruszają - to nie są nowości.
|
|
94
|
+
*/
|
|
95
|
+
const playEntered = useEffectEvent((viewport, added) => {
|
|
96
|
+
if (motion === 'none')
|
|
97
|
+
return;
|
|
98
|
+
const hosts = viewport.querySelectorAll(':scope > .kpt-chat-message-host');
|
|
99
|
+
const messageRows = rows.filter((row) => row.kind === 'message');
|
|
100
|
+
const count = Math.min(added, 5, hosts.length);
|
|
101
|
+
for (let k = 0; k < count; k++) {
|
|
102
|
+
const index = hosts.length - count + k;
|
|
103
|
+
const row = messageRows[index];
|
|
104
|
+
const host = hosts[index];
|
|
105
|
+
if (!row || !host || row.kind !== 'message')
|
|
106
|
+
continue;
|
|
107
|
+
playEnterMotion(host, motion, row.own ? 'below' : 'start', k * 40);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
// Dosunięcie liczone po ułożeniu, nie po malowaniu - inaczej widać skok listy.
|
|
89
111
|
useLayoutEffect(() => {
|
|
90
112
|
if (!viewportRef.current)
|
|
91
113
|
return;
|
|
@@ -94,7 +116,7 @@ export function KptChat({ messages = [], currentUser = '', groupGapMs = KPT_CHAT
|
|
|
94
116
|
const added = count - lastCount.current;
|
|
95
117
|
const first = lastCount.current === 0;
|
|
96
118
|
const firstId = messages[0]?.id ?? null;
|
|
97
|
-
// Starsze wiadomości doklejone na górze (`onLoadMore`)
|
|
119
|
+
// Starsze wiadomości doklejone na górze (`onLoadMore`) - nie są nowe, a widok ma zostać w miejscu.
|
|
98
120
|
const prepended = !first && added > 0 && firstId !== firstIdRef.current;
|
|
99
121
|
lastCount.current = count;
|
|
100
122
|
firstIdRef.current = firstId;
|
|
@@ -108,14 +130,16 @@ export function KptChat({ messages = [], currentUser = '', groupGapMs = KPT_CHAT
|
|
|
108
130
|
prevScrollHeight.current = element.scrollHeight;
|
|
109
131
|
if (added <= 0)
|
|
110
132
|
return;
|
|
111
|
-
|
|
133
|
+
if (!first)
|
|
134
|
+
playEntered(element, added);
|
|
135
|
+
// Pierwsze wejście zawsze ląduje na dole - rozmowę czyta się od końca.
|
|
112
136
|
if (first || (autoScrollOnNew() && pinnedNow()))
|
|
113
137
|
scrollToBottom(first ? 'auto' : undefined);
|
|
114
|
-
// Tyle, ile naprawdę przyszło
|
|
138
|
+
// Tyle, ile naprawdę przyszło - paczka pięciu wiadomości to "5 nowych", nie "1".
|
|
115
139
|
else
|
|
116
140
|
bumpNewCount(added);
|
|
117
141
|
}, [messages]);
|
|
118
|
-
// Po każdej zmianie listy wiersze stoją gdzie indziej
|
|
142
|
+
// Po każdej zmianie listy wiersze stoją gdzie indziej - pigułkę trzeba przeliczyć, inaczej
|
|
119
143
|
// pokazywałaby dzień sprzed dojścia nowej wiadomości.
|
|
120
144
|
useEffect(() => {
|
|
121
145
|
syncDay();
|
|
@@ -135,7 +159,7 @@ export function KptChat({ messages = [], currentUser = '', groupGapMs = KPT_CHAT
|
|
|
135
159
|
setPinned(atBottom);
|
|
136
160
|
if (atBottom)
|
|
137
161
|
setNewCount(0);
|
|
138
|
-
// `onLoadMore` tylko na wejściu w strefę szczytu
|
|
162
|
+
// `onLoadMore` tylko na wejściu w strefę szczytu - przy każdym zdarzeniu scroll
|
|
139
163
|
// aplikacja dostawałaby dziesiątki żądań na jedno przewinięcie.
|
|
140
164
|
const atTop = element.scrollTop < PIN_THRESHOLD;
|
|
141
165
|
if (atTop && !wasAtTop.current)
|
|
@@ -155,8 +179,8 @@ export function KptChat({ messages = [], currentUser = '', groupGapMs = KPT_CHAT
|
|
|
155
179
|
scrollToBottom();
|
|
156
180
|
};
|
|
157
181
|
/**
|
|
158
|
-
* Etykieta separatora dnia. Rdzeń zwraca rodzaj, słownik daje
|
|
159
|
-
* a nazwę dnia i pełną datę
|
|
182
|
+
* Etykieta separatora dnia. Rdzeń zwraca rodzaj, słownik daje "dziś"/"wczoraj",
|
|
183
|
+
* a nazwę dnia i pełną datę - `Intl`, żeby nie trzymać w słowniku kalendarza.
|
|
160
184
|
*/
|
|
161
185
|
const dateText = (label) => {
|
|
162
186
|
switch (label.kind) {
|
|
@@ -176,7 +200,7 @@ export function KptChat({ messages = [], currentUser = '', groupGapMs = KPT_CHAT
|
|
|
176
200
|
};
|
|
177
201
|
return (_jsxs("div", { className: cn('kpt-chat-host', className), ...rest, children: [offline ? (_jsxs("p", { className: "kpt-chat__offline", role: "status", children: [_jsx(KptIcon, { name: "alert-triangle" }), _jsx("span", { children: t('chat.offline') }), pending ? (_jsx("span", { className: "kpt-chat__offline-count", children: t('chat.pending', { count: pending }) })) : null] })) : null, _jsxs("div", { className: "kpt-chat__body", children: [_jsxs("div", { ref: viewportRef, className: "kpt-chat__viewport", role: "log", "aria-live": "polite", "aria-relevant": "additions",
|
|
178
202
|
// Przewijana historia musi być osiągalna z klawiatury także bez fokusowalnych bąbli.
|
|
179
|
-
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- przewijany region musi być osiągalny z klawiatury (WCAG 2.1.1)
|
|
203
|
+
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- przewijany region musi być osiągalny z klawiatury (WCAG 2.1.1) - role="log" nie jest interaktywna, przewijanie tak
|
|
180
204
|
tabIndex: 0, "aria-label": t('chat.history'), onScroll: (event) => onScroll(event.currentTarget), children: [rows.length === 0 ? (_jsx("p", { className: "kpt-chat__empty", children: emptyLabel || t('chat.empty') })) : null, rows.map((row) => {
|
|
181
205
|
if (row.kind === 'date') {
|
|
182
206
|
const label = dateText(row.label);
|
|
@@ -185,6 +209,6 @@ export function KptChat({ messages = [], currentUser = '', groupGapMs = KPT_CHAT
|
|
|
185
209
|
if (row.kind === 'unread') {
|
|
186
210
|
return (_jsx("p", { className: "kpt-chat__unread", role: "separator", "aria-label": t('chat.newMessages', { count: row.count }), children: _jsx("span", { children: t('chat.unread') }) }, row.key));
|
|
187
211
|
}
|
|
188
|
-
return (_jsx(KptChatMessage, { message: row.message, text: renderMessage ? '' : null, align: row.own ? 'end' : 'start', position: row.position, showAuthor: row.showAuthor, showAvatar: row.showAvatar, showMeta: row.showMeta, actions: actions, reactionOptions: reactionOptions, locale: locale, dictionary: dictionary, onRetry: () => onRetry?.(row.message), onReply: () => onReply?.(row.message), onReact: (emoji) => onReact?.({ message: row.message, emoji }), onQuoted: (quote) => onQuoted?.(quote), children: renderMessage ? renderMessage(row.message, row) : null }, row.key));
|
|
212
|
+
return (_jsx(KptChatMessage, { message: row.message, text: renderMessage ? '' : null, align: row.own ? 'end' : 'start', position: row.position, showAuthor: row.showAuthor, showAvatar: row.showAvatar, showMeta: row.showMeta, actions: actions, reactionOptions: reactionOptions, enterMotion: motion, locale: locale, dictionary: dictionary, onRetry: () => onRetry?.(row.message), onReply: () => onReply?.(row.message), onReact: (emoji) => onReact?.({ message: row.message, emoji }), onQuoted: (quote) => onQuoted?.(quote), children: renderMessage ? renderMessage(row.message, row) : null }, row.key));
|
|
189
213
|
}), typing.length ? (_jsx("div", { "aria-live": "off", children: _jsx(KptChatTyping, { authors: typing, locale: locale, dictionary: dictionary }) })) : null] }), _jsx("p", { ref: dayRef, className: "kpt-chat__day", "aria-hidden": "true", "data-hidden": dayVisible ? undefined : '', children: dayLabel }), newCount ? (_jsxs("button", { type: "button", className: "kpt-chat__jump", onClick: jumpToLatest, children: [_jsx(KptIcon, { name: "arrow-down" }), t('chat.newMessages', { count: newCount })] })) : null] })] }));
|
|
190
214
|
}
|