entangle-ui 0.7.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +190 -0
- package/dist/esm/assets/src/components/controls/ColorPicker/{ColorPicker.css.ts.vanilla-Do5nbdgO.css → ColorPicker.css.ts.vanilla-D7ccNVQx.css} +14 -0
- package/dist/esm/assets/src/components/controls/Select/{Select.css.ts.vanilla-D4C059Ua.css → Select.css.ts.vanilla-oZnFUorL.css} +11 -0
- package/dist/esm/assets/src/components/controls/Slider/{Slider.css.ts.vanilla-C5SJ_7A1.css → Slider.css.ts.vanilla-Cqm3fQ0S.css} +14 -0
- package/dist/esm/assets/src/components/controls/TreeView/{TreeNode.css.ts.vanilla-D3ylUhuW.css → TreeNode.css.ts.vanilla-B_f8pUb8.css} +5 -0
- package/dist/esm/assets/src/components/controls/VectorInput/{VectorInput.css.ts.vanilla-BJma3iQ4.css → VectorInput.css.ts.vanilla-BpoiuhDA.css} +9 -0
- package/dist/esm/assets/src/components/editor/ChatPanel/{ChatPanel.css.ts.vanilla-BI5569ZO.css → ChatPanel.css.ts.vanilla-CLn8idfz.css} +117 -133
- package/dist/esm/assets/src/components/editor/PropertyInspector/{PropertySection.css.ts.vanilla-DJBtY_xk.css → PropertySection.css.ts.vanilla-DK12opZc.css} +5 -0
- package/dist/esm/assets/src/components/editor/TransformControl/TransformControl.css.ts.vanilla-H-iW-T0s.css +82 -0
- package/dist/esm/assets/src/components/feedback/Alert/Alert.css.ts.vanilla-CRAI-xHx.css +84 -0
- package/dist/esm/assets/src/components/feedback/Dialog/{Dialog.css.ts.vanilla-BrXTOHwS.css → Dialog.css.ts.vanilla-BxBFePLG.css} +8 -0
- package/dist/esm/assets/src/components/feedback/ProgressBar/ProgressBar.css.ts.vanilla-4WLVf1hx.css +152 -0
- package/dist/esm/assets/src/components/feedback/Skeleton/Skeleton.css.ts.vanilla-Dk2_SSsC.css +39 -0
- package/dist/esm/assets/src/components/feedback/Toast/{ToastItem.css.ts.vanilla-D6UuPKAj.css → ToastItem.css.ts.vanilla-DUeXqiaH.css} +9 -0
- package/dist/esm/assets/src/components/form/{InputWrapper.css.ts.vanilla-Bl7u62PI.css → InputWrapper.css.ts.vanilla-CLpKbEjq.css} +5 -0
- package/dist/esm/assets/src/components/layout/Accordion/{Accordion.css.ts.vanilla-Ck5Yew0e.css → Accordion.css.ts.vanilla-CJQum8px.css} +8 -0
- package/dist/esm/assets/src/components/navigation/Breadcrumbs/Breadcrumbs.css.ts.vanilla-DZ4jm_bw.css +128 -0
- package/dist/esm/assets/src/components/navigation/SegmentedControl/SegmentedControl.css.ts.vanilla-BHOnDD2B.css +197 -0
- package/dist/esm/assets/src/components/navigation/Tabs/{Tabs.css.ts.vanilla-D7RGpDPC.css → Tabs.css.ts.vanilla-CQucokdg.css} +14 -0
- package/dist/esm/assets/src/components/primitives/Avatar/Avatar.css.ts.vanilla-jG5hUudL.css +149 -0
- package/dist/esm/assets/src/components/primitives/Button/{Button.css.ts.vanilla-CT592JL7.css → Button.css.ts.vanilla-DXJcIb94.css} +9 -0
- package/dist/esm/assets/src/components/primitives/Checkbox/{Checkbox.css.ts.vanilla-dvrGPiPs.css → Checkbox.css.ts.vanilla-DNa-Gqto.css} +5 -0
- package/dist/esm/assets/src/components/primitives/Collapsible/{Collapsible.css.ts.vanilla-C1rYV-JT.css → Collapsible.css.ts.vanilla-Dz4Vy-ob.css} +8 -0
- package/dist/esm/assets/src/components/primitives/IconButton/{IconButton.css.ts.vanilla-C-xAQoR3.css → IconButton.css.ts.vanilla-CPkPZJRU.css} +9 -0
- package/dist/esm/assets/src/components/primitives/Kbd/Kbd.css.ts.vanilla-Co2-Rxgv.css +60 -0
- package/dist/esm/assets/src/components/primitives/Link/Link.css.ts.vanilla-q-bqHUOF.css +82 -0
- package/dist/esm/assets/src/components/primitives/Popover/{Popover.css.ts.vanilla-DW6aAr57.css → Popover.css.ts.vanilla-KCfDIs4G.css} +5 -0
- package/dist/esm/assets/src/components/primitives/Radio/Radio.css.ts.vanilla-CPjdD-ZM.css +127 -0
- package/dist/esm/assets/src/components/primitives/Switch/{Switch.css.ts.vanilla-CxqwUToB.css → Switch.css.ts.vanilla-CDSt-M5W.css} +5 -0
- package/dist/esm/assets/src/components/primitives/TextArea/{TextArea.css.ts.vanilla-DTOMjGkp.css → TextArea.css.ts.vanilla-M9l1t4HR.css} +5 -0
- package/dist/esm/assets/src/components/primitives/VisuallyHidden/VisuallyHidden.css.ts.vanilla-DBulVh4Q.css +36 -0
- package/dist/esm/assets/src/theme/lightTheme.css.ts.vanilla-OaRI_wIc.css +99 -0
- package/dist/esm/assets/src/utils/{animations.css.ts.vanilla-DOVlpljP.css → animations.css.ts.vanilla-CRLFsBSV.css} +22 -8
- package/dist/esm/components/Icons/AddIcon.js +30 -0
- package/dist/esm/components/Icons/AddIcon.js.map +1 -0
- package/dist/esm/components/Icons/AiChatIcon.js +31 -0
- package/dist/esm/components/Icons/AiChatIcon.js.map +1 -0
- package/dist/esm/components/Icons/AiSparklesIcon.js +31 -0
- package/dist/esm/components/Icons/AiSparklesIcon.js.map +1 -0
- package/dist/esm/components/Icons/ArrowDownIcon.js +30 -0
- package/dist/esm/components/Icons/ArrowDownIcon.js.map +1 -0
- package/dist/esm/components/Icons/ArrowLeftIcon.js +30 -0
- package/dist/esm/components/Icons/ArrowLeftIcon.js.map +1 -0
- package/dist/esm/components/Icons/ArrowRightIcon.js +30 -0
- package/dist/esm/components/Icons/ArrowRightIcon.js.map +1 -0
- package/dist/esm/components/Icons/ArrowUpIcon.js +30 -0
- package/dist/esm/components/Icons/ArrowUpIcon.js.map +1 -0
- package/dist/esm/components/Icons/BookmarkIcon.js +30 -0
- package/dist/esm/components/Icons/BookmarkIcon.js.map +1 -0
- package/dist/esm/components/Icons/CalendarIcon.js +30 -0
- package/dist/esm/components/Icons/CalendarIcon.js.map +1 -0
- package/dist/esm/components/Icons/ClockIcon.js +30 -0
- package/dist/esm/components/Icons/ClockIcon.js.map +1 -0
- package/dist/esm/components/Icons/CodeIcon.js +30 -0
- package/dist/esm/components/Icons/CodeIcon.js.map +1 -0
- package/dist/esm/components/Icons/CopyIcon.js +30 -0
- package/dist/esm/components/Icons/CopyIcon.js.map +1 -0
- package/dist/esm/components/Icons/CutIcon.js +30 -0
- package/dist/esm/components/Icons/CutIcon.js.map +1 -0
- package/dist/esm/components/Icons/DownloadIcon.js +30 -0
- package/dist/esm/components/Icons/DownloadIcon.js.map +1 -0
- package/dist/esm/components/Icons/EditIcon.js +30 -0
- package/dist/esm/components/Icons/EditIcon.js.map +1 -0
- package/dist/esm/components/Icons/ErrorIcon.js +30 -0
- package/dist/esm/components/Icons/ErrorIcon.js.map +1 -0
- package/dist/esm/components/Icons/EyeIcon.js +30 -0
- package/dist/esm/components/Icons/EyeIcon.js.map +1 -0
- package/dist/esm/components/Icons/FilterIcon.js +30 -0
- package/dist/esm/components/Icons/FilterIcon.js.map +1 -0
- package/dist/esm/components/Icons/FolderIcon.js +30 -0
- package/dist/esm/components/Icons/FolderIcon.js.map +1 -0
- package/dist/esm/components/Icons/FullscreenIcon.js +30 -0
- package/dist/esm/components/Icons/FullscreenIcon.js.map +1 -0
- package/dist/esm/components/Icons/GridIcon.js +30 -0
- package/dist/esm/components/Icons/GridIcon.js.map +1 -0
- package/dist/esm/components/Icons/HeartIcon.js +30 -0
- package/dist/esm/components/Icons/HeartIcon.js.map +1 -0
- package/dist/esm/components/Icons/HelpIcon.js +30 -0
- package/dist/esm/components/Icons/HelpIcon.js.map +1 -0
- package/dist/esm/components/Icons/HomeIcon.js +30 -0
- package/dist/esm/components/Icons/HomeIcon.js.map +1 -0
- package/dist/esm/components/Icons/InfoIcon.js +30 -0
- package/dist/esm/components/Icons/InfoIcon.js.map +1 -0
- package/dist/esm/components/Icons/LinkIcon.js +30 -0
- package/dist/esm/components/Icons/LinkIcon.js.map +1 -0
- package/dist/esm/components/Icons/ListIcon.js +30 -0
- package/dist/esm/components/Icons/ListIcon.js.map +1 -0
- package/dist/esm/components/Icons/LockIcon.js +30 -0
- package/dist/esm/components/Icons/LockIcon.js.map +1 -0
- package/dist/esm/components/Icons/MaximizeIcon.js +30 -0
- package/dist/esm/components/Icons/MaximizeIcon.js.map +1 -0
- package/dist/esm/components/Icons/MenuIcon.js +30 -0
- package/dist/esm/components/Icons/MenuIcon.js.map +1 -0
- package/dist/esm/components/Icons/MinimizeIcon.js +30 -0
- package/dist/esm/components/Icons/MinimizeIcon.js.map +1 -0
- package/dist/esm/components/Icons/PasteIcon.js +30 -0
- package/dist/esm/components/Icons/PasteIcon.js.map +1 -0
- package/dist/esm/components/Icons/PlayIcon.js +30 -0
- package/dist/esm/components/Icons/PlayIcon.js.map +1 -0
- package/dist/esm/components/Icons/RedoIcon.js +30 -0
- package/dist/esm/components/Icons/RedoIcon.js.map +1 -0
- package/dist/esm/components/Icons/RefreshIcon.js +30 -0
- package/dist/esm/components/Icons/RefreshIcon.js.map +1 -0
- package/dist/esm/components/Icons/RobotIcon.js +30 -0
- package/dist/esm/components/Icons/RobotIcon.js.map +1 -0
- package/dist/esm/components/Icons/SaveIcon.js +30 -0
- package/dist/esm/components/Icons/SaveIcon.js.map +1 -0
- package/dist/esm/components/Icons/SearchIcon.js +30 -0
- package/dist/esm/components/Icons/SearchIcon.js.map +1 -0
- package/dist/esm/components/Icons/SettingsIcon.js +30 -0
- package/dist/esm/components/Icons/SettingsIcon.js.map +1 -0
- package/dist/esm/components/Icons/SortIcon.js +30 -0
- package/dist/esm/components/Icons/SortIcon.js.map +1 -0
- package/dist/esm/components/Icons/StarIcon.js +30 -0
- package/dist/esm/components/Icons/StarIcon.js.map +1 -0
- package/dist/esm/components/Icons/SuccessIcon.js +30 -0
- package/dist/esm/components/Icons/SuccessIcon.js.map +1 -0
- package/dist/esm/components/Icons/TagIcon.js +30 -0
- package/dist/esm/components/Icons/TagIcon.js.map +1 -0
- package/dist/esm/components/Icons/TrashIcon.js +30 -0
- package/dist/esm/components/Icons/TrashIcon.js.map +1 -0
- package/dist/esm/components/Icons/UndoIcon.js +30 -0
- package/dist/esm/components/Icons/UndoIcon.js.map +1 -0
- package/dist/esm/components/Icons/UnlockIcon.js +30 -0
- package/dist/esm/components/Icons/UnlockIcon.js.map +1 -0
- package/dist/esm/components/Icons/UploadIcon.js +30 -0
- package/dist/esm/components/Icons/UploadIcon.js.map +1 -0
- package/dist/esm/components/Icons/UserIcon.js +30 -0
- package/dist/esm/components/Icons/UserIcon.js.map +1 -0
- package/dist/esm/components/Icons/WarningIcon.js +30 -0
- package/dist/esm/components/Icons/WarningIcon.js.map +1 -0
- package/dist/esm/components/Icons/ZoomInIcon.js +30 -0
- package/dist/esm/components/Icons/ZoomInIcon.js.map +1 -0
- package/dist/esm/components/Icons/ZoomOutIcon.js +30 -0
- package/dist/esm/components/Icons/ZoomOutIcon.js.map +1 -0
- package/dist/esm/components/controls/ColorPicker/ColorPicker.css.js +1 -1
- package/dist/esm/components/controls/NumberInput/useNumberInput.js +2 -1
- package/dist/esm/components/controls/NumberInput/useNumberInput.js.map +1 -1
- package/dist/esm/components/controls/Select/Select.css.js +1 -1
- package/dist/esm/components/controls/Slider/Slider.css.js +1 -1
- package/dist/esm/components/controls/TreeView/TreeNode.css.js +1 -1
- package/dist/esm/components/controls/VectorInput/VectorInput.css.js +1 -1
- package/dist/esm/components/controls/VectorInput/VectorInput.js +1 -0
- package/dist/esm/components/controls/VectorInput/VectorInput.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/ChatMessage.js +4 -12
- package/dist/esm/components/editor/ChatPanel/ChatMessage.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/ChatMessageList.js +4 -10
- package/dist/esm/components/editor/ChatPanel/ChatMessageList.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/ChatPanel.css.js +72 -74
- package/dist/esm/components/editor/ChatPanel/ChatPanel.css.js.map +1 -1
- package/dist/esm/components/editor/ChatPanel/useChatScroll.js +22 -28
- package/dist/esm/components/editor/ChatPanel/useChatScroll.js.map +1 -1
- package/dist/esm/components/editor/PropertyInspector/PropertySection.css.js +1 -1
- package/dist/esm/components/editor/TransformControl/TransformControl.css.js +11 -0
- package/dist/esm/components/editor/TransformControl/TransformControl.css.js.map +1 -0
- package/dist/esm/components/editor/TransformControl/TransformControl.js +158 -0
- package/dist/esm/components/editor/TransformControl/TransformControl.js.map +1 -0
- package/dist/esm/components/feedback/Alert/Alert.css.js +16 -0
- package/dist/esm/components/feedback/Alert/Alert.css.js.map +1 -0
- package/dist/esm/components/feedback/Alert/Alert.js +90 -0
- package/dist/esm/components/feedback/Alert/Alert.js.map +1 -0
- package/dist/esm/components/feedback/Alert/AlertActions.js +30 -0
- package/dist/esm/components/feedback/Alert/AlertActions.js.map +1 -0
- package/dist/esm/components/feedback/Alert/AlertDescription.js +28 -0
- package/dist/esm/components/feedback/Alert/AlertDescription.js.map +1 -0
- package/dist/esm/components/feedback/Alert/AlertTitle.js +28 -0
- package/dist/esm/components/feedback/Alert/AlertTitle.js.map +1 -0
- package/dist/esm/components/feedback/Dialog/Dialog.css.js +1 -1
- package/dist/esm/components/feedback/Dialog/Dialog.js +4 -12
- package/dist/esm/components/feedback/Dialog/Dialog.js.map +1 -1
- package/dist/esm/components/feedback/Dialog/useDialogAnimation.js +10 -3
- package/dist/esm/components/feedback/Dialog/useDialogAnimation.js.map +1 -1
- package/dist/esm/components/feedback/ProgressBar/CircularProgress.js +113 -0
- package/dist/esm/components/feedback/ProgressBar/CircularProgress.js.map +1 -0
- package/dist/esm/components/feedback/ProgressBar/ProgressBar.css.js +22 -0
- package/dist/esm/components/feedback/ProgressBar/ProgressBar.css.js.map +1 -0
- package/dist/esm/components/feedback/ProgressBar/ProgressBar.js +80 -0
- package/dist/esm/components/feedback/ProgressBar/ProgressBar.js.map +1 -0
- package/dist/esm/components/feedback/Skeleton/Skeleton.css.js +13 -0
- package/dist/esm/components/feedback/Skeleton/Skeleton.css.js.map +1 -0
- package/dist/esm/components/feedback/Skeleton/Skeleton.js +78 -0
- package/dist/esm/components/feedback/Skeleton/Skeleton.js.map +1 -0
- package/dist/esm/components/feedback/Skeleton/SkeletonGroup.js +58 -0
- package/dist/esm/components/feedback/Skeleton/SkeletonGroup.js.map +1 -0
- package/dist/esm/components/feedback/Spinner/Spinner.css.js +1 -1
- package/dist/esm/components/feedback/Toast/ToastItem.css.js +1 -1
- package/dist/esm/components/form/InputWrapper.css.js +1 -1
- package/dist/esm/components/layout/Accordion/Accordion.css.js +1 -1
- package/dist/esm/components/layout/ScrollArea/ScrollArea.js +17 -20
- package/dist/esm/components/layout/ScrollArea/ScrollArea.js.map +1 -1
- package/dist/esm/components/layout/SplitPane/SplitPane.js +2 -10
- package/dist/esm/components/layout/SplitPane/SplitPane.js.map +1 -1
- package/dist/esm/components/navigation/Breadcrumbs/BreadcrumbEllipsis.js +49 -0
- package/dist/esm/components/navigation/Breadcrumbs/BreadcrumbEllipsis.js.map +1 -0
- package/dist/esm/components/navigation/Breadcrumbs/BreadcrumbItem.js +89 -0
- package/dist/esm/components/navigation/Breadcrumbs/BreadcrumbItem.js.map +1 -0
- package/dist/esm/components/navigation/Breadcrumbs/BreadcrumbSeparator.js +22 -0
- package/dist/esm/components/navigation/Breadcrumbs/BreadcrumbSeparator.js.map +1 -0
- package/dist/esm/components/navigation/Breadcrumbs/Breadcrumbs.css.js +16 -0
- package/dist/esm/components/navigation/Breadcrumbs/Breadcrumbs.css.js.map +1 -0
- package/dist/esm/components/navigation/Breadcrumbs/Breadcrumbs.js +152 -0
- package/dist/esm/components/navigation/Breadcrumbs/Breadcrumbs.js.map +1 -0
- package/dist/esm/components/navigation/SegmentedControl/SegmentedControl.css.js +15 -0
- package/dist/esm/components/navigation/SegmentedControl/SegmentedControl.css.js.map +1 -0
- package/dist/esm/components/navigation/SegmentedControl/SegmentedControl.js +240 -0
- package/dist/esm/components/navigation/SegmentedControl/SegmentedControl.js.map +1 -0
- package/dist/esm/components/navigation/SegmentedControl/SegmentedControlItem.js +83 -0
- package/dist/esm/components/navigation/SegmentedControl/SegmentedControlItem.js.map +1 -0
- package/dist/esm/components/navigation/Tabs/Tab.js +0 -1
- package/dist/esm/components/navigation/Tabs/Tab.js.map +1 -1
- package/dist/esm/components/navigation/Tabs/Tabs.css.js +1 -1
- package/dist/esm/components/primitives/Avatar/Avatar.css.js +16 -0
- package/dist/esm/components/primitives/Avatar/Avatar.css.js.map +1 -0
- package/dist/esm/components/primitives/Avatar/Avatar.js +138 -0
- package/dist/esm/components/primitives/Avatar/Avatar.js.map +1 -0
- package/dist/esm/components/primitives/Avatar/AvatarGroup.js +81 -0
- package/dist/esm/components/primitives/Avatar/AvatarGroup.js.map +1 -0
- package/dist/esm/components/primitives/Button/Button.css.js +1 -1
- package/dist/esm/components/primitives/Checkbox/Checkbox.css.js +1 -1
- package/dist/esm/components/primitives/Checkbox/Checkbox.js +9 -1
- package/dist/esm/components/primitives/Checkbox/Checkbox.js.map +1 -1
- package/dist/esm/components/primitives/Collapsible/Collapsible.css.js +1 -1
- package/dist/esm/components/primitives/IconButton/IconButton.css.js +1 -1
- package/dist/esm/components/primitives/Kbd/Kbd.css.js +9 -0
- package/dist/esm/components/primitives/Kbd/Kbd.css.js.map +1 -0
- package/dist/esm/components/primitives/Kbd/Kbd.js +46 -0
- package/dist/esm/components/primitives/Kbd/Kbd.js.map +1 -0
- package/dist/esm/components/primitives/Link/Link.css.js +11 -0
- package/dist/esm/components/primitives/Link/Link.css.js.map +1 -0
- package/dist/esm/components/primitives/Link/Link.js +160 -0
- package/dist/esm/components/primitives/Link/Link.js.map +1 -0
- package/dist/esm/components/primitives/Popover/Popover.css.js +1 -1
- package/dist/esm/components/primitives/Radio/Radio.css.js +18 -0
- package/dist/esm/components/primitives/Radio/Radio.css.js.map +1 -0
- package/dist/esm/components/primitives/Radio/Radio.js +109 -0
- package/dist/esm/components/primitives/Radio/Radio.js.map +1 -0
- package/dist/esm/components/primitives/Radio/RadioGroup.js +82 -0
- package/dist/esm/components/primitives/Radio/RadioGroup.js.map +1 -0
- package/dist/esm/components/primitives/Switch/Switch.css.js +1 -1
- package/dist/esm/components/primitives/TextArea/TextArea.css.js +1 -1
- package/dist/esm/components/primitives/Tooltip/Tooltip.js +7 -2
- package/dist/esm/components/primitives/Tooltip/Tooltip.js.map +1 -1
- package/dist/esm/components/primitives/VisuallyHidden/VisuallyHidden.css.js +7 -0
- package/dist/esm/components/primitives/VisuallyHidden/VisuallyHidden.css.js.map +1 -0
- package/dist/esm/components/primitives/VisuallyHidden/VisuallyHidden.js +38 -0
- package/dist/esm/components/primitives/VisuallyHidden/VisuallyHidden.js.map +1 -0
- package/dist/esm/components/shell/FloatingPanel/FloatingPanel.js +2 -10
- package/dist/esm/components/shell/FloatingPanel/FloatingPanel.js.map +1 -1
- package/dist/esm/context/KeyboardContext.js +35 -10
- package/dist/esm/context/KeyboardContext.js.map +1 -1
- package/dist/esm/hooks/useClickOutside/useClickOutside.js +60 -0
- package/dist/esm/hooks/useClickOutside/useClickOutside.js.map +1 -0
- package/dist/esm/hooks/useClipboard/useClipboard.js +147 -0
- package/dist/esm/hooks/useClipboard/useClipboard.js.map +1 -0
- package/dist/esm/hooks/useControlledState/useControlledState.js +75 -0
- package/dist/esm/hooks/useControlledState/useControlledState.js.map +1 -0
- package/dist/esm/hooks/useDisclosure/useDisclosure.js +49 -0
- package/dist/esm/hooks/useDisclosure/useDisclosure.js.map +1 -0
- package/dist/esm/{components/feedback/Dialog → hooks/useFocusTrap}/useFocusTrap.js +7 -7
- package/dist/esm/hooks/useFocusTrap/useFocusTrap.js.map +1 -0
- package/dist/esm/hooks/useHotkey/useHotkey.js +203 -0
- package/dist/esm/hooks/useHotkey/useHotkey.js.map +1 -0
- package/dist/esm/hooks/useKeyboard/useKeyboard.js +56 -0
- package/dist/esm/hooks/useKeyboard/useKeyboard.js.map +1 -0
- package/dist/esm/hooks/useKeyboard/utils.js +56 -0
- package/dist/esm/hooks/useKeyboard/utils.js.map +1 -0
- package/dist/esm/hooks/useMergedRef/useMergedRef.js +39 -0
- package/dist/esm/hooks/useMergedRef/useMergedRef.js.map +1 -0
- package/dist/esm/hooks/useResizeObserver/useResizeObserver.js +75 -0
- package/dist/esm/hooks/useResizeObserver/useResizeObserver.js.map +1 -0
- package/dist/esm/hooks/useTheme/useTheme.js +199 -0
- package/dist/esm/hooks/useTheme/useTheme.js.map +1 -0
- package/dist/esm/index.js +104 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/theme/ThemeProvider.js +3 -2
- package/dist/esm/theme/ThemeProvider.js.map +1 -1
- package/dist/esm/theme/createLightTheme.js +29 -0
- package/dist/esm/theme/createLightTheme.js.map +1 -0
- package/dist/esm/theme/darkThemeValues.js +155 -0
- package/dist/esm/theme/darkThemeValues.js.map +1 -0
- package/dist/esm/theme/index.js +10 -0
- package/dist/esm/theme/index.js.map +1 -0
- package/dist/esm/theme/lightTheme.css.js +6 -0
- package/dist/esm/theme/lightTheme.css.js.map +1 -0
- package/dist/esm/theme/lightThemeValues.js +164 -0
- package/dist/esm/theme/lightThemeValues.js.map +1 -0
- package/dist/esm/theme/themeContractData.js +161 -0
- package/dist/esm/theme/themeContractData.js.map +1 -0
- package/dist/esm/theme-values.js +4 -0
- package/dist/esm/theme-values.js.map +1 -0
- package/dist/esm/utils/animations.css.js +8 -6
- package/dist/esm/utils/animations.css.js.map +1 -1
- package/dist/esm/utils/devWarn.js +36 -0
- package/dist/esm/utils/devWarn.js.map +1 -0
- package/dist/esm/utils/platform.js +91 -0
- package/dist/esm/utils/platform.js.map +1 -0
- package/dist/tokens/tokens.dark.css +98 -0
- package/dist/tokens/tokens.json +851 -0
- package/dist/tokens/tokens.light.css +98 -0
- package/dist/types/components/Icons/AddIcon.d.ts +33 -0
- package/dist/types/components/Icons/AiChatIcon.d.ts +34 -0
- package/dist/types/components/Icons/AiSparklesIcon.d.ts +34 -0
- package/dist/types/components/Icons/ArrowDownIcon.d.ts +33 -0
- package/dist/types/components/Icons/ArrowLeftIcon.d.ts +33 -0
- package/dist/types/components/Icons/ArrowRightIcon.d.ts +33 -0
- package/dist/types/components/Icons/ArrowUpIcon.d.ts +33 -0
- package/dist/types/components/Icons/BookmarkIcon.d.ts +33 -0
- package/dist/types/components/Icons/CalendarIcon.d.ts +33 -0
- package/dist/types/components/Icons/CheckIcon.d.ts +33 -0
- package/dist/types/components/Icons/ChevronDownIcon.d.ts +33 -0
- package/dist/types/components/Icons/ChevronUpIcon.d.ts +33 -0
- package/dist/types/components/Icons/CircleIcon.d.ts +33 -0
- package/dist/types/components/Icons/ClockIcon.d.ts +33 -0
- package/dist/types/components/Icons/CloseIcon.d.ts +33 -0
- package/dist/types/components/Icons/CodeIcon.d.ts +33 -0
- package/dist/types/components/Icons/CopyIcon.d.ts +33 -0
- package/dist/types/components/Icons/CutIcon.d.ts +33 -0
- package/dist/types/components/Icons/DownloadIcon.d.ts +33 -0
- package/dist/types/components/Icons/EditIcon.d.ts +33 -0
- package/dist/types/components/Icons/ErrorIcon.d.ts +33 -0
- package/dist/types/components/Icons/EyeDropperIcon.d.ts +34 -0
- package/dist/types/components/Icons/EyeIcon.d.ts +33 -0
- package/dist/types/components/Icons/FilterIcon.d.ts +33 -0
- package/dist/types/components/Icons/FolderIcon.d.ts +33 -0
- package/dist/types/components/Icons/FullscreenIcon.d.ts +33 -0
- package/dist/types/components/Icons/GridIcon.d.ts +33 -0
- package/dist/types/components/Icons/HeartIcon.d.ts +33 -0
- package/dist/types/components/Icons/HelpIcon.d.ts +33 -0
- package/dist/types/components/Icons/HomeIcon.d.ts +33 -0
- package/dist/types/components/Icons/InfoIcon.d.ts +33 -0
- package/dist/types/components/Icons/LinkIcon.d.ts +33 -0
- package/dist/types/components/Icons/ListIcon.d.ts +33 -0
- package/dist/types/components/Icons/LockIcon.d.ts +33 -0
- package/dist/types/components/Icons/MaximizeIcon.d.ts +33 -0
- package/dist/types/components/Icons/MenuIcon.d.ts +33 -0
- package/dist/types/components/Icons/MinimizeIcon.d.ts +33 -0
- package/dist/types/components/Icons/PasteIcon.d.ts +33 -0
- package/dist/types/components/Icons/PlayIcon.d.ts +33 -0
- package/dist/types/components/Icons/RedoIcon.d.ts +33 -0
- package/dist/types/components/Icons/RefreshIcon.d.ts +33 -0
- package/dist/types/components/Icons/RobotIcon.d.ts +33 -0
- package/dist/types/components/Icons/SaveIcon.d.ts +33 -0
- package/dist/types/components/Icons/SearchIcon.d.ts +33 -0
- package/dist/types/components/Icons/SettingsIcon.d.ts +33 -0
- package/dist/types/components/Icons/SortIcon.d.ts +33 -0
- package/dist/types/components/Icons/StarIcon.d.ts +33 -0
- package/dist/types/components/Icons/SuccessIcon.d.ts +33 -0
- package/dist/types/components/Icons/TagIcon.d.ts +33 -0
- package/dist/types/components/Icons/TangentAlignedIcon.d.ts +15 -0
- package/dist/types/components/Icons/TangentAutoIcon.d.ts +15 -0
- package/dist/types/components/Icons/TangentFreeIcon.d.ts +15 -0
- package/dist/types/components/Icons/TangentLinearIcon.d.ts +15 -0
- package/dist/types/components/Icons/TangentMirroredIcon.d.ts +15 -0
- package/dist/types/components/Icons/TangentStepIcon.d.ts +15 -0
- package/dist/types/components/Icons/TrashIcon.d.ts +33 -0
- package/dist/types/components/Icons/UndoIcon.d.ts +33 -0
- package/dist/types/components/Icons/UnlockIcon.d.ts +33 -0
- package/dist/types/components/Icons/UploadIcon.d.ts +33 -0
- package/dist/types/components/Icons/UserIcon.d.ts +33 -0
- package/dist/types/components/Icons/WarningIcon.d.ts +33 -0
- package/dist/types/components/Icons/ZoomInIcon.d.ts +33 -0
- package/dist/types/components/Icons/ZoomOutIcon.d.ts +33 -0
- package/dist/types/components/editor/TransformControl/TransformControl.d.ts +34 -0
- package/dist/types/components/editor/TransformControl/TransformControl.types.d.ts +153 -0
- package/dist/types/components/feedback/Alert/Alert.d.ts +340 -0
- package/dist/types/components/feedback/Alert/Alert.types.d.ts +82 -0
- package/dist/types/components/feedback/Alert/AlertActions.d.ts +306 -0
- package/dist/types/components/feedback/Alert/AlertDescription.d.ts +303 -0
- package/dist/types/components/feedback/Alert/AlertTitle.d.ts +303 -0
- package/dist/types/components/feedback/ProgressBar/CircularProgress.d.ts +313 -0
- package/dist/types/components/feedback/ProgressBar/ProgressBar.d.ts +315 -0
- package/dist/types/components/feedback/ProgressBar/ProgressBar.types.d.ts +132 -0
- package/dist/types/components/feedback/Skeleton/Skeleton.d.ts +312 -0
- package/dist/types/components/feedback/Skeleton/Skeleton.types.d.ts +82 -0
- package/dist/types/components/feedback/Skeleton/SkeletonGroup.d.ts +313 -0
- package/dist/types/components/navigation/Breadcrumbs/BreadcrumbEllipsis.d.ts +297 -0
- package/dist/types/components/navigation/Breadcrumbs/BreadcrumbItem.d.ts +304 -0
- package/dist/types/components/navigation/Breadcrumbs/BreadcrumbSeparator.d.ts +296 -0
- package/dist/types/components/navigation/Breadcrumbs/Breadcrumbs.d.ts +311 -0
- package/dist/types/components/navigation/Breadcrumbs/Breadcrumbs.types.d.ts +89 -0
- package/dist/types/components/navigation/SegmentedControl/SegmentedControl.d.ts +24 -0
- package/dist/types/components/navigation/SegmentedControl/SegmentedControl.types.d.ts +85 -0
- package/dist/types/components/navigation/SegmentedControl/SegmentedControlItem.d.ts +12 -0
- package/dist/types/components/primitives/Avatar/Avatar.d.ts +317 -0
- package/dist/types/components/primitives/Avatar/Avatar.types.d.ts +139 -0
- package/dist/types/components/primitives/Avatar/AvatarGroup.d.ts +316 -0
- package/dist/types/components/primitives/Button/Button.d.ts +2 -2
- package/dist/types/components/primitives/IconButton/IconButton.d.ts +2 -2
- package/dist/types/components/primitives/Kbd/Kbd.d.ts +307 -0
- package/dist/types/components/primitives/Kbd/Kbd.types.d.ts +49 -0
- package/dist/types/components/primitives/Link/Link.d.ts +20 -0
- package/dist/types/components/primitives/Link/Link.types.d.ts +123 -0
- package/dist/types/components/primitives/Radio/Radio.d.ts +319 -0
- package/dist/types/components/primitives/Radio/Radio.types.d.ts +155 -0
- package/dist/types/components/primitives/Radio/RadioGroup.d.ts +320 -0
- package/dist/types/components/primitives/VisuallyHidden/VisuallyHidden.d.ts +316 -0
- package/dist/types/components/primitives/VisuallyHidden/VisuallyHidden.types.d.ts +29 -0
- package/dist/types/context/KeyboardContext.d.ts +20 -0
- package/dist/types/hooks/useClickOutside/useClickOutside.d.ts +37 -0
- package/dist/types/hooks/useClipboard/useClipboard.d.ts +24 -0
- package/dist/types/hooks/useClipboard/useClipboard.types.d.ts +22 -0
- package/dist/types/hooks/useControlledState/useControlledState.d.ts +38 -0
- package/dist/types/hooks/useDisclosure/useDisclosure.d.ts +25 -0
- package/dist/types/hooks/useDisclosure/useDisclosure.types.d.ts +22 -0
- package/dist/types/hooks/useFocusTrap/useFocusTrap.d.ts +30 -0
- package/dist/types/hooks/useHotkey/useHotkey.d.ts +23 -0
- package/dist/types/hooks/useHotkey/useHotkey.types.d.ts +36 -0
- package/dist/types/hooks/useKeyboard/types.d.ts +14 -0
- package/dist/types/hooks/useKeyboard/useKeyboard.d.ts +36 -0
- package/dist/types/hooks/useKeyboard/utils.d.ts +6 -0
- package/dist/types/hooks/useMergedRef/useMergedRef.d.ts +22 -0
- package/dist/types/hooks/useResizeObserver/useResizeObserver.d.ts +35 -0
- package/dist/types/hooks/useTheme/useTheme.d.ts +48 -0
- package/dist/types/hooks/useTheme/useTheme.types.d.ts +60 -0
- package/dist/types/index.d.ts +120 -3
- package/dist/types/theme/contract.css.d.ts +125 -121
- package/dist/types/theme/createCustomTheme.d.ts +1 -1
- package/dist/types/theme/createLightTheme.d.ts +24 -0
- package/dist/types/theme/{darkTheme.css.d.ts → darkThemeValues.d.ts} +6 -2
- package/dist/types/theme/globalScrollbars.css.d.ts +15 -0
- package/dist/types/theme/index.d.ts +9 -0
- package/dist/types/theme/lightTheme.css.d.ts +17 -0
- package/dist/types/theme/lightThemeValues.d.ts +168 -0
- package/dist/types/theme/themeContractData.d.ts +160 -0
- package/dist/types/theme-values.d.ts +10 -0
- package/dist/types/utils/animations.css.d.ts +3 -1
- package/dist/types/utils/platform.d.ts +16 -0
- package/package.json +13 -4
- package/dist/esm/components/feedback/Dialog/useFocusTrap.js.map +0 -1
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useState, useRef, useEffect, useCallback } from 'react';
|
|
3
|
+
import { devWarn } from '../../utils/devWarn.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Manage a value that may be either controlled (via prop) or uncontrolled
|
|
7
|
+
* (managed internally with a default).
|
|
8
|
+
*
|
|
9
|
+
* Returns a `[value, setValue]` tuple just like `useState`. When
|
|
10
|
+
* `options.value` is defined the state is read from there and `setValue`
|
|
11
|
+
* becomes a pure side-effect callback that calls `onChange` only — internal
|
|
12
|
+
* state is never mutated. When `options.value` is undefined the hook owns the
|
|
13
|
+
* state and `setValue` updates it as well as calls `onChange`.
|
|
14
|
+
*
|
|
15
|
+
* Switching between controlled and uncontrolled within a component's lifetime
|
|
16
|
+
* is a known pitfall (matches React's own warning for `<input value/defaultValue>`).
|
|
17
|
+
* The hook emits a development-only warning when this happens.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const [value, setValue] = useControlledState({
|
|
22
|
+
* value: props.value,
|
|
23
|
+
* defaultValue: props.defaultValue,
|
|
24
|
+
* onChange: props.onChange,
|
|
25
|
+
* fallback: '',
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
function useControlledState(options) {
|
|
30
|
+
const { value, defaultValue, onChange, fallback } = options;
|
|
31
|
+
const isControlled = value !== undefined;
|
|
32
|
+
// Only `undefined` means "no defaultValue given" — `null` is a legal value
|
|
33
|
+
// for generic T (e.g. `string | null`) and must not be replaced by fallback.
|
|
34
|
+
const [internalValue, setInternalValue] = useState(
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
36
|
+
defaultValue !== undefined ? defaultValue : fallback);
|
|
37
|
+
// Stable refs to avoid stale closures and unnecessary identity changes.
|
|
38
|
+
const onChangeRef = useRef(onChange);
|
|
39
|
+
const internalValueRef = useRef(internalValue);
|
|
40
|
+
const isControlledRef = useRef(isControlled);
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
onChangeRef.current = onChange;
|
|
43
|
+
}, [onChange]);
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
internalValueRef.current = internalValue;
|
|
46
|
+
}, [internalValue]);
|
|
47
|
+
// Dev-only warning when controlled <-> uncontrolled flips after mount.
|
|
48
|
+
// Mirrors React's behavior for <input value/defaultValue>.
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
const wasControlled = isControlledRef.current;
|
|
51
|
+
if (wasControlled !== isControlled) {
|
|
52
|
+
devWarn(`[useControlledState] Component is changing from ${wasControlled ? 'controlled' : 'uncontrolled'} to ${isControlled ? 'controlled' : 'uncontrolled'}. ` +
|
|
53
|
+
'Components should not switch between controlled and uncontrolled ' +
|
|
54
|
+
'(or vice versa) during their lifetime. Decide between using a ' +
|
|
55
|
+
'controlled or uncontrolled mode for the lifetime of the component.');
|
|
56
|
+
isControlledRef.current = isControlled;
|
|
57
|
+
}
|
|
58
|
+
}, [isControlled]);
|
|
59
|
+
const setValue = useCallback((next) => {
|
|
60
|
+
const prev = isControlledRef.current
|
|
61
|
+
? value
|
|
62
|
+
: internalValueRef.current;
|
|
63
|
+
const resolved = typeof next === 'function' ? next(prev) : next;
|
|
64
|
+
if (!isControlledRef.current) {
|
|
65
|
+
setInternalValue(resolved);
|
|
66
|
+
internalValueRef.current = resolved;
|
|
67
|
+
}
|
|
68
|
+
onChangeRef.current?.(resolved);
|
|
69
|
+
}, [value]);
|
|
70
|
+
const currentValue = isControlled ? value : internalValue;
|
|
71
|
+
return [currentValue, setValue];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export { useControlledState };
|
|
75
|
+
//# sourceMappingURL=useControlledState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useControlledState.js","sources":["../../../../../src/hooks/useControlledState/useControlledState.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAgBA;;;;;;;;;;;;;;;;;;;;;;;AAuBG;AACG;;AAKJ;;;AAIA;;;;AAMA;AACA;AACA;;AAGE;AACF;;AAGE;AACF;;;;AAKE;AACA;;;;AAOM;AAEJ;;AAEJ;AAEA;AAEI;AACE;AACA;AACF;AAGA;;AAEE;;AAEF;AACF;;AAKF;AACF;;"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback, useMemo } from 'react';
|
|
3
|
+
import { useControlledState } from '../useControlledState/useControlledState.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Manage an open/closed state with stable `open`, `close`, `toggle` callbacks.
|
|
7
|
+
*
|
|
8
|
+
* Supports both controlled (driven by an `open` prop) and uncontrolled
|
|
9
|
+
* (managed internally with `defaultOpen`) modes. Built on top of
|
|
10
|
+
* `useControlledState` so the same controlled / uncontrolled rules apply —
|
|
11
|
+
* including the development warning when switching modes mid-life.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* const { isOpen, open, close, toggle } = useDisclosure();
|
|
16
|
+
*
|
|
17
|
+
* return (
|
|
18
|
+
* <>
|
|
19
|
+
* <Button onClick={open}>Open</Button>
|
|
20
|
+
* <Dialog open={isOpen} onClose={close}>...</Dialog>
|
|
21
|
+
* </>
|
|
22
|
+
* );
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
function useDisclosure(options = {}) {
|
|
26
|
+
const { defaultOpen, open: controlledOpen, onOpenChange } = options;
|
|
27
|
+
const [isOpen, setOpenState] = useControlledState({
|
|
28
|
+
value: controlledOpen,
|
|
29
|
+
defaultValue: defaultOpen,
|
|
30
|
+
onChange: onOpenChange,
|
|
31
|
+
fallback: false,
|
|
32
|
+
});
|
|
33
|
+
const setOpen = useCallback((next) => {
|
|
34
|
+
setOpenState(next);
|
|
35
|
+
}, [setOpenState]);
|
|
36
|
+
const open = useCallback(() => {
|
|
37
|
+
setOpenState(true);
|
|
38
|
+
}, [setOpenState]);
|
|
39
|
+
const close = useCallback(() => {
|
|
40
|
+
setOpenState(false);
|
|
41
|
+
}, [setOpenState]);
|
|
42
|
+
const toggle = useCallback(() => {
|
|
43
|
+
setOpenState(prev => !prev);
|
|
44
|
+
}, [setOpenState]);
|
|
45
|
+
return useMemo(() => ({ isOpen, open, close, toggle, setOpen }), [isOpen, open, close, toggle, setOpen]);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { useDisclosure };
|
|
49
|
+
//# sourceMappingURL=useDisclosure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDisclosure.js","sources":["../../../../../src/hooks/useDisclosure/useDisclosure.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;AASA;;;;;;;;;;;;;;;;;;;AAmBG;AACG;;AAKJ;AACE;AACA;AACA;AACA;AACD;AAED;;AAGE;AAIF;;AAEA;AAEA;;AAEA;AAEA;;AAEA;AAEA;AAIF;;"}
|
|
@@ -10,17 +10,17 @@ const FOCUSABLE_SELECTOR = [
|
|
|
10
10
|
'[tabindex]:not([tabindex="-1"])',
|
|
11
11
|
].join(', ');
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* Trap focus within a container element. Tab and Shift+Tab cycle through the
|
|
14
|
+
* focusable descendants without escaping the container.
|
|
14
15
|
*
|
|
15
|
-
*
|
|
16
|
-
* wrapping focus from last to first element and vice versa.
|
|
17
|
-
*
|
|
18
|
-
* @returns onKeyDown handler to attach to the container element
|
|
16
|
+
* Returns a keyboard event handler to attach to the container's `onKeyDown`.
|
|
19
17
|
*
|
|
20
18
|
* @example
|
|
21
19
|
* ```tsx
|
|
22
|
-
* const
|
|
23
|
-
*
|
|
20
|
+
* const ref = useRef<HTMLDivElement>(null);
|
|
21
|
+
* const handleKeyDown = useFocusTrap({ containerRef: ref, enabled: isOpen });
|
|
22
|
+
*
|
|
23
|
+
* return <div ref={ref} onKeyDown={handleKeyDown}>...</div>;
|
|
24
24
|
* ```
|
|
25
25
|
*/
|
|
26
26
|
function useFocusTrap({ containerRef, enabled = true, }) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFocusTrap.js","sources":["../../../../../src/hooks/useFocusTrap/useFocusTrap.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAIA;;;;;;;AAOC;AAaD;;;;;;;;;;;;;AAaG;AACG;AAIJ;AAEI;;AAEA;AACA;;AAEA;AAIA;;;;AAKA;;AAKA;AACE;;;;;;AAKA;;;;;AAKJ;AAGJ;;"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRef, useMemo, useEffect } from 'react';
|
|
3
|
+
import { parseShortcut, getPlatform } from '../../utils/platform.js';
|
|
4
|
+
|
|
5
|
+
function isRefObject(value) {
|
|
6
|
+
return (typeof value === 'object' &&
|
|
7
|
+
value !== null &&
|
|
8
|
+
'current' in value);
|
|
9
|
+
}
|
|
10
|
+
function resolveTarget(target) {
|
|
11
|
+
if (target === undefined) {
|
|
12
|
+
return typeof window === 'undefined' ? null : window;
|
|
13
|
+
}
|
|
14
|
+
if (target === null)
|
|
15
|
+
return null;
|
|
16
|
+
if (isRefObject(target))
|
|
17
|
+
return target.current;
|
|
18
|
+
return target;
|
|
19
|
+
}
|
|
20
|
+
const MODIFIERS = new Set(['ctrl', 'cmd', 'meta', 'alt', 'option', 'shift']);
|
|
21
|
+
const KEY_ALIASES = {
|
|
22
|
+
esc: 'escape',
|
|
23
|
+
return: 'enter',
|
|
24
|
+
space: ' ',
|
|
25
|
+
spacebar: ' ',
|
|
26
|
+
up: 'arrowup',
|
|
27
|
+
down: 'arrowdown',
|
|
28
|
+
left: 'arrowleft',
|
|
29
|
+
right: 'arrowright',
|
|
30
|
+
plus: '+',
|
|
31
|
+
};
|
|
32
|
+
function normalizeKey(key) {
|
|
33
|
+
const lower = key.toLowerCase();
|
|
34
|
+
return KEY_ALIASES[lower] ?? lower;
|
|
35
|
+
}
|
|
36
|
+
function parseCombo(combo) {
|
|
37
|
+
const parts = parseShortcut(combo);
|
|
38
|
+
if (parts.length === 0)
|
|
39
|
+
return null;
|
|
40
|
+
const platform = getPlatform();
|
|
41
|
+
const isMac = platform === 'mac';
|
|
42
|
+
let ctrl = false;
|
|
43
|
+
let meta = false;
|
|
44
|
+
let alt = false;
|
|
45
|
+
let shift = false;
|
|
46
|
+
let key = null;
|
|
47
|
+
for (const raw of parts) {
|
|
48
|
+
const lower = raw.toLowerCase();
|
|
49
|
+
if (MODIFIERS.has(lower)) {
|
|
50
|
+
switch (lower) {
|
|
51
|
+
case 'ctrl':
|
|
52
|
+
ctrl = true;
|
|
53
|
+
break;
|
|
54
|
+
case 'cmd':
|
|
55
|
+
// Cmd auto-maps to Ctrl on non-Mac.
|
|
56
|
+
if (isMac) {
|
|
57
|
+
meta = true;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
ctrl = true;
|
|
61
|
+
}
|
|
62
|
+
break;
|
|
63
|
+
case 'meta':
|
|
64
|
+
meta = true;
|
|
65
|
+
break;
|
|
66
|
+
case 'alt':
|
|
67
|
+
case 'option':
|
|
68
|
+
alt = true;
|
|
69
|
+
break;
|
|
70
|
+
case 'shift':
|
|
71
|
+
shift = true;
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
key = normalizeKey(raw);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (key === null)
|
|
80
|
+
return null;
|
|
81
|
+
return { ctrl, meta, alt, shift, key };
|
|
82
|
+
}
|
|
83
|
+
function isEditableTarget(target) {
|
|
84
|
+
if (!(target instanceof HTMLElement))
|
|
85
|
+
return false;
|
|
86
|
+
if (target.isContentEditable)
|
|
87
|
+
return true;
|
|
88
|
+
const tag = target.tagName;
|
|
89
|
+
if (tag === 'INPUT') {
|
|
90
|
+
const type = target.type.toLowerCase();
|
|
91
|
+
// Buttons and similar non-text inputs should not block hotkeys.
|
|
92
|
+
const nonEditable = new Set([
|
|
93
|
+
'button',
|
|
94
|
+
'submit',
|
|
95
|
+
'reset',
|
|
96
|
+
'checkbox',
|
|
97
|
+
'radio',
|
|
98
|
+
'file',
|
|
99
|
+
'image',
|
|
100
|
+
'range',
|
|
101
|
+
'color',
|
|
102
|
+
]);
|
|
103
|
+
return !nonEditable.has(type);
|
|
104
|
+
}
|
|
105
|
+
return tag === 'TEXTAREA' || tag === 'SELECT';
|
|
106
|
+
}
|
|
107
|
+
function matches(parsed, event) {
|
|
108
|
+
if (event.ctrlKey !== parsed.ctrl)
|
|
109
|
+
return false;
|
|
110
|
+
if (event.metaKey !== parsed.meta)
|
|
111
|
+
return false;
|
|
112
|
+
if (event.altKey !== parsed.alt)
|
|
113
|
+
return false;
|
|
114
|
+
if (event.shiftKey !== parsed.shift)
|
|
115
|
+
return false;
|
|
116
|
+
const eventKey = event.key.toLowerCase();
|
|
117
|
+
return eventKey === parsed.key;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Bind a single keyboard combo to a callback.
|
|
121
|
+
*
|
|
122
|
+
* Combos use the same `+`-separated string format as `MenuBar`'s `shortcut`
|
|
123
|
+
* prop: `"Ctrl+S"`, `"Cmd+Shift+P"`, `"Escape"`. Modifiers: `Ctrl`, `Cmd`
|
|
124
|
+
* (= Meta), `Alt` / `Option`, `Shift`. `Cmd` automatically maps to `Ctrl` on
|
|
125
|
+
* non-Mac platforms via `getPlatform()`.
|
|
126
|
+
*
|
|
127
|
+
* The handler reference is stable — passing a fresh inline function on every
|
|
128
|
+
* render is safe and does not re-subscribe the underlying listener.
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```tsx
|
|
132
|
+
* useHotkey('Ctrl+S', e => save(), { preventDefault: true });
|
|
133
|
+
* useHotkey('Escape', () => setOpen(false));
|
|
134
|
+
* useHotkey('Cmd+K', () => openCommandPalette()); // Cmd on Mac, Ctrl elsewhere
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
function useHotkey(combo, handler, options = {}) {
|
|
138
|
+
const { enabled = true, enableInInputs = false, preventDefault = true, stopPropagation = false, target, } = options;
|
|
139
|
+
const handlerRef = useRef(handler);
|
|
140
|
+
handlerRef.current = handler;
|
|
141
|
+
const optionsRef = useRef({
|
|
142
|
+
enabled,
|
|
143
|
+
enableInInputs,
|
|
144
|
+
preventDefault,
|
|
145
|
+
stopPropagation,
|
|
146
|
+
});
|
|
147
|
+
optionsRef.current = {
|
|
148
|
+
enabled,
|
|
149
|
+
enableInInputs,
|
|
150
|
+
preventDefault,
|
|
151
|
+
stopPropagation,
|
|
152
|
+
};
|
|
153
|
+
const parsed = useMemo(() => parseCombo(combo), [combo]);
|
|
154
|
+
const parsedRef = useRef(parsed);
|
|
155
|
+
parsedRef.current = parsed;
|
|
156
|
+
const attachedTargetRef = useRef(null);
|
|
157
|
+
const listenerRef = useRef(null);
|
|
158
|
+
// Runs every render so a ref whose `.current` becomes available after the
|
|
159
|
+
// first render (conditional rendering, lazy children) is picked up. The
|
|
160
|
+
// identity check on the resolved target keeps re-attaches limited to the
|
|
161
|
+
// moments the underlying element actually changes.
|
|
162
|
+
useEffect(() => {
|
|
163
|
+
const desired = enabled && parsed !== null ? resolveTarget(target) : null;
|
|
164
|
+
if (desired === attachedTargetRef.current)
|
|
165
|
+
return;
|
|
166
|
+
if (attachedTargetRef.current && listenerRef.current) {
|
|
167
|
+
attachedTargetRef.current.removeEventListener('keydown', listenerRef.current);
|
|
168
|
+
}
|
|
169
|
+
attachedTargetRef.current = desired;
|
|
170
|
+
if (desired === null) {
|
|
171
|
+
listenerRef.current = null;
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const listener = (event) => {
|
|
175
|
+
const ke = event;
|
|
176
|
+
const opts = optionsRef.current;
|
|
177
|
+
const p = parsedRef.current;
|
|
178
|
+
if (p === null || !opts.enabled)
|
|
179
|
+
return;
|
|
180
|
+
if (!matches(p, ke))
|
|
181
|
+
return;
|
|
182
|
+
if (!opts.enableInInputs && isEditableTarget(ke.target))
|
|
183
|
+
return;
|
|
184
|
+
if (opts.preventDefault)
|
|
185
|
+
ke.preventDefault();
|
|
186
|
+
handlerRef.current(ke);
|
|
187
|
+
if (opts.stopPropagation)
|
|
188
|
+
ke.stopPropagation();
|
|
189
|
+
};
|
|
190
|
+
listenerRef.current = listener;
|
|
191
|
+
desired.addEventListener('keydown', listener);
|
|
192
|
+
});
|
|
193
|
+
useEffect(() => () => {
|
|
194
|
+
if (attachedTargetRef.current && listenerRef.current) {
|
|
195
|
+
attachedTargetRef.current.removeEventListener('keydown', listenerRef.current);
|
|
196
|
+
}
|
|
197
|
+
attachedTargetRef.current = null;
|
|
198
|
+
listenerRef.current = null;
|
|
199
|
+
}, []);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export { useHotkey };
|
|
203
|
+
//# sourceMappingURL=useHotkey.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useHotkey.js","sources":["../../../../../src/hooks/useHotkey/useHotkey.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAMA;AACE;AAEE;;AAGJ;AAEA;AACE;AACE;;;AAEmB;;;AAErB;AACF;AAWA;AAEA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGF;AACE;AACA;AACF;AAEA;AACE;AACA;AAAwB;AAExB;AACA;;;;;;AAQA;AACE;AACA;;AAEI;;;AAGA;;;;;;;;;AAQA;;;AAGA;AACA;;;AAGA;;;;;;AAKF;;;;AAIc;;AAEpB;AAEA;AACE;AAAsC;;AACR;AAC9B;AACA;;;AAGE;;;;;;;;;;AAUC;AACD;;AAEF;AACF;AAEA;AACE;AAAmC;AACnC;AAAmC;AACnC;AAAiC;AACjC;AAAqC;;AAGrC;AACF;AAEA;;;;;;;;;;;;;;;;;AAiBG;AACG;;AAaJ;AACA;;;;;;AAOC;;;;;;;AAQD;AACA;AACA;AAEA;AACA;;;;;;AAOE;AACA;;;;;AAQA;AACA;AACE;;;AAIF;;AAEE;AACA;AACA;;AACA;;;;;;AAIA;;;AAEF;AACA;AACA;AACF;AAEA;;;;AAQI;AACA;;AAIN;;"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useState, useCallback, useEffect, useMemo } from 'react';
|
|
3
|
+
import { updateState, mapInnerStateToState } from './utils.js';
|
|
4
|
+
export { isKeyPressed, isModifierKey } from './utils.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Hook for tracking keyboard state including modifier keys and pressed keys.
|
|
8
|
+
*
|
|
9
|
+
* Useful for components that need to respond to keyboard modifiers like
|
|
10
|
+
* Ctrl+drag for snapping, Shift+drag for precision, etc.
|
|
11
|
+
* @returns Current keyboard state
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* // Track all keys and modifiers
|
|
16
|
+
* const keyboard = useKeyboard();
|
|
17
|
+
*
|
|
18
|
+
* const handleMouseMove = (e: MouseEvent) => {
|
|
19
|
+
* if (keyboard.ctrl) {
|
|
20
|
+
* // Snap to grid
|
|
21
|
+
* } else if (keyboard.shift) {
|
|
22
|
+
* // Precision mode
|
|
23
|
+
* }
|
|
24
|
+
* };
|
|
25
|
+
*
|
|
26
|
+
* // Track only specific keys
|
|
27
|
+
* const keyboard = useKeyboard({
|
|
28
|
+
* trackAllKeys: false,
|
|
29
|
+
* trackedKeys: ['Space', 'Enter', 'Escape']
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* // Check if specific key is pressed
|
|
33
|
+
* const isSpacePressed = keyboard.pressedKeys.includes('Space');
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
const useKeyboard = () => {
|
|
37
|
+
const [keyboardState, setKeyboardState] = useState(new Set());
|
|
38
|
+
const handleKeyDown = useCallback((event) => {
|
|
39
|
+
setKeyboardState(prevState => updateState(prevState, event));
|
|
40
|
+
}, []);
|
|
41
|
+
const handleKeyUp = useCallback((event) => {
|
|
42
|
+
setKeyboardState(prevState => updateState(prevState, event));
|
|
43
|
+
}, []);
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
46
|
+
window.addEventListener('keyup', handleKeyUp);
|
|
47
|
+
return () => {
|
|
48
|
+
window.removeEventListener('keydown', handleKeyDown);
|
|
49
|
+
window.removeEventListener('keyup', handleKeyUp);
|
|
50
|
+
};
|
|
51
|
+
}, [handleKeyDown, handleKeyUp]);
|
|
52
|
+
return useMemo(() => mapInnerStateToState(keyboardState), [keyboardState]);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export { useKeyboard };
|
|
56
|
+
//# sourceMappingURL=useKeyboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useKeyboard.js","sources":["../../../../../src/hooks/useKeyboard/useKeyboard.tsx"],"sourcesContent":[null],"names":[],"mappings":";;;;;AAUA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BG;AACI;AACL;AAIA;AACE;;AAGF;AACE;;;AAIA;AACA;AAEA;AACE;AACA;AACF;AACF;AAEA;AACF;;"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { devWarn } from '../../utils/devWarn.js';
|
|
2
|
+
|
|
3
|
+
const isModifierKey = (key) => {
|
|
4
|
+
return ['ctrl', 'shift', 'alt', 'meta', 'control'].includes(key);
|
|
5
|
+
};
|
|
6
|
+
const KeypressUpdate = (prevState, key) => {
|
|
7
|
+
if (prevState.has(key)) {
|
|
8
|
+
return prevState;
|
|
9
|
+
}
|
|
10
|
+
const newState = new Set(prevState);
|
|
11
|
+
newState.add(key);
|
|
12
|
+
return newState;
|
|
13
|
+
};
|
|
14
|
+
const KeyReleaseUpdate = (prevState, key) => {
|
|
15
|
+
if (!prevState.has(key)) {
|
|
16
|
+
return prevState;
|
|
17
|
+
}
|
|
18
|
+
const newState = new Set(prevState);
|
|
19
|
+
newState.delete(key);
|
|
20
|
+
return newState;
|
|
21
|
+
};
|
|
22
|
+
const updateState = (prevState, event) => {
|
|
23
|
+
const key = event.key.toLowerCase();
|
|
24
|
+
const eventType = event.type;
|
|
25
|
+
switch (eventType) {
|
|
26
|
+
case 'keydown':
|
|
27
|
+
return KeypressUpdate(prevState, key);
|
|
28
|
+
case 'keyup':
|
|
29
|
+
return KeyReleaseUpdate(prevState, key);
|
|
30
|
+
default:
|
|
31
|
+
devWarn(`Unhandled event type: ${eventType}`);
|
|
32
|
+
return prevState;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
const mapInnerStateToState = (innerState) => {
|
|
36
|
+
const modifiers = {
|
|
37
|
+
control: innerState.has('control') || innerState.has('ctrl'),
|
|
38
|
+
shift: innerState.has('shift'),
|
|
39
|
+
alt: innerState.has('alt'),
|
|
40
|
+
meta: innerState.has('meta'),
|
|
41
|
+
};
|
|
42
|
+
const pressedKeys = Array.from(innerState).filter(key => !isModifierKey(key));
|
|
43
|
+
return {
|
|
44
|
+
pressedKeys,
|
|
45
|
+
modifiers,
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
const isKeyPressed = (keyboardState, key) => {
|
|
49
|
+
if (isModifierKey(key)) {
|
|
50
|
+
return keyboardState.modifiers[key];
|
|
51
|
+
}
|
|
52
|
+
return keyboardState.pressedKeys.includes(key);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export { isKeyPressed, isModifierKey, mapInnerStateToState, updateState };
|
|
56
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../../../../../src/hooks/useKeyboard/utils.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAQO,MAAM,aAAa,GAAG,CAAC,GAAW,KAAyB;AAChE,IAAA,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;AAClE;AAEA,MAAM,cAAc,GAAG,CACrB,SAA6B,EAC7B,GAAY,KACU;AACtB,IAAA,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;AACtB,QAAA,OAAO,SAAS;IAClB;AACA,IAAA,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC;AACnC,IAAA,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;AACjB,IAAA,OAAO,QAAQ;AACjB,CAAC;AAED,MAAM,gBAAgB,GAAG,CACvB,SAA6B,EAC7B,GAAY,KACU;IACtB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;AACvB,QAAA,OAAO,SAAS;IAClB;AACA,IAAA,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC;AACnC,IAAA,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC;AACpB,IAAA,OAAO,QAAQ;AACjB,CAAC;MAEY,WAAW,GAAG,CACzB,SAA6B,EAC7B,KAAoB,KACE;IACtB,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE;AACnC,IAAA,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI;IAC5B,QAAQ,SAAS;AACf,QAAA,KAAK,SAAS;AACZ,YAAA,OAAO,cAAc,CAAC,SAAS,EAAE,GAAG,CAAC;AACvC,QAAA,KAAK,OAAO;AACV,YAAA,OAAO,gBAAgB,CAAC,SAAS,EAAE,GAAG,CAAC;AACzC,QAAA;AACE,YAAA,OAAO,CAAC,CAAA,sBAAA,EAAyB,SAAS,CAAA,CAAE,CAAC;AAC7C,YAAA,OAAO,SAAS;;AAEtB;AAEO,MAAM,oBAAoB,GAAG,CAClC,UAA8B,KACb;AACjB,IAAA,MAAM,SAAS,GAA+B;AAC5C,QAAA,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC;AAC5D,QAAA,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC;AAC9B,QAAA,GAAG,EAAE,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC;AAC1B,QAAA,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC;KAC7B;IACD,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAC7E,OAAO;QACL,WAAW;QACX,SAAS;KACV;AACH;MAEa,YAAY,GAAG,CAC1B,aAA4B,EAC5B,GAAY,KACD;AACX,IAAA,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE;AACtB,QAAA,OAAO,aAAa,CAAC,SAAS,CAAC,GAAG,CAAC;IACrC;IACA,OAAO,aAAa,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC;AAChD;;;;"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Merge multiple refs into a single callback ref. Each provided ref (object
|
|
6
|
+
* ref, callback ref, or `null`/`undefined`) receives the node when the merged
|
|
7
|
+
* ref fires.
|
|
8
|
+
*
|
|
9
|
+
* Useful when a component needs to keep an internal ref to a DOM node while
|
|
10
|
+
* also forwarding the same node through an externally supplied `ref` prop
|
|
11
|
+
* (ref-as-prop in React 19).
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* const internalRef = useRef<HTMLDivElement>(null);
|
|
16
|
+
* const mergedRef = useMergedRef(internalRef, props.ref);
|
|
17
|
+
*
|
|
18
|
+
* return <div ref={mergedRef} />;
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
function useMergedRef(...refs) {
|
|
22
|
+
// The spread of refs is intentional — the merged callback must pick up the
|
|
23
|
+
// latest set of refs the consumer is passing in.
|
|
24
|
+
return useCallback((node) => {
|
|
25
|
+
for (const ref of refs) {
|
|
26
|
+
if (!ref)
|
|
27
|
+
continue;
|
|
28
|
+
if (typeof ref === 'function') {
|
|
29
|
+
ref(node);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
ref.current = node;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}, refs);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { useMergedRef };
|
|
39
|
+
//# sourceMappingURL=useMergedRef.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMergedRef.js","sources":["../../../../../src/hooks/useMergedRef/useMergedRef.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAIA;;;;;;;;;;;;;;;;AAgBG;AACG;;;AAKJ;AACE;AACE;;AACA;;;;AAGG;;;;AAIT;;"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRef, useEffect } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Observe size changes on an element. SSR-safe; cleans up on unmount.
|
|
6
|
+
*
|
|
7
|
+
* The callback is wrapped in a ref so consumers do not have to memoize it —
|
|
8
|
+
* the underlying observer never re-subscribes when the callback identity
|
|
9
|
+
* changes.
|
|
10
|
+
*
|
|
11
|
+
* The hook re-checks `ref.current` on every render so it picks up nodes that
|
|
12
|
+
* mount later (e.g. through conditional rendering). When the observed node
|
|
13
|
+
* has not changed the only cost is a single identity comparison.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* const ref = useRef<HTMLDivElement>(null);
|
|
18
|
+
* useResizeObserver(ref, entry => {
|
|
19
|
+
* console.log(entry.contentRect.width);
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* return <div ref={ref} />;
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
function useResizeObserver(ref, callback, options) {
|
|
26
|
+
const { enabled = true } = options ?? {};
|
|
27
|
+
const callbackRef = useRef(callback);
|
|
28
|
+
const observerRef = useRef(null);
|
|
29
|
+
const observedNodeRef = useRef(null);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
callbackRef.current = callback;
|
|
32
|
+
}, [callback]);
|
|
33
|
+
// Runs on every render so a node that mounts after the first render
|
|
34
|
+
// (conditional rendering, lazy children, suspense fallback flips, ...) is
|
|
35
|
+
// picked up automatically. Short-circuits on the common case where the
|
|
36
|
+
// observed node has not changed.
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (typeof ResizeObserver === 'undefined')
|
|
39
|
+
return;
|
|
40
|
+
if (!enabled) {
|
|
41
|
+
if (observerRef.current) {
|
|
42
|
+
observerRef.current.disconnect();
|
|
43
|
+
observerRef.current = null;
|
|
44
|
+
observedNodeRef.current = null;
|
|
45
|
+
}
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const node = ref.current;
|
|
49
|
+
if (node === observedNodeRef.current)
|
|
50
|
+
return;
|
|
51
|
+
if (observerRef.current) {
|
|
52
|
+
observerRef.current.disconnect();
|
|
53
|
+
observerRef.current = null;
|
|
54
|
+
}
|
|
55
|
+
observedNodeRef.current = node;
|
|
56
|
+
if (!node)
|
|
57
|
+
return;
|
|
58
|
+
const observer = new ResizeObserver(entries => {
|
|
59
|
+
for (const entry of entries) {
|
|
60
|
+
callbackRef.current(entry);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
observer.observe(node);
|
|
64
|
+
observerRef.current = observer;
|
|
65
|
+
});
|
|
66
|
+
// Final cleanup on unmount.
|
|
67
|
+
useEffect(() => () => {
|
|
68
|
+
observerRef.current?.disconnect();
|
|
69
|
+
observerRef.current = null;
|
|
70
|
+
observedNodeRef.current = null;
|
|
71
|
+
}, []);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export { useResizeObserver };
|
|
75
|
+
//# sourceMappingURL=useResizeObserver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useResizeObserver.js","sources":["../../../../../src/hooks/useResizeObserver/useResizeObserver.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAaA;;;;;;;;;;;;;;;;;;;;AAoBG;;;AAQD;AACA;AACA;;AAGE;AACF;;;;;;;;;AAUI;AACE;AACA;AACA;;;;AAKJ;AACA;;AAEA;AACE;AACA;;AAEF;AACA;;AAEA;AACE;AACE;;AAEJ;AACA;AACA;AACF;;AAGA;AAEI;AACA;AACA;;AAIN;;"}
|