build: optimize (#560)

* build: replace ts-loader with @babel/preset-typescript
This commit is contained in:
Simona 2020-11-10 14:24:09 +08:00 committed by GitHub
parent 9a3d2911d7
commit c5fc8b4e9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 747 additions and 835 deletions

58
babel.config.js Normal file
View File

@ -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',
},
},
],
],
},
},
}

39
build/build-locale.js Normal file
View File

@ -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)
}
})
})

View File

@ -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(),
],
}

View File

@ -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"
]
}

View File

@ -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()

View File

@ -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)
}
}

View File

@ -113,16 +113,6 @@ interface IUseOptions {
currentColor: ComputedRef<string>
}
interface IProps {
modelValue?: string
showAlpha?: boolean
colorFormat?: string
disabled?: boolean
size?: string
popperClass?: string
predefine?: Array<string>
}
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)

View File

@ -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%')
})
})
})

View File

@ -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)

View File

@ -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<HTMLElement>
vVm: IDrawerFakeComponentInst
}
// XXX openModal needed, will be replaced?
export declare type IDrawerPopupModalOption = {
zIndex?: number
modalClass?: string
modalFade?: boolean
}
export declare type IDrawerWithPopupOption = IDrawerProps & IDrawerPopupModalOption

View File

@ -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 = `
<transition
name="el-drawer-fade"
@after-enter="afterEnter"
@after-leave="afterLeave"
>
<div
v-show="modelValue"
ref="root"
class="el-drawer__wrapper"
tabindex="-1"
>
<div
class="el-drawer__container"
:class="modelValue && 'el-drawer__open'"
tabindex="-1"
role="document"
@click.self="handleWrapperClick"
>
<div
ref="drawer"
aria-modal="true"
aria-labelledby="el-drawer__title"
:aria-label="title"
class="el-drawer"
:class="[direction, customClass]"
:style="isHorizontal ? 'width: ' + size : 'height: ' + size"
role="dialog"
tabindex="-1"
>
<header
v-if="withHeader"
id="el-drawer__title"
class="el-drawer__header"
>
<slot name="title">
<span role="heading" tabindex="0" :title="title">{{
title
}}</span>
</slot>
<button
v-if="showClose"
:aria-label="'close ' + (title || 'drawer')"
class="el-drawer__close-btn"
type="button"
@click="closeDrawer"
>
<i class="el-drawer__close el-icon el-icon-close"></i>
</button>
</header>
<section v-if="popupData.rendered" class="el-drawer__body">
<slot></slot>
</section>
</div>
</div>
</div>
</transition>`
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<IDrawerDirection>,
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<HTMLElement>(null)
const root = ref<HTMLElement>(null)
const prevActiveElement = ref<HTMLElement>(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: `<teleport v-if="appendToBody" to="body">${template}</teleport><template v-else>${template}</template>`,
})

View File

