diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index 97ac062c9..e5b55698c 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -1,7 +1,59 @@ # Change Log +`ant-design-vue` strictly follows [Semantic Versioning 2.0.0](http://semver.org/). + +#### Release Schedule + +* Weekly release: patch version at the end of every week for routine bugfix (anytime for urgent bugfix). +* Monthly release: minor version for new features. +* Major version release is not included in this schedule for breaking change and new features. + --- +## 1.3.0 +`2019-01-12` + +- 🎉 🎉 🎉 Publish the vscode plugin [ant-design-vue-helper](https://marketplace.visualstudio.com/items?itemName=ant-design-vue.vscode-ant-design-vue-helper) + +### Component features and styles are synchronized to antd version 3.11.6. +1.3.0 brings two new Components, a lot of exciting changes and new features. + +- 🔥 Added a new component [Comment](https://vuecomponent.github.io/ant-design-vue/components/comment/)。 +- 🔥 dded a new component [ConfigProvider](https://vuecomponent.github.io/ant-design-vue/components/config-provider/) for user to customize some global setting. + +Component Fixes / Enhancements: + +- 🌟 Avatar Added `srcSet` prop that is a list of sources to use for different screen resolutions. +- 🌟 Notification Added `onClick` prop that is called when the notification is clicked. +- Transfer + - 🌟 Added `search` event that is executed when search field are changed and deprecated `searchChange` event. + - 🌟 Added `disabled` prop that whether disable transfer. +- 🌟 Refactor Badge, support `count` as custom component. +- Slider + - 🌟 Added `tooltipVisible` prop that whether Tooltip will always show. + - 🌟 Optimize the focus effect + - 🐞 Fix tooltip does not display the problem when focus through the keyboard tab. + - 🐞 Fix the hidden switch problem of Tooltip while dragging. +- Calendar + - 🌟 Support multiple date format. + - 🌟 showSearch added `limit` prop that support limit filtered item count. +- Table + - 🌟 Added `expandIcon` prop that custom the default expand icon. + - 🌟 customCell added `index` prop. +- Select + - 🌟 Added `removeIcon`、`clearIcon`、`menuItemSelectedIcon` prop,allow setting `remove`、`clear`、`menuItemSelected` custom icons. + - 🌟 Added `dropdownRender` prop that custom dropdown content. + - 🌟 Added `loading` prop that indicate loading state. +- 🌟 Optimize the display of the Button when it contains an Icon. +- ⚡️ Refactor Tag component with less code and better performance. +- 💄 Added `title` prop that Menu.Item support tooltip title when collapsed. +- 💄 Chore Card header and loading UI. +- 💄 Optimized Spin wrapper styles and improve performance slightly. +- 🐞 Fix TextArea use resize observer to check textarea size. +- 🐞 Fix Tooltip in the disabled state, the style error problem.[#389](https://github.com/vueComponent/ant-design-vue/issues/389) +- 🐞 Fix some component TypeScript definitions. + + ## 1.2.5 `2019-01-06` diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index 0f77d5d23..14339afe1 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -1,7 +1,59 @@ # 更新日志 +`ant-design-vue` 严格遵循 [Semantic Versioning 2.0.0](http://semver.org/lang/zh-CN/) 语义化版本规范。 + +#### 发布周期 + +* 修订版本号:每周末会进行日常 bugfix 更新。(如果有紧急的 bugfix,则任何时候都可发布) +* 次版本号:带有新特性的向下兼容的版本。 +* 主版本号:含有破坏性更新和新特性,不在发布周期内。 + --- +## 1.3.0 +`2019-01-12` + +- 🎉 🎉 🎉 发布 vscode 插件 [ant-design-vue-helper](https://marketplace.visualstudio.com/items?itemName=ant-design-vue.vscode-ant-design-vue-helper) + +### 组件功能和样式同步到 antd 3.11.6 版本。 +1.3.0 版本带来了两个新组件,还有很多激动人心的变化和新特性。 + +- 🔥 增加了一个新组件 [Comment](https://vuecomponent.github.io/ant-design-vue/components/comment-cn/)。 +- 🔥 增加了一个新组件 [ConfigProvider](https://vuecomponent.github.io/ant-design-vue/components/config-provider-cn/) 为组件提供统一的全局化配置。 + +组件修复/功能增强: + +- 🌟 Avatar 组件增加 `srcSet` 属性,用于设置图片类头像响应式资源地址。 +- 🌟 Notification 组件增加 `onClick` 属性,点击通知时触发的回调函数。 +- Transfer + - 🌟 增加 `search` 事件,搜索框内容时改变时的回调函数,并废弃 `searchChange` 事件。 + - 🌟 增加 `disabled` 属性,用于禁用搜索框。 +- 🌟 Badge 进行了重构,`count` 支持自定义组件。 +- Slider + - 🌟 增加 `tooltipVisible` 属性,用于 Tooltip 是否始终显示。 + - 🌟 优化focus效果 + - 🐞 修复键盘tab键聚焦时,Tooltip不显示问题。 + - 🐞 修复拖动时Tooltip不停的显隐切换问题。 +- Calendar + - 🌟 支持多种时间格式。 + - 🌟 showSearch 方法增加 `limit` 参数,用于限制搜索结果展示数量。 +- Table + - 🌟 增加 `expandIcon` 属性,用于自定义表格展开图标。 + - 🌟 customCell 方法增加 `index` 参数。 +- Select + - 🌟 增加 `removeIcon`、`clearIcon`、`menuItemSelectedIcon` 属性,用于自定义删除、清空、选中的图标。 + - 🌟 增加 `dropdownRender` 属性, 用于自定义下拉框内容。 + - 🌟 增加 `loading` 属性, 用于展示加载中状态。 +- 🌟 优化 Button 在含有Icon时的显示效果。 +- ⚡️ 重构 Tag 组件,简化代码并提升性能。 +- 💄 Menu.Item 组件增加 `title` 属性,用于在收缩时展示的悬浮标题。 +- 💄 微调 Card 头部和加载中的样式细节。 +- 💄 优化 Spin 样式并略微提升了切换状态的性能。 +- 🐞 修复 TextArea 组件高度不能自适应问题。 +- 🐞 修复 Tooltip 在disabled状态下Button中,样式错误问题。[#389](https://github.com/vueComponent/ant-design-vue/issues/389) +- 🐞 修复一些组件 TypeScript 定义。 + + ## 1.2.5 `2019-01-06` 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/_util/Dom/addEventListener.js b/components/_util/Dom/addEventListener.js index 2c4c3eec3..4ea8998c8 100644 --- a/components/_util/Dom/addEventListener.js +++ b/components/_util/Dom/addEventListener.js @@ -1,5 +1,5 @@ import addDOMEventListener from 'add-dom-event-listener' -export default function addEventListenerWrap (target, eventType, cb) { - return addDOMEventListener(target, eventType, cb) +export default function addEventListenerWrap (target, eventType, cb, option) { + return addDOMEventListener(target, eventType, cb, option) } diff --git a/components/_util/props-util.js b/components/_util/props-util.js index 996b6f8a6..65856cae9 100644 --- a/components/_util/props-util.js +++ b/components/_util/props-util.js @@ -52,9 +52,11 @@ const getSlots = (ele) => { const children = ele.children || componentOptions.children || [] const slots = {} children.forEach(child => { - const name = (child.data && child.data.slot) || 'default' - slots[name] = slots[name] || [] - slots[name].push(child) + if (!isEmptyElement(child)) { + const name = (child.data && child.data.slot) || 'default' + slots[name] = slots[name] || [] + slots[name].push(child) + } }) return slots } @@ -215,12 +217,12 @@ export function getComponentName (opts) { return opts && (opts.Ctor.options.name || opts.tag) } -export function isEmptyElement (ele) { - return !(ele.tag || ele.text.trim() !== '') +export function isEmptyElement (c) { + return !(c.tag || (c.text && c.text.trim() !== '')) } export function filterEmpty (children = []) { - return children.filter(c => c.tag || (c.text && c.text.trim() !== '')) + return children.filter(c => !isEmptyElement(c)) } const initDefaultProps = (propTypes, defaultProps) => { Object.keys(defaultProps).forEach(k => { @@ -252,7 +254,11 @@ export function mergeProps () { } function isValidElement (element) { - return element && element.context && element.context._isVue + return element && + typeof element === 'object' && + 'componentOptions' in element && + 'context' in element && + element.tag !== undefined // remove text node } export { diff --git a/components/_util/wave.jsx b/components/_util/wave.jsx index ac262e156..396d5d5bc 100644 --- a/components/_util/wave.jsx +++ b/components/_util/wave.jsx @@ -117,7 +117,7 @@ export default { }, resetEffect (node) { - if (!node || node === this.extraNode) { + if (!node || node === this.extraNode || !(node instanceof Element)) { return } const { insertExtraNode } = this.$props diff --git a/components/affix/index.jsx b/components/affix/index.jsx index a9fb0b25b..56df9af4f 100644 --- a/components/affix/index.jsx +++ b/components/affix/index.jsx @@ -83,6 +83,8 @@ const Affix = { // Wait for parent component ref has its value this.timeout = setTimeout(() => { this.setTargetEventListeners(target) + // Mock Event object. + this.updatePosition({}) }) }, watch: { diff --git a/components/affix/style/index.less b/components/affix/style/index.less index cd61d1ed0..9f19860e5 100644 --- a/components/affix/style/index.less +++ b/components/affix/style/index.less @@ -1,4 +1,4 @@ -@import "../../style/themes/default"; +@import '../../style/themes/default'; .@{ant-prefix}-affix { position: fixed; diff --git a/components/alert/__tests__/__snapshots__/demo.test.js.snap b/components/alert/__tests__/__snapshots__/demo.test.js.snap index b42763a71..c053c3624 100644 --- a/components/alert/__tests__/__snapshots__/demo.test.js.snap +++ b/components/alert/__tests__/__snapshots__/demo.test.js.snap @@ -5,7 +5,7 @@ exports[`renders ./components/alert/demo/banner.md correctly 1`] = `
Warning text

