Using the components
Attributes, properties, events and framework integration.
The components are standard custom elements. Everything below is plain DOM and needs no framework, followed by the details each framework adds.
Attributes and properties
Each parameter can be set either as an HTML attribute or as a JavaScript property. The name differs between the two:
- Attribute written in HTML, always lowercase:
iconright - Property set from JavaScript, in
camelCase:iconRight
Every component page lists both names side by side. Most attributes are the property name in lowercase; two are written with a hyphen:
| Property | Attribute | Element |
|---|---|---|
borderRadius | border-radius | tuix-paper |
visibilityDuration | visibility-duration | tuix-toast |
Objects and arrays
Attribute values are always text. The parameters that take an object or an array are therefore set as properties:
| Element | Parameters |
|---|---|
tuix-dropdown | options, value |
tuix-radio-button | options |
tuix-table | data, headers, pageSizeOptions, loader |
In a plain HTML page there is no JavaScript to do that, so the value goes into the attribute as JSON instead:
JSON cannot carry functions, so a header that uses cellColor has to be set as
a property.
The next section shows how each framework sets a property.
Passing a parameter
Every parameter falls into one of five kinds, and each framework has one way of
passing each. The tabs show the same dropdown written three times: a string, an
enum, an object list, the shared dark boolean and an 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)
}
}| Kind | Plain HTML | Angular | Vue | React |
|---|---|---|---|---|
| String | title="Country" | same | same | title="Country" |
| Enum | type="search" | [type] | :type | type={...} |
Boolean, dark included | dark | [dark] | :dark | dark={...} |
| Object or array | JSON | [options] | :options | options={...} |
| Event | addEventListener | (select) | @select | onSelect={...} |
Dark mode
Every element except tuix-table takes a dark
boolean. Nothing reads a global theme: the application passes dark per
element, from whatever it uses to track the theme.
dark reaches what a component renders itself (the modal hands it to its
card and its close icon, the toast and the checkbox to the label they draw) and
never what is slotted into it. Content of your own therefore carries its own
dark:
That one exception is worth planning for: the table's own tuix-text and
tuix-icon stay on the light palette whatever the page does, so a dark design
gives the table a light surface rather than switching it.
Events
The components communicate through CustomEvents that bubble. The payload, when
there is one, is in event.detail, which for most events means
event.detail.value:
tuix-table's three pagination events are the exception: they carry
event.detail.page and event.detail.pageSize and no value at all. A
checkbox and a toggle put event.detail.label next to the value.
Note the names are not the native ones: a button fires customClick, an input
fires on-change. The full list is in Events.
Only tuix-table's pagination events cross the shadow boundary (composed: true). The rest bubble inside the tree
they were fired in, which is what a normal listener on the element or one of its ancestors sees.
In a framework
Each framework needs a little setup: a wrapper library for React, a compiler flag for Vue, a schema for Angular. One guide each, and once that is done every example on the component pages can be read in the framework picked in the tabs above it:
React and Next.js
The generated wrappers, and what SSR needs.
Vue
isCustomElement, property binding and the camelCase event.
Angular
CUSTOM_ELEMENTS_SCHEMA, bindings and a ControlValueAccessor.
Plain HTML
Load the bundle with the two tags from Installation. Their URLs carry the release, so they are generated there rather than written out here. The elements are then plain tags:
Slots and layout
Text content goes into the default slot of the element, and the components that
have more than one region name their slots (tuix-modal: title, body,
actions; tuix-table: one slot per cell). Because the content stays in the
light DOM, the page's own styles still apply to it; only the component's chrome
is isolated.