Skip to content

Commit

Permalink
feat: 1. useTemplate support attrs, props, emits with ref, reactive, …
Browse files Browse the repository at this point in the history
…computed object 2. rename options.onUnmounted to options.hideOnUnmounted 3. add more test cases
  • Loading branch information
hunterliu1003 committed Feb 22, 2024
1 parent 70883bf commit e1fa815
Show file tree
Hide file tree
Showing 11 changed files with 367 additions and 68 deletions.
29 changes: 29 additions & 0 deletions cypress/components/DialogConfirmPreview.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<script setup lang="ts">
import { defineAsyncComponent, h } from 'vue'
import { Container, defineTemplate, useTemplate } from '../../src/index'
const { show, hide } = useTemplate({
component: defineAsyncComponent(() => import('./DialogConfirm.vue')),
attrs: {
title: 'Hello World!',
onConfirm: () => hide(),
onCancel: () => hide(),
},
slots: {
default: defineTemplate({
component: () => h('p', 'This is a dialog content.'),
}),
},
})
show()
</script>

<template>
<div>
<button @click="() => show()">
Open Modal
</button>

<Container />
</div>
</template>
22 changes: 22 additions & 0 deletions cypress/components/HideOnUnmounted.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script setup lang="ts">
import { ref } from 'vue'
import { Container } from '../../src/index'
import HideOnUnmountedDialog from './HideOnUnmountedDialog.vue'
defineProps<{
hideOnUnmounted: boolean
}>()
const showOnUnmountedDialog = ref(true)
</script>

<template>
<div>
<HideOnUnmountedDialog v-if="showOnUnmountedDialog" :hide-on-unmounted="hideOnUnmounted" />
<button @click="() => showOnUnmountedDialog = false">
Hide OnUnmountedDialog
</button>

<Container />
</div>
</template>
19 changes: 19 additions & 0 deletions cypress/components/HideOnUnmountedDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script setup lang="ts">
import { h } from 'vue'
import { useTemplate } from '../../src/index'
const props = defineProps<{
hideOnUnmounted: boolean
}>()
const text = 'Hello World!'
const { show } = useTemplate({ component: () => h('div', text) }, {
hideOnUnmounted: props.hideOnUnmounted,
})
</script>

<template>
<button @click="() => show()">
Open Modal
</button>
</template>
184 changes: 182 additions & 2 deletions cypress/components/index.cy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { defineAsyncComponent, h } from 'vue'
import { defineAsyncComponent, h, reactive, ref } from 'vue'
import { Container, createTemplatePlugin, defineTemplate, useTemplate } from '../../src/index'
import DialogConfirmPreview from './DialogConfirmPreview.vue'
import HideOnUnmounted from './HideOnUnmounted.vue'

