Einstellungsseiten-Muster
Live PreviewOpen in Storybook ↗
Einstellungsseiten kombinieren Formularvalidierung, Abschnittsgliederung und Speicher-Feedback. Dieses Muster erstellt einen vollständigen Einstellungsbildschirm mit Tab-basierter Navigation zwischen Abschnitten, Inline-Validierung und Toast-Benachrichtigung beim Speichern.
Wann dieses Muster verwenden
- Konto-, Profil-, Benachrichtigungs- und Abrechnungseinstellungen
- Formulare mit vielen Feldern, die in logische Abschnitte unterteilt sind
- Wenn dauerhaftes Speicher-Feedback ohne Blockierung der UI gezeigt werden soll
Komponenten-Setup
app/settings/page.tsx
import { Tabs } from "@prokodo/ui/tabs"
import "@prokodo/ui/tabs.css"
import { ProfileSection } from "./ProfileSection"
import { NotificationsSection } from "./NotificationsSection"
const tabs = [
{ value: "profile", label: "Profil", content: <ProfileSection /> },
{
value: "notifications",
label: "Benachrichtigungen",
content: <NotificationsSection />,
},
{ value: "security", label: "Sicherheit", content: <SecuritySection /> },
]
export default function SettingsPage() {
return (
<main style={{ maxWidth: "720px", margin: "0 auto", padding: "2rem" }}>
<h1>Einstellungen</h1>
<Tabs
id="settings-tabs"
ariaLabel="Einstellungsbereiche"
items={tabs}
defaultValue="profile"
/>
</main>
)
}
Profil-Formular
app/settings/ProfileSection.tsx
"use client"
import { useState } from "react"
import { Input } from "@prokodo/ui/input/client"
import { Select } from "@prokodo/ui/select/client"
import { Snackbar } from "@prokodo/ui/snackbar/client"
import { Button } from "@prokodo/ui/button/client"
import "@prokodo/ui/input.css"
import "@prokodo/ui/select.css"
import "@prokodo/ui/snackbar.css"
import "@prokodo/ui/button.css"
export function ProfileSection() {
const [saved, setSaved] = useState(false)
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault()
const data = new FormData(e.currentTarget)
await updateProfile({
name: data.get("name") as string,
timezone: data.get("timezone") as string,
})
setSaved(true)
setTimeout(() => setSaved(false), 3000)
}
return (
<>
<form onSubmit={handleSubmit} style={{ display: "grid", gap: "1rem" }}>
<Input
name="name"
label="Anzeigename"
required
minLength={2}
autoComplete="name"
/>
<Select
id="timezone-select"
name="timezone"
label="Zeitzone"
items={[
{ value: "UTC", label: "UTC" },
{ value: "Europe/Berlin", label: "Europe/Berlin" },
{ value: "America/New_York", label: "America/New_York" },
]}
defaultValue="Europe/Berlin"
onChange={(_e, _v) => {}}
/>
<Button
title="Änderungen speichern"
type="submit"
variant="contained"
color="primary"
/>
</form>
<Snackbar
message="Einstellungen gespeichert"
color="success"
open={saved}
autoHideDuration={3000}
onClose={() => setSaved(false)}
anchorOrigin={{ vertical: "bottom", horizontal: "center" }}
/>
</>
)
}
Formularvalidierung
Form führt native Constraint-Validierung durch, bevor action aufgerufen wird. Für asynchrone Servervalidierung useActionState (React 19) verwenden:
import { useActionState } from "react"
const [state, action, isPending] = useActionState(updateProfile, undefined)
<Input name="name" label="Anzeigename" errorText={state?.errors?.name} />
Barrierefreiheit
- Jeder Formularabschnitt sollte in ein
<section>mit einem visuell versteckten<h2>eingebettet sein. Snackbarverwendet standardmäßigrole="status"undaria-live="polite".
Verwandte Komponenten
Form— Server-Action-kompatibel, Constraint-ValidierungInput— Label, Hint, Fehler- und Pflichtfeld-ZuständeSelect— Einzel- und Mehrfachauswahl-VariantenSnackbar— Toast-Nachrichten mit VariantenTabs— tastaturzugängliche Tab-Navigation
Weiterführende Informationen
- React
useActionState - Next.js Server Actions
- prokodo Next.js Agentur — wir entwickeln und betreiben Produkt-UIs