Skip to content

Style Composition with Arrays #740

@jonavila

Description

@jonavila

Is your feature request related to a problem? Please describe.
I would like to request the ability to use arrays with the sx prop to compose styles

Describe the solution you'd like
Emotion's css prop accepts arrays for composition. I would like to have this support for Theme-UI.

Describe alternatives you've considered
An alternative would be to build a utility function using Theme-UI's css utility that an array of styles and converts the objects to the styles that can be consumed the Emotion's css prop. In this case, we would bypass sx prop and use the css prop directly.

Example:

import { css } from 'theme-ui';

const theme = {
    colors: {
        gray1: '#999999',
        darkGray3: '#666666',
        darkGray2: '#4a4a4a',
        darkGray1: '#323232',        
    }
    fonts: {
        body: '"Source Sans Pro", system-ui, sans-serif',
        heading: '"Source Sans Pro", system-ui, sans-serif',
        monospace: 'Monaco, Menlo, "Ubuntu Mono", Consolas, source-code-pro, monospace',
    },
    fontSizes: [12, 14, 16, 18, 24, 32, 48, 64, 72],
    fontWeights: {
        normal: 400,
        heading: 500,
        bold: 700,
    },
    lineHeights: {
        body: 1.25,
        heading: 1.125,
    },
    text: {
        base: {
            color: 'darkGray2',
        },
        muted: {
            color: 'gray1',
        },
    }
    headings: {
        base: {
            fontFamily: 'heading',
            fontWeight: 'heading',
            lineHeight: 'heading',
        },
    },
}

const themeCss = (style: SystemStyleObject | SystemStyleObject[]) => {
    // use some implementation of flattenDeep, like lodash or something custom
    const styles = Array.isArray(style) ? flattenDeep<SystemStyleObject>(style) : [style];

    return styles.map(s => css(s)(theme));
};

const baseStyles = themeCss([{ variant: 'headings.base' }, { variant: 'text.muted'}]);
const withFontSizeStyles = themeCss([defaultHeadingStyles, { fontSize: [1, 2, 3] }]);

// using the above styles with css prop
<h3 css={baseStyles}> Some Heading</h3>

<h3> css={withFontSizeStyles}>Some other Heading</h3>

This works well, but it would mean manually wrapping the styles with the custom built utility.

Additional context
PR #704, but this will give us an issue to discuss whether this functionality makes sense in Theme UI

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions