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
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** Status hints whose words carry the status and the color repeats it — `tone`. */
|
|
2
|
+
import { Hint, Icon, Typography } from "prime-ui-kit";
|
|
3
|
+
|
|
4
|
+
export default function HintVariantsExample() {
|
|
5
|
+
return (
|
|
6
|
+
<div>
|
|
7
|
+
<div>
|
|
8
|
+
<Hint.Root>Действует до 30 ноября.</Hint.Root>
|
|
9
|
+
<Typography as="span" variant="caption" tone="muted">
|
|
10
|
+
neutral
|
|
11
|
+
</Typography>
|
|
12
|
+
</div>
|
|
13
|
+
<div>
|
|
14
|
+
<Hint.Root tone="success">
|
|
15
|
+
<Hint.Icon>
|
|
16
|
+
<Icon name="status.success" />
|
|
17
|
+
</Hint.Icon>
|
|
18
|
+
ИНН проверен в ФНС.
|
|
19
|
+
</Hint.Root>
|
|
20
|
+
<Typography as="span" variant="caption" tone="muted">
|
|
21
|
+
success
|
|
22
|
+
</Typography>
|
|
23
|
+
</div>
|
|
24
|
+
<div>
|
|
25
|
+
<Hint.Root tone="warning">
|
|
26
|
+
<Hint.Icon>
|
|
27
|
+
<Icon name="status.warning" />
|
|
28
|
+
</Hint.Icon>
|
|
29
|
+
Осталось 12 дней.
|
|
30
|
+
</Hint.Root>
|
|
31
|
+
<Typography as="span" variant="caption" tone="muted">
|
|
32
|
+
warning
|
|
33
|
+
</Typography>
|
|
34
|
+
</div>
|
|
35
|
+
<div>
|
|
36
|
+
<Hint.Root tone="danger">
|
|
37
|
+
<Hint.Icon>
|
|
38
|
+
<Icon name="status.danger" />
|
|
39
|
+
</Hint.Icon>
|
|
40
|
+
Срок истёк 3 дня назад.
|
|
41
|
+
</Hint.Root>
|
|
42
|
+
<Typography as="span" variant="caption" tone="muted">
|
|
43
|
+
danger
|
|
44
|
+
</Typography>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
@@ -11,12 +11,15 @@
|
|
|
11
11
|
- Values with a fixed prefix/suffix (`https://`, domain, `₽`, `%`).
|
|
12
12
|
- Inline editing in a record card: each field saves itself (`onCommit`) on blur and Enter.
|
|
13
13
|
- A value with actions beside it: copy, write, open a profile (`Input.CopyButton`, `Input.Action`); a password with a show toggle (`Input.RevealButton`).
|
|
14
|
+
- Free text with suggestions (a combobox): a place, a city, a tag the team typed before — `suggestions`; any other text stays allowed.
|
|
15
|
+
- A picker and a text as one field (an icon and a name, a channel and an address): a `Select` inside `Input.Wrapper` is the box's start segment.
|
|
16
|
+
- A time of day: `Input.Field type="time"` — the browser's hour and minute segments (arrows step them, `step`, `min`, `max`), a wheel on phones, and no calendar to open.
|
|
14
17
|
- As the reference field: Select, Datepicker, TagSelect and Textarea follow the same label / field / support-row contract.
|
|
15
18
|
|
|
16
19
|
## When not to use
|
|
17
20
|
- Multi-line text → use [Textarea](../textarea/COMPONENT.md).
|
|
18
21
|
- One-time codes split into cells → use [DigitInput](../digit-input/COMPONENT.md).
|
|
19
|
-
- Choosing from a fixed list → use [Select](../select/COMPONENT.md) or [TagSelect](../tag-select/COMPONENT.md).
|
|
22
|
+
- Choosing from a fixed list, where the value must be one of it → use [Select](../select/COMPONENT.md) or [TagSelect](../tag-select/COMPONENT.md); `suggestions` only help typing free text.
|
|
20
23
|
- Dates → use [Datepicker](../datepicker/COMPONENT.md).
|
|
21
24
|
- A standalone label or message without an Input field → use [Label](../label/COMPONENT.md) / [Hint](../hint/COMPONENT.md).
|
|
22
25
|
- Global search across the app in a dialog → use [CommandMenu](../command-menu/COMPONENT.md).
|
|
@@ -33,14 +36,16 @@ Input.Root label row, field body, support row; provides size / invali
|
|
|
33
36
|
├─ Input.Affix tinted section flush with the edge (start | end)
|
|
34
37
|
├─ Input.Icon decorative icon (start | end)
|
|
35
38
|
├─ Input.InlineAffix muted text next to the value (start | end)
|
|
36
|
-
├─
|
|
39
|
+
├─ Select.Root optional start segment: an icon-only picker in the box (no frame)
|
|
40
|
+
├─ Input.Field native <input>; a combobox with `suggestions`
|
|
37
41
|
├─ Input.ClearButton clear segment (kit-rendered)
|
|
38
42
|
├─ Input.CopyButton copy segment; the glyph morphs into a check (kit-rendered)
|
|
39
43
|
├─ Input.RevealButton show / hide a password segment, aria-pressed (kit-rendered)
|
|
40
44
|
└─ Input.Action the consumer's named icon action with a tooltip (button or asChild link)
|
|
45
|
+
listbox `suggestions`: a floating list under the box, as wide as it
|
|
41
46
|
Input.Counter goes into Input.Root `counter` (support row, right side)
|
|
42
47
|
```
|
|
43
|
-
The trailing side has a fixed CSS `order`, independent of JSX order: value · end inline affix · commit status (`onCommit`) · end icon · segments · end affix. The segments (`ClearButton`, `CopyButton`, `RevealButton`, `Action`) keep their JSX order among themselves and sit edge to edge, full field height, flush with the end edge. All `side="start"` slots share one order before the value, so among them the JSX order decides — write them as affix, icon, inline affix.
|
|
48
|
+
The trailing side has a fixed CSS `order`, independent of JSX order: value · end inline affix · commit status (`onCommit`) · end icon · segments · end affix. The segments (`ClearButton`, `CopyButton`, `RevealButton`, `Action`) keep their JSX order among themselves and sit edge to edge, full field height, flush with the end edge. A `Select` segment comes first, flush with the start edge. All `side="start"` slots share one order before the value, so among them the JSX order decides — write them as affix, icon, inline affix.
|
|
44
49
|
|
|
45
50
|
## API
|
|
46
51
|
|
|
@@ -56,6 +61,7 @@ The trailing side has a fixed CSS `order`, independent of JSX order: value · en
|
|
|
56
61
|
| `required` | `boolean` | `false` | Red `*` after the label (`aria-hidden`) and native `required` on `Input.Field`. |
|
|
57
62
|
| `optional` | `boolean` | `false` | Muted marker right after the label text (`labels.optional`). |
|
|
58
63
|
| `hint` | `ReactNode` | — | Help text under the field. Hidden while `error` is shown. |
|
|
64
|
+
| `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. |
|
|
59
65
|
| `error` | `ReactNode` | — | Error message in the hint slot; implies `invalid`. |
|
|
60
66
|
| `invalid` | `boolean` | `false` | Danger inset ring on the field, `aria-invalid` on the input. A non-empty `error` implies it. |
|
|
61
67
|
| `focusRing` | `boolean` | `true` | `false` hides only the visual focus ring on `Input.Wrapper` (`data-focus-ring="false"`); focus, keyboard, ARIA and the invalid ring stay. |
|
|
@@ -65,6 +71,9 @@ The trailing side has a fixed CSS `order`, independent of JSX order: value · en
|
|
|
65
71
|
| `strength` | `boolean` | `false` | A password strength meter for new-password fields: a stepped `ProgressBar` under the field and the level word (weak … hard) in the support row. Follows the value of `Input.Field`. |
|
|
66
72
|
| `getStrength` | `(value: string) => 0 \| 1 \| 2 \| 3 \| 4` | `getPasswordStrength` | Replaces the kit's estimate of `strength`. Return 0 for empty, 1 weak … 4 hard. A hint for the person typing, not a security check. |
|
|
67
73
|
| `onCommit` | `(value: string) => void \| Promise<void>` | — | Inline save: fires with a changed value on blur and Enter; Escape reverts. Return a Promise: the field shows a spinner and stays editable; a rejection restores the value — show why through `error`. |
|
|
74
|
+
| `suggestions` | `readonly string[]` | — | Suggestions for free text (a combobox): a list under the box shows those containing the text; a pick goes into the field as typing would. Any text stays allowed; a value from a list only is `Select`. |
|
|
75
|
+
| `closeOnEscape` | `boolean` | `true` | Escape closes the `suggestions` list; the text and the focus stay in the field. |
|
|
76
|
+
| `closeOnOutsideClick` | `boolean` | `true` | A press outside the field and the `suggestions` list closes the list. |
|
|
68
77
|
| `labels` | `Partial<InputLabels>` | — | Built-in strings, see Labels. |
|
|
69
78
|
| `children` | `ReactNode` | — (required) | Usually `Input.Wrapper`. |
|
|
70
79
|
| `…rest` | `Omit<HTMLAttributes<HTMLDivElement>, "id" \| "children" \| "defaultValue" \| "defaultChecked" \| "onChange">` | — | `className`, `data-*` and the other attributes of the field frame `<div>` (field-root rule: `className`, `ref` and the rest → frame, `id` → control). |
|
|
@@ -83,7 +92,7 @@ The trailing side has a fixed CSS `order`, independent of JSX order: value · en
|
|
|
83
92
|
| Prop | Type | Default | Description |
|
|
84
93
|
|---|---|---|---|
|
|
85
94
|
| `onValueChange` | `(value: string) => void` | — | Called with the new string; native `onChange` still fires first. |
|
|
86
|
-
| `aria-describedby` | `string` | — | Merged with the hint/error ids from the root. |
|
|
95
|
+
| `aria-describedby` | `string` | — | Merged with the affix and hint/error ids from the root. |
|
|
87
96
|
| `required` | `boolean` | — | Overrides the root's `required` for the native input. |
|
|
88
97
|
| `…rest` | `Omit<InputHTMLAttributes<HTMLInputElement>, "size" \| "id">` | — | `value`, `defaultValue`, `onChange`, `type`, `disabled`, `readOnly`, `maxLength`, `placeholder`… |
|
|
89
98
|
|
|
@@ -97,21 +106,23 @@ The trailing side has a fixed CSS `order`, independent of JSX order: value · en
|
|
|
97
106
|
| `…rest` | `Omit<HTMLAttributes<HTMLSpanElement>, "children">` | — | `className` and the other attributes of the `<span>`. |
|
|
98
107
|
|
|
99
108
|
### Input.Affix
|
|
100
|
-
`ref` → `HTMLDivElement`. Tinted section flush with the edge (`aria-hidden
|
|
109
|
+
`ref` → `HTMLDivElement`. Tinted section flush with the edge (`aria-hidden`, its text describes the input); the wrapper drops its padding there.
|
|
101
110
|
|
|
102
111
|
| Prop | Type | Default | Description |
|
|
103
112
|
|---|---|---|---|
|
|
104
113
|
| `side` | `"start" \| "end"` | — (required) | Edge the section sits on. |
|
|
105
114
|
| `children` | `ReactNode` | — (required) | Static text: protocol, domain, country code. |
|
|
115
|
+
| `aria-label` | `string` | — | What a screen reader says instead of the text in the input's description. |
|
|
106
116
|
| `…rest` | `Omit<HTMLAttributes<HTMLDivElement>, "children">` | — | `className` and the other attributes of the `<div>`. |
|
|
107
117
|
|
|
108
118
|
### Input.InlineAffix
|
|
109
|
-
`ref` → `HTMLSpanElement`. Muted unit next to the value (`aria-hidden
|
|
119
|
+
`ref` → `HTMLSpanElement`. Muted unit next to the value (`aria-hidden`, its text describes the input) — the one place of the unit.
|
|
110
120
|
|
|
111
121
|
| Prop | Type | Default | Description |
|
|
112
122
|
|---|---|---|---|
|
|
113
123
|
| `side` | `"start" \| "end"` | — (required) | Side of the value. |
|
|
114
124
|
| `children` | `ReactNode` | — (required) | Short unit: `₽`, `%`, `кг`. |
|
|
125
|
+
| `aria-label` | `string` | — | The unit in words for a screen reader («рублей»), said instead of the sign in the input's description. |
|
|
115
126
|
| `…rest` | `Omit<HTMLAttributes<HTMLSpanElement>, "children">` | — | `className` and the other attributes of the `<span>`. |
|
|
116
127
|
|
|
117
128
|
### Input.ClearButton
|
|
@@ -181,6 +192,8 @@ Input has no `variant` or `tone`: there is one field treatment (fill, no visible
|
|
|
181
192
|
|---|---|---|---|
|
|
182
193
|
| `focusRing` | `false`: no focus ring; the field still switches to the focus fill, caret visible | A single search field where focus is obvious | `true` |
|
|
183
194
|
| `reserveSupportRow` | Empty support row of hint height under the field | Fields validated on the fly; neighbouring fields in one grid row | `false` |
|
|
195
|
+
| `closeOnOutsideClick` | `false`: a press beside the field keeps the `suggestions` list open | The person copies the value from elsewhere on the page | `true` |
|
|
196
|
+
| `closeOnEscape` | `false`: Escape leaves the `suggestions` list open | Rare: the list closes only by a pick, Tab or blur | `true` |
|
|
184
197
|
| `required` / `optional` | Red `*` / muted «необязательно» after the label | Mark the minority: required when most are optional, optional when most are required | `false` |
|
|
185
198
|
|
|
186
199
|
**Combinations**
|
|
@@ -202,6 +215,8 @@ Input has no `variant` or `tone`: there is one field treatment (fill, no visible
|
|
|
202
215
|
| read-only | native `readOnly` on `Input.Field` | no hover, default cursor |
|
|
203
216
|
| reserved support row | `reserveSupportRow` | `data-reserve="true"` on the support row |
|
|
204
217
|
| counter over limit | `current > max` | `data-invalid="true"` on `Input.Counter`; the current count rolls its digits to each new value |
|
|
218
|
+
| suggesting | `suggestions` + typing, ↓ / ↑ or a click in the field | `role="combobox"`, `aria-expanded="true"` and `aria-controls` on the input; the list fades in under the box (the floating panel's motion) with the matching part of each suggestion marked; the highlight is a fill (`data-highlighted`, `aria-selected`) named by `aria-activedescendant`; closes on a pick, Escape, Tab, blur or a press outside |
|
|
219
|
+
| select segment | a `Select` inside `Input.Wrapper` | `data-field-segment` on the select root, `data-segment="true"` on its trigger: a tinted section (`fill-subtle`) flush with the start edge, a stronger fill on hover and while open, its own inset focus ring; the box's ring stays for the text |
|
|
205
220
|
| strength | `strength` + the value of `Input.Field` | a stepped `ProgressBar` (4 cells, `aria-label` = `labels.strength`) under the field fills one cell after another, weak · easy · medium · hard, toned danger → warning → accent → success; the level word at the end of the support row flows in letter by letter and is announced (`aria-live`); the support row is reserved |
|
|
206
221
|
| saving | `onCommit` returned a pending Promise | `aria-busy="true"` on the input; a `Spinner` at the end of the field (`data-commit="pending"`); the field stays editable and focusable, neighbours are untouched; a live region says `labels.saving` |
|
|
207
222
|
| saved | the Promise resolved (or `onCommit` returned nothing) | the spinner cross-fades into a success check (`data-commit="saved"`) that fades out after a moment; the live region says `labels.saved` |
|
|
@@ -215,6 +230,8 @@ Inline save (`onCommit`): the value at focus is the committed one. Blur and Ente
|
|
|
215
230
|
|
|
216
231
|
Strength estimate (`strength`, replaced by `getStrength`): every trait adds a point on its own, in any order — lowercase, uppercase, digits, symbols, 10+ and 14+ characters; 0–2 points weak, 3 easy, 4 medium, 5+ hard, and under 8 characters at most easy. The meter follows `Input.Field` controlled or not.
|
|
217
232
|
|
|
233
|
+
Suggestions (`suggestions`): the list shows the suggestions that contain the typed text (case-insensitive), and nothing when the text already is the only match. A pick writes the suggestion into the input the way typing does, so `onValueChange` (and `onCommit` on blur) receive it; the text is never restricted to the list.
|
|
234
|
+
|
|
218
235
|
Controlled: `value` + `onChange` (or `onValueChange`) on `Input.Field`. Uncontrolled: `defaultValue`. Both are native input props.
|
|
219
236
|
|
|
220
237
|
## Layout & spacing
|
|
@@ -234,6 +251,10 @@ Controlled: `value` + `onChange` (or `onValueChange`) on `Input.Field`. Uncontro
|
|
|
234
251
|
| `Tab` | Focuses the field, then the segments at its end (clear, copy, reveal, actions). |
|
|
235
252
|
| `Enter` · `Space` | On a segment: runs its action (the clear button returns focus to the field). |
|
|
236
253
|
| `Enter` | With `onCommit`: saves a changed value; focus stays in the field. |
|
|
254
|
+
| `↓` · `↑` | With `suggestions`: opens the list on the first (last) suggestion; in the open list moves the highlight, wrapping. Focus stays in the field. |
|
|
255
|
+
| `Alt + ↓` | With `suggestions`: opens the list without highlighting. |
|
|
256
|
+
| `Enter` | With `suggestions`: puts the highlighted suggestion into the field and closes the list; with no highlight the typed text stays. |
|
|
257
|
+
| `Escape` | With `suggestions`: closes the open list, the text stays; a dialog around the field stays open. |
|
|
237
258
|
| `Escape` | With `onCommit`: puts the committed value back. |
|
|
238
259
|
|
|
239
260
|
### ARIA
|
|
@@ -241,7 +262,9 @@ Controlled: `value` + `onChange` (or `onValueChange`) on `Input.Field`. Uncontro
|
|
|
241
262
|
|
|
242
263
|
- `label` renders a `<label htmlFor>` bound to the input. Without `label`, set `aria-label` on `Input.Field`. A placeholder never replaces the label.
|
|
243
264
|
- Hint and error are linked through `aria-describedby`; the error replaces the hint and sets `aria-invalid="true"`.
|
|
244
|
-
- `Input.Icon
|
|
265
|
+
- `Input.Icon` is decorative (`aria-hidden`). `Input.Affix` and `Input.InlineAffix` are `aria-hidden` in the reading order but describe the input (`aria-describedby`, before the hint): the unit is heard with the field, so the label never repeats it. An `aria-label` on the affix is said instead of its text («рублей» for `₽`).
|
|
266
|
+
- `suggestions` make the input a `combobox` (`aria-autocomplete="list"`, `aria-expanded`, `aria-controls` on the open `listbox`, which the label names); the highlight is `aria-activedescendant`, so focus never leaves the field.
|
|
267
|
+
- A `Select` inside `Input.Wrapper` is the box's start segment: its trigger is named by the select root's `aria-label` and the picked value («Иконка: Звезда»).
|
|
245
268
|
- `Input.ClearButton` is a real button named by `labels.clear`, with `aria-controls` on the input.
|
|
246
269
|
- `Input.Action` and `Input.CopyButton` are buttons (or a link with `asChild`) named by their label, with a tooltip; copying announces `labels.copied` through a polite live region.
|
|
247
270
|
- `Input.RevealButton` is a toggle: a constant name `labels.reveal`, `aria-pressed` and `aria-controls` on the input; a pointer press keeps the focus in the field.
|
|
@@ -276,11 +299,15 @@ Controlled: `value` + `onChange` (or `onValueChange`) on `Input.Field`. Uncontro
|
|
|
276
299
|
| [states.tsx](examples/states.tsx) | A default field next to a disabled, a read-only and an invalid one with no message — `disabled`, `readOnly`, `invalid`. |
|
|
277
300
|
| [validation.tsx](examples/validation.tsx) | Live validation: an error shakes the field as it arrives, drops in and leaves as soon as the value is fixed; required and optional markers, a hint and a support row that does not shift — `required`, `optional`, `hint`, `error`, `reserveSupportRow`. |
|
|
278
301
|
| [with-icon.tsx](examples/with-icon.tsx) | A decorative icon at either end of the value — `Input.Icon`, `side`. |
|
|
279
|
-
| [affixes.tsx](examples/affixes.tsx) | A fixed prefix and suffix flush with the edges and a unit next to the value — `Input.Affix`, `Input.InlineAffix`. |
|
|
302
|
+
| [affixes.tsx](examples/affixes.tsx) | A fixed prefix and suffix flush with the edges and a unit next to the value, heard as a word by a screen reader — `Input.Affix`, `Input.InlineAffix`, `aria-label`. |
|
|
280
303
|
| [without-focus-ring.tsx](examples/without-focus-ring.tsx) | A single search field where the caret and the lighter fill show focus — `focusRing`. |
|
|
281
304
|
| [password-strength.tsx](examples/password-strength.tsx) | A new password with a show toggle and a meter that fills step by step and names the level beside the hint, and a service password measured by the company's own rule — `Input.RevealButton`, `strength`, `getStrength`. |
|
|
282
305
|
| [edge-actions.tsx](examples/edge-actions.tsx) | Actions at the field's end: a mail link with a tooltip beside copying the value, and a profile link on a read-only field — `Input.Action`, `Input.CopyButton`. |
|
|
283
306
|
| [inline-edit.tsx](examples/inline-edit.tsx) | Record card fields that save on blur and Enter, revert on Escape and show the server's refusal — `onCommit`, `error`. |
|
|
307
|
+
| [suggestions.tsx](examples/suggestions.tsx) | Where a returned order is kept: free text with the places already used as suggestions — `suggestions`. |
|
|
308
|
+
| [with-select.tsx](examples/with-select.tsx) | A menu section's icon and name as one field: an icon-only Select is the box's start segment — `Input.Wrapper`, `Select.Root`, `aria-label`. |
|
|
309
|
+
| [time.tsx](examples/time.tsx) | A call slot as a time of day: the browser's hour and minute segments, arrows step them, working hours only — `type`, `step`, `min`, `max`. |
|
|
310
|
+
| [dismiss.tsx](examples/dismiss.tsx) | A delivery city whose suggestions stay open on a press beside the field while the address is copied from a letter; Escape still closes them — `closeOnOutsideClick`, `closeOnEscape`. |
|
|
284
311
|
| [controlled.tsx](examples/controlled.tsx) | The parent owns the value: a clear button and a character counter follow it — `value`, `onValueChange`, `Input.ClearButton`, `Input.Counter`. |
|
|
285
312
|
| [in-form.tsx](examples/in-form.tsx) | Company details form: required fields checked on submit, each error leaves as its field is fixed and a saved form turns the button green; neighbours keep their bottoms aligned — `required`, `error`, `reserveSupportRow`. |
|
|
286
313
|
|
|
@@ -294,8 +321,11 @@ Controlled: `value` + `onChange` (or `onValueChange`) on `Input.Field`. Uncontro
|
|
|
294
321
|
- `tone="danger"` / `error` as a boolean → use `invalid` or an `error` message.
|
|
295
322
|
- A `Button` placed next to the field for «copy» or «call» → `Input.CopyButton` / `Input.Action` inside `Input.Wrapper`.
|
|
296
323
|
- Hand-written blur / Enter / Escape handlers and a `disabled` field while saving → `onCommit` returning the save Promise; the field stays editable.
|
|
324
|
+
- `<datalist>` with `list` on `Input.Field` → `suggestions` on `Input.Root`: the kit's list, keyboard and ARIA in both themes.
|
|
325
|
+
- A Select and an Input side by side for one value (an icon + a name) → the Select inside `Input.Wrapper`, named by its `aria-label`.
|
|
326
|
+
- A text field with a hand-made time mask, or a Datepicker for a time of day → `Input.Field type="time"`.
|
|
297
327
|
- Returning `false` from `onCommit` to refuse → reject the Promise (throw) and set `error`.
|
|
298
328
|
|
|
299
329
|
## Related
|
|
300
|
-
- **Built from:** [Label](../label/COMPONENT.md) (`label`), [Hint](../hint/COMPONENT.md) (`hint`, `error`), [Tooltip](../tooltip/COMPONENT.md) (`Input.Action`, `Input.CopyButton`), [Spinner](../spinner/COMPONENT.md) (`onCommit`), [ProgressBar](../progress-bar/COMPONENT.md) (`strength`), `Icon` (segments), [VisuallyHidden](../visually-hidden/COMPONENT.md)
|
|
330
|
+
- **Built from:** [Label](../label/COMPONENT.md) (`label`), [Hint](../hint/COMPONENT.md) (`hint`, `error`), [Tooltip](../tooltip/COMPONENT.md) (`Input.Action`, `Input.CopyButton`), [Spinner](../spinner/COMPONENT.md) (`onCommit`), [ProgressBar](../progress-bar/COMPONENT.md) (`strength`), `Icon` (segments), [VisuallyHidden](../visually-hidden/COMPONENT.md), [ScrollContainer](../scroll-container/COMPONENT.md) (the `suggestions` list)
|
|
301
331
|
- **See also:** [Textarea](../textarea/COMPONENT.md), [Select](../select/COMPONENT.md), [Datepicker](../datepicker/COMPONENT.md), [TagSelect](../tag-select/COMPONENT.md) — fields with the same contract
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** A fixed prefix and suffix flush with the edges and a unit next to the value — `Input.Affix`, `Input.InlineAffix`. */
|
|
1
|
+
/** A fixed prefix and suffix flush with the edges and a unit next to the value, heard as a word by a screen reader — `Input.Affix`, `Input.InlineAffix`, `aria-label`. */
|
|
2
2
|
import { Input } from "prime-ui-kit";
|
|
3
3
|
|
|
4
4
|
export default function InputAffixesExample() {
|
|
@@ -14,7 +14,9 @@ export default function InputAffixesExample() {
|
|
|
14
14
|
<Input.Root label="Сумма платежа">
|
|
15
15
|
<Input.Wrapper>
|
|
16
16
|
<Input.Field placeholder="0,00" inputMode="decimal" />
|
|
17
|
-
<Input.InlineAffix side="end"
|
|
17
|
+
<Input.InlineAffix side="end" aria-label="рублей">
|
|
18
|
+
₽
|
|
19
|
+
</Input.InlineAffix>
|
|
18
20
|
</Input.Wrapper>
|
|
19
21
|
</Input.Root>
|
|
20
22
|
</>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** A delivery city whose suggestions stay open on a press beside the field while the address is copied from a letter; Escape still closes them — `closeOnOutsideClick`, `closeOnEscape`. */
|
|
2
|
+
import { Input } from "prime-ui-kit";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
|
|
5
|
+
const CITIES = [
|
|
6
|
+
"Москва",
|
|
7
|
+
"Санкт-Петербург",
|
|
8
|
+
"Новосибирск",
|
|
9
|
+
"Екатеринбург",
|
|
10
|
+
"Казань",
|
|
11
|
+
"Нижний Новгород",
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
export default function InputDismissExample() {
|
|
15
|
+
const [city, setCity] = React.useState("");
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<Input.Root
|
|
19
|
+
label="Город доставки"
|
|
20
|
+
suggestions={CITIES}
|
|
21
|
+
closeOnOutsideClick={false}
|
|
22
|
+
closeOnEscape
|
|
23
|
+
>
|
|
24
|
+
<Input.Wrapper>
|
|
25
|
+
<Input.Field value={city} onValueChange={setCity} />
|
|
26
|
+
</Input.Wrapper>
|
|
27
|
+
</Input.Root>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Where a returned order is kept: free text with the places already used as suggestions — `suggestions`. */
|
|
2
|
+
import { Input } from "prime-ui-kit";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
|
|
5
|
+
const PLACES = [
|
|
6
|
+
"Склад на Складочной, стеллаж А",
|
|
7
|
+
"Склад на Складочной, зона возвратов",
|
|
8
|
+
"Пункт выдачи на Лесной",
|
|
9
|
+
"Сервисный центр на Нагатинской",
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
export default function InputSuggestionsExample() {
|
|
13
|
+
const [place, setPlace] = React.useState("");
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<Input.Root
|
|
17
|
+
label="Где хранится возврат"
|
|
18
|
+
hint="Выберите из прошлых мест или впишите новое"
|
|
19
|
+
suggestions={PLACES}
|
|
20
|
+
>
|
|
21
|
+
<Input.Wrapper>
|
|
22
|
+
<Input.Field value={place} onValueChange={setPlace} placeholder="Склад на Складочной" />
|
|
23
|
+
</Input.Wrapper>
|
|
24
|
+
</Input.Root>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** A call slot as a time of day: the browser's hour and minute segments, arrows step them, working hours only — `type`, `step`, `min`, `max`. */
|
|
2
|
+
import { Input } from "prime-ui-kit";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
|
|
5
|
+
const QUARTER_HOUR = 15 * 60;
|
|
6
|
+
|
|
7
|
+
export default function InputTimeExample() {
|
|
8
|
+
const [time, setTime] = React.useState("10:30");
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<Input.Root label="Время звонка" hint="С 09:00 до 18:00, шаг 15 минут">
|
|
12
|
+
<Input.Wrapper>
|
|
13
|
+
<Input.Field
|
|
14
|
+
type="time"
|
|
15
|
+
value={time}
|
|
16
|
+
onValueChange={setTime}
|
|
17
|
+
step={QUARTER_HOUR}
|
|
18
|
+
min="09:00"
|
|
19
|
+
max="18:00"
|
|
20
|
+
/>
|
|
21
|
+
</Input.Wrapper>
|
|
22
|
+
</Input.Root>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** A menu section's icon and name as one field: an icon-only Select is the box's start segment — `Input.Wrapper`, `Select.Root`, `aria-label`. */
|
|
2
|
+
import { Icon, type IconName, Input, Select } from "prime-ui-kit";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
|
|
5
|
+
const ICONS: { value: IconName; label: string }[] = [
|
|
6
|
+
{ value: "object.package", label: "Склад" },
|
|
7
|
+
{ value: "object.truck", label: "Доставка" },
|
|
8
|
+
{ value: "object.receipt", label: "Счета" },
|
|
9
|
+
{ value: "object.users", label: "Клиенты" },
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
export default function InputWithSelectExample() {
|
|
13
|
+
const [icon, setIcon] = React.useState<IconName>("object.truck");
|
|
14
|
+
const [name, setName] = React.useState("Отгрузки");
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<Input.Root label="Раздел в меню" hint="Иконка и название видны в боковой панели">
|
|
18
|
+
<Input.Wrapper>
|
|
19
|
+
<Select.Root
|
|
20
|
+
aria-label="Иконка раздела"
|
|
21
|
+
value={icon}
|
|
22
|
+
onValueChange={(next) => setIcon(next as IconName)}
|
|
23
|
+
>
|
|
24
|
+
<Select.Trigger>
|
|
25
|
+
<Select.TriggerIcon>
|
|
26
|
+
<Icon name={icon} />
|
|
27
|
+
</Select.TriggerIcon>
|
|
28
|
+
</Select.Trigger>
|
|
29
|
+
<Select.Content>
|
|
30
|
+
{ICONS.map((option) => (
|
|
31
|
+
<Select.Item key={option.value} value={option.value}>
|
|
32
|
+
<Select.ItemIcon>
|
|
33
|
+
<Icon name={option.value} />
|
|
34
|
+
</Select.ItemIcon>
|
|
35
|
+
{option.label}
|
|
36
|
+
</Select.Item>
|
|
37
|
+
))}
|
|
38
|
+
</Select.Content>
|
|
39
|
+
</Select.Root>
|
|
40
|
+
<Input.Field value={name} onValueChange={setName} />
|
|
41
|
+
</Input.Wrapper>
|
|
42
|
+
</Input.Root>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
@@ -35,13 +35,13 @@ Kanban.Root board: horizontal strip of columns, its own
|
|
|
35
35
|
└─ <li> column (from `columns`) no well with a header plate (`plain`) or a header line (`line`), or a `fill-muted` well (`well`)
|
|
36
36
|
├─ header title (`columnTitleAs`, h3) · count Badge (the stage color) · renderColumnActions(column) · [grip Dnd.Handle, a lock when `locked`]
|
|
37
37
|
│ ├─ description muted line under the title (`column.description`)
|
|
38
|
-
│ └─ meta the stage's figures (`renderColumnMeta(column)`)
|
|
38
|
+
│ └─ meta the stage's figures (`renderColumnMeta(column)`), a line per array entry
|
|
39
39
|
└─ <ul> (Dnd.Sortable) own vertical scroll; Skeleton cards while loading; EmptyPage (Dnd `empty`) when empty
|
|
40
40
|
└─ Kanban.Item <li> card from renderItem(item); with getItemHref an <a> covers it
|
|
41
41
|
├─ Kanban.ItemHeader optional top row over a faint hairline: key · priority (or a full-width Thumbnail cover)
|
|
42
42
|
├─ Kanban.ItemTitle title, up to three lines
|
|
43
43
|
├─ Kanban.ItemDescription muted meta line: id, due date
|
|
44
|
-
├─ Kanban.ItemBadges wrapping row of Badge
|
|
44
|
+
├─ Kanban.ItemBadges wrapping row of Badge (a Badge.Group)
|
|
45
45
|
└─ Kanban.ItemFooter row: Kanban.ItemCount … at the start, the assignee at the end
|
|
46
46
|
└─ Kanban.ItemCount icon + number
|
|
47
47
|
```
|
|
@@ -72,7 +72,7 @@ Generic `Kanban.Root<T>`; `ref` → `HTMLDivElement`. The board: a strip of colu
|
|
|
72
72
|
| `onItemOpen` | `(item: T, event: KanbanItemOpenEvent) => void` | — | Opens a card in place (a Drawer): a click, Enter or Space; never from a control inside it or after a drag. With `getItemHref` it gets plain clicks: `event.preventDefault()` routes in the app. |
|
|
73
73
|
| `columnTitleAs` | `"h2" \| "h3" \| "h4"` | `"h3"` | Heading level of the column titles in the page outline; the look does not change. |
|
|
74
74
|
| `renderColumnActions` | `(column: KanbanColumn) => ReactNode` | — | Trailing actions of a column header (add a card, a menu); kit controls inside take the `s` tier. |
|
|
75
|
-
| `renderColumnMeta` | `(column: KanbanColumn) => ReactNode` | — | The meta
|
|
75
|
+
| `renderColumnMeta` | `(column: KanbanColumn) => ReactNode \| readonly ReactNode[]` | — | The meta under a column's title and description: the stage's figures («12 сделок · 4,8 млн ₽»); an array is a line per entry, in order. Describes the column's list. |
|
|
76
76
|
| `canDrop` | `(id: string, columnId: string) => boolean \| string` | — | A workflow rule: refuses card `id` in column `columnId` — `false`, or a string that says why (spoken and shown under the carried card). The column turns `danger` before the release. |
|
|
77
77
|
| `variant` | `"plain" \| "line" \| "well"` | `"plain"` | No wells: `plain` — a filled header plate over the cards, `line` — a bare header over a faint line; cards stand on the host. `well`: every column is a filled well holding its cards (bounded queues). |
|
|
78
78
|
| `loading` | `boolean` | `false` | Columns show skeleton cards in the card geometry; the cards cross-fade in when it turns off. |
|
|
@@ -103,7 +103,7 @@ Generic `Kanban.Root<T>`; `ref` → `HTMLDivElement`. The board: a strip of colu
|
|
|
103
103
|
| `…rest` | `HTMLAttributes<HTMLSpanElement>` | — | `children`, `className` and the other span attributes. |
|
|
104
104
|
|
|
105
105
|
### Kanban.ItemBadges
|
|
106
|
-
`ref` → `HTMLDivElement`. A wrapping row of `Badge`s: labels, priority.
|
|
106
|
+
`ref` → `HTMLDivElement`. A wrapping row of `Badge`s (a `Badge.Group`): labels, priority.
|
|
107
107
|
|
|
108
108
|
| Prop | Type | Default | Description |
|
|
109
109
|
|---|---|---|---|
|
|
@@ -138,7 +138,7 @@ Do not wrap a `plain` board's columns in your own boxes, and do not put a `well`
|
|
|
138
138
|
|---|---|---|---|
|
|
139
139
|
| `limit` (column) | count reads `count / limit`, orange when full; a full column refuses cards from others with the reason `labels.full` | a WIP limit per status | — |
|
|
140
140
|
| `description` (column) | a muted caption line under the column title, one line with an ellipsis | the column's rule or meaning («Ответить в течение дня») | — |
|
|
141
|
-
| `renderColumnMeta` |
|
|
141
|
+
| `renderColumnMeta` | caption lines in tabular digits under the description: one, or a line per entry of an array, in order | the stage's figures («2 сделки · 576 000 ₽», «Средний чек 288 000 ₽») | — |
|
|
142
142
|
| `color` (column) | the count Badge in the stage's hue (soft) | telling stages apart, matching their color elsewhere; the title still names the column | — |
|
|
143
143
|
| `locked` (column) | a lock where the grip would be; the column holds its place, no column moves past it | system stages: the first «Новые», the last «Закрыто» | — |
|
|
144
144
|
| `reorderableColumns` | a ghost grip at the end of every column header, after the actions; the column is carried by it | the user arranges the stages | `false` |
|
|
@@ -228,13 +228,13 @@ A card's own `onKeyDown` runs before the board's: `preventDefault()` in it keeps
|
|
|
228
228
|
| [structure.tsx](examples/structure.tsx) | Cards take only the parts they need: a title alone, a meta line, labels, a footer with counts and an assignee — `Kanban.ItemTitle`, `Kanban.ItemDescription`, `Kanban.ItemBadges`, `Kanban.ItemFooter`, `Kanban.ItemCount`. |
|
|
229
229
|
| [cards.tsx](examples/cards.tsx) | Three kinds of cards on one board: a plain note, a ticket with a header row of key and priority, a design task with a cover — `Kanban.ItemHeader`, `Thumbnail`, `Kanban.ItemFooter`. |
|
|
230
230
|
| [limits.tsx](examples/limits.tsx) | A support queue with a work-in-progress limit and a workflow rule, its columns drawn as wells so each reads as a bounded queue: a full column and a blocked ticket are refused before the release with the reason under the card, from the keyboard too — `limit`, `canDrop`, `variant`. |
|
|
231
|
-
| [columns.tsx](examples/columns.tsx) | A sales pipeline whose stages move by the grip in their header while the first and the last stay locked; each stage carries its color on the count, a rule and its figures under the title, and is edited in a popover; the page keeps the order — `reorderableColumns`, `columnOrder`, `onColumnOrderChange`, `locked`, `color`, `description`, `renderColumnMeta`, `renderColumnActions`. |
|
|
231
|
+
| [columns.tsx](examples/columns.tsx) | A sales pipeline whose stages move by the grip in their header while the first and the last stay locked; each stage carries its color on the count, a rule and its figures in two lines under the title, and is edited in a popover; the page keeps the order — `reorderableColumns`, `columnOrder`, `onColumnOrderChange`, `locked`, `color`, `description`, `renderColumnMeta`, `renderColumnActions`. |
|
|
232
232
|
| [saving.tsx](examples/saving.tsx) | Every move is saved on the server: the card waits busy in its new place, and an invoice the server refuses to close glides back to its column — `onValueChange`. |
|
|
233
233
|
| [item-link.tsx](examples/item-link.tsx) | Tickets that open: each card is a link to its page, so ⌘-click or a middle click opens a new tab, a plain click, Enter or Space opens it in place, and a drag only moves it — `getItemHref`, `onItemOpen`. |
|
|
234
234
|
| [states.tsx](examples/states.tsx) | Loading draws skeleton cards in the card geometry; an empty column keeps its drop area and a closed order stays in place while the rest move; a read-only board drags nothing — `loading`, `disabled`. |
|
|
235
235
|
| [controlled.tsx](examples/controlled.tsx) | The placement lives in the parent: every move arrives with its source, target and position to save, and a button resets the board — `value`, `onValueChange`. |
|
|
236
236
|
| [narrow.tsx](examples/narrow.tsx) | On a phone-width screen a column takes 85% of the board and snaps into place, so the next one peeks; the strip scrolls inside the board, never the page — `Kanban.Root`, `columns`. |
|
|
237
|
-
| [screen.tsx](examples/screen.tsx) | A sales pipeline as a work screen: the title with the open deals and their sum, search, filter, the board / list switch and the one primary action in
|
|
237
|
+
| [screen.tsx](examples/screen.tsx) | A sales pipeline as a work screen: the title with the open deals and their sum, search, filter, the board / list switch and the one primary action in its top bar, a full-height Kanban of deals by stage with totals, moves saved on the server that can be refused, and the deal in a Drawer — `value`, `onValueChange`, `renderColumnMeta`, `onItemOpen`. |
|
|
238
238
|
|
|
239
239
|
## Mistakes
|
|
240
240
|
- Returning something other than `Kanban.Item` from `renderItem` → the card does not drag and Alt + arrows do nothing.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** A sales pipeline whose stages move by the grip in their header while the first and the last stay locked; each stage carries its color on the count, a rule and its figures under the title, and is edited in a popover; the page keeps the order — `reorderableColumns`, `columnOrder`, `onColumnOrderChange`, `locked`, `color`, `description`, `renderColumnMeta`, `renderColumnActions`. */
|
|
1
|
+
/** A sales pipeline whose stages move by the grip in their header while the first and the last stay locked; each stage carries its color on the count, a rule and its figures in two lines under the title, and is edited in a popover; the page keeps the order — `reorderableColumns`, `columnOrder`, `onColumnOrderChange`, `locked`, `color`, `description`, `renderColumnMeta`, `renderColumnActions`. */
|
|
2
2
|
import {
|
|
3
3
|
Button,
|
|
4
4
|
ColorSwatches,
|
|
@@ -89,7 +89,9 @@ export default function KanbanColumnsExample() {
|
|
|
89
89
|
DEALS.filter((deal) => deal.id === id),
|
|
90
90
|
);
|
|
91
91
|
const sum = deals.reduce((total, deal) => total + deal.amount, 0);
|
|
92
|
-
|
|
92
|
+
const lines = [`${deals.length} ${dealsWord(deals.length)} · ${RUBLES.format(sum)}`];
|
|
93
|
+
if (deals.length > 0) lines.push(`Средний чек ${RUBLES.format(sum / deals.length)}`);
|
|
94
|
+
return lines;
|
|
93
95
|
};
|
|
94
96
|
|
|
95
97
|
return (
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* Kanban board: a work screen — the header carries the title and the tools, the page fills the app
|
|
2
|
-
panel (`AppShell.Root fillViewport` + `
|
|
2
|
+
panel (`AppShell.Root fillViewport` + `Page.Root fill`) and the board or the list takes
|
|
3
3
|
the free height; every column scrolls inside the board, never the page. */
|
|
4
4
|
|
|
5
5
|
/* Company cell: the name over the deal id (the column's `minWidth` keeps it on its lines). */
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
/** A sales pipeline as a work screen: the title with the open deals and their sum, search, filter, the board / list switch and the one primary action in
|
|
1
|
+
/** A sales pipeline as a work screen: the title with the open deals and their sum, search, filter, the board / list switch and the one primary action in its top bar, a full-height Kanban of deals by stage with totals, moves saved on the server that can be refused, and the deal in a Drawer — `value`, `onValueChange`, `renderColumnMeta`, `onItemOpen`. */
|
|
2
2
|
import {
|
|
3
|
-
AppHeader,
|
|
4
3
|
Avatar,
|
|
5
4
|
Badge,
|
|
6
5
|
Button,
|
|
@@ -16,8 +15,7 @@ import {
|
|
|
16
15
|
type KanbanColumn,
|
|
17
16
|
type KanbanValue,
|
|
18
17
|
matchesSmartFilter,
|
|
19
|
-
|
|
20
|
-
PageToolbar,
|
|
18
|
+
Page,
|
|
21
19
|
type PaletteColor,
|
|
22
20
|
SegmentedControl,
|
|
23
21
|
SmartFilter,
|
|
@@ -359,64 +357,51 @@ export default function KanbanScreenExample() {
|
|
|
359
357
|
const nextStage = STAGES[STAGES.findIndex((stage) => stage.id === dealStage) + 1];
|
|
360
358
|
|
|
361
359
|
return (
|
|
362
|
-
|
|
363
|
-
{
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
</
|
|
386
|
-
<
|
|
387
|
-
<SegmentedControl.
|
|
388
|
-
<
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
Новая сделка
|
|
408
|
-
</Button.Root>
|
|
409
|
-
</PageToolbar.Actions>
|
|
410
|
-
<PageToolbar.Chips>
|
|
411
|
-
<SmartFilter.Chips />
|
|
412
|
-
</PageToolbar.Chips>
|
|
413
|
-
</PageToolbar.Root>
|
|
414
|
-
</SmartFilter.Root>
|
|
415
|
-
</AppHeader.Tools>
|
|
416
|
-
</AppHeader.Root>
|
|
417
|
-
|
|
418
|
-
<PageContent.Root fill>
|
|
419
|
-
<PageContent.Body>
|
|
360
|
+
<SmartFilter.Root
|
|
361
|
+
fields={FIELDS}
|
|
362
|
+
value={filter}
|
|
363
|
+
onValueChange={setFilter}
|
|
364
|
+
search={search}
|
|
365
|
+
onSearchChange={setSearch}
|
|
366
|
+
>
|
|
367
|
+
<Page.Root fill>
|
|
368
|
+
{/* A work screen titles itself in its top bar: the only h1, the search and the filters, the
|
|
369
|
+
view, the one primary action. */}
|
|
370
|
+
<Page.TopBar>
|
|
371
|
+
<Page.Heading>
|
|
372
|
+
<Page.Title>Сделки</Page.Title>
|
|
373
|
+
<Page.Description>{loading ? "Загружаем воронку…" : pipeline}</Page.Description>
|
|
374
|
+
</Page.Heading>
|
|
375
|
+
<Page.Tools aria-label="Сделки">
|
|
376
|
+
<SmartFilter.Toolbar />
|
|
377
|
+
<SegmentedControl.Root value={view} onValueChange={setView} aria-label="Вид">
|
|
378
|
+
<SegmentedControl.Item value="board">
|
|
379
|
+
<SegmentedControl.Icon>
|
|
380
|
+
<Icon name="view.columns" />
|
|
381
|
+
</SegmentedControl.Icon>
|
|
382
|
+
Доска
|
|
383
|
+
</SegmentedControl.Item>
|
|
384
|
+
<SegmentedControl.Item value="list">
|
|
385
|
+
<SegmentedControl.Icon>
|
|
386
|
+
<Icon name="format.list" />
|
|
387
|
+
</SegmentedControl.Icon>
|
|
388
|
+
Список
|
|
389
|
+
</SegmentedControl.Item>
|
|
390
|
+
</SegmentedControl.Root>
|
|
391
|
+
</Page.Tools>
|
|
392
|
+
<Page.Actions>
|
|
393
|
+
<Button.Root>
|
|
394
|
+
<Button.Icon>
|
|
395
|
+
<Icon name="action.add" />
|
|
396
|
+
</Button.Icon>
|
|
397
|
+
Новая сделка
|
|
398
|
+
</Button.Root>
|
|
399
|
+
</Page.Actions>
|
|
400
|
+
<Page.Chips>
|
|
401
|
+
<SmartFilter.Chips />
|
|
402
|
+
</Page.Chips>
|
|
403
|
+
</Page.TopBar>
|
|
404
|
+
<Page.Body>
|
|
420
405
|
<Crossfade state={view} fill>
|
|
421
406
|
{view === "board" ? (
|
|
422
407
|
// `plain` (the default): the board is the page's main region, so the stages are no
|
|
@@ -567,8 +552,8 @@ export default function KanbanScreenExample() {
|
|
|
567
552
|
</Drawer.Footer>
|
|
568
553
|
</Drawer.Content>
|
|
569
554
|
</Drawer.Root>
|
|
570
|
-
</
|
|
571
|
-
</
|
|
572
|
-
|
|
555
|
+
</Page.Body>
|
|
556
|
+
</Page.Root>
|
|
557
|
+
</SmartFilter.Root>
|
|
573
558
|
);
|
|
574
559
|
}
|
|
@@ -39,7 +39,7 @@ Kbd <kbd>; one key, its badge tier, children (text, Icon or both)
|
|
|
39
39
|
| `…rest` | `Omit<HTMLAttributes<HTMLElement>, "size">` | — | `className`, `title`, `aria-label` and the other `<kbd>` attributes. |
|
|
40
40
|
|
|
41
41
|
## Variants
|
|
42
|
-
Kbd has one look: monospace text in `text-secondary` on a translucent `fill-subtle-active` wash, no border, weight 500. No `variant`, `tone` or `color`.
|
|
42
|
+
Kbd has one look: monospace text (`--prime-font-family-key`: the mono faces, with ⇧ ⌥ ⌃ ⌘ from the system face so they match the letters) in `text-secondary` on a translucent `fill-subtle-active` wash, no border, weight 500. No `variant`, `tone` or `color`.
|
|
43
43
|
|
|
44
44
|
### size
|
|
45
45
|
| Value | Looks like | Use when | Default |
|