mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-10 22:20:14 +00:00
feat(studio): add media properties panel for video/audio elements
Adds a new Media section to the Design panel that appears when a <video> or <audio> element is selected. Controls include volume (slider), playback rate, media start offset, loop/muted toggles, and for video: object-fit, object-position, poster, and has-audio-track toggle. Extends the source patcher with an "html-attribute" operation type for native HTML attributes (loop, muted, poster) that don't use the data- prefix. Adds coalesceKey to attribute commits so rapid slider/scrub edits merge into a single undo entry.
This commit is contained in:
@@ -14,6 +14,7 @@ import {
|
||||
buildDomEditStylePatchOperation,
|
||||
buildDomEditTextPatchOperation,
|
||||
findElementForSelection,
|
||||
getDomEditTargetKey,
|
||||
isTextEditableSelection,
|
||||
serializeDomEditTextFields,
|
||||
buildDefaultDomEditTextField,
|
||||
@@ -125,7 +126,8 @@ export function useDomEditTextCommits({
|
||||
const op: PatchOperation = { type: "attribute", property: attr, value };
|
||||
try {
|
||||
await persistDomEditOperations(domEditSelection, [op], {
|
||||
label: "Edit timing",
|
||||
label: `Edit ${attr.replace(/-/g, " ")}`,
|
||||
coalesceKey: `attr:${attr}:${getDomEditTargetKey(domEditSelection)}`,
|
||||
skipRefresh: false,
|
||||
});
|
||||
} catch (err) {
|
||||
@@ -145,6 +147,45 @@ export function useDomEditTextCommits({
|
||||
],
|
||||
);
|
||||
|
||||
const handleDomHtmlAttributeCommit = useCallback(
|
||||
async (attr: string, value: string | null) => {
|
||||
if (!domEditSelection) return;
|
||||
const iframe = previewIframeRef.current;
|
||||
const doc = iframe?.contentDocument;
|
||||
if (doc) {
|
||||
const el = findElementForSelection(doc, domEditSelection, activeCompPath);
|
||||
if (el) {
|
||||
if (value === null || value === "" || value === "false") {
|
||||
el.removeAttribute(attr);
|
||||
} else {
|
||||
el.setAttribute(attr, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
const op: PatchOperation = { type: "html-attribute", property: attr, value };
|
||||
try {
|
||||
await persistDomEditOperations(domEditSelection, [op], {
|
||||
label: `Edit ${attr}`,
|
||||
coalesceKey: `html-attr:${attr}:${getDomEditTargetKey(domEditSelection)}`,
|
||||
skipRefresh: false,
|
||||
});
|
||||
} catch (err) {
|
||||
console.warn(
|
||||
"[Studio] HTML attribute persist failed:",
|
||||
err instanceof Error ? err.message : err,
|
||||
);
|
||||
}
|
||||
refreshDomEditSelectionFromPreview(domEditSelection);
|
||||
},
|
||||
[
|
||||
activeCompPath,
|
||||
domEditSelection,
|
||||
persistDomEditOperations,
|
||||
refreshDomEditSelectionFromPreview,
|
||||
previewIframeRef,
|
||||
],
|
||||
);
|
||||
|
||||
const handleDomTextCommit = useCallback(
|
||||
async (value: string, fieldKey?: string) => {
|
||||
if (!domEditSelection) return;
|
||||
@@ -354,6 +395,7 @@ export function useDomEditTextCommits({
|
||||
return {
|
||||
handleDomStyleCommit,
|
||||
handleDomAttributeCommit,
|
||||
handleDomHtmlAttributeCommit,
|
||||
handleDomTextCommit,
|
||||
commitDomTextFields,
|
||||
handleDomTextFieldStyleCommit,
|
||||
|
||||
Reference in New Issue
Block a user