mui / material-ui

Material UI: Ready-to-use foundational React components, free forever. It includes Material UI, which implements Google's Material Design.
https://mui.com/material-ui/
MIT License
92.48k stars 31.87k forks source link

Type safe colors #26475

Open dstoyanoff opened 3 years ago

dstoyanoff commented 3 years ago

As discussed in #13875, there is currently support for specifying the colors, based on the configuration in the theme in the following format: "common.white". For example:

<Typography color="common.white">text</Typography>

This works great, but it is not type safe. With the introduction of Template Literal Types in TypeScript, I believe that this should now be possible to ensure the type-safety.

siriwatknp commented 3 years ago

"it is not type safe", Do you mean there is an error or it is not showing value suggestion?

eps1lon commented 3 years ago

With the introduction of Template Literal Types in TypeScript, I believe that this should now be possible to ensure the type-safety.

This is definitely the plan. But we have to wait for TypeScript 4.0 to reach end-of-life. Until then we still have to support TypeScript 4.0 and the additional effort of shipping types for multiple TypeScript versions is probably not worth the effort. If people are interested in it, they can upvote the issue.

dstoyanoff commented 3 years ago

"it is not type safe", Do you mean there is an error or it is not showing value suggestion?

Hey, I mean there is no suggestion and/or validation of the value that was passed. This is especially problematic in cases of refactoring, where this cannot be automatically replaced.

siriwatknp commented 3 years ago

"it is not type safe", Do you mean there is an error or it is not showing value suggestion?

Hey, I mean there is no suggestion and/or validation of the value that was passed. This is especially problematic in cases of refactoring, where this cannot be automatically replaced.

Agreed, that would be nice to have but from my understanding color prop also accept any string like <Typography color="#ff5252" />. I don't see that it is currently possible in typescript right?

image

https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wG4AocmATzCTgAUUAbJGGJAYQmejgF4CYKKBRRqAOhApgAO3xwAPgQDOSNBFkATMZOlz8lSjTpxuvKAxxgBjFmw7m+ylTBGyA5pUwBXWRmBNOAAVWggPKBQwAAtqAAphCDAVAC44AG84DQs0p0trOABfAEoM8jgKuCIYHyhZOAAeLWAANzgAegA+ckLKBu7KxtDICKjYrJ5ofgAiAGJMAFZFxemOgcqG4fDImOoJixnhUXEpGVlVrvIGrqA

eps1lon commented 3 years ago

I don't see that it is currently possible in typescript right?

It should be with template literal types but we would need to experiment if we can cover every possible color and if that's viable. Better autocomplete would already be a good first step.

import React from 'react';

type NamedColor = 'primary' | 'secondary'
type ColorVariant = 'main' | 300 | 400 | 500

// too complex to represent
// type HexNumber = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | number
// type HexColorTriplet = `${HexNumber}${HexNumber}${HexNumber}${HexNumber}${HexNumber}${HexNumber}`
type HexColorTriplet = string

type PaletteColor = `#${HexColorTriplet}` | `${NamedColor}.${ColorVariant}`

type ColorProp = PaletteColor

function Typography(props: { color: ColorProp }) {
    return <div />
}

<>
    <Typography color="#f5f5f5" />
    <Typography color="primary.main" />

    <Typography
        // @ts-expect-error
        color="tertiary.main" />
</>

Playground Link

Raicuparta commented 3 years ago

Sounds like trying to type every possible css color might be a pretty big task with a lot of gotchas. There must be some other project that did this, but I'm not finding anything.

maapteh commented 1 year ago

chakra-ui did this