Skip to content

Return a hex string for dynamic and grayscale colors in toHex - #15

Merged
Jeehut merged 2 commits into
mainfrom
wip/tohex-dynamic-colors
Oct 15, 2026
Merged

Jeehut merged 2 commits into
mainfrom
wip/tohex-dynamic-colors

Conversation

@Jeehut

@Jeehut Jeehut commented Oct 14, 2026

Copy link
Copy Markdown
Member

Overview

Color.toHex(alpha:) read cgColor, which is nil for dynamic colors (.primary, .blue, .systemBlue, …), so it returned nil for them. For colors in a gray color space it also returned nil (two components), and Display P3 colors were reported with their raw P3 numbers. It now reads sRGB components through UIColor/NSColor, which resolve dynamic colors, and clamps wide-gamut values to sRGB.

Color (macOS, dark) main This branch
.blue nil 0091FF
.red / .gray / .primary nil FF4245 / 98989D / FFFFFF
CGColor(gray: 0.5) nil 929292
Display P3 (0.5, 0.8, 0.3) 80CC4D (raw P3) 64CE2F (sRGB)
sRGB, white, black unchanged unchanged

Dynamic colors resolve against the traits current at the time of the call. The doc comment says so and points to rgbo(in:) for the color a view actually displays.

Split out of #7.

How this was verified

Red, with main's ColorExt.swift:

✘ hexOfDynamicColors(): color.toHex() is nil
✘ hexOfDisplayP3ColorIsConvertedToSRGB(): toHex() == "64CE2F"
✘ hexOfGrayscaleColor(): gray.toHex() is nil
✔ hexRoundTrips(), hexOfWideGamutColorIsClampedToSRGB()
✘ Test run with 5 tests in 1 suite failed with 3 issues.

Green, this branch:

✔ Test run with 5 tests in 1 suite passed.

toHex read the components from cgColor, which is nil for dynamic
colors like .primary or .systemBlue and has only two components for
colors in a gray color space, so it returned nil for all of them. It
now reads sRGB components through UIColor/NSColor, which resolves
dynamic colors against the current appearance, and clamps wide-gamut
components to the sRGB range hex can represent.
toHex resolves dynamic colors against the traits current at the time of
the call, which usually differ from a view's environment; the doc
comment now says so and points to rgbo(in:). A new test pins that an
in-gamut Display P3 color is converted to sRGB instead of reporting its
raw P3 components.
@Jeehut
Jeehut merged commit 2feefca into main Oct 15, 2026
5 checks passed
@Jeehut
Jeehut deleted the wip/tohex-dynamic-colors branch October 15, 2026 09:35
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.

1 participant