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
|
@@ -13,142 +13,167 @@ playground page. What each screen teaches is in [Screen rules](#screen-rules) at
|
|
|
13
13
|
|
|
14
14
|
| Screen | Main component | File | Shows |
|
|
15
15
|
|---|---|---|---|
|
|
16
|
-
| [List page](#list-page) | data-table | [screen.tsx](reference/components/data-table/examples/screen.tsx) | the title, a line of figures, SmartFilter search and filters, export and one primary action in the
|
|
17
|
-
| [Detail page](#detail-page) | description-list | [screen.tsx](reference/components/description-list/examples/screen.tsx) | a nested record:
|
|
18
|
-
| [Settings page](#settings-page) | page
|
|
19
|
-
| [Form in a Drawer](#form-in-a-drawer) | drawer | [screen.tsx](reference/components/drawer/examples/screen.tsx) | the title, counts, search and the Drawer trigger in the
|
|
20
|
-
| [Record editor](#record-editor) | field-list | [screen.tsx](reference/components/field-list/examples/screen.tsx) | a document page (a long form): the title
|
|
21
|
-
| [Dashboard](#dashboard) | card | [screen.tsx](reference/components/card/examples/screen.tsx) | title + a line of data in
|
|
22
|
-
| [Screen states](#screen-states) | crossfade | [screen.tsx](reference/components/crossfade/examples/screen.tsx) | title + the statement date in `
|
|
23
|
-
| [Messenger](#messenger) | chat | [screen.tsx](reference/components/chat/examples/screen.tsx) | title + the unread count in `
|
|
24
|
-
| [Sales pipeline board](#sales-pipeline-board) | kanban | [screen.tsx](reference/components/kanban/examples/screen.tsx) |
|
|
25
|
-
| [App frame](#app-frame) | app-shell | [screen.tsx](reference/layout/app-shell/examples/screen.tsx) | Sidebar rail on a wide screen, floating BottomNav in `AppShell.Footer` on a phone («Ещё» opens the Sidebar panel),
|
|
26
|
-
| [Media library](#media-library) | file-upload | [screen.tsx](reference/components/file-upload/examples/screen.tsx) |
|
|
27
|
-
| [Resource schedule](#resource-schedule) | gantt | [screen.tsx](reference/components/gantt/examples/screen.tsx) |
|
|
16
|
+
| [List page](#list-page) | data-table | [screen.tsx](reference/components/data-table/examples/screen.tsx) | the title, a line of figures, SmartFilter search and filters, export and one primary action in the page's top bar; statuses, row menu, pages, filtered empty state |
|
|
17
|
+
| [Detail page](#detail-page) | description-list | [screen.tsx](reference/components/description-list/examples/screen.tsx) | a nested record: the path ending in the title, status and due date and the record's actions by weight in the top bar; main column + side column of Cards, Timeline |
|
|
18
|
+
| [Settings page](#settings-page) | page | [screen.tsx](reference/layout/page/examples/screen.tsx) | the path in a collapsing top bar, the large title in the flow, heading column + panel per section, form with its own save, Switches that apply at once, danger zone with a confirm |
|
|
19
|
+
| [Form in a Drawer](#form-in-a-drawer) | drawer | [screen.tsx](reference/components/drawer/examples/screen.tsx) | the title, counts, search and the Drawer trigger in the top bar; Drawer form: groups, errors on submit, focus on the first invalid field, loading, toast |
|
|
20
|
+
| [Record editor](#record-editor) | field-list | [screen.tsx](reference/components/field-list/examples/screen.tsx) | a document page (a long form): the title and a line of description in `Page.Heading`, «Сохранить тариф» in `Page.Actions`, both in a `Page.Header` in the flow; a plan card edited in aside sections: name and description, specs in a `FieldList` (icon-only `Select` and `ColorPresets` in compact columns, pinned rows, reorder), the price and its changes by month in one list with the base row pinned, a setup fee in three currencies in one row under one heading, save with «Сохранено» on the button |
|
|
21
|
+
| [Dashboard](#dashboard) | card | [screen.tsx](reference/components/card/examples/screen.tsx) | the large title + a line of data in the flow, period switch and report in a collapsing `Page.TopBar`; KPI row that cross-fades to the new period, a Sparkline revenue trend, invoiced vs paid in a ChartFrame, panels with progress and a split, short table + link to the list |
|
|
22
|
+
| [Screen states](#screen-states) | crossfade | [screen.tsx](reference/components/crossfade/examples/screen.tsx) | title + the statement date in `Page.TopBar`, page error in a Banner with retry, region loading with a Skeleton, Crossfade between states, table error in place, first-run EmptyPage |
|
|
23
|
+
| [Messenger](#messenger) | chat | [screen.tsx](reference/components/chat/examples/screen.tsx) | title + the unread count in `Page.TopBar`; a full-height Page.Split of a `ChatList` with its search (live last message, ticks, unread counts, «печатает…») and a `Chat`: `Chat.Header` with the back button, avatar, title, the status that turns into «печатает…» (`typing`) and the search button, `Chat.Search`, `Chat.Messages` from `items` + `renderMessage` (dates, runs and the unread band from the data, history loaded above with `hasOlder` / `onLoadOlder`, a first load in skeletons), text, a photo, a file and sent voice, reply and edit from the menu through `Composer.Context messageId` (`replyTo` / `editOf`), the jump to the quoted message (`Message.Reply target`), optimistic sends whose messages rise from the composer while the client's answer slides in, «печатает…» both ways (`onActivityChange` → `Chat.Root typing`), unread counts from `onNewMessage` and `onRead`, the Composer with attachments in `Chat.Footer` |
|
|
24
|
+
| [Sales pipeline board](#sales-pipeline-board) | kanban | [screen.tsx](reference/components/kanban/examples/screen.tsx) | `Page.TopBar` titles the page (`h1` + a Description with the open deals and their sum) with SmartFilter search and a board / list SegmentedControl in `Page.Tools` and the one primary action in `Page.Actions`; Crossfade between a `plain` Kanban (stages without wells, deal cards on the page) and a DataTable of the same deals, column totals in `renderColumnMeta`, moves saved through an `onValueChange` promise that the server can refuse, the deal in a Drawer with a DescriptionList and stage actions, skeleton first load |
|
|
25
|
+
| [App frame](#app-frame) | app-shell | [screen.tsx](reference/layout/app-shell/examples/screen.tsx) | Sidebar rail on a wide screen, floating BottomNav in `AppShell.Footer` on a phone («Ещё» opens the Sidebar panel), a `Page.TopBar` with the menu button and the page title (`h1`) with a line of data, counts on items, a home page that cross-fades between sections |
|
|
26
|
+
| [Media library](#media-library) | file-upload | [screen.tsx](reference/components/file-upload/examples/screen.tsx) | `Page.TopBar` titles the page (`h1` + a Description with the object) with sections and counts, search (`SmartFilter` with `fields={[]}`) and order in `Page.Tools` and «Загрузить» in `Page.Actions`; uploads through `useUploadQueue` in `FileUpload` tiles (`trigger="tile"`, `layout="grid"`) with progress, a failure and retry, a done file moving into the library; a grid of `Thumbnail` / `Thumbnail.Video` tiles that open `MediaViewer` out of the tile (`getOrigin`, `thumbnails`, `renderActions`) or, in selection mode, are picked (`checked`) for bulk download and a `ConfirmDialog` delete; a Skeleton first load and a filtered `EmptyPage` in a `Crossfade` |
|
|
27
|
+
| [Resource schedule](#resource-schedule) | gantt | [screen.tsx](reference/components/gantt/examples/screen.tsx) | `Page.TopBar` titles the page (`h1` + a Description with the people shown) with search, role / client filters and team sections in `Page.Tools` and «Назначить» in `Page.Actions` over a full-height `Gantt` (`scrollHeight="fill"`); people with avatars, client hues, lanes for overlaps, locked absences and milestones; moves saved through an async `onBarChange` or refused and glided back, new work drawn with `onBarCreate` and named in a Modal (cancel fades the ghost), `onItemOpen` details in a Drawer with a `DescriptionList` and a confirmed removal, `loading` and filtered `empty` |
|
|
28
28
|
|
|
29
29
|
Pick the closest one, rename the domain, keep the skeleton. Change structure only when the task needs
|
|
30
30
|
it, and then by the rules below.
|
|
31
31
|
|
|
32
32
|
## 1. Page skeleton
|
|
33
33
|
|
|
34
|
-
**
|
|
35
|
-
app header
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
34
|
+
**The app is navigation and the page.** `AppShell` holds the Sidebar and `AppShell.Main`; there is no
|
|
35
|
+
app-wide header and no global search. Everything at the top belongs to the page: one `Page.Root` with
|
|
36
|
+
its `Page.TopBar` (sticky) and its `Page.Body`, plus a `Page.Header` in the flow on a document page.
|
|
37
|
+
|
|
38
|
+
**One title per page.** `Page.Title` is the page's only `<h1>`, a `Page.Description` with it is one
|
|
39
|
+
line that carries data («Среда, 14 октября · 3 задачи», «Отправлен · оплатить до 14 октября»), and a
|
|
40
|
+
nested record puts the path up (a `Breadcrumb.Root` before the title) — all three inside
|
|
41
|
+
`Page.Heading`, the title group. Where the heading stands follows the kind of page; its size follows
|
|
42
|
+
the place:
|
|
43
|
+
|
|
44
|
+
- **Work screens** — a list, a board, a chat, a schedule, a record: `Page.Heading` stands in
|
|
45
|
+
`Page.TopBar` beside the page's tools and buttons ([the top bar](#the-top-bar)); there is no header
|
|
46
|
+
in the flow.
|
|
47
|
+
- **Document pages** — settings, a long form, an article or help text: `Page.Header` in the flow
|
|
48
|
+
holds `Page.Heading` (the large title with one sentence of `Page.Description`) and the page's save
|
|
49
|
+
action in `Page.Actions`; optionally a `Page.TopBar collapse` with only the path in its
|
|
50
|
+
`Page.Heading`, which repeats the title once it scrolls away.
|
|
51
|
+
- **Overviews** — dashboards: a `Page.TopBar collapse` with the page's tools (the period) in
|
|
52
|
+
`Page.Tools` and its buttons (a report) in `Page.Actions`, and the titled `Page.Header` in the flow.
|
|
53
|
+
|
|
54
|
+
Never two titles; never no `<h1>`. A bar whose page shows no title still holds a `Page.Title` — inside
|
|
55
|
+
`VisuallyHidden` — unless a flow `Page.Header` has one.
|
|
46
56
|
|
|
47
57
|
```
|
|
48
58
|
AppShell.Root once per app (layouts.md#app-frame-once-per-app)
|
|
49
59
|
├─ AppShell.Nav → Sidebar navigation rail, one layer above the page
|
|
50
|
-
|
|
51
|
-
└─
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
└─
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
└─
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
60
|
+
└─ AppShell.Main gutters, top air (24, 32 from 1024px), bottom air 64; the page renders here
|
|
61
|
+
└─ SmartFilter.Root a filtered page only: the filter's state, no DOM, around the page
|
|
62
|
+
└─ Page.Root the page you deliver
|
|
63
|
+
├─ Page.Guard a page that edits a record: holds leaving it (busy, dirty); no DOM
|
|
64
|
+
├─ Page.TopBar sticky; led by the menu button while the Sidebar is off-canvas
|
|
65
|
+
│ ├─ Page.Heading the path › the title on one line, the line of data under it
|
|
66
|
+
│ │ ├─ Breadcrumb.Root only on a nested record: the levels above this page
|
|
67
|
+
│ │ ├─ Page.Title the one h1, the path's last level
|
|
68
|
+
│ │ └─ Page.Description a line of data
|
|
69
|
+
│ ├─ Page.Tools sections, search and filter, view — kit controls in reading order
|
|
70
|
+
│ ├─ Page.Actions every button of the page, each with an icon; the primary last
|
|
71
|
+
│ └─ Page.Chips SmartFilter.Chips: a line under everything, gone while empty
|
|
72
|
+
└─ Page.Body blocks 24 apart, the first 24 under the bar's controls
|
|
73
|
+
├─ Page.Grid every tile of the screen, 16 on both axes
|
|
74
|
+
│ └─ Page.Cell span (of 12), rows; the tile fills it
|
|
75
|
+
└─ Page.Section a new topic: h2 label (+ Page.Actions), 40 from its neighbours
|
|
76
|
+
|
|
77
|
+
Document page or overview: the title in the flow
|
|
78
|
+
└─ Page.Root maxWidth="wide" | "readable"
|
|
79
|
+
├─ Page.TopBar collapse the path (an overview: its tools and buttons); repeats the title once it scrolls away
|
|
80
|
+
├─ Page.Header Page.Heading (the one h1, a sentence of description) + Page.Actions; 24 above the body
|
|
81
|
+
└─ Page.Body
|
|
70
82
|
```
|
|
71
83
|
|
|
72
|
-
- A screen renders its page:
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
84
|
+
- A screen renders its page: one `Page.Root` with its top bar and its body. Styles, `applyTheme`,
|
|
85
|
+
`NotificationProvider` and `AppShell` live at the app root.
|
|
86
|
+
- `Page.Root` for app pages (full panel width); `Page.Root maxWidth="wide"` for settings,
|
|
87
|
+
`maxWidth="readable"` for one narrow column of text or fields.
|
|
88
|
+
- No outer padding, no margins: `AppShell.Main` hands the page its gutters and its top and bottom air, `Page` has
|
|
89
|
+
block → block 24, section → section 40, tile → tile 16 (and header → body 24). Your CSS lays out
|
|
90
|
+
only the inside of a block.
|
|
91
|
+
|
|
92
|
+
### The top bar
|
|
93
|
+
|
|
94
|
+
`Page.TopBar` holds up to four groups and nothing else. Write them in reading order; the DOM and Tab
|
|
95
|
+
order is Heading, Tools, Actions, Chips whatever the JSX order.
|
|
96
|
+
|
|
97
|
+
- **`Page.Heading`** — the path ends in the title: `Breadcrumb.Root` with the levels above this page,
|
|
98
|
+
then `Page.Title` with its name, on one line (the heading draws the chevron between them), and
|
|
99
|
+
`Page.Description` under the whole line. The title is never a row of its own under the path, and
|
|
100
|
+
the path never repeats the title as its last item.
|
|
101
|
+
- **`Page.Tools`** — the page's own tools as kit controls, in the order a person reads them: sections
|
|
102
|
+
(a `SegmentedControl` with counts), search and filter (`SmartFilter.Toolbar`), the view or the
|
|
103
|
+
period. Named with `aria-label`; no buttons and no wrappers inside.
|
|
104
|
+
- **`Page.Actions`** — the one place for the page's buttons: secondary ones (`soft` + `neutral`)
|
|
105
|
+
first, the primary (`solid`) last. Every Button carries a `Button.Icon` beside its label: the bar
|
|
106
|
+
shows it as the icon alone when the line runs short.
|
|
107
|
+
- **`Page.Chips`** — `SmartFilter.Chips`: the active filters.
|
|
108
|
+
- `SmartFilter.Root` draws nothing and its toolbar and chips stand in two groups, so it wraps
|
|
109
|
+
`Page.Root` (or whatever holds both) — never a group of the bar.
|
|
110
|
+
- The bar gives the title its natural size and decides the rest by width:
|
|
111
|
+
[the page's top bar](responsive.md#the-pages-top-bar--pagetopbar). The classic mistakes, bad →
|
|
112
|
+
good: [anti-slop.md](anti-slop.md#7b-a-top-bar-out-of-its-groups).
|
|
80
113
|
|
|
81
114
|
```tsx
|
|
82
115
|
import {
|
|
83
|
-
|
|
116
|
+
Breadcrumb,
|
|
84
117
|
Button,
|
|
85
|
-
Dropdown,
|
|
86
118
|
Icon,
|
|
87
|
-
|
|
119
|
+
Page,
|
|
120
|
+
SegmentedControl,
|
|
88
121
|
SmartFilter,
|
|
89
122
|
type SmartFilterField,
|
|
90
123
|
type SmartFilterValue,
|
|
91
124
|
} from "prime-ui-kit";
|
|
125
|
+
import type { ReactNode } from "react";
|
|
92
126
|
|
|
93
|
-
type
|
|
127
|
+
type DealsPageProps = {
|
|
94
128
|
fields: SmartFilterField[];
|
|
95
129
|
filter: SmartFilterValue;
|
|
96
130
|
onFilterChange: (value: SmartFilterValue) => void;
|
|
97
|
-
|
|
98
|
-
|
|
131
|
+
view: string;
|
|
132
|
+
onViewChange: (view: string) => void;
|
|
133
|
+
children: ReactNode;
|
|
99
134
|
};
|
|
100
135
|
|
|
101
|
-
export function
|
|
136
|
+
export function DealsPage({ fields, filter, onFilterChange, view, onViewChange, children }: DealsPageProps) {
|
|
102
137
|
return (
|
|
103
|
-
<
|
|
104
|
-
<
|
|
105
|
-
<
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
138
|
+
<SmartFilter.Root fields={fields} value={filter} onValueChange={onFilterChange}>
|
|
139
|
+
<Page.Root>
|
|
140
|
+
<Page.TopBar>
|
|
141
|
+
<Page.Heading>
|
|
142
|
+
<Breadcrumb.Root>
|
|
143
|
+
<Breadcrumb.Item href="/clients">Клиенты</Breadcrumb.Item>
|
|
144
|
+
<Breadcrumb.Item href="/clients/north">ООО «Север»</Breadcrumb.Item>
|
|
145
|
+
</Breadcrumb.Root>
|
|
146
|
+
<Page.Title>Сделки</Page.Title>
|
|
147
|
+
<Page.Description>7 в работе · 6,5 млн ₽</Page.Description>
|
|
148
|
+
</Page.Heading>
|
|
149
|
+
<Page.Tools aria-label="Сделки">
|
|
150
|
+
<SmartFilter.Toolbar />
|
|
151
|
+
<SegmentedControl.Root value={view} onValueChange={onViewChange} aria-label="Вид">
|
|
152
|
+
<SegmentedControl.Item value="board">Доска</SegmentedControl.Item>
|
|
153
|
+
<SegmentedControl.Item value="list">Список</SegmentedControl.Item>
|
|
154
|
+
</SegmentedControl.Root>
|
|
155
|
+
</Page.Tools>
|
|
156
|
+
<Page.Actions>
|
|
157
|
+
<Button.Root variant="soft" tone="neutral">
|
|
114
158
|
<Button.Icon>
|
|
115
|
-
<Icon name="action.
|
|
159
|
+
<Icon name="action.download" />
|
|
116
160
|
</Button.Icon>
|
|
161
|
+
Экспорт
|
|
117
162
|
</Button.Root>
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
>
|
|
133
|
-
<PageToolbar.Root aria-label="Заказы">
|
|
134
|
-
<PageToolbar.Tools>
|
|
135
|
-
<SmartFilter.Toolbar />
|
|
136
|
-
</PageToolbar.Tools>
|
|
137
|
-
<PageToolbar.Actions>
|
|
138
|
-
<Button.Root>
|
|
139
|
-
<Button.Icon>
|
|
140
|
-
<Icon name="action.add" />
|
|
141
|
-
</Button.Icon>
|
|
142
|
-
Создать заказ
|
|
143
|
-
</Button.Root>
|
|
144
|
-
</PageToolbar.Actions>
|
|
145
|
-
<PageToolbar.Chips>
|
|
146
|
-
<SmartFilter.Chips />
|
|
147
|
-
</PageToolbar.Chips>
|
|
148
|
-
</PageToolbar.Root>
|
|
149
|
-
</SmartFilter.Root>
|
|
150
|
-
</AppHeader.Tools>
|
|
151
|
-
</AppHeader.Root>
|
|
163
|
+
<Button.Root>
|
|
164
|
+
<Button.Icon>
|
|
165
|
+
<Icon name="action.add" />
|
|
166
|
+
</Button.Icon>
|
|
167
|
+
Новая сделка
|
|
168
|
+
</Button.Root>
|
|
169
|
+
</Page.Actions>
|
|
170
|
+
<Page.Chips>
|
|
171
|
+
<SmartFilter.Chips />
|
|
172
|
+
</Page.Chips>
|
|
173
|
+
</Page.TopBar>
|
|
174
|
+
<Page.Body>{children}</Page.Body>
|
|
175
|
+
</Page.Root>
|
|
176
|
+
</SmartFilter.Root>
|
|
152
177
|
);
|
|
153
178
|
}
|
|
154
179
|
```
|
|
@@ -162,20 +187,21 @@ Every gap is a `--prime-space-N` token (N × 4px) set as `gap` on the parent. Cl
|
|
|
162
187
|
| label → field, field → hint | 4–8 | built into fields — never add |
|
|
163
188
|
| buttons, chips, filters in a row | 8 | `--prime-space-2` |
|
|
164
189
|
| text lines of one item (name over meta) | 0–4 | `--prime-space-1` |
|
|
165
|
-
| heading → its content (group, section) | 16 | `--prime-space-4` (`
|
|
166
|
-
| tile → tile, both axes (KPI, charts, panels) | 16 | `
|
|
190
|
+
| heading → its content (group, section) | 16 | `--prime-space-4` (`Page.Section` does it) |
|
|
191
|
+
| tile → tile, both axes (KPI, charts, panels) | 16 | `Page.Grid` |
|
|
167
192
|
| field → field, switch → switch | 20 | `--prime-space-5` |
|
|
168
193
|
| main column → side column | 24 | `--prime-space-6` |
|
|
169
|
-
|
|
|
170
|
-
|
|
|
171
|
-
| block → block on a page | 24 | `
|
|
194
|
+
| top bar → the page's first block | 24 under the bar's controls | the rhythm's header → body; the bar's own bottom padding is part of it |
|
|
195
|
+
| flow header → body (a document page) | 24 | `Page.Header` |
|
|
196
|
+
| block → block on a page | 24 | `Page.Body` |
|
|
172
197
|
| group → group in a form | 32 | `--prime-space-8` |
|
|
173
|
-
| section → section (a new topic with an `h2`) | 40 | `
|
|
198
|
+
| section → section (a new topic with an `h2`) | 40 | `Page.Section` |
|
|
199
|
+
| the page's last block → the panel's bottom edge | 64; a `Page.Root fill` page the side gutter | `AppShell.Main` (beside the Sidebar rail too) |
|
|
174
200
|
|
|
175
201
|
A screen with one gap everywhere reads as a list of unrelated things. Use at least three levels: inside
|
|
176
202
|
an item, between items, between blocks. The tiles of one screen are one board: put them all in one
|
|
177
|
-
`
|
|
178
|
-
with its own heading (`
|
|
203
|
+
`Page.Grid` (one gap on both axes), never a grid per row — and keep the large air for a new topic
|
|
204
|
+
with its own heading (`Page.Section`).
|
|
179
205
|
|
|
180
206
|
## 3. Hierarchy — air first, then type
|
|
181
207
|
|
|
@@ -183,10 +209,11 @@ Hierarchy comes from space and a handful of type roles, not from size jumps, col
|
|
|
183
209
|
|
|
184
210
|
| Text | Use |
|
|
185
211
|
|---|---|
|
|
186
|
-
| page title | `
|
|
187
|
-
| section heading without a card | `
|
|
212
|
+
| page title | `Page.Title` (the only `h1`): `title-m` in the top bar, `heading-m` in the flow |
|
|
213
|
+
| section heading without a card | `Page.Section label` (an `h2` in `title-m`) |
|
|
188
214
|
| card / panel title | `Card.Title as="h2"` (under the page title) |
|
|
189
215
|
| heading of a group of fields | `Fieldset label` (`title-s` in the `<legend>`) |
|
|
216
|
+
| section heading inside a Drawer or a Modal | `Drawer.Section label` / `Modal.Section label` (an `h3` in `title-s`, `Drawer.Actions` at its end) |
|
|
190
217
|
| other group heading inside a card | `Typography as="h3" variant="title-s"` |
|
|
191
218
|
| body text, cells | `body-m` |
|
|
192
219
|
| lead under a heading | `body-m` + `tone="secondary"` |
|
|
@@ -228,7 +255,7 @@ Hierarchy comes from space and a handful of type roles, not from size jumps, col
|
|
|
228
255
|
`neutral` in Modal / Drawer footers. Rare actions: a `Dropdown` behind an `action.more` icon button —
|
|
229
256
|
`soft` + `neutral` in a header row (it has a shape beside the other buttons), `ghost` size `s` in a
|
|
230
257
|
table cell.
|
|
231
|
-
- Placement: the page
|
|
258
|
+
- Placement: every button of the page in one `Page.Actions` — of `Page.TopBar` on a work screen, of the flow `Page.Header` on a document page — the primary last; card actions in `Card.Footer`; dialog actions in
|
|
232
259
|
`Modal.Footer` / `Drawer.Footer`; row actions in the last column; bulk actions in the table toolbar.
|
|
233
260
|
- An empty state's action replaces the header's primary, it does not duplicate it.
|
|
234
261
|
- Destructive: `tone="danger"`; a standalone trigger is `outline`, in a menu it is the last item, the
|
|
@@ -246,6 +273,9 @@ Hierarchy comes from space and a handful of type roles, not from size jumps, col
|
|
|
246
273
|
- One value in several units is one row of fields under one heading, each unit in its field's
|
|
247
274
|
`Input.InlineAffix`; a base value with overrides is one `FieldList` with the base pinned first.
|
|
248
275
|
The shape of the data decides the layout: [ux.md](ux.md#2-the-shape-of-the-data-decides-the-layout).
|
|
276
|
+
- Rows that add up (shares of a bonus, hours, amounts) carry their sums under them in the same list:
|
|
277
|
+
`FieldList renderTotals`, a short number in a `width: "xs"` column. Return the save's promise from
|
|
278
|
+
its `onValueChange` when each edit saves at once.
|
|
249
279
|
- Fields 20 apart; related short fields side by side in an
|
|
250
280
|
[intrinsic grid](responsive.md#intrinsic-grids) with `align-items: start`
|
|
251
281
|
(`reserveSupportRow` on Input / Textarea keeps neighbours aligned); groups 32 apart, each a
|
|
@@ -266,9 +296,9 @@ Hierarchy comes from space and a handful of type roles, not from size jumps, col
|
|
|
266
296
|
|
|
267
297
|
### Where the filters go
|
|
268
298
|
|
|
269
|
-
- The page's
|
|
270
|
-
|
|
271
|
-
|
|
299
|
+
- The page's search and filters are the page's: `SmartFilter.Root` around `Page.Root`,
|
|
300
|
+
`SmartFilter.Toolbar` in the bar's `Page.Tools`, `SmartFilter.Chips` in its `Page.Chips`
|
|
301
|
+
([the list page](#list-page)).
|
|
272
302
|
A search alone is the same SmartFilter with `fields={[]}`.
|
|
273
303
|
- The DataTable `toolbar` keeps the table's own tools: `DataTable.ColumnsMenu`, a bulk bar of the
|
|
274
304
|
selected rows. Search and filters go there only when the table is not the page's main region (a
|
|
@@ -297,8 +327,9 @@ Hierarchy comes from space and a handful of type roles, not from size jumps, col
|
|
|
297
327
|
|---|---|
|
|
298
328
|
| the result of an action (sent, created, failed to save; saved when the form goes away) | `Notification` via `notify()` |
|
|
299
329
|
| a form saved and still on screen | the submit button's text: «Сохранено» |
|
|
300
|
-
| a state of the page or a section that persists (sync failed, trial ends, read-only) | `Banner` as the first block of `
|
|
330
|
+
| a state of the page or a section that persists (sync failed, trial ends, read-only) | `Banner` as the first block of `Page.Body` (or inside the Card it concerns) |
|
|
301
331
|
| a problem with one field | the field's `error` |
|
|
332
|
+
| a refused sign-in | `invalid` on the fields it concerns and the reason in an always-mounted `VisuallyHidden live="assertive"` — no Banner on a sign-in or sign-up form ([LoginForm](reference/components/login-form/COMPONENT.md)) |
|
|
302
333
|
| a region failed to load | the region shows it in place: DataTable `loadError`, or `EmptyPage tone="danger"` with `EmptyPage.RetryButton` |
|
|
303
334
|
| a region is loading | DataTable `loading`; otherwise a `Skeleton` in the geometry of the content + `aria-busy` on the region; `Spinner` only when there is no shape to hold |
|
|
304
335
|
| a region changes state (loading → data → empty → error, another record) | its content in `Crossfade state={status}` — always, so the change flows instead of flipping |
|
|
@@ -329,11 +360,17 @@ Every overlay closes on Escape and on a press outside unless you turn it off
|
|
|
329
360
|
closing with `Modal.Guard` / `Drawer.Guard` (`busy` while a request runs, `dirty` for unsaved
|
|
330
361
|
changes) instead.
|
|
331
362
|
|
|
363
|
+
A toast is no layer of that stack: `notify()` from inside a Drawer leaves it open, and a press on
|
|
364
|
+
the toast closes nothing below it. Titled groups of a dialog's body (a client's contacts, its deals)
|
|
365
|
+
are `Drawer.Section` / `Modal.Section` with their own `Drawer.Actions` / `Modal.Actions`, not a
|
|
366
|
+
hand-made heading row; a footer's `Drawer.Meta` / `Modal.Meta` goes above the buttons by itself when
|
|
367
|
+
the footer runs short.
|
|
368
|
+
|
|
332
369
|
## 11. Narrow screens
|
|
333
370
|
|
|
334
371
|
- Layouts are [intrinsic](responsive.md#intrinsic-grids) — no breakpoints needed, and they work in
|
|
335
372
|
any container; a media query only in [the breakpoints' scope](responsive.md#breakpoints).
|
|
336
|
-
- From 320px: the page's tools
|
|
373
|
+
- From 320px: the page's tools take a line under the page title ([the page's top bar](responsive.md#the-pages-top-bar--pagetopbar)), side columns drop below the main one,
|
|
337
374
|
pairs of fields stack, tables scroll inside themselves, dialogs stack their footers (built in).
|
|
338
375
|
- Rearrange, never hide: every function of the desktop screen is on the phone — in another place or a
|
|
339
376
|
menu. App sections on phones: `BottomNav` in `AppShell.Footer`; a short task from the bottom
|
|
@@ -406,7 +443,7 @@ export function RevenuePanel() {
|
|
|
406
443
|
```
|
|
407
444
|
|
|
408
445
|
For a plain KPI row use `Card.Root variant="stat-trend"` (Label · Value · Delta), each in a
|
|
409
|
-
`
|
|
446
|
+
`Page.Cell span={3}` of the page's `Page.Grid` — see [the dashboard screen](reference/components/card/examples/screen.tsx). When the trend over days matters, put a
|
|
410
447
|
`Sparkline` in the `Card.Body` instead: it brings the value, the change and a line to scrub.
|
|
411
448
|
|
|
412
449
|
## Screen rules
|
|
@@ -417,8 +454,8 @@ What each screen in [the index](#screens) demonstrates — keep these when you s
|
|
|
417
454
|
|
|
418
455
|
[data-table/examples/screen.tsx](reference/components/data-table/examples/screen.tsx)
|
|
419
456
|
|
|
420
|
-
-
|
|
421
|
-
-
|
|
457
|
+
- A work screen titles itself in its `Page.TopBar`: `Page.Title` is the only heading, its `Page.Description` is one line of figures («10 счетов · просрочено 2 на …»), not a sentence about the page; there is no second header in the flow.
|
|
458
|
+
- `SmartFilter.Root` wraps the page: `SmartFilter.Toolbar` in `Page.Tools`, `SmartFilter.Chips` in `Page.Chips`; export (`soft` + `neutral`, an icon beside its label) and the one primary action (`solid`, last) in `Page.Actions`. The table itself has no `toolbar`.
|
|
422
459
|
- A status is a `Badge` with one `tone` per meaning across the product (`STATUS` is one map); the text carries the meaning, the tone repeats it.
|
|
423
460
|
- Numbers and dates are `numeric` columns with `headerAlign="end"` (tabular figures, values and heading on the end edge). On a phone the table scrolls inside itself and `stickyFirstColumn` keeps the number in place — the page never scrolls sideways.
|
|
424
461
|
- Row actions are a `Dropdown` behind an `action.more` icon of size `s`: controls in cells are one tier below the table. Delete is `tone="danger"` at the end of the menu.
|
|
@@ -428,19 +465,20 @@ What each screen in [the index](#screens) demonstrates — keep these when you s
|
|
|
428
465
|
|
|
429
466
|
[description-list/examples/screen.tsx](reference/components/description-list/examples/screen.tsx)
|
|
430
467
|
|
|
431
|
-
- A nested record titles itself in
|
|
432
|
-
- The status is words next to the fact that matters now, in `
|
|
433
|
-
- The record's actions are the
|
|
468
|
+
- A nested record titles itself in its `Page.TopBar`: `Page.Heading` holds the path up (`Breadcrumb.Root` with the list, «Счета») ending in `Page.Title` with the record's name on the same line; there is no second header in the flow. Top-level pages have no breadcrumb.
|
|
469
|
+
- The status is words next to the fact that matters now, in `Page.Description` («Отправлен · оплатить до 14 октября»), not a separate plate.
|
|
470
|
+
- The record's actions are the bar's `Page.Actions`, by weight: one primary (`solid`, last), the secondary `soft` + `tone="neutral"`, each with an icon beside its label. Rare and destructive ones live in a `Dropdown` behind an `action.more` icon (also `soft`, so the button has a shape beside its neighbours); voiding is `tone="danger"` at the bottom of the menu.
|
|
434
471
|
- Columns are a CSS module on flex-wrap without breakpoints: the main one grows, the side one holds ~18rem and drops below when the main one runs out of room.
|
|
435
|
-
- A section without a frame is `
|
|
472
|
+
- A section without a frame is `Page.Section label`: an h2 heading 16 px above the table; `Card variant="panel"` only for standalone blocks of the side column. A table is already a filled block — never put it in a card.
|
|
436
473
|
- «Label → value» pairs about the client are `DescriptionList.Root orientation="vertical"` with `DescriptionList.Item label`; amounts are tabular figures, the total is larger (`title-m`) and ends where the «Сумма» column ends (the table cell inset).
|
|
437
474
|
- History is a `Timeline`: events top-down from the latest, dates in `Timeline.ItemMeta`; a row highlights on hover.
|
|
438
475
|
|
|
439
476
|
### Settings page
|
|
440
477
|
|
|
441
|
-
[page
|
|
478
|
+
[page/examples/screen.tsx](reference/layout/page/examples/screen.tsx)
|
|
442
479
|
|
|
443
|
-
- A
|
|
480
|
+
- A document page: `Page.Root maxWidth="wide"`, the large `Page.Title` with a sentence of `Page.Description` in the `Page.Heading` of a `Page.Header` in the flow, and a `Page.TopBar collapse` whose `Page.Heading` holds only the path and repeats the title once it scrolls away.
|
|
481
|
+
- A section is `Page.Section layout="aside"`: a heading column (`label` + a line of `description`) and a `Card variant="panel"` panel; sections are 40 px apart; on a narrow screen the column moves above the panel by itself (flex-wrap, no breakpoints).
|
|
444
482
|
- The form wraps the whole `Card.Root` in `<form noValidate>`; the buttons are in `Card.Footer`: «Отменить изменения» `ghost` + `neutral`, then the primary «Сохранить». While the request runs — `loading` on the button, and one `Fieldset disabled` turns the fields off; the form stays on screen, so success is the button text «Сохранено» for two seconds, without a notification.
|
|
445
483
|
- Fields are 20 px apart; two short related fields side by side while there is width, with `align-items: start` and `reserveSupportRow`, so an error does not shift the neighbour.
|
|
446
484
|
- An error comes through the field's `error` after submit, not while typing; a format hint goes in `hint`.
|
|
@@ -451,8 +489,8 @@ What each screen in [the index](#screens) demonstrates — keep these when you s
|
|
|
451
489
|
|
|
452
490
|
[drawer/examples/screen.tsx](reference/components/drawer/examples/screen.tsx)
|
|
453
491
|
|
|
454
|
-
-
|
|
455
|
-
- The opening button is the page's primary action in `
|
|
492
|
+
- A work screen titles itself in its `Page.TopBar`: `Page.Title` with the counts in `Page.Description`, the search (`SmartFilter` with `fields={[]}`) in `Page.Tools`; there is no second header in the flow.
|
|
493
|
+
- The opening button is the page's primary action in `Page.Actions`; `Drawer.Trigger` wraps it as a slot.
|
|
456
494
|
- The form is tied to the footer button through `form={formId}`: `Drawer.Footer` is outside the `<form>`, and submitting still works, by Enter too.
|
|
457
495
|
- Groups are a `Fieldset` without a frame with a `title-s` heading 16 px above the fields; 32 px of air between groups, no dividers. `Fieldset disabled` turns all the fields off while the request runs.
|
|
458
496
|
- Validation on submit: errors in each field's `error`, focus on the first invalid field; mark the minority: required fields are the majority, so `optional` stands only on the optional ones.
|
|
@@ -464,36 +502,37 @@ What each screen in [the index](#screens) demonstrates — keep these when you s
|
|
|
464
502
|
|
|
465
503
|
[field-list/examples/screen.tsx](reference/components/field-list/examples/screen.tsx)
|
|
466
504
|
|
|
467
|
-
- A record editor is a document page — a long form read top to bottom in aside sections, like Settings — so its title
|
|
505
|
+
- A record editor is a document page — a long form read top to bottom in aside sections, like Settings — so its title stands in the flow: `Page.Header` with the title and one line of description in `Page.Heading` and the primary action in `Page.Actions`; no second title anywhere.
|
|
468
506
|
- The shape of the data decides the layout: records a person adds and removes are a `FieldList`, one row per record; the column headings stand once above the rows, and the fields in the cells take them as their labels.
|
|
469
507
|
- No label in every row and no numbered one («Преимущество 1»): a one-column list has no headings at all — its section names it ([reorder.tsx](reference/components/field-list/examples/reorder.tsx)).
|
|
470
508
|
- Small attributes of a record go in compact columns of its row: the icon is a `Select` with only `Select.TriggerIcon`, the color `ColorPresets`; the first specs are pinned (`getLocked`) — the lock says so itself, without explanatory text.
|
|
471
509
|
- The base price and its changes are one list: the base row is pinned first and shows when it applies, the changes are rows with a month and a price; the ruble sign is in the field (`Input.InlineAffix`), not in every heading.
|
|
472
510
|
- One value in three currencies is three fields in one row under one group heading, each with its own name for screen readers and the currency inside the field.
|
|
473
|
-
- The lists live in the page state, the name and description fields in the `<form>` of the first section; the primary «Сохранить тариф» in
|
|
511
|
+
- The lists live in the page state, the name and description fields in the `<form>` of the first section; the primary «Сохранить тариф» in `Page.Actions` is tied to it through `form={formId}` and saves everything. While the request runs the fields and the lists are off (`Fieldset disabled`, `disabled`), afterwards «Сохранено» on the button.
|
|
474
512
|
|
|
475
513
|
### Dashboard
|
|
476
514
|
|
|
477
515
|
[card/examples/screen.tsx](reference/components/card/examples/screen.tsx)
|
|
478
516
|
|
|
479
|
-
-
|
|
480
|
-
- The period is a `SegmentedControl` in `
|
|
481
|
-
- Every tile of the screen is one `
|
|
482
|
-
- Another period — other values: each KPI tile is wrapped in `Crossfade state={period}` and flows instead of blinking.
|
|
517
|
+
- An overview: the large `Page.Title` «Обзор» with a `Page.Description` line of data (what and as of when) in a `Page.Header` in the flow; a `Page.TopBar collapse` above it keeps the page's tools and buttons in reach and repeats the title once it scrolls away; the body starts with the tiles.
|
|
518
|
+
- The period is a `SegmentedControl` in the bar's `Page.Tools` and the report a `soft` + `neutral` button with an icon in its `Page.Actions`: the period changes the values on this same screen. Tabs (`Tabs`) are for different content, not for a period.
|
|
519
|
+
- Every tile of the screen is one `Page.Grid`: KPI `Card variant="stat-trend"` in `Page.Cell span={3}`, 16 px on both axes; `Card.Delta` with a `tone` by the meaning of the change: overdue growing is `danger`, its decline `success`.
|
|
520
|
+
- Another period — other values: each KPI tile is wrapped in `Crossfade state={period}` and flows instead of blinking; a Crossfade right in a `Page.Cell` fills it, so the tiles of a row keep one height.
|
|
483
521
|
- A trend over days is a `Sparkline` in a `Card` in a full-width cell: the last value, the change and a line you can scrub with a finger; a new series appears by itself.
|
|
484
|
-
- A chart with axes and several series is a `ChartFrame` in `
|
|
522
|
+
- A chart with axes and several series is a `ChartFrame` in `Page.Cell span={8} rows={2}` beside two panels; `ChartFrame.Plot height="fill"` takes their height. A sized plot area (`renderPlot`), a legend that turns series off and a table for screen readers; series colors come from `series`, never your own.
|
|
485
523
|
- Panels are `Card variant="panel"` with `Card.Title as="h2"` in `Card.Header` and quiet context on the right after the title (`caption` + `muted`).
|
|
486
524
|
- Progress of one value is a `ProgressBar` with `label` and `showValue`; parts of a whole are `ProgressBar segments` with `legend` and `formatValue`: statuses are colored by `tone`, categories by `color`.
|
|
487
|
-
- Tiles of one screen are 16 px apart (`
|
|
488
|
-
- A short list is a `DataTable paging="none"` in `
|
|
525
|
+
- Tiles of one screen are 16 px apart (`Page.Grid`), page blocks 24 px (`Page.Body`), a new topic with a heading 40 px (`Page.Section`): proximity shows what is related.
|
|
526
|
+
- A short list is a `DataTable paging="none"` in `Page.Section label` without a card; «Все счета» is a `LinkButton` in the section's `Page.Actions`: it is a way somewhere, not an action.
|
|
489
527
|
|
|
490
528
|
### Screen states
|
|
491
529
|
|
|
492
530
|
[crossfade/examples/screen.tsx](reference/components/crossfade/examples/screen.tsx)
|
|
493
531
|
|
|
494
|
-
- The
|
|
495
|
-
- An error that concerns the whole page is a `Banner tone="danger"` as the first block of `
|
|
532
|
+
- The top bar carries the page: `Page.Title` with a `Page.Description` line of data — the accounts and the date of the statement the screen stands on; there is no second header in the flow.
|
|
533
|
+
- An error that concerns the whole page is a `Banner tone="danger"` as the first block of `Page.Body` with a «Повторить» action; the action's result is a `Notification`.
|
|
496
534
|
- A region's error is in the region's place: `loadError` on the `DataTable` (the table head stays), not a pop-up.
|
|
535
|
+
- The page's line of data that waits for a load (`Page.Description` with counts or sums) stays mounted with `loading` — mounting it after the load moves the title in the bar.
|
|
497
536
|
- Table loading is `loading` + `loadingRows` (a skeleton of rows); card loading is a `Skeleton` in the shape of its rows and `aria-busy` on the card, and the block's height does not change. The state change is smooth: the card's region is in `Crossfade state={status}`, the table body changes by itself.
|
|
498
537
|
- Stale data beats emptiness: the balances are shown as of the previous date, and that is said on the right in `Card.Header`.
|
|
499
538
|
- Empty on the first run is `EmptyPage size="s"` inside the panel: an icon with `tone="accent"`, what it is and why, one action. An empty filter result is the table's `empty`.
|
|
@@ -503,8 +542,8 @@ What each screen in [the index](#screens) demonstrates — keep these when you s
|
|
|
503
542
|
|
|
504
543
|
[chat/examples/screen.tsx](reference/components/chat/examples/screen.tsx)
|
|
505
544
|
|
|
506
|
-
- A work screen: the title «Поддержка» is `
|
|
507
|
-
- Layout: `
|
|
545
|
+
- A work screen: the title «Поддержка» is `Page.Title` in `Page.TopBar` with the unread count in `Page.Description`.
|
|
546
|
+
- Layout: `Page.Split` (`Page.List`, `Page.Detail`) in a `fill` page: the dialog list `ChatList` (last message, ticks, unread, «печатает…») and the conversation beside it; on a narrow panel one pane at a time with `Page.BackButton` in `Chat.Header`.
|
|
508
547
|
- Search over the dialogs is the field of `ChatList` itself: `search` and `onSearchChange`; you filter the list (by name and last message), and the list shows the match in rows, the number found and an empty result itself. Never put a field of your own above the list.
|
|
509
548
|
- The conversation is `Chat.Root` in the pane's card: the header, `Chat.Search`, `Chat.Messages` and `Chat.Footer` with the Composer. Never assemble your own header, `ScrollContainer` and feed — the chat links search, jumps, selection and «печатает…» itself.
|
|
510
549
|
- Messages are data: `items` with `getKey`, `getAuthor`, `getDate` (service events through `isService`), the first unread is `unread`; the feed computes dates, runs, tails and the avatar place. `renderMessage` may be inline: only a message whose item or place changed renders again, so whatever a row shows lives in its item, and a reply's original comes from `entry.find(key)`.
|
|
@@ -520,8 +559,8 @@ What each screen in [the index](#screens) demonstrates — keep these when you s
|
|
|
520
559
|
|
|
521
560
|
[kanban/examples/screen.tsx](reference/components/kanban/examples/screen.tsx)
|
|
522
561
|
|
|
523
|
-
- The page titles itself in
|
|
524
|
-
- Search, filters
|
|
562
|
+
- The page titles itself in its top bar: `Page.Title` with a `Page.Description` that carries data («7 сделок в работе · 6 461 750 ₽», counted over the filtered deals).
|
|
563
|
+
- Search, filters and the view switch are the bar's `Page.Tools`, the one primary action «Новая сделка» its `Page.Actions`, the active filters its `Page.Chips`; `SmartFilter.Root` wraps the page.
|
|
525
564
|
- The board and the list are the same data: `Kanban` and `DataTable` replace each other through `Crossfade`, the filter is `matchesSmartFilter`.
|
|
526
565
|
- The board is the main area of the page, so its `variant` is the default, `plain`: stages without wells, headers and deal cards stand right on the page — one level of nesting, no frames of your own around the columns.
|
|
527
566
|
- The placement of deals is `value` as `{ [stage]: id[] }`; `onValueChange` returns the request's promise and applies `value` only after the answer; a server refusal returns the card to its place.
|
|
@@ -533,10 +572,10 @@ What each screen in [the index](#screens) demonstrates — keep these when you s
|
|
|
533
572
|
|
|
534
573
|
[app-shell/examples/screen.tsx](reference/layout/app-shell/examples/screen.tsx)
|
|
535
574
|
|
|
536
|
-
- The frame is `AppShell.Template` (or `AppShell.Root`): `nav` is `Sidebar.Root`, `
|
|
537
|
-
- The kit decides the switch itself: below 768 px the `Sidebar` goes off the edge, the `
|
|
575
|
+
- The frame is `AppShell.Template` (or `AppShell.Root`): `nav` is `Sidebar.Root`, `footer` is `BottomNav.Root`; the page is the children, and everything at the top belongs to it. There is no app-wide header. `scrollResetKey` is the current section (in a router, the pathname), so a new page opens at the top.
|
|
576
|
+
- The kit decides the switch itself: below 768 px the `Sidebar` goes off the edge, the page's `Page.TopBar` draws its menu button and `AppShell.Footer` shows the `BottomNav`; while the rail is on screen the footer is hidden. No media queries, menu state or `position: fixed` of your own.
|
|
538
577
|
- `BottomNav` holds 2–6 main sections, one word each; the rest lives in the `Sidebar`, and «Ещё» opens it as a panel through `useAppShellNav()` (`aria-expanded`, `aria-controls`, `setOpen`). `floating` is a glass capsule; `AppShell.Main` leaves room under it itself.
|
|
539
|
-
- Every page titles itself in
|
|
578
|
+
- Every page titles itself in its `Page.TopBar`: `Page.Title` with the section's name and a `Page.Description` that carries data («Среда, 14 октября · открытых задач: 3»); its body starts with the page's blocks.
|
|
540
579
|
- Counts: `Sidebar.ItemCount` (a plain number for information, `color="red"` when it needs action) and `BottomNav.ItemCount` only for what needs attention; the number is the same in both navigations.
|
|
541
580
|
- Choosing a section in either navigation goes through one handler; an activated Sidebar item closes the off-canvas panel by itself.
|
|
542
581
|
- A section change is a `Crossfade` by `state`: the page changes smoothly instead of jumping. Menu items in an app with a router are `asChild` + `NavLink`.
|
|
@@ -545,8 +584,8 @@ What each screen in [the index](#screens) demonstrates — keep these when you s
|
|
|
545
584
|
|
|
546
585
|
[file-upload/examples/screen.tsx](reference/components/file-upload/examples/screen.tsx)
|
|
547
586
|
|
|
548
|
-
- A work screen titles itself in
|
|
549
|
-
- Sections, search
|
|
587
|
+
- A work screen titles itself in its top bar: `Page.Title` «Медиатека» with a `Page.Description` naming the object.
|
|
588
|
+
- Sections, search and order are the bar's `Page.Tools`, «Загрузить» its `Page.Actions`: search is a `SmartFilter.Toolbar` with `fields={[]}`, sections a `SegmentedControl` with `SegmentedControl.Count`.
|
|
550
589
|
- Uploads are `useUploadQueue` + `FileUpload.Root trigger="tile" layout="grid"`: progress, «В очереди», the failure reason and retry are built in, the add tile is also the drop zone; «Загрузить» opens the same picker (`picker.current?.open()`).
|
|
551
590
|
- A finished file leaves the queue for the library: its address is `item.result` of the server's answer, not the queue's `preview`.
|
|
552
591
|
- The library grid is a CSS grid of `Thumbnail` with `fullWidth` and one `ratio`; a video is `Thumbnail.Video`, which draws the duration and the play mark itself. `Gallery` does not fit here: it is an album of up to 10.
|
|
@@ -559,9 +598,9 @@ What each screen in [the index](#screens) demonstrates — keep these when you s
|
|
|
559
598
|
|
|
560
599
|
[gantt/examples/screen.tsx](reference/components/gantt/examples/screen.tsx)
|
|
561
600
|
|
|
562
|
-
- The page titles itself in
|
|
601
|
+
- The page titles itself in its top bar: `Page.Title` with a `Page.Description` that carries data («Сотрудников: 9 из 9»).
|
|
563
602
|
- A `fill` page: `Gantt scrollHeight="fill"` takes the free height — the header and the first column stick inside the chart, the page never scrolls sideways.
|
|
564
|
-
-
|
|
603
|
+
- `SmartFilter.Root` wraps the page: search with the role and client filter and teams (a `SegmentedControl` with counts) in `Page.Tools`, the primary action «Назначить» in `Page.Actions`, the active filters `SmartFilter.Chips` in `Page.Chips`. Zoom and «Сегодня» are built into `Gantt` — never add your own.
|
|
565
604
|
- A row is a person: `renderRowAvatar` with an `Avatar`, `renderRow` with the name and role; on a narrow chart the column keeps only the avatar. Overlapping works lay themselves out in lanes, an absence is a `readOnly` bar, a milestone has `start` equal to `end`.
|
|
566
605
|
- `onBarChange` returns a promise and changes the data only after the service answers: while it runs the bar is busy; a refusal (work on an absence) is `notify` and `throw`, and the bar returns to its previous dates by itself.
|
|
567
606
|
- `onBarCreate`: a range drawn on an empty place holds a busy draft while a `Modal` with `Modal.Guard busy` asks for the name and the client; saving adds the bar and resolves the promise, cancel rejects it — the draft dissolves. Work over an absence is refused at once.
|