Cette page a été traduite automatiquement et peut contenir des erreurs. Lire l'original en anglais

Éléments

DataTable

DataTable affiche des lignes et des colonnes comme un tableur et défile dans les deux sens, quel que soit leur nombre. Seules les cellules visibles sont créées : un tableau d’un million de lignes et de dix mille colonnes défile aussi aisément qu’un petit. Les lignes, les colonnes ou les cellules se sélectionnent au pointeur et au clavier ; les colonnes ont des largeurs fixes, se redimensionnent en faisant glisser leur bord, se déplacent en faisant glisser leur titre, restent à gauche pendant que les autres défilent, et se trient. Les titres peuvent être placés sous des libellés de groupe, et une cellule ou un titre peut être dessiné par l’app.

el-data-table.tsx
el-data-table.tsxLive
import { mount, signal, Text, View } from "nsh";
import { DataTable, type DataTableColumn, type DataTableSort } from "nsh/base";
import { dataTableClasses, dataTableFitPadding, Log, Segmented, Split, ui, wide } from "./palette";

const NAMES = ["Ada", "Alan", "Grace", "Linus", "Margaret", "Dennis", "Barbara", "Ken"];
const CITIES = ["Oslo", "Lima", "Kyoto", "Cairo", "Perth", "Quito", "Turin", "Hanoi"];

type Person = { id: number; name: string; city: string; score: number };

const people: Person[] = Array.from({ length: 2000 }, (_, i) => ({
  id: i + 1,
  name: `${NAMES[i % NAMES.length]} ${i + 1}`,
  city: CITIES[(i * 7) % CITIES.length],
  score: (i * 37) % 1000,
}));

const columns: DataTableColumn[] = [
  { key: "id", title: "ID", width: 70, align: "end", fixed: true, sortable: true },
  { key: "name", title: "Name", width: 150, sortable: true },
  { key: "city", title: "City", width: 120, sortable: true },
  { key: "score", title: "Score", width: 90, align: "end", sortable: true },
];

// Sorting is the app's: the table reports the next sort (`onSortChange`),
// the app orders its rows and sets `sort`.
function App() {
  const mode = signal<"row" | "cell">("row");
  const sort = signal<DataTableSort | undefined>(undefined);
  const rows = signal<Person[]>(people);
  const events = signal<string[]>([]);
  const log = (line: string) => events.set([line, ...events()].slice(0, 4));

  const sortBy = (next: DataTableSort | undefined) => {
    sort.set(next);
    if (!next) return rows.set(people);
    const key = next.key as keyof Person;
    const sign = next.direction === "descending" ? -1 : 1;
    rows.set([...people].sort((a, b) => (a[key] < b[key] ? -sign : a[key] > b[key] ? sign : 0)));
  };

  return (
    <View style={{ flex: 1, backgroundColor: ui().page, padding: 20, paddingTop: 24, gap: 14 }}>
      <Text style={{ fontSize: 22, fontWeight: "700", color: ui().text }}>data table</Text>
      <Text style={{ color: ui().muted }}>Press a title to sort, drag its edge to resize or the title to move it</Text>

      <Split
        grow
        width={680}
        inspector={
          <>
            <Segmented label="selection" options={["row", "cell"] as const} value={mode()} onChange={(v) => mode.set(v)} />
            <Log title="events" lines={events()} minHeight={96} />
          </>
        }
      >
        <View style={{ height: wide() ? 360 : 320 }}>
          <DataTable
            columns={columns.map((column) => ({ ...column, fitPadding: dataTableFitPadding }))}
            classes={dataTableClasses}
            data={rows()}
            rowHeader={false}
            stripe
            cellSelectable={mode() === "cell"}
            sort={sort()}
            onSortChange={({ sort: next }) => {
              sortBy(next ?? undefined);
              log(`onSortChange: ${next ? `${next.key} ${next.direction}` : "none"}`);
            }}
            onSelectionChange={({ selection }) => log(`onSelectionChange: ${selection ? JSON.stringify(selection) : "none"}`)}
            onColumnResize={({ key, width }) => log(`onColumnResize: ${key} ${Math.round(width)}`)}
            style={{ flex: 1 }}
          />
        </View>
      </Split>
    </View>
  );
}

mount(App);

DataTable fournit la mise en page, l’alignement, la virtualisation et l’interaction. L’app donne à ses parties leur espacement interne, leurs couleurs, leurs bordures et le retour visuel de la sélection via classes et styles. En Rust, on en crée un avec nsh_base::data_table() ; en TSX, avec <DataTable> depuis nsh/base.

