npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

themed-jss

v0.3.5

Published

Themed JSS styles

Downloads

18

Readme

themed-jss

Themed styles with JSS + Dark Mode

tests coverage version docs

npm i themed-jss

Features:

👉 Read the Docs

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))

►Playground

👉 Global styles:

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,
  }
})))

►Playground

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',
  }
)

►Playground

👉 Dark mode by default is read from system settings. You can also assume manual control:

import { DarkMode } from 'themed-jss/dark-mode'

DarkMode.initialize()

// ...

btn.addEventListener('click', () => DarkMode.toggle())

►Playground

☝️ When you manually override dark mode settings, the preference is automatically stored in local storage and loaded on next page load (thats what 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}`
  }
}))

👉 Read the Docs

Callbag JSX

👉 Use 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>
  )
}

►Playground

👉 themePlug() returns a ComponentProcessor, so it can be used to plug themes into any render-jsx based renderers.

👉 Read the Docs

React

👉 Use <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>
  )
}

►Playground

👉 Read the Docs

Type Safety

👉 You can specify the theme object type that a style() would accept:

const myStyle = style<MyThemeType>(theme => ({
  // ...
}))

👉 You can specify the theme object type that a theme() object should produce:

const myTheme = theme<MyThemeType>({
  ...
})

👉 You can specify the this argument for callbag-jsx (in general render-jsx) components:

import { ThemedComponentThis } from 'themed-jss/jsx'

// ...

function MyBtn(this: ThemedComponentThis, ...) {
   // ...
}

👉 You can even specify the theme type that a particular component will be expecting:

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/`)