revite/src/components/ui/ColourSwatches.tsx

119 lines
2.5 KiB
TypeScript
Raw Normal View History

2021-06-18 09:20:57 -04:00
import { useRef } from 'preact/hooks';
import { Check } from '@styled-icons/feather';
import styled, { css } from 'styled-components';
import { Pencil } from '@styled-icons/bootstrap';
interface Props {
value: string;
onChange: (value: string) => void;
}
const presets = [
[
"#7B68EE",
"#3498DB",
"#1ABC9C",
"#F1C40F",
"#FF7F50",
"#FD6671",
"#E91E63",
"#D468EE"
],
[
"#594CAD",
"#206694",
"#11806A",
"#C27C0E",
"#CD5B45",
"#FF424F",
"#AD1457",
"#954AA8"
]
];
const SwatchesBase = styled.div`
gap: 8px;
display: flex;
input {
opacity: 0;
margin-top: 44px;
position: absolute;
pointer-events: none;
}
`;
const Swatch = styled.div<{ type: 'small' | 'large', colour: string }>`
flex-shrink: 0;
cursor: pointer;
border-radius: 4px;
background-color: ${ props => props.colour };
display: grid;
place-items: center;
&:hover {
border: 3px solid var(--foreground);
transition: border ease-in-out .07s;
}
svg {
color: white;
}
${ props => props.type === 'small' ? css`
width: 30px;
height: 30px;
svg {
stroke-width: 2;
}
` : css`
width: 68px;
height: 68px;
` }
`;
const Rows = styled.div`
gap: 8px;
display: flex;
flex-direction: column;
> div {
gap: 8px;
display: flex;
flex-direction: row;
}
`;
export function ColourSwatches({ value, onChange }: Props) {
const ref = useRef<HTMLInputElement>();
return (
<SwatchesBase>
<Swatch colour={value} type='large'
onClick={() => ref.current.click()}>
<Pencil size={32} />
</Swatch>
<input
type="color"
value={value}
ref={ref}
onChange={ev => onChange(ev.currentTarget.value)}
/>
<Rows>
{presets.map(row => (
<div>
{ row.map(swatch => (
<Swatch colour={swatch} type='small'
onClick={() => onChange(swatch)}>
{swatch === value && <Check size={18} strokeWidth={2} />}
</Swatch>
)) }
</div>
))}
</Rows>
</SwatchesBase>
)
}