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

boxl

v4.0.1

Published

Layout primitives for the styled component age.

Downloads

10

Readme

B ❐ X L

A layout primitive for the styled component age.

npm version Build Status codecov License: MIT

Installation

$ npm i boxl styled-components

Built with styled components which is required as a peer dependency

Usage

Examples are written in TypeScript

Define Components

Create components with the boxl function passing default props and styling. (All following examples use these components.)

// Base.tsx
import { boxl } from "boxl"

interface ParentProps {
  withHeight?: boolean
}

export const Parent = boxl.div<ParentProps>({
  css: styled => styled`
    height: ${props => props.withHeight 
      ? "449px" 
      : "auto"
    };
    background: white;
    border: 8px solid black;
    box-shadow: 12px -12px 0 0 black;
    margin: 12px 12px 0 0;
    padding: 20px;
  `,
  spacing: "14px",
})

interface ChildProps {
  secondary?: boolean
}

export const Child = boxl.div<ChildProps>({
  css: styled => styled`
    background: ${props => 
      props.secondary ? "white" : "black"
    };
    border: 8px solid black;
    color: ${props => 
      props.secondary ? "white" : "black"
    };
    padding: 20px;
  `,
})

Examples

direction: vertical (default)

Example 001

import React from "react"
import { Child, Parent } from "./Base"

export const Example001 = () => (
  <Parent>
    <Child />
    <Child />
    <Child />
  </Parent>
)

direction: horizontal

Example 002

import React from "react"
import { Child, Parent } from "./Base"

export const Example002 = () => (
  <Parent direction="horizontal">
    <Child grow={1} />
    <Child secondary={true} />
    <Child secondary={true} />
  </Parent>
)

Theme Setup

First, follow Styled Components instructions on setting up a theme with TypeScript.

Once you have defined a theme, we must annotate boxl with it using the provided Boxl<T> interface. A common pattern is to re-export the annotated boxl function for reuse.

import { Boxl, boxl as b } from "boxl"
import { Theme } from "../types/Theme"

export const boxl = b as Boxl<Theme>

API

boxl

boxl is a function that returns a BoxlComponent. There are two ways to use it:

  1. Use predefined element methods:
boxl.div(BoxlProps)

Available for all JSX.IntrinsicElements

  1. Pass a component:
boxl(React.ComponentType)(BoxlProps)

React.ComponentType is any function or class component

Component Example

