mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-04 07:19:52 +00:00
fix(studio): span the clip on the remaining duration-less tween paths
Two sibling call paths still answered from GSAP's 0.5s default while the toggle path had moved to the clip-wide fallback. isPlayheadWithinTween now takes the selection, so the toolbar stops promising "extends animation" on a duration-less tween whose click actually toggles an interior keyframe. The arc drag commit resolves its replacement duration the same way its click-path sibling does, instead of authoring duration 0.5 and collapsing the arc window. The flat text section drops its two marker-clearing effects: the autofocus marker is a ref now, read and cleared by the render that consumes it.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useTrackDesignInput } from "../../contexts/DesignPanelInputContext";
|
||||
import { Plus, X } from "../../icons/SystemIcons";
|
||||
import { isTextEditableSelection, type DomEditSelection } from "./domEditing";
|
||||
@@ -257,7 +257,10 @@ export function FlatTextSection({
|
||||
const [activeFieldKey, setActiveFieldKey] = useState<string | null>(
|
||||
element.textFields[0]?.key ?? null,
|
||||
);
|
||||
const [autoFocusFieldKey, setAutoFocusFieldKey] = useState<string | null>(null);
|
||||
// Armed by the add handler, read and cleared by the render that first shows
|
||||
// the new field. A ref rather than state: the marker only has to survive one
|
||||
// render, and clearing it afterwards would be a state-syncing effect.
|
||||
const autoFocusFieldKeyRef = useRef<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const nextFields = element.textFields;
|
||||
@@ -267,21 +270,14 @@ export function FlatTextSection({
|
||||
});
|
||||
}, [element.id, element.selector, element.textFields]);
|
||||
|
||||
useEffect(() => {
|
||||
setAutoFocusFieldKey(null);
|
||||
}, [element.id, element.selector]);
|
||||
|
||||
useEffect(() => {
|
||||
if (autoFocusFieldKey && autoFocusFieldKey === activeFieldKey) {
|
||||
setAutoFocusFieldKey(null);
|
||||
}
|
||||
}, [activeFieldKey, autoFocusFieldKey]);
|
||||
|
||||
if (!isTextEditableSelection(element)) return null;
|
||||
const textFields = element.textFields;
|
||||
const activeField = textFields.find((field) => field.key === activeFieldKey) ?? textFields[0];
|
||||
if (!activeField) return null;
|
||||
|
||||
const autoFocusActiveField = autoFocusFieldKeyRef.current === activeField.key;
|
||||
if (autoFocusActiveField) autoFocusFieldKeyRef.current = null;
|
||||
|
||||
if (textFields.length > 1) {
|
||||
return (
|
||||
<div className="space-y-2.5">
|
||||
@@ -290,13 +286,13 @@ export function FlatTextSection({
|
||||
activeFieldKey={activeField.key}
|
||||
styles={styles}
|
||||
onSelect={(fieldKey) => {
|
||||
setAutoFocusFieldKey(null);
|
||||
autoFocusFieldKeyRef.current = null;
|
||||
setActiveFieldKey(fieldKey);
|
||||
}}
|
||||
onAdd={() =>
|
||||
void Promise.resolve(onAddTextField(activeField.key)).then((nextKey) => {
|
||||
if (!nextKey) return;
|
||||
setAutoFocusFieldKey(nextKey);
|
||||
autoFocusFieldKeyRef.current = nextKey;
|
||||
setActiveFieldKey(nextKey);
|
||||
})
|
||||
}
|
||||
@@ -311,7 +307,7 @@ export function FlatTextSection({
|
||||
onSetText={onSetText}
|
||||
onSetTextFieldStyle={onSetTextFieldStyle}
|
||||
onPreviewTextFieldStyle={onPreviewTextFieldStyle}
|
||||
autoFocus={autoFocusFieldKey === activeField.key}
|
||||
autoFocus={autoFocusActiveField}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@@ -334,7 +330,7 @@ export function FlatTextSection({
|
||||
track("button", "Add text field");
|
||||
void Promise.resolve(onAddTextField(activeField.key)).then((nextKey) => {
|
||||
if (!nextKey) return;
|
||||
setAutoFocusFieldKey(nextKey);
|
||||
autoFocusFieldKeyRef.current = nextKey;
|
||||
setActiveFieldKey(nextKey);
|
||||
});
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user