At work we have a design system for our colours, for example
red-1 red-2 red-3
green-1 green-2 green-3
The hex codes behind these might change, but also a component or set of components might, for example, change their colour from red-1 to red-2.
We also want to handle dark mode. In light mode you might have a background as red-1, but in dark mode it needs to be green-1. This means we might want semantic colours as well, like:
background-1 (red-1 in light mode, green-1 in dark mode) foreground-1
etc.
I know that the simplest way to handle dark mode with the least boilerplate is to use Asset catalogues. So you'd have a color asset called background-1, and that would have a dark and light mode color.
The problem is, that color can't reference other custom colors (like red-1). Instead you have to manually put in the hex code, meaning if red-1 changes, you've got a real headache on your hands in changing all the semantic colors that use red-1.
On the other hand, as far as I can see, if you go down the programmatic route (i.e. use an asset catalogue for your red-1, green-1, and a class/enum for your semantic colors) you need to add a ton of boilerplate to each class that uses these colors (traitCollectionDidChange, I think?).
Can anyone think of a happy medium here? Happy to use external tools if one exists.
EDIT: One idea I had:
- Colors.xcassets - this has our semantic colours
- ColorSystem.json - this has the real colours and their hexes (red-1 etc.)
- ColorMap.json - this has a marrying of the two
- Build phase script to take ColorSystem.json and ColorMap.json and marry the two to generate a fresh Colors.xcassets system.
Then whenever we change a hex, we change ColorMap.json. Whenever we change a semantic color to use a different "real" color, we changed ColorMap.json.