/* Copyright (c) 2018-2020 Uber Technologies, Inc. This source code is licensed under the MIT license found in the LICENSE file in the root directory of this source tree. */ // @flow import * as React from 'react'; import ResizeObserver from 'resize-observer-polyfill'; import { Button, SHAPE as BUTTON_SHAPES, SIZE as BUTTON_SIZES, KIND as BUTTON_KINDS, } from '../button/index.js'; import Search from '../icon/search.js'; import {Input, SIZE as INPUT_SIZES} from '../input/index.js'; import {Popover} from '../popover/index.js'; import {useStyletron} from '../styles/index.js'; import {Tag} from '../tag/index.js'; import FilterMenu from './filter-menu.js'; import {Unstable_DataTable} from './data-table.js'; import {Unstable_StatefulContainer} from './stateful-container.js'; import type {StatefulDataTablePropsT} from './types.js'; function useResizeObserver( ref: {current: HTMLElement | null}, callback: (ResizeObserverEntry[], ResizeObserver) => mixed, ) { React.useLayoutEffect(() => { if (__BROWSER__) { if (ref.current) { //$FlowFixMe const observer = new ResizeObserver(callback); observer.observe(ref.current); return () => observer.disconnect(); } } }, [ref]); } function QueryInput(props) { const [css, theme] = useStyletron(); const [value, setValue] = React.useState(''); React.useEffect(() => { const timeout = setTimeout(() => props.onChange(value), 250); return () => clearTimeout(timeout); }, [value]); return (
); }, }} size={INPUT_SIZES.compact} onChange={event => setValue(event.target.value)} value={value} clearable /> ); } function FilterTag(props) { const [, theme] = useStyletron(); const [isOpen, setIsOpen] = React.useState(false); const columnIndex = props.columns.findIndex(c => c.title === props.title); const column = props.columns[columnIndex]; if (!column) { return null; } const data = props.rows.map(r => column.mapDataToValue(r.data)); const Filter = column.renderFilter; return ( setIsOpen(false)} content={() => ( setIsOpen(false)} data={data} filterParams={props.filter} setFilter={filterParams => props.onFilterAdd(props.title, filterParams) } /> )} >
setIsOpen(!isOpen)} onActionClick={() => props.onFilterRemove(props.title)} overrides={{ Root: { style: { borderTopLeftRadius: '36px', borderTopRightRadius: '36px', borderBottomLeftRadius: '36px', borderBottomRightRadius: '36px', height: '36px', marginTop: null, marginBottom: theme.sizing.scale500, }, }, Action: { style: { borderTopRightRadius: '36px', borderBottomRightRadius: '36px', height: '22px', }, }, }} > {props.title}: {props.filter.description}
); } export function Unstable_StatefulDataTable(props: StatefulDataTablePropsT) { const [css, theme] = useStyletron(); const headlineRef = React.useRef(null); const [headlineHeight, setHeadlineHeight] = React.useState(64); useResizeObserver(headlineRef, entries => { setHeadlineHeight(entries[0].contentRect.height); }); const filterable = props.filterable === undefined ? true : props.filterable; const searchable = props.searchable === undefined ? true : props.searchable; return ( {({ filters, onFilterAdd, onFilterRemove, onIncludedRowsChange, onRowHighlightChange, onSelectMany, onSelectNone, onSelectOne, onSort, onTextQueryChange, rowHighlightIndex, selectedRowIds, sortIndex, sortDirection, textQuery, }) => (
{!selectedRowIds.size && (
{searchable && } {filterable && ( {Array.from(filters).map(([title, filter]) => ( ))} )}
)} {Boolean(selectedRowIds.size) && props.batchActions && (
{props.batchActions.map(action => { function onClick(event) { action.onClick({ clearSelection: onSelectNone, event, selection: props.rows.filter(r => selectedRowIds.has(r.id), ), }); } if (action.renderIcon) { const Icon = action.renderIcon; return ( ); } return ( ); })}
)}
)}
); } declare var __DEV__: boolean; declare var __NODE__: boolean; declare var __BROWSER__: boolean;