@hadihallak/styled
TypeScript icon, indicating that this package has built-in type declarations

9.0.0-alpha.9 • Public • Published

Use stitches to create styled components in React.

Read more about stitches at @stitches/css.

Get started

npm install @stitches/styled

// css.ts
import { createStyled } from "@stitches/styled";

export const { styled, css } = createStyled({
  // CSS config
});
// App.tsx
import * as React from "react";
import { styled } from "./css";

const Header = styled.h1({
  color: "red",
  margin: "2rem",
});

export const App: React.FC = () => {
  return (
    <div>
      {/*
        You can change the underlying element, which also
        changes the typing of the component
      */}
      <Header as="h2">Hello World!</Header>
    </div>
  );
};

Variants

Instead of providing props to the styled elements, you rather have variants. This fixes two important issues with styled APIs:

  1. No invalid props are passed down to the underlying DOM node
  2. The css definition has no dynamic behaviour, meaning there is only a single evaluation. This creates a big performance improvement
import { styled } from "./css";

export const Button = styled.button(
  {
    borderRadius: 1,
  },
  {
    variant: {
      primary: {
        backgroundColor: "red",
      },
      muted: {
        backgroundColor: "gray",
        opacity: 0.5,
      },
    },
    size: {
      small: {
        fontSize: 2,
      },
      big: {
        fontSize: 4,
      },
    },
  }
);

The dynamic behaviour is defined where you consume the styled component:

<Button variant="primary" size="small"></Button>

<Button variant={isDisabled ? 'muted' : 'primary'} size="small" disabled={isDisabled}></Button>

Variants can also be triggered by screen:

<Button
  variant={{
    mobile: "primary",
    tablet: "secondary",
  }}
  size="small"
></Button>

Override

All styled components takes a css property. This property allow you to override styles. You should ideally use the css factory to create overriding style outside the component or using a memo hook, but you can inline if you really want to. Inlining forces Stitches to evaluate the styling on every render, but this is a tiny overhead not really noticeable in practice.

const override = css({
  '&:hover': {
    color: "blue",
  },
});

export const MyComponent = () => {
  return (
    <div>
      <Button variant="primary" css={override}></Button>
      <Button variant="primary" css={{
        '&:hover': {
          color: 'blue'
        }
      }}>
    </div>
  );
};

Composition

The styled api can be called directly as well:

const Header = styled("h1", {
  color: "red",
  margin: "2rem",
});

This gives the same result as earlier. But you can rather pass an existing component:

const Header = styled.h1({
  color: "red",
  margin: "2rem",
});

const UltimateHeader = styled(Header, {
  fontSize: "100px",
});

Any variants defined by what you compose is typed and made available to the composed styled component.

You can also compose dynamically by doing:

<Header as={SomeOtherStyledComponent} />

You can also create logical components by using the low level styled.Box component:

const Alert: PolymorphicComponent<{ isOpen: boolean }, "div"> = styled(
  ({ isOpen, as, ...props }) => {
    const [open, setOpen] = React.useState(isOpen);

    return open ? <styled.Box {...props} as={as || "div"} /> : null;
  }
);

Now this component can be used as a normal styled component, you could even have given it a base styling and/or variants.

Server side rendering

import { renderToString } from "react-dom/server";
import { css } from "../css";
import { App } from "../App";

const { styles, result } = css.getStyles(() => renderToString(<App />));

styles is an array of style contents. Each item in the array should result in a style tag passed to the browser. result is just the result of the callback, in this example the string returned from renderToString.

Versions

Current Tags

Version History

Package Sidebar

Install

npm i @hadihallak/styled

Weekly Downloads

1

Version

9.0.0-alpha.9

License

MIT

Unpacked Size

71.3 kB

Total Files

8

Last publish

Collaborators

  • hadihallak