feat(configurator): paste any colour format + always-visible hex reference - #636
Conversation
…cal space Colour fields accepted only the token's own format, so a designer with a brand hex had to pre-convert to OKLCH by hand. Now any CSS colour the browser understands — hex (3/4/6/8), rgb(a), hsl(a), named, hwb, lab/lch, color(), even oklab — is normalised into the field's target space on commit, using the live preview iframe's colour engine via relative-colour syntax so the result matches exactly what gets painted. - New lib/colorConvert.ts: colorSpaceOf() classifies a value; convertColor() resolves oklch(from <input> l c h) / oklab(from …) through the probe and reformats to the compact convention (alpha preserved); normalizeColorInput() is the commit helper — var() refs and already-canonical values pass through, foreign colours convert, unparseable text is kept verbatim. - OklchColorDesk Raw field and ColorInput (text commit + native picker output) route through it. The desk's L/C/H sliders now populate from a pasted hex. Configurator-only; no framework tokens or version touched. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013BRVgKfEYocPCHz9KU96FN
…colour After a pasted hex is normalised to oklch(), designers lost sight of the colour they recognised. Show the real gamut-mapped sRGB hex next to the canonical value in both the brand desk and the generic colour input, so a hex-native workflow always has its reference (e.g. "oklch(0.744 0.181 56.4) · #ff8801"). Resolved off the preview canvas, reactive via previewVersion. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013BRVgKfEYocPCHz9KU96FN
|
Warning Review limit reached
Next review available in: 45 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThe configurator adds shared CSS color classification, canonical OKLCH/OKLAB conversion, safe reference handling, and hex previews. Both color editors use the normalization flow for commits and display resolved hex values, with tests covering classification and unavailable preview engines. ChangesColor normalization and configurator integration
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant ColorInput
participant normalizeColorInput
participant PreviewIframe
participant TokenEditor
User->>ColorInput: enter or pick CSS color
ColorInput->>normalizeColorInput: commit input and target space
normalizeColorInput->>PreviewIframe: resolve and convert color
PreviewIframe-->>normalizeColorInput: canonical color or unresolved result
normalizeColorInput->>TokenEditor: store canonical or pass-through value
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Greptile SummaryThis PR adds two quality-of-life improvements to the configurator's colour editing: any CSS colour format (hex, rgb, hsl, named, lab, lch, etc.) can now be pasted into colour fields and is normalised to the token's canonical space (OKLCH/OKLAB) via the browser's relative-colour syntax engine; and an always-visible sRGB hex reference is shown alongside the canonical value.
Confidence Score: 3/5Mostly safe, but a logic gap in normalizeColorInput causes pasted oklab values to be stored unchanged in oklch fields, silently breaking the L/C/H sliders. The cross-space conversion gap means pasting oklab into an oklch field stores the wrong format and leaves sliders stuck at hardcoded defaults. The rest of the feature is well-constructed. configurator/src/lib/colorConvert.ts needs the cross-space branch fixed in normalizeColorInput, and a matching test case added to colorConvert.test.ts. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["User input (paste / picker / blur)"] --> B["commit() / commitRaw()"]
B --> C["normalizeColorInput(value, target)"]
C --> D{colorSpaceOf}
D -->|"null (var ref / empty)"| E["Pass through unchanged"]
D -->|"oklch or oklab (canonical)"| F{"space === target?"}
F -->|"yes"| G["Pass through unchanged"]
F -->|"no: cross-space BUG"| H["Pass through unchanged - wrong space stored"]
D -->|"other (hex/rgb/hsl/named)"| I["convertColor(value, target)"]
I --> J["resolveColor via preview iframe"]
J -->|"starts with target prefix"| K["format to compact canonical string"]
J -->|"null / wrong prefix"| L["Fallback: raw text preserved"]
K --> M["onSet / onChange"]
E --> M
G --> M
H --> M
L --> M
style H fill:#fca5a5,stroke:#dc2626
%%{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"}}}%%
flowchart TD
A["User input (paste / picker / blur)"] --> B["commit() / commitRaw()"]
B --> C["normalizeColorInput(value, target)"]
C --> D{colorSpaceOf}
D -->|"null (var ref / empty)"| E["Pass through unchanged"]
D -->|"oklch or oklab (canonical)"| F{"space === target?"}
F -->|"yes"| G["Pass through unchanged"]
F -->|"no: cross-space BUG"| H["Pass through unchanged - wrong space stored"]
D -->|"other (hex/rgb/hsl/named)"| I["convertColor(value, target)"]
I --> J["resolveColor via preview iframe"]
J -->|"starts with target prefix"| K["format to compact canonical string"]
J -->|"null / wrong prefix"| L["Fallback: raw text preserved"]
K --> M["onSet / onChange"]
E --> M
G --> M
H --> M
L --> M
style H fill:#fca5a5,stroke:#dc2626
Reviews (1): Last reviewed commit: "feat(configurator): always show a hex re..." | Re-trigger Greptile |
…debounce picker Addresses review findings on the colour-paste feature: - normalizeColorInput now converts a value whose canonical space differs from the target (e.g. an oklab() pasted into an oklch field), instead of storing it verbatim and leaving the desk's L/C/H sliders stuck on their defaults. - format() accepts the CSS Color 4 `none` channel keyword (achromatic colours), treating it as 0, so those pastes convert instead of falling back to raw text. - ColorInput's native colour picker stores the raw hex live on `input` (fast, no per-drag iframe round-trip) and canonicalises once on `change` when the picker closes — also avoids oklch round-trip thumb jitter. Tests extended to cover cross-space conversion, the `none` channel, and alpha. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013BRVgKfEYocPCHz9KU96FN
Summary
Two related quality-of-life improvements to the configurator's colour editing, aimed at hex-native workflows.
1. Paste any CSS colour, stored canonical. Colour fields previously accepted only the token's own format, so a designer with a brand hex had to pre-convert to OKLCH by hand. Now any CSS colour the browser understands — hex (3/4/6/8),
rgb()/rgba(),hsl(), named colours,hwb,lab()/lch(),color(), evenoklab()— is normalised into the field's target space on commit. Conversion uses the live preview iframe's own colour engine via relative-colour syntax (oklch(from <input> l c h)), so the result matches exactly what the browser paints — no colour-math library, no drift.var()references and already-canonical values pass through untouched; unparseable text is kept verbatim so a paste is never silently dropped.2. Always-visible hex reference. After a pasted hex is normalised to
oklch(), the recognisable colour "disappeared". The real gamut-mapped sRGB hex now sits next to the canonical value in both the brand desk and the generic colour input (e.g.oklch(0.744 0.181 56.4) · #ff8801), so a hex-native workflow always has its reference. Resolved off the preview canvas, reactive as sliders/values change.Verified in-browser: pasting
#ff8800into the Primary source Raw field storesoklch(0.744 0.181 56.4), the L/C/H sliders populate, and the header reads… · #ff8801(the round-trip differs by 1/255 — imperceptible).Type
Checklist
core/*.css, no framework tokens, no version changesvelte-checkpasses (0 errors)tests/colorConvert.test.ts, 5 cases)check:doc-refspasses (CHANGELOG under## Unreleased)Notes
New
configurator/src/lib/colorConvert.ts:colorSpaceOf()classifies a value;convertColor()resolves the relative-colour expression through the probe and reformats to the compact convention (alpha preserved);normalizeColorInput()is the commit helper;previewHex()returns the painted sRGB hex for the reference. Wired intoOklchColorDesk(Raw field + header) andColorInput(text commit, native picker output, display). Pure classification/pass-through/fallback logic is unit-tested; the browser-native conversion itself is verified at runtime (can't run headless without the preview iframe).No version bump — versioning is handled manually.
🤖 Generated with Claude Code
Generated by Claude Code
Summary by CodeRabbit
rgb(),hsl(), named colors,lab(),lch(), andcolor().