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

react-stylescope

v0.9.3

Published

Component based styling for react. Write styles that are scoped to the components where they are created.

Downloads

15

Readme

react-stylescope NPM Version GitHub License

Component based styling for react. Write styles that are scoped to the components where they are created. A react implementation of the @scope CSS at-rule with support for all browsers that can run JavaScript.

React allows you to write components to define your app's UI. Every component have its own logic and state which allows for a dclarative and mantainable codebase. However, how do we style those components? What if the are differnt teams working on different parts of the application? How do we solve the confusion of CSS name conflicts easily? Team A sets .card{ background-color: white;} Team B thinks .card{ background-color: blue;} works perfectly for them. Both Teams push to production. What happens next? Disaster!!

There are solutions like styled-components. Styled-components is one of the good solutions out there to help write styles that are scoped or tied to components. However, wouldn't it be easier to write styles with auto completions out of the box than writing as strings?

All you will need to do is npm install react-stylescope

Write your style-scopped component.

import { useScopedStyleSheet, getScopedName, ScopedStyleSheets } from 'react-stylescope'

type CardProps = {backgroundColor: 'white'|'blue',caption:string}

const Card = ({backgroundColor, caption}: CardProps)=>{
    const scoped = getScopedName('Card')
    const { keys, sheet } = useScopedStyleSheet({
        '.card-container': {
            width: '320px',
            backgroundColor: `${backgroundColor}`
        },
        '.card-container img':{
            lineHeight: 1.5,
            display: 'block',
            margin: '10px'
        }
    }, scoped)

    return (
        <div className={keys['.card-container']} >
            <div><img src='image.png' alt='Some text'  /></div>
            <div>{caption}</div>
            <ScopedStyleSheets styles={sheet} />
        </div>
    )
}

Now from the above component, Team A and Team B can use their desired color for background without anymore worries.

And, relax. The style object passed to useScopedStyleSheet does not get to the browser. Hurray! It's transpiled into strings before the code gets served to the browser. You get what I'm heading to right? Write the styles with code completions and it's converted into strings for you. No more pain writing css in strings.

How to use react-stylescope

After installation, if the project was created with create-react-app navigate to the project directory and run npx stylescope --setup react

Else, add the code below to the end of the module.rules array in the webpack.config.js and run npx stylescope --setup device

{
    test:/(\.ts|\.js|\.cjs|\.mjs|\.tsx|\.jsx)$/,
    exclude:/node_modules/,
    loader: require.resolve('react-stylescope/dist/lib/loader.js')
}

Using Vite?

Import the ScopedStyleVitePlugin and add to the plugins array in the vite.config.js file and run npx stylescope --setup device

import { ScopedStyleVitePlugin } from "react-stylescope/dist/lib/vite-loader";

// A possible config may looked like this
export default defineConfig({
  plugins: [react(), ScopedStyleVitePlugin()] // Added to the plugin array
});

That is all to configure.

API documentation

getScopedName

Returns a scoped name unique to the calling component. The value returned must be stored in a variable named scoped. This is a requirement

@param name A unique name for the component. It may be the name of the component.

Do not forget to name your variable scoped

 const App = ()=>{
     // Prevent regeneration of new scoped name on re-render
     const scoped = useMemo(()=>getScopedName('App'),[]);
     // rest of your code...
}

ScopedStyleSheets

A component that renders a style element with your style sheet.
@param props.styles Pass the style sheet to the styles prop

useScopedStyleSheet

Creates a css string from a React CSSProperties object. The style object passed to useScopedStyleSheet does not get to the browser. It's transpiled into strings before the code gets served to the browser. The function only returns a pre-computed object when your application runs in the browser.
All dirty works (conversion of the styles object to css string) is done before the code gets to the browser.

@param styleSheet Styles object.

@param marker Pass the scoped variable here. Anything other than the varible named scoped won't work.

const App = ()=>{
     const [ theme, setTheme ] = useState('light')
     const color = `${theme==='light'?'black':'white'}`;
     // Prevent regeneration of new scoped name on re-render
     const scoped = useMemo(()=>getScopedName('App'),[]);
     // Get keys and style sheet
     const { keys, sheet } = useScopedStyleSheet({
         '.container':{
             opacity: 0.9,
             margin: '10px',
             // Dynamic values must be set inside template literals
             color: `${color}`
         }
     },scoped)
     // rest of your code...

     return (
         <div className={keys['.container']}>
             <h1>Hello world</h1>
              <ScopedStyleSheet styles={sheet} />
         </div>
     )
}

Setting style values dynamically

In your style objects passed to useScopedStyleSheet, when setting the values dynamically, do so only in template literals.

The following are wrong ❌ when setting style object values

Rule 1
This is wrong.

const styleObject = { /*...*/ };
const {keys, sheet} = useScopedStyleSheet(styleObject,scoped) 
 

Solution: Do not pass the object dynamically. Do it like below;

const {keys, sheet} = useScopedStyleSheet({ /*...*/ },scoped)   

Rule 2
This is wrong.

const className = '.my-class';
const {keys, sheet} = useScopedStyleSheet({
   [className]: { /*...*/ }
},scoped)   

Solution: Do not set keys dynamically. Do it like below;

const {keys, sheet} = useScopedStyleSheet({
   '.my-class': { /*...*/ }
},scoped)   

Rule 3
This is wrong.

const {keys, sheet} = useScopedStyleSheet({
  '.my-class': {
       margin: 10 + 'px'
   }
},scoped)   

Solution: Set dynamic values this way instead. Always have the final value stored in a variable and set using template literals.

const margin = 10 + 'px';
const {keys, sheet} = useScopedStyleSheet({
  '.my-class': {
       margin: `${margin}`
   }
},scoped)   

Happy Coding!