Setup

How to setup your project to use Foundations.

Prerequisites

We are using React 19. If you still on 18, please check the React 19 migration guide.
A few common changes are:

  • ref is now a prop like the others, so we don't need to use forwardRef.
  • <Context> as a provider: You can now render <Context> as a provider instead of <Context.Provider>.
  • use can be used instead of useContext.
  • MutableRefObject is now RefObject.

It's possible to use these components in React 18, but you will have to adapt the code as needed.

Installation

Install the core dependencies:

npm install cva@beta tailwind-merge

We are using CVA 1.0.0 (beta). Check what's new in their docs.

CSS Setup

@import "tailwindcss";
 
@theme {
  /* Typography */
  --text-2xs: 0.625rem;
 
  /* Colors */
  --color-background: oklch(100% 0 0);
  --color-background-secondary: oklch(95% 0 0);
 
  --color-foreground: oklch(0% 0 0);
  --color-foreground-secondary: oklch(65% 0 0);
 
  --color-border: oklch(94% 0 0);
  --color-border-hard: oklch(92% 0 0);
 
  --color-ring: oklch(0% 0 0 / 0.1);
 
  /* Shadows */
  --shadow-*: initial;
  --shadow-xs: 0 1px 2px oklch(0 0 0 / 0.03);
  --shadow-sm: 0 1px 2px oklch(0 0 0 / 0.02), 0 2px 4px oklch(0 0 0 / 0.02);
  --shadow-md: 0 2px 3px oklch(0 0 0 / 0.02), 0 3px 6px oklch(0 0 0 / 0.02);
  --shadow-lg:
    0 2px 4px oklch(0 0 0 / 0.02), 0 4px 8px oklch(0 0 0 / 0.02),
    0 8px 16px oklch(0 0 0 / 0.02);
}
 
@media (prefers-color-scheme: dark) {
  :root {
    --color-background: oklch(12% 0 0);
    --color-background-secondary: oklch(22% 0 0);
 
    --color-foreground: oklch(95% 0 0);
    --color-foreground-secondary: oklch(53% 0 0);
 
    --color-border: oklch(26% 0 0);
    --color-border-hard: oklch(28% 0 0);
 
    --color-ring: oklch(100% 0 0 / 0.12);
  }
 
  body {
    color-scheme: dark;
  }
}
 
body {
  font-family: var(--font-sans);
 
  background-color: var(--color-background);
  color: var(--color-foreground);
 
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
@import "tailwindcss";
 
@variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));
 
@theme {
  /* Typography */
  --text-2xs: 0.625rem;
 
  /* Colors */
  --color-background: oklch(100% 0 0);
  --color-background-secondary: oklch(95% 0 0);
 
  --color-foreground: oklch(0% 0 0);
  --color-foreground-secondary: oklch(65% 0 0);
 
  --color-border: oklch(94% 0 0);
  --color-border-hard: oklch(92% 0 0);
 
  --color-ring: oklch(0% 0 0 / 0.1);
 
  /* Shadows */
  --shadow-*: initial;
  --shadow-xs: 0 1px 2px oklch(0 0 0 / 0.03);
  --shadow-sm: 0 1px 2px oklch(0 0 0 / 0.02), 0 2px 4px oklch(0 0 0 / 0.02);
  --shadow-md: 0 2px 3px oklch(0 0 0 / 0.02), 0 3px 6px oklch(0 0 0 / 0.02);
  --shadow-lg:
    0 2px 4px oklch(0 0 0 / 0.02), 0 4px 8px oklch(0 0 0 / 0.02),
    0 8px 16px oklch(0 0 0 / 0.02);
}
 
[data-theme="dark"] {
  color-scheme: dark;
 
  --color-background: oklch(12% 0 0);
  --color-background-secondary: oklch(22% 0 0);
 
  --color-foreground: oklch(95% 0 0);
  --color-foreground-secondary: oklch(53% 0 0);
 
  --color-border: oklch(26% 0 0);
  --color-border-hard: oklch(28% 0 0);
 
  --color-ring: oklch(100% 0 0 / 0.12);
}
 
body {
  font-family: var(--font-sans);
 
  background-color: var(--color-background);
  color: var(--color-foreground);
 
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

Utilities Setup

Create a lib/utils.ts file with our utility functions:

import { defineConfig } from "cva";
import { twMerge } from "tailwind-merge";
 
export const {
  cva,
  cx: cn,
  compose,
} = defineConfig({
  hooks: {
    onComplete: (className) => twMerge(className),
  },
});

Icons Setup

We use Phosphor Icons by default, but you can use any icon library of your choice:

npm install @phosphor-icons/react