Theme-ui: @theme-ui/color functions do not work in "long-hand" declarations, e.g. boxShadow

Created on 21 Mar 2020  路  5Comments  路  Source: system-ui/theme-ui

Describe the bug
I would have expected that color functions like transparentize('primary', 0.7) work in template strings for long-hand declarations like boxShadow, especially since there is no short-hand boxShadowColor available.
Unfortunately, that does not work.

To Reproduce
Steps to reproduce the behavior:

  1. Install @theme-ui/[email protected]
  2. Declare a style with the sx prop on an element like so:
const Example = props => (
  <div
    {...props}
    sx={{
      boxShadow: `0 0 1px 4px ${transparentize('primary', 0.5)}, 0 0 1px 8px ${transparentize('primary', 0.7)}`,
      height: `40px`,
      width: `40px`,
      transition: 'box-shadow 0.25s ease-in-out',
      ':hover': {
        boxShadow: `0 0 1px 12px ${transparentize('primary', 0.7)}, 0 0 1px 20px ${transparentize('primary', 0.9)}`,
      },
    }}
  />
);

Additional context
Workaround using css custom properties:

const Example = props => (
  <div
    {...props}
    sx={{
      '--box-shadow-color-light': transparentize('primary', 0.9),
      '--box-shadow-color-med': transparentize('primary', 0.7),
      '--box-shadow-color-dark': transparentize('primary', 0.5),
      boxShadow: `0 0 1px 4px var(--box-shadow-color-dark), 0 0 1px 8px var(--box-shadow-color-med)`,
      height: `40px`,
      width: `40px`,
      transition: 'box-shadow 0.25s ease-in-out',
      ':hover': {
        boxShadow: `0 0 1px 12px var(--box-shadow-color-med), 0 0 1px 20px var(--box-shadow-color-light)`,
      },
    }}
  />
);

Most helpful comment

To use @theme-ui/color functions in properties like boxShadow, you can manually pass the theme object with a functional value (this isn't an ideal API, but should work with the current release):

boxShadow: theme => `0 0 2px 4px ${transparentize('primary', 0.9)(theme)}`,

All 5 comments

Just as a side note to your original question. It might be simpler to instead use the shadows property on the theme. Your shadows will be more consistent as you won鈥檛 need to provide inline values to either theboxShadow property or the transparentize function.

To use @theme-ui/color functions in properties like boxShadow, you can manually pass the theme object with a functional value (this isn't an ideal API, but should work with the current release):

boxShadow: theme => `0 0 2px 4px ${transparentize('primary', 0.9)(theme)}`,

manually pass the theme object with a functional value

boxShadow: theme => `0 0 2px 4px ${transparentize('primary', 0.9)(theme)}`,

How do you do this in eg. a variant object?

@ekafyi you don't really need whole theme there. Just { colors } are enough.

Variant objects are just style objects, so AFAIK it should just work like in jxnblk's snippet.


Another thing we can consider, is computing all possible "derived" colors ahead of time. I like to do this to stay consistent.

import { alpha, mix } from "@theme-ui/color";

const light = {
  text: "#020202",
  background: "#fff",
  primary: "#0633f0",
  muted: "#edf1ff",
};

type BaseColorMode = typeof light;

const dark: BaseColorMode = {
  text: "#f0f0f0",
  background: "#031420",
  primary: "#80a9ff",,
  muted: "#1f262e",
};

const soft: BaseColorMode = {
  text: "#182522",
  background: "#f9f3ea",
  primary: "#ca3030",
  muted: "#ebe0d2",
};

const deriveAdditionalColors = (colors: BaseColorMode) => {
  return {
    ...colors,
    text092: alpha("text", 0.92)({ colors }),
    mutedPrimary09: mix("muted", "primary", 0.9)({ colors }),
  };
};

export type ColorMode = ReturnType<typeof deriveAdditionalColors>;

export const colorModes = {
  light: deriveAdditionalColors(light),
  dark: deriveAdditionalColors(dark),
  soft: deriveAdditionalColors(soft),
}

export type ColorModeName = keyof typeof colorModes;

@hasparus I鈥檓 good to close this since it seems like we鈥檙e not planning to change this behavior

Was this page helpful?
0 / 5 - 0 ratings

Related issues

moshemo picture moshemo  路  3Comments

jxnblk picture jxnblk  路  4Comments

johno picture johno  路  3Comments

mxstbr picture mxstbr  路  3Comments

LeunensMichiel picture LeunensMichiel  路  3Comments