Zum Hauptinhalt springen
Sachbearbeiter-Cockpit

Field

const Field: React.FC<FieldProps>

Anzeige-/Eingabefeld, das den Wert aus einem JSON-Objekt per Pfad liest.

Ermittelt den Wert aus dem Ergebnis der dataSource-Query (per jsonPath). ISO-Datumswerte werden als DD.MM.YYYY formatiert, Booleans als „Ja"/„Nein"; während des Ladens erscheint ein Skeleton.

Hinweis Dieses Component ist für Read-only und editierbare Felder gedacht. In Storybook/Tests ohne echten Query-Hook staticSource nutzen.

// Mit Query-Hook (wie bei List)
const Field = createField(() => useFile(id));
<Field jsonPath="title.de" label="Titel" />

// Statisches Objekt (Storybook/Tests)
<Field dataSource={staticSource({ user: { name: 'Ada' } })} jsonPath="user.name" label="Name" />

// Vollständig gestylt: className überschreibt kollidierende Defaults
<Field … className="text-2xl font-bold text-red-600 my-0"
classNames={{ label: "text-sm text-blue-600 uppercase" }} />

Vorschau

Name
Ada Lovelace
Erstellt am
15.01.2026
Aktiv
Ja
Name (editierbar)

Im Sachbearbeiter-Cockpit verwenden

Wie du eine Datenquelle einmal definierst und an mehrere Felder weitergibst (und wann createField die bessere Wahl ist), steht unter Datenquellen.

Für die Optik gibt es zwei Props: className stylt den Wrapper um Label und Wert — Label und Wert erben davon, weil sie keine eigenen Text-Klassen setzen. Reicht das nicht, adressiert classNames die einzelnen Slots root, label, value, input, empty und skeleton. In beiden Fällen werden kollidierende Default-Klassen entfernt, deine Angabe gewinnt also (text-sm ersetzt das interne text-base):

<Field … className="text-2xl font-bold text-red-600 my-0"
classNames={{ label: "text-sm text-blue-600 uppercase" }} />
Kein Schreiben

editable rendert ein Input-Feld, gibt Änderungen aber nicht an einen Store weiter — zum Speichern brauchst du ein eigenes Formular plus useSaveFile(), siehe Erste App bauen.

Props

Props für das Field Component.

Properties

className?

optional className?: string

Klassen für den Wrapper — inklusive Typografie.

Kollidierende Default-Klassen werden entfernt, className gewinnt also immer (auch text-*, font-*, leading-*, my-*, flex-*, ...). Typografie wird vom Wrapper an Wert und Input vererbt; das Label hat eigene Größe/Farbe und wird über classNames.label gestylt.

<Field … className="text-2xl font-bold text-red-600 my-0" />

Nicht betroffen ist der Entwickler-Hinweis bei einem unbekannten jsonPath — der bleibt absichtlich als Fehlerdarstellung erkennbar.


classNames?

optional classNames?: FieldClassNames

Styling einzelner Slots, wenn className (Wrapper + Vererbung) nicht ausreicht — z.B. nur das Label oder nur das Input-Feld.


dataSource

dataSource: () => UseQueryResult<JsonObject, Error>

Datenquelle als Query-Funktion. Wird beim Rendern aufgerufen; Field liest den Wert (per jsonPath) aus query.data und zeigt während isPending/isPlaceholderData ein Skeleton.

Liegt bereits ein statisches Objekt vor (kein echter Query-Hook), mit staticSource umwickeln: dataSource={staticSource(obj)}.

Returns

UseQueryResult<JsonObject, Error>


editable?

optional editable?: boolean

Zeigt ein Input-Feld statt statischem Text.


jsonPath

jsonPath: string

Pfad innerhalb des JSON (z.B. "user.name").


label?

optional label?: string

Label oberhalb des Werts.

FieldClassNames

Klassen für die einzelnen Bausteine („Slots") des Field Components.

Jeder Wert wird mit den Default-Klassen des jeweiligen Slots zusammengeführt und überschreibt dabei kollidierende Defaults (z.B. ersetzt text-sm das interne text-base).

Properties

empty?

optional empty?: string

Platzhalter („—"), wenn kein Wert vorhanden ist.


input?

optional input?: string

Das Input-Feld im editable-Modus.


label?

optional label?: string

Label über dem Wert.


root?

optional root?: string

Wrapper um Label + Wert — gleichwertig zu FieldProps.className.


skeleton?

optional skeleton?: string

Container um das Lade-Skeleton.


value?

optional value?: string

Der Wert im Read-only-Modus.

createField

createField(dataSource): FC<BoundFieldProps>

Factory: erzeugt eine Field-Variante mit fest verdrahteter dataSource. Praktisch in Detailansichten, in denen viele Felder an derselben Quelle hängen.

Der Aufruf gehört auf Modulebene. Innerhalb einer Render-Funktion entstünde bei jedem Render ein neuer Komponententyp, wodurch React den Teilbaum neu aufbaut — ein Eingabefeld verliert dann bei jedem Tastendruck den Fokus.

Braucht die Quelle einen Parameter, holt sie ihn selbst — sie ist ein Hook und darf useParams, Context o. Ä. verwenden.

Parameters

dataSource

() => UseQueryResult<JsonObject, Error>

Query-Funktion, die für jede Instanz verwendet wird.

Returns

FC<BoundFieldProps>

Eine Komponente, die alle BoundFieldProps annimmt.

Example

function useAkteAusRoute() {
const { fileId = "" } = useParams();
return useFile(fileId);
}
const AktenFeld = createField(useAkteAusRoute);

<AktenFeld jsonPath="title.de" label="Betreff" />