use nsh_base::{DataTableColumn, data_table};
use nsh_core::prelude::*;

fn column(key: &str, title: &str) -> DataTableColumn {
    let mut column = DataTableColumn::default();
    column.key = key.into();
    column.title = Some(title.into());
    column
}

fn table() -> impl IntoElement {
    data_table()
        .columns(vec![column("name", "Name"), column("city", "City")])
        .flex_1()
}

Le tableau remplit la boîte que l’app lui donne (flex-1, une hauteur) et défile à l’intérieur : verticalement à travers les lignes et horizontalement à travers les colonnes, avec des barres de défilement (scrollbar={false} les masque, bounces={false} supprime l’effet de rebond aux extrémités sur les plateformes qui en ont un).

#Lignes et colonnes

data désigne les lignes : des objets dont les champs sont nommés par les key des colonnes, ou des tableaux que les colonnes indexent par position. Les nombres, booléens et chaînes s’affichent comme du texte. En Rust, les lignes sont fournies champ par champ, chacun d’un seul type : DataTableRows::new(2).texts("symbol", ["AAPL", "MSFT"]).numbers("change", [1.2, -0.4]). Une colonne est un DataTableColumn :

ChampDescription
keySon identité, unique parmi les colonnes : le champ des lignes que ses cellules affichent, et le nom qu’utilisent les événements et la ref.
titleLe texte de son titre. Par défaut, son key.
widthSa largeur, en points. Par défaut 120.
minWidth, maxWidthLa largeur minimale et maximale qu’un glissement ou un ajustement peut lui donner. Par défaut 20 et 1200.
fitPaddingEspace supplémentaire pour l’espacement interne, les icônes ou les badges de l’app, ajouté au texte de titre ou de cellule le plus large lors de l’ajustement de la colonne.
align"start" (par défaut), "center" ou "end", pour les nombres. S’applique aux cellules comme au titre.
sortableSon titre a un bouton de tri qui demande un tri (voir Tri).
fixedElle reste à gauche pendant que les autres colonnes défilent dessous. Les colonnes fixes précèdent les autres, dans leur ordre.
resizable, movableIndiquent si un glissement de son bord la redimensionne et si un glissement de son titre la déplace. Par défaut resizableColumns et movableColumns du tableau.
selectableIndique si elle participe à la sélection. Une colonne de boutons ou de cases à cocher définit false. Par défaut true.
cellClassClasses des cellules de la colonne, après celles de la partie cell : espacements internes ou alignement d’une seule colonne.
headerClassClasses du titre de la colonne, après celles de la partie headerCell.
positiveClassClasses des cellules de la colonne qui contiennent une hausse : un nombre supérieur à zéro, ou un texte commençant par +.
negativeClassClasses des cellules de la colonne qui contiennent une baisse : un nombre inférieur à zéro, ou un texte commençant par -.

rowHeight est la hauteur d’une ligne du corps (par défaut 32) et headerHeight la hauteur d’une ligne de titres (par défaut la hauteur des lignes). rowHeader ajoute à gauche une colonne de numéros de ligne, qui sélectionne les lignes. stripe donne aux lignes impaires la partie rowOdd.

#Libellés de groupe

groups place des libellés au-dessus des colonnes, en commençant par le niveau le plus bas. Chaque niveau est une liste de { label, span } dont les étendues totalisent le nombre de colonnes, ou celui du niveau inférieur.

<DataTable
  columns={columns}
  data={rows}
  groups={[
    [{ label: "Person", span: 2 }, { label: "Result", span: 1 }],
  ]}
  class="flex-1"
/>

#Un nombre quelconque de lignes

Le tableau demande les lignes par position, et l’app les fournit. rowCount est le nombre total de lignes, data les lignes que l’app détient, et dataStart la position de la première d’entre elles. Les lignes hors de data restent vides jusqu’à ce que l’app les fournisse. onVisibleRowsChange signale les lignes visibles, { range: { start, end } }, à chaque pas de défilement, et c’est l’endroit où récupérer la page qui les entoure.

const ROWS = 1_000_000;
const page = signal({ start: 0, rows: load(0) });

<DataTable
  columns={columns}
  data={page().rows}
  dataStart={page().start}
  rowCount={ROWS}
  onVisibleRowsChange={({ range: { start, end } }) => {
    // Keep the rows in view inside the page held.
    const held = page();
    if (start < held.start || end > held.start + held.rows.length) {
      const first = Math.max(0, start - 200);
      page.set({ start: first, rows: load(first) });
    }
  }}
  class="flex-1"
