summaryrefslogtreecommitdiff
path: root/apps/web/src/components/editor/panels/properties/effect-properties.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'apps/web/src/components/editor/panels/properties/effect-properties.tsx')
-rw-r--r--apps/web/src/components/editor/panels/properties/effect-properties.tsx103
1 files changed, 29 insertions, 74 deletions
diff --git a/apps/web/src/components/editor/panels/properties/effect-properties.tsx b/apps/web/src/components/editor/panels/properties/effect-properties.tsx
index bf137291..75fc30a1 100644
--- a/apps/web/src/components/editor/panels/properties/effect-properties.tsx
+++ b/apps/web/src/components/editor/panels/properties/effect-properties.tsx
@@ -1,78 +1,16 @@
"use client";
import type { EffectElement } from "@/types/timeline";
-import type { EffectParamDefinition } from "@/types/effects";
import { getEffect } from "@/lib/effects/registry";
import { useEditor } from "@/hooks/use-editor";
-import { clamp } from "@/utils/math";
-import { Section, SectionContent, SectionHeader, SectionField, SectionFields } from "./section";
-import { Slider } from "@/components/ui/slider";
-import { NumberField } from "@/components/ui/number-field";
-import { usePropertyDraft } from "./hooks/use-property-draft";
-
-function EffectParamField({
- param,
- element,
- trackId,
-}: {
- param: EffectParamDefinition;
- element: EffectElement;
- trackId: string;
-}) {
- const editor = useEditor();
-
- const currentValue = Number(element.params[param.key] ?? param.default);
- const min = param.min ?? 0;
- const max = param.max ?? 100;
- const step = param.step ?? 1;
-
- const updateParam = (value: number) =>
- editor.timeline.previewElements({
- updates: [
- {
- trackId,
- elementId: element.id,
- updates: { params: { ...element.params, [param.key]: value } },
- },
- ],
- });
-
- const commitParam = () => editor.timeline.commitPreview();
-
- const draft = usePropertyDraft({
- displayValue: String(currentValue),
- parse: (input) => {
- const parsed = parseFloat(input);
- if (Number.isNaN(parsed)) return null;
- return clamp({ value: parsed, min, max });
- },
- onPreview: updateParam,
- onCommit: commitParam,
- });
-
- return (
- <SectionField label={param.label}>
- <div className="flex items-center gap-3">
- <Slider
- className="flex-1"
- min={min}
- max={max}
- step={step}
- value={[currentValue]}
- onValueChange={([value]) => updateParam(value)}
- onValueCommit={commitParam}
- />
- <NumberField
- className="w-16 shrink-0"
- value={draft.displayValue}
- onFocus={draft.onFocus}
- onChange={draft.onChange}
- onBlur={draft.onBlur}
- />
- </div>
- </SectionField>
- );
-}
+import {
+ Section,
+ SectionContent,
+ SectionHeader,
+ SectionFields,
+ SectionTitle,
+} from "./section";
+import { EffectParamField } from "./effect-param-field";
export function EffectProperties({
element,
@@ -81,19 +19,36 @@ export function EffectProperties({
element: EffectElement;
trackId: string;
}) {
+ const editor = useEditor();
const definition = getEffect({ effectType: element.effectType });
+ const previewParam =
+ ({ key }: { key: string }) =>
+ (value: number | string | boolean) =>
+ editor.timeline.previewElements({
+ updates: [
+ {
+ trackId,
+ elementId: element.id,
+ updates: { params: { ...element.params, [key]: value } },
+ },
+ ],
+ });
+
return (
- <Section hasBorderTop={false}>
- <SectionHeader title={definition.name} />
+ <Section showTopBorder={false}>
+ <SectionHeader>
+ <SectionTitle>{definition.name}</SectionTitle>
+ </SectionHeader>
<SectionContent>
<SectionFields>
{definition.params.map((param) => (
<EffectParamField
key={param.key}
param={param}
- element={element}
- trackId={trackId}
+ value={element.params[param.key] ?? param.default}
+ onPreview={previewParam({ key: param.key })}
+ onCommit={() => editor.timeline.commitPreview()}
/>
))}
</SectionFields>