Skip to content
12 changes: 12 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# AGENTS.md

React component library for [Cloudscape Design System](https://cloudscape.design/) — an open source design system for building accessible, inclusive web experiences at scale.

## Getting Started

See [docs/SETUP.md](docs/SETUP.md) for setup, building, and running locally.

## Docs Index

See [docs/CLOUDSCAPE_COMPONENTS_GUIDE.md](docs/CLOUDSCAPE_COMPONENTS_GUIDE.md) for guides on component conventions, styling, writing tests, and more.
For running tests and configs, see [docs/RUNNING_TESTS.md](docs/RUNNING_TESTS.md).
198 changes: 6 additions & 192 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,9 @@

Use this repository to [create bug reports or feature requests](https://github.com/cloudscape-design/components/issues/new/choose). You can also [start a discussion](https://github.com/cloudscape-design/components/discussions) to ask a question. We will do our best to reply. To minimize duplicates, we recommend that you search for existing bug reports, feature requests, or discussions before initiating a new thread.

## Versioning
## Documentation

We release patch versions on a daily basis to release bug fixes and new features and components. Patch versions do not contain breaking changes.

### Public APIs

Our public API consists of

- [Components APIs](https://cloudscape.design/components) (properties, slots, events, functions)
- [Test utilities](https://cloudscape.design/get-started/testing/introduction/)
- Typescript definitions
- [Design tokens](https://cloudscape.design/foundation/visual-foundation/design-tokens)

The inner HTML structure and class names of our components are not part of our APIs. Modifications to those are not considered breaking changes.

## Frameworks support

We support

- React 16.8+
- Jest 25+

## Browsers support

We support the latest 3 *major* versions of these browsers for desktop:
- Google Chrome
- Mozilla Firefox
- Microsoft Edge

and the latest three *minor* versions of Apple Safari for macOS for desktop.

We do not support Microsoft Internet Explorer or mobile browsers. We support all viewport sizes across desktop browsers.
For detailed guides on component conventions, styling, writing tests, and more, see the [Cloudscape Components Guide](docs/CLOUDSCAPE_COMPONENTS_GUIDE.md).

## How to contribute code

Expand Down Expand Up @@ -67,178 +38,21 @@ Clone this repository and install the dependencies:
```
git clone git@github.com:cloudscape-design/components.git
cd components
npm install
```

To generate the build artifacts, run the following command:

```
npm run build
```

Then, start the dev-server by running:

```
npm start
```

This will open a webpack-dev-server at http://localhost:8080 and watch
for file changes.
For setup, building, and running locally, see [Setup](docs/SETUP.md).

### Quick rebuild

To quickly rebuild this package, run `npm run quick-build`. This runs only the source code build, skipping
documentation and screenshot testing builds.
To quickly rebuild this package, run `npm run quick-build`. This runs only the source code build, skipping documentation and screenshot testing builds.

### Running tests

The package contains three types of tests:

- **Build-tool tests** test the build-tools code in a NodeJS context.
- **Unit tests** emulate a browser environment using JSDOM.
- **Integration tests** test against real browser behavior on Chrome, with motion disabled.
- **Motion tests** run a specific set of tests on Chrome, with motion enabled.

#### Run all tests:

```
npm test
```

#### Run build tool and unit tests:

```
npm run test:unit
```

#### Run integration tests:

If you're running integration tests on a Mac, make sure you have ChromeDriver:

```
npm i -g chromedriver
```

Then, run the dev server and integration tests in separate terminals:

```
npm start
```

```
npm run test:integ
```

#### Run motion tests:

As in integration tests, make sure you have ChromeDriver installed and start the dev server:

```
npm i -g chromedriver
npm start
```

Then, run the motion tests in a separate terminal:

```
npm test:motion
```

#### Run a single test suite

To run a single test suite, you can call Jest directly using the appropriate config:

```
# Run a single button unit test suite
npx jest -c jest.unit.config.js src/button/__tests__/button.test.tsx

# Run all input integration tests
npx jest -c jest.integ.config.js src/input

# Run motion tests for the flashbar component
npx jest -c jest.motion.config.js src/flashbar

# Test all stylelint rules
npx jest -c jest.build-tools.config.js build-tools/stylelint
```

Note: when running jest directly you may see errors about `--experimental-vm-modules`, to fix this you can set this NodeJS flag as follows:

```
export NODE_OPTIONS="$NODE_OPTIONS --experimental-vm-modules"
```

Alternatively, you can set the flag inline with the command:

```
# Run a single integration test file
NODE_OPTIONS='--experimental-vm-modules' npx jest -c jest.integ.config.js src/input/__integ__/input.test.ts
```

#### Updating all snapshots

When component APIs change, you may need to update test snapshots. Use the `-u` flag to update snapshots:

```
npx jest -u snapshot -c jest.unit.config.js src/
```

### Run visual regression tests

Visual regression tests for the permutation pages are automatically run when opening a pull request in GitHub.

#### Checking results in a pull requests

To look at the results of the tests, check the details of the "Visual Regression Tests" action in the pull request.
The logs of the "Test for regressions" step should indicate what pages failed the regression tests.

To check the full report in a browser, go to the action summary and download the `visual-regression-results` artifacts.
Unzip the downloaded archive and open the `html_report/index.html` file in your browser.

If there are unexpected regressions, fix your pull request.
If the changes are expected, call this out in your pull request comments.
For targeting specific files, updating snapshots, ChromeDriver setup, and visual regression tests, see [docs/RUNNING_TESTS.md](docs/RUNNING_TESTS.md).

### Directory layout

```
├── __mocks__ - jest mocks for external dependencies
├── build-tools - build tasks and configuration for gulp
├── pages - react pages for development, scenario and permutation testing
│ └── <page>.page.tsx
├── src
│ ├── __a11y__ - global a11y tests for all components
│ ├── __integ__ - global integ tests for all components
│ ├── __tests__ - global unit tests for all components
| |
│ ├── <component-dir>
│ │ ├── __tests__ - jest unit tests
│ │ ├── __integ__ - jest integration tests
│ │ ├── __motion__ - jest motion tests
│ │ ├── index.tsx - main component file (imports other files and styles)
│ │ └── styles.scss - main SCSS file
| │
| ├── test-utils - test utils for components
│ │ ├── dom - main source code for test utils
│ │ └── selectors - utils for integration testing, generated from the code in `dom` folder
| |
| └── internal - library internals
| ├── base-component - necessary declarations for every public component
| ├── components - internal utility components
| ├── events - utilities for firing public events
| ├── hooks - internal utility hooks
| └── generated - generated code from style-dictionary
| └── styles - base styles and SCSS-mixins
├── lib - build output
| ├── components - the primary components package
| ├── components-definitions – generated metadata for components
| └── design-tokens - exported design tokens
|
└── style-dictionary - style dictionary tokens and roles
```
See [docs/DIRECTORY_LAYOUT.md](docs/DIRECTORY_LAYOUT.md) for the full repo structure.

## Code of Conduct

Expand Down
15 changes: 15 additions & 0 deletions docs/API_DOCS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# API Documentation Comments

This project uses `@cloudscape-design/documenter` to generate API docs from JSDoc comments in component interface files (`src/<component>/interfaces.ts`).

## Special Tags

- `@i18n` — marks internationalization properties
- `@analytics` — marks analytics metadata properties
- `@deprecated` — marks deprecated properties (include replacement info)
- `@displayname` — overrides the display name (e.g. `children``text`)
- `@awsuiSystem` — tags a property or import by internal system (e.g. `@awsuiSystem core`), used for internal classification

## Sub-types

Define union types as named type aliases in the component's namespace, not as inline unions. Then reference them in the interface: `variant?: ButtonProps.Variant`.
13 changes: 13 additions & 0 deletions docs/CLOUDSCAPE_COMPONENTS_GUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Cloudscape Components Documentation

Reference docs for contributing to [cloudscape-design/components](https://github.com/cloudscape-design/components).

- [General Guide](https://github.com/cloudscape-design/components/blob/main/docs/GENERAL_GUIDE.md) — setup, building, running locally, frameworks, versioning
- [Component Conventions](https://github.com/cloudscape-design/components/blob/main/docs/COMPONENT_CONVENTIONS.md) — component structure, props, events, refs
- [Styling](https://github.com/cloudscape-design/components/blob/main/docs/STYLING.md) — design tokens, CSS rules, RTL support
- [Writing Tests](https://github.com/cloudscape-design/components/blob/main/docs/WRITING_TESTS.md) — test utils, unit and integration tests
- [Running Tests](https://github.com/cloudscape-design/components/blob/main/docs/RUNNING_TESTS.md) — test configs and commands
- [Code Style](https://github.com/cloudscape-design/components/blob/main/docs/CODE_STYLE.md) — prettier, stylelint, eslint
- [TEST Pages](https://github.com/cloudscape-design/components/blob/main/docs/TEST_PAGES.md) — dev/test pages and running in the browser
- [API Docs](https://github.com/cloudscape-design/components/blob/main/docs/API_DOCS.md) — API documentation comments
- [Internals](https://github.com/cloudscape-design/components/blob/main/docs/INTERNALS.md) — internal shared utilities
9 changes: 9 additions & 0 deletions docs/CODE_STYLE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Code Style

Run `npm run lint` to check formatting and linting. The project uses:

- **Prettier** for code formatting
- **Stylelint** for CSS/SCSS linting
- **ESLint** for JavaScript/TypeScript linting

See the respective config files in the project root for rules.
72 changes: 72 additions & 0 deletions docs/COMPONENT_CONVENTIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Component Conventions

## Component Structure

Each component is exposed from `src/<component-name>/index.tsx`.

- `applyDisplayName` — readable name in consumers' devtools

### Internal Component (`internal.tsx`)

The APIs exported from `src/<component>/index.tsx` are public and must not be used internally by other components. For internal usage, each component exposes a private counterpart at `internal.tsx`.

## Props & Interfaces

- Props interface: `${ComponentName}Props`, namespace sub-types under it (e.g. `${ComponentName}Props.Variant`)
- Union types must be type aliases (no inline unions)
- Array types must use `ReadonlyArray<T>`

For how to document props, see [API_DOCS.md](API_DOCS.md).

## Events

Use `CancelableEventHandler<DetailType>` or `NonCancelableEventHandler<DetailType>`. All `on*` props must use these interfaces (build fails otherwise).

Events are similar to native events with `event.preventDefault()` for cancelable events, but are not dispatched via DOM.

## Refs

The component ref API does not give access to the underlying DOM node. Instead, we expose specific methods — most commonly `focus()`, for which a dedicated util `useForwardFocus` is available.

When a component accepts a ref, create `${ComponentName}ForwardRefType` as follows:

```tsx
interface MyComponentForwardRefType {
<T>(props: MyComponentProps<T> & { ref?: React.Ref<MyComponentProps.Ref> }): JSX.Element;
}
```

## Controllable Components

Use the same behavior as built-in React components:

1. If only `onChange` is provided → uncontrolled (component manages its own state, `onChange` fires for side effects)
2. If `value` is provided → controlled (with or without `onChange`; without `onChange` it's read-only)

Implementation:
1. Create a controlled component first
2. Use `useControllable` to wrap customer-provided properties — gives you a `[value, setValue]` pair
3. If `value` is provided without `onChange`, `useControllable` emits a console warning

## I18n

Centralize all translatable strings under a skippable property (e.g. `i18nStrings`). Internationalization code lives in `src/i18n/`. The `useInternalI18n` hook is what components use to resolve translated strings.

```tsx
const i18n = useInternalI18n('alert');
<InternalButton ariaLabel={i18n('dismissAriaLabel', dismissAriaLabel)} />
```

## Dependencies

Before adding any dependency: must support React 16.8+ and latest 3 major Chrome/Firefox/Edge, no global state, ESM preferred.

## Test Utils

Test-utils core is a separate package: https://github.com/cloudscape-design/test-utils

- Test-utils should not have any dependencies — they can be used with any tech stack.
- Test-utils extend `ComponentWrapper`. `ElementWrapper` is only a return type when no more specific type is available.
- Methods must have explicitly declared return types (enforced via ESLint).
- Wrapper classes must have a static `rootSelector` property.
- For methods that always return a value, add a non-null assertion.
43 changes: 43 additions & 0 deletions docs/DIRECTORY_LAYOUT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Directory Layout

```
├── __mocks__ - jest mocks for external dependencies
├── build-tools - build tasks and configuration for gulp
├── pages - react pages for development, scenario and permutation testing
│ └── <page>.page.tsx
├── src
│ ├── __a11y__ - global a11y tests for all components
│ ├── __integ__ - global integ tests for all components
│ ├── __tests__ - global unit tests for all components
│ │
│ ├── <component-dir>
│ │ ├── __tests__ - jest unit tests
│ │ ├── __integ__ - jest integration tests
│ │ ├── __motion__ - jest motion tests
│ │ ├── index.tsx - main component file (imports other files and styles)
│ │ └── styles.scss - main SCSS file
│ │
│ ├── test-utils - test utils for components
│ │ ├── dom - main source code for test utils
│ │ └── selectors - utils for integration testing, generated from the code in `dom` folder
│ │
│ ├── i18n - internationalization: messages, providers, and the useInternalI18n hook
│ │
│ └── internal - library internals
│ ├── base-component - necessary declarations for every public component
│ ├── components - internal utility components
│ ├── events - utilities for firing public events
│ ├── hooks - internal utility hooks
│ ├── generated - generated code from style-dictionary
│ └── styles - base styles and SCSS-mixins
├── lib - build output
│ ├── components - the primary components package
│ ├── components-definitions - generated metadata for components
│ └── design-tokens - exported design tokens
└── style-dictionary - design token definitions (colors, spacing, typography, etc.)
```
Loading
Loading