From a47c6ef75bd6a4e52d9e56aa91f00c56f3d9ddf6 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Thu, 27 Dec 2018 22:14:32 +0800 Subject: [PATCH 01/63] feat: add multiFormats --- components/_util/BaseMixin.js | 28 ++--- components/vc-calendar/demo/antd-calendar.vue | 38 +++++- components/vc-calendar/index.js | 2 +- components/vc-calendar/src/Calendar.jsx | 6 +- components/vc-calendar/src/date/DateInput.jsx | 112 ++++++++++-------- components/vc-calendar/src/locale/it_IT.js | 14 +-- components/vc-calendar/src/util/index.js | 12 ++ 7 files changed, 140 insertions(+), 72 deletions(-) diff --git a/components/_util/BaseMixin.js b/components/_util/BaseMixin.js index 1897d3cfe..f01a6b5e3 100644 --- a/components/_util/BaseMixin.js +++ b/components/_util/BaseMixin.js @@ -1,21 +1,21 @@ export default { - directives: { - ref: { - bind: function (el, binding, vnode) { - binding.value(vnode.componentInstance ? vnode.componentInstance : vnode.elm) - }, - update: function (el, binding, vnode) { - binding.value(vnode.componentInstance ? vnode.componentInstance : vnode.elm) - }, - unbind: function (el, binding, vnode) { - binding.value(null) - }, - }, - }, + // directives: { + // ref: { + // bind: function (el, binding, vnode) { + // binding.value(vnode.componentInstance ? vnode.componentInstance : vnode.elm) + // }, + // update: function (el, binding, vnode) { + // binding.value(vnode.componentInstance ? vnode.componentInstance : vnode.elm) + // }, + // unbind: function (el, binding, vnode) { + // binding.value(null) + // }, + // }, + // }, methods: { setState (state, callback) { - const newState = typeof state === 'function' ? state(this.$data) : state + const newState = typeof state === 'function' ? state(this.$data, this.$props) : state // if (this.getDerivedStateFromProps) { // Object.assign(newState, this.getDerivedStateFromProps(getOptionProps(this), { ...this.$data, ...newState }, true) || {}) // } diff --git a/components/vc-calendar/demo/antd-calendar.vue b/components/vc-calendar/demo/antd-calendar.vue index aef18638a..edc45f623 100644 --- a/components/vc-calendar/demo/antd-calendar.vue +++ b/components/vc-calendar/demo/antd-calendar.vue @@ -183,6 +183,39 @@ const Demo = { }, } +const multiFormats = ['DD/MM/YYYY', 'DD/MM/YY', 'DDMMYY', 'D/M/YY'] + +const DemoMultiFormat = { + data: () => ({ + value: now, + }), + methods: { + onChange (value) { + console.log('Calendar change: ', (value && value.format(format))) + this.value = value + }, + }, + + render () { + const state = this.$data + return (
+
+ Accepts multiple input formats +
+ {multiFormats.join(', ')} +
+ +
) + }, +} + function onStandaloneSelect (value) { console.log('onStandaloneSelect') console.log(value && value.format(format)) @@ -212,7 +245,7 @@ export default { defaultValue={now} disabledTime={disabledTime} showToday - formatter={getFormat(true)} + format={getFormat(true)} showOk={false} timePicker={timePickerElement(h)} onChange={onStandaloneChange} @@ -228,6 +261,9 @@ export default {
+
+ +
) diff --git a/components/vc-calendar/index.js b/components/vc-calendar/index.js index ecdc1894c..d2486831c 100644 --- a/components/vc-calendar/index.js +++ b/components/vc-calendar/index.js @@ -1,3 +1,3 @@ -// based on rc-calendar 9.7.9 +// based on rc-calendar 9.8.2 import Calendar from './src/' export default Calendar diff --git a/components/vc-calendar/src/Calendar.jsx b/components/vc-calendar/src/Calendar.jsx index ccfc1628d..f25f4eadb 100644 --- a/components/vc-calendar/src/Calendar.jsx +++ b/components/vc-calendar/src/Calendar.jsx @@ -26,7 +26,7 @@ const MomentType = PropTypes.custom(isMoment) const Calendar = { props: { locale: PropTypes.object.def(enUs), - format: PropTypes.string, + format: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), visible: PropTypes.bool.def(true), prefixCls: PropTypes.string.def('rc-calendar'), // prefixCls: PropTypes.string, @@ -295,7 +295,9 @@ const Calendar = { selectedValue={sSelectedValue} value={sValue} disabledDate={disabledDate} - okDisabled={!this.isAllowedDate(sSelectedValue)} + okDisabled={ + props.showOk !== false && (!sSelectedValue || !this.isAllowedDate(sSelectedValue)) + } onOk={this.onOk} onSelect={this.onSelect} onToday={this.onToday} diff --git a/components/vc-calendar/src/date/DateInput.jsx b/components/vc-calendar/src/date/DateInput.jsx index b5cb9da62..cba7f95e6 100644 --- a/components/vc-calendar/src/date/DateInput.jsx +++ b/components/vc-calendar/src/date/DateInput.jsx @@ -3,6 +3,7 @@ import PropTypes from '../../../_util/vue-types' import BaseMixin from '../../../_util/BaseMixin' import { getComponentFromProp } from '../../../_util/props-util' import moment from 'moment' +import { formatDate } from '../util' const DateInput = { mixins: [BaseMixin], @@ -11,7 +12,7 @@ const DateInput = { timePicker: PropTypes.object, value: PropTypes.object, disabledTime: PropTypes.any, - format: PropTypes.string, + format: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), locale: PropTypes.object, disabledDate: PropTypes.func, // onChange: PropTypes.func, @@ -25,8 +26,9 @@ const DateInput = { data () { const selectedValue = this.selectedValue return { - str: selectedValue && selectedValue.format(this.format) || '', + str: formatDate(selectedValue, this.format), invalid: false, + hasFocus: false, } }, watch: { @@ -40,7 +42,7 @@ const DateInput = { updated () { this.$nextTick(() => { - if (!this.invalid && + if (this.$data.hasFocus && !this.invalid && !(this.cachedSelectionStart === 0 && this.cachedSelectionEnd === 0)) { this.$refs.dateInputInstance.setSelectionRange(this.cachedSelectionStart, this.cachedSelectionEnd) } @@ -52,56 +54,60 @@ const DateInput = { this.cachedSelectionEnd = this.$refs.dateInputInstance.selectionEnd // when popup show, click body will call this, bug! const selectedValue = this.selectedValue - this.setState({ - str: selectedValue && selectedValue.format(this.format) || '', - invalid: false, - }) + if (!this.$data.hasFocus) { + this.setState({ + str: formatDate(selectedValue, this.format), + invalid: false, + }) + } }, onInputChange (event) { const str = event.target.value - this.setState({ - str, - }) - let value - const { disabledDate, format } = this - if (str) { - const parsed = moment(str, format, true) - if (!parsed.isValid()) { - this.setState({ - invalid: true, - }) - return - } - value = this.value.clone() - value - .year(parsed.year()) - .month(parsed.month()) - .date(parsed.date()) - .hour(parsed.hour()) - .minute(parsed.minute()) - .second(parsed.second()) + const { disabledDate, format, selectedValue } = this.$props - if (value && (!disabledDate || !disabledDate(value))) { - const originalValue = this.selectedValue - if (originalValue && value) { - if (!originalValue.isSame(value)) { - this.__emit('change', value) - } - } else if (originalValue !== value) { - this.__emit('change', value) - } - } else { - this.setState({ - invalid: true, - }) - return - } - } else { + // 没有内容,合法并直接退出 + if (!str) { this.__emit('change', null) + this.setState({ + invalid: false, + str, + }) + return + } + + const parsed = moment(str, format, true) + if (!parsed.isValid()) { + this.setState({ + invalid: true, + str, + }) + return + } + const value = this.value.clone() + value + .year(parsed.year()) + .month(parsed.month()) + .date(parsed.date()) + .hour(parsed.hour()) + .minute(parsed.minute()) + .second(parsed.second()) + + if (!value || (disabledDate && disabledDate(value))) { + this.setState({ + invalid: true, + str, + }) + return + } + + if (selectedValue !== value || ( + selectedValue && value && !selectedValue.isSame(value) + )) { + this.setState({ + str, + }) + this.__emit('change', value) } - this.setState({ - invalid: false, - }) }, onClear () { @@ -120,6 +126,16 @@ const DateInput = { this.$refs.dateInputInstance.focus() } }, + onFocus () { + this.setState({ hasFocus: true }) + }, + + onBlur () { + this.setState((prevState, prevProps) => ({ + hasFocus: false, + str: formatDate(prevProps.value, prevProps.format), + })) + }, }, render () { @@ -135,6 +151,8 @@ const DateInput = { disabled={disabled} placeholder={placeholder} onInput={this.onInputChange} + onFocus={this.onFocus} + onBlur={this.onBlur} /> {showClear ? Date: Mon, 31 Dec 2018 22:08:27 +0800 Subject: [PATCH 02/63] feat: update vc-cascaser vc-checkbox vc-collapse --- components/vc-cascader/Cascader.jsx | 5 ++++- components/vc-cascader/index.js | 2 +- components/vc-checkbox/index.js | 2 +- components/vc-checkbox/src/Checkbox.jsx | 2 +- components/vc-collapse/index.js | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/components/vc-cascader/Cascader.jsx b/components/vc-cascader/Cascader.jsx index a504ded48..139e0be1e 100644 --- a/components/vc-cascader/Cascader.jsx +++ b/components/vc-cascader/Cascader.jsx @@ -83,7 +83,7 @@ export default { initialValue = defaultValue || [] } // warning(!('filedNames' in props), - // '`filedNames` of Cascader is a typo usage and deprecated, please use `fieldNames` intead.'); + // '`filedNames` of Cascader is a typo usage and deprecated, please use `fieldNames` instead.'); return { sPopupVisible: popupVisible, @@ -242,6 +242,7 @@ export default { return } if (e.keyCode === KeyCode.DOWN || e.keyCode === KeyCode.UP) { + e.preventDefault() let nextIndex = currentIndex if (nextIndex !== -1) { if (e.keyCode === KeyCode.DOWN) { @@ -256,8 +257,10 @@ export default { } activeValue[currentLevel] = currentOptions[nextIndex][this.getFieldName('value')] } else if (e.keyCode === KeyCode.LEFT || e.keyCode === KeyCode.BACKSPACE) { + e.preventDefault() activeValue.splice(activeValue.length - 1, 1) } else if (e.keyCode === KeyCode.RIGHT) { + e.preventDefault() if (currentOptions[currentIndex] && currentOptions[currentIndex][this.getFieldName('children')]) { activeValue.push(currentOptions[currentIndex][this.getFieldName('children')][0][this.getFieldName('value')]) diff --git a/components/vc-cascader/index.js b/components/vc-cascader/index.js index 5493ec1b2..fbadc97e0 100644 --- a/components/vc-cascader/index.js +++ b/components/vc-cascader/index.js @@ -1,3 +1,3 @@ -// based on rc-cascader 0.16.0 +// based on rc-cascader 0.16.2 import Cascader from './Cascader' export default Cascader diff --git a/components/vc-checkbox/index.js b/components/vc-checkbox/index.js index 5008cca7b..0914da164 100644 --- a/components/vc-checkbox/index.js +++ b/components/vc-checkbox/index.js @@ -1,2 +1,2 @@ -// based on rc-checkbox 2.1.5 +// based on rc-checkbox 2.1.6 export { default } from './src/' diff --git a/components/vc-checkbox/src/Checkbox.jsx b/components/vc-checkbox/src/Checkbox.jsx index 3cfe0d5ca..4a1ad3f56 100644 --- a/components/vc-checkbox/src/Checkbox.jsx +++ b/components/vc-checkbox/src/Checkbox.jsx @@ -20,7 +20,7 @@ export default { // onBlur: PropTypes.func, // onChange: PropTypes.func, // onClick: PropTypes.func, - tabIndex: PropTypes.string, + tabIndex: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), readOnly: PropTypes.bool, autoFocus: PropTypes.bool, value: PropTypes.any, diff --git a/components/vc-collapse/index.js b/components/vc-collapse/index.js index 874d7a9ad..2ae78c34f 100644 --- a/components/vc-collapse/index.js +++ b/components/vc-collapse/index.js @@ -1,4 +1,4 @@ -// based on rc-collapse 1.10.0 +// based on rc-collapse 1.10.2 import CollapsePanel from './src/Panel' import Collapse from './src/Collapse' import { collapseProps, panelProps } from './src/commonProps' From 429e7f4b7202e00c887117628b398db9027e04a5 Mon Sep 17 00:00:00 2001 From: wangxueliang Date: Tue, 1 Jan 2019 15:33:43 +0800 Subject: [PATCH 03/63] feat: add comment --- .../__tests__/__snapshots__/demo.test.js.snap | 167 ++++++++++++++++++ components/comment/__tests__/demo.test.js | 3 + components/comment/demo/basic.md | 78 ++++++++ components/comment/demo/editor.md | 93 ++++++++++ components/comment/demo/index.vue | 52 ++++++ components/comment/demo/list.md | 61 +++++++ components/comment/demo/nested.md | 74 ++++++++ components/comment/index.en-US.md | 10 ++ components/comment/index.jsx | 96 ++++++++++ components/comment/index.zh-CN.md | 24 +++ components/comment/style/index.js | 2 + components/comment/style/index.less | 93 ++++++++++ components/index.js | 4 + components/style.js | 1 + components/style/themes/default.less | 9 + site/components.js | 2 + site/demo.js | 6 + site/demoRoutes.js | 8 + 18 files changed, 783 insertions(+) create mode 100644 components/comment/__tests__/__snapshots__/demo.test.js.snap create mode 100755 components/comment/__tests__/demo.test.js create mode 100644 components/comment/demo/basic.md create mode 100644 components/comment/demo/editor.md create mode 100644 components/comment/demo/index.vue create mode 100644 components/comment/demo/list.md create mode 100644 components/comment/demo/nested.md create mode 100644 components/comment/index.en-US.md create mode 100644 components/comment/index.jsx create mode 100644 components/comment/index.zh-CN.md create mode 100644 components/comment/style/index.js create mode 100644 components/comment/style/index.less diff --git a/components/comment/__tests__/__snapshots__/demo.test.js.snap b/components/comment/__tests__/__snapshots__/demo.test.js.snap new file mode 100644 index 000000000..6ebcdcd34 --- /dev/null +++ b/components/comment/__tests__/__snapshots__/demo.test.js.snap @@ -0,0 +1,167 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders ./components/comment/demo/basic.md correctly 1`] = ` +
+
+
Han Solo
+
+ +
+

We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.

+
+
    +
  • + 0 +
  • +
  • +
  • + 0 +
  • +
  • +
  • Reply to
  • +
+
+
+
+`; + +exports[`renders ./components/comment/demo/editor.md correctly 1`] = ` +
+ +
+
+
Han Solo
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+`; + +exports[`renders ./components/comment/demo/list.md correctly 1`] = ` +
+
2 replies
+
+
+
+
+
+
+
+
+ +
+

We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.

+
+
    +
  • Reply to
  • +
+
+
+
+
+
+
+
+
+
+
+
+ +
+

We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure), to help people create their product prototypes beautifully and efficiently.

+
+
    +
  • Reply to
  • +
+
+
+
+
+
+
+
+
+`; + +exports[`renders ./components/comment/demo/nested.md correctly 1`] = ` +
+
+
Han Solo
+
+ +
+

We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure).

