hyperframes 0.8.81 → 0.8.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backgroundChecksWorker.js +890 -0
- package/dist/cli.js +4272 -2792
- package/dist/commands/layout-audit.browser.js +55 -25
- package/dist/fontLocalizeCli.js +714 -344
- package/dist/hyperframe-runtime.js +83 -58
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +83 -58
- package/dist/hyperframes-player.global.js +3 -3
- package/dist/registry/localSemantic.js +7 -3
- package/dist/renderSetupWorker.js +62 -32
- package/dist/sherpaWorker.js +179 -0
- package/dist/skills/hyperframes/SKILL.md +2 -0
- package/dist/skills/hyperframes/references/plugin-installation.md +43 -0
- package/dist/skills/hyperframes/references/skill-lifecycle.md +2 -0
- package/dist/skills/hyperframes/scripts/plugin-cli.mjs +88 -0
- package/dist/skills/hyperframes/scripts/plugin-cli.test.mjs +117 -0
- package/dist/skills/hyperframes-cli/SKILL.md +2 -0
- package/dist/skills/hyperframes-cli/references/upgrade-info-misc.md +1 -0
- package/dist/skills/media-use/SKILL.md +2 -0
- package/dist/skills/media-use/references/operations.md +7 -5
- package/dist/skills/media-use/references/setup-providers.md +9 -9
- package/dist/skills/media-use/registry/localSemantic.js +7 -3
- package/dist/skills/media-use/scripts/lib/ff-binaries.mjs +37 -0
- package/dist/skills/media-use/scripts/lib/probe.mjs +3 -1
- package/dist/skills/media-use/scripts/lib/probe.test.mjs +118 -1
- package/dist/skills/media-use/scripts/lib/tts-local-provider.mjs +5 -3
- package/dist/skills/media-use/scripts/resolve-plugin.test.mjs +62 -0
- package/dist/skills/media-use/scripts/resolve.mjs +45 -19
- package/dist/skills/media-use/scripts/transcribe.mjs +39 -25
- package/dist/skills/media-use/scripts/transcribe.test.mjs +112 -0
- package/dist/skills/registry/localSemantic.js +7 -3
- package/dist/studio/assets/{hyperframes-player-C68UawR3.js → hyperframes-player-BAerMCex.js} +1 -1
- package/dist/studio/assets/{index-CMzPGv9P.js → index-BUhcVhNy.js} +1 -1
- package/dist/studio/assets/{index-hNVM9Pd2.js → index-BYhK_KMc.js} +187 -187
- package/dist/studio/assets/{index-CS5SImRT.js → index-Iv0HI7eM.js} +1 -1
- package/dist/studio/{chunk-I7XNAIOF.js → chunk-3IOCVWB6.js} +6 -97
- package/dist/studio/chunk-3IOCVWB6.js.map +1 -0
- package/dist/studio/chunk-62DDWOSH.js +189 -0
- package/dist/studio/chunk-62DDWOSH.js.map +1 -0
- package/dist/studio/chunk-LPZMAGS7.js +1871 -0
- package/dist/studio/chunk-LPZMAGS7.js.map +1 -0
- package/dist/studio/chunk-QZ6HNNFG.js +934 -0
- package/dist/studio/chunk-QZ6HNNFG.js.map +1 -0
- package/dist/studio/chunk-S65AQH6M.js +101 -0
- package/dist/studio/chunk-S65AQH6M.js.map +1 -0
- package/dist/studio/{domEditingLayers-MHFDKAQ7.js → domEditingLayers-ZOOMN7CQ.js} +3 -2
- package/dist/studio/index.d.ts +834 -330
- package/dist/studio/index.html +1 -1
- package/dist/studio/index.js +26378 -28802
- package/dist/studio/index.js.map +1 -1
- package/dist/studio/player.d.ts +30 -0
- package/dist/studio/player.js +10 -0
- package/dist/studio/player.js.map +1 -0
- package/dist/studio/ui.d.ts +294 -0
- package/dist/studio/ui.js +66 -0
- package/dist/studio/ui.js.map +1 -0
- package/dist/templates/_shared/AGENTS.md +5 -1
- package/dist/templates/_shared/CLAUDE.md +5 -1
- package/package.json +1 -1
- package/dist/studio/chunk-I7XNAIOF.js.map +0 -1
- /package/dist/studio/{domEditingLayers-MHFDKAQ7.js.map → domEditingLayers-ZOOMN7CQ.js.map} +0 -0
package/dist/studio/index.d.ts
CHANGED
|
@@ -1,331 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
import { ButtonHTMLAttributes, ReactNode, ElementType, ComponentPropsWithoutRef, ReactElement, RefObject, MutableRefObject, DragEventHandler, ComponentProps, RefCallback, MouseEvent, CSSProperties, UIEvent, PointerEvent } from 'react';
|
|
1
|
+
export { Button, ButtonSize, ButtonVariant, ContextMenu, HyperframesLoader, HyperframesLoaderProps, HyperframesLogo, IconButton, Input, InputProps, Menu, MenuItem, MenuItemTone, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuShortcut, NumberField, NumberFieldProps, Popover, PopupPreviewState, PreviewState, Select, SelectOption, SelectProps, Slider, SliderProps, Tab, TabPanel, Tabs, TabsList, Toggle, ToggleProps, Tooltip, buttonBase, buttonSizes, buttonVariants, cn, fieldBase, fieldText, popupSurface } from './ui.js';
|
|
3
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import { ContextMenu as ContextMenu$1 } from '@base-ui/react/context-menu';
|
|
7
|
-
import { Menu as Menu$1 } from '@base-ui/react/menu';
|
|
8
|
-
import { Popover as Popover$1 } from '@base-ui/react/popover';
|
|
3
|
+
import * as react from 'react';
|
|
4
|
+
import { RefObject, MutableRefObject, ReactNode, DragEventHandler, ComponentProps, RefCallback, MouseEvent, CSSProperties, UIEvent, PointerEvent } from 'react';
|
|
9
5
|
import { RuntimeTimelineClipIdentity, HyperframePickerElementInfo } from '@hyperframes/core';
|
|
10
|
-
import { GsapAnimation, PropertyGroupName } from '@hyperframes/core/gsap-parser';
|
|
6
|
+
import { GsapAnimation, ParsedGsap, PropertyGroupName } from '@hyperframes/core/gsap-parser';
|
|
7
|
+
export { Player } from './player.js';
|
|
8
|
+
import { Composition } from '@hyperframes/sdk';
|
|
11
9
|
import { MusicBeatAnalysis } from '@hyperframes/core/beats';
|
|
12
10
|
import * as zustand from 'zustand';
|
|
13
11
|
import { StoreApi } from 'zustand';
|
|
14
12
|
import { GsapAnimation as GsapAnimation$1, ArcPathSegment } from '@hyperframes/parsers/gsap-parser';
|
|
13
|
+
import * as _hyperframes_parsers from '@hyperframes/parsers';
|
|
15
14
|
import { CanvasResolution } from '@hyperframes/parsers';
|
|
16
|
-
import { Composition } from '@hyperframes/sdk';
|
|
17
15
|
export { SeamTransitionFrameSource, SeamTransitionLoopHandle, SeamTransitionLoopOptions, playSeamTransitionLoop } from '@hyperframes/shader-transitions';
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
interface ButtonBaseProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
24
|
-
variant?: ButtonVariant;
|
|
25
|
-
size?: ButtonSize;
|
|
26
|
-
"data-preview-state"?: PreviewState;
|
|
27
|
-
}
|
|
28
|
-
interface ButtonProps extends ButtonBaseProps {
|
|
29
|
-
loading?: boolean;
|
|
30
|
-
icon?: ReactNode;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Shared by Button and IconButton. `disabled:` keeps pointer events alive so a
|
|
34
|
-
* wrapping Tooltip can still explain why the control is disabled.
|
|
35
|
-
*/
|
|
36
|
-
declare const buttonBase: string;
|
|
37
|
-
/**
|
|
38
|
-
* One entry per variant. The `data-[preview-state=…]` half of each string
|
|
39
|
-
* repeats the `hover:` and `active:` half exactly; the test pairs them.
|
|
40
|
-
*/
|
|
41
|
-
declare const buttonVariants: Record<ButtonVariant, string>;
|
|
42
|
-
/**
|
|
43
|
-
* The three control heights, 24 / 28 / 32 px, from `--spacing-ctl-*`.
|
|
44
|
-
* Exported so the Capture download `<a href>` can wear the same recipe as a Button.
|
|
45
|
-
*/
|
|
46
|
-
declare const buttonSizes: Record<ButtonSize, string>;
|
|
47
|
-
declare const Button: react.ForwardRefExoticComponent<ButtonProps & react.RefAttributes<HTMLButtonElement>>;
|
|
48
|
-
|
|
49
|
-
declare function HyperframesLogo(): react_jsx_runtime.JSX.Element;
|
|
50
|
-
|
|
51
|
-
interface IconButtonProps extends ButtonBaseProps {
|
|
52
|
-
icon: ReactNode;
|
|
53
|
-
"aria-label": string;
|
|
54
|
-
}
|
|
55
|
-
declare const IconButton: react.ForwardRefExoticComponent<IconButtonProps & react.RefAttributes<HTMLButtonElement>>;
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Base UI lets `className` be a function of the part's state. Studio's parts
|
|
59
|
-
* merge a string with `cn`, so the string form is the one they accept.
|
|
60
|
-
*/
|
|
61
|
-
type StyledProps$1<T extends ElementType> = Omit<ComponentPropsWithoutRef<T>, "className"> & {
|
|
62
|
-
className?: string;
|
|
63
|
-
};
|
|
64
|
-
/**
|
|
65
|
-
* Groups a tab list with its panels. Uncontrolled by default; pass `value` and
|
|
66
|
-
* `onValueChange` for a strip whose selection lives in a store.
|
|
67
|
-
*/
|
|
68
|
-
declare function Tabs(props: ComponentPropsWithoutRef<typeof Tabs$1.Root>): react_jsx_runtime.JSX.Element;
|
|
69
|
-
/** The strip. Give it an `aria-label`: a tablist with no name is unlabelled. */
|
|
70
|
-
declare function TabsList({ className, ...props }: StyledProps$1<typeof Tabs$1.List>): react_jsx_runtime.JSX.Element;
|
|
71
|
-
interface TabProps extends StyledProps$1<typeof Tabs$1.Tab> {
|
|
72
|
-
value: string;
|
|
73
|
-
"data-preview-state"?: PreviewState;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* aria-selected drives the selected look (Base UI sets it) so assistive tech
|
|
77
|
-
* and sighted users match. data-preview-state is for gallery shots only.
|
|
78
|
-
*/
|
|
79
|
-
declare function Tab({ value, className, ...props }: TabProps): react_jsx_runtime.JSX.Element;
|
|
80
|
-
/** The panel for one tab. Base UI wires `aria-labelledby` back to its tab. */
|
|
81
|
-
declare function TabPanel({ className, ...props }: StyledProps$1<typeof Tabs$1.Panel>): react_jsx_runtime.JSX.Element;
|
|
82
|
-
|
|
83
|
-
interface HyperframesLoaderProps {
|
|
84
|
-
/** Status text shown below the mark. */
|
|
85
|
-
title: string;
|
|
86
|
-
/** Optional secondary detail line. */
|
|
87
|
-
detail?: string;
|
|
88
|
-
/** Optional monospace third line for IDs, counts, or percentages. */
|
|
89
|
-
mono?: string;
|
|
90
|
-
/** Pixel size of the mark itself; status text scales independently. */
|
|
91
|
-
size?: number;
|
|
92
|
-
/** Optional normalized progress value from 0 to 1. */
|
|
93
|
-
progress?: number;
|
|
94
|
-
}
|
|
95
|
-
declare function HyperframesLoader({ title, detail, mono, size, progress, }: HyperframesLoaderProps): react_jsx_runtime.JSX.Element;
|
|
96
|
-
|
|
97
|
-
interface TooltipProps {
|
|
98
|
-
label: string;
|
|
99
|
-
/** A single element, wrapped in a box-less span so a disabled one still gets hover. */
|
|
100
|
-
children: ReactElement<{
|
|
101
|
-
"aria-describedby"?: string;
|
|
102
|
-
}>;
|
|
103
|
-
/** Hover delay in ms. */
|
|
104
|
-
delay?: number;
|
|
105
|
-
side?: "top" | "bottom" | "left" | "right";
|
|
106
|
-
}
|
|
107
|
-
declare function Tooltip({ label, children, delay, side }: TooltipProps): react_jsx_runtime.JSX.Element;
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Studio's tailwind-merge config: teaches it the two scales `theme.css`
|
|
111
|
-
* invents (`text-step-*`, `ctl`/`ctl-sm`/`ctl-lg`) so overrides replace, not stack.
|
|
112
|
-
*/
|
|
113
|
-
declare const cn: node_modules_cn_dist_types.CnFunction;
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Base UI lets `className` be a function of the part's state. Studio's parts
|
|
117
|
-
* merge a string with `cn`, so the string form is the one they accept.
|
|
118
|
-
*/
|
|
119
|
-
type StyledProps<T extends ElementType> = Omit<ComponentPropsWithoutRef<T>, "className"> & {
|
|
120
|
-
className?: string;
|
|
121
|
-
};
|
|
122
|
-
/** Forces the settled open look for a gallery shot; CSS-only, open state stays controlled. */
|
|
123
|
-
type PopupPreviewState = "open";
|
|
124
|
-
/** Where the portal puts the popup. `null` keeps it inline, next to its trigger. */
|
|
125
|
-
type PortalContainer$1 = ComponentPropsWithoutRef<typeof Menu$1.Portal>["container"];
|
|
126
|
-
/**
|
|
127
|
-
* Chrome shared by every floating panel (`Popover` too); callers add their own shadow token.
|
|
128
|
-
*/
|
|
129
|
-
declare const popupSurface: string;
|
|
130
|
-
type MenuItemTone = "default" | "danger";
|
|
131
|
-
interface PositionedProps {
|
|
132
|
-
side?: "top" | "bottom" | "left" | "right";
|
|
133
|
-
align?: "start" | "center" | "end";
|
|
134
|
-
sideOffset?: number;
|
|
135
|
-
/** Portal target. Pass the shadow root when the trigger lives in one. */
|
|
136
|
-
container?: PortalContainer$1;
|
|
137
|
-
/** Names the popup for assistive tech. A menu with no name is unlabelled. */
|
|
138
|
-
"aria-label"?: string;
|
|
139
|
-
className?: string;
|
|
140
|
-
"data-preview-state"?: PopupPreviewState;
|
|
141
|
-
}
|
|
142
|
-
interface MenuProps extends PositionedProps, Omit<ComponentPropsWithoutRef<typeof Menu$1.Root>, "children"> {
|
|
143
|
-
/** A single element. It becomes the trigger; no wrapper is added around it. */
|
|
144
|
-
trigger: ReactElement;
|
|
145
|
-
/** The items: `MenuItem`, `MenuRadioGroup`, `MenuSeparator`. */
|
|
146
|
-
children: ReactNode;
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* A menu opened by its trigger. Uncontrolled by default; pass `open` and
|
|
150
|
-
* `onOpenChange` for a menu whose state lives in a store.
|
|
151
|
-
*/
|
|
152
|
-
declare function Menu({ trigger, children, side, align, sideOffset, container, className, "aria-label": ariaLabel, "data-preview-state": previewState, ...root }: MenuProps): react_jsx_runtime.JSX.Element;
|
|
153
|
-
interface ContextMenuProps extends PositionedProps, Omit<ComponentPropsWithoutRef<typeof ContextMenu$1.Root>, "children"> {
|
|
154
|
-
/**
|
|
155
|
-
* The right-clickable area, as the caller's own element. Its children are
|
|
156
|
-
* kept: the trigger renders that element rather than wrapping it.
|
|
157
|
-
*/
|
|
158
|
-
trigger: ReactElement;
|
|
159
|
-
children: ReactNode;
|
|
160
|
-
}
|
|
161
|
-
/** Opened by right click or long press at the pointer, so `side` and `align` are not offered. */
|
|
162
|
-
declare function ContextMenu({ trigger, children, container, className, "aria-label": ariaLabel, "data-preview-state": previewState, ...root }: Omit<ContextMenuProps, "side" | "align" | "sideOffset">): react_jsx_runtime.JSX.Element;
|
|
163
|
-
/** Keyboard shortcut hint, mono and tabular; exported for hints that are not a plain string. */
|
|
164
|
-
declare function MenuShortcut({ className, ...props }: StyledProps<"span">): react_jsx_runtime.JSX.Element;
|
|
165
|
-
interface MenuItemProps extends StyledProps<typeof Menu$1.Item> {
|
|
166
|
-
/** Rendered as a dim mono hint on the trailing edge. Decorative. */
|
|
167
|
-
shortcut?: string;
|
|
168
|
-
/** `danger` for a destructive action (Delete, Remove). */
|
|
169
|
-
tone?: MenuItemTone;
|
|
170
|
-
"data-preview-state"?: "hover";
|
|
171
|
-
}
|
|
172
|
-
/** One action. `disabled` items are skipped by the arrow keys, not just dimmed. */
|
|
173
|
-
declare function MenuItem({ shortcut, tone, className, children, ...props }: MenuItemProps): react_jsx_runtime.JSX.Element;
|
|
174
|
-
/** Single-choice group; selection is `aria-checked` on each item, which the dot indicator draws from. */
|
|
175
|
-
declare function MenuRadioGroup(props: ComponentPropsWithoutRef<typeof Menu$1.RadioGroup>): react_jsx_runtime.JSX.Element;
|
|
176
|
-
interface MenuRadioItemProps extends StyledProps<typeof Menu$1.RadioItem> {
|
|
177
|
-
"data-preview-state"?: "hover";
|
|
178
|
-
}
|
|
179
|
-
/** One choice in a `MenuRadioGroup`. The dot renders only while it is checked. */
|
|
180
|
-
declare function MenuRadioItem({ className, children, ...props }: MenuRadioItemProps): react_jsx_runtime.JSX.Element;
|
|
181
|
-
/** A hairline between two groups of items. */
|
|
182
|
-
declare function MenuSeparator({ className, ...props }: StyledProps<typeof Menu$1.Separator>): react_jsx_runtime.JSX.Element;
|
|
183
|
-
|
|
184
|
-
type PortalContainer = ComponentPropsWithoutRef<typeof Popover$1.Portal>["container"];
|
|
185
|
-
interface PopoverProps extends Omit<ComponentPropsWithoutRef<typeof Popover$1.Root>, "children"> {
|
|
186
|
-
/** A single element. It becomes the trigger; no wrapper is added around it. */
|
|
187
|
-
trigger: ReactElement;
|
|
188
|
-
/** Arbitrary content. The popover owns none of its keys. */
|
|
189
|
-
children: ReactNode;
|
|
190
|
-
side?: "top" | "bottom" | "left" | "right";
|
|
191
|
-
align?: "start" | "center" | "end";
|
|
192
|
-
sideOffset?: number;
|
|
193
|
-
/** Portal target. Pass the shadow root when the trigger lives in one. */
|
|
194
|
-
container?: PortalContainer;
|
|
195
|
-
/** Names the popup for assistive tech. */
|
|
196
|
-
"aria-label"?: string;
|
|
197
|
-
/**
|
|
198
|
-
* What to focus on open. Defaults to Base UI's behaviour (the first tabbable
|
|
199
|
-
* element), which is what a rename field wants.
|
|
200
|
-
*/
|
|
201
|
-
initialFocus?: ComponentPropsWithoutRef<typeof Popover$1.Popup>["initialFocus"];
|
|
202
|
-
className?: string;
|
|
203
|
-
"data-preview-state"?: PopupPreviewState;
|
|
204
|
-
}
|
|
205
|
-
declare function Popover({ trigger, children, side, align, sideOffset, container, className, initialFocus, "aria-label": ariaLabel, "data-preview-state": previewState, ...root }: PopoverProps): react_jsx_runtime.JSX.Element;
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Shared field look (also used by NumberField and Select). Each interactive state is written
|
|
209
|
-
* twice, real and `data-[preview-state=...]`; `valueControls.test.tsx` asserts the lists match.
|
|
210
|
-
*/
|
|
211
|
-
declare const fieldBase: string;
|
|
212
|
-
/** The text itself, inside the box. The box owns the border and the ring. */
|
|
213
|
-
declare const fieldText: string;
|
|
214
|
-
interface InputProps extends Omit<ComponentPropsWithoutRef<"input">, "value" | "onChange" | "className"> {
|
|
215
|
-
/** The committed value. A draft lives inside until Enter or blur. */
|
|
216
|
-
value: string;
|
|
217
|
-
/** Called with the draft on Enter and on blur, only when it really changed. */
|
|
218
|
-
onCommit: (next: string) => void;
|
|
219
|
-
/** Called once per committed change, for design-input telemetry. */
|
|
220
|
-
onTrack?: () => void;
|
|
221
|
-
/** Marks the field invalid: red boundary and `aria-invalid`. */
|
|
222
|
-
invalid?: boolean;
|
|
223
|
-
className?: string;
|
|
224
|
-
"data-preview-state"?: PreviewState;
|
|
225
|
-
}
|
|
226
|
-
declare function Input({ value, onCommit, onTrack, invalid, disabled, className, "data-preview-state": previewState, ...props }: InputProps): react_jsx_runtime.JSX.Element;
|
|
227
|
-
|
|
228
|
-
interface NumberFieldProps {
|
|
229
|
-
/** Accessible name. The inspector's row label is the usual one. */
|
|
230
|
-
label: string;
|
|
231
|
-
/** The committed value. */
|
|
232
|
-
value: number;
|
|
233
|
-
/** Called when a commit boundary produces a value different from `value`. */
|
|
234
|
-
onCommit: (next: number) => void;
|
|
235
|
-
/** Called once per committed change, for design-input telemetry. */
|
|
236
|
-
onTrack?: () => void;
|
|
237
|
-
/** Rendered beside the number: "px", "%", "deg". Never part of the text. */
|
|
238
|
-
unit?: string;
|
|
239
|
-
min?: number;
|
|
240
|
-
max?: number;
|
|
241
|
-
step?: number;
|
|
242
|
-
disabled?: boolean;
|
|
243
|
-
className?: string;
|
|
244
|
-
"data-preview-state"?: PreviewState;
|
|
245
|
-
}
|
|
246
|
-
declare function NumberField({ label, value, onCommit, onTrack, unit, min, max, step, disabled, className, "data-preview-state": previewState, }: NumberFieldProps): react_jsx_runtime.JSX.Element;
|
|
247
|
-
|
|
248
|
-
interface SelectOption {
|
|
249
|
-
label: string;
|
|
250
|
-
value: string;
|
|
251
|
-
/** Offered but not choosable; the label stays visible so the reason stays visible too. */
|
|
252
|
-
disabled?: boolean;
|
|
253
|
-
}
|
|
254
|
-
interface SelectProps {
|
|
255
|
-
/** Accessible name for the trigger. */
|
|
256
|
-
label: string;
|
|
257
|
-
value: string;
|
|
258
|
-
options: SelectOption[];
|
|
259
|
-
/** Called when a different option is chosen. */
|
|
260
|
-
onCommit: (next: string) => void;
|
|
261
|
-
/** Called once per committed change, for design-input telemetry. */
|
|
262
|
-
onTrack?: () => void;
|
|
263
|
-
disabled?: boolean;
|
|
264
|
-
className?: string;
|
|
265
|
-
"data-preview-state"?: PreviewState;
|
|
266
|
-
}
|
|
267
|
-
declare function Select({ label, value, options, onCommit, onTrack, disabled, className, "data-preview-state": previewState, }: SelectProps): react_jsx_runtime.JSX.Element;
|
|
268
|
-
|
|
269
|
-
interface SliderProps {
|
|
270
|
-
/** Accessible name for the thumb. The inspector's row label is the usual one. */
|
|
271
|
-
label: string;
|
|
272
|
-
/** The committed value. */
|
|
273
|
-
value: number;
|
|
274
|
-
min: number;
|
|
275
|
-
max: number;
|
|
276
|
-
step?: number;
|
|
277
|
-
/** Every intermediate value while dragging or stepping. Not a commit. */
|
|
278
|
-
onPreview?: (next: number) => void;
|
|
279
|
-
/** Called at a commit boundary when the value really changed. */
|
|
280
|
-
onCommit: (next: number) => void;
|
|
281
|
-
/** Called once per commit boundary, for design-input telemetry. */
|
|
282
|
-
onTrack?: () => void;
|
|
283
|
-
disabled?: boolean;
|
|
284
|
-
className?: string;
|
|
285
|
-
"data-preview-state"?: PreviewState;
|
|
286
|
-
}
|
|
287
|
-
declare function Slider({ label, value, min, max, step, onPreview, onCommit, onTrack, disabled, className, "data-preview-state": previewState, }: SliderProps): react_jsx_runtime.JSX.Element;
|
|
288
|
-
|
|
289
|
-
interface ToggleProps {
|
|
290
|
-
/** Accessible name. */
|
|
291
|
-
label: string;
|
|
292
|
-
checked: boolean;
|
|
293
|
-
/** Called on every flip. */
|
|
294
|
-
onCommit: (next: boolean) => void;
|
|
295
|
-
/** Called once per flip, for design-input telemetry. */
|
|
296
|
-
onTrack?: () => void;
|
|
297
|
-
disabled?: boolean;
|
|
298
|
-
className?: string;
|
|
299
|
-
"data-preview-state"?: PreviewState;
|
|
300
|
-
}
|
|
301
|
-
declare function Toggle({ label, checked, onCommit, onTrack, disabled, className, "data-preview-state": previewState, }: ToggleProps): react_jsx_runtime.JSX.Element;
|
|
302
|
-
|
|
303
|
-
interface PlayerProps {
|
|
304
|
-
projectId?: string;
|
|
305
|
-
directUrl?: string;
|
|
306
|
-
onLoad: () => void;
|
|
307
|
-
/** Fires once the loaded document is painted and every loader (shader, assets) has cleared. */
|
|
308
|
-
onReadyToShowChange?: (ready: boolean) => void;
|
|
309
|
-
onPreviewError?: (message: string) => void;
|
|
310
|
-
onCompositionLoadingChange?: (loading: boolean) => void;
|
|
311
|
-
onPainted?: (details: {
|
|
312
|
-
iframe: HTMLIFrameElement;
|
|
313
|
-
startedAt: number;
|
|
314
|
-
loadId: number;
|
|
315
|
-
}) => void;
|
|
316
|
-
portrait?: boolean;
|
|
317
|
-
style?: React.CSSProperties;
|
|
318
|
-
suppressLoadingOverlay?: boolean;
|
|
319
|
-
}
|
|
320
|
-
/**
|
|
321
|
-
* Renders a composition preview using the <hyperframes-player> web component.
|
|
322
|
-
*
|
|
323
|
-
* The web component handles iframe scaling, dimension detection, and
|
|
324
|
-
* ResizeObserver internally. This wrapper bridges its inner iframe to the
|
|
325
|
-
* forwarded ref so useTimelinePlayer can access it for clip manifest parsing,
|
|
326
|
-
* timeline probing, and DOM inspection.
|
|
327
|
-
*/
|
|
328
|
-
declare const Player: react.ForwardRefExoticComponent<PlayerProps & react.RefAttributes<HTMLIFrameElement>>;
|
|
16
|
+
import '@base-ui/react/tabs';
|
|
17
|
+
import 'node_modules/cn/dist/types';
|
|
18
|
+
import '@base-ui/react/context-menu';
|
|
19
|
+
import '@base-ui/react/menu';
|
|
20
|
+
import '@base-ui/react/popover';
|
|
329
21
|
|
|
330
22
|
interface ShortcutHint {
|
|
331
23
|
key: string;
|
|
@@ -654,8 +346,9 @@ interface TimelineElement {
|
|
|
654
346
|
playbackRate?: number;
|
|
655
347
|
sourceDuration?: number;
|
|
656
348
|
volume?: number;
|
|
657
|
-
/** `data-has-audio
|
|
349
|
+
/** A video with sound to mix (`data-has-audio`, or unmuted without it); `muted` silences it. */
|
|
658
350
|
hasAudio?: boolean;
|
|
351
|
+
muted?: boolean;
|
|
659
352
|
/** Clip-edge fades from `data-fade-in` / `data-fade-out`, seconds; absent means none. */
|
|
660
353
|
fadeIn?: number;
|
|
661
354
|
fadeOut?: number;
|
|
@@ -1080,6 +773,12 @@ interface TimelineRangeSelection {
|
|
|
1080
773
|
anchorY: number;
|
|
1081
774
|
}
|
|
1082
775
|
|
|
776
|
+
/** Durable evidence returned by the one Studio DOM persistence actor. */
|
|
777
|
+
interface DomEditPersistOutcome {
|
|
778
|
+
sourceFile: string;
|
|
779
|
+
version: string;
|
|
780
|
+
changed: boolean;
|
|
781
|
+
}
|
|
1083
782
|
/**
|
|
1084
783
|
* Durability report for a patch-batches commit. `durable === false` means the
|
|
1085
784
|
* server could not locate at least one patch target on disk — the preview was
|
|
@@ -1094,7 +793,7 @@ interface DomEditPatchBatchesResult {
|
|
|
1094
793
|
changed: boolean;
|
|
1095
794
|
}
|
|
1096
795
|
|
|
1097
|
-
interface RecordEditInput$
|
|
796
|
+
interface RecordEditInput$4 {
|
|
1098
797
|
label: string;
|
|
1099
798
|
coalesceKey?: string;
|
|
1100
799
|
files: Record<string, {
|
|
@@ -1118,7 +817,7 @@ interface UseTimelineEditingOptions {
|
|
|
1118
817
|
showToast: (message: string, tone?: "error" | "info") => void;
|
|
1119
818
|
writeProjectFile: (path: string, content: string, expectedContent?: string) => Promise<void>;
|
|
1120
819
|
observeProjectFileVersion?: (path: string, version: string | null) => void;
|
|
1121
|
-
recordEdit: (input: RecordEditInput$
|
|
820
|
+
recordEdit: (input: RecordEditInput$4) => Promise<void>;
|
|
1122
821
|
reloadPreview: () => void;
|
|
1123
822
|
previewIframeRef: RefObject<HTMLIFrameElement | null>;
|
|
1124
823
|
pendingTimelineEditPathRef: MutableRefObject<Set<string>>;
|
|
@@ -1142,6 +841,101 @@ type TimelineMoveUpdates = Pick<TimelineElement, "start" | "track"> & {
|
|
|
1142
841
|
stackingReorder?: TimelineStackingReorderIntent | null;
|
|
1143
842
|
};
|
|
1144
843
|
|
|
844
|
+
/** Value-only channels a `tl.set(...)` patch may touch. */
|
|
845
|
+
interface SetPatchProps {
|
|
846
|
+
x?: number;
|
|
847
|
+
y?: number;
|
|
848
|
+
rotation?: number;
|
|
849
|
+
rotationX?: number;
|
|
850
|
+
rotationY?: number;
|
|
851
|
+
rotationZ?: number;
|
|
852
|
+
z?: number;
|
|
853
|
+
transformPerspective?: number;
|
|
854
|
+
scaleX?: number;
|
|
855
|
+
scaleY?: number;
|
|
856
|
+
scale?: number;
|
|
857
|
+
opacity?: number;
|
|
858
|
+
}
|
|
859
|
+
/** A single keyframe step's numeric channels (the GSAP array-keyframe form). */
|
|
860
|
+
type KeyframeStep = Record<string, number>;
|
|
861
|
+
type RuntimeTweenChange = {
|
|
862
|
+
kind: "set";
|
|
863
|
+
props: SetPatchProps;
|
|
864
|
+
} | {
|
|
865
|
+
kind: "keyframes";
|
|
866
|
+
keyframes: KeyframeStep[];
|
|
867
|
+
} | {
|
|
868
|
+
kind: "keyframe-rebuild";
|
|
869
|
+
pct: number;
|
|
870
|
+
props: KeyframeStep;
|
|
871
|
+
} | {
|
|
872
|
+
kind: "global-set";
|
|
873
|
+
props: SetPatchProps;
|
|
874
|
+
};
|
|
875
|
+
|
|
876
|
+
interface MutationResult {
|
|
877
|
+
ok: boolean;
|
|
878
|
+
changed?: boolean;
|
|
879
|
+
parsed?: ParsedGsap;
|
|
880
|
+
before?: string;
|
|
881
|
+
after?: string;
|
|
882
|
+
scriptText?: string;
|
|
883
|
+
}
|
|
884
|
+
interface CommitMutationOptions {
|
|
885
|
+
label: string;
|
|
886
|
+
/** Observe the durable writer result without duplicating the request path. */
|
|
887
|
+
onResult?: (result: MutationResult) => void;
|
|
888
|
+
coalesceKey?: string;
|
|
889
|
+
coalesceMs?: number;
|
|
890
|
+
softReload?: boolean;
|
|
891
|
+
skipReload?: boolean;
|
|
892
|
+
/**
|
|
893
|
+
* Write the source but leave the preview alone; the caller renders once when it
|
|
894
|
+
* is done. For a multi-write action like a group drag, rendering after each
|
|
895
|
+
* write shows a source where the members not yet written still hold their old
|
|
896
|
+
* values, so they snap back until their own write lands. This also defers the
|
|
897
|
+
* in-place runtime patch's seek, which re-renders the whole timeline and repaints
|
|
898
|
+
* the queued members the same way. Unlike `skipReload` this changes nothing about
|
|
899
|
+
* error handling — a failed write still throws.
|
|
900
|
+
*/
|
|
901
|
+
deferPreviewSync?: boolean;
|
|
902
|
+
/** Shares an in-place patch miss with the final render of one multi-write action. */
|
|
903
|
+
previewFallbackLatch?: {
|
|
904
|
+
pending: boolean;
|
|
905
|
+
};
|
|
906
|
+
beforeReload?: () => void;
|
|
907
|
+
/**
|
|
908
|
+
* Serialize this commit against others sharing the same key. Used to chain
|
|
909
|
+
* per-animationId GSAP meta updates. Every commit independently takes the
|
|
910
|
+
* project/file mutation lock, so this key only adds ordering and can never
|
|
911
|
+
* bypass whole-file serialization.
|
|
912
|
+
*/
|
|
913
|
+
serializeKey?: string;
|
|
914
|
+
/**
|
|
915
|
+
* Value-only edit fast path. When present, `runCommit` first tries to patch the
|
|
916
|
+
* one changed tween in the preview's runtime timeline in place
|
|
917
|
+
* (`patchRuntimeTweenInPlace`) — instant, no composition re-run, no iframe
|
|
918
|
+
* remount. On a successful patch the reload is skipped entirely (panels still
|
|
919
|
+
* refresh); when the patch can't be confidently applied it falls back to the
|
|
920
|
+
* existing soft/full reload path. Structural edits omit this and reload as before.
|
|
921
|
+
*/
|
|
922
|
+
instantPatch?: {
|
|
923
|
+
selector: string;
|
|
924
|
+
change: RuntimeTweenChange;
|
|
925
|
+
};
|
|
926
|
+
/**
|
|
927
|
+
* The same fast path for a batched commit: one patch per element the batch
|
|
928
|
+
* wrote, applied in order. All of them must land for the reload to be skipped
|
|
929
|
+
* — one that can't be applied leaves the preview half-patched, so the whole
|
|
930
|
+
* batch falls back to the reload. Only the last patch re-renders (see
|
|
931
|
+
* `deferSeek`), so a ten-element batch repaints once.
|
|
932
|
+
*/
|
|
933
|
+
instantPatches?: Array<{
|
|
934
|
+
selector: string;
|
|
935
|
+
change: RuntimeTweenChange;
|
|
936
|
+
}>;
|
|
937
|
+
}
|
|
938
|
+
|
|
1145
939
|
interface TimelineGroupMoveChange {
|
|
1146
940
|
element: TimelineElement;
|
|
1147
941
|
start: number;
|
|
@@ -1310,18 +1104,24 @@ interface TimelineTheme {
|
|
|
1310
1104
|
|
|
1311
1105
|
type TimelineEditOverrides = Pick<TimelineEditCallbacks, "onMoveElement" | "onMoveElements" | "onResizeElement" | "onResizeElements" | "onBlockedEditAttempt" | "onSplitElement">;
|
|
1312
1106
|
|
|
1107
|
+
/** With both set, a lane move restacks the preview's z-index to match the rows; each overrides Studio's own. */
|
|
1108
|
+
interface TimelineStackingSyncProps {
|
|
1109
|
+
previewIframeRef?: RefObject<HTMLIFrameElement | null>;
|
|
1110
|
+
onZIndexReorder?: TimelineZIndexReorderCommit;
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1313
1113
|
interface TimelineClipRenderContext {
|
|
1314
1114
|
priority: "overscan" | "visible" | "interaction";
|
|
1315
1115
|
rich: boolean;
|
|
1316
1116
|
}
|
|
1317
|
-
interface TimelineProps extends TimelineDropCallbacks, TimelineEditOverrides {
|
|
1117
|
+
interface TimelineProps extends TimelineDropCallbacks, TimelineEditOverrides, TimelineStackingSyncProps {
|
|
1318
1118
|
/** Project-scoped reset boundary; soft source refreshes retain the same epoch. */
|
|
1319
1119
|
sessionEpoch?: number;
|
|
1320
|
-
/** keepPlaying: true preserves the current play state across the seek. */
|
|
1321
1120
|
onSeek?: (time: number, options?: {
|
|
1322
1121
|
keepPlaying?: boolean;
|
|
1323
1122
|
}) => void;
|
|
1324
1123
|
onDrillDown?: (element: TimelineElement) => void;
|
|
1124
|
+
/** Picture only: takes no pointer input. Interactive content goes in renderClipOverlay. */
|
|
1325
1125
|
renderClipContent?: (element: TimelineElement, style: {
|
|
1326
1126
|
clip: string;
|
|
1327
1127
|
label: string;
|
|
@@ -1347,7 +1147,7 @@ interface TimelineEmptyStateProps {
|
|
|
1347
1147
|
}
|
|
1348
1148
|
declare function TimelineEmptyState({ isDragOver, onFileDrop, onDragOver, onDragLeave, onDrop, }: TimelineEmptyStateProps): react_jsx_runtime.JSX.Element;
|
|
1349
1149
|
|
|
1350
|
-
interface Rect {
|
|
1150
|
+
interface Rect$1 {
|
|
1351
1151
|
left: number;
|
|
1352
1152
|
top: number;
|
|
1353
1153
|
width: number;
|
|
@@ -1694,7 +1494,7 @@ type TimelineCanvasState = Omit<TimelineLaneBaseProps, "setRangeSelection" | "se
|
|
|
1694
1494
|
effectiveDuration: number;
|
|
1695
1495
|
majorTickInterval: number;
|
|
1696
1496
|
rangeSelection: TimelineRangeSelection | null;
|
|
1697
|
-
marqueeRect: Rect | null;
|
|
1497
|
+
marqueeRect: Rect$1 | null;
|
|
1698
1498
|
resizingClip: ResizingClipState | null;
|
|
1699
1499
|
isScrubbing: boolean;
|
|
1700
1500
|
playheadRef: React.RefObject<HTMLDivElement | null>;
|
|
@@ -2448,6 +2248,7 @@ interface StudioAppProps {
|
|
|
2448
2248
|
}
|
|
2449
2249
|
declare function StudioApp({ readOnlyPreview, readOnlyPreviewReason }?: StudioAppProps): react_jsx_runtime.JSX.Element;
|
|
2450
2250
|
|
|
2251
|
+
type RightPanelTab = "layers" | "design" | "renders" | "block-params" | "slideshow" | "variables";
|
|
2451
2252
|
interface AgentModalAnchorPoint {
|
|
2452
2253
|
x: number;
|
|
2453
2254
|
y: number;
|
|
@@ -2648,7 +2449,7 @@ declare function findElementBlock(html: string, elementId: string): {
|
|
|
2648
2449
|
isSelfClosing: boolean;
|
|
2649
2450
|
} | null;
|
|
2650
2451
|
|
|
2651
|
-
interface RecordEditInput {
|
|
2452
|
+
interface RecordEditInput$3 {
|
|
2652
2453
|
label: string;
|
|
2653
2454
|
coalesceKey?: string;
|
|
2654
2455
|
coalesceMs?: number;
|
|
@@ -2694,7 +2495,7 @@ declare function usePersistentEditHistory({ projectId }: UsePersistentEditHistor
|
|
|
2694
2495
|
createdAt: number;
|
|
2695
2496
|
}[];
|
|
2696
2497
|
};
|
|
2697
|
-
recordEdit: ({ label, coalesceKey, coalesceMs, files }: RecordEditInput) => Promise<void>;
|
|
2498
|
+
recordEdit: ({ label, coalesceKey, coalesceMs, files }: RecordEditInput$3) => Promise<void>;
|
|
2698
2499
|
undo: (callbacks: ApplyCallbacks) => Promise<ApplyResult>;
|
|
2699
2500
|
redo: (callbacks: ApplyCallbacks) => Promise<ApplyResult>;
|
|
2700
2501
|
};
|
|
@@ -2890,4 +2691,707 @@ declare function TimelineEditProvider({ value, children, }: {
|
|
|
2890
2691
|
children: ReactNode;
|
|
2891
2692
|
}): react_jsx_runtime.JSX.Element;
|
|
2892
2693
|
|
|
2893
|
-
|
|
2694
|
+
interface EnableKeyframesSession {
|
|
2695
|
+
domEditSelection: DomEditSelection | null;
|
|
2696
|
+
selectedGsapAnimations: GsapAnimation[];
|
|
2697
|
+
previewIframeRef?: React.RefObject<HTMLIFrameElement | null>;
|
|
2698
|
+
handleGsapAddAnimation: (method: "to" | "from" | "set" | "fromTo") => void;
|
|
2699
|
+
handleGsapConvertToKeyframes: (animId: string, resolvedFromValues?: Record<string, number | string>, duration?: number, commitOverrides?: Partial<CommitMutationOptions>) => void | Promise<void>;
|
|
2700
|
+
handleGsapRemoveKeyframe: (animId: string, pct: number) => void;
|
|
2701
|
+
handleGsapAddKeyframeBatch?: (animId: string, pct: number, properties: Record<string, number | string>, commitOverrides?: Partial<CommitMutationOptions>) => Promise<void>;
|
|
2702
|
+
commitMutation?: (mutation: Record<string, unknown>, options: CommitMutationOptions) => Promise<void>;
|
|
2703
|
+
}
|
|
2704
|
+
|
|
2705
|
+
interface TimelineHistoryButtonsProps {
|
|
2706
|
+
canUndo?: boolean;
|
|
2707
|
+
canRedo?: boolean;
|
|
2708
|
+
undoLabel?: string;
|
|
2709
|
+
redoLabel?: string;
|
|
2710
|
+
onUndo?: () => Promise<void> | void;
|
|
2711
|
+
onRedo?: () => Promise<void> | void;
|
|
2712
|
+
}
|
|
2713
|
+
/** Undo and Redo: a host's props win, else the shell's edit history. */
|
|
2714
|
+
declare function TimelineHistoryButtons(props: TimelineHistoryButtonsProps): react_jsx_runtime.JSX.Element;
|
|
2715
|
+
|
|
2716
|
+
interface DomEditSessionSlice extends EnableKeyframesSession {
|
|
2717
|
+
domEditSelection: DomEditSelection | null;
|
|
2718
|
+
selectedGsapAnimations: GsapAnimation[];
|
|
2719
|
+
}
|
|
2720
|
+
interface TimelineToolbarProps {
|
|
2721
|
+
domEditSession?: DomEditSessionSlice;
|
|
2722
|
+
onSplitElement?: (element: TimelineElement, splitTime: number) => void;
|
|
2723
|
+
history?: TimelineHistoryButtonsProps;
|
|
2724
|
+
showAddBeat?: boolean;
|
|
2725
|
+
}
|
|
2726
|
+
declare function TimelineToolbar({ domEditSession, onSplitElement, history, showAddBeat, }: TimelineToolbarProps): react_jsx_runtime.JSX.Element;
|
|
2727
|
+
|
|
2728
|
+
interface AudioMeterStripProps {
|
|
2729
|
+
/** Pass a stable ref (useRef): a new object each render restarts the meter loop. */
|
|
2730
|
+
previewIframeRef?: RefObject<HTMLIFrameElement | null>;
|
|
2731
|
+
}
|
|
2732
|
+
declare const AudioMeterStrip: react.NamedExoticComponent<AudioMeterStripProps>;
|
|
2733
|
+
|
|
2734
|
+
interface RecordEditInput$2 {
|
|
2735
|
+
label: string;
|
|
2736
|
+
coalesceKey?: string;
|
|
2737
|
+
files: Record<string, {
|
|
2738
|
+
before: string;
|
|
2739
|
+
after: string;
|
|
2740
|
+
}>;
|
|
2741
|
+
}
|
|
2742
|
+
interface UseClipboardOptions {
|
|
2743
|
+
projectId: string | null;
|
|
2744
|
+
activeCompPath: string | null;
|
|
2745
|
+
domEditSelectionRef: React.MutableRefObject<DomEditSelection | null>;
|
|
2746
|
+
showToast: (message: string, tone?: "error" | "info") => void;
|
|
2747
|
+
writeProjectFile: (path: string, content: string) => Promise<void>;
|
|
2748
|
+
recordEdit: (input: RecordEditInput$2) => Promise<void>;
|
|
2749
|
+
reloadPreview: () => void;
|
|
2750
|
+
handleTimelineElementsDelete: (elements: TimelineElement[]) => Promise<void>;
|
|
2751
|
+
handleDomEditElementDelete: (selection: DomEditSelection) => Promise<void>;
|
|
2752
|
+
previewIframeRef: React.MutableRefObject<HTMLIFrameElement | null>;
|
|
2753
|
+
waitForPendingDomEditSaves: () => Promise<void>;
|
|
2754
|
+
}
|
|
2755
|
+
declare function useClipboard({ projectId, activeCompPath, domEditSelectionRef, showToast, writeProjectFile, recordEdit, reloadPreview, handleTimelineElementsDelete, handleDomEditElementDelete, previewIframeRef, waitForPendingDomEditSaves, }: UseClipboardOptions): {
|
|
2756
|
+
handleCopy: () => boolean;
|
|
2757
|
+
handlePaste: () => Promise<void>;
|
|
2758
|
+
handleCut: () => Promise<boolean>;
|
|
2759
|
+
handleDuplicate: () => Promise<boolean>;
|
|
2760
|
+
canPaste: () => boolean;
|
|
2761
|
+
};
|
|
2762
|
+
|
|
2763
|
+
/** The live markup to persist and the session snapshot to restore on failure. */
|
|
2764
|
+
interface InlineTextEditCommit {
|
|
2765
|
+
/** The exact preview node that owned the edit; a reload must not retarget it. */
|
|
2766
|
+
element: HTMLElement;
|
|
2767
|
+
html: string;
|
|
2768
|
+
previousHtml: string;
|
|
2769
|
+
}
|
|
2770
|
+
|
|
2771
|
+
declare const SNAP_THRESHOLD_PX = 6;
|
|
2772
|
+
/** Whether a move of this size has travelled far enough for snapping to apply. */
|
|
2773
|
+
declare function snapEngagedForTravel(dx: number, dy: number): boolean;
|
|
2774
|
+
interface SnapEdge {
|
|
2775
|
+
position: number;
|
|
2776
|
+
source: "grid";
|
|
2777
|
+
id: string;
|
|
2778
|
+
}
|
|
2779
|
+
interface SnapTarget {
|
|
2780
|
+
left: number;
|
|
2781
|
+
top: number;
|
|
2782
|
+
right: number;
|
|
2783
|
+
bottom: number;
|
|
2784
|
+
centerX: number;
|
|
2785
|
+
centerY: number;
|
|
2786
|
+
id: string;
|
|
2787
|
+
}
|
|
2788
|
+
interface SnapGuide {
|
|
2789
|
+
axis: "x" | "y";
|
|
2790
|
+
position: number;
|
|
2791
|
+
/** Extent of the guide line (min of involved elements). */
|
|
2792
|
+
from: number;
|
|
2793
|
+
/** Extent of the guide line (max of involved elements). */
|
|
2794
|
+
to: number;
|
|
2795
|
+
}
|
|
2796
|
+
interface SpacingGuide {
|
|
2797
|
+
axis: "x" | "y";
|
|
2798
|
+
/** Position of the gap (start of gap). */
|
|
2799
|
+
position: number;
|
|
2800
|
+
/** Size of the gap in pixels. */
|
|
2801
|
+
size: number;
|
|
2802
|
+
/** Extent for rendering the indicator. */
|
|
2803
|
+
from: number;
|
|
2804
|
+
/** Extent for rendering the indicator. */
|
|
2805
|
+
to: number;
|
|
2806
|
+
}
|
|
2807
|
+
interface SnapResult {
|
|
2808
|
+
dx: number;
|
|
2809
|
+
dy: number;
|
|
2810
|
+
guides: SnapGuide[];
|
|
2811
|
+
spacingGuides: SpacingGuide[];
|
|
2812
|
+
}
|
|
2813
|
+
interface Rect {
|
|
2814
|
+
left: number;
|
|
2815
|
+
top: number;
|
|
2816
|
+
width: number;
|
|
2817
|
+
height: number;
|
|
2818
|
+
}
|
|
2819
|
+
/**
|
|
2820
|
+
* Convert overlay rects to snap targets with precomputed edges & centers.
|
|
2821
|
+
*/
|
|
2822
|
+
declare function extractSnapTargets(entries: Array<{
|
|
2823
|
+
rect: Rect;
|
|
2824
|
+
id: string;
|
|
2825
|
+
}>): SnapTarget[];
|
|
2826
|
+
/**
|
|
2827
|
+
* Create a snap target from the composition/overlay boundary.
|
|
2828
|
+
*/
|
|
2829
|
+
declare function buildCompositionSnapTarget(rect: Rect): SnapTarget;
|
|
2830
|
+
/**
|
|
2831
|
+
* Generate grid-line snap edges.
|
|
2832
|
+
* `gridSpacing` is in composition pixels; `scale` converts to overlay pixels.
|
|
2833
|
+
* X edges are vertical grid lines; Y edges are horizontal grid lines.
|
|
2834
|
+
*/
|
|
2835
|
+
declare function buildGridSnapEdges(compositionRect: Rect, gridSpacing: number, scale: number): {
|
|
2836
|
+
x: SnapEdge[];
|
|
2837
|
+
y: SnapEdge[];
|
|
2838
|
+
};
|
|
2839
|
+
declare function resolveSnapAdjustment(input: {
|
|
2840
|
+
movingRect: Rect;
|
|
2841
|
+
proposedDx: number;
|
|
2842
|
+
proposedDy: number;
|
|
2843
|
+
targets: SnapTarget[];
|
|
2844
|
+
gridEdges?: {
|
|
2845
|
+
x: SnapEdge[];
|
|
2846
|
+
y: SnapEdge[];
|
|
2847
|
+
};
|
|
2848
|
+
threshold: number;
|
|
2849
|
+
disabled: boolean;
|
|
2850
|
+
/** Set when the gesture has not travelled far enough for snapping yet. */
|
|
2851
|
+
disabledForTravel?: boolean;
|
|
2852
|
+
}): SnapResult;
|
|
2853
|
+
/**
|
|
2854
|
+
* Full-length guide line spanning the composition: a vertical line (axis "x")
|
|
2855
|
+
* runs the composition's height at the snapped x position; a horizontal line
|
|
2856
|
+
* (axis "y") runs the composition's width. `composition` is the composition
|
|
2857
|
+
* rect in overlay space — guide positions are already overlay-space, so the
|
|
2858
|
+
* line must be offset by the composition's left/top (the canvas is usually
|
|
2859
|
+
* letterboxed inside the overlay).
|
|
2860
|
+
*/
|
|
2861
|
+
declare function resolveGuideLineRect(guide: SnapGuide, composition: Rect): Rect;
|
|
2862
|
+
declare function resolveEquidistanceGuides(input: {
|
|
2863
|
+
movingRect: Rect;
|
|
2864
|
+
targets: SnapTarget[];
|
|
2865
|
+
threshold: number;
|
|
2866
|
+
}): SpacingGuide[];
|
|
2867
|
+
|
|
2868
|
+
interface SnapContext {
|
|
2869
|
+
targets: SnapTarget[];
|
|
2870
|
+
compositionTarget: SnapTarget | null;
|
|
2871
|
+
gridEdges: {
|
|
2872
|
+
x: SnapEdge[];
|
|
2873
|
+
y: SnapEdge[];
|
|
2874
|
+
} | null;
|
|
2875
|
+
snapEnabled: boolean;
|
|
2876
|
+
}
|
|
2877
|
+
declare function collectSnapContext(input: {
|
|
2878
|
+
overlayEl: HTMLDivElement;
|
|
2879
|
+
iframe: HTMLIFrameElement;
|
|
2880
|
+
excludeElements: Set<HTMLElement>;
|
|
2881
|
+
}): SnapContext;
|
|
2882
|
+
|
|
2883
|
+
interface SnapGuidesState {
|
|
2884
|
+
guides: SnapGuide[];
|
|
2885
|
+
spacingGuides: SpacingGuide[];
|
|
2886
|
+
}
|
|
2887
|
+
interface SnapGuideOverlayProps {
|
|
2888
|
+
snapGuidesRef: RefObject<SnapGuidesState | null>;
|
|
2889
|
+
/** Composition rect in overlay space — guide lines span exactly this rect. */
|
|
2890
|
+
compositionLeft: number;
|
|
2891
|
+
compositionTop: number;
|
|
2892
|
+
compositionWidth: number;
|
|
2893
|
+
compositionHeight: number;
|
|
2894
|
+
}
|
|
2895
|
+
declare const SnapGuideOverlay: react.NamedExoticComponent<SnapGuideOverlayProps>;
|
|
2896
|
+
|
|
2897
|
+
interface ApplyDomSelectionOptions {
|
|
2898
|
+
revealPanel?: boolean;
|
|
2899
|
+
additive?: boolean;
|
|
2900
|
+
preserveGroup?: boolean;
|
|
2901
|
+
announce?: boolean;
|
|
2902
|
+
}
|
|
2903
|
+
interface ResolveDomSelectionOptions {
|
|
2904
|
+
preferClipAncestor?: boolean;
|
|
2905
|
+
skipSourceProbe?: boolean;
|
|
2906
|
+
activeGroupElement?: HTMLElement | null;
|
|
2907
|
+
/** Resolve this node itself instead of applying human group-capture behavior. */
|
|
2908
|
+
exactTarget?: boolean;
|
|
2909
|
+
}
|
|
2910
|
+
interface DomEditTimelineParams {
|
|
2911
|
+
projectId: string | null;
|
|
2912
|
+
activeCompPath: string | null;
|
|
2913
|
+
compIdToSrc: Map<string, string>;
|
|
2914
|
+
captionEditMode: boolean;
|
|
2915
|
+
previewIframeRef: MutableRefObject<HTMLIFrameElement | null>;
|
|
2916
|
+
timelineElements: TimelineElement[];
|
|
2917
|
+
getTimelineSelectionSet: () => ReadonlySet<string>;
|
|
2918
|
+
setSelectedTimelineElementId: (id: string | null, options?: SelectElementOptions) => void;
|
|
2919
|
+
/** Publishes a whole multi-selection to the timeline; the anchor is set separately. */
|
|
2920
|
+
setTimelineSelectionSet: (ids: Set<string>) => void;
|
|
2921
|
+
setRightCollapsed: (collapsed: boolean) => void;
|
|
2922
|
+
setRightPanelTab: (tab: RightPanelTab) => void;
|
|
2923
|
+
}
|
|
2924
|
+
|
|
2925
|
+
interface PreviewMouseDownOptions {
|
|
2926
|
+
preferClipAncestor?: boolean;
|
|
2927
|
+
hoverSelection?: DomEditSelection | null;
|
|
2928
|
+
}
|
|
2929
|
+
|
|
2930
|
+
interface DomEditGroupPathOffsetCommit {
|
|
2931
|
+
selection: DomEditSelection;
|
|
2932
|
+
next: {
|
|
2933
|
+
x: number;
|
|
2934
|
+
y: number;
|
|
2935
|
+
};
|
|
2936
|
+
}
|
|
2937
|
+
|
|
2938
|
+
/**
|
|
2939
|
+
* Why a DOM edit commit did not change the file.
|
|
2940
|
+
*
|
|
2941
|
+
* `runDomEditCommit` resolves on persist failure by design (see its contract
|
|
2942
|
+
* above), so a caller cannot learn whether the write landed by awaiting it — a
|
|
2943
|
+
* failed persist and a successful one are indistinguishable. Capture and apply
|
|
2944
|
+
* bugs still reject. The human path does not need to ask about handled persist
|
|
2945
|
+
* failures, because `onError` already put a toast on screen. A programmatic
|
|
2946
|
+
* caller has no screen, so it has to be told.
|
|
2947
|
+
*/
|
|
2948
|
+
type DomEditCommitDeclineReason = "no-project" | "no-selection" | "geometry-property" | "styles-not-editable" | "not-text-editable" | "preview-stale" | "persist-failed";
|
|
2949
|
+
type DomEditCommitOutcome = {
|
|
2950
|
+
ok: true;
|
|
2951
|
+
persistence?: DomEditPersistOutcome;
|
|
2952
|
+
} | {
|
|
2953
|
+
ok: false;
|
|
2954
|
+
reason: DomEditCommitDeclineReason;
|
|
2955
|
+
};
|
|
2956
|
+
|
|
2957
|
+
/**
|
|
2958
|
+
* Which elements a delete acts on.
|
|
2959
|
+
*
|
|
2960
|
+
* Its own module so `useDomEditSession.ts` stays under the studio's 600-line
|
|
2961
|
+
* cap; it reads only its arguments.
|
|
2962
|
+
*/
|
|
2963
|
+
|
|
2964
|
+
/** One entry in the studio's edit history, as `useDomEditSession`'s caller
|
|
2965
|
+
* supplies it. */
|
|
2966
|
+
interface RecordEditInput$1 {
|
|
2967
|
+
label: string;
|
|
2968
|
+
coalesceKey?: string;
|
|
2969
|
+
files: Record<string, {
|
|
2970
|
+
before: string;
|
|
2971
|
+
after: string;
|
|
2972
|
+
}>;
|
|
2973
|
+
}
|
|
2974
|
+
|
|
2975
|
+
interface UseDomEditSessionParams extends DomEditTimelineParams {
|
|
2976
|
+
compositionLoading: boolean;
|
|
2977
|
+
showToast: (message: string, tone?: "error" | "info") => void;
|
|
2978
|
+
isRecordingRef?: React.RefObject<boolean>;
|
|
2979
|
+
refreshPreviewDocumentVersion: () => void;
|
|
2980
|
+
queueDomEditSave: <T>(save: () => Promise<T>) => Promise<T>;
|
|
2981
|
+
readProjectFile: (path: string) => Promise<string>;
|
|
2982
|
+
writeProjectFile: (path: string, content: string, expectedContent?: string) => Promise<void>;
|
|
2983
|
+
updateEditingFileContent: (path: string, content: string) => void;
|
|
2984
|
+
editHistory: {
|
|
2985
|
+
recordEdit: (entry: RecordEditInput$1) => Promise<void>;
|
|
2986
|
+
};
|
|
2987
|
+
fileTree: string[];
|
|
2988
|
+
importedFontAssetsRef: React.MutableRefObject<ImportedFontAsset[]>;
|
|
2989
|
+
projectDir: string | null;
|
|
2990
|
+
projectIdRef: React.MutableRefObject<string | null>;
|
|
2991
|
+
previewIframe: HTMLIFrameElement | null;
|
|
2992
|
+
refreshKey: number;
|
|
2993
|
+
previewDocumentVersion: number;
|
|
2994
|
+
rightPanelTab: RightPanelTab;
|
|
2995
|
+
applyStudioManualEditsToPreviewRef: React.MutableRefObject<(iframe: HTMLIFrameElement) => Promise<void>>;
|
|
2996
|
+
syncPreviewHotkeys: (iframe: HTMLIFrameElement | null) => void;
|
|
2997
|
+
reloadPreview: () => void;
|
|
2998
|
+
setRefreshKey: React.Dispatch<React.SetStateAction<number>>;
|
|
2999
|
+
openSourceForSelection?: (sourceFile: string, target: PatchTarget) => void;
|
|
3000
|
+
sdkSession?: Composition | null;
|
|
3001
|
+
publishSdkSession?: PublishSdkSession;
|
|
3002
|
+
forceReloadSdkSession?: () => void;
|
|
3003
|
+
/** The timeline context menu's delete op — a canvas selection that IS a
|
|
3004
|
+
* timeline row hands off here instead of the REST remove-elements path. */
|
|
3005
|
+
handleTimelineElementsDelete: (elements: TimelineElement[]) => Promise<void>;
|
|
3006
|
+
readOnlyPreview: boolean;
|
|
3007
|
+
}
|
|
3008
|
+
declare function useDomEditSession({ projectId, activeCompPath, compIdToSrc, captionEditMode, compositionLoading, previewIframeRef, timelineElements, getTimelineSelectionSet, setSelectedTimelineElementId, setTimelineSelectionSet, setRightCollapsed, setRightPanelTab, showToast, isRecordingRef, refreshPreviewDocumentVersion, queueDomEditSave, readProjectFile, writeProjectFile, updateEditingFileContent, editHistory, fileTree, importedFontAssetsRef, projectDir, projectIdRef, previewIframe, refreshKey, previewDocumentVersion, rightPanelTab, applyStudioManualEditsToPreviewRef, syncPreviewHotkeys, reloadPreview, setRefreshKey: _setRefreshKey, openSourceForSelection, sdkSession, publishSdkSession, forceReloadSdkSession, handleTimelineElementsDelete, readOnlyPreview, }: UseDomEditSessionParams): {
|
|
3009
|
+
domEditSelection: DomEditSelection | null;
|
|
3010
|
+
domEditGroupSelections: DomEditSelection[];
|
|
3011
|
+
domEditHoverSelection: DomEditSelection | null;
|
|
3012
|
+
activeGroupElement: HTMLElement | null;
|
|
3013
|
+
agentModalOpen: boolean;
|
|
3014
|
+
agentModalAnchorPoint: AgentModalAnchorPoint | null;
|
|
3015
|
+
copiedAgentPrompt: boolean;
|
|
3016
|
+
agentPromptSelectionContext: string | undefined;
|
|
3017
|
+
domEditSelectionRef: react.MutableRefObject<DomEditSelection | null>;
|
|
3018
|
+
handleTimelineElementSelect: (element: TimelineElement | null) => Promise<void>;
|
|
3019
|
+
handlePreviewCanvasMouseDown: (e: React.MouseEvent<HTMLDivElement>, options?: PreviewMouseDownOptions) => Promise<void>;
|
|
3020
|
+
handlePreviewCanvasPointerMove: (e: React.PointerEvent<HTMLDivElement>, options?: {
|
|
3021
|
+
preferClipAncestor?: boolean;
|
|
3022
|
+
}) => Promise<DomEditSelection | null>;
|
|
3023
|
+
handlePreviewCanvasPointerLeave: () => void;
|
|
3024
|
+
applyDomSelection: (selection: DomEditSelection | null, options?: ApplyDomSelectionOptions) => void;
|
|
3025
|
+
clearDomSelection: () => void;
|
|
3026
|
+
refreshDomEditSelectionFromPreview: (selection: DomEditSelection) => Promise<void>;
|
|
3027
|
+
handleDomStyleCommit: (property: string, value: string) => Promise<DomEditCommitOutcome>;
|
|
3028
|
+
handleDomStyleCommitForSelection: (selection: DomEditSelection, property: string, value: string) => Promise<DomEditCommitOutcome>;
|
|
3029
|
+
handleDomAttributeCommit: (attr: string, value: string) => Promise<void>;
|
|
3030
|
+
handleDomAttributeLiveCommit: (attr: string, value: string | null, onSettled?: (ok: boolean) => void, live?: {
|
|
3031
|
+
previewOnly?: boolean;
|
|
3032
|
+
}) => Promise<void>;
|
|
3033
|
+
handleDomAttributeQuietCommit: (attr: string, value: string | null) => Promise<void>;
|
|
3034
|
+
handleDomHtmlAttributeCommit: (attr: string, value: string | null) => Promise<void>;
|
|
3035
|
+
handleDomAttributesCommit: (selection: DomEditSelection, attrs: Record<string, string>) => Promise<void>;
|
|
3036
|
+
handleDomPathOffsetCommit: (selection: DomEditSelection, next: {
|
|
3037
|
+
x: number;
|
|
3038
|
+
y: number;
|
|
3039
|
+
}, modifiers?: {
|
|
3040
|
+
altKey?: boolean;
|
|
3041
|
+
}) => Promise<void>;
|
|
3042
|
+
handleDomGroupPathOffsetCommit: (updates: DomEditGroupPathOffsetCommit[]) => Promise<void>;
|
|
3043
|
+
handleDomZIndexReorderCommit: (entries: Array<{
|
|
3044
|
+
element: HTMLElement;
|
|
3045
|
+
zIndex: number;
|
|
3046
|
+
id?: string;
|
|
3047
|
+
selector?: string;
|
|
3048
|
+
selectorIndex?: number;
|
|
3049
|
+
sourceFile: string;
|
|
3050
|
+
key?: string;
|
|
3051
|
+
}>, gestureCoalesceKey?: string, actionKind?: string) => Promise<void> | Promise<DomEditPatchBatchesResult>;
|
|
3052
|
+
handleDomBoxSizeCommit: (selection: DomEditSelection, next: {
|
|
3053
|
+
width: number;
|
|
3054
|
+
height: number;
|
|
3055
|
+
}, offset?: {
|
|
3056
|
+
x: number;
|
|
3057
|
+
y: number;
|
|
3058
|
+
}, restore?: () => void) => Promise<void>;
|
|
3059
|
+
handleDomRotationCommit: (selection: DomEditSelection, next: {
|
|
3060
|
+
angle: number;
|
|
3061
|
+
}) => Promise<void>;
|
|
3062
|
+
handleDomManualEditsReset: (selection: DomEditSelection) => Promise<void>;
|
|
3063
|
+
handleDomTextCommit: (value: string, fieldKey?: string) => Promise<DomEditCommitOutcome>;
|
|
3064
|
+
handleDomTextCommitForSelection: (selection: DomEditSelection, value: string, fieldKey?: string) => Promise<DomEditCommitOutcome>;
|
|
3065
|
+
handleDomRichTextCommit: ({ element, html, previousHtml }: InlineTextEditCommit) => Promise<void>;
|
|
3066
|
+
handleDomTextFieldStyleCommit: (fieldKey: string, property: string, value: string) => Promise<void>;
|
|
3067
|
+
handleDomAddTextField: (afterFieldKey?: string) => Promise<string | null>;
|
|
3068
|
+
handleDomRemoveTextField: (fieldKey: string) => Promise<void>;
|
|
3069
|
+
getGsapAnimationsForSelection: (selection: DomEditSelection) => _hyperframes_parsers.GsapAnimation[] | Promise<_hyperframes_parsers.GsapAnimation[]>;
|
|
3070
|
+
handleAskAgent: () => void;
|
|
3071
|
+
handleAgentModalSubmit: (userInstruction: string) => Promise<void>;
|
|
3072
|
+
handleBlockedDomMove: (selection: DomEditSelection) => void;
|
|
3073
|
+
handleDomManualDragStart: () => void;
|
|
3074
|
+
handleDomEditElementDelete: (selection: DomEditSelection, options?: {
|
|
3075
|
+
expandGroup?: boolean;
|
|
3076
|
+
}) => Promise<void>;
|
|
3077
|
+
handleGroupSelection: () => void;
|
|
3078
|
+
handleUngroupSelection: () => void;
|
|
3079
|
+
setActiveGroupElement: (el: HTMLElement | null) => void;
|
|
3080
|
+
buildDomSelectionFromTarget: (target: HTMLElement, options?: ResolveDomSelectionOptions) => Promise<DomEditSelection | null>;
|
|
3081
|
+
buildDomSelectionForTimelineElement: (element: TimelineElement) => Promise<DomEditSelection | null>;
|
|
3082
|
+
updateDomEditHoverSelection: (selection: DomEditSelection | null) => void;
|
|
3083
|
+
applyMarqueeSelection: (selections: DomEditSelection[], additive: boolean) => void;
|
|
3084
|
+
resolveImportedFontAsset: (fontFamilyValue: string) => ImportedFontAsset | null;
|
|
3085
|
+
setAgentModalOpen: react.Dispatch<react.SetStateAction<boolean>>;
|
|
3086
|
+
setAgentPromptSelectionContext: react.Dispatch<react.SetStateAction<string | undefined>>;
|
|
3087
|
+
setAgentModalAnchorPoint: react.Dispatch<react.SetStateAction<AgentModalAnchorPoint | null>>;
|
|
3088
|
+
selectedGsapAnimations: _hyperframes_parsers.GsapAnimation[];
|
|
3089
|
+
gsapMultipleTimelines: boolean;
|
|
3090
|
+
gsapUnsupportedTimelinePattern: boolean;
|
|
3091
|
+
handleGsapUpdateProperty: (animId: string, prop: string, value: number | string) => void;
|
|
3092
|
+
handleGsapUpdateMeta: (animId: string, updates: {
|
|
3093
|
+
duration?: number;
|
|
3094
|
+
ease?: string;
|
|
3095
|
+
position?: number;
|
|
3096
|
+
}, selectionOverride?: DomEditSelection | null) => Promise<boolean>;
|
|
3097
|
+
handleGsapDeleteAnimation: (animId: string, selectionOverride?: DomEditSelection | null) => Promise<boolean>;
|
|
3098
|
+
handleGsapDeleteAllForElement: (targetSelector: string) => void;
|
|
3099
|
+
handleGsapAddAnimation: (method: "to" | "from" | "set" | "fromTo", selectionOverride?: DomEditSelection | null) => Promise<boolean>;
|
|
3100
|
+
handleGsapAddProperty: (animId: string, prop: string) => void;
|
|
3101
|
+
handleGsapRemoveProperty: (animId: string, prop: string) => void;
|
|
3102
|
+
handleGsapUpdateFromProperty: (animId: string, prop: string, value: number | string) => void;
|
|
3103
|
+
handleGsapAddFromProperty: (animId: string, prop: string) => void;
|
|
3104
|
+
handleGsapRemoveFromProperty: (animId: string, prop: string) => void;
|
|
3105
|
+
handleGsapAddKeyframe: (animId: string, percentage: number, property: string, value: number | string, selectionOverride?: DomEditSelection | null) => void;
|
|
3106
|
+
handleGsapAddKeyframeBatch: (animId: string, percentage: number, properties: Record<string, number | string>, commitOverrides?: Partial<CommitMutationOptions>, selectionOverride?: DomEditSelection | null) => Promise<void>;
|
|
3107
|
+
handleGsapRemoveKeyframe: (animId: string, percentage: number, commitOverrides?: Partial<CommitMutationOptions>, selectionOverride?: DomEditSelection | null) => void;
|
|
3108
|
+
handleGsapMoveKeyframeToPlayhead: (animId: string, fromPercentage: number, selectionOverride?: DomEditSelection | null, animationOverride?: _hyperframes_parsers.GsapAnimation) => void;
|
|
3109
|
+
handleGsapMoveKeyframe: (animId: string, fromPercentage: number, toPercentage: number, selectionOverride?: DomEditSelection | null) => Promise<boolean>;
|
|
3110
|
+
handleGsapResizeKeyframedTween: (animId: string, position: number, duration: number, pctRemap: Array<{
|
|
3111
|
+
from: number;
|
|
3112
|
+
to: number;
|
|
3113
|
+
}>, selectionOverride?: DomEditSelection | null) => Promise<boolean>;
|
|
3114
|
+
handleGsapConvertToKeyframes: (animId: string, resolvedFromValues?: Record<string, number | string>, duration?: number, commitOverrides?: Partial<CommitMutationOptions>, selectionOverride?: DomEditSelection | null) => Promise<void>;
|
|
3115
|
+
handleGsapRemoveAllKeyframes: (animId: string, selectionOverride?: DomEditSelection | null) => Promise<boolean>;
|
|
3116
|
+
handleResetSelectedElementKeyframes: () => boolean;
|
|
3117
|
+
handleUpdateKeyframeEase: (animationId: string, percentage: number, ease: string) => void;
|
|
3118
|
+
handleUpdateSegmentEase: (targets: AnimationKeyframeTarget[], ease: string) => void;
|
|
3119
|
+
handleSetAllKeyframeEases: (animationId: string, ease: string) => void;
|
|
3120
|
+
commitAnimatedProperty: (selection: DomEditSelection, property: string, value: number | string) => Promise<void>;
|
|
3121
|
+
commitAnimatedProperties: (selection: DomEditSelection, properties: Record<string, number | string>) => Promise<void>;
|
|
3122
|
+
handleSetArcPath: (animId: string, config: Parameters<(sel: DomEditSelection, animId: string, config: {
|
|
3123
|
+
enabled: boolean;
|
|
3124
|
+
autoRotate?: boolean | number;
|
|
3125
|
+
segments?: Array<{
|
|
3126
|
+
curviness: number;
|
|
3127
|
+
cp1?: {
|
|
3128
|
+
x: number;
|
|
3129
|
+
y: number;
|
|
3130
|
+
};
|
|
3131
|
+
cp2?: {
|
|
3132
|
+
x: number;
|
|
3133
|
+
y: number;
|
|
3134
|
+
};
|
|
3135
|
+
}>;
|
|
3136
|
+
}) => void>[2]) => void;
|
|
3137
|
+
handleUpdateArcSegment: (animId: string, segmentIndex: number, update: Parameters<(sel: DomEditSelection, animId: string, segmentIndex: number, update: {
|
|
3138
|
+
curviness?: number;
|
|
3139
|
+
cp1?: {
|
|
3140
|
+
x: number;
|
|
3141
|
+
y: number;
|
|
3142
|
+
};
|
|
3143
|
+
cp2?: {
|
|
3144
|
+
x: number;
|
|
3145
|
+
y: number;
|
|
3146
|
+
};
|
|
3147
|
+
}) => void>[3]) => void;
|
|
3148
|
+
handleUnroll: () => void;
|
|
3149
|
+
invalidateGsapCache: () => void;
|
|
3150
|
+
previewIframeRef: react.MutableRefObject<HTMLIFrameElement | null>;
|
|
3151
|
+
commitMutation: (mutation: Record<string, unknown>, options: {
|
|
3152
|
+
label: string;
|
|
3153
|
+
softReload?: boolean;
|
|
3154
|
+
}) => Promise<void>;
|
|
3155
|
+
};
|
|
3156
|
+
|
|
3157
|
+
interface DomEditSaveQueue {
|
|
3158
|
+
enqueue: <T>(save: () => Promise<T>) => Promise<T>;
|
|
3159
|
+
waitForIdle: () => Promise<DomEditSaveDrainResult>;
|
|
3160
|
+
reset: () => void;
|
|
3161
|
+
destroy: () => void;
|
|
3162
|
+
}
|
|
3163
|
+
type DomEditSaveDrainResult = StudioSaveDrainResult;
|
|
3164
|
+
|
|
3165
|
+
/** One file's restore from the edit-history store: before (live) / after (target) bytes. */
|
|
3166
|
+
interface UndoRestoreFile {
|
|
3167
|
+
previous: string;
|
|
3168
|
+
restored: string;
|
|
3169
|
+
}
|
|
3170
|
+
|
|
3171
|
+
/** The restore payload the undo/redo preview-sync consumes (from the history store). */
|
|
3172
|
+
interface HistoryPreviewRestore {
|
|
3173
|
+
paths?: string[];
|
|
3174
|
+
files?: Record<string, UndoRestoreFile>;
|
|
3175
|
+
}
|
|
3176
|
+
interface RecordEditInput {
|
|
3177
|
+
label: string;
|
|
3178
|
+
coalesceKey?: string;
|
|
3179
|
+
files: Record<string, {
|
|
3180
|
+
before: string;
|
|
3181
|
+
after: string;
|
|
3182
|
+
}>;
|
|
3183
|
+
}
|
|
3184
|
+
interface UsePreviewPersistenceParams {
|
|
3185
|
+
showToast: (message: string, tone?: "error" | "info") => void;
|
|
3186
|
+
readOptionalProjectFile: (path: string) => Promise<string>;
|
|
3187
|
+
writeProjectFile: (path: string, content: string) => Promise<void>;
|
|
3188
|
+
recordEdit: (entry: RecordEditInput) => Promise<void>;
|
|
3189
|
+
previewIframeRef: React.MutableRefObject<HTMLIFrameElement | null>;
|
|
3190
|
+
activeCompPathRef: React.MutableRefObject<string | null>;
|
|
3191
|
+
/** Called to reload the preview after undo/redo or external file changes. */
|
|
3192
|
+
reloadPreview: () => void;
|
|
3193
|
+
}
|
|
3194
|
+
declare function usePreviewPersistence({ showToast, readOptionalProjectFile: _readOptionalProjectFile, writeProjectFile: _writeProjectFile, recordEdit: _recordEdit, previewIframeRef, activeCompPathRef, reloadPreview, }: UsePreviewPersistenceParams): {
|
|
3195
|
+
domTextCommitVersionRef: react.RefObject<number>;
|
|
3196
|
+
domEditSaveQueueRef: react.RefObject<DomEditSaveQueue | null>;
|
|
3197
|
+
applyStudioManualEditsToPreviewRef: react.RefObject<(iframe?: HTMLIFrameElement | null) => Promise<void>>;
|
|
3198
|
+
queueDomEditSave: <T>(save: () => Promise<T>) => Promise<T>;
|
|
3199
|
+
drainPendingDomEditSaves: () => Promise<{
|
|
3200
|
+
status: "clean";
|
|
3201
|
+
} | {
|
|
3202
|
+
status: "conflict";
|
|
3203
|
+
error: StudioFileConflictError;
|
|
3204
|
+
} | {
|
|
3205
|
+
status: "failed";
|
|
3206
|
+
error: unknown;
|
|
3207
|
+
}>;
|
|
3208
|
+
waitForPendingDomEditSaves: () => Promise<void>;
|
|
3209
|
+
domEditSaveQueuePaused: string | null;
|
|
3210
|
+
resetDomEditSaveQueueBreaker: () => void;
|
|
3211
|
+
applyCurrentStudioManualEditsToPreview: (iframe?: HTMLIFrameElement | null) => void;
|
|
3212
|
+
applyStudioManualEditsToPreview: (iframe?: HTMLIFrameElement | null) => Promise<void>;
|
|
3213
|
+
syncHistoryPreviewAfterApply: (restore: HistoryPreviewRestore) => Promise<void>;
|
|
3214
|
+
};
|
|
3215
|
+
|
|
3216
|
+
type DomEditValue = ReturnType<typeof useDomEditSession>;
|
|
3217
|
+
interface DomEditSelectionValue extends Pick<DomEditValue, "domEditSelection" | "domEditGroupSelections" | "domEditHoverSelection" | "activeGroupElement" | "domEditSelectionRef" | "selectedGsapAnimations" | "gsapMultipleTimelines" | "gsapUnsupportedTimelinePattern" | "agentModalOpen" | "agentModalAnchorPoint" | "copiedAgentPrompt" | "agentPromptSelectionContext"> {
|
|
3218
|
+
}
|
|
3219
|
+
declare function useDomEditSelectionContext(): DomEditSelectionValue;
|
|
3220
|
+
declare function DomEditProvider({ value: { domEditSelection, domEditGroupSelections, domEditHoverSelection, agentModalOpen, agentModalAnchorPoint, copiedAgentPrompt, agentPromptSelectionContext, domEditSelectionRef, handleTimelineElementSelect, handlePreviewCanvasMouseDown, handlePreviewCanvasPointerMove, handlePreviewCanvasPointerLeave, applyDomSelection, clearDomSelection, refreshDomEditSelectionFromPreview, handleDomStyleCommit, handleDomStyleCommitForSelection, handleDomAttributeCommit, handleDomAttributeLiveCommit, handleDomAttributeQuietCommit, handleDomHtmlAttributeCommit, handleDomAttributesCommit, handleDomPathOffsetCommit, handleDomGroupPathOffsetCommit, handleDomZIndexReorderCommit, handleDomBoxSizeCommit, handleDomRotationCommit, handleDomManualEditsReset, handleDomTextCommit, handleDomTextCommitForSelection, handleDomRichTextCommit, handleDomTextFieldStyleCommit, handleDomAddTextField, handleDomRemoveTextField, getGsapAnimationsForSelection, handleAskAgent, handleAgentModalSubmit, handleBlockedDomMove, handleDomManualDragStart, handleDomEditElementDelete, handleGroupSelection, handleUngroupSelection, setActiveGroupElement, activeGroupElement, buildDomSelectionFromTarget, buildDomSelectionForTimelineElement, updateDomEditHoverSelection, resolveImportedFontAsset, setAgentModalOpen, setAgentPromptSelectionContext, setAgentModalAnchorPoint, selectedGsapAnimations, gsapMultipleTimelines, gsapUnsupportedTimelinePattern, handleGsapUpdateProperty, handleGsapUpdateMeta, handleGsapDeleteAnimation, handleGsapDeleteAllForElement, handleGsapAddAnimation, handleGsapAddProperty, handleGsapRemoveProperty, handleGsapUpdateFromProperty, handleGsapAddFromProperty, handleGsapRemoveFromProperty, handleGsapAddKeyframe, handleGsapAddKeyframeBatch, handleGsapRemoveKeyframe, handleGsapMoveKeyframeToPlayhead, handleGsapMoveKeyframe, handleGsapResizeKeyframedTween, handleGsapConvertToKeyframes, handleGsapRemoveAllKeyframes, handleResetSelectedElementKeyframes, commitAnimatedProperty, commitAnimatedProperties, handleSetArcPath, handleUpdateArcSegment, handleUnroll, invalidateGsapCache, previewIframeRef, commitMutation, applyMarqueeSelection, handleUpdateKeyframeEase, handleUpdateSegmentEase, handleSetAllKeyframeEases, }, children, }: {
|
|
3221
|
+
value: DomEditValue;
|
|
3222
|
+
children: ReactNode;
|
|
3223
|
+
}): react_jsx_runtime.JSX.Element;
|
|
3224
|
+
|
|
3225
|
+
declare function PreviewReadOnlyProvider({ readOnly, reason, children, }: {
|
|
3226
|
+
readOnly: boolean;
|
|
3227
|
+
reason?: string;
|
|
3228
|
+
children: ReactNode;
|
|
3229
|
+
}): react_jsx_runtime.JSX.Element;
|
|
3230
|
+
|
|
3231
|
+
/**
|
|
3232
|
+
* Pure z-order helpers for the canvas right-click context menu.
|
|
3233
|
+
*
|
|
3234
|
+
* Layering strategy: z-index + CSS stacking context (position ≠ static).
|
|
3235
|
+
* All sibling z-index values are read from the live iframe DOM via
|
|
3236
|
+
* element.style.zIndex (inline style, set by the editor) falling back to
|
|
3237
|
+
* the computed value. Treat missing / "auto" as 0 for comparison purposes.
|
|
3238
|
+
*
|
|
3239
|
+
* "Overlapping siblings" = siblings whose bounding rects intersect the
|
|
3240
|
+
* target's bounding rect AND are actually visible at the current frame.
|
|
3241
|
+
* Forward/backward operate within that set; front/back operate across all
|
|
3242
|
+
* siblings (full painting family, visible or not — unchanged semantics).
|
|
3243
|
+
*
|
|
3244
|
+
* ── Visibility ───────────────────────────────────────────────────────────────
|
|
3245
|
+
* In HyperFrames compositions the nearest z-neighbor is often INVISIBLE at the
|
|
3246
|
+
* paused frame: the runtime hides time-inactive clips with inline
|
|
3247
|
+
* `visibility:hidden` / `display:none` (see core runtime
|
|
3248
|
+
* syncTimedElementVisibility), and GSAP timelines park elements at `opacity:0`.
|
|
3249
|
+
* Stepping "forward" over such a sibling looks like a silent no-op. The
|
|
3250
|
+
* forward/backward comparison set therefore keeps only siblings whose
|
|
3251
|
+
* element-level computed style is visible (display ≠ none, visibility ≠
|
|
3252
|
+
* hidden, opacity > 0.01) — all runtime hiding signals are inline styles, so
|
|
3253
|
+
* computed style covers them. Ancestor-chain checks are unnecessary here:
|
|
3254
|
+
* siblings share the target's ancestors. The probe is injectable
|
|
3255
|
+
* (ZOrderResolveOptions.isVisible) so the pure-module tests stay meaningful
|
|
3256
|
+
* without a real style engine, mirroring how tests stub rect reading.
|
|
3257
|
+
*
|
|
3258
|
+
* ── Tie-awareness ────────────────────────────────────────────────────────────
|
|
3259
|
+
* CSS paint order for elements that share a z-index is DOM document order:
|
|
3260
|
+
* the element that comes LATER in the DOM paints ON TOP. The old resolver
|
|
3261
|
+
* compared z-index alone, so a target tied with the element visually below it
|
|
3262
|
+
* (equal z, target later in DOM) had an empty "below" set and silently
|
|
3263
|
+
* no-op'd. This module computes true render order — sort by
|
|
3264
|
+
* (zIndex asc, DOM position asc), bottom→top — moves the target one step (or
|
|
3265
|
+
* to an end) in that order, then realizes the new order back into z values.
|
|
3266
|
+
*
|
|
3267
|
+
* The result is a MULTI-element patch: a single-element patch when a
|
|
3268
|
+
* strictly-between z value can express the new order given DOM-order
|
|
3269
|
+
* tie-breaking, otherwise a minimal renumber of the affected set (emitting
|
|
3270
|
+
* patches only for elements whose z actually changes). z is never negative
|
|
3271
|
+
* (project convention clamps z ≥ 0).
|
|
3272
|
+
*/
|
|
3273
|
+
type ZOrderAction = "bring-forward" | "send-backward" | "bring-to-front" | "send-to-back";
|
|
3274
|
+
/** A resolved change: set `element`'s z-index to `zIndex`. */
|
|
3275
|
+
interface ZOrderPatch {
|
|
3276
|
+
element: HTMLElement;
|
|
3277
|
+
zIndex: number;
|
|
3278
|
+
}
|
|
3279
|
+
|
|
3280
|
+
interface DomEditOverlayProps {
|
|
3281
|
+
iframeRef: RefObject<HTMLIFrameElement | null>;
|
|
3282
|
+
activeCompositionPath: string | null;
|
|
3283
|
+
selection: DomEditSelection | null;
|
|
3284
|
+
groupSelections?: DomEditSelection[];
|
|
3285
|
+
hoverSelection: DomEditSelection | null;
|
|
3286
|
+
allowCanvasMovement?: boolean;
|
|
3287
|
+
/** "host": no hover, marquee or box re-select; Enter with nothing focused still opens text. */
|
|
3288
|
+
canvasInput?: "overlay" | "host";
|
|
3289
|
+
onTextEditingChange?: (editing: boolean) => void;
|
|
3290
|
+
/** A click on a single selection's box, in either mode; the event may be the pointerup. */
|
|
3291
|
+
onSelectionBoxClick?: (event: React.MouseEvent<HTMLDivElement>, selection: DomEditSelection) => void;
|
|
3292
|
+
onCanvasMouseDown: (event: React.MouseEvent<HTMLDivElement>, options?: PreviewMouseDownOptions) => void;
|
|
3293
|
+
onCanvasPointerMove: (event: React.PointerEvent<HTMLDivElement>, options?: {
|
|
3294
|
+
preferClipAncestor?: boolean;
|
|
3295
|
+
}) => Promise<DomEditSelection | null>;
|
|
3296
|
+
onCanvasPointerLeave: () => void;
|
|
3297
|
+
onSelectionChange: (selection: DomEditSelection, options?: {
|
|
3298
|
+
revealPanel?: boolean;
|
|
3299
|
+
additive?: boolean;
|
|
3300
|
+
}) => void;
|
|
3301
|
+
onBlockedMove: (selection: DomEditSelection) => void;
|
|
3302
|
+
onManualDragStart?: () => void;
|
|
3303
|
+
onPathOffsetCommit: (selection: DomEditSelection, next: {
|
|
3304
|
+
x: number;
|
|
3305
|
+
y: number;
|
|
3306
|
+
}, modifiers?: {
|
|
3307
|
+
altKey?: boolean;
|
|
3308
|
+
}) => Promise<void> | void;
|
|
3309
|
+
onGroupPathOffsetCommit: (updates: DomEditGroupPathOffsetCommit[]) => Promise<void> | void;
|
|
3310
|
+
onBoxSizeCommit: (selection: DomEditSelection, next: {
|
|
3311
|
+
width: number;
|
|
3312
|
+
height: number;
|
|
3313
|
+
}, offset?: {
|
|
3314
|
+
x: number;
|
|
3315
|
+
y: number;
|
|
3316
|
+
}, restore?: () => void) => Promise<void> | void;
|
|
3317
|
+
onRotationCommit: (selection: DomEditSelection, next: {
|
|
3318
|
+
angle: number;
|
|
3319
|
+
}) => Promise<void> | void;
|
|
3320
|
+
onStyleCommit?: (property: string, value: string) => Promise<unknown> | void;
|
|
3321
|
+
recordingState?: GestureRecordingState;
|
|
3322
|
+
onToggleRecording?: () => void;
|
|
3323
|
+
onMarqueeSelect?: (selections: DomEditSelection[], additive: boolean) => void;
|
|
3324
|
+
/**
|
|
3325
|
+
* Delete the selected canvas element.
|
|
3326
|
+
* Wire to handleDomEditElementDelete from useDomEditActionsContext —
|
|
3327
|
+
* same handler the Delete/Backspace hotkey uses.
|
|
3328
|
+
*/
|
|
3329
|
+
onDeleteSelection?: (selection: DomEditSelection) => void;
|
|
3330
|
+
/**
|
|
3331
|
+
* Called with the resolved z-order patch list and the menu action that
|
|
3332
|
+
* produced it (feeds the undo coalesce key). The patch list is tie-aware and
|
|
3333
|
+
* may include sibling elements (see canvasContextMenuZOrder); the live DOM is
|
|
3334
|
+
* NOT yet mutated. Wire to handleDomZIndexReorderCommit from
|
|
3335
|
+
* useDomEditActionsContext. See CanvasContextMenu.tsx module comment.
|
|
3336
|
+
*/
|
|
3337
|
+
onApplyZIndex?: (selection: DomEditSelection, patches: ZOrderPatch[], action: ZOrderAction,
|
|
3338
|
+
/** Sibling a forward/backward step moved past (pre-mutation render order);
|
|
3339
|
+
* null for front/back. Feeds the timeline z-mirror's crossedKey. */
|
|
3340
|
+
crossed: HTMLElement | null) => void;
|
|
3341
|
+
}
|
|
3342
|
+
declare const DomEditOverlay: react.NamedExoticComponent<DomEditOverlayProps>;
|
|
3343
|
+
|
|
3344
|
+
type HostInputProps = Pick<ComponentProps<typeof DomEditOverlay>, "canvasInput" | "onSelectionBoxClick">;
|
|
3345
|
+
interface ConnectedDomEditOverlayProps extends HostInputProps {
|
|
3346
|
+
activeCompositionPath: string | null;
|
|
3347
|
+
showHoverSelection: boolean;
|
|
3348
|
+
shouldShowSelectedDomBounds: boolean;
|
|
3349
|
+
isGestureRecording?: boolean;
|
|
3350
|
+
/** True when an in-place text edit opens its caret, false when it ends or unmounts. */
|
|
3351
|
+
onTextEditingChange?: (editing: boolean) => void;
|
|
3352
|
+
}
|
|
3353
|
+
declare function ConnectedDomEditOverlay({ activeCompositionPath, showHoverSelection, shouldShowSelectedDomBounds, isGestureRecording, canvasInput, onTextEditingChange, onSelectionBoxClick, }: ConnectedDomEditOverlayProps): react_jsx_runtime.JSX.Element;
|
|
3354
|
+
|
|
3355
|
+
interface MarqueeGesturesDeps<T = DomEditSelection> {
|
|
3356
|
+
iframeRef: React.RefObject<HTMLIFrameElement | null>;
|
|
3357
|
+
overlayRef: React.RefObject<HTMLDivElement | null>;
|
|
3358
|
+
activeCompositionPathRef: React.RefObject<string | null>;
|
|
3359
|
+
onMarqueeSelectRef: React.RefObject<((selections: T[], additive: boolean) => void) | undefined>;
|
|
3360
|
+
/** Turns the elements a drag touched into picks; without it, Studio's edit selections. */
|
|
3361
|
+
resolveHits?: (elements: HTMLElement[]) => T[] | Promise<T[]>;
|
|
3362
|
+
selectionRef?: React.RefObject<DomEditSelection | null>;
|
|
3363
|
+
/** Studio's pointer handling, for the events that are not part of a marquee. */
|
|
3364
|
+
gestures?: {
|
|
3365
|
+
onPointerMove: (event: React.PointerEvent<HTMLDivElement>) => void;
|
|
3366
|
+
onPointerUp: (event: React.PointerEvent<HTMLDivElement>) => void;
|
|
3367
|
+
clearPointerState: (ref: React.RefObject<DomEditSelection | null>) => void;
|
|
3368
|
+
};
|
|
3369
|
+
}
|
|
3370
|
+
interface MarqueeGestures {
|
|
3371
|
+
marqueeRect: Rect$1 | null;
|
|
3372
|
+
candidateRects: Rect$1[];
|
|
3373
|
+
/** Starts a marquee at this press; the host has decided it landed on empty canvas. */
|
|
3374
|
+
begin: (event: React.PointerEvent<HTMLElement>) => void;
|
|
3375
|
+
/** Drops an active marquee without selecting anything. */
|
|
3376
|
+
cancel: () => void;
|
|
3377
|
+
onPointerMove: (event: React.PointerEvent<HTMLDivElement>) => void;
|
|
3378
|
+
onPointerUp: (event: React.PointerEvent<HTMLDivElement>) => void;
|
|
3379
|
+
onPointerCancel: () => void;
|
|
3380
|
+
}
|
|
3381
|
+
declare function useMarqueeGestures(deps: MarqueeGesturesDeps): MarqueeGestures;
|
|
3382
|
+
declare function useMarqueeGestures<T>(deps: MarqueeGesturesDeps<T> & Required<Pick<MarqueeGesturesDeps<T>, "resolveHits">>): MarqueeGestures;
|
|
3383
|
+
|
|
3384
|
+
interface MarqueeOverlayProps {
|
|
3385
|
+
/** Elements the marquee currently intersects — outlined live before mouse-up. */
|
|
3386
|
+
candidateRects: Rect$1[];
|
|
3387
|
+
/** The marquee drag rectangle itself, or null when not marquee-selecting. */
|
|
3388
|
+
marqueeRect: Rect$1 | null;
|
|
3389
|
+
}
|
|
3390
|
+
/**
|
|
3391
|
+
* The marquee selection visuals: a live "candidate" outline on each element the
|
|
3392
|
+
* box currently touches, plus the dashed drag rectangle. Extracted from
|
|
3393
|
+
* DomEditOverlay to keep that file under the 600-line cap.
|
|
3394
|
+
*/
|
|
3395
|
+
declare function MarqueeOverlay({ candidateRects, marqueeRect }: MarqueeOverlayProps): react_jsx_runtime.JSX.Element;
|
|
3396
|
+
|
|
3397
|
+
export { type AgentModalAnchorPoint, type AgentPromptElementInfo, AskAgentModal, type AskAgentModalProps, AudioMeterStrip, type AudioMeterStripProps, AudioWaveform, type AudioWaveformProps, type BlockedTimelineEditIntent, type CanEditTimelineElement, CompositionBreadcrumb, type CompositionDimensions, type CompositionLevel, CompositionThumbnail, ConnectedDomEditOverlay, type ConnectedDomEditOverlayProps, DEFAULT_SHORTCUT_SECTIONS, type DomEditCapabilities, DomEditProvider, type DomEditSelection, type EditHistoryHandle, EditorShell, type EditorShellProps, type ExternalFileChangeBlockedState, type ExternalFileChangeCoordinatorHandle, ExternalFileConflictBanner, type FfmpegStatus, FileTree, GridOverlay, ImageThumbnail, type ImageThumbnailProps, type MarqueeGestures, type MarqueeGesturesDeps, MarqueeOverlay, type MarqueeOverlayProps, type Rect$1 as MarqueeRect, NLEPreview, type PatchOperation, type PersistedRenderSettings, type PickedElement, PlayerControls, type PlayerHandle, type PlayerHandleElement, type PlayerHandleListener, type PlayerHandleTimeListener, type DomEditCompositionRect as PreviewCompositionRect, PreviewGuides, PreviewOverlayProvider, type PreviewOverlayProviderProps, PreviewReadOnlyProvider, type PreviewSnapPreferences, PropertyPanel, type RenderJob, RenderQueue, type RenderQueueProps, type ResolutionPreset, SNAP_THRESHOLD_PX, type ShortcutHint, type ShortcutSection, type SnapContext, type SnapEdge, type SnapGuide, SnapGuideOverlay, type SnapGuideOverlayProps, type SnapGuidesState, type Rect as SnapRect, type SnapResult, type SnapTarget, SnapToolbar, SourceEditor, type SpacingGuide, type StartRenderOptions, StudioApp, StudioFileConflictError, type StudioPendingEditsDrainResult, type ThumbnailPriority, Timeline, TimelineClipMenu, type TimelineClipRenderContext, type TimelineEditCallbacks, type TimelineEditOutcome, type TimelineEditPermission, TimelineEditPopover, TimelineEditProvider, type TimelineElement, TimelineEmptyStatePart, TimelineFrame, TimelineGapMenu, TimelineHistoryButtons, type TimelineHistoryButtonsProps, TimelineKeyframeMenu, TimelineLanes, TimelineOverlays, TimelinePane, type TimelinePaneProps, TimelinePlayhead, TimelineProvider, TimelineRazorGuide, TimelineRuler, TimelineShortcutHint, type TimelineTheme, type TimelineTimeRange$1 as TimelineTimeRange, TimelineToolbar, type TimelineToolbarProps, type TimelineZIndexReorderCommit, type UseClipboardOptions, type UseDomEditSessionParams, type UseEditHistoryActionsOptions, type UsePersistentEditHistoryOptions, type UsePreviewPersistenceParams, type UseProjectFileWriterOptions, type UseRenderClipContentOptions, type UseTimelineEditingOptions, VideoThumbnail, applyPatch, buildCompositionSnapTarget, buildGridSnapEdges, buildPickerAgentContextPreview, buildPickerAgentPrompt, collectSnapContext, extractSnapTargets, findElementBlock, flushStudioPendingEdits, formatTime, getPersistedRenderSettings, liveTime, mergeStyleIntoTag, parseStyleString, persistRenderSettings, resolveEquidistanceGuides, resolveGuideLineRect, resolveIframe, resolveSnapAdjustment, resolveSourceFile, snapEngagedForTravel, useClipboard, useDomEditSelectionContext, useDomEditSession, useEditHistoryActions, useElementPicker, useMarqueeGestures, usePersistentEditHistory, usePlayerHandle, usePlayerStore, usePreviewCompositionRect, usePreviewGuidesStore, usePreviewOverlayContext, usePreviewPersistence, useProjectFileWriter, useRenderClipContent, useRenderQueue, useTimelineContext, useTimelineEditing, useTimelinePlayer };
|