struct UI::DesignTokens::Color

Overview

Canonical color.

The OKLCH triple is the source of truth; the sRGB triple is the deterministic bake used by native renderers. Constructors taking OKLCH compute the sRGB; constructors taking sRGB store sRGB verbatim and leave OKLCH nil — that nil case is reserved for platform-system color references that must not round-trip (e.g., a sentinel NSColor.labelColor which the AppKit renderer resolves separately).

Sentinel values

Color::SYSTEM_ACCENT is a sentinel that means "resolve to the platform's native accent color at render time": UIColor.tintColor / the SwiftUI .accentColor cascade on iOS, NSColor.controlAccentColor on macOS, the CSS Color 4 AccentColor system keyword on web, and ?attr/colorPrimary on Android. Renderers detect the sentinel via Color#system_accent? and route to the platform-native accent path instead of consuming the baked sRGB triple. Phase 6.12A introduced the sentinel as part of the library-identity pivot — Tokens.default brand_primary family resolves to system accent so consumers who do not call .with_brand(...) get Apple-HIG-correct system blue / mac control accent rather than an opinionated library palette colour.

Defined in:

ui/design_tokens.cr

Constant Summary

SYSTEM_ACCENT = new(l: nil, c: nil, h: nil, r: 0.0, g: 0.0, b: 0.0, alpha: 0.0, sentinel: :system_accent)

Sentinel meaning "platform-native accent color". See the struct-level docstring for renderer mapping. Constructed with zeroed sRGB / nil OKLCH because the bake is unused — every consumer must guard on #system_accent? before reading r/g/b/alpha.

Constructors

Instance Method Summary

Constructor Detail

def self.hex(value : String) : Color #

Construct from a "#rrggbb" or "#rrggbbaa" hex string.


[View source]
def self.new(l : Float64 | Nil, c : Float64 | Nil, h : Float64 | Nil, r : Float64, g : Float64, b : Float64, alpha : Float64 = 1.0, sentinel : Symbol | Nil = nil) #

[View source]
def self.oklch(l : Float64, c : Float64, h : Float64, alpha : Float64 = 1.0) : Color #

Construct from an OKLCH triple. Lightness on [0, 1], chroma typically on [0, 0.4], hue in degrees on [0, 360). Alpha on [0, 1].

If the triple is out of gamut, chroma is reduced until the result lies within sRGB — the hue and lightness are preserved exactly.


[View source]
def self.parse_oklch(css : String) : Color #

Construct from a CSS-style oklch() string: "oklch(0.52 0.16 50)" or "oklch(0.66 0.15 50 / 0.58)". Whitespace-tolerant.


[View source]
def self.rgb(r : Float64, g : Float64, b : Float64, alpha : Float64 = 1.0) : Color #

Construct from an sRGB triple on [0, 1]. The OKLCH counterpart is computed and stored too, so #to_oklch_css is meaningful.


[View source]

Instance Method Detail

def ==(other : Color) : Bool #

Equality includes the sentinel kind so Color::SYSTEM_ACCENT is not accidentally equal to a colour that happens to bake to all zeros (which would otherwise compare equal via the r/g/b/alpha fields). Two sentinels of the same kind are equal regardless of their (unused) bake.


[View source]
def alpha : Float64 #

[View source]
def b : Float64 #

[View source]
def brand_tint_action : Symbol #

Phase 6.12A — pure decision the AppKit / UIKit renderers use to route a brand colour through LibSwiftKitBridge. Lives on Color (not on the renderer) so the assertion is testable without linking the native bridge. The renderers' #brand_tint_action methods delegate here.

Returns :clear for the SYSTEM_ACCENT sentinel — the renderer calls apsk_runtime_clear_brand_tint so SwiftUI's automatic .accentColor cascade resolves to the platform-native accent. Returns :set for any opinionated colour — the renderer calls apsk_runtime_set_brand_tint(r, g, b, a) with the baked sRGB triple, which propagates as a SwiftUI .tint() cascade.


