@itwin/itwinui-react
Version:
A react component library for iTwinUI
657 lines (656 loc) • 15.7 kB
JavaScript
import {
ActionColumn,
Table,
TablePaginator,
tableFilters,
EditableCell,
DefaultCell,
SelectionColumn,
ExpanderColumn,
} from '../core/Table/index.js';
import React from 'react';
import {
Anchor,
DropdownMenu,
IconButton,
Input,
MenuItem,
Text,
Tooltip,
} from '../index.js';
() => {
let columns = [
{
Header: 'Header 1',
accessor: 'header1',
},
{
Header: 'Header 2',
accessor: 'header2',
},
];
let data = [
{
header1: 'row1',
header2: 'row1',
},
{
header1: 'row2',
header2: 'row2',
},
];
return React.createElement(Table, {
columns: columns,
data: data,
emptyTableContent: 'No data.',
});
};
() => {
let columns = [
{
Header: 'Header 1',
accessor: 'header1',
columns: [
{
Header: 'Header 2',
accessor: 'header2',
},
],
},
];
};
() => {
let cellRenderer = React.useCallback(
(props) =>
React.createElement('div', null, props.cellProps.row.original.header1),
[],
);
let columns = [
{
Header: 'Header 1',
accessor: 'header1',
cellRenderer: cellRenderer,
},
{
Header: 'Header 2',
accessor: 'header2',
Cell: (props) =>
React.createElement('div', null, props.row.original.header2),
},
];
let data = [
{
header1: 'row1',
header2: 'row1',
},
{
header1: 'row2',
header2: 'row2',
},
];
return React.createElement(Table, {
columns: columns,
data: data,
emptyTableContent: 'No data.',
});
};
() => {
let Cell = React.useCallback(
(props) => React.createElement('div', null, props.row.original.header1),
[],
);
let columns = [
{
Header: 'Header 1',
accessor: 'header1',
Cell: Cell,
},
{
Header: 'Header 2',
accessor: 'header2',
},
];
let data = [
{
header1: 'row1',
header2: 'row1',
},
{
header1: 'row2',
header2: 'row2',
},
];
return React.createElement(Table, {
columns: columns,
data: data,
emptyTableContent: 'No data.',
});
};
() => {
let columns = React.useMemo(
() => [
{
id: 'name',
Header: 'Name',
Filter: tableFilters.TextFilter(),
accessor: 'name',
},
{
id: 'description',
Header: 'Description',
accessor: 'description',
maxWidth: 200,
},
],
[],
);
let data = React.useMemo(
() => [
{
name: 'Name1',
description: 'description',
},
{
name: 'Name2',
description: 'description',
},
{
name: 'Name3',
description: 'description',
},
],
[],
);
return React.createElement(Table, {
columns: columns,
emptyTableContent: 'No data.',
data: data,
});
};
() => {
let translatedLabels = React.useMemo(
() => ({
filter: 'Filter',
clear: 'Clear',
from: 'From',
to: 'To',
}),
[],
);
let formatter = React.useMemo(
() =>
new Intl.DateTimeFormat('en-us', {
month: 'short',
day: 'numeric',
year: 'numeric',
}),
[],
);
let formatDate = React.useCallback(
(date) => formatter.format(date),
[formatter],
);
let menuItems = React.useCallback(
(close) => [
React.createElement(
MenuItem,
{
key: 1,
onClick: () => close(),
},
'Edit',
),
React.createElement(
MenuItem,
{
key: 2,
onClick: () => close(),
},
'Delete',
),
],
[],
);
let isRowDisabled = React.useCallback(
(rowData) => 'Name2' === rowData.name,
[],
);
let isCheckboxDisabled = React.useCallback(
(rowData) => 'Name1' === rowData.name,
[],
);
let isExpanderDisabled = React.useCallback(
(rowData) => 'Name2' === rowData.name,
[],
);
let isCellDisabled = React.useCallback(
(rowData) => 'Name3' === rowData.name,
[],
);
let onCellEdit = React.useCallback((columnId, value, rowData) => {
console.log({
columnId,
value,
rowData,
});
}, []);
let cellRenderer = React.useCallback(
(props) =>
React.createElement(
React.Fragment,
null,
isRowDisabled(props.cellProps.row.original) ||
'Fetching...' === props.cellProps.value
? React.createElement(DefaultCell, {
...props,
status:
'Fetching...' === props.cellProps.value ? void 0 : 'positive',
isDisabled: (rowData) =>
isCellDisabled(rowData) || isRowDisabled(rowData),
})
: React.createElement(EditableCell, {
...props,
onCellEdit: onCellEdit,
}),
),
[isCellDisabled, isRowDisabled, onCellEdit],
);
let expandedSubComponent = React.useCallback(
(row) =>
React.createElement(
'div',
{
style: {
padding: 16,
},
},
React.createElement(
Text,
{
variant: 'leading',
},
'Extra information',
),
React.createElement(
'pre',
null,
React.createElement(
'code',
null,
JSON.stringify(
{
values: row.values,
},
null,
2,
),
),
),
),
[],
);
let onClickHandler = React.useCallback(
(props) => console.log(props.row.original.name),
[],
);
let columns = React.useMemo(
() => [
SelectionColumn({
isDisabled: isCheckboxDisabled,
}),
ExpanderColumn({
subComponent: expandedSubComponent,
isDisabled: isExpanderDisabled,
}),
{
id: 'index',
Header: '#',
accessor: 'index',
width: 80,
fieldType: 'number',
Filter: tableFilters.NumberRangeFilter(translatedLabels),
filter: 'between',
disableToggleVisibility: true,
sticky: 'left',
},
{
id: 'name',
Header: 'Name',
accessor: 'name',
fieldType: 'text',
cellRenderer,
Filter: tableFilters.TextFilter(translatedLabels),
disableReordering: true,
},
{
id: 'description',
Header: 'Description',
accessor: 'description',
fieldType: 'text',
Filter: tableFilters.TextFilter(translatedLabels),
maxWidth: 200,
},
{
id: 'ids',
Header: 'IDs (enter one of the IDs in the filter)',
accessor: 'ids',
Cell: (props) =>
React.createElement(
React.Fragment,
null,
props.row.original.ids.join(', '),
),
Filter: tableFilters.TextFilter(translatedLabels),
filter: 'includes',
minWidth: 200,
},
{
id: 'startDate',
Header: 'Start date',
accessor: 'startDate',
Cell: (props) =>
React.createElement(
React.Fragment,
null,
formatDate(props.row.original.startDate),
),
Filter: tableFilters.DateRangeFilter({
translatedLabels,
}),
filter: 'betweenDate',
},
{
id: 'endDate',
Header: 'End date',
accessor: (rowData) => new Date(rowData.endDate),
Cell: (props) =>
React.createElement(
React.Fragment,
null,
formatDate(new Date(props.row.original.endDate)),
),
Filter: tableFilters.DateRangeFilter({
translatedLabels,
}),
filter: 'betweenDate',
},
{
id: 'click-me',
Header: 'Click',
width: 100,
Cell: (props) =>
React.createElement(
Anchor,
{
as: 'button',
onClick: (e) => {
e.stopPropagation();
console.log(props.row.original.name);
onClickHandler(props);
},
},
'Click me!',
),
disableResizing: true,
},
{
...ActionColumn({
columnManager: true,
}),
Cell: (props) =>
React.createElement(
DropdownMenu,
{
menuItems: menuItems,
},
React.createElement(
IconButton,
{
styleType: 'borderless',
onClick: (e) => e.stopPropagation(),
disabled: isRowDisabled(props.row.original),
label: 'Column manager',
},
React.createElement('svg', null),
),
),
sticky: 'right',
},
],
[
isCheckboxDisabled,
expandedSubComponent,
isExpanderDisabled,
translatedLabels,
cellRenderer,
formatDate,
onClickHandler,
menuItems,
isRowDisabled,
],
);
let data = React.useMemo(
() => [
{
index: 1,
name: 'Name1',
description: 'Description1',
ids: ['1'],
startDate: new Date('May 1, 2021'),
endDate: '2021-05-31T21:00:00.000Z',
subRows: [
{
index: 11,
name: 'Name11',
description: 'Description11',
ids: ['11'],
startDate: new Date('May 11, 2021'),
endDate: '2021-05-31T21:00:00.000Z',
subRows: [
{
index: 111,
name: 'Name111',
description: 'Description111',
ids: ['111'],
startDate: new Date('May 11, 2021'),
endDate: '2021-05-31T21:00:00.000Z',
subRows: [],
},
],
},
],
},
{
index: 2,
name: 'Name2',
description: 'Description2',
ids: ['2', '3', '4'],
startDate: new Date('May 2, 2021'),
endDate: '2021-06-01T21:00:00.000Z',
subRows: [
{
index: 21,
name: 'Name21',
description: 'Description21',
ids: ['21'],
startDate: new Date('May 21, 2021'),
endDate: '2021-06-01T21:00:00.000Z',
subRows: [],
},
{
index: 22,
name: 'Name22',
description: 'Description22',
ids: ['22'],
startDate: new Date('May 22, 2021'),
endDate: '2021-06-01T21:00:00.000Z',
subRows: [],
},
],
},
{
index: 3,
name: 'Name3',
description: 'Description3',
ids: ['3', '4'],
startDate: new Date('May 3, 2021'),
endDate: '2021-06-02T21:00:00.000Z',
subRows: [],
},
],
[],
);
let onFilter = React.useCallback((filters, state, filteredData) => {
let rowInfo = '[';
filteredData?.forEach((row) => {
rowInfo += `${JSON.stringify(row.original)},`;
});
rowInfo = rowInfo.slice(0, rowInfo.length - 1);
rowInfo += ']';
console.log(
`Filter changed. Filters: ${JSON.stringify(
filters,
)}, State: ${JSON.stringify(state)}, Rows: ${rowInfo}`,
);
}, []);
let onSelect = React.useCallback(
(rows, state) =>
console.log(
`Selected rows: ${JSON.stringify(rows)}, Table state: ${JSON.stringify(
state,
)}`,
),
[],
);
let onRowClick = React.useCallback(
(event, row) => console.log(`Row clicked: ${JSON.stringify(row.original)}`),
[],
);
let onSort = React.useCallback(
(state) =>
console.log(`Sort changed. Table state: ${JSON.stringify(state)}`),
[],
);
let onExpand = React.useCallback(
(rows, state) =>
console.log(
`Expanded rows: ${JSON.stringify(rows)}. Table state: ${JSON.stringify(
state,
)}`,
),
[],
);
let onRowInViewport = React.useCallback((rowData) => {
console.log(`Row in view: ${JSON.stringify(rowData)}`);
}, []);
let rowProps = React.useCallback(
(row) => ({
onMouseEnter: () => {
console.log(`Hovered over ${row.original.name}`);
setHoveredRowIndex(row.index);
},
ref: (el) => {
if (el)
setRowRefMap((r) => {
r[row.index] = el;
return r;
});
},
}),
[],
);
let pageSizeList = React.useMemo(() => [10, 25, 50], []);
let paginator = React.useCallback(
(props) =>
React.createElement(TablePaginator, {
...props,
pageSizeList: pageSizeList,
localization: {
pageSizeLabel: (size) => `${size} per localized page`,
rangeLabel: (startIndex, endIndex, totalRows, isLoading) =>
isLoading
? `${startIndex}-${endIndex} localized`
: `${startIndex}-${endIndex} of localized ${totalRows}`,
previousPage: 'Previous localized page',
nextPage: 'Next localized page',
goToPageLabel: (page) => `Go to localized page ${page}`,
rowsPerPageLabel: 'Rows per localized page',
rowsSelectedLabel: (totalSelectedRowsCount) =>
`${totalSelectedRowsCount} localized ${
1 === totalSelectedRowsCount ? 'row' : 'rows'
} selected`,
},
}),
[pageSizeList],
);
let [globalFilter, setGlobalFilter] = React.useState('');
let tableInstance = React.useRef(void 0);
let [hoveredRowIndex, setHoveredRowIndex] = React.useState(0);
let [rowRefMap, setRowRefMap] = React.useState({});
return React.createElement(
'div',
null,
React.createElement(Input, {
placeholder: 'Search...',
value: globalFilter,
onInput: (e) => setGlobalFilter(e.target.value),
}),
React.createElement(Table, {
columns: columns,
data: data,
emptyTableContent: 'No data.',
onFilter: onFilter,
globalFilterValue: globalFilter,
onSelect: onSelect,
isSelectable: true,
isSortable: true,
isResizable: true,
enableColumnReordering: true,
onSort: onSort,
onRowClick: onRowClick,
onExpand: onExpand,
subComponent: expandedSubComponent,
onRowInViewport: onRowInViewport,
selectionMode: 'multi',
isRowDisabled: isRowDisabled,
initialState: {
filters: [
{
id: 'name',
value: '1',
},
],
selectedRowIds: {
0: true,
1: true,
4: true,
5: true,
},
},
stateReducer: React.useCallback(
(newState, action, prevState, instance) => {
tableInstance.current = instance;
return newState;
},
[],
),
rowProps: rowProps,
paginatorRenderer: paginator,
density: 'condensed',
autoResetFilters: false,
autoResetSortBy: false,
columnResizeMode: 'expand',
styleType: 'zebra-rows',
enableVirtualization: true,
scrollToRow: React.useCallback(
(rows, data) => rows.findIndex((row) => 1 === row.original.index),
[],
),
}),
React.createElement(Tooltip, {
reference: rowRefMap[hoveredRowIndex],
content: `Hovered over ${data[hoveredRowIndex].name}.`,
placement: 'bottom',
}),
);
};