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
package/dist/skill/cheatsheet.md
CHANGED
|
@@ -37,11 +37,15 @@ reference is each component's `COMPONENT.md` ([components.md](components.md)), t
|
|
|
37
37
|
- After-upload work (attach the file to a record) runs inside `upload` after the request resolves — `context.id` is the item; a file the user can open is `FileUploadFile.href`, not your own download button beside the row.
|
|
38
38
|
- A choice in a form (SegmentedControl, ButtonGroup) is a field too: `label`, `hint`, `error` on its root — not a `Label` wired by hand.
|
|
39
39
|
- A record card that saves each field: `<Input.Root onCommit={save}>` (save returns a Promise) — not hand-written blur / Enter / Escape handlers or a field disabled while saving.
|
|
40
|
-
- Markdown text outside a chat (an announcement, a task description) is `<Textarea.Root formatting>`: the Composer's toolbar, hotkeys and subset (`**`, `_`, `~~`, `` ` ``, `||spoiler||`, links, `> `) — not a hand-made toolbar over a textarea. Turn it on only where the text is shown with its Markdown.
|
|
40
|
+
- Markdown text outside a chat (an announcement, a task description) is written in `<Textarea.Root formatting>`: the Composer's toolbar, hotkeys and subset (`**`, `_`, `~~`, `` ` ``, `||spoiler||`, links, `> `) — not a hand-made toolbar over a textarea. Turn it on only where the text is shown with its Markdown, and show it with `<RichText>{text}</RichText>` — not `dangerouslySetInnerHTML` or a Markdown library.
|
|
41
|
+
- Free text the team often repeats (a city, a place): `<Input.Root suggestions={CITIES}>` — any text stays allowed; not a `<datalist>` or a Select. A time of day: `<Input.Field type="time" />` — not a Datepicker or two Selects.
|
|
42
|
+
- A status of the value under a field («Осталось 12 дней»): `hint` with `hintTone="warning"`, the words carrying the status — not a coloured text of your own, and never `hintTone="danger"` for a validation error (that is `error`).
|
|
43
|
+
- A unit or a prefix stands in the field's affix (`Input.InlineAffix`, `Input.Affix`) — not in its `label` too: the affix is read with the field.
|
|
41
44
|
- Copy or call next to a value: `Input.CopyButton`, `Input.Action` inside `Input.Wrapper` — not a Button beside the field; a password: `Input.RevealButton`.
|
|
42
45
|
- Records of one shape a person adds and removes (invoice lines, contacts, specs, prices by period): `<FieldList columns={[{ label: "Услуга" }, { label: "Цена", width: "m" }]} value onValueChange getId createItem addLabel renderItem={(item, row) => <>…fields without label…</>} />` — the headings stand once, every field takes its column heading as its label; not a `.map()` of fields with a `label` in every row, not «Позиция 1», «Позиция 2».
|
|
43
46
|
- Small attributes in a row of fields: an icon-only `Select` (`<Select.Trigger><Select.TriggerIcon>…</Select.TriggerIcon></Select.Trigger>`, no `Select.Value`) and a `ColorPresets` swatch in `width: "compact"` columns — not a full-width Select and a ColorField on a line of their own.
|
|
44
47
|
- A base value with overrides (a price and its changes by month): one `FieldList`, the base as the first row pinned by `getLocked` — not a separate field above a list in another geometry.
|
|
48
|
+
- Rows that add up: `FieldList renderTotals={(items) => <>…one node per column…</>}` draws «Итого» under the rows on the same tracks — not a line of text typed under the list, not a DataTable of fields.
|
|
45
49
|
- One value in several units (a deposit in ₽, $, ฿): the fields side by side in one row under one heading, each unit in `Input.InlineAffix` — not a label per field, not the unit in the label and in the field.
|
|
46
50
|
|
|
47
51
|
## State
|
|
@@ -78,24 +82,32 @@ reference is each component's `COMPONENT.md` ([components.md](components.md)), t
|
|
|
78
82
|
|
|
79
83
|
## Page title and header
|
|
80
84
|
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
-
|
|
84
|
-
- A
|
|
85
|
+
- The app is navigation and the page: everything at the top belongs to the page's `<Page.Root>` — not an app-wide header, a global search or notifications above every page.
|
|
86
|
+
- A work screen (a list, a board, a chat, a record) titles itself in `<Page.TopBar>`: `<Page.Heading>` with `<Page.Title>` + `<Page.Description>` carrying a line of data («128 в работе · 6 ждут оплаты») — not a sentence about the page.
|
|
87
|
+
- The bar holds only its four groups: `<Page.Heading>`, `<Page.Tools aria-label>` (sections, `<SmartFilter.Toolbar />`, the view — in reading order), `<Page.Actions>`, `<Page.Chips>` (`<SmartFilter.Chips />`) — not a hand-made flex row of title, tabs, search and buttons ([the top bar](composition.md#the-top-bar)).
|
|
88
|
+
- A nested record: `<Breadcrumb.Root>` first in `<Page.Heading>`, then `<Page.Title>` with the record's name — the path ends in the title on one line; not a title row under the path, not a breadcrumb in the body. With a router each crumb is `<Breadcrumb.Item asChild>` around its `Link`.
|
|
89
|
+
- A line of data that loads after the page opens: `<Page.Description loading={!summary}>` from the first render — not a Description mounted when the data arrives, which moves the title.
|
|
90
|
+
- A page that edits a record: `<Page.Guard dirty={changed} busy={saving} />` inside `Page.Root` — the Sidebar, BottomNav and path links ask before the changes are lost; not your own `beforeunload` or a confirm wired to each link.
|
|
91
|
+
- Every button of the page goes into one `<Page.Actions>`, secondary first, the primary last, each with a `<Button.Icon>` beside its label — not buttons split between two places, not a button with only text.
|
|
92
|
+
- A filtered page: `<SmartFilter.Root>` wraps `<Page.Root>` — it draws nothing; not `SmartFilter.Root` inside the bar.
|
|
93
|
+
- No size knob on the title: the bar sizes the heading and gives way by width itself ([the five steps](responsive.md#the-pages-top-bar--pagetopbar)).
|
|
94
|
+
- A document page (settings, a long form, help) and an overview (a dashboard) put `<Page.Header>` with its `<Page.Heading>` in the flow — the large title — with an optional `<Page.TopBar collapse>` above it that repeats the title once it scrolls away. One `<Page.Title>` per page — never two titles, never no `<h1>`.
|
|
85
95
|
|
|
86
96
|
## Cards and surfaces
|
|
87
97
|
|
|
88
98
|
- `Card.Root` only for a bounded block with its own title: a KPI tile (`variant="stat-trend"`), a settings panel (`variant="panel"`), side facts — not around a whole section, a form field or a page.
|
|
89
99
|
- Never a `DataTable` inside a Card — the table is already a filled block; a card in a card only sparingly ([the rule](foundations.md#card-in-a-card)).
|
|
90
|
-
- Section without a card: `<
|
|
91
|
-
- The tiles of a screen (KPI cards, charts, panels): one `<
|
|
100
|
+
- Section without a card: `<Page.Section label="…">` + the content (a link or button beside the heading in `Page.Actions`) — not a hand-made `<section>` + `Typography as="h2"` + own gap.
|
|
101
|
+
- The tiles of a screen (KPI cards, charts, panels): one `<Page.Grid>` with a `<Page.Cell span>` per tile — not a grid per row (the rows would stand 24 apart instead of 16). A chart beside a panel is an 8 and a 4 written next to each other — the grid pairs them at mid widths; not 6 + 6 to dodge a hole.
|
|
102
|
+
- A KPI tile whose figure loads: `<Card.Root variant="stat-trend" loading>` with its parts mounted — not Skeletons placed in `Card.Value` by hand.
|
|
103
|
+
- Several tags or labels as one value (a client's tags): `<Badge.Group>` of `Badge.Root` — not a flex row with its own gap.
|
|
92
104
|
- Depth from fill, not lines: no borders around blocks; `<Divider />` only inside a block.
|
|
93
|
-
- Every scroll region is a `ScrollContainer` — never `overflow: auto` on a `div`: its hidden edges fade by themselves (`edges="shadow"` on a filled surface, `"none"` only for a page column), `scrollbar="hidden"` on strips, `snap` on strips of cards, `lock` to hold a list still, `anchor="end"` for a log. Kit components already scroll through it; do not wrap them again.
|
|
105
|
+
- Every scroll region is a `ScrollContainer` — never `overflow: auto` on a `div`: its hidden edges fade by themselves (`edges="shadow"` on a filled surface, `"none"` only for a page column), `scrollbar="hidden"` on strips, `snap` on strips of cards (it settles once the scroll ends; never `scroll-snap-type`), `lock` to hold a list still, `anchor="end"` for a log. Kit components already scroll through it; do not wrap them again.
|
|
94
106
|
- Tabs are a bar, not a container: `Tabs.Root` stands in the host's padding and the panel content goes straight into `Tabs.Panel` — never a Card or a padded `div` around the tabs or inside a panel. In a Modal / Drawer, `Tabs.Root` wraps `X.Header` + `X.Body` and `Tabs.List` goes last into the header — not a tab strip at the top of the body.
|
|
95
107
|
|
|
96
108
|
## Tables
|
|
97
109
|
|
|
98
|
-
- A list page is a `<DataTable columns rows getRowKey>` under the page's `<SmartFilter.Root fields value onValueChange>` with `<SmartFilter.Toolbar />`
|
|
110
|
+
- A list page is a `<DataTable columns rows getRowKey>` under the page's `<SmartFilter.Root fields value onValueChange>` with `<SmartFilter.Toolbar />` in its `Page.Tools` and `<SmartFilter.Chips />` in its `Page.Chips` ([where the filters go](composition.md#where-the-filters-go)); filter rows with `matchesSmartFilter` — not a search Input and a row of Selects above the table.
|
|
99
111
|
- Search over a table or a list page is always SmartFilter, even with no filter fields yet (`fields={[]}` is a plain search that grows into filters). A search `Input` only outside a filtered list: inside a picker, a settings section, a panel.
|
|
100
112
|
- Paging is built in: `paging="pages"` (default) with `pageSize`, `paging="infinite"` for feeds, `paging="none"` for short lists — not a separate `<Pagination>` under a DataTable.
|
|
101
113
|
- Long lists are virtualized inside the kit: pass the whole array to `DataTable` (with `scrollHeight` or `paging="infinite"`; over 100 rows — grouped, `onReorder` and `renderExpanded` bodies render every row, keep those short or paged), `TagSelect options`, `Chat.Messages items`, `Gantt rows` — never slice it by hand, never wrap a kit list in react-window / react-virtual or your own windowing. Big remote data is still paged or loaded on scroll by the server (`source="server"`, `onLoadMore`).
|
|
@@ -104,18 +116,23 @@ reference is each component's `COMPONENT.md` ([components.md](components.md)), t
|
|
|
104
116
|
- A chart with axes or several series: `<ChartFrame.Root series rows state>` around the library (or your SVG) with `ChartFrame.Plot renderPlot` and `Legend`; `rows` is the data table screen readers get — not a hand-made Card with a grey box while loading and a legend of colored dots.
|
|
105
117
|
- A tooltip on your own SVG chart: `<ChartFrame.Tooltip point={{ x, y }} items>` with the pointer in plot coordinates — not a `foreignObject` or a div placed and clamped by hand; it flips only when out of room.
|
|
106
118
|
- Amounts, counts and dates are `numeric` columns; statuses are `Badge.Root tone` from one status → tone map.
|
|
119
|
+
- A column header that needs a word more («Маржа»): the column's `description` (an info glyph with a tooltip) — not the explanation squeezed into the header, not your own icon and Tooltip in `header`.
|
|
120
|
+
- A list row with controls of its own (a Switch, a ⋯ menu): `List.ItemActions` inside `List.Item`, a stage colour as `Badge.Dot color` in `List.ItemIcon` — not a control inside the row's button, not a row rebuilt as a `div`.
|
|
107
121
|
- Rows people order by hand: `onReorder(id, beforeId)` (apply it with `moveBefore`, return the save's Promise) — not a Dnd list rebuilt next to the table.
|
|
108
122
|
- A short list of records people order by hand (stages, priorities) is `<List.Root onReorder>` with `List.Item value` — not up / down buttons or a hand-made `Dnd.Sortable`.
|
|
109
123
|
- Groups that fold: pass `defaultCollapsedGroups={[]}` (or the controlled `collapsedGroups` + `onCollapsedGroupsChange`) — not your own button in `renderGroupHeader` or filtering `rows`. One heatmap over several columns: the same `scale: { min, max }` on each.
|
|
110
124
|
- A trend in a table row is `<Sparkline layout="compact">` in the column's `cell` (a column `width`, series built once, not inline, the same `min` / `max` on every row when rows compare by size); the number itself goes in its own column. A missing day is `value: null`, never `0`.
|
|
111
125
|
- Properties of one record: `<DescriptionList.Root>` of `DescriptionList.Item` — not a hand-made grid of label / value text, not a one-row DataTable.
|
|
112
126
|
- Who is busy when, a plan with dates: `Gantt` with `onBarChange` / `onBarCreate` — not bars drawn by hand or a DataTable of start and end dates. Statuses moved by hand: `Kanban` — `plain` (default, a header plate) or `line` (a header over a line) for a board that is the page's main region, `variant="well"` only when columns must read as bounded queues (WIP limits, sparse columns); never a Card or a filled box around a column.
|
|
127
|
+
- A stage's figures go in `renderColumnMeta` (an array is a line per entry: «12 сделок · 4,8 млн ₽», «Средний чек 400 000 ₽») — not in the column `title`.
|
|
113
128
|
- Open a board card with `Kanban.Root onItemOpen` (click, Enter, Space, never after a drag) or `getItemHref`; a Gantt row with `onRowClick` / `getRowHref` (the DataTable contract), a bar with `onItemOpen`; more facts in a bar tooltip with `renderBarTooltip` (it adds lines under the dates). A legend of hues is a row of `Badge.Root color` + `Badge.Dot` in the host's `toolbar`, the category also in text. Hour slots (bookings, appointments) are not Gantt — its unit is a calendar day.
|
|
114
129
|
|
|
115
130
|
## Chat
|
|
116
131
|
|
|
117
132
|
- A conversation is `Chat`: `<Chat.Root typing selected search>` with `Chat.Header` (avatar, `Chat.Title`, `Chat.Description`, `Chat.Actions` + `Chat.SearchButton`), `Chat.Search`, `Chat.Pinned`, `<Chat.Messages items getKey getAuthor getDate renderMessage>` and `<Chat.Footer><Composer.Root /></Chat.Footer>` — not a header, a ScrollContainer and a list of your own, not Cards or a Timeline styled as bubbles, not a Textarea with a send button. A list without the rest is `Chat.Root` with `Chat.Messages` alone; one message on its own is `Message.Root`.
|
|
118
|
-
- The list of conversations is `ChatList` — not a `List` or Cards with your own preview, unread counts and «печатает…». Back button and avatar in the chat header are plain children of `Chat.Header`: it lays them out side by side.
|
|
133
|
+
- The list of conversations is `ChatList` — not a `List` or Cards with your own preview, unread counts and «печатает…». Back button and avatar in the chat header are plain children of `Chat.Header`: it lays them out side by side. A dialog with its own route is `<ChatList.Item asChild>` around the router `Link`.
|
|
134
|
+
- Times in the operator's zone, not the browser's: `timeZone="Europe/Moscow"` on `Chat.Messages`, `ChatList.Root` and a lone `Message.Root` — not dates shifted by hand.
|
|
135
|
+
- A sticker is `Message.Sticker` (your Lottie or video player inside it); a message shown outside a chat (a bot's welcome message in its settings) is `<Message.Root preview>` — not a screenshot or a bubble drawn again.
|
|
119
136
|
- A dialog loading is `<Chat.Messages loading>` (bubble skeletons that cross-fade into the list) — not a Spinner or grey boxes. A bot's buttons under a message are `Message.Actions` rows of `Button.Root variant="soft" tone="neutral"` (`asChild` for links), never buttons inside `Message.Text`.
|
|
120
137
|
- `renderMessage` returns a `Message.Root` (its `value` and `position` are set for you) or a `Chat.Service`; an inline function is fine: an item renders again only when it or its place changes, so a row shows what its item holds, and another message (a reply's original) comes from `entry.find(key)`. Dates, runs and the unread band (`unread={key}`) come from the list.
|
|
121
138
|
- A group chat is `<Chat.Messages group>`: put `Message.Author` (`color={hueOf(user.id)}`, `tag`, `Message.AuthorIcon` for a crown) and `Message.Avatar` on every message — the list shows the header on the first of a run and the avatar on the last; a direct chat shows neither.
|
|
@@ -136,12 +153,13 @@ reference is each component's `COMPONENT.md` ([components.md](components.md)), t
|
|
|
136
153
|
|
|
137
154
|
- Blocking decision or ≤ 4 fields → `Modal` (`<Modal.Content size="s">` for a confirm); long form, filters, details → `Drawer`; a short task that ends by itself (a date, an action, a note) → `Sheet`; small panel at a control → `Popover`; list of actions → `Dropdown`; a field value → `Select`; a name for an icon button → `Tooltip`; ⌘K → `CommandMenu`; a photo, a scan or a video full screen from its thumbnail → `MediaViewer` (an album in a grid is `Gallery`, which opens it for you; a standalone viewer keeps `open` and `index` in two states) — not a Modal with an `<img>`.
|
|
138
155
|
- A record's drawer or modal shows its person or object as `Drawer.Icon` / `Modal.Icon` around `Avatar.Root` / `Thumbnail.Root`. A confirm that asks for input (a reason) is a `Modal size="s"` with the field, `Modal.Confirm` and `Modal.Guard busy` — `ConfirmDialog` is a question only.
|
|
156
|
+
- A titled group in a dialog's body (contacts, deals, history): `<Drawer.Section label="Контакты">` (`Modal.Section`), its button in `Drawer.Actions` inside it — not a `Typography as="h3"` row with buttons of your own.
|
|
139
157
|
- Never a hand-made `div` backdrop, dialog, menu or tooltip.
|
|
140
158
|
- Every Modal and Drawer has its `Header` (title, ×); `Body` (content, scrolls) and `Footer` (actions) are there when it has content and actions. Actions always go into the `Footer`: details `<Drawer.Footer><Drawer.Close><Button.Root variant="outline" tone="neutral">Закрыть</Button.Root></Drawer.Close></Drawer.Footer>`, plus the main action last; a form: «Отмена» + submit — not Save at the bottom of the body. A `Sheet` (from the bottom edge) is the opposite: no footer by default — a pick or a swipe ends it — and its header is optional: keep it when the content needs a title, drop it (× and hairline go too) when the content speaks for itself, with `aria-label` on `Sheet.Content`. Never `Drawer.Content side="bottom"`.
|
|
141
159
|
- Content inside a Drawer, a Sheet or a Card is the host's own: a calendar is `Datepicker.Panel` straight in the body, across its width — no card, no padded box around it.
|
|
142
160
|
- A destructive confirm is `<ConfirmDialog.Root title description confirmLabel onConfirm={remove}>` with a `ConfirmDialog.Trigger` — not a Modal assembled as a confirm with your own pending state; a reversible delete offers «Отменить» in the notification instead.
|
|
143
161
|
- Overlays close smoothly only if they stay mounted: render the `Root` always and drive visibility with `open` alone — never `{open && <Drawer.Root>}`, never a changing `key` on the Root. The kit keeps the last content on screen while the exit plays.
|
|
144
|
-
- Placement of a menu, popover, select or picker: leave the defaults — `side="bottom"`, `align="auto"`: it opens below the trigger, lines up with the trigger edge that has the room (a «⋯» at the end of a row grows toward the start) and flips to the top by itself. Never write `side` or `align` to restate that; set `align` only when the panel must line up with one edge of a block whatever room there is.
|
|
162
|
+
- Placement of a menu, popover, select or picker: leave the defaults — `side="bottom"`, `align="auto"`: it opens below the trigger, lines up with the trigger edge that has the room (a «⋯» at the end of a row grows toward the start) and flips to the top by itself. Never write `side` or `align` to restate that; set `align` only when the panel must line up with one edge of a block whatever room there is. A Popover under a wide anchor that must never be narrower than it: `<Popover.Content width="min-trigger">`.
|
|
145
163
|
- While a request runs: `<Modal.Guard busy={saving} />` inside the content (`Drawer.Guard`, `Sheet.Guard` alike) — Escape, a press outside, × and `Close` are held, × and `Close` disabled; add `dirty` to ask before unsaved changes are lost. Not `closeOnEscape={false}` or `showClose={false}` by hand.
|
|
146
164
|
|
|
147
165
|
## Motion — it comes with the components
|
|
@@ -167,12 +185,13 @@ State change is continuous in the whole kit: every region that changes what it s
|
|
|
167
185
|
- Refreshing data already on screen: keep it, set `aria-busy` — not back to a skeleton on every refetch.
|
|
168
186
|
- Table states in place: `loading` (+ `loadingRows`), `empty`, `loadError` on `DataTable` — the head and toolbar stay.
|
|
169
187
|
- First run of a page or region: `EmptyPage.Root` + `EmptyPage.Icon` + `EmptyPage.Title` + `EmptyPage.Description` + `EmptyPage.Actions` with one action — not «Здесь пока ничего нет».
|
|
170
|
-
- Page-level persistent problem: `<Banner.Root tone="danger">` first in `
|
|
188
|
+
- Page-level persistent problem: `<Banner.Root tone="danger">` first in `Page.Body`; the result of an action: `useNotifications().notify({ tone, title })` — a toast never closes the Drawer or Modal it was raised from.
|
|
189
|
+
- A refused sign-in: `invalid` on the fields it concerns and the reason in a `<VisuallyHidden live="assertive">` mounted from the start — not a Banner in a `LoginForm`.
|
|
171
190
|
|
|
172
191
|
## Sidebar
|
|
173
192
|
|
|
174
193
|
- Brand header: `Sidebar.Header` > `Sidebar.Brand href description` (with `Sidebar.BrandLogo`) + `<Sidebar.Toggle variant="header" />` — not a Toggle in the footer when the rail has a brand.
|
|
175
|
-
- Off-canvas: `offCanvas="auto"` (default, below 768px), `"always"` for navigation behind a menu at any width, `"never"` for a rail that always stays; the
|
|
194
|
+
- Off-canvas: `offCanvas="auto"` (default, below 768px), `"always"` for navigation behind a menu at any width, `"never"` for a rail that always stays; the page's `Page.TopBar` draws the menu button that opens it — no menu state of your own; another trigger reads `useAppShellNav()`.
|
|
176
195
|
- Every item is a link (`href` or `asChild` with the router `NavLink`; `current` marks the page), with a `Sidebar.ItemIcon` on the [top-level items and sub-list parents](layouts.md#sidebar-icons).
|
|
177
196
|
- The signed-in user: `Sidebar.Account` inside `Dropdown.Trigger` at the end of `Sidebar.Footer`.
|
|
178
197
|
- Structure: everyday places on top without a label, categories as `Sidebar.Group label collapsible` (one short word, 3–7 items), views of one section as `Sidebar.Sub` (one level, the parent only discloses) — not every group folded, not a sub-list inside a sub-list.
|
|
@@ -183,20 +202,19 @@ State change is continuous in the whole kit: every region that changes what it s
|
|
|
183
202
|
|
|
184
203
|
Full rules: [responsive.md](responsive.md).
|
|
185
204
|
|
|
186
|
-
- The page panel is `<PageToolbar.Root>` with `Tools` (`SmartFilter.Toolbar`), `Sections` (a `fullWidth` SegmentedControl), `View`, `Actions`, `Chips` — it orders and wraps them itself ([the page panel](responsive.md#page-panel--pagetoolbar)); not a hand-made flex row of tabs, search and buttons.
|
|
187
205
|
- Rearrange, never hide: every desktop function is on the phone, in another place or a menu — not `display: none` below a breakpoint.
|
|
188
206
|
- Breakpoints only in [their scope](responsive.md#breakpoints); inside a page — [intrinsic grids](responsive.md#intrinsic-grids) and container queries.
|
|
189
207
|
- A wide table scrolls inside itself; offer `DataTable.ColumnsMenu` in its `toolbar` — never drop columns by breakpoint, never hand-build the chooser.
|
|
190
208
|
- A row that opens a record page is `getRowHref` (a real link: ⌘-click, new tab), a row that opens a drawer is `onRowClick` — never `navigate()` in `onRowClick`, never your own `event.target` checks for buttons in the row.
|
|
191
|
-
- A list + detail screen is `
|
|
209
|
+
- A list + detail screen is `Page.Split` (`Page.List`, `Page.Detail`) in a `Page.Root fill` page, its records a `List` (`current` on the open one) — never ghost Buttons with a soft current; a full-height table is `scrollHeight="fill"` — never a height computed from `100vh`.
|
|
192
210
|
- App sections on phones: `BottomNav` in `AppShell.Footer` — not in Main, not `position: fixed`, no own media query: the shell hides the footer while the Sidebar rail is on screen; a short task from the bottom edge: `Sheet` — Select, Dropdown, Popover and Modal become sheets below 640 by themselves.
|
|
193
211
|
- Your hover styles inside `@media (hover: hover)`; nothing hover-only. Do not wrap kit fields to raise their text for iOS — they keep 16px on touch already.
|
|
194
212
|
- A long form saves through the panel action with a count («Сохранить 3 изменения») — not a sticky bar at the bottom of a phone.
|
|
195
|
-
- Sticky comes from the kit (`
|
|
213
|
+
- Sticky comes from the kit (`Page.TopBar`, the DataTable head, `stickyFirstColumn`, the Gantt header) — not your own `position: sticky` bar.
|
|
196
214
|
|
|
197
215
|
## Spacing and values
|
|
198
216
|
|
|
199
|
-
- Gaps are `gap` on the parent with `--prime-space-N` (N × 4px): 8 in a row of buttons, 16 tile → tile, 20 field → field, 32 group → group; `
|
|
217
|
+
- Gaps are `gap` on the parent with `--prime-space-N` (N × 4px): 8 in a row of buttons, 16 tile → tile, 20 field → field, 32 group → group; `Page` already spaces blocks 24 and sections 40 — not margins, not outer padding.
|
|
200
218
|
- Tokens only: `var(--prime-space-4)`, `var(--prime-color-text-secondary)`, `var(--prime-radius-m)` — never raw `px` / `rem` / hex, never `--prime-ref-*`, never inline `style`.
|
|
201
219
|
- Text through `Typography` roles (`title-m`, `title-s`, `body-m`, `caption`) and its `tone` — not `font-size` or `color` in CSS ([text colour](foundations.md#text-colour)).
|
|
202
220
|
|
|
@@ -231,19 +249,21 @@ applyTheme("light");
|
|
|
231
249
|
The frame itself (providers, `AppShell` with the `Sidebar`) is built once too: copy it from
|
|
232
250
|
[layouts.md](layouts.md#app-frame-once-per-app).
|
|
233
251
|
|
|
234
|
-
A document page (a form) — its title
|
|
252
|
+
A document page (a form) — its large title stands in the flow:
|
|
235
253
|
|
|
236
254
|
```tsx
|
|
237
|
-
import { Button, Icon, Input,
|
|
255
|
+
import { Button, Icon, Input, Page } from "prime-ui-kit";
|
|
238
256
|
import styles from "./ProfilePage.module.css"; // .form { display: grid; gap: var(--prime-space-5); }
|
|
239
257
|
|
|
240
258
|
export function ProfilePage() {
|
|
241
259
|
return (
|
|
242
|
-
<
|
|
243
|
-
<
|
|
244
|
-
<
|
|
245
|
-
|
|
246
|
-
|
|
260
|
+
<Page.Root maxWidth="readable">
|
|
261
|
+
<Page.Header>
|
|
262
|
+
<Page.Heading>
|
|
263
|
+
<Page.Title>Профиль</Page.Title>
|
|
264
|
+
</Page.Heading>
|
|
265
|
+
</Page.Header>
|
|
266
|
+
<Page.Body>
|
|
247
267
|
<form className={styles.form} noValidate onSubmit={(event) => event.preventDefault()}>
|
|
248
268
|
<Input.Root label="Рабочая почта" hint="На неё придут счета" required>
|
|
249
269
|
<Input.Wrapper>
|
|
@@ -255,8 +275,8 @@ export function ProfilePage() {
|
|
|
255
275
|
</Input.Root>
|
|
256
276
|
<Button.Root type="submit">Сохранить</Button.Root>
|
|
257
277
|
</form>
|
|
258
|
-
</
|
|
259
|
-
</
|
|
278
|
+
</Page.Body>
|
|
279
|
+
</Page.Root>
|
|
260
280
|
);
|
|
261
281
|
}
|
|
262
282
|
```
|
package/dist/skill/checklist.md
CHANGED
|
@@ -5,8 +5,11 @@ checks.
|
|
|
5
5
|
|
|
6
6
|
## Composition
|
|
7
7
|
- [ ] The screen starts from the closest working screen and keeps its skeleton ([screens](composition.md#screens)).
|
|
8
|
-
- [ ]
|
|
9
|
-
- [ ] The
|
|
8
|
+
- [ ] One `Page.Title` per page, always an `<h1>`: a work screen titles itself in the `Page.Heading` of its `Page.TopBar`, a document page or an overview in a `Page.Header` in the flow ([page skeleton](composition.md#1-page-skeleton)).
|
|
9
|
+
- [ ] The top bar holds only this page's groups — `Page.Heading`, `Page.Tools`, `Page.Actions`, `Page.Chips` — no app-wide header or global search ([the top bar](composition.md#the-top-bar)).
|
|
10
|
+
- [ ] A nested record's path ends in its title on one line inside `Page.Heading`; no title row under the path ([the top bar](composition.md#the-top-bar)).
|
|
11
|
+
- [ ] Every button of the page is in one `Page.Actions`, the primary last, each with a `Button.Icon` ([the top bar](composition.md#the-top-bar)).
|
|
12
|
+
- [ ] `SmartFilter.Root` wraps `Page.Root`; its toolbar is in `Page.Tools`, its chips in `Page.Chips` ([the top bar](composition.md#the-top-bar)).
|
|
10
13
|
- [ ] A Card only for a standalone titled block — never around a table, a single field or the page ([surfaces](composition.md#4-surfaces)).
|
|
11
14
|
|
|
12
15
|
## UX ([ux.md](ux.md))
|
|
@@ -17,6 +20,7 @@ checks.
|
|
|
17
20
|
- [ ] Buttons say the verb and the object, errors say how to fix it, empty states offer the next step ([words](ux.md#4-words)).
|
|
18
21
|
- [ ] Money, numbers and dates go through `Intl` with `ru-RU`, in Russian typography ([words](ux.md#4-words)).
|
|
19
22
|
- [ ] The friction of every action matches the cost of a mistake ([friction](ux.md#5-friction-matches-the-cost-of-a-mistake)).
|
|
23
|
+
- [ ] A form in a dialog holds its dismiss with `Modal.Guard` / `Drawer.Guard`, a form that is the page with `Page.Guard` ([friction](ux.md#5-friction-matches-the-cost-of-a-mistake)).
|
|
20
24
|
- [ ] A disabled control says why when the reason is off screen; an action without permission is hidden ([nothing to guess](ux.md#6-nothing-to-guess)).
|
|
21
25
|
- [ ] A request a value starts — a simulated one too — is cancelled when the value changes again ([nothing to guess](ux.md#6-nothing-to-guess)).
|
|
22
26
|
- [ ] Tabs, filters, search, page and the open record are in the URL ([nothing to guess](ux.md#6-nothing-to-guess)).
|
|
@@ -63,6 +67,8 @@ checks.
|
|
|
63
67
|
- [ ] Fields show `hint` and `error`; only the minority is marked `required` or `optional` ([forms](api-contract.md#forms)).
|
|
64
68
|
- [ ] Every data block has its loading, empty and error states ([feedback](composition.md#9-feedback)).
|
|
65
69
|
- [ ] Every region swaps its states through `Crossfade`, loading is a `Skeleton` of the data ([continuity](foundations.md#11-state-changes-are-continuous)).
|
|
70
|
+
- [ ] A `Page.Description` that waits for data stays mounted with `loading`, so the title in the bar never jumps ([screen states](composition.md#screen-states)).
|
|
71
|
+
- [ ] A KPI tile that waits for its figure is `Card.Root loading`, its parts mounted ([inside a category](choosing.md#2-inside-a-category)).
|
|
66
72
|
- [ ] While a form saves, its submit is `loading` and its fields sit in a `Fieldset disabled` ([forms](api-contract.md#forms)).
|
|
67
73
|
- [ ] A save that stays says «Сохранено» on its button, one that goes away notifies, a failure always shows ([feedback](composition.md#9-feedback)).
|
|
68
74
|
- [ ] Overlays stay mounted and are driven by `open` only ([motion mistakes](motion.md#6-mistakes)).
|
|
@@ -72,10 +78,13 @@ checks.
|
|
|
72
78
|
|
|
73
79
|
## Themes and widths
|
|
74
80
|
- [ ] The screen passes the responsive checklist in both themes ([responsive](responsive.md#checklist-before-handing-a-screen-over)).
|
|
75
|
-
- [ ] On a phone the Sidebar opens from the menu button the
|
|
81
|
+
- [ ] On a phone the Sidebar opens from the menu button the top bar draws; the page title stays in the bar ([app frame](layouts.md#app-frame-once-per-app)).
|
|
82
|
+
- [ ] At every width the bar fits: tools on their own line, then icon-only buttons, then «⋯», the primary always on screen ([the page's top bar](responsive.md#the-pages-top-bar--pagetopbar)).
|
|
76
83
|
|
|
77
84
|
## Keyboard and a11y
|
|
78
85
|
- [ ] Every action is reachable by Tab in reading order and works with Enter / Space ([interaction](responsive.md#interaction-and-accessibility)).
|
|
79
86
|
- [ ] Every field has a label (visible, or `aria-label` for a toolbar search) ([forms](api-contract.md#forms)).
|
|
80
87
|
- [ ] Meaning is never colour alone ([tone and color](foundations.md#6-tone-and-color)).
|
|
88
|
+
- [ ] A toned hint says its status in words; a validation problem is `error`, never a `danger` hint ([forms](api-contract.md#forms)).
|
|
89
|
+
- [ ] A refused sign-in marks its fields `invalid` and says why in a hidden live region, with no Banner ([feedback](composition.md#9-feedback)).
|
|
81
90
|
- [ ] Custom `labels` replace the default Russian strings where they do not fit ([system strings](api-contract.md#shared-vocabulary-exported-types)).
|
package/dist/skill/choosing.md
CHANGED
|
@@ -10,12 +10,12 @@ confuse. Links: [components.md](components.md). Whole screens: [composition.md](
|
|
|
10
10
|
| trigger an action (save, delete, go on) | Actions — Button, ButtonGroup, LinkButton |
|
|
11
11
|
| type a value (text, number, code, file, photos), group the fields of a form, edit a list of records of one shape | Inputs — Input, Textarea, DigitInput, FileUpload, Label, Hint, Fieldset, FieldList |
|
|
12
12
|
| pick from options, toggle, set a range, filter, a date or a color | Selection — Checkbox, Radio, Switch, SegmentedControl, Slider, Select, NativeSelect, TagSelect, SmartFilter, Datepicker, ColorField, ColorPicker, ColorSwatches |
|
|
13
|
-
| see data: status labels, people, objects, numbers and their trend, properties of a record, rows, a board, a schedule, events, code, disclosed sections | Data display — Badge, Avatar, Thumbnail, Kbd, Card, DescriptionList, DataTable, Kanban, Gantt, Timeline, CodeBlock, Accordion, Sparkline, ChartFrame |
|
|
13
|
+
| see data: status labels, people, objects, numbers and their trend, properties of a record, rows, a board, a schedule, events, code, disclosed sections | Data display — Badge, Avatar, Thumbnail, Kbd, Card, DescriptionList, DataTable, Kanban, Gantt, Timeline, CodeBlock, RichText, Accordion, Sparkline, ChartFrame |
|
|
14
14
|
| hold a conversation: pick a dialog, read and send chat messages of every kind | Messages — Chat, ChatList, Message, Gallery, VoicePlayer, VideoNote, Composer |
|
|
15
15
|
| learn what happened, how far along it is, or watch a region load and change state; say it to a screen reader | Status and loading — Banner, Notification, ProgressBar, ProgressCircle, Spinner, Skeleton, Crossfade, EmptyPage, VisuallyHidden |
|
|
16
16
|
| move between places: app sections, panels of a screen, the records of a list, the path, pages, steps | Navigation — Tabs, Breadcrumb, Pagination, List, Stepper, Sidebar, BottomNav |
|
|
17
17
|
| see something on top of the page, or a photo or video full screen | Overlays — Tooltip, Popover, Dropdown, Modal, ConfirmDialog, Drawer, Sheet, CommandMenu, MediaViewer |
|
|
18
|
-
| get the app frame and the structure of a page, or a whole ready-made screen block (sign-in, sign-up, password reset, code) | Page — AppShell,
|
|
18
|
+
| get the app frame and the structure of a page, or a whole ready-made screen block (sign-in, sign-up, password reset, code) | Page — AppShell, Page, Divider, ScrollContainer, LoginForm |
|
|
19
19
|
| drag things by hand | Interaction — Dnd (a status board: Kanban in Data display) |
|
|
20
20
|
| style text | Foundations — Typography |
|
|
21
21
|
|
|
@@ -33,7 +33,8 @@ Input with `Input.InlineAffix`. Search and filters above a list or table → Sma
|
|
|
33
33
|
field outside a list (a picker, a settings section, a panel) → Input with `Input.Icon` + `type="search"`
|
|
34
34
|
and `aria-label`. Several fields of a form under one heading → Fieldset (`label`, `disabled` while the
|
|
35
35
|
form saves). Several records of the same fields that a person adds, edits and removes (invoice lines,
|
|
36
|
-
contacts, specs, prices by period) → FieldList: one row per record, the headings once
|
|
36
|
+
contacts, specs, prices by period) → FieldList: one row per record, the headings once; their sums
|
|
37
|
+
under them → its `renderTotals`.
|
|
37
38
|
|
|
38
39
|
**Selection.**
|
|
39
40
|
|
|
@@ -46,21 +47,27 @@ contacts, specs, prices by period) → FieldList: one row per record, the headin
|
|
|
46
47
|
| one of many (> 5) or a long list; icons, descriptions, search, groups | Select (`Select.Content searchable`) |
|
|
47
48
|
| one record out of thousands for a form field (a client, a contract), searched on the server | Select with `search` / `onSearchChange`, `filter={false}`, `loading`, `hasMore` + `onLoadMore` — never a read-only field that opens a CommandMenu |
|
|
48
49
|
| one value from a plain text list on a mobile-first form, posted with the form (`name`) | NativeSelect — the OS picker opens on phones |
|
|
50
|
+
| free text the team often repeats (a place, a city), any other text allowed | Input with `suggestions` — never a `<datalist>`, never a Select |
|
|
51
|
+
| a pick that belongs to a text (an icon before a name) | Select with only `Select.TriggerIcon` inside `Input.Wrapper`, named by `aria-label` |
|
|
49
52
|
| several of many, shown as tags, with search / creation | TagSelect (`Select.Root multiple` when tags are not needed) |
|
|
50
53
|
| narrowing a list or table by several fields, with search and show / hide | SmartFilter |
|
|
51
54
|
| an approximate number in a range | Slider (exact number → Input) |
|
|
52
55
|
| a date or a period | Datepicker |
|
|
56
|
+
| a time of day without a date | Input with `Input.Field type="time"` (a date with a time → Datepicker `withTime`) |
|
|
53
57
|
| a color from a fixed palette in a form or dialog | ColorSwatches (inline grid, default choice) |
|
|
54
|
-
| a compact color next to a field or in a list row | ColorPresets (trigger + popover palette) |
|
|
58
|
+
| a compact color next to a field or in a list row | ColorPresets (trigger + popover palette; `allowCustom` when any hex is valid too) |
|
|
55
59
|
| any color as a field of a form (swatch + hex, picker in a popover) | ColorField |
|
|
56
60
|
| any color in a panel of its own (hex, eyedropper, channels) | ColorPicker |
|
|
57
61
|
|
|
58
62
|
**Data.** Status, count, removable value or applied filter → Badge (`tone` for a status, `color` for a
|
|
59
|
-
category, `onRemove` to remove, `pressed` / `onPressedChange` to toggle)
|
|
63
|
+
category, `onRemove` to remove, `pressed` / `onPressedChange` to toggle); several badges as one value
|
|
64
|
+
(a client's tags) → `Badge.Group`. Person or organization → Avatar. Object (product, vehicle, file, cover) → Thumbnail with a
|
|
60
65
|
`ratio` — never a round Avatar for things. Keyboard shortcut → Kbd. One block of related
|
|
61
66
|
numbers/content → Card (pick the template; a whole tile that opens its details → `Card.Root asChild`
|
|
62
67
|
with a link). Read-only properties of one record («label — value») → DescriptionList, never a
|
|
63
|
-
hand-made grid of text pairs. Rows with columns, sorting, selection → DataTable
|
|
68
|
+
hand-made grid of text pairs. Rows with columns, sorting, selection → DataTable (a header that
|
|
69
|
+
needs explaining → the column's `description`). A KPI tile waiting for its figure →
|
|
70
|
+
`Card.Root loading`, never Skeletons inside its parts.
|
|
64
71
|
Items that flow through statuses and are moved by hand → Kanban (a single list to reorder, or items
|
|
65
72
|
dropped onto folders or assignees → Dnd directly). Its look: `plain` (default; `line` for a quieter header over a line) when the board is
|
|
66
73
|
the page's main region or sits in a Card / Drawer — headers and cards stand on the host, one level of
|
|
@@ -69,7 +76,7 @@ columns, a dense board of narrow columns). Never your own box around a column.
|
|
|
69
76
|
Records with a start and an end compared across time — who is busy when, a project plan with
|
|
70
77
|
phases and milestones → Gantt (never a DataTable of dates or hand-drawn bars); moved and resized by
|
|
71
78
|
hand through `onBarChange`.
|
|
72
|
-
Chronological events → Timeline; a conversation between people (support, a team chat) → Message —
|
|
79
|
+
Chronological events → Timeline (two facts under an event → two `Timeline.ItemMeta`, they stack); a conversation between people (support, a team chat) → Message —
|
|
73
80
|
never a Timeline or a list of Cards styled as bubbles. Code → CodeBlock. A number with its trend over days or weeks (revenue, orders, sign-ups) → Sparkline: the latest value, its change and a line you can scrub; values with a sign by period → Sparkline `variant="bars"`; against a plan → `reference`; missing days → `value: null`; a chart with axes or several series → ChartFrame around a chart library or your own SVG (the panel, legend, tooltip, states and the screen-reader table come from the kit, the colors from `series` / `chartColors` — never status tones); values to read, sort or compare row by row → DataTable, not a chart.
|
|
74
81
|
|
|
75
82
|
**Messages.** A whole conversation → `Chat`: `Chat.Root` with `Chat.Header` (avatar, `Chat.Title`,
|
|
@@ -92,7 +99,11 @@ comment, a report) → `Gallery`; one picture of an object → `Thumbnail`. A vi
|
|
|
92
99
|
`Message.Media` or `Thumbnail.Video`, not VideoNote. «Печатает…» → `Chat.Root typing` (or
|
|
93
100
|
`Message.Typing`), never a text row; a jump to a message → `Message.Reply target`, `Chat.Pinned` or
|
|
94
101
|
`Chat.Root jumpTo`, never `scrollIntoView`; search inside a chat → `Chat.Search`. Files, photos,
|
|
95
|
-
places and contacts sent in a chat → the `Message` parts, not FileUpload rows or Cards
|
|
102
|
+
places and contacts sent in a chat → the `Message` parts, not FileUpload rows or Cards; a sticker →
|
|
103
|
+
`Message.Sticker` (a Lottie or video sticker is your player inside it). A message shown outside a
|
|
104
|
+
chat (a bot's welcome message in its settings) → `Message.Root preview`; its formatted text alone →
|
|
105
|
+
`RichText`, never `dangerouslySetInnerHTML`. Times and date separators in a profile's zone →
|
|
106
|
+
`timeZone` on `Chat.Messages`, `ChatList.Root` and a lone `Message.Root`.
|
|
96
107
|
|
|
97
108
|
**Status and loading.** See the pair below. Progress of a single task → ProgressBar `value`; parts of a whole →
|
|
98
109
|
ProgressBar `segments` (categories wear `color`, meanings wear `tone`; `legend` for color · name ·
|
|
@@ -111,7 +122,8 @@ loading, data, empty and error, or showing one record at a time → its content
|
|
|
111
122
|
**Overlays.** See the pairs below. Global search over commands and pages (⌘K) → CommandMenu. Menus,
|
|
112
123
|
selects, pickers and Modal turn into bottom sheets below 640px by themselves — never build your own.
|
|
113
124
|
A photo, a scan or a video opened full screen from its thumbnail (a Gallery tile, a Thumbnail button)
|
|
114
|
-
→ MediaViewer, never a Modal with an `<img>`.
|
|
125
|
+
→ MediaViewer, never a Modal with an `<img>`. A titled block inside a Drawer or a Modal (a client's
|
|
126
|
+
contacts, its deals) → `Drawer.Section` / `Modal.Section`.
|
|
115
127
|
|
|
116
128
|
**Phone navigation.** App navigation is Sidebar on a wide screen and `BottomNav` in `AppShell.Footer`
|
|
117
129
|
on a phone for 2–6 main sections (the shell hides it by itself while the Sidebar rail is on screen;
|
|
@@ -122,14 +134,16 @@ Drawer menu.
|
|
|
122
134
|
`Sidebar.Header` — at the header's end while expanded, a small round button on the rail's edge while
|
|
123
135
|
compact (the default for a branded rail); `Sidebar.Toggle` (`variant="item"`) in `Sidebar.Footer` when
|
|
124
136
|
the rail has no brand header. On phones the off-canvas Sidebar opens from the menu button the
|
|
125
|
-
`
|
|
126
|
-
panel is the page's `
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
`
|
|
131
|
-
|
|
132
|
-
|
|
137
|
+
page's `Page.TopBar` draws by itself; a trigger of your own reads `useAppShellNav()`. There is no
|
|
138
|
+
app-wide header: the bar at the top of the panel is the page's `Page.TopBar` — on a work screen the
|
|
139
|
+
title group (`Page.Heading`), the page's tools (`Page.Tools`), its buttons (`Page.Actions`) and the
|
|
140
|
+
active filters (`Page.Chips`) — [the top bar](composition.md#the-top-bar). A document
|
|
141
|
+
page (settings, a long form, help) or an overview has its large title in the flow (`Page.Header`
|
|
142
|
+
outside the bar), with an optional `Page.TopBar collapse` that repeats it once it scrolls away. A record opened from a table: its own page → DataTable `getRowHref`; in place →
|
|
143
|
+
`onRowClick` + Drawer; a list worked through record by record → `Page.Split` with a `List` of
|
|
144
|
+
the records (tickets, letters, invoices; `current` on the open one; a row's own Switch or menu in
|
|
145
|
+
`List.ItemActions`) or a `ChatList` of the conversations. A record edited on a page of its own →
|
|
146
|
+
`Page.Guard` holds leaving it with unsaved changes. Sections of a long rail → `Sidebar.Group collapsible`; a section with sub-pages →
|
|
133
147
|
`Sidebar.Sub`; the signed-in user → `Sidebar.Account` in a `Dropdown.Trigger` at the bottom of
|
|
134
148
|
`Sidebar.Footer`.
|
|
135
149
|
|
|
@@ -145,14 +159,14 @@ conversations. Sections of a long rail → `Sidebar.Group collapsible`; a sectio
|
|
|
145
159
|
| Select / Dropdown / CommandMenu / TagSelect | Select picks a **value** for a field (form data). Dropdown runs **actions** (Edit, Duplicate, Delete). CommandMenu searches commands and pages across the app (locally or on the server) — it is not a field. TagSelect picks **several values** as tags. |
|
|
146
160
|
| SmartFilter / SegmentedControl / Select | Search and filters over a list → SmartFilter (`fields={[]}` for a search alone), even with one field. A switch of what the same data shows (sections with counts, a period, a view) → SegmentedControl, or a Select when the options are many. |
|
|
147
161
|
| Badge / Button | A badge labels or holds a value (status, filter, keyword): `onRemove` drops it, `pressed` toggles it. A command (save, open, go) is always a Button. |
|
|
148
|
-
| Banner / Notification / Hint | Banner: persistent message in the page flow about a page/section state (sync failed, trial ends). Notification: transient toast about the result of an action (saved, failed). Hint / `error`: help or validation text under one field. |
|
|
162
|
+
| Banner / Notification / Hint | Banner: persistent message in the page flow about a page/section state (sync failed, trial ends). Notification: transient toast about the result of an action (saved, failed). Hint / `error`: help or validation text under one field; a status of its value (a deadline that nears) → `hintTone` on the field, `tone` on a lone Hint. |
|
|
149
163
|
| ProgressBar / ProgressCircle / Spinner | ProgressBar: a share with width to spare and words beside it (an upload row, an import, a quota line). ProgressCircle: a share on the data scale (24–80) where width is short or a ring reads better (a KPI goal, a ring breakdown, a named import card); `value={null}` while the share is unknown, `spin` while a share grows, an icon in the centre. Spinner: an anonymous «busy» on the icon scale inside a control or a status line, no share, no name of its own. A ring you can press (cancel, retry, download a transfer) → Button `shape="circle"` with `progress`, not any of the three. |
|
|
150
164
|
| Button / LinkButton | Button does something (submit, open, delete). LinkButton goes somewhere (a URL, «Подробнее», «Все заказы»). |
|
|
151
165
|
| Checkbox / Switch / Radio | Checkbox: choice submitted later with a button, can be multiple. Switch: on/off that applies at once (no Save button). Radio: one of several, submitted later. A privacy toggle inside a create form that is submitted → Checkbox. |
|
|
152
166
|
| Gallery / MediaViewer / Thumbnail | Thumbnail: one picture or video of an object in a list, card or picker (selectable with `checked`). Gallery: an album of 1–10 photos and videos laid out by their ratios; it opens MediaViewer itself. MediaViewer: the full-screen viewer on its own, opened from your own thumbnails or a button (`getOrigin` for the zoom out of the tile). A grid of many images to browse → a CSS grid of Thumbnails, not a Gallery. |
|
|
153
167
|
| Sparkline / ChartFrame | Sparkline: one series as a headline number with its change and a small line or bars you can scrub (`variant="bars"` for signed values). ChartFrame: a panel around a real chart (axes, several series, legend, tooltip, states) drawn by a library or your SVG. Rows to compare → DataTable. |
|
|
154
168
|
| VoicePlayer / VideoNote | The same player props (`src`, `duration`, `playing`, transcript, `transfer`). VoicePlayer: audio, a waveform seek slider and a playback rate. VideoNote: a round face-to-camera video with a `poster`; alone in `Message.Root` it is the message. A video with controls → `Thumbnail.Video` / `Message.Media`. |
|
|
155
|
-
| Card / plain section / Grid | Card for a bounded block of related content that stands out (metric, settings panel, side facts). A page section that is the only thing in its region needs no card: `
|
|
169
|
+
| Card / plain section / Grid | Card for a bounded block of related content that stands out (metric, settings panel, side facts). A page section that is the only thing in its region needs no card: `Page.Section label` and the content. Several tiles of one screen → one `Page.Grid` with a `Page.Cell span` each; a grid inside one block (thumbnails, fields) is the block's own CSS. Never wrap a single field, a DataTable or a whole page in a Card. |
|
|
156
170
|
| EmptyPage / empty DataTable | Empty table (no rows yet or nothing matches the filter): the DataTable `empty` prop — headers and toolbar stay. Whole page or region with no data at all (first run): EmptyPage with one action. |
|
|
157
171
|
| Accordion / Tabs | Accordion when the user may need several sections open or reads them in order (FAQ, settings groups). Tabs when sections are alternatives viewed one at a time. |
|
|
158
172
|
| Divider / gap | Divider inside a block between rows or a form and its footer. Between blocks and groups use air (`gap`), not lines. |
|
|
@@ -162,7 +176,7 @@ conversations. Sections of a long rail → `Sidebar.Group collapsible`; a sectio
|
|
|
162
176
|
| Gantt / Timeline / Kanban / DataTable | Gantt: records with a start and an end compared across time (who is busy when, a plan with phases and milestones), moved, stretched and drawn by hand (`onBarChange`, `onBarCreate`). Timeline: a history of events at points in time, read top to bottom. Kanban: work items moved between statuses, time does not matter. DataTable: many records compared by many attributes, sorted, filtered and selected — dates are only columns. |
|
|
163
177
|
| DescriptionList / DataTable / Card | DescriptionList: the properties of **one** record as «label — value» pairs (requisites, deal terms, a summary before a confirm). DataTable: **many** records with the same properties. Card: the bounded block they sit in, or one headline number (`mini`, `stat-trend`) — a DescriptionList inside a `Card.Body`, never a Card per property. |
|
|
164
178
|
| ConfirmDialog / Modal / `holdToConfirm` / undo | Which of them an action deserves is its cost: [ux.md → friction](ux.md#5-friction-matches-the-cost-of-a-mistake). ConfirmDialog only asks a question (`onConfirm` returns the request; pending, failure and dismiss rules are built in); a form, a choice or more than a sentence of content → Modal; never a Modal hand-built as a confirm. |
|
|
165
|
-
| Composer / Textarea | Composer: the message input of a conversation — Enter sends, attachments, a reply or edit bar, voice and round video. Textarea: long text saved with a form (a description, a comment field) by its submit button. |
|
|
179
|
+
| Composer / Textarea / RichText | Composer: the message input of a conversation — Enter sends, attachments, a reply or edit bar, voice and round video. Textarea: long text saved with a form (a description, a comment field) by its submit button; `formatting` when the text keeps the chat's Markdown. RichText: that Markdown shown, read-only, outside a message (a template, a bot's welcome text). |
|
|
166
180
|
| Chat / Message / Gallery | Chat: a conversation — the header, search, pinned, the one message list (dates, runs, selection, jumps, read receipts, typing) and the Composer in its footer; a list without the rest is `Chat.Root` with `Chat.Messages`. Message: one message and its content parts — a row of that list, or a bubble on its own (a quoted reply in a ticket). Gallery: an album of photos and videos laid out by their ratios — `Message.Media` in a message, `Gallery` anywhere else (a post, a comment, a report). |
|
|
167
181
|
| Message / Timeline / Notification | Message: what people say to each other in a conversation, in bubbles. Timeline: what happened to a record (status changes, an audit log). Notification: the result of the user's own action, for a few seconds. A chat event («Анна добавила Олега») is `Chat.Service`, not a Notification. |
|
|
168
182
|
| FileUpload list / grid / gallery / strip | One component, four shapes. **List** (`layout="list"`, the default, with the drop zone): documents of a form, where the name matters; rows do not reorder. **Cards** (`trigger="tile"` `layout="grid"`): mixed photos and documents whose order matters (an inspection report). **Gallery** (`trigger="tile"` `layout="grid"` `cover` `accept="image/*"`): the photos of one object (a listing, a product); the first is the cover and dragging a photo first makes it the cover — no «make cover» button. **Strip** (`trigger="button"` + `FileUpload.Queue layout="strip"`): a paperclip and one scrolling row of tiles above a message field; the Composer already is this. Files on a server are `value` + `onValueChange` (return a promise to save); uploads are `queue` from `useUploadQueue`. One picture of a person is the avatar zone, not a gallery. |
|
package/dist/skill/components.md
CHANGED
|
@@ -78,6 +78,7 @@ Show data: labels, people, objects, cards, tables, boards, feeds, code, disclose
|
|
|
78
78
|
| Gantt | A resource or project schedule: rows of people, rooms, vehicles or tasks with bars on a day / week / month axis, edited by pointer and keyboard. | [COMPONENT.md](reference/components/gantt/COMPONENT.md) · [examples](reference/components/gantt/examples/) |
|
|
79
79
|
| Timeline | An event feed: dots on a thin line, event title and date, an optional amount on the right, grouped under labels. | [COMPONENT.md](reference/components/timeline/COMPONENT.md) · [examples](reference/components/timeline/examples/) |
|
|
80
80
|
| CodeBlock | A static TypeScript / TSX snippet with syntax highlighting, on a filled panel or bare inside a host. | [COMPONENT.md](reference/components/code-block/COMPONENT.md) · [examples](reference/components/code-block/examples/) |
|
|
81
|
+
| RichText | Text in the chat's Markdown subset outside a message — a bot's welcome text, a template, a comment — rendered as elements, never as HTML. | [COMPONENT.md](reference/components/rich-text/COMPONENT.md) · [examples](reference/components/rich-text/examples/) |
|
|
81
82
|
| Accordion | Collapsible sections: FAQ, settings groups, checkout steps. | [COMPONENT.md](reference/components/accordion/COMPONENT.md) · [examples](reference/components/accordion/examples/) |
|
|
82
83
|
| Sparkline | A small chart — a smooth line over a fading area, a bare line or bars — with its headline: the value at rest, its change and its date; any point can be scrubbed. | [COMPONENT.md](reference/components/sparkline/COMPONENT.md) · [examples](reference/components/sparkline/examples/) |
|
|
83
84
|
| ChartFrame | A dashboard panel around any chart — Recharts, ECharts, visx, Chart.js or a hand-drawn SVG — with the title, a headline value, a measured plot area, a series legend, a tooltip body and a data table for screen readers. | [COMPONENT.md](reference/components/chart-frame/COMPONENT.md) · [examples](reference/components/chart-frame/examples/) |
|
|
@@ -145,14 +146,12 @@ Floating layers above the page, from tooltip to modal.
|
|
|
145
146
|
|
|
146
147
|
## Page (`page`)
|
|
147
148
|
|
|
148
|
-
The frame and structure of a screen: app shell,
|
|
149
|
+
The frame and structure of a screen: app shell, the page (its top bar, header, tools, sections, grid, list and detail), separators, scroll regions, and ready-made screen blocks (sign-in).
|
|
149
150
|
|
|
150
151
|
| Component | Purpose | Docs |
|
|
151
152
|
|---|---|---|
|
|
152
|
-
| AppShell | The app frame: a content panel that is the page itself and a navigation rail one layer above it. | [COMPONENT.md](reference/layout/app-shell/COMPONENT.md) · [examples](reference/layout/app-shell/examples/) |
|
|
153
|
-
|
|
|
154
|
-
| PageContent | Page structure inside the main column: title, page actions and content blocks, titled sections and the tile grid of a dashboard; a page as high as the panel and the list + detail layout. | [COMPONENT.md](reference/components/page-content/COMPONENT.md) · [examples](reference/components/page-content/examples/) |
|
|
155
|
-
| PageToolbar | The panel at the top of a page — sections, filter and search, view options and the primary action — laid out from its own width: one row when wide, stacked rows when narrow, search and filter always first with the active filters under the top row. | [COMPONENT.md](reference/components/page-toolbar/COMPONENT.md) · [examples](reference/components/page-toolbar/examples/) |
|
|
153
|
+
| AppShell | The app frame — navigation and the page: a content panel that is the page itself and a navigation rail one layer above it. | [COMPONENT.md](reference/layout/app-shell/COMPONENT.md) · [examples](reference/layout/app-shell/examples/) |
|
|
154
|
+
| Page | The page inside the app frame: everything at the top belongs to it — a top bar with the title, tools and buttons, the large document title in the flow — then sections, the tile grid and the list + detail layout. | [COMPONENT.md](reference/layout/page/COMPONENT.md) · [examples](reference/layout/page/examples/) |
|
|
156
155
|
| Divider | A hairline separator inside one surface, horizontal or vertical, with or without a label. | [COMPONENT.md](reference/components/divider/COMPONENT.md) · [examples](reference/components/divider/examples/) |
|
|
157
156
|
| ScrollContainer | The kit's one scroll region: a thin scrollbar, soft edges wherever content is hidden, and correct shrinking inside flex and grid parents. | [COMPONENT.md](reference/components/scroll-container/COMPONENT.md) · [examples](reference/components/scroll-container/examples/) |
|
|
158
157
|
| LoginForm | A sign-in card with a logo, title, provider buttons and a form; covers sign-in, sign-up, password reset and code confirmation. | [COMPONENT.md](reference/components/login-form/COMPONENT.md) · [examples](reference/components/login-form/examples/) |
|