# Contract: Controls + Selection Version: 1.3 ## Shared Base - This pattern inherits the shared `table-management` contract. - Visual styling comes from `web-visual-baseline`. - Reuse shared toolbar/table/icon geometry from the base contract first, then define only controls-specific additions below. ## Buttons - Use a small stable button taxonomy: `primary`, `secondary`, `ghost`, `danger`, `disabled`. - Destructive actions (`archive`, `delete`, `remove`) must use danger styling and explicit labels. - Button text should describe the action outcome, not implementation detail. - Inside a data-table row action column, buttons are icon-only. Each one must have a deterministic `title` and `aria-label`; text labels belong in toolbars, forms and confirmation dialogs, not repeated in every row. - Buttons are text-first; icons are optional and must not replace labels on primary/danger actions. - Base examples must show both `disabled` and `loading` states. - Any control that triggers a network or database call must show a visible busy state for the whole duration of that call (spinner on the control, disabled control, or an equivalent indicator), and must not be re-triggerable while busy. Without it, "slow" is indistinguishable from "broken". - This applies to every call, not only to long-running background tasks. The server-side half of the rule — a bounded timeout on the call itself — is owned by `go-api`. - Do not use a hyperlink (``/link-styled text) to open a modal, drawer, detail view, or any other in-page element. Use a `button` (or button-styled control) instead, unless the user explicitly asks for a hyperlink. Hyperlinks are reserved for navigation to another URL/page. ## Checkbox Selection - Row checkboxes support bulk actions from a shared action bar. - Header checkbox semantics must be explicit: - select visible rows only, or - select all rows in query scope (must be clearly labeled) - In paginated views, the UI should distinguish selection on the current page from selection across the filtered/query scope. - Selection state should survive pagination/filter navigation via explicit state (query params, server session, or another deterministic mechanism). - Same-page interactions should preserve reading position (module anchor pattern is preferred in canonical server-rendered flows). ## Segmented Filters - Segment/toggle filters are allowed for small enumerations (status, active/archived). - Segmented controls are grouped joined-buttons: - one shared outer shell, - rounded corners only on the first/last segment, - straight internal separators between middle segments. - Active segment color may vary by context (for example blue preset selector vs dark status scope tabs), but geometry must remain consistent. - Segment changes should preserve other active filters where possible. ## Bulk Action Safety - Bulk action click should preview count and target scope before execution. - Destructive bulk actions require confirmation. - Dense bulk action bars may move rare actions into an explicit overflow menu (`More actions`) while keeping primary actions visible.