Convert Figma logo to code with AI

reach logoreach-ui

The Accessible Foundation for React Apps and Design Systems

5,964
561
5,964
101

Top Related Projects

37,442

⚡️ Simple, Modular & Accessible UI Components for your React Applications

Radix Primitives is an open-source UI component library for building high-quality, accessible design systems and web apps. Maintained by @workos.

A collection of libraries and tools that help you build adaptive, accessible, and robust user experiences.

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.

Completely unstyled, fully accessible UI components, designed to integrate beautifully with Tailwind CSS.

Quick Overview

Reach UI is a collection of accessible and composable React components designed to create user interfaces with a focus on accessibility and usability. It provides a set of low-level UI primitives that can be used to build more complex components and applications while ensuring adherence to WAI-ARIA standards.

Pros

  • Strong focus on accessibility, making it easier to create inclusive web applications
  • Highly composable components that can be customized and extended
  • Well-documented with examples and guidelines for proper usage
  • Lightweight and modular, allowing developers to use only the components they need

Cons

  • Limited set of components compared to some larger UI libraries
  • May require additional styling and customization for more complex designs
  • Learning curve for developers unfamiliar with accessibility best practices
  • Some components may have performance implications in certain scenarios

Code Examples

  1. Using the Dialog component:
import { Dialog } from "@reach/dialog";
import "@reach/dialog/styles.css";

function App() {
  const [showDialog, setShowDialog] = React.useState(false);
  const open = () => setShowDialog(true);
  const close = () => setShowDialog(false);

  return (
    <div>
      <button onClick={open}>Open Dialog</button>
      <Dialog isOpen={showDialog} onDismiss={close}>
        <h2>Dialog Content</h2>
        <p>This is an accessible dialog.</p>
        <button onClick={close}>Close</button>
      </Dialog>
    </div>
  );
}
  1. Using the Menu component:
import { Menu, MenuList, MenuButton, MenuItem } from "@reach/menu-button";
import "@reach/menu-button/styles.css";

function App() {
  return (
    <Menu>
      <MenuButton>
        Actions <span aria-hidden></span>
      </MenuButton>
      <MenuList>
        <MenuItem onSelect={() => alert("Download")}>Download</MenuItem>
        <MenuItem onSelect={() => alert("Copy")}>Create a Copy</MenuItem>
        <MenuItem onSelect={() => alert("Delete")}>Delete</MenuItem>
      </MenuList>
    </Menu>
  );
}
  1. Using the Tabs component:
import { Tabs, TabList, Tab, TabPanels, TabPanel } from "@reach/tabs";
import "@reach/tabs/styles.css";

function App() {
  return (
    <Tabs>
      <TabList>
        <Tab>One</Tab>
        <Tab>Two</Tab>
        <Tab>Three</Tab>
      </TabList>
      <TabPanels>
        <TabPanel>
          <p>Panel One</p>
        </TabPanel>
        <TabPanel>
          <p>Panel Two</p>
        </TabPanel>
        <TabPanel>
          <p>Panel Three</p>
        </TabPanel>
      </TabPanels>
    </Tabs>
  );
}

Getting Started

To start using Reach UI in your React project:

  1. Install the package:
npm install @reach/component-name
  1. Import the component and its styles:
import { ComponentName } from "@reach/component-name";
import "@reach/component-name/styles.css";
  1. Use the component in your React application:
function App() {
  return (
    <ComponentName>
      {/* Component content */}
    </ComponentName>
  );
}

Replace component-name with the specific Reach UI component you want to use (e.g., dialog, menu-button, tabs).

Competitor Comparisons

37,442

⚡️ Simple, Modular & Accessible UI Components for your React Applications

Pros of Chakra UI

  • More comprehensive component library with a wider range of pre-built components
  • Highly customizable theming system with built-in dark mode support
  • Better documentation and larger community support

Cons of Chakra UI

  • Steeper learning curve due to its extensive API and features
  • Larger bundle size, which may impact initial load times
  • More opinionated styling approach, which might not suit all project needs

Code Comparison

Reach UI:

import { Menu, MenuButton, MenuList, MenuItem } from "@reach/menu-button"

<Menu>
  <MenuButton>Actions</MenuButton>
  <MenuList>
    <MenuItem onSelect={() => alert("Download")}>Download</MenuItem>
    <MenuItem onSelect={() => alert("Copy")}>Create a Copy</MenuItem>
  </MenuList>
</Menu>

Chakra UI:

import { Menu, MenuButton, MenuList, MenuItem, Button } from "@chakra-ui/react"

<Menu>
  <MenuButton as={Button}>Actions</MenuButton>
  <MenuList>
    <MenuItem onClick={() => alert("Download")}>Download</MenuItem>
    <MenuItem onClick={() => alert("Copy")}>Create a Copy</MenuItem>
  </MenuList>
