diff --git a/.eslintrc b/.eslintrc index fbc3d1c14..6d1be14cc 100644 --- a/.eslintrc +++ b/.eslintrc @@ -14,7 +14,8 @@ "plugins": ["markdown"], "overrides": [ { - "files": ["**/demo/**"], + "files": ["**/demo/*.md"], + "processor": "markdown/markdown", "rules": { "no-console": "off" } @@ -33,6 +34,7 @@ "vue/require-prop-types": "off", "vue/require-default-prop": "off", "vue/no-reserved-keys": "off", + "vue/comment-directive": "off", "vue/prop-name-casing": "off", "vue/max-attributes-per-line": [ 2, diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 5deffe7f7..6706e4c0c 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest steps: - name: checkout - uses: actions/checkout@master + uses: actions/checkout@v2 - name: cache package-lock.json uses: actions/cache@v1 @@ -40,10 +40,16 @@ jobs: runs-on: ubuntu-latest steps: - name: checkout - uses: actions/checkout@master + uses: actions/checkout@v2 with: token: ${{ secrets.ACCESS_TOKEN }} - submodules: true + + - name: Checkout submodules + uses: actions/checkout@v2 + with: + repository: tangjinzhou/antdv-demo + token: ${{ secrets.ACCESS_TOKEN }} + path: antdv-demo - name: restore cache from package-lock.json uses: actions/cache@v1 @@ -66,6 +72,5 @@ jobs: uses: codecov/codecov-action@v1 with: token: ${{ secrets.CODECOV_TOKEN }} - - needs: setup + needs: setup diff --git a/BACKERS.md b/BACKERS.md index 23adcda30..28457d76a 100644 --- a/BACKERS.md +++ b/BACKERS.md @@ -38,6 +38,12 @@

+

Patreon

+ +

+ +

+

支付宝/微信

### 使用支付宝/微信的赞助的用户,如需要添加名单,赞助后可发 github 账号到邮箱(antdv@foxmail.com) diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index 59ec150d5..831613349 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -1,4 +1,4 @@ -# Change Log +# Change Log (The following content is translated by Google) `ant-design-vue` strictly follows [Semantic Versioning 2.0.0](http://semver.org/). @@ -10,6 +10,67 @@ --- +## 1.6.1 + +`2020-05-25` + +- 🐞 Fix the problem of filling the current time when DatePicker blur [#2246](https://github.com/vueComponent/ant-design-vue/issues/2246) +- 🐞 Fix Drawer error when destroying [#2254](https://github.com/vueComponent/ant-design-vue/issues/2254) +- 🐞 Fix Tabs cannot remove tabs with 0 as key [55bbf9](https://github.com/vueComponent/ant-design-vue/commit/55bbf940401cf2a67114102da1c035abc4152f06) +- 🐞 Fix Menu trigger twice click event [#2266](https://github.com/vueComponent/ant-design-vue/issues/2266) +- 🐞 Fix Menu active class name is not added [ffc002](https://github.com/vueComponent/ant-design-vue/commit/ffc002f09454a56b531aeb08530303d566cf24f2) +- 🌟 TreeSelect add custom data field function [#2253](https://github.com/vueComponent/ant-design-vue/issues/2253) +- 🌟 Modal added dialogStyle and dialogClass instead of style and class before refactoring [#2285](https://github.com/vueComponent/ant-design-vue/issues/2285) +- 🐞 Fix Table sorting trigger infinite update issue [#2270](https://github.com/vueComponent/ant-design-vue/issues/2270) + +## 1.6.0 + +`2020-05-15` + +- 🌟 Tootip supports custom components [741897](https://github.com/vueComponent/ant-design-vue/commit/741897be6742c752f0b0d29481add702ee7e7fb0) +- 🐞 Refactor Modal's underlying Portal components to solve the problem of delayed content update in Modal [#2244](https://github.com/vueComponent/ant-design-vue/issues/2244) +- 🐞 Fix Select option focus border style in Input.Group [#2224](https://github.com/vueComponent/ant-design-vue/pull/2224) +- 🐞 Fix Cascader option icon color when disabled [#2223](https://github.com/vueComponent/ant-design-vue/pull/2223) +- 🐞 Fix DatePicker color when separator is disabled [#2222](https://github.com/vueComponent/ant-design-vue/pull/2222) +- 🐞 Fix Carousel keyboard switch to Radio / Checkbox on inactive slide. +- 🐞 Fix the problem that Table filter menu is not displayed when less version is `2.x`. [#23272](https://github.com/ant-design/ant-design/pull/23272) +- 🐞 Fix the failure of Table `column.filtered`. +- 🐞 Fix the style problem of Input in Safari browser in Select `multiple` mode. [#22586](https://github.com/ant-design/ant-design/pull/22586) +- 🐞 Fix the problem that Descriptions can not adapt in small size. [#22407](https://github.com/ant-design/ant-design/pull/22407) + +## 1.5.6 + +`2020-05-09` + +- 🐞 Fix the problem of missing css, min.js and other files in the dist folder + +## 1.5.5 + +`2020-05-08` + +- 🐞 Fix `Tabs` not showing issue under safari 13 [#2199](https://github.com/vueComponent/ant-design-vue/issues/2199) +- 🐞 Fix the first input failure of `Input` under FireFox [#2151](https://github.com/vueComponent/ant-design-vue/issues/2151) +- 🐞 Fix `Input` cursor shift issue in Modal component [#2207](https://github.com/vueComponent/ant-design-vue/issues/2207) + +## 1.5.4 + +`2020-04-30` + +- 🌟 `DatePicker` supports the align attribute and sets the popup position [#1112f2](https://github.com/vueComponent/ant-design-vue/commit/1112f2f791fd64866284ec82def90baefe81e798) +- 🌟 `DatePicker` supports inputReadOnly attribute [#138eae](https://github.com/vueComponent/ant-design-vue/commit/138eae594dd440ce815e45d811a0778cb3e7583f) +- 🌟 `DatePicker` `TimePicker` `Calendar` supports string-type binding values ​​[#718](https://github.com/vueComponent/ant-design-vue/issues/718) +- 🌟 `Table` `ConfigProvider` adds `transformCellText` for transforming table rendering values, such as processing of empty data [#2109](https://github.com/vueComponent/ant-design-vue/issues/2109) +- 🌟 `FormModel` added validateMessages attribute [#2130](https://github.com/vueComponent/ant-design-vue/issues/2130) +- 🌟 Optimize pop-up window animation effect [#bf52f73](https://github.com/vueComponent/ant-design-vue/commit/bf52f73c5c2f8d05981e426b41a5f46d66e096db) +- 🐞 Fix the `tabBarGutter` attribute of the `Tabs` component does not take effect [#2083](https://github.com/vueComponent/ant-design-vue/issues/2083) +- 🐞 Fix renderTabBar of `Tabs` component not working [#2157](https://github.com/vueComponent/ant-design-vue/issues/2157) +- 🌟 `Tabs` component supports number 0 as key [#2167](https://github.com/vueComponent/ant-design-vue/issues/2167) +- 🐞 Fix the style of the Input.Search component is misaligned [#2077](https://github.com/vueComponent/ant-design-vue/issues/2077) +- 🐞 Fix the style misalignment of `Slider` component [#2097](https://github.com/vueComponent/ant-design-vue/issues/2097) +- 🐞 Fix `Tree.TreeNode` customTitle scope slot can not get selected status issue [#2006](https://github.com/vueComponent/ant-design-vue/issues/2006) +- 🐞 Fix `SelectTree` showSearch error when reporting [#2082](https://github.com/vueComponent/ant-design-vue/issues/2082) +- 🐞 Fix the inconsistent position of original dots in `Badge` dot state [#2121](https://github.com/vueComponent/ant-design-vue/issues/2121) + ## 1.5.3 `2020-04-13` @@ -20,10 +81,10 @@ `2020-04-09` -- 🐞 Fix ts type of `FormModel` not introduced [# 1996](https://github.com/vueComponent/ant-design-vue/issues/1966) -- 🐞 Fix `DatePicker.WeekPicker` type file error [# 2044](https://github.com/vueComponent/ant-design-vue/issues/2044) -- 🐞 Fix "Tabs" tabClick event does not take effect [# 2030](https://github.com/vueComponent/ant-design-vue/issues/2030) -- 🐞 Fix `Table` resize error issue [# 2033](https://github.com/vueComponent/ant-design-vue/issues/2033) +- 🐞 Fix ts type of `FormModel` not introduced [#1996](https://github.com/vueComponent/ant-design-vue/issues/1966) +- 🐞 Fix `DatePicker.WeekPicker` type file error [#2044](https://github.com/vueComponent/ant-design-vue/issues/2044) +- 🐞 Fix "Tabs" tabClick event does not take effect [#2030](https://github.com/vueComponent/ant-design-vue/issues/2030) +- 🐞 Fix `Table` resize error issue [#2033](https://github.com/vueComponent/ant-design-vue/issues/2033) ## 1.5.1 @@ -172,7 +233,7 @@ `2019-11-27` -- 🌟 `getPopupContainer` of`ConfigProvider` Added popup context as the second parameter for uniform configuration of `getPopupContainer` in`Modal` [7a3c88] (https://github.com/vueComponent/ant-design -vue / commit / 7a3c88107598b4b1cf6842d3254b43dc26103c14) +- 🌟 `getPopupContainer` of`ConfigProvider` Added popup context as the second parameter for uniform configuration of `getPopupContainer` in`Modal` [7a3c88](https://github.com/vueComponent/ant-design -vue / commit / 7a3c88107598b4b1cf6842d3254b43dc26103c14) - 🐞 Fix `ConfigProvider` reporting error in Vue 2.5 [309baa](https://github.com/vueComponent/ant-design-vue/commit/309baa138a9c9a1885c17ef636c9132349024359) - 🐞 Fix `Menu` click event is triggered twice [#1450](https://github.com/vueComponent/ant-design-vue/issues/1427) - 🐞 Fix incorrect width of input box in `Select` [#1458](https://github.com/vueComponent/ant-design-vue/issues/1458) diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index 989ba5b92..d3ab13506 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -10,6 +10,67 @@ --- +## 1.6.1 + +`2020-05-25` + +- 🐞 修复 DatePicker blur 时填充当前时间的问题 [#2246](https://github.com/vueComponent/ant-design-vue/issues/2246) +- 🐞 修复 Drawer 销毁时报错问题 [#2254](https://github.com/vueComponent/ant-design-vue/issues/2254) +- 🐞 修复 Tabs 不能移除已 0 作为 key 的选项卡 [55bbf9](https://github.com/vueComponent/ant-design-vue/commit/55bbf940401cf2a67114102da1c035abc4152f06) +- 🐞 修复 Menu 触发两次 click 事件的问题 [#2266](https://github.com/vueComponent/ant-design-vue/issues/2266) +- 🐞 修复 Menu active 类名没有添加问题 [ffc002](https://github.com/vueComponent/ant-design-vue/commit/ffc002f09454a56b531aeb08530303d566cf24f2) +- 🌟 TreeSelect 添加自定义数据字段功能 [#2253](https://github.com/vueComponent/ant-design-vue/issues/2253) +- 🌟 Modal 新增 dialogStyle、dialogClass 代替重构前的 style、class [#2285](https://github.com/vueComponent/ant-design-vue/issues/2285) +- 🐞 修复 Table 排序触发无限更新问题 [#2270](https://github.com/vueComponent/ant-design-vue/issues/2270) + +## 1.6.0 + +`2020-05-15` + +- 🌟 Tootip 支持自定义组件 [741897](https://github.com/vueComponent/ant-design-vue/commit/741897be6742c752f0b0d29481add702ee7e7fb0) +- 🐞 重构 Modal、Drawer 底层 Portal 组件,解决 Modal、Drawer 内容更新延迟问题 [#2244](https://github.com/vueComponent/ant-design-vue/issues/2244) +- 🐞 修复 Input.Group 中 Select 选项 focus 边框样式 [#2224](https://github.com/vueComponent/ant-design-vue/pull/2224) +- 🐞 修复 Cascader 选项图标禁用时的颜色 [#2223](https://github.com/vueComponent/ant-design-vue/pull/2223) +- 🐞 修复 DatePicker 分隔符禁用时颜色 [#2222](https://github.com/vueComponent/ant-design-vue/pull/2222) +- 🐞 修复 Carousel 键盘切换到非活跃 slide 上的 Radio/Checkbox 的问题。 +- 🐞 修复 Table 筛选菜单在 less 版本为 `2.x` 时不显示的问题。[#23272](https://github.com/ant-design/ant-design/pull/23272) +- 🐞 修复 Table `column.filtered` 失效的问题。 +- 🐞 修复 Select `multiple` 模式下,Input 在 Safari 浏览器的样式问题。[#22586](https://github.com/ant-design/ant-design/pull/22586) +- 🐞 修复 Descriptions 在小尺寸下无法自适应的问题。[#22407](https://github.com/ant-design/ant-design/pull/22407) + +## 1.5.6 + +`2020-05-09` + +- 🐞 修复 dist 文件夹丢失 css、min.js 等文件问题 + +## 1.5.5 + +`2020-05-08` + +- 🐞 修复 `Tabs` 在 safari 13 下不展示问题 [#2199](https://github.com/vueComponent/ant-design-vue/issues/2199) +- 🐞 修复 `Input` 在 FireFox 下第一次输入失败问题 [#2151](https://github.com/vueComponent/ant-design-vue/issues/2151) +- 🐞 修复 `Input` 在 Modal 组件中光标移位问题 [#2207](https://github.com/vueComponent/ant-design-vue/issues/2207) + +## 1.5.4 + +`2020-04-30` + +- 🌟 `DatePicker` 支持 align 属性,设置弹窗位置 [#1112f2](https://github.com/vueComponent/ant-design-vue/commit/1112f2f791fd64866284ec82def90baefe81e798) +- 🌟 `DatePicker` 支持 inputReadOnly 属性 [#138eae](https://github.com/vueComponent/ant-design-vue/commit/138eae594dd440ce815e45d811a0778cb3e7583f) +- 🌟 `DatePicker` `TimePicker` `Calendar` 支持字符串类型的绑定值 [#718](https://github.com/vueComponent/ant-design-vue/issues/718) +- 🌟 `Table` `ConfigProvider` 新增 `transformCellText` 用于转换表格渲染值, 如对空数据的处理 [#2109](https://github.com/vueComponent/ant-design-vue/issues/2109) +- 🌟 `FormModel` 新增 validateMessages 属性 [#2130](https://github.com/vueComponent/ant-design-vue/issues/2130) +- 🌟 优化弹窗动画效果 [#bf52f73](https://github.com/vueComponent/ant-design-vue/commit/bf52f73c5c2f8d05981e426b41a5f46d66e096db) +- 🐞 修复 `Tabs` 组件的 `tabBarGutter` 属性不生效问题 [#2083](https://github.com/vueComponent/ant-design-vue/issues/2083) +- 🐞 修复 `Tabs` 组件的 renderTabBar 不生效问题 [#2157](https://github.com/vueComponent/ant-design-vue/issues/2157) +- 🌟 `Tabs` 组件支持数字 0 作为 key [#2167](https://github.com/vueComponent/ant-design-vue/issues/2167) +- 🐞 修复 `Input.Search` 组件的样式错位问题 [#2077](https://github.com/vueComponent/ant-design-vue/issues/2077) +- 🐞 修复 `Slider` 组件的样式错位问题 [#2097](https://github.com/vueComponent/ant-design-vue/issues/2097) +- 🐞 修复 `Tree.TreeNode` customTitle 作用域插槽无法获取 selected 状态问题 [#2006](https://github.com/vueComponent/ant-design-vue/issues/2006) +- 🐞 修复 `SelectTree` showSearch 时报错问题 [#2082](https://github.com/vueComponent/ant-design-vue/issues/2082) +- 🐞 修复 `Badge` dot 状态的原圆点位置不一致问题 [#2121](https://github.com/vueComponent/ant-design-vue/issues/2121) + ## 1.5.3 `2020-04-13` diff --git a/README-zh_CN.md b/README-zh_CN.md index d34e43ffc..97c1d56d7 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -107,4 +107,10 @@ Support us with a monthly donation and help us continue our activities. [[Become +## Patreon + +Support us with a monthly donation and help us continue our activities. [[Become a backer](https://www.patreon.com/tangjinzhou)] + + + ## [更多赞助者 (通过 Patreon、支付宝、微信、paypal 等等)](https://github.com/vueComponent/ant-design-vue/blob/master/BACKERS.md) diff --git a/README.md b/README.md index 85cf68919..00d9b8670 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,12 @@ Support us with a monthly donation and help us continue our activities. [[Become +## Patreon + +Support us with a monthly donation and help us continue our activities. [[Become a backer](https://www.patreon.com/tangjinzhou)] + + + ## [More Sponsor (From Patreon、alipay、wechat、paypal...)](https://github.com/vueComponent/ant-design-vue/blob/master/BACKERS.md) [![Let's fund issues in this repository](https://issuehunt.io/static/embed/issuehunt-button-v1.svg)](https://issuehunt.io/repos/104172832) diff --git a/antd-tools/getWebpackConfig.js b/antd-tools/getWebpackConfig.js index edcafe366..4d46ccc73 100644 --- a/antd-tools/getWebpackConfig.js +++ b/antd-tools/getWebpackConfig.js @@ -132,8 +132,10 @@ function getWebpackConfig(modules) { { loader: 'less-loader', options: { - sourceMap: true, - javascriptEnabled: true, + lessOptions: { + sourceMap: true, + javascriptEnabled: true, + }, }, }, ], diff --git a/antdv-demo b/antdv-demo index f9276815b..745711870 160000 --- a/antdv-demo +++ b/antdv-demo @@ -1 +1 @@ -Subproject commit f9276815b07efeec931404c2cad4e998eba7af14 +Subproject commit 7457118702fced496e8b1d251b1ea2c50cd5071a diff --git a/components/_util/BaseMixin.js b/components/_util/BaseMixin.js index d1e94aeda..629368e99 100644 --- a/components/_util/BaseMixin.js +++ b/components/_util/BaseMixin.js @@ -1,23 +1,20 @@ +import { getOptionProps } from './props-util'; + 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) - // }, - // }, - // }, methods: { - setState(state, callback) { - 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) || {}) - // } + setState(state = {}, callback) { + let newState = typeof state === 'function' ? state(this.$data, this.$props) : state; + if (this.getDerivedStateFromProps) { + const s = this.getDerivedStateFromProps(getOptionProps(this), { + ...this.$data, + ...newState, + }); + if (s === null) { + return; + } else { + newState = { ...newState, ...(s || {}) }; + } + } Object.assign(this.$data, newState); this.$forceUpdate(); this.$nextTick(() => { diff --git a/components/_util/Portal.js b/components/_util/Portal.js new file mode 100644 index 000000000..5e0fdf7cb --- /dev/null +++ b/components/_util/Portal.js @@ -0,0 +1,51 @@ +import PropTypes from './vue-types'; +import { cloneElement } from './vnode'; + +export default { + name: 'Portal', + props: { + getContainer: PropTypes.func.isRequired, + children: PropTypes.any.isRequired, + didUpdate: PropTypes.func, + }, + mounted() { + this.createContainer(); + }, + updated() { + const { didUpdate } = this.$props; + if (didUpdate) { + this.$nextTick(() => { + didUpdate(this.$props); + }); + } + }, + + beforeDestroy() { + this.removeContainer(); + }, + methods: { + createContainer() { + this._container = this.$props.getContainer(); + this.$forceUpdate(); + }, + removeContainer() { + if (this._container && this._container.parentNode) { + this._container.parentNode.removeChild(this._container); + } + }, + }, + + render() { + if (this._container) { + return cloneElement(this.$props.children, { + directives: [ + { + name: 'ant-portal', + value: this._container, + }, + ], + }); + } + return null; + }, +}; diff --git a/components/_util/PortalWrapper.js b/components/_util/PortalWrapper.js new file mode 100644 index 000000000..ab72d8083 --- /dev/null +++ b/components/_util/PortalWrapper.js @@ -0,0 +1,156 @@ +import PropTypes from './vue-types'; +import switchScrollingEffect from './switchScrollingEffect'; +import setStyle from './setStyle'; +import Portal from './Portal'; + +let openCount = 0; +const windowIsUndefined = !( + typeof window !== 'undefined' && + window.document && + window.document.createElement +); +// https://github.com/ant-design/ant-design/issues/19340 +// https://github.com/ant-design/ant-design/issues/19332 +let cacheOverflow = {}; + +export default { + name: 'PortalWrapper', + props: { + wrapperClassName: PropTypes.string, + forceRender: PropTypes.bool, + getContainer: PropTypes.any, + children: PropTypes.func, + visible: PropTypes.bool, + }, + data() { + const { visible } = this.$props; + openCount = visible ? openCount + 1 : openCount; + return {}; + }, + updated() { + this.setWrapperClassName(); + }, + watch: { + visible(val) { + openCount = val ? openCount + 1 : openCount - 1; + }, + getContainer(getContainer, prevGetContainer) { + const getContainerIsFunc = + typeof getContainer === 'function' && typeof prevGetContainer === 'function'; + if ( + getContainerIsFunc + ? getContainer.toString() !== prevGetContainer.toString() + : getContainer !== prevGetContainer + ) { + this.removeCurrentContainer(false); + } + }, + }, + beforeDestroy() { + const { visible } = this.$props; + // 离开时不会 render, 导到离开时数值不变,改用 func 。。 + openCount = visible && openCount ? openCount - 1 : openCount; + this.removeCurrentContainer(visible); + }, + methods: { + getParent() { + const { getContainer } = this.$props; + if (getContainer) { + if (typeof getContainer === 'string') { + return document.querySelectorAll(getContainer)[0]; + } + if (typeof getContainer === 'function') { + return getContainer(); + } + if (typeof getContainer === 'object' && getContainer instanceof window.HTMLElement) { + return getContainer; + } + } + return document.body; + }, + + getDomContainer() { + if (windowIsUndefined) { + return null; + } + if (!this.container) { + this.container = document.createElement('div'); + const parent = this.getParent(); + if (parent) { + parent.appendChild(this.container); + } + } + this.setWrapperClassName(); + return this.container; + }, + + setWrapperClassName() { + const { wrapperClassName } = this.$props; + if (this.container && wrapperClassName && wrapperClassName !== this.container.className) { + this.container.className = wrapperClassName; + } + }, + + savePortal(c) { + // Warning: don't rename _component + // https://github.com/react-component/util/pull/65#discussion_r352407916 + this._component = c; + }, + + removeCurrentContainer() { + this.container = null; + this._component = null; + }, + + /** + * Enhance ./switchScrollingEffect + * 1. Simulate document body scroll bar with + * 2. Record body has overflow style and recover when all of PortalWrapper invisible + * 3. Disable body scroll when PortalWrapper has open + * + * @memberof PortalWrapper + */ + switchScrollingEffect() { + if (openCount === 1 && !Object.keys(cacheOverflow).length) { + switchScrollingEffect(); + // Must be set after switchScrollingEffect + cacheOverflow = setStyle({ + overflow: 'hidden', + overflowX: 'hidden', + overflowY: 'hidden', + }); + } else if (!openCount) { + setStyle(cacheOverflow); + cacheOverflow = {}; + switchScrollingEffect(true); + } + }, + }, + + render() { + const { children, forceRender, visible } = this.$props; + let portal = null; + const childProps = { + getOpenCount: () => openCount, + getContainer: this.getDomContainer, + switchScrollingEffect: this.switchScrollingEffect, + }; + if (forceRender || visible || this._component) { + portal = ( + + ); + } + return portal; + }, +}; diff --git a/components/_util/antDirective.js b/components/_util/antDirective.js index 9e686a459..bdd49a948 100644 --- a/components/_util/antDirective.js +++ b/components/_util/antDirective.js @@ -1,11 +1,13 @@ import ref from 'vue-ref'; import { antInput } from './antInputDirective'; import { antDecorator } from './FormDecoratorDirective'; +import { antPortal } from './portalDirective'; export default { install: Vue => { Vue.use(ref, { name: 'ant-ref' }); antInput(Vue); antDecorator(Vue); + antPortal(Vue); }, }; diff --git a/components/_util/antInputDirective.js b/components/_util/antInputDirective.js index aad61bb32..abbb4d7fe 100644 --- a/components/_util/antInputDirective.js +++ b/components/_util/antInputDirective.js @@ -17,15 +17,12 @@ function makeMap(str, expectsLowerCase) { const isTextInputType = makeMap('text,number,password,search,email,tel,url'); function onCompositionStart(e) { - e.target.originPlaceholder = e.target.placeholder; - e.target.placeholder = ''; e.target.composing = true; } function onCompositionEnd(e) { // prevent triggering an input event for no reason if (!e.target.composing) return; - e.target.placeholder = e.target.originPlaceholder; e.target.composing = false; trigger(e.target, 'input'); } diff --git a/components/_util/isValid.js b/components/_util/isValid.js new file mode 100644 index 000000000..c4536912e --- /dev/null +++ b/components/_util/isValid.js @@ -0,0 +1,4 @@ +const isValid = value => { + return value !== undefined && value !== null && value !== ''; +}; +export default isValid; diff --git a/components/_util/moment-util.js b/components/_util/moment-util.js new file mode 100644 index 000000000..163effc36 --- /dev/null +++ b/components/_util/moment-util.js @@ -0,0 +1,75 @@ +import interopDefault from './interopDefault'; +import * as moment from 'moment'; +import warning from './warning'; +import isNil from 'lodash/isNil'; + +export const TimeType = { + validator(value) { + return typeof value === 'string' || isNil(value) || moment.isMoment(value); + }, +}; + +export const TimesType = { + validator(value) { + if (Array.isArray(value)) { + return ( + value.length === 0 || + value.findIndex(val => typeof val !== 'string') === -1 || + value.findIndex(val => !isNil(val) && !moment.isMoment(val)) === -1 + ); + } + return false; + }, +}; + +export const TimeOrTimesType = { + validator(value) { + if (Array.isArray(value)) { + return ( + value.length === 0 || + value.findIndex(val => typeof val !== 'string') === -1 || + value.findIndex(val => !isNil(val) && !moment.isMoment(val)) === -1 + ); + } else { + return typeof value === 'string' || isNil(value) || moment.isMoment(value); + } + }, +}; + +export function checkValidate(componentName, value, propName, valueFormat) { + const values = Array.isArray(value) ? value : [value]; + values.forEach(val => { + if (!val) return; + valueFormat && + warning( + interopDefault(moment)(val, valueFormat).isValid(), + componentName, + `When set \`valueFormat\`, \`${propName}\` should provides invalidate string time. `, + ); + !valueFormat && + warning( + interopDefault(moment).isMoment(val) && val.isValid(), + componentName, + `\`${propName}\` provides invalidate moment time. If you want to set empty value, use \`null\` instead.`, + ); + }); +} +export const stringToMoment = (value, valueFormat) => { + if (Array.isArray(value)) { + return value.map(val => + typeof val === 'string' && val ? interopDefault(moment)(val, valueFormat) : val || null, + ); + } else { + return typeof value === 'string' && value + ? interopDefault(moment)(value, valueFormat) + : value || null; + } +}; + +export const momentToString = (value, valueFormat) => { + if (Array.isArray(value)) { + return value.map(val => (interopDefault(moment).isMoment(val) ? val.format(valueFormat) : val)); + } else { + return interopDefault(moment).isMoment(value) ? value.format(valueFormat) : value; + } +}; diff --git a/components/_util/portalDirective.js b/components/_util/portalDirective.js new file mode 100644 index 000000000..3dea2513c --- /dev/null +++ b/components/_util/portalDirective.js @@ -0,0 +1,24 @@ +export function antPortal(Vue) { + return Vue.directive('ant-portal', { + inserted(el, binding) { + const { value } = binding; + const parentNode = typeof value === 'function' ? value(el) : value; + if (parentNode !== el.parentNode) { + parentNode.appendChild(el); + } + }, + componentUpdated(el, binding) { + const { value } = binding; + const parentNode = typeof value === 'function' ? value(el) : value; + if (parentNode !== el.parentNode) { + parentNode.appendChild(el); + } + }, + }); +} + +export default { + install: Vue => { + antPortal(Vue); + }, +}; diff --git a/components/_util/props-util.js b/components/_util/props-util.js index b91bd3619..bcc5f5136 100644 --- a/components/_util/props-util.js +++ b/components/_util/props-util.js @@ -198,6 +198,15 @@ export function getEvents(child) { return { ...events }; } +// 获取 xxx.native 或者 原生标签 事件 +export function getDataEvents(child) { + let events = {}; + if (child.data && child.data.on) { + events = child.data.on; + } + return { ...events }; +} + // use getListeners instead this.$listeners // https://github.com/vueComponent/ant-design-vue/issues/1705 export function getListeners(context) { diff --git a/components/_util/setStyle.js b/components/_util/setStyle.js new file mode 100644 index 000000000..3d44e3ac3 --- /dev/null +++ b/components/_util/setStyle.js @@ -0,0 +1,25 @@ +/** + * Easy to set element style, return previous style + * IE browser compatible(IE browser doesn't merge overflow style, need to set it separately) + * https://github.com/ant-design/ant-design/issues/19393 + * + */ +function setStyle(style, options = {}) { + const { element = document.body } = options; + const oldStyle = {}; + + const styleKeys = Object.keys(style); + + // IE browser compatible + styleKeys.forEach(key => { + oldStyle[key] = element.style[key]; + }); + + styleKeys.forEach(key => { + element.style[key] = style[key]; + }); + + return oldStyle; +} + +export default setStyle; diff --git a/components/_util/store/connect.jsx b/components/_util/store/connect.jsx index 3fab39ef6..e6efe9623 100644 --- a/components/_util/store/connect.jsx +++ b/components/_util/store/connect.jsx @@ -80,7 +80,6 @@ export default function connect(mapStateToProps) { }, }, render() { - this.preProps = { ...this.$props }; const { $slots = {}, $scopedSlots, subscribed, store } = this; const props = getOptionProps(this); this.preProps = { ...omit(props, ['__propsSymbol__']) }; diff --git a/components/_util/vnode.js b/components/_util/vnode.js index d523d4adb..c11f17daa 100644 --- a/components/_util/vnode.js +++ b/components/_util/vnode.js @@ -67,7 +67,7 @@ export function cloneElement(n, nodeProps = {}, deep) { // !(node.fnOptions && node.fnOptions.functional), // `can not use cloneElement for functional component (${node.fnOptions && node.fnOptions.name})`, // ); - const { props = {}, key, on = {}, children, directives = [] } = nodeProps; + const { props = {}, key, on = {}, nativeOn = {}, children, directives = [] } = nodeProps; const data = node.data || {}; let cls = {}; let style = {}; @@ -129,8 +129,12 @@ export function cloneElement(n, nodeProps = {}, deep) { node.componentOptions.children = children; } } else { + if (children) { + node.children = children; + } node.data.on = { ...(node.data.on || {}), ...on }; } + node.data.on = { ...(node.data.on || {}), ...nativeOn }; if (key !== undefined) { node.key = key; diff --git a/components/affix/index.jsx b/components/affix/index.jsx index d82d00716..d7019d017 100644 --- a/components/affix/index.jsx +++ b/components/affix/index.jsx @@ -100,6 +100,8 @@ const Affix = { clearTimeout(this.timeout); removeObserveTarget(this); this.updatePosition.cancel(); + // https://github.com/ant-design/ant-design/issues/22683 + this.lazyUpdatePosition.cancel(); }, methods: { getOffsetTop() { diff --git a/components/auto-complete/__tests__/__snapshots__/demo.test.js.snap b/components/auto-complete/__tests__/__snapshots__/demo.test.js.snap index 00a6d4cd0..127d4bd27 100644 --- a/components/auto-complete/__tests__/__snapshots__/demo.test.js.snap +++ b/components/auto-complete/__tests__/__snapshots__/demo.test.js.snap @@ -1,6 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`renders ./antdv-demo/docs/auto-complete/demo/basic.md correctly 1`] = ` +<<<<<<< HEAD
+======= + `; diff --git a/components/avatar/__tests__/__snapshots__/demo.test.js.snap b/components/avatar/__tests__/__snapshots__/demo.test.js.snap index 00727e923..f0f3d1961 100644 --- a/components/avatar/__tests__/__snapshots__/demo.test.js.snap +++ b/components/avatar/__tests__/__snapshots__/demo.test.js.snap @@ -9,6 +9,18 @@ exports[`renders ./antdv-demo/docs/avatar/demo/basic.md correctly 1`] = `
`; -exports[`renders ./antdv-demo/docs/avatar/demo/dynamic.md correctly 1`] = `
U
`; +exports[`renders ./antdv-demo/docs/avatar/demo/dynamic.md correctly 1`] = ` +
+ U +
+`; +<<<<<<< HEAD exports[`renders ./antdv-demo/docs/avatar/demo/type.md correctly 1`] = `
U USER U
`; +======= +exports[`renders ./antdv-demo/docs/avatar/demo/type.md correctly 1`] = ` +
U USER + U +
+`; +>>>>>>> origin/master diff --git a/components/badge/__tests__/__snapshots__/demo.test.js.snap b/components/badge/__tests__/__snapshots__/demo.test.js.snap index 7caac372a..d45909181 100644 --- a/components/badge/__tests__/__snapshots__/demo.test.js.snap +++ b/components/badge/__tests__/__snapshots__/demo.test.js.snap @@ -13,7 +13,9 @@ exports[`renders ./antdv-demo/docs/badge/demo/change.md correctly 1`] = ` exports[`renders ./antdv-demo/docs/badge/demo/colors.md correctly 1`] = `
-

Presets:

+

+ Presets: +

pink
red
@@ -29,7 +31,9 @@ exports[`renders ./antdv-demo/docs/badge/demo/colors.md correctly 1`] = `
gold
lime
-

Custom:

+

+ Custom: +

#f50
#2db7f5
#87d068
#108ee9
`; diff --git a/components/breadcrumb/__tests__/__snapshots__/demo.test.js.snap b/components/breadcrumb/__tests__/__snapshots__/demo.test.js.snap index 8eed9a1a1..a16e95709 100644 --- a/components/breadcrumb/__tests__/__snapshots__/demo.test.js.snap +++ b/components/breadcrumb/__tests__/__snapshots__/demo.test.js.snap @@ -6,12 +6,26 @@ exports[`renders ./antdv-demo/docs/breadcrumb/demo/overlay.md correctly 1`] = `< exports[`renders ./antdv-demo/docs/breadcrumb/demo/separator.md correctly 1`] = `
-
Home>Application Center>Application List>An Application>
-
Home>Application Center>Application List>An Application>
+
Home> + Application Center + > + Application List + >An Application>
+
Home> + Application Center + > + Application List + >An Application>
`; -exports[`renders ./antdv-demo/docs/breadcrumb/demo/separator-indepent.md correctly 1`] = `
Location:Application Center/Application List/An Application
`; +exports[`renders ./antdv-demo/docs/breadcrumb/demo/separator-indepent.md correctly 1`] = ` +
Location: + Application Center + / + Application List + /An Application
+`; exports[`renders ./antdv-demo/docs/breadcrumb/demo/withIcon.md correctly 1`] = `
/ Application List/ diff --git a/components/button/__tests__/__snapshots__/demo.test.js.snap b/components/button/__tests__/__snapshots__/demo.test.js.snap index e3897bac0..ae6cd326b 100644 --- a/components/button/__tests__/__snapshots__/demo.test.js.snap +++ b/components/button/__tests__/__snapshots__/demo.test.js.snap @@ -32,7 +32,32 @@ exports[`renders ./antdv-demo/docs/button/demo/multiple.md correctly 1`] = `
+<<<<<<< HEAD




+======= +



Download
+
+>>>>>>> origin/master
`; diff --git a/components/calendar/index.jsx b/components/calendar/index.jsx index eabf79009..e793a4b56 100644 --- a/components/calendar/index.jsx +++ b/components/calendar/index.jsx @@ -9,6 +9,7 @@ import interopDefault from '../_util/interopDefault'; import { ConfigConsumerProps } from '../config-provider'; import enUS from './locale/en_US'; import Base from '../base'; +import { checkValidate, stringToMoment, momentToString, TimeType } from '../_util/moment-util'; function noop() { return null; @@ -20,12 +21,6 @@ function zerofixed(v) { } return `${v}`; } -export const MomentType = { - type: Object, - validator(value) { - return moment.isMoment(value); - }, -}; function isMomentArray(value) { return Array.isArray(value) && !!value.find(val => moment.isMoment(val)); } @@ -33,8 +28,8 @@ export const CalendarMode = PropTypes.oneOf(['month', 'year']); export const CalendarProps = () => ({ prefixCls: PropTypes.string, - value: MomentType, - defaultValue: MomentType, + value: TimeType, + defaultValue: TimeType, mode: CalendarMode, fullscreen: PropTypes.bool, // dateCellRender: PropTypes.func, @@ -47,6 +42,7 @@ export const CalendarProps = () => ({ disabledDate: PropTypes.func, validRange: PropTypes.custom(isMomentArray), headerRender: PropTypes.func, + valueFormat: PropTypes.string, }); const Calendar = { @@ -64,20 +60,21 @@ const Calendar = { configProvider: { default: () => ConfigConsumerProps }, }, data() { - const value = this.value || this.defaultValue || interopDefault(moment)(); - if (!interopDefault(moment).isMoment(value)) { - throw new Error('The value/defaultValue of Calendar must be a moment object, '); - } + const { value, defaultValue, valueFormat } = this; + const sValue = value || defaultValue || interopDefault(moment)(); + checkValidate('Calendar', defaultValue, 'defaultValue', valueFormat); + checkValidate('Calendar', value, 'value', valueFormat); this._sPrefixCls = undefined; return { - sValue: value, + sValue: stringToMoment(sValue, valueFormat), sMode: this.mode || 'month', }; }, watch: { value(val) { + checkValidate('Calendar', val, 'value', this.valueFormat); this.setState({ - sValue: val, + sValue: stringToMoment(val, this.valueFormat), }); }, mode(val) { @@ -95,9 +92,10 @@ const Calendar = { this.onPanelChange(this.sValue, mode); }, onPanelChange(value, mode) { - this.$emit('panelChange', value, mode); + const val = this.valueFormat ? momentToString(value, this.valueFormat) : value; + this.$emit('panelChange', val, mode); if (value !== this.sValue) { - this.$emit('change', value); + this.$emit('change', val); } }, @@ -105,8 +103,8 @@ const Calendar = { this.setValue(value, 'select'); }, setValue(value, way) { - const prevValue = this.value || this.sValue; - const { sMode: mode } = this; + const prevValue = this.value ? stringToMoment(this.value, this.valueFormat) : this.sValue; + const { sMode: mode, valueFormat } = this; if (!hasProp(this, 'value')) { this.setState({ sValue: value }); } @@ -114,7 +112,7 @@ const Calendar = { if (prevValue && prevValue.month() !== value.month()) { this.onPanelChange(value, mode); } - this.$emit('select', value); + this.$emit('select', valueFormat ? momentToString(value, valueFormat) : value); } else if (way === 'changePanel') { this.onPanelChange(value, mode); } diff --git a/components/card/__tests__/__snapshots__/demo.test.js.snap b/components/card/__tests__/__snapshots__/demo.test.js.snap index 5321ce1ed..3732e48a0 100644 --- a/components/card/__tests__/__snapshots__/demo.test.js.snap +++ b/components/card/__tests__/__snapshots__/demo.test.js.snap @@ -55,7 +55,9 @@ exports[`renders ./antdv-demo/docs/card/demo/flexible-content.md correctly 1`] =
Europe Street beat
-
www.instagram.com
+
+ www.instagram.com +
@@ -70,14 +72,30 @@ exports[`renders ./antdv-demo/docs/card/demo/grid-card.md correctly 1`] = `
-
Content
-
Content
-
Content
-
Content
-
Content
-
Content
-
Content
-
Content
+
+ Content +
+
+ Content +
+
+ Content +
+
+ Content +
+
+ Content +
+
+ Content +
+
+ Content +
+
+ Content +
`; @@ -321,7 +339,9 @@ exports[`renders ./antdv-demo/docs/card/demo/tabs.md correctly 1`] = `
-

app content

+

+ app content +

diff --git a/components/carousel/__tests__/__snapshots__/demo.test.js.snap b/components/carousel/__tests__/__snapshots__/demo.test.js.snap index 8876bc51d..fc3c1e732 100644 --- a/components/carousel/__tests__/__snapshots__/demo.test.js.snap +++ b/components/carousel/__tests__/__snapshots__/demo.test.js.snap @@ -351,7 +351,15 @@ exports[`renders ./antdv-demo/docs/carousel/demo/fade.md correctly 1`] = ` exports[`renders ./antdv-demo/docs/carousel/demo/position.md correctly 1`] = `
-
+

Home
+======= +
+ Home +
+
+>>>>>>> origin/master `; exports[`renders ./antdv-demo/docs/input/demo/password-input.md correctly 1`] = ``; +<<<<<<< HEAD exports[`renders ./antdv-demo/docs/input/demo/presuffix.md correctly 1`] = `


RMB
`; +======= +exports[`renders ./antdv-demo/docs/input/demo/presuffix.md correctly 1`] = `


RMB
`; +>>>>>>> origin/master exports[`renders ./antdv-demo/docs/input/demo/search-input.md correctly 1`] = `






`; diff --git a/components/input/style/mixin.less b/components/input/style/mixin.less index d122c0f52..21e7d3114 100644 --- a/components/input/style/mixin.less +++ b/components/input/style/mixin.less @@ -327,6 +327,10 @@ } } + & > .@{ant-prefix}-select-focused { + z-index: 1; + } + & > *:first-child, & > .@{ant-prefix}-select:first-child > .@{ant-prefix}-select-selection, & > .@{ant-prefix}-calendar-picker:first-child .@{ant-prefix}-input, diff --git a/components/layout/__tests__/__snapshots__/demo.test.js.snap b/components/layout/__tests__/__snapshots__/demo.test.js.snap index 2fca65d47..cadd16e9a 100644 --- a/components/layout/__tests__/__snapshots__/demo.test.js.snap +++ b/components/layout/__tests__/__snapshots__/demo.test.js.snap @@ -69,15 +69,21 @@ exports[`renders ./antdv-demo/docs/layout/demo/fixed.md correctly 1`] = ` - + - + - + @@ -85,7 +91,9 @@ exports[`renders ./antdv-demo/docs/layout/demo/fixed.md correctly 1`] = `
Home/List/App/
-
Content
+
+ Content +