@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
package/dist/card/card.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { cn } from "../lib/cn.js";
|
|
2
|
+
import { cn, cnAll } from "../lib/cn.js";
|
|
3
3
|
import { cva } from "class-variance-authority";
|
|
4
|
-
import { forwardRef } from "react";
|
|
4
|
+
import { forwardRef, useState } from "react";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
6
|
//#region src/card/card.tsx
|
|
7
7
|
/**
|
|
@@ -34,7 +34,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
34
34
|
*/
|
|
35
35
|
const cardVariants = cva([
|
|
36
36
|
"flex flex-col gap-6",
|
|
37
|
-
"rounded-
|
|
37
|
+
"rounded-panel border-(length:--border-width) border-border py-6",
|
|
38
38
|
"bg-card text-card-foreground shadow-surface",
|
|
39
39
|
"box-border font-sans"
|
|
40
40
|
]);
|
|
@@ -50,12 +50,23 @@ const cardTitleVariants = cva(["text-base leading-(--leading-none) font-semibold
|
|
|
50
50
|
const cardDescriptionVariants = cva(["text-sm leading-(--leading-normal) text-muted-foreground"]);
|
|
51
51
|
const cardContentVariants = cva("px-6");
|
|
52
52
|
const cardFooterVariants = cva("flex items-center px-6");
|
|
53
|
-
const Card = forwardRef(function Card({ className, ...props }, ref) {
|
|
53
|
+
const Card = forwardRef(function Card({ className, interactive = false, onPointerEnter, onPointerLeave, ...props }, ref) {
|
|
54
|
+
const [pointed, setPointed] = useState(false);
|
|
54
55
|
return /* @__PURE__ */ jsx("div", {
|
|
55
56
|
ref,
|
|
56
57
|
...props,
|
|
57
58
|
"data-slot": "card",
|
|
58
|
-
|
|
59
|
+
"data-interactive": interactive || void 0,
|
|
60
|
+
"data-pointed": interactive && pointed || void 0,
|
|
61
|
+
onPointerEnter: (event) => {
|
|
62
|
+
onPointerEnter?.(event);
|
|
63
|
+
if (interactive && event.pointerType !== "touch") setPointed(true);
|
|
64
|
+
},
|
|
65
|
+
onPointerLeave: (event) => {
|
|
66
|
+
onPointerLeave?.(event);
|
|
67
|
+
setPointed(false);
|
|
68
|
+
},
|
|
69
|
+
className: cnAll(cardVariants(), interactive && "card-lift", className)
|
|
59
70
|
});
|
|
60
71
|
});
|
|
61
72
|
const CardHeader = forwardRef(function CardHeader({ className, ...props }, ref) {
|
package/dist/card/card.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card.js","names":[],"sources":["../../src/card/card.tsx"],"sourcesContent":["\"use client\";\n\nimport { cva } from \"class-variance-authority\";\nimport { forwardRef, type ComponentPropsWithoutRef } from \"react\";\n\nimport { cn } from \"../lib/cn.js\";\n\n/**\n * Card, ported from the legacy shadcn component.\n *\n * Presentational, so there is no React Aria base -- React Aria ships no card,\n * and a container that is not focusable, selectable or interactive needs no\n * behaviour to inherit.\n *\n * Five parts, from six. The census (24 consumer files, the most-used\n * container in the app) reads: Card 55, CardContent 40, CardHeader 21,\n * CardTitle 19, CardDescription 8, CardFooter 2, **CardAction 0**.\n *\n * Dropping `CardAction` takes three things with it, which is most of the\n * legacy header's complexity: the `grid`, the `grid-rows-[auto_auto]`, and\n * the `has-data-[slot=card-action]:grid-cols-[1fr_auto]` rule that existed\n * only to reserve a column for it. With no action to place, a header is a\n * stack.\n *\n * Two more legacy rules are gone. `[.border-b]:pb-6` and `[.border-t]:pt-6`\n * added padding when the CONSUMER happened to add a border class -- clever,\n * but action at a distance through a class name we do not own, and the census\n * found zero application call sites relying on it (one call site passes\n * `border-b-0`, which removes a border it never had). `@container/card-header`\n * named a container nothing queried.\n *\n * Every string in the cva blocks below is a STATIC literal. Tailwind scans\n * source text, so a class assembled at runtime is invisible to it and would\n * simply never be emitted.\n */\nexport const cardVariants = cva([\n \"flex flex-col gap-6\",\n \"rounded-
|
|
1
|
+
{"version":3,"file":"card.js","names":[],"sources":["../../src/card/card.tsx"],"sourcesContent":["\"use client\";\n\nimport { cva } from \"class-variance-authority\";\nimport { forwardRef, useState, type ComponentPropsWithoutRef } from \"react\";\n\nimport { cn, cnAll } from \"../lib/cn.js\";\n\n/**\n * Card, ported from the legacy shadcn component.\n *\n * Presentational, so there is no React Aria base -- React Aria ships no card,\n * and a container that is not focusable, selectable or interactive needs no\n * behaviour to inherit.\n *\n * Five parts, from six. The census (24 consumer files, the most-used\n * container in the app) reads: Card 55, CardContent 40, CardHeader 21,\n * CardTitle 19, CardDescription 8, CardFooter 2, **CardAction 0**.\n *\n * Dropping `CardAction` takes three things with it, which is most of the\n * legacy header's complexity: the `grid`, the `grid-rows-[auto_auto]`, and\n * the `has-data-[slot=card-action]:grid-cols-[1fr_auto]` rule that existed\n * only to reserve a column for it. With no action to place, a header is a\n * stack.\n *\n * Two more legacy rules are gone. `[.border-b]:pb-6` and `[.border-t]:pt-6`\n * added padding when the CONSUMER happened to add a border class -- clever,\n * but action at a distance through a class name we do not own, and the census\n * found zero application call sites relying on it (one call site passes\n * `border-b-0`, which removes a border it never had). `@container/card-header`\n * named a container nothing queried.\n *\n * Every string in the cva blocks below is a STATIC literal. Tailwind scans\n * source text, so a class assembled at runtime is invisible to it and would\n * simply never be emitted.\n */\nexport const cardVariants = cva([\n \"flex flex-col gap-6\",\n \"rounded-panel border-(length:--border-width) border-border py-6\",\n \"bg-card text-card-foreground shadow-surface\",\n\n // box-border and font-sans are not boilerplate. The reset in\n // @seekalfred/styles is OPT-IN, so a consumer may load none: content-box\n // would add the padding to any width they set (the Alert shipped\n // overflowing its container by 46px), and an unstyled document renders\n // text in a serif (the Accordion shipped its panel that way). Declaring\n // the family HERE rather than on each part means one declaration covers\n // the whole subtree by inheritance.\n \"box-border font-sans\",\n]);\n\n/**\n * Padding is inline-only on the sections and block-only on the shell.\n *\n * That split is load-bearing rather than stylistic: it is what lets a\n * consumer run a divider or a full-bleed image edge to edge, which a single\n * `p-6` on the shell would make impossible.\n */\nexport const cardHeaderVariants = cva(\"flex flex-col gap-1.5 px-6\");\n\nexport const cardTitleVariants = cva([\n // leading-* AFTER text-*: tailwind-merge treats a later text-* as owning\n // line-height and silently strips a leading-* that precedes it.\n \"text-base leading-(--leading-none) font-semibold\",\n // The user-agent <h3> ships a 1em block margin and font-size 1.17em. The\n // legacy component was a <div> and never met either.\n \"m-0\",\n]);\n\nexport const cardDescriptionVariants = cva([\n \"text-sm leading-(--leading-normal) text-muted-foreground\",\n]);\n\nexport const cardContentVariants = cva(\"px-6\");\n\nexport const cardFooterVariants = cva(\"flex items-center px-6\");\n\n/**\n * A content container.\n *\n * @example\n * <Card>\n * <CardHeader>\n * <CardTitle>Learning Progress</CardTitle>\n * <CardDescription>Across all active courses.</CardDescription>\n * </CardHeader>\n * <CardContent>Twelve of eighteen modules complete.</CardContent>\n * </Card>\n */\nexport interface CardProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * Make the card respond to a pointer: it floats 2px on a spring while it is pointed\n * at, its border darkens and its shadow deepens. Mouse and pen only; touch never lifts.\n * Leave it off for a card that is not a target: a static card should not move.\n */\n interactive?: boolean;\n}\n\nexport const Card = forwardRef<HTMLDivElement, CardProps>(function Card(\n { className, interactive = false, onPointerEnter, onPointerLeave, ...props },\n ref,\n) {\n // Pointed at by a mouse or pen. Touch never lifts, so it is read from the pointer, not :hover (which a tap leaves stuck).\n const [pointed, setPointed] = useState(false);\n return (\n <div\n ref={ref}\n {...props}\n data-slot=\"card\"\n data-interactive={interactive || undefined}\n data-pointed={(interactive && pointed) || undefined}\n onPointerEnter={(event) => {\n onPointerEnter?.(event);\n if (interactive && event.pointerType !== \"touch\") setPointed(true);\n }}\n onPointerLeave={(event) => {\n onPointerLeave?.(event);\n setPointed(false);\n }}\n className={cnAll(cardVariants(), interactive && \"card-lift\", className)}\n />\n );\n});\n\n/** Title and description, stacked. */\nexport type CardHeaderProps = ComponentPropsWithoutRef<\"div\">;\n\nexport const CardHeader = forwardRef<HTMLDivElement, CardHeaderProps>(function CardHeader(\n { className, ...props },\n ref,\n) {\n return (\n <div\n ref={ref}\n {...props}\n data-slot=\"card-header\"\n className={cn(cardHeaderVariants(), className)}\n />\n );\n});\n\n/**\n * The card's heading.\n *\n * A REAL heading, unlike the legacy `<div class=\"font-semibold\">`. None of\n * the 19 legacy call sites wrapped one, so 19 card titles were invisible to\n * screen-reader heading navigation -- the same shape of finding as the Avatar\n * port's missing `alt`, and the migration is when it gets answered.\n */\nexport interface CardTitleProps extends ComponentPropsWithoutRef<\"h3\"> {\n /**\n * Heading level.\n *\n * `3` by default, because a card almost always sits under a section\n * heading. It is a prop rather than a constant because the correct level\n * is a fact about the PAGE, and a fixed one would be wrong somewhere; the\n * level changes semantics only, never the rendered size.\n *\n * @default 3\n */\n level?: 1 | 2 | 3 | 4 | 5 | 6;\n}\n\nexport const CardTitle = forwardRef<HTMLHeadingElement, CardTitleProps>(function CardTitle(\n { className, level = 3, ...props },\n ref,\n) {\n // Static union, not a template literal: `h${level}` is a string React\n // accepts but TypeScript cannot narrow to an intrinsic element, and the\n // cast that silences it would also accept `h7`.\n const Heading = ({ 1: \"h1\", 2: \"h2\", 3: \"h3\", 4: \"h4\", 5: \"h5\", 6: \"h6\" } as const)[level];\n\n return (\n <Heading\n ref={ref}\n {...props}\n data-slot=\"card-title\"\n className={cn(cardTitleVariants(), className)}\n />\n );\n});\n\n/** Secondary text under the title. */\nexport type CardDescriptionProps = ComponentPropsWithoutRef<\"div\">;\n\nexport const CardDescription = forwardRef<HTMLDivElement, CardDescriptionProps>(\n function CardDescription({ className, ...props }, ref) {\n return (\n <div\n ref={ref}\n {...props}\n data-slot=\"card-description\"\n className={cn(cardDescriptionVariants(), className)}\n />\n );\n },\n);\n\n/** The card's body. */\nexport type CardContentProps = ComponentPropsWithoutRef<\"div\">;\n\nexport const CardContent = forwardRef<HTMLDivElement, CardContentProps>(function CardContent(\n { className, ...props },\n ref,\n) {\n return (\n <div\n ref={ref}\n {...props}\n data-slot=\"card-content\"\n className={cn(cardContentVariants(), className)}\n />\n );\n});\n\n/** Actions or metadata at the foot of the card. */\nexport type CardFooterProps = ComponentPropsWithoutRef<\"div\">;\n\nexport const CardFooter = forwardRef<HTMLDivElement, CardFooterProps>(function CardFooter(\n { className, ...props },\n ref,\n) {\n return (\n <div\n ref={ref}\n {...props}\n data-slot=\"card-footer\"\n className={cn(cardFooterVariants(), className)}\n />\n );\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,MAAa,eAAe,IAAI;CAC9B;CACA;CACA;CASA;AACF,CAAC;;;;;;;;AASD,MAAa,qBAAqB,IAAI,4BAA4B;AAElE,MAAa,oBAAoB,IAAI,CAGnC,oDAGA,KACF,CAAC;AAED,MAAa,0BAA0B,IAAI,CACzC,0DACF,CAAC;AAED,MAAa,sBAAsB,IAAI,MAAM;AAE7C,MAAa,qBAAqB,IAAI,wBAAwB;AAuB9D,MAAa,OAAO,WAAsC,SAAS,KACjE,EAAE,WAAW,cAAc,OAAO,gBAAgB,gBAAgB,GAAG,SACrE,KACA;CAEA,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAC5C,OACE,oBAAC,OAAD;EACO;EACL,GAAI;EACJ,aAAU;EACV,oBAAkB,eAAe,KAAA;EACjC,gBAAe,eAAe,WAAY,KAAA;EAC1C,iBAAiB,UAAU;GACzB,iBAAiB,KAAK;GACtB,IAAI,eAAe,MAAM,gBAAgB,SAAS,WAAW,IAAI;EACnE;EACA,iBAAiB,UAAU;GACzB,iBAAiB,KAAK;GACtB,WAAW,KAAK;EAClB;EACA,WAAW,MAAM,aAAa,GAAG,eAAe,aAAa,SAAS;CACvE,CAAA;AAEL,CAAC;AAKD,MAAa,aAAa,WAA4C,SAAS,WAC7E,EAAE,WAAW,GAAG,SAChB,KACA;CACA,OACE,oBAAC,OAAD;EACO;EACL,GAAI;EACJ,aAAU;EACV,WAAW,GAAG,mBAAmB,GAAG,SAAS;CAC9C,CAAA;AAEL,CAAC;AAwBD,MAAa,YAAY,WAA+C,SAAS,UAC/E,EAAE,WAAW,QAAQ,GAAG,GAAG,SAC3B,KACA;CAIA,MAAM,UAAW;EAAE,GAAG;EAAM,GAAG;EAAM,GAAG;EAAM,GAAG;EAAM,GAAG;EAAM,GAAG;CAAK,EAAY;CAEpF,OACE,oBAAC,SAAD;EACO;EACL,GAAI;EACJ,aAAU;EACV,WAAW,GAAG,kBAAkB,GAAG,SAAS;CAC7C,CAAA;AAEL,CAAC;AAKD,MAAa,kBAAkB,WAC7B,SAAS,gBAAgB,EAAE,WAAW,GAAG,SAAS,KAAK;CACrD,OACE,oBAAC,OAAD;EACO;EACL,GAAI;EACJ,aAAU;EACV,WAAW,GAAG,wBAAwB,GAAG,SAAS;CACnD,CAAA;AAEL,CACF;AAKA,MAAa,cAAc,WAA6C,SAAS,YAC/E,EAAE,WAAW,GAAG,SAChB,KACA;CACA,OACE,oBAAC,OAAD;EACO;EACL,GAAI;EACJ,aAAU;EACV,WAAW,GAAG,oBAAoB,GAAG,SAAS;CAC/C,CAAA;AAEL,CAAC;AAKD,MAAa,aAAa,WAA4C,SAAS,WAC7E,EAAE,WAAW,GAAG,SAChB,KACA;CACA,OACE,oBAAC,OAAD;EACO;EACL,GAAI;EACJ,aAAU;EACV,WAAW,GAAG,mBAAmB,GAAG,SAAS;CAC9C,CAAA;AAEL,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
//#region src/card-stack/card-stack.d.ts
|
|
3
|
+
export type CardDecision = "left" | "right";
|
|
4
|
+
/**
|
|
5
|
+
* CardStack: a deck of cards reviewed one at a time. Drag or flick the top card
|
|
6
|
+
* left or right, or use the buttons and the arrow keys. The cards behind peek
|
|
7
|
+
* out below it and rise as it leaves; a card in the hand tips the way it is
|
|
8
|
+
* moving and shows a stamp (the action it will take); let go early and it springs
|
|
9
|
+
* home, let go far enough, or fast enough, and it is thrown. Undo brings the
|
|
10
|
+
* last card back from where it left, and Start over deals the deck again.
|
|
11
|
+
*
|
|
12
|
+
* Use it for quick triage where each item deserves a moment of attention:
|
|
13
|
+
* shortlisting destinations, candidates or design options. Use a list or a
|
|
14
|
+
* table when people need to compare items side by side.
|
|
15
|
+
*
|
|
16
|
+
* Keyboard: the stack takes one tab stop; Left and Right decide the top card,
|
|
17
|
+
* Backspace (or Ctrl or Cmd with Z) undoes. Every decision is announced politely
|
|
18
|
+
* and the buttons do the same, so nothing needs a drag. Reduced motion fades the
|
|
19
|
+
* card out and back instead of throwing it.
|
|
20
|
+
*/
|
|
21
|
+
export interface CardStackProps<T> {
|
|
22
|
+
items: T[];
|
|
23
|
+
/** A stable key for an item. */
|
|
24
|
+
getKey: (item: T) => string;
|
|
25
|
+
/** A short name for the card, used in its accessible label and announcements, such as "Lisbon". */
|
|
26
|
+
getLabel: (item: T) => string;
|
|
27
|
+
/** The card's content. It fills the card, whose size the stack sets. */
|
|
28
|
+
renderCard: (item: T) => ReactNode;
|
|
29
|
+
/** Called when a card is decided. */
|
|
30
|
+
onDecide?: (item: T, decision: CardDecision) => void;
|
|
31
|
+
/** Called when a decision is undone. */
|
|
32
|
+
onUndo?: (item: T, decision: CardDecision) => void;
|
|
33
|
+
/** Called when the deck is dealt again. */
|
|
34
|
+
onReset?: () => void;
|
|
35
|
+
/** Action names for each side, used on the buttons and the stamps that appear while dragging. @default { left: "Pass", right: "Keep" } */
|
|
36
|
+
labels?: {
|
|
37
|
+
left: string;
|
|
38
|
+
right: string;
|
|
39
|
+
};
|
|
40
|
+
/** Past tense of each action for announcements, such as "skipped" and "shortlisted". Without it a decision reads "Lisbon: Keep". */
|
|
41
|
+
outcomes?: {
|
|
42
|
+
left: string;
|
|
43
|
+
right: string;
|
|
44
|
+
};
|
|
45
|
+
/** Accessible name for the stack. @default "Cards" */
|
|
46
|
+
label?: string;
|
|
47
|
+
/** Shown once every card has been decided. Receives a function that brings all cards back. */
|
|
48
|
+
renderEmpty?: (reset: () => void) => ReactNode;
|
|
49
|
+
/** Extra classes for the stack. Merged last. */
|
|
50
|
+
className?: string;
|
|
51
|
+
}
|
|
52
|
+
export declare function CardStack<T>({ items, getKey, getLabel, renderCard, onDecide, onUndo, onReset, labels, outcomes, label, renderEmpty, className }: CardStackProps<T>): import("react").JSX.Element;
|
|
53
|
+
//#endregion
|
|
54
|
+
//# sourceMappingURL=card-stack.d.ts.map
|
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { prefersReducedMotion, useExitBackstop, useIsomorphicLayoutEffect } from "../lib/motion.js";
|
|
4
|
+
import { Button } from "../button/button.js";
|
|
5
|
+
import { useCallback, useId, useRef, useState } from "react";
|
|
6
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
//#region src/card-stack/card-stack.tsx
|
|
8
|
+
/** Cards rendered in the stack. The last one waits invisibly one step behind and fades in as it rises. */
|
|
9
|
+
const VISIBLE = 4;
|
|
10
|
+
/** Degrees of rotation per pixel of horizontal travel. */
|
|
11
|
+
const ROTATE = .065;
|
|
12
|
+
/** A release faster than this (px/s) throws the card even when it has only moved a little. */
|
|
13
|
+
const FLICK = 500;
|
|
14
|
+
/** Drag distance at which the cards behind have fully risen. */
|
|
15
|
+
const LIFT_DISTANCE = 160;
|
|
16
|
+
/** Vertical travel is not a decision, so past a small free zone it resists like a rubber band. */
|
|
17
|
+
const FREE_Y = 48;
|
|
18
|
+
const STRETCH_Y = 140;
|
|
19
|
+
/** The stamp is fully shown at 96px of travel and starts at 16px. */
|
|
20
|
+
const STAMP_FROM = 16;
|
|
21
|
+
/** A thrown card is gone this long after it starts (the fade finishes well before); the backstop for a transition that never ends. */
|
|
22
|
+
const FLIGHT_BACKSTOP_MS = 1500;
|
|
23
|
+
const resistY = (raw) => {
|
|
24
|
+
const distance = Math.abs(raw);
|
|
25
|
+
return distance <= FREE_Y ? raw : Math.sign(raw) * (FREE_Y + (1 - 1 / ((distance - FREE_Y) * .55 / STRETCH_Y + 1)) * STRETCH_Y);
|
|
26
|
+
};
|
|
27
|
+
const unresistY = (shown) => {
|
|
28
|
+
const distance = Math.abs(shown);
|
|
29
|
+
if (distance <= FREE_Y) return shown;
|
|
30
|
+
const stretch = Math.min(distance - FREE_Y, 139);
|
|
31
|
+
return Math.sign(shown) * (FREE_Y + (1 / (1 - stretch / STRETCH_Y) - 1) * STRETCH_Y / .55);
|
|
32
|
+
};
|
|
33
|
+
const clampUnit = (value) => Math.min(1, Math.max(0, value));
|
|
34
|
+
/** Where the card is now, mid-flight included: the computed translate, in px. */
|
|
35
|
+
function readOffset(el) {
|
|
36
|
+
const value = getComputedStyle(el).translate;
|
|
37
|
+
if (!value || value === "none") return {
|
|
38
|
+
x: 0,
|
|
39
|
+
y: 0
|
|
40
|
+
};
|
|
41
|
+
const [x, y] = value.split(" ").map(parseFloat);
|
|
42
|
+
return {
|
|
43
|
+
x: x || 0,
|
|
44
|
+
y: y || 0
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function velocityOf(samples, now) {
|
|
48
|
+
const recent = samples.filter((sample) => now - sample.t <= 80);
|
|
49
|
+
const first = recent[0];
|
|
50
|
+
const last = recent[recent.length - 1];
|
|
51
|
+
if (!first || !last || first === last || now - last.t > 60) return {
|
|
52
|
+
x: 0,
|
|
53
|
+
y: 0
|
|
54
|
+
};
|
|
55
|
+
const seconds = (last.t - first.t) / 1e3;
|
|
56
|
+
return {
|
|
57
|
+
x: (last.x - first.x) / seconds,
|
|
58
|
+
y: (last.y - first.y) / seconds
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const iconProps = {
|
|
62
|
+
width: 16,
|
|
63
|
+
height: 16,
|
|
64
|
+
viewBox: "0 0 24 24",
|
|
65
|
+
fill: "none",
|
|
66
|
+
stroke: "currentColor",
|
|
67
|
+
strokeWidth: 1.75,
|
|
68
|
+
strokeLinecap: "round",
|
|
69
|
+
strokeLinejoin: "round",
|
|
70
|
+
"aria-hidden": true
|
|
71
|
+
};
|
|
72
|
+
const CheckIcon = () => /* @__PURE__ */ jsx("svg", {
|
|
73
|
+
...iconProps,
|
|
74
|
+
children: /* @__PURE__ */ jsx("path", { d: "M5 12.5 10 17.5 19 7" })
|
|
75
|
+
});
|
|
76
|
+
const CloseIcon = () => /* @__PURE__ */ jsx("svg", {
|
|
77
|
+
...iconProps,
|
|
78
|
+
children: /* @__PURE__ */ jsx("path", { d: "M6 6l12 12M18 6 6 18" })
|
|
79
|
+
});
|
|
80
|
+
const UndoIcon = () => /* @__PURE__ */ jsx("svg", {
|
|
81
|
+
...iconProps,
|
|
82
|
+
children: /* @__PURE__ */ jsx("path", { d: "M4 12a8 8 0 1 0 2.5-5.8M4 4v4.5h4.5" })
|
|
83
|
+
});
|
|
84
|
+
/**
|
|
85
|
+
* A control that stays focusable when it has nothing to do: React Aria drops `aria-disabled` and a disabled button would
|
|
86
|
+
* drop focus to the page when the stack runs out, so the attribute is set by hand and the press is guarded.
|
|
87
|
+
*/
|
|
88
|
+
function Control({ disabled, onPress, ...rest }) {
|
|
89
|
+
const ref = useRef(null);
|
|
90
|
+
useIsomorphicLayoutEffect(() => {
|
|
91
|
+
if (disabled) ref.current?.setAttribute("aria-disabled", "true");
|
|
92
|
+
else ref.current?.removeAttribute("aria-disabled");
|
|
93
|
+
}, [disabled]);
|
|
94
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
95
|
+
...rest,
|
|
96
|
+
ref,
|
|
97
|
+
className: "aria-disabled:cursor-default aria-disabled:opacity-40",
|
|
98
|
+
onPress: () => {
|
|
99
|
+
if (!disabled) onPress();
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
/** Renders a custom empty state; the reset handler travels as a prop so render never touches the stack's refs. */
|
|
104
|
+
function EmptySlot({ render, onReset }) {
|
|
105
|
+
return /* @__PURE__ */ jsx(Fragment$1, { children: render(onReset) });
|
|
106
|
+
}
|
|
107
|
+
const HOME_TRANSITION = (delay) => `translate var(--duration-smooth) var(--ease-smooth) ${delay}ms, rotate var(--duration-smooth) var(--ease-smooth) ${delay}ms, opacity var(--duration-quick) var(--ease-enter) ${delay}ms`;
|
|
108
|
+
const SPRING_BACK = "translate var(--duration-morph) var(--ease-morph), rotate var(--duration-morph) var(--ease-morph)";
|
|
109
|
+
const THROW = "translate var(--duration-calm) var(--ease-calm), rotate var(--duration-calm) var(--ease-calm), opacity 220ms var(--ease-settle) 120ms";
|
|
110
|
+
const REDUCED_FADE = "opacity 150ms linear";
|
|
111
|
+
function StackCard({ id, depth, decision, returnFrom, interactive, zIndex, label, labels, stage, fling, onRelease, onThrown, onGone, children }) {
|
|
112
|
+
const card = useRef(null);
|
|
113
|
+
const tilt = useRef(returnFrom?.tilt ?? 1);
|
|
114
|
+
const drag = useRef(null);
|
|
115
|
+
const settled = useRef(!returnFrom);
|
|
116
|
+
const wasDecided = useRef(false);
|
|
117
|
+
const lift = (value) => stage.current?.style.setProperty("--lift", String(value));
|
|
118
|
+
/** Writes the card's place and what follows from it (its tilt and its stamps) straight to the DOM: a drag never re-renders. */
|
|
119
|
+
const place = (el, x, y) => {
|
|
120
|
+
el.style.translate = `${x}px ${y}px`;
|
|
121
|
+
el.style.rotate = `${x * ROTATE * tilt.current}deg`;
|
|
122
|
+
el.style.setProperty("--keep", String(clampUnit((x - STAMP_FROM) / 80)));
|
|
123
|
+
el.style.setProperty("--pass", String(clampUnit((-16 - x) / 80)));
|
|
124
|
+
};
|
|
125
|
+
useIsomorphicLayoutEffect(() => {
|
|
126
|
+
const el = card.current;
|
|
127
|
+
if (!el) return;
|
|
128
|
+
const reduced = prefersReducedMotion();
|
|
129
|
+
if (decision) {
|
|
130
|
+
drag.current = null;
|
|
131
|
+
el.removeAttribute("data-dragging");
|
|
132
|
+
wasDecided.current = true;
|
|
133
|
+
const direction = decision === "right" ? 1 : -1;
|
|
134
|
+
const { x: cx, y: cy } = readOffset(el);
|
|
135
|
+
const velocity = fling(id) ?? {
|
|
136
|
+
x: direction * 900,
|
|
137
|
+
y: -120
|
|
138
|
+
};
|
|
139
|
+
const speed = Math.hypot(velocity.x, velocity.y);
|
|
140
|
+
let ux = velocity.x;
|
|
141
|
+
let uy = velocity.y;
|
|
142
|
+
if (speed < 200 || Math.sign(ux) !== direction) {
|
|
143
|
+
ux = Math.abs(cx) > 8 ? cx : direction;
|
|
144
|
+
uy = Math.abs(cx) > 8 ? cy * .5 : -.12;
|
|
145
|
+
}
|
|
146
|
+
const length = Math.hypot(ux, uy) || 1;
|
|
147
|
+
ux /= length;
|
|
148
|
+
uy /= length;
|
|
149
|
+
if (Math.abs(ux) < .45) {
|
|
150
|
+
ux = direction * .45;
|
|
151
|
+
uy = Math.sign(uy || -1) * Math.sqrt(.7975);
|
|
152
|
+
}
|
|
153
|
+
const reach = el.offsetWidth * 1.6;
|
|
154
|
+
const exit = {
|
|
155
|
+
x: cx + ux * reach,
|
|
156
|
+
y: cy + uy * reach,
|
|
157
|
+
tilt: tilt.current
|
|
158
|
+
};
|
|
159
|
+
onThrown(id, exit);
|
|
160
|
+
el.style.setProperty(direction > 0 ? "--keep" : "--pass", "1");
|
|
161
|
+
if (reduced) el.style.transition = REDUCED_FADE;
|
|
162
|
+
else {
|
|
163
|
+
el.style.transition = THROW;
|
|
164
|
+
place(el, exit.x, exit.y);
|
|
165
|
+
}
|
|
166
|
+
el.style.opacity = "0";
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (!wasDecided.current && settled.current) return;
|
|
170
|
+
wasDecided.current = false;
|
|
171
|
+
const delay = returnFrom?.delay ?? 0;
|
|
172
|
+
if (!settled.current && !reduced && returnFrom) {
|
|
173
|
+
el.style.transition = "none";
|
|
174
|
+
place(el, returnFrom.x, returnFrom.y);
|
|
175
|
+
el.style.opacity = "0";
|
|
176
|
+
el.offsetWidth;
|
|
177
|
+
}
|
|
178
|
+
settled.current = true;
|
|
179
|
+
if (reduced) {
|
|
180
|
+
el.style.transition = `${REDUCED_FADE} ${delay}ms`;
|
|
181
|
+
place(el, 0, 0);
|
|
182
|
+
} else {
|
|
183
|
+
el.style.transition = HOME_TRANSITION(delay);
|
|
184
|
+
place(el, 0, 0);
|
|
185
|
+
}
|
|
186
|
+
el.style.opacity = "1";
|
|
187
|
+
}, [decision]);
|
|
188
|
+
const gone = useCallback(() => onGone(id), [onGone, id]);
|
|
189
|
+
useExitBackstop(decision !== null, gone, FLIGHT_BACKSTOP_MS);
|
|
190
|
+
function down(event) {
|
|
191
|
+
if (!interactive || event.button !== 0 || !event.isPrimary) return;
|
|
192
|
+
if (event.target instanceof Element && event.target.closest("button, a, input, select, textarea, [role='button']")) return;
|
|
193
|
+
const el = event.currentTarget;
|
|
194
|
+
const now = readOffset(el);
|
|
195
|
+
el.style.transition = "none";
|
|
196
|
+
if (Math.abs(now.x) < 2) {
|
|
197
|
+
const rect = el.getBoundingClientRect();
|
|
198
|
+
tilt.current = event.clientY < rect.top + rect.height / 2 ? 1 : -1;
|
|
199
|
+
}
|
|
200
|
+
place(el, now.x, now.y);
|
|
201
|
+
drag.current = {
|
|
202
|
+
ox: event.clientX - now.x,
|
|
203
|
+
oy: event.clientY - unresistY(now.y),
|
|
204
|
+
samples: [{
|
|
205
|
+
t: event.timeStamp,
|
|
206
|
+
x: event.clientX,
|
|
207
|
+
y: event.clientY
|
|
208
|
+
}]
|
|
209
|
+
};
|
|
210
|
+
try {
|
|
211
|
+
el.setPointerCapture(event.pointerId);
|
|
212
|
+
} catch {}
|
|
213
|
+
el.setAttribute("data-dragging", "");
|
|
214
|
+
}
|
|
215
|
+
function move(event) {
|
|
216
|
+
const state = drag.current;
|
|
217
|
+
if (!state || !interactive) return;
|
|
218
|
+
const x = event.clientX - state.ox;
|
|
219
|
+
const y = resistY(event.clientY - state.oy);
|
|
220
|
+
place(event.currentTarget, x, y);
|
|
221
|
+
lift(clampUnit(Math.hypot(x, y * .5) / LIFT_DISTANCE));
|
|
222
|
+
state.samples.push({
|
|
223
|
+
t: event.timeStamp,
|
|
224
|
+
x: event.clientX,
|
|
225
|
+
y: event.clientY
|
|
226
|
+
});
|
|
227
|
+
if (state.samples.length > 12) state.samples.shift();
|
|
228
|
+
}
|
|
229
|
+
function up(event) {
|
|
230
|
+
const state = drag.current;
|
|
231
|
+
drag.current = null;
|
|
232
|
+
const el = event.currentTarget;
|
|
233
|
+
el.removeAttribute("data-dragging");
|
|
234
|
+
if (el.hasPointerCapture(event.pointerId)) el.releasePointerCapture(event.pointerId);
|
|
235
|
+
if (!state || !interactive) return;
|
|
236
|
+
const velocity = event.type === "pointercancel" ? {
|
|
237
|
+
x: 0,
|
|
238
|
+
y: 0
|
|
239
|
+
} : velocityOf(state.samples, event.timeStamp);
|
|
240
|
+
if (onRelease(id, readOffset(el), velocity, el.offsetWidth)) return;
|
|
241
|
+
el.style.transition = prefersReducedMotion() ? "none" : SPRING_BACK;
|
|
242
|
+
place(el, 0, 0);
|
|
243
|
+
lift(0);
|
|
244
|
+
}
|
|
245
|
+
return /* @__PURE__ */ jsx("div", {
|
|
246
|
+
className: "card-stack-slot",
|
|
247
|
+
style: {
|
|
248
|
+
"--depth": depth,
|
|
249
|
+
zIndex
|
|
250
|
+
},
|
|
251
|
+
"aria-hidden": interactive ? void 0 : true,
|
|
252
|
+
ref: (node) => {
|
|
253
|
+
if (!node) return;
|
|
254
|
+
if (interactive) node.removeAttribute("inert");
|
|
255
|
+
else node.setAttribute("inert", "");
|
|
256
|
+
},
|
|
257
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
258
|
+
ref: card,
|
|
259
|
+
className: "card-stack-card",
|
|
260
|
+
"data-top": interactive ? "" : void 0,
|
|
261
|
+
"data-flying": decision ? "" : void 0,
|
|
262
|
+
role: interactive ? "group" : void 0,
|
|
263
|
+
"aria-label": interactive ? label : void 0,
|
|
264
|
+
onPointerDown: down,
|
|
265
|
+
onPointerMove: move,
|
|
266
|
+
onPointerUp: up,
|
|
267
|
+
onPointerCancel: up,
|
|
268
|
+
onTransitionEnd: (event) => {
|
|
269
|
+
if (decision && event.target === event.currentTarget && event.propertyName === "opacity") gone();
|
|
270
|
+
},
|
|
271
|
+
children: [
|
|
272
|
+
/* @__PURE__ */ jsxs("div", {
|
|
273
|
+
className: "card-stack-face",
|
|
274
|
+
children: [children, /* @__PURE__ */ jsx("span", {
|
|
275
|
+
className: "card-stack-shade",
|
|
276
|
+
"aria-hidden": "true"
|
|
277
|
+
})]
|
|
278
|
+
}),
|
|
279
|
+
/* @__PURE__ */ jsxs("span", {
|
|
280
|
+
className: "card-stack-stamp",
|
|
281
|
+
"data-side": "right",
|
|
282
|
+
"aria-hidden": "true",
|
|
283
|
+
children: [/* @__PURE__ */ jsx(CheckIcon, {}), labels.right]
|
|
284
|
+
}),
|
|
285
|
+
/* @__PURE__ */ jsxs("span", {
|
|
286
|
+
className: "card-stack-stamp",
|
|
287
|
+
"data-side": "left",
|
|
288
|
+
"aria-hidden": "true",
|
|
289
|
+
children: [/* @__PURE__ */ jsx(CloseIcon, {}), labels.left]
|
|
290
|
+
})
|
|
291
|
+
]
|
|
292
|
+
})
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
function CardStack({ items, getKey, getLabel, renderCard, onDecide, onUndo, onReset, labels = {
|
|
296
|
+
left: "Pass",
|
|
297
|
+
right: "Keep"
|
|
298
|
+
}, outcomes, label = "Cards", renderEmpty, className }) {
|
|
299
|
+
const hintId = useId();
|
|
300
|
+
const stage = useRef(null);
|
|
301
|
+
const [position, setPosition] = useState(0);
|
|
302
|
+
const [history, setHistory] = useState([]);
|
|
303
|
+
const [flying, setFlying] = useState([]);
|
|
304
|
+
const [returning, setReturning] = useState({});
|
|
305
|
+
const [message, setMessage] = useState("");
|
|
306
|
+
const exits = useRef({});
|
|
307
|
+
const flings = useRef(/* @__PURE__ */ new Map());
|
|
308
|
+
const top = items[position];
|
|
309
|
+
const remaining = Math.max(0, items.length - position);
|
|
310
|
+
function decide(decision) {
|
|
311
|
+
if (!top) return;
|
|
312
|
+
const key = getKey(top);
|
|
313
|
+
stage.current?.style.setProperty("--lift", "0");
|
|
314
|
+
setPosition(position + 1);
|
|
315
|
+
setHistory([...history, {
|
|
316
|
+
key,
|
|
317
|
+
decision
|
|
318
|
+
}]);
|
|
319
|
+
setFlying((current) => [...current, key]);
|
|
320
|
+
setReturning({});
|
|
321
|
+
const left = remaining - 1;
|
|
322
|
+
setMessage(`${getLabel(top)}${outcomes ? ` ${outcomes[decision]}` : `: ${labels[decision]}`}. ${left ? `${left} left.` : "All cards reviewed."}`);
|
|
323
|
+
onDecide?.(top, decision);
|
|
324
|
+
}
|
|
325
|
+
function undo() {
|
|
326
|
+
const last = history[history.length - 1];
|
|
327
|
+
const item = last && items.find((entry) => getKey(entry) === last.key);
|
|
328
|
+
if (!last || !item) return;
|
|
329
|
+
const exit = exits.current[last.key];
|
|
330
|
+
setPosition(position - 1);
|
|
331
|
+
setHistory(history.slice(0, -1));
|
|
332
|
+
setFlying((current) => current.filter((key) => key !== last.key));
|
|
333
|
+
setReturning(exit ? { [last.key]: {
|
|
334
|
+
...exit,
|
|
335
|
+
delay: 0
|
|
336
|
+
} } : {});
|
|
337
|
+
setMessage(`${getLabel(item)} restored.`);
|
|
338
|
+
onUndo?.(item, last.decision);
|
|
339
|
+
}
|
|
340
|
+
function reset() {
|
|
341
|
+
if (!history.length) return;
|
|
342
|
+
const count = Math.min(VISIBLE, items.length);
|
|
343
|
+
const back = {};
|
|
344
|
+
items.slice(0, count).forEach((item, index) => {
|
|
345
|
+
const key = getKey(item);
|
|
346
|
+
const exit = exits.current[key];
|
|
347
|
+
if (exit && index < position) back[key] = {
|
|
348
|
+
...exit,
|
|
349
|
+
delay: (count - 1 - index) * 60
|
|
350
|
+
};
|
|
351
|
+
});
|
|
352
|
+
setPosition(0);
|
|
353
|
+
setHistory([]);
|
|
354
|
+
setFlying([]);
|
|
355
|
+
setReturning(back);
|
|
356
|
+
setMessage("All cards are back in the stack.");
|
|
357
|
+
onReset?.();
|
|
358
|
+
}
|
|
359
|
+
function release(key, offset, velocity, width) {
|
|
360
|
+
const direction = Math.sign(offset.x);
|
|
361
|
+
if (!direction || !top || getKey(top) !== key) return false;
|
|
362
|
+
const flick = Math.abs(velocity.x) > FLICK && Math.sign(velocity.x) === direction && Math.abs(offset.x) > 12;
|
|
363
|
+
const far = Math.abs(offset.x) > Math.min(width * .35, 140) && !(Math.sign(velocity.x) === -direction && Math.abs(velocity.x) > 300);
|
|
364
|
+
if (!flick && !far) return false;
|
|
365
|
+
flings.current.set(key, velocity);
|
|
366
|
+
decide(direction > 0 ? "right" : "left");
|
|
367
|
+
return true;
|
|
368
|
+
}
|
|
369
|
+
function onKeyDown(event) {
|
|
370
|
+
if (event.target !== event.currentTarget) return;
|
|
371
|
+
if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
|
|
372
|
+
event.preventDefault();
|
|
373
|
+
decide(event.key === "ArrowRight" ? "right" : "left");
|
|
374
|
+
} else if (event.key === "Backspace" || (event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "z") {
|
|
375
|
+
event.preventDefault();
|
|
376
|
+
undo();
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
const decided = new Map(history.map((entry) => [entry.key, entry.decision]));
|
|
380
|
+
const windowKeys = new Set(items.slice(position, position + VISIBLE).map(getKey));
|
|
381
|
+
const rendered = items.filter((item) => windowKeys.has(getKey(item)) || flying.includes(getKey(item)));
|
|
382
|
+
const empty = position >= items.length && flying.length === 0;
|
|
383
|
+
const takeFling = useCallback((key) => {
|
|
384
|
+
const velocity = flings.current.get(key);
|
|
385
|
+
flings.current.delete(key);
|
|
386
|
+
return velocity;
|
|
387
|
+
}, []);
|
|
388
|
+
const recordExit = useCallback((key, exit) => {
|
|
389
|
+
exits.current[key] = exit;
|
|
390
|
+
}, []);
|
|
391
|
+
const finish = useCallback((key) => setFlying((current) => current.filter((entry) => entry !== key)), []);
|
|
392
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
393
|
+
"data-slot": "card-stack",
|
|
394
|
+
className: cn("card-stack", className),
|
|
395
|
+
children: [
|
|
396
|
+
/* @__PURE__ */ jsxs("div", {
|
|
397
|
+
ref: stage,
|
|
398
|
+
className: "card-stack-stage",
|
|
399
|
+
role: "application",
|
|
400
|
+
"aria-roledescription": "card stack",
|
|
401
|
+
"aria-label": label,
|
|
402
|
+
"aria-describedby": hintId,
|
|
403
|
+
tabIndex: 0,
|
|
404
|
+
onKeyDown,
|
|
405
|
+
children: [rendered.map((item) => {
|
|
406
|
+
const id = getKey(item);
|
|
407
|
+
const index = items.indexOf(item);
|
|
408
|
+
const decision = decided.get(id) ?? null;
|
|
409
|
+
const depth = decision ? 0 : index - position;
|
|
410
|
+
return /* @__PURE__ */ jsx(StackCard, {
|
|
411
|
+
id,
|
|
412
|
+
depth,
|
|
413
|
+
decision,
|
|
414
|
+
returnFrom: returning[id],
|
|
415
|
+
interactive: !decision && depth === 0,
|
|
416
|
+
zIndex: decision ? 20 + flying.indexOf(id) : VISIBLE - depth,
|
|
417
|
+
label: `${getLabel(item)}, ${index + 1} of ${items.length}`,
|
|
418
|
+
labels,
|
|
419
|
+
stage,
|
|
420
|
+
fling: takeFling,
|
|
421
|
+
onRelease: release,
|
|
422
|
+
onThrown: recordExit,
|
|
423
|
+
onGone: finish,
|
|
424
|
+
children: renderCard(item)
|
|
425
|
+
}, id);
|
|
426
|
+
}), empty ? /* @__PURE__ */ jsx("div", {
|
|
427
|
+
className: "card-stack-empty",
|
|
428
|
+
children: renderEmpty ? /* @__PURE__ */ jsx(EmptySlot, {
|
|
429
|
+
render: renderEmpty,
|
|
430
|
+
onReset: reset
|
|
431
|
+
}) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("p", {
|
|
432
|
+
className: "m-0 text-base font-medium",
|
|
433
|
+
children: "All cards reviewed"
|
|
434
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
435
|
+
variant: "outline",
|
|
436
|
+
onPress: reset,
|
|
437
|
+
startIcon: /* @__PURE__ */ jsx(UndoIcon, {}),
|
|
438
|
+
children: "Start over"
|
|
439
|
+
})] })
|
|
440
|
+
}) : null]
|
|
441
|
+
}),
|
|
442
|
+
/* @__PURE__ */ jsxs("div", {
|
|
443
|
+
className: "flex flex-wrap justify-center gap-2",
|
|
444
|
+
children: [
|
|
445
|
+
/* @__PURE__ */ jsx(Control, {
|
|
446
|
+
variant: "outline",
|
|
447
|
+
disabled: !top,
|
|
448
|
+
onPress: () => decide("left"),
|
|
449
|
+
startIcon: /* @__PURE__ */ jsx(CloseIcon, {}),
|
|
450
|
+
children: labels.left
|
|
451
|
+
}),
|
|
452
|
+
/* @__PURE__ */ jsx(Control, {
|
|
453
|
+
variant: "ghost",
|
|
454
|
+
disabled: !history.length,
|
|
455
|
+
onPress: undo,
|
|
456
|
+
startIcon: /* @__PURE__ */ jsx(UndoIcon, {}),
|
|
457
|
+
children: "Undo"
|
|
458
|
+
}),
|
|
459
|
+
/* @__PURE__ */ jsx(Control, {
|
|
460
|
+
variant: "primary",
|
|
461
|
+
disabled: !top,
|
|
462
|
+
onPress: () => decide("right"),
|
|
463
|
+
startIcon: /* @__PURE__ */ jsx(CheckIcon, {}),
|
|
464
|
+
children: labels.right
|
|
465
|
+
})
|
|
466
|
+
]
|
|
467
|
+
}),
|
|
468
|
+
/* @__PURE__ */ jsxs("p", {
|
|
469
|
+
id: hintId,
|
|
470
|
+
className: "sr-only",
|
|
471
|
+
children: [
|
|
472
|
+
"Drag the top card, or use the left and right arrow keys to ",
|
|
473
|
+
labels.left.toLowerCase(),
|
|
474
|
+
" or",
|
|
475
|
+
" ",
|
|
476
|
+
labels.right.toLowerCase(),
|
|
477
|
+
" it. Backspace undoes the last decision."
|
|
478
|
+
]
|
|
479
|
+
}),
|
|
480
|
+
/* @__PURE__ */ jsx("p", {
|
|
481
|
+
className: "sr-only",
|
|
482
|
+
role: "status",
|
|
483
|
+
"aria-live": "polite",
|
|
484
|
+
children: message
|
|
485
|
+
})
|
|
486
|
+
]
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
//#endregion
|
|
490
|
+
export { CardStack };
|
|
491
|
+
|
|
492
|
+
//# sourceMappingURL=card-stack.js.map
|