Skip to content

Commit

Permalink
Merge pull request #605 from XiaoMi/develop
Browse files Browse the repository at this point in the history
2.2.0
  • Loading branch information
solarjoker authored Aug 29, 2019
2 parents 9ca4bd3 + 71cacb4 commit 1539fba
Show file tree
Hide file tree
Showing 24 changed files with 409 additions and 41 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# 更新日志

## 2.2.0

- 新增 `<Carousel />` 走马灯组件 [#115](https://github.com/XiaoMi/hiui/issues/115)
- 新增 `<DatePicker />` clearable 属性控制是否可清空 [#590](https://github.com/XiaoMi/hiui/issues/590)
- 新增 `<Tooltip />` visible 属性手动控制显示或隐藏 [#589](https://github.com/XiaoMi/hiui/issues/589)
- 新增 `<Popover />` visible 属性手动控制显示或隐藏 [#588](https://github.com/XiaoMi/hiui/issues/588)
- 修复 `<Select />` 异步用法 params 不生效的问题 [#587](https://github.com/XiaoMi/hiui/issues/587)
- 修复 `<Tooltip />` 包裹禁用按钮时不能隐藏的问题 [#583](https://github.com/XiaoMi/hiui/issues/583)
- 修复 `<Popover />` 中含输入项时失焦造成的问题 [#581](https://github.com/XiaoMi/hiui/issues/581)
- 修复 `<Tree />` 清空搜索条件后无法收起的问题 [#561](https://github.com/XiaoMi/hiui/issues/561)

## 2.1.2

- 修复 `<Input />` clearable 不生效的问题 [#580](https://github.com/XiaoMi/hiui/issues/580)
Expand Down
1 change: 1 addition & 0 deletions components/button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ import ButtonGroup from './ButtonGroup'
import './style/index'

Button.Group = ButtonGroup
Button.IS_HI_COMPONENT = true
export default Button
177 changes: 177 additions & 0 deletions components/carousel/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import Icon from '../icon'
import classNames from 'classnames'
import './style/index'

// const url = 'http://i1.mifile.cn/f/i/hiui/docs/'
class Carousel extends Component {
constructor (props) {
super(props)
this.rootRef = React.createRef()
const defaultActive = props.defaultActive
this.state = {
rootWidth: 0,
showArrow: false,
active: (defaultActive >= props.children.length || defaultActive < 0) ? 0 : defaultActive
}
this.timer = null
}

componentDidMount () {
this.setState({
rootWidth: this.rootRef.current.clientWidth
}, () => {
if (this.props.duration) {
this.autoPage()
}
})
}

goTo (page) {
if (page > this.props.children.length || page < 0) {
return
}
this.setState({
active: page
})
}
componentWillUnmount () {
this.timer && window.clearInterval(this.timer)
}

autoPage () {
this.timer = window.setInterval(() => {
this.preNextEvent(1)
}, this.props.duration)
}

pageEvent (active) {
this.setState({
active
})
}

preNextEvent (val) {
let active = this.state.active + val
if (active >= this.props.children.length) {
active = 0
}
this.setState({
active
})
}

renderDot (type, key, index, active) {
if (type === 'sign') {
return <li className='hi-carousel__dot hi-carousel__dot--sign' />
} else {
const cls = classNames(
'hi-carousel__dot',
active === index && 'hi-carousel__dot--active'
)
return (
<li
className={cls}
key={index}
onClick={this.pageEvent.bind(this, index)}
/>
)
}
}

mouseEvent (type) {
let showArrow = true
if (type === 'over') {
this.timer && window.clearInterval(this.timer)
} else {
showArrow = false
this.props.duration && this.autoPage()
}
this.setState({showArrow})
}
render () {
const { rootWidth, active, showArrow } = this.state
const { showDots, showArrows } = this.props
const children = React.Children.toArray(this.props.children)
const arrowCls = classNames(
'hi-carousel__arrows',
showArrow && 'hi-carousel__arrows--show'
)
return <div
className='hi-carousel'
ref={this.rootRef}
onMouseOver={this.mouseEvent.bind(this, 'over')}
onMouseOut={this.mouseEvent.bind(this, 'out')}>
<div
className='hi-carousel__container'
style={{
width: rootWidth * children.length
}}
>
{
children.map((child, index) => {
return React.cloneElement(child, {
key: index,
style: {
position: 'relative',
opacity: active === index ? 1 : 0,
transition: 'opacity 300ms ease 0s',
left: -(rootWidth * index),
width: rootWidth,
display: 'inline-block',
fontSize: 24,
...child.props.style
}
})
})
}
</div>
{
showArrows && <ul className={arrowCls}>
<li className='hi-carousel__arrow' onClick={this.preNextEvent.bind(this, -1)}>
<Icon name='left' />
</li>
<li className='hi-carousel__arrow' onClick={this.preNextEvent.bind(this, 1)}>
<Icon name='right' />
</li>
</ul>
}
{
showDots && <ul className='hi-carousel__dots'>
{
children.map((_, index) => {
const cls = classNames('hi-carousel__dot', active === index && 'hi-carousel__dot--active')
return <li
className={cls}
key={index}
onClick={this.pageEvent.bind(this, index)}
/>
})
}
</ul>
}
</div>
}
}

Carousel.propTypes = {
duration: PropTypes.number,
onClick: PropTypes.func,
beforeChange: PropTypes.func,
afterChange: PropTypes.func,
showDots: PropTypes.bool,
showArrows: PropTypes.bool,
defaultActive: PropTypes.number
}
Carousel.defaultProps = {
duration: 0,
onClick: () => {},
beforeChange: () => {},
afterChange: () => {},
showDots: true,
showArrows: true,
defaultActive: 0
}

export default Carousel
1 change: 1 addition & 0 deletions components/carousel/style/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import './index.scss'
74 changes: 74 additions & 0 deletions components/carousel/style/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
.hi-carousel {
width: 100%;
color: rgba(153, 153, 153, 1);
overflow: hidden;
position: relative;

&__container {
height: 100%;
transition: all 500ms;
}

&__dots {
position: absolute;
bottom: 24px;
margin: 0;
padding: 0;
left: 50%;
transform: translateX(-50%);
}

&__dot {
width: 24px;
height: 4px;
background: rgba(255, 255, 255, 0.4);
border-radius: 2px;
display: inline-block;
margin-left: 4px;
cursor: pointer;
transition: all 1s;

&--active:not(.hi-carousel__dot--sign) {
background: rgba(255, 255, 255, 1);
width: 48px;
}

&--sign {
width: 24px;
}
}

&__arrows {
position: absolute;
width: 100%;
list-style: none;
margin: 0;
padding: 0;
top: 50%;
transform: translateY(-28px);
display: flex;
justify-content: space-between;
visibility: hidden;

&--show {
visibility: visible;
}
}

&__arrow {
width: 56px;
height: 56px;
background: rgba(0, 0, 0, 0.25);
border-radius: 50%;
text-align: center;
line-height: 56px;
color: #fff;
font-size: 32px;
margin-left: 24px;
cursor: pointer;

&:last-child {
margin-right: 24px;
}
}
}
14 changes: 10 additions & 4 deletions components/date-picker/BasePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -264,12 +264,13 @@ class BasePicker extends Component {
}
_icon () {
const {isFocus} = this.state
const { clearable } = this.props
const iconCls = classNames(
'hi-datepicker__input-icon',
'hi-icon',
isFocus ? 'icon-close-circle clear' : 'icon-date'
(isFocus && clearable) ? 'icon-close-circle clear' : 'icon-date'
)
return isFocus
return (isFocus && clearable)
? <span className={iconCls} onClick={this._clear.bind(this)} />
: <span className={iconCls} onClick={(e) => {
if (this.props.disabled) return
Expand Down Expand Up @@ -341,6 +342,9 @@ BasePicker.propTypes = {
if (val === undefined || val === null) {
return null
}
if (!val) {
return null
}
if (val.start && val.end) {
const _start = dateFormat(val.start)
const _end = dateFormat(val.end)
Expand All @@ -364,13 +368,15 @@ BasePicker.propTypes = {
if (val < 5 || val > 480 || (val > 60 && val % 60 !== 0) || (val < 60 && 60 % val !== 0)) {
return new Error(`Invalid prop ${propName} supplied to ${componentName}. This value must be greater than 5 and less than 480 and is a multiple of 60.`)
}
}
},
clearable: PropTypes.bool
}
BasePicker.defaultProps = {
type: 'date',
disabled: false,
showWeekNumber: true,
weekOffset: 0,
timeInterval: 240
timeInterval: 240,
clearable: true
}
export default BasePicker
1 change: 1 addition & 0 deletions components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,5 @@ export { default as Rate } from './rate'
export { default as Message } from './message'
export { default as Tag } from './tag'
export { default as Breadcrumb } from './breadcrumb'
export { default as Carousel } from './carousel'
export { ThemeContext, LocaleContext } from './context'
12 changes: 6 additions & 6 deletions components/popover/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ export default class Popover extends Component {

this.element = ReactDOM.findDOMNode(this)
const referenceRef = ReactDOM.findDOMNode(this.referenceRef)
// this.reference = ReactDOM.findDOMNode(this.refs.reference)
if (referenceRef === null) return

if (trigger === 'click') {
Expand Down Expand Up @@ -105,27 +104,28 @@ export default class Popover extends Component {
this.unbindHover = false
popper.current.addEventListener('mouseenter', e => {
this.eventTarget = e.target
// this.showPopper()
})
popper.current.addEventListener('mouseleave', e => {
this.delayHidePopper(e)
const poperPosition = popper.current.getBoundingClientRect()
if (e.clientY > poperPosition.y + poperPosition.height - 1 || e.clientY < poperPosition.y || e.clientX < poperPosition.x || e.clientX > poperPosition.x + poperPosition.width - 1) {
this.delayHidePopper(e)
}
})
}
}

render () {
const { style, className, title, content, placement, width } = this.props
const { style, className, title, content, placement, width, visible } = this.props
const {
showPopper
} = this.state

return (
<div className={classNames(className, 'hi-popover')} style={style} ref={node => { this.popoverContainer = node }}>
{ React.cloneElement(React.Children.only(this.props.children), { ref: (el) => { this.referenceRef = el }, tabIndex: '0' }) }

<Popper
className='hi-popover__popper'
show={showPopper}
show={[true, false].includes(visible) ? visible : showPopper}
attachEle={this.popoverContainer}
placement={placement}
zIndex={1040}
Expand Down
Loading

0 comments on commit 1539fba

Please sign in to comment.