[ci] format
This commit is contained in:
parent
6a12fcecb0
commit
7a6ca236e8
12 changed files with 198 additions and 148 deletions
|
@ -7,8 +7,9 @@ export interface Props {
|
|||
|
||||
const { fallback = 'animate' } = Astro.props as Props;
|
||||
---
|
||||
<meta name="astro-view-transitions-enabled" content="true">
|
||||
<meta name="astro-view-transitions-fallback" content={fallback}>
|
||||
|
||||
<meta name="astro-view-transitions-enabled" content="true" />
|
||||
<meta name="astro-view-transitions-fallback" content={fallback} />
|
||||
<script>
|
||||
type Fallback = 'none' | 'animate' | 'swap';
|
||||
type Direction = 'forward' | 'back';
|
||||
|
@ -22,10 +23,11 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|||
}
|
||||
|
||||
const supportsViewTransitions = !!document.startViewTransition;
|
||||
const transitionEnabledOnThisPage = () => !!document.querySelector('[name="astro-view-transitions-enabled"]');
|
||||
const transitionEnabledOnThisPage = () =>
|
||||
!!document.querySelector('[name="astro-view-transitions-enabled"]');
|
||||
|
||||
async function getHTML(href: string) {
|
||||
const res = await fetch(href)
|
||||
const res = await fetch(href);
|
||||
const html = await res.text();
|
||||
return { ok: res.ok, html };
|
||||
}
|
||||
|
@ -47,7 +49,7 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|||
|
||||
if (fallback === 'animate') {
|
||||
let isAnimating = false;
|
||||
addEventListener('animationstart', () => isAnimating = true, { once: true });
|
||||
addEventListener('animationstart', () => (isAnimating = true), { once: true });
|
||||
|
||||
// Trigger the animations
|
||||
document.documentElement.dataset.astroTransitionFallback = 'old';
|
||||
|
@ -105,7 +107,8 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|||
// This check verifies that the click is happening on an anchor
|
||||
// that is going to another page within the same origin. Basically it determines
|
||||
// same-origin navigation, but omits special key combos for new tabs, etc.
|
||||
if (link &&
|
||||
if (
|
||||
link &&
|
||||
link instanceof HTMLAnchorElement &&
|
||||
link.href &&
|
||||
(!link.target || link.target === '_self') &&
|
||||
|
@ -126,21 +129,29 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|||
});
|
||||
window.addEventListener('popstate', () => {
|
||||
if (!transitionEnabledOnThisPage()) return;
|
||||
const nextIndex = history.state?.index ?? (currentHistoryIndex + 1);
|
||||
const nextIndex = history.state?.index ?? currentHistoryIndex + 1;
|
||||
const direction: Direction = nextIndex > currentHistoryIndex ? 'forward' : 'back';
|
||||
navigate(direction, location.href);
|
||||
currentHistoryIndex = nextIndex;
|
||||
});
|
||||
|
||||
['mouseenter', 'touchstart', 'focus'].forEach(evName => {
|
||||
document.addEventListener(evName, ev => {
|
||||
['mouseenter', 'touchstart', 'focus'].forEach((evName) => {
|
||||
document.addEventListener(
|
||||
evName,
|
||||
(ev) => {
|
||||
if (ev.target instanceof HTMLAnchorElement) {
|
||||
let el = ev.target;
|
||||
if(el.origin === location.origin && el.pathname !== location.pathname && transitionEnabledOnThisPage()) {
|
||||
if (
|
||||
el.origin === location.origin &&
|
||||
el.pathname !== location.pathname &&
|
||||
transitionEnabledOnThisPage()
|
||||
) {
|
||||
maybePrefetch(el.pathname);
|
||||
}
|
||||
}
|
||||
}, { passive: true, capture: true });
|
||||
},
|
||||
{ passive: true, capture: true }
|
||||
);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -8,25 +8,37 @@
|
|||
}
|
||||
|
||||
@keyframes astroFadeIn {
|
||||
from { opacity: 0; }
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes astroFadeOut {
|
||||
to { opacity: 0; }
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes astroSlideFromRight {
|
||||
from { transform: translateX(100%); }
|
||||
from {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes astroSlideFromLeft {
|
||||
from { transform: translateX(-100%); }
|
||||
from {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes astroSlideToRight {
|
||||
to { transform: translateX(100%); }
|
||||
to {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes astroSlideToLeft {
|
||||
to { transform: translateX(-100%); }
|
||||
to {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ test.afterAll(async () => {
|
|||
test.describe('View Transitions', () => {
|
||||
test('Moving from page 1 to page 2', async ({ page, astro }) => {
|
||||
const loads = [];
|
||||
page.addListener('load', p => {
|
||||
page.addListener('load', (p) => {
|
||||
loads.push(p.title());
|
||||
});
|
||||
|
||||
|
@ -35,7 +35,7 @@ test.describe('View Transitions', () => {
|
|||
|
||||
test('Back button is captured', async ({ page, astro }) => {
|
||||
const loads = [];
|
||||
page.addListener('load', p => {
|
||||
page.addListener('load', (p) => {
|
||||
loads.push(p.title());
|
||||
});
|
||||
|
||||
|
@ -59,7 +59,7 @@ test.describe('View Transitions', () => {
|
|||
|
||||
test('Clicking on a link with nested content', async ({ page, astro }) => {
|
||||
const loads = [];
|
||||
page.addListener('load', p => {
|
||||
page.addListener('load', (p) => {
|
||||
loads.push(p.title());
|
||||
});
|
||||
|
||||
|
@ -76,9 +76,12 @@ test.describe('View Transitions', () => {
|
|||
expect(loads.length, 'There should only be 1 page load').toEqual(1);
|
||||
});
|
||||
|
||||
test('Moving from a page without ViewTransitions triggers a full page navigation', async ({ page, astro }) => {
|
||||
test('Moving from a page without ViewTransitions triggers a full page navigation', async ({
|
||||
page,
|
||||
astro,
|
||||
}) => {
|
||||
const loads = [];
|
||||
page.addListener('load', p => {
|
||||
page.addListener('load', (p) => {
|
||||
loads.push(p.title());
|
||||
});
|
||||
|
||||
|
@ -96,6 +99,9 @@ test.describe('View Transitions', () => {
|
|||
p = page.locator('#two');
|
||||
await expect(p, 'should have content').toHaveText('Page 2');
|
||||
|
||||
expect(loads.length, 'There should be 2 page loads. The original, then going from 3 to 2').toEqual(2);
|
||||
expect(
|
||||
loads.length,
|
||||
'There should be 2 page loads. The original, then going from 3 to 2'
|
||||
).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -233,7 +233,10 @@ export const AstroConfigSchema = z.object({
|
|||
experimental: z
|
||||
.object({
|
||||
assets: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.assets),
|
||||
viewTransitions: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.viewTransitions),
|
||||
viewTransitions: z
|
||||
.boolean()
|
||||
.optional()
|
||||
.default(ASTRO_CONFIG_DEFAULTS.experimental.viewTransitions),
|
||||
})
|
||||
.passthrough()
|
||||
.refine(
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
astroContentImportPlugin,
|
||||
astroContentVirtualModPlugin,
|
||||
} from '../content/index.js';
|
||||
import astroTransitions from '../transitions/vite-plugin-transitions.js';
|
||||
import astroPostprocessVitePlugin from '../vite-plugin-astro-postprocess/index.js';
|
||||
import { vitePluginAstroServer } from '../vite-plugin-astro-server/index.js';
|
||||
import astroVitePlugin from '../vite-plugin-astro/index.js';
|
||||
|
@ -27,7 +28,6 @@ import astroScannerPlugin from '../vite-plugin-scanner/index.js';
|
|||
import astroScriptsPlugin from '../vite-plugin-scripts/index.js';
|
||||
import astroScriptsPageSSRPlugin from '../vite-plugin-scripts/page-ssr.js';
|
||||
import { vitePluginSSRManifest } from '../vite-plugin-ssr-manifest/index.js';
|
||||
import astroTransitions from '../transitions/vite-plugin-transitions.js';
|
||||
import { joinPaths } from './path.js';
|
||||
|
||||
interface CreateViteOptions {
|
||||
|
|
|
@ -7,7 +7,11 @@ function validateArgs(args: unknown[]): args is Parameters<AstroComponentFactory
|
|||
if (!args[0] || typeof args[0] !== 'object') return false;
|
||||
return true;
|
||||
}
|
||||
function baseCreateComponent(cb: AstroComponentFactory, moduleId?: string, propagation?: PropagationHint): AstroComponentFactory {
|
||||
function baseCreateComponent(
|
||||
cb: AstroComponentFactory,
|
||||
moduleId?: string,
|
||||
propagation?: PropagationHint
|
||||
): AstroComponentFactory {
|
||||
const name = moduleId?.split('/').pop()?.replace('.astro', '') ?? '';
|
||||
const fn = (...args: Parameters<AstroComponentFactory>) => {
|
||||
if (!validateArgs(args)) {
|
||||
|
@ -40,7 +44,7 @@ function createComponentWithOptions(opts: CreateComponentOptions) {
|
|||
export function createComponent(
|
||||
arg1: AstroComponentFactory | CreateComponentOptions,
|
||||
moduleId?: string,
|
||||
propagation?: PropagationHint,
|
||||
propagation?: PropagationHint
|
||||
) {
|
||||
if (typeof arg1 === 'function') {
|
||||
return baseCreateComponent(arg1, moduleId, propagation);
|
||||
|
|
|
@ -33,13 +33,13 @@ export {
|
|||
stringifyChunk,
|
||||
voidElementNames,
|
||||
} from './render/index.js';
|
||||
export { renderTransition } from './transition.js';
|
||||
export type {
|
||||
AstroComponentFactory,
|
||||
AstroComponentInstance,
|
||||
ComponentSlots,
|
||||
RenderInstruction,
|
||||
} from './render/index.js';
|
||||
export { renderTransition } from './transition.js';
|
||||
|
||||
import { markHTMLString } from './escape.js';
|
||||
import { addAttribute, Renderer } from './render/index.js';
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import type {
|
||||
SSRResult,
|
||||
TransitionAnimation,
|
||||
TransitionDirectionalAnimations,
|
||||
TransitionAnimationValue,
|
||||
TransitionDirectionalAnimations,
|
||||
} from '../../@types/astro';
|
||||
import { fade, slide } from '../../transitions/index.js';
|
||||
import { markHTMLString } from './escape.js';
|
||||
import { slide, fade } from '../../transitions/index.js';
|
||||
|
||||
const transitionNameMap = new WeakMap<SSRResult, number>();
|
||||
function incrementTransitionNumber(result: SSRResult) {
|
||||
|
@ -21,7 +21,12 @@ function createTransitionScope(result: SSRResult, hash: string) {
|
|||
const num = incrementTransitionNumber(result);
|
||||
return `astro-${hash}-${num}`;
|
||||
}
|
||||
export function renderTransition(result: SSRResult, hash: string, animationName: TransitionAnimationValue | undefined, transitionName: string) {
|
||||
export function renderTransition(
|
||||
result: SSRResult,
|
||||
hash: string,
|
||||
animationName: TransitionAnimationValue | undefined,
|
||||
transitionName: string
|
||||
) {
|
||||
let animations: TransitionDirectionalAnimations | null = null;
|
||||
switch (animationName) {
|
||||
case 'fade': {
|
||||
|
@ -49,8 +54,10 @@ export function renderTransition(result: SSRResult, hash: string, animationName:
|
|||
const styles = markHTMLString(`<style>[data-astro-transition-scope="${scope}"] {
|
||||
view-transition-name: ${transitionName};
|
||||
}
|
||||
${!animations ? `` :
|
||||
// Regular animations
|
||||
${
|
||||
!animations
|
||||
? ``
|
||||
: // Regular animations
|
||||
`
|
||||
::view-transition-old(${transitionName}) {
|
||||
${stringifyAnimation(animations.forwards.old)}
|
||||
|
@ -79,8 +86,9 @@ export function renderTransition(result: SSRResult, hash: string, animationName:
|
|||
[data-astro-transition=back][data-astro-transition-fallback=new] [data-astro-transition-scope="${scope}"] {
|
||||
${stringifyAnimation(animations.backwards.new)}
|
||||
}
|
||||
`.trim()}
|
||||
</style>`)
|
||||
`.trim()
|
||||
}
|
||||
</style>`);
|
||||
|
||||
result._metadata.extraHead.push(styles);
|
||||
|
||||
|
@ -90,7 +98,7 @@ export function renderTransition(result: SSRResult, hash: string, animationName:
|
|||
type AnimationBuilder = {
|
||||
toString(): string;
|
||||
[key: string]: string[] | ((k: string) => string);
|
||||
}
|
||||
};
|
||||
|
||||
function addAnimationProperty(builder: AnimationBuilder, prop: string, value: string | number) {
|
||||
let arr = builder[prop];
|
||||
|
@ -108,11 +116,11 @@ function animationBuilder(): AnimationBuilder {
|
|||
for (let k in this) {
|
||||
let value = this[k];
|
||||
if (Array.isArray(value)) {
|
||||
out += `\n\t${k}: ${value.join(', ')};`
|
||||
out += `\n\t${k}: ${value.join(', ')};`;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,45 +1,51 @@
|
|||
import type { TransitionDirectionalAnimations, TransitionAnimationPair } from '../@types/astro';
|
||||
import type { TransitionDirectionalAnimations } from '../@types/astro';
|
||||
|
||||
export function slide({
|
||||
duration
|
||||
duration,
|
||||
}: {
|
||||
duration?: string | number;
|
||||
} = {}): TransitionDirectionalAnimations {
|
||||
return {
|
||||
forwards: {
|
||||
old: [{
|
||||
old: [
|
||||
{
|
||||
name: 'astroFadeOut',
|
||||
duration: duration ?? '90ms',
|
||||
easing: 'cubic-bezier(0.4, 0, 1, 1)',
|
||||
fillMode: 'both'
|
||||
}, {
|
||||
fillMode: 'both',
|
||||
},
|
||||
{
|
||||
name: 'astroSlideToLeft',
|
||||
duration: duration ?? '300ms',
|
||||
easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
||||
fillMode: 'both'
|
||||
}],
|
||||
new: [{
|
||||
fillMode: 'both',
|
||||
},
|
||||
],
|
||||
new: [
|
||||
{
|
||||
name: 'astroFadeIn',
|
||||
duration: duration ?? '210ms',
|
||||
easing: 'cubic-bezier(0, 0, 0.2, 1)',
|
||||
delay: '90ms',
|
||||
fillMode: 'both'
|
||||
}, {
|
||||
fillMode: 'both',
|
||||
},
|
||||
{
|
||||
name: 'astroSlideFromRight',
|
||||
duration: duration ?? '300ms',
|
||||
easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
||||
fillMode: 'both'
|
||||
}]
|
||||
fillMode: 'both',
|
||||
},
|
||||
],
|
||||
},
|
||||
backwards: {
|
||||
old: [{ name: 'astroFadeOut' }, { name: 'astroSlideToRight' }],
|
||||
new: [{ name: 'astroFadeIn' }, { name: 'astroSlideFromLeft' }]
|
||||
}
|
||||
new: [{ name: 'astroFadeIn' }, { name: 'astroSlideFromLeft' }],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function fade({
|
||||
duration
|
||||
duration,
|
||||
}: {
|
||||
duration?: string | number;
|
||||
} = {}): TransitionDirectionalAnimations {
|
||||
|
@ -55,7 +61,7 @@ export function fade({
|
|||
duration: duration ?? '0.3s',
|
||||
easing: 'linear',
|
||||
fillMode: 'backwards',
|
||||
}
|
||||
},
|
||||
} satisfies TransitionAnimationPair;
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import type { AstroConfig } from '../@types/astro';
|
||||
import * as vite from 'vite';
|
||||
import type { AstroConfig } from '../@types/astro';
|
||||
import { AstroError } from '../core/errors/index.js';
|
||||
|
||||
const virtualModuleId = 'astro:transitions';
|
||||
const resolvedVirtualModuleId = '\0' + virtualModuleId;
|
||||
|
||||
// The virtual module for the astro:transitions namespace
|
||||
export default function astroTransitions({ config }: { config: AstroConfig; }): vite.Plugin {
|
||||
export default function astroTransitions({ config }: { config: AstroConfig }): vite.Plugin {
|
||||
return {
|
||||
name: 'astro:transitions',
|
||||
async resolveId(id) {
|
||||
|
@ -25,7 +25,7 @@ export default defineConfig({
|
|||
experimental: {
|
||||
viewTransitions: true
|
||||
}
|
||||
})`
|
||||
})`,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ describe('astro/src/core/compile', () => {
|
|||
await cachedCompilation({
|
||||
astroConfig: {
|
||||
root: pathToFileURL('/'),
|
||||
experimental: {}
|
||||
experimental: {},
|
||||
},
|
||||
viteConfig: await resolveConfig({ configFile: false }, 'serve'),
|
||||
filename: '/src/pages/index.astro',
|
||||
|
|
Loading…
Reference in a new issue