prime-ui-kit 0.13.1 → 0.15.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 +20 -20
- package/dist/chunks/{chunk-XNOJEX55.js → chunk-2IKH55MI.js} +1 -1
- package/dist/chunks/{chunk-JV2KB5JZ.js → chunk-THFZIHKU.js} +3761 -3041
- package/dist/chunks/{chunk-PK2GC77E.js → chunk-XJAVS6FH.js} +213 -188
- package/dist/color-picker.js +2 -2
- package/dist/components/banner/Banner.d.ts +5 -2
- package/dist/components/chart-frame/ChartFrame.d.ts +19 -6
- package/dist/components/chat/Chat.d.ts +2 -2
- package/dist/components/chat/ChatPinned.d.ts +2 -2
- package/dist/components/chat/MessageList.d.ts +1 -1
- package/dist/components/chat/chatContext.d.ts +1 -1
- package/dist/components/dnd/Dnd.d.ts +1 -1
- package/dist/components/field-list/FieldList.d.ts +90 -0
- package/dist/components/index.d.ts +3 -1
- package/dist/components/input/Input.d.ts +2 -2
- package/dist/components/kanban/Kanban.d.ts +6 -3
- package/dist/components/login-form/LoginForm.d.ts +5 -1
- package/dist/components/page-content/PageContent.d.ts +55 -4
- package/dist/components/sparkline/Sparkline.d.ts +64 -15
- package/dist/components/sparkline/geometry.d.ts +26 -0
- package/dist/components/tooltip/Tooltip.d.ts +5 -2
- package/dist/hooks/usePosition.d.ts +15 -4
- package/dist/index.css +1 -1
- package/dist/index.js +4 -2
- package/dist/internal/ChartTooltip.d.ts +26 -0
- package/dist/internal/FieldAction.d.ts +6 -7
- package/dist/internal/fieldCell.d.ts +21 -0
- package/dist/internal/messageList.d.ts +2 -2
- package/dist/internal/palette.d.ts +7 -0
- package/dist/internal/swatch.d.ts +6 -2
- package/dist/layout/app-header/AppHeader.d.ts +9 -28
- package/dist/layout/index.d.ts +1 -1
- package/dist/skill/SKILL.md +32 -20
- package/dist/skill/anti-slop.md +77 -4
- package/dist/skill/api-contract.md +2 -2
- package/dist/skill/cheatsheet.md +33 -7
- package/dist/skill/checklist.md +28 -6
- package/dist/skill/choosing.md +17 -14
- package/dist/skill/components.md +9 -15
- package/dist/skill/composition.md +301 -61
- package/dist/skill/foundations.md +9 -7
- package/dist/skill/layouts.md +70 -37
- package/dist/skill/reference/components/avatar/COMPONENT.md +4 -4
- package/dist/skill/reference/components/avatar/examples/presence.tsx +1 -1
- package/dist/skill/reference/components/avatar/examples/states.tsx +5 -5
- package/dist/skill/reference/components/badge/examples/applied-filters.tsx +13 -19
- package/dist/skill/reference/components/badge/examples/examples.module.css +1 -8
- package/dist/skill/reference/components/badge/examples/server-tags.tsx +2 -6
- package/dist/skill/reference/components/banner/COMPONENT.md +6 -6
- package/dist/skill/reference/components/banner/examples/dismissible.tsx +22 -11
- package/dist/skill/reference/components/banner/examples/examples.module.css +4 -8
- package/dist/skill/reference/components/banner/examples/narrow.tsx +1 -1
- package/dist/skill/reference/components/banner/examples/page-strip.tsx +16 -22
- package/dist/skill/reference/components/breadcrumb/COMPONENT.md +5 -4
- package/dist/skill/reference/components/breadcrumb/examples/ellipsis.tsx +2 -2
- package/dist/skill/reference/components/breadcrumb/examples/overflow.tsx +1 -1
- package/dist/skill/reference/components/button-group/COMPONENT.md +2 -2
- package/dist/skill/reference/components/button-group/examples/in-form.tsx +22 -2
- package/dist/skill/reference/components/button-group/examples/states.tsx +10 -1
- package/dist/skill/reference/components/card/COMPONENT.md +7 -5
- package/dist/skill/reference/components/card/examples/examples.module.css +0 -28
- package/dist/skill/reference/components/card/examples/kpi-media.tsx +13 -11
- package/dist/skill/reference/components/card/examples/narrow.tsx +1 -1
- package/dist/skill/reference/components/card/examples/panel-chart.tsx +45 -22
- package/dist/skill/reference/components/card/examples/screen.module.css +14 -0
- package/dist/skill/reference/components/card/examples/screen.tsx +362 -0
- package/dist/skill/reference/components/card/examples/variants.tsx +15 -1
- package/dist/skill/reference/components/chart-frame/COMPONENT.md +12 -8
- package/dist/skill/reference/components/chart-frame/examples/fill-height.tsx +119 -0
- package/dist/skill/reference/components/chart-frame/examples/states.tsx +3 -1
- package/dist/skill/reference/components/chart-frame/examples/tooltip.tsx +20 -24
- package/dist/skill/reference/components/chat/COMPONENT.md +6 -4
- package/dist/skill/reference/components/chat/examples/group-chat.tsx +15 -2
- package/dist/skill/reference/components/chat/examples/reactions.tsx +121 -0
- package/dist/skill/reference/components/chat/examples/screen.module.css +9 -0
- package/dist/skill/{patterns/chat.tsx → reference/components/chat/examples/screen.tsx} +187 -350
- package/dist/skill/reference/components/chat/examples/search.tsx +1 -1
- package/dist/skill/reference/components/chat-list/COMPONENT.md +2 -1
- package/dist/skill/reference/components/chat-list/examples/links.tsx +72 -0
- package/dist/skill/reference/components/checkbox/COMPONENT.md +1 -1
- package/dist/skill/reference/components/checkbox/examples/examples.module.css +5 -1
- package/dist/skill/reference/components/checkbox/examples/indicator.tsx +37 -9
- package/dist/skill/reference/components/checkbox/examples/states.tsx +6 -1
- package/dist/skill/reference/components/color-field/COMPONENT.md +1 -1
- package/dist/skill/reference/components/color-picker/COMPONENT.md +6 -5
- package/dist/skill/reference/components/color-picker/examples/controlled-open.tsx +37 -0
- package/dist/skill/reference/components/color-picker/examples/presets.tsx +2 -2
- package/dist/skill/reference/components/color-picker/examples/states.tsx +23 -14
- package/dist/skill/reference/components/color-swatches/COMPONENT.md +1 -0
- package/dist/skill/reference/components/composer/COMPONENT.md +2 -1
- package/dist/skill/reference/components/composer/examples/attach-menu.tsx +78 -0
- package/dist/skill/reference/components/composer/examples/attachments.tsx +2 -2
- package/dist/skill/reference/components/crossfade/COMPONENT.md +1 -0
- package/dist/skill/{patterns/screen-states.module.css → reference/components/crossfade/examples/screen.module.css} +3 -17
- package/dist/skill/reference/components/crossfade/examples/screen.tsx +197 -0
- package/dist/skill/reference/components/data-table/COMPONENT.md +3 -2
- package/dist/skill/reference/components/data-table/examples/detail-panel.tsx +36 -37
- package/dist/skill/reference/components/data-table/examples/examples.module.css +0 -12
- package/dist/skill/reference/components/data-table/examples/numeric.tsx +36 -4
- package/dist/skill/reference/components/data-table/examples/overview.tsx +1 -0
- package/dist/skill/reference/components/data-table/examples/row-open.tsx +7 -36
- package/dist/skill/{patterns/list-page.module.css → reference/components/data-table/examples/screen.module.css} +1 -7
- package/dist/skill/{patterns/list-page.tsx → reference/components/data-table/examples/screen.tsx} +84 -64
- package/dist/skill/reference/components/datepicker/COMPONENT.md +6 -4
- package/dist/skill/reference/components/datepicker/examples/examples.module.css +2 -6
- package/dist/skill/reference/components/datepicker/examples/in-form.tsx +47 -55
- package/dist/skill/reference/components/datepicker/examples/locale.tsx +35 -0
- package/dist/skill/reference/components/datepicker/examples/range-presets.tsx +11 -2
- package/dist/skill/reference/components/datepicker/examples/states.tsx +9 -1
- package/dist/skill/reference/components/description-list/COMPONENT.md +1 -0
- package/dist/skill/{patterns/detail-page.module.css → reference/components/description-list/examples/screen.module.css} +2 -12
- package/dist/skill/reference/components/description-list/examples/screen.tsx +214 -0
- package/dist/skill/reference/components/description-list/examples/structure.tsx +1 -1
- package/dist/skill/reference/components/digit-input/COMPONENT.md +3 -1
- package/dist/skill/reference/components/digit-input/examples/states.tsx +3 -1
- package/dist/skill/reference/components/digit-input/examples/without-focus-ring.tsx +13 -0
- package/dist/skill/reference/components/divider/examples/with-icon.tsx +2 -2
- package/dist/skill/reference/components/dnd/COMPONENT.md +7 -5
- package/dist/skill/reference/components/dnd/examples/drop-zones.tsx +82 -49
- package/dist/skill/reference/components/dnd/examples/examples.module.css +50 -0
- package/dist/skill/reference/components/dnd/examples/states.tsx +54 -0
- package/dist/skill/reference/components/dnd/examples/table.tsx +113 -0
- package/dist/skill/reference/components/drawer/COMPONENT.md +1 -0
- package/dist/skill/reference/components/drawer/examples/dismiss.tsx +5 -3
- package/dist/skill/reference/components/drawer/examples/examples.module.css +0 -13
- package/dist/skill/reference/components/drawer/examples/header-actions.tsx +5 -9
- package/dist/skill/reference/components/drawer/examples/overview.tsx +6 -18
- package/dist/skill/reference/components/drawer/examples/screen.tsx +298 -0
- package/dist/skill/reference/components/dropdown/examples/examples.module.css +1 -5
- package/dist/skill/reference/components/empty-page/COMPONENT.md +1 -1
- package/dist/skill/reference/components/empty-page/examples/region-error.tsx +8 -2
- package/dist/skill/reference/components/example-frame/COMPONENT.md +3 -2
- package/dist/skill/reference/components/example-frame/examples/initial-view.tsx +44 -0
- package/dist/skill/reference/components/field-list/COMPONENT.md +165 -0
- package/dist/skill/reference/components/field-list/examples/base-row.tsx +76 -0
- package/dist/skill/reference/components/field-list/examples/controlled.tsx +72 -0
- package/dist/skill/reference/components/field-list/examples/errors.tsx +88 -0
- package/dist/skill/reference/components/field-list/examples/examples.module.css +34 -0
- package/dist/skill/reference/components/field-list/examples/limits.tsx +55 -0
- package/dist/skill/reference/components/field-list/examples/locked.tsx +139 -0
- package/dist/skill/reference/components/field-list/examples/narrow.tsx +68 -0
- package/dist/skill/reference/components/field-list/examples/overview.tsx +66 -0
- package/dist/skill/reference/components/field-list/examples/reorder.tsx +42 -0
- package/dist/skill/reference/components/field-list/examples/screen.module.css +18 -0
- package/dist/skill/reference/components/field-list/examples/screen.tsx +316 -0
- package/dist/skill/reference/components/field-list/examples/sizes.tsx +42 -0
- package/dist/skill/reference/components/field-list/examples/states.tsx +51 -0
- package/dist/skill/reference/components/file-upload/COMPONENT.md +7 -6
- package/dist/skill/reference/components/file-upload/examples/custom-body.tsx +2 -1
- package/dist/skill/reference/components/file-upload/examples/examples.module.css +1 -7
- package/dist/skill/reference/components/file-upload/examples/file-cards.tsx +10 -1
- package/dist/skill/reference/components/file-upload/examples/gallery.tsx +2 -2
- package/dist/skill/reference/components/file-upload/examples/in-form.tsx +4 -9
- package/dist/skill/reference/components/file-upload/examples/overview.tsx +5 -1
- package/dist/skill/reference/components/file-upload/examples/row-parts.tsx +24 -1
- package/dist/skill/{patterns/media-library.module.css → reference/components/file-upload/examples/screen.module.css} +2 -23
- package/dist/skill/reference/components/file-upload/examples/screen.tsx +646 -0
- package/dist/skill/reference/components/file-upload/examples/states.tsx +6 -2
- package/dist/skill/reference/components/file-upload/examples/validation.tsx +11 -2
- package/dist/skill/reference/components/file-upload/examples/variants.tsx +3 -20
- package/dist/skill/reference/components/gantt/COMPONENT.md +2 -1
- package/dist/skill/reference/components/gantt/examples/screen.module.css +14 -0
- package/dist/skill/{patterns/schedule.tsx → reference/components/gantt/examples/screen.tsx} +174 -170
- package/dist/skill/reference/components/gantt/examples/states.tsx +6 -2
- package/dist/skill/reference/components/input/COMPONENT.md +2 -2
- package/dist/skill/reference/components/input/examples/examples.module.css +2 -13
- package/dist/skill/reference/components/input/examples/in-form.tsx +1 -9
- package/dist/skill/reference/components/input/examples/password-strength.tsx +34 -8
- package/dist/skill/reference/components/input/examples/states.tsx +6 -1
- package/dist/skill/reference/components/kanban/COMPONENT.md +16 -11
- package/dist/skill/reference/components/kanban/examples/columns.tsx +8 -5
- package/dist/skill/reference/components/kanban/examples/limits.tsx +2 -1
- package/dist/skill/reference/components/kanban/examples/screen.module.css +17 -0
- package/dist/skill/{patterns/kanban-board.tsx → reference/components/kanban/examples/screen.tsx} +132 -172
- package/dist/skill/reference/components/kanban/examples/states.tsx +17 -6
- package/dist/skill/reference/components/kanban/examples/variants.tsx +16 -8
- package/dist/skill/reference/components/list/COMPONENT.md +1 -1
- package/dist/skill/reference/components/login-form/COMPONENT.md +6 -5
- package/dist/skill/reference/components/login-form/examples/examples.module.css +2 -21
- package/dist/skill/reference/components/login-form/examples/forgot-password.tsx +28 -32
- package/dist/skill/reference/components/login-form/examples/narrow.tsx +1 -1
- package/dist/skill/reference/components/login-form/examples/overview.tsx +45 -47
- package/dist/skill/reference/components/login-form/examples/register.tsx +64 -68
- package/dist/skill/reference/components/login-form/examples/reset-password.tsx +50 -47
- package/dist/skill/reference/components/login-form/examples/sizes.tsx +4 -6
- package/dist/skill/reference/components/login-form/examples/states.tsx +53 -57
- package/dist/skill/reference/components/login-form/examples/structure.tsx +18 -22
- package/dist/skill/reference/components/login-form/examples/verification-code.tsx +41 -45
- package/dist/skill/reference/components/media-viewer/COMPONENT.md +3 -3
- package/dist/skill/reference/components/media-viewer/examples/dismiss.tsx +5 -1
- package/dist/skill/reference/components/message/COMPONENT.md +6 -5
- package/dist/skill/reference/components/message/examples/file.tsx +5 -1
- package/dist/skill/reference/components/message/examples/media-open.tsx +48 -0
- package/dist/skill/reference/components/message/examples/status.tsx +21 -3
- package/dist/skill/reference/components/message/examples/text-formatting.tsx +7 -1
- package/dist/skill/reference/components/modal/COMPONENT.md +2 -1
- package/dist/skill/reference/components/modal/examples/custom-container.tsx +20 -20
- package/dist/skill/reference/components/modal/examples/dismiss.tsx +5 -3
- package/dist/skill/reference/components/modal/examples/enter-key.tsx +116 -0
- package/dist/skill/reference/components/modal/examples/examples.module.css +7 -13
- package/dist/skill/reference/components/modal/examples/structure.tsx +5 -2
- package/dist/skill/reference/components/native-select/COMPONENT.md +1 -1
- package/dist/skill/reference/components/native-select/examples/states.tsx +5 -1
- package/dist/skill/reference/components/notification/COMPONENT.md +2 -1
- package/dist/skill/reference/components/notification/examples/dismiss.tsx +2 -2
- package/dist/skill/reference/components/page-content/COMPONENT.md +71 -14
- package/dist/skill/reference/components/page-content/examples/grid.tsx +107 -0
- package/dist/skill/reference/components/page-content/examples/list-detail.tsx +0 -3
- package/dist/skill/reference/components/page-content/examples/overview.tsx +2 -2
- package/dist/skill/{patterns/settings-page.module.css → reference/components/page-content/examples/screen.module.css} +1 -21
- package/dist/skill/{patterns/settings-page.tsx → reference/components/page-content/examples/screen.tsx} +61 -82
- package/dist/skill/reference/components/page-content/examples/sections.tsx +81 -0
- package/dist/skill/reference/components/page-content/examples/variants.tsx +4 -11
- package/dist/skill/reference/components/page-toolbar/COMPONENT.md +18 -16
- package/dist/skill/reference/components/page-toolbar/examples/narrow.tsx +6 -3
- package/dist/skill/reference/components/pagination/examples/controlled.tsx +29 -29
- package/dist/skill/reference/components/pagination/examples/examples.module.css +0 -2
- package/dist/skill/reference/components/progress-bar/COMPONENT.md +1 -1
- package/dist/skill/reference/components/progress-bar/examples/segments.tsx +2 -2
- package/dist/skill/reference/components/progress-circle/COMPONENT.md +1 -1
- package/dist/skill/reference/components/progress-circle/examples/segments.tsx +8 -3
- package/dist/skill/reference/components/radio/COMPONENT.md +1 -0
- package/dist/skill/reference/components/radio/examples/examples.module.css +14 -0
- package/dist/skill/reference/components/radio/examples/in-form.tsx +45 -0
- package/dist/skill/reference/components/scroll-container/COMPONENT.md +1 -0
- package/dist/skill/reference/components/scroll-container/examples/auto-scroll.tsx +3 -3
- package/dist/skill/reference/components/scroll-container/examples/chat.tsx +3 -3
- package/dist/skill/reference/components/scroll-container/examples/edges.tsx +6 -3
- package/dist/skill/reference/components/scroll-container/examples/examples.module.css +4 -17
- package/dist/skill/reference/components/scroll-container/examples/load-more.tsx +51 -0
- package/dist/skill/reference/components/scroll-container/examples/lock.tsx +3 -5
- package/dist/skill/reference/components/scroll-container/examples/overscroll.tsx +3 -3
- package/dist/skill/reference/components/scroll-container/examples/overview.tsx +3 -3
- package/dist/skill/reference/components/scroll-container/examples/scrollbar.tsx +13 -7
- package/dist/skill/reference/components/scroll-container/examples/variants.tsx +13 -7
- package/dist/skill/reference/components/segmented-control/COMPONENT.md +3 -2
- package/dist/skill/reference/components/segmented-control/examples/in-form.tsx +5 -1
- package/dist/skill/reference/components/segmented-control/examples/states.tsx +10 -1
- package/dist/skill/reference/components/select/COMPONENT.md +5 -3
- package/dist/skill/reference/components/select/examples/examples.module.css +2 -7
- package/dist/skill/reference/components/select/examples/icon-only.tsx +38 -0
- package/dist/skill/reference/components/select/examples/states.tsx +13 -1
- package/dist/skill/reference/components/sheet/COMPONENT.md +2 -0
- package/dist/skill/reference/components/sheet/examples/guard.tsx +72 -0
- package/dist/skill/reference/components/sheet/examples/header-actions.tsx +56 -0
- package/dist/skill/reference/components/slider/COMPONENT.md +2 -1
- package/dist/skill/reference/components/slider/examples/examples.module.css +8 -0
- package/dist/skill/reference/components/slider/examples/in-form.tsx +47 -0
- package/dist/skill/reference/components/slider/examples/states.tsx +4 -1
- package/dist/skill/reference/components/smart-filter/COMPONENT.md +1 -1
- package/dist/skill/reference/components/smart-filter/examples/controlled.tsx +3 -3
- package/dist/skill/reference/components/smart-filter/examples/ranges.tsx +44 -10
- package/dist/skill/reference/components/sparkline/COMPONENT.md +83 -30
- package/dist/skill/reference/components/sparkline/examples/compact.tsx +1 -1
- package/dist/skill/reference/components/sparkline/examples/curve.tsx +28 -0
- package/dist/skill/reference/components/sparkline/examples/gaps.tsx +33 -0
- package/dist/skill/reference/components/sparkline/examples/overview.tsx +11 -2
- package/dist/skill/reference/components/sparkline/examples/period.tsx +7 -2
- package/dist/skill/reference/components/sparkline/examples/reference.tsx +38 -0
- package/dist/skill/reference/components/sparkline/examples/variants.tsx +2 -2
- package/dist/skill/reference/components/tabs/COMPONENT.md +1 -1
- package/dist/skill/reference/components/tabs/examples/examples.module.css +0 -6
- package/dist/skill/reference/components/tabs/examples/in-drawer.tsx +11 -13
- package/dist/skill/reference/components/tabs/examples/sizes.tsx +1 -1
- package/dist/skill/reference/components/tag-select/COMPONENT.md +1 -1
- package/dist/skill/reference/components/tag-select/examples/states.tsx +8 -1
- package/dist/skill/reference/components/textarea/COMPONENT.md +1 -1
- package/dist/skill/reference/components/textarea/examples/examples.module.css +0 -6
- package/dist/skill/reference/components/textarea/examples/in-form.tsx +1 -9
- package/dist/skill/reference/components/textarea/examples/states.tsx +2 -1
- package/dist/skill/reference/components/thumbnail/COMPONENT.md +2 -1
- package/dist/skill/reference/components/thumbnail/examples/examples.module.css +1 -1
- package/dist/skill/reference/components/thumbnail/examples/fit.tsx +24 -0
- package/dist/skill/reference/components/thumbnail/examples/video.tsx +20 -1
- package/dist/skill/reference/components/timeline/COMPONENT.md +1 -1
- package/dist/skill/reference/components/timeline/examples/examples.module.css +0 -8
- package/dist/skill/reference/components/timeline/examples/links.tsx +55 -14
- package/dist/skill/reference/components/timeline/examples/narrow.tsx +2 -2
- package/dist/skill/reference/components/timeline/examples/sizes.tsx +3 -3
- package/dist/skill/reference/components/timeline/examples/variants.tsx +4 -4
- package/dist/skill/reference/components/tooltip/COMPONENT.md +7 -5
- package/dist/skill/reference/components/tooltip/examples/placement.tsx +2 -1
- package/dist/skill/reference/components/tooltip/examples/toolbar.tsx +2 -2
- package/dist/skill/reference/components/typography/examples/weights.tsx +3 -0
- package/dist/skill/reference/components/video-note/COMPONENT.md +3 -3
- package/dist/skill/reference/components/video-note/examples/controlled.tsx +19 -2
- package/dist/skill/reference/components/video-note/examples/in-message.tsx +5 -2
- package/dist/skill/reference/components/visually-hidden/COMPONENT.md +2 -1
- package/dist/skill/reference/components/visually-hidden/examples/assertive.tsx +39 -0
- package/dist/skill/reference/components/voice-player/COMPONENT.md +3 -3
- package/dist/skill/reference/components/voice-player/examples/call-recording.tsx +19 -9
- package/dist/skill/reference/components/voice-player/examples/controlled.tsx +20 -3
- package/dist/skill/reference/layout/app-header/COMPONENT.md +46 -63
- package/dist/skill/reference/layout/app-header/examples/breadcrumbs.tsx +10 -9
- package/dist/skill/reference/layout/app-header/examples/examples.module.css +1 -1
- package/dist/skill/reference/layout/app-header/examples/in-app-shell.tsx +2 -3
- package/dist/skill/reference/layout/app-header/examples/narrow.tsx +4 -5
- package/dist/skill/reference/layout/app-header/examples/overview.tsx +8 -10
- package/dist/skill/reference/layout/app-header/examples/page-title.tsx +3 -10
- package/dist/skill/reference/layout/app-shell/COMPONENT.md +5 -4
- package/dist/skill/reference/layout/app-shell/examples/footer.tsx +2 -2
- package/dist/skill/reference/layout/app-shell/examples/overview.tsx +17 -32
- package/dist/skill/{patterns/app-shell.module.css → reference/layout/app-shell/examples/screen.module.css} +1 -8
- package/dist/skill/reference/layout/app-shell/examples/screen.tsx +262 -0
- package/dist/skill/reference/layout/app-shell/examples/template.tsx +31 -11
- package/dist/skill/reference/layout/bottom-nav/examples/floating-action.tsx +2 -2
- package/dist/skill/reference/layout/bottom-nav/examples/floating.tsx +2 -2
- package/dist/skill/reference/layout/bottom-nav/examples/in-app-shell.tsx +2 -2
- package/dist/skill/reference/layout/sidebar/COMPONENT.md +7 -4
- package/dist/skill/reference/layout/sidebar/examples/account.tsx +2 -2
- package/dist/skill/reference/layout/sidebar/examples/collapsible-groups.tsx +12 -4
- package/dist/skill/reference/layout/sidebar/examples/custom-part.tsx +53 -0
- package/dist/skill/reference/layout/sidebar/examples/examples.module.css +5 -0
- package/dist/skill/reference/layout/sidebar/examples/narrow.tsx +53 -0
- package/dist/skill/reference/layout/sidebar/examples/persist.tsx +57 -0
- package/dist/skill/reference/layout/sidebar/examples/router.tsx +14 -2
- package/dist/skill/reference/layout/sidebar/examples/structure.tsx +7 -2
- package/dist/skill/responsive.md +7 -5
- package/dist/skill/ux.md +145 -0
- package/dist/tokens/semantic.d.ts +2 -0
- package/package.json +1 -1
- package/src/components/avatar/COMPONENT.md +4 -4
- package/src/components/avatar/examples/presence.tsx +1 -1
- package/src/components/avatar/examples/states.tsx +5 -5
- package/src/components/badge/examples/applied-filters.tsx +13 -19
- package/src/components/badge/examples/examples.module.css +1 -8
- package/src/components/badge/examples/server-tags.tsx +2 -6
- package/src/components/banner/COMPONENT.md +6 -6
- package/src/components/banner/examples/dismissible.tsx +22 -11
- package/src/components/banner/examples/examples.module.css +4 -8
- package/src/components/banner/examples/narrow.tsx +1 -1
- package/src/components/banner/examples/page-strip.tsx +16 -22
- package/src/components/breadcrumb/COMPONENT.md +5 -4
- package/src/components/breadcrumb/examples/ellipsis.tsx +2 -2
- package/src/components/breadcrumb/examples/overflow.tsx +1 -1
- package/src/components/button-group/COMPONENT.md +2 -2
- package/src/components/button-group/examples/in-form.tsx +22 -2
- package/src/components/button-group/examples/states.tsx +10 -1
- package/src/components/card/COMPONENT.md +7 -5
- package/src/components/card/examples/examples.module.css +0 -28
- package/src/components/card/examples/kpi-media.tsx +13 -11
- package/src/components/card/examples/narrow.tsx +1 -1
- package/src/components/card/examples/panel-chart.tsx +45 -22
- package/src/components/card/examples/screen.module.css +14 -0
- package/src/components/card/examples/screen.tsx +362 -0
- package/src/components/card/examples/variants.tsx +15 -1
- package/src/components/chart-frame/COMPONENT.md +12 -8
- package/src/components/chart-frame/examples/fill-height.tsx +119 -0
- package/src/components/chart-frame/examples/states.tsx +3 -1
- package/src/components/chart-frame/examples/tooltip.tsx +20 -24
- package/src/components/chat/COMPONENT.md +6 -4
- package/src/components/chat/examples/group-chat.tsx +15 -2
- package/src/components/chat/examples/reactions.tsx +121 -0
- package/src/components/chat/examples/screen.module.css +9 -0
- package/src/components/chat/examples/screen.tsx +718 -0
- package/src/components/chat/examples/search.tsx +1 -1
- package/src/components/chat-list/COMPONENT.md +2 -1
- package/src/components/chat-list/examples/links.tsx +72 -0
- package/src/components/checkbox/COMPONENT.md +1 -1
- package/src/components/checkbox/examples/examples.module.css +5 -1
- package/src/components/checkbox/examples/indicator.tsx +37 -9
- package/src/components/checkbox/examples/states.tsx +6 -1
- package/src/components/color-field/COMPONENT.md +1 -1
- package/src/components/color-picker/COMPONENT.md +6 -5
- package/src/components/color-picker/examples/controlled-open.tsx +37 -0
- package/src/components/color-picker/examples/presets.tsx +2 -2
- package/src/components/color-picker/examples/states.tsx +23 -14
- package/src/components/color-swatches/COMPONENT.md +1 -0
- package/src/components/composer/COMPONENT.md +2 -1
- package/src/components/composer/examples/attach-menu.tsx +78 -0
- package/src/components/composer/examples/attachments.tsx +2 -2
- package/src/components/crossfade/COMPONENT.md +1 -0
- package/src/components/crossfade/examples/screen.module.css +40 -0
- package/src/components/crossfade/examples/screen.tsx +197 -0
- package/src/components/data-table/COMPONENT.md +3 -2
- package/src/components/data-table/examples/detail-panel.tsx +36 -37
- package/src/components/data-table/examples/examples.module.css +0 -12
- package/src/components/data-table/examples/numeric.tsx +36 -4
- package/src/components/data-table/examples/overview.tsx +1 -0
- package/src/components/data-table/examples/row-open.tsx +7 -36
- package/src/components/data-table/examples/screen.module.css +13 -0
- package/src/components/data-table/examples/screen.tsx +354 -0
- package/src/components/datepicker/COMPONENT.md +6 -4
- package/src/components/datepicker/examples/examples.module.css +2 -6
- package/src/components/datepicker/examples/in-form.tsx +47 -55
- package/src/components/datepicker/examples/locale.tsx +35 -0
- package/src/components/datepicker/examples/range-presets.tsx +11 -2
- package/src/components/datepicker/examples/states.tsx +9 -1
- package/src/components/description-list/COMPONENT.md +1 -0
- package/src/components/description-list/examples/screen.module.css +64 -0
- package/src/components/description-list/examples/screen.tsx +214 -0
- package/src/components/description-list/examples/structure.tsx +1 -1
- package/src/components/digit-input/COMPONENT.md +3 -1
- package/src/components/digit-input/examples/states.tsx +3 -1
- package/src/components/digit-input/examples/without-focus-ring.tsx +13 -0
- package/src/components/divider/examples/with-icon.tsx +2 -2
- package/src/components/dnd/COMPONENT.md +7 -5
- package/src/components/dnd/examples/drop-zones.tsx +82 -49
- package/src/components/dnd/examples/examples.module.css +50 -0
- package/src/components/dnd/examples/states.tsx +54 -0
- package/src/components/dnd/examples/table.tsx +113 -0
- package/src/components/drawer/COMPONENT.md +1 -0
- package/src/components/drawer/examples/dismiss.tsx +5 -3
- package/src/components/drawer/examples/examples.module.css +0 -13
- package/src/components/drawer/examples/header-actions.tsx +5 -9
- package/src/components/drawer/examples/overview.tsx +6 -18
- package/src/components/drawer/examples/screen.module.css +14 -0
- package/src/components/drawer/examples/screen.tsx +298 -0
- package/src/components/dropdown/examples/examples.module.css +1 -5
- package/src/components/empty-page/COMPONENT.md +1 -1
- package/src/components/empty-page/examples/region-error.tsx +8 -2
- package/src/components/example-frame/COMPONENT.md +3 -2
- package/src/components/example-frame/examples/initial-view.tsx +44 -0
- package/src/components/field-list/COMPONENT.md +165 -0
- package/src/components/field-list/examples/base-row.tsx +76 -0
- package/src/components/field-list/examples/controlled.tsx +72 -0
- package/src/components/field-list/examples/errors.tsx +88 -0
- package/src/components/field-list/examples/examples.module.css +34 -0
- package/src/components/field-list/examples/limits.tsx +55 -0
- package/src/components/field-list/examples/locked.tsx +139 -0
- package/src/components/field-list/examples/narrow.tsx +68 -0
- package/src/components/field-list/examples/overview.tsx +66 -0
- package/src/components/field-list/examples/reorder.tsx +42 -0
- package/src/components/field-list/examples/screen.module.css +18 -0
- package/src/components/field-list/examples/screen.tsx +316 -0
- package/src/components/field-list/examples/sizes.tsx +42 -0
- package/src/components/field-list/examples/states.tsx +51 -0
- package/src/components/file-upload/COMPONENT.md +7 -6
- package/src/components/file-upload/examples/custom-body.tsx +2 -1
- package/src/components/file-upload/examples/examples.module.css +1 -7
- package/src/components/file-upload/examples/file-cards.tsx +10 -1
- package/src/components/file-upload/examples/gallery.tsx +2 -2
- package/src/components/file-upload/examples/in-form.tsx +4 -9
- package/src/components/file-upload/examples/overview.tsx +5 -1
- package/src/components/file-upload/examples/row-parts.tsx +24 -1
- package/src/components/file-upload/examples/screen.module.css +45 -0
- package/src/components/file-upload/examples/screen.tsx +646 -0
- package/src/components/file-upload/examples/states.tsx +6 -2
- package/src/components/file-upload/examples/validation.tsx +11 -2
- package/src/components/file-upload/examples/variants.tsx +3 -20
- package/src/components/gantt/COMPONENT.md +2 -1
- package/src/components/gantt/examples/screen.module.css +14 -0
- package/src/components/gantt/examples/screen.tsx +726 -0
- package/src/components/gantt/examples/states.tsx +6 -2
- package/src/components/input/COMPONENT.md +2 -2
- package/src/components/input/examples/examples.module.css +2 -13
- package/src/components/input/examples/in-form.tsx +1 -9
- package/src/components/input/examples/password-strength.tsx +34 -8
- package/src/components/input/examples/states.tsx +6 -1
- package/src/components/kanban/COMPONENT.md +16 -11
- package/src/components/kanban/examples/columns.tsx +8 -5
- package/src/components/kanban/examples/limits.tsx +2 -1
- package/src/components/kanban/examples/screen.module.css +17 -0
- package/src/components/kanban/examples/screen.tsx +572 -0
- package/src/components/kanban/examples/states.tsx +17 -6
- package/src/components/kanban/examples/variants.tsx +16 -8
- package/src/components/list/COMPONENT.md +1 -1
- package/src/components/login-form/COMPONENT.md +6 -5
- package/src/components/login-form/examples/examples.module.css +2 -21
- package/src/components/login-form/examples/forgot-password.tsx +28 -32
- package/src/components/login-form/examples/narrow.tsx +1 -1
- package/src/components/login-form/examples/overview.tsx +45 -47
- package/src/components/login-form/examples/register.tsx +64 -68
- package/src/components/login-form/examples/reset-password.tsx +50 -47
- package/src/components/login-form/examples/sizes.tsx +4 -6
- package/src/components/login-form/examples/states.tsx +53 -57
- package/src/components/login-form/examples/structure.tsx +18 -22
- package/src/components/login-form/examples/verification-code.tsx +41 -45
- package/src/components/media-viewer/COMPONENT.md +3 -3
- package/src/components/media-viewer/examples/dismiss.tsx +5 -1
- package/src/components/message/COMPONENT.md +6 -5
- package/src/components/message/examples/file.tsx +5 -1
- package/src/components/message/examples/media-open.tsx +48 -0
- package/src/components/message/examples/status.tsx +21 -3
- package/src/components/message/examples/text-formatting.tsx +7 -1
- package/src/components/modal/COMPONENT.md +2 -1
- package/src/components/modal/examples/custom-container.tsx +20 -20
- package/src/components/modal/examples/dismiss.tsx +5 -3
- package/src/components/modal/examples/enter-key.tsx +116 -0
- package/src/components/modal/examples/examples.module.css +7 -13
- package/src/components/modal/examples/structure.tsx +5 -2
- package/src/components/native-select/COMPONENT.md +1 -1
- package/src/components/native-select/examples/states.tsx +5 -1
- package/src/components/notification/COMPONENT.md +2 -1
- package/src/components/notification/examples/dismiss.tsx +2 -2
- package/src/components/page-content/COMPONENT.md +71 -14
- package/src/components/page-content/examples/grid.tsx +107 -0
- package/src/components/page-content/examples/list-detail.tsx +0 -3
- package/src/components/page-content/examples/overview.tsx +2 -2
- package/src/components/page-content/examples/screen.module.css +27 -0
- package/src/components/page-content/examples/screen.tsx +196 -0
- package/src/components/page-content/examples/sections.tsx +81 -0
- package/src/components/page-content/examples/variants.tsx +4 -11
- package/src/components/page-toolbar/COMPONENT.md +18 -16
- package/src/components/page-toolbar/examples/narrow.tsx +6 -3
- package/src/components/pagination/examples/controlled.tsx +29 -29
- package/src/components/pagination/examples/examples.module.css +0 -2
- package/src/components/progress-bar/COMPONENT.md +1 -1
- package/src/components/progress-bar/examples/segments.tsx +2 -2
- package/src/components/progress-circle/COMPONENT.md +1 -1
- package/src/components/progress-circle/examples/segments.tsx +8 -3
- package/src/components/radio/COMPONENT.md +1 -0
- package/src/components/radio/examples/examples.module.css +14 -0
- package/src/components/radio/examples/in-form.tsx +45 -0
- package/src/components/scroll-container/COMPONENT.md +1 -0
- package/src/components/scroll-container/examples/auto-scroll.tsx +3 -3
- package/src/components/scroll-container/examples/chat.tsx +3 -3
- package/src/components/scroll-container/examples/edges.tsx +6 -3
- package/src/components/scroll-container/examples/examples.module.css +4 -17
- package/src/components/scroll-container/examples/load-more.tsx +51 -0
- package/src/components/scroll-container/examples/lock.tsx +3 -5
- package/src/components/scroll-container/examples/overscroll.tsx +3 -3
- package/src/components/scroll-container/examples/overview.tsx +3 -3
- package/src/components/scroll-container/examples/scrollbar.tsx +13 -7
- package/src/components/scroll-container/examples/variants.tsx +13 -7
- package/src/components/segmented-control/COMPONENT.md +3 -2
- package/src/components/segmented-control/examples/in-form.tsx +5 -1
- package/src/components/segmented-control/examples/states.tsx +10 -1
- package/src/components/select/COMPONENT.md +5 -3
- package/src/components/select/examples/examples.module.css +2 -7
- package/src/components/select/examples/icon-only.tsx +38 -0
- package/src/components/select/examples/states.tsx +13 -1
- package/src/components/sheet/COMPONENT.md +2 -0
- package/src/components/sheet/examples/guard.tsx +72 -0
- package/src/components/sheet/examples/header-actions.tsx +56 -0
- package/src/components/slider/COMPONENT.md +2 -1
- package/src/components/slider/examples/examples.module.css +8 -0
- package/src/components/slider/examples/in-form.tsx +47 -0
- package/src/components/slider/examples/states.tsx +4 -1
- package/src/components/smart-filter/COMPONENT.md +1 -1
- package/src/components/smart-filter/examples/controlled.tsx +3 -3
- package/src/components/smart-filter/examples/ranges.tsx +44 -10
- package/src/components/sparkline/COMPONENT.md +83 -30
- package/src/components/sparkline/examples/compact.tsx +1 -1
- package/src/components/sparkline/examples/curve.tsx +28 -0
- package/src/components/sparkline/examples/gaps.tsx +33 -0
- package/src/components/sparkline/examples/overview.tsx +11 -2
- package/src/components/sparkline/examples/period.tsx +7 -2
- package/src/components/sparkline/examples/reference.tsx +38 -0
- package/src/components/sparkline/examples/variants.tsx +2 -2
- package/src/components/tabs/COMPONENT.md +1 -1
- package/src/components/tabs/examples/examples.module.css +0 -6
- package/src/components/tabs/examples/in-drawer.tsx +11 -13
- package/src/components/tabs/examples/sizes.tsx +1 -1
- package/src/components/tag-select/COMPONENT.md +1 -1
- package/src/components/tag-select/examples/states.tsx +8 -1
- package/src/components/textarea/COMPONENT.md +1 -1
- package/src/components/textarea/examples/examples.module.css +0 -6
- package/src/components/textarea/examples/in-form.tsx +1 -9
- package/src/components/textarea/examples/states.tsx +2 -1
- package/src/components/thumbnail/COMPONENT.md +2 -1
- package/src/components/thumbnail/examples/examples.module.css +1 -1
- package/src/components/thumbnail/examples/fit.tsx +24 -0
- package/src/components/thumbnail/examples/video.tsx +20 -1
- package/src/components/timeline/COMPONENT.md +1 -1
- package/src/components/timeline/examples/examples.module.css +0 -8
- package/src/components/timeline/examples/links.tsx +55 -14
- package/src/components/timeline/examples/narrow.tsx +2 -2
- package/src/components/timeline/examples/sizes.tsx +3 -3
- package/src/components/timeline/examples/variants.tsx +4 -4
- package/src/components/tooltip/COMPONENT.md +7 -5
- package/src/components/tooltip/examples/placement.tsx +2 -1
- package/src/components/tooltip/examples/toolbar.tsx +2 -2
- package/src/components/typography/examples/weights.tsx +3 -0
- package/src/components/video-note/COMPONENT.md +3 -3
- package/src/components/video-note/examples/controlled.tsx +19 -2
- package/src/components/video-note/examples/in-message.tsx +5 -2
- package/src/components/visually-hidden/COMPONENT.md +2 -1
- package/src/components/visually-hidden/examples/assertive.tsx +39 -0
- package/src/components/voice-player/COMPONENT.md +3 -3
- package/src/components/voice-player/examples/call-recording.tsx +19 -9
- package/src/components/voice-player/examples/controlled.tsx +20 -3
- package/src/layout/app-header/COMPONENT.md +46 -63
- package/src/layout/app-header/examples/breadcrumbs.tsx +10 -9
- package/src/layout/app-header/examples/examples.module.css +1 -1
- package/src/layout/app-header/examples/in-app-shell.tsx +2 -3
- package/src/layout/app-header/examples/narrow.tsx +4 -5
- package/src/layout/app-header/examples/overview.tsx +8 -10
- package/src/layout/app-header/examples/page-title.tsx +3 -10
- package/src/layout/app-shell/COMPONENT.md +5 -4
- package/src/layout/app-shell/examples/footer.tsx +2 -2
- package/src/layout/app-shell/examples/overview.tsx +17 -32
- package/src/layout/app-shell/examples/screen.module.css +11 -0
- package/src/layout/app-shell/examples/screen.tsx +262 -0
- package/src/layout/app-shell/examples/template.tsx +31 -11
- package/src/layout/bottom-nav/examples/floating-action.tsx +2 -2
- package/src/layout/bottom-nav/examples/floating.tsx +2 -2
- package/src/layout/bottom-nav/examples/in-app-shell.tsx +2 -2
- package/src/layout/sidebar/COMPONENT.md +7 -4
- package/src/layout/sidebar/examples/account.tsx +2 -2
- package/src/layout/sidebar/examples/collapsible-groups.tsx +12 -4
- package/src/layout/sidebar/examples/custom-part.tsx +53 -0
- package/src/layout/sidebar/examples/examples.module.css +5 -0
- package/src/layout/sidebar/examples/narrow.tsx +53 -0
- package/src/layout/sidebar/examples/persist.tsx +57 -0
- package/src/layout/sidebar/examples/router.tsx +14 -2
- package/src/layout/sidebar/examples/structure.tsx +7 -2
- package/src/styles/theme-light.css +1 -0
- package/dist/skill/patterns/app-shell.tsx +0 -301
- package/dist/skill/patterns/chat.module.css +0 -8
- package/dist/skill/patterns/dashboard.module.css +0 -44
- package/dist/skill/patterns/dashboard.tsx +0 -326
- package/dist/skill/patterns/detail-page.tsx +0 -209
- package/dist/skill/patterns/form-drawer.tsx +0 -240
- package/dist/skill/patterns/kanban-board.module.css +0 -28
- package/dist/skill/patterns/media-library.tsx +0 -638
- package/dist/skill/patterns/schedule.module.css +0 -22
- package/dist/skill/patterns/screen-states.tsx +0 -186
- /package/dist/skill/{patterns/form-drawer.module.css → reference/components/drawer/examples/screen.module.css} +0 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
/** A dashboard: the title, a line of data, the period switch and the report in the app header; one grid of KPI tiles that cross-fade to the new period, a revenue trend, invoiced against paid beside two panels, and the latest payments with a link to the list — `AppHeader.Tools`, `PageContent.Grid`. */
|
|
2
|
+
import {
|
|
3
|
+
AppHeader,
|
|
4
|
+
Badge,
|
|
5
|
+
Button,
|
|
6
|
+
Card,
|
|
7
|
+
ChartFrame,
|
|
8
|
+
type ChartFrameSeries,
|
|
9
|
+
Crossfade,
|
|
10
|
+
chartColors,
|
|
11
|
+
DataTable,
|
|
12
|
+
type DataTableColumn,
|
|
13
|
+
Icon,
|
|
14
|
+
LinkButton,
|
|
15
|
+
PageContent,
|
|
16
|
+
PageToolbar,
|
|
17
|
+
ProgressBar,
|
|
18
|
+
type ProgressSegment,
|
|
19
|
+
SegmentedControl,
|
|
20
|
+
Sparkline,
|
|
21
|
+
type SparklinePoint,
|
|
22
|
+
Typography,
|
|
23
|
+
} from "prime-ui-kit";
|
|
24
|
+
import * as React from "react";
|
|
25
|
+
|
|
26
|
+
import styles from "./screen.module.css";
|
|
27
|
+
|
|
28
|
+
type Period = "week" | "month" | "quarter";
|
|
29
|
+
type Payment = { id: string; client: string; date: string; amount: number; late: boolean };
|
|
30
|
+
|
|
31
|
+
const KPIS: Record<
|
|
32
|
+
Period,
|
|
33
|
+
{ label: string; value: string; delta: string; tone: "success" | "danger" | "neutral" }[]
|
|
34
|
+
> = {
|
|
35
|
+
week: [
|
|
36
|
+
{ label: "Выручка", value: "2,1 млн ₽", delta: "+6% к прошлой неделе", tone: "success" },
|
|
37
|
+
{ label: "Оплачено счетов", value: "54", delta: "+4", tone: "success" },
|
|
38
|
+
{ label: "Средний чек", value: "38 900 ₽", delta: "без изменений", tone: "neutral" },
|
|
39
|
+
{ label: "Просрочено", value: "1,2 млн ₽", delta: "+180 тыс. ₽", tone: "danger" },
|
|
40
|
+
],
|
|
41
|
+
month: [
|
|
42
|
+
{ label: "Выручка", value: "8,4 млн ₽", delta: "+12% к сентябрю", tone: "success" },
|
|
43
|
+
{ label: "Оплачено счетов", value: "214", delta: "+17", tone: "success" },
|
|
44
|
+
{ label: "Средний чек", value: "39 300 ₽", delta: "−3% к сентябрю", tone: "danger" },
|
|
45
|
+
{ label: "Просрочено", value: "1,2 млн ₽", delta: "−340 тыс. ₽", tone: "success" },
|
|
46
|
+
],
|
|
47
|
+
quarter: [
|
|
48
|
+
{ label: "Выручка", value: "24,6 млн ₽", delta: "+21% ко II кварталу", tone: "success" },
|
|
49
|
+
{ label: "Оплачено счетов", value: "631", delta: "+88", tone: "success" },
|
|
50
|
+
{ label: "Средний чек", value: "39 000 ₽", delta: "+1%", tone: "neutral" },
|
|
51
|
+
{ label: "Просрочено", value: "1,2 млн ₽", delta: "−1,1 млн ₽", tone: "success" },
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const MONTHS = ["янв", "фев", "мар", "апр", "мая", "июн", "июл", "авг", "сен", "окт", "ноя", "дек"];
|
|
56
|
+
|
|
57
|
+
/** Daily revenue up to 8 October 2026: `days` points ending that day, a deterministic wave. */
|
|
58
|
+
function dailyRevenue(days: number, base: number): SparklinePoint[] {
|
|
59
|
+
return Array.from({ length: days }, (_, i) => {
|
|
60
|
+
const day = new Date(2026, 9, 8 - (days - 1 - i));
|
|
61
|
+
const wave = Math.sin(i / 2.3) * 0.12 + Math.sin(i / 0.9) * 0.05 + i / days / 6;
|
|
62
|
+
return {
|
|
63
|
+
label: `${day.getDate()} ${MONTHS[day.getMonth()]}`,
|
|
64
|
+
value: Math.round((base * (1 + wave)) / 1000) * 1000,
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const REVENUE: Record<Period, SparklinePoint[]> = {
|
|
70
|
+
week: dailyRevenue(7, 300_000),
|
|
71
|
+
month: dailyRevenue(30, 280_000),
|
|
72
|
+
quarter: dailyRevenue(90, 270_000),
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const formatRubles = (value: number) => `${value.toLocaleString("ru-RU")} ₽`;
|
|
76
|
+
|
|
77
|
+
const BILLING_SERIES: ChartFrameSeries[] = [
|
|
78
|
+
{ id: "invoiced", label: "Выставлено" },
|
|
79
|
+
{ id: "paid", label: "Оплачено" },
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
/** Invoiced and paid, in millions of rubles, by the buckets of each period. */
|
|
83
|
+
const BILLING: Record<Period, { label: string; invoiced: number; paid: number }[]> = {
|
|
84
|
+
week: [
|
|
85
|
+
{ label: "пн", invoiced: 0.42, paid: 0.31 },
|
|
86
|
+
{ label: "вт", invoiced: 0.38, paid: 0.4 },
|
|
87
|
+
{ label: "ср", invoiced: 0.51, paid: 0.36 },
|
|
88
|
+
{ label: "чт", invoiced: 0.47, paid: 0.44 },
|
|
89
|
+
{ label: "пт", invoiced: 0.56, paid: 0.52 },
|
|
90
|
+
],
|
|
91
|
+
month: [
|
|
92
|
+
{ label: "нед 37", invoiced: 2.1, paid: 1.8 },
|
|
93
|
+
{ label: "нед 38", invoiced: 2.4, paid: 2.0 },
|
|
94
|
+
{ label: "нед 39", invoiced: 1.9, paid: 2.2 },
|
|
95
|
+
{ label: "нед 40", invoiced: 2.6, paid: 2.1 },
|
|
96
|
+
],
|
|
97
|
+
quarter: [
|
|
98
|
+
{ label: "авг", invoiced: 7.8, paid: 6.9 },
|
|
99
|
+
{ label: "сен", invoiced: 8.1, paid: 7.6 },
|
|
100
|
+
{ label: "окт", invoiced: 8.9, paid: 8.4 },
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const BILLING_MARGIN = { top: 8, bottom: 24, left: 36 };
|
|
105
|
+
|
|
106
|
+
const formatMillionsShort = (value: number) => `${value.toLocaleString("ru-RU")} млн ₽`;
|
|
107
|
+
|
|
108
|
+
const PLAN = [
|
|
109
|
+
{ manager: "Анна Климова", value: 92 },
|
|
110
|
+
{ manager: "Илья Петров", value: 74 },
|
|
111
|
+
{ manager: "Марат Хасанов", value: 48 },
|
|
112
|
+
];
|
|
113
|
+
|
|
114
|
+
/** Display of an amount in millions: «5,1 млн ₽». */
|
|
115
|
+
const formatMillions = (value: number) => `${String(value).replace(".", ",")} млн ₽`;
|
|
116
|
+
|
|
117
|
+
const RECEIVABLES: ProgressSegment[] = [
|
|
118
|
+
{ value: 5.1, label: "В срок", tone: "success" },
|
|
119
|
+
{ value: 1.9, label: "До 30 дней", tone: "warning" },
|
|
120
|
+
{ value: 1.2, label: "Больше 30 дней", tone: "danger" },
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
const PAYMENTS: Payment[] = [
|
|
124
|
+
{ id: "p1", client: "ООО «Мостострой»", date: "7 окт.", amount: 2_480_000, late: false },
|
|
125
|
+
{ id: "p2", client: "АО «Волга-Энерго»", date: "6 окт.", amount: 1_095_000, late: false },
|
|
126
|
+
{ id: "p3", client: "ООО «Логистик Плюс»", date: "5 окт.", amount: 312_000, late: true },
|
|
127
|
+
{ id: "p4", client: "ООО «Гранит»", date: "3 окт.", amount: 94_750, late: false },
|
|
128
|
+
];
|
|
129
|
+
|
|
130
|
+
const MONEY = new Intl.NumberFormat("ru-RU", {
|
|
131
|
+
style: "currency",
|
|
132
|
+
currency: "RUB",
|
|
133
|
+
maximumFractionDigits: 0,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const COLUMNS: DataTableColumn<Payment>[] = [
|
|
137
|
+
{
|
|
138
|
+
id: "client",
|
|
139
|
+
header: "Клиент",
|
|
140
|
+
cell: (row) => (
|
|
141
|
+
<span className={styles.client}>
|
|
142
|
+
{row.client}
|
|
143
|
+
{row.late ? <Badge.Root color="orange">С опозданием</Badge.Root> : null}
|
|
144
|
+
</span>
|
|
145
|
+
),
|
|
146
|
+
},
|
|
147
|
+
{ id: "date", header: "Дата", accessor: "date", numeric: true, headerAlign: "end" },
|
|
148
|
+
{
|
|
149
|
+
id: "amount",
|
|
150
|
+
header: "Сумма",
|
|
151
|
+
numeric: true,
|
|
152
|
+
headerAlign: "end",
|
|
153
|
+
cell: (row) => MONEY.format(row.amount),
|
|
154
|
+
},
|
|
155
|
+
];
|
|
156
|
+
|
|
157
|
+
export default function CardScreenExample() {
|
|
158
|
+
const [period, setPeriod] = React.useState<Period>("month");
|
|
159
|
+
|
|
160
|
+
return (
|
|
161
|
+
<>
|
|
162
|
+
{/* In an app this header fills the shell's `header` slot and carries the page: the only h1,
|
|
163
|
+
a line of data under it and the page's tools; main has no PageContent.Header. */}
|
|
164
|
+
<AppHeader.Root>
|
|
165
|
+
<AppHeader.Start>
|
|
166
|
+
<AppHeader.Title>
|
|
167
|
+
Обзор
|
|
168
|
+
<AppHeader.Description>Продажи и оплаты · на 8 октября, 9:40</AppHeader.Description>
|
|
169
|
+
</AppHeader.Title>
|
|
170
|
+
</AppHeader.Start>
|
|
171
|
+
<AppHeader.Tools>
|
|
172
|
+
<PageToolbar.Root aria-label="Обзор">
|
|
173
|
+
<PageToolbar.View>
|
|
174
|
+
<SegmentedControl.Root
|
|
175
|
+
aria-label="Период"
|
|
176
|
+
value={period}
|
|
177
|
+
onValueChange={(next) => setPeriod(next as Period)}
|
|
178
|
+
>
|
|
179
|
+
<SegmentedControl.Item value="week">Неделя</SegmentedControl.Item>
|
|
180
|
+
<SegmentedControl.Item value="month">Месяц</SegmentedControl.Item>
|
|
181
|
+
<SegmentedControl.Item value="quarter">Квартал</SegmentedControl.Item>
|
|
182
|
+
</SegmentedControl.Root>
|
|
183
|
+
</PageToolbar.View>
|
|
184
|
+
<PageToolbar.Actions>
|
|
185
|
+
<Button.Root variant="soft" tone="neutral">
|
|
186
|
+
<Button.Icon>
|
|
187
|
+
<Icon name="action.download" />
|
|
188
|
+
</Button.Icon>
|
|
189
|
+
Отчёт
|
|
190
|
+
</Button.Root>
|
|
191
|
+
</PageToolbar.Actions>
|
|
192
|
+
</PageToolbar.Root>
|
|
193
|
+
</AppHeader.Tools>
|
|
194
|
+
</AppHeader.Root>
|
|
195
|
+
|
|
196
|
+
<PageContent.Root>
|
|
197
|
+
<PageContent.Body>
|
|
198
|
+
{/* One board: every tile of the screen in one grid, 16 apart on both axes. */}
|
|
199
|
+
<PageContent.Grid>
|
|
200
|
+
{KPIS[period].map((kpi) => (
|
|
201
|
+
<PageContent.Cell key={kpi.label} span={3}>
|
|
202
|
+
{/* Another period is another set of values: the tile cross-fades instead of flipping. */}
|
|
203
|
+
<Crossfade state={period}>
|
|
204
|
+
<Card.Root variant="stat-trend">
|
|
205
|
+
<Card.Label>{kpi.label}</Card.Label>
|
|
206
|
+
<Card.Value>{kpi.value}</Card.Value>
|
|
207
|
+
<Card.Delta tone={kpi.tone}>{kpi.delta}</Card.Delta>
|
|
208
|
+
</Card.Root>
|
|
209
|
+
</Crossfade>
|
|
210
|
+
</PageContent.Cell>
|
|
211
|
+
))}
|
|
212
|
+
|
|
213
|
+
<PageContent.Cell>
|
|
214
|
+
<Card.Root variant="panel">
|
|
215
|
+
<Card.Body>
|
|
216
|
+
<Sparkline
|
|
217
|
+
data={REVENUE[period]}
|
|
218
|
+
label="Выручка по дням"
|
|
219
|
+
summary="sum"
|
|
220
|
+
formatValue={formatRubles}
|
|
221
|
+
/>
|
|
222
|
+
</Card.Body>
|
|
223
|
+
</Card.Root>
|
|
224
|
+
</PageContent.Cell>
|
|
225
|
+
|
|
226
|
+
{/* The chart spans two rows beside the two panels and fills their height. */}
|
|
227
|
+
<PageContent.Cell span={8} rows={2}>
|
|
228
|
+
<ChartFrame.Root series={BILLING_SERIES} formatValue={formatMillionsShort}>
|
|
229
|
+
<ChartFrame.Header>
|
|
230
|
+
<ChartFrame.Title as="h2">Выставлено и оплачено</ChartFrame.Title>
|
|
231
|
+
<ChartFrame.Description>Счета за период, млн ₽</ChartFrame.Description>
|
|
232
|
+
</ChartFrame.Header>
|
|
233
|
+
<ChartFrame.Plot
|
|
234
|
+
height="fill"
|
|
235
|
+
renderPlot={({ width, height, series }) => {
|
|
236
|
+
const rows = BILLING[period];
|
|
237
|
+
const top = Math.ceil(Math.max(...rows.map((row) => row.invoiced)));
|
|
238
|
+
const innerH = height - BILLING_MARGIN.top - BILLING_MARGIN.bottom;
|
|
239
|
+
const band = (width - BILLING_MARGIN.left) / rows.length;
|
|
240
|
+
const bar = Math.min(28, (band - 16) / series.length);
|
|
241
|
+
const y = (value: number) => BILLING_MARGIN.top + innerH * (1 - value / top);
|
|
242
|
+
return (
|
|
243
|
+
<svg width={width} height={height} aria-hidden="true">
|
|
244
|
+
{[0, top / 2, top].map((tick) => (
|
|
245
|
+
<g key={tick}>
|
|
246
|
+
<line
|
|
247
|
+
x1={BILLING_MARGIN.left}
|
|
248
|
+
x2={width}
|
|
249
|
+
y1={y(tick)}
|
|
250
|
+
y2={y(tick)}
|
|
251
|
+
stroke={tick === 0 ? chartColors.axis : chartColors.grid}
|
|
252
|
+
/>
|
|
253
|
+
<text
|
|
254
|
+
x={BILLING_MARGIN.left - 8}
|
|
255
|
+
y={y(tick)}
|
|
256
|
+
textAnchor="end"
|
|
257
|
+
dominantBaseline="middle"
|
|
258
|
+
>
|
|
259
|
+
{tick.toLocaleString("ru-RU")}
|
|
260
|
+
</text>
|
|
261
|
+
</g>
|
|
262
|
+
))}
|
|
263
|
+
{rows.map((row, i) => {
|
|
264
|
+
const center = BILLING_MARGIN.left + band * i + band / 2;
|
|
265
|
+
return (
|
|
266
|
+
<g key={row.label}>
|
|
267
|
+
{series.map((s, j) => {
|
|
268
|
+
const value = s.id === "paid" ? row.paid : row.invoiced;
|
|
269
|
+
return (
|
|
270
|
+
<rect
|
|
271
|
+
key={s.id}
|
|
272
|
+
data-hidden={s.hidden}
|
|
273
|
+
x={center - (bar * series.length) / 2 + bar * j}
|
|
274
|
+
y={y(value)}
|
|
275
|
+
width={bar - 2}
|
|
276
|
+
height={y(0) - y(value)}
|
|
277
|
+
rx={2}
|
|
278
|
+
fill={s.color}
|
|
279
|
+
/>
|
|
280
|
+
);
|
|
281
|
+
})}
|
|
282
|
+
<text x={center} y={height - 4} textAnchor="middle">
|
|
283
|
+
{row.label}
|
|
284
|
+
</text>
|
|
285
|
+
</g>
|
|
286
|
+
);
|
|
287
|
+
})}
|
|
288
|
+
</svg>
|
|
289
|
+
);
|
|
290
|
+
}}
|
|
291
|
+
/>
|
|
292
|
+
<ChartFrame.Legend />
|
|
293
|
+
<ChartFrame.Table
|
|
294
|
+
rows={BILLING[period].map((row) => ({
|
|
295
|
+
label: row.label,
|
|
296
|
+
values: { invoiced: row.invoiced, paid: row.paid },
|
|
297
|
+
}))}
|
|
298
|
+
/>
|
|
299
|
+
</ChartFrame.Root>
|
|
300
|
+
</PageContent.Cell>
|
|
301
|
+
|
|
302
|
+
<PageContent.Cell span={4}>
|
|
303
|
+
<Card.Root variant="panel">
|
|
304
|
+
<Card.Header>
|
|
305
|
+
<Card.Title as="h2">План продаж</Card.Title>
|
|
306
|
+
<Typography as="span" variant="caption" tone="muted">
|
|
307
|
+
Октябрь
|
|
308
|
+
</Typography>
|
|
309
|
+
</Card.Header>
|
|
310
|
+
<Card.Body>
|
|
311
|
+
<div className={styles.bars}>
|
|
312
|
+
{PLAN.map((row) => (
|
|
313
|
+
<ProgressBar
|
|
314
|
+
key={row.manager}
|
|
315
|
+
value={row.value}
|
|
316
|
+
label={row.manager}
|
|
317
|
+
tone={row.value < 50 ? "warning" : "accent"}
|
|
318
|
+
showValue
|
|
319
|
+
/>
|
|
320
|
+
))}
|
|
321
|
+
</div>
|
|
322
|
+
</Card.Body>
|
|
323
|
+
</Card.Root>
|
|
324
|
+
</PageContent.Cell>
|
|
325
|
+
|
|
326
|
+
<PageContent.Cell span={4}>
|
|
327
|
+
<Card.Root variant="panel">
|
|
328
|
+
<Card.Header>
|
|
329
|
+
<Card.Title as="h2">Дебиторка</Card.Title>
|
|
330
|
+
<Typography as="span" variant="caption" tone="muted">
|
|
331
|
+
8,2 млн ₽
|
|
332
|
+
</Typography>
|
|
333
|
+
</Card.Header>
|
|
334
|
+
<Card.Body>
|
|
335
|
+
<ProgressBar
|
|
336
|
+
segments={RECEIVABLES}
|
|
337
|
+
label="По сроку оплаты"
|
|
338
|
+
legend
|
|
339
|
+
formatValue={formatMillions}
|
|
340
|
+
/>
|
|
341
|
+
</Card.Body>
|
|
342
|
+
</Card.Root>
|
|
343
|
+
</PageContent.Cell>
|
|
344
|
+
</PageContent.Grid>
|
|
345
|
+
|
|
346
|
+
{/* A new topic: a titled section, set off by more air than the tiles. */}
|
|
347
|
+
<PageContent.Section label="Последние оплаты">
|
|
348
|
+
<PageContent.Actions>
|
|
349
|
+
<LinkButton href="#invoices">Все счета</LinkButton>
|
|
350
|
+
</PageContent.Actions>
|
|
351
|
+
<DataTable
|
|
352
|
+
columns={COLUMNS}
|
|
353
|
+
rows={PAYMENTS}
|
|
354
|
+
getRowKey={(row) => row.id}
|
|
355
|
+
paging="none"
|
|
356
|
+
/>
|
|
357
|
+
</PageContent.Section>
|
|
358
|
+
</PageContent.Body>
|
|
359
|
+
</PageContent.Root>
|
|
360
|
+
</>
|
|
361
|
+
);
|
|
362
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** KPI templates: an icon tile with a value, a badge with a value in the header row, and a large value with its change and a reference line — `variant`, `Card.Delta`, `Card.Meta`. */
|
|
1
|
+
/** KPI templates: an icon tile with a value, a badge with a value in the header row, and a large value with its change in every tone and a reference line — `variant`, `Card.Delta`, `tone`, `Card.Meta`. */
|
|
2
2
|
import { Badge, Card, Icon } from "prime-ui-kit";
|
|
3
3
|
|
|
4
4
|
import styles from "./examples.module.css";
|
|
@@ -35,6 +35,20 @@ export default function CardVariantsExample() {
|
|
|
35
35
|
<Card.Delta tone="danger">+0,6 п. п. за неделю</Card.Delta>
|
|
36
36
|
<Card.Meta>Ушло 38 из 1 226 клиентов</Card.Meta>
|
|
37
37
|
</Card.Root>
|
|
38
|
+
|
|
39
|
+
<Card.Root variant="stat-trend">
|
|
40
|
+
<Card.Label>Первый ответ поддержки</Card.Label>
|
|
41
|
+
<Card.Value>3,4 ч</Card.Value>
|
|
42
|
+
<Card.Delta tone="warning">+40 мин — близко к SLA 4 ч</Card.Delta>
|
|
43
|
+
<Card.Meta>Открыто 62 обращения</Card.Meta>
|
|
44
|
+
</Card.Root>
|
|
45
|
+
|
|
46
|
+
<Card.Root variant="stat-trend">
|
|
47
|
+
<Card.Label>Средний чек</Card.Label>
|
|
48
|
+
<Card.Value>38 900 ₽</Card.Value>
|
|
49
|
+
<Card.Delta>без изменений</Card.Delta>
|
|
50
|
+
<Card.Meta>Оплачено 214 счетов</Card.Meta>
|
|
51
|
+
</Card.Root>
|
|
38
52
|
</div>
|
|
39
53
|
);
|
|
40
54
|
}
|
|
@@ -33,7 +33,7 @@ ChartFrame.Root <figure>; surface of the depth ladder; state, serie
|
|
|
33
33
|
├─ ChartFrame.Plot <div>; fixed height, measured; Crossfade of plot / Skeleton / empty / error
|
|
34
34
|
├─ ChartFrame.Legend <ul>; a toggle button per series: swatch · name · value
|
|
35
35
|
├─ ChartFrame.Table <table>; visually hidden data, ready state only
|
|
36
|
-
└─ ChartFrame.Tooltip <div>;
|
|
36
|
+
└─ ChartFrame.Tooltip <div>; with `point` portaled beside that point of the plot, else in place for a library's tooltip hook
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
## API
|
|
@@ -104,7 +104,7 @@ ChartFrame.Root <figure>; surface of the depth ladder; state, serie
|
|
|
104
104
|
|
|
105
105
|
| Prop | Type | Default | Description |
|
|
106
106
|
|---|---|---|---|
|
|
107
|
-
| `height` | `number` | `240, 160 under 30rem` | Height of the plot area in px. |
|
|
107
|
+
| `height` | `number \| "fill"` | `240, 160 under 30rem` | Height of the plot area in px. `fill` takes the free height of a stretched panel (a `PageContent.Cell` with `rows`), the default height at least. |
|
|
108
108
|
| `renderPlot` | `(area: ChartFramePlotArea) => ReactNode` | — | Renders the chart at the measured `{ width, height }` with every series `{ id, label, color, hidden }` — for libraries that need explicit sizes (Chart.js, visx). |
|
|
109
109
|
| `children` | `ReactNode` | — | A chart that sizes itself to its container (an SVG with a `viewBox`, `ResponsiveContainer`); it fills the area. |
|
|
110
110
|
| `…rest` | `HTMLAttributes<HTMLDivElement>` | — | `className` and the other div attributes. |
|
|
@@ -118,12 +118,13 @@ ChartFrame.Root <figure>; surface of the depth ladder; state, serie
|
|
|
118
118
|
| `…rest` | `HTMLAttributes<HTMLUListElement>` | — | `className` and the other ul attributes. |
|
|
119
119
|
|
|
120
120
|
### ChartFrame.Tooltip
|
|
121
|
-
`ref` → `HTMLDivElement`. The kit's tooltip body for a
|
|
121
|
+
`ref` → `HTMLDivElement`. The kit's chart tooltip: with `point` it floats beside that point of the plot; without it it is the body for a library's tooltip hook (Recharts `content`). Inside `ChartFrame.Root`.
|
|
122
122
|
|
|
123
123
|
| Prop | Type | Default | Description |
|
|
124
124
|
|---|---|---|---|
|
|
125
125
|
| `label` | `string` | — | The point the rows belong to («Неделя 41»). |
|
|
126
126
|
| `items` | `ChartFrameTooltipItem[]` | — (required) | `{ id, value }` per series at that point; name and color come from the root's series, rows of hidden series are left out, values go through `formatValue`. |
|
|
127
|
+
| `point` | `{ x: number; y: number } \| null` | — | A point in `renderPlot` coordinates (the pointer, or the point the arrows reached): the tooltip floats right of it, left only without room; `null` hides it. Floating, it is `aria-hidden`. |
|
|
127
128
|
| `…rest` | `HTMLAttributes<HTMLDivElement>` | — | `className` and the other div attributes. |
|
|
128
129
|
|
|
129
130
|
### ChartFrame.Table
|
|
@@ -177,7 +178,7 @@ ChartFrame.Root <figure>; surface of the depth ladder; state, serie
|
|
|
177
178
|
- The header puts the title and the description in the first column and the actions at the end; under 24rem of panel width the actions drop under the description.
|
|
178
179
|
- The plot is 240 px high (160 px under 30rem of panel width) unless `height` is set; it never changes height between states.
|
|
179
180
|
- Legend entries wrap onto more lines; each has a 44 px touch hit area on coarse pointers.
|
|
180
|
-
- `ChartFrame.Tooltip` is
|
|
181
|
+
- `ChartFrame.Tooltip` is the floating layer of the ladder with the point's label over rows of swatch · series name · value. With `point` the kit places it like every anchored layer (`usePosition`): right of the point at its height, on the left only where the right has no room in the viewport, inside the viewport, following the plot on scroll. Without `point` the chart library positions it (Recharts `content`).
|
|
181
182
|
- SVG `<text>` in the plot takes the caption type in `--prime-color-text-muted`; a class of your own still wins.
|
|
182
183
|
- Works from 320 px; the container queries are on the panel's own width, so it adapts in a grid cell as on a phone.
|
|
183
184
|
|
|
@@ -195,6 +196,7 @@ ChartFrame.Root <figure>; surface of the depth ladder; state, serie
|
|
|
195
196
|
- The root is a `<figure>` named by `ChartFrame.Title` and described by `ChartFrame.Description`; `aria-busy` while loading.
|
|
196
197
|
- A legend entry is a button with `aria-pressed` — pressed while its series is shown; the legend list is named by `labels.legend`. A hidden series differs by the swatch's shape (a ring) and a quiet name, never by color alone.
|
|
197
198
|
- `ChartFrame.Table` is a visually hidden table with the chart's data, named by the title: a row header per point, a column per shown series, values through `formatValue`.
|
|
199
|
+
- A `ChartFrame.Tooltip` with `point` is `aria-hidden` and passive (no focus, no presses; `Escape` hides it until the point moves): it repeats what the plot speaks — give a focusable plot an `aria-valuetext`, like the slider in the tooltip example.
|
|
198
200
|
- The empty state is `role="status"`, the error `role="alert"` with the retry button.
|
|
199
201
|
- The drawing is the library's: hide a decorative SVG (`aria-hidden`) when `ChartFrame.Table` carries the data; marks you make focusable need their own `aria-label`.
|
|
200
202
|
|
|
@@ -213,8 +215,9 @@ ChartFrame.Root <figure>; surface of the depth ladder; state, serie
|
|
|
213
215
|
| Example | Shows |
|
|
214
216
|
|---|---|
|
|
215
217
|
| [overview.tsx](examples/overview.tsx) | Revenue by month as a hand-drawn SVG line chart in a dashboard panel: the headline with its change, a period switch, a legend that turns series off and a table for screen readers — `series`, `formatValue`, `renderPlot`. |
|
|
216
|
-
| [tooltip.tsx](examples/tooltip.tsx) | Invoices by week as grouped bars:
|
|
217
|
-
| [
|
|
218
|
+
| [tooltip.tsx](examples/tooltip.tsx) | Invoices by week as grouped bars: the kit tooltip follows the pointer with a row per series, the arrows step through the weeks — `ChartFrame.Tooltip`, `items`, `point`. |
|
|
219
|
+
| [fill-height.tsx](examples/fill-height.tsx) | Revenue against the plan beside two KPI tiles: the plot takes the height of the stretched grid cell, and the plan line starts hidden until the legend turns it on — `height`, `defaultHiddenSeries`. |
|
|
220
|
+
| [states.tsx](examples/states.tsx) | Loading, empty, error and data swap in the plot's place without moving the panel; the error retries, and the legend of the one series only names it — `state`, `onRetry`, `readOnly`. |
|
|
218
221
|
| [controlled.tsx](examples/controlled.tsx) | Lead sources with totals in the legend; the hidden series live in the page state and one button shows them all again — `hiddenSeries`, `onHiddenSeriesChange`. |
|
|
219
222
|
| [narrow.tsx](examples/narrow.tsx) | A 320px column: the actions drop under the title, the plot gets lower and a self-sizing SVG stretches to it — `children`, `height`. |
|
|
220
223
|
|
|
@@ -249,7 +252,7 @@ ChartFrame.Root <figure>; surface of the depth ladder; state, serie
|
|
|
249
252
|
<ChartFrame.Table rows={tableRows} />
|
|
250
253
|
</ChartFrame.Root>
|
|
251
254
|
```
|
|
252
|
-
ECharts and Chart.js take the same `width`, `height` and `series[i].color`; their HTML tooltips are strings, so use their own tooltip there or
|
|
255
|
+
ECharts and Chart.js take the same `width`, `height` and `series[i].color`; their HTML tooltips are strings, so use their own tooltip there or `ChartFrame.Tooltip` with `point` from their hover event.
|
|
253
256
|
|
|
254
257
|
## Mistakes
|
|
255
258
|
- Colors picked per chart (`#3b82f6`) → `series[i].color` from `renderPlot`, or `chartColors`; status tones (`success`, `danger`) never paint categories.
|
|
@@ -259,7 +262,8 @@ ECharts and Chart.js take the same `width`, `height` and `series[i].color`; thei
|
|
|
259
262
|
- A legend for a single series → the title already names it; leave `ChartFrame.Legend` out.
|
|
260
263
|
- Two y-axes of different measures in one frame → two ChartFrames side by side.
|
|
261
264
|
- The data only in the drawing → add `ChartFrame.Table`; screen readers cannot read a plot.
|
|
265
|
+
- A hand-drawn chart with its tooltip placed by hand (a `foreignObject`, clamped coordinates) → `ChartFrame.Tooltip` with `point`: it flips only when out of room and never jumps at the middle.
|
|
262
266
|
|
|
263
267
|
## Related
|
|
264
|
-
- **Built from:** [Crossfade](../crossfade/COMPONENT.md) (state swap), [Skeleton](../skeleton/COMPONENT.md) (loading), [EmptyPage](../empty-page/COMPONENT.md) (empty, error, retry), `Icon`, `chartColors`
|
|
268
|
+
- **Built from:** [Crossfade](../crossfade/COMPONENT.md) (state swap), [Skeleton](../skeleton/COMPONENT.md) (loading), [EmptyPage](../empty-page/COMPONENT.md) (empty, error, retry), `Icon`, `chartColors`, `ChartTooltip` (the chart tooltip shared with Sparkline)
|
|
265
269
|
- **See also:** [Sparkline](../sparkline/COMPONENT.md), [Card](../card/COMPONENT.md), [ProgressBar](../progress-bar/COMPONENT.md), [DataTable](../data-table/COMPONENT.md), [SegmentedControl](../segmented-control/COMPONENT.md)
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/** Revenue against the plan beside two KPI tiles: the plot takes the height of the stretched grid cell, and the plan line starts hidden until the legend turns it on — `height`, `defaultHiddenSeries`. */
|
|
2
|
+
import { Card, ChartFrame, type ChartFrameSeries, chartColors, PageContent } from "prime-ui-kit";
|
|
3
|
+
|
|
4
|
+
const SERIES: ChartFrameSeries[] = [
|
|
5
|
+
{ id: "fact", label: "Факт" },
|
|
6
|
+
{ id: "plan", label: "План" },
|
|
7
|
+
];
|
|
8
|
+
|
|
9
|
+
const MONTHS = [
|
|
10
|
+
{ month: "май", fact: 6.2, plan: 6.0 },
|
|
11
|
+
{ month: "июн", fact: 6.8, plan: 6.5 },
|
|
12
|
+
{ month: "июл", fact: 6.4, plan: 7.0 },
|
|
13
|
+
{ month: "авг", fact: 7.1, plan: 7.4 },
|
|
14
|
+
{ month: "сен", fact: 7.5, plan: 7.8 },
|
|
15
|
+
{ month: "окт", fact: 7.9, plan: 8.2 },
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
const MARGIN = { top: 8, right: 16, bottom: 24, left: 32 };
|
|
19
|
+
const TICKS = [0, 3, 6, 9];
|
|
20
|
+
|
|
21
|
+
const formatMillions = (value: number) => `${value.toLocaleString("ru-RU")} млн ₽`;
|
|
22
|
+
|
|
23
|
+
export default function ChartFrameFillHeightExample() {
|
|
24
|
+
return (
|
|
25
|
+
<PageContent.Grid>
|
|
26
|
+
{/* The cell spans two rows beside the tiles; `height="fill"` takes all of it. */}
|
|
27
|
+
<PageContent.Cell span={8} rows={2}>
|
|
28
|
+
<ChartFrame.Root
|
|
29
|
+
series={SERIES}
|
|
30
|
+
defaultHiddenSeries={["plan"]}
|
|
31
|
+
formatValue={formatMillions}
|
|
32
|
+
>
|
|
33
|
+
<ChartFrame.Header>
|
|
34
|
+
<ChartFrame.Title as="h2">Выручка и план</ChartFrame.Title>
|
|
35
|
+
<ChartFrame.Description>По месяцам, млн ₽</ChartFrame.Description>
|
|
36
|
+
</ChartFrame.Header>
|
|
37
|
+
<ChartFrame.Value>
|
|
38
|
+
7,9 млн ₽<ChartFrame.Delta tone="warning">−4% к плану</ChartFrame.Delta>
|
|
39
|
+
</ChartFrame.Value>
|
|
40
|
+
<ChartFrame.Plot
|
|
41
|
+
height="fill"
|
|
42
|
+
renderPlot={({ width, height, series }) => {
|
|
43
|
+
const innerW = width - MARGIN.left - MARGIN.right;
|
|
44
|
+
const innerH = height - MARGIN.top - MARGIN.bottom;
|
|
45
|
+
const x = (i: number) => MARGIN.left + (innerW * i) / (MONTHS.length - 1);
|
|
46
|
+
const y = (v: number) => MARGIN.top + innerH * (1 - v / TICKS[TICKS.length - 1]);
|
|
47
|
+
return (
|
|
48
|
+
<svg width={width} height={height} aria-hidden="true">
|
|
49
|
+
{TICKS.map((tick) => (
|
|
50
|
+
<g key={tick}>
|
|
51
|
+
<line
|
|
52
|
+
x1={MARGIN.left}
|
|
53
|
+
x2={width - MARGIN.right}
|
|
54
|
+
y1={y(tick)}
|
|
55
|
+
y2={y(tick)}
|
|
56
|
+
stroke={tick === 0 ? chartColors.axis : chartColors.grid}
|
|
57
|
+
/>
|
|
58
|
+
<text
|
|
59
|
+
x={MARGIN.left - 8}
|
|
60
|
+
y={y(tick)}
|
|
61
|
+
textAnchor="end"
|
|
62
|
+
dominantBaseline="middle"
|
|
63
|
+
>
|
|
64
|
+
{tick}
|
|
65
|
+
</text>
|
|
66
|
+
</g>
|
|
67
|
+
))}
|
|
68
|
+
{MONTHS.map((row, i) => (
|
|
69
|
+
<text key={row.month} x={x(i)} y={height - 4} textAnchor="middle">
|
|
70
|
+
{row.month}
|
|
71
|
+
</text>
|
|
72
|
+
))}
|
|
73
|
+
{series.map((s) => (
|
|
74
|
+
<path
|
|
75
|
+
key={s.id}
|
|
76
|
+
data-hidden={s.hidden}
|
|
77
|
+
d={MONTHS.map(
|
|
78
|
+
(row, i) =>
|
|
79
|
+
`${i ? "L" : "M"}${x(i)},${y(s.id === "plan" ? row.plan : row.fact)}`,
|
|
80
|
+
).join("")}
|
|
81
|
+
fill="none"
|
|
82
|
+
stroke={s.color}
|
|
83
|
+
strokeWidth={2}
|
|
84
|
+
strokeDasharray={s.id === "plan" ? "4 4" : undefined}
|
|
85
|
+
strokeLinejoin="round"
|
|
86
|
+
/>
|
|
87
|
+
))}
|
|
88
|
+
</svg>
|
|
89
|
+
);
|
|
90
|
+
}}
|
|
91
|
+
/>
|
|
92
|
+
<ChartFrame.Legend />
|
|
93
|
+
<ChartFrame.Table
|
|
94
|
+
rows={MONTHS.map((row) => ({
|
|
95
|
+
label: row.month,
|
|
96
|
+
values: { fact: row.fact, plan: row.plan },
|
|
97
|
+
}))}
|
|
98
|
+
/>
|
|
99
|
+
</ChartFrame.Root>
|
|
100
|
+
</PageContent.Cell>
|
|
101
|
+
|
|
102
|
+
<PageContent.Cell span={4}>
|
|
103
|
+
<Card.Root variant="stat-trend">
|
|
104
|
+
<Card.Label>Выполнение плана</Card.Label>
|
|
105
|
+
<Card.Value>96%</Card.Value>
|
|
106
|
+
<Card.Delta tone="warning">−4 п. п. за октябрь</Card.Delta>
|
|
107
|
+
</Card.Root>
|
|
108
|
+
</PageContent.Cell>
|
|
109
|
+
|
|
110
|
+
<PageContent.Cell span={4}>
|
|
111
|
+
<Card.Root variant="stat-trend">
|
|
112
|
+
<Card.Label>Прогноз на год</Card.Label>
|
|
113
|
+
<Card.Value>84 млн ₽</Card.Value>
|
|
114
|
+
<Card.Delta>План — 86 млн ₽</Card.Delta>
|
|
115
|
+
</Card.Root>
|
|
116
|
+
</PageContent.Cell>
|
|
117
|
+
</PageContent.Grid>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Loading, empty, error and data swap in the plot's place without moving the panel; the error retries — `state`, `onRetry`. */
|
|
1
|
+
/** Loading, empty, error and data swap in the plot's place without moving the panel; the error retries, and the legend of the one series only names it — `state`, `onRetry`, `readOnly`. */
|
|
2
2
|
import {
|
|
3
3
|
ChartFrame,
|
|
4
4
|
type ChartFrameSeries,
|
|
@@ -72,6 +72,8 @@ export default function ChartFrameStatesExample() {
|
|
|
72
72
|
);
|
|
73
73
|
}}
|
|
74
74
|
/>
|
|
75
|
+
{/* One series: the legend only names it, there is nothing to turn off. */}
|
|
76
|
+
<ChartFrame.Legend readOnly />
|
|
75
77
|
</ChartFrame.Root>
|
|
76
78
|
</>
|
|
77
79
|
);
|