Implemented types.stringLiteral(.., {as})

This commit is contained in:
Aria Minaei 2021-07-06 21:58:38 +02:00
parent 97ce94d52a
commit a4f83e0f84
8 changed files with 180 additions and 34 deletions

View file

@ -293,21 +293,33 @@ const editorSheetObjectConfig = types.compound({
showAxes: types.boolean(true), showAxes: types.boolean(true),
showGrid: types.boolean(true), showGrid: types.boolean(true),
showOverlayIcons: types.boolean(false), showOverlayIcons: types.boolean(false),
transformControlsMode: types.stringLiteral('translate', { transformControlsMode: types.stringLiteral(
'translate',
{
translate: 'Translate', translate: 'Translate',
rotate: 'Rotate', rotate: 'Rotate',
scale: 'Scale', scale: 'Scale',
}), },
transformControlsSpace: types.stringLiteral('world', { {as: 'switch'},
),
transformControlsSpace: types.stringLiteral(
'world',
{
local: 'Local', local: 'Local',
world: 'World', world: 'World',
}), },
viewportShading: types.stringLiteral('rendered', { {as: 'switch'},
),
viewportShading: types.stringLiteral(
'rendered',
{
flat: 'Flat', flat: 'Flat',
rendered: 'Rendered', rendered: 'Rendered',
solid: 'Solid', solid: 'Solid',
wireframe: 'Wireframe', wireframe: 'Wireframe',
}), },
{as: 'menu'},
),
}) })
export const bindToCanvas: BindFunction = ({ export const bindToCanvas: BindFunction = ({

View file

@ -62,11 +62,13 @@ export interface PropTypeConfig_StringLiteral<T extends string>
type: 'stringLiteral' type: 'stringLiteral'
default: T default: T
options: Record<T, string> options: Record<T, string>
as: 'menu' | 'switch'
} }
export function stringLiteral<Opts extends {[key in string]: string}>( export function stringLiteral<Opts extends {[key in string]: string}>(
defaultValue: Extract<keyof Opts, string>, defaultValue: Extract<keyof Opts, string>,
options: Opts, options: Opts,
extras?: {as?: 'menu' | 'switch'},
): PropTypeConfig_StringLiteral<Extract<keyof Opts, string>> { ): PropTypeConfig_StringLiteral<Extract<keyof Opts, string>> {
return { return {
type: 'stringLiteral', type: 'stringLiteral',
@ -74,6 +76,7 @@ export function stringLiteral<Opts extends {[key in string]: string}>(
options: {...options}, options: {...options},
[s]: 'TheatrePropType', [s]: 'TheatrePropType',
valueType: null as $IntentionalAny, valueType: null as $IntentionalAny,
as: extras?.as ?? 'menu',
} }
} }

View file

@ -36,9 +36,11 @@ const Label = styled.div`
color: white; color: white;
} }
` `
const Body = styled.div` const Body = styled.label`
cursor: ew-resize;
display: flex; display: flex;
align-items: center;
padding-left: 8px;
box-sizing: border-box;
width: 140px; width: 140px;
height: 100%; height: 100%;
margin-right: 16px; margin-right: 16px;
@ -76,12 +78,6 @@ const BooleanPropEditor: React.FC<{
{stuff.controlIndicators} {stuff.controlIndicators}
<Body> <Body>
<input type="checkbox" checked={stuff.value} onChange={onChange} /> <input type="checkbox" checked={stuff.value} onChange={onChange} />
{/* <BasicNumberEditor
value={stuff.value}
temporarilySetValue={stuff.temporarilySetValue}
discardTemporaryValue={stuff.discardTemporaryValue}
permenantlySetValue={stuff.permenantlySetValue}
/> */}
</Body> </Body>
</Container> </Container>
) )

View file

@ -1,6 +1,6 @@
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 type SheetObject from '@theatre/core/sheetObjects/SheetObject'
import BasicNumberEditor from '@theatre/studio/uiComponents/BasicNumberEditor' import BasicNumberEditor from '@theatre/studio/uiComponents/form/BasicNumberEditor'
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 {getPointerParts} from '@theatre/dataverse' import {getPointerParts} from '@theatre/dataverse'

View file

@ -11,6 +11,8 @@ import {
useEditingToolsForPrimitiveProp, useEditingToolsForPrimitiveProp,
} from './useEditingToolsForPrimitiveProp' } from './useEditingToolsForPrimitiveProp'
import type {$IntentionalAny} from '@theatre/shared/utils/types' import type {$IntentionalAny} from '@theatre/shared/utils/types'
import BasicSwitchEditor from '@theatre/studio/uiComponents/form/BasicSwitchEditor'
import BasicSelectEditor from '@theatre/studio/uiComponents/form/BasicSelectEditor'
const Container = styled.div` const Container = styled.div`
display: flex; display: flex;
@ -62,8 +64,8 @@ const StringLiteralPropEditor: React.FC<{
}) })
const onChange = useCallback( const onChange = useCallback(
(el: React.ChangeEvent<HTMLSelectElement>) => { (val: string) => {
stuff.permenantlySetValue(String(el.target.value)) stuff.permenantlySetValue(val)
}, },
[propConfig, pointerToProp, obj], [propConfig, pointerToProp, obj],
) )
@ -76,13 +78,19 @@ const StringLiteralPropEditor: React.FC<{
<Label ref={labelRef}>{label}</Label> <Label ref={labelRef}>{label}</Label>
{stuff.controlIndicators} {stuff.controlIndicators}
<Body> <Body>
<select value={stuff.value} onChange={onChange}> {propConfig.as === 'menu' ? (
{Object.keys(propConfig.options).map((key, i) => ( <BasicSelectEditor
<option key={'option-' + i} value={key}> value={stuff.value}
{propConfig.options[key]} onChange={onChange}
</option> options={propConfig.options}
))} />
</select> ) : (
<BasicSwitchEditor
value={stuff.value}
onChange={onChange}
options={propConfig.options}
/>
)}
</Body> </Body>
</Container> </Container>
) )

View file

@ -3,7 +3,7 @@ import {isInteger, round} from 'lodash-es'
import {darken, lighten} from 'polished' import {darken, lighten} from 'polished'
import React, {useMemo, useRef, useState} from 'react' import React, {useMemo, useRef, useState} from 'react'
import styled from 'styled-components' import styled from 'styled-components'
import DraggableArea from './DraggableArea' import DraggableArea from '@theatre/studio/uiComponents/DraggableArea'
type IMode = IState['mode'] type IMode = IState['mode']

View file

@ -0,0 +1,48 @@
import {theme} from '@theatre/studio/css'
import {darken, lighten} from 'polished'
import React, {useCallback} from 'react'
import styled from 'styled-components'
const Select = styled.select`
background: transparent;
box-sizing: border-box;
border: 1px solid transparent;
color: rgba(255, 255, 255, 0.9);
padding: 1px 6px;
font: inherit;
outline: none;
text-align: left;
width: 100%;
height: calc(100% - 4px);
border-radius: 2px;
&:hover,
&:focus {
background: ${darken(0.9, theme.panel.bg)};
border: 1px solid ${lighten(0.1, theme.panel.bg)};
}
`
const BasicSelectEditor: React.FC<{
value: string
onChange: (val: string) => void
options: Record<string, string>
}> = ({value, onChange, options}) => {
const _onChange = useCallback(
(el: React.ChangeEvent<HTMLSelectElement>) => {
onChange(String(el.target.value))
},
[onChange],
)
return (
<Select value={value} onChange={_onChange}>
{Object.keys(options).map((key, i) => (
<option key={'option-' + i} value={key}>
{options[key]}
</option>
))}
</Select>
)
}
export default BasicSelectEditor

View file

@ -0,0 +1,79 @@
import {darken} from 'polished'
import React, {useCallback} from 'react'
import styled from 'styled-components'
const Container = styled.form`
display: flex;
flex-direction: row;
align-items: stretch;
vertical-align: middle;
height: 24px;
`
const Label = styled.label`
padding: 0 0.5em;
background: transparent;
/* background: #373748; */
display: flex;
align-items: center;
color: #a7a7a7;
border: 1px solid #1c2123;
box-sizing: border-box;
border-right-width: 0px;
& + &:last-child {
border-right-width: 1px;
}
${Container}:hover > & {
/* background-color: #373748; */
/* color: ${darken(0.1, 'white')}; */
}
&&:hover {
background-color: #464654;
}
&&[data-checked='true'] {
color: white;
background: #3f3f4c;
}
`
const Input = styled.input`
position: absolute;
opacity: 0;
pointer-events: none;
width: 0;
height: 0;
`
const BasicSwitchEditor: React.FC<{
value: string
onChange: (val: string) => void
options: Record<string, string>
}> = ({value, onChange, options}) => {
const _onChange = useCallback(
(el: React.ChangeEvent<HTMLInputElement>) => {
onChange(String(el.target.value))
},
[onChange],
)
return (
<Container role="radiogroup">
{Object.keys(options).map((key, i) => (
<Label key={'label-' + i} data-checked={value === key}>
{options[key]}
<Input
type="radio"
checked={value === key}
value={key}
onChange={_onChange}
name="switchbox"
/>
</Label>
))}
</Container>
)
}
export default BasicSwitchEditor