@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":"brush-chart.js","names":[],"sources":["../../src/brush-chart/brush-chart.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\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 { live, retarget, SMOOTH, tween } from \"../lib/spring-tween.js\";\n\n/**\n * BrushChart: a long, dense time series, when people need the whole history\n * and a close look at any stretch of it.\n *\n * A main plot shows the window; an overview strip under it shows everything.\n * Drag the window to pan, drag an edge to resize it, drag empty track to draw\n * a new window, tap to recentre, double tap (or Escape) to show it all. Zoomed\n * out, a seven point average and its low to high band replace the raw line so\n * dense weeks read as texture; zoomed in, the raw line fades in. The value\n * axis springs to the tallest point in view. Hover, drag or the arrow keys\n * scrub the plot: a crosshair and a tooltip with the day, the value and the\n * change against a week earlier. Annotations mark events on both charts.\n *\n * Plain SVG and CSS. The window, every path and the markers are written\n * straight to the DOM as the window moves, so a drag never re-renders the\n * chart. The plot and the window, and each edge, are sliders; a visually\n * hidden table carries every point in the window.\n */\nexport interface BrushChartDatum {\n /** A point in time, as a Date or epoch milliseconds. Points must be in ascending order. */\n date: Date | number;\n value: number;\n}\n\nexport interface BrushChartAnnotation {\n date: Date | number;\n /** Short label printed beside the marker, such as \"v2 launch\". */\n label: string;\n /** Longer note for the tooltip and screen readers. */\n description?: string;\n}\n\nexport interface BrushChartProps {\n data: BrushChartDatum[];\n /** What is measured, such as \"Daily active users\". Names the chart for assistive technology. */\n label: string;\n /** Unit after each value, such as \"users\". */\n unit?: string;\n formatValue?: (value: number) => string;\n /** Formats the value axis. Defaults to a compact number, such as 12K. */\n formatTick?: (value: number) => string;\n /** Formats a date in the tooltip and announcements. */\n formatDate?: (date: Date) => string;\n /** Events drawn as markers on both charts. */\n annotations?: BrushChartAnnotation[];\n /** Controlled window as [start, end] epoch milliseconds. A new value glides the window there. */\n range?: [number, number];\n /** Initial window when uncontrolled. Defaults to the whole series. */\n defaultRange?: [number, number];\n /** Called while the window is dragged, resized, stepped, or reset. */\n onRangeChange?: (range: [number, number]) => void;\n /** Smallest window in milliseconds. @default seven days */\n minSpan?: number;\n /** Main plot height in pixels. @default 240 */\n height?: number;\n /** Overview strip height in pixels. @default 52 */\n overviewHeight?: number;\n /** @default \"No data yet\" */\n emptyLabel?: string;\n /** Extra classes for the root. Merged last. */\n className?: string;\n}\n\ntype Point = { t: number; value: number };\ntype Window = [number, number];\ntype Drag = {\n mode: \"start\" | \"end\" | \"pan\" | \"new\";\n pointerX: number;\n from: Window;\n anchor: number;\n moved: boolean;\n};\n\nconst DAY = 86_400_000;\n/** Room above the top gridline, the gap between a point and its tooltip, and how close to an edge a press grabs it. */\nconst TOP = 28;\nconst GAP = 14;\nconst GRIP = 14;\n/** Width of an edge handle's hit area. */\nconst HANDLE = 28;\nconst COMPACT = new Intl.NumberFormat(\"en-US\", { notation: \"compact\", maximumFractionDigits: 1 });\nconst GROUPED = new Intl.NumberFormat(\"en-US\", { maximumFractionDigits: 1 });\nconst utc = (options: Intl.DateTimeFormatOptions) =>\n new Intl.DateTimeFormat(\"en-US\", { timeZone: \"UTC\", ...options });\nconst FULL_DATE = utc({ weekday: \"short\", month: \"short\", day: \"numeric\", year: \"numeric\" });\nconst DAY_TICK = utc({ month: \"short\", day: \"numeric\" });\nconst MONTH_TICK = utc({ month: \"short\" });\nconst YEAR_TICK = utc({ year: \"numeric\" });\nconst SHORT_DATE = utc({ month: \"short\", day: \"numeric\", year: \"numeric\" });\nconst clamp = (value: number, low: number, high: number) => Math.min(high, Math.max(low, value));\nconst time = (date: Date | number) => (typeof date === \"number\" ? date : date.getTime());\nconst clean = (value: number) => Number(value.toPrecision(12));\n\n/** Clean gridlines from zero: the smallest step of 1, 2, 2.5 or 5 that covers the data in four rows or fewer. */\nfunction niceTop(high: number) {\n const hi = Math.max(high, 1);\n const magnitude = 10 ** Math.floor(Math.log10(hi / 4));\n for (const factor of [1, 2, 2.5, 5, 10]) {\n const step = factor * magnitude;\n const top = Math.ceil(hi / step) * step;\n if (top / step <= 4 + 1e-9) return { top: clean(top), step: clean(step) };\n }\n return { top: hi, step: hi / 4 };\n}\n\n/** Calendar ticks that fit the width: days, weeks, then months, quarters and years, each landing on a real boundary. */\nfunction timeTicks(start: number, end: number, width: number) {\n const room = Math.max(2, Math.floor(width / 76));\n const span = end - start;\n for (const days of [1, 2, 7, 14]) {\n if (span / (days * DAY) > room) continue;\n const ticks: { t: number; label: string }[] = [];\n let t = Math.ceil(start / DAY) * DAY;\n if (days >= 7) while (new Date(t).getUTCDay() !== 1) t += DAY;\n for (; t <= end; t += days * DAY) ticks.push({ t, label: DAY_TICK.format(t) });\n return ticks;\n }\n for (const months of [1, 2, 3, 6, 12]) {\n if (span / (months * 30.44 * DAY) > room) continue;\n const ticks: { t: number; label: string }[] = [];\n const first = new Date(start);\n let y = first.getUTCFullYear();\n let m = first.getUTCMonth() + (first.getUTCDate() > 1 || first.getUTCHours() > 0 ? 1 : 0);\n for (;;) {\n y += Math.floor(m / 12);\n m %= 12;\n const t = Date.UTC(y, m, 1);\n if (t > end) break;\n if (m % months === 0)\n ticks.push({ t, label: m === 0 ? YEAR_TICK.format(t) : MONTH_TICK.format(t) });\n m += 1;\n }\n return ticks;\n }\n const ticks: { t: number; label: string }[] = [];\n for (let y = new Date(start).getUTCFullYear() + 1; Date.UTC(y, 0, 1) <= end; y++) {\n ticks.push({ t: Date.UTC(y, 0, 1), label: String(y) });\n }\n return ticks;\n}\n\n/** First index at or after t. */\nfunction lowerBound(points: { t: number }[], t: number) {\n let low = 0;\n let high = points.length;\n while (low < high) {\n const middle = (low + high) >> 1;\n if (points[middle]!.t < t) low = middle + 1;\n else high = middle;\n }\n return low;\n}\n\n/** A line through the points in view. Past two points per pixel, each pixel column keeps only its low and high so spikes survive. */\nfunction linePath(\n points: Point[],\n from: number,\n to: number,\n x: (t: number) => number,\n y: (value: number) => number,\n width: number,\n) {\n const slice = points.slice(Math.max(0, from), Math.min(points.length, to));\n if (!slice.length) return \"\";\n const parts: string[] = [];\n const add = (point: Point) => parts.push(`${x(point.t).toFixed(1)},${y(point.value).toFixed(1)}`);\n if (slice.length <= width * 2) {\n for (const point of slice) add(point);\n } else {\n let column = Number.NaN;\n let low: Point | null = null;\n let high: Point | null = null;\n const flush = () => {\n if (!low || !high) return;\n for (const point of low.t < high.t ? [low, high] : [high, low]) add(point);\n };\n for (const point of slice) {\n const at = Math.floor(x(point.t));\n if (at !== column) {\n flush();\n column = at;\n low = high = point;\n continue;\n }\n if (point.value < low!.value) low = point;\n if (point.value > high!.value) high = point;\n }\n flush();\n }\n return `M${parts.join(\"L\")}`;\n}\n\n/** A centred seven point average and its low to high band, each averaged once more so the edges ease instead of stepping. */\nfunction smoothed(points: Point[]) {\n const around = <T,>(index: number, read: (at: number) => T) => {\n const out: T[] = [];\n for (let at = Math.max(0, index - 3); at <= Math.min(points.length - 1, index + 3); at++)\n out.push(read(at));\n return out;\n };\n const raw = points.map((_, index) => {\n const values = around(index, (at) => points[at]!.value);\n return {\n value: values.reduce((sum, value) => sum + value, 0) / values.length,\n low: Math.min(...values),\n high: Math.max(...values),\n };\n });\n return points.map((point, index) => {\n const near = around(index, (at) => raw[at]!);\n return {\n t: point.t,\n value: raw[index]!.value,\n low: near.reduce((sum, item) => sum + item.low, 0) / near.length,\n high: near.reduce((sum, item) => sum + item.high, 0) / near.length,\n };\n });\n}\n\nexport const BrushChart = forwardRef<HTMLElement, BrushChartProps>(function BrushChart(\n {\n data,\n label,\n unit = \"\",\n formatValue = (value) => GROUPED.format(value),\n formatTick = (value) => COMPACT.format(value),\n formatDate = (date) => FULL_DATE.format(date),\n annotations,\n range,\n defaultRange,\n onRangeChange,\n minSpan = 7 * DAY,\n height = 240,\n overviewHeight = 52,\n emptyLabel = \"No data yet\",\n className,\n },\n ref,\n) {\n const uid = `brush${useId().replace(/[^a-zA-Z0-9-]/g, \"\")}`;\n const figure = useRef<HTMLElement | null>(null);\n const refs = useMemo(() => mergeRefs(ref, figure), [ref]);\n const plot = useRef<HTMLDivElement>(null);\n const plotSvg = useRef<SVGSVGElement>(null);\n const strip = useRef<HTMLDivElement>(null);\n const tip = useRef<HTMLDivElement>(null);\n const gutter = useRef<HTMLDivElement>(null);\n const axis = useRef<HTMLDivElement>(null);\n\n const points = useMemo<Point[]>(\n () => data.map((item) => ({ t: time(item.date), value: item.value })),\n [data],\n );\n const smooth = useMemo(() => smoothed(points), [points]);\n const events = useMemo(\n () =>\n (annotations ?? [])\n .map((item) => ({ ...item, t: time(item.date) }))\n .sort((a, b) => a.t - b.t),\n [annotations],\n );\n const empty = points.length < 2;\n const first = points[0]?.t ?? 0;\n const lastT = points[points.length - 1]?.t ?? 1;\n const whole: Window = [first, lastT];\n const fit = ([start, end]: Window): Window => {\n const span = clamp(end - start, Math.min(minSpan, lastT - first), lastT - first);\n const s = clamp(start, first, lastT - span);\n return [s, s + span];\n };\n\n // The window. `view` is where it is on screen right now; `shown` is the same, a few times a second, for what React renders.\n const view = useRef<Window>(range ?? defaultRange ?? whole);\n const [shown, setShown] = useState<Window>(view.current);\n const touched = useRef(false);\n const settleTimer = useRef(0);\n const flight = useRef<(() => void) | null>(null);\n const flush = useCallback(() => {\n window.clearTimeout(settleTimer.current);\n settleTimer.current = 0;\n setShown((now) =>\n now[0] === view.current[0] && now[1] === view.current[1] ? now : [...view.current],\n );\n }, []);\n const settleSoon = useCallback(() => {\n if (!settleTimer.current) settleTimer.current = window.setTimeout(flush, 100);\n }, [flush]);\n\n const latest = useRef({ points, smooth, events, first, lastT, height, overviewHeight, empty });\n const activeRef = useRef<{ index: number | null; event: number | null }>({\n index: null,\n event: null,\n });\n const plotW = useRef(0);\n const stripW = useRef(0);\n const topLive = useRef(live(0));\n const aimed = useRef<number | null>(null);\n const paintRef = useRef<() => void>(() => {});\n const [plotWidth, setPlotWidth] = useState(0);\n const [stripWidth, setStripWidth] = useState(0);\n\n /** One writer: the window, every path, the axes, the markers, the crosshair and the tooltip, straight onto the elements. */\n const paint = useCallback(() => {\n const L = latest.current;\n const w = plotW.current;\n const root = plotSvg.current;\n const sw = stripW.current;\n if (!root || L.empty) return;\n const [start, end] = view.current;\n const span = Math.max(1, end - start);\n const P = L.points;\n const x = (t: number) => ((t - start) / span) * w;\n const from = Math.max(0, lowerBound(P, start) - 1);\n const to = Math.min(P.length, lowerBound(P, end) + 1);\n let peak = 0;\n for (let index = from; index < to; index++) peak = Math.max(peak, P[index]!.value);\n const want = niceTop(peak * 1.04).top;\n // The value axis springs to the tallest point in view, so zooming into a quiet stretch fills the plot.\n if (aimed.current === null) {\n aimed.current = want;\n topLive.current.value = want;\n } else if (aimed.current !== want) {\n aimed.current = want;\n retarget(topLive.current, want, SMOOTH, () => paintRef.current());\n }\n const top = topLive.current.value || want;\n const H = L.height;\n const y = (value: number) => TOP + (1 - value / (top || 1)) * (H - TOP);\n // How much of the raw line shows: all of it past about four pixels a point, none below about three.\n const pxPerPoint = w && P.length > 1 ? (w * (L.lastT - L.first)) / (P.length - 1) / span : w;\n const detail = clamp((pxPerPoint - 2.75) / 1.5, 0, 1);\n\n if (w) {\n const line = linePath(P, from, to, x, y, w);\n const area = line\n ? `${line}L${x(P[to - 1]!.t).toFixed(1)},${H}L${x(P[from]!.t).toFixed(1)},${H}Z`\n : \"\";\n const S = L.smooth;\n const trend = linePath(S, from, to, x, y, w * 4);\n const upper = linePath(\n S.map((point) => ({ t: point.t, value: point.high })),\n from,\n to,\n x,\n y,\n w * 4,\n );\n const lower = linePath(\n S.map((point) => ({ t: point.t, value: point.low })),\n from,\n to,\n x,\n y,\n w * 4,\n );\n const band = trend ? `${upper}L${lower.slice(1).split(\"L\").reverse().join(\"L\")}Z` : \"\";\n const set = (part: string, d: string, opacity: number) => {\n const node = root.querySelector<SVGPathElement>(`[data-part=${part}]`);\n node?.setAttribute(\"d\", d);\n if (node) node.style.opacity = String(opacity);\n };\n set(\"line\", line, detail);\n set(\"area\", area, detail);\n set(\"trend\", trend, 1 - detail);\n set(\"band\", band, 1 - detail);\n }\n for (const node of root.querySelectorAll<SVGLineElement>(\"[data-grid]\")) {\n const value = Number(node.dataset.grid);\n const yy = String(Math.round(y(value)) + 0.5);\n node.setAttribute(\"y1\", yy);\n node.setAttribute(\"y2\", yy);\n node.style.visibility = value > top * 1.001 ? \"hidden\" : \"visible\";\n }\n for (const node of gutter.current?.querySelectorAll<HTMLElement>(\"[data-tick]\") ?? []) {\n const value = Number(node.dataset.tick);\n node.style.translate = `0 ${Math.round(y(value))}px`;\n node.style.visibility = value > top * 1.001 ? \"hidden\" : \"visible\";\n }\n for (const node of axis.current?.querySelectorAll<HTMLElement>(\"[data-t]\") ?? []) {\n const px = x(Number(node.dataset.t));\n node.style.left = `${px}px`;\n node.style.translate = `${px < 24 ? 0 : px > w - 24 ? -100 : -50}% 0`;\n }\n\n // Event markers: placed where they fall in the window, labelled left to right and skipped when they would collide with the one before.\n const marks = [...(plot.current?.querySelectorAll<HTMLElement>(\"[data-event]\") ?? [])];\n const inside = marks.filter((node) => {\n const t = L.events[Number(node.dataset.event)]!.t;\n return t >= start && t <= end;\n });\n marks.forEach((node) => {\n const index = Number(node.dataset.event);\n const t = L.events[index]!.t;\n const visible = inside.includes(node);\n node.toggleAttribute(\"data-out\", !visible);\n const px = x(t);\n node.style.left = `${px}px`;\n const rule = root.querySelector<SVGLineElement>(`[data-rule=\"${index}\"]`);\n rule?.toggleAttribute(\"data-out\", !visible);\n rule?.setAttribute(\"x1\", String(Math.round(px) + 0.5));\n rule?.setAttribute(\"x2\", String(Math.round(px) + 0.5));\n node.removeAttribute(\"data-labelled\");\n node.removeAttribute(\"data-flip\");\n });\n let edge = -Infinity;\n inside.forEach((node, at) => {\n const index = Number(node.dataset.event);\n const px = x(L.events[index]!.t);\n const text = L.events[index]!.label.length * 6.2 + 4;\n const next =\n at + 1 < inside.length ? x(L.events[Number(inside[at + 1]!.dataset.event)]!.t) - 10 : w;\n if (px + 14 >= edge && px + 14 + text <= next) {\n node.setAttribute(\"data-labelled\", \"\");\n edge = px + 14 + text + 8;\n return;\n }\n const before = at === 0 ? -Infinity : x(L.events[Number(inside[at - 1]!.dataset.event)]!.t);\n if (px - 14 - text >= Math.max(0, edge) && (at === 0 || px - 14 - text >= before + 12)) {\n node.setAttribute(\"data-labelled\", \"\");\n node.setAttribute(\"data-flip\", \"\");\n edge = px + 12;\n return;\n }\n edge = Math.max(edge, px + 12);\n });\n\n // The crosshair sits on the scrubbed point; the tooltip beside it, flipping before it leaves the plot.\n const { index, event } = activeRef.current;\n const at = index !== null && index >= from && index < to ? index : null;\n const cx = at === null ? 0 : x(P[at]!.t);\n const cy =\n at === null ? 0 : y(L.smooth[at]!.value + (P[at]!.value - L.smooth[at]!.value) * detail);\n const crossX = String(Math.round(cx) + 0.5);\n // A hovered event shows its tooltip with no point under it: then the crosshair and the dot stay hidden.\n const cross = root.querySelector<SVGElement>(\"[data-part=crosshair]\");\n cross?.setAttribute(\"x1\", crossX);\n cross?.setAttribute(\"x2\", crossX);\n if (cross) cross.style.opacity = at === null ? \"0\" : \"\";\n const dot = root.querySelector<SVGElement>(\"[data-part=dot]\");\n dot?.setAttribute(\"cx\", String(cx));\n dot?.setAttribute(\"cy\", String(cy));\n if (dot) dot.style.opacity = at === null ? \"0\" : \"\";\n const bubble = tip.current;\n if (bubble) {\n const ax = event !== null ? x(L.events[event]!.t) : cx;\n const ay = event !== null ? TOP : cy;\n const tw = bubble.offsetWidth;\n const th = bubble.offsetHeight;\n let left = ax + GAP;\n if (left + tw > w) left = ax - GAP - tw;\n let topY = ay - th - GAP;\n if (topY < 0) topY = ay + GAP;\n bubble.style.translate = `${clamp(left, 0, Math.max(0, w - tw))}px ${clamp(topY, 0, Math.max(0, H - th))}px`;\n }\n\n // The overview: the window box, its edges and the shades beside it, and the values the sliders report.\n const ox = (t: number) => ((t - L.first) / (L.lastT - L.first || 1)) * sw;\n const wx0 = ox(start);\n const wx1 = ox(end);\n const box = strip.current;\n if (box) {\n const place = (selector: string, css: Record<string, string>) => {\n const node = box.querySelector<HTMLElement>(selector);\n if (node) Object.assign(node.style, css);\n };\n place(\"[data-part=window-box]\", { left: `${wx0}px`, width: `${Math.max(0, wx1 - wx0)}px` });\n // The handles sit outside the window, so they never overlap each other or the window, however narrow it gets. The start handle turns inward at the left edge, where there is no room outside.\n const inward = wx0 < HANDLE;\n place(\"[data-handle=start]\", { left: `${inward ? wx0 : wx0 - HANDLE}px` });\n box.querySelector(\"[data-handle=start]\")?.toggleAttribute(\"data-inward\", inward);\n place(\"[data-handle=end]\", { left: `${wx1}px` });\n place(\"[data-edge=start]\", { left: \"0px\", width: `${Math.max(0, wx0)}px` });\n place(\"[data-edge=end]\", { left: `${wx1}px`, right: \"0px\" });\n const clip = box.querySelector(\"[data-part=window-clip]\");\n clip?.setAttribute(\"x\", String(wx0));\n clip?.setAttribute(\"width\", String(Math.max(0, wx1 - wx0)));\n const text = `${SHORT_DATE.format(start)} to ${SHORT_DATE.format(end)}`;\n const slider = (\n selector: string,\n min: number,\n max: number,\n now: number,\n valuetext: string,\n ) => {\n const node = box.querySelector<HTMLElement>(selector);\n if (!node) return;\n node.setAttribute(\"aria-valuemin\", String(Math.round(min)));\n node.setAttribute(\"aria-valuemax\", String(Math.round(max)));\n node.setAttribute(\"aria-valuenow\", String(Math.round(now)));\n node.setAttribute(\"aria-valuetext\", valuetext);\n };\n slider(\"[data-part=window]\", L.first, L.lastT, start, text);\n slider(\"[data-handle=start]\", L.first, end, start, SHORT_DATE.format(start));\n slider(\"[data-handle=end]\", start, L.lastT, end, SHORT_DATE.format(end));\n }\n }, []);\n useIsomorphicLayoutEffect(() => {\n latest.current = { points, smooth, events, first, lastT, height, overviewHeight, empty };\n paintRef.current = paint;\n paint();\n });\n\n const setView = (next: Window) => {\n view.current = next;\n paint();\n settleSoon();\n };\n const glideTo = (next: Window) => {\n flight.current?.();\n const from = view.current;\n flight.current = tween(\n SMOOTH,\n (p) => setView([from[0] + (next[0] - from[0]) * p, from[1] + (next[1] - from[1]) * p]),\n flush,\n );\n };\n const commit = (next: Window, smoothly: boolean) => {\n const target = fit(next);\n touched.current = true;\n if (smoothly) glideTo(target);\n else {\n flight.current?.();\n setView(target);\n }\n onRangeChange?.(target);\n };\n\n // A new controlled window glides there; data that no longer covers the window pulls it back inside.\n const rangeKey = range ? `${range[0]}:${range[1]}` : \"\";\n useEffect(() => {\n if (!range || empty) return;\n const target = fit(range);\n const now = view.current;\n if (Math.abs(target[0] - now[0]) + Math.abs(target[1] - now[1]) > 1000) glideTo(target);\n // The key stands for `range`.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [rangeKey, empty]);\n useEffect(() => {\n if (empty) return;\n const target = touched.current || range || defaultRange ? fit(view.current) : whole;\n if (target[0] !== view.current[0] || target[1] !== view.current[1]) {\n view.current = target;\n paint();\n flush();\n }\n // Only a change in what the data covers moves the window.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [first, lastT, empty]);\n useEffect(\n () => () => {\n flight.current?.();\n topLive.current.stop();\n window.clearTimeout(settleTimer.current);\n },\n [],\n );\n\n // Both charts draw in their own pixels: measure the widths and follow resizes.\n useIsomorphicLayoutEffect(() => {\n const nodes = [\n [plot.current, plotW, setPlotWidth],\n [strip.current, stripW, setStripWidth],\n ] as const;\n const stops: (() => void)[] = [];\n for (const [node, store, setter] of nodes) {\n if (!node) continue;\n const read = () => {\n store.current = node.clientWidth;\n setter(node.clientWidth);\n paintRef.current();\n };\n read();\n if (typeof ResizeObserver === \"undefined\") continue;\n const observer = new ResizeObserver(read);\n observer.observe(node);\n stops.push(() => observer.disconnect());\n }\n return () => stops.forEach((stop) => stop());\n }, []);\n\n // The line draws in from the left the first time the chart is seen.\n const [drawn, setDrawn] = useState(false);\n useEffect(() => {\n if (empty || drawn) return;\n const node = figure.current;\n if (!node || prefersReducedMotion() || typeof IntersectionObserver === \"undefined\") {\n setDrawn(true);\n return;\n }\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (!entry?.isIntersecting) return;\n observer.disconnect();\n setDrawn(true);\n },\n { threshold: 0.3 },\n );\n observer.observe(node);\n return () => observer.disconnect();\n }, [drawn, empty]);\n\n // The crosshair rides the nearest point in view; a hovered event shows its note instead.\n const [active, setActive] = useState<number | null>(null);\n const [hoverEvent, setHoverEvent] = useState<number | null>(null);\n const [start, end] = shown;\n const from = Math.max(0, lowerBound(points, start) - 1);\n const to = Math.min(points.length, lowerBound(points, end) + 1);\n const index = active !== null && active >= from && active < to ? active : null;\n const eventAt =\n index === null\n ? null\n : (events.find((item) => Math.abs(item.t - points[index]!.t) < DAY / 2) ?? null);\n const shownEvent = hoverEvent !== null ? (events[hoverEvent] ?? null) : null;\n const tipOn = index !== null || shownEvent !== null;\n useIsomorphicLayoutEffect(() => {\n activeRef.current = { index, event: shownEvent ? events.indexOf(shownEvent) : null };\n paint();\n });\n\n const nearest = (clientX: number) => {\n const rect = plot.current?.getBoundingClientRect();\n if (!rect?.width || empty) return null;\n const [s, e] = view.current;\n const t = s + ((clientX - rect.left) / rect.width) * (e - s);\n const at = clamp(lowerBound(points, t), 1, points.length - 1);\n const lo = Math.max(0, lowerBound(points, s) - 1);\n const hi = Math.min(points.length, lowerBound(points, e) + 1);\n return clamp(t - points[at - 1]!.t < points[at]!.t - t ? at - 1 : at, lo, hi - 1);\n };\n const windowBounds = () => {\n const [s, e] = view.current;\n return [\n Math.max(0, lowerBound(points, s) - 1),\n Math.min(points.length, lowerBound(points, e) + 1),\n ] as const;\n };\n const onPlotKey = (event: KeyboardEvent<HTMLDivElement>) => {\n if (empty) return;\n if (event.key === \"Escape\" && index !== null) {\n event.preventDefault();\n setActive(null);\n return;\n }\n const [lo, hi] = windowBounds();\n const current = index ?? hi - 1;\n const page = Math.max(1, Math.round((hi - lo) / 8));\n const next = (\n {\n ArrowLeft: current - 1,\n ArrowRight: index === null ? hi - 1 : current + 1,\n PageDown: current - page,\n PageUp: current + page,\n Home: lo,\n End: hi - 1,\n } as Record<string, number>\n )[event.key];\n if (next === undefined) return;\n event.preventDefault();\n setActive(clamp(next, lo, hi - 1));\n };\n\n // Overview gestures: grab an edge to resize, the window to pan, or empty track to draw a new window. A tap recentres; a double tap resets.\n const drag = useRef<Drag | null>(null);\n const toTime = (clientX: number) => {\n const rect = strip.current?.getBoundingClientRect();\n return rect?.width\n ? first + clamp((clientX - rect.left) / rect.width, 0, 1) * (lastT - first)\n : first;\n };\n const onStripDown = (event: PointerEvent<HTMLDivElement>) => {\n if (empty || event.button > 0) return;\n const rect = strip.current!.getBoundingClientRect();\n const px = event.clientX - rect.left;\n const [s, e] = view.current;\n const wx0 = ((s - first) / (lastT - first)) * rect.width;\n const wx1 = ((e - first) / (lastT - first)) * rect.width;\n const mode: Drag[\"mode\"] =\n Math.abs(px - wx0) <= GRIP && px <= (wx0 + wx1) / 2\n ? \"start\"\n : Math.abs(px - wx1) <= GRIP\n ? \"end\"\n : px > wx0 && px < wx1\n ? \"pan\"\n : \"new\";\n drag.current = {\n mode,\n pointerX: event.clientX,\n from: view.current,\n anchor: toTime(event.clientX),\n moved: false,\n };\n try {\n event.currentTarget.setPointerCapture?.(event.pointerId);\n } catch {\n // A synthetic pointer has nothing to capture.\n }\n flight.current?.();\n };\n const onStripMove = (event: PointerEvent<HTMLDivElement>) => {\n const current = drag.current;\n if (!current) return;\n if (!current.moved && Math.abs(event.clientX - current.pointerX) < 3) return;\n current.moved = true;\n const t = toTime(event.clientX);\n const shift = t - current.anchor;\n const [s, e] = current.from;\n const least = Math.min(minSpan, lastT - first);\n const next: Window =\n current.mode === \"pan\"\n ? [s + shift, e + shift]\n : current.mode === \"start\"\n ? [clamp(t, first, e - least), e]\n : current.mode === \"end\"\n ? [s, clamp(t, s + least, lastT)]\n : [Math.min(current.anchor, t), Math.max(current.anchor, t)];\n if (current.mode === \"new\" && next[1] - next[0] < least) {\n if (t >= current.anchor) next[1] = next[0] + least;\n else next[0] = next[1] - least;\n }\n commit(next, false);\n };\n const onStripUp = () => {\n const current = drag.current;\n drag.current = null;\n if (current?.moved) flush();\n if (!current || current.moved || current.mode !== \"new\") return;\n const half = (view.current[1] - view.current[0]) / 2;\n commit([current.anchor - half, current.anchor + half], true);\n };\n const reset = () => commit(whole, true);\n\n const stepSize = Math.max(DAY, (lastT - first) / Math.max(1, points.length - 1));\n const onHandleKey = (event: KeyboardEvent<HTMLDivElement>, edge: \"start\" | \"end\" | \"window\") => {\n const [s, e] = view.current;\n const win = e - s;\n const big = event.shiftKey || event.key.startsWith(\"Page\");\n const delta = (\n {\n ArrowLeft: -1,\n ArrowDown: -1,\n PageDown: -1,\n ArrowRight: 1,\n ArrowUp: 1,\n PageUp: 1,\n } as Record<string, number>\n )[event.key];\n let next: Window | null = null;\n if (event.key === \"Escape\" || event.key === \"0\") next = whole;\n else if (edge === \"window\" && (event.key === \"+\" || event.key === \"=\"))\n next = [s + win / 4, e - win / 4];\n else if (edge === \"window\" && (event.key === \"-\" || event.key === \"_\"))\n next = [s - win / 2, e + win / 2];\n else if (event.key === \"Home\")\n next =\n edge === \"end\"\n ? [s, s + Math.min(minSpan, lastT - first)]\n : [first, edge === \"window\" ? first + win : e];\n else if (event.key === \"End\")\n next =\n edge === \"start\"\n ? [e - Math.min(minSpan, lastT - first), e]\n : [edge === \"window\" ? lastT - win : s, lastT];\n else if (delta) {\n const move =\n delta * (edge === \"window\" ? win * (big ? 0.5 : 0.1) : stepSize * (big ? 10 : 1));\n next =\n edge === \"window\"\n ? [s + move, e + move]\n : edge === \"start\"\n ? [Math.min(s + move, e - minSpan), e]\n : [s, Math.max(e + move, s + minSpan)];\n }\n if (!next) return;\n event.preventDefault();\n commit(next, false);\n flush();\n };\n\n // What React renders follows the settled window: gridlines and ticks, the event list, the overview and the table.\n const peak = useMemo(() => {\n let high = 0;\n for (let at = from; at < to; at++) high = Math.max(high, points[at]!.value);\n return high;\n }, [points, from, to]);\n const scale = niceTop(peak * 1.04);\n // The raw line is fully drawn past about four pixels a point; below that the tooltip speaks of the average.\n const detailShown = clamp(\n ((plotWidth && points.length > 1\n ? (plotWidth * (lastT - first)) / (points.length - 1) / Math.max(1, end - start)\n : plotWidth) -\n 2.75) /\n 1.5,\n 0,\n 1,\n );\n const ticks =\n scale.top > 0\n ? Array.from({ length: Math.round(scale.top / scale.step) + 1 }, (_, at) =>\n clean(at * scale.step),\n )\n : [];\n const xTicks = plotWidth && !empty ? timeTicks(start, end, plotWidth) : [];\n const overview = useMemo(() => {\n if (!stripWidth || empty)\n return { line: \"\", area: \"\", marks: [] as { t: number; x: number; y: number }[] };\n const ox = (t: number) => ((t - first) / (lastT - first || 1)) * stripWidth;\n const max = niceTop(smooth.reduce((m, point) => Math.max(m, point.value), 0)).top || 1;\n const oy = (value: number) => 4 + (1 - value / max) * (overviewHeight - 4);\n const path = linePath(smooth, 0, smooth.length, ox, oy, stripWidth * 4);\n const marks = events.map((item) => {\n const at = clamp(lowerBound(smooth, item.t), 0, smooth.length - 1);\n return { t: item.t, x: ox(item.t), y: oy(smooth[at]!.value) };\n });\n return {\n line: path,\n area: `${path}L${stripWidth},${overviewHeight}L0,${overviewHeight}Z`,\n marks,\n };\n }, [smooth, events, stripWidth, overviewHeight, empty, first, lastT]);\n\n const format = (value: number) => `${formatValue(value)}${unit ? ` ${unit}` : \"\"}`;\n const reading = index === null ? null : points[index]!;\n const previous = index !== null && index >= 7 ? points[index - 7]! : null;\n const change =\n reading && previous && previous.value\n ? (reading.value - previous.value) / previous.value\n : null;\n const windowText = `${SHORT_DATE.format(start)} to ${SHORT_DATE.format(end)}`;\n const announce = reading\n ? `${formatDate(new Date(reading.t))}, ${format(reading.value)}${eventAt ? `. ${eventAt.label}` : \"\"}`\n : \"\";\n const summary = empty\n ? `${label}. ${emptyLabel}.`\n : `${label}, ${SHORT_DATE.format(first)} to ${SHORT_DATE.format(lastT)}. Showing ${windowText}.`;\n const rows = empty ? [] : points.slice(lowerBound(points, start), lowerBound(points, end + 1));\n\n return (\n <figure\n ref={refs}\n data-slot=\"brush-chart\"\n aria-label={label}\n className={cn(\"brush-chart\", className)}\n style={{ \"--series\": \"var(--color-chart-1)\" } as CSSProperties}\n >\n <div\n data-slot=\"brush-chart-chart\"\n data-scrubbing={tipOn || undefined}\n className=\"brush-chart-frame\"\n >\n <div\n ref={plot}\n data-slot=\"brush-chart-plot\"\n role=\"slider\"\n tabIndex={empty ? -1 : 0}\n aria-label={`${label}, ${windowText}. Use left and right arrows to read values.`}\n aria-orientation=\"horizontal\"\n aria-valuemin={1}\n aria-valuemax={Math.max(1, points.length)}\n aria-valuenow={(index ?? Math.max(0, to - 1)) + 1}\n aria-valuetext={reading ? announce : summary}\n onPointerMove={(event) => {\n if (event.pointerType === \"mouse\" || event.buttons) setActive(nearest(event.clientX));\n }}\n onPointerDown={(event) => {\n if (event.pointerType === \"mouse\") return;\n event.currentTarget.setPointerCapture?.(event.pointerId);\n setActive(nearest(event.clientX));\n }}\n onPointerUp={(event) => {\n if (event.pointerType !== \"mouse\") setActive(null);\n }}\n onPointerCancel={() => setActive(null)}\n onPointerLeave={(event) => {\n if (event.pointerType === \"mouse\") setActive(null);\n }}\n onKeyDown={onPlotKey}\n onBlur={() => setActive(null)}\n onDoubleClick={reset}\n onFocus={(event) => {\n if (event.currentTarget.matches(\":focus-visible\") && !empty) {\n setActive((current) => current ?? windowBounds()[1] - 1);\n }\n }}\n className=\"line-chart-plot\"\n style={{ height }}\n >\n <svg\n ref={plotSvg}\n width=\"100%\"\n height={height}\n aria-hidden=\"true\"\n focusable=\"false\"\n className=\"block overflow-visible\"\n >\n <defs>\n <clipPath id={`${uid}-draw`} clipPathUnits=\"userSpaceOnUse\">\n <rect\n className=\"line-chart-reveal\"\n x={-8}\n y={-16}\n height={height + 32}\n style={{ width: drawn ? plotWidth + 16 : 0 }}\n />\n </clipPath>\n </defs>\n {ticks.slice(1).map((value) => (\n <line key={value} data-grid={value} className=\"line-chart-grid\" x1={0} x2=\"100%\" />\n ))}\n <line\n className=\"line-chart-baseline\"\n x1={0}\n x2=\"100%\"\n y1={height - 0.5}\n y2={height - 0.5}\n />\n {events.map((item, at) => (\n <line\n key={item.t}\n data-rule={at}\n data-active={shownEvent === item || eventAt === item || undefined}\n className=\"brush-chart-rule\"\n y1={TOP - 10}\n y2={height}\n />\n ))}\n <g clipPath={`url(#${uid}-draw)`}>\n <path data-part=\"band\" className=\"brush-chart-band\" />\n <path data-part=\"area\" className=\"line-chart-area\" />\n <path data-part=\"trend\" className=\"brush-chart-trend\" />\n <path data-part=\"line\" className=\"line-chart-line\" />\n </g>\n <line\n data-part=\"crosshair\"\n className=\"line-chart-crosshair\"\n y1={TOP - 10}\n y2={height}\n />\n <circle data-part=\"dot\" r={4} className=\"line-chart-dot\" />\n </svg>\n {events.map((item, at) => (\n <span\n key={item.t}\n data-event={at}\n data-active={shownEvent === item || eventAt === item || undefined}\n aria-hidden=\"true\"\n className=\"brush-chart-event\"\n onPointerEnter={() => setHoverEvent(at)}\n onPointerLeave={() => setHoverEvent(null)}\n onPointerDown={(event) => event.stopPropagation()}\n >\n <span className=\"brush-chart-event-dot\" />\n <span className=\"brush-chart-event-label\">{item.label}</span>\n </span>\n ))}\n <div\n ref={tip}\n aria-hidden=\"true\"\n data-slot=\"brush-chart-tooltip\"\n className=\"line-chart-tooltip\"\n >\n {shownEvent ? (\n <>\n <p className=\"m-0 mb-0.5 whitespace-nowrap text-xs tabular-nums text-text-secondary\">\n {formatDate(new Date(shownEvent.t))}\n </p>\n <p className=\"m-0 text-base font-medium tabular-nums text-foreground\">\n {shownEvent.label}\n </p>\n {shownEvent.description ? (\n <p className=\"m-0 text-xs text-text-secondary\">{shownEvent.description}</p>\n ) : null}\n </>\n ) : reading ? (\n <>\n <p className=\"m-0 mb-0.5 whitespace-nowrap text-xs tabular-nums text-text-secondary\">\n {formatDate(new Date(reading.t))}\n </p>\n <p className=\"m-0 text-base font-medium tabular-nums text-foreground\">\n {format(reading.value)}\n </p>\n {index !== null && detailShown < 1 && smooth[index] ? (\n <p className=\"m-0 text-xs tabular-nums text-text-secondary\">\n {`${formatValue(Math.round(smooth[index].value))} seven day average`}\n </p>\n ) : null}\n {change !== null ? (\n <p className=\"m-0 text-xs tabular-nums text-text-secondary\">\n {`${change >= 0 ? \"+\" : \"−\"}${Math.abs(change * 100).toFixed(1)}% vs a week earlier`}\n </p>\n ) : null}\n {eventAt ? (\n <p className=\"m-0 mt-1 flex items-center gap-1.5 text-xs text-foreground\">\n <span aria-hidden=\"true\" className=\"brush-chart-tip-dot\" />\n {eventAt.label}\n </p>\n ) : null}\n </>\n ) : null}\n </div>\n {empty ? (\n <p className=\"absolute inset-0 m-0 grid place-items-center text-sm text-muted-foreground pointer-events-none motion-safe:animate-fade-in\">\n {emptyLabel}\n </p>\n ) : null}\n </div>\n <div ref={gutter} aria-hidden=\"true\" className=\"relative min-w-0 [grid-area:1/2]\">\n {ticks.map((value) => (\n <span\n key={value}\n data-tick={value}\n className=\"line-chart-tick motion-safe:animate-fade-in\"\n >\n <span className=\"block -translate-y-1/2 text-xs leading-none tabular-nums text-muted-foreground\">\n {formatTick(value)}\n </span>\n </span>\n ))}\n </div>\n <div ref={axis} aria-hidden=\"true\" className=\"relative min-w-0 [grid-area:2/1]\">\n {xTicks.map((tick) => (\n <span\n key={tick.t}\n data-t={tick.t}\n className=\"absolute top-2 whitespace-nowrap text-xs leading-none tabular-nums text-muted-foreground\"\n >\n {tick.label}\n </span>\n ))}\n </div>\n <div\n ref={strip}\n data-slot=\"brush-chart-overview\"\n className=\"brush-chart-strip\"\n style={{ height: overviewHeight }}\n onPointerDown={onStripDown}\n onPointerMove={onStripMove}\n onPointerUp={onStripUp}\n onPointerCancel={() => {\n drag.current = null;\n }}\n onDoubleClick={reset}\n >\n <svg\n width=\"100%\"\n height={overviewHeight}\n aria-hidden=\"true\"\n focusable=\"false\"\n className=\"brush-chart-overview-svg\"\n >\n <defs>\n <clipPath id={`${uid}-window`}>\n <rect data-part=\"window-clip\" y={-2} height={overviewHeight + 4} />\n </clipPath>\n </defs>\n <path d={overview.area} className=\"brush-chart-overview-area\" />\n <path d={overview.line} className=\"brush-chart-overview-line\" />\n <g clipPath={`url(#${uid}-window)`}>\n <path d={overview.area} className=\"brush-chart-overview-area-in\" />\n <path d={overview.line} className=\"brush-chart-overview-line-in\" />\n </g>\n {overview.marks.map((mark) => (\n <circle\n key={mark.t}\n cx={mark.x}\n cy={mark.y}\n r={2.5}\n className=\"brush-chart-overview-event\"\n />\n ))}\n </svg>\n {empty ? null : (\n <>\n <div data-edge=\"start\" className=\"brush-chart-shade\" />\n <div data-edge=\"end\" className=\"brush-chart-shade\" />\n <div\n data-part=\"window\"\n role=\"slider\"\n tabIndex={0}\n aria-label={`${label} window`}\n aria-roledescription=\"range window\"\n onKeyDown={(event) => onHandleKey(event, \"window\")}\n className=\"brush-chart-window-key\"\n />\n <div data-part=\"window-box\" aria-hidden=\"true\" className=\"brush-chart-window\" />\n <div\n data-handle=\"start\"\n role=\"slider\"\n tabIndex={0}\n aria-label=\"Window start\"\n onKeyDown={(event) => onHandleKey(event, \"start\")}\n className=\"brush-chart-handle\"\n >\n <span className=\"brush-chart-grip\" />\n </div>\n <div\n data-handle=\"end\"\n role=\"slider\"\n tabIndex={0}\n aria-label=\"Window end\"\n onKeyDown={(event) => onHandleKey(event, \"end\")}\n className=\"brush-chart-handle\"\n >\n <span className=\"brush-chart-grip\" />\n </div>\n </>\n )}\n </div>\n </div>\n <p className=\"sr-only\" aria-live=\"polite\" aria-atomic=\"true\">\n {announce}\n </p>\n <p className=\"sr-only\">{summary}</p>\n {empty ? null : (\n <div className=\"sr-only\">\n <table>\n <caption>{`${label}, ${windowText}`}</caption>\n <thead>\n <tr>\n <th scope=\"col\">Date</th>\n <th scope=\"col\">{label}</th>\n <th scope=\"col\">Event</th>\n </tr>\n </thead>\n <tbody>\n {rows.map((point) => {\n const event = events.find((item) => Math.abs(item.t - point.t) < DAY / 2);\n return (\n <tr key={point.t}>\n <th scope=\"row\">{SHORT_DATE.format(point.t)}</th>\n <td>{format(point.value)}</td>\n <td>\n {event\n ? `${event.label}${event.description ? `. ${event.description}` : \"\"}`\n : \"\"}\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n )}\n </figure>\n );\n});\n"],"mappings":"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"}
|
package/dist/button/button.d.ts
CHANGED
|
@@ -1,28 +1,10 @@
|
|
|
1
1
|
import { VariantProps } from "class-variance-authority";
|
|
2
2
|
import { ReactNode } from "react";
|
|
3
|
-
import { ButtonProps } from "react-aria-components";
|
|
3
|
+
import { ButtonProps, LinkProps } from "react-aria-components";
|
|
4
4
|
//#region src/button/button.d.ts
|
|
5
|
-
/**
|
|
6
|
-
* Variant classes, exported so a consumer can reuse the exact classes we ship
|
|
7
|
-
* rather than guessing at them. This is also the supported answer for the
|
|
8
|
-
* link-shaped cases React Aria's Button cannot cover: it never renders an
|
|
9
|
-
* anchor, so `<a className={buttonVariants({ variant: "outline" })}>` is how a
|
|
10
|
-
* real navigation target gets button styling until the Link primitive lands.
|
|
11
|
-
*
|
|
12
|
-
* Ported from the legacy shadcn Button. The variant and size vocabulary is
|
|
13
|
-
* deliberately identical so existing call sites migrate by rename, with six
|
|
14
|
-
* corrections that the Alfred contracts require -- each marked below.
|
|
15
|
-
*
|
|
16
|
-
* Every string here is a STATIC literal. Tailwind scans source text, so a class
|
|
17
|
-
* assembled at runtime is invisible to it and would simply never be emitted.
|
|
18
|
-
*
|
|
19
|
-
* State comes from React Aria data attributes rather than pseudo-classes:
|
|
20
|
-
* data-[focus-visible] is keyboard focus only, and data-[pressed] covers mouse,
|
|
21
|
-
* touch and keyboard uniformly. The original had no pressed state at all.
|
|
22
|
-
*/
|
|
23
5
|
export declare const buttonVariants: (props?: ({
|
|
24
|
-
variant?: "
|
|
25
|
-
size?: "
|
|
6
|
+
variant?: "link" | "outline" | "primary" | "ai" | "secondary" | "outlineNeutral" | "ghost" | "destructive" | null | undefined;
|
|
7
|
+
size?: "icon" | "sm" | "md" | "lg" | null | undefined;
|
|
26
8
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
27
9
|
/**
|
|
28
10
|
* Props.
|
|
@@ -30,8 +12,8 @@ export declare const buttonVariants: (props?: ({
|
|
|
30
12
|
* CORRECTION 6 -- the legacy Button was a plain `<button>`, so it took
|
|
31
13
|
* `onClick`, `disabled` and Radix's `asChild`. React Aria's Button has none of
|
|
32
14
|
* those: `ButtonProps` explicitly omits `onClick` and `href`. The replacements
|
|
33
|
-
* are `onPress`, `isDisabled`, and `
|
|
34
|
-
*
|
|
15
|
+
* are `onPress`, `isDisabled`, and `href` -- which renders React Aria's Link in
|
|
16
|
+
* place of its Button. See the migration table in the package README.
|
|
35
17
|
*
|
|
36
18
|
* Deliberately NOT intersected with ComponentPropsWithoutRef<"button">: that
|
|
37
19
|
* would advertise disabled, tabIndex and role, which React Aria does not
|
|
@@ -59,10 +41,40 @@ interface ButtonProps$1 extends Omit<ButtonProps, "className" | "style">, Varian
|
|
|
59
41
|
startIcon?: ReactNode;
|
|
60
42
|
/** Icon rendered after the label. Same rules as {@link ButtonProps.startIcon}. */
|
|
61
43
|
endIcon?: ReactNode;
|
|
44
|
+
/**
|
|
45
|
+
* Makes the button a link. It renders React Aria's `Link` -- a real `<a>`,
|
|
46
|
+
* announced as a link -- with exactly the classes a button of the same
|
|
47
|
+
* `variant` and `size` gets, and the same hover, press and focus-ring states.
|
|
48
|
+
*
|
|
49
|
+
* Use it whenever activating the control navigates. A button that navigates
|
|
50
|
+
* cannot be opened in a new tab, is announced as the wrong role, and is
|
|
51
|
+
* skipped by a screen reader's list of links.
|
|
52
|
+
*
|
|
53
|
+
* Client-side routing needs React Aria's `RouterProvider` mounted once above
|
|
54
|
+
* it; without one, an `href` is an ordinary page load, which is also what an
|
|
55
|
+
* external or download link wants.
|
|
56
|
+
*
|
|
57
|
+
* Button-only props have nothing to act on here: `type`, `form*` and
|
|
58
|
+
* `isPending` are ignored, and the `ref` receives the `<a>`.
|
|
59
|
+
*/
|
|
60
|
+
href?: LinkProps["href"];
|
|
61
|
+
/** With `href` only: where to open it, e.g. `"_blank"`. */
|
|
62
|
+
target?: LinkProps["target"];
|
|
63
|
+
/** With `href` only. Give `"noreferrer"` alongside `target="_blank"` to an external site. */
|
|
64
|
+
rel?: LinkProps["rel"];
|
|
65
|
+
/** With `href` only: download the target instead of opening it, optionally under this file name. */
|
|
66
|
+
download?: LinkProps["download"];
|
|
62
67
|
}
|
|
63
68
|
/**
|
|
64
69
|
* A button.
|
|
65
70
|
*
|
|
71
|
+
* A label that changes (a different text, or a different icon) crossfades, and
|
|
72
|
+
* the button's width springs to fit it. While that runs, the OUTGOING label is
|
|
73
|
+
* still in the DOM for about 200ms, `aria-hidden` and out of flow, so read a
|
|
74
|
+
* button's text after the change settles, and do not put `id`s, inputs or
|
|
75
|
+
* anything stateful inside a label that changes. Text that changes constantly,
|
|
76
|
+
* such as a live counter, crossfades every time it does.
|
|
77
|
+
*
|
|
66
78
|
* `size="icon"` renders a square button with no visible text, so it **must**
|
|
67
79
|
* carry an `aria-label` -- otherwise it has no accessible name and fails axe's
|
|
68
80
|
* `button-name` rule. The IconOnly story is the guard on that.
|
|
@@ -72,6 +84,7 @@ interface ButtonProps$1 extends Omit<ButtonProps, "className" | "style">, Varian
|
|
|
72
84
|
* <Button startIcon={<SaveIcon aria-hidden />}>Save changes</Button>
|
|
73
85
|
* <Button endIcon={<ChevronIcon aria-hidden />}>Continue</Button>
|
|
74
86
|
* <Button variant="outline" size="icon" aria-label="Close"><XIcon /></Button>
|
|
87
|
+
* <Button href="/reports" variant="outlineNeutral">View reports</Button>
|
|
75
88
|
*/
|
|
76
89
|
declare const Button$1: import("react").ForwardRefExoticComponent<ButtonProps$1 & import("react").RefAttributes<HTMLButtonElement>>;
|
|
77
90
|
//#endregion
|
package/dist/button/button.js
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { mergeRefs } from "../lib/merge-refs.js";
|
|
4
|
+
import { anchorsLayer, pressScaleFor, useAriaBusy, useExitBackstop, useLeavingItems, useMorphWidth } from "../lib/motion.js";
|
|
3
5
|
import { cva } from "class-variance-authority";
|
|
4
|
-
import { forwardRef } from "react";
|
|
5
|
-
import { Button } from "react-aria-components";
|
|
6
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { forwardRef, isValidElement, useCallback, useRef, useState } from "react";
|
|
7
|
+
import { Button, Link } from "react-aria-components";
|
|
8
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
7
9
|
//#region src/button/button.tsx
|
|
8
10
|
/**
|
|
9
11
|
* Variant classes, exported so a consumer can reuse the exact classes we ship
|
|
10
|
-
* rather than guessing at them.
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* rather than guessing at them.
|
|
13
|
+
*
|
|
14
|
+
* NOT the answer for a link-shaped button any more: pass `href` to Button. On a
|
|
15
|
+
* consumer's own <a> these classes get none of their states -- hover, press and
|
|
16
|
+
* the focus ring all key on React Aria data attributes that a plain anchor never
|
|
17
|
+
* receives, and the base sets outline-none, so keyboard focus was invisible.
|
|
14
18
|
*
|
|
15
19
|
* Ported from the legacy shadcn Button. The variant and size vocabulary is
|
|
16
20
|
* deliberately identical so existing call sites migrate by rename, with six
|
|
@@ -23,9 +27,10 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
23
27
|
* data-[focus-visible] is keyboard focus only, and data-[pressed] covers mouse,
|
|
24
28
|
* touch and keyboard uniformly. The original had no pressed state at all.
|
|
25
29
|
*/
|
|
30
|
+
const pressScale = "motion-safe:data-[pressed]:scale-(--press-scale) [&:is([aria-haspopup]:not([aria-haspopup=false]),[data-state],[role=combobox])]:scale-none!";
|
|
26
31
|
const buttonVariants = cva([
|
|
27
32
|
"inline-flex items-center justify-center gap-(--density-control-gap) shrink-0 whitespace-nowrap",
|
|
28
|
-
"rounded-
|
|
33
|
+
"rounded-control font-sans font-medium",
|
|
29
34
|
"cursor-pointer select-none",
|
|
30
35
|
"border-(length:--border-width) border-transparent bg-transparent",
|
|
31
36
|
"[&_svg]:pointer-events-none [&_svg]:shrink-0",
|
|
@@ -35,56 +40,81 @@ const buttonVariants = cva([
|
|
|
35
40
|
"data-[focus-visible]:outline-(length:--focus-ring-width)",
|
|
36
41
|
"data-[focus-visible]:outline-offset-(--focus-ring-offset)",
|
|
37
42
|
"data-[focus-visible]:outline-(--color-ring)",
|
|
38
|
-
"data-[disabled]:cursor-not-allowed
|
|
43
|
+
"data-[disabled]:cursor-not-allowed",
|
|
44
|
+
"[-webkit-tap-highlight-color:transparent]",
|
|
39
45
|
"data-[pending]:cursor-progress"
|
|
40
46
|
], {
|
|
41
47
|
variants: {
|
|
42
48
|
variant: {
|
|
43
49
|
primary: [
|
|
44
50
|
"bg-primary text-primary-foreground shadow-surface",
|
|
45
|
-
"motion-safe:
|
|
51
|
+
"motion-safe:button-motion",
|
|
52
|
+
pressScale,
|
|
53
|
+
"data-[hovered]:bg-primary-hover data-[hovered]:shadow-resting",
|
|
54
|
+
"data-[pressed]:bg-primary-pressed",
|
|
55
|
+
"data-[disabled]:opacity-(--opacity-button-disabled)"
|
|
56
|
+
],
|
|
57
|
+
ai: [
|
|
58
|
+
"bg-primary text-primary-foreground shadow-surface",
|
|
59
|
+
"ai-beam",
|
|
60
|
+
"motion-safe:button-motion",
|
|
61
|
+
pressScale,
|
|
46
62
|
"data-[hovered]:bg-primary-hover",
|
|
47
|
-
"data-[
|
|
63
|
+
"motion-safe:data-[hovered]:[&_svg]:-rotate-12",
|
|
64
|
+
"data-[disabled]:opacity-(--opacity-button-disabled)"
|
|
48
65
|
],
|
|
49
66
|
secondary: [
|
|
50
|
-
"bg-
|
|
51
|
-
"motion-safe:
|
|
52
|
-
|
|
53
|
-
"data-[
|
|
67
|
+
"bg-surface text-foreground border-(length:--border-width) border-border shadow-surface",
|
|
68
|
+
"motion-safe:button-motion",
|
|
69
|
+
pressScale,
|
|
70
|
+
"data-[hovered]:bg-muted data-[hovered]:shadow-resting",
|
|
71
|
+
"data-[pressed]:bg-muted",
|
|
72
|
+
"data-[disabled]:opacity-100 data-[disabled]:bg-muted data-[disabled]:text-muted-foreground data-[disabled]:border-border"
|
|
54
73
|
],
|
|
55
74
|
outline: [
|
|
56
|
-
"bg-
|
|
57
|
-
"motion-safe:
|
|
58
|
-
|
|
59
|
-
"data-[
|
|
75
|
+
"bg-surface text-primary-strong border-(length:--border-width) border-primary-strong shadow-surface",
|
|
76
|
+
"motion-safe:button-motion",
|
|
77
|
+
pressScale,
|
|
78
|
+
"data-[hovered]:bg-muted data-[hovered]:shadow-resting",
|
|
79
|
+
"data-[pressed]:bg-muted data-[pressed]:border-foreground",
|
|
80
|
+
"data-[disabled]:opacity-100 data-[disabled]:bg-muted data-[disabled]:text-muted-foreground data-[disabled]:border-border"
|
|
60
81
|
],
|
|
61
82
|
outlineNeutral: [
|
|
62
|
-
"bg-
|
|
63
|
-
"motion-safe:
|
|
64
|
-
|
|
65
|
-
"data-[
|
|
83
|
+
"bg-surface text-foreground border-(length:--border-width) border-border shadow-surface",
|
|
84
|
+
"motion-safe:button-motion",
|
|
85
|
+
pressScale,
|
|
86
|
+
"data-[hovered]:bg-muted data-[hovered]:shadow-resting",
|
|
87
|
+
"data-[pressed]:bg-muted",
|
|
88
|
+
"data-[disabled]:opacity-100 data-[disabled]:bg-muted data-[disabled]:text-text-disabled"
|
|
66
89
|
],
|
|
67
90
|
ghost: [
|
|
68
|
-
"bg-transparent text-
|
|
69
|
-
"motion-safe:
|
|
70
|
-
|
|
91
|
+
"bg-transparent text-text-secondary",
|
|
92
|
+
"motion-safe:button-motion",
|
|
93
|
+
pressScale,
|
|
94
|
+
"data-[hovered]:bg-muted data-[hovered]:text-foreground",
|
|
95
|
+
"data-[disabled]:opacity-100 data-[disabled]:text-text-disabled",
|
|
71
96
|
"data-[pressed]:bg-muted data-[pressed]:border-primary-strong"
|
|
72
97
|
],
|
|
73
98
|
destructive: [
|
|
74
|
-
"bg-
|
|
75
|
-
"motion-safe:
|
|
76
|
-
|
|
77
|
-
"data-[
|
|
99
|
+
"bg-surface text-destructive-strong border-(length:--border-width) border-border shadow-surface",
|
|
100
|
+
"motion-safe:button-motion",
|
|
101
|
+
pressScale,
|
|
102
|
+
"data-[hovered]:bg-muted data-[hovered]:border-destructive-strong",
|
|
103
|
+
"data-[pressed]:bg-muted data-[pressed]:border-destructive-strong",
|
|
104
|
+
"data-[disabled]:opacity-100 data-[disabled]:bg-muted data-[disabled]:border-border data-[disabled]:text-[color-mix(in_oklab,var(--color-destructive)_55%,var(--color-muted))]"
|
|
78
105
|
],
|
|
79
106
|
link: [
|
|
80
|
-
"bg-transparent text-
|
|
107
|
+
"bg-transparent text-text-link underline-offset-(--underline-offset)",
|
|
108
|
+
"motion-safe:button-motion",
|
|
109
|
+
"data-[disabled]:text-text-disabled",
|
|
81
110
|
"data-[hovered]:underline",
|
|
82
|
-
"data-[pressed]:underline"
|
|
111
|
+
"data-[pressed]:underline data-[pressed]:opacity-80",
|
|
112
|
+
"[&_svg:last-child]:transition-transform motion-safe:data-[hovered]:[&_svg:last-child]:translate-x-0.75 rtl:motion-safe:data-[hovered]:[&_svg:last-child]:-translate-x-0.75"
|
|
83
113
|
]
|
|
84
114
|
},
|
|
85
115
|
size: {
|
|
86
|
-
sm: "h-(--density-control-h-sm) px-
|
|
87
|
-
md: "h-(--density-control-h-md) px-
|
|
116
|
+
sm: "h-(--density-control-h-sm) px-4 text-sm",
|
|
117
|
+
md: "h-(--density-control-h-md) px-4 text-sm",
|
|
88
118
|
lg: "h-(--density-control-h-lg) px-(--density-control-pad-lg) text-lg",
|
|
89
119
|
icon: "size-(--density-control-h-md) px-0 text-base"
|
|
90
120
|
}
|
|
@@ -94,9 +124,101 @@ const buttonVariants = cva([
|
|
|
94
124
|
size: "md"
|
|
95
125
|
}
|
|
96
126
|
});
|
|
127
|
+
/** A key for the label content: text plus element names, so a new label or icon crossfades while prop-only updates stay in place. */
|
|
128
|
+
function labelKey(node) {
|
|
129
|
+
if (node == null || typeof node === "boolean") return "";
|
|
130
|
+
if (typeof node === "string" || typeof node === "number" || typeof node === "bigint") return String(node);
|
|
131
|
+
if (Array.isArray(node)) return node.map(labelKey).join("");
|
|
132
|
+
if (!isValidElement(node)) return "";
|
|
133
|
+
const type = node.type;
|
|
134
|
+
return "<" + (typeof type === "string" ? type : type?.displayName ?? type?.name ?? "") + ">" + labelKey(node.props.children);
|
|
135
|
+
}
|
|
136
|
+
/** A label with no text once element names are stripped is an icon, which scales instead of rising. */
|
|
137
|
+
const isIconKey = (key) => !/\S/.test(key.replace(/<[^>]*>/g, ""));
|
|
138
|
+
function LeavingPhase({ phase, onDone }) {
|
|
139
|
+
const { id } = phase;
|
|
140
|
+
const remove = useCallback(() => onDone(id), [onDone, id]);
|
|
141
|
+
useExitBackstop(true, remove);
|
|
142
|
+
return /* @__PURE__ */ jsx("span", {
|
|
143
|
+
"aria-hidden": "true",
|
|
144
|
+
onAnimationEnd: (event) => {
|
|
145
|
+
if (event.target === event.currentTarget) remove();
|
|
146
|
+
},
|
|
147
|
+
style: phase.rect,
|
|
148
|
+
className: cn("absolute inline-flex items-center justify-center gap-(--density-control-gap) whitespace-nowrap [&_svg]:shrink-0", phase.icon ? "motion-safe:animate-glyph-out motion-reduce:animate-fade-out" : "motion-safe:animate-label-out motion-reduce:animate-fade-out"),
|
|
149
|
+
children: phase.node
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
/** The loading spinner: it scales in on the snappy spring, and out smaller with a little blur. Nothing animates if it is there on first mount. */
|
|
153
|
+
function Loader({ show }) {
|
|
154
|
+
const [initial] = useState(show);
|
|
155
|
+
const [rendered, setRendered] = useState(show);
|
|
156
|
+
const [animated, setAnimated] = useState(false);
|
|
157
|
+
const leaving = rendered && !show;
|
|
158
|
+
if (show && !rendered) setRendered(true);
|
|
159
|
+
if (!animated && show !== initial) setAnimated(true);
|
|
160
|
+
const unmount = useCallback(() => setRendered(false), []);
|
|
161
|
+
useExitBackstop(leaving, unmount);
|
|
162
|
+
if (!rendered) return null;
|
|
163
|
+
return /* @__PURE__ */ jsx("span", {
|
|
164
|
+
"aria-hidden": "true",
|
|
165
|
+
onAnimationEnd: (event) => {
|
|
166
|
+
if (leaving && event.target === event.currentTarget) unmount();
|
|
167
|
+
},
|
|
168
|
+
className: cn("absolute top-1/2 left-1/2 -m-2 grid size-4", leaving ? "motion-safe:animate-loader-out motion-reduce:animate-fade-out" : animated && "motion-safe:animate-loader-in motion-reduce:animate-fade-in"),
|
|
169
|
+
children: /* @__PURE__ */ jsx("span", { className: "rounded-circle border-(length:--border-width-spinner) border-current border-r-transparent motion-safe:animate-spin-fast" })
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* The button's inside: a loader, and a slot that holds the current label.
|
|
174
|
+
*
|
|
175
|
+
* A new label (a different text, or a different icon) mounts under a new key and
|
|
176
|
+
* rises in while the old one is popped out of flow where it was and lifts away.
|
|
177
|
+
* Nothing animates on first mount, and a prop-only update (same key) stays in
|
|
178
|
+
* place.
|
|
179
|
+
*/
|
|
180
|
+
function ButtonContent({ children, pending }) {
|
|
181
|
+
const key = labelKey(children);
|
|
182
|
+
const icon = isIconKey(key);
|
|
183
|
+
const contentRef = useRef(null);
|
|
184
|
+
const phaseRef = useRef(null);
|
|
185
|
+
useMorphWidth(contentRef, key);
|
|
186
|
+
const { leaving, changed, remove } = useLeavingItems(key, {
|
|
187
|
+
node: children,
|
|
188
|
+
icon
|
|
189
|
+
}, () => phaseRef.current);
|
|
190
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Loader, { show: pending }), /* @__PURE__ */ jsx("span", {
|
|
191
|
+
className: cn("button-slot", pending && "opacity-0"),
|
|
192
|
+
children: /* @__PURE__ */ jsxs("span", {
|
|
193
|
+
ref: contentRef,
|
|
194
|
+
className: "inline-flex flex-none items-center",
|
|
195
|
+
children: [leaving.map((item) => /* @__PURE__ */ jsx(LeavingPhase, {
|
|
196
|
+
phase: {
|
|
197
|
+
id: item.id,
|
|
198
|
+
node: item.value.node,
|
|
199
|
+
icon: item.value.icon,
|
|
200
|
+
rect: item.rect
|
|
201
|
+
},
|
|
202
|
+
onDone: remove
|
|
203
|
+
}, item.id)), /* @__PURE__ */ jsx("span", {
|
|
204
|
+
ref: phaseRef,
|
|
205
|
+
"data-slot": "button-label",
|
|
206
|
+
className: cn("inline-flex items-center justify-center gap-(--density-control-gap) whitespace-nowrap [&_svg]:shrink-0", changed && (icon ? "motion-safe:animate-glyph-in motion-reduce:animate-fade-in" : "motion-safe:animate-label-in motion-reduce:animate-fade-in")),
|
|
207
|
+
children
|
|
208
|
+
}, key)]
|
|
209
|
+
})
|
|
210
|
+
})] });
|
|
211
|
+
}
|
|
97
212
|
/**
|
|
98
213
|
* A button.
|
|
99
214
|
*
|
|
215
|
+
* A label that changes (a different text, or a different icon) crossfades, and
|
|
216
|
+
* the button's width springs to fit it. While that runs, the OUTGOING label is
|
|
217
|
+
* still in the DOM for about 200ms, `aria-hidden` and out of flow, so read a
|
|
218
|
+
* button's text after the change settles, and do not put `id`s, inputs or
|
|
219
|
+
* anything stateful inside a label that changes. Text that changes constantly,
|
|
220
|
+
* such as a live counter, crossfades every time it does.
|
|
221
|
+
*
|
|
100
222
|
* `size="icon"` renders a square button with no visible text, so it **must**
|
|
101
223
|
* carry an `aria-label` -- otherwise it has no accessible name and fails axe's
|
|
102
224
|
* `button-name` rule. The IconOnly story is the guard on that.
|
|
@@ -106,21 +228,52 @@ const buttonVariants = cva([
|
|
|
106
228
|
* <Button startIcon={<SaveIcon aria-hidden />}>Save changes</Button>
|
|
107
229
|
* <Button endIcon={<ChevronIcon aria-hidden />}>Continue</Button>
|
|
108
230
|
* <Button variant="outline" size="icon" aria-label="Close"><XIcon /></Button>
|
|
231
|
+
* <Button href="/reports" variant="outlineNeutral">View reports</Button>
|
|
109
232
|
*/
|
|
110
|
-
const Button$1 = forwardRef(function Button$2({ className, variant, size, startIcon, endIcon, children, ...props }, ref) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
children: startIcon === void 0 && endIcon === void 0 ? children : (renderProps) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
233
|
+
const Button$1 = forwardRef(function Button$2({ className, variant, size, startIcon, endIcon, children, href, target, rel, download, ...props }, ref) {
|
|
234
|
+
const classes = cn(buttonVariants({
|
|
235
|
+
variant,
|
|
236
|
+
size
|
|
237
|
+
}), className);
|
|
238
|
+
const button = useAriaBusy(props.isPending === true);
|
|
239
|
+
const content = (renderProps) => /* @__PURE__ */ jsxs(ButtonContent, {
|
|
240
|
+
pending: renderProps.isPending,
|
|
241
|
+
children: [
|
|
120
242
|
startIcon,
|
|
121
243
|
typeof children === "function" ? children(renderProps) : children,
|
|
122
244
|
endIcon
|
|
123
|
-
]
|
|
245
|
+
]
|
|
246
|
+
});
|
|
247
|
+
const { onPressStart } = props;
|
|
248
|
+
const pressStart = (event) => {
|
|
249
|
+
if (!anchorsLayer(props)) {
|
|
250
|
+
const target = event.target;
|
|
251
|
+
target.style.setProperty("--press-scale", pressScaleFor(target.offsetWidth));
|
|
252
|
+
}
|
|
253
|
+
onPressStart?.(event);
|
|
254
|
+
};
|
|
255
|
+
if (href !== void 0) return /* @__PURE__ */ jsx(Link, {
|
|
256
|
+
ref,
|
|
257
|
+
...props,
|
|
258
|
+
onPressStart: pressStart,
|
|
259
|
+
href,
|
|
260
|
+
target,
|
|
261
|
+
rel,
|
|
262
|
+
download,
|
|
263
|
+
"data-slot": "button",
|
|
264
|
+
className: classes,
|
|
265
|
+
children: (renderProps) => content({
|
|
266
|
+
...renderProps,
|
|
267
|
+
isPending: false
|
|
268
|
+
})
|
|
269
|
+
});
|
|
270
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
271
|
+
ref: mergeRefs(ref, button),
|
|
272
|
+
...props,
|
|
273
|
+
onPressStart: pressStart,
|
|
274
|
+
"data-slot": "button",
|
|
275
|
+
className: classes,
|
|
276
|
+
children: content
|
|
124
277
|
});
|
|
125
278
|
});
|
|
126
279
|
//#endregion
|