mirror of
https://github.com/vector-im/element-call.git
synced 2026-09-13 21:59:30 +00:00
* Add AGENTS.md documenting the repo's conventions Codifies what is currently tribal knowledge or only discoverable by reading CI config: the view model / view contract, the rule that nothing reads the page, Clean Code ordering, the three test layers, and reuse-before-you-build. The root AGENTS.md is the always-loaded minimum and routes to docs/agents/, so an agent loads only the detail its task needs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Allow either hand at the commit, and measure continuous redraws Committing from the agent rules out running it where there is no git identity, a sandbox included. Either is now fine: commit on the user's word where the setup allows it, or write the message and hand it over. Redrawing continuously is the other addition. A level meter reported a fresh value every animation frame, so its whole menu reconciled sixty times a second, silence included, and nobody noticed until review. A PR that adds anything of the kind now says what it costs, or better, counts the redraws — commits rather than render calls, since React runs a component it then discards. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
75 lines
3.5 KiB
Markdown
75 lines
3.5 KiB
Markdown
# Code style
|
|
|
|
_Clean Code_ (Robert C. Martin): small functions, intention-revealing names, low
|
|
noise.
|
|
|
|
## Reuse before you build
|
|
|
|
Look before you write, in this order:
|
|
|
|
1. **Compound Web** — `@vector-im/compound-web` for buttons, tooltips, alerts,
|
|
dialogs, menus, form controls, avatars; icons in
|
|
`@vector-im/compound-design-tokens/assets/web/icons`.
|
|
2. **This repo** — `src/button/`, `src/components/`, `src/input/`, `src/form/`,
|
|
`src/tabs/`, and `Modal`, `Avatar`, `Toast`, `Slider`, `ErrorView`,
|
|
`FullScreenView` at the root of `src/`.
|
|
3. **The nearest existing feature** — grep for the same shape first. A hook is
|
|
often what you want to extract, not a component.
|
|
|
|
If nothing fits, name the new shared component in the PR body and say what you
|
|
rejected and why — never add one silently. Extend or parameterise before forking,
|
|
and extract shared logic into a hook both callers use before copying it; if you
|
|
copy, the PR says so.
|
|
|
|
## Ordering
|
|
|
|
- **Newspaper order.** Headline first, detail down. A file opens with what it
|
|
exists to provide.
|
|
- **Stepdown rule.** Caller above callee. A helper used by one function sits
|
|
beneath it, which needs a `function` declaration, not a `const` arrow. Existing
|
|
arrow components above their callers are not a pattern to extend — nor to churn.
|
|
- **Suites.** Test cases first, helpers below. Older suites invert this; follow the
|
|
rule in new ones, don't reorder old ones.
|
|
- **Names.** What a thing means, not what it is made of: `naturalLayout$`, not
|
|
`computedLayout$`. Comments explain why, never what.
|
|
|
|
## TypeScript, React and RxJS idiom win on a clash
|
|
|
|
- Hooks stay unconditional at the top of a component.
|
|
- `useCallback` / `useMemo` dependency arrays sometimes force inlining.
|
|
- An RxJS pipeline stays one expression. Name the behavior, not each operator.
|
|
- A long factory is fine when it reads as a list of named behaviors.
|
|
`CallViewModel.ts` is long because the domain is.
|
|
- Marble test tables are dense on purpose.
|
|
|
|
## Enforced by lint
|
|
|
|
- Copyright header on every file: `Copyright <current year> Element Creations Ltd.`
|
|
plus the AGPL / commercial SPDX line.
|
|
- `logger` from `matrix-js-sdk/lib/logger`, never `console`, and no top-level
|
|
`logger.getChild()`. The `console` ban is only enforced under `src/*/**`.
|
|
- No floating or misused promises; async functions typed `Promise<T>`.
|
|
- Inline type imports (`import { type Foo }`), so matrix-js-sdk stays lazily
|
|
loadable.
|
|
- Deep-import `matrix-js-sdk/lib/<module>` as the codebase does. Banned is the bare
|
|
`matrix-js-sdk/lib`, `lib/index` and anything under `src/`.
|
|
|
|
## CSS
|
|
|
|
- Compound components and `--cpd-*` tokens in CSS modules. A hardcoded colour or px
|
|
spacing is a design question, not a licence to inline a hex.
|
|
- Size against the root, not the window: `@container element-call (…)` and
|
|
`cqw` / `cqh`, never `@media (width)` or `vw` / `vh`. Media queries stay correct
|
|
only in standalone-only views — home, login.
|
|
- Style `[data-element-call-root]`, never `body` or `:root`; the component build
|
|
makes those stand for the root (`component/build/scopeStylesToRoot.ts`).
|
|
|
|
## Strings and a11y
|
|
|
|
- Strings through `t()`: add the key, run `pnpm i18n`, fill `locales/en/app.json`.
|
|
Other locales come from Localazy; never hand-edit them.
|
|
- `t` from `useTranslation()`, or `src/utils/i18n.ts` outside React. Never the
|
|
`i18next` global — several instances share a page.
|
|
- Accessible names on controls, `aria-pressed` on toggles, keyboard reachability.
|
|
`jsx-a11y` rules are errors; `vitest-axe` is available.
|