diff --git a/packages/ui-transitions/playground/src/pages/index.vue b/packages/ui-transitions/playground/src/pages/index.vue index 174f7cc55..70b231963 100644 --- a/packages/ui-transitions/playground/src/pages/index.vue +++ b/packages/ui-transitions/playground/src/pages/index.vue @@ -5,7 +5,9 @@ import Buttons from '../components/Buttons.vue' definePage({ meta: { - stageTransition: 'slide', + stageTransition: { + name: 'slide', + }, }, }) diff --git a/packages/ui-transitions/playground/src/pages/transition-2.vue b/packages/ui-transitions/playground/src/pages/transition-2.vue index 330391fa5..0085013e2 100644 --- a/packages/ui-transitions/playground/src/pages/transition-2.vue +++ b/packages/ui-transitions/playground/src/pages/transition-2.vue @@ -5,7 +5,9 @@ import Buttons from '../components/Buttons.vue' definePage({ meta: { - stageTransition: 'slope-slide', + stageTransition: { + name: 'slope-slide', + }, }, }) diff --git a/packages/ui-transitions/playground/src/pages/transition-3.vue b/packages/ui-transitions/playground/src/pages/transition-3.vue index 7aede3b8f..9c72c597e 100644 --- a/packages/ui-transitions/playground/src/pages/transition-3.vue +++ b/packages/ui-transitions/playground/src/pages/transition-3.vue @@ -5,7 +5,9 @@ import Buttons from '../components/Buttons.vue' definePage({ meta: { - stageTransition: 'arrow', + stageTransition: { + name: 'arrow', + }, }, }) diff --git a/packages/ui-transitions/playground/src/pages/transition-4.vue b/packages/ui-transitions/playground/src/pages/transition-4.vue index c45fd0c30..95e84b2c3 100644 --- a/packages/ui-transitions/playground/src/pages/transition-4.vue +++ b/packages/ui-transitions/playground/src/pages/transition-4.vue @@ -5,7 +5,9 @@ import Buttons from '../components/Buttons.vue' definePage({ meta: { - stageTransition: 'multiple-blocks-reveal', + stageTransition: { + name: 'multiple-blocks-reveal', + }, }, }) diff --git a/packages/ui-transitions/playground/src/pages/transition-5.vue b/packages/ui-transitions/playground/src/pages/transition-5.vue index b72b0fba4..fe4120534 100644 --- a/packages/ui-transitions/playground/src/pages/transition-5.vue +++ b/packages/ui-transitions/playground/src/pages/transition-5.vue @@ -5,7 +5,9 @@ import Buttons from '../components/Buttons.vue' definePage({ meta: { - stageTransition: 'fantasy-fall', + stageTransition: { + name: 'fantasy-fall', + }, }, }) diff --git a/packages/ui-transitions/playground/src/pages/transition-6.vue b/packages/ui-transitions/playground/src/pages/transition-6.vue index 7947bcdda..4dac7067c 100644 --- a/packages/ui-transitions/playground/src/pages/transition-6.vue +++ b/packages/ui-transitions/playground/src/pages/transition-6.vue @@ -5,7 +5,9 @@ import Buttons from '../components/Buttons.vue' definePage({ meta: { - stageTransition: 'rectangles-rotate', + stageTransition: { + name: 'rectangles-rotate', + }, }, }) diff --git a/packages/ui-transitions/playground/src/pages/transition-7.vue b/packages/ui-transitions/playground/src/pages/transition-7.vue index 795c89080..174f1f2ab 100644 --- a/packages/ui-transitions/playground/src/pages/transition-7.vue +++ b/packages/ui-transitions/playground/src/pages/transition-7.vue @@ -5,7 +5,9 @@ import Buttons from '../components/Buttons.vue' definePage({ meta: { - stageTransition: 'bubble-wave-out', + stageTransition: { + name: 'bubble-wave-out', + }, }, }) diff --git a/packages/ui-transitions/src/components/ArrowTransition.vue b/packages/ui-transitions/src/components/ArrowTransition.vue index 0a57655f6..0b180372c 100644 --- a/packages/ui-transitions/src/components/ArrowTransition.vue +++ b/packages/ui-transitions/src/components/ArrowTransition.vue @@ -2,15 +2,20 @@ import { computed, onMounted } from 'vue' const props = withDefaults(defineProps<{ - primaryColor?: string - secondaryColor?: string + stageTransition?: { + primaryColor?: string + secondaryColor?: string + } }>(), { - primaryColor: '#666', - secondaryColor: '#ccc', + stageTransition: () => ({ + primaryColor: '#666', + secondaryColor: '#ccc', + }), }) -const overlayColor1 = computed(() => props.primaryColor || '#666') -const overlayColor2 = computed(() => props.secondaryColor || '#ccc') +const stageTransition = computed(() => props.stageTransition) +const overlayColor1 = computed(() => stageTransition.value.primaryColor || '#666') +const overlayColor2 = computed(() => stageTransition.value.secondaryColor || '#ccc') onMounted(() => { document.documentElement.style.setProperty('--stage-transition-3-overlay-color-1', overlayColor1.value) diff --git a/packages/ui-transitions/src/components/BubbleWaveOutTransition.vue b/packages/ui-transitions/src/components/BubbleWaveOutTransition.vue index b2e2d73f9..d2868dfa1 100644 --- a/packages/ui-transitions/src/components/BubbleWaveOutTransition.vue +++ b/packages/ui-transitions/src/components/BubbleWaveOutTransition.vue @@ -1,20 +1,20 @@ diff --git a/packages/ui-transitions/src/components/MultipleBlocksRevealTransition.vue b/packages/ui-transitions/src/components/MultipleBlocksRevealTransition.vue index 450f99494..307f8b26d 100644 --- a/packages/ui-transitions/src/components/MultipleBlocksRevealTransition.vue +++ b/packages/ui-transitions/src/components/MultipleBlocksRevealTransition.vue @@ -2,15 +2,20 @@ import { computed, onMounted } from 'vue' const props = withDefaults(defineProps<{ - primaryColor?: string - secondaryColor?: string + stageTransition?: { + primaryColor?: string + secondaryColor?: string + } }>(), { - primaryColor: '#666', - secondaryColor: '#ccc', + stageTransition: () => ({ + primaryColor: '#666', + secondaryColor: '#ccc', + }), }) -const overlayColor1 = computed(() => props.primaryColor || '#666') -const overlayColor2 = computed(() => props.secondaryColor || '#ccc') +const stageTransition = computed(() => props.stageTransition) +const overlayColor1 = computed(() => stageTransition.value.primaryColor || '#666') +const overlayColor2 = computed(() => stageTransition.value.secondaryColor || '#ccc') onMounted(() => { document.documentElement.style.setProperty('--stage-transition-4-overlay-color-1', overlayColor1.value) diff --git a/packages/ui-transitions/src/components/RectanglesRotateTransition.vue b/packages/ui-transitions/src/components/RectanglesRotateTransition.vue index 7529cf592..ae6601b4b 100644 --- a/packages/ui-transitions/src/components/RectanglesRotateTransition.vue +++ b/packages/ui-transitions/src/components/RectanglesRotateTransition.vue @@ -1,33 +1,27 @@ diff --git a/packages/ui-transitions/src/components/SlideTransition.vue b/packages/ui-transitions/src/components/SlideTransition.vue index 6a0eca561..5762d3df7 100644 --- a/packages/ui-transitions/src/components/SlideTransition.vue +++ b/packages/ui-transitions/src/components/SlideTransition.vue @@ -2,15 +2,20 @@ import { computed, onMounted } from 'vue' const props = withDefaults(defineProps<{ - primaryColor?: string - secondaryColor?: string + stageTransition?: { + primaryColor?: string + secondaryColor?: string + } }>(), { - primaryColor: '#666', - secondaryColor: '#ccc', + stageTransition: () => ({ + primaryColor: '#666', + secondaryColor: '#ccc', + }), }) -const overlayColor1 = computed(() => props.primaryColor || '#666') -const overlayColor2 = computed(() => props.secondaryColor || '#ccc') +const stageTransition = computed(() => props.stageTransition) +const overlayColor1 = computed(() => stageTransition.value.primaryColor || '#666') +const overlayColor2 = computed(() => stageTransition.value.secondaryColor || '#ccc') onMounted(() => { document.documentElement.style.setProperty('--stage-transition-1-overlay-color-1', overlayColor1.value) diff --git a/packages/ui-transitions/src/components/SlopeSlideTransition.vue b/packages/ui-transitions/src/components/SlopeSlideTransition.vue index 3ad2c206d..75e2e70d8 100644 --- a/packages/ui-transitions/src/components/SlopeSlideTransition.vue +++ b/packages/ui-transitions/src/components/SlopeSlideTransition.vue @@ -2,15 +2,20 @@ import { computed, onMounted } from 'vue' const props = withDefaults(defineProps<{ - primaryColor?: string - secondaryColor?: string + stageTransition?: { + primaryColor?: string + secondaryColor?: string + } }>(), { - primaryColor: '#666', - secondaryColor: '#ccc', + stageTransition: () => ({ + primaryColor: '#666', + secondaryColor: '#ccc', + }), }) -const overlayColor1 = computed(() => props.primaryColor || '#666') -const overlayColor2 = computed(() => props.secondaryColor || '#ccc') +const stageTransition = computed(() => props.stageTransition) +const overlayColor1 = computed(() => stageTransition.value.primaryColor || '#666') +const overlayColor2 = computed(() => stageTransition.value.secondaryColor || '#ccc') onMounted(() => { document.documentElement.style.setProperty('--stage-transition-2-overlay-color-1', overlayColor1.value) diff --git a/packages/ui-transitions/src/components/StageTransitionGroup.vue b/packages/ui-transitions/src/components/StageTransitionGroup.vue index bba899db8..450a63a5e 100644 --- a/packages/ui-transitions/src/components/StageTransitionGroup.vue +++ b/packages/ui-transitions/src/components/StageTransitionGroup.vue @@ -10,13 +10,17 @@ import RectanglesRotateTransition from './RectanglesRotateTransition.vue' import SlideTransition from './SlideTransition.vue' import SlopeSlideTransition from './SlopeSlideTransition.vue' -withDefaults(defineProps<{ +const props = defineProps<{ primaryColor?: string secondaryColor?: string -}>(), { - primaryColor: '#666', - secondaryColor: '#ccc', -}) +}>() + +interface StageTransitionCommonParams { + name: string + primaryColor?: string + secondaryColor?: string + direction?: 'top' | 'bottom' | 'left' | 'right' +} type TransitionComponent = | typeof SlideTransition @@ -29,8 +33,10 @@ type TransitionComponent = const router = useRouter() const showTransition = ref(false) +const transitionStage = ref() + const activeTransitionName = ref('') -const transitionStage = ref(null) +const activeStageTransitionParams = ref() // Define transition lifecycle events export type TransitionStage = @@ -115,10 +121,10 @@ async function triggerHooks(stage: TransitionStage, data: any = {}) { } } -async function triggerTransitionAsyncFn(name: string, next: NavigationCallback, resolve: (value: void | PromiseLike) => void) { - const transition = transitions.value[name] +async function triggerTransitionAsyncFn(params: StageTransitionCommonParams, next: NavigationCallback, resolve: (value: void | PromiseLike) => void) { + const transition = transitions.value[params.name] if (!transition) { - console.error(`Transition ${name} not found`) + console.error(`Transition ${params.name} not found`) next() resolve() return @@ -144,13 +150,14 @@ async function triggerTransitionAsyncFn(name: string, next: NavigationCallback, try { // Before enter - await triggerHooks('before-enter', { transitionName: name }) + await triggerHooks('before-enter', { transitionName: params.name }) // Handle resetting current transition if needed if (showTransition.value) { // Fast track to exit if a transition is already active await triggerHooks('before-leave', { transitionName: activeTransitionName.value }) activeTransitionName.value = '' + activeStageTransitionParams.value = undefined showTransition.value = false await triggerHooks('after-leave', { transitionName: activeTransitionName.value }) @@ -159,7 +166,8 @@ async function triggerTransitionAsyncFn(name: string, next: NavigationCallback, } // Start new transition - activeTransitionName.value = name + activeTransitionName.value = params.name + activeStageTransitionParams.value = params showTransition.value = true // Enter active phase @@ -167,10 +175,7 @@ async function triggerTransitionAsyncFn(name: string, next: NavigationCallback, // Trigger navigation phase at the configured time setTimeout(async () => { - await triggerHooks('navigation', { - transitionName: name, - config: transition, // Pass full config to hooks - }) + await triggerHooks('navigation', { transitionName: params.name, config: transition }) // Ensure navigation happens even if no hook handled it if (!hasNavigated) { @@ -181,17 +186,17 @@ async function triggerTransitionAsyncFn(name: string, next: NavigationCallback, // After enter - entry phase complete setTimeout(async () => { - await triggerHooks('after-enter', { transitionName: name }) + await triggerHooks('after-enter', { transitionName: params.name }) }, transition.duration) // Before leave - start exit phase setTimeout(async () => { - await triggerHooks('before-leave', { transitionName: name }) + await triggerHooks('before-leave', { transitionName: params.name }) }, transition.duration + 10) // Small offset after enter completes // Leave active - exit animation running setTimeout(async () => { - await triggerHooks('leave-active', { transitionName: name }) + await triggerHooks('leave-active', { transitionName: params.name }) }, transition.duration + 20) // Small offset // After leave - completely finished @@ -199,10 +204,14 @@ async function triggerTransitionAsyncFn(name: string, next: NavigationCallback, setTimeout(async () => { showTransition.value = false activeTransitionName.value = '' - await triggerHooks('after-leave', { transitionName: name }) + activeStageTransitionParams.value = undefined + await triggerHooks('after-leave', { transitionName: params.name }) resolve() }, transition.duration + totalDuration) } + catch (error) { + console.error(error) + } finally { // Always remove the navigation hook removeNavHook() @@ -218,14 +227,27 @@ async function triggerTransitionAsyncFn(name: string, next: NavigationCallback, } // Improved transition trigger with navigation callback -function triggerTransition(name: string, next: NavigationCallback) { +function triggerTransition(params: StageTransitionCommonParams, next: NavigationCallback) { return new Promise((resolve) => { - triggerTransitionAsyncFn(name, next, resolve) + triggerTransitionAsyncFn(params, next, resolve) }) } router.beforeEach((to, _from, next) => { - triggerTransition(to.meta.stageTransition as string, next) + if (typeof to.meta.stageTransition !== 'object') { + next() + return + } + + const stageTransition = to.meta.stageTransition as StageTransitionCommonParams + if (typeof props.primaryColor !== 'undefined') { + stageTransition.primaryColor = props.primaryColor + } + if (typeof props.secondaryColor !== 'undefined') { + stageTransition.secondaryColor = props.secondaryColor + } + + triggerTransition(stageTransition, next) }) @@ -233,7 +255,7 @@ router.beforeEach((to, _from, next) => {