mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 06:30:03 +00:00
fix(core,cli,lint): close the figma brand-token loop — runtime CSS variables, --name, snippet lint
Brand-loop live test (SDS duplicate, plans/figma/brand-loop-test-plan.md) proved the recolor chain end-to-end and surfaced three gaps: - runtime now defines every declared composition variable as a CSS custom property (document root at init + scoped sub-comp hosts in the loader), so imported var(--slug, literal) fills resolve live — without this the frozen literal always won and variable-driven rebranding could not propagate. Slug kept byte-compatible with the figma importer (parity test). render --variables overrides win. - figma component --name: variant frames are often all named 'Platform=Desktop' and slug-collided across imports. - imported fragments carry data-hf-snippet and the project linter skips composition-root rules for them. - /figma skill documents the field-tested non-Enterprise tokens path (MCP get_variable_defs joined with REST boundVariables ids). Shared-helper extractions (injectScopedStyles, flattenedRoot module, parseHostVariableValues, rasterizeFallback, shapeCss) satisfy the dedup/complexity audit the runtime changes tripped. Validated live: brand-loop renders purple from the attribute alone (no manual :root); 118 figma + 662 runtime/compiler + 331 lint tests green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
80271863d3
commit
def276524b
@@ -210,6 +210,11 @@ export async function lintProject(projectDir: string): Promise<ProjectLintResult
|
||||
const html = readFileSync(filePath, "utf-8");
|
||||
const compSrcPath = `compositions/${file}`;
|
||||
allHtmlSources.push({ html, compSrcPath });
|
||||
// Mountable fragments (figma component imports, registry snippets) are
|
||||
// not standalone compositions — composition-root rules don't apply.
|
||||
// Anchored to the file's ROOT element so a real composition that merely
|
||||
// inlines snippet markup (or mentions the token in text) is still linted.
|
||||
if (isSnippetFragment(html)) continue;
|
||||
const result = await lintHyperframeHtml(html, {
|
||||
filePath,
|
||||
isSubComposition: true,
|
||||
@@ -610,3 +615,11 @@ function lintMissingOrEmptySubComposition(
|
||||
|
||||
return findings;
|
||||
}
|
||||
|
||||
/** True when the file's first element carries data-hf-snippet — i.e. the file
|
||||
* IS a mountable fragment, not a composition that merely contains one. */
|
||||
function isSnippetFragment(html: string): boolean {
|
||||
const firstTag = html.match(/<[a-zA-Z][^>]*>/);
|
||||
if (!firstTag) return false;
|
||||
return /\bdata-hf-snippet\b/.test(firstTag[0]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user