describe('test useTemplate()', () => {
it('hello world - createTemplatePlugin', () => {
Expand All @@ -16,7 +18,7 @@ describe('test useTemplate()', () => {
cy.contains(text).should('not.exist')
})

it('DialogConfirm', () => {
it('DialogConfirm - given static attrs', () => {
const templatePlugin = createTemplatePlugin()
cy.mount(Container as any, { global: { plugins: [templatePlugin] } }).as('container')

Expand Down Expand Up @@ -63,4 +65,182 @@ describe('test useTemplate()', () => {
})
cy.get('@onCancel').should('have.callCount', 1)
})

it('DialogConfirm - given ref props', () => {
const templatePlugin = createTemplatePlugin()
cy.mount(Container as any, { global: { plugins: [templatePlugin] } }).as('container')

const props = ref({ title: 'Hello World!' })
const content = 'This is a dialog content.'
const onConfirm = cy.spy().as('onConfirm')
const onCancel = cy.spy().as('onCancel')

const { show, hide } = useTemplate({
component: defineAsyncComponent(() => import('./DialogConfirm.vue')),
props,
emits: {
onConfirm: () => {
onConfirm()
hide()
},
onCancel: () => {
onCancel()
hide()
},
},
slots: {
default: defineTemplate({ component: () => h('p', content) }),
},
})

/** Confirm */
cy.get('@container').then(() => show())
cy.get('dialog').should('exist')
cy.contains(props.value.title)
cy.contains('p', content)
cy.get('@container').then(() => {
props.value.title = 'Title Changed!'
})
cy.get('@container').then(() => {
cy.contains('Title Changed!')
})

cy.contains('button', 'Confirm').click()
cy.get('@container').then(() => {
cy.get('dialog').should('not.exist')
})
cy.get('@onConfirm').should('have.callCount', 1)

/** Cancel */
cy.get('@container').then(() => show())
cy.get('dialog').should('exist')
cy.contains('button', 'Cancel').click()
cy.get('@container').then(() => {
cy.get('dialog').should('not.exist')
})
cy.get('@onCancel').should('have.callCount', 1)
})

it('DialogConfirm - given reactive props', () => {
const templatePlugin = createTemplatePlugin()
cy.mount(Container as any, { global: { plugins: [templatePlugin] } }).as('container')

const props = reactive({ title: 'Hello World!' })
const content = 'This is a dialog content.'
const onConfirm = cy.spy().as('onConfirm')
const onCancel = cy.spy().as('onCancel')

const { show, hide } = useTemplate({
component: defineAsyncComponent(() => import('./DialogConfirm.vue')),
props,
emits: {
onConfirm: () => {
onConfirm()
hide()
},
onCancel: () => {
onCancel()
hide()
},
},
slots: {
default: defineTemplate({ component: () => h('p', content) }),
},
})

/** Confirm */
cy.get('@container').then(() => show())
cy.get('dialog').should('exist')
cy.contains(props.title)
cy.contains('p', content)
cy.get('@container').then(() => {
props.title = 'Title Changed!'
})
cy.get('@container').then(() => {
cy.contains('Title Changed!')
})

cy.contains('button', 'Confirm').click()
cy.get('@container').then(() => {
cy.get('dialog').should('not.exist')
})
cy.get('@onConfirm').should('have.callCount', 1)

/** Cancel */
cy.get('@container').then(() => show())
cy.get('dialog').should('exist')
cy.contains('button', 'Cancel').click()
cy.get('@container').then(() => {
cy.get('dialog').should('not.exist')
})
cy.get('@onCancel').should('have.callCount', 1)
})

it('DialogConfirmPreview', () => {
const templatePlugin = createTemplatePlugin()
cy.mount(DialogConfirmPreview, { global: { plugins: [templatePlugin] } }).as('container')

cy.get('dialog').should('exist')
cy.contains('button', 'Cancel').click()
cy.get('@container').then(() => {
cy.get('dialog').should('not.exist')
})
cy.contains('button', 'Open Modal').click()
cy.get('@container').then(() => {
cy.get('dialog').should('exist')
})
cy.contains('button', 'Cancel').click()
cy.get('@container').then(() => {
cy.get('dialog').should('not.exist')
})
cy.contains('button', 'Open Modal').click()
cy.get('@container').then(() => {
cy.get('dialog').should('exist')
})
})
})

describe('test useTemplate() options', () => {
it('hideOnUnmounted: false', () => {
const templatePlugin = createTemplatePlugin()
cy.mount(HideOnUnmounted, {
global: { plugins: [templatePlugin] },
props: {
hideOnUnmounted: false,
},
}).as('container')

cy.contains('Hello World!').should('not.exist')

cy.contains('button', 'Open Modal').click()
cy.get('@container').then(() => {
cy.contains('Hello World!').should('exist')
})

cy.contains('button', 'Hide OnUnmountedDialog').click()
cy.get('@container').then(() => {
cy.contains('Hello World!').should('exist')
})
})
it('hideOnUnmounted: true', () => {
const templatePlugin = createTemplatePlugin()
cy.mount(HideOnUnmounted, {
global: { plugins: [templatePlugin] },
props: {
hideOnUnmounted: true,
},
}).as('container')

cy.contains('Hello World!').should('not.exist')

cy.contains('button', 'Open Modal').click()
cy.get('@container').then(() => {
cy.contains('Hello World!').should('exist')
})

cy.contains('button', 'Hide OnUnmountedDialog').click()
cy.get('@container').then(() => {
cy.contains('Hello World!').should('not.exist')
})
})
})
33 changes: 19 additions & 14 deletions examples/nuxt3/components/DialogConfirm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,26 @@ const emit = defineEmits<{
(e: 'confirm'): void
(e: 'cancel'): void
}>()
const text = ref('')
</script>

<template>
<dialog open class="fixed inset-0 rounded-md p-4 space-y-4">
<h1 class="font-bold text-xl">
{{ title }}
</h1>
<slot />
<div class="space-x-2">
<button class="px-2 border rounded" @click="emit('confirm')">
Confirm
</button>
<button class="px-2 border rounded" @click="emit('cancel')">
Cancel
</button>
</div>
</dialog>
<Teleport to="body">
<dialog open class="fixed inset-0 rounded-md p-4 space-y-4">
<h1 class="font-bold text-xl">
{{ title }}
</h1>
<input v-model="text" type="text">
<slot />
<div class="space-x-2">
<button class="px-2 border rounded" @click="emit('confirm')">
Confirm
</button>
<button class="px-2 border rounded" @click="emit('cancel')">
Cancel
</button>
</div>
</dialog>
</Teleport>
</template>
17 changes: 10 additions & 7 deletions examples/nuxt3/components/DialogConfirmPreview.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
<script setup lang="ts">
import { defineAsyncComponent, h } from 'vue'
import { defineAsyncComponent, h, reactive } from 'vue'
import { defineTemplate, useTemplate } from 'vue-use-template'
const props = reactive({
title: 'Hello World!',
})
const { show, hide } = useTemplate({
component: defineAsyncComponent(() => import('./DialogConfirm.vue')),
attrs: {
title: 'Hello World!',
props,
emits: {
onConfirm: () => {
hide()
},
onCancel: () => {
hide()
props.title = 'Confirmed!'
setTimeout(() => hide(), 1000)
},
onCancel: () => hide(),
},
slots: {
default: defineTemplate({
Expand Down
33 changes: 19 additions & 14 deletions examples/vue3/src/components/DialogConfirm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,26 @@ const emit = defineEmits<{
(e: 'confirm'): void
(e: 'cancel'): void
}>()
const text = ref('')
</script>

<template>
<dialog open class="fixed inset-0 rounded-md p-4 space-y-4">
<h1 class="font-bold text-xl">
{{ title }}
</h1>
<slot />
<div class="space-x-2">
<button class="px-2 border rounded" @click="emit('confirm')">
Confirm
</button>
<button class="px-2 border rounded" @click="emit('cancel')">
Cancel
</button>
</div>
</dialog>
<Teleport to="body">
<dialog open class="fixed inset-0 rounded-md p-4 space-y-4">
<h1 class="font-bold text-xl">
{{ title }}
</h1>
<input v-model="text" type="text">
<slot />
<div class="space-x-2">
<button class="px-2 border rounded" @click="emit('confirm')">
Confirm
</button>
<button class="px-2 border rounded" @click="emit('cancel')">
Cancel
</button>
</div>
</dialog>
</Teleport>
</template>

0 comments on commit e1fa815

Please sign in to comment.