Skip to content

Commit 3748a2d

Browse files
chore(mosaic): add layer boundary, test and effect lint rules (#10426)
1 parent 7095120 commit 3748a2d

19 files changed

Lines changed: 710 additions & 170 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
---

‎packages/mosaic/AGENTS.md‎

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -31,33 +31,33 @@ A flow lives in `src/features/<feature>/`. The **model** (`*.model.ts(x)`) is th
3131

3232
Most problems a feature hits already have a shared answer. Find the row for your problem and use it. Do not write a local version, even a small one.
3333

34-
| Problem | Use |
35-
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- |
36-
| An async action from a button or row: pending, an error, one lock | `usePendingAction` (`src/hooks/`) |
37-
| A form: values, validation, submit, field errors | `useForm` (`src/components/form/`), with `validateAsync` for a server-side check |
38-
| A `<form>` element, without the browser's validation popup | `Form` (`src/primitives/form/`) |
39-
| A model save whose Clerk errors should land on form fields | `save` in the model (`src/utils/errors.ts`), or reject with `FormSubmitError` |
40-
| A confirm step before an action | `useConfirmController` (`src/blocks/confirm/`) with `Confirmation` (`src/blocks/confirmation/`) |
41-
| A delete that needs the user to type a phrase | `useConfirmController` (`src/blocks/confirm/`) with `Destructive` (`src/blocks/destructive/`) |
42-
| An action that may need step-up verification | `useReverificationFlow` (`src/features/reverification/`) in the model, passed to `useConfirmController` |
43-
| A direct action that needs step-up verification | `useReverificationFlow` in the model, with `ReverificationDialog` (`src/blocks/reverification/`) in the view |
44-
| Showing any error to the user | One of the owners above. They call `toLocalizableError` and resolve copy with `useErrorText` |
45-
| Moving focus after a list row is removed | `useListRemovalFocus` (`src/hooks/`) |
46-
| A debounced, abortable async check as the user types | `useDebouncedAsync` (`src/hooks/`) |
47-
| A spinner that should not flash or flicker | `useSpinDelay` (`src/hooks/`) |
48-
| A placeholder for content that is still loading | `Skeleton` (`src/components/skeleton/`), see [Skeletons](docs/skeletons.md) |
49-
| A date shown to the user | `formatDate` (`src/utils/format-date.ts`) |
50-
| A value turned into kebab case, e.g. for a `data-*` attribute | `kebabCase` (`src/utils/kebab-case.ts`) |
51-
| Current time for display labels | `useNow` + `MosaicProvider` ([#10098](https://github.com/clerk/javascript/pull/10098), once available) |
52-
| Whether enterprise SSO permits adding another identification | `allowsIdentificationCreation` (`src/utils/allows-identification-creation.ts`) |
53-
| An inline message row that animates open and closed | `useHeldMessage`, `useMessageHeight`, `FeedbackBody` (`src/utils/feedback.tsx`) + `styles/feedback.styles.ts` |
54-
| A table whose sorting, paging and search are done by the server | `useServerDataTable` (`src/hooks/`) |
55-
| Data read from a Clerk resource that should be cached across mounts | A query hook in `src/queries/`, called from the model (`use-user-sessions-query.ts`) |
56-
| An item changed in place in an infinite list, kept until the next reload | `replaceInPages` (`src/utils/infinite-pages.ts`), passed to the list's `setData` |
57-
| Siblings that slide when an item is added or removed | `useLayoutAnimation` (`src/primitives/hooks/`) |
58-
| An input that reformats as the user types without moving the caret | `useFormattedInput` (`src/primitives/hooks/`) |
59-
| An interaction with an async lifecycle or two values that move together | A machine in the controller file, via `setup()` (`src/machine/`) |
60-
| Styles several components share | `src/styles/*.styles.ts` |
34+
| Problem | Use |
35+
| ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------- |
36+
| An async action from a button or row: pending, an error, one lock | `usePendingAction` (`src/hooks/`) |
37+
| A form: values, validation, submit, field errors | `useForm` (`src/components/form/`), with `validateAsync` for a server-side check |
38+
| A `<form>` element, without the browser's validation popup | `Form` (`src/primitives/form/`) |
39+
| A model save whose Clerk errors should land on form fields | `save` (`src/utils/errors.ts`) in the model, or reject with `FormSubmitError` |
40+
| A confirm step before an action | `useConfirmController` (`src/blocks/confirm/`) with `Confirmation` (`src/blocks/confirmation/`) |
41+
| A delete that needs the user to type a phrase | `useConfirmController` (`src/blocks/confirm/`) with `Destructive` (`src/blocks/destructive/`) |
42+
| An action that may need step-up verification | `useReverificationFlow` (`src/features/reverification/`) in the model, passed to `useConfirmController` |
43+
| A direct action that needs step-up verification | `useReverificationFlow` in the model, with `ReverificationDialog` (`src/blocks/reverification/`) in the view |
44+
| Showing any error to the user | One of the owners above. They call `toLocalizableError` and resolve copy with `useErrorText` |
45+
| Moving focus after a list row is removed | `useListRemovalFocus` (`src/hooks/`) |
46+
| A debounced, abortable async check as the user types | `useDebouncedAsync` (`src/hooks/`) |
47+
| A spinner that should not flash or flicker | `useSpinDelay` (`src/hooks/`) |
48+
| A placeholder for content that is still loading | `Skeleton` (`src/components/skeleton/`), see [Skeletons](docs/skeletons.md) |
49+
| A date shown to the user | `formatDate` (`src/utils/format-date.ts`) |
50+
| A value turned into kebab case, e.g. for a `data-*` attribute | `kebabCase` (`src/utils/kebab-case.ts`) |
51+
| Current time for display labels | `useNow` (`src/hooks/`) |
52+
| Whether enterprise SSO permits adding another identification | `allowsIdentificationCreation` (`src/utils/allows-identification-creation.ts`) |
53+
| An inline message row that animates open and closed | `useHeldMessage`, `useMessageHeight`, `FeedbackBody` (`src/utils/feedback.tsx`) + `src/styles/feedback.styles.ts` |
54+
| A table whose sorting, paging and search are done by the server | `useServerDataTable` (`src/hooks/`) |
55+
| Data read from a Clerk resource that should be cached across mounts | A query hook in `src/queries/`, called from the model (`src/queries/use-user-sessions-query.ts`) |
56+
| An item changed in place in an infinite list, kept until the next reload | `replaceInPages` (`src/utils/infinite-pages.ts`), passed to the list's `setData` |
57+
| Siblings that slide when an item is added or removed | `useLayoutAnimation` (`src/primitives/hooks/`) |
58+
| An input that reformats as the user types without moving the caret | `useFormattedInput` (`src/primitives/hooks/`) |
59+
| An interaction with an async lifecycle or two values that move together | A machine in the controller file, via `setup()` (`src/machine/`) |
60+
| Styles several components share | `src/styles/*.styles.ts` |
6161

6262
## Signs you are about to invent a pattern
6363

@@ -96,7 +96,7 @@ A PR that adds, renames or changes the signature of a shared helper in `src/hook
9696

9797
## Lint
9898

99-
Mosaic runs stricter lint rules than the rest of the repo: the `packages/mosaic` block in the root `eslint.config.mjs`, plus the layer import guards in `packages/mosaic/eslint/config.mjs`, which only load through `packages/mosaic/eslint.config.mjs`. Lint with `pnpm lint` from `packages/mosaic`. Running `eslint` from the repo root skips the import guards.
99+
Mosaic runs stricter lint rules than the rest of the repo: the `packages/mosaic` block in the root `eslint.config.mjs`, plus the layer boundaries, test rules and effect rules in `packages/mosaic/eslint/config.mjs`, which only load through `packages/mosaic/eslint.config.mjs`. Lint with `pnpm lint` from `packages/mosaic`. Running `eslint` from the repo root skips them.
100100

101101
Every disable directive in `src` needs a `-- reason` (`@eslint-community/eslint-comments/require-description`). The reason is not a code comment under the root no-comments rule. Write why the rule does not apply here, not what the code does; it is what a reviewer judges.
102102

‎packages/mosaic/eslint-suppressions.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
}
3131
},
3232
"src/features/user-profile/user-profile-web3-wallets-section/user-profile-solana-wallet.model.ts": {
33-
"@typescript-eslint/no-restricted-imports": {
33+
"boundaries/dependencies": {
3434
"count": 1
3535
}
3636
},

0 commit comments

Comments
 (0)