Updates to Dialog - UI Components (#1809)
* Updates to Dialog after conversations with Agi * Fix z-indexing * Add throttle to onScroll
This commit is contained in:
committed by
GitHub
parent
11bcb8d4a2
commit
76cef613cd
@@ -32,11 +32,11 @@ export const Default: StoryObj = {
|
||||
<FormButton @click="() => open = true">Trigger dialog</FormButton>
|
||||
<LayoutDialog v-model:open="open" v-bind="args">
|
||||
<div class="flex flex-col text-foreground space-y-4">
|
||||
<div class="h4 font-bold">Hello world!</div>
|
||||
<div>Lorem ipsum blah blah blah</div>
|
||||
<div class="flex justify-end">
|
||||
<FormButton @click="() => open = false">Close</FormButton>
|
||||
</div>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris vehicula mauris sed tortor tempor, eget viverra arcu dapibus. Vivamus ac erat sit amet justo pulvinar condimentum. Vivamus volutpat eget justo in elementum. Quisque ut metus sed elit eleifend faucibus eget vel diam. Sed eget accumsan felis. Nullam sollicitudin a felis eget aliquet. Fusce vitae erat rutrum, convallis ipsum in, efficitur lectus. Mauris sed augue at lacus malesuada mattis. Mauris tincidunt augue nec magna mollis efficitur. Etiam suscipit pellentesque lorem, quis placerat mi tristique et. Donec at scelerisque dolor. Proin nec libero vitae ligula tincidunt interdum eget et odio.</p>
|
||||
<p>Phasellus at felis quis quam facilisis ullamcorper a et risus. Cras orci velit, tempor quis congue non, elementum sed lacus. Vestibulum quis iaculis purus, in pharetra massa. Donec sed bibendum magna. Aliquam vulputate augue enim, eu tempor massa elementum sit amet. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Maecenas sit amet dictum ipsum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent ac augue maximus, interdum diam ac, iaculis massa. Maecenas consequat libero non turpis varius, sit amet consectetur elit imperdiet. Maecenas euismod justo sit amet varius porta.</p>
|
||||
<p>Maecenas ultricies sollicitudin viverra. Maecenas nec lobortis ante. Cras ut semper metus, eu sodales nibh. Integer a turpis non tellus congue elementum. Etiam ornare augue eu dolor elementum, non semper eros eleifend. Sed ut faucibus risus. Donec at faucibus arcu. Mauris id sapien vel velit mollis gravida. Vivamus et arcu in urna pellentesque euismod. Suspendisse non sagittis sapien, quis semper nulla. Aliquam maximus sit amet ipsum ac ultricies. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus eget interdum orci, a finibus magna.</p>
|
||||
<p>Sed tortor metus, auctor mattis lacinia quis, euismod vel leo. In hac habitasse platea dictumst. Sed egestas dui sapien, et volutpat arcu cursus ac. Quisque ut massa eu magna sodales laoreet vel quis massa. Nullam tortor ipsum, vulputate id tempor vel, accumsan at arcu. Fusce porttitor sed augue in fermentum. Integer imperdiet finibus sagittis. Curabitur pulvinar nunc id interdum euismod. Aliquam sodales faucibus vulputate.</p>
|
||||
<p>Maecenas convallis, magna quis egestas sodales, magna quam suscipit tortor, eget commodo erat diam lobortis mauris. Cras molestie erat ac pharetra faucibus. Nulla rutrum mauris a arcu pulvinar maximus. Donec malesuada, mi sed pretium dignissim, arcu dui feugiat ex, non vehicula nulla elit a nulla. Vivamus venenatis ligula urna, quis varius magna euismod vel. Nullam aliquam nibh nec urna ultrices gravida. Suspendisse potenti. Phasellus pulvinar massa porta orci condimentum vulputate. Integer nulla elit, gravida ac nisi eu, lacinia placerat nisl. Curabitur dui lacus, rutrum sed ex vitae, aliquet maximus sem. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</p>
|
||||
</div>
|
||||
</LayoutDialog>
|
||||
</div>`
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
leave-to="opacity-0"
|
||||
>
|
||||
<div
|
||||
class="fixed inset-0 bg-neutral-100/70 dark:bg-neutral-900/70 transition-opacity"
|
||||
class="fixed inset-0 bg-neutral-100/70 dark:bg-neutral-900/70 transition-opacity backdrop-blur-xs"
|
||||
/>
|
||||
</TransitionChild>
|
||||
|
||||
<div class="fixed inset-0 z-10 overflow-y-auto">
|
||||
<div class="flex min-h-full justify-center p-4 text-center items-center sm:p-0">
|
||||
<div class="fixed inset-0 z-10 h-screen w-screen">
|
||||
<div class="flex justify-center items-center h-full w-full p-4 sm:p-0">
|
||||
<TransitionChild
|
||||
as="template"
|
||||
enter="ease-out duration-300"
|
||||
@@ -29,7 +29,7 @@
|
||||
>
|
||||
<DialogPanel
|
||||
:class="[
|
||||
'transform rounded-lg bg-foundation text-left shadow-xl transition-all',
|
||||
'transform rounded-lg bg-foundation text-left shadow-xl transition-all flex flex-col max-h-[90vh]',
|
||||
widthClasses
|
||||
]"
|
||||
:as="isForm ? 'form' : 'div'"
|
||||
@@ -37,23 +37,30 @@
|
||||
>
|
||||
<div
|
||||
v-if="title"
|
||||
class="flex items-center justify-center shadow p-4 relative z-10 bg-foundation rounded-t-lg"
|
||||
class="relative z-10 flex items-center justify-start rounded-t-lg shrink-0 h-16 px-8"
|
||||
:class="scrolledFromTop && 'shadow'"
|
||||
>
|
||||
<h4 class="text-2xl font-bold">{{ title }}</h4>
|
||||
</div>
|
||||
<button
|
||||
v-if="!hideCloser"
|
||||
class="absolute z-20 top-5 right-4 text-foreground"
|
||||
class="absolute z-20 right-4 text-foreground bg-foundation rounded-full p-1"
|
||||
:class="title ? 'top-4' : 'top-3'"
|
||||
@click="open = false"
|
||||
>
|
||||
<XMarkIcon class="h-6 w-6" />
|
||||
</button>
|
||||
<div class="p-4 sm:p-6">
|
||||
<div
|
||||
class="flex-1 simple-scrollbar overflow-y-auto bg-white"
|
||||
:class="title ? 'py-6 px-8' : 'p-10'"
|
||||
@scroll="onScroll"
|
||||
>
|
||||
<slot>Put your content here!</slot>
|
||||
</div>
|
||||
<div
|
||||
v-if="hasButtons"
|
||||
class="flex p-4 sm:px-6 sm:py-5 border-t gap-2 border-outline-3"
|
||||
class="flex p-4 sm:px-6 gap-2 shrink-0"
|
||||
:class="!scrolledToBottom && 'shadow-t'"
|
||||
>
|
||||
<template v-if="buttons">
|
||||
<FormButton
|
||||
@@ -80,7 +87,8 @@
|
||||
import { Dialog, DialogPanel, TransitionChild, TransitionRoot } from '@headlessui/vue'
|
||||
import { FormButton } from '~~/src/lib'
|
||||
import { XMarkIcon } from '@heroicons/vue/24/outline'
|
||||
import { computed, useSlots } from 'vue'
|
||||
import { computed, ref, useSlots } from 'vue'
|
||||
import { throttle } from 'lodash'
|
||||
|
||||
type MaxWidthValue = 'sm' | 'md' | 'lg' | 'xl'
|
||||
|
||||
@@ -111,6 +119,9 @@ const props = defineProps<{
|
||||
|
||||
const slots = useSlots()
|
||||
|
||||
const scrolledFromTop = ref(false)
|
||||
const scrolledToBottom = ref(false)
|
||||
|
||||
const isForm = computed(() => !!props.onSubmit)
|
||||
const hasButtons = computed(() => props.buttons || slots.buttons)
|
||||
|
||||
@@ -137,24 +148,20 @@ const maxWidthWeight = computed(() => {
|
||||
const widthClasses = computed(() => {
|
||||
const classParts: string[] = ['w-full', 'sm:my-8 sm:w-full sm:max-w-xl']
|
||||
|
||||
if (!props.title && !hasButtons.value) {
|
||||
classParts.push('px-4 pt-4 pb-4', 'sm:p-6')
|
||||
}
|
||||
|
||||
if (maxWidthWeight.value >= 1) {
|
||||
classParts.push('md:max-w-2xl')
|
||||
classParts.push('max-w-2xl')
|
||||
}
|
||||
|
||||
if (maxWidthWeight.value >= 2) {
|
||||
classParts.push('lg:max-w-4xl')
|
||||
classParts.push('max-w-4xl')
|
||||
}
|
||||
|
||||
if (maxWidthWeight.value >= 3) {
|
||||
classParts.push('xl:max-w-6xl')
|
||||
classParts.push('max-w-6xl')
|
||||
}
|
||||
|
||||
if (maxWidthWeight.value >= 4) {
|
||||
classParts.push('2xl:max-w-7xl')
|
||||
classParts.push('max-w-7xl')
|
||||
}
|
||||
|
||||
return classParts.join(' ')
|
||||
@@ -164,4 +171,11 @@ const onClose = () => {
|
||||
if (props.preventCloseOnClickOutside) return
|
||||
open.value = false
|
||||
}
|
||||
|
||||
const onScroll = throttle((e: Event) => {
|
||||
const target = e.target as HTMLElement
|
||||
const { scrollTop, offsetHeight, scrollHeight } = target
|
||||
scrolledFromTop.value = scrollTop > 0
|
||||
scrolledToBottom.value = scrollTop + offsetHeight >= scrollHeight
|
||||
}, 60)
|
||||
</script>
|
||||
|
||||
@@ -10,5 +10,16 @@ module.exports = {
|
||||
'./src/**/*.{js,ts,jsx,tsx,vue}',
|
||||
tailwindContentEntry(require)
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
// Standard Tailwind Shadows add shadows below the element, 'shadow-t" variant adds shadow to the top of the element.
|
||||
boxShadow: {
|
||||
t: '0 -1px 3px 0 rgb(0 0 0 / 10%), 0 -1px 2px -1px rgb(0 0 0 / 6%)'
|
||||
},
|
||||
backdropBlur: {
|
||||
xs: '1px'
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [speckleTheme.default, formsPlugin]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user