Repository navigation
feat(core): expand {option} placeholders in visual recipe selectors - #1586
Merged
Merged
Conversation
added 3 commits
October 31, 2026 22:25
A token or relationship selector can name any declared option, for example {style}. It compiles once per declared value and each candidate pins that option, so the solver and the JS runtime need no change. SPEC-061 reports a placeholder that is not size, sizeIndex or a declared option with values. {size} and {sizeIndex} behave as before.
🦋 Changeset detectedLatest commit: f3f68a8 The changes in this PR will be included in the next version bump. This PR includes changesets to release 9 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Contributor
Run report for f3f68a8eTotal time: 6m 13s | Comparison time: 18m 32s | Estimated savings: 12m 19s (66.4% faster)
Expanded report
Changed files |
Contributor
🎨 Token Changes ReportTokens Changed (0)Original Branch: This comment was automatically generated by the token diff tool. 🤖 |
Contributor
🧩 Component Schema Changes ReportNo component schema changes detected.This comment was automatically generated by the component schema diff tool. 🤖 |
…y pins
A recipe that uses an option only through a {option} selector placeholder no longer
gets a SPEC-066 warning. A relationship that pins an option to an array of values now
matches under a placeholder when the array contains the value. The no-match message is
built without a second graph scan.
This was referenced Nov 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Recipe
tokenandrelationshipselectors can now use{<option>}for any option the component declares, such as{style}.{size}and{sizeIndex}work as before.visual-runtime.jspick by the request and need no change.{name}placeholder that is notsize,sizeIndexor a declared option that lists its values. SPEC-062, 066, 067, 069 and 071 expand the placeholders before resolving, and SPEC-066 counts an option used only through a placeholder as used.component-visuals.md, therules.yamlnotes and the schema description are updated. Theinvalid/SPEC-061conformance fixture covers the new check.This departs from proposal 014, which said to ship the first iOS Button slice with explicit per-style entries and template before a third style. Measured with the proposal's recipe shape, explicit entries cost 144, 197 and 250 lines for one, two and three styles (515 for eight). The templated recipe is 128 lines for any number of styles. Templating is already shorter at one style, so writing two explicit styles and then rewriting them is wasted work. The proposal has a dated note.
Output for recipes that use no option placeholder is unchanged:
recipe_snapshotsand every committed golden are untouched.Related Issue
p6ga.8.46, part of epic p6ga.8 (platform-aware rendering). It unblocks the iOS Button recipe in p6ga.8.40.
Motivation and Context
The iOS Button binds tokens directly by name, per style. Without option templating, every added style adds about 53 lines to the recipe, and eight styles reach 515. With it, adding a style is a token and an option value.
Risks
An unknown identifier-like
{name}in a recipe selector used to pass silently as literal text. It is now a SPEC-061 error, and the message names the selector path. No committed recipe is affected: the only placeholders inpackages/design-data/visualsandplatformsare{size}and{sizeIndex}, and the existing validation and snapshot suites pass unchanged. A recipe outside this repo that has such a brace would need to rename it or add the option.How Has This Been Tested?
size,sizeIndexand non-identifier braces are fine) and SPEC-062 (expansion over declared values).{option}placeholder is not reported as unused. Compile: a relationship that pins an option to an array of values still matches under a placeholder.invalid/SPEC-061conformance fixture with a second expected error.sdk/wasm/test/visual-runtime-option-templates.test.jsrenders a compiled{style}recipe throughvisual-runtime.jsand asserts thataccent,primaryand the default select different candidates. Its compiled fixture is thecompile_recipeoutput of the Rust test, pasted in, so it can drift from the compiler. The existing parity test does not cover an option-templated recipe, because no committed recipe uses one yet.cargo fmt --checkandclippy -D warningsclean;cargo checkafter each commit.moon run sdk:test sdk-wasm:test design-data:validate design-data:validate-dataset tokens:verifyLegacyOutput root:validate-platform-recipes root:test-platform-recipes-guard root:test-platform-recipes-e2e --force: all pass (1733 SDK tests, 121 WASM tests).--fail-on-warnings,check-ci-coverageandai:checkpass;pnpm-lock.yamldiff is empty.Screenshots (if appropriate):
N/A
Types of changes
Checklist: