Theming With Linaria
This is a followup on the post I did about Getting Started with Linaria
The starter I worked on last time I made into a template so it can be used as the base of this project.
I’ll use the Gatsby CLI to spin up a new project:
1gatsby new gatsby-linaria-starter-with-theme https://github.com/spences10/gatsby-starter-linaria
Defaults
In this example I’m using the defaults from Tailwind CSS for the theme.
With this as a base I can then add my own theme on top of that. An
example of why I would want to do that would be with the Tailwind
default there’s no primary
colour.
If I want to add my own primary colour to the theme I can spread the
defaults into my theme
object, first up though, default theme.
To do that I’m going to create a theme-defaults.js
file in the
theme
directory, then create a project-theme.js
file where I’ll
add in the theme properties I want in there.
1# create the files2touch src/theme/{theme-defaults.js,project-theme.js}
Paste the Tailwind defaults into the theme-defaults.js
file, I
prefer to have a named export on files so I’m going to change the
module.exports = {
to export const defaults = {
.
1export const defaults = {2 prefix: '',3 important: false,4 separator: ':',5 theme: {6 screens: {7 ...
The ...
represents the reset of the items in the object, I’ve
shortend it for brevity otherwise this would be a 400 line snippet. 😅
Really all I need from this is the theme
object but rather than mess
around with the object I’ll destructure the theme out of it in the
project-theme.js
file.
I can now use the Tailwind defaults in the project-theme.js
file,
this is also where I can add additional theme options, more on that
shortly, for now I’m going to import the defaults, destructure the
theme out of defaults
and label it as themeDefaults
I can then
spread them into my theme object.
1import { defaults } from './theme-defaults'2
3const { theme: themeDefaults } = defaults4
5export const theme = {6 ...themeDefaults,7}
Theming with Linaria
If I wanted to I could create my own theme with Linaria
using CSS custom properties but instead I’m going to be
using the Callstack theme provider which has a hook I can use in
useTheme
.
1# install the theme provider2yarn add @callstack/react-theme-provider
I’m going to create another file in the theme folder imaginatively
named theme-provider.js
in there I’ll import and pass in the theme
object I created:
1import { createTheming } from '@callstack/react-theme-provider'2import { theme } from './theme'3
4export const { useTheme } = createTheming(theme)
Now I’ll be able to use the useTheme
hook in my Linaria components
using the styled
tag.
Example
In the Header
component I can now change the background property to
use the theme.
I’ll need to import the useTheme
hook and pass the theme object to
the Linaria styled
component theme
prop.
1const Header = ({ siteTitle }) => {2 const theme = useTheme()3 return (4 <StyledHeader theme={theme}>5 <div>6 <h1>7 <Link to="/">{siteTitle}</Link>8 </h1>9 </div>10 </StyledHeader>11 )12}
Now in the Linaria styled
componet I can use any of the theme
values. In the Header component I’ll change the background
to blue:
1const StyledHeader = styled.header`2 background: ${({ theme }) => theme.colors.blue[500]};3 margin-bottom: 1.45rem;4 div {5 margin: 0 auto;6 max-width: 960px;7 padding: 1.45rem 1.0875rem;8 h1 {9 margin: 0;10 a {11 color: white;12 text-decoration: none;13 }14 }15 }16`
Also a valid way to get the theme values would be:
1background: ${props => props.theme.colors.blue[500]};
I prefer to destructure the theme out of the props (({ theme })
)
however.
Moar theme options
So I have some nice defaults I can call on from the default config file I jacked from the Tailwind defaults. But what about that primary colour option?
Taking a look at the defaults there’s no option for rebeccapurple (hex #663399) so I’m going to add one.
In the project-theme.js
I’ll define a new object for the primary
colours, tip if you want to get shades of a particular colour take a
look at 0to255.com.
With my shades of rebeccapurple I can add that to the theme
object.
1import { defaults } from './theme-defaults'2
3const { theme: themeDefaults } = defaults4
5export const theme = {6 ...themeDefaults,7 colors: {8 primary: {9 100: '#aa7fd4',10 200: '#9966cc',11 300: '#884cc3',12 400: '#773bb2',13 500: '#663399',14 600: '#552b80',15 700: '#442266',16 800: '#331a4d',17 900: '#221133',18 },19 ...themeDefaults.colors,20 },21}
Take note that I’m spreading the colours back in after defining the new colour property. If I don’t do this then the object will be overwritten with the values provided here instead of both.
The new colour can now be used in the same way as before and I swap
out the blue
colour for the primary
one.
Wrap up
So that’s how I add theming with Linaria, there was also the
ThemeProvider
and withTheme
options that could be used from the
react-theme-provider
although I did find this way more suited to my
needs.
Back to Top