256 lines
6.7 KiB
TypeScript
256 lines
6.7 KiB
TypeScript
import { ease } from "@unom/style";
|
|
import { motion } from "framer-motion";
|
|
import {
|
|
AnimatedTextEntity,
|
|
AnimatedRectEntity,
|
|
AnimatedStaggeredTextEntity,
|
|
AnimatedEllipseEntity,
|
|
} from "primitives/AnimatedEntities";
|
|
import { Paint, PaintStyle, PaintStyleType } from "primitives/Paint";
|
|
import { FC } from "react";
|
|
import { z } from "zod";
|
|
import { ColorProperties } from "./Values";
|
|
import { PropertiesProps } from "./common";
|
|
import { useFontsStore } from "stores/fonts.store";
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
} from "components/Inputs/Select";
|
|
|
|
type TextPropertiesProps = PropertiesProps<z.input<typeof AnimatedTextEntity>>;
|
|
type StaggeredTextPropertiesProps = PropertiesProps<
|
|
z.input<typeof AnimatedStaggeredTextEntity>
|
|
>;
|
|
type PaintPropertiesProps = PropertiesProps<z.input<typeof Paint>>;
|
|
type RectPropertiesProps = PropertiesProps<z.input<typeof AnimatedRectEntity>>;
|
|
type EllipsePropertiesProps = PropertiesProps<
|
|
z.input<typeof AnimatedEllipseEntity>
|
|
>;
|
|
|
|
export const PaintProperties: FC<PaintPropertiesProps> = ({
|
|
entity,
|
|
onUpdate,
|
|
}) => {
|
|
return (
|
|
<div>
|
|
<fieldset>
|
|
<label htmlFor="paint-style-type">PaintStyle</label>
|
|
<Select
|
|
defaultValue={entity.style.type}
|
|
onValueChange={(value) => {
|
|
if (entity.style.type !== value) {
|
|
const paintStyle = { type: value };
|
|
|
|
const parsedPaintStyle = PaintStyle.parse(paintStyle);
|
|
|
|
onUpdate({ style: parsedPaintStyle });
|
|
}
|
|
}}
|
|
>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Choose a paint style" />
|
|
</SelectTrigger>
|
|
<SelectContent id="paint-style-type" className="overflow-hidden">
|
|
{Object.keys(PaintStyleType.Values).map((paintStyleType) => (
|
|
<SelectItem value={paintStyleType}>{paintStyleType}</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
</fieldset>
|
|
{entity.style.color && (
|
|
<ColorProperties
|
|
label="Color"
|
|
onUpdate={(color) =>
|
|
onUpdate({ ...entity, style: { ...entity.style, color } })
|
|
}
|
|
entity={entity.style.color}
|
|
/>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export const TextProperties: FC<TextPropertiesProps> = ({
|
|
entity,
|
|
onUpdate,
|
|
}) => {
|
|
const { fonts } = useFontsStore();
|
|
|
|
return (
|
|
<motion.div
|
|
variants={{ enter: { opacity: 1, y: 0 }, from: { opacity: 0, y: 50 } }}
|
|
animate="enter"
|
|
initial="from"
|
|
transition={ease.quint(0.9).out}
|
|
>
|
|
<fieldset>
|
|
<label htmlFor="text-content">Text</label>
|
|
<input
|
|
id="text-content"
|
|
value={entity.text}
|
|
onChange={(e) => onUpdate({ ...entity, text: e.target.value })}
|
|
/>
|
|
</fieldset>
|
|
<fieldset>
|
|
<label htmlFor="text-size">Size</label>
|
|
<input
|
|
id="text-size"
|
|
value={entity.paint.size}
|
|
onChange={(e) =>
|
|
onUpdate({
|
|
...entity,
|
|
paint: { ...entity.paint, size: Number(e.target.value) },
|
|
})
|
|
}
|
|
/>
|
|
</fieldset>
|
|
<fieldset>
|
|
<label htmlFor="text-font">Font</label>
|
|
|
|
<Select
|
|
defaultValue={entity.paint.font_name}
|
|
onValueChange={(val) => {
|
|
onUpdate({
|
|
...entity,
|
|
cache: { valid: false },
|
|
paint: { ...entity.paint, font_name: val },
|
|
});
|
|
}}
|
|
>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Choose a font" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{fonts.map((font) => (
|
|
<SelectItem value={font}>{font}</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
</fieldset>
|
|
</motion.div>
|
|
);
|
|
};
|
|
|
|
export const StaggeredTextProperties: FC<StaggeredTextPropertiesProps> = ({
|
|
entity,
|
|
onUpdate,
|
|
}) => {
|
|
const { fonts } = useFontsStore();
|
|
|
|
return (
|
|
<motion.div
|
|
variants={{ enter: { opacity: 1, y: 0 }, from: { opacity: 0, y: 50 } }}
|
|
animate="enter"
|
|
initial="from"
|
|
transition={ease.quint(0.9).out}
|
|
>
|
|
<fieldset>
|
|
<label htmlFor="staggered-text-content">Text</label>
|
|
<input
|
|
id="staggered-text-content"
|
|
value={entity.text}
|
|
onChange={(e) =>
|
|
onUpdate({
|
|
...entity,
|
|
text: e.target.value,
|
|
cache: { valid: false },
|
|
})
|
|
}
|
|
/>
|
|
</fieldset>
|
|
<fieldset>
|
|
<label htmlFor="staggered-text-letter-font">Font</label>
|
|
<Select
|
|
defaultValue={entity.letter.paint.font_name}
|
|
onValueChange={(val) => {
|
|
onUpdate({
|
|
...entity,
|
|
cache: { valid: false },
|
|
letter: {
|
|
...entity.letter,
|
|
paint: { ...entity.letter.paint, font_name: val },
|
|
},
|
|
});
|
|
}}
|
|
>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Choose a font" />
|
|
</SelectTrigger>
|
|
<SelectContent className="overflow-hidden">
|
|
{fonts.map((font) => (
|
|
<SelectItem value={font}>{font}</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
</fieldset>
|
|
<fieldset>
|
|
<label htmlFor="staggered-text-letter-size">Size</label>
|
|
<input
|
|
id="staggered-text-letter-size"
|
|
value={entity.letter.paint.size}
|
|
onChange={(e) =>
|
|
onUpdate({
|
|
...entity,
|
|
cache: { valid: false },
|
|
letter: {
|
|
...entity.letter,
|
|
paint: {
|
|
...entity.letter.paint,
|
|
size: Number(e.target.value),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
/>
|
|
</fieldset>
|
|
<PaintProperties
|
|
entity={entity.letter.paint}
|
|
onUpdate={(paint) =>
|
|
onUpdate({
|
|
...entity,
|
|
letter: {
|
|
...entity.letter,
|
|
paint: { ...entity.letter.paint, ...paint },
|
|
},
|
|
})
|
|
}
|
|
/>
|
|
</motion.div>
|
|
);
|
|
};
|
|
|
|
export const RectProperties: FC<RectPropertiesProps> = ({
|
|
entity,
|
|
onUpdate,
|
|
}) => {
|
|
return (
|
|
<div className="dark:text-white">
|
|
<PaintProperties
|
|
entity={entity.paint}
|
|
onUpdate={(paint) =>
|
|
onUpdate({ ...entity, paint: { ...entity.paint, ...paint } })
|
|
}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export const EllipseProperties: FC<EllipsePropertiesProps> = ({
|
|
entity,
|
|
onUpdate,
|
|
}) => {
|
|
return (
|
|
<div className="dark:text-white">
|
|
<PaintProperties
|
|
entity={entity.paint}
|
|
onUpdate={(paint) =>
|
|
onUpdate({ ...entity, paint: { ...entity.paint, ...paint } })
|
|
}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|