Escape Hatches
Überblick
Die UX-Spezifikationen von Jutro Design System basieren auf den erkannten UX-Anwendungsfällen und beschreiben die Probleme und Anforderungen sowie die zu deren Berücksichtigung empfohlenen Ansätze und Richtlinien. Die verschiedenen Jutro-Komponenten wurden entsprechend diesen UX-Spezifikationen erstellt. Alle verfügbaren Eigenschaften und Funktionen basieren auf diesen Spezifikationen.
Obwohl die UX-Angleichung der Komponenten im Vordergrund steht, enthalten sie auch benutzerdefinierte Alternativen, mit denen Entwickler über das Standardverhalten hinausgehen können. Und hier kommen Escape Hatches ins Spiel.
Was sind Escape Hatches?
„Escape Hatch“ ist ein Begriff aus der Softwareentwicklung, der sich auf absichtliche Alternativen (Lecks) im Modell bezieht, die es Benutzern ermöglichen, „auszubrechen“ und Zugang zu einer niedrigeren Abstraktionsschicht zu erhalten. Dies kann auch als Hintertür betrachtet werden, durch die der spezifische Abstraktionsvertrag „gehackt“ werden kann.
Ein für Jutro-Entwickler relevantes Beispiel sind die React Escape Hatches.
Escape Hatches in Jutro Design System
Beachten Sie die möglichen Nebeneffekte eines eventuell verwendeten Escape Hatch. Escape Hatches bieten zwar eine Möglichkeit zur Erweiterung eines Verhaltens oder zum Verringern von Anforderungslücken, können aber je nach Verwendung unerwartete Auswirkungen haben. Einige mögliche Auswirkungen sind fehlerhafte Funktionen, Probleme mit der Barrierefreiheit und Komplikationen bei künftigen Upgrades.
Jede Jutro-Komponente kann je nach Anwendungsfall und Komponententyp verschiedene Escape Hatches enthalten. In einigen Fällen sind diese Teil der stabilen API der Komponente, jedoch als Escape Hatches enthalten, da sie Optionen bieten, die neben der Angleichung der UX-Spezifikationen zusätzliche Flexibilität ermöglichen.
Nachstehend werden einige der gebräuchlichsten Escape Hatches beschrieben, die in Jutro-Komponenten enthalten sind. Informationen zu komponentenspezifischen Escape Hatches finden Sie in der Dokumentation der jeweiligen Komponente.
Design-Token
Obwohl sie Teil der API von Jutro-Komponenten sind, können Design-Token als Escape Hatches betrachtet werden, da sie die Anpassung der UX-Entscheidungen in Bezug auf Themes ermöglichen.
Weitere Informationen finden Sie im Abschnitt Design-Token.
dangerouslySet-Eigenschaften
Einige Komponenten verfügen über eine oder mehrere dangerouslySet...-Eigenschaften. Diese ermöglichen es dem Entwickler, ein ganzes Element oder einen Aspekt der Komponente vollständig zu überschreiben. In den meisten Fällen besteht diese Möglichkeit, wenn UX-Spezifikationen einen Grenzfall mit unbekannten Alternativen angeben.
Die Eigenschaft dangerouslySet wird als ReactNode typisiert. Normalerweise gibt es einen entsprechenden Hook für den Zugriff auf den Komponentenkontext.
Beispiel: Die Kopfzeile von AccordionCard besteht normalerweise nur aus Text (Eigenschaft title), in einigen spezifischen Fällen sind jedoch noch weitere Elemente wie Symbole, Tags oder auch Schaltflächen erforderlich. Daher wird eine dangerouslySetHeader-Eigenschaft bereitgestellt.
function MyCustomHeader() {
const { disabled } = useComponentState(); // provided hook for context information
return <span>{disabled ? 'I am disabled' : 'I am not disabled'}</span>;
}
<AccordionCard title="some title" dangerouslySetHeader={{<MyCustomHeader />}}/>
children-Eigenschaft
Im Allgemeinen wird jede Komponenteneigenschaft typisiert, um die möglichen Werte und Optionen einzuschränken, in einigen Fällen kann sie jedoch völlig offen gelassen werden (durch children: ReactNode). Das häufigste Szenario für diesen Fall sind die Komponenten, die hauptsächlich als Container für andere Inhalte verwendet werden sollen (z. B. modale Fenster).
className-Eigenschaft
Jutro-Komponenten werden in der Regel mit einem vordefinierten HTML-Klassenattribut gerendert. Einige Komponenten können die Eigenschaft className enthalten, die eine Klasse zum obersten Element der Komponente hinzufügt. Beispielsweise hat <DatePicker className="foo"> ein übergeordnetes Element mit einer Klasse, die in etwa so aussieht: <div class="foo fieldContainer_TIDj">.
Selektoren mit zugrunde liegender HTML-Struktur
Wenn Sie bestimmte HTML-Elemente einer gerenderten Komponente formatieren möchten, können Sie die zugrunde liegende generierte HTML-Struktur untersuchen und CSS-Selektoren zur Auswahl verwenden. Beispielsweise kann Text in allen von <DatePicker className="foo"> gerenderten label-HTML-Elementen folgendermaßen fett formatiert werden:
.foo label {
font-weight: bold;
}
Die zugrunde liegende HTML-Struktur einer Komponente ist nicht Teil der Komponenten-API, sodass sie Änderungen unterliegen kann, ohne dass diese als Breaking Change gelten. Während das oberste Element der Komponente stabil bleibt, kann die übrige interne Struktur geändert werden.
Selektoren mit vordefinierten Klassenattributen
Anstelle eines bereitgestellten className können Sie auch das vordefinierte Klassenattribut verwenden. Ohne className-Eigenschaft sieht DatePicker beispielsweise in etwa so aus: <div class="fieldContainer_TIDj">. Das zugehörige label-Element kann mit dem vordefinierten Klassenattribut wie folgt ausgewählt werden:
.fieldContainer_TIDj label {
font-weight: bold;
}
Die meisten internen Elemente verfügen zudem über vordefinierte HTML-Klassenattribute. Sie können diese auch zum Erstellen von CSS-Selektoren verwenden. Das gerenderte label-Element sieht beispielsweise in etwa so aus:
<label class="labelContainer_wEwV"><span>Choose date</span></label>
Anschließend kann es in etwa folgendermaßen ausgewählt werden:
.labelContainer_wEwV {
font-weight: bold;
}
Vordefinierte HTML-Klassenattribute sind nicht Teil der Komponenten-API, einschließlich des vordefinierten Klassenattributs der Komponente der obersten Ebene, sodass diese Werte Änderungen unterliegen können, ohne dass diese als Breaking Change gelten.
Wenn Sie die vordefinierten Klassenattribute in Ihrem Code verwenden, können sich diese zwischen Aktualisierungen ändern, was berücksichtigt werden muss.
Übergeben von HTML-Standardattributen zulassen
Neben der von Jutro definierten API ermöglichen einige Komponenten das Übergeben einer zusätzlichen Gruppe der nativen HTML-Attribute, die die Komponente enthalten kann. Diese zusätzlichen Attribute werden direkt an das Element der obersten Ebene oder an das in der Dokumentation der Komponente angegebene spezifische Element übergeben.
Ein Beispiel für diesen Anwendungsfall ist, dass einige der „input“-Jutro-Komponenten möglicherweise das Übergeben der HTML-Standardattribute zulassen, die ein natives input-HTML-Element unterstützt: z. B. id oder name. Die Liste der Attribute kann eingeschränkt werden, um zu verhindern, dass die Attribute die Eigenschaften und das Verhalten der Komponente beeinträchtigen Wenn eine Komponente beispielsweise bereits die maximal zulässige Länge ihres Inhalts verarbeitet, wird das native maxLength-Attribut möglicherweise nicht unterstützt.
Wie in anderen Fällen müssen auch hier die Nebenwirkungen der verwendeten Attribute berücksichtigt werden.
useId von @jutro/platform verwenden, um sicherzustellen, dass die ID eindeutig ist. Weitere Informationen zum Hook useId finden Sie auf der Seite Hooks.ref-Eigenschaft und imperative Handler
ref ist ein Escape Hatch, der Zugriff auf DOM-Knoten oder React-Komponenten bietet, sodass Entwickler Elemente außerhalb des Rendering-Ablaufs ändern können. In Jutro kann diese Option in einigen spezifischen Komponenten berücksichtigt werden, sie wird jedoch normalerweise nach dem Ansatz der imperativen Handler implementiert: Anstatt nur Zugriff auf das gesamte Element zu gewähren, werden spezifische Methoden oder Eigenschaften basierend auf den bekannten Anwendungsfällen verfügbar gemacht. Sie können in künftigen Bibliotheksversionen weiterentwickelt und erweitert werden.
Ein Beispiel für diese Option ist die Erstellung einer ref-Eigenschaft, die nur Zugriff auf bestimmte Funktionen gewährt, z. B. das Setzen des Fokus auf ein Feld oder das Scrollen zu einem bestimmten Element.
Native Ereigniseigenschaft
Jutro-Eingabekomponenten machen Ereignisse wie onChange verfügbar. Diese Ereignisse enthalten neben anderen benutzerdefinierten Werten normalerweise das native event-Objekt, das das Ereignis ausgelöst hat.
Es wird erwartet, dass die benutzerdefinierten Werte, die an das Ereignis übergeben werden, Entwicklern in der Regel ausreichend Informationen liefern. Dieses event-Objekt ermöglicht jedoch eine erweiterte Steuerung einiger grundlegender Funktionen wie preventDefault.
Ein onChange-Ereignis kann z. B. wie folgt definiert werden: (event: React.ChangeEvent<HTMLInputElement>, newValue: T) => void. So kann der Entwickler einfach newValue verwenden, um Validierungen oder Aktionen basierend auf der Benutzereingabe durchzuführen. Das native Ereignis ist aber auch für jede zusätzliche Funktion verfügbar.