Skip to content

Commit

Permalink
feat(ui/dialog): add component dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
ayangweb committed Mar 1, 2022
1 parent c924549 commit 7bb1e52
Show file tree
Hide file tree
Showing 15 changed files with 1,426 additions and 0 deletions.
167 changes: 167 additions & 0 deletions packages/varlet-vue2-ui/src/dialog/Dialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<template>
<var-popup
class="var-dialog__popup"
var-dialog-cover
:show="popupShow"
:overlay="overlay"
:overlay-class="overlayClass"
:overlay-style="overlayStyle"
:lock-scroll="lockScroll"
:close-on-click-overlay="popupCloseOnClickOverlay"
:teleport="teleport"
@open="onOpen"
@close="onClose"
@closed="onClosed"
@opened="onOpened"
@route-change="onRouteChange"
@click-overlay="handleClickOverlay"
>
<div class="var--box var-dialog" :class="dialogClass" :style="dialogStyle" v-bind="$attrs">
<div class="var-dialog__title">
<slot name="title">{{ dt(title, pack.dialogTitle) }}</slot>
</div>
<div class="var-dialog__message" :style="{ textAlign: messageAlign }">
<slot>
{{ message }}
</slot>
</div>
<div class="var-dialog__actions">
<var-button
class="var-dialog__button var-dialog__cancel-button"
var-dialog-cover
text
:text-color="cancelButtonTextColor"
:color="cancelButtonColor"
v-if="cancelButton"
@click="cancel"
>
{{ dt(cancelButtonText, pack.dialogCancelButtonText) }}
</var-button>
<var-button
class="var-dialog__button var-dialog__confirm-button"
var-dialog-cover
text
:text-color="confirmButtonTextColor"
:color="confirmButtonColor"
v-if="confirmButton"
@click="confirm"
>
{{ dt(confirmButtonText, pack.dialogConfirmButtonText) }}
</var-button>
</div>
</div>
</var-popup>
</template>

<script>
import VarPopup from '../popup'
import VarButton from '../button'
import { props } from './props'
import { defineComponent } from '../utils/create'
import { dt } from '../utils/shared'
import { pack } from '../locale'
export default defineComponent({
name: 'VarDialog',
components: {
VarPopup,
VarButton,
},
inheritAttrs: false,
props,
data: () => ({
popupShow: false,
popupCloseOnClickOverlay: false,
}),
computed: {
pack() {
return pack.value
},
},
watch: {
show: {
handler(newValue) {
this.popupShow = newValue
},
immediate: true,
},
closeOnClickOverlay: {
handler(newValue) {
if (this.getListeners().onBeforeClose != null) {
this.popupCloseOnClickOverlay = false
return
}
this.popupCloseOnClickOverlay = newValue
},
immediate: true,
},
},
methods: {
dt,
done() {
this.getListeners()['onUpdate:show']?.(false)
},
handleClickOverlay() {
const { closeOnClickOverlay, getListeners } = this
const [onClickOverlay, onBeforeClose] = getListeners()
onClickOverlay?.()
if (!closeOnClickOverlay) {
return
}
if (onBeforeClose != null) {
onBeforeClose('close', this.done)
return
}
getListeners()['onUpdate:show']?.(false)
},
confirm() {
const { onBeforeClose, onConfirm } = this.getListeners()
onConfirm?.()
if (onBeforeClose != null) {
onBeforeClose('confirm', this.done)
return
}
this.getListeners()['onUpdate:show']?.(false)
},
cancel() {
const { onBeforeClose, onCancel } = this.getListeners()
onCancel?.()
if (onBeforeClose != null) {
onBeforeClose('cancel', this.done)
return
}
this.getListeners()['onUpdate:show']?.(false)
},
},
})
</script>
<style lang="less">
@import '../styles/common';
@import '../popup/popup';
@import '../button/button';
@import './dialog';
</style>
67 changes: 67 additions & 0 deletions packages/varlet-vue2-ui/src/dialog/__tests__/component.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import Dialog from '..'
import VarDialog from '../Dialog'
import { mount } from '@vue/test-utils'
import Vue from 'vue'

test('test dialog component plugin', () => {
Vue.use(Dialog.Component)
expect(Vue.component(Dialog.Component.name)).toBeTruthy()
})

const Wrapper = {
components: {
[VarDialog.name]: VarDialog,
},
props: ['closeOnClickOverlay', 'onBeforeClose', 'onClickOverlay'],
data: () => ({
show: false,
}),
template: `
<var-dialog v-model:show="show" v-bind="$props" />
`,
}

test('test dialog component click overlay', async () => {
const onClickOverlay = jest.fn()

const wrapper = mount(Wrapper, {
propsData: {
onClickOverlay,
closeOnClickOverlay: false,
},
})
await wrapper.setData({ show: true })

await wrapper.find('.var-popup__overlay').trigger('click')
expect(onClickOverlay).toHaveBeenCalledTimes(1)
expect(wrapper.vm.show).toBe(true)

await wrapper.setProps({ closeOnClickOverlay: true })
await wrapper.find('.var-popup__overlay').trigger('click')
expect(onClickOverlay).toHaveBeenCalledTimes(2)
expect(wrapper.vm.show).toBe(false)

wrapper.destroy()
})

test('test dialog component onBeforeClose', async () => {
const onBeforeClose = jest.fn()

const wrapper = mount(Wrapper, {
listeners: {
beforeClose: onBeforeClose,
},
})
await wrapper.setData({ show: true })

await wrapper.find('.var-popup__overlay').trigger('click')
expect(onBeforeClose).toHaveBeenCalledTimes(1)

await wrapper.find('.var-dialog__cancel-button').trigger('click')
expect(onBeforeClose).toHaveBeenCalledTimes(2)

await wrapper.find('.var-dialog__confirm-button').trigger('click')
expect(onBeforeClose).toHaveBeenCalledTimes(3)

wrapper.destroy()
})
62 changes: 62 additions & 0 deletions packages/varlet-vue2-ui/src/dialog/__tests__/index.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import Dialog from '../index'
import VarDialog from '../Dialog'
import Vue from 'vue'
import { delay, trigger } from '../../utils/jest'

test('test dialog plugin', () => {
Vue.use(Dialog)
expect(Vue.component(VarDialog.name)).toBeTruthy()
})

test('test dialog functional show & close', async () => {
const onOpen = jest.fn()
const onOpened = jest.fn()
const onClose = jest.fn()
const onClosed = jest.fn()

Dialog({
message: 'test message',
onOpen,
onOpened,
onClose,
onClosed,
})

await delay(16)
expect(onOpen).toHaveBeenCalledTimes(1)
await delay(300)
expect(onOpened).toHaveBeenCalledTimes(1)
expect(document.querySelector('.var-popup').style.display).toBe('')

Dialog.close()

await delay(20)
expect(onClose).toHaveBeenCalledTimes(1)
await delay(300)
expect(onClosed).toHaveBeenCalledTimes(1)
expect(document.querySelector('.var-popup')).toBeFalsy()
})

test('test dialog functional confirm & cancel', async () => {
const onConfirm = jest.fn()
const onCancel = jest.fn()

Dialog({
message: 'test confirm',
onConfirm,
})
await delay(16)
await trigger(document.querySelector('.var-dialog__confirm-button'), 'click')
expect(onConfirm).toHaveBeenCalledTimes(1)
await delay(300)

Dialog({
message: 'test cancel',
onCancel,
})
await delay(16)
await trigger(document.querySelector('.var-dialog__cancel-button'), 'click')
expect(onCancel).toHaveBeenCalledTimes(1)

Dialog.close()
})
77 changes: 77 additions & 0 deletions packages/varlet-vue2-ui/src/dialog/dialog.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
@dialog-width: 280px;
@dialog-border-radius: 3px;
@dialog-title-padding: 20px 20px 0;
@dialog-message-color: #888;
@dialog-message-padding: 12px 20px;
@dialog-message-line-height: 24px;
@dialog-message-font-size: var(--font-size-md);
@dialog-title-font-size: var(--font-size-lg);
@dialog-actions-padding: 0 12px 12px;
@dialog-button-margin-left: 6px;
@dialog-confirm-button-color: var(--color-primary);
@dialog-cancel-button-color: var(--color-primary);
@dialog-background: #fff;

:root {
--dialog-width: @dialog-width;
--dialog-border-radius: @dialog-border-radius;
--dialog-title-padding: @dialog-title-padding;
--dialog-message-color: @dialog-message-color;
--dialog-message-padding: @dialog-message-padding;
--dialog-message-line-height: @dialog-message-line-height;
--dialog-message-font-size: @dialog-message-font-size;
--dialog-title-font-size: @dialog-title-font-size;
--dialog-actions-padding: @dialog-actions-padding;
--dialog-button-margin-left: @dialog-button-margin-left;
--dialog-confirm-button-color: @dialog-confirm-button-color;
--dialog-cancel-button-color: @dialog-cancel-button-color;
--dialog-background: @dialog-background;
}

.var-dialog {
width: var(--dialog-width);
border-radius: var(--dialog-border-radius);
background: var(--dialog-background);
transition: 0.25s background-color;

&__popup[var-dialog-cover] {
background: transparent;
}

&__title {
font-size: var(--dialog-title-font-size);
font-weight: 400;
padding: var(--dialog-title-padding);
}

&__message {
padding: var(--dialog-message-padding);
color: var(--dialog-message-color);
line-height: var(--dialog-message-line-height);
font-size: var(--dialog-message-font-size);
}

&__actions {
display: flex;
justify-content: flex-end;
padding: var(--dialog-actions-padding);
}

&__button[var-dialog-cover] {
margin-left: var(--dialog-button-margin-left);
background-color: transparent;
box-shadow: none;

&:active {
box-shadow: none;
}
}

&__confirm-button[var-dialog-cover] {
color: var(--dialog-confirm-button-color);
}

&__cancel-button[var-dialog-cover] {
color: var(--dialog-cancel-button-color);
}
}
Loading

0 comments on commit 7bb1e52

Please sign in to comment.