kopia lustrzana https://github.com/elk-zone/elk
				
				
				
			feat: improve dialog
							rodzic
							
								
									cd4658506d
								
							
						
					
					
						commit
						4703b6884a
					
				| 
						 | 
				
			
			@ -6,6 +6,10 @@ interface Team {
 | 
			
		|||
  mastodon: string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const emit = defineEmits<{
 | 
			
		||||
  (event: 'close'): void
 | 
			
		||||
}>()
 | 
			
		||||
 | 
			
		||||
const teams: Team[] = [
 | 
			
		||||
  {
 | 
			
		||||
    github: 'antfu',
 | 
			
		||||
| 
						 | 
				
			
			@ -35,7 +39,11 @@ const teams: Team[] = [
 | 
			
		|||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <div p8 flex="~ col gap-4">
 | 
			
		||||
  <div p8 flex="~ col gap-4" relative max-h-screen of-auto>
 | 
			
		||||
    <button btn-action-icon absolute top-0 right-0 m1 @click="emit('close')">
 | 
			
		||||
      <div i-ri:close-fill />
 | 
			
		||||
    </button>
 | 
			
		||||
 | 
			
		||||
    <img src="/logo.svg" w-20 h-20 mxa alt="logo">
 | 
			
		||||
    <h1 mxa text-4xl mb4>
 | 
			
		||||
      Elk is in Preview!
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +61,7 @@ const teams: Team[] = [
 | 
			
		|||
    </p>
 | 
			
		||||
    <p flex="~ gap-2 wrap" mxa>
 | 
			
		||||
      <template v-for="team of teams" :key="team.github">
 | 
			
		||||
        <a :href="`https://github.com/sponsors/${team.github}`" target="_blank">
 | 
			
		||||
        <a :href="`https://github.com/sponsors/${team.github}`" target="_blank" rounded-full>
 | 
			
		||||
          <img :src="`https://github.com/${team.github}.png`" :alt="team.display" rounded-full w-15 h-15>
 | 
			
		||||
        </a>
 | 
			
		||||
      </template>
 | 
			
		||||
| 
						 | 
				
			
			@ -61,5 +69,9 @@ const teams: Team[] = [
 | 
			
		|||
    <p italic text-2xl>
 | 
			
		||||
      <span text-lg font-script>The Elk Team</span>
 | 
			
		||||
    </p>
 | 
			
		||||
 | 
			
		||||
    <button btn-solid mxa @click="emit('close')">
 | 
			
		||||
      Enter App
 | 
			
		||||
    </button>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,8 +16,8 @@ import {
 | 
			
		|||
  <ModalDialog v-model="isSigninDialogOpen">
 | 
			
		||||
    <UserSignIn m6 />
 | 
			
		||||
  </ModalDialog>
 | 
			
		||||
  <ModalDialog v-model="isPreviewHelpOpen">
 | 
			
		||||
    <HelpPreview />
 | 
			
		||||
  <ModalDialog v-model="isPreviewHelpOpen" :type="isSmallScreen ? 'bottom' : 'dialog'">
 | 
			
		||||
    <HelpPreview @close="closePreviewHelp()" />
 | 
			
		||||
  </ModalDialog>
 | 
			
		||||
  <ModalDialog v-model="isPublishDialogOpen">
 | 
			
		||||
    <PublishWidget draft-key="dialog" expanded min-w-180 />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,8 +11,12 @@ const {
 | 
			
		|||
 | 
			
		||||
const { modelValue } = defineModel<{
 | 
			
		||||
  modelValue: boolean
 | 
			
		||||
  closeButton?: boolean
 | 
			
		||||
}>()
 | 
			
		||||
 | 
			
		||||
let isVisible = $ref(modelValue.value)
 | 
			
		||||
let isOut = $ref(!modelValue.value)
 | 
			
		||||
 | 
			
		||||
const positionClass = computed(() => {
 | 
			
		||||
  switch (type) {
 | 
			
		||||
    case 'dialog':
 | 
			
		||||
| 
						 | 
				
			
			@ -30,24 +34,32 @@ const positionClass = computed(() => {
 | 
			
		|||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
const transform = computed(() => {
 | 
			
		||||
  switch (type) {
 | 
			
		||||
    case 'bottom':
 | 
			
		||||
      return 'translateY(100%)'
 | 
			
		||||
    case 'top':
 | 
			
		||||
      return 'translateY(-100%)'
 | 
			
		||||
    case 'left':
 | 
			
		||||
      return 'translateX(-100%)'
 | 
			
		||||
    case 'right':
 | 
			
		||||
      return 'translateX(100%)'
 | 
			
		||||
    default:
 | 
			
		||||
      return ''
 | 
			
		||||
const transformClass = computed(() => {
 | 
			
		||||
  if (isOut) {
 | 
			
		||||
    switch (type) {
 | 
			
		||||
      case 'dialog':
 | 
			
		||||
        return 'op0'
 | 
			
		||||
      case 'bottom':
 | 
			
		||||
        return 'translate-y-[100%]'
 | 
			
		||||
      case 'top':
 | 
			
		||||
        return 'translate-y-[100%]'
 | 
			
		||||
      case 'left':
 | 
			
		||||
        return 'translate-x-[-100%]'
 | 
			
		||||
      case 'right':
 | 
			
		||||
        return 'translate-x-[100%]'
 | 
			
		||||
      default:
 | 
			
		||||
        return ''
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
const target = ref<HTMLElement | null>(null)
 | 
			
		||||
const { activate, deactivate } = useFocusTrap(target)
 | 
			
		||||
 | 
			
		||||
function close() {
 | 
			
		||||
  modelValue.value = false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
watchEffect(() => {
 | 
			
		||||
  if (modelValue)
 | 
			
		||||
    activate()
 | 
			
		||||
| 
						 | 
				
			
			@ -55,29 +67,52 @@ watchEffect(() => {
 | 
			
		|||
    deactivate()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
let init = $ref(modelValue)
 | 
			
		||||
watchOnce(modelValue, () => {
 | 
			
		||||
  init = true
 | 
			
		||||
useEventListener('keydown', (e: KeyboardEvent) => {
 | 
			
		||||
  if (!modelValue.value)
 | 
			
		||||
    return
 | 
			
		||||
  if (e.key === 'Escape') {
 | 
			
		||||
    close()
 | 
			
		||||
    e.preventDefault()
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
watch(modelValue, async (v) => {
 | 
			
		||||
  if (v) {
 | 
			
		||||
    isOut = true
 | 
			
		||||
    isVisible = true
 | 
			
		||||
    setTimeout(() => {
 | 
			
		||||
      isOut = false
 | 
			
		||||
    }, 10)
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    isOut = true
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
function onTransitionEnd() {
 | 
			
		||||
  if (!modelValue.value)
 | 
			
		||||
    isVisible = false
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <div
 | 
			
		||||
    v-if="isVisible"
 | 
			
		||||
    fixed top-0 bottom-0 left-0 right-0 z-40
 | 
			
		||||
    :class="modelValue ? '' : 'pointer-events-none'"
 | 
			
		||||
  >
 | 
			
		||||
    <div
 | 
			
		||||
      bg-base bottom-0 left-0 right-0 top-0 absolute transition-opacity duration-500 ease-out
 | 
			
		||||
      :class="modelValue ? 'opacity-85' : 'opacity-0'"
 | 
			
		||||
      @click="modelValue = false"
 | 
			
		||||
      :class="isOut ? 'opacity-0' : 'opacity-85'"
 | 
			
		||||
      @click="close"
 | 
			
		||||
    />
 | 
			
		||||
    <div
 | 
			
		||||
      ref="target" bg-base border-base absolute transition-all duration-200
 | 
			
		||||
      ease-out
 | 
			
		||||
      :class="positionClass"
 | 
			
		||||
      :style="modelValue ? {} : { transform }"
 | 
			
		||||
      ref="target"
 | 
			
		||||
      bg-base border-base absolute transition-all duration-200 ease-out transform
 | 
			
		||||
      :class="`${positionClass} ${transformClass}`"
 | 
			
		||||
      @transitionend="onTransitionEnd"
 | 
			
		||||
    >
 | 
			
		||||
      <slot v-if="init" />
 | 
			
		||||
      <slot />
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,7 @@
 | 
			
		|||
</script>
 | 
			
		||||
 | 
			
		||||
<template>
 | 
			
		||||
  <nav h-14 fixed bottom-0 left-0 right-0 z-50 border="t base" bg-base flex flex-row>
 | 
			
		||||
  <nav h-14 fixed bottom-0 left-0 right-0 z-10 border="t base" bg-base flex flex-row>
 | 
			
		||||
    <template v-if="currentUser">
 | 
			
		||||
      <NuxtLink to="/home" active-class="text-primary" flex flex-row items-center place-content-center h-full flex-1>
 | 
			
		||||
        <div i-ri:home-5-line />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
<template>
 | 
			
		||||
  <div px3 py4 flex="~ col gap2" text-lg>
 | 
			
		||||
  <nav px3 py4 flex="~ col gap2" text-lg>
 | 
			
		||||
    <template v-if="currentUser">
 | 
			
		||||
      <NavSideItem text="Home" to="/home" icon="i-ri:home-5-line" />
 | 
			
		||||
      <NavSideItem text="Notifications" to="/notifications" icon="i-ri:notification-4-line" />
 | 
			
		||||
| 
						 | 
				
			
			@ -17,5 +17,5 @@
 | 
			
		|||
        </template>
 | 
			
		||||
      </NavSideItem>
 | 
			
		||||
    </template>
 | 
			
		||||
  </div>
 | 
			
		||||
  </nav>
 | 
			
		||||
</template>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,3 +49,7 @@ export function openEditHistoryDialog(edit: StatusEdit) {
 | 
			
		|||
export function openPreviewHelp() {
 | 
			
		||||
  isPreviewHelpOpen.value = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function closePreviewHelp() {
 | 
			
		||||
  isPreviewHelpOpen.value = false
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
import { breakpointsTailwind } from '@vueuse/core'
 | 
			
		||||
 | 
			
		||||
export const breakpoints = useBreakpoints(breakpointsTailwind)
 | 
			
		||||
 | 
			
		||||
export const isSmallScreen = breakpoints.smallerOrEqual('md')
 | 
			
		||||
| 
						 | 
				
			
			@ -13,7 +13,7 @@
 | 
			
		|||
          </slot>
 | 
			
		||||
        </div>
 | 
			
		||||
      </aside>
 | 
			
		||||
      <NavBottom md:hidden />
 | 
			
		||||
      <NavBottom v-if="isSmallScreen" md:hidden />
 | 
			
		||||
      <div class="w-full mb14 md:(w-2/4 mb0) min-h-screen" border="l r base">
 | 
			
		||||
        <slot />
 | 
			
		||||
      </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue