Platzily UI Styling API

Styling API provide the user a way to style its components, also Platzily UI components are styled using @platzily-ui/styling.

Installation

To install and save in your package.json dependencies, run:

With npm

npm install @platzily-ui/styling

With yarn

yarn add @platzily-ui/styling

Getting started

First create a theme, you can use the createTheme helper function.

import { createTheme } from '@platzily-ui/styling';

export const theme = createTheme();

createTheme could receive a not complemeted Theme Object as a param, this way the user could customize the theme.

If no theme is passed the function will use the default theme, is no option is passed the function will use its default value.

The default theme looks like this:

  {
    palette: {
      primary: {
        main: '#19213c',
        secondary: '#454C62',
        tertiary: '#717788'
      },
      secondary: {
        main: '#97c343',
        secondary: '#AACE68',
        tertiary: '#BCD88D'
      },
      tertiary: {
        main: '#2F8CCC',
        secondary: '#56A2D5',
        tertiary: '#7EB7DF'
      },
      success: {
        main: '#43B839',
        secondary: '#075500'
      },
      warning: {
        main: '#C3B643',
        secondary: '#5C4E00'
      },
      info: {
        main: '#1198FF',
        secondary: '#2F8CCC'
      },
      error: {
        main: '#C34343',
        secondary: '#610002'
      },
      neutral: {
        main: '#273B46',
        secondary: '#7E95A5',
        tertiary: '#F4F8FB',
        light: '#FFFFFF',
        dark: '#000000',
      },
    },
    spacing: 5,
    radius: 5,
    elevations: [
      '0 0px 4px rgba(0, 0, 0, 0.25)',
      '0 1px 4px rgba(0, 0, 0, 0.25)',
      '0 2px 4px rgba(0, 0, 0, 0.25)',
      '0 3px 6px rgba(0, 0, 0, 0.25)',
      '0 4px 8px rgba(0, 0, 0, 0.25)',
      '0 6px 12px rgba(0, 0, 0, 0.25)',
      '0 8px 16px rgba(0, 0, 0, 0.25)',
      '0 12px 24px rgba(0, 0, 0, 0.25)',
    ]
  }

After the theme is created you need to wrap your application using the ThemeProvider and pass the theme as a prop

import { ThemeProvider } from '@platzily-ui/styling';
import App from './App';
import theme from './theme';

export default function Root() {
  return (
    <ThemeProvider theme={theme}>
      <App/>
    </ThemeProvider>
  );
}

After this is done you're ready to generate styles.

To generate styles use the createStyleSheet API.

import { createStyleSheet } from '@platzily-ui/styling';

const useStyleSheet = createStyleSheet((theme, props) => {
  return {
    root: {
      display: 'flex',
      justifyContent: 'center'
    },
    box: {
      backgroundColor: props.color || theme.palette.primary.main,
      width: 200,
      height: 200
    }
  };
}, { key: 'StyledBox' });

export default function StyledBox(props) {
  const { classes } = useStyleSheet(props);

  return (
    <div className={classes.root}>
      <div className={classes.box}/>
    </div>
  );
}

After that you just have to call your component:

<StyledBox/>

The code above will result in:

You could compose using the props approach like this

<StyledBox color="pink"/>

The code above will result in:

createStyleSheet

This is the principal function you'll be using to generate styles. It receive two params

  • styles: This is a function or an object, if a function is used it receives the global theme and the props as parameters. It should always return an object.
  • config: The config object receive a unique key called key, it is used to prepend a string to the class resulting of the styles object, if no config object is pased platzily-ui will be used.

A createStyleSheet invoke looks like this:

import { createStyleSheet } from '@platzily-ui/styling';

// Look how the styles function receive theme and props, the props are available if you
// pass the component props to the useStyleSheet function
const useStyleSheet = createStyleSheet((theme, props) => ({
  // This is a className
  root: {
    // Here goes the css properties
    display: 'flex',
    justifyContent: 'center'
  },
  // Another className
  box: {
    // More css properties
    backgroundColor: props.color || theme.palette.primary.main,
    width: 200,
    height: 200
  }
  // If this param is not passed it will be { key: 'platzily-ui' }
  // nothing wrong with it unless you need to achieve styles encapsulation
}), { key: 'keyToPrepend' });

