diff --git a/packages/varlet-cli/src/config/webpack.dev.config.ts b/packages/varlet-cli/src/config/webpack.dev.config.ts index 261d3534885..d6596764902 100644 --- a/packages/varlet-cli/src/config/webpack.dev.config.ts +++ b/packages/varlet-cli/src/config/webpack.dev.config.ts @@ -18,7 +18,8 @@ export function getDevConfig() { publicPath: '/', stats: 'errors-only', disableHostCheck: true, - hot: true + hot: true, + open: true }, plugins: [ new WebpackBarPlugin({ diff --git a/packages/varlet-eslint-config/index.js b/packages/varlet-eslint-config/index.js index adfbeced3f6..34343e3590d 100644 --- a/packages/varlet-eslint-config/index.js +++ b/packages/varlet-eslint-config/index.js @@ -50,6 +50,7 @@ module.exports = { 'vue/attributes-order': 'off', 'vue/require-default-prop': 'off', 'vue/no-unused-components': 'off', + 'vue/require-explicit-emits': 'off', // typescript-eslint '@typescript-eslint/camelcase': 'off', '@typescript-eslint/ban-ts-ignore': 'off', diff --git a/packages/varlet-ui/src/button/propsEmits.ts b/packages/varlet-ui/src/button/propsEmits.ts index 408743812ea..8c1a6aca049 100644 --- a/packages/varlet-ui/src/button/propsEmits.ts +++ b/packages/varlet-ui/src/button/propsEmits.ts @@ -1,19 +1,12 @@ -import { - typeValidator as loadingTypeValidator, - sizeValidator as loadingSizeValidator, - getTypeDefault as getLoadingTypeDefault -} from '../loading/propsEmits' +import { props as loadingProps } from '../loading/propsEmits' +import { pickProps } from '../utils/components' function typeValidator(type: string): boolean { - const validTypes = ['plain', 'primary', 'info', 'success', 'warning', 'danger'] - - return validTypes.includes(type) + return ['plain', 'primary', 'info', 'success', 'warning', 'danger'].includes(type) } function sizeValidator(size: string): boolean { - const validSizes = ['normal', 'mini', 'small', 'large'] - - return validSizes.includes(size) + return ['normal', 'mini', 'small', 'large'].includes(size) } export const props = { @@ -35,17 +28,9 @@ export const props = { default: false }, // 加载动画类型 - loadingType: { - type: String, - default: getLoadingTypeDefault, - validator: loadingTypeValidator - }, + loadingType: pickProps(loadingProps, 'type'), // 加载动画尺寸 - loadingSize: { - type: String, - default: (props: any) => props.size, - validator: loadingSizeValidator - }, + loadingSize: pickProps(loadingProps, 'size'), // 圆型按钮 round: { type: Boolean, diff --git a/packages/varlet-ui/src/context/lock.ts b/packages/varlet-ui/src/context/lock.ts index 809ba91d8ce..5b78f77ce89 100644 --- a/packages/varlet-ui/src/context/lock.ts +++ b/packages/varlet-ui/src/context/lock.ts @@ -10,9 +10,7 @@ import { import context from '.' export function resolveLock() { - const lockCounts: number = Object.keys(context.locks).reduce((lockCounts: number, key: string) => { - return lockCounts + context.locks[key] - }, 0) + const lockCounts: number = Object.keys(context.locks).length lockCounts <= 0 ? document.body.classList.remove('var--lock') : document.body.classList.add('var--lock') @@ -20,16 +18,39 @@ export function resolveLock() { export function addLock(uid: number) { context.locks[uid] = 1 + resolveLock() } export function releaseLock(uid: number) { - context.locks[uid] = 0 + delete context.locks[uid] + resolveLock() } -export function useLock(props: any, state: string) { +/** + * 组件锁操作 + * @param props 组件props + * @param state 组件props中控制组件加锁的开关对应的key值 + * @param use 组件props中控制组件加锁的开关是否可用对应的key值 + */ +export function useLock(props: any, state: string, use?: string) { const { uid } = getCurrentInstance() as ComponentInternalInstance + if (use) { + watch(() => props[use], (newValue: boolean) => { + if (newValue === false) { + // 改变为禁用状态 组件解锁 + releaseLock(uid) + } else if (newValue === true && props[state] === true) { + // 改变为启用状态 并且popup处于开启状态 组件加锁 + addLock(uid) + } + }) + } + + watch(() => props[state], (newValue: boolean) => { + if (use && props[use] === false) { + return + } - watch(() => props[state], (newValue) => { if (newValue === true) { // popup开启 组件加锁 addLock(uid) @@ -37,43 +58,49 @@ export function useLock(props: any, state: string) { // popup关闭 组件解锁 releaseLock(uid) } - // 处理全局锁 - resolveLock() }) onBeforeMount(() => { + if (use && props[use] === false) { + return + } + if (props[state] === true) { // popup处于开启状态 组件挂载 组件加锁 addLock(uid) } - // 处理全局锁 - resolveLock() }) onUnmounted(() => { + if (use && props[use] === false) { + return + } + if (props[state] === true) { // popup处于开启状态 组件卸载 组件解锁 releaseLock(uid) } - // 处理全局锁 - resolveLock() }) onActivated(() => { + if (use && props[use] === false) { + return + } + if (props[state] === true) { // popup处于开启状态 组件处于keepalive前台 组件加锁 addLock(uid) } - // 处理全局锁 - resolveLock() }) onDeactivated(() => { + if (use && props[use] === false) { + return + } + if (props[state] === true) { // popup处于开启状态 组件处于keepalive后台 组件解锁 releaseLock(uid) } - - resolveLock() }) } diff --git a/packages/varlet-ui/src/context/zIndex.ts b/packages/varlet-ui/src/context/zIndex.ts index 983614d68ac..2292f00e549 100644 --- a/packages/varlet-ui/src/context/zIndex.ts +++ b/packages/varlet-ui/src/context/zIndex.ts @@ -1,10 +1,15 @@ import context from './index' -import { watch } from 'vue' +import { watch, ref, Ref } from 'vue' + +export function useZIndex(props: any, state: string, count: number) { + const zIndex: Ref = ref(context.zIndex) -export function useZIndex(props: any, state: string, zIndex: number) { watch(() => props[state], (newValue) => { if (newValue === true) { - context.zIndex += zIndex + context.zIndex += count + zIndex.value = context.zIndex } }, { immediate: true }) + + return { zIndex } } diff --git a/packages/varlet-ui/src/dialog/Dialog.vue b/packages/varlet-ui/src/dialog/Dialog.vue index 1e47dc36a39..72f4c90eb2c 100644 --- a/packages/varlet-ui/src/dialog/Dialog.vue +++ b/packages/varlet-ui/src/dialog/Dialog.vue @@ -1,17 +1,136 @@ diff --git a/packages/varlet-ui/src/dialog/dialog.less b/packages/varlet-ui/src/dialog/dialog.less new file mode 100644 index 00000000000..07fc14b29cc --- /dev/null +++ b/packages/varlet-ui/src/dialog/dialog.less @@ -0,0 +1,47 @@ +@import "../styles/var"; + +@dialog-width: 270px; +@dialog-padding: 20px; +@dialog-border-radius: 2px; + +@dialog-message-padding: 26px 0; +@dialog-message-line-height: 24px; + +@dialog-button-margin-left: 6px; + +.var-dialog { + width: @dialog-width; + padding: @dialog-padding; + border-radius: 3px; + + &__popup-radius { + border-radius: @dialog-border-radius + } + + &__title { + font-size: @font-size-lg; + font-weight: 600; + } + + &__message { + padding: @dialog-message-padding; + color: @color-font-md; + line-height: @dialog-message-line-height; + font-size: @font-size-md; + } + + &__actions { + display: flex; + justify-content: flex-end; + } + + &__button { + margin-left: @dialog-button-margin-left; + background-color: transparent; + box-shadow: none; + + &:active { + box-shadow: none; + } + } +} diff --git a/packages/varlet-ui/src/dialog/example/index.vue b/packages/varlet-ui/src/dialog/example/index.vue index 5fcce65c88d..d4146c718c4 100644 --- a/packages/varlet-ui/src/dialog/example/index.vue +++ b/packages/varlet-ui/src/dialog/example/index.vue @@ -1,15 +1,56 @@ diff --git a/packages/varlet-ui/src/dialog/index.ts b/packages/varlet-ui/src/dialog/index.ts index a7b8f45aa32..afe36624e8f 100644 --- a/packages/varlet-ui/src/dialog/index.ts +++ b/packages/varlet-ui/src/dialog/index.ts @@ -1,7 +1,63 @@ -import Dialog from './Dialog.vue' +import VarDialog from './Dialog.vue' +import { isString } from '../utils/shared' +import { mountInstance } from '../utils/components' +import { reactive } from 'vue' + +interface DialogOptions { + show?: boolean + title?: string + message?: string + messageAlign?: string + confirmButton?: boolean + cancelButton?: boolean + confirmButtonText?: string + cancelButtonText?: string + confirmButtonColor?: string + cancelButtonColor?: string + confirmButtonBackground?: string + cancelButtonBackground?: string + beforeClose?: (done: () => void) => void + overlay?: boolean + overlayClass?: string + lockScroll?: boolean + closeOnClickOverlay?: boolean +} + +type DialogResolveState = 'confirm' | 'cancel' | 'close' + +function Dialog(options: DialogOptions | string): Promise { + return new Promise((resolve) => { + const dialogOptions: DialogOptions = (isString(options) ? { message: options } : options) + const reactiveDialogOptions: DialogOptions = reactive(dialogOptions) + + const { unmountInstance } = mountInstance( + VarDialog, + reactiveDialogOptions, { + 'onConfirm': () => { + resolve('confirm') + }, + 'onCancel': () => { + resolve('cancel') + }, + 'onClose': () => { + resolve('close') + }, + 'onClosed': () => { + unmountInstance() + }, + 'onUpdate:show': (value: boolean) => { + reactiveDialogOptions.show = value + } + }) + + reactiveDialogOptions.show = true + }) +} Dialog.install = function(app: any) { - app.component(Dialog.name, Dialog) + app.component(VarDialog.name, VarDialog) } +Dialog.Component = VarDialog + export default Dialog diff --git a/packages/varlet-ui/src/dialog/propsEmits.ts b/packages/varlet-ui/src/dialog/propsEmits.ts new file mode 100644 index 00000000000..586007fc9fa --- /dev/null +++ b/packages/varlet-ui/src/dialog/propsEmits.ts @@ -0,0 +1,91 @@ +import { pickProps } from '../utils/components' +import { props as popupProps, emits as popupEmits } from '../popup/propsEmits' + +function messageAlignValidator(messageAlign: string): boolean { + return ['left', 'right'].includes(messageAlign) +} + +export const props = { + // 开关 + show: { + type: Boolean, + default: false + }, + // 标题 + title: { + type: String, + default: '提示' + }, + // 信息 + message: { + type: String + }, + // 信息对齐方式 + messageAlign: { + type: String, + default: 'left', + validator: messageAlignValidator + }, + // 显示确认按钮 + confirmButton: { + type: Boolean, + default: true, + }, + // 显示取消按钮 + cancelButton: { + type: Boolean, + default: true + }, + // 确认按钮文案 + confirmButtonText: { + type: String, + default: '确定', + }, + // 取消按钮文案 + cancelButtonText: { + type: String, + default: '取消' + }, + // 确认按钮文字颜色 + confirmButtonColor: { + type: String, + default: '#005CAF' + }, + // 取消按钮文字颜色 + cancelButtonColor: { + type: String, + default: '#005CAF' + }, + // 确认按钮背景 + confirmButtonBackground: { + type: String + }, + // 确认按钮背景 + cancelButtonBackground: { + type: String + }, + // 关闭前回调函数 + beforeClose: { + type: Function + }, + ...pickProps(popupProps, [ + 'overlay', + 'overlayClass', + 'lockScroll', + 'closeOnClickOverlay', + 'teleport' + ]) +} + +export const emits = { + 'update:show': null, + 'confirm': null, + 'cancel': null, + ...pickProps(popupEmits, [ + 'open', + 'close', + 'opened', + 'closed', + 'click-overlay' + ]) +} diff --git a/packages/varlet-ui/src/loading/propsEmits.ts b/packages/varlet-ui/src/loading/propsEmits.ts index e20eceaa3d5..0f41f86a41b 100644 --- a/packages/varlet-ui/src/loading/propsEmits.ts +++ b/packages/varlet-ui/src/loading/propsEmits.ts @@ -1,29 +1,22 @@ export function typeValidator(type: string): boolean { - const validTypes = ['wave', 'cube', 'rect', 'disappear'] - return validTypes.includes(type) + return ['wave', 'cube', 'rect', 'disappear'].includes(type) } export function sizeValidator(size: string): boolean { - const validSizes = ['normal', 'mini', 'small', 'large'] - - return validSizes.includes(size) + return ['normal', 'mini', 'small', 'large'].includes(size) } -export const getTypeDefault = () => 'wave' - -export const getSizeDefault = () => 'normal' - export const props = { // loading类型 type: { type: String, - default: getTypeDefault, + default: 'wave', validator: typeValidator, }, // loading尺寸 size: { type: String, - default: getSizeDefault, + default: 'normal', validator: sizeValidator, }, // loading颜色 diff --git a/packages/varlet-ui/src/popup/Popup.vue b/packages/varlet-ui/src/popup/Popup.vue index 05d8fd33c15..6ffc80fbf16 100644 --- a/packages/varlet-ui/src/popup/Popup.vue +++ b/packages/varlet-ui/src/popup/Popup.vue @@ -1,23 +1,30 @@ - +