Register shared form textarea governance

This commit is contained in:
rcourtman
2026-06-12 16:03:34 +01:00
parent 21c79c898c
commit 4ccadb0b38
19 changed files with 504 additions and 113 deletions
@@ -482,6 +482,11 @@ Agent profile management tables follow that same presentation boundary:
profile and assignment columns, but embedded table framing must route through
`PulseDataGrid`'s shared frame variants instead of lifecycle-local
`overflow-x-auto` or side-border wrappers.
Agent profile prompt and description textareas follow the same shared primitive
boundary. `AgentProfilesPanel.tsx` and `SuggestProfileModal.tsx` may own agent
profile lifecycle behavior and API mutations, but multi-line form controls in
those surfaces must compose `FormTextarea` instead of local raw `<textarea>`
wrappers.
## Extension Points
@@ -205,6 +205,13 @@ alignment classes.
Alert filter option semantics stay alert-owned, but FilterBar chip
presentation is frontend-primitives-owned: severity filter leading dots must
use `filterChipStatusDot` rather than alert-local span factories.
Alert notification and timeline form textareas are also shared-primitive
consumers. Email recipient lists, Apprise target lists, webhook payload
templates, threshold ignored-prefix input, and incident timeline notes must
compose `FormTextarea` for label/id/help wiring and textarea chrome instead of
recreating raw labelled `<textarea>` shells locally. Alert resource row/mobile
note editors are the only bounded residual until their row-editor behavior is
migrated through the same primitive.
Guest metric canonical state remains resource-backed and therefore node-scoped
for Proxmox guests, so node moves must not strand active alert state on the
previous resource ID. When a guest metric alert survives a node move, alerts
@@ -1286,6 +1286,11 @@ including the existing-key field label/help text and legacy-key exchange
notice, while `selfHostedBillingPresentation.ts` owns the first-class plan and
license-state copy that belongs on the primary billing surface. That split
prevents manual key redemption from drifting back into the main purchase path.
The recovery key input is also a frontend-primitives consumer:
`SelfHostedCommercialRecoverySection.tsx` must compose `FormTextarea` for the
manual license-key field so label/id/help wiring and textarea chrome remain
shared while cloud-paid continues to own the commercial copy and recovery
actions.
That same recovery boundary also owns the linked legal surface:
`SelfHostedCommercialRecoverySection.tsx` must route its Terms-of-Service link
through the shipped `TERMS.md` docs asset instead of sending operators to
@@ -2442,6 +2442,14 @@ history range controls must compose `FormSelect` rather than recreating a
screen-reader label plus raw `<select>` shell locally, and future native-select
migrations should extend that primitive instead of forking labelled select
wrappers.
Native textarea controls follow the same contract. `FormTextarea` owns
label/id wiring, helper-text description merging, value synchronization, default
textarea chrome, and compact styling hooks for multi-line text fields. Alert
destination fields, incident notes, infrastructure merge reports, commercial
recovery input, and agent-profile prompt/description fields must compose
`FormTextarea`; bounded residual raw textareas are limited to editor-specific
surfaces called out in the shared-template registry until their dedicated
migration slices retire them.
Search controls are registry-backed too. `SearchField` owns simple search
input chrome, clear affordance, keyboard forwarding, focus handling, aria
labels, and trailing-control padding, while `SearchInput` owns resource-list