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
|
@@ -3,19 +3,23 @@ import { Slider } from "prime-ui-kit";
|
|
|
3
3
|
|
|
4
4
|
export default function SliderStatesExample() {
|
|
5
5
|
return (
|
|
6
|
-
|
|
6
|
+
<>
|
|
7
7
|
<div>
|
|
8
|
-
<
|
|
8
|
+
<div>
|
|
9
|
+
<Slider label="min" showValue defaultValue={0} />
|
|
10
|
+
</div>
|
|
11
|
+
<div>
|
|
12
|
+
<Slider label="max" showValue defaultValue={100} />
|
|
13
|
+
</div>
|
|
9
14
|
</div>
|
|
10
15
|
<div>
|
|
11
|
-
<
|
|
16
|
+
<div>
|
|
17
|
+
<Slider label="invalid" showValue defaultValue={90} invalid />
|
|
18
|
+
</div>
|
|
19
|
+
<div>
|
|
20
|
+
<Slider label="disabled" showValue defaultValue={35} disabled />
|
|
21
|
+
</div>
|
|
12
22
|
</div>
|
|
13
|
-
|
|
14
|
-
<Slider label="invalid" showValue defaultValue={90} invalid />
|
|
15
|
-
</div>
|
|
16
|
-
<div>
|
|
17
|
-
<Slider label="disabled" showValue defaultValue={35} disabled />
|
|
18
|
-
</div>
|
|
19
|
-
</div>
|
|
23
|
+
</>
|
|
20
24
|
);
|
|
21
25
|
}
|
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
- An API that takes one value per field (`multiple: false`), a screen whose text search lives elsewhere (`searchable={false}`), values of different kinds in one field (`group`).
|
|
14
14
|
|
|
15
15
|
## When not to use
|
|
16
|
-
- One field with a few options → use [SegmentedControl](../segmented-control/COMPONENT.md), [Select](../select/COMPONENT.md) or [TagSelect](../tag-select/COMPONENT.md) in the
|
|
16
|
+
- One field with a few options → use [SegmentedControl](../segmented-control/COMPONENT.md), [Select](../select/COMPONENT.md) or [TagSelect](../tag-select/COMPONENT.md) in the page's `Page.Tools`.
|
|
17
17
|
- A search outside a table or list page (inside a picker, a settings section, a panel) → [Input](../input/COMPONENT.md) with a search icon. Over a table or list page the search is SmartFilter even with no fields yet (`fields={[]}`): it grows into filters without a rebuild.
|
|
18
18
|
- Choosing values for a form field → use [TagSelect](../tag-select/COMPONENT.md).
|
|
19
|
-
- One period that drives a whole dashboard → [Datepicker](../datepicker/COMPONENT.md) in the page
|
|
19
|
+
- One period that drives a whole dashboard → [Datepicker](../datepicker/COMPONENT.md) in the page's `Page.Tools`; SmartFilter ranges filter rows of a list.
|
|
20
20
|
|
|
21
21
|
## Import
|
|
22
22
|
```tsx
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
|
|
31
31
|
## Anatomy
|
|
32
32
|
```
|
|
33
|
-
SmartFilter.Root state + context
|
|
33
|
+
SmartFilter.Root state + context, no DOM
|
|
34
34
|
├─ SmartFilter.Toolbar [search Input (searchable)] [filter Button (count Badge)] — the anchor of the panel
|
|
35
35
|
│ └─ panel flush Popover as wide as the toolbar; sections split by Dividers
|
|
36
36
|
│ ├─ query row ghost Button «Искать «text»» + Kbd ↵, while typing
|
|
@@ -41,14 +41,14 @@ SmartFilter.Root state + context (flex column)
|
|
|
41
41
|
│ └─ footer hint · count · Reset Button
|
|
42
42
|
└─ SmartFilter.Chips applied filters as removable Badges · add / clear all Buttons
|
|
43
43
|
```
|
|
44
|
-
The toolbar and the chips are separate parts so a page can put them in different places; both only need to be inside `Root
|
|
44
|
+
The toolbar and the chips are separate parts so a page can put them in different places; both only need to be inside `Root`, which draws nothing of its own.
|
|
45
45
|
|
|
46
46
|
## API
|
|
47
47
|
|
|
48
48
|
<!-- Generated from api.ts by `bun run docs:build`. Edit api.ts, not this section. -->
|
|
49
49
|
|
|
50
50
|
### SmartFilter.Root
|
|
51
|
-
|
|
51
|
+
No DOM, no ref. The value, the search and the panel state shared by its parts; the host places the parts.
|
|
52
52
|
|
|
53
53
|
| Prop | Type | Default | Description |
|
|
54
54
|
|---|---|---|---|
|
|
@@ -62,11 +62,10 @@ The toolbar and the chips are separate parts so a page can put them in different
|
|
|
62
62
|
| `size` | `"xs" \| "s" \| "m" \| "l" \| "xl"` | host tier, else `"m"` | Tier of the filter button, the search, the tags and the panel. Without it the tier of its host, else `m`. |
|
|
63
63
|
| `collapsedLimit` | `number` | `12` | Values of one field shown before «Ещё N» (not while searching). |
|
|
64
64
|
| `labels` | `Partial<SmartFilterLabels>` | — | Built-in strings, see Labels. |
|
|
65
|
-
| `children` | `ReactNode` | — (required) | `SmartFilter.Toolbar` and `SmartFilter.Chips`, anywhere inside. |
|
|
66
|
-
| `…rest` | `Omit<HTMLAttributes<HTMLDivElement>, "children" \| "defaultValue" \| "onChange">` | — | `className` and the other div attributes. |
|
|
65
|
+
| `children` | `ReactNode` | — (required) | `SmartFilter.Toolbar` and `SmartFilter.Chips`, anywhere inside — in a page bar the Root wraps `Page.Root`. |
|
|
67
66
|
|
|
68
67
|
### SmartFilter.Toolbar
|
|
69
|
-
`ref` → `HTMLDivElement`. A `<div>`: the search Input first, then the filter Button (a count Badge while filters apply); the anchor of the panel, a flush Popover.
|
|
68
|
+
`ref` → `HTMLDivElement`. A `<div>`: the search Input first, then the filter Button (a count Badge while filters apply), which shows only its icon and count when the search would get too little room; the anchor of the panel, a flush Popover.
|
|
70
69
|
|
|
71
70
|
| Prop | Type | Default | Description |
|
|
72
71
|
|---|---|---|---|
|
|
@@ -165,15 +164,16 @@ same height and type.
|
|
|
165
164
|
| range inverted | `from` above `to` | both bound inputs `aria-invalid` with the danger ring; nothing matches |
|
|
166
165
|
| single value | `multiple: false` | at most one value `aria-pressed`; no «−» |
|
|
167
166
|
| no filters | empty value | no count on the button, no Chips |
|
|
167
|
+
| compact button | the toolbar narrower than the search's 9rem plus the labelled button (search and fields both present) | the button shows its icon and the count Badge; its name stays «Фильтр» (`aria-label` without filters, a visually hidden label with them) |
|
|
168
168
|
|
|
169
169
|
## Layout & spacing
|
|
170
|
-
- The panel is a flush Popover as wide as the toolbar; every section is a full-width row with its own padding (`--prime-space-3` × `--prime-space-4`, footer `--prime-space-2` × `--prime-space-4`), Dividers run edge to edge, the field label column is `--prime-space-24
|
|
171
|
-
- The toolbar is one row of controls (`--prime-space-2` gap): the search first, growing from 9rem (`--prime-space-24` × 1.5), then the filter button at its own width. When less than 9rem is left beside the button, the button
|
|
170
|
+
- The panel is a flush Popover at least as wide as the toolbar (`width="min-trigger"`), by its content up to twice the panel minimum when the toolbar is narrow; every section is a full-width row with its own padding (`--prime-space-3` × `--prime-space-4`, footer `--prime-space-2` × `--prime-space-4`), Dividers run edge to edge, the field label column is at least `--prime-space-24` (a longer name takes its own width, never breaking inside a word); a row narrower than 24rem stacks the label over the values (an intrinsic wrap, no breakpoint).
|
|
171
|
+
- The toolbar is one row of controls (`--prime-space-2` gap): the search first, growing from 9rem (`--prime-space-24` × 1.5), then the filter button at its own width. When less than 9rem is left beside the labelled button, the button shows only its icon and count and stays beside the search, which gives its width instead of wrapping. Every row stays one control high. The search and the button also stand alone: `searchable={false}` keeps the button, empty `fields` keep the search. Search first, filter second — the active filters (`SmartFilter.Chips`) sit under them.
|
|
172
172
|
- Chips are Badges of the toolbar tier on the badge scale (`xs` → `s`), so a tag sits lower than the controls above it; «Добавить фильтр» is a tag of the same tier and «Сбросить все» a LinkButton with the tag's text size.
|
|
173
173
|
- Values and chips wrap with `--prime-space-2` gaps; «Сбросить все» is pushed to the end. The chips row rises in with the first filter and closes up in place with the last (`partPresence`).
|
|
174
174
|
- Option groups stack `--prime-space-3` apart, a caption `--prime-space-1` above each group's values. A range row holds two equal Inputs with a dash between them, centred on the field label.
|
|
175
175
|
- While typing a search a range row stays only when its field name matches.
|
|
176
|
-
- The root
|
|
176
|
+
- The root draws nothing: its host places Toolbar and Chips. In a page bar the Toolbar goes in `Page.Tools` and the Chips in `Page.Chips`, with `SmartFilter.Root` around `Page.Root`; outside a page a host stacks them (a `Card.Body`, a form column).
|
|
177
177
|
|
|
178
178
|
## Accessibility
|
|
179
179
|
|
|
@@ -244,7 +244,7 @@ same height and type.
|
|
|
244
244
|
- A fixed field marked `finite: false` → the user can hide every value and get an empty list.
|
|
245
245
|
- Filtering the list with `includes` → use `matchesSmartFilter` (empty `include` is "any", `exclude` rejects; range bounds are inclusive, dates by whole days; an item with no value passes only an empty filter).
|
|
246
246
|
- Sending `include` to a server for a hidden value of a fixed field → use `resolveSmartFilterValues` («hide» becomes «all except», `[]` means no filter).
|
|
247
|
-
- Putting `Chips` outside `SmartFilter.Root` → every part needs the root.
|
|
247
|
+
- Putting `Chips` outside `SmartFilter.Root` → every part needs the root; when Toolbar and Chips stand in different groups of a page bar, wrap `Page.Root` in it.
|
|
248
248
|
- A second row of filter buttons next to the toolbar → fields belong in `fields`.
|
|
249
249
|
- An amount or a period in its own Popover beside the toolbar → a `range` / `date-range` field; it gets a chip and the count.
|
|
250
250
|
- One field split in two because its values are of different kinds → one field with `group` on the options.
|
|
@@ -252,4 +252,4 @@ same height and type.
|
|
|
252
252
|
|
|
253
253
|
## Related
|
|
254
254
|
- **Built from:** [Button](../button/COMPONENT.md), [Badge](../badge/COMPONENT.md), [Input](../input/COMPONENT.md), [Datepicker](../datepicker/COMPONENT.md), [Popover](../popover/COMPONENT.md), [Divider](../divider/COMPONENT.md), [Kbd](../kbd/COMPONENT.md), [EmptyPage](../empty-page/COMPONENT.md), [LinkButton](../link-button/COMPONENT.md), [Typography](../typography/COMPONENT.md), Icon (`action.search`, `action.filter`, `action.add`, `nav.chevronDown`), [VisuallyHidden](../visually-hidden/COMPONENT.md)
|
|
255
|
-
- **See also:** [
|
|
255
|
+
- **See also:** [Page](../../layout/page/COMPONENT.md) (`Page.Tools`, `Page.Chips`), [TagSelect](../tag-select/COMPONENT.md), [DataTable](../data-table/COMPONENT.md)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/** An open set of twenty services, degraded ones marked with an icon, collapsed after eight; typing narrows the panel and marks the match in accent — `finite`, `icon`, `collapsedLimit`. */
|
|
2
2
|
import { Icon, SmartFilter, type SmartFilterField } from "prime-ui-kit";
|
|
3
3
|
|
|
4
|
+
import styles from "./examples.module.css";
|
|
5
|
+
|
|
4
6
|
const SERVICES = [
|
|
5
7
|
"access-policy",
|
|
6
8
|
"billing",
|
|
@@ -41,13 +43,15 @@ const FIELDS: SmartFilterField[] = [
|
|
|
41
43
|
|
|
42
44
|
export default function SmartFilterManyValuesExample() {
|
|
43
45
|
return (
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
46
|
+
<div className={styles.stack}>
|
|
47
|
+
<SmartFilter.Root
|
|
48
|
+
fields={FIELDS}
|
|
49
|
+
collapsedLimit={8}
|
|
50
|
+
defaultValue={{ service: { include: [], exclude: ["events"] } }}
|
|
51
|
+
>
|
|
52
|
+
<SmartFilter.Toolbar />
|
|
53
|
+
<SmartFilter.Chips />
|
|
54
|
+
</SmartFilter.Root>
|
|
55
|
+
</div>
|
|
52
56
|
);
|
|
53
57
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Every size tier: the filter button, the search, the tags and the panel follow one tier — `size`. */
|
|
2
|
-
import { SmartFilter, type SmartFilterField, Typography } from "prime-ui-kit";
|
|
2
|
+
import { Card, SmartFilter, type SmartFilterField, Typography } from "prime-ui-kit";
|
|
3
3
|
|
|
4
4
|
const FIELDS: SmartFilterField[] = [
|
|
5
5
|
{
|
|
@@ -18,8 +18,12 @@ export default function SmartFilterSizesExample() {
|
|
|
18
18
|
{SIZES.map((size) => (
|
|
19
19
|
<div key={size}>
|
|
20
20
|
<SmartFilter.Root fields={FIELDS} size={size} defaultValue={ONLY_GET}>
|
|
21
|
-
<
|
|
22
|
-
|
|
21
|
+
<Card.Root>
|
|
22
|
+
<Card.Body>
|
|
23
|
+
<SmartFilter.Toolbar />
|
|
24
|
+
<SmartFilter.Chips />
|
|
25
|
+
</Card.Body>
|
|
26
|
+
</Card.Root>
|
|
23
27
|
</SmartFilter.Root>
|
|
24
28
|
<Typography as="span" variant="caption" tone="muted">
|
|
25
29
|
{size}
|
|
@@ -133,6 +133,7 @@ Put it in a `Card` for a dashboard tile.
|
|
|
133
133
|
- Bars share the width equally, 4 px apart; the zero line sits where 0 falls on the scale (the bottom when every value is positive).
|
|
134
134
|
- In a dashboard, wrap it in `Card.Root` + `Card.Body`; several cards go in a grid.
|
|
135
135
|
- When the value row does not fit (a narrow card), the change badge wraps under the value.
|
|
136
|
+
- On a head narrower than 20rem (a phone card) the date takes its own line under the title, which wraps instead of being cut; the break follows the width only, so a date that changes while scrubbing never moves it.
|
|
136
137
|
- `layout="compact"` fits a DataTable row of any tier (plot and dot within an `xs` control height) and takes the cell width, at least `--prime-space-24`; give the column a `width` for an even plot per row. Put the number next to it in its own column: the compact plot shows a value only in its tooltip while scrubbed.
|
|
137
138
|
- The tooltip is the kit's chart tooltip, placed like every anchored layer (`usePosition`): right of the pointer at its height, on the left only where the right has no room in the viewport — crossing the middle never moves it; from the keyboard right of the point at mid-height. Portaled, so a card or a table scroller never clips it.
|
|
138
139
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/** The same month of active users as a smooth curve, straight segments and steps — `curve`. */
|
|
2
|
-
import { Sparkline, type SparklinePoint
|
|
2
|
+
import { Card, Sparkline, type SparklinePoint } from "prime-ui-kit";
|
|
3
|
+
|
|
4
|
+
import styles from "./examples.module.css";
|
|
3
5
|
|
|
4
6
|
const USERS: SparklinePoint[] = [
|
|
5
7
|
{ label: "сен, 1 нед.", value: 1240 },
|
|
@@ -10,19 +12,22 @@ const USERS: SparklinePoint[] = [
|
|
|
10
12
|
{ label: "окт, 2 нед.", value: 1840 },
|
|
11
13
|
];
|
|
12
14
|
|
|
13
|
-
const CURVES = [
|
|
15
|
+
const CURVES = [
|
|
16
|
+
{ curve: "smooth", title: "Плавная кривая" },
|
|
17
|
+
{ curve: "linear", title: "Прямые отрезки" },
|
|
18
|
+
{ curve: "step", title: "Ступени" },
|
|
19
|
+
] as const;
|
|
14
20
|
|
|
15
21
|
export default function SparklineCurveExample() {
|
|
16
22
|
return (
|
|
17
|
-
|
|
18
|
-
{CURVES.map((curve) => (
|
|
19
|
-
<
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
</div>
|
|
23
|
+
<>
|
|
24
|
+
{CURVES.map(({ curve, title }) => (
|
|
25
|
+
<Card.Root key={curve} className={styles.card}>
|
|
26
|
+
<Card.Body>
|
|
27
|
+
<Sparkline data={USERS} label={title} curve={curve} />
|
|
28
|
+
</Card.Body>
|
|
29
|
+
</Card.Root>
|
|
25
30
|
))}
|
|
26
|
-
|
|
31
|
+
</>
|
|
27
32
|
);
|
|
28
33
|
}
|
|
@@ -12,19 +12,23 @@ const formatRubles = (value: number) => `${value.toLocaleString("ru-RU")} ₽`;
|
|
|
12
12
|
|
|
13
13
|
export default function SparklineStatesExample() {
|
|
14
14
|
return (
|
|
15
|
-
|
|
15
|
+
<>
|
|
16
16
|
<div>
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
<div>
|
|
18
|
+
<Sparkline data={REVENUE} label="Выручка" formatValue={formatRubles} />
|
|
19
|
+
<Typography as="span" variant="caption" tone="muted">
|
|
20
|
+
data
|
|
21
|
+
</Typography>
|
|
22
|
+
</div>
|
|
21
23
|
</div>
|
|
22
24
|
<div>
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
<div>
|
|
26
|
+
<Sparkline data={[]} label="Выручка" loading />
|
|
27
|
+
<Typography as="span" variant="caption" tone="muted">
|
|
28
|
+
loading
|
|
29
|
+
</Typography>
|
|
30
|
+
</div>
|
|
27
31
|
</div>
|
|
28
|
-
|
|
32
|
+
</>
|
|
29
33
|
);
|
|
30
34
|
}
|
|
@@ -46,6 +46,7 @@ Switch.Root field grid; ref and input props go to the native input (rol
|
|
|
46
46
|
| `optional` | `boolean` | `false` | Muted `labels.optional` after the label text; the field may stay off. |
|
|
47
47
|
| `labels` | `Partial<SwitchLabels>` | — | Built-in strings, see Labels. |
|
|
48
48
|
| `hint` | `ReactNode` | — | Help text under the label text. Hidden while `error` is shown. |
|
|
49
|
+
| `hintTone` | `"neutral" \| "success" \| "warning" \| "danger"` | `"neutral"` | Status color of `hint` («Осталось 12 дней» in `warning`). The words carry the status, the color repeats it; an `error` replaces the hint and its tone. A validation error is `error`, never a `danger` hint. |
|
|
49
50
|
| `error` | `ReactNode` | — | Error message in the hint slot; implies `invalid`. |
|
|
50
51
|
| `invalid` | `boolean` | `false` | Danger ring on the off track and `aria-invalid`. A non-empty `error` implies it. |
|
|
51
52
|
| `disabled` | `boolean` | `false` | No toggling; muted track (on = `accent-soft`), dimmed text and hint. |
|
|
@@ -97,7 +98,7 @@ No `variant` / `tone` / `color`.
|
|
|
97
98
|
| off | `checked={false}` / default | `data-state="unchecked"`; track `fill-strong` (hover `fill-strong-hover`), thumb at the start |
|
|
98
99
|
| on | `checked` / `defaultChecked` | `data-state="checked"`; accent track, the thumb glides to the end |
|
|
99
100
|
| invalid | `invalid` or a non-empty `error` | `data-invalid="true"`, `aria-invalid`; danger ring on the off track and on focus; the row shakes once when an error arrives (`data-shake`) |
|
|
100
|
-
| disabled | `disabled` | `data-disabled="true"`; off track `fill-muted`, on track `accent-soft`, `cursor: not-allowed` |
|
|
101
|
+
| disabled | `disabled` | `data-disabled="true"`; off track `fill-muted`, on track `accent-soft`, thumb `control-thumb-disabled` without shadow, `cursor: not-allowed` |
|
|
101
102
|
| read-only | `readOnly` | `aria-readonly="true"` on the input, `data-readonly="true"` on the field; no hover or press, default cursor |
|
|
102
103
|
| saving | `loading`, or `onCheckedChange` returned a pending promise | the thumb stands in the new position with a `Spinner` inside (accent when on, muted when off; it fades in by itself), `aria-busy` on the input, `data-loading` on the track, presses ignored; a rejection glides the thumb back (`base`, emphasized) |
|
|
103
104
|
| pressed | pointer press | the track scales to the compact press scale (not when disabled or read-only) |
|
|
@@ -189,7 +189,7 @@ Avoid icons or descriptions on only some tabs (uneven rows; without an icon on e
|
|
|
189
189
|
| closing, confirm pending | `onRemove` returned a promise that has not settled | the close button is `loading` (`aria-busy`); the tab, its selection and focus stay; resolved → the neighbour takes over, rejected → nothing changes |
|
|
190
190
|
| two-line | `Tabs.Description` child | `data-two-line="true"` |
|
|
191
191
|
| collapsed | tabs wider than the list, or a label that would be cut (horizontal) | list `data-collapse="full" \| "compact" \| "icon"`: `compact` hides icons and descriptions; `icon` takes labels, counts and close buttons out of the row — a `VisuallyHidden` copy of the label names the tab and a `Tooltip` shows it — only when every tab has an icon |
|
|
192
|
-
| overflow | tabs at their narrowest (content width, `minItemWidth` or icon squares) still wider than the list | `data-overflow-start` / `data-overflow-end` on the list (the switcher row, a ScrollContainer), faded edges as deep as the hidden part at most (they grow and melt with the scroll, never switch); the active tab is kept in view and clear of the fades on mount and on every value change, the first and the last tab scroll all the way to the end — only the list scrolls, never the page. A column (a wide vertical list) has plain edges |
|
|
192
|
+
| overflow | tabs at their narrowest (content width, `minItemWidth` or icon squares) still wider than the list | `data-overflow-start` / `data-overflow-end` on the list (the switcher row, a ScrollContainer), faded edges as deep as the hidden part at most (they grow and melt with the scroll, never switch); when the end edge would cut only a tab's empty side, the tabs at `minItemWidth` widen a little (`--tabs-peek`, up to 30%) so a label fades out at the edge and shows that more tabs follow; the active tab is kept in view and clear of the fades on mount and on every value change, the first and the last tab scroll all the way to the end — only the list scrolls, never the page. A column (a wide vertical list) has plain edges |
|
|
193
193
|
|
|
194
194
|
The indicator glides (`emphasized` + `base`, `data-animate="true"`) only into a choice by click, arrow keys or closing the active tab; on mount, a value set from outside, a resize, font loading, tabs added or removed and collapse it is placed without motion, and it stays still under `prefers-reduced-motion`. The list scrolls smoothly to the active tab only after such a choice too.
|
|
195
195
|
|
|
@@ -60,6 +60,7 @@ TagSelect field frame: label · control · hint/error (sin
|
|
|
60
60
|
| `onOptionDelete` | `(value: string) => void \| Promise<void>` | — | Enables «Удалить» in the row menu; the value also leaves the selection. A returned Promise defers it: resolve deletes, reject keeps everything (e.g. after a confirmation). |
|
|
61
61
|
| `label` | `ReactNode` | — | Field label above; names the input. |
|
|
62
62
|
| `hint` | `ReactNode` | — | Support text under the field; linked by `aria-describedby`. |
|
|
63
|
+
| `hintTone` | `"neutral" \| "success" \| "warning" \| "danger"` | `"neutral"` | Status color of `hint` («Осталось 12 дней» in `warning`). The words carry the status, the color repeats it; an `error` replaces the hint and its tone. A validation error is `error`, never a `danger` hint. |
|
|
63
64
|
| `error` | `ReactNode` | — | Error message; replaces the hint and implies `invalid`. |
|
|
64
65
|
| `required` | `boolean` | `false` | Red `*` after the label and `aria-required` on the input. |
|
|
65
66
|
| `optional` | `boolean` | — | Muted `labels.optional` after the label. |
|
|
@@ -46,6 +46,7 @@ Unlike Input, Textarea has no Wrapper / Field parts: `Textarea.Root` renders the
|
|
|
46
46
|
| `required` | `boolean` | — | Native `required` on the textarea and a red `*` after the label (`aria-hidden`). |
|
|
47
47
|
| `optional` | `boolean` | `false` | Muted marker right after the label text (`labels.optional`). |
|
|
48
48
|
| `hint` | `ReactNode` | — | Help text under the field. Hidden while `error` is shown. |
|
|
49
|
+
| `hintTone` | `"neutral" \| "success" \| "warning" \| "danger"` | `"neutral"` | Status color of `hint` («Осталось 12 дней» in `warning`). The words carry the status, the color repeats it; an `error` replaces the hint and its tone. A validation error is `error`, never a `danger` hint. |
|
|
49
50
|
| `error` | `ReactNode` | — | Error message in the hint slot; implies `invalid`. |
|
|
50
51
|
| `invalid` | `boolean` | `false` | Danger inset ring on the field box, `aria-invalid` on the textarea. A non-empty `error` implies it. |
|
|
51
52
|
| `focusRing` | `boolean` | `true` | `false` hides only the visual focus ring on the field box (`data-focus-ring="false"`); focus, keyboard, ARIA and the invalid ring stay. |
|
|
@@ -27,7 +27,7 @@ Timeline.Root size container, sets the tier (size, else the h
|
|
|
27
27
|
└─ Timeline.Group label labelled <ol role="list">; the line runs from its first dot to its last
|
|
28
28
|
├─ Timeline.Item <li> + row (div | button | a | asChild element) with the dot
|
|
29
29
|
│ ├─ Timeline.ItemTitle first line
|
|
30
|
-
│ ├─ Timeline.ItemMeta second line (date); <strong> emphasizes a part
|
|
30
|
+
│ ├─ Timeline.ItemMeta second line (date); <strong> emphasizes a part; repeats, lines stack
|
|
31
31
|
│ └─ Timeline.ItemValue trailing amount
|
|
32
32
|
│ └─ Timeline.ItemMeta second line under the amount
|
|
33
33
|
└─ Timeline.Gap <li>: interval between events (dashed segment, hollow dot)
|
|
@@ -73,7 +73,7 @@ Timeline.Root size container, sets the tier (size, else the h
|
|
|
73
73
|
| `…rest` | `Omit<HTMLAttributes<HTMLElement>, "children" \| "color" \| "onClick">` | — | The other row attributes (`target`, `rel`, `download` with `href`). |
|
|
74
74
|
|
|
75
75
|
### Timeline.ItemTitle · Timeline.ItemMeta
|
|
76
|
-
`ref` → `HTMLSpanElement`. `<span>` lines: the event (medium,
|
|
76
|
+
`ref` → `HTMLSpanElement`. `<span>` lines: the event (medium, wraps) and the muted secondary line, tabular — under the title the date (`<strong>` emphasizes a part; several `Timeline.ItemMeta` stack), inside `Timeline.ItemValue` the value's second line.
|
|
77
77
|
|
|
78
78
|
| Prop | Type | Default | Description |
|
|
79
79
|
|---|---|---|---|
|
|
@@ -180,7 +180,7 @@ No `labels`.
|
|
|
180
180
|
| [overview.tsx](examples/overview.tsx) | An operations feed: one labelled group, a line through the dots, the row under the pointer highlighted — `Timeline.Group`, `Timeline.ItemValue`. |
|
|
181
181
|
| [variants.tsx](examples/variants.tsx) | Dot hues for categories at reduced emphasis, and status tones on items, values and gaps at full emphasis — `color`, `tone`. |
|
|
182
182
|
| [sizes.tsx](examples/sizes.tsx) | Every tier scales text, dot and row rhythm, rows 40 to 76 px — `size`. |
|
|
183
|
-
| [structure.tsx](examples/structure.tsx) | A service history with intervals between events, a caption on the right of a gap and a second value line — `Timeline.Gap`, `Timeline.Description`, `Timeline.ItemMeta`. |
|
|
183
|
+
| [structure.tsx](examples/structure.tsx) | A service history with intervals between events, a caption on the right of a gap, two meta lines under a repair and a second value line — `Timeline.Gap`, `Timeline.Description`, `Timeline.ItemMeta`. |
|
|
184
184
|
| [links.tsx](examples/links.tsx) | Rows that open something: an operation page by a link or by your router link through the slot, a receipt in place by a button; one Tab stop each with a focus ring — `href`, `asChild`, `onClick`. |
|
|
185
185
|
| [narrow.tsx](examples/narrow.tsx) | At 375 px the title wraps and the amount stays right; below 20rem of its own width the amount moves under the meta line — `Timeline.ItemValue`. |
|
|
186
186
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** A service history with intervals between events, a caption on the right of a gap and a second value line — `Timeline.Gap`, `Timeline.Description`, `Timeline.ItemMeta`. */
|
|
1
|
+
/** A service history with intervals between events, a caption on the right of a gap, two meta lines under a repair and a second value line — `Timeline.Gap`, `Timeline.Description`, `Timeline.ItemMeta`. */
|
|
2
2
|
import { Timeline } from "prime-ui-kit";
|
|
3
3
|
|
|
4
4
|
import styles from "./examples.module.css";
|
|
@@ -36,6 +36,7 @@ export default function TimelineStructureExample() {
|
|
|
36
36
|
<Timeline.ItemMeta>
|
|
37
37
|
<strong>07.06.26</strong> · 12 100 км
|
|
38
38
|
</Timeline.ItemMeta>
|
|
39
|
+
<Timeline.ItemMeta>Мастер Олег Смирнов · гарантия 6 месяцев</Timeline.ItemMeta>
|
|
39
40
|
<Timeline.ItemValue>
|
|
40
41
|
2 800 ₽<Timeline.ItemMeta>Ремонт</Timeline.ItemMeta>
|
|
41
42
|
</Timeline.ItemValue>
|
|
@@ -94,7 +94,7 @@ Text has no interactive states.
|
|
|
94
94
|
- No outer margins: spacing comes from the parent's `gap`.
|
|
95
95
|
- Title, heading and display roles balance their lines (`text-wrap-style: balance`); body and caption avoid a lone last word (`pretty`). Long words break (`overflow-wrap: break-word`).
|
|
96
96
|
- `code` uses the mono family (JetBrains Mono); every other role the sans family (Golos Text).
|
|
97
|
-
- Reading text: cap the column at the reading measure (
|
|
97
|
+
- Reading text: cap the column at the reading measure (`Page.Root maxWidth="readable"`, 60–75 characters).
|
|
98
98
|
- `truncate` needs a block element and a shrinking parent (`min-width: 0` in flex rows).
|
|
99
99
|
|
|
100
100
|
## Accessibility
|
|
@@ -138,4 +138,4 @@ No `labels`.
|
|
|
138
138
|
|
|
139
139
|
## Related
|
|
140
140
|
- **Built from:** —
|
|
141
|
-
- **See also:** [LinkButton](../link-button/COMPONENT.md), [CodeBlock](../code-block/COMPONENT.md), [Label](../label/COMPONENT.md), [
|
|
141
|
+
- **See also:** [LinkButton](../link-button/COMPONENT.md), [CodeBlock](../code-block/COMPONENT.md), [Label](../label/COMPONENT.md), [Page](../../layout/page/COMPONENT.md)
|
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
**Category:** page
|
|
4
4
|
**Kind:** layout
|
|
5
5
|
|
|
6
|
-
> The app frame: a content panel that is the page itself and a navigation rail one layer above it.
|
|
6
|
+
> The app frame — navigation and the page: a content panel that is the page itself and a navigation rail one layer above it.
|
|
7
7
|
|
|
8
8
|
## When to use
|
|
9
|
-
- The root layout of an application: navigation column,
|
|
9
|
+
- The root layout of an application: navigation column, the scrolling main where the page renders, a bottom bar for phone navigation.
|
|
10
10
|
- Any page that needs the kit's responsive gutters and the surface ladder for cards and fields.
|
|
11
11
|
|
|
12
12
|
## When not to use
|
|
13
13
|
- The navigation itself → use [Sidebar](../sidebar/COMPONENT.md) inside `AppShell.Nav`, [BottomNav](../bottom-nav/COMPONENT.md) inside `AppShell.Footer`.
|
|
14
|
-
-
|
|
15
|
-
- Page heading, actions and sections inside main → use [
|
|
14
|
+
- Anything at the top of the page — the title, its actions and tools, the phone menu button → the page's own top bar, [Page](../page/COMPONENT.md) `Page.TopBar`; the shell has no header.
|
|
15
|
+
- Page heading, actions and sections inside main → use [Page](../page/COMPONENT.md).
|
|
16
16
|
- A temporary side panel over the page → use [Drawer](../../components/drawer/COMPONENT.md).
|
|
17
17
|
- A scroll region inside a page → use [ScrollContainer](../../components/scroll-container/COMPONENT.md).
|
|
18
18
|
|
|
@@ -25,25 +25,24 @@ import { AppShell } from "prime-ui-kit";
|
|
|
25
25
|
```
|
|
26
26
|
AppShell.Root grid: nav column | content panel (the page, layer 0)
|
|
27
27
|
├─ AppShell.Nav navigation column (usually Sidebar.Root, a surface one layer above the page)
|
|
28
|
-
├─
|
|
29
|
-
├─ AppShell.Main <main>, scrolls, carries the gutters
|
|
28
|
+
├─ AppShell.Main <main>, scrolls; hands the page (Page.Root) its gutters and top air
|
|
30
29
|
└─ AppShell.Footer sticky bottom bar of the panel (usually BottomNav.Root)
|
|
31
|
-
AppShell.Template Root + Nav +
|
|
30
|
+
AppShell.Template Root + Nav + Main + Footer in one component
|
|
32
31
|
useAppShellNav() the navigation the Sidebar publishes, for triggers outside the rail
|
|
33
32
|
```
|
|
34
|
-
Every child of Root that is not `AppShell.Nav` is placed into the content panel.
|
|
33
|
+
Every child of Root that is not `AppShell.Nav` is placed into the content panel. Everything at the top of the panel belongs to the page: its `Page.TopBar` sticks to the top of main.
|
|
35
34
|
|
|
36
35
|
## API
|
|
37
36
|
|
|
38
37
|
<!-- Generated from api.ts by `bun run docs:build`. Edit api.ts, not this section. -->
|
|
39
38
|
|
|
40
39
|
### AppShell.Root
|
|
41
|
-
`ref` → `HTMLDivElement`. Grid of the nav column and the content panel (the page itself); every child but `AppShell.Nav` goes into the panel. Owns the navigation its Sidebar publishes (`useAppShellNav`)
|
|
40
|
+
`ref` → `HTMLDivElement`. Grid of the nav column and the content panel (the page itself); every child but `AppShell.Nav` goes into the panel. Owns the navigation its Sidebar publishes (`useAppShellNav`).
|
|
42
41
|
|
|
43
42
|
| Prop | Type | Default | Description |
|
|
44
43
|
|---|---|---|---|
|
|
45
44
|
| `fillViewport` | `boolean` | `false` | The shell is exactly the viewport high and only `AppShell.Main` scrolls; otherwise the document scrolls and the nav is sticky. |
|
|
46
|
-
| `…rest` | `HTMLAttributes<HTMLDivElement>` | — | `children` (Nav,
|
|
45
|
+
| `…rest` | `HTMLAttributes<HTMLDivElement>` | — | `children` (Nav, Main, Footer), `className` and the other div attributes. |
|
|
47
46
|
|
|
48
47
|
### AppShell.Nav
|
|
49
48
|
`ref` → `HTMLDivElement`. The navigation column slot (not a landmark: Sidebar renders the `<nav>`).
|
|
@@ -53,11 +52,10 @@ Every child of Root that is not `AppShell.Nav` is placed into the content panel.
|
|
|
53
52
|
| `…rest` | `HTMLAttributes<HTMLDivElement>` | — | `children` (usually `Sidebar.Root`), `className` and the other div attributes. |
|
|
54
53
|
|
|
55
54
|
### AppShell.Main
|
|
56
|
-
`ref` → `HTMLElement`. The `<main>`
|
|
55
|
+
`ref` → `HTMLElement`. The `<main>` where the page renders: a vertical `ScrollContainer` that hands `Page.Root` the gutters and top air (`--page-gutter`, `--page-top`).
|
|
57
56
|
|
|
58
57
|
| Prop | Type | Default | Description |
|
|
59
58
|
|---|---|---|---|
|
|
60
|
-
| `contentWidth` | `"contained" \| "full"` | `"full"` | `full` — the whole panel with gutters; `contained` — a centred column up to `--prime-layout-content-max-width`. |
|
|
61
59
|
| `…rest` | `HTMLAttributes<HTMLElement>` | — | `children`, `className` and the other attributes. |
|
|
62
60
|
|
|
63
61
|
### AppShell.Footer
|
|
@@ -68,17 +66,16 @@ Every child of Root that is not `AppShell.Nav` is placed into the content panel.
|
|
|
68
66
|
| `…rest` | `HTMLAttributes<HTMLDivElement>` | — | `children` (usually `BottomNav.Root`), `className` and the other div attributes. |
|
|
69
67
|
|
|
70
68
|
### AppShell.Template
|
|
71
|
-
`ref` → the `<main>`. Root + Nav +
|
|
69
|
+
`ref` → the `<main>`. Root + Nav + Main + Footer in one; main scrolls to the top when `scrollResetKey` changes.
|
|
72
70
|
|
|
73
71
|
| Prop | Type | Default | Description |
|
|
74
72
|
|---|---|---|---|
|
|
75
73
|
| `fillViewport` | `boolean` | `false` | As on `AppShell.Root`: only `<main>` scrolls. |
|
|
76
74
|
| `nav` | `ReactNode` | — | Navigation column content; without it the panel takes the full width. |
|
|
77
|
-
| `header` | `ReactNode` | — | The default header row, an `AppHeader.Root`: a page that renders its own header replaces it while that page is on screen. |
|
|
78
75
|
| `footer` | `ReactNode` | — | Footer content (`BottomNav`); no footer when omitted. |
|
|
79
|
-
| `mainProps` | `Omit<AppShellMainProps, "children">` | — | Props for Main (
|
|
76
|
+
| `mainProps` | `Omit<AppShellMainProps, "children">` | — | Props for Main (`id`, `tabIndex` for a skip link). |
|
|
80
77
|
| `scrollResetKey` | `unknown` | — | Main scrolls back to the top whenever this value changes; pass the router pathname. |
|
|
81
|
-
| `children` | `ReactNode` | — |
|
|
78
|
+
| `children` | `ReactNode` | — | The page inside Main (`Page.Root`). |
|
|
82
79
|
| `…rest` | `Omit<AppShellRootProps, "children">` | — | Root props: `fillViewport`, `className` and the div attributes. |
|
|
83
80
|
|
|
84
81
|
### Types
|
|
@@ -108,38 +105,29 @@ The navigation of the nearest `AppShell.Root` for a trigger outside the rail (a
|
|
|
108
105
|
| Value | Looks like | Use when | Default |
|
|
109
106
|
|---|---|---|---|
|
|
110
107
|
| `false` | Shell at least viewport high; the document scrolls; nav sticks to the top | Content sites, simple apps | yes |
|
|
111
|
-
| `true` | Shell exactly viewport high; only Main scrolls;
|
|
112
|
-
|
|
113
|
-
### contentWidth (Main)
|
|
114
|
-
| Value | Looks like | Use when | Default |
|
|
115
|
-
|---|---|---|---|
|
|
116
|
-
| `full` | Content spans the panel with responsive gutters | Tables, dashboards | yes |
|
|
117
|
-
| `contained` | Centred column up to the content max width | Long-read pages | |
|
|
108
|
+
| `true` | Shell exactly viewport high; only Main scrolls; nav and the page's sticky top bar stay put | Dense apps with a fixed frame | |
|
|
118
109
|
|
|
119
110
|
### Structure
|
|
120
111
|
| Value | Looks like | Use when | Default |
|
|
121
112
|
|---|---|---|---|
|
|
122
113
|
| with `AppShell.Nav` | Two columns: a rail one layer above the page + the panel that is the page | Apps with navigation | |
|
|
123
114
|
| without Nav | Panel takes the full width | Single-page tools, auth screens | |
|
|
124
|
-
| with `AppHeader.Root` | Sticky bar in the header row at the top of the panel, from anywhere in the shell | The page title (or the path and the record), the page's tools and buttons; on a phone it leads with the menu button | |
|
|
125
115
|
| with `AppShell.Footer` | Sticky bar at the bottom of the panel, shown while no navigation column is on screen | BottomNav on a phone | |
|
|
126
116
|
|
|
127
|
-
`AppShell.Template` with `nav={<Sidebar.Root …/>}` and `
|
|
117
|
+
`AppShell.Template` with `nav={<Sidebar.Root …/>}` and a `Page.Root` inside is the standard app; `Page.Root maxWidth="readable"` for docs and articles.
|
|
128
118
|
|
|
129
119
|
## States
|
|
130
120
|
| State | Driven by | DOM |
|
|
131
121
|
|---|---|---|
|
|
132
122
|
| fixed frame | `fillViewport` | `data-fill-viewport="true"` on Root |
|
|
133
123
|
| navigation column | an `AppShell.Nav` child | `data-nav="true"` on Root (two grid columns) |
|
|
134
|
-
| content width | `contentWidth` | `data-content-width` on Main |
|
|
135
124
|
| off-canvas navigation | the Sidebar publishes that it is an off-canvas panel (`offCanvas="auto"` on a phone, `"always"`) | `data-off-canvas="true"` on Root; `useAppShellNav()` reports `offCanvas`, `open`, `navId` |
|
|
136
125
|
| footer bar | the navigation column: `AppShell.Nav` with a Sidebar that is not off-canvas | the footer is `display: none` while the rail is on screen; without Nav or with an off-canvas Sidebar it stays at any width |
|
|
137
|
-
| header row | an `AppHeader.Root` in the shell | the latest one on screen renders at the top of the panel, before main |
|
|
138
126
|
|
|
139
127
|
## Layout & spacing
|
|
140
128
|
- Two full-height planes edge to edge: no inset, radius, shadow or border — the boundary is the fill change (the Sidebar rail is layer 1, the panel the page: white rail beside a gray page in light, a rail one step lighter than the near-black page in dark).
|
|
141
|
-
-
|
|
142
|
-
- A page that fills the panel height (`
|
|
129
|
+
- Main hands the page its edge air: `--page-gutter` is the page gutter `--prime-layout-gutter` — `--prime-layout-gutter-s` (16) → `-m` (24) from 640px → `-l` (32) from 1024px; `--page-top` is `--prime-space-6` (24) → `--prime-space-8` (32) from 1024px. `Page.Root` pads itself with them (its top bar steps out to the panel's edges). Main itself pads only the bottom: `--prime-space-16`, the scroll tail of a long page. Inside Main the page gutter is the small one again, so a frame nested in the page starts from its own gutter, not the shell's.
|
|
130
|
+
- A page that fills the panel height (`Page.Root fill`): Main's bottom padding drops to the side gutter, so no long scroll tail stays under it — beside the Sidebar rail too.
|
|
143
131
|
- Main scrolls with `overscroll-behavior: contain`, so its scroll never chains to the document.
|
|
144
132
|
- Nav column: sticky at the top, viewport high, `z-index: --prime-z-sticky` (above the panel, so the compact Sidebar toggle can ride the rail edge); with `fillViewport` it fills the shell height instead.
|
|
145
133
|
- Footer: no padding of its own (BottomNav keeps the bottom safe-area inset), sticky at the bottom, `z-index: --prime-z-sticky`.
|
|
@@ -156,8 +144,8 @@ No keyboard interaction.
|
|
|
156
144
|
### ARIA
|
|
157
145
|
<!-- Generated from api.ts by `bun run docs:build`. Edit api.ts, not this section. -->
|
|
158
146
|
|
|
159
|
-
- Main is the `<main>` landmark; the
|
|
160
|
-
- One `<h1>` per page:
|
|
147
|
+
- Main is the `<main>` landmark; the navigation landmarks come from Sidebar and BottomNav (`<nav>`). The page's top bar is a `<header>` inside main, not a banner.
|
|
148
|
+
- One `<h1>` per page: its `Page.Title`, in the top bar or in the flow.
|
|
161
149
|
|
|
162
150
|
### Labels
|
|
163
151
|
<!-- Generated from api.ts by `bun run docs:build`. Edit api.ts, not this section. -->
|
|
@@ -167,21 +155,20 @@ No `labels`.
|
|
|
167
155
|
## Examples
|
|
168
156
|
| Example | Shows |
|
|
169
157
|
|---|---|
|
|
170
|
-
| [overview.tsx](examples/overview.tsx) | The app frame: Sidebar in the nav column, the page title and
|
|
171
|
-
| [contained.tsx](examples/contained.tsx) | A shell without navigation whose main column is centred and capped for long reads — `contentWidth`. |
|
|
158
|
+
| [overview.tsx](examples/overview.tsx) | The app frame: Sidebar in the nav column, the page in main with its title and action in its top bar; only main scrolls — `fillViewport`. |
|
|
172
159
|
| [footer.tsx](examples/footer.tsx) | A phone app without a Sidebar: the bar in the footer stays at the bottom while main scrolls under it — `AppShell.Footer`. |
|
|
173
|
-
| [template.tsx](examples/template.tsx) | Root, nav,
|
|
174
|
-
| [screen.tsx](examples/screen.tsx) | The app frame for desktop and phone: the Sidebar rail on a wide screen, the floating BottomNav in the footer on a phone whose More item opens the Sidebar, the
|
|
160
|
+
| [template.tsx](examples/template.tsx) | Root, nav, main and footer in one component; main scrolls back to the top whenever the page changes — `AppShell.Template`, `scrollResetKey`. |
|
|
161
|
+
| [screen.tsx](examples/screen.tsx) | The app frame for desktop and phone: the Sidebar rail on a wide screen, the floating BottomNav in the footer on a phone whose More item opens the Sidebar, the page top bar with the menu button it draws by itself, the page title with a line of data, and a simple home page that swaps with the current section — `fillViewport`, `scrollResetKey`, `useAppShellNav`. |
|
|
175
162
|
|
|
176
163
|
## Mistakes
|
|
177
|
-
- Adding padding around the page content →
|
|
164
|
+
- Adding padding around the page content → `Page.Root` takes the gutters Main hands it.
|
|
178
165
|
- Wrapping Main content in another scroll container → Main scrolls (with `fillViewport`) or the document does.
|
|
179
166
|
- A border or shadow between nav and panel → the fill change is the boundary.
|
|
180
167
|
- Putting the Sidebar directly in Root without `AppShell.Nav` → it lands inside the content panel.
|
|
181
168
|
- BottomNav anywhere but `AppShell.Footer` → it stays next to the Sidebar rail on a desktop; the footer is what leaves while the rail is on screen.
|
|
182
169
|
- `AppShell.Template` in a router app without `scrollResetKey` → a new page opens at the old scroll position; pass the pathname.
|
|
183
|
-
- A hand-wired menu state shared by the Sidebar, a menu button and a BottomNav «Ещё» → the Sidebar publishes it to the shell: the
|
|
170
|
+
- A hand-wired menu state shared by the Sidebar, a menu button and a BottomNav «Ещё» → the Sidebar publishes it to the shell: the page's `Page.TopBar` draws the menu button, other triggers read `useAppShellNav()`.
|
|
184
171
|
|
|
185
172
|
## Related
|
|
186
173
|
- **Built from:** [ScrollContainer](../../components/scroll-container/COMPONENT.md)
|
|
187
|
-
- **See also:** [
|
|
174
|
+
- **See also:** [Page](../page/COMPONENT.md), [Sidebar](../sidebar/COMPONENT.md), [BottomNav](../bottom-nav/COMPONENT.md), [Breadcrumb](../../components/breadcrumb/COMPONENT.md)
|