/>

Pour une liste qui s’allonge par la fin, définissez hasMore : onLoadMore se déclenche une fois pour chaque nombre de lignes lorsque les lignes visibles arrivent à moins de loadMoreThreshold (par défaut 20) de la dernière. Tant que loading est vrai, il attend, et le slot loadingView s’affiche par-dessus les lignes. Le slot empty s’affiche lorsqu’il n’y a aucune ligne.

Au-delà de quelques millions de points de contenu, les barres de défilement couvrent une plage mise à l’échelle, de sorte qu’un million de lignes permet encore d’atteindre chaque ligne.

#Sélection

Trois commutateurs déterminent ce qu’un appui sélectionne, comme dans gpui-component :

PropUn appui sélectionneselection
rowSelectable (par défaut true)Une ligne : n’importe laquelle de ses cellules, ou son en-tête de ligne{ row }
columnSelectable (par défaut true)Une colonne : son titre{ column }
cellSelectable (par défaut false)Une cellule ; l’en-tête de ligne (affiché par défaut avec elle) sélectionne les lignes{ row, column }

Avec cellSelectable et l’en-tête de ligne masqué (rowHeader={false}), appuyer de nouveau sur la cellule sélectionnée sélectionne sa ligne. Un appui avec Maj ou la touche de commande de la plateforme enfoncée ne sélectionne une ligne que si selectOnModifierPress (par défaut true) ; une app qui gère sa propre sélection multiligne traite donc elle-même ces appuis : onRowPress signale chaque appui sur le corps avec sa ligne, la colonne sous le pointeur, les clics dans une ligne et les touches de modification enfoncées. Une colonne dont selectable vaut false ne se sélectionne pas elle-même et ne sélectionne pas ses cellules.

Les lignes sont numérotées à partir de 0 dans les données, et une colonne est identifiée par son index dans columns, quel que soit l’ordre dans lequel l’utilisateur les a déplacées. onSelectionChange signale ce que l’utilisateur a sélectionné (null si rien). La prop selection définit la sélection depuis l’app ; si elle n’est pas définie, le tableau la conserve. onDoublePress signale une ligne, une cellule ou un titre sur lesquels on a appuyé deux fois, et onContextMenu un appui secondaire ou long, avec le point où ouvrir le Menu de l’app. Les deux désignent la cellule sous le pointeur (son row et son column), le numéro d’une ligne (row seulement) ou un titre (column seulement). Jusqu’au prochain appui, la cellule pour laquelle un menu a été demandé a la partie cellActive, ou sa ligne la partie rowActive lorsque les cellules ne se sélectionnent pas.

Les lecteurs d’écran obtiennent une grille (nommée par accessibilityLabel) d’en-têtes de colonnes et de cellules, les éléments sélectionnés étant annoncés comme sélectionnés.

#Clavier

Appuyer sur le tableau, ou l’atteindre avec Tab (macOS, le web), lui donne le clavier jusqu’à un autre appui, un changement de focus ou blur() ; focus() le lui donne depuis l’app. Le tableau constitue un seul arrêt de Tab : à l’intérieur, Tab déplace la sélection, et Échap rend le clavier.

TouchesEffet
FlèchesDéplacent la sélection d’une ligne, d’une colonne ou d’une cellule, en la faisant défiler dans la vue.
Tab, Maj+TabPassent à la colonne suivante ou précédente.
Page précédente, Page suivanteSe déplacent d’une page de lignes.
Début, FinPassent à la première ou à la dernière.
ÉchapEfface la sélection, puis rend le clavier.
Raccourci de copiePlace le texte de la sélection dans le presse-papiers (copy()).

loopSelection (par défaut true) fait que les flèches bouclent aux extrémités.

#Tri

Une colonne sortable a un bouton de tri à la fin de son titre, un petit bouton fantôme atténué tant que la colonne n’est pas triée. Appuyer dessus signale le tri suivant ({ key, direction }) dans le cycle : non trié, croissant, décroissant, puis de nouveau non trié, avec onSortChange({ sort }) (null pour effacer). Le tableau ne réordonne pas les lignes : l’app trie ses données, ou demande à son serveur les lignes dans le nouvel ordre, et définit sort pour que le titre l’indique. Comme l’app maîtrise l’ordre, le tri fonctionne de la même façon sur un million de lignes que l’app ne détient jamais.

