From 9d9fc1680e5bd4f0b3ead5536759e7c0fd6f58a7 Mon Sep 17 00:00:00 2001 From: Cole Lawrence Date: Wed, 27 Apr 2022 15:41:25 -0400 Subject: [PATCH] refactor: add pointer types for prop editors --- theatre/core/src/sheetObjects/SheetObject.ts | 6 ++++-- .../propEditors/BooleanPropEditor.tsx | 12 ++++++------ .../propEditors/CompoundPropEditor.tsx | 11 ++++------- .../propEditors/DeterminePropEditor.tsx | 17 +++++++++++++---- .../propEditors/NumberPropEditor.tsx | 12 ++++++------ .../DetailPanel/propEditors/RgbaPropEditor.tsx | 18 +++++++----------- .../propEditors/StringLiteralPropEditor.tsx | 10 ++++------ .../propEditors/StringPropEditor.tsx | 14 +++++++------- .../propEditors/utils/IPropEditorFC.ts | 12 ++++++++++++ .../propEditors/utils/SingleRowPropEditor.tsx | 18 ++++++++++++++---- .../utils/useEditingToolsForPrimitiveProp.tsx | 3 ++- 11 files changed, 79 insertions(+), 54 deletions(-) create mode 100644 theatre/studio/src/panels/DetailPanel/propEditors/utils/IPropEditorFC.ts diff --git a/theatre/core/src/sheetObjects/SheetObject.ts b/theatre/core/src/sheetObjects/SheetObject.ts index fafa7ff..22b37ef 100644 --- a/theatre/core/src/sheetObjects/SheetObject.ts +++ b/theatre/core/src/sheetObjects/SheetObject.ts @@ -108,11 +108,13 @@ export default class SheetObject implements IdentityDerivationProvider { ) } - getValueByPointer(pointer: SheetObject['propsP']): SerializableValue { + getValueByPointer(pointer: Pointer): T { const allValuesP = val(this.getValues()) const {path} = getPointerParts(pointer) - return val(pointerDeep(allValuesP as $FixMe, path)) as SerializableMap + return val( + pointerDeep(allValuesP as $FixMe, path), + ) as SerializableValue as T } getIdentityDerivation(path: Array): IDerivation { diff --git a/theatre/studio/src/panels/DetailPanel/propEditors/BooleanPropEditor.tsx b/theatre/studio/src/panels/DetailPanel/propEditors/BooleanPropEditor.tsx index cc109d3..9174111 100644 --- a/theatre/studio/src/panels/DetailPanel/propEditors/BooleanPropEditor.tsx +++ b/theatre/studio/src/panels/DetailPanel/propEditors/BooleanPropEditor.tsx @@ -1,20 +1,20 @@ import type {PropTypeConfig_Boolean} from '@theatre/core/propTypes' -import type SheetObject from '@theatre/core/sheetObjects/SheetObject' import React, {useCallback} from 'react' import {useEditingToolsForPrimitiveProp} from './utils/useEditingToolsForPrimitiveProp' import {SingleRowPropEditor} from './utils/SingleRowPropEditor' import styled from 'styled-components' import BasicCheckbox from '@theatre/studio/uiComponents/form/BasicCheckbox' +import type {IPropEditorFC} from './utils/IPropEditorFC' const Input = styled(BasicCheckbox)` margin-left: 6px; ` -const BooleanPropEditor: React.FC<{ - propConfig: PropTypeConfig_Boolean - pointerToProp: SheetObject['propsP'] - obj: SheetObject -}> = ({propConfig, pointerToProp, obj}) => { +const BooleanPropEditor: IPropEditorFC = ({ + propConfig, + pointerToProp, + obj, +}) => { const stuff = useEditingToolsForPrimitiveProp( pointerToProp, obj, diff --git a/theatre/studio/src/panels/DetailPanel/propEditors/CompoundPropEditor.tsx b/theatre/studio/src/panels/DetailPanel/propEditors/CompoundPropEditor.tsx index 60f6520..6513f9b 100644 --- a/theatre/studio/src/panels/DetailPanel/propEditors/CompoundPropEditor.tsx +++ b/theatre/studio/src/panels/DetailPanel/propEditors/CompoundPropEditor.tsx @@ -1,6 +1,5 @@ import type {PropTypeConfig_Compound} from '@theatre/core/propTypes' import {isPropConfigComposite} from '@theatre/shared/propTypes/utils' -import type SheetObject from '@theatre/core/sheetObjects/SheetObject' import type {$IntentionalAny} from '@theatre/shared/utils/types' import {getPointerParts} from '@theatre/dataverse' import last from 'lodash-es/last' @@ -16,6 +15,7 @@ import { import DefaultOrStaticValueIndicator from './utils/DefaultValueIndicator' import {pointerEventsAutoInNormalMode} from '@theatre/studio/css' import useRefAndState from '@theatre/studio/utils/useRefAndState' +import type {IPropEditorFC} from './utils/IPropEditorFC' const Container = styled.div` --step: 8px; @@ -59,12 +59,9 @@ const SubProps = styled.div<{depth: number; lastSubIsComposite: boolean}>` /* padding: ${(props) => (props.lastSubIsComposite ? 0 : '4px')} 0; */ ` -const CompoundPropEditor: React.FC<{ - pointerToProp: SheetObject['propsP'] - obj: SheetObject - propConfig: PropTypeConfig_Compound<$IntentionalAny> - depth: number -}> = ({pointerToProp, obj, propConfig, depth}) => { +const CompoundPropEditor: IPropEditorFC< + PropTypeConfig_Compound<$IntentionalAny> +> = ({pointerToProp, obj, propConfig, depth}) => { const propName = propConfig.label ?? last(getPointerParts(pointerToProp).path) const allSubs = Object.entries(propConfig.props) diff --git a/theatre/studio/src/panels/DetailPanel/propEditors/DeterminePropEditor.tsx b/theatre/studio/src/panels/DetailPanel/propEditors/DeterminePropEditor.tsx index c049a8b..30e9fa7 100644 --- a/theatre/studio/src/panels/DetailPanel/propEditors/DeterminePropEditor.tsx +++ b/theatre/studio/src/panels/DetailPanel/propEditors/DeterminePropEditor.tsx @@ -1,6 +1,7 @@ import type {PropTypeConfig} from '@theatre/core/propTypes' import type SheetObject from '@theatre/core/sheetObjects/SheetObject' import {getPointerParts} from '@theatre/dataverse' +import type {Pointer} from '@theatre/dataverse' import React from 'react' import BooleanPropEditor from './BooleanPropEditor' import CompoundPropEditor from './CompoundPropEditor' @@ -56,14 +57,21 @@ export const getPropTypeByPointer = ( return conf } -const propEditorByPropType: { +type PropConfigByType = Extract< + PropTypeConfig, + {type: K} +> + +type IPropEditorByPropType = { [K in PropTypeConfig['type']]: React.FC<{ obj: SheetObject - pointerToProp: SheetObject['propsP'] - propConfig: Extract + pointerToProp: Pointer['valueType']> + propConfig: PropConfigByType depth: number }> -} = { +} + +const propEditorByPropType: IPropEditorByPropType = { compound: CompoundPropEditor, number: NumberPropEditor, string: StringPropEditor, @@ -88,6 +96,7 @@ const DeterminePropEditor: React.FC<{ = ({propConfig, pointerToProp, obj}) => { +const NumberPropEditor: IPropEditorFC = ({ + propConfig, + pointerToProp, + obj, +}) => { const stuff = useEditingToolsForPrimitiveProp( pointerToProp, obj, diff --git a/theatre/studio/src/panels/DetailPanel/propEditors/RgbaPropEditor.tsx b/theatre/studio/src/panels/DetailPanel/propEditors/RgbaPropEditor.tsx index 3c7e00b..4a5f5cb 100644 --- a/theatre/studio/src/panels/DetailPanel/propEditors/RgbaPropEditor.tsx +++ b/theatre/studio/src/panels/DetailPanel/propEditors/RgbaPropEditor.tsx @@ -5,7 +5,6 @@ import { rgba2hex, parseRgbaFromHex, } from '@theatre/shared/utils/color' -import type SheetObject from '@theatre/core/sheetObjects/SheetObject' import React, {useCallback, useRef} from 'react' import {useEditingToolsForPrimitiveProp} from './utils/useEditingToolsForPrimitiveProp' import {SingleRowPropEditor} from './utils/SingleRowPropEditor' @@ -14,6 +13,7 @@ import styled from 'styled-components' import usePopover from '@theatre/studio/uiComponents/Popover/usePopover' import BasicStringInput from '@theatre/studio/uiComponents/form/BasicStringInput' import {popoverBackgroundColor} from '@theatre/studio/uiComponents/Popover/BasicPopover' +import type {IPropEditorFC} from './utils/IPropEditorFC' const RowContainer = styled.div` display: flex; @@ -60,18 +60,14 @@ const Popover = styled.div` box-shadow: none; ` -const RgbaPropEditor: React.FC<{ - propConfig: PropTypeConfig_Rgba - pointerToProp: SheetObject['propsP'] - obj: SheetObject -}> = ({propConfig, pointerToProp, obj}) => { +const RgbaPropEditor: IPropEditorFC = ({ + propConfig, + pointerToProp, + obj, +}) => { const containerRef = useRef(null!) - const stuff = useEditingToolsForPrimitiveProp( - pointerToProp, - obj, - propConfig, - ) + const stuff = useEditingToolsForPrimitiveProp(pointerToProp, obj, propConfig) const onChange = useCallback( (color: string) => { diff --git a/theatre/studio/src/panels/DetailPanel/propEditors/StringLiteralPropEditor.tsx b/theatre/studio/src/panels/DetailPanel/propEditors/StringLiteralPropEditor.tsx index d9c50a2..ed70a2f 100644 --- a/theatre/studio/src/panels/DetailPanel/propEditors/StringLiteralPropEditor.tsx +++ b/theatre/studio/src/panels/DetailPanel/propEditors/StringLiteralPropEditor.tsx @@ -1,17 +1,15 @@ import type {PropTypeConfig_StringLiteral} from '@theatre/core/propTypes' -import type SheetObject from '@theatre/core/sheetObjects/SheetObject' import React, {useCallback} from 'react' import {useEditingToolsForPrimitiveProp} from './utils/useEditingToolsForPrimitiveProp' import type {$IntentionalAny} from '@theatre/shared/utils/types' import BasicSwitch from '@theatre/studio/uiComponents/form/BasicSwitch' import BasicSelect from '@theatre/studio/uiComponents/form/BasicSelect' import {SingleRowPropEditor} from './utils/SingleRowPropEditor' +import type {IPropEditorFC} from './utils/IPropEditorFC' -const StringLiteralPropEditor: React.FC<{ - propConfig: PropTypeConfig_StringLiteral<$IntentionalAny> - pointerToProp: SheetObject['propsP'] - obj: SheetObject -}> = ({propConfig, pointerToProp, obj}) => { +const StringLiteralPropEditor: IPropEditorFC< + PropTypeConfig_StringLiteral<$IntentionalAny> +> = ({propConfig, pointerToProp, obj}) => { const stuff = useEditingToolsForPrimitiveProp( pointerToProp, obj, diff --git a/theatre/studio/src/panels/DetailPanel/propEditors/StringPropEditor.tsx b/theatre/studio/src/panels/DetailPanel/propEditors/StringPropEditor.tsx index a406dd2..0f6fed3 100644 --- a/theatre/studio/src/panels/DetailPanel/propEditors/StringPropEditor.tsx +++ b/theatre/studio/src/panels/DetailPanel/propEditors/StringPropEditor.tsx @@ -1,15 +1,15 @@ -import type {PropTypeConfig_String} from '@theatre/core/propTypes' -import type SheetObject from '@theatre/core/sheetObjects/SheetObject' import React from 'react' +import type {PropTypeConfig_String} from '@theatre/core/propTypes' import {useEditingToolsForPrimitiveProp} from './utils/useEditingToolsForPrimitiveProp' import {SingleRowPropEditor} from './utils/SingleRowPropEditor' import BasicStringInput from '@theatre/studio/uiComponents/form/BasicStringInput' +import type {IPropEditorFC} from './utils/IPropEditorFC' -const StringPropEditor: React.FC<{ - propConfig: PropTypeConfig_String - pointerToProp: SheetObject['propsP'] - obj: SheetObject -}> = ({propConfig, pointerToProp, obj}) => { +const StringPropEditor: IPropEditorFC = ({ + propConfig, + pointerToProp, + obj, +}) => { const stuff = useEditingToolsForPrimitiveProp( pointerToProp, obj, diff --git a/theatre/studio/src/panels/DetailPanel/propEditors/utils/IPropEditorFC.ts b/theatre/studio/src/panels/DetailPanel/propEditors/utils/IPropEditorFC.ts new file mode 100644 index 0000000..4671f99 --- /dev/null +++ b/theatre/studio/src/panels/DetailPanel/propEditors/utils/IPropEditorFC.ts @@ -0,0 +1,12 @@ +import type {IBasePropType} from '@theatre/core/propTypes' +import type SheetObject from '@theatre/core/sheetObjects/SheetObject' +import type {Pointer} from '@theatre/dataverse' + +/** Helper for defining consistent prop editor components */ +export type IPropEditorFC> = + React.FC<{ + propConfig: TPropTypeConfig + pointerToProp: Pointer + obj: SheetObject + depth: number + }> diff --git a/theatre/studio/src/panels/DetailPanel/propEditors/utils/SingleRowPropEditor.tsx b/theatre/studio/src/panels/DetailPanel/propEditors/utils/SingleRowPropEditor.tsx index bb31e1a..18ae40a 100644 --- a/theatre/studio/src/panels/DetailPanel/propEditors/utils/SingleRowPropEditor.tsx +++ b/theatre/studio/src/panels/DetailPanel/propEditors/utils/SingleRowPropEditor.tsx @@ -1,6 +1,6 @@ import type * as propTypes from '@theatre/core/propTypes' -import type SheetObject from '@theatre/core/sheetObjects/SheetObject' import {getPointerParts} from '@theatre/dataverse' +import type {Pointer} from '@theatre/dataverse' import useContextMenu from '@theatre/studio/uiComponents/simpleContextMenu/useContextMenu' import useRefAndState from '@theatre/studio/utils/useRefAndState' import {last} from 'lodash-es' @@ -108,11 +108,21 @@ const InputContainer = styled.div` flex-grow: 0; ` -export const SingleRowPropEditor: React.FC<{ +type ISingleRowPropEditorProps = { propConfig: propTypes.PropTypeConfig - pointerToProp: SheetObject['propsP'] + pointerToProp: Pointer stuff: ReturnType -}> = ({propConfig, pointerToProp, stuff, children}) => { +} + +export function SingleRowPropEditor({ + propConfig, + pointerToProp, + stuff, + children, +}: React.PropsWithChildren>): React.ReactElement< + any, + any +> | null { const label = propConfig.label ?? last(getPointerParts(pointerToProp).path) const [propNameContainerRef, propNameContainer] = diff --git a/theatre/studio/src/panels/DetailPanel/propEditors/utils/useEditingToolsForPrimitiveProp.tsx b/theatre/studio/src/panels/DetailPanel/propEditors/utils/useEditingToolsForPrimitiveProp.tsx index 38c04ef..3fc6861 100644 --- a/theatre/studio/src/panels/DetailPanel/propEditors/utils/useEditingToolsForPrimitiveProp.tsx +++ b/theatre/studio/src/panels/DetailPanel/propEditors/utils/useEditingToolsForPrimitiveProp.tsx @@ -7,6 +7,7 @@ import getDeep from '@theatre/shared/utils/getDeep' import {usePrism} from '@theatre/react' import type {$FixMe, SerializablePrimitive} from '@theatre/shared/utils/types' import {getPointerParts, prism, val} from '@theatre/dataverse' +import type {Pointer} from '@theatre/dataverse' import get from 'lodash-es/get' import last from 'lodash-es/last' import React from 'react' @@ -47,7 +48,7 @@ type Stuff = Default | Static | Sequenced export function useEditingToolsForPrimitiveProp< T extends SerializablePrimitive, >( - pointerToProp: SheetObject['propsP'], + pointerToProp: Pointer, obj: SheetObject, propConfig: PropTypeConfig, ): Stuff {