diff --git a/editor/src/components/inspector/flex-section.tsx b/editor/src/components/inspector/flex-section.tsx index 5114495c30a3..ea9ef2d445ad 100644 --- a/editor/src/components/inspector/flex-section.tsx +++ b/editor/src/components/inspector/flex-section.tsx @@ -4,7 +4,7 @@ import { jsx } from '@emotion/react' import React from 'react' import { createSelector } from 'reselect' -import { unless, when } from '../../utils/react-conditionals' +import { when } from '../../utils/react-conditionals' import { Substores, useEditorState, useRefEditorState } from '../editor/store/store-hook' import { AddRemoveLayoutSystemControl } from './add-remove-layout-system-control' import { FlexDirectionToggle } from './flex-direction-control' @@ -554,9 +554,15 @@ function AxisDimensionControl({ opener: (isOpen: boolean) => React.ReactElement }) { const testId = `grid-dimension-${axis}-${index}` - const [isOpen, setIsOpen] = React.useState(false) - const onOpenChange = React.useCallback((isDropdownOpen: boolean) => { - setIsOpen(isDropdownOpen) + const [isDotsMenuOpen, setDotsMenuOpen] = React.useState(false) + const [isTitleMenuOpen, setTitleMenuOpen] = React.useState(false) + + const onOpenChangeDotsMenu = React.useCallback((isDropdownOpen: boolean) => { + setDotsMenuOpen(isDropdownOpen) + }, []) + + const onOpenChangeTitleMenu = React.useCallback(() => { + setTitleMenuOpen(false) }, []) const isDynamic = React.useMemo(() => { @@ -584,6 +590,14 @@ function AxisDimensionControl({ setIsHovered(false) }, []) + const onContextMenuTitle = React.useCallback((e: React.MouseEvent) => { + e.preventDefault() + e.stopPropagation() + setTitleMenuOpen(true) + }, []) + + const invisibleOpener = React.useCallback(() => null, []) + return (
{title} + {when( - (isHovered && !gridExpressionInputFocused.focused) || isOpen, + (isHovered && !gridExpressionInputFocused.focused) || isDotsMenuOpen, - + , )}
diff --git a/editor/src/uuiui/radix-components.tsx b/editor/src/uuiui/radix-components.tsx index 86ed787124af..00568db5e82f 100644 --- a/editor/src/uuiui/radix-components.tsx +++ b/editor/src/uuiui/radix-components.tsx @@ -90,6 +90,7 @@ export interface DropdownMenuProps { alignOffset?: number onOpenChange?: (open: boolean) => void style?: CSSProperties + isOpen?: boolean } export const ItemContainerTestId = (id: string) => `item-container-${id}` @@ -103,7 +104,7 @@ export const DropdownMenu = React.memo((props) => { }, []) const onEscapeKeyDown = React.useCallback((e: KeyboardEvent) => e.stopPropagation(), []) - const [open, setOpen] = React.useState(false) + const [open, setOpen] = useIsDropdownMenuOpen(props.isOpen ?? null) const shouldShowCheckboxes = props.items.some( (i) => !isSeparatorDropdownMenuItem(i) && i.checked != null, @@ -408,3 +409,15 @@ export const RadixSelect = React.memo( }, ) RadixSelect.displayName = 'RadixSelect' + +function useIsDropdownMenuOpen(isOpenFromProps: boolean | null) { + const state = React.useState(isOpenFromProps || false) + const [, setOpen] = state + + // If the `isOpen` value coming from props changes, update the state. + React.useEffect(() => { + setOpen(isOpenFromProps || false) + }, [setOpen, isOpenFromProps]) + + return state +}