From 9aafb0f7ef84475b0e6966280580b4cbdaeda4dd Mon Sep 17 00:00:00 2001 From: solarjoker Date: Wed, 1 Apr 2020 12:39:39 +0800 Subject: [PATCH 01/90] feat: #1021 --- components/tree/TreeItem.js | 7 ++++--- components/tree/TreeNode.js | 11 ++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/components/tree/TreeItem.js b/components/tree/TreeItem.js index fa6af872c..485f1a680 100644 --- a/components/tree/TreeItem.js +++ b/components/tree/TreeItem.js @@ -18,6 +18,7 @@ class TreeItem extends Component { } render () { const { + level, editable, draggable, dropDividerPosition, @@ -176,7 +177,7 @@ class TreeItem extends Component { } if (editable) { e.preventDefault() - showRightClickMenu(item, e) + showRightClickMenu(item, e, level) } }} onClick={e => { @@ -208,7 +209,7 @@ class TreeItem extends Component { } if (this.props.editable) { e.preventDefault() - showRightClickMenu(item, e) + showRightClickMenu(item, e, level) } }} onClick={e => { @@ -226,7 +227,7 @@ class TreeItem extends Component { )} - {item.children && item.children.length > 0 && expanded ? renderTree(item.children) : null} + {item.children && item.children.length > 0 && expanded ? renderTree(item.children, [], level + 1) : null} {item.children && expanded && targetNode === item.id && diff --git a/components/tree/TreeNode.js b/components/tree/TreeNode.js index cfa4a831e..eeb811389 100644 --- a/components/tree/TreeNode.js +++ b/components/tree/TreeNode.js @@ -445,7 +445,7 @@ class TreeNode extends Component { highlight: item.id }) } - showRightClickMenu = (item, e) => { + showRightClickMenu = (item, e, level) => { const rect = e.target ? e.target.getBoundingClientRect() : {left: 0, top: 0, width: 0} const _st = document.documentElement.scrollTop || document.body.scrollTop const { contextMenu } = this.props @@ -458,7 +458,7 @@ class TreeNode extends Component { _cm = contextMenu } if (type === '[object Function]') { - _cm = contextMenu(item) + _cm = contextMenu(item, level) if (!_cm) { return } @@ -509,7 +509,7 @@ class TreeNode extends Component { currentDeleteNode: nodeId }) } - renderTree = (data, allData = []) => { + renderTree = (data, allData = [], level) => { const { draggable, prefixCls, @@ -548,6 +548,7 @@ class TreeNode extends Component { origin={origin} showLine={showLine} key={item.id} + level={level} isRoot={allData.some(d => d.id === item.id)} isLevelLast={index === data.length - 1} editable={editable} @@ -631,8 +632,8 @@ class TreeNode extends Component { )} {searchable - ? this.renderTree(this.highlightData(cloneDeep(dataCache), searchValue), dataCache) - : this.renderTree(cloneDeep(dataCache), dataCache)} + ? this.renderTree(this.highlightData(cloneDeep(dataCache), searchValue), dataCache, 0) + : this.renderTree(cloneDeep(dataCache), dataCache, 0)} Date: Wed, 1 Apr 2020 12:51:17 +0800 Subject: [PATCH 02/90] feat: #1022 --- components/tree/TreeItem.js | 2 +- components/tree/TreeNode.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/tree/TreeItem.js b/components/tree/TreeItem.js index 485f1a680..2aa40ef9f 100644 --- a/components/tree/TreeItem.js +++ b/components/tree/TreeItem.js @@ -145,7 +145,7 @@ class TreeItem extends Component { style={(editingNodes.find(node => node.id === item.id) || {}).title === '' ? { marginRight: 12, color: '#999', cursor: 'not-allowed' } : { cursor: 'pointer', marginRight: 12, color: themeColor[theme] }} onClick={() => { if ((editingNodes.find(node => node.id === item.id) || {}).title !== '') { - saveEditNode(item.id) + saveEditNode(item.id, level) } }} > diff --git a/components/tree/TreeNode.js b/components/tree/TreeNode.js index eeb811389..69098abba 100644 --- a/components/tree/TreeNode.js +++ b/components/tree/TreeNode.js @@ -296,7 +296,7 @@ class TreeNode extends Component { } }) } - saveEditNode = itemId => { + saveEditNode = (itemId, level) => { const { editNodes, dataCache, editingNodes } = this.state const nodeEdited = editingNodes.find(node => node.id === itemId) const _dataCache = cloneDeep(dataCache) @@ -307,7 +307,7 @@ class TreeNode extends Component { editingNodes: editingNodes.filter(node => node.id !== itemId) }) const node = findNode(itemId, _dataCache) - this.props.onSave(node, _dataCache) + this.props.onSave(node, _dataCache, level) } // 删除拖动的节点 _delDragNode = (itemId, data) => { From 7c31fb81a0aeb8309ffbb9c97d3321e492708b74 Mon Sep 17 00:00:00 2001 From: solarjoker Date: Wed, 1 Apr 2020 14:15:35 +0800 Subject: [PATCH 03/90] fix: #1023 --- components/tree/TreeNode.js | 19 +++++++++++-------- docs/demo/tree/section-edit.jsx | 19 +++++++++++++++---- docs/zh-CN/components/tree.mdx | 4 ++-- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/components/tree/TreeNode.js b/components/tree/TreeNode.js index 69098abba..fe33f2b35 100644 --- a/components/tree/TreeNode.js +++ b/components/tree/TreeNode.js @@ -44,7 +44,8 @@ class TreeNode extends Component { this.defaultEditNodeMenu = { 'editNode': (item, menu, index) => { return
  • { - menu.onClick ? menu.onClick(item, this) : this.editNode(item) + const node = findNode(item.id, this.state.dataCache) + menu.onClick ? menu.onClick(item, this) : this.editNode(node) this.closeRightClickMenu() }}>{menu.title || edit}
  • }, @@ -300,14 +301,16 @@ class TreeNode extends Component { const { editNodes, dataCache, editingNodes } = this.state const nodeEdited = editingNodes.find(node => node.id === itemId) const _dataCache = cloneDeep(dataCache) - this._saveEditNode(itemId, _dataCache, nodeEdited) - this.setState({ - dataCache: _dataCache, - editNodes: editNodes.filter(node => node.id !== itemId), - editingNodes: editingNodes.filter(node => node.id !== itemId) - }) const node = findNode(itemId, _dataCache) - this.props.onSave(node, _dataCache, level) + const result = this.props.onSave(node, _dataCache, level) + if (result !== false) { + this._saveEditNode(itemId, _dataCache, nodeEdited) + this.setState({ + dataCache: _dataCache, + editNodes: editNodes.filter(node => node.id !== itemId), + editingNodes: editingNodes.filter(node => node.id !== itemId) + }) + } } // 删除拖动的节点 _delDragNode = (itemId, data) => { diff --git a/docs/demo/tree/section-edit.jsx b/docs/demo/tree/section-edit.jsx index d7dee11d2..1d2b29ae6 100644 --- a/docs/demo/tree/section-edit.jsx +++ b/docs/demo/tree/section-edit.jsx @@ -1,6 +1,7 @@ import React from 'react' import DocViewer from '../../../libs/doc-viewer' import Tree from '../../../components/tree' +import Notification from '../../../components/notification' const prefix = 'tree-edit' const desc = '通过树的节点进行新增、删除、编辑等操作' const rightOptions = ['基础', '自定义菜单'] @@ -92,13 +93,23 @@ class Demo extends React.Component { apperance="line" editable={true} data={this.state.treeData} - onSave={(saveNode, data) => { - console.log(saveNode, data) + onSave={(saveNode, data, level) => { + if (level === 0) { + Notification.open({ + title:'保存失败', + type:'error' + }) + return false + } else { + return true + } + console.log(saveNode, data,level) + }} onDelete={(deleteNode, data) => { console.log(deleteNode, data) }} - contextMenu={(currentItemData) => { + contextMenu={(currentItemData, level) => { if (currentItemData.customData === 'Y') { return [{ type: 'addChildNode' @@ -141,7 +152,7 @@ class Demo extends React.Component { const DemoEdit = () => ( ContextMenuOption[] | | [] | +| contextMenu | 自定义右键菜单,参考 _示例_ 及 _页面底部自定义右键菜单使用说明_ | ContextMenuOption[] \| (item: DataItem,level: number) => ContextMenuOption[] | | [] | | onChange | 树组件改变时触发 | (data: TreeNode[]) => void | - | - | | onExpand | 节点被点击(展开/收起)时触发 | (expanded: boolean, expandIds: string[], expandedNode: TreeNode) => void | - | - | | onCheck | 点击节点多选框触发 | (checked: boolean, checkedIds: string[], checkedNode: TreeNode) => void | - | - | @@ -78,7 +78,7 @@ import DemoLine from '../../demo/tree/section-line.jsx' | onDrop | 节点拖拽时触发 | (dragNode: TreeNode, dropNode: TreeNode) => boolean | - | - | | onDropEnd | 节点拖拽成功时触发 | (dragNode: TreeNode, dropNode: TreeNode) => void | - | - | | onDelete | 节点删除时触发 | (deletedNode: TreeNode, data: TreeNode[]) => void | - | - | -| onSave | 节点保存新增、编辑状态时触发 | (savedNode: TreeNode, data: TreeNode[]) => void | - | - | +| onSave | 节点保存新增、编辑状态时触发, 返回 false 则保存新增、编辑失败 | (savedNode: TreeNode, data: TreeNode[], level: number) => boolean | - | - | ## Type From 3737f864ee995a3f0c5bac51b6a215d65fe7645e Mon Sep 17 00:00:00 2001 From: solarjoker Date: Wed, 1 Apr 2020 15:33:32 +0800 Subject: [PATCH 04/90] feat: fix onsave --- components/tree/TreeNode.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/tree/TreeNode.js b/components/tree/TreeNode.js index fe33f2b35..ea4db7fcf 100644 --- a/components/tree/TreeNode.js +++ b/components/tree/TreeNode.js @@ -301,8 +301,7 @@ class TreeNode extends Component { const { editNodes, dataCache, editingNodes } = this.state const nodeEdited = editingNodes.find(node => node.id === itemId) const _dataCache = cloneDeep(dataCache) - const node = findNode(itemId, _dataCache) - const result = this.props.onSave(node, _dataCache, level) + const result = this.props.onSave(nodeEdited, _dataCache, level) if (result !== false) { this._saveEditNode(itemId, _dataCache, nodeEdited) this.setState({ From 0fb42cddec2fa565065f8010b81388ac1ff89879 Mon Sep 17 00:00:00 2001 From: solarjoker Date: Wed, 1 Apr 2020 18:03:25 +0800 Subject: [PATCH 05/90] fix: editable bug --- components/tree/TreeNode.js | 2 +- docs/demo/tree/section-edit.jsx | 4 +++- package.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/components/tree/TreeNode.js b/components/tree/TreeNode.js index ea4db7fcf..5f62c115e 100644 --- a/components/tree/TreeNode.js +++ b/components/tree/TreeNode.js @@ -45,7 +45,7 @@ class TreeNode extends Component { 'editNode': (item, menu, index) => { return
  • { const node = findNode(item.id, this.state.dataCache) - menu.onClick ? menu.onClick(item, this) : this.editNode(node) + menu.onClick ? menu.onClick(node, this) : this.editNode(node) this.closeRightClickMenu() }}>{menu.title || edit}
  • }, diff --git a/docs/demo/tree/section-edit.jsx b/docs/demo/tree/section-edit.jsx index 1d2b29ae6..0a984b024 100644 --- a/docs/demo/tree/section-edit.jsx +++ b/docs/demo/tree/section-edit.jsx @@ -50,7 +50,8 @@ class Demo extends React.Component { apperance="line" editable={true} data={this.state.treeData} - onSave={(saveNode, data) => { + onSave={(saveNode, data,level) => { + console.log(saveNode, data) }} onDelete={(deleteNode, data) => { @@ -89,6 +90,7 @@ class Demo extends React.Component { return (
    Date: Thu, 2 Apr 2020 08:52:08 +0800 Subject: [PATCH 06/90] feat: #1024 --- components/watermark/watermark.js | 5 +++-- docs/demo/watermark/section-base.jsx | 9 +++++++-- docs/zh-CN/components/watermark.mdx | 3 ++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/components/watermark/watermark.js b/components/watermark/watermark.js index 2fbc78adc..d0468294a 100644 --- a/components/watermark/watermark.js +++ b/components/watermark/watermark.js @@ -101,7 +101,8 @@ const drawLogo = (ctx, logo, cb) => { } const toImage = (canvas, key, container, options) => { - var base64Url = canvas.toDataURL() + const base64Url = canvas.toDataURL() + const { opacity = 1 } = options const _top = (options._top || 0) + 'px' const __wm = document.querySelector(`.${key}`) const watermarkDiv = __wm || document.createElement('div') @@ -117,7 +118,7 @@ const toImage = (canvas, key, container, options) => { background-repeat:repeat; visibility:visible !important; display: block !important; - opacity: 1 !important; + opacity: ${opacity} !important; background-image:url('${base64Url}'); ${options.grayLogo ? '-webkit-filter: grayscale(100%);-moz-filter: grayscale(100%);-ms-filter: grayscale(100%);-o-filter: grayscale(100%);filter:progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);_filter:none;' : ''} ` diff --git a/docs/demo/watermark/section-base.jsx b/docs/demo/watermark/section-base.jsx index 72ad8a86d..3e214deaa 100755 --- a/docs/demo/watermark/section-base.jsx +++ b/docs/demo/watermark/section-base.jsx @@ -5,11 +5,16 @@ import logo from '../../../site/static/img/logo.png' const prefix = 'watermark-base' const desc = '' const code = `import React from 'react' +import logo from '本地图片路径或者base64' import Watermark from '@hi-ui/hiui/es/Watermark'\n class Demo extends React.Component { constructor(props) { super(props) - this.options = {logo: logo, content: ['HIUI', '做中台,就用 HIUI'],density:'high'} + this.options = { + logo: logo, // 本地图片路径或者base64 + content: ['HIUI', '做中台,就用 HIUI'], + density:'high' + } } render () { return ( @@ -17,7 +22,7 @@ class Demo extends React.Component { {...this.options} >
    ) diff --git a/docs/zh-CN/components/watermark.mdx b/docs/zh-CN/components/watermark.mdx index 6297efe14..68a7b2bbf 100755 --- a/docs/zh-CN/components/watermark.mdx +++ b/docs/zh-CN/components/watermark.mdx @@ -17,5 +17,6 @@ import DemoBase from '../../demo/watermark/section-base.jsx' | 参数 | 说明 | 类型 | 可选值 | 默认值 | | ------- | ------------------------------------------ | ----------------------- | ---------------------------- | ---------- | | density | 水印间距,调节疏密程度 | string | 'low' \| 'default' \| 'high' | 'default' | -| content | 水印文案,传入数组代表多行,不建议超过三行 | string \| Array[string] | - | '请勿外传' | +| content | 水印文案,传入数组代表多行,不建议超过三行 | string \| Array[string] | - | '请勿外传' | | logo | 图片资源地址(暂只支持本地资源) | string | - | - | +| opacity | 水印透明度 | number | 0~1 | 1 | From b70a0a0bb49eda4840d1b8300b9bc0644f26d10d Mon Sep 17 00:00:00 2001 From: solarjoker Date: Fri, 3 Apr 2020 00:39:45 +0800 Subject: [PATCH 07/90] feat: add onBeforeDelete --- components/tree/Tree.js | 2 ++ components/tree/TreeNode.js | 43 ++++++++++++++++++++------------- docs/demo/tree/section-edit.jsx | 5 ++++ docs/zh-CN/components/tree.mdx | 3 ++- 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/components/tree/Tree.js b/components/tree/Tree.js index 7314a88dd..fa14891ab 100644 --- a/components/tree/Tree.js +++ b/components/tree/Tree.js @@ -181,6 +181,7 @@ export class Tree extends Component { onDrop, onDropEnd, onDelete, + onBeforeDelete, onSave, onClick, apperance, @@ -222,6 +223,7 @@ export class Tree extends Component { onDrop={onDrop} onDropEnd={onDropEnd} onDelete={onDelete} + onBeforeDelete={onBeforeDelete} onSave={onSave} contextMenu={contextMenu} /> diff --git a/components/tree/TreeNode.js b/components/tree/TreeNode.js index 5f62c115e..94089f10f 100644 --- a/components/tree/TreeNode.js +++ b/components/tree/TreeNode.js @@ -42,29 +42,29 @@ class TreeNode extends Component { } const { addNode, addChildNode, edit, del } = props.localeDatas.tree this.defaultEditNodeMenu = { - 'editNode': (item, menu, index) => { + 'editNode': (item, menu, index, level) => { return
  • { const node = findNode(item.id, this.state.dataCache) menu.onClick ? menu.onClick(node, this) : this.editNode(node) this.closeRightClickMenu() }}>{menu.title || edit}
  • }, - 'addChildNode': (item, menu, index) => { + 'addChildNode': (item, menu, index, level) => { return
  • { menu.onClick ? menu.onClick(item, this) : this.addChildNode(item) this.closeRightClickMenu() }}>{menu.title || addChildNode}
  • }, - 'addSiblingNode': (item, menu, index) => { + 'addSiblingNode': (item, menu, index, level) => { return
  • { menu.onClick ? menu.onClick(item, this) : this.addSiblingNode(item.id) this.closeRightClickMenu() }}>{menu.title || addNode}
  • }, - 'deleteNode': (item, menu, index) => { + 'deleteNode': (item, menu, index, level) => { return
  • { - menu.onClick ? menu.onClick(item, this) : this.deleteNode(item) + menu.onClick ? menu.onClick(item, this) : this.deleteNode(item, level) this.closeRightClickMenu() }} > @@ -237,8 +237,8 @@ class TreeNode extends Component { this._addChildNode(item.id, _dataCache, _editingNodes) this.setState({ dataCache: _dataCache, editingNodes: _editingNodes }) } - deleteNode = item => { - this.setCurrentDeleteNode(item.id) + deleteNode = (item, level) => { + this.setCurrentDeleteNode({id: item.id, level}) this.openModal() } // 编辑节点 @@ -434,13 +434,22 @@ class TreeNode extends Component { } }) } - _deleteNode = itemId => { + _deleteNode = (delNode) => { const { dataCache } = this.state const _dataCache = cloneDeep(dataCache) - this.__deleteNode(itemId, _dataCache) - this.setState({ dataCache: _dataCache }) - const node = findNode(itemId, dataCache) - this.props.onDelete(node, _dataCache) + const node = findNode(delNode.id, dataCache) + if (this.props.onBeforeDelete) { + const result = this.props.onBeforeDelete(node, dataCache, delNode.level) + if (result === true) { + this.__deleteNode(delNode.id, _dataCache) + this.setState({ dataCache: _dataCache }) + this.props.onDelete(node, _dataCache) + } + } else { + this.__deleteNode(delNode.id, _dataCache) + this.setState({ dataCache: _dataCache }) + this.props.onDelete(node, _dataCache) + } } onSetHighlight = item => { this.setState({ @@ -471,15 +480,15 @@ class TreeNode extends Component { _cm.length > 0 ? _cm.map((cm, index) => { if (cm.type && this.defaultEditNodeMenu[cm.type]) { - return this.defaultEditNodeMenu[cm.type](item, cm, index) + return this.defaultEditNodeMenu[cm.type](item, cm, index, level) } else { - return this.defaultEditNodeMenu['customer'](item, cm, index) + return this.defaultEditNodeMenu['customer'](item, cm, index, level) } }) : Object.keys(this.defaultEditNodeMenu).map((key, index) => { if (key === 'customer') { return null } - return this.defaultEditNodeMenu[key](item, {}, index) + return this.defaultEditNodeMenu[key](item, {}, index, level) }) } @@ -506,9 +515,9 @@ class TreeNode extends Component { showModal: true }) } - setCurrentDeleteNode = nodeId => { + setCurrentDeleteNode =(node) => { this.setState({ - currentDeleteNode: nodeId + currentDeleteNode: node }) } renderTree = (data, allData = [], level) => { diff --git a/docs/demo/tree/section-edit.jsx b/docs/demo/tree/section-edit.jsx index 0a984b024..75bd9a34e 100644 --- a/docs/demo/tree/section-edit.jsx +++ b/docs/demo/tree/section-edit.jsx @@ -54,6 +54,10 @@ class Demo extends React.Component { console.log(saveNode, data) }} + onBeforeDelete={(deleteNode, data, level) => { + console.log(deleteNode, data,level) + return true + }} onDelete={(deleteNode, data) => { console.log(deleteNode, data) }} @@ -108,6 +112,7 @@ class Demo extends React.Component { console.log(saveNode, data,level) }} + onDelete={(deleteNode, data) => { console.log(deleteNode, data) }} diff --git a/docs/zh-CN/components/tree.mdx b/docs/zh-CN/components/tree.mdx index 7adc3a088..b226c217e 100755 --- a/docs/zh-CN/components/tree.mdx +++ b/docs/zh-CN/components/tree.mdx @@ -77,7 +77,8 @@ import DemoLine from '../../demo/tree/section-line.jsx' | onDragStart | 节点开始拖拽时触发 | (dragNode: TreeNode) => void | - | - | | onDrop | 节点拖拽时触发 | (dragNode: TreeNode, dropNode: TreeNode) => boolean | - | - | | onDropEnd | 节点拖拽成功时触发 | (dragNode: TreeNode, dropNode: TreeNode) => void | - | - | -| onDelete | 节点删除时触发 | (deletedNode: TreeNode, data: TreeNode[]) => void | - | - | +| onBeforeDelete | 节点删除前触发,返回 false 则节点删除失败,不会触发 onDelete | (deletedNode: TreeNode, data: TreeNode[], level: number) => boolean | - | - | +| onDelete | 节点删除后触发 | (deletedNode: TreeNode, data: TreeNode[]) => void | - | - | | onSave | 节点保存新增、编辑状态时触发, 返回 false 则保存新增、编辑失败 | (savedNode: TreeNode, data: TreeNode[], level: number) => boolean | - | - | ## Type From bd38341d25aa184fb4a50d34286c71e55cfaa413 Mon Sep 17 00:00:00 2001 From: solarjoker Date: Fri, 3 Apr 2020 01:32:25 +0800 Subject: [PATCH 08/90] feat: enhance onDrop --- components/tree/TreeItem.js | 10 +++++----- components/tree/TreeNode.js | 8 ++++---- components/tree/util.js | 20 +++++++++++++++----- docs/demo/tree/section-drag.jsx | 3 +++ docs/zh-CN/components/tree.mdx | 10 +++++++++- 5 files changed, 36 insertions(+), 15 deletions(-) diff --git a/components/tree/TreeItem.js b/components/tree/TreeItem.js index 2aa40ef9f..a9cdf8e3f 100644 --- a/components/tree/TreeItem.js +++ b/components/tree/TreeItem.js @@ -245,7 +245,7 @@ const source = { props.closeExpandedTreeNode(props.item.id) } props.onDragStart(props.item) - return { sourceItem: props.item, originalExpandStatus: props.expanded } + return { sourceItem: props.item, originalExpandStatus: props.expanded, sourceLevel: props.level } }, endDrag (props, monitor) { const dropResult = monitor.getDropResult() @@ -258,16 +258,16 @@ const source = { } const target = { drop (props, monitor) { - const { sourceItem, originalExpandStatus } = monitor.getItem() + const { sourceItem, originalExpandStatus, sourceLevel } = monitor.getItem() const { item: targetItem, dropNode, removeDraggingNode, expandTreeNode, removeTargetNode, - dropDividerPosition + dropDividerPosition, + level } = props - // 先看下是不是在最近得组件 if (monitor.isOver({ shallow: true })) { if ( @@ -285,7 +285,7 @@ const target = { removeTargetNode() } else { // 移动节点到相应位置 - dropNode(sourceItem, targetItem, dropDividerPosition) + dropNode(sourceItem, targetItem, dropDividerPosition, {before: sourceLevel, after: level}) removeDraggingNode() removeTargetNode() } diff --git a/components/tree/TreeNode.js b/components/tree/TreeNode.js index 94089f10f..f5dc75098 100644 --- a/components/tree/TreeNode.js +++ b/components/tree/TreeNode.js @@ -7,7 +7,7 @@ import Icon from '../icon' import uuidv4 from 'uuid/v4' import TreeItem from './TreeItem' import Modal from '../modal' -import { collectExpandId, findNode } from './util' +import { collectExpandId, findNode, getParent } from './util' import axios from 'axios' import qs from 'qs' import Provider from '../context' @@ -396,7 +396,7 @@ class TreeNode extends Component { } }) } - dropNode = (sourceItem, targetItem, dropDividerPosition) => { + dropNode = (sourceItem, targetItem, dropDividerPosition, {before, after}) => { const { dataCache } = this.state const _dataCache = cloneDeep(dataCache) this._delDragNode(sourceItem.id, _dataCache) @@ -408,8 +408,9 @@ class TreeNode extends Component { } const _sourceItem = findNode(sourceItem.id, dataCache) const _targetItem = findNode(targetItem.id, dataCache) + const targetParent = dropDividerPosition === 'sub' ? _targetItem : getParent(targetItem.id, dataCache) if (this.props.onDrop) { - if (this.props.onDrop(_sourceItem, _targetItem)) { + if (this.props.onDrop(_sourceItem, _targetItem, targetParent, {before, after: dropDividerPosition === 'sub' ? after + 1 : after})) { this.props.onDropEnd(_sourceItem, _targetItem) this.setState({ dataCache: _dataCache @@ -587,7 +588,6 @@ class TreeNode extends Component { renderSwitcher={this.renderSwitcher} cancelAddSiblingNode={this.cancelAddSiblingNode} apperance={apperance} - // renderRightClickMenu={this.renderRightClickMenu} onCheckChange={onCheckChange} saveEditNode={this.saveEditNode} onClick={onClick} diff --git a/components/tree/util.js b/components/tree/util.js index 46b7144cb..2aadf9a1c 100644 --- a/components/tree/util.js +++ b/components/tree/util.js @@ -1,8 +1,3 @@ -/** - * @Author lishuaishuai - * @Date 2018-03-22 11:14:48 - * @Description tree相关工具封装 - */ export function deepMap (data, parent) { let arr = [] for (let key in data) { @@ -92,6 +87,21 @@ export const getParentId = (id, data) => { }) return parentId } + +// 寻找某一节点的父节点 +export const getParent = (id, data) => { + let parent + data.forEach(item => { + if (item.children) { + if (item.children.some(item => item.id === id)) { + parent = item + } else if (getParent(id, item.children)) { + parent = getParent(id, item.children) + } + } + }) + return parent +} // 寻找某一节点的所有子节点 export const getChildrenIds = (node, arr = []) => { if (node.children) { diff --git a/docs/demo/tree/section-drag.jsx b/docs/demo/tree/section-drag.jsx index ebd205c4e..64243e653 100644 --- a/docs/demo/tree/section-drag.jsx +++ b/docs/demo/tree/section-drag.jsx @@ -49,6 +49,9 @@ class Demo extends React.Component { onDragStart = {(dragNode)=> { console.log(dragNode) }} + onDrop = {(dragNode, dropNode, newParent, level)=> { + console.log(dragNode,dropNode,newParent, level) + }} onDropEnd = {(dragNode,dropNode)=> { console.log(dragNode,dropNode) }} diff --git a/docs/zh-CN/components/tree.mdx b/docs/zh-CN/components/tree.mdx index b226c217e..e607901a9 100755 --- a/docs/zh-CN/components/tree.mdx +++ b/docs/zh-CN/components/tree.mdx @@ -75,7 +75,7 @@ import DemoLine from '../../demo/tree/section-line.jsx' | onCheck | 点击节点多选框触发 | (checked: boolean, checkedIds: string[], checkedNode: TreeNode) => void | - | - | | onClick | 点击节点文字时触发 | (clickNode: TreeNode) => void | - | - | | onDragStart | 节点开始拖拽时触发 | (dragNode: TreeNode) => void | - | - | -| onDrop | 节点拖拽时触发 | (dragNode: TreeNode, dropNode: TreeNode) => boolean | - | - | +| onDrop | 节点拖拽时触发 | (dragNode: TreeNode, dropNode: TreeNode, newParent: TreeNode, level: Level) => boolean | - | - | | onDropEnd | 节点拖拽成功时触发 | (dragNode: TreeNode, dropNode: TreeNode) => void | - | - | | onBeforeDelete | 节点删除前触发,返回 false 则节点删除失败,不会触发 onDelete | (deletedNode: TreeNode, data: TreeNode[], level: number) => boolean | - | - | | onDelete | 节点删除后触发 | (deletedNode: TreeNode, data: TreeNode[]) => void | - | - | @@ -103,6 +103,14 @@ import DemoLine from '../../demo/tree/section-line.jsx' | disabled | 是否禁用节点 | boolean | true \| false | false | | children | 该节点的子节点 | TreeNode[] | - | - | +### Level + +| 参数 | 说明 | 类型 | 可选值 | 默认值 | +| -------- | -------------- | ------------------- | ------------- | ------ | +| before | 拖拽前在树中的层级 | number | - | - | +| after | 拖拽后在树中的层级 | number | - | - | + + ### ContextMenuOption | 参数 | 说明 | 类型 | 可选值 | 默认值 | From c19c8f3cc496653879474fd61a9dd419e20e6865 Mon Sep 17 00:00:00 2001 From: solarjoker Date: Fri, 3 Apr 2020 01:50:14 +0800 Subject: [PATCH 09/90] feat: add onBeforeSave --- components/tree/Tree.js | 2 ++ components/tree/TreeNode.js | 15 +++++++++++++-- docs/demo/tree/section-edit.jsx | 6 +++++- docs/zh-CN/components/tree.mdx | 3 ++- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/components/tree/Tree.js b/components/tree/Tree.js index fa14891ab..48ed60313 100644 --- a/components/tree/Tree.js +++ b/components/tree/Tree.js @@ -183,6 +183,7 @@ export class Tree extends Component { onDelete, onBeforeDelete, onSave, + onBeforeSave, onClick, apperance, contextMenu, @@ -225,6 +226,7 @@ export class Tree extends Component { onDelete={onDelete} onBeforeDelete={onBeforeDelete} onSave={onSave} + onBeforeSave={onBeforeSave} contextMenu={contextMenu} />
  • diff --git a/components/tree/TreeNode.js b/components/tree/TreeNode.js index f5dc75098..a5a4b06a6 100644 --- a/components/tree/TreeNode.js +++ b/components/tree/TreeNode.js @@ -301,14 +301,25 @@ class TreeNode extends Component { const { editNodes, dataCache, editingNodes } = this.state const nodeEdited = editingNodes.find(node => node.id === itemId) const _dataCache = cloneDeep(dataCache) - const result = this.props.onSave(nodeEdited, _dataCache, level) - if (result !== false) { + if (this.props.onBeforeSave) { + const result = this.props.onBeforeSave(nodeEdited, dataCache, level) + if (result === true) { + this._saveEditNode(itemId, _dataCache, nodeEdited) + this.setState({ + dataCache: _dataCache, + editNodes: editNodes.filter(node => node.id !== itemId), + editingNodes: editingNodes.filter(node => node.id !== itemId) + }) + this.props.onSave(nodeEdited, _dataCache) + } + } else { this._saveEditNode(itemId, _dataCache, nodeEdited) this.setState({ dataCache: _dataCache, editNodes: editNodes.filter(node => node.id !== itemId), editingNodes: editingNodes.filter(node => node.id !== itemId) }) + this.props.onSave(nodeEdited, _dataCache) } } // 删除拖动的节点 diff --git a/docs/demo/tree/section-edit.jsx b/docs/demo/tree/section-edit.jsx index 75bd9a34e..f33e0707c 100644 --- a/docs/demo/tree/section-edit.jsx +++ b/docs/demo/tree/section-edit.jsx @@ -50,7 +50,11 @@ class Demo extends React.Component { apperance="line" editable={true} data={this.state.treeData} - onSave={(saveNode, data,level) => { + onBeforeSave={(saveNode, data, level) => { + console.log(saveNode, data,level) + return true + }} + onSave={(saveNode, data) => { console.log(saveNode, data) }} diff --git a/docs/zh-CN/components/tree.mdx b/docs/zh-CN/components/tree.mdx index e607901a9..cca8b2249 100755 --- a/docs/zh-CN/components/tree.mdx +++ b/docs/zh-CN/components/tree.mdx @@ -79,7 +79,8 @@ import DemoLine from '../../demo/tree/section-line.jsx' | onDropEnd | 节点拖拽成功时触发 | (dragNode: TreeNode, dropNode: TreeNode) => void | - | - | | onBeforeDelete | 节点删除前触发,返回 false 则节点删除失败,不会触发 onDelete | (deletedNode: TreeNode, data: TreeNode[], level: number) => boolean | - | - | | onDelete | 节点删除后触发 | (deletedNode: TreeNode, data: TreeNode[]) => void | - | - | -| onSave | 节点保存新增、编辑状态时触发, 返回 false 则保存新增、编辑失败 | (savedNode: TreeNode, data: TreeNode[], level: number) => boolean | - | - | +| onBeforeSave | 节点保存新增、编辑状态时触发, 返回 false 则保存新增、编辑失败,不会触发 onSave | (savedNode: TreeNode, data: TreeNode[], level: number) => boolean | - | - | +| onSave | 节点保存新增、编辑状态后触发 | (savedNode: TreeNode, data: TreeNode[]) => void | - | - | ## Type From 94170a0a786415d0a5386714a88e5cdafa4ea780 Mon Sep 17 00:00:00 2001 From: solarjoker Date: Fri, 3 Apr 2020 10:52:13 +0800 Subject: [PATCH 10/90] feat: update on hooks --- components/tree/TreeNode.js | 15 ++++++--------- components/tree/util.js | 14 -------------- docs/demo/tree/section-drag.jsx | 4 ++-- docs/zh-CN/components/tree.mdx | 13 ++++++++++--- package.json | 2 +- 5 files changed, 19 insertions(+), 29 deletions(-) diff --git a/components/tree/TreeNode.js b/components/tree/TreeNode.js index a5a4b06a6..711158249 100644 --- a/components/tree/TreeNode.js +++ b/components/tree/TreeNode.js @@ -7,7 +7,7 @@ import Icon from '../icon' import uuidv4 from 'uuid/v4' import TreeItem from './TreeItem' import Modal from '../modal' -import { collectExpandId, findNode, getParent } from './util' +import { collectExpandId, findNode } from './util' import axios from 'axios' import qs from 'qs' import Provider from '../context' @@ -301,10 +301,10 @@ class TreeNode extends Component { const { editNodes, dataCache, editingNodes } = this.state const nodeEdited = editingNodes.find(node => node.id === itemId) const _dataCache = cloneDeep(dataCache) + this._saveEditNode(itemId, _dataCache, nodeEdited) if (this.props.onBeforeSave) { - const result = this.props.onBeforeSave(nodeEdited, dataCache, level) + const result = this.props.onBeforeSave(nodeEdited, {before: dataCache, after: _dataCache}, level) if (result === true) { - this._saveEditNode(itemId, _dataCache, nodeEdited) this.setState({ dataCache: _dataCache, editNodes: editNodes.filter(node => node.id !== itemId), @@ -313,7 +313,6 @@ class TreeNode extends Component { this.props.onSave(nodeEdited, _dataCache) } } else { - this._saveEditNode(itemId, _dataCache, nodeEdited) this.setState({ dataCache: _dataCache, editNodes: editNodes.filter(node => node.id !== itemId), @@ -419,9 +418,8 @@ class TreeNode extends Component { } const _sourceItem = findNode(sourceItem.id, dataCache) const _targetItem = findNode(targetItem.id, dataCache) - const targetParent = dropDividerPosition === 'sub' ? _targetItem : getParent(targetItem.id, dataCache) if (this.props.onDrop) { - if (this.props.onDrop(_sourceItem, _targetItem, targetParent, {before, after: dropDividerPosition === 'sub' ? after + 1 : after})) { + if (this.props.onDrop(_sourceItem, _targetItem, {before: dataCache, after: _dataCache}, {before, after: dropDividerPosition === 'sub' ? after + 1 : after})) { this.props.onDropEnd(_sourceItem, _targetItem) this.setState({ dataCache: _dataCache @@ -450,15 +448,14 @@ class TreeNode extends Component { const { dataCache } = this.state const _dataCache = cloneDeep(dataCache) const node = findNode(delNode.id, dataCache) + this.__deleteNode(delNode.id, _dataCache) if (this.props.onBeforeDelete) { - const result = this.props.onBeforeDelete(node, dataCache, delNode.level) + const result = this.props.onBeforeDelete(node, {before: dataCache, after: _dataCache}, delNode.level) if (result === true) { - this.__deleteNode(delNode.id, _dataCache) this.setState({ dataCache: _dataCache }) this.props.onDelete(node, _dataCache) } } else { - this.__deleteNode(delNode.id, _dataCache) this.setState({ dataCache: _dataCache }) this.props.onDelete(node, _dataCache) } diff --git a/components/tree/util.js b/components/tree/util.js index 2aadf9a1c..a1c44b242 100644 --- a/components/tree/util.js +++ b/components/tree/util.js @@ -88,20 +88,6 @@ export const getParentId = (id, data) => { return parentId } -// 寻找某一节点的父节点 -export const getParent = (id, data) => { - let parent - data.forEach(item => { - if (item.children) { - if (item.children.some(item => item.id === id)) { - parent = item - } else if (getParent(id, item.children)) { - parent = getParent(id, item.children) - } - } - }) - return parent -} // 寻找某一节点的所有子节点 export const getChildrenIds = (node, arr = []) => { if (node.children) { diff --git a/docs/demo/tree/section-drag.jsx b/docs/demo/tree/section-drag.jsx index 64243e653..a1190501f 100644 --- a/docs/demo/tree/section-drag.jsx +++ b/docs/demo/tree/section-drag.jsx @@ -49,8 +49,8 @@ class Demo extends React.Component { onDragStart = {(dragNode)=> { console.log(dragNode) }} - onDrop = {(dragNode, dropNode, newParent, level)=> { - console.log(dragNode,dropNode,newParent, level) + onDrop = {(dragNode, dropNode, data, level)=> { + console.log(dragNode,dropNode,data, level) }} onDropEnd = {(dragNode,dropNode)=> { console.log(dragNode,dropNode) diff --git a/docs/zh-CN/components/tree.mdx b/docs/zh-CN/components/tree.mdx index cca8b2249..b1b96624d 100755 --- a/docs/zh-CN/components/tree.mdx +++ b/docs/zh-CN/components/tree.mdx @@ -75,11 +75,11 @@ import DemoLine from '../../demo/tree/section-line.jsx' | onCheck | 点击节点多选框触发 | (checked: boolean, checkedIds: string[], checkedNode: TreeNode) => void | - | - | | onClick | 点击节点文字时触发 | (clickNode: TreeNode) => void | - | - | | onDragStart | 节点开始拖拽时触发 | (dragNode: TreeNode) => void | - | - | -| onDrop | 节点拖拽时触发 | (dragNode: TreeNode, dropNode: TreeNode, newParent: TreeNode, level: Level) => boolean | - | - | +| onDrop | 节点拖拽时触发 | (dragNode: TreeNode, dropNode: TreeNode, data: DataStatus, level: Level) => boolean | - | - | | onDropEnd | 节点拖拽成功时触发 | (dragNode: TreeNode, dropNode: TreeNode) => void | - | - | -| onBeforeDelete | 节点删除前触发,返回 false 则节点删除失败,不会触发 onDelete | (deletedNode: TreeNode, data: TreeNode[], level: number) => boolean | - | - | +| onBeforeDelete | 节点删除前触发,返回 false 则节点删除失败,不会触发 onDelete | (deletedNode: TreeNode, data: DataStatus, level: number) => boolean | - | - | | onDelete | 节点删除后触发 | (deletedNode: TreeNode, data: TreeNode[]) => void | - | - | -| onBeforeSave | 节点保存新增、编辑状态时触发, 返回 false 则保存新增、编辑失败,不会触发 onSave | (savedNode: TreeNode, data: TreeNode[], level: number) => boolean | - | - | +| onBeforeSave | 节点保存新增、编辑状态时触发, 返回 false 则保存新增、编辑失败,不会触发 onSave | (savedNode: TreeNode, data: DataStatus, level: number) => boolean | - | - | | onSave | 节点保存新增、编辑状态后触发 | (savedNode: TreeNode, data: TreeNode[]) => void | - | - | ## Type @@ -111,6 +111,13 @@ import DemoLine from '../../demo/tree/section-line.jsx' | before | 拖拽前在树中的层级 | number | - | - | | after | 拖拽后在树中的层级 | number | - | - | +### DataStatus + +| 参数 | 说明 | 类型 | 可选值 | 默认值 | +| -------- | -------------- | ------------------- | ------------- | ------ | +| before | 更新前整个树的数据结构 | []TreeNode | - | - | +| after | 更新后整个树的数据结构 | []TreeNode | - | - | + ### ContextMenuOption diff --git a/package.json b/package.json index 0c5291694..c6d44fa70 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@hi-ui/hiui", - "version": "2.13.0-rc.2", + "version": "2.13.0-rc.4", "description": "HIUI for React", "scripts": { "test": "node_modules/.bin/standard && node_modules/.bin/stylelint --config .stylelintrc 'components/**/*.scss'", From 3cad16a73cb761f9119a714915ffcc7e7060a58b Mon Sep 17 00:00:00 2001 From: solarjoker Date: Sun, 5 Apr 2020 00:13:06 +0800 Subject: [PATCH 11/90] feat: opt tree drag performance --- components/tree/TreeItem.js | 79 +++++++++++++------------------------ components/tree/TreeNode.js | 52 +----------------------- package.json | 2 +- 3 files changed, 30 insertions(+), 103 deletions(-) diff --git a/components/tree/TreeItem.js b/components/tree/TreeItem.js index a9cdf8e3f..151cc557c 100644 --- a/components/tree/TreeItem.js +++ b/components/tree/TreeItem.js @@ -21,7 +21,7 @@ class TreeItem extends Component { level, editable, draggable, - dropDividerPosition, + direction, checked, expanded, highlight, @@ -32,7 +32,6 @@ class TreeItem extends Component { onClick, highlightable, item, - draggingNode, checkable, itemStyle, onExpanded, @@ -48,7 +47,7 @@ class TreeItem extends Component { connectDragSource, connectDropTarget, isOver, - targetNode, + isDragging, saveEditNode, origin, loadChildren, @@ -80,7 +79,7 @@ class TreeItem extends Component { } )} > - {targetNode === item.id && dropDividerPosition === 'up' && isOver && ( + { direction === 'up' && isOver && ( )}
    {(!item.children || (item.children && !expanded)) && - targetNode === item.id && - dropDividerPosition === 'down' && + direction === 'down' && isOver && } { { if (item.disabled) { return false @@ -192,7 +190,7 @@ class TreeItem extends Component { > {item.title} {/* {renderRightClickMenu(item)} */} - {targetNode === item.id && dropDividerPosition === 'sub' && isOver && ( + { direction === 'sub' && isOver && ( )} @@ -202,7 +200,7 @@ class TreeItem extends Component { style={item.style} className={`${prefixCls}_item-text ${itemStyle} ${ highlight === item.id ? 'highlight' : '' - } ${draggingNode === item.id ? 'dragging' : ''} ${item.disabled ? prefixCls + '_item-text--disabled' : ''}`} + } ${isDragging ? 'dragging' : ''} ${item.disabled ? prefixCls + '_item-text--disabled' : ''}`} onContextMenu={e => { if (item.disabled) { return false @@ -230,8 +228,8 @@ class TreeItem extends Component { {item.children && item.children.length > 0 && expanded ? renderTree(item.children, [], level + 1) : null} {item.children && expanded && - targetNode === item.id && - dropDividerPosition === 'down' && + + direction === 'down' && isOver && } ) @@ -246,14 +244,6 @@ const source = { } props.onDragStart(props.item) return { sourceItem: props.item, originalExpandStatus: props.expanded, sourceLevel: props.level } - }, - endDrag (props, monitor) { - const dropResult = monitor.getDropResult() - if (!dropResult) { - const { removeTargetNode, removeDraggingNode } = props - removeDraggingNode() - removeTargetNode() - } } } const target = { @@ -262,10 +252,8 @@ const target = { const { item: targetItem, dropNode, - removeDraggingNode, expandTreeNode, - removeTargetNode, - dropDividerPosition, + direction, level } = props // 先看下是不是在最近得组件 @@ -274,51 +262,36 @@ const target = { sourceItem.id === targetItem.id || (targetItem.children && targetItem.children.map(t => t.id).includes(sourceItem.id) && - dropDividerPosition === 'sub') + direction === 'sub') ) { // 如果源节点就是目的节点或者源节点是目的节点的子节点(直系)再或者源节点是目的节点的父节点,那么什么都不做 // 如果什么都不做,原来展开则现在还展开 if (originalExpandStatus) { expandTreeNode(sourceItem.id) } - removeDraggingNode() - removeTargetNode() } else { // 移动节点到相应位置 - dropNode(sourceItem, targetItem, dropDividerPosition, {before: sourceLevel, after: level}) - removeDraggingNode() - removeTargetNode() + dropNode(sourceItem, targetItem, direction, {before: sourceLevel, after: level}) } } }, hover (props, monitor, component) { - const { sourceItem } = monitor.getItem() const { - item: targetItem, - setDraggingNode, - setTargetNode, - positionX, - positionY, - setPosition + setDirection } = props // 先看下是不是在最近得组件 if (monitor.isOver({ shallow: true })) { const sourcePosition = monitor.getClientOffset() const targetComponent = findDOMNode(component).getBoundingClientRect() - if (!(sourcePosition.x === positionX && sourcePosition.y === positionY)) { - setPosition(sourcePosition.x, sourcePosition.y) - // 如果在节点的上半部分,则为移动其内部,如果为下半部分,则为节点下方 - if (sourcePosition.y <= targetComponent.y + targetComponent.height / 3) { - setTargetNode(targetItem.id, 'up') - } else if ( - targetComponent.y + targetComponent.height / 3 < sourcePosition.y && - sourcePosition.y <= targetComponent.y + (targetComponent.height * 2) / 3 - ) { - setTargetNode(targetItem.id, 'sub') - } else { - setTargetNode(targetItem.id, 'down') - } - setDraggingNode(sourceItem.id) + if (sourcePosition.y <= targetComponent.y + targetComponent.height / 3) { + setDirection('up') + } else if ( + targetComponent.y + targetComponent.height / 3 < sourcePosition.y && + sourcePosition.y <= targetComponent.y + (targetComponent.height * 2) / 3 + ) { + setDirection('sub') + } else { + setDirection('down') } } } @@ -332,7 +305,7 @@ function sourceCollect (connect, monitor) { function targetCollect (connect, monitor) { return { connectDropTarget: connect.dropTarget(), - isOver: monitor.isOver() + isOver: monitor.isOver({ shallow: true }) } } @@ -341,11 +314,15 @@ const DraggableTreeItem = DropTarget(Types['TreeNode'], target, targetCollect)( ) const HOCTreeItem = TreeItemComponent => { return class WrapperTreeItem extends Component { + state={direction: null} + setDirection = (direction) => { + this.setState({direction}) + } render () { const { draggable } = this.props return draggable ? ( - + ) : ( ) diff --git a/components/tree/TreeNode.js b/components/tree/TreeNode.js index 711158249..a676504fd 100644 --- a/components/tree/TreeNode.js +++ b/components/tree/TreeNode.js @@ -25,19 +25,11 @@ class TreeNode extends Component { editNodes: [], // 存储编辑节点的状态 editingNodes: [], - // 处于拖拽状态的节点 - draggingNode: null, - // 处于目标状态的节点 - targetNode: null, - // 放置线的位置,分为上线、下线和子线,上线则放置在该节点上方,下线则放置在该节点下侧,子线为放置在该节点内部 - dropDividerPosition: null, searchValue: '', showModal: false, currentDeleteNode: null, // 总共高亮的项 highlightNum: 0, - positionX: null, - positionY: null, contextMenuPanel: null } const { addNode, addChildNode, edit, del } = props.localeDatas.tree @@ -93,15 +85,6 @@ class TreeNode extends Component { } return state } - setPosition = (x, y) => { - const { positionX, positionY } = this.state - if (!(x === positionX && y === positionY)) { - this.setState({ - positionX: x, - positionY: y - }) - } - } // 高亮检索值 highlightData = (data, highlightValue) => { @@ -159,18 +142,6 @@ class TreeNode extends Component { return } - // 设置拖拽中的节点 - setDraggingNode = itemId => { - this.setState({ - draggingNode: itemId - }) - } - // 移除拖拽中的节点 - removeDraggingNode = () => { - this.setState({ - draggingNode: null - }) - } // 添加兄弟节点 _addSibNode = (itemId, data, editingNodes) => { data.forEach((d, index) => { @@ -513,12 +484,6 @@ class TreeNode extends Component { showRightClickMenu: null }) } - setTargetNode = (id, position) => { - this.setState({ targetNode: id, dropDividerPosition: position }) - } - removeTargetNode = () => { - this.setState({ targetNode: null }) - } openModal = () => { this.setState({ showModal: true @@ -553,12 +518,7 @@ class TreeNode extends Component { const { highlight, editNodes, - editingNodes, - draggingNode, - targetNode, - dropDividerPosition, - positionX, - positionY + editingNodes } = this.state return (
      @@ -572,7 +532,6 @@ class TreeNode extends Component { isRoot={allData.some(d => d.id === item.id)} isLevelLast={index === data.length - 1} editable={editable} - dropDividerPosition={dropDividerPosition} prefixCls={prefixCls} draggable={draggable} onDragStart={onDragStart} @@ -590,9 +549,6 @@ class TreeNode extends Component { onExpanded={onExpanded} onValueChange={this.onValueChange} renderTree={this.renderTree} - setPosition={this.setPosition} - positionX={positionX} - positionY={positionY} renderSwitcher={this.renderSwitcher} cancelAddSiblingNode={this.cancelAddSiblingNode} apperance={apperance} @@ -603,13 +559,7 @@ class TreeNode extends Component { showRightClickMenu={this.showRightClickMenu} closeRightClickMenu={this.closeRightClickMenu} dropNode={this.dropNode} - setDraggingNode={this.setDraggingNode} - removeDraggingNode={this.removeDraggingNode} - draggingNode={draggingNode} closeExpandedTreeNode={closeExpandedTreeNode} - setTargetNode={this.setTargetNode} - targetNode={targetNode} - removeTargetNode={this.removeTargetNode} cancelEditNode={this.cancelEditNode} item={item} loadChildren={this.loadChildren} diff --git a/package.json b/package.json index c6d44fa70..759819739 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@hi-ui/hiui", - "version": "2.13.0-rc.4", + "version": "2.13.0-rc.6", "description": "HIUI for React", "scripts": { "test": "node_modules/.bin/standard && node_modules/.bin/stylelint --config .stylelintrc 'components/**/*.scss'", From 5158162a9a507676bf4e24da09a86959b117e6e7 Mon Sep 17 00:00:00 2001 From: Wugaoliang Date: Mon, 13 Apr 2020 16:35:39 +0800 Subject: [PATCH 12/90] fix: #1027 --- components/menu/Menu.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/menu/Menu.js b/components/menu/Menu.js index 0973a9023..f55557c0d 100644 --- a/components/menu/Menu.js +++ b/components/menu/Menu.js @@ -1,4 +1,5 @@ import React, { Component } from 'react' +import _ from 'lodash' import PropTypes from 'prop-types' import classNames from 'classnames' import Title from './Title' @@ -28,7 +29,7 @@ class Menu extends Component { } componentWillReceiveProps (nextProps) { - if (nextProps.activeId !== this.props.activeId) { + if (nextProps.activeId !== this.props.activeId || !_.isEqual(nextProps.data, this.props.data)) { const activeIndex = this.getActiveIndex(nextProps.activeId, nextProps.data) this.setState({ From 1c8d7e310baf8c1cc9c856ac2e86b0e3839d6166 Mon Sep 17 00:00:00 2001 From: Wugaoliang Date: Tue, 14 Apr 2020 09:54:21 +0800 Subject: [PATCH 13/90] fix: #1029 --- components/menu/Menu.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/components/menu/Menu.js b/components/menu/Menu.js index f55557c0d..a45780865 100644 --- a/components/menu/Menu.js +++ b/components/menu/Menu.js @@ -29,18 +29,28 @@ class Menu extends Component { } componentWillReceiveProps (nextProps) { - if (nextProps.activeId !== this.props.activeId || !_.isEqual(nextProps.data, this.props.data)) { - const activeIndex = this.getActiveIndex(nextProps.activeId, nextProps.data) + const { activeId, data, collapsed } = nextProps + if (activeId !== this.props.activeId || !_.isEqual(data, this.props.data)) { + const activeIndex = this.getActiveIndex(activeId, data) this.setState({ - activeId: nextProps.activeId, + activeId: activeId, activeIndex }) + this.isNoMiniVertaicalMenu(collapsed) && + this.setState({ + expandIndex: [ + activeIndex + .split('-') + .slice(0, -1) + .join('-') + ] + }) } - if (nextProps.collapsed !== this.props.collapsed) { + if (collapsed !== this.props.collapsed) { this.setState({ - collapsed: nextProps.collapsed + collapsed: collapsed }) } } From 0f71fa5ab33e9073c7d701f12c1f0b8baac40f09 Mon Sep 17 00:00:00 2001 From: Wugaoliang Date: Wed, 15 Apr 2020 11:41:16 +0800 Subject: [PATCH 14/90] fix: hotfix/#1032 --- components/upload/upload-legacy/Upload.js | 3 ++- docs/demo/collapse/section-accordion.jsx | 2 +- docs/demo/collapse/section-basic.jsx | 2 +- docs/demo/upload/section-custom.jsx | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/components/upload/upload-legacy/Upload.js b/components/upload/upload-legacy/Upload.js index e6e71d264..cf146ea0c 100644 --- a/components/upload/upload-legacy/Upload.js +++ b/components/upload/upload-legacy/Upload.js @@ -49,7 +49,7 @@ class Upload extends Component { fileType = 'zip' break case 'doc': - case 'dcox': + case 'docx': fileType = 'word' break case 'pdf': @@ -119,6 +119,7 @@ class Upload extends Component { file.fileId = this.getFileId() file.uploadState = 'loading' file.fileType = this.getFileType(file) + console.log('file.fileType ', this.getFileType(file), file) fileList.unshift(file) this.setState({ fileList }) this.uploadFile(file) diff --git a/docs/demo/collapse/section-accordion.jsx b/docs/demo/collapse/section-accordion.jsx index 34fce843a..00bb0eefb 100644 --- a/docs/demo/collapse/section-accordion.jsx +++ b/docs/demo/collapse/section-accordion.jsx @@ -7,7 +7,7 @@ const desc = '一次仅展开一个面板,有效减少垂直空间的占用' const code = [ { code: `import React from 'react' -import Checkbox from '@hi-ui/hiui/es/checkbox'\n +import Collapse from '@hi-ui/hiui/es/collapse'\n class Demo extends React.Component { render(){ return( diff --git a/docs/demo/collapse/section-basic.jsx b/docs/demo/collapse/section-basic.jsx index a4eb3b126..91b80b134 100644 --- a/docs/demo/collapse/section-basic.jsx +++ b/docs/demo/collapse/section-basic.jsx @@ -7,7 +7,7 @@ const desc = '可以同时展开多个面板,对垂直空间没有特别限制 const code = [ { code: `import React from 'react' -import Checkbox from '@hi-ui/hiui/es/checkbox'\n +import Collapse from '@hi-ui/hiui/es/collapse'\n class Demo extends React.Component { render(){ return( diff --git a/docs/demo/upload/section-custom.jsx b/docs/demo/upload/section-custom.jsx index 0ef32a86b..70fad3cc8 100644 --- a/docs/demo/upload/section-custom.jsx +++ b/docs/demo/upload/section-custom.jsx @@ -39,7 +39,7 @@ class Demo extends React.Component { customUpload={files => { const _fileList = fileList.concat({ name: files[0].name, - fileType: 'img', + fileType: files[0].name.slice(files[0].name.lastIndexOf('.') + 1).toLowerCase(), uploadState: 'success' }) this.setState({ From 20d280e1c7d27573f1a7efd105d0fc6d3fd48f90 Mon Sep 17 00:00:00 2001 From: Wugaoliang Date: Thu, 16 Apr 2020 18:04:57 +0800 Subject: [PATCH 15/90] fix: #1032 --- components/upload/Upload.js | 4 +++- components/upload/UploadPhoto.js | 27 ++++++++++++++++++++---- components/upload/style/index.scss | 34 ++++++++++++++++++++++++++---- components/watermark/index.js | 2 +- docs/zh-CN/components/upload.mdx | 2 +- 5 files changed, 58 insertions(+), 11 deletions(-) diff --git a/components/upload/Upload.js b/components/upload/Upload.js index 7b5e1622c..373b7a9b6 100644 --- a/components/upload/Upload.js +++ b/components/upload/Upload.js @@ -217,7 +217,9 @@ class Upload extends Component { const XMLHttpRequest = window.XMLHttpRequest const FormData = window.FormData const { fileList } = this.state - const { name, params, headers, uploadAction, withCredentials } = this.props + const { name, params, headers, uploadAction, withCredentials, maxCount } = this.props + + this.setState({ fileCountLimted: fileList.length >= maxCount }) const onerror = err => { const { fileList } = this.state const errRes = err !== undefined ? err : { status: xhr.status, statusText: xhr.statusText } diff --git a/components/upload/UploadPhoto.js b/components/upload/UploadPhoto.js index 64217ab7c..0a108cda1 100644 --- a/components/upload/UploadPhoto.js +++ b/components/upload/UploadPhoto.js @@ -48,7 +48,8 @@ class UploadPhoto extends Upload { disabled, accept, localeDatas, - theme + theme, + size = 'default' } = this.props const images = fileList.map(file => { return { @@ -70,7 +71,11 @@ class UploadPhoto extends Upload { {fileList.map((file, index) => { if (file.uploadState === 'loading') { return ( -
    • +
    • {file.progressNumber ? (file.progressNumber < 100 ? (file.progressNumber + '%') : localeDatas.upload.uploadSuccess) : (0 + '%')}

      @@ -82,7 +87,15 @@ class UploadPhoto extends Upload { ) } else { return ( -
    • this.previewImage(file, index)}> +
    • this.previewImage(file, index)} + > { onRemove && { @@ -100,7 +113,13 @@ class UploadPhoto extends Upload { } })} { - !fileCountLimted &&
    • + !fileCountLimted &&
    • } From 354607f3b55d8130e56a5a831508a6b963310f59 Mon Sep 17 00:00:00 2001 From: Wugaoliang Date: Tue, 21 Apr 2020 16:21:51 +0800 Subject: [PATCH 28/90] fix: #1042 --- components/form/style/index.scss | 10 ++++++++-- docs/demo/form/section-check.jsx | 5 ++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/components/form/style/index.scss b/components/form/style/index.scss index 26bec0bb1..6fd7290eb 100644 --- a/components/form/style/index.scss +++ b/components/form/style/index.scss @@ -95,8 +95,14 @@ } &__error { - .hi-form-item__content .hi-input__inner { - border-color: get-color($palette-secondary, 'danger'); + .hi-form-item__content { + .hi-input__inner, + .hi-select__input, + .hi-cascader__input-container, + .hi-datepicker__input, + .hi-input { + border-color: get-color($palette-secondary, 'danger'); + } } } diff --git a/docs/demo/form/section-check.jsx b/docs/demo/form/section-check.jsx index 9fa15d46a..6207a127e 100644 --- a/docs/demo/form/section-check.jsx +++ b/docs/demo/form/section-check.jsx @@ -5,6 +5,9 @@ import Input from '../../../components/input' import Grid from '../../../components/grid' import Radio from '../../../components/radio' import Button from '../../../components/button' +import Select from '../../../components/select' +import Cascader from '../../../components/cascader' +import DatePicker from '../../../components/date-picker' const prefix = 'form-check' const desc = '表单项内容的格式、逻辑有特殊要求' const code = `import React from 'react' @@ -120,7 +123,7 @@ class Demo extends React.Component { const DemoCloseable = () => ( From 2503dc5da7e427ec3c7385b41deb573877a8216f Mon Sep 17 00:00:00 2001 From: Wugaoliang Date: Tue, 21 Apr 2020 16:47:50 +0800 Subject: [PATCH 29/90] fix: #1042 --- components/form/style/index.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/components/form/style/index.scss b/components/form/style/index.scss index 6fd7290eb..ded932442 100644 --- a/components/form/style/index.scss +++ b/components/form/style/index.scss @@ -100,6 +100,7 @@ .hi-select__input, .hi-cascader__input-container, .hi-datepicker__input, + .tree-select__tag-wrapper, .hi-input { border-color: get-color($palette-secondary, 'danger'); } From b22e30341eaa8072ebf9057637e2af3653493463 Mon Sep 17 00:00:00 2001 From: solarjoker Date: Tue, 21 Apr 2020 21:58:45 +0800 Subject: [PATCH 30/90] docs: update button doc --- docs/zh-CN/components/button.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/zh-CN/components/button.mdx b/docs/zh-CN/components/button.mdx index a93678da9..2c6d0e7b0 100755 --- a/docs/zh-CN/components/button.mdx +++ b/docs/zh-CN/components/button.mdx @@ -56,6 +56,7 @@ import DemoGroup from '../../demo/button/section-group.jsx' | ---------- | --------------------------------------------- | ----------------------- | --------------------------------------------------------- | --------- | | type | 设置按钮类型 | string | 'primary' \| 'line' \| 'success' \| 'danger' \| 'default' | 'default' | | appearance | 设置按钮外观 | string | 'link' \| 'button' | 'button' | +| disabled | 设置按钮是否禁用 | boolean | true \| false | false | | size | 设置按钮尺寸 | string | 'large' \| 'default' \| 'small' | 'default' | | icon | 设置按钮图标 | string | 详见 [``](/hiui/zh-CN/docs/icon) 组件 ︎ | - | | href | 设置按钮链接,设置后将用 a 标签渲染按钮 | string | ︎ | - | From 1acf1c3360d747e5c90d80c5b45c2d4f9bbf08d1 Mon Sep 17 00:00:00 2001 From: wugaoliang Date: Tue, 21 Apr 2020 22:25:46 +0800 Subject: [PATCH 31/90] fix: #1044 --- components/select/Select.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/select/Select.js b/components/select/Select.js index a9a439b03..d5417fadc 100644 --- a/components/select/Select.js +++ b/components/select/Select.js @@ -190,7 +190,7 @@ class Select extends Component { selectedItems.push(item) } }) - return reviceSelectedItems.concat(selectedItems) + return _.uniqBy(reviceSelectedItems.concat(selectedItems), 'id') } onEnterSelect () { From 7c6f7f8259ecd86723ce956a21bdab49d4e7a70e Mon Sep 17 00:00:00 2001 From: solarjoker Date: Wed, 22 Apr 2020 10:12:34 +0800 Subject: [PATCH 32/90] fix: #1046 --- components/tabs/style/index.scss | 286 ++++++++++++++++--------------- 1 file changed, 150 insertions(+), 136 deletions(-) diff --git a/components/tabs/style/index.scss b/components/tabs/style/index.scss index f85f2fc84..fb62e56fa 100644 --- a/components/tabs/style/index.scss +++ b/components/tabs/style/index.scss @@ -48,25 +48,27 @@ $prefix: 'hi-tabs' !default; } &--card { - .#{$prefix}__nav { - display: flex; - flex-wrap: nowrap; - } + & > .#{$prefix}__header { + .#{$prefix}__nav { + display: flex; + flex-wrap: nowrap; + } - .#{$prefix}__item { - height: 48px; - line-height: 46px; - padding: 0 16px; - box-sizing: border-box; + .#{$prefix}__item { + height: 48px; + line-height: 46px; + padding: 0 16px; + box-sizing: border-box; - &:hover { - color: #4284f5; - } + &:hover { + color: #4284f5; + } - &--active { - border: 1px solid #e6e7e8; - border-radius: 2px; - color: #4284f5; + &--active { + border: 1px solid #e6e7e8; + border-radius: 2px; + color: #4284f5; + } } } } @@ -113,126 +115,130 @@ $prefix: 'hi-tabs' !default; } &--editable { - .#{$prefix}__nav { - display: flex; - flex-wrap: nowrap; - overflow: hidden; - margin-bottom: -1px; - margin-right: 40px; - min-height: 40px; - } - - .#{$prefix}__header { + & > .#{$prefix}__header { border-bottom: 1px solid #e6e7e8; - } - .#{$prefix}__item { - height: 40px; - min-width: 48px; - line-height: 40px; - margin-right: 4px; - padding: 0 8px; - background: #fafafa; - border-radius: 2px 2px 0 0; - border: 1px solid #e6e7e8; - text-align: center; - box-sizing: border-box; - - &:last-child { - margin-right: 0; + .#{$prefix}__nav { + display: flex; + flex-wrap: nowrap; + overflow: hidden; + margin-bottom: -1px; + margin-right: 40px; + min-height: 40px; } - &:hover:not(.#{$prefix}__item--active) { - background-color: #f0f0f0; - } + .#{$prefix}__item { + height: 40px; + min-width: 48px; + line-height: 40px; + margin-right: 4px; + padding: 0 8px; + background: #fafafa; + border-radius: 2px 2px 0 0; + border: 1px solid #e6e7e8; + text-align: center; + box-sizing: border-box; - &--active { - background-color: #fff; - border-bottom-color: #fff; - color: #4284f5; + &:last-child { + margin-right: 0; + } + + &:hover:not(.#{$prefix}__item--active) { + background-color: #f0f0f0; + } + + &--active { + background-color: #fff; + border-bottom-color: #fff; + color: #4284f5; + } } - } - .#{$prefix}__add { - right: 4px; - bottom: 12px; + .#{$prefix}__add { + right: 4px; + bottom: 12px; + } } } &--desc { - .#{$prefix}__nav { - display: flex; - flex-wrap: nowrap; - overflow: hidden; - } - - .#{$prefix}__item { - flex: none; - display: flex; - flex-direction: column; - padding: 16px 20px; - text-align: center; - border: 1px solid #e6e7e8; - box-sizing: border-box; - - &:not(:first-child) { - margin-left: -1px; + & > .#{$prefix}__header { + .#{$prefix}__nav { + display: flex; + flex-wrap: nowrap; + overflow: hidden; } - &:hover { - color: #4284f5; + .#{$prefix}__item { + flex: none; + display: flex; + flex-direction: column; + padding: 16px 20px; + text-align: center; + border: 1px solid #e6e7e8; + box-sizing: border-box; - .#{$prefix}__item-desc { - color: #4284f5; + &:not(:first-child) { + margin-left: -1px; } - } - &--active { - color: #4284f5; - border-color: #4284f5; - z-index: 1; + &:hover { + color: #4284f5; - .#{$prefix}__item-desc { + .#{$prefix}__item-desc { + color: #4284f5; + } + } + + &--active { color: #4284f5; + border-color: #4284f5; + z-index: 1; + + .#{$prefix}__item-desc { + color: #4284f5; + } } - } - &-name { - margin-top: 4px; - } + &-name { + margin-top: 4px; + } - &-desc { - font-size: 12px; - color: #999; + &-desc { + font-size: 12px; + color: #999; + } } } } &--button { - .#{$prefix}__nav { - display: flex; - flex-wrap: wrap; - } - - .#{$prefix}__item { - flex: none; - height: 36px; - line-height: 34px; - padding: 0 23px; - box-sizing: border-box; - margin-right: 24px; - border: 1px solid #d8d8d8; - border-radius: 18px; - - &:hover:not(.hi-tabs__item--active) { - color: #4284f5; - border: 1px solid #4284f5; + & > .#{$prefix}__header { + .#{$prefix}__nav { + display: flex; + flex-wrap: wrap; } - &--active { - color: #fff; - background-color: #4284f5; - border: 1px solid #4284f5; + .#{$prefix}__item { + flex: none; + height: 36px; + line-height: 34px; + padding: 0 23px; + box-sizing: border-box; + margin-right: 24px; + border: 1px solid #d8d8d8; + border-radius: 18px; + + &:hover:not(.hi-tabs__item--active) { + color: #4284f5; + border: 1px solid #4284f5; + } + + &--active { + color: #fff; + background-color: #4284f5; + border: 1px solid #4284f5; + } } } } @@ -277,56 +283,64 @@ $prefix: 'hi-tabs' !default; @each $key, $value in $theme-colors { .theme__#{$key}.#{$prefix} { &--card { - .#{$prefix}__item { - &:hover { - color: $value; - } + & > .#{$prefix}__header { + .#{$prefix}__item { + &:hover { + color: $value; + } - &--active { - color: $value; + &--active { + color: $value; + } } } } &--editable { - .#{$prefix}__item { - &--active { - color: $value; + & > .#{$prefix}__header { + .#{$prefix}__item { + &--active { + color: $value; + } } } } &--desc { - .#{$prefix}__item { - &:hover { - color: $value; - - .#{$prefix}__item-desc { + & > .#{$prefix}__header { + .#{$prefix}__item { + &:hover { color: $value; - } - } - &--active { - color: $value; - border-color: $value; + .#{$prefix}__item-desc { + color: $value; + } + } - .#{$prefix}__item-desc { + &--active { color: $value; + border-color: $value; + + .#{$prefix}__item-desc { + color: $value; + } } } } } &--button { - .#{$prefix}__item { - &:hover:not(.hi-tabs__item--active) { - color: $value; - border: 1px solid $value; - } + & > .#{$prefix}__header { + .#{$prefix}__item { + &:hover:not(.hi-tabs__item--active) { + color: $value; + border: 1px solid $value; + } - &--active { - background-color: $value; - border: 1px solid $value; + &--active { + background-color: $value; + border: 1px solid $value; + } } } } From b083db2bd8dafd269c5ec78597e8022c5e07a268 Mon Sep 17 00:00:00 2001 From: Wugaoliang Date: Thu, 23 Apr 2020 09:33:27 +0800 Subject: [PATCH 33/90] fix: #1039 --- components/date-picker/Calender.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/date-picker/Calender.js b/components/date-picker/Calender.js index 0d6e1b750..18b7628e1 100644 --- a/components/date-picker/Calender.js +++ b/components/date-picker/Calender.js @@ -166,7 +166,9 @@ class Calender extends Component { newDate = addMonths(newDate, 1) } - !(type === 'year' || type === 'month') && newDate.setDate(clickVal) + if (!(type === 'year' || type === 'month')) { + newDate.setDate(clickVal) + } if (type === 'daterange' || type === 'weekrange') { if (range.selecting) { From ac065b8123d8b68d09aa6f578de95375c8377a89 Mon Sep 17 00:00:00 2001 From: Wugaoliang Date: Thu, 23 Apr 2020 09:56:30 +0800 Subject: [PATCH 34/90] fix: #1032 --- components/upload/UploadDrag.js | 2 +- components/upload/UploadPhoto.js | 8 ++++---- docs/zh-CN/components/upload.mdx | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/components/upload/UploadDrag.js b/components/upload/UploadDrag.js index a9d9481ae..d27bdb8c5 100644 --- a/components/upload/UploadDrag.js +++ b/components/upload/UploadDrag.js @@ -119,7 +119,7 @@ class UploadDrag extends Upload { {fileCountLimted ? localeDatas.upload.dragTipsLimited : localeDatas.upload.dragTips} - {tips && ',' + tips} + {tips && (',' + tips)} } diff --git a/components/upload/UploadPhoto.js b/components/upload/UploadPhoto.js index 0a108cda1..975897d8b 100644 --- a/components/upload/UploadPhoto.js +++ b/components/upload/UploadPhoto.js @@ -49,7 +49,7 @@ class UploadPhoto extends Upload { accept, localeDatas, theme, - size = 'default' + photoSize = 'default' } = this.props const images = fileList.map(file => { return { @@ -74,7 +74,7 @@ class UploadPhoto extends Upload {
    • @@ -91,7 +91,7 @@ class UploadPhoto extends Upload { key={index} className={classNames( 'hi-upload__item', - `hi-upload__item--${size}` + `hi-upload__item--${photoSize}` )} style={{cursor: 'pointer'}} onClick={() => this.previewImage(file, index)} @@ -117,7 +117,7 @@ class UploadPhoto extends Upload { className={classNames( 'hi-upload__item', 'hi-upload__item--upload', - `hi-upload__item--${size}` + `hi-upload__item--${photoSize}` )} >
    • + {layout === 'normal' && type === 'default' && ( +
    • + ) + } + /** + * 渲染列表,被递归调用 + * @param {Array} datas 数据 + * @param {String | React.ReactNode} groupTitle 分组标题 + * @param {Number} originIndex 原始索引,用于判断是否为第一个分组标题 + */ + renderItems (data, groupTitle, isSub) { + const { layout, localeDatas, type } = this.props + return data.map((item, index) => { + const { groupTitle: gt } = item + if (gt) { + // 渲染分组 + return this.renderItems(item.children, gt) + } + if (item.children && layout !== 'cross' && type !== 'cross') { + // 子项 含 收起按钮 + const foldingEl = ( + + ) + // 如果含有子项,需先渲染当前项 + let el = this.renderItem(item, index, groupTitle) + return [el, foldingEl] + } + return this.renderItem(item, index, groupTitle, isSub) + }) + } + + render () { + const { layout, type, list, data, theme } = this.props + const _layout = type === 'default' ? layout : type + const rootCls = classNames('hi-timeline', `theme__${theme}`, `hi-timeline--${_layout}`) + return ( +
      +
        {this.renderItems(data || list)}
      +
      + ) + } +} +Timeline.defaultProps = { + layout: 'normal', // TODO:废弃,使用 type + type: 'default' +} +export default Provider(Timeline) diff --git a/components/timeline/index.js b/components/timeline/index.js index 62b0312eb..076948313 100644 --- a/components/timeline/index.js +++ b/components/timeline/index.js @@ -5,14 +5,11 @@ import './style/index' import FoldingItem from './FoldingItem' import Icon from '../icon' -const Time = props => { +const Time = (props) => { return (
      {props.groupTitle && ( -
      +
      {props.groupTitle}
      )} @@ -29,88 +26,129 @@ class Timeline extends Component { * @param {*} groupTitle 分组标题 * @param {*} isSub 是否是子项,只支持一级 */ - renderItem (item, index, groupTitle, isSub) { - const { layout, type } = this.props - // TODO: dot 废弃,使用 icon - const dot = item.dot - const icon = item.icon - let dotEl = isSub ? ( -
      - ) : ( -
      - ) - if (dot && typeof dot === 'object') { - dotEl =
      {dot}
      - } - if (icon && typeof icon === 'string') { - dotEl = ( -
      - -
      - ) - } else if (icon && React.isValidElement(icon)) { - dotEl =
      {icon}
      - } - const itemCls = classNames('hi-timeline__item', isSub && 'hi-timeline__item--sub') - return ( -
    • - {layout === 'normal' && type === 'default' && ( -
    • - ) - } + // renderItem (item, index, groupTitle, isSub) { + // const { layout, type } = this.props + // // TODO: dot 废弃,使用 icon + // const dot = item.dot + // const icon = item.icon + // let dotEl = isSub ? ( + //
      + // ) : ( + //
      + // ) + // if (dot && typeof dot === 'object') { + // dotEl =
      {dot}
      + // } + // if (icon && typeof icon === 'string') { + // dotEl = ( + //
      + // + //
      + // ) + // } else if (icon && React.isValidElement(icon)) { + // dotEl =
      {icon}
      + // } + // const itemCls = classNames('hi-timeline__item', isSub && 'hi-timeline__item--sub') + // return ( + //
    • + // {layout === 'normal' && type === 'default' && ( + //
    • + // ) + // } /** * 渲染列表,被递归调用 * @param {Array} datas 数据 * @param {String | React.ReactNode} groupTitle 分组标题 * @param {Number} originIndex 原始索引,用于判断是否为第一个分组标题 */ - renderItems (data, groupTitle, isSub) { - const { layout, localeDatas, type } = this.props - return data.map((item, index) => { - const { groupTitle: gt } = item - if (gt) { - // 渲染分组 - return this.renderItems(item.children, gt) - } - if (item.children && layout !== 'cross' && type !== 'cross') { - // 子项 含 收起按钮 - const foldingEl = ( - - ) - // 如果含有子项,需先渲染当前项 - let el = this.renderItem(item, index, groupTitle) - return [el, foldingEl] - } - return this.renderItem(item, index, groupTitle, isSub) - }) + // renderItems (data, groupTitle, isSub) { + // const { layout, localeDatas, type } = this.props + // return data.map((item, index) => { + // const { groupTitle: gt } = item + // if (gt) { + // // 渲染分组 + // return this.renderItems(item.children, gt) + // } + // if (item.children && layout !== 'cross' && type !== 'cross') { + // // 子项 含 收起按钮 + // const foldingEl = ( + // + // ) + // // 如果含有子项,需先渲染当前项 + // let el = this.renderItem(item, index, groupTitle) + // return [el, foldingEl] + // } + // return this.renderItem(item, index, groupTitle, isSub) + // }) + // } + renderGroup = (item) => { + return ( +
      +
      {item.groupTitle}
      +
      {item.children.map((i) => this.renderItem(i))}
      +
      + ) + } + + renderItem = (item) => { + return ( +
      +
      {item.title}
      +
      {item.content}
      +
      {item.timestamp}
      +
      {item.extraTime}
      +
      + ) } + renderDefault = (item) => { + return ( +
      +
      +
      {item.timestamp}
      +
      {item.extraTime}
      +
      +
      +
      {item.title}
      +
      {item.content}
      +
      +
      + ) + } render () { const { layout, type, list, data, theme } = this.props const _layout = type === 'default' ? layout : type const rootCls = classNames('hi-timeline', `theme__${theme}`, `hi-timeline--${_layout}`) return (
      -
        {this.renderItems(data || list)}
      +
        + {(data || list).map((item) => { + if (item.groupTitle) { + return this.renderGroup(item) + } else { + return this.renderItem(item) + } + })} +
      ) } diff --git a/package.json b/package.json index 759819739..0bedbfd3c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@hi-ui/hiui", - "version": "2.13.0-rc.6", + "version": "2.13.0-rc.12", "description": "HIUI for React", "scripts": { "test": "node_modules/.bin/standard && node_modules/.bin/stylelint --config .stylelintrc 'components/**/*.scss'", From c2dcaf1819c4b015f1791b766b8d15e8c9b73128 Mon Sep 17 00:00:00 2001 From: solarjoker Date: Tue, 28 Apr 2020 02:26:46 +0800 Subject: [PATCH 38/90] feat: update timeline --- components/timeline/index.js | 116 +++++-- components/timeline/style/index.scss | 475 ++++++++++++++++----------- docs/demo/timeline/section-cross.jsx | 69 ++-- 3 files changed, 404 insertions(+), 256 deletions(-) diff --git a/components/timeline/index.js b/components/timeline/index.js index 076948313..b0d073e09 100644 --- a/components/timeline/index.js +++ b/components/timeline/index.js @@ -100,36 +100,101 @@ class Timeline extends Component { // return this.renderItem(item, index, groupTitle, isSub) // }) // } - renderGroup = (item) => { + renderGroup = (item, index, isLast) => { return (
      -
      {item.groupTitle}
      -
      {item.children.map((i) => this.renderItem(i))}
      +
      + {item.groupTitle} + {index !== 0 &&
      } +
      +
      + {item.children.map((i, idx) => { + const isFirst = index === 0 && idx === 0 + const _isLast = isLast && idx === item.children.length - 1 + return this.renderItem(i, idx, _isLast, isFirst) + })} +
      ) } - renderItem = (item) => { + renderItem = (item, index, isLast, isFirst) => { + if (this.props.type === 'default') { + return this.renderDefault(item, index, isLast, isFirst) + } + if (this.props.type === 'right') { + return this.renderRight(item, index, isLast, isFirst) + } + if (this.props.type === 'cross') { + return this.renderCross(item, index, isLast, isFirst) + } + } + + renderRight = (item, index, isLast, isFirst) => { return ( -
      -
      {item.title}
      -
      {item.content}
      -
      {item.timestamp}
      -
      {item.extraTime}
      +
      +
      {item.title}
      +
      {item.content}
      +
      + {item.timestamp} {item.extraTime} +
      + +
      +
      ) } - renderDefault = (item) => { + renderCross = (item, index, isLast, isFirst) => { return ( -
      -
      -
      {item.timestamp}
      -
      {item.extraTime}
      +
      +
      +
      {item.timestamp}
      +
      {item.extraTime}
      -
      -
      {item.title}
      -
      {item.content}
      +
      +
      +
      +
      {item.title}
      +
      {item.content}
      +
      +
      + ) + } + + renderDefault = (item, index, isLast, isFirst) => { + return ( +
      +
      +
      {item.timestamp}
      +
      {item.extraTime}
      +
      +
      +
      +
      +
      {item.title}
      +
      {item.content}
      ) @@ -137,15 +202,24 @@ class Timeline extends Component { render () { const { layout, type, list, data, theme } = this.props const _layout = type === 'default' ? layout : type - const rootCls = classNames('hi-timeline', `theme__${theme}`, `hi-timeline--${_layout}`) + const rootCls = classNames( + 'hi-timeline', + `theme__${theme}`, + `hi-timeline--${ + ['normal', 'default'].includes(_layout) ? 'default' : _layout + }` + ) return (
        - {(data || list).map((item) => { + {(data || list).map((item, index) => { if (item.groupTitle) { - return this.renderGroup(item) + const isLast = index === (data || list).length - 1 + return this.renderGroup(item, index, isLast) } else { - return this.renderItem(item) + const isLast = index === (data || list).length - 1 + const isFirst = index === 0 + return this.renderItem(item, index, isLast, isFirst) } })}
      diff --git a/components/timeline/style/index.scss b/components/timeline/style/index.scss index 96171ee57..0fd310116 100755 --- a/components/timeline/style/index.scss +++ b/components/timeline/style/index.scss @@ -2,248 +2,351 @@ .hi-timeline { position: relative; - padding: 8px; + padding: 4px; ul { margin: 0 !important; padding: 0 !important; } - &__item { - margin: 0; - padding: 0; - list-style: none; - display: flex; - position: relative; - padding-bottom: 10px; - - &:last-child { - .hi-timeline__line { - display: none; - } - } - - &--folding { + &--cross { + .timeline__item { position: relative; - padding-bottom: 20px; - display: block; - margin-top: 0 !important; + margin-bottom: 20px; + display: flex; - .hi-timeline__line { - z-index: 1; - } - } - - &--sub { - &:last-child { - padding-bottom: 40px; + &--last { + margin-bottom: 0; - .hi-timeline__line { - display: block; + .item__line { + height: 100% !important; } } - } - } - &__arrow { - position: absolute; - left: 74px; - bottom: 8px; - cursor: pointer; - } - - &__row { - margin-left: 40px; - display: flex; - } + &--first { + .item__line { + top: 7px; + height: calc(100% + 20px - 7px) !important; + } + } - &__content-container { - display: inline-block; - } + &--left { + width: calc(50% - 20px); + margin-right: calc(50% + 20px); + flex-direction: row-reverse; + + .item__dot { + width: 8px; + height: 8px; + border: 2px solid #4284f5; + background: #fff; + border-radius: 50%; + box-sizing: border-box; + position: absolute; + top: 7px; + right: -20px; + transform: translateX(50%); + z-index: 2; + } - &__time { - flex: 0 0 36px; - text-align: right; - display: inline-block; - vertical-align: top; - - &--extra { - width: auto; - text-align: left; - font-size: 12px; - color: #999; - margin-top: 6px; - } - } + .item__line { + position: absolute; + right: -20px; + width: 2px; + background: rgb(242, 242, 242); + height: calc(100% + 20px); + transform: translateX(50%); + } - &__extra-time { - font-size: 12px; - color: #666; - margin-top: 2px; - } + .item--left { + text-align: right; + width: calc(30% - 20px); + margin-left: 20px; + + .item__time { + color: rgb(51, 51, 51); + font-size: 14px; + line-height: 22px; + margin-bottom: 2px; + } + + .item__extra { + color: rgb(158, 158, 158); + font-size: 12px; + line-height: 20px; + } + } - &__title { - font-size: 14px; - color: #333; - text-align: left; - } + .item--right { + text-align: right; + width: 70%; + + .item__title { + color: rgb(51, 51, 51); + font-size: 14px; + line-height: 22px; + margin-bottom: 2px; + } + + .item__content { + color: rgb(158, 158, 158); + font-size: 12px; + line-height: 20px; + } + } + } - &__desc { - margin-top: 8px; - font-size: 12px; - color: #666; - } + &--right { + width: calc(50% - 20px); + margin-left: calc(50% + 20px); + + .item__dot { + width: 8px; + height: 8px; + border: 2px solid #4284f5; + background: #fff; + border-radius: 50%; + box-sizing: border-box; + position: absolute; + top: 7px; + left: -20px; + transform: translateX(-50%); + z-index: 2; + } - &__line { - position: absolute; - top: 0.75em; - height: 100%; - width: 2px; - background: rgba(242, 242, 242, 1); - left: 55px; - // border-left: 2px solid #e8e8e8; - } + .item__line { + position: absolute; + left: -20px; + width: 2px; + background: rgb(242, 242, 242); + height: calc(100% + 20px); + transform: translateX(-50%); + } - &__dot { - width: 8px; - height: 8px; - border: 2px solid #4284f5; - border-radius: 50%; - box-sizing: border-box; - position: absolute; - top: 0.5em; - left: 52px; - z-index: 2; - - &--sub { - width: 6px; - height: 6px; - border: 0; - background: #4284f5; - left: 53px; - } + .item--left { + width: calc(30% - 20px); + margin-right: 20px; + + .item__time { + color: rgb(51, 51, 51); + font-size: 14px; + line-height: 22px; + margin-bottom: 2px; + } + + .item__extra { + color: rgb(158, 158, 158); + font-size: 12px; + line-height: 20px; + } + } - &--custom { - border: none; - border-radius: 0; - font-size: 12px; - width: auto; - height: auto; - // left: 4px; - background: #fff; - transform: translate(-50%, -30%); + .item--right { + width: 70%; + + .item__title { + color: rgb(51, 51, 51); + font-size: 14px; + line-height: 22px; + margin-bottom: 2px; + } + + .item__content { + color: rgb(158, 158, 158); + font-size: 12px; + line-height: 20px; + } + } + } } } &--right { - .hi-timeline__line { - left: 3px; - } - - .hi-timeline__row { + .timeline__item { + position: relative; + margin-bottom: 20px; margin-left: 24px; - } - .hi-timeline__dot { - left: 0; + .item__title { + color: rgb(51, 51, 51); + font-size: 14px; + line-height: 22px; + margin-bottom: 2px; + } - &--custom { - left: 4px; + .item__content { + color: #666; + font-size: 12px; + line-height: 20px; + margin-bottom: 6px; } - &--sub { - left: 1px; + .item__time { + color: #999; + font-size: 12px; + line-height: 20px; } - } - .hi-timeline__arrow { - left: 40px; - } - } + &--last { + &.timeline__item { + margin-bottom: 0; + + .item__line { + height: calc(100%); + } + } + } + + &--first { + &.timeline__item { + .item__line { + top: 7px; + height: calc(100% + 20px - 7px); + } + } + } + + .item__dot { + width: 8px; + height: 8px; + border: 2px solid #4284f5; + background: #fff; + border-radius: 50%; + box-sizing: border-box; + position: absolute; + top: 7px; + left: -20px; + transform: translateX(-50%); + z-index: 2; + } - &--normal { - .hi-timeline__dot { - &--custom { - left: 56px; + .item__line { + position: absolute; + left: -22px; + top: 0; + width: 2px; + background: rgb(242, 242, 242); + height: calc(100% + 20px); + transform: translateX(50%); } } } - &--cross { - .hi-timeline__row { - width: 50%; + &--default { + .timeline__group-title { + text-align: right; + width: calc(30% - 20px); + margin-right: 20px; + margin-bottom: 10px; + color: rgb(0, 0, 0); + font-weight: bolder; + position: relative; + + .item__line { + position: absolute; + top: 0; + left: calc(100% + 20px); + right: 0; + width: 2px; + background: #f2f2f2; + height: calc(100% + 10px); + transform: translateX(-50%); + } } - .hi-timeline__item:nth-child(even) { - .hi-timeline__row { - margin-left: -19px; + .timeline__item { + display: flex; + position: relative; + + .item--left { text-align: right; - display: inline-block; + width: calc(30% - 20px); + margin-right: 20px; - .hi-timeline__time { - float: right; + .item__time { + color: rgb(51, 51, 51); + font-size: 14px; + line-height: 22px; + margin-bottom: 2px; } - } - .hi-timeline__content-container { - margin-right: 20px; + .item__extra { + color: rgb(158, 158, 158); + font-size: 12px; + line-height: 20px; + } } - .hi-timeline__title { - text-align: right; + .item__dot { + width: 8px; + height: 8px; + border: 2px solid #4284f5; + background: #fff; + border-radius: 50%; + box-sizing: border-box; + position: absolute; + top: 7px; + left: 30%; + transform: translateX(-50%); + z-index: 2; } - } - - .hi-timeline__item:nth-child(odd) { - .hi-timeline__row { - margin-left: 50%; - padding-left: 19px; - text-align: left; - .hi-timeline__time { - text-align: left; - } + .item__line { + position: absolute; + left: 30%; + width: 2px; + background: rgb(242, 242, 242); + height: 100%; + transform: translateX(-50%); } - .hi-timeline__content-container { + .item--right { + width: calc(70% - 20px); margin-left: 20px; - } - } - - .hi-timeline__line { - left: 50%; - transform: translateX(-1px); - } + margin-bottom: 20px; - .hi-timeline__dot { - left: 50%; - transform: translateX(-4px); + .item__title { + color: rgb(51, 51, 51); + font-size: 14px; + line-height: 22px; + margin-bottom: 2px; + } - &--custom { - transform: translate(-50%, -30%); + .item__content { + color: rgb(158, 158, 158); + font-size: 12px; + line-height: 20px; + } } - } - } - - &__group-title { - font-size: 12px; - color: #666; - margin-bottom: 4px; - } -} -@each $key, $value in $theme-colors { - .theme__#{$key}.hi-timeline { - .hi-timeline__dot { - border: 2px solid $value; - - &.hi-timeline__dot--custom { - border: none; + &--last { + .item--right { + margin-bottom: 0; + } } - &--sub { - background: $value; + &--first { + .item__line { + top: 7px; + height: calc(100% - 7px); + } } } } } + +// @each $key, $value in $theme-colors { +// .theme__#{$key}.hi-timeline { +// .hi-timeline__dot { +// border: 2px solid $value; + +// &.hi-timeline__dot--custom { +// border: none; +// } + +// &--sub { +// background: $value; +// } +// } +// } +// } diff --git a/docs/demo/timeline/section-cross.jsx b/docs/demo/timeline/section-cross.jsx index 4e60acb95..98732dcb0 100644 --- a/docs/demo/timeline/section-cross.jsx +++ b/docs/demo/timeline/section-cross.jsx @@ -10,55 +10,26 @@ import Timeline from '@hi-ui/hiui/es/timeline'\n class Demo extends React.Component { render () { const data = [{ - groupTitle: '上午', - children: [{ - title: 'Title - 1', - content: 'Here are some descriptions', - timestamp: '9:00', - extraTime: '02-25' - }, { - title: 'Title 1-2', - content: 'Here are some descriptions', - timestamp: '10:00', - extraTime: '02-25' - }] - }, { - groupTitle: '下午', - children: [{ - title: 'Title 2-1', - content: 'Here are some descriptions', - timestamp: '12:00', - extraTime: '02-25', - folding: true, - children: [{ - title: 'Sub 1', - content: 'Here are some descriptions' - }, { - title: 'Sub 2', - content: 'Here are some descriptions' - }] - }, { - icon: , - title: 'Title 2-2', - content: 'Here are some descriptions', - timestamp: '14:00', - extraTime: '02-25' - }] - }, { - groupTitle: 'Group 3', - children: [{ - title: 'Title 3-1', - content: 'Here are some descriptions', - timestamp: '16:00', - extraTime: '11-25', - extraTime: '02-25' - }, { - title: 'Title 3-2', - content: 'Here are some descriptions', - timestamp: '18:00', - extraTime: '02-25' - }] - }] + title: '信息部全员财务培训需求收集', + content: '为使信息部同事更好的研发、运维和服务财务部的需求和工作,财务部计划给信息部同事提供财务相关的培训', + timestamp: '10:00', + extraTime: '02-23' + }, { + title: '信息部全员财务培训需求收集', + content: '为使信息部同事更好的研发、运维和服务财务部的需求和工作,财务部计划给信息部同事提供财务相关的培训', + timestamp: '10:00', + extraTime: '02-27' + }, { + title: '信息部全员财务培训需求收集', + content: '为使信息部同事更好的研发、运维和服务财务部的需求和工作,财务部计划给信息部同事提供财务相关的培训', + timestamp: '12:00', + extraTime: '03-02' + }, { + title: '信息部全员财务培训需求收集', + content: '为使信息部同事更好的研发、运维和服务财务部的需求和工作,财务部计划给信息部同事提供财务相关的培训', + timestamp: '11:00', + extraTime: '03-10' + }] return (
      From c51fe8308caeed3b7cf106199e204ebbc34fc379 Mon Sep 17 00:00:00 2001 From: solarjoker Date: Tue, 28 Apr 2020 10:44:57 +0800 Subject: [PATCH 39/90] feat: update timeline --- components/timeline/FoldingItem.js | 22 ---- components/timeline/index-old.js | 122 -------------------- components/timeline/index.js | 161 ++++++++++----------------- components/timeline/style/index.scss | 64 ++++++++++- docs/demo/timeline/section-basic.jsx | 12 +- docs/demo/timeline/section-info.jsx | 8 +- 6 files changed, 129 insertions(+), 260 deletions(-) delete mode 100644 components/timeline/FoldingItem.js delete mode 100644 components/timeline/index-old.js diff --git a/components/timeline/FoldingItem.js b/components/timeline/FoldingItem.js deleted file mode 100644 index bc84590ff..000000000 --- a/components/timeline/FoldingItem.js +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react' -import Icon from '../icon' - -export default class FoldingItem extends React.Component { - constructor (props) { - super(props) - this.state = { - showSub: false - } - } - render () { - const { showSub } = this.state - const { texts } = this.props - let text = showSub ? texts.collapse : texts.expand - let iconName = showSub ? 'up' : 'down' - return
    • - { showSub &&
        {this.props.subChildren}
      } - this.setState({showSub: !this.state.showSub})}>{text} -
      -
    • - } -} diff --git a/components/timeline/index-old.js b/components/timeline/index-old.js deleted file mode 100644 index 62b0312eb..000000000 --- a/components/timeline/index-old.js +++ /dev/null @@ -1,122 +0,0 @@ -import React, { Component } from 'react' -import classNames from 'classnames' -import Provider from '../context' -import './style/index' -import FoldingItem from './FoldingItem' -import Icon from '../icon' - -const Time = props => { - return ( -
      - {props.groupTitle && ( -
      - {props.groupTitle} -
      - )} - {props.item.timestamp} - {
      {props.item.extraTime}
      } -
      - ) -} -class Timeline extends Component { - /** - * 渲染列表项 - * @param {*} item 原始数据 - * @param {*} index 用于是否渲染 groupTitle 的条件 - * @param {*} groupTitle 分组标题 - * @param {*} isSub 是否是子项,只支持一级 - */ - renderItem (item, index, groupTitle, isSub) { - const { layout, type } = this.props - // TODO: dot 废弃,使用 icon - const dot = item.dot - const icon = item.icon - let dotEl = isSub ? ( -
      - ) : ( -
      - ) - if (dot && typeof dot === 'object') { - dotEl =
      {dot}
      - } - if (icon && typeof icon === 'string') { - dotEl = ( -
      - -
      - ) - } else if (icon && React.isValidElement(icon)) { - dotEl =
      {icon}
      - } - const itemCls = classNames('hi-timeline__item', isSub && 'hi-timeline__item--sub') - return ( -
    • - {layout === 'normal' && type === 'default' && ( -
    • - ) - } - /** - * 渲染列表,被递归调用 - * @param {Array} datas 数据 - * @param {String | React.ReactNode} groupTitle 分组标题 - * @param {Number} originIndex 原始索引,用于判断是否为第一个分组标题 - */ - renderItems (data, groupTitle, isSub) { - const { layout, localeDatas, type } = this.props - return data.map((item, index) => { - const { groupTitle: gt } = item - if (gt) { - // 渲染分组 - return this.renderItems(item.children, gt) - } - if (item.children && layout !== 'cross' && type !== 'cross') { - // 子项 含 收起按钮 - const foldingEl = ( - - ) - // 如果含有子项,需先渲染当前项 - let el = this.renderItem(item, index, groupTitle) - return [el, foldingEl] - } - return this.renderItem(item, index, groupTitle, isSub) - }) - } - - render () { - const { layout, type, list, data, theme } = this.props - const _layout = type === 'default' ? layout : type - const rootCls = classNames('hi-timeline', `theme__${theme}`, `hi-timeline--${_layout}`) - return ( -
      -
        {this.renderItems(data || list)}
      -
      - ) - } -} -Timeline.defaultProps = { - layout: 'normal', // TODO:废弃,使用 type - type: 'default' -} -export default Provider(Timeline) diff --git a/components/timeline/index.js b/components/timeline/index.js index b0d073e09..4b5d44ae3 100644 --- a/components/timeline/index.js +++ b/components/timeline/index.js @@ -2,104 +2,10 @@ import React, { Component } from 'react' import classNames from 'classnames' import Provider from '../context' import './style/index' -import FoldingItem from './FoldingItem' import Icon from '../icon' -const Time = (props) => { - return ( -
      - {props.groupTitle && ( -
      - {props.groupTitle} -
      - )} - {props.item.timestamp} - {
      {props.item.extraTime}
      } -
      - ) -} class Timeline extends Component { - /** - * 渲染列表项 - * @param {*} item 原始数据 - * @param {*} index 用于是否渲染 groupTitle 的条件 - * @param {*} groupTitle 分组标题 - * @param {*} isSub 是否是子项,只支持一级 - */ - // renderItem (item, index, groupTitle, isSub) { - // const { layout, type } = this.props - // // TODO: dot 废弃,使用 icon - // const dot = item.dot - // const icon = item.icon - // let dotEl = isSub ? ( - //
      - // ) : ( - //
      - // ) - // if (dot && typeof dot === 'object') { - // dotEl =
      {dot}
      - // } - // if (icon && typeof icon === 'string') { - // dotEl = ( - //
      - // - //
      - // ) - // } else if (icon && React.isValidElement(icon)) { - // dotEl =
      {icon}
      - // } - // const itemCls = classNames('hi-timeline__item', isSub && 'hi-timeline__item--sub') - // return ( - //
    • - // {layout === 'normal' && type === 'default' && ( - //
    • - // ) - // } - /** - * 渲染列表,被递归调用 - * @param {Array} datas 数据 - * @param {String | React.ReactNode} groupTitle 分组标题 - * @param {Number} originIndex 原始索引,用于判断是否为第一个分组标题 - */ - // renderItems (data, groupTitle, isSub) { - // const { layout, localeDatas, type } = this.props - // return data.map((item, index) => { - // const { groupTitle: gt } = item - // if (gt) { - // // 渲染分组 - // return this.renderItems(item.children, gt) - // } - // if (item.children && layout !== 'cross' && type !== 'cross') { - // // 子项 含 收起按钮 - // const foldingEl = ( - // - // ) - // // 如果含有子项,需先渲染当前项 - // let el = this.renderItem(item, index, groupTitle) - // return [el, foldingEl] - // } - // return this.renderItem(item, index, groupTitle, isSub) - // }) - // } + state = { expanded: false } renderGroup = (item, index, isLast) => { return (
      @@ -148,12 +54,54 @@ class Timeline extends Component { {item.timestamp} {item.extraTime}
      -
      + {(item.icon &&
      {item.icon}
      ) || ( +
      + )}
      ) } - + renderCollapse = (subItems) => { + return ( +
      + {this.state.expanded === true && + subItems.map((c) => { + return this.renderSub(c) + })} +
      { + this.setState({ expanded: !this.state.expanded }) + }} + > + {this.state.expanded === true ? '收起' : '展开'} + +
      +
      +
      + ) + } + renderSub = (item, index, isLast, isFirst) => { + return ( +
      +
      +
      {item.timestamp}
      +
      {item.extraTime}
      +
      + {item.icon ||
      } +
      +
      +
      {item.title}
      +
      {item.content}
      +
      +
      + ) + } renderCross = (item, index, isLast, isFirst) => { return (
      {item.timestamp}
      {item.extraTime}
      -
      + {(item.icon &&
      {item.icon}
      ) || ( +
      + )}
      {item.title}
      @@ -179,7 +129,7 @@ class Timeline extends Component { } renderDefault = (item, index, isLast, isFirst) => { - return ( + return [
      {item.timestamp}
      {item.extraTime}
      -
      + {(item.icon &&
      {item.icon}
      ) || ( +
      + )}
      {item.title}
      {item.content}
      -
      - ) +
      , + item.children && this.renderCollapse(item.children) + ] } render () { const { layout, type, list, data, theme } = this.props @@ -205,9 +158,7 @@ class Timeline extends Component { const rootCls = classNames( 'hi-timeline', `theme__${theme}`, - `hi-timeline--${ - ['normal', 'default'].includes(_layout) ? 'default' : _layout - }` + `hi-timeline--${['normal', 'default'].includes(_layout) ? 'default' : _layout}` ) return (
      diff --git a/components/timeline/style/index.scss b/components/timeline/style/index.scss index 0fd310116..670dc75b4 100755 --- a/components/timeline/style/index.scss +++ b/components/timeline/style/index.scss @@ -19,7 +19,7 @@ margin-bottom: 0; .item__line { - height: 100% !important; + height: 7px !important; } } @@ -49,6 +49,15 @@ z-index: 2; } + .item__icon { + position: absolute; + background: #fff; + top: 7px; + right: -20px; + transform: translateX(50%); + z-index: 2; + } + .item__line { position: absolute; right: -20px; @@ -192,7 +201,7 @@ margin-bottom: 0; .item__line { - height: calc(100%); + height: 7px; } } } @@ -220,6 +229,15 @@ z-index: 2; } + .item__icon { + position: absolute; + background: #fff; + top: 7px; + left: -20px; + transform: translateX(-50%); + z-index: 2; + } + .item__line { position: absolute; left: -22px; @@ -233,6 +251,35 @@ } &--default { + .timeline__collapse { + margin-bottom: 24px; + + .collapse-opt { + font-size: 12px; + margin-left: calc(30% + 20px); + cursor: pointer; + position: relative; + } + + .item__line { + position: absolute; + top: 0; + left: -20px; + width: 2px; + background: #f2f2f2; + height: calc(100% + 24px); + transform: translateX(-50%); + } + + .item__dot { + width: 4px !important; + height: 4px !important; + background: #4284f5 !important; + border-radius: 50%; + top: 9px !important; + } + } + .timeline__group-title { text-align: right; width: calc(30% - 20px); @@ -291,6 +338,15 @@ z-index: 2; } + .item__icon { + position: absolute; + background: #fff; + top: 7px; + left: 30%; + transform: translateX(-50%); + z-index: 2; + } + .item__line { position: absolute; left: 30%; @@ -323,6 +379,10 @@ .item--right { margin-bottom: 0; } + + .item__line { + height: 7px; + } } &--first { diff --git a/docs/demo/timeline/section-basic.jsx b/docs/demo/timeline/section-basic.jsx index bc1e5a1ce..15b3eec4c 100644 --- a/docs/demo/timeline/section-basic.jsx +++ b/docs/demo/timeline/section-basic.jsx @@ -6,6 +6,7 @@ import Form from '../../../components/form' import Input from '../../../components/input' import Radio from '../../../components/radio' import Button from '../../../components/button' +import Icon from '../../../components/icon' const prefix = 'timeline-basic' const desc = '以时间为第一维度,展示该时间点的事务、日程、任务或记录' const code = `import React from 'react' @@ -108,8 +109,8 @@ class Demo extends React.Component { extraTime: '03-10' }] }] - - } + + } return (
      @@ -140,6 +141,11 @@ class Demo extends React.Component { }` const DemoBasic = () => ( - + ) export default DemoBasic diff --git a/docs/demo/timeline/section-info.jsx b/docs/demo/timeline/section-info.jsx index c26357348..ffd1e4f6f 100644 --- a/docs/demo/timeline/section-info.jsx +++ b/docs/demo/timeline/section-info.jsx @@ -1,6 +1,7 @@ import React from 'react' import DocViewer from '../../../libs/doc-viewer' import Timeline from '../../../components/timeline' +import Icon from '../../../components/icon' const prefix = 'timeline-info' const desc = '在一段时间范围里,信息流向增长,数量庞大,必要时可收起部分' const code = `import React from 'react' @@ -40,11 +41,6 @@ class Demo extends React.Component { }` const DemoInfo = () => ( - + ) export default DemoInfo From 574952473539bec423614fb08dc91d09225b4c1f Mon Sep 17 00:00:00 2001 From: solarjoker Date: Tue, 28 Apr 2020 10:54:55 +0800 Subject: [PATCH 40/90] feat: update new timeline --- components/timeline/index.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/components/timeline/index.js b/components/timeline/index.js index 4b5d44ae3..b5e0e5aca 100644 --- a/components/timeline/index.js +++ b/components/timeline/index.js @@ -8,7 +8,7 @@ class Timeline extends Component { state = { expanded: false } renderGroup = (item, index, isLast) => { return ( -
      +
      { return (
      { return ( -
      +
      {this.state.expanded === true && - subItems.map((c) => { - return this.renderSub(c) + subItems.map((c, idx) => { + return this.renderSub(c, idx) })}
      { return (
      { return (
      { return [
      Date: Tue, 28 Apr 2020 16:43:44 +0800 Subject: [PATCH 41/90] feat: update timeline style --- components/timeline/style/index.scss | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/timeline/style/index.scss b/components/timeline/style/index.scss index 670dc75b4..fb3a8ca29 100755 --- a/components/timeline/style/index.scss +++ b/components/timeline/style/index.scss @@ -304,6 +304,7 @@ .timeline__item { display: flex; position: relative; + margin-bottom: 20px; .item--left { text-align: right; @@ -352,14 +353,13 @@ left: 30%; width: 2px; background: rgb(242, 242, 242); - height: 100%; + height: calc(100% + 20px); transform: translateX(-50%); } .item--right { width: calc(70% - 20px); margin-left: 20px; - margin-bottom: 20px; .item__title { color: rgb(51, 51, 51); @@ -388,7 +388,7 @@ &--first { .item__line { top: 7px; - height: calc(100% - 7px); + height: calc(100% + 20px - 7px); } } } diff --git a/package.json b/package.json index 0bedbfd3c..07229a664 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@hi-ui/hiui", - "version": "2.13.0-rc.12", + "version": "2.13.0-rc.25", "description": "HIUI for React", "scripts": { "test": "node_modules/.bin/standard && node_modules/.bin/stylelint --config .stylelintrc 'components/**/*.scss'", From 0f2bfe54b25a81b12ed455aabfaa08ead0006685 Mon Sep 17 00:00:00 2001 From: solarjoker Date: Wed, 29 Apr 2020 11:25:16 +0800 Subject: [PATCH 42/90] feat: tabs add line type --- components/tabs/Tabs.js | 119 +++++++++++++++---------------- components/tabs/style/index.scss | 45 ++++++++++++ 2 files changed, 101 insertions(+), 63 deletions(-) diff --git a/components/tabs/Tabs.js b/components/tabs/Tabs.js index be3a59352..6083a3ad4 100644 --- a/components/tabs/Tabs.js +++ b/components/tabs/Tabs.js @@ -9,7 +9,7 @@ const noop = () => {} class Tabs extends Component { static propTypes = { - type: PropTypes.oneOf(['desc', 'card', 'button', 'editable']), + type: PropTypes.oneOf(['desc', 'card', 'button', 'editable', 'line']), placement: PropTypes.oneOf(['horizontal', 'vertical']), activeId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), defaultActiveId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), @@ -38,13 +38,13 @@ class Tabs extends Component { super(props) const { defaultActiveId, activeId } = props - const { - showTabItems, - hiddenTabItems - } = this.getTabItems(this.props) + const { showTabItems, hiddenTabItems } = this.getTabItems(this.props) this.state = { - activeId: activeId !== undefined ? activeId : (defaultActiveId || (showTabItems && showTabItems[0] && showTabItems[0].tabId)), + activeId: + activeId !== undefined + ? activeId + : defaultActiveId || (showTabItems && showTabItems[0] && showTabItems[0].tabId), showTabItems, hiddenTabItems, defaultActiveId @@ -52,10 +52,7 @@ class Tabs extends Component { } componentWillReceiveProps (nextProps) { - const { - showTabItems, - hiddenTabItems - } = this.getTabItems(nextProps) + const { showTabItems, hiddenTabItems } = this.getTabItems(nextProps) this.setState({ showTabItems, hiddenTabItems @@ -70,22 +67,25 @@ class Tabs extends Component { this.setState({ activeId: nextProps.children[0] && nextProps.children[0].props.tabId }) } - if (this.props.children.length > nextProps.children.length && this.deletetabId && this.deletetabId === this.state.activeId) { // 删除的是当前激活的tab,需重置激活tab - this.setState({ - activeId: (nextProps.children[0] && nextProps.children[0].props.tabId) || undefined - }, () => { - this.deletetabId = null - }) + if ( + this.props.children.length > nextProps.children.length && + this.deletetabId && + this.deletetabId === this.state.activeId + ) { + // 删除的是当前激活的tab,需重置激活tab + this.setState( + { + activeId: (nextProps.children[0] && nextProps.children[0].props.tabId) || undefined + }, + () => { + this.deletetabId = null + } + ) } } getTabItems (props) { - const { - children, - type, - placement, - max - } = props + const { children, type, placement, max } = props const showTabItems = [] const hiddenTabItems = [] @@ -94,14 +94,15 @@ class Tabs extends Component { const { tabTitle, tabId, tabDesc, disabled, closeable } = child.props const item = { tabTitle, tabId, tabDesc, disabled, closeable } - if (type === 'card' && placement === 'horizontal' && showTabItems.length >= max) { // 卡片式标签超过max时,其余标签的隐藏 + if (type === 'card' && placement === 'horizontal' && showTabItems.length >= max) { + // 卡片式标签超过max时,其余标签的隐藏 hiddenTabItems.push(item) } else { showTabItems.push(item) } } }) - return {showTabItems, hiddenTabItems} + return { showTabItems, hiddenTabItems } } handleClick (tab, e) { @@ -113,20 +114,17 @@ class Tabs extends Component { onTabClick(tab.tabId, e) const activeId = this.props.activeId - activeId !== undefined || this.setState({ - activeId: tab.tabId - }) + activeId !== undefined || + this.setState({ + activeId: tab.tabId + }) } addTab () { - const { - onEdit, - editable, - children - } = this.props + const { onEdit, editable, children } = this.props if (editable) { - onEdit('add', (children.length + 1)) + onEdit('add', children.length + 1) } } @@ -134,10 +132,7 @@ class Tabs extends Component { e.stopPropagation() this.deletetabId = tabId - const { - onEdit, - editable - } = this.props + const { onEdit, editable } = this.props if (editable) { onEdit('delete', index, tabId) @@ -145,10 +140,7 @@ class Tabs extends Component { } checkEditable () { - const { - editable, - type - } = this.props + const { editable, type } = this.props return editable && type === 'editable' } @@ -165,9 +157,15 @@ class Tabs extends Component { const { activeId, showTabItems, hiddenTabItems, defaultActiveId } = this.state const { prefixCls, type, placement, children, className, theme } = this.props const editable = this.checkEditable() - const tabsClasses = classNames(prefixCls, className, `${prefixCls}--${type}`, `theme__${theme}`, { - [`${prefixCls}--${placement}`]: type === 'card' - }) + const tabsClasses = classNames( + prefixCls, + className, + `${prefixCls}--${type}`, + `theme__${theme}`, + { + [`${prefixCls}--${placement}`]: type === 'card' + } + ) let activeTabInHiddenItems = true return ( @@ -187,28 +185,24 @@ class Tabs extends Component { this.handleClick(item, e)} + onClick={(e) => this.handleClick(item, e)} title={tabTitle} > {tabTitle} - { - type === 'desc' && - {tabDesc} - } - { - editable && closeable && + {type === 'desc' && {tabDesc}} + {editable && closeable && ( - this.deleteTab(e, tabId, index)} name='close' /> + this.deleteTab(e, tabId, index)} name='close' /> - } + )} ) })} - { - hiddenTabItems.length > 0 && -
      0 && ( +
      - } + )}
      - { - editable && + {editable && (
      - } + )}
      - {React.Children.map(children, item => { + {React.Children.map(children, (item) => { return item && this.renderTabContent(item) })}
      diff --git a/components/tabs/style/index.scss b/components/tabs/style/index.scss index fb62e56fa..78cd6c8ad 100644 --- a/components/tabs/style/index.scss +++ b/components/tabs/style/index.scss @@ -47,6 +47,51 @@ $prefix: 'hi-tabs' !default; font-size: 16px; } + &--line { + & > .#{$prefix}__header { + .#{$prefix}__nav { + display: flex; + flex-wrap: nowrap; + border-bottom: 1px solid #e6e7e8; + } + + .#{$prefix}__item { + position: relative; + height: 40px; + line-height: 40px; + margin-right: 32px; + box-sizing: border-box; + border: none; + transition: color 0.5s linear; + + &::after { + display: inline-block; + position: absolute; + content: ''; + height: 2px; + width: 100%; + background: #4284f5; + bottom: 0; + left: 0; + opacity: 0; + transition: opacity 0.5s linear; + } + + &:hover { + color: #4284f5; + } + + &--active { + &::after { + opacity: 1; + } + + color: #4284f5; + } + } + } + } + &--card { & > .#{$prefix}__header { .#{$prefix}__nav { From e6f7756925850011d76177dd65289fc68dbf542b Mon Sep 17 00:00:00 2001 From: solarjoker Date: Wed, 29 Apr 2020 15:04:41 +0800 Subject: [PATCH 43/90] feat: opt watermark --- components/watermark/index.js | 3 ++- components/watermark/watermark.js | 35 ++++++++++++++++++++++------ docs/demo/watermark/section-base.jsx | 16 +++++-------- 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/components/watermark/index.js b/components/watermark/index.js index a5fc9c75c..c4b7567fd 100644 --- a/components/watermark/index.js +++ b/components/watermark/index.js @@ -44,7 +44,8 @@ Watermark.defaultProps = { id: null, density: 'default', textAlign: 'left', - font: '16px microsoft yahei', + font: + '12px -apple-system,BlinkMacSystemFont,"Helvetica Neue",Helvetica,Arial,"Microsoft Yahei","Hiragino Sans GB","Heiti SC","WenQuanYi Micro Hei",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol""', color: 'rgba(128, 128, 128, 0.2)', content: '请勿外传', rotate: -30, diff --git a/components/watermark/watermark.js b/components/watermark/watermark.js index d0468294a..6c8c8f776 100644 --- a/components/watermark/watermark.js +++ b/components/watermark/watermark.js @@ -1,7 +1,7 @@ const defaultOptions = { id: null, textAlign: 'left', - font: '16px microsoft yahei', + font: '12px microsoft yahei', color: 'rgba(128, 128, 128, 0.2)', content: '请勿外传', rotate: -30, @@ -100,6 +100,18 @@ const drawLogo = (ctx, logo, cb) => { } } +const getPixelRatio = (context) => { + const backingStore = + context.backingStorePixelRatio || + context.webkitBackingStorePixelRatio || + context.mozBackingStorePixelRatio || + context.msBackingStorePixelRatio || + context.oBackingStorePixelRatio || + context.backingStorePixelRatio || + 1 + return (window.devicePixelRatio || 1) / backingStore +} + const toImage = (canvas, key, container, options) => { const base64Url = canvas.toDataURL() const { opacity = 1 } = options @@ -166,7 +178,7 @@ const WaterMarker = (container, args) => { height, textAlign, textBaseline, - font, + // font, color, logo, rotate @@ -177,16 +189,25 @@ const WaterMarker = (container, args) => { } const canvas = document.createElement('canvas') var ctx = canvas.getContext('2d') - canvas.setAttribute('width', width + 'px') - canvas.setAttribute('height', height + 'px') + const ratio = getPixelRatio(ctx) + canvas.style.width = width / ratio + 'px' + canvas.style.height = height / ratio + 'px' + canvas.width = width + canvas.height = height + // canvas.setAttribute('width', width + 'px') + // canvas.setAttribute('height', height + 'px') + // canvas.width = canvas.width * ratio + // canvas.width = canvas.height * ratio + ctx.scale(ratio, ratio) ctx.textAlign = textAlign ctx.textBaseline = textBaseline - ctx.font = font + ctx.font = '12px microsoft yahei' + ctx.fontWeight = 100 ctx.fillStyle = color - ctx.translate(width / 2, height / 2) + // ctx.translate(width / (ratio * 2), height / (ratio * 2)) ctx.rotate(Math.PI / 180 * rotate) - ctx.translate(-width / 2, -height / 2) + // ctx.translate(-width / (ratio * 2), -height / (ratio * 2)) drawText(ctx, options) if (logo) { diff --git a/docs/demo/watermark/section-base.jsx b/docs/demo/watermark/section-base.jsx index 3e214deaa..6c9c15490 100755 --- a/docs/demo/watermark/section-base.jsx +++ b/docs/demo/watermark/section-base.jsx @@ -11,9 +11,9 @@ class Demo extends React.Component { constructor(props) { super(props) this.options = { - logo: logo, // 本地图片路径或者base64 - content: ['HIUI', '做中台,就用 HIUI'], - density:'high' + content: ['chenxian 陈晛'], + // density:'low', + rotate:-15 } } render () { @@ -21,7 +21,7 @@ class Demo extends React.Component { -
      @@ -30,10 +30,6 @@ class Demo extends React.Component { }` const DemoBase = () => ( - ) + +) export default DemoBase From c2678e8e6c3f50b34459cf477452c2e954138732 Mon Sep 17 00:00:00 2001 From: Wugaoliang Date: Wed, 29 Apr 2020 16:17:15 +0800 Subject: [PATCH 44/90] feat: update-tree --- components/watermark/index.js | 4 +-- components/watermark/watermark.js | 56 +++++++++++++++++-------------- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/components/watermark/index.js b/components/watermark/index.js index c4b7567fd..728731ee8 100644 --- a/components/watermark/index.js +++ b/components/watermark/index.js @@ -45,8 +45,8 @@ Watermark.defaultProps = { density: 'default', textAlign: 'left', font: - '12px -apple-system,BlinkMacSystemFont,"Helvetica Neue",Helvetica,Arial,"Microsoft Yahei","Hiragino Sans GB","Heiti SC","WenQuanYi Micro Hei",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol""', - color: 'rgba(128, 128, 128, 0.2)', + 'normal normal lighter 24px Microsoft YaHei', + color: 'rgba(148, 148, 148, 0.2)', content: '请勿外传', rotate: -30, zIndex: 1000, diff --git a/components/watermark/watermark.js b/components/watermark/watermark.js index 6c8c8f776..45af746d2 100644 --- a/components/watermark/watermark.js +++ b/components/watermark/watermark.js @@ -100,17 +100,17 @@ const drawLogo = (ctx, logo, cb) => { } } -const getPixelRatio = (context) => { - const backingStore = - context.backingStorePixelRatio || - context.webkitBackingStorePixelRatio || - context.mozBackingStorePixelRatio || - context.msBackingStorePixelRatio || - context.oBackingStorePixelRatio || - context.backingStorePixelRatio || - 1 - return (window.devicePixelRatio || 1) / backingStore -} +// const getPixelRatio = (context) => { +// const backingStore = +// context.backingStorePixelRatio || +// context.webkitBackingStorePixelRatio || +// context.mozBackingStorePixelRatio || +// context.msBackingStorePixelRatio || +// context.oBackingStorePixelRatio || +// context.backingStorePixelRatio || +// 1 +// return (window.devicePixelRatio || 1) / backingStore +// } const toImage = (canvas, key, container, options) => { const base64Url = canvas.toDataURL() @@ -125,6 +125,7 @@ const toImage = (canvas, key, container, options) => { bottom:0; width:100%; height:100%; + transform:scale(0.5); z-index:${options.zIndex}; pointer-events:none; background-repeat:repeat; @@ -178,7 +179,7 @@ const WaterMarker = (container, args) => { height, textAlign, textBaseline, - // font, + font, color, logo, rotate @@ -189,25 +190,30 @@ const WaterMarker = (container, args) => { } const canvas = document.createElement('canvas') var ctx = canvas.getContext('2d') - const ratio = getPixelRatio(ctx) - canvas.style.width = width / ratio + 'px' - canvas.style.height = height / ratio + 'px' - canvas.width = width - canvas.height = height - - // canvas.setAttribute('width', width + 'px') - // canvas.setAttribute('height', height + 'px') + // const ratio = getPixelRatio(ctx) + canvas.setAttribute('width', width + 'px') + canvas.setAttribute('height', height + 'px') // canvas.width = canvas.width * ratio // canvas.width = canvas.height * ratio - ctx.scale(ratio, ratio) ctx.textAlign = textAlign ctx.textBaseline = textBaseline - ctx.font = '12px microsoft yahei' - ctx.fontWeight = 100 + ctx.font = font ctx.fillStyle = color - // ctx.translate(width / (ratio * 2), height / (ratio * 2)) + ctx.translate(width / 2, height / 2) ctx.rotate(Math.PI / 180 * rotate) - // ctx.translate(-width / (ratio * 2), -height / (ratio * 2)) + ctx.translate(-width / 2, -height / 2) + // canvas.setAttribute('width', width + 'px') + // canvas.setAttribute('height', height + 'px') + // // canvas.width = canvas.width * ratio + // // canvas.width = canvas.height * ratio + // ctx.scale(ratio, ratio) + // ctx.textAlign = textAlign + // ctx.textBaseline = textBaseline + // ctx.font = '100 12px microsoft yahei' + // ctx.fillStyle = color + // ctx.translate(width / (ratio * 2), height / (ratio * 2)) + // ctx.rotate(Math.PI / 180 * rotate) + // // ctx.translate(-width / (ratio * 2), -height / (ratio * 2)) drawText(ctx, options) if (logo) { From 0a46048d01d2a4ef5c4cfce6131ac849c2344831 Mon Sep 17 00:00:00 2001 From: Wugaoliang Date: Wed, 29 Apr 2020 17:07:57 +0800 Subject: [PATCH 45/90] feat: opt-watermark --- components/watermark/index.js | 2 +- components/watermark/watermark.js | 57 ++++++++-------------------- docs/demo/watermark/section-base.jsx | 5 +-- 3 files changed, 18 insertions(+), 46 deletions(-) diff --git a/components/watermark/index.js b/components/watermark/index.js index 728731ee8..18fd62135 100644 --- a/components/watermark/index.js +++ b/components/watermark/index.js @@ -45,7 +45,7 @@ Watermark.defaultProps = { density: 'default', textAlign: 'left', font: - 'normal normal lighter 24px Microsoft YaHei', + 'normal normal lighter 28px Microsoft YaHei,-apple-system,BlinkMacSystemFont,"Helvetica Neue",Helvetica,Arial,"Microsoft Yahei","Hiragino Sans GB","Heiti SC","WenQuanYi Micro Hei",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"', color: 'rgba(148, 148, 148, 0.2)', content: '请勿外传', rotate: -30, diff --git a/components/watermark/watermark.js b/components/watermark/watermark.js index 45af746d2..12e48f9d3 100644 --- a/components/watermark/watermark.js +++ b/components/watermark/watermark.js @@ -53,7 +53,7 @@ const drawText = (ctx, options) => { } = options let oldBaseLine = ctx.textBaseline let x = 0 - let y = 0 + let y = 16 ctx.textBaseline = 'hanging' /** * LOGO 固定宽高: 32 * 32 @@ -62,8 +62,8 @@ const drawText = (ctx, options) => { */ let lineHeight = parseInt(ctx.font) // ctx.font必须以'XXpx'开头 if (logo) { - x += 32 - _w -= 32 + x += 64 + _w -= 64 } const lines = parseTextData(ctx, text, width, isAutoWrap) @@ -73,11 +73,11 @@ const drawText = (ctx, options) => { for (let line of lines) { let lineX if (ctx.textAlign === 'center') { - lineX = x + width / 2 + 4 + lineX = x + width + 40 } else if (ctx.textAlign === 'right') { - lineX = x + width + 4 + lineX = x + width + 40 } else { - lineX = x + 4 + lineX = x + 40 } if (textOverflowEffect === 'zoom') { const size = parseInt(Math.sqrt((_w * _w + height * height) / 2)) @@ -95,23 +95,11 @@ const drawLogo = (ctx, logo, cb) => { img.src = logo img.onload = () => { ctx.globalAlpha = 0.2 - ctx.drawImage(img, 0, ctx.canvas.height / 2 - 16, 32, 32) + ctx.drawImage(img, 32, ctx.canvas.height / 2 - 16, 64, 64) cb() } } -// const getPixelRatio = (context) => { -// const backingStore = -// context.backingStorePixelRatio || -// context.webkitBackingStorePixelRatio || -// context.mozBackingStorePixelRatio || -// context.msBackingStorePixelRatio || -// context.oBackingStorePixelRatio || -// context.backingStorePixelRatio || -// 1 -// return (window.devicePixelRatio || 1) / backingStore -// } - const toImage = (canvas, key, container, options) => { const base64Url = canvas.toDataURL() const { opacity = 1 } = options @@ -121,10 +109,10 @@ const toImage = (canvas, key, container, options) => { const styleStr = ` position:absolute; top:${_top}; - left:0; - bottom:0; - width:100%; - height:100%; + left:-50%; + top:-50%; + width:200%; + height:200%; transform:scale(0.5); z-index:${options.zIndex}; pointer-events:none; @@ -163,13 +151,13 @@ const WaterMarker = (container, args) => { const _container = container || document.body const {density} = args let _markSize = { - width: 210, - height: 180 + width: 420, + height: 270 } if (['low', 'high'].includes(density)) { _markSize = { - width: density === 'low' ? 240 : 180, - height: density === 'low' ? 210 : 150 + width: density === 'low' ? 540 : 360, + height: density === 'low' ? 410 : 210 } } const options = Object.assign({}, defaultOptions, _markSize, args) @@ -190,11 +178,8 @@ const WaterMarker = (container, args) => { } const canvas = document.createElement('canvas') var ctx = canvas.getContext('2d') - // const ratio = getPixelRatio(ctx) canvas.setAttribute('width', width + 'px') canvas.setAttribute('height', height + 'px') - // canvas.width = canvas.width * ratio - // canvas.width = canvas.height * ratio ctx.textAlign = textAlign ctx.textBaseline = textBaseline ctx.font = font @@ -202,18 +187,6 @@ const WaterMarker = (container, args) => { ctx.translate(width / 2, height / 2) ctx.rotate(Math.PI / 180 * rotate) ctx.translate(-width / 2, -height / 2) - // canvas.setAttribute('width', width + 'px') - // canvas.setAttribute('height', height + 'px') - // // canvas.width = canvas.width * ratio - // // canvas.width = canvas.height * ratio - // ctx.scale(ratio, ratio) - // ctx.textAlign = textAlign - // ctx.textBaseline = textBaseline - // ctx.font = '100 12px microsoft yahei' - // ctx.fillStyle = color - // ctx.translate(width / (ratio * 2), height / (ratio * 2)) - // ctx.rotate(Math.PI / 180 * rotate) - // // ctx.translate(-width / (ratio * 2), -height / (ratio * 2)) drawText(ctx, options) if (logo) { diff --git a/docs/demo/watermark/section-base.jsx b/docs/demo/watermark/section-base.jsx index 6c9c15490..6df2ddce4 100755 --- a/docs/demo/watermark/section-base.jsx +++ b/docs/demo/watermark/section-base.jsx @@ -11,9 +11,8 @@ class Demo extends React.Component { constructor(props) { super(props) this.options = { - content: ['chenxian 陈晛'], - // density:'low', - rotate:-15 + logo: logo, // 本地图片路径或者base64 + content: ['HIUI', '做中台,就用 HIUI'], } } render () { From 42f47a5be59ccbe3d7705cc74a9ea741fd3c41ae Mon Sep 17 00:00:00 2001 From: solarjoker Date: Wed, 29 Apr 2020 17:37:34 +0800 Subject: [PATCH 46/90] feat: update watermark font --- components/watermark/index.js | 2 +- components/watermark/watermark.js | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/watermark/index.js b/components/watermark/index.js index 18fd62135..5b577b95d 100644 --- a/components/watermark/index.js +++ b/components/watermark/index.js @@ -45,7 +45,7 @@ Watermark.defaultProps = { density: 'default', textAlign: 'left', font: - 'normal normal lighter 28px Microsoft YaHei,-apple-system,BlinkMacSystemFont,"Helvetica Neue",Helvetica,Arial,"Microsoft Yahei","Hiragino Sans GB","Heiti SC","WenQuanYi Micro Hei",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"', + 'normal normal lighter 28px -apple-system,BlinkMacSystemFont,"Helvetica Neue",Helvetica,Arial,"Microsoft Yahei","Hiragino Sans GB","Heiti SC","WenQuanYi Micro Hei",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"', color: 'rgba(148, 148, 148, 0.2)', content: '请勿外传', rotate: -30, diff --git a/components/watermark/watermark.js b/components/watermark/watermark.js index 12e48f9d3..eccb7aca4 100644 --- a/components/watermark/watermark.js +++ b/components/watermark/watermark.js @@ -1,8 +1,8 @@ const defaultOptions = { id: null, textAlign: 'left', - font: '12px microsoft yahei', - color: 'rgba(128, 128, 128, 0.2)', + font: 'normal normal lighter 28px -apple-system,BlinkMacSystemFont,"Helvetica Neue",Helvetica,Arial,"Microsoft Yahei","Hiragino Sans GB","Heiti SC","WenQuanYi Micro Hei",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"', + color: 'rgba(148, 148, 148, 0.2)', content: '请勿外传', rotate: -30, zIndex: 1000, diff --git a/package.json b/package.json index 07229a664..913545826 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@hi-ui/hiui", - "version": "2.13.0-rc.25", + "version": "2.13.0-rc.26", "description": "HIUI for React", "scripts": { "test": "node_modules/.bin/standard && node_modules/.bin/stylelint --config .stylelintrc 'components/**/*.scss'", From f972fbf19c4c9554158cb6a6e1c26f96ad6e38b2 Mon Sep 17 00:00:00 2001 From: Wugaoliang Date: Thu, 30 Apr 2020 14:29:46 +0800 Subject: [PATCH 47/90] fix: waterMark --- components/watermark/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/watermark/index.js b/components/watermark/index.js index 18fd62135..2af29394c 100644 --- a/components/watermark/index.js +++ b/components/watermark/index.js @@ -45,7 +45,7 @@ Watermark.defaultProps = { density: 'default', textAlign: 'left', font: - 'normal normal lighter 28px Microsoft YaHei,-apple-system,BlinkMacSystemFont,"Helvetica Neue",Helvetica,Arial,"Microsoft Yahei","Hiragino Sans GB","Heiti SC","WenQuanYi Micro Hei",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"', + 'normal normal lighter 28px Microsoft YaHei,helvetica,arial', color: 'rgba(148, 148, 148, 0.2)', content: '请勿外传', rotate: -30, From 5bdb0b74e9d120250519cd623f000e96eab27b68 Mon Sep 17 00:00:00 2001 From: Wugaoliang Date: Thu, 7 May 2020 14:23:46 +0800 Subject: [PATCH 48/90] fix: watermark --- components/watermark/watermark.js | 4 ++-- docs/demo/watermark/section-base.jsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/watermark/watermark.js b/components/watermark/watermark.js index d7457171c..0a5669f22 100644 --- a/components/watermark/watermark.js +++ b/components/watermark/watermark.js @@ -61,7 +61,7 @@ const drawText = (ctx, options) => { * 内容区域为 画布宽度 - 48 (预留左右各24的 padding) * 如含 LOGO ,文字的起始 X 坐标为: 24(padding-left) + 32(logo size) + 4(logo 与 text 间距) */ - let lineHeight = parseInt(font) // ctx.font必须以'XXpx'开头 + let lineHeight = parseInt(font * 2) // ctx.font必须以'XXpx'开头 if (logo) { x += 64 _w -= 64 @@ -183,7 +183,7 @@ const WaterMarker = (container, args) => { canvas.setAttribute('height', height + 'px') ctx.textAlign = textAlign ctx.textBaseline = textBaseline - ctx.font = `normal normal lighter ${Number(font * 2)}px Microsoft YaHei,helvetica,arial` + ctx.font = `normal normal lighter ${Number(font * 2)}px -apple-system,BlinkMacSystemFont,"Helvetica Neue",Helvetica,Arial,"Microsoft Yahei","Hiragino Sans GB","Heiti SC","WenQuanYi Micro Hei",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"` ctx.fillStyle = color ctx.translate(width / 2, height / 2) ctx.rotate(Math.PI / 180 * rotate) diff --git a/docs/demo/watermark/section-base.jsx b/docs/demo/watermark/section-base.jsx index 6df2ddce4..f724f6471 100755 --- a/docs/demo/watermark/section-base.jsx +++ b/docs/demo/watermark/section-base.jsx @@ -6,7 +6,7 @@ const prefix = 'watermark-base' const desc = '' const code = `import React from 'react' import logo from '本地图片路径或者base64' -import Watermark from '@hi-ui/hiui/es/Watermark'\n +import Watermark from '@hi-ui/hiui/es/watermark'\n class Demo extends React.Component { constructor(props) { super(props) From 2e0df548de6449ed727ae59c5c1a5c37dae57a46 Mon Sep 17 00:00:00 2001 From: solarjoker Date: Wed, 13 May 2020 10:35:30 +0800 Subject: [PATCH 49/90] docs: update date picker doc --- docs/zh-CN/components/date-picker.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/zh-CN/components/date-picker.mdx b/docs/zh-CN/components/date-picker.mdx index da6ee3c22..6de8684c8 100755 --- a/docs/zh-CN/components/date-picker.mdx +++ b/docs/zh-CN/components/date-picker.mdx @@ -50,9 +50,9 @@ import DemoCalendar from '../../demo/date-picker/section-calendar.jsx' | ----------------- | ---------------------------------------- | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | | type | 选择器类型 | string | date 普通日期
      daterange 日期范围
      year 年份
      month 月份
      week 周
      weekrange 周范围
      timeperiod 时间段(1.5 新增) | date | | value | 默认显示的日期 | Date \| string \| number\| DateRange \| undefined \| null | - | null | -| width | 输入框宽度 | number | - | null | -| minDate | 最小日期 | Date | null | null | -| maxDate | 最大日期 | Date | null | null | +| width | 输入框宽度 | number | - | null | +| min | 最小日期 | Date | null | null | +| max | 最大日期 | Date | null | null | | disabled | 是否禁用输入框 | boolean | true \| false | false | | disabledDate | 不可选择的日期 | (currentDate: Date) => boolean | true \| false | false | | clearable | 是否可以清空 | boolean | true \| false | true | From 7af92b7d0c118ff2e69a84004b5ba4392e2886e6 Mon Sep 17 00:00:00 2001 From: solarjoker Date: Wed, 13 May 2020 11:32:24 +0800 Subject: [PATCH 50/90] fix: #1053 --- components/cascader/style/cascader.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/cascader/style/cascader.scss b/components/cascader/style/cascader.scss index 8dcb72950..57f26c941 100644 --- a/components/cascader/style/cascader.scss +++ b/components/cascader/style/cascader.scss @@ -35,7 +35,7 @@ $cascader: 'hi-cascader' !default; &__input-container { display: flex; align-items: center; - padding: 5px 12px; + padding: 4px 12px; border: 1px solid #d8d8d8; } From 7ff2389fc57aa31dd8711cdbfa091ba251558ab1 Mon Sep 17 00:00:00 2001 From: solarjoker Date: Wed, 13 May 2020 15:32:27 +0800 Subject: [PATCH 51/90] feat: add normal tag --- components/tag/style/index.scss | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/components/tag/style/index.scss b/components/tag/style/index.scss index f0404159c..83fac0e0b 100644 --- a/components/tag/style/index.scss +++ b/components/tag/style/index.scss @@ -2,6 +2,7 @@ $prefix: 'hi-tag' !default; $primary: get-color($palette-primary, 'hiui-blue') !default; +$normal: #999 !default; .#{$prefix} { &__container { @@ -24,6 +25,10 @@ $primary: get-color($palette-primary, 'hiui-blue') !default; background: $primary; color: $white; + &.#{$prefix}__container--normal { + background: $normal; + } + @each $key in 'success', 'danger', 'warning' { &.#{$prefix}__container--#{$key} { $status-color: map-get(get-palette(get-color($palette-secondary, $key)), '50'); @@ -40,6 +45,11 @@ $primary: get-color($palette-primary, 'hiui-blue') !default; padding: 0 5px; line-height: $line-height-size-normal - 2; + &.#{$prefix}__container--normal { + border: 1px solid $normal; + color: $normal; + } + @each $key in 'success', 'danger', 'warning' { &.#{$prefix}__container--#{$key} { $status-color: map-get(get-palette(get-color($palette-secondary, $key)), '50'); From 4346f7caef9c28db05c66bac23bf2d5b97e75754 Mon Sep 17 00:00:00 2001 From: wugaoliang Date: Wed, 13 May 2020 21:57:21 +0800 Subject: [PATCH 52/90] fix: #1054 --- docs/zh-CN/components/menu.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh-CN/components/menu.mdx b/docs/zh-CN/components/menu.mdx index f601592e3..f0f6846ab 100755 --- a/docs/zh-CN/components/menu.mdx +++ b/docs/zh-CN/components/menu.mdx @@ -50,7 +50,7 @@ import { Badge } from '@libs' | 参数 | 说明 | 类型 | 可选值 | 默认值 | | -------- | ------------------------------------------------ | ------------------- | ------------- | ------ | | content | 菜单项标题 | string \| ReactNode | - | - | -| icon | 菜单项 icon,为 string 时会座位 Icon 组件的 name | string \| ReactNode | - | - | +| icon | 菜单项 icon, 为string时为HIUI Icon组件的name | string \| ReactNode | - | - | | id | 菜单项唯一标识 | string \| number | - | - | | disabled | 菜单项是否禁止点击 | boolean | true \| false | false | | children | 子菜单项配置 | DataItem[] | - | - | From 90a1fc43c850c560d8f4fd0fb5e84bfb5869d4f0 Mon Sep 17 00:00:00 2001 From: wugaoliang Date: Wed, 13 May 2020 22:04:30 +0800 Subject: [PATCH 53/90] fix: #1055 --- docs/zh-CN/components/tree.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/zh-CN/components/tree.mdx b/docs/zh-CN/components/tree.mdx index db4e2a875..c15c29d9a 100755 --- a/docs/zh-CN/components/tree.mdx +++ b/docs/zh-CN/components/tree.mdx @@ -64,7 +64,7 @@ import DemoLine from '../../demo/tree/section-line.jsx' | highlightable | 节点高亮 | boolean | true \| false | false | | loadTreeNode | 点击异步加载子项 | LoadTreeNode \| (id: string) => LoadTreeNode | - | - | | defaultExpandAll | 是否默认展开所有树节点 | boolean | true \| false | false | -| defaultHighlightId | 默认高亮的节点 | boolean | true \| false | false | +| defaultHighlightId | 默认高亮的节点 | string | - | - | | checkedIds | 选中的 checkbox | string[] | - | - | | openIcon | 表示展开的图标 | string | Icon 图标名称 | - | | closeIcon | 表示闭合的图标 | string | Icon 图标名称 | - | From badff733c001b34ac0011529b09106438e6eca7c Mon Sep 17 00:00:00 2001 From: wugaoliang Date: Wed, 13 May 2020 22:40:38 +0800 Subject: [PATCH 54/90] fix: #1049 --- components/message/style/index.scss | 22 +++++++++++++++++----- components/notice/NoticeContainer.js | 1 - components/notification/style/index.scss | 22 +++++++++++++++++----- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/components/message/style/index.scss b/components/message/style/index.scss index f50b1bb31..5dd578915 100755 --- a/components/message/style/index.scss +++ b/components/message/style/index.scss @@ -1,6 +1,15 @@ @import '@hi-ui/core-css/index.scss'; @import '../../style/icon/index.scss'; +$theme-colors-notice: ( + 'orange': #ffefea, + 'cyan': #ecf8f4 , + 'magenta': #ffeef1, + 'lavender': #f7edfb, + 'blue': #ebf6fe, + 'purple': #8a8acb +) !default; + .hi-message__container { position: fixed; top: 20px; @@ -111,11 +120,6 @@ @each $key, $value in $theme-colors { .hi-message__container { .theme__#{$key}.hi-message.hi-message--info { - background-color: - rgba( - map-get(get-palette(get-color($palette-primary, $key)), '50'), - 0.1 - ); border: 1px solid @@ -132,3 +136,11 @@ } } } + +@each $key, $value in $theme-colors-notice { + .hi-message__container { + .theme__#{$key}.hi-message.hi-message--info { + background-color: $value; + } + } +} diff --git a/components/notice/NoticeContainer.js b/components/notice/NoticeContainer.js index cf539a995..33a077fce 100755 --- a/components/notice/NoticeContainer.js +++ b/components/notice/NoticeContainer.js @@ -25,7 +25,6 @@ export default class NoticeContainer extends Component { const { prefix } = this.props return (
      {queue.map((notice, index) => { diff --git a/components/notification/style/index.scss b/components/notification/style/index.scss index d2b4a96f5..b1cdd899a 100755 --- a/components/notification/style/index.scss +++ b/components/notification/style/index.scss @@ -1,6 +1,15 @@ @import '@hi-ui/core-css/index.scss'; @import '../../style/icon/index.scss'; +$theme-colors-notice: ( + 'orange': #ffefea, + 'cyan': #ecf8f4 , + 'magenta': #ffeef1, + 'lavender': #f7edfb, + 'blue': #ebf6fe, + 'purple': #8a8acb +) !default; + .hi-notification__container { position: fixed; top: 20px; @@ -138,11 +147,6 @@ @each $key, $value in $theme-colors { .hi-notification__container { .theme__#{$key}.hi-notification.hi-notification--info { - background-color: - rgba( - map-get(get-palette(get-color($palette-primary, $key)), '50'), - 0.1 - ); border: 1px solid @@ -163,3 +167,11 @@ } } } + +@each $key, $value in $theme-colors-notice { + .hi-notification__container { + .theme__#{$key}.hi-notification.hi-notification--info { + background-color: $value; + } + } +} From 6f822df7180bd1ea2d2b04af5052aef02ebfa518 Mon Sep 17 00:00:00 2001 From: solarjoker Date: Thu, 14 May 2020 12:03:57 +0800 Subject: [PATCH 55/90] fix: #1059 --- components/form/Form.js | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/components/form/Form.js b/components/form/Form.js index 7efd5c5f5..2340d3320 100644 --- a/components/form/Form.js +++ b/components/form/Form.js @@ -33,14 +33,14 @@ class Form extends Component { } addField (field) { - this.setState(prevState => ({ + this.setState((prevState) => ({ fields: prevState.fields.concat(field) })) } removeField (prop) { - this.setState(prevState => ({ - fields: prevState.fields.filter(field => field.props.field !== prop) + this.setState((prevState) => ({ + fields: prevState.fields.filter((field) => field.props.field !== prop) })) } @@ -52,21 +52,20 @@ class Form extends Component { cb(valid) } - fields.forEach(field => { - field.validate('', errors => { + fields.forEach((field) => { + field.validate('', (errors) => { if (errors) { valid = false - } else { - if (typeof cb === 'function' && ++count === fields.length) { - cb(valid) - } + } + if (typeof cb === 'function' && ++count === fields.length) { + cb(valid) } }) }) } validateField (key, cb) { - const field = this.state.fields.filter(field => field.props.field === key)[0] + const field = this.state.fields.filter((field) => field.props.field === key)[0] if (!field) { throw new Error('must call validate Field with valid key string!') @@ -76,7 +75,7 @@ class Form extends Component { } resetValidates () { - this.state.fields.forEach(field => { + this.state.fields.forEach((field) => { field.resetValidate() }) } From 91dd01b2751e9bc7c3f69988ced61a727ea7f1fa Mon Sep 17 00:00:00 2001 From: solarjoker Date: Thu, 14 May 2020 18:28:21 +0800 Subject: [PATCH 56/90] chore: update version and changlog --- CHANGELOG.md | 22 ++++++++++++++++++++++ package.json | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f450a1c01..9eb1073ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,27 @@ # 更新日志 +## 2.13.0 + +- 修复 `
      ` validate 验证不通过回调函数没有调用的问题 [#1059](https://github.com/XiaoMi/hiui/issues/1059) +- 修复 `` 校验不通过时的样式问题 [#1042](https://github.com/XiaoMi/hiui/issues/1042) +- 修复 `` 高度不正确问题 [#1053](https://github.com/XiaoMi/hiui/issues/1053) +- 修复 ``、`` 白色背景的问题 [#1049](https://github.com/XiaoMi/hiui/issues/1049) +- 修复 `` 上传过程中 maxCount 不起作用的问题 [#1032](https://github.com/XiaoMi/hiui/issues/1032) +- 修复 `` 拖拽上传时,tips 展示不正确的问题 [#1041](https://github.com/XiaoMi/hiui/issues/1041) +- 修复 `` 点击每月 31 号,输入框显示异常的问题 [#1039](https://github.com/XiaoMi/hiui/issues/1039) +- 修复 `` title 为 nubmer 类型时的问题 [#1077](https://github.com/XiaoMi/hiui/issues/1077) +- 修复 `` 异步多选受控时,选中项会重复添加的问题 [#1039](https://github.com/XiaoMi/hiui/issues/1039) -- 修复 `` 嵌套使用 type 不生效的问题 [#](https://github.com/XiaoMi/hiui/issues/) +- 修复 `` 在 type 为 date 时执行了农历方法的问题 [#1050](https://github.com/XiaoMi/hiui/issues/1050) +- 修复 `` title 为 nubmer 类型时的问题 [#1077](https://github.com/XiaoMi/hiui/issues/1077) - 修复 `` 优化弹窗位置计算触发机制 [#1072](https://github.com/XiaoMi/hiui/issues/1072) +- 修复 `` 异步多选受控时,选中项会重复添加的问题 [#1044](https://github.com/XiaoMi/hiui/issues/1044) - 修复 `` 嵌套使用 type 不生效的问题 [#1046](https://github.com/XiaoMi/hiui/issues/1046) -- 修复 `` activeId 发生改变时 [#1029](https://github.com/XiaoMi/hiui/issues/1029) +- 修复 `` activeId 发生改变时展开选中项 [#1029](https://github.com/XiaoMi/hiui/issues/1029) - 修复 `` 异步获取数据时,activeId 失效的问题 [#1027](https://github.com/XiaoMi/hiui/issues/1027) -- 优化 `` 展示效果 [#](https://github.com/XiaoMi/hiui/issues/) -- 优化 `` 展示效果 [#](https://github.com/XiaoMi/hiui/issues/) -- 优化 `` 拖拽性能 [#](https://github.com/XiaoMi/hiui/issues/) -- 新增 `` onBeforeSave onBeforeDelete 函数 [#](https://github.com/XiaoMi/hiui/issues/) +- 修复 `` editable 和 searchable 不同同时使用的问题 [#1023](https://github.com/XiaoMi/hiui/issues/1023) +- 优化 `` 展示效果 [#1024](https://github.com/XiaoMi/hiui/issues/1024) +- 优化 `` 展示效果 [#1086](https://github.com/XiaoMi/hiui/issues/1086)[#1048](https://github.com/XiaoMi/hiui/issues/1048) +- 优化 `` 拖拽性能 [#1087](https://github.com/XiaoMi/hiui/issues/1087) +- 新增 `` onBeforeSave onBeforeDelete 函数 [#1093](https://github.com/XiaoMi/hiui/issues/1093) - 新增 `` 普通模式配色 [#1060](https://github.com/XiaoMi/hiui/issues/1060) -- 新增 `` 线性模式 [#](https://github.com/XiaoMi/hiui/issues/) +- 新增 `` 线性模式 [#1088](https://github.com/XiaoMi/hiui/issues/1088) - 新增 `` 支持单独选中父级菜单 [#1038](https://github.com/XiaoMi/hiui/issues/1038) -- 新增 `` confirm 调用方式 [#](https://github.com/XiaoMi/hiui/issues/) +- 新增 `` confirm 调用方式 [#1090](https://github.com/XiaoMi/hiui/issues/1090) - 新增 `` 支持宽度调整 [#1033](https://github.com/XiaoMi/hiui/issues/1033) - 新增 `` 增加月范围选择和年范围选择面板 [#1074](https://github.com/XiaoMi/hiui/issues/1074) -- 新增 `` trigger 属性配置选项展开的触发方式 [#](https://github.com/XiaoMi/hiui/issues/) -- 新增 `` onPageSizeChange 可通过返回 false 来防止触发 onChange [#](https://github.com/XiaoMi/hiui/issues/) +- 新增 `` 快捷方式「近半年」 [#1063](https://github.com/XiaoMi/hiui/issues/1063) +- 新增 `` trigger 属性配置选项展开的触发方式 [#1092](https://github.com/XiaoMi/hiui/issues/1092) +- 新增 `` onPageSizeChange 可通过返回 false 来防止触发 onChange [#1091](https://github.com/XiaoMi/hiui/issues/1091) +- 新增 `` 支持通过 icon 配置 HiUI icon [#1064](https://github.com/XiaoMi/hiui/issues/1064) +- 新增 `` contextMenu 增加层级回调参数 [#1021](https://github.com/XiaoMi/hiui/issues/1021) +- 新增多语言繁体支持 [#1062](https://github.com/XiaoMi/hiui/issues/1062) ## 2.12.0 diff --git a/docs/zh-CN/components/changelog.mdx b/docs/zh-CN/components/changelog.mdx index f450a1c01..b577119d4 100644 --- a/docs/zh-CN/components/changelog.mdx +++ b/docs/zh-CN/components/changelog.mdx @@ -1,5 +1,44 @@ # 更新日志 +## 2.13.0 + +- 修复 `` 行高不正确问题 [#1061](https://github.com/XiaoMi/hiui/issues/1061) +- 修复 `` 在单选情况下受控时清空报错的问题 [#1070](https://github.com/XiaoMi/hiui/issues/1070) +- 修复 `` 受控模式的异步多选,默认选项消失的问题 [#1047](https://github.com/XiaoMi/hiui/issues/1047) +- 修复 `` validate 验证不通过回调函数没有调用的问题 [#1059](https://github.com/XiaoMi/hiui/issues/1059) +- 修复 `` 校验不通过时的样式问题 [#1042](https://github.com/XiaoMi/hiui/issues/1042) [#1036](https://github.com/XiaoMi/hiui/issues/1036) +- 修复 `` 高度不正确问题 [#1053](https://github.com/XiaoMi/hiui/issues/1053) +- 修复 `` 同时展开多个的问题 [#1066](https://github.com/XiaoMi/hiui/issues/1066) +- 修复 ``、`` 白色背景的问题 [#1049](https://github.com/XiaoMi/hiui/issues/1049) +- 修复 `` 上传过程中 maxCount 不起作用的问题 [#1032](https://github.com/XiaoMi/hiui/issues/1032) +- 修复 `` 拖拽上传时,tips 展示不正确的问题 [#1041](https://github.com/XiaoMi/hiui/issues/1041) +- 修复 `` 点击每月 31 号,输入框显示异常的问题 [#1039](https://github.com/XiaoMi/hiui/issues/1039) +- 修复 `` 在 type 为 date 时执行了农历方法的问题 [#1050](https://github.com/XiaoMi/hiui/issues/1050) +- 修复 `` 切换月异常的问题 [#1079](https://github.com/XiaoMi/hiui/issues/1079) +- 修复 `