diff options
| author | Maze Winther <mazewinther@gmail.com> | 2025-07-10 21:48:26 +0200 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2025-07-10 21:48:26 +0200 |
| commit | fe6492f359b245a22882adf49990052d3ca6830d (patch) | |
| tree | 45b3e60a77b457e31af02de786343a5687eb4afc /apps/web/src/components/editor/properties-panel | |
| parent | ed4e9dad192cef58c7b15dea06dd9c41feb2a510 (diff) | |
| download | opencut-fe6492f359b245a22882adf49990052d3ca6830d.tar.gz | |
refactor: separate property item component
Diffstat (limited to 'apps/web/src/components/editor/properties-panel')
| -rw-r--r-- | apps/web/src/components/editor/properties-panel/property-item.tsx | 47 | ||||
| -rw-r--r-- | apps/web/src/components/editor/properties-panel/text-properties.tsx | 104 |
2 files changed, 103 insertions, 48 deletions
diff --git a/apps/web/src/components/editor/properties-panel/property-item.tsx b/apps/web/src/components/editor/properties-panel/property-item.tsx new file mode 100644 index 00000000..beb8c799 --- /dev/null +++ b/apps/web/src/components/editor/properties-panel/property-item.tsx @@ -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>;
+}
diff --git a/apps/web/src/components/editor/properties-panel/text-properties.tsx b/apps/web/src/components/editor/properties-panel/text-properties.tsx index c91e7cb8..66856d3b 100644 --- a/apps/web/src/components/editor/properties-panel/text-properties.tsx +++ b/apps/web/src/components/editor/properties-panel/text-properties.tsx @@ -1,5 +1,4 @@ import { Textarea } from "@/components/ui/textarea";
-import { Label } from "@/components/ui/label";
import {
Select,
SelectContent,
@@ -12,6 +11,11 @@ import { TextElement } from "@/types/timeline"; import { useTimelineStore } from "@/stores/timeline-store";
import { Slider } from "@/components/ui/slider";
import { Input } from "@/components/ui/input";
+import {
+ PropertyItem,
+ PropertyItemLabel,
+ PropertyItemValue,
+} from "./property-item";
export function TextProperties({
element,
@@ -32,54 +36,58 @@ export function TextProperties({ updateTextElement(trackId, element.id, { content: e.target.value })
}
/>
- <div className="flex items-center justify-between gap-6">
- <Label className="text-xs">Font</Label>
- <Select
- defaultValue={element.fontFamily}
- 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"
- />
- <Input
- type="number"
- value={element.fontSize}
- onChange={(e) =>
- updateTextElement(trackId, element.id, {
- fontSize: parseInt(e.target.value),
- })
+ <PropertyItem direction="row">
+ <PropertyItemLabel>Font</PropertyItemLabel>
+ <PropertyItemValue>
+ <Select
+ defaultValue={element.fontFamily}
+ onValueChange={(value: FontFamily) =>
+ updateTextElement(trackId, element.id, { fontFamily: 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>
- </div>
+ >
+ <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>
+ </PropertyItemValue>
+ </PropertyItem>
+ <PropertyItem direction="column">
+ <PropertyItemLabel>Font size</PropertyItemLabel>
+ <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>
);
}
|
