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-redux-layout

v0.1.1

Published

Unleash your creativity with dynamic layouts

Downloads

8

Readme

react-redux-layout

Unleash your creativity with dynamic layouts!

This is an experimental project. It isn't battle-tested and has some known limitations (more below).

Best suited for unconventional layouts, when the DOM is treated more like a canvas than a document. Yay for games, presentations and other full-screen experiences. Nay for articles, forums, e-commerce. YMMV.

Illustrated Algorithms and Flatris are using this. Resize and play with aspect ratios to get the feel of it.

What does this solve?

Relationships between DOM elements in a responsive layout can get annoyingly hard to define via high level CSS.

A classic example is scaling the font size to parent width. This can be done traditionally using viewport-percentage lengths. But what if:

  1. We want to scale border-width instead, ensure the value is a multiplier or 2 and constrain it between min/max values?
  2. The parent is a cell in a grid with a dynamic number of columns? Depending on run time data, the parent might be 50vw (two columns) or 25vw (four columns). Or maybe those columns are actually resizable panes.

Whether we need to scale values using custom functions (1) or adapt layout to user data (2), sooner or later media queries and classes will not be enough.

I say "high level CSS" because we can always go rogue and compute each value by hand. We can derive our layout from the viewport size, trickling CSS attributes down the component hierarchy. This is precisely what react-redux-layout is about!

PS. You might've encountered a bad React pattern when a component absolutely needs to know the size of the parent container: Wasting a render loop. Once the DOM is created, the component puts the parent width/height into its local state for child components to use in the next render loop. react-redux-layout fixes this.

How does this work?

First and foremost, this is not another CSS-in-JS alternative! It is complementary to existing tools. It might be helpful to separate styles as:

  1. Static styles. Nothing changes here. Continue to set these via plain imports, css-modules, glamor, styled-jsx, styled-components, etc.
  2. Dynamic styles. While the values are computed via react-redux-layout, how to assign them to elements is errbody's bidness. style object literals might suffice, but we can also pass the style values to something like jsxstyle or as styled-components props.

Now that we got that out of the way, let's get to the fun part: Piggybacking Redux!

Warning: React and Redux knowledge required 🤓

1. Register layout reducer and init layout listener

import initLayout, { layoutReducer } from 'react-redux-layout';
import computeLayout from './layout';

const store = combineReducers({
  layout: layoutReducer
});

initLayout({ store, computeLayout });

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>
);

2. Define layout computer (pure function)

const COLS = 6;
const ROWS = 10;

export default ({ width, height }) => {
  const landscape = width > height && width >= 640;
  const contentWidth = landscape ? floor(width / 2) : width;
  const colWidth = floor(contentWidth / COLS);

  return {
    content: {
      width: contentWidth,
      height
    },
    col: {
      width: colWidth,
      height: floor(height / ROWS)
    }
  };
};

3. Colocate layout data with component styles

import { connect } from 'react-redux';

const Col = ({ styles }) => (
  <div styles={styles.root}>
    I'm so tired of JS
  </div>
);

export default connect(({ layout }) => ({
  styles: {
    root: layout.col.width
  }
}))(Col);

Performance

Dynamic styles are slower and more verbose than classes. It's up to each of us to decide if the benefits outweigh the cost. Remember, most CSS attributes are static and should continue to be applied using classes.

SSR

Known limitation: While the layout can be computed without a DOM, it needs a viewport (width, height) to derive the values from. The server can provide an arbitrary viewport, but the initial DOM will not match the client viewport until the client-side JS recomputes the layout. Workarounds:

  • Illustrated Algorithms keeps initial DOM transparent and fades it in only after client-side rendering. Not ideal, but the static DOM is still used (React only needs to apply the diff between the dynamic style values).
  • Don't use dynamic styles in the landing page. Flatris uses a preloader styled with regular percentage values.

This is insane!

This setup is liberating once in place. It's also pretty crazy, so let me know what you think!