From e0294dd8a5e3983406b8e7eff6373be669c213ef Mon Sep 17 00:00:00 2001 From: Mike Date: Mon, 29 Jul 2024 13:38:14 +0200 Subject: [PATCH] Feat: Add option to show modal not fullscreen on mobile (#2535) --- .../frontend-2/components/settings/Dialog.vue | 2 +- .../src/components/layout/Dialog.vue | 142 ++++++++++++------ 2 files changed, 98 insertions(+), 46 deletions(-) diff --git a/packages/frontend-2/components/settings/Dialog.vue b/packages/frontend-2/components/settings/Dialog.vue index 6b25d91cb..01eb05aad 100644 --- a/packages/frontend-2/components/settings/Dialog.vue +++ b/packages/frontend-2/components/settings/Dialog.vue @@ -4,7 +4,7 @@ v-bind=" isMobile ? { title: selectedMenuItem ? selectedMenuItem.title : 'Settings' } : {} " - fullscreen + fullscreen="all" :show-back-button="isMobile && !!selectedMenuItem" @back="targetMenuItem = null" > diff --git a/packages/ui-components/src/components/layout/Dialog.vue b/packages/ui-components/src/components/layout/Dialog.vue index a74c989ed..ee9ad6903 100644 --- a/packages/ui-components/src/components/layout/Dialog.vue +++ b/packages/ui-components/src/components/layout/Dialog.vue @@ -16,24 +16,34 @@
@@ -73,16 +83,7 @@ > -
+
Put your content here!
() -const props = defineProps<{ - open: boolean - maxWidth?: MaxWidthValue - fullscreen?: boolean - hideCloser?: boolean - showBackButton?: boolean - /** - * Prevent modal from closing when the user clicks outside of the modal or presses Esc - */ - preventCloseOnClickOutside?: boolean - title?: string - buttons?: Array - /** - * Extra classes to apply to the button container. - */ - buttonsWrapperClasses?: string - /** - * If set, the modal will be wrapped in a form element and the `onSubmit` callback will be invoked when the user submits the form - */ - onSubmit?: (e: SubmitEvent) => void -}>() +const props = withDefaults( + defineProps<{ + open: boolean + maxWidth?: MaxWidthValue + fullscreen?: FullscreenValues + hideCloser?: boolean + showBackButton?: boolean + /** + * Prevent modal from closing when the user clicks outside of the modal or presses Esc + */ + preventCloseOnClickOutside?: boolean + title?: string + buttons?: Array + /** + * Extra classes to apply to the button container. + */ + buttonsWrapperClasses?: string + /** + * If set, the modal will be wrapped in a form element and the `onSubmit` callback will be invoked when the user submits the form + */ + onSubmit?: (e: SubmitEvent) => void + }>(), + { + fullscreen: 'mobile' + } +) const slots = useSlots() @@ -197,7 +204,7 @@ const maxWidthWeight = computed(() => { const widthClasses = computed(() => { const classParts: string[] = ['w-full', 'sm:w-full'] - if (!props.fullscreen) { + if (!isFullscreenDesktop.value) { classParts.push('md:max-w-2xl') if (maxWidthWeight.value >= 2) { @@ -214,6 +221,56 @@ const widthClasses = computed(() => { return classParts.join(' ') }) +const isFullscreenDesktop = computed( + () => props.fullscreen === 'desktop' || props.fullscreen === 'all' +) + +const dialogPanelClasses = computed(() => { + const classParts: string[] = [ + 'transform md:rounded-xl text-foreground overflow-hidden transition-all bg-foundation text-left shadow-xl flex flex-col md:h-auto' + ] + + if (isFullscreenDesktop.value) { + classParts.push('md:h-full md:h-[98vh] md:!h-[98dvh]') + } else { + classParts.push('md:max-h-[90vh]') + } + + if (props.fullscreen === 'mobile') { + classParts.push('max-md:h-[98vh] max-md:!h-[98dvh]') + } + + if (props.fullscreen === 'all') { + classParts.push('h-[98vh] !h-[98dvh]') + } + + if (props.fullscreen === 'none' || props.fullscreen === 'desktop') { + classParts.push('rounded-lg max-h-[90vh]') + } else { + classParts.push('rounded-t-lg') + } + + classParts.push(widthClasses.value) + return classParts.join(' ') +}) + +const slotContainerClasses = computed(() => { + const classParts: string[] = [ + 'flex-1 simple-scrollbar overflow-y-auto text-sm sm:text-base' + ] + + if (hasTitle.value) { + classParts.push('px-6 pb-4') + if (isFullscreenDesktop.value) { + classParts.push('md:p-0') + } + } else if (!isFullscreenDesktop.value) { + classParts.push('p-6') + } + + return classParts.join(' ') +}) + const onClose = () => { if (props.preventCloseOnClickOutside) return open.value = false @@ -260,9 +317,4 @@ html.dialog-open { html.dialog-open body { overflow: hidden !important; } -/* Workaround because in Tailwind vh gets added after dvh */ -.dialog-panel { - height: 98vh; - height: 98dvh; -}