@seekalfred/primitives 0.5.1 → 0.7.1
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 +682 -19
- package/dist/accordion/accordion.js +10 -4
- package/dist/accordion/accordion.js.map +1 -1
- package/dist/action-button/action-button.d.ts +50 -0
- package/dist/action-button/action-button.js +159 -0
- package/dist/action-button/action-button.js.map +1 -0
- package/dist/action-button/index.d.ts +2 -0
- package/dist/action-button/index.js +2 -0
- package/dist/activity-heatmap/activity-heatmap.d.ts +92 -0
- package/dist/activity-heatmap/activity-heatmap.js +699 -0
- package/dist/activity-heatmap/activity-heatmap.js.map +1 -0
- package/dist/activity-heatmap/index.d.ts +2 -0
- package/dist/activity-heatmap/index.js +2 -0
- package/dist/alert/alert.d.ts +19 -1
- package/dist/alert/alert.js +180 -23
- package/dist/alert/alert.js.map +1 -1
- package/dist/alert-dialog/alert-dialog.d.ts +45 -18
- package/dist/alert-dialog/alert-dialog.js +128 -9
- package/dist/alert-dialog/alert-dialog.js.map +1 -1
- package/dist/alert-dialog/index.d.ts +2 -2
- package/dist/alert-dialog/index.js +2 -2
- package/dist/animated-counter/animated-counter.d.ts +38 -0
- package/dist/animated-counter/animated-counter.js +230 -0
- package/dist/animated-counter/animated-counter.js.map +1 -0
- package/dist/animated-counter/index.d.ts +2 -0
- package/dist/animated-counter/index.js +2 -0
- package/dist/announcement-bar/announcement-bar.d.ts +67 -0
- package/dist/announcement-bar/announcement-bar.js +364 -0
- package/dist/announcement-bar/announcement-bar.js.map +1 -0
- package/dist/announcement-bar/index.d.ts +2 -0
- package/dist/announcement-bar/index.js +2 -0
- package/dist/avatar/avatar.d.ts +6 -0
- package/dist/avatar/avatar.js +47 -16
- package/dist/avatar/avatar.js.map +1 -1
- package/dist/badge/badge.d.ts +10 -3
- package/dist/badge/badge.js +35 -5
- package/dist/badge/badge.js.map +1 -1
- package/dist/bar-chart/bar-chart.d.ts +51 -0
- package/dist/bar-chart/bar-chart.js +565 -0
- package/dist/bar-chart/bar-chart.js.map +1 -0
- package/dist/bar-chart/index.d.ts +2 -0
- package/dist/bar-chart/index.js +2 -0
- package/dist/breadcrumb/breadcrumb.d.ts +2 -29
- package/dist/breadcrumb/breadcrumb.js +32 -9
- package/dist/breadcrumb/breadcrumb.js.map +1 -1
- package/dist/brush-chart/brush-chart.d.ts +64 -0
- package/dist/brush-chart/brush-chart.js +1056 -0
- package/dist/brush-chart/brush-chart.js.map +1 -0
- package/dist/brush-chart/index.d.ts +2 -0
- package/dist/brush-chart/index.js +2 -0
- package/dist/button/button.d.ts +36 -23
- package/dist/button/button.js +198 -45
- package/dist/button/button.js.map +1 -1
- package/dist/button-group/button-group.d.ts +76 -0
- package/dist/button-group/button-group.js +402 -0
- package/dist/button-group/button-group.js.map +1 -0
- package/dist/button-group/index.d.ts +2 -0
- package/dist/button-group/index.js +2 -0
- package/dist/calendar/calendar.d.ts +1 -1
- package/dist/calendar/calendar.js +257 -30
- package/dist/calendar/calendar.js.map +1 -1
- package/dist/card/card.d.ts +9 -2
- package/dist/card/card.js +16 -5
- package/dist/card/card.js.map +1 -1
- package/dist/card-stack/card-stack.d.ts +54 -0
- package/dist/card-stack/card-stack.js +492 -0
- package/dist/card-stack/card-stack.js.map +1 -0
- package/dist/card-stack/index.d.ts +2 -0
- package/dist/card-stack/index.js +2 -0
- package/dist/carousel/carousel.d.ts +56 -0
- package/dist/carousel/carousel.js +389 -0
- package/dist/carousel/carousel.js.map +1 -0
- package/dist/carousel/index.d.ts +2 -0
- package/dist/carousel/index.js +2 -0
- package/dist/checkbox/checkbox.d.ts +0 -7
- package/dist/checkbox/checkbox.js +26 -29
- package/dist/checkbox/checkbox.js.map +1 -1
- package/dist/chip-group/chip-group.d.ts +37 -0
- package/dist/chip-group/chip-group.js +148 -0
- package/dist/chip-group/chip-group.js.map +1 -0
- package/dist/chip-group/index.d.ts +2 -0
- package/dist/chip-group/index.js +2 -0
- package/dist/confirm-morph/confirm-morph.d.ts +85 -0
- package/dist/confirm-morph/confirm-morph.js +652 -0
- package/dist/confirm-morph/confirm-morph.js.map +1 -0
- package/dist/confirm-morph/index.d.ts +2 -0
- package/dist/confirm-morph/index.js +2 -0
- package/dist/copy-button/copy-button.d.ts +32 -0
- package/dist/copy-button/copy-button.js +134 -0
- package/dist/copy-button/copy-button.js.map +1 -0
- package/dist/copy-button/index.d.ts +2 -0
- package/dist/copy-button/index.js +2 -0
- package/dist/countdown/countdown.d.ts +45 -0
- package/dist/countdown/countdown.js +298 -0
- package/dist/countdown/countdown.js.map +1 -0
- package/dist/countdown/index.d.ts +2 -0
- package/dist/countdown/index.js +2 -0
- package/dist/date-picker/date-picker.d.ts +51 -0
- package/dist/date-picker/date-picker.js +241 -0
- package/dist/date-picker/date-picker.js.map +1 -0
- package/dist/date-picker/date-range-picker.d.ts +78 -0
- package/dist/date-picker/date-range-picker.js +1015 -0
- package/dist/date-picker/date-range-picker.js.map +1 -0
- package/dist/date-picker/index.d.ts +4 -0
- package/dist/date-picker/index.js +4 -0
- package/dist/date-picker/picker-parts.d.ts +46 -0
- package/dist/date-picker/picker-parts.js +135 -0
- package/dist/date-picker/picker-parts.js.map +1 -0
- package/dist/dialog/dialog.d.ts +10 -14
- package/dist/dialog/dialog.js +40 -12
- package/dist/dialog/dialog.js.map +1 -1
- package/dist/donut-chart/donut-chart.d.ts +64 -0
- package/dist/donut-chart/donut-chart.js +576 -0
- package/dist/donut-chart/donut-chart.js.map +1 -0
- package/dist/donut-chart/index.d.ts +2 -0
- package/dist/donut-chart/index.js +2 -0
- package/dist/empty-state/empty-state.d.ts +55 -0
- package/dist/empty-state/empty-state.js +89 -0
- package/dist/empty-state/empty-state.js.map +1 -0
- package/dist/empty-state/index.d.ts +2 -0
- package/dist/empty-state/index.js +2 -0
- package/dist/expanding-button-group/expanding-button-group.d.ts +54 -0
- package/dist/expanding-button-group/expanding-button-group.js +350 -0
- package/dist/expanding-button-group/expanding-button-group.js.map +1 -0
- package/dist/expanding-button-group/index.d.ts +2 -0
- package/dist/expanding-button-group/index.js +2 -0
- package/dist/file-drop-zone/file-drop-zone.d.ts +71 -0
- package/dist/file-drop-zone/file-drop-zone.js +116 -0
- package/dist/file-drop-zone/file-drop-zone.js.map +1 -0
- package/dist/file-drop-zone/index.d.ts +2 -0
- package/dist/file-drop-zone/index.js +2 -0
- package/dist/filter-bar/filter-bar.d.ts +142 -0
- package/dist/filter-bar/filter-bar.js +416 -0
- package/dist/filter-bar/filter-bar.js.map +1 -0
- package/dist/filter-bar/index.d.ts +2 -0
- package/dist/filter-bar/index.js +2 -0
- package/dist/floating-button-group/floating-button-group.d.ts +61 -0
- package/dist/floating-button-group/floating-button-group.js +340 -0
- package/dist/floating-button-group/floating-button-group.js.map +1 -0
- package/dist/floating-button-group/index.d.ts +2 -0
- package/dist/floating-button-group/index.js +2 -0
- package/dist/gauge/gauge.d.ts +45 -0
- package/dist/gauge/gauge.js +219 -0
- package/dist/gauge/gauge.js.map +1 -0
- package/dist/gauge/index.d.ts +2 -0
- package/dist/gauge/index.js +2 -0
- package/dist/icon-morph/icon-morph.d.ts +55 -0
- package/dist/icon-morph/icon-morph.js +331 -0
- package/dist/icon-morph/icon-morph.js.map +1 -0
- package/dist/icon-morph/index.d.ts +2 -0
- package/dist/icon-morph/index.js +2 -0
- package/dist/in-view-title/in-view-title.d.ts +33 -0
- package/dist/in-view-title/in-view-title.js +119 -0
- package/dist/in-view-title/in-view-title.js.map +1 -0
- package/dist/in-view-title/index.d.ts +2 -0
- package/dist/in-view-title/index.js +2 -0
- package/dist/index.d.ts +71 -6
- package/dist/index.js +73 -11
- package/dist/input/input.d.ts +22 -0
- package/dist/input/input.js +36 -12
- package/dist/input/input.js.map +1 -1
- package/dist/lib/cn.js +11 -1
- package/dist/lib/cn.js.map +1 -1
- package/dist/lib/count-to.js +113 -0
- package/dist/lib/count-to.js.map +1 -0
- package/dist/lib/eye-morph.js +62 -0
- package/dist/lib/eye-morph.js.map +1 -0
- package/dist/lib/field-message.js +354 -0
- package/dist/lib/field-message.js.map +1 -0
- package/dist/lib/field-shell.js +81 -0
- package/dist/lib/field-shell.js.map +1 -0
- package/dist/lib/field-surface.js +11 -8
- package/dist/lib/field-surface.js.map +1 -1
- package/dist/lib/flag-emoji.js +50 -0
- package/dist/lib/flag-emoji.js.map +1 -0
- package/dist/lib/flip.js +88 -0
- package/dist/lib/flip.js.map +1 -0
- package/dist/lib/height-follow.js +59 -0
- package/dist/lib/height-follow.js.map +1 -0
- package/dist/lib/icon-swap.js +47 -0
- package/dist/lib/icon-swap.js.map +1 -0
- package/dist/lib/leaving-list.js +57 -0
- package/dist/lib/leaving-list.js.map +1 -0
- package/dist/lib/menu-highlight.js +64 -0
- package/dist/lib/menu-highlight.js.map +1 -0
- package/dist/lib/merge-refs.js +3 -3
- package/dist/lib/merge-refs.js.map +1 -1
- package/dist/lib/morph-text.js +128 -0
- package/dist/lib/morph-text.js.map +1 -0
- package/dist/lib/motion.js +169 -0
- package/dist/lib/motion.js.map +1 -0
- package/dist/lib/pausable-timeout.js +67 -0
- package/dist/lib/pausable-timeout.js.map +1 -0
- package/dist/lib/rolling-value.js +31 -0
- package/dist/lib/rolling-value.js.map +1 -0
- package/dist/lib/spring-progress.js +114 -0
- package/dist/lib/spring-progress.js.map +1 -0
- package/dist/lib/spring-tween.js +500 -0
- package/dist/lib/spring-tween.js.map +1 -0
- package/dist/lib/svg-id.js +10 -0
- package/dist/lib/svg-id.js.map +1 -0
- package/dist/lib/swap-text.js +79 -0
- package/dist/lib/swap-text.js.map +1 -0
- package/dist/lib/use-copy-feedback.js +36 -0
- package/dist/lib/use-copy-feedback.js.map +1 -0
- package/dist/line-chart/index.d.ts +2 -0
- package/dist/line-chart/index.js +2 -0
- package/dist/line-chart/line-chart.d.ts +76 -0
- package/dist/line-chart/line-chart.js +611 -0
- package/dist/line-chart/line-chart.js.map +1 -0
- package/dist/mention-input/index.d.ts +2 -0
- package/dist/mention-input/index.js +2 -0
- package/dist/mention-input/mention-input.d.ts +98 -0
- package/dist/mention-input/mention-input.js +576 -0
- package/dist/mention-input/mention-input.js.map +1 -0
- package/dist/menu/menu.d.ts +2 -0
- package/dist/menu/menu.js +23 -12
- package/dist/menu/menu.js.map +1 -1
- package/dist/money-input/index.d.ts +2 -0
- package/dist/money-input/index.js +2 -0
- package/dist/money-input/money-input.d.ts +65 -0
- package/dist/money-input/money-input.js +607 -0
- package/dist/money-input/money-input.js.map +1 -0
- package/dist/morph-select/index.d.ts +2 -0
- package/dist/morph-select/index.js +2 -0
- package/dist/morph-select/morph-select.d.ts +71 -0
- package/dist/morph-select/morph-select.js +693 -0
- package/dist/morph-select/morph-select.js.map +1 -0
- package/dist/multi-select/index.d.ts +2 -0
- package/dist/multi-select/index.js +2 -0
- package/dist/multi-select/multi-select.d.ts +36 -0
- package/dist/multi-select/multi-select.js +152 -0
- package/dist/multi-select/multi-select.js.map +1 -0
- package/dist/number-field/index.d.ts +2 -0
- package/dist/number-field/index.js +2 -0
- package/dist/number-field/number-field.d.ts +42 -0
- package/dist/number-field/number-field.js +199 -0
- package/dist/number-field/number-field.js.map +1 -0
- package/dist/onboarding-checklist/index.d.ts +2 -0
- package/dist/onboarding-checklist/index.js +2 -0
- package/dist/onboarding-checklist/onboarding-checklist.d.ts +55 -0
- package/dist/onboarding-checklist/onboarding-checklist.js +577 -0
- package/dist/onboarding-checklist/onboarding-checklist.js.map +1 -0
- package/dist/page-header/index.d.ts +2 -0
- package/dist/page-header/index.js +2 -0
- package/dist/page-header/page-header.d.ts +75 -0
- package/dist/page-header/page-header.js +83 -0
- package/dist/page-header/page-header.js.map +1 -0
- package/dist/password-field/index.d.ts +2 -0
- package/dist/password-field/index.js +2 -0
- package/dist/password-field/password-field.d.ts +37 -0
- package/dist/password-field/password-field.js +101 -0
- package/dist/password-field/password-field.js.map +1 -0
- package/dist/password-strength/index.d.ts +2 -0
- package/dist/password-strength/index.js +2 -0
- package/dist/password-strength/password-strength.d.ts +127 -0
- package/dist/password-strength/password-strength.js +455 -0
- package/dist/password-strength/password-strength.js.map +1 -0
- package/dist/phone-input/index.d.ts +3 -0
- package/dist/phone-input/index.js +3 -0
- package/dist/phone-input/phone-countries.d.ts +29 -0
- package/dist/phone-input/phone-countries.js +170 -0
- package/dist/phone-input/phone-countries.js.map +1 -0
- package/dist/phone-input/phone-input.d.ts +66 -0
- package/dist/phone-input/phone-input.js +440 -0
- package/dist/phone-input/phone-input.js.map +1 -0
- package/dist/popover/popover.d.ts +20 -0
- package/dist/popover/popover.js +33 -9
- package/dist/popover/popover.js.map +1 -1
- package/dist/progress/progress.js +46 -5
- package/dist/progress/progress.js.map +1 -1
- package/dist/radio-group/radio-group.js +8 -7
- package/dist/radio-group/radio-group.js.map +1 -1
- package/dist/reactions/index.d.ts +2 -0
- package/dist/reactions/index.js +2 -0
- package/dist/reactions/reactions.d.ts +50 -0
- package/dist/reactions/reactions.js +315 -0
- package/dist/reactions/reactions.js.map +1 -0
- package/dist/rich-text-editor/index.d.ts +3 -0
- package/dist/rich-text-editor/index.js +2 -0
- package/dist/rich-text-editor/rich-text-editor.d.ts +70 -0
- package/dist/rich-text-editor/rich-text-editor.js +909 -0
- package/dist/rich-text-editor/rich-text-editor.js.map +1 -0
- package/dist/rich-text-editor/rich-text-engine.d.ts +16 -0
- package/dist/rich-text-editor/rich-text-engine.js +366 -0
- package/dist/rich-text-editor/rich-text-engine.js.map +1 -0
- package/dist/rich-text-editor/rich-text-html.js +174 -0
- package/dist/rich-text-editor/rich-text-html.js.map +1 -0
- package/dist/rich-text-editor/rich-text-icons.js +43 -0
- package/dist/rich-text-editor/rich-text-icons.js.map +1 -0
- package/dist/ridgeline/index.d.ts +2 -0
- package/dist/ridgeline/index.js +2 -0
- package/dist/ridgeline/ridgeline.d.ts +55 -0
- package/dist/ridgeline/ridgeline.js +701 -0
- package/dist/ridgeline/ridgeline.js.map +1 -0
- package/dist/scroll-area/index.d.ts +2 -2
- package/dist/scroll-area/index.js +2 -2
- package/dist/scroll-area/scroll-area.d.ts +75 -28
- package/dist/scroll-area/scroll-area.js +212 -41
- package/dist/scroll-area/scroll-area.js.map +1 -1
- package/dist/scrub-input/evaluate.d.ts +14 -0
- package/dist/scrub-input/evaluate.js +72 -0
- package/dist/scrub-input/evaluate.js.map +1 -0
- package/dist/scrub-input/index.d.ts +3 -0
- package/dist/scrub-input/index.js +3 -0
- package/dist/scrub-input/scrub-input.d.ts +74 -0
- package/dist/scrub-input/scrub-input.js +486 -0
- package/dist/scrub-input/scrub-input.js.map +1 -0
- package/dist/search-field/index.d.ts +2 -0
- package/dist/search-field/index.js +2 -0
- package/dist/search-field/search-field.d.ts +27 -0
- package/dist/search-field/search-field.js +155 -0
- package/dist/search-field/search-field.js.map +1 -0
- package/dist/select/select.d.ts +3 -1
- package/dist/select/select.js +95 -25
- package/dist/select/select.js.map +1 -1
- package/dist/separator/separator.d.ts +1 -1
- package/dist/sheet/sheet.js +4 -2
- package/dist/sheet/sheet.js.map +1 -1
- package/dist/shortcut-recorder/index.d.ts +3 -0
- package/dist/shortcut-recorder/index.js +3 -0
- package/dist/shortcut-recorder/shortcut-model.d.ts +27 -0
- package/dist/shortcut-recorder/shortcut-model.js +206 -0
- package/dist/shortcut-recorder/shortcut-model.js.map +1 -0
- package/dist/shortcut-recorder/shortcut-recorder.d.ts +93 -0
- package/dist/shortcut-recorder/shortcut-recorder.js +489 -0
- package/dist/shortcut-recorder/shortcut-recorder.js.map +1 -0
- package/dist/side-nav/index.d.ts +2 -0
- package/dist/side-nav/index.js +2 -0
- package/dist/side-nav/side-nav.d.ts +72 -0
- package/dist/side-nav/side-nav.js +142 -0
- package/dist/side-nav/side-nav.js.map +1 -0
- package/dist/skeleton/skeleton.d.ts +8 -2
- package/dist/skeleton/skeleton.js +6 -2
- package/dist/skeleton/skeleton.js.map +1 -1
- package/dist/slider/index.d.ts +2 -2
- package/dist/slider/slider.d.ts +46 -14
- package/dist/slider/slider.js +188 -50
- package/dist/slider/slider.js.map +1 -1
- package/dist/slope-chart/index.d.ts +2 -0
- package/dist/slope-chart/index.js +2 -0
- package/dist/slope-chart/slope-chart.d.ts +54 -0
- package/dist/slope-chart/slope-chart.js +568 -0
- package/dist/slope-chart/slope-chart.js.map +1 -0
- package/dist/sparkline/index.d.ts +2 -0
- package/dist/sparkline/index.js +2 -0
- package/dist/sparkline/sparkline.d.ts +46 -0
- package/dist/sparkline/sparkline.js +390 -0
- package/dist/sparkline/sparkline.js.map +1 -0
- package/dist/split-bar/index.d.ts +2 -0
- package/dist/split-bar/index.js +2 -0
- package/dist/split-bar/split-bar.d.ts +62 -0
- package/dist/split-bar/split-bar.js +513 -0
- package/dist/split-bar/split-bar.js.map +1 -0
- package/dist/split-button/index.d.ts +2 -0
- package/dist/split-button/index.js +2 -0
- package/dist/split-button/split-button.d.ts +46 -0
- package/dist/split-button/split-button.js +123 -0
- package/dist/split-button/split-button.js.map +1 -0
- package/dist/stat-card/index.d.ts +2 -0
- package/dist/stat-card/index.js +2 -0
- package/dist/stat-card/stat-card.d.ts +101 -0
- package/dist/stat-card/stat-card.js +249 -0
- package/dist/stat-card/stat-card.js.map +1 -0
- package/dist/stepper/index.d.ts +2 -0
- package/dist/stepper/index.js +2 -0
- package/dist/stepper/stepper.d.ts +51 -0
- package/dist/stepper/stepper.js +215 -0
- package/dist/stepper/stepper.js.map +1 -0
- package/dist/streamgraph/index.d.ts +2 -0
- package/dist/streamgraph/index.js +2 -0
- package/dist/streamgraph/streamgraph.d.ts +70 -0
- package/dist/streamgraph/streamgraph.js +613 -0
- package/dist/streamgraph/streamgraph.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/swipe-actions/index.d.ts +2 -0
- package/dist/swipe-actions/index.js +2 -0
- package/dist/swipe-actions/swipe-actions.d.ts +67 -0
- package/dist/swipe-actions/swipe-actions.js +552 -0
- package/dist/swipe-actions/swipe-actions.js.map +1 -0
- package/dist/switch/switch.js +10 -9
- package/dist/switch/switch.js.map +1 -1
- package/dist/table/index.d.ts +2 -2
- package/dist/table/index.js +2 -2
- package/dist/table/table.d.ts +87 -4
- package/dist/table/table.js +441 -165
- package/dist/table/table.js.map +1 -1
- package/dist/tabs/tabs.js +143 -7
- package/dist/tabs/tabs.js.map +1 -1
- package/dist/tag-input/index.d.ts +2 -0
- package/dist/tag-input/index.js +2 -0
- package/dist/tag-input/tag-input.d.ts +40 -0
- package/dist/tag-input/tag-input.js +269 -0
- package/dist/tag-input/tag-input.js.map +1 -0
- package/dist/text-morph/index.d.ts +2 -0
- package/dist/text-morph/index.js +2 -0
- package/dist/text-morph/text-morph.d.ts +23 -0
- package/dist/text-morph/text-morph.js +21 -0
- package/dist/text-morph/text-morph.js.map +1 -0
- package/dist/text-reveal/index.d.ts +2 -0
- package/dist/text-reveal/index.js +2 -0
- package/dist/text-reveal/text-reveal.d.ts +27 -0
- package/dist/text-reveal/text-reveal.js +51 -0
- package/dist/text-reveal/text-reveal.js.map +1 -0
- package/dist/text-shimmer/index.d.ts +2 -0
- package/dist/text-shimmer/index.js +2 -0
- package/dist/text-shimmer/text-shimmer.d.ts +29 -0
- package/dist/text-shimmer/text-shimmer.js +29 -0
- package/dist/text-shimmer/text-shimmer.js.map +1 -0
- package/dist/textarea/textarea.d.ts +23 -0
- package/dist/textarea/textarea.js +24 -2
- package/dist/textarea/textarea.js.map +1 -1
- package/dist/theme-switch/index.d.ts +2 -0
- package/dist/theme-switch/index.js +2 -0
- package/dist/theme-switch/theme-switch.d.ts +37 -0
- package/dist/theme-switch/theme-switch.js +123 -0
- package/dist/theme-switch/theme-switch.js.map +1 -0
- package/dist/time-picker/index.d.ts +2 -0
- package/dist/time-picker/index.js +2 -0
- package/dist/time-picker/time-picker.d.ts +54 -0
- package/dist/time-picker/time-picker.js +201 -0
- package/dist/time-picker/time-picker.js.map +1 -0
- package/dist/toast/index.d.ts +2 -2
- package/dist/toast/index.js +2 -2
- package/dist/toast/toast.d.ts +6 -0
- package/dist/toast/toast.js +98 -36
- package/dist/toast/toast.js.map +1 -1
- package/dist/tooltip/tooltip.d.ts +10 -3
- package/dist/tooltip/tooltip.js +67 -18
- package/dist/tooltip/tooltip.js.map +1 -1
- package/dist/treemap/index.d.ts +2 -0
- package/dist/treemap/index.js +2 -0
- package/dist/treemap/treemap.d.ts +53 -0
- package/dist/treemap/treemap.js +699 -0
- package/dist/treemap/treemap.js.map +1 -0
- package/dist/usage-meter/index.d.ts +2 -0
- package/dist/usage-meter/index.js +2 -0
- package/dist/usage-meter/usage-meter.d.ts +50 -0
- package/dist/usage-meter/usage-meter.js +440 -0
- package/dist/usage-meter/usage-meter.js.map +1 -0
- package/dist/waffle-chart/index.d.ts +2 -0
- package/dist/waffle-chart/index.js +2 -0
- package/dist/waffle-chart/waffle-chart.d.ts +57 -0
- package/dist/waffle-chart/waffle-chart.js +426 -0
- package/dist/waffle-chart/waffle-chart.js.map +1 -0
- package/package.json +245 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ridgeline.js","names":[],"sources":["../../src/ridgeline/ridgeline.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n forwardRef,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type PointerEvent,\n} from \"react\";\n\nimport { cn } from \"../lib/cn.js\";\nimport { mergeRefs } from \"../lib/merge-refs.js\";\nimport { prefersReducedMotion, useIsomorphicLayoutEffect } from \"../lib/motion.js\";\nimport { REVEAL, SWELL, tween } from \"../lib/spring-tween.js\";\n\n/**\n * Ridgeline: compare the shape of many distributions at once, such as daily\n * temperatures by month or response times by region. Each series is one ridge, a\n * smoothed density of its raw values, drawn top to bottom and overlapping the row\n * behind it; the ridges share one value axis.\n *\n * The ridges roll in from the top row down once the chart is in view. New data\n * morphs every ridge from the shape on screen, and the axis follows. Hovering,\n * touching or the arrow keys lift one ridge above its neighbours with its middle\n * half shaded and its median marked, step the others back, and show a tooltip with\n * the median, the middle half and the range. Moving along the values shows how\n * much of the series sits at or below that value. Each ridge is shaded by its\n * median, from a light tint to the full first series colour, with the scale\n * under the axis.\n *\n * Plain SVG written straight to the DOM by one small spring tween.\n */\nexport interface RidgelineSeries {\n /** Stable identity. A ridge that survives a data change morphs into its new shape. */\n id: string;\n label: string;\n /** Raw observations. The ridge is a smoothed density of these values. */\n values: number[];\n}\n\nexport interface RidgelineProps {\n /** One ridge per series, drawn top to bottom. */\n series: RidgelineSeries[];\n /** What is measured, such as \"Daily highs in Zurich\". Names the chart for assistive technology. */\n label: string;\n /** Unit after each value, such as \"°C\". */\n unit?: string;\n formatValue?: (value: number) => string;\n /** Value range of the axis. Defaults to the data with a little room on each side. */\n domain?: [number, number];\n /** How far a ridge may rise into the rows above, in row heights. @default 2.4 */\n overlap?: number;\n /** Height of one row in pixels. @default 30 */\n rowHeight?: number;\n /** Smoothing in value units. Defaults to Silverman's rule per series. */\n bandwidth?: number;\n /** Shades each ridge by its median, from a light tint to the full first series colour, and shows the scale under the axis. @default true */\n tint?: boolean;\n /** Controlled id of the lifted ridge. */\n active?: string | null;\n defaultActive?: string | null;\n onActiveChange?: (id: string | null) => void;\n /** @default \"No data yet\" */\n emptyLabel?: string;\n /** Extra classes for the root. Merged last. */\n className?: string;\n}\n\ntype Stats = { q1: number; median: number; q3: number; min: number; max: number; n: number; sorted: number[] };\ntype Shape = { xs: number[]; ys: number[]; row: number; q1: number; median: number; q3: number };\n\n/** Points along each ridge, the axis strip, the gap between the tooltip and what it describes, and how far the lifted ridge rises, in pixels. */\nconst SAMPLES = 96;\nconst AXIS = 28;\nconst TIP = 14;\nconst LIFT = 6;\nconst GROUPED = new Intl.NumberFormat(\"en-US\", { maximumFractionDigits: 1 });\nconst PERCENT = new Intl.NumberFormat(\"en-US\", { style: \"percent\", maximumFractionDigits: 0 });\nconst clamp = (value: number, low: number, high: number) => Math.min(high, Math.max(low, value));\nconst mix = (a: number, b: number, t: number) => a + (b - a) * t;\n\nfunction quantile(sorted: number[], q: number) {\n if (!sorted.length) return 0;\n const at = (sorted.length - 1) * q;\n const low = Math.floor(at);\n const high = Math.ceil(at);\n return sorted[low]! + (sorted[high]! - sorted[low]!) * (at - low);\n}\nfunction statsOf(values: number[]): Stats {\n const sorted = values.filter(Number.isFinite).sort((a, b) => a - b);\n return {\n sorted,\n n: sorted.length,\n min: sorted[0] ?? 0,\n max: sorted[sorted.length - 1] ?? 0,\n q1: quantile(sorted, 0.25),\n median: quantile(sorted, 0.5),\n q3: quantile(sorted, 0.75),\n };\n}\n/** Silverman's rule of thumb for the smoothing of a Gaussian kernel. */\nfunction silverman(stats: Stats) {\n if (stats.n < 2) return 1;\n const mean = stats.sorted.reduce((sum, value) => sum + value, 0) / stats.n;\n const sd = Math.sqrt(stats.sorted.reduce((sum, value) => sum + (value - mean) ** 2, 0) / (stats.n - 1));\n const spread = Math.min(sd, (stats.q3 - stats.q1) / 1.34 || sd);\n return Math.max(1e-6, 0.9 * (spread || 1) * Math.pow(stats.n, -0.2));\n}\nfunction niceStep(span: number, count: number) {\n const raw = span / Math.max(1, count) || 1;\n const power = Math.pow(10, Math.floor(Math.log10(raw)));\n const unit = raw / power;\n return (unit >= 5 ? 5 : unit >= 2 ? 2 : 1) * power;\n}\n/** Samples a Gaussian kernel density across the domain. */\nfunction density(stats: Stats, lo: number, hi: number, bandwidth: number) {\n const xs: number[] = [];\n const ys: number[] = [];\n const norm = 1 / (Math.max(1, stats.n) * bandwidth * Math.sqrt(2 * Math.PI));\n for (let i = 0; i < SAMPLES; i++) {\n const x = lo + ((hi - lo) * i) / (SAMPLES - 1);\n let sum = 0;\n for (const value of stats.sorted) {\n const u = (x - value) / bandwidth;\n if (u > -5 && u < 5) sum += Math.exp(-0.5 * u * u);\n }\n xs.push(x);\n ys.push(sum * norm);\n }\n return { xs, ys };\n}\nconst heightAt = (shape: Shape, x: number) => {\n const { xs, ys } = shape;\n if (x <= xs[0]! || x >= xs[xs.length - 1]!) return 0;\n let i = 1;\n while (i < xs.length - 1 && xs[i]! < x) i++;\n const t = (x - xs[i - 1]!) / (xs[i]! - xs[i - 1]! || 1);\n return mix(ys[i - 1]!, ys[i]!, t);\n};\n/** Ridge tone: one hue, the first series colour, from a light tint (low median) to full strength (high median), so the scale never passes through a muddy middle. */\nconst toneOf = (t: number) => `color-mix(in oklab, var(--color-chart-1) ${Math.round(38 + clamp(t, 0, 1) * 62)}%, var(--color-surface))`;\n\nexport const Ridgeline = forwardRef<HTMLElement, RidgelineProps>(function Ridgeline(\n {\n series,\n label,\n unit = \"\",\n formatValue,\n domain,\n overlap = 2.4,\n rowHeight = 30,\n bandwidth,\n tint = true,\n active,\n defaultActive = null,\n onActiveChange,\n emptyLabel = \"No data yet\",\n className,\n },\n ref,\n) {\n const figure = useRef<HTMLElement | null>(null);\n const refs = useMemo(() => mergeRefs(ref, figure), [ref]);\n const plot = useRef<HTMLDivElement>(null);\n const tip = useRef<HTMLDivElement>(null);\n const cross = useRef<HTMLDivElement>(null);\n // A true minus sign keeps negative values tight and lined up with the tabular digits.\n const format = (value: number) => (formatValue ? formatValue(value) : `${GROUPED.format(value).replace(\"-\", \"−\")}${unit}`);\n\n const [width, setWidth] = useState(0);\n useIsomorphicLayoutEffect(() => {\n const node = plot.current;\n if (!node || typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(() => setWidth(node.clientWidth));\n observer.observe(node);\n setWidth(node.clientWidth);\n return () => observer.disconnect();\n }, []);\n\n // Targets: one density per series on a shared domain, scaled so the tallest peak of all rises `overlap` rows.\n const signature = JSON.stringify([series, domain, bandwidth]);\n const model = useMemo(() => {\n const stats = series.map((entry) => statsOf(entry.values));\n const widths = stats.map((entry) => bandwidth ?? silverman(entry));\n const filled = stats.map((entry, index) => ({ entry, room: 2.5 * widths[index]! })).filter(({ entry }) => entry.n);\n let lo = domain?.[0] ?? Math.min(...filled.map(({ entry, room }) => entry.min - room));\n let hi = domain?.[1] ?? Math.max(...filled.map(({ entry, room }) => entry.max + room));\n if (!Number.isFinite(lo) || !Number.isFinite(hi) || lo === hi) {\n lo = 0;\n hi = 1;\n }\n if (!domain) {\n const step = niceStep(hi - lo, 5);\n lo = Math.floor(lo / step) * step;\n hi = Math.ceil(hi / step) * step;\n }\n const curves = stats.map((entry, index) =>\n entry.n\n ? density(entry, lo, hi, widths[index]!)\n : { xs: Array.from({ length: SAMPLES }, (_, i) => lo + ((hi - lo) * i) / (SAMPLES - 1)), ys: new Array<number>(SAMPLES).fill(0) },\n );\n const peak = Math.max(1e-9, ...curves.flatMap((curve) => curve.ys));\n const shapes = new Map<string, Shape>(\n series.map((entry, index) => {\n const curve = curves[index]!;\n const stat = stats[index]!;\n return [entry.id, { xs: curve.xs, ys: curve.ys.map((y) => y / peak), row: index, q1: stat.q1, median: stat.median, q3: stat.q3 }];\n }),\n );\n return { stats: new Map(series.map((entry, index) => [entry.id, stats[index]!])), shapes, lo, hi };\n // The signature stands for the series, the domain and the bandwidth.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [signature]);\n\n const [ownActive, setOwnActive] = useState<string | null>(defaultActive);\n const current = active !== undefined ? active : ownActive;\n const setCurrent = (id: string | null) => {\n if (active === undefined) setOwnActive(id);\n if (id !== current) onActiveChange?.(id);\n };\n const [cursor, setCursor] = useState<{ value: number; pointerY: number | null } | null>(null);\n\n const narrow = width > 0 && width < 420;\n const gutter = narrow ? 36 : 52;\n const top = Math.ceil((overlap - 1) * rowHeight) + LIFT + 8;\n const height = top + series.length * rowHeight + AXIS;\n const plotWidth = Math.max(40, width - gutter - 4);\n const baselineOf = (row: number) => top + (row + 1) * rowHeight;\n\n // Drawn geometry lives outside React; a spring interpolates it from what is on screen to the new targets.\n const drawn = useRef({ shapes: new Map<string, Shape>(), lo: 0, hi: 1 });\n const geometry = useRef({ gutter, plotWidth, rowHeight, overlap, top, current });\n const xOf = (value: number) => {\n const d = drawn.current;\n return gutter + ((value - d.lo) / (d.hi - d.lo || 1)) * plotWidth;\n };\n\n const paint = () => {\n const root = plot.current;\n if (!root) return;\n const d = drawn.current;\n const g = geometry.current;\n const sx = (value: number) => g.gutter + ((value - d.lo) / (d.hi - d.lo || 1)) * g.plotWidth;\n const lift = g.rowHeight * g.overlap;\n /** A ridge as a path; `from` and `to` cut it to a stretch of the axis (the middle half). */\n const curvePath = (shape: Shape, closed: boolean, from = -Infinity, to = Infinity) => {\n const base = g.top + (shape.row + 1) * g.rowHeight;\n const points: string[] = [];\n const push = (x: number, y: number) => points.push(`${sx(x).toFixed(2)},${(base - y * lift).toFixed(2)}`);\n if (from > -Infinity) push(from, heightAt(shape, from));\n shape.xs.forEach((x, i) => {\n if (x > from && x < to) push(x, shape.ys[i]!);\n });\n if (to < Infinity) push(to, heightAt(shape, to));\n if (!points.length) return \"\";\n const first = from > -Infinity ? from : shape.xs[0]!;\n const last = to < Infinity ? to : shape.xs[shape.xs.length - 1]!;\n return closed ? `M${sx(first).toFixed(2)},${base}L${points.join(\"L\")}L${sx(last).toFixed(2)},${base}Z` : `M${points.join(\"L\")}`;\n };\n const mark = (node: Element | null, shape: Shape) => {\n if (!node) return;\n const x = sx(shape.median).toFixed(2);\n const base = g.top + (shape.row + 1) * g.rowHeight;\n node.setAttribute(\"x1\", x);\n node.setAttribute(\"x2\", x);\n node.setAttribute(\"y1\", String(base));\n node.setAttribute(\"y2\", (base - heightAt(shape, shape.median) * lift).toFixed(2));\n };\n for (const [id, shape] of d.shapes) {\n const group = root.querySelector(`[data-ridge=\"${CSS.escape(id)}\"]`);\n group?.querySelector(\"[data-part=fill]\")?.setAttribute(\"d\", curvePath(shape, true));\n group?.querySelector(\"[data-part=line]\")?.setAttribute(\"d\", curvePath(shape, false));\n mark(group?.querySelector(\"[data-part=median]\") ?? null, shape);\n }\n const shape = g.current ? d.shapes.get(g.current) : undefined;\n if (shape) {\n const lens = root.querySelector(\"[data-part=lens]\");\n lens?.querySelector(\"[data-part=lens-fill]\")?.setAttribute(\"d\", curvePath(shape, true));\n lens?.querySelector(\"[data-part=lens-line]\")?.setAttribute(\"d\", curvePath(shape, false));\n lens?.querySelector(\"[data-part=lens-band]\")?.setAttribute(\"d\", curvePath(shape, true, shape.q1, shape.q3));\n mark(lens?.querySelector(\"[data-part=lens-median]\") ?? null, shape);\n }\n for (const node of root.querySelectorAll<HTMLElement>(\"[data-tick]\")) {\n node.style.transform = `translate3d(${sx(Number(node.dataset.tick)).toFixed(2)}px, 0, 0)`;\n }\n };\n const paintRef = useRef(paint);\n useIsomorphicLayoutEffect(() => {\n geometry.current = { gutter, plotWidth, rowHeight, overlap, top, current };\n paintRef.current = paint;\n paint();\n });\n\n // The ridges roll in once a third of the chart is in view.\n const [shown, setShown] = useState(false);\n useEffect(() => {\n const node = figure.current;\n if (!node || prefersReducedMotion() || typeof IntersectionObserver === \"undefined\") {\n setShown(true);\n return;\n }\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (!entry?.isIntersecting) return;\n observer.disconnect();\n setShown(true);\n },\n { threshold: 0.3 },\n );\n observer.observe(node);\n return () => observer.disconnect();\n }, []);\n\n // New data morphs every ridge, and the axis, from what is on screen; the first time, ridges grow from flat, a beat apart from the top row down.\n useEffect(() => {\n if (!shown) return;\n const d = drawn.current;\n const first = d.shapes.size === 0;\n const from = new Map<string, Shape>();\n for (const [id, target] of model.shapes) {\n const now = d.shapes.get(id);\n from.set(id, now ? { ...now, xs: [...now.xs], ys: [...now.ys] } : { ...target, ys: target.ys.map(() => 0), q1: target.median, q3: target.median });\n }\n const fromLo = first ? model.lo : d.lo;\n const fromHi = first ? model.hi : d.hi;\n const settle = () => {\n d.shapes = new Map([...model.shapes].map(([id, shape]) => [id, { ...shape }]));\n d.lo = model.lo;\n d.hi = model.hi;\n paintRef.current();\n };\n d.shapes = new Map([...from].map(([id, shape]) => [id, { ...shape, xs: [...shape.xs], ys: [...shape.ys] }]));\n return tween(\n first ? SWELL : REVEAL,\n (t) => {\n d.lo = mix(fromLo, model.lo, t);\n d.hi = mix(fromHi, model.hi, t);\n for (const [id, to] of model.shapes) {\n const f = from.get(id)!;\n const out = d.shapes.get(id)!;\n const local = first ? clamp((t - to.row * 0.025) / (1 - Math.min(0.5, model.shapes.size * 0.025)), 0, 1) : t;\n for (let i = 0; i < SAMPLES; i++) {\n out.xs[i] = mix(f.xs[i]!, to.xs[i]!, local);\n out.ys[i] = mix(f.ys[i]!, to.ys[i]!, local);\n }\n out.row = mix(f.row, to.row, local);\n out.q1 = mix(f.q1, to.q1, local);\n out.median = mix(f.median, to.median, local);\n out.q3 = mix(f.q3, to.q3, local);\n }\n paintRef.current();\n },\n settle,\n );\n }, [shown, model]);\n\n // Axis ticks for the target domain; their positions follow the drawn domain every frame.\n const tickCount = Math.max(2, Math.floor(plotWidth / 72));\n const step = niceStep(model.hi - model.lo, tickCount);\n const ticks: number[] = [];\n for (let value = Math.ceil(model.lo / step) * step; value <= model.hi + 1e-9; value += step) ticks.push(Math.round(value * 1e6) / 1e6 || 0);\n\n const activeStats = current ? model.stats.get(current) : undefined;\n const activeSeries = current ? series.find((entry) => entry.id === current) : undefined;\n const reading =\n cursor && activeStats\n ? { value: cursor.value, below: activeStats.n ? activeStats.sorted.filter((value) => value <= cursor.value).length / activeStats.n : 0 }\n : null;\n // The tooltip keeps its last content while it fades out, so it never collapses to an empty box on leave.\n const [held, setHeld] = useState<{ id: string; value: number | null } | null>(null);\n if (current && (held?.id !== current || held.value !== (reading?.value ?? null))) setHeld({ id: current, value: reading?.value ?? null });\n const tipSeries = held ? series.find((entry) => entry.id === held.id) : undefined;\n const tipStats = held ? model.stats.get(held.id) : undefined;\n const tipBelow = held && held.value !== null && tipStats?.n ? tipStats.sorted.filter((value) => value <= held.value!).length / tipStats.n : 0;\n\n // The tooltip trails the pointer or the keyboard cursor and stays inside the chart; it glides between ridges once showing.\n const shownBefore = useRef(false);\n useIsomorphicLayoutEffect(() => {\n const bubble = tip.current;\n const shape = current ? model.shapes.get(current) : undefined;\n if (cross.current) cross.current.style.transform = `translate3d(${reading ? xOf(reading.value).toFixed(2) : 0}px, 0, 0)`;\n if (!bubble || !shape || !width) {\n shownBefore.current = false;\n return;\n }\n const tw = bubble.offsetWidth;\n const th = bubble.offsetHeight;\n const ax = reading ? xOf(reading.value) : xOf(shape.median);\n const ay = cursor?.pointerY ?? baselineOf(shape.row) - heightAt(shape, shape.median) * rowHeight * overlap - LIFT;\n let left = ax + TIP;\n if (left + tw > width) left = ax - TIP - tw;\n let y = ay - th - TIP;\n if (y < 0) y = ay + TIP;\n if (!shownBefore.current) bubble.style.transition = \"none\";\n bubble.style.translate = `${clamp(left, 0, Math.max(0, width - tw))}px ${clamp(y, 0, Math.max(0, height - th))}px`;\n if (!shownBefore.current) {\n void bubble.offsetWidth;\n bubble.style.transition = \"\";\n }\n shownBefore.current = true;\n });\n\n const valueAt = (x: number) => {\n const d = drawn.current;\n return d.lo + clamp((x - gutter) / plotWidth, 0, 1) * (d.hi - d.lo);\n };\n /** The ridge under the pointer: the front-most one whose outline holds it, else the row it is in. */\n const pick = (x: number, y: number) => {\n const value = valueAt(x);\n const lift = rowHeight * overlap;\n let best: Shape | null = null;\n let bestId: string | null = null;\n for (const [id, shape] of drawn.current.shapes) {\n const base = baselineOf(shape.row);\n const h = heightAt(shape, value) * lift;\n if (y <= base + 2 && y >= base - h - 4 && (!best || shape.row > best.row)) {\n best = shape;\n bestId = id;\n }\n }\n if (!bestId) {\n const row = clamp(Math.floor((y - top) / rowHeight), 0, series.length - 1);\n bestId = series[row]?.id ?? null;\n }\n return { id: bestId, value };\n };\n const onPointerMove = (event: PointerEvent<HTMLDivElement>) => {\n const rect = event.currentTarget.getBoundingClientRect();\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n if (x < gutter - 8 || y > height - AXIS + 4) {\n if (event.pointerType === \"mouse\") {\n setCurrent(null);\n setCursor(null);\n }\n return;\n }\n const hit = pick(x, y);\n setCurrent(hit.id);\n setCursor({ value: hit.value, pointerY: y });\n };\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n const at = current ? series.findIndex((entry) => entry.id === current) : -1;\n const choose = (index: number) => {\n event.preventDefault();\n const next = series[clamp(index, 0, series.length - 1)];\n if (!next) return;\n setCurrent(next.id);\n setCursor({ value: cursor?.value ?? model.stats.get(next.id)?.median ?? model.lo, pointerY: null });\n };\n const nudge = (direction: number) => {\n event.preventDefault();\n if (!current) {\n choose(0);\n return;\n }\n const base = cursor?.value ?? model.stats.get(current)?.median ?? model.lo;\n setCursor({ value: clamp((Math.round(base / step) + direction) * step, model.lo, model.hi), pointerY: null });\n };\n if (event.key === \"ArrowDown\") choose(at + 1);\n else if (event.key === \"ArrowUp\") choose(at < 0 ? 0 : at - 1);\n else if (event.key === \"Home\") choose(0);\n else if (event.key === \"End\") choose(series.length - 1);\n else if (event.key === \"ArrowRight\") nudge(1);\n else if (event.key === \"ArrowLeft\") nudge(-1);\n else if (event.key === \"Escape\" && current) {\n event.preventDefault();\n setCurrent(null);\n setCursor(null);\n }\n };\n\n const empty = !series.length || series.every((entry) => !entry.values.length);\n const ridgeColor = (value: number) => (tint ? toneOf((value - model.lo) / (model.hi - model.lo || 1)) : \"var(--color-chart-1)\");\n const describe = (entry: RidgelineSeries) => {\n const s = model.stats.get(entry.id)!;\n return `${entry.label}: median ${format(s.median)}, middle half ${format(s.q1)} to ${format(s.q3)}, range ${format(s.min)} to ${format(s.max)}, ${s.n} values`;\n };\n const spoken = activeSeries ? `${describe(activeSeries)}${reading ? `. ${PERCENT.format(reading.below)} at or below ${format(reading.value)}` : \"\"}` : \"\";\n const summary = empty ? `${label}. ${emptyLabel}.` : `${label}. ${series.map(describe).join(\". \")}.`;\n\n return (\n <figure ref={refs} data-slot=\"ridgeline\" aria-label={label} className={cn(\"ridgeline box-border font-sans text-foreground\", className)}>\n <div\n ref={plot}\n data-slot=\"ridgeline-plot\"\n data-active={current ? \"\" : undefined}\n data-scrubbing={current ? \"\" : undefined}\n data-cursor={reading ? \"\" : undefined}\n role={empty ? undefined : \"slider\"}\n tabIndex={empty ? undefined : 0}\n aria-label={empty ? undefined : `${label}, choose a ridge`}\n aria-orientation={empty ? undefined : \"vertical\"}\n aria-valuemin={empty ? undefined : 1}\n aria-valuemax={empty ? undefined : series.length}\n aria-valuenow={empty ? undefined : (activeSeries ? series.indexOf(activeSeries) : 0) + 1}\n aria-valuetext={empty ? undefined : spoken || summary}\n className=\"ridgeline-plot\"\n style={{ height }}\n onPointerMove={onPointerMove}\n onPointerDown={onPointerMove}\n onPointerLeave={(event) => {\n if (event.pointerType === \"mouse\") {\n setCurrent(null);\n setCursor(null);\n }\n }}\n onKeyDown={onKeyDown}\n onBlur={() => {\n setCurrent(null);\n setCursor(null);\n }}\n >\n <div aria-hidden=\"true\" className=\"pointer-events-none absolute inset-x-0 top-0\" style={{ height: height - AXIS + 22 }}>\n {ticks.map((value) => (\n <div key={value} data-tick={value} className=\"ridgeline-tick motion-safe:animate-fade-in\" style={{ top: top - rowHeight * 0.5 }}>\n <span className=\"ridgeline-tick-label\">{format(value)}</span>\n </div>\n ))}\n </div>\n <div ref={cross} aria-hidden=\"true\" className=\"ridgeline-crosshair\" style={{ top: top - rowHeight * 0.5, height: height - AXIS - top + rowHeight * 0.5 }} />\n <svg width={width || undefined} height={height} viewBox={`0 0 ${Math.max(1, width)} ${height}`} aria-hidden=\"true\" focusable=\"false\" className=\"absolute inset-0 block overflow-visible\">\n {series.map((entry) => (\n <g\n key={entry.id}\n data-ridge={entry.id}\n data-dim={(current !== null && current !== entry.id) || undefined}\n data-lifted={current === entry.id || undefined}\n className=\"ridgeline-ridge\"\n style={{ \"--ridge\": ridgeColor(model.stats.get(entry.id)?.median ?? model.lo) } as CSSProperties}\n >\n <path data-part=\"fill\" className=\"ridgeline-fill\" />\n <line data-part=\"median\" className=\"ridgeline-median\" />\n <path data-part=\"line\" className=\"ridgeline-line\" />\n </g>\n ))}\n <g\n data-part=\"lens\"\n data-on={current ? \"\" : undefined}\n className=\"ridgeline-lens\"\n style={tipStats ? ({ \"--ridge\": ridgeColor(tipStats.median) } as CSSProperties) : undefined}\n >\n <path data-part=\"lens-fill\" className=\"ridgeline-lens-fill\" />\n <path data-part=\"lens-band\" className=\"ridgeline-lens-band\" />\n <line data-part=\"lens-median\" className=\"ridgeline-lens-median\" />\n <path data-part=\"lens-line\" className=\"ridgeline-lens-line\" />\n </g>\n </svg>\n <div aria-hidden=\"true\" className=\"pointer-events-none absolute inset-0\">\n {series.map((entry, index) => (\n <span key={entry.id} data-active={current === entry.id || undefined} className=\"ridgeline-row-label\" style={{ top: baselineOf(index) - 18, width: gutter - 10 }}>\n {entry.label}\n </span>\n ))}\n </div>\n {empty ? <p className=\"pointer-events-none absolute inset-0 m-0 grid place-items-center text-sm text-muted-foreground\">{emptyLabel}</p> : null}\n <div ref={tip} aria-hidden=\"true\" data-slot=\"ridgeline-tooltip\" className=\"line-chart-tooltip\">\n {tipSeries && tipStats ? (\n <>\n <p className=\"m-0 mb-0.5 text-xs text-text-secondary\">{tipSeries.label}</p>\n <p className=\"ridgeline-tip-row text-sm font-medium\">\n <span className=\"text-xs font-normal text-muted-foreground\">Median</span>\n <span>{format(tipStats.median)}</span>\n </p>\n <p className=\"ridgeline-tip-row text-xs\">\n <span className=\"text-muted-foreground\">Middle half</span>\n <span>\n {format(tipStats.q1)} to {format(tipStats.q3)}\n </span>\n </p>\n <p className=\"ridgeline-tip-row text-xs\">\n <span className=\"text-muted-foreground\">Range</span>\n <span>\n {format(tipStats.min)} to {format(tipStats.max)}\n </span>\n </p>\n {held?.value != null ? (\n <p className=\"m-0 mt-1 text-xs tabular-nums text-muted-foreground\">\n {PERCENT.format(tipBelow)} at or below {format(held.value)}\n </p>\n ) : null}\n </>\n ) : null}\n </div>\n </div>\n {tint && !empty ? (\n <div aria-hidden=\"true\" className=\"mt-3 flex flex-wrap items-center justify-end gap-2 text-xs tabular-nums text-muted-foreground\">\n <span className=\"me-1 text-text-secondary\">Median</span>\n <span>{format(model.lo)}</span>\n <span className=\"inline-flex gap-0.5\">\n {[0, 0.25, 0.5, 0.75, 1].map((at) => (\n <span key={at} className=\"ridgeline-step\" style={{ \"--ridge\": toneOf(at) } as CSSProperties} />\n ))}\n </span>\n <span>{format(model.hi)}</span>\n </div>\n ) : null}\n <p className=\"sr-only\">{summary}</p>\n <p className=\"sr-only\" aria-live=\"polite\" aria-atomic=\"true\">\n {spoken}\n </p>\n {empty ? null : (\n <div className=\"sr-only\">\n <table>\n <caption>{label}</caption>\n <thead>\n <tr>\n <th scope=\"col\">Series</th>\n <th scope=\"col\">Median</th>\n <th scope=\"col\">First quartile</th>\n <th scope=\"col\">Third quartile</th>\n <th scope=\"col\">Lowest</th>\n <th scope=\"col\">Highest</th>\n <th scope=\"col\">Count</th>\n </tr>\n </thead>\n <tbody>\n {series.map((entry) => {\n const s = model.stats.get(entry.id)!;\n return (\n <tr key={entry.id}>\n <th scope=\"row\">{entry.label}</th>\n <td>{format(s.median)}</td>\n <td>{format(s.q1)}</td>\n <td>{format(s.q3)}</td>\n <td>{format(s.min)}</td>\n <td>{format(s.max)}</td>\n <td>{s.n}</td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n )}\n </figure>\n );\n});\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { ScrollArea, ScrollAreaProps, scrollAreaVariants } from "./scroll-area.js";
|
|
2
|
-
export { ScrollArea, type ScrollAreaProps, scrollAreaVariants };
|
|
1
|
+
import { ScrollArea, ScrollAreaProps, scrollAreaRootVariants, scrollAreaVariants } from "./scroll-area.js";
|
|
2
|
+
export { ScrollArea, type ScrollAreaProps, scrollAreaRootVariants, scrollAreaVariants };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { ScrollArea, scrollAreaVariants } from "./scroll-area.js";
|
|
2
|
-
export { ScrollArea, scrollAreaVariants };
|
|
1
|
+
import { ScrollArea, scrollAreaRootVariants, scrollAreaVariants } from "./scroll-area.js";
|
|
2
|
+
export { ScrollArea, scrollAreaRootVariants, scrollAreaVariants };
|
|
@@ -1,38 +1,44 @@
|
|
|
1
1
|
import { ComponentPropsWithoutRef, ReactNode } from "react";
|
|
2
2
|
//#region src/scroll-area/scroll-area.d.ts
|
|
3
3
|
/**
|
|
4
|
-
* ScrollArea
|
|
5
|
-
*
|
|
4
|
+
* ScrollArea: a native scroll container with thin overlay scrollbars and edge
|
|
5
|
+
* fades. React Aria has no equivalent, so the scrolling stays the browser's --
|
|
6
|
+
* keyboard, touch momentum and scroll snap all behave as the platform expects --
|
|
7
|
+
* and only the scrollbar is drawn here.
|
|
6
8
|
*
|
|
7
|
-
* Census: fourteen paths match, thirteen are counted, ELEVEN render
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* `orientation="horizontal"` has zero call sites.
|
|
9
|
+
* Census: fourteen paths match, thirteen are counted, ELEVEN render anything,
|
|
10
|
+
* and across them 17 uses. Every one passes `className` and nothing else, and 13
|
|
11
|
+
* of the 17 are a height or flex constraint plus padding. The legacy Radix one
|
|
12
|
+
* cannot be scrolled by keyboard at all.
|
|
12
13
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* `ScrollArea` cannot be scrolled by keyboard at all.
|
|
14
|
+
* The native scrollbar is hidden and replaced by an overlay pill that appears
|
|
15
|
+
* while scrolling or hovering and fades away at rest (or stays, with
|
|
16
|
+
* `scrollbars="always"`). It is written straight to the DOM on each scroll
|
|
17
|
+
* frame, so scrolling never re-renders React. The pill can be dragged, and
|
|
18
|
+
* pressing its track pages toward the pointer.
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* WHERE THINGS LAND. `className`, `style` and the rest go on the ROOT, the box
|
|
21
|
+
* that carries the height and the optional card. `ref` and `viewportClassName`
|
|
22
|
+
* go on the VIEWPORT, the element that really scrolls -- so a caller can call
|
|
23
|
+
* `ref.current.scrollTo(...)` or `scrollBy(...)` for a "back to top" or an
|
|
24
|
+
* arrow button, and put padding on the content without moving the scrollbar
|
|
25
|
+
* inside it.
|
|
23
26
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* those but is non-standard and Firefox has never supported it. This
|
|
28
|
-
* component uses the standard properties only.
|
|
27
|
+
* The font is declared here: the reset in @seekalfred/styles is OPT-IN, so a
|
|
28
|
+
* consumer may load none, and a scroll area's content (a list of plain
|
|
29
|
+
* paragraphs) would render in the browser's serif.
|
|
29
30
|
*/
|
|
30
|
-
export declare const
|
|
31
|
+
export declare const scrollAreaRootVariants: (props?: ({
|
|
32
|
+
framed?: boolean | null | undefined;
|
|
33
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
34
|
+
export declare const scrollAreaVariants: (props?: ({
|
|
35
|
+
orientation?: "vertical" | "horizontal" | "both" | null | undefined;
|
|
36
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
31
37
|
/**
|
|
32
38
|
* A scrolling region.
|
|
33
39
|
*
|
|
34
40
|
* @example
|
|
35
|
-
* <ScrollArea label="
|
|
41
|
+
* <ScrollArea label="Activity" className="h-64" framed fade={28}>...</ScrollArea>
|
|
36
42
|
*/
|
|
37
43
|
export interface ScrollAreaProps extends ComponentPropsWithoutRef<"div"> {
|
|
38
44
|
children?: ReactNode;
|
|
@@ -41,7 +47,7 @@ export interface ScrollAreaProps extends ComponentPropsWithoutRef<"div"> {
|
|
|
41
47
|
*
|
|
42
48
|
* **Required**, and it took a failing test to get here. A focusable
|
|
43
49
|
* element with no role fails axe `focus-order-semantics`, so the
|
|
44
|
-
* keyboard fix
|
|
50
|
+
* keyboard fix cannot ship without a role -- and a role with no
|
|
45
51
|
* accessible name is a violation of its own. Naming it is the only
|
|
46
52
|
* combination that is actually correct.
|
|
47
53
|
*
|
|
@@ -53,16 +59,56 @@ export interface ScrollAreaProps extends ComponentPropsWithoutRef<"div"> {
|
|
|
53
59
|
* jump to it is the point.
|
|
54
60
|
*/
|
|
55
61
|
label: string;
|
|
62
|
+
/**
|
|
63
|
+
* Which axes scroll.
|
|
64
|
+
*
|
|
65
|
+
* @default "vertical"
|
|
66
|
+
*/
|
|
67
|
+
orientation?: "vertical" | "horizontal" | "both";
|
|
68
|
+
/**
|
|
69
|
+
* Fade the content out at an edge by exactly as much as there is content hidden
|
|
70
|
+
* past it, up to this many pixels: the fade grows in with the first pixels of
|
|
71
|
+
* scroll and is gone at the ends, so an edge fades only while content
|
|
72
|
+
* overflows past it. `0` turns it off, and the default leaves the area as it
|
|
73
|
+
* was. Written on each scroll frame straight to the element, so scrolling
|
|
74
|
+
* never re-renders.
|
|
75
|
+
*
|
|
76
|
+
* @default 0
|
|
77
|
+
*/
|
|
78
|
+
fade?: number;
|
|
79
|
+
/**
|
|
80
|
+
* `auto` shows the scrollbar while scrolling or hovering and fades it away at
|
|
81
|
+
* rest; `always` keeps it visible whenever the content overflows.
|
|
82
|
+
*
|
|
83
|
+
* @default "auto"
|
|
84
|
+
*/
|
|
85
|
+
scrollbars?: "auto" | "always";
|
|
86
|
+
/**
|
|
87
|
+
* How long the scrollbar lingers after scrolling stops, in ms.
|
|
88
|
+
*
|
|
89
|
+
* @default 900
|
|
90
|
+
*/
|
|
91
|
+
hideDelay?: number;
|
|
92
|
+
/**
|
|
93
|
+
* Draws the area as a white card: the panel radius and a light border. The
|
|
94
|
+
* content is clipped to it, so an edge fade and the scrollbar sit inside.
|
|
95
|
+
*
|
|
96
|
+
* @default false
|
|
97
|
+
*/
|
|
98
|
+
framed?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Classes for the viewport, the element that scrolls. Padding for the
|
|
101
|
+
* content goes here.
|
|
102
|
+
*/
|
|
103
|
+
viewportClassName?: string;
|
|
56
104
|
/**
|
|
57
105
|
* Change this when the contents change, and the region scrolls back to the
|
|
58
106
|
* top.
|
|
59
107
|
*
|
|
60
|
-
* This stays a declarative prop even though a `ref`
|
|
108
|
+
* This stays a declarative prop even though a `ref` exists: reaching
|
|
61
109
|
* for it would mean the caller writes `ref.current.scrollTop = 0` in their
|
|
62
110
|
* own effect on every content change, which is worse ergonomics than a
|
|
63
|
-
* prop that says "reset when this value changes."
|
|
64
|
-
* independent of whether a ref is available, not a consequence of one
|
|
65
|
-
* being withheld.
|
|
111
|
+
* prop that says "reset when this value changes."
|
|
66
112
|
*
|
|
67
113
|
* Sheet forwards its own `scrollResetKey` straight through: going a level
|
|
68
114
|
* deeper in a panel and landing halfway down the new view is disorienting,
|
|
@@ -70,6 +116,7 @@ export interface ScrollAreaProps extends ComponentPropsWithoutRef<"div"> {
|
|
|
70
116
|
*/
|
|
71
117
|
scrollResetKey?: string | number;
|
|
72
118
|
}
|
|
119
|
+
/** The `ref` reaches the VIEWPORT, the element that scrolls. `onScroll` runs on its scroll events. */
|
|
73
120
|
export declare const ScrollArea: import("react").ForwardRefExoticComponent<ScrollAreaProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
74
121
|
//#endregion
|
|
75
122
|
//# sourceMappingURL=scroll-area.d.ts.map
|
|
@@ -1,65 +1,236 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { cn } from "../lib/cn.js";
|
|
2
|
+
import { cn, cnAll } from "../lib/cn.js";
|
|
3
3
|
import { mergeRefs } from "../lib/merge-refs.js";
|
|
4
|
+
import { prefersReducedMotion, useIsomorphicLayoutEffect } from "../lib/motion.js";
|
|
4
5
|
import { cva } from "class-variance-authority";
|
|
5
|
-
import { forwardRef, useEffect, useMemo, useRef } from "react";
|
|
6
|
-
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
import { forwardRef, useCallback, useEffect, useMemo, useRef } from "react";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
8
|
//#region src/scroll-area/scroll-area.tsx
|
|
8
9
|
/**
|
|
9
|
-
* ScrollArea
|
|
10
|
-
*
|
|
10
|
+
* ScrollArea: a native scroll container with thin overlay scrollbars and edge
|
|
11
|
+
* fades. React Aria has no equivalent, so the scrolling stays the browser's --
|
|
12
|
+
* keyboard, touch momentum and scroll snap all behave as the platform expects --
|
|
13
|
+
* and only the scrollbar is drawn here.
|
|
11
14
|
*
|
|
12
|
-
* Census: fourteen paths match, thirteen are counted, ELEVEN render
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* `orientation="horizontal"` has zero call sites.
|
|
15
|
+
* Census: fourteen paths match, thirteen are counted, ELEVEN render anything,
|
|
16
|
+
* and across them 17 uses. Every one passes `className` and nothing else, and 13
|
|
17
|
+
* of the 17 are a height or flex constraint plus padding. The legacy Radix one
|
|
18
|
+
* cannot be scrolled by keyboard at all.
|
|
17
19
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* `ScrollArea` cannot be scrolled by keyboard at all.
|
|
20
|
+
* The native scrollbar is hidden and replaced by an overlay pill that appears
|
|
21
|
+
* while scrolling or hovering and fades away at rest (or stays, with
|
|
22
|
+
* `scrollbars="always"`). It is written straight to the DOM on each scroll
|
|
23
|
+
* frame, so scrolling never re-renders React. The pill can be dragged, and
|
|
24
|
+
* pressing its track pages toward the pointer.
|
|
24
25
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
26
|
+
* WHERE THINGS LAND. `className`, `style` and the rest go on the ROOT, the box
|
|
27
|
+
* that carries the height and the optional card. `ref` and `viewportClassName`
|
|
28
|
+
* go on the VIEWPORT, the element that really scrolls -- so a caller can call
|
|
29
|
+
* `ref.current.scrollTo(...)` or `scrollBy(...)` for a "back to top" or an
|
|
30
|
+
* arrow button, and put padding on the content without moving the scrollbar
|
|
31
|
+
* inside it.
|
|
28
32
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* those but is non-standard and Firefox has never supported it. This
|
|
33
|
-
* component uses the standard properties only.
|
|
33
|
+
* The font is declared here: the reset in @seekalfred/styles is OPT-IN, so a
|
|
34
|
+
* consumer may load none, and a scroll area's content (a list of plain
|
|
35
|
+
* paragraphs) would render in the browser's serif.
|
|
34
36
|
*/
|
|
37
|
+
const scrollAreaRootVariants = cva(["scroll-area relative flex min-h-0 min-w-0 flex-col overflow-hidden box-border font-sans"], {
|
|
38
|
+
variants: {
|
|
39
|
+
/** The area is a white card: the panel radius and a hairline border. */
|
|
40
|
+
framed: {
|
|
41
|
+
true: "rounded-panel border-(length:--border-width) border-border bg-surface",
|
|
42
|
+
false: ""
|
|
43
|
+
} },
|
|
44
|
+
defaultVariants: { framed: false }
|
|
45
|
+
});
|
|
35
46
|
const scrollAreaVariants = cva([
|
|
36
|
-
"
|
|
37
|
-
"box-border",
|
|
38
|
-
"scrollbar-thin scrollbar-thumb-border scrollbar-track-transparent",
|
|
47
|
+
"scroll-area-viewport min-h-0 min-w-0 flex-1 overscroll-contain box-border",
|
|
39
48
|
"outline-none",
|
|
40
49
|
"focus-visible:outline-solid",
|
|
41
50
|
"focus-visible:outline-(length:--focus-ring-width)",
|
|
42
51
|
"focus-visible:outline-offset-(--focus-ring-offset)",
|
|
43
52
|
"focus-visible:outline-(--color-ring)"
|
|
44
|
-
]
|
|
45
|
-
|
|
46
|
-
|
|
53
|
+
], {
|
|
54
|
+
variants: { orientation: {
|
|
55
|
+
vertical: "overflow-x-hidden overflow-y-auto",
|
|
56
|
+
horizontal: "overflow-x-auto overflow-y-hidden",
|
|
57
|
+
both: "overflow-auto"
|
|
58
|
+
} },
|
|
59
|
+
defaultVariants: { orientation: "vertical" }
|
|
60
|
+
});
|
|
61
|
+
/** The shortest a scrollbar thumb gets, so a very long list still leaves something to grab. */
|
|
62
|
+
const MIN_THUMB = 28;
|
|
63
|
+
/** The `ref` reaches the VIEWPORT, the element that scrolls. `onScroll` runs on its scroll events. */
|
|
64
|
+
const ScrollArea = forwardRef(function ScrollArea({ className, children, label, scrollResetKey, orientation = "vertical", fade = 0, scrollbars = "auto", hideDelay = 900, framed = false, viewportClassName, onScroll, ...props }, ref) {
|
|
65
|
+
const root = useRef(null);
|
|
66
|
+
const viewport = useRef(null);
|
|
67
|
+
const tracks = useRef({
|
|
68
|
+
x: null,
|
|
69
|
+
y: null
|
|
70
|
+
});
|
|
71
|
+
const thumbs = useRef({
|
|
72
|
+
x: null,
|
|
73
|
+
y: null
|
|
74
|
+
});
|
|
75
|
+
const hideTimer = useRef(void 0);
|
|
76
|
+
const drag = useRef(null);
|
|
77
|
+
const vertical = orientation !== "horizontal";
|
|
78
|
+
const horizontal = orientation !== "vertical";
|
|
47
79
|
useEffect(() => {
|
|
48
|
-
if (
|
|
80
|
+
if (viewport.current) viewport.current.scrollTop = 0;
|
|
49
81
|
}, [scrollResetKey]);
|
|
50
|
-
const
|
|
51
|
-
|
|
82
|
+
const viewportRef = useMemo(() => mergeRefs(ref, viewport), [ref]);
|
|
83
|
+
const sync = useCallback(() => {
|
|
84
|
+
const node = viewport.current;
|
|
85
|
+
if (!node) return;
|
|
86
|
+
const { scrollTop, scrollHeight, clientHeight, scrollWidth, clientWidth } = node;
|
|
87
|
+
const maxY = Math.max(0, scrollHeight - clientHeight);
|
|
88
|
+
const maxX = Math.max(0, scrollWidth - clientWidth);
|
|
89
|
+
const left = Math.abs(node.scrollLeft);
|
|
90
|
+
if (fade > 0) {
|
|
91
|
+
node.style.setProperty("--fade-top", `${vertical ? Math.min(fade, scrollTop) : 0}px`);
|
|
92
|
+
node.style.setProperty("--fade-bottom", `${vertical ? Math.min(fade, Math.max(0, maxY - scrollTop)) : 0}px`);
|
|
93
|
+
node.style.setProperty("--fade-left", `${horizontal ? Math.min(fade, left) : 0}px`);
|
|
94
|
+
node.style.setProperty("--fade-right", `${horizontal ? Math.min(fade, Math.max(0, maxX - left)) : 0}px`);
|
|
95
|
+
}
|
|
96
|
+
const place = (axis, scroll, max, client, total) => {
|
|
97
|
+
const track = tracks.current[axis];
|
|
98
|
+
const thumb = thumbs.current[axis];
|
|
99
|
+
if (!track || !thumb) return;
|
|
100
|
+
const overflowing = max > .5;
|
|
101
|
+
track.toggleAttribute("data-hidden", !overflowing);
|
|
102
|
+
if (!overflowing) return;
|
|
103
|
+
const length = axis === "y" ? track.clientHeight : track.clientWidth;
|
|
104
|
+
const size = Math.max(MIN_THUMB, length * client / total);
|
|
105
|
+
const offset = (length - size) * (scroll / max);
|
|
106
|
+
const sign = axis === "x" && getComputedStyle(node).direction === "rtl" ? -1 : 1;
|
|
107
|
+
thumb.style[axis === "y" ? "height" : "width"] = `${size}px`;
|
|
108
|
+
thumb.style.transform = axis === "y" ? `translate3d(0, ${offset}px, 0)` : `translate3d(${offset * sign}px, 0, 0)`;
|
|
109
|
+
};
|
|
110
|
+
if (vertical) place("y", scrollTop, maxY, clientHeight, scrollHeight);
|
|
111
|
+
if (horizontal) place("x", left, maxX, clientWidth, scrollWidth);
|
|
112
|
+
root.current?.toggleAttribute("data-overflow", maxY > .5 || maxX > .5);
|
|
113
|
+
}, [
|
|
114
|
+
fade,
|
|
115
|
+
horizontal,
|
|
116
|
+
vertical
|
|
117
|
+
]);
|
|
118
|
+
useIsomorphicLayoutEffect(() => {
|
|
119
|
+
const node = viewport.current;
|
|
120
|
+
if (!node) return;
|
|
121
|
+
sync();
|
|
122
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
123
|
+
const observer = new ResizeObserver(() => sync());
|
|
124
|
+
observer.observe(node);
|
|
125
|
+
for (const child of Array.from(node.children)) observer.observe(child);
|
|
126
|
+
return () => observer.disconnect();
|
|
127
|
+
}, [sync, children]);
|
|
128
|
+
useEffect(() => () => window.clearTimeout(hideTimer.current), []);
|
|
129
|
+
const wake = () => {
|
|
130
|
+
const el = root.current;
|
|
131
|
+
if (!el) return;
|
|
132
|
+
el.setAttribute("data-scrolling", "");
|
|
133
|
+
window.clearTimeout(hideTimer.current);
|
|
134
|
+
hideTimer.current = window.setTimeout(() => el.removeAttribute("data-scrolling"), hideDelay);
|
|
135
|
+
};
|
|
136
|
+
const onThumbDown = (event, axis) => {
|
|
137
|
+
const node = viewport.current;
|
|
138
|
+
const track = tracks.current[axis];
|
|
139
|
+
const thumb = thumbs.current[axis];
|
|
140
|
+
if (!node || !track || !thumb || event.button !== 0) return;
|
|
141
|
+
event.preventDefault();
|
|
142
|
+
event.stopPropagation();
|
|
143
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
144
|
+
const length = axis === "y" ? track.clientHeight : track.clientWidth;
|
|
145
|
+
const size = axis === "y" ? thumb.offsetHeight : thumb.offsetWidth;
|
|
146
|
+
const max = axis === "y" ? node.scrollHeight - node.clientHeight : node.scrollWidth - node.clientWidth;
|
|
147
|
+
drag.current = {
|
|
148
|
+
axis,
|
|
149
|
+
start: axis === "y" ? event.clientY : event.clientX,
|
|
150
|
+
scroll: axis === "y" ? node.scrollTop : node.scrollLeft,
|
|
151
|
+
ratio: max / Math.max(1, length - size),
|
|
152
|
+
sign: axis === "x" && getComputedStyle(node).direction === "rtl" ? -1 : 1
|
|
153
|
+
};
|
|
154
|
+
root.current?.setAttribute("data-dragging", axis);
|
|
155
|
+
};
|
|
156
|
+
const onThumbMove = (event) => {
|
|
157
|
+
const state = drag.current;
|
|
158
|
+
const node = viewport.current;
|
|
159
|
+
if (!state || !node) return;
|
|
160
|
+
const travel = (state.axis === "y" ? event.clientY : event.clientX) - state.start;
|
|
161
|
+
const to = state.scroll + travel * state.ratio * state.sign;
|
|
162
|
+
if (state.axis === "y") node.scrollTop = to;
|
|
163
|
+
else node.scrollLeft = to;
|
|
164
|
+
};
|
|
165
|
+
const onThumbUp = (event) => {
|
|
166
|
+
if (!drag.current) return;
|
|
167
|
+
drag.current = null;
|
|
168
|
+
if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
|
|
169
|
+
root.current?.removeAttribute("data-dragging");
|
|
170
|
+
wake();
|
|
171
|
+
};
|
|
172
|
+
const onTrackDown = (event, axis) => {
|
|
173
|
+
const node = viewport.current;
|
|
174
|
+
const thumb = thumbs.current[axis];
|
|
175
|
+
if (!node || !thumb || event.button !== 0 || event.target !== event.currentTarget) return;
|
|
176
|
+
const box = thumb.getBoundingClientRect();
|
|
177
|
+
const before = axis === "y" ? event.clientY < box.top : event.clientX < box.left;
|
|
178
|
+
const page = (axis === "y" ? node.clientHeight : node.clientWidth) * .9 * (before ? -1 : 1);
|
|
179
|
+
node.scrollBy({
|
|
180
|
+
[axis === "y" ? "top" : "left"]: page,
|
|
181
|
+
behavior: prefersReducedMotion() ? "auto" : "smooth"
|
|
182
|
+
});
|
|
183
|
+
};
|
|
184
|
+
const bar = (axis) => /* @__PURE__ */ jsx("div", {
|
|
185
|
+
ref: (node) => {
|
|
186
|
+
tracks.current[axis] = node;
|
|
187
|
+
},
|
|
188
|
+
"data-slot": "scroll-area-track",
|
|
189
|
+
"data-axis": axis,
|
|
190
|
+
"data-hidden": "",
|
|
191
|
+
"aria-hidden": "true",
|
|
192
|
+
onPointerDown: (event) => onTrackDown(event, axis),
|
|
193
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
194
|
+
ref: (node) => {
|
|
195
|
+
thumbs.current[axis] = node;
|
|
196
|
+
},
|
|
197
|
+
"data-slot": "scroll-area-thumb",
|
|
198
|
+
onPointerDown: (event) => onThumbDown(event, axis),
|
|
199
|
+
onPointerMove: onThumbMove,
|
|
200
|
+
onPointerUp: onThumbUp,
|
|
201
|
+
onPointerCancel: onThumbUp
|
|
202
|
+
})
|
|
203
|
+
});
|
|
204
|
+
const fadeClass = orientation === "vertical" ? "scroll-fade-y" : orientation === "horizontal" ? "scroll-fade-x" : "scroll-fade-both";
|
|
205
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
52
206
|
...props,
|
|
53
|
-
ref:
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
207
|
+
ref: root,
|
|
208
|
+
"data-slot": "scroll-area-root",
|
|
209
|
+
"data-orientation": orientation,
|
|
210
|
+
"data-scrollbars": scrollbars,
|
|
211
|
+
className: cn(scrollAreaRootVariants({ framed }), className),
|
|
212
|
+
children: [
|
|
213
|
+
/* @__PURE__ */ jsx("div", {
|
|
214
|
+
ref: viewportRef,
|
|
215
|
+
tabIndex: 0,
|
|
216
|
+
role: "region",
|
|
217
|
+
"aria-label": label,
|
|
218
|
+
"data-slot": "scroll-area",
|
|
219
|
+
"data-fade": fade > 0 ? "" : void 0,
|
|
220
|
+
onScroll: (event) => {
|
|
221
|
+
sync();
|
|
222
|
+
wake();
|
|
223
|
+
onScroll?.(event);
|
|
224
|
+
},
|
|
225
|
+
className: cn(cnAll(scrollAreaVariants({ orientation }), fade > 0 && fadeClass), viewportClassName),
|
|
226
|
+
children
|
|
227
|
+
}),
|
|
228
|
+
vertical ? bar("y") : null,
|
|
229
|
+
horizontal ? bar("x") : null
|
|
230
|
+
]
|
|
60
231
|
});
|
|
61
232
|
});
|
|
62
233
|
//#endregion
|
|
63
|
-
export { ScrollArea, scrollAreaVariants };
|
|
234
|
+
export { ScrollArea, scrollAreaRootVariants, scrollAreaVariants };
|
|
64
235
|
|
|
65
236
|
//# sourceMappingURL=scroll-area.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scroll-area.js","names":[],"sources":["../../src/scroll-area/scroll-area.tsx"],"sourcesContent":["\"use client\";\n\nimport { cva } from \"class-variance-authority\";\nimport {\n forwardRef,\n useEffect,\n useMemo,\n useRef,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from \"react\";\n\nimport { cn } from \"../lib/cn.js\";\nimport { mergeRefs } from \"../lib/merge-refs.js\";\n\n/**\n * ScrollArea. React Aria has no equivalent, so this is a plain scrolling\n * div -- and that is the honest answer rather than a shortcut.\n *\n * Census: fourteen paths match, thirteen are counted, ELEVEN render\n * anything, and across them 17 uses. Every single one passes `className`\n * and nothing else, and 13 of the 17 are a height or flex constraint plus\n * padding. `ScrollBar` is exported by the legacy and imported by nobody.\n * `orientation=\"horizontal\"` has zero call sites.\n *\n * So there is no styled-scrollbar requirement to port. The legacy pays for\n * one anyway: Radix injects a `<style>` tag that hides the native\n * scrollbar, then re-draws it in JavaScript with a ResizeObserver, a\n * portal-free overlay and a `display: table` content wrapper. That is a\n * lot of machinery to reproduce a scrollbar, and it is why the legacy\n * `ScrollArea` cannot be scrolled by keyboard at all.\n *\n * Tailwind 4.3.3 ships `scrollbar-width` and `scrollbar-color` utilities\n * (verified in the installed dist, not assumed), which gets the same look\n * in three classes and no JavaScript.\n *\n * WHAT CANNOT BE STYLED, stated rather than glossed: `scrollbar-color`\n * takes a thumb and a track colour and nothing else -- no width in pixels,\n * no radius, no hover state, no margins. `::-webkit-scrollbar` can do\n * those but is non-standard and Firefox has never supported it. This\n * component uses the standard properties only.\n */\nexport const scrollAreaVariants = cva([\n \"overflow-y-auto overscroll-contain\",\n \"box-border\",\n // Standard scrollbar properties. thumb = --color-border (5.25:1 on the\n // page), track transparent so it does not draw a channel.\n \"scrollbar-thin scrollbar-thumb-border scrollbar-track-transparent\",\n // A scrollable region must be reachable by keyboard, or its content is\n // unreachable without a pointer -- WCAG 2.1.1, and axe's\n // scrollable-region-focusable rule. The legacy has no tabIndex at all,\n // so all 17 of its scroll areas are keyboard traps in the other\n // direction: you can see the content but never scroll to it.\n \"outline-none\",\n \"focus-visible:outline-solid\",\n \"focus-visible:outline-(length:--focus-ring-width)\",\n \"focus-visible:outline-offset-(--focus-ring-offset)\",\n \"focus-visible:outline-(--color-ring)\",\n]);\n\n/**\n * A scrolling region.\n *\n * @example\n * <ScrollArea label=\"Chat messages\" className=\"h-64\">...</ScrollArea>\n */\nexport interface ScrollAreaProps extends ComponentPropsWithoutRef<\"div\"> {\n children?: ReactNode;\n /**\n * Names the scrolling region.\n *\n * **Required**, and it took a failing test to get here. A focusable\n * element with no role fails axe `focus-order-semantics`, so the\n * keyboard fix below cannot ship without a role -- and a role with no\n * accessible name is a violation of its own. Naming it is the only\n * combination that is actually correct.\n *\n * `role=\"region\"` specifically. `group` was the first attempt -- it is\n * lighter, since region is a landmark and seventeen landmarks in one app\n * is noise -- but axe does not accept `group` as an appropriate role for\n * a focusable element, and it is right: a named region is the role the\n * ARIA practices name for a scrollable content area, and being able to\n * jump to it is the point.\n */\n label: string;\n /**\n * Change this when the contents change, and the region scrolls back to the\n * top.\n *\n * This stays a declarative prop even though a `ref` now exists: reaching\n * for it would mean the caller writes `ref.current.scrollTop = 0` in their\n * own effect on every content change, which is worse ergonomics than a\n * prop that says \"reset when this value changes.\" That is a design choice\n * independent of whether a ref is available, not a consequence of one\n * being withheld.\n *\n * Sheet forwards its own `scrollResetKey` straight through: going a level\n * deeper in a panel and landing halfway down the new view is disorienting,\n * and it is exactly the thing every call site forgets.\n */\n scrollResetKey?: string | number;\n}\n\nexport const ScrollArea = forwardRef<HTMLDivElement, ScrollAreaProps>(function ScrollArea(\n { className, children, label, scrollResetKey, ...props },\n ref,\n) {\n const region = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n // Unconditional rather than guarded on scrollResetKey being set: with no\n // key this runs once on mount, where scrollTop is already 0.\n if (region.current) region.current.scrollTop = 0;\n }, [scrollResetKey]);\n\n // Memoized, not called inline on the div below: mergeRefs returns a new\n // callback every call, and an inline call is a new callback every render --\n // React would detach and reattach the DOM ref on every re-render instead of\n // only on mount, which matters here more than most, since ScrollArea's own\n // purpose is wrapping content that re-renders often.\n const rootRef = useMemo(() => mergeRefs(ref, region), [ref, region]);\n\n return (\n <div\n {...props}\n ref={rootRef}\n // tabIndex 0 unconditionally: whether the content overflows is a\n // runtime fact that changes as the content does, and a region that\n // becomes scrollable after a fetch would otherwise never gain focus.\n tabIndex={0}\n role=\"region\"\n aria-label={label}\n data-slot=\"scroll-area\"\n className={cn(scrollAreaVariants(), className)}\n >\n {children}\n </div>\n );\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,MAAa,qBAAqB,IAAI;CACpC;CACA;CAGA;CAMA;CACA;CACA;CACA;CACA;AACF,CAAC;AA6CD,MAAa,aAAa,WAA4C,SAAS,WAC7E,EAAE,WAAW,UAAU,OAAO,gBAAgB,GAAG,SACjD,KACA;CACA,MAAM,SAAS,OAAuB,IAAI;CAE1C,gBAAgB;EAGd,IAAI,OAAO,SAAS,OAAO,QAAQ,YAAY;CACjD,GAAG,CAAC,cAAc,CAAC;CAOnB,MAAM,UAAU,cAAc,UAAU,KAAK,MAAM,GAAG,CAAC,KAAK,MAAM,CAAC;CAEnE,OACE,oBAAC,OAAD;EACE,GAAI;EACJ,KAAK;EAIL,UAAU;EACV,MAAK;EACL,cAAY;EACZ,aAAU;EACV,WAAW,GAAG,mBAAmB,GAAG,SAAS;EAE5C;CACE,CAAA;AAET,CAAC"}
|
|
1
|
+
{"version":3,"file":"scroll-area.js","names":[],"sources":["../../src/scroll-area/scroll-area.tsx"],"sourcesContent":["\"use client\";\n\nimport { cva } from \"class-variance-authority\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n type ComponentPropsWithoutRef,\n type PointerEvent as ReactPointerEvent,\n type ReactNode,\n} from \"react\";\n\nimport { cn, cnAll } from \"../lib/cn.js\";\nimport { mergeRefs } from \"../lib/merge-refs.js\";\nimport { prefersReducedMotion, useIsomorphicLayoutEffect } from \"../lib/motion.js\";\n\n/**\n * ScrollArea: a native scroll container with thin overlay scrollbars and edge\n * fades. React Aria has no equivalent, so the scrolling stays the browser's --\n * keyboard, touch momentum and scroll snap all behave as the platform expects --\n * and only the scrollbar is drawn here.\n *\n * Census: fourteen paths match, thirteen are counted, ELEVEN render anything,\n * and across them 17 uses. Every one passes `className` and nothing else, and 13\n * of the 17 are a height or flex constraint plus padding. The legacy Radix one\n * cannot be scrolled by keyboard at all.\n *\n * The native scrollbar is hidden and replaced by an overlay pill that appears\n * while scrolling or hovering and fades away at rest (or stays, with\n * `scrollbars=\"always\"`). It is written straight to the DOM on each scroll\n * frame, so scrolling never re-renders React. The pill can be dragged, and\n * pressing its track pages toward the pointer.\n *\n * WHERE THINGS LAND. `className`, `style` and the rest go on the ROOT, the box\n * that carries the height and the optional card. `ref` and `viewportClassName`\n * go on the VIEWPORT, the element that really scrolls -- so a caller can call\n * `ref.current.scrollTo(...)` or `scrollBy(...)` for a \"back to top\" or an\n * arrow button, and put padding on the content without moving the scrollbar\n * inside it.\n *\n * The font is declared here: the reset in @seekalfred/styles is OPT-IN, so a\n * consumer may load none, and a scroll area's content (a list of plain\n * paragraphs) would render in the browser's serif.\n */\nexport const scrollAreaRootVariants = cva(\n [\"scroll-area relative flex min-h-0 min-w-0 flex-col overflow-hidden box-border font-sans\"],\n {\n variants: {\n /** The area is a white card: the panel radius and a hairline border. */\n framed: {\n true: \"rounded-panel border-(length:--border-width) border-border bg-surface\",\n false: \"\",\n },\n },\n defaultVariants: { framed: false },\n },\n);\n\nexport const scrollAreaVariants = cva(\n [\n \"scroll-area-viewport min-h-0 min-w-0 flex-1 overscroll-contain box-border\",\n // A scrollable region must be reachable by keyboard, or its content is\n // unreachable without a pointer -- WCAG 2.1.1, and axe's\n // scrollable-region-focusable rule. The legacy has no tabIndex at all.\n \"outline-none\",\n \"focus-visible:outline-solid\",\n \"focus-visible:outline-(length:--focus-ring-width)\",\n \"focus-visible:outline-offset-(--focus-ring-offset)\",\n \"focus-visible:outline-(--color-ring)\",\n ],\n {\n variants: {\n orientation: {\n vertical: \"overflow-x-hidden overflow-y-auto\",\n horizontal: \"overflow-x-auto overflow-y-hidden\",\n both: \"overflow-auto\",\n },\n },\n defaultVariants: { orientation: \"vertical\" },\n },\n);\n\ntype Axis = \"y\" | \"x\";\n\ninterface Drag {\n axis: Axis;\n start: number;\n scroll: number;\n ratio: number;\n sign: number;\n}\n\n/** The shortest a scrollbar thumb gets, so a very long list still leaves something to grab. */\nconst MIN_THUMB = 28;\n\n/**\n * A scrolling region.\n *\n * @example\n * <ScrollArea label=\"Activity\" className=\"h-64\" framed fade={28}>...</ScrollArea>\n */\nexport interface ScrollAreaProps extends ComponentPropsWithoutRef<\"div\"> {\n children?: ReactNode;\n /**\n * Names the scrolling region.\n *\n * **Required**, and it took a failing test to get here. A focusable\n * element with no role fails axe `focus-order-semantics`, so the\n * keyboard fix cannot ship without a role -- and a role with no\n * accessible name is a violation of its own. Naming it is the only\n * combination that is actually correct.\n *\n * `role=\"region\"` specifically. `group` was the first attempt -- it is\n * lighter, since region is a landmark and seventeen landmarks in one app\n * is noise -- but axe does not accept `group` as an appropriate role for\n * a focusable element, and it is right: a named region is the role the\n * ARIA practices name for a scrollable content area, and being able to\n * jump to it is the point.\n */\n label: string;\n /**\n * Which axes scroll.\n *\n * @default \"vertical\"\n */\n orientation?: \"vertical\" | \"horizontal\" | \"both\";\n /**\n * Fade the content out at an edge by exactly as much as there is content hidden\n * past it, up to this many pixels: the fade grows in with the first pixels of\n * scroll and is gone at the ends, so an edge fades only while content\n * overflows past it. `0` turns it off, and the default leaves the area as it\n * was. Written on each scroll frame straight to the element, so scrolling\n * never re-renders.\n *\n * @default 0\n */\n fade?: number;\n /**\n * `auto` shows the scrollbar while scrolling or hovering and fades it away at\n * rest; `always` keeps it visible whenever the content overflows.\n *\n * @default \"auto\"\n */\n scrollbars?: \"auto\" | \"always\";\n /**\n * How long the scrollbar lingers after scrolling stops, in ms.\n *\n * @default 900\n */\n hideDelay?: number;\n /**\n * Draws the area as a white card: the panel radius and a light border. The\n * content is clipped to it, so an edge fade and the scrollbar sit inside.\n *\n * @default false\n */\n framed?: boolean;\n /**\n * Classes for the viewport, the element that scrolls. Padding for the\n * content goes here.\n */\n viewportClassName?: string;\n /**\n * Change this when the contents change, and the region scrolls back to the\n * top.\n *\n * This stays a declarative prop even though a `ref` exists: reaching\n * for it would mean the caller writes `ref.current.scrollTop = 0` in their\n * own effect on every content change, which is worse ergonomics than a\n * prop that says \"reset when this value changes.\"\n *\n * Sheet forwards its own `scrollResetKey` straight through: going a level\n * deeper in a panel and landing halfway down the new view is disorienting,\n * and it is exactly the thing every call site forgets.\n */\n scrollResetKey?: string | number;\n}\n\n/** The `ref` reaches the VIEWPORT, the element that scrolls. `onScroll` runs on its scroll events. */\nexport const ScrollArea = forwardRef<HTMLDivElement, ScrollAreaProps>(function ScrollArea(\n {\n className,\n children,\n label,\n scrollResetKey,\n orientation = \"vertical\",\n fade = 0,\n scrollbars = \"auto\",\n hideDelay = 900,\n framed = false,\n viewportClassName,\n onScroll,\n ...props\n },\n ref,\n) {\n const root = useRef<HTMLDivElement>(null);\n const viewport = useRef<HTMLDivElement>(null);\n const tracks = useRef<Record<Axis, HTMLDivElement | null>>({ x: null, y: null });\n const thumbs = useRef<Record<Axis, HTMLDivElement | null>>({ x: null, y: null });\n const hideTimer = useRef<number | undefined>(undefined);\n const drag = useRef<Drag | null>(null);\n\n const vertical = orientation !== \"horizontal\";\n const horizontal = orientation !== \"vertical\";\n\n useEffect(() => {\n // Unconditional rather than guarded on scrollResetKey being set: with no\n // key this runs once on mount, where scrollTop is already 0.\n if (viewport.current) viewport.current.scrollTop = 0;\n }, [scrollResetKey]);\n\n // Memoized, not called inline: mergeRefs returns a new callback every call, so\n // an inline call would detach and reattach the DOM ref on every re-render.\n const viewportRef = useMemo(() => mergeRefs(ref, viewport), [ref]);\n\n /*\n * Everything visual is written straight to the DOM: the fade at each edge is\n * how much content is hidden past it (up to `fade`), and a thumb is sized and\n * placed from the scroll position. A track with nothing to scroll is hidden.\n */\n const sync = useCallback(() => {\n const node = viewport.current;\n if (!node) return;\n const { scrollTop, scrollHeight, clientHeight, scrollWidth, clientWidth } = node;\n const maxY = Math.max(0, scrollHeight - clientHeight);\n const maxX = Math.max(0, scrollWidth - clientWidth);\n // scrollLeft runs negative in a right-to-left layout; the distance travelled is what counts.\n const left = Math.abs(node.scrollLeft);\n\n if (fade > 0) {\n node.style.setProperty(\"--fade-top\", `${vertical ? Math.min(fade, scrollTop) : 0}px`);\n node.style.setProperty(\n \"--fade-bottom\",\n `${vertical ? Math.min(fade, Math.max(0, maxY - scrollTop)) : 0}px`,\n );\n node.style.setProperty(\"--fade-left\", `${horizontal ? Math.min(fade, left) : 0}px`);\n node.style.setProperty(\n \"--fade-right\",\n `${horizontal ? Math.min(fade, Math.max(0, maxX - left)) : 0}px`,\n );\n }\n\n const place = (axis: Axis, scroll: number, max: number, client: number, total: number) => {\n const track = tracks.current[axis];\n const thumb = thumbs.current[axis];\n if (!track || !thumb) return;\n const overflowing = max > 0.5;\n track.toggleAttribute(\"data-hidden\", !overflowing);\n if (!overflowing) return;\n const length = axis === \"y\" ? track.clientHeight : track.clientWidth;\n const size = Math.max(MIN_THUMB, (length * client) / total);\n const offset = (length - size) * (scroll / max);\n const sign = axis === \"x\" && getComputedStyle(node).direction === \"rtl\" ? -1 : 1;\n thumb.style[axis === \"y\" ? \"height\" : \"width\"] = `${size}px`;\n thumb.style.transform =\n axis === \"y\" ? `translate3d(0, ${offset}px, 0)` : `translate3d(${offset * sign}px, 0, 0)`;\n };\n if (vertical) place(\"y\", scrollTop, maxY, clientHeight, scrollHeight);\n if (horizontal) place(\"x\", left, maxX, clientWidth, scrollWidth);\n root.current?.toggleAttribute(\"data-overflow\", maxY > 0.5 || maxX > 0.5);\n }, [fade, horizontal, vertical]);\n\n useIsomorphicLayoutEffect(() => {\n const node = viewport.current;\n if (!node) return;\n sync();\n if (typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(() => sync());\n observer.observe(node);\n for (const child of Array.from(node.children)) observer.observe(child);\n return () => observer.disconnect();\n // `children` re-observes when the content's own boxes are replaced.\n }, [sync, children]);\n\n useEffect(() => () => window.clearTimeout(hideTimer.current), []);\n\n const wake = () => {\n const el = root.current;\n if (!el) return;\n el.setAttribute(\"data-scrolling\", \"\");\n window.clearTimeout(hideTimer.current);\n hideTimer.current = window.setTimeout(() => el.removeAttribute(\"data-scrolling\"), hideDelay);\n };\n\n /* Dragging a thumb maps pointer travel to scroll distance. */\n const onThumbDown = (event: ReactPointerEvent<HTMLDivElement>, axis: Axis) => {\n const node = viewport.current;\n const track = tracks.current[axis];\n const thumb = thumbs.current[axis];\n if (!node || !track || !thumb || event.button !== 0) return;\n event.preventDefault();\n event.stopPropagation();\n event.currentTarget.setPointerCapture(event.pointerId);\n const length = axis === \"y\" ? track.clientHeight : track.clientWidth;\n const size = axis === \"y\" ? thumb.offsetHeight : thumb.offsetWidth;\n const max =\n axis === \"y\" ? node.scrollHeight - node.clientHeight : node.scrollWidth - node.clientWidth;\n drag.current = {\n axis,\n start: axis === \"y\" ? event.clientY : event.clientX,\n scroll: axis === \"y\" ? node.scrollTop : node.scrollLeft,\n ratio: max / Math.max(1, length - size),\n sign: axis === \"x\" && getComputedStyle(node).direction === \"rtl\" ? -1 : 1,\n };\n root.current?.setAttribute(\"data-dragging\", axis);\n };\n const onThumbMove = (event: ReactPointerEvent<HTMLDivElement>) => {\n const state = drag.current;\n const node = viewport.current;\n if (!state || !node) return;\n const travel = (state.axis === \"y\" ? event.clientY : event.clientX) - state.start;\n const to = state.scroll + travel * state.ratio * state.sign;\n if (state.axis === \"y\") node.scrollTop = to;\n else node.scrollLeft = to;\n };\n const onThumbUp = (event: ReactPointerEvent<HTMLDivElement>) => {\n if (!drag.current) return;\n drag.current = null;\n if (event.currentTarget.hasPointerCapture(event.pointerId)) {\n event.currentTarget.releasePointerCapture(event.pointerId);\n }\n root.current?.removeAttribute(\"data-dragging\");\n wake();\n };\n /* Pressing the track pages toward the pointer. */\n const onTrackDown = (event: ReactPointerEvent<HTMLDivElement>, axis: Axis) => {\n const node = viewport.current;\n const thumb = thumbs.current[axis];\n if (!node || !thumb || event.button !== 0 || event.target !== event.currentTarget) return;\n const box = thumb.getBoundingClientRect();\n const before = axis === \"y\" ? event.clientY < box.top : event.clientX < box.left;\n const page = (axis === \"y\" ? node.clientHeight : node.clientWidth) * 0.9 * (before ? -1 : 1);\n node.scrollBy({\n [axis === \"y\" ? \"top\" : \"left\"]: page,\n behavior: prefersReducedMotion() ? \"auto\" : \"smooth\",\n });\n };\n\n const bar = (axis: Axis) => (\n <div\n ref={(node) => {\n tracks.current[axis] = node;\n }}\n data-slot=\"scroll-area-track\"\n data-axis={axis}\n data-hidden=\"\"\n aria-hidden=\"true\"\n onPointerDown={(event) => onTrackDown(event, axis)}\n >\n <div\n ref={(node) => {\n thumbs.current[axis] = node;\n }}\n data-slot=\"scroll-area-thumb\"\n onPointerDown={(event) => onThumbDown(event, axis)}\n onPointerMove={onThumbMove}\n onPointerUp={onThumbUp}\n onPointerCancel={onThumbUp}\n />\n </div>\n );\n\n const fadeClass =\n orientation === \"vertical\"\n ? \"scroll-fade-y\"\n : orientation === \"horizontal\"\n ? \"scroll-fade-x\"\n : \"scroll-fade-both\";\n\n return (\n <div\n {...props}\n ref={root}\n data-slot=\"scroll-area-root\"\n data-orientation={orientation}\n data-scrollbars={scrollbars}\n className={cn(scrollAreaRootVariants({ framed }), className)}\n >\n <div\n ref={viewportRef}\n // tabIndex 0 unconditionally: whether the content overflows is a\n // runtime fact that changes as the content does, and a region that\n // becomes scrollable after a fetch would otherwise never gain focus.\n tabIndex={0}\n role=\"region\"\n aria-label={label}\n data-slot=\"scroll-area\"\n data-fade={fade > 0 ? \"\" : undefined}\n onScroll={(event) => {\n sync();\n wake();\n onScroll?.(event);\n }}\n className={cn(\n cnAll(scrollAreaVariants({ orientation }), fade > 0 && fadeClass),\n viewportClassName,\n )}\n >\n {children}\n </div>\n {vertical ? bar(\"y\") : null}\n {horizontal ? bar(\"x\") : null}\n </div>\n );\n});\n"],"mappings":"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"}
|