Theme
The theme is a set of design primitives that affect the look of all your UI across all components. This includes color, spacing, typography (like font sizes, weight, line heights etc.) and breakpoints.
The theme needs to be initialized with the PabloThemeProvider
.
import { PabloThemeProvider } from '@bojagi/pablo/theme';
const customTheme = { /* your custom theme */ };
const App = () => (
<PabloThemeProvider theme={customTheme}>
/* The rest of your app */
</PabloThemeProvider>
)
You can overwrite all or some of the theme values. They will be merged with the default ones to create a complete theme.
Color
There are different types of colors you can use. The most important color being brand
, which represents
your brand color. It is used to highlight interactable elements and sets the tone of your brand. Brand is a shaded color.
Shaded colors
Shaded colors are brand
, positive
, negative
and neutral
. They have a main
variant which is used when
there is no specific shade specified and and different darker or lighter shades:
lightest
light
main
dark
darkest
contrastText
contrastTextLight
In addition to the shades they all have contrast text for normal/dark and light backgrounds as well to define a text color that guarantees contrast and readability on colored backgrounds (like buttons).
Gray
There are three kinds of gray color palettes: gray
, blackOpacity
and whiteOpacity
. They all have
the same shades:
50
, 100
, 200
, 300
, 400
, 500
, 600
, 700
, 800
, 900
By default these represent a percentage scale from black to white, where 50
is 5% black and 900
90%.
The two opacity palettes use transparency instead of solid shades where the base color is either black or white.
This is useful when you want to use gray scales on top of colored backgrounds (e.g. whiteOpacity
on dark backgrounds)
because of the transparency the gray shades adjust to the background color.
Common colors
There are some common colors specified:
white
(default#ffffff
)black
(default#000000
)whiteContrastText
: (default#000000
)blackContrastText
: (default#ffffff
)
Other colors
You can also set text, border and background colors. For a full overview look at the default theme displayed at the end of this document.
Spacing
Spacing is used to define spaces between components (not used for spacing inside components like padding between button borders and text).
Currently it's an array of values, so when you want to access it you specify the index of the array:
[0, 2, 4, 6, 8, 12, 16, 24, 32, 64, 128]
Above you see the default spacings which grows in a fibunacci like scale, to get spacing of 8px
you need to use index 4
.
Disclaimer: This is subject to change in favor of multiplication of a base spacing as it is easier to remember and is calculatable.
Typography
Pablo uses the following typography elements which mostly reflect the Typography
variants:
paragraph
paragraphBold
button
headline
title
subtitle
info
infoBold
Exception for this are the two Bold
suffixed properties which are used for <strong/>
emphasis text
within paragraph and info text respectively.
In addition to the above properties there is also a base
config that are shared among all
Typography
variants.
In base
you can define the following options for all typography:
fontFamily
, which is used by all variantsfontWeight
, which is overwritten by some variants
The specific variants above have the following properties that overwrites the base
when set:
fontSize
lineHeight
marginBottom
, which defines the margin at the end of the text blockfontFamily
(optional)fontWeight
(optional)
Breakpoints
Pablo uses five different breakpoints:
- default is mobile and up
sm
is used for portrait tabletsmd
for landscape tableslg
for small desktops like a laptopxl
for big screens
These breakpoints are specified as an array. To customize it you can use the createBreakpoints
utility.
import { createBreakpoints } from '@bojagi/pablo/theme';
// default mobile breakpoint is excluded, as it starts at 0
const breakpoints = createBreakpoints(['700px', '1000px', '1200px', '1920px']);
In addition to the array you an then also access the named sizes (like lg
) though this as well
const isTheSame = breakpoints[2] === breakpoints.lg;
console.log(isTheSame) // logs 'true'
Using theme values in custom components
You can use the theme values in custom components that have been written with emotion
.
const MyComponent = styled.div`
background-color: ${props => props.theme.color.brand.main};
`;
As you can see this is quite long and a pain to write, therefore Pablo offers a set of helper functions.
Color
import { theme } from '@bojagi/pablo/theme';
const MyComponent = styled.div`
background-color: ${theme.colors.brand.main};
`;
You can access theme colors by just referencing them specific theme color from the theme
object.
This theme object contains nested objects that hold the CSS variable name to the color, so you don't
need to reference the whole variable and get type safety through TypeScript.
getSpacing
With getSpacing
you can get a spacing value of a specific index:
import { getSpacing } from '@bojagi/pablo/styleHelpers';
const MyComponent = styled.div`
margin: ${getSpacing(1)}; /* resolves to 8px on the default theme */
`;
breakpoints
Use the breakpoints
function to apply specific styles depending on the screen size.
import { breakpoint, getSpacing } from '@bojagi/pablo/styleHelpers';
import { css } from '@emotion/react';
const MyComponent = styled.div`
/* Base styles (mobile and up) */
padding: ${getSpacing(1)};
/* Landscape tablet styles (and up) */
${breakpoint(
'md',
css`
padding: ${getSpacing(1.5)};
`,
)}
`;
By default it applies the breakpoint styles the defined breakpoint and up. If you want to apply
it for styles below, you can pass the mediaQueryBelow
function as third argument.
import { breakpoint, getSpacing } from '@bojagi/pablo/styleHelpers';
import { mediaQueryBelow } from '@bojagi/pablo/breakpoints';
import { css } from '@emotion/react';
const MyComponent = styled.div`
/* Landscape tablet styles (and up) */
padding: ${getSpacing(1.5)};
/* Base styles (mobile and up) */
${breakpoint(
'md',
css`
padding: ${getSpacing(1)};
`,
mediaQueryBelow,
)}
`;
Default theme
For reference here you can find the full default theme:
import { createBreakpoints } from '@bojagi/pablo/theme';
export const defaultTheme = {
background: '#fafafa',
common: {
white: '#ffffff',
black: '#000000',
whiteContrastText: '#000000'
blackContrastText: '#ffffff',
},
gray: {
'50': '#f0f0f0',
'100': '#e0e0e0',
'200': '#d0d0d0',
'300': '#b0b0b0',
'400': '#a0a0a0',
'500': '#808080',
'600': '#606060',
'700': '#505050',
'800': '#303030',
'900': '#202020',
},
blackOpacity: {
'50': 'rgba(0,0,0,0.05)',
'100': 'rgba(0,0,0,0.1)',
'200': 'rgba(0,0,0,0.2)',
'300': 'rgba(0,0,0,0.3)',
'400': 'rgba(0,0,0,0.4)',
'500': 'rgba(0,0,0,0.5)',
'600': 'rgba(0,0,0,0.6)',
'700': 'rgba(0,0,0,0.7)',
'800': 'rgba(0,0,0,0.8)',
'900': 'rgba(0,0,0,0.9)',
},
whiteOpacity: {
'50': 'rgba(255,255,255,0.05)',
'100': 'rgba(255,255,255,0.1)',
'200': 'rgba(255,255,255,0.2)',
'300': 'rgba(255,255,255,0.3)',
'400': 'rgba(255,255,255,0.4)',
'500': 'rgba(255,255,255,0.5)',
'600': 'rgba(255,255,255,0.6)',
'700': 'rgba(255,255,255,0.7)',
'800': 'rgba(255,255,255,0.8)',
'900': 'rgba(255,255,255,0.9)',
},
borders: {
main: 'rgba(0,0,0,0.25)',
light: 'rgba(0,0,0,0.1)',
},
text: {
main: '#000000',
info: 'rgba(0,0,0,0.5)',
},
brand: {
lightest: '#EBE7FF',
light: '#D6CEFF',
main: '#6A50F2',
dark: '#4129BD',
darkest: '#281683',
contrastText: '#ffffff',
contrastTextLight: '#000000',
},
positive: {
lightest: '#DFF6E6',
light: '#BBECCB',
main: '#38C765',
dark: '#2FB85A',
darkest: '#108B36',
contrastText: '#ffffff',
contrastTextLight: '#000000',
},
negative: {
lightest: '#FFE7E5',
light: '#FFCFCC',
main: '#F21D0D',
dark: '#CA271B',
darkest: '#871A12',
contrastText: '#ffffff',
contrastTextLight: '#000000',
},
neutral: {
lightest: '#FCF5DB',
light: '#FFEB9E',
main: '#FFDD5B',
dark: '#EDC52A',
darkest: '#D6AC0B',
contrastText: '#ffffff',
contrastTextLight: '#000000',
},
breakpoints: createBreakpoints(['700px', '1000px', '1200px', '1920px']),
};