Field
constField: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
- Vorschau
- Code
import { Field, staticSource } from '@gentics/cockpit/widgets';
// Im echten Sachbearbeiter-Cockpit den Query-Hook binden:
// const BoundField = createField(() => useFile(id));
// <BoundField jsonPath="title.de" label="Titel" />
<Field dataSource={staticSource({ user: { name: 'Ada Lovelace' } })} jsonPath="user.name" label="Name" />
<Field dataSource={staticSource({ created: '2026-01-15' })} jsonPath="created" label="Erstellt am" />
<Field dataSource={staticSource({ active: true })} jsonPath="active" label="Aktiv" />
<Field editable dataSource={staticSource({ user: { name: 'Ada Lovelace' } })} jsonPath="user.name" label="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" }} />
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?
optionalclassName?: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?
optionalclassNames?: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?
optionaleditable?:boolean
Zeigt ein Input-Feld statt statischem Text.
jsonPath
jsonPath:
string
Pfad innerhalb des JSON (z.B. "user.name").
label?
optionallabel?: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?
optionalempty?:string
Platzhalter („—"), wenn kein Wert vorhanden ist.
input?
optionalinput?:string
Das Input-Feld im editable-Modus.
label?
optionallabel?:string
Label über dem Wert.
root?
optionalroot?:string
Wrapper um Label + Wert — gleichwertig zu FieldProps.className.
skeleton?
optionalskeleton?:string
Container um das Lade-Skeleton.
value?
optionalvalue?: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" />
