UNPKG

@itwin/itwinui-react

Version:

A react component library for iTwinUI

657 lines (656 loc) 15.7 kB
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', }), ); };