</Menu>

Both libraries offer similar component structures, but Chakra UI provides more styling options out of the box and integrates with its own Button component.

Radix Primitives is an open-source UI component library for building high-quality, accessible design systems and web apps. Maintained by @workos.

Pros of Primitives

  • More extensive component library with a wider range of UI elements
  • Stronger focus on customization and theming capabilities
  • Better TypeScript support and type definitions

Cons of Primitives

  • Steeper learning curve due to more complex API and configuration options
  • Less opinionated styling, which may require more work for consistent designs

Code Comparison

Primitives (Dialog component):

import * as Dialog from '@radix-ui/react-dialog';

<Dialog.Root>
  <Dialog.Trigger>Open</Dialog.Trigger>
  <Dialog.Portal>
    <Dialog.Overlay />
    <Dialog.Content>
      <Dialog.Title>Dialog Title</Dialog.Title>
      <Dialog.Description>Dialog content here</Dialog.Description>
      <Dialog.Close>Close</Dialog.Close>
    </Dialog.Content>
  </Dialog.Portal>
</Dialog.Root>

Reach UI (Dialog component):

import { Dialog } from '@reach/dialog';

<Dialog isOpen={showDialog} onDismiss={close}>
  <h2>Dialog Title</h2>
  <p>Dialog content here</p>
  <button onClick={close}>Close</button>
</Dialog>

Both libraries provide accessible and customizable UI components for React applications. Primitives offers a more extensive set of components with greater customization options, while Reach UI focuses on simplicity and ease of use. The choice between the two depends on project requirements, team expertise, and desired level of control over component styling and behavior.

A collection of libraries and tools that help you build adaptive, accessible, and robust user experiences.

Pros of React Spectrum

  • Comprehensive design system with a wide range of components
  • Robust accessibility features and internationalization support
  • Extensive documentation and design guidelines

Cons of React Spectrum

  • Larger bundle size due to its comprehensive nature
  • Steeper learning curve for developers new to the system
  • Less flexibility for custom styling compared to Reach UI

Code Comparison

React Spectrum:

import { Button } from '@adobe/react-spectrum'

function MyComponent() {
  return <Button variant="cta">Click me</Button>
}

Reach UI:

import { Button } from '@reach/button'

function MyComponent() {
  return <Button>Click me</Button>
}

React Spectrum provides more built-in styling options and variants, while Reach UI offers a simpler API that requires custom styling for advanced appearances.

Both libraries prioritize accessibility, but React Spectrum includes more comprehensive features out-of-the-box. Reach UI is generally lighter-weight and more flexible, making it easier to integrate into existing projects. React Spectrum, on the other hand, offers a more complete design system experience, which can be beneficial for larger applications or those seeking consistency with Adobe's design language.

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.

Pros of Material-UI

  • Extensive component library with a wide range of pre-built UI elements
  • Robust theming system for easy customization and consistent design
  • Large community and ecosystem with extensive documentation and support

Cons of Material-UI

  • Larger bundle size due to comprehensive feature set
  • Steeper learning curve for advanced customization
  • Opinionated design system may require more effort to deviate from Material Design

Code Comparison

Material-UI:

import { Button, TextField } from '@mui/material';

<Button variant="contained" color="primary">
  Submit
</Button>
<TextField label="Name" variant="outlined" />

Reach UI:

import { Button } from '@reach/button';

<Button>Submit</Button>
<input type="text" placeholder="Name" />

Key Differences

  • Material-UI offers more out-of-the-box styling and variants
  • Reach UI focuses on accessibility and minimal styling
  • Material-UI components are more opinionated in terms of design
  • Reach UI provides a lighter-weight alternative with fewer dependencies

Use Cases

  • Material-UI: Ideal for large-scale applications requiring a comprehensive UI kit
  • Reach UI: Better suited for projects prioritizing accessibility and custom styling

Community and Ecosystem

  • Material-UI has a larger user base and more third-party extensions
  • Reach UI has a growing community focused on accessibility-first development

Completely unstyled, fully accessible UI components, designed to integrate beautifully with Tailwind CSS.

Pros of Headless UI

  • Fully unstyled components, offering maximum flexibility for custom designs
  • Seamless integration with Tailwind CSS for rapid development
  • Supports both React and Vue.js frameworks

Cons of Headless UI

  • Less extensive component library compared to Reach UI
  • Steeper learning curve for developers unfamiliar with headless UI concepts
  • May require more initial setup and customization for complex components

Code Comparison

Reach UI (Dropdown):

<Menu>
  <MenuButton>
    Actions <span aria-hidden></span>
  </MenuButton>
  <MenuList>
    <MenuItem onSelect={() => alert("Download")}>Download</MenuItem>
    <MenuItem onSelect={() => alert("Copy")}>Create a Copy</MenuItem>
  </MenuList>