<DataTable
  columns={columns}
  data={rows()}
  sort={sort()}
  onSortChange={({ sort: next }) => {
    sort.set(next ?? undefined);
    rows.set(sorted(people, next));
  }}
  class="flex-1"
/>

#Redimensionner et déplacer les colonnes

Un glissement du bord de fin d’une colonne la redimensionne dans les limites de minWidth et maxWidth, et onColumnResize({ key, width }) signale chaque pas. Appuyer deux fois de suite sur le bord ajuste la colonne à son texte et son titre les plus larges. Un glissement d’un titre déplace la colonne, et une ligne indique où elle sera déposée ; onColumnMove signale { key, from, to, order }, order étant les key de toutes les colonnes dans l’ordre affiché. Les colonnes fixes restent parmi les colonnes fixes. resizableColumns et movableColumns désactivent les deux pour le tableau, et les resizable et movable d’une colonne l’emportent sur eux.

#Données en direct

Un tableau de cotations change plusieurs fois par seconde. L’app formate les lignes visibles et une marge autour (elle les connaît grâce à onVisibleRowsChange) et les transmet sous forme de data depuis dataStart ; une mise à jour ne coûte donc que ce qui est à l’écran, quel que soit le nombre de lignes. Les hausses et les baisses tirent leurs couleurs des positiveClass et negativeClass de la colonne, appliquées nativement aux cellules dont la valeur est supérieure ou inférieure à zéro (ou dont le texte commence par + ou -).

const tone = { positiveClass: "text-green-600", negativeClass: "text-red-600" };
const columns: DataTableColumn[] = [
  { key: "symbol", title: "Symbol", fixed: true },
  { key: "price", title: "Price", align: "end", sortable: true },
  { key: "change", title: "Chg%", align: "end", ...tone },
];

Les lignes et les colonnes sont des slots que le tableau crée une fois et conserve : le défilement leur attribue d’autres lignes et colonnes à afficher, de sorte qu’un défilement, aussi long soit-il, ne change que des textes et des positions.

#Dessiner les cellules et les titres

renderCell dessine les cellules propres à l’app lorsqu’une colonne n’est pas que du texte (un badge, un bouton). Il n’est appelé que pour les cellules visibles, avec un DataTableCell : row, column, key, text (ce que le tableau afficherait) et selected. L’app retrouve ses propres données par row. renderHeaderCell dessine un titre sur toute sa cellule, avec un DataTableHeaderCell : column, key, title, sort (la direction, ou aucune) et selected.

<DataTable
  columns={columns}
  data={rows()}
  renderCell={(cell) =>
    cell.key === "status" ? (
      <View class={cell.text === "open" ? "rounded bg-green-500/20 px-2" : "rounded bg-muted px-2"}>
        <Text class="text-xs">{cell.text}</Text>
      </View>
    ) : (
      <Text class="px-2 text-sm">{cell.text}</Text>
    )
  }
  class="flex-1"
/>

fontFamily et fontSize (par défaut 14) définissent la police des cellules, dans laquelle le tableau mesure aussi les textes pour ajuster les colonnes.

#La ref

ref fournit un DataTableRef. Une méthode à laquelle on donne une ligne, une colonne ou une clé de colonne que le tableau ne possède pas ne change rien et journalise un avertissement nommant la méthode et la valeur ; fitColumn est rejetée avec un TypeError pour une clé inconnue.

MéthodeDescription
scrollToRow(row, animated?)Fait défiler une ligne dans la vue.
scrollToColumn(key, animated?)Fait défiler une colonne dans la vue.
selection()Ce qui est sélectionné, null si rien.
select(selection)Sélectionne (null : rien) et amène la sélection dans la vue, sans onSelectionChange.
visibleRows(), visibleColumns()Les lignes et les colonnes défilantes visibles, sous forme de { start, end } (end exclues).
columnWidths()Les largeurs actuelles, dans l’ordre de columns.
setColumnWidth(key, width)Définit la largeur d’une colonne, dans ses limites.
fitColumn(key)Donne à une colonne la largeur que nécessitent son texte et son titre les plus larges, parmi les lignes visibles et jusqu’à mille de plus autour. Renvoie la largeur.
dump(start?, end?)Les textes des lignes données (par défaut toutes celles détenues) et des titres, tels qu’affichés : { headers, rows }, pour l’export.
copy()Place le texte de la sélection dans le presse-papiers : les cellules d’une ligne séparées par des tabulations, celles d’une colonne par des sauts de ligne, le texte d’une cellule.
focus(), blur()Donne le clavier au tableau ou le lui retire.
menuTarget(), clearMenuTarget()L’endroit pour lequel le dernier menu contextuel a été demandé ({ row?, column? }, marqué par cellActive / rowActive), et la suppression de ce marquage lorsque le menu de l’app se ferme.

#Styliser les parties

class et style stylisent la boîte du tableau. classes accepte des classes Tailwind par partie et styles des styles en ligne par partie ; les parties fournissent la structure et l’alignement du tableau ; leurs classes fournissent l’apparence, et les styles l’emportent sur les classes.

<DataTable
  columns={columns}
  data={rows()}
  stripe
  class="flex-1 rounded-lg border border-border"
  classes={{
    header: "bg-secondary",
    headerCell: "pl-2 pr-1",
    headerContent: "gap-1",
    cell: "px-2",
    resizeHandle: "bg-border group-hover:bg-primary",
    sortAscending: "text-muted-foreground opacity-60 selected:text-foreground selected:opacity-100",
    sortDescending: "text-muted-foreground opacity-60 selected:text-foreground selected:opacity-100",
    rowSelected: "bg-primary/10",
    rowHover: "bg-muted/50",
    fixedEdge: "bg-border",
  }}
/>
PartieCe que c’est
rootLa boîte du tableau : sa bordure, son rayon et son arrière-plan
headerL’en-tête sur toute la largeur du tableau, avec ses lignes de libellés de groupe et de titres
groupCellUn libellé de groupe au-dessus des colonnes qu’il couvre
headerCellLa cellule de titre de chaque colonne
headerContentLa ligne de mise en page du libellé et du bouton de tri ; définissez ici leur espacement
headerCellDraggingLe titre en cours de glissement, après headerCell
headerCellSortedLe titre de la colonne selon laquelle le tableau est trié, après headerCell
headerCellSelectedLe titre de la colonne sélectionnée, après headerCell
sortIndicatorLe bouton de tri d’une colonne triable
sortAscending, sortDescendingSes deux chevrons ; selected: s’applique à la direction du tri
resizeHandleLa ligne au bord de fin d’une colonne qu’un glissement redimensionne
moveIndicatorLa ligne où une colonne glissée sera déposée
rowChaque ligne du corps
rowOddLes lignes impaires, après row (stripe)
rowHoverLa ligne survolée par le pointeur, après row
rowSelectedLa ligne sélectionnée, après row
rowActiveLa ligne pour laquelle un menu contextuel a été demandé lorsque les cellules ne se sélectionnent pas, jusqu’au prochain appui, après row
cellChaque cellule du corps
cellSelectedLa cellule sélectionnée, après cell
cellActiveLa cellule pour laquelle un menu contextuel a été demandé, jusqu’au prochain appui, après cell
cellColumnSelectedLes cellules de la colonne sélectionnée, après cell
rowHeaderLes cellules d’en-tête de ligne, les numéros de ligne
rowHeaderCornerLe coin au-dessus des en-têtes de ligne
fixedEdgeLa ligne au bord de fin des colonnes fixes, au-dessus des colonnes qui défilent dessous
emptyLa boîte du slot empty

#Props

