@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":"onboarding-checklist.js","names":[],"sources":["../../src/onboarding-checklist/onboarding-checklist.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n forwardRef,\n useEffect,\n useId,\n useMemo,\n useReducer,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type ReactNode,\n} from \"react\";\n\nimport { ActionButton } from \"../action-button/action-button.js\";\nimport { cn } from \"../lib/cn.js\";\nimport { RollingNumber } from \"../lib/field-message.js\";\nimport { mergeRefs } from \"../lib/merge-refs.js\";\nimport { SwapText } from \"../lib/swap-text.js\";\n\n/**\n * OnboardingChecklist: a getting-started card for a new account or workspace,\n * for a short, one-time setup of three to eight loosely ordered steps. (Use a\n * Stepper when the order is strict and steps map to screens.)\n *\n * The progress ring and the count follow every check: the ring fills on the\n * morph spring, the count rolls its digits, and at 100% a tick draws in the\n * ring while the title morphs to `doneTitle`. A checked step fills its circle\n * from the centre, draws its tick and strikes its title through; 720ms later it\n * folds into a \"N completed\" row that opens again, and the next unfinished step\n * opens and takes focus if the finished one had it. A step with an `actionLabel`\n * runs `onAction`: resolving checks the step, throwing an Error keeps it open\n * and shows the message. The body can be hidden and shown again.\n *\n * Rows and panels open and close their height on a spring that never\n * overshoots, closing a little quicker. Nothing animates on first render, and\n * reduced motion removes the height animation and keeps short fades.\n *\n * Built on plain buttons and the shared swap and rolling-number helpers; the\n * action is the library's ActionButton, whose arrow becomes a spinner and then\n * a tick that draws itself. Keyboard: Up and Down walk the step titles,\n * Home and End jump to the first and last, Enter or Space expands a step,\n * toggles its checkbox or runs its action.\n */\nexport interface OnboardingStep {\n id: string;\n title: string;\n description?: string;\n /** Label of the button that does the step. Without it, the step is checked off by hand. */\n actionLabel?: string;\n /** Runs the step. Resolve to check it off; throw an Error to keep it open and show the error's message. */\n onAction?: () => void | Promise<void>;\n}\n\nexport interface OnboardingChecklistProps {\n /** Card title while steps remain. */\n title: string;\n /** Title once every step is done. @default \"You’re all set\" */\n doneTitle?: string;\n /** Steps in order. */\n steps: OnboardingStep[];\n /** Step ids that start completed. */\n defaultCompleted?: string[];\n /** Called with the completed ids, in step order, whenever they change. */\n onCompletedChange?: (completed: string[]) => void;\n /** Starts with the body collapsed. @default false */\n defaultHidden?: boolean;\n /** Called when the Hide or Show button is used. */\n onHiddenChange?: (hidden: boolean) => void;\n /** Extra classes for the card. Merged last. */\n className?: string;\n}\n\ninterface State {\n done: string[];\n settled: string[];\n expanded: string | null;\n errors: Record<string, string>;\n groupOpen: boolean;\n hidden: boolean;\n message: string;\n}\ntype Action =\n | { type: \"check\" | \"uncheck\" | \"settle\" | \"expand\" | \"start\"; id: string; steps: OnboardingStep[] }\n | { type: \"fail\"; id: string; message: string }\n | { type: \"group\" | \"hide\" };\n\n/** How long a checked step stays in place, struck through, before it folds into the completed row. */\nconst SETTLE_MS = 720;\n\nconst ordered = (ids: string[], steps: OnboardingStep[]) =>\n steps.map((step) => step.id).filter((id) => ids.includes(id));\nconst without = (ids: string[], id: string) => ids.filter((item) => item !== id);\nconst omit = (errors: Record<string, string>, id: string) =>\n Object.fromEntries(Object.entries(errors).filter(([key]) => key !== id));\nconst titleOf = (steps: OnboardingStep[], id: string) =>\n steps.find((step) => step.id === id)?.title ?? \"Step\";\n\nfunction init({\n steps,\n completed,\n hidden,\n}: {\n steps: OnboardingStep[];\n completed: string[];\n hidden: boolean;\n}): State {\n const done = ordered(completed, steps);\n return {\n done,\n settled: done,\n expanded: steps.find((step) => !done.includes(step.id))?.id ?? null,\n errors: {},\n groupOpen: false,\n hidden,\n message: \"\",\n };\n}\n\nfunction reducer(state: State, action: Action): State {\n switch (action.type) {\n case \"check\": {\n if (state.done.includes(action.id)) return state;\n const done = ordered([...state.done, action.id], action.steps);\n const total = action.steps.length;\n return {\n ...state,\n done,\n errors: omit(state.errors, action.id),\n message:\n done.length === total\n ? `All ${total} steps done.`\n : `${titleOf(action.steps, action.id)} done. ${done.length} of ${total} complete.`,\n };\n }\n case \"uncheck\": {\n if (!state.done.includes(action.id)) return state;\n const done = without(state.done, action.id);\n return {\n ...state,\n done,\n settled: without(state.settled, action.id),\n expanded: state.expanded ?? action.id,\n message: `${titleOf(action.steps, action.id)} marked as not done. ${done.length} of ${action.steps.length} complete.`,\n };\n }\n case \"settle\": {\n if (!state.done.includes(action.id) || state.settled.includes(action.id)) return state;\n let expanded = state.expanded;\n // The step that just finished hands the open panel to the next unfinished step, wrapping to the top.\n if (expanded === action.id) {\n const order = action.steps.map((step) => step.id);\n const start = order.indexOf(action.id);\n expanded =\n order\n .map((_, offset) => order[(start + offset + 1) % order.length]!)\n .find((id) => !state.done.includes(id)) ?? null;\n }\n return { ...state, settled: ordered([...state.settled, action.id], action.steps), expanded };\n }\n case \"expand\":\n return { ...state, expanded: state.expanded === action.id ? null : action.id };\n case \"start\":\n return { ...state, errors: omit(state.errors, action.id) };\n case \"fail\":\n return {\n ...state,\n errors: { ...state.errors, [action.id]: action.message },\n message: action.message,\n };\n case \"group\":\n return { ...state, groupOpen: !state.groupOpen };\n case \"hide\":\n return { ...state, hidden: !state.hidden };\n }\n}\n\nconst Chevron = () => (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.75}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"m18 15-6-6-6 6\" />\n </svg>\n);\n\n/**\n * A box that opens and closes its height (a grid track going between 0fr and 1fr).\n * Closed, it is visibility: hidden once folded, so it leaves the tab order.\n */\nfunction Collapse({ show, children }: { show: boolean; children: ReactNode }) {\n return (\n <div data-shown={show || undefined} className=\"checklist-collapse\">\n <div>{children}</div>\n </div>\n );\n}\n\n/** Every label the slot can show sits invisibly underneath, so a swap never changes the slot's size. */\nfunction SwapLabel({ text, options }: { text: string; options: string[] }) {\n return (\n <span className=\"checklist-swap\" aria-hidden=\"true\">\n {options.map((option, index) => (\n <span key={index} className=\"checklist-swap-sizer\">\n {option}\n </span>\n ))}\n <SwapText swapKey={text} motion=\"rise\" className=\"checklist-swap-item\">\n {text}\n </SwapText>\n </span>\n );\n}\n\n/** The ring's stroke fills on a spring as steps are checked; once every step is done a tick draws in its center. */\nfunction ProgressRing({ done, total }: { done: number; total: number }) {\n const ratio = total ? done / total : 0;\n const complete = total > 0 && done === total;\n return (\n <span\n className=\"checklist-ring\"\n role=\"progressbar\"\n aria-label=\"Setup progress\"\n aria-valuemin={0}\n aria-valuemax={total}\n aria-valuenow={done}\n aria-valuetext={`${done} of ${total} steps done`}\n >\n <svg viewBox=\"0 0 40 40\" fill=\"none\" aria-hidden=\"true\">\n <circle className=\"checklist-ring-track\" cx=\"20\" cy=\"20\" r=\"17\" strokeWidth={3} />\n <g transform=\"rotate(-90 20 20)\">\n <circle\n className=\"checklist-ring-fill\"\n cx=\"20\"\n cy=\"20\"\n r=\"17\"\n strokeWidth={3}\n strokeLinecap=\"round\"\n pathLength={1}\n data-started={ratio > 0 ? \"\" : undefined}\n style={{ \"--ratio\": ratio } as CSSProperties}\n />\n </g>\n </svg>\n <span className=\"checklist-ring-tick\" aria-hidden=\"true\">\n <SwapText swapKey={complete ? \"tick\" : \"\"} motion=\"glyph\" className=\"grid place-items-center\">\n {complete ? (\n <svg viewBox=\"0 0 40 40\" fill=\"none\">\n <path\n className=\"checklist-draw\"\n pathLength={1}\n d=\"M13.5 20.5 18 25l8.5-9.5\"\n stroke=\"currentColor\"\n strokeWidth={2.25}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n ) : null}\n </SwapText>\n </span>\n </span>\n );\n}\n\n/** The fill grows from the center while the tick draws from its short stroke; unchecking retracts both quickly. */\nfunction CheckButton({\n checked,\n labelledBy,\n onToggle,\n}: {\n checked: boolean;\n labelledBy: string;\n onToggle: () => void;\n}) {\n return (\n <button\n type=\"button\"\n role=\"checkbox\"\n aria-checked={checked}\n aria-labelledby={labelledBy}\n className=\"checklist-check\"\n data-check=\"\"\n onClick={onToggle}\n >\n <span className=\"checklist-check-visual\" aria-hidden=\"true\">\n <span className=\"checklist-check-fill\" />\n <svg className=\"checklist-check-mark\" viewBox=\"0 0 22 22\" fill=\"none\">\n <path\n pathLength={1}\n d=\"M6.75 11.25 9.75 14.25 15.25 8.25\"\n stroke=\"currentColor\"\n strokeWidth={1.75}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </span>\n </button>\n );\n}\n\ninterface StepItemProps {\n step: OnboardingStep;\n baseId: string;\n done: boolean;\n settled: boolean;\n expanded: boolean;\n error: string | undefined;\n onToggle: () => void;\n onExpand: () => void;\n onRun: () => Promise<void>;\n}\n\nfunction StepItem({\n step,\n baseId,\n done,\n settled,\n expanded,\n error,\n onToggle,\n onExpand,\n onRun,\n}: StepItemProps) {\n const titleId = `${baseId}-${step.id}-title`;\n const panelId = `${baseId}-${step.id}-panel`;\n // The message stays while its slot folds away.\n const [lastError, setLastError] = useState(error);\n if (error && error !== lastError) setLastError(error);\n return (\n <li\n data-step={step.id}\n data-done={done || undefined}\n data-current={expanded || undefined}\n data-open={settled ? undefined : \"\"}\n >\n <Collapse show={!settled}>\n <div className=\"checklist-step-inner\">\n <CheckButton checked={done} labelledBy={titleId} onToggle={onToggle} />\n <div className=\"checklist-step-main\">\n <button\n type=\"button\"\n className=\"checklist-step-title\"\n data-title=\"\"\n aria-expanded={expanded}\n aria-controls={panelId}\n onClick={onExpand}\n >\n <span id={titleId} className=\"checklist-title-text\">\n {step.title}\n </span>\n </button>\n <Collapse show={expanded}>\n <div id={panelId} role=\"region\" aria-labelledby={titleId} className=\"checklist-panel-inner\">\n {step.description ? <p className=\"checklist-description\">{step.description}</p> : null}\n <Collapse show={Boolean(error)}>\n <p role=\"alert\" className=\"checklist-error\">\n {lastError}\n </p>\n </Collapse>\n {step.actionLabel ? (\n // The label stays put through the whole action: only the icon beside it changes.\n <ActionButton\n variant=\"primary\"\n size=\"sm\"\n className=\"mt-3\"\n data-primary=\"\"\n pendingLabel={step.actionLabel}\n successLabel={step.actionLabel}\n onAction={onRun}\n >\n {step.actionLabel}\n </ActionButton>\n ) : null}\n </div>\n </Collapse>\n </div>\n </div>\n </Collapse>\n </li>\n );\n}\n\nexport const OnboardingChecklist = forwardRef<HTMLElement, OnboardingChecklistProps>(\n function OnboardingChecklist(\n {\n title,\n doneTitle = \"You’re all set\",\n steps,\n defaultCompleted = [],\n onCompletedChange,\n defaultHidden = false,\n onHiddenChange,\n className,\n },\n ref,\n ) {\n const baseId = useId();\n const [state, dispatch] = useReducer(\n reducer,\n { steps, completed: defaultCompleted, hidden: defaultHidden },\n init,\n );\n const root = useRef<HTMLElement | null>(null);\n const refs = useMemo(() => mergeRefs(ref, root), [ref]);\n const timers = useRef(new Map<string, ReturnType<typeof setTimeout>>());\n const focusRequest = useRef<\"next\" | { id: string } | null>(null);\n const reportCompleted = useRef(onCompletedChange);\n const reported = useRef(state.done);\n\n useEffect(() => {\n reportCompleted.current = onCompletedChange;\n });\n useEffect(() => {\n if (reported.current === state.done) return;\n reported.current = state.done;\n reportCompleted.current?.(state.done);\n }, [state.done]);\n useEffect(() => {\n const pending = timers.current;\n return () => pending.forEach(clearTimeout);\n }, []);\n // Focus moves after the commit that opens its target: the next step's action, or the step reopened from the completed row.\n useEffect(() => {\n const request = focusRequest.current;\n const node = root.current;\n if (!request || !node) return;\n focusRequest.current = null;\n let target: HTMLElement | null;\n if (request === \"next\") {\n const next = state.expanded\n ? node.querySelector<HTMLElement>(`[data-step=\"${state.expanded}\"][data-open]`)\n : null;\n target =\n next?.querySelector<HTMLElement>(\"[data-primary]\") ??\n next?.querySelector<HTMLElement>(\"[data-title]\") ??\n node.querySelector<HTMLElement>(\"[data-group-toggle]\");\n } else {\n target = node.querySelector<HTMLElement>(`[data-step=\"${request.id}\"][data-open] [data-check]`);\n }\n target?.focus({ preventScroll: true });\n });\n\n function check(id: string) {\n dispatch({ type: \"check\", id, steps });\n if (timers.current.has(id)) return;\n timers.current.set(\n id,\n setTimeout(() => {\n timers.current.delete(id);\n if (root.current?.querySelector(`[data-step=\"${id}\"]`)?.contains(document.activeElement))\n focusRequest.current = \"next\";\n dispatch({ type: \"settle\", id, steps });\n }, SETTLE_MS),\n );\n }\n\n function uncheck(id: string, fromGroup: boolean) {\n clearTimeout(timers.current.get(id));\n timers.current.delete(id);\n if (fromGroup) focusRequest.current = { id };\n dispatch({ type: \"uncheck\", id, steps });\n }\n\n async function run(step: OnboardingStep) {\n if (!step.onAction || state.done.includes(step.id)) return;\n dispatch({ type: \"start\", id: step.id, steps });\n try {\n await step.onAction();\n } catch (error) {\n dispatch({\n type: \"fail\",\n id: step.id,\n message:\n error instanceof Error && error.message ? error.message : \"That didn’t work. Try again.\",\n });\n // The button goes back to rest on a rejection.\n throw error;\n }\n check(step.id);\n }\n\n function toggleHidden() {\n dispatch({ type: \"hide\" });\n onHiddenChange?.(!state.hidden);\n }\n\n /** Up and Down walk the step titles, Home and End jump to the first and last. */\n function navigate(event: KeyboardEvent<HTMLUListElement>) {\n const target = event.target as HTMLElement;\n if (!target.matches(\"[data-title]\") || ![\"ArrowDown\", \"ArrowUp\", \"Home\", \"End\"].includes(event.key))\n return;\n const titles = Array.from(\n event.currentTarget.querySelectorAll<HTMLElement>(\"li[data-open] [data-title]\"),\n );\n const index = titles.indexOf(target);\n const next =\n event.key === \"Home\"\n ? 0\n : event.key === \"End\"\n ? titles.length - 1\n : (index + (event.key === \"ArrowDown\" ? 1 : -1) + titles.length) % titles.length;\n event.preventDefault();\n titles[next]?.focus();\n }\n\n const total = steps.length;\n const doneCount = state.done.length;\n const allDone = total > 0 && doneCount === total;\n const completed = steps.filter((step) => state.settled.includes(step.id));\n const titleId = `${baseId}-title`;\n const bodyId = `${baseId}-body`;\n const groupId = `${baseId}-completed`;\n\n return (\n <section\n ref={refs}\n aria-labelledby={titleId}\n data-slot=\"onboarding-checklist\"\n data-complete={allDone || undefined}\n data-hidden={state.hidden || undefined}\n className={cn(\"checklist box-border font-sans\", className)}\n >\n <div className=\"checklist-header\">\n <ProgressRing done={doneCount} total={total} />\n <div className=\"checklist-heading\">\n <h3 id={titleId} className=\"checklist-title\">\n <span className=\"sr-only\">{allDone ? doneTitle : title}</span>\n <SwapLabel text={allDone ? doneTitle : title} options={[title, doneTitle]} />\n </h3>\n <p className=\"checklist-count\">\n <span className=\"sr-only\">\n {doneCount} of {total} done\n </span>\n <span className=\"checklist-count-visual\" aria-hidden=\"true\">\n <RollingNumber word={String(doneCount)} />\n of {total} done\n </span>\n </p>\n </div>\n <button\n type=\"button\"\n className=\"checklist-hide\"\n aria-expanded={!state.hidden}\n aria-controls={bodyId}\n onClick={toggleHidden}\n >\n <span className=\"checklist-hide-label\">\n <SwapLabel text={state.hidden ? \"Show\" : \"Hide\"} options={[\"Hide\", \"Show\"]} />\n </span>\n <span className=\"sr-only\">{state.hidden ? \"Show\" : \"Hide\"} checklist</span>\n <span className=\"checklist-chevron\" aria-hidden=\"true\" data-flipped={state.hidden || undefined}>\n <Chevron />\n </span>\n </button>\n </div>\n <div id={bodyId} data-shown={state.hidden ? undefined : \"\"} className=\"checklist-collapse\">\n <div>\n <div className=\"checklist-body-inner\">\n <ul\n className=\"checklist-list\"\n aria-label=\"Steps to do\"\n aria-hidden={completed.length === total ? true : undefined}\n onKeyDown={navigate}\n >\n {steps.map((step) => (\n <StepItem\n key={step.id}\n step={step}\n baseId={baseId}\n done={state.done.includes(step.id)}\n settled={state.settled.includes(step.id)}\n expanded={state.expanded === step.id}\n error={state.errors[step.id]}\n onToggle={() =>\n state.done.includes(step.id) ? uncheck(step.id, false) : check(step.id)\n }\n onExpand={() => dispatch({ type: \"expand\", id: step.id, steps })}\n onRun={() => run(step)}\n />\n ))}\n </ul>\n <Collapse show={completed.length > 0}>\n <button\n type=\"button\"\n className=\"checklist-group-toggle\"\n data-group-toggle=\"\"\n aria-expanded={state.groupOpen}\n aria-controls={groupId}\n onClick={() => dispatch({ type: \"group\" })}\n >\n <span className=\"sr-only\">{completed.length} completed</span>\n <span className=\"checklist-count-visual\" aria-hidden=\"true\">\n <RollingNumber word={String(completed.length)} />\n completed\n </span>\n <span\n className=\"checklist-chevron\"\n aria-hidden=\"true\"\n data-flipped={state.groupOpen ? undefined : \"\"}\n >\n <Chevron />\n </span>\n </button>\n <Collapse show={state.groupOpen}>\n <div id={groupId}>\n <ul className=\"checklist-list\" aria-label=\"Completed steps\">\n {steps.map((step) => {\n const doneId = `${baseId}-${step.id}-done`;\n return (\n <li key={step.id} data-completed-step={step.id} data-done=\"\">\n <Collapse show={state.settled.includes(step.id)}>\n <div className=\"checklist-step-inner\">\n <CheckButton checked labelledBy={doneId} onToggle={() => uncheck(step.id, true)} />\n <span className=\"checklist-done-title\">\n <span id={doneId} className=\"checklist-title-text\">\n {step.title}\n </span>\n </span>\n </div>\n </Collapse>\n </li>\n );\n })}\n </ul>\n </div>\n </Collapse>\n </Collapse>\n </div>\n </div>\n </div>\n <span className=\"sr-only\" role=\"status\">\n {state.message}\n </span>\n </section>\n );\n },\n);\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { PageHeader, PageHeaderProps, pageHeaderActionsVariants, pageHeaderBackVariants, pageHeaderDescriptionVariants, pageHeaderMetaVariants, pageHeaderRowVariants, pageHeaderTitleVariants, pageHeaderVariants } from "./page-header.js";
|
|
2
|
+
export { PageHeader, type PageHeaderProps, pageHeaderActionsVariants, pageHeaderBackVariants, pageHeaderDescriptionVariants, pageHeaderMetaVariants, pageHeaderRowVariants, pageHeaderTitleVariants, pageHeaderVariants };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { PageHeader, pageHeaderActionsVariants, pageHeaderBackVariants, pageHeaderDescriptionVariants, pageHeaderMetaVariants, pageHeaderRowVariants, pageHeaderTitleVariants, pageHeaderVariants } from "./page-header.js";
|
|
2
|
+
export { PageHeader, pageHeaderActionsVariants, pageHeaderBackVariants, pageHeaderDescriptionVariants, pageHeaderMetaVariants, pageHeaderRowVariants, pageHeaderTitleVariants, pageHeaderVariants };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { ComponentPropsWithoutRef, ReactNode } from "react";
|
|
2
|
+
//#region src/page-header/page-header.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* PageHeader: the top of a page. One title, an optional line saying what the
|
|
5
|
+
* page is for, the page's own actions, a short piece of metadata and an
|
|
6
|
+
* optional way back.
|
|
7
|
+
*
|
|
8
|
+
* Presentational, so there is no React Aria base. It exists because a page
|
|
9
|
+
* title is the one element every screen has, and without a shared component
|
|
10
|
+
* each screen picks its own size, weight, spacing and action placement, so the
|
|
11
|
+
* title moves as a person moves between pages.
|
|
12
|
+
*
|
|
13
|
+
* The title renders the page's single `<h1>`. A page has one, and putting it
|
|
14
|
+
* here means a consumer cannot render two by accident.
|
|
15
|
+
*
|
|
16
|
+
* Every string in the cva blocks below is a STATIC literal. Tailwind scans
|
|
17
|
+
* source text, so a class assembled at runtime is invisible to it and would
|
|
18
|
+
* simply never be emitted.
|
|
19
|
+
*/
|
|
20
|
+
export declare const pageHeaderVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
21
|
+
/**
|
|
22
|
+
* Title block and actions share one row. `items-start` keeps the actions level
|
|
23
|
+
* with the title when a description wraps under it; `flex-wrap` moves the
|
|
24
|
+
* actions below the title on a narrow screen instead of squeezing it.
|
|
25
|
+
*/
|
|
26
|
+
export declare const pageHeaderRowVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
27
|
+
export declare const pageHeaderTitleVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
28
|
+
export declare const pageHeaderMetaVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
29
|
+
/**
|
|
30
|
+
* Capped at the md breakpoint (48rem), a readable measure for a sentence or
|
|
31
|
+
* two. The scale defines no container size between `max` and nothing, and a
|
|
32
|
+
* bracket length is rejected by check:hardcoding, so the token is referenced.
|
|
33
|
+
*/
|
|
34
|
+
export declare const pageHeaderDescriptionVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
35
|
+
export declare const pageHeaderActionsVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
36
|
+
export declare const pageHeaderBackVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
|
|
37
|
+
/**
|
|
38
|
+
* The header at the top of a page.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* <PageHeader
|
|
42
|
+
* title="Projects"
|
|
43
|
+
* description="Everything your team is working on."
|
|
44
|
+
* meta="updated 14 Oct 2026"
|
|
45
|
+
* actions={<Button>New project</Button>}
|
|
46
|
+
* />
|
|
47
|
+
*/
|
|
48
|
+
export interface PageHeaderProps extends Omit<ComponentPropsWithoutRef<"header">, "title"> {
|
|
49
|
+
/** The page's title. Rendered as the page's single `<h1>`. */
|
|
50
|
+
title: ReactNode;
|
|
51
|
+
/**
|
|
52
|
+
* One or two sentences under the title saying what the page is for.
|
|
53
|
+
* Muted, and capped at a readable measure.
|
|
54
|
+
*/
|
|
55
|
+
description?: ReactNode;
|
|
56
|
+
/**
|
|
57
|
+
* The page's primary actions, right-aligned on the title row. They wrap
|
|
58
|
+
* below the title on a narrow screen. Pass buttons or links; the header
|
|
59
|
+
* spaces them and does not style them.
|
|
60
|
+
*/
|
|
61
|
+
actions?: ReactNode;
|
|
62
|
+
/**
|
|
63
|
+
* A short piece of context inline after the title, on the same baseline:
|
|
64
|
+
* a date the figures are as of, a status chip, a count.
|
|
65
|
+
*/
|
|
66
|
+
meta?: ReactNode;
|
|
67
|
+
/**
|
|
68
|
+
* A slot above the title for a way back, on a detail page. Supply the link
|
|
69
|
+
* yourself so it uses your router; the header sizes and colours the slot.
|
|
70
|
+
*/
|
|
71
|
+
back?: ReactNode;
|
|
72
|
+
}
|
|
73
|
+
export declare const PageHeader: import("react").ForwardRefExoticComponent<PageHeaderProps & import("react").RefAttributes<HTMLElement>>;
|
|
74
|
+
//#endregion
|
|
75
|
+
//# sourceMappingURL=page-header.d.ts.map
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { cva } from "class-variance-authority";
|
|
4
|
+
import { forwardRef } from "react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
//#region src/page-header/page-header.tsx
|
|
7
|
+
/**
|
|
8
|
+
* PageHeader: the top of a page. One title, an optional line saying what the
|
|
9
|
+
* page is for, the page's own actions, a short piece of metadata and an
|
|
10
|
+
* optional way back.
|
|
11
|
+
*
|
|
12
|
+
* Presentational, so there is no React Aria base. It exists because a page
|
|
13
|
+
* title is the one element every screen has, and without a shared component
|
|
14
|
+
* each screen picks its own size, weight, spacing and action placement, so the
|
|
15
|
+
* title moves as a person moves between pages.
|
|
16
|
+
*
|
|
17
|
+
* The title renders the page's single `<h1>`. A page has one, and putting it
|
|
18
|
+
* here means a consumer cannot render two by accident.
|
|
19
|
+
*
|
|
20
|
+
* Every string in the cva blocks below is a STATIC literal. Tailwind scans
|
|
21
|
+
* source text, so a class assembled at runtime is invisible to it and would
|
|
22
|
+
* simply never be emitted.
|
|
23
|
+
*/
|
|
24
|
+
const pageHeaderVariants = cva(["mb-6 block", "box-border font-sans text-foreground"]);
|
|
25
|
+
/**
|
|
26
|
+
* Title block and actions share one row. `items-start` keeps the actions level
|
|
27
|
+
* with the title when a description wraps under it; `flex-wrap` moves the
|
|
28
|
+
* actions below the title on a narrow screen instead of squeezing it.
|
|
29
|
+
*/
|
|
30
|
+
const pageHeaderRowVariants = cva("flex flex-wrap items-start justify-between gap-3");
|
|
31
|
+
const pageHeaderTitleVariants = cva(["font-display text-h3 leading-(--leading-snug) font-semibold", "m-0"]);
|
|
32
|
+
const pageHeaderMetaVariants = cva("text-xs leading-(--leading-normal) text-muted-foreground");
|
|
33
|
+
/**
|
|
34
|
+
* Capped at the md breakpoint (48rem), a readable measure for a sentence or
|
|
35
|
+
* two. The scale defines no container size between `max` and nothing, and a
|
|
36
|
+
* bracket length is rejected by check:hardcoding, so the token is referenced.
|
|
37
|
+
*/
|
|
38
|
+
const pageHeaderDescriptionVariants = cva(["mt-1 mb-0 max-w-(--breakpoint-md)", "text-sm leading-(--leading-normal) text-muted-foreground"]);
|
|
39
|
+
const pageHeaderActionsVariants = cva("flex shrink-0 flex-wrap items-center gap-2");
|
|
40
|
+
const pageHeaderBackVariants = cva("mb-2 text-xs leading-(--leading-normal) text-muted-foreground");
|
|
41
|
+
const PageHeader = forwardRef(function PageHeader({ className, title, description, actions, meta, back, ...props }, ref) {
|
|
42
|
+
return /* @__PURE__ */ jsxs("header", {
|
|
43
|
+
ref,
|
|
44
|
+
...props,
|
|
45
|
+
"data-slot": "page-header",
|
|
46
|
+
className: cn(pageHeaderVariants(), className),
|
|
47
|
+
children: [back === void 0 ? null : /* @__PURE__ */ jsx("div", {
|
|
48
|
+
"data-slot": "page-header-back",
|
|
49
|
+
className: pageHeaderBackVariants(),
|
|
50
|
+
children: back
|
|
51
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
52
|
+
"data-slot": "page-header-row",
|
|
53
|
+
className: pageHeaderRowVariants(),
|
|
54
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
55
|
+
className: "min-w-0 grow basis-64",
|
|
56
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
57
|
+
className: "flex flex-wrap items-baseline gap-x-3 gap-y-1",
|
|
58
|
+
children: [/* @__PURE__ */ jsx("h1", {
|
|
59
|
+
"data-slot": "page-header-title",
|
|
60
|
+
className: pageHeaderTitleVariants(),
|
|
61
|
+
children: title
|
|
62
|
+
}), meta === void 0 ? null : /* @__PURE__ */ jsx("div", {
|
|
63
|
+
"data-slot": "page-header-meta",
|
|
64
|
+
className: pageHeaderMetaVariants(),
|
|
65
|
+
children: meta
|
|
66
|
+
})]
|
|
67
|
+
}), description === void 0 ? null : /* @__PURE__ */ jsx("p", {
|
|
68
|
+
"data-slot": "page-header-description",
|
|
69
|
+
className: pageHeaderDescriptionVariants(),
|
|
70
|
+
children: description
|
|
71
|
+
})]
|
|
72
|
+
}), actions === void 0 ? null : /* @__PURE__ */ jsx("div", {
|
|
73
|
+
"data-slot": "page-header-actions",
|
|
74
|
+
className: pageHeaderActionsVariants(),
|
|
75
|
+
children: actions
|
|
76
|
+
})]
|
|
77
|
+
})]
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
//#endregion
|
|
81
|
+
export { PageHeader, pageHeaderActionsVariants, pageHeaderBackVariants, pageHeaderDescriptionVariants, pageHeaderMetaVariants, pageHeaderRowVariants, pageHeaderTitleVariants, pageHeaderVariants };
|
|
82
|
+
|
|
83
|
+
//# sourceMappingURL=page-header.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-header.js","names":[],"sources":["../../src/page-header/page-header.tsx"],"sourcesContent":["\"use client\";\n\nimport { cva } from \"class-variance-authority\";\nimport { forwardRef, type ComponentPropsWithoutRef, type ReactNode } from \"react\";\n\nimport { cn } from \"../lib/cn.js\";\n\n/**\n * PageHeader: the top of a page. One title, an optional line saying what the\n * page is for, the page's own actions, a short piece of metadata and an\n * optional way back.\n *\n * Presentational, so there is no React Aria base. It exists because a page\n * title is the one element every screen has, and without a shared component\n * each screen picks its own size, weight, spacing and action placement, so the\n * title moves as a person moves between pages.\n *\n * The title renders the page's single `<h1>`. A page has one, and putting it\n * here means a consumer cannot render two by accident.\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 pageHeaderVariants = cva([\n \"mb-6 block\",\n // box-border and font-sans are not boilerplate: the reset in\n // @seekalfred/styles is opt-in, so a consumer may load none, and an\n // unstyled document renders text in a serif.\n \"box-border font-sans text-foreground\",\n]);\n\n/**\n * Title block and actions share one row. `items-start` keeps the actions level\n * with the title when a description wraps under it; `flex-wrap` moves the\n * actions below the title on a narrow screen instead of squeezing it.\n */\nexport const pageHeaderRowVariants = cva(\"flex flex-wrap items-start justify-between gap-3\");\n\nexport const pageHeaderTitleVariants = 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 \"font-display text-h3 leading-(--leading-snug) font-semibold\",\n // The user-agent <h1> ships a 0.67em block margin and font-size 2em.\n \"m-0\",\n]);\n\nexport const pageHeaderMetaVariants = cva(\n \"text-xs leading-(--leading-normal) text-muted-foreground\",\n);\n\n/**\n * Capped at the md breakpoint (48rem), a readable measure for a sentence or\n * two. The scale defines no container size between `max` and nothing, and a\n * bracket length is rejected by check:hardcoding, so the token is referenced.\n */\nexport const pageHeaderDescriptionVariants = cva([\n \"mt-1 mb-0 max-w-(--breakpoint-md)\",\n \"text-sm leading-(--leading-normal) text-muted-foreground\",\n]);\n\nexport const pageHeaderActionsVariants = cva(\"flex shrink-0 flex-wrap items-center gap-2\");\n\nexport const pageHeaderBackVariants = cva(\n \"mb-2 text-xs leading-(--leading-normal) text-muted-foreground\",\n);\n\n/**\n * The header at the top of a page.\n *\n * @example\n * <PageHeader\n * title=\"Projects\"\n * description=\"Everything your team is working on.\"\n * meta=\"updated 14 Oct 2026\"\n * actions={<Button>New project</Button>}\n * />\n */\nexport interface PageHeaderProps\n // The native `title` attribute is omitted so this component can use the\n // name for its heading. A tooltip on a page header is not keyboard\n // reachable, and silently shadowing it with a ReactNode would be a type\n // error waiting for the first consumer who tried both.\n extends Omit<ComponentPropsWithoutRef<\"header\">, \"title\"> {\n /** The page's title. Rendered as the page's single `<h1>`. */\n title: ReactNode;\n /**\n * One or two sentences under the title saying what the page is for.\n * Muted, and capped at a readable measure.\n */\n description?: ReactNode;\n /**\n * The page's primary actions, right-aligned on the title row. They wrap\n * below the title on a narrow screen. Pass buttons or links; the header\n * spaces them and does not style them.\n */\n actions?: ReactNode;\n /**\n * A short piece of context inline after the title, on the same baseline:\n * a date the figures are as of, a status chip, a count.\n */\n meta?: ReactNode;\n /**\n * A slot above the title for a way back, on a detail page. Supply the link\n * yourself so it uses your router; the header sizes and colours the slot.\n */\n back?: ReactNode;\n}\n\nexport const PageHeader = forwardRef<HTMLElement, PageHeaderProps>(function PageHeader(\n { className, title, description, actions, meta, back, ...props },\n ref,\n) {\n return (\n <header\n ref={ref}\n {...props}\n data-slot=\"page-header\"\n className={cn(pageHeaderVariants(), className)}\n >\n {back === undefined ? null : (\n <div data-slot=\"page-header-back\" className={pageHeaderBackVariants()}>\n {back}\n </div>\n )}\n <div data-slot=\"page-header-row\" className={pageHeaderRowVariants()}>\n {/*\n * grow from a 16rem basis, not flex-1. flex-1 is a 0% basis, so the\n * row never wraps: the actions keep their width and the title is\n * crushed into a one-word column beside them on a phone. A real basis\n * is the width the title needs before the actions move below it.\n */}\n <div className=\"min-w-0 grow basis-64\">\n <div className=\"flex flex-wrap items-baseline gap-x-3 gap-y-1\">\n <h1 data-slot=\"page-header-title\" className={pageHeaderTitleVariants()}>\n {title}\n </h1>\n {meta === undefined ? null : (\n <div data-slot=\"page-header-meta\" className={pageHeaderMetaVariants()}>\n {meta}\n </div>\n )}\n </div>\n {description === undefined ? null : (\n <p data-slot=\"page-header-description\" className={pageHeaderDescriptionVariants()}>\n {description}\n </p>\n )}\n </div>\n {actions === undefined ? null : (\n <div data-slot=\"page-header-actions\" className={pageHeaderActionsVariants()}>\n {actions}\n </div>\n )}\n </div>\n </header>\n );\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAa,qBAAqB,IAAI,CACpC,cAIA,sCACF,CAAC;;;;;;AAOD,MAAa,wBAAwB,IAAI,kDAAkD;AAE3F,MAAa,0BAA0B,IAAI,CAGzC,+DAEA,KACF,CAAC;AAED,MAAa,yBAAyB,IACpC,0DACF;;;;;;AAOA,MAAa,gCAAgC,IAAI,CAC/C,qCACA,0DACF,CAAC;AAED,MAAa,4BAA4B,IAAI,4CAA4C;AAEzF,MAAa,yBAAyB,IACpC,+DACF;AA4CA,MAAa,aAAa,WAAyC,SAAS,WAC1E,EAAE,WAAW,OAAO,aAAa,SAAS,MAAM,MAAM,GAAG,SACzD,KACA;CACA,OACE,qBAAC,UAAD;EACO;EACL,GAAI;EACJ,aAAU;EACV,WAAW,GAAG,mBAAmB,GAAG,SAAS;EAJ/C,UAAA,CAMG,SAAS,KAAA,IAAY,OACpB,oBAAC,OAAD;GAAK,aAAU;GAAmB,WAAW,uBAAuB;GACjE,UAAA;EACE,CAAA,GAEP,qBAAC,OAAD;GAAK,aAAU;GAAkB,WAAW,sBAAsB;GAAlE,UAAA,CAOE,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,oBAAC,MAAD;MAAI,aAAU;MAAoB,WAAW,wBAAwB;MAClE,UAAA;KACC,CAAA,GACH,SAAS,KAAA,IAAY,OACpB,oBAAC,OAAD;MAAK,aAAU;MAAmB,WAAW,uBAAuB;MACjE,UAAA;KACE,CAAA,CAEJ;IACJ,CAAA,GAAA,gBAAgB,KAAA,IAAY,OAC3B,oBAAC,KAAD;KAAG,aAAU;KAA0B,WAAW,8BAA8B;KAC7E,UAAA;IACA,CAAA,CAEF;GACJ,CAAA,GAAA,YAAY,KAAA,IAAY,OACvB,oBAAC,OAAD;IAAK,aAAU;IAAsB,WAAW,0BAA0B;IACvE,UAAA;GACE,CAAA,CAEJ;EACC,CAAA,CAAA;;AAEZ,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { InputProps } from "react-aria-components";
|
|
2
|
+
//#region src/password-field/password-field.d.ts
|
|
3
|
+
/** The toggle's accessible names. Both have English defaults; pass the ones you translate. */
|
|
4
|
+
export interface PasswordFieldMessages {
|
|
5
|
+
showPassword: string;
|
|
6
|
+
hidePassword: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const defaultPasswordFieldMessages: PasswordFieldMessages;
|
|
9
|
+
export interface PasswordFieldProps extends Omit<InputProps, "className" | "style" | "size" | "type"> {
|
|
10
|
+
/** Extra classes for the input. Merged last, so they win conflicts with ours. */
|
|
11
|
+
className?: string;
|
|
12
|
+
/** The visible label, tied to the input with `htmlFor`. */
|
|
13
|
+
label: string;
|
|
14
|
+
/**
|
|
15
|
+
* Helper text under the field, named by `aria-describedby`. A string, because
|
|
16
|
+
* the copy is animated word by word: it opens on a spring when it appears
|
|
17
|
+
* after mount and changed words rise in. Nothing animates on first render.
|
|
18
|
+
*/
|
|
19
|
+
description?: string;
|
|
20
|
+
/** Translated or reworded toggle names. */
|
|
21
|
+
messages?: Partial<PasswordFieldMessages>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A password input with a show and hide toggle. Switching resolves the text in
|
|
25
|
+
* place from a soft blur, and the eye is one outline that a slash draws across.
|
|
26
|
+
* Native input props apply to the input; `disabled` also disables the toggle,
|
|
27
|
+
* and `aria-invalid` gives the box its invalid border.
|
|
28
|
+
*
|
|
29
|
+
* The toggle's name changes with the state and it is also `aria-pressed`, so a
|
|
30
|
+
* screen reader may announce both ("Hide password, pressed").
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* <PasswordField label="Password" description="At least eight characters." />
|
|
34
|
+
*/
|
|
35
|
+
export declare const PasswordField: import("react").ForwardRefExoticComponent<PasswordFieldProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
36
|
+
//#endregion
|
|
37
|
+
//# sourceMappingURL=password-field.d.ts.map
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { fieldSurfaceVariants } from "../lib/field-surface.js";
|
|
4
|
+
import { FieldShell, useFieldWiring } from "../lib/field-shell.js";
|
|
5
|
+
import { EyeMorph } from "../lib/eye-morph.js";
|
|
6
|
+
import { forwardRef, useState } from "react";
|
|
7
|
+
import { Button, Group, Input } from "react-aria-components";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
//#region src/password-field/password-field.tsx
|
|
10
|
+
const defaultPasswordFieldMessages = {
|
|
11
|
+
showPassword: "Show password",
|
|
12
|
+
hidePassword: "Hide password"
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* The field's box. A React Aria `Group` rather than the input, because the
|
|
16
|
+
* toggle sits inside the same border: it carries the shared field surface (the
|
|
17
|
+
* 160ms border transition, the darker border on hover and focus, the muted
|
|
18
|
+
* disabled look, the invalid border) and the input inside is borderless.
|
|
19
|
+
*
|
|
20
|
+
* `data-focus-within` darkens the border too. A Group reports focus-visible
|
|
21
|
+
* from the input modality, so a mouse click into the input, or onto the toggle,
|
|
22
|
+
* would otherwise leave the border pale; a plain Input is different because
|
|
23
|
+
* React Aria treats a text input as always keyboard-focused.
|
|
24
|
+
*/
|
|
25
|
+
const shellClass = cn(fieldSurfaceVariants(), "flex items-center h-(--density-control-h-md) ps-(--density-control-pad-md) field-toggle-shell [&:where([data-focus-within])]:border-border-strong");
|
|
26
|
+
/** The input inside the box: no border, no fill, no outline of its own. */
|
|
27
|
+
const inputClass = "min-w-0 flex-1 border-0 bg-transparent p-0 font-sans text-base text-foreground outline-none placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground data-[disabled]:cursor-not-allowed motion-safe:data-[reveal=shown]:animate-field-reveal-shown motion-safe:data-[reveal=hidden]:animate-field-reveal-hidden";
|
|
28
|
+
const toggleClass = "field-toggle-button grid size-7.5 flex-none cursor-pointer place-items-center rounded-control border-0 bg-transparent p-0 text-muted-foreground outline-none data-[hovered]:bg-muted data-[hovered]:text-foreground aria-pressed:text-foreground data-[focus-visible]:outline-solid data-[focus-visible]:outline-(length:--focus-ring-width) data-[focus-visible]:outline-offset-(--focus-ring-offset) data-[focus-visible]:outline-(--color-ring) data-[disabled]:cursor-not-allowed";
|
|
29
|
+
/**
|
|
30
|
+
* A password input with a show and hide toggle. Switching resolves the text in
|
|
31
|
+
* place from a soft blur, and the eye is one outline that a slash draws across.
|
|
32
|
+
* Native input props apply to the input; `disabled` also disables the toggle,
|
|
33
|
+
* and `aria-invalid` gives the box its invalid border.
|
|
34
|
+
*
|
|
35
|
+
* The toggle's name changes with the state and it is also `aria-pressed`, so a
|
|
36
|
+
* screen reader may announce both ("Hide password, pressed").
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* <PasswordField label="Password" description="At least eight characters." />
|
|
40
|
+
*/
|
|
41
|
+
const PasswordField = forwardRef(function PasswordField({ label, description, messages: messagesProp, className, ...props }, ref) {
|
|
42
|
+
const messages = {
|
|
43
|
+
...defaultPasswordFieldMessages,
|
|
44
|
+
...messagesProp
|
|
45
|
+
};
|
|
46
|
+
const [visible, setVisible] = useState(false);
|
|
47
|
+
const [toggled, setToggled] = useState(false);
|
|
48
|
+
const field = useFieldWiring({
|
|
49
|
+
enabled: true,
|
|
50
|
+
id: props.id,
|
|
51
|
+
describedBy: props["aria-describedby"],
|
|
52
|
+
invalid: props["aria-invalid"],
|
|
53
|
+
description,
|
|
54
|
+
error: void 0
|
|
55
|
+
});
|
|
56
|
+
const disabled = Boolean(props.disabled);
|
|
57
|
+
const ariaInvalid = props["aria-invalid"];
|
|
58
|
+
const control = /* @__PURE__ */ jsxs(Group, {
|
|
59
|
+
role: "presentation",
|
|
60
|
+
isDisabled: disabled,
|
|
61
|
+
isInvalid: ariaInvalid !== void 0 && ariaInvalid !== false && ariaInvalid !== "false",
|
|
62
|
+
"data-slot": "password-field-shell",
|
|
63
|
+
className: shellClass,
|
|
64
|
+
children: [/* @__PURE__ */ jsx(Input, {
|
|
65
|
+
ref,
|
|
66
|
+
...props,
|
|
67
|
+
...field.controlProps,
|
|
68
|
+
type: visible ? "text" : "password",
|
|
69
|
+
"data-slot": "password-field",
|
|
70
|
+
"data-reveal": toggled ? visible ? "shown" : "hidden" : void 0,
|
|
71
|
+
className: cn(inputClass, className)
|
|
72
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
73
|
+
type: "button",
|
|
74
|
+
isDisabled: disabled,
|
|
75
|
+
"aria-label": visible ? messages.hidePassword : messages.showPassword,
|
|
76
|
+
"aria-pressed": visible,
|
|
77
|
+
onPress: () => {
|
|
78
|
+
setVisible((current) => !current);
|
|
79
|
+
setToggled(true);
|
|
80
|
+
},
|
|
81
|
+
className: toggleClass,
|
|
82
|
+
children: /* @__PURE__ */ jsx(EyeMorph, { slashed: visible })
|
|
83
|
+
})]
|
|
84
|
+
});
|
|
85
|
+
if (!field.active) return control;
|
|
86
|
+
return /* @__PURE__ */ jsx(FieldShell, {
|
|
87
|
+
label,
|
|
88
|
+
controlId: field.controlId,
|
|
89
|
+
description,
|
|
90
|
+
hintId: field.hintId,
|
|
91
|
+
error: void 0,
|
|
92
|
+
errorId: void 0,
|
|
93
|
+
wordExit: "sharp",
|
|
94
|
+
numbers: false,
|
|
95
|
+
children: control
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
//#endregion
|
|
99
|
+
export { PasswordField, defaultPasswordFieldMessages };
|
|
100
|
+
|
|
101
|
+
//# sourceMappingURL=password-field.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password-field.js","names":["AriaGroup","AriaInput","AriaButton"],"sources":["../../src/password-field/password-field.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, useState } from \"react\";\nimport {\n Button as AriaButton,\n Group as AriaGroup,\n Input as AriaInput,\n type InputProps as AriaInputProps,\n} from \"react-aria-components\";\n\nimport { cn } from \"../lib/cn.js\";\nimport { EyeMorph } from \"../lib/eye-morph.js\";\nimport { FieldShell, useFieldWiring } from \"../lib/field-shell.js\";\nimport { fieldSurfaceVariants } from \"../lib/field-surface.js\";\n\n/** The toggle's accessible names. Both have English defaults; pass the ones you translate. */\nexport interface PasswordFieldMessages {\n showPassword: string;\n hidePassword: string;\n}\n\nexport const defaultPasswordFieldMessages: PasswordFieldMessages = {\n showPassword: \"Show password\",\n hidePassword: \"Hide password\",\n};\n\n/**\n * The field's box. A React Aria `Group` rather than the input, because the\n * toggle sits inside the same border: it carries the shared field surface (the\n * 160ms border transition, the darker border on hover and focus, the muted\n * disabled look, the invalid border) and the input inside is borderless.\n *\n * `data-focus-within` darkens the border too. A Group reports focus-visible\n * from the input modality, so a mouse click into the input, or onto the toggle,\n * would otherwise leave the border pale; a plain Input is different because\n * React Aria treats a text input as always keyboard-focused.\n */\nconst shellClass = cn(\n fieldSurfaceVariants(),\n \"flex items-center h-(--density-control-h-md) ps-(--density-control-pad-md) field-toggle-shell [&:where([data-focus-within])]:border-border-strong\",\n);\n\n/** The input inside the box: no border, no fill, no outline of its own. */\nconst inputClass =\n \"min-w-0 flex-1 border-0 bg-transparent p-0 font-sans text-base text-foreground outline-none placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground data-[disabled]:cursor-not-allowed motion-safe:data-[reveal=shown]:animate-field-reveal-shown motion-safe:data-[reveal=hidden]:animate-field-reveal-hidden\";\n\nconst toggleClass =\n \"field-toggle-button grid size-7.5 flex-none cursor-pointer place-items-center rounded-control border-0 bg-transparent p-0 text-muted-foreground outline-none data-[hovered]:bg-muted data-[hovered]:text-foreground aria-pressed:text-foreground data-[focus-visible]:outline-solid data-[focus-visible]:outline-(length:--focus-ring-width) data-[focus-visible]:outline-offset-(--focus-ring-offset) data-[focus-visible]:outline-(--color-ring) data-[disabled]:cursor-not-allowed\";\n\nexport interface PasswordFieldProps extends Omit<\n AriaInputProps,\n \"className\" | \"style\" | \"size\" | \"type\"\n> {\n /** Extra classes for the input. Merged last, so they win conflicts with ours. */\n className?: string;\n /** The visible label, tied to the input with `htmlFor`. */\n label: string;\n /**\n * Helper text under the field, named by `aria-describedby`. A string, because\n * the copy is animated word by word: it opens on a spring when it appears\n * after mount and changed words rise in. Nothing animates on first render.\n */\n description?: string;\n /** Translated or reworded toggle names. */\n messages?: Partial<PasswordFieldMessages>;\n}\n\n/**\n * A password input with a show and hide toggle. Switching resolves the text in\n * place from a soft blur, and the eye is one outline that a slash draws across.\n * Native input props apply to the input; `disabled` also disables the toggle,\n * and `aria-invalid` gives the box its invalid border.\n *\n * The toggle's name changes with the state and it is also `aria-pressed`, so a\n * screen reader may announce both (\"Hide password, pressed\").\n *\n * @example\n * <PasswordField label=\"Password\" description=\"At least eight characters.\" />\n */\nexport const PasswordField = forwardRef<HTMLInputElement, PasswordFieldProps>(\n function PasswordField({ label, description, messages: messagesProp, className, ...props }, ref) {\n const messages = { ...defaultPasswordFieldMessages, ...messagesProp };\n const [visible, setVisible] = useState(false);\n // data-reveal only appears after the first toggle, so the animation runs on each change but never on mount.\n const [toggled, setToggled] = useState(false);\n const field = useFieldWiring({\n enabled: true,\n id: props.id,\n describedBy: props[\"aria-describedby\"],\n invalid: props[\"aria-invalid\"],\n description,\n error: undefined,\n });\n const disabled = Boolean(props.disabled);\n const ariaInvalid = props[\"aria-invalid\"];\n const invalid = ariaInvalid !== undefined && ariaInvalid !== false && ariaInvalid !== \"false\";\n\n const control = (\n <AriaGroup\n role=\"presentation\"\n isDisabled={disabled}\n isInvalid={invalid}\n data-slot=\"password-field-shell\"\n className={shellClass}\n >\n <AriaInput\n ref={ref}\n {...props}\n {...field.controlProps}\n type={visible ? \"text\" : \"password\"}\n data-slot=\"password-field\"\n data-reveal={toggled ? (visible ? \"shown\" : \"hidden\") : undefined}\n className={cn(inputClass, className)}\n />\n <AriaButton\n type=\"button\"\n isDisabled={disabled}\n aria-label={visible ? messages.hidePassword : messages.showPassword}\n aria-pressed={visible}\n onPress={() => {\n setVisible((current) => !current);\n setToggled(true);\n }}\n className={toggleClass}\n >\n <EyeMorph slashed={visible} />\n </AriaButton>\n </AriaGroup>\n );\n\n if (!field.active) return control;\n return (\n <FieldShell\n label={label}\n controlId={field.controlId}\n description={description}\n hintId={field.hintId}\n error={undefined}\n errorId={undefined}\n wordExit=\"sharp\"\n numbers={false}\n >\n {control}\n </FieldShell>\n );\n },\n);\n"],"mappings":";;;;;;;;;AAqBA,MAAa,+BAAsD;CACjE,cAAc;CACd,cAAc;AAChB;;;;;;;;;;;;AAaA,MAAM,aAAa,GACjB,qBAAqB,GACrB,mJACF;;AAGA,MAAM,aACJ;AAEF,MAAM,cACJ;;;;;;;;;;;;;AAgCF,MAAa,gBAAgB,WAC3B,SAAS,cAAc,EAAE,OAAO,aAAa,UAAU,cAAc,WAAW,GAAG,SAAS,KAAK;CAC/F,MAAM,WAAW;EAAE,GAAG;EAA8B,GAAG;CAAa;CACpE,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAE5C,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAC5C,MAAM,QAAQ,eAAe;EAC3B,SAAS;EACT,IAAI,MAAM;EACV,aAAa,MAAM;EACnB,SAAS,MAAM;EACf;EACA,OAAO,KAAA;CACT,CAAC;CACD,MAAM,WAAW,QAAQ,MAAM,QAAQ;CACvC,MAAM,cAAc,MAAM;CAG1B,MAAM,UACJ,qBAACA,OAAD;EACE,MAAK;EACL,YAAY;EACZ,WANY,gBAAgB,KAAA,KAAa,gBAAgB,SAAS,gBAAgB;EAOlF,aAAU;EACV,WAAW;EALb,UAAA,CAOE,oBAACC,OAAD;GACO;GACL,GAAI;GACJ,GAAI,MAAM;GACV,MAAM,UAAU,SAAS;GACzB,aAAU;GACV,eAAa,UAAW,UAAU,UAAU,WAAY,KAAA;GACxD,WAAW,GAAG,YAAY,SAAS;EACpC,CAAA,GACD,oBAACC,QAAD;GACE,MAAK;GACL,YAAY;GACZ,cAAY,UAAU,SAAS,eAAe,SAAS;GACvD,gBAAc;GACd,eAAe;IACb,YAAY,YAAY,CAAC,OAAO;IAChC,WAAW,IAAI;GACjB;GACA,WAAW;GAEX,UAAA,oBAAC,UAAD,EAAU,SAAS,QAAU,CAAA;EACnB,CAAA,CACH;;CAGb,IAAI,CAAC,MAAM,QAAQ,OAAO;CAC1B,OACE,oBAAC,YAAD;EACS;EACP,WAAW,MAAM;EACJ;EACb,QAAQ,MAAM;EACd,OAAO,KAAA;EACP,SAAS,KAAA;EACT,UAAS;EACT,SAAS;EAER,UAAA;CACS,CAAA;AAEhB,CACF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { EstimateStrengthOptions, PasswordRule, PasswordRuleLabels, PasswordRuleOptions, PasswordStrength, PasswordStrengthLevels, PasswordStrengthMessages, PasswordStrengthMessagesInput, PasswordStrengthProps, PasswordStrengthResult, countCodePoints, createPasswordRules, defaultPasswordRules, defaultPasswordStrengthMessages, estimateStrength } from "./password-strength.js";
|
|
2
|
+
export { type EstimateStrengthOptions, type PasswordRule, type PasswordRuleLabels, type PasswordRuleOptions, PasswordStrength, type PasswordStrengthLevels, type PasswordStrengthMessages, type PasswordStrengthMessagesInput, type PasswordStrengthProps, type PasswordStrengthResult, countCodePoints, createPasswordRules, defaultPasswordRules, defaultPasswordStrengthMessages, estimateStrength };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { PasswordStrength, countCodePoints, createPasswordRules, defaultPasswordRules, defaultPasswordStrengthMessages, estimateStrength } from "./password-strength.js";
|
|
2
|
+
export { PasswordStrength, countCodePoints, createPasswordRules, defaultPasswordRules, defaultPasswordStrengthMessages, estimateStrength };
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { InputProps } from "react-aria-components";
|
|
2
|
+
//#region src/password-strength/password-strength.d.ts
|
|
3
|
+
export interface PasswordRule {
|
|
4
|
+
id: string;
|
|
5
|
+
label: string;
|
|
6
|
+
test: (password: string) => boolean;
|
|
7
|
+
/** Characters still missing. Shown as a rolling count beside the rule while it is unmet. */
|
|
8
|
+
remaining?: (password: string) => number;
|
|
9
|
+
}
|
|
10
|
+
export interface PasswordStrengthResult {
|
|
11
|
+
level: 0 | 1 | 2 | 3 | 4;
|
|
12
|
+
label: string;
|
|
13
|
+
met: string[];
|
|
14
|
+
/** True while the password is shorter than the short length, so the meter holds at its first step. */
|
|
15
|
+
short?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/** The strength words, one per meter step. Override them to translate the meter. */
|
|
18
|
+
export interface PasswordStrengthLevels {
|
|
19
|
+
tooShort: string;
|
|
20
|
+
weak: string;
|
|
21
|
+
fair: string;
|
|
22
|
+
good: string;
|
|
23
|
+
strong: string;
|
|
24
|
+
}
|
|
25
|
+
/** Every user-facing string in PasswordStrength. All have English defaults; pass only the ones you change. */
|
|
26
|
+
export interface PasswordStrengthMessages {
|
|
27
|
+
levels: PasswordStrengthLevels;
|
|
28
|
+
/** Name of the show password toggle. It is a pressed toggle (aria-pressed), so the name stays the same in both states. */
|
|
29
|
+
showPassword: string;
|
|
30
|
+
/** Accessible name of the strength meter. */
|
|
31
|
+
meterLabel: string;
|
|
32
|
+
/** Meter value text while the field is empty. */
|
|
33
|
+
noPassword: string;
|
|
34
|
+
/** Accessible name of the requirements list. */
|
|
35
|
+
rulesLabel: string;
|
|
36
|
+
/** Read after a rule's label for screen readers, including any leading punctuation. */
|
|
37
|
+
ruleMet: string;
|
|
38
|
+
ruleNotMet: string;
|
|
39
|
+
/** Words around the rolling count beside an unmet rule, as in "4 more". */
|
|
40
|
+
remainingPrefix: string;
|
|
41
|
+
remainingSuffix: string;
|
|
42
|
+
/** The polite live-region summary read after each change. */
|
|
43
|
+
summary: (result: {
|
|
44
|
+
label: string;
|
|
45
|
+
met: number;
|
|
46
|
+
total: number;
|
|
47
|
+
}) => string;
|
|
48
|
+
}
|
|
49
|
+
export declare const defaultPasswordStrengthMessages: PasswordStrengthMessages;
|
|
50
|
+
/** Partial messages, with partial strength words, for the `messages` prop. */
|
|
51
|
+
export type PasswordStrengthMessagesInput = Partial<Omit<PasswordStrengthMessages, "levels">> & {
|
|
52
|
+
levels?: Partial<PasswordStrengthLevels>;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* A new-password field that shows how strong the password is while it is typed:
|
|
56
|
+
* four segments fill and change tone, each rule checks off with a drawn tick, and
|
|
57
|
+
* the strength word swaps in place. Use it when creating or changing a password;
|
|
58
|
+
* use `PasswordField` for sign in. Scoring happens on the device, nothing is sent
|
|
59
|
+
* anywhere.
|
|
60
|
+
*
|
|
61
|
+
* Native input props apply to the input (`className` too); `disabled` also
|
|
62
|
+
* disables the toggle, and `aria-invalid` gives the box its invalid border.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* <PasswordStrength label="New password" onValueChange={(value, strength) => save(value, strength.level)} />
|
|
66
|
+
*/
|
|
67
|
+
export interface PasswordStrengthProps extends Omit<InputProps, "className" | "style" | "size" | "type" | "value" | "defaultValue" | "children"> {
|
|
68
|
+
/** Extra classes for the input. Merged last, so they win conflicts with ours. */
|
|
69
|
+
className?: string;
|
|
70
|
+
/** The visible label, tied to the input with `htmlFor`. */
|
|
71
|
+
label: string;
|
|
72
|
+
value?: string;
|
|
73
|
+
defaultValue?: string;
|
|
74
|
+
onValueChange?: (value: string, strength: PasswordStrengthResult) => void;
|
|
75
|
+
/** Rules to check. Strength is the share of rules met, spread over four steps. */
|
|
76
|
+
rules?: PasswordRule[];
|
|
77
|
+
/**
|
|
78
|
+
* Error copy tied to the field. It is an alert, opens on a spring and swaps as a
|
|
79
|
+
* whole when it changes; the field shakes once each time a new error appears.
|
|
80
|
+
*/
|
|
81
|
+
error?: string;
|
|
82
|
+
revealed?: boolean;
|
|
83
|
+
onRevealedChange?: (revealed: boolean) => void;
|
|
84
|
+
/** Translated or reworded copy. Every string has an English default; see PasswordStrengthMessages. */
|
|
85
|
+
messages?: PasswordStrengthMessagesInput;
|
|
86
|
+
/** Below this many characters the meter holds at its first step and reads "Too short". Defaults to 8. */
|
|
87
|
+
shortLength?: number;
|
|
88
|
+
/** How characters are counted for shortLength. Defaults to code points, so an emoji counts once; pass `password => password.length` to count UTF-16 units like a server might. */
|
|
89
|
+
countCharacters?: (password: string) => number;
|
|
90
|
+
}
|
|
91
|
+
/** Counts code points, so an emoji or other astral character counts as one. */
|
|
92
|
+
export declare const countCodePoints: (password: string) => number;
|
|
93
|
+
/** Labels for the built-in rules. `length` receives the minimum length. */
|
|
94
|
+
export interface PasswordRuleLabels {
|
|
95
|
+
length: (minLength: number) => string;
|
|
96
|
+
case: string;
|
|
97
|
+
number: string;
|
|
98
|
+
symbol: string;
|
|
99
|
+
}
|
|
100
|
+
export interface PasswordRuleOptions {
|
|
101
|
+
/** Characters the length rule asks for. Defaults to 12. */
|
|
102
|
+
minLength?: number;
|
|
103
|
+
/** Translated or reworded rule labels. */
|
|
104
|
+
labels?: Partial<PasswordRuleLabels>;
|
|
105
|
+
/** How the length rule counts characters. Defaults to code points. */
|
|
106
|
+
countCharacters?: (password: string) => number;
|
|
107
|
+
}
|
|
108
|
+
/** The built-in rules (length, mixed case, number, symbol) with your own minimum length, labels and character count. */
|
|
109
|
+
export declare function createPasswordRules({ minLength, labels, countCharacters }?: PasswordRuleOptions): PasswordRule[];
|
|
110
|
+
export declare const defaultPasswordRules: PasswordRule[];
|
|
111
|
+
export interface EstimateStrengthOptions {
|
|
112
|
+
/** Below this many characters a password stays at the first step, however varied it is. Defaults to 8. */
|
|
113
|
+
shortLength?: number;
|
|
114
|
+
/** Strength words for the result's label. */
|
|
115
|
+
levels?: Partial<PasswordStrengthLevels>;
|
|
116
|
+
/** How characters are counted for shortLength. Defaults to code points. */
|
|
117
|
+
countCharacters?: (password: string) => number;
|
|
118
|
+
}
|
|
119
|
+
/** Scores a password on the device: one step per share of rules met, capped at the first step while it is shorter than the short length (8 by default). */
|
|
120
|
+
export declare function estimateStrength(password: string, rules?: PasswordRule[], { shortLength, levels, countCharacters }?: EstimateStrengthOptions): PasswordStrengthResult;
|
|
121
|
+
/**
|
|
122
|
+
* A new-password input with a strength meter and a checklist (see
|
|
123
|
+
* {@link PasswordStrengthProps}).
|
|
124
|
+
*/
|
|
125
|
+
export declare const PasswordStrength: import("react").ForwardRefExoticComponent<PasswordStrengthProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
126
|
+
//#endregion
|
|
127
|
+
//# sourceMappingURL=password-strength.d.ts.map
|