Joseph
Joseph

Reputation: 7755

How to Access Theme Colors Through SX in Material UI

How do I access the colors of the theme through using sx? I tried below but it doesn't work.

<Card
  sx={{
    border: "2px solid primary.main",
  }}
>

Upvotes: 17

Views: 14908

Answers (3)

jbyrd
jbyrd

Reputation: 5585

I wanted to go a little more in depth on Tim's answer above. First, here's some documentation on the sx property itself, and you should also be familiar with the theme object.

But perhaps a better starting point is understanding that there are 2 ways to access theme colors through the sx property:

  1. Implicitly (for theme-mappable CSS properties)
  2. Explicitly (using a function callback)

Implicitly (for Theme-Mappable CSS Properties)

<Card
  sx={{
    borderColor: 'primary.main'
  }}
>

So how/why exactly does this work? This page documents all the style properties you can use for sx (in addition you can use any CSS property) and if/how they are linked with the theme. So first that means not all properties link to the theme. If you look at the Properties reference table, the last column ("Theme mapping") tells you if/how the property is linked to the theme object. Let's take a look at a screen shot from that reference table:

MUI system property reference table

At the bottom, you can see the display property is not linked to the theme object. However, near the top, you can see the borderColor property is linked to the theme object, and the linking is described as theme.palette[value]. That means that the value you give it can be a property of the theme.palette object. So now let's take a look at the default theme object to see what values we can pass:

MUI default theme object

We can see the theme.palette object includes a bunch of properties like common, primary, secondary, etc., and underneath these properties, you get actual color values, such as main, which is #1976d2. So putting it altogether, when we specify a borderColor of primary.main, that is grabbing the value of theme.palette.primary.main. Technically we could even specify a theme.palette property not intended for a border color, like divider - that would give a border color of rgba(0, 0, 0, 0.12).

Explicitly (Using a Function Callback)

You can also pass a function callback, which gives you explicit access to the theme base object, and then you can return any value you want using any property of the theme object. In this way we could, for example, specify all the border properties in one go like this:

<Card
  sx={{
    border: (theme) => `2px solid ${theme.palette.primary.main}`,
  }}
>

Upvotes: 15

Tim Hallowell
Tim Hallowell

Reputation: 307

As an alternative, you should be able to do:

<Card sx={{border: "2px solid", borderColor: "primary.main"}}>

The shorthand "border" doesn't seem to access the theme colors properly. Hope that's helpful.

Update: Just wanted to add to this that you could also use a function value to set the border color according to your theme.

    <Card sx={{border: "2px solid", borderColor: (theme) => theme.palette.primary.main}}>

Upvotes: 22

Anton Bahurinsky
Anton Bahurinsky

Reputation: 456

The useTheme() hook will help:

export default function App() {
  const theme = useTheme()
  return <Card sx={{ border: `2px solid ${theme.palette.primary.main}` }}>...
}

Upvotes: 2

Related Questions