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: