Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #642

Merged
merged 22 commits into from
Sep 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# 更新日志

## 2.2.1

- 修复 `<Select />` 多选时历史数据污染的问题 [#606](https://github.com/XiaoMi/hiui/issues/606)
- 修复 `<Checkbox />` data 无法更新的问题 [#603](https://github.com/XiaoMi/hiui/issues/603)
- 修复 `<Radio />` data 无法更新的问题 [#607](https://github.com/XiaoMi/hiui/issues/607)
- 修复 `<Notification />` 组件销毁没有清空定时器的问题 [#624](https://github.com/XiaoMi/hiui/issues/624)
- 修复 `<Notification />` onClose 失效的问题 [#627](https://github.com/XiaoMi/hiui/issues/627)
- 修复 `<DatePicker />` 长度不够展示时间被遮挡的问题 [#615](https://github.com/XiaoMi/hiui/issues/615)
- 修复 `<Form />` 动态渲染的时候 removeField 数量不正确的问题 [#636](https://github.com/XiaoMi/hiui/issues/636)

## 2.2.0

- 新增 `<Carousel />` 走马灯组件 [#115](https://github.com/XiaoMi/hiui/issues/115)
Expand Down
37 changes: 17 additions & 20 deletions components/checkbox/Group.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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([
Expand Down
9 changes: 5 additions & 4 deletions components/date-picker/BasePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
? <span className={iconCls} onClick={this._clear.bind(this)} />
Expand All @@ -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 (
Expand Down
4 changes: 4 additions & 0 deletions components/date-picker/style/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ $basic-color: #4284f5 !default;
&--range {
width: 320px;

&-time {
width: 400px;
}

input {
flex: 0 1 40%;
text-align: center;
Expand Down
12 changes: 5 additions & 7 deletions components/form/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
3 changes: 2 additions & 1 deletion components/form/Item.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -215,4 +216,4 @@ FormItem.defaultProps = {
size: 'small'
}

export default FormItem
export default depreactedPropsCompat([['field', 'prop']])(FormItem)
3 changes: 1 addition & 2 deletions components/form/index.js
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
2 changes: 1 addition & 1 deletion components/loading/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
11 changes: 8 additions & 3 deletions components/notice/Notice.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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)
}}
>
<div className={classNames(`hi-${prefix}`, { [`hi-${prefix}--${type}`]: type })}>
Expand Down
5 changes: 4 additions & 1 deletion components/notice/NoticeContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ export default class NoticeContainer extends Component {
<Notice
key={notice.key}
id={notice.key}
onClose={this.removeNotice}
onClose={noticeId => {
this.removeNotice(noticeId)
notice.onClose && notice.onClose()
}}
duration={notice.duration}
prefix={prefix}
type={notice.type}
Expand Down
4 changes: 3 additions & 1 deletion components/notification/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -12,6 +12,8 @@ const iconMap = {
info: 'tishi'
}

export const handleNotificate = _handleNotificate

const notification = {
close: key => {
notice.close('notification', key)
Expand Down
37 changes: 17 additions & 20 deletions components/radio/Group.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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([
Expand Down
47 changes: 19 additions & 28 deletions components/select/Select.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,26 +119,27 @@ 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
)
this.setState({
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
})
}
}
}

Expand Down Expand Up @@ -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
}

Expand Down
2 changes: 1 addition & 1 deletion components/tooltip/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion docs/demo/modal/section-size.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
Loading