@arolariu/components 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +89 -0
- package/EXAMPLES.md +2510 -0
- package/dist/components/ui/accordion.js +3 -3
- package/dist/components/ui/accordion.js.map +1 -1
- package/dist/components/ui/accordion_module.css.map +1 -1
- package/dist/components/ui/alert-dialog.d.ts +4 -16
- package/dist/components/ui/alert-dialog.d.ts.map +1 -1
- package/dist/components/ui/alert-dialog.js +21 -17
- package/dist/components/ui/alert-dialog.js.map +1 -1
- package/dist/components/ui/alert-dialog_module.css +1 -1
- package/dist/components/ui/alert-dialog_module.css.map +1 -1
- package/dist/components/ui/alert.js +4 -4
- package/dist/components/ui/alert.js.map +1 -1
- package/dist/components/ui/alert_module.css.map +1 -1
- package/dist/components/ui/aspect-ratio.js +2 -2
- package/dist/components/ui/aspect-ratio.js.map +1 -1
- package/dist/components/ui/aspect-ratio_module.css.map +1 -1
- package/dist/components/ui/async-boundary.js +2 -2
- package/dist/components/ui/async-boundary.js.map +1 -1
- package/dist/components/ui/avatar.d.ts +3 -12
- package/dist/components/ui/avatar.d.ts.map +1 -1
- package/dist/components/ui/avatar.js +18 -15
- package/dist/components/ui/avatar.js.map +1 -1
- package/dist/components/ui/avatar_module.css.map +1 -1
- package/dist/components/ui/background-beams.js +3 -3
- package/dist/components/ui/background-beams.js.map +1 -1
- package/dist/components/ui/background-beams_module.css.map +1 -1
- package/dist/components/ui/badge.js +2 -2
- package/dist/components/ui/badge.js.map +1 -1
- package/dist/components/ui/badge_module.css.map +1 -1
- package/dist/components/ui/breadcrumb.js +10 -10
- package/dist/components/ui/breadcrumb.js.map +1 -1
- package/dist/components/ui/breadcrumb_module.css.map +1 -1
- package/dist/components/ui/bubble-background.js +5 -5
- package/dist/components/ui/bubble-background.js.map +1 -1
- package/dist/components/ui/bubble-background_module.css.map +1 -1
- package/dist/components/ui/button-group.d.ts +1 -1
- package/dist/components/ui/button-group.d.ts.map +1 -1
- package/dist/components/ui/button-group.js +6 -6
- package/dist/components/ui/button-group.js.map +1 -1
- package/dist/components/ui/button-group_module.css.map +1 -1
- package/dist/components/ui/button.js +4 -4
- package/dist/components/ui/button.js.map +1 -1
- package/dist/components/ui/button_module.css.map +1 -1
- package/dist/components/ui/calendar.d.ts +3 -5
- package/dist/components/ui/calendar.d.ts.map +1 -1
- package/dist/components/ui/calendar.js +9 -9
- package/dist/components/ui/calendar.js.map +1 -1
- package/dist/components/ui/calendar_module.css.map +1 -1
- package/dist/components/ui/card-skeleton.js +2 -2
- package/dist/components/ui/card-skeleton.js.map +1 -1
- package/dist/components/ui/card-skeleton_module.css.map +1 -1
- package/dist/components/ui/card.js +8 -8
- package/dist/components/ui/card.js.map +1 -1
- package/dist/components/ui/card_module.css.map +1 -1
- package/dist/components/ui/carousel.d.ts.map +1 -1
- package/dist/components/ui/carousel.js +16 -16
- package/dist/components/ui/carousel.js.map +1 -1
- package/dist/components/ui/carousel_module.css +1 -1
- package/dist/components/ui/carousel_module.css.map +1 -1
- package/dist/components/ui/chart.d.ts +6 -3
- package/dist/components/ui/chart.d.ts.map +1 -1
- package/dist/components/ui/chart.js +70 -70
- package/dist/components/ui/chart.js.map +1 -1
- package/dist/components/ui/chart_module.css.map +1 -1
- package/dist/components/ui/checkbox-group.d.ts +2 -6
- package/dist/components/ui/checkbox-group.d.ts.map +1 -1
- package/dist/components/ui/checkbox-group.js +8 -7
- package/dist/components/ui/checkbox-group.js.map +1 -1
- package/dist/components/ui/checkbox-group_module.css.map +1 -1
- package/dist/components/ui/checkbox.d.ts +3 -1
- package/dist/components/ui/checkbox.d.ts.map +1 -1
- package/dist/components/ui/checkbox.js +6 -3
- package/dist/components/ui/checkbox.js.map +1 -1
- package/dist/components/ui/checkbox_module.css.map +1 -1
- package/dist/components/ui/collapsible.d.ts.map +1 -1
- package/dist/components/ui/collapsible.js +4 -4
- package/dist/components/ui/collapsible.js.map +1 -1
- package/dist/components/ui/collapsible_module.css.map +1 -1
- package/dist/components/ui/combobox.d.ts +335 -0
- package/dist/components/ui/combobox.d.ts.map +1 -0
- package/dist/components/ui/combobox.js +206 -0
- package/dist/components/ui/combobox.js.map +1 -0
- package/dist/components/ui/combobox.module.js +23 -0
- package/dist/components/ui/combobox.module.js.map +1 -0
- package/dist/components/ui/combobox_module.css +142 -0
- package/dist/components/ui/combobox_module.css.map +1 -0
- package/dist/components/ui/command.d.ts.map +1 -1
- package/dist/components/ui/command.js +62 -53
- package/dist/components/ui/command.js.map +1 -1
- package/dist/components/ui/command_module.css +1 -1
- package/dist/components/ui/command_module.css.map +1 -1
- package/dist/components/ui/context-menu.d.ts.map +1 -1
- package/dist/components/ui/context-menu.js +6 -6
- package/dist/components/ui/context-menu.js.map +1 -1
- package/dist/components/ui/context-menu_module.css.map +1 -1
- package/dist/components/ui/copy-button.js +6 -6
- package/dist/components/ui/copy-button.js.map +1 -1
- package/dist/components/ui/copy-button_module.css.map +1 -1
- package/dist/components/ui/counting-number.js +6 -6
- package/dist/components/ui/counting-number.js.map +1 -1
- package/dist/components/ui/counting-number_module.css.map +1 -1
- package/dist/components/ui/dialog.js +6 -6
- package/dist/components/ui/dialog.js.map +1 -1
- package/dist/components/ui/dialog_module.css +1 -1
- package/dist/components/ui/dialog_module.css.map +1 -1
- package/dist/components/ui/dot-background_module.css.map +1 -1
- package/dist/components/ui/drawer.d.ts.map +1 -1
- package/dist/components/ui/drawer.js +5 -5
- package/dist/components/ui/drawer.js.map +1 -1
- package/dist/components/ui/drawer_module.css.map +1 -1
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/components/ui/dropdown-menu.js +6 -6
- package/dist/components/ui/dropdown-menu.js.map +1 -1
- package/dist/components/ui/dropdown-menu_module.css.map +1 -1
- package/dist/components/ui/dropdrawer.d.ts +10 -16
- package/dist/components/ui/dropdrawer.d.ts.map +1 -1
- package/dist/components/ui/dropdrawer.js +73 -65
- package/dist/components/ui/dropdrawer.js.map +1 -1
- package/dist/components/ui/dropdrawer_module.css.map +1 -1
- package/dist/components/ui/empty.js +7 -7
- package/dist/components/ui/empty.js.map +1 -1
- package/dist/components/ui/empty_module.css.map +1 -1
- package/dist/components/ui/error-boundary.js +2 -2
- package/dist/components/ui/error-boundary.js.map +1 -1
- package/dist/components/ui/error-boundary_module.css.map +1 -1
- package/dist/components/ui/field.js +12 -12
- package/dist/components/ui/field.js.map +1 -1
- package/dist/components/ui/field_module.css.map +1 -1
- package/dist/components/ui/fireworks-background.js +6 -6
- package/dist/components/ui/fireworks-background.js.map +1 -1
- package/dist/components/ui/fireworks-background_module.css.map +1 -1
- package/dist/components/ui/flip-button.js +5 -5
- package/dist/components/ui/flip-button.js.map +1 -1
- package/dist/components/ui/flip-button_module.css.map +1 -1
- package/dist/components/ui/focus-scope.js +6 -6
- package/dist/components/ui/focus-scope.js.map +1 -1
- package/dist/components/ui/focus-scope_module.css.map +1 -1
- package/dist/components/ui/form-skeleton.js +2 -2
- package/dist/components/ui/form-skeleton.js.map +1 -1
- package/dist/components/ui/form-skeleton_module.css.map +1 -1
- package/dist/components/ui/form.d.ts +3 -3
- package/dist/components/ui/form.d.ts.map +1 -1
- package/dist/components/ui/form.js +13 -13
- package/dist/components/ui/form.js.map +1 -1
- package/dist/components/ui/form_module.css.map +1 -1
- package/dist/components/ui/gradient-background.js +2 -2
- package/dist/components/ui/gradient-background.js.map +1 -1
- package/dist/components/ui/gradient-background_module.css.map +1 -1
- package/dist/components/ui/gradient-text.js +2 -2
- package/dist/components/ui/gradient-text.js.map +1 -1
- package/dist/components/ui/gradient-text_module.css.map +1 -1
- package/dist/components/ui/highlight-text.js +4 -4
- package/dist/components/ui/highlight-text.js.map +1 -1
- package/dist/components/ui/highlight-text_module.css.map +1 -1
- package/dist/components/ui/hole-background.js +21 -21
- package/dist/components/ui/hole-background.js.map +1 -1
- package/dist/components/ui/hole-background_module.css.map +1 -1
- package/dist/components/ui/hover-card.js +3 -3
- package/dist/components/ui/hover-card.js.map +1 -1
- package/dist/components/ui/hover-card_module.css.map +1 -1
- package/dist/components/ui/input-group.js +7 -7
- package/dist/components/ui/input-group.js.map +1 -1
- package/dist/components/ui/input-group_module.css.map +1 -1
- package/dist/components/ui/input-otp.d.ts +3 -3
- package/dist/components/ui/input-otp.d.ts.map +1 -1
- package/dist/components/ui/input-otp.js +6 -6
- package/dist/components/ui/input-otp.js.map +1 -1
- package/dist/components/ui/input-otp_module.css.map +1 -1
- package/dist/components/ui/input.js +2 -2
- package/dist/components/ui/input.js.map +1 -1
- package/dist/components/ui/input_module.css.map +1 -1
- package/dist/components/ui/item.d.ts +1 -1
- package/dist/components/ui/item.d.ts.map +1 -1
- package/dist/components/ui/item.js +13 -13
- package/dist/components/ui/item.js.map +1 -1
- package/dist/components/ui/item_module.css.map +1 -1
- package/dist/components/ui/kbd.js +3 -3
- package/dist/components/ui/kbd.js.map +1 -1
- package/dist/components/ui/kbd_module.css.map +1 -1
- package/dist/components/ui/label.js +2 -2
- package/dist/components/ui/label.js.map +1 -1
- package/dist/components/ui/label_module.css.map +1 -1
- package/dist/components/ui/list-skeleton.js +2 -2
- package/dist/components/ui/list-skeleton.js.map +1 -1
- package/dist/components/ui/list-skeleton_module.css.map +1 -1
- package/dist/components/ui/loading-overlay.js +2 -2
- package/dist/components/ui/loading-overlay.js.map +1 -1
- package/dist/components/ui/loading-overlay_module.css.map +1 -1
- package/dist/components/ui/menubar.d.ts +11 -13
- package/dist/components/ui/menubar.d.ts.map +1 -1
- package/dist/components/ui/menubar.js +4 -4
- package/dist/components/ui/menubar.js.map +1 -1
- package/dist/components/ui/menubar_module.css.map +1 -1
- package/dist/components/ui/meter.d.ts +8 -24
- package/dist/components/ui/meter.d.ts.map +1 -1
- package/dist/components/ui/meter.js +23 -19
- package/dist/components/ui/meter.js.map +1 -1
- package/dist/components/ui/meter_module.css.map +1 -1
- package/dist/components/ui/navigation-menu.d.ts +3 -12
- package/dist/components/ui/navigation-menu.d.ts.map +1 -1
- package/dist/components/ui/navigation-menu.js +15 -12
- package/dist/components/ui/navigation-menu.js.map +1 -1
- package/dist/components/ui/navigation-menu_module.css +1 -1
- package/dist/components/ui/navigation-menu_module.css.map +1 -1
- package/dist/components/ui/number-field.d.ts +6 -12
- package/dist/components/ui/number-field.d.ts.map +1 -1
- package/dist/components/ui/number-field.js +3 -3
- package/dist/components/ui/number-field.js.map +1 -1
- package/dist/components/ui/number-field_module.css.map +1 -1
- package/dist/components/ui/pagination.js +8 -8
- package/dist/components/ui/pagination.js.map +1 -1
- package/dist/components/ui/pagination_module.css.map +1 -1
- package/dist/components/ui/popover.js +5 -5
- package/dist/components/ui/popover.js.map +1 -1
- package/dist/components/ui/popover_module.css.map +1 -1
- package/dist/components/ui/progress.d.ts +1 -4
- package/dist/components/ui/progress.d.ts.map +1 -1
- package/dist/components/ui/progress.js +10 -9
- package/dist/components/ui/progress.js.map +1 -1
- package/dist/components/ui/progress_module.css.map +1 -1
- package/dist/components/ui/radio-group.d.ts +2 -4
- package/dist/components/ui/radio-group.d.ts.map +1 -1
- package/dist/components/ui/radio-group.js +3 -3
- package/dist/components/ui/radio-group.js.map +1 -1
- package/dist/components/ui/radio-group_module.css.map +1 -1
- package/dist/components/ui/resizable.d.ts +13 -29
- package/dist/components/ui/resizable.d.ts.map +1 -1
- package/dist/components/ui/resizable.js +8 -7
- package/dist/components/ui/resizable.js.map +1 -1
- package/dist/components/ui/resizable_module.css.map +1 -1
- package/dist/components/ui/ripple-button.js +9 -9
- package/dist/components/ui/ripple-button.js.map +1 -1
- package/dist/components/ui/ripple-button_module.css.map +1 -1
- package/dist/components/ui/scratcher.d.ts +1 -1
- package/dist/components/ui/scratcher.d.ts.map +1 -1
- package/dist/components/ui/scratcher.js +5 -4
- package/dist/components/ui/scratcher.js.map +1 -1
- package/dist/components/ui/scratcher_module.css.map +1 -1
- package/dist/components/ui/scroll-area.d.ts +2 -4
- package/dist/components/ui/scroll-area.d.ts.map +1 -1
- package/dist/components/ui/scroll-area.js +2 -2
- package/dist/components/ui/scroll-area.js.map +1 -1
- package/dist/components/ui/scroll-area_module.css.map +1 -1
- package/dist/components/ui/select.js +4 -4
- package/dist/components/ui/select.js.map +1 -1
- package/dist/components/ui/select_module.css.map +1 -1
- package/dist/components/ui/separator.d.ts +1 -4
- package/dist/components/ui/separator.d.ts.map +1 -1
- package/dist/components/ui/separator.js +9 -8
- package/dist/components/ui/separator.js.map +1 -1
- package/dist/components/ui/separator_module.css.map +1 -1
- package/dist/components/ui/sheet.d.ts.map +1 -1
- package/dist/components/ui/sheet.js +6 -6
- package/dist/components/ui/sheet.js.map +1 -1
- package/dist/components/ui/sheet_module.css.map +1 -1
- package/dist/components/ui/sidebar.d.ts +1 -1
- package/dist/components/ui/sidebar.d.ts.map +1 -1
- package/dist/components/ui/sidebar.js +36 -36
- package/dist/components/ui/sidebar.js.map +1 -1
- package/dist/components/ui/sidebar_module.css.map +1 -1
- package/dist/components/ui/skeleton.js +2 -2
- package/dist/components/ui/skeleton.js.map +1 -1
- package/dist/components/ui/skeleton_module.css.map +1 -1
- package/dist/components/ui/slider.js +2 -2
- package/dist/components/ui/slider.js.map +1 -1
- package/dist/components/ui/slider_module.css.map +1 -1
- package/dist/components/ui/spinner.js +2 -2
- package/dist/components/ui/spinner.js.map +1 -1
- package/dist/components/ui/spinner_module.css.map +1 -1
- package/dist/components/ui/stepper.js +2 -2
- package/dist/components/ui/stepper.js.map +1 -1
- package/dist/components/ui/stepper_module.css.map +1 -1
- package/dist/components/ui/switch.js +2 -2
- package/dist/components/ui/switch.js.map +1 -1
- package/dist/components/ui/switch_module.css.map +1 -1
- package/dist/components/ui/table-skeleton.js +2 -2
- package/dist/components/ui/table-skeleton.js.map +1 -1
- package/dist/components/ui/table-skeleton_module.css.map +1 -1
- package/dist/components/ui/table.js +9 -9
- package/dist/components/ui/table.js.map +1 -1
- package/dist/components/ui/table_module.css.map +1 -1
- package/dist/components/ui/tabs.js +3 -3
- package/dist/components/ui/tabs.js.map +1 -1
- package/dist/components/ui/tabs_module.css.map +1 -1
- package/dist/components/ui/textarea.js +2 -2
- package/dist/components/ui/textarea.js.map +1 -1
- package/dist/components/ui/textarea_module.css.map +1 -1
- package/dist/components/ui/timeline.js +5 -5
- package/dist/components/ui/timeline.js.map +1 -1
- package/dist/components/ui/timeline_module.css.map +1 -1
- package/dist/components/ui/{sonner.d.ts → toast.d.ts} +15 -6
- package/dist/components/ui/toast.d.ts.map +1 -0
- package/dist/components/ui/{sonner.js → toast.js} +43 -42
- package/dist/components/ui/toast.js.map +1 -0
- package/dist/components/ui/toast.module.js +34 -0
- package/dist/components/ui/toast.module.js.map +1 -0
- package/dist/components/ui/{sonner_module.css → toast_module.css} +35 -35
- package/dist/components/ui/toast_module.css.map +1 -0
- package/dist/components/ui/toggle-group.d.ts +2 -8
- package/dist/components/ui/toggle-group.d.ts.map +1 -1
- package/dist/components/ui/toggle-group.js +14 -12
- package/dist/components/ui/toggle-group.js.map +1 -1
- package/dist/components/ui/toggle-group_module.css.map +1 -1
- package/dist/components/ui/toggle.js +2 -2
- package/dist/components/ui/toggle.js.map +1 -1
- package/dist/components/ui/toggle_module.css.map +1 -1
- package/dist/components/ui/toolbar.d.ts +10 -30
- package/dist/components/ui/toolbar.d.ts.map +1 -1
- package/dist/components/ui/toolbar.js +28 -23
- package/dist/components/ui/toolbar.js.map +1 -1
- package/dist/components/ui/toolbar_module.css.map +1 -1
- package/dist/components/ui/tooltip.js +4 -4
- package/dist/components/ui/tooltip.js.map +1 -1
- package/dist/components/ui/tooltip_module.css.map +1 -1
- package/dist/components/ui/typewriter.js +4 -4
- package/dist/components/ui/typewriter.js.map +1 -1
- package/dist/components/ui/typewriter_module.css.map +1 -1
- package/dist/components/ui/visually-hidden.js +2 -2
- package/dist/components/ui/visually-hidden.js.map +1 -1
- package/dist/components/ui/visually-hidden_module.css.map +1 -1
- package/dist/hooks/useAnnounce.js +5 -5
- package/dist/hooks/useAnnounce.js.map +1 -1
- package/dist/hooks/useClipboard.d.ts +77 -0
- package/dist/hooks/useClipboard.d.ts.map +1 -0
- package/dist/hooks/useClipboard.js +42 -0
- package/dist/hooks/useClipboard.js.map +1 -0
- package/dist/hooks/useControllableState.d.ts +54 -0
- package/dist/hooks/useControllableState.d.ts.map +1 -0
- package/dist/hooks/useControllableState.js +29 -0
- package/dist/hooks/useControllableState.js.map +1 -0
- package/dist/hooks/useDebounce.d.ts +33 -0
- package/dist/hooks/useDebounce.d.ts.map +1 -0
- package/dist/hooks/useDebounce.js +20 -0
- package/dist/hooks/useDebounce.js.map +1 -0
- package/dist/hooks/useEventCallback.d.ts +34 -0
- package/dist/hooks/useEventCallback.d.ts.map +1 -0
- package/dist/hooks/useEventCallback.js +12 -0
- package/dist/hooks/useEventCallback.js.map +1 -0
- package/dist/hooks/useFocusManager.js +6 -6
- package/dist/hooks/useFocusManager.js.map +1 -1
- package/dist/hooks/useFocusVisible.js +5 -5
- package/dist/hooks/useFocusVisible.js.map +1 -1
- package/dist/hooks/useId.d.ts +30 -0
- package/dist/hooks/useId.d.ts.map +1 -0
- package/dist/hooks/useId.js +9 -0
- package/dist/hooks/useId.js.map +1 -0
- package/dist/hooks/useIntersectionObserver.d.ts +51 -0
- package/dist/hooks/useIntersectionObserver.d.ts.map +1 -0
- package/dist/hooks/useIntersectionObserver.js +25 -0
- package/dist/hooks/useIntersectionObserver.js.map +1 -0
- package/dist/hooks/useInterval.d.ts +55 -0
- package/dist/hooks/useInterval.d.ts.map +1 -0
- package/dist/hooks/useInterval.js +24 -0
- package/dist/hooks/useInterval.js.map +1 -0
- package/dist/hooks/useLocalStorage.d.ts +43 -0
- package/dist/hooks/useLocalStorage.d.ts.map +1 -0
- package/dist/hooks/useLocalStorage.js +53 -0
- package/dist/hooks/useLocalStorage.js.map +1 -0
- package/dist/hooks/useMediaQuery.js +3 -3
- package/dist/hooks/useMediaQuery.js.map +1 -1
- package/dist/hooks/useMergedRefs.d.ts +27 -0
- package/dist/hooks/useMergedRefs.d.ts.map +1 -0
- package/dist/hooks/useMergedRefs.js +11 -0
- package/dist/hooks/useMergedRefs.js.map +1 -0
- package/dist/hooks/useOnClickOutside.d.ts +32 -0
- package/dist/hooks/useOnClickOutside.d.ts.map +1 -0
- package/dist/hooks/useOnClickOutside.js +23 -0
- package/dist/hooks/useOnClickOutside.js.map +1 -0
- package/dist/hooks/usePrevious.d.ts +33 -0
- package/dist/hooks/usePrevious.d.ts.map +1 -0
- package/dist/hooks/usePrevious.js +14 -0
- package/dist/hooks/usePrevious.js.map +1 -0
- package/dist/hooks/useThrottle.d.ts +37 -0
- package/dist/hooks/useThrottle.d.ts.map +1 -0
- package/dist/hooks/useThrottle.js +34 -0
- package/dist/hooks/useThrottle.js.map +1 -0
- package/dist/hooks/useTimeout.d.ts +28 -0
- package/dist/hooks/useTimeout.d.ts.map +1 -0
- package/dist/hooks/useTimeout.js +24 -0
- package/dist/hooks/useTimeout.js.map +1 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +17 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -1
- package/dist/lib/utilities.d.ts +2 -3
- package/dist/lib/utilities.d.ts.map +1 -1
- package/dist/lib/utilities.js.map +1 -1
- package/dist/motion/Collapse.js +2 -2
- package/dist/motion/Collapse.js.map +1 -1
- package/dist/motion/Collapse_module.css.map +1 -1
- package/dist/motion/tokens.js +5 -5
- package/dist/motion/tokens.js.map +1 -1
- package/package.json +88 -10
- package/src/components/ui/alert-dialog.tsx +15 -8
- package/src/components/ui/avatar.tsx +9 -6
- package/src/components/ui/calendar.tsx +9 -14
- package/src/components/ui/carousel.tsx +2 -0
- package/src/components/ui/chart.tsx +65 -62
- package/src/components/ui/checkbox-group.tsx +4 -5
- package/src/components/ui/checkbox.tsx +10 -2
- package/src/components/ui/collapsible.tsx +1 -0
- package/src/components/ui/combobox.module.css +158 -0
- package/src/components/ui/combobox.tsx +569 -0
- package/src/components/ui/command.tsx +31 -15
- package/src/components/ui/context-menu.tsx +3 -0
- package/src/components/ui/drawer.tsx +2 -0
- package/src/components/ui/dropdown-menu.tsx +3 -0
- package/src/components/ui/dropdrawer.tsx +80 -62
- package/src/components/ui/form.tsx +28 -3
- package/src/components/ui/input-otp.tsx +3 -3
- package/src/components/ui/menubar.tsx +9 -10
- package/src/components/ui/meter.tsx +16 -17
- package/src/components/ui/navigation-menu.tsx +41 -33
- package/src/components/ui/number-field.tsx +6 -13
- package/src/components/ui/progress.tsx +3 -2
- package/src/components/ui/radio-group.tsx +2 -5
- package/src/components/ui/resizable.tsx +15 -18
- package/src/components/ui/scratcher.tsx +6 -10
- package/src/components/ui/scroll-area.tsx +2 -5
- package/src/components/ui/separator.tsx +4 -3
- package/src/components/ui/sheet.tsx +3 -0
- package/src/components/ui/sidebar.tsx +1 -0
- package/src/components/ui/{sonner.module.css → toast.module.css} +1 -1
- package/src/components/ui/{sonner.tsx → toast.tsx} +22 -14
- package/src/components/ui/toggle-group.tsx +6 -4
- package/src/components/ui/toolbar.tsx +20 -21
- package/src/hooks/useClipboard.tsx +137 -0
- package/src/hooks/useControllableState.tsx +81 -0
- package/src/hooks/useDebounce.tsx +50 -0
- package/src/hooks/useEventCallback.tsx +47 -0
- package/src/hooks/useId.tsx +36 -0
- package/src/hooks/useIntersectionObserver.tsx +81 -0
- package/src/hooks/useInterval.tsx +80 -0
- package/src/hooks/useLocalStorage.tsx +111 -0
- package/src/hooks/useMergedRefs.tsx +48 -0
- package/src/hooks/useOnClickOutside.tsx +55 -0
- package/src/hooks/usePrevious.tsx +44 -0
- package/src/hooks/useThrottle.tsx +78 -0
- package/src/hooks/useTimeout.tsx +51 -0
- package/src/index.ts +27 -4
- package/src/lib/utilities.ts +4 -4
- package/src/motion/tokens.ts +4 -4
- package/src/stories/DesignPrinciples.mdx +48 -0
- package/src/stories/GettingStarted.mdx +92 -0
- package/src/stories/Welcome.mdx +44 -0
- package/dist/components/ui/sonner.d.ts.map +0 -1
- package/dist/components/ui/sonner.js.map +0 -1
- package/dist/components/ui/sonner.module.js +0 -34
- package/dist/components/ui/sonner.module.js.map +0 -1
- package/dist/components/ui/sonner_module.css.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
|
-
import { cloneElement, createContext, forwardRef, isValidElement, useContext, useId } from "react";
|
|
4
3
|
import { Controller, FormProvider, useController, useFieldArray, useForm, useFormContext, useFormState, useWatch } from "react-hook-form";
|
|
5
4
|
import { cn } from "../../lib/utilities.js";
|
|
6
5
|
import form_module from "./form.module.js";
|
|
6
|
+
import * as __rspack_external_react from "react";
|
|
7
7
|
const Form = Object.assign(FormProvider, {
|
|
8
8
|
displayName: "Form"
|
|
9
9
|
});
|
|
@@ -22,7 +22,7 @@ function mergeAriaDescribedBy(...describedByValues) {
|
|
|
22
22
|
...new Set(tokens)
|
|
23
23
|
].join(" ") : void 0;
|
|
24
24
|
}
|
|
25
|
-
const FormFieldContext = /*#__PURE__*/ createContext(null);
|
|
25
|
+
const FormFieldContext = /*#__PURE__*/ __rspack_external_react.createContext(null);
|
|
26
26
|
const FormField = ({ ...props })=>/*#__PURE__*/ jsx(FormFieldContext.Provider, {
|
|
27
27
|
value: {
|
|
28
28
|
name: props.name
|
|
@@ -32,8 +32,8 @@ const FormField = ({ ...props })=>/*#__PURE__*/ jsx(FormFieldContext.Provider, {
|
|
|
32
32
|
})
|
|
33
33
|
});
|
|
34
34
|
const useFormField = ()=>{
|
|
35
|
-
const fieldContext = useContext(FormFieldContext);
|
|
36
|
-
const itemContext = useContext(FormItemContext);
|
|
35
|
+
const fieldContext = __rspack_external_react.useContext(FormFieldContext);
|
|
36
|
+
const itemContext = __rspack_external_react.useContext(FormItemContext);
|
|
37
37
|
const { getFieldState, formState } = useFormContext();
|
|
38
38
|
if (!fieldContext) throw new Error("useFormField should be used within <FormField>");
|
|
39
39
|
if (!itemContext) throw new Error("useFormField should be used within <FormItem>");
|
|
@@ -52,9 +52,9 @@ const useFormField = ()=>{
|
|
|
52
52
|
name: fieldContext.name
|
|
53
53
|
};
|
|
54
54
|
};
|
|
55
|
-
const FormItemContext = /*#__PURE__*/ createContext(null);
|
|
56
|
-
const FormItem = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=>{
|
|
57
|
-
const id = useId();
|
|
55
|
+
const FormItemContext = /*#__PURE__*/ __rspack_external_react.createContext(null);
|
|
56
|
+
const FormItem = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, ...props }, ref)=>{
|
|
57
|
+
const id = __rspack_external_react.useId();
|
|
58
58
|
return /*#__PURE__*/ jsx(FormItemContext.Provider, {
|
|
59
59
|
value: {
|
|
60
60
|
id
|
|
@@ -67,7 +67,7 @@ const FormItem = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=>{
|
|
|
67
67
|
});
|
|
68
68
|
});
|
|
69
69
|
FormItem.displayName = "FormItem";
|
|
70
|
-
const FormLabel = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=>{
|
|
70
|
+
const FormLabel = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, ...props }, ref)=>{
|
|
71
71
|
const { error, formItemId } = useFormField();
|
|
72
72
|
return /*#__PURE__*/ jsx("label", {
|
|
73
73
|
ref: ref,
|
|
@@ -77,13 +77,13 @@ const FormLabel = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=>{
|
|
|
77
77
|
});
|
|
78
78
|
});
|
|
79
79
|
FormLabel.displayName = "FormLabel";
|
|
80
|
-
const FormControl = /*#__PURE__*/ forwardRef(({ children, ...props }, ref)=>{
|
|
80
|
+
const FormControl = /*#__PURE__*/ __rspack_external_react.forwardRef(({ children, ...props }, ref)=>{
|
|
81
81
|
const { error, formDescriptionId, formItemId, formMessageId } = useFormField();
|
|
82
82
|
const describedBy = mergeAriaDescribedBy("string" == typeof props["aria-describedby"] ? props["aria-describedby"] : void 0, formDescriptionId, error ? formMessageId : void 0);
|
|
83
|
-
if (/*#__PURE__*/ isValidElement(children)) {
|
|
83
|
+
if (/*#__PURE__*/ __rspack_external_react.isValidElement(children)) {
|
|
84
84
|
const child = children;
|
|
85
85
|
const childDescribedBy = "string" == typeof child.props["aria-describedby"] ? child.props["aria-describedby"] : void 0;
|
|
86
|
-
return /*#__PURE__*/ cloneElement(child, {
|
|
86
|
+
return /*#__PURE__*/ __rspack_external_react.cloneElement(child, {
|
|
87
87
|
...props,
|
|
88
88
|
ref: composeRefs(ref, child.props.ref),
|
|
89
89
|
id: formItemId,
|
|
@@ -101,7 +101,7 @@ const FormControl = /*#__PURE__*/ forwardRef(({ children, ...props }, ref)=>{
|
|
|
101
101
|
});
|
|
102
102
|
});
|
|
103
103
|
FormControl.displayName = "FormControl";
|
|
104
|
-
const FormDescription = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=>{
|
|
104
|
+
const FormDescription = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, ...props }, ref)=>{
|
|
105
105
|
const { formDescriptionId } = useFormField();
|
|
106
106
|
return /*#__PURE__*/ jsx("p", {
|
|
107
107
|
ref: ref,
|
|
@@ -111,7 +111,7 @@ const FormDescription = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=
|
|
|
111
111
|
});
|
|
112
112
|
});
|
|
113
113
|
FormDescription.displayName = "FormDescription";
|
|
114
|
-
const FormMessage = /*#__PURE__*/ forwardRef(({ className, children, ...props }, ref)=>{
|
|
114
|
+
const FormMessage = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, children, ...props }, ref)=>{
|
|
115
115
|
const { error, formMessageId } = useFormField();
|
|
116
116
|
const body = error ? String(error.message ?? "") : children;
|
|
117
117
|
if (!body) return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components/ui/form.js","sources":["../../../src/components/ui/form.tsx"],"sourcesContent":["\"use client\";\r\n\r\n/* eslint-disable react/prop-types */\r\n\r\nimport * as React from \"react\";\r\nimport {Controller, FormProvider, useFormContext, type ControllerProps, type FieldPath, type FieldValues} from \"react-hook-form\";\r\n\r\nimport {cn} from \"@/lib/utilities\";\r\n\r\nimport styles from \"./form.module.css\";\r\n\r\n/**\r\n * Provides the `react-hook-form` context to nested form primitives.\r\n *\r\n * @remarks\r\n * - Renders the `FormProvider` component from `react-hook-form`\r\n * - Built on `react-hook-form`\r\n *\r\n * @example\r\n * ```tsx\r\n * <Form {...form}>\r\n * <form>...</form>\r\n * </Form>\r\n * ```\r\n *\r\n * @see {@link https://react-hook-form.com/docs/formprovider | React Hook Form FormProvider Docs}\r\n */\r\nconst Form = Object.assign(FormProvider, {displayName: \"Form\"});\r\n\r\ntype FormControlElementProps = React.HTMLAttributes<HTMLElement> & {\r\n ref?: React.Ref<HTMLElement>;\r\n};\r\n\r\ninterface FormControlProps extends Omit<React.HTMLAttributes<HTMLElement>, \"children\"> {\r\n /**\r\n * Single form control element or fallback content to receive field accessibility attributes.\r\n * @default undefined\r\n */\r\n children: React.ReactNode;\r\n}\r\n\r\nfunction assignRef<TValue>(ref: React.Ref<TValue> | undefined, value: TValue | null): void {\r\n if (typeof ref === \"function\") {\r\n ref(value);\r\n return;\r\n }\r\n\r\n if (ref) {\r\n ref.current = value;\r\n }\r\n}\r\n\r\nfunction composeRefs<TValue>(...refs: Array<React.Ref<TValue> | undefined>): React.RefCallback<TValue> {\r\n return (value: TValue | null): void => {\r\n for (const ref of refs) {\r\n assignRef(ref, value);\r\n }\r\n };\r\n}\r\n\r\nfunction mergeAriaDescribedBy(...describedByValues: Array<string | undefined>): string | undefined {\r\n const tokens = describedByValues\r\n .flatMap((describedByValue) => describedByValue?.split(/\\s+/u) ?? [])\r\n .filter((token): token is string => token.length > 0);\r\n\r\n return tokens.length > 0 ? [...new Set(tokens)].join(\" \") : undefined;\r\n}\r\n\r\ntype FormFieldContextValue<\r\n TFieldValues extends FieldValues = FieldValues,\r\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\r\n> = {\r\n name: TName;\r\n};\r\n\r\nconst FormFieldContext = React.createContext<FormFieldContextValue | null>(null);\r\n\r\n/**\r\n * Binds a single field name to the shared form field context.\r\n *\r\n * @remarks\r\n * - Renders the `Controller` component from `react-hook-form`\r\n * - Built on `react-hook-form` controller primitives\r\n *\r\n * @example\r\n * ```tsx\r\n * <FormField\r\n * control={form.control}\r\n * name='email'\r\n * render={({field}) => <input {...field} />}\r\n * />\r\n * ```\r\n *\r\n * @see {@link https://react-hook-form.com/docs/usecontroller/controller | React Hook Form Controller Docs}\r\n */\r\nconst FormField = <TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({\r\n ...props\r\n}: ControllerProps<TFieldValues, TName>): React.JSX.Element => {\r\n return (\r\n <FormFieldContext.Provider value={{name: props.name}}>\r\n <Controller {...props} />\r\n </FormFieldContext.Provider>\r\n );\r\n};\r\n\r\ntype UseFormFieldReturn = {\r\n id: string;\r\n name: FieldPath<FieldValues>;\r\n formItemId: string;\r\n formDescriptionId: string;\r\n formMessageId: string;\r\n invalid: boolean;\r\n isDirty: boolean;\r\n isTouched: boolean;\r\n isValidating: boolean;\r\n error?: ReturnType<ReturnType<typeof useFormContext>[\"getFieldState\"]>[\"error\"];\r\n};\r\n\r\n/**\r\n * Returns the resolved form field metadata for nested form primitives.\r\n *\r\n * @remarks\r\n * Reads the nearest {@link FormField} and {@link FormItem} contexts, then combines them\r\n * with `react-hook-form` field state to expose stable IDs and validation metadata.\r\n *\r\n * @example\r\n * ```tsx\r\n * const field = useFormField();\r\n * ```\r\n *\r\n * @see {@link https://react-hook-form.com/docs/useformcontext | React Hook Form useFormContext Docs}\r\n */\r\nconst useFormField = (): UseFormFieldReturn => {\r\n const fieldContext = React.useContext(FormFieldContext);\r\n const itemContext = React.useContext(FormItemContext);\r\n const {getFieldState, formState} = useFormContext();\r\n\r\n if (!fieldContext) {\r\n throw new Error(\"useFormField should be used within <FormField>\");\r\n }\r\n\r\n if (!itemContext) {\r\n throw new Error(\"useFormField should be used within <FormItem>\");\r\n }\r\n\r\n const fieldState = getFieldState(fieldContext.name, formState);\r\n const {id} = itemContext;\r\n\r\n return {\r\n error: fieldState.error,\r\n formDescriptionId: `${id}-form-item-description`,\r\n formItemId: `${id}-form-item`,\r\n formMessageId: `${id}-form-item-message`,\r\n id,\r\n invalid: fieldState.invalid,\r\n isDirty: fieldState.isDirty,\r\n isTouched: fieldState.isTouched,\r\n isValidating: fieldState.isValidating,\r\n name: fieldContext.name as FieldPath<FieldValues>,\r\n };\r\n};\r\n\r\ntype FormItemContextValue = {\r\n id: string;\r\n};\r\n\r\nconst FormItemContext = React.createContext<FormItemContextValue | null>(null);\r\n\r\n/**\r\n * Wraps a label, control, description, and message into a single form item.\r\n *\r\n * @remarks\r\n * - Renders a `<div>` element\r\n * - Built on the shared form item context\r\n *\r\n * @example\r\n * ```tsx\r\n * <FormItem>\r\n * <FormLabel>Email</FormLabel>\r\n * </FormItem>\r\n * ```\r\n *\r\n * @see {@link https://react-hook-form.com/docs/useformcontext | React Hook Form Docs}\r\n */\r\nconst FormItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(({className, ...props}, ref) => {\r\n const id = React.useId();\r\n\r\n return (\r\n <FormItemContext.Provider value={{id}}>\r\n <div\r\n ref={ref}\r\n className={cn(styles.item, className)}\r\n {...props}\r\n />\r\n </FormItemContext.Provider>\r\n );\r\n});\r\nFormItem.displayName = \"FormItem\";\r\n\r\n/**\r\n * Renders the accessible label for the current form item.\r\n *\r\n * @remarks\r\n * - Renders a `<label>` element\r\n * - Built on the shared form field metadata hook\r\n *\r\n * @example\r\n * ```tsx\r\n * <FormLabel>Email</FormLabel>\r\n * ```\r\n *\r\n * @see {@link https://developer.mozilla.org/docs/Web/HTML/Element/label | HTML label element}\r\n */\r\nconst FormLabel = React.forwardRef<HTMLLabelElement, React.LabelHTMLAttributes<HTMLLabelElement>>(({className, ...props}, ref) => {\r\n const {error, formItemId} = useFormField();\r\n\r\n return (\r\n <label\r\n ref={ref}\r\n className={cn(error && styles.labelError, className)}\r\n htmlFor={formItemId}\r\n {...props}\r\n />\r\n );\r\n});\r\nFormLabel.displayName = \"FormLabel\";\r\n\r\n/**\r\n * Provides react-hook-form field metadata to a single control element.\r\n *\r\n * @remarks\r\n * This replaces the former Radix Slot-based implementation by cloning the\r\n * direct child element and merging the accessibility attributes required by the\r\n * surrounding form primitives. A fallback wrapper is rendered only when the\r\n * child is not a valid React element.\r\n */\r\nconst FormControl = React.forwardRef<HTMLElement, FormControlProps>(\r\n ({children, ...props}: Readonly<FormControlProps>, ref): React.JSX.Element => {\r\n const {error, formDescriptionId, formItemId, formMessageId} = useFormField();\r\n const describedBy = mergeAriaDescribedBy(\r\n typeof props[\"aria-describedby\"] === \"string\" ? props[\"aria-describedby\"] : undefined,\r\n formDescriptionId,\r\n error ? formMessageId : undefined,\r\n );\r\n\r\n if (React.isValidElement(children)) {\r\n const child = children as React.ReactElement<FormControlElementProps>;\r\n const childDescribedBy = typeof child.props[\"aria-describedby\"] === \"string\" ? child.props[\"aria-describedby\"] : undefined;\r\n\r\n // eslint-disable-next-line react-x/no-clone-element -- removes Radix Slot while preserving child element semantics\r\n return React.cloneElement(child, {\r\n ...props,\r\n ref: composeRefs(ref, child.props.ref),\r\n id: formItemId,\r\n \"aria-describedby\": mergeAriaDescribedBy(childDescribedBy, describedBy),\r\n \"aria-invalid\": Boolean(error),\r\n });\r\n }\r\n\r\n return (\r\n <div\r\n ref={ref as React.Ref<HTMLDivElement>}\r\n id={formItemId}\r\n aria-describedby={describedBy}\r\n aria-invalid={Boolean(error)}\r\n {...props}>\r\n {children}\r\n </div>\r\n );\r\n },\r\n);\r\nFormControl.displayName = \"FormControl\";\r\n\r\n/**\r\n * Renders helper text that describes the current form control.\r\n *\r\n * @remarks\r\n * - Renders a `<p>` element\r\n * - Built on the shared form field metadata hook\r\n *\r\n * @example\r\n * ```tsx\r\n * <FormDescription>We'll never share your email.</FormDescription>\r\n * ```\r\n *\r\n * @see {@link https://developer.mozilla.org/docs/Web/HTML/Element/p | HTML paragraph element}\r\n */\r\nconst FormDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(({className, ...props}, ref) => {\r\n const {formDescriptionId} = useFormField();\r\n\r\n return (\r\n <p\r\n ref={ref}\r\n id={formDescriptionId}\r\n className={cn(styles.description, className)}\r\n {...props}\r\n />\r\n );\r\n});\r\nFormDescription.displayName = \"FormDescription\";\r\n\r\n/**\r\n * Renders the validation message or fallback message for the current form control.\r\n *\r\n * @remarks\r\n * - Renders a `<p>` element when content is available\r\n * - Built on the shared form field metadata hook\r\n *\r\n * @example\r\n * ```tsx\r\n * <FormMessage />\r\n * ```\r\n *\r\n * @see {@link https://developer.mozilla.org/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-invalid | ARIA invalid state}\r\n */\r\nconst FormMessage = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(\r\n ({className, children, ...props}, ref) => {\r\n const {error, formMessageId} = useFormField();\r\n const body = error ? String(error.message ?? \"\") : children;\r\n\r\n if (!body) {\r\n return null;\r\n }\r\n\r\n return (\r\n <p\r\n ref={ref}\r\n id={formMessageId}\r\n className={cn(styles.message, className)}\r\n {...props}>\r\n {body}\r\n </p>\r\n );\r\n },\r\n);\r\nFormMessage.displayName = \"FormMessage\";\r\nFormField.displayName = \"FormField\";\r\n\r\nexport {Controller, useController, useFieldArray, useForm, useFormContext, useFormState, useWatch} from \"react-hook-form\";\r\nexport type {\r\n Control,\r\n ControllerFieldState,\r\n ControllerProps,\r\n ControllerRenderProps,\r\n DefaultValues,\r\n FieldError,\r\n FieldErrors,\r\n FieldPath,\r\n FieldValues,\r\n Path,\r\n RegisterOptions,\r\n Resolver,\r\n SubmitHandler,\r\n UseControllerReturn,\r\n UseFieldArrayReturn,\r\n UseFormReturn,\r\n} from \"react-hook-form\";\r\nexport {Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, useFormField};\r\nexport type {FormControlProps};\r\n"],"names":["Form","Object","FormProvider","assignRef","ref","value","composeRefs","refs","mergeAriaDescribedBy","describedByValues","tokens","describedByValue","token","Set","undefined","FormFieldContext","React","FormField","props","Controller","useFormField","fieldContext","itemContext","FormItemContext","getFieldState","formState","useFormContext","Error","fieldState","id","FormItem","className","cn","styles","FormLabel","error","formItemId","FormControl","children","formDescriptionId","formMessageId","describedBy","child","childDescribedBy","Boolean","FormDescription","FormMessage","body","String"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"components/ui/form.js","sources":["../../../src/components/ui/form.tsx"],"sourcesContent":["\"use client\";\r\n\r\n/* eslint-disable react/prop-types */\r\n\r\nimport * as React from \"react\";\r\nimport {\r\n Controller,\r\n FormProvider,\r\n useController,\r\n useFieldArray,\r\n useForm,\r\n useFormContext,\r\n useFormState,\r\n useWatch,\r\n type Control,\r\n type ControllerFieldState,\r\n type ControllerProps,\r\n type ControllerRenderProps,\r\n type DefaultValues,\r\n type FieldError,\r\n type FieldErrors,\r\n type FieldPath,\r\n type FieldValues,\r\n type Path,\r\n type RegisterOptions,\r\n type Resolver,\r\n type SubmitHandler,\r\n type UseControllerReturn,\r\n type UseFieldArrayReturn,\r\n type UseFormReturn,\r\n} from \"react-hook-form\";\r\n\r\nimport {cn} from \"@/lib/utilities\";\r\n\r\nimport styles from \"./form.module.css\";\r\n\r\n/**\r\n * Provides the `react-hook-form` context to nested form primitives.\r\n *\r\n * @remarks\r\n * - Renders the `FormProvider` component from `react-hook-form`\r\n * - Built on `react-hook-form`\r\n *\r\n * @example\r\n * ```tsx\r\n * <Form {...form}>\r\n * <form>...</form>\r\n * </Form>\r\n * ```\r\n *\r\n * @see {@link https://react-hook-form.com/docs/formprovider | React Hook Form FormProvider Docs}\r\n */\r\nconst Form = Object.assign(FormProvider, {displayName: \"Form\"});\r\n\r\ntype FormControlElementProps = React.HTMLAttributes<HTMLElement> & {\r\n ref?: React.Ref<HTMLElement>;\r\n};\r\n\r\ninterface FormControlProps extends Omit<React.HTMLAttributes<HTMLElement>, \"children\"> {\r\n /**\r\n * Single form control element or fallback content to receive field accessibility attributes.\r\n * @default undefined\r\n */\r\n children: React.ReactNode;\r\n}\r\n\r\nfunction assignRef<TValue>(ref: React.Ref<TValue> | undefined, value: TValue | null): void {\r\n if (typeof ref === \"function\") {\r\n ref(value);\r\n return;\r\n }\r\n\r\n if (ref) {\r\n ref.current = value;\r\n }\r\n}\r\n\r\nfunction composeRefs<TValue>(...refs: Array<React.Ref<TValue> | undefined>): React.RefCallback<TValue> {\r\n return (value: TValue | null): void => {\r\n for (const ref of refs) {\r\n assignRef(ref, value);\r\n }\r\n };\r\n}\r\n\r\nfunction mergeAriaDescribedBy(...describedByValues: Array<string | undefined>): string | undefined {\r\n const tokens = describedByValues\r\n .flatMap((describedByValue) => describedByValue?.split(/\\s+/u) ?? [])\r\n .filter((token): token is string => token.length > 0);\r\n\r\n return tokens.length > 0 ? [...new Set(tokens)].join(\" \") : undefined;\r\n}\r\n\r\ntype FormFieldContextValue<\r\n TFieldValues extends FieldValues = FieldValues,\r\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\r\n> = {\r\n name: TName;\r\n};\r\n\r\nconst FormFieldContext = React.createContext<FormFieldContextValue | null>(null);\r\n\r\n/**\r\n * Binds a single field name to the shared form field context.\r\n *\r\n * @remarks\r\n * - Renders the `Controller` component from `react-hook-form`\r\n * - Built on `react-hook-form` controller primitives\r\n *\r\n * @example\r\n * ```tsx\r\n * <FormField\r\n * control={form.control}\r\n * name='email'\r\n * render={({field}) => <input {...field} />}\r\n * />\r\n * ```\r\n *\r\n * @see {@link https://react-hook-form.com/docs/usecontroller/controller | React Hook Form Controller Docs}\r\n */\r\nconst FormField = <TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({\r\n ...props\r\n}: ControllerProps<TFieldValues, TName>): React.JSX.Element => {\r\n return (\r\n <FormFieldContext.Provider value={{name: props.name}}>\r\n <Controller {...props} />\r\n </FormFieldContext.Provider>\r\n );\r\n};\r\n\r\ntype UseFormFieldReturn = {\r\n id: string;\r\n name: FieldPath<FieldValues>;\r\n formItemId: string;\r\n formDescriptionId: string;\r\n formMessageId: string;\r\n invalid: boolean;\r\n isDirty: boolean;\r\n isTouched: boolean;\r\n isValidating: boolean;\r\n error?: ReturnType<ReturnType<typeof useFormContext>[\"getFieldState\"]>[\"error\"];\r\n};\r\n\r\n/**\r\n * Returns the resolved form field metadata for nested form primitives.\r\n *\r\n * @remarks\r\n * Reads the nearest {@link FormField} and {@link FormItem} contexts, then combines them\r\n * with `react-hook-form` field state to expose stable IDs and validation metadata.\r\n *\r\n * @example\r\n * ```tsx\r\n * const field = useFormField();\r\n * ```\r\n *\r\n * @see {@link https://react-hook-form.com/docs/useformcontext | React Hook Form useFormContext Docs}\r\n */\r\nconst useFormField = (): UseFormFieldReturn => {\r\n const fieldContext = React.useContext(FormFieldContext);\r\n const itemContext = React.useContext(FormItemContext);\r\n const {getFieldState, formState} = useFormContext();\r\n\r\n if (!fieldContext) {\r\n throw new Error(\"useFormField should be used within <FormField>\");\r\n }\r\n\r\n if (!itemContext) {\r\n throw new Error(\"useFormField should be used within <FormItem>\");\r\n }\r\n\r\n const fieldState = getFieldState(fieldContext.name, formState);\r\n const {id} = itemContext;\r\n\r\n return {\r\n error: fieldState.error,\r\n formDescriptionId: `${id}-form-item-description`,\r\n formItemId: `${id}-form-item`,\r\n formMessageId: `${id}-form-item-message`,\r\n id,\r\n invalid: fieldState.invalid,\r\n isDirty: fieldState.isDirty,\r\n isTouched: fieldState.isTouched,\r\n isValidating: fieldState.isValidating,\r\n name: fieldContext.name as FieldPath<FieldValues>,\r\n };\r\n};\r\n\r\ntype FormItemContextValue = {\r\n id: string;\r\n};\r\n\r\nconst FormItemContext = React.createContext<FormItemContextValue | null>(null);\r\n\r\n/**\r\n * Wraps a label, control, description, and message into a single form item.\r\n *\r\n * @remarks\r\n * - Renders a `<div>` element\r\n * - Built on the shared form item context\r\n *\r\n * @example\r\n * ```tsx\r\n * <FormItem>\r\n * <FormLabel>Email</FormLabel>\r\n * </FormItem>\r\n * ```\r\n *\r\n * @see {@link https://react-hook-form.com/docs/useformcontext | React Hook Form Docs}\r\n */\r\nconst FormItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(({className, ...props}, ref) => {\r\n const id = React.useId();\r\n\r\n return (\r\n <FormItemContext.Provider value={{id}}>\r\n <div\r\n ref={ref}\r\n className={cn(styles.item, className)}\r\n {...props}\r\n />\r\n </FormItemContext.Provider>\r\n );\r\n});\r\nFormItem.displayName = \"FormItem\";\r\n\r\n/**\r\n * Renders the accessible label for the current form item.\r\n *\r\n * @remarks\r\n * - Renders a `<label>` element\r\n * - Built on the shared form field metadata hook\r\n *\r\n * @example\r\n * ```tsx\r\n * <FormLabel>Email</FormLabel>\r\n * ```\r\n *\r\n * @see {@link https://developer.mozilla.org/docs/Web/HTML/Element/label | HTML label element}\r\n */\r\nconst FormLabel = React.forwardRef<HTMLLabelElement, React.LabelHTMLAttributes<HTMLLabelElement>>(({className, ...props}, ref) => {\r\n const {error, formItemId} = useFormField();\r\n\r\n return (\r\n <label\r\n ref={ref}\r\n className={cn(error && styles.labelError, className)}\r\n htmlFor={formItemId}\r\n {...props}\r\n />\r\n );\r\n});\r\nFormLabel.displayName = \"FormLabel\";\r\n\r\n/**\r\n * Provides react-hook-form field metadata to a single control element.\r\n *\r\n * @remarks\r\n * This replaces the former Radix Slot-based implementation by cloning the\r\n * direct child element and merging the accessibility attributes required by the\r\n * surrounding form primitives. A fallback wrapper is rendered only when the\r\n * child is not a valid React element.\r\n */\r\nconst FormControl = React.forwardRef<HTMLElement, FormControlProps>(\r\n ({children, ...props}: Readonly<FormControlProps>, ref): React.JSX.Element => {\r\n const {error, formDescriptionId, formItemId, formMessageId} = useFormField();\r\n const describedBy = mergeAriaDescribedBy(\r\n typeof props[\"aria-describedby\"] === \"string\" ? props[\"aria-describedby\"] : undefined,\r\n formDescriptionId,\r\n error ? formMessageId : undefined,\r\n );\r\n\r\n if (React.isValidElement(children)) {\r\n const child = children as React.ReactElement<FormControlElementProps>;\r\n const childDescribedBy = typeof child.props[\"aria-describedby\"] === \"string\" ? child.props[\"aria-describedby\"] : undefined;\r\n\r\n // eslint-disable-next-line react-x/no-clone-element -- removes Radix Slot while preserving child element semantics\r\n return React.cloneElement(child, {\r\n ...props,\r\n ref: composeRefs(ref, child.props.ref),\r\n id: formItemId,\r\n \"aria-describedby\": mergeAriaDescribedBy(childDescribedBy, describedBy),\r\n \"aria-invalid\": Boolean(error),\r\n });\r\n }\r\n\r\n return (\r\n <div\r\n ref={ref as React.Ref<HTMLDivElement>}\r\n id={formItemId}\r\n aria-describedby={describedBy}\r\n aria-invalid={Boolean(error)}\r\n {...props}>\r\n {children}\r\n </div>\r\n );\r\n },\r\n);\r\nFormControl.displayName = \"FormControl\";\r\n\r\n/**\r\n * Renders helper text that describes the current form control.\r\n *\r\n * @remarks\r\n * - Renders a `<p>` element\r\n * - Built on the shared form field metadata hook\r\n *\r\n * @example\r\n * ```tsx\r\n * <FormDescription>We'll never share your email.</FormDescription>\r\n * ```\r\n *\r\n * @see {@link https://developer.mozilla.org/docs/Web/HTML/Element/p | HTML paragraph element}\r\n */\r\nconst FormDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(({className, ...props}, ref) => {\r\n const {formDescriptionId} = useFormField();\r\n\r\n return (\r\n <p\r\n ref={ref}\r\n id={formDescriptionId}\r\n className={cn(styles.description, className)}\r\n {...props}\r\n />\r\n );\r\n});\r\nFormDescription.displayName = \"FormDescription\";\r\n\r\n/**\r\n * Renders the validation message or fallback message for the current form control.\r\n *\r\n * @remarks\r\n * - Renders a `<p>` element when content is available\r\n * - Built on the shared form field metadata hook\r\n *\r\n * @example\r\n * ```tsx\r\n * <FormMessage />\r\n * ```\r\n *\r\n * @see {@link https://developer.mozilla.org/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-invalid | ARIA invalid state}\r\n */\r\nconst FormMessage = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(\r\n ({className, children, ...props}, ref) => {\r\n const {error, formMessageId} = useFormField();\r\n const body = error ? String(error.message ?? \"\") : children;\r\n\r\n if (!body) {\r\n return null;\r\n }\r\n\r\n return (\r\n <p\r\n ref={ref}\r\n id={formMessageId}\r\n className={cn(styles.message, className)}\r\n {...props}>\r\n {body}\r\n </p>\r\n );\r\n },\r\n);\r\nFormMessage.displayName = \"FormMessage\";\r\nFormField.displayName = \"FormField\";\r\n\r\nexport {Controller, useController, useFieldArray, useForm, useFormContext, useFormState, useWatch};\r\nexport type {\r\n Control,\r\n ControllerFieldState,\r\n ControllerProps,\r\n ControllerRenderProps,\r\n DefaultValues,\r\n FieldError,\r\n FieldErrors,\r\n FieldPath,\r\n FieldValues,\r\n Path,\r\n RegisterOptions,\r\n Resolver,\r\n SubmitHandler,\r\n UseControllerReturn,\r\n UseFieldArrayReturn,\r\n UseFormReturn,\r\n};\r\nexport {Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, useFormField};\r\nexport type {FormControlProps};\r\n"],"names":["Form","Object","FormProvider","assignRef","ref","value","composeRefs","refs","mergeAriaDescribedBy","describedByValues","tokens","describedByValue","token","Set","undefined","FormFieldContext","React","FormField","props","Controller","useFormField","fieldContext","itemContext","FormItemContext","getFieldState","formState","useFormContext","Error","fieldState","id","FormItem","className","cn","styles","FormLabel","error","formItemId","FormControl","children","formDescriptionId","formMessageId","describedBy","child","childDescribedBy","Boolean","FormDescription","FormMessage","body","String"],"mappings":";;;;;;AAoDA,MAAMA,OAAOC,OAAO,MAAM,CAACC,cAAc;IAAC,aAAa;AAAM;AAc7D,SAASC,UAAkBC,GAAkC,EAAEC,KAAoB;IACjF,IAAI,AAAe,cAAf,OAAOD,KAAoB,YAC7BA,IAAIC;IAIN,IAAID,KACFA,IAAI,OAAO,GAAGC;AAElB;AAEA,SAASC,YAAoB,GAAGC,IAA0C;IACxE,OAAO,CAACF;QACN,KAAK,MAAMD,OAAOG,KAChBJ,UAAUC,KAAKC;IAEnB;AACF;AAEA,SAASG,qBAAqB,GAAGC,iBAA4C;IAC3E,MAAMC,SAASD,kBACZ,OAAO,CAAC,CAACE,mBAAqBA,kBAAkB,MAAM,WAAW,EAAE,EACnE,MAAM,CAAC,CAACC,QAA2BA,MAAM,MAAM,GAAG;IAErD,OAAOF,OAAO,MAAM,GAAG,IAAI;WAAI,IAAIG,IAAIH;KAAQ,CAAC,IAAI,CAAC,OAAOI;AAC9D;AASA,MAAMC,mBAAmB,WAAHA,GAAGC,wBAAAA,aAAmB,CAA+B;AAoB3E,MAAMC,YAAY,CAAkH,EAClI,GAAGC,OACkC,GAC9B,WAAP,GACE,IAACH,iBAAiB,QAAQ;QAAC,OAAO;YAAC,MAAMG,MAAM,IAAI;QAAA;kBACjD,kBAACC,YAAUA;YAAE,GAAGD,KAAK;;;AAgC3B,MAAME,eAAe;IACnB,MAAMC,eAAeL,wBAAAA,UAAgB,CAACD;IACtC,MAAMO,cAAcN,wBAAAA,UAAgB,CAACO;IACrC,MAAM,EAACC,aAAa,EAAEC,SAAS,EAAC,GAAGC;IAEnC,IAAI,CAACL,cACH,MAAM,IAAIM,MAAM;IAGlB,IAAI,CAACL,aACH,MAAM,IAAIK,MAAM;IAGlB,MAAMC,aAAaJ,cAAcH,aAAa,IAAI,EAAEI;IACpD,MAAM,EAACI,EAAE,EAAC,GAAGP;IAEb,OAAO;QACL,OAAOM,WAAW,KAAK;QACvB,mBAAmB,GAAGC,GAAG,sBAAsB,CAAC;QAChD,YAAY,GAAGA,GAAG,UAAU,CAAC;QAC7B,eAAe,GAAGA,GAAG,kBAAkB,CAAC;QACxCA;QACA,SAASD,WAAW,OAAO;QAC3B,SAASA,WAAW,OAAO;QAC3B,WAAWA,WAAW,SAAS;QAC/B,cAAcA,WAAW,YAAY;QACrC,MAAMP,aAAa,IAAI;IACzB;AACF;AAMA,MAAME,kBAAkB,WAAHA,GAAGP,wBAAAA,aAAmB,CAA8B;AAkBzE,MAAMc,WAAW,WAAHA,GAAGd,wBAAAA,UAAgB,CAAuD,CAAC,EAACe,SAAS,EAAE,GAAGb,OAAM,EAAEd;IAC9G,MAAMyB,KAAKb,wBAAAA,KAAW;IAEtB,OAAO,WAAP,GACE,IAACO,gBAAgB,QAAQ;QAAC,OAAO;YAACM;QAAE;kBAClC,kBAAC;YACC,KAAKzB;YACL,WAAW4B,GAAGC,YAAAA,IAAW,EAAEF;YAC1B,GAAGb,KAAK;;;AAIjB;AACAY,SAAS,WAAW,GAAG;AAgBvB,MAAMI,YAAY,WAAHA,GAAGlB,wBAAAA,UAAgB,CAAgE,CAAC,EAACe,SAAS,EAAE,GAAGb,OAAM,EAAEd;IACxH,MAAM,EAAC+B,KAAK,EAAEC,UAAU,EAAC,GAAGhB;IAE5B,OAAO,WAAP,GACE,IAAC;QACC,KAAKhB;QACL,WAAW4B,GAAGG,SAASF,YAAAA,UAAiB,EAAEF;QAC1C,SAASK;QACR,GAAGlB,KAAK;;AAGf;AACAgB,UAAU,WAAW,GAAG;AAWxB,MAAMG,cAAc,WAAHA,GAAGrB,wBAAAA,UAAgB,CAClC,CAAC,EAACsB,QAAQ,EAAE,GAAGpB,OAAkC,EAAEd;IACjD,MAAM,EAAC+B,KAAK,EAAEI,iBAAiB,EAAEH,UAAU,EAAEI,aAAa,EAAC,GAAGpB;IAC9D,MAAMqB,cAAcjC,qBAClB,AAAqC,YAArC,OAAOU,KAAK,CAAC,mBAAmB,GAAgBA,KAAK,CAAC,mBAAmB,GAAGJ,QAC5EyB,mBACAJ,QAAQK,gBAAgB1B;IAG1B,IAAI,WAAJ,GAAIE,wBAAAA,cAAoB,CAACsB,WAAW;QAClC,MAAMI,QAAQJ;QACd,MAAMK,mBAAmB,AAA2C,YAA3C,OAAOD,MAAM,KAAK,CAAC,mBAAmB,GAAgBA,MAAM,KAAK,CAAC,mBAAmB,GAAG5B;QAGjH,OAAO,WAAP,GAAOE,wBAAAA,YAAkB,CAAC0B,OAAO;YAC/B,GAAGxB,KAAK;YACR,KAAKZ,YAAYF,KAAKsC,MAAM,KAAK,CAAC,GAAG;YACrC,IAAIN;YACJ,oBAAoB5B,qBAAqBmC,kBAAkBF;YAC3D,gBAAgBG,QAAQT;QAC1B;IACF;IAEA,OAAO,WAAP,GACE,IAAC;QACC,KAAK/B;QACL,IAAIgC;QACJ,oBAAkBK;QAClB,gBAAcG,QAAQT;QACrB,GAAGjB,KAAK;kBACRoB;;AAGP;AAEFD,YAAY,WAAW,GAAG;AAgB1B,MAAMQ,kBAAkB,WAAHA,GAAG7B,wBAAAA,UAAgB,CAAmE,CAAC,EAACe,SAAS,EAAE,GAAGb,OAAM,EAAEd;IACjI,MAAM,EAACmC,iBAAiB,EAAC,GAAGnB;IAE5B,OAAO,WAAP,GACE,IAAC;QACC,KAAKhB;QACL,IAAImC;QACJ,WAAWP,GAAGC,YAAAA,WAAkB,EAAEF;QACjC,GAAGb,KAAK;;AAGf;AACA2B,gBAAgB,WAAW,GAAG;AAgB9B,MAAMC,cAAc,WAAHA,GAAG9B,wBAAAA,UAAgB,CAClC,CAAC,EAACe,SAAS,EAAEO,QAAQ,EAAE,GAAGpB,OAAM,EAAEd;IAChC,MAAM,EAAC+B,KAAK,EAAEK,aAAa,EAAC,GAAGpB;IAC/B,MAAM2B,OAAOZ,QAAQa,OAAOb,MAAM,OAAO,IAAI,MAAMG;IAEnD,IAAI,CAACS,MACH,OAAO;IAGT,OAAO,WAAP,GACE,IAAC;QACC,KAAK3C;QACL,IAAIoC;QACJ,WAAWR,GAAGC,YAAAA,OAAc,EAAEF;QAC7B,GAAGb,KAAK;kBACR6B;;AAGP;AAEFD,YAAY,WAAW,GAAG;AAC1B7B,UAAU,WAAW,GAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["webpack
|
|
1
|
+
{"version":3,"sources":["webpack://./../../node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].oneOf[2].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].oneOf[2].use[2]!/home/runner/work/arolariu.ro/arolariu.ro/node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/postcss-loader/index.js??ruleSet[1].rules[1].oneOf[2].use[3]!/home/runner/work/arolariu.ro/arolariu.ro/packages/components/src/components/ui/form.module.css","webpack://./src/components/ui/form.module.css"],"names":[],"mappings":"AAAA;ECCE,sBAAsB;EACtB,aAAa;AACf;;ADHyC;ECMvC,4BAA4B;AAC9B;;ADPiF;ECU/E,iCAAiC;EACjC,gBAAgB;AAClB;;ADZ+I;ECe7I,4BAA4B;EAC5B,gBAAgB;EAChB,gBAAgB;AAClB","sourcesContent":[".item{display:grid;gap:var(--ac-space-2)}.labelError{color:var(--ac-destructive)}.description{color:var(--ac-muted-foreground);font-size:.8rem}.message{color:var(--ac-destructive);font-size:.8rem;font-weight:500}",".item {\n gap: var(--ac-space-2);\n display: grid;\n}\n\n.labelError {\n color: var(--ac-destructive);\n}\n\n.description {\n color: var(--ac-muted-foreground);\n font-size: .8rem;\n}\n\n.message {\n color: var(--ac-destructive);\n font-size: .8rem;\n font-weight: 500;\n}\n"],"sourceRoot":""}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
import { motion } from "motion/react";
|
|
4
|
-
import { forwardRef } from "react";
|
|
5
4
|
import { cn } from "../../lib/utilities.js";
|
|
6
5
|
import gradient_background_module from "./gradient-background.module.js";
|
|
7
|
-
|
|
6
|
+
import * as __rspack_external_react from "react";
|
|
7
|
+
const GradientBackground = /*#__PURE__*/ __rspack_external_react.forwardRef(({ className, transition = {
|
|
8
8
|
duration: 15,
|
|
9
9
|
ease: "easeInOut",
|
|
10
10
|
repeat: 1 / 0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components/ui/gradient-background.js","sources":["../../../src/components/ui/gradient-background.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport {motion, type HTMLMotionProps, type Transition} from \"motion/react\";\r\nimport * as React from \"react\";\r\n\r\nimport {cn} from \"@/lib/utilities\";\r\nimport styles from \"./gradient-background.module.css\";\r\n\r\n/** Props accepted by {@link GradientBackground}. */\r\nexport interface GradientBackgroundProps extends HTMLMotionProps<\"div\"> {\r\n /** Motion timing used for the animated background-position sweep. @default {duration: 15, ease: \"easeInOut\", repeat: Infinity} */\r\n transition?: Transition;\r\n}\r\n\r\n/**\r\n * Renders a continuously shifting multicolor gradient background.\r\n *\r\n * @remarks\r\n * - Animated component using the `motion` library\r\n * - Renders a `<div>` element\r\n * - Styling via CSS Modules with `--ac-*` custom properties\r\n * - Client-side only (`\"use client\"` directive)\r\n *\r\n * @example\r\n * ```tsx\r\n * <GradientBackground />\r\n * ```\r\n *\r\n * @see {@link GradientBackgroundProps} for available props\r\n */\r\nconst GradientBackground = React.forwardRef<HTMLDivElement, GradientBackgroundProps>(\r\n ({className, transition = {duration: 15, ease: \"easeInOut\", repeat: Infinity}, ...props}, ref) => {\r\n // eslint-disable-next-line sonarjs/no-unused-vars -- removing React key avoids implicit key spreading\r\n const {key: _ignoredKey, ...restProps} = props;\r\n\r\n return (\r\n <motion.div\r\n ref={ref}\r\n className={cn(styles.root, className)}\r\n animate={{\r\n backgroundPosition: [\"0% 50%\", \"100% 50%\", \"0% 50%\"],\r\n }}\r\n transition={transition}\r\n {...restProps}\r\n />\r\n );\r\n },\r\n);\r\n\r\nGradientBackground.displayName = \"GradientBackground\";\r\n\r\nexport {GradientBackground};\r\n"],"names":["GradientBackground","React","className","transition","Infinity","props","ref","_ignoredKey","restProps","motion","cn","styles"],"mappings":";;;;;;AA8BA,MAAMA,qBAAqB,WAAHA,GAAGC,
|
|
1
|
+
{"version":3,"file":"components/ui/gradient-background.js","sources":["../../../src/components/ui/gradient-background.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport {motion, type HTMLMotionProps, type Transition} from \"motion/react\";\r\nimport * as React from \"react\";\r\n\r\nimport {cn} from \"@/lib/utilities\";\r\nimport styles from \"./gradient-background.module.css\";\r\n\r\n/** Props accepted by {@link GradientBackground}. */\r\nexport interface GradientBackgroundProps extends HTMLMotionProps<\"div\"> {\r\n /** Motion timing used for the animated background-position sweep. @default {duration: 15, ease: \"easeInOut\", repeat: Infinity} */\r\n transition?: Transition;\r\n}\r\n\r\n/**\r\n * Renders a continuously shifting multicolor gradient background.\r\n *\r\n * @remarks\r\n * - Animated component using the `motion` library\r\n * - Renders a `<div>` element\r\n * - Styling via CSS Modules with `--ac-*` custom properties\r\n * - Client-side only (`\"use client\"` directive)\r\n *\r\n * @example\r\n * ```tsx\r\n * <GradientBackground />\r\n * ```\r\n *\r\n * @see {@link GradientBackgroundProps} for available props\r\n */\r\nconst GradientBackground = React.forwardRef<HTMLDivElement, GradientBackgroundProps>(\r\n ({className, transition = {duration: 15, ease: \"easeInOut\", repeat: Infinity}, ...props}, ref) => {\r\n // eslint-disable-next-line sonarjs/no-unused-vars -- removing React key avoids implicit key spreading\r\n const {key: _ignoredKey, ...restProps} = props;\r\n\r\n return (\r\n <motion.div\r\n ref={ref}\r\n className={cn(styles.root, className)}\r\n animate={{\r\n backgroundPosition: [\"0% 50%\", \"100% 50%\", \"0% 50%\"],\r\n }}\r\n transition={transition}\r\n {...restProps}\r\n />\r\n );\r\n },\r\n);\r\n\r\nGradientBackground.displayName = \"GradientBackground\";\r\n\r\nexport {GradientBackground};\r\n"],"names":["GradientBackground","React","className","transition","Infinity","props","ref","_ignoredKey","restProps","motion","cn","styles"],"mappings":";;;;;;AA8BA,MAAMA,qBAAqB,WAAHA,GAAGC,wBAAAA,UAAgB,CACzC,CAAC,EAACC,SAAS,EAAEC,aAAa;IAAC,UAAU;IAAI,MAAM;IAAa,QAAQC;AAAQ,CAAC,EAAE,GAAGC,OAAM,EAAEC;IAExF,MAAM,EAAC,KAAKC,WAAW,EAAE,GAAGC,WAAU,GAAGH;IAEzC,OAAO,WAAP,GACE,IAACI,OAAO,GAAG;QACT,KAAKH;QACL,WAAWI,GAAGC,2BAAAA,IAAW,EAAET;QAC3B,SAAS;YACP,oBAAoB;gBAAC;gBAAU;gBAAY;aAAS;QACtD;QACA,YAAYC;QACX,GAAGK,SAAS;;AAGnB;AAGFR,mBAAmB,WAAW,GAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["webpack
|
|
1
|
+
{"version":3,"sources":["webpack://./../../node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].oneOf[2].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].oneOf[2].use[2]!/home/runner/work/arolariu.ro/arolariu.ro/node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/postcss-loader/index.js??ruleSet[1].rules[1].oneOf[2].use[3]!/home/runner/work/arolariu.ro/arolariu.ro/packages/components/src/components/ui/gradient-background.module.css","webpack://./src/components/ui/gradient-background.module.css"],"names":[],"mappings":"AAAA;ECCE,wEAAwE;EACxE,0BAA0B;EAC1B,WAAW;EACX,YAAY;AACd","sourcesContent":[".root{background-image:linear-gradient(135deg,#3b82f6,#a855f7 50%,#ec4899);background-size:400% 400%;height:100%;width:100%}",".root {\n background-image: linear-gradient(135deg, #3b82f6, #a855f7 50%, #ec4899);\n background-size: 400% 400%;\n width: 100%;\n height: 100%;\n}\n"],"sourceRoot":""}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { motion } from "motion/react";
|
|
4
|
-
import { forwardRef } from "react";
|
|
5
4
|
import { cn } from "../../lib/utilities.js";
|
|
6
5
|
import gradient_text_module from "./gradient-text.module.js";
|
|
7
|
-
|
|
6
|
+
import * as __rspack_external_react from "react";
|
|
7
|
+
const GradientText = /*#__PURE__*/ __rspack_external_react.forwardRef(({ text, className, gradient = "linear-gradient(90deg, #3b82f6 0%, #a855f7 20%, #ec4899 50%, #a855f7 80%, #3b82f6 100%)", neon = false, transition = {
|
|
8
8
|
duration: 50,
|
|
9
9
|
repeat: 1 / 0,
|
|
10
10
|
ease: "linear"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components/ui/gradient-text.js","sources":["../../../src/components/ui/gradient-text.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport {motion, type Transition} from \"motion/react\";\r\nimport * as React from \"react\";\r\n\r\nimport {cn} from \"@/lib/utilities\";\r\nimport styles from \"./gradient-text.module.css\";\r\n\r\n/** Props accepted by {@link GradientText}. */\r\nexport interface GradientTextProps extends React.HTMLAttributes<HTMLSpanElement> {\r\n /** Text content rendered with the animated gradient fill. @default undefined */\r\n text: string;\r\n /** CSS gradient string assigned to the animated text fill. @default \"linear-gradient(90deg, #3b82f6 0%, #a855f7 20%, #ec4899 50%, #a855f7 80%, #3b82f6 100%)\" */\r\n gradient?: string;\r\n /** Adds a blurred neon duplicate behind the primary text layer. @default false */\r\n neon?: boolean;\r\n /** Motion timing used for the animated gradient background. @default {duration: 50, repeat: Infinity, ease: \"linear\"} */\r\n transition?: Transition;\r\n}\r\n\r\ntype GradientStyleProperties = React.CSSProperties & {\r\n \"--ac-gradient-text-background\": string;\r\n};\r\n\r\n/**\r\n * Renders animated gradient-filled text with an optional neon glow layer.\r\n *\r\n * @remarks\r\n * - Animated component using the `motion` library\r\n * - Renders a `<span>` element\r\n * - Styling via CSS Modules with `--ac-*` custom properties\r\n * - Client-side only (`\"use client\"` directive)\r\n *\r\n * @example\r\n * ```tsx\r\n * <GradientText text=\"Launch ready\" />\r\n * ```\r\n *\r\n * @see {@link GradientTextProps} for available props\r\n */\r\nconst GradientText = React.forwardRef<HTMLSpanElement, GradientTextProps>(\r\n (\r\n {\r\n text,\r\n className,\r\n gradient = \"linear-gradient(90deg, #3b82f6 0%, #a855f7 20%, #ec4899 50%, #a855f7 80%, #3b82f6 100%)\",\r\n neon = false,\r\n transition = {duration: 50, repeat: Infinity, ease: \"linear\"},\r\n ...props\r\n },\r\n ref,\r\n ) => {\r\n const baseStyle: GradientStyleProperties = {\r\n \"--ac-gradient-text-background\": gradient,\r\n };\r\n\r\n return (\r\n <span\r\n ref={ref}\r\n className={cn(styles.root, className)}\r\n {...props}>\r\n <motion.span\r\n className={styles.text}\r\n style={baseStyle}\r\n initial={{backgroundPosition: \"0% 0%\"}}\r\n animate={{backgroundPosition: \"500% 100%\"}}\r\n transition={transition}>\r\n {text}\r\n </motion.span>\r\n\r\n {neon ? (\r\n <motion.span\r\n aria-hidden='true'\r\n className={styles.neon}\r\n style={baseStyle}\r\n initial={{backgroundPosition: \"0% 0%\"}}\r\n animate={{backgroundPosition: \"500% 100%\"}}\r\n transition={transition}>\r\n {text}\r\n </motion.span>\r\n ) : null}\r\n </span>\r\n );\r\n },\r\n);\r\n\r\nGradientText.displayName = \"GradientText\";\r\n\r\nexport {GradientText};\r\n"],"names":["GradientText","React","text","className","gradient","neon","transition","Infinity","props","ref","baseStyle","cn","styles","motion"],"mappings":";;;;;;AAwCA,MAAMA,eAAe,WAAHA,GAAGC,
|
|
1
|
+
{"version":3,"file":"components/ui/gradient-text.js","sources":["../../../src/components/ui/gradient-text.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport {motion, type Transition} from \"motion/react\";\r\nimport * as React from \"react\";\r\n\r\nimport {cn} from \"@/lib/utilities\";\r\nimport styles from \"./gradient-text.module.css\";\r\n\r\n/** Props accepted by {@link GradientText}. */\r\nexport interface GradientTextProps extends React.HTMLAttributes<HTMLSpanElement> {\r\n /** Text content rendered with the animated gradient fill. @default undefined */\r\n text: string;\r\n /** CSS gradient string assigned to the animated text fill. @default \"linear-gradient(90deg, #3b82f6 0%, #a855f7 20%, #ec4899 50%, #a855f7 80%, #3b82f6 100%)\" */\r\n gradient?: string;\r\n /** Adds a blurred neon duplicate behind the primary text layer. @default false */\r\n neon?: boolean;\r\n /** Motion timing used for the animated gradient background. @default {duration: 50, repeat: Infinity, ease: \"linear\"} */\r\n transition?: Transition;\r\n}\r\n\r\ntype GradientStyleProperties = React.CSSProperties & {\r\n \"--ac-gradient-text-background\": string;\r\n};\r\n\r\n/**\r\n * Renders animated gradient-filled text with an optional neon glow layer.\r\n *\r\n * @remarks\r\n * - Animated component using the `motion` library\r\n * - Renders a `<span>` element\r\n * - Styling via CSS Modules with `--ac-*` custom properties\r\n * - Client-side only (`\"use client\"` directive)\r\n *\r\n * @example\r\n * ```tsx\r\n * <GradientText text=\"Launch ready\" />\r\n * ```\r\n *\r\n * @see {@link GradientTextProps} for available props\r\n */\r\nconst GradientText = React.forwardRef<HTMLSpanElement, GradientTextProps>(\r\n (\r\n {\r\n text,\r\n className,\r\n gradient = \"linear-gradient(90deg, #3b82f6 0%, #a855f7 20%, #ec4899 50%, #a855f7 80%, #3b82f6 100%)\",\r\n neon = false,\r\n transition = {duration: 50, repeat: Infinity, ease: \"linear\"},\r\n ...props\r\n },\r\n ref,\r\n ) => {\r\n const baseStyle: GradientStyleProperties = {\r\n \"--ac-gradient-text-background\": gradient,\r\n };\r\n\r\n return (\r\n <span\r\n ref={ref}\r\n className={cn(styles.root, className)}\r\n {...props}>\r\n <motion.span\r\n className={styles.text}\r\n style={baseStyle}\r\n initial={{backgroundPosition: \"0% 0%\"}}\r\n animate={{backgroundPosition: \"500% 100%\"}}\r\n transition={transition}>\r\n {text}\r\n </motion.span>\r\n\r\n {neon ? (\r\n <motion.span\r\n aria-hidden='true'\r\n className={styles.neon}\r\n style={baseStyle}\r\n initial={{backgroundPosition: \"0% 0%\"}}\r\n animate={{backgroundPosition: \"500% 100%\"}}\r\n transition={transition}>\r\n {text}\r\n </motion.span>\r\n ) : null}\r\n </span>\r\n );\r\n },\r\n);\r\n\r\nGradientText.displayName = \"GradientText\";\r\n\r\nexport {GradientText};\r\n"],"names":["GradientText","React","text","className","gradient","neon","transition","Infinity","props","ref","baseStyle","cn","styles","motion"],"mappings":";;;;;;AAwCA,MAAMA,eAAe,WAAHA,GAAGC,wBAAAA,UAAgB,CACnC,CACE,EACEC,IAAI,EACJC,SAAS,EACTC,WAAW,yFAAyF,EACpGC,OAAO,KAAK,EACZC,aAAa;IAAC,UAAU;IAAI,QAAQC;IAAU,MAAM;AAAQ,CAAC,EAC7D,GAAGC,OACJ,EACDC;IAEA,MAAMC,YAAqC;QACzC,iCAAiCN;IACnC;IAEA,OAAO,WAAP,GACE,KAAC;QACC,KAAKK;QACL,WAAWE,GAAGC,qBAAAA,IAAW,EAAET;QAC1B,GAAGK,KAAK;;0BACT,IAACK,OAAO,IAAI;gBACV,WAAWD,qBAAAA,IAAW;gBACtB,OAAOF;gBACP,SAAS;oBAAC,oBAAoB;gBAAO;gBACrC,SAAS;oBAAC,oBAAoB;gBAAW;gBACzC,YAAYJ;0BACXJ;;YAGFG,OAAO,WAAPA,GACC,IAACQ,OAAO,IAAI;gBACV,eAAY;gBACZ,WAAWD,qBAAAA,IAAW;gBACtB,OAAOF;gBACP,SAAS;oBAAC,oBAAoB;gBAAO;gBACrC,SAAS;oBAAC,oBAAoB;gBAAW;gBACzC,YAAYJ;0BACXJ;iBAED;;;AAGV;AAGFF,aAAa,WAAW,GAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["webpack
|
|
1
|
+
{"version":3,"sources":["webpack://./../../node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].oneOf[2].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].oneOf[2].use[2]!/home/runner/work/arolariu.ro/arolariu.ro/node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/postcss-loader/index.js??ruleSet[1].rules[1].oneOf[2].use[3]!/home/runner/work/arolariu.ro/arolariu.ro/packages/components/src/components/ui/gradient-text.module.css","webpack://./src/components/ui/gradient-text.module.css"],"names":[],"mappings":"AAAA;ECCE,qBAAqB;EACrB,kBAAkB;AACpB;;ADH6C;ECM3C,qBAAqB;EACrB,oDAAoD;EACpD,YAAY;EACZ,wBAAwB;EACxB,0BAA0B;EAC1B,SAAS;AACX;;ADZ4O;ECe1O,iBAAiB;EACjB,4BAA4B;EAC5B,oBAAoB;EACpB,kBAAkB;EAClB,QAAQ;AACV","sourcesContent":[".root{display:inline-block;position:relative}.neon,.text{-webkit-background-clip:text;background-clip:text;background-image:var(--ac-gradient-text-background);background-position:0 0;background-size:700% 100%;color:transparent;margin:0}.neon{filter:blur(8px);inset:0;mix-blend-mode:plus-lighter;pointer-events:none;position:absolute}",".root {\n display: inline-block;\n position: relative;\n}\n\n.neon, .text {\n background-clip: text;\n background-image: var(--ac-gradient-text-background);\n color: #0000;\n background-position: 0 0;\n background-size: 700% 100%;\n margin: 0;\n}\n\n.neon {\n filter: blur(8px);\n mix-blend-mode: plus-lighter;\n pointer-events: none;\n position: absolute;\n inset: 0;\n}\n"],"sourceRoot":""}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
import { motion, useInView } from "motion/react";
|
|
4
|
-
import { forwardRef, useImperativeHandle, useRef } from "react";
|
|
5
4
|
import { cn } from "../../lib/utilities.js";
|
|
6
5
|
import highlight_text_module from "./highlight-text.module.js";
|
|
6
|
+
import * as __rspack_external_react from "react";
|
|
7
7
|
const animation = {
|
|
8
8
|
backgroundSize: "100% 100%"
|
|
9
9
|
};
|
|
10
|
-
const HighlightText = /*#__PURE__*/ forwardRef(({ text, className, inView = false, inViewMargin = "0px", inViewOnce = true, transition = {
|
|
10
|
+
const HighlightText = /*#__PURE__*/ __rspack_external_react.forwardRef(({ text, className, inView = false, inViewMargin = "0px", inViewOnce = true, transition = {
|
|
11
11
|
duration: 2,
|
|
12
12
|
ease: "easeInOut"
|
|
13
13
|
}, ...props }, ref)=>{
|
|
14
14
|
const { key: _ignoredKey, ...restProps } = props;
|
|
15
|
-
const localRef = useRef(null);
|
|
16
|
-
useImperativeHandle(ref, ()=>localRef.current, []);
|
|
15
|
+
const localRef = __rspack_external_react.useRef(null);
|
|
16
|
+
__rspack_external_react.useImperativeHandle(ref, ()=>localRef.current, []);
|
|
17
17
|
const inViewResult = useInView(localRef, {
|
|
18
18
|
once: inViewOnce,
|
|
19
19
|
margin: inViewMargin
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components/ui/highlight-text.js","sources":["../../../src/components/ui/highlight-text.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport {motion, useInView, type HTMLMotionProps, type Transition, type UseInViewOptions} from \"motion/react\";\r\nimport * as React from \"react\";\r\n\r\nimport {cn} from \"@/lib/utilities\";\r\nimport styles from \"./highlight-text.module.css\";\r\n\r\n/** Props accepted by {@link HighlightText}. */\r\nexport interface HighlightTextProps extends HTMLMotionProps<\"span\"> {\r\n /** Inline text content that receives the animated highlight sweep. @default undefined */\r\n text: string;\r\n /** Delays the highlight animation until the text enters the viewport. @default false */\r\n inView?: boolean;\r\n /** Margin passed to the in-view observer when `inView` is enabled. @default \"0px\" */\r\n inViewMargin?: UseInViewOptions[\"margin\"];\r\n /** Prevents the in-view animation from replaying after the first reveal. @default true */\r\n inViewOnce?: boolean;\r\n /** Motion timing used for the highlight fill animation. @default {duration: 2, ease: \"easeInOut\"} */\r\n transition?: Transition;\r\n}\r\n\r\nconst animation = {backgroundSize: \"100% 100%\"};\r\n\r\n/**\r\n * Animates a gradient highlight fill behind inline text content.\r\n *\r\n * @remarks\r\n * - Animated component using the `motion` library\r\n * - Renders a `<span>` element\r\n * - Styling via CSS Modules with `--ac-*` custom properties\r\n * - Client-side only (`\"use client\"` directive)\r\n *\r\n * @example\r\n * ```tsx\r\n * <HighlightText text=\"Highlighted copy\" />\r\n * ```\r\n *\r\n * @see {@link HighlightTextProps} for available props\r\n */\r\nconst HighlightText = React.forwardRef<HTMLSpanElement, HighlightTextProps>(\r\n (\r\n {text, className, inView = false, inViewMargin = \"0px\", inViewOnce = true, transition = {duration: 2, ease: \"easeInOut\"}, ...props},\r\n ref,\r\n ) => {\r\n // eslint-disable-next-line sonarjs/no-unused-vars -- removing React key avoids implicit key spreading\r\n const {key: _ignoredKey, ...restProps} = props;\r\n const localRef = React.useRef<HTMLSpanElement>(null);\r\n\r\n React.useImperativeHandle(ref, () => localRef.current!, []);\r\n\r\n const inViewResult = useInView(localRef, {\r\n once: inViewOnce,\r\n margin: inViewMargin,\r\n });\r\n const isInView = !inView || inViewResult;\r\n\r\n return (\r\n <motion.span\r\n ref={localRef}\r\n initial={{\r\n backgroundSize: \"0% 100%\",\r\n }}\r\n animate={isInView ? animation : undefined}\r\n transition={transition}\r\n className={cn(styles.highlight, className)}\r\n {...restProps}>\r\n {text}\r\n </motion.span>\r\n );\r\n },\r\n);\r\n\r\nHighlightText.displayName = \"HighlightText\";\r\n\r\nexport {HighlightText};\r\n"],"names":["animation","HighlightText","React","text","className","inView","inViewMargin","inViewOnce","transition","props","ref","_ignoredKey","restProps","localRef","inViewResult","useInView","isInView","motion","undefined","cn","styles"],"mappings":";;;;;;AAsBA,MAAMA,YAAY;IAAC,gBAAgB;AAAW;AAkB9C,MAAMC,gBAAgB,WAAHA,GAAGC,
|
|
1
|
+
{"version":3,"file":"components/ui/highlight-text.js","sources":["../../../src/components/ui/highlight-text.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport {motion, useInView, type HTMLMotionProps, type Transition, type UseInViewOptions} from \"motion/react\";\r\nimport * as React from \"react\";\r\n\r\nimport {cn} from \"@/lib/utilities\";\r\nimport styles from \"./highlight-text.module.css\";\r\n\r\n/** Props accepted by {@link HighlightText}. */\r\nexport interface HighlightTextProps extends HTMLMotionProps<\"span\"> {\r\n /** Inline text content that receives the animated highlight sweep. @default undefined */\r\n text: string;\r\n /** Delays the highlight animation until the text enters the viewport. @default false */\r\n inView?: boolean;\r\n /** Margin passed to the in-view observer when `inView` is enabled. @default \"0px\" */\r\n inViewMargin?: UseInViewOptions[\"margin\"];\r\n /** Prevents the in-view animation from replaying after the first reveal. @default true */\r\n inViewOnce?: boolean;\r\n /** Motion timing used for the highlight fill animation. @default {duration: 2, ease: \"easeInOut\"} */\r\n transition?: Transition;\r\n}\r\n\r\nconst animation = {backgroundSize: \"100% 100%\"};\r\n\r\n/**\r\n * Animates a gradient highlight fill behind inline text content.\r\n *\r\n * @remarks\r\n * - Animated component using the `motion` library\r\n * - Renders a `<span>` element\r\n * - Styling via CSS Modules with `--ac-*` custom properties\r\n * - Client-side only (`\"use client\"` directive)\r\n *\r\n * @example\r\n * ```tsx\r\n * <HighlightText text=\"Highlighted copy\" />\r\n * ```\r\n *\r\n * @see {@link HighlightTextProps} for available props\r\n */\r\nconst HighlightText = React.forwardRef<HTMLSpanElement, HighlightTextProps>(\r\n (\r\n {text, className, inView = false, inViewMargin = \"0px\", inViewOnce = true, transition = {duration: 2, ease: \"easeInOut\"}, ...props},\r\n ref,\r\n ) => {\r\n // eslint-disable-next-line sonarjs/no-unused-vars -- removing React key avoids implicit key spreading\r\n const {key: _ignoredKey, ...restProps} = props;\r\n const localRef = React.useRef<HTMLSpanElement>(null);\r\n\r\n React.useImperativeHandle(ref, () => localRef.current!, []);\r\n\r\n const inViewResult = useInView(localRef, {\r\n once: inViewOnce,\r\n margin: inViewMargin,\r\n });\r\n const isInView = !inView || inViewResult;\r\n\r\n return (\r\n <motion.span\r\n ref={localRef}\r\n initial={{\r\n backgroundSize: \"0% 100%\",\r\n }}\r\n animate={isInView ? animation : undefined}\r\n transition={transition}\r\n className={cn(styles.highlight, className)}\r\n {...restProps}>\r\n {text}\r\n </motion.span>\r\n );\r\n },\r\n);\r\n\r\nHighlightText.displayName = \"HighlightText\";\r\n\r\nexport {HighlightText};\r\n"],"names":["animation","HighlightText","React","text","className","inView","inViewMargin","inViewOnce","transition","props","ref","_ignoredKey","restProps","localRef","inViewResult","useInView","isInView","motion","undefined","cn","styles"],"mappings":";;;;;;AAsBA,MAAMA,YAAY;IAAC,gBAAgB;AAAW;AAkB9C,MAAMC,gBAAgB,WAAHA,GAAGC,wBAAAA,UAAgB,CACpC,CACE,EAACC,IAAI,EAAEC,SAAS,EAAEC,SAAS,KAAK,EAAEC,eAAe,KAAK,EAAEC,aAAa,IAAI,EAAEC,aAAa;IAAC,UAAU;IAAG,MAAM;AAAW,CAAC,EAAE,GAAGC,OAAM,EACnIC;IAGA,MAAM,EAAC,KAAKC,WAAW,EAAE,GAAGC,WAAU,GAAGH;IACzC,MAAMI,WAAWX,wBAAAA,MAAY,CAAkB;IAE/CA,wBAAAA,mBAAyB,CAACQ,KAAK,IAAMG,SAAS,OAAO,EAAG,EAAE;IAE1D,MAAMC,eAAeC,UAAUF,UAAU;QACvC,MAAMN;QACN,QAAQD;IACV;IACA,MAAMU,WAAW,CAACX,UAAUS;IAE5B,OAAO,WAAP,GACE,IAACG,OAAO,IAAI;QACV,KAAKJ;QACL,SAAS;YACP,gBAAgB;QAClB;QACA,SAASG,WAAWhB,YAAYkB;QAChC,YAAYV;QACZ,WAAWW,GAAGC,sBAAAA,SAAgB,EAAEhB;QAC/B,GAAGQ,SAAS;kBACZT;;AAGP;AAGFF,cAAc,WAAW,GAAG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["webpack
|
|
1
|
+
{"version":3,"sources":["webpack://./../../node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].oneOf[2].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].oneOf[2].use[2]!/home/runner/work/arolariu.ro/arolariu.ro/node_modules/@rslib/core/node_modules/@rsbuild/core/compiled/postcss-loader/index.js??ruleSet[1].rules[1].oneOf[2].use[3]!/home/runner/work/arolariu.ro/arolariu.ro/packages/components/src/components/ui/highlight-text.module.css","webpack://./src/components/ui/highlight-text.module.css"],"names":[],"mappings":"AAAA;ECCE,kCAAkC;EAClC,0DAA0D;EAC1D,sBAAsB;EACtB,4BAA4B;EAC5B,qBAAqB;EACrB,eAAe;EACf,kBAAkB;AACpB;;ADR6M;ECW3M,8HAA8H;AAChI","sourcesContent":[".highlight{background-image:linear-gradient(90deg,#dbeafe,#f3e8ff);background-position:0;background-repeat:no-repeat;border-radius:var(--ac-radius-lg);display:inline;padding:.25rem .5rem;position:relative}:global(.dark) .highlight,:global([data-theme=dark]) .highlight{background-image:linear-gradient(90deg,color-mix(in oklch,var(--ac-primary),#fff 35%) 0,color-mix(in oklch,#a855f7,#fff 15%) 100%)}",".highlight {\n border-radius: var(--ac-radius-lg);\n background-image: linear-gradient(90deg, #dbeafe, #f3e8ff);\n background-position: 0;\n background-repeat: no-repeat;\n padding: .25rem .5rem;\n display: inline;\n position: relative;\n}\n\n:is(:global(.dark) .highlight, :global([data-theme=dark]) .highlight) {\n background-image: linear-gradient(90deg,color-mix(in oklch,var(--ac-primary),#fff 35%) 0,oklch(68.2819% .197661 303.901) 100%);\n}\n"],"sourceRoot":""}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { motion } from "motion/react";
|
|
4
|
-
import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef } from "react";
|
|
5
4
|
import { cn } from "../../lib/utilities.js";
|
|
6
5
|
import hole_background_module from "./hole-background.module.js";
|
|
6
|
+
import * as __rspack_external_react from "react";
|
|
7
7
|
const linear = (progress)=>progress;
|
|
8
8
|
const easeInExpo = (progress)=>0 === progress ? 0 : 2 ** (10 * (progress - 1));
|
|
9
9
|
const createEmptyDisc = ()=>({
|
|
@@ -43,21 +43,21 @@ const createInitialState = ()=>({
|
|
|
43
43
|
particleArea: createEmptyParticleArea(),
|
|
44
44
|
linesCanvas: null
|
|
45
45
|
});
|
|
46
|
-
const HoleBackground = /*#__PURE__*/ forwardRef(({ strokeColor = "#737373", numberOfLines = 50, numberOfDiscs = 50, particleRGBColor = [
|
|
46
|
+
const HoleBackground = /*#__PURE__*/ __rspack_external_react.forwardRef(({ strokeColor = "#737373", numberOfLines = 50, numberOfDiscs = 50, particleRGBColor = [
|
|
47
47
|
255,
|
|
48
48
|
255,
|
|
49
49
|
255
|
|
50
50
|
], className, children, ...props }, ref)=>{
|
|
51
|
-
const canvasRef = useRef(null);
|
|
52
|
-
const animationFrameIdRef = useRef(0);
|
|
53
|
-
const stateRef = useRef(createInitialState());
|
|
54
|
-
useImperativeHandle(ref, ()=>canvasRef.current, []);
|
|
55
|
-
const tweenValue = useCallback((start, end, progress, ease = null)=>{
|
|
51
|
+
const canvasRef = __rspack_external_react.useRef(null);
|
|
52
|
+
const animationFrameIdRef = __rspack_external_react.useRef(0);
|
|
53
|
+
const stateRef = __rspack_external_react.useRef(createInitialState());
|
|
54
|
+
__rspack_external_react.useImperativeHandle(ref, ()=>canvasRef.current, []);
|
|
55
|
+
const tweenValue = __rspack_external_react.useCallback((start, end, progress, ease = null)=>{
|
|
56
56
|
const delta = end - start;
|
|
57
57
|
const easeFunction = "inExpo" === ease ? easeInExpo : linear;
|
|
58
58
|
return start + delta * easeFunction(progress);
|
|
59
59
|
}, []);
|
|
60
|
-
const tweenDisc = useCallback((disc)=>{
|
|
60
|
+
const tweenDisc = __rspack_external_react.useCallback((disc)=>{
|
|
61
61
|
const { startDisc, endDisc } = stateRef.current;
|
|
62
62
|
disc.x = tweenValue(startDisc.x, endDisc.x, disc.p);
|
|
63
63
|
disc.y = tweenValue(startDisc.y, endDisc.y, disc.p, "inExpo");
|
|
@@ -66,7 +66,7 @@ const HoleBackground = /*#__PURE__*/ forwardRef(({ strokeColor = "#737373", numb
|
|
|
66
66
|
}, [
|
|
67
67
|
tweenValue
|
|
68
68
|
]);
|
|
69
|
-
const setSize = useCallback(()=>{
|
|
69
|
+
const setSize = __rspack_external_react.useCallback(()=>{
|
|
70
70
|
const canvas = canvasRef.current;
|
|
71
71
|
if (!canvas) return;
|
|
72
72
|
const rect = canvas.getBoundingClientRect();
|
|
@@ -82,7 +82,7 @@ const HoleBackground = /*#__PURE__*/ forwardRef(({ strokeColor = "#737373", numb
|
|
|
82
82
|
canvas.width = stateRef.current.render.width * stateRef.current.render.dpi;
|
|
83
83
|
canvas.height = stateRef.current.render.height * stateRef.current.render.dpi;
|
|
84
84
|
}, []);
|
|
85
|
-
const setDiscs = useCallback(()=>{
|
|
85
|
+
const setDiscs = __rspack_external_react.useCallback(()=>{
|
|
86
86
|
const { width, height } = stateRef.current.rect;
|
|
87
87
|
stateRef.current.discs = [];
|
|
88
88
|
stateRef.current.startDisc = {
|
|
@@ -135,7 +135,7 @@ const HoleBackground = /*#__PURE__*/ forwardRef(({ strokeColor = "#737373", numb
|
|
|
135
135
|
numberOfDiscs,
|
|
136
136
|
tweenDisc
|
|
137
137
|
]);
|
|
138
|
-
const setLines = useCallback(()=>{
|
|
138
|
+
const setLines = __rspack_external_react.useCallback(()=>{
|
|
139
139
|
const { width, height } = stateRef.current.rect;
|
|
140
140
|
stateRef.current.lines = [];
|
|
141
141
|
const linesAngle = 2 * Math.PI / numberOfLines;
|
|
@@ -179,7 +179,7 @@ const HoleBackground = /*#__PURE__*/ forwardRef(({ strokeColor = "#737373", numb
|
|
|
179
179
|
numberOfLines,
|
|
180
180
|
strokeColor
|
|
181
181
|
]);
|
|
182
|
-
const initParticle = useCallback((start = false)=>{
|
|
182
|
+
const initParticle = __rspack_external_react.useCallback((start = false)=>{
|
|
183
183
|
const { particleArea } = stateRef.current;
|
|
184
184
|
const sx = particleArea.sx + particleArea.sw * Math.random();
|
|
185
185
|
const ex = particleArea.ex + particleArea.ew * Math.random();
|
|
@@ -200,7 +200,7 @@ const HoleBackground = /*#__PURE__*/ forwardRef(({ strokeColor = "#737373", numb
|
|
|
200
200
|
}, [
|
|
201
201
|
particleRGBColor
|
|
202
202
|
]);
|
|
203
|
-
const setParticles = useCallback(()=>{
|
|
203
|
+
const setParticles = __rspack_external_react.useCallback(()=>{
|
|
204
204
|
const { width, height } = stateRef.current.rect;
|
|
205
205
|
stateRef.current.particles = [];
|
|
206
206
|
const { disc } = stateRef.current.clip;
|
|
@@ -215,7 +215,7 @@ const HoleBackground = /*#__PURE__*/ forwardRef(({ strokeColor = "#737373", numb
|
|
|
215
215
|
}, [
|
|
216
216
|
initParticle
|
|
217
217
|
]);
|
|
218
|
-
const drawDiscs = useCallback((context)=>{
|
|
218
|
+
const drawDiscs = __rspack_external_react.useCallback((context)=>{
|
|
219
219
|
context.strokeStyle = strokeColor;
|
|
220
220
|
context.lineWidth = 2;
|
|
221
221
|
const outerDisc = stateRef.current.startDisc;
|
|
@@ -239,10 +239,10 @@ const HoleBackground = /*#__PURE__*/ forwardRef(({ strokeColor = "#737373", numb
|
|
|
239
239
|
}, [
|
|
240
240
|
strokeColor
|
|
241
241
|
]);
|
|
242
|
-
const drawLines = useCallback((context)=>{
|
|
242
|
+
const drawLines = __rspack_external_react.useCallback((context)=>{
|
|
243
243
|
if (stateRef.current.linesCanvas) context.drawImage(stateRef.current.linesCanvas, 0, 0);
|
|
244
244
|
}, []);
|
|
245
|
-
const drawParticles = useCallback((context)=>{
|
|
245
|
+
const drawParticles = __rspack_external_react.useCallback((context)=>{
|
|
246
246
|
const clipPath = stateRef.current.clip.path;
|
|
247
247
|
if (!clipPath) return;
|
|
248
248
|
context.save();
|
|
@@ -256,7 +256,7 @@ const HoleBackground = /*#__PURE__*/ forwardRef(({ strokeColor = "#737373", numb
|
|
|
256
256
|
});
|
|
257
257
|
context.restore();
|
|
258
258
|
}, []);
|
|
259
|
-
const moveDiscs = useCallback(()=>{
|
|
259
|
+
const moveDiscs = __rspack_external_react.useCallback(()=>{
|
|
260
260
|
stateRef.current.discs.forEach((disc)=>{
|
|
261
261
|
disc.p = (disc.p + 0.001) % 1;
|
|
262
262
|
tweenDisc(disc);
|
|
@@ -264,7 +264,7 @@ const HoleBackground = /*#__PURE__*/ forwardRef(({ strokeColor = "#737373", numb
|
|
|
264
264
|
}, [
|
|
265
265
|
tweenDisc
|
|
266
266
|
]);
|
|
267
|
-
const moveParticles = useCallback(()=>{
|
|
267
|
+
const moveParticles = __rspack_external_react.useCallback(()=>{
|
|
268
268
|
stateRef.current.particles.forEach((particle, index)=>{
|
|
269
269
|
particle.p = 1 - particle.y / Math.max(stateRef.current.particleArea.h, 1);
|
|
270
270
|
particle.x = particle.sx + particle.dx * particle.p;
|
|
@@ -274,7 +274,7 @@ const HoleBackground = /*#__PURE__*/ forwardRef(({ strokeColor = "#737373", numb
|
|
|
274
274
|
}, [
|
|
275
275
|
initParticle
|
|
276
276
|
]);
|
|
277
|
-
const tick = useCallback(()=>{
|
|
277
|
+
const tick = __rspack_external_react.useCallback(()=>{
|
|
278
278
|
const canvas = canvasRef.current;
|
|
279
279
|
if (!canvas) return;
|
|
280
280
|
const context = canvas.getContext("2d");
|
|
@@ -296,7 +296,7 @@ const HoleBackground = /*#__PURE__*/ forwardRef(({ strokeColor = "#737373", numb
|
|
|
296
296
|
moveDiscs,
|
|
297
297
|
moveParticles
|
|
298
298
|
]);
|
|
299
|
-
const init = useCallback(()=>{
|
|
299
|
+
const init = __rspack_external_react.useCallback(()=>{
|
|
300
300
|
setSize();
|
|
301
301
|
setDiscs();
|
|
302
302
|
setLines();
|
|
@@ -307,7 +307,7 @@ const HoleBackground = /*#__PURE__*/ forwardRef(({ strokeColor = "#737373", numb
|
|
|
307
307
|
setParticles,
|
|
308
308
|
setSize
|
|
309
309
|
]);
|
|
310
|
-
useEffect(()=>{
|
|
310
|
+
__rspack_external_react.useEffect(()=>{
|
|
311
311
|
const canvas = canvasRef.current;
|
|
312
312
|
if (!canvas) return;
|
|
313
313
|
init();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components/ui/hole-background.js","sources":["../../../src/components/ui/hole-background.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport {motion} from \"motion/react\";\r\nimport * as React from \"react\";\r\n\r\nimport {cn} from \"@/lib/utilities\";\r\nimport styles from \"./hole-background.module.css\";\r\n\r\n/** Props accepted by {@link HoleBackground}. */\r\nexport interface HoleBackgroundProps extends React.HTMLAttributes<HTMLCanvasElement> {\r\n /** Stroke color used for the wireframe discs and line work. @default \"#737373\" */\r\n strokeColor?: string;\r\n /** Number of radial line groups drawn through the tunnel. @default 50 */\r\n numberOfLines?: number;\r\n /** Number of animated discs used to build the tunnel depth effect. @default 50 */\r\n numberOfDiscs?: number;\r\n /** RGB tuple used to tint the floating particle field. @default [255, 255, 255] */\r\n particleRGBColor?: [number, number, number];\r\n}\r\n\r\ninterface Disc {\r\n p: number;\r\n x: number;\r\n y: number;\r\n w: number;\r\n h: number;\r\n}\r\n\r\ninterface Point {\r\n x: number;\r\n y: number;\r\n}\r\n\r\ninterface Particle {\r\n x: number;\r\n sx: number;\r\n dx: number;\r\n y: number;\r\n vy: number;\r\n p: number;\r\n r: number;\r\n c: string;\r\n}\r\n\r\ninterface ClipState {\r\n disc: Disc;\r\n i: number;\r\n path: Path2D | null;\r\n}\r\n\r\ninterface RectState {\r\n width: number;\r\n height: number;\r\n}\r\n\r\ninterface RenderState {\r\n width: number;\r\n height: number;\r\n dpi: number;\r\n}\r\n\r\ninterface ParticleArea {\r\n sx: number;\r\n sw: number;\r\n ex: number;\r\n ew: number;\r\n h: number;\r\n}\r\n\r\ninterface HoleState {\r\n discs: Array<Disc>;\r\n lines: Array<Array<Point>>;\r\n particles: Array<Particle>;\r\n clip: ClipState;\r\n startDisc: Disc;\r\n endDisc: Disc;\r\n rect: RectState;\r\n render: RenderState;\r\n particleArea: ParticleArea;\r\n linesCanvas: HTMLCanvasElement | null;\r\n}\r\n\r\nconst linear = (progress: number): number => progress;\r\nconst easeInExpo = (progress: number): number => (progress === 0 ? 0 : 2 ** (10 * (progress - 1)));\r\n\r\nconst createEmptyDisc = (): Disc => ({p: 0, x: 0, y: 0, w: 0, h: 0});\r\nconst createEmptyParticleArea = (): ParticleArea => ({sx: 0, sw: 0, ex: 0, ew: 0, h: 0});\r\nconst createInitialState = (): HoleState => ({\r\n discs: [],\r\n lines: [],\r\n particles: [],\r\n clip: {disc: createEmptyDisc(), i: 0, path: null},\r\n startDisc: createEmptyDisc(),\r\n endDisc: createEmptyDisc(),\r\n rect: {width: 0, height: 0},\r\n render: {width: 0, height: 0, dpi: 1},\r\n particleArea: createEmptyParticleArea(),\r\n linesCanvas: null,\r\n});\r\n\r\n/**\r\n * Renders a vortex-style tunnel animation with discs, scanlines, and particles.\r\n *\r\n * @remarks\r\n * - Animated component using the `motion` library\r\n * - Renders a `<div>` element containing a `<canvas>`\r\n * - Styling via CSS Modules with `--ac-*` custom properties\r\n * - Client-side only (`\"use client\"` directive)\r\n *\r\n * @example\r\n * ```tsx\r\n * <HoleBackground />\r\n * ```\r\n *\r\n * @see {@link HoleBackgroundProps} for available props\r\n */\r\nconst HoleBackground = React.forwardRef<HTMLCanvasElement, HoleBackgroundProps>(\r\n (\r\n {strokeColor = \"#737373\", numberOfLines = 50, numberOfDiscs = 50, particleRGBColor = [255, 255, 255], className, children, ...props},\r\n ref,\r\n ) => {\r\n const canvasRef = React.useRef<HTMLCanvasElement>(null);\r\n const animationFrameIdRef = React.useRef(0);\r\n const stateRef = React.useRef<HoleState>(createInitialState());\r\n\r\n React.useImperativeHandle(ref, () => canvasRef.current!, []);\r\n\r\n const tweenValue = React.useCallback((start: number, end: number, progress: number, ease: \"inExpo\" | null = null): number => {\r\n const delta = end - start;\r\n const easeFunction = ease === \"inExpo\" ? easeInExpo : linear;\r\n return start + delta * easeFunction(progress);\r\n }, []);\r\n\r\n const tweenDisc = React.useCallback(\r\n (disc: Disc): void => {\r\n const {startDisc, endDisc} = stateRef.current;\r\n disc.x = tweenValue(startDisc.x, endDisc.x, disc.p);\r\n disc.y = tweenValue(startDisc.y, endDisc.y, disc.p, \"inExpo\");\r\n disc.w = tweenValue(startDisc.w, endDisc.w, disc.p);\r\n disc.h = tweenValue(startDisc.h, endDisc.h, disc.p);\r\n },\r\n [tweenValue],\r\n );\r\n\r\n const setSize = React.useCallback((): void => {\r\n const canvas = canvasRef.current;\r\n if (!canvas) {\r\n return;\r\n }\r\n\r\n const rect = canvas.getBoundingClientRect();\r\n stateRef.current.rect = {width: rect.width, height: rect.height};\r\n stateRef.current.render = {\r\n width: rect.width,\r\n height: rect.height,\r\n dpi: globalThis.window.devicePixelRatio || 1,\r\n };\r\n canvas.width = stateRef.current.render.width * stateRef.current.render.dpi;\r\n canvas.height = stateRef.current.render.height * stateRef.current.render.dpi;\r\n }, []);\r\n\r\n const setDiscs = React.useCallback((): void => {\r\n const {width, height} = stateRef.current.rect;\r\n stateRef.current.discs = [];\r\n stateRef.current.startDisc = {\r\n x: width * 0.5,\r\n y: height * 0.45,\r\n w: width * 0.75,\r\n h: height * 0.7,\r\n p: 0,\r\n };\r\n stateRef.current.endDisc = {\r\n x: width * 0.5,\r\n y: height * 0.95,\r\n w: 0,\r\n h: 0,\r\n p: 0,\r\n };\r\n\r\n let previousBottom = height;\r\n stateRef.current.clip = {disc: createEmptyDisc(), i: 0, path: null};\r\n\r\n for (let index = 0; index < numberOfDiscs; index += 1) {\r\n const progress = index / numberOfDiscs;\r\n const disc: Disc = {p: progress, x: 0, y: 0, w: 0, h: 0};\r\n tweenDisc(disc);\r\n const bottom = disc.y + disc.h;\r\n if (bottom <= previousBottom) {\r\n stateRef.current.clip = {disc: {...disc}, i: index, path: null};\r\n }\r\n previousBottom = bottom;\r\n stateRef.current.discs.push(disc);\r\n }\r\n\r\n const clipPath = new globalThis.Path2D();\r\n const {disc} = stateRef.current.clip;\r\n clipPath.ellipse(disc.x, disc.y, disc.w, disc.h, 0, 0, Math.PI * 2);\r\n clipPath.rect(disc.x - disc.w, 0, disc.w * 2, disc.y);\r\n stateRef.current.clip.path = clipPath;\r\n }, [numberOfDiscs, tweenDisc]);\r\n\r\n const setLines = React.useCallback((): void => {\r\n const {width, height} = stateRef.current.rect;\r\n stateRef.current.lines = [];\r\n const linesAngle = (Math.PI * 2) / numberOfLines;\r\n for (let index = 0; index < numberOfLines; index += 1) {\r\n stateRef.current.lines.push([]);\r\n }\r\n\r\n stateRef.current.discs.forEach((disc) => {\r\n for (let index = 0; index < numberOfLines; index += 1) {\r\n const angle = index * linesAngle;\r\n const point: Point = {\r\n x: disc.x + Math.cos(angle) * disc.w,\r\n y: disc.y + Math.sin(angle) * disc.h,\r\n };\r\n stateRef.current.lines[index]!.push(point);\r\n }\r\n });\r\n\r\n const offCanvas = globalThis.document.createElement(\"canvas\");\r\n offCanvas.width = width;\r\n offCanvas.height = height;\r\n const context = offCanvas.getContext(\"2d\");\r\n const clipPath = stateRef.current.clip.path;\r\n if (!context || !clipPath) {\r\n return;\r\n }\r\n\r\n stateRef.current.lines.forEach((line) => {\r\n context.save();\r\n let lineIsIn = false;\r\n line.forEach((point, lineIndex) => {\r\n if (lineIndex === 0) {\r\n return;\r\n }\r\n\r\n const previousPoint = line[lineIndex - 1]!;\r\n if (!lineIsIn && (context.isPointInPath(clipPath, point.x, point.y) || context.isPointInStroke(clipPath, point.x, point.y))) {\r\n lineIsIn = true;\r\n } else if (lineIsIn) {\r\n context.clip(clipPath);\r\n }\r\n\r\n context.beginPath();\r\n context.moveTo(previousPoint.x, previousPoint.y);\r\n context.lineTo(point.x, point.y);\r\n context.strokeStyle = strokeColor;\r\n context.lineWidth = 2;\r\n context.stroke();\r\n context.closePath();\r\n });\r\n context.restore();\r\n });\r\n\r\n stateRef.current.linesCanvas = offCanvas;\r\n }, [numberOfLines, strokeColor]);\r\n\r\n const initParticle = React.useCallback(\r\n (start = false): Particle => {\r\n const {particleArea} = stateRef.current;\r\n const sx = particleArea.sx + particleArea.sw * Math.random();\r\n const ex = particleArea.ex + particleArea.ew * Math.random();\r\n const dx = ex - sx;\r\n const y = start ? particleArea.h * Math.random() : particleArea.h;\r\n const radius = 0.5 + Math.random() * 4;\r\n const vy = 0.5 + Math.random();\r\n\r\n return {\r\n x: sx,\r\n sx,\r\n dx,\r\n y,\r\n vy,\r\n p: 0,\r\n r: radius,\r\n c: `rgba(${particleRGBColor[0]}, ${particleRGBColor[1]}, ${particleRGBColor[2]}, ${Math.random()})`,\r\n };\r\n },\r\n [particleRGBColor],\r\n );\r\n\r\n const setParticles = React.useCallback((): void => {\r\n const {width, height} = stateRef.current.rect;\r\n stateRef.current.particles = [];\r\n const {disc} = stateRef.current.clip;\r\n stateRef.current.particleArea = {\r\n sx: (width - disc.w * 0.5) / 2,\r\n sw: disc.w * 0.5,\r\n ex: (width - disc.w * 2) / 2,\r\n ew: disc.w * 2,\r\n h: height * 0.85,\r\n };\r\n\r\n for (let index = 0; index < 100; index += 1) {\r\n stateRef.current.particles.push(initParticle(true));\r\n }\r\n }, [initParticle]);\r\n\r\n const drawDiscs = React.useCallback(\r\n (context: CanvasRenderingContext2D): void => {\r\n context.strokeStyle = strokeColor;\r\n context.lineWidth = 2;\r\n const outerDisc = stateRef.current.startDisc;\r\n context.beginPath();\r\n context.ellipse(outerDisc.x, outerDisc.y, outerDisc.w, outerDisc.h, 0, 0, Math.PI * 2);\r\n context.stroke();\r\n context.closePath();\r\n\r\n const clipPath = stateRef.current.clip.path;\r\n stateRef.current.discs.forEach((disc, index) => {\r\n if (index % 5 !== 0) {\r\n return;\r\n }\r\n\r\n if (clipPath && disc.w < stateRef.current.clip.disc.w - 5) {\r\n context.save();\r\n context.clip(clipPath);\r\n }\r\n\r\n context.beginPath();\r\n context.ellipse(disc.x, disc.y, disc.w, disc.h, 0, 0, Math.PI * 2);\r\n context.stroke();\r\n context.closePath();\r\n\r\n if (clipPath && disc.w < stateRef.current.clip.disc.w - 5) {\r\n context.restore();\r\n }\r\n });\r\n },\r\n [strokeColor],\r\n );\r\n\r\n const drawLines = React.useCallback((context: CanvasRenderingContext2D): void => {\r\n if (stateRef.current.linesCanvas) {\r\n context.drawImage(stateRef.current.linesCanvas, 0, 0);\r\n }\r\n }, []);\r\n\r\n const drawParticles = React.useCallback((context: CanvasRenderingContext2D): void => {\r\n const clipPath = stateRef.current.clip.path;\r\n if (!clipPath) {\r\n return;\r\n }\r\n\r\n context.save();\r\n context.clip(clipPath);\r\n stateRef.current.particles.forEach((particle) => {\r\n context.fillStyle = particle.c;\r\n context.beginPath();\r\n context.rect(particle.x, particle.y, particle.r, particle.r);\r\n context.closePath();\r\n context.fill();\r\n });\r\n context.restore();\r\n }, []);\r\n\r\n const moveDiscs = React.useCallback((): void => {\r\n stateRef.current.discs.forEach((disc) => {\r\n disc.p = (disc.p + 0.001) % 1;\r\n tweenDisc(disc);\r\n });\r\n }, [tweenDisc]);\r\n\r\n const moveParticles = React.useCallback((): void => {\r\n stateRef.current.particles.forEach((particle, index) => {\r\n particle.p = 1 - particle.y / Math.max(stateRef.current.particleArea.h, 1);\r\n particle.x = particle.sx + particle.dx * particle.p;\r\n particle.y -= particle.vy;\r\n if (particle.y < 0) {\r\n stateRef.current.particles[index] = initParticle();\r\n }\r\n });\r\n }, [initParticle]);\r\n\r\n const tick = React.useCallback((): void => {\r\n const canvas = canvasRef.current;\r\n if (!canvas) {\r\n return;\r\n }\r\n\r\n const context = canvas.getContext(\"2d\");\r\n if (!context) {\r\n return;\r\n }\r\n\r\n context.clearRect(0, 0, canvas.width, canvas.height);\r\n context.save();\r\n context.scale(stateRef.current.render.dpi, stateRef.current.render.dpi);\r\n moveDiscs();\r\n moveParticles();\r\n drawDiscs(context);\r\n drawLines(context);\r\n drawParticles(context);\r\n context.restore();\r\n animationFrameIdRef.current = globalThis.requestAnimationFrame(tick);\r\n }, [drawDiscs, drawLines, drawParticles, moveDiscs, moveParticles]);\r\n\r\n const init = React.useCallback((): void => {\r\n setSize();\r\n setDiscs();\r\n setLines();\r\n setParticles();\r\n }, [setDiscs, setLines, setParticles, setSize]);\r\n\r\n React.useEffect(() => {\r\n const canvas = canvasRef.current;\r\n if (!canvas) {\r\n return;\r\n }\r\n\r\n init();\r\n tick();\r\n\r\n const handleResize = (): void => {\r\n setSize();\r\n setDiscs();\r\n setLines();\r\n setParticles();\r\n };\r\n\r\n globalThis.window.addEventListener(\"resize\", handleResize);\r\n return () => {\r\n globalThis.window.removeEventListener(\"resize\", handleResize);\r\n globalThis.cancelAnimationFrame(animationFrameIdRef.current);\r\n };\r\n }, [init, setDiscs, setLines, setParticles, setSize, tick]);\r\n\r\n return (\r\n <div className={cn(styles.root, className)}>\r\n {children}\r\n <canvas\r\n ref={canvasRef}\r\n className={styles.canvas}\r\n {...props}\r\n />\r\n <motion.div\r\n aria-hidden='true'\r\n className={styles.glow}\r\n animate={{backgroundPosition: \"0% 300%\"}}\r\n transition={{duration: 5, ease: \"linear\", repeat: Infinity}}\r\n />\r\n <div\r\n aria-hidden='true'\r\n className={styles.scanlines}\r\n />\r\n </div>\r\n );\r\n },\r\n);\r\n\r\nHoleBackground.displayName = \"HoleBackground\";\r\n\r\nexport {HoleBackground};\r\n"],"names":["linear","progress","easeInExpo","createEmptyDisc","createEmptyParticleArea","createInitialState","HoleBackground","React","strokeColor","numberOfLines","numberOfDiscs","particleRGBColor","className","children","props","ref","canvasRef","animationFrameIdRef","stateRef","tweenValue","start","end","ease","delta","easeFunction","tweenDisc","disc","startDisc","endDisc","setSize","canvas","rect","globalThis","setDiscs","width","height","previousBottom","index","bottom","clipPath","Math","setLines","linesAngle","angle","point","offCanvas","context","line","lineIsIn","lineIndex","previousPoint","initParticle","particleArea","sx","ex","dx","y","radius","vy","setParticles","drawDiscs","outerDisc","drawLines","drawParticles","particle","moveDiscs","moveParticles","tick","init","handleResize","cn","styles","motion","Infinity"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"components/ui/hole-background.js","sources":["../../../src/components/ui/hole-background.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport {motion} from \"motion/react\";\r\nimport * as React from \"react\";\r\n\r\nimport {cn} from \"@/lib/utilities\";\r\nimport styles from \"./hole-background.module.css\";\r\n\r\n/** Props accepted by {@link HoleBackground}. */\r\nexport interface HoleBackgroundProps extends React.HTMLAttributes<HTMLCanvasElement> {\r\n /** Stroke color used for the wireframe discs and line work. @default \"#737373\" */\r\n strokeColor?: string;\r\n /** Number of radial line groups drawn through the tunnel. @default 50 */\r\n numberOfLines?: number;\r\n /** Number of animated discs used to build the tunnel depth effect. @default 50 */\r\n numberOfDiscs?: number;\r\n /** RGB tuple used to tint the floating particle field. @default [255, 255, 255] */\r\n particleRGBColor?: [number, number, number];\r\n}\r\n\r\ninterface Disc {\r\n p: number;\r\n x: number;\r\n y: number;\r\n w: number;\r\n h: number;\r\n}\r\n\r\ninterface Point {\r\n x: number;\r\n y: number;\r\n}\r\n\r\ninterface Particle {\r\n x: number;\r\n sx: number;\r\n dx: number;\r\n y: number;\r\n vy: number;\r\n p: number;\r\n r: number;\r\n c: string;\r\n}\r\n\r\ninterface ClipState {\r\n disc: Disc;\r\n i: number;\r\n path: Path2D | null;\r\n}\r\n\r\ninterface RectState {\r\n width: number;\r\n height: number;\r\n}\r\n\r\ninterface RenderState {\r\n width: number;\r\n height: number;\r\n dpi: number;\r\n}\r\n\r\ninterface ParticleArea {\r\n sx: number;\r\n sw: number;\r\n ex: number;\r\n ew: number;\r\n h: number;\r\n}\r\n\r\ninterface HoleState {\r\n discs: Array<Disc>;\r\n lines: Array<Array<Point>>;\r\n particles: Array<Particle>;\r\n clip: ClipState;\r\n startDisc: Disc;\r\n endDisc: Disc;\r\n rect: RectState;\r\n render: RenderState;\r\n particleArea: ParticleArea;\r\n linesCanvas: HTMLCanvasElement | null;\r\n}\r\n\r\nconst linear = (progress: number): number => progress;\r\nconst easeInExpo = (progress: number): number => (progress === 0 ? 0 : 2 ** (10 * (progress - 1)));\r\n\r\nconst createEmptyDisc = (): Disc => ({p: 0, x: 0, y: 0, w: 0, h: 0});\r\nconst createEmptyParticleArea = (): ParticleArea => ({sx: 0, sw: 0, ex: 0, ew: 0, h: 0});\r\nconst createInitialState = (): HoleState => ({\r\n discs: [],\r\n lines: [],\r\n particles: [],\r\n clip: {disc: createEmptyDisc(), i: 0, path: null},\r\n startDisc: createEmptyDisc(),\r\n endDisc: createEmptyDisc(),\r\n rect: {width: 0, height: 0},\r\n render: {width: 0, height: 0, dpi: 1},\r\n particleArea: createEmptyParticleArea(),\r\n linesCanvas: null,\r\n});\r\n\r\n/**\r\n * Renders a vortex-style tunnel animation with discs, scanlines, and particles.\r\n *\r\n * @remarks\r\n * - Animated component using the `motion` library\r\n * - Renders a `<div>` element containing a `<canvas>`\r\n * - Styling via CSS Modules with `--ac-*` custom properties\r\n * - Client-side only (`\"use client\"` directive)\r\n *\r\n * @example\r\n * ```tsx\r\n * <HoleBackground />\r\n * ```\r\n *\r\n * @see {@link HoleBackgroundProps} for available props\r\n */\r\nconst HoleBackground = React.forwardRef<HTMLCanvasElement, HoleBackgroundProps>(\r\n (\r\n {strokeColor = \"#737373\", numberOfLines = 50, numberOfDiscs = 50, particleRGBColor = [255, 255, 255], className, children, ...props},\r\n ref,\r\n ) => {\r\n const canvasRef = React.useRef<HTMLCanvasElement>(null);\r\n const animationFrameIdRef = React.useRef(0);\r\n const stateRef = React.useRef<HoleState>(createInitialState());\r\n\r\n React.useImperativeHandle(ref, () => canvasRef.current!, []);\r\n\r\n const tweenValue = React.useCallback((start: number, end: number, progress: number, ease: \"inExpo\" | null = null): number => {\r\n const delta = end - start;\r\n const easeFunction = ease === \"inExpo\" ? easeInExpo : linear;\r\n return start + delta * easeFunction(progress);\r\n }, []);\r\n\r\n const tweenDisc = React.useCallback(\r\n (disc: Disc): void => {\r\n const {startDisc, endDisc} = stateRef.current;\r\n disc.x = tweenValue(startDisc.x, endDisc.x, disc.p);\r\n disc.y = tweenValue(startDisc.y, endDisc.y, disc.p, \"inExpo\");\r\n disc.w = tweenValue(startDisc.w, endDisc.w, disc.p);\r\n disc.h = tweenValue(startDisc.h, endDisc.h, disc.p);\r\n },\r\n [tweenValue],\r\n );\r\n\r\n const setSize = React.useCallback((): void => {\r\n const canvas = canvasRef.current;\r\n if (!canvas) {\r\n return;\r\n }\r\n\r\n const rect = canvas.getBoundingClientRect();\r\n stateRef.current.rect = {width: rect.width, height: rect.height};\r\n stateRef.current.render = {\r\n width: rect.width,\r\n height: rect.height,\r\n dpi: globalThis.window.devicePixelRatio || 1,\r\n };\r\n canvas.width = stateRef.current.render.width * stateRef.current.render.dpi;\r\n canvas.height = stateRef.current.render.height * stateRef.current.render.dpi;\r\n }, []);\r\n\r\n const setDiscs = React.useCallback((): void => {\r\n const {width, height} = stateRef.current.rect;\r\n stateRef.current.discs = [];\r\n stateRef.current.startDisc = {\r\n x: width * 0.5,\r\n y: height * 0.45,\r\n w: width * 0.75,\r\n h: height * 0.7,\r\n p: 0,\r\n };\r\n stateRef.current.endDisc = {\r\n x: width * 0.5,\r\n y: height * 0.95,\r\n w: 0,\r\n h: 0,\r\n p: 0,\r\n };\r\n\r\n let previousBottom = height;\r\n stateRef.current.clip = {disc: createEmptyDisc(), i: 0, path: null};\r\n\r\n for (let index = 0; index < numberOfDiscs; index += 1) {\r\n const progress = index / numberOfDiscs;\r\n const disc: Disc = {p: progress, x: 0, y: 0, w: 0, h: 0};\r\n tweenDisc(disc);\r\n const bottom = disc.y + disc.h;\r\n if (bottom <= previousBottom) {\r\n stateRef.current.clip = {disc: {...disc}, i: index, path: null};\r\n }\r\n previousBottom = bottom;\r\n stateRef.current.discs.push(disc);\r\n }\r\n\r\n const clipPath = new globalThis.Path2D();\r\n const {disc} = stateRef.current.clip;\r\n clipPath.ellipse(disc.x, disc.y, disc.w, disc.h, 0, 0, Math.PI * 2);\r\n clipPath.rect(disc.x - disc.w, 0, disc.w * 2, disc.y);\r\n stateRef.current.clip.path = clipPath;\r\n }, [numberOfDiscs, tweenDisc]);\r\n\r\n const setLines = React.useCallback((): void => {\r\n const {width, height} = stateRef.current.rect;\r\n stateRef.current.lines = [];\r\n const linesAngle = (Math.PI * 2) / numberOfLines;\r\n for (let index = 0; index < numberOfLines; index += 1) {\r\n stateRef.current.lines.push([]);\r\n }\r\n\r\n stateRef.current.discs.forEach((disc) => {\r\n for (let index = 0; index < numberOfLines; index += 1) {\r\n const angle = index * linesAngle;\r\n const point: Point = {\r\n x: disc.x + Math.cos(angle) * disc.w,\r\n y: disc.y + Math.sin(angle) * disc.h,\r\n };\r\n stateRef.current.lines[index]!.push(point);\r\n }\r\n });\r\n\r\n const offCanvas = globalThis.document.createElement(\"canvas\");\r\n offCanvas.width = width;\r\n offCanvas.height = height;\r\n const context = offCanvas.getContext(\"2d\");\r\n const clipPath = stateRef.current.clip.path;\r\n if (!context || !clipPath) {\r\n return;\r\n }\r\n\r\n stateRef.current.lines.forEach((line) => {\r\n context.save();\r\n let lineIsIn = false;\r\n line.forEach((point, lineIndex) => {\r\n if (lineIndex === 0) {\r\n return;\r\n }\r\n\r\n const previousPoint = line[lineIndex - 1]!;\r\n if (!lineIsIn && (context.isPointInPath(clipPath, point.x, point.y) || context.isPointInStroke(clipPath, point.x, point.y))) {\r\n lineIsIn = true;\r\n } else if (lineIsIn) {\r\n context.clip(clipPath);\r\n }\r\n\r\n context.beginPath();\r\n context.moveTo(previousPoint.x, previousPoint.y);\r\n context.lineTo(point.x, point.y);\r\n context.strokeStyle = strokeColor;\r\n context.lineWidth = 2;\r\n context.stroke();\r\n context.closePath();\r\n });\r\n context.restore();\r\n });\r\n\r\n stateRef.current.linesCanvas = offCanvas;\r\n }, [numberOfLines, strokeColor]);\r\n\r\n const initParticle = React.useCallback(\r\n (start = false): Particle => {\r\n const {particleArea} = stateRef.current;\r\n const sx = particleArea.sx + particleArea.sw * Math.random();\r\n const ex = particleArea.ex + particleArea.ew * Math.random();\r\n const dx = ex - sx;\r\n const y = start ? particleArea.h * Math.random() : particleArea.h;\r\n const radius = 0.5 + Math.random() * 4;\r\n const vy = 0.5 + Math.random();\r\n\r\n return {\r\n x: sx,\r\n sx,\r\n dx,\r\n y,\r\n vy,\r\n p: 0,\r\n r: radius,\r\n c: `rgba(${particleRGBColor[0]}, ${particleRGBColor[1]}, ${particleRGBColor[2]}, ${Math.random()})`,\r\n };\r\n },\r\n [particleRGBColor],\r\n );\r\n\r\n const setParticles = React.useCallback((): void => {\r\n const {width, height} = stateRef.current.rect;\r\n stateRef.current.particles = [];\r\n const {disc} = stateRef.current.clip;\r\n stateRef.current.particleArea = {\r\n sx: (width - disc.w * 0.5) / 2,\r\n sw: disc.w * 0.5,\r\n ex: (width - disc.w * 2) / 2,\r\n ew: disc.w * 2,\r\n h: height * 0.85,\r\n };\r\n\r\n for (let index = 0; index < 100; index += 1) {\r\n stateRef.current.particles.push(initParticle(true));\r\n }\r\n }, [initParticle]);\r\n\r\n const drawDiscs = React.useCallback(\r\n (context: CanvasRenderingContext2D): void => {\r\n context.strokeStyle = strokeColor;\r\n context.lineWidth = 2;\r\n const outerDisc = stateRef.current.startDisc;\r\n context.beginPath();\r\n context.ellipse(outerDisc.x, outerDisc.y, outerDisc.w, outerDisc.h, 0, 0, Math.PI * 2);\r\n context.stroke();\r\n context.closePath();\r\n\r\n const clipPath = stateRef.current.clip.path;\r\n stateRef.current.discs.forEach((disc, index) => {\r\n if (index % 5 !== 0) {\r\n return;\r\n }\r\n\r\n if (clipPath && disc.w < stateRef.current.clip.disc.w - 5) {\r\n context.save();\r\n context.clip(clipPath);\r\n }\r\n\r\n context.beginPath();\r\n context.ellipse(disc.x, disc.y, disc.w, disc.h, 0, 0, Math.PI * 2);\r\n context.stroke();\r\n context.closePath();\r\n\r\n if (clipPath && disc.w < stateRef.current.clip.disc.w - 5) {\r\n context.restore();\r\n }\r\n });\r\n },\r\n [strokeColor],\r\n );\r\n\r\n const drawLines = React.useCallback((context: CanvasRenderingContext2D): void => {\r\n if (stateRef.current.linesCanvas) {\r\n context.drawImage(stateRef.current.linesCanvas, 0, 0);\r\n }\r\n }, []);\r\n\r\n const drawParticles = React.useCallback((context: CanvasRenderingContext2D): void => {\r\n const clipPath = stateRef.current.clip.path;\r\n if (!clipPath) {\r\n return;\r\n }\r\n\r\n context.save();\r\n context.clip(clipPath);\r\n stateRef.current.particles.forEach((particle) => {\r\n context.fillStyle = particle.c;\r\n context.beginPath();\r\n context.rect(particle.x, particle.y, particle.r, particle.r);\r\n context.closePath();\r\n context.fill();\r\n });\r\n context.restore();\r\n }, []);\r\n\r\n const moveDiscs = React.useCallback((): void => {\r\n stateRef.current.discs.forEach((disc) => {\r\n disc.p = (disc.p + 0.001) % 1;\r\n tweenDisc(disc);\r\n });\r\n }, [tweenDisc]);\r\n\r\n const moveParticles = React.useCallback((): void => {\r\n stateRef.current.particles.forEach((particle, index) => {\r\n particle.p = 1 - particle.y / Math.max(stateRef.current.particleArea.h, 1);\r\n particle.x = particle.sx + particle.dx * particle.p;\r\n particle.y -= particle.vy;\r\n if (particle.y < 0) {\r\n stateRef.current.particles[index] = initParticle();\r\n }\r\n });\r\n }, [initParticle]);\r\n\r\n const tick = React.useCallback((): void => {\r\n const canvas = canvasRef.current;\r\n if (!canvas) {\r\n return;\r\n }\r\n\r\n const context = canvas.getContext(\"2d\");\r\n if (!context) {\r\n return;\r\n }\r\n\r\n context.clearRect(0, 0, canvas.width, canvas.height);\r\n context.save();\r\n context.scale(stateRef.current.render.dpi, stateRef.current.render.dpi);\r\n moveDiscs();\r\n moveParticles();\r\n drawDiscs(context);\r\n drawLines(context);\r\n drawParticles(context);\r\n context.restore();\r\n animationFrameIdRef.current = globalThis.requestAnimationFrame(tick);\r\n }, [drawDiscs, drawLines, drawParticles, moveDiscs, moveParticles]);\r\n\r\n const init = React.useCallback((): void => {\r\n setSize();\r\n setDiscs();\r\n setLines();\r\n setParticles();\r\n }, [setDiscs, setLines, setParticles, setSize]);\r\n\r\n React.useEffect(() => {\r\n const canvas = canvasRef.current;\r\n if (!canvas) {\r\n return;\r\n }\r\n\r\n init();\r\n tick();\r\n\r\n const handleResize = (): void => {\r\n setSize();\r\n setDiscs();\r\n setLines();\r\n setParticles();\r\n };\r\n\r\n globalThis.window.addEventListener(\"resize\", handleResize);\r\n return () => {\r\n globalThis.window.removeEventListener(\"resize\", handleResize);\r\n globalThis.cancelAnimationFrame(animationFrameIdRef.current);\r\n };\r\n }, [init, setDiscs, setLines, setParticles, setSize, tick]);\r\n\r\n return (\r\n <div className={cn(styles.root, className)}>\r\n {children}\r\n <canvas\r\n ref={canvasRef}\r\n className={styles.canvas}\r\n {...props}\r\n />\r\n <motion.div\r\n aria-hidden='true'\r\n className={styles.glow}\r\n animate={{backgroundPosition: \"0% 300%\"}}\r\n transition={{duration: 5, ease: \"linear\", repeat: Infinity}}\r\n />\r\n <div\r\n aria-hidden='true'\r\n className={styles.scanlines}\r\n />\r\n </div>\r\n );\r\n },\r\n);\r\n\r\nHoleBackground.displayName = \"HoleBackground\";\r\n\r\nexport {HoleBackground};\r\n"],"names":["linear","progress","easeInExpo","createEmptyDisc","createEmptyParticleArea","createInitialState","HoleBackground","React","strokeColor","numberOfLines","numberOfDiscs","particleRGBColor","className","children","props","ref","canvasRef","animationFrameIdRef","stateRef","tweenValue","start","end","ease","delta","easeFunction","tweenDisc","disc","startDisc","endDisc","setSize","canvas","rect","globalThis","setDiscs","width","height","previousBottom","index","bottom","clipPath","Math","setLines","linesAngle","angle","point","offCanvas","context","line","lineIsIn","lineIndex","previousPoint","initParticle","particleArea","sx","ex","dx","y","radius","vy","setParticles","drawDiscs","outerDisc","drawLines","drawParticles","particle","moveDiscs","moveParticles","tick","init","handleResize","cn","styles","motion","Infinity"],"mappings":"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"}
|