refactor: add pointer types for prop editors

This commit is contained in:
Cole Lawrence 2022-04-27 15:41:25 -04:00
parent 91794f550d
commit 9d9fc1680e
11 changed files with 79 additions and 54 deletions

View file

@ -108,11 +108,13 @@ export default class SheetObject implements IdentityDerivationProvider {
) )
} }
getValueByPointer(pointer: SheetObject['propsP']): SerializableValue { getValueByPointer<T extends SerializableValue>(pointer: Pointer<T>): T {
const allValuesP = val(this.getValues()) const allValuesP = val(this.getValues())
const {path} = getPointerParts(pointer) 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<string | number>): IDerivation<unknown> { getIdentityDerivation(path: Array<string | number>): IDerivation<unknown> {

View file

@ -1,20 +1,20 @@
import type {PropTypeConfig_Boolean} from '@theatre/core/propTypes' import type {PropTypeConfig_Boolean} from '@theatre/core/propTypes'
import type SheetObject from '@theatre/core/sheetObjects/SheetObject'
import React, {useCallback} from 'react' import React, {useCallback} from 'react'
import {useEditingToolsForPrimitiveProp} from './utils/useEditingToolsForPrimitiveProp' import {useEditingToolsForPrimitiveProp} from './utils/useEditingToolsForPrimitiveProp'
import {SingleRowPropEditor} from './utils/SingleRowPropEditor' import {SingleRowPropEditor} from './utils/SingleRowPropEditor'
import styled from 'styled-components' import styled from 'styled-components'
import BasicCheckbox from '@theatre/studio/uiComponents/form/BasicCheckbox' import BasicCheckbox from '@theatre/studio/uiComponents/form/BasicCheckbox'
import type {IPropEditorFC} from './utils/IPropEditorFC'
const Input = styled(BasicCheckbox)` const Input = styled(BasicCheckbox)`
margin-left: 6px; margin-left: 6px;
` `
const BooleanPropEditor: React.FC<{ const BooleanPropEditor: IPropEditorFC<PropTypeConfig_Boolean> = ({
propConfig: PropTypeConfig_Boolean propConfig,
pointerToProp: SheetObject['propsP'] pointerToProp,
obj: SheetObject obj,
}> = ({propConfig, pointerToProp, obj}) => { }) => {
const stuff = useEditingToolsForPrimitiveProp<boolean>( const stuff = useEditingToolsForPrimitiveProp<boolean>(
pointerToProp, pointerToProp,
obj, obj,

View file

@ -1,6 +1,5 @@
import type {PropTypeConfig_Compound} from '@theatre/core/propTypes' import type {PropTypeConfig_Compound} from '@theatre/core/propTypes'
import {isPropConfigComposite} from '@theatre/shared/propTypes/utils' import {isPropConfigComposite} from '@theatre/shared/propTypes/utils'
import type SheetObject from '@theatre/core/sheetObjects/SheetObject'
import type {$IntentionalAny} from '@theatre/shared/utils/types' import type {$IntentionalAny} from '@theatre/shared/utils/types'
import {getPointerParts} from '@theatre/dataverse' import {getPointerParts} from '@theatre/dataverse'
import last from 'lodash-es/last' import last from 'lodash-es/last'
@ -16,6 +15,7 @@ import {
import DefaultOrStaticValueIndicator from './utils/DefaultValueIndicator' import DefaultOrStaticValueIndicator from './utils/DefaultValueIndicator'
import {pointerEventsAutoInNormalMode} from '@theatre/studio/css' import {pointerEventsAutoInNormalMode} from '@theatre/studio/css'
import useRefAndState from '@theatre/studio/utils/useRefAndState' import useRefAndState from '@theatre/studio/utils/useRefAndState'
import type {IPropEditorFC} from './utils/IPropEditorFC'
const Container = styled.div` const Container = styled.div`
--step: 8px; --step: 8px;
@ -59,12 +59,9 @@ const SubProps = styled.div<{depth: number; lastSubIsComposite: boolean}>`
/* padding: ${(props) => (props.lastSubIsComposite ? 0 : '4px')} 0; */ /* padding: ${(props) => (props.lastSubIsComposite ? 0 : '4px')} 0; */
` `
const CompoundPropEditor: React.FC<{ const CompoundPropEditor: IPropEditorFC<
pointerToProp: SheetObject['propsP'] PropTypeConfig_Compound<$IntentionalAny>
obj: SheetObject > = ({pointerToProp, obj, propConfig, depth}) => {
propConfig: PropTypeConfig_Compound<$IntentionalAny>
depth: number
}> = ({pointerToProp, obj, propConfig, depth}) => {
const propName = propConfig.label ?? last(getPointerParts(pointerToProp).path) const propName = propConfig.label ?? last(getPointerParts(pointerToProp).path)
const allSubs = Object.entries(propConfig.props) const allSubs = Object.entries(propConfig.props)

View file

@ -1,6 +1,7 @@
import type {PropTypeConfig} from '@theatre/core/propTypes' import type {PropTypeConfig} from '@theatre/core/propTypes'
import type SheetObject from '@theatre/core/sheetObjects/SheetObject' import type SheetObject from '@theatre/core/sheetObjects/SheetObject'
import {getPointerParts} from '@theatre/dataverse' import {getPointerParts} from '@theatre/dataverse'
import type {Pointer} from '@theatre/dataverse'
import React from 'react' import React from 'react'
import BooleanPropEditor from './BooleanPropEditor' import BooleanPropEditor from './BooleanPropEditor'
import CompoundPropEditor from './CompoundPropEditor' import CompoundPropEditor from './CompoundPropEditor'
@ -56,14 +57,21 @@ export const getPropTypeByPointer = (
return conf return conf
} }
const propEditorByPropType: { type PropConfigByType<K extends PropTypeConfig['type']> = Extract<
PropTypeConfig,
{type: K}
>
type IPropEditorByPropType = {
[K in PropTypeConfig['type']]: React.FC<{ [K in PropTypeConfig['type']]: React.FC<{
obj: SheetObject obj: SheetObject
pointerToProp: SheetObject['propsP'] pointerToProp: Pointer<PropConfigByType<K>['valueType']>
propConfig: Extract<PropTypeConfig, {type: K}> propConfig: PropConfigByType<K>
depth: number depth: number
}> }>
} = { }
const propEditorByPropType: IPropEditorByPropType = {
compound: CompoundPropEditor, compound: CompoundPropEditor,
number: NumberPropEditor, number: NumberPropEditor,
string: StringPropEditor, string: StringPropEditor,
@ -88,6 +96,7 @@ const DeterminePropEditor: React.FC<{
<PropEditor <PropEditor
obj={p.obj} obj={p.obj}
depth={p.depth} depth={p.depth}
// @ts-expect-error This is fine
pointerToProp={p.pointerToProp} pointerToProp={p.pointerToProp}
// @ts-expect-error This is fine // @ts-expect-error This is fine
propConfig={propConfig} propConfig={propConfig}

View file

@ -1,15 +1,15 @@
import type {PropTypeConfig_Number} from '@theatre/core/propTypes' import type {PropTypeConfig_Number} from '@theatre/core/propTypes'
import type SheetObject from '@theatre/core/sheetObjects/SheetObject'
import BasicNumberInput from '@theatre/studio/uiComponents/form/BasicNumberInput' import BasicNumberInput from '@theatre/studio/uiComponents/form/BasicNumberInput'
import React, {useCallback} from 'react' import React, {useCallback} from 'react'
import {useEditingToolsForPrimitiveProp} from './utils/useEditingToolsForPrimitiveProp' import {useEditingToolsForPrimitiveProp} from './utils/useEditingToolsForPrimitiveProp'
import {SingleRowPropEditor} from './utils/SingleRowPropEditor' import {SingleRowPropEditor} from './utils/SingleRowPropEditor'
import type {IPropEditorFC} from './utils/IPropEditorFC'
const NumberPropEditor: React.FC<{ const NumberPropEditor: IPropEditorFC<PropTypeConfig_Number> = ({
propConfig: PropTypeConfig_Number propConfig,
pointerToProp: SheetObject['propsP'] pointerToProp,
obj: SheetObject obj,
}> = ({propConfig, pointerToProp, obj}) => { }) => {
const stuff = useEditingToolsForPrimitiveProp<number>( const stuff = useEditingToolsForPrimitiveProp<number>(
pointerToProp, pointerToProp,
obj, obj,

View file

@ -5,7 +5,6 @@ import {
rgba2hex, rgba2hex,
parseRgbaFromHex, parseRgbaFromHex,
} from '@theatre/shared/utils/color' } from '@theatre/shared/utils/color'
import type SheetObject from '@theatre/core/sheetObjects/SheetObject'
import React, {useCallback, useRef} from 'react' import React, {useCallback, useRef} from 'react'
import {useEditingToolsForPrimitiveProp} from './utils/useEditingToolsForPrimitiveProp' import {useEditingToolsForPrimitiveProp} from './utils/useEditingToolsForPrimitiveProp'
import {SingleRowPropEditor} from './utils/SingleRowPropEditor' import {SingleRowPropEditor} from './utils/SingleRowPropEditor'
@ -14,6 +13,7 @@ import styled from 'styled-components'
import usePopover from '@theatre/studio/uiComponents/Popover/usePopover' import usePopover from '@theatre/studio/uiComponents/Popover/usePopover'
import BasicStringInput from '@theatre/studio/uiComponents/form/BasicStringInput' import BasicStringInput from '@theatre/studio/uiComponents/form/BasicStringInput'
import {popoverBackgroundColor} from '@theatre/studio/uiComponents/Popover/BasicPopover' import {popoverBackgroundColor} from '@theatre/studio/uiComponents/Popover/BasicPopover'
import type {IPropEditorFC} from './utils/IPropEditorFC'
const RowContainer = styled.div` const RowContainer = styled.div`
display: flex; display: flex;
@ -60,18 +60,14 @@ const Popover = styled.div`
box-shadow: none; box-shadow: none;
` `
const RgbaPropEditor: React.FC<{ const RgbaPropEditor: IPropEditorFC<PropTypeConfig_Rgba> = ({
propConfig: PropTypeConfig_Rgba propConfig,
pointerToProp: SheetObject['propsP']
obj: SheetObject
}> = ({propConfig, pointerToProp, obj}) => {
const containerRef = useRef<HTMLDivElement>(null!)
const stuff = useEditingToolsForPrimitiveProp<Rgba>(
pointerToProp, pointerToProp,
obj, obj,
propConfig, }) => {
) const containerRef = useRef<HTMLDivElement>(null!)
const stuff = useEditingToolsForPrimitiveProp(pointerToProp, obj, propConfig)
const onChange = useCallback( const onChange = useCallback(
(color: string) => { (color: string) => {

View file

@ -1,17 +1,15 @@
import type {PropTypeConfig_StringLiteral} from '@theatre/core/propTypes' import type {PropTypeConfig_StringLiteral} from '@theatre/core/propTypes'
import type SheetObject from '@theatre/core/sheetObjects/SheetObject'
import React, {useCallback} from 'react' import React, {useCallback} from 'react'
import {useEditingToolsForPrimitiveProp} from './utils/useEditingToolsForPrimitiveProp' import {useEditingToolsForPrimitiveProp} from './utils/useEditingToolsForPrimitiveProp'
import type {$IntentionalAny} from '@theatre/shared/utils/types' import type {$IntentionalAny} from '@theatre/shared/utils/types'
import BasicSwitch from '@theatre/studio/uiComponents/form/BasicSwitch' import BasicSwitch from '@theatre/studio/uiComponents/form/BasicSwitch'
import BasicSelect from '@theatre/studio/uiComponents/form/BasicSelect' import BasicSelect from '@theatre/studio/uiComponents/form/BasicSelect'
import {SingleRowPropEditor} from './utils/SingleRowPropEditor' import {SingleRowPropEditor} from './utils/SingleRowPropEditor'
import type {IPropEditorFC} from './utils/IPropEditorFC'
const StringLiteralPropEditor: React.FC<{ const StringLiteralPropEditor: IPropEditorFC<
propConfig: PropTypeConfig_StringLiteral<$IntentionalAny> PropTypeConfig_StringLiteral<$IntentionalAny>
pointerToProp: SheetObject['propsP'] > = ({propConfig, pointerToProp, obj}) => {
obj: SheetObject
}> = ({propConfig, pointerToProp, obj}) => {
const stuff = useEditingToolsForPrimitiveProp<string>( const stuff = useEditingToolsForPrimitiveProp<string>(
pointerToProp, pointerToProp,
obj, obj,

View file

@ -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 React from 'react'
import type {PropTypeConfig_String} from '@theatre/core/propTypes'
import {useEditingToolsForPrimitiveProp} from './utils/useEditingToolsForPrimitiveProp' import {useEditingToolsForPrimitiveProp} from './utils/useEditingToolsForPrimitiveProp'
import {SingleRowPropEditor} from './utils/SingleRowPropEditor' import {SingleRowPropEditor} from './utils/SingleRowPropEditor'
import BasicStringInput from '@theatre/studio/uiComponents/form/BasicStringInput' import BasicStringInput from '@theatre/studio/uiComponents/form/BasicStringInput'
import type {IPropEditorFC} from './utils/IPropEditorFC'
const StringPropEditor: React.FC<{ const StringPropEditor: IPropEditorFC<PropTypeConfig_String> = ({
propConfig: PropTypeConfig_String propConfig,
pointerToProp: SheetObject['propsP'] pointerToProp,
obj: SheetObject obj,
}> = ({propConfig, pointerToProp, obj}) => { }) => {
const stuff = useEditingToolsForPrimitiveProp<string>( const stuff = useEditingToolsForPrimitiveProp<string>(
pointerToProp, pointerToProp,
obj, obj,

View file

@ -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<TPropTypeConfig extends IBasePropType<string, any>> =
React.FC<{
propConfig: TPropTypeConfig
pointerToProp: Pointer<TPropTypeConfig['valueType']>
obj: SheetObject
depth: number
}>

View file

@ -1,6 +1,6 @@
import type * as propTypes from '@theatre/core/propTypes' import type * as propTypes from '@theatre/core/propTypes'
import type SheetObject from '@theatre/core/sheetObjects/SheetObject'
import {getPointerParts} from '@theatre/dataverse' import {getPointerParts} from '@theatre/dataverse'
import type {Pointer} from '@theatre/dataverse'
import useContextMenu from '@theatre/studio/uiComponents/simpleContextMenu/useContextMenu' import useContextMenu from '@theatre/studio/uiComponents/simpleContextMenu/useContextMenu'
import useRefAndState from '@theatre/studio/utils/useRefAndState' import useRefAndState from '@theatre/studio/utils/useRefAndState'
import {last} from 'lodash-es' import {last} from 'lodash-es'
@ -108,11 +108,21 @@ const InputContainer = styled.div`
flex-grow: 0; flex-grow: 0;
` `
export const SingleRowPropEditor: React.FC<{ type ISingleRowPropEditorProps<T> = {
propConfig: propTypes.PropTypeConfig propConfig: propTypes.PropTypeConfig
pointerToProp: SheetObject['propsP'] pointerToProp: Pointer<T>
stuff: ReturnType<typeof useEditingToolsForPrimitiveProp> stuff: ReturnType<typeof useEditingToolsForPrimitiveProp>
}> = ({propConfig, pointerToProp, stuff, children}) => { }
export function SingleRowPropEditor<T>({
propConfig,
pointerToProp,
stuff,
children,
}: React.PropsWithChildren<ISingleRowPropEditorProps<T>>): React.ReactElement<
any,
any
> | null {
const label = propConfig.label ?? last(getPointerParts(pointerToProp).path) const label = propConfig.label ?? last(getPointerParts(pointerToProp).path)
const [propNameContainerRef, propNameContainer] = const [propNameContainerRef, propNameContainer] =

View file

@ -7,6 +7,7 @@ import getDeep from '@theatre/shared/utils/getDeep'
import {usePrism} from '@theatre/react' import {usePrism} from '@theatre/react'
import type {$FixMe, SerializablePrimitive} from '@theatre/shared/utils/types' import type {$FixMe, SerializablePrimitive} from '@theatre/shared/utils/types'
import {getPointerParts, prism, val} from '@theatre/dataverse' import {getPointerParts, prism, val} from '@theatre/dataverse'
import type {Pointer} from '@theatre/dataverse'
import get from 'lodash-es/get' import get from 'lodash-es/get'
import last from 'lodash-es/last' import last from 'lodash-es/last'
import React from 'react' import React from 'react'
@ -47,7 +48,7 @@ type Stuff<T> = Default<T> | Static<T> | Sequenced<T>
export function useEditingToolsForPrimitiveProp< export function useEditingToolsForPrimitiveProp<
T extends SerializablePrimitive, T extends SerializablePrimitive,
>( >(
pointerToProp: SheetObject['propsP'], pointerToProp: Pointer<T>,
obj: SheetObject, obj: SheetObject,
propConfig: PropTypeConfig, propConfig: PropTypeConfig,
): Stuff<T> { ): Stuff<T> {