mirror of
https://github.com/iconoir-icons/iconoir
synced 2024-06-26 17:30:16 +02:00
8ec9a33978
* fix: optimized customization panel * Update iconoir.com/components/CustomizationEditor.tsx Co-authored-by: Sam Marks <sam@sammarks.me> --------- Co-authored-by: Sam Marks <sam@sammarks.me>
127 lines
3.3 KiB
TypeScript
127 lines
3.3 KiB
TypeScript
import React from 'react';
|
|
import styled from 'styled-components';
|
|
import { Button } from './Button';
|
|
import { DEFAULT_CUSTOMIZATIONS, IconListCustomizations } from './IconList';
|
|
import { ColorButton, ColorInput } from './Input';
|
|
import { Slider } from './Slider';
|
|
import { Text13, Text15 } from './Typography';
|
|
|
|
export interface CustomizationEditorProps {
|
|
customizations: IconListCustomizations;
|
|
// eslint-disable-next-line no-unused-vars
|
|
onChange: (customizations: IconListCustomizations) => void;
|
|
}
|
|
export function CustomizationEditor({
|
|
customizations,
|
|
onChange,
|
|
}: CustomizationEditorProps) {
|
|
const [, startTransition] = (React as any).useTransition();
|
|
const [color, setColor] = React.useState(customizations.hexColor);
|
|
const [size, setSize] = React.useState(customizations.size);
|
|
const [strokeWidth, setStrokeWidth] = React.useState(
|
|
customizations.strokeWidth
|
|
);
|
|
React.useEffect(() => {
|
|
setColor(customizations.hexColor);
|
|
setSize(customizations.size);
|
|
setStrokeWidth(customizations.strokeWidth);
|
|
}, [customizations]);
|
|
|
|
function updateCustomizations(partial: Partial<IconListCustomizations>) {
|
|
startTransition(() => {
|
|
onChange({
|
|
...customizations,
|
|
...partial,
|
|
});
|
|
});
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<CustomizationBox>
|
|
<Header>
|
|
<Text15 style={{ fontWeight: 700, color: 'var(--black)' }}>
|
|
Customize
|
|
</Text15>
|
|
<ResetButton onClick={() => onChange(DEFAULT_CUSTOMIZATIONS)}>Reset</ResetButton>
|
|
</Header>
|
|
<Field>
|
|
<Slider
|
|
label={'Optical Size'}
|
|
minValue={16}
|
|
maxValue={64}
|
|
value={[size]}
|
|
formatOptions={{ maximumFractionDigits: 0 }}
|
|
onChange={(values) => {
|
|
setSize(values[0]);
|
|
updateCustomizations({ size: values[0] });
|
|
}}
|
|
/>
|
|
</Field>
|
|
<Field>
|
|
<Slider
|
|
label={'Stroke Weight'}
|
|
minValue={0.5}
|
|
maxValue={3}
|
|
value={[strokeWidth]}
|
|
step={0.1}
|
|
formatOptions={{ maximumFractionDigits: 1 }}
|
|
onChange={(values) => {
|
|
setStrokeWidth(values[0]);
|
|
updateCustomizations({ strokeWidth: values[0] });
|
|
}}
|
|
/>
|
|
</Field>
|
|
<HorizontalField>
|
|
<Text13>Color</Text13>
|
|
<ColorInput
|
|
type={'color'}
|
|
value={color}
|
|
onChange={(e) => {
|
|
setColor(e.target.value);
|
|
updateCustomizations({ hexColor: e.target.value });
|
|
}}
|
|
/>
|
|
<ColorButton />
|
|
|
|
</HorizontalField>
|
|
</CustomizationBox>
|
|
</>
|
|
);
|
|
}
|
|
|
|
const CustomizationBox = styled.div`
|
|
background-color:var(--gray-200);
|
|
width: 84%;
|
|
padding: 8%;
|
|
border-radius: 10px;
|
|
margin-bottom: 30px;
|
|
`;
|
|
const Header = styled.div`
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-bottom: 30px;
|
|
border-bottom: solid 1px var(--light-gray);
|
|
padding-bottom: 10px;
|
|
`;
|
|
const Field = styled.div`
|
|
margin-bottom: 24px;
|
|
`;
|
|
const HorizontalField = styled(Field)`
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
`;
|
|
const ResetButton = styled(Field)`
|
|
margin: initial;
|
|
text-decoration: underline;
|
|
color: var(--dark-gray);
|
|
font-size: 13px;
|
|
|
|
&:hover{
|
|
color: var(--black);
|
|
cursor: pointer;
|
|
}
|
|
`;
|