swarm-ui: fix create-agent form field alignment and panel width
TextField and SelectField's shared FormField wrapper had no width of its own, so inside the form's shrink-to-fit flex column each field's input/select resolved its 'width: 100%' against its own shrunk wrapper rather than a shared column width — two fields with differently-long labels ended up with differently-wide controls. FormField now caps its own width the same way the control already does, so every field in a form lines up regardless of label length. Also wrapped the page in a max-width container: Panel has no width opinion of its own, so it filled the full page column, leaving a lot of bare panel to the right of the ~16em-wide form.
This commit is contained in:
parent
7880483b51
commit
f14fc154cc
3 changed files with 69 additions and 40 deletions
|
|
@ -4,7 +4,19 @@
|
|||
not row: with a second field (hive) added, a row layout put fields of
|
||||
different natural widths on one baseline and looked misaligned —
|
||||
mara: "make it a col". Reuses the same base16 slots (../theme.css)
|
||||
every other component draws from. */
|
||||
every other component draws from.
|
||||
|
||||
`.create-agent-page` caps the panel's own width: `Panel` has no width
|
||||
opinion of its own, so left unconstrained it filled `.shell-body`'s
|
||||
full 60em column — a lot of bare panel to the right of a ~16em-wide
|
||||
form, the "weird empty space" mara flagged alongside the field
|
||||
misalignment. 24em roughly matches the fields' own 16em cap
|
||||
(../ui/form-field/FormField.css) plus the panel's 1em body padding on
|
||||
each side and a little breathing room, so the panel reads as sized to
|
||||
its content instead of to the page column. */
|
||||
.create-agent-page {
|
||||
max-width: 24em;
|
||||
}
|
||||
.create-agent-intro {
|
||||
margin: 0 0 1.5em;
|
||||
color: var(--muted);
|
||||
|
|
|
|||
|
|
@ -125,44 +125,48 @@ export function CreateAgentPage() {
|
|||
}
|
||||
|
||||
return (
|
||||
<Panel title="create agent">
|
||||
<p class="create-agent-intro">
|
||||
Create a new agent's swarm-level identity. This only queues the job — check{' '}
|
||||
<Link href="/jobs">jobs</Link> to watch it settle.
|
||||
</p>
|
||||
{hivesError && <ApiErrorPanel context="failed to load the hive list" problem={hivesError} />}
|
||||
<form class="create-agent-form" onSubmit={submit}>
|
||||
<TextField
|
||||
id="agent-name"
|
||||
label="agent name"
|
||||
value={name}
|
||||
pattern={NAME_PATTERN}
|
||||
title="1-63 chars: lowercase letters, digits, hyphens"
|
||||
required
|
||||
onInput={setName}
|
||||
/>
|
||||
<SelectField
|
||||
id="agent-hive"
|
||||
label="hive"
|
||||
value={hive}
|
||||
onChange={setHive}
|
||||
options={hiveOptions}
|
||||
required
|
||||
disabled={!hivesReady}
|
||||
placeholder={!hives ? 'loading…' : hives.length === 0 ? 'no hives configured' : 'select a hive'}
|
||||
/>
|
||||
<Button variant="primary" type="submit" disabled={result.status === 'submitting' || !hivesReady}>
|
||||
{result.status === 'submitting' ? 'creating…' : 'create'}
|
||||
</Button>
|
||||
</form>
|
||||
{result.status === 'done' && (
|
||||
<p class="create-agent-result create-agent-result-ok">
|
||||
queued as job node #{result.nodeId} — <Link href="/jobs">watch it in jobs</Link>
|
||||
<div class="create-agent-page">
|
||||
<Panel title="create agent">
|
||||
<p class="create-agent-intro">
|
||||
Create a new agent's swarm-level identity. This only queues the job — check{' '}
|
||||
<Link href="/jobs">jobs</Link> to watch it settle.
|
||||
</p>
|
||||
)}
|
||||
{result.status === 'error' && (
|
||||
<ApiErrorPanel context="failed to queue" problem={result.problem} />
|
||||
)}
|
||||
</Panel>
|
||||
{hivesError && <ApiErrorPanel context="failed to load the hive list" problem={hivesError} />}
|
||||
<form class="create-agent-form" onSubmit={submit}>
|
||||
<TextField
|
||||
id="agent-name"
|
||||
label="agent name"
|
||||
value={name}
|
||||
pattern={NAME_PATTERN}
|
||||
title="1-63 chars: lowercase letters, digits, hyphens"
|
||||
required
|
||||
onInput={setName}
|
||||
/>
|
||||
<SelectField
|
||||
id="agent-hive"
|
||||
label="hive"
|
||||
value={hive}
|
||||
onChange={setHive}
|
||||
options={hiveOptions}
|
||||
required
|
||||
disabled={!hivesReady}
|
||||
placeholder={
|
||||
!hives ? 'loading…' : hives.length === 0 ? 'no hives configured' : 'select a hive'
|
||||
}
|
||||
/>
|
||||
<Button variant="primary" type="submit" disabled={result.status === 'submitting' || !hivesReady}>
|
||||
{result.status === 'submitting' ? 'creating…' : 'create'}
|
||||
</Button>
|
||||
</form>
|
||||
{result.status === 'done' && (
|
||||
<p class="create-agent-result create-agent-result-ok">
|
||||
queued as job node #{result.nodeId} — <Link href="/jobs">watch it in jobs</Link>
|
||||
</p>
|
||||
)}
|
||||
{result.status === 'error' && (
|
||||
<ApiErrorPanel context="failed to queue" problem={result.problem} />
|
||||
)}
|
||||
</Panel>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,24 @@
|
|||
every control in the kit whether or not it's ever used on a touch
|
||||
device, since the alternative is a component that behaves differently
|
||||
per input method. Colours are the shared base16-derived vars
|
||||
(../../theme.css), never literal. */
|
||||
(../../theme.css), never literal.
|
||||
|
||||
The field wrapper repeats `.ui-form-control`'s own `width: 100%;
|
||||
max-width: 16em` rather than leaving the wrapper unconstrained: inside
|
||||
a shrink-to-fit flex column (`CreateAgentPage`'s form is one), an
|
||||
unconstrained wrapper sizes to its own content — and a `width: 100%`
|
||||
*control* inside an auto-width wrapper resolves against that shrunk
|
||||
width, not the intended 16em cap, so two fields with differently-long
|
||||
labels ("agent name" vs "hive") ended up with differently-wide inputs —
|
||||
the misalignment mara reported on the create-agent page. Matching the
|
||||
two declarations here means every field's control width is driven by
|
||||
the same fixed cap regardless of its label's length or its siblings'. */
|
||||
.ui-form-field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.3em;
|
||||
width: 100%;
|
||||
max-width: 16em;
|
||||
}
|
||||
.ui-form-field-label {
|
||||
font-size: 0.85em;
|
||||
|
|
|
|||
Loading…
Reference in a new issue