Skip to content

fix(configurator): lumlocker locked preview follows live sources - #634

Merged
jackgranatowski merged 1 commit into
mainfrom
claude/configurator-controls-audit-zqi10q
Jul 19, 2026
Merged

fix(configurator): lumlocker locked preview follows live sources#634
jackgranatowski merged 1 commit into
mainfrom
claude/configurator-controls-audit-zqi10q

Conversation

@jackgranatowski

@jackgranatowski jackgranatowski commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes the LumLocker locked-swatch preview in the configurator's Colors panel. The locked swatches were rendering stock framework defaults (blue) instead of following the live brand sources — e.g. an orange primary showed a blue "locked" swatch. The locked preview now derives its colour from the live --sf-color-*-source-{light,dark} tokens, pinning only lightness (L) via --sf-lumlocker and preserving each source's chroma and hue.

Also includes a full verification pass over every panel preview: confirmed each preview reacts to the controls that drive it (var()-based previews via injectLivePreview, which writes all overrides with no allowlist; schematic previews via $derived values traced back to overrides), with truthful numeric labels on the capped Layout schematics. No further changes were needed from that audit.

Type

  • fix

Checklist

  • Conventional Commit messages (feat:, fix:, docs:, …) — enforced by commitlint
  • npm run lint:css passes (stylelint) — no CSS source touched
  • npm run build rebuilds dist/ — no framework/dist changes
  • Configurator-only change (Svelte); no framework tokens added or renamed
  • Version references unchanged (no version-related files touched)
  • No core/*.css / optional/*.css / token-registry.json changes — LLM guide unaffected
  • No generated artifacts hand-edited

Notes

Scope is configurator/src only. Verified in-browser: primary light oklch(0.62 0.19 45) (orange) with auto-dark now yields locked dark oklch(0.65 0.171 45) — same hue, pinned lightness — instead of the stock blue swatch.

🤖 Generated with Claude Code


Generated by Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved LumLocker color handling when override values are invalid.
    • Updated locked color previews to correctly resolve CSS variables and provide a dark-to-light fallback.
    • Ensured locked color swatches accurately reflect the active light or dark theme.

… stock defaults

The Locked column re-derived its swatches from `overrides[src] ?? hardcoded
default`, so any brand in Auto dark mode (no dark override — the default)
previewed its lock from the stock blue sources: an orange brand showed blue
"locked" swatches, which is impossible (the lock only pins L, never hue).

Build the locked expression from the live tokens instead, mirroring the
framework's core/themes.css formula exactly — including the
`var(--source-dark, var(--source-light))` fallback — and resolve it per-theme
through the preview iframe like the Current column. Overrides, auto-derived
dark sources and the light fallback all flow through. Also NaN-guards the
--sf-lumlocker read.

Verified: with primary light set to oklch(0.62 0.19 45) and dark on auto, the
locked D swatch resolves to oklch(0.65 0.171 45) — same hue, pinned L — where
it previously showed the default blue.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013BRVgKfEYocPCHz9KU96FN
@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: de710309-a078-46ce-b0aa-acb0df804c1a

📥 Commits

Reviewing files that changed from the base of the PR and between f608bf1 and 6fcc245.

📒 Files selected for processing (1)
  • configurator/src/components/panels/ColorsPanel.svelte

📝 Walkthrough

Walkthrough

LumLocker now validates luminance overrides, generates locked colors from CSS variables with dark-to-light fallback behavior, and renders locked swatches through theme-aware painting.

Changes

LumLocker theme resolution

Layer / File(s) Summary
LumLocker derivation and preview
configurator/src/components/panels/ColorsPanel.svelte
Invalid luminance overrides fall back to 0.65; locked colors use CSS variable-based oklch expressions with dark-to-light fallback; locked swatches use paintTheme(...).

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested labels: codex

Suggested reviewers: claude

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: making the LumLocker locked preview follow live source tokens in the configurator.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/configurator-controls-audit-zqi10q

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added the codex label Jul 19, 2026
@greptile-apps

greptile-apps Bot commented Jul 19, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes the LumLocker locked-swatch preview in the configurator's Colors panel. Previously lockedColor() resolved source colors via a JS-side overrides lookup, which missed auto-derived dark sources (producing the stock blue default instead of the live brand color). The fix replaces that with a var(--sf-color-*-source-{side}) CSS reference resolved through the iframe-based resolveColorForTheme, and switches the swatch renderer from paint to paintTheme so each swatch resolves in the correct light/dark probe context.

  • lumlockerL now guards against NaN with Number.isFinite, preventing invalid oklch(from … NaN c h) expressions when the override field holds a non-numeric string.
  • lockedColor() no longer reads overrides directly; it returns a var()-based CSS expression that the iframe's themed probe resolves, correctly capturing auto-derived dark sources and live overrides.
  • Swatch render switched from paint to paintTheme, ensuring the dark locked swatch resolves against a [data-theme=dark] probe rather than the preview iframe's currently-active theme.

Confidence Score: 5/5

Safe to merge — the change is purely additive to the configurator UI and touches no framework CSS tokens or shared library code.

The three changes are tightly scoped: the NaN guard on lumlockerL is straightforwardly defensive, the var()-based lockedColor() correctly delegates resolution to the iframe-hosted themed probe (matching how every other swatch in the same loop already works), and paintTheme is the established mechanism for per-theme resolution throughout the panel. The dark-to-light var() fallback mirrors the framework's own CSS fallback behaviour. No regressions visible in related logic.

No files require special attention.

Important Files Changed

Filename Overview
configurator/src/components/panels/ColorsPanel.svelte Three targeted changes: NaN guard on lumlockerL, var()-based lockedColor(), and paintTheme switch for the locked swatch. Logic is consistent with how the rest of the panel uses resolveColorForTheme, and the dark-fallback var() chain correctly mirrors the framework's own light→dark source fallback.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant T as Template
    participant LC as lockedColor()
    participant PT as paintTheme()
    participant RC as resolveColorForTheme()
    participant IF as Preview iframe (themed probe)

    T->>LC: lockedColor(colorKey, "dark")
    LC-->>T: "oklch(from var(--sf-color-{key}-source-dark,\n  var(--sf-color-{key}-source-light)) 0.65 c h)"
    T->>PT: paintTheme(locked, "dark", locked)
    PT->>RC: resolveColorForTheme(locked, "dark")
    RC->>IF: "el.style.color = locked (inside [data-theme=dark] wrapper)"
    IF-->>RC: getComputedStyle().color → "oklch(0.65 0.171 45)"
    RC-->>PT: "oklch(0.65 0.171 45)"
    PT-->>T: "oklch(0.65 0.171 45)"
    T->>T: "style="background:oklch(0.65 0.171 45)""
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant T as Template
    participant LC as lockedColor()
    participant PT as paintTheme()
    participant RC as resolveColorForTheme()
    participant IF as Preview iframe (themed probe)

    T->>LC: lockedColor(colorKey, "dark")
    LC-->>T: "oklch(from var(--sf-color-{key}-source-dark,\n  var(--sf-color-{key}-source-light)) 0.65 c h)"
    T->>PT: paintTheme(locked, "dark", locked)
    PT->>RC: resolveColorForTheme(locked, "dark")
    RC->>IF: "el.style.color = locked (inside [data-theme=dark] wrapper)"
    IF-->>RC: getComputedStyle().color → "oklch(0.65 0.171 45)"
    RC-->>PT: "oklch(0.65 0.171 45)"
    PT-->>T: "oklch(0.65 0.171 45)"
    T->>T: "style="background:oklch(0.65 0.171 45)""
Loading

Reviews (1): Last reviewed commit: "fix(configurator): lumlocker locked prev..." | Re-trigger Greptile

@jackgranatowski
jackgranatowski merged commit 4c0e053 into main Jul 19, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants