-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ui/dialog): add component dialog
- Loading branch information
Showing
15 changed files
with
1,426 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
67
packages/varlet-vue2-ui/src/dialog/__tests__/component.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
62
packages/varlet-vue2-ui/src/dialog/__tests__/index.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
Oops, something went wrong.