UNPKG

vue-virtualized-table-booway

Version:

The second version of implementation of `vue-virtual-table` component, it was inspired from [rc-table](https://github.com/react-component/table) and [ant-table](https://ant.design/components/table), API design is 60%+ consistent. Or you could think I tran

190 lines (166 loc) 4.44 kB
/* eslint-disable no-undef */ import { isArray, isValidArray, isObject } from './type' /** * findAllChildrenKeys * @param {Tree[]} data * @param {GetRowKey} getRowKey * @param {string} childrenColumnName * @returns {string[]} */ export function findValidChildrenKeys(data, getRowKey, childrenColumnName) { return data.reduce((keys, item, index) => { const key = getRowKey(item, index) const children = item[childrenColumnName] if (isValidArray(children)) { return [ key, ...findValidChildrenKeys(children, getRowKey, childrenColumnName), ...keys ] } return keys }, []) } /** * flatten tree data 展开树形数据 * * @typedef {import("../types/index").RowModel} RowModel * @typedef {(item: object, index: number)=>string} GetRowKey * @typedef Tree * @property {string|number} [key] * @property {Tree[]} [children] * * @param {Tree[]} tree * @param {string} childrenColumnName * @param {number} [depth] * @param {RowModel[]} [flatten] * @param {RowModel} [parent] */ export function flattenData( tree, childrenColumnName, depth = 0, flatten = [], parent = null ) { for (let index = 0; index < tree.length; index++) { const item = tree[index] const children = item[childrenColumnName] const hasNestChildren = isValidArray(children) // record the depth number if (!item.__depth || item.__depth !== depth) { item.__depth = depth } // record the index number if (!item.__index || item.__index !== index) { item.__index = index } // record the parent ref if (parent && (!item.__parent || item.__parent !== parent)) { item.__parent = parent } flatten.push(item) if (hasNestChildren) { flattenData(children, childrenColumnName, depth + 1, flatten, item) } } return flatten } /** * flattenMap 记录当前 rowKey 的 tree-paths * * @param {Tree[]} tree * @param {(item: RowModel, index: number)=> string} getRowKey * @param {string} childrenColumnName * @param {string[]} prefix * @param {Object<string, string[]>} preset */ export function flattenMap( tree = [], getRowKey, childrenColumnName, prefix = [], preset = {} ) { return tree.reduce((prev, item, index) => { const children = item[childrenColumnName] const hasNestChildren = isValidArray(children) if (hasNestChildren) { const key = getRowKey(item, index) const path = prefix.length ? [...prefix, key] : [key] prev[key] = path return flattenMap(children, getRowKey, childrenColumnName, path, prev) } return prev }, preset) } /** * genExpandedKeyPaths * @param {RowModel} record * @param {(row: object, index: number)=>string} getRowKey * @param {string} childrenColumnName * @param {*} rowKey */ export function genExpandedKeyPaths(record, getRowKey, childrenColumnName) { let parent = record.__parent let results = isValidArray(record[childrenColumnName]) ? [getRowKey(item)] : [] while (isObject(parent)) { results = [getRowKey(parent), ...results] parent = parent.__parent } return results } /** * insertDataFromStart * @param {[]} data * @param {number} startIndex * @param {[]} middle */ export function insertDataFromStart( data, // any[] startIndex = -1, // number middle = [] // any[] ) { if (!isArray(data) || !isArray(middle)) throw new TypeError() const left = data.slice(0, startIndex + 1) const right = data.slice(startIndex + 1) return [...left, ...middle, ...right] } /** * renderExpandIcon * @typedef {{ * prefixCls: string, record: object, onExpand: function, expanded: boolean, expandable: boolean, * }} ExpandConfig * @param {import("@/components/virtualized-table/utils/vue").CreateElement} h * @param {ExpandConfig} expandConfig */ export const renderExpandIcon = ( h, { prefixCls, record, onExpand, expanded, expandable } ) => { const iconPrefix = `${prefixCls}-row-expand-icon` return ( <button type="button" onClick={(e) => { onExpand(record, e) e.stopPropagation() }} class={[ iconPrefix, { [`${iconPrefix}-spaced`]: !expandable, [`${iconPrefix}-expanded`]: expandable && expanded, [`${iconPrefix}-collapsed`]: expandable && !expanded } ]} aria-label={expanded ? `collapse` : `expand`} /> ) }