[View source]
def c : Float64 | Nil #

[View source]
def copy_with(l : Float64 | Nil = @l, c : Float64 | Nil = @c, h : Float64 | Nil = @h, r : Float64 = @r, g : Float64 = @g, b : Float64 = @b, alpha : Float64 = @alpha, sentinel : Symbol | Nil = @sentinel) : Color #

Returns a new Color with the given fields replaced (manual copy_with because Color is a struct, not a record). The #sentinel field propagates by default so SYSTEM_ACCENT.copy_with(alpha: 0.5) stays a sentinel; callers that intend to materialise a sentinel into a concrete colour must pass sentinel: nil explicitly.


[View source]
def g : Float64 #

[View source]
def h : Float64 | Nil #

[View source]
def l : Float64 | Nil #

[View source]
def r : Float64 #

[View source]
def sentinel : Symbol | Nil #

nil for normal colours; :system_accent for Color::SYSTEM_ACCENT. The ivar is intentionally narrow today (single sentinel kind) but the type is Symbol? so future sentinels (e.g. :label, :system_background) can join the same predicate-driven dispatch without a struct shape change.


[View source]
def system_accent? : Bool #

Predicate so renderers and generators can detect the sentinel without inspecting @sentinel directly.


[View source]
def to_android_argb : Int32 #

Packed 0xAARRGGBB ARGB int for Android (the deferred Android generator consumes this through the Crystal model rather than computing it again). SYSTEM_ACCENT raises AndroidRendererNotImplemented — the honest Android emission is ?attr/colorPrimary, not an ARGB literal, and that is the deferred Android generator's responsibility.


[View source]
def to_css : String #

CSS-context serialization. For SYSTEM_ACCENT, returns the CSS Color Module Level 4 system colour KEYWORD AccentColor (capitalised, no hyphen — distinct from the accent-color PROPERTY that styles form controls). Browsers resolve AccentColor to the OS's user- selected accent. For all other colours, returns the canonical oklch(...) form (the most expressive CSS representation).


[View source]
def to_hex : String #

"#rrggbb" or "#rrggbbaa" hex string. Raises for SYSTEM_ACCENT — a hex literal cannot represent "resolve to the platform accent".


[View source]
def to_oklch_css : String #

CSS oklch(L C H / alpha) string. Component digits are formatted with 3 decimal places for L/C and 2 for H so the generator output is deterministic regardless of float printing quirks.

SYSTEM_ACCENT returns the CSS Color 4 AccentColor keyword so the generated CSS dist file (web_tokens.css) lowers system-accent tokens to a single platform-resolved value rather than baking a specific sRGB triple.


[View source]
def to_rgb_triple_css : String #

Generator-friendly "r g b" triple (space-separated 0..255 ints) for use inside CSS .rgb() / .oklch() paired tokens. Raises for the SYSTEM_ACCENT sentinel — there is no honest channel triple to emit; callers must guard on #system_accent? before composing a paired-token expression around this helper.


[View source]
def to_rgba_css : String #

CSS rgba(r, g, b, alpha) string with integer 0..255 channels. SYSTEM_ACCENT returns the CSS Color 4 AccentColor keyword (an rgba(0, 0, 0, 0) literal would silently render fully transparent black — a worse failure mode than emitting the platform token).


[View source]
def to_s(io : IO) : Nil #
Description copied from struct Struct

Same as #inspect(io).


[View source]
def to_swift : String #

SwiftUI-context serialization. For SYSTEM_ACCENT, returns the SwiftUI environment accent Color.accentColor. For all other colours, returns the explicit sRGB Color(...) literal that #to_swift_color produces.


[View source]
def to_swift_color : String #

SwiftUI Color literal source. SYSTEM_ACCENT returns the SwiftUI environment accent Color.accentColor (the generated swift dist file reads public static let brandPrimary = SwiftUI.Color.accentColor, which is the SwiftUI cascade-friendly form).


[View source]