@are-visual/virtual-table
Version:
### VirtualTable
285 lines (276 loc) • 8.05 kB
JavaScript
import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
import { useScrollSynchronize, Colgroup, useTableSticky, isValidFixedLeft, isValidFixedRight, isValidFixed, createMiddleware } from '@are-visual/virtual-table';
import clsx from 'clsx';
import { createContext, useState, memo, useMemo, useContext, createElement, isValidElement, cloneElement, Fragment, Children } from 'react';
import { getScrollbarSize } from '@are-visual/virtual-table/middleware/utils/getScrollbarSize';
const SummaryContext = /*#__PURE__*/createContext(null);
const Footer = props => {
const {
className,
style,
zIndex,
bottom,
columns,
fixed,
children,
defaultColumnWidth
} = props;
const [scrollbarHeight] = useState(() => getScrollbarSize().height);
const wrapperRef = useScrollSynchronize('virtual-table-summary');
return jsx("div", {
className: clsx('virtual-table-summary-wrapper', fixed && 'virtual-table-summary-sticky-bottom virtual-table-summary-top-border', className),
style: {
...(fixed ? {
'--virtual-table-summary-z-index': zIndex,
'--virtual-table-summary-sticky-bottom': Number.isFinite(bottom) ? `${bottom}px` : bottom
} : {}),
...style,
paddingBottom: scrollbarHeight
},
ref: wrapperRef,
children: jsxs("table", {
className: "virtual-table-summary",
children: [jsx(Colgroup, {
columns: columns,
defaultColumnWidth: defaultColumnWidth
}), jsx("tfoot", {
className: "virtual-table-summary-tfoot",
children: children
})]
})
});
};
function Cell(props) {
const {
className,
style,
children,
align,
colSpan,
columnKey,
...restProps
} = props;
const {
size: stickySizes,
fixed: columnsFixed
} = useTableSticky();
const stickySize = columnKey == null ? 0 : stickySizes.get(columnKey);
const fixed = columnsFixed.find(x => x.key === columnKey)?.fixed;
const {
left: lastFixedLeftColumnKey,
right: firstFixedRightColumnKey
} = useMemo(() => {
const left = columnsFixed.reduce((result, x) => {
if (isValidFixedLeft(x.fixed)) {
return x.key;
}
return result;
}, undefined);
const right = columnsFixed.find(x => isValidFixedRight(x.fixed))?.key;
return {
left,
right
};
}, [columnsFixed]);
if (colSpan === 0) {
return null;
}
return jsx("td", {
...restProps,
colSpan: colSpan,
className: clsx('virtual-table-cell virtual-table-summary-cell', align != null && `virtual-table-align-${align}`, isValidFixed(fixed) && 'virtual-table-sticky-cell', lastFixedLeftColumnKey === columnKey && 'virtual-table-cell-fix-left-last', firstFixedRightColumnKey === columnKey && 'virtual-table-cell-fix-right-first', className),
style: {
...style,
left: isValidFixedLeft(fixed) ? stickySize : undefined,
right: isValidFixedRight(fixed) ? stickySize : undefined
},
children: children
});
}
var Cell$1 = /*#__PURE__*/memo(Cell);
function SummaryOutlet(props) {
const {
dataSource,
...restProps
} = props;
const descriptor = useContext(SummaryContext);
if (descriptor == null) {
throw new Error('SummaryOutlet is missing the columns context and cannot use children as a function.');
}
return jsx("tr", {
...restProps,
children: descriptor.map(item => {
const {
key
} = item;
if (item.type === 'blank') {
return jsx("td", {}, key);
}
const {
column
} = item;
const {
render,
...cellProps
} = column.summary ?? {};
return /*#__PURE__*/createElement(Cell$1, {
...cellProps,
key: key,
columnKey: key
}, render?.(dataSource));
})
});
}
const SummaryRow = _ref => {
let {
children,
...props
} = _ref;
const descriptor = useContext(SummaryContext);
if (typeof children === 'function') {
if (descriptor != null) {
return jsx("tr", {
...props,
children: descriptor.map(item => {
const {
key
} = item;
if (item.type === 'blank') {
return jsx("td", {}, key);
}
const {
column
} = item;
let childNode = children(column, key);
if (/*#__PURE__*/isValidElement(childNode) && childNode.type === Cell$1) {
childNode = /*#__PURE__*/cloneElement(childNode, {
columnKey: key
});
}
return jsx(Fragment, {
children: childNode
}, key);
})
});
}
throw new Error('SummaryRow is missing the columns context and cannot use children as a function.');
}
return jsx("tr", {
...props,
children: children
});
};
function Summary(_ref) {
let {
children
} = _ref;
return children;
}
Summary.Row = SummaryRow;
Summary.Cell = Cell$1;
Summary.Outlet = SummaryOutlet;
function useTableSummary(ctx, options) {
const {
className,
style,
zIndex,
bottom,
summary
} = options ?? {};
const {
dataSource,
instance
} = ctx;
let hasFixedTop = false;
let hasFixedBottom = false;
const summaryNode = summary?.(dataSource);
const topNode = [];
const bottomNode = [];
const handleRowElement = node => {
const fixed = node.props.fixed;
if (fixed === 'top') {
hasFixedTop = true;
topNode.push(node);
} else {
if (fixed === 'bottom' || fixed === true) {
hasFixedBottom = true;
}
bottomNode.push(node);
}
};
if (summary == null) {
return ctx;
}
if (/*#__PURE__*/isValidElement(summaryNode)) {
if (summaryNode.type === Fragment) {
const rawChildren = summaryNode.props.children;
// eslint-disable-next-line @eslint-react/no-children-for-each
Children.forEach(rawChildren, child => {
if (/*#__PURE__*/isValidElement(child) && child.type === Summary) {
handleRowElement(child);
} else {
if (process.env.NODE_ENV === 'development') {
console.warn(child, 'The summary function does not support components other than Fragment and Summary.');
}
}
});
} else if (summaryNode.type === Summary) {
handleRowElement(summaryNode);
} else {
if (process.env.NODE_ENV === 'development') {
console.error(summaryNode, 'The summary function does not support components other than Fragment and Summary.');
throw new Error('The summary function does not support components other than Fragment and Summary.');
}
}
} else {
return ctx;
}
return {
...ctx,
...(hasFixedTop ? {
renderHeader: (children, _ref) => {
let {
columnDescriptor
} = _ref;
return jsxs(Fragment$1, {
children: [children, jsx("tfoot", {
className: clsx('virtual-table-summary-tfoot', className),
style: style,
children: jsx(SummaryContext.Provider, {
value: columnDescriptor,
children: topNode
})
})]
});
}
} : {}),
...(hasFixedBottom ? {
renderContent(children, _ref2) {
let {
columnDescriptor
} = _ref2;
const {
defaultColumnWidth
} = instance.getCurrentProps();
return jsxs(Fragment$1, {
children: [children, jsx(Footer, {
className: className,
style: style,
zIndex: zIndex,
bottom: bottom,
fixed: hasFixedBottom,
columns: columnDescriptor,
defaultColumnWidth: defaultColumnWidth,
children: jsx(SummaryContext.Provider, {
value: columnDescriptor,
children: bottomNode
})
})]
});
}
} : {})
};
}
const tableSummary = createMiddleware(useTableSummary);
export { Summary, tableSummary };
//# sourceMappingURL=index.js.map