@ -0,0 +1,261 @@
<template>
<teleport to="body" :disabled="!appendToBody">
<transition
name="el-drawer-fade"
@after-enter="afterEnter"
@after-leave="afterLeave"
>
<div
v-show="modelValue"
ref="root"
class="el-drawer__wrapper"
tabindex="-1"
>
<div
class="el-drawer__container"
:class="modelValue && 'el-drawer__open'"
tabindex="-1"
role="document"
@click.self="handleWrapperClick"
>
<div
ref="drawer"
aria-modal="true"
aria-labelledby="el-drawer__title"
:aria-label="title"
class="el-drawer"
:class="[direction, customClass]"
:style="isHorizontal ? 'width: ' + size : 'height: ' + size"
role="dialog"
tabindex="-1"
>
<header
v-if="withHeader"
id="el-drawer__title"
class="el-drawer__header"
>
<slot name="title">
<span role="heading" tabindex="-1" :title="title">
{{ title }}
</span>
</slot>
<button
v-if="showClose"
:aria-label="'close ' + (title || 'drawer')"
class="el-drawer__close-btn"
type="button"
@click="closeDrawer"
>
<i class="el-drawer__close el-icon el-icon-close"></i>
</button>
</header>
<section v-if="state.rendered" class="el-drawer__body">
<slot></slot>
</section>
</div>
</div>
</div>
</transition>
</teleport>
</template>
<script lang='ts'>
import {
defineComponent, ref, computed,
watch, nextTick,
onMounted,
} from 'vue'
import usePopup from '@element-plus/utils/popup/usePopup'
import Utils from '@element-plus/utils/aria'
import type { PropType } from 'vue'
type Hide = (cancel: boolean) => void
type DrawerDirection = 'ltr' | 'rtl' | 'ttb' | 'btt'
export default defineComponent({
name: 'ElDrawer',
props: {
modelValue: Boolean,
appendToBody: {
type: Boolean,
default: false,
},
beforeClose: Function as PropType<(hide: Hide) => void>,
customClass: {
type: String,
default: '',
},
direction: {
type: String as PropType<DrawerDirection>,
default: 'rtl',
validator: (val: DrawerDirection) => {
return ['ltr', 'rtl', 'ttb', 'btt'].indexOf(val) !== -1
},
},
showClose: {
type: Boolean,
default: true,
},
size: {
type: String,
default: '30%',
},
title: {
type: String,
default: '',
},
wrapperClosable: {
type: Boolean,
default: true,
},
withHeader: {
type: Boolean,
default: true,
},
openDelay: {
type: Number,
default: 0,
},
closeDelay: {
type: Number,
default: 0,
},
zIndex: Number,
modal: {
type: Boolean,
default: true,
},
modalFade: {
type: Boolean,
default: true,
},
modalClass: String,
modalAppendToBody: {
type: Boolean,
default: true,
},
lockScroll: {
type: Boolean,
default: true,
},
closeOnPressEscape: {
type: Boolean,
default: true,
},
closeOnClickModal: {
type: Boolean,
default: false,
},
destroyOnClose: {
type: Boolean,
default: false,
},
},
emits: ['open', 'opened', 'close', 'closed', 'update:modelValue'],
setup(props, ctx) {
const {
state,
doAfterClose,
updateClosingFlag,
restoreBodyStyle,
} = usePopup(props, doClose)
const drawer = ref<HTMLElement>(null)
const root = ref<HTMLElement>(null)
const prevActiveElement = ref<HTMLElement>(null)
const closed = ref(false)
const isHorizontal = computed(() => props.direction === 'rtl' || props.direction === 'ltr')
function afterEnter() {
ctx.emit('opened')
}
function doClose() {
updateClosingFlag(true)
props.lockScroll && setTimeout(restoreBodyStyle, 200)
state.opened = false
doAfterClose()
}
function afterLeave() {
ctx.emit('closed')
}
function hide(cancel = true) {
if (cancel !== false) {
ctx.emit('update:modelValue', false)
ctx.emit('close')
if (props.destroyOnClose === true) {
state.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 => {
state.visible = 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(() => {
prevActiveElement.value?.focus()
})
}
},
)
onMounted(() => {
if (props.modelValue) {
state.rendered = true
state.visible = true
}
})
return {
state,
root,
drawer,
closed,
afterEnter,
afterLeave,
handleWrapperClick,
isHorizontal,
closeDrawer,
handleClose,
}
},
})
</script>

View File

@ -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<IDrawerWithPopupOption> = {}) {
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<any>)
})
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

View File

@ -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'

View File

@ -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"
]
}

View File

