diff --git a/docs/swarm/ui.md b/docs/swarm/ui.md index 26d77b00..054b04b0 100644 --- a/docs/swarm/ui.md +++ b/docs/swarm/ui.md @@ -11,6 +11,15 @@ The signed-in user's avatar sits at the right end of the header on every page. It opens a menu with the user's name and links to authelia's settings and sign-out pages; the hive dashboard and the per-agent page have the same menu. +Every dropdown (a form's select, the refresh interval, the history window) opens a +list in the swarm UI's own theme, not the browser's, and works the same in every +current browser. Open it with a click, or with the arrow keys, **Enter** or +**Space** while it has focus. Then the arrow keys, **Home**, **End**, **Page Up** +and **Page Down** move through the options, and **Enter**, **Space** or a click take +the highlighted one. **Escape**, **Tab** or a click elsewhere shut the list without +changing anything. Typing the start of an option's name picks it, also with the list +shut. A dropdown inside a dialog opens above the dialog and the dialog doesn't cut it off. + | route | what | | ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `/` | the start page: the swarm's name over a digital-rain backdrop, plus a paperclip offering to set up an agent while no `ruth` exists (it opens the create form with `ruth` filled in); the swarm name in the header links here | diff --git a/frontend/packages/swarm-ui/src/pages/CreateAgentForm.tsx b/frontend/packages/swarm-ui/src/pages/CreateAgentForm.tsx index dce9f873..fbb0ceec 100644 --- a/frontend/packages/swarm-ui/src/pages/CreateAgentForm.tsx +++ b/frontend/packages/swarm-ui/src/pages/CreateAgentForm.tsx @@ -14,7 +14,7 @@ // // `hive` field added because agent creation had no way to record which // hive an agent runs on. `POST /api/agents` now requires it, so the -// roster fetched off `GET /api/hives` backs a required select here +// roster fetched off `GET /api/hives` backs a required dropdown here // rather than a free-text field — a spawn target has to be one of the // swarm's actual hives, same reasoning `Ident.parse` gets client-side // pattern validation for `name`. @@ -159,8 +159,8 @@ export function CreateAgentForm({ setHives(data); // Single-hive swarms are the common case — default it rather than // making the operator pick the only option. Multi-hive swarms get - // no default (the placeholder stays selected), so `required` on - // the select below forces an explicit choice per mara's scope. + // no default (the placeholder stays selected), so the identity step + // cannot be left until one is picked (`stepProblem`), per mara's scope. if (data.length === 1) setHive(data[0].name); })().catch((e: unknown) => setHivesError({ detail: String(e) })); }, []); diff --git a/frontend/packages/swarm-ui/src/ui/refresh-interval/RefreshInterval.css b/frontend/packages/swarm-ui/src/ui/refresh-interval/RefreshInterval.css index 0e1a134d..bc7cde1e 100644 --- a/frontend/packages/swarm-ui/src/ui/refresh-interval/RefreshInterval.css +++ b/frontend/packages/swarm-ui/src/ui/refresh-interval/RefreshInterval.css @@ -13,7 +13,6 @@ border-radius: 0.4em; color: var(--muted); font-size: 0.9em; - cursor: pointer; } .ui-refresh-picker:hover, .ui-refresh-picker:focus-within { @@ -21,22 +20,21 @@ background: var(--bg); color: var(--fg); } -/* The select drives the interaction (native listbox, keyboard, a11y) but - contributes no chrome of its own — its own box is invisible, sized to - just its selected option's text, and its default arrow is stripped - since the chevron span stands in for it. */ -.ui-refresh-picker-select { - appearance: none; +/* The Listbox contributes only its value and chevron: its own box is + invisible and as wide as the value, so the picker's border is the one + that shows. */ +.ui-refresh-picker .ui-listbox { + width: auto; +} +.ui-refresh-picker-select.ui-form-control { + width: auto; + min-height: 2.5em; + padding: 0; border: none; background: none; color: inherit; - font: inherit; - padding: 0; - margin: 0; - cursor: pointer; } -.ui-refresh-picker-icon, -.ui-refresh-picker-chevron { +.ui-refresh-picker-icon { font-size: 0.85em; line-height: 1; } diff --git a/frontend/packages/swarm-ui/src/ui/refresh-interval/RefreshInterval.tsx b/frontend/packages/swarm-ui/src/ui/refresh-interval/RefreshInterval.tsx index a42cb1b8..9dc97977 100644 --- a/frontend/packages/swarm-ui/src/ui/refresh-interval/RefreshInterval.tsx +++ b/frontend/packages/swarm-ui/src/ui/refresh-interval/RefreshInterval.tsx @@ -14,18 +14,17 @@ // passive-until-touched setting that lives in a panel's title row // (`Panel`'s `actions` slot), not a form. Visually quiet (no border/ // fill until hovered/focused) the same way `LinksMenu`'s header button -// is, so it reads as chrome rather than another input to fill in. A -// native `` for the accessible - // name a sighted-only icon+chevron can't supply). -