mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-05 23:32:06 +00:00
66 lines
2.7 KiB
Markdown
66 lines
2.7 KiB
Markdown
# Frontend maintainability conventions
|
|
|
|
## Conditional rendering
|
|
|
|
Use logical `&&` or the `when` prop on `Text` when JSX has only a rendered state and an empty
|
|
state. Use a ternary only when both branches render meaningful alternatives.
|
|
|
|
```tsx
|
|
{
|
|
error && <Alert severity="error">{error.message}</Alert>;
|
|
}
|
|
|
|
<Text variant="description" when={Boolean(description)}>
|
|
{description}
|
|
</Text>;
|
|
```
|
|
|
|
ESLint rejects `condition ? <Element /> : null`. This keeps one-sided conditions visually
|
|
distinct from real either-or UI decisions.
|
|
|
|
## Typography and feedback
|
|
|
|
Use `Text` from `@/components/ui/text` for headings, paragraphs, descriptions, labels, captions,
|
|
code, and asynchronous feedback. It owns:
|
|
|
|
- semantic HTML for each visual variant;
|
|
- the display, body, and monospace font families;
|
|
- default, muted, error, success, and warning tones;
|
|
- accessible `alert` and `status` live regions for error and feedback text;
|
|
- one-sided conditional text through `when`.
|
|
|
|
ESLint rejects raw paragraph and heading elements. Existing MUI `Typography` usages remain valid,
|
|
but new shared UI should prefer `Text` so semantics and design tokens do not drift.
|
|
|
|
## Forms and mutations
|
|
|
|
Use the libraries already established in the application:
|
|
|
|
- React Hook Form owns field registration, touched/dirty state, and client form lifecycle.
|
|
- Zod owns form validation and inferred form value types.
|
|
- TanStack Query owns server reads and mutations, including pending/error state, cache
|
|
invalidation, and retries where safe.
|
|
|
|
Do not add TanStack Form alongside React Hook Form. It would create two form conventions without
|
|
removing any current dependency. Reconsider only as a deliberate repository-wide migration with
|
|
benchmarks, a codemod plan, and an approved deprecation path.
|
|
|
|
File uploads are not ordinary form fields. Keep file selection and client validation in a focused
|
|
component, and use a TanStack Query mutation for upload progress, errors, completion refresh, and
|
|
retry state. Do not place upload orchestration in a route-sized page component.
|
|
|
|
## Page state
|
|
|
|
Pages should compose focused state components instead of accumulating unrelated booleans:
|
|
|
|
- query loading, error, and empty states stay adjacent to the query result;
|
|
- mutation pending/error state belongs to the component that initiated the mutation;
|
|
- route pages coordinate sections and navigation;
|
|
- reusable sections own their interaction details;
|
|
- errors render inline with accessible feedback, with toasts reserved for cross-page outcomes.
|
|
|
|
## Enforcement and rollout
|
|
|
|
The lint rules are repository-wide and the initial violations were migrated in the same change.
|
|
`npm run lint`, `npm run build`, and the `Text` behavior tests are required gates. Future
|
|
maintainability rules must also land with a green migration rather than a warning-only backlog.
|