This allows another component to be passed for styling and is useful when you need to style a 3rd party component (e.g. react-router's <Link />).

component: example 1

import React, { SFC } from "react";
import { 
  boxl, 
  BoxlComponentProps 
} from "boxl";
import { Parent } from "./Base";

const SomeButton: SFC<BoxlComponentProps> = 
  ({boxlProps, ...props}) => 
    <button {...props} />;

const MyButton = boxl(SomeButton)({
  css: styled => styled`
    background: hsl(200, 100%, 50%);
    border-radius: 0.25em;
    border: none;
    color: white;
    cursor: pointer;
    font-size: 0.75em;
    outline: none;
    padding: 0.5em 1em;
    &:active {
      background: hsl(200, 100%, 40%);
    }
    &:hover {
      background: hsl(200, 100%, 60%);
    }
  `,
})

export const Component001 = () =>
  <Parent alignHorizontal="center">
    <SomeButton>Old Button</SomeButton>
    <MyButton>New Button</MyButton>
  </Parent>

BoxlProps

These props may be passed as a default props object or to the returned component itself as JSX props.

With the exception of css, each prop is defined as BoxlProp<A, P, T>.


alignHorizontal - left | center | right

Description

Control horizontal alignment of children. If value is undefined, Child fills available Parent space.

Example: center

alignHorizontal: example 1

// AlignHorizontal.tsx

import React from "react"
import { Child, Parent } from "./Base"

export const AlignHorizontal001 = () =>
  <Parent alignHorizontal="center">
    <Child />
  </Parent>

alignVertical - top | center | bottom

Description

Aligns children vertically regardless of direction.

Example: bottom

alignVertical: example 1

// AlignVertical.tsx
import React from "react"
import { Child, Parent } from "./Base"

export const AlignVertical001 = () =>
  <Parent 
    alignVertical="bottom" 
    withHeight={true}
  >
    <Child />
  </Parent>

childGrow - number

Description

Sets grow amount on all children equally. Useful in combination with childWrap.

Example

childGrow={1} causes Child components to fill available Parent space evenly if possible.

childGrow: example 1

// ChildGrow.tsx
import React from "react"
import { Child, Parent } from "./Base"

export const ChildGrow001 = () =>
  <Parent 
    childGrow={1}
    direction="horizontal"
  >
    <Child />
    <Child />
  </Parent>

childIdealSize - string (CSS length)

Description

Sets idealSize on all children. Useful in combination with childWrap.

Example

childIdealSize="150px" causes Child components to prefer 150 pixel width if possible.

childIdealSize: example 1

import React from "react"
import { Child, Parent } from "./Base"

export const ChildIdealSize001 = () =>
  <Parent 
    childIdealSize="150px"
    direction="horizontal" 
  >
    <Child />
    <Child />
    <Child />
    <Child />
  </Parent>

childWrap - auto | even

Description

Allows Child components to wrap if needed.

Example 1: childWrap="auto"

childWrap: example 1

import React from "react"
import { Child, Parent } from "./Base"

export const ChildWrap001 = () =>
  <Parent
    childIdealSize="200px"
    childWrap="auto"
    direction="horizontal"
    grow={1}
  >
    <Child />
    <Child />
    <Child />
    <Child />
  </Parent>
Example 2: childWrap="auto" with childGrow={1}

childWrap: example 2

import React from "react"
import { Child, Parent } from "./Base"

export const ChildWrap002 = () =>
  <Parent
    childGrow={1}
    childIdealSize="200px"
    childWrap="auto"
    direction="horizontal"
    grow={1}
  >
    <Child />
    <Child />
    <Child />
    <Child />
  </Parent>
Example 3: childWrap="even" with childGrow={1}

childWrap: example 3

import React from "react"
import { Child, Parent } from "./Base"

export const ChildWrap003 = () =>
  <Parent
    childGrow={1}
    childIdealSize="200px"
    childWrap="even"
    direction="horizontal"
    grow={1}
  >
    <Child />
    <Child />
    <Child />
    <Child />
  </Parent>

css:

  • string
  • CSSObject
  • template literal
  • function passed a tagged template literal
Description

Applies style to the component.

Example

css: example 1

import React from "react"
import { boxl } from "../../lib/boxl"
import { Parent } from "./Base"

const StyleString = boxl.div({
  css: "background: black; border-radius: 10px; height: 50px;",
});

const StyleObject = boxl.div({
  css: {
    background: "black",
    borderRadius: 10,
    height: 50,
  },
})

const TemplateLiteral = boxl.div({
  css: `
    background: black;
    border-radius: 10px;
    height: 50px;
  `,
})

const TaggedTemplateLiteralFn = boxl.div({
  css: styled => styled`
    background: black;
    border-radius: 10px;
    height: 50px;
  `,
})

export const Style001 = () =>
  <Parent>
    <StyleString />
    <StyleObject />
    <TemplateLiteral />
    <TaggedTemplateLiteralFn />
  </Parent>

direction - vertical | horizontal

Description

Controls the direction that children flow.

Example 1: "vertical"

direction: example 1

import React from "react"
import { Child, Parent } from "./Base"

export const Direction001 = () =>
  <Parent direction="vertical">
    <Child />
    <Child />
    <Child />
  </Parent>
Example 2: "horizontal"

direction: example 2

import React from "react"
import { Child, Parent } from "./Base"

export const Direction002 = () =>
  <Parent direction="horizontal">
    <Child />
    <Child />
    <Child />
  </Parent>

grow - number

Description

Determines how the component expands in relation to its parent and siblings.

Example

grow: example 1

import React from "react"
import { Child, Parent } from "./Base"

export const Grow001 = () =>
  <Parent direction="horizontal">
    <Child />
    <Child grow={1} />
    <Child />
  </Parent>

idealSize - string (CSS length)

Description

Defines the preferred/ideal width or hight (depending on the parent's direction) of the component and may need to be combined with min-/max-/width via the css property to achieve the desired result.

If the parent direction is "vertical" (default), idealSize will affect the height of the component. If the parent direction is "horizontal", idealSize will affect the width of the component.

Example

idealSize: example 1

import React from "react"
import { Child, Parent } from "./Base"

export const IdealSize001 = () =>
  <Parent direction="horizontal">
    <Child idealSize="50%" />
  </Parent>

spacing - string (CSS length)

Description

Defines the space between children without affecting their distance from the edge of their parent.

Example

spacing: example 1

import React from "react"
import { Child, Parent } from "./Base"

export const Spacing001 = () =>
  <Parent 
    childGrow={1} 
    direction="horizontal" 
    spacing="100px"
  >
    <Child />
    <Child />
    <Child />
  </Parent>

BoxlProp<A, P, T>

BoxlProp<A, P, T> is an interface where parameter A is a primitive value (e.g. "left" | "center" | "right"), P is props, and T is theme:

type BoxlProp<A, P, T> =
  | (A | undefined)
  | (BoxlPropThemeFn<A | undefined, P, T>)
  | (BoxlPropMediaQuery<A | undefined, P, T>);

type BoxlPropThemeFn<A, P, T> = (
  props: BoxlPropsBaseThemed<P, T>
) => BoxlProp<A, P, T>;

type BoxlPropMediaQuery<A, P, T> = {
  [key: string]: BoxlProp<A, P, T>;
};

BoxlProp is the union of three types:

  1. | (A | undefined) - a primitive value (or undefined)
  2. | (BoxlPropThemeFn<A | undefined, P, T>) - a function that receives component props and returns BoxlProp
  3. | (BoxlPropMediaQuery<A | undefined, P, T>) - an object with keys corresponding to a media query string and values that are BoxlProp

Example Usage:

// alignHorizontal as A
const Example01 = boxl.div({
  alignHorizontal: "left"
})

interface Props { 
  foo: boolean 
}

// alignHorizontal as BoxlPropThemeFn
const Example02 = boxl.div<Props>({
  alignHorizontal: props => 
    props.foo ? "left" : "right",
})

// alignHorizontal as BoxlPropMediaQuery
const Example03 = boxl.div<Props>({
  alignHorizontal: { 
    "@media (max-width: 600px)": "left",
    "@media (max-width: 800px)": props => 
      props.foo ? "left" : "center",
  },
})

Develop

  • npm i install project and test app deps
  • npm start starts storybook
  • npm test:unit runs unit tests
  • npm test:visual runs visual tests (requires storybook to be running e.g. npm start)
  • npm test:visual:watch runs visual tests in watch mode
  • npm run build compiles dist/
  • npm pack generates .tgz for local testing