diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..7cffbf5f3 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "antdv-demo"] + path = antdv-demo + url = https://github.com/tangjinzhou/antdv-demo.git diff --git a/.prettierignore b/.prettierignore index 419f88a9c..6a0eec280 100644 --- a/.prettierignore +++ b/.prettierignore @@ -24,6 +24,6 @@ components/style/color/*.less .gitattributes .stylelintrc .vcmrc -logo.png +.png .npmrc.template .huskyrc diff --git a/.travis.yml b/.travis.yml index e1695d2dd..b2dce90ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,12 @@ language: node_js sudo: required +git: + submodules: false node_js: - 12.4.0 +before_install: + - echo -e "[submodule "antdv-demo"]\n path = antdv-demo\n https://$GITHUB_TOKEN@github.com/tangjinzhou/antdv-demo.git" >~/.gitmodules + - git submodule update --init --recursive before_script: - npm install vue vue-template-compiler script: @@ -9,7 +14,6 @@ script: - COVERAGE=true npm run test - npm run codecov - if [[ $TRAVIS_BRANCH == "master" && $TRAVIS_PULL_REQUEST == "false" ]]; then npm run pub-with-ci; fi - - bash ./scripts/deploy-to-gh-pages.sh env: matrix: secure: PBbJaS48HA/mkj9PuGuRxs00DEJR77XfuPdSlTvCq0QxLIR6wIO+t3LLJdOQctZIX6KWBR/Zq3zSn5bRxgPIaRcoyuEU25ga4cexJMEh1ymE23uTiDcnWwWN0X1jZKGuHPvqVKjyToAv6XW24mTXNvEAqD2uL101JxBseoWJ/2VtyOjJFJwcGbw+MTLymWCZiAF10w+k0SyigawaxZLlYL9LZXv4w3oCjCwuiTD/T6rvyT3wGQzXx7/P7XQGL4el4lE7leuK5m2PhWvX2S3t2FRpoZPw0DINJu5XzuBr3DSMErQjCrP4Ep8iqW8pGGLkoXbcxK3/K+uSy0k+DdBN7jRgnnOeLpqeVUSMaM6LRnl2XyDWL3dKpVbEzZaFkRTmAwdbgYjI+7Enn3/GtseMASo/gK47m2k+kE/msoqwpTGLC5DBOBKxdNShdFnEbOxLUUiVNgoZRXbj6VhdueqK89LsMDsnxzmFtrU8Ytgv8wJsFd5IkIhCStmQ9bdTqER659hd1Qqdh6Qe36AfpZcetOLr86Z++CSwA/pZbLPeEVrfCHDh6V3DPQXG+Zlf/m60OAmhosJ+4dxZwRnR8LnaDFZ+uLYMz+vJGeOtFHvczz7TW4mznjguLE51crG+mkBGT2dx1UUg7zs41lz3GtH9WY8cSG4y5ryjDl6YkXwoiZI= diff --git a/BACKERS.md b/BACKERS.md index 4990f389e..737cee6b6 100644 --- a/BACKERS.md +++ b/BACKERS.md @@ -35,7 +35,7 @@

支付宝/微信

-### 使用支付宝/微信的赞助的用户,如需要添加名单,赞助后可发 github 账号到邮箱(415800467@qq.com) +### 使用支付宝/微信的赞助的用户,如需要添加名单,赞助后可发 github 账号到邮箱(antdv@foxmail.com) - [fastgoo](https://github.com/fastgoo) - [sendya](https://github.com/sendya) diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md index cff07f329..796655739 100644 --- a/CHANGELOG.en-US.md +++ b/CHANGELOG.en-US.md @@ -4,12 +4,85 @@ #### Release Schedule -- Weekly release: patch version at the end of every week for routine bugfix (anytime for urgent bugfix). +- Weekly release: patch version for routine bugfix. - Monthly release: minor version for new features. - Major version release is not included in this schedule for breaking change and new features. --- +## 1.5.0 + +`2020-03-06` + +### Component features and styles are synchronized to antd version 3.26.12. + +- Four new components have been added: + - 🔥🔥🔥 [Mentions](https://antdv.com/components/mentions-cn/) Added mentioned components and discarded the original Mention components. + - 🔥🔥🔥 [Descriptions](https://antdv.com/components/descriptions-cn/) Display multiple read-only fields in groups. + - 🔥🔥🔥 [PageHeader](https://antdv.com/components/page-header-cn/) can be used to declare the topic of the page, display important information about the page that the user is concerned about, and carry the operation items related to the current page. + - 🔥🔥🔥 [Result](https://antdv.com/components/result) is used to feedback the processing results of a series of operation tasks. +- 🔥 Descriptions supports vertical layout. +- 🔥 Progress.Circle supports gradient colors. +- 🔥 Progress.Line supports gradient colors. +- Breadcrumb + - 🎉 Breadcrumb.Item supports the `overlay` property to define drop-down menus. + - 🌟 Added `Breadcrumb.Separator` component, you can customize`separator`. +- 🌟 TreeSelect's `showSearch` supports multiple selection mode. +- 🌟 Timeline.Item adds `gray` color type, which can be used in incomplete or invalid state. +- 🌟 Modal supports `closeIcon` property for customizing the close icon. +- Upload + - 🌟 Upload provides `previewFile` property to customize the preview logic. + - 🌟 Upload adds `transformFile` to support converting files before uploading. + - 🌟 Upload supports previewing pictures in jfif format. + - 🌟 Added `showDownloadIcon` property for displaying download icons. +- 🌟 Input.Search adds `loading` property, which is used to display the loading status. +- 🌟 Grid's `gutter` property adds support for vertical spacing. Now you can set an array for`gutter`, the second value of the array represents the vertical spacing. +- 🌟 message Added support for updating content with unique `key`. +- 🌟 TextArea supports `allowClear`. +- 🌟 Dropdown.Button supports `icon` property to customize the icon. +- Drawer + - 🌟 Support `afterVisibleChange` property, which is triggered after the drawer animation is completed. + - 🌟 Support `ESC` shutdown. + - 🌟 Added `keyboard`, which allows the response to keyboard events to be turned on and off. +- 🌟 TreeNode supports `checkable` property. +- 🌟 Transfer supports `children` custom rendering list. +- 🌟 Pagination supports `disabled` property. +- 🌟 Steps support click to switch function. +- Slider + - 🌟 Support `tooltipPlacement` to define the location of the tip. + - 🌟 Support `getTooltipPopupContainer` to allow custom container for the prompt. + - 🌟 Flip `trigger` direction when Sider is on the right. +- 🌟 Calendar supports `headerRender` to customize header. +- 🌟 Carousel supports custom panel pointing point locations. +- 🌟 Collapse supports `expandIconPosition` property. +- 🌟 Popconfirm adds `disabled` props, which are used to control whether clicking child elements pop up. +- 🌟 Select supports `showArrow` in multi-select mode. +- 🌟 Collapse.Panel added `extra`. +- Card + - 🌟 Card component added `tabBarExtraContent` property. + - 🌟 Card.Grid added a hoverable property to allow floating effects to be disabled. +- 🌟 Anchor.Link adds `target` attribute. +- 🌟 TimePicker added `clearIcon` prop for custom clear icon. +- Form + - 🌟 Support to configure the `colon` property directly on the Form. + - 🌟 Support `labelAlign` property. +- Table + - 🌟 Table adds `getPopupContainer` property for setting various floating layer rendering nodes in the table. + - 💄 Adjust the style of the Table expand button. + - 🌟 Added `tableLayout` property, supports setting the table's`table-layout` layout, and enables `tableLayout =" fixed "` by default under fixed headers / columns, to solve the column alignment problem caused by the table layout automatically based on content . + - 🌟 Added `column.ellipsis` to support automatic omission of cell contents. + - 🌟 Added `scroll.scrollToFirstRowOnChange` property, which is used to set whether to scroll to the top of the table after page turning.   -Filter `filterDropdown` Added`visible` parameter to get the display status of the drop-down box. + - 🌟 The `title` method adds a`sortColumn` parameter to get the currently sorted column.   -Sort When sorting, the `sorter` parameter of`onChange` will always contain `column` information. +- 🌟 Tree component supports `blockNode` property. +- 🌟 RangePicker adds `separator` definition. +- Empty + - 🌟 Empty supports the `imageStyle` property. + - 🌟 Empty `description` supports`false`. + - 🌟 Empty Supports access to preset pictures via `Empty.PRESENTED_IMAGE_DEFAULT` and`Empty.PRESENTED_IMAGE_SIMPLE` +- 🌟 Badge supports custom colors. +- 🐞 Fix the problem that the label of Steps is not centered. +- 🐞 Fix cursor style problem of DatePicker and TimePicker. + ## 1.4.12 `2020-03-03` diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md index e0c3e0ef8..e5fbcd62a 100644 --- a/CHANGELOG.zh-CN.md +++ b/CHANGELOG.zh-CN.md @@ -4,12 +4,87 @@ #### 发布周期 -- 修订版本号:每周末会进行日常 bugfix 更新。(如果有紧急的 bugfix,则任何时候都可发布) +- 修订版本号:日常 bugfix 更新 - 次版本号:带有新特性的向下兼容的版本。 - 主版本号:含有破坏性更新和新特性,不在发布周期内。 --- +## 1.5.0 + +`2020-03-06` + +### 组件功能和样式同步到 antd 3.26.12 版本。 + +- 新增了四个组件: + - 🔥🔥🔥 [Mentions](https://antdv.com/components/mentions-cn/) 新增提及组件并废弃原有 Mention 组件。 + - 🔥🔥🔥 [Descriptions](https://antdv.com/components/descriptions-cn/) 成组展示多个只读字段。 + - 🔥🔥🔥 [PageHeader](https://antdv.com/components/page-header-cn/) 可用于声明页面主题、展示用户所关注的页面重要信息,以及承载与当前页相关的操作项。 + - 🔥🔥🔥 [Result](https://antdv.com/components/result) 用于反馈一系列操作任务的处理结果。 +- 🔥 Descriptions 支持垂直布局。 +- 🔥 Progress.Circle 支持渐变色。 +- 🔥 Progress.Line 支持渐变色。 +- Breadcrumb + - 🎉 Breadcrumb.Item 支持 `overlay` 属性来定义下拉菜单。 + - 🌟 新增 `Breadcrumb.Separator` 组件,可进行 `separator` 自定义。 +- 🌟 TreeSelect 的 `showSearch` 支持多选模式。 +- 🌟 Timeline.Item 新增 `gray` 色彩类型,可用于未完成或失效状态。 +- 🌟 Modal 支持 `closeIcon` 属性用于自定义关闭图标。 +- 🌟 Upload + - 🌟 Upload 提供 `previewFile` 属性以自定义预览逻辑。 + - 🌟 Upload 新增 `transformFile` 支持上传之前转换文件。 + - 🌟 Upload 支持预览 `jfif` 格式图片。 + - 🌟 新增 `showDownloadIcon` 属性,用于展示下载图标。 +- 🌟 Input.Search 新增 `loading` 属性,用于展示加载中的状态。 +- 🌟 Grid 的 `gutter` 属性新增垂直间距的支持,现在你可以给 `gutter` 设置一个数组,数组的第二个值就表示垂直间距。 +- 🌟 message 新增支持通过唯一的 `key` 来更新内容。 +- 🌟 TextArea 支持 `allowClear`。 +- 🌟 Dropdown.Button 支持 `icon` 属性来自定义图标。 +- Drawer + - 🌟 支持 `afterVisibleChange` 属性,在抽屉动画完成后触发。 + - 🌟 支持 `ESC` 关闭。 + - 🌟 新增 `keyboard`,允许打开关闭对键盘事件的响应。 +- 🌟 TreeNode 支持 `checkable` 属性。 +- 🌟 Transfer 支持 `children` 来自定义渲染列表。 +- 🌟 Pagination 支持 `disabled` 属性。 +- 🌟 Steps 支持点击切换功能。 +- Slider + - 🌟 支持 `tooltipPlacement` 以定义提示所在位置。 + - 🌟 支持 `getTooltipPopupContainer` 以允许自定义提示所在容器。 + - 🌟 当 Sider 在右边时,翻转 `trigger` 方向。 +- 🌟 Calendar 支持 `headerRender` 以自定义头部。 +- 🌟 Carousel 支持自定义面板指示点的位置。 +- 🌟 Collapse 支持 `expandIconPosition` 属性。 +- 🌟 Popconfirm 增加 `disabled` props,用于控制点击子元素是否弹出。 +- 🌟 Select 在多选模式下支持 `showArrow`。 +- 🌟 Collapse.Panel 新增了 `extra`。 +- Card + - 🌟 Card 组件新增了 `tabBarExtraContent` 属性。 + - 🌟 Card.Grid 新增 `hoverable` 属性允许禁用浮动效果。 +- 🌟 Anchor.Link 增加 `target` 属性。 +- 🌟 TimePicker 新增了 `clearIcon` prop,用于自定义清除图标。 +- Form + - 🌟 支持直接在 Form 上面配置 `colon` 属性。 + - 🌟 支持 `labelAlign` 属性。 +- Table + - 🌟 Table 新增 `getPopupContainer` 属性用于设置表格内的各类浮层渲染节点。 + - 💄 调整 Table 展开按钮的样式。 + - 🌟 新增 `tableLayout` 属性,支持设置表格的 `table-layout` 布局,并在固定表头/列下默认开启 `tableLayout="fixed"`,解决因为表格自动根据内容排版造成的列对齐问题。 + - 🌟 新增 `column.ellipsis` 支持单元格内容自动省略。 + - 🌟 新增 `scroll.scrollToFirstRowOnChange` 属性,用于设置在翻页后是否滚动到表格顶部。 + - 🌟 `filterDropdown` 新增 `visible` 参数,用于获取下拉框的显示状态。 + - 🌟 `title` 方法新增 `sortColumn` 参数,用于获取当前排序的列。 + - 🌟 排序时 `onChange` 的 `sorter` 参数将始终包含 `column` 信息。 +- 🌟 Tree 组件支持 `blockNode` 属性。 +- 🌟 RangePicker 添加 `separator` 定义。 +- Empty + - 🌟 Empty 支持 `imageStyle` 属性。 + - 🌟 Empty `description` 支持 `false`。 + - 🌟 Empty 支持通过 `Empty.PRESENTED_IMAGE_DEFAULT` 和 `Empty.PRESENTED_IMAGE_SIMPLE` 访问预置图片。 +- 🌟 Badge 支持自定义颜色。 +- 🐞 修复 Steps 的 label 不居中的问题。 +- 🐞 修复 DatePicker 和 TimePicker 的 cursor 样式问题。 + ## 1.4.12 `2020-03-03` diff --git a/antd-tools/gulpfile.js b/antd-tools/gulpfile.js index d91348953..63ff5971f 100644 --- a/antd-tools/gulpfile.js +++ b/antd-tools/gulpfile.js @@ -295,11 +295,12 @@ gulp.task( gulp.task( 'pub', gulp.series('check-git', 'compile', done => { - if (!process.env.GITHUB_TOKEN) { - console.log('no GitHub token found, skip'); - } else { - pub(done); - } + // if (!process.env.GITHUB_TOKEN) { + // console.log('no GitHub token found, skip'); + // } else { + // pub(done); + // } + pub(done); }), ); diff --git a/antdv-demo b/antdv-demo new file mode 160000 index 000000000..805d3298a --- /dev/null +++ b/antdv-demo @@ -0,0 +1 @@ +Subproject commit 805d3298a8c2a6fc5deee94ad0db8cab014cd2d8 diff --git a/build/config.js b/build/config.js index f9333a91d..ddbb5d3d1 100644 --- a/build/config.js +++ b/build/config.js @@ -1,5 +1,5 @@ module.exports = { dev: { - componentName: 'tree', // dev components + componentName: 'badge', // dev components }, }; diff --git a/build/dev.js b/build/dev.js index 0d0a3e0d8..a5ffaa67d 100644 --- a/build/dev.js +++ b/build/dev.js @@ -28,7 +28,6 @@ let { componentName } = require('./config').dev; const componentsInPrototype = ['Modal', 'message', 'notification']; const MAIN_TEMPLATE = `import 'babel-polyfill'; -import './index.less'; import 'highlight.js/styles/solarized-light.css'; import Vue from 'vue'; import Vuex from 'vuex'; @@ -38,6 +37,7 @@ import VueClipboard from 'vue-clipboard2'; import Md from './components/md'; import Api from './components/api'; import demoBox from './components/demoBox'; +import demoSort from './components/demoSort'; import demoContainer from './components/demoContainer'; import Modal from '../components/modal'; import message from '../components/message'; @@ -47,9 +47,10 @@ import notification from '../components/notification'; import '../components/modal/style'; import '../components/message/style'; import '../components/notification/style'; -import Test from '../components/{{name}}/demo/index.vue'; +import Test from '../antdv-demo/{{name}}/demo/index.vue'; import zhCN from './theme/zh-CN'; import enUS from './theme/en-US'; +import './index.less'; Vue.use(Vuex); Vue.use(VueClipboard); @@ -58,6 +59,7 @@ Vue.use(VueI18n); Vue.component(Md.name, Md); Vue.component(Api.name, Api); Vue.component('demo-box', demoBox); +Vue.component('demo-sort', demoSort); Vue.component('demo-container', demoContainer); Vue.prototype.$message = message; @@ -132,8 +134,8 @@ const renderTemplate = name => { }; const demoPaths = fs - .readdirSync(path.join(__dirname, `../components/${name}/demo`)) - .map(p => `../components/${name}/demo/${p}`); + .readdirSync(path.join(__dirname, `../antdv-demo/${name}/demo`)) + .map(p => `../antdv-demo/${name}/demo/${p}`); const testPaths = fs .readdirSync(path.join(__dirname, `../components/test`)) .map(p => `../components/test/${p}`); @@ -194,7 +196,7 @@ chokidar.watch(configPath, { ignoreInitial: true }).on('change', async () => { demoWatcher && (await demoWatcher.close()); - demoWatcher = chokidar.watch(path.join(__dirname, `../components/${componentName}/demo`)); + demoWatcher = chokidar.watch(path.join(__dirname, `../antdv-demo/${componentName}/demo`)); demoWatcher.on('change', () => { renderTemplate(componentName); }); diff --git a/build/webpack.dev.conf.js b/build/webpack.dev.conf.js index 7d7aea5c2..6f9ec46ed 100644 --- a/build/webpack.dev.conf.js +++ b/build/webpack.dev.conf.js @@ -30,7 +30,7 @@ module.exports = merge(baseWebpackConfig, { ], }, devServer: { - port: 3000, + port: process.env.PORT || 3000, host: '0.0.0.0', historyApiFallback: { rewrites: [{ from: /./, to: '/index.html' }], diff --git a/components/__tests__/util/domHook.js b/components/__tests__/util/domHook.js new file mode 100644 index 000000000..dddc3ffc2 --- /dev/null +++ b/components/__tests__/util/domHook.js @@ -0,0 +1,58 @@ +const __NULL__ = { notExist: true }; + +export function spyElementPrototypes(Element, properties) { + const propNames = Object.keys(properties); + const originDescriptors = {}; + + propNames.forEach(propName => { + const originDescriptor = Object.getOwnPropertyDescriptor(Element.prototype, propName); + originDescriptors[propName] = originDescriptor || __NULL__; + + const spyProp = properties[propName]; + + if (typeof spyProp === 'function') { + // If is a function + Element.prototype[propName] = function spyFunc(...args) { + return spyProp.call(this, originDescriptor, ...args); + }; + } else { + // Otherwise tread as a property + Object.defineProperty(Element.prototype, propName, { + ...spyProp, + set(value) { + if (spyProp.set) { + return spyProp.set.call(this, originDescriptor, value); + } + return originDescriptor.set(value); + }, + get() { + if (spyProp.get) { + return spyProp.get.call(this, originDescriptor); + } + return originDescriptor.get(); + }, + }); + } + }); + + return { + mockRestore() { + propNames.forEach(propName => { + const originDescriptor = originDescriptors[propName]; + if (originDescriptor === __NULL__) { + delete Element.prototype[propName]; + } else if (typeof originDescriptor === 'function') { + Element.prototype[propName] = originDescriptor; + } else { + Object.defineProperty(Element.prototype, propName, originDescriptor); + } + }); + }, + }; +} + +export function spyElementPrototype(Element, propName, property) { + return spyElementPrototypes(Element, { + [propName]: property, + }); +} diff --git a/components/_util/BaseMixin.js b/components/_util/BaseMixin.js index fefcf18df..d15669e7d 100644 --- a/components/_util/BaseMixin.js +++ b/components/_util/BaseMixin.js @@ -19,6 +19,7 @@ export default { // Object.assign(newState, this.getDerivedStateFromProps(getOptionProps(this), { ...this.$data, ...newState }, true) || {}) // } Object.assign(this.$data, newState); + this.$forceUpdate(); this.$nextTick(() => { callback && callback(); }); diff --git a/components/_util/Dom/class-util.js b/components/_util/Dom/class-util.js deleted file mode 100644 index 5012f5722..000000000 --- a/components/_util/Dom/class-util.js +++ /dev/null @@ -1,61 +0,0 @@ -/* @flow */ - -/** - * Add class with compatibility for SVG since classList is not supported on - * SVG elements in IE - */ -export function addClass(el, cls) { - /* istanbul ignore if */ - if (!cls || !(cls = cls.trim())) { - return; - } - - /* istanbul ignore else */ - if (el.classList) { - if (cls.indexOf(' ') > -1) { - cls.split(/\s+/).forEach(c => el.classList.add(c)); - } else { - el.classList.add(cls); - } - } else { - const cur = ` ${el.getAttribute('class') || ''} `; - if (cur.indexOf(' ' + cls + ' ') < 0) { - el.setAttribute('class', (cur + cls).trim()); - } - } -} - -/** - * Remove class with compatibility for SVG since classList is not supported on - * SVG elements in IE - */ -export function removeClass(el, cls) { - /* istanbul ignore if */ - if (!cls || !(cls = cls.trim())) { - return; - } - - /* istanbul ignore else */ - if (el.classList) { - if (cls.indexOf(' ') > -1) { - cls.split(/\s+/).forEach(c => el.classList.remove(c)); - } else { - el.classList.remove(cls); - } - if (!el.classList.length) { - el.removeAttribute('class'); - } - } else { - let cur = ` ${el.getAttribute('class') || ''} `; - const tar = ' ' + cls + ' '; - while (cur.indexOf(tar) >= 0) { - cur = cur.replace(tar, ' '); - } - cur = cur.trim(); - if (cur) { - el.setAttribute('class', cur); - } else { - el.removeAttribute('class'); - } - } -} diff --git a/components/_util/__tests__/easings.test.js b/components/_util/__tests__/easings.test.js new file mode 100644 index 000000000..d32e0dd7f --- /dev/null +++ b/components/_util/__tests__/easings.test.js @@ -0,0 +1,13 @@ +import { easeInOutCubic } from '../easings'; + +describe('Test easings', () => { + it('easeInOutCubic return value', () => { + const nums = []; + // eslint-disable-next-line no-plusplus + for (let index = 0; index < 5; index++) { + nums.push(easeInOutCubic(index, 1, 5, 4)); + } + + expect(nums).toEqual([1, 1.25, 3, 4.75, 5]); + }); +}); diff --git a/components/_util/__tests__/scrollTo.test.js b/components/_util/__tests__/scrollTo.test.js new file mode 100644 index 000000000..3e41a60ee --- /dev/null +++ b/components/_util/__tests__/scrollTo.test.js @@ -0,0 +1,56 @@ +import scrollTo from '../scrollTo'; + +describe('Test ScrollTo function', () => { + let dateNowMock; + + beforeAll(() => { + jest.useFakeTimers(); + }); + + afterAll(() => { + jest.useRealTimers(); + }); + + beforeEach(() => { + dateNowMock = jest + .spyOn(Date, 'now') + .mockImplementationOnce(() => 0) + .mockImplementationOnce(() => 1000); + }); + + afterEach(() => { + dateNowMock.mockRestore(); + }); + + it('test scrollTo', async () => { + const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => { + window.scrollY = y; + window.pageYOffset = y; + }); + + scrollTo(1000); + + jest.runAllTimers(); + expect(window.pageYOffset).toBe(1000); + + scrollToSpy.mockRestore(); + }); + + it('test callback - option', async () => { + const cbMock = jest.fn(); + scrollTo(1000, { + callback: cbMock, + }); + jest.runAllTimers(); + expect(cbMock).toHaveBeenCalledTimes(1); + }); + + it('test getContainer - option', async () => { + const div = document.createElement('div'); + scrollTo(1000, { + getContainer: () => div, + }); + jest.runAllTimers(); + expect(div.scrollTop).toBe(1000); + }); +}); diff --git a/components/_util/colors.js b/components/_util/colors.js new file mode 100644 index 000000000..5b0d35bd3 --- /dev/null +++ b/components/_util/colors.js @@ -0,0 +1,17 @@ +import { tuple } from './type'; + +export const PresetColorTypes = tuple( + 'pink', + 'red', + 'yellow', + 'orange', + 'cyan', + 'green', + 'blue', + 'purple', + 'geekblue', + 'magenta', + 'volcano', + 'gold', + 'lime', +); diff --git a/components/_util/easings.js b/components/_util/easings.js new file mode 100644 index 000000000..e11ab904d --- /dev/null +++ b/components/_util/easings.js @@ -0,0 +1,8 @@ +export function easeInOutCubic(t, b, c, d) { + const cc = c - b; + t /= d / 2; + if (t < 1) { + return (cc / 2) * t * t * t + b; + } + return (cc / 2) * ((t -= 2) * t * t + 2) + b; +} diff --git a/components/_util/getTransitionProps.js b/components/_util/getTransitionProps.js index 19d7a312a..623060c8d 100644 --- a/components/_util/getTransitionProps.js +++ b/components/_util/getTransitionProps.js @@ -1,7 +1,7 @@ import animate from './css-animation'; const noop = () => {}; const getTransitionProps = (transitionName, opt = {}) => { - const { beforeEnter, enter, afterEnter, leave, afterLeave, appear = true, tag } = opt; + const { beforeEnter, enter, afterEnter, leave, afterLeave, appear = true, tag, nativeOn } = opt; const transitionProps = { props: { appear, @@ -22,6 +22,7 @@ const getTransitionProps = (transitionName, opt = {}) => { }), afterLeave: afterLeave || noop, }, + nativeOn, }; // transition-group if (tag) { diff --git a/components/_util/openAnimation.js b/components/_util/openAnimation.js index 9d63df31c..2c81887ee 100644 --- a/components/_util/openAnimation.js +++ b/components/_util/openAnimation.js @@ -6,7 +6,7 @@ function animate(node, show, done) { let height; let requestAnimationFrameId; let appearRequestAnimationFrameId; - return cssAnimation(node, 'ant-motion-collapse', { + return cssAnimation(node, 'ant-motion-collapse-legacy', { start() { if (appearRequestAnimationFrameId) { raf.cancel(appearRequestAnimationFrameId); diff --git a/components/_util/props-util.js b/components/_util/props-util.js index 4868f59c0..050f634d4 100644 --- a/components/_util/props-util.js +++ b/components/_util/props-util.js @@ -259,6 +259,10 @@ export function isEmptyElement(c) { return !(c.tag || (c.text && c.text.trim() !== '')); } +export function isStringElement(c) { + return !c.tag; +} + export function filterEmpty(children = []) { return children.filter(c => !isEmptyElement(c)); } diff --git a/components/_util/raf.js b/components/_util/raf.js index 6e8c9b083..e4c4d28a5 100644 --- a/components/_util/raf.js +++ b/components/_util/raf.js @@ -13,18 +13,20 @@ export default function wrapperRaf(callback, delayFrames = 1) { if (restFrames <= 0) { callback(); - delete ids[id]; + delete ids[myId]; } else { - ids[id] = raf(internalCallback); + ids[myId] = raf(internalCallback); } } - ids[id] = raf(internalCallback); + ids[myId] = raf(internalCallback); return myId; } wrapperRaf.cancel = function(pid) { + if (pid === undefined) return; raf.cancel(ids[pid]); delete ids[pid]; }; +wrapperRaf.ids = ids; // export this for test usage diff --git a/components/_util/responsiveObserve.js b/components/_util/responsiveObserve.js new file mode 100644 index 000000000..88a29c774 --- /dev/null +++ b/components/_util/responsiveObserve.js @@ -0,0 +1,94 @@ +// matchMedia polyfill for +// https://github.com/WickyNilliams/enquire.js/issues/82 +let enquire; + +// TODO: Will be removed in antd 4.0 because we will no longer support ie9 +if (typeof window !== 'undefined') { + const matchMediaPolyfill = mediaQuery => { + return { + media: mediaQuery, + matches: false, + addListener() {}, + removeListener() {}, + }; + }; + // ref: https://github.com/ant-design/ant-design/issues/18774 + if (!window.matchMedia) window.matchMedia = matchMediaPolyfill; + // eslint-disable-next-line global-require + enquire = require('enquire.js'); +} + +export const responsiveArray = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs']; + +export const responsiveMap = { + xs: '(max-width: 575px)', + sm: '(min-width: 576px)', + md: '(min-width: 768px)', + lg: '(min-width: 992px)', + xl: '(min-width: 1200px)', + xxl: '(min-width: 1600px)', +}; + +let subscribers = []; +let subUid = -1; +let screens = {}; + +const responsiveObserve = { + dispatch(pointMap) { + screens = pointMap; + if (subscribers.length < 1) { + return false; + } + + subscribers.forEach(item => { + item.func(screens); + }); + + return true; + }, + subscribe(func) { + if (subscribers.length === 0) { + this.register(); + } + const token = (++subUid).toString(); + subscribers.push({ + token, + func, + }); + func(screens); + return token; + }, + unsubscribe(token) { + subscribers = subscribers.filter(item => item.token !== token); + if (subscribers.length === 0) { + this.unregister(); + } + }, + unregister() { + Object.keys(responsiveMap).map(screen => enquire.unregister(responsiveMap[screen])); + }, + register() { + Object.keys(responsiveMap).map(screen => + enquire.register(responsiveMap[screen], { + match: () => { + const pointMap = { + ...screens, + [screen]: true, + }; + this.dispatch(pointMap); + }, + unmatch: () => { + const pointMap = { + ...screens, + [screen]: false, + }; + this.dispatch(pointMap); + }, + // Keep a empty destory to avoid triggering unmatch when unregister + destroy() {}, + }), + ); + }, +}; + +export default responsiveObserve; diff --git a/components/_util/scrollTo.js b/components/_util/scrollTo.js new file mode 100644 index 000000000..efdb25200 --- /dev/null +++ b/components/_util/scrollTo.js @@ -0,0 +1,37 @@ +import raf from 'raf'; +import getScroll from './getScroll'; +import { easeInOutCubic } from './easings'; + +// interface ScrollToOptions { +// /** Scroll container, default as window */ +// getContainer?: () => HTMLElement | Window; +// /** Scroll end callback */ +// callback?: () => any; +// /** Animation duration, default as 450 */ +// duration?: number; +// } + +export default function scrollTo(y, options = {}) { + const { getContainer = () => window, callback, duration = 450 } = options; + + const container = getContainer(); + const scrollTop = getScroll(container, true); + const startTime = Date.now(); + + const frameFunc = () => { + const timestamp = Date.now(); + const time = timestamp - startTime; + const nextScrollTop = easeInOutCubic(time > duration ? duration : time, scrollTop, y, duration); + if (container === window) { + window.scrollTo(window.pageXOffset, nextScrollTop); + } else { + container.scrollTop = nextScrollTop; + } + if (time < duration) { + raf(frameFunc); + } else if (typeof callback === 'function') { + callback(); + } + }; + raf(frameFunc); +} diff --git a/components/_util/styleChecker.js b/components/_util/styleChecker.js index f54c1f7a9..967f0422f 100644 --- a/components/_util/styleChecker.js +++ b/components/_util/styleChecker.js @@ -1,4 +1,4 @@ -function isStyleSupport(styleName) { +const isStyleSupport = styleName => { if (typeof window !== 'undefined' && window.document && window.document.documentElement) { const styleNameList = Array.isArray(styleName) ? styleName : [styleName]; const { documentElement } = window.document; @@ -6,7 +6,7 @@ function isStyleSupport(styleName) { return styleNameList.some(name => name in documentElement.style); } return false; -} +}; export const isFlexSupported = isStyleSupport(['flex', 'webkitFlex', 'Flex', 'msFlex']); diff --git a/components/_util/transButton.jsx b/components/_util/transButton.jsx new file mode 100644 index 000000000..29b3cc9a3 --- /dev/null +++ b/components/_util/transButton.jsx @@ -0,0 +1,81 @@ +/** + * Wrap of sub component which need use as Button capacity (like Icon component). + * This helps accessibility reader to tread as a interactive button to operation. + */ +import KeyCode from './KeyCode'; +import PropTypes from './vue-types'; + +const inlineStyle = { + border: 0, + background: 'transparent', + padding: 0, + lineHeight: 'inherit', + display: 'inline-block', +}; + +const TransButton = { + props: { + noStyle: PropTypes.bool, + }, + + methods: { + onKeyDown(event) { + const { keyCode } = event; + if (keyCode === KeyCode.ENTER) { + event.preventDefault(); + } + }, + + onKeyUp(event) { + const { keyCode } = event; + if (keyCode === KeyCode.ENTER) { + this.$emit('click', event); + } + }, + + setRef(btn) { + this.div = btn; + }, + + focus() { + if (this.div) { + this.div.focus(); + } + }, + + blur() { + if (this.div) { + this.div.blur(); + } + }, + }, + + render() { + const { noStyle } = this.$props; + + return ( +
+ {this.$slots.default} +
+ ); + }, +}; + +export default TransButton; diff --git a/components/_util/type.js b/components/_util/type.js new file mode 100644 index 000000000..8d3e0d7cb --- /dev/null +++ b/components/_util/type.js @@ -0,0 +1,4 @@ +// https://stackoverflow.com/questions/46176165/ways-to-get-string-literal-type-of-array-values-without-enum-overhead +export const tuple = (...args) => args; + +export const tupleNum = (...args) => args; diff --git a/components/_util/warning.js b/components/_util/warning.js index b76fce037..59681e40a 100644 --- a/components/_util/warning.js +++ b/components/_util/warning.js @@ -1,38 +1,7 @@ -/* eslint-disable no-console */ -let warned = {}; +import warning, { resetWarned } from '../vc-util/warning'; -export function warning(valid, message) { - // Support uglify - if (process.env.NODE_ENV !== 'production' && !valid && console !== undefined) { - console.error(`Warning: ${message}`); - } -} +export { resetWarned }; -export function note(valid, message) { - // Support uglify - if (process.env.NODE_ENV !== 'production' && !valid && console !== undefined) { - console.warn(`Note: ${message}`); - } -} - -export function resetWarned() { - warned = {}; -} - -export function call(method, valid, message) { - if (!valid && !warned[message]) { - method(false, message); - warned[message] = true; - } -} - -export function warningOnce(valid, message) { - call(warning, valid, message); -} - -export function noteOnce(valid, message) { - call(note, valid, message); -} - -export default warningOnce; -/* eslint-enable */ +export default (valid, component, message = '') => { + warning(valid, `[antdv: ${component}] ${message}`); +}; diff --git a/components/_util/wave.jsx b/components/_util/wave.jsx index 61cd2ed9e..ae7776204 100644 --- a/components/_util/wave.jsx +++ b/components/_util/wave.jsx @@ -1,5 +1,6 @@ import TransitionEvents from './css-animation/Event'; -import raf from '../_util/raf'; +import raf from './raf'; +import { ConfigConsumerProps } from '../config-provider'; let styleForPesudo; // Where el is the DOM element you'd like to test for visibility @@ -9,7 +10,14 @@ function isHidden(element) { } return !element || element.offsetParent === null; } - +function isNotGrey(color) { + // eslint-disable-next-line no-useless-escape + const match = (color || '').match(/rgba?\((\d*), (\d*), (\d*)(, [\.\d]*)?\)/); + if (match && match[1] && match[2] && match[3]) { + return !(match[1] === match[2] && match[2] === match[3]); + } + return true; +} export default { name: 'Wave', props: ['insertExtraNode'], @@ -22,7 +30,9 @@ export default { this.instance = this.bindAnimationEvent(node); }); }, - + inject: { + configProvider: { default: () => ConfigConsumerProps }, + }, beforeDestroy() { if (this.instance) { this.instance.cancel(); @@ -33,19 +43,10 @@ export default { this.destroy = true; }, methods: { - isNotGrey(color) { - const match = (color || '').match(/rgba?\((\d*), (\d*), (\d*)(, [\.\d]*)?\)/); - if (match && match[1] && match[2] && match[3]) { - return !(match[1] === match[2] && match[2] === match[3]); - } - return true; - }, - onClick(node, waveColor) { if (!node || isHidden(node) || node.className.indexOf('-leave') >= 0) { return; } - this.removeExtraStyleNode(); const { insertExtraNode } = this.$props; this.extraNode = document.createElement('div'); const extraNode = this.extraNode; @@ -59,13 +60,19 @@ export default { waveColor && waveColor !== '#ffffff' && waveColor !== 'rgb(255, 255, 255)' && - this.isNotGrey(waveColor) && + isNotGrey(waveColor) && !/rgba\(\d*, \d*, \d*, 0\)/.test(waveColor) && // any transparent rgba color waveColor !== 'transparent' ) { + // Add nonce if CSP exist + if (this.csp && this.csp.nonce) { + styleForPesudo.nonce = this.csp.nonce; + } extraNode.style.borderColor = waveColor; - - styleForPesudo.innerHTML = `[ant-click-animating-without-extra-node]:after { border-color: ${waveColor}; }`; + styleForPesudo.innerHTML = ` + [ant-click-animating-without-extra-node='true']::after, .ant-click-animating-node { + --antd-wave-shadow-color: ${waveColor}; + }`; if (!document.body.contains(styleForPesudo)) { document.body.appendChild(styleForPesudo); } @@ -76,7 +83,28 @@ export default { TransitionEvents.addStartEventListener(node, this.onTransitionStart); TransitionEvents.addEndEventListener(node, this.onTransitionEnd); }, + onTransitionStart(e) { + if (this.destroy) return; + const node = this.$el; + if (!e || e.target !== node) { + return; + } + + if (!this.animationStart) { + this.resetEffect(node); + } + }, + onTransitionEnd(e) { + if (!e || e.animationName !== 'fadeEffect') { + return; + } + this.resetEffect(e.target); + }, + getAttributeName() { + const { insertExtraNode } = this.$props; + return insertExtraNode ? 'ant-click-animating' : 'ant-click-animating-without-extra-node'; + }, bindAnimationEvent(node) { if ( !node || @@ -113,10 +141,6 @@ export default { }, }; }, - getAttributeName() { - const { insertExtraNode } = this.$props; - return insertExtraNode ? 'ant-click-animating' : 'ant-click-animating-without-extra-node'; - }, resetEffect(node) { if (!node || node === this.extraNode || !(node instanceof Element)) { @@ -124,40 +148,22 @@ export default { } const { insertExtraNode } = this.$props; const attributeName = this.getAttributeName(); - node.removeAttribute(attributeName); - this.removeExtraStyleNode(); + node.setAttribute(attributeName, 'false'); // edge has bug on `removeAttribute` #14466 + if (styleForPesudo) { + styleForPesudo.innerHTML = ''; + } if (insertExtraNode && this.extraNode && node.contains(this.extraNode)) { node.removeChild(this.extraNode); } TransitionEvents.removeStartEventListener(node, this.onTransitionStart); TransitionEvents.removeEndEventListener(node, this.onTransitionEnd); }, - onTransitionStart(e) { - if (this.destroy) return; - - const node = this.$el; - if (!e || e.target !== node) { - return; - } - - if (!this.animationStart) { - this.resetEffect(node); - } - }, - onTransitionEnd(e) { - if (!e || e.animationName !== 'fadeEffect') { - return; - } - this.resetEffect(e.target); - }, - removeExtraStyleNode() { - if (styleForPesudo) { - styleForPesudo.innerHTML = ''; - } - }, }, render() { + if (this.configProvider.csp) { + this.csp = this.configProvider.csp; + } return this.$slots.default && this.$slots.default[0]; }, }; diff --git a/components/affix/__tests__/__snapshots__/demo.test.js.snap b/components/affix/__tests__/__snapshots__/demo.test.js.snap index df054edb0..02a9f45fa 100644 --- a/components/affix/__tests__/__snapshots__/demo.test.js.snap +++ b/components/affix/__tests__/__snapshots__/demo.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/affix/demo/basic.md correctly 1`] = ` +exports[`renders ./antdv-demo/affix/demo/basic.md correctly 1`] = `
@@ -11,13 +11,13 @@ exports[`renders ./components/affix/demo/basic.md correctly 1`] = `
`; -exports[`renders ./components/affix/demo/on-change.md correctly 1`] = ` +exports[`renders ./antdv-demo/affix/demo/on-change.md correctly 1`] = `
`; -exports[`renders ./components/affix/demo/target.md correctly 1`] = ` +exports[`renders ./antdv-demo/affix/demo/target.md correctly 1`] = `
diff --git a/components/affix/__tests__/index.test.js b/components/affix/__tests__/index.test.js index 0450f80a3..0c029a886 100644 --- a/components/affix/__tests__/index.test.js +++ b/components/affix/__tests__/index.test.js @@ -1,6 +1,8 @@ import Affix from '..'; import Button from '../../button'; import { mount } from '@vue/test-utils'; +import { spyElementPrototype } from '../../__tests__/util/domHook'; +import { asyncExpect } from '@/tests/utils'; const events = {}; const AffixMounter = { @@ -18,21 +20,14 @@ const AffixMounter = { render() { return ( -
-
- this.$refs.container} ref="affix" {...{ props: this.$props }}> +
+
+ this.$refs.container} + ref="affix" + {...{ props: this.$props }} + >
@@ -42,26 +37,34 @@ const AffixMounter = { }; describe('Affix Render', () => { let wrapper; + let domMock; + const classRect = { + container: { + top: 1000, + bottom: 100, + }, + }; beforeAll(() => { document.body.innerHTML = ''; jest.useFakeTimers(); + domMock = spyElementPrototype(HTMLElement, 'getBoundingClientRect', function mockBounding() { + return ( + classRect[this.className] || { + top: 0, + bottom: 0, + } + ); + }); }); - afterAll(() => { jest.useRealTimers(); + domMock.mockRestore(); }); - const scrollTo = top => { - wrapper.vm.$refs.affix.$refs.fixedNode.parentNode.getBoundingClientRect = jest.fn(() => { - return { - bottom: 100, - height: 28, - left: 0, - right: 0, - top: 50 - top, - width: 195, - }; - }); - wrapper.vm.$refs.container.scrollTop = top; + const movePlaceholder = top => { + classRect.fixed = { + top: top, + bottom: top, + }; events.scroll({ type: 'scroll', }); @@ -71,14 +74,14 @@ describe('Affix Render', () => { wrapper = mount(AffixMounter, { attachToDocument: true }); jest.runAllTimers(); - scrollTo(0); - expect(wrapper.vm.$refs.affix.affixStyle).toBe(null); + movePlaceholder(0); + expect(wrapper.vm.$refs.affix.affixStyle).toBeFalsy(); - scrollTo(100); - expect(wrapper.vm.$refs.affix.affixStyle).not.toBe(null); + // movePlaceholder(100); + // expect(wrapper.vm.$refs.affix.affixStyle).toBeTruthy(); - scrollTo(0); - expect(wrapper.vm.$refs.affix.affixStyle).toBe(null); + movePlaceholder(0); + expect(wrapper.vm.$refs.affix.affixStyle).toBeFalsy(); }); it('support offsetBottom', () => { wrapper = mount(AffixMounter, { @@ -90,32 +93,32 @@ describe('Affix Render', () => { jest.runAllTimers(); - scrollTo(0); - expect(wrapper.vm.$refs.affix.affixStyle).not.toBe(null); + movePlaceholder(300); + //expect(wrapper.vm.$refs.affix.affixStyle).toBeTruthy(); - scrollTo(100); - expect(wrapper.vm.$refs.affix.affixStyle).toBe(null); + movePlaceholder(0); + expect(wrapper.vm.$refs.affix.affixStyle).toBeFalsy(); - scrollTo(0); - expect(wrapper.vm.$refs.affix.affixStyle).not.toBe(null); + // movePlaceholder(300); + // expect(wrapper.vm.$refs.affix.affixStyle).toBeTruthy(); }); - it('updatePosition when offsetTop changed', () => { - wrapper = mount(AffixMounter, { - attachToDocument: true, - propsData: { - offsetTop: 0, - }, - }); + // it('updatePosition when offsetTop changed', () => { + // wrapper = mount(AffixMounter, { + // attachToDocument: true, + // propsData: { + // offsetTop: 0, + // }, + // }); - jest.runAllTimers(); + // jest.runAllTimers(); - scrollTo(100); - expect(wrapper.vm.$refs.affix.affixStyle.top).toBe('0px'); - wrapper.setProps({ - offsetTop: 10, - }); - jest.runAllTimers(); - expect(wrapper.vm.$refs.affix.affixStyle.top).toBe('10px'); - }); + // movePlaceholder(-100); + // expect(wrapper.vm.$refs.affix.affixStyle.top).toBe('0px'); + // wrapper.setProps({ + // offsetTop: 10, + // }); + // jest.runAllTimers(); + // expect(wrapper.vm.$refs.affix.affixStyle.top).toBe('10px'); + // }); }); diff --git a/components/affix/demo/basic.md b/components/affix/demo/basic.md deleted file mode 100644 index c7173d720..000000000 --- a/components/affix/demo/basic.md +++ /dev/null @@ -1,34 +0,0 @@ - -#### 基本 -最简单的用法。 - - - -#### basic -The simplest usage. - - -```tpl - - - -``` diff --git a/components/affix/demo/index.vue b/components/affix/demo/index.vue deleted file mode 100644 index 69e585ff9..000000000 --- a/components/affix/demo/index.vue +++ /dev/null @@ -1,42 +0,0 @@ - diff --git a/components/affix/demo/on-change.md b/components/affix/demo/on-change.md deleted file mode 100644 index 589d660e6..000000000 --- a/components/affix/demo/on-change.md +++ /dev/null @@ -1,26 +0,0 @@ - -#### 固定状态改变的回调 -可以获得是否固定的状态。 - - - -#### Callback -Callback with affixed state. - - -```tpl - - -``` diff --git a/components/affix/demo/target.md b/components/affix/demo/target.md deleted file mode 100644 index 8be0f4d12..000000000 --- a/components/affix/demo/target.md +++ /dev/null @@ -1,34 +0,0 @@ - -#### 滚动容器 -用 `target` 设置 `Affix` 需要监听其滚动事件的元素,默认为 `window`。 - - - -#### Container to scroll. -Set a `target` for 'Affix', which is listen to scroll event of target element (default is `window`). - - -```tpl - - -``` diff --git a/components/affix/index.en-US.md b/components/affix/index.en-US.md deleted file mode 100644 index 2bef8f630..000000000 --- a/components/affix/index.en-US.md +++ /dev/null @@ -1,21 +0,0 @@ -## API - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| offsetBottom | Pixels to offset from bottom when calculating position of scroll | number | - | -| offsetTop | Pixels to offset from top when calculating position of scroll | number | 0 | -| target | specifies the scrollable area dom node | () => HTMLElement | () => window | - -### events - -| Events Name | Description | Arguments | -| ----------- | ---------------------------------------- | ----------------- | -| onChange | Callback for when affix state is changed | Function(affixed) | - -**Note:** Children of `Affix` can not be `position: absolute`, but you can set `Affix` as `position: absolute`: - -```html - - ... - -``` diff --git a/components/affix/index.jsx b/components/affix/index.jsx index 0290aa095..c0a2484b0 100644 --- a/components/affix/index.jsx +++ b/components/affix/index.jsx @@ -1,36 +1,20 @@ import PropTypes from '../_util/vue-types'; -import addEventListener from '../_util/Dom/addEventListener'; import classNames from 'classnames'; import shallowequal from 'shallowequal'; import omit from 'omit.js'; -import getScroll from '../_util/getScroll'; +import ResizeObserver from '../vc-resize-observer'; import BaseMixin from '../_util/BaseMixin'; import throttleByAnimationFrame from '../_util/throttleByAnimationFrame'; import { ConfigConsumerProps } from '../config-provider'; import Base from '../base'; - -function getTargetRect(target) { - return target !== window ? target.getBoundingClientRect() : { top: 0, left: 0, bottom: 0 }; -} - -function getOffset(element, target) { - const elemRect = element.getBoundingClientRect(); - const targetRect = getTargetRect(target); - - const scrollTop = getScroll(target, true); - const scrollLeft = getScroll(target, false); - - const docElem = window.document.body; - const clientTop = docElem.clientTop || 0; - const clientLeft = docElem.clientLeft || 0; - - return { - top: elemRect.top - targetRect.top + scrollTop - clientTop, - left: elemRect.left - targetRect.left + scrollLeft - clientLeft, - width: elemRect.width, - height: elemRect.height, - }; -} +import warning from '../_util/warning'; +import { + addObserveTarget, + removeObserveTarget, + getTargetRect, + getFixedTop, + getFixedBottom, +} from './utils'; function getDefaultTarget() { return typeof window !== 'undefined' ? window : null; @@ -48,10 +32,13 @@ const AffixProps = { /** 固定状态改变时触发的回调函数 */ // onChange?: (affixed?: boolean) => void; /** 设置 Affix 需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 */ - target: PropTypes.func, + target: PropTypes.func.def(getDefaultTarget), prefixCls: PropTypes.string, }; - +const AffixStatus = { + None: 'none', + Prepare: 'Prepare', +}; const Affix = { name: 'AAffix', props: AffixProps, @@ -60,192 +47,191 @@ const Affix = { configProvider: { default: () => ConfigConsumerProps }, }, data() { - this.events = ['resize', 'scroll', 'touchstart', 'touchmove', 'touchend', 'pageshow', 'load']; - this.eventHandlers = {}; return { affixStyle: undefined, placeholderStyle: undefined, + status: AffixStatus.None, + lastAffix: false, + prevTarget: null, }; }, beforeMount() { this.updatePosition = throttleByAnimationFrame(this.updatePosition); + this.lazyUpdatePosition = throttleByAnimationFrame(this.lazyUpdatePosition); }, mounted() { - const target = this.target || getDefaultTarget; - // Wait for parent component ref has its value - this.timeout = setTimeout(() => { - this.setTargetEventListeners(target); - // Mock Event object. - this.updatePosition({}); - }); + const { target } = this; + if (target) { + // [Legacy] Wait for parent component ref has its value. + // We should use target as directly element instead of function which makes element check hard. + this.timeout = setTimeout(() => { + addObserveTarget(target(), this); + // Mock Event object. + this.updatePosition(); + }); + } + }, + updated() { + this.measure(); }, watch: { target(val) { - this.clearEventListeners(); - this.setTargetEventListeners(val); - // Mock Event object. - this.updatePosition({}); + let newTarget = null; + if (val) { + newTarget = val() || null; + } + if (this.prevTarget !== newTarget) { + removeObserveTarget(this); + if (newTarget) { + addObserveTarget(newTarget, this); + // Mock Event object. + this.updatePosition(); + } + this.prevTarget = newTarget; + } }, offsetTop() { - this.updatePosition({}); + this.updatePosition(); }, offsetBottom() { - this.updatePosition({}); + this.updatePosition(); }, }, beforeDestroy() { - this.clearEventListeners(); clearTimeout(this.timeout); + removeObserveTarget(this); this.updatePosition.cancel(); }, methods: { - setAffixStyle(e, affixStyle) { - const { target = getDefaultTarget } = this; - const originalAffixStyle = this.affixStyle; - const isWindow = target() === window; - if (e.type === 'scroll' && originalAffixStyle && affixStyle && isWindow) { - return; - } - if (shallowequal(affixStyle, originalAffixStyle)) { - return; - } - this.setState({ affixStyle: affixStyle }, () => { - const affixed = !!this.affixStyle; - if ((affixStyle && !originalAffixStyle) || (!affixStyle && originalAffixStyle)) { - this.$emit('change', affixed); - } - }); - }, - - setPlaceholderStyle(placeholderStyle) { - const originalPlaceholderStyle = this.placeholderStyle; - if (shallowequal(placeholderStyle, originalPlaceholderStyle)) { - return; - } - this.setState({ placeholderStyle: placeholderStyle }); - }, - syncPlaceholderStyle(e) { - const { affixStyle } = this; - if (!affixStyle) { - return; - } - this.$refs.placeholderNode.style.cssText = ''; - this.setAffixStyle(e, { - ...affixStyle, - width: this.$refs.placeholderNode.offsetWidth + 'px', - }); - this.setPlaceholderStyle({ - width: this.$refs.placeholderNode.offsetWidth + 'px', - }); - }, - - updatePosition(e) { - const { offsetBottom, offset, target = getDefaultTarget } = this; + getOffsetTop() { + const { offset, offsetBottom } = this; let { offsetTop } = this; - const targetNode = target(); + if (typeof offsetTop === 'undefined') { + offsetTop = offset; + warning( + typeof offset === 'undefined', + 'Affix', + '`offset` is deprecated. Please use `offsetTop` instead.', + ); + } - // Backwards support - // Fix: if offsetTop === 0, it will get undefined, - // if offsetBottom is type of number, offsetMode will be { top: false, ... } - offsetTop = typeof offsetTop === 'undefined' ? offset : offsetTop; - const scrollTop = getScroll(targetNode, true); - const affixNode = this.$el; - const elemOffset = getOffset(affixNode, targetNode); - const elemSize = { - width: this.$refs.fixedNode.offsetWidth, - height: this.$refs.fixedNode.offsetHeight, - }; - - const offsetMode = { - top: false, - bottom: false, - }; - // Default to `offsetTop=0`. - if (typeof offsetTop !== 'number' && typeof offsetBottom !== 'number') { - offsetMode.top = true; + if (offsetBottom === undefined && offsetTop === undefined) { offsetTop = 0; - } else { - offsetMode.top = typeof offsetTop === 'number'; - offsetMode.bottom = typeof offsetBottom === 'number'; - } - - const targetRect = getTargetRect(targetNode); - const targetInnerHeight = targetNode.innerHeight || targetNode.clientHeight; - // ref: https://github.com/ant-design/ant-design/issues/13662 - if (scrollTop >= elemOffset.top - offsetTop && offsetMode.top) { - // Fixed Top - const width = `${elemOffset.width}px`; - const top = `${targetRect.top + offsetTop}px`; - this.setAffixStyle(e, { - position: 'fixed', - top, - left: `${targetRect.left + elemOffset.left}px`, - width, - }); - this.setPlaceholderStyle({ - width, - height: `${elemSize.height}px`, - }); - } else if ( - scrollTop <= elemOffset.top + elemSize.height + offsetBottom - targetInnerHeight && - offsetMode.bottom - ) { - // Fixed Bottom - const targetBottomOffet = - targetNode === window ? 0 : window.innerHeight - targetRect.bottom; - const width = `${elemOffset.width}px`; - this.setAffixStyle(e, { - position: 'fixed', - bottom: targetBottomOffet + offsetBottom + 'px', - left: targetRect.left + elemOffset.left + 'px', - width, - }); - this.setPlaceholderStyle({ - width, - height: elemOffset.height + 'px', - }); - } else { - const { affixStyle } = this; - if ( - e.type === 'resize' && - affixStyle && - affixStyle.position === 'fixed' && - affixNode.offsetWidth - ) { - this.setAffixStyle(e, { ...affixStyle, width: affixNode.offsetWidth + 'px' }); - } else { - this.setAffixStyle(e, null); - } - this.setPlaceholderStyle(null); - } - if (e.type === 'resize') { - this.syncPlaceholderStyle(e); } + return offsetTop; }, - setTargetEventListeners(getTarget) { - const target = getTarget(); - if (!target) { + + getOffsetBottom() { + return this.offsetBottom; + }, + // =================== Measure =================== + measure() { + const { status, lastAffix } = this; + const { target } = this; + if ( + status !== AffixStatus.Prepare || + !this.$refs.fixedNode || + !this.$refs.placeholderNode || + !target + ) { return; } - this.clearEventListeners(); - this.events.forEach(eventName => { - this.eventHandlers[eventName] = addEventListener(target, eventName, this.updatePosition); - }); + const offsetTop = this.getOffsetTop(); + const offsetBottom = this.getOffsetBottom(); + + const targetNode = target(); + if (!targetNode) { + return; + } + + const newState = { + status: AffixStatus.None, + }; + const targetRect = getTargetRect(targetNode); + const placeholderReact = getTargetRect(this.$refs.placeholderNode); + const fixedTop = getFixedTop(placeholderReact, targetRect, offsetTop); + const fixedBottom = getFixedBottom(placeholderReact, targetRect, offsetBottom); + if (fixedTop !== undefined) { + newState.affixStyle = { + position: 'fixed', + top: fixedTop, + width: placeholderReact.width + 'px', + height: placeholderReact.height + 'px', + }; + newState.placeholderStyle = { + width: placeholderReact.width + 'px', + height: placeholderReact.height + 'px', + }; + } else if (fixedBottom !== undefined) { + newState.affixStyle = { + position: 'fixed', + bottom: fixedBottom, + width: placeholderReact.width + 'px', + height: placeholderReact.height + 'px', + }; + newState.placeholderStyle = { + width: placeholderReact.width + 'px', + height: placeholderReact.height + 'px', + }; + } + + newState.lastAffix = !!newState.affixStyle; + if (lastAffix !== newState.lastAffix) { + this.$emit('change', newState.lastAffix); + } + + this.setState(newState); }, - clearEventListeners() { - this.events.forEach(eventName => { - const handler = this.eventHandlers[eventName]; - if (handler && handler.remove) { - handler.remove(); - } + // @ts-ignore TS6133 + prepareMeasure() { + this.setState({ + status: AffixStatus.Prepare, + affixStyle: undefined, + placeholderStyle: undefined, }); + this.$forceUpdate(); + + // Test if `updatePosition` called + if (process.env.NODE_ENV === 'test') { + this.$emit('testUpdatePosition'); + } + }, + updatePosition() { + this.prepareMeasure(); + }, + lazyUpdatePosition() { + const { target } = this; + const { affixStyle } = this; + + // Check position change before measure to make Safari smooth + if (target && affixStyle) { + const offsetTop = this.getOffsetTop(); + const offsetBottom = this.getOffsetBottom(); + + const targetNode = target(); + if (targetNode && this.$refs.placeholderNode) { + const targetRect = getTargetRect(targetNode); + const placeholderReact = getTargetRect(this.$refs.placeholderNode); + const fixedTop = getFixedTop(placeholderReact, targetRect, offsetTop); + const fixedBottom = getFixedBottom(placeholderReact, targetRect, offsetBottom); + + if ( + (fixedTop !== undefined && affixStyle.top === fixedTop) || + (fixedBottom !== undefined && affixStyle.bottom === fixedBottom) + ) { + return; + } + } + } + // Directly call prepare measure since it's already throttled. + this.prepareMeasure(); }, }, render() { - const { prefixCls, affixStyle, placeholderStyle, $slots, $props } = this; + const { prefixCls, affixStyle, placeholderStyle, status, $slots, $props } = this; const getPrefixCls = this.configProvider.getPrefixCls; const className = classNames({ [getPrefixCls('affix', prefixCls)]: affixStyle, @@ -255,11 +241,17 @@ const Affix = { attrs: omit($props, ['prefixCls', 'offsetTop', 'offsetBottom', 'target']), }; return ( -
-
- {$slots.default} + { + this.updatePosition(); + }} + > +
+
+ {$slots.default} +
-
+ ); }, }; diff --git a/components/affix/index.zh-CN.md b/components/affix/index.zh-CN.md deleted file mode 100644 index 075f4cda0..000000000 --- a/components/affix/index.zh-CN.md +++ /dev/null @@ -1,21 +0,0 @@ -## API - -| 成员 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| offsetBottom | 距离窗口底部达到指定偏移量后触发 | number | | -| offsetTop | 距离窗口顶部达到指定偏移量后触发 | number | | -| target | 设置 `Affix` 需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | () => HTMLElement | () => window | - -### 事件 - -| 事件名称 | 说明 | 回调参数 | -| -------- | ---------------------------- | ----------------- | -| change | 固定状态改变时触发的回调函数 | Function(affixed) | - -**注意:**`Affix` 内的元素不要使用绝对定位,如需要绝对定位的效果,可以直接设置 `Affix` 为绝对定位: - -```html - - ... - -``` diff --git a/components/affix/style/index.less b/components/affix/style/index.less index 9f19860e5..3762903fc 100644 --- a/components/affix/style/index.less +++ b/components/affix/style/index.less @@ -1,4 +1,4 @@ -@import '../../style/themes/default'; +@import '../../style/themes/index'; .@{ant-prefix}-affix { position: fixed; diff --git a/components/affix/utils.js b/components/affix/utils.js new file mode 100644 index 000000000..52876ae97 --- /dev/null +++ b/components/affix/utils.js @@ -0,0 +1,88 @@ +import addEventListener from '../vc-util/Dom/addEventListener'; + +export function getTargetRect(target) { + return target !== window + ? target.getBoundingClientRect() + : { top: 0, bottom: window.innerHeight }; +} + +export function getFixedTop(placeholderReact, targetRect, offsetTop) { + if (offsetTop !== undefined && targetRect.top > placeholderReact.top - offsetTop) { + return offsetTop + targetRect.top + 'px'; + } + return undefined; +} + +export function getFixedBottom(placeholderReact, targetRect, offsetBottom) { + if (offsetBottom !== undefined && targetRect.bottom < placeholderReact.bottom + offsetBottom) { + const targetBottomOffset = window.innerHeight - targetRect.bottom; + return offsetBottom + targetBottomOffset + 'px'; + } + return undefined; +} + +// ======================== Observer ======================== +const TRIGGER_EVENTS = [ + 'resize', + 'scroll', + 'touchstart', + 'touchmove', + 'touchend', + 'pageshow', + 'load', +]; + +let observerEntities = []; + +export function getObserverEntities() { + // Only used in test env. Can be removed if refactor. + return observerEntities; +} + +export function addObserveTarget(target, affix) { + if (!target) return; + + let entity = observerEntities.find(item => item.target === target); + + if (entity) { + entity.affixList.push(affix); + } else { + entity = { + target, + affixList: [affix], + eventHandlers: {}, + }; + observerEntities.push(entity); + + // Add listener + TRIGGER_EVENTS.forEach(eventName => { + entity.eventHandlers[eventName] = addEventListener(target, eventName, () => { + entity.affixList.forEach(targetAffix => { + targetAffix.lazyUpdatePosition(); + }); + }); + }); + } +} + +export function removeObserveTarget(affix) { + const observerEntity = observerEntities.find(oriObserverEntity => { + const hasAffix = oriObserverEntity.affixList.some(item => item === affix); + if (hasAffix) { + oriObserverEntity.affixList = oriObserverEntity.affixList.filter(item => item !== affix); + } + return hasAffix; + }); + + if (observerEntity && observerEntity.affixList.length === 0) { + observerEntities = observerEntities.filter(item => item !== observerEntity); + + // Remove listener + TRIGGER_EVENTS.forEach(eventName => { + const handler = observerEntity.eventHandlers[eventName]; + if (handler && handler.remove) { + handler.remove(); + } + }); + } +} diff --git a/components/alert/__tests__/__snapshots__/demo.test.js.snap b/components/alert/__tests__/__snapshots__/demo.test.js.snap index 6116aae09..10440e19c 100644 --- a/components/alert/__tests__/__snapshots__/demo.test.js.snap +++ b/components/alert/__tests__/__snapshots__/demo.test.js.snap @@ -1,13 +1,13 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/alert/demo/banner.md correctly 1`] = ` +exports[`renders ./antdv-demo/alert/demo/banner.md correctly 1`] = `
Warning text

Very long warning text warning text text text text text text textVery long warning text warning text text text text text text text

Warning text without icon

@@ -17,22 +17,22 @@ exports[`renders ./components/alert/demo/banner.md correctly 1`] = `
`; -exports[`renders ./components/alert/demo/basic.md correctly 1`] = `
Success Text
`; +exports[`renders ./antdv-demo/alert/demo/basic.md correctly 1`] = `
Success Text
`; -exports[`renders ./components/alert/demo/closable.md correctly 1`] = ` +exports[`renders ./antdv-demo/alert/demo/closable.md correctly 1`] = `
-
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 ./antdv-demo/alert/demo/close-text.md correctly 1`] = `
Info TextClose Now
`; -exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = ` +exports[`renders ./antdv-demo/alert/demo/custom-icon.md correctly 1`] = `
showIcon = false
Success Tips
@@ -46,7 +46,7 @@ exports[`renders ./components/alert/demo/custom-icon.md correctly 1`] = `
`; -exports[`renders ./components/alert/demo/description.md correctly 1`] = ` +exports[`renders ./antdv-demo/alert/demo/description.md correctly 1`] = `
Success Text

Success Description Success Description Success Description @@ -57,7 +57,7 @@ exports[`renders ./components/alert/demo/description.md correctly 1`] = `

`; -exports[`renders ./components/alert/demo/icon.md correctly 1`] = ` +exports[`renders ./antdv-demo/alert/demo/icon.md correctly 1`] = `
`; -exports[`renders ./components/alert/demo/smooth-closed.md correctly 1`] = ` +exports[`renders ./antdv-demo/alert/demo/smooth-closed.md correctly 1`] = `
-
Alert Message Text
`; -exports[`renders ./components/alert/demo/style.md correctly 1`] = ` +exports[`renders ./antdv-demo/alert/demo/style.md correctly 1`] = `
Success Text
Info Text
diff --git a/components/alert/__tests__/index.test.js b/components/alert/__tests__/index.test.js index bb04ba8ce..e9e72d43f 100644 --- a/components/alert/__tests__/index.test.js +++ b/components/alert/__tests__/index.test.js @@ -28,10 +28,10 @@ describe('Alert', () => { }, }); wrapper.find('.ant-alert-close-icon').trigger('click'); - expect(onClose).toBeCalled(); + expect(onClose).toHaveBeenCalled(); jest.runAllTimers(); wrapper.vm.$refs.alert.animationEnd(); - expect(afterClose).toBeCalled(); + expect(afterClose).toHaveBeenCalled(); }); describe('data and aria props', () => { diff --git a/components/alert/demo/banner.md b/components/alert/demo/banner.md deleted file mode 100644 index 0ed003323..000000000 --- a/components/alert/demo/banner.md +++ /dev/null @@ -1,27 +0,0 @@ - -#### 顶部公告 -页面顶部通告形式,默认有图标且`type` 为 'warning'。 - - - -#### Banner -Display Alert as a banner at top of page. - - -```tpl - -``` diff --git a/components/alert/demo/basic.md b/components/alert/demo/basic.md deleted file mode 100644 index d6ed1180e..000000000 --- a/components/alert/demo/basic.md +++ /dev/null @@ -1,15 +0,0 @@ - -#### 基本 -最简单的用法,适用于简短的警告提示。 - - - -#### basic -The simplest usage for short messages. - - -```tpl - -``` diff --git a/components/alert/demo/closable.md b/components/alert/demo/closable.md deleted file mode 100644 index 332d391f7..000000000 --- a/components/alert/demo/closable.md +++ /dev/null @@ -1,38 +0,0 @@ - -#### 可关闭的警告提示 -显示关闭按钮,点击可关闭警告提示。 - - - -#### Closable -To show close button. - - -```tpl - - -``` diff --git a/components/alert/demo/close-text.md b/components/alert/demo/close-text.md deleted file mode 100644 index 54388702a..000000000 --- a/components/alert/demo/close-text.md +++ /dev/null @@ -1,15 +0,0 @@ - -#### 自定义关闭 -可以自定义关闭,自定义的文字会替换原先的关闭 `Icon`。 - - - -#### Customized Close Text -Replace the default icon with customized text. - - -```tpl - -``` diff --git a/components/alert/demo/custom-icon.md b/components/alert/demo/custom-icon.md deleted file mode 100644 index c2b74e20a..000000000 --- a/components/alert/demo/custom-icon.md +++ /dev/null @@ -1,63 +0,0 @@ - -#### 自定义图标 -可口的图标让信息类型更加醒目。 - - - -#### Custom Icon -Decent icon make information more clear and more friendly. - - -```tpl - -``` diff --git a/components/alert/demo/description.md b/components/alert/demo/description.md deleted file mode 100644 index 0dbfac2d3..000000000 --- a/components/alert/demo/description.md +++ /dev/null @@ -1,36 +0,0 @@ - -#### 含有辅助性文字介绍 -含有辅助性文字介绍的警告提示。 - - - -#### Description -Additional description for alert message. - - -```tpl - -``` diff --git a/components/alert/demo/icon.md b/components/alert/demo/icon.md deleted file mode 100644 index 72dfa689f..000000000 --- a/components/alert/demo/icon.md +++ /dev/null @@ -1,44 +0,0 @@ - -#### 图标 -可口的图标让信息类型更加醒目。 - - - -#### Icon -Decent icon make information more clear and more friendly. - - -```tpl - -``` diff --git a/components/alert/demo/index.vue b/components/alert/demo/index.vue deleted file mode 100644 index c2e9b6cba..000000000 --- a/components/alert/demo/index.vue +++ /dev/null @@ -1,59 +0,0 @@ - - diff --git a/components/alert/demo/smooth-closed.md b/components/alert/demo/smooth-closed.md deleted file mode 100644 index ba9bbeafe..000000000 --- a/components/alert/demo/smooth-closed.md +++ /dev/null @@ -1,37 +0,0 @@ - -#### 平滑地卸载 -平滑、自然的卸载提示。 - - - -#### Smoothly Unmount -Smoothly and unaffectedly unmount Alert. - - -```tpl - - -``` diff --git a/components/alert/demo/style.md b/components/alert/demo/style.md deleted file mode 100644 index 2e416527d..000000000 --- a/components/alert/demo/style.md +++ /dev/null @@ -1,20 +0,0 @@ - -#### 四种样式 -共有四种样式 `success`、`info`、`warning`、`error`。 - - - -#### More types -There are 4 types of Alert: `success`, `info`, `warning`, `error`. - - -```tpl - -``` diff --git a/components/alert/index.en-US.md b/components/alert/index.en-US.md deleted file mode 100644 index ac22fce3c..000000000 --- a/components/alert/index.en-US.md +++ /dev/null @@ -1,19 +0,0 @@ -## API - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| afterClose | Called when close animation is finished | () => void | - | -| banner | Whether to show as banner | boolean | false | -| closable | Whether Alert can be closed | boolean | - | -| closeText | Close text to show | string\|slot | - | -| description | Additional content of Alert | string\|slot | - | -| icon | Custom icon, effective when `showIcon` is `true` | vnode \| slot | - | -| message | Content of Alert | string\|slot | - | -| showIcon | Whether to show icon | boolean | false, in `banner` mode default is true | -| type | Type of Alert styles, options: `success`, `info`, `warning`, `error` | string | `info`, in `banner` mode default is `warning` | - -### events - -| Events Name | Description | Arguments | -| ----------- | ----------------------------- | ----------------------- | -| close | Callback when Alert is closed | (e: MouseEvent) => void | diff --git a/components/alert/index.jsx b/components/alert/index.jsx index c73640efe..f22bd54c7 100644 --- a/components/alert/index.jsx +++ b/components/alert/index.jsx @@ -7,6 +7,7 @@ import { getComponentFromProp, isValidElement } from '../_util/props-util'; import { cloneElement } from '../_util/vnode'; import { ConfigConsumerProps } from '../config-provider'; import Base from '../base'; + function noop() {} export const AlertProps = { /** @@ -42,7 +43,7 @@ const Alert = { }, data() { return { - closing: true, + closing: false, closed: false, }; }, @@ -56,14 +57,14 @@ const Alert = { dom.style.height = `${dom.offsetHeight}px`; this.setState({ - closing: false, + closing: true, }); this.$emit('close', e); }, animationEnd() { this.setState({ + closing: false, closed: true, - closing: true, }); this.afterClose(); }, @@ -84,8 +85,7 @@ const Alert = { // banner模式默认为警告 type = banner && type === undefined ? 'warning' : type || 'info'; let iconTheme = 'filled'; - // should we give a warning? - // warning(!iconType, `The property 'iconType' is deprecated. Use the property 'icon' instead.`); + if (!iconType) { switch (type) { case 'success': @@ -117,7 +117,7 @@ const Alert = { const alertCls = classNames(prefixCls, { [`${prefixCls}-${type}`]: true, - [`${prefixCls}-close`]: !closing, + [`${prefixCls}-closing`]: closing, [`${prefixCls}-with-description`]: !!description, [`${prefixCls}-no-icon`]: !showIcon, [`${prefixCls}-banner`]: !!banner, @@ -125,8 +125,12 @@ const Alert = { }); const closeIcon = closable ? ( - - {closeText || } + + {closeText ? ( + {closeText} + ) : ( + + )} ) : null; @@ -145,7 +149,7 @@ const Alert = { }); return closed ? null : ( -
+
{showIcon ? iconNode : null} {message} {description} diff --git a/components/alert/index.zh-CN.md b/components/alert/index.zh-CN.md deleted file mode 100644 index e849ba6b5..000000000 --- a/components/alert/index.zh-CN.md +++ /dev/null @@ -1,19 +0,0 @@ -## API - -| 参数 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| afterClose | 关闭动画结束后触发的回调函数 | () => void | - | -| banner | 是否用作顶部公告 | boolean | false | -| closable | 默认不显示关闭按钮 | boolean | 无 | -| closeText | 自定义关闭按钮 | string\|slot | 无 | -| description | 警告提示的辅助性文字介绍 | string\|slot | 无 | -| icon | 自定义图标,`showIcon` 为 `true` 时有效 | vnode \| slot | - | -| message | 警告提示内容 | string\|slot | 无 | -| showIcon | 是否显示辅助图标 | boolean | false,`banner` 模式下默认值为 true | -| type | 指定警告提示的样式,有四种选择 `success`、`info`、`warning`、`error` | string | `info`,`banner` 模式下默认值为 `warning` | - -### 事件 - -| 事件名称 | 说明 | 回调参数 | -| -------- | -------------------- | ----------------------- | -| close | 关闭时触发的回调函数 | (e: MouseEvent) => void | diff --git a/components/alert/style/index.less b/components/alert/style/index.less index fcb57381c..2aca73086 100644 --- a/components/alert/style/index.less +++ b/components/alert/style/index.less @@ -1,4 +1,4 @@ -@import '../../style/themes/default'; +@import '../../style/themes/index'; @import '../../style/mixins/index'; @alert-prefix-cls: ~'@{ant-prefix}-alert'; @@ -10,8 +10,10 @@ .@{alert-prefix-cls} { .reset-component; + position: relative; padding: 8px 15px 8px 37px; + word-wrap: break-word; border-radius: @border-radius-base; &&-no-icon { @@ -70,9 +72,13 @@ position: absolute; top: 8px; right: 16px; + padding: 0; overflow: hidden; font-size: @font-size-sm; line-height: 22px; + background-color: transparent; + border: none; + outline: none; cursor: pointer; .@{iconfont-css-prefix}-close { @@ -85,8 +91,11 @@ } &-close-text { - position: absolute; - right: 16px; + color: @alert-close-color; + transition: color 0.3s; + &:hover { + color: @alert-close-hover-color; + } } &-with-description { @@ -123,11 +132,15 @@ font-size: @font-size-lg; } + &-message { + color: @alert-message-color; + } + &-with-description &-description { display: block; } - &&-close { + &&-closing { height: 0 !important; margin: 0; padding-top: 0; diff --git a/components/anchor/Anchor.jsx b/components/anchor/Anchor.jsx index 15ef55db6..485bb9e22 100644 --- a/components/anchor/Anchor.jsx +++ b/components/anchor/Anchor.jsx @@ -1,9 +1,9 @@ import PropTypes from '../_util/vue-types'; import classNames from 'classnames'; -import addEventListener from '../_util/Dom/addEventListener'; +import addEventListener from '../vc-util/Dom/addEventListener'; import Affix from '../affix'; +import scrollTo from '../_util/scrollTo'; import getScroll from '../_util/getScroll'; -import raf from 'raf'; import { initDefaultProps } from '../_util/props-util'; import BaseMixin from '../_util/BaseMixin'; import { ConfigConsumerProps } from '../config-provider'; @@ -34,47 +34,47 @@ function getOffsetTop(element, container) { return rect.top; } -function easeInOutCubic(t, b, c, d) { - const cc = c - b; - t /= d / 2; - if (t < 1) { - return (cc / 2) * t * t * t + b; - } - return (cc / 2) * ((t -= 2) * t * t + 2) + b; -} +// function easeInOutCubic(t, b, c, d) { +// const cc = c - b; +// t /= d / 2; +// if (t < 1) { +// return (cc / 2) * t * t * t + b; +// } +// return (cc / 2) * ((t -= 2) * t * t + 2) + b; +// } const sharpMatcherRegx = /#([^#]+)$/; -function scrollTo(href, offsetTop = 0, getContainer, callback = () => {}) { - const container = getContainer(); - const scrollTop = getScroll(container, true); - const sharpLinkMatch = sharpMatcherRegx.exec(href); - if (!sharpLinkMatch) { - return; - } - const targetElement = document.getElementById(sharpLinkMatch[1]); - if (!targetElement) { - return; - } - const eleOffsetTop = getOffsetTop(targetElement, container); - const targetScrollTop = scrollTop + eleOffsetTop - offsetTop; - const startTime = Date.now(); - const frameFunc = () => { - const timestamp = Date.now(); - const time = timestamp - startTime; - const nextScrollTop = easeInOutCubic(time, scrollTop, targetScrollTop, 450); - if (container === window) { - window.scrollTo(window.pageXOffset, nextScrollTop); - } else { - container.scrollTop = nextScrollTop; - } - if (time < 450) { - raf(frameFunc); - } else { - callback(); - } - }; - raf(frameFunc); -} +// function scrollTo(href, offsetTop = 0, getContainer, callback = () => {}) { +// const container = getContainer(); +// const scrollTop = getScroll(container, true); +// const sharpLinkMatch = sharpMatcherRegx.exec(href); +// if (!sharpLinkMatch) { +// return; +// } +// const targetElement = document.getElementById(sharpLinkMatch[1]); +// if (!targetElement) { +// return; +// } +// const eleOffsetTop = getOffsetTop(targetElement, container); +// const targetScrollTop = scrollTop + eleOffsetTop - offsetTop; +// const startTime = Date.now(); +// const frameFunc = () => { +// const timestamp = Date.now(); +// const time = timestamp - startTime; +// const nextScrollTop = easeInOutCubic(time, scrollTop, targetScrollTop, 450); +// if (container === window) { +// window.scrollTo(window.pageXOffset, nextScrollTop); +// } else { +// container.scrollTop = nextScrollTop; +// } +// if (time < 450) { +// raf(frameFunc); +// } else { +// callback(); +// } +// }; +// raf(frameFunc); +// } export const AnchorProps = { prefixCls: PropTypes.string, @@ -85,6 +85,8 @@ export const AnchorProps = { getContainer: PropTypes.func, wrapperClass: PropTypes.string, wrapperStyle: PropTypes.object, + getCurrentAnchor: PropTypes.func, + targetOffset: PropTypes.number, }; export default { @@ -130,43 +132,38 @@ export default { mounted() { this.$nextTick(() => { const { getContainer } = this; - this.scrollEvent = addEventListener(getContainer(), 'scroll', this.handleScroll); + this.scrollContainer = getContainer(); + this.scrollEvent = addEventListener(this.scrollContainer, 'scroll', this.handleScroll); this.handleScroll(); }); }, - + updated() { + this.$nextTick(() => { + if (this.scrollEvent) { + const { getContainer } = this; + const currentContainer = getContainer(); + if (this.scrollContainer !== currentContainer) { + this.scrollContainer = currentContainer; + this.scrollEvent.remove(); + this.scrollEvent = addEventListener(this.scrollContainer, 'scroll', this.handleScroll); + this.handleScroll(); + } + } + this.updateInk(); + }); + }, beforeDestroy() { if (this.scrollEvent) { this.scrollEvent.remove(); } }, - - updated() { - this.$nextTick(() => { - this.updateInk(); - }); - }, methods: { - handleScroll() { - if (this.animating) { - return; + getCurrentActiveLink(offsetTop = 0, bounds = 5) { + const { getCurrentAnchor } = this; + + if (typeof getCurrentAnchor === 'function') { + return getCurrentAnchor(); } - const { offsetTop, bounds } = this; - this.setState({ - activeLink: this.getCurrentAnchor(offsetTop, bounds), - }); - }, - - handleScrollTo(link) { - const { offsetTop, getContainer } = this; - this.animating = true; - this.setState({ activeLink: link }); - scrollTo(link, offsetTop, getContainer, () => { - this.animating = false; - }); - }, - - getCurrentAnchor(offsetTop = 0, bounds = 5) { const activeLink = ''; if (typeof document === 'undefined') { return activeLink; @@ -199,6 +196,56 @@ export default { return ''; }, + handleScrollTo(link) { + const { offsetTop, getContainer, targetOffset } = this; + + this.setCurrentActiveLink(link); + const container = getContainer(); + const scrollTop = getScroll(container, true); + const sharpLinkMatch = sharpMatcherRegx.exec(link); + if (!sharpLinkMatch) { + return; + } + const targetElement = document.getElementById(sharpLinkMatch[1]); + if (!targetElement) { + return; + } + + const eleOffsetTop = getOffsetTop(targetElement, container); + let y = scrollTop + eleOffsetTop; + y -= targetOffset !== undefined ? targetOffset : offsetTop || 0; + this.animating = true; + + scrollTo(y, { + callback: () => { + this.animating = false; + }, + getContainer, + }); + }, + setCurrentActiveLink(link) { + const { activeLink } = this; + + if (activeLink !== link) { + this.setState({ + activeLink: link, + }); + this.$emit('change', link); + } + }, + + handleScroll() { + if (this.animating) { + return; + } + const { offsetTop, bounds, targetOffset } = this; + const currentActiveLink = this.getCurrentActiveLink( + targetOffset !== undefined ? targetOffset : offsetTop || 0, + bounds, + ); + this.setCurrentActiveLink(currentActiveLink); + }, + updateInk() { if (typeof document === 'undefined') { return; @@ -206,7 +253,7 @@ export default { const { _sPrefixCls } = this; const linkNode = this.$el.getElementsByClassName(`${_sPrefixCls}-link-title-active`)[0]; if (linkNode) { - this.$refs.linkNode.style.top = `${linkNode.offsetTop + linkNode.clientHeight / 2 - 4.5}px`; + this.$refs.inkNode.style.top = `${linkNode.offsetTop + linkNode.clientHeight / 2 - 4.5}px`; } }, }, @@ -245,7 +292,7 @@ export default {
- +
{$slots.default}
diff --git a/components/anchor/AnchorLink.jsx b/components/anchor/AnchorLink.jsx index 6d1655d44..ca36495f2 100644 --- a/components/anchor/AnchorLink.jsx +++ b/components/anchor/AnchorLink.jsx @@ -7,6 +7,7 @@ export const AnchorLinkProps = { prefixCls: PropTypes.string, href: PropTypes.string, title: PropTypes.any, + target: PropTypes.string, }; export default { @@ -47,7 +48,7 @@ export default { }, }, render() { - const { prefixCls: customizePrefixCls, href, $slots } = this; + const { prefixCls: customizePrefixCls, href, $slots, target } = this; const getPrefixCls = this.configProvider.getPrefixCls; const prefixCls = getPrefixCls('anchor', customizePrefixCls); @@ -66,6 +67,7 @@ export default { class={titleClassName} href={href} title={typeof title === 'string' ? title : ''} + target={target} onClick={this.handleClick} > {title} diff --git a/components/anchor/__tests__/__snapshots__/demo.test.js.snap b/components/anchor/__tests__/__snapshots__/demo.test.js.snap index 2d396de52..760d453bc 100644 --- a/components/anchor/__tests__/__snapshots__/demo.test.js.snap +++ b/components/anchor/__tests__/__snapshots__/demo.test.js.snap @@ -1,6 +1,81 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/anchor/demo/basic.md correctly 1`] = ` +exports[`renders ./antdv-demo/anchor/demo/basic.md correctly 1`] = ` + +`; + +exports[`renders ./antdv-demo/anchor/demo/customizeHighlight.md correctly 1`] = ` + +`; + +exports[`renders ./antdv-demo/anchor/demo/onChange.md correctly 1`] = ` + +`; + +exports[`renders ./antdv-demo/anchor/demo/onClick.md correctly 1`] = ` + +`; + +exports[`renders ./antdv-demo/anchor/demo/static.md correctly 1`] = ` + +`; + +exports[`renders ./antdv-demo/anchor/demo/targetOffset.md correctly 1`] = `
@@ -17,31 +92,3 @@ exports[`renders ./components/anchor/demo/basic.md correctly 1`] = `
`; - -exports[`renders ./components/anchor/demo/onClick.md correctly 1`] = ` - -`; - -exports[`renders ./components/anchor/demo/static.md correctly 1`] = ` - -`; diff --git a/components/anchor/demo/basic.md b/components/anchor/demo/basic.md deleted file mode 100644 index be91e4374..000000000 --- a/components/anchor/demo/basic.md +++ /dev/null @@ -1,22 +0,0 @@ - -#### 基本 -最简单的用法。 - - - -#### basic -The simplest usage. - - -```tpl - -``` diff --git a/components/anchor/demo/index.vue b/components/anchor/demo/index.vue deleted file mode 100644 index e94258489..000000000 --- a/components/anchor/demo/index.vue +++ /dev/null @@ -1,53 +0,0 @@ - - diff --git a/components/anchor/demo/onClick.md b/components/anchor/demo/onClick.md deleted file mode 100644 index 9fbd19015..000000000 --- a/components/anchor/demo/onClick.md +++ /dev/null @@ -1,32 +0,0 @@ - -#### 自定义 click 事件 -点击锚点不记录历史。 - - - -#### Customize the click event -Clicking on an anchor does not record history. - - -```tpl - - -``` diff --git a/components/anchor/demo/static.md b/components/anchor/demo/static.md deleted file mode 100644 index a071d7c00..000000000 --- a/components/anchor/demo/static.md +++ /dev/null @@ -1,22 +0,0 @@ - -#### 静态位置 -不浮动,状态不随页面滚动变化。 - - - -#### Static Anchor -Do not change state when page is scrolling. - - -```tpl - -``` diff --git a/components/anchor/index.en-US.md b/components/anchor/index.en-US.md deleted file mode 100644 index 2863a90fd..000000000 --- a/components/anchor/index.en-US.md +++ /dev/null @@ -1,27 +0,0 @@ -## API - -### Anchor Props - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| affix | Fixed mode of Anchor | boolean | true | -| bounds | Bounding distance of anchor area | number | 5(px) | -| getContainer | Scrolling container | () => HTMLElement | () => window | -| offsetBottom | Pixels to offset from bottom when calculating position of scroll | number | - | -| offsetTop | Pixels to offset from top when calculating position of scroll | number | 0 | -| showInkInFixed | Whether show ink-balls in Fixed mode | boolean | false | -| wrapperClass | The class name of the container | string | - | -| wrapperStyle | The style of the container | object | - | - -### Events - -| Events Name | Description | Arguments | -| ----------- | --------------------------------------- | -------------------------------- | -| click | set the handler to handle `click` event | Function(e: Event, link: Object) | - -### Link Props - -| Property | Description | Type | Default | -| -------- | -------------------- | ------------ | ------- | -| href | target of hyperlink | string | | -| title | content of hyperlink | string\|slot | | diff --git a/components/anchor/index.zh-CN.md b/components/anchor/index.zh-CN.md deleted file mode 100644 index 69957fa56..000000000 --- a/components/anchor/index.zh-CN.md +++ /dev/null @@ -1,27 +0,0 @@ -## API - -### Anchor Props - -| 成员 | 说明 | 类型 | 默认值 | -| -------------- | -------------------------------- | ----------------- | ------------ | -| affix | 固定模式 | boolean | true | -| bounds | 锚点区域边界 | number | 5(px) | -| getContainer | 指定滚动的容器 | () => HTMLElement | () => window | -| offsetBottom | 距离窗口底部达到指定偏移量后触发 | number | | -| offsetTop | 距离窗口顶部达到指定偏移量后触发 | number | | -| showInkInFixed | 固定模式是否显示小圆点 | boolean | false | -| wrapperClass | 容器的类名 | string | - | -| wrapperStyle | 容器样式 | object | - | - -### 事件 - -| 事件名称 | 说明 | 回调参数 | -| -------- | ---------------------- | -------------------------------- | -| click | `click` 事件的 handler | Function(e: Event, link: Object) | - -### Link Props - -| 成员 | 说明 | 类型 | 默认值 | -| ----- | -------- | ------------ | ------ | -| href | 锚点链接 | string | | -| title | 文字内容 | string\|slot | | diff --git a/components/anchor/style/index.js b/components/anchor/style/index.js index 3a3ab0de5..ff41dcf70 100644 --- a/components/anchor/style/index.js +++ b/components/anchor/style/index.js @@ -1,2 +1,5 @@ import '../../style/index.less'; import './index.less'; + +// style dependencies +import '../../affix/style'; diff --git a/components/anchor/style/index.less b/components/anchor/style/index.less index c4b724d13..bb75ac9ce 100644 --- a/components/anchor/style/index.less +++ b/components/anchor/style/index.less @@ -1,10 +1,11 @@ -@import '../../style/themes/default'; +@import '../../style/themes/index'; @import '../../style/mixins/index'; @anchor-border-width: 2px; .@{ant-prefix}-anchor { .reset-component; + position: relative; padding-left: @anchor-border-width; @@ -26,7 +27,7 @@ width: @anchor-border-width; height: 100%; margin: 0 auto; - background-color: @border-color-split; + background-color: @anchor-border-color; content: ' '; } &-ball { diff --git a/components/auto-complete/InputElement.jsx b/components/auto-complete/InputElement.jsx index 2ba4e1a4e..131b3bf0a 100644 --- a/components/auto-complete/InputElement.jsx +++ b/components/auto-complete/InputElement.jsx @@ -20,17 +20,6 @@ export default { disabled: PropTypes.bool, placeholder: PropTypes.string, }, - methods: { - focus() { - const ele = this.$refs.ele; - ele.focus ? ele.focus() : this.$el.focus(); - }, - blur() { - const ele = this.$refs.ele; - ele.blur ? ele.blur() : this.$el.blur(); - }, - }, - render() { const { $slots = {}, $attrs = {}, placeholder } = this; const listeners = getListeners(this); diff --git a/components/auto-complete/__tests__/__snapshots__/demo.test.js.snap b/components/auto-complete/__tests__/__snapshots__/demo.test.js.snap index 0c067869c..b3cd389ba 100644 --- a/components/auto-complete/__tests__/__snapshots__/demo.test.js.snap +++ b/components/auto-complete/__tests__/__snapshots__/demo.test.js.snap @@ -1,20 +1,33 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/auto-complete/demo/basic.md correctly 1`] = ` - +
`; @@ -2222,9 +2306,7 @@ exports[`Locale Provider should display the text as da 1`] = `
-
~ Click to confirm +
~ Click to confirm
0 element
@@ -2233,8 +2315,16 @@ exports[`Locale Provider should display the text as da 1`] = `
-
-
Ingen data
+
+
+ + + + + + + +

Ingen data

@@ -2252,8 +2342,16 @@ exports[`Locale Provider should display the text as da 1`] = `
-
-
Ingen data
+
+
+ + + + + + + +

Ingen data

@@ -2276,7 +2374,7 @@ exports[`Locale Provider should display the text as da 1`] = `
-
+
@@ -2576,31 +2674,38 @@ exports[`Locale Provider should display the text as da 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Ingen data
-

Ingen data

-
-
-
-
-
-
+ +
Age +
+ + + + +
+
+
+
+ + + + + + + +
+

Ingen data

- +
+
+
+
+
+
+
`; @@ -2636,9 +2741,7 @@ exports[`Locale Provider should display the text as de 1`] = `
-
~ Click to confirm +
~ Click to confirm
0 Eintrag
@@ -2647,8 +2750,16 @@ exports[`Locale Provider should display the text as de 1`] = `
-
-
Keine Daten
+
+
+ + + + + + + +

Keine Daten

@@ -2666,8 +2777,16 @@ exports[`Locale Provider should display the text as de 1`] = `
-
-
Keine Daten
+
+
+ + + + + + + +

Keine Daten

@@ -2690,7 +2809,7 @@ exports[`Locale Provider should display the text as de 1`] = `
-
+
@@ -2990,31 +3109,38 @@ exports[`Locale Provider should display the text as de 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Keine Daten
-

Keine Daten

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Keine Daten

- +
+ + + + + + `; @@ -3050,9 +3176,7 @@ exports[`Locale Provider should display the text as el 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 αντικείμενο
@@ -3061,8 +3185,16 @@ exports[`Locale Provider should display the text as el 1`] = `
-
-
Δεν υπάρχουν δεδομένα
+
+
+ + + + + + + +

Δεν υπάρχουν δεδομένα

@@ -3080,8 +3212,16 @@ exports[`Locale Provider should display the text as el 1`] = `
-
-
Δεν υπάρχουν δεδομένα
+
+
+ + + + + + + +

Δεν υπάρχουν δεδομένα

@@ -3104,7 +3244,7 @@ exports[`Locale Provider should display the text as el 1`] = `
-
+
@@ -3404,31 +3544,38 @@ exports[`Locale Provider should display the text as el 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Δεν υπάρχουν δεδομένα
-

Δεν υπάρχουν δεδομένα

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Δεν υπάρχουν δεδομένα

- +
+ + + + + + `; @@ -3464,9 +3611,7 @@ exports[`Locale Provider should display the text as en 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 item
@@ -3475,8 +3620,16 @@ exports[`Locale Provider should display the text as en 1`] = `
-
-
No Data
+
+
+ + + + + + + +

No Data

@@ -3494,8 +3647,16 @@ exports[`Locale Provider should display the text as en 1`] = `
-
-
No Data
+
+
+ + + + + + + +

No Data

@@ -3518,7 +3679,7 @@ exports[`Locale Provider should display the text as en 1`] = `
-
+
@@ -3818,31 +3979,38 @@ exports[`Locale Provider should display the text as en 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
No Data
-

No Data

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

No Data

- +
+ + + + + + `; @@ -3878,9 +4046,7 @@ exports[`Locale Provider should display the text as en-gb 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 item
@@ -3889,8 +4055,16 @@ exports[`Locale Provider should display the text as en-gb 1`] = `
-
-
No data
+
+
+ + + + + + + +

No data

@@ -3908,8 +4082,16 @@ exports[`Locale Provider should display the text as en-gb 1`] = `
-
-
No data
+
+
+ + + + + + + +

No data

@@ -3932,7 +4114,7 @@ exports[`Locale Provider should display the text as en-gb 1`] = `
-
+
@@ -4232,38 +4414,45 @@ exports[`Locale Provider should display the text as en-gb 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
No data
-

No data

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

No data

- +
+ + + + + + `; exports[`Locale Provider should display the text as es 1`] = `
    -
  • 1
  • @@ -4271,7 +4460,7 @@ exports[`Locale Provider should display the text as es 1`] = `
  • 3
  • 4
  • 5
  • -
  • @@ -4279,7 +4468,7 @@ exports[`Locale Provider should display the text as es 1`] = `
    10 / página
    -
    +
@@ -4290,40 +4479,54 @@ exports[`Locale Provider should display the text as es 1`] = ` - + -
~ Click to confirm +
~ Click to confirm
0 elemento
-
0 elemento
sep.
-
+
-
+
@@ -4646,31 +4849,38 @@ exports[`Locale Provider should display the text as es 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
No hay datos
-

No hay datos

-
-
-
-
-
- + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

No hay datos

- +
+ + + + + + `; @@ -4706,9 +4916,7 @@ exports[`Locale Provider should display the text as et 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 kogus
@@ -4717,8 +4925,16 @@ exports[`Locale Provider should display the text as et 1`] = `
-
-
Andmed puuduvad
+
+
+ + + + + + + +

Andmed puuduvad

@@ -4736,8 +4952,16 @@ exports[`Locale Provider should display the text as et 1`] = `
-
-
Andmed puuduvad
+
+
+ + + + + + + +

Andmed puuduvad

@@ -4760,7 +4984,7 @@ exports[`Locale Provider should display the text as et 1`] = `
-
+
@@ -5060,31 +5284,38 @@ exports[`Locale Provider should display the text as et 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Andmed puuduvad
-

Andmed puuduvad

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Andmed puuduvad

- +
+ + + + + + `; @@ -5120,9 +5351,7 @@ exports[`Locale Provider should display the text as fa 1`] = ` -
~ Click to confirm +
~ Click to confirm
0
@@ -5131,8 +5360,16 @@ exports[`Locale Provider should display the text as fa 1`] = `
-
-
داده‌ای موجود نیست
+
+
+ + + + + + + +

داده‌ای موجود نیست

@@ -5150,8 +5387,16 @@ exports[`Locale Provider should display the text as fa 1`] = `
-
-
داده‌ای موجود نیست
+
+
+ + + + + + + +

داده‌ای موجود نیست

@@ -5174,7 +5419,7 @@ exports[`Locale Provider should display the text as fa 1`] = `
-
+
@@ -5474,31 +5719,38 @@ exports[`Locale Provider should display the text as fa 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
داده‌ای موجود نیست
-

داده‌ای موجود نیست

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

داده‌ای موجود نیست

- +
+ + + + + + `; @@ -5534,9 +5786,7 @@ exports[`Locale Provider should display the text as fi 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 kohde
@@ -5545,8 +5795,16 @@ exports[`Locale Provider should display the text as fi 1`] = `
-
-
Ei kohteita
+
+
+ + + + + + + +

Ei kohteita

@@ -5564,8 +5822,16 @@ exports[`Locale Provider should display the text as fi 1`] = `
-
-
Ei kohteita
+
+
+ + + + + + + +

Ei kohteita

@@ -5588,7 +5854,7 @@ exports[`Locale Provider should display the text as fi 1`] = `
-
+
@@ -5888,31 +6154,38 @@ exports[`Locale Provider should display the text as fi 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Ei kohteita
-

Ei kohteita

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Ei kohteita

- +
+ + + + + + `; @@ -5948,9 +6221,7 @@ exports[`Locale Provider should display the text as fr 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 élément
@@ -5959,8 +6230,16 @@ exports[`Locale Provider should display the text as fr 1`] = `
-
-
Aucune donnée
+
+
+ + + + + + + +

Aucune donnée

@@ -5978,8 +6257,16 @@ exports[`Locale Provider should display the text as fr 1`] = `
-
-
Aucune donnée
+
+
+ + + + + + + +

Aucune donnée

@@ -6002,7 +6289,7 @@ exports[`Locale Provider should display the text as fr 1`] = `
-
+
@@ -6302,31 +6589,38 @@ exports[`Locale Provider should display the text as fr 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Aucune donnée
-

Aucune donnée

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Aucune donnée

- +
+ + + + + + `; @@ -6362,9 +6656,7 @@ exports[`Locale Provider should display the text as fr 2`] = ` -
~ Click to confirm +
~ Click to confirm
0 élément
@@ -6373,8 +6665,16 @@ exports[`Locale Provider should display the text as fr 2`] = `
-
-
Aucune donnée
+
+
+ + + + + + + +

Aucune donnée

@@ -6392,8 +6692,16 @@ exports[`Locale Provider should display the text as fr 2`] = `
-
-
Aucune donnée
+
+
+ + + + + + + +

Aucune donnée

@@ -6416,7 +6724,7 @@ exports[`Locale Provider should display the text as fr 2`] = `
-
+
@@ -6716,31 +7024,38 @@ exports[`Locale Provider should display the text as fr 2`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Aucune donnée
-

Aucune donnée

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Aucune donnée

- +
+ + + + + + `; @@ -6776,9 +7091,7 @@ exports[`Locale Provider should display the text as he 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 פריט
@@ -6787,8 +7100,16 @@ exports[`Locale Provider should display the text as he 1`] = `
-
-
אין מידע
+
+
+ + + + + + + +

אין מידע

@@ -6806,8 +7127,16 @@ exports[`Locale Provider should display the text as he 1`] = `
-
-
אין מידע
+
+
+ + + + + + + +

אין מידע

@@ -6830,7 +7159,7 @@ exports[`Locale Provider should display the text as he 1`] = `
-
+
@@ -7130,31 +7459,38 @@ exports[`Locale Provider should display the text as he 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
אין מידע
-

אין מידע

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

אין מידע

- +
+ + + + + + `; @@ -7190,9 +7526,7 @@ exports[`Locale Provider should display the text as hi 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 तत्त्व
@@ -7201,8 +7535,16 @@ exports[`Locale Provider should display the text as hi 1`] = `
-
-
No Data
+
+
+ + + + + + + +

No Data

@@ -7220,8 +7562,16 @@ exports[`Locale Provider should display the text as hi 1`] = `
-
-
No Data
+
+
+ + + + + + + +

No Data

@@ -7244,7 +7594,7 @@ exports[`Locale Provider should display the text as hi 1`] = `
-
+
@@ -7544,26 +7894,473 @@ exports[`Locale Provider should display the text as hi 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
कोई जानकारी नहीं
+
+
Age +
+ + + + +
+
+
+
+ + + + + + + +
+

No Data

+
+
+
+ + + + + + +`; + +exports[`Locale Provider should display the text as hr 1`] = ` +
+ +
+
+
+ +
+
+
~ Click to confirm +
+
+
0 stavka
+ +
+
+
+
0 stavka
+
- +
+
+
+
+
+
2017
+
+
+
+
+
+
+
ruj.
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
poutsrčepesune
+
+
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
+
+
+
+
+
08
+
+
+
+
+
+
+
+
+
+
+
+ +
+ + + + + + + + + + + + +
Name +
+
Age +
+
+
+
+
+ + + + + + + +
+

Nema podataka

+
+
+
+
+
+
+
+
`; @@ -7599,9 +8396,7 @@ exports[`Locale Provider should display the text as hu 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 elem
@@ -7610,8 +8405,16 @@ exports[`Locale Provider should display the text as hu 1`] = `
-
-
Nincs adat
+
+
+ + + + + + + +

Nincs adat

@@ -7629,8 +8432,16 @@ exports[`Locale Provider should display the text as hu 1`] = `
-
-
Nincs adat
+
+
+ + + + + + + +

Nincs adat

@@ -7653,7 +8464,7 @@ exports[`Locale Provider should display the text as hu 1`] = `
-
+
@@ -7953,31 +8764,473 @@ exports[`Locale Provider should display the text as hu 1`] = ` - -
Name
- - -
Age
- - - - - -
-
-
-
Nincs adat
-

Nincs adat

-
+
Name
+
+
Age +
+ + + + +
+
+
+
+ + + + + + + +
+

Nincs adat

+
+
+
+ + + + + + +`; + +exports[`Locale Provider should display the text as hy 1`] = ` +
+ +
+
+
+ +
+
+
~ Click to confirm +
+
+
0 պարագան
+ +
+
+
+
0 պարագան
+
- +
+
+
+
+
+
2017
+
+
+
+
+
+
+
szept
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
hkszecspszov
+
+
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
+
+
+
+
+
08
+
+
+
+
+
+
+
+
+
+
+
+ +
+ + + + + + + + + + + + +
Name +
+
Age +
+
+
+
+
+ + + + + + + +
+

Տվյալներ չկան

+
+
+
+
+
+
+
+
`; @@ -8013,9 +9266,7 @@ exports[`Locale Provider should display the text as id 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 item
@@ -8024,8 +9275,16 @@ exports[`Locale Provider should display the text as id 1`] = `
-
-
Tidak ada data
+
+
+ + + + + + + +

Tidak ada data

@@ -8043,8 +9302,16 @@ exports[`Locale Provider should display the text as id 1`] = `
-
-
Tidak ada data
+
+
+ + + + + + + +

Tidak ada data

@@ -8067,7 +9334,7 @@ exports[`Locale Provider should display the text as id 1`] = `
-
+
@@ -8367,31 +9634,38 @@ exports[`Locale Provider should display the text as id 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Tidak ada data
-

Tidak ada data

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Tidak ada data

- +
+ + + + + + `; @@ -8427,9 +9701,7 @@ exports[`Locale Provider should display the text as is 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 færsla
@@ -8438,8 +9710,16 @@ exports[`Locale Provider should display the text as is 1`] = `
-
-
Engin gögn
+
+
+ + + + + + + +

Engin gögn

@@ -8457,8 +9737,16 @@ exports[`Locale Provider should display the text as is 1`] = `
-
-
Engin gögn
+
+
+ + + + + + + +

Engin gögn

@@ -8481,7 +9769,7 @@ exports[`Locale Provider should display the text as is 1`] = `
-
+
@@ -8781,38 +10069,45 @@ exports[`Locale Provider should display the text as is 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Engin gögn
-

Engin gögn

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Engin gögn

- +
+ + + + + + `; exports[`Locale Provider should display the text as it 1`] = `
    -
  • 1
  • @@ -8820,7 +10115,7 @@ exports[`Locale Provider should display the text as it 1`] = `
  • 3
  • 4
  • 5
  • -
  • @@ -8828,7 +10123,7 @@ exports[`Locale Provider should display the text as it 1`] = `
    10 / pagina
    -
    +
@@ -8839,40 +10134,54 @@ exports[`Locale Provider should display the text as it 1`] = ` - + -
~ Click to confirm +
~ Click to confirm
-
0 articolo
+
0 elemento
-
-
0 articolo
+
0 elemento
set
-
+
-
+
@@ -9195,31 +10504,38 @@ exports[`Locale Provider should display the text as it 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Nessun dato
-

Nessun dato

-
-
-
-
-
- + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Nessun dato

- +
+ + + + + + `; @@ -9255,9 +10571,7 @@ exports[`Locale Provider should display the text as ja 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 アイテム
@@ -9266,8 +10580,16 @@ exports[`Locale Provider should display the text as ja 1`] = `
-
-
データがありません
+
+
+ + + + + + + +

データがありません

@@ -9285,8 +10607,16 @@ exports[`Locale Provider should display the text as ja 1`] = `
-
-
データがありません
+
+
+ + + + + + + +

データがありません

@@ -9309,7 +10639,7 @@ exports[`Locale Provider should display the text as ja 1`] = `
-
+
@@ -9609,31 +10939,38 @@ exports[`Locale Provider should display the text as ja 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
データがありません
-

データがありません

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

データがありません

- +
+ + + + + + `; @@ -9669,9 +11006,7 @@ exports[`Locale Provider should display the text as kn 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 ವಿಷಯ
@@ -9680,8 +11015,16 @@ exports[`Locale Provider should display the text as kn 1`] = `
-
-
No Data
+
+
+ + + + + + + +

No Data

@@ -9699,8 +11042,16 @@ exports[`Locale Provider should display the text as kn 1`] = `
-
-
No Data
+
+
+ + + + + + + +

No Data

@@ -9723,7 +11074,7 @@ exports[`Locale Provider should display the text as kn 1`] = `
-
+
@@ -10023,26 +11374,38 @@ exports[`Locale Provider should display the text as kn 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
ಮಾಹಿತಿ ಇಲ್ಲ
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

No Data

- +
+ + + + + + `; @@ -10078,9 +11441,7 @@ exports[`Locale Provider should display the text as ko 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 개
@@ -10089,8 +11450,16 @@ exports[`Locale Provider should display the text as ko 1`] = `
-
-
데이터 없음
+
+
+ + + + + + + +

데이터 없음

@@ -10108,8 +11477,16 @@ exports[`Locale Provider should display the text as ko 1`] = `
-
-
데이터 없음
+
+
+ + + + + + + +

데이터 없음

@@ -10132,7 +11509,7 @@ exports[`Locale Provider should display the text as ko 1`] = `
-
+
@@ -10432,31 +11809,38 @@ exports[`Locale Provider should display the text as ko 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
데이터 없음
-

데이터 없음

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

데이터 없음

- +
+ + + + + + `; @@ -10492,9 +11876,7 @@ exports[`Locale Provider should display the text as ku-iq 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 tişt
@@ -10503,8 +11885,16 @@ exports[`Locale Provider should display the text as ku-iq 1`] = `
-
-
Agahî tune
+
+
+ + + + + + + +

Agahî tune

@@ -10522,8 +11912,16 @@ exports[`Locale Provider should display the text as ku-iq 1`] = `
-
-
Agahî tune
+
+
+ + + + + + + +

Agahî tune

@@ -10546,7 +11944,7 @@ exports[`Locale Provider should display the text as ku-iq 1`] = `
-
+
@@ -10846,31 +12244,908 @@ exports[`Locale Provider should display the text as ku-iq 1`] = ` - -
Name
- - -
Age
- - - - - -
-
-
-
Agahî tune
-

Agahî tune

-
+
Name
+
+
Age +
+ + + + +
+
+
+
+ + + + + + + +
+

Agahî tune

+
+
+
+ + + + + + +`; + +exports[`Locale Provider should display the text as lv 1`] = ` +
+ +
+
+
+ +
+
+
~ Click to confirm +
+
+
0 vienumu
+ +
+
+
+
0 vienumu
+
- +
+
+
+
+
+
2017
+
+
+
+
+
+
+
sep
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
POTCPkSSv
+
+
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
+
+
+
+
+
08
+
+
+
+
+
+
+
+
+
+
+
+ +
+ + + + + + + + + + + + +
Name +
+
Age +
+
+
+
+
+ + + + + + + +
+

Nav datu

+
+
+
+
+
+
+
+ +
+`; + +exports[`Locale Provider should display the text as mk 1`] = ` +
+ +
+
+
+ +
+
+
~ Click to confirm +
+
+
0 предмет
+ +
+
+
+
0 предмет
+ +
+
+
+
+
+
+
+
2017
+
+
+
+
+
+
+
сеп
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
пoвтсрчепесaнe
+
+
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
+
+
+
+
+
08
+
+
+
+
+
+
+
+
+
+
+
+ +
+ + + + + + + + + + + + +
Name +
+
Age +
+
+
+
+
+ + + + + + + +
+

Нема податоци

+
+
+
+
+
+
+
+
`; @@ -10906,9 +13181,7 @@ exports[`Locale Provider should display the text as mn-mn 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 Зүйл
@@ -10917,8 +13190,16 @@ exports[`Locale Provider should display the text as mn-mn 1`] = `
-
-
Мэдээлэл байхгүй байна
+
+
+ + + + + + + +

Мэдээлэл байхгүй байна

@@ -10936,8 +13217,16 @@ exports[`Locale Provider should display the text as mn-mn 1`] = `
-
-
Мэдээлэл байхгүй байна
+
+
+ + + + + + + +

Мэдээлэл байхгүй байна

@@ -10960,7 +13249,7 @@ exports[`Locale Provider should display the text as mn-mn 1`] = `
-
+
@@ -11260,31 +13549,473 @@ exports[`Locale Provider should display the text as mn-mn 1`] = ` - -
Name
- - -
Age
- - - - - -
-
-
-
Мэдээлэл байхгүй байна
-

Мэдээлэл байхгүй байна

-
+
Name
+
+
Age +
+ + + + +
+
+
+
+ + + + + + + +
+

Мэдээлэл байхгүй байна

+
+
+
+ + + + + + +`; + +exports[`Locale Provider should display the text as ms-my 1`] = ` +
+ +
+
+
+ +
+
+
~ Click to confirm +
+
+
0 item
+ +
+
+
+
0 item
+
- +
+
+
+
+
+
2017
+
+
+
+
+
+
+
Sep
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IsSlRbKmJmSbAh
+
+
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
+
+
+
+
+
08
+
+
+
+
+
+
+
+
+
+
+
+ +
+ + + + + + + + + + + + +
Name +
+
Age +
+
+
+
+
+ + + + + + + +
+

Tiada data

+
+
+
+
+
+
+
+
`; @@ -11320,9 +14051,7 @@ exports[`Locale Provider should display the text as nb 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 element
@@ -11331,8 +14060,16 @@ exports[`Locale Provider should display the text as nb 1`] = `
-
-
Ingen data
+
+
+ + + + + + + +

Ingen data

@@ -11350,8 +14087,16 @@ exports[`Locale Provider should display the text as nb 1`] = `
-
-
Ingen data
+
+
+ + + + + + + +

Ingen data

@@ -11374,7 +14119,7 @@ exports[`Locale Provider should display the text as nb 1`] = `
-
+
@@ -11674,31 +14419,38 @@ exports[`Locale Provider should display the text as nb 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Ingen data
-

Ingen data

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Ingen data

- +
+ + + + + + `; @@ -11734,9 +14486,7 @@ exports[`Locale Provider should display the text as ne-np 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 वस्तु
@@ -11745,8 +14495,16 @@ exports[`Locale Provider should display the text as ne-np 1`] = `
-
-
डाटा छैन
+
+
+ + + + + + + +

डाटा छैन

@@ -11764,8 +14522,16 @@ exports[`Locale Provider should display the text as ne-np 1`] = `
-
-
डाटा छैन
+
+
+ + + + + + + +

डाटा छैन

@@ -11788,7 +14554,7 @@ exports[`Locale Provider should display the text as ne-np 1`] = `
-
+
@@ -12088,38 +14854,45 @@ exports[`Locale Provider should display the text as ne-np 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
डाटा छैन
-

डाटा छैन

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

डाटा छैन

- +
+ + + + + + `; exports[`Locale Provider should display the text as nl 1`] = `
    -
  • 1
  • @@ -12127,7 +14900,7 @@ exports[`Locale Provider should display the text as nl 1`] = `
  • 3
  • 4
  • 5
  • -
  • @@ -12135,7 +14908,7 @@ exports[`Locale Provider should display the text as nl 1`] = `
    10 / pagina
    -
    +
@@ -12146,40 +14919,54 @@ exports[`Locale Provider should display the text as nl 1`] = ` - + -
~ Click to confirm +
~ Click to confirm
0 item
-
0 item
sep.
-
+
-
+
@@ -12502,31 +15289,38 @@ exports[`Locale Provider should display the text as nl 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Geen gegevens
-

Geen gegevens

-
-
-
-
-
- + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Geen gegevens

- +
+ + + + + + `; @@ -12562,9 +15356,7 @@ exports[`Locale Provider should display the text as nl-be 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 item
@@ -12573,8 +15365,16 @@ exports[`Locale Provider should display the text as nl-be 1`] = `
-
-
Geen gegevens
+
+
+ + + + + + + +

Geen gegevens

@@ -12592,8 +15392,16 @@ exports[`Locale Provider should display the text as nl-be 1`] = `
-
-
Geen gegevens
+
+
+ + + + + + + +

Geen gegevens

@@ -12616,7 +15424,7 @@ exports[`Locale Provider should display the text as nl-be 1`] = `
-
+
@@ -12916,31 +15724,38 @@ exports[`Locale Provider should display the text as nl-be 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Geen gegevens
-

Geen gegevens

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Geen gegevens

- +
+ + + + + + `; @@ -12976,9 +15791,7 @@ exports[`Locale Provider should display the text as pl 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 obiekt
@@ -12987,8 +15800,16 @@ exports[`Locale Provider should display the text as pl 1`] = `
-
-
Brak danych
+
+
+ + + + + + + +

Brak danych

@@ -13006,8 +15827,16 @@ exports[`Locale Provider should display the text as pl 1`] = `
-
-
Brak danych
+
+
+ + + + + + + +

Brak danych

@@ -13030,7 +15859,7 @@ exports[`Locale Provider should display the text as pl 1`] = `
-
+
@@ -13330,31 +16159,38 @@ exports[`Locale Provider should display the text as pl 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Brak danych
-

Brak danych

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Brak danych

- +
+ + + + + + `; @@ -13390,9 +16226,7 @@ exports[`Locale Provider should display the text as pt 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 item
@@ -13401,8 +16235,16 @@ exports[`Locale Provider should display the text as pt 1`] = `
-
-
Sem resultados
+
+
+ + + + + + + +

Sem resultados

@@ -13420,8 +16262,16 @@ exports[`Locale Provider should display the text as pt 1`] = `
-
-
Sem resultados
+
+
+ + + + + + + +

Sem resultados

@@ -13444,7 +16294,7 @@ exports[`Locale Provider should display the text as pt 1`] = `
-
+
@@ -13744,31 +16594,38 @@ exports[`Locale Provider should display the text as pt 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Sem resultados
-

Sem resultados

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Sem resultados

- +
+ + + + + + `; @@ -13804,9 +16661,7 @@ exports[`Locale Provider should display the text as pt-br 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 item
@@ -13815,8 +16670,16 @@ exports[`Locale Provider should display the text as pt-br 1`] = `
-
-
Não há dados
+
+
+ + + + + + + +

Não há dados

@@ -13834,8 +16697,16 @@ exports[`Locale Provider should display the text as pt-br 1`] = `
-
-
Não há dados
+
+
+ + + + + + + +

Não há dados

@@ -13858,7 +16729,7 @@ exports[`Locale Provider should display the text as pt-br 1`] = `
-
+
@@ -14158,31 +17029,473 @@ exports[`Locale Provider should display the text as pt-br 1`] = ` - -
Name
- - -
Age
- - - - - -
-
-
-
Não há dados
-

Não há dados

-
+
Name
+
+
Age +
+ + + + +
+
+
+
+ + + + + + + +
+

Não há dados

+
+
+
+ + + + + + +`; + +exports[`Locale Provider should display the text as ro 1`] = ` +
+ +
+
+
+ +
+
+
~ Click to confirm +
+
+
0 element
+ +
+
+
+
0 element
+
- +
+
+
+
+
+
2017
+
+
+
+
+
+
+
sept.
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LuMaMiJoViDu
+
+
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
+
+
+
+
+
08
+
+
+
+
+
+
+
+
+
+
+
+ +
+ + + + + + + + + + + + +
Name +
+
Age +
+
+
+
+
+ + + + + + + +
+

Fără date

+
+
+
+
+
+
+
+
`; @@ -14218,9 +17531,7 @@ exports[`Locale Provider should display the text as ru 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 элем.
@@ -14229,8 +17540,16 @@ exports[`Locale Provider should display the text as ru 1`] = `
-
-
Нет данных
+
+
+ + + + + + + +

Нет данных

@@ -14248,8 +17567,16 @@ exports[`Locale Provider should display the text as ru 1`] = `
-
-
Нет данных
+
+
+ + + + + + + +

Нет данных

@@ -14272,7 +17599,7 @@ exports[`Locale Provider should display the text as ru 1`] = `
-
+
@@ -14572,38 +17899,45 @@ exports[`Locale Provider should display the text as ru 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Нет данных
-

Нет данных

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Нет данных

- +
+ + + + + + `; exports[`Locale Provider should display the text as sk 1`] = `
    -
  • 1
  • @@ -14611,7 +17945,7 @@ exports[`Locale Provider should display the text as sk 1`] = `
  • 3
  • 4
  • 5
  • -
  • @@ -14619,7 +17953,7 @@ exports[`Locale Provider should display the text as sk 1`] = `
    10 / strana
    -
    +
@@ -14630,40 +17964,54 @@ exports[`Locale Provider should display the text as sk 1`] = ` - + -
~ Click to confirm +
~ Click to confirm
0 položka
-
0 položka
sep
-
+
-
+
@@ -14986,31 +18334,38 @@ exports[`Locale Provider should display the text as sk 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Žiadne dáta
-

Žiadne dáta

-
-
-
-
-
- + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Žiadne dáta

- +
+ + + + + + `; @@ -15046,9 +18401,7 @@ exports[`Locale Provider should display the text as sl 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 Objekt
@@ -15057,8 +18410,16 @@ exports[`Locale Provider should display the text as sl 1`] = `
-
-
Ni podatkov
+
+
+ + + + + + + +

Ni podatkov

@@ -15076,8 +18437,16 @@ exports[`Locale Provider should display the text as sl 1`] = `
-
-
Ni podatkov
+
+
+ + + + + + + +

Ni podatkov

@@ -15100,7 +18469,7 @@ exports[`Locale Provider should display the text as sl 1`] = `
-
+
@@ -15400,31 +18769,38 @@ exports[`Locale Provider should display the text as sl 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Ni podatkov
-

Ni podatkov

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Ni podatkov

- +
+ + + + + + `; @@ -15460,9 +18836,7 @@ exports[`Locale Provider should display the text as sr 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 stavka
@@ -15471,8 +18845,16 @@ exports[`Locale Provider should display the text as sr 1`] = `
-
-
Nema podataka
+
+
+ + + + + + + +

Nema podataka

@@ -15490,8 +18872,16 @@ exports[`Locale Provider should display the text as sr 1`] = `
-
-
Nema podataka
+
+
+ + + + + + + +

Nema podataka

@@ -15514,7 +18904,7 @@ exports[`Locale Provider should display the text as sr 1`] = `
-
+
@@ -15814,31 +19204,38 @@ exports[`Locale Provider should display the text as sr 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Nema podataka
-

Nema podataka

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Nema podataka

- +
+ + + + + + `; @@ -15874,9 +19271,7 @@ exports[`Locale Provider should display the text as sv 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 element
@@ -15885,8 +19280,16 @@ exports[`Locale Provider should display the text as sv 1`] = `
-
-
Ingen information
+
+
+ + + + + + + +

Ingen information

@@ -15904,8 +19307,16 @@ exports[`Locale Provider should display the text as sv 1`] = `
-
-
Ingen information
+
+
+ + + + + + + +

Ingen information

@@ -15928,7 +19339,7 @@ exports[`Locale Provider should display the text as sv 1`] = `
-
+
@@ -16228,38 +19639,45 @@ exports[`Locale Provider should display the text as sv 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Ingen information
-

Ingen information

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Ingen information

- +
+ + + + + + `; -exports[`Locale Provider should display the text as th 1`] = ` +exports[`Locale Provider should display the text as ta 1`] = `
    -
  • 1
  • @@ -16267,15 +19685,15 @@ exports[`Locale Provider should display the text as th 1`] = `
  • 3
  • 4
  • 5
  • -
  • -
    10 / หน้า
    -
    +
    10 / பக்கம்
    +
@@ -16286,40 +19704,489 @@ exports[`Locale Provider should display the text as th 1`] = ` - + -
~ Click to confirm +
~ 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 +
+
+
+
+
+ + + + + + + +
+

தகவல் இல்லை

+
+
+
+
+
+
+
+ + +`; + +exports[`Locale Provider should display the text as th 1`] = ` +
+ +
+
+
+ +
+
+
~ Click to confirm
0 ชิ้น
-
0 ชิ้น
ก.ย.
-
+
-
+
@@ -16642,31 +20509,38 @@ exports[`Locale Provider should display the text as th 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
ไม่มีข้อมูล
-

ไม่มีข้อมูล

-
-
-
-
-
-
+ +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

ไม่มีข้อมูล

- +
+ + + + + + `; @@ -16702,9 +20576,7 @@ exports[`Locale Provider should display the text as tr 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 Öğe
@@ -16713,8 +20585,16 @@ exports[`Locale Provider should display the text as tr 1`] = `
-
-
Veri Yok
+
+
+ + + + + + + +

Veri Yok

@@ -16732,8 +20612,16 @@ exports[`Locale Provider should display the text as tr 1`] = `
-
-
Veri Yok
+
+
+ + + + + + + +

Veri Yok

@@ -16756,7 +20644,7 @@ exports[`Locale Provider should display the text as tr 1`] = `
-
+
@@ -17056,31 +20944,38 @@ exports[`Locale Provider should display the text as tr 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Veri Yok
-

Veri Yok

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Veri Yok

- +
+ + + + + + `; @@ -17116,9 +21011,7 @@ exports[`Locale Provider should display the text as uk 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 item
@@ -17127,8 +21020,16 @@ exports[`Locale Provider should display the text as uk 1`] = `
-
-
Даних немає
+
+
+ + + + + + + +

Даних немає

@@ -17146,8 +21047,16 @@ exports[`Locale Provider should display the text as uk 1`] = `
-
-
Даних немає
+
+
+ + + + + + + +

Даних немає

@@ -17170,7 +21079,7 @@ exports[`Locale Provider should display the text as uk 1`] = `
-
+
@@ -17470,31 +21379,38 @@ exports[`Locale Provider should display the text as uk 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Даних немає
-

Даних немає

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Даних немає

- +
+ + + + + + `; @@ -17530,9 +21446,7 @@ exports[`Locale Provider should display the text as vi 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 mục
@@ -17541,8 +21455,16 @@ exports[`Locale Provider should display the text as vi 1`] = `
-
-
Trống
+
+
+ + + + + + + +

Trống

@@ -17560,8 +21482,16 @@ exports[`Locale Provider should display the text as vi 1`] = `
-
-
Trống
+
+
+ + + + + + + +

Trống

@@ -17584,7 +21514,7 @@ exports[`Locale Provider should display the text as vi 1`] = `
-
+
@@ -17884,31 +21814,38 @@ exports[`Locale Provider should display the text as vi 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
Trống
-

Trống

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

Trống

- +
+ + + + + + `; @@ -17944,9 +21881,7 @@ exports[`Locale Provider should display the text as zh-cn 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 项
@@ -17955,8 +21890,16 @@ exports[`Locale Provider should display the text as zh-cn 1`] = `
-
-
暂无数据
+
+
+ + + + + + + +

暂无数据

@@ -17974,8 +21917,16 @@ exports[`Locale Provider should display the text as zh-cn 1`] = `
-
-
暂无数据
+
+
+ + + + + + + +

暂无数据

@@ -17998,7 +21949,7 @@ exports[`Locale Provider should display the text as zh-cn 1`] = `
-
+
@@ -18298,31 +22249,38 @@ exports[`Locale Provider should display the text as zh-cn 1`] = ` - -
Name
- - -
Age
- - - - - +
Name
-
-
-
暂无数据
-

暂无数据

-
-
-
-
- - + +
Age +
+ + + + + +
+
+
+ + + + + + + +
+

暂无数据

- +
+ + + + + + `; @@ -18358,9 +22316,7 @@ exports[`Locale Provider should display the text as zh-tw 1`] = ` -
~ Click to confirm +
~ Click to confirm
0 項目
@@ -18369,8 +22325,16 @@ exports[`Locale Provider should display the text as zh-tw 1`] = `
-
-
無此資料
+
+
+ + + + + + + +

無此資料

@@ -18388,8 +22352,16 @@ exports[`Locale Provider should display the text as zh-tw 1`] = `
-
-
無此資料
+
+
+ + + + + + + +

無此資料

@@ -18412,7 +22384,7 @@ exports[`Locale Provider should display the text as zh-tw 1`] = `
-
+
@@ -18712,30 +22684,37 @@ 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 783c21828..ce76e9bad 100644 --- a/components/locale-provider/__tests__/index.test.js +++ b/components/locale-provider/__tests__/index.test.js @@ -31,14 +31,18 @@ import frBE from '../fr_BE'; import frFR from '../fr_FR'; import heIL from '../he_IL'; import hiIN from '../hi_IN'; +import hrHR from '../hr_HR'; import huHU from '../hu_HU'; +import hyAM from '../hy_AM'; import isIS from '../is_IS'; import itIT from '../it_IT'; import jaJP from '../ja_JP'; import knIN from '../kn_IN'; import koKR from '../ko_KR'; import kuIQ from '../ku_IQ'; +import mkMK from '../mk_MK'; import mnMN from '../mn_MN'; +import msMY from '../ms_MY'; import nbNO from '../nb_NO'; import neNP from '../ne-NP'; import nlBE from '../nl_BE'; @@ -46,16 +50,19 @@ import nlNL from '../nl_NL'; import plPL from '../pl_PL'; import ptBR from '../pt_BR'; import ptPT from '../pt_PT'; +import roRO from '../ro_RO'; import ruRU from '../ru_RU'; import skSK from '../sk_SK'; import slSI from '../sl_SI'; import srRS from '../sr_RS'; import svSE from '../sv_SE'; +import taIN from '../ta_IN'; 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 lvLV from '../lv_LV'; import zhCN from '../zh_CN'; import zhTW from '../zh_TW'; @@ -77,13 +84,17 @@ const locales = [ frFR, heIL, hiIN, + hrHR, huHU, + hyAM, isIS, itIT, jaJP, knIN, koKR, kuIQ, + mkMK, + msMY, mnMN, nbNO, neNP, @@ -92,16 +103,19 @@ const locales = [ plPL, ptBR, ptPT, + roRO, ruRU, skSK, slSI, srRS, svSE, + taIN, thTH, trTR, ukUA, viVN, idID, + lvLV, zhCN, zhTW, ]; diff --git a/components/locale-provider/ar_EG.js b/components/locale-provider/ar_EG.js index 254065d1b..55b7906d9 100644 --- a/components/locale-provider/ar_EG.js +++ b/components/locale-provider/ar_EG.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/ar_EG'; -import DatePicker from '../date-picker/locale/ar_EG'; -import TimePicker from '../time-picker/locale/ar_EG'; -import Calendar from '../calendar/locale/ar_EG'; +import locale from '../locale/ar_EG'; -export default { - locale: 'ar', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'الفلاتر', - filterConfirm: 'تأكيد', - filterReset: 'إعادة ضبط', - selectAll: 'اختيار الكل', - selectInvert: 'إلغاء الاختيار', - }, - Modal: { - okText: 'تأكيد', - cancelText: 'إلغاء', - justOkText: 'تأكيد', - }, - Popconfirm: { - okText: 'تأكيد', - cancelText: 'إلغاء', - }, - Transfer: { - searchPlaceholder: 'ابحث هنا', - itemUnit: 'عنصر', - itemsUnit: 'عناصر', - }, - Upload: { - uploading: 'جاري الرفع...', - removeFile: 'احذف الملف', - uploadError: 'مشكلة فى الرفع', - previewFile: 'استعرض الملف', - }, - Empty: { - description: 'لا توجد بيانات', - }, -}; +export default locale; diff --git a/components/locale-provider/bg_BG.js b/components/locale-provider/bg_BG.js index d2c14b2db..2cf89f06a 100644 --- a/components/locale-provider/bg_BG.js +++ b/components/locale-provider/bg_BG.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/bg_BG'; -import DatePicker from '../date-picker/locale/bg_BG'; -import TimePicker from '../time-picker/locale/bg_BG'; -import Calendar from '../calendar/locale/bg_BG'; +import locale from '../locale/bg_BG'; -export default { - locale: 'bg', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Филтриране', - filterConfirm: 'Добре', - filterReset: 'Нулиране', - selectAll: 'Избор на текуща страница', - selectInvert: 'Обръщане', - }, - Modal: { - okText: 'Добре', - cancelText: 'Отказ', - justOkText: 'Добре', - }, - Popconfirm: { - okText: 'Добре', - cancelText: 'Отказ', - }, - Transfer: { - searchPlaceholder: 'Търсене', - itemUnit: 'избор', - itemsUnit: 'избори', - }, - Upload: { - uploading: 'Качване...', - removeFile: 'Премахване', - uploadError: 'Грешка при качването', - previewFile: 'Преглед', - }, - Empty: { - description: 'Няма данни', - }, -}; +export default locale; diff --git a/components/locale-provider/ca_ES.js b/components/locale-provider/ca_ES.js index 3ab4f2244..bfca16842 100644 --- a/components/locale-provider/ca_ES.js +++ b/components/locale-provider/ca_ES.js @@ -1,34 +1,3 @@ -import Pagination from '../vc-pagination/locale/ca_ES'; -import DatePicker from '../date-picker/locale/ca_ES'; -import TimePicker from '../time-picker/locale/ca_ES'; -import Calendar from '../calendar/locale/ca_ES'; +import locale from '../locale/ca_ES'; -export default { - locale: 'ca', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filtrar Menu', - filterConfirm: 'OK', - filterReset: 'Restablir', - }, - Modal: { - okText: 'OK', - cancelText: 'Cancel·lar', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Cancel·lar', - }, - Transfer: { - searchPlaceholder: 'Cercar aquí', - itemUnit: 'item', - itemsUnit: 'items', - }, - Empty: { - description: 'Sense dades', - }, -}; +export default locale; diff --git a/components/locale-provider/cs_CZ.js b/components/locale-provider/cs_CZ.js index aa473afbb..a14aefebd 100644 --- a/components/locale-provider/cs_CZ.js +++ b/components/locale-provider/cs_CZ.js @@ -1,40 +1,3 @@ -import Pagination from '../vc-pagination/locale/cs_CZ'; -import DatePicker from '../date-picker/locale/cs_CZ'; -import TimePicker from '../time-picker/locale/cs_CZ'; -import Calendar from '../calendar/locale/cs_CZ'; +import locale from '../locale/cs_CZ'; -export default { - locale: 'cs', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filtr', - filterConfirm: 'Potvrdit', - filterReset: 'Obnovit', - }, - Modal: { - okText: 'Ok', - cancelText: 'Storno', - justOkText: 'Ok', - }, - Popconfirm: { - okText: 'Ok', - cancelText: 'Storno', - }, - Transfer: { - searchPlaceholder: 'Vyhledávání', - itemUnit: 'položka', - itemsUnit: 'položek', - }, - Upload: { - uploading: 'Nahrávání...', - removeFile: 'Odstranit soubor', - uploadError: 'Chyba při nahrávání', - previewFile: 'Zobrazit soubor', - }, - Empty: { - description: 'Žádná data', - }, -}; +export default locale; diff --git a/components/locale-provider/da_DK.js b/components/locale-provider/da_DK.js index b67cd6096..92a83f169 100644 --- a/components/locale-provider/da_DK.js +++ b/components/locale-provider/da_DK.js @@ -1,42 +1,3 @@ -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'; +import locale from '../locale/da_DK'; -export default { - locale: 'da', - DatePicker, - TimePicker, - Calendar, - Pagination, - Table: { - filterTitle: 'Filtermenu', - filterConfirm: 'OK', - filterReset: 'Nulstil', - selectAll: 'Vælg alle', - selectInvert: 'Inverter valg', - }, - Modal: { - okText: 'OK', - cancelText: 'Afbryd', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Afbryd', - }, - Transfer: { - searchPlaceholder: 'Søg her', - itemUnit: 'element', - itemsUnit: 'elementer', - }, - Upload: { - uploading: 'Uploader...', - removeFile: 'Fjern fil', - uploadError: 'Fejl ved upload', - previewFile: 'Forhåndsvisning', - }, - Empty: { - description: 'Ingen data', - }, -}; +export default locale; diff --git a/components/locale-provider/de_DE.js b/components/locale-provider/de_DE.js index d131cb35e..f804a836e 100644 --- a/components/locale-provider/de_DE.js +++ b/components/locale-provider/de_DE.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/de_DE'; -import DatePicker from '../date-picker/locale/de_DE'; -import TimePicker from '../time-picker/locale/de_DE'; -import Calendar from '../calendar/locale/de_DE'; +import locale from '../locale/de_DE'; -export default { - locale: 'de', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filter-Menü', - filterConfirm: 'OK', - filterReset: 'Zurücksetzen', - selectAll: 'Selektiere Alle', - selectInvert: 'Selektion Invertieren', - }, - Modal: { - okText: 'OK', - cancelText: 'Abbrechen', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Abbrechen', - }, - Transfer: { - searchPlaceholder: 'Suchen', - itemUnit: 'Eintrag', - itemsUnit: 'Einträge', - }, - Upload: { - uploading: 'Hochladen...', - removeFile: 'Datei entfernen', - uploadError: 'Fehler beim Hochladen', - previewFile: 'Dateivorschau', - }, - Empty: { - description: 'Keine Daten', - }, -}; +export default locale; diff --git a/components/locale-provider/default.js b/components/locale-provider/default.js index 542196f36..474055018 100644 --- a/components/locale-provider/default.js +++ b/components/locale-provider/default.js @@ -1,50 +1,3 @@ -import Pagination from '../vc-pagination/locale/en_US'; -import DatePicker from '../date-picker/locale/en_US'; -import TimePicker from '../time-picker/locale/en_US'; -import Calendar from '../calendar/locale/en_US'; +import locale from '../locale/default'; -export default { - locale: 'en', - Pagination, - DatePicker, - TimePicker, - Calendar, - global: { - placeholder: 'Please select', - }, - Table: { - filterTitle: 'Filter menu', - filterConfirm: 'OK', - filterReset: 'Reset', - selectAll: 'Select current page', - selectInvert: 'Invert current page', - sortTitle: 'Sort', - }, - Modal: { - okText: 'OK', - cancelText: 'Cancel', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Cancel', - }, - Transfer: { - titles: ['', ''], - searchPlaceholder: 'Search here', - itemUnit: 'item', - itemsUnit: 'items', - }, - Upload: { - uploading: 'Uploading...', - removeFile: 'Remove file', - uploadError: 'Upload error', - previewFile: 'Preview file', - }, - Empty: { - description: 'No Data', - }, - Icon: { - icon: 'icon', - }, -}; +export default locale; diff --git a/components/locale-provider/demo/all.md b/components/locale-provider/demo/all.md deleted file mode 100644 index 836bad6d4..000000000 --- a/components/locale-provider/demo/all.md +++ /dev/null @@ -1,139 +0,0 @@ - -#### 所有组件 -此处列出 Ant Design 中需要国际化支持的组件,你可以在演示里切换语言。 - - - -#### All components -Components which need localization support are listed here, you can toggle the language in the demo. - - -```tpl - - - - -``` diff --git a/components/locale-provider/demo/basic.md b/components/locale-provider/demo/basic.md deleted file mode 100644 index 5dc4d1ee4..000000000 --- a/components/locale-provider/demo/basic.md +++ /dev/null @@ -1,28 +0,0 @@ - -#### 国际化 -用 `LocaleProvider` 包裹你的应用,并引用对应的语言包。 - - - -#### Localization -Wrap your app with `LocaleProvider`, and apply the corresponding language package. - - -```tpl - - -``` diff --git a/components/locale-provider/demo/index.vue b/components/locale-provider/demo/index.vue deleted file mode 100644 index b513cac9b..000000000 --- a/components/locale-provider/demo/index.vue +++ /dev/null @@ -1,40 +0,0 @@ - diff --git a/components/locale-provider/el_GR.js b/components/locale-provider/el_GR.js index 090cec7a2..0934a503f 100644 --- a/components/locale-provider/el_GR.js +++ b/components/locale-provider/el_GR.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/el_GR'; -import DatePicker from '../date-picker/locale/el_GR'; -import TimePicker from '../time-picker/locale/el_GR'; -import Calendar from '../calendar/locale/el_GR'; +import locale from '../locale/el_GR'; -export default { - locale: 'el', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Μενού φίλτρων', - filterConfirm: 'ΟΚ', - filterReset: 'Επαναφορά', - selectAll: 'Επιλογή τρέχουσας σελίδας', - selectInvert: 'Αντιστροφή τρέχουσας σελίδας', - }, - Modal: { - okText: 'ΟΚ', - cancelText: 'Άκυρο', - justOkText: 'ΟΚ', - }, - Popconfirm: { - okText: 'ΟΚ', - cancelText: 'Άκυρο', - }, - Transfer: { - searchPlaceholder: 'Αναζήτηση', - itemUnit: 'αντικείμενο', - itemsUnit: 'αντικείμενα', - }, - Upload: { - uploading: 'Μεταφόρτωση...', - removeFile: 'Αφαίρεση αρχείου', - uploadError: 'Σφάλμα μεταφόρτωσης', - previewFile: 'Προεπισκόπηση αρχείου', - }, - Empty: { - description: 'Δεν υπάρχουν δεδομένα', - }, -}; +export default locale; diff --git a/components/locale-provider/en_GB.js b/components/locale-provider/en_GB.js index 7f86145da..73926d57b 100644 --- a/components/locale-provider/en_GB.js +++ b/components/locale-provider/en_GB.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/en_GB'; -import DatePicker from '../date-picker/locale/en_GB'; -import TimePicker from '../time-picker/locale/en_GB'; -import Calendar from '../calendar/locale/en_GB'; +import locale from '../locale/en_GB'; -export default { - locale: 'en-gb', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filter menu', - filterConfirm: 'OK', - filterReset: 'Reset', - selectAll: 'Select current page', - selectInvert: 'Invert current page', - }, - Modal: { - okText: 'OK', - cancelText: 'Cancel', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Cancel', - }, - Transfer: { - searchPlaceholder: 'Search here', - itemUnit: 'item', - itemsUnit: 'items', - }, - Upload: { - uploading: 'Uploading...', - removeFile: 'Remove file', - uploadError: 'Upload error', - previewFile: 'Preview file', - }, - Empty: { - description: 'No data', - }, -}; +export default locale; diff --git a/components/locale-provider/en_US.js b/components/locale-provider/en_US.js index 5d08924d7..c1a1995e1 100644 --- a/components/locale-provider/en_US.js +++ b/components/locale-provider/en_US.js @@ -1,3 +1,3 @@ -import defaultLocale from './default'; +import locale from '../locale/en_US'; -export default defaultLocale; +export default locale; diff --git a/components/locale-provider/es_ES.js b/components/locale-provider/es_ES.js index fac439c6c..2ad9715e1 100644 --- a/components/locale-provider/es_ES.js +++ b/components/locale-provider/es_ES.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/es_ES'; -import DatePicker from '../date-picker/locale/es_ES'; -import TimePicker from '../time-picker/locale/es_ES'; -import Calendar from '../calendar/locale/es_ES'; +import locale from '../locale/es_ES'; -export default { - locale: 'es', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filtrar menú', - filterConfirm: 'Aceptar', - filterReset: 'Reiniciar', - selectAll: 'Seleccionar todo', - selectInvert: 'Invertir selección', - }, - Modal: { - okText: 'Aceptar', - cancelText: 'Cancelar', - justOkText: 'Aceptar', - }, - Popconfirm: { - okText: 'Aceptar', - cancelText: 'Cancelar', - }, - Transfer: { - searchPlaceholder: 'Buscar aquí', - itemUnit: 'elemento', - itemsUnit: 'elementos', - }, - Upload: { - uploading: 'Subiendo...', - removeFile: 'Eliminar archivo', - uploadError: 'Error al subir el archivo', - previewFile: 'Vista previa', - }, - Empty: { - description: 'No hay datos', - }, -}; +export default locale; diff --git a/components/locale-provider/et_EE.js b/components/locale-provider/et_EE.js index 520b77d17..0b6a19b02 100644 --- a/components/locale-provider/et_EE.js +++ b/components/locale-provider/et_EE.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/et_EE'; -import DatePicker from '../date-picker/locale/et_EE'; -import TimePicker from '../time-picker/locale/et_EE'; -import Calendar from '../calendar/locale/et_EE'; +import locale from '../locale/et_EE'; -export default { - locale: 'et', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filtri menüü', - filterConfirm: 'OK', - filterReset: 'Nulli', - selectAll: 'Vali kõik', - selectInvert: 'Inverteeri valik', - }, - Modal: { - okText: 'OK', - cancelText: 'Tühista', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Tühista', - }, - Transfer: { - searchPlaceholder: 'Otsi siit', - itemUnit: 'kogus', - itemsUnit: 'kogus', - }, - Upload: { - uploading: 'Üleslaadimine...', - removeFile: 'Eemalda fail', - uploadError: 'Üleslaadimise tõrge', - previewFile: 'Faili eelvaade', - }, - Empty: { - description: 'Andmed puuduvad', - }, -}; +export default locale; diff --git a/components/locale-provider/fa_IR.js b/components/locale-provider/fa_IR.js index e466b0295..a1d65051f 100644 --- a/components/locale-provider/fa_IR.js +++ b/components/locale-provider/fa_IR.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/fa_IR'; -import DatePicker from '../date-picker/locale/fa_IR'; -import TimePicker from '../time-picker/locale/fa_IR'; -import Calendar from '../calendar/locale/fa_IR'; +import locale from '../locale/fa_IR'; -export default { - locale: 'fa', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'منوی فیلتر', - filterConfirm: 'تایید', - filterReset: 'پاک کردن', - selectAll: 'انتخاب صفحه‌ی کنونی', - selectInvert: 'معکوس کردن انتخاب‌ها در صفحه ی کنونی', - }, - Modal: { - okText: 'تایید', - cancelText: 'لغو', - justOkText: 'تایید', - }, - Popconfirm: { - okText: 'تایید', - cancelText: 'لغو', - }, - Transfer: { - searchPlaceholder: 'جستجو', - itemUnit: '', - itemsUnit: '', - }, - Upload: { - uploading: 'در حال آپلود...', - removeFile: 'حذف فایل', - uploadError: 'خطا در آپلود', - previewFile: 'مشاهده‌ی فایل', - }, - Empty: { - description: 'داده‌ای موجود نیست', - }, -}; +export default locale; diff --git a/components/locale-provider/fi_FI.js b/components/locale-provider/fi_FI.js index 08c5474ff..59c506f6b 100644 --- a/components/locale-provider/fi_FI.js +++ b/components/locale-provider/fi_FI.js @@ -1,43 +1,3 @@ -import Pagination from '../vc-pagination/locale/fi_FI'; -import DatePicker from '../date-picker/locale/fi_FI'; -import TimePicker from '../time-picker/locale/fi_FI'; -import Calendar from '../calendar/locale/fi_FI'; +import locale from '../locale/fi_FI'; -export default { - locale: 'fi', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Suodatus valikko', - filterConfirm: 'OK', - filterReset: 'Tyhjennä', - selectAll: 'Valitse kaikki', - selectInvert: 'Valitse päinvastoin', - sortTitle: 'Lajittele', - }, - Modal: { - okText: 'OK', - cancelText: 'Peruuta', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Peruuta', - }, - Transfer: { - searchPlaceholder: 'Etsi täältä', - itemUnit: 'kohde', - itemsUnit: 'kohdetta', - }, - Upload: { - uploading: 'Lähetetään...', - removeFile: 'Poista tiedosto', - uploadError: 'Virhe lähetyksessä', - previewFile: 'Esikatsele tiedostoa', - }, - Empty: { - description: 'Ei kohteita', - }, -}; +export default locale; diff --git a/components/locale-provider/fr_BE.js b/components/locale-provider/fr_BE.js index c00ae5638..b93758edc 100644 --- a/components/locale-provider/fr_BE.js +++ b/components/locale-provider/fr_BE.js @@ -1,34 +1,3 @@ -import Pagination from '../vc-pagination/locale/fr_BE'; -import DatePicker from '../date-picker/locale/fr_BE'; -import TimePicker from '../time-picker/locale/fr_BE'; -import Calendar from '../calendar/locale/fr_BE'; +import locale from '../locale/fr_BE'; -export default { - locale: 'fr', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filtrer', - filterConfirm: 'OK', - filterReset: 'Réinitialiser', - }, - Modal: { - okText: 'OK', - cancelText: 'Annuler', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Annuler', - }, - Transfer: { - searchPlaceholder: 'Recherche', - itemUnit: 'élément', - itemsUnit: 'éléments', - }, - Empty: { - description: 'Aucune donnée', - }, -}; +export default locale; diff --git a/components/locale-provider/fr_FR.js b/components/locale-provider/fr_FR.js index 5ee3ee122..97184887b 100644 --- a/components/locale-provider/fr_FR.js +++ b/components/locale-provider/fr_FR.js @@ -1,34 +1,3 @@ -import Pagination from '../vc-pagination/locale/fr_FR'; -import DatePicker from '../date-picker/locale/fr_FR'; -import TimePicker from '../time-picker/locale/fr_FR'; -import Calendar from '../calendar/locale/fr_FR'; +import locale from '../locale/fr_FR'; -export default { - locale: 'fr', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filtrer', - filterConfirm: 'OK', - filterReset: 'Réinitialiser', - }, - Modal: { - okText: 'OK', - cancelText: 'Annuler', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Annuler', - }, - Transfer: { - searchPlaceholder: 'Recherche', - itemUnit: 'élément', - itemsUnit: 'éléments', - }, - Empty: { - description: 'Aucune donnée', - }, -}; +export default locale; diff --git a/components/locale-provider/he_IL.js b/components/locale-provider/he_IL.js index 834fcd30c..225fc31cb 100644 --- a/components/locale-provider/he_IL.js +++ b/components/locale-provider/he_IL.js @@ -1,42 +1,3 @@ -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'; +import locale from '../locale/he_IL'; -export default { - locale: 'he', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'תפריט סינון', - filterConfirm: 'אישור', - filterReset: 'איפוס', - selectAll: 'בחר הכל', - selectInvert: 'הפוך בחירה', - }, - Modal: { - okText: 'אישור', - cancelText: 'ביטול', - justOkText: 'אישור', - }, - Popconfirm: { - okText: 'אישור', - cancelText: 'ביטול', - }, - Transfer: { - searchPlaceholder: 'חפש כאן', - itemUnit: 'פריט', - itemsUnit: 'פריטים', - }, - Upload: { - uploading: 'מעלה...', - removeFile: 'הסר קובץ', - uploadError: 'שגיאת העלאה', - previewFile: 'הצג קובץ', - }, - Empty: { - description: 'אין מידע', - }, -}; +export default locale; diff --git a/components/locale-provider/hi_IN.js b/components/locale-provider/hi_IN.js index 7f4b1d1de..fb1b0bda4 100644 --- a/components/locale-provider/hi_IN.js +++ b/components/locale-provider/hi_IN.js @@ -1,50 +1,3 @@ -import Pagination from '../vc-pagination/locale/hi_IN'; -import DatePicker from '../date-picker/locale/hi_IN'; -import TimePicker from '../time-picker/locale/hi_IN'; -import Calendar from '../calendar/locale/hi_IN'; +import locale from '../locale/hi_IN'; -export default { - locale: 'hi', - Pagination, - DatePicker, - TimePicker, - Calendar, - // locales for all comoponents - global: { - placeholder: 'कृपया चुनें', - }, - Table: { - filterTitle: 'सूची बंद करें', - filterConfirm: 'अच्छी तरह से', - filterReset: 'रीसेट', - emptyText: 'कोई जानकारी नहीं', - selectAll: 'वर्तमान पृष्ठ का चयन करें', - selectInvert: 'वर्तमान पृष्ठ घुमाएं', - sortTitle: 'द्वारा क्रमबद्ध करें', - }, - Modal: { - okText: 'अच्छी तरह से', - cancelText: 'रद्द करना', - justOkText: 'अच्छी तरह से', - }, - Popconfirm: { - okText: 'अच्छी तरह से', - cancelText: 'रद्द करना', - }, - Transfer: { - titles: ['', ''], - notFoundContent: 'नहीं मिला', - searchPlaceholder: 'यहां खोजें', - itemUnit: 'तत्त्व', - itemsUnit: 'विषय-वस्तु', - }, - Select: { - notFoundContent: 'नहीं मिला', - }, - Upload: { - uploading: 'अपलोडिंग...', - removeFile: 'फ़ाइल निकालें', - uploadError: 'अपलोड में त्रुटि', - previewFile: 'फ़ाइल पूर्वावलोकन', - }, -}; +export default locale; diff --git a/components/locale-provider/hr_HR.js b/components/locale-provider/hr_HR.js new file mode 100644 index 000000000..d021e1101 --- /dev/null +++ b/components/locale-provider/hr_HR.js @@ -0,0 +1,3 @@ +import locale from '../locale/hr_HR'; + +export default locale; diff --git a/components/locale-provider/hu_HU.js b/components/locale-provider/hu_HU.js index 5ec5c98fd..6087d3fd3 100644 --- a/components/locale-provider/hu_HU.js +++ b/components/locale-provider/hu_HU.js @@ -1,43 +1,3 @@ -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'; +import locale from '../locale/hu_HU'; -export default { - locale: 'hu', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Szűrők', - filterConfirm: 'Alkalmazás', - filterReset: 'Visszaállítás', - 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: { - searchPlaceholder: 'Keresés', - itemUnit: 'elem', - itemsUnit: 'elemek', - }, - Upload: { - uploading: 'Feltöltés...', - removeFile: 'Fájl eltávolítása', - uploadError: 'Feltöltési hiba', - previewFile: 'Fájl előnézet', - }, - Empty: { - description: 'Nincs adat', - }, -}; +export default locale; diff --git a/components/locale-provider/hy_AM.js b/components/locale-provider/hy_AM.js new file mode 100644 index 000000000..70cfbb12b --- /dev/null +++ b/components/locale-provider/hy_AM.js @@ -0,0 +1,3 @@ +import locale from '../locale/hy_AM'; + +export default locale; diff --git a/components/locale-provider/id_ID.js b/components/locale-provider/id_ID.js index 5653b617d..59b676133 100644 --- a/components/locale-provider/id_ID.js +++ b/components/locale-provider/id_ID.js @@ -1,44 +1,3 @@ -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'; +import locale from '../locale/id_ID'; -export default { - locale: 'id', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Saring', - filterConfirm: 'OK', - filterReset: 'Hapus', - selectAll: 'Pilih semua di halaman ini', - selectInvert: 'Balikkan pilihan di halaman ini', - sortTitle: 'Urutkan', - }, - Modal: { - okText: 'OK', - cancelText: 'Batal', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Batal', - }, - Transfer: { - titles: ['', ''], - searchPlaceholder: 'Cari', - itemUnit: 'item', - itemsUnit: 'item', - }, - Upload: { - uploading: 'Mengunggah...', - removeFile: 'Hapus file', - uploadError: 'Kesalahan pengunggahan', - previewFile: 'File pratinjau', - }, - Empty: { - description: 'Tidak ada data', - }, -}; +export default locale; diff --git a/components/locale-provider/index.en-US.md b/components/locale-provider/index.en-US.md deleted file mode 100644 index 88cb1f637..000000000 --- a/components/locale-provider/index.en-US.md +++ /dev/null @@ -1,54 +0,0 @@ -# LocaleProvider - -`LocaleProvider` provides a uniform localization support for built-in text of components. - -## Usage - -`LocaleProvider` takes use of [provide/inject](https://vuejs.org/v2/api/#provide-inject), a feature of Vue, to accomplish global effectiveness by wrapping the app only once. - -```html - - -``` - -We provide some locale like English, Chinese, Russian, German, French and etc, all locale packages can be found in [here](https://github.com/vueComponent/ant-design-vue/tree/master/components/locale-provider). - -Note: if you need to use antd's UMD dist file, please use `antd/dist/antd-with-locales.js` and corresponding moment locale: - -```html - - -``` - -### Add a new language - -If you can't find your language, you are welcome to create a locale package based on [en_US](https://github.com/vueComponent/ant-design-vue/blob/master/components/locale-provider/en_US.js) and send us a pull request. - -### Other localization needs - -This component aims for localization of the built-in text, if you want to support other documents, we recommend using [vue-i18n](https://github.com/kazupon/vue-i18n). - -## Examples diff --git a/components/locale-provider/index.jsx b/components/locale-provider/index.jsx index 52672225c..5ce511ca3 100644 --- a/components/locale-provider/index.jsx +++ b/components/locale-provider/index.jsx @@ -3,6 +3,7 @@ import * as moment from 'moment'; import interopDefault from '../_util/interopDefault'; import { changeConfirmLocale } from '../modal/locale'; import Base from '../base'; +import warning from '../_util/warning'; // export interface Locale { // locale: string; // Pagination?: Object; @@ -16,7 +17,7 @@ import Base from '../base'; // Select?: Object; // Upload?: Object; // } - +export const ANT_MARK = 'internalMark'; function setMomentLocale(locale) { if (locale && locale.locale) { interopDefault(moment).locale(locale.locale); @@ -28,9 +29,15 @@ function setMomentLocale(locale) { const LocaleProvider = { name: 'ALocaleProvider', props: { - locale: PropTypes.object.def({}), + locale: PropTypes.object.def(() => ({})), + _ANT_MARK__: PropTypes.string, }, data() { + warning( + this._ANT_MARK__ === ANT_MARK, + 'LocaleProvider', + '`LocaleProvider` is deprecated. Please use `locale` with `ConfigProvider` instead', + ); return { antLocale: { ...this.locale, @@ -50,6 +57,7 @@ const LocaleProvider = { exist: true, }; setMomentLocale(val); + changeConfirmLocale(val && val.Modal); }, }, created() { @@ -57,10 +65,6 @@ const LocaleProvider = { setMomentLocale(locale); changeConfirmLocale(locale && locale.Modal); }, - updated() { - const { locale } = this; - changeConfirmLocale(locale && locale.Modal); - }, beforeDestroy() { changeConfirmLocale(); }, diff --git a/components/locale-provider/index.zh-CN.md b/components/locale-provider/index.zh-CN.md deleted file mode 100644 index bda8b66c5..000000000 --- a/components/locale-provider/index.zh-CN.md +++ /dev/null @@ -1,54 +0,0 @@ -# LocaleProvider 国际化 - -为组件内建文案提供统一的国际化支持。 - -## 使用 - -LocaleProvider 使用 Vue 的 [provide/inject](https://cn.vuejs.org/v2/api/#provide-inject) 特性,只需在应用外围包裹一次即可全局生效。 - -```html - - -``` - -我们提供了英语,中文,俄语,法语,德语等多种语言支持,所有语言包可以在 [这里](https://github.com/vueComponent/ant-design-vue/tree/master/components/locale-provider) 找到。 - -注意:如果你需要使用 UMD 版的 dist 文件,应该引入 `antd/dist/antd-with-locales.js`,同时引入 moment 对应的 locale,然后按以下方式使用: - -```html - - -``` - -### 增加语言包 - -如果你找不到你需要的语言包,欢迎你在 [英文语言包](https://github.com/vueComponent/ant-design-vue/blob/master/components/locale-provider/en_US.js) 的基础上创建一个新的语言包,并给我们 Pull Request。 - -### 其他国际化需求 - -本模块仅用于组件的内建文案,若有业务文案的国际化需求,建议使用 [vue-i18n](https://github.com/kazupon/vue-i18n) - -## 代码演示 diff --git a/components/locale-provider/is_IS.js b/components/locale-provider/is_IS.js index 88386db25..cf8b9a9f6 100644 --- a/components/locale-provider/is_IS.js +++ b/components/locale-provider/is_IS.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/is_IS'; -import DatePicker from '../date-picker/locale/is_IS'; -import TimePicker from '../time-picker/locale/is_IS'; -import Calendar from '../calendar/locale/is_IS'; +import locale from '../locale/is_IS'; -export default { - locale: 'is', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Afmarkanir', - filterConfirm: 'Staðfesta', - filterReset: 'Núllstilla', - selectAll: 'Velja allt', - selectInvert: 'Viðsnúa vali', - }, - Modal: { - okText: 'Áfram', - cancelText: 'Hætta við', - justOkText: 'Í lagi', - }, - Popconfirm: { - okText: 'Áfram', - cancelText: 'Hætta við', - }, - Transfer: { - searchPlaceholder: 'Leita hér', - itemUnit: 'færsla', - itemsUnit: 'færslur', - }, - Upload: { - uploading: 'Hleð upp...', - removeFile: 'Fjarlægja skrá', - uploadError: 'Villa við að hlaða upp', - previewFile: 'Forskoða skrá', - }, - Empty: { - description: 'Engin gögn', - }, -}; +export default locale; diff --git a/components/locale-provider/it_IT.js b/components/locale-provider/it_IT.js index 0be4d90f2..c3f68f401 100644 --- a/components/locale-provider/it_IT.js +++ b/components/locale-provider/it_IT.js @@ -1,43 +1,3 @@ -import Pagination from '../vc-pagination/locale/it_IT'; -import DatePicker from '../date-picker/locale/it_IT'; -import TimePicker from '../time-picker/locale/it_IT'; -import Calendar from '../calendar/locale/it_IT'; +import locale from '../locale/it_IT'; -export default { - locale: 'it', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Menù Filtro', - filterConfirm: 'OK', - filterReset: 'Reset', - selectAll: 'Seleziona pagina corrente', - selectInvert: 'Inverti selezione nella pagina corrente', - sortTitle: 'Ordina', - }, - Modal: { - okText: 'OK', - cancelText: 'Annulla', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Annulla', - }, - Transfer: { - searchPlaceholder: 'Cerca qui', - itemUnit: 'articolo', - itemsUnit: 'elementi', - }, - Upload: { - uploading: 'Caricamento...', - removeFile: 'Rimuovi il file', - uploadError: 'Errore di caricamento', - previewFile: 'Anteprima file', - }, - Empty: { - description: 'Nessun dato', - }, -}; +export default locale; diff --git a/components/locale-provider/ja_JP.js b/components/locale-provider/ja_JP.js index 07469486e..9f1f2f794 100644 --- a/components/locale-provider/ja_JP.js +++ b/components/locale-provider/ja_JP.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/ja_JP'; -import DatePicker from '../date-picker/locale/ja_JP'; -import TimePicker from '../time-picker/locale/ja_JP'; -import Calendar from '../calendar/locale/ja_JP'; +import locale from '../locale/ja_JP'; -export default { - locale: 'ja', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'メニューをフィルター', - filterConfirm: 'OK', - filterReset: 'リセット', - selectAll: 'すべてを選択', - selectInvert: '選択を反転', - }, - Modal: { - okText: 'OK', - cancelText: 'キャンセル', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'キャンセル', - }, - Transfer: { - searchPlaceholder: 'ここを検索', - itemUnit: 'アイテム', - itemsUnit: 'アイテム', - }, - Upload: { - uploading: 'アップロード中...', - removeFile: 'ファイルを削除', - uploadError: 'アップロードエラー', - previewFile: 'ファイルをプレビュー', - }, - Empty: { - description: 'データがありません', - }, -}; +export default locale; diff --git a/components/locale-provider/kn_IN.js b/components/locale-provider/kn_IN.js index 89213fdbf..ed0ac385b 100644 --- a/components/locale-provider/kn_IN.js +++ b/components/locale-provider/kn_IN.js @@ -1,50 +1,3 @@ -import Pagination from '../vc-pagination/locale/kn_IN'; -import DatePicker from '../date-picker/locale/kn_IN'; -import TimePicker from '../time-picker/locale/kn_IN'; -import Calendar from '../calendar/locale/kn_IN'; +import locale from '../locale/kn_IN'; -export default { - locale: 'kn', - Pagination, - DatePicker, - TimePicker, - Calendar, - // locales for all comoponents - global: { - placeholder: 'ದಯವಿಟ್ಟು ಆರಿಸಿ', - }, - Table: { - filterTitle: 'ಪಟ್ಟಿ ಸೋಸಿ', - filterConfirm: 'ಸರಿ', - filterReset: 'ಮರುಹೊಂದಿಸಿ', - emptyText: 'ಮಾಹಿತಿ ಇಲ್ಲ', - selectAll: 'ಪ್ರಸ್ತುತ ಪುಟವನ್ನು ಆಯ್ಕೆಮಾಡಿ', - selectInvert: 'ಪ್ರಸ್ತುತ ಪುಟವನ್ನು ತಿರುಗಿಸಿ', - sortTitle: 'ವಿಂಗಡಿಸಿ', - }, - Modal: { - okText: 'ಸರಿ', - cancelText: 'ರದ್ದು', - justOkText: 'ಸರಿ', - }, - Popconfirm: { - okText: 'ಸರಿ', - cancelText: 'ರದ್ದು', - }, - Transfer: { - titles: ['', ''], - notFoundContent: 'ದೊರೆತಿಲ್ಲ', - searchPlaceholder: 'ಇಲ್ಲಿ ಹುಡುಕಿ', - itemUnit: 'ವಿಷಯ', - itemsUnit: 'ವಿಷಯಗಳು', - }, - Select: { - notFoundContent: 'ದೊರೆತಿಲ್ಲ', - }, - Upload: { - uploading: 'ಏರಿಸಿ...', - removeFile: 'ಫೈಲ್ ತೆಗೆದುಹಾಕಿ', - uploadError: 'ಏರಿಸುವ ದೋಷ', - previewFile: 'ಫೈಲ್ ಮುನ್ನೋಟ', - }, -}; +export default locale; diff --git a/components/locale-provider/ko_KR.js b/components/locale-provider/ko_KR.js index 8fbceb8ae..75e5750d5 100644 --- a/components/locale-provider/ko_KR.js +++ b/components/locale-provider/ko_KR.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/ko_KR'; -import DatePicker from '../date-picker/locale/ko_KR'; -import TimePicker from '../time-picker/locale/ko_KR'; -import Calendar from '../calendar/locale/ko_KR'; +import locale from '../locale/ko_KR'; -export default { - locale: 'ko', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: '필터 메뉴', - filterConfirm: '확인', - filterReset: '초기화', - selectAll: '모두 선택', - selectInvert: '선택 반전', - }, - Modal: { - okText: '확인', - cancelText: '취소', - justOkText: '확인', - }, - Popconfirm: { - okText: '확인', - cancelText: '취소', - }, - Transfer: { - searchPlaceholder: '여기에 검색하세요', - itemUnit: '개', - itemsUnit: '개', - }, - Upload: { - uploading: '업로드 중...', - removeFile: '파일 삭제', - uploadError: '업로드 실패', - previewFile: '파일 미리보기', - }, - Empty: { - description: '데이터 없음', - }, -}; +export default locale; diff --git a/components/locale-provider/ku_IQ.js b/components/locale-provider/ku_IQ.js old mode 100755 new mode 100644 index c55d192bc..daf734fb1 --- a/components/locale-provider/ku_IQ.js +++ b/components/locale-provider/ku_IQ.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/ku_IQ'; -import DatePicker from '../date-picker/locale/ku_IQ'; -import TimePicker from '../time-picker/locale/ku_IQ'; -import Calendar from '../calendar/locale/ku_IQ'; +import locale from '../locale/ku_IQ'; -export default { - locale: 'ku-iq', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Menuê peldanka', - filterConfirm: 'Temam', - filterReset: 'Jê bibe', - selectAll: 'Hemî hilbijêre', - selectInvert: 'Hilbijartinan veguhere', - }, - Modal: { - okText: 'Temam', - cancelText: 'Betal ke', - justOkText: 'Temam', - }, - Popconfirm: { - okText: 'Temam', - cancelText: 'Betal ke', - }, - Transfer: { - searchPlaceholder: 'Lêgerîn', - itemUnit: 'tişt', - itemsUnit: 'tişt', - }, - Upload: { - uploading: 'Bardike...', - removeFile: 'Pelê rabike', - uploadError: 'Xeta barkirine', - previewFile: 'Pelê pêşbibîne', - }, - Empty: { - description: 'Agahî tune', - }, -}; +export default locale; diff --git a/components/locale-provider/lv_LV.js b/components/locale-provider/lv_LV.js new file mode 100644 index 000000000..57ace7195 --- /dev/null +++ b/components/locale-provider/lv_LV.js @@ -0,0 +1,3 @@ +import locale from '../locale/lv_LV'; + +export default locale; diff --git a/components/locale-provider/mk_MK.js b/components/locale-provider/mk_MK.js new file mode 100644 index 000000000..c4e03653b --- /dev/null +++ b/components/locale-provider/mk_MK.js @@ -0,0 +1,3 @@ +import locale from '../locale/mk_MK'; + +export default locale; diff --git a/components/locale-provider/mn_MN.js b/components/locale-provider/mn_MN.js index 3be424766..bbfb83f73 100644 --- a/components/locale-provider/mn_MN.js +++ b/components/locale-provider/mn_MN.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/mn_MN'; -import DatePicker from '../date-picker/locale/mn_MN'; -import TimePicker from '../time-picker/locale/mn_MN'; -import Calendar from '../calendar/locale/mn_MN'; +import locale from '../locale/mn_MN'; -export default { - locale: 'mn-mn', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Хайх цэс', - filterConfirm: 'OK', - filterReset: 'Цэвэрлэх', - selectAll: 'Бүгдийг сонгох', - selectInvert: 'Бусдыг сонгох', - }, - Modal: { - okText: 'OK', - cancelText: 'Цуцлах', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Цуцлах', - }, - Transfer: { - searchPlaceholder: 'Хайх', - itemUnit: 'Зүйл', - itemsUnit: 'Зүйлүүд', - }, - Upload: { - uploading: 'Хуулж байна...', - removeFile: 'Файл устгах', - uploadError: 'Хуулахад алдаа гарлаа', - previewFile: 'Файлыг түргэн үзэх', - }, - Empty: { - description: 'Мэдээлэл байхгүй байна', - }, -}; +export default locale; diff --git a/components/locale-provider/ms_MY.js b/components/locale-provider/ms_MY.js new file mode 100644 index 000000000..80799ae69 --- /dev/null +++ b/components/locale-provider/ms_MY.js @@ -0,0 +1,3 @@ +import locale from '../locale/ms_MY'; + +export default locale; diff --git a/components/locale-provider/nb_NO.js b/components/locale-provider/nb_NO.js index 84f736047..6f0c0d4e7 100644 --- a/components/locale-provider/nb_NO.js +++ b/components/locale-provider/nb_NO.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/nb_NO'; -import DatePicker from '../date-picker/locale/nb_NO'; -import TimePicker from '../time-picker/locale/nb_NO'; -import Calendar from '../calendar/locale/nb_NO'; +import locale from '../locale/nb_NO'; -export default { - locale: 'nb', - DatePicker, - TimePicker, - Calendar, - Pagination, - Table: { - filterTitle: 'Filtermeny', - filterConfirm: 'OK', - filterReset: 'Nullstill', - selectAll: 'Velg alle', - selectInvert: 'Inverter valg', - }, - Modal: { - okText: 'OK', - cancelText: 'Avbryt', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Avbryt', - }, - Transfer: { - searchPlaceholder: 'Søk her', - itemUnit: 'element', - itemsUnit: 'elementer', - }, - Upload: { - uploading: 'Laster opp...', - removeFile: 'Fjern fil', - uploadError: 'Feil ved opplastning', - previewFile: 'Forhåndsvisning', - }, - Empty: { - description: 'Ingen data', - }, -}; +export default locale; diff --git a/components/locale-provider/ne-NP.js b/components/locale-provider/ne-NP.js index 8c4c5eeee..234388b4d 100644 --- a/components/locale-provider/ne-NP.js +++ b/components/locale-provider/ne-NP.js @@ -1,43 +1,3 @@ -import Pagination from '../vc-pagination/locale/en_US'; -import DatePicker from '../date-picker/locale/en_US'; -import TimePicker from '../time-picker/locale/en_US'; -import Calendar from '../calendar/locale/en_US'; +import locale from '../locale/ne_NP'; -export default { - locale: 'ne-np', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'फिल्टर मेनु', - filterConfirm: 'हो', - filterReset: 'रीसेट', - selectAll: 'सबै छान्नुुहोस्', - selectInvert: 'छनौट उल्टाउनुहोस', - }, - Modal: { - okText: 'हो', - cancelText: 'होईन', - justOkText: 'हो', - }, - Popconfirm: { - okText: 'हो', - cancelText: 'होईन', - }, - Transfer: { - titles: ['', ''], - searchPlaceholder: 'यहाँ खोज्नुहोस्', - itemUnit: 'वस्तु', - itemsUnit: 'वस्तुहरू', - }, - Upload: { - uploading: 'अपलोड गर्दै...', - removeFile: 'फाइल हटाउनुहोस्', - uploadError: 'अप्लोडमा समस्या भयो', - previewFile: 'फाइल पूर्वावलोकन गर्नुहोस्', - }, - Empty: { - description: 'डाटा छैन', - }, -}; +export default locale; diff --git a/components/locale-provider/ne_NP.js b/components/locale-provider/ne_NP.js new file mode 100644 index 000000000..234388b4d --- /dev/null +++ b/components/locale-provider/ne_NP.js @@ -0,0 +1,3 @@ +import locale from '../locale/ne_NP'; + +export default locale; diff --git a/components/locale-provider/nl_BE.js b/components/locale-provider/nl_BE.js index 3e8524aa7..a52233beb 100644 --- a/components/locale-provider/nl_BE.js +++ b/components/locale-provider/nl_BE.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/nl_BE'; -import DatePicker from '../date-picker/locale/nl_BE'; -import TimePicker from '../time-picker/locale/nl_BE'; -import Calendar from '../calendar/locale/nl_BE'; +import locale from '../locale/nl_BE'; -export default { - locale: 'nl-be', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'FilterMenu', - filterConfirm: 'OK', - filterReset: 'Reset', - selectAll: 'Selecteer huidige pagina', - selectInvert: 'Selecteer huidige pagina', - }, - Modal: { - okText: 'OK', - cancelText: 'Annuleer', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Annuleer', - }, - Transfer: { - searchPlaceholder: 'Zoek hier', - itemUnit: 'item', - itemsUnit: 'items', - }, - Upload: { - uploading: 'Uploaden...', - removeFile: 'Bestand verwijderen', - uploadError: 'Upload fout', - previewFile: 'Preview bestand', - }, - Empty: { - description: 'Geen gegevens', - }, -}; +export default locale; diff --git a/components/locale-provider/nl_NL.js b/components/locale-provider/nl_NL.js index 0c34d7aac..ee14c0d4b 100644 --- a/components/locale-provider/nl_NL.js +++ b/components/locale-provider/nl_NL.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/nl_NL'; -import DatePicker from '../date-picker/locale/nl_NL'; -import TimePicker from '../time-picker/locale/nl_NL'; -import Calendar from '../calendar/locale/nl_NL'; +import locale from '../locale/nl_NL'; -export default { - locale: 'nl', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filteren', - filterConfirm: 'OK', - filterReset: 'Reset', - selectAll: 'Selecteer huidige pagina', - selectInvert: 'Deselecteer huidige pagina', - }, - Modal: { - okText: 'OK', - cancelText: 'Annuleren', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Annuleren', - }, - Transfer: { - searchPlaceholder: 'Zoeken', - itemUnit: 'item', - itemsUnit: 'items', - }, - Upload: { - uploading: 'Uploaden...', - removeFile: 'Verwijder bestand', - uploadError: 'Fout tijdens uploaden', - previewFile: 'Bekijk bestand', - }, - Empty: { - description: 'Geen gegevens', - }, -}; +export default locale; diff --git a/components/locale-provider/pl_PL.js b/components/locale-provider/pl_PL.js index 1ec848133..6ec40c21a 100644 --- a/components/locale-provider/pl_PL.js +++ b/components/locale-provider/pl_PL.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/pl_PL'; -import DatePicker from '../date-picker/locale/pl_PL'; -import TimePicker from '../time-picker/locale/pl_PL'; -import Calendar from '../calendar/locale/pl_PL'; +import locale from '../locale/pl_PL'; -export default { - locale: 'pl', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Menu filtra', - filterConfirm: 'OK', - filterReset: 'Wyczyść', - selectAll: 'Zaznacz bieżącą stronę', - selectInvert: 'Odwróć zaznaczenie', - }, - Modal: { - okText: 'OK', - cancelText: 'Anuluj', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Anuluj', - }, - Transfer: { - searchPlaceholder: 'Szukaj', - itemUnit: 'obiekt', - itemsUnit: 'obiekty', - }, - Upload: { - uploading: 'Wysyłanie...', - removeFile: 'Usuń plik', - uploadError: 'Błąd wysyłania', - previewFile: 'Podejrzyj plik', - }, - Empty: { - description: 'Brak danych', - }, -}; +export default locale; diff --git a/components/locale-provider/pt_BR.js b/components/locale-provider/pt_BR.js index 832c0de7e..bca2fbc17 100644 --- a/components/locale-provider/pt_BR.js +++ b/components/locale-provider/pt_BR.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/pt_BR'; -import DatePicker from '../date-picker/locale/pt_BR'; -import TimePicker from '../time-picker/locale/pt_BR'; -import Calendar from '../calendar/locale/pt_BR'; +import locale from '../locale/pt_BR'; -export default { - locale: 'pt-br', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filtro', - filterConfirm: 'OK', - filterReset: 'Resetar', - selectAll: 'Selecionar página atual', - selectInvert: 'Inverter seleção', - }, - Modal: { - okText: 'OK', - cancelText: 'Cancelar', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Cancelar', - }, - Transfer: { - searchPlaceholder: 'Procurar', - itemUnit: 'item', - itemsUnit: 'items', - }, - Upload: { - uploading: 'Enviando...', - removeFile: 'Remover arquivo', - uploadError: 'Erro no envio', - previewFile: 'Visualizar arquivo', - }, - Empty: { - description: 'Não há dados', - }, -}; +export default locale; diff --git a/components/locale-provider/pt_PT.js b/components/locale-provider/pt_PT.js index a20a5cf1b..325077d95 100644 --- a/components/locale-provider/pt_PT.js +++ b/components/locale-provider/pt_PT.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/pt_PT'; -import DatePicker from '../date-picker/locale/pt_PT'; -import TimePicker from '../time-picker/locale/pt_PT'; -import Calendar from '../calendar/locale/pt_PT'; +import locale from '../locale/pt_PT'; -export default { - locale: 'pt', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filtro', - filterConfirm: 'Aplicar', - filterReset: 'Reiniciar', - selectAll: 'Selecionar página atual', - selectInvert: 'Inverter seleção', - }, - Modal: { - okText: 'OK', - cancelText: 'Cancelar', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Cancelar', - }, - Transfer: { - searchPlaceholder: 'Procurar...', - itemUnit: 'item', - itemsUnit: 'itens', - }, - Upload: { - uploading: 'A carregar...', - removeFile: 'Remover', - uploadError: 'Erro ao carregar', - previewFile: 'Pré-visualizar', - }, - Empty: { - description: 'Sem resultados', - }, -}; +export default locale; diff --git a/components/locale-provider/ro_RO.js b/components/locale-provider/ro_RO.js new file mode 100644 index 000000000..c95794f77 --- /dev/null +++ b/components/locale-provider/ro_RO.js @@ -0,0 +1,3 @@ +import locale from '../locale/ro_RO'; + +export default locale; diff --git a/components/locale-provider/ru_RU.js b/components/locale-provider/ru_RU.js index a16b5b344..130e0f459 100644 --- a/components/locale-provider/ru_RU.js +++ b/components/locale-provider/ru_RU.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/ru_RU'; -import DatePicker from '../date-picker/locale/ru_RU'; -import TimePicker from '../time-picker/locale/ru_RU'; -import Calendar from '../calendar/locale/ru_RU'; +import locale from '../locale/ru_RU'; -export default { - locale: 'ru', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Фильтр', - filterConfirm: 'OK', - filterReset: 'Сбросить', - selectAll: 'Выбрать всё', - selectInvert: 'Инвертировать выбор', - }, - Modal: { - okText: 'OK', - cancelText: 'Отмена', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Отмена', - }, - Transfer: { - searchPlaceholder: 'Поиск', - itemUnit: 'элем.', - itemsUnit: 'элем.', - }, - Upload: { - uploading: 'Загрузка...', - removeFile: 'Удалить файл', - uploadError: 'При загрузке произошла ошибка', - previewFile: 'Предпросмотр файла', - }, - Empty: { - description: 'Нет данных', - }, -}; +export default locale; diff --git a/components/locale-provider/sk_SK.js b/components/locale-provider/sk_SK.js index ae6dde795..1a7836054 100644 --- a/components/locale-provider/sk_SK.js +++ b/components/locale-provider/sk_SK.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/sk_SK'; -import DatePicker from '../date-picker/locale/sk_SK'; -import TimePicker from '../time-picker/locale/sk_SK'; -import Calendar from '../calendar/locale/sk_SK'; +import locale from '../locale/sk_SK'; -export default { - locale: 'sk', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filter', - filterConfirm: 'OK', - filterReset: 'Obnoviť', - selectAll: 'Vybrať všetko', - selectInvert: 'Vybrať opačné', - }, - Modal: { - okText: 'OK', - cancelText: 'Zrušiť', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Zrušiť', - }, - Transfer: { - searchPlaceholder: 'Vyhľadávanie', - itemUnit: 'položka', - itemsUnit: 'položiek', - }, - Upload: { - uploading: 'Nahrávanie...', - removeFile: 'Odstrániť súbor', - uploadError: 'Chyba pri nahrávaní', - previewFile: 'Zobraziť súbor', - }, - Empty: { - description: 'Žiadne dáta', - }, -}; +export default locale; diff --git a/components/locale-provider/sl_SI.js b/components/locale-provider/sl_SI.js index 7218b1e74..183230ce6 100644 --- a/components/locale-provider/sl_SI.js +++ b/components/locale-provider/sl_SI.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/sl_SI'; -import DatePicker from '../date-picker/locale/sl_SI'; -import TimePicker from '../time-picker/locale/sl_SI'; -import Calendar from '../calendar/locale/sl_SI'; +import locale from '../locale/sl_SI'; -export default { - locale: 'sl', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filter', - filterConfirm: 'Filtriraj', - filterReset: 'Pobriši filter', - selectAll: 'Izberi vse na trenutni strani', - selectInvert: 'Obrni izbor na trenutni strani', - }, - Modal: { - okText: 'V redu', - cancelText: 'Prekliči', - justOkText: 'V redu', - }, - Popconfirm: { - okText: 'v redu', - cancelText: 'Prekliči', - }, - Transfer: { - searchPlaceholder: 'Išči tukaj', - itemUnit: 'Objekt', - itemsUnit: 'Objektov', - }, - Upload: { - uploading: 'Nalaganje...', - removeFile: 'Odstrani datoteko', - uploadError: 'Napaka pri nalaganju', - previewFile: 'Predogled datoteke', - }, - Empty: { - description: 'Ni podatkov', - }, -}; +export default locale; diff --git a/components/locale-provider/sr_RS.js b/components/locale-provider/sr_RS.js index a71b345a8..3af113eb1 100644 --- a/components/locale-provider/sr_RS.js +++ b/components/locale-provider/sr_RS.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/sr_RS'; -import DatePicker from '../date-picker/locale/sr_RS'; -import TimePicker from '../time-picker/locale/sr_RS'; -import Calendar from '../calendar/locale/sr_RS'; +import locale from '../locale/sr_RS'; -export default { - locale: 'sr', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filter', - filterConfirm: 'Primeni filter', - filterReset: 'Resetuj filter', - selectAll: 'Obeleži sve na trenutnoj strani', - selectInvert: 'Obrni selekciju na trenutnoj stranici', - }, - Modal: { - okText: 'U redu', - cancelText: 'Otkaži', - justOkText: 'U redu', - }, - Popconfirm: { - okText: 'U redu', - cancelText: 'Otkaži', - }, - Transfer: { - searchPlaceholder: 'Pretražite ovde', - itemUnit: 'stavka', - itemsUnit: 'stavki', - }, - Upload: { - uploading: 'Slanje...', - removeFile: 'Ukloni fajl', - uploadError: 'Greška prilikom slanja', - previewFile: 'Pogledaj fajl', - }, - Empty: { - description: 'Nema podataka', - }, -}; +export default locale; diff --git a/components/locale-provider/style/index.less b/components/locale-provider/style/index.less index df1dee5e0..eaf3a7d1e 100644 --- a/components/locale-provider/style/index.less +++ b/components/locale-provider/style/index.less @@ -1,2 +1,2 @@ // placeholder -@import '../../style/themes/default'; +@import '../../style/themes/index'; diff --git a/components/locale-provider/sv_SE.js b/components/locale-provider/sv_SE.js index 0bcf4726f..8bdc8e9ff 100644 --- a/components/locale-provider/sv_SE.js +++ b/components/locale-provider/sv_SE.js @@ -1,34 +1,3 @@ -import Pagination from '../vc-pagination/locale/sv_SE'; -import DatePicker from '../date-picker/locale/sv_SE'; -import TimePicker from '../time-picker/locale/sv_SE'; -import Calendar from '../calendar/locale/sv_SE'; +import locale from '../locale/sv_SE'; -export default { - locale: 'sv', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Filtermeny', - filterConfirm: 'OK', - filterReset: 'Rensa', - }, - Modal: { - okText: 'OK', - cancelText: 'Avbryt', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Avbryt', - }, - Transfer: { - searchPlaceholder: 'Sök', - itemUnit: 'element', - itemsUnit: 'element', - }, - Empty: { - description: 'Ingen information', - }, -}; +export default locale; diff --git a/components/locale-provider/ta_IN.js b/components/locale-provider/ta_IN.js new file mode 100644 index 000000000..a1729531b --- /dev/null +++ b/components/locale-provider/ta_IN.js @@ -0,0 +1,62 @@ +import Pagination from '../vc-pagination/locale/ta_IN'; +import DatePicker from '../date-picker/locale/ta_IN'; +import TimePicker from '../time-picker/locale/ta_IN'; +import Calendar from '../calendar/locale/ta_IN'; + +export default { + locale: 'ta', + Pagination, + DatePicker, + TimePicker, + Calendar, + // locales for all comoponents + global: { + placeholder: 'தேதியைத் தேர்ந்தெடுக்கவும்', + }, + Table: { + filterTitle: 'பட்டியலை மூடு', + filterConfirm: 'சரி', + filterReset: 'மீட்டமை', + emptyText: 'தகவல் இல்லை', + selectAll: 'அனைத்தையும் தேர்வுசெய்', + selectInvert: 'தலைகீழாக மாற்று', + sortTitle: 'தலைப்பை வரிசைப்படுத்தவும்', + }, + Modal: { + okText: 'சரி', + cancelText: 'ரத்து செய்யவும்', + justOkText: 'பரவாயில்லை, சரி', + }, + Popconfirm: { + okText: 'சரி', + cancelText: 'ரத்து செய்யவும்', + }, + Transfer: { + titles: ['', ''], + notFoundContent: 'உள்ளடக்கம் கிடைக்கவில்லை', + searchPlaceholder: 'இங்கு தேடவும்', + itemUnit: 'தகவல்', + itemsUnit: 'தகவல்கள்', + }, + Upload: { + uploading: 'பதிவேற்றுகிறது...', + removeFile: 'கோப்பை அகற்று', + uploadError: 'பதிவேற்றுவதில் பிழை', + previewFile: 'கோப்பை முன்னோட்டமிடுங்கள்', + }, + Empty: { + description: 'தகவல் இல்லை', + }, + Icon: { + icon: 'உருவம்', + }, + Text: { + edit: 'திருத்து', + copy: 'நகல் எடு', + copied: 'நகல் எடுக்கப்பட்டது', + expand: 'விரிவாக்கவும்', + }, + PageHeader: { + back: 'பின் செல்லவும்', + }, +}; diff --git a/components/locale-provider/th_TH.js b/components/locale-provider/th_TH.js index 7c8f3f4ad..085c55668 100644 --- a/components/locale-provider/th_TH.js +++ b/components/locale-provider/th_TH.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/th_TH'; -import DatePicker from '../date-picker/locale/th_TH'; -import TimePicker from '../time-picker/locale/th_TH'; -import Calendar from '../calendar/locale/th_TH'; +import locale from '../locale/th_TH'; -export default { - locale: 'th', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'ตัวกรอง', - filterConfirm: 'ยืนยัน', - filterReset: 'รีเซ็ต', - selectAll: 'เลือกทั้งหมดในหน้านี้', - selectInvert: 'เลือกสถานะตรงกันข้าม', - }, - Modal: { - okText: 'ตกลง', - cancelText: 'ยกเลิก', - justOkText: 'ตกลง', - }, - Popconfirm: { - okText: 'ตกลง', - cancelText: 'ยกเลิก', - }, - Transfer: { - searchPlaceholder: 'ค้นหา', - itemUnit: 'ชิ้น', - itemsUnit: 'ชิ้น', - }, - Upload: { - uploading: 'กำลังอัปโหลด...', - removeFile: 'ลบไฟล์', - uploadError: 'เกิดข้อผิดพลาดในการอัปโหลด', - previewFile: 'ดูตัวอย่างไฟล์', - }, - Empty: { - description: 'ไม่มีข้อมูล', - }, -}; +export default locale; diff --git a/components/locale-provider/tr_TR.js b/components/locale-provider/tr_TR.js index befada65b..83005e59d 100644 --- a/components/locale-provider/tr_TR.js +++ b/components/locale-provider/tr_TR.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/tr_TR'; -import DatePicker from '../date-picker/locale/tr_TR'; -import TimePicker from '../time-picker/locale/tr_TR'; -import Calendar from '../calendar/locale/tr_TR'; +import locale from '../locale/tr_TR'; -export default { - locale: 'tr', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Menü Filtrele', - filterConfirm: 'Tamam', - filterReset: 'Sıfırla', - selectAll: 'Hepsini Seç', - selectInvert: 'Tersini Seç', - }, - Modal: { - okText: 'Tamam', - cancelText: 'İptal', - justOkText: 'Tamam', - }, - Popconfirm: { - okText: 'Tamam', - cancelText: 'İptal', - }, - Transfer: { - searchPlaceholder: 'Arama', - itemUnit: 'Öğe', - itemsUnit: 'Öğeler', - }, - Upload: { - uploading: 'Yükleniyor...', - removeFile: `Dosyayı kaldır`, - uploadError: 'Yükleme Hatası', - previewFile: `Dosyayı Önizle`, - }, - Empty: { - description: 'Veri Yok', - }, -}; +export default locale; diff --git a/components/locale-provider/uk_UA.js b/components/locale-provider/uk_UA.js index 67489c9f9..819c5b655 100644 --- a/components/locale-provider/uk_UA.js +++ b/components/locale-provider/uk_UA.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/uk_UA'; -import DatePicker from '../date-picker/locale/uk_UA'; -import TimePicker from '../time-picker/locale/uk_UA'; -import Calendar from '../calendar/locale/uk_UA'; +import locale from '../locale/uk_UA'; -export default { - locale: 'uk', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Фільтрувати', - filterConfirm: 'OK', - filterReset: 'Скинути', - selectAll: 'Обрати всі', - selectInvert: 'Інвертувати вибір', - }, - Modal: { - okText: 'Гаразд', - cancelText: 'Скасувати', - justOkText: 'Гаразд', - }, - Popconfirm: { - okText: 'Гаразд', - cancelText: 'Скасувати', - }, - Transfer: { - searchPlaceholder: 'Введіть текст для пошуку', - itemUnit: 'item', - itemsUnit: 'items', - }, - Upload: { - uploading: 'Завантаження ...', - removeFile: 'Видалити файл', - uploadError: 'Помилка завантаження', - previewFile: 'Попередній перегляд файлу', - }, - Empty: { - description: 'Даних немає', - }, -}; +export default locale; diff --git a/components/locale-provider/vi_VN.js b/components/locale-provider/vi_VN.js index 53b51a345..77ab9897e 100644 --- a/components/locale-provider/vi_VN.js +++ b/components/locale-provider/vi_VN.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/vi_VN'; -import DatePicker from '../date-picker/locale/vi_VN'; -import TimePicker from '../time-picker/locale/vi_VN'; -import Calendar from '../calendar/locale/vi_VN'; +import locale from '../locale/vi_VN'; -export default { - locale: 'vi', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: 'Bộ ', - filterConfirm: 'OK', - filterReset: 'Tạo Lại', - selectAll: 'Chọn Tất Cả', - selectInvert: 'Chọn Ngược Lại', - }, - Modal: { - okText: 'OK', - cancelText: 'Huỷ', - justOkText: 'OK', - }, - Popconfirm: { - okText: 'OK', - cancelText: 'Huỷ', - }, - Transfer: { - searchPlaceholder: 'Tìm ở đây', - itemUnit: 'mục', - itemsUnit: 'mục', - }, - Upload: { - uploading: 'Đang tải lên...', - removeFile: 'Gỡ bỏ tập tin', - uploadError: 'Lỗi tải lên', - previewFile: 'Xem thử tập tin', - }, - Empty: { - description: 'Trống', - }, -}; +export default locale; diff --git a/components/locale-provider/zh_CN.js b/components/locale-provider/zh_CN.js index e4e03c0d3..eda5720f9 100644 --- a/components/locale-provider/zh_CN.js +++ b/components/locale-provider/zh_CN.js @@ -1,50 +1,3 @@ -import Pagination from '../vc-pagination/locale/zh_CN'; -import DatePicker from '../date-picker/locale/zh_CN'; -import TimePicker from '../time-picker/locale/zh_CN'; -import Calendar from '../calendar/locale/zh_CN'; +import locale from '../locale/zh_CN'; -export default { - locale: 'zh-cn', - Pagination, - DatePicker, - TimePicker, - Calendar, - // locales for all comoponents - global: { - placeholder: '请选择', - }, - Table: { - filterTitle: '筛选', - filterConfirm: '确定', - filterReset: '重置', - selectAll: '全选当页', - selectInvert: '反选当页', - sortTitle: '排序', - }, - Modal: { - okText: '确定', - cancelText: '取消', - justOkText: '知道了', - }, - Popconfirm: { - cancelText: '取消', - okText: '确定', - }, - Transfer: { - searchPlaceholder: '请输入搜索内容', - itemUnit: '项', - itemsUnit: '项', - }, - Upload: { - uploading: '文件上传中', - removeFile: '删除文件', - uploadError: '上传错误', - previewFile: '预览文件', - }, - Empty: { - description: '暂无数据', - }, - Icon: { - icon: '图标', - }, -}; +export default locale; diff --git a/components/locale-provider/zh_TW.js b/components/locale-provider/zh_TW.js index 0aa553436..7e4917fa1 100644 --- a/components/locale-provider/zh_TW.js +++ b/components/locale-provider/zh_TW.js @@ -1,42 +1,3 @@ -import Pagination from '../vc-pagination/locale/zh_TW'; -import DatePicker from '../date-picker/locale/zh_TW'; -import TimePicker from '../time-picker/locale/zh_TW'; -import Calendar from '../calendar/locale/zh_TW'; +import locale from '../locale/zh_TW'; -export default { - locale: 'zh-tw', - Pagination, - DatePicker, - TimePicker, - Calendar, - Table: { - filterTitle: '篩選器', - filterConfirm: '確 定', - filterReset: '重 置', - selectAll: '全部選取', - selectInvert: '反向選取', - }, - Modal: { - okText: '確 定', - cancelText: '取 消', - justOkText: 'OK', - }, - Popconfirm: { - okText: '確 定', - cancelText: '取 消', - }, - Transfer: { - searchPlaceholder: '搜尋資料', - itemUnit: '項目', - itemsUnit: '項目', - }, - Upload: { - uploading: '正在上傳...', - removeFile: '刪除檔案', - uploadError: '上傳失敗', - previewFile: '檔案預覽', - }, - Empty: { - description: '無此資料', - }, -}; +export default locale; diff --git a/components/locale/ar_EG.js b/components/locale/ar_EG.js new file mode 100644 index 000000000..25be688a2 --- /dev/null +++ b/components/locale/ar_EG.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/ar_EG'; +import DatePicker from '../date-picker/locale/ar_EG'; +import TimePicker from '../time-picker/locale/ar_EG'; +import Calendar from '../calendar/locale/ar_EG'; + +export default { + locale: 'ar', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'الفلاتر', + filterConfirm: 'تأكيد', + filterReset: 'إعادة ضبط', + selectAll: 'اختيار الكل', + selectInvert: 'إلغاء الاختيار', + }, + Modal: { + okText: 'تأكيد', + cancelText: 'إلغاء', + justOkText: 'تأكيد', + }, + Popconfirm: { + okText: 'تأكيد', + cancelText: 'إلغاء', + }, + Transfer: { + searchPlaceholder: 'ابحث هنا', + itemUnit: 'عنصر', + itemsUnit: 'عناصر', + }, + Upload: { + uploading: 'جاري الرفع...', + removeFile: 'احذف الملف', + uploadError: 'مشكلة فى الرفع', + previewFile: 'استعرض الملف', + downloadFile: 'تحميل الملف', + }, + Empty: { + description: 'لا توجد بيانات', + }, +}; diff --git a/components/locale/bg_BG.js b/components/locale/bg_BG.js new file mode 100644 index 000000000..551dfb0fb --- /dev/null +++ b/components/locale/bg_BG.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/bg_BG'; +import DatePicker from '../date-picker/locale/bg_BG'; +import TimePicker from '../time-picker/locale/bg_BG'; +import Calendar from '../calendar/locale/bg_BG'; + +export default { + locale: 'bg', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Филтриране', + filterConfirm: 'Добре', + filterReset: 'Нулиране', + selectAll: 'Избор на текуща страница', + selectInvert: 'Обръщане', + }, + Modal: { + okText: 'Добре', + cancelText: 'Отказ', + justOkText: 'Добре', + }, + Popconfirm: { + okText: 'Добре', + cancelText: 'Отказ', + }, + Transfer: { + searchPlaceholder: 'Търсене', + itemUnit: 'избор', + itemsUnit: 'избори', + }, + Upload: { + uploading: 'Качване...', + removeFile: 'Премахване', + uploadError: 'Грешка при качването', + previewFile: 'Преглед', + downloadFile: 'Свали файл', + }, + Empty: { + description: 'Няма данни', + }, +}; diff --git a/components/locale/ca_ES.js b/components/locale/ca_ES.js new file mode 100644 index 000000000..1c960ae20 --- /dev/null +++ b/components/locale/ca_ES.js @@ -0,0 +1,41 @@ +import Pagination from '../vc-pagination/locale/ca_ES'; +import DatePicker from '../date-picker/locale/ca_ES'; +import TimePicker from '../time-picker/locale/ca_ES'; +import Calendar from '../calendar/locale/ca_ES'; + +export default { + locale: 'ca', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Filtrar Menu', + filterConfirm: 'OK', + filterReset: 'Restablir', + }, + Modal: { + okText: 'OK', + cancelText: 'Cancel·lar', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Cancel·lar', + }, + Transfer: { + searchPlaceholder: 'Cercar aquí', + itemUnit: 'item', + itemsUnit: 'items', + }, + Upload: { + uploading: 'Carregant...', + removeFile: 'Elimina el fitxer', + uploadError: 'Error de càrrega', + previewFile: 'Vista prèvia del fitxer', + downloadFile: "Descarrega l'arxiu", + }, + Empty: { + description: 'Sense dades', + }, +}; diff --git a/components/locale/cs_CZ.js b/components/locale/cs_CZ.js new file mode 100644 index 000000000..11440a259 --- /dev/null +++ b/components/locale/cs_CZ.js @@ -0,0 +1,41 @@ +import Pagination from '../vc-pagination/locale/cs_CZ'; +import DatePicker from '../date-picker/locale/cs_CZ'; +import TimePicker from '../time-picker/locale/cs_CZ'; +import Calendar from '../calendar/locale/cs_CZ'; + +export default { + locale: 'cs', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Filtr', + filterConfirm: 'Potvrdit', + filterReset: 'Obnovit', + }, + Modal: { + okText: 'Ok', + cancelText: 'Storno', + justOkText: 'Ok', + }, + Popconfirm: { + okText: 'Ok', + cancelText: 'Storno', + }, + Transfer: { + searchPlaceholder: 'Vyhledávání', + itemUnit: 'položka', + itemsUnit: 'položek', + }, + Upload: { + uploading: 'Nahrávání...', + removeFile: 'Odstranit soubor', + uploadError: 'Chyba při nahrávání', + previewFile: 'Zobrazit soubor', + downloadFile: 'Stáhnout soubor', + }, + Empty: { + description: 'Žádná data', + }, +}; diff --git a/components/locale/da_DK.js b/components/locale/da_DK.js new file mode 100644 index 000000000..2a764267a --- /dev/null +++ b/components/locale/da_DK.js @@ -0,0 +1,43 @@ +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', + selectAll: 'Vælg alle', + selectInvert: 'Inverter valg', + }, + Modal: { + okText: 'OK', + cancelText: 'Afbryd', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Afbryd', + }, + Transfer: { + searchPlaceholder: 'Søg her', + itemUnit: 'element', + itemsUnit: 'elementer', + }, + Upload: { + uploading: 'Uploader...', + removeFile: 'Fjern fil', + uploadError: 'Fejl ved upload', + previewFile: 'Forhåndsvisning', + downloadFile: 'Download fil', + }, + Empty: { + description: 'Ingen data', + }, +}; diff --git a/components/locale/de_DE.js b/components/locale/de_DE.js new file mode 100644 index 000000000..5f0611342 --- /dev/null +++ b/components/locale/de_DE.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/de_DE'; +import DatePicker from '../date-picker/locale/de_DE'; +import TimePicker from '../time-picker/locale/de_DE'; +import Calendar from '../calendar/locale/de_DE'; + +export default { + locale: 'de', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Filter-Menü', + filterConfirm: 'OK', + filterReset: 'Zurücksetzen', + selectAll: 'Selektiere Alle', + selectInvert: 'Selektion Invertieren', + }, + Modal: { + okText: 'OK', + cancelText: 'Abbrechen', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Abbrechen', + }, + Transfer: { + searchPlaceholder: 'Suchen', + itemUnit: 'Eintrag', + itemsUnit: 'Einträge', + }, + Upload: { + uploading: 'Hochladen...', + removeFile: 'Datei entfernen', + uploadError: 'Fehler beim Hochladen', + previewFile: 'Dateivorschau', + downloadFile: 'Download-Datei', + }, + Empty: { + description: 'Keine Daten', + }, +}; diff --git a/components/locale/default.js b/components/locale/default.js new file mode 100644 index 000000000..b7c5c1654 --- /dev/null +++ b/components/locale/default.js @@ -0,0 +1,62 @@ +import Pagination from '../vc-pagination/locale/en_US'; +import DatePicker from '../date-picker/locale/en_US'; +import TimePicker from '../time-picker/locale/en_US'; +import Calendar from '../calendar/locale/en_US'; + +export default { + locale: 'en', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Please select', + }, + Table: { + filterTitle: 'Filter menu', + filterConfirm: 'OK', + filterReset: 'Reset', + selectAll: 'Select current page', + selectInvert: 'Invert current page', + sortTitle: 'Sort', + expand: 'Expand row', + collapse: 'Collapse row', + }, + Modal: { + okText: 'OK', + cancelText: 'Cancel', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Cancel', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Search here', + itemUnit: 'item', + itemsUnit: 'items', + }, + Upload: { + uploading: 'Uploading...', + removeFile: 'Remove file', + uploadError: 'Upload error', + previewFile: 'Preview file', + downloadFile: 'Download file', + }, + Empty: { + description: 'No Data', + }, + Icon: { + icon: 'icon', + }, + Text: { + edit: 'Edit', + copy: 'Copy', + copied: 'Copied', + expand: 'Expand', + }, + PageHeader: { + back: 'Back', + }, +}; diff --git a/components/locale/el_GR.js b/components/locale/el_GR.js new file mode 100644 index 000000000..2b9d7b659 --- /dev/null +++ b/components/locale/el_GR.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/el_GR'; +import DatePicker from '../date-picker/locale/el_GR'; +import TimePicker from '../time-picker/locale/el_GR'; +import Calendar from '../calendar/locale/el_GR'; + +export default { + locale: 'el', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Μενού φίλτρων', + filterConfirm: 'ΟΚ', + filterReset: 'Επαναφορά', + selectAll: 'Επιλογή τρέχουσας σελίδας', + selectInvert: 'Αντιστροφή τρέχουσας σελίδας', + }, + Modal: { + okText: 'ΟΚ', + cancelText: 'Άκυρο', + justOkText: 'ΟΚ', + }, + Popconfirm: { + okText: 'ΟΚ', + cancelText: 'Άκυρο', + }, + Transfer: { + searchPlaceholder: 'Αναζήτηση', + itemUnit: 'αντικείμενο', + itemsUnit: 'αντικείμενα', + }, + Upload: { + uploading: 'Μεταφόρτωση...', + removeFile: 'Αφαίρεση αρχείου', + uploadError: 'Σφάλμα μεταφόρτωσης', + previewFile: 'Προεπισκόπηση αρχείου', + downloadFile: 'Λήψη αρχείου', + }, + Empty: { + description: 'Δεν υπάρχουν δεδομένα', + }, +}; diff --git a/components/locale/en_GB.js b/components/locale/en_GB.js new file mode 100644 index 000000000..828c819c6 --- /dev/null +++ b/components/locale/en_GB.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/en_GB'; +import DatePicker from '../date-picker/locale/en_GB'; +import TimePicker from '../time-picker/locale/en_GB'; +import Calendar from '../calendar/locale/en_GB'; + +export default { + locale: 'en-gb', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Filter menu', + filterConfirm: 'OK', + filterReset: 'Reset', + selectAll: 'Select current page', + selectInvert: 'Invert current page', + }, + Modal: { + okText: 'OK', + cancelText: 'Cancel', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Cancel', + }, + Transfer: { + searchPlaceholder: 'Search here', + itemUnit: 'item', + itemsUnit: 'items', + }, + Upload: { + uploading: 'Uploading...', + removeFile: 'Remove file', + uploadError: 'Upload error', + previewFile: 'Preview file', + downloadFile: 'Download file', + }, + Empty: { + description: 'No data', + }, +}; diff --git a/components/locale/en_US.js b/components/locale/en_US.js new file mode 100644 index 000000000..5d08924d7 --- /dev/null +++ b/components/locale/en_US.js @@ -0,0 +1,3 @@ +import defaultLocale from './default'; + +export default defaultLocale; diff --git a/components/locale/es_ES.js b/components/locale/es_ES.js new file mode 100644 index 000000000..1852ca810 --- /dev/null +++ b/components/locale/es_ES.js @@ -0,0 +1,59 @@ +import Pagination from '../vc-pagination/locale/es_ES'; +import DatePicker from '../date-picker/locale/es_ES'; +import TimePicker from '../time-picker/locale/es_ES'; +import Calendar from '../calendar/locale/es_ES'; + +export default { + locale: 'es', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Seleccione', + }, + Table: { + filterTitle: 'Filtrar menú', + filterConfirm: 'Aceptar', + filterReset: 'Reiniciar', + selectAll: 'Seleccionar todo', + selectInvert: 'Invertir selección', + sortTitle: 'Ordenar', + }, + Modal: { + okText: 'Aceptar', + cancelText: 'Cancelar', + justOkText: 'Aceptar', + }, + Popconfirm: { + okText: 'Aceptar', + cancelText: 'Cancelar', + }, + Transfer: { + searchPlaceholder: 'Buscar aquí', + itemUnit: 'elemento', + itemsUnit: 'elementos', + }, + Upload: { + uploading: 'Subiendo...', + removeFile: 'Eliminar archivo', + uploadError: 'Error al subir el archivo', + previewFile: 'Vista previa', + downloadFile: 'Descargar archivo', + }, + Empty: { + description: 'No hay datos', + }, + Icon: { + icon: 'ícono', + }, + Text: { + edit: 'editar', + copy: 'copiar', + copied: 'copiado', + expand: 'expandir', + }, + PageHeader: { + back: 'volver', + }, +}; diff --git a/components/locale/et_EE.js b/components/locale/et_EE.js new file mode 100644 index 000000000..1c1f91e58 --- /dev/null +++ b/components/locale/et_EE.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/et_EE'; +import DatePicker from '../date-picker/locale/et_EE'; +import TimePicker from '../time-picker/locale/et_EE'; +import Calendar from '../calendar/locale/et_EE'; + +export default { + locale: 'et', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Filtri menüü', + filterConfirm: 'OK', + filterReset: 'Nulli', + selectAll: 'Vali kõik', + selectInvert: 'Inverteeri valik', + }, + Modal: { + okText: 'OK', + cancelText: 'Tühista', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Tühista', + }, + Transfer: { + searchPlaceholder: 'Otsi siit', + itemUnit: 'kogus', + itemsUnit: 'kogus', + }, + Upload: { + uploading: 'Üleslaadimine...', + removeFile: 'Eemalda fail', + uploadError: 'Üleslaadimise tõrge', + previewFile: 'Faili eelvaade', + downloadFile: 'Laadige fail alla', + }, + Empty: { + description: 'Andmed puuduvad', + }, +}; diff --git a/components/locale/fa_IR.js b/components/locale/fa_IR.js new file mode 100644 index 000000000..6390fb37a --- /dev/null +++ b/components/locale/fa_IR.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/fa_IR'; +import DatePicker from '../date-picker/locale/fa_IR'; +import TimePicker from '../time-picker/locale/fa_IR'; +import Calendar from '../calendar/locale/fa_IR'; + +export default { + locale: 'fa', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'منوی فیلتر', + filterConfirm: 'تایید', + filterReset: 'پاک کردن', + selectAll: 'انتخاب صفحه‌ی کنونی', + selectInvert: 'معکوس کردن انتخاب‌ها در صفحه ی کنونی', + }, + Modal: { + okText: 'تایید', + cancelText: 'لغو', + justOkText: 'تایید', + }, + Popconfirm: { + okText: 'تایید', + cancelText: 'لغو', + }, + Transfer: { + searchPlaceholder: 'جستجو', + itemUnit: '', + itemsUnit: '', + }, + Upload: { + uploading: 'در حال آپلود...', + removeFile: 'حذف فایل', + uploadError: 'خطا در آپلود', + previewFile: 'مشاهده‌ی فایل', + downloadFile: 'دریافت فایل', + }, + Empty: { + description: 'داده‌ای موجود نیست', + }, +}; diff --git a/components/locale/fi_FI.js b/components/locale/fi_FI.js new file mode 100644 index 000000000..8612f184e --- /dev/null +++ b/components/locale/fi_FI.js @@ -0,0 +1,44 @@ +import Pagination from '../vc-pagination/locale/fi_FI'; +import DatePicker from '../date-picker/locale/fi_FI'; +import TimePicker from '../time-picker/locale/fi_FI'; +import Calendar from '../calendar/locale/fi_FI'; + +export default { + locale: 'fi', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Suodatus valikko', + filterConfirm: 'OK', + filterReset: 'Tyhjennä', + selectAll: 'Valitse kaikki', + selectInvert: 'Valitse päinvastoin', + sortTitle: 'Lajittele', + }, + Modal: { + okText: 'OK', + cancelText: 'Peruuta', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Peruuta', + }, + Transfer: { + searchPlaceholder: 'Etsi täältä', + itemUnit: 'kohde', + itemsUnit: 'kohdetta', + }, + Upload: { + uploading: 'Lähetetään...', + removeFile: 'Poista tiedosto', + uploadError: 'Virhe lähetyksessä', + previewFile: 'Esikatsele tiedostoa', + downloadFile: 'Lataa tiedosto', + }, + Empty: { + description: 'Ei kohteita', + }, +}; diff --git a/components/locale/fr_BE.js b/components/locale/fr_BE.js new file mode 100644 index 000000000..0317e25d0 --- /dev/null +++ b/components/locale/fr_BE.js @@ -0,0 +1,47 @@ +import Pagination from '../vc-pagination/locale/fr_BE'; +import DatePicker from '../date-picker/locale/fr_BE'; +import TimePicker from '../time-picker/locale/fr_BE'; +import Calendar from '../calendar/locale/fr_BE'; + +export default { + locale: 'fr', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Filtrer', + filterConfirm: 'OK', + filterReset: 'Réinitialiser', + }, + Modal: { + okText: 'OK', + cancelText: 'Annuler', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Annuler', + }, + Transfer: { + searchPlaceholder: 'Recherche', + itemUnit: 'élément', + itemsUnit: 'éléments', + }, + Upload: { + uploading: 'Téléchargement...', + removeFile: 'Effacer le fichier', + uploadError: 'Erreur de téléchargement', + previewFile: 'Fichier de prévisualisation', + downloadFile: 'Télécharger un fichier', + }, + Empty: { + description: 'Aucune donnée', + }, + Text: { + edit: 'éditer', + copy: 'copier', + copied: 'copie effectuée', + expand: 'développer', + }, +}; diff --git a/components/locale/fr_FR.js b/components/locale/fr_FR.js new file mode 100644 index 000000000..169264562 --- /dev/null +++ b/components/locale/fr_FR.js @@ -0,0 +1,47 @@ +import Pagination from '../vc-pagination/locale/fr_FR'; +import DatePicker from '../date-picker/locale/fr_FR'; +import TimePicker from '../time-picker/locale/fr_FR'; +import Calendar from '../calendar/locale/fr_FR'; + +export default { + locale: 'fr', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Filtrer', + filterConfirm: 'OK', + filterReset: 'Réinitialiser', + }, + Modal: { + okText: 'OK', + cancelText: 'Annuler', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Annuler', + }, + Transfer: { + searchPlaceholder: 'Recherche', + itemUnit: 'élément', + itemsUnit: 'éléments', + }, + Empty: { + description: 'Aucune donnée', + }, + Upload: { + uploading: 'Téléchargement...', + removeFile: 'Effacer le fichier', + uploadError: 'Erreur de téléchargement', + previewFile: 'Fichier de prévisualisation', + downloadFile: 'Télécharger un fichier', + }, + Text: { + edit: 'éditer', + copy: 'copier', + copied: 'copie effectuée', + expand: 'développer', + }, +}; diff --git a/components/locale/he_IL.js b/components/locale/he_IL.js new file mode 100644 index 000000000..6df4736a8 --- /dev/null +++ b/components/locale/he_IL.js @@ -0,0 +1,43 @@ +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: 'איפוס', + selectAll: 'בחר הכל', + selectInvert: 'הפוך בחירה', + }, + Modal: { + okText: 'אישור', + cancelText: 'ביטול', + justOkText: 'אישור', + }, + Popconfirm: { + okText: 'אישור', + cancelText: 'ביטול', + }, + Transfer: { + searchPlaceholder: 'חפש כאן', + itemUnit: 'פריט', + itemsUnit: 'פריטים', + }, + Upload: { + uploading: 'מעלה...', + removeFile: 'הסר קובץ', + uploadError: 'שגיאת העלאה', + previewFile: 'הצג קובץ', + downloadFile: 'הורד קובץ', + }, + Empty: { + description: 'אין מידע', + }, +}; diff --git a/components/locale/hi_IN.js b/components/locale/hi_IN.js new file mode 100644 index 000000000..e8b7510bf --- /dev/null +++ b/components/locale/hi_IN.js @@ -0,0 +1,51 @@ +import Pagination from '../vc-pagination/locale/hi_IN'; +import DatePicker from '../date-picker/locale/hi_IN'; +import TimePicker from '../time-picker/locale/hi_IN'; +import Calendar from '../calendar/locale/hi_IN'; + +export default { + locale: 'hi', + Pagination, + DatePicker, + TimePicker, + Calendar, + // locales for all comoponents + global: { + placeholder: 'कृपया चुनें', + }, + Table: { + filterTitle: 'सूची बंद करें', + filterConfirm: 'अच्छी तरह से', + filterReset: 'रीसेट', + emptyText: 'कोई जानकारी नहीं', + selectAll: 'वर्तमान पृष्ठ का चयन करें', + selectInvert: 'वर्तमान पृष्ठ घुमाएं', + sortTitle: 'द्वारा क्रमबद्ध करें', + }, + Modal: { + okText: 'अच्छी तरह से', + cancelText: 'रद्द करना', + justOkText: 'अच्छी तरह से', + }, + Popconfirm: { + okText: 'अच्छी तरह से', + cancelText: 'रद्द करना', + }, + Transfer: { + titles: ['', ''], + notFoundContent: 'नहीं मिला', + searchPlaceholder: 'यहां खोजें', + itemUnit: 'तत्त्व', + itemsUnit: 'विषय-वस्तु', + }, + Select: { + notFoundContent: 'नहीं मिला', + }, + Upload: { + uploading: 'अपलोडिंग...', + removeFile: 'फ़ाइल निकालें', + uploadError: 'अपलोड में त्रुटि', + previewFile: 'फ़ाइल पूर्वावलोकन', + downloadFile: 'फ़ाइल डाउनलोड करें', + }, +}; diff --git a/components/locale/hr_HR.js b/components/locale/hr_HR.js new file mode 100644 index 000000000..8403cd456 --- /dev/null +++ b/components/locale/hr_HR.js @@ -0,0 +1,57 @@ +import Pagination from '../vc-pagination/locale/hr_HR'; +import DatePicker from '../date-picker/locale/hr_HR'; +import TimePicker from '../time-picker/locale/hr_HR'; +import Calendar from '../calendar/locale/hr_HR'; + +export default { + locale: 'hr', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Molimo označite', + }, + Table: { + filterTitle: 'Filter meni', + filterConfirm: 'OK', + filterReset: 'Reset', + selectAll: 'Označi trenutnu stranicu', + selectInvert: 'Invertiraj trenutnu stranicu', + sortTitle: 'Sortiraj', + }, + Modal: { + okText: 'OK', + cancelText: 'Odustani', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Odustani', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Pretraži ovdje', + itemUnit: 'stavka', + itemsUnit: 'stavke', + }, + Upload: { + uploading: 'Upload u tijeku...', + removeFile: 'Makni datoteku', + uploadError: 'Greška kod uploada', + previewFile: 'Pogledaj datoteku', + downloadFile: 'Preuzmi datoteku', + }, + Empty: { + description: 'Nema podataka', + }, + Icon: { + icon: 'ikona', + }, + Text: { + edit: 'uredi', + copy: 'kopiraj', + copied: 'kopiranje uspješno', + expand: 'proširi', + }, +}; diff --git a/components/locale/hu_HU.js b/components/locale/hu_HU.js new file mode 100644 index 000000000..8e90608a4 --- /dev/null +++ b/components/locale/hu_HU.js @@ -0,0 +1,44 @@ +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', + 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: { + searchPlaceholder: 'Keresés', + itemUnit: 'elem', + itemsUnit: 'elemek', + }, + Upload: { + uploading: 'Feltöltés...', + removeFile: 'Fájl eltávolítása', + uploadError: 'Feltöltési hiba', + previewFile: 'Fájl előnézet', + downloadFile: 'Fájl letöltése', + }, + Empty: { + description: 'Nincs adat', + }, +}; diff --git a/components/locale/hy_AM.js b/components/locale/hy_AM.js new file mode 100644 index 000000000..ee698cdda --- /dev/null +++ b/components/locale/hy_AM.js @@ -0,0 +1,109 @@ +const datePickerLocale = { + lang: { + placeholder: 'Ընտրեք ամսաթիվը', + rangePlaceholder: ['Մեկնարկի ամսաթիվ', 'Ավարտի ամսաթիվը'], + today: 'Այսօր', + now: 'Հիմա', + backToToday: 'Վերադառնալ այսօր', + ok: 'Օկ', + clear: 'Մաքրել', + month: 'Ամիս', + year: 'Տարի', + timeSelect: 'ընտրեք ժամը', + dateSelect: 'ընտրեք ամսաթիվը', + weekSelect: 'Ընտրեք շաբաթը', + monthSelect: 'Ընտրեք ամիսը', + yearSelect: 'Ընտրեք տարին', + decadeSelect: 'Ընտրեք տասնամյակը', + yearFormat: 'YYYY', + dateFormat: 'DD/MM//YYYY', + dayFormat: 'DD', + dateTimeFormat: 'DD/MM//YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'Անցած ամիս (PageUp)', + nextMonth: 'Մյուս ամիս (PageDown)', + previousYear: 'Անցած տարի (Control + left)', + nextYear: 'Մյուս տարի (Control + right)', + previousDecade: 'Անցած տասնամյակ', + nextDecade: 'Մյուս տասնամյակ', + previousCentury: 'Անցած դար', + nextCentury: 'Մյուս դար', + }, + timePickerLocale: { + placeholder: 'Ընտրեք ժամը', + }, +}; + +export default { + locale: 'hy', + Pagination: { + // Options.jsx + items_per_page: '/ էջ', + jump_to: 'Գնալ', + jump_to_confirm: 'հաստատել', + page: '', + + // Pagination.jsx + prev_page: 'Նախորդ Էջ', + next_page: 'Հաջորդ Էջ', + prev_5: 'Նախորդ 5 Էջերը', + next_5: 'Հաջորդ 5 Էջերը', + prev_3: 'Նախորդ 3 Էջերը', + next_3: 'Հաջորդ 3 Էջերը', + }, + DatePicker: datePickerLocale, + TimePicker: { + placeholder: 'Ընտրեք ժամը', + }, + Calendar: datePickerLocale, + global: { + placeholder: 'Ընտրեք', + }, + Table: { + filterTitle: 'ֆիլտրի ընտրացանկ', + filterConfirm: 'ֆիլտրել', + filterReset: 'Զրոյացնել', + selectAll: 'Ընտրեք ընթացիկ էջը', + selectInvert: 'Փոխարկել ընթացիկ էջը', + sortTitle: 'Տեսակավորել', + expand: 'Ընդլայնեք տողը', + collapse: 'Կրճատել տողը', + }, + Modal: { + okText: 'Օկ', + cancelText: 'Չեղարկել', + justOkText: 'Օկ', + }, + Popconfirm: { + okText: 'Հաստատել', + cancelText: 'Մերժել', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Որոնեք այստեղ', + itemUnit: 'պարագան', + itemsUnit: 'պարագաները', + }, + Upload: { + uploading: 'Ներբեռնում...', + removeFile: 'Հեռացնել ֆայլը', + uploadError: 'Ներբեռնման սխալ', + previewFile: 'Դիտել ֆայլը', + downloadFile: 'Ներբեռնել ֆայլը', + }, + Empty: { + description: 'Տվյալներ չկան', + }, + Icon: { + icon: 'պատկեր', + }, + Text: { + edit: 'Խմբագրել', + copy: 'Պատճենել', + copied: 'Պատճենվել է', + expand: 'Տեսնել ավելին', + }, + PageHeader: { + back: 'Հետ', + }, +}; diff --git a/components/locale/id_ID.js b/components/locale/id_ID.js new file mode 100644 index 000000000..cc89bd93e --- /dev/null +++ b/components/locale/id_ID.js @@ -0,0 +1,45 @@ +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: 'Saring', + filterConfirm: 'OK', + filterReset: 'Hapus', + selectAll: 'Pilih semua di halaman ini', + selectInvert: 'Balikkan pilihan di halaman ini', + sortTitle: 'Urutkan', + }, + Modal: { + okText: 'OK', + cancelText: 'Batal', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Batal', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Cari', + itemUnit: 'item', + itemsUnit: 'item', + }, + Upload: { + uploading: 'Mengunggah...', + removeFile: 'Hapus file', + uploadError: 'Kesalahan pengunggahan', + previewFile: 'File pratinjau', + downloadFile: 'Unduh berkas', + }, + Empty: { + description: 'Tidak ada data', + }, +}; diff --git a/components/locale/is_IS.js b/components/locale/is_IS.js new file mode 100644 index 000000000..745e1ee91 --- /dev/null +++ b/components/locale/is_IS.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/is_IS'; +import DatePicker from '../date-picker/locale/is_IS'; +import TimePicker from '../time-picker/locale/is_IS'; +import Calendar from '../calendar/locale/is_IS'; + +export default { + locale: 'is', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Afmarkanir', + filterConfirm: 'Staðfesta', + filterReset: 'Núllstilla', + selectAll: 'Velja allt', + selectInvert: 'Viðsnúa vali', + }, + Modal: { + okText: 'Áfram', + cancelText: 'Hætta við', + justOkText: 'Í lagi', + }, + Popconfirm: { + okText: 'Áfram', + cancelText: 'Hætta við', + }, + Transfer: { + searchPlaceholder: 'Leita hér', + itemUnit: 'færsla', + itemsUnit: 'færslur', + }, + Upload: { + uploading: 'Hleð upp...', + removeFile: 'Fjarlægja skrá', + uploadError: 'Villa við að hlaða upp', + previewFile: 'Forskoða skrá', + downloadFile: 'Hlaða niður skrá', + }, + Empty: { + description: 'Engin gögn', + }, +}; diff --git a/components/locale/it_IT.js b/components/locale/it_IT.js new file mode 100644 index 000000000..0843b9ff3 --- /dev/null +++ b/components/locale/it_IT.js @@ -0,0 +1,56 @@ +import Pagination from '../vc-pagination/locale/it_IT'; +import DatePicker from '../date-picker/locale/it_IT'; +import TimePicker from '../time-picker/locale/it_IT'; +import Calendar from '../calendar/locale/it_IT'; + +export default { + locale: 'it', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Selezionare', + }, + Table: { + filterTitle: 'Menù Filtro', + filterConfirm: 'OK', + filterReset: 'Reset', + selectAll: 'Seleziona pagina corrente', + selectInvert: 'Inverti selezione nella pagina corrente', + sortTitle: 'Ordina', + }, + Modal: { + okText: 'OK', + cancelText: 'Annulla', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Annulla', + }, + Transfer: { + searchPlaceholder: 'Cerca qui', + itemUnit: 'elemento', + itemsUnit: 'elementi', + }, + Upload: { + uploading: 'Caricamento...', + removeFile: 'Rimuovi il file', + uploadError: 'Errore di caricamento', + previewFile: 'Anteprima file', + downloadFile: 'Download file', + }, + Empty: { + description: 'Nessun dato', + }, + Icon: { + icon: 'icona', + }, + Text: { + edit: 'modifica', + copy: 'copia', + copied: 'copia effettuata', + expand: 'espandi', + }, +}; diff --git a/components/locale/ja_JP.js b/components/locale/ja_JP.js new file mode 100644 index 000000000..49f64d647 --- /dev/null +++ b/components/locale/ja_JP.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/ja_JP'; +import DatePicker from '../date-picker/locale/ja_JP'; +import TimePicker from '../time-picker/locale/ja_JP'; +import Calendar from '../calendar/locale/ja_JP'; + +export default { + locale: 'ja', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'メニューをフィルター', + filterConfirm: 'OK', + filterReset: 'リセット', + selectAll: 'すべてを選択', + selectInvert: '選択を反転', + }, + Modal: { + okText: 'OK', + cancelText: 'キャンセル', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'キャンセル', + }, + Transfer: { + searchPlaceholder: 'ここを検索', + itemUnit: 'アイテム', + itemsUnit: 'アイテム', + }, + Upload: { + uploading: 'アップロード中...', + removeFile: 'ファイルを削除', + uploadError: 'アップロードエラー', + previewFile: 'ファイルをプレビュー', + downloadFile: 'ダウンロードファイル', + }, + Empty: { + description: 'データがありません', + }, +}; diff --git a/components/locale/kn_IN.js b/components/locale/kn_IN.js new file mode 100644 index 000000000..26308eb41 --- /dev/null +++ b/components/locale/kn_IN.js @@ -0,0 +1,51 @@ +import Pagination from '../vc-pagination/locale/kn_IN'; +import DatePicker from '../date-picker/locale/kn_IN'; +import TimePicker from '../time-picker/locale/kn_IN'; +import Calendar from '../calendar/locale/kn_IN'; + +export default { + locale: 'kn', + Pagination, + DatePicker, + TimePicker, + Calendar, + // locales for all comoponents + global: { + placeholder: 'ದಯವಿಟ್ಟು ಆರಿಸಿ', + }, + Table: { + filterTitle: 'ಪಟ್ಟಿ ಸೋಸಿ', + filterConfirm: 'ಸರಿ', + filterReset: 'ಮರುಹೊಂದಿಸಿ', + emptyText: 'ಮಾಹಿತಿ ಇಲ್ಲ', + selectAll: 'ಪ್ರಸ್ತುತ ಪುಟವನ್ನು ಆಯ್ಕೆಮಾಡಿ', + selectInvert: 'ಪ್ರಸ್ತುತ ಪುಟವನ್ನು ತಿರುಗಿಸಿ', + sortTitle: 'ವಿಂಗಡಿಸಿ', + }, + Modal: { + okText: 'ಸರಿ', + cancelText: 'ರದ್ದು', + justOkText: 'ಸರಿ', + }, + Popconfirm: { + okText: 'ಸರಿ', + cancelText: 'ರದ್ದು', + }, + Transfer: { + titles: ['', ''], + notFoundContent: 'ದೊರೆತಿಲ್ಲ', + searchPlaceholder: 'ಇಲ್ಲಿ ಹುಡುಕಿ', + itemUnit: 'ವಿಷಯ', + itemsUnit: 'ವಿಷಯಗಳು', + }, + Select: { + notFoundContent: 'ದೊರೆತಿಲ್ಲ', + }, + Upload: { + uploading: 'ಏರಿಸಿ...', + removeFile: 'ಫೈಲ್ ತೆಗೆದುಹಾಕಿ', + uploadError: 'ಏರಿಸುವ ದೋಷ', + previewFile: 'ಫೈಲ್ ಮುನ್ನೋಟ', + downloadFile: 'ಫೈಲ್ ಡೌನ್‌ಲೋಡ್ ಮಾಡಿ', + }, +}; diff --git a/components/locale/ko_KR.js b/components/locale/ko_KR.js new file mode 100644 index 000000000..f0de0736c --- /dev/null +++ b/components/locale/ko_KR.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/ko_KR'; +import DatePicker from '../date-picker/locale/ko_KR'; +import TimePicker from '../time-picker/locale/ko_KR'; +import Calendar from '../calendar/locale/ko_KR'; + +export default { + locale: 'ko', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: '필터 메뉴', + filterConfirm: '확인', + filterReset: '초기화', + selectAll: '모두 선택', + selectInvert: '선택 반전', + }, + Modal: { + okText: '확인', + cancelText: '취소', + justOkText: '확인', + }, + Popconfirm: { + okText: '확인', + cancelText: '취소', + }, + Transfer: { + searchPlaceholder: '여기에 검색하세요', + itemUnit: '개', + itemsUnit: '개', + }, + Upload: { + uploading: '업로드 중...', + removeFile: '파일 삭제', + uploadError: '업로드 실패', + previewFile: '파일 미리보기', + downloadFile: '파일 다운로드', + }, + Empty: { + description: '데이터 없음', + }, +}; diff --git a/components/locale/ku_IQ.js b/components/locale/ku_IQ.js new file mode 100755 index 000000000..72fbef498 --- /dev/null +++ b/components/locale/ku_IQ.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/ku_IQ'; +import DatePicker from '../date-picker/locale/ku_IQ'; +import TimePicker from '../time-picker/locale/ku_IQ'; +import Calendar from '../calendar/locale/ku_IQ'; + +export default { + locale: 'ku-iq', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Menuê peldanka', + filterConfirm: 'Temam', + filterReset: 'Jê bibe', + selectAll: 'Hemî hilbijêre', + selectInvert: 'Hilbijartinan veguhere', + }, + Modal: { + okText: 'Temam', + cancelText: 'Betal ke', + justOkText: 'Temam', + }, + Popconfirm: { + okText: 'Temam', + cancelText: 'Betal ke', + }, + Transfer: { + searchPlaceholder: 'Lêgerîn', + itemUnit: 'tişt', + itemsUnit: 'tişt', + }, + Upload: { + uploading: 'Bardike...', + removeFile: 'Pelê rabike', + uploadError: 'Xeta barkirine', + previewFile: 'Pelê pêşbibîne', + downloadFile: 'Pelê dakêşin', + }, + Empty: { + description: 'Agahî tune', + }, +}; diff --git a/components/locale/lv_LV.js b/components/locale/lv_LV.js new file mode 100644 index 000000000..20e1fa5cd --- /dev/null +++ b/components/locale/lv_LV.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/lv_LV'; +import DatePicker from '../date-picker/locale/lv_LV'; +import TimePicker from '../time-picker/locale/lv_LV'; +import Calendar from '../calendar/locale/lv_LV'; + +export default { + locale: 'lv', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Filtrēšanas izvēlne', + filterConfirm: 'OK', + filterReset: 'Atiestatīt', + selectAll: 'Atlasiet pašreizējo lapu', + selectInvert: 'Pārvērst pašreizējo lapu', + }, + Modal: { + okText: 'OK', + cancelText: 'Atcelt', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Atcelt', + }, + Transfer: { + searchPlaceholder: 'Meklēt šeit', + itemUnit: 'vienumu', + itemsUnit: 'vienumus', + }, + Upload: { + uploading: 'Augšupielāde...', + removeFile: 'Noņemt failu', + uploadError: 'Augšupielādes kļūda', + previewFile: 'Priekšskatiet failu', + downloadFile: 'Lejupielādēt failu', + }, + Empty: { + description: 'Nav datu', + }, +}; diff --git a/components/locale/mk_MK.js b/components/locale/mk_MK.js new file mode 100644 index 000000000..b42cfd79a --- /dev/null +++ b/components/locale/mk_MK.js @@ -0,0 +1,58 @@ +import Pagination from '../vc-pagination/locale/mk_MK'; +import DatePicker from '../date-picker/locale/mk_MK'; +import TimePicker from '../time-picker/locale/mk_MK'; +import Calendar from '../calendar/locale/mk_MK'; + +export default { + locale: 'mk', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Ве молиме означете', + }, + Table: { + filterTitle: 'Мени за филтрирање', + filterConfirm: 'ОК', + filterReset: 'Избриши', + selectAll: 'Одбери страница', + selectInvert: 'Инвертирај страница', + }, + Modal: { + okText: 'ОК', + cancelText: 'Откажи', + justOkText: 'ОК', + }, + Popconfirm: { + okText: 'ОК', + cancelText: 'Откажи', + }, + Transfer: { + searchPlaceholder: 'Пребарај тука', + itemUnit: 'предмет', + itemsUnit: 'предмети', + }, + Upload: { + uploading: 'Се прикачува...', + removeFile: 'Избриши фајл', + uploadError: 'Грешка при прикачување', + previewFile: 'Прикажи фајл', + downloadFile: 'Преземи фајл', + }, + Empty: { + description: 'Нема податоци', + }, + Icon: { + icon: 'Икона', + }, + Text: { + edit: 'Уреди', + copy: 'Копирај', + copied: 'Копирано', + expand: 'Зголеми', + }, + PageHeader: { + back: 'Назад', + }, +}; diff --git a/components/locale/mn_MN.js b/components/locale/mn_MN.js new file mode 100644 index 000000000..2f3a31b26 --- /dev/null +++ b/components/locale/mn_MN.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/mn_MN'; +import DatePicker from '../date-picker/locale/mn_MN'; +import TimePicker from '../time-picker/locale/mn_MN'; +import Calendar from '../calendar/locale/mn_MN'; + +export default { + locale: 'mn-mn', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Хайх цэс', + filterConfirm: 'OK', + filterReset: 'Цэвэрлэх', + selectAll: 'Бүгдийг сонгох', + selectInvert: 'Бусдыг сонгох', + }, + Modal: { + okText: 'OK', + cancelText: 'Цуцлах', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Цуцлах', + }, + Transfer: { + searchPlaceholder: 'Хайх', + itemUnit: 'Зүйл', + itemsUnit: 'Зүйлүүд', + }, + Upload: { + uploading: 'Хуулж байна...', + removeFile: 'Файл устгах', + uploadError: 'Хуулахад алдаа гарлаа', + previewFile: 'Файлыг түргэн үзэх', + downloadFile: 'Файлыг татах', + }, + Empty: { + description: 'Мэдээлэл байхгүй байна', + }, +}; diff --git a/components/locale/ms_MY.js b/components/locale/ms_MY.js new file mode 100644 index 000000000..9a42b1e83 --- /dev/null +++ b/components/locale/ms_MY.js @@ -0,0 +1,63 @@ +import Pagination from '../vc-pagination/locale/ms_MY'; +import DatePicker from '../date-picker/locale/ms_MY'; +import TimePicker from '../time-picker/locale/ms_MY'; +import Calendar from '../calendar/locale/ms_MY'; + +export default { + locale: 'ms-my', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Sila pilih', + }, + PageHeader: { + back: 'Kembali', + }, + Text: { + edit: 'Sunting', + copy: 'Salin', + copied: 'Berjaya menyalin', + expand: 'Kembang', + }, + Empty: { + description: 'Tiada data', + }, + Table: { + filterTitle: 'Cari dengan tajuk', + filterConfirm: 'Ok', + filterReset: 'Menetapkan semula', + emptyText: 'Tiada data', + selectAll: 'Pilih semua', + selectInvert: 'Terbalikkan', + }, + Modal: { + okText: 'OK', + cancelText: 'Batal', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Batal', + }, + Transfer: { + notFoundContent: 'Tidak dijumpai', + searchPlaceholder: 'Carian di sini', + itemUnit: 'item', + itemsUnit: 'item', + }, + Icon: { + icon: 'ikon', + }, + Select: { + notFoundContent: 'Tidak Dijumpai', + }, + Upload: { + uploading: 'Sedang memuat naik...', + removeFile: 'Buang fail', + uploadError: 'Masalah muat naik', + previewFile: 'Tengok fail', + downloadFile: 'Muat turun fail', + }, +}; diff --git a/components/locale/nb_NO.js b/components/locale/nb_NO.js new file mode 100644 index 000000000..83d246625 --- /dev/null +++ b/components/locale/nb_NO.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/nb_NO'; +import DatePicker from '../date-picker/locale/nb_NO'; +import TimePicker from '../time-picker/locale/nb_NO'; +import Calendar from '../calendar/locale/nb_NO'; + +export default { + locale: 'nb', + DatePicker, + TimePicker, + Calendar, + Pagination, + Table: { + filterTitle: 'Filtermeny', + filterConfirm: 'OK', + filterReset: 'Nullstill', + selectAll: 'Velg alle', + selectInvert: 'Inverter valg', + }, + Modal: { + okText: 'OK', + cancelText: 'Avbryt', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Avbryt', + }, + Transfer: { + searchPlaceholder: 'Søk her', + itemUnit: 'element', + itemsUnit: 'elementer', + }, + Upload: { + uploading: 'Laster opp...', + removeFile: 'Fjern fil', + uploadError: 'Feil ved opplastning', + previewFile: 'Forhåndsvisning', + downloadFile: 'Last ned fil', + }, + Empty: { + description: 'Ingen data', + }, +}; diff --git a/components/locale/ne_NP.js b/components/locale/ne_NP.js new file mode 100644 index 000000000..bedd096e6 --- /dev/null +++ b/components/locale/ne_NP.js @@ -0,0 +1,44 @@ +import Pagination from '../vc-pagination/locale/en_US'; +import DatePicker from '../date-picker/locale/en_US'; +import TimePicker from '../time-picker/locale/en_US'; +import Calendar from '../calendar/locale/en_US'; + +export default { + locale: 'ne-np', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'फिल्टर मेनु', + filterConfirm: 'हो', + filterReset: 'रीसेट', + selectAll: 'सबै छान्नुुहोस्', + selectInvert: 'छनौट उल्टाउनुहोस', + }, + Modal: { + okText: 'हो', + cancelText: 'होईन', + justOkText: 'हो', + }, + Popconfirm: { + okText: 'हो', + cancelText: 'होईन', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'यहाँ खोज्नुहोस्', + itemUnit: 'वस्तु', + itemsUnit: 'वस्तुहरू', + }, + Upload: { + uploading: 'अपलोड गर्दै...', + removeFile: 'फाइल हटाउनुहोस्', + uploadError: 'अप्लोडमा समस्या भयो', + previewFile: 'फाइल पूर्वावलोकन गर्नुहोस्', + downloadFile: 'डाउनलोड फाइल', + }, + Empty: { + description: 'डाटा छैन', + }, +}; diff --git a/components/locale/nl_BE.js b/components/locale/nl_BE.js new file mode 100644 index 000000000..cc2d5c825 --- /dev/null +++ b/components/locale/nl_BE.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/nl_BE'; +import DatePicker from '../date-picker/locale/nl_BE'; +import TimePicker from '../time-picker/locale/nl_BE'; +import Calendar from '../calendar/locale/nl_BE'; + +export default { + locale: 'nl-be', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'FilterMenu', + filterConfirm: 'OK', + filterReset: 'Reset', + selectAll: 'Selecteer huidige pagina', + selectInvert: 'Selecteer huidige pagina', + }, + Modal: { + okText: 'OK', + cancelText: 'Annuleer', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Annuleer', + }, + Transfer: { + searchPlaceholder: 'Zoek hier', + itemUnit: 'item', + itemsUnit: 'items', + }, + Upload: { + uploading: 'Uploaden...', + removeFile: 'Bestand verwijderen', + uploadError: 'Upload fout', + previewFile: 'Preview bestand', + downloadFile: 'Download bestand', + }, + Empty: { + description: 'Geen gegevens', + }, +}; diff --git a/components/locale/nl_NL.js b/components/locale/nl_NL.js new file mode 100644 index 000000000..773d5068a --- /dev/null +++ b/components/locale/nl_NL.js @@ -0,0 +1,62 @@ +import Pagination from '../vc-pagination/locale/nl_NL'; +import DatePicker from '../date-picker/locale/nl_NL'; +import TimePicker from '../time-picker/locale/nl_NL'; +import Calendar from '../calendar/locale/nl_NL'; + +export default { + locale: 'nl', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Maak een selectie', + }, + Table: { + filterTitle: 'Filteren', + filterConfirm: 'OK', + filterReset: 'Reset', + selectAll: 'Selecteer huidige pagina', + selectInvert: 'Deselecteer huidige pagina', + sortTitle: 'Sorteren', + expand: 'Rij uitklappen', + collapse: 'Rij inklappen', + }, + Modal: { + okText: 'OK', + cancelText: 'Annuleren', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Annuleren', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Zoeken', + itemUnit: 'item', + itemsUnit: 'items', + }, + Upload: { + uploading: 'Uploaden...', + removeFile: 'Verwijder bestand', + uploadError: 'Fout tijdens uploaden', + previewFile: 'Bekijk bestand', + downloadFile: 'Downloaden bestand', + }, + Empty: { + description: 'Geen gegevens', + }, + Icon: { + icon: 'icoon', + }, + Text: { + edit: 'Bewerken', + copy: 'Kopieren', + copied: 'Gekopieerd', + expand: 'Uitklappen', + }, + PageHeader: { + back: 'Terug', + }, +}; diff --git a/components/locale/pl_PL.js b/components/locale/pl_PL.js new file mode 100644 index 000000000..c5da9e9ba --- /dev/null +++ b/components/locale/pl_PL.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/pl_PL'; +import DatePicker from '../date-picker/locale/pl_PL'; +import TimePicker from '../time-picker/locale/pl_PL'; +import Calendar from '../calendar/locale/pl_PL'; + +export default { + locale: 'pl', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Menu filtra', + filterConfirm: 'OK', + filterReset: 'Wyczyść', + selectAll: 'Zaznacz bieżącą stronę', + selectInvert: 'Odwróć zaznaczenie', + }, + Modal: { + okText: 'OK', + cancelText: 'Anuluj', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Anuluj', + }, + Transfer: { + searchPlaceholder: 'Szukaj', + itemUnit: 'obiekt', + itemsUnit: 'obiekty', + }, + Upload: { + uploading: 'Wysyłanie...', + removeFile: 'Usuń plik', + uploadError: 'Błąd wysyłania', + previewFile: 'Podejrzyj plik', + downloadFile: 'Pobieranie pliku', + }, + Empty: { + description: 'Brak danych', + }, +}; diff --git a/components/locale/pt_BR.js b/components/locale/pt_BR.js new file mode 100644 index 000000000..c50b9283a --- /dev/null +++ b/components/locale/pt_BR.js @@ -0,0 +1,49 @@ +import Pagination from '../vc-pagination/locale/pt_BR'; +import DatePicker from '../date-picker/locale/pt_BR'; +import TimePicker from '../time-picker/locale/pt_BR'; +import Calendar from '../calendar/locale/pt_BR'; + +export default { + locale: 'pt-br', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Filtro', + filterConfirm: 'OK', + filterReset: 'Resetar', + selectAll: 'Selecionar página atual', + selectInvert: 'Inverter seleção', + }, + Modal: { + okText: 'OK', + cancelText: 'Cancelar', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Cancelar', + }, + Transfer: { + searchPlaceholder: 'Procurar', + itemUnit: 'item', + itemsUnit: 'items', + }, + Upload: { + uploading: 'Enviando...', + removeFile: 'Remover arquivo', + uploadError: 'Erro no envio', + previewFile: 'Visualizar arquivo', + downloadFile: 'Baixar arquivo', + }, + Empty: { + description: 'Não há dados', + }, + Text: { + edit: 'editar', + copy: 'copiar', + copied: 'copiado', + expand: 'expandir', + }, +}; diff --git a/components/locale/pt_PT.js b/components/locale/pt_PT.js new file mode 100644 index 000000000..89deec39b --- /dev/null +++ b/components/locale/pt_PT.js @@ -0,0 +1,44 @@ +import Pagination from '../vc-pagination/locale/pt_PT'; +import DatePicker from '../date-picker/locale/pt_PT'; +import TimePicker from '../time-picker/locale/pt_PT'; +import Calendar from '../calendar/locale/pt_PT'; + +export default { + locale: 'pt', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Filtro', + filterConfirm: 'Aplicar', + filterReset: 'Reiniciar', + selectAll: 'Selecionar página atual', + selectInvert: 'Inverter seleção', + sortTitle: 'Ordenação', + }, + Modal: { + okText: 'OK', + cancelText: 'Cancelar', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Cancelar', + }, + Transfer: { + searchPlaceholder: 'Procurar...', + itemUnit: 'item', + itemsUnit: 'itens', + }, + Upload: { + uploading: 'A carregar...', + removeFile: 'Remover', + uploadError: 'Erro ao carregar', + previewFile: 'Pré-visualizar', + downloadFile: 'Baixar', + }, + Empty: { + description: 'Sem resultados', + }, +}; diff --git a/components/locale/ro_RO.js b/components/locale/ro_RO.js new file mode 100644 index 000000000..eec391c0e --- /dev/null +++ b/components/locale/ro_RO.js @@ -0,0 +1,62 @@ +import Pagination from '../vc-pagination/locale/ro_RO'; +import DatePicker from '../date-picker/locale/ro_RO'; +import TimePicker from '../time-picker/locale/ro_RO'; +import Calendar from '../calendar/locale/ro_RO'; + +export default { + locale: 'ro', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Selectează', + }, + Table: { + filterTitle: 'Filtrează', + filterConfirm: 'OK', + filterReset: 'Resetează', + selectAll: 'Selectează pagina curentă', + selectInvert: 'Inversează pagina curentă', + sortTitle: 'Ordonează', + expand: 'Extinde rândul', + collapse: 'Micșorează rândul', + }, + Modal: { + okText: 'OK', + cancelText: 'Anulare', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Anulare', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Căutare', + itemUnit: 'element', + itemsUnit: 'elemente', + }, + Upload: { + uploading: 'Se transferă...', + removeFile: 'Înlătură fișierul', + uploadError: 'Eroare la upload', + previewFile: 'Previzualizare fișier', + downloadFile: 'Descărcare fișier', + }, + Empty: { + description: 'Fără date', + }, + Icon: { + icon: 'icon', + }, + Text: { + edit: 'editează', + copy: 'copiază', + copied: 'copiat', + expand: 'extinde', + }, + PageHeader: { + back: 'înapoi', + }, +}; diff --git a/components/locale/ru_RU.js b/components/locale/ru_RU.js new file mode 100644 index 000000000..451235a23 --- /dev/null +++ b/components/locale/ru_RU.js @@ -0,0 +1,53 @@ +import Pagination from '../vc-pagination/locale/ru_RU'; +import DatePicker from '../date-picker/locale/ru_RU'; +import TimePicker from '../time-picker/locale/ru_RU'; +import Calendar from '../calendar/locale/ru_RU'; + +export default { + locale: 'ru', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Фильтр', + filterConfirm: 'OK', + filterReset: 'Сбросить', + selectAll: 'Выбрать всё', + selectInvert: 'Инвертировать выбор', + sortTitle: 'Сортировка', + }, + Modal: { + okText: 'OK', + cancelText: 'Отмена', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Отмена', + }, + Transfer: { + searchPlaceholder: 'Поиск', + itemUnit: 'элем.', + itemsUnit: 'элем.', + }, + Upload: { + uploading: 'Загрузка...', + removeFile: 'Удалить файл', + uploadError: 'При загрузке произошла ошибка', + previewFile: 'Предпросмотр файла', + downloadFile: 'Загрузить файл', + }, + Empty: { + description: 'Нет данных', + }, + Text: { + edit: 'редактировать', + copy: 'копировать', + copied: 'скопировано', + expand: 'раскрыть', + }, + PageHeader: { + back: 'назад', + }, +}; diff --git a/components/locale/sk_SK.js b/components/locale/sk_SK.js new file mode 100644 index 000000000..fd3e67226 --- /dev/null +++ b/components/locale/sk_SK.js @@ -0,0 +1,62 @@ +import Pagination from '../vc-pagination/locale/sk_SK'; +import DatePicker from '../date-picker/locale/sk_SK'; +import TimePicker from '../time-picker/locale/sk_SK'; +import Calendar from '../calendar/locale/sk_SK'; + +export default { + locale: 'sk', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Prosím vyberte', + }, + Table: { + filterTitle: 'Filter', + filterConfirm: 'OK', + filterReset: 'Obnoviť', + selectAll: 'Vybrať všetko', + selectInvert: 'Vybrať opačné', + sortTitle: 'Zoradiť', + expand: 'Rozbaliť riadok', + collapse: 'Zbaliť riadok', + }, + Modal: { + okText: 'OK', + cancelText: 'Zrušiť', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Zrušiť', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Vyhľadávanie', + itemUnit: 'položka', + itemsUnit: 'položiek', + }, + Upload: { + uploading: 'Nahrávanie...', + removeFile: 'Odstrániť súbor', + uploadError: 'Chyba pri nahrávaní', + previewFile: 'Zobraziť súbor', + downloadFile: 'Stiahnuť súbor', + }, + Empty: { + description: 'Žiadne dáta', + }, + Icon: { + icon: 'ikona', + }, + Text: { + edit: 'Upraviť', + copy: 'Kopírovať', + copied: 'Skopírované', + expand: 'Zväčšiť', + }, + PageHeader: { + back: 'Späť', + }, +}; diff --git a/components/locale/sl_SI.js b/components/locale/sl_SI.js new file mode 100644 index 000000000..afbbde48c --- /dev/null +++ b/components/locale/sl_SI.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/sl_SI'; +import DatePicker from '../date-picker/locale/sl_SI'; +import TimePicker from '../time-picker/locale/sl_SI'; +import Calendar from '../calendar/locale/sl_SI'; + +export default { + locale: 'sl', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Filter', + filterConfirm: 'Filtriraj', + filterReset: 'Pobriši filter', + selectAll: 'Izberi vse na trenutni strani', + selectInvert: 'Obrni izbor na trenutni strani', + }, + Modal: { + okText: 'V redu', + cancelText: 'Prekliči', + justOkText: 'V redu', + }, + Popconfirm: { + okText: 'v redu', + cancelText: 'Prekliči', + }, + Transfer: { + searchPlaceholder: 'Išči tukaj', + itemUnit: 'Objekt', + itemsUnit: 'Objektov', + }, + Upload: { + uploading: 'Nalaganje...', + removeFile: 'Odstrani datoteko', + uploadError: 'Napaka pri nalaganju', + previewFile: 'Predogled datoteke', + downloadFile: 'Prenos datoteke', + }, + Empty: { + description: 'Ni podatkov', + }, +}; diff --git a/components/locale/sr_RS.js b/components/locale/sr_RS.js new file mode 100644 index 000000000..0cdda61b0 --- /dev/null +++ b/components/locale/sr_RS.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/sr_RS'; +import DatePicker from '../date-picker/locale/sr_RS'; +import TimePicker from '../time-picker/locale/sr_RS'; +import Calendar from '../calendar/locale/sr_RS'; + +export default { + locale: 'sr', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Filter', + filterConfirm: 'Primeni filter', + filterReset: 'Resetuj filter', + selectAll: 'Obeleži sve na trenutnoj strani', + selectInvert: 'Obrni selekciju na trenutnoj stranici', + }, + Modal: { + okText: 'U redu', + cancelText: 'Otkaži', + justOkText: 'U redu', + }, + Popconfirm: { + okText: 'U redu', + cancelText: 'Otkaži', + }, + Transfer: { + searchPlaceholder: 'Pretražite ovde', + itemUnit: 'stavka', + itemsUnit: 'stavki', + }, + Upload: { + uploading: 'Slanje...', + removeFile: 'Ukloni fajl', + uploadError: 'Greška prilikom slanja', + previewFile: 'Pogledaj fajl', + downloadFile: 'Preuzmi datoteku', + }, + Empty: { + description: 'Nema podataka', + }, +}; diff --git a/components/locale/sv_SE.js b/components/locale/sv_SE.js new file mode 100644 index 000000000..48340c593 --- /dev/null +++ b/components/locale/sv_SE.js @@ -0,0 +1,47 @@ +import Pagination from '../vc-pagination/locale/sv_SE'; +import DatePicker from '../date-picker/locale/sv_SE'; +import TimePicker from '../time-picker/locale/sv_SE'; +import Calendar from '../calendar/locale/sv_SE'; + +export default { + locale: 'sv', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Filtermeny', + filterConfirm: 'OK', + filterReset: 'Rensa', + }, + Modal: { + okText: 'OK', + cancelText: 'Avbryt', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Avbryt', + }, + Transfer: { + searchPlaceholder: 'Sök', + itemUnit: 'element', + itemsUnit: 'element', + }, + Empty: { + description: 'Ingen information', + }, + Text: { + edit: 'editera', + copy: 'kopiera', + copied: 'kopierad', + expand: 'expandera', + }, + Upload: { + uploading: 'Uppladdning...', + removeFile: 'Ta bort fil', + uploadError: 'Uppladdningsfel', + previewFile: 'Förhandsgranska filen', + downloadFile: 'Nedladdning fil', + }, +}; diff --git a/components/locale/ta_IN.js b/components/locale/ta_IN.js new file mode 100644 index 000000000..2b0e9079c --- /dev/null +++ b/components/locale/ta_IN.js @@ -0,0 +1,63 @@ +import Pagination from '../vc-pagination/locale/ta_IN'; +import DatePicker from '../date-picker/locale/ta_IN'; +import TimePicker from '../time-picker/locale/ta_IN'; +import Calendar from '../calendar/locale/ta_IN'; + +export default { + locale: 'ta', + Pagination, + DatePicker, + TimePicker, + Calendar, + // locales for all comoponents + global: { + placeholder: 'தேதியைத் தேர்ந்தெடுக்கவும்', + }, + Table: { + filterTitle: 'பட்டியலை மூடு', + filterConfirm: 'சரி', + filterReset: 'மீட்டமை', + emptyText: 'தகவல் இல்லை', + selectAll: 'அனைத்தையும் தேர்வுசெய்', + selectInvert: 'தலைகீழாக மாற்று', + sortTitle: 'தலைப்பை வரிசைப்படுத்தவும்', + }, + Modal: { + okText: 'சரி', + cancelText: 'ரத்து செய்யவும்', + justOkText: 'பரவாயில்லை, சரி', + }, + Popconfirm: { + okText: 'சரி', + cancelText: 'ரத்து செய்யவும்', + }, + Transfer: { + titles: ['', ''], + notFoundContent: 'உள்ளடக்கம் கிடைக்கவில்லை', + searchPlaceholder: 'இங்கு தேடவும்', + itemUnit: 'தகவல்', + itemsUnit: 'தகவல்கள்', + }, + Upload: { + uploading: 'பதிவேற்றுகிறது...', + removeFile: 'கோப்பை அகற்று', + uploadError: 'பதிவேற்றுவதில் பிழை', + previewFile: 'கோப்பை முன்னோட்டமிடுங்கள்', + downloadFile: 'பதிவிறக்க கோப்பு', + }, + Empty: { + description: 'தகவல் இல்லை', + }, + Icon: { + icon: 'உருவம்', + }, + Text: { + edit: 'திருத்து', + copy: 'நகல் எடு', + copied: 'நகல் எடுக்கப்பட்டது', + expand: 'விரிவாக்கவும்', + }, + PageHeader: { + back: 'பின் செல்லவும்', + }, +}; diff --git a/components/locale/th_TH.js b/components/locale/th_TH.js new file mode 100644 index 000000000..8257cd3f5 --- /dev/null +++ b/components/locale/th_TH.js @@ -0,0 +1,62 @@ +import Pagination from '../vc-pagination/locale/th_TH'; +import DatePicker from '../date-picker/locale/th_TH'; +import TimePicker from '../time-picker/locale/th_TH'; +import Calendar from '../calendar/locale/th_TH'; + +export default { + locale: 'th', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'กรุณาเลือก', + }, + Table: { + filterTitle: 'ตัวกรอง', + filterConfirm: 'ยืนยัน', + filterReset: 'รีเซ็ต', + selectAll: 'เลือกทั้งหมดในหน้านี้', + selectInvert: 'เลือกสถานะตรงกันข้าม', + sortTitle: 'เรียง', + expand: 'แสดงแถวข้อมูล', + collapse: 'ย่อแถวข้อมูล', + }, + Modal: { + okText: 'ตกลง', + cancelText: 'ยกเลิก', + justOkText: 'ตกลง', + }, + Popconfirm: { + okText: 'ตกลง', + cancelText: 'ยกเลิก', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'ค้นหา', + itemUnit: 'ชิ้น', + itemsUnit: 'ชิ้น', + }, + Upload: { + uploading: 'กำลังอัปโหลด...', + removeFile: 'ลบไฟล์', + uploadError: 'เกิดข้อผิดพลาดในการอัปโหลด', + previewFile: 'ดูตัวอย่างไฟล์', + downloadFile: 'ดาวน์โหลดไฟล์', + }, + Empty: { + description: 'ไม่มีข้อมูล', + }, + Icon: { + icon: 'ไอคอน', + }, + Text: { + edit: 'แก้ไข', + copy: 'คัดลอก', + copied: 'คัดลอกแล้ว', + expand: 'ขยาย', + }, + PageHeader: { + back: 'ย้อนกลับ', + }, +}; diff --git a/components/locale/tr_TR.js b/components/locale/tr_TR.js new file mode 100644 index 000000000..a82bd9812 --- /dev/null +++ b/components/locale/tr_TR.js @@ -0,0 +1,57 @@ +import Pagination from '../vc-pagination/locale/tr_TR'; +import DatePicker from '../date-picker/locale/tr_TR'; +import TimePicker from '../time-picker/locale/tr_TR'; +import Calendar from '../calendar/locale/tr_TR'; + +export default { + locale: 'tr', + Pagination, + DatePicker, + TimePicker, + Calendar, + global: { + placeholder: 'Lütfen seçiniz', + }, + Table: { + filterTitle: 'Menü Filtrele', + filterConfirm: 'Tamam', + filterReset: 'Sıfırla', + selectAll: 'Hepsini Seç', + selectInvert: 'Tersini Seç', + sortTitle: 'Sırala', + }, + Modal: { + okText: 'Tamam', + cancelText: 'İptal', + justOkText: 'Tamam', + }, + Popconfirm: { + okText: 'Tamam', + cancelText: 'İptal', + }, + Transfer: { + titles: ['', ''], + searchPlaceholder: 'Arama', + itemUnit: 'Öğe', + itemsUnit: 'Öğeler', + }, + Upload: { + uploading: 'Yükleniyor...', + removeFile: `Dosyayı kaldır`, + uploadError: 'Yükleme Hatası', + previewFile: `Dosyayı Önizle`, + downloadFile: 'Dosyayı indir', + }, + Empty: { + description: 'Veri Yok', + }, + Icon: { + icon: 'icon', + }, + Text: { + edit: 'düzenle', + copy: 'kopyala', + copied: 'kopyalandı', + expand: 'genişlet', + }, +}; diff --git a/components/locale/uk_UA.js b/components/locale/uk_UA.js new file mode 100644 index 000000000..1712bc6b2 --- /dev/null +++ b/components/locale/uk_UA.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/uk_UA'; +import DatePicker from '../date-picker/locale/uk_UA'; +import TimePicker from '../time-picker/locale/uk_UA'; +import Calendar from '../calendar/locale/uk_UA'; + +export default { + locale: 'uk', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Фільтрувати', + filterConfirm: 'OK', + filterReset: 'Скинути', + selectAll: 'Обрати всі', + selectInvert: 'Інвертувати вибір', + }, + Modal: { + okText: 'Гаразд', + cancelText: 'Скасувати', + justOkText: 'Гаразд', + }, + Popconfirm: { + okText: 'Гаразд', + cancelText: 'Скасувати', + }, + Transfer: { + searchPlaceholder: 'Введіть текст для пошуку', + itemUnit: 'item', + itemsUnit: 'items', + }, + Upload: { + uploading: 'Завантаження ...', + removeFile: 'Видалити файл', + uploadError: 'Помилка завантаження', + previewFile: 'Попередній перегляд файлу', + downloadFile: 'Завантажити файл', + }, + Empty: { + description: 'Даних немає', + }, +}; diff --git a/components/locale/vi_VN.js b/components/locale/vi_VN.js new file mode 100644 index 000000000..f09c4f104 --- /dev/null +++ b/components/locale/vi_VN.js @@ -0,0 +1,43 @@ +import Pagination from '../vc-pagination/locale/vi_VN'; +import DatePicker from '../date-picker/locale/vi_VN'; +import TimePicker from '../time-picker/locale/vi_VN'; +import Calendar from '../calendar/locale/vi_VN'; + +export default { + locale: 'vi', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: 'Bộ ', + filterConfirm: 'OK', + filterReset: 'Tạo Lại', + selectAll: 'Chọn Tất Cả', + selectInvert: 'Chọn Ngược Lại', + }, + Modal: { + okText: 'OK', + cancelText: 'Huỷ', + justOkText: 'OK', + }, + Popconfirm: { + okText: 'OK', + cancelText: 'Huỷ', + }, + Transfer: { + searchPlaceholder: 'Tìm ở đây', + itemUnit: 'mục', + itemsUnit: 'mục', + }, + Upload: { + uploading: 'Đang tải lên...', + removeFile: 'Gỡ bỏ tập tin', + uploadError: 'Lỗi tải lên', + previewFile: 'Xem thử tập tin', + downloadFile: 'Tải tập tin', + }, + Empty: { + description: 'Trống', + }, +}; diff --git a/components/locale/zh_CN.js b/components/locale/zh_CN.js new file mode 100644 index 000000000..65283c371 --- /dev/null +++ b/components/locale/zh_CN.js @@ -0,0 +1,62 @@ +import Pagination from '../vc-pagination/locale/zh_CN'; +import DatePicker from '../date-picker/locale/zh_CN'; +import TimePicker from '../time-picker/locale/zh_CN'; +import Calendar from '../calendar/locale/zh_CN'; + +export default { + locale: 'zh-cn', + Pagination, + DatePicker, + TimePicker, + Calendar, + // locales for all comoponents + global: { + placeholder: '请选择', + }, + Table: { + filterTitle: '筛选', + filterConfirm: '确定', + filterReset: '重置', + selectAll: '全选当页', + selectInvert: '反选当页', + sortTitle: '排序', + expand: '展开行', + collapse: '关闭行', + }, + Modal: { + okText: '确定', + cancelText: '取消', + justOkText: '知道了', + }, + Popconfirm: { + cancelText: '取消', + okText: '确定', + }, + Transfer: { + searchPlaceholder: '请输入搜索内容', + itemUnit: '项', + itemsUnit: '项', + }, + Upload: { + uploading: '文件上传中', + removeFile: '删除文件', + uploadError: '上传错误', + previewFile: '预览文件', + downloadFile: '下载文件', + }, + Empty: { + description: '暂无数据', + }, + Icon: { + icon: '图标', + }, + Text: { + edit: '编辑', + copy: '复制', + copied: '复制成功', + expand: '展开', + }, + PageHeader: { + back: '返回', + }, +}; diff --git a/components/locale/zh_TW.js b/components/locale/zh_TW.js new file mode 100644 index 000000000..bc216f302 --- /dev/null +++ b/components/locale/zh_TW.js @@ -0,0 +1,46 @@ +import Pagination from '../vc-pagination/locale/zh_TW'; +import DatePicker from '../date-picker/locale/zh_TW'; +import TimePicker from '../time-picker/locale/zh_TW'; +import Calendar from '../calendar/locale/zh_TW'; + +export default { + locale: 'zh-tw', + Pagination, + DatePicker, + TimePicker, + Calendar, + Table: { + filterTitle: '篩選器', + filterConfirm: '確 定', + filterReset: '重 置', + selectAll: '全部選取', + selectInvert: '反向選取', + }, + Modal: { + okText: '確 定', + cancelText: '取 消', + justOkText: 'OK', + }, + Popconfirm: { + okText: '確 定', + cancelText: '取 消', + }, + Transfer: { + searchPlaceholder: '搜尋資料', + itemUnit: '項目', + itemsUnit: '項目', + }, + Upload: { + uploading: '正在上傳...', + removeFile: '刪除檔案', + uploadError: '上傳失敗', + previewFile: '檔案預覽', + downloadFile: '下载文件', + }, + Empty: { + description: '無此資料', + }, + PageHeader: { + back: '返回', + }, +}; diff --git a/components/mentions/__test__/__snapshots__/demo.test.js.snap b/components/mentions/__test__/__snapshots__/demo.test.js.snap new file mode 100644 index 000000000..8e659e777 --- /dev/null +++ b/components/mentions/__test__/__snapshots__/demo.test.js.snap @@ -0,0 +1,46 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders ./antdv-demo/mentions/demo/async.md correctly 1`] = `
`; + +exports[`renders ./antdv-demo/mentions/demo/basic.md correctly 1`] = `
`; + +exports[`renders ./antdv-demo/mentions/demo/form.md correctly 1`] = ` +
+
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+`; + +exports[`renders ./antdv-demo/mentions/demo/placement.md correctly 1`] = `
`; + +exports[`renders ./antdv-demo/mentions/demo/prefix.md correctly 1`] = `
`; + +exports[`renders ./antdv-demo/mentions/demo/readonly.md correctly 1`] = ` +
+
+
+
+
+
+`; diff --git a/components/mentions/__test__/demo.test.js b/components/mentions/__test__/demo.test.js new file mode 100644 index 000000000..1946e5565 --- /dev/null +++ b/components/mentions/__test__/demo.test.js @@ -0,0 +1,3 @@ +import demoTest from '../../../tests/shared/demoTest'; + +demoTest('mentions'); diff --git a/components/mentions/__test__/index.test.js b/components/mentions/__test__/index.test.js new file mode 100644 index 000000000..a9625d44d --- /dev/null +++ b/components/mentions/__test__/index.test.js @@ -0,0 +1,91 @@ +import { mount } from '@vue/test-utils'; +import Vue from 'vue'; +import Mentions from '..'; +import { asyncExpect } from '@/tests/utils'; +import focusTest from '../../../tests/shared/focusTest'; + +const { getMentions } = Mentions; + +function $$(className) { + return document.body.querySelectorAll(className); +} + +function triggerInput(wrapper, text = '') { + wrapper.find('textarea').element.value = text; + wrapper.find('textarea').element.selectionStart = text.length; + wrapper.find('textarea').trigger('keydown'); + wrapper.find('textarea').trigger('change'); + wrapper.find('textarea').trigger('keyup'); +} + +describe('Mentions', () => { + beforeAll(() => { + jest.useFakeTimers(); + }); + + afterAll(() => { + jest.useRealTimers(); + }); + + it('getMentions', () => { + const mentions = getMentions('@light #bamboo cat', { prefix: ['@', '#'] }); + expect(mentions).toEqual([ + { + prefix: '@', + value: 'light', + }, + { + prefix: '#', + value: 'bamboo', + }, + ]); + }); + + it('focus', () => { + const onFocus = jest.fn(); + const onBlur = jest.fn(); + + const wrapper = mount({ + render() { + return ; + }, + }); + wrapper.find('textarea').trigger('focus'); + expect(wrapper.find('.ant-mentions').classes('ant-mentions-focused')).toBeTruthy(); + expect(onFocus).toHaveBeenCalled(); + + wrapper.find('textarea').trigger('blur'); + jest.runAllTimers(); + expect(wrapper.classes()).not.toContain('ant-mentions-focused'); + expect(onBlur).toHaveBeenCalled(); + }); + + it('loading', done => { + const wrapper = mount( + { + render() { + return ; + }, + }, + { sync: false }, + ); + triggerInput(wrapper, '@'); + Vue.nextTick(() => { + mount( + { + render() { + return wrapper.find({ name: 'Trigger' }).vm.getComponent(); + }, + }, + { sync: false }, + ); + Vue.nextTick(() => { + expect($$('.ant-mentions-dropdown-menu-item').length).toBeTruthy(); + expect($$('.ant-spin')).toBeTruthy(); + done(); + }); + }); + }); + + focusTest(Mentions); +}); diff --git a/components/mentions/index.jsx b/components/mentions/index.jsx new file mode 100644 index 000000000..8f170d3b0 --- /dev/null +++ b/components/mentions/index.jsx @@ -0,0 +1,189 @@ +import classNames from 'classnames'; +import omit from 'omit.js'; +import PropTypes from '../_util/vue-types'; +import VcMentions from '../vc-mentions'; +import { mentionsProps } from '../vc-mentions/src/mentionsProps'; +import Base from '../base'; +import Spin from '../spin'; +import BaseMixin from '../_util/BaseMixin'; +import { ConfigConsumerProps } from '../config-provider'; +import { + getOptionProps, + getComponentFromProp, + getListeners, + filterEmpty, +} from '../_util/props-util'; + +const { Option } = VcMentions; + +function loadingFilterOption() { + return true; +} + +function getMentions(value = '', config) { + const { prefix = '@', split = ' ' } = config || {}; + const prefixList = Array.isArray(prefix) ? prefix : [prefix]; + + return value + .split(split) + .map((str = '') => { + let hitPrefix = null; + + prefixList.some(prefixStr => { + const startStr = str.slice(0, prefixStr.length); + if (startStr === prefixStr) { + hitPrefix = prefixStr; + return true; + } + return false; + }); + + if (hitPrefix !== null) { + return { + prefix: hitPrefix, + value: str.slice(hitPrefix.length), + }; + } + return null; + }) + .filter(entity => !!entity && !!entity.value); +} + +const Mentions = { + name: 'AMentions', + mixins: [BaseMixin], + inheritAttrs: false, + model: { + prop: 'value', + event: 'change', + }, + Option: { ...Option, name: 'AMentionsOption' }, + getMentions, + props: { + ...mentionsProps, + loading: PropTypes.bool, + }, + inject: { + configProvider: { default: () => ConfigConsumerProps }, + }, + data() { + return { + focused: false, + }; + }, + mounted() { + this.$nextTick(() => { + if (this.autoFocus) { + this.focus(); + } + }); + }, + methods: { + onFocus(...args) { + this.$emit('focus', ...args); + this.setState({ + focused: true, + }); + }, + onBlur(...args) { + this.$emit('blur', ...args); + this.setState({ + focused: false, + }); + }, + onSelect(...args) { + this.$emit('select', ...args); + this.setState({ + focused: true, + }); + }, + onChange(val) { + this.$emit('change', val); + }, + getNotFoundContent(renderEmpty) { + const h = this.$createElement; + const notFoundContent = getComponentFromProp(this, 'notFoundContent'); + if (notFoundContent !== undefined) { + return notFoundContent; + } + + return renderEmpty(h, 'Select'); + }, + getOptions() { + const { loading } = this.$props; + const children = filterEmpty(this.$slots.default || []); + + if (loading) { + return ( + + ); + } + return children; + }, + getFilterOption() { + const { filterOption, loading } = this.$props; + if (loading) { + return loadingFilterOption; + } + return filterOption; + }, + focus() { + this.$refs.vcMentions.focus(); + }, + blur() { + this.$refs.vcMentions.blur(); + }, + }, + render() { + const { focused } = this.$data; + const { getPrefixCls, renderEmpty } = this.configProvider; + const { + prefixCls: customizePrefixCls, + disabled, + getPopupContainer, + ...restProps + } = getOptionProps(this); + const prefixCls = getPrefixCls('mentions', customizePrefixCls); + const otherProps = omit(restProps, ['loading']); + + const mergedClassName = classNames({ + [`${prefixCls}-disabled`]: disabled, + [`${prefixCls}-focused`]: focused, + }); + + const mentionsProps = { + props: { + prefixCls, + notFoundContent: this.getNotFoundContent(renderEmpty), + ...otherProps, + disabled, + filterOption: this.getFilterOption(), + getPopupContainer: getPopupContainer, + children: this.getOptions(), + }, + class: mergedClassName, + attrs: { rows: 1, ...this.$attrs }, + on: { + ...getListeners(this), + change: this.onChange, + select: this.onSelect, + focus: this.onFocus, + blur: this.onBlur, + }, + ref: 'vcMentions', + }; + + return ; + }, +}; + +/* istanbul ignore next */ +Mentions.install = function(Vue) { + Vue.use(Base); + Vue.component(Mentions.name, Mentions); + Vue.component(Mentions.Option.name, Mentions.Option); +}; + +export default Mentions; diff --git a/components/mentions/style/index.js b/components/mentions/style/index.js new file mode 100644 index 000000000..5fa72cf4f --- /dev/null +++ b/components/mentions/style/index.js @@ -0,0 +1,5 @@ +import './index.less'; + +// style dependencies +import '../../empty/style'; +import '../../spin/style'; diff --git a/components/mentions/style/index.less b/components/mentions/style/index.less new file mode 100644 index 000000000..143a0673f --- /dev/null +++ b/components/mentions/style/index.less @@ -0,0 +1,164 @@ +@import '../../style/themes/index'; +@import '../../style/mixins/index'; +@import '../../input/style/mixin'; + +@mention-prefix-cls: ~'@{ant-prefix}-mentions'; + +.@{mention-prefix-cls} { + .reset-component; + .input; + + position: relative; + display: inline-block; + height: auto; + padding: 0; + overflow: hidden; + line-height: @line-height-base; + white-space: pre-wrap; + vertical-align: bottom; + + // =================== Status =================== + &-disabled { + > textarea { + .disabled(); + } + } + + &-focused { + .active(); + } + + // ================= Input Area ================= + > textarea, + &-measure { + min-height: @input-height-base - 2px; + margin: 0; + padding: @input-padding-vertical-base @input-padding-horizontal-base; + overflow: inherit; + overflow-x: hidden; + overflow-y: auto; + font-weight: inherit; + font-size: inherit; + font-family: inherit; + font-style: inherit; + font-variant: inherit; + font-size-adjust: inherit; + font-stretch: inherit; + line-height: inherit; + direction: inherit; + letter-spacing: inherit; + white-space: inherit; + text-align: inherit; + vertical-align: top; + word-wrap: break-word; + word-break: inherit; + tab-size: inherit; + } + + > textarea { + width: 100%; + border: none; + outline: none; + resize: none; + .placeholder(); + + &:read-only { + cursor: default; + } + } + + &-measure { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: -1; + color: transparent; + pointer-events: none; + + > span { + display: inline-block; + min-height: 1em; + } + } + + // ================== Dropdown ================== + &-dropdown { + // Ref select dropdown style + .reset-component; + + position: absolute; + top: -9999px; + left: -9999px; + z-index: @zindex-dropdown; + box-sizing: border-box; + font-size: @font-size-base; + font-variant: initial; + background-color: @component-background; + border-radius: @border-radius-base; + outline: none; + box-shadow: @box-shadow-base; + + &-hidden { + display: none; + } + + &-menu { + max-height: 250px; + margin-bottom: 0; + padding-left: 0; // Override default ul/ol + overflow: auto; + list-style: none; + outline: none; + + &-item { + position: relative; + display: block; + min-width: 100px; + padding: 5px @control-padding-horizontal; + overflow: hidden; + color: @text-color; + font-weight: normal; + line-height: 22px; + white-space: nowrap; + text-overflow: ellipsis; + cursor: pointer; + transition: background 0.3s ease; + + &:hover { + background-color: @item-hover-bg; + } + + &:first-child { + border-radius: @border-radius-base @border-radius-base 0 0; + } + + &:last-child { + border-radius: 0 0 @border-radius-base @border-radius-base; + } + + &-disabled { + color: @disabled-color; + cursor: not-allowed; + + &:hover { + color: @disabled-color; + background-color: @component-background; + cursor: not-allowed; + } + } + + &-selected { + color: @text-color; + font-weight: @select-item-selected-font-weight; + background-color: @background-color-light; + } + + &-active { + background-color: @item-active-bg; + } + } + } + } +} diff --git a/components/menu/MenuItem.jsx b/components/menu/MenuItem.jsx index bf06b726c..c9196d999 100644 --- a/components/menu/MenuItem.jsx +++ b/components/menu/MenuItem.jsx @@ -8,8 +8,9 @@ export default { props: itemProps, inject: { getInlineCollapsed: { default: () => noop }, + layoutSiderContext: { default: () => ({}) }, }, - isMenuItem: 1, + isMenuItem: true, methods: { onKeyDown(e) { this.$refs.menuItem.onKeyDown(e); @@ -20,22 +21,28 @@ export default { const { level, title, rootPrefixCls } = props; const { getInlineCollapsed, $slots, $attrs: attrs } = this; const inlineCollapsed = getInlineCollapsed(); - let titleNode; - if (inlineCollapsed) { - titleNode = title || (level === 1 ? $slots.default : ''); + const tooltipProps = { + title: title || (level === 1 ? $slots.default : ''), + }; + const siderCollapsed = this.layoutSiderContext.sCollapsed; + if (!siderCollapsed && !inlineCollapsed) { + tooltipProps.title = null; + // Reset `visible` to fix control mode tooltip display not correct + // ref: https://github.com/ant-design/ant-design/issues/16742 + tooltipProps.visible = false; } const itemProps = { props: { ...props, - title: inlineCollapsed ? null : title, + title, }, attrs, on: getListeners(this), }; const toolTipProps = { props: { - title: titleNode, + ...tooltipProps, placement: 'right', overlayClassName: `${rootPrefixCls}-inline-collapsed-tooltip`, }, diff --git a/components/menu/SubMenu.jsx b/components/menu/SubMenu.jsx new file mode 100644 index 000000000..302084bee --- /dev/null +++ b/components/menu/SubMenu.jsx @@ -0,0 +1,42 @@ +import { SubMenu as VcSubMenu } from '../vc-menu'; +import { getListeners } from '../_util/props-util'; +import classNames from 'classnames'; + +export default { + name: 'ASubMenu', + isSubMenu: true, + props: { ...VcSubMenu.props }, + inject: { + menuPropsContext: { default: () => ({}) }, + }, + methods: { + onKeyDown(e) { + this.$refs.subMenu.onKeyDown(e); + }, + }, + + render() { + const { $slots, $scopedSlots } = this; + const { rootPrefixCls, popupClassName } = this.$props; + const { theme: antdMenuTheme } = this.menuPropsContext; + const props = { + props: { + ...this.$props, + popupClassName: classNames(`${rootPrefixCls}-${antdMenuTheme}`, popupClassName), + }, + ref: 'subMenu', + on: getListeners(this), + scopedSlots: $scopedSlots, + }; + const slotsKey = Object.keys($slots); + return ( + + {slotsKey.length + ? slotsKey.map(name => { + return ; + }) + : null} + + ); + }, +}; diff --git a/components/menu/__tests__/__snapshots__/demo.test.js.snap b/components/menu/__tests__/__snapshots__/demo.test.js.snap index 65446698f..e389fd56b 100644 --- a/components/menu/__tests__/__snapshots__/demo.test.js.snap +++ b/components/menu/__tests__/__snapshots__/demo.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/menu/demo/horizontal.md correctly 1`] = ` +exports[`renders ./antdv-demo/menu/demo/horizontal.md correctly 1`] = `
`; -exports[`renders ./components/menu/demo/inline.md correctly 1`] = ` +exports[`renders ./antdv-demo/menu/demo/inline.md correctly 1`] = `
`; -exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = ` +exports[`renders ./antdv-demo/menu/demo/inline-collapsed.md correctly 1`] = `
@@ -99,7 +99,7 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
`; -exports[`renders ./components/menu/demo/sider-current.md correctly 1`] = ` +exports[`renders ./antdv-demo/menu/demo/sider-current.md correctly 1`] = `
`; -exports[`renders ./components/menu/demo/switch-mode.md correctly 1`] = ` +exports[`renders ./antdv-demo/menu/demo/switch-mode.md correctly 1`] = `
Change Mode Change Theme

@@ -157,7 +157,7 @@ exports[`renders ./components/menu/demo/switch-mode.md correctly 1`] = `
`; -exports[`renders ./components/menu/demo/template.md correctly 1`] = ` +exports[`renders ./antdv-demo/menu/demo/template.md correctly 1`] = `
@@ -178,7 +178,7 @@ exports[`renders ./components/menu/demo/template.md correctly 1`] = `
`; -exports[`renders ./components/menu/demo/theme.md correctly 1`] = ` +exports[`renders ./antdv-demo/menu/demo/theme.md correctly 1`] = `


`; -exports[`renders ./components/menu/demo/vertical.md correctly 1`] = ` +exports[`renders ./antdv-demo/menu/demo/vertical.md correctly 1`] = `

-
`; -exports[`renders ./components/pagination/demo/more.md correctly 1`] = ` +exports[`renders ./antdv-demo/pagination/demo/more.md correctly 1`] = ` `; -exports[`renders ./components/pagination/demo/simple.md correctly 1`] = ` +exports[`renders ./antdv-demo/pagination/demo/simple.md correctly 1`] = ` `; -exports[`renders ./components/pagination/demo/total.md correctly 1`] = ` +exports[`renders ./antdv-demo/pagination/demo/total.md correctly 1`] = `
  • Total 85 items
  • diff --git a/components/pagination/__tests__/index.test.js b/components/pagination/__tests__/index.test.js new file mode 100644 index 000000000..cf32ca33c --- /dev/null +++ b/components/pagination/__tests__/index.test.js @@ -0,0 +1,6 @@ +import Pagination from '..'; +import mountTest from '../../../tests/shared/mountTest'; + +describe('Pagination', () => { + mountTest(Pagination); +}); diff --git a/components/pagination/demo/basic.md b/components/pagination/demo/basic.md deleted file mode 100644 index 41b038db8..000000000 --- a/components/pagination/demo/basic.md +++ /dev/null @@ -1,24 +0,0 @@ - -#### 基本 -基础分页。 - - - -#### Basic -Basic pagination. - - -```tpl - - -``` diff --git a/components/pagination/demo/changer.md b/components/pagination/demo/changer.md deleted file mode 100644 index 75961c6ba..000000000 --- a/components/pagination/demo/changer.md +++ /dev/null @@ -1,53 +0,0 @@ - -#### 改变 -改变每页显示条目数。 - - - -#### Changer -Change `pageSize`. - - -```tpl - - -``` diff --git a/components/pagination/demo/controlled.md b/components/pagination/demo/controlled.md deleted file mode 100644 index 84fdba22b..000000000 --- a/components/pagination/demo/controlled.md +++ /dev/null @@ -1,29 +0,0 @@ - -#### 受控 -受控制的页码。 - - - -#### Controlled -Controlled page number. - - -```tpl - - -``` diff --git a/components/pagination/demo/custom-changer.md b/components/pagination/demo/custom-changer.md deleted file mode 100644 index 0afbf63ee..000000000 --- a/components/pagination/demo/custom-changer.md +++ /dev/null @@ -1,44 +0,0 @@ - -#### 自定义下拉选项 -自定义下拉选项,例如添加全部选项 - - - -#### Custom dropdown options -Customize dropdown options such as adding all options - - -```tpl - - -``` diff --git a/components/pagination/demo/index.vue b/components/pagination/demo/index.vue deleted file mode 100644 index 8356eb98d..000000000 --- a/components/pagination/demo/index.vue +++ /dev/null @@ -1,67 +0,0 @@ - diff --git a/components/pagination/demo/itemRender.md b/components/pagination/demo/itemRender.md deleted file mode 100644 index 6b8da5ebe..000000000 --- a/components/pagination/demo/itemRender.md +++ /dev/null @@ -1,29 +0,0 @@ - -#### 上一步和下一步 -修改上一步和下一步为文字链接。 - - - -#### Prev and next -Use text link for prev and next button. - - -```tpl - - -``` diff --git a/components/pagination/demo/jump.md b/components/pagination/demo/jump.md deleted file mode 100644 index b055c56a8..000000000 --- a/components/pagination/demo/jump.md +++ /dev/null @@ -1,24 +0,0 @@ - -#### 跳转 -快速跳转到某一页。 - - - -#### Jumper -Jump to a page directly. - - -```tpl - - -``` diff --git a/components/pagination/demo/mini.md b/components/pagination/demo/mini.md deleted file mode 100644 index 131078f8b..000000000 --- a/components/pagination/demo/mini.md +++ /dev/null @@ -1,24 +0,0 @@ - -#### 迷你 -迷你版本。 - - - -#### Mini size -Mini size pagination. - - -```tpl - - -``` diff --git a/components/pagination/demo/more.md b/components/pagination/demo/more.md deleted file mode 100644 index 2cb0b1e3e..000000000 --- a/components/pagination/demo/more.md +++ /dev/null @@ -1,15 +0,0 @@ - -#### 更多 -更多分页。 - - - -#### more -Mode pages. - - -```tpl - -``` diff --git a/components/pagination/demo/simple.md b/components/pagination/demo/simple.md deleted file mode 100644 index 3de4a3804..000000000 --- a/components/pagination/demo/simple.md +++ /dev/null @@ -1,15 +0,0 @@ - -#### 简洁 -简单的翻页。 - - - -#### Simple mode -Simple mode. - - -```tpl - -``` diff --git a/components/pagination/demo/total.md b/components/pagination/demo/total.md deleted file mode 100644 index 2a53909a8..000000000 --- a/components/pagination/demo/total.md +++ /dev/null @@ -1,29 +0,0 @@ - -#### 总数 -通过设置 `showTotal` 展示总共有多少数据。 - - - -#### Total number -You can show the total number of data by setting `showTotal`. - - -```tpl - -``` diff --git a/components/pagination/index.en-US.md b/components/pagination/index.en-US.md deleted file mode 100644 index 0ff177541..000000000 --- a/components/pagination/index.en-US.md +++ /dev/null @@ -1,28 +0,0 @@ -## API - -```html - -``` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| current(v-model) | current page number | number | - | -| defaultCurrent | default initial page number | number | 1 | -| defaultPageSize | default number of data items per page | number | 10 | -| hideOnSinglePage | Whether to hide pager on single page | boolean | false | -| itemRender | to customize item innerHTML | (page, type: 'page' \| 'prev' \| 'next', originalElement) => vNode | - | -| pageSize(.sync) | number of data items per page | number | - | -| pageSizeOptions | specify the sizeChanger options | string\[] | \['10', '20', '30', '40'] | -| showQuickJumper | determine whether you can jump to pages directly | boolean | false | -| showSizeChanger | determine whether `pageSize` can be changed | boolean | false | -| showTotal | to display the total number and range | Function(total, range) | - | -| simple | whether to use simple mode | boolean | - | -| size | specify the size of `Pagination`, can be set to `small` | string | "" | -| total | total number of data items | number | 0 | - -### events - -| Events Name | Description | Arguments | -| --- | --- | --- | -| change | a callback function, executed when the page number is changed, and it takes the resulting page number and pageSize as its arguments | Function(page, pageSize) | noop | -| showSizeChange | a callback function, executed when `pageSize` is changed | Function(current, size) | noop | diff --git a/components/pagination/index.zh-CN.md b/components/pagination/index.zh-CN.md deleted file mode 100644 index 24304d8cb..000000000 --- a/components/pagination/index.zh-CN.md +++ /dev/null @@ -1,28 +0,0 @@ -## API - -```html - -``` - -| 参数 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| current(v-model) | 当前页数 | number | - | -| defaultCurrent | 默认的当前页数 | number | 1 | -| defaultPageSize | 默认的每页条数 | number | 10 | -| hideOnSinglePage | 只有一页时是否隐藏分页器 | boolean | false | -| itemRender | 用于自定义页码的结构,可用于优化 SEO | (page, type: 'page' \| 'prev' \| 'next', originalElement) => vNode | - | -| pageSize(.sync) | 每页条数 | number | - | -| pageSizeOptions | 指定每页可以显示多少条 | string\[] | \['10', '20', '30', '40'] | -| showQuickJumper | 是否可以快速跳转至某页 | boolean | false | -| showSizeChanger | 是否可以改变 pageSize | boolean | false | -| showTotal | 用于显示数据总量和当前数据顺序 | Function(total, range) | - | -| simple | 当添加该属性时,显示为简单分页 | boolean | - | -| size | 当为「small」时,是小尺寸分页 | string | "" | -| total | 数据总数 | number | 0 | - -### 事件 - -| 事件名称 | 说明 | 回调参数 | -| -------------- | -------------------------------------------- | ------------------------ | -| change | 页码改变的回调,参数是改变后的页码及每页条数 | Function(page, pageSize) | noop | -| showSizeChange | pageSize 变化的回调 | Function(current, size) | noop | diff --git a/components/pagination/style/index.js b/components/pagination/style/index.js index d841ee8fa..17626c8e4 100644 --- a/components/pagination/style/index.js +++ b/components/pagination/style/index.js @@ -3,4 +3,3 @@ import './index.less'; // style dependencies import '../../select/style'; -import '../../input/style'; diff --git a/components/pagination/style/index.less b/components/pagination/style/index.less index b6ea0e43c..2266fe266 100644 --- a/components/pagination/style/index.less +++ b/components/pagination/style/index.less @@ -1,4 +1,4 @@ -@import '../../style/themes/default'; +@import '../../style/themes/index'; @import '../../style/mixins/index'; @import '../../input/style/mixin'; @@ -49,10 +49,14 @@ user-select: none; a { - margin: 0 6px; + display: block; + padding: 0 6px; color: @text-color; - text-decoration: none; transition: none; + + &:hover { + text-decoration: none; + } } &:focus, @@ -66,6 +70,7 @@ &-active { font-weight: @pagination-font-weight-active; + background: @pagination-item-bg-active; border-color: @primary-color; a { @@ -92,6 +97,7 @@ .@{pagination-prefix-cls}-item-link-icon { .iconfont-size-under-12px(12px); + color: @primary-color; letter-spacing: -1px; opacity: 0; @@ -225,6 +231,7 @@ input { .input; + width: 50px; margin: 0 8px; } @@ -320,10 +327,61 @@ input { .input-sm; + width: 44px; } } } + + // ============================ Disabled ============================ + &&-disabled { + cursor: not-allowed; + + .@{pagination-prefix-cls}-item { + background: @disabled-bg; + border-color: @border-color-base; + cursor: not-allowed; + + a { + color: @disabled-color; + background: transparent; + border: none; + cursor: not-allowed; + } + + &-active { + background: darken(@disabled-bg, 10%); + border-color: transparent; + a { + color: #fff; + } + } + } + + .@{pagination-prefix-cls}-item-link { + &, + &:hover, + &:focus { + color: @text-color-secondary; + background: @disabled-bg; + border-color: @border-color-base; + cursor: not-allowed; + } + } + + .@{pagination-prefix-cls}-jump-prev, + .@{pagination-prefix-cls}-jump-next { + &:focus, + &:hover { + .@{pagination-prefix-cls}-item-link-icon { + opacity: 0; + } + .@{pagination-prefix-cls}-item-ellipsis { + opacity: 1; + } + } + } + } } @media only screen and (max-width: @screen-lg) { diff --git a/components/popconfirm/__tests__/__snapshots__/demo.test.js.snap b/components/popconfirm/__tests__/__snapshots__/demo.test.js.snap index 7033f012f..e1be324f8 100644 --- a/components/popconfirm/__tests__/__snapshots__/demo.test.js.snap +++ b/components/popconfirm/__tests__/__snapshots__/demo.test.js.snap @@ -1,17 +1,17 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/popconfirm/demo/basic.md correctly 1`] = `
    Delete`; +exports[`renders ./antdv-demo/popconfirm/demo/basic.md correctly 1`] = `Delete`; -exports[`renders ./components/popconfirm/demo/dynamic-trigger.md correctly 1`] = ` +exports[`renders ./antdv-demo/popconfirm/demo/dynamic-trigger.md correctly 1`] = `
    Delete a task

    Whether directly execute:
    `; -exports[`renders ./components/popconfirm/demo/icon.md correctly 1`] = `Delete`; +exports[`renders ./antdv-demo/popconfirm/demo/icon.md correctly 1`] = `Delete`; -exports[`renders ./components/popconfirm/demo/local.md correctly 1`] = `Delete`; +exports[`renders ./antdv-demo/popconfirm/demo/local.md correctly 1`] = `Delete`; -exports[`renders ./components/popconfirm/demo/placement.md correctly 1`] = ` +exports[`renders ./antdv-demo/popconfirm/demo/placement.md correctly 1`] = `
    diff --git a/components/popconfirm/__tests__/index.test.js b/components/popconfirm/__tests__/index.test.js index 0a8477f50..8b21d6d86 100644 --- a/components/popconfirm/__tests__/index.test.js +++ b/components/popconfirm/__tests__/index.test.js @@ -72,4 +72,27 @@ describe('Popconfirm', () => { expect(popup.innerHTML).toMatchSnapshot(); }, 1000); }); + + it('should not open in disabled', async () => { + const popconfirm = mount( + { + render() { + return ( + + click me + + ); + }, + }, + { sync: false }, + ); + + await asyncExpect(() => { + popconfirm.find('span').trigger('click'); + }, 1000); + await asyncExpect(() => { + const popup = popconfirm.vm.$refs.popconfirm.getPopupDomNode(); + expect(popup).toBeFalsy(); + }, 1000); + }); }); diff --git a/components/popconfirm/demo/basic.md b/components/popconfirm/demo/basic.md deleted file mode 100644 index 9a8855a58..000000000 --- a/components/popconfirm/demo/basic.md +++ /dev/null @@ -1,37 +0,0 @@ - -#### 基本 -最简单的用法。 - - - -#### Basic -The basic example. - - -```tpl - - -``` diff --git a/components/popconfirm/demo/dynamic-trigger.md b/components/popconfirm/demo/dynamic-trigger.md deleted file mode 100644 index fbe9f2d44..000000000 --- a/components/popconfirm/demo/dynamic-trigger.md +++ /dev/null @@ -1,68 +0,0 @@ - -#### 条件触发 -可以判断是否需要弹出。 - - - -#### Conditional trigger -Make it pop up under some conditions. - - -```tpl - - -``` diff --git a/components/popconfirm/demo/icon.md b/components/popconfirm/demo/icon.md deleted file mode 100644 index 85c5e2fdb..000000000 --- a/components/popconfirm/demo/icon.md +++ /dev/null @@ -1,18 +0,0 @@ - -#### 自定义 Icon 图标 -使用 `icon` 自定义提示 `icon`。 - - - -#### Customize icon -Set `icon` props to customize the icon. - - -```tpl - -``` diff --git a/components/popconfirm/demo/index.vue b/components/popconfirm/demo/index.vue deleted file mode 100644 index 89a84694f..000000000 --- a/components/popconfirm/demo/index.vue +++ /dev/null @@ -1,57 +0,0 @@ - diff --git a/components/popconfirm/demo/local.md b/components/popconfirm/demo/local.md deleted file mode 100644 index e359ee489..000000000 --- a/components/popconfirm/demo/local.md +++ /dev/null @@ -1,17 +0,0 @@ - -#### 国际化 -使用 `okText` 和 `cancelText` 自定义按钮文字。 - - - -#### Locale text -Set `okText` and `cancelText` props to customize the button's labels. - - -```tpl - -``` diff --git a/components/popconfirm/demo/placement.md b/components/popconfirm/demo/placement.md deleted file mode 100644 index 74a39c43f..000000000 --- a/components/popconfirm/demo/placement.md +++ /dev/null @@ -1,134 +0,0 @@ - -#### 位置 -位置有十二个方向。如需箭头指向目标元素中心,可以设置 `arrowPointAtCenter`。 - - - -#### Placement -There are 12 `placement` options available. Use `arrowPointAtCenter` if you want arrow point at the center of target. - - -```tpl - - - -``` diff --git a/components/popconfirm/index.en-US.md b/components/popconfirm/index.en-US.md deleted file mode 100644 index 98dc1efb8..000000000 --- a/components/popconfirm/index.en-US.md +++ /dev/null @@ -1,23 +0,0 @@ -## API - -| Param | Description | Type | Default value | -| --- | --- | --- | --- | -| cancelText | text of the Cancel button | string\|slot | `Cancel` | -| okText | text of the Confirm button | string\|slot | `Confirm` | -| okType | Button `type` of the Confirm button | string | `primary` | -| title | title of the confirmation box | string\|slot | - | -| icon | customize icon of confirmation | vNode\|slot | <Icon type="exclamation-circle" /> | - -### events - -| Events Name | Description | Arguments | -| --- | --- | --- | -| cancel | callback of cancel | function(e) | - | -| confirm | callback of confirmation | function(e) | - | -| visibleChange | Callback executed when visibility of the tooltip card is changed | function(visible) | - | - -Consult [Tooltip's documentation](/components/tooltip/#API) to find more APIs. - -## Note - -Please ensure that the child node of `Popconfirm` accepts `mouseenter`, `mouseleave`, `focus`, `click` events. diff --git a/components/popconfirm/index.jsx b/components/popconfirm/index.jsx index df7e676d5..b52446909 100644 --- a/components/popconfirm/index.jsx +++ b/components/popconfirm/index.jsx @@ -24,6 +24,7 @@ const Popconfirm = { title: PropTypes.any, trigger: tooltipProps.trigger.def('click'), okType: btnProps.type.def('primary'), + disabled: PropTypes.bool.def(false), okText: PropTypes.any, cancelText: PropTypes.any, icon: PropTypes.any, @@ -48,7 +49,8 @@ const Popconfirm = { const state = { sVisible: false }; if ('visible' in props) { state.sVisible = props.visible; - } else if ('defaultVisible' in props) { + } + if ('defaultVisible' in props) { state.sVisible = props.defaultVisible; } return state; @@ -65,6 +67,10 @@ const Popconfirm = { }, onVisibleChange(sVisible) { + const { disabled } = this.$props; + if (disabled) { + return; + } this.setVisible(sVisible); }, diff --git a/components/popconfirm/index.zh-CN.md b/components/popconfirm/index.zh-CN.md deleted file mode 100644 index 8a5119907..000000000 --- a/components/popconfirm/index.zh-CN.md +++ /dev/null @@ -1,23 +0,0 @@ -## API - -| 参数 | 说明 | 类型 | 默认值 | -| ---------- | ------------------------ | ------------ | ---------------------------------------- | -| cancelText | 取消按钮文字 | string\|slot | 取消 | -| okText | 确认按钮文字 | string\|slot | 确定 | -| okType | 确认按钮类型 | string | primary | -| title | 确认框的描述 | string\|slot | 无 | -| icon | 自定义弹出气泡 Icon 图标 | vNode | <Icon type="exclamation-circle" /> | - -### 事件 - -| 事件名称 | 说明 | 回调参数 | -| ------------- | -------------- | ----------------- | -| cancel | 点击取消的回调 | function(e) | -| confirm | 点击确认的回调 | function(e) | -| visibleChange | 显示隐藏的回调 | function(visible) | - -更多属性请参考 [Tooltip](/components/tooltip-cn/#API)。 - -## 注意 - -请确保 `Popconfirm` 的子元素能接受 `mouseenter`、`mouseleave`、`focus`、`click` 事件。 diff --git a/components/popconfirm/style/index.js b/components/popconfirm/style/index.js index c4708ebdd..3a57ddc78 100644 --- a/components/popconfirm/style/index.js +++ b/components/popconfirm/style/index.js @@ -1,5 +1,6 @@ import '../../style/index.less'; // style dependencies +// deps-lint-skip: tooltip, popover import '../../popover/style'; import '../../button/style'; diff --git a/components/popover/__tests__/__snapshots__/demo.test.js.snap b/components/popover/__tests__/__snapshots__/demo.test.js.snap index 86f96ad7f..1faa94eb7 100644 --- a/components/popover/__tests__/__snapshots__/demo.test.js.snap +++ b/components/popover/__tests__/__snapshots__/demo.test.js.snap @@ -1,14 +1,14 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/popover/demo/arrow-point-at-center.md correctly 1`] = `
    `; +exports[`renders ./antdv-demo/popover/demo/arrow-point-at-center.md correctly 1`] = `
    `; -exports[`renders ./components/popover/demo/basic.md correctly 1`] = ``; +exports[`renders ./antdv-demo/popover/demo/basic.md correctly 1`] = ``; -exports[`renders ./components/popover/demo/control.md correctly 1`] = ``; +exports[`renders ./antdv-demo/popover/demo/control.md correctly 1`] = ``; -exports[`renders ./components/popover/demo/hover-with-click.md correctly 1`] = ``; +exports[`renders ./antdv-demo/popover/demo/hover-with-click.md correctly 1`] = ``; -exports[`renders ./components/popover/demo/placement.md correctly 1`] = ` +exports[`renders ./antdv-demo/popover/demo/placement.md correctly 1`] = `
    @@ -17,4 +17,4 @@ exports[`renders ./components/popover/demo/placement.md correctly 1`] = `
    `; -exports[`renders ./components/popover/demo/triggerType.md correctly 1`] = `
    `; +exports[`renders ./antdv-demo/popover/demo/triggerType.md correctly 1`] = `
    `; diff --git a/components/popover/__tests__/index.test.js b/components/popover/__tests__/index.test.js index 8b8d4e649..5bdf80fc5 100644 --- a/components/popover/__tests__/index.test.js +++ b/components/popover/__tests__/index.test.js @@ -1,8 +1,10 @@ import { mount } from '@vue/test-utils'; import { asyncExpect } from '@/tests/utils'; import Popover from '..'; +import mountTest from '../../../tests/shared/mountTest'; describe('Popover', () => { + mountTest(Popover); it('should show overlay when trigger is clicked', async () => { const popover = mount( { diff --git a/components/popover/demo/arrow-point-at-center.md b/components/popover/demo/arrow-point-at-center.md deleted file mode 100644 index 22a6e2814..000000000 --- a/components/popover/demo/arrow-point-at-center.md +++ /dev/null @@ -1,32 +0,0 @@ - -#### 箭头指向 -设置了 `arrowPointAtCenter` 后,箭头将指向目标元素的中心。 - - - -#### Arrow pointing -The arrow points to the center of the target element, which set `arrowPointAtCenter`. - - -```tpl - -``` diff --git a/components/popover/demo/basic.md b/components/popover/demo/basic.md deleted file mode 100644 index 2df2cf743..000000000 --- a/components/popover/demo/basic.md +++ /dev/null @@ -1,21 +0,0 @@ - -#### 基本 -最简单的用法,浮层的大小由内容区域决定。 - - - -#### Basic -The most basic example. The size of the floating layer depends on the contents region. - - -```tpl - -``` diff --git a/components/popover/demo/control.md b/components/popover/demo/control.md deleted file mode 100644 index 752deed6f..000000000 --- a/components/popover/demo/control.md +++ /dev/null @@ -1,34 +0,0 @@ - -#### 从浮层内关闭 -使用 `visible` 属性控制浮层显示。 - - - -#### Controlling the close of the dialog -Use `visible` prop to control the display of the card. - - -```tpl - - - -``` diff --git a/components/popover/demo/hover-with-click.md b/components/popover/demo/hover-with-click.md deleted file mode 100644 index 15c56ba83..000000000 --- a/components/popover/demo/hover-with-click.md +++ /dev/null @@ -1,59 +0,0 @@ - -#### 悬停点击弹出窗口 -以下示例显示如何创建可悬停和单击的弹出窗口。 - - - -#### Hover with click popover -The following example shows how to create a popover which can be hovered and clicked. - - -```tpl - - -``` diff --git a/components/popover/demo/index.vue b/components/popover/demo/index.vue deleted file mode 100644 index 7422fa342..000000000 --- a/components/popover/demo/index.vue +++ /dev/null @@ -1,59 +0,0 @@ - diff --git a/components/popover/demo/placement.md b/components/popover/demo/placement.md deleted file mode 100644 index 90c28285e..000000000 --- a/components/popover/demo/placement.md +++ /dev/null @@ -1,163 +0,0 @@ - -#### 位置 -位置有十二个方向。 - - - -#### Placement -There are 12 `placement` options available. - - -```tpl - - - - -``` diff --git a/components/popover/demo/triggerType.md b/components/popover/demo/triggerType.md deleted file mode 100644 index ca752149b..000000000 --- a/components/popover/demo/triggerType.md +++ /dev/null @@ -1,37 +0,0 @@ - -#### 三种触发方式 -鼠标移入、聚集、点击。 - - - -#### Three ways to trigger -Mouse to click, focus and move in. - - -```tpl - -``` diff --git a/components/popover/index.en-US.md b/components/popover/index.en-US.md deleted file mode 100644 index d165379c4..000000000 --- a/components/popover/index.en-US.md +++ /dev/null @@ -1,12 +0,0 @@ -## API - -| Param | Description | Type | Default value | -| ------- | ------------------- | ------------------- | ------------- | -| content | Content of the card | string\|slot\|vNode | - | -| title | Title of the card | string\|slot\|VNode | - | - -Consult [Tooltip's documentation](/components/tooltip/#API) to find more APIs. - -## Note - -Please ensure that the child node of `Popover` accepts `onMouseenter`, `onMouseleave`, `onFocus`, `onClick` events. diff --git a/components/popover/index.zh-CN.md b/components/popover/index.zh-CN.md deleted file mode 100644 index 0ca9376a1..000000000 --- a/components/popover/index.zh-CN.md +++ /dev/null @@ -1,12 +0,0 @@ -## API - -| 参数 | 说明 | 类型 | 默认值 | -| ------- | -------- | ------------------- | ------ | -| content | 卡片内容 | string\|slot\|VNode | 无 | -| title | 卡片标题 | string\|slot\|VNode | 无 | - -更多属性请参考 [Tooltip](/components/tooltip-cn/#API)。 - -## 注意 - -请确保 `Popover` 的子元素能接受 `mouseenter`、`mouseleave`、`focus`、`click` 事件。 diff --git a/components/popover/style/index.js b/components/popover/style/index.js index 3a3ab0de5..9f2a34a79 100644 --- a/components/popover/style/index.js +++ b/components/popover/style/index.js @@ -1,2 +1,5 @@ import '../../style/index.less'; import './index.less'; + +// style dependencies +// deps-lint-skip: tooltip diff --git a/components/popover/style/index.less b/components/popover/style/index.less index c76e8a7fa..631e0437c 100644 --- a/components/popover/style/index.less +++ b/components/popover/style/index.less @@ -1,10 +1,11 @@ -@import '../../style/themes/default'; +@import '../../style/themes/index'; @import '../../style/mixins/index'; @popover-prefix-cls: ~'@{ant-prefix}-popover'; .@{popover-prefix-cls} { .reset-component; + position: absolute; top: 0; left: 0; @@ -113,8 +114,8 @@ width: sqrt(@popover-arrow-width * @popover-arrow-width * 2); height: sqrt(@popover-arrow-width * @popover-arrow-width * 2); background: transparent; - border-width: sqrt(@popover-arrow-width * @popover-arrow-width * 2) / 2; border-style: solid; + border-width: sqrt(@popover-arrow-width * @popover-arrow-width * 2) / 2; transform: rotate(45deg); } diff --git a/components/progress/__tests__/__snapshots__/demo.test.js.snap b/components/progress/__tests__/__snapshots__/demo.test.js.snap index dad696448..69875f3a6 100644 --- a/components/progress/__tests__/__snapshots__/demo.test.js.snap +++ b/components/progress/__tests__/__snapshots__/demo.test.js.snap @@ -1,50 +1,50 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/progress/demo/circle.md correctly 1`] = ` +exports[`renders ./antdv-demo/progress/demo/circle.md correctly 1`] = `
    + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="#f3f3f3" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-trail" style="stroke: #f3f3f3; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-path" style="stroke: #108ee9; stroke-dasharray: 221.48228207808043px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> 75%
    + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="#f3f3f3" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-trail" style="stroke: #f3f3f3; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-path" style="stroke: #ff5500; stroke-dasharray: 206.7167966062084px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;">
    + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="#f3f3f3" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-trail" style="stroke: #f3f3f3; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-path" style="stroke: #87d068; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;">
    `; -exports[`renders ./components/progress/demo/circle-dynamic.md correctly 1`] = ` +exports[`renders ./antdv-demo/progress/demo/circle-dynamic.md correctly 1`] = `
    + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="#f3f3f3" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-trail" style="stroke: #f3f3f3; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="" stroke-linecap="round" stroke-width="0" fill-opacity="0" class="ant-progress-circle-path" style="stroke: #108ee9; stroke-dasharray: 0px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> 0%
    `; -exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = ` +exports[`renders ./antdv-demo/progress/demo/circle-mini.md correctly 1`] = `
    + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="#f3f3f3" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-trail" style="stroke: #f3f3f3; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-path" style="stroke: #108ee9; stroke-dasharray: 88.59291283123217px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> 30%
    + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="#f3f3f3" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-trail" style="stroke: #f3f3f3; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-path" style="stroke: #ff5500; stroke-dasharray: 206.7167966062084px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;">
    + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="#f3f3f3" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-trail" style="stroke: #f3f3f3; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-path" style="stroke: #87d068; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;">
    `; -exports[`renders ./components/progress/demo/dashboard.md correctly 1`] = ` +exports[`renders ./antdv-demo/progress/demo/dashboard.md correctly 1`] = `
    + a 47,47 0 1 1 0,-94 + a 47,47 0 1 1 0,94" stroke="#f3f3f3" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-trail" style="stroke: #f3f3f3; stroke-dasharray: 220.30970943744057px 295.3097094374406px; stroke-dashoffset: -37.5px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> + a 47,47 0 1 1 0,-94 + a 47,47 0 1 1 0,94" stroke="" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-path" style="stroke: #108ee9; stroke-dasharray: 165.23228207808043px 295.3097094374406px; stroke-dashoffset: -37.5px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> 75%
    `; -exports[`renders ./components/progress/demo/dynamic.md correctly 1`] = ` +exports[`renders ./antdv-demo/progress/demo/dynamic.md correctly 1`] = `
    @@ -126,42 +126,97 @@ exports[`renders ./components/progress/demo/dynamic.md correctly 1`] = `
    `; -exports[`renders ./components/progress/demo/format.md correctly 1`] = ` +exports[`renders ./antdv-demo/progress/demo/format.md correctly 1`] = `
    + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="#f3f3f3" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-trail" style="stroke: #f3f3f3; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-path" style="stroke: #108ee9; stroke-dasharray: 221.48228207808043px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> 75 Days
    + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="#f3f3f3" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-trail" style="stroke: #f3f3f3; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-path" style="stroke: #87d068; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> Done
    + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="#f3f3f3" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-trail" style="stroke: #f3f3f3; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-path" style="stroke: #108ee9; stroke-dasharray: 221.48228207808043px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> 75
    `; -exports[`renders ./components/progress/demo/line.md correctly 1`] = ` +exports[`renders ./antdv-demo/progress/demo/gradient-line.md correctly 1`] = ` +
    +
    +
    +
    +
    +
    +
    +
    99.9% +
    +
    +
    +
    +
    +
    +
    +
    +
    99.9% +
    +
    +
    +
    + + + + + + + + + 90%
    +
    +
    +
    + + + + + + + + +
    +
    +
    +`; + +exports[`renders ./antdv-demo/progress/demo/line.md correctly 1`] = `
    @@ -211,7 +266,7 @@ exports[`renders ./components/progress/demo/line.md correctly 1`] = `
    `; -exports[`renders ./components/progress/demo/line-mini.md correctly 1`] = ` +exports[`renders ./antdv-demo/progress/demo/line-mini.md correctly 1`] = `
    @@ -252,7 +307,7 @@ exports[`renders ./components/progress/demo/line-mini.md correctly 1`] = `
    `; -exports[`renders ./components/progress/demo/linecap.md correctly 1`] = ` +exports[`renders ./antdv-demo/progress/demo/linecap.md correctly 1`] = `
    @@ -266,34 +321,34 @@ exports[`renders ./components/progress/demo/linecap.md correctly 1`] = `
    + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="#f3f3f3" stroke-linecap="square" stroke-width="6" fill-opacity="0" class="ant-progress-circle-trail" style="stroke: #f3f3f3; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="" stroke-linecap="square" stroke-width="6" fill-opacity="0" class="ant-progress-circle-path" style="stroke: #108ee9; stroke-dasharray: 221.48228207808043px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> 75%
    + a 47,47 0 1 1 0,-94 + a 47,47 0 1 1 0,94" stroke="#f3f3f3" stroke-linecap="square" stroke-width="6" fill-opacity="0" class="ant-progress-circle-trail" style="stroke: #f3f3f3; stroke-dasharray: 220.30970943744057px 295.3097094374406px; stroke-dashoffset: -37.5px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> + a 47,47 0 1 1 0,-94 + a 47,47 0 1 1 0,94" stroke="" stroke-linecap="square" stroke-width="6" fill-opacity="0" class="ant-progress-circle-path" style="stroke: #108ee9; stroke-dasharray: 165.23228207808043px 295.3097094374406px; stroke-dashoffset: -37.5px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> 75%
    `; -exports[`renders ./components/progress/demo/segment.md correctly 1`] = ` +exports[`renders ./antdv-demo/progress/demo/segment.md correctly 1`] = `
    -
    +
    60%
    @@ -301,27 +356,27 @@ exports[`renders ./components/progress/demo/segment.md correctly 1`] = `
    + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="#f3f3f3" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-trail" style="stroke: #f3f3f3; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-path" style="stroke: #108ee9; stroke-dasharray: 88.59291283123217px 295.3097094374406px; stroke-dashoffset: -88.59291283123217px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-path" style="stroke: #87d068; stroke-dasharray: 88.59291283123217px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> 60%
    + a 47,47 0 1 1 0,-94 + a 47,47 0 1 1 0,94" stroke="#f3f3f3" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-trail" style="stroke: #f3f3f3; stroke-dasharray: 220.30970943744057px 295.3097094374406px; stroke-dashoffset: -37.5px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> + a 47,47 0 1 1 0,-94 + a 47,47 0 1 1 0,94" stroke="" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-path" style="stroke: #108ee9; stroke-dasharray: 66.09291283123217px 295.3097094374406px; stroke-dashoffset: -103.59291283123217px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> + a 47,47 0 1 1 0,-94 + a 47,47 0 1 1 0,94" stroke="" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-path" style="stroke: #87d068; stroke-dasharray: 66.09291283123217px 295.3097094374406px; stroke-dashoffset: -37.5px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> 60%
    diff --git a/components/progress/__tests__/__snapshots__/index.test.js.snap b/components/progress/__tests__/__snapshots__/index.test.js.snap index a5644a808..4bddd237a 100644 --- a/components/progress/__tests__/__snapshots__/index.test.js.snap +++ b/components/progress/__tests__/__snapshots__/index.test.js.snap @@ -4,11 +4,11 @@ exports[`Progress render format 1`] = `
    + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="#f3f3f3" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-trail" style="stroke: #f3f3f3; stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> + a 47,47 0 1 1 0,94 + a 47,47 0 1 1 0,-94" stroke="" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-path" style="stroke: red; stroke-dasharray: 147.6548547187203px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s;"> 50%
    `; @@ -31,7 +31,7 @@ exports[`Progress render negetive successPercent 1`] = `
    -
    +
    50%
    @@ -44,7 +44,7 @@ exports[`Progress render negetive successPercent 2`] = `
    -
    +
    50 10
    diff --git a/components/progress/circle.jsx b/components/progress/circle.jsx index 581bffe9f..787e14d56 100644 --- a/components/progress/circle.jsx +++ b/components/progress/circle.jsx @@ -44,14 +44,21 @@ const Circle = { const circleWidth = strokeWidth || 6; const gapPos = gapPosition || (type === 'dashboard' && 'bottom') || 'top'; const gapDeg = gapDegree || (type === 'dashboard' && 75); + const strokeColor = getStrokeColor(props); + const isGradient = Object.prototype.toString.call(strokeColor) === '[object Object]'; + + const wrapperClassName = { + [`${prefixCls}-inner`]: true, + [`${prefixCls}-circle-gradient`]: isGradient, + }; return ( -
    +
    -#### 进度圈动态展示 -会动的进度条才是好进度条。 - - - -#### Dynamic circular progress bar -A dynamic progress bar is better. - - -```tpl - - -``` diff --git a/components/progress/demo/circle-mini.md b/components/progress/demo/circle-mini.md deleted file mode 100644 index 496831695..000000000 --- a/components/progress/demo/circle-mini.md +++ /dev/null @@ -1,26 +0,0 @@ - -#### 小型进度圈 -小一号的圈形进度。 - - - -#### Mini size circular progress bar -A smaller circular progress bar. - - -```tpl - - -``` diff --git a/components/progress/demo/circle.md b/components/progress/demo/circle.md deleted file mode 100644 index 875a1a50e..000000000 --- a/components/progress/demo/circle.md +++ /dev/null @@ -1,26 +0,0 @@ - -#### 进度圈 -圈形的进度。 - - - -#### Circular progress bar -A circular progress bar. - - -```tpl - - -``` diff --git a/components/progress/demo/dashboard.md b/components/progress/demo/dashboard.md deleted file mode 100644 index 77ec08be7..000000000 --- a/components/progress/demo/dashboard.md +++ /dev/null @@ -1,17 +0,0 @@ - -#### 仪表盘 -By setting `type=dashboard`, you can get a dashboard style of progress easily. - - - -#### Dashboard -A standard progress bar. - - -```tpl - -``` diff --git a/components/progress/demo/dynamic.md b/components/progress/demo/dynamic.md deleted file mode 100644 index c62421bf7..000000000 --- a/components/progress/demo/dynamic.md +++ /dev/null @@ -1,46 +0,0 @@ - -#### 动态展示 -会动的进度条才是好进度条。 - - - -#### Dynamic -A dynamic progress bar is better. - - -```tpl - - -``` diff --git a/components/progress/demo/format.md b/components/progress/demo/format.md deleted file mode 100644 index 7c016dd67..000000000 --- a/components/progress/demo/format.md +++ /dev/null @@ -1,30 +0,0 @@ - -#### 自定义文字格式 -`format` 属性指定格式。 - - - -#### Custom text format -You can set a custom text by setting the `format` prop. - - -```tpl - - -``` diff --git a/components/progress/demo/index.vue b/components/progress/demo/index.vue deleted file mode 100644 index 6eb52403c..000000000 --- a/components/progress/demo/index.vue +++ /dev/null @@ -1,74 +0,0 @@ - diff --git a/components/progress/demo/line-mini.md b/components/progress/demo/line-mini.md deleted file mode 100644 index 0ba81188f..000000000 --- a/components/progress/demo/line-mini.md +++ /dev/null @@ -1,20 +0,0 @@ - -#### 小型进度条 -适合放在较狭窄的区域内。 - - - -#### Mini size progress bar -Appropriate for a narrow area. - - -```tpl - -``` diff --git a/components/progress/demo/line.md b/components/progress/demo/line.md deleted file mode 100644 index 7f4f572ea..000000000 --- a/components/progress/demo/line.md +++ /dev/null @@ -1,21 +0,0 @@ - -#### 进度条 -标准的进度条。 - - - -#### Progress bar -A standard progress bar. - - -```tpl - -``` diff --git a/components/progress/demo/linecap.md b/components/progress/demo/linecap.md deleted file mode 100644 index 458698531..000000000 --- a/components/progress/demo/linecap.md +++ /dev/null @@ -1,19 +0,0 @@ - -#### 圆角/方角边缘 -`strokeLinecap="square|round"` 可以调整进度条边缘的形状。 - - - -#### Square linecaps -`strokeLinecap="square|round"` 可以调整进度条边缘的形状。 - - -```tpl - -``` diff --git a/components/progress/demo/segment.md b/components/progress/demo/segment.md deleted file mode 100644 index d95ea9dee..000000000 --- a/components/progress/demo/segment.md +++ /dev/null @@ -1,25 +0,0 @@ - -#### 分段进度条 -标准的进度条。 - - - -#### Progress bar with success segment -A standard progress bar. - - -```tpl - -``` diff --git a/components/progress/index.en-US.md b/components/progress/index.en-US.md deleted file mode 100644 index 573299329..000000000 --- a/components/progress/index.en-US.md +++ /dev/null @@ -1,36 +0,0 @@ -## API - -Properties that shared by all types. - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| type | to set the type, options: `line` `circle` `dashboard` | string | `line` | -| format | template function of the content | function(percent, successPercent) \| v-slot:format="percent, successPercent" | `percent => percent + '%'` | -| percent | to set the completion percentage | number | 0 | -| showInfo | whether to display the progress value and the status icon | boolean | true | -| status | to set the status of the Progress, options: `success` `exception` `active` `normal` | string | - | -| strokeLinecap | to set the style of the progress linecap | Enum{ 'round', 'square' } | `round` | -| strokeColor | color of progress bar | string | - | -| successPercent | segmented success percent | number | 0 | - -### `type="line"` - -| Property | Description | Type | Default | -| ----------- | ------------------------------------------------ | ------ | ------- | -| strokeWidth | to set the width of the progress bar, unit: `px` | number | 10 | - -### `type="circle"` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| width | to set the canvas width of the circular progress, unit: `px` | number | 132 | -| strokeWidth | to set the width of the circular progress, unit: percentage of the canvas width | number | 6 | - -### `type="dashboard"` - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| width | to set the canvas width of the dashboard progress, unit: `px` | number | 132 | -| strokeWidth | to set the width of the dashboard progress, unit: percentage of the canvas width | number | 6 | -| gapDegree | the gap degree of half circle, 0 ~ 360 | number | 0 | -| gapPosition | the gap position, options: `top` `bottom` `left` `right` | string | `top` | diff --git a/components/progress/index.zh-CN.md b/components/progress/index.zh-CN.md deleted file mode 100644 index c4d40ad17..000000000 --- a/components/progress/index.zh-CN.md +++ /dev/null @@ -1,36 +0,0 @@ -## API - -各类型共用的属性。 - -| 属性 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| type | 类型,可选 `line` `circle` `dashboard` | string | `line` | -| format | 内容的模板函数 | function(percent, successPercent) \| v-slot:format="percent, successPercent" | `percent => percent + '%'` | -| percent | 百分比 | number | 0 | -| showInfo | 是否显示进度数值或状态图标 | boolean | true | -| status | 状态,可选:`success` `exception` `active` `normal` | string | - | -| strokeLinecap | | Enum{ 'round', 'square' } | `round` | -| strokeColor | 进度条的色彩 | string | - | -| successPercent | 已完成的分段百分比 | number | 0 | - -### `type="line"` - -| 属性 | 说明 | 类型 | 默认值 | -| ----------- | ----------------------- | ------ | ------ | -| strokeWidth | 进度条线的宽度,单位 px | number | 10 | - -### `type="circle"` - -| 属性 | 说明 | 类型 | 默认值 | -| ----------- | ------------------------------------------------ | ------ | ------ | -| width | 圆形进度条画布宽度,单位 px | number | 132 | -| strokeWidth | 圆形进度条线的宽度,单位是进度条画布宽度的百分比 | number | 6 | - -### `type="dashboard"` - -| 属性 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| width | 仪表盘进度条画布宽度,单位 px | number | 132 | -| strokeWidth | 仪表盘进度条线的宽度,单位是进度条画布宽度的百分比 | number | 6 | -| gapDegree | 仪表盘进度条缺口角度,可取值 0 ~ 360 | number | 0 | -| gapPosition | 仪表盘进度条缺口位置 | Enum{ 'top', 'bottom', 'left', 'right' } | `top` | diff --git a/components/progress/line.jsx b/components/progress/line.jsx index 6e201fb7d..84eb16053 100644 --- a/components/progress/line.jsx +++ b/components/progress/line.jsx @@ -1,5 +1,55 @@ import { validProgress } from './utils'; +/** + * { + * '0%': '#afc163', + * '75%': '#009900', + * '50%': 'green', ====> '#afc163 0%, #66FF00 25%, #00CC00 50%, #009900 75%, #ffffff 100%' + * '25%': '#66FF00', + * '100%': '#ffffff' + * } + */ +export const sortGradient = gradients => { + let tempArr = []; + // eslint-disable-next-line no-restricted-syntax + for (const [key, value] of Object.entries(gradients)) { + const formatKey = parseFloat(key.replace(/%/g, '')); + if (isNaN(formatKey)) { + return {}; + } + tempArr.push({ + key: formatKey, + value, + }); + } + tempArr = tempArr.sort((a, b) => a.key - b.key); + return tempArr.map(({ key, value }) => `${value} ${key}%`).join(', '); +}; + +/** + * { + * '0%': '#afc163', + * '25%': '#66FF00', + * '50%': '#00CC00', ====> linear-gradient(to right, #afc163 0%, #66FF00 25%, + * '75%': '#009900', #00CC00 50%, #009900 75%, #ffffff 100%) + * '100%': '#ffffff' + * } + * + * Then this man came to realize the truth: + * Besides six pence, there is the moon. + * Besides bread and butter, there is the bug. + * And... + * Besides women, there is the code. + */ +export const handleGradient = strokeColor => { + const { from = '#1890ff', to = '#1890ff', direction = 'to right', ...rest } = strokeColor; + if (Object.keys(rest).length !== 0) { + const sortedGradients = sortGradient(rest); + return { backgroundImage: `linear-gradient(${direction}, ${sortedGradients})` }; + } + return { backgroundImage: `linear-gradient(${direction}, ${from}, ${to})` }; +}; + const Line = { functional: true, render(h, context) { @@ -13,16 +63,25 @@ const Line = { strokeColor, strokeLinecap, } = props; + let backgroundProps; + if (strokeColor && typeof strokeColor !== 'string') { + backgroundProps = handleGradient(strokeColor); + } else { + backgroundProps = { + background: strokeColor, + }; + } const percentStyle = { width: `${validProgress(percent)}%`, height: `${strokeWidth || (size === 'small' ? 6 : 8)}px`, background: strokeColor, borderRadius: strokeLinecap === 'square' ? 0 : '100px', + ...backgroundProps, }; const successPercentStyle = { width: `${validProgress(successPercent)}%`, height: `${strokeWidth || (size === 'small' ? 6 : 8)}px`, - borderRadius: strokeLinecap === 'square' ? 0 : '100px', + borderRadius: strokeLinecap === 'square' ? 0 : '', }; const successSegment = successPercent !== undefined ? ( diff --git a/components/progress/progress.jsx b/components/progress/progress.jsx index f6aca2f0e..eda3b8a98 100644 --- a/components/progress/progress.jsx +++ b/components/progress/progress.jsx @@ -11,7 +11,7 @@ function addUnit(num, unit) { const unitType = unit || 'px'; return num ? num + unitType : null; } - +const ProgressStatuses = ['normal', 'exception', 'active', 'success']; export const ProgressType = PropTypes.oneOf(['line', 'circle', 'dashboard']); export const ProgressSize = PropTypes.oneOf(['default', 'small']); @@ -21,11 +21,11 @@ export const ProgressProps = { percent: PropTypes.number, successPercent: PropTypes.number, format: PropTypes.func, - status: PropTypes.oneOf(['normal', 'success', 'active', 'exception']), + status: PropTypes.oneOf(ProgressStatuses), showInfo: PropTypes.bool, strokeWidth: PropTypes.number, - strokeLinecap: PropTypes.oneOf(['round', 'square']), - strokeColor: PropTypes.string, + strokeLinecap: PropTypes.oneOf(['butt', 'round', 'square']), + strokeColor: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), trailColor: PropTypes.string, width: PropTypes.number, gapDegree: PropTypes.number, @@ -48,6 +48,21 @@ export default { configProvider: { default: () => ConfigConsumerProps }, }, methods: { + getPercentNumber() { + const { successPercent, percent = 0 } = this.$props; + return parseInt( + successPercent !== undefined ? successPercent.toString() : percent.toString(), + 10, + ); + }, + + getProgressStatus() { + const { status } = this.$props; + if (ProgressStatuses.indexOf(status) < 0 && this.getPercentNumber() >= 100) { + return 'success'; + } + return status || 'normal'; + }, renderProcessInfo(prefixCls, progressStatus) { const { showInfo, format, type, percent, successPercent } = this.$props; if (!showInfo) return null; @@ -96,15 +111,11 @@ export default { } = props; const getPrefixCls = this.configProvider.getPrefixCls; const prefixCls = getPrefixCls('progress', customizePrefixCls); - - const progressStatus = - parseInt(successPercent !== undefined ? successPercent.toString() : percent.toString(), 10) >= - 100 && !('status' in props) - ? 'success' - : status || 'normal'; - let progress; + const progressStatus = this.getProgressStatus(); const progressInfo = this.renderProcessInfo(prefixCls, progressStatus); + let progress; + // Render progress shape if (type === 'line') { const lineProps = { diff --git a/components/progress/style/index.less b/components/progress/style/index.less index 1a5c5364f..185716496 100644 --- a/components/progress/style/index.less +++ b/components/progress/style/index.less @@ -1,10 +1,11 @@ -@import '../../style/themes/default'; +@import '../../style/themes/index'; @import '../../style/mixins/index'; @progress-prefix-cls: ~'@{ant-prefix}-progress'; .@{progress-prefix-cls} { .reset-component; + display: inline-block; &-line { @@ -33,10 +34,10 @@ position: relative; display: inline-block; width: 100%; + overflow: hidden; vertical-align: middle; background-color: @progress-remaining-color; - border-radius: 100px; - overflow: hidden; + border-radius: @progress-radius; } &-circle-trail { @@ -45,13 +46,19 @@ &-circle-path { animation: ~'@{ant-prefix}-progress-appear' 0.3s; - stroke: @progress-default-color; + } + + &-inner:not(.@{ant-prefix}-progress-circle-gradient) { + .@{ant-prefix}-progress-circle-path { + stroke: @progress-default-color; + } } &-success-bg, &-bg { position: relative; background-color: @progress-default-color; + border-radius: @progress-radius; transition: all 0.4s @ease-out-circ 0s; } @@ -100,6 +107,9 @@ .@{progress-prefix-cls}-text { color: @error-color; } + } + + &-status-exception &-inner:not(.@{progress-prefix-cls}-circle-gradient) { .@{progress-prefix-cls}-circle-path { stroke: @error-color; } @@ -112,6 +122,9 @@ .@{progress-prefix-cls}-text { color: @success-color; } + } + + &-status-success &-inner:not(.@{progress-prefix-cls}-circle-gradient) { .@{progress-prefix-cls}-circle-path { stroke: @success-color; } diff --git a/components/progress/utils.js b/components/progress/utils.js index 3252d8eb7..a2dd16ddf 100644 --- a/components/progress/utils.js +++ b/components/progress/utils.js @@ -1,7 +1,8 @@ export function validProgress(progress) { if (!progress || progress < 0) { return 0; - } else if (progress > 100) { + } + if (progress > 100) { return 100; } return progress; diff --git a/components/radio/Group.jsx b/components/radio/Group.jsx index f334af5cb..0f0815ceb 100644 --- a/components/radio/Group.jsx +++ b/components/radio/Group.jsx @@ -104,7 +104,7 @@ export default { if (typeof option === 'string') { return ( ConfigConsumerProps }, }, methods: { - handleChange(event) { - const targetChecked = event.target.checked; - this.$emit('input', targetChecked); - this.$emit('change', event); - }, focus() { this.$refs.vcCheckbox.focus(); }, blur() { this.$refs.vcCheckbox.blur(); }, + handleChange(event) { + const targetChecked = event.target.checked; + this.$emit('input', targetChecked); + this.$emit('change', event); + }, onChange(e) { this.$emit('change', e); if (this.radioGroupContext && this.radioGroupContext.onRadioChange) { diff --git a/components/radio/__tests__/__snapshots__/demo.test.js.snap b/components/radio/__tests__/__snapshots__/demo.test.js.snap index 6de35a496..2485e3770 100644 --- a/components/radio/__tests__/__snapshots__/demo.test.js.snap +++ b/components/radio/__tests__/__snapshots__/demo.test.js.snap @@ -1,14 +1,14 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/radio/demo/basic.md correctly 1`] = ``; +exports[`renders ./antdv-demo/radio/demo/basic.md correctly 1`] = ``; -exports[`renders ./components/radio/demo/disabled.md correctly 1`] = ` +exports[`renders ./antdv-demo/radio/demo/disabled.md correctly 1`] = `

    `; -exports[`renders ./components/radio/demo/radioButton.md correctly 1`] = ` +exports[`renders ./antdv-demo/radio/demo/radioButton.md correctly 1`] = `
    @@ -22,7 +22,7 @@ exports[`renders ./components/radio/demo/radioButton.md correctly 1`] = `
    `; -exports[`renders ./components/radio/demo/radioButton-solid.md correctly 1`] = ` +exports[`renders ./antdv-demo/radio/demo/radioButton-solid.md correctly 1`] = `
    @@ -33,19 +33,19 @@ exports[`renders ./components/radio/demo/radioButton-solid.md correctly 1`] = `
    `; -exports[`renders ./components/radio/demo/radioGroup.md correctly 1`] = ` +exports[`renders ./antdv-demo/radio/demo/radioGroup.md correctly 1`] = `
    `; -exports[`renders ./components/radio/demo/radioGroup-more.md correctly 1`] = ` +exports[`renders ./antdv-demo/radio/demo/radioGroup-more.md correctly 1`] = `
    `; -exports[`renders ./components/radio/demo/radioGroup-options.md correctly 1`] = ` +exports[`renders ./antdv-demo/radio/demo/radioGroup-options.md correctly 1`] = `


    @@ -53,9 +53,9 @@ exports[`renders ./components/radio/demo/radioGroup-options.md correctly 1`] = `
    `; -exports[`renders ./components/radio/demo/radioGroup-with-name.md correctly 1`] = `
    `; +exports[`renders ./antdv-demo/radio/demo/radioGroup-with-name.md correctly 1`] = `
    `; -exports[`renders ./components/radio/demo/size.md correctly 1`] = ` +exports[`renders ./antdv-demo/radio/demo/size.md correctly 1`] = `
    diff --git a/components/radio/__tests__/radio.test.js b/components/radio/__tests__/radio.test.js index 7141c3072..ac7806e89 100644 --- a/components/radio/__tests__/radio.test.js +++ b/components/radio/__tests__/radio.test.js @@ -1,10 +1,14 @@ import { mount } from '@vue/test-utils'; import { asyncExpect } from '@/tests/utils'; -import Radio from '../Radio'; +import Radio, { Group, Button } from '..'; import focusTest from '../../../tests/shared/focusTest'; +import mountTest from '../../../tests/shared/mountTest'; describe('Radio', () => { focusTest(Radio); + mountTest(Radio); + mountTest(Group); + mountTest(Button); it('should render correctly', () => { const wrapper = mount({ diff --git a/components/radio/demo/basic.md b/components/radio/demo/basic.md deleted file mode 100644 index b03fa5076..000000000 --- a/components/radio/demo/basic.md +++ /dev/null @@ -1,15 +0,0 @@ - -#### 基本 -最简单的用法。 - - - -#### Basic -The simplest use. - - -```tpl - -``` diff --git a/components/radio/demo/disabled.md b/components/radio/demo/disabled.md deleted file mode 100644 index 1439ba851..000000000 --- a/components/radio/demo/disabled.md +++ /dev/null @@ -1,38 +0,0 @@ - -#### 不可用 -Radio 不可用。 - - - -#### disabled -Radio unavailable. - - -```tpl - - -``` diff --git a/components/radio/demo/index.vue b/components/radio/demo/index.vue deleted file mode 100644 index 93a63513f..000000000 --- a/components/radio/demo/index.vue +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/components/radio/demo/radioButton-solid.md b/components/radio/demo/radioButton-solid.md deleted file mode 100644 index fc1e9c1cd..000000000 --- a/components/radio/demo/radioButton-solid.md +++ /dev/null @@ -1,32 +0,0 @@ - -#### 填底的按钮样式 -实色填底的单选按钮样式。 - - - -#### Solid radio button -Solid radio button style. - - -```tpl - -``` diff --git a/components/radio/demo/radioButton.md b/components/radio/demo/radioButton.md deleted file mode 100644 index 82f2aa8ec..000000000 --- a/components/radio/demo/radioButton.md +++ /dev/null @@ -1,54 +0,0 @@ - -#### 按钮样式 -按钮样式的单选组合。 - - - -#### radio style -The combination of radio button style. - - -```tpl - - -``` diff --git a/components/radio/demo/radioGroup-more.md b/components/radio/demo/radioGroup-more.md deleted file mode 100644 index 7d091ffc1..000000000 --- a/components/radio/demo/radioGroup-more.md +++ /dev/null @@ -1,42 +0,0 @@ - -#### RadioGroup 垂直 -垂直的 RadioGroup,配合更多输入框选项。 - - - -#### Vertical RadioGroup -Vertical RadioGroup, with more radios. - - -```tpl - - -``` diff --git a/components/radio/demo/radioGroup-options.md b/components/radio/demo/radioGroup-options.md deleted file mode 100644 index ef690f931..000000000 --- a/components/radio/demo/radioGroup-options.md +++ /dev/null @@ -1,57 +0,0 @@ - -#### RadioGroup 组合 - 配置方式 -通过配置 `options` 参数来渲染单选框。 - - - -#### RadioGroup group - optional -Render radios by configuring `options`. - - -```tpl - - -``` diff --git a/components/radio/demo/radioGroup-with-name.md b/components/radio/demo/radioGroup-with-name.md deleted file mode 100644 index 4580ac7c5..000000000 --- a/components/radio/demo/radioGroup-with-name.md +++ /dev/null @@ -1,20 +0,0 @@ - -#### 单选组合 - 配合 name 使用 -可以为 RadioGroup 配置 `name` 参数,为组合内的 input 元素赋予相同的 `name` 属性,使浏览器把 RadioGroup 下的 Radio 真正看作是一组(例如可以通过方向键始终**在同一组内**更改选项)。 - - - -#### RadioGroup with name -Passing the `name` property to all `input[type="radio"]` that are in the same RadioGroup. It is usually used to let the browser see your RadioGroup as a real "group" and keep the default behavior. For example, using left/right keyboard arrow to change your selection that in the same RadioGroup. - - -```tpl - -``` diff --git a/components/radio/demo/radioGroup.md b/components/radio/demo/radioGroup.md deleted file mode 100644 index 303453f3c..000000000 --- a/components/radio/demo/radioGroup.md +++ /dev/null @@ -1,36 +0,0 @@ - -#### 单选组合 -一组互斥的 Radio 配合使用。 - - - -#### Radio Group -A group of radio components. - - -```tpl - - -``` diff --git a/components/radio/demo/size.md b/components/radio/demo/size.md deleted file mode 100644 index 8e1f17346..000000000 --- a/components/radio/demo/size.md +++ /dev/null @@ -1,40 +0,0 @@ - -#### 大小 -大中小三种组合,可以和表单输入框进行对应配合。 - - - -#### size -There are three sizes available: large, medium, and small. It can coordinate with input box. - - -```tpl - -``` diff --git a/components/radio/index.en-US.md b/components/radio/index.en-US.md deleted file mode 100644 index f178ac4f0..000000000 --- a/components/radio/index.en-US.md +++ /dev/null @@ -1,40 +0,0 @@ -## API - -### Radio - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| autoFocus | get focus when component mounted | boolean | false | -| checked | Specifies whether the radio is selected. | boolean | - | -| defaultChecked | Specifies the initial state: whether or not the radio is selected. | boolean | | false | -| disabled | Disable radio | boolean | false | -| value | According to value for comparison, to determine whether the selected | any | - | - -### RadioGroup - -Radio group can wrap a group of `Radio`。 - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| defaultValue | Default selected value | any | - | -| disabled | Disable all radio buttons | boolean | false | -| name | The `name` property of all `input[type="radio"]` children | string | - | -| options | set children optional | string\[] \| Array<{ label: string value: string disabled?: boolean }> | - | -| size | size for radio button style | `large` \| `default` \| `small` | `default` | -| value(v-model) | Used for setting the currently selected value. | any | - | -| buttonStyle | style type of radio button | `outline` \| `solid` | `outline` | - -### RadioGroup Events - -| Events Name | Description | Arguments | -| --- | --- | --- | -| change | The callback function that is triggered when the state changes. | Function(e:Event) | - -## Methods - -### Radio - -| Name | Description | -| ------- | ------------ | -| blur() | remove focus | -| focus() | get focus | diff --git a/components/radio/index.zh-CN.md b/components/radio/index.zh-CN.md deleted file mode 100644 index 32f33fd99..000000000 --- a/components/radio/index.zh-CN.md +++ /dev/null @@ -1,39 +0,0 @@ -## API - -### Radio - -| 参数 | 说明 | 类型 | 默认值 | -| -------------- | --------------------------------- | ------- | ------ | -| autoFocus | 自动获取焦点 | boolean | false | -| checked | 指定当前是否选中 | boolean | false | -| defaultChecked | 初始是否选中 | boolean | false | -| value | 根据 value 进行比较,判断是否选中 | any | - | - -### RadioGroup - -单选框组合,用于包裹一组 `Radio`。 - -| 参数 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| defaultValue | 默认选中的值 | any | - | -| disabled | 禁选所有子单选器 | boolean | false | -| name | RadioGroup 下所有 `input[type="radio"]` 的 `name` 属性 | string | - | -| options | 以配置形式设置子元素 | string\[] \| Array<{ label: string value: string disabled?: boolean }> | - | -| size | 大小,只对按钮样式生效 | `large` \| `default` \| `small` | `default` | -| value(v-model) | 用于设置当前选中的值 | any | - | -| buttonStyle | RadioButton 的风格样式,目前有描边和填色两种风格 | `outline` \| `solid` | `outline` | - -### RadioGroup 事件 - -| 事件名称 | 说明 | 回调参数 | -| -------- | -------------------- | ----------------- | -| change | 选项变化时的回调函数 | Function(e:Event) | - -## 方法 - -### Radio - -| 名称 | 描述 | -| ------- | -------- | -| blur() | 移除焦点 | -| focus() | 获取焦点 | diff --git a/components/radio/style/index.less b/components/radio/style/index.less index 7ba347c2c..e6095051b 100644 --- a/components/radio/style/index.less +++ b/components/radio/style/index.less @@ -1,4 +1,4 @@ -@import '../../style/themes/default'; +@import '../../style/themes/index'; @import '../../style/mixins/index'; @radio-prefix-cls: ~'@{ant-prefix}-radio'; @@ -9,13 +9,14 @@ .@{radio-group-prefix-cls} { .reset-component; + display: inline-block; - line-height: unset; } // 一般状态 .@{radio-prefix-cls}-wrapper { .reset-component; + position: relative; display: inline-block; margin-right: 8px; @@ -25,6 +26,7 @@ .@{radio-prefix-cls} { .reset-component; + position: relative; display: inline-block; line-height: 1; @@ -65,6 +67,7 @@ &-inner { &::after { @radio-dot-size: @radio-size - 8px; + position: absolute; top: (@radio-size - @radio-dot-size) / 2 - 1px; left: (@radio-size - @radio-dot-size) / 2 - 1px; @@ -88,9 +91,9 @@ width: @radio-size; height: @radio-size; background-color: @radio-button-bg; - border-width: 1px; - border-style: solid; border-color: @border-color-base; + border-style: solid; + border-width: 1px; border-radius: 100px; transition: all @radio-duration; } @@ -112,7 +115,7 @@ .@{radio-inner-prefix-cls} { border-color: @radio-dot-color; &::after { - transform: scale(0.875); + transform: scale(1); opacity: 1; transition: all @radio-duration @ease-in-out-circ; } @@ -227,16 +230,18 @@ span.@{radio-prefix-cls} + * { pointer-events: none; } - &-checked { + &-checked:not(&-disabled) { z-index: 1; color: @radio-dot-color; - background: @radio-button-bg; + background: @radio-button-checked-bg; border-color: @radio-dot-color; box-shadow: -1px 0 0 0 @radio-dot-color; + &::before { background-color: @radio-dot-color !important; opacity: 0.1; } + &:first-child { border-color: @radio-dot-color; box-shadow: none !important; diff --git a/components/rate/__tests__/__snapshots__/demo.test.js.snap b/components/rate/__tests__/__snapshots__/demo.test.js.snap index 6ee092615..bf49aaa9c 100644 --- a/components/rate/__tests__/__snapshots__/demo.test.js.snap +++ b/components/rate/__tests__/__snapshots__/demo.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/rate/demo/basic.md correctly 1`] = ` +exports[`renders ./antdv-demo/rate/demo/basic.md correctly 1`] = `
    • @@ -55,7 +55,7 @@ exports[`renders ./components/rate/demo/basic.md correctly 1`] = `
    `; -exports[`renders ./components/rate/demo/character.md correctly 1`] = ` +exports[`renders ./antdv-demo/rate/demo/character.md correctly 1`] = `
    • @@ -176,7 +176,7 @@ exports[`renders ./components/rate/demo/character.md correctly 1`] = `
    `; -exports[`renders ./components/rate/demo/clear.md correctly 1`] = ` +exports[`renders ./antdv-demo/rate/demo/clear.md correctly 1`] = `
    • @@ -229,8 +229,7 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
    -
allowClear: true -
+ allowClear: true
  • @@ -282,12 +281,11 @@ exports[`renders ./components/rate/demo/clear.md correctly 1`] = `
- allowClear: false -
+ allowClear: false `; -exports[`renders ./components/rate/demo/disabled.md correctly 1`] = ` +exports[`renders ./antdv-demo/rate/demo/disabled.md correctly 1`] = `
  • @@ -342,7 +340,7 @@ exports[`renders ./components/rate/demo/disabled.md correctly 1`] = `
`; -exports[`renders ./components/rate/demo/half.md correctly 1`] = ` +exports[`renders ./antdv-demo/rate/demo/half.md correctly 1`] = `
  • @@ -397,4 +395,4 @@ exports[`renders ./components/rate/demo/half.md correctly 1`] = `
`; -exports[`renders ./components/rate/demo/text.md correctly 1`] = `
normal
`; +exports[`renders ./antdv-demo/rate/demo/text.md correctly 1`] = `
normal
`; diff --git a/components/rate/__tests__/index.test.js b/components/rate/__tests__/index.test.js index 36295752f..3944c14c4 100644 --- a/components/rate/__tests__/index.test.js +++ b/components/rate/__tests__/index.test.js @@ -1,6 +1,8 @@ import Rate from '..'; import focusTest from '../../../tests/shared/focusTest'; +import mountTest from '../../../tests/shared/mountTest'; describe('Rate', () => { focusTest(Rate); + mountTest(Rate); }); diff --git a/components/rate/demo/basic.md b/components/rate/demo/basic.md deleted file mode 100644 index 0e606b4f7..000000000 --- a/components/rate/demo/basic.md +++ /dev/null @@ -1,24 +0,0 @@ - -#### 基本 -最简单的用法。 - - - -#### Basic -The simplest usage. - - -```tpl - - -``` diff --git a/components/rate/demo/character.md b/components/rate/demo/character.md deleted file mode 100644 index d58972cb9..000000000 --- a/components/rate/demo/character.md +++ /dev/null @@ -1,24 +0,0 @@ - -#### 其他字符 -可以将星星替换为其他字符,比如字母,数字,字体图标甚至中文。 - - - -#### Other Character -Replace the default star to other character like alphabet, digit, iconfont or even Chinese word. - - -```tpl - -``` diff --git a/components/rate/demo/clear.md b/components/rate/demo/clear.md deleted file mode 100644 index 44a4a24b6..000000000 --- a/components/rate/demo/clear.md +++ /dev/null @@ -1,20 +0,0 @@ - -#### 清除 -支持允许或者禁用清除。 - - - -#### Clear star -Support set allow to clear star when click again. - - -```tpl - -``` diff --git a/components/rate/demo/disabled.md b/components/rate/demo/disabled.md deleted file mode 100644 index 20cd11f83..000000000 --- a/components/rate/demo/disabled.md +++ /dev/null @@ -1,15 +0,0 @@ - -#### 只读 -只读,无法进行鼠标交互。 - - - -#### Read only -Read only, can't use mouse to interact. - - -```tpl - -``` diff --git a/components/rate/demo/half.md b/components/rate/demo/half.md deleted file mode 100644 index ae13172e6..000000000 --- a/components/rate/demo/half.md +++ /dev/null @@ -1,15 +0,0 @@ - -#### 半星 -支持选中半星。 - - - -#### Half star -Support select half star. - - -```tpl - -``` diff --git a/components/rate/demo/index.vue b/components/rate/demo/index.vue deleted file mode 100644 index ce0fdbcae..000000000 --- a/components/rate/demo/index.vue +++ /dev/null @@ -1,65 +0,0 @@ - diff --git a/components/rate/demo/text.md b/components/rate/demo/text.md deleted file mode 100644 index faabaad5b..000000000 --- a/components/rate/demo/text.md +++ /dev/null @@ -1,28 +0,0 @@ - -#### 文案展现 -给评分组件加上文案展示。 - - - -#### Show copywriting -Add copywriting in rate components. - - -```tpl - - -``` diff --git a/components/rate/index.en-US.md b/components/rate/index.en-US.md deleted file mode 100644 index e362a77c2..000000000 --- a/components/rate/index.en-US.md +++ /dev/null @@ -1,30 +0,0 @@ -## API - -| Property | Description | type | Default | -| --- | --- | --- | --- | -| allowClear | whether to allow clear when click again | boolean | true | -| allowHalf | whether to allow semi selection | boolean | false | -| autoFocus | get focus when component mounted | boolean | false | -| character | custom character of rate | String or slot="character" | `` | -| count | star count | number | 5 | -| defaultValue | default value | number | 0 | -| disabled | read only, unable to interact | boolean | false | -| tooltips | Customize tooltip by each character | string\[] | - | -| value(v-model) | current value | number | - | - -### events - -| Events Name | Description | Arguments | -| ----------- | ---------------------------------- | ----------------------- | -| blur | callback when component lose focus | Function() | - | -| change | callback when select value | Function(value: number) | - | -| focus | callback when component get focus | Function() | - | -| hoverChange | callback when hover item | Function(value: number) | - | -| keydown | callback when keydown on component | Function(event) | - | - -## Methods - -| Name | Description | -| ------- | ------------ | -| blur() | remove focus | -| focus() | get focus | diff --git a/components/rate/index.jsx b/components/rate/index.jsx index f92c14239..0188deb51 100644 --- a/components/rate/index.jsx +++ b/components/rate/index.jsx @@ -31,17 +31,17 @@ const Rate = { configProvider: { default: () => ConfigConsumerProps }, }, methods: { + characterRender(node, { index }) { + const { tooltips } = this.$props; + if (!tooltips) return node; + return {node}; + }, focus() { this.$refs.refRate.focus(); }, blur() { this.$refs.refRate.blur(); }, - characterRender(node, { index }) { - const { tooltips } = this.$props; - if (!tooltips) return node; - return {node}; - }, }, render() { const { prefixCls: customizePrefixCls, ...restProps } = getOptionProps(this); diff --git a/components/rate/index.zh-CN.md b/components/rate/index.zh-CN.md deleted file mode 100644 index 55c843a75..000000000 --- a/components/rate/index.zh-CN.md +++ /dev/null @@ -1,30 +0,0 @@ -## API - -| 属性 | 说明 | 类型 | 默认值 | -| -------------- | ---------------------- | -------------------------- | ---------------------- | -| allowClear | 是否允许再次点击后清除 | boolean | true | -| allowHalf | 是否允许半选 | boolean | false | -| autoFocus | 自动获取焦点 | boolean | false | -| character | 自定义字符 | String or slot="character" | `` | -| count | star 总数 | number | 5 | -| defaultValue | 默认值 | number | 0 | -| disabled | 只读,无法进行交互 | boolean | false | -| tooltips | 自定义每项的提示信息 | string\[] | - | -| value(v-model) | 当前数,受控值 | number | - | - -### 事件 - -| 事件名称 | 说明 | 回调参数 | -| ----------- | ------------------------ | ----------------------- | -| blur | 失去焦点时的回调 | Function() | - | -| change | 选择时的回调 | Function(value: number) | - | -| focus | 获取焦点时的回调 | Function() | - | -| hoverChange | 鼠标经过时数值变化的回调 | Function(value: number) | - | -| keydown | 按键回调 | Function(event) | - | - -## 方法 - -| 名称 | 描述 | -| ------- | -------- | -| blur() | 移除焦点 | -| focus() | 获取焦点 | diff --git a/components/rate/style/index.js b/components/rate/style/index.js index 3a3ab0de5..7bd39f61b 100644 --- a/components/rate/style/index.js +++ b/components/rate/style/index.js @@ -1,2 +1,5 @@ import '../../style/index.less'; import './index.less'; + +// style dependencies +import '../../tooltip/style'; diff --git a/components/rate/style/index.less b/components/rate/style/index.less index ef4738246..34214491f 100644 --- a/components/rate/style/index.less +++ b/components/rate/style/index.less @@ -1,10 +1,11 @@ -@import '../../style/themes/default'; +@import '../../style/themes/index'; @import '../../style/mixins/index'; @rate-prefix-cls: ~'@{ant-prefix}-rate'; .@{rate-prefix-cls} { .reset-component; + display: inline-block; margin: 0; padding: 0; @@ -25,12 +26,15 @@ position: relative; display: inline-block; margin: 0; - margin-right: 8px; padding: 0; color: inherit; cursor: pointer; transition: all 0.3s; + &:not(:last-child) { + margin-right: 8px; + } + > div { &:focus { outline: 0; diff --git a/components/result/__tests__/__snapshots__/demo.test.js.snap b/components/result/__tests__/__snapshots__/demo.test.js.snap new file mode 100644 index 000000000..38efe2a01 --- /dev/null +++ b/components/result/__tests__/__snapshots__/demo.test.js.snap @@ -0,0 +1,289 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders ./antdv-demo/result/demo/403.md correctly 1`] = ` +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
403
+
Sorry, you are not authorized to access this page.
+
+
+`; + +exports[`renders ./antdv-demo/result/demo/404.md correctly 1`] = ` +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
404
+
Sorry, the page you visited does not exist.
+
+
+`; + +exports[`renders ./antdv-demo/result/demo/500.md correctly 1`] = ` +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
500
+
Sorry, the server is wrong.
+
+
+`; + +exports[`renders ./antdv-demo/result/demo/customIcon.md correctly 1`] = ` +
+
+
Great, we have done all the operations!
+
+
+`; + +exports[`renders ./antdv-demo/result/demo/error.md correctly 1`] = ` +
+
+
Submission Failed
+
Please check and modify the following information before resubmitting.
+
+
+

The content you submitted has the following error:

+

Your account has been frozen Thaw immediately >

+

Your account is not yet eligible to apply Apply Unlock >

+
+
+
+
+`; + +exports[`renders ./antdv-demo/result/demo/info.md correctly 1`] = ` +
+
+
Your operation has been executed
+
+
+`; + +exports[`renders ./antdv-demo/result/demo/success.md correctly 1`] = ` +
+
+
Successfully Purchased Cloud Server ECS!
+
Order number: 2017182818828182881 Cloud server configuration takes 1-5 minutes, please wait.
+
+
+`; + +exports[`renders ./antdv-demo/result/demo/warning.md correctly 1`] = ` +
+
+
There are some problems with your operation.
+
+
+`; diff --git a/components/result/__tests__/demo.test.js b/components/result/__tests__/demo.test.js new file mode 100644 index 000000000..bb3506ef1 --- /dev/null +++ b/components/result/__tests__/demo.test.js @@ -0,0 +1,3 @@ +import demoTest from '../../../tests/shared/demoTest'; + +demoTest('result'); diff --git a/components/result/__tests__/index.test.js b/components/result/__tests__/index.test.js new file mode 100644 index 000000000..50e085684 --- /dev/null +++ b/components/result/__tests__/index.test.js @@ -0,0 +1,69 @@ +import { mount } from '@vue/test-utils'; +import Result from '../index'; +import Button from '../../button'; + +describe('Result', () => { + it('🙂 successPercent should decide the progress status when it exists', () => { + const wrapper = mount({ + render() { + return ( + + Go Console + + } + /> + ); + }, + }); + expect(wrapper.findAll('.anticon-check-circle')).toHaveLength(1); + }); + + it('🙂 different status, different class', () => { + const wrapper = mount(Result, { propsData: { status: 'warning' } }); + expect(wrapper.findAll('.ant-result-warning')).toHaveLength(1); + + wrapper.setProps({ + status: 'error', + }); + + expect(wrapper.findAll('.ant-result-error')).toHaveLength(1); + + wrapper.setProps({ + status: '500', + }); + + expect(wrapper.findAll('.ant-result-500')).toHaveLength(1); + }); + + it('🙂 When status = 404, the icon is an image', () => { + const wrapper = mount({ + render() { + return ; + }, + }); + expect(wrapper.findAll('.ant-result-404 .ant-result-image')).toHaveLength(1); + }); + + it('🙂 When extra is undefined, the extra dom is undefined', () => { + const wrapper = mount({ + render() { + return ; + }, + }); + expect(wrapper.findAll('.ant-result-extra')).toHaveLength(0); + }); + + it('🙂 result should support className', () => { + const wrapper = mount({ + render() { + return ; + }, + }); + expect(wrapper.findAll('.ant-result.my-result')).toHaveLength(1); + }); +}); diff --git a/components/result/index.jsx b/components/result/index.jsx new file mode 100644 index 000000000..dcf64e5c5 --- /dev/null +++ b/components/result/index.jsx @@ -0,0 +1,91 @@ +import PropTypes from '../_util/vue-types'; +import { getOptionProps, getComponentFromProp } from '../_util/props-util'; +import { ConfigConsumerProps } from '../config-provider'; +import Icon from '../icon'; +import Base from '../base'; +import noFound from './noFound'; +import serverError from './serverError'; +import unauthorized from './unauthorized'; + +export const IconMap = { + success: 'check-circle', + error: 'close-circle', + info: 'exclamation-circle', + warning: 'warning', +}; + +export const ExceptionMap = { + '404': noFound, + '500': serverError, + '403': unauthorized, +}; + +// ExceptionImageMap keys +const ExceptionStatus = Object.keys(ExceptionMap); + +export const ResultProps = { + prefixCls: PropTypes.string, + icon: PropTypes.any, + status: PropTypes.oneOf(['success', 'error', 'info', 'warning', '404', '403', '500']).def('info'), + title: PropTypes.any, + subTitle: PropTypes.any, + extra: PropTypes.any, +}; + +const renderIcon = (h, prefixCls, { status, icon }) => { + if (ExceptionStatus.includes(status)) { + const SVGComponent = ExceptionMap[status]; + return ( +
+ +
+ ); + } + // prop `icon` require slot or VNode + const iconString = IconMap[status]; + const iconNode = icon || ; + return
{iconNode}
; +}; + +const renderExtra = (h, prefixCls, extra) => + extra &&
{extra}
; + +const Result = { + name: 'AResult', + props: ResultProps, + inject: { + configProvider: { default: () => ConfigConsumerProps }, + }, + render(h) { + const { prefixCls: customizePrefixCls, status, ...restProps } = this; + const getPrefixCls = this.configProvider.getPrefixCls; + const prefixCls = getPrefixCls('result', customizePrefixCls); + + const title = getComponentFromProp(this, 'title'); + const subTitle = getComponentFromProp(this, 'subTitle'); + const icon = getComponentFromProp(this, 'icon'); + const extra = getComponentFromProp(this, 'extra'); + + return ( +
+ {renderIcon(h, prefixCls, { status, icon })} +
{title}
+ {subTitle &&
{subTitle}
} + {this.$slots.default &&
{this.$slots.default}
} + {renderExtra(h, prefixCls, extra)} +
+ ); + }, +}; + +/* add resource */ +Result.PRESENTED_IMAGE_403 = ExceptionMap[403]; +Result.PRESENTED_IMAGE_404 = ExceptionMap[404]; +Result.PRESENTED_IMAGE_500 = ExceptionMap[500]; + +/* istanbul ignore next */ +Result.install = function(Vue) { + Vue.use(Base); + Vue.component(Result.name, Result); +}; +export default Result; diff --git a/components/result/noFound.jsx b/components/result/noFound.jsx new file mode 100644 index 000000000..4c7f77a8f --- /dev/null +++ b/components/result/noFound.jsx @@ -0,0 +1,292 @@ +const NoFound = { + functional: true, + render() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); + }, +}; + +export default NoFound; diff --git a/components/result/serverError.jsx b/components/result/serverError.jsx new file mode 100644 index 000000000..986d03372 --- /dev/null +++ b/components/result/serverError.jsx @@ -0,0 +1,334 @@ +const ServerError = { + functional: true, + render() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); + }, +}; + +export default ServerError; diff --git a/components/result/style/index.js b/components/result/style/index.js new file mode 100644 index 000000000..3a3ab0de5 --- /dev/null +++ b/components/result/style/index.js @@ -0,0 +1,2 @@ +import '../../style/index.less'; +import './index.less'; diff --git a/components/result/style/index.less b/components/result/style/index.less new file mode 100644 index 000000000..5ebf40dcf --- /dev/null +++ b/components/result/style/index.less @@ -0,0 +1,71 @@ +@import '../../style/themes/default'; +@import '../../style/mixins/index'; + +@result-prefix-cls: ~'@{ant-prefix}-result'; + +.@{result-prefix-cls} { + padding: 48px 32px; + // status color + &-success &-icon > .anticon { + color: @success-color; + } + + &-error &-icon > .anticon { + color: @error-color; + } + + &-info &-icon > .anticon { + color: @info-color; + } + + &-warning &-icon > .anticon { + color: @warning-color; + } + + // Exception Status image + &-image { + width: 250px; + height: 295px; + margin: auto; + } + + &-icon { + margin-bottom: 24px; + text-align: center; + + > .anticon { + font-size: 72px; + } + } + + &-title { + color: @heading-color; + font-size: 24px; + line-height: 1.8; + text-align: center; + } + + &-subtitle { + color: @text-color-secondary; + font-size: 14px; + line-height: 1.6; + text-align: center; + } + + &-extra { + margin-top: 32px; + text-align: center; + > * { + margin-right: 8px; + &:last-child { + margin-right: 0; + } + } + } + + &-content { + margin-top: 24px; + padding: 24px 40px; + background-color: @background-color-light; + } +} diff --git a/components/result/unauthorized.jsx b/components/result/unauthorized.jsx new file mode 100644 index 000000000..9fd2f4ac5 --- /dev/null +++ b/components/result/unauthorized.jsx @@ -0,0 +1,283 @@ +const Unauthorized = { + functional: true, + render() { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); + }, +}; + +export default Unauthorized; diff --git a/components/row/style/index.js b/components/row/style/index.js index cc2ae69ee..2127e6804 100644 --- a/components/row/style/index.js +++ b/components/row/style/index.js @@ -1,2 +1,5 @@ import '../../style/index.less'; -import '../../grid/style/index.less'; + +// style dependencies +// deps-lint-skip: grid +import '../../grid/style'; diff --git a/components/select/__tests__/__snapshots__/demo.test.js.snap b/components/select/__tests__/__snapshots__/demo.test.js.snap index e25c2b860..824603767 100644 --- a/components/select/__tests__/__snapshots__/demo.test.js.snap +++ b/components/select/__tests__/__snapshots__/demo.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/select/demo/automatic-tokenization.md correctly 1`] = ` +exports[`renders ./antdv-demo/select/demo/automatic-tokenization.md correctly 1`] = `
@@ -14,7 +14,7 @@ exports[`renders ./components/select/demo/automatic-tokenization.md correctly 1`
`; -exports[`renders ./components/select/demo/basic.md correctly 1`] = ` +exports[`renders ./antdv-demo/select/demo/basic.md correctly 1`] = `
@@ -40,7 +40,7 @@ exports[`renders ./components/select/demo/basic.md correctly 1`] = `
`; -exports[`renders ./components/select/demo/coordinate.md correctly 1`] = ` +exports[`renders ./antdv-demo/select/demo/coordinate.md correctly 1`] = `
@@ -59,17 +59,17 @@ exports[`renders ./components/select/demo/coordinate.md correctly 1`] = `
`; -exports[`renders ./components/select/demo/custom-dropdown-menu.md correctly 1`] = ` +exports[`renders ./antdv-demo/select/demo/custom-dropdown-menu.md correctly 1`] = `
-
Lucy
+
lucy
`; -exports[`renders ./components/select/demo/hide-selected.md correctly 1`] = ` +exports[`renders ./antdv-demo/select/demo/hide-selected.md correctly 1`] = `
@@ -84,7 +84,7 @@ exports[`renders ./components/select/demo/hide-selected.md correctly 1`] = `
`; -exports[`renders ./components/select/demo/label-in-value.md correctly 1`] = ` +exports[`renders ./antdv-demo/select/demo/label-in-value.md correctly 1`] = `
@@ -94,7 +94,7 @@ exports[`renders ./components/select/demo/label-in-value.md correctly 1`] = `
`; -exports[`renders ./components/select/demo/multiple.md correctly 1`] = ` +exports[`renders ./antdv-demo/select/demo/multiple.md correctly 1`] = `
@@ -115,7 +115,7 @@ exports[`renders ./components/select/demo/multiple.md correctly 1`] = `
`; -exports[`renders ./components/select/demo/optgroup.md correctly 1`] = ` +exports[`renders ./antdv-demo/select/demo/optgroup.md correctly 1`] = `
@@ -125,7 +125,25 @@ exports[`renders ./components/select/demo/optgroup.md correctly 1`] = `
`; -exports[`renders ./components/select/demo/options.md correctly 1`] = ` +exports[`renders ./antdv-demo/select/demo/option-label-prop.md correctly 1`] = ` +
+
+
+ +
+ + +
+
+
+
+`; + +exports[`renders ./antdv-demo/select/demo/options.md correctly 1`] = `
@@ -135,7 +153,7 @@ exports[`renders ./components/select/demo/options.md correctly 1`] = `
`; -exports[`renders ./components/select/demo/search.md correctly 1`] = ` +exports[`renders ./antdv-demo/select/demo/search.md correctly 1`] = `
@@ -148,7 +166,7 @@ exports[`renders ./components/select/demo/search.md correctly 1`] = `
`; -exports[`renders ./components/select/demo/search-box.md correctly 1`] = ` +exports[`renders ./antdv-demo/select/demo/search-box.md correctly 1`] = `
@@ -161,7 +179,7 @@ exports[`renders ./components/select/demo/search-box.md correctly 1`] = `
`; -exports[`renders ./components/select/demo/select-users.md correctly 1`] = ` +exports[`renders ./antdv-demo/select/demo/select-users.md correctly 1`] = `
@@ -176,7 +194,7 @@ exports[`renders ./components/select/demo/select-users.md correctly 1`] = `
`; -exports[`renders ./components/select/demo/size.md correctly 1`] = ` +exports[`renders ./antdv-demo/select/demo/size.md correctly 1`] = `


@@ -235,7 +253,7 @@ exports[`renders ./components/select/demo/size.md correctly 1`] = `
`; -exports[`renders ./components/select/demo/suffix.md correctly 1`] = ` +exports[`renders ./antdv-demo/select/demo/suffix.md correctly 1`] = `
@@ -254,7 +272,7 @@ exports[`renders ./components/select/demo/suffix.md correctly 1`] = `
`; -exports[`renders ./components/select/demo/tags.md correctly 1`] = ` +exports[`renders ./antdv-demo/select/demo/tags.md correctly 1`] = `
diff --git a/components/select/__tests__/index.test.js b/components/select/__tests__/index.test.js index e15f0c926..19fa6f06a 100644 --- a/components/select/__tests__/index.test.js +++ b/components/select/__tests__/index.test.js @@ -3,9 +3,11 @@ import { asyncExpect } from '@/tests/utils'; import Select from '..'; import Icon from '../../icon'; import focusTest from '../../../tests/shared/focusTest'; +import mountTest from '../../../tests/shared/mountTest'; describe('Select', () => { focusTest(Select); + mountTest(Select); it('should have default notFoundContent', async () => { const wrapper = mount(Select, { diff --git a/components/select/demo/automatic-tokenization.md b/components/select/demo/automatic-tokenization.md deleted file mode 100644 index caa325e1e..000000000 --- a/components/select/demo/automatic-tokenization.md +++ /dev/null @@ -1,28 +0,0 @@ - -#### 自动分词 -试下复制 `露西,杰克` 到输入框里。只在 tags 和 multiple 模式下可用。 - - - -#### Automatic tokenization -Try to copy `Lucy,Jack` to the input. Only available in tags and multiple mode. - - -```tpl - - -``` diff --git a/components/select/demo/basic.md b/components/select/demo/basic.md deleted file mode 100644 index 5fe9bdcdd..000000000 --- a/components/select/demo/basic.md +++ /dev/null @@ -1,37 +0,0 @@ - -#### 基本使用 -基本使用。 - - - -#### Basic Usage -Basic Usage - - -```tpl - - -``` diff --git a/components/select/demo/coordinate.md b/components/select/demo/coordinate.md deleted file mode 100644 index 4327b711c..000000000 --- a/components/select/demo/coordinate.md +++ /dev/null @@ -1,49 +0,0 @@ - -#### 联动 -省市联动是典型的例子。 -推荐使用 [Cascader](/components/cascader-cn/) 组件。 - - - -#### coordinate -Coordinating the selection of provinces and cities is a common use case and demonstrates how selection can be coordinated. -Using the [Cascader](/components/cascader) component is strongly recommended instead as it is more flexible and capable. - - -```tpl - - -``` diff --git a/components/select/demo/custom-dropdown-menu.md b/components/select/demo/custom-dropdown-menu.md deleted file mode 100644 index b1957560f..000000000 --- a/components/select/demo/custom-dropdown-menu.md +++ /dev/null @@ -1,34 +0,0 @@ - -#### 扩展菜单 -使用 `dropdownRender` 对下拉菜单进行自由扩展。 - - - -#### Custom dropdown -Customize the dropdown menu via `dropdownRender`. - - -```tpl - - -``` diff --git a/components/select/demo/hide-selected.md b/components/select/demo/hide-selected.md deleted file mode 100644 index fcda89e45..000000000 --- a/components/select/demo/hide-selected.md +++ /dev/null @@ -1,45 +0,0 @@ - -#### 隐藏已选择选项 -隐藏下拉列表中已选择的选项。 - - - -#### Hide Already Selected -Hide already selected options in the dropdown. - - -```tpl - - -``` diff --git a/components/select/demo/index.vue b/components/select/demo/index.vue deleted file mode 100644 index 03fae3114..000000000 --- a/components/select/demo/index.vue +++ /dev/null @@ -1,71 +0,0 @@ - - -> diff --git a/components/select/demo/label-in-value.md b/components/select/demo/label-in-value.md deleted file mode 100644 index 29c8182e6..000000000 --- a/components/select/demo/label-in-value.md +++ /dev/null @@ -1,34 +0,0 @@ - -#### 获得选项的文本 -默认情况下 `onChange` 里只能拿到 value,如果需要拿到选中的节点文本 label,可以使用 `labelInValue` 属性。 -选中项的 label 会被包装到 value 中传递给 `onChange` 等函数,此时 value 是一个对象。 - - - -#### Get value of selected item -As a default behavior, the onChange callback can only get the value of the selected item. The labelInValue prop can be used to get the label property of the selected item. -The label of the selected item will be packed as an object for passing to the onChange callback. - - -```tpl - - -``` diff --git a/components/select/demo/multiple.md b/components/select/demo/multiple.md deleted file mode 100644 index dcb2f0894..000000000 --- a/components/select/demo/multiple.md +++ /dev/null @@ -1,34 +0,0 @@ - -#### 多选 -多选,从已有条目中选择(scroll the menu) - - - -#### multiple selection -Multiple selection, selecting from existing items (scroll the menu). - - -```tpl - - -``` diff --git a/components/select/demo/optgroup.md b/components/select/demo/optgroup.md deleted file mode 100644 index cf2535318..000000000 --- a/components/select/demo/optgroup.md +++ /dev/null @@ -1,33 +0,0 @@ - -#### 分组 -用 `OptGroup` 进行选项分组。 - - - -#### Option Group -Using `OptGroup` to group the options. - - -```tpl - - -``` diff --git a/components/select/demo/options.md b/components/select/demo/options.md deleted file mode 100644 index 1749730db..000000000 --- a/components/select/demo/options.md +++ /dev/null @@ -1,47 +0,0 @@ - -#### 从数据直接生成 -使用 `options` 把 JSON 数据直接生成选择列表。 - - - -#### Generate form options -The select list can be populated using `options` property. This is a quick and easy way to provide the select content. - - -```tpl - - -``` diff --git a/components/select/demo/search-box.md b/components/select/demo/search-box.md deleted file mode 100644 index 2cc159fbd..000000000 --- a/components/select/demo/search-box.md +++ /dev/null @@ -1,85 +0,0 @@ - -#### 搜索框 -搜索和远程数据结合。 - - - -#### Search Box -Search with remote data. - - -```tpl - - -``` diff --git a/components/select/demo/search.md b/components/select/demo/search.md deleted file mode 100644 index adc2d2bec..000000000 --- a/components/select/demo/search.md +++ /dev/null @@ -1,48 +0,0 @@ - -#### 带搜索框 -展开后可对选项进行搜索。 - - - -#### Select with search field -Search the options while expanded. - - -```tpl - - -``` diff --git a/components/select/demo/select-users.md b/components/select/demo/select-users.md deleted file mode 100644 index 2f65bb742..000000000 --- a/components/select/demo/select-users.md +++ /dev/null @@ -1,75 +0,0 @@ - -#### 搜索用户 -一个带有远程搜索,节流控制,请求时序控制,加载状态的多选示例。 - - - -#### Search and Select Users -A complete multiple select sample with remote search, debounce fetch, ajax callback order flow, and loading state. - - -```tpl - - -``` diff --git a/components/select/demo/size.md b/components/select/demo/size.md deleted file mode 100644 index 66b907fa9..000000000 --- a/components/select/demo/size.md +++ /dev/null @@ -1,71 +0,0 @@ - -#### 三种大小 -三种大小的选择框,当 size 分别为 `large` 和 `small` 时,输入框高度为 `40px` 和 `24px` ,默认高度为 `32px`。 - - - -#### Sizes -The height of the input field for the select defaults to 32px. If size is set to large, the height will be 40px, and if set to small, 24px. - - -```tpl - - -``` diff --git a/components/select/demo/suffix.md b/components/select/demo/suffix.md deleted file mode 100644 index 7173d5d22..000000000 --- a/components/select/demo/suffix.md +++ /dev/null @@ -1,36 +0,0 @@ - -#### 后缀图标 -基本使用。 - - - -#### Suffix -Basic Usage - - -```tpl - - -``` diff --git a/components/select/demo/tags.md b/components/select/demo/tags.md deleted file mode 100644 index 030dec100..000000000 --- a/components/select/demo/tags.md +++ /dev/null @@ -1,28 +0,0 @@ - -#### 标签 -tags select,随意输入的内容(scroll the menu) - - - -#### Tags -Select with tags, transform input to tag (scroll the menu) - - -```tpl - - -``` diff --git a/components/select/index.en-US.md b/components/select/index.en-US.md deleted file mode 100644 index fbd9ab587..000000000 --- a/components/select/index.en-US.md +++ /dev/null @@ -1,87 +0,0 @@ -## API - -```html - - lucy - -``` - -### Select props - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| allowClear | Show clear button. | boolean | false | -| autoClearSearchValue | Whether the current search will be cleared on selecting an item. Only applies when `mode` is set to `multiple` or `tags`. | boolean | true | -| autoFocus | Get focus by default | boolean | false | -| defaultActiveFirstOption | Whether active first option by default | boolean | true | -| defaultValue | Initial selected option. | string\|string\[]
number\|number\[] | - | -| 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\[] | - | -| getPopupContainer | Parent Node which the selector should be rendered to. Default to `body`. When position issues happen, try to modify it into scrollable content and position it relative. | function(triggerNode) | () => document.body | -| labelInValue | whether to embed label in value, turn the format of value from `string` to `{key: string, label: vNodes}` | boolean | false | -| maxTagCount | Max tag count to show | number | - | -| maxTagPlaceholder | Placeholder for not showing tags | slot/function(omittedValues) | - | -| maxTagTextLength | Max text length to show | number | - | -| mode | Set mode of Select | 'default' \| 'multiple' \| 'tags' | 'default' | -| notFoundContent | Specify content to show when no result matches.. | string\|slot | 'Not Found' | -| optionFilterProp | Which prop value of option will be used for filter if filterOption is true | string | value | -| optionLabelProp | Which prop value of option will render as content of select. | string | `value` for `combobox`, `children` for other modes | -| placeholder | Placeholder of select | string\|slot | - | -| 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 | 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 | -| --- | --- | --- | -| blur | Called when blur | function | -| change | Called when select an option or input value change, or value of input is changed in combobox mode | function(value, option:Option/Array<Option>) | -| deselect | Called when a option is deselected, the params are option's value (or key) . only called for multiple or tags, effective in multiple or tags mode only. | function(value, option:Option) | -| focus | Called when focus | function | -| inputKeydown | Called when key pressed | function | -| mouseenter | Called when mouse enter | function | -| mouseleave | Called when mouse leave | function | -| popupScroll | Called when dropdown scrolls | function | -| search | Callback function that is fired when input changed. | function(value: string) | -| select | Called when a option is selected, the params are option's value (or key) and option instance. | function(value, option:Option) | -| dropdownVisibleChange | Call when dropdown open | function(open) | - -### Select Methods - -| Name | Description | -| ------- | ------------ | -| blur() | Remove focus | -| focus() | Get focus | - -### Option props - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| disabled | Disable this option | boolean | false | -| key | Same usage as `value`. If Vue request you to set this property, you can set it to value of option, and then omit value property. | string | | -| title | `title` of Select after select this Option | string | - | -| value | default to filter with this property | string\|number | - | -| class | additional class to option | string | - | - -### OptGroup props - -| Property | Description | Type | Default | -| -------- | ----------- | ------------ | ------- | -| key | | string | - | -| label | Group label | string\|slot | - | diff --git a/components/select/index.jsx b/components/select/index.jsx index 80d492a63..706c9886a 100644 --- a/components/select/index.jsx +++ b/components/select/index.jsx @@ -118,21 +118,13 @@ const Select = { created() { warning( this.$props.mode !== 'combobox', + 'Select', 'The combobox mode of Select is deprecated,' + 'it will be removed in next major version,' + 'please use AutoComplete instead', ); }, methods: { - savePopupRef(ref) { - this.popupRef = ref; - }, - focus() { - this.$refs.vcSelect.focus(); - }, - blur() { - this.$refs.vcSelect.blur(); - }, getNotFoundContent(renderEmpty) { const h = this.$createElement; const notFoundContent = getComponentFromProp(this, 'notFoundContent'); @@ -144,6 +136,16 @@ const Select = { } return renderEmpty(h, 'Select'); }, + savePopupRef(ref) { + this.popupRef = ref; + }, + focus() { + this.$refs.vcSelect.focus(); + }, + blur() { + this.$refs.vcSelect.blur(); + }, + isCombobox() { const { mode } = this; return mode === 'combobox' || mode === SECRET_COMBOBOX_MODE_DO_NOT_USE; @@ -171,6 +173,7 @@ const Select = { mode, options, getPopupContainer, + showArrow, ...restProps } = getOptionProps(this); @@ -198,6 +201,7 @@ const Select = { const cls = { [`${prefixCls}-lg`]: size === 'large', [`${prefixCls}-sm`]: size === 'small', + [`${prefixCls}-show-arrow`]: showArrow, }; let { optionLabelProp } = this.$props; @@ -234,6 +238,7 @@ const Select = { removeIcon: finalRemoveIcon, clearIcon: finalClearIcon, menuItemSelectedIcon: finalMenuItemSelectedIcon, + showArrow, ...rest, ...modeConfig, prefixCls, diff --git a/components/select/index.zh-CN.md b/components/select/index.zh-CN.md deleted file mode 100644 index f1e1a5230..000000000 --- a/components/select/index.zh-CN.md +++ /dev/null @@ -1,88 +0,0 @@ -## API - -```html - - lucy - -``` - -### Select props - -| 参数 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| allowClear | 支持清除 | boolean | false | -| autoClearSearchValue | 是否在选中项后清空搜索框,只在 `mode` 为 `multiple` 或 `tags` 时有效。 | boolean | true | -| autoFocus | 默认获取焦点 | boolean | false | -| defaultActiveFirstOption | 是否默认高亮第一个选项。 | boolean | true | -| defaultValue | 指定默认选中的条目 | string\|string\[]\|number\|number\[] | - | -| 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\[] | - | -| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。 | Function(triggerNode) | () => document.body | -| labelInValue | 是否把每个选项的 label 包装到 value 中,会把 Select 的 value 类型从 `string` 变为 `{key: string, label: vNodes}` 的格式 | boolean | false | -| maxTagCount | 最多显示多少个 tag | number | - | -| maxTagPlaceholder | 隐藏 tag 时显示的内容 | slot/function(omittedValues) | - | -| maxTagTextLength | 最大显示的 tag 文本长度 | number | - | -| mode | 设置 Select 的模式为多选或标签 | 'default' \| 'multiple' \| 'tags' \| 'combobox' | - | -| notFoundContent | 当下拉列表为空时显示的内容 | string\|slot | 'Not Found' | -| optionFilterProp | 搜索时过滤对应的 option 属性,如设置为 children 表示对内嵌内容进行搜索 | string | value | -| optionLabelProp | 回填到选择框的 Option 的属性值,默认是 Option 的子元素。比如在子元素需要高亮效果时,此值可以设为 `value`。 | string | `children` (combobox 模式下为 `value`) | -| placeholder | 选择框默认文字 | string\|slot | - | -| showSearch | 使单选模式可搜索 | boolean | false | -| showArrow | 是否显示下拉小箭头 | boolean | true | -| size | 选择框大小,可选 `large` `small` | string | default | -| 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]}> | \[] | -| defaultOpen | 是否默认展开下拉菜单 | boolean | - | -| open | 是否展开下拉菜单 | boolean | - | - -> 注意,如果发现下拉菜单跟随页面滚动,或者需要在其他弹层中触发 Select,请尝试使用 `getPopupContainer={triggerNode => triggerNode.parentNode}` 将下拉弹层渲染节点固定在触发器的父元素中。 - -### 事件 - -| 事件名称 | 说明 | 回调参数 | -| --- | --- | --- | -| blur | 失去焦点的时回调 | function | -| change | 选中 option,或 input 的 value 变化(combobox 模式下)时,调用此函数 | function(value, option:Option/Array<Option>) | -| deselect | 取消选中时调用,参数为选中项的 value (或 key) 值,仅在 multiple 或 tags 模式下生效 | function(value,option:Option) | -| focus | 获得焦点时回调 | function | -| inputKeydown | 键盘按下时回调 | function | -| mouseenter | 鼠标移入时回调 | function | -| mouseleave | 鼠标移出时回调 | function | -| popupScroll | 下拉列表滚动时的回调 | function | -| search | 文本框值变化时回调 | function(value: string) | -| select | 被选中时调用,参数为选中项的 value (或 key) 值 | function(value, option:Option) | -| dropdownVisibleChange | 展开下拉菜单的回调 | function(open) | - -### Select Methods - -| 名称 | 说明 | -| ------- | -------- | -| blur() | 取消焦点 | -| focus() | 获取焦点 | - -### Option props - -| 参数 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| disabled | 是否禁用 | boolean | false | -| key | 和 value 含义一致。如果 Vue 需要你设置此项,此项值与 value 的值相同,然后可以省略 value 设置 | string | | -| title | 选中该 Option 后,Select 的 title | string | - | -| value | 默认根据此属性值进行筛选 | string\|number | - | -| class | Option 器类名 | string | - | - -### OptGroup props - -| 参数 | 说明 | 类型 | 默认值 | -| ----- | ---- | --------------------------- | ------ | -| key | | string | - | -| label | 组名 | string\|\|function(h)\|slot | 无 | diff --git a/components/select/style/index.js b/components/select/style/index.js index b64c64e2f..a914d0b4b 100644 --- a/components/select/style/index.js +++ b/components/select/style/index.js @@ -3,4 +3,3 @@ import './index.less'; // style dependencies import '../../empty/style'; -import '../../input/style'; diff --git a/components/select/style/index.less b/components/select/style/index.less index 8af34857f..99cf643aa 100644 --- a/components/select/style/index.less +++ b/components/select/style/index.less @@ -1,4 +1,4 @@ -@import '../../style/themes/default'; +@import '../../style/themes/index'; @import '../../style/mixins/index'; @import '../../input/style/mixin'; @@ -34,6 +34,7 @@ .@{select-prefix-cls} { .reset-component; + position: relative; display: inline-block; outline: 0; @@ -53,6 +54,7 @@ // arrow &-arrow { .iconfont-mixin(); + position: absolute; top: 50%; right: @control-padding-horizontal - 1px; @@ -69,10 +71,8 @@ &-selection { display: block; - box-sizing: border-box; - - background-color: @component-background; + background-color: @select-background; border: @border-width-base @border-style-base @select-border-color; // strange align fix for chrome but works // https://gw.alipayobjects.com/zos/rmsportal/VFTfKXJuogBAXcvfAUWJ.gif @@ -103,7 +103,6 @@ &-selected-value { float: left; max-width: 100%; - padding-right: 20px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; @@ -148,6 +147,16 @@ position: relative; height: @input-height-base; cursor: pointer; + + .@{select-prefix-cls}-selection__rendered { + margin-right: 24px; + } + } + + &-no-arrow { + .@{select-prefix-cls}-selection__rendered { + margin-right: @control-padding-horizontal - 1px; + } } &-selection__rendered { @@ -161,8 +170,8 @@ display: inline-block; width: 0; visibility: hidden; - pointer-events: none; content: '.'; + pointer-events: none; } } @@ -182,7 +191,8 @@ line-height: @input-height-lg - 8px; } } - .@{select-prefix-cls}-selection__clear { + .@{select-prefix-cls}-selection__clear, + .@{select-prefix-cls}-arrow { top: @input-height-lg / 2; } } @@ -193,7 +203,7 @@ height: @input-height-sm; } .@{select-prefix-cls}-selection__rendered { - margin: 0 @control-padding-horizontal-sm - 1px; + margin-left: @control-padding-horizontal-sm - 1px; line-height: @input-height-sm - 2px; } .@{select-prefix-cls}-selection--multiple { @@ -204,7 +214,8 @@ line-height: @input-height-sm - 10px; } } - .@{select-prefix-cls}-selection__clear { + .@{select-prefix-cls}-selection__clear, + .@{select-prefix-cls}-arrow { top: @input-height-sm / 2; } } @@ -349,6 +360,7 @@ .@{select-prefix-cls}-selection__choice__remove { .iconfont-mixin(); + position: absolute; right: 4px; display: inline-block; @@ -364,16 +376,14 @@ } } - .@{select-prefix-cls}-selection__clear { + .@{select-prefix-cls}-selection__clear, + .@{select-prefix-cls}-arrow { top: @input-height-base / 2; } } - &-allow-clear &-selection--single &-selection-selected-value { - padding-right: 16px; - } - - &-allow-clear &-selection--multiple &-selection__rendered { + &-allow-clear &-selection--multiple &-selection__rendered, + &-show-arrow &-selection--multiple &-selection__rendered { margin-right: 20px; // In case that clear button will overlap content } @@ -410,13 +420,15 @@ transition: all 0.3s @ease-in-out, height 0s; } } - &-combobox&-allow-clear &-selection:hover &-selection__rendered { + &-combobox&-allow-clear &-selection:hover &-selection__rendered, + &-combobox&-show-arrow &-selection:hover &-selection__rendered { margin-right: 20px; // In case that clear button will overlap content } } .@{select-prefix-cls}-dropdown { .reset-component; + position: absolute; top: -9999px; left: -9999px; @@ -427,8 +439,7 @@ // https://github.com/ant-design/ant-design/issues/11456 // https://github.com/ant-design/ant-design/issues/11843 font-variant: initial; - - background-color: @component-background; + background-color: @select-dropdown-bg; border-radius: @border-radius-base; outline: none; box-shadow: @box-shadow-base; @@ -458,6 +469,7 @@ &-menu { max-height: 250px; margin-bottom: 0; + padding: @select-dropdown-edge-child-vertical-padding 0; //Change padding-left: 0; // Override default ul/ol overflow: auto; list-style: none; @@ -488,26 +500,37 @@ &-item { position: relative; display: block; - padding: 5px @control-padding-horizontal; + padding: @select-dropdown-vertical-padding @control-padding-horizontal; overflow: hidden; color: @text-color; font-weight: normal; - line-height: 22px; + font-size: @select-dropdown-font-size; + line-height: @select-dropdown-line-height; white-space: nowrap; text-overflow: ellipsis; cursor: pointer; transition: background 0.3s ease; - &:hover { + &:hover:not(&-disabled) { background-color: @item-hover-bg; } &:first-child { - border-radius: @border-radius-base @border-radius-base 0 0; + & when (@select-dropdown-edge-child-vertical-padding = 0) { + border-radius: @border-radius-base @border-radius-base 0 0; + } } &:last-child { - border-radius: 0 0 @border-radius-base @border-radius-base; + & when (@select-dropdown-edge-child-vertical-padding = 0) { + border-radius: 0 0 @border-radius-base @border-radius-base; + } + } + + &-selected { + color: @text-color; + font-weight: @select-item-selected-font-weight; + background-color: @select-item-selected-bg; } &-disabled { @@ -516,22 +539,12 @@ &:hover { color: @disabled-color; - background-color: @component-background; cursor: not-allowed; } } - &-selected { - &, - &:hover { - color: @text-color; - font-weight: 600; - background-color: @background-color-light; - } - } - - &-active { - background-color: @item-active-bg; + &-active:not(&-disabled) { + background-color: @select-item-active-bg; } &-divider { @@ -575,6 +588,12 @@ } } + // Patch for popup adjust + // https://github.com/ant-design/ant-design/issues/14422 + &--empty&--multiple &-menu-item { + padding-right: @control-padding-horizontal; + } + &-container-open, &-open { .@{select-prefix-cls}-dropdown { diff --git a/components/skeleton/Avatar.jsx b/components/skeleton/Avatar.jsx index 4fd269726..75f5671c5 100644 --- a/components/skeleton/Avatar.jsx +++ b/components/skeleton/Avatar.jsx @@ -4,7 +4,7 @@ import { initDefaultProps } from '../_util/props-util'; const skeletonAvatarProps = { prefixCls: PropTypes.string, - size: PropTypes.oneOf(['large', 'small', 'default']), + size: PropTypes.oneOfType([PropTypes.oneOf(['large', 'small', 'default']), PropTypes.number]), shape: PropTypes.oneOf(['circle', 'square']), }; @@ -27,7 +27,16 @@ const Avatar = { [`${prefixCls}-square`]: shape === 'square', }); - return ; + const sizeStyle = + typeof size === 'number' + ? { + width: `${size}px`, + height: `${size}px`, + lineHeight: `${size}px`, + } + : {}; + + return ; }, }; diff --git a/components/skeleton/__tests__/__snapshots__/demo.test.js.snap b/components/skeleton/__tests__/__snapshots__/demo.test.js.snap index 52997b8aa..7a39d4afe 100644 --- a/components/skeleton/__tests__/__snapshots__/demo.test.js.snap +++ b/components/skeleton/__tests__/__snapshots__/demo.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/skeleton/demo/active.md correctly 1`] = ` +exports[`renders ./antdv-demo/skeleton/demo/active.md correctly 1`] = `

@@ -13,7 +13,7 @@ exports[`renders ./components/skeleton/demo/active.md correctly 1`] = `
`; -exports[`renders ./components/skeleton/demo/basic.md correctly 1`] = ` +exports[`renders ./antdv-demo/skeleton/demo/basic.md correctly 1`] = `

@@ -26,7 +26,7 @@ exports[`renders ./components/skeleton/demo/basic.md correctly 1`] = `
`; -exports[`renders ./components/skeleton/demo/children.md correctly 1`] = ` +exports[`renders ./antdv-demo/skeleton/demo/children.md correctly 1`] = `

Ant Design Vue, a design language

@@ -39,7 +39,7 @@ exports[`renders ./components/skeleton/demo/children.md correctly 1`] = `
`; -exports[`renders ./components/skeleton/demo/complex.md correctly 1`] = ` +exports[`renders ./antdv-demo/skeleton/demo/complex.md correctly 1`] = `
@@ -54,13 +54,17 @@ exports[`renders ./components/skeleton/demo/complex.md correctly 1`] = `
`; -exports[`renders ./components/skeleton/demo/list.md correctly 1`] = ` +exports[`renders ./antdv-demo/skeleton/demo/list.md correctly 1`] = `
-
-
+
    +
  • + + + +
    @@ -71,10 +75,12 @@ exports[`renders ./components/skeleton/demo/list.md correctly 1`] = `
-
-
-
-
+ +
  • + + + +
    @@ -85,10 +91,12 @@ exports[`renders ./components/skeleton/demo/list.md correctly 1`] = `
    -
  • -
    -
    -
    + +
  • + + + +
    @@ -99,8 +107,8 @@ exports[`renders ./components/skeleton/demo/list.md correctly 1`] = `
    -
  • -
    + +
    diff --git a/components/skeleton/__tests__/__snapshots__/index.test.js.snap b/components/skeleton/__tests__/__snapshots__/index.test.js.snap index df16afe2e..e57b9bae4 100644 --- a/components/skeleton/__tests__/__snapshots__/index.test.js.snap +++ b/components/skeleton/__tests__/__snapshots__/index.test.js.snap @@ -65,6 +65,19 @@ exports[`Skeleton avatar size 3`] = `
    `; +exports[`Skeleton avatar size 4`] = ` +
    +
    +
    +

    +
      +
    • +
    • +
    +
    +
    +`; + exports[`Skeleton paragraph rows 1`] = `
    diff --git a/components/skeleton/__tests__/index.test.js b/components/skeleton/__tests__/index.test.js index 173ae4295..592c0d875 100644 --- a/components/skeleton/__tests__/index.test.js +++ b/components/skeleton/__tests__/index.test.js @@ -1,6 +1,7 @@ import { mount } from '@vue/test-utils'; import { asyncExpect } from '@/tests/utils'; import Skeleton from '..'; +import mountTest from '../../../tests/shared/mountTest'; describe('Skeleton', () => { const genSkeleton = props => { @@ -16,7 +17,7 @@ describe('Skeleton', () => { }; return mount(Skeleton, skeletonProps); }; - + mountTest(Skeleton); describe('avatar', () => { it('size', async () => { const wrapperSmall = genSkeleton({ avatar: { size: 'small' } }); @@ -35,6 +36,12 @@ describe('Skeleton', () => { await asyncExpect(() => { expect(wrapperLarge.html()).toMatchSnapshot(); }); + + const wrapperNumber = genSkeleton({ avatar: { size: 20 } }); + + await asyncExpect(() => { + expect(wrapperNumber.html()).toMatchSnapshot(); + }); }); it('shape', async () => { diff --git a/components/skeleton/demo/active.md b/components/skeleton/demo/active.md deleted file mode 100644 index 73fa94c1f..000000000 --- a/components/skeleton/demo/active.md +++ /dev/null @@ -1,15 +0,0 @@ - -#### 动画效果 -显示动画效果。 - - - -#### Active Animation -Display active animation. - - -```tpl - -``` diff --git a/components/skeleton/demo/basic.md b/components/skeleton/demo/basic.md deleted file mode 100644 index 339eb1b45..000000000 --- a/components/skeleton/demo/basic.md +++ /dev/null @@ -1,15 +0,0 @@ - -#### 基本 -最简单的占位效果。 - - - -#### Basic -Simplest Skeleton usage. - - -```tpl - -``` diff --git a/components/skeleton/demo/children.md b/components/skeleton/demo/children.md deleted file mode 100644 index 506b9dfe7..000000000 --- a/components/skeleton/demo/children.md +++ /dev/null @@ -1,54 +0,0 @@ - -#### 包含子组件 -加载占位图包含子组件。 - - - -#### Contains sub component -Skeleton contains sub component. - - -```tpl - - - -``` diff --git a/components/skeleton/demo/complex.md b/components/skeleton/demo/complex.md deleted file mode 100644 index c04c73f17..000000000 --- a/components/skeleton/demo/complex.md +++ /dev/null @@ -1,15 +0,0 @@ - -#### 复杂的组合 -更复杂的组合。 - - - -#### Complex combination -Complex combination with avatar and multiple paragraphs. - - -```tpl - -``` diff --git a/components/skeleton/demo/index.vue b/components/skeleton/demo/index.vue deleted file mode 100644 index 65c6d185f..000000000 --- a/components/skeleton/demo/index.vue +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/components/skeleton/demo/list.md b/components/skeleton/demo/list.md deleted file mode 100644 index 63e59246b..000000000 --- a/components/skeleton/demo/list.md +++ /dev/null @@ -1,79 +0,0 @@ - -#### 列表 -在列表组件中使用加载占位符。 - - - -#### List -Use skeleton in list component. - - -```tpl - - - -``` diff --git a/components/skeleton/index.en-US.md b/components/skeleton/index.en-US.md deleted file mode 100644 index 9db28782b..000000000 --- a/components/skeleton/index.en-US.md +++ /dev/null @@ -1,31 +0,0 @@ -## API - -### Skeleton - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| active | Show animation effect | boolean | false | -| avatar | Show avatar placeholder | boolean \| [SkeletonAvatarProps](#SkeletonAvatarProps) | false | -| loading | Display the skeleton when `true` | boolean | - | -| paragraph | Show paragraph placeholder | boolean \| [SkeletonParagraphProps](#SkeletonParagraphProps) | true | -| title | Show title placeholder | boolean \| [SkeletonTitleProps](#SkeletonTitleProps) | true | - -### SkeletonAvatarProps - -| Property | Description | Type | Default | -| -------- | ----------------------- | ----------------------------------- | ------- | -| size | Set the size of avatar | Enum{ 'large', 'small', 'default' } | - | -| shape | Set the shape of avatar | Enum{ 'circle', 'square' } | - | - -### SkeletonTitleProps - -| Property | Description | Type | Default | -| -------- | ---------------------- | ---------------- | ------- | -| width | Set the width of title | number \| string | - | - -### SkeletonParagraphProps - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| rows | Set the row count of paragraph | number | - | -| width | Set the width of paragraph. When width is an Array, it can set the width of each row. Otherwise only set the last row width | number \| string \| Array | - | diff --git a/components/skeleton/index.zh-CN.md b/components/skeleton/index.zh-CN.md deleted file mode 100644 index 123d8a4bb..000000000 --- a/components/skeleton/index.zh-CN.md +++ /dev/null @@ -1,31 +0,0 @@ -## API - -### Skeleton - -| 属性 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| active | 是否展示动画效果 | boolean | false | -| avatar | 是否显示头像占位图 | boolean \| [SkeletonAvatarProps](#SkeletonAvatarProps) | false | -| loading | 为 `true` 时,显示占位图。反之则直接展示子组件 | boolean | - | -| paragraph | 是否显示段落占位图 | boolean \| [SkeletonParagraphProps](#SkeletonParagraphProps) | true | -| title | 是否显示标题占位图 | boolean \| [SkeletonTitleProps](#SkeletonTitleProps) | true | - -### SkeletonAvatarProps - -| 属性 | 说明 | 类型 | 默认值 | -| ----- | -------------------- | ----------------------------------- | ------ | -| size | 设置头像占位图的大小 | Enum{ 'large', 'small', 'default' } | - | -| shape | 指定头像的形状 | Enum{ 'circle', 'square' } | - | - -### SkeletonTitleProps - -| 属性 | 说明 | 类型 | 默认值 | -| ----- | -------------------- | ---------------- | ------ | -| width | 设置标题占位图的宽度 | number \| string | - | - -### SkeletonParagraphProps - -| 属性 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| rows | 设置段落占位图的行数 | number | - | -| width | 设置段落占位图的宽度,若为数组时则为对应的每行宽度,反之则是最后一行的宽度 | number \| string \| Array | - | diff --git a/components/skeleton/style/index.less b/components/skeleton/style/index.less index c6a6bfc9d..4b09574a7 100644 --- a/components/skeleton/style/index.less +++ b/components/skeleton/style/index.less @@ -1,4 +1,4 @@ -@import '../../style/themes/default'; +@import '../../style/themes/index'; @import '../../style/mixins/index'; @skeleton-prefix-cls: ~'@{ant-prefix}-skeleton'; @@ -54,6 +54,8 @@ // paragraph .@{skeleton-paragraph-prefix-cls} { + padding: 0; + > li { width: 100%; height: 16px; diff --git a/components/slider/__tests__/__snapshots__/demo.test.js.snap b/components/slider/__tests__/__snapshots__/demo.test.js.snap index 7020d63a7..be5c8a83f 100644 --- a/components/slider/__tests__/__snapshots__/demo.test.js.snap +++ b/components/slider/__tests__/__snapshots__/demo.test.js.snap @@ -1,47 +1,47 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/slider/demo/basic.md correctly 1`] = ` +exports[`renders ./antdv-demo/slider/demo/basic.md correctly 1`] = `
    -
    +
    -
    -
    +
    +
    Disabled:
    `; -exports[`renders ./components/slider/demo/event.md correctly 1`] = ` +exports[`renders ./antdv-demo/slider/demo/event.md correctly 1`] = `
    -
    +
    -
    -
    +
    +
    `; -exports[`renders ./components/slider/demo/icon-slider.md correctly 1`] = ` +exports[`renders ./antdv-demo/slider/demo/icon-slider.md correctly 1`] = `
    @@ -49,14 +49,14 @@ exports[`renders ./components/slider/demo/icon-slider.md correctly 1`] = `
    -
    +
    -
    +
    `; -exports[`renders ./components/slider/demo/input-number.md correctly 1`] = ` +exports[`renders ./antdv-demo/slider/demo/input-number.md correctly 1`] = `
    -
    +
    -
    +
    -
    +
    -
    +
    -
    +
    -
    +
    -
    +
    -
    +
    `; -exports[`renders ./components/slider/demo/mark.md correctly 1`] = ` +exports[`renders ./antdv-demo/slider/demo/mark.md correctly 1`] = `

    included=true

    -
    -
    0°C26°C37°C100°C
    +
    +
    0°C26°C37°C100°C
    -
    -
    -
    0°C26°C37°C100°C
    +
    +
    +
    0°C26°C37°C100°C

    included=false

    -
    -
    0°C26°C37°C100°C
    +
    +
    0°C26°C37°C100°C

    marks & step

    -
    -
    0°C26°C37°C100°C
    +
    +
    0°C26°C37°C100°C

    step=null

    -
    -
    0°C26°C37°C100°C
    +
    +
    0°C26°C37°C100°C
    `; -exports[`renders ./components/slider/demo/show-tooltip.md correctly 1`] = ` +exports[`renders ./antdv-demo/slider/demo/reverse.md correctly 1`] = ` +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + Reversed: +
    +`; + +exports[`renders ./antdv-demo/slider/demo/show-tooltip.md correctly 1`] = `
    -
    +
    `; -exports[`renders ./components/slider/demo/tip-formatter.md correctly 1`] = ` +exports[`renders ./antdv-demo/slider/demo/tip-formatter.md correctly 1`] = `
    -
    +
    -
    +
    `; -exports[`renders ./components/slider/demo/vertical.md correctly 1`] = ` +exports[`renders ./antdv-demo/slider/demo/vertical.md correctly 1`] = `
    -
    +
    -
    +
    -
    +
    -
    -
    +
    +
    -
    +
    -
    -
    +
    +
    0°C26°C37°C100°C
    diff --git a/components/slider/__tests__/__snapshots__/index.test.js.snap b/components/slider/__tests__/__snapshots__/index.test.js.snap index bac9eb631..ffc02983c 100644 --- a/components/slider/__tests__/__snapshots__/index.test.js.snap +++ b/components/slider/__tests__/__snapshots__/index.test.js.snap @@ -2,7 +2,7 @@ exports[`Slider should show tooltip when hovering slider handler 1`] = `
    -
    +
    @@ -13,7 +13,7 @@ exports[`Slider should show tooltip when hovering slider handler 1`] = ` exports[`Slider should show tooltip when hovering slider handler 2`] = `
    - + + Invite 一 Joe Black Delete More actions + + + +
    +
    +
    + +
    +
    `; -exports[`renders ./components/table/demo/bordered.md correctly 1`] = ` +exports[`renders ./antdv-demo/table/demo/bordered.md correctly 1`] = `
    @@ -154,60 +151,54 @@ exports[`renders ./components/table/demo/bordered.md correctly 1`] = ` - -
    Name
    - - -
    Cash Assets
    - - -
    Address
    - - - - - - - John Brown - ¥300,000.00 - New York No. 1 Lake Park - - - - Jim Green - ¥1,256,000.00 - London No. 1 Lake Park - - - - Joe Black - ¥120,000.00 - Sidney No. 1 Lake Park - - - -
    - -
    -
    - +
    Name +
    +
    Cash Assets +
    +
    Address +
    + + + + + John Brown + ¥300,000.00 + New York No. 1 Lake Park + + + Jim Green + ¥1,256,000.00 + London No. 1 Lake Park + + + Joe Black + ¥120,000.00 + Sidney No. 1 Lake Park + + + +
    +
    + +
    +
    +
    `; -exports[`renders ./components/table/demo/colspan-rowspan.md correctly 1`] = ` +exports[`renders ./antdv-demo/table/demo/colspan-rowspan.md correctly 1`] = `
    @@ -225,82 +216,73 @@ exports[`renders ./components/table/demo/colspan-rowspan.md correctly 1`] = ` - -
    Name
    - - -
    Age
    - - -
    Home phone
    - - -
    Address
    - - - - - - - John Brown - 32 - 0571-22098909 - 18889898989 - New York No. 1 Lake Park - - - - Jim Green - 42 - 0571-22098333 - 18889898888 - London No. 1 Lake Park - - - - Joe Black - 32 - 0575-22098909 - 18900010002 - Sidney No. 1 Lake Park - - - - Jim Red - 18 - - 18900010002 - London No. 2 Lake Park - - - - Jake White - - - - - - - -
    -
    -
    -
      -
    • -
    • 1
    • -
    • +
      Name +
      +
      Age +
      +
      Home phone +
      +
      Address +
      + + + + + John Brown + 32 + 0571-22098909 + 18889898989 + New York No. 1 Lake Park + + + Jim Green + 42 + 0571-22098333 + 18889898888 + London No. 1 Lake Park + + + Joe Black + 32 + 0575-22098909 + 18900010002 + Sidney No. 1 Lake Park + + + Jim Red + 18 -
    -
    + 18900010002 + London No. 2 Lake Park + + + Jake White + + + + + + +
    +
    + +
    +
    +
    `; -exports[`renders ./components/table/demo/custom-filter-panel.md correctly 1`] = ` +exports[`renders ./antdv-demo/table/demo/custom-filter-panel.md correctly 1`] = `
    @@ -316,69 +298,62 @@ exports[`renders ./components/table/demo/custom-filter-panel.md correctly 1`] = - -
    Name
    - - -
    Age
    - - -
    Address
    - - - - - - - John Brown - 32 - New York No. 1 Lake Park - - - - Joe Black - 42 - London No. 1 Lake Park - - - - Jim Green - 32 - Sidney No. 1 Lake Park - - - - Jim Red - 32 - London No. 2 Lake Park - - - -
    -
    -
    - +
    Name +
    +
    Age +
    +
    Address +
    + + + + + John Brown + 32 + New York No. 1 Lake Park + + + Joe Black + 42 + London No. 1 Lake Park + + + Jim Green + 32 + Sidney No. 1 Lake Park + + + Jim Red + 32 + London No. 2 Lake Park + + +
    + +
    +
    +
    `; -exports[`renders ./components/table/demo/edit-cell.md correctly 1`] = ` +exports[`renders ./antdv-demo/table/demo/edit-cell.md correctly 1`] = `
    @@ -396,73 +371,67 @@ exports[`renders ./components/table/demo/edit-cell.md correctly 1`] = ` - -
    name
    - - -
    age
    - - -
    address
    - - -
    operation
    - - - - - - - -
    -
    - Edward King 0 -
    -
    - - 32 - London, Park Lane no. 0 - Delete - - - - -
    -
    - Edward King 1 -
    -
    - - 32 - London, Park Lane no. 1 - Delete - - - +
    name +
    +
    age +
    +
    address +
    +
    operation +
    + + + + + +
    +
    + Edward King 0 +
    -
    -
    - -
    + + 32 + London, Park Lane no. 0 + Delete + + + +
    +
    + Edward King 1 +
    +
    + + 32 + London, Park Lane no. 1 + Delete + + +
    + +
    +
    +
    +
    `; -exports[`renders ./components/table/demo/edit-row.md correctly 1`] = ` +exports[`renders ./antdv-demo/table/demo/edit-row.md correctly 1`] = `
    @@ -479,202 +448,266 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = ` - -
    name
    - - -
    age
    - - -
    address
    - - -
    operation
    - - - - - - - -
    Edrward 0
    - - -
    32
    - - -
    London Park no. 0
    - - - - - - - - -
    Edrward 1
    - - -
    32
    - - -
    London Park no. 1
    - - - - - - - - -
    Edrward 2
    - - -
    32
    - - -
    London Park no. 2
    - - - - - - - - -
    Edrward 3
    - - -
    32
    - - -
    London Park no. 3
    - - - - - - - - -
    Edrward 4
    - - -
    32
    - - -
    London Park no. 4
    - - - - - - - - -
    Edrward 5
    - - -
    32
    - - -
    London Park no. 5
    - - - - - - - - -
    Edrward 6
    - - -
    32
    - - -
    London Park no. 6
    - - - - - - - - -
    Edrward 7
    - - -
    32
    - - -
    London Park no. 7
    - - - - - - - - -
    Edrward 8
    - - -
    32
    - - -
    London Park no. 8
    - - - - - - - - -
    Edrward 9
    - - -
    32
    - - -
    London Park no. 9
    - - - - - - - -
    -
    -
    - -
    +
    name +
    +
    age +
    +
    address +
    +
    operation +
    + + + + + +
    Edrward 0
    + + +
    32
    + + +
    London Park no. 0
    + + + + + + + +
    Edrward 1
    + + +
    32
    + + +
    London Park no. 1
    + + + + + + + +
    Edrward 2
    + + +
    32
    + + +
    London Park no. 2
    + + + + + + + +
    Edrward 3
    + + +
    32
    + + +
    London Park no. 3
    + + + + + + + +
    Edrward 4
    + + +
    32
    + + +
    London Park no. 4
    + + + + + + + +
    Edrward 5
    + + +
    32
    + + +
    London Park no. 5
    + + + + + + + +
    Edrward 6
    + + +
    32
    + + +
    London Park no. 6
    + + + + + + + +
    Edrward 7
    + + +
    32
    + + +
    London Park no. 7
    + + + + + + + +
    Edrward 8
    + + +
    32
    + + +
    London Park no. 8
    + + + + + + + +
    Edrward 9
    + + +
    32
    + + +
    London Park no. 9
    + + + + + + +
    +
    + +
    +
    +
    `; -exports[`renders ./components/table/demo/expand.md correctly 1`] = ` +exports[`renders ./antdv-demo/table/demo/ellipsis.md correctly 1`] = ` +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Name +
    Age +
    Address +
    Long Column Long Column Long Column +
    Long Column Long Column +
    Long Column +
    John Brown32New York No. 1 Lake Park, New York No. 1 Lake ParkNew York No. 1 Lake Park, New York No. 1 Lake ParkNew York No. 1 Lake Park, New York No. 1 Lake ParkNew York No. 1 Lake Park, New York No. 1 Lake Park
    Jim Green42London No. 2 Lake Park, London No. 2 Lake ParkLondon No. 2 Lake Park, London No. 2 Lake ParkLondon No. 2 Lake Park, London No. 2 Lake ParkLondon No. 2 Lake Park, London No. 2 Lake Park
    Joe Black32Sidney No. 1 Lake Park, Sidney No. 1 Lake ParkSidney No. 1 Lake Park, Sidney No. 1 Lake ParkSidney No. 1 Lake Park, Sidney No. 1 Lake ParkSidney No. 1 Lake Park, Sidney No. 1 Lake Park
    +
    +
    +
    + +
    +
    +
    +`; + +exports[`renders ./antdv-demo/table/demo/expand.md correctly 1`] = `
    @@ -693,66 +726,68 @@ exports[`renders ./components/table/demo/expand.md correctly 1`] = ` - -
    Name
    - - -
    Age
    - - -
    Address
    - - -
    Action
    - - - - - - - John Brown - 32 - New York No. 1 Lake Park - Delete - - - - - Jim Green - 42 - London No. 1 Lake Park - Delete - - - - - Joe Black - 32 - Sidney No. 1 Lake Park - Delete - - - - -
    -
    -
    - -
    +
    Name +
    +
    Age +
    +
    Address +
    +
    Action +
    + + + + + +
    + + John Brown + 32 + New York No. 1 Lake Park + Delete + + + + +
    + + Jim Green + 42 + London No. 1 Lake Park + Delete + + + + +
    + + Joe Black + 32 + Sidney No. 1 Lake Park + Delete + + + +
    +
    + +
    + + `; -exports[`renders ./components/table/demo/expand-children.md correctly 1`] = ` +exports[`renders ./antdv-demo/table/demo/expand-children.md correctly 1`] = `
    @@ -762,78 +797,74 @@ exports[`renders ./components/table/demo/expand-children.md correctly 1`] = `
    - + - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    Name
    -
    -
    Age
    -
    -
    Address
    -
    John Brown sr.60New York No. 1 Lake Park
    Joe Black32Sidney No. 1 Lake Park
    -
    -
    -
    - -
    - +
    +
    +
    +
    Name +
    +
    Age +
    +
    Address +
    + + + + + + +
    John Brown sr. + 60 + New York No. 1 Lake Park + + + + + + + + + + + Joe Black + 32 + Sidney No. 1 Lake Park + + + + + + + + + `; -exports[`renders ./components/table/demo/fixed-columns.md correctly 1`] = ` +exports[`renders ./antdv-demo/table/demo/fixed-columns.md correctly 1`] = `
    -
    +
    -
    +
    @@ -850,158 +881,136 @@ exports[`renders ./components/table/demo/fixed-columns.md correctly 1`] = ` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    Full Name
    -
    -
    Age
    -
    -
    Column 1
    -
    -
    Column 2
    -
    -
    Column 3
    -
    -
    Column 4
    -
    -
    Column 5
    -
    -
    Column 6
    -
    -
    Column 7
    -
    -
    Column 8
    -
    -
    Action
    -
    - John Brown32New York ParkNew York ParkNew York ParkNew York ParkNew York ParkNew York ParkNew York ParkNew York Parkaction
    - Jim Green40London ParkLondon ParkLondon ParkLondon ParkLondon ParkLondon ParkLondon ParkLondon Parkaction
    -
    -
    -
    - -
    -
    - - - - - - - - - - - - - - - - - - - - - -
    -
    Full Name
    -
    -
    Age
    -
    - John Brown32
    - Jim Green40
    -
    -
    -
    -
    - -
    -
    - - - - - - - - - - - - - - - - - -
    -
    Action
    -
    action
    action
    -
    -
    -
    -
    -
    - -
    +
    Full Name +
    +
    Age +
    +
    Column 1 +
    +
    Column 2 +
    +
    Column 3 +
    +
    Column 4 +
    +
    Column 5 +
    +
    Column 6
    +
    Column 7
    +
    Column 8
    +
    Action
    + + + + + John Brown + 32 + New York Park + New York Park + New York Park + New York Park + New York Park + New York Park + New York Park + New York Park + action + + + Jim Green + 40 + London Park + London Park + London Park + London Park + London Park + London Park + London Park + London Park + action + + + +
    +
    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Full Name +
    Age +
    John Brown32
    Jim Green40
    +
    +
    +
    +
    + +
    +
    + + + + + + + + + + + + + + + + + +
    Action +
    action
    action
    +
    +
    +
    + + + + `; -exports[`renders ./components/table/demo/fixed-columns-header.md correctly 1`] = ` +exports[`renders ./antdv-demo/table/demo/fixed-columns-header.md correctly 1`] = `
    -
    +
    @@ -1021,374 +1030,336 @@ exports[`renders ./components/table/demo/fixed-columns-header.md correctly 1`] = - -
    Full Name
    - - -
    Age
    - - -
    Column 1
    - - -
    Column 2
    - - -
    Column 3
    - - -
    Column 4
    - - -
    Column 5
    - - -
    Column 6
    - - -
    Column 7
    - - -
    Column 8
    - - -
    Action
    - - - - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Edrward 032London Park no. 0London Park no. 0London Park no. 0London Park no. 0London Park no. 0London Park no. 0London Park no. 0London Park no. 0action
    - Edrward 132London Park no. 1London Park no. 1London Park no. 1London Park no. 1London Park no. 1London Park no. 1London Park no. 1London Park no. 1action
    - Edrward 232London Park no. 2London Park no. 2London Park no. 2London Park no. 2London Park no. 2London Park no. 2London Park no. 2London Park no. 2action
    - Edrward 332London Park no. 3London Park no. 3London Park no. 3London Park no. 3London Park no. 3London Park no. 3London Park no. 3London Park no. 3action
    - Edrward 432London Park no. 4London Park no. 4London Park no. 4London Park no. 4London Park no. 4London Park no. 4London Park no. 4London Park no. 4action
    - Edrward 532London Park no. 5London Park no. 5London Park no. 5London Park no. 5London Park no. 5London Park no. 5London Park no. 5London Park no. 5action
    - Edrward 632London Park no. 6London Park no. 6London Park no. 6London Park no. 6London Park no. 6London Park no. 6London Park no. 6London Park no. 6action
    - Edrward 732London Park no. 7London Park no. 7London Park no. 7London Park no. 7London Park no. 7London Park no. 7London Park no. 7London Park no. 7action
    - Edrward 832London Park no. 8London Park no. 8London Park no. 8London Park no. 8London Park no. 8London Park no. 8London Park no. 8London Park no. 8action
    - Edrward 932London Park no. 9London Park no. 9London Park no. 9London Park no. 9London Park no. 9London Park no. 9London Park no. 9London Park no. 9action
    -
    -
    -
    -
    - - - - - - - - - - - -
    -
    Full Name
    -
    -
    Age
    -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Edrward 032
    - Edrward 132
    - Edrward 232
    - Edrward 332
    - Edrward 432
    - Edrward 532
    - Edrward 632
    - Edrward 732
    - Edrward 832
    - Edrward 932
    -
    -
    -
    -
    -
    - - - - - - - - - -
    -
    Action
    -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    action
    action
    action
    action
    action
    action
    action
    action
    action
    action
    -
    -
    -
    -
    -
    - -
    +
    Full Name +
    +
    Age +
    +
    Column 1 +
    +
    Column 2 +
    +
    Column 3 +
    +
    Column 4 +
    +
    Column 5 +
    +
    Column 6
    +
    Column 7
    +
    Column 8
    +
    Action
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Edrward 032London Park no. 0London Park no. 0London Park no. 0London Park no. 0London Park no. 0London Park no. 0London Park no. 0London Park no. 0action
    Edrward 132London Park no. 1London Park no. 1London Park no. 1London Park no. 1London Park no. 1London Park no. 1London Park no. 1London Park no. 1action
    Edrward 232London Park no. 2London Park no. 2London Park no. 2London Park no. 2London Park no. 2London Park no. 2London Park no. 2London Park no. 2action
    Edrward 332London Park no. 3London Park no. 3London Park no. 3London Park no. 3London Park no. 3London Park no. 3London Park no. 3London Park no. 3action
    Edrward 432London Park no. 4London Park no. 4London Park no. 4London Park no. 4London Park no. 4London Park no. 4London Park no. 4London Park no. 4action
    Edrward 532London Park no. 5London Park no. 5London Park no. 5London Park no. 5London Park no. 5London Park no. 5London Park no. 5London Park no. 5action
    Edrward 632London Park no. 6London Park no. 6London Park no. 6London Park no. 6London Park no. 6London Park no. 6London Park no. 6London Park no. 6action
    Edrward 732London Park no. 7London Park no. 7London Park no. 7London Park no. 7London Park no. 7London Park no. 7London Park no. 7London Park no. 7action
    Edrward 832London Park no. 8London Park no. 8London Park no. 8London Park no. 8London Park no. 8London Park no. 8London Park no. 8London Park no. 8action
    Edrward 932London Park no. 9London Park no. 9London Park no. 9London Park no. 9London Park no. 9London Park no. 9London Park no. 9London Park no. 9action
    +
    +
    +
    +
    + + + + + + + + + + + +
    Full Name +
    Age +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Edrward 032
    Edrward 132
    Edrward 232
    Edrward 332
    Edrward 432
    Edrward 532
    Edrward 632
    Edrward 732
    Edrward 832
    Edrward 932
    +
    +
    +
    + + + + + + + + + +
    Action +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    action
    action
    action
    action
    action
    action
    action
    action
    action
    action
    +
    +
    +
    +
    + + + + + `; -exports[`renders ./components/table/demo/fixed-header.md correctly 1`] = ` +exports[`renders ./antdv-demo/table/demo/fixed-header.md correctly 1`] = `
    -
    +
    @@ -1400,704 +1371,607 @@ exports[`renders ./components/table/demo/fixed-header.md correctly 1`] = ` - -
    Name
    - - -
    Age
    - - -
    Address
    - - - - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - Edward King 032London, Park Lane no. 0
    - Edward King 132London, Park Lane no. 1
    - Edward King 232London, Park Lane no. 2
    - Edward King 332London, Park Lane no. 3
    - Edward King 432London, Park Lane no. 4
    - Edward King 532London, Park Lane no. 5
    - Edward King 632London, Park Lane no. 6
    - Edward King 732London, Park Lane no. 7
    - Edward King 832London, Park Lane no. 8
    - Edward King 932London, Park Lane no. 9
    - Edward King 1032London, Park Lane no. 10
    - Edward King 1132London, Park Lane no. 11
    - Edward King 1232London, Park Lane no. 12
    - Edward King 1332London, Park Lane no. 13
    - Edward King 1432London, Park Lane no. 14
    - Edward King 1532London, Park Lane no. 15
    - Edward King 1632London, Park Lane no. 16
    - Edward King 1732London, Park Lane no. 17
    - Edward King 1832London, Park Lane no. 18
    - Edward King 1932London, Park Lane no. 19
    - Edward King 2032London, Park Lane no. 20
    - Edward King 2132London, Park Lane no. 21
    - Edward King 2232London, Park Lane no. 22
    - Edward King 2332London, Park Lane no. 23
    - Edward King 2432London, Park Lane no. 24
    - Edward King 2532London, Park Lane no. 25
    - Edward King 2632London, Park Lane no. 26
    - Edward King 2732London, Park Lane no. 27
    - Edward King 2832London, Park Lane no. 28
    - Edward King 2932London, Park Lane no. 29
    - Edward King 3032London, Park Lane no. 30
    - Edward King 3132London, Park Lane no. 31
    - Edward King 3232London, Park Lane no. 32
    - Edward King 3332London, Park Lane no. 33
    - Edward King 3432London, Park Lane no. 34
    - Edward King 3532London, Park Lane no. 35
    - Edward King 3632London, Park Lane no. 36
    - Edward King 3732London, Park Lane no. 37
    - Edward King 3832London, Park Lane no. 38
    - Edward King 3932London, Park Lane no. 39
    - Edward King 4032London, Park Lane no. 40
    - Edward King 4132London, Park Lane no. 41
    - Edward King 4232London, Park Lane no. 42
    - Edward King 4332London, Park Lane no. 43
    - Edward King 4432London, Park Lane no. 44
    - Edward King 4532London, Park Lane no. 45
    - Edward King 4632London, Park Lane no. 46
    - Edward King 4732London, Park Lane no. 47
    - Edward King 4832London, Park Lane no. 48
    - Edward King 4932London, Park Lane no. 49
    -
    -
    -
    +
    Name +
    +
    Age +
    +
    Address +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Edward King 032London, Park Lane no. 0
    Edward King 132London, Park Lane no. 1
    Edward King 232London, Park Lane no. 2
    Edward King 332London, Park Lane no. 3
    Edward King 432London, Park Lane no. 4
    Edward King 532London, Park Lane no. 5
    Edward King 632London, Park Lane no. 6
    Edward King 732London, Park Lane no. 7
    Edward King 832London, Park Lane no. 8
    Edward King 932London, Park Lane no. 9
    Edward King 1032London, Park Lane no. 10
    Edward King 1132London, Park Lane no. 11
    Edward King 1232London, Park Lane no. 12
    Edward King 1332London, Park Lane no. 13
    Edward King 1432London, Park Lane no. 14
    Edward King 1532London, Park Lane no. 15
    Edward King 1632London, Park Lane no. 16
    Edward King 1732London, Park Lane no. 17
    Edward King 1832London, Park Lane no. 18
    Edward King 1932London, Park Lane no. 19
    Edward King 2032London, Park Lane no. 20
    Edward King 2132London, Park Lane no. 21
    Edward King 2232London, Park Lane no. 22
    Edward King 2332London, Park Lane no. 23
    Edward King 2432London, Park Lane no. 24
    Edward King 2532London, Park Lane no. 25
    Edward King 2632London, Park Lane no. 26
    Edward King 2732London, Park Lane no. 27
    Edward King 2832London, Park Lane no. 28
    Edward King 2932London, Park Lane no. 29
    Edward King 3032London, Park Lane no. 30
    Edward King 3132London, Park Lane no. 31
    Edward King 3232London, Park Lane no. 32
    Edward King 3332London, Park Lane no. 33
    Edward King 3432London, Park Lane no. 34
    Edward King 3532London, Park Lane no. 35
    Edward King 3632London, Park Lane no. 36
    Edward King 3732London, Park Lane no. 37
    Edward King 3832London, Park Lane no. 38
    Edward King 3932London, Park Lane no. 39
    Edward King 4032London, Park Lane no. 40
    Edward King 4132London, Park Lane no. 41
    Edward King 4232London, Park Lane no. 42
    Edward King 4332London, Park Lane no. 43
    Edward King 4432London, Park Lane no. 44
    Edward King 4532London, Park Lane no. 45
    Edward King 4632London, Park Lane no. 46
    Edward King 4732London, Park Lane no. 47
    Edward King 4832London, Park Lane no. 48
    Edward King 4932London, Park Lane no. 49
    -
    + +
    + + `; -exports[`renders ./components/table/demo/grouping-columns.md correctly 1`] = ` +exports[`renders ./antdv-demo/table/demo/grouping-columns.md correctly 1`] = `
    -
    +
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    Name
    -
    -
    Other
    -
    -
    Company
    -
    -
    Gender
    -
    -
    Age
    -
    -
    -
    Address
    -
    -
    Company Address
    -
    -
    Company Name
    -
    -
    Street
    -
    -
    Block
    -
    -
    Building
    -
    -
    Door No.
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - John Brown1Lake ParkC2035Lake Street 42SoftLake CoM
    - John Brown2Lake ParkC2035Lake Street 42SoftLake CoM
    - John Brown3Lake ParkC2035Lake Street 42SoftLake CoM
    - John Brown4Lake ParkC2035Lake Street 42SoftLake CoM
    - John Brown5Lake ParkC2035Lake Street 42SoftLake CoM
    - John Brown6Lake ParkC2035Lake Street 42SoftLake CoM
    - John Brown7Lake ParkC2035Lake Street 42SoftLake CoM
    - John Brown8Lake ParkC2035Lake Street 42SoftLake CoM
    - John Brown9Lake ParkC2035Lake Street 42SoftLake CoM
    - John Brown10Lake ParkC2035Lake Street 42SoftLake CoM
    -
    -
    -
    - - - - - - -
    -
    Name
    -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - John Brown
    - John Brown
    - John Brown
    - John Brown
    - John Brown
    - John Brown
    - John Brown
    - John Brown
    - John Brown
    - John Brown
    -
    -
    -
    -
    -
    - - + + + + + + - - - -
    -
    Gender
    -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    M
    M
    M
    M
    M
    M
    M
    M
    M
    M
    -
    -
    -
    -
    -
    - -
    +
    Name +
    +
    Other +
    +
    Company +
    +
    Gender +
    + + +
    Age
    +
    +
    Address +
    +
    Company Address +
    +
    Company Name
    + + +
    Street
    +
    Block
    + + +
    Building
    +
    Door No.
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    John Brown1Lake ParkC2035Lake Street 42SoftLake CoM
    John Brown2Lake ParkC2035Lake Street 42SoftLake CoM
    John Brown3Lake ParkC2035Lake Street 42SoftLake CoM
    John Brown4Lake ParkC2035Lake Street 42SoftLake CoM
    John Brown5Lake ParkC2035Lake Street 42SoftLake CoM
    John Brown6Lake ParkC2035Lake Street 42SoftLake CoM
    John Brown7Lake ParkC2035Lake Street 42SoftLake CoM
    John Brown8Lake ParkC2035Lake Street 42SoftLake CoM
    John Brown9Lake ParkC2035Lake Street 42SoftLake CoM
    John Brown10Lake ParkC2035Lake Street 42SoftLake CoM
    +
    +
    +
    +
    + + + + + + + + + +
    Name +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    John Brown
    John Brown
    John Brown
    John Brown
    John Brown
    John Brown
    John Brown
    John Brown
    John Brown
    John Brown
    +
    +
    +
    + + + + + + + + + +
    Gender +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    M
    M
    M
    M
    M
    M
    M
    M
    M
    M
    +
    +
    +
    +
    + + + + + `; -exports[`renders ./components/table/demo/head.md correctly 1`] = ` +exports[`renders ./antdv-demo/table/demo/head.md correctly 1`] = `
    @@ -2113,80 +1987,60 @@ exports[`renders ./components/table/demo/head.md correctly 1`] = ` - -
    Name
    -
    - - -
    Age
    -
    - - -
    Address
    -
    - - - - - - - John Brown - 32 - New York No. 1 Lake Park - - - - Jim Green - 42 - London No. 1 Lake Park - - - - Joe Black - 32 - Sidney No. 1 Lake Park - - - - Jim Red - 32 - London No. 2 Lake Park - - - -
    -
    -
    - +
    Name
    +
    +
    Age
    +
    +
    Address
    +
    + + + + + Jim Green + 42 + London No. 1 Lake Park + + + John Brown + 32 + New York No. 1 Lake Park + + + Joe Black + 32 + Sidney No. 1 Lake Park + + + Jim Red + 32 + London No. 2 Lake Park + + + + + + + `; -exports[`renders ./components/table/demo/nested-table.md correctly 1`] = ` +exports[`renders ./antdv-demo/table/demo/nested-table.md correctly 1`] = `
    @@ -2208,90 +2062,88 @@ exports[`renders ./components/table/demo/nested-table.md correctly 1`] = ` - -
    Name
    - - -
    Platform
    - - -
    Version
    - - -
    Upgraded
    - - -
    Creator
    - - -
    Date
    - - -
    Action
    - - - - - - - Screem - iOS - 10.3.4.5654 - 500 - Jack - 2014-12-24 23:12:00 - Publish - - - - - Screem - iOS - 10.3.4.5654 - 500 - Jack - 2014-12-24 23:12:00 - Publish - - - - - Screem - iOS - 10.3.4.5654 - 500 - Jack - 2014-12-24 23:12:00 - Publish - - - - -
    -
    -
    - - - +
    Name +
    +
    Platform +
    +
    Version +
    +
    Upgraded +
    +
    Creator +
    +
    Date +
    +
    Action
    + + + + + +
    + + Screem + iOS + 10.3.4.5654 + 500 + Jack + 2014-12-24 23:12:00 + Publish + + + + +
    + + Screem + iOS + 10.3.4.5654 + 500 + Jack + 2014-12-24 23:12:00 + Publish + + + + +
    + + Screem + iOS + 10.3.4.5654 + 500 + Jack + 2014-12-24 23:12:00 + Publish + + + + + + + + + + `; -exports[`renders ./components/table/demo/reset-filter.md correctly 1`] = ` +exports[`renders ./antdv-demo/table/demo/reset-filter.md correctly 1`] = `
    -
    +
    @@ -2303,83 +2155,61 @@ exports[`renders ./components/table/demo/reset-filter.md correctly 1`] = ` - -
    Name
    -
    - - -
    Age
    -
    - - -
    Address
    -
    - - - - - - - John Brown - 32 - New York No. 1 Lake Park - - - - Jim Green - 42 - London No. 1 Lake Park - - - - Joe Black - 32 - Sidney No. 1 Lake Park - - - - Jim Red - 32 - London No. 2 Lake Park - - - -
    -
    -
    - +
    Name
    +
    +
    Age
    +
    +
    Address
    +
    + + + + + John Brown + 32 + New York No. 1 Lake Park + + + Jim Green + 42 + London No. 1 Lake Park + + + Joe Black + 32 + Sidney No. 1 Lake Park + + + Jim Red + 32 + London No. 2 Lake Park + + +
    + +
    +
    + `; -exports[`renders ./components/table/demo/row-selection.md correctly 1`] = ` +exports[`renders ./antdv-demo/table/demo/row-selection.md correctly 1`] = `
    @@ -2389,79 +2219,70 @@ exports[`renders ./components/table/demo/row-selection.md correctly 1`] = `
    - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    Name
    -
    -
    Age
    -
    -
    Address
    -
    - John Brown32New York No. 1 Lake Park
    - Jim Green42London No. 1 Lake Park
    - Joe Black32Sidney No. 1 Lake Park
    - Disabled User99Sidney No. 1 Lake Park
    -
    -
    -
    - -
    - +
    +
    +
    +
    Name +
    +
    Age +
    +
    Address +
    + + + + + + John Brown + 32 + New York No. 1 Lake Park + + + + Jim Green + 42 + London No. 1 Lake Park + + + + Joe Black + 32 + Sidney No. 1 Lake Park + + + + Disabled User + 99 + Sidney No. 1 Lake Park + + + + + + + + + `; -exports[`renders ./components/table/demo/row-selection-and-operation.md correctly 1`] = ` +exports[`renders ./antdv-demo/table/demo/row-selection-and-operation.md correctly 1`] = `
    @@ -2473,126 +2294,111 @@ exports[`renders ./components/table/demo/row-selection-and-operation.md correctl
    - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    Name
    -
    -
    Age
    -
    -
    Address
    -
    - Edward King 032London, Park Lane no. 0
    - Edward King 132London, Park Lane no. 1
    - Edward King 232London, Park Lane no. 2
    - Edward King 332London, Park Lane no. 3
    - Edward King 432London, Park Lane no. 4
    - Edward King 532London, Park Lane no. 5
    - Edward King 632London, Park Lane no. 6
    - Edward King 732London, Park Lane no. 7
    - Edward King 832London, Park Lane no. 8
    - Edward King 932London, Park Lane no. 9
    -
    -
    -
    - - - +
    +
    +
    +
    Name +
    +
    Age +
    +
    Address +
    + + + + + + Edward King 0 + 32 + London, Park Lane no. 0 + + + + Edward King 1 + 32 + London, Park Lane no. 1 + + + + Edward King 2 + 32 + London, Park Lane no. 2 + + + + Edward King 3 + 32 + London, Park Lane no. 3 + + + + Edward King 4 + 32 + London, Park Lane no. 4 + + + + Edward King 5 + 32 + London, Park Lane no. 5 + + + + Edward King 6 + 32 + London, Park Lane no. 6 + + + + Edward King 7 + 32 + London, Park Lane no. 7 + + + + Edward King 8 + 32 + London, Park Lane no. 8 + + + + Edward King 9 + 32 + London, Park Lane no. 9 + + + + + + + + + `; -exports[`renders ./components/table/demo/row-selection-custom.md correctly 1`] = ` +exports[`renders ./antdv-demo/table/demo/row-selection-custom.md correctly 1`] = `
    @@ -2602,129 +2408,113 @@ exports[`renders ./components/table/demo/row-selection-custom.md correctly 1`] =
    - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    -
    -
    -
    -
    Name
    -
    -
    Age
    -
    -
    Address
    -
    - Edward King 032London, Park Lane no. 0
    - Edward King 132London, Park Lane no. 1
    - Edward King 232London, Park Lane no. 2
    - Edward King 332London, Park Lane no. 3
    - Edward King 432London, Park Lane no. 4
    - Edward King 532London, Park Lane no. 5
    - Edward King 632London, Park Lane no. 6
    - Edward King 732London, Park Lane no. 7
    - Edward King 832London, Park Lane no. 8
    - Edward King 932London, Park Lane no. 9
    -
    -
    -
    - -
    - +
    +
    +
    +
    +
    Name +
    +
    Age +
    +
    Address +
    + + + + + + Edward King 0 + 32 + London, Park Lane no. 0 + + + + Edward King 1 + 32 + London, Park Lane no. 1 + + + + Edward King 2 + 32 + London, Park Lane no. 2 + + + + Edward King 3 + 32 + London, Park Lane no. 3 + + + + Edward King 4 + 32 + London, Park Lane no. 4 + + + + Edward King 5 + 32 + London, Park Lane no. 5 + + + + Edward King 6 + 32 + London, Park Lane no. 6 + + + + Edward King 7 + 32 + London, Park Lane no. 7 + + + + Edward King 8 + 32 + London, Park Lane no. 8 + + + + Edward King 9 + 32 + London, Park Lane no. 9 + + + + + + + + + `; -exports[`renders ./components/table/demo/size.md correctly 1`] = ` +exports[`renders ./antdv-demo/table/demo/size.md correctly 1`] = `

    Middle size table

    @@ -2742,122 +2532,110 @@ exports[`renders ./components/table/demo/size.md correctly 1`] = ` - -
    Name
    - - -
    Age
    - - -
    Address
    - - - - - - - John Brown - 32 - New York No. 1 Lake Park - - - - Jim Green - 42 - London No. 1 Lake Park - - - - Joe Black - 32 - Sidney No. 1 Lake Park - - - -
    -
    - - +
    Name +
    +
    Age +
    +
    Address +
    + + + + + John Brown + 32 + New York No. 1 Lake Park + + + Jim Green + 42 + London No. 1 Lake Park + + + Joe Black + 32 + Sidney No. 1 Lake Park + + + -

    Small size table

    -
    -
    -
    -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    Name
    -
    -
    Age
    -
    -
    Address
    -
    - John Brown32New York No. 1 Lake Park
    - Jim Green42London No. 1 Lake Park
    - Joe Black32Sidney No. 1 Lake Park
    -
    -
    -
    -
    +
    +
    +

    Small size table

    +
    +
    +
    +
    +
    - -
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Name +
    Age +
    Address +
    John Brown32New York No. 1 Lake Park
    Jim Green42London No. 1 Lake Park
    Joe Black32Sidney No. 1 Lake Park
    + +
    +
    + + `; -exports[`renders ./components/table/demo/template.md correctly 1`] = ` +exports[`renders ./antdv-demo/table/demo/template.md correctly 1`] = `
    @@ -2876,75 +2654,64 @@ exports[`renders ./components/table/demo/template.md correctly 1`] = ` - -
    Name
    - - -
    Age
    - - -
    Address
    - - -
    Tags
    - - -
    Action
    - - - - -
    First Name
    - - -
    Last Name
    - - - - - - - John - Brown - 32 - New York No. 1 Lake Park -
    nice
    developer
    - Action 一 John
    Delete
    - - - - Jim - Green - 42 - London No. 1 Lake Park -
    loser
    - Action 一 Jim
    Delete
    - - - - Joe - Black - 32 - Sidney No. 1 Lake Park -
    cool
    teacher
    - Action 一 Joe
    Delete
    - - - -
    -
    -
    - - - +
    Name +
    +
    Age +
    +
    Address +
    +
    Tags +
    +
    Action +
    + + +
    First Name +
    +
    Last Name
    + + + + + John + Brown + 32 + New York No. 1 Lake Park + nicedeveloper + Action 一 John Delete + + + Jim + Green + 42 + London No. 1 Lake Park + loser + Action 一 Jim Delete + + + Joe + Black + 32 + Sidney No. 1 Lake Park + coolteacher + Action 一 Joe Delete + + + + + + + + + `; diff --git a/components/table/__tests__/__snapshots__/empty.test.js.snap b/components/table/__tests__/__snapshots__/empty.test.js.snap index bce809622..4a92bb528 100644 --- a/components/table/__tests__/__snapshots__/empty.test.js.snap +++ b/components/table/__tests__/__snapshots__/empty.test.js.snap @@ -21,46 +21,44 @@ exports[`Table renders empty table 1`] = ` - -
    Column 1
    - - -
    Column 2
    - - -
    Column 3
    - - -
    Column 4
    - - -
    Column 5
    - - -
    Column 6
    - - -
    Column 7
    - - -
    Column 8
    - - - - - - -
    -
    -
    No Data
    -

    No Data

    -
    -
    - - - +
    Column 1 +
    +
    Column 2 +
    +
    Column 3 +
    +
    Column 4 +
    +
    Column 5 +
    +
    Column 6 +
    +
    Column 7
    +
    Column 8
    + + + + + +
    +
    +
    + + + + + + + +
    +

    No Data

    + + + + + `; exports[`Table renders empty table with custom emptyText 1`] = ` @@ -84,40 +82,30 @@ exports[`Table renders empty table with custom emptyText 1`] = ` - -
    Column 1
    - - -
    Column 2
    - - -
    Column 3
    - - -
    Column 4
    - - -
    Column 5
    - - -
    Column 6
    - - -
    Column 7
    - - -
    Column 8
    - - - - - - -
    custom empty text
    - - - - +
    Column 1 +
    +
    Column 2 +
    +
    Column 3 +
    +
    Column 4 +
    +
    Column 5 +
    +
    Column 6 +
    +
    Column 7
    +
    Column 8
    + + + + + +
    custom empty text
    + + + + `; @@ -146,107 +134,97 @@ exports[`Table renders empty table with fixed columns 1`] = ` - -
    Full Name
    - - -
    Age
    - - -
    Column 1
    - - -
    Column 2
    - - -
    Column 3
    - - -
    Column 4
    - - -
    Column 5
    - - -
    Column 6
    - - -
    Column 7
    - - -
    Column 8
    - - -
    Action
    - - - - - - -
    -
    -
    No Data
    -

    No Data

    -
    -
    - -
    - -
    -
    - - - - - - - - - - - - -
    -
    Full Name
    -
    -
    Age
    -
    -
    -
    -
    -
    - -
    -
    - - - - - - - - - - -
    -
    Action
    -
    -
    -
    -
    - - - +
    Full Name +
    +
    Age +
    +
    Column 1 +
    +
    Column 2 +
    +
    Column 3 +
    +
    Column 4 +
    +
    Column 5 +
    +
    Column 6
    +
    Column 7
    +
    Column 8
    +
    Action
    + + + + + +
    +
    +
    + + + + + + + +
    +

    No Data

    + +
    + +
    +
    + + + + + + + + + + + + +
    Full Name +
    Age +
    +
    +
    +
    +
    + +
    +
    + + + + + + + + + + +
    Action +
    +
    +
    +
    + + + + + `; exports[`Table renders empty table without emptyText when loading 1`] = `
    -
    +
    @@ -266,39 +244,42 @@ exports[`Table renders empty table without emptyText when loading 1`] = ` - -
    Column 1
    - - -
    Column 2
    - - -
    Column 3
    - - -
    Column 4
    - - -
    Column 5
    - - -
    Column 6
    - - -
    Column 7
    - - -
    Column 8
    - - - - - -
    -
    -
    -
    -
    +
    Column 1 +
    +
    Column 2 +
    +
    Column 3 +
    +
    Column 4 +
    +
    Column 5 +
    +
    Column 6 +
    +
    Column 7
    +
    Column 8
    + + + + + +
    +
    +
    + + + + + + + +
    +

    No Data

    + + + + + `; diff --git a/components/table/createBodyRow.jsx b/components/table/createBodyRow.jsx index 2b4df6d72..a31f53427 100644 --- a/components/table/createBodyRow.jsx +++ b/components/table/createBodyRow.jsx @@ -9,7 +9,7 @@ const BodyRowProps = { prefixCls: PropTypes.string, }; -export default function createTableRow(Component = 'tr') { +export default function createBodyRow(Component = 'tr') { const BodyRow = { name: 'BodyRow', props: BodyRowProps, diff --git a/components/table/demo/EditableCell.vue b/components/table/demo/EditableCell.vue deleted file mode 100644 index abe40f72b..000000000 --- a/components/table/demo/EditableCell.vue +++ /dev/null @@ -1,41 +0,0 @@ - - diff --git a/components/table/demo/ajax.md b/components/table/demo/ajax.md deleted file mode 100644 index 69ffd2766..000000000 --- a/components/table/demo/ajax.md +++ /dev/null @@ -1,101 +0,0 @@ - -#### 远程加载数据 -这个例子通过简单的 ajax 读取方式,演示了如何从服务端读取并展现数据,具有筛选、排序等功能以及页面 loading 效果。开发者可以自行接入其他数据处理方式。 -另外,本例也展示了筛选排序功能如何交给服务端实现,列不需要指定具体的 `onFilter` 和 `sorter` 函数,而是在把筛选和排序的参数发到服务端来处理。 -**注意,此示例使用 [模拟接口](https://randomuser.me),展示数据可能不准确,请打开网络面板查看请求。** - - - -#### Ajax -This example shows how to fetch and present data from a remote server, and how to implement filtering and sorting in server side by sending related parameters to server. -**Note, this example use [Mock API](https://randomuser.me) that you can look up in Network Console.** - - -```tpl - - -``` diff --git a/components/table/demo/basic.md b/components/table/demo/basic.md deleted file mode 100644 index 18be12335..000000000 --- a/components/table/demo/basic.md +++ /dev/null @@ -1,98 +0,0 @@ - -#### 基本用法 -简单的表格,最后一列是各种操作。 - - - -#### basic Usage -Simple table with actions. - - -```tpl - - -``` diff --git a/components/table/demo/bordered.md b/components/table/demo/bordered.md deleted file mode 100644 index 07e66cc57..000000000 --- a/components/table/demo/bordered.md +++ /dev/null @@ -1,79 +0,0 @@ - -#### 带边框 -添加表格边框线,页头和页脚。 - - - -#### border, title and footer -Add border, title and footer for table. - - -```tpl - - - -``` diff --git a/components/table/demo/colspan-rowspan.md b/components/table/demo/colspan-rowspan.md deleted file mode 100644 index 2edc6fb21..000000000 --- a/components/table/demo/colspan-rowspan.md +++ /dev/null @@ -1,142 +0,0 @@ - -#### 表格行/列合并 -表头只支持列合并,使用 column 里的 colSpan 进行设置。 -表格支持行/列合并,使用 render 里的单元格属性 colSpan 或者 rowSpan 设值为 0 时,设置的表格不会渲染。 - - - -#### colSpan and rowSpan -Table column title supports `colSpan` that set in `column`. -Table cell supports `colSpan` and `rowSpan` that set in render return object. When each of them is set to `0`, the cell will not be rendered. - - -```tpl - - -``` diff --git a/components/table/demo/custom-filter-panel.md b/components/table/demo/custom-filter-panel.md deleted file mode 100644 index 68d3d3fe3..000000000 --- a/components/table/demo/custom-filter-panel.md +++ /dev/null @@ -1,179 +0,0 @@ - -#### 自定义筛选菜单 -通过 `filterDropdown` 定义自定义的列筛选功能,并实现一个搜索列的示例。 - - - -#### Customized filter panel -Implement a customized column search example via `filterDropdown`. - - -```tpl - - - - -``` diff --git a/components/table/demo/edit-cell.md b/components/table/demo/edit-cell.md deleted file mode 100644 index bc0a01004..000000000 --- a/components/table/demo/edit-cell.md +++ /dev/null @@ -1,151 +0,0 @@ - -#### 可编辑单元格 -带单元格编辑功能的表格。 - - - -#### Editable Cells -Table with editable cells. - - -```tpl - - - -``` diff --git a/components/table/demo/edit-row.md b/components/table/demo/edit-row.md deleted file mode 100644 index 540389ead..000000000 --- a/components/table/demo/edit-row.md +++ /dev/null @@ -1,139 +0,0 @@ - -#### 可编辑行 -带行编辑功能的表格。 - - - -#### Editable Rows -Table with editable rows. - - -```tpl - - - -``` diff --git a/components/table/demo/expand-children.md b/components/table/demo/expand-children.md deleted file mode 100644 index be2a1b9b3..000000000 --- a/components/table/demo/expand-children.md +++ /dev/null @@ -1,127 +0,0 @@ - -#### 树形数据展示 -表格支持树形数据的展示,当数据中有 `children` 字段时会自动展示为树形表格,如果不需要或配置为其他字段可以用 `childrenColumnName` 进行配置。 -可以通过设置 `indentSize` 以控制每一层的缩进宽度。 -> 注:暂不支持父子数据递归关联选择。 - - - -#### Tree data -Display tree structure data in Table when there is field key `children` in dataSource, try to customize `childrenColumnName` property to avoid tree table structure. -You can control the indent width by setting `indentSize`. -> Note, no support for recursive selection of tree structure data table yet. - - -```tpl - - -``` diff --git a/components/table/demo/expand.md b/components/table/demo/expand.md deleted file mode 100644 index cfb8ee962..000000000 --- a/components/table/demo/expand.md +++ /dev/null @@ -1,59 +0,0 @@ - -#### 可展开 -当表格内容较多不能一次性完全展示时。 - - - -#### Expandable Row -When there's too much information to show and the table can't display all at once. - - -```tpl - - -``` diff --git a/components/table/demo/fixed-columns-header.md b/components/table/demo/fixed-columns-header.md deleted file mode 100644 index 76410c112..000000000 --- a/components/table/demo/fixed-columns-header.md +++ /dev/null @@ -1,61 +0,0 @@ - -#### 固定头和列 -适合同时展示有大量数据和数据列。 -> 若列头与内容不对齐或出现列重复,请指定**固定列**的宽度 `width`。 -> 建议指定 `scroll.x` 为大于表格宽度的固定值或百分比。注意,且非固定列宽度之和不要超过 `scroll.x`。 - - - -#### Fixed Columns and Header -A Solution for displaying large amounts of data with long columns. -> Specify the width of columns if header and cell do not align properly. (Leave one column at least without width to fit fluid layout) -> A fixed value which is greater than table width for `scroll.x` is recommended. The sum of unfixed columns should not greater than `scroll.x`. - - -```tpl - - -``` diff --git a/components/table/demo/fixed-columns.md b/components/table/demo/fixed-columns.md deleted file mode 100644 index 37245a0f1..000000000 --- a/components/table/demo/fixed-columns.md +++ /dev/null @@ -1,66 +0,0 @@ - -#### 固定列 -对于列数很多的数据,可以固定前后的列,横向滚动查看其它数据,需要和 `scroll.x` 配合使用。 -> 若列头与内容不对齐或出现列重复,请指定**固定列**的宽度 `width`。 -> 建议指定 `scroll.x` 为大于表格宽度的固定值或百分比。注意,且非固定列宽度之和不要超过 `scroll.x`。 - - - -#### Fixed Columns -To fix some columns and scroll inside other columns, and you must set `scroll.x` meanwhile. -> Specify the width of columns if header and cell do not align properly.(Leave one column at least without width to fit fluid layout) -> A fixed value which is greater than table width for `scroll.x` is recommended. The sum of unfixed columns should not greater than `scroll.x`. - - -```tpl - - -``` diff --git a/components/table/demo/fixed-header.md b/components/table/demo/fixed-header.md deleted file mode 100644 index f673cc069..000000000 --- a/components/table/demo/fixed-header.md +++ /dev/null @@ -1,59 +0,0 @@ - -#### 固定表头 -方便一页内展示大量数据。 -需要指定 column 的 `width` 属性,否则列头和内容可能不对齐。(建议留一列不设宽度以适应弹性布局) - - - -#### Fixed Header -Display large amounts of data in scrollable view. -> Specify width of columns if header and cell do not align properly.(Leave one column at least without width to fit fluid layout) - - -```tpl - - -``` diff --git a/components/table/demo/grouping-columns.md b/components/table/demo/grouping-columns.md deleted file mode 100644 index 4ef9a1650..000000000 --- a/components/table/demo/grouping-columns.md +++ /dev/null @@ -1,129 +0,0 @@ - -#### 表头分组 -`columns[n]` 可以内嵌 `children`,以渲染分组表头。 - - - -#### Grouping table head -Group table head with `columns[n].children`. - - -```tpl - - -``` diff --git a/components/table/demo/head.md b/components/table/demo/head.md deleted file mode 100644 index 8825a50fa..000000000 --- a/components/table/demo/head.md +++ /dev/null @@ -1,125 +0,0 @@ - -#### 筛选和排序 -对某一列数据进行筛选,使用列的 `filters` 属性来指定需要筛选菜单的列,`onFilter` 用于筛选当前数据,`filterMultiple` 用于指定多选和单选。 -对某一列数据进行排序,通过指定列的 `sorter` 函数即可启动排序按钮。`sorter: function(rowA, rowB) { ... }`, rowA、rowB 为比较的两个行数据。 -`sortDirections: ['ascend' | 'descend']`改变每列可用的排序方式,切换排序时按数组内容依次切换,设置在table props上时对所有列生效。 -使用 `defaultSortOrder` 属性,设置列的默认排序顺序。 - - - -#### Filter and sorter -Use `filters` to generate filter menu in columns, `onFilter` to determine filtered result, and `filterMultiple` to indicate whether it's multiple or single selection. -Use `sorter` to make a column sortable. `sorter` can be a function of the type `function(a, b) { ... }` for sorting data locally. -`sortDirections: ['ascend' | 'descend']` defines available sort methods for each columns, effective for all columns when set on table props. -Uses `defaultSortOrder` to make a column sorted by default. -If a `sortOrder` or `defaultSortOrder` is specified with the value `ascend` or `descend`, you can access this value from within the function passed to the `sorter` as explained above. Such a function can take the form: `function(a, b, sortOrder) { ... }`. - - -```tpl - - -``` diff --git a/components/table/demo/index.vue b/components/table/demo/index.vue deleted file mode 100644 index 0f545b554..000000000 --- a/components/table/demo/index.vue +++ /dev/null @@ -1,101 +0,0 @@ - diff --git a/components/table/demo/nested-table.md b/components/table/demo/nested-table.md deleted file mode 100644 index 858b5331b..000000000 --- a/components/table/demo/nested-table.md +++ /dev/null @@ -1,99 +0,0 @@ - -#### 嵌套子表格 -展示每行数据更详细的信息。 - - - -#### Nested tables -Showing more detailed info of every row. - - -```tpl - - -``` diff --git a/components/table/demo/reset-filter.md b/components/table/demo/reset-filter.md deleted file mode 100644 index aca6a756e..000000000 --- a/components/table/demo/reset-filter.md +++ /dev/null @@ -1,132 +0,0 @@ - -#### 可控的筛选和排序 -使用受控属性对筛选和排序状态进行控制。 -> 1. columns 中定义了 filteredValue 和 sortOrder 属性即视为受控模式。 -> 2. 只支持同时对一列进行排序,请保证只有一列的 sortOrder 属性是生效的。 -> 3. 务必指定 `column.key`。 - - - -#### Reset filters and sorters -Control filters and sorters by `filteredValue` and `sortOrder`. -> 1. Defining `filteredValue` or `sortOrder` means that it is in the controlled mode. -> 2. Make sure `sortOrder` is assigned for only one column. -> 3. `column.key` is required. - - -```tpl - - - -``` diff --git a/components/table/demo/resizable-column.vue b/components/table/demo/resizable-column.vue deleted file mode 100755 index ef6472d98..000000000 --- a/components/table/demo/resizable-column.vue +++ /dev/null @@ -1,142 +0,0 @@ - -#### 可伸缩列 -集成 [vue-draggable-resizable](https://github.com/mauricius/vue-draggable-resizable) 来实现可伸缩列。 - - - -#### Resizable column -Implement resizable column by integrate with [vue-draggable-resizable](https://github.com/mauricius/vue-draggable-resizable). - - - - - - diff --git a/components/table/demo/row-selection-and-operation.md b/components/table/demo/row-selection-and-operation.md deleted file mode 100644 index c5839b020..000000000 --- a/components/table/demo/row-selection-and-operation.md +++ /dev/null @@ -1,87 +0,0 @@ - -#### 选择和操作 -选择后进行操作,完成后清空选择,通过 `rowSelection.selectedRowKeys` 来控制选中项。 - - - -#### Selection and operation -To perform operations and clear selections after selecting some rows, use `rowSelection.selectedRowKeys` to control selected rows. - - -```tpl - - -``` diff --git a/components/table/demo/row-selection-custom.md b/components/table/demo/row-selection-custom.md deleted file mode 100644 index 5b241ee92..000000000 --- a/components/table/demo/row-selection-custom.md +++ /dev/null @@ -1,105 +0,0 @@ - -#### 自定义选择项 -通过 `rowSelection.selections` 自定义选择项,默认不显示下拉选项,设为 `true` 时显示默认选择项。 - - - -#### Custom selection -Use `rowSelection.selections` custom selections, default no select dropdown, show default selections via setting to `true`. - - -```tpl - - -``` diff --git a/components/table/demo/row-selection.md b/components/table/demo/row-selection.md deleted file mode 100644 index acd24fd91..000000000 --- a/components/table/demo/row-selection.md +++ /dev/null @@ -1,87 +0,0 @@ - -#### 可选择 -第一列是联动的选择框。 -> 默认点击 checkbox 触发选择行为 - - - -#### selection -Rows can be selectable by making first column as a selectable column. -> selection happens when clicking checkbox defaultly. - - -```tpl - - -``` diff --git a/components/table/demo/size.md b/components/table/demo/size.md deleted file mode 100644 index a21198211..000000000 --- a/components/table/demo/size.md +++ /dev/null @@ -1,70 +0,0 @@ - -#### 紧凑型 -两种紧凑型的列表,小型列表只用于对话框内。 - - - -#### size -Two compacted table size: `middle` and `small`, `small` size is used in Modal only. - - -```tpl - - - -``` diff --git a/components/table/demo/template.md b/components/table/demo/template.md deleted file mode 100644 index 9cf22eaef..000000000 --- a/components/table/demo/template.md +++ /dev/null @@ -1,79 +0,0 @@ - -#### template 风格的 API -使用 template 风格的 API -> 这个只是一个描述 `columns` 的语法糖,所以你不能用其他组件去包裹 `Column` 和 `ColumnGroup`。 - - - -#### template style API -Using template style API -> Since this is just a syntax sugar for the prop `columns`, so that you can't compose `Column` and `ColumnGroup` with other Components. - - -```tpl - - -``` diff --git a/components/table/filterDropdown.jsx b/components/table/filterDropdown.jsx index ea41aa926..d3454a9dc 100755 --- a/components/table/filterDropdown.jsx +++ b/components/table/filterDropdown.jsx @@ -8,9 +8,10 @@ import Checkbox from '../checkbox'; import Radio from '../radio'; import FilterDropdownMenuWrapper from './FilterDropdownMenuWrapper'; import { FilterMenuProps } from './interface'; -import { initDefaultProps, getOptionProps } from '../_util/props-util'; +import { initDefaultProps, getOptionProps, isValidElement } from '../_util/props-util'; import { cloneElement } from '../_util/vnode'; import BaseMixin from '../_util/BaseMixin'; +import { generateValueMaps } from './util'; function stopPropagation(e) { e.stopPropagation(); @@ -32,13 +33,13 @@ export default { sSelectedKeys: this.selectedKeys, sKeyPathOfSelectedItem: {}, // 记录所有有选中子菜单的祖先菜单 sVisible: visible, + sValueKeys: generateValueMaps(this.column.filters), }; }, watch: { _propsSymbol() { const nextProps = getOptionProps(this); const { column } = nextProps; - this.setNeverShown(column); const newState = {}; /** @@ -54,6 +55,9 @@ export default { ) { newState.sSelectedKeys = nextProps.selectedKeys; } + if (!shallowequal((this.preProps.column || {}).filters, (nextProps.column || {}).filters)) { + newState.sValueKeys = generateValueMaps(nextProps.column.filters); + } if ('filterDropdownVisible' in column) { newState.sVisible = column.filterDropdownVisible; } @@ -81,6 +85,12 @@ export default { this.setNeverShown(column); }); }, + updated() { + const { column } = this; + this.$nextTick(() => { + this.setNeverShown(column); + }); + }, methods: { getDropdownVisible() { return this.neverShown ? false : this.sVisible; @@ -133,33 +143,26 @@ export default { onVisibleChange(visible) { this.setVisible(visible); - if (!visible) { + const { column } = this.$props; + // https://github.com/ant-design/ant-design/issues/17833 + if (!visible && !(column.filterDropdown instanceof Function)) { this.confirmFilter2(); } }, - - confirmFilter2() { - if (!shallowequal(this.sSelectedKeys, this.selectedKeys)) { - this.confirmFilter(this.column, this.sSelectedKeys); - } - }, - - renderMenuItem(item) { - const { column } = this; + handleMenuItemClick(info) { const { sSelectedKeys: selectedKeys } = this.$data; - const multiple = 'filterMultiple' in column ? column.filterMultiple : true; - const input = multiple ? ( - = 0} /> - ) : ( - = 0} /> - ); - - return ( - - {input} - {item.text} - - ); + if (!info.keyPath || info.keyPath.length <= 1) { + return; + } + const { sKeyPathOfSelectedItem: keyPathOfSelectedItem } = this.$data; + if (selectedKeys && selectedKeys.indexOf(info.key) >= 0) { + // deselect SubMenu child + delete keyPathOfSelectedItem[info.key]; + } else { + // select SubMenu child + keyPathOfSelectedItem[info.key] = info.keyPath; + } + this.setState({ sKeyPathOfSelectedItem: keyPathOfSelectedItem }); }, hasSubMenu() { @@ -169,18 +172,34 @@ export default { return filters.some(item => !!(item.children && item.children.length > 0)); }, + confirmFilter2() { + const { column, selectedKeys: propSelectedKeys, confirmFilter } = this.$props; + const { sSelectedKeys: selectedKeys, sValueKeys: valueKeys } = this.$data; + const { filterDropdown } = column; + + if (!shallowequal(selectedKeys, propSelectedKeys)) { + confirmFilter( + column, + filterDropdown + ? selectedKeys + : selectedKeys.map(key => valueKeys[key]).filter(key => key !== undefined), + ); + } + }, + renderMenus(items) { + const { dropdownPrefixCls, prefixCls } = this.$props; return items.map(item => { if (item.children && item.children.length > 0) { const { sKeyPathOfSelectedItem } = this; const containSelected = Object.keys(sKeyPathOfSelectedItem).some( key => sKeyPathOfSelectedItem[key].indexOf(item.value) >= 0, ); - const subMenuCls = containSelected - ? `${this.dropdownPrefixCls}-submenu-contain-selected` - : ''; + const subMenuCls = classNames(`${prefixCls}-dropdown-submenu`, { + [`${dropdownPrefixCls}-submenu-contain-selected`]: containSelected, + }); return ( - + {this.renderMenus(item.children)} ); @@ -189,22 +208,6 @@ export default { }); }, - handleMenuItemClick(info) { - const { sSelectedKeys: selectedKeys } = this.$data; - if (!info.keyPath || info.keyPath.length <= 1) { - return; - } - const keyPathOfSelectedItem = this.sKeyPathOfSelectedItem; - if (selectedKeys && selectedKeys.indexOf(info.key) >= 0) { - // deselect SubMenu child - delete keyPathOfSelectedItem[info.key]; - } else { - // select SubMenu child - keyPathOfSelectedItem[info.key] = info.keyPath; - } - this.setState({ keyPathOfSelectedItem }); - }, - renderFilterIcon() { const { column, locale, prefixCls, selectedKeys } = this; const filtered = selectedKeys && selectedKeys.length > 0; @@ -216,30 +219,53 @@ export default { [`${prefixCls}-selected`]: filtered, [`${prefixCls}-open`]: this.getDropdownVisible(), }); - - return filterIcon ? ( - cloneElement(filterIcon, { - attrs: { - title: locale.filterTitle, - }, + if (!filterIcon) { + return ( + + ); + } + if (filterIcon.length === 1 && isValidElement(filterIcon[0])) { + return cloneElement(filterIcon[0], { on: { click: stopPropagation, }, class: classNames(`${prefixCls}-icon`, dropdownIconClass), - }) + }); + } + return {filterIcon}; + }, + + renderMenuItem(item) { + const { column } = this; + const { sSelectedKeys: selectedKeys } = this.$data; + const multiple = 'filterMultiple' in column ? column.filterMultiple : true; + + // We still need trade key as string since Menu render need string + // const internalSelectedKeys = (selectedKeys || []).map(key => key.toString()); + + const input = multiple ? ( + = 0} /> ) : ( - + = 0} /> + ); + + return ( + + {input} + {item.text} + ); }, }, render() { + const { sSelectedKeys: originSelectedKeys } = this.$data; const { column, locale, prefixCls, dropdownPrefixCls, getPopupContainer } = this; // default multiple selection in filter dropdown const multiple = 'filterMultiple' in column ? column.filterMultiple : true; @@ -251,11 +277,11 @@ export default { filterDropdown = filterDropdown({ prefixCls: `${dropdownPrefixCls}-custom`, setSelectedKeys: selectedKeys => this.setSelectedKeys({ selectedKeys }), - selectedKeys: this.sSelectedKeys, + selectedKeys: originSelectedKeys, confirm: this.handleConfirm, clearFilters: this.handleClearFilters, filters: column.filters, - getPopupContainer: triggerNode => triggerNode.parentNode, + visible: this.getDropdownVisible(), column, }); } @@ -273,8 +299,8 @@ export default { class={dropdownMenuClass} onSelect={this.setSelectedKeys} onDeselect={this.setSelectedKeys} - selectedKeys={this.sSelectedKeys} - getPopupContainer={triggerNode => triggerNode.parentNode} + selectedKeys={originSelectedKeys && originSelectedKeys.map(val => val.toString())} + getPopupContainer={getPopupContainer} > {this.renderMenus(column.filters)} diff --git a/components/table/index.en-US.md b/components/table/index.en-US.md deleted file mode 100644 index 20555a302..000000000 --- a/components/table/index.en-US.md +++ /dev/null @@ -1,159 +0,0 @@ -## API - -### Table - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| bordered | Whether to show all table borders | boolean | `false` | -| childrenColumnName | The column contains children to display | string\[] | children | -| columns | Columns of table [config](#Column) | array | - | -| components | Override default table elements | object | - | -| dataSource | Data record array to be displayed | any\[] | - | -| defaultExpandAllRows | Expand all rows initially | boolean | `false` | -| defaultExpandedRowKeys | Initial expanded row keys | string\[] | - | -| expandedRowKeys | Current expanded row keys | string\[] | - | -| expandedRowRender | Expanded container render for each row | Function(record, index, indent, expanded):VNode\|slot-scope | - | -| expandIcon | Customize row expand Icon. | Function(props):VNode \| slot="expandIcon" slot-scope="props" | - | -| expandRowByClick | Whether to expand row by clicking anywhere in the whole row | boolean | `false` | -| footer | Table footer renderer | Function(currentPageData)\|slot-scope | | -| indentSize | Indent size in pixels of tree data | number | 15 | -| loading | Loading status of table | boolean\|[object](/components/spin) | `false` | -| locale | i18n text including filter, sort, empty text, etc | object | filterConfirm: 'Ok'
    filterReset: 'Reset'
    emptyText: 'No Data' | -| pagination | Config of pagination. You can ref table pagination [config](#pagination) or full [`pagination`](/components/pagination/) document, hide it by setting it to `false` | object | | -| rowClassName | Row's className | Function(record, index):string | - | -| rowKey | Row's unique key, could be a string or function that returns a string | string\|Function(record, index):string | `key` | -| rowSelection | Row selection [config](#rowSelection) | object | null | -| scroll | Set horizontal or vertical scrolling, can also be used to specify the width and height of the scroll area. It is recommended to set a number for `x`, if you want to set it to `true`, you need to add style `.ant-table td { white-space: nowrap; }`. | { x: number \| true, y: number } | - | -| showHeader | Whether to show table header | boolean | `true` | -| size | Size of table | `default` \| `middle` \| `small` \| `large` | `default` | -| title | Table title renderer | Function(currentPageData)\|slot-scope | | -| customHeaderRow | Set props on per header row | Function(column, index) | - | -| customRow | Set props on per row | Function(record, index) | - | - -### Events - -| Events Name | Description | Arguments | -| --- | --- | --- | -| change | Callback executed when pagination, filters or sorter is changed | Function(pagination, filters, sorter, { currentDataSource }) | | -| expand | Callback executed when the row expand icon is clicked | Function(expanded, record) | | -| expandedRowsChange | Callback executed when the expanded rows change | Function(expandedRows) | | - -#### customRow usage - -Same as `customRow` `customHeaderRow` `customCell` `customHeaderCell`. Follow [Vue jsx](https://github.com/vuejs/babel-plugin-transform-vue-jsx) syntax。 - -```jsx - { - return { - props: { - xxx... - }, - on: { - click: (event) => {}, // click row - dblclick: (event) => {}, // double click row - contextmenu: (event) => {} // right button click row - mouseenter: (event) => {} // mouse enter row - mouseleave: (event) => {} // mouse leave row - }, - }; - )} - customHeaderRow={(column) => { - return { - on: { - click: () => {}, // click header row - }, - }; - )} -/> -``` - -### Column - -One of the Table `columns` prop for describing the table's columns, Column has the same API. - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| align | specify how content is aligned | 'left' \| 'right' \| 'center' | 'left' | -| colSpan | Span of this column's title | number | | -| dataIndex | Display field of the data record, could be set like `a.b.c` | string | - | -| defaultSortOrder | Default order of sorted values: `'ascend'` `'descend'` `null` | string | - | -| filterDropdown | Customized filter overlay | slot \| slot-scope | - | -| filterDropdownVisible | Whether `filterDropdown` is visible | boolean | - | -| filtered | Whether the `dataSource` is filtered | boolean | `false` | -| filteredValue | Controlled filtered value, filter icon will highlight | string\[] | - | -| filterIcon | Customized filter icon | slot \| slot-scope \| (filtered: boolean, column: Column) | `false` | -| filterMultiple | Whether multiple filters can be selected | boolean | `true` | -| filters | Filter menu config | object\[] | - | -| fixed | Set column to be fixed: `true`(same as left) `'left'` `'right'` | boolean\|string | `false` | -| key | Unique key of this column, you can ignore this prop if you've set a unique `dataIndex` | string | - | -| customRender | Renderer of the table cell. The return value should be a VNode, or an object for colSpan/rowSpan config | Function(text, record, index) {}\|slot-scope | - | -| sorter | Sort function for local sort, see [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)'s compareFunction. If you need sort buttons only, set to `true` | Function\|boolean | - | -| sortOrder | Order of sorted values: `'ascend'` `'descend'` `false` | boolean\|string | - | -| title | Title of this column | string\|slot | - | -| width | Width of this column | string\|number | - | -| customCell | Set props on per cell | Function(record, rowIndex) | - | -| customHeaderCell | Set props on per header cell | Function(column) | - | -| onFilter | Callback executed when the confirm filter button is clicked, Use as a `filter` event when using template or jsx | Function | - | -| onFilterDropdownVisibleChange | Callback executed when `filterDropdownVisible` is changed, Use as a `filterDropdownVisible` event when using template or jsx | function(visible) {} | - | -| slots | When using columns, you can use this property to configure the properties that support the slot, such as `slots: { filterIcon: 'XXX'}` | object | - | -| scopedSlots | When using columns, you can use this property to configure the properties that support the slot-scope, such as `scopedSlots: { customRender: 'XXX'}` | object | - | - -### ColumnGroup - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| title | Title of the column group | string\|slot | - | -| slots | When using columns, you can use this property to configure the properties that support the slot, such as `slots: { title: 'XXX'}` | object | - | - -### pagination - -Properties for pagination. - -| Property | Description | Type | Default | -| -------- | ------------------------------------ | --------------------------- | -------- | -| position | specify the position of `Pagination` | 'top' \| 'bottom' \| 'both' | 'bottom' | - -More about pagination, please check [`Pagination`](/components/pagination/). - -### rowSelection - -Properties for row selection. - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| columnWidth | Set the width of the selection column | string\|number | - | -| columnTitle | Set the title of the selection column | string\|VNode | - | -| fixed | Fixed selection column on the left | boolean | - | -| getCheckboxProps | Get Checkbox or Radio props | Function(record) | - | -| hideDefaultSelections | Remove the default `Select All` and `Select Invert` selections | boolean | `false` | -| selectedRowKeys | Controlled selected row keys | string\[] | \[] | -| selections | Custom selection config, only displays default selections when set to `true` | object\[]\|boolean | - | -| type | `checkbox` or `radio` | `checkbox` \| `radio` | `checkbox` | -| onChange | Callback executed when selected rows change | Function(selectedRowKeys, selectedRows) | - | -| onSelect | Callback executed when select/deselect one row | Function(record, selected, selectedRows, nativeEvent) | - | -| onSelectAll | Callback executed when select/deselect all rows | Function(selected, selectedRows, changeRows) | - | -| onSelectInvert | Callback executed when row selection is inverted | Function(selectedRows) | - | - -### selection - -Custom selection config - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| key | Unique key of this selection | string | - | -| text | Display text of this selection | string\|VNode | - | -| onSelect | Callback executed when this selection is clicked | Function(changeableRowKeys) | - | - -## Note - -The values inside `dataSource` and `columns` should follow this in Table, and `dataSource[i].key` would be treated as key value default for `dataSource`. - -If `dataSource[i].key` is not provided, then you should specify the primary key of dataSource value via `rowKey`. If not, warnings will show in browser console. - -```jsx -// primary key is uid -return
    ; -// or -return
    record.uid} />; -``` diff --git a/components/table/index.jsx b/components/table/index.jsx index dd2a3faf0..b83a966d9 100644 --- a/components/table/index.jsx +++ b/components/table/index.jsx @@ -1,5 +1,6 @@ import T from './Table'; - +import ref from 'vue-ref'; +import Vue from 'vue'; import { getOptionProps, getKey, @@ -13,6 +14,8 @@ import { } from '../_util/props-util'; import Base from '../base'; +Vue.use(ref, { name: 'ant-ref' }); + const Table = { name: 'ATable', Column: T.Column, diff --git a/components/table/index.zh-CN.md b/components/table/index.zh-CN.md deleted file mode 100644 index 522900b21..000000000 --- a/components/table/index.zh-CN.md +++ /dev/null @@ -1,159 +0,0 @@ -## API - -### Table - -| 参数 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| bordered | 是否展示外边框和列边框 | boolean | false | -| childrenColumnName | 指定树形结构的列名 | string\[] | children | -| columns | 表格列的配置描述,具体项见[下表](#Column) | array | - | -| components | 覆盖默认的 table 元素 | object | - | -| dataSource | 数据数组 | any\[] | | -| defaultExpandAllRows | 初始时,是否展开所有行 | boolean | false | -| defaultExpandedRowKeys | 默认展开的行 | string\[] | - | -| expandedRowKeys | 展开的行,控制属性 | string\[] | - | -| expandedRowRender | 额外的展开行 | Function(record, index, indent, expanded):VNode \| slot="expandedRowRender" slot-scope="record, index, indent, expanded" | - | -| expandIcon | 自定义展开图标 | Function(props):VNode \| slot="expandIcon" slot-scope="props" | - | -| expandRowByClick | 通过点击行来展开子行 | boolean | `false` | -| footer | 表格尾部 | Function(currentPageData)\|slot-scope | | -| indentSize | 展示树形数据时,每层缩进的宽度,以 px 为单位 | number | 15 | -| loading | 页面是否加载中 | boolean\|[object](/components/spin-cn) | false | -| locale | 默认文案设置,目前包括排序、过滤、空数据文案 | object | filterConfirm: '确定'
    filterReset: '重置'
    emptyText: '暂无数据' | -| pagination | 分页器,参考[配置项](#pagination)或 [pagination](/components/pagination-cn/)文档,设为 false 时不展示和进行分页 | object | | -| rowClassName | 表格行的类名 | Function(record, index):string | - | -| rowKey | 表格行 key 的取值,可以是字符串或一个函数 | string\|Function(record):string | 'key' | -| rowSelection | 列表项是否可选择,[配置项](#rowSelection) | object | null | -| scroll | 设置横向或纵向滚动,也可用于指定滚动区域的宽和高,建议为 `x` 设置一个数字,如果要设置为 `true`,需要配合样式 `.ant-table td { white-space: nowrap; }` | { x: number \| true, y: number } | - | -| showHeader | 是否显示表头 | boolean | true | -| size | 表格大小 | default \| middle \| small | default | -| title | 表格标题 | Function(currentPageData)\|slot-scope | | -| customHeaderRow | 设置头部行属性 | Function(column, index) | - | -| customRow | 设置行属性 | Function(record, index) | - | - -### 事件 - -| 事件名称 | 说明 | 回调参数 | -| --- | --- | --- | -| expandedRowsChange | 展开的行变化时触发 | Function(expandedRows) | -| change | 分页、排序、筛选变化时触发 | Function(pagination, filters, sorter, { currentDataSource }) | -| expand | 点击展开图标时触发 | Function(expanded, record) | - -#### customRow 用法 - -适用于 `customRow` `customHeaderRow` `customCell` `customHeaderCell`。遵循[Vue jsx](https://github.com/vuejs/babel-plugin-transform-vue-jsx)语法。 - -```jsx -
    { - return { - props: { - xxx... //属性 - }, - on: { // 事件 - click: (event) => {}, // 点击行 - dblclick: (event) => {}, - contextmenu: (event) => {}, - mouseenter: (event) => {}, // 鼠标移入行 - mouseleave: (event) => {} - }, - - }; - )} - customHeaderRow={(column) => { - return { - on: { - click: () => {}, // 点击表头行 - } - }; - )} -/> -``` - -### Column - -列描述数据对象,是 columns 中的一项,Column 使用相同的 API。 - -| 参数 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| align | 设置列内容的对齐方式 | 'left' \| 'right' \| 'center' | 'left' | -| colSpan | 表头列合并,设置为 0 时,不渲染 | number | | -| dataIndex | 列数据在数据项中对应的 key,支持 `a.b.c` 的嵌套写法 | string | - | -| filterDropdown | 可以自定义筛选菜单,此函数只负责渲染图层,需要自行编写各种交互 | VNode \| slot-scope | - | -| filterDropdownVisible | 用于控制自定义筛选菜单是否可见 | boolean | - | -| filtered | 标识数据是否经过过滤,筛选图标会高亮 | boolean | false | -| filteredValue | 筛选的受控属性,外界可用此控制列的筛选状态,值为已筛选的 value 数组 | string\[] | - | -| filterIcon | 自定义 fiter 图标。 | VNode \| (filtered: boolean, column: Column) => vNode \|slot \|slot-scope | false | -| filterMultiple | 是否多选 | boolean | true | -| filters | 表头的筛选菜单项 | object\[] | - | -| fixed | 列是否固定,可选 `true`(等效于 left) `'left'` `'right'` | boolean\|string | false | -| key | Vue 需要的 key,如果已经设置了唯一的 `dataIndex`,可以忽略这个属性 | string | - | -| customRender | 生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引,@return 里面可以设置表格行/列合并,可参考 demo 表格行/列合并 | Function(text, record, index) {}\|slot-scope | - | -| sorter | 排序函数,本地排序使用一个函数(参考 [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 的 compareFunction),需要服务端排序可设为 true | Function\|boolean | - | -| sortOrder | 排序的受控属性,外界可用此控制列的排序,可设置为 `'ascend'` `'descend'` `false` | boolean\|string | - | -| title | 列头显示文字 | string\|slot | - | -| width | 列宽度 | string\|number | - | -| customCell | 设置单元格属性 | Function(record, rowIndex) | - | -| customHeaderCell | 设置头部单元格属性 | Function(column) | - | -| onFilter | 本地模式下,确定筛选的运行函数, 使用 template 或 jsx 时作为`filter`事件使用 | Function | - | -| onFilterDropdownVisibleChange | 自定义筛选菜单可见变化时调用,使用 template 或 jsx 时作为`filterDropdownVisibleChange`事件使用 | function(visible) {} | - | -| slots | 使用 columns 时,可以通过该属性配置支持 slot 的属性,如 `slots: { filterIcon: 'XXX'}` | object | - | -| scopedSlots | 使用 columns 时,可以通过该属性配置支持 slot-scope 的属性,如 `scopedSlots: { customRender: 'XXX'}` | object | - | - -### ColumnGroup - -| 参数 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| title | 列头显示文字 | string\|slot | - | -| slots | 使用 columns 时,可以通过该属性配置支持 slot 的属性,如 `slots: { title: 'XXX'}` | object | - | - -### pagination - -分页的配置项。 - -| 参数 | 说明 | 类型 | 默认值 | -| -------- | ------------------ | --------------------------- | -------- | -| position | 指定分页显示的位置 | 'top' \| 'bottom' \| 'both' | 'bottom' | - -更多配置项,请查看 [`Pagination`](/components/pagination/)。 - -### rowSelection - -选择功能的配置。 - -| 参数 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| columnWidth | 自定义列表选择框宽度 | string\|number | - | -| columnTitle | 自定义列表选择框标题 | string\|VNode | - | -| fixed | 把选择框列固定在左边 | boolean | - | -| getCheckboxProps | 选择框的默认属性配置 | Function(record) | - | -| hideDefaultSelections | 去掉『全选』『反选』两个默认选项 | boolean | false | -| selectedRowKeys | 指定选中项的 key 数组,需要和 onChange 进行配合 | string\[] | \[] | -| selections | 自定义选择配置项, 设为 `true` 时使用默认选择项 | object\[]\|boolean | true | -| type | 多选/单选,`checkbox` or `radio` | string | `checkbox` | -| onChange | 选中项发生变化时的回调 | Function(selectedRowKeys, selectedRows) | - | -| onSelect | 用户手动选择/取消选择某列的回调 | Function(record, selected, selectedRows, nativeEvent) | - | -| onSelectAll | 用户手动选择/取消选择所有列的回调 | Function(selected, selectedRows, changeRows) | - | -| onSelectInvert | 用户手动选择反选的回调 | Function(selectedRows) | - | - -### selection - -自定义选择配置项 - -| 参数 | 说明 | 类型 | 默认值 | -| -------- | ------------------------ | --------------------------- | ------ | -| key | Vue 需要的 key,建议设置 | string | - | -| text | 选择项显示的文字 | string\|VNode | - | -| onSelect | 选择项点击回调 | Function(changeableRowKeys) | - | - -## 注意 - -在 Table 中,`dataSource` 和 `columns` 里的数据值都需要指定 `key` 值。对于 `dataSource` 默认将每列数据的 `key` 属性作为唯一的标识。 - -如果你的数据没有这个属性,务必使用 `rowKey` 来指定数据列的主键。若没有指定,控制台会出现缺少 key 的提示,表格组件也会出现各类奇怪的错误。 - -```jsx -// 比如你的数据主键是 uid -return
    ; -// 或 -return
    record.uid} />; -``` diff --git a/components/table/interface.js b/components/table/interface.js index 8b61384c4..b8c3e0ea8 100644 --- a/components/table/interface.js +++ b/components/table/interface.js @@ -21,6 +21,7 @@ export const ColumnProps = { customCell: PropTypes.func, customHeaderCell: PropTypes.func, align: PropTypes.oneOf(['left', 'right', 'center']), + ellipsis: PropTypes.bool, filters: PropTypes.arrayOf(ColumnFilterItem), // onFilter: (value: any, record: T) => PropTypes.bool, filterMultiple: PropTypes.bool, @@ -35,6 +36,7 @@ export const ColumnProps = { fixed: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['left', 'right'])]), filterIcon: PropTypes.any, filteredValue: PropTypes.array, + defaultFilteredValue: PropTypes.array, sortOrder: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['ascend', 'descend'])]), sortDirections: PropTypes.array, // children?: ColumnProps[]; @@ -65,6 +67,8 @@ export const TableLocale = PropTypes.shape({ selectAll: PropTypes.any, selectInvert: PropTypes.any, sortTitle: PropTypes.string, + expand: PropTypes.string, + collapse: PropTypes.string, }).loose; export const RowSelectionType = PropTypes.oneOf(['checkbox', 'radio']); @@ -128,6 +132,8 @@ export const TableProps = { childrenColumnName: PropTypes.oneOfType([PropTypes.array, PropTypes.string]), bodyStyle: PropTypes.any, sortDirections: PropTypes.array, + tableLayout: PropTypes.string, + getPopupContainer: PropTypes.func, expandIcon: PropTypes.func, // className?: PropTypes.string, // style?: React.CSSProperties; diff --git a/components/table/style/index.js b/components/table/style/index.js index 3d02361cd..c1ff86a1a 100644 --- a/components/table/style/index.js +++ b/components/table/style/index.js @@ -2,6 +2,7 @@ import '../../style/index.less'; import './index.less'; // style dependencies +// deps-lint-skip: menu import '../../empty/style'; import '../../radio/style'; import '../../checkbox/style'; diff --git a/components/table/style/index.less b/components/table/style/index.less index 101a985b7..300a3e4f6 100644 --- a/components/table/style/index.less +++ b/components/table/style/index.less @@ -1,10 +1,11 @@ -@import '../../style/themes/default'; +@import '../../style/themes/index'; @import '../../style/mixins/index'; @table-prefix-cls: ~'@{ant-prefix}-table'; @table-header-icon-color: #bfbfbf; @table-header-sort-active-bg: darken(@table-header-bg, 3%); @table-header-filter-active-bg: darken(@table-header-sort-active-bg, 5%); +@table-selection-column-width: 60px; .@{table-prefix-cls}-wrapper { .clearfix; @@ -12,6 +13,7 @@ .@{table-prefix-cls} { .reset-component; + position: relative; clear: both; @@ -20,14 +22,23 @@ } &-empty &-body { - overflow: auto !important; + // https://github.com/ant-design/ant-design/issues/11135 + overflow-x: auto !important; + // https://github.com/ant-design/ant-design/issues/17175 + overflow-y: hidden !important; } + // https://github.com/ant-design/ant-design/issues/17611 table { width: 100%; text-align: left; border-radius: @table-border-radius-base @table-border-radius-base 0 0; - border-collapse: collapse; + border-collapse: separate; + border-spacing: 0; + } + + &-layout-fixed table { + table-layout: fixed; } &-thead > tr > th { @@ -38,7 +49,7 @@ border-bottom: @border-width-base @border-style-base @border-color-split; transition: background 0.3s ease; - &[colspan] { + &[colspan]:not([colspan='1']) { text-align: center; } @@ -69,30 +80,44 @@ } .@{table-prefix-cls}-column-sorter { - position: absolute; - top: 50%; - right: 6px; - width: 14px; - height: @font-size-lg + 1px; - margin-top: -(@font-size-lg + 1px) / 2; - color: @table-header-icon-color; - text-align: center; - transition: all 0.3s; + display: table-cell; + vertical-align: middle; - &-up, - &-down { - .iconfont-size-under-12px(11px); - display: block; - height: 4px; - line-height: 4px; + .@{table-prefix-cls}-column-sorter-inner { + height: 1em; + margin-top: 0.35em; + margin-left: 0.57142857em; + color: @table-header-icon-color; + line-height: 1em; + text-align: center; transition: all 0.3s; - &.on { - color: @primary-color; - } - } - &-down { - margin-top: 4px; + .@{table-prefix-cls}-column-sorter-up, + .@{table-prefix-cls}-column-sorter-down { + .iconfont-size-under-12px(11px); + + display: block; + height: 1em; + line-height: 1em; + transition: all 0.3s; + &.on { + color: @primary-color; + } + } + + &-full { + margin-top: -0.15em; + + .@{table-prefix-cls}-column-sorter-up, + .@{table-prefix-cls}-column-sorter-down { + height: 0.5em; + line-height: 0.5em; + } + + .@{table-prefix-cls}-column-sorter-down { + margin-top: 0.125em; + } + } } } @@ -103,6 +128,9 @@ -webkit-background-clip: border-box; // For Chrome extra space: https://github.com/ant-design/ant-design/issues/14926 &.@{table-prefix-cls}-column-has-filters { + // https://github.com/ant-design/ant-design/issues/12650 + padding-right: 30px !important; + .@{iconfont-css-prefix}-filter, .@{table-prefix-cls}-filter-icon { &.@{table-prefix-cls}-filter-open { @@ -110,7 +138,7 @@ background: @table-header-filter-active-bg; } } - // Very complicated styles logic but neccessary + // Very complicated styles logic but necessary &:hover { .@{iconfont-css-prefix}-filter, .@{table-prefix-cls}-filter-icon { @@ -141,39 +169,38 @@ } } } - - // https://github.com/ant-design/ant-design/issues/12650 - &.@{table-prefix-cls}-column-has-sorters, - &.@{table-prefix-cls}-column-has-filters { - padding-right: 30px !important; - } - - &.@{table-prefix-cls}-column-has-sorters.@{table-prefix-cls}-column-has-filters { - padding-right: 54px !important; - } } - .@{table-prefix-cls}-column-sorters { - > *:not(.@{table-prefix-cls}-column-sorter) { - position: relative; - } - &::before { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - background: transparent; - transition: all 0.3s; - content: ''; - } - &:hover::before { - background: rgba(0, 0, 0, 0.04); - } - } + .@{table-prefix-cls}-header-column { + display: inline-block; + max-width: 100%; + vertical-align: top; - &.@{table-prefix-cls}-column-has-filters .@{table-prefix-cls}-column-sorter { - right: 28px + 6px; + .@{table-prefix-cls}-column-sorters { + display: table; + + > .@{table-prefix-cls}-column-title { + display: table-cell; + vertical-align: middle; + } + + > *:not(.@{table-prefix-cls}-column-sorter) { + position: relative; + } + &::before { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: transparent; + transition: all 0.3s; + content: ''; + } + &:hover::before { + background: rgba(0, 0, 0, 0.04); + } + } } &.@{table-prefix-cls}-column-has-sorters { @@ -207,10 +234,23 @@ transition: all 0.3s, height 0s; &.@{table-prefix-cls}-row-hover, &:hover { - &:not(.@{table-prefix-cls}-expanded-row) > td { + &:not(.@{table-prefix-cls}-expanded-row):not(.@{table-prefix-cls}-row-selected) > td { background: @table-row-hover-bg; } } + &.@{table-prefix-cls}-row-selected > td { + &.@{table-prefix-cls}-column-sort { + background: @table-body-selected-sort-bg; + } + } + &:hover { + &.@{table-prefix-cls}-row-selected > td { + background: @table-selected-row-hover-bg; + &.@{table-prefix-cls}-column-sort { + background: @table-body-selected-sort-bg; + } + } + } } &-thead > tr:hover { @@ -220,7 +260,8 @@ &-footer { position: relative; padding: @table-padding-vertical @table-padding-horizontal; - background: @table-header-bg; + color: @table-footer-color; + background: @table-footer-bg; border-top: @border-width-base @border-style-base @border-color-split; border-radius: 0 0 @table-border-radius-base @table-border-radius-base; &::before { @@ -229,7 +270,7 @@ left: 0; width: 100%; height: 1px; - background: @table-header-bg; + background: @table-footer-bg; content: ''; } } @@ -253,8 +294,8 @@ &-title + &-content { position: relative; - overflow: hidden; border-radius: @table-border-radius-base @table-border-radius-base 0 0; + .@{table-prefix-cls}-bordered & { &, table, @@ -277,6 +318,7 @@ } &-tbody > tr.@{table-prefix-cls}-row-selected td { + color: @table-selected-row-color; background: @table-selected-row-bg; } @@ -291,20 +333,7 @@ &-thead > tr > th, &-tbody > tr > td { padding: @table-padding-vertical @table-padding-horizontal; - } - - &-thead > tr > th.@{table-prefix-cls}-selection-column-custom { - .@{table-prefix-cls}-selection { - margin-right: -15px; - } - } - - &-thead > tr > th.@{table-prefix-cls}-selection-column, - &-tbody > tr > td.@{table-prefix-cls}-selection-column { - text-align: center; - .@{ant-prefix}-radio-wrapper { - margin-right: 0; - } + overflow-wrap: break-word; } &-expand-icon-th, @@ -386,28 +415,20 @@ .@{table-prefix-cls}-tbody > tr > td { border-right: @border-width-base @border-style-base @border-color-split; } - - .@{table-prefix-cls}-title + .@{table-prefix-cls}-content { - .@{table-prefix-cls}-fixed-left, - .@{table-prefix-cls}-fixed-right { - border-radius: 0; - } - } } &-placeholder { position: relative; z-index: 1; + margin-top: -1px; padding: @table-padding-vertical @table-padding-horizontal; - color: @text-color-secondary; + color: @disabled-color; font-size: @font-size-base; text-align: center; background: @component-background; + border-top: @border-width-base @border-style-base @border-color-split; border-bottom: @border-width-base @border-style-base @border-color-split; border-radius: 0 0 @border-radius-base @border-radius-base; - .@{iconfont-css-prefix} { - margin-right: 4px; - } } &-pagination.@{ant-prefix}-pagination { @@ -524,15 +545,26 @@ &-row { &-expand-icon { + .operation-unit(); + display: inline-block; width: 17px; height: 17px; - line-height: 14px; + color: inherit; + line-height: 13px; text-align: center; background: @component-background; border: @border-width-base @border-style-base @border-color-split; - cursor: pointer; + border-radius: @border-radius-sm; + outline: none; + transition: all 0.3s; user-select: none; + + &:focus, + &:hover, + &:active { + border-color: currentColor; + } } &-expanded::after { @@ -550,8 +582,20 @@ } } - &[class*='@{table-prefix-cls}-row-level-0'] .@{table-prefix-cls}-selection-column > span { - display: inline-block; + &-cell-ellipsis, + &-cell-ellipsis .@{table-prefix-cls}-column-title { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + + &-cell-ellipsis .@{table-prefix-cls}-column-title { + display: block; + } + + &-cell-break-word { + word-wrap: break-word; + word-break: break-word; } } @@ -574,12 +618,15 @@ overflow: auto; overflow-x: hidden; table { - width: auto; min-width: 100%; // https://github.com/ant-design/ant-design/issues/14545 - .@{table-prefix-cls}-fixed-columns-in-body { - visibility: hidden; + // https://github.com/ant-design/ant-design/issues/19491 + .@{table-prefix-cls}-fixed-columns-in-body:not([colspan]) { + color: transparent; + & > * { + visibility: hidden; + } } } } @@ -604,6 +651,40 @@ // Workaround for additional scroll bar on the table header // https://github.com/ant-design/ant-design/issues/6515#issuecomment-419634369 opacity: 0.9999; + + &::-webkit-scrollbar { + border: 1px solid @border-color-split; + border-width: 0 0 1px 0; + } + } + + &-hide-scrollbar { + // https://github.com/ant-design/ant-design/issues/4637 + // https://stackoverflow.com/a/54101063 + // https://github.com/react-component/table/pull/333 + scrollbar-color: transparent transparent; + min-width: unset; + + &::-webkit-scrollbar { + // set min width to window chrome scrollbar + // https://github.com/ant-design/ant-design/issues/19952#issuecomment-559367149 + min-width: inherit; + background-color: transparent; + } + } + + // optimize header style of borderd table after hide extra scrollbar + &-bordered&-fixed-header &-scroll &-header { + &::-webkit-scrollbar { + border: 1px solid @border-color-split; + border-width: 1px 1px 1px 0; + } + &.@{table-prefix-cls}-hide-scrollbar + .@{table-prefix-cls}-thead + > tr:only-child + > th:last-child { + border-right-color: transparent; + } } &-fixed-left, @@ -673,6 +754,49 @@ &&-scroll-position-right &-fixed-right { box-shadow: none; } + + // ========================== Row Selection ========================== + colgroup { + > col.@{table-prefix-cls}-selection-col { + width: @table-selection-column-width; + } + } + + &-thead > tr > th.@{table-prefix-cls}-selection-column-custom { + .@{table-prefix-cls}-selection { + margin-right: -15px; + } + } + + &-thead > tr > th.@{table-prefix-cls}-selection-column, + &-tbody > tr > td.@{table-prefix-cls}-selection-column { + text-align: center; + + .@{ant-prefix}-radio-wrapper { + margin-right: 0; + } + } + + &-row[class*='@{table-prefix-cls}-row-level-0'] .@{table-prefix-cls}-selection-column > span { + display: inline-block; + } +} + +.@{table-prefix-cls}-filter-dropdown, +.@{table-prefix-cls}-filter-dropdown-submenu { + .@{ant-prefix}-checkbox-wrapper + span { + padding-left: 8px; + } +} + +/** +* Another fix of Firefox: +*/ +@supports (-moz-appearance: meterbar) { + // https://github.com/ant-design/ant-design/issues/12628 + .@{table-prefix-cls}-thead > tr > th.@{table-prefix-cls}-column-has-actions { + background-clip: padding-box; + } } @import './size'; diff --git a/components/table/style/size.less b/components/table/style/size.less index b591d0b56..edea6e15c 100644 --- a/components/table/style/size.less +++ b/components/table/style/size.less @@ -5,7 +5,7 @@ .@{table-prefix-cls}-middle { > .@{table-prefix-cls}-title, - > .@{table-prefix-cls}-footer { + > .@{table-prefix-cls}-content > .@{table-prefix-cls}-footer { padding: @table-padding-vertical-md @table-padding-horizontal-md; } > .@{table-prefix-cls}-content { @@ -31,7 +31,8 @@ } tr.@{table-prefix-cls}-expanded-row td > .@{table-prefix-cls}-wrapper { - margin: -@table-padding-vertical-md -@table-padding-horizontal -@table-padding-vertical-md - 1px; + margin: -@table-padding-vertical-md -@table-padding-horizontal / 2 -@table-padding-vertical-md - + 1px; } } @@ -40,7 +41,7 @@ border-radius: @table-border-radius-base; > .@{table-prefix-cls}-title, - > .@{table-prefix-cls}-footer { + > .@{table-prefix-cls}-content > .@{table-prefix-cls}-footer { padding: @table-padding-vertical-sm @table-padding-horizontal-sm; } @@ -49,6 +50,14 @@ border-bottom: @border-width-base @border-style-base @border-color-split; } + > .@{table-prefix-cls}-content > .@{table-prefix-cls}-footer { + background-color: transparent; + border-top: @border-width-base @border-style-base @border-color-split; + &::before { + background-color: transparent; + } + } + > .@{table-prefix-cls}-content { > .@{table-prefix-cls}-body { margin: 0 @table-padding-horizontal-sm; @@ -74,7 +83,9 @@ padding: @table-padding-vertical-sm @table-padding-horizontal-sm; } > .@{table-prefix-cls}-thead > tr > th { - background-color: transparent; + background-color: @table-header-bg-sm; + } + > .@{table-prefix-cls}-thead > tr { border-bottom: @border-width-base @border-style-base @border-color-split; } > .@{table-prefix-cls}-thead > tr > th.@{table-prefix-cls}-column-sort { @@ -98,7 +109,8 @@ } .@{table-prefix-cls}-header { - background-color: @component-background; + background-color: @table-header-bg-sm; + border-radius: @table-border-radius-base @table-border-radius-base 0 0; } .@{table-prefix-cls}-placeholder, @@ -123,7 +135,6 @@ .@{table-prefix-cls}-footer { border: 0; border-top: @border-width-base @border-style-base @border-color-split; - border-right: @border-width-base @border-style-base @border-color-split; &::before { display: none; } @@ -135,7 +146,7 @@ border-left: 0; } - .@{table-prefix-cls}-thead > tr > th:last-child, + .@{table-prefix-cls}-thead > tr > th.@{table-prefix-cls}-row-cell-last, .@{table-prefix-cls}-tbody > tr > td:last-child { border-right: none; } @@ -154,6 +165,15 @@ } tr.@{table-prefix-cls}-expanded-row td > .@{table-prefix-cls}-wrapper { - margin: -@table-padding-vertical-sm -@table-padding-horizontal -@table-padding-vertical-sm - 1px; + margin: -@table-padding-vertical-sm -@table-padding-horizontal / 2 -@table-padding-vertical-sm - + 1px; + } + + // https://github.com/ant-design/ant-design/issues/19287#issuecomment-544368967 + &.@{table-prefix-cls}-fixed-header + > .@{table-prefix-cls}-content + > .@{table-prefix-cls}-scroll + > .@{table-prefix-cls}-body { + border-radius: 0 0 @table-border-radius-base @table-border-radius-base; } } diff --git a/components/table/util.js b/components/table/util.js index cd3ce403c..efd8c858f 100644 --- a/components/table/util.js +++ b/components/table/util.js @@ -63,3 +63,11 @@ export function flatFilter(tree, callback) { // }) // return columns // } + +export function generateValueMaps(items, maps = {}) { + (items || []).forEach(({ value, children }) => { + maps[value.toString()] = value; + generateValueMaps(children, maps); + }); + return maps; +} diff --git a/components/tabs/__tests__/__snapshots__/demo.test.js.snap b/components/tabs/__tests__/__snapshots__/demo.test.js.snap index a6a6ad70b..43922c31d 100644 --- a/components/tabs/__tests__/__snapshots__/demo.test.js.snap +++ b/components/tabs/__tests__/__snapshots__/demo.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/tabs/demo/basic.md correctly 1`] = ` +exports[`renders ./antdv-demo/tabs/demo/basic.md correctly 1`] = `
    @@ -32,7 +32,7 @@ exports[`renders ./components/tabs/demo/basic.md correctly 1`] = `
    `; -exports[`renders ./components/tabs/demo/card.md correctly 1`] = ` +exports[`renders ./antdv-demo/tabs/demo/card.md correctly 1`] = `
    @@ -62,7 +62,7 @@ exports[`renders ./components/tabs/demo/card.md correctly 1`] = `
    `; -exports[`renders ./components/tabs/demo/card-top.md correctly 1`] = ` +exports[`renders ./antdv-demo/tabs/demo/card-top.md correctly 1`] = `
    @@ -98,7 +98,7 @@ exports[`renders ./components/tabs/demo/card-top.md correctly 1`] = `
    `; -exports[`renders ./components/tabs/demo/custom-add-trigger.md correctly 1`] = ` +exports[`renders ./antdv-demo/tabs/demo/custom-add-trigger.md correctly 1`] = `
    @@ -139,7 +139,7 @@ exports[`renders ./components/tabs/demo/custom-add-trigger.md correctly 1`] = `
    `; -exports[`renders ./components/tabs/demo/custom-tab-bar.md correctly 1`] = ` +exports[`renders ./antdv-demo/tabs/demo/custom-tab-bar.md correctly 1`] = `
    @@ -171,7 +171,7 @@ exports[`renders ./components/tabs/demo/custom-tab-bar.md correctly 1`] = `
    `; -exports[`renders ./components/tabs/demo/disabled.md correctly 1`] = ` +exports[`renders ./antdv-demo/tabs/demo/disabled.md correctly 1`] = `
    @@ -201,7 +201,7 @@ exports[`renders ./components/tabs/demo/disabled.md correctly 1`] = `
    `; -exports[`renders ./components/tabs/demo/editable-card.md correctly 1`] = ` +exports[`renders ./antdv-demo/tabs/demo/editable-card.md correctly 1`] = `
    @@ -244,7 +244,7 @@ exports[`renders ./components/tabs/demo/editable-card.md correctly 1`] = `
    `; -exports[`renders ./components/tabs/demo/extra.md correctly 1`] = ` +exports[`renders ./antdv-demo/tabs/demo/extra.md correctly 1`] = `
    @@ -275,7 +275,7 @@ exports[`renders ./components/tabs/demo/extra.md correctly 1`] = `
    `; -exports[`renders ./components/tabs/demo/icon.md correctly 1`] = ` +exports[`renders ./antdv-demo/tabs/demo/icon.md correctly 1`] = `
    @@ -309,7 +309,7 @@ exports[`renders ./components/tabs/demo/icon.md correctly 1`] = `
    `; -exports[`renders ./components/tabs/demo/nest.md correctly 1`] = ` +exports[`renders ./antdv-demo/tabs/demo/nest.md correctly 1`] = `
    @@ -421,7 +421,7 @@ exports[`renders ./components/tabs/demo/nest.md correctly 1`] = `
    `; -exports[`renders ./components/tabs/demo/position.md correctly 1`] = ` +exports[`renders ./antdv-demo/tabs/demo/position.md correctly 1`] = `
    @@ -454,7 +454,7 @@ exports[`renders ./components/tabs/demo/position.md correctly 1`] = `
    `; -exports[`renders ./components/tabs/demo/size.md correctly 1`] = ` +exports[`renders ./antdv-demo/tabs/demo/size.md correctly 1`] = `
    @@ -487,7 +487,7 @@ exports[`renders ./components/tabs/demo/size.md correctly 1`] = `
    `; -exports[`renders ./components/tabs/demo/slide.md correctly 1`] = ` +exports[`renders ./antdv-demo/tabs/demo/slide.md correctly 1`] = `
    @@ -497,29 +497,65 @@ exports[`renders ./components/tabs/demo/slide.md correctly 1`] = `
    - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    -
    +
    -
    -
    -
    Content of tab 1
    -
    +
    -
    -
    No Data
    +
    +
    + + + + + + + +

    No Data

    @@ -2234,3 +2258,199 @@ exports[`renders ./components/transfer/demo/search.md correctly 1`] = `
    `; + +exports[`renders ./antdv-demo/transfer/demo/table-transfer.md correctly 1`] = ` +
    +
    +
    +
    14 items
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    Name +
    Tag +
    Description +
    content1description of content1
    content2description of content2
    content4description of content4
    content5description of content5
    content7description of content7
    content8description of content8
    content10description of content10
    content11description of content11
    content13description of content13
    content14description of content14
    + + + + + + + + + + +
    +
    +
    6 items
    +
    +
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    Name +
    content3
    content6
    content9
    content12
    content15
    content18
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +`; diff --git a/components/transfer/__tests__/__snapshots__/index.test.js.snap b/components/transfer/__tests__/__snapshots__/index.test.js.snap index 98bab0925..b32fec2be 100644 --- a/components/transfer/__tests__/__snapshots__/index.test.js.snap +++ b/components/transfer/__tests__/__snapshots__/index.test.js.snap @@ -4,9 +4,12 @@ exports[`Transfer should render correctly 1`] = `
    1/2 items
    -
  • -
  • -
    +
    +
      +
    • +
    • +
    +
    1 item
    -
  • +
    +
      +
    • +
    +
    `; @@ -24,7 +31,11 @@ exports[`Transfer should show sorted targetkey 1`] = `
    1 item
    -
  • a
  • +
    +
      +
    • a
    • +
    +
    2 items
    -
  • c
  • -
  • b
  • -
    +
    +
      +
    • c
    • +
    • b
    • +
    +
    `; diff --git a/components/transfer/__tests__/__snapshots__/list.test.js.snap b/components/transfer/__tests__/__snapshots__/list.test.js.snap index 4f5da4fa6..ffedae977 100644 --- a/components/transfer/__tests__/__snapshots__/list.test.js.snap +++ b/components/transfer/__tests__/__snapshots__/list.test.js.snap @@ -3,9 +3,12 @@ exports[`List should render correctly 1`] = `
    1/3
    -
  • -
  • -
  • -
    +
    +
      +
    • +
    • +
    • +
    +
    `; diff --git a/components/transfer/__tests__/index.test.js b/components/transfer/__tests__/index.test.js index f142b6a9e..f8aed71ad 100644 --- a/components/transfer/__tests__/index.test.js +++ b/components/transfer/__tests__/index.test.js @@ -3,6 +3,7 @@ import { renderToString } from '@vue/server-test-utils'; import Transfer from '..'; import Vue from 'vue'; import { asyncExpect } from '@/tests/utils'; +import mountTest from '../../../tests/shared/mountTest'; const listCommonProps = { dataSource: [ @@ -87,6 +88,7 @@ const searchTransferProps = { }; describe('Transfer', () => { + mountTest(Transfer); it('should render correctly', () => { const props = { propsData: listCommonProps, diff --git a/components/transfer/__tests__/search.test.js b/components/transfer/__tests__/search.test.js index 47309dd57..1512da2e8 100644 --- a/components/transfer/__tests__/search.test.js +++ b/components/transfer/__tests__/search.test.js @@ -108,7 +108,7 @@ describe('Search', () => { input.trigger('input'); expect(errorSpy.mock.calls[0][0]).toMatch( - 'Warning: `searchChange` in Transfer is deprecated. Please use `search` instead.', + 'Warning: [antdv: Transfer] `searchChange` in Transfer is deprecated. Please use `search` instead.', ); expect(onSearchChange.mock.calls[0][0]).toEqual('left'); expect(onSearchChange.mock.calls[0][1].target.value).toEqual('a'); diff --git a/components/transfer/demo/advanced.md b/components/transfer/demo/advanced.md deleted file mode 100644 index c947be65c..000000000 --- a/components/transfer/demo/advanced.md +++ /dev/null @@ -1,76 +0,0 @@ - -#### 高级用法 -穿梭框高级用法,可配置操作文案,可定制宽高,可对底部进行自定义渲染。 - - - -#### Advanced -You can customize the labels of the transfer buttons, the width and height of the columns, and what should be displayed in the footer. - - -```tpl - - -``` diff --git a/components/transfer/demo/basic.md b/components/transfer/demo/basic.md deleted file mode 100644 index b0551524a..000000000 --- a/components/transfer/demo/basic.md +++ /dev/null @@ -1,79 +0,0 @@ - -#### 基本用法 -最基本的用法,展示了 `dataSource`、`targetKeys`、每行的渲染函数 `render` 以及回调函数 `change` `selectChange` `scroll` 的用法。 - - - -#### Basic -The most basic usage of `Transfer` involves providing the source data and target keys arrays, plus the rendering and some callback functions. - - -```tpl - - -``` diff --git a/components/transfer/demo/custom-item.md b/components/transfer/demo/custom-item.md deleted file mode 100644 index 35c042296..000000000 --- a/components/transfer/demo/custom-item.md +++ /dev/null @@ -1,74 +0,0 @@ - -#### 自定义渲染行数据 -自定义渲染每一个 Transfer Item,可用于渲染复杂数据。 - - - -#### Custom datasource -Custom each Transfer Item, and in this way you can render a complex datasource. - - -```tpl - - -``` diff --git a/components/transfer/demo/index.vue b/components/transfer/demo/index.vue deleted file mode 100644 index 22bda1441..000000000 --- a/components/transfer/demo/index.vue +++ /dev/null @@ -1,61 +0,0 @@ - diff --git a/components/transfer/demo/large-data.md b/components/transfer/demo/large-data.md deleted file mode 100644 index 8f7143ed7..000000000 --- a/components/transfer/demo/large-data.md +++ /dev/null @@ -1,59 +0,0 @@ - -#### 大数据性能测试 -2000 条数据。 - - - -#### Performance Test -2000 items. - - -```tpl - - -``` diff --git a/components/transfer/demo/search.md b/components/transfer/demo/search.md deleted file mode 100644 index ac81e27c8..000000000 --- a/components/transfer/demo/search.md +++ /dev/null @@ -1,67 +0,0 @@ - -#### 带搜索框 -带搜索框的穿梭框,可以自定义搜索函数。 - - - -#### Search -Transfer with a search box. - - -```tpl - - -``` diff --git a/components/transfer/index.en-US.md b/components/transfer/index.en-US.md deleted file mode 100644 index 3103a4fb6..000000000 --- a/components/transfer/index.en-US.md +++ /dev/null @@ -1,37 +0,0 @@ -## API - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| dataSource | Used for setting the source data. The elements that are part of this array will be present the left column. Except the elements whose keys are included in `targetKeys` prop. | \[{key: string.isRequired,title: string.isRequired,description: string,disabled: bool}\] | \[] | -| disabled | Whether disabled transfer | boolean | false | -| filterOption | A function to determine whether an item should show in search result list | (inputValue, option): boolean | | -| footer | customize the progress dot by setting a scoped slot | slot="footer" slot-scope="props" | | -| lazy | property of vc-lazy-load for lazy rendering items. Turn off it by set to `false`. | object\|boolean | `{ height: 32, offset: 32 }` | -| listStyle | A custom CSS style used for rendering the transfer columns. | object | | -| locale | i18n text including filter, empty text, item unit, etc | object | `{ itemUnit: 'item', itemsUnit: 'items', notFoundContent: 'The list is empty', searchPlaceholder: 'Search here' }` | -| operations | A set of operations that are sorted from top to bottom. | string\[] | \['>', '<'] | -| render | The function to generate the item shown on a column. Based on an record (element of the dataSource array), this function should return a element which is generated from that record. Also, it can return a plain object with `value` and `label`, `label` is a element and `value` is for title | Function(record) | | -| selectedKeys | A set of keys of selected items. | string\[] | \[] | -| showSearch | If included, a search box is shown on each column. | boolean | false | -| targetKeys | A set of keys of elements that are listed on the right column. | string\[] | \[] | -| titles | A set of titles that are sorted from left to right. | string\[] | - | - -### events - -| Events Name | Description | Arguments | -| --- | --- | --- | -| change | A callback function that is executed when the transfer between columns is complete. | (targetKeys, direction, moveKeys): void | | -| scroll | A callback function which is executed when scroll options list | (direction, event): void | | -| search | A callback function which is executed when search field are changed | (direction: 'left'\|'right', value: string): void | - | -| selectChange | A callback function which is executed when selected items are changed. | (sourceSelectedKeys, targetSelectedKeys): void | | - -## Warning - -According the standard of Vue, the key should always be supplied directly to the elements in the array. In Transfer, the keys should be set on the elements included in `dataSource` array. By default, `key` property is used as an unique identifier. - -If there's no `key` in your data, you should use `rowKey` to specify the key that will be used for uniquely identify each element. - -```jsx -// eg. your primary key is `uid` -return ; -``` diff --git a/components/transfer/index.jsx b/components/transfer/index.jsx index 6e382ad5f..c8d670b27 100644 --- a/components/transfer/index.jsx +++ b/components/transfer/index.jsx @@ -32,7 +32,7 @@ export const TransferProps = { targetKeys: PropTypes.arrayOf(PropTypes.string), selectedKeys: PropTypes.arrayOf(PropTypes.string), render: PropTypes.func, - listStyle: PropTypes.object, + listStyle: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), operationStyle: PropTypes.object, titles: PropTypes.arrayOf(PropTypes.string), operations: PropTypes.arrayOf(PropTypes.string), @@ -43,6 +43,7 @@ export const TransferProps = { locale: PropTypes.object, rowKey: PropTypes.func, lazy: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]), + showSelectAll: PropTypes.bool, }; export const TransferLocale = { @@ -59,6 +60,7 @@ const Transfer = { dataSource: [], locale: {}, showSearch: false, + listStyle: () => {}, }), inject: { configProvider: { default: () => ConfigConsumerProps }, @@ -70,12 +72,6 @@ const Transfer = { // 'Transfer[notFoundContent] and Transfer[searchPlaceholder] will be removed, ' + // 'please use Transfer[locale] instead.', // ) - - this.separatedDataSource = - { - leftDataSource: [], - rightDataSource: [], - } | null; const { selectedKeys = [], targetKeys = [] } = this; return { leftFilter: '', @@ -112,6 +108,33 @@ const Transfer = { }, }, methods: { + getSelectedKeysName(direction) { + return direction === 'left' ? 'sourceSelectedKeys' : 'targetSelectedKeys'; + }, + + getTitles(transferLocale) { + if (this.titles) { + return this.titles; + } + return transferLocale.titles || ['', '']; + }, + + getLocale(transferLocale, renderEmpty) { + const h = this.$createElement; + // Keep old locale props still working. + const oldLocale = { + notFoundContent: renderEmpty(h, 'Transfer'), + }; + const notFoundContent = getComponentFromProp(this, 'notFoundContent'); + if (notFoundContent) { + oldLocale.notFoundContent = notFoundContent; + } + if (hasProp(this, 'searchPlaceholder')) { + oldLocale.searchPlaceholder = this.$props.searchPlaceholder; + } + + return { ...transferLocale, ...oldLocale, ...this.$props.locale }; + }, updateState() { const { sourceSelectedKeys, targetSelectedKeys } = this; this.separatedDataSource = null; @@ -136,37 +159,6 @@ const Transfer = { }); } }, - separateDataSource(props) { - if (this.separatedDataSource) { - return this.separatedDataSource; - } - - const { dataSource, rowKey, targetKeys = [] } = props; - - const leftDataSource = []; - const rightDataSource = new Array(targetKeys.length); - dataSource.forEach(record => { - if (rowKey) { - record.key = rowKey(record); - } - - // rightDataSource should be ordered by targetKeys - // leftDataSource should be ordered by dataSource - const indexOfKey = targetKeys.indexOf(record.key); - if (indexOfKey !== -1) { - rightDataSource[indexOfKey] = record; - } else { - leftDataSource.push(record); - } - }); - - this.separatedDataSource = { - leftDataSource, - rightDataSource, - }; - - return this.separatedDataSource; - }, moveTo(direction) { const { targetKeys = [], dataSource = [] } = this.$props; @@ -198,51 +190,61 @@ const Transfer = { this.moveTo('right'); }, - handleSelectChange(direction, holder) { - const { sourceSelectedKeys, targetSelectedKeys } = this; + onItemSelectAll(direction, selectedKeys, checkAll) { + const originalSelectedKeys = this.$data[this.getSelectedKeysName(direction)] || []; - if (direction === 'left') { - this.$emit('selectChange', holder, targetSelectedKeys); + let mergedCheckedKeys = []; + if (checkAll) { + // Merge current keys with origin key + mergedCheckedKeys = Array.from(new Set([...originalSelectedKeys, ...selectedKeys])); } else { - this.$emit('selectChange', sourceSelectedKeys, holder); + // Remove current keys from origin keys + mergedCheckedKeys = originalSelectedKeys.filter(key => selectedKeys.indexOf(key) === -1); } - }, - handleSelectAll(direction, filteredDataSource, checkAll) { - const originalSelectedKeys = this[this.getSelectedKeysName(direction)] || []; - const currentKeys = filteredDataSource.map(item => item.key); - // Only operate current keys from original selected keys - const newKeys1 = originalSelectedKeys.filter(key => currentKeys.indexOf(key) === -1); - const newKeys2 = [...originalSelectedKeys]; - currentKeys.forEach(key => { - if (newKeys2.indexOf(key) === -1) { - newKeys2.push(key); - } - }); - const holder = checkAll ? newKeys1 : newKeys2; - this.handleSelectChange(direction, holder); - if (!this.selectedKeys) { + this.handleSelectChange(direction, mergedCheckedKeys); + + if (!this.$props.selectedKeys) { this.setState({ - [this.getSelectedKeysName(direction)]: holder, + [this.getSelectedKeysName(direction)]: mergedCheckedKeys, }); } }, - handleLeftSelectAll(filteredDataSource, checkAll) { - this.handleSelectAll('left', filteredDataSource, checkAll); + handleSelectAll(direction, filteredDataSource, checkAll) { + this.onItemSelectAll( + direction, + filteredDataSource.map(({ key }) => key), + !checkAll, + ); }, + + // [Legacy] Old prop `body` pass origin check as arg. It's confusing. + // TODO: Remove this in next version. + handleLeftSelectAll(filteredDataSource, checkAll) { + return this.handleSelectAll('left', filteredDataSource, !checkAll); + }, + handleRightSelectAll(filteredDataSource, checkAll) { - this.handleSelectAll('right', filteredDataSource, checkAll); + return this.handleSelectAll('right', filteredDataSource, !checkAll); + }, + + onLeftItemSelectAll(selectedKeys, checkAll) { + return this.onItemSelectAll('left', selectedKeys, checkAll); + }, + + onRightItemSelectAll(selectedKeys, checkAll) { + return this.onItemSelectAll('right', selectedKeys, checkAll); }, handleFilter(direction, e) { const value = e.target.value; - this.setState({ - // add filter - [`${direction}Filter`]: value, - }); if (getListeners(this).searchChange) { - warning(false, '`searchChange` in Transfer is deprecated. Please use `search` instead.'); + warning( + false, + 'Transfer', + '`searchChange` in Transfer is deprecated. Please use `search` instead.', + ); this.$emit('searchChange', direction, e); } this.$emit('search', direction, value); @@ -256,9 +258,6 @@ const Transfer = { }, handleClear(direction) { - this.setState({ - [`${direction}Filter`]: '', - }); this.$emit('search', direction, ''); }, @@ -269,15 +268,15 @@ const Transfer = { this.handleClear('right'); }, - handleSelect(direction, selectedItem, checked) { + onItemSelect(direction, selectedKey, checked) { const { sourceSelectedKeys, targetSelectedKeys } = this; const holder = direction === 'left' ? [...sourceSelectedKeys] : [...targetSelectedKeys]; - const index = holder.indexOf(selectedItem.key); + const index = holder.indexOf(selectedKey); if (index > -1) { holder.splice(index, 1); } if (checked) { - holder.push(selectedItem.key); + holder.push(selectedKey); } this.handleSelectChange(direction, holder); @@ -288,6 +287,11 @@ const Transfer = { } }, + handleSelect(direction, selectedItem, checked) { + warning(false, 'Transfer', '`handleSelect` will be removed, please use `onSelect` instead.'); + this.onItemSelect(direction, selectedItem.key, checked); + }, + handleLeftSelect(selectedItem, checked) { return this.handleSelect('left', selectedItem, checked); }, @@ -296,6 +300,13 @@ const Transfer = { return this.handleSelect('right', selectedItem, checked); }, + onLeftItemSelect(selectedKey, checked) { + return this.onItemSelect('left', selectedKey, checked); + }, + onRightItemSelect(selectedKey, checked) { + return this.onItemSelect('right', selectedKey, checked); + }, + handleScroll(direction, e) { this.$emit('scroll', direction, e); }, @@ -307,32 +318,46 @@ const Transfer = { this.handleScroll('right', e); }, - getTitles(transferLocale) { - if (this.titles) { - return this.titles; + handleSelectChange(direction, holder) { + const { sourceSelectedKeys, targetSelectedKeys } = this; + + if (direction === 'left') { + this.$emit('selectChange', holder, targetSelectedKeys); + } else { + this.$emit('selectChange', sourceSelectedKeys, holder); } - return transferLocale.titles || ['', '']; + }, + handleListStyle(listStyle, direction) { + if (typeof listStyle === 'function') { + return listStyle({ direction }); + } + return listStyle; }, - getSelectedKeysName(direction) { - return direction === 'left' ? 'sourceSelectedKeys' : 'targetSelectedKeys'; - }, + separateDataSource() { + const { dataSource, rowKey, targetKeys = [] } = this.$props; - getLocale(transferLocale, renderEmpty) { - const h = this.$createElement; - // Keep old locale props still working. - const oldLocale = { - notFoundContent: renderEmpty(h, 'Transfer'), + const leftDataSource = []; + const rightDataSource = new Array(targetKeys.length); + dataSource.forEach(record => { + if (rowKey) { + record.key = rowKey(record); + } + + // rightDataSource should be ordered by targetKeys + // leftDataSource should be ordered by dataSource + const indexOfKey = targetKeys.indexOf(record.key); + if (indexOfKey !== -1) { + rightDataSource[indexOfKey] = record; + } else { + leftDataSource.push(record); + } + }); + + return { + leftDataSource, + rightDataSource, }; - const notFoundContent = getComponentFromProp(this, 'notFoundContent'); - if (notFoundContent) { - oldLocale.notFoundContent = notFoundContent; - } - if (hasProp(this, 'searchPlaceholder')) { - oldLocale.searchPlaceholder = this.$props.searchPlaceholder; - } - - return { ...transferLocale, ...oldLocale, ...this.$props.locale }; }, renderTransfer(transferLocale) { @@ -346,55 +371,59 @@ const Transfer = { operationStyle, filterOption, lazy, + showSelectAll, } = props; + const children = getComponentFromProp(this, 'children', {}, false); const getPrefixCls = this.configProvider.getPrefixCls; const prefixCls = getPrefixCls('transfer', customizePrefixCls); const renderEmpty = this.configProvider.renderEmpty; const locale = this.getLocale(transferLocale, renderEmpty); - const { - leftFilter, - rightFilter, - sourceSelectedKeys, - targetSelectedKeys, - $scopedSlots, - } = this; + const { sourceSelectedKeys, targetSelectedKeys, $scopedSlots } = this; const { body, footer } = $scopedSlots; const renderItem = props.render; - const { leftDataSource, rightDataSource } = this.separateDataSource(this.$props); + const { leftDataSource, rightDataSource } = this.separateDataSource(); const leftActive = targetSelectedKeys.length > 0; const rightActive = sourceSelectedKeys.length > 0; - const cls = classNames(prefixCls, disabled && `${prefixCls}-disabled`); - + const cls = classNames(prefixCls, { + [`${prefixCls}-disabled`]: disabled, + [`${prefixCls}-customize-list`]: !!children, + }); const titles = this.getTitles(locale); return (
    ', '<'] | -| render | 每行数据渲染函数,该函数的入参为 `dataSource` 中的项,返回值为 element。或者返回一个普通对象,其中 `label` 字段为 element,`value` 字段为 title | Function(record) | | -| selectedKeys | 设置哪些项应该被选中 | string\[] | \[] | -| showSearch | 是否显示搜索框 | boolean | false | -| targetKeys | 显示在右侧框数据的 key 集合 | string\[] | \[] | -| titles | 标题集合,顺序从左至右 | string\[] | \['', ''] | - -### 事件 - -| 事件名称 | 说明 | 回调参数 | -| --- | --- | --- | -| change | 选项在两栏之间转移时的回调函数 | (targetKeys, direction, moveKeys): void | | -| scroll | 选项列表滚动时的回调函数 | (direction, event): void | | -| search | 搜索框内容时改变时的回调函数 | (direction: 'left'\|'right', value: string): void | - | -| selectChange | 选中项发生改变时的回调函数 | (sourceSelectedKeys, targetSelectedKeys): void | | - -## 注意 - -按照 Vue 最新的规范,所有的组件数组最好绑定 key。在 Transfer 中,`dataSource`里的数据值需要指定 `key` 值。对于 `dataSource` 默认将每列数据的 `key` 属性作为唯一的标识。 - -如果你的数据没有这个属性,务必使用 `rowKey` 来指定数据列的主键。 - -```jsx -// 比如你的数据主键是 uid -return ; -``` diff --git a/components/transfer/list.jsx b/components/transfer/list.jsx index 01e5072be..8111509d9 100644 --- a/components/transfer/list.jsx +++ b/components/transfer/list.jsx @@ -1,15 +1,14 @@ import classNames from 'classnames'; import PropTypes from '../_util/vue-types'; -import { isValidElement, initDefaultProps } from '../_util/props-util'; +import { isValidElement, initDefaultProps, getListeners } from '../_util/props-util'; import BaseMixin from '../_util/BaseMixin'; -import getTransitionProps from '../_util/getTransitionProps'; import Checkbox from '../checkbox'; import Search from './search'; -import Item from './item'; +import defaultRenderList from './renderListBody'; import triggerEvent from '../_util/triggerEvent'; -import addEventListener from '../_util/Dom/addEventListener'; +import addEventListener from '../vc-util/Dom/addEventListener'; -function noop() {} +const defaultRender = () => null; const TransferItem = { key: PropTypes.string.isRequired, @@ -44,11 +43,26 @@ export const TransferListProps = { itemUnit: PropTypes.string, itemsUnit: PropTypes.string, body: PropTypes.any, + renderList: PropTypes.any, footer: PropTypes.any, lazy: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]), disabled: PropTypes.bool, + direction: PropTypes.string, + showSelectAll: PropTypes.bool, }; +function renderListNode(h, renderList, props) { + let bodyContent = renderList ? renderList(props) : null; + const customize = !!bodyContent; + if (!customize) { + bodyContent = defaultRenderList(h, props); + } + return { + customize, + bodyContent, + }; +} + export default { name: 'TransferList', mixins: [BaseMixin], @@ -56,35 +70,33 @@ export default { dataSource: [], titleText: '', showSearch: false, - renderItem: noop, lazy: {}, }), data() { this.timer = null; this.triggerScrollTimer = null; return { - mounted: false, + filterValue: '', }; }, - mounted() { - this.timer = setTimeout(() => { - this.setState({ - mounted: true, - }); - }, 0); - this.$nextTick(() => { - if (this.$refs.listContentWrapper) { - const listContentWrapperDom = this.$refs.listContentWrapper.$el; - this.scrollEvent = addEventListener(listContentWrapperDom, 'scroll', this.handleScroll); - } - }); - }, + // mounted() { + // this.timer = setTimeout(() => { + // this.setState({ + // mounted: true, + // }); + // }, 0); + // this.$nextTick(() => { + // if (this.$refs.listContentWrapper) { + // const listContentWrapperDom = this.$refs.listContentWrapper.$el; + // this.scrollEvent = addEventListener(listContentWrapperDom, 'scroll', this.handleScroll); + // } + // }); + // }, beforeDestroy() { - clearTimeout(this.timer); clearTimeout(this.triggerScrollTimer); - if (this.scrollEvent) { - this.scrollEvent.remove(); - } + // if (this.scrollEvent) { + // this.scrollEvent.remove(); + // } }, updated() { this.$nextTick(() => { @@ -101,23 +113,132 @@ export default { handleScroll(e) { this.$emit('scroll', e); }, - getCheckStatus(filteredDataSource) { + getCheckStatus(filteredItems) { const { checkedKeys } = this.$props; if (checkedKeys.length === 0) { return 'none'; - } else if (filteredDataSource.every(item => checkedKeys.indexOf(item.key) >= 0)) { + } + if (filteredItems.every(item => checkedKeys.indexOf(item.key) >= 0 || !!item.disabled)) { return 'all'; } return 'part'; }, + + getFilteredItems(dataSource, filterValue) { + const filteredItems = []; + const filteredRenderItems = []; + + dataSource.forEach(item => { + const renderedItem = this.renderItemHtml(item); + const { renderedText } = renderedItem; + + // Filter skip + if (filterValue && filterValue.trim() && !this.matchFilter(renderedText, item)) { + return null; + } + + filteredItems.push(item); + filteredRenderItems.push(renderedItem); + }); + + return { filteredItems, filteredRenderItems }; + }, + + getListBody( + prefixCls, + searchPlaceholder, + filterValue, + filteredItems, + notFoundContent, + bodyDom, + filteredRenderItems, + checkedKeys, + renderList, + showSearch, + disabled, + ) { + const search = showSearch ? ( +
    + +
    + ) : null; + + let listBody = bodyDom; + if (!listBody) { + let bodyNode; + + const { bodyContent, customize } = renderListNode(this.$createElement, renderList, { + props: { ...this.$props, filteredItems, filteredRenderItems, selectedKeys: checkedKeys }, + on: getListeners(this), + }); + + // We should wrap customize list body in a classNamed div to use flex layout. + if (customize) { + bodyNode =
    {bodyContent}
    ; + } else { + bodyNode = filteredItems.length ? ( + bodyContent + ) : ( +
    {notFoundContent}
    + ); + } + + listBody = ( +
    + {search} + {bodyNode} +
    + ); + } + return listBody; + }, + + getCheckBox(filteredItems, showSelectAll, disabled) { + const checkStatus = this.getCheckStatus(filteredItems); + const checkedAll = checkStatus === 'all'; + const checkAllCheckbox = showSelectAll !== false && ( + { + // Only select enabled items + this.$emit( + 'itemSelectAll', + filteredItems.filter(item => !item.disabled).map(({ key }) => key), + !checkedAll, + ); + }} + /> + ); + + return checkAllCheckbox; + }, + _handleSelect(selectedItem) { const { checkedKeys } = this.$props; const result = checkedKeys.some(key => key === selectedItem.key); this.handleSelect(selectedItem, !result); }, _handleFilter(e) { - this.handleFilter(e); - if (!e.target.value) { + const { handleFilter } = this.$props; + const { + target: { value: filterValue }, + } = e; + this.setState({ filterValue }); + handleFilter(e); + if (!filterValue) { return; } // Manually trigger scroll event for lazy search bug @@ -131,22 +252,25 @@ export default { }, 0); }, _handleClear(e) { + this.setState({ filterValue: '' }); this.handleClear(e); }, matchFilter(text, item) { - const { filter, filterOption } = this.$props; + const { filterValue } = this.$data; + const { filterOption } = this.$props; if (filterOption) { - return filterOption(filter, item); + return filterOption(filterValue, item); } - return text.indexOf(filter) >= 0; + return text.indexOf(filterValue) >= 0; }, renderItemHtml(item) { - const { renderItem = noop } = this.$props; + const { renderItem = defaultRender } = this.$props; const renderResult = renderItem(item); const isRenderResultPlain = isRenderResultPlainObject(renderResult); return { renderedText: isRenderResultPlain ? renderResult.value : renderResult, renderedEl: isRenderResultPlain ? renderResult.label : renderResult, + item, }; }, filterNull(arr) { @@ -157,21 +281,22 @@ export default { }, render() { + const { filterValue } = this.$data; const { prefixCls, dataSource, titleText, checkedKeys, - lazy, disabled, body, footer, showSearch, - filter, searchPlaceholder, notFoundContent, itemUnit, itemsUnit, + renderList, + showSelectAll, } = this.$props; // Custom Layout @@ -182,96 +307,31 @@ export default { [`${prefixCls}-with-footer`]: !!footerDom, }); - const filteredDataSource = []; - const totalDataSource = []; + // ====================== Get filtered, checked item list ====================== - const showItems = dataSource.map(item => { - const { renderedText, renderedEl } = this.renderItemHtml(item); - if (filter && filter.trim() && !this.matchFilter(renderedText, item)) { - return null; - } + const { filteredItems, filteredRenderItems } = this.getFilteredItems(dataSource, filterValue); - // all show items - totalDataSource.push(item); - if (!item.disabled) { - // response to checkAll items - filteredDataSource.push(item); - } - - const checked = checkedKeys.indexOf(item.key) >= 0; - return ( - - ); - }); + // ================================= List Body ================================= const unit = dataSource.length > 1 ? itemsUnit : itemUnit; - const search = showSearch ? ( -
    - -
    - ) : null; - const transitionName = this.mounted ? `${prefixCls}-content-item-highlight` : ''; - const transitionProps = getTransitionProps(transitionName, { - leave: noop, - }); - - const searchNotFound = showItems.every(item => item === null) && ( -
    {notFoundContent}
    - ); - const listBody = bodyDom || ( -
    - {search} - {!searchNotFound && ( - - {showItems} - - )} - {searchNotFound} -
    + const listBody = this.getListBody( + prefixCls, + searchPlaceholder, + filterValue, + filteredItems, + notFoundContent, + bodyDom, + filteredRenderItems, + checkedKeys, + renderList, + showSearch, + disabled, ); const listFooter = footerDom ?
    {footerDom}
    : null; - const checkStatus = this.getCheckStatus(filteredDataSource); - const checkedAll = checkStatus === 'all'; - const checkAllCheckbox = ( - { - this.handleSelectAll(filteredDataSource, checkedAll); - }} - /> - ); + const checkAllCheckbox = this.getCheckBox(filteredItems, showSelectAll, disabled); return (
    @@ -279,7 +339,7 @@ export default { {checkAllCheckbox} - {(checkedKeys.length > 0 ? `${checkedKeys.length}/` : '') + totalDataSource.length}{' '} + {(checkedKeys.length > 0 ? `${checkedKeys.length}/` : '') + filteredItems.length}{' '} {unit} {titleText} diff --git a/components/transfer/renderListBody.jsx b/components/transfer/renderListBody.jsx new file mode 100644 index 000000000..e58a239e6 --- /dev/null +++ b/components/transfer/renderListBody.jsx @@ -0,0 +1,108 @@ +import raf from '../_util/raf'; +import ListItem from './ListItem'; +import PropTypes from '../_util/vue-types'; +import getTransitionProps from '../_util/getTransitionProps'; +function noop() {} +const ListBody = { + name: 'ListBody', + inheritAttrs: false, + props: { + prefixCls: PropTypes.string, + filteredRenderItems: PropTypes.array.def([]), + lazy: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]), + selectedKeys: PropTypes.array, + disabled: PropTypes.bool, + }, + data() { + return { + mounted: false, + }; + }, + computed: { + itemsLength() { + return this.filteredRenderItems ? this.filteredRenderItems.length : 0; + }, + }, + watch: { + itemsLength() { + this.$nextTick(() => { + const { lazy } = this.$props; + if (lazy !== false) { + const container = this.$el; + raf.cancel(this.lazyId); + this.lazyId = raf(() => { + if (container) { + const scrollEvent = new Event('scroll', { bubbles: true }); + container.dispatchEvent(scrollEvent); + } + }); + } + }); + }, + }, + mounted() { + this.mountId = raf(() => { + this.mounted = true; + }); + }, + + beforeDestroy() { + raf.cancel(this.mountId); + raf.cancel(this.lazyId); + }, + methods: { + onItemSelect(item) { + const { selectedKeys } = this.$props; + const checked = selectedKeys.indexOf(item.key) >= 0; + this.$emit('itemSelect', item.key, !checked); + }, + onScroll(e) { + this.$emit('scroll', e); + }, + }, + render() { + const { mounted } = this.$data; + const { + prefixCls, + filteredRenderItems, + lazy, + selectedKeys, + disabled: globalDisabled, + } = this.$props; + const items = filteredRenderItems.map(({ renderedEl, renderedText, item }) => { + const { disabled } = item; + const checked = selectedKeys.indexOf(item.key) >= 0; + + return ( + + ); + }); + const transitionProps = getTransitionProps( + mounted ? `${prefixCls}-content-item-highlight` : '', + { + tag: 'ul', + nativeOn: { + scroll: this.onScroll, + }, + leave: noop, + }, + ); + return ( + + {items} + + ); + }, +}; + +export default (h, props) => ; diff --git a/components/transfer/style/customize.less b/components/transfer/style/customize.less new file mode 100644 index 000000000..632c43708 --- /dev/null +++ b/components/transfer/style/customize.less @@ -0,0 +1,62 @@ +@import './index.less'; + +@table-prefix-cls: ~'@{ant-prefix}-table'; + +.@{transfer-prefix-cls}-customize-list { + display: flex; + + .@{transfer-prefix-cls}-operation { + flex: none; + align-self: center; + } + + .@{transfer-prefix-cls}-list { + flex: auto; + width: auto; + height: auto; + min-height: @transfer-list-height; + + &-body { + &-with-search { + padding-top: 0; + } + + // Search box in customize mode do not need fix top + &-search-wrapper { + position: relative; + padding-bottom: 0; + } + + &-customize-wrapper { + padding: 12px; + } + } + } + + // =================== Hook Components =================== + .@{table-prefix-cls}-wrapper { + .@{table-prefix-cls}-small { + border: 0; + border-radius: 0; + + > .@{table-prefix-cls}-content { + // Header background color + > .@{table-prefix-cls}-body > table > .@{table-prefix-cls}-thead > tr > th { + background: @table-header-bg; + } + + .@{table-prefix-cls}-row:last-child td { + border-bottom: @border-width-base @border-style-base @border-color-split; + } + } + + .@{table-prefix-cls}-body { + margin: 0; + } + } + + .@{table-prefix-cls}-pagination.@{ant-prefix}-pagination { + margin: 16px 0 4px; + } + } +} diff --git a/components/transfer/style/index.less b/components/transfer/style/index.less index e0caae4d3..0b3b8ac9a 100644 --- a/components/transfer/style/index.less +++ b/components/transfer/style/index.less @@ -1,11 +1,17 @@ -@import '../../style/themes/default'; +@import '../../style/themes/index'; @import '../../style/mixins/index'; @import '../../checkbox/style/mixin'; +@import './customize.less'; @transfer-prefix-cls: ~'@{ant-prefix}-transfer'; +@transfer-header-vertical-padding: ( + @transfer-header-height - 1px - @font-size-base * @line-height-base + ) / 2; + .@{transfer-prefix-cls} { .reset-component; + position: relative; &-disabled { @@ -18,8 +24,8 @@ position: relative; display: inline-block; width: 180px; - height: 200px; - padding-top: 34px; + height: @transfer-list-height; + padding-top: @transfer-header-height; vertical-align: middle; border: @border-width-base @border-style-base @border-color-base; border-radius: @border-radius-base; @@ -29,12 +35,12 @@ } &-search { - padding: 0 @control-padding-horizontal-sm; + padding: 0 24px 0 @control-padding-horizontal-sm; &-action { position: absolute; - top: 4px; - right: 4px; - bottom: 4px; + top: 12px; + right: 12px; + bottom: 12px; width: 28px; color: @disabled-color; line-height: @input-height-base; @@ -57,7 +63,9 @@ top: 0; left: 0; width: 100%; - padding: 6px @control-padding-horizontal; + // border-top is on the transfer dom. We should minus 1px for this + padding: (@transfer-header-vertical-padding - 1px) @control-padding-horizontal + @transfer-header-vertical-padding; overflow: hidden; color: @text-color; background: @component-background; @@ -68,6 +76,10 @@ position: absolute; right: 12px; } + + .@{ant-prefix}-checkbox-wrapper + span { + padding-left: 8px; + } } &-body { @@ -80,12 +92,12 @@ top: 0; left: 0; width: 100%; - padding: 4px; + padding: 12px; } } &-body-with-search { - padding-top: @input-height-base + 8px; + padding-top: @input-height-base + 24px; } &-content { @@ -108,6 +120,9 @@ > span { padding-right: 0; } + &-text { + padding-left: 8px; + } } &-item:not(&-item-disabled):hover { diff --git a/components/tree-select/__tests__/__snapshots__/demo.test.js.snap b/components/tree-select/__tests__/__snapshots__/demo.test.js.snap index fa15a8390..c6bd7050e 100644 --- a/components/tree-select/__tests__/__snapshots__/demo.test.js.snap +++ b/components/tree-select/__tests__/__snapshots__/demo.test.js.snap @@ -1,19 +1,21 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/tree-select/demo/basic.md correctly 1`] = `Please select`; +exports[`renders ./antdv-demo/tree-select/demo/async.md correctly 1`] = `Please select`; -exports[`renders ./components/tree-select/demo/checkable.md correctly 1`] = ` -
    +exports[`renders ./antdv-demo/tree-select/demo/basic.md correctly 1`] = `Please select`; + +exports[`renders ./antdv-demo/tree-select/demo/checkable.md correctly 1`] = ` +
    `; -exports[`renders ./components/tree-select/demo/multiple.md correctly 1`] = ` -
    +exports[`renders ./antdv-demo/tree-select/demo/multiple.md correctly 1`] = ` +
    Please select
    `; -exports[`renders ./components/tree-select/demo/suffix.md correctly 1`] = `Please select`; +exports[`renders ./antdv-demo/tree-select/demo/suffix.md correctly 1`] = `Please select`; -exports[`renders ./components/tree-select/demo/treeData.md correctly 1`] = `Please select`; +exports[`renders ./antdv-demo/tree-select/demo/treeData.md correctly 1`] = `Please select`; diff --git a/components/tree-select/__tests__/index.test.js b/components/tree-select/__tests__/index.test.js index ca6174a1e..b185d68f3 100644 --- a/components/tree-select/__tests__/index.test.js +++ b/components/tree-select/__tests__/index.test.js @@ -1,6 +1,8 @@ import TreeSelect from '..'; import focusTest from '../../../tests/shared/focusTest'; +import mountTest from '../../../tests/shared/mountTest'; describe('TreeSelect', () => { focusTest(TreeSelect); + mountTest(TreeSelect); }); diff --git a/components/tree-select/demo/basic.md b/components/tree-select/demo/basic.md deleted file mode 100644 index a80eeabc7..000000000 --- a/components/tree-select/demo/basic.md +++ /dev/null @@ -1,53 +0,0 @@ - -#### 基本用法 -最简单的用法。 - - - -#### Basic -The most basic usage. - - -```tpl - - - -``` diff --git a/components/tree-select/demo/checkable.md b/components/tree-select/demo/checkable.md deleted file mode 100644 index 579b3f21d..000000000 --- a/components/tree-select/demo/checkable.md +++ /dev/null @@ -1,81 +0,0 @@ - -#### 可勾选 -使用勾选框实现多选功能。 - - - -#### Checkable -Multiple and checkable. - - -```tpl - - - -``` diff --git a/components/tree-select/demo/index.vue b/components/tree-select/demo/index.vue deleted file mode 100644 index dca769b62..000000000 --- a/components/tree-select/demo/index.vue +++ /dev/null @@ -1,50 +0,0 @@ - diff --git a/components/tree-select/demo/multiple.md b/components/tree-select/demo/multiple.md deleted file mode 100644 index f4afcb9b7..000000000 --- a/components/tree-select/demo/multiple.md +++ /dev/null @@ -1,61 +0,0 @@ - -#### 多选 -多选的树选择。 - - - -#### Multiple Selection -Multiple selection usage. - - -```tpl - - - -``` diff --git a/components/tree-select/demo/suffix.md b/components/tree-select/demo/suffix.md deleted file mode 100644 index 7c95fd2d1..000000000 --- a/components/tree-select/demo/suffix.md +++ /dev/null @@ -1,53 +0,0 @@ - -#### 后缀图标 -最简单的用法。 - - - -#### Suffix -The most basic usage. - - -```tpl - - - -``` diff --git a/components/tree-select/demo/treeData.md b/components/tree-select/demo/treeData.md deleted file mode 100644 index 03d628b3d..000000000 --- a/components/tree-select/demo/treeData.md +++ /dev/null @@ -1,69 +0,0 @@ - -#### 从数据直接生成 -使用 `treeData` 把 JSON 数据直接生成树结构。 - - - -#### Generate form tree data -The tree structure can be populated using `treeData` property. This is a quick and easy way to provide the tree content. - - -```tpl - - - -``` diff --git a/components/tree-select/index.en-US.md b/components/tree-select/index.en-US.md deleted file mode 100644 index cbc7c8b48..000000000 --- a/components/tree-select/index.en-US.md +++ /dev/null @@ -1,68 +0,0 @@ -## API - -### Tree props - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| allowClear | Whether allow clear | boolean | false | -| defaultValue | To set the initial selected treeNode(s). | string\|string\[] | - | -| disabled | Disabled or not | boolean | false | -| dropdownClassName | className of dropdown menu | string | - | -| dropdownMatchSelectWidth | Determine whether the dropdown menu and the select input are the same width | boolean | true | -| dropdownStyle | To set the style of the dropdown menu | object | - | -| filterTreeNode | Whether to filter treeNodes by input value. The value of `treeNodeFilterProp` is used for filtering by default. | boolean\|Function(inputValue: string, treeNode: TreeNode) (should return boolean) | Function | -| 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. | Function(triggerNode) | () => document.body | -| labelInValue | whether to embed label in value, turn the format of value from `string` to `{value: string, label: VNode, halfChecked: string[]}` | boolean | false | -| loadData | Load data asynchronously. | function(node) | - | -| maxTagCount | Max tag count to show | number | - | -| maxTagPlaceholder | Placeholder for not showing tags | slot/function(omittedValues) | - | -| multiple | Support multiple or not, will be `true` when enable `treeCheckable`. | boolean | false | -| placeholder | Placeholder of the select input | string\|slot | - | -| searchPlaceholder | Placeholder of the search input | string\|slot | - | -| searchValue(.sync) | work with `search` event to make search value controlled. | string | - | -| treeIcon | Shows the icon before a TreeNode's title. There is no default style; you must set a custom style for it if set to `true` | boolean | false | -| showCheckedStrategy | The way show selected item in box. **Default:** just show child nodes. **`TreeSelect.SHOW_ALL`:** show all checked treeNodes (include parent treeNode). **`TreeSelect.SHOW_PARENT`:** show checked treeNodes (just show parent treeNode). | enum { TreeSelect.SHOW_ALL, TreeSelect.SHOW_PARENT, TreeSelect.SHOW_CHILD } | TreeSelect.SHOW_CHILD | -| showSearch | Whether to display a search input in the dropdown menu(valid only in the single mode) | boolean | false | -| size | To set the size of the select input, options: `large` `small` | string | 'default' | -| suffixIcon | The custom suffix icon | VNode \| slot | - | -| treeCheckable | Whether to show checkbox on the treeNodes | boolean | false | -| treeCheckStrictly | Whether to check nodes precisely (in the `checkable` mode), means parent and child nodes are not associated, and it will make `labelInValue` be true | boolean | false | -| treeData | Data of the treeNodes, manual construction work is no longer needed if this property has been set(ensure the Uniqueness of each value) | array\<{ value, title, children, \[disabled, disableCheckbox, selectable] }> | \[] | -| treeDataSimpleMode | Enable simple mode of treeData. Changes the `treeData` schema to: \[{id:1, pId:0, value:'1', title:"test1",...},...] where pId is parent node's id). It is possible to replace the default `id` and `pId` keys by providing object to `treeDataSimpleMode` | false\|object\<{ id: string, pId: string, rootPId: null }> | false | -| treeDefaultExpandAll | Whether to expand all treeNodes by default | boolean | false | -| treeDefaultExpandedKeys | Default expanded treeNodes | string\[] \| number\[] | - | -| treeExpandedKeys(.sync) | Set expanded keys | string\[] \| number\[] | - | -| treeNodeFilterProp | Will be used for filtering if `filterTreeNode` returns true | string | 'value' | -| treeNodeLabelProp | Will render as content of select | string | 'title' | -| value(v-model) | To set the current selected treeNode(s). | string\|string\[] | - | - -### Events - -| Events Name | Description | Arguments | -| --- | --- | --- | -| change | A callback function, can be executed when selected treeNodes or input value change | function(value, label, extra) | -| search | A callback function, can be executed when the search input changes. | function(value: string) | -| select | A callback function, can be executed when you select a treeNode. | function(value, node, extra) | -| treeExpand | A callback function, can be executed when treeNode expanded | function(expandedKeys) | - -### Tree Methods - -| Name | Description | -| ------- | ------------ | -| blur() | remove focus | -| focus() | get focus | - -### TreeNode props - -> We recommend you to use `treeData` rather than `TreeNode`, to avoid the trouble of manual construction. - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| selectable | can be selected | boolean | true | -| disableCheckbox | Disables the checkbox of the treeNode | boolean | false | -| disabled | Disabled or not | boolean | false | -| isLeaf | Leaf node or not | boolean | false | -| key | Required property, should be unique in the tree | string \| number | - | -| title | Content showed on the treeNodes | string\|slot | '---' | -| value | Will be treated as `treeNodeFilterProp` by default, should be unique in the tree | string | - | -| scopedSlots | When using treeNodes, you can use this property to configure the properties that support the slot, such as `scopedSlots: { title: 'XXX'}` | object | - | diff --git a/components/tree-select/index.jsx b/components/tree-select/index.jsx index f3235d7e4..d65d6afa2 100644 --- a/components/tree-select/index.jsx +++ b/components/tree-select/index.jsx @@ -7,7 +7,6 @@ import { getOptionProps, getComponentFromProp, filterEmpty, - isValidElement, getListeners, } from '../_util/props-util'; import { ConfigConsumerProps } from '../config-provider'; @@ -16,7 +15,6 @@ import Base from '../base'; export { TreeData, TreeSelectProps } from './interface'; import Icon from '../icon'; import omit from 'omit.js'; -import { cloneElement } from '../_util/vnode'; const TreeSelect = { TreeNode: { ...TreeNode, name: 'ATreeSelectNode' }, @@ -39,6 +37,7 @@ const TreeSelect = { created() { warning( this.multiple !== false || !this.treeCheckable, + 'TreeSelect', '`multiple` will alway be `true` when `treeCheckable` is true', ); }, @@ -102,6 +101,8 @@ const TreeSelect = { const renderEmpty = this.configProvider.renderEmpty; const notFoundContent = getComponentFromProp(this, 'notFoundContent'); + const removeIcon = getComponentFromProp(this, 'removeIcon'); + const clearIcon = getComponentFromProp(this, 'clearIcon'); const { getPopupContainer: getContextPopupContainer } = this.configProvider; const rest = omit(restProps, [ 'inputIcon', @@ -121,27 +122,33 @@ const TreeSelect = { [`${prefixCls}-sm`]: size === 'small', }; + // showSearch: single - false, multiple - true + let { showSearch } = restProps; + if (!('showSearch' in restProps)) { + showSearch = !!(restProps.multiple || restProps.treeCheckable); + } + let checkable = getComponentFromProp(this, 'treeCheckable'); if (checkable) { checkable = ; } - const inputIcon = (suffixIcon && - (isValidElement(suffixIcon) ? cloneElement(suffixIcon) : suffixIcon)) || ( - + const inputIcon = suffixIcon || ; + + const finalRemoveIcon = removeIcon || ; + + const finalClearIcon = clearIcon || ( + ); - - const removeIcon = ; - - const clearIcon = ; const VcTreeSelectProps = { props: Object.assign( { switcherIcon: nodeProps => this.renderSwitcherIcon(prefixCls, nodeProps), inputIcon, - removeIcon, - clearIcon, + removeIcon: finalRemoveIcon, + clearIcon: finalClearIcon, ...rest, + showSearch, getPopupContainer: getPopupContainer || getContextPopupContainer, dropdownClassName: classNames(dropdownClassName, `${prefixCls}-tree-dropdown`), prefixCls, diff --git a/components/tree-select/index.zh-CN.md b/components/tree-select/index.zh-CN.md deleted file mode 100644 index 3c21d2806..000000000 --- a/components/tree-select/index.zh-CN.md +++ /dev/null @@ -1,68 +0,0 @@ -## API - -### Tree props - -| 参数 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| allowClear | 显示清除按钮 | boolean | false | -| defaultValue | 指定默认选中的条目 | string/string\[] | - | -| disabled | 是否禁用 | boolean | false | -| dropdownClassName | 下拉菜单的 className 属性 | string | - | -| dropdownMatchSelectWidth | 下拉菜单和选择器同宽 | boolean | true | -| dropdownStyle | 下拉菜单的样式 | object | - | -| filterTreeNode | 是否根据输入项进行筛选,默认用 treeNodeFilterProp 的值作为要筛选的 TreeNode 的属性值 | boolean\|Function(inputValue: string, treeNode: TreeNode) (函数需要返回 bool 值) | Function | -| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。 | Function(triggerNode) | () => document.body | -| labelInValue | 是否把每个选项的 label 包装到 value 中,会把 value 类型从 `string` 变为 `{value: string, label: VNode, halfChecked(treeCheckStrictly 时有效): string[] }` 的格式 | boolean | false | -| loadData | 异步加载数据 | function(node) | - | -| maxTagCount | 最多显示多少个 tag | number | - | -| maxTagPlaceholder | 隐藏 tag 时显示的内容 | slot/function(omittedValues) | - | -| multiple | 支持多选(当设置 treeCheckable 时自动变为 true) | boolean | false | -| placeholder | 选择框默认文字 | string\|slot | - | -| searchPlaceholder | 搜索框默认文字 | string\|slot | - | -| searchValue(.sync) | 搜索框的值,可以通过 `search` 事件获取用户输入 | string | - | -| treeIcon | 是否展示 TreeNode title 前的图标,没有默认样式,如设置为 true,需要自行定义图标相关样式 | boolean | false | -| showCheckedStrategy | 定义选中项回填的方式。`TreeSelect.SHOW_ALL`: 显示所有选中节点(包括父节点). `TreeSelect.SHOW_PARENT`: 只显示父节点(当父节点下所有子节点都选中时). 默认只显示子节点. | enum{TreeSelect.SHOW_ALL, TreeSelect.SHOW_PARENT, TreeSelect.SHOW_CHILD } | TreeSelect.SHOW_CHILD | -| showSearch | 在下拉中显示搜索框(仅在单选模式下生效) | boolean | false | -| size | 选择框大小,可选 `large` `small` | string | 'default' | -| suffixIcon | 自定义的选择框后缀图标 | VNode \| slot | - | -| treeCheckable | 显示 checkbox | boolean | false | -| treeCheckStrictly | checkable 状态下节点选择完全受控(父子节点选中状态不再关联),会使得 `labelInValue` 强制为 true | boolean | false | -| treeData | treeNodes 数据,如果设置则不需要手动构造 TreeNode 节点(value 在整个树范围内唯一) | array<{value, label, children, [disabled, disableCheckbox, selectable]}> | \[] | -| treeDataSimpleMode | 使用简单格式的 treeData,具体设置参考可设置的类型 (此时 treeData 应变为这样的数据结构: \[{id:1, pId:0, value:'1', label:"test1",...},...], `pId` 是父节点的 id) | false\|Array<{ id: string, pId: string, rootPId: null }> | false | -| treeDefaultExpandAll | 默认展开所有树节点 | boolean | false | -| treeDefaultExpandedKeys | 默认展开的树节点 | string\[] \| number\[] | - | -| treeExpandedKeys(.sync) | 设置展开的树节点 | string\[] \| number\[] | - | -| treeNodeFilterProp | 输入项过滤对应的 treeNode 属性 | string | 'value' | -| treeNodeLabelProp | 作为显示的 prop 设置 | string | 'title' | -| value(v-model) | 指定当前选中的条目 | string/string\[] | - | - -### 事件 - -| 事件名称 | 说明 | 回调参数 | -| ---------- | ---------------------- | ----------------------------- | -| change | 选中树节点时调用此函数 | function(value, label, extra) | -| search | 文本框值变化时回调 | function(value: string) | -| select | 被选中时调用 | function(value, node, extra) | -| treeExpand | 展开节点时调用 | function(expandedKeys) | - -### Tree 方法 - -| 名称 | 描述 | -| ------- | -------- | -| blur() | 移除焦点 | -| focus() | 获取焦点 | - -### TreeNode props - -> 建议使用 treeData 来代替 TreeNode,免去手工构造麻烦 - -| 参数 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| selectable | 是否可选 | boolean | true | -| disableCheckbox | 禁掉 checkbox | boolean | false | -| disabled | 是否禁用 | boolean | false | -| isLeaf | 是否是叶子节点 | boolean | false | -| key | 此项必须设置(其值在整个树范围内唯一) | string \| number | - | -| title | 树节点显示的内容 | string\|slot | '---' | -| value | 默认根据此属性值进行筛选(其值在整个树范围内唯一) | string | - | -| scopedSlots | 使用 treeData 时,可以通过该属性配置支持 slot 的属性,如 `scopedSlots: { title: 'XXX'}` | object | - | diff --git a/components/tree-select/style/index.js b/components/tree-select/style/index.js index c3f91d2d6..04ee7ce2f 100644 --- a/components/tree-select/style/index.js +++ b/components/tree-select/style/index.js @@ -2,5 +2,6 @@ import '../../style/index.less'; import './index.less'; // style dependencies +// deps-lint-skip: select import '../../select/style'; -import '../../checkbox/style'; +import '../../empty/style'; diff --git a/components/tree-select/style/index.less b/components/tree-select/style/index.less index 03dc245a5..126a40185 100644 --- a/components/tree-select/style/index.less +++ b/components/tree-select/style/index.less @@ -1,4 +1,4 @@ -@import '../../style/themes/default'; +@import '../../style/themes/index'; @import '../../style/mixins/index'; @import '../../tree/style/mixin'; @import '../../checkbox/style/mixin'; @@ -10,6 +10,7 @@ .@{select-tree-prefix-cls} { .reset-component; + margin: 0; margin-top: -4px; padding: 0 4px; @@ -35,7 +36,7 @@ padding: 3px 5px; color: @text-color; text-decoration: none; - border-radius: 2px; + border-radius: @border-radius-sm; cursor: pointer; transition: all 0.3s; &:hover { @@ -160,8 +161,12 @@ .@{select-prefix-cls}-tree-dropdown { .reset-component; .@{select-prefix-cls}-dropdown-search { + position: sticky; + top: 0; + z-index: 1; display: block; padding: 4px; + background: @component-background; .@{select-prefix-cls}-search__field__wrap { width: 100%; } diff --git a/components/tree/DirectoryTree.jsx b/components/tree/DirectoryTree.jsx index a9e3ae97e..727d13ba1 100644 --- a/components/tree/DirectoryTree.jsx +++ b/components/tree/DirectoryTree.jsx @@ -4,7 +4,12 @@ import PropTypes from '../_util/vue-types'; import warning from '../_util/warning'; import { conductExpandParent, convertTreeToEntities } from '../vc-tree/src/util'; import Tree, { TreeProps } from './Tree'; -import { calcRangeKeys, getFullKeyList } from './util'; +import { + calcRangeKeys, + getFullKeyList, + convertDirectoryKeysToNodes, + getFullKeyListByTreeData, +} from './util'; import Icon from '../icon'; import BaseMixin from '../_util/BaseMixin'; import { @@ -64,7 +69,11 @@ export default { // Expanded keys if (defaultExpandAll) { - state._expandedKeys = getFullKeyList(this.$slots.default); + if (props.treeData) { + state._expandedKeys = getFullKeyListByTreeData(props.treeData); + } else { + state._expandedKeys = getFullKeyList(this.$slots.default); + } } else if (defaultExpandParent) { state._expandedKeys = conductExpandParent(expandedKeys || defaultExpandedKeys, keyEntities); } else { @@ -125,6 +134,13 @@ export default { const { eventKey = '' } = node; const newState = {}; + + // We need wrap this event since some value is not same + const newEvent = { + ...event, + selected: true, // Directory selected always true + }; + // Windows / Mac single pick const ctrlPick = nativeEvent.ctrlKey || nativeEvent.metaKey; const shiftPick = nativeEvent.shiftKey; @@ -136,6 +152,7 @@ export default { newSelectedKeys = keys; this.lastSelectedKey = eventKey; this.cachedSelectedKeys = newSelectedKeys; + newEvent.selectedNodes = convertDirectoryKeysToNodes(children, newSelectedKeys); } else if (multiple && shiftPick) { // Shift click newSelectedKeys = Array.from( @@ -144,16 +161,18 @@ export default { ...calcRangeKeys(children, expandedKeys, eventKey, this.lastSelectedKey), ]), ); + newEvent.selectedNodes = convertDirectoryKeysToNodes(children, newSelectedKeys); } else { // Single click newSelectedKeys = [eventKey]; this.lastSelectedKey = eventKey; this.cachedSelectedKeys = newSelectedKeys; + newEvent.selectedNodes = [event.node]; } newState._selectedKeys = newSelectedKeys; this.$emit('update:selectedKeys', newSelectedKeys); - this.$emit('select', newSelectedKeys, event); + this.$emit('select', newSelectedKeys, newEvent); this.setUncontrolledState(newState); }, diff --git a/components/tree/Tree.jsx b/components/tree/Tree.jsx index 485730d0d..5292eef38 100644 --- a/components/tree/Tree.jsx +++ b/components/tree/Tree.jsx @@ -93,6 +93,7 @@ function TreeProps() { * 替换treeNode中 title,key,children字段为treeData中对应的字段 */ replaceFields: PropTypes.object, + blockNode: PropTypes.bool, }; } @@ -111,6 +112,7 @@ export default { on: animation, props: { appear: null }, }, + blockNode: false, }), inject: { configProvider: { default: () => ConfigConsumerProps }, @@ -128,32 +130,27 @@ export default { if (loading) { return ; } - if (showLine) { - if (isLeaf) { - return ; - } - return ( - - ); - } else { - const switcherCls = `${prefixCls}-switcher-icon`; - if (isLeaf) { - return null; - } else if (switcherIcon) { - const switcherOriginCls = getClass(switcherIcon[0]); - return cloneElement(switcherIcon, { - class: { - [switcherCls]: true, - }, - }); - } else { - return ; - } + + if (isLeaf) { + return showLine ? : null; } + const switcherCls = `${prefixCls}-switcher-icon`; + if (switcherIcon) { + return cloneElement(switcherIcon, { + class: { + [switcherCls]: true, + }, + }); + } + return showLine ? ( + + ) : ( + + ); }, updateTreeData(treeData) { const { $slots, $scopedSlots } = this; @@ -166,12 +163,17 @@ export default { const treeNodeProps = { ...restProps, icon: - $slots[slots.icon] || ($scopedSlots[scopedSlots.icon] && $scopedSlots[scopedSlots.icon](item)) || + $slots[slots.icon] || restProps.icon, + switcherIcon: + ($scopedSlots[scopedSlots.switcherIcon] && + $scopedSlots[scopedSlots.switcherIcon](item)) || + $slots[slots.switcherIcon] || + restProps.switcherIcon, title: - $slots[slots.title] || ($scopedSlots[scopedSlots.title] && $scopedSlots[scopedSlots.title](item)) || + $slots[slots.title] || restProps[replaceFields.title], dataRef: item, on, @@ -188,7 +190,8 @@ export default { }, render() { const props = getOptionProps(this); - const { prefixCls: customizePrefixCls, showIcon, treeNodes } = props; + const { $slots, $scopedSlots } = this; + const { prefixCls: customizePrefixCls, showIcon, treeNodes, blockNode } = props; const getPrefixCls = this.configProvider.getPrefixCls; const prefixCls = getPrefixCls('tree', customizePrefixCls); const switcherIcon = getComponentFromProp(this, 'switcherIcon'); @@ -202,13 +205,16 @@ export default { ...props, prefixCls, checkable: checkable ? : checkable, - children: filterEmpty(this.$slots.default || []), + children: filterEmpty($scopedSlots.default ? $scopedSlots.default() : $slots.default), __propsSymbol__: Symbol(), switcherIcon: nodeProps => this.renderSwitcherIcon(prefixCls, switcherIcon, nodeProps), }, on: getListeners(this), ref: 'tree', - class: !showIcon && `${prefixCls}-icon-hide`, + class: { + [`${prefixCls}-icon-hide`]: !showIcon, + [`${prefixCls}-block-node`]: blockNode, + }, }; if (treeData) { vcTreeProps.props.treeData = treeData; diff --git a/components/tree/__tests__/__snapshots__/demo.test.js.snap b/components/tree/__tests__/__snapshots__/demo.test.js.snap index c92d5eeda..1ebae9054 100644 --- a/components/tree/__tests__/__snapshots__/demo.test.js.snap +++ b/components/tree/__tests__/__snapshots__/demo.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/tree/demo/basic.md correctly 1`] = ` +exports[`renders ./antdv-demo/tree/demo/basic.md correctly 1`] = `
    • parent 1
        @@ -20,7 +20,7 @@ exports[`renders ./components/tree/demo/basic.md correctly 1`] = `
      `; -exports[`renders ./components/tree/demo/basic-controlled.md correctly 1`] = ` +exports[`renders ./antdv-demo/tree/demo/basic-controlled.md correctly 1`] = `
      • 0-0
          @@ -48,7 +48,7 @@ exports[`renders ./components/tree/demo/basic-controlled.md correctly 1`] = `
        `; -exports[`renders ./components/tree/demo/customized-icon.md correctly 1`] = ` +exports[`renders ./antdv-demo/tree/demo/customized-icon.md correctly 1`] = `
        • parent 1
            @@ -59,7 +59,7 @@ exports[`renders ./components/tree/demo/customized-icon.md correctly 1`] = `
          `; -exports[`renders ./components/tree/demo/directory.md correctly 1`] = ` +exports[`renders ./antdv-demo/tree/demo/directory.md correctly 1`] = `
          • parent 0
              @@ -76,7 +76,7 @@ exports[`renders ./components/tree/demo/directory.md correctly 1`] = `
            `; -exports[`renders ./components/tree/demo/draggable.md correctly 1`] = ` +exports[`renders ./antdv-demo/tree/demo/draggable.md correctly 1`] = `
            • 0-0
                @@ -100,7 +100,7 @@ exports[`renders ./components/tree/demo/draggable.md correctly 1`] = `
              `; -exports[`renders ./components/tree/demo/dynamic.md correctly 1`] = ` +exports[`renders ./antdv-demo/tree/demo/dynamic.md correctly 1`] = `
              • Expand to load
              • Expand to load
              • @@ -108,29 +108,39 @@ exports[`renders ./components/tree/demo/dynamic.md correctly 1`] = `
              `; -exports[`renders ./components/tree/demo/line.md correctly 1`] = ` -
                -
              • parent 1 -
                  -
                • parent 1-0 -
                    -
                  • leaf
                  • -
                  • leaf
                  • -
                  • leaf
                  • -
                  -
                • -
                • parent 1-1 - -
                • -
                • parent 1-2 - -
                • -
                -
              • -
              +exports[`renders ./antdv-demo/tree/demo/line.md correctly 1`] = ` +
              +
              + showLine:

              + showIcon:
              +
                +
              • parent 1 +
                  +
                • parent 1-0 +
                    +
                  • leaf
                  • +
                  • leaf
                  • +
                  • leaf
                  • +
                  +
                • +
                • parent 1-1 +
                    +
                  • leaf
                  • +
                  +
                • +
                • parent 1-2 +
                    +
                  • leaf
                  • +
                  • leaf
                  • +
                  +
                • +
                +
              • +
              +
              `; -exports[`renders ./components/tree/demo/replaceFields.md correctly 1`] = ` +exports[`renders ./antdv-demo/tree/demo/replaceFields.md correctly 1`] = `
              • parent 1
                  @@ -150,7 +160,7 @@ exports[`renders ./components/tree/demo/replaceFields.md correctly 1`] = `
                `; -exports[`renders ./components/tree/demo/search.md correctly 1`] = ` +exports[`renders ./antdv-demo/tree/demo/search.md correctly 1`] = `
                • @@ -175,3 +185,25 @@ exports[`renders ./components/tree/demo/search.md correctly 1`] = `
                `; + +exports[`renders ./antdv-demo/tree/demo/switcher-icon.md correctly 1`] = ` +
                  +
                • parent 1 +
                    +
                  • parent 1-0 +
                      +
                    • leaf
                    • +
                    • leaf
                    • +
                    • leaf
                    • +
                    +
                  • +
                  • parent 1-1 + +
                  • +
                  • parent 1-2 + +
                  • +
                  +
                • +
                +`; diff --git a/components/tree/demo/basic-controlled.md b/components/tree/demo/basic-controlled.md deleted file mode 100644 index eb8cda392..000000000 --- a/components/tree/demo/basic-controlled.md +++ /dev/null @@ -1,103 +0,0 @@ - -#### 受控操作示例 -受控操作示例 - - - -#### basic controlled example -basic controlled example - - -```tpl - - -``` diff --git a/components/tree/demo/basic.md b/components/tree/demo/basic.md deleted file mode 100644 index b41cdffd3..000000000 --- a/components/tree/demo/basic.md +++ /dev/null @@ -1,65 +0,0 @@ - -#### 基本用法 -最简单的用法,展示可勾选,可选中,禁用,默认展开等功能。 - - - -#### Basic -The most basic usage, tell you how to use checkable, selectable, disabled, defaultExpandKeys, and etc. - - -```tpl - - -``` diff --git a/components/tree/demo/customized-icon.md b/components/tree/demo/customized-icon.md deleted file mode 100644 index 25a64d984..000000000 --- a/components/tree/demo/customized-icon.md +++ /dev/null @@ -1,53 +0,0 @@ - -#### 自定义图标 -可以针对不同的节点定制图标。 - - - -#### Customize Icon -You can customize icons for different nodes. - - -```tpl - - -``` diff --git a/components/tree/demo/directory.md b/components/tree/demo/directory.md deleted file mode 100644 index 1d7e91ce0..000000000 --- a/components/tree/demo/directory.md +++ /dev/null @@ -1,36 +0,0 @@ - -#### 目录 -内置的目录树,`multiple` 模式支持 `ctrl(Windows)` / `command(Mac)` 复选。 - - - -#### Directory -Built-in directory tree. `multiple` support `ctrl(Windows)` / `command(Mac)` selection. - - -```tpl - - -``` diff --git a/components/tree/demo/draggable.md b/components/tree/demo/draggable.md deleted file mode 100644 index 7920ceda1..000000000 --- a/components/tree/demo/draggable.md +++ /dev/null @@ -1,123 +0,0 @@ - -#### 拖动示例 -将节点拖拽到其他节点内部或前后。 - - - -#### draggable -Drag treeNode to insert after the other treeNode or insert into the other parent TreeNode. - - -```tpl - - - -``` diff --git a/components/tree/demo/dynamic.md b/components/tree/demo/dynamic.md deleted file mode 100644 index e451f26ec..000000000 --- a/components/tree/demo/dynamic.md +++ /dev/null @@ -1,47 +0,0 @@ - -#### 异步数据加载 -点击展开节点,动态加载数据。 - - - -#### load data asynchronously -To load data asynchronously when click to expand a treeNode. - - -```tpl - - - -``` diff --git a/components/tree/demo/index.vue b/components/tree/demo/index.vue deleted file mode 100644 index 53cb48a10..000000000 --- a/components/tree/demo/index.vue +++ /dev/null @@ -1,58 +0,0 @@ - diff --git a/components/tree/demo/line.md b/components/tree/demo/line.md deleted file mode 100644 index 35fc2c91a..000000000 --- a/components/tree/demo/line.md +++ /dev/null @@ -1,41 +0,0 @@ - -#### 连接线 -带连接线的树。 - - - -#### Tree With Line -Tree With Line - - -```tpl - - - -``` diff --git a/components/tree/demo/replaceFields.md b/components/tree/demo/replaceFields.md deleted file mode 100644 index b558fac19..000000000 --- a/components/tree/demo/replaceFields.md +++ /dev/null @@ -1,67 +0,0 @@ - -#### 自定义TreeNode字段 -替换treeNode中 title,key,children字段为treeData中对应的字段 - - - -#### ReplaceFields -Replace the title,key and children fields in treeNode with the corresponding fields in treeData. - - -```tpl - - -``` diff --git a/components/tree/demo/search.md b/components/tree/demo/search.md deleted file mode 100644 index abfc51665..000000000 --- a/components/tree/demo/search.md +++ /dev/null @@ -1,122 +0,0 @@ - -#### 可搜索 -可搜索的树。 - - - -#### Searchable -Searchable Tree. - - -```tpl - - - -``` diff --git a/components/tree/index.en-US.md b/components/tree/index.en-US.md deleted file mode 100644 index 4b98bb33d..000000000 --- a/components/tree/index.en-US.md +++ /dev/null @@ -1,75 +0,0 @@ -## API - -### Tree props - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| treeData | treeNode of tree, please use `treeNodes` before v1.1.4 | array | - | -| replaceFields | Replace the title,key and children fields in treeNode with the corresponding fields in treeData | object | { children:'children', title:'title', key:'key' } | -| autoExpandParent | Whether to automatically expand a parent treeNode | boolean | true | -| checkable | Adds a `Checkbox` before the treeNodes | boolean | false | -| checkedKeys(v-model) | (Controlled) Specifies the keys of the checked treeNodes (PS: When this specifies the key of a treeNode which is also a parent treeNode, all the children treeNodes of will be checked; and vice versa, when it specifies the key of a treeNode which is a child treeNode, its parent treeNode will also be checked. When `checkable` and `checkStrictly` is true, its object has `checked` and `halfChecked` property. Regardless of whether the child or parent treeNode is checked, they won't impact each other. | string\[] \| number\[] \| {checked: string\[] \| number\[], halfChecked: string\[] \| number\[]} | \[] | -| checkStrictly | Check treeNode precisely; parent treeNode and children treeNodes are not associated | boolean | false | -| defaultCheckedKeys | Specifies the keys of the default checked treeNodes | string\[] \| number\[] | \[] | -| defaultExpandAll | Whether to expand all treeNodes by default | boolean | false | -| defaultExpandedKeys | Specify the keys of the default expanded treeNodes | string\[] \| number\[] | \[] | -| defaultExpandParent | auto expand parent treeNodes when init | bool | true | -| defaultSelectedKeys | Specifies the keys of the default selected treeNodes | string\[] \| number\[] | \[] | -| disabled | whether disabled the tree | bool | false | -| draggable | Specifies whether this Tree is draggable (IE > 8) | boolean | false | -| expandedKeys(.sync) | (Controlled) Specifies the keys of the expanded treeNodes | string\[] \| number\[] | \[] | -| filterTreeNode | Defines a function to filter (highlight) treeNodes. When the function returns `true`, the corresponding treeNode will be highlighted | function(node) | - | -| loadData | Load data asynchronously | function(node) | - | -| loadedKeys | (Controlled) Set loaded tree nodes. Need work with `loadData` | string\[] \| number\[] | \[] | -| multiple | Allows selecting multiple treeNodes | boolean | false | -| selectedKeys(.sync) | (Controlled) Specifies the keys of the selected treeNodes | string\[] \| number\[] | - | -| showIcon | Shows the icon before a TreeNode's title. There is no default style; you must set a custom style for it if set to `true` | boolean | false | -| switcherIcon | customize collapse/expand icon of tree node | slot | - | -| showLine | Shows a connecting line | boolean | false | - -### Events - -| Events Name | Description | Arguments | -| --- | --- | --- | -| check | Callback function for when the onCheck event occurs | function(checkedKeys, e:{checked: bool, checkedNodes, node, event}) | -| dragend | Callback function for when the onDragEnd event occurs | function({event, node}) | -| dragenter | Callback function for when the onDragEnter event occurs | function({event, node, expandedKeys}) | -| dragleave | Callback function for when the onDragLeave event occurs | function({event, node}) | -| dragover | Callback function for when the onDragOver event occurs | function({event, node}) | -| dragstart | Callback function for when the onDragStart event occurs | function({event, node}) | -| drop | Callback function for when the onDrop event occurs | function({event, node, dragNode, dragNodesKeys}) | -| expand | Callback function for when a treeNode is expanded or collapsed | function(expandedKeys, {expanded: bool, node}) | -| load | Callback function for when a treeNode is loaded | function(loadedKeys, {event, node}) | -| rightClick | Callback function for when the user right clicks a treeNode | function({event, node}) | -| select | Callback function for when the user clicks a treeNode | function(selectedKeys, e:{selected: bool, selectedNodes, node, event}) | - -### TreeNode props - -One of the Tree `treeNode` prop for describing the tree's node, TreeNode has the same API. - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| class | className | string | - | -| style | style | string\|object | - | -| disableCheckbox | Disables the checkbox of the treeNode | boolean | false | -| disabled | Disables the treeNode | boolean | false | -| icon | customize icon. When you pass component, whose render will receive full TreeNode props as component props | slot\|slot-scope | - | -| isLeaf | Determines if this is a leaf node(effective when `loadData` is specified) | boolean | false | -| key | Used with (default)ExpandedKeys / (default)CheckedKeys / (default)SelectedKeys. P.S.: It must be unique in all of treeNodes of the tree! | string \| number | internal calculated position of treeNode | -| selectable | Set whether the treeNode can be selected | boolean | true | -| title | Title | string\|slot\|slot-scope | '---' | -| slots | When using treeNodes, you can use this property to configure the properties that support the slot, such as `slots: { title: 'XXX'}` | object | - | -| scopedSlots | When using treeNodes, you can use this property to configure the properties that support the slot-scope, such as `scopedSlots: { title: 'XXX'}` | object | - | -| on | When using treeNodes, you can use this property to configure the events, such as `on: { click: () => {}}` | object | - | - -### DirectoryTree props - -| Property | Description | Type | Default | -| ------------ | ------------------------------------------------------------- | ------ | ------- | -| expandAction | Directory open logic, optional `false` `'click'` `'dblclick'` | string | click | - -## FAQ - -### How to hide file icon when use showLine? - -File icon realize by using switcherIcon. You can overwrite the style to hide it diff --git a/components/tree/index.zh-CN.md b/components/tree/index.zh-CN.md deleted file mode 100644 index 7bf576e83..000000000 --- a/components/tree/index.zh-CN.md +++ /dev/null @@ -1,75 +0,0 @@ -## API - -### Tree props - -| 参数 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| treeData | 节点的配置描述,具体项见下表, 1.1.4 之前的版本使用`treeNodes` | array | -- | -| replaceFields | 替换 treeNode 中 title,key,children 字段为 treeData 中对应的字段 | object | {children:'children', title:'title', key:'key' } | -| autoExpandParent | 是否自动展开父节点 | boolean | true | -| checkable | 节点前添加 Checkbox 复选框 | boolean | false | -| checkedKeys(v-model) | (受控)选中复选框的树节点(注意:父子节点有关联,如果传入父节点 key,则子节点自动选中;相应当子节点 key 都传入,父节点也自动选中。当设置`checkable`和`checkStrictly`,它是一个有`checked`和`halfChecked`属性的对象,并且父子节点的选中与否不再关联 | string\[] \| number\[] \| {checked: string\[] \| number\[], halfChecked: string\[] \| number\[]} | \[] | -| checkStrictly | checkable 状态下节点选择完全受控(父子节点选中状态不再关联) | boolean | false | -| defaultCheckedKeys | 默认选中复选框的树节点 | string\[] \| number\[] | \[] | -| defaultExpandAll | 默认展开所有树节点 | boolean | false | -| defaultExpandedKeys | 默认展开指定的树节点 | string\[] \| number\[] | \[] | -| defaultExpandParent | 默认展开父节点 | bool | true | -| defaultSelectedKeys | 默认选中的树节点 | string\[] \| number\[] | \[] | -| disabled | 将树禁用 | bool | false | -| draggable | 设置节点可拖拽 | boolean | false | -| expandedKeys(.sync) | (受控)展开指定的树节点 | string\[] \| number\[] | \[] | -| filterTreeNode | 按需筛选树节点(高亮),返回 true | function(node) | - | -| loadData | 异步加载数据 | function(node) | - | -| loadedKeys | (受控)已经加载的节点,需要配合 `loadData` 使用 | string\[] \| number\[] | \[] | -| multiple | 支持点选多个节点(节点本身) | boolean | false | -| selectedKeys(.sync) | (受控)设置选中的树节点 | string\[] \| number\[] | - | -| showIcon | 是否展示 TreeNode title 前的图标,没有默认样式,如设置为 true,需要自行定义图标相关样式 | boolean | false | -| switcherIcon | 自定义树节点的展开/折叠图标 | slot | - | -| showLine | 是否展示连接线 | boolean | false | - -### 事件 - -| 事件名称 | 说明 | 回调参数 | -| --- | --- | --- | -| check | 点击复选框触发 | function(checkedKeys, e:{checked: bool, checkedNodes, node, event}) | -| dragend | dragend 触发时调用 | function({event, node}) | -| dragenter | dragenter 触发时调用 | function({event, node, expandedKeys}) | -| dragleave | dragleave 触发时调用 | function({event, node}) | -| dragover | dragover 触发时调用 | function({event, node}) | -| dragstart | 开始拖拽时调用 | function({event, node}) | -| drop | drop 触发时调用 | function({event, node, dragNode, dragNodesKeys}) | -| expand | 展开/收起节点时触发 | function(expandedKeys, {expanded: bool, node}) | -| load | 节点加载完毕时触发 | function(loadedKeys, {event, node}) | -| rightClick | 响应右键点击 | function({event, node}) | -| select | 点击树节点触发 | function(selectedKeys, e:{selected: bool, selectedNodes, node, event}) | - -### TreeNode props - -结点描述数据对象,是 treeNodes 中的一项,TreeNode 使用相同的 API。 - -| 参数 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| class | 节点的 class | string | - | -| style | 节点的 style | string\|object | - | -| disableCheckbox | 禁掉 checkbox | boolean | false | -| disabled | 禁掉响应 | boolean | false | -| icon | 自定义图标。可接收组件,props 为当前节点 props | slot\|slot-scope | - | -| isLeaf | 设置为叶子节点(设置了`loadData`时有效) | boolean | false | -| key | 被树的 (default)ExpandedKeys / (default)CheckedKeys / (default)SelectedKeys 属性所用。注意:整个树范围内的所有节点的 key 值不能重复! | string \| number | 内部计算出的节点位置 | -| selectable | 设置节点是否可被选中 | boolean | true | -| title | 标题 | string\|slot\|slot-scope | '---' | -| slots | 使用 treeNodes 时,可以通过该属性配置支持 slot 的属性,如 `slots: { title: 'XXX'}` | object | - | -| scopedSlots | 使用 columns 时,可以通过该属性配置支持 slot-scope 的属性,如 `scopedSlots: { title: 'XXX'}` | object | - | -| on | 事件对象,仅在 treeNodes 使用方式中生效,如`{click: () => {}}` | object | '---' | - -### DirectoryTree props - -| 参数 | 说明 | 类型 | 默认值 | -| ------------ | ------------------------------------------------- | ------ | ------ | -| expandAction | 目录展开逻辑,可选 `false` `'click'` `'dblclick'` | string | click | - -## FAQ - -### 在 showLine 时,如何隐藏子节点图标? - -文件图标通过 switcherIcon 来实现,如果不需要你可以覆盖对应的样式 diff --git a/components/tree/style/directory.less b/components/tree/style/directory.less index e11a78698..91caf33c0 100644 --- a/components/tree/style/directory.less +++ b/components/tree/style/directory.less @@ -1,4 +1,4 @@ -@import '../../style/themes/default'; +@import '../../style/themes/index'; @tree-prefix-cls: ~'@{ant-prefix}-tree'; diff --git a/components/tree/style/index.js b/components/tree/style/index.js index 68627a2a9..3a3ab0de5 100644 --- a/components/tree/style/index.js +++ b/components/tree/style/index.js @@ -1,5 +1,2 @@ import '../../style/index.less'; import './index.less'; - -// style dependencies -import '../../checkbox/style'; diff --git a/components/tree/style/index.less b/components/tree/style/index.less index 2f63f55c6..9321463a3 100644 --- a/components/tree/style/index.less +++ b/components/tree/style/index.less @@ -1,4 +1,4 @@ -@import '../../style/themes/default'; +@import '../../style/themes/index'; @import '../../style/mixins/index'; @import '../../checkbox/style/mixin'; @import './mixin'; @@ -11,7 +11,17 @@ .antCheckboxFn(@checkbox-prefix-cls: ~'@{ant-prefix}-tree-checkbox'); .@{tree-prefix-cls} { + /* see https://github.com/ant-design/ant-design/issues/16259 */ + &-checkbox-checked::after { + position: absolute; + top: 16.67%; + left: 0; + width: 100%; + height: 66.67%; + } + .reset-component; + margin: 0; padding: 0; @@ -73,7 +83,7 @@ left: 0; display: inline-block; width: 24px; - height: 24px; + height: @tree-title-height; color: @primary-color; font-size: 14px; transform: none; @@ -112,21 +122,24 @@ cursor: pointer; transition: all 0.3s; &:hover { - background-color: @item-hover-bg; + background-color: @tree-node-hover-bg; } &.@{tree-prefix-cls}-node-selected { - background-color: @primary-2; + background-color: @tree-node-selected-bg; } } span { &.@{tree-prefix-cls}-checkbox { - margin: 4px 4px 0 2px; + top: initial; + height: @tree-title-height; + margin: 0 4px 0 2px; + padding: ((@tree-title-height - 16px) / 2) 0; } &.@{tree-prefix-cls}-switcher, &.@{tree-prefix-cls}-iconEle { display: inline-block; width: 24px; - height: 24px; + height: @tree-title-height; margin: 0; line-height: @tree-title-height; text-align: center; @@ -136,6 +149,10 @@ cursor: pointer; } + &.@{tree-prefix-cls}-iconEle:empty { + display: none; + } + &.@{tree-prefix-cls}-switcher { position: relative; @@ -174,11 +191,6 @@ } } &-child-tree { - display: none; - &-open { - display: block; - } - // https://github.com/ant-design/ant-design/issues/14958 > li { // Provide additional padding between top child node and parent node @@ -236,7 +248,8 @@ left: 12px; width: 1px; height: 100%; - margin: 22px 0; + height: calc(100% - 22px); // Remove additional height if support + margin: 22px 0 0; border-left: 1px solid @border-color-base; content: ' '; } @@ -249,4 +262,19 @@ } } } + + &.@{tree-prefix-cls}-block-node { + li { + .@{tree-prefix-cls}-node-content-wrapper { + width: ~'calc(100% - 24px)'; + } + span { + &.@{tree-prefix-cls}-checkbox { + + .@{tree-prefix-cls}-node-content-wrapper { + width: ~'calc(100% - 46px)'; + } + } + } + } + } } diff --git a/components/tree/style/mixin.less b/components/tree/style/mixin.less index e90dfc651..929cecdee 100644 --- a/components/tree/style/mixin.less +++ b/components/tree/style/mixin.less @@ -7,6 +7,7 @@ .@{tree-prefix-cls}-switcher-icon, .@{tree-select-prefix-cls}-switcher-icon { .iconfont-size-under-12px(10px); + display: inline-block; font-weight: bold; svg { diff --git a/components/tree/util.js b/components/tree/util.js index eeebeea0e..496acd15f 100644 --- a/components/tree/util.js +++ b/components/tree/util.js @@ -14,7 +14,7 @@ function traverseNodesKey(rootChildren, callback) { function processNode(node) { const { key } = node; const children = getSlots(node).default; - if (callback(key) !== false) { + if (callback(key, node) !== false) { traverseNodesKey(typeof children === 'function' ? children() : children, callback); } } @@ -72,3 +72,30 @@ export function calcRangeKeys(rootChildren, expandedKeys, startKey, endKey) { return keys; } + +export function convertDirectoryKeysToNodes(rootChildren, keys) { + const restKeys = [...keys]; + const nodes = []; + traverseNodesKey(rootChildren, (key, node) => { + const index = restKeys.indexOf(key); + if (index !== -1) { + nodes.push(node); + restKeys.splice(index, 1); + } + + return !!restKeys.length; + }); + return nodes; +} + +export function getFullKeyListByTreeData(treeData) { + let keys = []; + + (treeData || []).forEach(item => { + keys.push(item.key); + if (item.children) { + keys = [...keys, ...getFullKeyListByTreeData(item.children)]; + } + }); + return keys; +} diff --git a/components/upload/Upload.jsx b/components/upload/Upload.jsx index f0e831cf7..528cd039e 100644 --- a/components/upload/Upload.jsx +++ b/components/upload/Upload.jsx @@ -1,6 +1,7 @@ import classNames from 'classnames'; import uniqBy from 'lodash/uniqBy'; import findIndex from 'lodash/findIndex'; +import pick from 'lodash/pick'; import VcUpload from '../vc-upload'; import BaseMixin from '../_util/BaseMixin'; import { getOptionProps, initDefaultProps, hasProp, getListeners } from '../_util/props-util'; @@ -66,25 +67,12 @@ export default { fileList: nextFileList, }); // fix ie progress - if (!window.FormData) { + if (!window.File || process.env.TEST_IE) { this.autoUpdateProgress(0, targetItem); } }, - autoUpdateProgress(_, file) { - const getPercent = genPercentAdd(); - let curPercent = 0; - this.clearProgressTimer(); - this.progressTimer = setInterval(() => { - curPercent = getPercent(curPercent); - this.onProgress( - { - percent: curPercent * 100, - }, - file, - ); - }, 200); - }, - onSuccess(response, file) { + + onSuccess(response, file, xhr) { this.clearProgressTimer(); try { if (typeof response === 'string') { @@ -101,6 +89,7 @@ export default { } targetItem.status = 'done'; targetItem.response = response; + targetItem.xhr = xhr; this.onChange({ file: { ...targetItem }, fileList, @@ -140,19 +129,24 @@ export default { this.$emit('reject', fileList); }, handleRemove(file) { - const { remove } = this; - const { status } = file; - file.status = 'removed'; // eslint-disable-line + const { remove: onRemove } = this; + const { sFileList: fileList } = this.$data; - Promise.resolve(typeof remove === 'function' ? remove(file) : remove).then(ret => { + Promise.resolve(typeof onRemove === 'function' ? onRemove(file) : onRemove).then(ret => { // Prevent removing file if (ret === false) { - file.status = status; return; } - const removedFileList = removeFileItem(file, this.sFileList); + const removedFileList = removeFileItem(file, fileList); + if (removedFileList) { + file.status = 'removed'; // eslint-disable-line + + if (this.upload) { + this.upload.abort(file); + } + this.onChange({ file, fileList: removedFileList, @@ -178,14 +172,16 @@ export default { }); }, reBeforeUpload(file, fileList) { - if (!this.beforeUpload) { + const { beforeUpload } = this.$props; + const { sFileList: stateFileList } = this.$data; + if (!beforeUpload) { return true; } - const result = this.beforeUpload(file, fileList); + const result = beforeUpload(file, fileList); if (result === false) { this.onChange({ file, - fileList: uniqBy(this.sFileList.concat(fileList.map(fileToObject)), item => item.uid), + fileList: uniqBy(stateFileList.concat(fileList.map(fileToObject)), item => item.uid), }); return false; } @@ -197,25 +193,45 @@ export default { clearProgressTimer() { clearInterval(this.progressTimer); }, + autoUpdateProgress(_, file) { + const getPercent = genPercentAdd(); + let curPercent = 0; + this.clearProgressTimer(); + this.progressTimer = setInterval(() => { + curPercent = getPercent(curPercent); + this.onProgress( + { + percent: curPercent * 100, + }, + file, + ); + }, 200); + }, renderUploadList(locale) { - const { showUploadList = {}, listType } = getOptionProps(this); - const { showRemoveIcon, showPreviewIcon } = showUploadList; + const { + showUploadList = {}, + listType, + previewFile, + disabled, + locale: propLocale, + } = getOptionProps(this); + const { showRemoveIcon, showPreviewIcon, showDownloadIcon } = showUploadList; + const { sFileList: fileList } = this.$data; const uploadListProps = { props: { listType, - items: this.sFileList, - showRemoveIcon, + items: fileList, + previewFile, + showRemoveIcon: !disabled && showRemoveIcon, showPreviewIcon, - locale: { ...locale, ...this.$props.locale }, + showDownloadIcon, + locale: { ...locale, ...propLocale }, }, on: { remove: this.handleManualRemove, + ...pick(getListeners(this), ['download', 'preview']), // 如果没有配置该事件,不要传递, uploadlist 会有相应逻辑 }, }; - const listeners = getListeners(this); - if (listeners.preview) { - uploadListProps.on.preview = listeners.preview; - } return ; }, }, @@ -227,7 +243,7 @@ export default { type, disabled, } = getOptionProps(this); - + const { sFileList: fileList, dragState } = this.$data; const getPrefixCls = this.configProvider.getPrefixCls; const prefixCls = getPrefixCls('upload', customizePrefixCls); @@ -261,8 +277,8 @@ export default { if (type === 'drag') { const dragCls = classNames(prefixCls, { [`${prefixCls}-drag`]: true, - [`${prefixCls}-drag-uploading`]: this.sFileList.some(file => file.status === 'uploading'), - [`${prefixCls}-drag-hover`]: this.dragState === 'dragover', + [`${prefixCls}-drag-uploading`]: fileList.some(file => file.status === 'uploading'), + [`${prefixCls}-drag-hover`]: dragState === 'dragover', [`${prefixCls}-disabled`]: disabled, }); return ( @@ -290,7 +306,7 @@ export default { // Remove id to avoid open by label when trigger is hidden // https://github.com/ant-design/ant-design/issues/14298 - if (!children) { + if (!children || disabled) { delete vcUploadProps.props.id; } @@ -302,7 +318,7 @@ export default { if (listType === 'picture-card') { return ( - + {uploadList} {uploadButton} diff --git a/components/upload/UploadList.jsx b/components/upload/UploadList.jsx index 43bc727d8..71bc5f29e 100644 --- a/components/upload/UploadList.jsx +++ b/components/upload/UploadList.jsx @@ -2,51 +2,13 @@ import BaseMixin from '../_util/BaseMixin'; import { getOptionProps, initDefaultProps, getListeners } from '../_util/props-util'; import getTransitionProps from '../_util/getTransitionProps'; import { ConfigConsumerProps } from '../config-provider'; +import { previewImage, isImageUrl } from './utils'; import Icon from '../icon'; import Tooltip from '../tooltip'; import Progress from '../progress'; import classNames from 'classnames'; import { UploadListProps } from './interface'; -const imageTypes = ['image', 'webp', 'png', 'svg', 'gif', 'jpg', 'jpeg', 'bmp', 'dpg', 'ico']; -// https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL -const previewFile = (file, callback) => { - if (file.type && !imageTypes.includes(file.type)) { - callback(''); - } - const reader = new window.FileReader(); - reader.onloadend = () => callback(reader.result); - reader.readAsDataURL(file); -}; - -const extname = url => { - if (!url) { - return ''; - } - const temp = url.split('/'); - const filename = temp[temp.length - 1]; - const filenameWithoutSuffix = filename.split(/#|\?/)[0]; - return (/\.[^./\\]*$/.exec(filenameWithoutSuffix) || [''])[0]; -}; - -const isImageUrl = file => { - if (imageTypes.includes(file.type)) { - return true; - } - const url = file.thumbUrl || file.url; - const extension = extname(url); - if (/^data:image\//.test(url) || /(webp|svg|png|gif|jpg|jpeg|bmp|dpg|ico)$/i.test(extension)) { - return true; - } else if (/^data:/.test(url)) { - // other file types of base64 - return false; - } else if (extension) { - // other file types which have extension - return false; - } - return true; -}; - export default { name: 'AUploadList', mixins: [BaseMixin], @@ -57,43 +19,43 @@ export default { showInfo: false, }, showRemoveIcon: true, + showDownloadIcon: false, showPreviewIcon: true, + previewFile: previewImage, }), inject: { configProvider: { default: () => ConfigConsumerProps }, }, updated() { this.$nextTick(() => { - if (this.listType !== 'picture' && this.listType !== 'picture-card') { + const { listType, items, previewFile } = this.$props; + if (listType !== 'picture' && listType !== 'picture-card') { return; } - (this.items || []).forEach(file => { + (items || []).forEach(file => { if ( typeof document === 'undefined' || typeof window === 'undefined' || !window.FileReader || !window.File || - !(file.originFileObj instanceof window.File) || + !(file.originFileObj instanceof File || file.originFileObj instanceof Blob) || file.thumbUrl !== undefined ) { return; } /*eslint-disable */ file.thumbUrl = ''; - /*eslint -enable */ - previewFile(file.originFileObj, previewDataUrl => { - // Need append '' to avoid dead loop - file.thumbUrl = previewDataUrl || ''; - /*eslint -enable */ - this.$forceUpdate(); - }); + if (previewFile) { + previewFile(file.originFileObj).then(previewDataUrl => { + // Need append '' to avoid dead loop + file.thumbUrl = previewDataUrl || ''; + this.$forceUpdate(); + }); + } }); }); }, methods: { - handleClose(file) { - this.$emit('remove', file); - }, handlePreview(file, e) { const { preview } = getListeners(this); if (!preview) { @@ -102,6 +64,18 @@ export default { e.preventDefault(); return this.$emit('preview', file); }, + handleDownload(file) { + const { download } = getListeners(this); + if (typeof download === 'function') { + download(file); + } else if (file.url) { + window.open(file.url); + } + }, + + handleClose(file) { + this.$emit('remove', file); + }, }, render() { const { @@ -110,7 +84,9 @@ export default { listType, showPreviewIcon, showRemoveIcon, + showDownloadIcon, locale, + progressAttr, } = getOptionProps(this); const getPrefixCls = this.configProvider.getPrefixCls; const prefixCls = getPrefixCls('upload', customizePrefixCls); @@ -126,7 +102,11 @@ export default { icon = ; } else { const thumbnail = isImageUrl(file) ? ( - {file.name} + {file.name} ) : ( ); @@ -147,7 +127,7 @@ export default { if (file.status === 'uploading') { const progressProps = { props: { - ...this.progressAttr, + ...progressAttr, type: 'line', percent: file.percent, }, @@ -164,30 +144,64 @@ export default { const infoUploadingClass = classNames({ [`${prefixCls}-list-item`]: true, [`${prefixCls}-list-item-${file.status}`]: true, + [`${prefixCls}-list-item-list-type-${listType}`]: true, }); const linkProps = typeof file.linkProps === 'string' ? JSON.parse(file.linkProps) : file.linkProps; - const preview = file.url ? ( - this.handlePreview(file, e)} - > - {file.name} - - ) : ( + + const removeIcon = showRemoveIcon ? ( + this.handleClose(file)} /> + ) : null; + const downloadIcon = + showDownloadIcon && file.status === 'done' ? ( + this.handleDownload(file)} + /> + ) : null; + const downloadOrDelete = listType !== 'picture-card' && ( this.handlePreview(file, e)} - title={file.name} + key="download-delete" + class={`${prefixCls}-list-item-card-actions ${listType === 'picture' ? 'picture' : ''}`} > - {file.name} + {downloadIcon && {downloadIcon}} + {removeIcon && {removeIcon}} ); + const listItemNameClass = classNames({ + [`${prefixCls}-list-item-name`]: true, + [`${prefixCls}-list-item-name-icon-count-${ + [downloadIcon, removeIcon].filter(x => x).length + }`]: true, + }); + + const preview = file.url + ? [ + this.handlePreview(file, e)} + > + {file.name} + , + downloadOrDelete, + ] + : [ + this.handlePreview(file, e)} + title={file.name} + > + {file.name} + , + downloadOrDelete, + ]; const style = file.url || file.thumbUrl ? undefined @@ -207,55 +221,41 @@ export default { ) : null; - const iconProps = { - props: { - type: 'delete', - title: locale.removeFile, - }, - on: { - click: () => { - this.handleClose(file); - }, - }, - }; - const iconProps1 = { ...iconProps, ...{ props: { type: 'close' } } }; - const removeIcon = showRemoveIcon ? : null; - const removeIconClose = showRemoveIcon ? : null; - const actions = - listType === 'picture-card' && file.status !== 'uploading' ? ( - - {previewIcon} - {removeIcon} - - ) : ( - removeIconClose - ); + const actions = listType === 'picture-card' && file.status !== 'uploading' && ( + + {previewIcon} + {file.status === 'done' && downloadIcon} + {removeIcon} + + ); let message; if (file.response && typeof file.response === 'string') { message = file.response; } else { message = (file.error && file.error.statusText) || locale.uploadError; } - const iconAndPreview = - file.status === 'error' ? ( - - {icon} - {preview} - - ) : ( - - {icon} - {preview} - - ); + const iconAndPreview = ( + + {icon} + {preview} + + ); const transitionProps = getTransitionProps('fade'); - return ( + const dom = (
                {iconAndPreview}
                {actions} {progress}
                ); + const listContainerNameClass = classNames({ + [`${prefixCls}-list-picture-card-container`]: listType === 'picture-card', + }); + return ( +
                + {file.status === 'error' ? {dom} : {dom}} +
                + ); }); const listClassNames = classNames({ [`${prefixCls}-list`]: true, diff --git a/components/upload/__tests__/__snapshots__/demo.test.js.snap b/components/upload/__tests__/__snapshots__/demo.test.js.snap index 5635ba8c0..b31a33fd6 100644 --- a/components/upload/__tests__/__snapshots__/demo.test.js.snap +++ b/components/upload/__tests__/__snapshots__/demo.test.js.snap @@ -1,82 +1,83 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders ./components/upload/demo/avatar.md correctly 1`] = `
                `; +exports[`renders ./antdv-demo/upload/demo/avatar.md correctly 1`] = `
                `; -exports[`renders ./components/upload/demo/basic.md correctly 1`] = `
                `; +exports[`renders ./antdv-demo/upload/demo/basic copy 3.md correctly 1`] = `
                `; -exports[`renders ./components/upload/demo/defaultFileList.md correctly 1`] = ` -
                +exports[`renders ./antdv-demo/upload/demo/basic.md correctly 1`] = `
                `; + +exports[`renders ./antdv-demo/upload/demo/defaultFileList.md correctly 1`] = ` +
                -
                - - -
                -
                - - -
                -
                - -`; - -exports[`renders ./components/upload/demo/directory.md correctly 1`] = `
                `; - -exports[`renders ./components/upload/demo/drag.md correctly 1`] = `
                `; - -exports[`renders ./components/upload/demo/fileList.md correctly 1`] = ` -
                +
                + +
                +
                + + +
                `; -exports[`renders ./components/upload/demo/picture-card.md correctly 1`] = ` -
                +exports[`renders ./antdv-demo/upload/demo/directory.md correctly 1`] = `
                `; + +exports[`renders ./antdv-demo/upload/demo/drag.md correctly 1`] = `
                `; + +exports[`renders ./antdv-demo/upload/demo/fileList.md correctly 1`] = ` +
                +`; + +exports[`renders ./antdv-demo/upload/demo/picture-card.md correctly 1`] = ` +
                + + + +
                +
                +
                image.png
                + +
                -
                -
                +
                `; -exports[`renders ./components/upload/demo/picture-style.md correctly 1`] = ` -
                +exports[`renders ./antdv-demo/upload/demo/picture-style.md correctly 1`] = ` +
                -
                - - -
                -


                +
                +
                -
                - - -
                -
                -
                +
                +


                + +
                `; -exports[`renders ./components/upload/demo/upload-manually.md correctly 1`] = `
                `; +exports[`renders ./antdv-demo/upload/demo/preview-file.md correctly 1`] = `
                `; + +exports[`renders ./antdv-demo/upload/demo/transform-file.md correctly 1`] = `
                `; + +exports[`renders ./antdv-demo/upload/demo/upload-manually.md correctly 1`] = `
                `; diff --git a/components/upload/__tests__/__snapshots__/uploadlist.test.js.snap b/components/upload/__tests__/__snapshots__/uploadlist.test.js.snap index d965dc721..d9bec99fe 100644 --- a/components/upload/__tests__/__snapshots__/uploadlist.test.js.snap +++ b/components/upload/__tests__/__snapshots__/uploadlist.test.js.snap @@ -1,9 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Upload List handle error 1`] = ` -
                foo.png
                +
                foo.png
                @@ -16,13 +14,11 @@ exports[`Upload List handle error 1`] = `
                - +
                `; exports[`Upload List handle error 2`] = ` -
                foo.png
                +
                foo.png
                @@ -35,64 +31,37 @@ exports[`Upload List handle error 2`] = `
                - +
                `; exports[`Upload List should be uploading when upload a file 1`] = `
                `; exports[`Upload List should non-image format file preview 1`] = ` -
                +
                -
                - - -
                -
                - - -
                -
                - - -
                -
                - - -
                -
                - - -
                -
                - - -
                -
                - - -
                -
                - - -
                -
                +
                +
                + +
                + + +
                + +
                +
                + +
                +
                + +
                +
                + +
                +
                + +
                `; diff --git a/components/upload/__tests__/uploadlist.test.js b/components/upload/__tests__/uploadlist.test.js index e2e6e2d3b..85671b23b 100644 --- a/components/upload/__tests__/uploadlist.test.js +++ b/components/upload/__tests__/uploadlist.test.js @@ -26,7 +26,16 @@ const fileList = [ ]; describe('Upload List', () => { + // jsdom not support `createObjectURL` yet. Let's handle this. + const originCreateObjectURL = window.URL.createObjectURL; + window.URL.createObjectURL = jest.fn(() => ''); + const originHTMLCanvasElementGetContext = window.HTMLCanvasElement.prototype.getContext; + window.HTMLCanvasElement.prototype.getContext = jest.fn(() => ''); // https://github.com/ant-design/ant-design/issues/4653 + afterAll(() => { + window.URL.createObjectURL = originCreateObjectURL; + window.HTMLCanvasElement.prototype.getContext = originHTMLCanvasElementGetContext; + }); it('should use file.thumbUrl for in priority', done => { const props = { propsData: { @@ -85,7 +94,7 @@ describe('Upload List', () => { wrapper .findAll('.ant-upload-list-item') .at(0) - .find('.anticon-close') + .find('.anticon-delete') .trigger('click'); await delay(400); // wrapper.update(); @@ -363,7 +372,7 @@ describe('Upload List', () => { defaultFileList: newFileList.push(newFile), }); await delay(200); - expect(wrapper.vm.sFileList[2].thumbUrl).not.toBeFalsy(); + expect(wrapper.vm.sFileList[2].thumbUrl).not.toBe(undefined); done(); }, 1000); }); diff --git a/components/upload/demo/avatar.md b/components/upload/demo/avatar.md deleted file mode 100644 index 423d0b17f..000000000 --- a/components/upload/demo/avatar.md +++ /dev/null @@ -1,87 +0,0 @@ - -#### 用户头像 -点击上传用户头像,并使用 `beforeUpload` 限制用户上传的图片格式和大小。 -`beforeUpload` 的返回值可以是一个 Promise 以支持异步处理,如服务端校验等 - - - -#### Avatar -Click to upload user's avatar, and validate size and format of picture with `beforeUpload`. -The return value of function `beforeUpload` can be a Promise to check asynchronously. - - -```tpl - - - -``` diff --git a/components/upload/demo/basic.md b/components/upload/demo/basic.md deleted file mode 100644 index 9d6e62b36..000000000 --- a/components/upload/demo/basic.md +++ /dev/null @@ -1,46 +0,0 @@ - -#### 点击上传 -经典款式,用户点击按钮弹出文件选择框。 - - - -#### Upload by clicking -Classic mode. File selection dialog pops up when upload button is clicked. - - -```tpl - - -``` diff --git a/components/upload/demo/defaultFileList.md b/components/upload/demo/defaultFileList.md deleted file mode 100644 index ad5e373b3..000000000 --- a/components/upload/demo/defaultFileList.md +++ /dev/null @@ -1,57 +0,0 @@ - -#### 已上传的文件列表 -使用 `defaultFileList` 设置已上传的内容。 - - - -#### Default Files -Use `defaultFileList` for uploaded files when page init. - - -```tpl - - -``` diff --git a/components/upload/demo/directory.md b/components/upload/demo/directory.md deleted file mode 100644 index 076b31f79..000000000 --- a/components/upload/demo/directory.md +++ /dev/null @@ -1,17 +0,0 @@ - -#### 文件夹上传 -支持上传一个文件夹里的所有文件。 - - - -#### Upload directory -You can select and upload a whole directory. - - -```tpl - -``` diff --git a/components/upload/demo/drag.md b/components/upload/demo/drag.md deleted file mode 100644 index 45fad4c8b..000000000 --- a/components/upload/demo/drag.md +++ /dev/null @@ -1,50 +0,0 @@ - -#### 拖拽上传 -把文件拖入指定区域,完成上传,同样支持点击上传。 -设置 `multiple` 后,在 `IE10+` 可以一次上传多个文件。 - - - -#### Drag and Drop -Classic mode. File selection dialog pops up when upload button is clicked. - - -```tpl - - -``` diff --git a/components/upload/demo/fileList.md b/components/upload/demo/fileList.md deleted file mode 100644 index e6a46486f..000000000 --- a/components/upload/demo/fileList.md +++ /dev/null @@ -1,64 +0,0 @@ - -#### 完全控制的上传列表 -使用 `fileList` 对列表进行完全控制,可以实现各种自定义功能,以下演示三种情况: -1) 上传列表数量的限制。 -2) 读取远程路径并显示链接。 -3) 按照服务器返回信息筛选成功上传的文件。 - - - -#### Complete control over file list -You can gain full control over filelist by configuring `fileList`. You can accomplish all kinds of customed functions. The following shows three circumstances: -1) limit the number of uploaded files. -2) read from response and show file link. -3) filter successfully uploaded files according to response from server. - - -```tpl - - -``` diff --git a/components/upload/demo/index.vue b/components/upload/demo/index.vue deleted file mode 100644 index dc32a0006..000000000 --- a/components/upload/demo/index.vue +++ /dev/null @@ -1,65 +0,0 @@ - diff --git a/components/upload/demo/picture-card.md b/components/upload/demo/picture-card.md deleted file mode 100644 index be833544a..000000000 --- a/components/upload/demo/picture-card.md +++ /dev/null @@ -1,73 +0,0 @@ - -#### 照片墙 -用户可以上传图片并在列表中显示缩略图。当上传照片数到达限制后,上传按钮消失。 - - - -#### Pictures Wall -After users upload picture, the thumbnail will be shown in list. The upload button will disappear when count meets limitation. - - -```tpl - - - -``` diff --git a/components/upload/demo/picture-style.md b/components/upload/demo/picture-style.md deleted file mode 100644 index f0f9b53ec..000000000 --- a/components/upload/demo/picture-style.md +++ /dev/null @@ -1,73 +0,0 @@ - -#### 图片列表样式 -上传文件为图片,可展示本地缩略图。`IE8/9` 不支持浏览器本地缩略图展示([Ref](https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL)),可以写 `thumbUrl` 属性来代替。 - - - -#### Pictures with list style -If uploaded file is a picture, the thumbnail can be shown. `IE8/9` do not support local thumbnail show. Please use `thumbUrl` instead. - - -```tpl - - - -``` diff --git a/components/upload/demo/upload-manually.md b/components/upload/demo/upload-manually.md deleted file mode 100644 index f5e48a4f1..000000000 --- a/components/upload/demo/upload-manually.md +++ /dev/null @@ -1,76 +0,0 @@ - -#### 手动上传 -`beforeUpload` 返回 `false` 后,手动上传文件。 - - - -#### Upload manually -Upload files manually after `beforeUpload` returns `false`. - - -```tpl - - -``` diff --git a/components/upload/index.en-US.md b/components/upload/index.en-US.md deleted file mode 100644 index 44c23ddfa..000000000 --- a/components/upload/index.en-US.md +++ /dev/null @@ -1,59 +0,0 @@ -## API - -| Property | Description | Type | Default | -| --- | --- | --- | --- | -| accept | File types that can be accepted. See [input accept Attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept) | string | - | -| action | Uploading URL | string\|(file) => `Promise` | - | -| directory | support upload whole directory ([caniuse](https://caniuse.com/#feat=input-file-directory)) | boolean | false | -| beforeUpload | Hook function which will be executed before uploading. Uploading will be stopped with `false` or a rejected Promise returned. **Warning:this function is not supported in IE9**。 | (file, fileList) => `boolean | Promise` | - | -| customRequest | override for the default xhr behavior allowing for additional customization and ability to implement your own XMLHttpRequest | Function | - | -| data | Uploading params or function which can return uploading params. | object\|function(file) | - | -| defaultFileList | Default list of files that have been uploaded. | object\[] | - | -| disabled | disable upload button | boolean | false | -| fileList | List of files that have been uploaded (controlled). Here is a common issue [#2423](https://github.com/ant-design/ant-design/issues/2423) when using it | object\[] | - | -| headers | Set request headers, valid above IE10. | object | - | -| listType | Built-in stylesheets, support for three types: `text`, `picture` or `picture-card` | string | 'text' | -| multiple | Whether to support selected multiple file. `IE10+` supported. You can select multiple files with CTRL holding down while multiple is set to be true | boolean | false | -| name | The name of uploading file | string | 'file' | -| showUploadList | Whether to show default upload list, could be an object to specify `showPreviewIcon` and `showRemoveIcon` individually | Boolean or { showPreviewIcon?: boolean, showRemoveIcon?: boolean } | true | -| supportServerRender | Need to be turned on while the server side is rendering. | boolean | false | -| withCredentials | ajax upload with cookie sent | boolean | false | -| openFileDialogOnClick | click open file dialog | boolean | true | -| remove | A callback function, will be executed when removing file button is clicked, remove event will be prevented when return value is `false` or a Promise which resolve(false) or reject. | Function(file): `boolean | Promise` | - | - -### events - -| Events Name | Description | Arguments | -| --- | --- | --- | -| change | A callback function, can be executed when uploading state is changing. See [change](#change) | Function | - | -| preview | A callback function, will be executed when file link or preview icon is clicked. | Function(file) | - | -| reject | A callback function, will be executed when drop files is not accept. | Function(fileList) | - | - -### change - -> The function will be called when uploading is in progress, completed or failed - -When uploading state change, it returns: - -```js -{ - file: { /* ... */ }, - fileList: [ /* ... */ ], - event: { /* ... */ }, -} -``` - -1. `file` File object for the current operation. - - ```js - { - uid: 'uid', // unique identifier, negative is recommend, to prevent interference with internal generated id - name: 'xx.png' // file name - status: 'done', // options:uploading, done, error, removed - response: '{"status": "success"}', // response from server - linkProps: '{"download": "image"}', // additional html props of file link - } - ``` - -2. `fileList` current list of files -3. `event` response from server, including uploading progress, supported by advanced browsers. diff --git a/components/upload/index.zh-CN.md b/components/upload/index.zh-CN.md deleted file mode 100644 index b2bcd17e7..000000000 --- a/components/upload/index.zh-CN.md +++ /dev/null @@ -1,59 +0,0 @@ -## API - -| 参数 | 说明 | 类型 | 默认值 | -| --- | --- | --- | --- | -| accept | 接受上传的文件类型, 详见 [input accept Attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept) | string | 无 | -| action | 上传的地址 | string\|(file) => `Promise` | 无 | -| directory | 支持上传文件夹([caniuse](https://caniuse.com/#feat=input-file-directory)) | boolean | false | -| beforeUpload | 上传文件之前的钩子,参数为上传的文件,若返回 `false` 则停止上传。支持返回一个 Promise 对象,Promise 对象 reject 时则停止上传,resolve 时开始上传( resolve 传入 `File` 或 `Blob` 对象则上传 resolve 传入对象)。**注意:IE9 不支持该方法**。 | (file, fileList) => `boolean | Promise` | 无 | -| customRequest | 通过覆盖默认的上传行为,可以自定义自己的上传实现 | Function | 无 | -| data | 上传所需参数或返回上传参数的方法 | object\|(file) => object | 无 | -| defaultFileList | 默认已经上传的文件列表 | object\[] | 无 | -| disabled | 是否禁用 | boolean | false | -| fileList | 已经上传的文件列表(受控) | object\[] | 无 | -| headers | 设置上传的请求头部,IE10 以上有效 | object | 无 | -| listType | 上传列表的内建样式,支持三种基本样式 `text`, `picture` 和 `picture-card` | string | 'text' | -| multiple | 是否支持多选文件,`ie10+` 支持。开启后按住 ctrl 可选择多个文件。 | boolean | false | -| name | 发到后台的文件参数名 | string | 'file' | -| showUploadList | 是否展示 uploadList, 可设为一个对象,用于单独设定 showPreviewIcon 和 showRemoveIcon | Boolean or { showPreviewIcon?: boolean, showRemoveIcon?: boolean } | true | -| supportServerRender | 服务端渲染时需要打开这个 | boolean | false | -| withCredentials | 上传请求时是否携带 cookie | boolean | false | -| openFileDialogOnClick | 点击打开文件对话框 | boolean | true | -| remove   | 点击移除文件时的回调,返回值为 false 时不移除。支持返回一个 Promise 对象,Promise 对象 resolve(false) 或 reject 时不移除。               | Function(file): `boolean | Promise` | 无   | - -### 事件 - -| 事件名称 | 说明 | 回调参数 | -| -------- | -------------------------------------------- | ------------------ | -| change | 上传文件改变时的状态,详见 [change](#change) | Function | 无 | -| preview | 点击文件链接或预览图标时的回调 | Function(file) | 无 | -| reject | 拖拽文件不符合 accept 类型时的回调 | Function(fileList) | 无 | - -### change - -> 上传中、完成、失败都会调用这个函数。 - -文件状态改变的回调,返回为: - -```js -{ - file: { /* ... */ }, - fileList: [ /* ... */ ], - event: { /* ... */ }, -} -``` - -1. `file` 当前操作的文件对象。 - - ```js - { - uid: 'uid', // 文件唯一标识,建议设置为负数,防止和内部产生的 id 冲突 - name: 'xx.png' // 文件名 - status: 'done', // 状态有:uploading done error removed - response: '{"status": "success"}', // 服务端响应内容 - linkProps: '{"download": "image"}', // 下载链接额外的 HTML 属性 - } - ``` - -2. `fileList` 当前的文件列表。 -3. `event` 上传中的服务端响应内容,包含了上传进度等信息,高级浏览器支持。 diff --git a/components/upload/interface.jsx b/components/upload/interface.jsx index 12c3e9932..080fd2cdd 100755 --- a/components/upload/interface.jsx +++ b/components/upload/interface.jsx @@ -54,6 +54,7 @@ export const ShowUploadListInterface = PropsTypes.shape({ export const UploadLocale = PropsTypes.shape({ uploading: PropsTypes.string, removeFile: PropsTypes.string, + downloadFile: PropsTypes.string, uploadError: PropsTypes.string, previewFile: PropsTypes.string, }).loose; @@ -66,6 +67,7 @@ export const UploadProps = { action: PropsTypes.oneOfType([PropsTypes.string, PropsTypes.func]), directory: PropsTypes.bool, data: PropsTypes.oneOfType([PropsTypes.object, PropsTypes.func]), + method: PropsTypes.oneOf(['POST', 'PUT', 'post', 'put']), headers: PropsTypes.object, showUploadList: PropsTypes.oneOfType([PropsTypes.bool, ShowUploadListInterface]), multiple: PropsTypes.bool, @@ -86,6 +88,8 @@ export const UploadProps = { locale: UploadLocale, height: PropsTypes.number, id: PropsTypes.string, + previewFile: PropsTypes.func, + transformFile: PropsTypes.func, }; export const UploadState = { @@ -103,6 +107,8 @@ export const UploadListProps = { progressAttr: PropsTypes.object, prefixCls: PropsTypes.string, showRemoveIcon: PropsTypes.bool, + showDownloadIcon: PropsTypes.bool, showPreviewIcon: PropsTypes.bool, locale: UploadLocale, + previewFile: PropsTypes.func, }; diff --git a/components/upload/style/index.less b/components/upload/style/index.less index de4a6a3b5..b074e4615 100644 --- a/components/upload/style/index.less +++ b/components/upload/style/index.less @@ -1,4 +1,4 @@ -@import '../../style/themes/default'; +@import '../../style/themes/index'; @import '../../style/mixins/index'; @upload-prefix-cls: ~'@{ant-prefix}-upload'; @@ -8,6 +8,7 @@ .@{upload-prefix-cls} { .reset-component; + outline: 0; p { @@ -28,8 +29,13 @@ display: inline-block; } + &&-disabled { + cursor: not-allowed; + } + &&-select-picture-card { display: table; + float: left; width: @upload-picture-card-size; height: @upload-picture-card-size; margin-right: 8px; @@ -72,7 +78,7 @@ } &.@{upload-prefix-cls}-drag-hover:not(.@{upload-prefix-cls}-disabled) { - border: 2px dashed @primary-5; + border-color: @primary-7; } &.@{upload-prefix-cls}-disabled { @@ -98,6 +104,7 @@ color: @primary-5; font-size: 48px; } + margin-bottom: 20px; } p.@{upload-prefix-cls}-text { @@ -121,11 +128,28 @@ color: @text-color-secondary; } } + + &-picture-card-wrapper { + .clearfix; + + display: inline-block; + width: 100%; + } } .@{upload-prefix-cls}-list { .reset-component; .clearfix; + &-item-list-type-text { + &:hover { + .@{upload-prefix-cls}-list-item-name-icon-count-1 { + padding-right: 14px; + } + .@{upload-prefix-cls}-list-item-name-icon-count-2 { + padding-right: 28px; + } + } + } &-item { position: relative; height: 22px; @@ -140,6 +164,25 @@ text-overflow: ellipsis; } + &-name-icon-count-1 { + padding-right: 14px; + } + + &-card-actions { + position: absolute; + right: 0; + opacity: 0; + &.picture { + top: 25px; + line-height: 1; + opacity: 1; + } + .anticon { + padding-right: 6px; + color: rgba(0, 0, 0, 0.45); + } + } + &-info { height: 100%; padding: 0 12px 0 4px; @@ -147,6 +190,8 @@ > span { display: block; + width: 100%; + height: 100%; } .@{iconfont-css-prefix}-loading, @@ -160,6 +205,7 @@ .@{iconfont-css-prefix}-close { .iconfont-size-under-12px(10px); + position: absolute; top: 6px; right: 4px; @@ -181,14 +227,20 @@ opacity: 1; } + &:hover &-card-actions { + opacity: 1; + } + &-error, &-error .@{iconfont-css-prefix}-paper-clip, &-error &-name { color: @error-color; } - &-error .@{iconfont-css-prefix}-close { - color: @error-color !important; + &-error &-card-actions { + .anticon { + color: @error-color; + } opacity: 1; } @@ -250,6 +302,10 @@ transform: translate(-50%, -50%); } + .@{upload-item}-image { + max-width: 100%; + } + .@{upload-item}-thumbnail img { display: block; width: 48px; @@ -271,6 +327,14 @@ transition: all 0.3s; } + .@{upload-item}-name-icon-count-1 { + padding-right: 18px; + } + + .@{upload-item}-name-icon-count-2 { + padding-right: 36px; + } + .@{upload-item}-uploading .@{upload-item}-name { line-height: 28px; } @@ -292,12 +356,15 @@ } &-picture-card { - // https://github.com/ant-design/ant-design/issues/11183 - float: left; - &.@{upload-prefix-cls}-list::after { display: none; } + &-container { + float: left; + width: @upload-picture-card-size; + height: @upload-picture-card-size; + margin: 0 8px 8px 0; + } .@{upload-item} { float: left; width: @upload-picture-card-size; @@ -337,6 +404,7 @@ transition: all 0.3s; .@{iconfont-css-prefix}-eye-o, + .@{iconfont-css-prefix}-download, .@{iconfont-css-prefix}-delete { z-index: 10; width: 16px; @@ -362,6 +430,7 @@ display: block; width: 100%; height: 100%; + object-fit: cover; } .@{upload-item}-name { @@ -373,6 +442,8 @@ } .anticon-picture + .@{upload-item}-name { + position: absolute; + bottom: 10px; display: block; } diff --git a/components/upload/utils.jsx b/components/upload/utils.jsx index e46a1a92c..3642ce9fb 100644 --- a/components/upload/utils.jsx +++ b/components/upload/utils.jsx @@ -54,3 +54,77 @@ export function removeFileItem(file, fileList) { } return removed; } + +// ==================== Default Image Preview ==================== +const extname = (url = '') => { + const temp = url.split('/'); + const filename = temp[temp.length - 1]; + const filenameWithoutSuffix = filename.split(/#|\?/)[0]; + return (/\.[^./\\]*$/.exec(filenameWithoutSuffix) || [''])[0]; +}; + +const isImageFileType = type => !!type && type.indexOf('image/') === 0; + +export const isImageUrl = file => { + if (isImageFileType(file.type)) { + return true; + } + const url = file.thumbUrl || file.url; + const extension = extname(url); + if ( + /^data:image\//.test(url) || + /(webp|svg|png|gif|jpg|jpeg|jfif|bmp|dpg|ico)$/i.test(extension) + ) { + return true; + } + if (/^data:/.test(url)) { + // other file types of base64 + return false; + } + if (extension) { + // other file types which have extension + return false; + } + return true; +}; + +const MEASURE_SIZE = 200; +export function previewImage(file) { + return new Promise(resolve => { + if (!isImageFileType(file.type)) { + resolve(''); + return; + } + + const canvas = document.createElement('canvas'); + canvas.width = MEASURE_SIZE; + canvas.height = MEASURE_SIZE; + canvas.style.cssText = `position: fixed; left: 0; top: 0; width: ${MEASURE_SIZE}px; height: ${MEASURE_SIZE}px; z-index: 9999; display: none;`; + document.body.appendChild(canvas); + const ctx = canvas.getContext('2d'); + const img = new Image(); + img.onload = () => { + const { width, height } = img; + + let drawWidth = MEASURE_SIZE; + let drawHeight = MEASURE_SIZE; + let offsetX = 0; + let offsetY = 0; + + if (width < height) { + drawHeight = height * (MEASURE_SIZE / width); + offsetY = -(drawHeight - drawWidth) / 2; + } else { + drawWidth = width * (MEASURE_SIZE / height); + offsetX = -(drawWidth - drawHeight) / 2; + } + + ctx.drawImage(img, offsetX, offsetY, drawWidth, drawHeight); + const dataURL = canvas.toDataURL(); + document.body.removeChild(canvas); + + resolve(dataURL); + }; + img.src = window.URL.createObjectURL(file); + }); +} diff --git a/components/vc-align/Align.jsx b/components/vc-align/Align.jsx index 39fc58ea7..d853a01d5 100644 --- a/components/vc-align/Align.jsx +++ b/components/vc-align/Align.jsx @@ -1,6 +1,6 @@ import PropTypes from '../_util/vue-types'; import { alignElement, alignPoint } from 'dom-align'; -import addEventListener from '../_util/Dom/addEventListener'; +import addEventListener from '../vc-util/Dom/addEventListener'; import { isWindow, buffer, isSamePoint, isSimilarValue, restoreFocus } from './util'; import { cloneElement } from '../_util/vnode.js'; import clonedeep from 'lodash/cloneDeep'; diff --git a/components/vc-align/demo/point.vue b/components/vc-align/demo/point.vue deleted file mode 100644 index 1326df8fd..000000000 --- a/components/vc-align/demo/point.vue +++ /dev/null @@ -1,53 +0,0 @@ - diff --git a/components/vc-align/demo/simple.vue b/components/vc-align/demo/simple.vue deleted file mode 100644 index f46c344ed..000000000 --- a/components/vc-align/demo/simple.vue +++ /dev/null @@ -1,82 +0,0 @@ - diff --git a/components/vc-align/util.js b/components/vc-align/util.js index 246a2eac1..73e14d203 100644 --- a/components/vc-align/util.js +++ b/components/vc-align/util.js @@ -1,4 +1,4 @@ -import contains from '../_util/Dom/contains'; +import contains from '../vc-util/Dom/contains'; export function buffer(fn, ms) { let timer; diff --git a/components/vc-calendar/demo/antd-calendar.vue b/components/vc-calendar/demo/antd-calendar.vue deleted file mode 100644 index 4220d944a..000000000 --- a/components/vc-calendar/demo/antd-calendar.vue +++ /dev/null @@ -1,270 +0,0 @@ - diff --git a/components/vc-calendar/demo/antd-month-calendar.vue b/components/vc-calendar/demo/antd-month-calendar.vue deleted file mode 100644 index 1428d52f9..000000000 --- a/components/vc-calendar/demo/antd-month-calendar.vue +++ /dev/null @@ -1,156 +0,0 @@ - diff --git a/components/vc-calendar/demo/antd-range-calendar.vue b/components/vc-calendar/demo/antd-range-calendar.vue deleted file mode 100644 index f6e25db68..000000000 --- a/components/vc-calendar/demo/antd-range-calendar.vue +++ /dev/null @@ -1,204 +0,0 @@ - diff --git a/components/vc-calendar/demo/full-calendar.vue b/components/vc-calendar/demo/full-calendar.vue deleted file mode 100644 index d8ab6437c..000000000 --- a/components/vc-calendar/demo/full-calendar.vue +++ /dev/null @@ -1,75 +0,0 @@ - diff --git a/components/vc-calendar/index.js b/components/vc-calendar/index.js index a81bab944..685b89bba 100644 --- a/components/vc-calendar/index.js +++ b/components/vc-calendar/index.js @@ -1,4 +1,4 @@ -// based on rc-calendar 9.10.10 +// based on rc-calendar 9.15.8 import Vue from 'vue'; import ref from 'vue-ref'; import Calendar from './src/'; diff --git a/components/vc-calendar/src/Calendar.jsx b/components/vc-calendar/src/Calendar.jsx index d4079f855..9d1b16d3f 100644 --- a/components/vc-calendar/src/Calendar.jsx +++ b/components/vc-calendar/src/Calendar.jsx @@ -14,6 +14,13 @@ import enUs from './locale/en_US'; import { getTimeConfig, getTodayTime, syncTime } from './util'; import { goStartMonth, goEndMonth, goTime } from './util/toTime'; +const getMomentObjectIfValid = date => { + if (moment.isMoment(date) && date.isValid()) { + return date; + } + return false; +}; + const Calendar = { props: { locale: PropTypes.object.def(enUs), @@ -46,6 +53,7 @@ const Calendar = { renderSidebar: PropTypes.func.def(() => null), clearIcon: PropTypes.any, focusablePanel: PropTypes.bool.def(true), + inputMode: PropTypes.string, }, mixins: [BaseMixin, CommonMixin, CalendarMixin], @@ -54,7 +62,10 @@ const Calendar = { const props = this.$props; return { sMode: this.mode || 'date', - sValue: props.value || props.defaultValue || moment(), + sValue: + getMomentObjectIfValid(props.value) || + getMomentObjectIfValid(props.defaultValue) || + moment(), sSelectedValue: props.selectedValue || props.defaultSelectedValue, }; }, @@ -63,9 +74,11 @@ const Calendar = { this.setState({ sMode: val }); }, value(val) { - const sValue = val || this.defaultValue || getNowByCurrentStateValue(this.sValue); this.setState({ - sValue, + sValue: + getMomentObjectIfValid(val) || + getMomentObjectIfValid(this.defaultValue) || + getNowByCurrentStateValue(this.sValue), }); }, selectedValue(val) { @@ -190,6 +203,25 @@ const Calendar = { source: 'todayButton', }); }, + + onBlur(event) { + setTimeout(() => { + const dateInput = DateInput.getInstance(); + const rootInstance = this.rootInstance; + + if ( + !rootInstance || + rootInstance.contains(document.activeElement) || + (dateInput && dateInput.contains(document.activeElement)) + ) { + // focused element is still part of Calendar + return; + } + + this.$emit('blur', event); + }, 0); + }, + getRootDOMNode() { return this.$el; }, @@ -217,6 +249,9 @@ const Calendar = { sSelectedValue, sMode, renderFooter, + inputMode, + monthCellRender, + monthCellContentRender, $props: props, } = this; const clearIcon = getComponentFromProp(this, 'clearIcon'); @@ -267,6 +302,7 @@ const Calendar = { onChange={this.onDateInputChange} clearIcon={clearIcon} onSelect={this.onDateInputSelect} + inputMode={inputMode} /> ) : null; const children = []; @@ -286,6 +322,8 @@ const Calendar = { renderFooter={renderFooter} showTimePicker={showTimePicker} prefixCls={prefixCls} + monthCellRender={monthCellRender} + monthCellContentRender={monthCellContentRender} /> {timePicker && showTimePicker ? (
                diff --git a/components/vc-calendar/src/FullCalendar.jsx b/components/vc-calendar/src/FullCalendar.jsx index 2743d146b..a1e04649d 100644 --- a/components/vc-calendar/src/FullCalendar.jsx +++ b/components/vc-calendar/src/FullCalendar.jsx @@ -11,7 +11,7 @@ import enUs from './locale/en_US'; const FullCalendar = { props: { locale: PropTypes.object.def(enUs), - format: PropTypes.string, + format: PropTypes.oneOfType([PropTypes.string, PropTypes.array]), visible: PropTypes.bool.def(true), prefixCls: PropTypes.string.def('rc-calendar'), defaultType: PropTypes.string.def('date'), diff --git a/components/vc-calendar/src/MonthCalendar.jsx b/components/vc-calendar/src/MonthCalendar.jsx index d77c9eca6..f0a219614 100644 --- a/components/vc-calendar/src/MonthCalendar.jsx +++ b/components/vc-calendar/src/MonthCalendar.jsx @@ -14,7 +14,6 @@ const MonthCalendar = { visible: PropTypes.bool.def(true), prefixCls: PropTypes.string.def('rc-calendar'), monthCellRender: PropTypes.func, - dateCellRender: PropTypes.func, value: PropTypes.object, defaultValue: PropTypes.object, selectedValue: PropTypes.object, diff --git a/components/vc-calendar/src/Picker.jsx b/components/vc-calendar/src/Picker.jsx index 14246a9c3..53695c7b8 100644 --- a/components/vc-calendar/src/Picker.jsx +++ b/components/vc-calendar/src/Picker.jsx @@ -19,11 +19,12 @@ function isMoment(value) { } const MomentType = PropTypes.custom(isMoment); const Picker = { + name: 'Picker', props: { animation: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), disabled: PropTypes.bool, transitionName: PropTypes.string, - format: PropTypes.string, + format: PropTypes.oneOfType([PropTypes.string, PropTypes.array]), // onChange: PropTypes.func, // onOpenChange: PropTypes.func, children: PropTypes.func, @@ -35,8 +36,9 @@ const Picker = { placement: PropTypes.any.def('bottomLeft'), value: PropTypes.oneOfType([MomentType, PropTypes.arrayOf(MomentType)]), defaultValue: PropTypes.oneOfType([MomentType, PropTypes.arrayOf(MomentType)]), - align: PropTypes.object.def({}), + align: PropTypes.object.def(() => ({})), dropdownClassName: PropTypes.string, + dateRender: PropTypes.func, }, mixins: [BaseMixin], @@ -122,6 +124,10 @@ const Picker = { this.closeCalendar(this.focus); }, + onCalendarBlur() { + this.setOpen(false); + }, + onVisibleChange(open) { this.setOpen(open); }, @@ -143,6 +149,7 @@ const Picker = { ok: createChainedFunction(calendarEvents.ok, this.onCalendarOk), select: createChainedFunction(calendarEvents.select, this.onCalendarSelect), clear: createChainedFunction(calendarEvents.clear, this.onCalendarClear), + blur: createChainedFunction(calendarEvents.blur, this.onCalendarBlur), }, }; diff --git a/components/vc-calendar/src/RangeCalendar.jsx b/components/vc-calendar/src/RangeCalendar.jsx index 6aedccc8c..73f00dfc2 100644 --- a/components/vc-calendar/src/RangeCalendar.jsx +++ b/components/vc-calendar/src/RangeCalendar.jsx @@ -38,9 +38,15 @@ function isArraysEqual(a, b) { } function getValueFromSelectedValue(selectedValue) { - const [start, end] = selectedValue; - const newEnd = end && end.isSame(start, 'month') ? end.clone().add(1, 'month') : end; - return [start, newEnd]; + let [start, end] = selectedValue; + if (end && (start === undefined || start === null)) { + start = end.clone().subtract(1, 'month'); + } + + if (start && (end === undefined || end === null)) { + end = start.clone().add(1, 'month'); + } + return [start, end]; } function normalizeAnchor(props, init) { @@ -73,7 +79,7 @@ function onInputSelect(direction, value, cause) { const index = direction === 'left' ? 0 : 1; selectedValue[index] = value; if (selectedValue[0] && this.compare(selectedValue[0], selectedValue[1]) > 0) { - selectedValue[1 - index] = this.showTimePicker ? selectedValue[index] : undefined; + selectedValue[1 - index] = this.sShowTimePicker ? selectedValue[index] : undefined; } this.__emit('inputSelect', selectedValue); this.fireSelectValueChange(selectedValue, null, cause || { source: 'dateInput' }); @@ -89,7 +95,7 @@ const RangeCalendar = { defaultValue: PropTypes.any, value: PropTypes.any, hoverValue: PropTypes.any, - mode: PropTypes.arrayOf(PropTypes.oneOf(['date', 'month', 'year', 'decade'])), + mode: PropTypes.arrayOf(PropTypes.oneOf(['time', 'date', 'month', 'year', 'decade'])), showDateInput: PropTypes.bool.def(true), timePicker: PropTypes.any, showOk: PropTypes.bool, @@ -104,7 +110,7 @@ const RangeCalendar = { // onValueChange: PropTypes.func, // onHoverChange: PropTypes.func, // onPanelChange: PropTypes.func, - format: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), + format: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), // onClear: PropTypes.func, type: PropTypes.any.def('both'), disabledDate: PropTypes.func, @@ -127,8 +133,9 @@ const RangeCalendar = { firstSelectedValue: null, sHoverValue: props.hoverValue || [], sValue: value, - showTimePicker: false, + sShowTimePicker: false, sMode: props.mode || ['date', 'date'], + sPanelTriggerSource: '', // Trigger by which picker panel: 'start' & 'end' }; }, watch: { @@ -359,12 +366,12 @@ const RangeCalendar = { onOpenTimePicker() { this.setState({ - showTimePicker: true, + sShowTimePicker: true, }); }, onCloseTimePicker() { this.setState({ - showTimePicker: false, + sShowTimePicker: false, }); }, @@ -412,11 +419,13 @@ const RangeCalendar = { const newMode = [mode, sMode[1]]; const newValue = [value || sValue[0], sValue[1]]; this.__emit('panelChange', newValue, newMode); + const newState = { + sPanelTriggerSource: 'start', + }; if (!hasProp(this, 'mode')) { - this.setState({ - sMode: newMode, - }); + newState.sMode = newMode; } + this.setState(newState); }, onEndPanelChange(value, mode) { @@ -424,37 +433,74 @@ const RangeCalendar = { const newMode = [sMode[0], mode]; const newValue = [sValue[0], value || sValue[1]]; this.__emit('panelChange', newValue, newMode); + const newState = { + sPanelTriggerSource: 'start', + }; if (!hasProp(this, 'mode')) { - this.setState({ - sMode: newMode, - }); + newState.sMode = newMode; } + this.setState(newState); }, getStartValue() { - let value = this.sValue[0]; - const selectedValue = this.sSelectedValue; + const { + sSelectedValue: selectedValue, + sShowTimePicker: showTimePicker, + sValue: value, + sMode: mode, + sPanelTriggerSource: panelTriggerSource, + } = this.$data; + let startValue = value[0]; // keep selectedTime when select date - if (selectedValue[0] && this.timePicker) { - value = value.clone(); - syncTime(selectedValue[0], value); + if (selectedValue[0] && this.$props.timePicker) { + startValue = startValue.clone(); + syncTime(selectedValue[0], startValue); } - if (this.showTimePicker && selectedValue[0]) { - return selectedValue[0]; + if (showTimePicker && selectedValue[0]) { + startValue = selectedValue[0]; } - return value; + + // Adjust month if date not align + if ( + panelTriggerSource === 'end' && + mode[0] === 'date' && + mode[1] === 'date' && + startValue.isSame(value[1], 'month') + ) { + startValue = startValue.clone().subtract(1, 'month'); + } + + return startValue; }, getEndValue() { - const { sValue, sSelectedValue, showTimePicker } = this; - const endValue = sValue[1] ? sValue[1].clone() : sValue[0].clone().add(1, 'month'); + const { + sSelectedValue: selectedValue, + sShowTimePicker: showTimePicker, + sValue: value, + sMode: mode, + sPanelTriggerSource: panelTriggerSource, + } = this.$data; + let endValue = value[1] ? value[1].clone() : value[0].clone().add(1, 'month'); // keep selectedTime when select date - if (sSelectedValue[1] && this.timePicker) { - syncTime(sSelectedValue[1], endValue); + if (selectedValue[1] && this.$props.timePicker) { + syncTime(selectedValue[1], endValue); } if (showTimePicker) { - return sSelectedValue[1] ? sSelectedValue[1] : this.getStartValue(); + endValue = selectedValue[1] ? selectedValue[1] : this.getStartValue(); } + + // Adjust month if date not align + if ( + !showTimePicker && + panelTriggerSource !== 'end' && + mode[0] === 'date' && + mode[1] === 'date' && + endValue.isSame(value[0], 'month') + ) { + endValue = endValue.clone().add(1, 'month'); + } + return endValue; }, // get disabled hours for second picker @@ -596,12 +642,12 @@ const RangeCalendar = { disabledStartMonth(month) { const { sValue } = this; - return month.isSameOrAfter(sValue[1], 'month'); + return month.isAfter(sValue[1], 'month'); }, disabledEndMonth(month) { const { sValue } = this; - return month.isSameOrBefore(sValue[0], 'month'); + return month.isBefore(sValue[0], 'month'); }, }, @@ -619,12 +665,12 @@ const RangeCalendar = { seperator, } = props; const clearIcon = getComponentFromProp(this, 'clearIcon'); - const { sHoverValue, sSelectedValue, sMode, showTimePicker, sValue } = this; + const { sHoverValue, sSelectedValue, sMode: mode, sShowTimePicker, sValue } = this; const className = { [prefixCls]: 1, [`${prefixCls}-hidden`]: !props.visible, [`${prefixCls}-range`]: 1, - [`${prefixCls}-show-time-picker`]: showTimePicker, + [`${prefixCls}-show-time-picker`]: sShowTimePicker, [`${prefixCls}-week-number`]: props.showWeekNumber, }; const baseProps = { @@ -682,13 +728,13 @@ const RangeCalendar = { disabledMonth: this.disabledStartMonth, format: this.getFormat(), value: startValue, - mode: sMode[0], + mode: mode[0], placeholder: placeholder1, showDateInput: this.showDateInput, timePicker: timePicker, - showTimePicker: showTimePicker, + showTimePicker: sShowTimePicker || mode[0] === 'time', enablePrev: true, - enableNext: !isClosestMonths || this.isMonthYearPanelShow(sMode[1]), + enableNext: !isClosestMonths || this.isMonthYearPanelShow(mode[1]), clearIcon, }, on: { @@ -706,13 +752,13 @@ const RangeCalendar = { timePickerDisabledTime: this.getEndDisableTime(), placeholder: placeholder2, value: endValue, - mode: sMode[1], + mode: mode[1], showDateInput: this.showDateInput, timePicker: timePicker, - showTimePicker: showTimePicker, + showTimePicker: sShowTimePicker || mode[1] === 'time', disabledTime: this.disabledEndTime, disabledMonth: this.disabledEndMonth, - enablePrev: !isClosestMonths || this.isMonthYearPanelShow(sMode[0]), + enablePrev: !isClosestMonths || this.isMonthYearPanelShow(mode[0]), enableNext: true, clearIcon, }, @@ -742,7 +788,7 @@ const RangeCalendar = { if (props.timePicker) { const timePickerButtonProps = mergeProps(baseProps, { props: { - showTimePicker: showTimePicker, + showTimePicker: sShowTimePicker || (mode[0] === 'time' && mode[1] === 'time'), timePickerDisabled: !this.hasSelectedValue() || sHoverValue.length, }, on: { @@ -768,7 +814,7 @@ const RangeCalendar = { }); OkButtonNode = ; } - const extraFooter = this.renderFooter(sMode); + const extraFooter = this.renderFooter(mode); return (
                {props.renderSidebar()} diff --git a/components/vc-calendar/src/date/DateInput.jsx b/components/vc-calendar/src/date/DateInput.jsx index 0183fc97c..d96275411 100644 --- a/components/vc-calendar/src/date/DateInput.jsx +++ b/components/vc-calendar/src/date/DateInput.jsx @@ -8,7 +8,6 @@ import KeyCode from '../../../_util/KeyCode'; let cachedSelectionStart; let cachedSelectionEnd; let dateInputInstance; -import { isIE, isIE9 } from '../../../_util/env'; const DateInput = { mixins: [BaseMixin], @@ -26,6 +25,7 @@ const DateInput = { // onSelect: PropTypes.func, selectedValue: PropTypes.object, clearIcon: PropTypes.any, + inputMode: PropTypes.string, }, data() { @@ -141,13 +141,15 @@ const DateInput = { str: formatDate(prevProps.value, prevProps.format), })); }, - onKeyDown({ keyCode }) { + onKeyDown(event) { + const { keyCode } = event; const { value, disabledDate } = this.$props; if (keyCode === KeyCode.ENTER) { const validateDate = !disabledDate || !disabledDate(value); if (validateDate) { this.__emit('select', value.clone()); } + event.preventDefault(); } }, getRootDOMNode() { @@ -164,7 +166,7 @@ const DateInput = { }, render() { - const { invalid, str, locale, prefixCls, placeholder, disabled, showClear } = this; + const { invalid, str, locale, prefixCls, placeholder, disabled, showClear, inputMode } = this; const clearIcon = getComponentFromProp(this, 'clearIcon'); const invalidClass = invalid ? `${prefixCls}-input-invalid` : ''; return ( @@ -190,6 +192,7 @@ const DateInput = { onKeydown={this.onKeyDown} onFocus={this.onFocus} onBlur={this.onBlur} + inputMode={inputMode} />
                {showClear ? ( diff --git a/components/vc-calendar/src/date/DateTBody.jsx b/components/vc-calendar/src/date/DateTBody.jsx index bf3c04da1..4db6ada64 100644 --- a/components/vc-calendar/src/date/DateTBody.jsx +++ b/components/vc-calendar/src/date/DateTBody.jsx @@ -139,11 +139,21 @@ const DateTBody = { cls += ` ${selectedStartDateClass}`; } } - if (startValue && endValue) { + if (startValue || endValue) { if (isSameDay(current, endValue)) { selected = true; isActiveWeek = true; cls += ` ${selectedEndDateClass}`; + } else if ( + (startValue === null || startValue === undefined) && + current.isBefore(endValue, 'day') + ) { + cls += ` ${inRangeClass}`; + } else if ( + (endValue === null || endValue === undefined) && + current.isAfter(startValue, 'day') + ) { + cls += ` ${inRangeClass}`; } else if (current.isAfter(startValue, 'day') && current.isBefore(endValue, 'day')) { cls += ` ${inRangeClass}`; } diff --git a/components/vc-calendar/src/locale/hr_HR.js b/components/vc-calendar/src/locale/hr_HR.js new file mode 100644 index 000000000..670c6cb02 --- /dev/null +++ b/components/vc-calendar/src/locale/hr_HR.js @@ -0,0 +1,28 @@ +export default { + today: 'Danas', + now: 'Sad', + backToToday: 'Natrag na danas', + ok: 'Ok', + clear: 'Očisti', + month: 'Mjesec', + year: 'Godina', + timeSelect: 'odaberite vrijeme', + dateSelect: 'odaberite datum', + weekSelect: 'Odaberite tjedan', + monthSelect: 'Odaberite mjesec', + yearSelect: 'Odaberite godinu', + decadeSelect: 'Odaberite desetljeće', + yearFormat: 'YYYY', + dateFormat: 'D.M.YYYY', + dayFormat: 'D', + dateTimeFormat: 'D.M.YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'Prošli mjesec (PageUp)', + nextMonth: 'Sljedeći mjesec (PageDown)', + previousYear: 'Prošla godina (Control + left)', + nextYear: 'Sljedeća godina (Control + right)', + previousDecade: 'Prošlo desetljeće', + nextDecade: 'Sljedeće desetljeće', + previousCentury: 'Prošlo stoljeće', + nextCentury: 'Sljedeće stoljeće', +}; diff --git a/components/vc-calendar/src/locale/id_ID.js b/components/vc-calendar/src/locale/id_ID.js index 2004bfcdd..1c9df774f 100644 --- a/components/vc-calendar/src/locale/id_ID.js +++ b/components/vc-calendar/src/locale/id_ID.js @@ -13,14 +13,14 @@ export default { yearSelect: 'Pilih satu tahun', decadeSelect: 'Pilih satu dekade', yearFormat: 'YYYY', - dateFormat: 'M/D/YYYY', + dateFormat: 'D/M/YYYY', dayFormat: 'D', - dateTimeFormat: 'M/D/YYYY HH:mm:ss', + dateTimeFormat: 'D/M/YYYY HH:mm:ss', monthBeforeYear: true, previousMonth: 'Bulan sebelumnya (PageUp)', - nextMonth: 'Bulan depan (PageDown)', + nextMonth: 'Bulan selanjutnya (PageDown)', previousYear: 'Tahun lalu (Control + kiri)', - nextYear: 'Tahun depan (Kontrol + kanan)', + nextYear: 'Tahun selanjutnya (Kontrol + kanan)', previousDecade: 'Dekade terakhir', nextDecade: 'Dekade berikutnya', previousCentury: 'Abad terakhir', diff --git a/components/vc-calendar/src/locale/lv_LV.js b/components/vc-calendar/src/locale/lv_LV.js new file mode 100644 index 000000000..f06ffcd4f --- /dev/null +++ b/components/vc-calendar/src/locale/lv_LV.js @@ -0,0 +1,27 @@ +export default { + today: 'Šodien', + now: 'Tagad', + backToToday: 'Atpakaļ pie šodienas', + ok: 'Ok', + clear: 'Skaidrs', + month: 'Mēnesis', + year: 'Gads', + timeSelect: 'Izvēlieties laiku', + dateSelect: 'Izvēlieties datumu', + monthSelect: 'Izvēlieties mēnesi', + yearSelect: 'Izvēlieties gadu', + decadeSelect: 'Izvēlieties desmit gadus', + yearFormat: 'YYYY', + dateFormat: 'D.M.YYYY', + dayFormat: 'D', + dateTimeFormat: 'D.M.YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'Iepriekšējais mēnesis (PageUp)', + nextMonth: 'Nākammēnes (PageDown)', + previousYear: 'Pagājušais gads (Control + left)', + nextYear: 'Nākamgad (Control + right)', + previousDecade: 'Pēdējā desmitgadē', + nextDecade: 'Nākamā desmitgade', + previousCentury: 'Pagājušajā gadsimtā', + nextCentury: 'Nākamajā gadsimtā', +}; diff --git a/components/vc-calendar/src/locale/mk_MK.js b/components/vc-calendar/src/locale/mk_MK.js new file mode 100644 index 000000000..91d9188a8 --- /dev/null +++ b/components/vc-calendar/src/locale/mk_MK.js @@ -0,0 +1,27 @@ +export default { + today: 'Денес', + now: 'Сега', + backToToday: 'Назад до денес', + ok: 'ОК', + clear: 'Избриши', + month: 'Месец', + year: 'Година', + timeSelect: 'Избери време', + dateSelect: 'Избери датум', + monthSelect: 'Избери месец', + yearSelect: 'Избери година', + decadeSelect: 'Избери деценија', + yearFormat: 'YYYY', + dateFormat: 'D.M.YYYY', + dayFormat: 'D', + dateTimeFormat: 'D.M.YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'Претходен месец (PageUp)', + nextMonth: 'Нареден месец (PageDown)', + previousYear: 'Претходна година (Control + left)', + nextYear: 'Наредна година (Control + right)', + previousDecade: 'Претходна деценија', + nextDecade: 'Наредна деценија', + previousCentury: 'Претходен век', + nextCentury: 'Нареден век', +}; diff --git a/components/vc-calendar/src/locale/ms_MY.js b/components/vc-calendar/src/locale/ms_MY.js new file mode 100644 index 000000000..a721e3e4c --- /dev/null +++ b/components/vc-calendar/src/locale/ms_MY.js @@ -0,0 +1,27 @@ +export default { + today: 'Hari ini', + now: 'Sekarang', + backToToday: 'Kembali ke hari ini', + ok: 'Ok', + timeSelect: 'Pilih masa', + dateSelect: 'Pilih tarikh', + weekSelect: 'Pilih minggu', + clear: 'Padam', + month: 'Bulan', + year: 'Tahun', + previousMonth: 'Bulan lepas', + nextMonth: 'Bulan depan', + monthSelect: 'Pilih bulan', + yearSelect: 'Pilih tahun', + decadeSelect: 'Pilih dekad', + yearFormat: 'YYYY', + dayFormat: 'D', + dateFormat: 'M/D/YYYY', + dateTimeFormat: 'M/D/YYYY HH:mm:ss', + previousYear: 'Tahun lepas (Ctrl+left)', + nextYear: 'Tahun depan (Ctrl+right)', + previousDecade: 'Dekad lepas', + nextDecade: 'Dekad depan', + previousCentury: 'Abad lepas', + nextCentury: 'Abad depan', +}; diff --git a/components/vc-calendar/src/locale/ro_RO.js b/components/vc-calendar/src/locale/ro_RO.js new file mode 100644 index 000000000..d69416804 --- /dev/null +++ b/components/vc-calendar/src/locale/ro_RO.js @@ -0,0 +1,28 @@ +export default { + today: 'Azi', + now: 'Acum', + backToToday: 'Înapoi la azi', + ok: 'Ok', + clear: 'Șterge', + month: 'Lună', + year: 'An', + timeSelect: 'selectează timpul', + dateSelect: 'selectează data', + weekSelect: 'Alege o săptămână', + monthSelect: 'Alege o lună', + yearSelect: 'Alege un an', + decadeSelect: 'Alege un deceniu', + yearFormat: 'YYYY', + dateFormat: 'D/M/YYYY', + dayFormat: 'D', + dateTimeFormat: 'D/M/YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'Luna anterioară (PageUp)', + nextMonth: 'Luna următoare (PageDown)', + previousYear: 'Anul anterior (Control + stânga)', + nextYear: 'Anul următor (Control + dreapta)', + previousDecade: 'Deceniul anterior', + nextDecade: 'Deceniul următor', + previousCentury: 'Secolul anterior', + nextCentury: 'Secolul următor', +}; diff --git a/components/vc-calendar/src/locale/sk_SK.js b/components/vc-calendar/src/locale/sk_SK.js index fadd50b49..a543172ce 100644 --- a/components/vc-calendar/src/locale/sk_SK.js +++ b/components/vc-calendar/src/locale/sk_SK.js @@ -8,6 +8,7 @@ export default { year: 'Rok', timeSelect: 'Vybrať čas', dateSelect: 'Vybrať dátum', + weekSelect: 'Vybrať týždeň', monthSelect: 'Vybrať mesiac', yearSelect: 'Vybrať rok', decadeSelect: 'Vybrať dekádu', diff --git a/components/vc-calendar/src/locale/ta_IN.js b/components/vc-calendar/src/locale/ta_IN.js new file mode 100644 index 000000000..20ac8316b --- /dev/null +++ b/components/vc-calendar/src/locale/ta_IN.js @@ -0,0 +1,28 @@ +export default { + today: 'இன்று', + now: 'இப்போது', + backToToday: 'இன்றுக்கு திரும்பு', + ok: 'சரி', + clear: 'அழி', + month: 'மாதம்', + year: 'வருடம்', + timeSelect: 'நேரத்தைத் தேர்ந்தெடு', + dateSelect: 'தேதியைத் தேர்ந்தெடு', + weekSelect: 'வாரத்தைத் தேர்வுசெய்க', + monthSelect: 'மாதத்தைத் தேர்வுசெய்க', + yearSelect: 'வருடத்தைத் தேர்வுசெய்க', + decadeSelect: 'தசாப்தத்தைத் தேர்வுசெய்க', + yearFormat: 'YYYY', + dateFormat: 'M/D/YYYY', + dayFormat: 'D', + dateTimeFormat: 'M/D/YYYY HH:mm:ss', + monthBeforeYear: true, + previousMonth: 'முந்தைய மாதம் (PageUp)', + nextMonth: 'அடுத்த மாதம் (PageDown)', + previousYear: 'முந்தைய வருடம் (Control + left)', + nextYear: 'அடுத்த வருடம் (Control + right)', + previousDecade: 'முந்தைய தசாப்தம்', + nextDecade: 'அடுத்த தசாப்தம்', + previousCentury: 'முந்தைய நூற்றாண்டு', + nextCentury: 'அடுத்த நூற்றாண்டு', +}; diff --git a/components/vc-calendar/src/mixin/CalendarMixin.js b/components/vc-calendar/src/mixin/CalendarMixin.js index cb6a388c9..d1f53640f 100644 --- a/components/vc-calendar/src/mixin/CalendarMixin.js +++ b/components/vc-calendar/src/mixin/CalendarMixin.js @@ -72,7 +72,13 @@ const CalendarMixin = { [newProps.class]: !!newProps.class, }; return ( -
                +
                {newProps.children}
                ); diff --git a/components/vc-calendar/src/mixin/CommonMixin.js b/components/vc-calendar/src/mixin/CommonMixin.js index 14d34c5dc..5216c3a81 100644 --- a/components/vc-calendar/src/mixin/CommonMixin.js +++ b/components/vc-calendar/src/mixin/CommonMixin.js @@ -1,22 +1,4 @@ export default { - // getDefaultProps () { - // return { - // locale: enUs, - // visible: true, - // prefixCls: 'rc-calendar', - - // renderFooter () { - // return null - // }, - // renderSidebar () { - // return null - // }, - // } - // }, - - // shouldComponentUpdate (nextProps) { - // return this.props.visible || nextProps.visible - // }, methods: { getFormat() { let { format } = this; diff --git a/components/vc-calendar/src/range-calendar/CalendarPart.jsx b/components/vc-calendar/src/range-calendar/CalendarPart.jsx index 7ff0d8b3a..7ca6349cc 100644 --- a/components/vc-calendar/src/range-calendar/CalendarPart.jsx +++ b/components/vc-calendar/src/range-calendar/CalendarPart.jsx @@ -30,8 +30,9 @@ const CalendarPart = { timePickerDisabledTime: PropTypes.object, enableNext: PropTypes.any, enablePrev: PropTypes.any, - dateRender: PropTypes.func, clearIcon: PropTypes.any, + dateRender: PropTypes.func, + inputMode: PropTypes.string, }, render() { const { $props: props } = this; @@ -56,6 +57,8 @@ const CalendarPart = { showDateInput, dateRender, showWeekNumber, + showClear, + inputMode, } = props; const clearIcon = getComponentFromProp(this, 'clearIcon'); const { @@ -107,12 +110,13 @@ const CalendarPart = { placeholder={placeholder} disabledTime={disabledTime} value={value} - showClear={false} + showClear={showClear || false} selectedValue={selectedValue[index]} onChange={inputSelect} onChange={inputChange} onSelect={inputSelect} clearIcon={clearIcon} + inputMode={inputMode} /> ); const headerProps = { diff --git a/components/vc-calendar/src/util/index.js b/components/vc-calendar/src/util/index.js index 260f3ba86..59665f68f 100644 --- a/components/vc-calendar/src/util/index.js +++ b/components/vc-calendar/src/util/index.js @@ -38,6 +38,7 @@ export function syncTime(from, to) { to.hour(from.hour()); to.minute(from.minute()); to.second(from.second()); + to.millisecond(from.millisecond()); } export function getTimeConfig(value, disabledTime) { diff --git a/components/vc-cascader/Cascader.jsx b/components/vc-cascader/Cascader.jsx index e977e5040..0e9bedab6 100644 --- a/components/vc-cascader/Cascader.jsx +++ b/components/vc-cascader/Cascader.jsx @@ -60,7 +60,7 @@ export default { disabled: PropTypes.bool.def(false), transitionName: PropTypes.string.def(''), popupClassName: PropTypes.string.def(''), - popupStyle: PropTypes.object.def({}), + popupStyle: PropTypes.object.def(() => ({})), popupPlacement: PropTypes.string.def('bottomLeft'), prefixCls: PropTypes.string.def('rc-cascader'), dropdownMenuColumnStyle: PropTypes.object, @@ -69,7 +69,11 @@ export default { changeOnSelect: PropTypes.bool, // onKeyDown: PropTypes.func, expandTrigger: PropTypes.string.def('click'), - fieldNames: PropTypes.object.def({ label: 'label', value: 'value', children: 'children' }), + fieldNames: PropTypes.object.def(() => ({ + label: 'label', + value: 'value', + children: 'children', + })), expandIcon: PropTypes.any, loadingIcon: PropTypes.any, getPopupContainer: PropTypes.func, diff --git a/components/vc-cascader/demo/animation.vue b/components/vc-cascader/demo/animation.vue deleted file mode 100644 index b7b7c4b23..000000000 --- a/components/vc-cascader/demo/animation.vue +++ /dev/null @@ -1,80 +0,0 @@ - diff --git a/components/vc-cascader/demo/custom-field-name.vue b/components/vc-cascader/demo/custom-field-name.vue deleted file mode 100644 index b49fa5786..000000000 --- a/components/vc-cascader/demo/custom-field-name.vue +++ /dev/null @@ -1,85 +0,0 @@ - diff --git a/components/vc-checkbox/demo/simple.js b/components/vc-checkbox/demo/simple.js deleted file mode 100644 index 5d7fb079f..000000000 --- a/components/vc-checkbox/demo/simple.js +++ /dev/null @@ -1,70 +0,0 @@ -/* eslint no-console:0 */ -import Checkbox from '../index'; -import '../assets/index.less'; - -function onChange(e) { - console.log('Checkbox checked:', e.target.checked); -} - -export default { - data() { - return { - disabled: false, - }; - }, - methods: { - toggle() { - this.disabled = !this.disabled; - }, - }, - render() { - return ( -
                -
                -

                - -    -

                -

                - -    -

                -
                - -
                -

                - -    -

                -
                - -
                -

                - -    -

                -
                - - -
                - ); - }, -}; diff --git a/components/vc-collapse/demo/custom-icon.jsx b/components/vc-collapse/demo/custom-icon.jsx deleted file mode 100644 index dfca75818..000000000 --- a/components/vc-collapse/demo/custom-icon.jsx +++ /dev/null @@ -1,127 +0,0 @@ -import '../assets/index.less'; -import Collapse from '../index'; - -const text = ` - A dog is a type of domesticated animal. - Known for its loyalty and faithfulness, - it can be found as a welcome guest in many households across the world. -`; - -function random() { - return parseInt(Math.random() * 10, 10) + 1; -} - -const arrowPath = - 'M869 487.8L491.2 159.9c-2.9-2.5-6.6-3.9-10.5-3.9h-88' + - '.5c-7.4 0-10.8 9.2-5.2 14l350.2 304H152c-4.4 0-8 3.6-8 8v60c0 4.4 3.' + - '6 8 8 8h585.1L386.9 854c-5.6 4.9-2.2 14 5.2 14h91.5c1.9 0 3.8-0.7 5.' + - '2-2L869 536.2c14.7-12.8 14.7-35.6 0-48.4z'; - -const { Panel } = Collapse; -export default { - data() { - return { - time: random(), - accordion: false, - activeKey: ['4'], - }; - }, - methods: { - onChange(activeKey) { - this.activeKey = activeKey; - }, - getItems() { - const items = []; - for (let i = 0, len = 3; i < len; i++) { - const key = i + 1; - items.push( - -

                {text.repeat(this.time)}

                -
                , - ); - } - items.push( - - - -

                {text}

                -
                -
                -
                , - ); - - items.push( - - - -
                - - -
                -
                -
                -
                , - ); - - items.push( - Extra Node}> -

                Panel with extra

                -
                , - ); - - return items; - }, - setActivityKey() { - this.activeKey = ['2']; - }, - reRender() { - this.time = random(); - }, - toggle() { - this.accordion = !this.accordion; - }, - expandIcon({ isActive }) { - return ( - - - - - - ); - }, - }, - render() { - const accordion = this.accordion; - const btn = accordion ? 'Mode: accordion' : 'Mode: collapse'; - const activeKey = this.activeKey; - return ( -
                - - -
                -
                - -
                -
                - - {this.getItems()} - -
                - ); - }, -}; diff --git a/components/vc-collapse/demo/simple.jsx b/components/vc-collapse/demo/simple.jsx deleted file mode 100644 index 33d89672d..000000000 --- a/components/vc-collapse/demo/simple.jsx +++ /dev/null @@ -1,97 +0,0 @@ -import '../assets/index.less'; -import Collapse from '../index'; - -const text = ` - A dog is a type of domesticated animal. - Known for its loyalty and faithfulness, - it can be found as a welcome guest in many households across the world. -`; - -function random() { - return parseInt(Math.random() * 10, 10) + 1; -} - -const { Panel } = Collapse; -export default { - data() { - return { - time: random(), - accordion: false, - activeKey: ['4'], - }; - }, - methods: { - onChange(activeKey) { - this.activeKey = activeKey; - }, - getItems() { - const items = []; - for (let i = 0, len = 3; i < len; i++) { - const key = i + 1; - items.push( - -

                {text.repeat(this.time)}

                -
                , - ); - } - items.push( - - - -

                {text}

                -
                -
                -
                , - ); - - items.push( - - - -
                - - -
                -
                -
                -
                , - ); - - items.push( - Extra Node}> -

                Panel with extra

                -
                , - ); - - return items; - }, - setActivityKey() { - this.activeKey = ['2']; - }, - reRender() { - this.time = random(); - }, - toggle() { - this.accordion = !this.accordion; - }, - }, - render() { - const accordion = this.accordion; - const btn = accordion ? 'Mode: accordion' : 'Mode: collapse'; - const activeKey = this.activeKey; - return ( -
                - - -
                -
                - -
                -
                - - {this.getItems()} - -
                - ); - }, -}; diff --git a/components/vc-collapse/index.js b/components/vc-collapse/index.js index 733445fb1..4baee412e 100644 --- a/components/vc-collapse/index.js +++ b/components/vc-collapse/index.js @@ -1,4 +1,4 @@ -// based on rc-collapse 1.11.7 +// based on rc-collapse 1.11.8 import CollapsePanel from './src/Panel'; import Collapse from './src/Collapse'; import { collapseProps, panelProps } from './src/commonProps'; diff --git a/components/vc-collapse/src/commonProps.js b/components/vc-collapse/src/commonProps.js index 7ef65fd7e..ec1860c72 100644 --- a/components/vc-collapse/src/commonProps.js +++ b/components/vc-collapse/src/commonProps.js @@ -17,6 +17,7 @@ const collapseProps = () => ({ bordered: PropTypes.bool, expandIcon: PropTypes.func, openAnimation: PropTypes.object, + expandIconPosition: PropTypes.oneOf(['left', 'right']), }); const panelProps = () => ({ diff --git a/components/vc-dialog/Dialog.jsx b/components/vc-dialog/Dialog.jsx index e24f7f736..87541abed 100644 --- a/components/vc-dialog/Dialog.jsx +++ b/components/vc-dialog/Dialog.jsx @@ -1,6 +1,6 @@ import { getComponentFromProp, initDefaultProps } from '../_util/props-util'; import KeyCode from '../_util/KeyCode'; -import contains from '../_util/Dom/contains'; +import contains from '../vc-util/Dom/contains'; import LazyRenderBox from './LazyRenderBox'; import BaseMixin from '../_util/BaseMixin'; import getTransitionProps from '../_util/getTransitionProps'; diff --git a/components/vc-dialog/IDialogPropTypes.js b/components/vc-dialog/IDialogPropTypes.js index 346df327e..a15a153a5 100644 --- a/components/vc-dialog/IDialogPropTypes.js +++ b/components/vc-dialog/IDialogPropTypes.js @@ -32,8 +32,8 @@ function IDialogPropTypes() { maskProps: PropTypes.any, wrapProps: PropTypes.any, getContainer: PropTypes.any, - dialogStyle: PropTypes.object.def({}), - dialogClass: PropTypes.object.def({}), + dialogStyle: PropTypes.object.def(() => ({})), + dialogClass: PropTypes.object.def(() => ({})), closeIcon: PropTypes.any, forceRender: PropTypes.bool, getOpenCount: PropTypes.func, diff --git a/components/vc-dialog/demo/ant-design.vue b/components/vc-dialog/demo/ant-design.vue deleted file mode 100644 index 9237d4b66..000000000 --- a/components/vc-dialog/demo/ant-design.vue +++ /dev/null @@ -1,154 +0,0 @@ - diff --git a/components/vc-drawer/demo/change-remove.jsx b/components/vc-drawer/demo/change-remove.jsx deleted file mode 100644 index f2e75c196..000000000 --- a/components/vc-drawer/demo/change-remove.jsx +++ /dev/null @@ -1,111 +0,0 @@ -import Drawer from '../src/index'; -import Menu from '../../menu/index'; -import Icon from '../../icon/index'; -import '../assets/index.less'; -import '../../menu/style/index'; -import '../../icon/style/index'; - -const SubMenu = Menu.SubMenu; -const MenuItemGroup = Menu.ItemGroup; - -export default { - data() { - return { - show: true, - }; - }, - mounted() { - this.$nextTick(() => { - setTimeout(() => { - // this.show = false - }, 2000); - }); - }, - render() { - const drawerProps = { - props: { - wrapperClassName: 'drawer-wrapper', - width: '20vw', - }, - slots: { - handler: () => { - return ( -
                alert('click')}> - -
                - ); - }, - }, - }; - return ( -
                - {this.show && ( - - - - - Navigation One - - } - > - - Option 1 - Option 2 - - - Option 3 - Option 4 - - - - - Navigation Two - - } - > - Option 5 - Option 6 - - Option 7 - Option 8 - - - - - Navigation Three - - } - > - Option 9 - Option 10 - Option 11 - Option 12 - - - - )} -
                - 内容区块 -
                -
                - ); - }, -}; diff --git a/components/vc-drawer/demo/change.jsx b/components/vc-drawer/demo/change.jsx deleted file mode 100644 index 3502e2786..000000000 --- a/components/vc-drawer/demo/change.jsx +++ /dev/null @@ -1,118 +0,0 @@ -import Drawer from '../src/index'; -import Menu from '../../menu/index'; -import Icon from '../../icon/index'; -import '../assets/index.less'; -import '../../menu/style/index'; -import '../../icon/style/index'; - -const SubMenu = Menu.SubMenu; -const MenuItemGroup = Menu.ItemGroup; - -export default { - data() { - return { - open: true, - }; - }, - mounted() { - this.$nextTick(() => { - setTimeout(() => { - this.open = false; - }, 2000); - }); - }, - methods: { - onChange(bool) { - console.log(bool); - }, - onTouchEnd() { - this.open = false; - }, - onSwitch() { - this.open = !this.open; - }, - }, - render() { - return ( -
                - - - - - Navigation One - - } - > - - Option 1 - Option 2 - - - Option 3 - Option 4 - - - - - Navigation Two - - } - > - Option 5 - Option 6 - - Option 7 - Option 8 - - - - - Navigation Three - - } - > - Option 9 - Option 10 - Option 11 - Option 12 - - - -
                - 内容区块 - -
                -
                - ); - }, -}; diff --git a/components/vc-drawer/demo/getContainer.jsx b/components/vc-drawer/demo/getContainer.jsx deleted file mode 100644 index bf282f823..000000000 --- a/components/vc-drawer/demo/getContainer.jsx +++ /dev/null @@ -1,76 +0,0 @@ -import Drawer from '../src/index'; -import Menu from '../../menu/index'; -import Icon from '../../icon/index'; -import '../assets/index.less'; -import '../../menu/style/index'; -import '../../icon/style/index'; - -const SubMenu = Menu.SubMenu; -const MenuItemGroup = Menu.ItemGroup; - -export default { - methods: { - getContainer() { - return this.$refs.container; - }, - }, - render() { - return ( -
                -
                - - - - - Navigation One - - } - > - - Option 1 - Option 2 - - - Option 3 - Option 4 - - - - - Navigation Two - - } - > - Option 5 - Option 6 - - Option 7 - Option 8 - - - - - Navigation Three - - } - > - Option 9 - Option 10 - Option 11 - Option 12 - - - -
                - ); - }, -}; diff --git a/components/vc-drawer/demo/level.jsx b/components/vc-drawer/demo/level.jsx deleted file mode 100644 index d578fd4f5..000000000 --- a/components/vc-drawer/demo/level.jsx +++ /dev/null @@ -1,97 +0,0 @@ -import Drawer from '../src/index'; -import Menu from '../../menu/index'; -import Icon from '../../icon/index'; -import Button from '../../button/index'; -import '../assets/index.less'; -import '../../menu/style/index'; -import '../../icon/style/index'; -import '../../button/style/index'; - -const SubMenu = Menu.SubMenu; -const MenuItemGroup = Menu.ItemGroup; - -export default { - data() { - return { - level: ['body > h1', '#__react-content'], - }; - }, - methods: { - onClick() { - this.level = this.level ? null : ['body > h1', '#__react-content']; - }, - }, - render() { - return ( -
                - - - - - Navigation One - - } - > - - Option 1 - Option 2 - - - Option 3 - Option 4 - - - - - Navigation Two - - } - > - Option 5 - Option 6 - - Option 7 - Option 8 - - - - - Navigation Three - - } - > - Option 9 - Option 10 - Option 11 - Option 12 - - - -
                - 内容区块 - -
                -
                - ); - }, -}; diff --git a/components/vc-drawer/demo/multiple.jsx b/components/vc-drawer/demo/multiple.jsx deleted file mode 100644 index 9856604a5..000000000 --- a/components/vc-drawer/demo/multiple.jsx +++ /dev/null @@ -1,88 +0,0 @@ -import Drawer from '../src/index'; -import Button from '../../button/index'; -import '../assets/index.less'; -import '../../menu/style/index'; -import '../../icon/style/index'; -import '../../button/style/index'; - -export default { - data() { - return { - open: false, - openChild: false, - openChildren: false, - }; - }, - methods: { - onClick() { - this.open = !this.open; - }, - onChildClick() { - this.openChild = !this.openChild; - }, - onChildrenClick() { - this.openChildren = !this.openChildren; - }, - getLevelMove(e) { - const target = e.target; - if (target.className.indexOf('drawer1') >= 0) { - return [200, 100]; - } - return 100; - }, - }, - render() { - return ( -
                -
                - -
                - -
                - - -
                - 二级抽屉 - - -
                三级抽屉
                -
                -
                -
                -
                -
                -
                - ); - }, -}; diff --git a/components/vc-drawer/demo/placement.jsx b/components/vc-drawer/demo/placement.jsx deleted file mode 100644 index 5c2a4bee3..000000000 --- a/components/vc-drawer/demo/placement.jsx +++ /dev/null @@ -1,116 +0,0 @@ -import Drawer from '../src/index'; -import Menu from '../../menu/index'; -import Icon from '../../icon/index'; -import '../assets/index.less'; -import '../../menu/style/index'; -import '../../icon/style/index'; -import '../../button/style/index'; -import '../../select/style/index'; - -const SubMenu = Menu.SubMenu; -const MenuItemGroup = Menu.ItemGroup; - -export default { - data() { - return { - placement: 'right', - childShow: true, - width: '20vw', - height: null, - }; - }, - methods: { - onChange(event) { - const value = event.target.value; - this.placement = value; - this.width = value === 'right' || value === 'left' ? '20vw' : null; - this.height = value === 'right' || value === 'left' ? null : '20vh'; - this.childShow = false; // 删除子级,删除切换时的过渡动画。。。 - this.$nextTick(() => { - this.childShow = true; - }); - }, - }, - render() { - return ( -
                - {this.childShow && ( - - - - - Navigation One - - } - > - - Option 1 - Option 2 - - - Option 3 - Option 4 - - - - - Navigation Two - - } - > - Option 5 - Option 6 - - Option 7 - Option 8 - - - - - Navigation Three - - } - > - Option 9 - Option 10 - Option 11 - Option 12 - - - - )} -
                - 选择位置: - -
                -
                - ); - }, -}; diff --git a/components/vc-drawer/src/Drawer.js b/components/vc-drawer/src/Drawer.js index 6743b3b99..bb30a7e54 100644 --- a/components/vc-drawer/src/Drawer.js +++ b/components/vc-drawer/src/Drawer.js @@ -6,7 +6,8 @@ import { initDefaultProps, getEvents, getListeners } from '../../_util/props-uti import { cloneElement } from '../../_util/vnode'; import ContainerRender from '../../_util/ContainerRender'; import getScrollBarSize from '../../_util/getScrollBarSize'; -import drawerProps from './drawerProps'; +import { IDrawerProps } from './IDrawerPropTypes'; +import KeyCode from '../../_util/KeyCode'; import { dataToArray, transitionEnd, @@ -29,7 +30,7 @@ const windowIsUndefined = !( Vue.use(ref, { name: 'ant-ref' }); const Drawer = { mixins: [BaseMixin], - props: initDefaultProps(drawerProps, { + props: initDefaultProps(IDrawerProps, { prefixCls: 'drawer', placement: 'left', getContainer: 'body', @@ -151,8 +152,14 @@ const Drawer = { } }, methods: { + onKeyDown(e) { + if (e.keyCode === KeyCode.ESC) { + e.stopPropagation(); + this.$emit('close', e); + } + }, onMaskTouchEnd(e) { - this.$emit('maskClick', e); + this.$emit('close', e); this.onTouchEnd(e, true); }, onIconTouchEnd(e) { @@ -170,15 +177,19 @@ const Drawer = { }); }, onWrapperTransitionEnd(e) { - if (e.target === this.contentWrapper) { + if (e.target === this.contentWrapper && e.propertyName.match(/transform$/)) { + const open = this.getOpen(); this.dom.style.transition = ''; - if (!this.sOpen && this.getCurrentDrawerSome()) { + if (!open && this.getCurrentDrawerSome()) { document.body.style.overflowX = ''; if (this.maskDom) { this.maskDom.style.left = ''; this.maskDom.style.width = ''; } } + if (this.afterVisibleChange) { + this.afterVisibleChange(!!open); + } } }, getDefault(props) { @@ -380,12 +391,15 @@ const Drawer = { width, height, wrapStyle, + keyboard, + maskClosable, } = this.$props; const children = this.$slots.default; const wrapperClassname = classnames(prefixCls, { [`${prefixCls}-${placement}`]: true, [`${prefixCls}-open`]: open, [className]: !!className, + 'no-mask': !showMask, }); const isOpenChange = this.isOpenChange; const isHorizontal = placement === 'left' || placement === 'right'; @@ -428,7 +442,6 @@ const Drawer = { ], }); } - const domContProps = { class: wrapperClassname, directives: [ @@ -441,6 +454,7 @@ const Drawer = { ], on: { transitionend: this.onWrapperTransitionEnd, + keydown: open && keyboard ? this.onKeyDown : noop, }, style: wrapStyle, }; @@ -469,11 +483,11 @@ const Drawer = { }, ]; return ( -
                +
                {showMask && (
                @@ -610,7 +624,7 @@ const Drawer = { }, ]; return ( -
                +
                {children}
                ); diff --git a/components/vc-drawer/src/drawerProps.js b/components/vc-drawer/src/IDrawerPropTypes.js similarity index 66% rename from components/vc-drawer/src/drawerProps.js rename to components/vc-drawer/src/IDrawerPropTypes.js index 28fedb2b8..6e0cc4bb1 100644 --- a/components/vc-drawer/src/drawerProps.js +++ b/components/vc-drawer/src/IDrawerPropTypes.js @@ -1,7 +1,6 @@ import PropTypes from '../../_util/vue-types'; -export default { - wrapperClassName: PropTypes.string, +const IProps = { width: PropTypes.any, height: PropTypes.any, defaultOpen: PropTypes.bool, @@ -13,15 +12,33 @@ export default { levelMove: PropTypes.oneOfType([PropTypes.number, PropTypes.func, PropTypes.array]), ease: PropTypes.string, duration: PropTypes.string, + handler: PropTypes.any, + showMask: PropTypes.bool, + maskStyle: PropTypes.object, + className: PropTypes.string, + wrapStyle: PropTypes.object, + maskClosable: PropTypes.bool, + afterVisibleChange: PropTypes.func, + keyboard: PropTypes.bool, +}; + +const IDrawerProps = { + ...IProps, + wrapperClassName: PropTypes.string, + forceRender: PropTypes.bool, getContainer: PropTypes.oneOfType([ PropTypes.string, PropTypes.func, PropTypes.object, PropTypes.bool, ]), - handler: PropTypes.any, - showMask: PropTypes.bool, - maskStyle: PropTypes.object, - className: PropTypes.string, - wrapStyle: PropTypes.object, }; + +const IDrawerChildProps = { + ...IProps, + getContainer: PropTypes.func, + getOpenCount: PropTypes.func, + switchScrollingEffect: PropTypes.func, +}; + +export { IDrawerProps, IDrawerChildProps }; diff --git a/components/vc-drawer/src/utils.js b/components/vc-drawer/src/utils.js index cf612ea34..7da5b91e3 100644 --- a/components/vc-drawer/src/utils.js +++ b/components/vc-drawer/src/utils.js @@ -54,3 +54,48 @@ export function transformArguments(arg, cb) { export const isNumeric = value => { return !isNaN(parseFloat(value)) && isFinite(value); // eslint-disable-line }; + +export const windowIsUndefined = !( + typeof window !== 'undefined' && + window.document && + window.document.createElement +); + +export const getTouchParentScroll = (root, currentTarget, differX, differY) => { + if (!currentTarget || currentTarget === document || currentTarget instanceof Document) { + return false; + } + // root 为 drawer-content 设定了 overflow, 判断为 root 的 parent 时结束滚动; + if (currentTarget === root.parentNode) { + return true; + } + + const isY = Math.max(Math.abs(differX), Math.abs(differY)) === Math.abs(differY); + const isX = Math.max(Math.abs(differX), Math.abs(differY)) === Math.abs(differX); + + const scrollY = currentTarget.scrollHeight - currentTarget.clientHeight; + const scrollX = currentTarget.scrollWidth - currentTarget.clientWidth; + + const style = document.defaultView.getComputedStyle(currentTarget); + const overflowY = style.overflowY === 'auto' || style.overflowY === 'scroll'; + const overflowX = style.overflowX === 'auto' || style.overflowX === 'scroll'; + + const y = scrollY && overflowY; + const x = scrollX && overflowX; + + if ( + (isY && + (!y || + (y && + ((currentTarget.scrollTop >= scrollY && differY < 0) || + (currentTarget.scrollTop <= 0 && differY > 0))))) || + (isX && + (!x || + (x && + ((currentTarget.scrollLeft >= scrollX && scrollX < 0) || + (currentTarget.scrollLeft <= 0 && scrollX > 0))))) + ) { + return getTouchParentScroll(root, currentTarget.parentNode, differX, differY); + } + return false; +}; diff --git a/components/vc-dropdown/demo/simple.jsx b/components/vc-dropdown/demo/simple.jsx deleted file mode 100644 index ccccb0121..000000000 --- a/components/vc-dropdown/demo/simple.jsx +++ /dev/null @@ -1,35 +0,0 @@ -import Menu, { Item as MenuItem, Divider } from '../../vc-menu/index'; -import Dropdown from '../src/index.js'; -import '../assets/index.less'; - -export default { - data() { - return {}; - }, - methods: { - onSelect({ key }) { - console.log(`${key} selected`); - }, - onVisibleChange(visible) { - console.log(visible); - }, - }, - render() { - return ( -
                -
                -
                - - - disabled - one - - two - - - -
                -
                - ); - }, -}; diff --git a/components/vc-dropdown/src/Dropdown.jsx b/components/vc-dropdown/src/Dropdown.jsx index 767ccbc70..4b08d2172 100644 --- a/components/vc-dropdown/src/Dropdown.jsx +++ b/components/vc-dropdown/src/Dropdown.jsx @@ -8,14 +8,14 @@ import { cloneElement } from '../../_util/vnode'; export default { mixins: [BaseMixin], props: { - minOverlayWidthMatchTrigger: PropTypes.bool.def(true), + minOverlayWidthMatchTrigger: PropTypes.bool, prefixCls: PropTypes.string.def('rc-dropdown'), transitionName: PropTypes.string, overlayClassName: PropTypes.string.def(''), openClassName: PropTypes.string, animation: PropTypes.any, align: PropTypes.object, - overlayStyle: PropTypes.object.def({}), + overlayStyle: PropTypes.object.def(() => ({})), placement: PropTypes.string.def('bottomLeft'), overlay: PropTypes.any, trigger: PropTypes.array.def(['hover']), @@ -198,7 +198,6 @@ export default { }, ref: 'trigger', }; - const child = this.$slots.default && this.$slots.default[0]; return ( {this.renderChildren()} diff --git a/components/vc-form/demo/async-init.js b/components/vc-form/demo/async-init.js deleted file mode 100644 index 556965888..000000000 --- a/components/vc-form/demo/async-init.js +++ /dev/null @@ -1,132 +0,0 @@ -/* eslint no-console:0 */ - -import { createForm } from '../index'; -import { regionStyle, errorStyle } from './styles'; -import BaseMixin from '../../_util/BaseMixin'; - -const Email = { - props: { - form: Object, - }, - methods: { - checkSpecial(rule, value, callback) { - setTimeout(() => { - if (value === 'yiminghe@gmail.com') { - callback('can not be!'); - } else { - callback(); - } - }, 1000); - }, - }, - - render() { - const { getFieldProps, getFieldError, isFieldValidating } = this.form; - const errors = getFieldError('email'); - return ( -
                -
                email validate onBlur
                -
                - -
                -
                {errors ? errors.join(',') : null}
                -
                {isFieldValidating('email') ? 'validating' : null}
                -
                - ); - }, -}; - -const Form = { - mixins: [BaseMixin], - props: { - form: Object, - }, - data() { - return { - loading: true, - }; - }, - - mounted() { - setTimeout(() => { - this.setState( - { - loading: false, - }, - () => { - setTimeout(() => { - this.form.setFieldsInitialValue({ - email: 'xx@gmail.com', - }); - }, 1000); - }, - ); - }, 1000); - }, - methods: { - onSubmit(e) { - e.preventDefault(); - this.form.submit(callback => { - setTimeout(() => { - this.form.validateFields((error, values) => { - if (!error) { - console.log('ok', values); - } else { - console.log('error', error, values); - } - callback(); - }); - }, 1000); - }); - }, - - reset(e) { - e.preventDefault(); - this.form.resetFields(); - }, - }, - - render() { - if (this.loading) { - return loading; - } - const { form } = this; - const disabled = form.isFieldsValidating() || form.isSubmitting(); - return ( -
                -

                async init field

                -
                - - -
                - -  {disabled ? disabled : null}  - -
                - -
                - ); - }, -}; - -export default createForm()(Form); diff --git a/components/vc-form/demo/dynamic-fields.js b/components/vc-form/demo/dynamic-fields.js deleted file mode 100644 index f771ea3ad..000000000 --- a/components/vc-form/demo/dynamic-fields.js +++ /dev/null @@ -1,287 +0,0 @@ -/* eslint no-console:0 */ - -import { createForm } from '../index'; -import BaseMixin from '../../_util/BaseMixin'; - -const Form1 = { - mixins: [BaseMixin], - props: { - form: Object, - }, - data() { - return { - useInput: true, - }; - }, - methods: { - onSubmit(e) { - e.preventDefault(); - this.form.validateFields((error, values) => { - if (!error) { - console.log('ok', values); - } else { - console.log('error', error, values); - } - }); - }, - changeUseInput(e) { - this.setState({ - useInput: e.target.checked, - }); - }, - }, - - render() { - const { getFieldError, getFieldDecorator } = this.form; - - return ( -
                -

                situation 1

                - {this.useInput - ? getFieldDecorator('name', { - initialValue: '', - rules: [ - { - required: true, - message: "What's your name 1?", - }, - ], - })() - : null} - text content - {this.useInput - ? null - : getFieldDecorator('name', { - initialValue: '', - rules: [ - { - required: true, - message: "What's your name 2?", - }, - ], - })()} -
                - - {(getFieldError('name') || []).join(', ')} -
                - -
                - ); - }, -}; - -const Form2 = { - mixins: [BaseMixin], - props: { - form: Object, - }, - data() { - return { - useInput: true, - }; - }, - beforeMount() { - const { getFieldDecorator } = this.form; - this.nameDecorator = getFieldDecorator('name', { - initialValue: '', - rules: [ - { - required: true, - message: "What's your name?", - }, - ], - }); - }, - methods: { - onSubmit(e) { - e.preventDefault(); - this.form.validateFields((error, values) => { - if (!error) { - console.log('ok', values); - } else { - console.log('error', error, values); - } - }); - }, - changeUseInput(e) { - this.setState({ - useInput: e.target.checked, - }); - }, - }, - - render() { - const { getFieldError } = this.form; - return ( -
                -

                situation 2

                - {this.useInput ? this.nameDecorator() : null} - text content - {this.useInput ? null : this.nameDecorator()} -
                - - {(getFieldError('name') || []).join(', ')} -
                - -
                - ); - }, -}; - -const Form3 = { - mixins: [BaseMixin], - props: { - form: Object, - }, - data() { - return { - useInput: false, - }; - }, - methods: { - onSubmit(e) { - e.preventDefault(); - this.form.validateFields((error, values) => { - if (!error) { - console.log('ok', values); - } else { - console.log('error', error, values); - } - }); - }, - changeUseInput(e) { - this.setState({ - useInput: e.target.checked, - }); - }, - }, - - render() { - const { getFieldError, getFieldDecorator } = this.form; - return ( -
                -

                situation 3

                - {getFieldDecorator('name', { - initialValue: '', - rules: [ - { - required: true, - message: "What's your name 1?", - }, - ], - })()} - {this.useInput - ? null - : getFieldDecorator('name2', { - initialValue: '', - rules: [ - { - required: true, - message: "What's your name 2?", - }, - ], - })()} -
                - - {(getFieldError('name') || []).join(', ')} -
                - -
                - ); - }, -}; - -const Form4 = { - mixins: [BaseMixin], - props: { - form: Object, - }, - data() { - return { - useInput: true, - }; - }, - methods: { - onSubmit(e) { - e.preventDefault(); - this.form.validateFields((error, values) => { - if (!error) { - console.log('ok', values); - } else { - console.log('error', error, values); - } - }); - }, - changeUseInput(e) { - this.setState({ - useInput: e.target.checked, - }); - }, - }, - - render() { - const { getFieldError, getFieldDecorator } = this.form; - return ( -
                -

                situation 4

                - {this.useInput - ? getFieldDecorator('name', { - initialValue: '', - trigger: 'input', - rules: [ - { - required: true, - message: "What's your name 1?", - }, - ], - })() - : getFieldDecorator('name2', { - initialValue: '', - trigger: 'input', - rules: [ - { - required: true, - message: "What's your name 2?", - }, - ], - })()} -
                - - {(getFieldError('name') || []).join(', ')} - {(getFieldError('name2') || []).join(', ')} -
                - -
                - ); - }, -}; - -const WrappedForm1 = createForm()(Form1); -const WrappedForm2 = createForm()(Form2); -const WrappedForm3 = createForm()(Form3); -const WrappedForm4 = createForm()(Form4); - -export default { - render() { - return ( -
                - - - - -
                - ); - }, -}; diff --git a/components/vc-form/demo/dynamic.js b/components/vc-form/demo/dynamic.js deleted file mode 100644 index 8b1091b1d..000000000 --- a/components/vc-form/demo/dynamic.js +++ /dev/null @@ -1,144 +0,0 @@ -/* eslint no-console:0 */ - -import { createForm } from '../index'; -import { regionStyle, errorStyle } from './styles'; - -const Email = { - props: { - form: Object, - hidden: Boolean, - }, - render() { - const { hidden, form } = this; - const { getFieldProps, getFieldError, isFieldValidating } = form; - const errors = getFieldError('email'); - const style = { - ...regionStyle, - display: hidden ? 'none' : '', - }; - return ( -
                -
                - email: - -
                - - {errors ?
                {errors.join(',')}
                : null} - - {isFieldValidating('email') ?
                validating
                : null} -
                - ); - }, -}; - -const User = { - props: { - form: Object, - }, - render() { - const { getFieldProps, getFieldError, isFieldValidating } = this.form; - const errors = getFieldError('user'); - return ( -
                -
                - user: - -
                - {errors ?
                {errors.join(',')}
                : null} - - {isFieldValidating('user') ?
                validating
                : null} -
                - ); - }, -}; - -const Form = { - props: { - form: Object, - }, - methods: { - onSubmit(e) { - e.preventDefault(); - this.form.validateFields((error, values) => { - if (!error) { - console.log('ok', values); - } else { - console.log('error', error, values); - } - }); - }, - }, - - render() { - const { form } = this; - const { getFieldProps, getFieldValue } = form; - return ( -
                -

                overview

                -
                -
                -
                - -
                -
                - - {getFieldValue('remove_user') ? null : } - -
                -
                - -
                -
                - -
                - ); - }, -}; - -export default createForm()(Form); diff --git a/components/vc-form/demo/file-input.js b/components/vc-form/demo/file-input.js deleted file mode 100644 index 3a3bc0b04..000000000 --- a/components/vc-form/demo/file-input.js +++ /dev/null @@ -1,85 +0,0 @@ -/* eslint no-console:0 */ - -import { createForm } from '../index'; -import { regionStyle, errorStyle } from './styles'; - -function getFileValueProps(value) { - if (value && value.target) { - return { - value: value.target.value, - }; - } - return { - value, - }; -} - -function getValueFromFileEvent({ target }) { - return { - target, - }; -} - -const Form = { - props: { - form: Object, - }, - methods: { - onSubmit(e) { - e.preventDefault(); - this.form.validateFields((error, values) => { - console.log(error, values); - if (!error) { - console.log('校验通过'); - } - }); - }, - checkSize(rule, value, callback) { - if (value && value.target) { - const files = value.target.files; - if (files[0]) { - callback(files[0].size > 1000000 ? 'file size must be less than 1M' : undefined); - } else { - callback(); - } - } else { - callback(); - } - }, - }, - - render() { - const { getFieldProps, getFieldError } = this.form; - const errors = getFieldError('attachment'); - return ( -
                -
                attachment:
                -
                - -
                -
                {errors ? errors.join(',') : null}
                - -
                - ); - }, -}; - -const NewForm = createForm()(Form); - -export default { - render() { - return ( -
                -

                input[type="file"]

                - -
                - ); - }, -}; diff --git a/components/vc-form/demo/getFieldDecorator.js b/components/vc-form/demo/getFieldDecorator.js deleted file mode 100644 index de2ecf7cf..000000000 --- a/components/vc-form/demo/getFieldDecorator.js +++ /dev/null @@ -1,51 +0,0 @@ -/* eslint no-console:0 */ - -import { createForm } from '../index'; - -const Form = { - props: { - form: Object, - }, - - beforeMount() { - this.nameDecorator = this.form.getFieldDecorator('name', { - initialValue: '', - rules: [ - { - required: true, - message: "What's your name?", - }, - ], - }); - }, - methods: { - onSubmit(e) { - e.preventDefault(); - this.form.validateFields((error, values) => { - if (!error) { - console.log('ok', values); - } else { - console.log('error', error, values); - } - }); - }, - - onChange(e) { - console.log(e.target.value); - }, - }, - - render() { - const { getFieldError } = this.form; - - return ( -
                - {this.nameDecorator()} -
                {(getFieldError('name') || []).join(', ')}
                - -
                - ); - }, -}; - -export default createForm()(Form); diff --git a/components/vc-form/demo/input-array.jsx b/components/vc-form/demo/input-array.jsx deleted file mode 100644 index 0d3b939ff..000000000 --- a/components/vc-form/demo/input-array.jsx +++ /dev/null @@ -1,69 +0,0 @@ -/* eslint no-console:0 */ - -import { createForm } from '../index'; -import { regionStyle } from './styles'; - -let uuid = 0; - -const Form = { - props: { - form: Object, - }, - methods: { - remove(k) { - const { form } = this; - // can use data-binding to get - let keys = form.getFieldValue('keys'); - keys = keys.filter(key => { - return key !== k; - }); - // can use data-binding to set - form.setFieldsValue({ - keys, - }); - }, - add() { - uuid++; - const { form } = this; - // can use data-binding to get - let keys = form.getFieldValue('keys'); - keys = keys.concat(uuid); - // can use data-binding to set - // important! notify form to detect changes - form.setFieldsValue({ - keys, - }); - }, - submit(e) { - e.preventDefault(); - console.log(this.form.getFieldsValue()); - }, - }, - - render() { - const { getFieldProps, getFieldValue } = this.form; - getFieldProps('keys', { - initialValue: [], - }); - const inputs = getFieldValue('keys').map(k => { - return ( -
                - - delete -
                - ); - }); - return ( -
                - {inputs} -
                - - - -
                -
                - ); - }, -}; - -export default createForm()(Form); diff --git a/components/vc-form/demo/modal.js b/components/vc-form/demo/modal.js deleted file mode 100644 index bc7253a14..000000000 --- a/components/vc-form/demo/modal.js +++ /dev/null @@ -1,91 +0,0 @@ -/* eslint no-console:0 */ - -import BaseMixin from '../../_util/BaseMixin'; -import createDOMForm from '../src/createDOMForm'; -import { Modal } from 'ant-design-vue'; -import { regionStyle, errorStyle } from './styles'; - -const Form = { - mixins: [BaseMixin], - props: { - form: Object, - }, - - data() { - return { visible: false }; - }, - methods: { - onSubmit(e) { - e.preventDefault(); - this.form.validateFieldsAndScroll((error, values) => { - if (!error) { - console.log('ok', values); - } else { - console.log('error', error, values); - } - }); - }, - - onCancel() { - this.setState({ visible: false }); - }, - - open() { - this.setState({ visible: true }); - }, - }, - - render() { - const { getFieldProps, getFieldError } = this.form; - return ( -
                -

                modal

                - -
                -
                - -
                - {getFieldError('required') ? ( - getFieldError('required').join(',') - ) : ( - - 1 - - )} -
                -
                - -
                -
                -
                -
                -
                - -
                -
                - ); - }, -}; -export default createDOMForm()(Form); diff --git a/components/vc-form/demo/nested-field.js b/components/vc-form/demo/nested-field.js deleted file mode 100644 index 82752726f..000000000 --- a/components/vc-form/demo/nested-field.js +++ /dev/null @@ -1,183 +0,0 @@ -/* eslint no-console:0 */ - -import createForm from '../src/createDOMForm'; - -const Form = { - props: { - form: Object, - }, - methods: { - onSubmit(e) { - e.preventDefault(); - console.log('Values of member[0].name.firstname and a[0][1].b.c[0]'); - console.log(this.form.getFieldsValue(['member[0].name.firstname', 'a[0][1].b.c[0]'])); - console.log('Values of all fields'); - console.log(this.form.getFieldsValue()); - - this.form.validateFieldsAndScroll((error, values) => { - if (!error) { - console.log('ok', values); - } else { - console.log('error', error, values); - } - }); - }, - - onChange(e) { - console.log(e.target.value); - }, - - setField() { - this.form.setFieldsValue({ - member: [ - { - name: { - firstname: 'm1 first', - lastname: 'm1 last', - }, - }, - { - name: { - firstname: 'm2 first', - lastname: 'm2 last', - }, - }, - ], - a: [ - [ - undefined, - { - b: { - c: ['Value of a[0][1].b.c[0]'], - }, - }, - ], - ], - w: { - x: { - y: { - z: ['Value of w.x.y.z[0]'], - }, - }, - }, - }); - }, - - resetFields() { - console.log('reset'); - this.form.resetFields(); - }, - }, - - render() { - const { getFieldDecorator, getFieldError } = this.form; - - return ( -
                -
                Member 0 firstname
                - {getFieldDecorator('member[0].name.firstname', { - initialValue: '', - rules: [ - { - required: true, - message: "What's the member_0 firstname?", - }, - ], - })()} -
                - {(getFieldError('member[0].name.firstname') || []).join(', ')} -
                - -
                Member 0 lastname
                - {getFieldDecorator('member[0].name.lastname', { - initialValue: '', - rules: [ - { - required: true, - message: "What's the member_0 lastname?", - }, - ], - })()} -
                - {(getFieldError('member[0].name.firstname') || []).join(', ')} -
                - -
                Member 1 firstname
                - {getFieldDecorator('member[1].name.firstname', { - initialValue: '', - rules: [ - { - required: true, - message: "What's the member_1 fistname?", - }, - ], - })()} -
                - {(getFieldError('member[1].name.firstname') || []).join(', ')} -
                - -
                Member 1 lastname
                - {getFieldDecorator('member[1].name.lastname', { - initialValue: '', - rules: [ - { - required: true, - message: "What's the member_1 lastname?", - }, - ], - })()} -
                - {(getFieldError('member[1].name.firstname') || []).join(', ')} -
                - -
                a[0][1].b.c[0]
                - {getFieldDecorator('a[0][1].b.c[0]', { - initialValue: '', - rules: [ - { - required: true, - message: "What's a[0][1].b.c[0]?", - }, - ], - })()} -
                {(getFieldError('a[0][1].b.c[0]') || []).join(', ')}
                - -
                w.x.y.z[0]
                - {getFieldDecorator('w.x.y.z[0]', { - initialValue: '', - rules: [ - { - required: true, - message: "What's w.x.y.z[0]?", - }, - ], - })()} -
                {(getFieldError('w.x.y.z[0]') || []).join(', ')}
                - - - - -
                - ); - }, -}; - -const NewForm = createForm({ - onFieldsChange(_, changedFields, allFields) { - console.log('onFieldsChange: ', changedFields, allFields); - }, - onValuesChange(_, changedValues, allValues) { - console.log('onValuesChange: ', changedValues, allValues); - }, -})(Form); - -export default { - render() { - return ( -
                -

                setFieldsValue

                - -
                - ); - }, -}; diff --git a/components/vc-form/demo/normalize.js b/components/vc-form/demo/normalize.js deleted file mode 100644 index bd2e26849..000000000 --- a/components/vc-form/demo/normalize.js +++ /dev/null @@ -1,161 +0,0 @@ -/* eslint no-console:0 */ - -import { createForm } from '../index'; -import { regionStyle, errorStyle } from './styles'; - -const CustomInput = { - props: { - form: Object, - }, - data() { - return { - data: [], - }; - }, - methods: { - checkUpper(rule, value = '', callback) { - if (value !== value.toUpperCase()) { - callback(new Error('need to be upper!')); - } else { - callback(); - } - }, - toUpper(v, prev) { - if (v === prev) { - return v; - } - return v.toUpperCase(); - }, - }, - - render() { - const { getFieldProps, getFieldError } = this.form; - const errors = getFieldError('upper'); - return ( -
                -
                upper normalize
                -
                - -
                -
                {errors ? errors.join(',') : null}
                -
                - ); - }, -}; - -const MaxMin = { - props: { - form: Object, - }, - methods: { - normalizeMin(value, prevValue, allValues) { - console.log('normalizeMin', allValues.min, allValues.max); - const previousAllValues = this.form.getFieldsValue(); - if (allValues.max !== previousAllValues.max) { - // max changed - if (value === '' || Number(allValues.max) < Number(value)) { - return allValues.max; - } - } - return value; - }, - normalizeMax(value, prevValue, allValues) { - console.log('normalizeMax', allValues.min, allValues.max); - const previousAllValues = this.form.getFieldsValue(); - if (allValues.min !== previousAllValues.min) { - // min changed - if (value === '' || Number(allValues.min) > Number(value)) { - return allValues.min; - } - } - return value; - }, - }, - - render() { - const { getFieldProps } = this.form; - return ( -
                -
                - min:{' '} - -
                -
                - max:{' '} - -
                -
                - ); - }, -}; - -const Form = { - // props: { - // form: Object, - // }, - methods: { - onSubmit(e) { - e.preventDefault(); - this.form.validateFields((error, values) => { - if (!error) { - console.log('ok', values); - } else { - console.log('error', error, values); - } - }); - }, - }, - - render() { - const { form } = this; - return ( -
                -

                normalize

                -
                - - - - -
                - -
                - -
                - ); - }, -}; - -export default createForm()(Form); diff --git a/components/vc-form/demo/overview.js b/components/vc-form/demo/overview.js deleted file mode 100644 index cbe1b8cad..000000000 --- a/components/vc-form/demo/overview.js +++ /dev/null @@ -1,269 +0,0 @@ -/* eslint no-console:0 */ - -import createDOMForm from '../src/createDOMForm'; -import { DatePicker, Select } from 'ant-design-vue'; -import { regionStyle, errorStyle } from './styles'; -const { Option } = Select; - -const Email = { - props: { - form: Object, - }, - render() { - const { getFieldProps, getFieldError, isFieldValidating } = this.form; - const errors = getFieldError('email'); - return ( -
                -
                email sync validate
                -
                - 错误的 email 格式 }], - })} - /> -
                -
                {errors}
                -
                {isFieldValidating('email') ? 'validating' : null}
                -
                - ); - }, -}; - -const User = { - props: { - form: Object, - }, - methods: { - userExists(rule, value, callback) { - setTimeout(() => { - if (value === '1') { - callback([new Error('are you kidding?')]); - } else if (value === 'yiminghe') { - callback([new Error('forbid yiminghe')]); - } else { - callback(); - } - }, 300); - }, - }, - - render() { - const { getFieldProps, getFieldError, isFieldValidating } = this.form; - const errors = getFieldError('user'); - return ( -
                -
                - - * - - user async validate -
                -
                - -
                -
                {errors ? errors.join(',') : null}
                -
                {isFieldValidating('user') ? 'validating' : null}
                -
                - ); - }, -}; - -const CustomInput = { - props: { - form: Object, - }, - render() { - const { getFieldProps, getFieldError, isFieldValidating } = this.form; - const errors = getFieldError('select'); - return ( -
                -
                - - * - - custom select sync validate -
                -
                - -
                -
                {errors ? errors.join(',') : null}
                -
                {isFieldValidating('select') ? 'validating' : null}
                -
                - ); - }, -}; - -const DateInput = { - props: { - form: Object, - }, - render() { - const { getFieldProps, getFieldError } = this.form; - const errors = getFieldError('date'); - return ( -
                -
                - - * - - DateInput sync validate -
                -
                - -
                -
                {errors ? errors.join(',') : null}
                -
                - ); - }, -}; - -function toNumber(v) { - if (v === undefined) { - return v; - } - if (v === '') { - return undefined; - } - if (v && v.trim() === '') { - return NaN; - } - return Number(v); -} - -const NumberInput = { - props: { - form: Object, - }, - render() { - const { getFieldProps, getFieldError } = this.form; - const errors = getFieldError('number'); - return ( -
                -
                number input
                -
                - -
                -
                {errors ? errors.join(',') : null}
                -
                - ); - }, -}; - -const Form = { - methods: { - onSubmit(e) { - console.log('submit'); - e.preventDefault(); - this.form.validateFieldsAndScroll( - { - scroll: { - offsetTop: 20, - }, - }, - (error, values) => { - if (!error) { - console.log('ok', values); - } else { - console.log('error', error, values); - } - }, - ); - }, - - reset(e) { - e.preventDefault(); - this.form.resetFields(); - }, - }, - - render() { - const { form } = this; - const { getFieldProps, getFieldError } = form; - return ( -
                -

                overview

                -
                - - - - - - - - - - -
                -
                normal required input
                -
                - -
                -
                - {getFieldError('normal') ? getFieldError('normal').join(',') : null} -
                -
                - -
                - -   - -
                - -
                - ); - }, -}; - -export default createDOMForm({ - validateMessages: { - required(field) { - return `${field} 必填`; - }, - }, -})(Form); diff --git a/components/vc-form/demo/parallel-form.js b/components/vc-form/demo/parallel-form.js deleted file mode 100644 index 5935ed742..000000000 --- a/components/vc-form/demo/parallel-form.js +++ /dev/null @@ -1,83 +0,0 @@ -/* eslint no-console:0 */ - -import { createForm } from '../index'; -import { regionStyle } from './styles'; -import { Switch } from 'ant-design-vue'; - -const TopForm = { - props: { - form: Object, - }, - render() { - const { getFieldProps } = this.form; - return ( -
                -
                has email?
                -
                - -
                -
                - ); - }, -}; - -const BottomForm = { - props: { - form: Object, - on: Boolean, - }, - render() { - const { form } = this; - const on = form.getFieldValue('on'); - const style = { - ...regionStyle, - display: on ? 'block' : 'none', - }; - return ( -
                -
                email:
                -
                - -
                -
                - ); - }, -}; - -const Form = { - props: { - form: Object, - }, - methods: { - onSubmit(e) { - e.preventDefault(); - console.log(this.form.getFieldsValue()); - }, - }, - - render() { - const { form } = this; - return ( -
                - - -
                - -
                -
                - ); - }, -}; - -const NewForm = createForm()(Form); - -export default { - render() { - return ( -
                -

                parallel form

                - -
                - ); - }, -}; diff --git a/components/vc-form/demo/promise-validate.js b/components/vc-form/demo/promise-validate.js deleted file mode 100644 index b2d5092d4..000000000 --- a/components/vc-form/demo/promise-validate.js +++ /dev/null @@ -1,30 +0,0 @@ -import { createForm } from '../index'; -const Form = { - methods: { - handleSubmit(e) { - e.preventDefault(); - const { validateFields } = this.form; - validateFields() - .then(console.log) - .catch(console.error); - }, - }, - - render() { - const { getFieldDecorator } = this.form; - return ( -
                - {getFieldDecorator('name', { - rules: [ - { - required: true, - }, - ], - })()} - -
                - ); - }, -}; - -export default createForm()(Form); diff --git a/components/vc-form/demo/start-end-date.js b/components/vc-form/demo/start-end-date.js deleted file mode 100644 index a6ec0d6b9..000000000 --- a/components/vc-form/demo/start-end-date.js +++ /dev/null @@ -1,87 +0,0 @@ -/* eslint no-console:0 */ - -import { DatePicker } from 'ant-design-vue'; -import createDOMForm from '../src/createDOMForm'; -import { regionStyle, errorStyle } from './styles'; - -const Form = { - props: { - form: Object, - }, - methods: { - onSubmit(e) { - console.log('submit'); - e.preventDefault(); - this.form.validateFieldsAndScroll((error, values) => { - if (!error) { - console.log('ok', values); - } else { - console.log('error', error, values); - } - }); - }, - - reset(e) { - e.preventDefault(); - this.form.resetFields(); - }, - - checkStart(rule, value, callback) { - const { validateFields } = this.form; - validateFields(['end'], { force: true }); - callback(); - }, - - checkEnd(rule, value, callback) { - const end = value; - const { getFieldValue } = this.form; - const start = getFieldValue('start'); - if (!end || !start) { - callback('please select both start and end time'); - } else if (end.valueOf() < start.valueOf()) { - callback('start time should be less than end time'); - } else { - callback(); - } - }, - }, - - render() { - const { form } = this; - const { getFieldProps, getFieldError } = form; - return ( -
                -

                startTime and endTime validation

                -
                -
                -
                start:
                -
                - -
                -
                - -
                -
                end:
                -
                - -
                -
                - -
                {getFieldError('end') ? getFieldError('end').join(',') : ''}
                - -
                - -   - -
                -
                -
                - ); - }, -}; - -export default createDOMForm()(Form); diff --git a/components/vc-form/demo/styles.js b/components/vc-form/demo/styles.js deleted file mode 100644 index 6599f8f75..000000000 --- a/components/vc-form/demo/styles.js +++ /dev/null @@ -1,11 +0,0 @@ -export const regionStyle = { - border: '1px solid red', - marginTop: '10px', - padding: '10px', -}; - -export const errorStyle = { - color: 'red', - marginTop: '10px', - padding: '10px', -}; diff --git a/components/vc-form/demo/suggest.js b/components/vc-form/demo/suggest.js deleted file mode 100644 index 166cc85eb..000000000 --- a/components/vc-form/demo/suggest.js +++ /dev/null @@ -1,123 +0,0 @@ -/* eslint no-console:0 */ - -import { createForm } from '../index'; -import { Select } from 'ant-design-vue'; -import { regionStyle, errorStyle } from './styles'; -import { mergeProps } from '../../_util/props-util'; -const emailTpl = ['@gmail.com', '@outlook.com', '@qq.com']; -const { Option } = Select; -const CustomInput = { - props: { - form: Object, - }, - data() { - return { data: [] }; - }, - methods: { - onChange(v) { - if (v.indexOf('@') === -1) { - this.data = emailTpl.map(m => v + m); - } else if (this.data.length) { - this.data = []; - } - }, - }, - - render() { - const { getFieldProps, getFieldError, isFieldValidating } = this.form; - const errors = getFieldError('select'); - return ( -
                -
                custom select sync validate
                -
                - -
                -
                - {errors ? ( - errors.join(',') - ) : ( - - 1 - - )} -
                -
                - {isFieldValidating('select') ? ( - 'validating' - ) : ( - - 1 - - )} -
                -
                - ); - }, -}; - -const Form = { - props: { - form: Object, - }, - methods: { - onSubmit(e) { - e.preventDefault(); - this.form.validateFields((error, values) => { - if (!error) { - console.log('ok', values); - } else { - console.log('error', error, values); - } - }); - }, - }, - - render() { - const { form } = this; - return ( -
                -

                suggest

                -
                - - -
                - -
                - -
                - ); - }, -}; - -export default createForm()(Form); diff --git a/components/vc-form/demo/validateFirst.js b/components/vc-form/demo/validateFirst.js deleted file mode 100644 index 1b6c3c6d5..000000000 --- a/components/vc-form/demo/validateFirst.js +++ /dev/null @@ -1,133 +0,0 @@ -/* eslint no-console:0 */ - -import { createForm } from '../index'; -import { regionStyle, errorStyle } from './styles'; - -const Email = { - props: { - form: Object, - }, - render() { - const { getFieldProps, getFieldError, isFieldValidating } = this.form; - const errors = getFieldError('email'); - return ( -
                -
                email sync validate
                -
                - -
                -
                {errors ? errors.join(',') : null}
                -
                {isFieldValidating('email') ? 'validating' : null}
                -
                - ); - }, -}; - -const User = { - props: { - form: Object, - }, - methods: { - userExists(rule, value, callback) { - setTimeout(() => { - if (value === '1') { - callback([new Error('are you kidding?')]); - } else if (value === 'yiminghe') { - callback([new Error('forbid yiminghe')]); - } else { - callback(); - } - }, 300); - }, - }, - - render() { - const { getFieldProps, getFieldError, isFieldValidating } = this.form; - const errors = getFieldError('user'); - return ( -
                -
                user async validate
                -
                - -
                -
                {errors ? errors.join(',') : null}
                -
                {isFieldValidating('user') ? 'validating' : null}
                -
                - ); - }, -}; - -const Form = { - methods: { - onSubmit(e) { - console.log('submit'); - e.preventDefault(); - this.form.validateFields( - { - // firstFields: false, - }, - (error, values) => { - if (!error) { - console.log('ok', values); - } else { - console.log('error', error, values); - } - }, - ); - }, - - reset(e) { - e.preventDefault(); - this.form.resetFields(); - }, - }, - - render() { - const { form } = this; - return ( -
                -

                validateFirst

                -
                - - - - -
                - -   - -
                - -
                - ); - }, -}; - -export default createForm()(Form); diff --git a/components/vc-form/demo/validateTrigger.js b/components/vc-form/demo/validateTrigger.js deleted file mode 100644 index d57de9011..000000000 --- a/components/vc-form/demo/validateTrigger.js +++ /dev/null @@ -1,117 +0,0 @@ -/* eslint no-console:0 */ - -import { createForm } from '../index'; -import { regionStyle, errorStyle } from './styles'; - -const Email = { - props: { - form: Object, - }, - render() { - const { getFieldProps, getFieldError, isFieldValidating } = this.form; - const errors = getFieldError('email'); - return ( -
                -
                email validate onBlur && onChange
                -
                - -
                -
                {errors ? errors.join(',') : null}
                -
                {isFieldValidating('email') ? 'validating' : null}
                -
                - ); - }, -}; - -const User = { - props: { - form: Object, - }, - render() { - const { getFieldProps, getFieldError, isFieldValidating } = this.form; - const errors = getFieldError('user'); - return ( -
                -
                user validate on submit
                -
                - -
                -
                {errors ? errors.join(',') : null}
                -
                {isFieldValidating('user') ? 'validating' : null}
                -
                - ); - }, -}; - -const Form = { - props: { - form: Object, - }, - methods: { - onSubmit(e) { - e.preventDefault(); - this.form.validateFields((error, values) => { - if (!error) { - console.log('ok', values); - } else { - console.log('error', error, values); - } - }); - }, - }, - - render() { - const { form } = this; - return ( -
                -

                use validateTrigger config

                -
                - - - - -
                - -
                - -
                - ); - }, -}; - -export default createForm()(Form); diff --git a/components/vc-input-number/demo/combination-key-format.jsx b/components/vc-input-number/demo/combination-key-format.jsx deleted file mode 100644 index 958c0e266..000000000 --- a/components/vc-input-number/demo/combination-key-format.jsx +++ /dev/null @@ -1,59 +0,0 @@ -import InputNumber from '../src/index'; -import '../assets/index.less'; - -export default { - data() { - return { - disabled: false, - readOnly: false, - value: 50000, - }; - }, - methods: { - onChange(value) { - console.log('onChange:', value); - this.value = value; - }, - toggleDisabled() { - this.disabled = !this.disabled; - }, - toggleReadOnly() { - this.readOnly = !this.readOnly; - }, - numberWithCommas(x) { - return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); - }, - format(num) { - return `$ ${this.numberWithCommas(num)} boeing737`; - }, - parser(num) { - return num - .toString() - .split(' ')[1] - .replace(/,*/g, ''); - }, - }, - render() { - return ( -
                - -

                - - -

                -
                - ); - }, -}; diff --git a/components/vc-input-number/demo/custom.jsx b/components/vc-input-number/demo/custom.jsx deleted file mode 100644 index 42459a8cf..000000000 --- a/components/vc-input-number/demo/custom.jsx +++ /dev/null @@ -1,43 +0,0 @@ -import InputNumber from '../src/index'; -import '../assets/index.less'; - -export default { - data() { - return { - disabled: false, - readOnly: false, - value: 5, - }; - }, - methods: { - onChange(value) { - console.log('onChange:', value); - this.value = value; - }, - toggleDisabled() { - this.disabled = !this.disabled; - }, - toggleReadOnly() { - this.readOnly = !this.readOnly; - }, - }, - render() { - const upHandler =
                x
                ; - const downHandler =
                V
                ; - return ( -
                - -
                - ); - }, -}; diff --git a/components/vc-input-number/demo/decimal.jsx b/components/vc-input-number/demo/decimal.jsx deleted file mode 100644 index 0ac9f5c8f..000000000 --- a/components/vc-input-number/demo/decimal.jsx +++ /dev/null @@ -1,44 +0,0 @@ -import InputNumber from '../src/index'; -import '../assets/index.less'; - -export default { - data() { - return { - disabled: false, - readOnly: false, - value: 8, - }; - }, - methods: { - onChange(value) { - console.log('onChange:', value); - this.value = value; - }, - toggleDisabled() { - this.disabled = !this.disabled; - }, - toggleReadOnly() { - this.readOnly = !this.readOnly; - }, - }, - render() { - return ( -
                - -

                - - -

                -
                - ); - }, -}; diff --git a/components/vc-input-number/demo/formatter.jsx b/components/vc-input-number/demo/formatter.jsx deleted file mode 100644 index 085d9c91b..000000000 --- a/components/vc-input-number/demo/formatter.jsx +++ /dev/null @@ -1,62 +0,0 @@ -import InputNumber from '../src/index'; -import '../assets/index.less'; - -function getSum(str) { - let total = 0; - str.split('').forEach(c => { - const num = Number(c); - - if (!isNaN(num)) { - total += num; - } - }); - - return total; -} - -export default { - data() { - return { - value: 1000, - }; - }, - render() { - return ( -
                - `$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} - /> - `${value}%`} - parser={value => value.replace('%', '')} - /> - `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} - /> - -
                -

                In Control

                - { - this.value = value; - }} - formatter={value => `$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')} - /> -
                - -
                -

                Strange Format

                - `$ ${value} - ${getSum(value)}`} - parser={value => (value.match(/^\$ ([\d\.]*) .*$/) || [])[1]} - /> -
                -
                - ); - }, -}; diff --git a/components/vc-input-number/demo/index.vue b/components/vc-input-number/demo/index.vue deleted file mode 100644 index ee33d839e..000000000 --- a/components/vc-input-number/demo/index.vue +++ /dev/null @@ -1,25 +0,0 @@ - diff --git a/components/vc-input-number/demo/precision.jsx b/components/vc-input-number/demo/precision.jsx deleted file mode 100644 index 5978f1b85..000000000 --- a/components/vc-input-number/demo/precision.jsx +++ /dev/null @@ -1,30 +0,0 @@ -import InputNumber from '../src/index'; -import '../assets/index.less'; - -export default { - data() { - return { - precision: 2, - }; - }, - methods: { - onChange(value) { - console.log('onChange:', value); - this.value = value; - }, - changeprecision(e) { - this.precision = parseInt(e.target.value, 10); - }, - }, - render() { - return ( -
                - -

                - precision: - -

                -
                - ); - }, -}; diff --git a/components/vc-input-number/demo/simple-use-touch.jsx b/components/vc-input-number/demo/simple-use-touch.jsx deleted file mode 100644 index 670cd28e4..000000000 --- a/components/vc-input-number/demo/simple-use-touch.jsx +++ /dev/null @@ -1,44 +0,0 @@ -import InputNumber from '../src/index'; -import '../assets/index.less'; - -export default { - data() { - return { - disabled: false, - readOnly: false, - value: 5, - }; - }, - methods: { - onChange(value) { - console.log('onChange:', value); - this.value = value; - }, - toggleDisabled() { - this.disabled = !this.disabled; - }, - toggleReadOnly() { - this.readOnly = !this.readOnly; - }, - }, - render() { - return ( -
                - -

                - - -

                -
                - ); - }, -}; diff --git a/components/vc-input-number/demo/simple.jsx b/components/vc-input-number/demo/simple.jsx deleted file mode 100644 index 62caf23fc..000000000 --- a/components/vc-input-number/demo/simple.jsx +++ /dev/null @@ -1,43 +0,0 @@ -import InputNumber from '../src/index'; -import '../assets/index.less'; - -export default { - data() { - return { - disabled: false, - readOnly: false, - value: 5, - }; - }, - methods: { - onChange(value) { - console.log('onChange:', value); - this.value = value; - }, - toggleDisabled() { - this.disabled = !this.disabled; - }, - toggleReadOnly() { - this.readOnly = !this.readOnly; - }, - }, - render() { - return ( -
                - -

                - - -

                -
                - ); - }, -}; diff --git a/components/vc-input-number/demo/small-step.jsx b/components/vc-input-number/demo/small-step.jsx deleted file mode 100644 index ec8d11633..000000000 --- a/components/vc-input-number/demo/small-step.jsx +++ /dev/null @@ -1,36 +0,0 @@ -import InputNumber from '../src/index'; -import '../assets/index.less'; - -export default { - data() { - return { - value: 0.000000001, - }; - }, - methods: { - onChange(value) { - console.log('onChange:', value); - this.value = value; - }, - toggleDisabled() { - this.disabled = !this.disabled; - }, - toggleReadOnly() { - this.readOnly = !this.readOnly; - }, - }, - render() { - return ( -
                - -
                - ); - }, -}; diff --git a/components/vc-input-number/src/InputHandler.js b/components/vc-input-number/src/InputHandler.js index ba9b64994..75c866752 100755 --- a/components/vc-input-number/src/InputHandler.js +++ b/components/vc-input-number/src/InputHandler.js @@ -3,6 +3,7 @@ import Touchable from '../../vc-m-feedback'; import { getListeners } from '../../_util/props-util'; const InputHandler = { + name: 'InputHandler', props: { prefixCls: PropTypes.string, disabled: PropTypes.bool, diff --git a/components/vc-input-number/src/index.js b/components/vc-input-number/src/index.js index 7c4dc16cb..e0f2c5cd0 100755 --- a/components/vc-input-number/src/index.js +++ b/components/vc-input-number/src/index.js @@ -1,4 +1,4 @@ -// based on rc-input-number 4.4.0 +// based on rc-input-number 4.5.5 import PropTypes from '../../_util/vue-types'; import BaseMixin from '../../_util/BaseMixin'; import { initDefaultProps, hasProp, getOptionProps, getListeners } from '../../_util/props-util'; @@ -35,6 +35,13 @@ const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || Math.pow(2, 53) - 1; const isValidProps = value => value !== undefined && value !== null; +const isEqual = (oldValue, newValue) => + newValue === oldValue || + (typeof newValue === 'number' && + typeof oldValue === 'number' && + isNaN(newValue) && + isNaN(oldValue)); + const inputNumberProps = { value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), defaultValue: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), @@ -73,7 +80,7 @@ const inputNumberProps = { }; export default { - name: 'InputNumber', + name: 'VCInputNumber', mixins: [BaseMixin], model: { prop: 'value', @@ -90,17 +97,18 @@ export default { autoComplete: 'off', }), data() { + const props = getOptionProps(this); + this.prevProps = { ...props }; let value; - if (hasProp(this, 'value')) { + if ('value' in props) { value = this.value; } else { value = this.defaultValue; } - value = this.toNumber(value); - + const validValue = this.getValidValue(this.toNumber(value)); return { - inputValue: this.toPrecisionAsStep(value), - sValue: value, + inputValue: this.toPrecisionAsStep(validValue), + sValue: validValue, focused: this.autoFocus, }; }, @@ -112,19 +120,57 @@ export default { this.updatedFunc(); }); }, - beforeUpdate() { - this.$nextTick(() => { - try { - this.start = this.$refs.inputRef.selectionStart; - this.end = this.$refs.inputRef.selectionEnd; - } catch (e) { - // Fix error in Chrome: - // Failed to read the 'selectionStart' property from 'HTMLInputElement' - // http://stackoverflow.com/q/21177489/3040605 - } - }); - }, updated() { + const { value, max, min } = this.$props; + const { focused } = this.$data; + const { prevProps } = this; + const props = getOptionProps(this); + // Don't trigger in componentDidMount + if (prevProps) { + if ( + !isEqual(prevProps.value, value) || + !isEqual(prevProps.max, max) || + !isEqual(prevProps.min, min) + ) { + const validValue = focused ? value : this.getValidValue(value); + let nextInputValue; + if (this.pressingUpOrDown) { + nextInputValue = validValue; + } else if (this.inputting) { + nextInputValue = this.rawInput; + } else { + nextInputValue = this.toPrecisionAsStep(validValue); + } + this.setState({ + // eslint-disable-line + sValue: validValue, + inputValue: nextInputValue, + }); + } + + // Trigger onChange when max or min change + // https://github.com/ant-design/ant-design/issues/11574 + const nextValue = 'value' in props ? value : this.sValue; + // ref: null < 20 === true + // https://github.com/ant-design/ant-design/issues/14277 + if ( + 'max' in props && + prevProps.max !== max && + typeof nextValue === 'number' && + nextValue > max + ) { + this.$emit('change', max); + } + if ( + 'min' in props && + prevProps.min !== min && + typeof nextValue === 'number' && + nextValue < min + ) { + this.$emit('change', min); + } + } + this.prevProps = { ...props }; this.$nextTick(() => { this.updatedFunc(); }); @@ -132,33 +178,6 @@ export default { beforeDestroy() { this.stop(); }, - watch: { - value(val) { - const value = this.focused ? val : this.getValidValue(val, this.min, this.max); - this.setState({ - sValue: val, - inputValue: this.inputting ? value : this.toPrecisionAsStep(value), - }); - }, - max(val) { - const props = getOptionProps(this); - // Trigger onChange when max or min change - // https://github.com/ant-design/ant-design/issues/11574 - const nextValue = 'value' in props ? props.value : this.sValue; - // ref: null < 20 === true - // https://github.com/ant-design/ant-design/issues/14277 - if (typeof nextValue === 'number' && nextValue > val) { - this.__emit('change', val); - } - }, - min(val) { - const props = getOptionProps(this); - const nextValue = 'value' in props ? props.value : this.sValue; - if (typeof nextValue === 'number' && nextValue < val) { - this.__emit('change', val); - } - }, - }, methods: { updatedFunc() { const inputElem = this.$refs.inputRef; @@ -231,6 +250,8 @@ export default { const ratio = this.getRatio(e); this.down(e, ratio); this.stop(); + } else if (e.keyCode === KeyCode.ENTER) { + this.$emit('pressEnter', e); } // Trigger user key down this.recordCursorPosition(); @@ -248,9 +269,9 @@ export default { if (this.focused) { this.inputting = true; } - const input = this.parser(this.getValueFromEvent(e)); - this.setState({ inputValue: input }); - this.$emit('change', this.toNumberWhenUserInput(input)); // valid number or invalid string + this.rawInput = this.parser(this.getValueFromEvent(e)); + this.setState({ inputValue: this.rawInput }); + this.$emit('change', this.toNumber(this.rawInput)); // valid number or invalid string }, onFocus(...args) { this.setState({ @@ -258,17 +279,20 @@ export default { }); this.$emit('focus', ...args); }, - onBlur(e, ...args) { + onBlur(...args) { this.inputting = false; this.setState({ focused: false, }); const value = this.getCurrentValidValue(this.inputValue); - // todo - // e.persist() // fix https://github.com/react-component/input-number/issues/51 - this.setValue(value, () => { - this.$emit('blur', e, ...args); - }); + const newValue = this.setValue(value); + if (this.$listeners.blur) { + const originValue = this.$refs.inputRef.value; + const inputValue = this.getInputDisplayValue({ focused: false, sValue: newValue }); + this.$refs.inputRef.value = inputValue; + this.$emit('blur', ...args); + this.$refs.inputRef.value = originValue; + } }, getCurrentValidValue(value) { let val = value; @@ -317,8 +341,14 @@ export default { }, setValue(v, callback) { // trigger onChange + const { precision } = this.$props; const newValue = this.isNotCompleteNumber(parseFloat(v, 10)) ? null : parseFloat(v, 10); - const changed = newValue !== this.sValue || `${newValue}` !== `${this.inputValue}`; // https://github.com/ant-design/ant-design/issues/7363 + const { sValue: value = null, inputValue = null } = this.$data; + // https://github.com/ant-design/ant-design/issues/7363 + // https://github.com/ant-design/ant-design/issues/16622 + const newValueInString = + typeof newValue === 'number' ? newValue.toFixed(precision) : `${newValue}`; + const changed = newValue !== value || newValueInString !== `${inputValue}`; if (!hasProp(this, 'value')) { this.setState( { @@ -339,6 +369,7 @@ export default { if (changed) { this.$emit('change', newValue); } + return newValue; }, getPrecision(value) { if (isValidProps(this.precision)) { @@ -357,7 +388,7 @@ export default { // step={1.0} value={1.51} // press + // then value should be 2.51, rather than 2.5 - // if this.props.precision is undefined + // if this.$props.precision is undefined // https://github.com/react-component/input-number/issues/39 getMaxPrecision(currentValue, ratio = 1) { if (isValidProps(this.precision)) { @@ -376,8 +407,8 @@ export default { const precision = this.getMaxPrecision(currentValue, ratio); return Math.pow(10, precision); }, - getInputDisplayValue() { - const { focused, inputValue, sValue } = this; + getInputDisplayValue(state) { + const { focused, inputValue, sValue } = state || this.$data; let inputDisplayValue; if (focused) { inputDisplayValue = inputValue; @@ -389,7 +420,14 @@ export default { inputDisplayValue = ''; } - return inputDisplayValue; + let inputDisplayValueFormat = this.formatWrapper(inputDisplayValue); + if (isValidProps(this.$props.decimalSeparator)) { + inputDisplayValueFormat = inputDisplayValueFormat + .toString() + .replace('.', this.$props.decimalSeparator); + } + + return inputDisplayValueFormat; }, recordCursorPosition() { // Record position @@ -407,7 +445,12 @@ export default { } }, fixCaret(start, end) { - if (start === undefined || end === undefined || !this.input || !this.input.value) { + if ( + start === undefined || + end === undefined || + !this.$refs.inputRef || + !this.$refs.inputRef.value + ) { return; } @@ -433,6 +476,14 @@ export default { if (index === -1) return false; + const prevCursorPos = this.cursorBefore.length; + if ( + this.lastKeyCode === KeyCode.DELETE && + this.cursorBefore.charAt(prevCursorPos - 1) === str[0] + ) { + this.fixCaret(prevCursorPos, prevCursorPos); + return true; + } if (index + str.length === fullStr.length) { this.fixCaret(index, index); @@ -463,9 +514,6 @@ export default { formatWrapper(num) { // http://2ality.com/2012/03/signedzero.html // https://github.com/ant-design/ant-design/issues/9439 - if (isNegativeZero(num)) { - return '-0'; - } if (this.formatter) { return this.formatter(num); } @@ -476,9 +524,6 @@ export default { return num; } const precision = Math.abs(this.getMaxPrecision(num)); - if (precision === 0) { - return num.toString(); - } if (!isNaN(precision)) { return Number(num).toFixed(precision); } @@ -494,48 +539,36 @@ export default { ); }, toNumber(num) { - if (this.isNotCompleteNumber(num)) { + const { precision, autoFocus } = this.$props; + const { focused = autoFocus } = this; + // num.length > 16 => This is to prevent input of large numbers + const numberIsTooLarge = num && num.length > 16 && focused; + if (this.isNotCompleteNumber(num) || numberIsTooLarge) { return num; } - if (isValidProps(this.precision)) { - return Number(Number(num).toFixed(this.precision)); + if (isValidProps(precision)) { + return Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision); } return Number(num); }, - // '1.0' '1.00' => may be a inputing number - toNumberWhenUserInput(num) { - // num.length > 16 => prevent input large number will became Infinity - if ((/\.\d*0$/.test(num) || num.length > 16) && this.focused) { - return num; - } - return this.toNumber(num); - }, upStep(val, rat) { - const { step, min } = this; + const { step } = this; const precisionFactor = this.getPrecisionFactor(val, rat); const precision = Math.abs(this.getMaxPrecision(val, rat)); - let result; - if (typeof val === 'number') { - result = ((precisionFactor * val + precisionFactor * step * rat) / precisionFactor).toFixed( - precision, - ); - } else { - result = min === -Infinity ? step : min; - } + const result = ( + (precisionFactor * val + precisionFactor * step * rat) / + precisionFactor + ).toFixed(precision); return this.toNumber(result); }, downStep(val, rat) { - const { step, min } = this; + const { step } = this; const precisionFactor = this.getPrecisionFactor(val, rat); const precision = Math.abs(this.getMaxPrecision(val, rat)); - let result; - if (typeof val === 'number') { - result = ((precisionFactor * val - precisionFactor * step * rat) / precisionFactor).toFixed( - precision, - ); - } else { - result = min === -Infinity ? -step : min; - } + const result = ( + (precisionFactor * val - precisionFactor * step * rat) / + precisionFactor + ).toFixed(precision); return this.toNumber(result); }, stepFn(type, e, ratio = 1, recursive) { @@ -627,16 +660,7 @@ export default { // focus state, show input value // unfocus state, show valid value - let inputDisplayValue; - if (this.focused) { - inputDisplayValue = this.inputValue; - } else { - inputDisplayValue = this.toPrecisionAsStep(this.sValue); - } - - if (inputDisplayValue === undefined || inputDisplayValue === null) { - inputDisplayValue = ''; - } + const inputDisplayValue = this.getInputDisplayValue(); let upEvents; let downEvents; @@ -661,12 +685,6 @@ export default { mouseleave: this.stop, }; } - let inputDisplayValueFormat = this.formatWrapper(inputDisplayValue); - if (isValidProps(this.decimalSeparator)) { - inputDisplayValueFormat = inputDisplayValueFormat - .toString() - .replace('.', this.decimalSeparator); - } const isUpDisabled = !!upDisabledClass || disabled || readOnly; const isDownDisabled = !!downDisabledClass || disabled || readOnly; const { @@ -733,14 +751,12 @@ export default { )}
                -
                +
                diff --git a/components/vc-lazy-load/demo/index.jsx b/components/vc-lazy-load/demo/index.jsx deleted file mode 100644 index d7673192c..000000000 --- a/components/vc-lazy-load/demo/index.jsx +++ /dev/null @@ -1,38 +0,0 @@ -import LazyLoad from '../src/LazyLoad'; - -import './style.less'; - -const Application = { - render() { - return ( -
                - Scroll to load images. -
                - - - -
                - - - - -
                -
                -
                -
                -
                - - - -
                -
                - - - -
                -
                - ); - }, -}; - -export default Application; diff --git a/components/vc-lazy-load/demo/style.less b/components/vc-lazy-load/demo/style.less deleted file mode 100644 index 85673b660..000000000 --- a/components/vc-lazy-load/demo/style.less +++ /dev/null @@ -1,18 +0,0 @@ -.LazyLoad { - opacity: 0; - transition: all 2s ease-in-out; - - &.is-visible { - opacity: 1; - } -} - -.filler { - height: 150px; -} - -.ScrollableContainer { - height: 200px; - overflow: scroll; - background-color: grey; -} diff --git a/components/vc-lazy-load/src/LazyLoad.jsx b/components/vc-lazy-load/src/LazyLoad.jsx index 64bd84f69..fa8f90204 100644 --- a/components/vc-lazy-load/src/LazyLoad.jsx +++ b/components/vc-lazy-load/src/LazyLoad.jsx @@ -1,6 +1,6 @@ import PropTypes from '../../_util/vue-types'; import BaseMixin from '../../_util/BaseMixin'; -import addEventListener from '../../_util/Dom/addEventListener'; +import addEventListener from '../../vc-util/Dom/addEventListener'; import { initDefaultProps } from '../../_util/props-util'; import warning from '../../_util/warning'; import debounce from 'lodash/debounce'; diff --git a/components/vc-m-feedback/demo/simple.jsx b/components/vc-m-feedback/demo/simple.jsx deleted file mode 100644 index 243381073..000000000 --- a/components/vc-m-feedback/demo/simple.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import TouchFeedback from '../index'; -import './simple.less'; - -export default { - render() { - return ( -
                - -
                console.log('click div')} - > - click to active -
                -
                -
                - ); - }, -}; diff --git a/components/vc-m-feedback/demo/simple.less b/components/vc-m-feedback/demo/simple.less deleted file mode 100644 index 91f3a933b..000000000 --- a/components/vc-m-feedback/demo/simple.less +++ /dev/null @@ -1,7 +0,0 @@ -.normal { - color: '#000'; -} - -.active { - font-size: 40px; -} diff --git a/components/vc-mentions/index.js b/components/vc-mentions/index.js new file mode 100644 index 000000000..14b917af8 --- /dev/null +++ b/components/vc-mentions/index.js @@ -0,0 +1,6 @@ +import Mentions from './src/Mentions'; +import Option from './src/Option'; + +Mentions.Option = Option; + +export default Mentions; diff --git a/components/vc-mentions/src/DropdownMenu.jsx b/components/vc-mentions/src/DropdownMenu.jsx new file mode 100644 index 000000000..3b0eaac7c --- /dev/null +++ b/components/vc-mentions/src/DropdownMenu.jsx @@ -0,0 +1,63 @@ +import Menu, { MenuItem } from '../../vc-menu'; +import PropTypes from '../../_util/vue-types'; +import { OptionProps } from './Option'; + +function noop() {} +export default { + name: 'DropdownMenu', + props: { + prefixCls: PropTypes.string, + options: PropTypes.arrayOf(OptionProps), + }, + inject: { + mentionsContext: { default: {} }, + }, + + render() { + const { + notFoundContent, + activeIndex, + setActiveIndex, + selectOption, + onFocus = noop, + onBlur = noop, + } = this.mentionsContext; + const { prefixCls, options } = this.$props; + const activeOption = options[activeIndex] || {}; + + return ( + { + const option = options.find(({ value }) => value === key); + selectOption(option); + }, + focus: onFocus, + blur: onBlur, + }, + }} + > + {options.map((option, index) => { + const { value, disabled, children } = option; + return ( + { + setActiveIndex(index); + }} + > + {children} + + ); + })} + {!options.length && {notFoundContent}} + + ); + }, +}; diff --git a/components/vc-mentions/src/KeywordTrigger.jsx b/components/vc-mentions/src/KeywordTrigger.jsx new file mode 100644 index 000000000..09d0dbcad --- /dev/null +++ b/components/vc-mentions/src/KeywordTrigger.jsx @@ -0,0 +1,70 @@ +import PropTypes from '../../_util/vue-types'; +import Trigger from '../../vc-trigger'; +import DropdownMenu from './DropdownMenu'; +import { OptionProps } from './Option'; +import { PlaceMent } from './placement'; + +const BUILT_IN_PLACEMENTS = { + bottomRight: { + points: ['tl', 'br'], + offset: [0, 4], + overflow: { + adjustX: 0, + adjustY: 1, + }, + }, + topRight: { + points: ['bl', 'tr'], + offset: [0, -4], + overflow: { + adjustX: 0, + adjustY: 1, + }, + }, +}; + +export default { + name: 'KeywordTrigger', + props: { + loading: PropTypes.bool, + options: PropTypes.arrayOf(OptionProps), + prefixCls: PropTypes.string, + placement: PropTypes.oneOf(PlaceMent), + visible: PropTypes.bool, + transitionName: PropTypes.string, + getPopupContainer: PropTypes.func, + }, + methods: { + getDropdownPrefix() { + return `${this.$props.prefixCls}-dropdown`; + }, + getDropdownElement() { + const { options } = this.$props; + return ; + }, + }, + + render() { + const { visible, placement, transitionName, getPopupContainer } = this.$props; + + const { $slots } = this; + + const children = $slots.default; + + const popupElement = this.getDropdownElement(); + + return ( + + {children} + + ); + }, +}; diff --git a/components/vc-mentions/src/Mentions.jsx b/components/vc-mentions/src/Mentions.jsx new file mode 100644 index 000000000..77ceab856 --- /dev/null +++ b/components/vc-mentions/src/Mentions.jsx @@ -0,0 +1,323 @@ +import omit from 'omit.js'; +import KeyCode from '../../_util/KeyCode'; +import BaseMixin from '../../_util/BaseMixin'; +import { + getSlots, + hasProp, + getOptionProps, + getListeners, + initDefaultProps, +} from '../../_util/props-util'; +import warning from 'warning'; +import { + getBeforeSelectionText, + getLastMeasureIndex, + replaceWithMeasure, + setInputSelection, +} from './util'; +import KeywordTrigger from './KeywordTrigger'; +import { vcMentionsProps, defaultProps } from './mentionsProps'; + +function noop() {} + +const Mentions = { + name: 'Mentions', + mixins: [BaseMixin], + inheritAttrs: false, + model: { + prop: 'value', + event: 'change', + }, + props: initDefaultProps(vcMentionsProps, defaultProps), + provide() { + return { + mentionsContext: this, + }; + }, + data() { + const { value = '', defaultValue = '' } = this.$props; + warning(this.$props.children, 'please children prop replace slots.default'); + return { + _value: !hasProp(this, 'value') ? defaultValue : value, + measuring: false, + measureLocation: 0, + measureText: null, + measurePrefix: '', + activeIndex: 0, + isFocus: false, + }; + }, + watch: { + value(val) { + this.$data._value = val; + }, + }, + updated() { + this.$nextTick(() => { + const { measuring } = this.$data; + + // Sync measure div top with textarea for rc-trigger usage + if (measuring) { + this.$refs.measure.scrollTop = this.$refs.textarea.scrollTop; + } + }); + }, + methods: { + triggerChange(value) { + const props = getOptionProps(this); + if (!('value' in props)) { + this.setState({ _value: value }); + } else { + this.$forceUpdate(); + } + this.$emit('change', value); + }, + onChange({ target: { value, composing } }) { + if (composing) return; + this.triggerChange(value); + }, + onKeyDown(event) { + const { which } = event; + const { activeIndex, measuring } = this.$data; + // Skip if not measuring + if (!measuring) { + return; + } + + if (which === KeyCode.UP || which === KeyCode.DOWN) { + // Control arrow function + const optionLen = this.getOptions().length; + const offset = which === KeyCode.UP ? -1 : 1; + const newActiveIndex = (activeIndex + offset + optionLen) % optionLen; + this.setState({ + activeIndex: newActiveIndex, + }); + event.preventDefault(); + } else if (which === KeyCode.ESC) { + this.stopMeasure(); + } else if (which === KeyCode.ENTER) { + // Measure hit + const option = this.getOptions()[activeIndex]; + this.selectOption(option); + event.preventDefault(); + } + }, + /** + * When to start measure: + * 1. When user press `prefix` + * 2. When measureText !== prevMeasureText + * - If measure hit + * - If measuring + * + * When to stop measure: + * 1. Selection is out of range + * 2. Contains `space` + * 3. ESC or select one + */ + onKeyUp(event) { + const { key, which } = event; + const { measureText: prevMeasureText, measuring } = this.$data; + const { prefix = '', validateSearch } = this.$props; + const target = event.target; + const selectionStartText = getBeforeSelectionText(target); + const { location: measureIndex, prefix: measurePrefix } = getLastMeasureIndex( + selectionStartText, + prefix, + ); + + // Skip if match the white key list + if ([KeyCode.ESC, KeyCode.UP, KeyCode.DOWN, KeyCode.ENTER].indexOf(which) !== -1) { + return; + } + + if (measureIndex !== -1) { + const measureText = selectionStartText.slice(measureIndex + measurePrefix.length); + const validateMeasure = validateSearch(measureText, this.$props); + const matchOption = !!this.getOptions(measureText).length; + + if (validateMeasure) { + if ( + key === measurePrefix || + measuring || + (measureText !== prevMeasureText && matchOption) + ) { + this.startMeasure(measureText, measurePrefix, measureIndex); + } + } else if (measuring) { + // Stop if measureText is invalidate + this.stopMeasure(); + } + + /** + * We will trigger `onSearch` to developer since they may use for async update. + * If met `space` means user finished searching. + */ + if (validateMeasure) { + this.$emit('search', measureText, measurePrefix); + } + } else if (measuring) { + this.stopMeasure(); + } + }, + onInputFocus(event) { + this.onFocus(event); + }, + onInputBlur(event) { + this.onBlur(event); + }, + onDropdownFocus() { + this.onFocus(); + }, + onDropdownBlur() { + this.onBlur(); + }, + onFocus(event) { + window.clearTimeout(this.focusId); + const { isFocus } = this.$data; + if (!isFocus && event) { + this.$emit('focus', event); + } + this.setState({ isFocus: true }); + }, + onBlur(event) { + this.focusId = window.setTimeout(() => { + this.setState({ isFocus: false }); + this.stopMeasure(); + this.$emit('blur', event); + }, 0); + }, + selectOption(option) { + const { _value: value, measureLocation, measurePrefix } = this.$data; + const { split } = this.$props; + const { value: mentionValue = '' } = option; + const { text, selectionLocation } = replaceWithMeasure(value, { + measureLocation, + targetText: mentionValue, + prefix: measurePrefix, + selectionStart: this.$refs.textarea.selectionStart, + split, + }); + this.triggerChange(text); + this.stopMeasure(() => { + // We need restore the selection position + setInputSelection(this.$refs.textarea, selectionLocation); + }); + + this.$emit('select', option, measurePrefix); + }, + setActiveIndex(activeIndex) { + this.setState({ + activeIndex, + }); + }, + getOptions(measureText) { + const targetMeasureText = measureText || this.$data.measureText || ''; + const { filterOption, children = [] } = this.$props; + const list = (Array.isArray(children) ? children : [children]) + .map(item => { + const children = getSlots(item).default; + return { ...getOptionProps(item), children }; + }) + .filter(option => { + /** Return all result if `filterOption` is false. */ + if (filterOption === false) { + return true; + } + return filterOption(targetMeasureText, option); + }); + return list; + }, + startMeasure(measureText, measurePrefix, measureLocation) { + this.setState({ + measuring: true, + measureText, + measurePrefix, + measureLocation, + activeIndex: 0, + }); + }, + stopMeasure(callback) { + this.setState( + { + measuring: false, + measureLocation: 0, + measureText: null, + }, + callback, + ); + }, + focus() { + this.$refs.textarea.focus(); + }, + blur() { + this.$refs.textarea.blur(); + }, + }, + + render() { + const { _value: value, measureLocation, measurePrefix, measuring } = this.$data; + const { + prefixCls, + placement, + transitionName, + autoFocus, + notFoundContent, + getPopupContainer, + ...restProps + } = getOptionProps(this); + + const inputProps = omit(restProps, [ + 'value', + 'defaultValue', + 'prefix', + 'split', + 'children', + 'validateSearch', + 'filterOption', + ]); + + const options = measuring ? this.getOptions() : []; + + return ( +
                +