diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 0000000000..7e2af08796 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,58 @@ +module.exports = { + // ATTENTION!! + // Preset ordering is reversed, so `@babel/typescript` will called first + // Do not put `@babel/typescript` before `@babel/env`, otherwise will cause a compile error + // See https://github.com/babel/babel/issues/12066 + presets: [ + [ + '@babel/env', + { + loose: true, + modules: false, + }, + ], + '@babel/typescript', + ], + plugins: [ + '@vue/babel-plugin-jsx', + '@babel/proposal-class-properties', + '@babel/transform-runtime', + 'lodash', + ], + overrides: [ + { + test: /\.vue$/, + plugins: [ + '@babel/transform-typescript', + ], + }, + ], + env: { + utils: { + ignore: [ + '**/*.test.ts', + '**/*.spec.ts', + ], + presets: [ + [ + '@babel/env', + { + loose: true, + modules: 'commonjs', + }, + ], + ], + plugins: [ + [ + 'babel-plugin-module-resolver', + { + root: ['element-plus'], + alias: { + '@element-plus': 'element-plus/lib', + }, + }, + ], + ], + }, + }, +} diff --git a/build/build-locale.js b/build/build-locale.js new file mode 100644 index 0000000000..7b0404a332 --- /dev/null +++ b/build/build-locale.js @@ -0,0 +1,39 @@ +/* eslint-disable */ +const fs = require('fs') +const save = require('file-save') +const { resolve, basename } = require('path') +const localePath = resolve(__dirname, '../packages/locale/lang') +const fileList = fs.readdirSync(localePath) + +const transform = function(filename, name, cb) { + require('@babel/core').transformFile(resolve(localePath, filename), { + plugins: [ + '@babel/plugin-transform-modules-umd', + ], + moduleId: name, + }, cb) +} + +fileList + .filter(function(file) { + return /\.ts$/.test(file) + }) + .forEach(function(file) { + const name = basename(file, '.ts') + + transform(file, name, function(err, result) { + if (err) { + console.error(err) + } else { + const code = result.code + const transformedCode = code + .replace('define(\"', 'define(\"element/locale/') + .replace( + /global\.(\S*) = mod.exports/, + 'global.ELEMENT.lang = global.ELEMENT.lang || {};\n global.ELEMENT.lang.$1 = mod.exports.default' + ) + + save(resolve(__dirname, '../lib/umd/locale', `${name}.js`)).write(transformedCode) + } + }) + }) diff --git a/build/webpack.config.js b/build/webpack.config.js index 8b7622c380..de496be2da 100644 --- a/build/webpack.config.js +++ b/build/webpack.config.js @@ -1,13 +1,10 @@ /* eslint-disable @typescript-eslint/no-var-requires */ const path = require('path') const { VueLoaderPlugin } = require('vue-loader') - -const babelOptions = { - plugins: ['@vue/babel-plugin-jsx'], -} +// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin module.exports = { - mode: 'production', + mode: 'development', entry: path.resolve(__dirname, '../packages/element-plus/index.ts'), output: { path: path.resolve(__dirname, '../lib'), @@ -27,40 +24,9 @@ module.exports = { use: 'vue-loader', }, { - test: /\.ts$/, + test: /\.(ts|js)x?$/, exclude: /node_modules/, - loader: 'ts-loader', - options: { - appendTsSuffixTo: [/\.vue$/], - transpileOnly: true, - }, - }, - { - test: /\.tsx$/, - exclude: /node_modules/, - use: [ - { - loader: 'babel-loader', - options: babelOptions, - }, - { - loader: 'ts-loader', - options: { - appendTsxSuffixTo: [/\.vue$/], - transpileOnly: true, - }, - }, - ], - }, - { - test: /\.js(x?)$/, - exclude: /node_modules/, - use: [ - { - loader: 'babel-loader', - options: babelOptions, - }, - ], + loader: 'babel-loader', }, ], }, @@ -77,5 +43,6 @@ module.exports = { }, plugins: [ new VueLoaderPlugin(), + // new BundleAnalyzerPlugin(), ], } diff --git a/package.json b/package.json index aff34cef5e..4235f059b6 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,9 @@ "build:lib": "rimraf lib && webpack --config ./build/webpack.config.js", "build:esm-bundle": "rollup --config ./build/rollup.config.bundle.js", "build:esm": "node ./build/bincomp.js", - "build:utils": "npx tsc -p packages/utils", - "build:locale": "npx tsc -p packages/locale", + "build:utils": "cross-env BABEL_ENV=utils babel packages/utils --extensions .ts --out-dir lib/utils", + "build:locale": "cross-env BABEL_ENV=utils babel packages/locale --extensions .ts --out-dir lib/locale", + "build:locale-umd": "node ./build/build-locale.js", "build:theme": "rimraf packages/theme-chalk/lib && gulp build --gulpfile packages/theme-chalk/gulpfile.js && cp-cli packages/theme-chalk/lib lib/theme-chalk && rimraf packages/theme-chalk/lib", "lint": "eslint ./packages --ext .vue,.js,.ts", "lint-fix": "eslint --fix ./packages --ext .vue,.js,.ts", @@ -24,8 +25,10 @@ "vue": "^3.0.0" }, "devDependencies": { + "@babel/cli": "^7.12.1", "@babel/core": "^7.11.4", "@babel/plugin-proposal-class-properties": "^7.12.1", + "@babel/plugin-transform-runtime": "^7.12.1", "@babel/preset-env": "^7.11.5", "@babel/preset-typescript": "^7.10.4", "@commitlint/cli": "^9.1.2", @@ -43,6 +46,8 @@ "algoliasearch": "^4.4.0", "babel-jest": "^26.3.0", "babel-loader": "^8.1.0", + "babel-plugin-lodash": "^3.3.4", + "babel-plugin-module-resolver": "^4.0.0", "babel-preset-vue": "^2.0.2", "chalk": "^4.1.0", "cp-cli": "^2.0.0", @@ -52,6 +57,7 @@ "eslint": "^7.7.0", "eslint-plugin-vue": "^7.0.0-beta.0", "file-loader": "^6.0.0", + "file-save": "^0.2.0", "highlight.js": "^10.1.2", "html-webpack-plugin": "^4.3.0", "husky": "^4.2.5", @@ -84,6 +90,7 @@ "vue-router": "^4.0.0-beta.4", "vue-template-compiler": "^2.6.12", "webpack": "^4.44.1", + "webpack-bundle-analyzer": "^3.9.0", "webpack-cli": "^3.3.12", "webpack-dev-server": "^3.11.0" }, @@ -130,6 +137,8 @@ "unpkg": "lib/index.js", "style": "lib/theme-chalk/index.css", "browserslist": [ - "last 2 version" + "> 1%", + "last 2 versions", + "not ie <= 8" ] } diff --git a/packages/checkbox/src/useCheckbox.ts b/packages/checkbox/src/useCheckbox.ts index 8a015cb2de..96770f4aff 100644 --- a/packages/checkbox/src/useCheckbox.ts +++ b/packages/checkbox/src/useCheckbox.ts @@ -9,10 +9,10 @@ import { toTypeString } from '@vue/shared' import { UPDATE_MODEL_EVENT } from '@element-plus/utils/constants' import { useGlobalConfig } from '@element-plus/utils/util' import { PartialReturnType } from '@element-plus/utils/types' -import { elFormKey, elFormItemKey } from '@element-plus/form/src/token' +import { elFormKey, elFormItemKey } from '@element-plus/form' import { ICheckboxGroupInstance, ICheckboxProps } from './checkbox' -import type { ElFormContext, ElFormItemContext } from '@element-plus/form/src/token' +import type { ElFormContext, ElFormItemContext } from '@element-plus/form' export const useCheckboxGroup = () => { const ELEMENT = useGlobalConfig() diff --git a/packages/color-picker/src/draggable.ts b/packages/color-picker/src/draggable.ts index 16d3966cac..fed311c9eb 100644 --- a/packages/color-picker/src/draggable.ts +++ b/packages/color-picker/src/draggable.ts @@ -2,17 +2,15 @@ import isServer from '@element-plus/utils/isServer' let isDragging = false export declare interface IOptions { - drag: (event: Event) => void - start: (event: Event) => void - end: (event: Event) => void + drag?: (event: Event) => void + start?: (event: Event) => void + end?: (event: Event) => void } export default function(element: HTMLElement, options: IOptions) { if (isServer) return const moveFn = function(event) { - if (options.drag) { - options.drag(event) - } + options.drag?.(event) } const upFn = function(event) { document.onmousemove = null @@ -22,9 +20,7 @@ export default function(element: HTMLElement, options: IOptions) { isDragging = false - if (options.end) { - options.end(event) - } + options.end?.(event) } element.onmousedown = function(event) { if (isDragging) return @@ -35,8 +31,6 @@ export default function(element: HTMLElement, options: IOptions) { document.onmouseup = upFn isDragging = true - if (options.start) { - options.start(event) - } + options.start?.(event) } } diff --git a/packages/color-picker/src/index.vue b/packages/color-picker/src/index.vue index dd80710ce6..023d409070 100644 --- a/packages/color-picker/src/index.vue +++ b/packages/color-picker/src/index.vue @@ -113,16 +113,6 @@ interface IUseOptions { currentColor: ComputedRef } -interface IProps { - modelValue?: string - showAlpha?: boolean - colorFormat?: string - disabled?: boolean - size?: string - popperClass?: string - predefine?: Array -} - const OPTIONS_KEY = Symbol() export const useOptions = () => { @@ -160,7 +150,7 @@ export default defineComponent( { 'active-change': null, [UPDATE_MODEL_EVENT]: null, }, - setup(props: IProps, { emit }) { + setup(props, { emit }) { const ELEMENT = useGlobalConfig() const elForm = inject(elFormKey, {} as ElFormContext) const elFormItem = inject(elFormItemKey, {} as ElFormItemContext) diff --git a/packages/drawer/__tests__/drawer.spec.ts b/packages/drawer/__tests__/drawer.spec.ts index c69bdfdeec..678f9e35eb 100644 --- a/packages/drawer/__tests__/drawer.spec.ts +++ b/packages/drawer/__tests__/drawer.spec.ts @@ -1,5 +1,5 @@ import { mount } from '@vue/test-utils' -import Drawer from '../src/index' +import Drawer from '../src/index.vue' import Button from '../../button/src/button.vue' import { nextTick } from 'vue' @@ -29,10 +29,13 @@ describe('Drawer', () => { visible: true, }), ) - const vm = wrapper.vm + const wrapperEl = wrapper.find('.el-drawer__wrapper').element as HTMLDivElement + const headerEl = wrapper.find('.el-drawer__header').element + + await nextTick() expect(document.querySelector('.v-modal')).not.toBeNull() - expect(vm.$el.querySelector('.el-drawer__header').textContent).toEqual(title) - expect(vm.$el.style.display).not.toEqual('none') + expect(wrapperEl.style.display).not.toEqual('none') + expect(headerEl.textContent).toEqual(title) }) test('render correct content', async () => { @@ -92,18 +95,12 @@ describe('Drawer', () => { const vm = wrapper.vm as any await nextTick() - const drawer = wrapper.findComponent(Drawer).vm - const drawerEl = drawer.$el + const drawerEl = wrapper.find('.el-drawer__wrapper').element as HTMLDivElement expect(drawerEl.style.display).toEqual('none') vm.visible = true await nextTick() expect(drawerEl.style.display).not.toEqual('none') - - // TODO these will be added back when the @vue/text-utils is updated with transition-stub - // vm.visible = false - // await nextTick() - // expect(drawerEl.style.display).toEqual('none') }) test('should destroy every child after drawer was closed when destroy-on-close flag is true', async () => { @@ -124,7 +121,7 @@ describe('Drawer', () => { expect(wrapper.find('.el-drawer__body span').element.textContent).toEqual(content) vm.$refs.drawer.closeDrawer() await nextTick() - expect(vm.$el.querySelector('.el-drawer__body')).toBeNull() + expect(wrapper.find('.el-drawer__body').exists()).toBe(false) }) test('should close dialog by clicking the close button', async () => { @@ -184,9 +181,8 @@ describe('Drawer', () => { visible: true, }), ) - const vm = wrapper.vm as any - expect(vm.$el.querySelector('.el-drawer__close-btn')).toBeNull() + expect(wrapper.find('.el-drawer__close-btn').exists()).toBe(false) }) test('should have custom classes when custom classes were given', async () => { @@ -202,9 +198,8 @@ describe('Drawer', () => { visible: true, }), ) - const vm = wrapper.vm as any - expect(vm.$el.querySelector(`.${classes}`)).not.toBeNull() + expect(wrapper.find(`.${classes}`).exists()).toBe(true) }) test('should not render header when withHeader attribute is false', async () => { @@ -219,9 +214,8 @@ describe('Drawer', () => { visible: true, }), ) - const vm = wrapper.vm as any - expect(vm.$el.querySelector('.el-drawer__header')).toBeNull() + expect(wrapper.find('.el-drawer__header').exists()).toBe(false) }) describe('directions', () => { @@ -239,19 +233,19 @@ describe('Drawer', () => { ) } test('should render from left to right', async () => { - expect(renderer('ltr').find('.ltr').element).not.toBeUndefined() + expect(renderer('ltr').find('.ltr').exists()).toBe(true) }) test('should render from right to left', async () => { - expect(renderer('rtl').find('.rtl').element).not.toBeUndefined() + expect(renderer('rtl').find('.rtl').exists()).toBe(true) }) test('should render from top to bottom', async () => { - expect(renderer('ttb').find('.ttb').element).not.toBeUndefined() + expect(renderer('ttb').find('.ttb').exists()).toBe(true) }) test('should render from bottom to top', async () => { - expect(renderer('btt').find('.btt').element).not.toBeUndefined() + expect(renderer('btt').find('.btt').exists()).toBe(true) }) }) @@ -287,7 +281,7 @@ describe('Drawer', () => { }, ) const vm = wrapper.vm as any - const drawer = wrapper.findComponent(Drawer).vm + const drawer = wrapper.vm.$refs.drawer as any vm.visible = true await nextTick() @@ -319,17 +313,13 @@ describe('Drawer', () => { ) test('should effect height when drawer is vertical', async () => { - const size = '50%' - const vm = renderer(size, true).vm as any - - expect(vm.$el.querySelector('.el-drawer').style.width).toEqual('50%') + const drawerEl = renderer('50%', true).find('.el-drawer').element as HTMLDivElement + expect(drawerEl.style.width).toEqual('50%') }) test('should effect width when drawer is horizontal', async () => { - const size = '50%' - const vm = renderer(size, false).vm as any - - expect(vm.$el.querySelector('.el-drawer').style.height).toEqual('50%') + const drawerEl = renderer('50%', false).find('.el-drawer').element as HTMLDivElement + expect(drawerEl.style.height).toEqual('50%') }) }) }) diff --git a/packages/drawer/index.ts b/packages/drawer/index.ts index 41c508299b..4af4b27703 100644 --- a/packages/drawer/index.ts +++ b/packages/drawer/index.ts @@ -1,5 +1,5 @@ import { App } from 'vue' -import Drawer from './src/index' +import Drawer from './src/index.vue' export default (app: App): void => { app.component(Drawer.name, Drawer) diff --git a/packages/drawer/src/drawer.d.ts b/packages/drawer/src/drawer.d.ts deleted file mode 100644 index 1b7be2c6f9..0000000000 --- a/packages/drawer/src/drawer.d.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Ref } from 'vue' -export declare type IDrawerDirection = 'ltr' | 'rtl' | 'ttb' | 'btt' - -export declare interface IDrawerProps { - appendToBody: boolean - beforeClose: (any) => void - customClass: string - closeOnPressEscape: boolean - destroyOnClose: boolean - modal: boolean - direction: IDrawerDirection - modalAppendToBody: boolean - showClose: boolean - size: string - title: string - modelValue: boolean - wrapperClosable: boolean - withHeader: boolean - lockScroll: boolean - closeOnClickModal: boolean -} - -// XXX fake a vue component for popup -export declare type IDrawerFakeComponentInst = { - handleClose: () => void - closeOnClickModal: IDrawerProps[ 'closeOnClickModal' ] -} - -export declare type IDrawerPopupOption = { - props: IDrawerWithPopupOption - $el: Ref - vVm: IDrawerFakeComponentInst -} - -// XXX openModal needed, will be replaced? -export declare type IDrawerPopupModalOption = { - zIndex?: number - modalClass?: string - modalFade?: boolean -} - -export declare type IDrawerWithPopupOption = IDrawerProps & IDrawerPopupModalOption diff --git a/packages/drawer/src/index.ts b/packages/drawer/src/index.ts deleted file mode 100644 index 8c3839d422..0000000000 --- a/packages/drawer/src/index.ts +++ /dev/null @@ -1,218 +0,0 @@ -import { defineComponent, PropType, ref, computed, watch, nextTick } from 'vue' -import usePopup from './popup' -import Utils from '@element-plus/utils/aria' -import { IDrawerDirection, IDrawerProps } from './drawer' - -const template = ` - -
-
- -
-
-
` - -export default defineComponent({ - name: 'ElDrawer', - props: { - appendToBody: { - type: Boolean, - default: false, - }, - beforeClose: { - type: Function as PropType<(any) => void>, - default: null, - }, - customClass: { - type: String, - default: '', - }, - closeOnPressEscape: { - type: Boolean, - default: true, - }, - destroyOnClose: { - type: Boolean, - default: false, - }, - modal: { - type: Boolean, - default: true, - }, - direction: { - type: String as PropType, - default: 'rtl', - validator(val: IDrawerDirection) { - return ['ltr', 'rtl', 'ttb', 'btt'].indexOf(val) !== -1 - }, - }, - modalAppendToBody: { - type: Boolean, - default: true, - }, - showClose: { - type: Boolean, - default: true, - }, - size: { - type: String, - default: '30%', - }, - title: { - type: String, - default: '', - }, - modelValue: { - type: Boolean, - }, - wrapperClosable: { - type: Boolean, - default: true, - }, - withHeader: { - type: Boolean, - default: true, - }, - }, - - emits: ['open', 'opened', 'close', 'closed', 'update:modelValue'], - - setup(props: IDrawerProps, ctx) { - const drawer = ref(null) - const root = ref(null) - const prevActiveElement = ref(null) - const closed = ref(false) - const isHorizontal = computed(() => props.direction === 'rtl' || props.direction === 'ltr') - - const { popupData, open } = usePopup({ - props, - $el: root, - vVm: { handleClose, closeOnClickModal: props.closeOnClickModal }, - }) - - function afterEnter() { - ctx.emit('opened') - } - - function afterLeave() { - ctx.emit('closed') - } - - function hide(cancel = true) { - if (cancel !== false) { - ctx.emit('update:modelValue', false) - ctx.emit('close') - if (props.destroyOnClose === true) { - popupData.rendered = false - } - closed.value = true - } - } - - function handleWrapperClick() { - if (props.wrapperClosable) { - closeDrawer() - } - } - - function closeDrawer() { - if (typeof props.beforeClose === 'function') { - props.beforeClose(hide) - } else { - hide() - } - } - - function handleClose() { - // This method here will be called by PopupManger, when the `closeOnPressEscape` was set to true - // pressing `ESC` will call this method, and also close the drawer. - // This method also calls `beforeClose` if there was one. - closeDrawer() - } - - watch( - () => props.modelValue, - val => { - if (val) { - closed.value = false - ctx.emit('open') - prevActiveElement.value = document.activeElement as HTMLElement - nextTick(() => { - Utils.focusFirstDescendant(drawer.value) - }) - } else { - if (!closed.value) ctx.emit('close') - nextTick(() => { - if (prevActiveElement.value) { - prevActiveElement.value.focus() - } - }) - } - }, - ) - - return { - root, - drawer, - closed, - afterEnter, - afterLeave, - handleWrapperClick, - isHorizontal, - closeDrawer, - popupData, - open, - } - }, - - template: `${template}`, -}) diff --git a/packages/drawer/src/index.vue b/packages/drawer/src/index.vue new file mode 100644 index 0000000000..c6c3a3f559 --- /dev/null +++ b/packages/drawer/src/index.vue @@ -0,0 +1,261 @@ + + + diff --git a/packages/drawer/src/popup.ts b/packages/drawer/src/popup.ts deleted file mode 100644 index 99c01e7886..0000000000 --- a/packages/drawer/src/popup.ts +++ /dev/null @@ -1,229 +0,0 @@ -import PopupManager from '@element-plus/utils/popup-manager' -import isServer from '@element-plus/utils/isServer' -import { - reactive, - watch, - nextTick, - ComponentPublicInstance, - onBeforeUnmount, - onBeforeMount, - onMounted, -} from 'vue' -import { - getStyle, - addClass, - removeClass, - hasClass, -} from '@element-plus/utils/dom' -import { merge } from 'lodash' -import getScrollBarWidth from '@element-plus/utils/scrollbar-width' -import { IDrawerWithPopupOption, IDrawerPopupOption } from './drawer' - -let idSeed = 1 -let scrollBarWidth: number - -// XXX this may be replaced with other usePopup as Dialog? -const usePopup = ({ props, $el, vVm }: IDrawerPopupOption) => { - let _popupId: string - let _opening = false - let _closing = false - // let _closeTimer = null // XXX These code will be removed ? - // let _openTimer = null - - const drawerState = reactive({ - opened: false, - bodyPaddingRight: null, - computedBodyPaddingRight: 0, - withoutHiddenClass: true, - rendered: false, - }) - - function open(options: Partial = {}) { - if (!drawerState.rendered) { - drawerState.rendered = true - } - - const propsNew = merge({}, props, options) - // XXX These code will be removed ? - // const props = merge({}, this.$props || this, options); - - // if (_closeTimer) { - // clearTimeout(_closeTimer); - // _closeTimer = null; - // } - // clearTimeout(_openTimer); - - // const openDelay = Number(propsNew.openDelay); - // if (openDelay > 0) { - // _openTimer = setTimeout(() => { - // _openTimer = null; - // doOpen(propsNew); - // }, openDelay); - // } else { - doOpen(propsNew) - // } - } - - function doOpen(props: IDrawerWithPopupOption) { - if (isServer) return - // if (props.willOpen && !props.willOpen()) return - if (drawerState.opened) return - - _opening = true - const dom = $el.value - const modal = props.modal - const zIndex = props.zIndex - if (zIndex) { - PopupManager.zIndex = zIndex - } - - if (modal) { - if (_closing) { - PopupManager.closeModal(_popupId) - _closing = false - } - PopupManager.openModal( - _popupId, - PopupManager.nextZIndex(), - props.modalAppendToBody ? undefined : dom, - props.modalClass || '', - props.modalFade || false, - ) - if (props.lockScroll) { - drawerState.withoutHiddenClass = !hasClass( - document.body, - 'el-popup-parent--hidden', - ) - if (drawerState.withoutHiddenClass) { - drawerState.bodyPaddingRight = document.body.style.paddingRight - drawerState.computedBodyPaddingRight = parseInt( - getStyle(document.body, 'paddingRight'), - 10, - ) - } - scrollBarWidth = getScrollBarWidth() - const bodyHasOverflow = - document.documentElement.clientHeight < document.body.scrollHeight - const bodyOverflowY = getStyle(document.body, 'overflowY') - if ( - scrollBarWidth > 0 && - (bodyHasOverflow || bodyOverflowY === 'scroll') && - drawerState.withoutHiddenClass - ) { - document.body.style.paddingRight = - drawerState.computedBodyPaddingRight + scrollBarWidth + 'px' - } - addClass(document.body, 'el-popup-parent--hidden') - } - } - - if (getComputedStyle(dom).position === 'static') { - dom.style.position = 'absolute' - } - - dom.style.zIndex = String(PopupManager.nextZIndex()) - drawerState.opened = true - - // XXX These code will be removed ? - // props.onOpen && onOpen(); - - doAfterOpen() - } - - function doAfterOpen() { - _opening = false - } - - function close() { - // XXX These code will be removed ? - // if (props.willClose && !props.willClose()) return; - - // if (_openTimer !== null) { - // clearTimeout(_openTimer); - // _openTimer = null; - // } - // clearTimeout(_closeTimer); - - // const closeDelay = Number(this.closeDelay); - - // if (closeDelay > 0) { - // _closeTimer = setTimeout(() => { - // _closeTimer = null; - // this.doClose(); - // }, closeDelay); - // } else { - doClose() - // } - } - - function doClose() { - _closing = true - - // XXX These code will be removed ? - // this.onClose && this.onClose(); - - if (props.lockScroll) { - setTimeout(restoreBodyStyle, 200) - } - - drawerState.opened = false - - doAfterClose() - } - - function doAfterClose() { - PopupManager.closeModal(_popupId) - _closing = false - } - - function restoreBodyStyle() { - if (props.modal && drawerState.withoutHiddenClass) { - document.body.style.paddingRight = drawerState.bodyPaddingRight - removeClass(document.body, 'el-popup-parent--hidden') - } - drawerState.withoutHiddenClass = true - } - - onMounted(() => { - if (props.modelValue) { - drawerState.rendered = true - open() - } - }) - - onBeforeMount(() => { - _popupId = 'popup-' + idSeed++ - PopupManager.register(_popupId, { - ...vVm, - close, - } as ComponentPublicInstance) - }) - - onBeforeUnmount(() => { - PopupManager.deregister(_popupId) - PopupManager.closeModal(_popupId) - restoreBodyStyle() - }) - - watch( - () => props.modelValue, - val => { - if (val) { - if (_opening) return - if (!drawerState.rendered) { - drawerState.rendered = true - nextTick(() => { - open() - }) - } else { - open() - } - } else { - close() - } - }, - ) - return { popupData: drawerState, open } -} - -export default usePopup diff --git a/packages/input-number/src/index.vue b/packages/input-number/src/index.vue index 3d63836235..4bd3a1b6bb 100644 --- a/packages/input-number/src/index.vue +++ b/packages/input-number/src/index.vue @@ -64,7 +64,6 @@ import { Input as ElInput } from '@element-plus/input' import { useGlobalConfig } from '@element-plus/utils/util' import { isValidComponentSize } from '@element-plus/utils/validators' import { elFormKey, elFormItemKey } from '@element-plus/form' -import { parseInt } from 'lodash' import type { PropType } from 'vue' import type { ElFormContext, ElFormItemContext } from '@element-plus/form' diff --git a/packages/locale/tsconfig.json b/packages/locale/tsconfig.json deleted file mode 100644 index a3b4b6c8eb..0000000000 --- a/packages/locale/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compilerOptions": { - "module": "ESNext", - "declaration": false, - "noImplicitAny": false, - "removeComments": true, - "moduleResolution": "node", - "esModuleInterop": true, - "jsx": "preserve", - "noLib": false, - "target": "es6", - "sourceMap": false, - "lib": [ - "ESNext", "DOM" - ], - "allowSyntheticDefaultImports": true, - "allowUnreachableCode": true, - "allowUnusedLabels": true, - "outDir": "../../lib/locale" - }, - "exclude": [ - "node_modules", - "__test__/*.ts" - ] - } diff --git a/packages/message-box/src/index.vue b/packages/message-box/src/index.vue index 7d6e4f160d..fb5441e846 100644 --- a/packages/message-box/src/index.vue +++ b/packages/message-box/src/index.vue @@ -2,6 +2,7 @@
({ + const state = reactive({ uid: 1, title: undefined, message: '', diff --git a/packages/message-box/src/messageBox.ts b/packages/message-box/src/messageBox.ts index 96ebeebb51..005bd86907 100644 --- a/packages/message-box/src/messageBox.ts +++ b/packages/message-box/src/messageBox.ts @@ -180,6 +180,7 @@ MessageBox.alert = (message, title, options?: ElMessageBoxOptions) => { } else if (title === undefined) { title = '' } + return MessageBox(Object.assign({ title: title, message: message, diff --git a/packages/radio/src/useRadio.ts b/packages/radio/src/useRadio.ts index 8dd23992d5..0999f8cb06 100644 --- a/packages/radio/src/useRadio.ts +++ b/packages/radio/src/useRadio.ts @@ -1,10 +1,10 @@ import { ref, computed, inject, WritableComputedRef } from 'vue' -import { elFormKey, elFormItemKey } from '@element-plus/form/src/token' +import { elFormKey, elFormItemKey } from '@element-plus/form' import { useGlobalConfig } from '@element-plus/utils/util' import radioGroupKey from './token' import type { ComputedRef } from 'vue' -import type { ElFormContext, ElFormItemContext } from '@element-plus/form/src/token' +import type { ElFormContext, ElFormItemContext } from '@element-plus/form' import type { RadioGroupContext } from './token' export const useRadio = () => { diff --git a/packages/select/src/useSelect.ts b/packages/select/src/useSelect.ts index 4b7fb9f21b..ad622812cb 100644 --- a/packages/select/src/useSelect.ts +++ b/packages/select/src/useSelect.ts @@ -19,10 +19,10 @@ import { isEdge, useGlobalConfig, } from '@element-plus/utils/util' -import { elFormKey, elFormItemKey } from '@element-plus/form/src/token' +import { elFormKey, elFormItemKey } from '@element-plus/form' import isEqual from 'lodash/isEqual' -import type { ElFormContext, ElFormItemContext } from '@element-plus/form/src/token' +import type { ElFormContext, ElFormItemContext } from '@element-plus/form' export function useSelectStates(props) { const selectEmitter = mitt() diff --git a/packages/slider/src/useSlide.ts b/packages/slider/src/useSlide.ts index ba960f23e2..a52c4fc758 100644 --- a/packages/slider/src/useSlide.ts +++ b/packages/slider/src/useSlide.ts @@ -1,9 +1,9 @@ import { computed, inject, nextTick, ref } from 'vue' import { CHANGE_EVENT } from '@element-plus/utils/constants' -import { elFormKey, elFormItemKey } from '@element-plus/form/src/token' +import { elFormKey, elFormItemKey } from '@element-plus/form' import { ButtonRefs, ISliderInitData, ISliderProps } from './Slider' -import type { ElFormContext, ElFormItemContext } from '@element-plus/form/src/token' +import type { ElFormContext, ElFormItemContext } from '@element-plus/form' export const useSlide = (props: ISliderProps, initData: ISliderInitData, emit) => { const elForm = inject(elFormKey, {} as ElFormContext) diff --git a/packages/switch/src/index.vue b/packages/switch/src/index.vue index b474104d82..7d8e47da23 100644 --- a/packages/switch/src/index.vue +++ b/packages/switch/src/index.vue @@ -228,5 +228,3 @@ export default defineComponent({ }, }) - - diff --git a/packages/utils/popup-manager.ts b/packages/utils/popup-manager.ts index ee3c832993..5a692fd428 100644 --- a/packages/utils/popup-manager.ts +++ b/packages/utils/popup-manager.ts @@ -1,19 +1,17 @@ -import { ComponentPublicInstance } from 'vue' +import { Ref } from 'vue' import isServer from './isServer' import { getConfig } from './config' import { addClass, removeClass, on } from './dom' import { EVENT_CODE } from './aria' -interface ComponentMethods { - closeOnClickModal: boolean +interface Instance { + closeOnClickModal: Ref + closeOnPressEscape: Ref close: () => void - closeOnPressEscape: boolean - handleClose: () => void - handleAction: (action: string) => void + handleClose?: () => void + handleAction?: (action: string) => void } -type Instance = ComponentPublicInstance; - type StackFrame = { id: string; zIndex: number; modalClass: string; }; interface IPopupManager { @@ -100,7 +98,7 @@ const PopupManager: IPopupManager = { if (!topItem) return const instance = PopupManager.getInstance(topItem.id) - if (instance && instance.closeOnClickModal) { + if (instance && instance.closeOnClickModal.value) { instance.close() } }, @@ -223,7 +221,7 @@ if (!isServer) { if (event.code === EVENT_CODE.esc) { const topPopup = getTopPopup() - if (topPopup && topPopup.closeOnPressEscape) { + if (topPopup && topPopup.closeOnPressEscape.value) { topPopup.handleClose ? topPopup.handleClose() : topPopup.handleAction diff --git a/packages/utils/popup/usePopup.ts b/packages/utils/popup/usePopup.ts index 74d049e459..c0cd6eca8d 100644 --- a/packages/utils/popup/usePopup.ts +++ b/packages/utils/popup/usePopup.ts @@ -3,48 +3,39 @@ import { reactive, onBeforeMount, onBeforeUnmount, - onMounted, getCurrentInstance, watch, + toRefs, } from 'vue' import PopupManager from '../popup-manager' import getScrollBarWidth from '../scrollbar-width' import { getStyle, addClass, removeClass, hasClass } from '../dom' import isServer from '../isServer' +interface Props { + openDelay: number + closeDelay: number + closeOnClickModal: boolean + closeOnPressEscape: boolean + lockScroll: boolean + modal: boolean + modalAppendToBody: boolean + modalClass?: string + modalFade: boolean + zIndex?: number +} + let idSeed = 1 let scrollBarWidth -export const usePopup1 = { - watch: { - visible(val) { - if (val) { - if (this._opening) return - if (!this.rendered) { - this.rendered = true - nextTick(() => { - this.open() - }).then(() => { - // - }) - } else { - this.open() - } - } else { - this.close() - } - }, - }, -} - -const usePopup = (props, doClose) => { +const usePopup = (props: Readonly, doClose: () => void, rootRef = 'root') => { let _popupId let _opening = false let _closing = false - let vm let _closeTimer = null let _openTimer = null + const vm = getCurrentInstance() const state = reactive({ opened: false, bodyPaddingRight: null, @@ -54,13 +45,15 @@ const usePopup = (props, doClose) => { visible: false, }) - onMounted(() => { - vm = getCurrentInstance() - }) - onBeforeMount(() => { + const { handleClose, handleAction } = vm.proxy as any _popupId = 'popup-' + idSeed++ - PopupManager.register(_popupId, vm) + PopupManager.register(_popupId, { + ...toRefs(props), + close, + handleClose, + handleAction, + }) }) onBeforeUnmount(() => { @@ -75,7 +68,8 @@ const usePopup = (props, doClose) => { _opening = true - const dom = vm.vnode.el + // `vm.vnode.el` will be a comment node when using `Teleport` + const dom = vm.refs[rootRef] as HTMLElement const modal = merProps.modal @@ -89,7 +83,14 @@ const usePopup = (props, doClose) => { PopupManager.closeModal(_popupId) _closing = false } - PopupManager.openModal(_popupId, PopupManager.nextZIndex(), props.modalAppendToBody ? undefined : dom, merProps.modalClass, merProps.modalFade) + PopupManager.openModal( + _popupId, + PopupManager.nextZIndex(), + props.modalAppendToBody ? undefined : dom, + merProps.modalClass, + merProps.modalFade, + ) + if (merProps.lockScroll) { state.withoutHiddenClass = !hasClass(document.body, 'el-popup-parent--hidden') if (state.withoutHiddenClass) { @@ -110,7 +111,7 @@ const usePopup = (props, doClose) => { dom.style.position = 'absolute' } - dom.style.zIndex = PopupManager.nextZIndex() + dom.style.zIndex = String(PopupManager.nextZIndex()) state.opened = true doAfterOpen() @@ -196,6 +197,7 @@ const usePopup = (props, doClose) => { return { state, + open, close, doAfterClose, updateClosingFlag, diff --git a/packages/utils/tsconfig.json b/packages/utils/tsconfig.json deleted file mode 100644 index 5ebfbcf5e6..0000000000 --- a/packages/utils/tsconfig.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "compilerOptions": { - "module": "ESNext", - "declaration": false, - "noImplicitAny": false, - "removeComments": true, - "moduleResolution": "node", - "esModuleInterop": true, - "jsx": "preserve", - "noLib": false, - "target": "es6", - "sourceMap": false, - "lib": [ - "ESNext", "DOM" - ], - "allowSyntheticDefaultImports": true, - "allowUnreachableCode": true, - "allowUnusedLabels": true, - "outDir": "../../lib/utils" - }, - "include": [ - "./**/*.ts", - "../../typings/vue-shim.d.ts" - ], - "exclude": [ - "node_modules", - "tests/*.ts" - ] - } diff --git a/packages/utils/util.ts b/packages/utils/util.ts index 7ab2de1da3..9bd9ff7f27 100644 --- a/packages/utils/util.ts +++ b/packages/utils/util.ts @@ -1,5 +1,4 @@ import { getCurrentInstance } from 'vue' -import { castArray } from 'lodash' import { isObject, @@ -82,8 +81,8 @@ export const escapeRegexpString = (value = ''): string => // coerce truthy value to array export const coerceTruthyValueToArray = arr => { - if (!arr) { return [] } - return castArray(arr) + if (!arr && arr !== 0) { return [] } + return Array.isArray(arr) ? arr : [arr] } export const isIE = function(): boolean { @@ -146,8 +145,6 @@ export function rafThrottle>(fn: T): AnyFunction) => { clearTimeout(timer.value) timer.value = null diff --git a/website/docs/en-US/drawer.md b/website/docs/en-US/drawer.md index 7e99cdd780..852df72aff 100644 --- a/website/docs/en-US/drawer.md +++ b/website/docs/en-US/drawer.md @@ -6,7 +6,7 @@ Sometimes, `Dialog` does not always satisfy our requirements, let's say you have Callout a temporary drawer, from multiple direction -:::demo You must set `visible` for `Drawer` like `Dialog` does to control the visibility of `Drawer` itself, it's `boolean` type. `Drawer` has to parts: `title` & `body`, the `title` is a named slot, you can also set the title through attribute named `title`, default to an empty string, the `body` part is the main area of `Drawer`, which contains user defined content. When opening, `Drawer` expand itself from the **right corner to left** which size is **30%** of the browser window by default. You can change that default behavior by setting `direction` and `size` attribute. This show case also demonstrated how to use the `before-close` API, check the Attribute section for more detail +:::demo You must set `model-value` for `Drawer` like `Dialog` does to control the visibility of `Drawer` itself, it's `boolean` type. `Drawer` has to parts: `title` & `body`, the `title` is a named slot, you can also set the title through attribute named `title`, default to an empty string, the `body` part is the main area of `Drawer`, which contains user defined content. When opening, `Drawer` expand itself from the **right corner to left** which size is **30%** of the browser window by default. You can change that default behavior by setting `direction` and `size` attribute. This show case also demonstrated how to use the `before-close` API, check the Attribute section for more detail ```html @@ -22,7 +22,7 @@ Callout a temporary drawer, from multiple direction Hi, there! @@ -63,7 +63,7 @@ When you no longer need a title, you can remove title from drawer. Hi there! @@ -91,7 +91,7 @@ Like `Dialog`, `Drawer` can do many diverse interaction as you wanted. Open Drawer with nested form @@ -104,7 +104,7 @@ Like `Dialog`, `Drawer` can do many diverse interaction as you wanted.
Click me! @@ -216,7 +216,7 @@ You can also have multiple layer of `Drawer` just like `Dialog`. title="I'm inner Drawer" :append-to-body="true" :before-close="handleClose" - :visible.sync="innerDrawer"> + v-model="innerDrawer">

_(:зゝ∠)_

@@ -257,12 +257,6 @@ Drawer provides an API called `destroyOnClose`, which is a flag variable that in ::: -:::tip - -If the variable bound to `visible` is managed in Vuex store, the `.sync` can not work properly. In this case, please remove the `.sync` modifier, listen to `open` and `close` events of Dialog, and commit Vuex mutations to update the value of that variable in the event handlers. - -::: - ### Drawer Attributes | Parameter| Description | Type | Acceptable Values | Defaults | @@ -278,7 +272,7 @@ If the variable bound to `visible` is managed in Vuex store, the `.sync` can not | show-close | Should show close button at the top right of Drawer | boolean | — | true | | size | Drawer's size, if Drawer is horizontal mode, it effects the width property, otherwise it effects the height property, when size is `number` type, it describes the size by unit of pixels; when size is `string` type, it should be used with `x%` notation, other wise it will be interpreted to pixel unit | number / string | - | '30%' | | title | Drawer's title, can also be set by named slot, detailed descriptions can be found in the slot form | string | — | — | -| visible | Should Drawer be displayed, also support the `.sync` notation | boolean | — | false | +| model-value | Should Drawer be displayed, also support the `.sync` notation | boolean | — | false | | wrapperClosable | Indicates whether user can close Drawer by clicking the shadowing layer. | boolean | - | true | | withHeader | Flag that controls the header section's existance, default to true, when withHeader set to false, both `title attribute` and `title slot` won't work | boolean | - | true | diff --git a/website/docs/es/drawer.md b/website/docs/es/drawer.md index cd4b0ff569..62b8f048b1 100644 --- a/website/docs/es/drawer.md +++ b/website/docs/es/drawer.md @@ -6,7 +6,7 @@ A veces, `Dialog` no siempre satisface nuestros requisitos, digamos que tiene un Llamada de un drawer temporal, desde varias direcciones -:::demo Debe establecer `visible` para `Drawer` como lo hace `Dialog` para controlar la visibilidad. `visible` es del tipo `boolean`. `Drawer` tiene partes: `title` & `body`, el `title` es un slot con nombre, también puede establecer el título a través de un atributo llamado `title`, por defecto a una cadena vacía, la parte `body` es el área principal de `Drawer`, que contiene contenido definido por el usuario. Al abrir, `Drawer` se expande desde la **esquina derecha a la izquierda** cuyo tamaño es **30%** de la ventana del navegador por defecto. Puede cambiar ese comportamiento predeterminado estableciendo los atributos `direction` y `size`. Este caso de demostración también muestra cómo utilizar la API `before-close`, consulte la sección Atributos para obtener más detalles. +:::demo Debe establecer `model-value` para `Drawer` como lo hace `Dialog` para controlar la visibilidad. `visible` es del tipo `boolean`. `Drawer` tiene partes: `title` & `body`, el `title` es un slot con nombre, también puede establecer el título a través de un atributo llamado `title`, por defecto a una cadena vacía, la parte `body` es el área principal de `Drawer`, que contiene contenido definido por el usuario. Al abrir, `Drawer` se expande desde la **esquina derecha a la izquierda** cuyo tamaño es **30%** de la ventana del navegador por defecto. Puede cambiar ese comportamiento predeterminado estableciendo los atributos `direction` y `size`. Este caso de demostración también muestra cómo utilizar la API `before-close`, consulte la sección Atributos para obtener más detalles. ```html @@ -22,7 +22,7 @@ Llamada de un drawer temporal, desde varias direcciones Hi, there! @@ -63,7 +63,7 @@ When you no longer need a title, you can remove title from drawer. Hi there! @@ -91,7 +91,7 @@ Al igual que `Dialog`, `Drawer` puede hacer muchas interacciones diversas. Open Drawer with nested form @@ -104,7 +104,7 @@ Al igual que `Dialog`, `Drawer` puede hacer muchas interacciones diversas.
Click me! @@ -216,7 +216,7 @@ También puede tener varias capas de `Drawer` al igual que con `Dialog`. title="I'm inner Drawer" :append-to-body="true" :before-close="handleClose" - :visible.sync="innerDrawer"> + v-model="innerDrawer">

_(:зゝ∠)_

@@ -257,12 +257,6 @@ El Drawer proporciona una API llamada "destroyOnClose", que es una variable de b ::: -:::tip - -Si la variable `visible` se gestiona en el almacén de Vuex, el `.sync` no puede funcionar correctamente. En este caso, elimine el modificador `.sync`, escuche los eventos `open` y `close` de Drawer, y envíe mutaciones Vuex para actualizar el valor de esa variable en los manejadores de eventos. - -::: - ### Atributos de Drawer | Parámetros | Descripción | Tipo | Valores aceptados | Por defecto | @@ -278,7 +272,7 @@ Si la variable `visible` se gestiona en el almacén de Vuex, el `.sync` no puede | show-close | Se mostrará el botón de cerrar en la parte superior derecha del Drawer | boolean | — | true | | size | Tamaño del Drawer. Si el Drawer está en modo horizontal, afecta a la propiedad width, de lo contrario afecta a la propiedad height, cuando el tamaño es tipo `number`, describe el tamaño por unidad de píxeles; cuando el tamaño es tipo `string`, se debe usar con notación `x%`, de lo contrario se interpretará como unidad de píxeles. | number / string | - | '30%' | | title | El título del Drawer, también se puede establecer por slot con nombre, las descripciones detalladas se pueden encontrar en el formulario de slot. | string | — | — | -| visible | Si se muestra el Drawer, también soporta la notación `.sync` | boolean | — | false | +| model-value | Si se muestra el Drawer, también soporta la notación `.sync` | boolean | — | false | | wrapperClosable | Indica si el usuario puede cerrar el Drawer haciendo clic en la capa de sombreado. | boolean | - | true | | withHeader | Flag that controls the header section's existance, default to true, when withHeader set to false, both `title attribute` and `title slot` won't work | boolean | - | true | diff --git a/website/docs/fr-FR/drawer.md b/website/docs/fr-FR/drawer.md index 7e99cdd780..852df72aff 100644 --- a/website/docs/fr-FR/drawer.md +++ b/website/docs/fr-FR/drawer.md @@ -6,7 +6,7 @@ Sometimes, `Dialog` does not always satisfy our requirements, let's say you have Callout a temporary drawer, from multiple direction -:::demo You must set `visible` for `Drawer` like `Dialog` does to control the visibility of `Drawer` itself, it's `boolean` type. `Drawer` has to parts: `title` & `body`, the `title` is a named slot, you can also set the title through attribute named `title`, default to an empty string, the `body` part is the main area of `Drawer`, which contains user defined content. When opening, `Drawer` expand itself from the **right corner to left** which size is **30%** of the browser window by default. You can change that default behavior by setting `direction` and `size` attribute. This show case also demonstrated how to use the `before-close` API, check the Attribute section for more detail +:::demo You must set `model-value` for `Drawer` like `Dialog` does to control the visibility of `Drawer` itself, it's `boolean` type. `Drawer` has to parts: `title` & `body`, the `title` is a named slot, you can also set the title through attribute named `title`, default to an empty string, the `body` part is the main area of `Drawer`, which contains user defined content. When opening, `Drawer` expand itself from the **right corner to left** which size is **30%** of the browser window by default. You can change that default behavior by setting `direction` and `size` attribute. This show case also demonstrated how to use the `before-close` API, check the Attribute section for more detail ```html @@ -22,7 +22,7 @@ Callout a temporary drawer, from multiple direction Hi, there! @@ -63,7 +63,7 @@ When you no longer need a title, you can remove title from drawer. Hi there! @@ -91,7 +91,7 @@ Like `Dialog`, `Drawer` can do many diverse interaction as you wanted. Open Drawer with nested form @@ -104,7 +104,7 @@ Like `Dialog`, `Drawer` can do many diverse interaction as you wanted.
Click me! @@ -216,7 +216,7 @@ You can also have multiple layer of `Drawer` just like `Dialog`. title="I'm inner Drawer" :append-to-body="true" :before-close="handleClose" - :visible.sync="innerDrawer"> + v-model="innerDrawer">

_(:зゝ∠)_

@@ -257,12 +257,6 @@ Drawer provides an API called `destroyOnClose`, which is a flag variable that in ::: -:::tip - -If the variable bound to `visible` is managed in Vuex store, the `.sync` can not work properly. In this case, please remove the `.sync` modifier, listen to `open` and `close` events of Dialog, and commit Vuex mutations to update the value of that variable in the event handlers. - -::: - ### Drawer Attributes | Parameter| Description | Type | Acceptable Values | Defaults | @@ -278,7 +272,7 @@ If the variable bound to `visible` is managed in Vuex store, the `.sync` can not | show-close | Should show close button at the top right of Drawer | boolean | — | true | | size | Drawer's size, if Drawer is horizontal mode, it effects the width property, otherwise it effects the height property, when size is `number` type, it describes the size by unit of pixels; when size is `string` type, it should be used with `x%` notation, other wise it will be interpreted to pixel unit | number / string | - | '30%' | | title | Drawer's title, can also be set by named slot, detailed descriptions can be found in the slot form | string | — | — | -| visible | Should Drawer be displayed, also support the `.sync` notation | boolean | — | false | +| model-value | Should Drawer be displayed, also support the `.sync` notation | boolean | — | false | | wrapperClosable | Indicates whether user can close Drawer by clicking the shadowing layer. | boolean | - | true | | withHeader | Flag that controls the header section's existance, default to true, when withHeader set to false, both `title attribute` and `title slot` won't work | boolean | - | true | diff --git a/website/docs/jp/drawer.md b/website/docs/jp/drawer.md index c7b1899af1..023fcb09de 100644 --- a/website/docs/jp/drawer.md +++ b/website/docs/jp/drawer.md @@ -6,7 +6,7 @@ 一時的にDrawerを多方向から呼び出す -:::demo `Drawer` には `Dialog` のように `visible` を設定して `Drawer` 自体の表示を制御する必要があります。`title` は名前付きスロットで、タイトルは `title` という属性を使って設定することもできます。デフォルトでは、`Drawer`はブラウザウィンドウの**30%**の大きさの**右隅から**左隅に向かって展開します。このデフォルトの動作を変更するには、`direction` と `size` 属性を設定します。このショーケースでは `before-close` API の使い方も紹介しました。さらに詳しく知りたい場合は Attributesセクションもご覧ください。 +:::demo `Drawer` には `Dialog` のように `model-value` を設定して `Drawer` 自体の表示を制御する必要があります。`title` は名前付きスロットで、タイトルは `title` という属性を使って設定することもできます。デフォルトでは、`Drawer`はブラウザウィンドウの**30%**の大きさの**右隅から**左隅に向かって展開します。このデフォルトの動作を変更するには、`direction` と `size` 属性を設定します。このショーケースでは `before-close` API の使い方も紹介しました。さらに詳しく知りたい場合は Attributesセクションもご覧ください。 ```html @@ -22,7 +22,7 @@ Hi, there! @@ -63,7 +63,7 @@ Hi there! @@ -91,7 +91,7 @@ Open Drawer with nested form @@ -104,7 +104,7 @@
Click me! @@ -216,7 +216,7 @@ export default { title="I'm inner Drawer" :append-to-body="true" :before-close="handleClose" - :visible.sync="innerDrawer"> + v-model="innerDrawer">

_(:зゝ∠)_

@@ -257,12 +257,6 @@ Drawerは `destroyOnClose` というAPIを提供しています。これはフ ::: -:::tip - -Vuexストアで `visible` にバインドされた変数を管理している場合、`.sync` が正しく動作しません。この場合は、`.sync` 修飾子を削除し、Dialog の `open`, `close` イベントをリッスンし、Vuex ミューテーションをイベントハンドラでその変数の値を更新するよう、コミットします。 - -::: - ### Drawer属性 | Parameter| Description | Type | Acceptable Values | Defaults | @@ -278,7 +272,7 @@ Vuexストアで `visible` にバインドされた変数を管理している | show-close | Drawerの右上に閉じるボタンを表示するようにした | boolean | — | true | | size | Drawerのサイズ, ドローワが水平モードの場合は幅プロパティ, そうでない場合は高さプロパティ, サイズが `number` 型の場合はピクセル単位でサイズを記述します; サイズが `string` 型の場合は `x%` 記法を用います, それ以外の場合はピクセル単位で解釈されます | number / string | - | '30%' | | title | Drawerのタイトルは、スロットの名前を指定して設定することもできます。 | string | — | — | -| visible | Drawerを表示する場合は、`.sync` 記法もサポートします。 | boolean | — | false | +| model-value | Drawerを表示する場合は、`.sync` 記法もサポートします。 | boolean | — | false | | wrapperClosable | シャドウイングレイヤーをクリックしてDrwerを閉じることができるかどうかを示します。 | boolean | - | true | | withHeader | デフォルトは true で、withHeader が false に設定されている場合は `title attribute` と `title slot` の両方が動作しません。 | boolean | - | true | diff --git a/website/docs/zh-CN/drawer.md b/website/docs/zh-CN/drawer.md index 2b6c53a212..80d8f3909f 100644 --- a/website/docs/zh-CN/drawer.md +++ b/website/docs/zh-CN/drawer.md @@ -6,7 +6,7 @@ 呼出一个临时的侧边栏, 可以从多个方向呼出 -:::demo 需要设置 `visible` 属性,它的**类型**是 `boolean`,当为 **true** 时显示 Drawer。Drawer 分为两个部分:`title` 和 `body`,`title` 需要具名为 **title** 的 `slot`, 也可以通过 `title` 属性来定义,默认值为空。需要注意的是, Drawer 默认是从右往左打开, 当然可以设置对应的 `direction`, 详细请参考 `direction` 用法 最后,本例还展示了 `before-close` 的用法 +:::demo 需要设置 `model-value` 属性,它的**类型**是 `boolean`,当为 **true** 时显示 Drawer。Drawer 分为两个部分:`title` 和 `body`,`title` 需要具名为 **title** 的 `slot`, 也可以通过 `title` 属性来定义,默认值为空。需要注意的是, Drawer 默认是从右往左打开, 当然可以设置对应的 `direction`, 详细请参考 `direction` 用法 最后,本例还展示了 `before-close` 的用法 ```html @@ -22,9 +22,9 @@ + :before-close="handleClose" destroy-on-close> 我来啦! @@ -63,7 +63,7 @@ 我来啦! @@ -92,7 +92,7 @@ 打开嵌套 Form 的 Drawer @@ -105,7 +105,7 @@
打开里面的! @@ -218,7 +218,7 @@ export default { title="我是里面的" :append-to-body="true" :before-close="handleClose" - :visible.sync="innerDrawer"> + v-model="innerDrawer">

_(:зゝ∠)_

@@ -259,12 +259,6 @@ Drawer 提供一个 `destroyOnClose` API, 用来在关闭 Drawer 时销毁子组 ::: -:::tip - -如果 `visible` 属性绑定的变量位于 Vuex 的 store 内,那么 `.sync` 不会正常工作。此时需要去除 `.sync` 修饰符,同时监听 Drawer 的 `open` 和 `close` 事件,在事件回调中执行 Vuex 中对应的 mutation 更新 `visible` 属性绑定的变量的值。 - -::: - ### Drawer Attributes | 参数 | 说明 | 类型 | 可选值 | 默认值 | @@ -280,7 +274,7 @@ Drawer 提供一个 `destroyOnClose` API, 用来在关闭 Drawer 时销毁子组 | show-close | 是否显示关闭按钮 | boolean | — | true | | size | Drawer 窗体的大小, 当使用 `number` 类型时, 以像素为单位, 当使用 `string` 类型时, 请传入 'x%', 否则便会以 `number` 类型解释 | number / string | - | '30%' | | title | Drawer 的标题,也可通过具名 slot (见下表)传入 | string | — | — | -| visible | 是否显示 Drawer,支持 .sync 修饰符 | boolean | — | false | +| model-value | 是否显示 Drawer,支持 .sync 修饰符 | boolean | — | false | | wrapperClosable | 点击遮罩层是否可以关闭 Drawer | boolean | - | true | | withHeader | 控制是否显示 header 栏, 默认为 true, 当此项为 false 时, title attribute 和 title slot 均不生效 | boolean | - | true | diff --git a/website/webpack.config.js b/website/webpack.config.js index 6c76d6d81e..8ce4d343fa 100644 --- a/website/webpack.config.js +++ b/website/webpack.config.js @@ -8,10 +8,6 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin') const isProd = process.env.NODE_ENV === 'production' const isPlay = !!process.env.PLAY_ENV -const babelOptions = { - plugins: ['@vue/babel-plugin-jsx'], -} - const config = { mode: isProd ? 'production' : 'development', devtool: !isProd && 'cheap-module-eval-source-map', @@ -29,40 +25,9 @@ const config = { use: 'vue-loader', }, { - test: /\.ts$/, + test: /\.(ts|js)x?$/, exclude: /node_modules/, - loader: 'ts-loader', - options: { - appendTsSuffixTo: [/\.vue$/], - transpileOnly: true, - }, - }, - { - test: /\.tsx$/, - exclude: /node_modules/, - use: [ - { - loader: 'babel-loader', - options: babelOptions, - }, - { - loader: 'ts-loader', - options: { - appendTsxSuffixTo: [/\.vue$/], - transpileOnly: true, - }, - }, - ], - }, - { - test: /\.js(x?)$/, - exclude: /node_modules/, - use: [ - { - loader: 'babel-loader', - options: babelOptions, - }, - ], + loader: 'babel-loader', }, { test: /\.md$/, diff --git a/yarn.lock b/yarn.lock index 9b2d7b7ed9..7cee86f8c1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -92,6 +92,23 @@ "@algolia/logger-common" "4.4.0" "@algolia/requester-common" "4.4.0" +"@babel/cli@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.12.1.tgz#e08a0b1cb6fcd4b9eb6a606ba5602c5c0fe24a0c" + integrity sha512-eRJREyrfAJ2r42Iaxe8h3v6yyj1wu9OyosaUHW6UImjGf9ahGL9nsFNh7OCopvtcPL8WnEo7tp78wrZaZ6vG9g== + dependencies: + commander "^4.0.1" + convert-source-map "^1.1.0" + fs-readdir-recursive "^1.1.0" + glob "^7.0.0" + lodash "^4.17.19" + make-dir "^2.1.0" + slash "^2.0.0" + source-map "^0.5.0" + optionalDependencies: + "@nicolo-ribaudo/chokidar-2" "^2.1.8" + chokidar "^3.4.0" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" @@ -247,6 +264,13 @@ dependencies: "@babel/types" "^7.10.4" +"@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.12.1": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz#1bfc0229f794988f76ed0a4d4e90860850b54dfb" + integrity sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA== + dependencies: + "@babel/types" "^7.12.5" + "@babel/helper-module-transforms@^7.10.4", "@babel/helper-module-transforms@^7.10.5", "@babel/helper-module-transforms@^7.11.0": version "7.11.0" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz#b16f250229e47211abdd84b34b64737c2ab2d359" @@ -728,6 +752,16 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" +"@babel/plugin-transform-runtime@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.1.tgz#04b792057eb460389ff6a4198e377614ea1e7ba5" + integrity sha512-Ac/H6G9FEIkS2tXsZjL4RAdS3L3WHxci0usAnz7laPWUmFiGtj7tIASChqKZMHTSQTQY6xDbOq+V1/vIq3QrWg== + dependencies: + "@babel/helper-module-imports" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + resolve "^1.8.1" + semver "^5.5.1" + "@babel/plugin-transform-shorthand-properties@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz#9fd25ec5cdd555bb7f473e5e6ee1c971eede4dd6" @@ -922,6 +956,15 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" +"@babel/types@^7.0.0-beta.49", "@babel/types@^7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.5.tgz#5d6b4590cfe90c0c8d7396c83ffd9fc28b5a6450" + integrity sha512-gyTcvz7JFa4V45C0Zklv//GmFOAal5fL23OWpBLqc4nZ4Yrz67s4kCNwSK1Gu0MXGTU8mRY3zJYtacLdKXlzig== + dependencies: + "@babel/helper-validator-identifier" "^7.10.4" + lodash "^4.17.19" + to-fast-properties "^2.0.0" + "@babel/types@^7.12.1": version "7.12.1" resolved "https://registry.npmjs.org/@babel/types/-/types-7.12.1.tgz#e109d9ab99a8de735be287ee3d6a9947a190c4ae" @@ -1962,6 +2005,13 @@ call-me-maybe "^1.0.1" glob-to-regexp "^0.3.0" +"@nicolo-ribaudo/chokidar-2@^2.1.8": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8.tgz#eef8d9b47e8dc589499f14d656e8d2dd978c3d14" + integrity sha512-FohwULwAebCUKi/akMFyGi7jfc7JXTeMHzKxuP3umRd9mK/2Y7/SMBSI2jX+YLopPXi+PF9l307NmpfxTdCegA== + dependencies: + chokidar "2.1.8" + "@nodelib/fs.stat@^1.1.2": version "1.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" @@ -3166,6 +3216,28 @@ babel-plugin-jsx-v-model@^2.0.1: html-tags "^2.0.0" svg-tags "^1.0.0" +babel-plugin-lodash@^3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/babel-plugin-lodash/-/babel-plugin-lodash-3.3.4.tgz#4f6844358a1340baed182adbeffa8df9967bc196" + integrity sha512-yDZLjK7TCkWl1gpBeBGmuaDIFhZKmkoL+Cu2MUUjv5VxUZx/z7tBGBCBcQs5RI1Bkz5LLmNdjx7paOyQtMovyg== + dependencies: + "@babel/helper-module-imports" "^7.0.0-beta.49" + "@babel/types" "^7.0.0-beta.49" + glob "^7.1.1" + lodash "^4.17.10" + require-package-name "^2.0.1" + +babel-plugin-module-resolver@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.0.0.tgz#8f3a3d9d48287dc1d3b0d5595113adabd36a847f" + integrity sha512-3pdEq3PXALilSJ6dnC4wMWr0AZixHRM4utpdpBR9g5QG7B7JwWyukQv7a9hVxkbGFl+nQbrHDqqQOIBtTXTP/Q== + dependencies: + find-babel-config "^1.2.0" + glob "^7.1.6" + pkg-up "^3.1.0" + reselect "^4.0.0" + resolve "^1.13.1" + babel-plugin-syntax-jsx@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" @@ -3260,6 +3332,16 @@ before-after-hook@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.1.0.tgz#b6c03487f44e24200dd30ca5e6a1979c5d2fb635" +bfj@^6.1.1: + version "6.1.2" + resolved "https://registry.yarnpkg.com/bfj/-/bfj-6.1.2.tgz#325c861a822bcb358a41c78a33b8e6e2086dde7f" + integrity sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw== + dependencies: + bluebird "^3.5.5" + check-types "^8.0.3" + hoopy "^0.1.4" + tryer "^1.0.1" + big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" @@ -3677,21 +3759,12 @@ chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" -"chokidar@>=2.0.0 <4.0.0", chokidar@^3.4.1: - version "3.4.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.2.tgz#38dc8e658dec3809741eb3ef7bb0a47fe424232d" - dependencies: - anymatch "~3.1.1" - braces "~3.0.2" - glob-parent "~5.1.0" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.4.0" - optionalDependencies: - fsevents "~2.1.2" +check-types@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/check-types/-/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552" + integrity sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ== -chokidar@^2.0.0, chokidar@^2.1.8: +chokidar@2.1.8, chokidar@^2.0.0, chokidar@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== @@ -3710,6 +3783,35 @@ chokidar@^2.0.0, chokidar@^2.1.8: optionalDependencies: fsevents "^1.2.7" +"chokidar@>=2.0.0 <4.0.0", chokidar@^3.4.1: + version "3.4.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.2.tgz#38dc8e658dec3809741eb3ef7bb0a47fe424232d" + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.4.0" + optionalDependencies: + fsevents "~2.1.2" + +chokidar@^3.4.0: + version "3.4.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b" + integrity sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" + optionalDependencies: + fsevents "~2.1.2" + chownr@^1.1.1, chownr@^1.1.2: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" @@ -3932,11 +4034,11 @@ commander@2.8.x: dependencies: graceful-readlink ">= 1.0.0" -commander@^2.20.0: +commander@^2.18.0, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" -commander@^4.1.1: +commander@^4.0.1, commander@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" @@ -4169,7 +4271,7 @@ conventional-recommended-bump@^5.0.0: meow "^4.0.0" q "^1.5.1" -convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: +convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" dependencies: @@ -4850,6 +4952,11 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= +ejs@^2.6.1: + version "2.7.4" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" + integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== + electron-to-chromium@^1.3.564: version "1.3.564" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.564.tgz#e9c319ae437b3eb8bbf3e3bae4bead5a21945961" @@ -5298,7 +5405,7 @@ expect@^26.4.2: jest-message-util "^26.3.0" jest-regex-util "^26.0.0" -express@^4.17.1: +express@^4.16.3, express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== @@ -5482,11 +5589,23 @@ file-loader@^6.0.0: loader-utils "^2.0.0" schema-utils "^2.7.1" +file-save@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/file-save/-/file-save-0.2.0.tgz#39b20d0214e656b1417faa3c32d317b678545db7" + integrity sha1-ObINAhTmVrFBf6o8MtMXtnhUXbc= + dependencies: + mkdirp "~0.5.0" + file-uri-to-path@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== +filesize@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" + integrity sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg== + filesize@~2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/filesize/-/filesize-2.0.4.tgz#7805941c60fcdfe63f46d7ea358c59ade11c1325" @@ -5520,6 +5639,14 @@ finalhandler@~1.1.2: statuses "~1.5.0" unpipe "~1.0.0" +find-babel-config@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-1.2.0.tgz#a9b7b317eb5b9860cda9d54740a8c8337a2283a2" + integrity sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA== + dependencies: + json5 "^0.5.1" + path-exists "^3.0.0" + find-cache-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" @@ -5721,6 +5848,11 @@ fs-mkdirp-stream@^1.0.0: graceful-fs "^4.1.11" through2 "^2.0.3" +fs-readdir-recursive@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" + integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== + fs-write-stream-atomic@^1.0.8: version "1.0.10" resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" @@ -5955,7 +6087,7 @@ glob@7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: +glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" dependencies: @@ -6157,6 +6289,14 @@ gulplog@^1.0.0: dependencies: glogg "^1.0.0" +gzip-size@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" + integrity sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA== + dependencies: + duplexer "^0.1.1" + pify "^4.0.1" + handle-thing@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" @@ -6295,6 +6435,11 @@ homedir-polyfill@^1.0.1: dependencies: parse-passwd "^1.0.0" +hoopy@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" + integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== + hosted-git-info@^2.1.4, hosted-git-info@^2.7.1: version "2.8.8" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" @@ -6746,6 +6891,13 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" +is-core-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.0.0.tgz#58531b70aed1db7c0e8d4eb1a0a2d1ddd64bd12d" + integrity sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw== + dependencies: + has "^1.0.3" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -7524,6 +7676,11 @@ json5@2.x, json5@^2.1.2: dependencies: minimist "^1.2.5" +json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + json5@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" @@ -7952,7 +8109,7 @@ lodash.values@~2.4.1: dependencies: lodash.keys "~2.4.1" -lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.2.1: +lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.2.1: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" @@ -8426,7 +8583,7 @@ mkdirp@*: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" -mkdirp@0.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5: +mkdirp@0.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.0: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" dependencies: @@ -8942,6 +9099,11 @@ opencollective-postinstall@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259" +opener@^1.5.1: + version "1.5.2" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" + integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== + opn@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" @@ -9401,6 +9563,13 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +pkg-up@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" + integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== + dependencies: + find-up "^3.0.0" + please-upgrade-node@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" @@ -9870,6 +10039,13 @@ readdirp@~3.4.0: dependencies: picomatch "^2.2.1" +readdirp@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== + dependencies: + picomatch "^2.2.1" + rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -10073,11 +10249,21 @@ require-main-filename@^2.0.0: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== +require-package-name@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/require-package-name/-/require-package-name-2.0.1.tgz#c11e97276b65b8e2923f75dabf5fb2ef0c3841b9" + integrity sha1-wR6XJ2tluOKSP3Xav1+y7ww4Qbk= + requires-port@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= +reselect@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7" + integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA== + resize-observer-polyfill@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" @@ -10138,6 +10324,14 @@ resolve@1.17.0, resolve@1.x, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, re dependencies: path-parse "^1.0.6" +resolve@^1.13.1, resolve@^1.8.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.18.1.tgz#018fcb2c5b207d2a6424aee361c5a266da8f4130" + integrity sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA== + dependencies: + is-core-module "^2.0.0" + path-parse "^1.0.6" + restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -11350,6 +11544,11 @@ trim-off-newlines@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" +tryer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" + integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== + ts-jest@^24.0.0: version "24.3.0" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.3.0.tgz#b97814e3eab359ea840a1ac112deae68aa440869" @@ -11911,6 +12110,25 @@ webidl-conversions@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" +webpack-bundle-analyzer@^3.9.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.9.0.tgz#f6f94db108fb574e415ad313de41a2707d33ef3c" + integrity sha512-Ob8amZfCm3rMB1ScjQVlbYYUEJyEjdEtQ92jqiFUYt5VkEeO2v5UMbv49P/gnmCZm3A6yaFQzCBvpZqN4MUsdA== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + bfj "^6.1.1" + chalk "^2.4.1" + commander "^2.18.0" + ejs "^2.6.1" + express "^4.16.3" + filesize "^3.6.1" + gzip-size "^5.0.0" + lodash "^4.17.19" + mkdirp "^0.5.1" + opener "^1.5.1" + ws "^6.0.0" + webpack-chain@^4.9.0: version "4.12.1" resolved "https://registry.yarnpkg.com/webpack-chain/-/webpack-chain-4.12.1.tgz#6c8439bbb2ab550952d60e1ea9319141906c02a6" @@ -12207,7 +12425,7 @@ write@1.0.3: dependencies: mkdirp "^0.5.1" -ws@^6.2.1: +ws@^6.0.0, ws@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==