@espressif/dashboard-ui-components 1.11.2 → 1.12.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/.claude/rules/dashboard-ui-consumption.md +176 -5
- package/.cursor/rules/dashboard-ui-consumption.mdc +163 -4
- package/CHANGELOG.md +1005 -0
- package/README.md +240 -7
- package/THIRD-PARTY-NOTICES.md +2 -1
- package/dist/alert.props-CcKo49Rb.d.ts +44 -0
- package/dist/animation/index.d.ts +3 -0
- package/dist/animation/index.js +3 -0
- package/dist/avatar.props-2q5BsX-R.d.ts +29 -0
- package/dist/button-BK-DIR_L.d.ts +21 -0
- package/dist/button-BxJ7s6sR.d.ts +76 -0
- package/dist/calendar.props-BtCzuWH1.d.ts +12 -0
- package/dist/carousel/index.d.ts +2 -0
- package/dist/carousel/index.js +2 -0
- package/dist/charts/index.d.ts +5 -0
- package/dist/charts/index.js +9 -0
- package/dist/common/app-logo/app-logo.js +1 -1
- package/dist/common/index.d.ts +9 -20
- package/dist/common/my-account-menu/my-account-menu.js +45 -13
- package/dist/common/profile-card/profile-card.js +3 -2
- package/dist/components/accordion/accordion.js +14 -5
- package/dist/components/accordion/index.d.ts +36 -0
- package/dist/components/accordion/index.js +2 -0
- package/dist/components/advanced-search-box/advanced-search-box.js +8 -2
- package/dist/components/advanced-search-box/index.d.ts +29 -0
- package/dist/components/advanced-search-box/index.js +2 -0
- package/dist/components/alert/alert.js +2 -1
- package/dist/components/alert/index.d.ts +12 -0
- package/dist/components/alert/index.js +2 -0
- package/dist/components/anchored-panel/anchored-panel.js +83 -0
- package/dist/components/anchored-panel/index.d.ts +31 -0
- package/dist/components/anchored-panel/index.js +2 -0
- package/dist/components/animated-containers/index.d.ts +13 -0
- package/dist/components/animated-containers/index.js +2 -0
- package/dist/components/async-multi-select/async-multi-select.js +48 -7
- package/dist/components/async-multi-select/index.d.ts +63 -0
- package/dist/components/async-multi-select/index.js +2 -0
- package/dist/components/avatar/avatar.js +11 -4
- package/dist/components/avatar/index.d.ts +8 -0
- package/dist/components/avatar/index.js +2 -0
- package/dist/components/avatar-group/avatar-group.js +35 -0
- package/dist/components/avatar-group/index.d.ts +31 -0
- package/dist/components/avatar-group/index.js +2 -0
- package/dist/components/badge/index.d.ts +14 -0
- package/dist/components/badge/index.js +2 -0
- package/dist/components/breadcrumb/index.d.ts +21 -0
- package/dist/components/breadcrumb/index.js +2 -0
- package/dist/components/bubble/bubble.js +18 -0
- package/dist/components/bubble/index.d.ts +19 -0
- package/dist/components/bubble/index.js +2 -0
- package/dist/components/button/button.js +87 -25
- package/dist/components/button/flash-button.js +9 -3
- package/dist/components/button/index.d.ts +56 -0
- package/dist/components/button/index.js +6 -0
- package/dist/components/button-group/index.d.ts +16 -0
- package/dist/components/button-group/index.js +2 -0
- package/dist/components/calendar/calendar.js +5 -5
- package/dist/components/calendar/index.d.ts +11 -0
- package/dist/components/calendar/index.js +2 -0
- package/dist/components/card/index.d.ts +11 -0
- package/dist/components/card/index.js +2 -0
- package/dist/components/card-rail/card-rail.js +50 -0
- package/dist/components/card-rail/index.d.ts +30 -0
- package/dist/components/card-rail/index.js +2 -0
- package/dist/components/cards/collapsible-card.js +5 -2
- package/dist/components/cards/index.d.ts +16200 -0
- package/dist/components/cards/index.js +8 -0
- package/dist/components/cards/section-card.js +133 -8
- package/dist/components/cards/simple-card.js +5 -2
- package/dist/components/carousel/carousel.js +137 -49
- package/dist/components/carousel/index.d.ts +130 -0
- package/dist/components/carousel/index.js +2 -0
- package/dist/components/category-card/category-card.js +111 -0
- package/dist/components/category-card/index.d.ts +55 -0
- package/dist/components/category-card/index.js +2 -0
- package/dist/components/chart/area-chart.js +95 -85
- package/dist/components/chart/bar-chart.js +123 -60
- package/dist/components/chart/chart.js +127 -3
- package/dist/components/chart/composed-chart.js +109 -98
- package/dist/components/chart/donut-chart.js +23 -5
- package/dist/components/chart/index.d.ts +732 -0
- package/dist/components/chart/index.js +9 -0
- package/dist/components/chart/line-chart.js +93 -83
- package/dist/components/chart/treemap-chart.js +71 -58
- package/dist/components/check-badge/check-badge.js +25 -0
- package/dist/components/check-badge/index.d.ts +13 -0
- package/dist/components/check-badge/index.js +2 -0
- package/dist/components/checkbox/index.d.ts +8 -0
- package/dist/components/checkbox/index.js +2 -0
- package/dist/components/choice-card/choice-card.js +99 -0
- package/dist/components/choice-card/index.d.ts +41 -0
- package/dist/components/choice-card/index.js +2 -0
- package/dist/components/circular-progress/circular-progress.js +5 -2
- package/dist/components/circular-progress/index.d.ts +23 -0
- package/dist/components/circular-progress/index.js +2 -0
- package/dist/components/code/index.d.ts +40 -0
- package/dist/components/code/index.js +2 -0
- package/dist/components/code-editor/code-editor.js +9 -3
- package/dist/components/code-editor/index.d.ts +82 -0
- package/dist/components/code-editor/index.js +2 -0
- package/dist/components/collapsible/index.d.ts +42 -0
- package/dist/components/collapsible/index.js +2 -0
- package/dist/components/column-panel/column-panel.js +38 -0
- package/dist/components/column-panel/index.d.ts +37 -0
- package/dist/components/column-panel/index.js +3 -0
- package/dist/components/column-panel/use-panel-flag.js +27 -0
- package/dist/components/combobox/index.d.ts +28 -0
- package/dist/components/combobox/index.js +2 -0
- package/dist/components/confirmation-dialog/confirmation-dialog.js +1 -1
- package/dist/components/confirmation-dialog/index.d.ts +40 -0
- package/dist/components/confirmation-dialog/index.js +3 -0
- package/dist/components/content-container/index.d.ts +16 -0
- package/dist/components/content-container/index.js +2 -0
- package/dist/components/copiable-text/index.d.ts +33 -0
- package/dist/components/copiable-text/index.js +2 -0
- package/dist/components/coverflow/_constants/coverflow-poses.js +23 -0
- package/dist/components/coverflow/_constants/coverflow-shapes.js +23 -0
- package/dist/components/coverflow/_hooks/use-coverflow.js +90 -0
- package/dist/components/coverflow/_utils/ring.js +24 -0
- package/dist/components/coverflow/coverflow.js +198 -0
- package/dist/components/coverflow/index.d.ts +105 -0
- package/dist/components/coverflow/index.js +2 -0
- package/dist/components/data-table/data-table.js +9 -2
- package/dist/components/data-table/index.d.ts +120 -0
- package/dist/components/data-table/index.js +3 -0
- package/dist/components/date-picker/date-picker.js +5 -2
- package/dist/components/date-picker/index.d.ts +50 -0
- package/dist/components/date-picker/index.js +2 -0
- package/dist/components/date-range-picker/date-range-picker.js +11 -2
- package/dist/components/date-range-picker/index.d.ts +100 -0
- package/dist/components/date-range-picker/index.js +3 -0
- package/dist/components/date-time-picker/date-time-picker.js +5 -2
- package/dist/components/date-time-picker/index.d.ts +79 -0
- package/dist/components/date-time-picker/index.js +2 -0
- package/dist/components/device-icon/index.d.ts +17 -0
- package/dist/components/device-icon/index.js +2 -0
- package/dist/components/dialog/index.d.ts +38 -0
- package/dist/components/dialog/index.js +2 -0
- package/dist/components/dropdown-menu/index.d.ts +57 -0
- package/dist/components/dropdown-menu/index.js +2 -0
- package/dist/components/dynamic-list/dynamic-list.js +4 -4
- package/dist/components/dynamic-list/index.d.ts +74 -0
- package/dist/components/dynamic-list/index.js +2 -0
- package/dist/components/error-display/index.d.ts +17 -0
- package/dist/components/error-display/index.js +3 -0
- package/dist/components/expandable-text/expandable-text-overlay.js +78 -0
- package/dist/components/expandable-text/expandable-text.js +73 -0
- package/dist/components/expandable-text/index.d.ts +39 -0
- package/dist/components/expandable-text/index.js +2 -0
- package/dist/components/expandable-text/use-clamped.js +23 -0
- package/dist/components/facet-filters/_hooks/use-filter-group.js +51 -0
- package/dist/components/facet-filters/active-filters.js +31 -0
- package/dist/components/facet-filters/filter-group.js +110 -0
- package/dist/components/facet-filters/filters-panel.js +59 -0
- package/dist/components/facet-filters/filters-pill.js +40 -0
- package/dist/components/facet-filters/index.d.ts +104 -0
- package/dist/components/facet-filters/index.js +6 -0
- package/dist/components/facet-filters/use-filters-collapsed.js +21 -0
- package/dist/components/feature-grid/feature-grid.js +115 -0
- package/dist/components/feature-grid/index.d.ts +53 -0
- package/dist/components/feature-grid/index.js +2 -0
- package/dist/components/file-input/file-input.js +9 -3
- package/dist/components/file-input/index.d.ts +78 -0
- package/dist/components/file-input/index.js +2 -0
- package/dist/components/file-upload/file-upload.js +10 -5
- package/dist/components/file-upload/index.d.ts +38 -0
- package/dist/components/file-upload/index.js +2 -0
- package/dist/components/filters-bar/filters-bar.js +5 -1
- package/dist/components/filters-bar/index.d.ts +26 -0
- package/dist/components/filters-bar/index.js +2 -0
- package/dist/components/flip-card/flip-card.js +147 -0
- package/dist/components/flip-card/index.d.ts +43 -0
- package/dist/components/flip-card/index.js +2 -0
- package/dist/components/floating-window/_hooks/use-drag-move.js +76 -0
- package/dist/components/floating-window/floating-window.js +97 -0
- package/dist/components/floating-window/index.d.ts +45 -0
- package/dist/components/floating-window/index.js +2 -0
- package/dist/components/form/index.d.ts +28 -0
- package/dist/components/form/index.js +2 -0
- package/dist/components/fullscreen-dialog/fullscreen-dialog.js +6 -2
- package/dist/components/fullscreen-dialog/index.d.ts +38 -0
- package/dist/components/fullscreen-dialog/index.js +2 -0
- package/dist/components/horizontal-stepper/horizontal-stepper.js +122 -0
- package/dist/components/horizontal-stepper/index.d.ts +70 -0
- package/dist/components/horizontal-stepper/index.js +2 -0
- package/dist/components/icon-avatar/index.d.ts +9 -0
- package/dist/components/icon-avatar/index.js +2 -0
- package/dist/components/icon-text-action-card/icon-text-action-card.js +9 -5
- package/dist/components/icon-text-action-card/index.d.ts +11 -0
- package/dist/components/icon-text-action-card/index.js +2 -0
- package/dist/components/identicon/identicon.js +33 -0
- package/dist/components/identicon/index.d.ts +26 -0
- package/dist/components/identicon/index.js +2 -0
- package/dist/components/illustration/index.d.ts +37 -0
- package/dist/components/illustration/index.js +3 -0
- package/dist/components/index.d.ts +177 -19529
- package/dist/components/index.js +61 -10
- package/dist/components/input/index.d.ts +15 -0
- package/dist/components/input/index.js +3 -0
- package/dist/components/input-group/index.d.ts +35 -0
- package/dist/components/input-group/index.js +2 -0
- package/dist/components/input-group/input-group.js +41 -0
- package/dist/components/input-otp/index.d.ts +63 -0
- package/dist/components/input-otp/index.js +2 -0
- package/dist/components/key-value-manager/index.d.ts +63 -0
- package/dist/components/key-value-manager/index.js +2 -0
- package/dist/components/key-value-manager/key-value-manager-table.js +7 -5
- package/dist/components/label/index.d.ts +8 -0
- package/dist/components/label/index.js +2 -0
- package/dist/components/link/index.d.ts +33 -0
- package/dist/components/link/index.js +2 -0
- package/dist/components/list/index.d.ts +9 -0
- package/dist/components/list/index.js +3 -0
- package/dist/components/list/list-item.utils.js +1 -1
- package/dist/components/list/list.js +3 -1
- package/dist/components/list-details/index.d.ts +51 -0
- package/dist/components/list-details/index.js +2 -0
- package/dist/components/list-details/list-details.js +5 -2
- package/dist/components/lottie-animation-container/index.d.ts +10 -0
- package/dist/components/lottie-animation-container/index.js +2 -0
- package/dist/components/lottie-animation-container/lottie-animation-container.js +22 -3
- package/dist/components/lottie-animations/index.d.ts +8 -0
- package/dist/components/lottie-animations/index.js +2 -0
- package/dist/components/markdown-content/index.d.ts +32 -0
- package/dist/components/markdown-content/index.js +2 -0
- package/dist/components/media-card/index.d.ts +125 -0
- package/dist/components/media-card/index.js +4 -0
- package/dist/components/media-card/media-card-image.js +59 -0
- package/dist/components/media-card/media-card-reveal.js +76 -0
- package/dist/components/media-card/media-card.classes.js +37 -0
- package/dist/components/media-card/media-card.js +91 -0
- package/dist/components/media-stage/index.d.ts +41 -0
- package/dist/components/media-stage/index.js +2 -0
- package/dist/components/media-stage/media-stage.js +48 -0
- package/dist/components/menu/index.d.ts +14 -0
- package/dist/components/menu/index.js +2 -0
- package/dist/components/message-scroller/_hooks/use-follow-bottom.js +85 -0
- package/dist/components/message-scroller/index.d.ts +29 -0
- package/dist/components/message-scroller/index.js +2 -0
- package/dist/components/message-scroller/message-scroller.js +65 -0
- package/dist/components/mini-bar-chart/index.d.ts +40 -0
- package/dist/components/mini-bar-chart/index.js +2 -0
- package/dist/components/mini-bar-chart/mini-bar-chart.js +93 -0
- package/dist/components/monospace-content/index.d.ts +43 -0
- package/dist/components/monospace-content/index.js +2 -0
- package/dist/components/monospace-content/monospace-content.js +1 -1
- package/dist/components/nav-bar/index.d.ts +148 -0
- package/dist/components/nav-bar/index.js +2 -0
- package/dist/components/nav-bar/nav-bar-details-panel.js +158 -44
- package/dist/components/nav-bar/nav-bar-mobile-menu.js +93 -27
- package/dist/components/nav-bar/nav-bar.js +256 -138
- package/dist/components/nav-bar/use-nav-bar-hover-details.js +80 -0
- package/dist/components/nav-bar/use-nav-bar-overflow.js +5 -5
- package/dist/components/notice-strip/index.d.ts +32 -0
- package/dist/components/notice-strip/index.js +2 -0
- package/dist/components/notice-strip/notice-strip.js +57 -0
- package/dist/components/option-card-group/index.d.ts +50 -0
- package/dist/components/option-card-group/index.js +2 -0
- package/dist/components/option-card-group/option-card-group.js +76 -0
- package/dist/components/overflow-badge-list/index.d.ts +63 -0
- package/dist/components/overflow-badge-list/index.js +2 -0
- package/dist/components/overflow-badge-list/overflow-badge-list.js +78 -19
- package/dist/components/page-banner/index.d.ts +33 -0
- package/dist/components/page-banner/index.js +2 -0
- package/dist/components/page-banner/page-banner.js +56 -0
- package/dist/components/page-container/index.d.ts +20 -0
- package/dist/components/page-container/index.js +3 -0
- package/dist/components/page-container/page-container.js +5 -5
- package/dist/components/pagination/index.d.ts +31 -0
- package/dist/components/pagination/index.js +3 -0
- package/dist/components/popover/index.d.ts +60 -0
- package/dist/components/popover/index.js +3 -0
- package/dist/components/preview-card/index.d.ts +24 -0
- package/dist/components/preview-card/index.js +2 -0
- package/dist/components/progress-bar/index.d.ts +32 -0
- package/dist/components/progress-bar/index.js +2 -0
- package/dist/components/progress-bar/progress-bar.js +22 -6
- package/dist/components/radio-group/index.d.ts +24 -0
- package/dist/components/radio-group/index.js +2 -0
- package/dist/components/rank-numeral/index.d.ts +30 -0
- package/dist/components/rank-numeral/index.js +2 -0
- package/dist/components/rank-numeral/rank-numeral.js +26 -0
- package/dist/components/reaction-button/index.d.ts +32 -0
- package/dist/components/reaction-button/index.js +2 -0
- package/dist/components/reaction-button/reaction-button.js +50 -0
- package/dist/components/readout/index.d.ts +31 -0
- package/dist/components/readout/index.js +2 -0
- package/dist/components/readout/readout.js +63 -0
- package/dist/components/requirement-list/index.d.ts +52 -0
- package/dist/components/requirement-list/index.js +2 -0
- package/dist/components/requirement-list/requirement-list.js +29 -8
- package/dist/components/resizable/index.d.ts +31 -0
- package/dist/components/resizable/index.js +4 -0
- package/dist/components/resizable/resizable-group.js +23 -0
- package/dist/components/resizable/resizable-panel.js +28 -0
- package/dist/components/resizable/resizable-separator.js +24 -0
- package/dist/components/reveal/index.d.ts +23 -0
- package/dist/components/reveal/index.js +2 -0
- package/dist/components/reveal/reveal.js +24 -0
- package/dist/components/scroll-area/index.d.ts +27 -0
- package/dist/components/scroll-area/index.js +2 -0
- package/dist/components/scrollable-sections/index.d.ts +58 -0
- package/dist/components/scrollable-sections/index.js +2 -0
- package/dist/components/scrollable-sections/scrollable-sections.js +11 -3
- package/dist/components/search-box/index.d.ts +32 -0
- package/dist/components/search-box/index.js +2 -0
- package/dist/components/search-box/search-box.js +18 -3
- package/dist/components/search-field-shell.js +1 -1
- package/dist/components/select/index.d.ts +44 -0
- package/dist/components/select/index.js +2 -0
- package/dist/components/selectable-card-list/checkbox-card-list.js +5 -3
- package/dist/components/selectable-card-list/index.d.ts +76 -0
- package/dist/components/selectable-card-list/index.js +2 -0
- package/dist/components/selectable-card-list/radio-card-list.js +12 -6
- package/dist/components/selectable-card-list/selectable-card-list-shared.js +24 -12
- package/dist/components/selectable-card-list/selectable-card-list.js +12 -3
- package/dist/components/separator/index.d.ts +24 -0
- package/dist/components/separator/index.js +2 -0
- package/dist/components/share-menu/index.d.ts +55 -0
- package/dist/components/share-menu/index.js +2 -0
- package/dist/components/share-menu/share-marks.js +31 -0
- package/dist/components/share-menu/share-menu.js +140 -0
- package/dist/components/share-menu/share-urls.js +15 -0
- package/dist/components/sheet/index.d.ts +41 -0
- package/dist/components/sheet/index.js +2 -0
- package/dist/components/showcase-card/index.d.ts +53 -0
- package/dist/components/showcase-card/index.js +2 -0
- package/dist/components/showcase-card/showcase-card.js +75 -0
- package/dist/components/sidebar/index.d.ts +109 -0
- package/dist/components/sidebar/index.js +4 -0
- package/dist/components/sidebar/sidebar.js +56 -40
- package/dist/components/simple-clickable-card/index.d.ts +11 -0
- package/dist/components/simple-clickable-card/index.js +2 -0
- package/dist/components/simple-clickable-card/simple-clickable-card-shared.js +2 -2
- package/dist/components/simple-clickable-card/simple-clickable-card.js +5 -2
- package/dist/components/simple-info-card/index.d.ts +25 -0
- package/dist/components/simple-info-card/index.js +2 -0
- package/dist/components/simple-info-card/simple-info-card.js +6 -3
- package/dist/components/simple-list/index.d.ts +63 -0
- package/dist/components/simple-list/index.js +2 -0
- package/dist/components/simple-list/simple-list.js +3 -1
- package/dist/components/simple-paginated-list/index.d.ts +20 -0
- package/dist/components/simple-paginated-list/index.js +2 -0
- package/dist/components/simplified-date/index.d.ts +18 -0
- package/dist/components/simplified-date/index.js +2 -0
- package/dist/components/skeleton/index.d.ts +5 -0
- package/dist/components/skeleton/index.js +2 -0
- package/dist/components/skeletons/index.d.ts +11 -0
- package/dist/components/skeletons/index.js +2 -0
- package/dist/components/sort-menu/index.d.ts +34 -0
- package/dist/components/sort-menu/index.js +2 -0
- package/dist/components/sort-menu/sort-menu.js +39 -0
- package/dist/components/spinner/index.d.ts +15 -0
- package/dist/components/spinner/index.js +2 -0
- package/dist/components/stat-card/index.d.ts +43 -0
- package/dist/components/stat-card/index.js +2 -0
- package/dist/components/stat-card/stat-card.js +31 -12
- package/dist/components/status-badge/index.d.ts +24 -0
- package/dist/components/status-badge/index.js +2 -0
- package/dist/components/status-badge/status-badge.js +3 -2
- package/dist/components/status-card-list/index.d.ts +24 -0
- package/dist/components/status-card-list/index.js +2 -0
- package/dist/components/status-card-list/status-card-list.js +8 -4
- package/dist/components/step-tabs/index.d.ts +94 -0
- package/dist/components/step-tabs/index.js +2 -0
- package/dist/components/step-tabs/step-tabs.js +202 -0
- package/dist/components/style-scope/index.d.ts +32 -0
- package/dist/components/style-scope/index.js +2 -0
- package/dist/components/style-scope/style-scope.js +49 -0
- package/dist/components/switch/index.d.ts +15 -0
- package/dist/components/switch/index.js +2 -0
- package/dist/components/table/index.d.ts +18 -0
- package/dist/components/table/index.js +2 -0
- package/dist/components/tabs/index.d.ts +103 -0
- package/dist/components/tabs/index.js +2 -0
- package/dist/components/tag/index.d.ts +31 -0
- package/dist/components/tag/index.js +2 -0
- package/dist/components/tag/tag.js +79 -28
- package/dist/components/tag-input/index.d.ts +36 -0
- package/dist/components/tag-input/index.js +2 -0
- package/dist/components/tag-input/tag-input.js +10 -4
- package/dist/components/text-effects/index.d.ts +53 -0
- package/dist/components/text-effects/index.js +6 -0
- package/dist/components/textarea/index.d.ts +16 -0
- package/dist/components/textarea/index.js +2 -0
- package/dist/components/thumbnail-strip/index.d.ts +42 -0
- package/dist/components/thumbnail-strip/index.js +2 -0
- package/dist/components/thumbnail-strip/thumbnail-strip.js +124 -0
- package/dist/components/thumbnail-strip/use-scroll-edges.js +41 -0
- package/dist/components/time-picker/index.d.ts +13 -0
- package/dist/components/time-picker/index.js +2 -0
- package/dist/components/timeline/index.d.ts +39 -0
- package/dist/components/timeline/index.js +2 -0
- package/dist/components/timeline/timeline.js +85 -0
- package/dist/components/toast/index.d.ts +56 -0
- package/dist/components/toast/index.js +2 -0
- package/dist/components/toast/toast.js +42 -32
- package/dist/components/togglable-items-list/index.d.ts +28 -0
- package/dist/components/togglable-items-list/index.js +2 -0
- package/dist/components/toggle-group/index.d.ts +35 -0
- package/dist/components/toggle-group/index.js +2 -0
- package/dist/components/toolbar/index.d.ts +58 -0
- package/dist/components/toolbar/index.js +3 -0
- package/dist/components/toolbar/toolbar-button.js +40 -0
- package/dist/components/toolbar/toolbar.js +56 -0
- package/dist/components/tooltip/index.d.ts +29 -0
- package/dist/components/tooltip/index.js +3 -0
- package/dist/components/tooltip/tooltip.js +12 -2
- package/dist/components/transfer-list/index.d.ts +36 -0
- package/dist/components/transfer-list/index.js +2 -0
- package/dist/components/transfer-list/transfer-list.js +1 -1
- package/dist/components/truncated-line-with-tooltip/index.d.ts +22 -0
- package/dist/components/truncated-line-with-tooltip/index.js +2 -0
- package/dist/components/truncated-line-with-tooltip/truncated-line-with-tooltip.js +26 -8
- package/dist/components/typography/index.d.ts +19 -0
- package/dist/components/typography/index.js +3 -0
- package/dist/components/use-mobile/index.d.ts +3 -0
- package/dist/components/use-mobile/index.js +2 -0
- package/dist/components/user-type-badge/index.d.ts +39 -0
- package/dist/components/user-type-badge/index.js +3 -0
- package/dist/components/user-type-badge/user-type-badge.js +2 -1
- package/dist/components/vertical-stepper/index.d.ts +7 -0
- package/dist/components/vertical-stepper/index.js +2 -0
- package/dist/components/vertical-stepper/vertical-stepper.js +33 -6
- package/dist/components/view-toggle/index.d.ts +38 -0
- package/dist/components/view-toggle/index.js +2 -0
- package/dist/components/view-toggle/view-toggle.js +56 -0
- package/dist/core/animate-ui/components/animate/code.js +83 -9
- package/dist/core/animate-ui/components/animate/tabs.js +234 -19
- package/dist/core/animate-ui/components/animate/tooltip.js +10 -2
- package/dist/core/animate-ui/components/base/preview-card.js +20 -3
- package/dist/core/animate-ui/components/buttons/copy.js +12 -6
- package/dist/core/animate-ui/components/radix/dialog.js +17 -3
- package/dist/core/animate-ui/components/radix/dropdown-menu.js +26 -9
- package/dist/core/animate-ui/components/radix/sheet.js +20 -4
- package/dist/core/animate-ui/components/radix/sidebar.js +9 -9
- package/dist/core/animate-ui/components/radix/toggle-group.js +103 -13
- package/dist/core/animate-ui/components/radix/toggle.js +5 -5
- package/dist/core/animate-ui/primitives/animate/code-block.js +31 -4
- package/dist/core/animate-ui/primitives/animate/shiki-highlighter.js +5 -2
- package/dist/core/animate-ui/primitives/animate/tabs.js +7 -4
- package/dist/core/animate-ui/primitives/animate/tooltip.js +10 -3
- package/dist/core/animate-ui/primitives/base/preview-card.js +2 -2
- package/dist/core/animate-ui/primitives/base/progress.js +1 -1
- package/dist/core/animate-ui/primitives/base/radio.js +3 -3
- package/dist/core/animate-ui/primitives/effects/highlight.js +1 -0
- package/dist/core/animate-ui/primitives/radix/accordion.js +1 -1
- package/dist/core/animate-ui/primitives/radix/dialog.js +6 -3
- package/dist/core/animate-ui/primitives/radix/dropdown-menu.js +2 -2
- package/dist/core/animate-ui/primitives/radix/sheet.js +7 -3
- package/dist/core/animate-ui/primitives/radix/switch.js +2 -2
- package/dist/core/animate-ui/primitives/radix/toggle-group.js +2 -2
- package/dist/core/badge.js +5 -2
- package/dist/core/breadcrumb.js +1 -1
- package/dist/core/button/button.js +8 -8
- package/dist/core/button/craft-button.js +8 -2
- package/dist/core/button.js +17 -7
- package/dist/core/card.js +23 -5
- package/dist/core/combobox/combobox.js +8 -2
- package/dist/core/command.js +3 -3
- package/dist/core/form.js +1 -1
- package/dist/core/hooks/use-nested-layer-press-guard.js +46 -0
- package/dist/core/hooks/use-on-screen.js +33 -0
- package/dist/core/hooks/use-prefers-reduced-motion.js +19 -0
- package/dist/core/hooks/use-scroll-overflow.js +20 -0
- package/dist/core/index.d.ts +30 -5
- package/dist/core/index.js +5 -2
- package/dist/core/input/input-password.js +13 -9
- package/dist/core/input/input.js +38 -12
- package/dist/core/input-otp/input-otp.js +9 -5
- package/dist/core/popover-group.js +48 -0
- package/dist/core/popover-hover.js +127 -0
- package/dist/core/popover.js +75 -6
- package/dist/core/select.js +35 -20
- package/dist/core/table.js +5 -3
- package/dist/core/textarea/textarea.js +11 -3
- package/dist/data-table/index.d.ts +4 -0
- package/dist/data-table/index.js +3 -0
- package/dist/date/index.d.ts +11 -0
- package/dist/date/index.js +7 -0
- package/dist/forms/index.d.ts +4 -0
- package/dist/forms/index.js +2 -0
- package/dist/icon-avatar.props-RYtw2eSW.d.ts +31 -0
- package/dist/icon-text-action-card.props-B2ggncUK.d.ts +53 -0
- package/dist/index.d.ts +169 -15
- package/dist/index.js +63 -10
- package/dist/input-CYI1hhGc.d.ts +38 -0
- package/dist/layouts/index.d.ts +132 -8
- package/dist/layouts/index.js +3 -1
- package/dist/layouts/minimal-workspace-layout/minimal-workspace-layout-context.js +5 -0
- package/dist/layouts/minimal-workspace-layout/minimal-workspace-layout.js +404 -0
- package/dist/layouts/minimal-workspace-layout/rail-logo.js +90 -0
- package/dist/layouts/minimal-workspace-layout/sidebar-trigger.js +42 -0
- package/dist/layouts/shared/account-menu-props.js +21 -0
- package/dist/layouts/shared/footer-branding.js +34 -0
- package/dist/layouts/shared/sidebar-logo.js +59 -0
- package/dist/layouts/workspace-layout/account-menu/account-menu.js +9 -3
- package/dist/layouts/workspace-layout/footer/footer.js +1 -1
- package/dist/layouts/workspace-layout/header/header.js +1 -1
- package/dist/layouts/workspace-layout/workspace-layout.js +28 -80
- package/dist/{list.props-x1j3CbcF.d.ts → list.props-DP_xPTqU.d.ts} +2 -1
- package/dist/markdown/index.d.ts +11 -0
- package/dist/markdown/index.js +5 -0
- package/dist/my-account-menu.props-C7DK71WC.d.ts +67 -0
- package/dist/page-container.props-JutTvKFq.d.ts +48 -0
- package/dist/resizable.props-RxFY5tm_.d.ts +44 -0
- package/dist/section-card-B7c5uc08.d.ts +84 -0
- package/dist/simple-clickable-card.props-BrPCw7CR.d.ts +51 -0
- package/dist/slot-DGErA9zi.d.ts +10 -0
- package/dist/status-badge.props-lKlEOfRt.d.ts +32 -0
- package/dist/style-axes-DSQ2DGc5.d.ts +133 -0
- package/dist/toast/index.d.ts +6 -0
- package/dist/toast/index.js +2 -0
- package/dist/tooltip-C0bYa8a3.d.ts +37 -0
- package/dist/{types-DtUxK-Am.d.ts → types-CkXflqg7.d.ts} +31 -1
- package/dist/utils/cn.js +6 -1
- package/dist/utils/color.js +35 -10
- package/dist/utils/index.d.ts +18 -2
- package/dist/utils/index.js +4 -1
- package/dist/utils/silver-shine.js +16 -1
- package/dist/utils/style-axes.js +227 -0
- package/dist/utils/variant.js +104 -8
- package/dist/utils/view-transition.js +21 -0
- package/dist/variant-D81RhpbR.d.ts +104 -0
- package/dist/vertical-stepper.props-BXYcbW70.d.ts +29 -0
- package/package.json +52 -6
- package/src/styles/colors.css +100 -4
- package/src/styles/globals.css +8 -131
- package/src/styles/style-axes.css +21 -0
- package/src/styles/theme.css +696 -0
- package/dist/app-logo.props-Ct7QBdTd.d.ts +0 -40
- package/dist/popover-ByLD3-Qv.d.ts +0 -204
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
interface ExpandableTextLabels {
|
|
5
|
+
/** The link under clamped text ("Show more"). */
|
|
6
|
+
more: string;
|
|
7
|
+
/** Inline mode: the link under the full text ("Show less"). */
|
|
8
|
+
less: string;
|
|
9
|
+
/** Overlay mode: the close button's accessible name ("Close"). */
|
|
10
|
+
close: string;
|
|
11
|
+
}
|
|
12
|
+
interface ExpandableTextProps {
|
|
13
|
+
/** The text. Line breaks are kept. */
|
|
14
|
+
children: string;
|
|
15
|
+
/** Lines shown before it is clamped, 1 to 6. Default `2`. */
|
|
16
|
+
lines?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
17
|
+
/**
|
|
18
|
+
* `inline` grows in place. `overlay` keeps its own height and opens the full
|
|
19
|
+
* text over the nearest positioned ancestor (a card), so nothing around it
|
|
20
|
+
* moves; the ancestor needs `relative`. Default `inline`.
|
|
21
|
+
*/
|
|
22
|
+
mode?: "inline" | "overlay";
|
|
23
|
+
/** Already-translated labels. */
|
|
24
|
+
labels: ExpandableTextLabels;
|
|
25
|
+
/** Overlay mode: shown above the full text (the title it belongs to). */
|
|
26
|
+
header?: ReactNode;
|
|
27
|
+
/** Overlay mode: shown under the full text (tags, a byline). */
|
|
28
|
+
footer?: ReactNode;
|
|
29
|
+
className?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Text clamped to a few lines with a "Show more" link — shown only when the
|
|
34
|
+
* text really is cut off. `inline` grows in place; `overlay` opens the full
|
|
35
|
+
* text over its card, so the card never changes height.
|
|
36
|
+
*/
|
|
37
|
+
declare function ExpandableText({ children, lines, mode, labels, header, footer, className }: ExpandableTextProps): React.JSX.Element;
|
|
38
|
+
|
|
39
|
+
export { ExpandableText, type ExpandableTextLabels, type ExpandableTextProps };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
//#region src/components/expandable-text/use-clamped.ts
|
|
3
|
+
/**
|
|
4
|
+
* Whether the element's text is cut off by its line clamp, kept current as the
|
|
5
|
+
* element resizes. Measured, not guessed from the length: the same sentence
|
|
6
|
+
* fits on a wide card and clamps on a phone.
|
|
7
|
+
*/
|
|
8
|
+
function useClamped(ref, enabled) {
|
|
9
|
+
const [clamped, setClamped] = useState(false);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const el = ref.current;
|
|
12
|
+
if (!el || !enabled) return;
|
|
13
|
+
const measure = () => setClamped(el.scrollHeight > el.clientHeight + 1);
|
|
14
|
+
measure();
|
|
15
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
16
|
+
const observer = new ResizeObserver(measure);
|
|
17
|
+
observer.observe(el);
|
|
18
|
+
return () => observer.disconnect();
|
|
19
|
+
}, [ref, enabled]);
|
|
20
|
+
return clamped;
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
export { useClamped };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useMemo, useState } from "react";
|
|
2
|
+
//#region src/components/facet-filters/_hooks/use-filter-group.ts
|
|
3
|
+
/** Options a filter group shows before "Show more", and how many each click adds. */
|
|
4
|
+
var GROUP_INITIAL = 3;
|
|
5
|
+
var GROUP_STEP = 5;
|
|
6
|
+
/**
|
|
7
|
+
* What a filter group shows: the first few options, five more per "Show more",
|
|
8
|
+
* every match while its own search is open — and every TICKED option always,
|
|
9
|
+
* even past the limit, so a choice never disappears.
|
|
10
|
+
*/
|
|
11
|
+
function useFilterGroup(options, selected) {
|
|
12
|
+
const [view, setView] = useState({
|
|
13
|
+
limit: GROUP_INITIAL,
|
|
14
|
+
find: null
|
|
15
|
+
});
|
|
16
|
+
const visible = useMemo(() => {
|
|
17
|
+
const needle = view.find?.trim().toLowerCase();
|
|
18
|
+
if (needle !== void 0 && needle !== "") return options.filter((option) => option.label.toLowerCase().includes(needle));
|
|
19
|
+
if (view.find !== null) return options;
|
|
20
|
+
return options.filter((option, index) => index < view.limit || selected.includes(option.value));
|
|
21
|
+
}, [
|
|
22
|
+
options,
|
|
23
|
+
selected,
|
|
24
|
+
view
|
|
25
|
+
]);
|
|
26
|
+
return {
|
|
27
|
+
visible,
|
|
28
|
+
hidden: view.find === null ? options.length - visible.length : 0,
|
|
29
|
+
canShowLess: view.find === null && view.limit > GROUP_INITIAL,
|
|
30
|
+
searching: view.find !== null,
|
|
31
|
+
find: view.find ?? "",
|
|
32
|
+
showMore: () => setView((v) => ({
|
|
33
|
+
...v,
|
|
34
|
+
limit: v.limit + GROUP_STEP
|
|
35
|
+
})),
|
|
36
|
+
showLess: () => setView((v) => ({
|
|
37
|
+
...v,
|
|
38
|
+
limit: GROUP_INITIAL
|
|
39
|
+
})),
|
|
40
|
+
toggleSearch: () => setView((v) => ({
|
|
41
|
+
...v,
|
|
42
|
+
find: v.find === null ? "" : null
|
|
43
|
+
})),
|
|
44
|
+
setFind: (find) => setView((v) => ({
|
|
45
|
+
...v,
|
|
46
|
+
find
|
|
47
|
+
}))
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { GROUP_INITIAL, GROUP_STEP, useFilterGroup };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Button } from "../button/button.js";
|
|
2
|
+
import { Tag as Tag$1 } from "../tag/tag.js";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { X } from "lucide-react";
|
|
5
|
+
//#region src/components/facet-filters/active-filters.tsx
|
|
6
|
+
/** What is narrowing the list, each removable, and "Clear all". Nothing when nothing is. */
|
|
7
|
+
function ActiveFilters({ tags, clearLabel, onClearAll }) {
|
|
8
|
+
if (tags.length === 0) return null;
|
|
9
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
10
|
+
"data-slot": "active-filters",
|
|
11
|
+
className: "flex flex-wrap items-center gap-2",
|
|
12
|
+
children: [tags.map((tag) => /* @__PURE__ */ jsx(Tag$1, {
|
|
13
|
+
value: tag.label,
|
|
14
|
+
variant: "outline",
|
|
15
|
+
color: "silver",
|
|
16
|
+
size: "sm",
|
|
17
|
+
rounded: true,
|
|
18
|
+
onDelete: tag.onDelete
|
|
19
|
+
}, tag.key)), /* @__PURE__ */ jsx(Button, {
|
|
20
|
+
variant: "ghost",
|
|
21
|
+
color: "error",
|
|
22
|
+
size: "sm",
|
|
23
|
+
fullWidth: false,
|
|
24
|
+
startIcon: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" }),
|
|
25
|
+
onClick: onClearAll,
|
|
26
|
+
children: clearLabel
|
|
27
|
+
})]
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export { ActiveFilters };
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { cn } from "../../utils/cn.js";
|
|
2
|
+
import { Button } from "../button/button.js";
|
|
3
|
+
import { Typography } from "../typography/typography.js";
|
|
4
|
+
import { Checkbox } from "../../core/checkbox/motion-checkbox.js";
|
|
5
|
+
import SearchBox from "../search-box/search-box.js";
|
|
6
|
+
import { GROUP_STEP, useFilterGroup } from "./_hooks/use-filter-group.js";
|
|
7
|
+
import { useId } from "react";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
import { ChevronDown, ChevronUp, Search } from "lucide-react";
|
|
10
|
+
//#region src/components/facet-filters/filter-group.tsx
|
|
11
|
+
var RISE_DELAY = [
|
|
12
|
+
"delay-0",
|
|
13
|
+
"delay-75",
|
|
14
|
+
"delay-150"
|
|
15
|
+
];
|
|
16
|
+
/** One filter group: its options with counts, "Show more", and a search of its own. */
|
|
17
|
+
function FilterGroup({ group, selected, onToggle, order, animate, labels }) {
|
|
18
|
+
const headingId = useId();
|
|
19
|
+
const view = useFilterGroup(group.options, selected);
|
|
20
|
+
const lower = group.title.toLowerCase();
|
|
21
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
22
|
+
"aria-labelledby": headingId,
|
|
23
|
+
"data-slot": "filter-group",
|
|
24
|
+
className: cn("flex flex-col gap-2 border-t border-border pt-4", animate && "motion-safe:animate-rise-in", animate && RISE_DELAY[order % RISE_DELAY.length]),
|
|
25
|
+
children: [
|
|
26
|
+
/* @__PURE__ */ jsxs("div", {
|
|
27
|
+
className: "flex items-center justify-between",
|
|
28
|
+
children: [/* @__PURE__ */ jsx(Typography, {
|
|
29
|
+
id: headingId,
|
|
30
|
+
variant: "subtitle2",
|
|
31
|
+
as: "h3",
|
|
32
|
+
className: "m-0 text-foreground",
|
|
33
|
+
children: group.title
|
|
34
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
35
|
+
variant: "ghost",
|
|
36
|
+
size: "icon",
|
|
37
|
+
fullWidth: false,
|
|
38
|
+
"aria-label": labels.searchGroup(lower),
|
|
39
|
+
"aria-pressed": view.searching,
|
|
40
|
+
startIcon: /* @__PURE__ */ jsx(Search, { className: "h-4 w-4" }),
|
|
41
|
+
onClick: view.toggleSearch
|
|
42
|
+
})]
|
|
43
|
+
}),
|
|
44
|
+
view.searching && /* @__PURE__ */ jsx(SearchBox, {
|
|
45
|
+
size: "sm",
|
|
46
|
+
value: view.find,
|
|
47
|
+
onValueChange: view.setFind,
|
|
48
|
+
onSearch: view.setFind,
|
|
49
|
+
onClear: () => view.setFind(""),
|
|
50
|
+
placeholder: labels.searchGroupPlaceholder(lower),
|
|
51
|
+
"aria-label": labels.searchGroupPlaceholder(lower)
|
|
52
|
+
}),
|
|
53
|
+
/* @__PURE__ */ jsx("ul", {
|
|
54
|
+
className: "m-0 flex list-none flex-col gap-1 p-0",
|
|
55
|
+
children: view.visible.map((option) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("label", {
|
|
56
|
+
className: "flex cursor-pointer items-center gap-2 rounded-md px-1 py-1 text-sm text-foreground hover:bg-accent",
|
|
57
|
+
children: [
|
|
58
|
+
/* @__PURE__ */ jsx(Checkbox, {
|
|
59
|
+
checked: selected.includes(option.value),
|
|
60
|
+
onCheckedChange: () => onToggle(group.id, option.value)
|
|
61
|
+
}),
|
|
62
|
+
/* @__PURE__ */ jsx("span", {
|
|
63
|
+
className: "min-w-0 flex-1 truncate",
|
|
64
|
+
children: option.label
|
|
65
|
+
}),
|
|
66
|
+
/* @__PURE__ */ jsx("span", {
|
|
67
|
+
className: "font-mono text-xs text-foreground-muted",
|
|
68
|
+
children: option.count
|
|
69
|
+
})
|
|
70
|
+
]
|
|
71
|
+
}) }, option.value))
|
|
72
|
+
}),
|
|
73
|
+
view.searching && view.visible.length === 0 && /* @__PURE__ */ jsx(Typography, {
|
|
74
|
+
variant: "body2",
|
|
75
|
+
className: "m-0 px-1 text-foreground-muted",
|
|
76
|
+
children: labels.noOptions
|
|
77
|
+
}),
|
|
78
|
+
/* @__PURE__ */ jsx(GroupMoreLess, {
|
|
79
|
+
hidden: view.hidden,
|
|
80
|
+
canShowLess: view.canShowLess,
|
|
81
|
+
onMore: view.showMore,
|
|
82
|
+
onLess: view.showLess,
|
|
83
|
+
labels
|
|
84
|
+
})
|
|
85
|
+
]
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function GroupMoreLess({ hidden, canShowLess, onMore, onLess, labels }) {
|
|
89
|
+
if (hidden > 0) return /* @__PURE__ */ jsx(Button, {
|
|
90
|
+
variant: "ghost",
|
|
91
|
+
size: "sm",
|
|
92
|
+
fullWidth: false,
|
|
93
|
+
className: "self-start",
|
|
94
|
+
startIcon: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" }),
|
|
95
|
+
onClick: onMore,
|
|
96
|
+
children: labels.showMore(Math.min(hidden, GROUP_STEP))
|
|
97
|
+
});
|
|
98
|
+
if (canShowLess) return /* @__PURE__ */ jsx(Button, {
|
|
99
|
+
variant: "ghost",
|
|
100
|
+
size: "sm",
|
|
101
|
+
fullWidth: false,
|
|
102
|
+
className: "self-start",
|
|
103
|
+
startIcon: /* @__PURE__ */ jsx(ChevronUp, { className: "h-4 w-4" }),
|
|
104
|
+
onClick: onLess,
|
|
105
|
+
children: labels.showLess
|
|
106
|
+
});
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
//#endregion
|
|
110
|
+
export { FilterGroup };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { cn } from "../../utils/cn.js";
|
|
2
|
+
import { Button } from "../button/button.js";
|
|
3
|
+
import { Typography } from "../typography/typography.js";
|
|
4
|
+
import { Badge } from "../../core/badge.js";
|
|
5
|
+
import { FilterGroup } from "./filter-group.js";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { PanelLeftClose, SlidersHorizontal } from "lucide-react";
|
|
8
|
+
//#region src/components/facet-filters/filters-panel.tsx
|
|
9
|
+
/** The side panel: every filter group, and the button that folds it into the pill. */
|
|
10
|
+
function FiltersPanel({ groups, selected, activeCount, onToggle, onCollapse, animate, labels, children }) {
|
|
11
|
+
return /* @__PURE__ */ jsxs("aside", {
|
|
12
|
+
"aria-label": labels.title,
|
|
13
|
+
"data-slot": "filters-panel",
|
|
14
|
+
className: cn("view-transition-morph flex flex-col gap-4 rounded-2xl border border-border bg-card p-4", animate && "motion-safe:animate-slide-in-start"),
|
|
15
|
+
children: [
|
|
16
|
+
/* @__PURE__ */ jsxs("div", {
|
|
17
|
+
className: "flex items-center gap-2",
|
|
18
|
+
children: [
|
|
19
|
+
/* @__PURE__ */ jsx(SlidersHorizontal, {
|
|
20
|
+
className: "h-4 w-4 text-foreground-secondary",
|
|
21
|
+
"aria-hidden": true
|
|
22
|
+
}),
|
|
23
|
+
/* @__PURE__ */ jsxs(Typography, {
|
|
24
|
+
variant: "subtitle1",
|
|
25
|
+
as: "h2",
|
|
26
|
+
className: "m-0 flex-1 text-foreground",
|
|
27
|
+
children: [labels.title, activeCount > 0 && /* @__PURE__ */ jsx(Badge, {
|
|
28
|
+
variant: "soft",
|
|
29
|
+
color: "primary",
|
|
30
|
+
radius: "full",
|
|
31
|
+
className: "ml-2 font-mono",
|
|
32
|
+
children: labels.activeCount(activeCount)
|
|
33
|
+
})]
|
|
34
|
+
}),
|
|
35
|
+
/* @__PURE__ */ jsx(Button, {
|
|
36
|
+
variant: "ghost",
|
|
37
|
+
size: "icon",
|
|
38
|
+
fullWidth: false,
|
|
39
|
+
"aria-label": labels.collapse,
|
|
40
|
+
tooltip: labels.collapse,
|
|
41
|
+
startIcon: /* @__PURE__ */ jsx(PanelLeftClose, { className: "h-4 w-4" }),
|
|
42
|
+
onClick: onCollapse
|
|
43
|
+
})
|
|
44
|
+
]
|
|
45
|
+
}),
|
|
46
|
+
children,
|
|
47
|
+
groups.filter((group) => group.options.length > 0).map((group, index) => /* @__PURE__ */ jsx(FilterGroup, {
|
|
48
|
+
group,
|
|
49
|
+
selected: selected[group.id] ?? [],
|
|
50
|
+
onToggle,
|
|
51
|
+
order: index,
|
|
52
|
+
animate,
|
|
53
|
+
labels
|
|
54
|
+
}, group.id))
|
|
55
|
+
]
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
export { FiltersPanel };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { cn } from "../../utils/cn.js";
|
|
2
|
+
import { Button } from "../button/button.js";
|
|
3
|
+
import { Badge } from "../../core/badge.js";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { SlidersHorizontal } from "lucide-react";
|
|
6
|
+
//#region src/components/facet-filters/filters-pill.tsx
|
|
7
|
+
/**
|
|
8
|
+
* The folded filters: a floating button at the bottom of the screen, level
|
|
9
|
+
* with the content's left edge in a 1180px measure (centred on phones). It is
|
|
10
|
+
* the panel itself, morphed — the two share one view-transition name and are
|
|
11
|
+
* never shown together.
|
|
12
|
+
*/
|
|
13
|
+
function FiltersPill({ activeCount, onExpand, animate, labels }) {
|
|
14
|
+
return /* @__PURE__ */ jsx("div", {
|
|
15
|
+
"data-slot": "filters-pill",
|
|
16
|
+
className: "pointer-events-none fixed inset-x-0 bottom-6 z-40",
|
|
17
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
18
|
+
className: "mx-auto flex w-full max-w-295 justify-center px-4 lg:justify-start",
|
|
19
|
+
children: /* @__PURE__ */ jsxs(Button, {
|
|
20
|
+
color: "primary",
|
|
21
|
+
fullWidth: false,
|
|
22
|
+
radius: "full",
|
|
23
|
+
"aria-expanded": false,
|
|
24
|
+
title: labels.expand,
|
|
25
|
+
startIcon: /* @__PURE__ */ jsx(SlidersHorizontal, { className: "h-4 w-4 transition-transform group-hover:-rotate-12" }),
|
|
26
|
+
className: cn("group view-transition-morph pointer-events-auto shadow-lg transition-transform hover:-translate-y-0.5", animate && "motion-safe:animate-pop-in"),
|
|
27
|
+
onClick: onExpand,
|
|
28
|
+
children: [labels.title, activeCount > 0 && /* @__PURE__ */ jsx(Badge, {
|
|
29
|
+
variant: "solid",
|
|
30
|
+
color: "secondary",
|
|
31
|
+
radius: "full",
|
|
32
|
+
className: "ml-1 font-mono",
|
|
33
|
+
children: activeCount
|
|
34
|
+
})]
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { FiltersPill };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
interface FacetFilterOption {
|
|
5
|
+
value: string;
|
|
6
|
+
label: string;
|
|
7
|
+
count: number;
|
|
8
|
+
}
|
|
9
|
+
interface FacetFilterGroup {
|
|
10
|
+
id: string;
|
|
11
|
+
title: string;
|
|
12
|
+
options: FacetFilterOption[];
|
|
13
|
+
}
|
|
14
|
+
/** What is ticked, by group id. */
|
|
15
|
+
type FacetSelection = Record<string, string[]>;
|
|
16
|
+
interface FacetFiltersLabels {
|
|
17
|
+
/** The panel's heading and the pill's text. */
|
|
18
|
+
title: string;
|
|
19
|
+
activeCount: (count: number) => string;
|
|
20
|
+
collapse: string;
|
|
21
|
+
expand: string;
|
|
22
|
+
/** A group's own search toggle and field, given the group's title in lower case. */
|
|
23
|
+
searchGroup: (group: string) => string;
|
|
24
|
+
searchGroupPlaceholder: (group: string) => string;
|
|
25
|
+
showMore: (count: number) => string;
|
|
26
|
+
showLess: string;
|
|
27
|
+
noOptions: string;
|
|
28
|
+
}
|
|
29
|
+
/** One removable tag above the results. */
|
|
30
|
+
interface ActiveFilterTag {
|
|
31
|
+
key: string;
|
|
32
|
+
label: string;
|
|
33
|
+
onDelete: () => void;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface FiltersPanelProps {
|
|
37
|
+
/** Every group, counted and labelled by the page. A group with no options is left out. */
|
|
38
|
+
groups: FacetFilterGroup[];
|
|
39
|
+
selected: FacetSelection;
|
|
40
|
+
activeCount: number;
|
|
41
|
+
onToggle: (groupId: string, value: string) => void;
|
|
42
|
+
onCollapse: () => void;
|
|
43
|
+
/** Play the CSS entrance (only where the browser cannot morph it in). */
|
|
44
|
+
animate: boolean;
|
|
45
|
+
labels: FacetFiltersLabels;
|
|
46
|
+
/** Shown under the heading, above the groups (a page's own switch, like "On my bench"). */
|
|
47
|
+
children?: ReactNode;
|
|
48
|
+
}
|
|
49
|
+
interface FilterGroupProps {
|
|
50
|
+
group: FacetFilterGroup;
|
|
51
|
+
selected: string[];
|
|
52
|
+
onToggle: (groupId: string, value: string) => void;
|
|
53
|
+
/** Entrance order, for the staggered rise-in where view transitions are missing. */
|
|
54
|
+
order: number;
|
|
55
|
+
animate: boolean;
|
|
56
|
+
labels: FacetFiltersLabels;
|
|
57
|
+
}
|
|
58
|
+
interface FiltersPillProps {
|
|
59
|
+
activeCount: number;
|
|
60
|
+
onExpand: () => void;
|
|
61
|
+
animate: boolean;
|
|
62
|
+
labels: {
|
|
63
|
+
title: string;
|
|
64
|
+
expand: string;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
interface ActiveFiltersProps {
|
|
68
|
+
tags: ActiveFilterTag[];
|
|
69
|
+
clearLabel: string;
|
|
70
|
+
onClearAll: () => void;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** What is narrowing the list, each removable, and "Clear all". Nothing when nothing is. */
|
|
74
|
+
declare function ActiveFilters({ tags, clearLabel, onClearAll }: ActiveFiltersProps): React.JSX.Element | null;
|
|
75
|
+
|
|
76
|
+
/** One filter group: its options with counts, "Show more", and a search of its own. */
|
|
77
|
+
declare function FilterGroup({ group, selected, onToggle, order, animate, labels }: FilterGroupProps): React.JSX.Element;
|
|
78
|
+
|
|
79
|
+
/** The side panel: every filter group, and the button that folds it into the pill. */
|
|
80
|
+
declare function FiltersPanel({ groups, selected, activeCount, onToggle, onCollapse, animate, labels, children }: FiltersPanelProps): React.JSX.Element;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The folded filters: a floating button at the bottom of the screen, level
|
|
84
|
+
* with the content's left edge in a 1180px measure (centred on phones). It is
|
|
85
|
+
* the panel itself, morphed — the two share one view-transition name and are
|
|
86
|
+
* never shown together.
|
|
87
|
+
*/
|
|
88
|
+
declare function FiltersPill({ activeCount, onExpand, animate, labels }: FiltersPillProps): React.JSX.Element;
|
|
89
|
+
|
|
90
|
+
/** True where the browser can morph the panel into the pill itself. */
|
|
91
|
+
declare const supportsViewTransitions: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Whether the filters panel is folded into the floating pill. It starts folded,
|
|
94
|
+
* so the results get the page; the pill opens it. A change runs as a view
|
|
95
|
+
* transition, so the panel morphs into the pill and the cards glide to their
|
|
96
|
+
* new places.
|
|
97
|
+
*/
|
|
98
|
+
declare function useFiltersCollapsed(): {
|
|
99
|
+
collapsed: boolean;
|
|
100
|
+
collapse: () => void;
|
|
101
|
+
expand: () => void;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export { type ActiveFilterTag, ActiveFilters, type ActiveFiltersProps, type FacetFilterGroup, type FacetFilterOption, type FacetFiltersLabels, type FacetSelection, FilterGroup, type FilterGroupProps, FiltersPanel, type FiltersPanelProps, FiltersPill, type FiltersPillProps, supportsViewTransitions, useFiltersCollapsed };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ActiveFilters } from "./active-filters.js";
|
|
2
|
+
import { FilterGroup } from "./filter-group.js";
|
|
3
|
+
import { FiltersPanel } from "./filters-panel.js";
|
|
4
|
+
import { FiltersPill } from "./filters-pill.js";
|
|
5
|
+
import { supportsViewTransitions, useFiltersCollapsed } from "./use-filters-collapsed.js";
|
|
6
|
+
export { ActiveFilters, FilterGroup, FiltersPanel, FiltersPill, supportsViewTransitions, useFiltersCollapsed };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { startViewTransition } from "../../utils/view-transition.js";
|
|
2
|
+
import { useCallback, useState } from "react";
|
|
3
|
+
//#region src/components/facet-filters/use-filters-collapsed.ts
|
|
4
|
+
/** True where the browser can morph the panel into the pill itself. */
|
|
5
|
+
var supportsViewTransitions = typeof document !== "undefined" && "startViewTransition" in document;
|
|
6
|
+
/**
|
|
7
|
+
* Whether the filters panel is folded into the floating pill. It starts folded,
|
|
8
|
+
* so the results get the page; the pill opens it. A change runs as a view
|
|
9
|
+
* transition, so the panel morphs into the pill and the cards glide to their
|
|
10
|
+
* new places.
|
|
11
|
+
*/
|
|
12
|
+
function useFiltersCollapsed() {
|
|
13
|
+
const [collapsed, setCollapsed] = useState(true);
|
|
14
|
+
return {
|
|
15
|
+
collapsed,
|
|
16
|
+
collapse: useCallback(() => startViewTransition(() => setCollapsed(true)), []),
|
|
17
|
+
expand: useCallback(() => startViewTransition(() => setCollapsed(false)), [])
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { supportsViewTransitions, useFiltersCollapsed };
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { cn } from "../../utils/cn.js";
|
|
2
|
+
import { Button } from "../button/button.js";
|
|
3
|
+
import * as React$1 from "react";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { ChevronDown, ChevronUp } from "lucide-react";
|
|
6
|
+
//#region src/components/feature-grid/feature-grid.tsx
|
|
7
|
+
var DEFAULT_PAGE_SIZE = 6;
|
|
8
|
+
var DEFAULT_LABELS = {
|
|
9
|
+
showAll: (count) => `Show all ${count}`,
|
|
10
|
+
showMore: (count) => `Show ${count} more`,
|
|
11
|
+
showFewer: "Show fewer"
|
|
12
|
+
};
|
|
13
|
+
var COLUMNS = {
|
|
14
|
+
1: "grid-cols-1",
|
|
15
|
+
2: "grid-cols-1 @xl:grid-cols-2",
|
|
16
|
+
3: "grid-cols-1 @xl:grid-cols-2 @4xl:grid-cols-3"
|
|
17
|
+
};
|
|
18
|
+
/** `01`, `02`… — as many digits as the longest number needs, never fewer than two. */
|
|
19
|
+
function numberOf(index, total) {
|
|
20
|
+
return String(index + 1).padStart(Math.max(2, String(total).length), "0");
|
|
21
|
+
}
|
|
22
|
+
/** How many items show, and what the button does next: show all, show the next page, or fold back. */
|
|
23
|
+
function usePaging(total, pageSize, reveal) {
|
|
24
|
+
const [shown, setShown] = React$1.useState(pageSize);
|
|
25
|
+
const visible = Math.min(shown, total);
|
|
26
|
+
const left = total - visible;
|
|
27
|
+
let next = null;
|
|
28
|
+
if (left > 0) next = reveal === "page" ? "page" : "all";
|
|
29
|
+
else if (total > pageSize) next = "fewer";
|
|
30
|
+
return {
|
|
31
|
+
visible,
|
|
32
|
+
next,
|
|
33
|
+
nextCount: Math.min(pageSize, left),
|
|
34
|
+
showMore: () => setShown(next === "page" ? visible + pageSize : total),
|
|
35
|
+
showFewer: () => setShown(pageSize)
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* What something does, as a numbered grid: a short title per item and the
|
|
40
|
+
* sentence under it, two columns where there is room. Each item draws its own
|
|
41
|
+
* dividers, so an odd count leaves a clean empty cell, not a grey block. A
|
|
42
|
+
* long list shows its first `pageSize` items; the button under it shows the
|
|
43
|
+
* rest at once (`reveal="all"`) or a page at a time (`reveal="page"`), moving
|
|
44
|
+
* focus to the first item it adds, then folds back to the first page.
|
|
45
|
+
*/
|
|
46
|
+
var FeatureGrid = React$1.forwardRef(function FeatureGrid({ items, numbered = true, columns = 2, pageSize = DEFAULT_PAGE_SIZE, reveal = "all", titleAs: Title = "h3", labels, className, id, ...props }, ref) {
|
|
47
|
+
const text = {
|
|
48
|
+
...DEFAULT_LABELS,
|
|
49
|
+
...labels
|
|
50
|
+
};
|
|
51
|
+
const paging = usePaging(items.length, pageSize, reveal);
|
|
52
|
+
const generatedId = React$1.useId();
|
|
53
|
+
const listId = id ?? generatedId;
|
|
54
|
+
const focusIndex = React$1.useRef(null);
|
|
55
|
+
const itemRefs = React$1.useRef([]);
|
|
56
|
+
React$1.useEffect(() => {
|
|
57
|
+
if (focusIndex.current === null) return;
|
|
58
|
+
itemRefs.current[focusIndex.current]?.focus();
|
|
59
|
+
focusIndex.current = null;
|
|
60
|
+
}, [paging.visible]);
|
|
61
|
+
function handleClick() {
|
|
62
|
+
if (paging.next === "fewer") {
|
|
63
|
+
paging.showFewer();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
focusIndex.current = paging.visible;
|
|
67
|
+
paging.showMore();
|
|
68
|
+
}
|
|
69
|
+
const buttonText = paging.next === "fewer" ? text.showFewer : paging.next === "page" ? text.showMore(paging.nextCount) : text.showAll(items.length);
|
|
70
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
71
|
+
"data-slot": "feature-grid",
|
|
72
|
+
className: "@container flex flex-col gap-4",
|
|
73
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
74
|
+
className: "overflow-hidden rounded-xl border border-border",
|
|
75
|
+
children: /* @__PURE__ */ jsx("ol", {
|
|
76
|
+
ref,
|
|
77
|
+
id: listId,
|
|
78
|
+
className: cn("-mr-px -mb-px grid list-none p-0 m-0", COLUMNS[columns], className),
|
|
79
|
+
...props,
|
|
80
|
+
children: items.slice(0, paging.visible).map((item, index) => /* @__PURE__ */ jsxs("li", {
|
|
81
|
+
ref: (node) => {
|
|
82
|
+
itemRefs.current[index] = node;
|
|
83
|
+
},
|
|
84
|
+
tabIndex: -1,
|
|
85
|
+
className: cn("flex gap-3 border-r border-b border-border p-4 outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset", index >= pageSize && "motion-safe:animate-rise-in"),
|
|
86
|
+
children: [numbered && /* @__PURE__ */ jsx("span", {
|
|
87
|
+
"aria-hidden": true,
|
|
88
|
+
className: "h-fit shrink-0 rounded-md bg-muted px-1.5 py-0.5 font-mono text-xs font-semibold text-muted-foreground",
|
|
89
|
+
children: numberOf(index, items.length)
|
|
90
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
91
|
+
className: "flex min-w-0 flex-col gap-1",
|
|
92
|
+
children: [/* @__PURE__ */ jsx(Title, {
|
|
93
|
+
className: "m-0 text-sm font-semibold text-foreground [overflow-wrap:anywhere]",
|
|
94
|
+
children: item.title
|
|
95
|
+
}), item.description != null && /* @__PURE__ */ jsx("p", {
|
|
96
|
+
className: "m-0 text-sm leading-relaxed text-muted-foreground",
|
|
97
|
+
children: item.description
|
|
98
|
+
})]
|
|
99
|
+
})]
|
|
100
|
+
}, item.id))
|
|
101
|
+
})
|
|
102
|
+
}), paging.next && /* @__PURE__ */ jsx(Button, {
|
|
103
|
+
variant: "outline",
|
|
104
|
+
color: "gray",
|
|
105
|
+
"aria-controls": listId,
|
|
106
|
+
"aria-expanded": paging.next === "fewer",
|
|
107
|
+
endIcon: paging.next === "fewer" ? /* @__PURE__ */ jsx(ChevronUp, { "aria-hidden": true }) : /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": true }),
|
|
108
|
+
onClick: handleClick,
|
|
109
|
+
children: buttonText
|
|
110
|
+
})]
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
FeatureGrid.displayName = "FeatureGrid";
|
|
114
|
+
//#endregion
|
|
115
|
+
export { FeatureGrid };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { HTMLAttributes, ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
/** One item: a short title, and the sentence under it when it has one. */
|
|
5
|
+
interface FeatureGridItem {
|
|
6
|
+
/** Stable key. */
|
|
7
|
+
id: string;
|
|
8
|
+
title: ReactNode;
|
|
9
|
+
description?: ReactNode;
|
|
10
|
+
}
|
|
11
|
+
/** The most columns the grid uses; it follows its own width, not the viewport's. */
|
|
12
|
+
type FeatureGridColumns = 1 | 2 | 3;
|
|
13
|
+
/**
|
|
14
|
+
* What the button under a long list does. `all`: one click shows every item
|
|
15
|
+
* ("Show all 15"). `page`: each click shows the next `pageSize` items
|
|
16
|
+
* ("Show 6 more"). Either way, once every item shows it folds back ("Show fewer").
|
|
17
|
+
*/
|
|
18
|
+
type FeatureGridReveal = "all" | "page";
|
|
19
|
+
/** Already-translated labels; English when absent. */
|
|
20
|
+
interface FeatureGridLabels {
|
|
21
|
+
/** `reveal="all"`: `count` is how many items there are in all. */
|
|
22
|
+
showAll: (count: number) => string;
|
|
23
|
+
/** `reveal="page"`: `count` is how many the click will add. */
|
|
24
|
+
showMore: (count: number) => string;
|
|
25
|
+
/** Back to the first page, once every item shows. */
|
|
26
|
+
showFewer: string;
|
|
27
|
+
}
|
|
28
|
+
interface FeatureGridProps extends Omit<HTMLAttributes<HTMLOListElement>, "children"> {
|
|
29
|
+
items: readonly FeatureGridItem[];
|
|
30
|
+
/** Number the items 01, 02, 03… Default `true`. */
|
|
31
|
+
numbered?: boolean;
|
|
32
|
+
/** Default `2`: one column below 36rem of its own width, two above (three from 56rem with `3`). */
|
|
33
|
+
columns?: FeatureGridColumns;
|
|
34
|
+
/** Items shown at first, and how many more each "Show more" adds. Default 6. `Infinity` shows them all with no button. */
|
|
35
|
+
pageSize?: number;
|
|
36
|
+
/** Default `all`. */
|
|
37
|
+
reveal?: FeatureGridReveal;
|
|
38
|
+
/** The element each item's title is. Default `h3`: the grid usually sits under a section's `h2`. */
|
|
39
|
+
titleAs?: "h3" | "h4" | "p";
|
|
40
|
+
labels?: Partial<FeatureGridLabels>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* What something does, as a numbered grid: a short title per item and the
|
|
45
|
+
* sentence under it, two columns where there is room. Each item draws its own
|
|
46
|
+
* dividers, so an odd count leaves a clean empty cell, not a grey block. A
|
|
47
|
+
* long list shows its first `pageSize` items; the button under it shows the
|
|
48
|
+
* rest at once (`reveal="all"`) or a page at a time (`reveal="page"`), moving
|
|
49
|
+
* focus to the first item it adds, then folds back to the first page.
|
|
50
|
+
*/
|
|
51
|
+
declare const FeatureGrid: React.ForwardRefExoticComponent<FeatureGridProps & React.RefAttributes<HTMLOListElement>>;
|
|
52
|
+
|
|
53
|
+
export { FeatureGrid, type FeatureGridColumns, type FeatureGridItem, type FeatureGridLabels, type FeatureGridProps, type FeatureGridReveal };
|