From 996f9c8d4c3d1748c706e919fceb8c0e8293e46a Mon Sep 17 00:00:00 2001 From: redhoodsu Date: Fri, 15 Nov 2024 14:39:44 +0800 Subject: [PATCH] release(data-grid): v1.2.0 --- index.json | 2 +- src/data-grid/CHANGELOG.md | 5 +++ src/data-grid/README.md | 6 ++- src/data-grid/index.ts | 88 +++++++++++++++++++++++++++++++++++--- src/data-grid/package.json | 2 +- src/data-grid/react.tsx | 80 ++++++++++++++++------------------ src/data-grid/story.js | 3 +- 7 files changed, 133 insertions(+), 53 deletions(-) diff --git a/index.json b/index.json index 0e13bf2..50f23c3 100644 --- a/index.json +++ b/index.json @@ -74,7 +74,7 @@ "data-grid": { "react": true, "icon": true, - "version": "1.1.0", + "version": "1.2.0", "style": true, "test": true, "install": false, diff --git a/src/data-grid/CHANGELOG.md b/src/data-grid/CHANGELOG.md index 755e53e..7bc9ab7 100644 --- a/src/data-grid/CHANGELOG.md +++ b/src/data-grid/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.2.0 (15 Nov 2024) + +* feat: setData api +* perf: append a lot + ## 1.1.0 (3 Nov 2024) * feat: add auto theme diff --git a/src/data-grid/README.md b/src/data-grid/README.md index 7a07337..8641ea7 100644 --- a/src/data-grid/README.md +++ b/src/data-grid/README.md @@ -59,7 +59,7 @@ dataGrid.append({ ## Api -### append(data: PlainObj, options?: IDataGridNodeOptions): DataGridNode +### append(data: NodeData, options?: IDataGridNodeOptions): DataGridNode Append row data. @@ -71,6 +71,10 @@ Clear all data. Remove row data. +### setData(data: NodeData | [], uniqueId?: string): void + +Set data. + ## Types ### IColumn diff --git a/src/data-grid/index.ts b/src/data-grid/index.ts index dcd57e6..8ef2ce6 100644 --- a/src/data-grid/index.ts +++ b/src/data-grid/index.ts @@ -2,6 +2,7 @@ import $ from 'licia/$' import stripIndent from 'licia/stripIndent' import Component, { IComponentOptions } from '../share/Component' import each from 'licia/each' +import map from 'licia/map' import escape from 'licia/escape' import types from 'licia/types' import h from 'licia/h' @@ -15,6 +16,7 @@ import startWith from 'licia/startWith' import isNull from 'licia/isNull' import isFn from 'licia/isFn' import isRegExp from 'licia/isRegExp' +import isArr from 'licia/isArr' import isStr from 'licia/isStr' import trim from 'licia/trim' import contain from 'licia/contain' @@ -55,8 +57,12 @@ export interface IOptions extends IComponentOptions { minHeight?: number /** Data filter. */ filter?: string | RegExp | types.AnyFn + /** Default selectable for all nodes. */ + selectable?: boolean } +type NodeData = types.PlainObj + /** IDataGridNodeOptions */ export interface IDataGridNodeOptions { /** Whether the node is selectable. */ @@ -131,6 +137,7 @@ export default class DataGrid extends Component { minHeight: 41, maxHeight: Infinity, filter: '', + selectable: false, }) const { columns, minHeight, maxHeight } = this.options each(columns, (column) => { @@ -177,10 +184,10 @@ export default class DataGrid extends Component { } } /** Append row data. */ - append( - data: types.PlainObj, - options?: IDataGridNodeOptions - ) { + append(data: NodeData, options: IDataGridNodeOptions = {}) { + defaults(options, { + selectable: this.options.selectable, + }) const node = new DataGridNode(this, data, options) this.nodes.push(node) @@ -207,6 +214,75 @@ export default class DataGrid extends Component { this.appendTimer = null this.updateHeight() } + /** Set data. */ + setData( + data: Array, + uniqueId?: string + ) { + const items = map(data, (item) => { + if (!isArr(item)) { + return [ + item, + { + selectable: this.options.selectable, + }, + ] + } + + defaults(item[1], { + selectable: this.options.selectable, + }) + + return item + }) as Array<[NodeData, IDataGridNodeOptions]> + + if (!uniqueId) { + this.clear() + each(items, (item) => { + const node = new DataGridNode(this, item[0], item[1]) + this.nodes.push(node) + if (this.filterNode(node)) { + this.displayNodes.push(node) + } + }) + } else { + const nodesMap: types.PlainObj = {} + each(this.nodes, (node) => { + nodesMap[node.data[uniqueId] as string] = node + }) + const nodes: Array = [] + const displayNodes: Array = [] + + each(items, (item) => { + const id = item[0][uniqueId] as string + let node + if (nodesMap[id]) { + node = nodesMap[id] + node.data = item[0] + node.render() + } else { + node = new DataGridNode(this, item[0], item[1]) + } + nodes.push(node) + if (this.filterNode(node)) { + displayNodes.push(node) + } + }) + + if (this.selectedNode && !contain(nodes, this.selectedNode)) { + this.selectNode(null) + } + + this.nodes = nodes + this.displayNodes = displayNodes + } + + if (this.sortId) { + this.sortNodes(this.sortId, this.isAscending) + } else { + this.renderData() + } + } /** Clear all data. */ clear() { this.detachAll() @@ -587,9 +663,7 @@ export class DataGridNode { constructor( dataGrid: DataGrid, data: types.PlainObj, - options: IDataGridNodeOptions = { - selectable: false, - } + options: IDataGridNodeOptions ) { ;(this.container as any).dataGridNode = this this.$container = $(this.container) diff --git a/src/data-grid/package.json b/src/data-grid/package.json index 5bfe492..d45b8bc 100644 --- a/src/data-grid/package.json +++ b/src/data-grid/package.json @@ -1,6 +1,6 @@ { "name": "data-grid", - "version": "1.1.0", + "version": "1.2.0", "description": "Grid for displaying datasets", "luna": { "react": true, diff --git a/src/data-grid/react.tsx b/src/data-grid/react.tsx index 23d4d79..4132a31 100644 --- a/src/data-grid/react.tsx +++ b/src/data-grid/react.tsx @@ -1,23 +1,21 @@ import { FC, useEffect, useRef } from 'react' -import DataGrid, { IColumn, DataGridNode } from './index' -import types from 'licia/types' +import DataGrid, { DataGridNode, IOptions } from './index' import each from 'licia/each' +import lowerCase from 'licia/lowerCase' +import { useNonInitialEffect, usePrevious } from '../share/hooks' -interface IDataGridProps { - columns: IColumn[] +interface IDataGridProps extends IOptions { onSelect?: (node: DataGridNode) => void onDeselect?: () => void className?: string - data?: any[] - height?: number - maxHeight?: number - minHeight?: number - filter?: string | RegExp | types.AnyFn + uniqueId?: string + data: any[] } const LunaDataGrid: FC = (props) => { const dataGridRef = useRef(null) const dataGrid = useRef() + const prevProps = usePrevious(props) useEffect(() => { dataGrid.current = new DataGrid(dataGridRef.current!, { @@ -26,6 +24,7 @@ const LunaDataGrid: FC = (props) => { maxHeight: props.maxHeight, minHeight: props.minHeight, filter: props.filter, + selectable: props.selectable, }) if (props.onSelect) { dataGrid.current.on('select', props.onSelect) @@ -33,44 +32,41 @@ const LunaDataGrid: FC = (props) => { if (props.onDeselect) { dataGrid.current.on('deselect', props.onDeselect) } - setData(dataGrid, props.data) + dataGrid.current.setData(props.data, props.uniqueId) }, []) - useEffect(() => setData(dataGrid, props.data), [props.data]) - useEffect(() => setOption(dataGrid, 'height', props.height), [props.height]) - useEffect( - () => setOption(dataGrid, 'maxHeight', props.maxHeight), - [props.maxHeight] - ) - useEffect( - () => setOption(dataGrid, 'minHeight', props.minHeight), - [props.minHeight] - ) - useEffect(() => setOption(dataGrid, 'filter', props.filter), [props.filter]) + useNonInitialEffect(() => { + if (dataGrid.current) { + dataGrid.current.setData(props.data, props.uniqueId) + } + }, [props.data]) - return
-} + each(['onSelect', 'onDeselect'], (key: 'onSelect' | 'onDeselect') => { + useNonInitialEffect(() => { + if (dataGrid.current) { + const event = lowerCase(key.slice(2)) + if (prevProps?.[key]) { + dataGrid.current.off(event, prevProps[key]) + } + if (props[key]) { + dataGrid.current.on(event, props[key]) + } + } + }, [props[key]]) + }) -function setData( - dataGrid: React.MutableRefObject, - data: any = [] -) { - if (dataGrid.current) { - dataGrid.current.clear() - each(data, (item: any) => - dataGrid.current?.append(item, { selectable: true }) - ) - } -} + each( + ['height', 'maxHeight', 'minHeight', 'filter'], + (key: keyof IDataGridProps) => { + useNonInitialEffect(() => { + if (dataGrid.current) { + dataGrid.current.setOption(key, props[key]) + } + }, [props[key]]) + } + ) -function setOption( - dataGrid: React.MutableRefObject, - name: string, - val: any -) { - if (dataGrid.current) { - dataGrid.current.setOption(name, val) - } + return
} export default LunaDataGrid diff --git a/src/data-grid/story.js b/src/data-grid/story.js index 9022d3e..9e1f1c2 100644 --- a/src/data-grid/story.js +++ b/src/data-grid/story.js @@ -6,7 +6,7 @@ import changelog from './CHANGELOG.md' import each from 'licia/each' import toEl from 'licia/toEl' import LunaDataGrid from './react' -import { object, number, button, text } from '@storybook/addon-knobs' +import { number, button, text } from '@storybook/addon-knobs' const def = story( 'data-grid', @@ -58,6 +58,7 @@ const def = story( minHeight={minHeight} maxHeight={maxHeight} filter={filter} + selectable={true} data={getData()} /> )