tldraw/components/controls-panel/control.tsx

166 lines
3.5 KiB
TypeScript
Raw Normal View History

2021-06-21 21:35:28 +00:00
import state, { useSelector } from 'state'
import styled from 'styles'
2021-06-27 13:53:06 +00:00
import {
ControlType,
NumberCodeControl,
TextCodeControl,
VectorCodeControl,
} from 'types'
2021-05-17 10:01:11 +00:00
2021-06-21 21:35:28 +00:00
export default function Control({ id }: { id: string }): JSX.Element {
2021-05-17 10:01:11 +00:00
const control = useSelector((s) => s.data.codeControls[id])
if (!control) return null
return (
<>
<label>{control.label}</label>
2021-06-27 13:53:06 +00:00
{(() => {
switch (control.type) {
case ControlType.Number:
return <NumberControl {...control} />
case ControlType.Vector:
return <VectorControl {...control} />
case ControlType.Text:
return <TextControl {...control} />
}
})()}
2021-05-17 10:01:11 +00:00
</>
)
}
function NumberControl({ id, min, max, step, value }: NumberCodeControl) {
return (
<Inputs>
<input
type="range"
min={min}
max={max}
step={step}
value={value}
onChange={(e) =>
2021-06-21 21:35:28 +00:00
state.send('CHANGED_CODE_CONTROL', {
2021-05-17 10:01:11 +00:00
[id]: Number(e.currentTarget.value),
})
}
/>
<input
type="number"
min={min}
max={max}
step={step}
value={value}
onChange={(e) =>
2021-06-21 21:35:28 +00:00
state.send('CHANGED_CODE_CONTROL', {
2021-05-17 10:01:11 +00:00
[id]: Number(e.currentTarget.value),
})
}
/>
</Inputs>
)
}
function VectorControl({
id,
value,
min = -Infinity,
max = Infinity,
step = 0.01,
isNormalized = false,
}: VectorCodeControl) {
2021-05-17 10:01:11 +00:00
return (
<Inputs>
<input
type="range"
min={isNormalized ? -1 : min}
max={isNormalized ? 1 : max}
step={step}
2021-05-17 10:01:11 +00:00
value={value[0]}
onChange={(e) =>
2021-06-21 21:35:28 +00:00
state.send('CHANGED_CODE_CONTROL', {
2021-05-17 10:01:11 +00:00
[id]: [Number(e.currentTarget.value), value[1]],
})
}
/>
<input
type="number"
min={isNormalized ? -1 : min}
max={isNormalized ? 1 : max}
step={step}
2021-05-17 10:01:11 +00:00
value={value[0]}
onChange={(e) =>
2021-06-21 21:35:28 +00:00
state.send('CHANGED_CODE_CONTROL', {
2021-05-17 10:01:11 +00:00
[id]: [Number(e.currentTarget.value), value[1]],
})
}
/>
<input
type="range"
min={isNormalized ? -1 : min}
max={isNormalized ? 1 : max}
step={step}
2021-05-17 10:01:11 +00:00
value={value[1]}
onChange={(e) =>
2021-06-21 21:35:28 +00:00
state.send('CHANGED_CODE_CONTROL', {
2021-05-17 10:01:11 +00:00
[id]: [value[0], Number(e.currentTarget.value)],
})
}
/>
<input
type="number"
min={isNormalized ? -1 : min}
max={isNormalized ? 1 : max}
step={step}
2021-05-17 10:01:11 +00:00
value={value[1]}
onChange={(e) =>
2021-06-21 21:35:28 +00:00
state.send('CHANGED_CODE_CONTROL', {
2021-05-17 10:01:11 +00:00
[id]: [value[0], Number(e.currentTarget.value)],
})
}
/>
</Inputs>
)
}
2021-06-27 13:53:06 +00:00
function TextControl({ id, value }: TextCodeControl) {
return (
<Inputs>
<input
type="text"
value={value}
onChange={(e) =>
state.send('CHANGED_CODE_CONTROL', {
[id]: e.currentTarget.value,
})
}
/>
</Inputs>
)
}
2021-06-21 21:35:28 +00:00
const Inputs = styled('div', {
display: 'flex',
gap: '8px',
height: '100%',
2021-05-17 10:01:11 +00:00
2021-06-21 21:35:28 +00:00
'& input': {
font: '$ui',
width: '64px',
fontSize: '$1',
border: '1px solid $inputBorder',
backgroundColor: '$input',
color: '$text',
height: '100%',
padding: '0px 6px',
2021-05-17 10:01:11 +00:00
},
"& input[type='range']": {
padding: 0,
flexGrow: 2,
},
2021-06-27 13:53:06 +00:00
"& input[type='text']": {
minWidth: 200,
padding: 4,
flexGrow: 2,
},
2021-05-17 10:01:11 +00:00
})