Skip to content

Add custom brand colors via ordered colors prop (web + SwiftUI) - #7

Open
devinpatell wants to merge 1 commit into
Jakubantalik:mainfrom
devinpatell:claude/border-beam-prop-review-6c9ad3
Open

Add custom brand colors via ordered colors prop (web + SwiftUI)#7
devinpatell wants to merge 1 commit into
Jakubantalik:mainfrom
devinpatell:claude/border-beam-prop-review-6c9ad3

Conversation

@devinpatell

Copy link
Copy Markdown

Closes #4.

What this adds

An ordered list of custom colors on both platforms:

<BorderBeam colors={['#e63946', '#457b9d', '#2a9d8f']}></BorderBeam>
Card().borderBeam(.md, colors: [.purple, .pink])
  • Colors cycle in order through the palette's gradient stops — the first color is the most prominent; a single color gives a monochrome brand beam.
  • All hand-tuned geometry (positions, sizes, per-stop alphas) of the colorful reference palette is preserved — only the colors are swapped, across all five palette families (border ring, small, line, line-inner, line-bloom).
  • colors takes precedence over colorVariant and always renders with static hue (like mono) so brand colors stay exact; the tuned brightness/saturate still apply as a static filter.
  • Accepts hex (#rgb, #rgba, #rrggbb, #rrggbbaa) and rgb()/rgba() with number or percentage channels; alpha is ignored (layers manage their own opacity). Entries that fail to parse are skipped; if nothing parses, colorVariant applies. On iOS, [Color] resolves against the live SwiftUI environment so adaptive colors track appearance changes.

Cross-platform parity

The derivation contract lives in beam-spec.json § customColors (reference variant, forced static colors, line-bloom recolor map [0,1,0,1,2,3,4]), so the web (buildCustomPalettes in styles.ts) and iOS (BeamCustomPalette.swift) implementations recolor the same spec tables and cannot silently drift. Executing both derivations against the same input and diffing numerically produced an exact match across every family, both themes, all alphas.

Verification

  • Presets untouched: generated CSS byte-identical to main across all 80 preset combinations (5 sizes × 4 variants × 2 themes × 2 static modes).
  • Web: typecheck + build clean; 18-assertion parser/regression suite (attack inputs incl. malformed rgb, trailing garbage, NaN-shaped numerals); rendered-browser verification of all 5 sizes × 2 themes with live-DOM assertions (brand colors present, hue-shift absent, reference alphas retained).
  • iOS: 14/14 tests via both swift test and xcodebuild test with compiled Metal shaders; new tests pin the full line-bloom color map in both themes, cycling + alpha retention in every family, sRGB (gamma) color resolution, and a custom-color snapshot matrix.
  • An adversarial review pass (three independent reviewers instructed to refute) surfaced 10 findings — parser holes, a memo-key collision, missing static filters, init-time color resolution — all fixed and re-verified.

Demos

Both demos gained a Custom entry in the palette switcher with live ordered color editors (1–5 colors, add/remove): native ColorPicker row in the SwiftUI demo, color inputs in the web playground. The playground's generated snippet updates to the real colors={[…]} usage as you edit.

Notes

  • BeamColorVariant is intentionally left unextended (a new case would be source-breaking for String-raw-value + CaseIterable consumers); custom colors are a separate parameter on both platforms.
  • Suggested follow-up: a CI fixture that re-runs the web↔iOS palette diff automatically.

🤖 Generated with Claude Code

Implements Jakubantalik#4: an ordered list of user colors that recolors every palette
family while preserving the hand-tuned geometry and per-stop alphas of the
'colorful' reference. Colors cycle through the gradient stops (the first is
the most prominent), always render with static hue so brand colors stay
exact, and take precedence over colorVariant; invalid or empty input falls
back to the preset.

- Web: strict color parsing (hex / rgb / rgba, percentage channels, values
  clamped like CSS), custom palette builder threaded through every CSS
  generator, palette memoized per distinct color list
- iOS: BeamCustomPalette recolors the spec's reference tables; colors
  resolve against the live SwiftUI environment so adaptive colors track
  appearance; custom palettes keep the tuned brightness/saturate as a
  static filter (and the line bloom keeps its blur)
- Spec: customColors contract (reference variant, forced static colors,
  line-bloom recolor map) so ports cannot drift
- Tests: full bloom-map + cycling coverage in both themes, custom-color
  snapshot matrix; 14/14 pass incl. under xcodebuild with compiled Metal
  shaders; preset output verified byte-identical to HEAD across all 80
  combinations
- Demos: "Custom" palette option with live ordered color editors (SwiftUI
  ColorPicker row / web playground color inputs, 1-5 colors, add/remove)
- Docs: README custom colors section, prop docs, changelog; version 1.5.0

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

Custom colors please

1 participant