diff --git a/theatre/studio/src/panels/DetailPanel/ProjectDetails.tsx b/theatre/studio/src/panels/DetailPanel/ProjectDetails.tsx index aba7d8a..aeb347c 100644 --- a/theatre/studio/src/panels/DetailPanel/ProjectDetails.tsx +++ b/theatre/studio/src/panels/DetailPanel/ProjectDetails.tsx @@ -55,7 +55,7 @@ const ProjectDetails: React.FC<{ }, 40000) }, []) - const {node: tooltip, open: openExportTooltip} = usePopover( + const [tooltip, openExportTooltip] = usePopover( {debugName: 'ProjectDetails', pointerDistanceThreshold: 50}, () => ( diff --git a/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/AggregatedKeyframeTrack/AggregateKeyframeEditor/AggregateKeyframeConnector.tsx b/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/AggregatedKeyframeTrack/AggregateKeyframeEditor/AggregateKeyframeConnector.tsx index 218602d..99cebe7 100644 --- a/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/AggregatedKeyframeTrack/AggregateKeyframeEditor/AggregateKeyframeConnector.tsx +++ b/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/AggregatedKeyframeTrack/AggregateKeyframeEditor/AggregateKeyframeConnector.tsx @@ -55,11 +55,7 @@ export const AggregateKeyframeConnector: React.VFC { const rightDims = val(editorProps.layoutP.rightDims) @@ -93,7 +89,7 @@ export const AggregateKeyframeConnector: React.VFC { - if (node) togglePopover(e, node) + if (node) openPopover(e, node) }} /> {popoverNode} diff --git a/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/BasicKeyframeConnector.tsx b/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/BasicKeyframeConnector.tsx index 7038963..451b7a4 100644 --- a/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/BasicKeyframeConnector.tsx +++ b/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/BasicKeyframeConnector.tsx @@ -41,11 +41,7 @@ const BasicKeyframeConnector: React.VFC = ( const [nodeRef, node] = useRefAndState(null) - const { - node: popoverNode, - toggle: togglePopover, - close: closePopover, - } = usePopover( + const [popoverNode, openPopover, closePopover, isPopoverOpen] = usePopover( () => { const rightDims = val(props.layoutP.rightDims) return { @@ -87,7 +83,7 @@ const BasicKeyframeConnector: React.VFC = ( connectorLengthInUnitSpace={connectorLengthInUnitSpace} {...themeValues} openPopover={(e) => { - if (node) togglePopover(e, node) + if (node) openPopover(e, node) }} > {popoverNode} diff --git a/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/SingleKeyframeDot.tsx b/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/SingleKeyframeDot.tsx index 3f6087d..0cc379f 100644 --- a/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/SingleKeyframeDot.tsx +++ b/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/BasicKeyframedTrack/KeyframeEditor/SingleKeyframeDot.tsx @@ -94,14 +94,11 @@ const SingleKeyframeDot: React.VFC = (props) => { const [ref, node] = useRefAndState(null) const [contextMenu] = useSingleKeyframeContextMenu(node, logger, props) - const { - node: inlineEditorPopover, - toggle: toggleEditor, - isOpen: isInlineEditorPopoverOpen, - } = useSingleKeyframeInlineEditorPopover(props) + const [inlineEditorPopover, openEditor, _, isInlineEditorPopoverOpen] = + useSingleKeyframeInlineEditorPopover(props) const [isDragging] = useDragForSingleKeyframeDot(node, props, { onClickFromDrag(dragStartEvent) { - toggleEditor(dragStartEvent, ref.current!) + openEditor(dragStartEvent, ref.current!) }, }) @@ -230,8 +227,6 @@ function useDragForSingleKeyframeDot( const propsRef = useRef(props) propsRef.current = props - const {onClickFromDrag} = options - const useDragOpts = useMemo(() => { return { debugName: 'KeyframeDot/useDragKeyframe', @@ -287,7 +282,7 @@ function useDragForSingleKeyframeDot( return ( handlers && { ...handlers, - onClick: onClickFromDrag, + onClick: options.onClickFromDrag, onDragEnd: (...args) => { handlers.onDragEnd?.(...args) snapToNone() @@ -343,12 +338,12 @@ function useDragForSingleKeyframeDot( snapToNone() }, onClick(ev) { - onClickFromDrag(ev) + options.onClickFromDrag(ev) }, } }, } - }, [onClickFromDrag]) + }, []) const [isDragging] = useDrag(node, useDragOpts) diff --git a/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/LengthIndicator/LengthEditorPopover.tsx b/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/LengthIndicator/LengthEditorPopover.tsx index 82dbb5d..006f5de 100644 --- a/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/LengthIndicator/LengthEditorPopover.tsx +++ b/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/LengthIndicator/LengthEditorPopover.tsx @@ -32,7 +32,7 @@ const LengthEditorPopover: React.FC<{ * Called when user hits enter/escape */ onRequestClose: (reason: string) => void -}> = ({layoutP}) => { +}> = ({layoutP, onRequestClose}) => { const sheet = useVal(layoutP.sheet) const fns = useMemo(() => { @@ -89,6 +89,7 @@ const LengthEditorPopover: React.FC<{ {...fns} isValid={greaterThanZero} inputRef={inputRef} + onBlur={onRequestClose.bind(null, 'length editor number input blur')} nudge={nudge} /> diff --git a/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/LengthIndicator/LengthIndicator.tsx b/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/LengthIndicator/LengthIndicator.tsx index 461aebf..fb81d37 100644 --- a/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/LengthIndicator/LengthIndicator.tsx +++ b/theatre/studio/src/panels/SequenceEditorPanel/DopeSheet/Right/LengthIndicator/LengthIndicator.tsx @@ -138,17 +138,19 @@ const RENDER_OUT_OF_VIEW_X = -10000 const LengthIndicator: React.FC = ({layoutP}) => { const [nodeRef, node] = useRefAndState(null) const [isDragging] = useDragBulge(node, {layoutP}) - const { - node: popoverNode, - toggle: togglePopover, - close: closePopover, - } = usePopover({debugName: 'LengthIndicator'}, () => { - return ( - - - - ) - }) + const [popoverNode, openPopover, closePopover, isPopoverOpen] = usePopover( + {debugName: 'LengthIndicator'}, + () => { + return ( + + + + ) + }, + ) return usePrism(() => { const sheet = val(layoutP.sheet) @@ -189,7 +191,7 @@ const LengthIndicator: React.FC = ({layoutP}) => { ref={nodeRef} // title="Length of the sequence. Drag or click to change." onClick={(e) => { - togglePopover(e, node!) + openPopover(e, node!) }} {...includeLockFrameStampAttrs('hide')} > diff --git a/theatre/studio/src/panels/SequenceEditorPanel/RightOverlay/Playhead.tsx b/theatre/studio/src/panels/SequenceEditorPanel/RightOverlay/Playhead.tsx index b19ac57..6af70b5 100644 --- a/theatre/studio/src/panels/SequenceEditorPanel/RightOverlay/Playhead.tsx +++ b/theatre/studio/src/panels/SequenceEditorPanel/RightOverlay/Playhead.tsx @@ -193,20 +193,19 @@ const Playhead: React.FC<{layoutP: Pointer}> = ({ }) => { const [thumbRef, thumbNode] = useRefAndState(null) - const { - node: popoverNode, - toggle: togglePopover, - close: closePopover, - } = usePopover({debugName: 'Playhead'}, () => { - return ( - - - - ) - }) + const [popoverNode, openPopover, closePopover, isPopoverOpen] = usePopover( + {debugName: 'Playhead'}, + () => { + return ( + + + + ) + }, + ) const gestureHandlers = useMemo((): Parameters[1] => { return { @@ -237,7 +236,7 @@ const Playhead: React.FC<{layoutP: Pointer}> = ({ snapToNone() }, onClick(e) { - togglePopover(e, thumbRef.current!) + openPopover(e, thumbRef.current!) }, } }, diff --git a/theatre/studio/src/panels/SequenceEditorPanel/RightOverlay/PlayheadPositionPopover.tsx b/theatre/studio/src/panels/SequenceEditorPanel/RightOverlay/PlayheadPositionPopover.tsx index 27b4f73..492d673 100644 --- a/theatre/studio/src/panels/SequenceEditorPanel/RightOverlay/PlayheadPositionPopover.tsx +++ b/theatre/studio/src/panels/SequenceEditorPanel/RightOverlay/PlayheadPositionPopover.tsx @@ -33,7 +33,7 @@ const PlayheadPositionPopover: React.FC<{ * Called when user hits enter/escape */ onRequestClose: (reason: string) => void -}> = ({layoutP}) => { +}> = ({layoutP, onRequestClose}) => { const sheet = val(layoutP.sheet) const sequence = sheet.getSequence() @@ -80,6 +80,7 @@ const PlayheadPositionPopover: React.FC<{ {...fns} isValid={greaterThanZero} inputRef={inputRef} + onBlur={onRequestClose.bind(null, 'number input blur')} nudge={nudge} /> diff --git a/theatre/studio/src/propEditors/simpleEditors/RgbaPropEditor.tsx b/theatre/studio/src/propEditors/simpleEditors/RgbaPropEditor.tsx index 91fa27b..39dbab2 100644 --- a/theatre/studio/src/propEditors/simpleEditors/RgbaPropEditor.tsx +++ b/theatre/studio/src/propEditors/simpleEditors/RgbaPropEditor.tsx @@ -74,7 +74,7 @@ function RgbaPropEditor({ [editingTools], ) - const {node: popoverNode, toggle: togglePopover} = usePopover( + const [popoverNode, openPopover] = usePopover( {debugName: 'RgbaPropEditor'}, () => ( @@ -107,7 +107,7 @@ function RgbaPropEditor({ rgbaColor={value} ref={containerRef} onClick={(e) => { - togglePopover(e, containerRef.current) + openPopover(e, containerRef.current) }} /> { const hasUpdates = useVal(getStudio().atomP.ahistoric.updateChecker.result.hasUpdates) === true - const {node: moreMenu, toggle: toggleMenu} = usePopover( + const [moreMenu, openMoreMenu] = usePopover( () => { const triggerBounds = moreMenuTriggerRef.current!.getBoundingClientRect() return { @@ -138,7 +138,7 @@ const GlobalToolbar: React.FC = () => { { - toggleMenu(e, moreMenuTriggerRef.current!) + openMoreMenu(e, moreMenuTriggerRef.current!) }} > diff --git a/theatre/studio/src/uiComponents/Popover/TooltipWrapper.tsx b/theatre/studio/src/uiComponents/Popover/TooltipWrapper.tsx index 57b31d6..234afbc 100644 --- a/theatre/studio/src/uiComponents/Popover/TooltipWrapper.tsx +++ b/theatre/studio/src/uiComponents/Popover/TooltipWrapper.tsx @@ -138,10 +138,7 @@ const TooltipWrapper: React.FC<{ props.onPointerOutside, ]) - useOnClickOutside( - [container, props.target ?? null], - props.onClickOutside ?? noop, - ) + useOnClickOutside(container, props.onClickOutside ?? noop) return ( diff --git a/theatre/studio/src/uiComponents/Popover/usePopover.tsx b/theatre/studio/src/uiComponents/Popover/usePopover.tsx index f2567a7..f284069 100644 --- a/theatre/studio/src/uiComponents/Popover/usePopover.tsx +++ b/theatre/studio/src/uiComponents/Popover/usePopover.tsx @@ -51,13 +51,7 @@ type Opts = { export default function usePopover( opts: Opts | (() => Opts), render: () => React.ReactElement, -): { - node: React.ReactNode - open: OpenFn - close: CloseFn - toggle: OpenFn - isOpen: boolean -} { +): [node: React.ReactNode, open: OpenFn, close: CloseFn, isOpen: boolean] { const _debug = (...args: any) => {} // want to make sure that we don't close a popover when dragging something (like a curve editor handle) @@ -110,14 +104,6 @@ export default function usePopover( } }, []) - const toggle = useCallback((...args) => { - if (stateRef.current.isOpen) { - close('toggled') - } else { - open(...args) - } - }, []) - /** * See doc comment on {@link useAutoCloseLockState}. * Used to ensure that moving far away from a parent popover doesn't @@ -160,7 +146,7 @@ export default function usePopover( <> ) - return {node, open, close, toggle, isOpen: state.isOpen} + return [node, open, close, state.isOpen] } /** diff --git a/theatre/studio/src/uiComponents/useOnClickOutside.ts b/theatre/studio/src/uiComponents/useOnClickOutside.ts index ac729a5..96d533f 100644 --- a/theatre/studio/src/uiComponents/useOnClickOutside.ts +++ b/theatre/studio/src/uiComponents/useOnClickOutside.ts @@ -2,24 +2,15 @@ import type {$IntentionalAny} from '@theatre/shared/utils/types' import {useEffect} from 'react' export default function useOnClickOutside( - container: Element | null | (Element | null)[], + container: Element | null, onOutside: (e: MouseEvent) => void, enabled?: boolean, - // Can be used e.g. to prevent unexpected closing-reopening when clicking on a - // popover's trigger. ) { useEffect(() => { if (!container || enabled === false) return - const containers = Array.isArray(container) - ? (container.filter((container) => container) as Element[]) - : [container] - const onMouseDown = (e: MouseEvent) => { - if ( - containers.every((container) => !e.composedPath().includes(container)) - ) { - console.log('outside') + if (!e.composedPath().includes(container)) { onOutside(e) } }