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

styledux

v0.4.0

Published

A new approach of isomorphic css resolution with webpack, css-loader(css-modules) powered by redux.

Downloads

143

Readme

styledux

A new approach of isomorphic css resolution with webpack, css-loader(css-modules) powered by redux.

IT'S style-dux, not styled-ux.

Status: beta

Features

  • [x] Plain, simple, original css with css modules (with Webpack css-loader). Also support LESS, SCSS, Sass, Stylus, PostCSS...
  • [x] NO extra editor plugin required, because it's only PLAIN css + jsx.
  • [x] Universal javascript support (Server side rendering + Client side rendering)
  • [x] Thread-safe server side rendering, renderToNodeStream() / renderToStaticNodeStream() is OK.
  • [x] Remove styles when render() returns null automatically
  • [x] Middleware support (Powered by redux)
  • [x] Webpack Hot Module Replacement (HMR)

Installation

For npm

npm install styledux

For yarn

yarn add styledux

Usage

1. Configuration

Add styledux/loader before css-loader to your webpack configuration.

module: {
  rules: [
    {
      test: /\.css$/,
      use: [
        {
          loader: 'styledux/loader'
        },
        {
          loader: 'css-loader',
          options: {
            modules: true, // css modules support, important!!
            importLoaders: 1,
            localIdentName: process.env.NODE_ENV === 'production' ? '_[hash:base64:8]' : '[name]__[local]___[hash:base64:5]',
            minimize: process.env.NODE_ENV === 'production',
            sourceMap: true,
          }
        },
        {
          loader: 'postcss-loader'
        }
      ]
    }
  ]
}

styledux/loader is simply to export locals that generated from css-loader and wrap original css contents with a function _().

2. Decorate React components with @withStyle

ExampleComponent.css

.Block {
  background-color: green;
  display: block;
  left: 0;
  opacity: 0;
  position: fixed;
  width: 200px;
  height: 200px;
}

.SubModule {
  background-color: blue;
  display: block;
  width: 20px;
  height: 20px;
}

ExampleComponent.js

import { withStyle } from 'styledux'

import style from './ExampleComponent.css';

@withStyle(style)
export class ExampleComponent extends React.Component {
    render() {
      return (
        <div className={style.Block}>
          <div className={style.SubModule} />
        </div>
      );
    }
}

For stateless component

ExampleStatelessComponent.js

import { withStyle } from 'styledux'

import style from './ExampleComponent.css';

function ExampleStatelessComponent() {
  return (
    <div className={style.Block}>
      <div className={style.SubModule} />
    </div>
  );
}
const component = withStyle(style)(ExampleStatelessComponent);
export default component;

3. Server side rendering

import ReactDOMServer from 'react-dom/server';
import { createStyleduxStore, StyleduxProvider, mapStateOnServer } from 'styledux';

export function renderHTML(App) {
  const styleStore = createStyleduxStore();
  const appHtml = ReactDOMServer.renderToString(
    <StyleduxProvider store={styleStore}>
      <App />
    </StyleduxProvider>
  );
  const styles = mapStateOnServer(styleStore);
  return [
    '<!doctype html><html><head>',
    ...styles,
    '<style id="main_css"></style>', // for options.insertInto on client side
    // You can also add other styles which have higher priority
    '</head><body><div id="app">',
    appHtml,
    '</div></body></html>',
  ].join('');
}

4. Client Side Rendering

import ReactDOM from 'react-dom';
import { createStyleduxStore, StyleduxProvider, handleStateChangeOnClient } from 'styledux';

function rehydrateApp(App) {
  ReactDOM.hydrate(
    <StyleduxProvider store={createStyleduxStore(handleStateChangeOnClient({ insertAt: '#main_css' }))}>
      <App />
    </StyleduxProvider>,
    document.getElementById('app')
  );
}

API

<StyleduxProvider store>

See https://github.com/reactjs/react-redux/blob/master/docs/api.md#provider-store

Props
  • store: Plain redux store that created with createStyleduxStore()
  • children
Example:
import { StyleduxProvider } from 'styledux';

ReactDOM.render(
  <StyleduxProvider store={styleStore}>
    {your_app_component}
  </StyleduxProvider>,
  rootElement
)

createStyleduxStore(...middlewares)

Arguments
  • middlewares: Plain redux middlewares.

You can create your own middlewares to handle state changes.

handleStateChangeOnClient(options) creates a middleware that mount styles like style-loader.

Example

On server:

import { createStyleduxStore } from 'styledux';

const styleStore = createStyleduxStore();

On client:

import { createStyleduxStore, handleStateChangeOnClient } from 'styledux';

const middleware = handleStateChangeOnClient({ insertAt: '#main_css' });
const styleStore = createStyleduxStore(middleware);

withStyle(style)

Decorate a react component with style. It monitors render() of react component.

It dispatches an ADD_STYLE action when render() returned non-empty result, and dispatches a REMOVE_STYLE action when render() returned null.

Arguments
  • style (Object | Array): style object that was generated by styledux/loader.
Example
import { withStyle } from 'styledux';

import style1 from './style1.css';
import style2 from './style2.css';

@withStyle([style1, style2])
class ExampleComponent extends React.Component {
}
import { withStyle } from 'styledux';

import style from './style.css';

@withStyle(style)
class ExampleComponent extends React.Component {
}

mapStateOnServer(options) and handleStateChangeOnClient(options)

The built-in adapter for styledux.

When you build a universal web application, make sure mapStateOnServer(options) and handleStateChangeOnClient(options) use the same options.

options:

  • attrs (Object): Add custom attrs to <style></style> (default: {}).
  • transform (Function): Transform/Conditionally load CSS by passing a transform/condition function. (default: (obj) => obj)
  • transformId (Function): Transform webpack module id to element id. (default: see getOptions )
  • insertAt (null|String): Inserts at the given position. Different from style-loader. (default: null)
  • insertInto (String): Inserts into the given position. (default: )

mapStateOnServer(styleduxStore, options)

Only required for server-side rendering. Generate <style> from styleduxStore on server side.

Example
const styleStore = createStyleduxStore();
const content = ReactDOMServer.renderToString(
  <StyleduxProvider store={styleStore}>
    <App />
  </StyleduxProvider>
);
const styles = mapStateOnServer(styleStore);

const html = [
  '<!doctype html><html><head>',
  ...styles,
  '<style id="main_css"></style>', // The position for insert_at
  '<link rel="stylesheet" type="text/css" href="custom_theme.css">', // Other styles that may have higher priority
  '<script src="main.js" defer></script>',
  '</head><body><div id="app">',
  content,
  '</div></body></html>'
].join('');

handleStateChangeOnClient(options)

Handling state changes and mount styles dynamically on client side.

Example
const styleStore = createStyleduxStore(handleStateChangeOnClient({
  insertAt: '#main_css'
}));

const app = (
  <StyleduxProvider store={styleStore}>
    <App />
  </StyleduxProvider>
);
ReactDOM.hydrate(app, document.getElementById('app'));

LICENSE

MIT