diff --git a/theatre/studio/src/panels/DetailPanel/DeterminePropEditorForDetail/DetailCompoundPropEditor.tsx b/theatre/studio/src/panels/DetailPanel/DeterminePropEditorForDetail/DetailCompoundPropEditor.tsx
index 4136bef2e..22a9558b0 100644
--- a/theatre/studio/src/panels/DetailPanel/DeterminePropEditorForDetail/DetailCompoundPropEditor.tsx
+++ b/theatre/studio/src/panels/DetailPanel/DeterminePropEditorForDetail/DetailCompoundPropEditor.tsx
@@ -29,10 +29,11 @@ import {usePrism} from '@theatre/react'
import {val} from '@theatre/dataverse'
import {HiOutlineChevronRight} from 'react-icons/all'
import memoizeFn from '@theatre/utils/memoizeFn'
+import {collapsedMap} from './collapsedMap'
const Container = styled.div`
--step: 15px;
- --left-pad: 15px;
+ --left-pad: 10px;
${pointerEventsAutoInNormalMode};
--right-width: 60%;
`
@@ -193,8 +194,11 @@ function DetailCompoundPropEditor<
propConfig,
)
+ const label = propName || 'Props'
+
const [contextMenu] = useContextMenu(propNameContainer, {
menuItems: tools.contextMenuItems,
+ displayName: `${label}`,
})
const lastSubPropIsComposite = compositeSubs.length > 0
@@ -241,7 +245,7 @@ function DetailCompoundPropEditor<
isHighlighted={isPropHighlightedD}
ref={propNameContainerRef}
>
- {propName || 'Props'}
+ {label}
>()
diff --git a/theatre/studio/src/panels/DetailPanel/DeterminePropEditorForDetail/SingleRowPropEditor.tsx b/theatre/studio/src/panels/DetailPanel/DeterminePropEditorForDetail/SingleRowPropEditor.tsx
index e79e3d66a..7abaa1b98 100644
--- a/theatre/studio/src/panels/DetailPanel/DeterminePropEditorForDetail/SingleRowPropEditor.tsx
+++ b/theatre/studio/src/panels/DetailPanel/DeterminePropEditorForDetail/SingleRowPropEditor.tsx
@@ -111,6 +111,7 @@ export function SingleRowPropEditor({
useRefAndState(null)
const [contextMenu] = useContextMenu(propNameContainer, {
+ displayName: `${label}`,
menuItems: editingTools.contextMenuItems,
})
diff --git a/theatre/studio/src/panels/DetailPanel/DeterminePropEditorForDetail/collapsedMap.tsx b/theatre/studio/src/panels/DetailPanel/DeterminePropEditorForDetail/collapsedMap.tsx
new file mode 100644
index 000000000..bca84901f
--- /dev/null
+++ b/theatre/studio/src/panels/DetailPanel/DeterminePropEditorForDetail/collapsedMap.tsx
@@ -0,0 +1,3 @@
+import type {Atom} from '@theatre/dataverse'
+
+export const collapsedMap = new Map>()
diff --git a/theatre/studio/src/panels/SequenceEditorPanel/GraphEditor/BasicKeyframedTrack/BasicKeyframedTrack.tsx b/theatre/studio/src/panels/SequenceEditorPanel/GraphEditor/BasicKeyframedTrack/BasicKeyframedTrack.tsx
index 536ae6145..cbda75796 100644
--- a/theatre/studio/src/panels/SequenceEditorPanel/GraphEditor/BasicKeyframedTrack/BasicKeyframedTrack.tsx
+++ b/theatre/studio/src/panels/SequenceEditorPanel/GraphEditor/BasicKeyframedTrack/BasicKeyframedTrack.tsx
@@ -16,7 +16,10 @@ import {
import type {PropTypeConfig_AllSimples} from '@theatre/core/propTypes'
import {useVal} from '@theatre/react'
import type {GraphEditorColors} from '@theatre/sync-server/state/types'
-import {keyframeUtils} from '@theatre/sync-server/state/schema'
+import {
+ graphEditorColors,
+ keyframeUtils,
+} from '@theatre/sync-server/state/schema'
export type ExtremumSpace = {
fromValueSpace: (v: number) => number
@@ -121,11 +124,13 @@ const BasicKeyframedTrack: React.VFC<{
/>
))
+ const iconColor = graphEditorColors[color].iconColor
+
return (
{keyframeEditors}
diff --git a/theatre/studio/src/uiComponents/simpleContextMenu/ContextMenu/BaseMenu.tsx b/theatre/studio/src/uiComponents/simpleContextMenu/ContextMenu/BaseMenu.tsx
index c393db0bd..f0eb9bf25 100644
--- a/theatre/studio/src/uiComponents/simpleContextMenu/ContextMenu/BaseMenu.tsx
+++ b/theatre/studio/src/uiComponents/simpleContextMenu/ContextMenu/BaseMenu.tsx
@@ -14,23 +14,26 @@ const MenuContainer = styled.ul`
position: absolute;
min-width: ${minWidth}px;
z-index: 10000;
- background: ${transparentize(0.2, '#111')};
- backdrop-filter: blur(2px);
+ background: ${transparentize(0.8, '#000000')};
+ backdrop-filter: blur(8px) saturate(300%) contrast(65%) brightness(70%);
color: white;
+ border: 0.5px solid #6262622c;
+ box-sizing: border-box;
+ box-shadow: ${transparentize(0.75, '#000000')} 0px 4px 20px;
list-style-type: none;
- padding: 2px 0;
+ padding: 0;
margin: 0;
- border-radius: 1px;
+ border-radius: 3px;
cursor: default;
${pointerEventsAutoInNormalMode};
- border-radius: 3px;
+ border-radius: 4px;
`
const MenuTitle = styled.div`
- padding: 4px 10px;
- border-bottom: 1px solid #6262626d;
- color: #adadadb3;
- font-size: 11px;
+ padding: 8px 10px;
+ border-bottom: 1px solid #6262621b;
+ color: #d1d1d1;
+ font-size: 10px;
font-weight: 500;
`
diff --git a/theatre/studio/src/uiComponents/simpleContextMenu/ContextMenu/ContextMenu.tsx b/theatre/studio/src/uiComponents/simpleContextMenu/ContextMenu/ContextMenu.tsx
index 7c5b960a8..6c0bc33f1 100644
--- a/theatre/studio/src/uiComponents/simpleContextMenu/ContextMenu/ContextMenu.tsx
+++ b/theatre/studio/src/uiComponents/simpleContextMenu/ContextMenu/ContextMenu.tsx
@@ -9,6 +9,7 @@ import {height as itemHeight} from './Item'
import {PortalContext} from 'reakit'
import useOnKeyDown from '@theatre/studio/uiComponents/useOnKeyDown'
import BaseMenu from './BaseMenu'
+import type {$IntentionalAny} from '@theatre/utils/types'
/**
* How far from the menu should the pointer travel to auto close the menu
@@ -17,7 +18,7 @@ const pointerDistanceThreshold = 20
export type IContextMenuItemCustomNodeRenderFn = (controls: {
closeMenu(): void
-}) => React.ReactChild
+}) => React.ReactElement
export type IContextMenuItem = {
label: string | ElementType
@@ -38,6 +39,26 @@ export type ContextMenuProps = {
clientY: number
}
onRequestClose: () => void
+ // default: true
+ closeOnPointerLeave?: boolean
+}
+
+/**
+ * Useful helper in development to prevent the context menu from auto-closing,
+ * so its easier to inspect the DOM / change the styles, etc.
+ *
+ * Call window.$disableAutoCloseContextMenu() in the console to disable auto-close
+ */
+const shouldAutoCloseByDefault =
+ process.env.NODE_ENV === 'development'
+ ? (): boolean =>
+ (window as $IntentionalAny).__autoCloseContextMenuByDefault ?? true
+ : (): boolean => true
+
+if (process.env.NODE_ENV === 'development') {
+ ;(window as $IntentionalAny).$disableAutoCloseContextMenu = () => {
+ ;(window as $IntentionalAny).__autoCloseContextMenuByDefault = false
+ }
}
/**
@@ -86,7 +107,8 @@ const ContextMenu: React.FC = (props) => {
e.clientY < pos.top - pointerDistanceThreshold ||
e.clientY > pos.top + rect.height + pointerDistanceThreshold
) {
- props.onRequestClose()
+ if (props.closeOnPointerLeave !== false && shouldAutoCloseByDefault())
+ props.onRequestClose()
}
}
@@ -95,7 +117,14 @@ const ContextMenu: React.FC = (props) => {
return () => {
window.removeEventListener('mousemove', onMouseMove)
}
- }, [rect, container, props.clickPoint, windowSize, props.onRequestClose])
+ }, [
+ rect,
+ container,
+ props.clickPoint,
+ windowSize,
+ props.onRequestClose,
+ props.closeOnPointerLeave,
+ ])
const portalLayer = useContext(PortalContext)
useOnKeyDown((ev) => {
diff --git a/theatre/studio/src/uiComponents/simpleContextMenu/ContextMenu/Item.tsx b/theatre/studio/src/uiComponents/simpleContextMenu/ContextMenu/Item.tsx
index b2cb0d5ea..de66fa953 100644
--- a/theatre/studio/src/uiComponents/simpleContextMenu/ContextMenu/Item.tsx
+++ b/theatre/studio/src/uiComponents/simpleContextMenu/ContextMenu/Item.tsx
@@ -3,7 +3,7 @@ import type {ElementType} from 'react'
import React from 'react'
import styled from 'styled-components'
-export const height = 26
+export const height = 30
const ItemContainer = styled.li<{enabled: boolean}>`
height: ${height}px;
@@ -11,25 +11,24 @@ const ItemContainer = styled.li<{enabled: boolean}>`
margin: 0;
display: flex;
align-items: center;
- font-size: 11px;
font-weight: 400;
position: relative;
color: ${(props) => (props.enabled ? 'white' : '#8f8f8f')};
- cursor: ${(props) => (props.enabled ? 'normal' : 'not-allowed')};
+ cursor: ${(props) => (props.enabled ? 'default' : 'not-allowed')};
&:after {
position: absolute;
- inset: 2px 1px;
+ inset: 2px;
display: block;
content: ' ';
pointer-events: none;
z-index: -1;
- border-radius: 3px;
+ border-radius: 4px;
}
&:hover:after {
background-color: ${(props) =>
- props.enabled ? 'rgba(63, 174, 191, 0.75)' : 'initial'};
+ props.enabled ? 'rgba(255, 255, 255, 0.075)' : 'initial'};
}
`