PropRustTypeDéfautDescription
columns.columns(..)DataTableColumn[][]Les colonnes, de gauche à droite. Les colonnes fixes viennent en premier.
data.data(..)Row[][]Les lignes : objets indexés par la colonne key, ou tableaux indexés par position.
rowCount.row_count(..)numberles lignes fourniesLe nombre total de lignes.
dataStart.data_start(..)number0Le numéro de ligne de la première ligne de data.
rowClasses.row_classes(..)string[][]Classes des lignes données, selon leur position dans data : l’apparence propre à une ligne, sans appel à JS par ligne.
rowHeight.row_height(..)number32La hauteur d’une ligne du corps, en points.
headerHeight.header_height(..)numberla hauteur de ligneLa hauteur d’une ligne de titre.
groups.groups(..)DataTableColumnGroup[][][]Libellés au-dessus des colonnes, du niveau le plus bas au plus haut.
sort.sort(..)DataTableSortLe critère de tri des données, affiché sur le titre.
rowSelectable.row_selectable(..)booleantrueLes appuis et les touches sélectionnent des lignes.
columnSelectable.column_selectable(..)booleantrueL’appui sur un titre sélectionne sa colonne, et les touches horizontales passent d’une colonne à l’autre.
cellSelectable.cell_selectable(..)booleanfalseLes appuis et les touches sélectionnent des cellules.
selectOnModifierPress.select_on_modifier_press(..)booleantrueUn appui avec Shift ou la touche commande maintenue sélectionne une ligne.
selection.selection(..)DataTableSelectionCe qui est sélectionné, lorsque l’application le définit.
loopSelection.loop_selection(..)booleantrueLes touches fléchées bouclent aux extrémités.
accessibilityLabel.accessibility_label(..)stringaucunLe nom que les lecteurs d’écran donnent au tableau.
rowHeader.row_header(..)booleanaffiché avec cellSelectableUne colonne de numéros de ligne à gauche.
stripe.stripe(..)booleanfalseLes lignes impaires reçoivent la partie rowOdd.
resizableColumns.resizable_columns(..)booleantrueFaire glisser le bord d’une colonne la redimensionne.
movableColumns.movable_columns(..)booleantrueFaire glisser un titre déplace sa colonne.
loading.loading(..)booleanfalseLe tableau est en cours de chargement : onLoadMore attend et loadingView s’affiche.
hasMore.has_more(..)booleanfalseIl reste des lignes à charger.
loadMoreThreshold.load_more_threshold(..)number20À combien de lignes de la dernière onLoadMore se déclenche.
fontFamily.font_family(..)stringhéritéeLa police des cellules.
fontSize.font_size(..)number14La taille de police des cellules, en points.
scrollbar.scrollbar(..)booleantrueLes barres de défilement.
verticalScrollbar, horizontalScrollbar.vertical_scrollbar(..), .horizontal_scrollbar(..)booleanscrollbarLa barre de défilement d’un axe (la barre horizontale est celle des ordinateurs de bureau, sous le tableau).
bounces.bounces(..)booleantrueIndique si le défilement rebondit aux extrémités, là où la plateforme le permet.
renderCell.render_cell(..)(cell: DataTableCell) => JSX.ElementDessine les cellules visibles.
renderHeaderCell.render_header_cell(..)(cell: DataTableHeaderCell) => JSX.ElementDessine les titres.
empty.empty(..)JSX.ElementCe qui s’affiche quand il n’y a aucune ligne.
loadingView.loading_view(..)JSX.ElementCe qui s’affiche par-dessus les lignes tant que loading.
classes.classes(..)DataTableClasses{}Classes Tailwind par partie.
styles.styles(..)DataTableStyles{}Styles en ligne par partie, prioritaires sur les classes.
class, styleméthodes de stylestring, StyleProp<ViewStyle>La boîte du tableau.

#Événements

ÉvénementRustDescription
onSelectionChange.on_selection_change(|selection: &Option<DataTableSelection>| ..)L’utilisateur a modifié la sélection : { selection }, un { row?, column? } ou null.
onRowPress.on_row_press(|event: &DataTablePress| ..)Une ligne ou une cellule a été pressée : { row, column?, clicks, shift, control, alt, platform }.
onDoublePress.on_double_press(|target: &DataTableTarget| ..)Une ligne, une cellule ou un titre a été pressé deux fois : { target }, un { row?, column? }.
onContextMenu.on_context_menu(|event: &DataTableContextMenu| ..)Un menu contextuel a été demandé : { row?, column?, x, y }, le point dans la vue racine.
onSortChange.on_sort_change(|sort: &Option<DataTableSort>| ..)Un bouton de tri a été pressé : { sort }, le tri suivant { key, direction } ou null.
onColumnResize.on_column_resize(|key: &SharedString, width: &Points| ..)Une colonne a été redimensionnée ({ key, width }), à chaque étape d’un glissement et une fois de plus quand un ajustement la définit.
onColumnMove.on_column_move(|event: &DataTableColumnMove| ..)Une colonne a été déplacée : { key, from, to, order }.
onVisibleRowsChange.on_visible_rows_change(|range: &DataTableRange| ..)Les lignes visibles ont changé : { range }, un { start, end }. Récupérez les lignes à partir d’ici.
onVisibleColumnsChange.on_visible_columns_change(|range: &DataTableRange| ..)Les colonnes défilantes visibles ont changé : { range }.
onLoadMore.on_load_more(|| ..)Les lignes visibles sont arrivées à moins de loadMoreThreshold de la dernière alors que hasMore et non loading.

#Voir aussi

  • Editor et DiffView : les autres composants de base riches en données.
  • Menu : le menu à ouvrir depuis onContextMenu.
  • nsh/base : les autres composants de base.