UI Styling Standard

The eslint plugin to enforce and educate on Atlassian's UI Styling Standard

no-unsafe-values

Blocks styles that are difficult or impossible to statically analyze.

Examples

Function calls

Incorrect

Function calls are blocked as arguments or as values, unless they are specified in allowedFunctionCalls (or in the default list).

import { css } from '@compiled/react';

function getStyles() {
    return { width: 100 };
}

const styles = css(getStyles());
import { css } from '@compiled/react';

function getWidth() {
    return 100;
}

const styles = css({
    width: getWidth(),
});

Correct

Use inline literals for static values.

import { css } from '@compiled/react';

const styles = css({ width: 100 });

Use the style prop for dynamic values.

const Component = ({ width }) => <div style={{ width }} />;

Some functions such as tokens() are allowed.

import { css } from '@compiled/react';
import { token } from '@atlaskit/tokens';

const styles = css({ padding: token('space.100') });

Dynamic keys

Incorrect

Dynamic keys are blocked, unless they are specified in allowedDynamicKeys (or in the default list).

import { css } from '@compiled/react';

const HOVER_SELECTOR = '&:hover';
const MARGIN = 'margin';

const styles = css({
    [HOVER_SELECTOR]: {
        [MARGIN]: 0,
    },
    [`${HOVER_SELECTOR} > p`]: {
        width: 100,
    },
});

Correct

Use literal values for pseudo-states and property names.

Don't use nested selectors, apply styles directly instead.

import { css } from '@compiled/react';

const styles = css({
    '&:hover': {
        margin: 0,
    },
});

const paragraphStyles = css({
    width: 100,
});

Statically written CSS at-rule keys may be annotated with a type-only satisfies expression. The annotation is erased at runtime, so it does not make the key unsafe:

import { css } from '@atlaskit/css';
import type MediaAboveSm from '@atlaskit/css/at-rules/media-above-sm';

const styles = css({
    ['@media (min-width: 48rem)' satisfies MediaAboveSm]: {
        padding: '8px',
    },
});

Variables

Incorrect

Variables are only allowed as values if they:

  • have a simple, static value
  • are defined in the same file
import { css } from '@compiled/react';
import { HEIGHT } from '../shared';

const styles = css({
    height: HEIGHT,
});

Correct

Use inlined values.

import { css } from '@compiled/react';

const styles = css({
    height: '32px',
});

Alternatively, define variables in the same file.

import { css } from '@compiled/react';

const HEIGHT = '32px';

const styles = css({
    height: HEIGHT,
});

Object access

Incorrect

Don't access object members in values.

import { css } from '@compiled/react';
import { token } from '@atlaskit/tokens';

const colors = {
    text: token('color.text'),
};

const styles = css({
    color: colors.text,
});

Correct

Use inlined values.

import { css } from '@compiled/react';
import { token } from '@atlaskit/tokens';

const styles = css({
    color: token('color.text'),
});

Spread elements

Incorrect

Don't use the spread operator in styles.

import { css } from '@compiled/react';
import { token } from '@atlaskit/tokens';

const subtleTextStyles = {
    color: token('color.text.subtle'),
};

const styles = css({
    ...subtleTextStyles,
    margin: 0,
});

Correct

Use the css prop to compose styles.

import { css } from '@compiled/react';
import { token } from '@atlaskit/tokens';

const subtleTextStyles = {
    color: token('color.text.subtle'),
};

const styles = css({
    margin: 0,
});

const Component = () => <div css={[subtleTextStyles, styles]} />;

Array values

Incorrect

Don't use array values. This syntax is not supported by Compiled, or most other CSS-in-JS libraries.

import { css } from '@compiled/react';
import { token } from '@atlaskit/tokens';

const boldMixin = { fontWeight: token('font.weight.bold') };

const styles = css({
    '&::before': [boldMixin, { color: token('color.text.danger') }],
});

Correct

Use a single object with inlined styles.

import { css } from '@compiled/react';
import { token } from '@atlaskit/tokens';

const styles = css({
    '&::before': {
        fontWeight: token('font.weight.bold'),
        color: token('color.text.danger'),
    },
});

Options

allowedDynamicKeys: [string, string][]

Use this to allow specified imports as dynamic keys, in addition to the built-in allow-list.

Each value should be a two-element array. The first item is the entrypoint, and the second item is a named export.

Default imports are not supported.

// eslint.config.cjs

// ...
      rules: {
        '@atlaskit/eslint-plugin-ui-styling-standard/no-unsafe-values': [
          'error',
          {
            allowedDynamicKeys: [
              ['@atlaskit/primitives/responsive', 'media'],
            ]
          },
        ],
        // ...
      },
// ...

allowedFunctionCalls: [string, string][]

Use this to allow specific functions to be called, in addition to the built-in allow-list.

Each value should be a two-element array. The first item is the entrypoint, and the second item is a named export.

Default imports are not currently supported.

// eslint.config.cjs

// ...
      rules: {
        '@atlaskit/eslint-plugin-ui-styling-standard/no-unsafe-values': [
          'error',
          {
            allowedFunctionCalls: [
              ['@atlaskit/tokens', 'token'],
            ]
          },
        ],
        // ...
      },
// ...

importSources: string[]

By default, this rule will check styles using:

  • @atlaskit/css
  • @atlaskit/primitives
  • @compiled/react
  • @emotion/react
  • @emotion/core
  • @emotion/styled
  • styled-components

Override this list with the importSources option, which accepts an array of package names.

Was this page helpful?
We use this feedback to improve our documentation.
  • Design system
    • Get started
    • Foundations
    • Components
    • Rovo UI
    • Tools
    • Release phases
    • Contact us
© 2026 AtlassianTrademark, (opens new window)Privacy, (opens new window)License