Socket
Socket
Sign inDemoInstall

styled-variants

Package Overview
Dependencies
1
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    styled-variants

A scalable styled-component theming system that fully leverages JavaScript as a language for styles authoring and theming.


Version published
Weekly downloads
926
increased by60.49%
Maintainers
1
Created
Weekly downloads
 

Readme

Source

styled-variants

A scalable styled-component theming system that fully leverages JavaScript as a language for styles authoring and theming.


Table of contents

Why another theming library?

At Remine, we not only have multiple global themes (i.e. separate themes for different apps/stakeholders, with light and dark themes for each), but we also have multiple variants: size (e.g. small, large, etc), state (e.g. error, warning, etc), and type (e.g. primary, secondary, tertiary) with more to come. We couldn't find a library in the ecosystem that could support such a large number of variants with minimal code, so we decided to create one.

Most theming systems for styled-components available today spit out string values (e.g. styled-theming, styled-theme) which can add a code bloat since you still need to assign the theme value to a css property. styled-variants takes advantage of the first-class object functionality that styled-components has added in version 3.3.0 to help reduce this bloat and allow for cleaner, scalable theming.

Install

$ npm install --save styled-variants

Usage

See our Buttons example code if you'd rather read code to understand the use cases.

Basic

If we expect to write our HTML like this:

<!-- takes default/medium styles -->
<ThemedButton />

<!-- takes large styles -->
<ThemedButton size="large" />

<!-- takes small styles -->
<ThemedButton size="small" />

DIFFICULT TO READ

You'd normall use the string-based, extremely difficult to read code to dynamically style your components:
export const Button = styled.button`
    padding: ${props =>
        props.size === "large"
            ? "1em 1.2em"
            : props.size === "small"
            ? "0.3em 0.7em"
            : "0.7em 1em"};
    font-size: ${props =>
        props.size === "large"
            ? "1.2rem"
            : props.size === "small"
            ? "0.8rem"
            : "1rem"};
`;

Imagine what this would look like if we had even more size options or if "size" affected more css attributes!

EASIER TO READ

With styled-variants, not only can we see very easily what each variants prop value entails, but we can also read what each css value will interpolate to since we no longer have a bunch of conditionals bloating the code:
import styled from "styled-components";
import createTheme from "styled-variants";

const ButtonTheme = createTheme("Button");

const defaultSizeStyles = {
    padding: "0.7em 1em",
    fontSize: "1rem",
};

const sizeVariant = ButtonTheme.variant("size", {
    ...defaultSizeStyles,
    small: {
        padding: "0.3em 0.7em",
        fontSize: "0.8rem",
    },
    large: {
        padding: "1em 1.2em",
        fontSize: "1.2rem",
    },
});

export const ThemedButton = styled.button(sizeVariant);



Passing Props

Just like styled-components, styled-variants also supports passing of props via function:

import styled from "styled-components";
import createTheme from "styled-variants";

const ButtonTheme = createTheme("Button");

const defaultTypeStyles = {
    color: "white",
    border: ({ theme }) => `5px solid ${theme.colors.primary}`,
    backgroundColor: ({ theme }) => theme.colors.secondary,
};

export const typeVariant = ButtonTheme.variant("type", {
    ...defaultTypeStyles,
    secondary: {
        color: "black",
        backgroundColor: ({ theme }) => theme.colors.primary,
        borderColor: ({ theme }) => theme.colors.secondary,
    },
});

export const ThemedButton = styled.button(typeVariant);

Then we can use styled-components's ThemeProvider to inject a theme into the props of our styled-components:

import { ThemeProvider } from "styled-components";
import { ThemedButton } from "./ThemedButton.js";

const colors = {
    primary: "#09d3ac",
    secondary: "#282c34",
};

const MyApp = () => {
    return (
        <ThemeProvider theme={{ colors }}>
            <ThemedButton />
            <ThemedButton type="secondary" />
        </ThemeProvider>
    );
};



Boolean variants

If we have separate states (e.g. isDisabled, isActive, isOpen, etc) for each variant, we can easily incorporate those too:

const typeVariant = ButtonTheme.variant("type", {
    isDisabled: {
        opacity: 0.5,
        cursor: "default",
        pointerEvents: "none",
    },
    isActive: {
        boxShadow: "0px 0px 1px 1px purple",
    },
    secondary: {
        isDisabled: {
            opacity: 0.7,
        },
        isActive: {
            boxShadow: "0px 0px 1px 1px blue",
        },
    },
});

Then we can pass a prop value for isDisabled and isActive:

const MyApp = () => {
    const [isDisabled, setIsDisabled] = useState(false);

    return (
        <ThemeProvider theme={{ colors }}>
            <ThemedButton isDisabled={isDisabled} type="secondary" />
            <ThemedButton isDisabled={isDisabled} />
            <ThemedButton isDisabled={isDisabled} type="secondary" isActive />
        </ThemeProvider>
    );
};



Combining variants

Thankfully, styled-components allows for multiple sets of first class objects, so we can do the following to combine our variants:

/*** Insert previous examples here ***/

export const ThemedButton = styled.button(typeVariant, sizeVariant);



Pseudo class support

How to write pseudo classes:

import createTheme from "styled-variants";

const ButtonTheme = createTheme("Button");

const typeVariant = ButtonTheme.variant("type", {
    ...defaultTypeStyles,
    primary: {
        color: "green",
        "&:hover": {
            color: "limegreen",
        },
    },
    secondary: {
        color: "black",
        "&:focus, &:hover": {
            color: "purple",
        },
    },
});



Extending styled-components

If we have a styled-component already created, we can extend the styles by applying variants:

const sizeVariant = ButtonTheme.variant("size", {
    /* sizeVariant properties */
});

const Button = styled.button`
    padding: 0.7em 1em;
    fontsize: 1rem;
    color: blue;
`;

export const ThemedButton = styled(Button)(sizeVariant);



Contributing

Contributions are welcome. Standards have yet to be set but we will set these in the near future.

To see you changes as you make them, an example app has been created. You can run it with:

$ npm run example

License

MIT

Keywords

FAQs

Last updated on 14 Oct 2019

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc