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

looky

v0.3.1

Published

Responsively use values from your theme in your css-in-js

Downloads

35

Readme

looky

Looky is a utility that lets you resolve props into values from your theme responsively. It is intended for use in CSS-in-JS libraries like styled-components and emotion.

Install

npm install looky

Use

Here's a simple example of creating a Container component with responsive gutters and spacing.

import styled, { ThemeProvider } from "styled-components";
import Looky from "looky";

/*
First let's define a theme with spacing DNA among other attributes and a `media` property listing our breakpoints
*/
const theme = {
  spacings: {
    none: "0px",
    xsmall: "4px",
    small: "8px",
    default: "16px",
    large: "24px",
    xlarge: "32px"
  },
  colors: {
    primary: "#4834d4",
    secondary: "#535c68"
  },
  media: [
    "576px", // mobile landscape
    "768px", // tablet portrait
    "992px", // tablet landscape and small screen laptops
    "1200px" // larger laptops and desktops
  ]
};

/* We need to show Looky where to locate breakpoints in our theme */
const looky = Looky(theme => theme.media);

/* Now we can create some resolvers for some style attributes */

/*
This resolver will look at the value of the gutterX prop and resolve it from
our theme calling the interpolation function (the second arguments) to generate
css for corresponding breakpoints
*/
const gutterX = looky(
  "gutterX",
  value => `
padding-left: ${value};
padding-right: ${value};
`,
  // Since the theme is deeply structured we need to show looky how to get a
  // value from the theme given the value of a prop
  // If your theme is flat (no nested objects or arrays) then you don't need
  // this pass function
  (theme, value) => theme.spacings[value]
);

/* Same idea as the resolver for the gutterX prop */
const gutterY = looky(
  "gutterY",
  value => `
padding-left: ${value};
padding-right: ${value};
`,
  // see the comment in gutterX for why we need this function
  (theme, value) => theme.spacings[value]
);

/* Same idea as the resolver for the gutterX prop */
const spacing = looky(
  "spacing",
  value => `margin-bottom: ${value};`,
  // see the comment in gutterX for why we need this function
  (theme, value) => theme.spacings[value]
);

const Container = styled.div`
  box-sizing: border-box;
  ${gutterX};
  ${gutterY};
  ${spacing};
`;

/*
Imagine this is your top-level app component
*/
const App = () => {
  <ThemeProvider theme={theme}>
    <Container gutterX="spacings.small">
      This container will have horizontal gutters of 8px across all breakpoints
      since spacings.small resolves to 8px from our theme.
    </Container>

    <Container
      spacing={["spacings.small", "spacings.default", null, "spacings.large"]}
    >
      This container will have responsive spacing (margin-bottom). The first
      value is the default, mobile-first value. After that the spacing
      corresponds to:<br />
      1. From mobile and up, it will be small (8px)<br />
      2. For landscape mobiles and up, it will be default (16px)<br />
      3. For portrait tablets and up, we specified null meaning we carry on with
      the value from 2. (16px)<br />
      4. For landscape tablets and up, it will be large (24px)<br />
      5. Since we did not specify anything for the laptop/desktop breakpoint we carry
      on from 4. (24px)
    </Container>

    <Container
      gutterY="spacings.default"
      gutterX={["spacings.small", null, "spacings.default"]}
      spacing={["spacings.small", "spacings.default", null, "spacings.large"]}
    >
      Mix it up
    </Container>
  </ThemeProvider>;
};

In terms of generated CSS, consider the following snippet:

<Container
  spacing={["spacings.small", "spacings.default", null, "spacings.large"]}
>
  Hi there
</Container>

In this case, Container's styles will include:

/*
The class name for Container won't actually be .container
styled-components will generate something like sc-bdVaJa. This is illustrative.
*/
.container {
  margin-bottom: 8px;
}

@media (min-width: 576px) {
  .container {
    margin-bottom: 16px;
  }
}

@media (min-width: 992px) {
  .container {
    margin-bottom: 24px;
  }
}

Looky vs facepaint

This utility serves the same purpose as facepaint but the difference is that it does not allow styling props to take arbitrary values.

The main reason is that we want all styling values to come from your theme. This introduces consistency across your components since styling values come from a single source of truth (your theme). Furthermore, since arbitrary values are not allowed, we can introduce a level of protection against script injection scenarios in CSS-in-JS.