From a7579ac95a550f334d73eb71ba67fb72f3bc8fd8 Mon Sep 17 00:00:00 2001 From: EmaDev Date: Sun, 15 Feb 2026 20:13:14 +0100 Subject: [PATCH 1/5] go to props --- .../components/editor/keyframe-card.svelte | 82 +++++- .../editor/panels/input-propery.svelte | 12 +- .../editor/panels/input-wrapper.svelte | 6 +- .../editor/panels/inputs-wrapper.svelte | 6 +- .../editor/panels/properties-panel.svelte | 69 +++-- .../editor/timeline/timeline-keyframe.svelte | 11 +- src/lib/utils/property-names.ts | 244 ++++++++++++++++++ 7 files changed, 365 insertions(+), 65 deletions(-) create mode 100644 src/lib/utils/property-names.ts diff --git a/src/lib/components/editor/keyframe-card.svelte b/src/lib/components/editor/keyframe-card.svelte index fe2c85f..7fe2604 100644 --- a/src/lib/components/editor/keyframe-card.svelte +++ b/src/lib/components/editor/keyframe-card.svelte @@ -3,9 +3,16 @@ import { getEditorState } from '$lib/contexts/editor.svelte'; import { Button } from '$lib/components/ui/button'; import * as Popover from '$lib/components/ui/popover'; - import { Trash2, Palette, Move, RotateCw, Scale, Eye, Clock } from '@lucide/svelte'; + import { Trash2, Palette, Move, RotateCw, Scale, Eye, Clock, ScanSearch } from '@lucide/svelte'; import ScrubInput from './panels/scrub-input.svelte'; - + import { + getPropertyCategory, + getTransformInputId, + getStyleInputId, + isTransformProperty, + isStyleProperty, + type AnimatableProperty + } from '$lib/utils/property-names'; const editorState = $derived(getEditorState()); const projectStore = $derived(editorState.project); @@ -13,9 +20,10 @@ keyframe: Keyframe; layerId: string; readonlyTime?: boolean; + onGoToPropertyClick?: () => void; } - let { keyframe, layerId, readonlyTime = false }: Props = $props(); + let { keyframe, layerId, readonlyTime = false, onGoToPropertyClick }: Props = $props(); // Type-safe strategy labels - ensures all strategies have corresponding labels type ContinuousStrategy = Extract['strategy']; @@ -79,7 +87,6 @@ 'rotation.z': 'Rotation Z', 'scale.x': 'Scale X', 'scale.y': 'Scale Y', - 'scale.z': 'Scale Z', opacity: 'Opacity', color: 'Color' }; @@ -93,11 +100,11 @@ return property; } - function getPropertyIcon(property: string) { - if (property.startsWith('position.')) return Move; + function getPropertyIcon(property: AnimatableProperty) { + if (isTransformProperty(property)) return Move; if (property.startsWith('rotation.')) return RotateCw; if (property.startsWith('scale.')) return Scale; - if (property === 'opacity') return Eye; + if (isStyleProperty(property)) return Eye; if (property === 'color') return Palette; return Move; } @@ -170,6 +177,48 @@ } const Icon = $derived(getPropertyIcon(keyframe.property)); + + /** + * Maps keyframe property to the input ID in properties panel + * Uses unified naming convention from property-names utility + */ + function getInputIdFromProperty(property: AnimatableProperty): string { + const category = getPropertyCategory(property); + + if (category === 'transform') { + return getTransformInputId(property); + } + if (category === 'style') { + return getStyleInputId(property); + } + // For props.* properties, use the property name directly + if (property.startsWith('props.')) { + return property; + } + + // Fallback: use the property name as-is + return property; + } + + /** + * Scroll to and focus the corresponding input in the properties panel + * Uses ID attribute to find the input + */ + function handleGoToProperty() { + onGoToPropertyClick?.(); + const property = keyframe.property; + const inputId = getInputIdFromProperty(property); + + // Find input by ID + const input = document.getElementById(inputId) as HTMLElement | null; + if (input) { + input.scrollIntoView({ behavior: 'smooth', block: 'center' }); + setTimeout(() => { + (input as HTMLInputElement)?.focus?.(); + (input as HTMLInputElement)?.select?.(); + }, 500); + } + }
@@ -183,17 +232,26 @@ {getPropertyLabel(keyframe.property)} + + + /> {/snippet} diff --git a/src/lib/components/editor/panels/input-propery.svelte b/src/lib/components/editor/panels/input-propery.svelte index 1a2134b..52ba6d2 100644 --- a/src/lib/components/editor/panels/input-propery.svelte +++ b/src/lib/components/editor/panels/input-propery.svelte @@ -66,7 +66,7 @@ /> {:else if metadata.meta?.widget === 'textarea'}