-
Very long warning text warning text text text text text text text
-
Warning Text Warning Text Warning TextW arning Text Warning Text Warning TextWarning Text -
Error TextError Description Error Description Error Description Error Description Error Description Error Description
`; -exports[`renders ./components/alert/demo/close-text.md correctly 1`] = `
Info TextClose Now
`; +exports[`renders ./components/alert/demo/close-text.md correctly 1`] = `
Info TextClose Now
`; exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
@@ -92,7 +92,7 @@ exports[`renders ./components/alert/demo/icon.md correctly 1`] = ` exports[`renders ./components/alert/demo/smooth-closed.md correctly 1`] = `
-
Alert Message Text
diff --git a/components/alert/index.jsx b/components/alert/index.jsx index a02b244a1..53ad294ea 100644 --- a/components/alert/index.jsx +++ b/components/alert/index.jsx @@ -103,19 +103,20 @@ const Alert = { } } + // closeable when closeText is assigned + if (closeText) { + closable = true + } + const alertCls = classNames(prefixCls, { [`${prefixCls}-${type}`]: true, [`${prefixCls}-close`]: !closing, [`${prefixCls}-with-description`]: !!description, [`${prefixCls}-no-icon`]: !showIcon, [`${prefixCls}-banner`]: !!banner, + [`${prefixCls}-closable`]: closable, }) - // closeable when closeText is assigned - if (closeText) { - closable = true - } - const closeIcon = closable ? ( {closeText || } diff --git a/components/alert/style/index.less b/components/alert/style/index.less index a876d6921..180e9cf2f 100644 --- a/components/alert/style/index.less +++ b/components/alert/style/index.less @@ -1,11 +1,12 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; -@alert-prefix-cls: ~"@{ant-prefix}-alert"; +@alert-prefix-cls: ~'@{ant-prefix}-alert'; @alert-message-color: @heading-color; @alert-text-color: @text-color; @alert-close-color: @text-color-secondary; +@alert-close-hover-color: #404040; .@{alert-prefix-cls} { .reset-component; @@ -17,6 +18,10 @@ padding: 8px 15px; } + &&-closable { + padding-right: 30px; + } + &-icon { top: 8px + @font-size-base * @line-height-base / 2 - @font-size-base / 2; left: 16px; @@ -72,9 +77,9 @@ .@{iconfont-css-prefix}-close { color: @alert-close-color; - transition: color .3s; + transition: color 0.3s; &:hover { - color: #404040; + color: @alert-close-hover-color; } } } @@ -127,12 +132,12 @@ margin: 0; padding-top: 0; padding-bottom: 0; - transition: all .3s @ease-in-out-circ; + transition: all 0.3s @ease-in-out-circ; transform-origin: 50% 0; } &-slide-up-leave { - animation: antAlertSlideUpOut .3s @ease-in-out-circ; + animation: antAlertSlideUpOut 0.3s @ease-in-out-circ; animation-fill-mode: both; } diff --git a/components/anchor/style/index.less b/components/anchor/style/index.less index 3a5ddec9a..ec2386b82 100644 --- a/components/anchor/style/index.less +++ b/components/anchor/style/index.less @@ -1,5 +1,5 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; @anchor-border-width: 2px; @@ -38,7 +38,7 @@ border: 2px solid @primary-color; background-color: @component-background; left: 50%; - transition: top .3s ease-in-out; + transition: top 0.3s ease-in-out; transform: translateX(-50%); &.visible { display: inline-block; @@ -57,7 +57,7 @@ &-title { display: block; position: relative; - transition: all .3s; + transition: all 0.3s; color: @text-color; white-space: nowrap; overflow: hidden; diff --git a/components/auto-complete/__tests__/__snapshots__/demo.test.js.snap b/components/auto-complete/__tests__/__snapshots__/demo.test.js.snap index dc5a08f8e..5344c1781 100644 --- a/components/auto-complete/__tests__/__snapshots__/demo.test.js.snap +++ b/components/auto-complete/__tests__/__snapshots__/demo.test.js.snap @@ -2,15 +2,15 @@ exports[`renders ./components/auto-complete/demo/basic.md correctly 1`] = ` `; @@ -18,15 +18,15 @@ exports[`renders ./components/auto-complete/demo/basic.md correctly 1`] = ` exports[`renders ./components/auto-complete/demo/certain-category.md correctly 1`] = `
@@ -34,44 +34,44 @@ exports[`renders ./components/auto-complete/demo/certain-category.md correctly 1 exports[`renders ./components/auto-complete/demo/custom.md correctly 1`] = ` `; exports[`renders ./components/auto-complete/demo/non-case-sensitive.md correctly 1`] = ` `; exports[`renders ./components/auto-complete/demo/options.md correctly 1`] = ` `; @@ -79,15 +79,15 @@ exports[`renders ./components/auto-complete/demo/options.md correctly 1`] = ` exports[`renders ./components/auto-complete/demo/uncertain-category.md correctly 1`] = `
diff --git a/components/auto-complete/style/index.less b/components/auto-complete/style/index.less index 74e45c21c..4c9dc25e3 100644 --- a/components/auto-complete/style/index.less +++ b/components/auto-complete/style/index.less @@ -1,10 +1,10 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; -@import "../../input/style/mixin"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; +@import '../../input/style/mixin'; -@input-prefix-cls: ~"@{ant-prefix}-input"; -@select-prefix-cls: ~"@{ant-prefix}-select"; -@autocomplete-prefix-cls: ~"@{select-prefix-cls}-auto-complete"; +@input-prefix-cls: ~'@{ant-prefix}-input'; +@select-prefix-cls: ~'@{ant-prefix}-select'; +@autocomplete-prefix-cls: ~'@{select-prefix-cls}-auto-complete'; .@{autocomplete-prefix-cls} { .reset-component; diff --git a/components/avatar/Avatar.jsx b/components/avatar/Avatar.jsx index 5aedd58d8..baf1bafd7 100644 --- a/components/avatar/Avatar.jsx +++ b/components/avatar/Avatar.jsx @@ -19,6 +19,8 @@ export default { default: 'default', }, src: String, + /** Srcset of image avatar */ + srcSet: String, icon: String, alt: String, loadError: Function, @@ -71,7 +73,7 @@ export default { }, render () { const { - prefixCls, shape, size, src, icon, alt, + prefixCls, shape, size, src, icon, alt, srcSet, } = this.$props const { isImgExist, scale } = this.$data @@ -101,6 +103,7 @@ export default { children = ( {alt} diff --git a/components/avatar/__tests__/__snapshots__/demo.test.js.snap b/components/avatar/__tests__/__snapshots__/demo.test.js.snap index a6787108d..5b6266448 100644 --- a/components/avatar/__tests__/__snapshots__/demo.test.js.snap +++ b/components/avatar/__tests__/__snapshots__/demo.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/avatar/demo/badge.md correctly 1`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; +exports[`renders ./components/avatar/demo/badge.md correctly 1`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; exports[`renders ./components/avatar/demo/basic.md correctly 1`] = `
diff --git a/components/avatar/index.en-US.md b/components/avatar/index.en-US.md index 9e33ea2a6..8ccc83caa 100644 --- a/components/avatar/index.en-US.md +++ b/components/avatar/index.en-US.md @@ -6,6 +6,7 @@ | shape | the shape of avatar | `circle` \| `square` | `circle` | | size | the size of the avatar | number \| string: `large` `small` `default` | `default` | | src | the address of the image for an image avatar | string | - | +| srcSet | a list of sources to use for different screen resolutions | string | - | | alt | This attribute defines the alternative text describing the image | string | - | | loadError | handler when img load error,return false to prevent default fallback behavior | () => boolean | - | diff --git a/components/avatar/index.zh-CN.md b/components/avatar/index.zh-CN.md index 07d4c16dd..16b81f4bc 100644 --- a/components/avatar/index.zh-CN.md +++ b/components/avatar/index.zh-CN.md @@ -6,6 +6,7 @@ | shape | 指定头像的形状 | Enum{ 'circle', 'square' } | `circle` | | size | 设置头像的大小 | number \| Enum{ 'large', 'small', 'default' } | `default` | | src | 图片类头像的资源地址 | string | - | +| srcSet | 设置图片类头像响应式资源地址 | string | - | | alt | 图像无法显示时的替代文本 | string | - | | loadError | 图片加载失败的事件,返回 false 会关闭组件默认的 fallback 行为 | () => boolean | - | diff --git a/components/avatar/style/index.less b/components/avatar/style/index.less index da52c414d..8283ff76d 100644 --- a/components/avatar/style/index.less +++ b/components/avatar/style/index.less @@ -1,7 +1,7 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; -@avatar-prefix-cls: ~"@{ant-prefix}-avatar"; +@avatar-prefix-cls: ~'@{ant-prefix}-avatar'; .@{avatar-prefix-cls} { .reset-component; @@ -45,10 +45,6 @@ line-height: @size; border-radius: 50%; - & > * { - line-height: @size; - } - &-string { position: absolute; left: 50%; diff --git a/components/back-top/__tests__/index.test.js b/components/back-top/__tests__/index.test.js index 803b7d5e6..caddee20f 100644 --- a/components/back-top/__tests__/index.test.js +++ b/components/back-top/__tests__/index.test.js @@ -2,15 +2,7 @@ import { mount } from '@vue/test-utils' import BackTop from '..' describe('BackTop', () => { - beforeAll(() => { - jest.useFakeTimers() - }) - - afterAll(() => { - jest.useRealTimers() - }) - - it('should scroll to top after click it', () => { + it('should scroll to top after click it', async () => { const wrapper = mount(BackTop, { propsData: { visibilityHeight: -1, @@ -19,9 +11,9 @@ describe('BackTop', () => { document.documentElement.scrollTop = 400 // trigger scroll manually wrapper.vm.handleScroll() - jest.runAllTimers() + await new Promise(resolve => setTimeout(resolve, 0)) wrapper.find('.ant-back-top').trigger('click') - jest.runAllTimers() + await new Promise(resolve => setTimeout(resolve, 1000)) expect(Math.abs(Math.round(document.documentElement.scrollTop))).toBe(0) }) }) diff --git a/components/back-top/style/index.less b/components/back-top/style/index.less index 27d59ff6d..c1a0d29b2 100644 --- a/components/back-top/style/index.less +++ b/components/back-top/style/index.less @@ -1,7 +1,7 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; -@backtop-prefix-cls: ~"@{ant-prefix}-back-top"; +@backtop-prefix-cls: ~'@{ant-prefix}-back-top'; .@{backtop-prefix-cls} { .reset-component; @@ -20,12 +20,12 @@ background-color: @back-top-bg; color: @back-top-color; text-align: center; - transition: all .3s @ease-in-out; + transition: all 0.3s @ease-in-out; overflow: hidden; &:hover { background-color: @back-top-hover-bg; - transition: all .3s @ease-in-out; + transition: all 0.3s @ease-in-out; } } @@ -33,7 +33,8 @@ margin: 12px auto; width: 14px; height: 16px; - background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAoCAYAAACWwljjAAAABGdBTUEAALGPC/xhBQAAAbtJREFUWAntmMtKw0AUhhMvS5cuxILgQlRUpIggIoKIIoigG1eC+AA+jo+i6FIXBfeuXIgoeKVeitVWJX5HWhhDksnUpp3FDPyZk3Nm5nycmZKkXhAEOXSA3lG7muTeRzmfy6HneUvIhnYkQK+Q9NhAA0Opg0vBEhjBKHiyb8iGMyQMOYuK41BcBSypAL+MYXSKjtFAW7EAGEO3qN4uMQbbAkXiSfRQJ1H6a+yhlkKRcAoVFYiweYNjtCVQJJpBz2GCiPt7fBOZQpFgDpUikse5HgnkM4Fi4QX0Fpc5wf9EbLqpUCy4jMoJSXWhFwbMNgWKhVbRhy5jirhs9fy/oFhgHVVTJEs7RLZ8sSEoJm6iz7SZDMbJ+/OKERQTttCXQRLToRUmrKWCYuA2+jbN0MB4OQobYShfdTCgn/sL1K36M7TLrN3n+758aPy2rrpR6+/od5E8tf/A1uLS9aId5T7J3CNYihkQ4D9PiMdMC7mp4rjB9kjFjZp8BlnVHJBuO1yFXIV0FdDF3RlyFdJVQBdv5AxVdIsq8apiZ2PyYO1EVykesGfZEESsCkweyR8MUW+V8uJ1gkYipmpdP1pm2aJVPEGzAAAAAElFTkSuQmCC) ~"100%/100%" no-repeat; + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAoCAYAAACWwljjAAAABGdBTUEAALGPC/xhBQAAAbtJREFUWAntmMtKw0AUhhMvS5cuxILgQlRUpIggIoKIIoigG1eC+AA+jo+i6FIXBfeuXIgoeKVeitVWJX5HWhhDksnUpp3FDPyZk3Nm5nycmZKkXhAEOXSA3lG7muTeRzmfy6HneUvIhnYkQK+Q9NhAA0Opg0vBEhjBKHiyb8iGMyQMOYuK41BcBSypAL+MYXSKjtFAW7EAGEO3qN4uMQbbAkXiSfRQJ1H6a+yhlkKRcAoVFYiweYNjtCVQJJpBz2GCiPt7fBOZQpFgDpUikse5HgnkM4Fi4QX0Fpc5wf9EbLqpUCy4jMoJSXWhFwbMNgWKhVbRhy5jirhs9fy/oFhgHVVTJEs7RLZ8sSEoJm6iz7SZDMbJ+/OKERQTttCXQRLToRUmrKWCYuA2+jbN0MB4OQobYShfdTCgn/sL1K36M7TLrN3n+758aPy2rrpR6+/od5E8tf/A1uLS9aId5T7J3CNYihkQ4D9PiMdMC7mp4rjB9kjFjZp8BlnVHJBuO1yFXIV0FdDF3RlyFdJVQBdv5AxVdIsq8apiZ2PyYO1EVykesGfZEESsCkweyR8MUW+V8uJ1gkYipmpdP1pm2aJVPEGzAAAAAElFTkSuQmCC) + ~'100%/100%' no-repeat; } } diff --git a/components/badge/Badge.jsx b/components/badge/Badge.jsx index e9c9d5f25..c1c577599 100644 --- a/components/badge/Badge.jsx +++ b/components/badge/Badge.jsx @@ -2,12 +2,14 @@ import PropTypes from '../_util/vue-types' import ScrollNumber from './ScrollNumber' import classNames from 'classnames' -import { initDefaultProps, filterEmpty } from '../_util/props-util' +import { initDefaultProps, filterEmpty, getComponentFromProp } from '../_util/props-util' +import { cloneElement } from '../_util/vnode' import getTransitionProps from '../_util/getTransitionProps' +import isNumeric from '../_util/isNumeric' export const BadgeProps = { /** Number to show in badge */ - count: PropTypes.oneOfType([PropTypes.number, PropTypes.string, null]), + count: PropTypes.any, showZero: PropTypes.bool, /** Max count to show */ overflowCount: PropTypes.number, @@ -27,85 +29,162 @@ export default { props: initDefaultProps(BadgeProps, { prefixCls: 'ant-badge', scrollNumberPrefixCls: 'ant-scroll-number', - count: null, showZero: false, dot: false, overflowCount: 99, }), + methods: { + getBadgeClassName () { + const { prefixCls, status } = this.$props + const children = filterEmpty(this.$slots.default) + return classNames(prefixCls, { + [`${prefixCls}-status`]: !!status, + [`${prefixCls}-not-a-wrapper`]: !children.length, + }) + }, + + isZero () { + const numberedDispayCount = this.getNumberedDispayCount() + return numberedDispayCount === '0' || numberedDispayCount === 0 + }, + + isDot () { + const { dot, status } = this.$props + const isZero = this.isZero() + return (dot && !isZero) || status + }, + + isHidden () { + const { showZero } = this.$props + const displayCount = this.getDispayCount() + const isZero = this.isZero() + const isDot = this.isDot() + const isEmpty = displayCount === null || displayCount === undefined || displayCount === '' + return (isEmpty || (isZero && !showZero)) && !isDot + }, + + getNumberedDispayCount () { + const { overflowCount } = this.$props + const count = this.badgeCount + const displayCount = + count > overflowCount ? `${overflowCount}+` : count + return displayCount + }, + + getDispayCount () { + const isDot = this.isDot() + // dot mode don't need count + if (isDot) { + return '' + } + return this.getNumberedDispayCount() + }, + + getScollNumberTitle () { + const { title } = this.$props + const count = this.badgeCount + if (title) { + return title + } + return typeof count === 'string' || typeof count === 'number' ? count : undefined + }, + + getStyleWithOffset () { + const { offset, numberStyle } = this.$props + return offset + ? { + right: `${-parseInt(offset[0], 10)}px`, + marginTop: isNumeric(offset[1]) ? `${offset[1]}px` : offset[1], + ...numberStyle, + } + : numberStyle + }, + + renderStatusText () { + const { prefixCls, text } = this.$props + const hidden = this.isHidden() + return hidden || !text ? null : {text} + }, + + renderDispayComponent () { + const count = this.badgeCount + const customNode = count + if (!customNode || typeof customNode !== 'object') { + return undefined + } + return cloneElement(customNode, { + style: this.getStyleWithOffset(), + }) + }, + + renderBadgeNumber () { + const { prefixCls, scrollNumberPrefixCls, status } = this.$props + const count = this.badgeCount + const displayCount = this.getDispayCount() + const isDot = this.isDot() + const hidden = this.isHidden() + + const scrollNumberCls = { + [`${prefixCls}-dot`]: isDot, + [`${prefixCls}-count`]: !isDot, + [`${prefixCls}-multiple-words`]: + !isDot && count && count.toString && count.toString().length > 1, + [`${prefixCls}-status-${status}`]: !!status, + } + + return hidden ? null : ( + }> + title={this.getScollNumberTitle()} + style={this.getStyleWithOffset()} + key='scrollNumber' + /> + ) + }, + }, render () { const { - count, - showZero, prefixCls, - scrollNumberPrefixCls, - overflowCount, - dot, status, text, - offset, $slots, - numberStyle, - title, } = this - let displayCount = count > overflowCount ? `${overflowCount}+` : count - const isZero = displayCount === '0' || displayCount === 0 - const isDot = (dot && !isZero) || status - // dot mode don't need count - if (isDot) { - displayCount = '' - } const children = filterEmpty($slots.default) - const isEmpty = displayCount === null || displayCount === undefined || displayCount === '' - const hidden = (isEmpty || (isZero && !showZero)) && !isDot + let count = getComponentFromProp(this, 'count') + if (Array.isArray(count)) { + count = count[0] + } + this.badgeCount = count + const scrollNumber = this.renderBadgeNumber() + const statusText = this.renderStatusText() const statusCls = classNames({ [`${prefixCls}-status-dot`]: !!status, [`${prefixCls}-status-${status}`]: !!status, }) - const scrollNumberCls = classNames({ - [`${prefixCls}-dot`]: isDot, - [`${prefixCls}-count`]: !isDot, - [`${prefixCls}-multiple-words`]: !isDot && count && count.toString && count.toString().length > 1, - [`${prefixCls}-status-${status}`]: !!status, - }) - const badgeCls = classNames(prefixCls, { - [`${prefixCls}-status`]: !!status, - [`${prefixCls}-not-a-wrapper`]: !children.length, - }) - const styleWithOffset = offset ? { - right: -parseInt(offset[0], 10), - marginTop: typeof offset[1] === 'number' ? `${offset[1]}px` : offset[1], - ...numberStyle, - } : numberStyle - // + // if (!children.length && status) { return ( - + {text} ) } - const scrollNumber = hidden ? null : ( - - ) - - const statusText = (hidden || !text) ? null : ( - {text} - ) const transitionProps = getTransitionProps(children.length ? `${prefixCls}-zoom` : '') - return ( + return ( {children} {scrollNumber} diff --git a/components/badge/ScrollNumber.jsx b/components/badge/ScrollNumber.jsx index 341c1e1c7..4ed3ff060 100644 --- a/components/badge/ScrollNumber.jsx +++ b/components/badge/ScrollNumber.jsx @@ -1,8 +1,9 @@ - +import classNames from 'classnames' import PropTypes from '../_util/vue-types' import BaseMixin from '../_util/BaseMixin' import { getStyle } from '../_util/props-util' import omit from 'omit.js' +import { cloneElement } from '../_util/vnode' function getNumberArray (num) { return num @@ -14,9 +15,11 @@ function getNumberArray (num) { const ScrollNumberProps = { prefixCls: PropTypes.string.def('ant-scroll-number'), - count: PropTypes.oneOfType([PropTypes.number, PropTypes.string, null]).def(null), + count: PropTypes.any, component: PropTypes.string, title: PropTypes.oneOfType([PropTypes.number, PropTypes.string, null]), + displayComponent: PropTypes.any, + className: PropTypes.object, } export default { @@ -105,13 +108,19 @@ export default { }, render () { - const { prefixCls, title, component: Tag = 'sup' } = this + const { prefixCls, title, component: Tag = 'sup', displayComponent, className } = this + if (displayComponent) { + return cloneElement(displayComponent, { + class: `${prefixCls}-custom-component`, + }) + } const style = getStyle(this, true) // fix https://fb.me/react-unknown-prop const restProps = omit(this.$props, [ 'count', 'component', 'prefixCls', + 'displayComponent', ]) const newProps = { props: { @@ -120,8 +129,8 @@ export default { attrs: { title, }, - class: prefixCls, style, + class: classNames(prefixCls, className), } // allow specify the border // mock border-color by box-shadow for compatible with old usage: @@ -129,6 +138,7 @@ export default { if (style && style.borderColor) { newProps.style.boxShadow = `0 0 0 1px ${style.borderColor} inset` } + return ( { this.renderNumberElement()} diff --git a/components/badge/__tests__/__snapshots__/demo.test.js.snap b/components/badge/__tests__/__snapshots__/demo.test.js.snap index 6e4863e27..a2c8a7a5a 100644 --- a/components/badge/__tests__/__snapshots__/demo.test.js.snap +++ b/components/badge/__tests__/__snapshots__/demo.test.js.snap @@ -1,28 +1,28 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/badge/demo/basic.md correctly 1`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; +exports[`renders ./components/badge/demo/basic.md correctly 1`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; exports[`renders ./components/badge/demo/change.md correctly 1`] = `
-

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

+

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

-
+
`; -exports[`renders ./components/badge/demo/dot.md correctly 1`] = ``; +exports[`renders ./components/badge/demo/dot.md correctly 1`] = ``; -exports[`renders ./components/badge/demo/link.md correctly 1`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; +exports[`renders ./components/badge/demo/link.md correctly 1`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; -exports[`renders ./components/badge/demo/no-wrapper.md correctly 1`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

99+
`; +exports[`renders ./components/badge/demo/no-wrapper.md correctly 1`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

99+
`; -exports[`renders ./components/badge/demo/overflow.md correctly 1`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

99+ 10+ 999+
`; +exports[`renders ./components/badge/demo/overflow.md correctly 1`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

99+ 10+ 999+
`; exports[`renders ./components/badge/demo/status.md correctly 1`] = `

Success
Error
Default
Processing
warning
`; -exports[`renders ./components/badge/demo/title.md correctly 1`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; +exports[`renders ./components/badge/demo/title.md correctly 1`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; diff --git a/components/badge/__tests__/__snapshots__/index.test.js.snap b/components/badge/__tests__/__snapshots__/index.test.js.snap index 5d8f7e0d0..23c9ae8c0 100644 --- a/components/badge/__tests__/__snapshots__/index.test.js.snap +++ b/components/badge/__tests__/__snapshots__/index.test.js.snap @@ -1,13 +1,15 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Badge should be compatible with borderColor style 1`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; +exports[`Badge should be compatible with borderColor style 1`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; -exports[`Badge should render when count is changed 1`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; +exports[`Badge should render when count is changed 1`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; -exports[`Badge should render when count is changed 2`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; +exports[`Badge should render when count is changed 2`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; -exports[`Badge should render when count is changed 3`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; +exports[`Badge should render when count is changed 3`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; -exports[`Badge should render when count is changed 4`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; +exports[`Badge should render when count is changed 4`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; -exports[`Badge should render when count is changed 5`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; +exports[`Badge should render when count is changed 5`] = `

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

`; + +exports[`Badge should support offset when count is a ReactNode 1`] = ``; diff --git a/components/badge/__tests__/index.test.js b/components/badge/__tests__/index.test.js index ecc4e262f..0c8577b4d 100644 --- a/components/badge/__tests__/index.test.js +++ b/components/badge/__tests__/index.test.js @@ -85,4 +85,18 @@ describe('Badge', () => { expect(wrapper.html()).toMatchSnapshot() }) + + // https://github.com/ant-design/ant-design/issues/13694 + it('should support offset when count is a ReactNode', () => { + const wrapper = mount({ + render () { + return ( + } offset={[10, 20]}> + + + ) + }, + }) + expect(wrapper.html()).toMatchSnapshot() + }) }) diff --git a/components/badge/demo/basic.md b/components/badge/demo/basic.md index f14ddd221..cea87fe5a 100644 --- a/components/badge/demo/basic.md +++ b/components/badge/demo/basic.md @@ -17,6 +17,10 @@ Simplest Usage. Badge will be hidden when `count` is `0`, but we can use `showZe + + + +
``` diff --git a/components/badge/index.en_US.md b/components/badge/index.en_US.md index f86f2de85..60f3f8714 100644 --- a/components/badge/index.en_US.md +++ b/components/badge/index.en_US.md @@ -12,7 +12,7 @@ | Property | Description | Type | Default | | -------- | ----------- | ---- | ------- | -| count | Number to show in badge | number\|string | | +| count | Number to show in badge | number\|string \| slot | | | dot | Whether to display a red dot instead of `count` | boolean | `false` | | offset | set offset of the badge dot, like [x, y] | [number\|string, number\|string] | - | | overflowCount | Max count to show | number | 99 | diff --git a/components/badge/index.zh-CN.md b/components/badge/index.zh-CN.md index f03075a6d..bc9bc5ffb 100644 --- a/components/badge/index.zh-CN.md +++ b/components/badge/index.zh-CN.md @@ -13,7 +13,7 @@ | 参数 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | -| count | 展示的数字,大于 overflowCount 时显示为 `${overflowCount}+`,为 0 时隐藏 | number\|string | | +| count | 展示的数字,大于 overflowCount 时显示为 `${overflowCount}+`,为 0 时隐藏 | number \| string \| slot | | | dot | 不展示数字,只有一个小红点 | boolean | false | | offset | 设置状态点的位置偏移,格式为 [x, y] | [number\|string, number\|string] | - | | overflowCount | 展示封顶的数字值 | number | 99 | diff --git a/components/badge/style/index.less b/components/badge/style/index.less index 78616faa5..81ef4bc97 100644 --- a/components/badge/style/index.less +++ b/components/badge/style/index.less @@ -1,8 +1,8 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; -@badge-prefix-cls: ~"@{ant-prefix}-badge"; -@number-prefix-cls: ~"@{ant-prefix}-scroll-number"; +@badge-prefix-cls: ~'@{ant-prefix}-badge'; +@number-prefix-cls: ~'@{ant-prefix}-scroll-number'; .@{badge-prefix-cls} { .reset-component; @@ -47,13 +47,18 @@ } &-count, - &-dot { + &-dot, + .@{number-prefix-cls}-custom-component { position: absolute; right: 0; transform: translateX(50%); transform-origin: 100%; } + .@{number-prefix-cls}-custom-component { + transform: translate(50%, -50%); + } + &-status { line-height: inherit; vertical-align: baseline; @@ -81,7 +86,7 @@ height: 100%; border-radius: 50%; border: 1px solid @processing-color; - content: ""; + content: ''; animation: antStatusProcessing 1.2s infinite ease-in-out; } } @@ -103,12 +108,12 @@ &-zoom-appear, &-zoom-enter { - animation: antZoomBadgeIn .3s @ease-out-back; + animation: antZoomBadgeIn 0.3s @ease-out-back; animation-fill-mode: both; } &-zoom-leave { - animation: antZoomBadgeOut .3s @ease-in-back; + animation: antZoomBadgeOut 0.3s @ease-in-back; animation-fill-mode: both; } @@ -142,7 +147,7 @@ overflow: hidden; &-only { display: inline-block; - transition: all .3s @ease-in-out; + transition: all 0.3s @ease-in-out; height: @badge-height; > p { height: @badge-height; diff --git a/components/breadcrumb/style/index.less b/components/breadcrumb/style/index.less index 2d73ab20c..30caa8344 100644 --- a/components/breadcrumb/style/index.less +++ b/components/breadcrumb/style/index.less @@ -1,7 +1,7 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; -@breadcrumb-prefix-cls: ~"@{ant-prefix}-breadcrumb"; +@breadcrumb-prefix-cls: ~'@{ant-prefix}-breadcrumb'; .@{breadcrumb-prefix-cls} { .reset-component; @@ -14,7 +14,7 @@ a { color: @breadcrumb-link-color; - transition: color .3s; + transition: color 0.3s; &:hover { color: @breadcrumb-link-color-hover; } diff --git a/components/button/__tests__/__snapshots__/demo.test.js.snap b/components/button/__tests__/__snapshots__/demo.test.js.snap index 4dff6fe2a..c7ba670e2 100644 --- a/components/button/__tests__/__snapshots__/demo.test.js.snap +++ b/components/button/__tests__/__snapshots__/demo.test.js.snap @@ -8,14 +8,12 @@ exports[`renders ./components/button/demo/button-group.md correctly 1`] = `

Basic

-
+

With Icon



-
+


+
`; @@ -70,8 +68,7 @@ exports[`renders ./components/button/demo/loading.md correctly 1`] = ` `; exports[`renders ./components/button/demo/multiple.md correctly 1`] = ` -
`; @@ -85,9 +82,7 @@ exports[`renders ./components/button/demo/size.md correctly 1`] = ` Download
diff --git a/components/button/__tests__/__snapshots__/index.test.js.snap b/components/button/__tests__/__snapshots__/index.test.js.snap index 834e92354..d3cb7ff8d 100644 --- a/components/button/__tests__/__snapshots__/index.test.js.snap +++ b/components/button/__tests__/__snapshots__/index.test.js.snap @@ -15,7 +15,7 @@ exports[`Button renders Chinese characters correctly 1`] = ` exports[`Button renders Chinese characters correctly 2`] = ` + 按钮 `; exports[`Button renders Chinese characters correctly 3`] = ` @@ -38,4 +38,6 @@ exports[`Button renders Chinese characters correctly 5`] = ` exports[`Button renders correctly 1`] = ``; -exports[`Button should support link button 1`] = `link button`; +exports[`Button should not render as link button when href is undefined 1`] = ``; + +exports[`Button should support link button 1`] = `link button`; diff --git a/components/button/__tests__/index.test.js b/components/button/__tests__/index.test.js index ca29d4395..5f0ec9bdd 100644 --- a/components/button/__tests__/index.test.js +++ b/components/button/__tests__/index.test.js @@ -173,4 +173,15 @@ describe('Button', () => { }) expect(wrapper2.html()).toMatchSnapshot() }) + + it('should not render as link button when href is undefined', async () => { + const wrapper = mount({ + render () { + return ( + + ) + }, + }) + expect(wrapper.html()).toMatchSnapshot() + }) }) diff --git a/components/button/button.jsx b/components/button/button.jsx index b22228b40..73e1a926c 100644 --- a/components/button/button.jsx +++ b/components/button/button.jsx @@ -3,13 +3,13 @@ import Icon from '../icon' const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/ const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar) import buttonTypes from './buttonTypes' +import { filterEmpty } from '../_util/props-util' const props = buttonTypes() export default { + inheritAttrs: false, name: 'AButton', __ANT_BUTTON: true, - props: { - ...props, - }, + props, data () { return { sizeMap: { @@ -48,13 +48,15 @@ export default { computed: { classes () { const { prefixCls, type, shape, size, hasTwoCNChar, - sLoading, ghost, block, sizeMap } = this + sLoading, ghost, block, sizeMap, icon, $slots } = this const sizeCls = sizeMap[size] || '' + const children = filterEmpty($slots.default) return { [`${prefixCls}`]: true, [`${prefixCls}-${type}`]: type, [`${prefixCls}-${shape}`]: shape, [`${prefixCls}-${sizeCls}`]: sizeCls, + [`${prefixCls}-icon-only`]: !children && children !== 0 && icon, [`${prefixCls}-loading`]: sLoading, [`${prefixCls}-background-ghost`]: ghost || type === 'ghost', [`${prefixCls}-two-chinese-chars`]: hasTwoCNChar, @@ -106,11 +108,8 @@ export default { disabled, handleClick, sLoading, $slots, $attrs, $listeners } = this const buttonProps = { - props: { - }, attrs: { ...$attrs, - type: htmlType, disabled, }, class: classes, @@ -121,9 +120,10 @@ export default { } const iconType = sLoading ? 'loading' : icon const iconNode = iconType ? : null - const kids = $slots.default && $slots.default.length === 1 ? this.insertSpace($slots.default[0], this.isNeedInserted()) : $slots.default + const children = filterEmpty($slots.default) + const kids = children.map(child => this.insertSpace(child, this.isNeedInserted())) - if ('href' in $attrs) { + if ($attrs.href !== undefined) { return ( {iconNode}{kids} @@ -132,7 +132,7 @@ export default { } else { return ( - diff --git a/components/button/style/index.less b/components/button/style/index.less index c2a1cbf60..6f782647e 100644 --- a/components/button/style/index.less +++ b/components/button/style/index.less @@ -1,8 +1,8 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; -@import "./mixin"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; +@import './mixin'; -@btn-prefix-cls: ~"@{ant-prefix}-btn"; +@btn-prefix-cls: ~'@{ant-prefix}-btn'; // for compatible @btn-ghost-color: @text-color; @@ -82,16 +82,24 @@ right: -1px; background: #fff; opacity: 0.35; - content: ""; + content: ''; border-radius: inherit; z-index: 1; - transition: opacity .2s; + transition: opacity 0.2s; pointer-events: none; display: none; } .@{iconfont-css-prefix} { - transition: margin-left .3s @ease-in-out; + transition: margin-left 0.3s @ease-in-out; + // Follow icon blur under windows. Change the render. + // https://github.com/ant-design/ant-design/issues/13924 + &.@{iconfont-css-prefix}-plus, + &.@{iconfont-css-prefix}-minus { + > svg { + shape-rendering: optimizeSpeed; + } + } } &&-loading:before { @@ -102,7 +110,7 @@ padding-left: 29px; pointer-events: none; position: relative; - .@{iconfont-css-prefix} { + .@{iconfont-css-prefix}:not(:last-child) { margin-left: -14px; } } @@ -150,12 +158,12 @@ } &-two-chinese-chars:first-letter { - letter-spacing: .34em; + letter-spacing: 0.34em; } &-two-chinese-chars > *:not(.@{iconfont-css-prefix}) { - letter-spacing: .34em; - margin-right: -.34em; + letter-spacing: 0.34em; + margin-right: -0.34em; } &-block { diff --git a/components/button/style/mixin.less b/components/button/style/mixin.less index 138ca4903..285d47cff 100644 --- a/components/button/style/mixin.less +++ b/components/button/style/mixin.less @@ -24,17 +24,21 @@ .button-variant-primary(@color; @background) { .button-color(@color; @background; @background); - text-shadow: 0 -1px 0 rgba(0, 0, 0, .12); - box-shadow: 0 2px 0 rgba(0, 0, 0, .045); + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.12); + box-shadow: 0 2px 0 rgba(0, 0, 0, 0.045); &:hover, &:focus { - .button-color(@color; ~`colorPalette("@{background}", 5)`; ~`colorPalette("@{background}", 5)`); + .button-color( + @color; ~`colorPalette('@{background}', 5) `; ~`colorPalette('@{background}', 5) ` + ); } &:active, &.active { - .button-color(@color; ~`colorPalette("@{background}", 7)`; ~`colorPalette("@{background}", 7)`); + .button-color( + @color; ~`colorPalette('@{background}', 7) `; ~`colorPalette('@{background}', 7) ` + ); } .button-disabled(); @@ -60,16 +64,20 @@ .button-color(@color; @background; @border); &:hover { - .button-color(@btn-primary-color; ~`colorPalette("@{color}", 5)`; ~`colorPalette("@{color}", 5)`); + .button-color( + @btn-primary-color; ~`colorPalette('@{color}', 5) `; ~`colorPalette('@{color}', 5) ` + ); } &:focus { - .button-color(~`colorPalette("@{color}", 5)`; #fff; ~`colorPalette("@{color}", 5)`); + .button-color(~`colorPalette('@{color}', 5) `; #fff; ~`colorPalette('@{color}', 5) `); } &:active, &.active { - .button-color(@btn-primary-color; ~`colorPalette("@{color}", 7)`; ~`colorPalette("@{color}", 7)`); + .button-color( + @btn-primary-color; ~`colorPalette('@{color}', 7) `; ~`colorPalette('@{color}', 7) ` + ); } .button-disabled(); @@ -81,12 +89,12 @@ &:hover, &:focus { - .button-color(~`colorPalette("@{color}", 5)`; transparent; ~`colorPalette("@{color}", 5)`); + .button-color(~`colorPalette('@{color}', 5) `; transparent; ~`colorPalette('@{color}', 5) `); } &:active, &.active { - .button-color(~`colorPalette("@{color}", 7)`; transparent; ~`colorPalette("@{color}", 7)`); + .button-color(~`colorPalette('@{color}', 7) `; transparent; ~`colorPalette('@{color}', 7) `); } .button-disabled(); @@ -101,7 +109,7 @@ > a:only-child { color: currentColor; &:after { - content: ""; + content: ''; position: absolute; top: 0; left: 0; @@ -161,9 +169,9 @@ white-space: nowrap; .button-size(@btn-height-base; @btn-padding-base; @font-size-base; @btn-border-radius-base); user-select: none; - transition: all .3s @ease-in-out; + transition: all 0.3s @ease-in-out; position: relative; - box-shadow: 0 2px 0 rgba(0, 0, 0, .015); + box-shadow: 0 2px 0 rgba(0, 0, 0, 0.015); > .@{iconfont-css-prefix} { line-height: 1; diff --git a/components/calendar/__tests__/__snapshots__/demo.test.js.snap b/components/calendar/__tests__/__snapshots__/demo.test.js.snap index 00db10164..af5778814 100644 --- a/components/calendar/__tests__/__snapshots__/demo.test.js.snap +++ b/components/calendar/__tests__/__snapshots__/demo.test.js.snap @@ -4,17 +4,17 @@ exports[`renders ./components/calendar/demo/basic.md correctly 1`] = `
-
+
2016
-
+
-
+
Nov
-
+
@@ -310,17 +310,17 @@ exports[`renders ./components/calendar/demo/card.md correctly 1`] = `
-
+
2016
-
+
-
+
Nov
-
+
@@ -616,17 +616,17 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
-
+
2016
-
+
-
+
Nov
-
+
@@ -1029,17 +1029,17 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
-
+
2017
-
+
-
+
Jan
-
+
@@ -1333,17 +1333,17 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
-
+
2017
-
+
-
+
Jan
-
+
diff --git a/components/calendar/__tests__/__snapshots__/index.test.js.snap b/components/calendar/__tests__/__snapshots__/index.test.js.snap index 6f1ea3eb1..2a8cfe8f8 100644 --- a/components/calendar/__tests__/__snapshots__/index.test.js.snap +++ b/components/calendar/__tests__/__snapshots__/index.test.js.snap @@ -4,17 +4,17 @@ exports[`Calendar Calendar should support locale 1`] = `
-
+
2018年
-
+
-
+
Oct
-
+
diff --git a/components/calendar/locale/da_DK.js b/components/calendar/locale/da_DK.js new file mode 100644 index 000000000..01f9b5333 --- /dev/null +++ b/components/calendar/locale/da_DK.js @@ -0,0 +1,2 @@ +import da_DK from '../../date-picker/locale/da_DK' +export default da_DK diff --git a/components/calendar/locale/he_IL.js b/components/calendar/locale/he_IL.js new file mode 100644 index 000000000..b04226dcc --- /dev/null +++ b/components/calendar/locale/he_IL.js @@ -0,0 +1,2 @@ +import he_IL from '../../date-picker/locale/he_IL' +export default he_IL diff --git a/components/calendar/locale/hu_HU.js b/components/calendar/locale/hu_HU.js new file mode 100644 index 000000000..12326461c --- /dev/null +++ b/components/calendar/locale/hu_HU.js @@ -0,0 +1,2 @@ +import hu_HU from '../../date-picker/locale/hu_HU' +export default hu_HU diff --git a/components/calendar/locale/id_ID.js b/components/calendar/locale/id_ID.js new file mode 100644 index 000000000..39887f343 --- /dev/null +++ b/components/calendar/locale/id_ID.js @@ -0,0 +1,2 @@ +import id_ID from '../../date-picker/locale/id_ID' +export default id_ID diff --git a/components/calendar/style/index.less b/components/calendar/style/index.less index 0db0f391b..02581a5ac 100644 --- a/components/calendar/style/index.less +++ b/components/calendar/style/index.less @@ -1,7 +1,7 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; -@full-calendar-prefix-cls: ~"@{ant-prefix}-fullcalendar"; +@full-calendar-prefix-cls: ~'@{ant-prefix}-fullcalendar'; .@{full-calendar-prefix-cls} { .reset-component; @@ -84,7 +84,7 @@ &-month, &-date { text-align: center; - transition: all .3s; + transition: all 0.3s; } &-value { @@ -97,7 +97,7 @@ padding: 0; background: transparent; line-height: 24px; - transition: all .3s; + transition: all 0.3s; &:hover { background: @item-hover-bg; @@ -180,7 +180,7 @@ height: 116px; padding: 4px 8px; border-top: 2px solid @border-color-split; - transition: background .3s; + transition: background 0.3s; &:hover { background: @item-hover-bg; diff --git a/components/card/__tests__/__snapshots__/demo.test.js.snap b/components/card/__tests__/__snapshots__/demo.test.js.snap index f7effd168..f02dc83b5 100644 --- a/components/card/__tests__/__snapshots__/demo.test.js.snap +++ b/components/card/__tests__/__snapshots__/demo.test.js.snap @@ -268,15 +268,15 @@ exports[`renders ./components/card/demo/tabs.md correctly 1`] = `
-
+
-
-
+
+
-
+
@@ -303,16 +303,16 @@ exports[`renders ./components/card/demo/tabs.md correctly 1`] = `
-
+
-
-
+
+
-
+
diff --git a/components/card/style/index.less b/components/card/style/index.less index 9ecb1f2c3..effdb88e7 100644 --- a/components/card/style/index.less +++ b/components/card/style/index.less @@ -1,7 +1,7 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; -@card-prefix-cls: ~"@{ant-prefix}-card"; +@card-prefix-cls: ~'@{ant-prefix}-card'; @card-head-height: 48px; @card-hover-border: rgba(0, 0, 0, 0.09); @card-radius: @border-radius-sm; @@ -11,7 +11,7 @@ background: @component-background; border-radius: @card-radius; position: relative; - transition: all .3s; + transition: all 0.3s; &-hoverable { cursor: pointer; @@ -66,11 +66,10 @@ &-extra { float: right; - padding: @card-head-padding + 1.5px 0; + padding: @card-head-padding 0; font-size: @font-size-base; color: @text-color; font-weight: normal; - text-align: right; // https://stackoverflow.com/a/22429853/3040605 margin-left: auto; } @@ -88,11 +87,13 @@ &-grid { border-radius: 0; border: 0; - box-shadow: 1px 0 0 0 @border-color-split, 0 1px 0 0 @border-color-split, 1px 1px 0 0 @border-color-split, 1px 0 0 0 @border-color-split inset, 0 1px 0 0 @border-color-split inset; + box-shadow: 1px 0 0 0 @border-color-split, 0 1px 0 0 @border-color-split, + 1px 1px 0 0 @border-color-split, 1px 0 0 0 @border-color-split inset, + 0 1px 0 0 @border-color-split inset; width: 33.33%; float: left; padding: @card-padding-base; - transition: all .3s; + transition: all 0.3s; &:hover { position: relative; z-index: 1; @@ -143,7 +144,7 @@ &:hover { color: @primary-color; - transition: color .3s; + transition: color 0.3s; } & > .anticon { @@ -179,7 +180,7 @@ &-padding-transition &-head, &-padding-transition &-body { - transition: padding .3s; + transition: padding 0.3s; } &-type-inner &-head { @@ -230,6 +231,21 @@ } } + &-loading { + overflow: hidden; + position: relative; + + &:after { + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: @card-padding-base; + background: @component-background; + content: ''; + } + } + &-loading &-body { user-select: none; } @@ -244,7 +260,12 @@ height: 14px; margin: 4px 0; border-radius: @card-radius; - background: linear-gradient(90deg, rgba(207, 216, 220, .2), rgba(207, 216, 220, .4), rgba(207, 216, 220, .2)); + background: linear-gradient( + 90deg, + rgba(207, 216, 220, 0.2), + rgba(207, 216, 220, 0.4), + rgba(207, 216, 220, 0.2) + ); animation: card-loading 1.4s ease infinite; background-size: 600% 600%; } @@ -253,9 +274,9 @@ @keyframes card-loading { 0%, 100% { - background-position: 0 50%; - } - 50% { - background-position: 100% 50%; - } + background-position: 0 50%; + } + 50% { + background-position: 100% 50%; + } } diff --git a/components/carousel/__tests__/index.test.js b/components/carousel/__tests__/index.test.js index 03e17e5fb..d5a19c066 100644 --- a/components/carousel/__tests__/index.test.js +++ b/components/carousel/__tests__/index.test.js @@ -77,7 +77,7 @@ describe('Carousel', () => { sync: true, } const wrapper = mount(Carousel, props) - const onWindowResized = wrapper.vm.onWindowResized + const { onWindowResized } = wrapper.vm const spy = jest.spyOn(wrapper.vm.onWindowResized, 'cancel') const spy2 = jest.spyOn(window, 'removeEventListener') wrapper.destroy() diff --git a/components/carousel/style/index.less b/components/carousel/style/index.less index 64d1267c7..19eff4e17 100644 --- a/components/carousel/style/index.less +++ b/components/carousel/style/index.less @@ -1,5 +1,5 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; .@{ant-prefix}-carousel { .reset-component; @@ -49,7 +49,7 @@ &:before, &:after { - content: ""; + content: ''; display: table; } @@ -65,7 +65,7 @@ float: left; height: 100%; min-height: 1px; - [dir="rtl"] & { + [dir='rtl'] & { float: right; } img { @@ -133,14 +133,14 @@ .slick-prev { left: -25px; &:before { - content: "←"; + content: '←'; } } .slick-next { right: -25px; &:before { - content: "→"; + content: '→'; } } @@ -174,7 +174,7 @@ outline: none; font-size: 0; color: transparent; - transition: all .5s; + transition: all 0.5s; padding: 0; &:hover, &:focus { diff --git a/components/cascader/__tests__/__snapshots__/demo.test.js.snap b/components/cascader/__tests__/__snapshots__/demo.test.js.snap index 6f6d5e017..223ad17c3 100644 --- a/components/cascader/__tests__/__snapshots__/demo.test.js.snap +++ b/components/cascader/__tests__/__snapshots__/demo.test.js.snap @@ -1,19 +1,19 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`renders ./components/cascader/demo/basic.md correctly 1`] = ` - `; exports[`renders ./components/cascader/demo/change-on-select.md correctly 1`] = ` - `; exports[`renders ./components/cascader/demo/custom-render.md correctly 1`] = ` - + Zhejiang / Hangzhou / @@ -34,7 +34,7 @@ exports[`renders ./components/cascader/demo/custom-trigger.md correctly 1`] = ` `; exports[`renders ./components/cascader/demo/default-value.md correctly 1`] = ` -Zhejiang / Hangzhou / West LakeZhejiang / Hangzhou / West Lake `; exports[`renders ./components/cascader/demo/fields-name.md correctly 1`] = ` - `; exports[`renders ./components/cascader/demo/hover.md correctly 1`] = ` - `; exports[`renders ./components/cascader/demo/lazy.md correctly 1`] = ` - `; exports[`renders ./components/cascader/demo/search.md correctly 1`] = ` - `; exports[`renders ./components/cascader/demo/size.md correctly 1`] = ` -










`; exports[`renders ./components/cascader/demo/suffix.md correctly 1`] = ` -
ab
+
ab
`; diff --git a/components/cascader/__tests__/__snapshots__/index.test.js.snap b/components/cascader/__tests__/__snapshots__/index.test.js.snap index 291597ae7..8b4fc838c 100644 --- a/components/cascader/__tests__/__snapshots__/index.test.js.snap +++ b/components/cascader/__tests__/__snapshots__/index.test.js.snap @@ -95,7 +95,7 @@ exports[`Cascader popup correctly with defaultValue 1`] = ` `; exports[`Cascader support controlled mode 1`] = ` -Zhejiang / Hangzhou / West LakeZhejiang / Hangzhou / West Lake ) + const getPopupContainer = props.getPopupContainer || getContextPopupContainer const cascaderProps = { props: { ...props, + getPopupContainer, options: options, value: value, popupVisible: sPopupVisible, diff --git a/components/cascader/index.zh-CN.md b/components/cascader/index.zh-CN.md index 1a0d58d17..19e4a9970 100644 --- a/components/cascader/index.zh-CN.md +++ b/components/cascader/index.zh-CN.md @@ -34,6 +34,7 @@ | 参数 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | filter | 接收 `inputValue` `path` 两个参数,当 `path` 符合筛选条件时,应返回 true,反之则返回 false。 | `function(inputValue, path): boolean` | | +| limit | 搜索结果展示数量 | number \| false | 50 | | matchInputWidth | 搜索结果列表是否与输入框同宽 | boolean | | | render | 用于渲染 filter 后的选项,可使用slot="showSearchRender" 和 slot-scope="{inputValue, path}" | `function({inputValue, path}): vNode` | | | sort | 用于排序 filter 后的选项 | `function(a, b, inputValue)` | | diff --git a/components/cascader/style/index.less b/components/cascader/style/index.less index 5de52826e..a688905cf 100644 --- a/components/cascader/style/index.less +++ b/components/cascader/style/index.less @@ -1,8 +1,8 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; -@import "../../input/style/mixin"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; +@import '../../input/style/mixin'; -@cascader-prefix-cls: ~"@{ant-prefix}-cascader"; +@cascader-prefix-cls: ~'@{ant-prefix}-cascader'; .@{cascader-prefix-cls} { .reset-component; @@ -28,7 +28,7 @@ background-color: @component-background; border-radius: @border-radius-base; outline: 0; - transition: color .3s; + transition: color 0.3s; &-with-value &-label { color: transparent; @@ -101,7 +101,7 @@ margin-top: -6px; line-height: 12px; color: @disabled-color; - transition: transform .2s; + transition: transform 0.2s; &&-expand { transform: rotate(180deg); } diff --git a/components/checkbox/Group.jsx b/components/checkbox/Group.jsx index 4e2e8c989..fe993ef01 100644 --- a/components/checkbox/Group.jsx +++ b/components/checkbox/Group.jsx @@ -44,7 +44,7 @@ export default { }, methods: { getOptions () { - const { options } = this.$props + const { options, $scopedSlots } = this return options.map(option => { if (typeof option === 'string') { return { @@ -52,7 +52,11 @@ export default { value: option, } } - return option + let label = option.label + if (label === undefined && $scopedSlots.label) { + label = $scopedSlots.label(option) + } + return { ...option, label } }) }, toggleOption (option) { diff --git a/components/checkbox/__tests__/__snapshots__/demo.test.js.snap b/components/checkbox/__tests__/__snapshots__/demo.test.js.snap index 1a8b85542..72d6526c2 100644 --- a/components/checkbox/__tests__/__snapshots__/demo.test.js.snap +++ b/components/checkbox/__tests__/__snapshots__/demo.test.js.snap @@ -27,7 +27,7 @@ exports[`renders ./components/checkbox/demo/group.md correctly 1`] = `



-
+
`; diff --git a/components/checkbox/demo/group.md b/components/checkbox/demo/group.md index eb6c696af..19b3b5498 100644 --- a/components/checkbox/demo/group.md +++ b/components/checkbox/demo/group.md @@ -17,7 +17,9 @@ Generate a group of checkboxes from an array

- + + {{value}} +
+``` diff --git a/components/comment/demo/editor.md b/components/comment/demo/editor.md new file mode 100644 index 000000000..d2855251d --- /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..61f738f74 --- /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..d8544d8b7 --- /dev/null +++ b/components/comment/demo/nested.md @@ -0,0 +1,54 @@ + +#### 嵌套评论 +评论可以嵌套。 + + + +#### 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..ecde03e86 --- /dev/null +++ b/components/comment/index.en-US.md @@ -0,0 +1,9 @@ +## 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 | - | +| 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..bdcb446ac --- /dev/null +++ b/components/comment/index.jsx @@ -0,0 +1,95 @@ +import PropsTypes from '../_util/vue-types' +import { initDefaultProps, getComponentFromProp } from '../_util/props-util' + +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 = getComponentFromProp(this, 'actions') + const author = getComponentFromProp(this, 'author') + const avatar = getComponentFromProp(this, 'avatar') + const content = getComponentFromProp(this, 'content') + const datetime = getComponentFromProp(this, 'datetime') + + const avatarDom = ( +
    + {typeof avatar === 'string' ? : avatar} +
    + ) + + const actionDom = + actions && actions.length ? ( +
      {this.getAction(actions)}
    + ) : null + + const authorContent = ( + + ) + + 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..b7455b5b0 --- /dev/null +++ b/components/comment/index.zh-CN.md @@ -0,0 +1,9 @@ +## API + +| Property | Description | Type | Default | +| -------- | ----------- | ---- | ------- | +| actions | 在评论内容下面呈现的操作项列表 | Array\|slot | - | +| author | 要显示为注释作者的元素 | string\|slot | - | +| avatar | 要显示为评论头像的元素 - 通常是 antd `Avatar` 或者src | string\|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..3a3ab0de5 --- /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/config-provider/demo/index.vue b/components/config-provider/demo/index.vue new file mode 100644 index 000000000..08b0655ce --- /dev/null +++ b/components/config-provider/demo/index.vue @@ -0,0 +1,32 @@ + diff --git a/components/config-provider/index.en-US.md b/components/config-provider/index.en-US.md new file mode 100644 index 000000000..52629e520 --- /dev/null +++ b/components/config-provider/index.en-US.md @@ -0,0 +1,16 @@ + +## Usage + +This component provides a configuration to all Vue components underneath itself via the [provide / inject](https://vuejs.org/v2/api/#provide-inject), In the render tree all components will have access to the provided config. + +````html + + + +```` + +## API + +| Property | Description | Type | Default | +| -------- | ----------- | ---- | ------- | +| getPopupContainer | to set the container of the popup element. The default is to create a `div` element in `body`. | Function(triggerNode) | `() => document.body` | diff --git a/components/config-provider/index.jsx b/components/config-provider/index.jsx new file mode 100644 index 000000000..289f47327 --- /dev/null +++ b/components/config-provider/index.jsx @@ -0,0 +1,25 @@ + +import PropTypes from '../_util/vue-types' + +const ConfigProvider = { + name: 'AConfigProvider', + props: { + getPopupContainer: PropTypes.func, + }, + provide () { + return { + configProvider: this.$props, + } + }, + render () { + return this.$slots.default ? this.$slots.default[0] : null + }, +} + +/* istanbul ignore next */ +ConfigProvider.install = function (Vue) { + Vue.component(ConfigProvider.name, ConfigProvider) +} + +export default ConfigProvider + diff --git a/components/config-provider/index.zh-CN.md b/components/config-provider/index.zh-CN.md new file mode 100644 index 000000000..5beed7964 --- /dev/null +++ b/components/config-provider/index.zh-CN.md @@ -0,0 +1,15 @@ +## 使用 + +ConfigProvider 使用 Vue 的 [provide / inject](https://vuejs.org/v2/api/#provide-inject) 特性,只需在应用外围包裹一次即可全局生效。 + +````html + + + +```` + +## API + +| 参数 | 说明 | 类型 | 默认值 | +| --- | --- | --- | --- | +| getPopupContainer | 弹出框(Select, Tooltip, Menu 等等)渲染父节点,默认渲染到 body 上。 | Function(triggerNode) | () => document.body | diff --git a/components/config-provider/style/index.js b/components/config-provider/style/index.js new file mode 100644 index 000000000..d74e52ee9 --- /dev/null +++ b/components/config-provider/style/index.js @@ -0,0 +1 @@ +import './index.less'; diff --git a/components/config-provider/style/index.less b/components/config-provider/style/index.less new file mode 100644 index 000000000..df1dee5e0 --- /dev/null +++ b/components/config-provider/style/index.less @@ -0,0 +1,2 @@ +// placeholder +@import '../../style/themes/default'; diff --git a/components/date-picker/RangePicker.jsx b/components/date-picker/RangePicker.jsx index e62240197..20af18d8c 100644 --- a/components/date-picker/RangePicker.jsx +++ b/components/date-picker/RangePicker.jsx @@ -50,11 +50,12 @@ function fixLocale (value, localeCode) { if (!value || value.length === 0) { return } - if (value[0]) { - value[0].locale(localeCode) + const [start, end] = value + if (start) { + start.locale(localeCode) } - if (value[1]) { - value[1].locale(localeCode) + if (end) { + end.locale(localeCode) } } @@ -73,9 +74,10 @@ export default { }, data () { const value = this.value || this.defaultValue || [] + const [start, end] = value if ( - value[0] && !interopDefault(moment).isMoment(value[0]) || - value[1] && !interopDefault(moment).isMoment(value[1]) + start && !interopDefault(moment).isMoment(start) || + end && !interopDefault(moment).isMoment(end) ) { throw new Error( 'The value/defaultValue of RangePicker must be a moment object array after `antd@2.0`, ' + @@ -127,11 +129,11 @@ export default { sShowDate: getShowDateFromValue(value) || sShowDate, })) } + const [start, end] = value this.$emit('change', value, [ - formatValue(value[0], this.format), - formatValue(value[1], this.format), + formatValue(start, this.format), + formatValue(end, this.format), ]) - this.focus() }, handleOpenChange (open) { @@ -143,6 +145,10 @@ export default { this.clearHoverValue() } this.$emit('openChange', open) + + if (!open) { + this.focus() + } }, handleShowDateChange (showDate) { @@ -160,7 +166,8 @@ export default { }, handleCalendarInputSelect (value) { - if (!value[0]) { + const [start] = value + if (!start) { return } this.setState(({ sShowDate }) => ({ @@ -317,8 +324,8 @@ export default { if (props.showTime) { pickerStyle.width = '350px' } - - const clearIcon = (!props.disabled && props.allowClear && value && (value[0] || value[1])) ? ( + const [startValue, endValue] = value + const clearIcon = (!props.disabled && props.allowClear && value && (startValue || endValue)) ? ( { - const start = inputValue[0] - const end = inputValue[1] + const [start, end] = inputValue return ( ) - const clearIcon = (!disabled && allowClear && this.sValue) ? ( + const clearIcon = (!disabled && allowClear && $data._value) ? ( { return ( - +
    diff --git a/components/date-picker/__tests__/__snapshots__/WeekPicker.test.js.snap b/components/date-picker/__tests__/__snapshots__/WeekPicker.test.js.snap index e77c56ad6..387e42330 100644 --- a/components/date-picker/__tests__/__snapshots__/WeekPicker.test.js.snap +++ b/components/date-picker/__tests__/__snapshots__/WeekPicker.test.js.snap @@ -1,3 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`WeekPicker should support style prop 1`] = ``; +exports[`WeekPicker should support style prop 1`] = ``; diff --git a/components/date-picker/__tests__/__snapshots__/demo.test.js.snap b/components/date-picker/__tests__/__snapshots__/demo.test.js.snap index 6c1e5f529..ab062d217 100644 --- a/components/date-picker/__tests__/__snapshots__/demo.test.js.snap +++ b/components/date-picker/__tests__/__snapshots__/demo.test.js.snap @@ -3,13 +3,13 @@ exports[`renders ./components/date-picker/demo/basic.md correctly 1`] = `


    ~
    +

    `; exports[`renders ./components/date-picker/demo/date-render.md correctly 1`] = `
    ~
    +
    `; exports[`renders ./components/date-picker/demo/disabled.md correctly 1`] = ` @@ -58,7 +58,7 @@ exports[`renders ./components/date-picker/demo/size.md correctly 1`] = `




    ~
    +
    `; @@ -67,7 +67,7 @@ exports[`renders ./components/date-picker/demo/start-end.md correctly 1`] = `


    ~

    ab

    ab

    ~ ab
    ab
    +

    ab

    ab

    ~ ab
    ab
    `; exports[`renders ./components/date-picker/demo/time.md correctly 1`] = ` diff --git a/components/date-picker/__tests__/showTime.test.js b/components/date-picker/__tests__/showTime.test.js index 1c72997f6..6e364d972 100644 --- a/components/date-picker/__tests__/showTime.test.js +++ b/components/date-picker/__tests__/showTime.test.js @@ -1,5 +1,6 @@ import { mount } from '@vue/test-utils' import { asyncExpect } from '@/tests/utils' +import moment from 'moment' import DatePicker from '../' const { RangePicker } = DatePicker @@ -34,7 +35,14 @@ describe('DatePicker with showTime', () => { const onChangeFn = jest.fn() const wrapper = mount({ render () { - return + return }, }, { sync: false }) diff --git a/components/date-picker/createPicker.js b/components/date-picker/createPicker.js index d74f49fd2..8a3ed7efc 100644 --- a/components/date-picker/createPicker.js +++ b/components/date-picker/createPicker.js @@ -92,7 +92,6 @@ export default function createPicker (TheCalendar, props) { }) } this.$emit('change', value, (value && value.format(this.format)) || '') - this.focus() }, handleCalendarChange (value) { @@ -104,6 +103,9 @@ export default function createPicker (TheCalendar, props) { this.setState({ _open: open }) } this.$emit('openChange', open) + if (!open) { + this.focus() + } }, focus () { this.$refs.input.focus() diff --git a/components/date-picker/index.en-US.md b/components/date-picker/index.en-US.md index 03c19035a..290c69eb9 100644 --- a/components/date-picker/index.en-US.md +++ b/components/date-picker/index.en-US.md @@ -80,7 +80,7 @@ The following APIs are shared by DatePicker, MonthPicker, RangePicker, WeekPicke | -------- | ----------- | ---- | ------- | | defaultValue | to set default date | [moment](http://momentjs.com/) | - | | defaultPickerValue | to set default picker date | [moment](http://momentjs.com/) | - | -| format | to set the date format, refer to [moment.js](http://momentjs.com/) | string | "YYYY-MM" | +| format | to set the date format. When an array is provided, all values are used for parsing and first value for display. refer to [moment.js](http://momentjs.com/) | string \| string[] | "YYYY-MM" | | monthCellContentRender | Custom month cell content render method by setting a scoped slot | slot="monthCellContentRender" slot-scope="date, locale" | - | | renderExtraFooter | render extra footer in panel by setting a scoped slot | slot="renderExtraFooter" | - | | value(v-model) | to set date | [moment](http://momentjs.com/) | - | @@ -110,18 +110,18 @@ The following APIs are shared by DatePicker, MonthPicker, RangePicker, WeekPicke | -------- | ----------- | ---- | ------- | | defaultValue | to set default date | [moment](http://momentjs.com/)\[] | - | | defaultPickerValue | to set default picker date | [moment](http://momentjs.com/)\[] | - | -| disabledTime | to specify the time that cannot be selected | function(dates: [moment, moment], partial: `'start'|'end'`) | - | +| disabledTime | to specify the time that cannot be selected | function(dates: \[moment, moment\], partial: `'start'|'end'`) | - | | format | to set the date format | string | "YYYY-MM-DD HH:mm:ss" | | ranges | preseted ranges for quick selection | { \[range: string]: [moment](http://momentjs.com/)\[] } \| { \[range: string]: () => [moment](http://momentjs.com/)\[] } | - | | renderExtraFooter | render extra footer in panel by setting a scoped slot| slot="renderExtraFooter" | - | | showTime | to provide an additional time selection | object\|boolean | [TimePicker Options](/ant-design-vue/components/time-picker/#API) | -| showTime.defaultValue | to set default time of selected date, [demo](https://ant.design/components/date-picker/#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/)\[] | [moment(), moment()] | +| showTime.defaultValue | to set default time of selected date, [demo](https://ant.design/components/date-picker/#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/)\[] | \[moment(), moment()] | | value(v-model) | to set date | \[[moment](http://momentjs.com/), [moment](http://momentjs.com/)] | - | ### RangePicker Events | Events Name | Description | Arguments | | --- | --- | --- | -| calendarChange | a callback function, can be executed when the start time or the end time of the range is changing | function(dates: [moment, moment], dateStrings: [string, string]) | +| calendarChange | a callback function, can be executed when the start time or the end time of the range is changing | function(dates: \[moment, moment], dateStrings: \[string, string]) | | change | a callback function, can be executed when the selected time is changing | function(dates: [moment, moment], dateStrings: [string, string]) | -| ok | callback when click ok button | function() | +| ok | callback when click ok button | function(dates: [moment](http://momentjs.com/)\[]) | diff --git a/components/date-picker/index.zh-CN.md b/components/date-picker/index.zh-CN.md index 0df00d03c..a1cd98787 100644 --- a/components/date-picker/index.zh-CN.md +++ b/components/date-picker/index.zh-CN.md @@ -60,7 +60,7 @@ moment.locale('zh-cn'); | defaultValue | 默认日期 | [moment](http://momentjs.com/) | 无 | | defaultPickerValue | 默认面板日期 | [moment](http://momentjs.com/) | 无 | | disabledTime | 不可选择的时间 | function(date) | 无 | -| format | 展示的日期格式,配置参考 [moment.js](http://momentjs.com/) | string | "YYYY-MM-DD" | +| format | 设置日期格式,为数组时支持多格式匹配,展示以第一个为准。配置参考 [moment.js](http://momentjs.com/) | string \| string[] | "YYYY-MM-DD" | | renderExtraFooter | 在面板中添加额外的页脚 | slot="renderExtraFooter" | - | | showTime | 增加时间选择功能 | Object\|boolean | [TimePicker Options](/ant-design-vue/components/time-picker-cn/#API) | | showTime.defaultValue | 设置用户选择日期时默认的时分秒 | [moment](http://momentjs.com/) | moment() | @@ -112,19 +112,19 @@ moment.locale('zh-cn'); | --- | --- | --- | --- | | defaultValue | 默认日期 | [moment](http://momentjs.com/)\[] | 无 | | defaultPickerValue | 默认面板日期 | [moment](http://momentjs.com/)\[] | 无 | -| disabledTime | 不可选择的时间 | function(dates: [moment, moment], partial: `'start'|'end'`) | 无 | +| disabledTime | 不可选择的时间 | function(dates: \[moment, moment\], partial: `'start'|'end'`) | 无 | | format | 展示的日期格式 | string | "YYYY-MM-DD HH:mm:ss" | | ranges       | 预设时间范围快捷选择 | { \[range: string]: [moment](http://momentjs.com/)\[] } \| { \[range: string]: () => [moment](http://momentjs.com/)\[] } | 无 | | renderExtraFooter | 在面板中添加额外的页脚 | slot="renderExtraFooter" | - | | showTime | 增加时间选择功能 | Object\|boolean | [TimePicker Options](/ant-design-vue/components/time-picker-cn/#API) | -| showTime.defaultValue | 设置用户选择日期时默认的时分秒 | [moment](http://momentjs.com/)\[] | [moment(), moment()] | +| showTime.defaultValue | 设置用户选择日期时默认的时分秒 | [moment](http://momentjs.com/)\[] | \[moment(), moment()] | | value(v-model) | 日期 | [moment](http://momentjs.com/)\[] | 无 | ### RangePicker事件 | 事件名称 | 说明 | 回调参数 | | --- | --- | --- | -| calendarChange | 待选日期发生变化的回调 | function(dates: [moment, moment], dateStrings: [string, string]) | -| change | 日期范围发生变化的回调 | function(dates: [moment, moment], dateStrings: [string, string]) | 无 | -| ok | 点击确定按钮的回调 | function() | +| calendarChange | 待选日期发生变化的回调 | function(dates: \[moment, moment\], dateStrings: \[string, string\]) | +| change | 日期范围发生变化的回调 | function(dates: \[moment, moment\], dateStrings: \[string, string\]) | 无 | +| ok | 点击确定按钮的回调 | function(dates: [moment](http://momentjs.com/)\[]) | diff --git a/components/date-picker/interface.js b/components/date-picker/interface.js index 42b1a37c2..b759a6b63 100644 --- a/components/date-picker/interface.js +++ b/components/date-picker/interface.js @@ -13,7 +13,7 @@ export const PickerProps = () => ({ transitionName: PropTypes.string, prefixCls: PropTypes.string, inputPrefixCls: PropTypes.string, - format: PropTypes.string, + format: PropTypes.oneOfType([PropTypes.string, PropTypes.array]), disabled: PropTypes.bool, allowClear: PropTypes.bool, suffixIcon: PropTypes.any, diff --git a/components/date-picker/locale/da_DK.js b/components/date-picker/locale/da_DK.js new file mode 100644 index 000000000..ce506b97f --- /dev/null +++ b/components/date-picker/locale/da_DK.js @@ -0,0 +1,19 @@ +import CalendarLocale from '../../vc-calendar/src/locale/da_DK' +import TimePickerLocale from '../../time-picker/locale/da_DK' + +// Merge into a locale object +const locale = { + lang: { + placeholder: 'Vælg dato', + rangePlaceholder: ['Startdato', 'Slutdato'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +} + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale diff --git a/components/date-picker/locale/he_IL.js b/components/date-picker/locale/he_IL.js new file mode 100644 index 000000000..d0df808d8 --- /dev/null +++ b/components/date-picker/locale/he_IL.js @@ -0,0 +1,19 @@ +import CalendarLocale from '../../vc-calendar/src/locale/he_IL' +import TimePickerLocale from '../../time-picker/locale/he_IL' + +// Merge into a locale object +const locale = { + lang: { + placeholder: 'בחר תאריך', + rangePlaceholder: ['תאריך התחלה', 'תאריך סיום'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +} + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale diff --git a/components/date-picker/locale/hu_HU.js b/components/date-picker/locale/hu_HU.js new file mode 100644 index 000000000..189819675 --- /dev/null +++ b/components/date-picker/locale/hu_HU.js @@ -0,0 +1,19 @@ +import CalendarLocale from '../../vc-calendar/src/locale/hu_HU' +import TimePickerLocale from '../../time-picker/locale/hu_HU' + +// Merge into a locale object +const locale = { + lang: { + placeholder: 'Válasszon dátumot', + rangePlaceholder: ['Kezdő dátum', 'Befejezés dátuma'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +} + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale diff --git a/components/date-picker/locale/id_ID.js b/components/date-picker/locale/id_ID.js new file mode 100644 index 000000000..46c76de7c --- /dev/null +++ b/components/date-picker/locale/id_ID.js @@ -0,0 +1,19 @@ +import CalendarLocale from '../../vc-calendar/src/locale/id_ID' +import TimePickerLocale from '../../time-picker/locale/id_ID' + +// Merge into a locale object +const locale = { + lang: { + placeholder: 'Pilih tanggal', + rangePlaceholder: ['Mulai tanggal', 'Tanggal akhir'], + ...CalendarLocale, + }, + timePickerLocale: { + ...TimePickerLocale, + }, +} + +// All settings at: +// https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json + +export default locale diff --git a/components/date-picker/style/Calendar.less b/components/date-picker/style/Calendar.less index 93fed470d..7fc09eb7d 100644 --- a/components/date-picker/style/Calendar.less +++ b/components/date-picker/style/Calendar.less @@ -38,7 +38,7 @@ position: absolute; top: 0; color: @text-color-secondary; - font-family: Arial, "Hiragino Sans GB", "Microsoft Yahei", "Microsoft Sans Serif", sans-serif; + font-family: Arial, 'Hiragino Sans GB', 'Microsoft Yahei', 'Microsoft Sans Serif', sans-serif; padding: 0 5px; font-size: 16px; display: inline-block; @@ -214,7 +214,9 @@ background: tint(@primary-color, 80%); } - &-selected-date, &-selected-start-date, &-selected-end-date { + &-selected-date, + &-selected-start-date, + &-selected-end-date { .@{calendar-prefix-cls}-date { background: @primary-color; color: #fff; @@ -240,10 +242,10 @@ } &-disabled-cell&-today &-date { position: relative; - margin-right: 5px; + padding-right: 5px; padding-left: 5px; &:before { - content: " "; + content: ' '; position: absolute; top: -1px; left: 5px; diff --git a/components/date-picker/style/DecadePanel.less b/components/date-picker/style/DecadePanel.less index fc563ebbf..386eb3aab 100644 --- a/components/date-picker/style/DecadePanel.less +++ b/components/date-picker/style/DecadePanel.less @@ -15,11 +15,11 @@ } .@{calendar-prefix-cls}-decade-panel-header { - .calendarPanelHeader(~"@{calendar-prefix-cls}-decade-panel"); + .calendarPanelHeader(~'@{calendar-prefix-cls}-decade-panel'); } .@{calendar-prefix-cls}-decade-panel-body { - height: ~"calc(100% - 40px)"; + height: ~'calc(100% - 40px)'; } .@{calendar-prefix-cls}-decade-panel-table { diff --git a/components/date-picker/style/MonthPanel.less b/components/date-picker/style/MonthPanel.less index fbeceec8c..e2d7a0b91 100644 --- a/components/date-picker/style/MonthPanel.less +++ b/components/date-picker/style/MonthPanel.less @@ -9,7 +9,8 @@ background: @component-background; outline: none; - > div { // TODO: this is a useless wrapper, and we need to remove it in rc-calendar + > div { + // TODO: this is a useless wrapper, and we need to remove it in rc-calendar height: 100%; } } @@ -19,11 +20,11 @@ } .@{calendar-prefix-cls}-month-panel-header { - .calendarPanelHeader(~"@{calendar-prefix-cls}-month-panel"); + .calendarPanelHeader(~'@{calendar-prefix-cls}-month-panel'); } .@{calendar-prefix-cls}-month-panel-body { - height: ~"calc(100% - 40px)"; + height: ~'calc(100% - 40px)'; } .@{calendar-prefix-cls}-month-panel-table { diff --git a/components/date-picker/style/Picker.less b/components/date-picker/style/Picker.less index b9b085a88..cddc67f9f 100644 --- a/components/date-picker/style/Picker.less +++ b/components/date-picker/style/Picker.less @@ -1,4 +1,4 @@ -@import "../../button/style/mixin"; +@import '../../button/style/mixin'; .@{calendar-prefix-cls}-picker-container { .reset-component; @@ -65,7 +65,7 @@ margin-top: -7px; line-height: 14px; font-size: @font-size-sm; - transition: all .3s; + transition: all 0.3s; user-select: none; z-index: 1; } @@ -89,7 +89,7 @@ } &-icon { - font-family: "anticon"; + font-family: 'anticon'; font-size: @font-size-base; color: @disabled-color; display: inline-block; diff --git a/components/date-picker/style/RangePicker.less b/components/date-picker/style/RangePicker.less index 62cfe035d..94b0ef66c 100644 --- a/components/date-picker/style/RangePicker.less +++ b/components/date-picker/style/RangePicker.less @@ -28,7 +28,7 @@ .@{calendar-prefix-cls}-date-panel { &::after { - content: "."; + content: '.'; display: block; height: 0; clear: both; @@ -134,7 +134,7 @@ z-index: 1; } &:before { - content: ""; + content: ''; display: block; background: @item-active-bg; border-radius: 0; diff --git a/components/date-picker/style/TimePicker.less b/components/date-picker/style/TimePicker.less index 6bda07546..25e080cdc 100644 --- a/components/date-picker/style/TimePicker.less +++ b/components/date-picker/style/TimePicker.less @@ -90,7 +90,7 @@ } li:last-child:after { - content: ""; + content: ''; height: 202px; display: block; } diff --git a/components/date-picker/style/WeekPicker.less b/components/date-picker/style/WeekPicker.less index c2f674808..83eecea40 100644 --- a/components/date-picker/style/WeekPicker.less +++ b/components/date-picker/style/WeekPicker.less @@ -3,7 +3,7 @@ opacity: 0.5; } .@{calendar-prefix-cls}-body tr { - transition: all .3s; + transition: all 0.3s; cursor: pointer; &:hover { background: @primary-1; diff --git a/components/date-picker/style/YearPanel.less b/components/date-picker/style/YearPanel.less index cd7a328bc..8c7dd764a 100644 --- a/components/date-picker/style/YearPanel.less +++ b/components/date-picker/style/YearPanel.less @@ -9,7 +9,8 @@ background: @component-background; outline: none; - > div { // TODO: this is a useless wrapper, and we need to remove it in rc-calendar + > div { + // TODO: this is a useless wrapper, and we need to remove it in rc-calendar height: 100%; } } @@ -19,11 +20,11 @@ } .@{calendar-prefix-cls}-year-panel-header { - .calendarPanelHeader(~"@{calendar-prefix-cls}-year-panel"); + .calendarPanelHeader(~'@{calendar-prefix-cls}-year-panel'); } .@{calendar-prefix-cls}-year-panel-body { - height: ~"calc(100% - 40px)"; + height: ~'calc(100% - 40px)'; } .@{calendar-prefix-cls}-year-panel-table { diff --git a/components/date-picker/style/index.less b/components/date-picker/style/index.less index 466b7e889..d8e6026dc 100644 --- a/components/date-picker/style/index.less +++ b/components/date-picker/style/index.less @@ -1,17 +1,17 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; -@import "../../input/style/mixin"; -@import "../../button/style/mixin"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; +@import '../../input/style/mixin'; +@import '../../button/style/mixin'; -@calendar-prefix-cls: ~"@{ant-prefix}-calendar"; -@calendar-timepicker-prefix-cls: ~"@{ant-prefix}-calendar-time-picker"; +@calendar-prefix-cls: ~'@{ant-prefix}-calendar'; +@calendar-timepicker-prefix-cls: ~'@{ant-prefix}-calendar-time-picker'; -@import "Picker"; -@import "Calendar"; -@import "RangePicker"; -@import "TimePicker"; -@import "MonthPanel"; -@import "YearPanel"; -@import "DecadePanel"; -@import "MonthPicker"; -@import "WeekPicker"; +@import 'Picker'; +@import 'Calendar'; +@import 'RangePicker'; +@import 'TimePicker'; +@import 'MonthPanel'; +@import 'YearPanel'; +@import 'DecadePanel'; +@import 'MonthPicker'; +@import 'WeekPicker'; diff --git a/components/divider/style/index.less b/components/divider/style/index.less index c7e641189..c6ff97b74 100644 --- a/components/divider/style/index.less +++ b/components/divider/style/index.less @@ -1,7 +1,7 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; -@divider-prefix-cls: ~"@{ant-prefix}-divider"; +@divider-prefix-cls: ~'@{ant-prefix}-divider'; .@{divider-prefix-cls} { .reset-component; @@ -39,7 +39,7 @@ margin: 16px 0; &:before, &:after { - content: ""; + content: ''; display: table-cell; position: relative; top: 50%; diff --git a/components/drawer/__tests__/MultiDrawer.test.js b/components/drawer/__tests__/MultiDrawer.test.js index 8e84fb23b..d283954dc 100644 --- a/components/drawer/__tests__/MultiDrawer.test.js +++ b/components/drawer/__tests__/MultiDrawer.test.js @@ -133,7 +133,7 @@ describe('Drawer', () => { wrapper.find('#open_two_drawer').trigger('click') }, 0) await asyncExpect(() => { - const translateX = wrapper.find('.ant-drawer.test_drawer').element.parentElement.style.transform + const translateX = wrapper.find('.ant-drawer.test_drawer').element.style.transform expect(translateX).toEqual('translateX(-180px)') expect(wrapper.find('#two_drawer_text').exists()).toBe(true) }, 1000) @@ -154,7 +154,7 @@ describe('Drawer', () => { wrapper.find('#open_two_drawer').trigger('click') }, 0) await asyncExpect(() => { - const translateX = wrapper.find('.ant-drawer.test_drawer').element.parentElement.style.transform + const translateX = wrapper.find('.ant-drawer.test_drawer').element.style.transform expect(translateX).toEqual('translateX(180px)') expect(wrapper.find('#two_drawer_text').exists()).toBe(true) }, 1000) @@ -174,7 +174,7 @@ describe('Drawer', () => { wrapper.find('#open_two_drawer').trigger('click') }, 0) await asyncExpect(() => { - const translateY = wrapper.find('.ant-drawer.test_drawer').element.parentElement.style.transform + const translateY = wrapper.find('.ant-drawer.test_drawer').element.style.transform expect(translateY).toEqual('translateY(180px)') expect(wrapper.find('#two_drawer_text').exists()).toBe(true) }, 1000) diff --git a/components/drawer/__tests__/__snapshots__/Drawer.test.js.snap b/components/drawer/__tests__/__snapshots__/Drawer.test.js.snap index 688d5207a..4bbd01d5d 100644 --- a/components/drawer/__tests__/__snapshots__/Drawer.test.js.snap +++ b/components/drawer/__tests__/__snapshots__/Drawer.test.js.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Drawer class is test_drawer 1`] = ` -
    +
    @@ -16,7 +16,7 @@ exports[`Drawer class is test_drawer 1`] = ` `; exports[`Drawer closable is false 1`] = ` -
    +
    @@ -31,7 +31,7 @@ exports[`Drawer closable is false 1`] = ` `; exports[`Drawer destroyOnClose is true 1`] = ` -
    +
    @@ -46,7 +46,7 @@ exports[`Drawer destroyOnClose is true 1`] = ` `; exports[`Drawer have a title 1`] = ` -
    +
    @@ -64,7 +64,7 @@ exports[`Drawer have a title 1`] = ` `; exports[`Drawer render correctly 1`] = ` -
    +
    @@ -79,7 +79,7 @@ exports[`Drawer render correctly 1`] = ` `; exports[`Drawer render top drawer 1`] = ` -
    +
    diff --git a/components/drawer/__tests__/__snapshots__/DrawerEvent.test.js.snap b/components/drawer/__tests__/__snapshots__/DrawerEvent.test.js.snap index efd6a7c4e..7b7a6091f 100644 --- a/components/drawer/__tests__/__snapshots__/DrawerEvent.test.js.snap +++ b/components/drawer/__tests__/__snapshots__/DrawerEvent.test.js.snap @@ -2,7 +2,7 @@ exports[`Drawer render correctly 1`] = `
    -
    +
    diff --git a/components/drawer/__tests__/__snapshots__/demo.test.js.snap b/components/drawer/__tests__/__snapshots__/demo.test.js.snap index 5723e2095..d470284fd 100644 --- a/components/drawer/__tests__/__snapshots__/demo.test.js.snap +++ b/components/drawer/__tests__/__snapshots__/demo.test.js.snap @@ -6,6 +6,14 @@ exports[`renders ./components/drawer/demo/basic-right.md correctly 1`] = `
    `; +exports[`renders ./components/drawer/demo/form-in-drawer.md correctly 1`] = ` +
    + +
    +`; + exports[`renders ./components/drawer/demo/multi-level-drawer.md correctly 1`] = `
    diff --git a/components/drawer/__tests__/demo.test.js b/components/drawer/__tests__/demo.test.js index 975152a9a..695910730 100644 --- a/components/drawer/__tests__/demo.test.js +++ b/components/drawer/__tests__/demo.test.js @@ -1,3 +1,3 @@ import demoTest from '../../../tests/shared/demoTest' -demoTest('drawer', { skip: ['from-drawer.md'] }) +demoTest('drawer') diff --git a/components/drawer/demo/form-in-drawer.md b/components/drawer/demo/form-in-drawer.md new file mode 100644 index 000000000..c6b392195 --- /dev/null +++ b/components/drawer/demo/form-in-drawer.md @@ -0,0 +1,159 @@ + +#### 抽屉表单 +在抽屉中使用表单。 + + + +#### Submit form in drawer +Use form in drawer with submit button. + + +```html + + +``` diff --git a/components/drawer/demo/from-drawer.md b/components/drawer/demo/from-drawer.md deleted file mode 100644 index ffcf698c7..000000000 --- a/components/drawer/demo/from-drawer.md +++ /dev/null @@ -1,131 +0,0 @@ - -#### 对象编辑 -用于承载编辑相关操作,需要点击关闭按钮关闭。 - - - -#### Edit item in drawer -A drawer containing an editable form which needs to be collapsed by clicking the close button. - - -```html - - -``` diff --git a/components/drawer/demo/index.vue b/components/drawer/demo/index.vue index 15c24c5ea..c1db9a4a6 100644 --- a/components/drawer/demo/index.vue +++ b/components/drawer/demo/index.vue @@ -3,7 +3,7 @@ import BasicRight from './basic-right' import Placement from './placement' import UserProfile from './user-profile' import MultiLevelDrawer from './multi-level-drawer' -import FromDrawer from './from-drawer' +import FormInDrawer from './form-in-drawer' // import CustomPaging from './customPaging' // import CustomArrows from './customArrows' @@ -50,7 +50,7 @@ export default { - + diff --git a/components/drawer/index.en-US.md b/components/drawer/index.en-US.md index a1ea3659c..a944b2e94 100644 --- a/components/drawer/index.en-US.md +++ b/components/drawer/index.en-US.md @@ -4,16 +4,16 @@ | -------- | ----------- | ---- | ------- | | closable | Whether a close (x) button is visible on top right of the Drawer dialog or not. | boolean | true | | destroyOnClose | Whether to unmount child components on closing drawer or not. | boolean | false | -| getContainer | Return the mounted node for Drawer. | HTMLElement \| `() => HTMLElement` \| selectors  | 'body' | +| getContainer | Return the mounted node for Drawer. | HTMLElement \| `() => HTMLElement` \| Selectors | 'body' | | mask | Whether to show mask or not. | Boolean | true | | maskClosable | Clicking on the mask (area outside the Drawer) to close the Drawer or not. | boolean | true | | maskStyle | Style for Drawer's mask element. | object | {} | | title | The title for Drawer. | string\|slot | - | | visible | Whether the Drawer dialog is visible or not. | boolean | false | | wrapClassName | The class name of the container of the Drawer dialog. | string | - | +| wrapStyle | The style of the container of the Drawer dialog. | object | - | | width | Width of the Drawer dialog. | string\|number | 256 | | height | placement is `top` or `bottom`, height of the Drawer dialog. | string\|number | - | -| className | The class name of the container of the Drawer dialog. | string | - | | zIndex | The `z-index` of the Drawer. | Number | 1000 | | placement | The placement of the Drawer. | 'top' \| 'right' \| 'bottom' \| 'left' | 'right' | diff --git a/components/drawer/index.jsx b/components/drawer/index.jsx index c422588a7..1a61ff9ec 100644 --- a/components/drawer/index.jsx +++ b/components/drawer/index.jsx @@ -1,4 +1,4 @@ -import classNames from 'classnames' +import classnames from 'classnames' import VcDrawer from '../vc-drawer/src' import PropTypes from '../_util/vue-types' import BaseMixin from '../_util/BaseMixin' @@ -14,6 +14,7 @@ const Drawer = { maskClosable: PropTypes.bool.def(true), mask: PropTypes.bool.def(true), maskStyle: PropTypes.object, + wrapStyle: PropTypes.object, title: PropTypes.any, visible: PropTypes.bool, width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).def(256), @@ -22,7 +23,7 @@ const Drawer = { prefixCls: PropTypes.string.def('ant-drawer'), placement: PropTypes.oneOf(['top', 'right', 'bottom', 'left']).def('right'), level: PropTypes.any.def(null), - wrapClassName: PropTypes.string, + wrapClassName: PropTypes.string, // not use class like react, vue will add class to root dom }, mixins: [BaseMixin], data () { @@ -106,7 +107,7 @@ const Drawer = { return null } this.destoryClose = false - const { placement, bodyStyle } = this.$props + const { placement } = this.$props const containerStyle = placement === 'left' || placement === 'right' ? { @@ -156,26 +157,22 @@ const Drawer = { > {header} {closer} -
    +
    {this.$slots.default}
    ) }, getRcDrawerStyle () { - const { zIndex, placement, maskStyle } = this.$props - return this.$data._push - ? { - ...maskStyle, - zIndex, - transform: this.getPushTransform(placement), - } - : { - ...maskStyle, - zIndex, - } + const { zIndex, placement, maskStyle, wrapStyle } = this.$props + const { _push: push } = this.$data + return { + ...maskStyle, + zIndex, + transform: push ? this.getPushTransform(placement) : undefined, + ...wrapStyle, + } }, - }, render () { const props = getOptionProps(this) @@ -195,16 +192,16 @@ const Drawer = { open: visible, showMask: props.mask, placement, - wrapClassName: classNames({ + className: classnames({ [wrapClassName]: !!wrapClassName, [haveMask]: !!haveMask, }), + wrapStyle: this.getRcDrawerStyle(), }, on: { maskClick: this.onMaskClick, ...this.$listeners, }, - style: this.getRcDrawerStyle(), } return ( HTMLElement` \| selectors  | 'body' | +| getContainer | 指定 Drawer 挂载的 HTML 节点 | HTMLElement \| `() => HTMLElement` \| Selectors | 'body' | | maskClosable | 点击蒙层是否允许关闭 | boolean | true | | mask | 是否展示遮罩 | Boolean | true | | maskStyle | 遮罩样式 | object | {} | | title | 标题 | string \| slot | - | | visible | Drawer 是否可见 | boolean | - | | wrapClassName | 对话框外层容器的类名 | string | - | +| wrapStyle | 对话框外层容器的`style` | object | - | | width | 宽度 | string \| number | 256 | | height | 高度, 在 `placement` 为 `top` 或 `bottom` 时使用 | string \| number | 256 | | zIndex | 设置 Drawer 的 `z-index` | Number | 1000 | diff --git a/components/drawer/style/drawer.less b/components/drawer/style/drawer.less index 6475c781c..4288673bd 100644 --- a/components/drawer/style/drawer.less +++ b/components/drawer/style/drawer.less @@ -1,6 +1,6 @@ -@import "../../style/themes/default"; +@import '../../style/themes/default'; -@dawer-prefix-cls: ~"@{ant-prefix}-drawer"; +@dawer-prefix-cls: ~'@{ant-prefix}-drawer'; .@{dawer-prefix-cls} { position: fixed; @@ -169,7 +169,7 @@ height: 0; opacity: 0; background-color: @modal-mask-bg; - filter: ~"alpha(opacity=50)"; + filter: ~'alpha(opacity=50)'; transition: opacity @animation-duration-slow linear, height 0s ease @animation-duration-slow; } &-open { diff --git a/components/drawer/style/index.less b/components/drawer/style/index.less index 40a49a53b..a081a08ca 100644 --- a/components/drawer/style/index.less +++ b/components/drawer/style/index.less @@ -1,3 +1,3 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; -@import "./drawer"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; +@import './drawer'; diff --git a/components/dropdown/__tests__/__snapshots__/demo.test.js.snap b/components/dropdown/__tests__/__snapshots__/demo.test.js.snap index e1a1adcbb..46d62eb56 100644 --- a/components/dropdown/__tests__/__snapshots__/demo.test.js.snap +++ b/components/dropdown/__tests__/__snapshots__/demo.test.js.snap @@ -14,10 +14,9 @@ exports[`renders ./components/dropdown/demo/dropdown-button.md correctly 1`] = `
    -
    diff --git a/components/dropdown/__tests__/dropdown-button.test.js b/components/dropdown/__tests__/dropdown-button.test.js index 12cd3c37f..083e7742d 100644 --- a/components/dropdown/__tests__/dropdown-button.test.js +++ b/components/dropdown/__tests__/dropdown-button.test.js @@ -1,5 +1,6 @@ import { mount } from '@vue/test-utils' import Dropdown from '..' +import Menu from '../../menu' describe('DropdownButton', () => { it('pass appropriate props to Dropdown', () => { @@ -26,7 +27,17 @@ describe('DropdownButton', () => { }) it('don\'t pass visible to Dropdown if it\'s not exits', () => { - const wrapper = mount(Dropdown.Button) + const wrapper = mount({ + render () { + return ( + + foo + } + /> + ) + }, + }) const dropdownProps = wrapper.find({ name: 'ADropdown' }).props() expect('visible' in dropdownProps).toBe(false) diff --git a/components/dropdown/dropdown-button.jsx b/components/dropdown/dropdown-button.jsx index 85aa140d6..908bfdd5f 100644 --- a/components/dropdown/dropdown-button.jsx +++ b/components/dropdown/dropdown-button.jsx @@ -34,6 +34,9 @@ export default { prop: 'visible', event: 'visibleChange', }, + inject: { + configProvider: { default: {}}, + }, render () { const { type, disabled, htmlType, @@ -41,14 +44,14 @@ export default { visible, placement, getPopupContainer, ...restProps } = this.$props - + const { getPopupContainer: getContextPopupContainer } = this.configProvider const dropdownProps = { props: { align, disabled, trigger: disabled ? [] : trigger, placement, - getPopupContainer, + getPopupContainer: getPopupContainer || getContextPopupContainer, }, on: { visibleChange: this.onVisibleChange, diff --git a/components/dropdown/dropdown.jsx b/components/dropdown/dropdown.jsx index 84b012d3b..e5659b093 100644 --- a/components/dropdown/dropdown.jsx +++ b/components/dropdown/dropdown.jsx @@ -21,6 +21,9 @@ const Dropdown = { prop: 'visible', event: 'visibleChange', }, + inject: { + configProvider: { default: {}}, + }, methods: { getTransitionName () { const { placement = '', transitionName } = this.$props @@ -35,7 +38,15 @@ const Dropdown = { }, render () { - const { $slots, prefixCls, trigger, disabled, $listeners } = this + const { $slots, $listeners } = this + const props = getOptionProps(this) + const { + prefixCls, + trigger, + disabled, + getPopupContainer, + } = props + const { getPopupContainer: getContextPopupContainer } = this.configProvider const dropdownTrigger = cloneElement($slots.default, { class: `${prefixCls}-trigger`, disabled, @@ -68,7 +79,8 @@ const Dropdown = { const dropdownProps = { props: { alignPoint, - ...getOptionProps(this), + ...props, + getPopupContainer: getPopupContainer || getContextPopupContainer, transitionName: this.getTransitionName(), trigger: triggerActions, }, diff --git a/components/dropdown/getDropdownProps.js b/components/dropdown/getDropdownProps.js index 93b0391e9..e03f6ceb4 100644 --- a/components/dropdown/getDropdownProps.js +++ b/components/dropdown/getDropdownProps.js @@ -9,5 +9,9 @@ export default () => ({ prefixCls: PropTypes.string, transitionName: PropTypes.string, placement: PropTypes.oneOf(['topLeft', 'topCenter', 'topRight', 'bottomLeft', 'bottomCenter', 'bottomRight']), + overlayClassName: PropTypes.string, + overlayStyle: PropTypes.object, forceRender: PropTypes.bool, + mouseEnterDelay: PropTypes.number, + mouseLeaveDelay: PropTypes.number, }) diff --git a/components/dropdown/index.en-US.md b/components/dropdown/index.en-US.md index f6d3885c5..059bc28cf 100644 --- a/components/dropdown/index.en-US.md +++ b/components/dropdown/index.en-US.md @@ -7,6 +7,8 @@ | disabled | whether the dropdown menu is disabled | boolean | - | | getPopupContainer | to set the container of the dropdown menu. The default is to create a `div` element in `body`, you can reset it to the scrolling area and make a relative reposition. [example](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | Function(triggerNode) | `() => document.body` | | overlay(slot) | the dropdown menu | [Menu](/ant-design-vue/components/menu) | - | +| overlayClassName | Class name of the dropdown root element | string | - | +| overlayStyle | Style of the dropdown root element | object | - | | placement | placement of pop menu: `bottomLeft` `bottomCenter` `bottomRight` `topLeft` `topCenter` `topRight` | String | `bottomLeft` | | trigger | the trigger mode which executes the drop-down action | Array<`click`\|`hover`\|`contextmenu`> | `['hover']` | | visible(v-model) | whether the dropdown menu is visible | boolean | - | diff --git a/components/dropdown/index.zh-CN.md b/components/dropdown/index.zh-CN.md index 0c618f3d3..ef9ebc5ba 100644 --- a/components/dropdown/index.zh-CN.md +++ b/components/dropdown/index.zh-CN.md @@ -7,6 +7,8 @@ | disabled | 菜单是否禁用 | boolean | - | | getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。 | Function(triggerNode) | `() => document.body` | | overlay(slot) | 菜单 | [Menu](/ant-design-vue/components/menu-cn) | - | +| overlayClassName | 下拉根元素的类名称 | string | - | +| overlayStyle | 下拉根元素的样式 | object | - | | placement | 菜单弹出位置:`bottomLeft` `bottomCenter` `bottomRight` `topLeft` `topCenter` `topRight` | String | `bottomLeft` | | trigger | 触发下拉的行为 | Array<`click`\|`hover`\|`contextmenu`> | `['hover']` | | visible(v-model) | 菜单是否显示 | boolean | - | diff --git a/components/dropdown/style/index.less b/components/dropdown/style/index.less index ec0e955b0..19cfa8eb1 100644 --- a/components/dropdown/style/index.less +++ b/components/dropdown/style/index.less @@ -1,7 +1,7 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; -@dropdown-prefix-cls: ~"@{ant-prefix}-dropdown"; +@dropdown-prefix-cls: ~'@{ant-prefix}-dropdown'; .@{dropdown-prefix-cls} { .reset-component; @@ -11,6 +11,16 @@ z-index: @zindex-dropdown; display: block; + &:before { + position: absolute; + top: -7px; + left: -7px; + right: 0; + bottom: -7px; + content: ' '; + opacity: 0.0001; + } + &-wrap { position: relative; @@ -19,7 +29,7 @@ } .@{iconfont-css-prefix}-down:before { - transition: transform .2s; + transition: transform 0.2s; } } @@ -45,11 +55,12 @@ border-radius: @border-radius-base; box-shadow: @box-shadow-base; background-clip: padding-box; + -webkit-transform: translate3d(0, 0, 0); &-item-group-title { color: @text-color-secondary; padding: 5px @control-padding-horizontal; - transition: all .3s; + transition: all 0.3s; } &-submenu-popup { @@ -71,7 +82,7 @@ color: @text-color; white-space: nowrap; cursor: pointer; - transition: all .3s; + transition: all 0.3s; line-height: 22px; > .anticon:first-child { @@ -84,7 +95,7 @@ display: block; padding: 5px @control-padding-horizontal; margin: -5px -@control-padding-horizontal; - transition: all .3s; + transition: all 0.3s; &:focus { text-decoration: none; } @@ -187,7 +198,7 @@ .@{dropdown-prefix-cls}-trigger, .@{dropdown-prefix-cls}-link { - > .@{iconfont-css-prefix}:not(.@{iconfont-css-prefix}-ellipsis) { + > .@{iconfont-css-prefix}.@{iconfont-css-prefix}-down { .iconfont-size-under-12px(10px); } } @@ -199,7 +210,7 @@ padding-left: @padding-xs; padding-right: @padding-xs; } - .@{iconfont-css-prefix}:not(.@{iconfont-css-prefix}-ellipsis) { + .@{iconfont-css-prefix}.@{iconfont-css-prefix}-down { .iconfont-size-under-12px(10px); } } diff --git a/components/form/Form.jsx b/components/form/Form.jsx index 1406fb800..8c5c7a592 100755 --- a/components/form/Form.jsx +++ b/components/form/Form.jsx @@ -112,6 +112,8 @@ export const ValidationRule = { // normalize?: (value: any, prevValue: any, allValues: any) => any; // /** Whether stop validate on first rule of error for this field. */ // validateFirst?: boolean; +// /** 是否一直保留子节点的信息 */ +// preserve?: boolean; // }; const Form = { diff --git a/components/form/__tests__/__snapshots__/demo.test.js.snap b/components/form/__tests__/__snapshots__/demo.test.js.snap index aae9eb7c6..f6e2d75b7 100644 --- a/components/form/__tests__/__snapshots__/demo.test.js.snap +++ b/components/form/__tests__/__snapshots__/demo.test.js.snap @@ -129,7 +129,7 @@ exports[`renders ./components/form/demo/coordinated.vue correctly 1`] = `
    -
    Select a option and change input text above
    +
    Select a option and change input text above
    @@ -169,8 +169,7 @@ exports[`renders ./components/form/demo/dynamic-form-item.vue correctly 1`] = `
    -
    +
    @@ -371,7 +370,7 @@ exports[`renders ./components/form/demo/register.vue correctly 1`] = `
    -
    Zhejiang / Hangzhou / West Lake
    Zhejiang / Hangzhou / West Lake
    -
    +86
    +
    +86
    @@ -392,10 +391,10 @@ exports[`renders ./components/form/demo/register.vue correctly 1`] = `
    -
    -
    0 개
    @@ -6836,17 +8976,17 @@ exports[`Locale Provider should display the text as ko 1`] = `
    -
    +
    2017
    -
    +
    -
    +
    9월
    -
    +
    @@ -7135,7 +9275,39 @@ exports[`Locale Provider should display the text as ko 1`] = `
    -
    Name
    Age
    데이터 없음
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    데이터 없음
    +
    +
    +
    +
    +
    `; @@ -7156,21 +9328,21 @@ exports[`Locale Provider should display the text as ku-iq 1`] = `
  • -
    +
    10 / rûpel
    -
    +
  • -
    +
    -
    +
    ~
    0 tişt
    -
    0 tişt
    @@ -7203,17 +9375,17 @@ exports[`Locale Provider should display the text as ku-iq 1`] = `
    -
    +
    2017
    -
    +
    -
    +
    ئەیلوول
    -
    +
    @@ -7502,7 +9674,39 @@ exports[`Locale Provider should display the text as ku-iq 1`] = `
    -
    Name
    Age
    Agahî tune
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    Agahî tune
    +
    +
    +
    +
    +
    `; @@ -7523,21 +9727,21 @@ exports[`Locale Provider should display the text as mn-mn 1`] = `
  • -
    +
    10 / хуудас
    -
    +
  • -
    +
    -
    +
    ~
    0 Зүйл
    -
    0 Зүйл
    @@ -7570,17 +9774,17 @@ exports[`Locale Provider should display the text as mn-mn 1`] = `
    -
    +
    2017
    -
    +
    -
    +
    9 сар
    -
    +
    @@ -7869,7 +10073,39 @@ exports[`Locale Provider should display the text as mn-mn 1`] = `
    -
    Name
    Age
    Мэдээлэл байхгүй байна
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    Мэдээлэл байхгүй байна
    +
    +
    +
    +
    +
    `; @@ -7890,21 +10126,21 @@ exports[`Locale Provider should display the text as nb 1`] = `
  • -
    +
    10 / side
    -
    +
  • -
    +
    -
    +
    ~
    0 element
    -
    0 element
    @@ -7937,17 +10173,17 @@ exports[`Locale Provider should display the text as nb 1`] = `
    -
    +
    2017
    -
    +
    -
    +
    sep.
    -
    +
    @@ -8236,7 +10472,438 @@ exports[`Locale Provider should display the text as nb 1`] = `
    -
    Name
    Age
    Ingen data
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    Ingen data
    +
    +
    +
    +
    +
    + +
    +`; + +exports[`Locale Provider should display the text as ne-np 1`] = ` +
    + +
    +
    +
    + +
    +
    +
    ~ Click to confirm +
    +
    +
    0 वस्तु
    + +
    +
    +
    +
    0 वस्तु
    + +
    +
    +
    +
    +
    +
    +
    +
    2017
    +
    +
    +
    +
    +
    +
    +
    सेप्ट.
    +
    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    आ.सो.मं.बु.बि.शु.श.
    +
    +
    27
    +
    +
    +
    +
    +
    28
    +
    +
    +
    +
    +
    29
    +
    +
    +
    +
    +
    30
    +
    +
    +
    +
    +
    31
    +
    +
    +
    +
    +
    01
    +
    +
    +
    +
    +
    02
    +
    +
    +
    +
    +
    03
    +
    +
    +
    +
    +
    04
    +
    +
    +
    +
    +
    05
    +
    +
    +
    +
    +
    06
    +
    +
    +
    +
    +
    07
    +
    +
    +
    +
    +
    08
    +
    +
    +
    +
    +
    09
    +
    +
    +
    +
    +
    10
    +
    +
    +
    +
    +
    11
    +
    +
    +
    +
    +
    12
    +
    +
    +
    +
    +
    13
    +
    +
    +
    +
    +
    14
    +
    +
    +
    +
    +
    15
    +
    +
    +
    +
    +
    16
    +
    +
    +
    +
    +
    17
    +
    +
    +
    +
    +
    18
    +
    +
    +
    +
    +
    19
    +
    +
    +
    +
    +
    20
    +
    +
    +
    +
    +
    21
    +
    +
    +
    +
    +
    22
    +
    +
    +
    +
    +
    23
    +
    +
    +
    +
    +
    24
    +
    +
    +
    +
    +
    25
    +
    +
    +
    +
    +
    26
    +
    +
    +
    +
    +
    27
    +
    +
    +
    +
    +
    28
    +
    +
    +
    +
    +
    29
    +
    +
    +
    +
    +
    30
    +
    +
    +
    +
    +
    01
    +
    +
    +
    +
    +
    02
    +
    +
    +
    +
    +
    03
    +
    +
    +
    +
    +
    04
    +
    +
    +
    +
    +
    05
    +
    +
    +
    +
    +
    06
    +
    +
    +
    +
    +
    07
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    डाटा छैन
    +
    +
    +
    +
    +
    `; @@ -8257,21 +10924,21 @@ exports[`Locale Provider should display the text as nl 1`] = `
  • -
    +
    10 / pagina
    -
    +
  • -
    +
    -
    +
    ~
    0 item
    -
    0 item
    @@ -8304,17 +10971,17 @@ exports[`Locale Provider should display the text as nl 1`] = `
    -
    +
    2017
    -
    +
    -
    +
    sep.
    -
    +
    @@ -8603,7 +11270,39 @@ exports[`Locale Provider should display the text as nl 1`] = `
    -
    Name
    Age
    Geen gegevens
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    Geen gegevens
    +
    +
    +
    +
    +
    `; @@ -8624,21 +11323,21 @@ exports[`Locale Provider should display the text as nl-be 1`] = `
  • -
    +
    10 / pagina
    -
    +
  • -
    +
    -
    +
    ~
    0 item
    -
    0 item
    @@ -8671,17 +11370,17 @@ exports[`Locale Provider should display the text as nl-be 1`] = `
    -
    +
    2017
    -
    +
    -
    +
    sep.
    -
    +
    @@ -8970,7 +11669,39 @@ exports[`Locale Provider should display the text as nl-be 1`] = `
    -
    Name
    Age
    Geen gegevens
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    Geen gegevens
    +
    +
    +
    +
    +
    `; @@ -8991,21 +11722,21 @@ exports[`Locale Provider should display the text as pl 1`] = `
  • -
    +
    10 / stronę
    -
    +
  • -
    +
    -
    +
    ~
    0 obiekt
    -
    0 obiekt
    @@ -9038,17 +11769,17 @@ exports[`Locale Provider should display the text as pl 1`] = `
    -
    +
    2017
    -
    +
    -
    +
    wrz
    -
    +
    @@ -9337,7 +12068,39 @@ exports[`Locale Provider should display the text as pl 1`] = `
    -
    Name
    Age
    Brak danych
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    Brak danych
    +
    +
    +
    +
    +
    `; @@ -9358,21 +12121,21 @@ exports[`Locale Provider should display the text as pt 1`] = `
  • -
    +
    10 / página
    -
    +
  • -
    +
    -
    +
    ~
    0 item
    -
    0 item
    @@ -9405,17 +12168,17 @@ exports[`Locale Provider should display the text as pt 1`] = `
    -
    +
    2017
    -
    +
    -
    +
    set
    -
    +
    @@ -9704,7 +12467,39 @@ exports[`Locale Provider should display the text as pt 1`] = `
    -
    Name
    Age
    Sem resultados
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    Sem resultados
    +
    +
    +
    +
    +
    `; @@ -9725,21 +12520,21 @@ exports[`Locale Provider should display the text as pt-br 1`] = `
  • -
    +
    10 / páginas
    -
    +
  • -
    +
    -
    +
    ~
    0 item
    -
    0 item
    @@ -9772,17 +12567,17 @@ exports[`Locale Provider should display the text as pt-br 1`] = `
    -
    +
    2017
    -
    +
    -
    +
    set
    -
    +
    @@ -10071,7 +12866,39 @@ exports[`Locale Provider should display the text as pt-br 1`] = `
    -
    Name
    Age
    Não há dados
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    Não há dados
    +
    +
    +
    +
    +
    `; @@ -10092,21 +12919,21 @@ exports[`Locale Provider should display the text as ru 1`] = `
  • -
    +
    10 / стр.
    -
    +
  • -
    +
    -
    +
    ~
    0 элем.
    -
    0 элем.
    @@ -10139,17 +12966,17 @@ exports[`Locale Provider should display the text as ru 1`] = `
    -
    +
    2017
    -
    +
    -
    +
    сент.
    -
    +
    @@ -10438,7 +13265,39 @@ exports[`Locale Provider should display the text as ru 1`] = `
    -
    Name
    Age
    Нет данных
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    Нет данных
    +
    +
    +
    +
    +
    `; @@ -10459,21 +13318,21 @@ exports[`Locale Provider should display the text as sk 1`] = `
  • -
    +
    10 / strana
    -
    +
  • -
    +
    -
    +
    ~
    0 položka
    -
    0 položka
    @@ -10506,17 +13365,17 @@ exports[`Locale Provider should display the text as sk 1`] = `
    -
    +
    2017
    -
    +
    -
    +
    sep
    -
    +
    @@ -10805,7 +13664,39 @@ exports[`Locale Provider should display the text as sk 1`] = `
    -
    Name
    Age
    Žiadne dáta
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    Žiadne dáta
    +
    +
    +
    +
    +
    `; @@ -10826,21 +13717,21 @@ exports[`Locale Provider should display the text as sl 1`] = `
  • -
    +
    10 / strani
    -
    +
  • -
    +
    -
    +
    ~
    0 Objekt
    -
    0 Objekt
    @@ -10873,17 +13764,17 @@ exports[`Locale Provider should display the text as sl 1`] = `
    -
    +
    2017
    -
    +
    -
    +
    sep.
    -
    +
    @@ -11172,7 +14063,39 @@ exports[`Locale Provider should display the text as sl 1`] = `
    -
    Name
    Age
    Ni podatkov
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    Ni podatkov
    +
    +
    +
    +
    +
    `; @@ -11193,21 +14116,21 @@ exports[`Locale Provider should display the text as sr 1`] = `
  • -
    +
    10 / strani
    -
    +
  • -
    +
    -
    +
    ~
    0 stavka
    -
    0 stavka
    @@ -11240,17 +14163,17 @@ exports[`Locale Provider should display the text as sr 1`] = `
    -
    +
    2017
    -
    +
    -
    +
    sep.
    -
    +
    @@ -11539,7 +14462,39 @@ exports[`Locale Provider should display the text as sr 1`] = `
    -
    Name
    Age
    Nema podataka
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    Nema podataka
    +
    +
    +
    +
    +
    `; @@ -11560,21 +14515,21 @@ exports[`Locale Provider should display the text as sv 1`] = `
  • -
    +
    10 / sida
    -
    +
  • -
    +
    -
    +
    ~
    0 element
    -
    0 element
    @@ -11607,17 +14562,17 @@ exports[`Locale Provider should display the text as sv 1`] = `
    -
    +
    2017
    -
    +
    -
    +
    sep
    -
    +
    @@ -11906,7 +14861,39 @@ exports[`Locale Provider should display the text as sv 1`] = `
    -
    Name
    Age
    Ingen information
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    Ingen information
    +
    +
    +
    +
    +
    `; @@ -11927,21 +14914,21 @@ exports[`Locale Provider should display the text as th 1`] = `
  • -
    +
    10 / หน้า
    -
    +
  • -
    +
    -
    +
    ~
    0 ชิ้น
    -
    0 ชิ้น
    @@ -11974,17 +14961,17 @@ exports[`Locale Provider should display the text as th 1`] = `
    -
    +
    2017
    -
    +
    -
    +
    ก.ย.
    -
    +
    @@ -12273,7 +15260,39 @@ exports[`Locale Provider should display the text as th 1`] = `
    -
    Name
    Age
    ไม่มีข้อมูล
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    ไม่มีข้อมูล
    +
    +
    +
    +
    +
    `; @@ -12294,21 +15313,21 @@ exports[`Locale Provider should display the text as tr 1`] = `
  • -
    +
    10 / sayfa
    -
    +
  • -
    +
    -
    +
    ~
    0 Öğe
    -
    0 Öğe
    @@ -12341,17 +15360,17 @@ exports[`Locale Provider should display the text as tr 1`] = `
    -
    +
    2017
    -
    +
    -
    +
    Eyl
    -
    +
    @@ -12640,7 +15659,39 @@ exports[`Locale Provider should display the text as tr 1`] = `
    -
    Name
    Age
    Veri Yok
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    Veri Yok
    +
    +
    +
    +
    +
    `; @@ -12661,21 +15712,21 @@ exports[`Locale Provider should display the text as uk 1`] = `
  • -
    +
    10 / сторінці
    -
    +
  • -
    +
    -
    +
    ~
    0 item
    -
    0 item
    @@ -12708,17 +15759,17 @@ exports[`Locale Provider should display the text as uk 1`] = `
    -
    +
    2017
    -
    +
    -
    +
    вер
    -
    +
    @@ -13007,7 +16058,39 @@ exports[`Locale Provider should display the text as uk 1`] = `
    -
    Name
    Age
    Даних немає
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    Даних немає
    +
    +
    +
    +
    +
    `; @@ -13028,21 +16111,21 @@ exports[`Locale Provider should display the text as vi 1`] = `
  • -
    +
    10 / trang
    -
    +
  • -
    +
    -
    +
    ~
    0 mục
    -
    0 mục
    @@ -13075,17 +16158,17 @@ exports[`Locale Provider should display the text as vi 1`] = `
    -
    +
    2017
    -
    +
    -
    +
    Th09
    -
    +
    @@ -13374,7 +16457,39 @@ exports[`Locale Provider should display the text as vi 1`] = `
    -
    Name
    Age
    Trống
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    Trống
    +
    +
    +
    +
    +
    `; @@ -13395,21 +16510,21 @@ exports[`Locale Provider should display the text as zh-cn 1`] = `
  • -
    +
    10 条/页
    -
    +
  • -
    +
    -
    +
    ~
    0 项
    -
    0 项
    @@ -13442,17 +16557,17 @@ exports[`Locale Provider should display the text as zh-cn 1`] = `
    -
    +
    2017年
    -
    +
    -
    +
    9月
    -
    +
    @@ -13741,7 +16856,39 @@ exports[`Locale Provider should display the text as zh-cn 1`] = `
    -
    Name
    Age
    暂无数据
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    暂无数据
    +
    +
    +
    +
    +
    `; @@ -13762,21 +16909,21 @@ exports[`Locale Provider should display the text as zh-tw 1`] = `
  • -
    +
    10 條/頁
    -
    +
  • -
    +
    -
    +
    ~
    0 項目
    -
    0 項目
    @@ -13809,17 +16956,17 @@ exports[`Locale Provider should display the text as zh-tw 1`] = `
    -
    +
    2017年
    -
    +
    -
    +
    9月
    -
    +
    @@ -14108,7 +17255,39 @@ exports[`Locale Provider should display the text as zh-tw 1`] = `
    -
    Name
    Age
    目前尚無資料
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + +
    +
    Name
    +
    +
    Age
    +
    +
    +
    目前尚無資料
    +
    +
    +
    +
    +
    `; diff --git a/components/locale-provider/__tests__/index.test.js b/components/locale-provider/__tests__/index.test.js index f59baf29d..ac432f152 100644 --- a/components/locale-provider/__tests__/index.test.js +++ b/components/locale-provider/__tests__/index.test.js @@ -5,45 +5,93 @@ import moment from 'moment' import MockDate from 'mockdate' import { LocaleProvider, Pagination, DatePicker, TimePicker, Calendar, Popconfirm, Table, Modal, Select, Transfer } from '../..' +import arEG from '../ar_EG' +import bgBG from '../bg_BG' +import caES from '../ca_ES' +import csCZ from '../cs_CZ' +import daDK from '../da_DK' +import deDE from '../de_DE' +import elGR from '../el_GR' import enGB from '../en_GB' -import frFR from '../fr_FR' -import nlBE from '../nl_BE' -import itIT from '../it_IT' import enUS from '../en_US' +import esES from '../es_ES' +import etEE from '../et_EE' +import faIR from '../fa_IR' +import fiFI from '../fi_FI' +import frBE from '../fr_BE' +import frFR from '../fr_FR' +import heIL from '../he_IL' +import huHU from '../hu_HU' +import isIS from '../is_IS' +import itIT from '../it_IT' +import jaJP from '../ja_JP' +import koKR from '../ko_KR' +import kuIQ from '../ku_IQ' +import mnMN from '../mn_MN' +import nbNO from '../nb_NO' +import neNP from '../ne-NP' +import nlBE from '../nl_BE' +import nlNL from '../nl_NL' +import plPL from '../pl_PL' import ptBR from '../pt_BR' import ptPT from '../pt_PT' import ruRU from '../ru_RU' -import esES from '../es_ES' -import svSE from '../sv_SE' -import frBE from '../fr_BE' -import deDE from '../de_DE' -import nlNL from '../nl_NL' -import caES from '../ca_ES' -import csCZ from '../cs_CZ' -import koKR from '../ko_KR' -import etEE from '../et_EE' import skSK from '../sk_SK' -import jaJP from '../ja_JP' -import trTR from '../tr_TR' -import zhTW from '../zh_TW' -import fiFI from '../fi_FI' -import plPL from '../pl_PL' -import bgBG from '../bg_BG' -import viVN from '../vi_VN' -import thTH from '../th_TH' -import faIR from '../fa_IR' -import elGR from '../el_GR' -import nbNO from '../nb_NO' -import srRS from '../sr_RS' import slSI from '../sl_SI' -import isIS from '../is_IS' -import arEG from '../ar_EG' +import srRS from '../sr_RS' +import svSE from '../sv_SE' +import thTH from '../th_TH' +import trTR from '../tr_TR' import ukUA from '../uk_UA' +import viVN from '../vi_VN' +import idID from '../id_ID' import zhCN from '../zh_CN' -import kuIQ from '../ku_IQ' -import mnMN from '../mn_MN' +import zhTW from '../zh_TW' -const locales = [enUS, ptBR, ptPT, ruRU, esES, svSE, frBE, deDE, nlNL, caES, csCZ, koKR, etEE, skSK, jaJP, trTR, zhTW, fiFI, plPL, bgBG, enGB, frFR, nlBE, itIT, viVN, thTH, faIR, elGR, nbNO, srRS, slSI, isIS, arEG, ukUA, zhCN, kuIQ, mnMN] +const locales = [ + arEG, + bgBG, + caES, + csCZ, + daDK, + deDE, + elGR, + enGB, + enUS, + esES, + etEE, + faIR, + fiFI, + frBE, + frFR, + heIL, + huHU, + isIS, + itIT, + jaJP, + koKR, + kuIQ, + mnMN, + nbNO, + neNP, + nlBE, + nlNL, + plPL, + ptBR, + ptPT, + ruRU, + skSK, + slSI, + srRS, + svSE, + thTH, + trTR, + ukUA, + viVN, + idID, + zhCN, + zhTW, +] const { Option } = Select const { RangePicker } = DatePicker diff --git a/components/locale-provider/da_DK.js b/components/locale-provider/da_DK.js new file mode 100644 index 000000000..ea7540a53 --- /dev/null +++ b/components/locale-provider/da_DK.js @@ -0,0 +1,44 @@ +import Pagination from '../vc-pagination/locale/da_DK' +import DatePicker from '../date-picker/locale/da_DK' +import TimePicker from '../time-picker/locale/da_DK' +import Calendar from '../calendar/locale/da_DK' + +export default { + locale: 'da', + DatePicker, + TimePicker, + Calendar, + Pagination, + Table: { + filterTitle: 'Filtermenu', + filterConfirm: 'OK', + filterReset: 'Nulstil', + emptyText: 'Ingen data', + selectAll: 'Vælg alle', + selectInvert: 'Inverter valg', + }, + Modal: { + okText: 'OK', + cancelText: 'Afbryd', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Afbryd', + }, + Transfer: { + notFoundContent: 'Intet fundet', + searchPlaceholder: 'Søg her', + itemUnit: 'element', + itemsUnit: 'elementer', + }, + Select: { + notFoundContent: 'Intet fundet', + }, + Upload: { + uploading: 'Uploader...', + removeFile: 'Fjern fil', + uploadError: 'Fejl ved upload', + previewFile: 'Forhåndsvisning', + }, +} diff --git a/components/locale-provider/default.js b/components/locale-provider/default.js index b11a453e8..3c6bca897 100644 --- a/components/locale-provider/default.js +++ b/components/locale-provider/default.js @@ -9,6 +9,10 @@ export default { DatePicker, TimePicker, Calendar, + // locales for all comoponents + global: { + placeholder: 'Please select', + }, Table: { filterTitle: 'Filter menu', filterConfirm: 'OK', diff --git a/components/locale-provider/fi_FI.js b/components/locale-provider/fi_FI.js index 9bbfb6033..2b3279de0 100644 --- a/components/locale-provider/fi_FI.js +++ b/components/locale-provider/fi_FI.js @@ -16,6 +16,7 @@ export default { emptyText: 'Ei kohteita', selectAll: 'Valitse kaikki', selectInvert: 'Valitse päinvastoin', + sortTitle: 'Lajittele', }, Modal: { okText: 'OK', diff --git a/components/locale-provider/he_IL.js b/components/locale-provider/he_IL.js new file mode 100644 index 000000000..a90ad4dd6 --- /dev/null +++ b/components/locale-provider/he_IL.js @@ -0,0 +1,44 @@ +import Pagination from '../vc-pagination/locale/he_IL' +import DatePicker from '../date-picker/locale/he_IL' +import TimePicker from '../time-picker/locale/he_IL' +import Calendar from '../calendar/locale/he_IL' + +export default { + locale: 'he', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'תפריט סינון', + filterConfirm: 'אישור', + filterReset: 'איפוס', + emptyText: 'אין מידע', + selectAll: 'בחר הכל', + selectInvert: 'הפוך בחירה', + }, + Modal: { + okText: 'אישור', + cancelText: 'ביטול', + justOkText: 'אישור', + }, + Popconfirm: { + okText: 'אישור', + cancelText: 'ביטול', + }, + Transfer: { + notFoundContent: 'לא נמצא', + searchPlaceholder: 'חפש כאן', + itemUnit: 'פריט', + itemsUnit: 'פריטים', + }, + Select: { + notFoundContent: 'לא נמצא', + }, + Upload: { + uploading: 'מעלה...', + removeFile: 'הסר קובץ', + uploadError: 'שגיאת העלאה', + previewFile: 'הצג קובץ', + }, +} diff --git a/components/locale-provider/hu_HU.js b/components/locale-provider/hu_HU.js new file mode 100644 index 000000000..b9c387529 --- /dev/null +++ b/components/locale-provider/hu_HU.js @@ -0,0 +1,45 @@ +import Pagination from '../vc-pagination/locale/hu_HU' +import DatePicker from '../date-picker/locale/hu_HU' +import TimePicker from '../time-picker/locale/hu_HU' +import Calendar from '../calendar/locale/hu_HU' + +export default { + locale: 'hu', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Szűrők', + filterConfirm: 'Alkalmazás', + filterReset: 'Visszaállítás', + emptyText: 'Nincs adat', + selectAll: 'Jelenlegi oldal kiválasztása', + selectInvert: 'Jelenlegi oldal inverze', + sortTitle: 'Rendezés', + }, + Modal: { + okText: 'Alkalmazás', + cancelText: 'Visszavonás', + justOkText: 'Alkalmazás', + }, + Popconfirm: { + okText: 'Alkalmazás', + cancelText: 'Visszavonás', + }, + Transfer: { + notFoundContent: 'Nem található', + searchPlaceholder: 'Keresés', + itemUnit: 'elem', + itemsUnit: 'elemek', + }, + Select: { + notFoundContent: 'Nem található', + }, + Upload: { + uploading: 'Feltöltés...', + removeFile: 'Fájl eltávolítása', + uploadError: 'Feltöltési hiba', + previewFile: 'Fájl előnézet', + }, +} diff --git a/components/locale-provider/id_ID.js b/components/locale-provider/id_ID.js new file mode 100644 index 000000000..1bc4d2d7a --- /dev/null +++ b/components/locale-provider/id_ID.js @@ -0,0 +1,46 @@ +import Pagination from '../vc-pagination/locale/id_ID' +import DatePicker from '../date-picker/locale/id_ID' +import TimePicker from '../time-picker/locale/id_ID' +import Calendar from '../calendar/locale/id_ID' + +export default { + locale: 'id', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Menu filter', + filterConfirm: 'baik', + filterReset: 'Setel ulang', + emptyText: 'Tidak ada data', + selectAll: 'Pilih halaman saat ini', + selectInvert: 'Balikkan halaman saat ini', + sortTitle: 'Menyortir', + }, + Modal: { + okText: 'baik', + cancelText: 'Membatalkan', + justOkText: 'baik', + }, + Popconfirm: { + okText: 'baik', + cancelText: 'Membatalkan', + }, + Transfer: { + titles: ['', ''], + notFoundContent: 'Tidak ditemukan', + searchPlaceholder: 'Cari di sini', + itemUnit: 'barang', + itemsUnit: 'item', + }, + Select: { + notFoundContent: 'Tidak ditemukan', + }, + Upload: { + uploading: 'Mengunggah...', + removeFile: 'Hapus file', + uploadError: 'Kesalahan pengunggahan', + previewFile: 'File pratinjau', + }, +} diff --git a/components/locale-provider/index.en-US.md b/components/locale-provider/index.en-US.md index a958034e1..049a64fff 100644 --- a/components/locale-provider/index.en-US.md +++ b/components/locale-provider/index.en-US.md @@ -15,7 +15,10 @@ -``` \ No newline at end of file +``` diff --git a/components/menu/index.en-US.md b/components/menu/index.en-US.md index 4179e30f6..9b2d18b9e 100644 --- a/components/menu/index.en-US.md +++ b/components/menu/index.en-US.md @@ -46,6 +46,7 @@ | ----- | ----------- | ---- | ------------- | | disabled | whether menu item is disabled or not | boolean | false | | key | unique id of the menu item | string | | +| title | set display title for collapsed item | string | | ### Menu.SubMenu diff --git a/components/menu/index.jsx b/components/menu/index.jsx index bcbb0d2cc..447a9ad26 100644 --- a/components/menu/index.jsx +++ b/components/menu/index.jsx @@ -45,6 +45,7 @@ const Menu = { mixins: [BaseMixin], inject: { layoutSiderContext: { default: {}}, + configProvider: { default: {}}, }, model: { prop: 'selectedKeys', @@ -176,26 +177,19 @@ const Menu = { const { openAnimation, openTransitionName } = this.$props let menuOpenAnimation = openAnimation || openTransitionName if (openAnimation === undefined && openTransitionName === undefined) { - switch (menuMode) { - case 'horizontal': - menuOpenAnimation = 'slide-up' - break - case 'vertical': - case 'vertical-left': - case 'vertical-right': + if (menuMode === 'horizontal') { + menuOpenAnimation = 'slide-up' + } else if (menuMode === 'inline') { + menuOpenAnimation = { on: animation } + } else { // When mode switch from inline // submenu should hide without animation - if (this.switchingModeFromInline) { - menuOpenAnimation = '' - this.switchingModeFromInline = false - } else { - menuOpenAnimation = 'zoom-big' - } - break - case 'inline': - menuOpenAnimation = { on: animation } - break - default: + if (this.switchingModeFromInline) { + menuOpenAnimation = '' + this.switchingModeFromInline = false + } else { + menuOpenAnimation = 'zoom-big' + } } } return menuOpenAnimation @@ -204,7 +198,8 @@ const Menu = { render () { const { layoutSiderContext, $slots, $listeners } = this const { collapsedWidth } = layoutSiderContext - const { prefixCls, theme } = this.$props + const { getPopupContainer: getContextPopupContainer } = this.configProvider + const { prefixCls, theme, getPopupContainer } = this.$props const menuMode = this.getRealMenuMode() const menuOpenAnimation = this.getMenuOpenAnimation(menuMode) @@ -216,6 +211,7 @@ const Menu = { const menuProps = { props: { ...omit(this.$props, ['inlineCollapsed']), + getPopupContainer: getPopupContainer || getContextPopupContainer, openKeys: this.sOpenKeys, mode: menuMode, }, diff --git a/components/menu/index.zh-CN.md b/components/menu/index.zh-CN.md index c4c4604ee..aa19701f4 100644 --- a/components/menu/index.zh-CN.md +++ b/components/menu/index.zh-CN.md @@ -44,6 +44,7 @@ | --- | --- | --- | --- | | disabled | 是否禁用 | boolean | false | | key | item 的唯一标志 | string | | +| title | 设置收缩时展示的悬浮标题 | string | | ### Menu.SubMenu diff --git a/components/menu/style/dark.less b/components/menu/style/dark.less index 4428b9178..562c94ac0 100644 --- a/components/menu/style/dark.less +++ b/components/menu/style/dark.less @@ -5,8 +5,8 @@ color: @menu-dark-color; background: @menu-dark-bg; .@{menu-prefix-cls}-submenu-title .@{menu-prefix-cls}-submenu-arrow { - opacity: .45; - transition: all .3s; + opacity: 0.45; + transition: all 0.3s; &:after, &:before { background: @menu-dark-arrow-color; @@ -20,7 +20,7 @@ &-dark &-inline&-sub { background: @menu-dark-submenu-bg; - box-shadow: 0 2px 8px rgba(0, 0, 0, .45) inset; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.45) inset; } &-dark&-horizontal { diff --git a/components/menu/style/index.less b/components/menu/style/index.less index 0a3740dd4..82c2bb131 100644 --- a/components/menu/style/index.less +++ b/components/menu/style/index.less @@ -1,7 +1,7 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; -@menu-prefix-cls: ~"@{ant-prefix}-menu"; +@menu-prefix-cls: ~'@{ant-prefix}-menu'; // default theme .@{menu-prefix-cls} { @@ -14,7 +14,7 @@ color: @menu-item-color; background: @menu-bg; line-height: 0; // Fix display inline-block gap - transition: background .3s, width .2s; + transition: background 0.3s, width 0.2s; .clearfix; ul, @@ -33,12 +33,13 @@ font-size: @font-size-base; line-height: @line-height-base; padding: 8px 16px; - transition: all .3s; + transition: all 0.3s; } &-submenu, &-submenu-inline { - transition: border-color .3s @ease-in-out, background .3s @ease-in-out, padding .15s @ease-in-out; + transition: border-color 0.3s @ease-in-out, background 0.3s @ease-in-out, + padding 0.15s @ease-in-out; } &-item:active, @@ -48,7 +49,7 @@ &-submenu &-sub { cursor: initial; - transition: background .3s @ease-in-out, padding .3s @ease-in-out; + transition: background 0.3s @ease-in-out, padding 0.3s @ease-in-out; } &-item > a { @@ -67,7 +68,7 @@ left: 0; bottom: 0; right: 0; - content: ""; + content: ''; } } @@ -153,14 +154,15 @@ position: relative; display: block; white-space: nowrap; - transition: color .3s @ease-in-out, border-color .3s @ease-in-out, background .3s @ease-in-out, padding .15s @ease-in-out; + transition: color 0.3s @ease-in-out, border-color 0.3s @ease-in-out, + background 0.3s @ease-in-out, padding 0.15s @ease-in-out; .@{iconfont-css-prefix} { min-width: 14px; margin-right: 10px; font-size: @font-size-base; - transition: font-size .15s @ease-out, margin .3s @ease-in-out; + transition: font-size 0.15s @ease-out, margin 0.3s @ease-in-out; + span { - transition: opacity .3s @ease-in-out, width .3s @ease-in-out; + transition: opacity 0.3s @ease-in-out, width 0.3s @ease-in-out; opacity: 1; } } @@ -193,7 +195,7 @@ right: 0; bottom: 0; content: ' '; - opacity: .0001; + opacity: 0.0001; } } @@ -201,7 +203,7 @@ background-color: @menu-bg; border-radius: @border-radius-base; &-submenu-title:after { - transition: transform .3s @ease-in-out; + transition: transform 0.3s @ease-in-out; } } @@ -210,14 +212,14 @@ &-vertical-right, &-inline { > .@{menu-prefix-cls}-submenu-title .@{menu-prefix-cls}-submenu-arrow { - transition: transform .3s @ease-in-out; + transition: transform 0.3s @ease-in-out; position: absolute; top: 50%; right: 16px; width: 10px; &:before, &:after { - content: ""; + content: ''; position: absolute; vertical-align: baseline; background: #fff; @@ -225,7 +227,8 @@ width: 6px; height: 1.5px; border-radius: 2px; - transition: background .3s @ease-in-out, transform .3s @ease-in-out, top .3s @ease-in-out; + transition: background 0.3s @ease-in-out, transform 0.3s @ease-in-out, + top 0.3s @ease-in-out; } &:before { transform: rotate(45deg) translateY(-2px); @@ -252,7 +255,9 @@ } &-open { - &.@{menu-prefix-cls}-submenu-inline > .@{menu-prefix-cls}-submenu-title .@{menu-prefix-cls}-submenu-arrow { + &.@{menu-prefix-cls}-submenu-inline + > .@{menu-prefix-cls}-submenu-title + .@{menu-prefix-cls}-submenu-arrow { transform: translateY(-2px); &:after { transform: rotate(-45deg) translateX(-2px); @@ -314,7 +319,7 @@ } &:after { - content: "\20"; + content: '\20'; display: block; height: 0; clear: both; @@ -328,15 +333,15 @@ .@{menu-prefix-cls}-item { position: relative; &:after { - content: ""; + content: ''; position: absolute; right: 0; top: 0; bottom: 0; border-right: @menu-item-active-border-width solid @menu-highlight-color; - transform: scaleY(.0001); + transform: scaleY(0.0001); opacity: 0; - transition: transform .15s @ease-out, opacity .15s @ease-out; + transition: transform 0.15s @ease-out, opacity 0.15s @ease-out; } } @@ -373,7 +378,7 @@ .@{menu-prefix-cls}-selected, .@{menu-prefix-cls}-item-selected { &:after { - transition: transform .15s @ease-in-out, opacity .15s @ease-in-out; + transition: transform 0.15s @ease-in-out, opacity 0.15s @ease-in-out; opacity: 1; transform: scaleY(1); } @@ -381,7 +386,7 @@ .@{menu-prefix-cls}-item, .@{menu-prefix-cls}-submenu-title { - width: ~"calc(100% + 1px)"; + width: ~'calc(100% + 1px)'; } .@{menu-prefix-cls}-submenu-title { @@ -392,8 +397,13 @@ &-inline-collapsed { width: @menu-collapsed-width; > .@{menu-prefix-cls}-item, - > .@{menu-prefix-cls}-item-group > .@{menu-prefix-cls}-item-group-list > .@{menu-prefix-cls}-item, - > .@{menu-prefix-cls}-item-group > .@{menu-prefix-cls}-item-group-list > .@{menu-prefix-cls}-submenu > .@{menu-prefix-cls}-submenu-title, + > .@{menu-prefix-cls}-item-group + > .@{menu-prefix-cls}-item-group-list + > .@{menu-prefix-cls}-item, + > .@{menu-prefix-cls}-item-group + > .@{menu-prefix-cls}-item-group-list + > .@{menu-prefix-cls}-submenu + > .@{menu-prefix-cls}-submenu-title, > .@{menu-prefix-cls}-submenu > .@{menu-prefix-cls}-submenu-title { left: 0; text-overflow: clip; diff --git a/components/message/style/index.less b/components/message/style/index.less index bef367345..fca96c3b5 100644 --- a/components/message/style/index.less +++ b/components/message/style/index.less @@ -1,7 +1,7 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; -@message-prefix-cls: ~"@{ant-prefix}-message"; +@message-prefix-cls: ~'@{ant-prefix}-message'; .@{message-prefix-cls} { .reset-component; @@ -56,7 +56,7 @@ &-notice.move-up-leave.move-up-leave-active { animation-name: MessageMoveOut; overflow: hidden; - animation-duration: .3s; + animation-duration: 0.3s; } } diff --git a/components/modal/Modal.jsx b/components/modal/Modal.jsx index d79019a8c..5f9d12963 100644 --- a/components/modal/Modal.jsx +++ b/components/modal/Modal.jsx @@ -29,7 +29,7 @@ const modalProps = (defaultProps = {}) => { /** 点击模态框右上角叉、取消按钮、Props.maskClosable 值为 true 时的遮罩层或键盘按下 Esc 时的回调*/ // onCancel: (e: React.MouseEvent) => void, afterClose: PropTypes.func.def(noop), - /** 居中 */ + /** 垂直居中 */ centered: PropTypes.bool, /** 宽度*/ width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), diff --git a/components/modal/confirm.js b/components/modal/confirm.js index df5f92bc2..796187269 100644 --- a/components/modal/confirm.js +++ b/components/modal/confirm.js @@ -26,8 +26,7 @@ export default function confirm (config) { confirmDialogInstance = null div.parentNode.removeChild(div) } - const triggerCancel = args && args.length && - args.some(param => param && param.triggerCancel) + const triggerCancel = args.some(param => param && param.triggerCancel) if (config.onCancel && triggerCancel) { config.onCancel(...args) } diff --git a/components/modal/style/confirm.less b/components/modal/style/confirm.less index 68ebb7c0e..87dec63df 100644 --- a/components/modal/style/confirm.less +++ b/components/modal/style/confirm.less @@ -1,6 +1,6 @@ -@import "../../style/mixins/index"; +@import '../../style/mixins/index'; -@confirm-prefix-cls: ~"@{ant-prefix}-modal-confirm"; +@confirm-prefix-cls: ~'@{ant-prefix}-modal-confirm'; .@{confirm-prefix-cls} { .@{ant-prefix}-modal-header { diff --git a/components/modal/style/index.less b/components/modal/style/index.less index 6f5d0b74d..39d556571 100644 --- a/components/modal/style/index.less +++ b/components/modal/style/index.less @@ -1,4 +1,4 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; -@import "./modal"; -@import "./confirm"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; +@import './modal'; +@import './confirm'; diff --git a/components/modal/style/modal.less b/components/modal/style/modal.less index 7c40f9704..1d879696e 100644 --- a/components/modal/style/modal.less +++ b/components/modal/style/modal.less @@ -1,5 +1,5 @@ -@dialog-prefix-cls: ~"@{ant-prefix}-modal"; -@table-prefix-cls: ~"@{ant-prefix}-table"; +@dialog-prefix-cls: ~'@{ant-prefix}-modal'; +@table-prefix-cls: ~'@{ant-prefix}-table'; .@{dialog-prefix-cls} { .reset-component; @@ -49,7 +49,7 @@ font-weight: 700; line-height: 1; text-decoration: none; - transition: color .3s; + transition: color 0.3s; color: @text-color-secondary; outline: 0; padding: 0; @@ -117,7 +117,7 @@ background-color: @modal-mask-bg; height: 100%; z-index: @zindex-modal-mask; - filter: ~"alpha(opacity=50)"; + filter: ~'alpha(opacity=50)'; &-hidden { display: none; @@ -132,7 +132,7 @@ .@{dialog-prefix-cls}-centered { text-align: center; &:before { - content: ""; + content: ''; display: inline-block; height: 100%; vertical-align: middle; diff --git a/components/notification/__tests__/__snapshots__/demo.test.js.snap b/components/notification/__tests__/__snapshots__/demo.test.js.snap index 8a02df53c..f5f201259 100644 --- a/components/notification/__tests__/__snapshots__/demo.test.js.snap +++ b/components/notification/__tests__/__snapshots__/demo.test.js.snap @@ -11,10 +11,10 @@ exports[`renders ./components/notification/demo/duration.md correctly 1`] = `
    -
    +
    topRight
    -
    +
    diff --git a/components/notification/__tests__/index.test.js b/components/notification/__tests__/index.test.js index 47238e463..04e800931 100644 --- a/components/notification/__tests__/index.test.js +++ b/components/notification/__tests__/index.test.js @@ -82,4 +82,12 @@ describe('notification', () => { }) done() }) + + it('trigger onClick', () => { + notification.open({ + message: 'Notification Title', + duration: 0, + }) + expect(document.querySelectorAll('.ant-notification').length).toBe(1) + }) }) diff --git a/components/notification/__tests__/placement.test.js b/components/notification/__tests__/placement.test.js index d8bb7263d..3df336d93 100644 --- a/components/notification/__tests__/placement.test.js +++ b/components/notification/__tests__/placement.test.js @@ -8,9 +8,8 @@ describe('Notification.placement', () => { return document.body.querySelectorAll(className) } - function getStyle (el, prop, getComputedStyle, style) { - getComputedStyle = getComputedStyle || window.getComputedStyle - style = getComputedStyle ? getComputedStyle(el) : el.currentStyle + function getStyle (el, prop) { + const style = window.getComputedStyle ? window.getComputedStyle(el) : el.currentStyle // If a css property's value is `auto`, it will return an empty string. return prop ? style[prop] : style diff --git a/components/notification/demo/basic.md b/components/notification/demo/basic.md index d34fffc6c..609f2ebe3 100644 --- a/components/notification/demo/basic.md +++ b/components/notification/demo/basic.md @@ -20,6 +20,9 @@ The simplest usage that close the notification box after 4.5s. this.$notification.open({ message: 'Notification Title', description: 'This is the content of the notification. This is the content of the notification. This is the content of the notification.', + onClick: () => { + console.log('Notification Clicked!'); + }, }); }, } diff --git a/components/notification/index.en-US.md b/components/notification/index.en-US.md index 57e89b79b..f08ccc07d 100644 --- a/components/notification/index.en-US.md +++ b/components/notification/index.en-US.md @@ -23,6 +23,7 @@ The properties of config are as follows: | placement | Position of Notification, can be one of `topLeft` `topRight` `bottomLeft` `bottomRight` | string | `topRight` | | style | Customized inline style | Object \| string | - | | onClose | Specify a function that will be called when the close button is clicked | Function | - | +| onClick | Specify a function that will be called when the notification is clicked | Function | - | `notification` also provides a global `config()` method that can be used for specifying the default options. Once this method is used, all the notification boxes will take into account these globally defined options when displaying. diff --git a/components/notification/index.js b/components/notification/index.js index 5bb551415..5819ac5b5 100644 --- a/components/notification/index.js +++ b/components/notification/index.js @@ -157,6 +157,7 @@ function notice (args) { duration, closable: true, onClose: args.onClose, + onClick: args.onClick, key: args.key, style: args.style || {}, class: args.class, diff --git a/components/notification/index.zh-CN.md b/components/notification/index.zh-CN.md index ae8f0ef6c..f596c815a 100644 --- a/components/notification/index.zh-CN.md +++ b/components/notification/index.zh-CN.md @@ -31,6 +31,7 @@ config 参数如下: | placement | 弹出位置,可选 `topLeft` `topRight` `bottomLeft` `bottomRight` | string | topRight | | style | 自定义内联样式 | Object \| string | - | | onClose | 点击默认关闭按钮时触发的回调函数 | Function | - | +| onClick | 点击通知时触发的回调函数 | Function | - | 还提供了一个全局配置方法,在调用前提前配置,全局一次生效。 diff --git a/components/notification/style/index.less b/components/notification/style/index.less index aee8bacbc..d81edaa5e 100644 --- a/components/notification/style/index.less +++ b/components/notification/style/index.less @@ -1,7 +1,7 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; -@notification-prefix-cls: ~"@{ant-prefix}-notification"; +@notification-prefix-cls: ~'@{ant-prefix}-notification'; @notification-width: 384px; @notification-padding-vertical: 16px; @notification-padding-horizontal: 24px; @@ -14,7 +14,7 @@ position: fixed; z-index: @zindex-notification; width: @notification-width; - max-width: ~"calc(100vw - 32px)"; + max-width: ~'calc(100vw - 32px)'; margin-right: 24px; &-topLeft, @@ -52,13 +52,13 @@ // https://github.com/ant-design/ant-design/issues/5846#issuecomment-296244140 &-single-line-auto-margin { - width: ~"calc(@{notification-width} - @{notification-padding-horizontal} * 2 - 24px - 48px - 100%)"; + width: ~'calc(@{notification-width} - @{notification-padding-horizontal} * 2 - 24px - 48px - 100%)'; background-color: transparent; pointer-events: none; display: block; max-width: 4px; &:before { - content: ""; + content: ''; display: block; } } diff --git a/components/pagination/Pagination.jsx b/components/pagination/Pagination.jsx index 3f14d5863..f536fcab6 100644 --- a/components/pagination/Pagination.jsx +++ b/components/pagination/Pagination.jsx @@ -2,7 +2,6 @@ import PropTypes from '../_util/vue-types' import VcSelect from '../select' import MiniSelect from './MiniSelect' -import enUS from '../vc-pagination/locale/en_US' import LocaleReceiver from '../locale-provider/LocaleReceiver' import { getOptionProps } from '../_util/props-util' import VcPagination from '../vc-pagination' @@ -121,7 +120,6 @@ export default { return (
  • -
    +
    10 / page
    -
    +
  • @@ -68,10 +68,10 @@ exports[`renders ./components/pagination/demo/changer.md correctly 1`] = `
  • -
    +
    20 / page
    -
    +
  • @@ -111,12 +111,12 @@ exports[`renders ./components/pagination/demo/custom-changer.md correctly 1`] =
  • -
    +
    -
    10条/页 +
    10条/页
    -
    +
  • @@ -197,10 +197,10 @@ exports[`renders ./components/pagination/demo/mini.md correctly 1`] = `
  • -
    +
    10 / page
    -
    +
    Goto
    diff --git a/components/pagination/style/index.less b/components/pagination/style/index.less index 66383b3ce..2b5d945b7 100644 --- a/components/pagination/style/index.less +++ b/components/pagination/style/index.less @@ -1,8 +1,8 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; -@import "../../input/style/mixin"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; +@import '../../input/style/mixin'; -@pagination-prefix-cls: ~"@{ant-prefix}-pagination"; +@pagination-prefix-cls: ~'@{ant-prefix}-pagination'; .@{pagination-prefix-cls} { .reset-component; @@ -15,7 +15,7 @@ } &:after { - content: " "; + content: ' '; display: block; height: 0; clear: both; @@ -57,7 +57,7 @@ &:focus, &:hover { - transition: all .3s; + transition: all 0.3s; border-color: @primary-color; a { color: @primary-color; @@ -95,7 +95,7 @@ color: @primary-color; letter-spacing: -1px; opacity: 0; - transition: all .2s; + transition: all 0.2s; &-svg { top: 0; right: 0; @@ -112,7 +112,7 @@ color: @disabled-color; text-align: center; opacity: 1; - transition: all .2s; + transition: all 0.2s; top: 0; right: 0; bottom: 0; @@ -150,7 +150,7 @@ height: @pagination-item-size; line-height: @pagination-item-size; text-align: center; - transition: all .3s; + transition: all 0.3s; display: inline-block; vertical-align: middle; } @@ -174,7 +174,7 @@ border-radius: @border-radius-base; outline: none; display: block; - transition: all .3s; + transition: all 0.3s; font-size: 12px; height: 100%; text-align: center; @@ -260,7 +260,7 @@ padding: 0 6px; height: 100%; text-align: center; - transition: border-color .3s; + transition: border-color 0.3s; &:hover { border-color: @primary-color; diff --git a/components/popover/style/index.less b/components/popover/style/index.less index 4860be35d..d535f0c62 100644 --- a/components/popover/style/index.less +++ b/components/popover/style/index.less @@ -1,7 +1,7 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; -@popover-prefix-cls: ~"@{ant-prefix}-popover"; +@popover-prefix-cls: ~'@{ant-prefix}-popover'; .@{popover-prefix-cls} { .reset-component; @@ -16,7 +16,7 @@ text-align: left; &:after { - content: ""; + content: ''; position: absolute; background: rgba(255, 255, 255, 0.01); } @@ -101,6 +101,7 @@ &-arrow { background: @popover-bg; + background-color: inherit; width: sqrt(@popover-arrow-width * @popover-arrow-width * 2); height: sqrt(@popover-arrow-width * @popover-arrow-width * 2); transform: rotate(45deg); @@ -111,70 +112,70 @@ } &-placement-top > &-content > &-arrow, - &-placement-topLeft > &-content > &-arrow, - &-placement-topRight > &-content > &-arrow { + &-placement-topLeft > &-content > &-arrow, + &-placement-topRight > &-content > &-arrow { bottom: @popover-distance - @popover-arrow-width + 1.5px; box-shadow: 3px 3px 7px rgba(0, 0, 0, 0.07); } - &-placement-top > &-content > &-arrow { + &-placement-top > &-content > &-arrow { left: 50%; transform: translateX(-50%) rotate(45deg); } - &-placement-topLeft > &-content > &-arrow { + &-placement-topLeft > &-content > &-arrow { left: 16px; } - &-placement-topRight > &-content > &-arrow { + &-placement-topRight > &-content > &-arrow { right: 16px; } - &-placement-right > &-content > &-arrow, - &-placement-rightTop > &-content > &-arrow, - &-placement-rightBottom > &-content > &-arrow { + &-placement-right > &-content > &-arrow, + &-placement-rightTop > &-content > &-arrow, + &-placement-rightBottom > &-content > &-arrow { left: @popover-distance - @popover-arrow-width + 2px; box-shadow: -3px 3px 7px rgba(0, 0, 0, 0.07); } - &-placement-right > &-content > &-arrow { + &-placement-right > &-content > &-arrow { top: 50%; transform: translateY(-50%) rotate(45deg); } - &-placement-rightTop > &-content > &-arrow { + &-placement-rightTop > &-content > &-arrow { top: 12px; } - &-placement-rightBottom > &-content > &-arrow { + &-placement-rightBottom > &-content > &-arrow { bottom: 12px; } - &-placement-bottom > &-content > &-arrow, - &-placement-bottomLeft > &-content > &-arrow, - &-placement-bottomRight > &-content > &-arrow { + &-placement-bottom > &-content > &-arrow, + &-placement-bottomLeft > &-content > &-arrow, + &-placement-bottomRight > &-content > &-arrow { top: @popover-distance - @popover-arrow-width + 2px; box-shadow: -2px -2px 5px rgba(0, 0, 0, 0.06); } - &-placement-bottom > &-content > &-arrow { + &-placement-bottom > &-content > &-arrow { left: 50%; transform: translateX(-50%) rotate(45deg); } - &-placement-bottomLeft > &-content > &-arrow { + &-placement-bottomLeft > &-content > &-arrow { left: 16px; } - &-placement-bottomRight > &-content > &-arrow { + &-placement-bottomRight > &-content > &-arrow { right: 16px; } - &-placement-left > &-content > &-arrow, - &-placement-leftTop > &-content > &-arrow, - &-placement-leftBottom > &-content > &-arrow { + &-placement-left > &-content > &-arrow, + &-placement-leftTop > &-content > &-arrow, + &-placement-leftBottom > &-content > &-arrow { right: @popover-distance - @popover-arrow-width + 2px; box-shadow: 3px -3px 7px rgba(0, 0, 0, 0.07); } - &-placement-left > &-content > &-arrow { + &-placement-left > &-content > &-arrow { top: 50%; transform: translateY(-50%) rotate(45deg); } - &-placement-leftTop > &-content > &-arrow { + &-placement-leftTop > &-content > &-arrow { top: 12px; } - &-placement-leftBottom > &-content > &-arrow { + &-placement-leftBottom > &-content > &-arrow { bottom: 12px; } } diff --git a/components/progress/__tests__/__snapshots__/index.test.js.snap b/components/progress/__tests__/__snapshots__/index.test.js.snap index 6a0523a9d..5e9cac813 100644 --- a/components/progress/__tests__/__snapshots__/index.test.js.snap +++ b/components/progress/__tests__/__snapshots__/index.test.js.snap @@ -51,6 +51,18 @@ exports[`Progress render negetive successPercent 2`] = `
  • `; +exports[`Progress render normal progress 1`] = ` +
    +
    +
    +
    +
    +
    +
    0% +
    +
    +`; + exports[`Progress render out-of-range progress 1`] = `
    diff --git a/components/progress/__tests__/index.test.js b/components/progress/__tests__/index.test.js index 062b470ea..9237c7651 100644 --- a/components/progress/__tests__/index.test.js +++ b/components/progress/__tests__/index.test.js @@ -98,4 +98,9 @@ describe('Progress', () => { expect(wrapper.html()).toMatchSnapshot() }) }) + + it('render normal progress', () => { + const wrapper = mount(Progress, { propsData: { status: 'normal' }}) + expect(wrapper.html()).toMatchSnapshot() + }) }) diff --git a/components/progress/style/index.less b/components/progress/style/index.less index 91a873ce1..7ba6036f0 100644 --- a/components/progress/style/index.less +++ b/components/progress/style/index.less @@ -1,7 +1,7 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; -@progress-prefix-cls: ~"@{ant-prefix}-progress"; +@progress-prefix-cls: ~'@{ant-prefix}-progress'; .@{progress-prefix-cls} { .reset-component; @@ -24,8 +24,8 @@ margin-right: 0; padding-right: 0; .@{progress-prefix-cls}-show-info & { - padding-right: ~"calc(2em + 8px)"; - margin-right: ~"calc(-2em - 8px)"; + padding-right: ~'calc(2em + 8px)'; + margin-right: ~'calc(-2em - 8px)'; } } @@ -44,13 +44,13 @@ &-circle-path { stroke: @progress-default-color; - animation: ~"@{ant-prefix}-progress-appear" .3s; + animation: ~'@{ant-prefix}-progress-appear' 0.3s; } &-success-bg, &-bg { background-color: @progress-default-color; - transition: all .4s @ease-out-circ 0s; + transition: all 0.4s @ease-out-circ 0s; position: relative; } @@ -79,7 +79,7 @@ &-status-active { .@{progress-prefix-cls}-bg:before { - content: ""; + content: ''; opacity: 0; position: absolute; top: 0; @@ -88,7 +88,7 @@ bottom: 0; background: @component-background; border-radius: 10px; - animation: ~"@{ant-prefix}-progress-active" 2.4s @ease-out-quint infinite; + animation: ~'@{ant-prefix}-progress-active' 2.4s @ease-out-quint infinite; } } diff --git a/components/radio/style/index.less b/components/radio/style/index.less index b85768576..54f36fbae 100644 --- a/components/radio/style/index.less +++ b/components/radio/style/index.less @@ -1,10 +1,10 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; -@radio-prefix-cls: ~"@{ant-prefix}-radio"; -@radio-group-prefix-cls: ~"@{radio-prefix-cls}-group"; -@radio-inner-prefix-cls: ~"@{radio-prefix-cls}-inner"; -@radio-duration: .3s; +@radio-prefix-cls: ~'@{ant-prefix}-radio'; +@radio-group-prefix-cls: ~'@{radio-prefix-cls}-group'; +@radio-inner-prefix-cls: ~'@{radio-prefix-cls}-inner'; +@radio-duration: 0.3s; .@{radio-group-prefix-cls} { .reset-component; @@ -46,7 +46,7 @@ height: 100%; border-radius: 50%; border: 1px solid @radio-dot-color; - content: ""; + content: ''; animation: antRadioEffect 0.36s ease-in-out; animation-fill-mode: both; visibility: hidden; @@ -105,7 +105,7 @@ .@{radio-inner-prefix-cls} { border-color: @radio-dot-color; &:after { - transform: scale(.875); + transform: scale(0.875); opacity: 1; transition: all @radio-duration @ease-in-out-circ; } @@ -116,6 +116,7 @@ .@{radio-inner-prefix-cls} { border-color: @border-color-base !important; background-color: @input-disabled-bg; + cursor: not-allowed; &:after { background-color: #ccc; } @@ -178,7 +179,7 @@ span.@{radio-prefix-cls} + * { &:not(:first-child) { &::before { - content: ""; + content: ''; display: block; top: 0; left: -1px; @@ -208,8 +209,8 @@ span.@{radio-prefix-cls} + * { } .@{radio-prefix-cls}-inner, - input[type="checkbox"], - input[type="radio"] { + input[type='checkbox'], + input[type='radio'] { opacity: 0; width: 0; height: 0; @@ -296,7 +297,7 @@ span.@{radio-prefix-cls} + * { } // Firefox hack -@supports (-moz-appearance:meterbar) and (background-blend-mode:difference,normal) { +@supports (-moz-appearance: meterbar) and (background-blend-mode: difference, normal) { .@{radio-prefix-cls} { vertical-align: text-bottom; } diff --git a/components/rate/style/index.less b/components/rate/style/index.less index 111bc6dd8..aa64b5888 100644 --- a/components/rate/style/index.less +++ b/components/rate/style/index.less @@ -1,7 +1,7 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; -@rate-prefix-cls: ~"@{ant-prefix}-rate"; +@rate-prefix-cls: ~'@{ant-prefix}-rate'; .@{rate-prefix-cls} { .reset-component; @@ -27,7 +27,7 @@ display: inline-block; margin-right: 8px; position: relative; - transition: all .3s; + transition: all 0.3s; color: inherit; cursor: pointer; @@ -38,7 +38,7 @@ &-first, &-second { user-select: none; - transition: all .3s; + transition: all 0.3s; color: @rate-star-bg; .@{iconfont-css-prefix} { vertical-align: middle; diff --git a/components/select/__tests__/__snapshots__/demo.test.js.snap b/components/select/__tests__/__snapshots__/demo.test.js.snap index 03b6f0fd4..66ca4b97d 100644 --- a/components/select/__tests__/__snapshots__/demo.test.js.snap +++ b/components/select/__tests__/__snapshots__/demo.test.js.snap @@ -2,7 +2,7 @@ exports[`renders ./components/select/demo/automatic-tokenization.md correctly 1`] = `
    -
    +
    +
    @@ -54,24 +86,24 @@ exports[`renders ./components/select/demo/coordinate.md correctly 1`] = ` exports[`renders ./components/select/demo/label-in-value.md correctly 1`] = `
    -
    +
    Lucy (101)
    -
    +
    `; exports[`renders ./components/select/demo/multiple.md correctly 1`] = `
    -
    +
    - +
    -
  • +
  • -
  • +
  • -

    -
    +
    - +
    - -
    +``` + diff --git a/components/select/demo/hide-selected.md b/components/select/demo/hide-selected.md new file mode 100644 index 000000000..ecfdeecb9 --- /dev/null +++ b/components/select/demo/hide-selected.md @@ -0,0 +1,47 @@ + + +#### 隐藏已选择选项 +隐藏下拉列表中已选择的选项。 + + + +#### Hide Already Selected +Hide already selected options in the dropdown. + + +```html + + +``` + diff --git a/components/select/demo/index.vue b/components/select/demo/index.vue index 7245cfaaa..ba3522329 100644 --- a/components/select/demo/index.vue +++ b/components/select/demo/index.vue @@ -11,6 +11,8 @@ import SearchBox from './search-box' import Search from './search' import SelectUsers from './select-users' import Suffix from './suffix' +import HideSelected from './hide-selected' +import CustomDropdownMenu from './custom-dropdown-menu' import CN from '../index.zh-CN.md' import US from '../index.en-US.md' @@ -50,6 +52,8 @@ export default { + + diff --git a/components/select/index.en-US.md b/components/select/index.en-US.md index f61812b30..e46dbbf6a 100644 --- a/components/select/index.en-US.md +++ b/components/select/index.en-US.md @@ -19,6 +19,7 @@ | disabled | Whether disabled select | boolean | false | | dropdownClassName | className of dropdown menu | string | - | | dropdownMatchSelectWidth | Whether dropdown's width is same with select. | boolean | true | +| dropdownRender | Customize dropdown content | (menuNode: VNode, props) => VNode | - | | dropdownStyle | style of dropdown menu | object | - | | filterOption | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns `true`, the option will be included in the filtered set; Otherwise, it will be excluded. | boolean or function(inputValue, option) | true | | firstActiveValue | Value of action option by default | string\|string\[] | - | @@ -34,12 +35,16 @@ | showSearch | Whether show search input in single mode. | boolean | false | | showArrow | Whether to show the drop-down arrow | boolean | true | | size | Size of Select input. `default` `large` `small` | string | default | -| suffixIcon | The custom suffix icon | string \| VNode \| slot | - | +| suffixIcon | The custom suffix icon | VNode \| slot | - | +| removeIcon | The custom remove icon | VNode \| slot | - | +| clearIcon | The custom clear icon | VNode \| slot | - | +| menuItemSelectedIcon | The custom menuItemSelected icon | VNode \| slot | - | | tokenSeparators | Separator used to tokenize on tag/multiple mode | string\[] | | | value(v-model) | Current selected option. | string\|number\|string\[]\|number\[] | - | | options | Data of the selectOption, manual construction work is no longer needed if this property has been set | array<{value, label, [disabled, key, title]}> | \[] | | defaultOpen | Initial open state of dropdown | boolean | - | | open | Controlled open state of dropdown | boolean | - | +| loading | indicate loading state | Boolean | false | ### events | Events Name | Description | Arguments | diff --git a/components/select/index.jsx b/components/select/index.jsx index 7926eec9f..a1306424b 100644 --- a/components/select/index.jsx +++ b/components/select/index.jsx @@ -12,6 +12,10 @@ import { cloneElement } from '../_util/vnode' const AbstractSelectProps = () => ({ prefixCls: PropTypes.string, size: PropTypes.oneOf(['small', 'large', 'default']), + showAction: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.arrayOf(String), + ]), notFoundContent: PropTypes.any, transitionName: PropTypes.string, choiceTransitionName: PropTypes.string, @@ -37,6 +41,8 @@ const AbstractSelectProps = () => ({ open: PropTypes.bool, defaultOpen: PropTypes.bool, autoClearSearchValue: PropTypes.bool, + dropdownRender: PropTypes.func, + loading: PropTypes.bool, }) const Value = PropTypes.shape({ key: PropTypes.string, @@ -71,6 +77,9 @@ const SelectProps = { getInputElement: PropTypes.func, options: PropTypes.array, suffixIcon: PropTypes.any, + removeIcon: PropTypes.any, + clearIcon: PropTypes.any, + menuItemSelectedIcon: PropTypes.any, } const SelectPropTypes = { @@ -107,6 +116,9 @@ const Select = { prop: 'value', event: 'change', }, + inject: { + configProvider: { default: {}}, + }, created () { warning( this.$props.mode !== 'combobox', @@ -134,17 +146,39 @@ const Select = { const { mode } = this return mode === 'combobox' || mode === SECRET_COMBOBOX_MODE_DO_NOT_USE }, + + renderSuffixIcon () { + const { prefixCls, loading } = this.$props + let suffixIcon = getComponentFromProp(this, 'suffixIcon') + suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon + if (suffixIcon) { + return isValidElement(suffixIcon) + ? cloneElement(suffixIcon, { class: `${prefixCls}-arrow-icon` }) + : suffixIcon + } + if (loading) { + return + } + return + }, + renderSelect (locale) { const { prefixCls, size, mode, options, + getPopupContainer, ...restProps } = getOptionProps(this) - let suffixIcon = getComponentFromProp(this, 'suffixIcon') - suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon - const rest = omit(restProps, ['inputIcon', 'removeIcon', 'clearIcon', 'suffixIcon']) + const { getPopupContainer: getContextPopupContainer } = this.configProvider + let removeIcon = getComponentFromProp(this, 'removeIcon') + removeIcon = Array.isArray(removeIcon) ? removeIcon[0] : removeIcon + let clearIcon = getComponentFromProp(this, 'clearIcon') + clearIcon = Array.isArray(clearIcon) ? clearIcon[0] : clearIcon + let menuItemSelectedIcon = getComponentFromProp(this, 'menuItemSelectedIcon') + menuItemSelectedIcon = Array.isArray(menuItemSelectedIcon) ? menuItemSelectedIcon[0] : menuItemSelectedIcon + const rest = omit(restProps, ['inputIcon', 'removeIcon', 'clearIcon', 'suffixIcon', 'menuItemSelectedIcon']) const cls = { [`${prefixCls}-lg`]: size === 'large', @@ -162,31 +196,27 @@ const Select = { tags: mode === 'tags', combobox: this.isCombobox(), } + const finalRemoveIcon = (removeIcon && + (isValidElement(removeIcon) + ? cloneElement(removeIcon, { class: `${prefixCls}-remove-icon` }) + : removeIcon)) || - const inputIcon = suffixIcon && ( - isValidElement(suffixIcon) - ? cloneElement(suffixIcon) : suffixIcon) || ( - - ) + const finalClearIcon = (clearIcon && + (isValidElement(clearIcon) + ? cloneElement(clearIcon, { class: `${prefixCls}-clear-icon` }) + : clearIcon)) || () - const removeIcon = ( - - ) - - const clearIcon = ( - - ) - - const menuItemSelectedIcon = ( - - ) + const finalMenuItemSelectedIcon = (menuItemSelectedIcon && + (isValidElement(menuItemSelectedIcon) + ? cloneElement(menuItemSelectedIcon, { class: `${prefixCls}-selected-icon` }) + : menuItemSelectedIcon)) || const selectProps = { props: { - inputIcon, - removeIcon, - clearIcon, - menuItemSelectedIcon, + inputIcon: this.renderSuffixIcon(), + removeIcon: finalRemoveIcon, + clearIcon: finalClearIcon, + menuItemSelectedIcon: finalMenuItemSelectedIcon, ...rest, ...modeConfig, prefixCls, @@ -201,6 +231,8 @@ const Select = { }) : filterEmpty(this.$slots.default), __propsSymbol__: Symbol(), + dropdownRender: getComponentFromProp(this, 'dropdownRender', {}, false), + getPopupContainer: getPopupContainer || getContextPopupContainer, }, on: this.$listeners, class: cls, diff --git a/components/select/index.zh-CN.md b/components/select/index.zh-CN.md index ef25c7211..fea1f66df 100644 --- a/components/select/index.zh-CN.md +++ b/components/select/index.zh-CN.md @@ -18,6 +18,7 @@ | disabled | 是否禁用 | boolean | false | | dropdownClassName | 下拉菜单的 className 属性 | string | - | | dropdownMatchSelectWidth | 下拉菜单和选择器同宽 | boolean | true | +| dropdownRender | 自定义下拉框内容 | (menuNode: VNode, props) => VNode | - | | dropdownStyle | 下拉菜单的 style 属性 | object | - | | filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 `true`,反之则返回 `false`。 | boolean or function(inputValue, option) | true | | firstActiveValue | 默认高亮的选项 | string\|string\[] | - | @@ -33,7 +34,10 @@ | showSearch | 使单选模式可搜索 | boolean | false | | showArrow | 是否显示下拉小箭头 | boolean | true | | size | 选择框大小,可选 `large` `small` | string | default | -| suffixIcon | 自定义的选择框后缀图标 | string \| VNode \| slot | - | +| suffixIcon | 自定义的选择框后缀图标 | VNode \| slot | - | +| removeIcon | 自定义的多选框清除图标 | VNode \| slot | - | +| clearIcon | 自定义的多选框清空图标 | VNode \| slot | - | +| menuItemSelectedIcon | 自定义当前选中的条目图标 | VNode \| slot | - | | tokenSeparators | 在 tags 和 multiple 模式下自动分词的分隔符 | string\[] | | | value(v-model) | 指定当前选中的条目 | string\|string\[]\|number\|number\[] | - | | options | options 数据,如果设置则不需要手动构造 selectOption 节点 | array<{value, label, [disabled, key, title]}> | \[] | diff --git a/components/select/style/index.less b/components/select/style/index.less index 829b57bd3..a54939984 100644 --- a/components/select/style/index.less +++ b/components/select/style/index.less @@ -1,8 +1,8 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; -@import "../../input/style/mixin"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; +@import '../../input/style/mixin'; -@select-prefix-cls: ~"@{ant-prefix}-select"; +@select-prefix-cls: ~'@{ant-prefix}-select'; .selection__clear() { display: inline-block; @@ -64,7 +64,7 @@ font-size: @font-size-sm; & &-icon svg { - transition: transform .3s; + transition: transform 0.3s; } } @@ -81,7 +81,7 @@ // strange align fix for chrome but works // https://gw.alipayobjects.com/zos/rmsportal/VFTfKXJuogBAXcvfAUWJ.gif border-top-width: @border-width-base + 0.02px; - transition: all .3s @ease-in-out; + transition: all 0.3s @ease-in-out; &:hover { .hover; @@ -229,7 +229,8 @@ } &-selection__placeholder, - &-search__field__placeholder { // for TreeSelect compatibility + &-search__field__placeholder { + // for TreeSelect compatibility position: absolute; top: 50%; left: 0; @@ -313,7 +314,8 @@ } > ul > li, - .@{select-prefix-cls}-selection__rendered > ul > li { // for tree-select + .@{select-prefix-cls}-selection__rendered > ul > li { + // for tree-select margin-top: 3px; height: @input-height-base - 8px; line-height: @input-height-base - 8px - 2px; @@ -330,7 +332,7 @@ max-width: 99%; position: relative; overflow: hidden; - transition: padding .3s @ease-in-out; + transition: padding 0.3s @ease-in-out; padding: 0 20px 0 10px; &__disabled { padding: 0 10px; @@ -343,7 +345,7 @@ overflow: hidden; text-overflow: ellipsis; max-width: 100%; - transition: margin .3s @ease-in-out; + transition: margin 0.3s @ease-in-out; } .@{select-prefix-cls}-selection__choice__remove { @@ -353,7 +355,7 @@ cursor: pointer; display: inline-block; font-weight: bold; - transition: all .3s; + transition: all 0.3s; font-size: @font-size-sm; .iconfont-size-under-12px(10px); position: absolute; @@ -405,7 +407,7 @@ height: 100%; position: relative; z-index: 1; - transition: all .3s @ease-in-out, height 0s; + transition: all 0.3s @ease-in-out, height 0s; box-shadow: none; } } diff --git a/components/skeleton/style/index.less b/components/skeleton/style/index.less index 1d5054c45..fe4c2d295 100644 --- a/components/skeleton/style/index.less +++ b/components/skeleton/style/index.less @@ -1,10 +1,10 @@ -@import "../../style/themes/default"; -@import "../../style/mixins/index"; +@import '../../style/themes/default'; +@import '../../style/mixins/index'; -@skeleton-prefix-cls: ~"@{ant-prefix}-skeleton"; -@skeleton-avatar-prefix-cls: ~"@{skeleton-prefix-cls}-avatar"; -@skeleton-title-prefix-cls: ~"@{skeleton-prefix-cls}-title"; -@skeleton-paragraph-prefix-cls: ~"@{skeleton-prefix-cls}-paragraph"; +@skeleton-prefix-cls: ~'@{ant-prefix}-skeleton'; +@skeleton-avatar-prefix-cls: ~'@{skeleton-prefix-cls}-avatar'; +@skeleton-title-prefix-cls: ~'@{skeleton-prefix-cls}-title'; +@skeleton-paragraph-prefix-cls: ~'@{skeleton-prefix-cls}-paragraph'; @skeleton-to-color: shade(@skeleton-color, 5%); @@ -108,8 +108,13 @@ } .skeleton-color() { - background: linear-gradient(90deg, @skeleton-color 25%, @skeleton-to-color 37%, @skeleton-color 63%); - animation: ~"@{skeleton-prefix-cls}-loading" 1.4s ease infinite; + background: linear-gradient( + 90deg, + @skeleton-color 25%, + @skeleton-to-color 37%, + @skeleton-color 63% + ); + animation: ~'@{skeleton-prefix-cls}-loading' 1.4s ease infinite; background-size: 400% 100%; } diff --git a/components/slider/__tests__/__snapshots__/demo.test.js.snap b/components/slider/__tests__/__snapshots__/demo.test.js.snap index ba8b04785..370f919f3 100644 --- a/components/slider/__tests__/__snapshots__/demo.test.js.snap +++ b/components/slider/__tests__/__snapshots__/demo.test.js.snap @@ -2,14 +2,14 @@ exports[`renders ./components/slider/demo/basic.md correctly 1`] = `
    -
    +
    -
    +
    @@ -23,14 +23,14 @@ exports[`renders ./components/slider/demo/basic.md correctly 1`] = ` exports[`renders ./components/slider/demo/event.md correctly 1`] = `
    -
    +
    -
    +
    @@ -45,14 +45,14 @@ exports[`renders ./components/slider/demo/icon-slider.md correctly 1`] = `
    -
    +
    -
    +
    @@ -68,7 +68,7 @@ exports[`renders ./components/slider/demo/input-number.md correctly 1`] = `
    -
    +
    @@ -85,7 +85,7 @@ exports[`renders ./components/slider/demo/input-number.md correctly 1`] = `
    -
    +
    @@ -106,14 +106,14 @@ exports[`renders ./components/slider/demo/input-number.md correctly 1`] = ` exports[`renders ./components/slider/demo/mark.md correctly 1`] = `

    included=true

    -
    +
    0°C26°C37°C100°C
    -
    +
    @@ -122,7 +122,7 @@ exports[`renders ./components/slider/demo/mark.md correctly 1`] = `
    0°C26°C37°C100°C

    included=false

    -
    +
    @@ -130,7 +130,7 @@ exports[`renders ./components/slider/demo/mark.md correctly 1`] = `
    0°C26°C37°C100°C

    marks & step

    -
    +
    @@ -138,7 +138,7 @@ exports[`renders ./components/slider/demo/mark.md correctly 1`] = `
    0°C26°C37°C100°C

    step=null

    -
    +
    @@ -148,16 +148,26 @@ exports[`renders ./components/slider/demo/mark.md correctly 1`] = `
    `; +exports[`renders ./components/slider/demo/show-tooltip.md correctly 1`] = ` +
    +
    +
    +
    +
    +
    +
    +`; + exports[`renders ./components/slider/demo/tip-formatter.md correctly 1`] = `
    -
    +
    -
    +
    @@ -170,7 +180,7 @@ exports[`renders ./components/slider/demo/tip-formatter.md correctly 1`] = ` exports[`renders ./components/slider/demo/vertical.md correctly 1`] = `
    -
    +
    @@ -179,7 +189,7 @@ exports[`renders ./components/slider/demo/vertical.md correctly 1`] = `
    -
    +
    @@ -189,7 +199,7 @@ exports[`renders ./components/slider/demo/vertical.md correctly 1`] = `
    -
    +
    diff --git a/components/slider/__tests__/demo.test.js b/components/slider/__tests__/demo.test.js index 808e84aef..263263921 100644 --- a/components/slider/__tests__/demo.test.js +++ b/components/slider/__tests__/demo.test.js @@ -1,3 +1,3 @@ import demoTest from '../../../tests/shared/demoTest' -demoTest('slider') +demoTest('slider', { skip: process.env.LIB_DIR === 'dist' && ['show-tooltip.md'] }) diff --git a/components/slider/demo/basic.md b/components/slider/demo/basic.md index ef36d92d6..4d3302e6a 100644 --- a/components/slider/demo/basic.md +++ b/components/slider/demo/basic.md @@ -11,7 +11,7 @@ Basic slider. When `range` is `true`, display as dual thumb mode. When `disable` ```html