Premium Widgets
Custom Table
Table en React
Listas con columnas ordenables, acciones de fila y componentes incrustados. Adecuado para pedidos, inventario y listas de selección.
Referencia para @arcrider/arcwidgets-react@0.1.0-alpha.5. <a href="/docs/react/intro/setup-react">Instalación</a> · <a href="/docs/react/intro/react-components">Todos los componentes</a>.
Ejemplo completo
import {
ArcWidgetBadge,
ArcWidgetTable,
type ArcWidgetTableRow,
} from '@arcrider/arcwidgets-react';
import { useState } from 'react';
const lang = document.documentElement.lang.startsWith('en') ? 'en' : document.documentElement.lang.startsWith('es') ? 'es' : 'de'; const requested = new URLSearchParams(location.search).get('data'); const pack = requested === 'empty' || requested === 'busy' ? requested : 'demo'; const t = (de: string, en: string, es: string) => lang === 'en' ? en : lang === 'es' ? es : de;
const statusTone = { open: { color: '#d97706', label: t('Offen', 'Open', 'Abierto') }, work: { color: '#0f766e', label: t('In Arbeit', 'In progress', 'En curso') }, done: { color: '#15803d', label: t('Erledigt', 'Done', 'Hecho') }, wait: { color: '#be123c', label: t('Wartet', 'Waiting', 'En espera') }, };
type Status = keyof typeof statusTone; type Order = { id: string; title: string; amount: number; status: Status; items?: Order[]; };
const demoOrders: Order[] = [ { id: 'a', title: t('Auftrag Nordhafen', 'North Harbor order', 'Pedido Puerto Norte'), amount: 240, status: 'work', items: [ { id: 'a-1', title: t('Vorbereitung', 'Preparation', 'Preparación'), amount: 80, status: 'done', }, { id: 'a-2', title: t('Umsetzung', 'Delivery', 'Entrega'), amount: 160, status: 'work', }, ], }, { id: 'b', title: t('Auftrag Westpark', 'Westpark order', 'Pedido Westpark'), amount: 80, status: 'open', }, { id: 'c', title: t('Auftrag Innenstadt', 'Downtown order', 'Pedido centro'), amount: 420, status: 'wait', }, { id: 'd', title: t('Auftrag Werkstatt', 'Workshop order', 'Pedido taller'), amount: 150, status: 'done', }, ];
const SITES = [ 'Nordhafen', 'Westpark', 'Innenstadt', 'Werkstatt', 'Messe', 'Logistik', 'Campus', 'Hafen Süd', ]; const STATUSES: Status[] = ['open', 'work', 'done', 'wait'];
const busyOrders: Order[] = Array.from({ length: 800 }, (_, index) => ({ id: busy-${index + 1}, title: ${t('Auftrag', 'Order', 'Pedido')} ${SITES[index % SITES.length]} ${String(index + 1).padStart(3, '0')}, amount: 50 + ((index * 47) % 9950), status: STATUSES[index % STATUSES.length], }));
const orders = pack === 'empty' ? [] : pack === 'busy' ? busyOrders : demoOrders;
export default function Example() { const [selected, setSelected] = useState( t('Keine Auswahl', 'Nothing selected', 'Sin selección'), ); const statusMark = (status: Status) => pack === 'busy' ? ( <span style={{ display: 'inline-block', borderRadius: 6, padding: '3px 8px', fontSize: 12, fontWeight: 600, color: statusTone[status].color, backgroundColor: '#f4f4f5', }} > {statusTone[status].label} </span> ) : ( <ArcWidgetBadge data={{ value: statusTone[status].label, singleColor: statusTone[status].color, borderRadius: '6px', paddingX: '8px', paddingY: '3px', }} /> ); const row = (order: Order): ArcWidgetTableRow => ({ id: order.id, clickable: true, columns: [ { value: order.title, width: 'fraction' }, { value: statusMark(order.status), width: '130px', }, { value: order.amount, width: '90px', sort: { value: order.amount }, }, ], items: (order.items ?? []).map(row), }); return ( <> <ArcWidgetTable id="orders" data={{ height: pack === 'busy' ? '520px' : '320px', styles: { borders: { outer: true, rows: true, columns: false, color: '#e4e4e7', }, }, rowHoverAction: { hoverActive: true, backgroundColor: '#fafafa' }, header: { columns: [ { title: t('Auftrag', 'Order', 'Pedido'), width: 'fraction', sort: { enabled: true, type: 'text' }, }, { title: t('Status', 'Status', 'Estado'), width: '130px' }, { title: t('Betrag', 'Amount', 'Importe'), width: '90px', sort: { enabled: true, type: 'number' }, }, ], }, table: orders.map(row), emptyTable: { title: t('Keine Aufträge', 'No orders', 'Sin pedidos'), value: ( <div style={{ padding: 24, textAlign: 'center' }}> <strong> {t('Keine Aufträge', 'No orders', 'Sin pedidos')} </strong> <p> {t( 'Leerer Zustand — über Daten auf Voll oder Demo wechseln.', 'Empty state — switch Data to Full or Demo.', 'Estado vacío — cambia Datos a Completo o Demo.', )} </p> </div> ), }, }} onCellClick={(_event, { row_index }) => { setSelected( row_index == null ? t('Keine Auswahl', 'Nothing selected', 'Sin selección') : ${t('Zeile', 'Row', 'Fila')} ${row_index + 1}, ); }} /> <p aria-live="polite">{selected}</p> </> ); }</code></pre>
Props del componente
id
ID opcional y estable de la instancia del widget. Sin especificarlo, React genera un ID.
data
Configuración de tipo ArcWidgetTableData. Pasa los cambios como objetos nuevos; gestiona los datos de negocio y la selección en el estado de React.
onAction
Fallback opcional (type: string, ...args: unknown[]) => unknown. El callback concreto tiene prioridad. Detalles: <a href="/docs/react/patterns/react-state-events">Estado y eventos</a>.
onCellClick
Evento del navegador y posición de la celda. La capacidad de clic debe estar activada en la fila o la celda.
onCellClick?: (event: Event, payload: ArcWidgetTableCellPayload) => void;
onCellHoverEnter
Posición de la celda sobre la que se entra; requiere hover_enterable.
onCellHoverEnter?: (payload: ArcWidgetTableCellPayload) => void;
onCellHoverLeave
Posición de la celda que se abandona; requiere hover_leaveable.
onCellHoverLeave?: (payload: ArcWidgetTableCellPayload) => void;
Configuración
Los siguientes campos pertenecen a data. Los tamaños se indican como strings, los números y valores de tiempo según su tipo respectivo.
height
Alto del widget, p. ej. "320px". Los valores en porcentaje necesitan un contenedor padre con altura fija.
Tipo: string.
minHeight
Límite inferior de altura.
Tipo: string.
minWidth
Límite inferior de ancho.
Tipo: string.
maxHeight
Límite superior de altura.
Tipo: string.
groupedBy
Clave de agrupación; omítela para tablas planas.
Tipo: string.
groupsCollapsed
Estado inicial de los grupos.
Tipo: boolean.
collapsible
Expandir o contraer; el formato concreto está en el tipo.
Tipo: { enabled?: boolean; expandColumn?: number; indentColumn?: number }.
theme
Configuración de tema específica del widget. En React puedes establecer los colores directamente en styles y en las distintas áreas.
Tipo: ArcWidgetTableTheme | ArcNestedWidgetDescriptor | string.
rowHoverAction
Representación al pasar el cursor sobre una fila.
Tipo: ArcWidgetTableHoverAction.
header
Encabezados de columna, anchos y opciones de ordenación.
Tipo: ArcWidgetTableHeader.
emptyTable
title es el texto de fallback simple. Si value está establecido, ese contenido sustituye por completo al fallback. Para mostrar título y descripción juntos, usa un elemento JSX en value, como en el ejemplo en vivo.
Representación cuando la lista de filas está vacía.
Tipo: ArcWidgetTableEmpty.
scrollBar
Representación de la barra de desplazamiento.
Tipo: ArcWidgetTableScrollBar.
table
Filas de datos con columns; las subfilas opcionales están en items.
Tipo: ArcWidgetTableRow[].
footer
Contenidos y visibilidad del pie de tabla.
Tipo: ArcWidgetTableFooter.
styles
Colores, espaciados y bordes comunes; los campos disponibles son específicos del widget.
Tipo: ArcWidgetTableStyles | string.
borders
Configuración de bordes histórica. Prefiere styles.borders si el widget la ofrece.
Tipo: ArcWidgetTableBorders.
borderRadius
Redondeo de las esquinas.
Tipo: string.
Comportamiento y límites
- Cada columna necesita un ancho. Usa al menos una vez
width: "fraction"; el encabezado y las celdas deben tener el mismo orden de columnas.
- Establece
clickable: true en la fila o la celda para que se dispare onCellClick. row_index y col_index son índices que admiten nulo; compruébalos antes de usarlos.
- Con contenidos de celda JSX, la ordenación necesita un
sort.value escalar. Para ordenar por fecha, usa milisegundos en lugar de strings de fecha localizados.
- Las filas anidadas se describen mediante
items; collapsible controla la sangría y el despliegue. Los ejemplos planos pueden mapear row_index directamente a la lista de datos.
Los campos ArcWidgetSlot admitidos permiten elementos JSX individuales, texto o descriptores de widget. Pasa texto externo como texto JSX; los strings HTML se interpretan como HTML. <a href="/docs/react/patterns/nested-widget-descriptors">Combinar contenidos</a>.
Tipos de datos
Estos tipos relacionados con el widget se exportan desde el paquete. También están disponibles tipos comunes como ArcWidgetSlot, ArcWidgetStyles y ArcReactWidgetProps. Las firmas de índice permiten extensiones; no garantizan que el widget evalúe campos arbitrarios.
export interface ArcWidgetTableSort {
enabled?: boolean;
type?: 'text' | 'number' | 'date' | string;
value?: string | number;
}
export interface ArcWidgetTableHeaderColumn { title?: ArcWidgetSlot; width?: string; sort?: ArcWidgetTableSort; styles?: ArcWidgetStyles | string; [key: string]: unknown; }
export interface ArcWidgetTableHeader { showHeader?: boolean; height?: string; fontColor?: string; backgroundColor?: string; fontSize?: string; styles?: ArcWidgetStyles | string; columns?: ArcWidgetTableHeaderColumn[]; sortIcons?: { color?: string; activeColor?: string; hoverColor?: string; }; [key: string]: unknown; }
export interface ArcWidgetTableCellPayload { row_index?: number | null; col_index?: number | null; flat_index?: number | null; group_value?: string | null; }
export interface ArcWidgetTableColumn { title?: ArcWidgetSlot; value?: ArcWidgetSlot; color?: string; backgroundColor?: string; width?: string; align?: 'left' | 'center' | 'right' | string; paddingX?: string; paddingY?: string; groupExpandAction?: boolean; groupValue?: ArcWidgetSlot; groupByValue?: ArcWidgetSlot; clickable?: boolean; hover_enterable?: boolean; hover_leaveable?: boolean; popup_button?: { content?: ArcWidgetSlot }; sort?: ArcWidgetTableSort; styles?: ArcWidgetStyles | string; [key: string]: unknown; }
export interface ArcWidgetTableRow { id?: string | number; rowColor?: string; rowHeight?: string; rowPaddingY?: string; groupRowColor?: string; groupRowSettings?: { height?: string; [key: string]: unknown }; columns?: ArcWidgetTableColumn[]; items?: ArcWidgetTableRow[]; clickable?: boolean; styles?: ArcWidgetStyles | string; [key: string]: unknown; }
export interface ArcWidgetTableEmpty { title?: ArcWidgetSlot; value?: ArcWidgetSlot; backgroundColor?: string; [key: string]: unknown; }
export interface ArcWidgetTableTheme { [key: string]: unknown; }
export interface ArcWidgetTableFooter { showFooter?: boolean; showActionButton?: boolean; backgroundColor?: string; actionButtonTitle?: ArcWidgetSlot; leftSideContent?: ArcWidgetSlot; rightSideContent?: ArcWidgetSlot; [key: string]: unknown; }
export interface ArcWidgetTableScrollBar { showScrollBar?: boolean; height?: string; backgroundColor?: string; handle?: { height?: string; borderRadius?: string; backgroundColor?: string; [key: string]: unknown; }; [key: string]: unknown; }
export type ArcWidgetTableBorderLine = boolean | { color?: string; width?: string; borderColor?: string; borderWidth?: string; borderSize?: string; enabled?: boolean; };
export interface ArcWidgetTableBorders { color?: string; width?: string; outer?: ArcWidgetTableBorderLine; columns?: ArcWidgetTableBorderLine; rows?: ArcWidgetTableBorderLine; }
export interface ArcWidgetTableStyles extends ArcWidgetStyles { borders?: ArcWidgetTableBorders; }
export interface ArcWidgetTableHoverAction { hoverActive?: boolean; backgroundColor?: string; fontColor?: string; [key: string]: unknown; }
export interface ArcWidgetTableData extends ArcWidgetBaseData { height?: string; minHeight?: string; minWidth?: string; maxHeight?: string; groupedBy?: string; groupsCollapsed?: boolean; collapsible?: { enabled?: boolean; expandColumn?: number; indentColumn?: number }; theme?: ArcWidgetTableTheme | ArcNestedWidgetDescriptor | string; rowHoverAction?: ArcWidgetTableHoverAction; header?: ArcWidgetTableHeader; emptyTable?: ArcWidgetTableEmpty; scrollBar?: ArcWidgetTableScrollBar; table?: ArcWidgetTableRow[]; footer?: ArcWidgetTableFooter; styles?: ArcWidgetTableStyles | string; borders?: ArcWidgetTableBorders; borderRadius?: string; }
export interface ArcWidgetTableProps extends ArcReactWidgetProps<ArcWidgetTableData> { onCellClick?: (event: Event, payload: ArcWidgetTableCellPayload) => void; onCellHoverEnter?: (payload: ArcWidgetTableCellPayload) => void; onCellHoverLeave?: (payload: ArcWidgetTableCellPayload) => void; }</code></pre>