Tweak the style of ImagePropEditor
This commit is contained in:
parent
8deac10685
commit
41fb7de533
2 changed files with 91 additions and 54 deletions
|
@ -36,6 +36,7 @@ const ImageTypeExample: React.FC<{}> = (props) => {
|
||||||
label: 'another texture',
|
label: 'another texture',
|
||||||
}),
|
}),
|
||||||
something: 'asdf',
|
something: 'asdf',
|
||||||
|
color: types.rgba(),
|
||||||
})
|
})
|
||||||
object.onValuesChange(({image}) => {
|
object.onValuesChange(({image}) => {
|
||||||
setImageUrl(project.getAssetUrl(image))
|
setImageUrl(project.getAssetUrl(image))
|
||||||
|
|
|
@ -1,40 +1,62 @@
|
||||||
import type {PropTypeConfig_Image} from '@theatre/core/propTypes'
|
import type {PropTypeConfig_Image} from '@theatre/core/propTypes'
|
||||||
import {Trash} from '@theatre/studio/uiComponents/icons'
|
import {Trash} from '@theatre/studio/uiComponents/icons'
|
||||||
import React, {useCallback, useEffect} from 'react'
|
import React, {useCallback, useEffect} from 'react'
|
||||||
import styled from 'styled-components'
|
import styled, {css} from 'styled-components'
|
||||||
import type {ISimplePropEditorReactProps} from './ISimplePropEditorReactProps'
|
import type {ISimplePropEditorReactProps} from './ISimplePropEditorReactProps'
|
||||||
|
|
||||||
const Container = styled.div`
|
const Container = styled.div<{empty: boolean}>`
|
||||||
box-sizing: border-box;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
padding: 2px;
|
|
||||||
`
|
|
||||||
|
|
||||||
const Group = styled.div<{empty: boolean}>`
|
|
||||||
box-sizing: border-box;
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 4px;
|
|
||||||
overflow: hidden;
|
|
||||||
${({empty}) =>
|
|
||||||
empty
|
|
||||||
? `border: 1px dashed rgba(255, 255, 255, 0.2)`
|
|
||||||
: `border: 1px solid rgba(255, 255, 255, 0.05)`}
|
|
||||||
`
|
|
||||||
|
|
||||||
const InputLabel = styled.label`
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
height: 100%;
|
||||||
|
gap: 4px;
|
||||||
|
`
|
||||||
|
|
||||||
|
const AddImage = styled.div`
|
||||||
|
position: absolute;
|
||||||
|
inset: -5px;
|
||||||
|
// rotate 45deg
|
||||||
|
transform: rotate(45deg);
|
||||||
|
--checker-color: #ededed36;
|
||||||
|
&:hover {
|
||||||
|
--checker-color: #ededed77;
|
||||||
|
}
|
||||||
|
// checkerboard background with 4px squares
|
||||||
|
background-image: linear-gradient(
|
||||||
|
45deg,
|
||||||
|
var(--checker-color) 25%,
|
||||||
|
transparent 25%
|
||||||
|
),
|
||||||
|
linear-gradient(-45deg, var(--checker-color) 25%, transparent 25%),
|
||||||
|
linear-gradient(45deg, transparent 75%, var(--checker-color) 75%),
|
||||||
|
linear-gradient(-45deg, transparent 75%, var(--checker-color) 75%);
|
||||||
|
background-size: 5px 5px;
|
||||||
|
`
|
||||||
|
|
||||||
|
const InputLabel = styled.label<{empty: boolean}>`
|
||||||
|
position: relative;
|
||||||
|
cursor: default;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
color: #919191;
|
|
||||||
|
height: 18px;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 16px;
|
||||||
|
|
||||||
|
overflow: hidden;
|
||||||
|
color: #ccc;
|
||||||
|
&:hover {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
border-radius: 99999px;
|
||||||
|
border: 1px solid hwb(220deg 40% 52%);
|
||||||
|
&:hover {
|
||||||
|
border-color: hwb(220deg 45% 52%);
|
||||||
|
}
|
||||||
|
|
||||||
|
${(props) => (props.empty ? css`` : css``)}
|
||||||
`
|
`
|
||||||
|
|
||||||
// file input
|
// file input
|
||||||
|
@ -45,8 +67,9 @@ const Input = styled.input.attrs({type: 'file', accept: 'image/*'})`
|
||||||
const Preview = styled.img`
|
const Preview = styled.img`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
@ -55,16 +78,22 @@ const DeleteButton = styled.button`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
background: transparent;
|
||||||
color: #a8a8a9;
|
color: #a8a8a9;
|
||||||
background: rgba(255, 255, 255, 0.1);
|
|
||||||
|
|
||||||
border: none;
|
border: none;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
aspect-ratio: 1/1;
|
aspect-ratio: 1/1;
|
||||||
|
|
||||||
|
opacity: 0;
|
||||||
|
|
||||||
|
${Container}:hover & {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: rgba(255, 255, 255, 0.15);
|
opacity: 1;
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
@ -103,20 +132,28 @@ function ImagePropEditor({
|
||||||
[editingTools, value],
|
[editingTools, value],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const empty = !value?.id
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container empty={empty}>
|
||||||
<Group empty={!value}>
|
<InputLabel
|
||||||
<InputLabel>
|
empty={empty}
|
||||||
|
title={
|
||||||
|
empty ? 'Upload image' : `"${value.id}" (Click to upload new image)`
|
||||||
|
}
|
||||||
|
>
|
||||||
<Input
|
<Input
|
||||||
type="file"
|
type="file"
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
accept="image/*"
|
accept="image/*"
|
||||||
autoFocus={autoFocus}
|
autoFocus={autoFocus}
|
||||||
/>
|
/>
|
||||||
{previewUrl ? <Preview src={previewUrl} /> : <span>Add image</span>}
|
{previewUrl ? <Preview src={previewUrl} /> : <AddImage />}
|
||||||
</InputLabel>
|
</InputLabel>
|
||||||
{value && (
|
|
||||||
|
{!empty && (
|
||||||
<DeleteButton
|
<DeleteButton
|
||||||
|
title="Delete image"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
editingTools.permanentlySetValue({type: 'image', id: undefined})
|
editingTools.permanentlySetValue({type: 'image', id: undefined})
|
||||||
}}
|
}}
|
||||||
|
@ -124,7 +161,6 @@ function ImagePropEditor({
|
||||||
<Trash />
|
<Trash />
|
||||||
</DeleteButton>
|
</DeleteButton>
|
||||||
)}
|
)}
|
||||||
</Group>
|
|
||||||
</Container>
|
</Container>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue