refactor: separate property item component

This commit is contained in:
Maze Winther
2025-07-10 21:48:26 +02:00
parent ed4e9dad19
commit fe6492f359
2 changed files with 103 additions and 48 deletions

View File

@ -0,0 +1,47 @@
import { cn } from "@/lib/utils";
interface PropertyItemProps {
direction?: "row" | "column";
children: React.ReactNode;
className?: string;
}
export function PropertyItem({
direction = "row",
children,
className,
}: PropertyItemProps) {
return (
<div
className={cn(
"flex gap-2",
direction === "row"
? "items-center justify-between gap-6"
: "flex-col gap-1",
className
)}
>
{children}
</div>
);
}
export function PropertyItemLabel({
children,
className,
}: {
children: React.ReactNode;
className?: string;
}) {
return <label className={cn("text-xs", className)}>{children}</label>;
}
export function PropertyItemValue({
children,
className,
}: {
children: React.ReactNode;
className?: string;
}) {
return <div className={cn("flex-1", className)}>{children}</div>;
}

View File

@ -1,5 +1,4 @@
import { Textarea } from "@/components/ui/textarea"; import { Textarea } from "@/components/ui/textarea";
import { Label } from "@/components/ui/label";
import { import {
Select, Select,
SelectContent, SelectContent,
@ -12,6 +11,11 @@ import { TextElement } from "@/types/timeline";
import { useTimelineStore } from "@/stores/timeline-store"; import { useTimelineStore } from "@/stores/timeline-store";
import { Slider } from "@/components/ui/slider"; import { Slider } from "@/components/ui/slider";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import {
PropertyItem,
PropertyItemLabel,
PropertyItemValue,
} from "./property-item";
export function TextProperties({ export function TextProperties({
element, element,
@ -32,54 +36,58 @@ export function TextProperties({
updateTextElement(trackId, element.id, { content: e.target.value }) updateTextElement(trackId, element.id, { content: e.target.value })
} }
/> />
<div className="flex items-center justify-between gap-6"> <PropertyItem direction="row">
<Label className="text-xs">Font</Label> <PropertyItemLabel>Font</PropertyItemLabel>
<Select <PropertyItemValue>
defaultValue={element.fontFamily} <Select
onValueChange={(value: FontFamily) => defaultValue={element.fontFamily}
updateTextElement(trackId, element.id, { fontFamily: value }) onValueChange={(value: FontFamily) =>
} updateTextElement(trackId, element.id, { fontFamily: value })
>
<SelectTrigger className="w-full text-xs">
<SelectValue placeholder="Select a font" />
</SelectTrigger>
<SelectContent>
{FONT_OPTIONS.map((font) => (
<SelectItem key={font.value} value={font.value}>
{font.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="flex flex-col gap-1">
<Label className="text-xs">Font size</Label>
<div className="flex items-center gap-2">
<Slider
defaultValue={[element.fontSize]}
min={8}
max={200}
step={1}
onValueChange={([value]) =>
updateTextElement(trackId, element.id, { fontSize: value })
} }
className="w-full" >
/> <SelectTrigger className="w-full text-xs">
<Input <SelectValue placeholder="Select a font" />
type="number" </SelectTrigger>
value={element.fontSize} <SelectContent>
onChange={(e) => {FONT_OPTIONS.map((font) => (
updateTextElement(trackId, element.id, { <SelectItem key={font.value} value={font.value}>
fontSize: parseInt(e.target.value), {font.label}
}) </SelectItem>
} ))}
className="w-12 !text-xs h-7 rounded-sm text-center </SelectContent>
[appearance:textfield] </Select>
[&::-webkit-outer-spin-button]:appearance-none </PropertyItemValue>
[&::-webkit-inner-spin-button]:appearance-none" </PropertyItem>
/> <PropertyItem direction="column">
</div> <PropertyItemLabel>Font size</PropertyItemLabel>
</div> <PropertyItemValue>
<div className="flex items-center gap-2">
<Slider
defaultValue={[element.fontSize]}
min={8}
max={200}
step={1}
onValueChange={([value]) =>
updateTextElement(trackId, element.id, { fontSize: value })
}
className="w-full"
/>
<Input
type="number"
value={element.fontSize}
onChange={(e) =>
updateTextElement(trackId, element.id, {
fontSize: parseInt(e.target.value),
})
}
className="w-12 !text-xs h-7 rounded-sm text-center
[appearance:textfield]
[&::-webkit-outer-spin-button]:appearance-none
[&::-webkit-inner-spin-button]:appearance-none"
/>
</div>
</PropertyItemValue>
</PropertyItem>
</div> </div>
); );
} }