Use shared form controls and enforce UI patterns (Refs #110)
CI / checks (push) Successful in 4m51s

This commit is contained in:
2026-10-10 00:19:48 -04:00
parent 8d1bb69591
commit cc9c10226e
54 changed files with 1431 additions and 1449 deletions
+38 -37
View File
@@ -1,4 +1,7 @@
<script lang="ts">
import Select from '$ui/components/primitives/Select.svelte';
import Input from '$ui/components/primitives/Input.svelte';
import Field from '$ui/components/primitives/Field.svelte';
import RelativeTime from '$ui/components/RelativeTime.svelte';
import { onMount } from 'svelte';
import { page } from '$app/stores';
@@ -361,58 +364,54 @@
<form onsubmit={create} aria-busy={busy}>
<fieldset disabled={busy}>
{#if formError}<p class="error" role="alert">{formError}</p>{/if}
<label for="new-username"
>Username<input
<Field forId="new-username" label="Username">
<Input
id="new-username"
name="username"
required
minlength="3"
maxlength="64"
minlength={3}
maxlength={64}
pattern={'[a-zA-Z0-9][a-zA-Z0-9_.\\-]{2,63}'}
autocomplete="off"
autocapitalize="none"
spellcheck="false"
bind:value={username}
aria-describedby="new-username-help"
/></label
/></Field
>
<p class="hint" id="new-username-help">
3–64 characters: letters, numbers, periods, underscores, and hyphens. Start with a
letter or number.
</p>
<label for="new-name"
>Display name<input
<Field forId="new-name" label="Display name">
<Input
id="new-name"
name="displayName"
required
maxlength="100"
maxlength={100}
autocomplete="off"
bind:value={displayName}
/></label
/></Field
>
<label for="new-role"
>Role<select
id="new-role"
name="role"
bind:value={role}
aria-describedby="new-role-help"
<Field forId="new-role" label="Role">
<Select id="new-role" name="role" bind:value={role} aria-describedby="new-role-help"
>{#each roles as item}<option value={item.value}>{item.label}</option
>{/each}</select
></label
>{/each}</Select
></Field
>
<p class="hint" id="new-role-help">{roleDescription}</p>
<label for="temporary-password"
>Temporary password<input
<Field forId="temporary-password" label="Temporary password">
<Input
id="temporary-password"
name="password"
type={showPassword ? 'text' : 'password'}
required
minlength="8"
maxlength="128"
minlength={8}
maxlength={128}
autocomplete="new-password"
bind:value={password}
aria-describedby="temporary-help"
/></label
/></Field
>
<p class="hint" id="temporary-help">
8–128 characters. Save it before adding the user; it will not be displayed again.
@@ -445,25 +444,25 @@
<form onsubmit={save} aria-busy={busy}>
<fieldset disabled={busy}>
{#if formError}<p class="error" role="alert">{formError}</p>{/if}
<label for="edit-name"
>Display name<input
<Field forId="edit-name" label="Display name">
<Input
id="edit-name"
name="displayName"
required
maxlength="100"
maxlength={100}
autocomplete="off"
bind:value={displayName}
/></label
/></Field
>
<label for="edit-role"
>Role<select
<Field forId="edit-role" label="Role">
<Select
id="edit-role"
name="role"
bind:value={role}
aria-describedby="edit-role-help"
>{#each roles as item}<option value={item.value}>{item.label}</option
>{/each}</select
></label
>{/each}</Select
></Field
>
<p class="hint" id="edit-role-help">{roleDescription}</p>
<label class="checkbox"
@@ -476,17 +475,20 @@
Use <a href="/account">My account</a> to change your own password. Changes to your
access can sign you out.
</p>
{:else}<label for="reset-password"
>New temporary password <span class="optional">(optional)</span><input
{:else}<Field forId="reset-password"
>{#snippet label()}New temporary password <span class="optional"
>(optional)</span
>{/snippet}
<Input
id="reset-password"
name="password"
type={showPassword ? 'text' : 'password'}
minlength="8"
maxlength="128"
minlength={8}
maxlength={128}
autocomplete="new-password"
bind:value={password}
aria-describedby="reset-help"
/></label
/></Field
>
<p class="hint" id="reset-help">
Leave blank to keep the current password. A reset requires the user to choose a
@@ -663,8 +665,7 @@
gap: 8px;
font-size: var(--text-sm);
}
input:not([type='checkbox']),
select {
input:not([type='checkbox']) {
width: 100%;
padding: 11px;
color: var(--text-primary);