npm i themed-jss
Features:
- Theme-based styling based on JSS
- Integrates with
callbag-jsx
and react - Can be used with other frameworks or without any frameworks
- Automatic dark mode support
- Type safe
Usage
Create your styles based on a theme:
// styles.ts
import { style, when } from 'themed-jss'
export const btnStyle = style(theme => ({
background: theme.primaryColor,
color: theme.backgroundColor,
borderRadius: 3,
cursor: 'pointer',
border: '2px solid transparent',
padding: 8,
fontSize: 14,
[when(':hover')]: {
background: 'transparent',
color: theme.primaryColor,
border: `2px solid ${theme.primaryColor}`
}
}))
Then use a theme object to add your styles to the document:
import { theme } from 'themed-jss'
import { btnStyle } from './styles'
const btn = document.getElementById('btn')
const myTheme = theme({
primaryColor: '#00917c',
backgroundColor: 'white',
textColor: '#424242',
})
btn.classList.add(myTheme.class(btnStyle))
import { global } from 'themed-jss'
myTheme.add(global(theme => ({
body: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '100vw',
height: '100vh',
padding: 0,
margin: 0,
background: theme.backgroundColor,
}
})))
Dark Mode
Add some overrides to your theme for dark mode, themed-jss
takes care of the rest automatically:
const myTheme = theme(
{
primaryColor: '#00917c',
backgroundColor: '#fde8cd',
textColor: '#424242',
},
// --> overrides for dark mode:
{
backgroundColor: '#0f3057',
textColor: 'white',
}
)
import { DarkMode } from 'themed-jss/dark-mode'
DarkMode.initialize()
// ...
btn.addEventListener('click', () => DarkMode.toggle())
DarkMode.initialize()
does basically).
themed-jss
automatically injects additional CSS rules for properties that would change in dark mode. However, sometimes it is necessary
to enforce some CSS properties to appear in these dark-mode rules despite them not changing between dark and light mode, for example as it would
be superceded by some other rule otherwise. You can enforce CSS properties to be repeated in dark-mode rules by adding a !darkmode
at the end of your
property value:
const btnStyle = style(theme => ({
// ...
[when(':hover')]: {
background: 'transparent !darkmode',
color: `${theme.primaryColor} !darkmode`,
border: `2px solid ${theme.primaryColor}`
}
}))
Callbag JSX
themePlug()
to plug themes into callbag-jsx
renderers:
import { makeRenderer } from 'callbag-jsx'
import { themePlug } from 'themed-jss/jsx'
const myTheme = theme({ ... })
const renderer = makeRenderer().plug(themePlug(myTheme))
Now components can use this.theme
for accessing the theme:
import { style } from 'themed-jss'
import { DarkMode } from 'themed-jss/dark-mode'
const BtnStyle = style(theme => ({ ... }))
export function MyBtn(_, renderer) {
const cls = this.theme.class(BtnStyle)
return (
<button class={cls} onclick={() => DarkMode.toggle()}>
Toggle Dark Mode
</button>
)
}
themePlug()
returns a ComponentProcessor
, so it can be used to plug themes into any render-jsx
based renderers.
React
<Themed/>
component and useThemedStyle()
hook for utilizing themed styles in your components:
// my-btn.jsx
import { useThemedStyle } from 'themed-jss/react'
const BtnStyle = style(theme => ({ ... }))
export function MyBtn() {
const cls = useThemedStyle(BtnStyle)
return (
<button className={cls} onClick={() => DarkMode.toggle()}>
Switch Dark Mode
</button>
)
}
// app.jsx
import { theme } from 'themed-jss'
import { DarkMode } from 'themed-jss/dark-mode'
import { Themed } from 'themed-jss/react'
DarkMode.initialize()
const myTheme = theme({ ... })
export default function App() {
return (
<Themed theme={myTheme}>
<MyBtn/>
</Themed>
)
}
Type Safety
style()
would accept:
const myStyle = style<MyThemeType>(theme => ({
// ...
}))
theme()
object should produce:
const myTheme = theme<MyThemeType>({
...
})
this
argument for callbag-jsx
(in general render-jsx
) components:
import { ThemedComponentThis } from 'themed-jss/jsx'
// ...
function MyBtn(this: ThemedComponentThis, ...) {
// ...
}
import { ThemedComponentThis } from 'themed-jss/jsx'
// ...
function MyBtn(this: ThemedComponentThis<MyThemeType>, ...) {
// ...
}
Contribution
Be nice to each other. Here are some useful commands for development:
git clone https://github.com/loreanvictor/themed-jss.git
npm i # --> installs dependencies
npm start # --> servers `samples/index.tsx` on `localhost:3000`
npm test # --> runs tests
npm run cov:view # --> view coverage
npm i -g @codedoc/cli # --> install CODEDOC cli (for working on docs)
codedoc install # --> install CODEDOC dependencies (for working on docs)
codedoc serve # --> serve docs on `localhost:3000/themed-jss` (from `docs/md/`)