import { Textarea } from "@/components/ui/textarea"; import { FontPicker } from "@/components/ui/font-picker"; import type { TextElement } from "@/types/timeline"; import { NumberField } from "@/components/ui/number-field"; import { useRef } from "react"; import { Section, SectionContent, SectionField, SectionFields, SectionHeader } from "./section"; import { ColorPicker } from "@/components/ui/color-picker"; import { uppercase } from "@/utils/string"; import { clamp } from "@/utils/math"; import { useEditor } from "@/hooks/use-editor"; import { DEFAULT_COLOR } from "@/constants/project-constants"; import { DEFAULT_LETTER_SPACING, DEFAULT_LINE_HEIGHT, DEFAULT_TEXT_BACKGROUND, DEFAULT_TEXT_ELEMENT, MAX_FONT_SIZE, MIN_FONT_SIZE, } from "@/constants/text-constants"; import { usePropertyDraft } from "./hooks/use-property-draft"; import { TransformSection, BlendingSection } from "./sections"; import { HugeiconsIcon } from "@hugeicons/react"; import { TextFontIcon } from "@hugeicons/core-free-icons"; import { OcTextHeightIcon, OcTextWidthIcon } from "@opencut/ui/icons"; function createOffsetConverter({ defaultValue, scale = 1, min, }: { defaultValue: number; scale?: number; min?: number; }) { return { toDisplay: (value: number) => Math.round((value - defaultValue) * scale), fromDisplay: (display: number) => { const stored = defaultValue + display / scale; return min !== undefined ? Math.max(min, stored) : stored; }, }; } const lineHeightConverter = createOffsetConverter({ defaultValue: DEFAULT_LINE_HEIGHT, scale: 10 }); const paddingXConverter = createOffsetConverter({ defaultValue: DEFAULT_TEXT_BACKGROUND.paddingX, min: 0 }); const paddingYConverter = createOffsetConverter({ defaultValue: DEFAULT_TEXT_BACKGROUND.paddingY, min: 0 }); export function TextProperties({ element, trackId, }: { element: TextElement; trackId: string; }) { return (