</Menu>

Headless UI (Dropdown):

<Menu as="div">
  <Menu.Button>Actions</Menu.Button>
  <Menu.Items>
    <Menu.Item>
      {({ active }) => (
        <a className={`${active && 'bg-blue-500'}`} href="/download">
          Download
        </a>
      )}
    </Menu.Item>
    <Menu.Item>
      {({ active }) => (
        <a className={`${active && 'bg-blue-500'}`} href="/copy">
          Create a Copy
        </a>
      )}
    </Menu.Item>
  </Menu.Items>
</Menu>

Both libraries provide accessible and customizable components, but Headless UI offers more granular control over styling and behavior at the cost of additional setup complexity.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Welcome to Reach UI Development ♿️

Thanks for getting involved with Reach UI development!

Looking for the documentation?

https://reach.tech/

Getting Started

Reach UI is built and tested with Yarn. Please follow their install instructions to get Yarn installed on your system.

Then, run these commands:

git clone git@github.com:reach/reach-ui.git
cd reach-ui
pnpm install
pnpm build

Root Repo Scripts:

pnpm build        # builds all packages
pnpm dev        # starts storybook server
pnpm test         # runs tests in all packages

Running / Writing Examples

First do the steps in "Getting started", then start the Storybook server:

pnpm dev

Next, put a file in packages/<component-dir>/examples/<name>.example.js and make it look like this:

import * as React from "react";

// The name of the example (always name the variable `name`)
let name = "Basic";

// The example to render (always name the function `Example`)
function Example() {
	return <div>Cool cool cool</div>;
}

// Assign the name to the example and then export it as a named constant
Example.storyName = name;
export const Basic = Example;

// Default export an object with the title matching the name of the Reach package
export default { title: "Dialog" };

Now you can edit the files in packages/* and storybook will automatically reload your changes.

Note: If you change an internal dependency you will need to run yarn build again. For example, if working on MenuButton requires a change to Rect (an internal dependency of MenuButton), you will need to run yarn build for the changes to Rect to show up in your MenuButton example.

Running / Writing Tests

First do the steps in "Getting Started", then:

pnpm test

Or if you want to run the tests as you edit files:

pnpm test --watch

Often you'll want to just test the component you're working on:

cd packages/<component-path>
pnpm test --watch

Development Plans

The components to be built come from the the Aria Practices Design Patterns and Widgets, with a few exceptions. Here is a table of the components and their status.

✅ - Released
🛠 - Building

StatusName
✅Accordion
✅Alert
✅Alert Dialog
✅Checkbox
✅Combo Box
✅Dialog (Modal)
✅Disclosure
🛠Hover Card
✅Listbox
✅Menu Button
🛠Radio Group
✅Slider
✅Tabs
🛠Toggletip
✅Tooltip

Releases [DEPRECATED]

This is (was?) our current release process. It's not perfect, but it has almost the right balance of manual + automation for me. We might be able to put some of this in a script...

$ git checkout main
$ git pull origin main
$ git checkout dev
$ git pull origin dev
$ git checkout -b release-<version>
$ git merge main

# Resolve any merge conflicts and commit if necessary

# Run the build locally and make sure there are no problems
$ pnpm build
$ pnpm test

# Check out the `main` branch and merge release changes from `dev`
$ git checkout main
$ git pull origin main
$ git merge dev

# Write the changelog based on commits. We'll automate this part
# eventually, but for now this is manual.

# Then create a new version and git tag locally. Don't push yet!
$ pnpm ver [version]

# Take a look around and make sure everything is as you'd expect.
# You can inspect everything from the commit that lerna made with:
$ git log -p

# If something needs to be changed, you can undo the commit and
# delete the tag that lerna created and try again.

# If everything looks good, push to GitHub along with the new tag:
$ git push origin main --follow-tags

# Open up https://github.com/reach/reach-ui/actions and watch the build. There will
# be 2 builds, one for the push to the main branch and one for the
# new tag. The tag build will run the build and all the tests and then
# automatically publish to npm if everything passes. If there's a
# problem, we have to figure out how to fix manually.

# Paste the changelog into the release on GitHub. The release is
# complete … huzzah!

You need to be careful when publishing a new package because the lerna publish on CI will fail for new packages. To get around this, you should publish a 0.0.0 version of the package manually ahead of time. Then the release from CI will be ok. This is really janky but AFAICT the only workaround.

Stuff I'd like to improve:

  • Automate changelog generation and GitHub release from CI
  • Document how we're using GitHub PRs to generate the changelog somewhere

Website

The website is a Gatsby app in the website directory. It automatically deploys to https://reach.tech/ when the website branch is updated.