diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9f0f5db93..88baf74da 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,15 @@
# 更新日志
+## 2.2.1
+
+- 修复 `` 多选时历史数据污染的问题 [#606](https://github.com/XiaoMi/hiui/issues/606)
+- 修复 `` data 无法更新的问题 [#603](https://github.com/XiaoMi/hiui/issues/603)
+- 修复 `` data 无法更新的问题 [#607](https://github.com/XiaoMi/hiui/issues/607)
+- 修复 `` 组件销毁没有清空定时器的问题 [#624](https://github.com/XiaoMi/hiui/issues/624)
+- 修复 `` onClose 失效的问题 [#627](https://github.com/XiaoMi/hiui/issues/627)
+- 修复 `` 长度不够展示时间被遮挡的问题 [#615](https://github.com/XiaoMi/hiui/issues/615)
+- 修复 `
` 动态渲染的时候 removeField 数量不正确的问题 [#636](https://github.com/XiaoMi/hiui/issues/636)
+
## 2.2.0
- 新增 `` 走马灯组件 [#115](https://github.com/XiaoMi/hiui/issues/115)
diff --git a/components/checkbox/Group.js b/components/checkbox/Group.js
index a254d1187..26edc82d2 100644
--- a/components/checkbox/Group.js
+++ b/components/checkbox/Group.js
@@ -9,11 +9,11 @@ const prefixCls = 'hi-checkbox-group'
class Group extends Component {
constructor (props) {
super(props)
- this.state = getData(props)
+ this.state = { data: getData(props), value: props.value }
}
- static getDerivedStateFromProps (nextProps) {
- if (hasValue(nextProps)) {
- return getData(nextProps)
+ static getDerivedStateFromProps (nextProps, state) {
+ if (nextProps.value !== state.value || getData(nextProps) !== state.data) {
+ return { data: getData(nextProps), value: nextProps.value }
}
return null
}
@@ -63,27 +63,24 @@ class Group extends Component {
}
function hasValue (props) {
- const has = (key) => Object.prototype.hasOwnProperty.call(props, key)
- return has('value')
+ return props.value !== undefined
}
function getData (props) {
const { data, value, defaultValue } = props
const _value = hasValue(props) ? value : defaultValue
- return {
- data: data.map((item) => {
- const isPlain = typeof item === 'string'
- const label = isPlain ? item : item.content
- const value = isPlain ? item : item.id
- const disabled = !isPlain && item.disabled
- return {
- label,
- value,
- disabled,
- checked: (_value || []).includes(value)
- }
- })
- }
+ return data.map((item) => {
+ const isPlain = ['string', 'number'].includes(typeof item)
+ const label = isPlain ? item : item.content
+ const value = isPlain ? item : item.id
+ const disabled = !isPlain && item.disabled
+ return {
+ label,
+ value,
+ disabled,
+ checked: (_value || []).includes(value)
+ }
+ })
}
const PropTypesArrayOfStringOrNumber = PropTypes.oneOfType([
diff --git a/components/date-picker/BasePicker.js b/components/date-picker/BasePicker.js
index ae183cb54..4a136c07f 100644
--- a/components/date-picker/BasePicker.js
+++ b/components/date-picker/BasePicker.js
@@ -264,11 +264,11 @@ class BasePicker extends Component {
}
_icon () {
const {isFocus} = this.state
- const { clearable } = this.props
+ const { clearable, type, showTime } = this.props
const iconCls = classNames(
'hi-datepicker__input-icon',
'hi-icon',
- (isFocus && clearable) ? 'icon-close-circle clear' : 'icon-date'
+ (isFocus && clearable) ? 'icon-close-circle clear' : ((showTime || type === 'timeperiod') ? 'icon-time' : 'icon-date')
)
return (isFocus && clearable)
?
@@ -282,12 +282,13 @@ class BasePicker extends Component {
const {
localeDatas,
disabled,
- showTime
+ showTime,
+ type
} = this.props
const _cls = classNames(
'hi-datepicker__input',
'hi-datepicker__input--range',
- showTime && 'hi-datepicker__input--range-time',
+ (showTime || type === 'timeperiod') && 'hi-datepicker__input--range-time',
disabled && 'hi-datepicker__input--disabled'
)
return (
diff --git a/components/date-picker/style/index.scss b/components/date-picker/style/index.scss
index 546079f20..6824e2844 100644
--- a/components/date-picker/style/index.scss
+++ b/components/date-picker/style/index.scss
@@ -32,6 +32,10 @@ $basic-color: #4284f5 !default;
&--range {
width: 320px;
+ &-time {
+ width: 400px;
+ }
+
input {
flex: 0 1 40%;
text-align: center;
diff --git a/components/form/Form.js b/components/form/Form.js
index 579eaf521..1f7c906e7 100644
--- a/components/form/Form.js
+++ b/components/form/Form.js
@@ -41,13 +41,11 @@ class Form extends Component {
}
removeField (prop) {
- const fields = this.state.fields.filter(
- (field) => field.props.field !== prop
- )
-
- this.setState({
- fields
- })
+ this.setState((prevState) => ({
+ fields: prevState.fields.filter(
+ (field) => field.props.field !== prop
+ )
+ }))
}
validate (cb) {
diff --git a/components/form/Item.js b/components/form/Item.js
index 01c88b6e2..7b9f43006 100644
--- a/components/form/Item.js
+++ b/components/form/Item.js
@@ -2,6 +2,7 @@ import React, { Component } from 'react'
import classNames from 'classnames'
import AsyncValidator from 'async-validator'
import PropTypes from 'prop-types'
+import { depreactedPropsCompat } from '../_util'
class FormItem extends Component {
constructor (props, context) {
@@ -215,4 +216,4 @@ FormItem.defaultProps = {
size: 'small'
}
-export default FormItem
+export default depreactedPropsCompat([['field', 'prop']])(FormItem)
diff --git a/components/form/index.js b/components/form/index.js
index 334e83aba..936f96218 100644
--- a/components/form/index.js
+++ b/components/form/index.js
@@ -1,8 +1,7 @@
import Form from './Form'
import Item from './Item'
import './style/index'
-import { depreactedPropsCompat } from '../_util'
-Form.Item = depreactedPropsCompat([['field', 'prop']])(Item)
+Form.Item = Item
export default Form
diff --git a/components/index.js b/components/index.js
index 51ee73cd2..cf4121537 100755
--- a/components/index.js
+++ b/components/index.js
@@ -4,7 +4,7 @@ export { default as Pagination } from './pagination'
export { default as Tabs } from './tabs'
export { default as Table } from './table'
export { default as Notification } from './notification'
-export { handleNotificate } from './notification/HandleNotification'
+export { default as handleNotificate } from './notification/HandleNotification'
export { default as Modal } from './modal'
export { default as Alert } from './alert'
export { default as Panel } from './panel'
diff --git a/components/loading/index.js b/components/loading/index.js
index 1c5381033..56a890c4e 100755
--- a/components/loading/index.js
+++ b/components/loading/index.js
@@ -78,7 +78,7 @@ function deprecatedOpen ({ target, tip } = {}) {
}
function openWrapper (target, options) {
- if (target === null || (target && React.isValidElement(React.cloneElement(target)))) {
+ if (arguments.length >= 2) {
open(target, options)
} else {
return deprecatedOpen(target)
diff --git a/components/notice/Notice.js b/components/notice/Notice.js
index f01abcc0c..f25c1b4fa 100755
--- a/components/notice/Notice.js
+++ b/components/notice/Notice.js
@@ -5,17 +5,22 @@ import { CSSTransition } from 'react-transition-group'
export default class Notice extends Component {
state = { open: false }
+ openTimer = null
+ closeTimer = null
componentDidMount () {
this.setState({
open: true
})
if (this.props.duration !== null) {
- setTimeout(() => {
+ this.openTimer = setTimeout(() => {
this.setState({ open: false })
}, this.props.duration || 3000)
}
}
-
+ componentWillUnmount () {
+ clearTimeout(this.openTimer)
+ clearTimeout(this.closeTimer)
+ }
closeNotice = e => {
if (e) {
e.stopPropagation()
@@ -32,7 +37,7 @@ export default class Notice extends Component {
timeout={0}
classNames={`hi-${prefix}`}
onExited={() => {
- setTimeout(() => this.closeNotice(), 300)
+ this.closeTimer = setTimeout(() => this.closeNotice(), 300)
}}
>
diff --git a/components/notice/NoticeContainer.js b/components/notice/NoticeContainer.js
index 113d47c27..9ecfdf883 100755
--- a/components/notice/NoticeContainer.js
+++ b/components/notice/NoticeContainer.js
@@ -30,7 +30,10 @@ export default class NoticeContainer extends Component {
{
+ this.removeNotice(noticeId)
+ notice.onClose && notice.onClose()
+ }}
duration={notice.duration}
prefix={prefix}
type={notice.type}
diff --git a/components/notification/index.js b/components/notification/index.js
index 48862f5fb..c06a5b2fe 100755
--- a/components/notification/index.js
+++ b/components/notification/index.js
@@ -3,7 +3,7 @@ import './style/index'
import React from 'react'
import Button from '../button'
import classNames from 'classnames'
-import handleNotificate from './HandleNotification'
+import _handleNotificate from './HandleNotification'
const iconMap = {
success: 'chenggong',
@@ -12,6 +12,8 @@ const iconMap = {
info: 'tishi'
}
+export const handleNotificate = _handleNotificate
+
const notification = {
close: key => {
notice.close('notification', key)
diff --git a/components/radio/Group.js b/components/radio/Group.js
index f833510f6..422ae68bb 100644
--- a/components/radio/Group.js
+++ b/components/radio/Group.js
@@ -10,11 +10,11 @@ const prefixCls = 'hi-radio-group'
class Group extends React.Component {
constructor (props) {
super(props)
- this.state = getData(props)
+ this.state = { data: getData(props), value: props.value }
}
- static getDerivedStateFromProps (nextProps) {
- if (hasValue(nextProps)) {
- return getData(nextProps)
+ static getDerivedStateFromProps (nextProps, state) {
+ if (nextProps.value !== state.value || getData(nextProps) !== state.data) {
+ return { data: getData(nextProps), value: nextProps.value }
}
return null
}
@@ -71,27 +71,24 @@ function GroupWrapper ({ children, type, ...restProps }) {
}
function hasValue (props) {
- const has = (key) => Object.prototype.hasOwnProperty.call(props, key)
- return has('value')
+ return props.value !== undefined
}
function getData (props) {
const { data, value, defaultValue } = props
const _value = hasValue(props) ? value : defaultValue
- return {
- data: data.map((item) => {
- const isPlain = typeof item === 'string'
- const label = isPlain ? item : item.content
- const value = isPlain ? item : item.id
- const disabled = !isPlain && item.disabled
- return {
- label,
- value,
- disabled,
- checked: _value === value || Number(_value) === value
- }
- })
- }
+ return data.map((item) => {
+ const isPlain = ['string', 'number'].includes(typeof item)
+ const label = isPlain ? item : item.content
+ const value = isPlain ? item : item.id
+ const disabled = !isPlain && item.disabled
+ return {
+ label,
+ value,
+ disabled,
+ checked: _value === value || Number(_value) === value
+ }
+ })
}
const PropTypesOfStringOrNumber = PropTypes.oneOfType([
diff --git a/components/select/Select.js b/components/select/Select.js
index dd147e10c..03f49f11d 100644
--- a/components/select/Select.js
+++ b/components/select/Select.js
@@ -119,19 +119,9 @@ class Select extends Component {
}
componentWillReceiveProps (nextProps) {
- if (!shallowEqual(nextProps.value, this.props.value)) {
- const selectedItems = this.resetSelectedItems(
- nextProps.value,
- this.state.dropdownItems
- ) // 异步获取时会从内部改变dropdownItems,所以不能从list取
-
- this.setState({
- selectedItems
- })
- }
if (!shallowEqual(nextProps.data, this.props.data)) {
const selectedItems = this.resetSelectedItems(
- nextProps.value,
+ nextProps.value || this.state.selectedItems,
nextProps.data,
true
)
@@ -139,6 +129,17 @@ class Select extends Component {
selectedItems,
dropdownItems: cloneDeep(nextProps.data)
})
+ } else {
+ if (!shallowEqual(nextProps.value, this.props.value)) {
+ const selectedItems = this.resetSelectedItems(
+ nextProps.value,
+ this.state.dropdownItems
+ ) // 异步获取时会从内部改变dropdownItems,所以不能从list取
+
+ this.setState({
+ selectedItems
+ })
+ }
}
}
@@ -166,24 +167,14 @@ class Select extends Component {
return dataSource && !!dataSource.url
}
- resetSelectedItems (value, dropdownItems, listChanged = false) {
+ resetSelectedItems (value, dropdownItems = [], listChanged = false) {
const values = this.parseValue(value)
- const selectedItems =
- listChanged && this.props.type === 'multiple'
- ? this.state.selectedItems
- : [] // 如果是多选,dropdownItems有改动,需要保留之前的选中值
-
- dropdownItems &&
- dropdownItems.map((item) => {
- if (values.indexOf(item.id) !== -1) {
- const itemIndex = selectedItems.findIndex((sItem) => {
- // 多选时检查是否已选中
- return sItem.id === item.id
- })
-
- itemIndex === -1 && selectedItems.push(item)
- }
- })
+ let selectedItems = []
+ dropdownItems.forEach(item => {
+ if (values.includes(item.id)) {
+ selectedItems.push(item)
+ }
+ })
return selectedItems
}
diff --git a/components/tooltip/index.js b/components/tooltip/index.js
index 035145ff8..f8603ce7b 100644
--- a/components/tooltip/index.js
+++ b/components/tooltip/index.js
@@ -27,7 +27,7 @@ class Tooltip extends Component {
}
// 兼容处理 button disabled tooltip 不消失的问题
compatDisabledBtn = el => {
- if (el.type.IS_HI_COMPONENT && el.props.disabled) {
+ if (el && el.type && el.type.IS_HI_COMPONENT && el.props.disabled) {
return React.cloneElement(el, {
style: {
...el.props.style,
diff --git a/docs/demo/modal/section-size.jsx b/docs/demo/modal/section-size.jsx
index d3e94f474..4bf25609c 100644
--- a/docs/demo/modal/section-size.jsx
+++ b/docs/demo/modal/section-size.jsx
@@ -3,7 +3,7 @@ import DocViewer from '../../../libs/doc-viewer'
import Button from '../../../components/button'
import Modal from '../../../components/modal'
import Radio from '../../../components/radio'
-const desc = '通过 size 自定义尺寸,可使用 large、normal、small,默认为 default'
+const desc = '通过 size 自定义尺寸,可使用 large、default、small,默认为 default'
const prefix = 'modal-size'
const code = `import React from 'react'
import Button from '@hi-ui/hiui/es/button'
diff --git a/docs/zh-CN/components/changelog.mdx b/docs/zh-CN/components/changelog.mdx
index 91b88af8e..ec5806ceb 100644
--- a/docs/zh-CN/components/changelog.mdx
+++ b/docs/zh-CN/components/changelog.mdx
@@ -1,5 +1,15 @@
# 更新日志
+## 2.2.1
+
+- 修复 `` 多选时历史数据污染的问题 [#606](https://github.com/XiaoMi/hiui/issues/606)
+- 修复 `` data 无法更新的问题 [#603](https://github.com/XiaoMi/hiui/issues/603)
+- 修复 `` data 无法更新的问题 [#607](https://github.com/XiaoMi/hiui/issues/607)
+- 修复 `` 组件销毁没有清空定时器的问题 [#624](https://github.com/XiaoMi/hiui/issues/624)
+- 修复 `` onClose 失效的问题 [#627](https://github.com/XiaoMi/hiui/issues/627)
+- 修复 `` 长度不够展示时间被遮挡的问题 [#615](https://github.com/XiaoMi/hiui/issues/615)
+- 修复 `` 动态渲染的时候 removeField 数量不正确的问题 [#636](https://github.com/XiaoMi/hiui/issues/636)
+
## 2.2.0
- 新增 `` 走马灯组件 [#115](https://github.com/XiaoMi/hiui/issues/115)
diff --git a/docs/zh-CN/components/dropdown.mdx b/docs/zh-CN/components/dropdown.mdx
index 314674e06..3b4761417 100755
--- a/docs/zh-CN/components/dropdown.mdx
+++ b/docs/zh-CN/components/dropdown.mdx
@@ -44,7 +44,7 @@ import { Badge } from '@libs'
| onClick | 点击后的回调 | (item: DataItem)=> void | - | - |
| prefix | 前缀内容 | string \| ReactNode | - | - |
| suffix | 后缀内容 | string \| ReactNode | - | - |
-| trigger | 下拉菜单触发方式 | string \| string [] | 'click' \| 'contextmenu' \| 'hover' | 'click' |
+| trigger | 下拉菜单触发方式 | string \| string [] | 'click' \| 'contextmenu' | 'click' |
## Type
diff --git a/package-lock.json b/package-lock.json
index 181fff307..8aa0e3243 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "@hi-ui/hiui",
- "version": "2.1.1",
+ "version": "2.2.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -3156,6 +3156,12 @@
"requires": {
"ms": "2.0.0"
}
+ },
+ "qs": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+ "dev": true
}
}
},
@@ -6939,6 +6945,12 @@
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
"dev": true
+ },
+ "qs": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+ "dev": true
}
}
},
@@ -16539,10 +16551,9 @@
"dev": true
},
"qs": {
- "version": "6.7.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
- "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
- "dev": true
+ "version": "6.8.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.8.0.tgz",
+ "integrity": "sha512-tPSkj8y92PfZVbinY1n84i1Qdx75lZjMQYx9WZhnkofyxzw2r7Ho39G3/aEvSUdebxpnnM4LZJCtvE/Aq3+s9w=="
},
"query-string": {
"version": "4.3.4",
diff --git a/package.json b/package.json
index eb81a22ac..5d3d9d787 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@hi-ui/hiui",
- "version": "2.2.0",
+ "version": "2.2.1",
"description": "HIUI for React",
"scripts": {
"test": "node_modules/.bin/standard && node_modules/.bin/stylelint --config .stylelintrc 'components/**/*.scss'",