Form implementation guidance for the aghub desktop app. Use when building or refactoring forms in `crates/desktop/src`, especially HeroUI v3 + React forms, RHF integration, validation, custom editors, and error presentation. Triggers: MCP forms, settings dialogs, create/edit panels, `TextField`, `FieldError`, `Select`, `react-hook-form`, key-value editors, validation behavior.
Scanned 5/27/2026
Install via CLI
openskills install AkaraChen/aghub---
name: project-form-patterns
description: Form implementation guidance for the aghub desktop app. Use when building or refactoring forms in `crates/desktop/src`, especially HeroUI v3 + React forms, RHF integration, validation, custom editors, and error presentation. Triggers: MCP forms, settings dialogs, create/edit panels, `TextField`, `FieldError`, `Select`, `react-hook-form`, key-value editors, validation behavior.
---
# AGHub Form Patterns
Follow these rules when building forms in this project.
## Source of Truth
- Check the official docs first, not memory and not bundled/local docs, when form behavior is in question.
- For HeroUI, prefer the official site:
- `https://v3.heroui.com/docs/react/components/form`
- `https://v3.heroui.com/docs/react/components/text-field`
- `https://v3.heroui.com/docs/react/components/field-error`
- `https://v3.heroui.com/docs/react/components/select`
- Use local skill docs only as a convenience after confirming the official API.
## Default Stack
- Prefer `react-hook-form` for non-trivial forms.
- Use `Controller` for HeroUI `Select` and any custom controlled widgets.
- Keep one form state. Do not create a second derived validation state unless there is a concrete need the form library cannot express.
## Validation Behavior
- When RHF controls validation, set HeroUI form fields to `validationBehavior="aria"`.
- Do not rely on HeroUI/native validation defaults together with RHF. Native validation can steal focus and submission flow while bypassing the error UI you expect from RHF.
- Let RHF own validation rules and submission blocking.
## Error Rendering
- For HeroUI text fields, use:
- `isInvalid={Boolean(fieldState.error)}`
- Conditionally render `<FieldError>{fieldState.error.message}</FieldError>` inside the same `TextField`.
- Do not invent unsupported props. In particular, do not assume `TextField` supports an `errorMessage` prop.
- Keep the official anatomy:
```tsx
<TextField isInvalid={Boolean(fieldState.error)} validationBehavior="aria">
<Label>Name</Label>
<Input {...inputProps} />
{fieldState.error && <FieldError>{fieldState.error.message}</FieldError>}
</TextField>
```
- For non-form or custom composite controls, prefer HeroUI `ErrorMessage` instead of hand-rolled error text.
- Use `ErrorMessage` for collection-style or custom editors that are not true form fields, including key/value editors, tag selectors, and similar composite controls.
## Custom Editors
- Custom widgets like `AgentSelector`, `EnvEditor`, `HttpHeaderEditor`, and `KeyPairEditor` should still be registered in RHF through `Controller`.
- For custom editors that manage arrays or compound values, compute validation from the current field value and surface one aggregated error below the editor when possible.
- For that aggregated error, prefer HeroUI `ErrorMessage`.
- Do not inject per-row error UI into tight horizontal layouts unless the design explicitly calls for it.
## Key/Value Editors
- Keep row layout simple:
- two inputs
- one delete button
- no extra wrappers that change flex behavior unless necessary
- Prefer aggregate error text below the whole editor over inline row errors. This avoids breaking spacing and alignment.
- Implement that aggregate error with HeroUI `ErrorMessage`, not a custom `<p>` block.
- If you must show row-level issues, redesign the layout first; do not bolt error blocks into a row that was designed as a single-line control.
## Practical Rules
- Prefer `onPress` for HeroUI buttons.
- Use `type="button"` for non-submit buttons inside forms.
- Preserve existing visual patterns in this repo; do not restyle forms while adding validation.
- After form changes, run `bun run build` in `crates/desktop` when possible and separate unrelated existing build failures from the changes you made.
## Anti-Patterns
- Do not mix RHF validation with a parallel `validationErrors` state for the same fields.
- Do not depend on HeroUI default native validation when you expect RHF errors to drive the UI.
- Do not push validation messages into each key/value row unless you intentionally redesign that editor.
- Do not trust remembered HeroUI APIs for forms without checking the official site first.
No comments yet. Be the first to comment!