Theme Setup
How to implement a global theme
Overview
In order to create consistent and coherent styles throughout a project, it can often be
beneficial to use a theme
object to store and access common style values and scales.
Jynx
allows you to define a theme
object that can then be distributed to all of your
styled components with the added benefit of providing type assertions and input
suggestions to props that access defined theme
scales.
As a basic example:
/* theme.ts */
export const theme = {
colors: {
primary: '#e32020',
secondary: '#1b92c4'
}
}
/* Layout.tsx */
export const Container = styled.div<ColorProps>`
${color}
`
export const Layout: React.FC = ({ children }) => {
return (
// The values 'primary' and 'secondary' will be suggested here
// ⌄⌄
<Container bgColor=' '>
{children}
</Container>
)
}
Process
The process for setting up your theme requires 2-3 steps:
- define your
theme
- wrap your app in a
ThemeProvider
and pass yourtheme
to it - (optionally) declare your
theme
's types
1. Define your theme
You can define your theme
however you like, the only requirement is that it's an object.
However, to make your values accessible to certain functions, you do need to define them
under specific keys (check the API reference to see which
props correspond to which keys).
The simplest way to define your theme
is to create a theme.ts
/.js
file and export
your it from there:
/* theme.ts */
export const theme = {
breakpoints: {
sm: '640px',
md: '960px',
lg: '1280px'
}
}
2. Add a ThemeProvider
The next step is to wrap your entire app in a ThemeProvider
and pass it the exported
theme
- thereby making it accessible across your entire app.
Most CSS-in-JS libraries provide you with a ThemeProvider
component to use in this
situation. The example below is written using 'styled-components'
.
/* App.ts */
import { ThemeProvider } from 'styled-components'
import { theme } from '../theme.ts'
const App: React.FC = props => (
<ThemeProvider theme={theme}>
{/* application content */}
</ThemeProvider>
)
export default App
If you're not using Typescript then that's it, you're all set!
However, if you are using Typescript, you'll most likely want to make your theme type-safe, which means an additional step...
3. Declaring your types
As of v4.1.4, Typescript has allowed type definitions to be extended through
declaration merging.
We can use this to provide Jynx
with type information about our theme
which will then
permeate across the rest of our app.
Accessing your theme
type
To begin with, you need to get the type definition of your theme
. Whilst you can
define this manually, the recommended way is to export a type from your theme.ts
/.js
file that is the typeof
your theme object:
/* theme.ts */
export const theme = {
breakpoints: {
sm: '640px',
md: '960px',
lg: '1280px'
}
}
export type Theme = typeof theme
This way, as you expand, update and make changes your theme, your type declarations will reactively update too.
Creating a declarations file
Once you have your theme
type, you'll then need to create a declarations file. Name it
'jynx.d.ts'
(or another name of your choice).
/* import the existing declarations */
import 'jynx'
/* and your custom `Theme` type */
import type { Theme } from '@/themes'
/* Then declare the `jynx` module */
declare module 'jynx' {
/* and extend the `CustomTheme` interface with your own `Theme` type */
export interface CustomTheme extends Theme {}
}
The
CustomTheme
type being extended is just an empty interface that's used as part of the library'sDefaultTheme
type which conditionally resolves to the correct theme depending on whether a custom theme is defined.
And there you have it! Your theme
s types have now been declared and any style functions
you use will have access to them.
If you're using a library like styled-components or emotion then it's more than likely you'll be familiar with this process and will be doing it for that library too.
Make sure you complete this process as this declaration file only adds types to the jynx
functions and not to the components they're used in.