Range indicator for the number editor

This commit is contained in:
Aria Minaei 2021-07-16 11:08:09 +02:00
parent 4e4452f0ad
commit 232ffa7836
4 changed files with 63 additions and 9 deletions

View file

@ -295,7 +295,10 @@ const editorSheetObjectConfig = types.compound({
showAxes: types.boolean(true, {label: 'Axes'}),
showGrid: types.boolean(true, {label: 'Grid'}),
showOverlayIcons: types.boolean(false, {label: 'Overlay Icons'}),
resolution: types.number(1440, {label: 'Resolution'}),
resolution: types.number(1440, {
label: 'Resolution',
range: [0, 1000],
}),
shading: types.stringLiteral(
'rendered',
{

View file

@ -12,15 +12,12 @@ interface IBasePropType<ValueType> {
export interface PropTypeConfig_Number extends IBasePropType<number> {
type: 'number'
default: number
min?: number
max?: number
step?: number
range?: [min: number, max: number]
}
export const number = (
defaultValue: number,
opts?: Pick<PropTypeConfig_Number, 'min' | 'max' | 'step'> &
PropTypeConfigExtras,
opts?: Pick<PropTypeConfig_Number, 'range'> & PropTypeConfigExtras,
): PropTypeConfig_Number => {
return {
type: 'number',

View file

@ -19,6 +19,7 @@ const NumberPropEditor: React.FC<{
temporarilySetValue={stuff.temporarilySetValue}
discardTemporaryValue={stuff.discardTemporaryValue}
permenantlySetValue={stuff.permenantlySetValue}
range={propConfig.range}
/>
</SingleRowPropEditor>
)

View file

@ -1,5 +1,5 @@
import {theme} from '@theatre/studio/css'
import {isInteger, round} from 'lodash-es'
import {clamp, isInteger, round} from 'lodash-es'
import {darken, lighten} from 'polished'
import React, {useMemo, useRef, useState} from 'react'
import styled from 'styled-components'
@ -10,6 +10,31 @@ type IMode = IState['mode']
const Container = styled.div`
height: 100%;
width: 100%;
position: relative;
z-index: 0;
box-sizing: border-box;
&:after {
position: absolute;
inset: 1px 0 2px;
display: block;
content: ' ';
background-color: #2525252b;
border: 1px solid #1c2123;
z-index: -2;
box-sizing: border-box;
border-radius: 1px;
}
&:hover,
&.dragging,
&.editingViaKeyboard {
&:after {
background-color: #10101042;
/* background-color: ${darken(0.2, theme.panel.bg)}; */
border-color: #00000059;
}
}
`
const Input = styled.input`
@ -25,18 +50,32 @@ const Input = styled.input`
height: calc(100% - 4px);
border-radius: 2px;
&:hover,
/* &:hover,
&:focus,
${Container}.dragging > & {
background: ${darken(0.9, theme.panel.bg)};
border: 1px solid ${lighten(0.1, theme.panel.bg)};
}
} */
&:focus {
cursor: text;
}
`
const FillIndicator = styled.div`
position: absolute;
inset: 3px 2px 4px;
transform: scale(var(--percentage), 1);
transform-origin: top left;
background-color: #2d5561;
z-index: -1;
border-radius: 2px;
${Container}.dragging &, ${Container}.noFocus:hover & {
background-color: #338198;
}
`
function isValueAcceptable(s: string) {
const v = parseFloat(s)
return !isNaN(v)
@ -66,6 +105,7 @@ const BasicNumberInput: React.FC<{
discardTemporaryValue: () => void
permenantlySetValue: (v: number) => void
className?: string
range?: [min: number, max: number]
}> = (propsA) => {
const [stateA, setState] = useState<IState>({mode: 'noFocus'})
@ -238,6 +278,18 @@ const BasicNumberInput: React.FC<{
/>
)
const {range} = propsA
const num = parseFloat(value)
const fillIndicator = range ? (
<FillIndicator
style={{
// @ts-ignore
'--percentage': clamp((num - range[0]) / (range[1] - range[0]), 0, 1),
}}
/>
) : null
return (
<Container className={propsA.className + ' ' + refs.current.state.mode}>
<DraggableArea
@ -250,6 +302,7 @@ const BasicNumberInput: React.FC<{
>
{theInput}
</DraggableArea>
{fillIndicator}
</Container>
)
}