#Themeable & styled components

Bumbag has two methods of styling components, via:

  • Themeable components (recommended): Allowing you to create components that have a customized theme/style attached to them. This allows you to style components, as well as set default props, variants and modes to them.
  • Styled components: Allowing you to create a standalone styled component.

Note: Themeable components are not supported with third-party components that do not belong to Bumbag. You can use styled components instead.

#Creating a basic themeable component

To create a themeable component, import the applyTheme function and then invoke it with your desired component & theme configuration.

In this example, we are creating a themed button component, where the second parameter is the Button theme config.

Each component theme configuration always consists of 4 attributes:

  • styles - Where the main styling is defined for the component.
  • variants - Where the component variants are defined.
  • modes - Where the component color modes are defined.
  • defaultProps - The default props to apply to the component.

For each docs page of the component, you will find a Theming section where you can reference the schema of the component theme configuration.

Here is a basic example:
Here is a more complex example using all the attributes:

Read more on theme-based values

#Theming external components

Unfortunately, it is not possible to use applyTheme to components that do not belong to Bumbag. However, Bumbag exports Emotion's styled function to help you style external components.

If you want, you could also use this with Bumbag components.

import { styled, css } from 'bumbag';
import CustomComponent from 'external-library';
const FancyComponent = styled(CustomComponent)`
border: 1px solid black;
padding: 1rem 2rem;
`;
function Example() {
return (
<FancyComponent>Hello world</FancyComponent>
);
}
render(Example)

#Generating styles based from props

#With applyTheme

You can generate styles based on your props (and changes in props) by supplying a function (props => ...) to your theme attribute:

Hello world

#With styled

import { Box, styled, css } from 'bumbag';
const FancyBox = styled(Box)`
background-color: ${props => props.palette};
${props => props.type === 'rounded' && css`
border-radius: 10px;
`}
`;
function Example() {
return (
<FancyBox palette="pink" type="rounded">Hello world</FancyBox>
);
}
render(Example)

#Generating styles based from the theme

#Palette

#With applyTheme

You can specify a value from the palette in the global theme on any color CSS attribute.

Hello world

#With styled

Bumbag exports a palette helper function to retrieve a color from the palette.

import { Box, styled, palette } from 'bumbag';
const FancyBox = styled(Box)`
background-color: ${palette('primary')};
color: ${palette('primaryTint')};
`;
function Example() {
return (
<FancyBox>Hello world</FancyBox>
);
}
render(Example)

#Spacing

#With applyTheme

You can specify a value from the spacing in the global theme on any space-based CSS attribute (such as margins & paddings).

Hello world

#With styled

Bumbag exports a space helper function to retrieve a space from the spacing theme.

import { Box, styled, palette } from 'bumbag';
const FancyBox = styled(Box)`
padding: ${space(2, 'major')}rem ${space(4, 'major')}rem;
background-color: ${palette('primary')};
color: ${palette('primaryTint')};
`;
function Example() {
return (
<FancyBox>Hello world</FancyBox>
);
}
render(Example)

#Fonts

#With applyTheme

You can specify a value from the fonts in the global theme on any font CSS attribute.

Hello world

#With styled

Bumbag exports a font, fontSize and fontWeight helper function to retrieve a font from the theme.

import { Box, styled, font, fontSize, fontWeight } from 'bumbag';
const FancyBox = styled(Box)`
font-family: ${font('Comic Sans MS')};
font-size: ${fontSize('400')};
font-weight: ${fontWeight('semibold')};
`;
function Example() {
return (
<FancyBox>Hello world</FancyBox>
);
}
render(Example)

#Borders

#With applyTheme

You can specify a value from the borders in the global theme on any border CSS attribute.

Hello world

#With styled

Bumbag exports a border helper function to retrieve a border from the theme.

import { Box, styled, border, palette } from 'bumbag';
const FancyBox = styled(Box)`
border: ${border('default')};
`;
function Example() {
return (
<FancyBox>Hello world</FancyBox>
);
}
render(Example)

#Border radius

#With applyTheme

You can specify a value from the border radius in the global theme on the borderRadius CSS attribute.

Hello world

#With styled

Bumbag exports a borderRadius helper function to retrieve a border from the theme.

import { Box, styled, borderRadius, palette } from 'bumbag';
const FancyBox = styled(Box)`
border-radius: ${borderRadius('4')};
`;
function Example() {
return (
<FancyBox>Hello world</FancyBox>
);
}
render(Example)

#Breakpoints

#With applyTheme

You can specify breakpoint based values which will apply when the viewport hits a specific breakpoint.

Hello world

#With styled

Bumbag exports a breakpoint helper function to assist with breakpoint media queries.

import { Box, styled, css, breakpoint, palette } from 'bumbag';
const FancyBox = styled(Box)`
color: ${palette('primary')};
${breakpoint('max-desktop', css`
color: ${palette('secondary')};
`)}
`;
function Example() {
return (
<FancyBox>Hello world</FancyBox>
);
}
render(Example)

#Pseudo selectors

#With applyTheme

You can also specify pseudo selectors.

Hello world

#With styled

import { Box, styled, palette } from 'bumbag';
const FancyBox = styled(Box)`
&:hover {
color: ${palette('primary')};
}
`;
function Example() {
return (
<FancyBox>Hello world</FancyBox>
);
}
render(Example)
Copyright © 2020 Jake Moxey