Themeable & styled components#

Bumbag has two methods of styling components, via:

  • style props (recommended): Allowing you to add CSS as props on your components.
  • 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:
Editable example
Here is a more complex example using all the attributes:

Read more on theme-based values

Editable example

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
Editable example

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
Editable example

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
Editable example

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
Editable example

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
Editable example

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
Editable example

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
Editable example

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
Editable example

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 © 2021 Jake Moxey