baseui
Version:
A React Component library implementing the Base design language
283 lines (277 loc) • 10.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.StatefulDataTable = StatefulDataTable;
var React = _interopRequireWildcard(require("react"));
var _resizeObserverPolyfill = _interopRequireDefault(require("resize-observer-polyfill"));
var _button = require("../button");
var _search = _interopRequireDefault(require("../icon/search"));
var _input = require("../input");
var _popover = require("../popover");
var _styles = require("../styles");
var _tag = require("../tag");
var _filterMenu = _interopRequireDefault(require("./filter-menu"));
var _dataTable = require("./data-table");
var _statefulContainer = require("./stateful-container");
var _locale = require("../locale");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
/*
Copyright (c) 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.
*/
function useResizeObserver(ref, callback) {
React.useLayoutEffect(() => {
if (typeof document !== 'undefined') {
if (ref.current) {
const observer = new _resizeObserverPolyfill.default(callback);
observer.observe(ref.current);
return () => observer.disconnect();
}
}
}, [ref]);
}
// @ts-ignore
function QueryInput(props) {
const [css, theme] = (0, _styles.useStyletron)();
const locale = React.useContext(_locale.LocaleContext);
const [value, setValue] = React.useState(props.textQuery);
React.useEffect(() => {
const timeout = setTimeout(() => props.onChange(value), 250);
return () => clearTimeout(timeout);
}, [value]);
return /*#__PURE__*/React.createElement("div", {
className: css({
width: '375px',
marginBottom: theme.sizing.scale500
})
}, /*#__PURE__*/React.createElement(_input.Input, {
"aria-label": locale.datatable.searchAriaLabel,
overrides: {
Before: function Before() {
return /*#__PURE__*/React.createElement("div", {
className: css({
alignItems: 'center',
display: 'flex',
paddingLeft: theme.sizing.scale500
})
}, /*#__PURE__*/React.createElement(_search.default, {
size: "18px"
}));
}
},
size: _input.SIZE.compact,
onChange: event => setValue(event.target.value),
value: value,
clearable: true,
placeholder: props.textQueryPlaceholder || locale.datatable.textQueryPlaceholder
}));
}
// @ts-ignore
function FilterTag(props) {
const [, theme] = (0, _styles.useStyletron)();
const [isOpen, setIsOpen] = React.useState(false);
// @ts-ignore
const columnIndex = props.columns.findIndex(c => c.title === props.title);
const column = props.columns[columnIndex];
if (!column) {
return null;
}
// @ts-ignore
const data = props.rows.map(r => column.mapDataToValue(r.data));
const Filter = column.renderFilter;
return /*#__PURE__*/React.createElement(_popover.Popover, {
focusLock: true,
returnFocus: true,
key: props.title,
isOpen: isOpen,
onClick: () => setIsOpen(!isOpen),
onClickOutside: () => setIsOpen(false),
content: () => /*#__PURE__*/React.createElement(Filter, {
close: () => setIsOpen(false),
data: data,
filterParams: props.filter
// @ts-ignore
,
setFilter: filterParams => props.onFilterAdd(props.title, filterParams)
})
}, /*#__PURE__*/React.createElement(_tag.Tag, {
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'
}
},
Text: {
style: {
maxWidth: '160px'
}
}
}
}, props.title, ": ", props.filter.description));
}
function StatefulDataTable(props) {
const [css, theme] = (0, _styles.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;
const selectable = props.selectable === undefined ? false : props.selectable;
return /*#__PURE__*/React.createElement(_statefulContainer.StatefulContainer, {
batchActions: props.batchActions,
columns: props.columns,
initialFilters: props.initialFilters,
initialSelectedRowIds: props.initialSelectedRowIds,
initialSortIndex: props.initialSortIndex,
initialSortDirection: props.initialSortDirection,
initialTextQuery: props.initialTextQuery,
onFilterAdd: props.onFilterAdd,
onFilterRemove: props.onFilterRemove,
onIncludedRowsChange: props.onIncludedRowsChange,
onRowHighlightChange: props.onRowHighlightChange,
onSelectionChange: props.onSelectionChange,
onSort: props.onSort,
onTextQueryChange: props.onTextQueryChange,
resizableColumnWidths: props.resizableColumnWidths,
rows: props.rows,
rowActions: props.rowActions,
rowHighlightIndex: props.rowHighlightIndex
}, ({
filters,
onFilterAdd,
onFilterRemove,
onIncludedRowsChange,
onRowHighlightChange,
onSelectMany,
onSelectNone,
onSelectOne,
onSort,
onTextQueryChange,
resizableColumnWidths,
rowHighlightIndex,
selectedRowIds,
sortIndex,
sortDirection,
textQuery
}) => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
className: css({
height: `${headlineHeight}px`
})
}, /*#__PURE__*/React.createElement("div", {
ref: headlineRef
}, (selectable || !selectedRowIds.size) && /*#__PURE__*/React.createElement("div", {
className: css({
alignItems: 'end',
display: 'flex',
flexWrap: 'wrap',
paddingTop: theme.sizing.scale500
})
}, searchable && /*#__PURE__*/React.createElement(QueryInput, {
onChange: onTextQueryChange,
textQuery: textQuery,
textQueryPlaceholder: props.textQueryPlaceholder
}), filterable && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_filterMenu.default, {
columns: props.columns,
filters: filters,
rows: props.rows,
onSetFilter: onFilterAdd
}), Array.from(filters).map(([title, filter]) => /*#__PURE__*/React.createElement(FilterTag, {
key: title,
columns: props.columns,
filter: filter,
onFilterAdd: onFilterAdd,
onFilterRemove: onFilterRemove,
rows: props.rows,
title: title
})))), Boolean(selectedRowIds.size) && props.batchActions && /*#__PURE__*/React.createElement("div", {
className: css({
display: 'flex',
alignItems: 'center',
paddingTop: theme.sizing.scale300,
paddingBottom: theme.sizing.scale300
})
}, props.batchActions.map(action => {
// @ts-ignore
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 /*#__PURE__*/React.createElement(_button.Button, {
key: action.label,
overrides: {
BaseButton: {
props: {
'aria-label': action.label
}
}
},
onClick: onClick,
kind: _button.KIND.tertiary,
shape: _button.SHAPE.round
}, /*#__PURE__*/React.createElement(Icon, {
size: 16
}));
}
return /*#__PURE__*/React.createElement(_button.Button, {
key: action.label,
onClick: onClick,
kind: _button.KIND.secondary,
size: _button.SIZE.compact
}, action.label);
})))), /*#__PURE__*/React.createElement("div", {
style: {
width: '100%',
height: `calc(100% - ${headlineHeight}px)`
}
}, /*#__PURE__*/React.createElement(_dataTable.DataTable, {
selectable: selectable,
batchActions: props.batchActions,
columns: props.columns,
emptyMessage: props.emptyMessage,
filters: filters,
loading: props.loading,
loadingMessage: props.loadingMessage,
onIncludedRowsChange: onIncludedRowsChange,
onRowHighlightChange: onRowHighlightChange,
onSelectionChange: props.onSelectionChange,
onSelectMany: onSelectMany,
onSelectNone: onSelectNone,
onSelectOne: onSelectOne,
onSort: onSort,
resizableColumnWidths: resizableColumnWidths,
rowHighlightIndex: rowHighlightIndex,
rows: props.rows,
rowActions: props.rowActions,
rowHeight: props.rowHeight,
selectedRowIds: selectedRowIds,
sortDirection: sortDirection,
sortIndex: sortIndex,
textQuery: textQuery,
controlRef: props.controlRef
}))));
}