Then inside the component you use it like this:

export const MyComponent(props) {
  const { classes } = useStyleSheet()
  return (
    <div className={classes.root}>
      <div className={classes.box}/>
    </div>
  )
}

Note how the property classes is inside an object, this because actually useStyleSheet returns an object with three keys

  • classes: The classes used in the object of the styles passed to createStyleSheet.
  • theme: The global theme.
  • cx: A helper function to mix classNames, similar to clsx and classnames

useTheme

Sometimes you'll not need the useStyleSheet function resultin from createStyleSheet, but you'll have to access the global theme. A exposed way to do this is with the useTheme hook.

export default function StyledBox(props) {
  const theme = useTheme();

  const rootStyle = {
    display: 'flex',
    justifyContent: 'center'
  };

  const boxStyle = {
    backgroundColor: props.color || theme.palette.primary.main,
    width: 200,
    height: 200
  };

  return (
    <div style={rootStyle}>
      <div style={boxStyle} />
    </div>
  );
}

After that you just have to call your component:

<StyledBox/>

The code above will result in:

You could compose using the props approach like this

<StyledBox color="pink"/>

The code above will result in:

Custom theme

You could create your own custom theme like this

import { createTheme } from '@platzily-ui/styling';

export const theme = createTheme({
  palette: {
    primary: {
      main: 'rebeccapurple'
    }
  }
});

Then inject it through the Provider

import { ThemeProvider } from '@platzily-ui/styling';
import App from './App';
import theme from './theme';

export default function Root() {
  return (
    <ThemeProvider theme={theme}>
      <App/>
    </ThemeProvider>
  );
}

Then when you create your component

import { createStyleSheet } from '@platzily-ui/styling';

const useStyleSheet = createStyleSheet((theme, props) => {
  return {
    root: {
      display: 'flex',
      justifyContent: 'center'
    },
    box: {
      backgroundColor: props.color || theme.palette.primary.main,
      width: 200,
      height: 200
    }
  };
}, { key: 'StyledBox' });

export default function StyledBox(props) {
  const { classes } = useStyleSheet(props);

  return (
    <div className={classes.root}>
      <div className={classes.box}/>
    </div>
  );
}

And finally call it

<StyledBox/>

It will look like this

Theme composition

The ThemeProvider is meant to be used at the root of the app, but more ThemeProviders can be added nested in the dom tree.

You could use something like this.

import { ThemeProvider } from '@platzily-ui/styling';
import App from './App';
import theme from './theme';
import otherTheme from './otherTheme';

export default function Root() {
  return (
    <ThemeProvider theme={theme}>
      <App>
        <StyledBox/>
        <ThemeProvider theme={otherTheme}>
          <StyledBox/>
        </ThemeProvider>
      </App>
    </ThemeProvider>
  );
}

theme have a default configuration but otherTheme has a differente palette.primary.main color. The resulting of the code above will be this:


Function as a theme

If you decide to use an approach as the showed above you could pass a function as a theme in the inner ThemeProvider

🚨

Never pass the theme as a function in the higher ThemeProvider, it will not work

You could do it this way

import { ThemeProvider } from '@platzily-ui/styling';
import App from './App';
import theme from './theme';

export default function Root() {
  return (
    <ThemeProvider theme={theme}>
      <App>
        <StyledBox/>
        <ThemeProvider
          theme={(outerTheme) => ({
            ...outerTheme,
            palette: {
              ...outherTheme.palette,
              primary: {
                ...outherTheme.palette.primary,
                main: 'rebeccapurple'
              }
            }
          })}
        >
          <StyledBox/>
        </ThemeProvider>
      </App>
    </ThemeProvider>
  );
}

Note how the outer theme which is the theme passed to the higher ThemeProvider is received as a param in the function.

The code above will result in this: