From 889c5d0a4304f1383c5014a27eed1cef23fc8b8b Mon Sep 17 00:00:00 2001 From: Rob Snow Date: Mon, 20 Jul 2026 14:26:01 +1000 Subject: [PATCH 1/2] chore: add a Claude.md file to help with contributions --- CLAUDE.md | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000000..4a6ec69e0db --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,59 @@ +# CLAUDE.md + +Guidance for working in the react-spectrum monorepo. + +## Repo layout + +The repo is layered. Changes flow up from the lowest level: + +- **`@internationalized/*` and `@react-stately/*`** — the two lowest levels (i18n utilities and state management). +- **`@react-aria/*`** — behavior and accessibility hooks built on the above. +- **`react-aria-components` (RAC)** and some **React Spectrum v3 (RSP)** — component layer built on the hooks. +- **RSP S2 (`@react-spectrum/s2`)** — the Spectrum 2 design system, the highest level. + +Test suites are split by type: + +- **Jest tests** — `yarn test` +- **SSR tests** — `yarn test:ssr` +- **Browser tests** — `yarn test:browser` +- **Visual regression tests (VRT)** — `yarn chromatic` +- **High-contrast-mode VRT** — `yarn chromatic:forced-colors` + +Maintainers run the Chromatic VRT suites themselves — don't run `yarn chromatic` / `yarn chromatic:forced-colors`. You can still start the VRT Storybooks locally to verify visual state: `yarn start:chromatic` and `yarn start:chromatic-fc`. + +All commonly used commands live in the root `package.json` scripts. + +Tests are **not** co-located with source — each package keeps them in a sibling `test/` directory. The file suffix routes the test to a runner: `*.ssr.test.*` → `yarn test:ssr`, `*.browser.test.*` → `yarn test:browser`, plain `*.test.*` → `yarn test` (Jest). Shared test helpers live in `@react-aria/test-utils` / `@react-spectrum/test-utils` (the `User` event abstraction and per-component testers). + +## Tooling + +This repo does **not** use the conventional JS toolchain — reach for these, and don't hand-format code or swap in defaults: + +- **Format** — `oxfmt` (`yarn format`), not Prettier. The style is opinionated (single quotes, no bracket spacing → `{foo}`, no trailing commas). Always run the tool rather than formatting by hand. +- **Lint** — `oxlint` plus repo-local rules, not ESLint. `yarn lint` bundles format-check, type-check, `oxlint`, and Yarn `constraints` (which enforce cross-package dependency versions). +- **Type-check** — `tsgo` (`yarn check-types`), the native TypeScript compiler — not `tsc`. A `tsc` fallback exists as `yarn check-types:tsc`. +- **Build** — Parcel driven by `make` (`yarn build`), not plain `tsc`/rollup. +- **Yarn 4 workspaces** monorepo; use `yarn workspaces foreach` for cross-package operations. + +## Writing tests + +- **Run the full suite before committing.** Do not write PR descriptions that list a subset of specific passing tests — run everything (`yarn test`, and `yarn test:browser` when relevant). +- **Run lint and formatting before committing** (`yarn lint`, `yarn format`). +- **Test at the right level.** For any change at the RAC level or below (including hooks), write the test at the RAC level ideally. If the change lives at a higher level, test at that level. +- **Move to browser tests when needed.** If a test requires mocking specific browser behavior, consider moving it to the browser run (`yarn test:browser`). +- **Cover the reported issue.** When fixing a reported issue, add a test that reproduces the specific example given in the issue. +- **Check whether the test already exists.** Find a home for it near other similar tests. +- **Check code coverage** to decide whether a new test adds value — this is subjective. +- **In unit tests, prefer** fake timers, our test utils, and user event. +- **Keep comments minimal** — let the code speak for itself. +- **Combine tests** that share the same setup before an assertion. +- **Ground test titles in the goal**, not the implementation — double-check they are accurate. + +## Contributing + +- **Match the surrounding code** — follow the naming, structure, and patterns of neighboring files. +- **Commit format** — use conventional-commit prefixes (`fix:`, `feat:`, `chore:`, `docs:`) as seen in the git history. +- **Storybook** is the main way to develop and view components: `yarn start` (v3) and `yarn start:s2` (S2). +- **S2 styling** — style with the `style` macro (`import {style} from '../style' with {type: 'macro'};` — the `with {type: 'macro'}` attribute is load-bearing). Pass typed style objects to it; don't write CSS files or hand-rolled className strings for S2. +- **User-facing strings** — add the key to the package's `intl/en-US.json` (ICU MessageFormat) and read it via the localized string hook. Never hardcode UI text, and don't hand-edit the other locale files (translators own those). +- **Generated code** — icon components are generated (`yarn build:icons`), not hand-written, and `postinstall` runs `patch-package`, so run install on a fresh clone. From 55ac19ce58c254621be26f55428cd796e467ae96 Mon Sep 17 00:00:00 2001 From: Rob Snow Date: Tue, 28 Jul 2026 15:23:17 +1000 Subject: [PATCH 2/2] improving AI contribution expectations --- .github/PULL_REQUEST_TEMPLATE.md | 3 +++ CLAUDE.md | 13 ++++----- CONTRIBUTING.md | 46 ++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 85fa50515bf..3c0ae90bdb2 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,3 +1,4 @@ + Closes @@ -8,6 +9,8 @@ Closes - [ ] Filled out test instructions. - [ ] Updated documentation (if it already exists for this component). - [ ] Looked at the Accessibility Practices for this feature - [Aria Practices](https://www.w3.org/WAI/ARIA/apg/) +- [ ] I understand every change in this PR and can explain why it's there. +- [ ] If AI-assisted, I followed our [AI contribution guidance](https://github.com/adobe/react-spectrum/blob/main/CONTRIBUTING.md#ai-assisted-contributions) and pointed my assistant at [CLAUDE.md](https://github.com/adobe/react-spectrum/blob/main/CLAUDE.md). ## 📝 Test Instructions: diff --git a/CLAUDE.md b/CLAUDE.md index 4a6ec69e0db..0bfb77c6ff7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -43,17 +43,18 @@ This repo does **not** use the conventional JS toolchain — reach for these, an - **Move to browser tests when needed.** If a test requires mocking specific browser behavior, consider moving it to the browser run (`yarn test:browser`). - **Cover the reported issue.** When fixing a reported issue, add a test that reproduces the specific example given in the issue. - **Check whether the test already exists.** Find a home for it near other similar tests. -- **Check code coverage** to decide whether a new test adds value — this is subjective. -- **In unit tests, prefer** fake timers, our test utils, and user event. -- **Keep comments minimal** — let the code speak for itself. +- **Check code coverage** to help decide whether a new test adds value — this is subjective. +- **In unit tests, prefer** fake timers, our test utils, and user event. Aside from those, prefer not mocking other modules, instead, move the test to a higher level. - **Combine tests** that share the same setup before an assertion. - **Ground test titles in the goal**, not the implementation — double-check they are accurate. ## Contributing - **Match the surrounding code** — follow the naming, structure, and patterns of neighboring files. +- **Limit comments** — let the code speak for itself. Provide a holistic summary of how the changes work and why this approach was used in the description. If a particular section of code is complex, then prefer a higher level description of multiple lines over explaining a single line. - **Commit format** — use conventional-commit prefixes (`fix:`, `feat:`, `chore:`, `docs:`) as seen in the git history. -- **Storybook** is the main way to develop and view components: `yarn start` (v3) and `yarn start:s2` (S2). -- **S2 styling** — style with the `style` macro (`import {style} from '../style' with {type: 'macro'};` — the `with {type: 'macro'}` attribute is load-bearing). Pass typed style objects to it; don't write CSS files or hand-rolled className strings for S2. +- **Opening a PR** — use `.github/PULL_REQUEST_TEMPLATE.md` as the PR body (e.g. `gh pr create --body-file .github/PULL_REQUEST_TEMPLATE.md`), don't hand-write a body. Fill out the checklist honestly and disclose AI use. +- **Storybook** is the main way to develop and view components: `yarn start` (v3/RAC) and `yarn start:s2` (S2). +- **S2 styling** — style with the `style` macro (`import {style} from '../style' with {type: 'macro'};` — the `with {type: 'macro'}` attribute is required). Pass typed style objects to it; don't write CSS files or hand-rolled className strings for S2. - **User-facing strings** — add the key to the package's `intl/en-US.json` (ICU MessageFormat) and read it via the localized string hook. Never hardcode UI text, and don't hand-edit the other locale files (translators own those). -- **Generated code** — icon components are generated (`yarn build:icons`), not hand-written, and `postinstall` runs `patch-package`, so run install on a fresh clone. +- **Generated code** — v3 icon components are generated (`yarn build:icons`) and s2 are handled through a parcel transformer, not hand-written, and `postinstall` runs `patch-package`, so run install on a fresh clone. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ff52e57539a..94db3a9e4bd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -44,6 +44,52 @@ Read [GitHub's pull request documentation](https://help.github.com/articles/abou Lastly, please follow the pull request template when submitting a pull request! + +## AI-assisted contributions +Setting expectations: the AI doesn't contribute to React Spectrum or Quarry, you do. The AI is a tool, but you are still the author, and you own every line, every decision, and every explanation. + +If you use an AI assistant, point it at our [CLAUDE.md](CLAUDE.md), which captures the repo conventions we expect it to follow. + +### Aligning on a solution + +Open an issue or discussion, or at minimum, describe the problem and intended solution in the PR description. Otherwise, we have to reverse-engineer both the problem and the intended solution before we can even begin reviewing. An issue with: "here's what I'm seeing, here's what I plan to do, does that sound right?" really helps. + +### Give us the intent, not just the fix + +Tell us what you want and why, separately from how you did it. Then if we need to make a change to the PR, we can be confident that we're satisfying the goal you had. This framing helps when prompting the AI as well. + +### Tell us what you tested + +* mouse / touch / keyboard / screen reader +* LTR / RTL +* light / dark / high-contrast +* disabled / loading / error / empty +* narrow / wide / truncated / very long / wrapping text +* component sizes and zoom levels + +Even if you haven't tested all of these, it's hugely helpful to us to know where to focus efforts. + +### Beware false confidence + +One of the biggest issues we face with the rise of AI contributions is the wrong root cause but with a lot of details asserting why it is, in fact, the issue. Press the AI, and ask both it and yourself "is this the root cause, or a symptom?" and "what else could cause this?" before committing to a solution. + +### Keep a human in the loop of the conversation + +When you iterate between reviews, be sure you can say what changed and why, one sentence is enough. A PR that transforms completely between every review without explanation is exhausting to follow and makes us feel like we're arguing with a machine instead of collaborating with a person. + + +#### Requirements of front end code + +These can be useful constraints or reminders as AI is not inherently good at these things. + +* **Small** — everything you add ships across the network to the client, so more code means slower load times. +* **Fast** — must run well on constrained CPU and memory, not just the latest MacBook Pro. Many users are on years-old, low-end Android devices. +* **Mindful of the shared environment** — keep the global namespace clean, don't hog resources or throw uncaught errors, avoid CSS that leaks across boundaries, and keep ids unique. +* **Stable** — RSP and Quarry are libraries with many downstream dependents who upgrade on their own schedule, so avoid breaking them. +* **Accessible** — accessibility is still a relatively new web requirement, so strong examples are scarce and bad ones are common. use other examples in the repo or the APG examples first. +* **Cross-environment** — works across browsers, assistive technologies, and devices. + + ### Contributor License Agreement All third-party contributions to this project must be accompanied by a signed contributor license agreement. This gives Adobe permission to redistribute your contributions as part of the project. [Sign our CLA](https://opensource.adobe.com/cla.html). You only need to submit an Adobe CLA one time, so if you have submitted one previously, you are good to go!