+
+
    +
  • Reply to
  • +
+
+
+
+
+
+
Han Solo
+
+ +
+

We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure).

+
+
    +
  • Reply to
  • +
+
+
+
+
+
+
Han Solo
+
+ +
+

We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure).

+
+
    +
  • Reply to
  • +
+
+
+
+
+
+
Han Solo
+
+ +
+

We supply a series of design principles, practical patterns and high quality design resources (Sketch and Axure).

+
+
    +
  • Reply to
  • +
+
+
+
+
+
+
+
+`; diff --git a/components/comment/__tests__/demo.test.js b/components/comment/__tests__/demo.test.js new file mode 100755 index 000000000..83f648004 --- /dev/null +++ b/components/comment/__tests__/demo.test.js @@ -0,0 +1,3 @@ +import demoTest from '../../../tests/shared/demoTest' + +demoTest('comment') diff --git a/components/comment/demo/basic.md b/components/comment/demo/basic.md new file mode 100644 index 000000000..d851d211f --- /dev/null +++ b/components/comment/demo/basic.md @@ -0,0 +1,78 @@ + +#### 基本评论 +一个基本的评论组件,带有作者、头像、时间和操作。 + + + +#### Basic comment +A basic comment with author, avatar, time and actions. + + +```html + + +``` diff --git a/components/comment/demo/editor.md b/components/comment/demo/editor.md new file mode 100644 index 000000000..6fd229342 --- /dev/null +++ b/components/comment/demo/editor.md @@ -0,0 +1,93 @@ + +#### 回复框 +评论编辑器组件提供了相同样式的封装以支持自定义评论编辑器。 + + + +#### Reply Editor +Comment can be used as editor, user can customize the editor component. + + +```html + + +``` diff --git a/components/comment/demo/index.vue b/components/comment/demo/index.vue new file mode 100644 index 000000000..4dde88949 --- /dev/null +++ b/components/comment/demo/index.vue @@ -0,0 +1,52 @@ + diff --git a/components/comment/demo/list.md b/components/comment/demo/list.md new file mode 100644 index 000000000..0fe00d454 --- /dev/null +++ b/components/comment/demo/list.md @@ -0,0 +1,61 @@ + +#### 配合 List 组件 +配合 List 组件展现评论列表。 + + + +#### Usage with list +Displaying a series of comments using the `antd` List Component. + + +```html + + +``` diff --git a/components/comment/demo/nested.md b/components/comment/demo/nested.md new file mode 100644 index 000000000..4f28249e5 --- /dev/null +++ b/components/comment/demo/nested.md @@ -0,0 +1,74 @@ + +#### 嵌套评论 +评论可以嵌套。 + + + +#### Nested comments +Comments can be nested. + + +```html + +``` diff --git a/components/comment/index.en-US.md b/components/comment/index.en-US.md new file mode 100644 index 000000000..6c66ecbb9 --- /dev/null +++ b/components/comment/index.en-US.md @@ -0,0 +1,10 @@ +## API + +| Property | Description | Type | Default | +| -------- | ----------- | ---- | ------- | +| actions | List of action items rendered below the comment content | Array | slot | - | +| author | The element to display as the comment author | string\|slot | - | +| avatar | The element to display as the comment avatar - generally an antd `Avatar` or src | string\|slot | - | +| children | Nested comments should be provided as children of the Comment | slot | - | +| content | The main content of the comment | string\|slot | - | +| datetime | A datetime element containing the time to be displayed | string\|slot | - | diff --git a/components/comment/index.jsx b/components/comment/index.jsx new file mode 100644 index 000000000..0d9ffd1ff --- /dev/null +++ b/components/comment/index.jsx @@ -0,0 +1,96 @@ +import PropsTypes from '../_util/vue-types' +import { initDefaultProps, getComponentFromProp } from '../_util/props-util' +import classNames from 'classnames' + +export const CommentProps = { + actions: PropsTypes.array, + /** The element to display as the comment author. */ + author: PropsTypes.any, + /** The element to display as the comment avatar - generally an antd Avatar */ + avatar: PropsTypes.any, + /** The main content of the comment */ + content: PropsTypes.any, + /** Comment prefix defaults to '.ant-comment' */ + prefixCls: PropsTypes.string, + /** A datetime element containing the time to be displayed */ + datetime: PropsTypes.any, +} + +const Comment = { + name: 'AComment', + props: initDefaultProps(CommentProps, { + prefixCls: 'ant-comment', + }), + methods: { + getAction (actions) { + if (!actions || !actions.length) { + return null + } + const actionList = actions.map((action, index) =>
  • {action}
  • ) + return actionList + }, + renderNested (children) { + const { prefixCls } = this.$props + + return
    {children}
    + }, + }, + + render () { + const { + prefixCls, + } = this.$props + + const actions = this.$props.actions || getComponentFromProp(this, 'actions') + const author = this.$props.author || getComponentFromProp(this, 'author') + const avatar = this.$props.avatar || getComponentFromProp(this, 'avatar') + const content = this.$props.content || getComponentFromProp(this, 'content') + const datetime = this.$props.datetime || getComponentFromProp(this, 'datetime') + + const avatarDom = ( +
    + {typeof avatar === 'string' ? : avatar} +
    + ) + + const actionDom = + actions && actions.length ? ( + + ) : null + + const authorContent = ( +
    + {author && } + {datetime && } +
    + ) + + const contentDom = ( +
    + {authorContent} +
    {content}
    + {actionDom} +
    + ) + + const comment = ( +
    + {avatarDom} + {contentDom} +
    + ) + const children = this.$slots.default + return ( +
    + {comment} + {children ? this.renderNested(children) : null} +
    + ) + }, +} + +/* istanbul ignore next */ +Comment.install = function (Vue) { + Vue.component(Comment.name, Comment) +} +export default Comment diff --git a/components/comment/index.zh-CN.md b/components/comment/index.zh-CN.md new file mode 100644 index 000000000..115fb79c9 --- /dev/null +++ b/components/comment/index.zh-CN.md @@ -0,0 +1,24 @@ +--- +category: Components +type: 数据展示 +title: Comment +subtitle: 评论 +cols: 1 +--- + +对网站内容的反馈、评价和讨论。 + +## 何时使用 + +评论组件可用于对事物的讨论,例如页面、博客文章、问题等等。 + +## API + +| Property | Description | Type | Default | +| -------- | ----------- | ---- | ------- | +| actions | 在评论内容下面呈现的操作项列表 | Array|slot | - | +| author | 要显示为注释作者的元素 | string\|slot | - | +| avatar | 要显示为评论头像的元素 - 通常是 antd `Avatar` 或者src | string\|slot | - | +| children | 嵌套注释应作为注释的子项提供 | slot | - | +| content | 评论的主要内容 | string\|slot | - | +| datetime | 展示时间描述 | string\|slot | - | diff --git a/components/comment/style/index.js b/components/comment/style/index.js new file mode 100644 index 000000000..cf31ed80f --- /dev/null +++ b/components/comment/style/index.js @@ -0,0 +1,2 @@ +import '../../style/index.less' +import './index.less' diff --git a/components/comment/style/index.less b/components/comment/style/index.less new file mode 100644 index 000000000..891ea4209 --- /dev/null +++ b/components/comment/style/index.less @@ -0,0 +1,93 @@ +@import '../../style/themes/default'; +@import '../../style/mixins/index'; + +@comment-prefix-cls: ~'@{ant-prefix}-comment'; + +.@{comment-prefix-cls} { + position: relative; + + &-inner { + padding: @comment-padding-base; + display: flex; + } + + &-avatar { + flex-shrink: 0; + position: relative; + margin-right: 12px; + cursor: pointer; + img { + width: 32px; + height: 32px; + border-radius: 50%; + } + } + + &-content { + position: relative; + font-size: 14px; + flex: 1 1 auto; + min-width: 1px; + word-wrap: break-word; + + &-author { + margin-bottom: 4px; + font-size: 14px; + display: flex; + justify-content: flex-start; + & > a, + & > span { + height: 18px; + font-size: 12px; + line-height: 18px; + padding-right: 8px; + } + + &-name { + transition: color 0.3s; + font-size: 14px; + color: @comment-author-name-color; + > * { + color: @comment-author-name-color; + &:hover { + color: @comment-author-name-color; + } + } + } + + &-time { + cursor: auto; + color: @comment-author-time-color; + white-space: nowrap; + } + } + + &-detail p { + white-space: pre-wrap; + } + } + + &-actions { + margin-top: 12px; + padding-left: 0; + > li { + display: inline-block; + color: @comment-action-color; + > span { + padding-right: 10px; + transition: color 0.3s; + font-size: 12px; + color: @comment-action-color; + cursor: pointer; + user-select: none; + &:hover { + color: @comment-action-hover-color; + } + } + } + } + + &-nested { + margin-left: @comment-nest-indent; + } +} diff --git a/components/index.js b/components/index.js index 79d18c6c5..9d70e0f7e 100644 --- a/components/index.js +++ b/components/index.js @@ -124,6 +124,8 @@ import { default as Drawer } from './drawer' import { default as Skeleton } from './skeleton' +import { default as Comment } from './comment' + const components = [ Affix, Anchor, @@ -177,6 +179,7 @@ const components = [ Upload, Drawer, Skeleton, + Comment, ] const install = function (Vue) { @@ -255,6 +258,7 @@ export { Upload, Drawer, Skeleton, + Comment, } export default { diff --git a/components/style.js b/components/style.js index 4b4bbda16..25cf8b5b7 100644 --- a/components/style.js +++ b/components/style.js @@ -51,3 +51,4 @@ import './carousel/style' import './tree-select/style' import './drawer/style' import './skeleton/style' +import './comment/style' diff --git a/components/style/themes/default.less b/components/style/themes/default.less index a5a6fc9e8..db5d8bcf1 100644 --- a/components/style/themes/default.less +++ b/components/style/themes/default.less @@ -402,6 +402,15 @@ @card-actions-background: @background-color-light; @card-shadow: 0 2px 8px rgba(0, 0, 0, .09); +// Comment +// --- +@comment-padding-base: 16px 0; +@comment-nest-indent: 44px; +@comment-author-name-color: @text-color-secondary; +@comment-author-time-color: #ccc; +@comment-action-color: @text-color-secondary; +@comment-action-hover-color: #595959; + // Tabs // --- @tabs-card-head-background: @background-color-light; diff --git a/site/components.js b/site/components.js index 54b59717e..ad20b73bf 100644 --- a/site/components.js +++ b/site/components.js @@ -56,6 +56,7 @@ import { // version, Drawer, Skeleton, + Comment, } from 'ant-design-vue' Vue.prototype.$message = message @@ -119,6 +120,7 @@ Vue.use(Timeline) Vue.use(Tooltip) Vue.use(Upload) Vue.use(Skeleton) +Vue.use(Comment) /* v1.1.2 registration methods */ // Vue.component(Affix.name, Affix) // a-affix diff --git a/site/demo.js b/site/demo.js index 5bd8906cf..7f9a07cec 100644 --- a/site/demo.js +++ b/site/demo.js @@ -11,6 +11,12 @@ export default { type: 'Data Display', title: 'Badge', }, + comment: { + category: 'Components', + subtitle: '评论', + type: 'Data Display', + title: 'Comment', + }, breadcrumb: { category: 'Components', subtitle: '面包屑', diff --git a/site/demoRoutes.js b/site/demoRoutes.js index 3177842a6..64ee6f647 100644 --- a/site/demoRoutes.js +++ b/site/demoRoutes.js @@ -423,4 +423,12 @@ export default [ path: 'skeleton-cn', component: () => import('../components/skeleton/demo/index.vue'), }, + { + path: 'comment', + component: () => import('../components/comment/demo/index.vue'), + }, + { + path: 'comment-cn', + component: () => import('../components/comment/demo/index.vue'), + }, ] From 13b78b9543092a7976a3f2365e19f5a13afdc108 Mon Sep 17 00:00:00 2001 From: wangxueliang Date: Tue, 1 Jan 2019 15:37:10 +0800 Subject: [PATCH 04/63] docs: comment doc --- components/comment/index.zh-CN.md | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/components/comment/index.zh-CN.md b/components/comment/index.zh-CN.md index 115fb79c9..c6f3e8efe 100644 --- a/components/comment/index.zh-CN.md +++ b/components/comment/index.zh-CN.md @@ -1,17 +1,3 @@ ---- -category: Components -type: 数据展示 -title: Comment -subtitle: 评论 -cols: 1 ---- - -对网站内容的反馈、评价和讨论。 - -## 何时使用 - -评论组件可用于对事物的讨论,例如页面、博客文章、问题等等。 - ## API | Property | Description | Type | Default | From 754d89739365d259fd4b5a3483a2fd2dc562a55d Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Tue, 1 Jan 2019 16:25:50 +0800 Subject: [PATCH 05/63] feat: update vc-drawer vc-form --- components/drawer/index.jsx | 17 ++-- components/form/Form.jsx | 2 + components/form/demo/dynamic-form-item.vue | 1 + components/vc-drawer/demo/multiple.jsx | 6 +- components/vc-drawer/demo/placement.jsx | 2 +- components/vc-drawer/src/Drawer.js | 82 +++++++++-------- components/vc-drawer/src/drawerProps.js | 2 +- components/vc-drawer/src/index.js | 2 +- components/vc-drawer/src/utils.js | 8 +- components/vc-form/demo/promise-validate.js | 29 ++++++ components/vc-form/src/createBaseForm.jsx | 94 ++++++++++++-------- components/vc-form/src/createFieldsStore.jsx | 3 +- 12 files changed, 160 insertions(+), 88 deletions(-) create mode 100644 components/vc-form/demo/promise-validate.js diff --git a/components/drawer/index.jsx b/components/drawer/index.jsx index c422588a7..9a6054d12 100644 --- a/components/drawer/index.jsx +++ b/components/drawer/index.jsx @@ -1,9 +1,9 @@ -import classNames from 'classnames' +import warning from 'warning' import VcDrawer from '../vc-drawer/src' import PropTypes from '../_util/vue-types' import BaseMixin from '../_util/BaseMixin' import Icon from '../icon' -import { getComponentFromProp, getOptionProps } from '../_util/props-util' +import { getComponentFromProp, getOptionProps, getClass } from '../_util/props-util' const Drawer = { name: 'ADrawer', @@ -26,6 +26,10 @@ const Drawer = { }, mixins: [BaseMixin], data () { + warning( + this.wrapClassName === undefined, + 'wrapClassName is deprecated, please use className instead.', + ) this.destoryClose = false this.preVisible = this.$props.visible return { @@ -195,16 +199,17 @@ const Drawer = { open: visible, showMask: props.mask, placement, - wrapClassName: classNames({ - [wrapClassName]: !!wrapClassName, - [haveMask]: !!haveMask, - }), }, on: { maskClick: this.onMaskClick, ...this.$listeners, }, style: this.getRcDrawerStyle(), + class: { + [wrapClassName]: !!wrapClassName, + ...getClass(this), + [haveMask]: !!haveMask, + }, } return ( any; // /** Whether stop validate on first rule of error for this field. */ // validateFirst?: boolean; +// /** 是否一直保留子节点的信息 */ +// preserve?: boolean; // }; const Form = { diff --git a/components/form/demo/dynamic-form-item.vue b/components/form/demo/dynamic-form-item.vue index 8cf531a43..ce5ba58ff 100644 --- a/components/form/demo/dynamic-form-item.vue +++ b/components/form/demo/dynamic-form-item.vue @@ -23,6 +23,7 @@ Add or remove form items dynamically. `names[${k}]`, { validateTrigger: ['change', 'blur'], + preserve: true, rules: [{ required: true, whitespace: true, diff --git a/components/vc-drawer/demo/multiple.jsx b/components/vc-drawer/demo/multiple.jsx index 41f6016f5..cf562c38b 100644 --- a/components/vc-drawer/demo/multiple.jsx +++ b/components/vc-drawer/demo/multiple.jsx @@ -25,7 +25,7 @@ export default { }, getLevelMove (e) { const target = e.target - if (target.className === 'drawer1') { + if (target.className.indexOf('drawer1') >= 0) { return [200, 100] } return 100 @@ -47,7 +47,7 @@ export default { handler={false} open={this.open} onMaskClick={this.onClick} - wrapperClassName='drawer1' + class='drawer1' placement='right' >
    @@ -56,7 +56,7 @@ export default { handler={false} open={this.openChild} onMaskClick={this.onChildClick} - wrapperClassName='drawer2' + class='drawer2' level='.drawer1' placement='right' levelMove={100} diff --git a/components/vc-drawer/demo/placement.jsx b/components/vc-drawer/demo/placement.jsx index 52a9745ad..22d4df48f 100644 --- a/components/vc-drawer/demo/placement.jsx +++ b/components/vc-drawer/demo/placement.jsx @@ -35,7 +35,7 @@ export default { return (
    {this.childShow && ( - + currentDrawer[key]) }, getSelfContainer () { @@ -215,8 +216,11 @@ const Drawer = { if (level === 'all') { const children = Array.prototype.slice.call(this.parent.children) children.forEach(child => { - if (child.nodeName !== 'SCRIPT' && child.nodeName !== 'STYLE' && - child.nodeName !== 'LINK' && child !== this.container) { + if (child.nodeName !== 'SCRIPT' && + child.nodeName !== 'STYLE' && + child.nodeName !== 'LINK' && + child !== this.container + ) { this.levelDom.push(child) } }) @@ -251,9 +255,12 @@ const Drawer = { if (getContainer === 'body') { const eventArray = ['touchstart'] const domArray = [document.body, this.maskDom, this.handlerdom, this.contentDom] - const right = document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight) && + const right = + document.body.scrollHeight > + (window.innerHeight || document.documentElement.clientHeight) && window.innerWidth > document.body.offsetWidth - ? getScrollBarSize(1) : 0 + ? getScrollBarSize(1) + : 0 let widthTransition = `width ${duration} ${ease}` const trannsformTransition = `transform ${duration} ${ease}` if (open && document.body.style.overflow !== 'hidden') { @@ -295,12 +302,12 @@ const Drawer = { this.passive ) }) - } else if (this.getCrrentDrawerSome()) { + } else if (this.getCurrentDrawerSome()) { document.body.style.overflow = '' if ((this.isOpenChange || openTransition) && right) { document.body.style.position = '' document.body.style.width = '' - if (trnasitionStr) { + if (transitionStr) { document.body.style.overflowX = 'hidden' } this.dom.style.transition = 'none' @@ -367,21 +374,19 @@ const Drawer = { maskStyle, width, height, - wrapClassName, } = this.$props const children = this.$slots.default const wrapperClassname = classnames(prefixCls, { [`${prefixCls}-${placement}`]: true, [`${prefixCls}-open`]: open, - [wrapClassName]: !!wrapClassName, + ...getClass(this), }) const isOpenChange = this.isOpenChange const isHorizontal = placement === 'left' || placement === 'right' const placementName = `translate${isHorizontal ? 'X' : 'Y'}` // 百分比与像素动画不同步,第一次打用后全用像素动画。 // const defaultValue = !this.contentDom || !level ? '100%' : `${value}px`; - const placementPos = - placement === 'left' || placement === 'top' ? '-100%' : '100%' + const placementPos = placement === 'left' || placement === 'top' ? '-100%' : '100%' const transform = open ? '' : `${placementName}(${placementPos})` if (isOpenChange === undefined || isOpenChange) { const contentValue = this.contentDom ? this.contentDom.getBoundingClientRect()[ @@ -390,7 +395,7 @@ const Drawer = { const value = (isHorizontal ? width : height) || contentValue this.setLevelDomTransform(open, false, placementName, value) } - let handlerCildren + let handlerChildren if (handler !== false) { const handlerDefalut = (
    @@ -400,7 +405,7 @@ const Drawer = { const { handler: handlerSlot } = this.$slots const handlerSlotVnode = handlerSlot || handlerDefalut const { click: handleIconClick } = getEvents(handlerSlotVnode) - handlerCildren = cloneElement(handlerSlotVnode, { + handlerChildren = cloneElement(handlerSlotVnode, { on: { click: (e) => { handleIconClick && handleIconClick() @@ -475,7 +480,7 @@ const Drawer = { > {children}
    - {handlerCildren} + {handlerChildren}
    ) @@ -484,7 +489,7 @@ const Drawer = { return this.open !== undefined ? this.open : this.sOpen }, getTouchParentScroll (root, currentTarget, differX, differY) { - if (!currentTarget) { + if (!currentTarget || currentTarget === document) { return false } // root 为 drawer-content 设定了 overflow, 判断为 root 的 parent 时结束滚动; @@ -506,20 +511,27 @@ const Drawer = { */ const t = currentTarget.scrollTop const l = currentTarget.scrollLeft - currentTarget.scrollTo(currentTarget.scrollLeft + 1, currentTarget.scrollTop + 1) + if (currentTarget.scrollTo) { + currentTarget.scrollTo(currentTarget.scrollLeft + 1, currentTarget.scrollTop + 1) + } const currentT = currentTarget.scrollTop const currentL = currentTarget.scrollLeft - currentTarget.scrollTo(currentTarget.scrollLeft - 1, currentTarget.scrollTop - 1) - + if (currentTarget.scrollTo) { + currentTarget.scrollTo(currentTarget.scrollLeft - 1, currentTarget.scrollTop - 1) + } if ( - isY && (!scrollY || !(currentT - t) || - (scrollY && (currentTarget.scrollTop >= scrollY && differY < 0 || - currentTarget.scrollTop <= 0 && differY > 0)) - ) || - isX && (!scrollX || !(currentL - l) || - (scrollX && (currentTarget.scrollLeft >= scrollX && differX < 0 || - currentTarget.scrollLeft <= 0 && differX > 0)) - ) + (isY && + (!scrollY || + !(currentT - t) || + (scrollY && + ((currentTarget.scrollTop >= scrollY && differY < 0) || + (currentTarget.scrollTop <= 0 && differY > 0))))) || + (isX && + (!scrollX || + !(currentL - l) || + (scrollX && + ((currentTarget.scrollLeft >= scrollX && differX < 0) || + (currentTarget.scrollLeft <= 0 && differX > 0))))) ) { return this.getTouchParentScroll(root, currentTarget.parentNode, differX, differY) } @@ -544,8 +556,8 @@ const Drawer = { if ( currentTarget === this.maskDom || currentTarget === this.handlerdom || - currentTarget === this.contentDom && - this.getTouchParentScroll(currentTarget, e.target, differX, differY) + (currentTarget === this.contentDom && + this.getTouchParentScroll(currentTarget, e.target, differX, differY)) ) { e.preventDefault() } @@ -588,7 +600,7 @@ const Drawer = { ) } - if (!this.container || !open && !this.sFirstEnter) { + if (!this.container || (!open && !this.sFirstEnter)) { return null } return ( diff --git a/components/vc-drawer/src/drawerProps.js b/components/vc-drawer/src/drawerProps.js index 25fe11705..d8088b53a 100644 --- a/components/vc-drawer/src/drawerProps.js +++ b/components/vc-drawer/src/drawerProps.js @@ -1,7 +1,7 @@ import PropTypes from '../../_util/vue-types' export default { - wrapClassName: PropTypes.string, + wrapperClassName: PropTypes.string, width: PropTypes.any, height: PropTypes.any, defaultOpen: PropTypes.bool, diff --git a/components/vc-drawer/src/index.js b/components/vc-drawer/src/index.js index 304065c9d..9b38dd851 100644 --- a/components/vc-drawer/src/index.js +++ b/components/vc-drawer/src/index.js @@ -1,4 +1,4 @@ -// base in 1.7.6 +// base in 1.7.7 // export this package's api import Drawer from './Drawer' diff --git a/components/vc-drawer/src/utils.js b/components/vc-drawer/src/utils.js index e773d4a33..581885ed7 100644 --- a/components/vc-drawer/src/utils.js +++ b/components/vc-drawer/src/utils.js @@ -4,20 +4,20 @@ export function dataToArray (vars) { } return [vars] } -const trnasitionEndObject = { +const transitionEndObject = { transition: 'transitionend', WebkitTransition: 'webkitTransitionEnd', MozTransition: 'transitionend', OTransition: 'oTransitionEnd otransitionend', } -export const trnasitionStr = Object.keys(trnasitionEndObject).filter(key => { +export const transitionStr = Object.keys(transitionEndObject).filter(key => { if (typeof document === 'undefined') { return false } const html = document.getElementsByTagName('html')[0] return key in (html ? html.style : {}) })[0] -export const transitionEnd = trnasitionEndObject[trnasitionStr] +export const transitionEnd = transitionEndObject[transitionStr] export function addEventListener (target, eventType, callback, options) { if (target.addEventListener) { @@ -51,6 +51,6 @@ export function transformArguments (arg, cb) { return [result] } -export const isNumeric = (value) => { +export const isNumeric = value => { return !isNaN(parseFloat(value)) && isFinite(value);// eslint-disable-line } diff --git a/components/vc-form/demo/promise-validate.js b/components/vc-form/demo/promise-validate.js new file mode 100644 index 000000000..11fdd640c --- /dev/null +++ b/components/vc-form/demo/promise-validate.js @@ -0,0 +1,29 @@ +import { createForm } from '../index' +const Form = { + + methods: { + handleSubmit (e) { + e.preventDefault() + const { validateFields } = this.form + validateFields() + .then(console.log) + .catch(console.error) + }, + }, + + render () { + const { getFieldDecorator } = this.form + return ( +
    + {getFieldDecorator('name', { + rules: [{ + required: true, + }], + })()} + +
    + ) + }, +} + +export default createForm()(Form) diff --git a/components/vc-form/src/createBaseForm.jsx b/components/vc-form/src/createBaseForm.jsx index 44a7b58da..df140e89a 100644 --- a/components/vc-form/src/createBaseForm.jsx +++ b/components/vc-form/src/createBaseForm.jsx @@ -34,6 +34,7 @@ function createBaseForm (option = {}, mixins = []) { fieldMetaProp, fieldDataProp, formPropName = 'form', + name: formName, props = {}, templateContext, } = option @@ -267,7 +268,7 @@ function createBaseForm (option = {}, mixins = []) { const inputListeners = {} const inputAttrs = {} if (fieldNameProp) { - inputProps[fieldNameProp] = name + inputProps[fieldNameProp] = formName ? `${formName}_${name}` : name } const validateRules = normalizeValidateRules(validate, rules, validateTrigger) @@ -375,12 +376,15 @@ function createBaseForm (option = {}, mixins = []) { saveRef (name, _, component) { if (!component) { + const fieldMeta = this.fieldsStore.getFieldMeta(name) + if (!fieldMeta.preserve) { // after destroy, delete data - this.clearedFieldMetaCache[name] = { - field: this.fieldsStore.getField(name), - meta: this.fieldsStore.getFieldMeta(name), + this.clearedFieldMetaCache[name] = { + field: this.fieldsStore.getField(name), + meta: fieldMeta, + } + this.clearField(name) } - this.clearField(name) delete this.domFields[name] return } @@ -401,9 +405,10 @@ function createBaseForm (option = {}, mixins = []) { cleanUpUselessFields () { const fieldList = this.fieldsStore.getAllFieldsName() - const removedList = fieldList.filter(field => ( - !this.renderFields[field] && !this.domFields[field] - )) + const removedList = fieldList.filter(field => { + const fieldMeta = this.fieldsStore.getFieldMeta(field) + return (!this.renderFields[field] && !this.domFields[field] && !fieldMeta.preserve) + }) if (removedList.length) { removedList.forEach(this.clearField) } @@ -536,35 +541,52 @@ function createBaseForm (option = {}, mixins = []) { }, validateFields (ns, opt, cb) { - const { names, callback, options } = getParams(ns, opt, cb) - const fieldNames = names - ? this.fieldsStore.getValidFieldsFullName(names) - : this.fieldsStore.getValidFieldsName() - const fields = fieldNames - .filter(name => { - const fieldMeta = this.fieldsStore.getFieldMeta(name) - return hasRules(fieldMeta.validate) - }).map((name) => { - const field = this.fieldsStore.getField(name) - field.value = this.fieldsStore.getFieldValue(name) - return field - }) - if (!fields.length) { - if (callback) { - callback(null, this.fieldsStore.getFieldsValue(fieldNames)) + const pending = new Promise((resolve, reject) => { + const { names, options } = getParams(ns, opt, cb) + let { callback } = getParams(ns, opt, cb) + if (!callback || typeof callback === 'function') { + const oldCb = callback + callback = (errors, values) => { + if (oldCb) { + oldCb(errors, values) + } else if (errors) { + reject({ errors, values }) + } else { + resolve(values) + } + } } - return - } - if (!('firstFields' in options)) { - options.firstFields = fieldNames.filter((name) => { - const fieldMeta = this.fieldsStore.getFieldMeta(name) - return !!fieldMeta.validateFirst - }) - } - this.validateFieldsInternal(fields, { - fieldNames, - options, - }, callback) + const fieldNames = names + ? this.fieldsStore.getValidFieldsFullName(names) + : this.fieldsStore.getValidFieldsName() + const fields = fieldNames + .filter(name => { + const fieldMeta = this.fieldsStore.getFieldMeta(name) + return hasRules(fieldMeta.validate) + }).map((name) => { + const field = this.fieldsStore.getField(name) + field.value = this.fieldsStore.getFieldValue(name) + return field + }) + if (!fields.length) { + if (callback) { + callback(null, this.fieldsStore.getFieldsValue(fieldNames)) + } + return + } + if (!('firstFields' in options)) { + options.firstFields = fieldNames.filter((name) => { + const fieldMeta = this.fieldsStore.getFieldMeta(name) + return !!fieldMeta.validateFirst + }) + } + this.validateFieldsInternal(fields, { + fieldNames, + options, + }, callback) + }) + pending.catch((e) => e) + return pending }, isSubmitting () { diff --git a/components/vc-form/src/createFieldsStore.jsx b/components/vc-form/src/createFieldsStore.jsx index b3511a383..58d3e06ce 100644 --- a/components/vc-form/src/createFieldsStore.jsx +++ b/components/vc-form/src/createFieldsStore.jsx @@ -159,7 +159,8 @@ class FieldsStore { } getNotCollectedFields () { - return this.getValidFieldsName() + const fieldsName = this.getValidFieldsName() + return fieldsName .filter(name => !this.fields[name]) .map(name => ({ name, From 0aa764df51fa4f152ef42bebd662a39db888b94b Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Tue, 1 Jan 2019 16:44:48 +0800 Subject: [PATCH 06/63] feat: update form ts --- types/form/form.d.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/types/form/form.d.ts b/types/form/form.d.ts index 522299521..956cd2a64 100644 --- a/types/form/form.d.ts +++ b/types/form/form.d.ts @@ -177,6 +177,13 @@ declare interface FieldDecoratorOptions { * @type string */ valuePropName?: string; + + /** + * Whether to keep the information of the child node all the time. + * @default false + * @type boolean + */ + preserve?: boolean; } export interface WrappedFormUtils { From 639547953cae32e2cad945abb72fd1dea9106f70 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Tue, 1 Jan 2019 21:19:50 +0800 Subject: [PATCH 07/63] feat: update vc-notification vc-pagination --- components/vc-form/index.js | 2 +- components/vc-input-number/src/index.js | 17 ++- components/vc-menu/index.js | 2 +- components/vc-notification/Notice.jsx | 11 +- components/vc-notification/Notification.jsx | 4 + components/vc-notification/demo/simple.jsx | 3 + components/vc-notification/index.js | 2 +- components/vc-pagination/Pager.jsx | 4 + components/vc-pagination/Pagination.jsx | 136 ++++++++++++-------- components/vc-pagination/assets/index.less | 64 ++++++++- components/vc-pagination/index.js | 2 +- components/vc-pagination/locale/hi_IN.js | 15 +++ components/vc-pagination/locale/kn_IN.js | 15 +++ components/vc-pagination/locale/ro_RO.js | 15 +++ 14 files changed, 221 insertions(+), 71 deletions(-) create mode 100644 components/vc-pagination/locale/hi_IN.js create mode 100644 components/vc-pagination/locale/kn_IN.js create mode 100644 components/vc-pagination/locale/ro_RO.js diff --git a/components/vc-form/index.js b/components/vc-form/index.js index 160f2c58b..dda23d5a4 100644 --- a/components/vc-form/index.js +++ b/components/vc-form/index.js @@ -1,3 +1,3 @@ -// based on rc-form 2.2.6 +// based on rc-form 2.4.0 import { createForm, createFormField } from './src/' export { createForm, createFormField } diff --git a/components/vc-input-number/src/index.js b/components/vc-input-number/src/index.js index e4ffdcb35..524e5be28 100755 --- a/components/vc-input-number/src/index.js +++ b/components/vc-input-number/src/index.js @@ -1,4 +1,4 @@ -// based on rc-input-number 4.3.1 +// based on rc-input-number 4.3.7 import PropTypes from '../../_util/vue-types' import BaseMixin from '../../_util/BaseMixin' import { initDefaultProps, hasProp, getOptionProps } from '../../_util/props-util' @@ -73,6 +73,8 @@ const inputNumberProps = { required: PropTypes.bool, pattern: PropTypes.string, decimalSeparator: PropTypes.string, + autoComplete: PropTypes.string, + title: PropTypes.string, } export default { @@ -90,6 +92,7 @@ export default { step: 1, parser: defaultParser, required: false, + autoComplete: 'off', }), data () { let value @@ -274,7 +277,7 @@ export default { let val = value if (val === '') { val = '' - } else if (!this.isNotCompleteNumber(val)) { + } else if (!this.isNotCompleteNumber(parseFloat(val, 10))) { val = this.getValidValue(val) } else { val = this.sValue @@ -583,7 +586,8 @@ export default { }, }, render () { - const { prefixCls, disabled, readOnly, useTouch } = this.$props + const { prefixCls, disabled, readOnly, useTouch, autoComplete, + upHandler, downHandler } = this.$props const classes = classNames({ [prefixCls]: true, [`${prefixCls}-disabled`]: disabled, @@ -657,6 +661,7 @@ export default { const contentProps = { on: { mouseenter, mouseleave, mouseover, mouseout }, class: classes, + attrs: { title: this.$props.title }, } const upHandlerProps = { props: { @@ -697,7 +702,7 @@ export default { - {this.upHandler || - {this.downHandler ||
    {$slots.default}
    {closable diff --git a/components/vc-notification/Notification.jsx b/components/vc-notification/Notification.jsx index 6352044bd..bfffeed93 100644 --- a/components/vc-notification/Notification.jsx +++ b/components/vc-notification/Notification.jsx @@ -7,6 +7,9 @@ import createChainedFunction from '../_util/createChainedFunction' import getTransitionProps from '../_util/getTransitionProps' import Notice from './Notice' +function noop () { +} + let seed = 0 const now = Date.now() @@ -91,6 +94,7 @@ const Notification = { }, on: { close, + click: notice.onClick || noop, }, style, class: className, diff --git a/components/vc-notification/demo/simple.jsx b/components/vc-notification/demo/simple.jsx index 0f3036fd0..9f64ba175 100644 --- a/components/vc-notification/demo/simple.jsx +++ b/components/vc-notification/demo/simple.jsx @@ -35,6 +35,9 @@ function closableFn () { onClose () { console.log('closable close') }, + onClick () { + console.log('clicked!!!') + }, closable: true, }) } diff --git a/components/vc-notification/index.js b/components/vc-notification/index.js index a30798b2a..c90aca1bd 100644 --- a/components/vc-notification/index.js +++ b/components/vc-notification/index.js @@ -1,3 +1,3 @@ -// based on rc-notification 3.2.0 +// based on rc-notification 3.3.0 import Notification from './Notification' export default Notification diff --git a/components/vc-pagination/Pager.jsx b/components/vc-pagination/Pager.jsx index e8903871b..bda79157f 100644 --- a/components/vc-pagination/Pager.jsx +++ b/components/vc-pagination/Pager.jsx @@ -42,6 +42,10 @@ export default { cls = `${cls} ${prefixCls}-active` } + if (!page) { + cls = `${cls} ${prefixCls}-disabled` + } + return (
  • newCurrent ? newCurrent : current if (!hasProp(this, 'current')) { newState.stateCurrent = current @@ -112,42 +120,30 @@ export default { }, }, methods: { - isValid (page) { - return isInteger(page) && page >= 1 && page !== this.stateCurrent + getJumpPrevPage () { + return Math.max(1, this.stateCurrent - (this.showLessItems ? 3 : 5)) + }, + getJumpNextPage () { + return Math.min( + calculatePage(undefined, this.$data, this.$props), + this.stateCurrent + (this.showLessItems ? 3 : 5) + ) }, getItemIcon (icon) { const { prefixCls } = this.$props const iconNode = getComponentFromProp(this, icon, this.$props) || return iconNode }, - calculatePage (p) { - let pageSize = p - if (typeof pageSize === 'undefined') { - pageSize = this.statePageSize - } - return Math.floor((this.total - 1) / pageSize) + 1 - }, - handleGoTO (event) { - if (event.keyCode === KEYCODE.ENTER || event.type === 'click') { - this.handleChange(this.stateCurrentInputValue) - } - }, - prev () { - if (this.hasPrev()) { - this.handleChange(this.stateCurrent - 1) - } - }, - next () { - if (this.hasNext()) { - this.handleChange(this.stateCurrent + 1) - } - }, - hasPrev () { - return this.stateCurrent > 1 - }, - hasNext () { - return this.stateCurrent < this.calculatePage() + isValid (page) { + return isInteger(page) && page >= 1 && page !== this.stateCurrent }, + // calculatePage (p) { + // let pageSize = p + // if (typeof pageSize === 'undefined') { + // pageSize = this.statePageSize + // } + // return Math.floor((this.total - 1) / pageSize) + 1 + // }, handleKeyDown (event) { if (event.keyCode === KEYCODE.ARROW_UP || event.keyCode === KEYCODE.ARROW_DOWN) { event.preventDefault() @@ -183,7 +179,7 @@ export default { changePageSize (size) { let current = this.stateCurrent const preCurrent = current - const newCurrent = this.calculatePage(size) + const newCurrent = calculatePage(size, this.$data, this.$props) current = current > newCurrent ? newCurrent : current // fix the issue: // Once 'total' is 0, 'current' in 'onShowSizeChange' is 0, which is not correct. @@ -212,9 +208,9 @@ export default { handleChange (p) { let page = p if (this.isValid(page)) { - const allTotal = this.calculatePage() - if (page > allTotal) { - page = allTotal + const currentPage = calculatePage(undefined, this.$data, this.$props) + if (page > currentPage) { + page = currentPage } if (!hasProp(this, 'current')) { this.setState({ @@ -229,6 +225,28 @@ export default { } return this.stateCurrent }, + prev () { + if (this.hasPrev()) { + this.handleChange(this.stateCurrent - 1) + } + }, + next () { + if (this.hasNext()) { + this.handleChange(this.stateCurrent + 1) + } + }, + jumpPrev () { + this.handleChange(this.getJumpPrevPage()) + }, + jumpNext () { + this.handleChange(this.getJumpNextPage()) + }, + hasPrev () { + return this.stateCurrent > 1 + }, + hasNext () { + return this.stateCurrent < calculatePage(undefined, this.$data, this.$props) + }, runIfEnter (event, callback, ...restParams) { if (event.key === 'Enter' || event.charCode === 13) { callback(...restParams) @@ -246,17 +264,10 @@ export default { runIfEnterJumpNext (event) { this.runIfEnter(event, this.jumpNext) }, - getJumpPrevPage () { - return Math.max(1, this.stateCurrent - (this.showLessItems ? 3 : 5)) - }, - getJumpNextPage () { - return Math.min(this.calculatePage(), this.stateCurrent + (this.showLessItems ? 3 : 5)) - }, - jumpPrev () { - this.handleChange(this.getJumpPrevPage()) - }, - jumpNext () { - this.handleChange(this.getJumpNextPage()) + handleGoTO (event) { + if (event.keyCode === KEYCODE.ENTER || event.type === 'click') { + this.handleChange(this.stateCurrentInputValue) + } }, }, render () { @@ -268,7 +279,7 @@ export default { const locale = this.locale const prefixCls = this.prefixCls - const allPages = this.calculatePage() + const allPages = calculatePage(undefined, this.$data, this.$props) const pagerList = [] let jumpPrev = null let jumpNext = null @@ -354,19 +365,36 @@ export default { ) } if (allPages <= 5 + pageBufferSize * 2) { + const pagerProps = { + props: { + locale, + rootPrefixCls: prefixCls, + showTitle: props.showTitle, + itemRender: props.itemRender, + }, + on: { + click: this.handleChange, + keypress: this.runIfEnter, + }, + } + if (!allPages) { + pagerList.push( + + ) + } for (let i = 1; i <= allPages; i++) { const active = stateCurrent === i pagerList.push( ) } @@ -530,8 +558,8 @@ export default {
  • ) } - const prevDisabled = !this.hasPrev() - const nextDisabled = !this.hasNext() + const prevDisabled = !this.hasPrev() || !allPages + const nextDisabled = !this.hasNext() || !allPages const buildOptionText = this.buildOptionText || this.$scopedSlots.buildOptionText return (