resolveElementAffordances answers the question “what can the user do with this element right now?” given a live DOM element and its SDK model entry. It returns two objects: capabilities (boolean flags for each edit action) and sections (which inspector panels apply). You use these to conditionally render controls in your editor’s detail panel rather than showing a fixed field set for all elements.
This API lives on the
@hyperframes/sdk/editing subpath, available since @hyperframes/sdk@0.7.22. If the import fails to resolve, upgrade: npm install @hyperframes/sdk@latest.Import
Signature
liveEl— a live, laid-outHTMLElementfrom the composition iframe. The resolver callsgetComputedStyleon it, so it must be attached to a rendered document.modelEl— the SDK model element (comp.getElement(id)), ornullwhen the element exists in the live DOM but not in the SDK source model (generated elements). Passingnullrestricts affordances: style editing is disabled andreasonIfDisabledis set.ctx— optional context for studio-specific concepts. For most custom editors, omit it or leave all flags at their defaults (false).
AffordanceContext
ctx entirely.
Return value
capabilities
sections
sections.colorGrading is element-level only: it tells you this particular element supports color grading controls. Whether to show the color grading panel at all is still governed by your own feature flag — AND the two conditions together.
End-to-end example
Gotchas
Browser-only.resolveElementAffordances calls getComputedStyle internally. It must not be imported or called in Node, a server action, or any non-browser path. The SDK adapter (@hyperframes/sdk/editing) is separate from the pure core resolver precisely to keep the Node SDK path free of browser globals.
Needs a laid-out DOM. canMove and canResize require a live computed position, left, and top. If you call resolveElementAffordances before the iframe finishes layout (e.g. synchronously after srcdoc assignment), both flags will be false. Wait for the iframe’s load event or the composition’s first rendered frame before resolving affordances.
null model means select-only. When modelEl is null (the element is generated at runtime and has no source entry), the resolver sets existsInSource: false. This gives canSelect: true but canEditStyles: false, canMove: false, and all manual-geometry flags false, with reasonIfDisabled set to a human-readable explanation. You can still show the selection highlight; just hide or disable all edit controls.
canApplyManualOffset vs canMove. canMove is true only when the element has absolute/fixed positioning AND authored left/top px values AND no transform-driven geometry. canApplyManualOffset is true for all non-root non-host elements regardless of positioning. A translate-based canvas drag (the applyDraft / commitPreview flow in Canvas Integration) uses canApplyManualOffset as its gate — it does not require canMove.
colorGrading is element-level, not feature-level. sections.colorGrading tells you the element type supports grading (<video> or <img>). Your own feature flag is a separate AND condition. Never replace your feature flag with this field.
Type reference
The full type definitions —EditingAffordances, DomEditCapabilities, EditingSectionApplicability, AffordanceContext, HyperFramesElement — are documented at /sdk/reference/types.
The pure DOM-free resolver (resolveEditingAffordances, EditableElementFacts) lives in @hyperframes/core and is documented at /packages/core.
Canvas Integration
Get the live element and selection via hit-testing and the iframe adapter.
Types reference
Complete type definitions for the SDK public surface.