@walltowall/calico

React components for using atmoically generated styles via props.

Usage no npm install needed!

<script type="module">
  import walltowallCalico from 'https://cdn.skypack.dev/@walltowall/calico';
</script>

README

Calico

Calico is a customizable styling library that maps React props to statically generated class names.

Motiviation

Calico is a CSS-in-JS project library that aims to combine the benefits of various styling solutions into one:

  • Atomic CSS as inspired by libraries like Tailwind CSS
    • Statically extracted, but customizable upfront in a theme file.
    • Encourages reusabilty with a finite set of generated classNames.
  • Very light runtime made possible by the treat library.
    • Static style extraction with full type safety.
    • Dynamic styles via swapping classNames.
  • Developer-centric as inspired by styled-system and theme-ui.
    • Define responsive styles via arrays.
    • Namespaced styles to ease type-extensibility.
    • One-off styles can be defined in .treat files with additional responsive helpers added onto your theme.

Install

Install the package in addition to its peer dependencies:

yarn add @walltowall/calico treat react-treat

Depending on your project, you'll also need to configure webpack to support treat.

# If using Gatsby:
yarn add -D gatsby-plugin-treat

# If using NextJS
yarn add -D next-treat

For additional information about setting up treat, refer to their docs.

Getting Started

First, we'll need to define a theme that will define our design tokens.

// theme.ts
import { createCalicoTheme, baseCalicoTheme } from '@walltowall/calico'

const colors = {
  black: '#000',
} as const

const space = {
  0: 0,
  1: '0.25rem',
} as const

export type Theme = typeof theme
export const theme = createCalicoTheme({
  breakpoints: {
    mobile: '0rem',
    tablet: '48rem',
    desktop: '75rem',
    desktopWide: '90rem',
  },

  // The rules object will determine the classes we will generate
  // at build-time.
  rules: {
    // Any valid CSS property can be specified.
    color: colors,
    backgroundColor: colors,
    margin: space,

    // Extending default rules can be done naturally:
    borderRadius: {
      ...baseCalicoTheme.rules.borderRadius,
      full: '50%',
    },
  },

  // The variants object determines the variant classes that will be
  // generated.
  variants: {
    backgroundColor: {
      hover: true,
      focus: true,
    },
  },
})

Next, we'll need to create a treat file to generate the classes from our theme.

// theme.treat.ts
import { createTheme } from 'treat'
import { theme as calicoTheme } from './theme'

export const theme = createTheme(calicoTheme)

Once we've setup all of our className generation, let's setup TypeScript so we have full type-safety while we're styling in our project.

// calico.d.ts
import { Theme as CalicoTheme } from './theme'

declare module 'treat/theme' {
  export interface Theme extends CalicoTheme {}
}

Finally, we need to setup our <TreatProvider> so we can utilize our theme styles.

// app.tsx
import React from 'react'
import { TreatProvider } from 'react-treat'
import { theme } from './theme.treat'

const App: React.FC = ({ children }) => (
  <TreatProvider theme={theme}>{children}</TreatProvider>
)

Now that everyhing is in place, we can now style our components!

import React from 'react'
import { Box } from '@walltowall/calico'

export const Example = () => (
  <Box styles={{ color: 'black', margin: [1, 0] }}>
    I will be the color black!
  </Box>
)

API

All exported components and functions are documented via TSDoc.

View the source files using the links below to read each component or function's documentation.

  • Components
    • Box — Component that accepts atomic styles via props and resolves them to classNames,
  • Hooks
    • useBoxStyles — Low level react hook to resolve atomic CSS styles to classNames.
    • usePsuedoBoxStyles — Low level hook to resolve pseudo atomic CSS styles to classNames.
  • Functions
    • createCalicoTheme — Creates a treat compatible theme object whose rules are merged with the default calico rules.
    • mapFontsets — Utility function for generating treat styles that remove the leading and trailing white-space for your fonts.
    • createMq — Low level higher-order function that returns a version of style from treat that accepts ResponsiveProp inputs. This is automatically added to your theme in createCalicoTheme under theme.mq. Should not need to use this directly, but is provided if needed.
    • normalizeResponsiveProp — Low level function for normalizing a value to be a valid ResponsiveProp.
    • resolveResponsiveProp — Low level utility for resolving a ResponsiveProp to a list of classNames.
  • Other Exports
    • baseCalicoTheme — A theme object that contains all of the default rules and variants.
    • ResponsiveProp — A type that represents a valid responsive array.
    • SafeReactHTMLAttributes — A type that represents all safe React HTML props that are passed to <Box />.