Rethinking Our Color System: A Type-Safe Approach in Swift
Our design system1 provides colors for three different contexts: background, foreground, and borders. Each color can exist in four different states: normal, hovered, disabled, and pressed. Historically, we modeled this using a UIColor subclass that exposed properties for different states. When the instance was used as is, it implicitly represented the normal variant. While this approach was convenient—since developers never had to manually reference the normal state—it had trade-offs. As customization expanded and dark mode support became essential, we ran into a major issue: our subclass didn’t work with UIColor’s dynamic theming mechanism. It turns out, subclassing UIColor is possible but not recommended2.