tldraw/components/style-panel/color-picker.tsx

125 lines
2.5 KiB
TypeScript
Raw Normal View History

2021-05-28 20:30:27 +00:00
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
import { Square } from 'react-feather'
import styled from 'styles'
2021-05-26 10:34:10 +00:00
interface Props {
label: string
color: string
2021-05-26 21:47:46 +00:00
colors: Record<string, string>
2021-05-26 10:34:10 +00:00
onChange: (color: string) => void
}
2021-05-26 21:47:46 +00:00
export default function ColorPicker({ label, color, colors, onChange }: Props) {
2021-05-26 10:34:10 +00:00
return (
<DropdownMenu.Root>
<CurrentColor>
2021-05-28 20:30:27 +00:00
<label>{label}</label>
2021-05-26 10:34:10 +00:00
<ColorIcon color={color} />
</CurrentColor>
<Colors sideOffset={4}>
{Object.entries(colors).map(([name, color]) => (
<ColorButton key={name} title={name} onSelect={() => onChange(color)}>
<ColorIcon color={color} />
</ColorButton>
))}
</Colors>
</DropdownMenu.Root>
)
}
function ColorIcon({ color }: { color: string }) {
return (
2021-05-29 13:59:11 +00:00
<Square fill={color} strokeDasharray={color === 'none' ? '2, 3' : 'none'} />
2021-05-26 10:34:10 +00:00
)
}
const Colors = styled(DropdownMenu.Content, {
2021-05-28 20:30:27 +00:00
display: 'grid',
2021-05-26 10:34:10 +00:00
padding: 4,
2021-05-28 20:30:27 +00:00
gridTemplateColumns: 'repeat(6, 1fr)',
border: '1px solid $border',
backgroundColor: '$panel',
2021-05-26 10:34:10 +00:00
borderRadius: 4,
2021-05-28 20:30:27 +00:00
boxShadow: '0px 5px 15px -5px hsla(206,22%,7%,.15)',
2021-05-26 10:34:10 +00:00
})
const ColorButton = styled(DropdownMenu.Item, {
2021-05-28 20:30:27 +00:00
position: 'relative',
cursor: 'pointer',
2021-05-26 10:34:10 +00:00
height: 32,
width: 32,
2021-05-28 20:30:27 +00:00
border: 'none',
padding: 'none',
background: 'none',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
2021-05-26 10:34:10 +00:00
2021-05-28 20:30:27 +00:00
'&::before': {
2021-05-26 10:34:10 +00:00
content: "''",
2021-05-28 20:30:27 +00:00
position: 'absolute',
2021-05-26 10:34:10 +00:00
top: 4,
left: 4,
right: 4,
bottom: 4,
2021-05-28 20:30:27 +00:00
pointerEvents: 'none',
2021-05-26 10:34:10 +00:00
zIndex: 0,
},
2021-05-28 20:30:27 +00:00
'&:hover::before': {
backgroundColor: '$hover',
2021-05-26 10:34:10 +00:00
borderRadius: 4,
},
2021-05-28 20:30:27 +00:00
'& svg': {
position: 'relative',
stroke: 'rgba(0,0,0,.2)',
2021-05-26 10:34:10 +00:00
strokeWidth: 1,
zIndex: 1,
},
})
const CurrentColor = styled(DropdownMenu.Trigger, {
2021-05-28 20:30:27 +00:00
position: 'relative',
display: 'flex',
width: '100%',
background: 'none',
border: 'none',
cursor: 'pointer',
outline: 'none',
alignItems: 'center',
justifyContent: 'space-between',
padding: '4px 6px 4px 12px',
2021-05-26 10:34:10 +00:00
2021-05-28 20:30:27 +00:00
'&::before': {
2021-05-26 10:34:10 +00:00
content: "''",
2021-05-28 20:30:27 +00:00
position: 'absolute',
2021-05-26 19:20:52 +00:00
top: 0,
2021-05-27 17:59:40 +00:00
left: 0,
right: 0,
2021-05-26 19:20:52 +00:00
bottom: 0,
2021-05-28 20:30:27 +00:00
pointerEvents: 'none',
2021-05-26 10:34:10 +00:00
zIndex: -1,
},
2021-05-28 20:30:27 +00:00
'&:hover::before': {
backgroundColor: '$hover',
2021-05-26 10:34:10 +00:00
borderRadius: 4,
},
2021-05-28 20:30:27 +00:00
'& label': {
fontFamily: '$ui',
fontSize: '$2',
fontWeight: '$1',
2021-05-26 10:34:10 +00:00
margin: 0,
padding: 0,
},
2021-05-28 20:30:27 +00:00
'& svg': {
position: 'relative',
stroke: 'rgba(0,0,0,.2)',
2021-05-26 10:34:10 +00:00
strokeWidth: 1,
zIndex: 1,
},
})