UNPKG

es-grid-template

Version:

es-grid-template

160 lines 5.76 kB
import cx from 'classnames'; import React from 'react'; import { internals } from "../../internals"; import { collectNodes, mergeCellProps } from "../../utils"; import { always, flatMap } from "../../utils/others"; import { ExpansionCell, icons, InlineFlexCell } from "../../common-views"; const rowDetailSymbol = Symbol('row-detail'); const fallbackRenderDetail = () => /*#__PURE__*/React.createElement("div", { style: { margin: '8px 24px' } }, /*#__PURE__*/React.createElement("b", { style: { color: 'indianred' } }, "\u8BBE\u7F6E ", /*#__PURE__*/React.createElement("code", null, "rowDetail.renderDetail"), " \u6765\u81EA\u5B9A\u4E49\u8BE6\u60C5\u5185\u5BB9")); export function rowDetail(opts = {}) { return function rowDetailStep(pipeline) { const stateKey = 'rowDetail'; const primaryKey = pipeline.ensurePrimaryKey('rowDetail'); if (typeof primaryKey !== 'string') { throw new Error('rowDetail 仅支持字符串作为 primaryKey'); } const rowDetailMetaKey = opts.rowDetailMetaKey ?? rowDetailSymbol; const indents = pipeline.ctx.indents; const textOffset = indents.iconIndent + indents.iconWidth + indents.iconGap; const clickArea = opts.clickArea ?? 'cell'; const getDetailKey = opts.getDetailKey ?? (row => row[primaryKey] + '_detail'); const renderDetail = opts.renderDetail ?? fallbackRenderDetail; const hasDetail = opts.hasDetail ?? always(true); const openKeys = opts.openKeys ?? pipeline.getStateAtKey(stateKey) ?? (opts.defaultOpenAll ? pipeline.getDataSource().filter(hasDetail).map(row => row[primaryKey]) : opts.defaultOpenKeys) ?? []; const onChangeOpenKeys = (nextKeys, key, action) => { opts.onChangeOpenKeys?.(nextKeys, key, action); pipeline.setStateAtKey(stateKey, nextKeys, { key, action }); }; const openKeySet = new Set(openKeys); const toggle = rowKey => { const expanded = openKeySet.has(rowKey); if (expanded) { onChangeOpenKeys(openKeys.filter(key => key !== rowKey), rowKey, 'collapse'); } else { onChangeOpenKeys([...openKeys, rowKey], rowKey, 'expand'); } }; return pipeline.dataSource(flatMap(pipeline.getDataSource(), (row, rowIndex) => { if (openKeySet.has(row[primaryKey])) { return [row, { [rowDetailMetaKey]: true, ...row, [primaryKey]: getDetailKey(row, rowIndex) }]; } else { return [row]; } })).columns(processColumns(pipeline.getColumns())).appendRowPropsGetter(row => { if (row[rowDetailMetaKey]) { return { className: 'no-hover' }; } else { return {}; } }); function processColumns(columns) { if (columns.length === 0) { return columns; } const columnFlatCount = collectNodes(columns, 'leaf-only').length; const [firstCol, ...others] = columns; const render = (value, row, rowIndex) => { if (row[rowDetailMetaKey]) { return renderDetail(row, rowIndex); } const content = internals.safeRender(firstCol, row, rowIndex); if (!hasDetail(row, rowIndex)) { return /*#__PURE__*/React.createElement(InlineFlexCell, { style: { marginLeft: textOffset } }, content); } const rowKey = row[primaryKey]; const expanded = openKeySet.has(rowKey); const onClick = e => { if (opts.stopClickEventPropagation) { e.stopPropagation(); } toggle(rowKey); }; const expandCls = expanded ? 'expanded' : 'collapsed'; return /*#__PURE__*/React.createElement(ExpansionCell, { className: cx('expansion-cell', expandCls), style: { cursor: clickArea === 'content' ? 'pointer' : undefined }, onClick: clickArea === 'content' ? onClick : undefined }, /*#__PURE__*/React.createElement(icons.CaretRight, { style: { cursor: clickArea === 'icon' ? 'pointer' : undefined, marginLeft: indents.iconIndent, marginRight: indents.iconGap }, className: cx('expansion-icon', expandCls), onClick: clickArea === 'icon' ? onClick : undefined }), content); }; const getCellProps = (value, row, rowIndex) => { if (row[rowDetailMetaKey]) { return { style: { '--cell-padding': '0', overflow: 'hidden', ...opts.detailCellStyle } }; } const prevProps = firstCol.getCellProps?.(value, row, rowIndex); if (!hasDetail(row, rowIndex)) { return prevProps; } return mergeCellProps(prevProps, { onClick(e) { if (opts.stopClickEventPropagation) { e.stopPropagation(); } toggle(row[primaryKey]); }, style: { cursor: 'pointer' } }); }; return [{ ...firstCol, title: /*#__PURE__*/React.createElement("div", { style: { display: 'inline-block', marginLeft: textOffset } }, internals.safeRenderHeader(firstCol)), render, getCellProps: clickArea === 'cell' ? getCellProps : firstCol.getCellProps, getSpanRect(value, row, rowIndex) { if (row[rowDetailMetaKey]) { // detail 总是成一行 return { top: rowIndex, bottom: rowIndex + 1, left: 0, right: columnFlatCount }; } } }, ...others]; } }; }