Help me come up with the right name: `ColorScheme.select()`

I do quite a lot of these:

colorScheme == .light ? 1.0 : -1
colorScheme == .light ? Color.blue : .yellow
colorScheme == .light ? EdgeInsets(...) : EdgeInsets(...)

So I define this:

extension ColorScheme {
    func select<T>(_ light: T, _ dark: T) -> T {
        self == .light ? light : dark
    }
}

so can do this:

colorScheme.select(1.0, -1.0)

I want to make it short and clear. But select maybe not the best name for this? value(...)?

IMO, you should invert the priorities of the API. The property should be named insets and the implementation should be switching over the color scheme to return the right value.

If you do have a lot of these, another pattern I've used is the 'palette'. Basically you have a type like Palette<T>(light: T, dark: T) and then you have a method Palette.forColorScheme(_ scheme: ColorScheme) -> T (or possibly a subscript) which returns the appropriate value for the supplied state/scheme/etc.

So you suggest this:

Palette(0.5, -0.5)[colorScheme]

okay, so I will do this:

extension ColorScheme {
    func callAsFunction<T>(_ light: T, _ dark: T) -> T {
        self == .light ? light : dark
    }

    func callAsFunction<T>(_ palette: (T, T)) -> T {
        self == .light ? palette.0 : palette.1
    }
}
colorScheme(0.5, -0.5)
let palette = (Color.blue, Color.yellow)
...
colorScheme(palette)

I mean you can? Seems like confusing/unnecessarily terse API though. At least label your function parameters. Your exact needs are a little unclear but with something like a Palette approach you would define a struct like ViewProperties { let insets: EdgeInsets; let color: UIColor; let offset: CGFloat } and that would be the palette value. So you could do let properties = palette[colorScheme] once and then simply use properties.insets, properties.color etcetera.

I understand what "palette" is now. My ColorScheme dependent values are ad hoc on the spot where it's applied, Housing them inside a Palette struct is better. There is a little complication: some of these values depend on layoutDirection, I need to think about how to handle that.

Thanks!

This depends on your application's design but either you want Appearance { let background: Palette<UIColor> } or you want Appearance { let background: UIColor } paired with Palette<Appearance>, basically depends at what level you want to allow for color scheme variation.

(Exact type naming prolly should vary depending on above choice too.)

1 Like

Yeah if you need to support multiple axes of variation, you will have to extend the types to be able to handle that more dynamically. There are many approaches in this domain.

1 Like
Terms of Service

Privacy Policy

Cookie Policy