Die Komponenten verwenden
Attribute, Properties, Events und die Einbindung ins Framework.
Die Komponenten sind gewöhnliche Custom Elements. Alles Folgende ist reines DOM und braucht kein Framework; danach kommt, was die einzelnen Frameworks ergänzen.
Attribute und Properties
Jeder Parameter lässt sich entweder als HTML-Attribut oder als JavaScript-Property setzen. Die Schreibweise unterscheidet sich dabei:
- Attribut im HTML, immer kleingeschrieben:
iconright - Property aus JavaScript, in
camelCase:iconRight
Jede Komponentenseite führt beide Namen nebeneinander auf. Die meisten Attribute sind der kleingeschriebene Property-Name, zwei werden mit Bindestrich geschrieben:
| Property | Attribut | Element |
|---|---|---|
borderRadius | border-radius | tuix-paper |
visibilityDuration | visibility-duration | tuix-toast |
Objekte und Arrays
Attributwerte sind immer Text. Parameter, die ein Objekt oder ein Array erwarten, werden deshalb als Property gesetzt:
| Element | Parameter |
|---|---|
tuix-dropdown | options, value |
tuix-radio-button | options |
tuix-table | data, headers, pageSizeOptions, loader |
In einer reinen HTML-Seite gibt es dafür kein JavaScript, dort steht der Wert als JSON im Attribut:
JSON kann keine Funktionen transportieren; eine Spalte mit cellColor muss
deshalb als Property gesetzt werden.
Der nächste Abschnitt zeigt, wie die einzelnen Frameworks eine Property setzen.
Einen Parameter übergeben
Jeder Parameter gehört zu einer von fünf Arten, und jedes Framework hat je einen
Weg dafür. Die Tabs zeigen dasselbe Dropdown dreimal: ein String, ein Enum, eine
Objektliste, das gemeinsame Boolean dark und ein Event.
<tuix-dropdown
title="Country"
description="Pick a country"
[type]="DropdownType.SEARCH"
[descriptionType]="DescriptionType.ERROR"
[options]="countries"
[dark]="isDark"
(select)="onSelect($event)"
></tuix-dropdown>import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'
import { DescriptionType, DropdownType } from 'tuix-webcomponents'
@Component({
selector: 'app-example',
standalone: true,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
templateUrl: './example.component.html',
})
export class ExampleComponent {
readonly DescriptionType = DescriptionType
readonly DropdownType = DropdownType
readonly countries = [
{ name: 'Switzerland', value: 'CH' },
{ name: 'Germany', value: 'DE' },
]
isDark = false
onSelect(event: Event) {
const { value } = (event as CustomEvent<{ value: string | number | boolean }>).detail
console.log(value)
}
}| Art | Reines HTML | Angular | Vue | React |
|---|---|---|---|---|
| String | title="Country" | gleich | gleich | title="Country" |
| Enum | type="search" | [type] | :type | type={...} |
Boolean, auch dark | dark | [dark] | :dark | dark={...} |
| Objekt oder Array | JSON | [options] | :options | options={...} |
| Event | addEventListener | (select) | @select | onSelect={...} |
Dark Mode
Jedes Element ausser tuix-table nimmt ein Boolean
dark entgegen. Kein Element liest ein globales Theme: die Anwendung übergibt
dark pro Element, aus dem, womit sie das Theme verwaltet.
dark erreicht, was eine Komponente selbst rendert: das Modal reicht es an
seine Karte und sein Schliess-Icon weiter, Toast und Checkbox an das Label, das
sie zeichnen. Was in sie hineingeslottet wird, erreicht es nie. Eigener Inhalt
bringt sein dark deshalb selbst mit:
Diese eine Ausnahme will eingeplant sein: die tuix-text- und
tuix-icon-Elemente der Tabelle bleiben hell, was die Seite auch tut. Ein
dunkles Design gibt der Tabelle deshalb eine helle Fläche, statt sie
umzuschalten.
Events
Die Komponenten melden sich über CustomEvents, die bubblen. Die Nutzlast
liegt, wenn es eine gibt, in event.detail, bei den meisten Events also in
event.detail.value:
Die drei Pagination-Events von tuix-table sind die Ausnahme: sie tragen
event.detail.page und event.detail.pageSize und gar keinen value. Checkbox
und Toggle stellen neben den Wert noch event.detail.label.
Die Namen sind bewusst nicht die nativen: ein Button feuert customClick, ein
Input on-change. Die vollständige Liste steht unter
Events.
Nur die Pagination-Events von tuix-table überqueren die Shadow-Grenze (composed: true). Alle anderen bubblen
innerhalb des Baums, in dem sie gefeuert wurden, also genau dort, wo ein normaler Listener am Element oder an einem
seiner Vorfahren sie sieht.
Im Framework
Jedes Framework braucht etwas Vorbereitung: eine Wrapper-Bibliothek für React, ein Compiler-Flag für Vue, ein Schema für Angular. Je ein Guide, und danach lässt sich jedes Beispiel auf den Komponentenseiten in dem Framework lesen, das in den Tabs darüber gewählt ist:
React und Next.js
Die generierten Wrapper, und was SSR braucht.
Vue
isCustomElement, Property-Binding und das camelCase-Event.
Angular
CUSTOM_ELEMENTS_SCHEMA, Bindings und ein ControlValueAccessor.
Reines HTML
Das Bundle wird mit den zwei Tags aus der Installation geladen. Deren URLs enthalten das Release und werden deshalb dort generiert statt hier ausgeschrieben. Danach sind die Elemente einfache Tags:
Slots und Layout
Textinhalt kommt in den Default-Slot des Elements, und die Komponenten mit
mehreren Bereichen benennen ihre Slots (tuix-modal: title, body,
actions; tuix-table: ein Slot pro Zelle). Weil der Inhalt im Light DOM
bleibt, greifen die Styles der Seite weiterhin auf ihn; isoliert ist nur das
Innenleben der Komponente.