@ -2,6 +2,7 @@
<transition name="msgbox-fade">
<div
v-show="visible"
ref="root"
:aria-label="title || 'dialog'"
class="el-message-box__wrapper"
tabindex="-1"
@ -123,16 +124,14 @@ export default defineComponent({
},
props: {
openDelay: {
type: Boolean,
default: false,
type: Number,
default: 0,
},
closeDelay: {
type: Boolean,
default: false,
},
zIndex: {
type: Number,
default: 0,
},
zIndex: Number,
modalFade: {
type: Boolean,
default: true,
@ -181,7 +180,7 @@ export default defineComponent({
setup(props) {
let vm
const popup = usePopup(props, doClose)
const state = reactive<State>({
const state = reactive({
uid: 1,
title: undefined,
message: '',

View File

@ -180,6 +180,7 @@ MessageBox.alert = (message, title, options?: ElMessageBoxOptions) => {
} else if (title === undefined) {
title = ''
}
return MessageBox(Object.assign({
title: title,
message: message,

View File

@ -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 = () => {

View File

@ -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()

View File

@ -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)

View File

@ -228,5 +228,3 @@ export default defineComponent({
},
})
</script>

View File

@ -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<boolean>
closeOnPressEscape: Ref<boolean>
close: () => void
closeOnPressEscape: boolean
handleClose: () => void
handleAction: (action: string) => void
handleClose?: () => void
handleAction?: (action: string) => void
}
type Instance = ComponentPublicInstance<unknown, ComponentMethods>;
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

View File

@ -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<Props>, 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,

View File

@ -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"
]
}

View File

@ -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<T extends AnyFunction<any>>(fn: T): AnyFunction<void
}
}
export const objToArray = castArray
export const clearTimer = (timer: Ref<TimeoutHandle>) => {
clearTimeout(timer.value)
timer.value = null

View File

@ -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
<el-radio-group v-model="direction">
@ -22,7 +22,7 @@ Callout a temporary drawer, from multiple direction
<el-drawer
title="I am the title"
:visible.sync="drawer"
v-model="drawer"
:direction="direction"
:before-close="handleClose">
<span>Hi, there!</span>
@ -63,7 +63,7 @@ When you no longer need a title, you can remove title from drawer.
<el-drawer
title="I am the title"
:visible.sync="drawer"
v-model="drawer"
:with-header="false">
<span>Hi there!</span>
</el-drawer>
@ -91,7 +91,7 @@ Like `Dialog`, `Drawer` can do many diverse interaction as you wanted.
<el-button type="text" @click="dialog = true">Open Drawer with nested form</el-button>
<el-drawer
title="I have a nested table inside!"
:visible.sync="table"
v-model="table"
direction="rtl"
size="50%">
<el-table :data="gridData">
@ -104,7 +104,7 @@ Like `Dialog`, `Drawer` can do many diverse interaction as you wanted.
<el-drawer
title="I have a nested form inside!"
:before-close="handleClose"
:visible.sync="dialog"
v-model="dialog"
direction="ltr"
custom-class="demo-drawer"
ref="drawer"
@ -208,7 +208,7 @@ You can also have multiple layer of `Drawer` just like `Dialog`.
<el-drawer
title="I'm outer Drawer"
:visible.sync="drawer"
v-model="drawer"
size="50%">
<div>
<el-button @click="innerDrawer = true">Click me!</el-button>
@ -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">
<p>_(:зゝ∠)_</p>
</el-drawer>
</div>
@ -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 |

View File

@ -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
<el-radio-group v-model="direction">
@ -22,7 +22,7 @@ Llamada de un drawer temporal, desde varias direcciones
<el-drawer
title="I am the title"
:visible.sync="drawer"
v-model="drawer"
:direction="direction"
:before-close="handleClose">
<span>Hi, there!</span>
@ -63,7 +63,7 @@ When you no longer need a title, you can remove title from drawer.
<el-drawer
title="I am the title"
:visible.sync="drawer"
v-model="drawer"
:with-header="false">
<span>Hi there!</span>
</el-drawer>
@ -91,7 +91,7 @@ Al igual que `Dialog`, `Drawer` puede hacer muchas interacciones diversas.
<el-button type="text" @click="dialog = true">Open Drawer with nested form</el-button>
<el-drawer
title="I have a nested table inside!"
:visible.sync="table"
v-model="table"
direction="rtl"
size="50%">
<el-table :data="gridData">
@ -104,7 +104,7 @@ Al igual que `Dialog`, `Drawer` puede hacer muchas interacciones diversas.
<el-drawer
title="I have a nested form inside!"
:before-close="handleClose"
:visible.sync="dialog"
v-model="dialog"
direction="ltr"
custom-class="demo-drawer"
ref="drawer"
@ -208,7 +208,7 @@ También puede tener varias capas de `Drawer` al igual que con `Dialog`.
<el-drawer
title="I'm outer Drawer"
:visible.sync="drawer"
v-model="drawer"
size="50%">
<div>
<el-button @click="innerDrawer = true">Click me!</el-button>
@ -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">
<p>_(:зゝ∠)_</p>
</el-drawer>
</div>
@ -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 |

View File

@ -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
<el-radio-group v-model="direction">
@ -22,7 +22,7 @@ Callout a temporary drawer, from multiple direction
<el-drawer
title="I am the title"
:visible.sync="drawer"
v-model="drawer"
:direction="direction"
:before-close="handleClose">
<span>Hi, there!</span>
@ -63,7 +63,7 @@ When you no longer need a title, you can remove title from drawer.
<el-drawer
title="I am the title"
:visible.sync="drawer"
v-model="drawer"
:with-header="false">
<span>Hi there!</span>
</el-drawer>
@ -91,7 +91,7 @@ Like `Dialog`, `Drawer` can do many diverse interaction as you wanted.
<el-button type="text" @click="dialog = true">Open Drawer with nested form</el-button>
<el-drawer
title="I have a nested table inside!"
:visible.sync="table"
v-model="table"
direction="rtl"
size="50%">
<el-table :data="gridData">
@ -104,7 +104,7 @@ Like `Dialog`, `Drawer` can do many diverse interaction as you wanted.
<el-drawer
title="I have a nested form inside!"
:before-close="handleClose"
:visible.sync="dialog"
v-model="dialog"
direction="ltr"
custom-class="demo-drawer"
ref="drawer"
@ -208,7 +208,7 @@ You can also have multiple layer of `Drawer` just like `Dialog`.
<el-drawer
title="I'm outer Drawer"
:visible.sync="drawer"
v-model="drawer"
size="50%">
<div>
<el-button @click="innerDrawer = true">Click me!</el-button>
@ -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">
<p>_(:зゝ∠)_</p>
</el-drawer>
</div>
@ -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 |

View File

@ -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
<el-radio-group v-model="direction">
@ -22,7 +22,7 @@
<el-drawer
title="I am the title"
:visible.sync="drawer"
v-model="drawer"
:direction="direction"
:before-close="handleClose">
<span>Hi, there!</span>
@ -63,7 +63,7 @@
<el-drawer
title="I am the title"
:visible.sync="drawer"
v-model="drawer"
:with-header="false">
<span>Hi there!</span>
</el-drawer>
@ -91,7 +91,7 @@
<el-button type="text" @click="dialog = true">Open Drawer with nested form</el-button>
<el-drawer
title="I have a nested table inside!"
:visible.sync="table"
v-model="table"
direction="rtl"
size="50%">
<el-table :data="gridData">
@ -104,7 +104,7 @@
<el-drawer
title="I have a nested form inside!"
:before-close="handleClose"
:visible.sync="dialog"
v-model="dialog"
direction="ltr"
custom-class="demo-drawer"
ref="drawer"
@ -208,7 +208,7 @@ export default {
<el-drawer
title="I'm outer Drawer"
:visible.sync="drawer"
v-model="drawer"
size="50%">
<div>
<el-button @click="innerDrawer = true">Click me!</el-button>
@ -216,7 +216,7 @@ export default {
title="I'm inner Drawer"
:append-to-body="true"
:before-close="handleClose"
:visible.sync="innerDrawer">
v-model="innerDrawer">
<p>_(:зゝ∠)_</p>
</el-drawer>
</div>
@ -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 |

View File

@ -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
<el-radio-group v-model="direction">
@ -22,9 +22,9 @@
<el-drawer
title="我是标题"
:visible.sync="drawer"
v-model="drawer"
:direction="direction"
:before-close="handleClose">
:before-close="handleClose" destroy-on-close>
<span>我来啦!</span>
</el-drawer>
@ -63,7 +63,7 @@
<el-drawer
title="我是标题"
:visible.sync="drawer"
v-model="drawer"
:with-header="false">
<span>我来啦!</span>
</el-drawer>
@ -92,7 +92,7 @@
<el-button type="text" @click="dialog = true">打开嵌套 Form 的 Drawer</el-button>
<el-drawer
title="我嵌套了表格!"
:visible.sync="table"
v-model="table"
direction="rtl"
size="50%">
<el-table :data="gridData">
@ -105,7 +105,7 @@
<el-drawer
title="我嵌套了 Form !"
:before-close="handleClose"
:visible.sync="dialog"
v-model="dialog"
direction="ltr"
custom-class="demo-drawer"
ref="drawer"
@ -210,7 +210,7 @@ export default {
<el-drawer
title="我是外面的 Drawer"
:visible.sync="drawer"
v-model="drawer"
size="50%">
<div>
<el-button @click="innerDrawer = true">打开里面的!</el-button>
@ -218,7 +218,7 @@ export default {
title="我是里面的"
:append-to-body="true"
:before-close="handleClose"
:visible.sync="innerDrawer">
v-model="innerDrawer">
<p>_(:зゝ∠)_</p>
</el-drawer>
</div>
@ -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 |

View File

@ -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$/,

262
yarn.lock
View File

@ -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==