Skip to content

feat(studio): bind selected element properties to variables#2055

Open
jrusso1020 wants to merge 1 commit into
07-07-feat_core_declarative_variable_bindings_data-var-src_data-var-text_css_custom_propsfrom
07-07-feat_studio_bind_selected_element_properties_to_variables
Open

feat(studio): bind selected element properties to variables#2055
jrusso1020 wants to merge 1 commit into
07-07-feat_core_declarative_variable_bindings_data-var-src_data-var-text_css_custom_propsfrom
07-07-feat_studio_bind_selected_element_properties_to_variables

Conversation

@jrusso1020

@jrusso1020 jrusso1020 commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

What

Ninth PR of the template-variables stack: the promote-a-property gesture. Select an element on the canvas/timeline, open the Variables tab, and a "Bind selected" card offers per-property actions built from the selection:

  • Image/media source (img/video/audio — <source> deliberately excluded, rewriting it post-resource-selection is a spec no-op) → data-var-src
  • Text (leaf elements only — the promote-never-changes-the-render guarantee doesn't hold for containers) → data-var-text
  • Text color / Background / Font<prop>: var(--id) style bindings

Each action declares a variable whose default is the element's current value (computed rgb()/rgba() colors convert to hex; first computed font family becomes the font default). Declare + bind is one batched schema edit (single undo step). Binding to an existing id is allowed only when the types agree (toast otherwise); the card requires the SDK session to resolve the selected element (no dead binds on unmapped sub-comp elements) and resets its form state per selection.

UX polish from live testing feedback:

  • Selecting elements no longer yanks the panel to Design while the Variables tab is open — swap between canvas elements with the tab pinned, the bind card follows the selection

Also fixes two pre-existing bugs surfaced by this work:

  • buildSubCompositionHtml's extractElementAttrs rebuilt <html>/<body> attributes without HTML-escaping — data-composition-variables (JSON) was shredded into bogus markup, so getVariables() silently returned {} on every /preview/comp/* page (regression test added)
  • The capture pipeline's htmlExtractor had the same escape gap for &

Test plan

  • studio 1392 / studio-server 260 (incl. attribute-integrity regression test) / core 1127; all typechecks + builds
  • Driven end-to-end in a live browser session twice (initial + post-review-fixes): select headline → bind Text color → declaration + var(--headline-color) on disk → override in panel → player iframe carries the override, runtime applies the custom prop, element renders the override; tab-pinning and selection-swap verified live

🤖 Generated with Claude Code

Ninth PR of the template-variables stack: the promote-a-property gesture.
Select an element on the canvas/timeline, open the Variables tab, and the
panel offers per-property bind actions.

- "Bind selected" card in the Variables panel, built from the selection:
  image/media source (img/video/audio), text, text color, background, and
  font. Each action declares a variable whose default is the element's
  CURRENT value (promoting never changes the render — computed rgb colors
  convert to hex, the first computed font family becomes the font default)
  and writes the declarative binding the runtime resolves: data-var-src /
  data-var-text attributes or `<prop>: var(--id)` styles. Declare + bind
  run as one batched schema edit (one undo step); binding to an
  already-declared id skips the declare and just binds.
- guarded to selections from the composition the session models — a
  selection in another source file never writes bindings into this one.
- core: extract readVariablesForElement into runtime/variableScope.ts,
  shared by color grading and the declarative bindings (was duplicated).
- fix(studio-server): buildSubCompositionHtml's extractElementAttrs
  rebuilt html/body attributes without HTML-escaping values, shredding
  quote-bearing attributes — data-composition-variables (a JSON array)
  came out as mangled bogus attributes, so getVariables() silently
  returned {} on every /preview/comp/* page (no declared defaults, no
  runtime bindings). Pre-existing bug surfaced by live-testing this
  feature; regression test added.

Verified end-to-end in a live session: select headline → Bind text color
→ declaration + var(--headline-color) written to disk → override in the
panel → runtime applies the custom prop and the element renders the
override.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jrusso1020 jrusso1020 force-pushed the 07-07-feat_core_declarative_variable_bindings_data-var-src_data-var-text_css_custom_props branch from 605efea to a6b9835 Compare July 8, 2026 08:00
@jrusso1020 jrusso1020 force-pushed the 07-07-feat_studio_bind_selected_element_properties_to_variables branch from e2af893 to 18e9bfc Compare July 8, 2026 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant