Zum Hauptinhalt springen

Erstellen von Komponenten

Warning: Präsentationsmetadaten sind in Jutro 10.0 veraltet. JSX ist der empfohlene Mechanismus für die Implementierung der Benutzeroberfläche. Wenn Sie Dokumentation zu Metadaten benötigen, wechseln Sie zu einer Version der Dokumentation, die älter als 10.0 ist.

Vorbereitung​

In den meisten Fällen sollten Jutro-Komponenten Ihren Anforderungen entsprechen. Eventuell möchten Sie jedoch Komponenten erstellen, um Ihren Code zu organisieren und Ihre Seiten zu erstellen. In folgenden Fällen erstellen Sie eigene Komponenten:

  • Sie möchten den Status oder die komplexe Konfiguration einer Jutro-Komponente verwalten.
  • Sie möchten Ihre benutzerdefinierte Logik mit einer Komponente umschließen.
  • Sie möchten mehrere Komponenten in einem Widget gruppieren, das eine bestimmte Anforderung erfüllt. Insbesondere, wenn dieses Widget an mehreren Stellen wiederverwendet werden soll.
  • Sie fügen eine Seite in Ihrer Anwendung ein. Es ist sinnvoll, die Seite in einer React-Komponente zu kapseln und im Grundriss zu verwenden.

Ihre benutzerdefinierte Komponente kann wie folgt aussehen:

Erweiterte Komponenten​

Um eine Jutro-Komponente zu erweitern, können Sie sie mit einer eigenen Komponente umschließen. Damit können Sie Standardeigenschaften oder Ereignis-Handler festlegen. Diese Komponente erbt Lokalisierungs-, Zugänglichkeits- und andere relevante Funktionen.

Sie können beispielsweise das Feld FavoriteBook mit der Beschriftung „Favorite Book“ erstellen, für das immer ein spezifischer Stil angewendet wird.

import { TextInput } from '@jutro/components';
import messages from './FavoriteBook.messages.js';
import styles from './FavoriteBook.module.scss';
. . .
const FavoriteBook = () => {
return (
<TextInput
label="Favorite Book"
placeholder="What is your favorite book?"
classname="favoritebook"
/>
);
};

Zusammengesetzte Komponenten​

Sie können neue Komponenten erstellen, indem Sie vorhandene Jutro-Komponenten, erweiterte und benutzerdefinierte Komponenten gruppieren. Diese zusammengesetzten Komponenten erben alle relevanten Funktionen der verwendeten Jutro-Komponenten.

Note: Einzelne Komponenten können zwar responsiv sein, die Gruppe dagegen möglicherweise nicht. Daher sind Sie dafür zuständig, das Ihre zusammengesetzten Komponente responsiv sind oder dass Umwandlungsfunktionen verwendet werden.

Erstellen Sie z. B. eine benutzerdefinierte Komponente ControlCenter mit Jutro-Komponenten wie Card, NumberValuenumber, Grid oder Icon und mehreren benutzerdefinierten Eigenschaften und dem Lokalisierungsmechanismus, um spezifische Kundeninformationen anzuzeigen.

import { Card, NumberValue, Icon } from '@jutro/components';
import { Grid, GridItem } from '@jutro/layout';
import messages from './ControlCenter.messages.js';

export const ControlCenter = (props) => {
const icon =
props.daysSince < 7
? 'gw-error'
: props < 30
? 'gw-warning'
: 'gw-check-circle';
const style =
props.daysSince < 7
? { color: 'red' }
: props.daysSince < 30
? { color: 'orange' }
: { color: 'green' };

return (
<Card
title={messages.heading}
style={style}>
<Grid columns={['1fr', '1fr']}>
<GridItem>
<Icon icon={icon} />
</GridItem>
<GridItem>
<NumberValue
id="daysSince"
value={props.daysSince}
suffix={messages.dayssince}
/>
</GridItem>
</Grid>
</Card>
);
};

Best Practices für die Erstellung einer neuen Komponente​

Befolgen Sie beim Erstellen neuer Komponenten folgende allgemeine Richtlinien:

  • Verwenden Sie in den Komponenten keinen fest codierten Text. Speichern Sie Übersetzungszeichenfolgen in ComponentName.messages.js und importieren Sie sie wie folgt:

    import messages from './ComponentName.messages.js';
  • Fügen Sie Stile in der Datei ComponentName.module.scss hinzu und importieren Sie sie wie folgt:

    import styles from './ComponentName.module.scss';
  • Aus folgenden Gründen wird empfohlen, Funktionskomponenten anstelle von Klassenkomponenten zu verwenden:

    • Funktionskomponenten lassen sich erheblich einfacher lesen und testen, da es sich um einfache JavaScript-Funktionen ohne Status und Lebenszyklus-Hooks handelt.

    • Dadurch wird weniger Code verwendet.

    • Sie helfen Ihnen bei der Anwendung von Best Practices. Es wird einfacher, Container und Präsentationskomponenten zu trennen, da Sie sich eingehender mit dem Status der Komponente befassen müssen, wenn Sie keinen Zugriff auf setState() in der Komponente haben.

    Klicken Sie hier, um weitere Informationen zu Funktionskomponenten zu erhalten.

Ordnerstruktur erstellen​

Erstellen Sie unter src/Components ein Verzeichnis für die Komponente, z. B CustomInput, und fügen Sie die folgenden Dateien hinzu:

  • src/components/CustomInput/CustomInput.test.tsx
  • src/components/CustomInput/CustomInput.tsx
  • src/components/CustomInput/CustomInput.messages.ts
  • src/components/CustomInput/CustomInput.module.scss

Durch Einhaltung dieser Namenskonvention lassen sich künftige Aktualisierungen einfacher durchführen.

Komponente erstellen​

  1. Erstellen Sie im Verzeichnis CustomInput die Datei <componentName>.tsx, in diesem Beispiel ./CustomInput.tsx.
  2. Der Code der Komponente CustomInput muss Folgendes angeben:
    • Erwartete Eigenschaften (PropTypes) und deren zugehörige Werte
    • Statusverwaltungsfunktionen unter Verwendung der Funktionen writeValue und readValue. writeValue muss den Wert der Komponente testInput übernehmen, den Status der Komponente zurücksetzen und den Wert von testInput an die Komponente testOutput ausgeben.
import React, { useContext } from 'react';
import { TranslatorContext } from '@jutro/locale';

import styles from './CustomInput.module.scss';
import messages from './CustomInput.messages.ts';

type CustomInputProps = {
title?: string,
};

export const CustomInput: React.FC<CustomInputProps> = ({ title }) => {
const translator = useContext(TranslatorContext);

return (
<div
className={styles.customInput}
title={title}>
{translator(messages.label)}
</div>
);
};

Meldungsdatei erstellen (optional)​

Wie im Abschnitt Best Practices angegeben, sollte die Komponente keinen fest codierten Text enthalten. Sie müssen also eventuell die Meldungsdatei erstellen, um die Umwandlungszeichenfolgen zu speichern:

import { defineMessages } from 'react-intl';

export default defineMessages({
label: {
id: 'jutro-app.components.CustomInput.label',
defaultMessage: 'custom inputLabel',
},
});

Weitere Informationen finden Sie im Abschnitt Internationalisierung und Lokalisierung.

Note: Der Dateiname sollte nach dem Muster <ComponentName>.messages.js angegeben werden.

Stylesheet-Datei erstellen (optional)​

Bei Bedarf können Sie zusätzliche Stile in der Datei ./CustomInput.module.scss definieren.

Note: Der Dateiname sollte nach dem Muster <ComponentName>.module.scss angegeben werden.

Komponente auf Barrierefreiheit testen​

Achten Sie darauf, dass die Komponente zumindest die grundlegenden Anforderungen für die Zugänglichkeit erfüllt:

  • Verfügbarkeit für Screenreader
  • Navigation über Tastatur möglich
  • Angemessener Kontrast

Weitere Informationen finden Sie auf unserer Seite über Barrierefreiheit.

Tests für eigene Komponenten schreiben​

Damit Ihre Komponente lange Zeit funktionsfähig bleibt, sind vollständige und gründliche Tests unerlässlich. Weitere Informationen dazu finden Sie im umfassenden Abschnitt zu Tests.

Hier ein Beispieltest für die erstellte Komponente:

import React from 'react';
import {
render,
screen,
getTranslation,
checkA11yViolations,
} from '@jutro/test';

import messages from './CustomInput.messages';
import { CustomInput } from './CustomInput';

describe('CustomInput', () => {
it('renders default component', () => {
const sampleTitle = 'sample';

render(<CustomInput title={sampleTitle} />);

expect(screen.getByTitle('sample')).toBeInTheDocument();
});

it('renders with custom prop value', () => {
const newTitle = 'newTitle';

render(<CustomInput title={newTitle} />);

expect(screen.getByTitle(newTitle)).toBeInTheDocument();
});

it('renders with css class', () => {
const sampleTitle = 'sample';

render(<CustomInput title={sampleTitle} />);

expect(screen.getByTitle('sample')).toHaveClass('customInput');
});

it('renders with translation', () => {
render(<CustomInput />);

expect(
screen.getByText(getTranslation(messages.label))
).toBeInTheDocument();
});

it('has no a11y violations', async () => {
await checkA11yViolations(<CustomInput />);
});
});

Komponenten in einem neuen Paket​

Beim Erstellen von Komponenten, die vollständig eigenständig und wiederverwendbar sein müssen, empfiehlt es sich, einen Abhängigkeitsbaum in einer package.json-Datei auf Komponentenebene zu erstellen. Anschließend erstellen Sie eine JavaScript-Datei, die als Einstiegspunkt in Ihr Modul dient, die alle Unterkomponenten importiert und erneut exportiert, damit sie wiederverwendet werden können.

Für eine MyCustomComponent-Komponente gehen Sie wie folgt vor:

  1. Erstellen Sie einen neuen Paketordner mit dem Namen CustomInput.

  2. Erstellen Sie wie folgt die Datei index.js zum Exportieren der Unterkomponenten von CustomComponent:

    import SubComponent1 from './SubComponent1';
    import SubComponent2 from './SubComponent2';
    import SubComponent3 from './SubComponent3';

    export { SubComponent1, SubComponent2, SubComponent3 };
  3. Definieren Sie die Datei package.json mit Abhängigkeiten.

    {
    "name": "my-custom-component-module",
    "description": "Description for my-component",
    "main": "index.js",
    "version": "1.0.1-32745cd39da0",
    "author": "Your Name",
    "private": true,
    "dependencies": {
    // other component modules are re-used by MyComponent
    "self-contained-component-module": "someVersion",
    "another-self-contained-component-module": "someVersion"
    },
    "peerDependencies": {
    // dependencies such as React, Lodash are set as peer dependencies
    "react": "18.x",
    "prop-types": "15.x",
    "react-intl": "2.9.x",
    "lodash": "4.x",
    "classnames": "^2.x"
    }
    }
  4. Fügen Sie den Modulverweis (my-component-module) in der Datei package.json der Anwendung als Abhängigkeit hinzu.

  5. Verwenden Sie das Modul durch Importieren von Unterkomponenten aus dem Paket.

    import { SubComponent1, SubComponent3 } from 'my-custom-component-module';

Diese Komponente und ihre Unterkomponenten können in der Anwendung uneingeschränkt wiederverwendet werden.