prime-ui-kit 0.16.0 → 0.18.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 +15 -18
- package/dist/chunks/{chunk-A7OQWH6R.js → chunk-IVS3J7AS.js} +1 -1
- package/dist/chunks/{chunk-6TPHKCUJ.js → chunk-MB4CXSLL.js} +27732 -26723
- package/dist/chunks/{chunk-4PSQ64S4.js → chunk-OAXJWF3L.js} +6818 -6264
- package/dist/chunks/{chunk-U3Q2I3MY.js → chunk-QFHE5GKW.js} +3 -2
- package/dist/chunks/{chunk-HDBQICPW.js → chunk-X3JT5CLR.js} +60 -20
- package/dist/color-picker.d.ts +1 -1
- package/dist/color-picker.js +3 -3
- package/dist/components/badge/Badge.d.ts +17 -0
- package/dist/components/breadcrumb/Breadcrumb.d.ts +12 -3
- package/dist/components/button/Button.d.ts +1 -1
- package/dist/components/button-group/ButtonGroup.d.ts +1 -1
- package/dist/components/card/Card.d.ts +8 -4
- package/dist/components/chart-frame/ChartFrame.d.ts +1 -1
- package/dist/components/chat/Chat.d.ts +3 -3
- package/dist/components/chat/ChatRows.d.ts +5 -1
- package/dist/components/chat/MessageList.d.ts +5 -1
- package/dist/components/chat/groupMessages.d.ts +12 -4
- package/dist/components/chat-list/ChatList.d.ts +18 -9
- package/dist/components/chat-list/formatChatTime.d.ts +3 -3
- package/dist/components/checkbox/Checkbox.d.ts +6 -1
- package/dist/components/color-field/ColorField.d.ts +1 -1
- package/dist/components/color-picker/ColorPicker.d.ts +23 -1
- package/dist/components/color-picker/ColorPresets.d.ts +9 -1
- package/dist/components/crossfade/Crossfade.d.ts +1 -1
- package/dist/components/data-table/DataTable.d.ts +3 -1
- package/dist/components/data-table/Head.d.ts +3 -1
- package/dist/components/data-table/types.d.ts +5 -0
- package/dist/components/digit-input/DigitInput.d.ts +1 -1
- package/dist/components/drawer/Drawer.d.ts +3 -2
- package/dist/components/field-list/FieldList.d.ts +18 -6
- package/dist/components/hint/Hint.d.ts +8 -2
- package/dist/components/index.d.ts +6 -7
- package/dist/components/input/Input.d.ts +27 -5
- package/dist/components/input/inputSuggestions.d.ts +39 -0
- package/dist/components/kanban/Kanban.d.ts +4 -9
- package/dist/components/list/List.d.ts +19 -5
- package/dist/components/message/Message.d.ts +15 -3
- package/dist/components/message/MessageSticker.d.ts +27 -0
- package/dist/components/message/formatMessageTime.d.ts +5 -2
- package/dist/components/modal/Modal.d.ts +3 -2
- package/dist/components/native-select/NativeSelect.d.ts +1 -1
- package/dist/components/pagination/Pagination.d.ts +5 -1
- package/dist/components/popover/Popover.d.ts +1 -1
- package/dist/components/radio/Radio.d.ts +11 -2
- package/dist/components/rich-text/RichText.d.ts +23 -0
- package/dist/components/scroll-container/ScrollContainer.d.ts +1 -1
- package/dist/components/scroll-container/scrollGlide.d.ts +26 -0
- package/dist/components/scroll-container/useScrollMotion.d.ts +25 -0
- package/dist/components/segmented-control/SegmentedControl.d.ts +1 -1
- package/dist/components/select/selectContext.d.ts +7 -0
- package/dist/components/slider/Slider.d.ts +2 -2
- package/dist/components/smart-filter/SmartFilter.d.ts +4 -5
- package/dist/components/switch/Switch.d.ts +6 -1
- package/dist/components/tag-select/TagSelect.d.ts +1 -1
- package/dist/components/textarea/Textarea.d.ts +6 -1
- package/dist/components/timeline/Timeline.d.ts +1 -1
- package/dist/icon-set.js +2 -2
- package/dist/index.css +1 -1
- package/dist/index.js +7 -9
- package/dist/internal/ChoiceField.d.ts +3 -1
- package/dist/internal/FieldFrame.d.ts +8 -2
- package/dist/internal/barPlan.d.ts +44 -0
- package/dist/internal/fieldCell.d.ts +1 -1
- package/dist/internal/formatClock.d.ts +23 -2
- package/dist/internal/leaveGuard.d.ts +21 -0
- package/dist/internal/messageList.d.ts +2 -0
- package/dist/internal/overlay/DialogParts.d.ts +27 -2
- package/dist/internal/overlay/FloatingPanel.d.ts +1 -1
- package/dist/internal/overlay/focus.d.ts +3 -2
- package/dist/internal/parts.d.ts +1 -1
- package/dist/internal/slot.d.ts +0 -30
- package/dist/internal/swatch.d.ts +5 -0
- package/dist/internal/tokenDefaults.d.ts +1 -0
- package/dist/layout/app-shell/AppShell.d.ts +19 -38
- package/dist/layout/index.d.ts +3 -3
- package/dist/layout/page/Page.d.ts +302 -0
- package/dist/layout/sidebar/Sidebar.d.ts +1 -1
- package/dist/skill/SKILL.md +10 -10
- package/dist/skill/anti-slop.md +106 -5
- package/dist/skill/api-contract.md +15 -8
- package/dist/skill/cheatsheet.md +46 -26
- package/dist/skill/checklist.md +12 -3
- package/dist/skill/choosing.md +34 -20
- package/dist/skill/components.md +4 -5
- package/dist/skill/composition.md +193 -154
- package/dist/skill/foundations.md +9 -9
- package/dist/skill/layouts.md +42 -99
- package/dist/skill/reference/components/avatar/COMPONENT.md +2 -2
- package/dist/skill/reference/components/avatar/examples/team-group.tsx +1 -1
- package/dist/skill/reference/components/badge/COMPONENT.md +14 -1
- package/dist/skill/reference/components/badge/examples/examples.module.css +7 -0
- package/dist/skill/reference/components/badge/examples/tag-row.tsx +34 -0
- package/dist/skill/reference/components/banner/COMPONENT.md +4 -4
- package/dist/skill/reference/components/banner/examples/examples.module.css +6 -1
- package/dist/skill/reference/components/banner/examples/page-strip.tsx +24 -22
- package/dist/skill/reference/components/breadcrumb/COMPONENT.md +18 -12
- package/dist/skill/reference/components/breadcrumb/examples/router.tsx +17 -0
- package/dist/skill/reference/components/button/COMPONENT.md +2 -1
- package/dist/skill/reference/components/button/examples/hold-to-confirm.tsx +1 -1
- package/dist/skill/reference/components/button/examples/on-colored-host.tsx +8 -8
- package/dist/skill/reference/components/button-group/COMPONENT.md +1 -0
- package/dist/skill/reference/components/card/COMPONENT.md +14 -8
- package/dist/skill/reference/components/card/examples/screen.module.css +1 -1
- package/dist/skill/reference/components/card/examples/screen.tsx +184 -198
- package/dist/skill/reference/components/card/examples/states.tsx +59 -0
- package/dist/skill/reference/components/chart-frame/COMPONENT.md +1 -1
- package/dist/skill/reference/components/chart-frame/examples/fill-height.tsx +9 -9
- package/dist/skill/reference/components/chat/COMPONENT.md +8 -5
- package/dist/skill/reference/components/chat/examples/screen.module.css +1 -1
- package/dist/skill/reference/components/chat/examples/screen.tsx +110 -117
- package/dist/skill/reference/components/chat/examples/time-zone.tsx +83 -0
- package/dist/skill/reference/components/chat-list/COMPONENT.md +14 -8
- package/dist/skill/reference/components/chat-list/examples/controlled.tsx +2 -2
- package/dist/skill/reference/components/chat-list/examples/examples.module.css +8 -0
- package/dist/skill/reference/components/chat-list/examples/links.tsx +1 -1
- package/dist/skill/reference/components/chat-list/examples/router.tsx +63 -0
- package/dist/skill/reference/components/checkbox/COMPONENT.md +1 -0
- package/dist/skill/reference/components/checkbox/examples/examples.module.css +3 -2
- package/dist/skill/reference/components/code-block/COMPONENT.md +1 -1
- package/dist/skill/reference/components/code-block/examples/color-scheme.tsx +2 -4
- package/dist/skill/reference/components/code-block/examples/examples.module.css +0 -11
- package/dist/skill/reference/components/color-field/COMPONENT.md +2 -1
- package/dist/skill/reference/components/color-picker/COMPONENT.md +31 -11
- package/dist/skill/reference/components/color-picker/examples/examples.module.css +2 -5
- package/dist/skill/reference/components/color-picker/examples/overview.tsx +5 -10
- package/dist/skill/reference/components/color-picker/examples/presets-custom.tsx +31 -0
- package/dist/skill/reference/components/color-picker/examples/sizes.tsx +4 -8
- package/dist/skill/reference/components/color-swatches/COMPONENT.md +1 -0
- package/dist/skill/reference/components/crossfade/COMPONENT.md +3 -3
- package/dist/skill/reference/components/crossfade/examples/screen.tsx +107 -112
- package/dist/skill/reference/components/data-table/COMPONENT.md +12 -7
- package/dist/skill/reference/components/data-table/examples/examples.module.css +9 -0
- package/dist/skill/reference/components/data-table/examples/numeric.tsx +9 -2
- package/dist/skill/reference/components/data-table/examples/screen.tsx +42 -52
- package/dist/skill/reference/components/data-table/examples/server.tsx +6 -2
- package/dist/skill/reference/components/datepicker/COMPONENT.md +3 -1
- package/dist/skill/reference/components/datepicker/examples/deadline.tsx +33 -0
- package/dist/skill/reference/components/datepicker/examples/examples.module.css +6 -0
- package/dist/skill/reference/components/datepicker/examples/inline-panel.tsx +3 -1
- package/dist/skill/reference/components/description-list/COMPONENT.md +1 -1
- package/dist/skill/reference/components/description-list/examples/screen.tsx +120 -127
- package/dist/skill/reference/components/digit-input/COMPONENT.md +1 -0
- package/dist/skill/reference/components/digit-input/examples/grouped.tsx +4 -4
- package/dist/skill/reference/components/digit-input/examples/validation.tsx +1 -1
- package/dist/skill/reference/components/divider/COMPONENT.md +2 -2
- package/dist/skill/reference/components/divider/examples/examples.module.css +4 -1
- package/dist/skill/reference/components/divider/examples/vertical.tsx +22 -9
- package/dist/skill/reference/components/dnd/examples/examples.module.css +3 -1
- package/dist/skill/reference/components/drawer/COMPONENT.md +16 -3
- package/dist/skill/reference/components/drawer/examples/client-card.tsx +32 -8
- package/dist/skill/reference/components/drawer/examples/placement.tsx +26 -31
- package/dist/skill/reference/components/drawer/examples/screen.tsx +137 -160
- package/dist/skill/reference/components/dropdown/COMPONENT.md +1 -1
- package/dist/skill/reference/components/example-frame/COMPONENT.md +3 -3
- package/dist/skill/reference/components/field-list/COMPONENT.md +15 -3
- package/dist/skill/reference/components/field-list/examples/saving.tsx +83 -0
- package/dist/skill/reference/components/field-list/examples/screen.module.css +1 -1
- package/dist/skill/reference/components/field-list/examples/screen.tsx +19 -19
- package/dist/skill/reference/components/field-list/examples/totals.tsx +82 -0
- package/dist/skill/reference/components/fieldset/COMPONENT.md +1 -1
- package/dist/skill/reference/components/fieldset/examples/states.tsx +1 -1
- package/dist/skill/reference/components/file-upload/COMPONENT.md +2 -1
- package/dist/skill/reference/components/file-upload/examples/screen.module.css +2 -2
- package/dist/skill/reference/components/file-upload/examples/screen.tsx +65 -81
- package/dist/skill/reference/components/gallery/COMPONENT.md +1 -0
- package/dist/skill/reference/components/gantt/COMPONENT.md +1 -1
- package/dist/skill/reference/components/gantt/examples/screen.module.css +1 -1
- package/dist/skill/reference/components/gantt/examples/screen.tsx +55 -73
- package/dist/skill/reference/components/hint/COMPONENT.md +16 -2
- package/dist/skill/reference/components/hint/examples/examples.module.css +10 -1
- package/dist/skill/reference/components/hint/examples/overview.tsx +1 -1
- package/dist/skill/reference/components/hint/examples/variants.tsx +48 -0
- package/dist/skill/reference/components/input/COMPONENT.md +39 -9
- package/dist/skill/reference/components/input/examples/affixes.tsx +4 -2
- package/dist/skill/reference/components/input/examples/dismiss.tsx +29 -0
- package/dist/skill/reference/components/input/examples/suggestions.tsx +26 -0
- package/dist/skill/reference/components/input/examples/time.tsx +24 -0
- package/dist/skill/reference/components/input/examples/with-select.tsx +44 -0
- package/dist/skill/reference/components/kanban/COMPONENT.md +7 -7
- package/dist/skill/reference/components/kanban/examples/columns.tsx +4 -2
- package/dist/skill/reference/components/kanban/examples/screen.module.css +1 -1
- package/dist/skill/reference/components/kanban/examples/screen.tsx +50 -65
- package/dist/skill/reference/components/kbd/COMPONENT.md +1 -1
- package/dist/skill/reference/components/label/examples/examples.module.css +12 -1
- package/dist/skill/reference/components/label/examples/overview.tsx +1 -1
- package/dist/skill/reference/components/list/COMPONENT.md +26 -10
- package/dist/skill/reference/components/list/examples/row-controls.tsx +80 -0
- package/dist/skill/reference/components/list/examples/with-icon.tsx +23 -2
- package/dist/skill/reference/components/login-form/COMPONENT.md +8 -7
- package/dist/skill/reference/components/login-form/examples/states.tsx +12 -14
- package/dist/skill/reference/components/media-viewer/examples/controlled.tsx +16 -16
- package/dist/skill/reference/components/media-viewer/examples/examples.module.css +1 -3
- package/dist/skill/reference/components/message/COMPONENT.md +30 -9
- package/dist/skill/reference/components/message/examples/preview.tsx +28 -0
- package/dist/skill/reference/components/message/examples/sticker.tsx +35 -0
- package/dist/skill/reference/components/modal/COMPONENT.md +15 -3
- package/dist/skill/reference/components/modal/examples/long-content.tsx +37 -18
- package/dist/skill/reference/components/native-select/COMPONENT.md +1 -0
- package/dist/skill/reference/components/notification/COMPONENT.md +1 -1
- package/dist/skill/reference/components/pagination/COMPONENT.md +11 -3
- package/dist/skill/reference/components/pagination/examples/controlled.tsx +2 -1
- package/dist/skill/reference/components/popover/COMPONENT.md +3 -2
- package/dist/skill/reference/components/popover/examples/width.tsx +13 -1
- package/dist/skill/reference/components/radio/COMPONENT.md +2 -0
- package/dist/skill/reference/components/rich-text/COMPONENT.md +93 -0
- package/dist/skill/reference/components/rich-text/examples/overview.tsx +19 -0
- package/dist/skill/reference/components/scroll-container/COMPONENT.md +8 -5
- package/dist/skill/reference/components/segmented-control/COMPONENT.md +1 -0
- package/dist/skill/reference/components/segmented-control/examples/in-form.tsx +1 -1
- package/dist/skill/reference/components/select/COMPONENT.md +7 -3
- package/dist/skill/reference/components/slider/COMPONENT.md +4 -3
- package/dist/skill/reference/components/slider/examples/controlled.tsx +1 -1
- package/dist/skill/reference/components/slider/examples/states.tsx +14 -10
- package/dist/skill/reference/components/smart-filter/COMPONENT.md +13 -13
- package/dist/skill/reference/components/smart-filter/examples/examples.module.css +3 -0
- package/dist/skill/reference/components/smart-filter/examples/many-values.tsx +12 -8
- package/dist/skill/reference/components/smart-filter/examples/sizes.tsx +7 -3
- package/dist/skill/reference/components/sparkline/COMPONENT.md +1 -0
- package/dist/skill/reference/components/sparkline/examples/curve.tsx +16 -11
- package/dist/skill/reference/components/sparkline/examples/states.tsx +14 -10
- package/dist/skill/reference/components/switch/COMPONENT.md +2 -1
- package/dist/skill/reference/components/tabs/COMPONENT.md +1 -1
- package/dist/skill/reference/components/tag-select/COMPONENT.md +1 -0
- package/dist/skill/reference/components/textarea/COMPONENT.md +1 -0
- package/dist/skill/reference/components/timeline/COMPONENT.md +3 -3
- package/dist/skill/reference/components/timeline/examples/structure.tsx +2 -1
- package/dist/skill/reference/components/typography/COMPONENT.md +2 -2
- package/dist/skill/reference/foundation.md +15 -11
- package/dist/skill/reference/layout/app-shell/COMPONENT.md +25 -38
- package/dist/skill/reference/layout/app-shell/examples/footer.tsx +10 -10
- package/dist/skill/reference/layout/app-shell/examples/overview.tsx +20 -22
- package/dist/skill/reference/layout/app-shell/examples/screen.module.css +2 -2
- package/dist/skill/reference/layout/app-shell/examples/screen.tsx +25 -30
- package/dist/skill/reference/layout/app-shell/examples/template.tsx +13 -17
- package/dist/skill/reference/layout/bottom-nav/COMPONENT.md +4 -3
- package/dist/skill/reference/layout/bottom-nav/examples/floating-action.tsx +10 -19
- package/dist/skill/reference/layout/bottom-nav/examples/floating.tsx +10 -19
- package/dist/skill/reference/layout/bottom-nav/examples/in-app-shell.tsx +11 -19
- package/dist/skill/reference/layout/page/COMPONENT.md +382 -0
- package/dist/skill/reference/layout/page/examples/actions-collapse.tsx +45 -0
- package/dist/skill/reference/layout/page/examples/collapse.tsx +68 -0
- package/dist/skill/reference/layout/page/examples/examples.module.css +92 -0
- package/{src/components/page-content → dist/skill/reference/layout/page}/examples/grid.tsx +15 -15
- package/dist/skill/reference/layout/page/examples/guard.tsx +87 -0
- package/dist/skill/reference/{components/page-content → layout/page}/examples/list-detail.tsx +14 -14
- package/dist/skill/reference/layout/page/examples/loading.tsx +57 -0
- package/dist/skill/reference/layout/page/examples/narrow.tsx +75 -0
- package/dist/skill/reference/layout/page/examples/overview.tsx +57 -0
- package/dist/skill/reference/{components/page-content → layout/page}/examples/screen.module.css +1 -1
- package/{src/components/page-content → dist/skill/reference/layout/page}/examples/screen.tsx +29 -19
- package/dist/skill/reference/{components/page-content → layout/page}/examples/sections.tsx +17 -24
- package/dist/skill/reference/layout/page/examples/structure.tsx +41 -0
- package/dist/skill/reference/{components/page-toolbar/examples/narrow.tsx → layout/page/examples/tools.tsx} +38 -35
- package/dist/skill/reference/layout/page/examples/top-bar.tsx +85 -0
- package/dist/skill/reference/{components/page-content → layout/page}/examples/variants.tsx +7 -7
- package/dist/skill/reference/layout/sidebar/COMPONENT.md +6 -4
- package/dist/skill/reference/layout/sidebar/examples/dismiss.tsx +10 -7
- package/dist/skill/reference/layout/sidebar/examples/narrow.tsx +11 -8
- package/dist/skill/responsive.md +94 -75
- package/dist/skill/ux.md +5 -3
- package/dist/tokens/layers.d.ts +2 -0
- package/dist/tokens/primitives.d.ts +12 -2
- package/dist/tokens/semantic.d.ts +9 -0
- package/dist/tokens/themes/dark.d.ts +7 -2
- package/package.json +2 -2
- package/src/components/avatar/COMPONENT.md +2 -2
- package/src/components/avatar/examples/team-group.tsx +1 -1
- package/src/components/badge/COMPONENT.md +14 -1
- package/src/components/badge/examples/examples.module.css +7 -0
- package/src/components/badge/examples/tag-row.tsx +34 -0
- package/src/components/banner/COMPONENT.md +4 -4
- package/src/components/banner/examples/examples.module.css +6 -1
- package/src/components/banner/examples/page-strip.tsx +24 -22
- package/src/components/breadcrumb/COMPONENT.md +18 -12
- package/src/components/breadcrumb/examples/router.tsx +17 -0
- package/src/components/button/COMPONENT.md +2 -1
- package/src/components/button/examples/hold-to-confirm.tsx +1 -1
- package/src/components/button/examples/on-colored-host.tsx +8 -8
- package/src/components/button-group/COMPONENT.md +1 -0
- package/src/components/card/COMPONENT.md +14 -8
- package/src/components/card/examples/screen.module.css +1 -1
- package/src/components/card/examples/screen.tsx +184 -198
- package/src/components/card/examples/states.tsx +59 -0
- package/src/components/chart-frame/COMPONENT.md +1 -1
- package/src/components/chart-frame/examples/fill-height.tsx +9 -9
- package/src/components/chat/COMPONENT.md +8 -5
- package/src/components/chat/examples/screen.module.css +1 -1
- package/src/components/chat/examples/screen.tsx +110 -117
- package/src/components/chat/examples/time-zone.tsx +83 -0
- package/src/components/chat-list/COMPONENT.md +14 -8
- package/src/components/chat-list/examples/controlled.tsx +2 -2
- package/src/components/chat-list/examples/examples.module.css +8 -0
- package/src/components/chat-list/examples/links.tsx +1 -1
- package/src/components/chat-list/examples/router.tsx +63 -0
- package/src/components/checkbox/COMPONENT.md +1 -0
- package/src/components/checkbox/examples/examples.module.css +3 -2
- package/src/components/code-block/COMPONENT.md +1 -1
- package/src/components/code-block/examples/color-scheme.tsx +2 -4
- package/src/components/code-block/examples/examples.module.css +0 -11
- package/src/components/color-field/COMPONENT.md +2 -1
- package/src/components/color-picker/COMPONENT.md +31 -11
- package/src/components/color-picker/examples/examples.module.css +2 -5
- package/src/components/color-picker/examples/overview.tsx +5 -10
- package/src/components/color-picker/examples/presets-custom.tsx +31 -0
- package/src/components/color-picker/examples/sizes.tsx +4 -8
- package/src/components/color-swatches/COMPONENT.md +1 -0
- package/src/components/crossfade/COMPONENT.md +3 -3
- package/src/components/crossfade/examples/screen.tsx +107 -112
- package/src/components/data-table/COMPONENT.md +12 -7
- package/src/components/data-table/examples/examples.module.css +9 -0
- package/src/components/data-table/examples/numeric.tsx +9 -2
- package/src/components/data-table/examples/screen.tsx +42 -52
- package/src/components/data-table/examples/server.tsx +6 -2
- package/src/components/datepicker/COMPONENT.md +3 -1
- package/src/components/datepicker/examples/deadline.tsx +33 -0
- package/src/components/datepicker/examples/examples.module.css +6 -0
- package/src/components/datepicker/examples/inline-panel.tsx +3 -1
- package/src/components/description-list/COMPONENT.md +1 -1
- package/src/components/description-list/examples/screen.tsx +120 -127
- package/src/components/digit-input/COMPONENT.md +1 -0
- package/src/components/digit-input/examples/grouped.tsx +4 -4
- package/src/components/digit-input/examples/validation.tsx +1 -1
- package/src/components/divider/COMPONENT.md +2 -2
- package/src/components/divider/examples/examples.module.css +4 -1
- package/src/components/divider/examples/vertical.tsx +22 -9
- package/src/components/dnd/examples/examples.module.css +3 -1
- package/src/components/drawer/COMPONENT.md +16 -3
- package/src/components/drawer/examples/client-card.tsx +32 -8
- package/src/components/drawer/examples/placement.tsx +26 -31
- package/src/components/drawer/examples/screen.tsx +137 -160
- package/src/components/dropdown/COMPONENT.md +1 -1
- package/src/components/example-frame/COMPONENT.md +3 -3
- package/src/components/field-list/COMPONENT.md +15 -3
- package/src/components/field-list/examples/saving.tsx +83 -0
- package/src/components/field-list/examples/screen.module.css +1 -1
- package/src/components/field-list/examples/screen.tsx +19 -19
- package/src/components/field-list/examples/totals.tsx +82 -0
- package/src/components/fieldset/COMPONENT.md +1 -1
- package/src/components/fieldset/examples/states.tsx +1 -1
- package/src/components/file-upload/COMPONENT.md +2 -1
- package/src/components/file-upload/examples/screen.module.css +2 -2
- package/src/components/file-upload/examples/screen.tsx +65 -81
- package/src/components/gallery/COMPONENT.md +1 -0
- package/src/components/gantt/COMPONENT.md +1 -1
- package/src/components/gantt/examples/screen.module.css +1 -1
- package/src/components/gantt/examples/screen.tsx +55 -73
- package/src/components/hint/COMPONENT.md +16 -2
- package/src/components/hint/examples/examples.module.css +10 -1
- package/src/components/hint/examples/overview.tsx +1 -1
- package/src/components/hint/examples/variants.tsx +48 -0
- package/src/components/input/COMPONENT.md +39 -9
- package/src/components/input/examples/affixes.tsx +4 -2
- package/src/components/input/examples/dismiss.tsx +29 -0
- package/src/components/input/examples/suggestions.tsx +26 -0
- package/src/components/input/examples/time.tsx +24 -0
- package/src/components/input/examples/with-select.tsx +44 -0
- package/src/components/kanban/COMPONENT.md +7 -7
- package/src/components/kanban/examples/columns.tsx +4 -2
- package/src/components/kanban/examples/screen.module.css +1 -1
- package/src/components/kanban/examples/screen.tsx +50 -65
- package/src/components/kbd/COMPONENT.md +1 -1
- package/src/components/label/examples/examples.module.css +12 -1
- package/src/components/label/examples/overview.tsx +1 -1
- package/src/components/list/COMPONENT.md +26 -10
- package/src/components/list/examples/row-controls.tsx +80 -0
- package/src/components/list/examples/with-icon.tsx +23 -2
- package/src/components/login-form/COMPONENT.md +8 -7
- package/src/components/login-form/examples/states.tsx +12 -14
- package/src/components/media-viewer/examples/controlled.tsx +16 -16
- package/src/components/media-viewer/examples/examples.module.css +1 -3
- package/src/components/message/COMPONENT.md +30 -9
- package/src/components/message/examples/preview.tsx +28 -0
- package/src/components/message/examples/sticker.tsx +35 -0
- package/src/components/modal/COMPONENT.md +15 -3
- package/src/components/modal/examples/long-content.tsx +37 -18
- package/src/components/native-select/COMPONENT.md +1 -0
- package/src/components/notification/COMPONENT.md +1 -1
- package/src/components/pagination/COMPONENT.md +11 -3
- package/src/components/pagination/examples/controlled.tsx +2 -1
- package/src/components/popover/COMPONENT.md +3 -2
- package/src/components/popover/examples/width.tsx +13 -1
- package/src/components/radio/COMPONENT.md +2 -0
- package/src/components/rich-text/COMPONENT.md +93 -0
- package/src/components/rich-text/examples/overview.tsx +19 -0
- package/src/components/scroll-container/COMPONENT.md +8 -5
- package/src/components/segmented-control/COMPONENT.md +1 -0
- package/src/components/segmented-control/examples/in-form.tsx +1 -1
- package/src/components/select/COMPONENT.md +7 -3
- package/src/components/slider/COMPONENT.md +4 -3
- package/src/components/slider/examples/controlled.tsx +1 -1
- package/src/components/slider/examples/states.tsx +14 -10
- package/src/components/smart-filter/COMPONENT.md +13 -13
- package/src/components/smart-filter/examples/examples.module.css +3 -0
- package/src/components/smart-filter/examples/many-values.tsx +12 -8
- package/src/components/smart-filter/examples/sizes.tsx +7 -3
- package/src/components/sparkline/COMPONENT.md +1 -0
- package/src/components/sparkline/examples/curve.tsx +16 -11
- package/src/components/sparkline/examples/states.tsx +14 -10
- package/src/components/switch/COMPONENT.md +2 -1
- package/src/components/tabs/COMPONENT.md +1 -1
- package/src/components/tag-select/COMPONENT.md +1 -0
- package/src/components/textarea/COMPONENT.md +1 -0
- package/src/components/timeline/COMPONENT.md +3 -3
- package/src/components/timeline/examples/structure.tsx +2 -1
- package/src/components/typography/COMPONENT.md +2 -2
- package/src/layout/app-shell/COMPONENT.md +25 -38
- package/src/layout/app-shell/examples/footer.tsx +10 -10
- package/src/layout/app-shell/examples/overview.tsx +20 -22
- package/src/layout/app-shell/examples/screen.module.css +2 -2
- package/src/layout/app-shell/examples/screen.tsx +25 -30
- package/src/layout/app-shell/examples/template.tsx +13 -17
- package/src/layout/bottom-nav/COMPONENT.md +4 -3
- package/src/layout/bottom-nav/examples/floating-action.tsx +10 -19
- package/src/layout/bottom-nav/examples/floating.tsx +10 -19
- package/src/layout/bottom-nav/examples/in-app-shell.tsx +11 -19
- package/src/layout/page/COMPONENT.md +382 -0
- package/src/layout/page/examples/actions-collapse.tsx +45 -0
- package/src/layout/page/examples/collapse.tsx +68 -0
- package/src/layout/page/examples/examples.module.css +92 -0
- package/{dist/skill/reference/components/page-content → src/layout/page}/examples/grid.tsx +15 -15
- package/src/layout/page/examples/guard.tsx +87 -0
- package/src/{components/page-content → layout/page}/examples/list-detail.tsx +14 -14
- package/src/layout/page/examples/loading.tsx +57 -0
- package/src/layout/page/examples/narrow.tsx +75 -0
- package/src/layout/page/examples/overview.tsx +57 -0
- package/src/{components/page-content → layout/page}/examples/screen.module.css +1 -1
- package/{dist/skill/reference/components/page-content → src/layout/page}/examples/screen.tsx +29 -19
- package/src/{components/page-content → layout/page}/examples/sections.tsx +17 -24
- package/src/layout/page/examples/structure.tsx +41 -0
- package/src/{components/page-toolbar/examples/narrow.tsx → layout/page/examples/tools.tsx} +38 -35
- package/src/layout/page/examples/top-bar.tsx +85 -0
- package/src/{components/page-content → layout/page}/examples/variants.tsx +7 -7
- package/src/layout/sidebar/COMPONENT.md +6 -4
- package/src/layout/sidebar/examples/dismiss.tsx +10 -7
- package/src/layout/sidebar/examples/narrow.tsx +11 -8
- package/src/styles/theme-dark.css +12 -10
- package/src/styles/theme-light.css +4 -0
- package/src/styles/tokens.css +3 -1
- package/dist/components/page-content/PageContent.d.ts +0 -192
- package/dist/components/page-toolbar/PageToolbar.d.ts +0 -55
- package/dist/components/scroll-container/useWheelToInline.d.ts +0 -10
- package/dist/layout/app-header/AppHeader.d.ts +0 -118
- package/dist/skill/reference/components/page-content/COMPONENT.md +0 -264
- package/dist/skill/reference/components/page-content/examples/examples.module.css +0 -56
- package/dist/skill/reference/components/page-content/examples/narrow.tsx +0 -25
- package/dist/skill/reference/components/page-content/examples/overview.tsx +0 -41
- package/dist/skill/reference/components/page-toolbar/COMPONENT.md +0 -147
- package/dist/skill/reference/components/page-toolbar/examples/examples.module.css +0 -16
- package/dist/skill/reference/components/page-toolbar/examples/overview.tsx +0 -113
- package/dist/skill/reference/components/page-toolbar/examples/save-changes.tsx +0 -43
- package/dist/skill/reference/components/page-toolbar/examples/without-search.tsx +0 -60
- package/dist/skill/reference/layout/app-header/COMPONENT.md +0 -187
- package/dist/skill/reference/layout/app-header/examples/breadcrumbs.tsx +0 -37
- package/dist/skill/reference/layout/app-header/examples/examples.module.css +0 -28
- package/dist/skill/reference/layout/app-header/examples/in-app-shell.tsx +0 -67
- package/dist/skill/reference/layout/app-header/examples/narrow.tsx +0 -66
- package/dist/skill/reference/layout/app-header/examples/overview.tsx +0 -34
- package/dist/skill/reference/layout/app-header/examples/page-title.tsx +0 -78
- package/dist/skill/reference/layout/app-shell/examples/contained.tsx +0 -30
- package/src/components/page-content/COMPONENT.md +0 -264
- package/src/components/page-content/examples/examples.module.css +0 -56
- package/src/components/page-content/examples/narrow.tsx +0 -25
- package/src/components/page-content/examples/overview.tsx +0 -41
- package/src/components/page-toolbar/COMPONENT.md +0 -147
- package/src/components/page-toolbar/examples/examples.module.css +0 -16
- package/src/components/page-toolbar/examples/overview.tsx +0 -113
- package/src/components/page-toolbar/examples/save-changes.tsx +0 -43
- package/src/components/page-toolbar/examples/without-search.tsx +0 -60
- package/src/layout/app-header/COMPONENT.md +0 -187
- package/src/layout/app-header/examples/breadcrumbs.tsx +0 -37
- package/src/layout/app-header/examples/examples.module.css +0 -28
- package/src/layout/app-header/examples/in-app-shell.tsx +0 -67
- package/src/layout/app-header/examples/narrow.tsx +0 -66
- package/src/layout/app-header/examples/overview.tsx +0 -34
- package/src/layout/app-header/examples/page-title.tsx +0 -78
- package/src/layout/app-shell/examples/contained.tsx +0 -30
|
@@ -81,6 +81,7 @@ Chat.Root <div> column, fills its host; owns selection,
|
|
|
81
81
|
- `renderMessage` may be an inline function: an item renders again only when it or its place changes, so whatever a row shows lives in its item (an edit, a reaction, a pin). Another message (a reply's original) comes from `entry.find(key)`.
|
|
82
82
|
- `onRead` reports an incoming message once at least half of it, or half the view, has been on screen while the page is visible (`IntersectionObserver`); batched per frame, each `value` once per mount.
|
|
83
83
|
- One sound at a time on the page: a `VoicePlayer`, a `VideoNote` and a video in `Message.Media` pause each other; nothing to wire.
|
|
84
|
+
- Times in a profile's zone: `timeZone` (an IANA name) on `Chat.Messages` moves the date separators, the runs and every message's time to it; without it they follow the browser.
|
|
84
85
|
|
|
85
86
|
## API
|
|
86
87
|
|
|
@@ -107,7 +108,7 @@ Chat.Root <div> column, fills its host; owns selection,
|
|
|
107
108
|
|
|
108
109
|
| Prop | Type | Default | Description |
|
|
109
110
|
|---|---|---|---|
|
|
110
|
-
| `…rest` | `HTMLAttributes<HTMLDivElement>` | — | `children` (a `
|
|
111
|
+
| `…rest` | `HTMLAttributes<HTMLDivElement>` | — | `children` (a `Page.BackButton`, an `Avatar`, `Chat.Title`, `Chat.Description`, `Chat.Actions`), `className`. |
|
|
111
112
|
|
|
112
113
|
### Chat.Title
|
|
113
114
|
`ref` → `HTMLHeadingElement`. Who the chat is with, one line that ellipsizes; it also names the message list (`aria-labelledby`).
|
|
@@ -174,7 +175,8 @@ Chat.Root <div> column, fills its host; owns selection,
|
|
|
174
175
|
| `unread` | `string` | — | The key of the first unread item: the «Непрочитанные сообщения» band stands above it. |
|
|
175
176
|
| `groupWindow` | `number` | `5` | Messages of one author further apart than this many minutes start a new run. |
|
|
176
177
|
| `now` | `Date` | today | «Today» for the dates. |
|
|
177
|
-
| `
|
|
178
|
+
| `timeZone` | `string` | the browser's zone | The IANA zone of the date separators, the runs and every message time (`"Asia/Vladivostok"`): a profile's zone, not the browser's. |
|
|
179
|
+
| `formatDate` | `(date: Date, now: Date, timeZone?: string) => string` | `formatMessageDate` | The label of a date; gets the `timeZone`. |
|
|
178
180
|
| `loading` | `boolean` | `false` | The first load: bubble-shaped `Skeleton`s on both sides stand in the list's place (`aria-busy`, `labels.loading` announced), then cross-fade into the messages; none of them counts as new. |
|
|
179
181
|
| `hasOlder` | `boolean` | `false` | Older history exists: a bubble-shaped placeholder stands above the first message and `onLoadOlder` runs when the reader reaches the top. |
|
|
180
182
|
| `onLoadOlder` | `() => void \| Promise<void>` | — | Load older messages and prepend them (while `hasOlder`); the reader's place is kept. |
|
|
@@ -193,7 +195,7 @@ Chat.Root <div> column, fills its host; owns selection,
|
|
|
193
195
|
| `…rest` | `HTMLAttributes<HTMLDivElement>` | — | `children` — the actions (`Button.Root size="s"`: Переслать, Удалить), `className`. |
|
|
194
196
|
|
|
195
197
|
### Chat.Separator
|
|
196
|
-
`ref` → `HTMLDivElement`. A date between messages (`items` add them for you) («Сегодня», «12 марта» — `formatMessageDate`): a pill
|
|
198
|
+
`ref` → `HTMLDivElement`. A date between messages (`items` add them for you) («Сегодня», «12 марта» — `formatMessageDate`): a pill a step above the bubbles that stays at the top while its day scrolls, until the next date pushes it out.
|
|
197
199
|
|
|
198
200
|
| Prop | Type | Default | Description |
|
|
199
201
|
|---|---|---|---|
|
|
@@ -308,7 +310,7 @@ Chat.Root <div> column, fills its host; owns selection,
|
|
|
308
310
|
| `newMessages` | `"Новых сообщений: {count}. К последним сообщениям"` | The name of that button while new messages wait below. |
|
|
309
311
|
| `typing` | `"печатает…"` | The status line of the header while the other side types. |
|
|
310
312
|
| `search` | `"Поиск по переписке"` | The search button and the name of the search field. |
|
|
311
|
-
| `searchPlaceholder` | `"Поиск
|
|
313
|
+
| `searchPlaceholder` | `"Поиск"` | The placeholder of the search field. |
|
|
312
314
|
| `matches` | `"{index} из {count}"` | The place of the current match, counted from the newest. |
|
|
313
315
|
| `noMatches` | `"Нет совпадений"` | The search found nothing. |
|
|
314
316
|
| `previousMatch` | `"Предыдущее совпадение"` | The button that goes to the older match. |
|
|
@@ -334,10 +336,11 @@ Chat.Root <div> column, fills its host; owns selection,
|
|
|
334
336
|
| [reactions.tsx](examples/reactions.tsx) | A team's own reactions for approvals: a double tap or `L` puts the approval mark, a long press or `R` opens the team's set, and a chip toggles them back — `quickReaction`, `reactionOptions`, `onReactionToggle`. |
|
|
335
337
|
| [live.tsx](examples/live.tsx) | A live support chat: the client types — the header and the end of the list say so — then answers; new messages enter at the end, read receipts come from what is on screen, and scrolled up the round button counts what arrived — `typing`, `onNewMessage`, `onRead`. |
|
|
336
338
|
| [search.tsx](examples/search.tsx) | Search and pinned messages: the search bar marks every match in the texts and transcripts, counts them and steps between them while the others step back; a pinned message's press jumps to it and blinks it — `Chat.SearchButton`, `Chat.Search`, `defaultSearch`, `Chat.Pinned`. |
|
|
339
|
+
| [time-zone.tsx](examples/time-zone.tsx) | The conversation in the zone of the manager's profile, not the browser's: the date separators, the runs and every time follow it — `timeZone`, `items`, `renderMessage`. |
|
|
337
340
|
| [states.tsx](examples/states.tsx) | The first load of a conversation: bubble-shaped placeholders on both sides stand in the list's place, then cross-fade into the messages — `loading`. |
|
|
338
341
|
| [controlled.tsx](examples/controlled.tsx) | Selection mode owned by the screen: the Select item of a message's menu starts it, a check stands beside every message, a press toggles one while the others step back, the bar counts and acts, Escape leaves — `selected`, `onSelectedChange`, `Chat.SelectionBar`. |
|
|
339
342
|
| [narrow.tsx](examples/narrow.tsx) | At phone width the header keeps its actions and lets the title ellipsize, bubbles take up to 85% of the chat, long links wrap and an album keeps its layout — `Chat.Root`, `Chat.Header`, `Chat.Messages`, `Chat.Footer`. |
|
|
340
|
-
| [screen.tsx](examples/screen.tsx) | A support messenger as a work screen: the title and the unread count in
|
|
343
|
+
| [screen.tsx](examples/screen.tsx) | A support messenger as a work screen: the title and the unread count in its top bar, the dialogs with a search over them beside the conversation (one pane at a time on a phone), history that loads above as you scroll up, the unread band, reply and edit from the menu, the typing signal both ways, unread counts from what was seen, and the Composer whose messages rise into the list while the client answers — `items`, `renderMessage`, `hasOlder`, `onLoadOlder`, `typing`. |
|
|
341
344
|
|
|
342
345
|
## Mistakes
|
|
343
346
|
- A header, a search bar and a scroller of your own around the messages → `Chat.Header`, `Chat.Search`, `Chat.Messages`: the chat wires typing, search, jumps and selection between them.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* Messenger: a work screen — the header carries the title, the page fills the app panel
|
|
2
|
-
(`AppShell.Root fillViewport` + `
|
|
2
|
+
(`AppShell.Root fillViewport` + `Page.Root fill`); each pane is a card with a scrolling
|
|
3
3
|
region. */
|
|
4
4
|
|
|
5
5
|
.paneCard {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
/** A support messenger as a work screen: the title and the unread count in
|
|
1
|
+
/** A support messenger as a work screen: the title and the unread count in its top bar, the dialogs with a search over them beside the conversation (one pane at a time on a phone), history that loads above as you scroll up, the unread band, reply and edit from the menu, the typing signal both ways, unread counts from what was seen, and the Composer whose messages rise into the list while the client answers — `items`, `renderMessage`, `hasOlder`, `onLoadOlder`, `typing`. */
|
|
2
2
|
import {
|
|
3
|
-
AppHeader,
|
|
4
3
|
Avatar,
|
|
5
4
|
Card,
|
|
6
5
|
Chat,
|
|
@@ -16,7 +15,7 @@ import {
|
|
|
16
15
|
Icon,
|
|
17
16
|
Message,
|
|
18
17
|
type MessageStatus,
|
|
19
|
-
|
|
18
|
+
Page,
|
|
20
19
|
type UploadContext,
|
|
21
20
|
useUploadQueue,
|
|
22
21
|
VoicePlayer,
|
|
@@ -573,123 +572,117 @@ export default function ChatScreenExample() {
|
|
|
573
572
|
};
|
|
574
573
|
|
|
575
574
|
return (
|
|
576
|
-
|
|
577
|
-
{/* A work screen
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
<
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
575
|
+
<Page.Root fill>
|
|
576
|
+
{/* A work screen titles itself in its top bar: the only h1 and one line of data. */}
|
|
577
|
+
<Page.TopBar>
|
|
578
|
+
<Page.Heading>
|
|
579
|
+
<Page.Title>Поддержка</Page.Title>
|
|
580
|
+
<Page.Description>{unreadLabel(unreadTotal)}</Page.Description>
|
|
581
|
+
</Page.Heading>
|
|
582
|
+
</Page.TopBar>
|
|
583
|
+
<Page.Body>
|
|
584
|
+
<Page.Split
|
|
585
|
+
open={dialogId !== null}
|
|
586
|
+
onOpenChange={(next) => {
|
|
587
|
+
if (!next) setDialogId(null);
|
|
588
|
+
}}
|
|
589
|
+
>
|
|
590
|
+
<Page.List>
|
|
591
|
+
<Card.Root className={styles.paneCard}>
|
|
592
|
+
<ChatList.Root
|
|
593
|
+
items={foundDialogs}
|
|
594
|
+
getKey={(item) => item.id}
|
|
595
|
+
value={dialogId}
|
|
596
|
+
onValueChange={setDialogId}
|
|
597
|
+
search={dialogQuery}
|
|
598
|
+
onSearchChange={setDialogQuery}
|
|
599
|
+
now={NOW}
|
|
600
|
+
renderItem={(item) => {
|
|
601
|
+
const last = lastOf(item);
|
|
602
|
+
return (
|
|
603
|
+
<ChatList.Item
|
|
604
|
+
time={last?.sentAt ?? item.at}
|
|
605
|
+
status={last?.from === "me" ? last.status : undefined}
|
|
606
|
+
unread={unread[item.id] ?? 0}
|
|
607
|
+
typing={item.id === dialogId && clientTyping}
|
|
608
|
+
>
|
|
609
|
+
<ChatList.ItemIcon>
|
|
610
|
+
<Avatar.Root color={hueOf(item.id)}>
|
|
611
|
+
<Avatar.Fallback>{item.initials}</Avatar.Fallback>
|
|
612
|
+
{item.id === "vector" ? <Avatar.Status status="online" /> : null}
|
|
613
|
+
</Avatar.Root>
|
|
614
|
+
</ChatList.ItemIcon>
|
|
615
|
+
<ChatList.ItemText>{item.name}</ChatList.ItemText>
|
|
616
|
+
<ChatList.ItemDescription author={last?.from === "me" ? "Вы" : undefined}>
|
|
617
|
+
{previewOf(item)}
|
|
618
|
+
</ChatList.ItemDescription>
|
|
619
|
+
</ChatList.Item>
|
|
620
|
+
);
|
|
621
|
+
}}
|
|
622
|
+
/>
|
|
623
|
+
</Card.Root>
|
|
624
|
+
</Page.List>
|
|
625
|
+
|
|
626
|
+
<Page.Detail>
|
|
627
|
+
<Card.Root className={styles.paneCard}>
|
|
628
|
+
<Chat.Root typing={clientTyping}>
|
|
629
|
+
<Chat.Header>
|
|
630
|
+
<Page.BackButton />
|
|
631
|
+
<Avatar.Root color={hueOf(dialog.id)}>
|
|
632
|
+
<Avatar.Fallback>{dialog.initials}</Avatar.Fallback>
|
|
633
|
+
{dialog.id === "vector" ? <Avatar.Status status="online" /> : null}
|
|
634
|
+
</Avatar.Root>
|
|
635
|
+
<Chat.Title>{dialog.name}</Chat.Title>
|
|
636
|
+
<Chat.Description>{dialog.contact}</Chat.Description>
|
|
637
|
+
<Chat.Actions>
|
|
638
|
+
<Chat.SearchButton />
|
|
639
|
+
</Chat.Actions>
|
|
640
|
+
</Chat.Header>
|
|
641
|
+
<Chat.Search />
|
|
642
|
+
<Chat.Messages
|
|
643
|
+
loading={loadedId !== dialogId}
|
|
644
|
+
items={messages}
|
|
645
|
+
getKey={(message) => message.id}
|
|
646
|
+
getAuthor={(message) => message.from}
|
|
647
|
+
getDate={(message) => message.sentAt}
|
|
648
|
+
renderMessage={renderMessage}
|
|
649
|
+
unread={FIRST_UNREAD}
|
|
605
650
|
now={NOW}
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
<ChatList.ItemText>{item.name}</ChatList.ItemText>
|
|
622
|
-
<ChatList.ItemDescription author={last?.from === "me" ? "Вы" : undefined}>
|
|
623
|
-
{previewOf(item)}
|
|
624
|
-
</ChatList.ItemDescription>
|
|
625
|
-
</ChatList.Item>
|
|
626
|
-
);
|
|
651
|
+
hasOlder={hasOlder}
|
|
652
|
+
onLoadOlder={loadOlder}
|
|
653
|
+
onNewMessage={(_, { direction }) => {
|
|
654
|
+
if (direction !== "incoming" || !dialogId) return;
|
|
655
|
+
setUnread((current) => ({
|
|
656
|
+
...current,
|
|
657
|
+
[dialogId]: (current[dialogId] ?? 0) + 1,
|
|
658
|
+
}));
|
|
659
|
+
}}
|
|
660
|
+
onRead={(values) => {
|
|
661
|
+
if (!dialogId) return;
|
|
662
|
+
setUnread((current) => ({
|
|
663
|
+
...current,
|
|
664
|
+
[dialogId]: Math.max(0, (current[dialogId] ?? 0) - values.length),
|
|
665
|
+
}));
|
|
627
666
|
}}
|
|
628
667
|
/>
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
</Avatar.Root>
|
|
641
|
-
<Chat.Title>{dialog.name}</Chat.Title>
|
|
642
|
-
<Chat.Description>{dialog.contact}</Chat.Description>
|
|
643
|
-
<Chat.Actions>
|
|
644
|
-
<Chat.SearchButton />
|
|
645
|
-
</Chat.Actions>
|
|
646
|
-
</Chat.Header>
|
|
647
|
-
<Chat.Search />
|
|
648
|
-
<Chat.Messages
|
|
649
|
-
loading={loadedId !== dialogId}
|
|
650
|
-
items={messages}
|
|
651
|
-
getKey={(message) => message.id}
|
|
652
|
-
getAuthor={(message) => message.from}
|
|
653
|
-
getDate={(message) => message.sentAt}
|
|
654
|
-
renderMessage={renderMessage}
|
|
655
|
-
unread={FIRST_UNREAD}
|
|
656
|
-
now={NOW}
|
|
657
|
-
hasOlder={hasOlder}
|
|
658
|
-
onLoadOlder={loadOlder}
|
|
659
|
-
onNewMessage={(_, { direction }) => {
|
|
660
|
-
if (direction !== "incoming" || !dialogId) return;
|
|
661
|
-
setUnread((current) => ({
|
|
662
|
-
...current,
|
|
663
|
-
[dialogId]: (current[dialogId] ?? 0) + 1,
|
|
664
|
-
}));
|
|
665
|
-
}}
|
|
666
|
-
onRead={(values) => {
|
|
667
|
-
if (!dialogId) return;
|
|
668
|
-
setUnread((current) => ({
|
|
669
|
-
...current,
|
|
670
|
-
[dialogId]: Math.max(0, (current[dialogId] ?? 0) - values.length),
|
|
671
|
-
}));
|
|
672
|
-
}}
|
|
668
|
+
<Chat.Footer>
|
|
669
|
+
<ChatComposer
|
|
670
|
+
replyTo={replyTo}
|
|
671
|
+
replyAuthor={dialog.contactTo}
|
|
672
|
+
editing={editing}
|
|
673
|
+
onReplyDismiss={() => setReplyTo(null)}
|
|
674
|
+
onEditDismiss={() => setEditing(null)}
|
|
675
|
+
onEditLast={editLast}
|
|
676
|
+
onPost={post}
|
|
677
|
+
onSave={save}
|
|
678
|
+
onActivityChange={reportActivity}
|
|
673
679
|
/>
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
onEditLast={editLast}
|
|
682
|
-
onPost={post}
|
|
683
|
-
onSave={save}
|
|
684
|
-
onActivityChange={reportActivity}
|
|
685
|
-
/>
|
|
686
|
-
</Chat.Footer>
|
|
687
|
-
</Chat.Root>
|
|
688
|
-
</Card.Root>
|
|
689
|
-
</PageContent.Panel>
|
|
690
|
-
</PageContent.Split>
|
|
691
|
-
</PageContent.Body>
|
|
692
|
-
</PageContent.Root>
|
|
693
|
-
</>
|
|
680
|
+
</Chat.Footer>
|
|
681
|
+
</Chat.Root>
|
|
682
|
+
</Card.Root>
|
|
683
|
+
</Page.Detail>
|
|
684
|
+
</Page.Split>
|
|
685
|
+
</Page.Body>
|
|
686
|
+
</Page.Root>
|
|
694
687
|
);
|
|
695
688
|
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/** The conversation in the zone of the manager's profile, not the browser's: the date separators, the runs and every time follow it — `timeZone`, `items`, `renderMessage`. */
|
|
2
|
+
import { Card, Chat, Message, SegmentedControl } from "prime-ui-kit";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
|
|
5
|
+
import styles from "./examples.module.css";
|
|
6
|
+
|
|
7
|
+
const ZONES = [
|
|
8
|
+
{ value: "Europe/Moscow", label: "Москва" },
|
|
9
|
+
{ value: "Asia/Vladivostok", label: "Владивосток" },
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
const NOW = new Date(Date.UTC(2026, 9, 15, 4, 0));
|
|
13
|
+
const utc = (day: number, hour: number, minute: number) =>
|
|
14
|
+
new Date(Date.UTC(2026, 9, day, hour, minute));
|
|
15
|
+
|
|
16
|
+
const MESSAGES = [
|
|
17
|
+
{
|
|
18
|
+
id: "tz-1",
|
|
19
|
+
author: "client",
|
|
20
|
+
sentAt: utc(14, 12, 40),
|
|
21
|
+
text: "Добрый вечер! Машина с заказом № 4821 уже вышла?",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: "tz-2",
|
|
25
|
+
author: "manager",
|
|
26
|
+
sentAt: utc(14, 13, 5),
|
|
27
|
+
text: "Вышла в 18:00, будет у вас завтра до обеда.",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: "tz-3",
|
|
31
|
+
author: "client",
|
|
32
|
+
sentAt: utc(14, 14, 30),
|
|
33
|
+
text: "Спасибо, предупрежу склад.",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "tz-4",
|
|
37
|
+
author: "manager",
|
|
38
|
+
sentAt: utc(15, 0, 10),
|
|
39
|
+
text: "Водитель на месте, выгрузка через 10 минут.",
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
type ChatMessage = (typeof MESSAGES)[number];
|
|
44
|
+
|
|
45
|
+
export default function ChatTimeZoneExample() {
|
|
46
|
+
const [zone, setZone] = React.useState("Asia/Vladivostok");
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<div className={styles.live}>
|
|
50
|
+
<div className={styles.liveBar}>
|
|
51
|
+
<SegmentedControl.Root value={zone} onValueChange={setZone} aria-label="Пояс профиля">
|
|
52
|
+
{ZONES.map((item) => (
|
|
53
|
+
<SegmentedControl.Item key={item.value} value={item.value}>
|
|
54
|
+
{item.label}
|
|
55
|
+
</SegmentedControl.Item>
|
|
56
|
+
))}
|
|
57
|
+
</SegmentedControl.Root>
|
|
58
|
+
</div>
|
|
59
|
+
<Card.Root className={styles.short}>
|
|
60
|
+
<Chat.Root>
|
|
61
|
+
<Chat.Messages
|
|
62
|
+
aria-label="Переписка по заказу № 4821"
|
|
63
|
+
timeZone={zone}
|
|
64
|
+
now={NOW}
|
|
65
|
+
items={MESSAGES}
|
|
66
|
+
getKey={(message: ChatMessage) => message.id}
|
|
67
|
+
getAuthor={(message: ChatMessage) => message.author}
|
|
68
|
+
getDate={(message: ChatMessage) => message.sentAt}
|
|
69
|
+
renderMessage={(message: ChatMessage) => (
|
|
70
|
+
<Message.Root
|
|
71
|
+
direction={message.author === "manager" ? "outgoing" : "incoming"}
|
|
72
|
+
time={message.sentAt}
|
|
73
|
+
status={message.author === "manager" ? "read" : undefined}
|
|
74
|
+
>
|
|
75
|
+
<Message.Text>{message.text}</Message.Text>
|
|
76
|
+
</Message.Root>
|
|
77
|
+
)}
|
|
78
|
+
/>
|
|
79
|
+
</Chat.Root>
|
|
80
|
+
</Card.Root>
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
@@ -28,7 +28,7 @@ ChatList.Root <div> column filling its host (container `chat-lis
|
|
|
28
28
|
├─ ScrollContainer the list's own scroller; onReachEnd → onLoadMore while hasMore
|
|
29
29
|
│ └─ Crossfade loading (placeholder List rows) ⇄ empty (EmptyPage compact) ⇄ the list
|
|
30
30
|
│ └─ List.Root <ul> aria-label «Диалоги»; spacer <li aria-hidden> stand for rows out of view
|
|
31
|
-
│ └─ ChatList.Item List.Item <li> + <button> | <a href
|
|
31
|
+
│ └─ ChatList.Item List.Item <li> + <button> | <a href> | your element (asChild); current from value; one Tab stop
|
|
32
32
|
│ ├─ ChatList.ItemIcon before the name: avatar slot (aria-hidden); after it: a glyph
|
|
33
33
|
│ ├─ ChatList.ItemText the name; muted glyph after it
|
|
34
34
|
│ ├─ ChatList.ItemDescription author · media word · text — cross-fades with draft and «печатает…»
|
|
@@ -62,12 +62,13 @@ ChatList.Root <div> column filling its host (container `chat-lis
|
|
|
62
62
|
| `empty` | `ReactNode` | — | The empty state without a search (an `EmptyPage` with an action). Default: «Нет диалогов». |
|
|
63
63
|
| `size` | `"xs" \| "s" \| "m" \| "l" \| "xl"` | host tier, else `"m"` | Row tier: height, text, avatar, glyphs and the search field. Without it the tier of the host. |
|
|
64
64
|
| `now` | `Date` | — | «Now» for the times of the rows. Default: the moment of the render. |
|
|
65
|
-
| `
|
|
65
|
+
| `timeZone` | `string` | the browser's zone | The IANA zone the times of the rows are read in (`"Asia/Vladivostok"`): a profile's zone, not the browser's. |
|
|
66
|
+
| `formatTime` | `(date: Date, now: Date, timeZone?: string) => string` | `formatChatTime` | Display of a row's `Date` time: «14:32» today, «пн» this week, «12 мар», «12.03.2025»; gets the `timeZone`. |
|
|
66
67
|
| `labels` | `Partial<ChatListLabels>` | — | Built-in strings, see Labels. |
|
|
67
68
|
| `…rest` | `HTMLAttributes<HTMLDivElement>` | — | `className` and the other `div` attributes of the column. |
|
|
68
69
|
|
|
69
70
|
### ChatList.Item
|
|
70
|
-
`ref` → `HTMLElement` (the `<button>` or
|
|
71
|
+
`ref` → `HTMLElement` (the `<button>`, `<a>` or `asChild` element, not the `<li>`). A dialog: a `List.Item` row with the avatar, the name and the time over the preview and the counts. Its key and `current` come from the root.
|
|
71
72
|
|
|
72
73
|
| Prop | Type | Default | Description |
|
|
73
74
|
|---|---|---|---|
|
|
@@ -83,7 +84,8 @@ ChatList.Root <div> column filling its host (container `chat-lis
|
|
|
83
84
|
| `href` | `string` | — | Renders an `<a>` instead of a `<button>` (a dialog with its own URL). |
|
|
84
85
|
| `target` | `string` | — | Where the `<a>` opens (`href` only). |
|
|
85
86
|
| `rel` | `string` | — | Relationship of the `<a>` (`href` only). |
|
|
86
|
-
| `
|
|
87
|
+
| `asChild` | `boolean` | `false` | The one child element (a router `Link`) is the row; the parts go inside it. |
|
|
88
|
+
| `children` | `ReactNode` | — | `ChatList.ItemIcon`, `ChatList.ItemText`, `ChatList.ItemDescription`, `ChatList.ItemMenu` — inside the child element with `asChild`. |
|
|
87
89
|
| `…rest` | `ButtonHTMLAttributes<HTMLButtonElement>` | — | `className` and the native attributes of the row element. |
|
|
88
90
|
|
|
89
91
|
### ChatList.ItemIcon
|
|
@@ -150,6 +152,7 @@ The search field takes the tier too; counts are one tier down (the Badge's own r
|
|
|
150
152
|
| `muted` | a muted glyph after the name; the count soft gray | notifications are off | `false` |
|
|
151
153
|
| `mention` | a solid «@» before the count | the reader is mentioned | `false` |
|
|
152
154
|
| `pinned` | a pin under the time while nothing is unread | pinned by the reader — order pinned first in `items` | `false` |
|
|
155
|
+
| `asChild` | the same row, rendered as your one child element with the parts inside it | a router's `Link` opens the dialog without a reload | `false` |
|
|
153
156
|
| `status` | ✓ / ✓✓ in the accent / clock / failure mark before the time | the reader wrote the last message | — |
|
|
154
157
|
|
|
155
158
|
## States
|
|
@@ -171,7 +174,7 @@ The search field takes the tier too; counts are one tier down (the Badge's own r
|
|
|
171
174
|
Root attribute: `data-size`. Every motion honours reduced motion (durations collapse, glides and ghosts are skipped).
|
|
172
175
|
|
|
173
176
|
## Layout & spacing
|
|
174
|
-
- The root is a flex column that fills its host's height: put it straight into a `Card.Root` or a `
|
|
177
|
+
- The root is a flex column that fills its host's height: put it straight into a `Card.Root` or a `Page.List` pane with a height; the scroller takes the rest under the search field.
|
|
175
178
|
- One inset all round, the panel's 4px: the search field and the rows stand 4px from every edge of the host, so in a card (radius 12) their 8px corners follow the card's (nested radius = outer − padding). Rows stand 4px apart (a margin inside each `<li>`, so the virtual window measures rows with their space); the last row's margin is the inset below it.
|
|
176
179
|
- A row: avatar · name and preview · time over the counts. The name and the preview truncate; glyphs, the time and the counts never do.
|
|
177
180
|
- From 100 dialogs only the rows around the view render; spacers hold the rest of the height. The row with the Tab stop and the row with an open menu stay rendered.
|
|
@@ -195,7 +198,7 @@ Root attribute: `data-size`. Every motion honours reduced motion (durations coll
|
|
|
195
198
|
### ARIA
|
|
196
199
|
<!-- Generated from api.ts by `bun run docs:build`. Edit api.ts, not this section. -->
|
|
197
200
|
|
|
198
|
-
- The list is a `<ul>` named «Диалоги» (`labels.list`); each row an `<li>` with a button, or
|
|
201
|
+
- The list is a `<ul>` named «Диалоги» (`labels.list`); each row an `<li>` with a button, a link with `href`, or your link with `asChild`.
|
|
199
202
|
- The open dialog is `aria-current="true"` on a button, `"page"` on a link. Selection does not follow the focus: arrows only move it (a dialog may load a conversation); Enter, Space and a click open.
|
|
200
203
|
- The row is named by its content: the name, glyphs with a `label` («Без звука», a verified mark), the preview, the delivery mark («Прочитано»), the time, then «упоминание» and «непрочитанных: 3» instead of the bare badges; the avatar is `aria-hidden`.
|
|
201
204
|
- While the other side types, the preview is `aria-hidden` and «печатает…» is read; a draft reads «Черновик: …».
|
|
@@ -243,7 +246,8 @@ Root attribute: `data-size`. Every motion honours reduced motion (durations coll
|
|
|
243
246
|
| [search.tsx](examples/search.tsx) | The search field filters dialogs by name and by the last message, marks the match in both, says how many were found and shows a quiet state when none match — `defaultSearch`, `onSearchChange`. |
|
|
244
247
|
| [live.tsx](examples/live.tsx) | A live inbox: a client types, then writes — the preview turns into the typing line and back, the count rolls up and the dialog glides to the top; opening it clears the count — `typing`, `unread`, `items`. |
|
|
245
248
|
| [long-list.tsx](examples/long-list.tsx) | A sales inbox of a thousand dialogs: only the rows around the view render, arrows walk through all of them, and the next page loads as the end comes near — `hasMore`, `onLoadMore`. |
|
|
246
|
-
| [links.tsx](examples/links.tsx) | Dialogs with their own address: every row is a link the
|
|
249
|
+
| [links.tsx](examples/links.tsx) | Dialogs with their own address: every row is a link to the ticket's page, the time reads as how long ago, and the list is named for its queue — `href`, `formatTime`, `labels`. |
|
|
250
|
+
| [router.tsx](examples/router.tsx) | Router links as the dialogs, the times in the zone of the operator's profile; render it inside a router — `asChild`, `timeZone`. |
|
|
247
251
|
| [states.tsx](examples/states.tsx) | Loading and empty: placeholder rows in the rows' geometry cross-fade into the dialogs; a new workspace without dialogs shows its own empty state with an action — `loading`, `empty`. |
|
|
248
252
|
| [controlled.tsx](examples/controlled.tsx) | The open dialog lives in the screen: a row opens it beside the list, and a next-unread button opens the next one from outside — `value`, `onValueChange`. |
|
|
249
253
|
| [narrow.tsx](examples/narrow.tsx) | At phone width long names and previews truncate while the time and counts stay whole; a pane squeezed under 240px keeps only the names and the counts — `ChatList.Root`, `search`. |
|
|
@@ -256,7 +260,9 @@ Root attribute: `data-size`. Every motion honours reduced motion (durations coll
|
|
|
256
260
|
- An `Avatar.Root size="s"` to fit the row → leave `size` out; the slot sizes the avatar to the tier.
|
|
257
261
|
- A «⋯» button nested inside the row for the menu → `ChatList.ItemMenu`: it opens on right click, a long press and Shift+F10.
|
|
258
262
|
- Deleting from the menu without a question → open a `ConfirmDialog` from the menu item.
|
|
263
|
+
- `href` with an `onClick` that calls `preventDefault()` and the router's `navigate` → `asChild` with the router's `Link`, the parts inside it.
|
|
264
|
+
- Times shifted by hand to a profile's zone before `time` → `timeZone` on the root: «сегодня», the weekday and the clock are read in it.
|
|
259
265
|
|
|
260
266
|
## Related
|
|
261
267
|
- **Built from:** [List](../list/COMPONENT.md) (rows, current fill, focus, touch height), [Input](../input/COMPONENT.md) (search), [ScrollContainer](../scroll-container/COMPONENT.md), [Crossfade](../crossfade/COMPONENT.md), [Skeleton](../skeleton/COMPONENT.md), [EmptyPage](../empty-page/COMPONENT.md), [Badge](../badge/COMPONENT.md) (counts), [Dropdown](../dropdown/COMPONENT.md) (row menu), [VisuallyHidden](../visually-hidden/COMPONENT.md), `useFlipList` (the glide of a new order)
|
|
262
|
-
- **See also:** [Chat](../chat/COMPONENT.md), [Message](../message/COMPONENT.md), [Avatar](../avatar/COMPONENT.md), [
|
|
268
|
+
- **See also:** [Chat](../chat/COMPONENT.md), [Message](../message/COMPONENT.md), [Avatar](../avatar/COMPONENT.md), [Page](../../layout/page/COMPONENT.md), [ConfirmDialog](../confirm-dialog/COMPONENT.md)
|
|
@@ -56,7 +56,7 @@ export default function ChatListControlledExample() {
|
|
|
56
56
|
const dialog = dialogs.find((item) => item.id === dialogId);
|
|
57
57
|
|
|
58
58
|
return (
|
|
59
|
-
<div className={styles.
|
|
59
|
+
<div className={styles.screen}>
|
|
60
60
|
<div className={styles.bar}>
|
|
61
61
|
<Button.Root
|
|
62
62
|
variant="soft"
|
|
@@ -93,7 +93,7 @@ export default function ChatListControlledExample() {
|
|
|
93
93
|
<Card.Root>
|
|
94
94
|
<Card.Body>
|
|
95
95
|
<Typography variant="body-m" tone={dialog ? "default" : "muted"}>
|
|
96
|
-
{dialog ? `Открыт диалог: ${dialog.name}` : "Выберите диалог
|
|
96
|
+
{dialog ? `Открыт диалог: ${dialog.name}` : "Выберите диалог в списке"}
|
|
97
97
|
</Typography>
|
|
98
98
|
</Card.Body>
|
|
99
99
|
</Card.Root>
|
|
@@ -29,6 +29,14 @@
|
|
|
29
29
|
gap: var(--prime-space-2);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
/* controlled: a list + detail screen, as wide as the preview gives (no pane cap). */
|
|
33
|
+
.screen {
|
|
34
|
+
display: flex;
|
|
35
|
+
flex-direction: column;
|
|
36
|
+
gap: var(--prime-space-3);
|
|
37
|
+
inline-size: 100%;
|
|
38
|
+
}
|
|
39
|
+
|
|
32
40
|
/* controlled: the list beside the open dialog; they stack in a narrow column. */
|
|
33
41
|
.split {
|
|
34
42
|
display: flex;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Dialogs with their own address: every row is a link the
|
|
1
|
+
/** Dialogs with their own address: every row is a link to the ticket's page, the time reads as how long ago, and the list is named for its queue — `href`, `formatTime`, `labels`. */
|
|
2
2
|
import { Avatar, Card, ChatList, hueOf } from "prime-ui-kit";
|
|
3
3
|
|
|
4
4
|
import styles from "./examples.module.css";
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/** Router links as the dialogs, the times in the zone of the operator's profile; render it inside a router — `asChild`, `timeZone`. */
|
|
2
|
+
import { Avatar, Card, ChatList, hueOf } from "prime-ui-kit";
|
|
3
|
+
import { Link } from "react-router-dom";
|
|
4
|
+
|
|
5
|
+
import styles from "./examples.module.css";
|
|
6
|
+
|
|
7
|
+
const NOW = new Date(Date.UTC(2026, 9, 15, 4, 0));
|
|
8
|
+
const utc = (day: number, hour: number, minute: number) =>
|
|
9
|
+
new Date(Date.UTC(2026, 9, day, hour, minute));
|
|
10
|
+
|
|
11
|
+
const DIALOGS = [
|
|
12
|
+
{
|
|
13
|
+
id: "c-311",
|
|
14
|
+
name: "ООО «Вектор»",
|
|
15
|
+
initials: "ВК",
|
|
16
|
+
preview: "Машина на месте, начинаем выгрузку",
|
|
17
|
+
at: utc(15, 0, 10),
|
|
18
|
+
unread: 1,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: "c-308",
|
|
22
|
+
name: "ООО «Гранит»",
|
|
23
|
+
initials: "ГР",
|
|
24
|
+
preview: "Счёт № 2041 оплачен",
|
|
25
|
+
at: utc(14, 14, 30),
|
|
26
|
+
unread: 0,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: "c-297",
|
|
30
|
+
name: "ИП Козлов",
|
|
31
|
+
initials: "ИК",
|
|
32
|
+
preview: "Пришлите, пожалуйста, акт сверки",
|
|
33
|
+
at: utc(12, 6, 15),
|
|
34
|
+
unread: 0,
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
export default function ChatListRouterExample() {
|
|
39
|
+
return (
|
|
40
|
+
<Card.Root className={styles.short}>
|
|
41
|
+
<ChatList.Root
|
|
42
|
+
items={DIALOGS}
|
|
43
|
+
getKey={(item) => item.id}
|
|
44
|
+
defaultValue="c-311"
|
|
45
|
+
now={NOW}
|
|
46
|
+
timeZone="Asia/Vladivostok"
|
|
47
|
+
renderItem={(item) => (
|
|
48
|
+
<ChatList.Item asChild time={item.at} unread={item.unread}>
|
|
49
|
+
<Link to={`/chats/${item.id}`}>
|
|
50
|
+
<ChatList.ItemIcon>
|
|
51
|
+
<Avatar.Root color={hueOf(item.id)}>
|
|
52
|
+
<Avatar.Fallback>{item.initials}</Avatar.Fallback>
|
|
53
|
+
</Avatar.Root>
|
|
54
|
+
</ChatList.ItemIcon>
|
|
55
|
+
<ChatList.ItemText>{item.name}</ChatList.ItemText>
|
|
56
|
+
<ChatList.ItemDescription>{item.preview}</ChatList.ItemDescription>
|
|
57
|
+
</Link>
|
|
58
|
+
</ChatList.Item>
|
|
59
|
+
)}
|
|
60
|
+
/>
|
|
61
|
+
</Card.Root>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
@@ -50,6 +50,7 @@ Checkbox.Indicator the box alone, no input — a mark inside option / menu r
|
|
|
50
50
|
| `optional` | `boolean` | `false` | Muted `labels.optional` after the label text; the field may stay off. |
|
|
51
51
|
| `labels` | `Partial<CheckboxLabels>` | — | Built-in strings, see Labels. |
|
|
52
52
|
| `hint` | `ReactNode` | — | Help text under the label text. Hidden while `error` is shown. |
|
|
53
|
+
| `hintTone` | `"neutral" \| "success" \| "warning" \| "danger"` | `"neutral"` | Status color of `hint` («Осталось 12 дней» in `warning`). The words carry the status, the color repeats it; an `error` replaces the hint and its tone. A validation error is `error`, never a `danger` hint. |
|
|
53
54
|
| `error` | `ReactNode` | — | Error message in the hint slot; implies `invalid`. |
|
|
54
55
|
| `invalid` | `boolean` | `false` | Danger ring on the unchecked box and `aria-invalid`. A non-empty `error` implies it. |
|
|
55
56
|
| `disabled` | `boolean` | `false` | Disabled fill, dimmed label and hint, no toggling. |
|
|
@@ -19,12 +19,13 @@
|
|
|
19
19
|
width: min(100%, var(--prime-layout-form-width-s));
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
/* indicator.tsx: selectable tiles in a fluid grid
|
|
22
|
+
/* indicator.tsx: selectable tiles in a fluid grid; a column holds a whole module name (a tile
|
|
23
|
+
label stays on one line), so a narrow column stacks the tiles instead of truncating them. */
|
|
23
24
|
.tiles {
|
|
24
25
|
display: grid;
|
|
25
26
|
grid-template-columns: repeat(
|
|
26
27
|
auto-fit,
|
|
27
|
-
minmax(min(100%, var(--prime-layout-tile-min-width)), 1fr)
|
|
28
|
+
minmax(min(100%, calc(var(--prime-layout-tile-min-width) * 1.5)), 1fr)
|
|
28
29
|
);
|
|
29
30
|
gap: var(--prime-space-4);
|
|
30
31
|
width: 100%;
|
|
@@ -69,7 +69,7 @@ Syntax tokens: keywords purple (weight 500), strings teal, numbers orange, JSX t
|
|
|
69
69
|
## Layout & spacing
|
|
70
70
|
- `max-width: 100%`; the block takes the column width and long lines scroll horizontally inside it (`white-space: pre`, tab size 2), with the kit's thin scrollbar.
|
|
71
71
|
- Heading / text → code block: space step 2–4 (8–16px).
|
|
72
|
-
- Constrain the column (
|
|
72
|
+
- Constrain the column (`Page.Root maxWidth="readable"` for docs), not the block.
|
|
73
73
|
|
|
74
74
|
## Accessibility
|
|
75
75
|
|