Elemente
Table
Ein Table legt einige Zeilen aus, die die App als Kindelemente schreibt (Rechnungen, eine Zusammenfassung, einen Vergleich), und stellt Screenreadern eine Tabelle bereit: die Tabelle selbst, Zeilengruppen, Zeilen, Spaltenköpfe und Zellen, jeweils mit ihrer Rolle. Seine Teile sind TableHeader, TableBody und TableFooter (Zeilengruppen), TableRow (seine Zellen nebeneinander), TableHead (die Kopfzelle einer Spalte), TableCell und TableCaption. Das Aussehen bestimmt die App: Kein Teil hat eigene Farben, Rahmen, Innenabstände oder Breiten, und jedes übernimmt die class und style der App. Für viele Zeilen, Sortierung, Auswahl und in der Größe veränderbare Spalten ist DataTable die passende Tabelle.
import { mount, Text, View } from "nsh";
import { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from "nsh/base";
import { size, Stage, ui } from "./palette";
// A few rows the app writes out: the parts give screen readers a table, the
// classes and the palette give it its look.
const invoices = [
{ id: "INV001", status: "Paid", method: "Card", amount: 250 },
{ id: "INV002", status: "Pending", method: "Transfer", amount: 150 },
{ id: "INV003", status: "Unpaid", method: "Card", amount: 350 },
{ id: "INV004", status: "Paid", method: "Cash", amount: 450 },
];
const widths = ["w-24", "flex-1", "w-24", "w-24"];
function Cell(props: { i: number; head?: boolean; end?: boolean; children: string }) {
const style = { fontSize: size.label, color: props.head ? ui().muted : ui().text, fontWeight: props.head ? ("500" as const) : ("400" as const) };
const Part = props.head ? TableHead : TableCell;
return (
<Part class={`${widths[props.i]} px-3 py-2.5`}>
<Text style={{ ...style, textAlign: props.end ? "right" : "left" }}>{props.children}</Text>
</Part>
);
}
function App() {
const line = { borderBottomWidth: 1, borderColor: ui().line };
const total = invoices.reduce((sum, i) => sum + i.amount, 0);
return (
<Stage width={520}>
<View style={{ ...ui().card, borderRadius: 12, overflow: "hidden" }}>
<Table accessibilityLabel="Recent invoices">
<TableHeader>
<TableRow style={line}>
{["Invoice", "Status", "Method", "Amount"].map((title, i) => (
<Cell i={i} head end={i === 3}>
{title}
</Cell>
))}
</TableRow>
</TableHeader>
<TableBody>
{invoices.map((inv) => (
<TableRow style={line}>
<Cell i={0}>{inv.id}</Cell>
<Cell i={1}>{inv.status}</Cell>
<Cell i={2}>{inv.method}</Cell>
<Cell i={3} end>{`$${inv.amount.toFixed(2)}`}</Cell>
</TableRow>
))}
</TableBody>
<TableFooter>
<TableRow>
<Cell i={0} head>Total</Cell>
<Cell i={1}>{""}</Cell>
<Cell i={2}>{""}</Cell>
<Cell i={3} end>{`$${total.toFixed(2)}`}</Cell>
</TableRow>
</TableFooter>
<TableCaption class="px-3 py-2">
<Text style={{ fontSize: size.detail, color: ui().muted }}>A list of your recent invoices.</Text>
</TableCaption>
</Table>
</View>
</Stage>
);
}
mount(App);use nsh_base::{table, table_body, table_cell, table_head, table_header, table_row, theme};
use nsh_core::prelude::*;
fn invoices() -> impl IntoElement {
let cell = |label: &'static str| table_cell().w(px(120.0)).px_3().py_2().child(text(label));
table()
.accessibility_label("Recent invoices")
.child(
table_header().child(
table_row()
.border_b_1()
.border_color(move || theme().border)
.child(table_head().w(px(120.0)).px_3().py_2().child(text("Invoice")))
.child(table_head().w(px(120.0)).px_3().py_2().child(text("Amount"))),
),
)
.child(table_body().child(table_row().child(cell("INV001")).child(cell("$250.00"))))
}import { mount, Text } from "nsh";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "nsh/base";
function App() {
return (
<Table accessibilityLabel="Recent invoices">
<TableHeader>
<TableRow class="border-b border-border">
<TableHead class="w-32 px-3 py-2"><Text>Invoice</Text></TableHead>
<TableHead class="w-32 px-3 py-2"><Text>Amount</Text></TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell class="w-32 px-3 py-2"><Text>INV001</Text></TableCell>
<TableCell class="w-32 px-3 py-2"><Text>$250.00</Text></TableCell>
</TableRow>
</TableBody>
</Table>
);
}
mount(App);Table und seine Teile stammen aus nsh/base, dem nsh-base-Crate in Rust, in dem table(), table_header(), table_body(), table_footer(), table_row(), table_head(), table_cell() und table_caption() sie erzeugen, mit den typisierten Style-Methoden und .child(..). Eine Zeile legt ihre Zellen nebeneinander aus; die App gibt den Zellen ihre Breiten, sodass die Spalten ausgerichtet sind.
#Props
| Prop | Rust | Typ | Standard | Beschreibung |
|---|---|---|---|---|
accessibilityLabel |
.accessibility_label(..) |
string |
keiner | Nur Table: wie Screenreader die Tabelle nennen. |
children |
.child(..) |
JSX.Element |
keiner | Was das Teil enthält: Gruppen und eine Beschriftung in einem Table, Zeilen in einer Gruppe, Zellen in einer Zeile, Inhalt in einer Zelle. |
class, style |
Style-Methoden | string, StyleProp<ViewStyle> |
keiner | Aussehen und Layout des Teils. |
#Teile
| Teil | Enthalten in | Rolle für Screenreader |
|---|---|---|
Table |
Tabelle | |
TableHeader |
Table |
Zeilengruppe: die Zeilen mit den Spaltenköpfen |
TableBody |
Table |
Zeilengruppe: die Datenzeilen |
TableFooter |
Table |
Zeilengruppe: Summen, eine Zusammenfassungszeile |
TableRow |
eine Gruppe oder Table |
Zeile; ihre Zellen nebeneinander |
TableHead |
ein TableRow des Kopfbereichs |
Spaltenkopf |
TableCell |
TableRow |
Zelle |
TableCaption |
Table |
Inhalt, den die App zur Tabelle anzeigt |
Jede Plattform gibt die Rollen an ihren Screenreader weiter: Rollen für Tabelle, Zeile, Zelle und Spaltenkopf unter Linux (AT-SPI), im Web (ARIA), unter Android und im GPUI-Backend; Grids und Gruppen unter macOS und Windows; Köpfe als Header unter iOS.
#Siehe auch
- DataTable: eine Tabelle mit beliebig vielen Zeilen und Spalten, mit Auswahl, Sortierung und in der Größe veränderbaren, verschiebbaren Spalten.
- Accessibility: die
accessibilityRole-Werte, daruntertable,row,cell,columnheaderundrowgroup.