chore(preset): handle Modal / Slideover transitions

This commit is contained in:
Benjamin Canac
2022-10-05 00:24:44 +02:00
parent b20c8c82ab
commit d96b4ea119
3 changed files with 68 additions and 34 deletions

View File

@@ -7,7 +7,7 @@
:appear="appear"
v-bind="overlayTransition"
>
<div class="fixed inset-0 transition-opacity" :class="overlayClass" />
<div class="fixed inset-0 transition-opacity" :class="overlayBackgroundClass" />
</TransitionChild>
<div :class="wrapperClass">
@@ -78,9 +78,13 @@ const props = defineProps({
type: Boolean,
default: true
},
overlayClass: {
overlayBackgroundClass: {
type: String,
default: () => $ui.modal.overlay
default: () => $ui.modal.overlay.background
},
overlayTransitionClass: {
type: Object,
default: () => $ui.modal.overlay.transition
},
shadowClass: {
type: String,
@@ -101,6 +105,10 @@ const props = defineProps({
transition: {
type: Boolean,
default: true
},
transitionClass: {
type: Object,
default: () => $ui.modal.transition
}
})
@@ -131,14 +139,7 @@ const overlayTransition = computed(() => {
return {}
}
return {
enter: 'ease-out duration-300',
enterFrom: 'opacity-0',
enterTo: 'opacity-100',
leave: 'ease-in duration-200',
leaveFrom: 'opacity-100',
leaveTo: 'opacity-0'
}
return props.overlayTransitionClass
})
const modalTransition = computed(() => {
@@ -146,14 +147,7 @@ const modalTransition = computed(() => {
return {}
}
return {
enter: 'ease-out duration-300',
enterFrom: 'opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95',
enterTo: 'opacity-100 translate-y-0 sm:scale-100',
leave: 'ease-in duration-200',
leaveFrom: 'opacity-100 translate-y-0 sm:scale-100',
leaveTo: 'opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95'
}
return props.transitionClass
})
function close (value: boolean) {

View File

@@ -8,25 +8,20 @@
@close="isOpen = false"
>
<TransitionChild
v-if="overlay"
as="template"
enter="transition-opacity ease-linear duration-300"
enter-from="opacity-0"
enter-to="opacity-100"
leave="transition-opacity ease-linear duration-300"
leave-from="opacity-100"
leave-to="opacity-0"
v-bind="overlayTransitionClass"
>
<div class="fixed inset-0 transition-opacity" :class="overlayClass" />
<div class="fixed inset-0 transition-opacity" :class="overlayBackgroundClass" />
</TransitionChild>
<TransitionChild
as="template"
enter="transition ease-in-out duration-300 transform"
:enter-from="side === 'left' ? '-translate-x-full' : 'translate-x-full'"
enter-to="translate-x-0"
leave="transition ease-in-out duration-300 transform"
leave-from="translate-x-0"
:leave-to="side === 'left' ? '-translate-x-full' : 'translate-x-full'"
v-bind="transitionClass"
>
<DialogPanel :class="slideoverClass">
<div v-if="$slots.header" :class="headerClass">
@@ -64,9 +59,17 @@ const props = defineProps({
type: String,
default: () => $ui.slideover.background
},
overlayClass: {
overlay: {
type: Boolean,
default: true
},
overlayBackgroundClass: {
type: String,
default: () => $ui.slideover.overlay
default: () => $ui.slideover.overlay.background
},
overlayTransitionClass: {
type: Object,
default: () => $ui.slideover.overlay.transition
},
widthClass: {
type: String,
@@ -75,8 +78,13 @@ const props = defineProps({
headerClass: {
type: String,
default: () => $ui.slideover.header
},
transitionClass: {
type: Object,
default: () => $ui.slideover.transition
}
})
const emit = defineEmits(['update:modelValue'])
const isOpen: WritableComputedRef<boolean> = computed({

View File

@@ -253,12 +253,30 @@ export default (variantColors: string[]) => {
container: 'flex min-h-full items-end sm:items-center justify-center p-4 sm:p-0 text-center',
base: 'relative inline-block align-bottom text-left overflow-hidden transform transition-all sm:my-8 sm:align-middle w-full',
background: 'u-bg-white',
overlay: 'bg-gray-500/75 dark:bg-gray-600/75',
overlay: {
background: 'bg-gray-500/75 dark:bg-gray-600/75',
transition: {
enter: 'ease-out duration-300',
enterFrom: 'opacity-0',
enterTo: 'opacity-100',
leave: 'ease-in duration-200',
leaveFrom: 'opacity-100',
leaveTo: 'opacity-0'
}
},
border: '',
ring: '',
rounded: 'rounded-lg',
shadow: 'shadow-xl',
width: 'sm:max-w-lg'
width: 'sm:max-w-lg',
transition: {
enter: 'ease-out duration-300',
enterFrom: 'opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95',
enterTo: 'opacity-100 translate-y-0 sm:scale-100',
leave: 'ease-in duration-200',
leaveFrom: 'opacity-100 translate-y-0 sm:scale-100',
leaveTo: 'opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95'
}
}
const container = {
@@ -402,11 +420,25 @@ export default (variantColors: string[]) => {
}
const slideover = {
overlay: 'bg-gray-500/75 dark:bg-gray-600/75',
overlay: {
background: 'bg-gray-500/75 dark:bg-gray-600/75',
transition: {
enter: 'ease-in-out duration-500',
enterFrom: 'opacity-0',
enterTo: 'opacity-100',
leave: 'ease-in-out duration-500',
leaveFrom: 'opacity-100',
leaveTo: 'opacity-0'
}
},
base: 'relative flex-1 flex flex-col w-full focus:outline-none',
background: 'u-bg-white',
width: 'max-w-md',
header: 'flex items-center justify-between flex-shrink-0 px-4 sm:px-6 h-16 border-b u-border-gray-200'
header: 'flex items-center justify-between flex-shrink-0 px-4 sm:px-6 h-16 border-b u-border-gray-200',
transition: {
enter: 'transform transition ease-in-out duration-500 sm:duration-700',
leave: 'transform transition ease-in-out duration-500 sm:duration-700'
}
}
const notification = {