# React Design Toolkit

The React implementation of Pantheon's Design System

## Status

[![Coverage Status](https://coveralls.io/repos/github/pantheon-systems/design-toolkit-react/badge.svg?branch=main&t=JSDit4)](https://coveralls.io/github/pantheon-systems/design-toolkit-react?branch=main)

## Contributing

To contribute any changes, updates, or new components to the Design Toolkit [please follow the governance guidelines](https://docs.google.com/document/d/16Ey4XzW6wTRZwizQfgdH6Bl2If1oN70mVVR0f4Ry1ek/edit?usp=sharing).

## Development setup

**Prerequisites:**

- You must update your NPM config to allow for Font Awesome Pro: [Wiki](https://getpantheon.atlassian.net/wiki/spaces/VULCAN/pages/526254084/NPM+Configurations+Font+Awesome)
- Install Node.js with the active LTS version. To install the LTS version, you can use NVM (Node Version Manager), N version manager, or any other node manager tool.
  - Option: N
    - Run `yarn install -g n`
    - Run `n lts`
  - Option: NVM
    - Run `curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash` to install NVM.
    - Run `nvm install --lts`.

1. `yarn install` will get all the deps down
2. `yarn build` will get the toolkit built
3. `yarn storybook` will then open a browser tab that shows the completed components in storybook

## Optional setup configuration

**Automatic Node version switching**

- Set up automatic Node version switching on `.nvmrc` (optional):

  - For `nvm` as a Version manager, the following might help you:

    - If you happen to be a `bash` user, you can refer to [this script](https://github.com/nvm-sh/nvm#bash) on `nvm` README.

      - Please note that this will search up for a `.nvmrc` from your current working dir.

    - If you are more a `zsh` user, you can use [this script](https://github.com/nvm-sh/nvm#zsh) on `nvm` README.
    - If you use `fish`, there's also a [script](https://github.com/nvm-sh/nvm#fish) on `nvm` README for you.
      - This one requires you to have [bass](https://github.com/edc/bass) installed.

  - For `n` as a Version manager, it seems that it already does the switching for you,
    given that you have a version labeled as `auto` on `n`:

    - There is an auto label to read the target version from a file in the current directory, or any parent directory. n looks for in order:

      - `.n-node-version`: version on single line. Custom to n.
      - `.node-version`: version on single line. Used by multiple tools: node-version-usage
      - `.nvmrc`: version on single line. Used by nvm.
      - if no version file found, look for engine in `n` docs. More specifically, the part after the `auto` label instructions on [Specifying Node Versions](https://github.com/tj/n#specifying-node-versions).

## Testing commands

1. `yarn test` Run tests
2. `yarn test <dir-name or file-name>` Run tests on a specific file or directory only
3. `yarn test -u` Update snapshots

## Tagging Releases

[Follow the instructions found in our Wiki.](https://getpantheon.atlassian.net/wiki/spaces/VULCAN/pages/557580599/Publishing+Libraries)

## Design Toolkit Documentation

[Find Design Toolkit Documentation in its Storybook.](https://pantheon-systems.github.io/design-toolkit-react)

Please feel free to open a pull request in this repo to update the documentation. The more documentation, the better!

## Adopted Practices

General principles for maintaining healthy code. It's important to revisit this by adding to, or changing these as we learn.

### We Must

- We must include usage guidelines in the "style guide" output

### We Should

- We should use the id generator from the `@reach/auto-id` [library](https://reach.tech/auto-id/) for any elements where we need to use the `id` attribute, in order to avoid potential collisions when toolkit components get rendered on the same page. Example usage:

```
import { useId } from "@reach/auto-id";

// Pass in a user-supplied ID that will be used conditionally if provided
const id = useId(props.id);

<div class="foo-bar" id={id}>
```

- We should trend toward smaller, simpler components that are composed of each other vs. relying more on props to allow for simpler usage of the components in the toolkit.
- We should _not_ allow styles to be ovewritten by the consumer of the toolkit, but we should provide a clear API that makes it obvious when the consumer is overwriting styles (eg. `<BadStyleOverwrite/>`) where needed. The exception to this rule is allowing unstyled, or mostly unstlyed, primatives to accept styling (eg. `<ButtonBase/>`).

[Initial exploration into the API](https://github.com/pantheon-systems/hermes/pull/1927)

## Installation

### Published version

1. `yarn add @pantheon-systems/design-toolkit-react`
2. Install peer dependencies
3. Import `@pantheon-systems/design-toolkit-react/dist/index.css` into the entry point of your application. (ex. `index.jsx`)

### Local version for testing this package locally

Linking to this package locally via Yarn link will not work because there are known bugs with loading 2 copies of react. We can accomplish this instead via [Yalc](https://github.com/wclr/yalc):

1. Follow installation instructions to install yalc on your machine.
2. In the root folder, run `yarn build` to build your latest changes and then `yalc publish --private`
3. Run `yalc add @pantheon-systems/design-toolkit-react` in the consumer's root folder
4. If this is the first time the consumer is installing the toolkit, you will have to complete steps 2 and 3 of the [installation instructions for the published version](#published-version)
5. When changes are made locally, you can build them and then run `yalc push --private`. This will update all instances of the package in your projects that have added it through yalc.
6. When local testing is complete, run `yalc remove @pantheon-systems/design-toolkit-react` in the consumer to remove the yalc copy from node_modules.
