Эта страница переведена машинным способом и может содержать ошибки. Читать оригинал на английском

Элементы

Table

Table раскладывает несколько строк, которые приложение записывает как дочерние элементы (счета, итог, сравнение), и передаёт скринридерам таблицу: саму таблицу, группы строк, строки, заголовки столбцов и ячейки, каждую со своей ролью. Её части: TableHeader, TableBody и TableFooter (группы строк), TableRow (ячейки строки, расположенные рядом), TableHead (заголовочная ячейка столбца), TableCell и TableCaption. Внешний вид определяет приложение: ни у одной части нет собственных цветов, границ, отступов или ширины, и каждая принимает class и style приложения. Для большого числа строк, сортировки, выделения и столбцов с изменяемой шириной предназначен DataTable.

el-table.tsx
el-table.tsxLive
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"))))
}

Table и её части поставляются в nsh/base, crate nsh-base для Rust, где их создают table(), table_header(), table_body(), table_footer(), table_row(), table_head(), table_cell() и table_caption(), с типизированными методами стиля и .child(..). Строка раскладывает свои ячейки рядом; ширину ячейкам задаёт приложение, поэтому столбцы выравниваются.

#Свойства

СвойствоRustТипПо умолчаниюОписание
accessibilityLabel.accessibility_label(..)stringнетТолько для Table: как скринридеры называют таблицу.
children.child(..)JSX.ElementнетСодержимое части: группы и подпись в Table, строки в группе, ячейки в строке, содержимое в ячейке.
class, styleметоды стиляstring, StyleProp<ViewStyle>нетВнешний вид и раскладка части.

#Части

ЧастьВнутриРоль для скринридеров
Tableтаблица
TableHeaderTableгруппа строк: строки заголовков столбцов
TableBodyTableгруппа строк: строки данных
TableFooterTableгруппа строк: итоги, итоговая строка
TableRowгруппа или Tableстрока; её ячейки расположены рядом
TableHeadTableRow в заголовкезаголовок столбца
TableCellTableRowячейка
TableCaptionTableсодержимое, которое приложение показывает о таблице

Каждая платформа передаёт роли своему скринридеру: роли таблицы, строки, ячейки и заголовка столбца в Linux (AT-SPI), вебе (ARIA), Android и бэкенде GPUI; сетки и группы в macOS и Windows; заголовки как заголовки в iOS.

#См. также

  • DataTable: таблица с любым числом строк и столбцов, с выделением, сортировкой и столбцами, которые можно изменять по ширине и перемещать.
  • Accessibility: значения accessibilityRole, table, row, cell, columnheader и rowgroup в их числе.