Compare commits
89 commits
chris/soci
...
main
Author | SHA1 | Date | |
---|---|---|---|
993c085952 | |||
|
3f231cefed | ||
|
a8b979ef40 | ||
|
bd5aa1cd35 | ||
|
03e6979c28 | ||
|
75781643a2 | ||
|
9cd6a6657b | ||
|
c071458257 | ||
|
0ab6bad7df | ||
|
90d70eb7c4 | ||
|
054c5c6447 | ||
|
7ea27f6319 | ||
|
c4a7ec4255 | ||
|
a0dc79b946 | ||
|
160d1cd755 | ||
|
29cdfa0248 | ||
|
c24f70d916 | ||
|
33d0be50be | ||
|
93b092266f | ||
|
eaed844ea8 | ||
|
30de324361 | ||
|
2262814a92 | ||
|
f9131003d7 | ||
|
d51cf5e707 | ||
|
e5e6cf16eb | ||
|
41f93e0ccb | ||
|
4e5cafa5d2 | ||
|
ec82e73efa | ||
|
584d6f0680 | ||
|
78adbc4433 | ||
|
d78806dfe0 | ||
|
aa265d7302 | ||
|
b18d4bf3b1 | ||
|
21e0757ea2 | ||
|
272ad45958 | ||
|
21f4826576 | ||
|
71618f4074 | ||
|
240d8ff7c9 | ||
|
357270f2a3 | ||
|
f277ba8b70 | ||
|
6f60da805e | ||
|
d1c75fe158 | ||
|
f9477aade1 | ||
|
78fda5c3ec | ||
|
455af3235b | ||
|
6db2687ef0 | ||
|
5fb6a266f8 | ||
|
3dd65bf889 | ||
|
22fae5211a | ||
|
4c2bec681b | ||
|
a067c2a2c7 | ||
|
0b22bb9af4 | ||
|
47ea310f01 | ||
|
db83237dd3 | ||
|
148b5b8769 | ||
|
345808170f | ||
|
31c59ad8b6 | ||
|
c3572fd5e0 | ||
|
77d37853cb | ||
|
eb530e9b61 | ||
|
2d33b9362d | ||
|
2167ffd72f | ||
|
0ba32e4402 | ||
|
c4c616c0a5 | ||
|
cfd895d877 | ||
|
eada8ab8fa | ||
|
3c93476078 | ||
|
824dd4670a | ||
|
0e35457c0f | ||
|
f6ba533df6 | ||
|
23e7b259eb | ||
|
8617259fc9 | ||
|
ec249f7a98 | ||
|
0ab19ba615 | ||
|
e9b77cbf19 | ||
|
f5c617e3a3 | ||
|
c0708c921c | ||
|
408b50c5ea | ||
|
e797b68160 | ||
|
87d5b841af | ||
|
4ed410db50 | ||
|
a10a798c18 | ||
|
e6be2d8146 | ||
|
5121740de7 | ||
|
9b0114c7d3 | ||
|
e8495c853b | ||
|
aad756297c | ||
|
63bc37f2b6 | ||
|
9fe4b95969 |
367 changed files with 87471 additions and 6526 deletions
|
@ -1,8 +0,0 @@
|
|||
FROM gitpod/workspace-node
|
||||
|
||||
# Install latest pnpm
|
||||
RUN curl -fsSL https://get.pnpm.io/install.sh | SHELL=`which bash` bash -
|
||||
|
||||
# Install deno in gitpod
|
||||
RUN curl -fsSL https://deno.land/x/install/install.sh | sh
|
||||
RUN /home/gitpod/.deno/bin/deno completions bash > /home/gitpod/.bashrc.d/90-deno && echo 'export DENO_INSTALL="/home/gitpod/.deno"' >> /home/gitpod/.bashrc.d/90-deno && echo 'export PATH="$DENO_INSTALL/bin:$PATH"' >> /home/gitpod/.bashrc.d/90-deno
|
5
.changeset/forty-singers-ring.md
Normal file
5
.changeset/forty-singers-ring.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fixed an issue where the transitions router did not work within framework components.
|
5
.changeset/unlucky-avocados-brake.md
Normal file
5
.changeset/unlucky-avocados-brake.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@astrojs/cloudflare': patch
|
||||
---
|
||||
|
||||
fixes `AdvancedRuntime` & `DirectoryRuntime` types to work woth Cloudflare caches
|
|
@ -6,10 +6,6 @@ RUN npm install -g @playwright/test
|
|||
# Install latest pnpm
|
||||
RUN npm install -g pnpm
|
||||
|
||||
# Install deno
|
||||
ENV DENO_INSTALL=/usr/local
|
||||
RUN curl -fsSL https://deno.land/x/install/install.sh | sh
|
||||
|
||||
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
&& curl -sSL https://dl.google.com/linux/direct/google-chrome-stable_current_$(dpkg --print-architecture).deb -o /tmp/chrome.deb \
|
||||
&& apt-get -y install /tmp/chrome.deb
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"name": "Deno",
|
||||
"build": {
|
||||
"dockerfile": "../examples.deno.Dockerfile"
|
||||
},
|
||||
|
||||
"workspaceFolder": "/workspaces/astro/examples/deno",
|
||||
|
||||
"portsAttributes": {
|
||||
"4321": {
|
||||
"label": "Application",
|
||||
"onAutoForward": "openPreview"
|
||||
}
|
||||
},
|
||||
|
||||
"forwardPorts": [4321],
|
||||
|
||||
"postCreateCommand": "pnpm install && cd /workspaces/astro && pnpm run build",
|
||||
|
||||
"waitFor": "postCreateCommand",
|
||||
|
||||
"postAttachCommand": {
|
||||
"Server": "pnpm start --host"
|
||||
},
|
||||
|
||||
"customizations": {
|
||||
"codespaces": {
|
||||
"openFiles": ["src/pages/index.astro"]
|
||||
},
|
||||
"vscode": {
|
||||
"extensions": ["astro-build.astro-vscode", "esbenp.prettier-vscode"]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
FROM mcr.microsoft.com/devcontainers/javascript-node:0-18
|
||||
|
||||
# Install latest pnpm
|
||||
RUN npm install -g pnpm
|
||||
|
||||
# Install deno
|
||||
ENV DENO_INSTALL=/usr/local
|
||||
RUN curl -fsSL https://deno.land/x/install/install.sh | sh
|
||||
|
||||
COPY example-welcome-message.txt /usr/local/etc/vscode-dev-containers/first-run-notice.txt
|
9
.github/workflows/ci.yml
vendored
9
.github/workflows/ci.yml
vendored
|
@ -113,7 +113,7 @@ jobs:
|
|||
- os: macos-latest
|
||||
NODE_VERSION: 18
|
||||
- os: windows-latest
|
||||
NODE_VERSION: 18
|
||||
NODE_VERSION: 18.17.1
|
||||
fail-fast: false
|
||||
env:
|
||||
NODE_VERSION: ${{ matrix.NODE_VERSION }}
|
||||
|
@ -133,11 +133,6 @@ jobs:
|
|||
node-version: ${{ matrix.NODE_VERSION }}
|
||||
cache: "pnpm"
|
||||
|
||||
- name: Use Deno
|
||||
uses: denoland/setup-deno@v1
|
||||
with:
|
||||
deno-version: v1.35.0
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
|
@ -155,7 +150,7 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
OS: [ubuntu-latest, windows-latest]
|
||||
NODE_VERSION: [18]
|
||||
NODE_VERSION: [18.17.1]
|
||||
fail-fast: false
|
||||
env:
|
||||
NODE_VERSION: ${{ matrix.NODE_VERSION }}
|
||||
|
|
3
.github/workflows/release.yml
vendored
3
.github/workflows/release.yml
vendored
|
@ -22,6 +22,9 @@ jobs:
|
|||
name: Changelog PR or Release
|
||||
if: ${{ github.repository_owner == 'withastro' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
|
|
7
.github/workflows/snapshot-release.yml
vendored
7
.github/workflows/snapshot-release.yml
vendored
|
@ -19,6 +19,11 @@ jobs:
|
|||
name: Create a snapshot release of a pull request
|
||||
if: ${{ github.repository_owner == 'withastro' && github.event.issue.pull_request && startsWith(github.event.comment.body, '!preview') }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: "Check if user has admin access (only admins can publish snapshot releases)."
|
||||
uses: "lannonbr/repo-permission-check-action@2.0.0"
|
||||
|
@ -81,6 +86,8 @@ jobs:
|
|||
id: publish
|
||||
run: |
|
||||
pnpm run release --tag next--${{ steps.getSnapshotName.outputs.result }} > publish.output.txt 2>&1
|
||||
echo "Release complete"
|
||||
cat publish.output.txt
|
||||
echo ::set-output name=result::`cat publish.output.txt`
|
||||
env:
|
||||
# Needs access to publish to npm
|
||||
|
|
22
.github/workflows/test-hosts.yml
vendored
22
.github/workflows/test-hosts.yml
vendored
|
@ -11,8 +11,6 @@ env:
|
|||
VERCEL_ORG_ID: ${{ secrets.VERCEL_TEST_ORG_ID }}
|
||||
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_TEST_PROJECT_ID }}
|
||||
VERCEL_TOKEN: ${{ secrets.VERCEL_TEST_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_TEST_SITE_ID }}
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_TEST_AUTH_TOKEN }}
|
||||
FORCE_COLOR: true
|
||||
|
||||
jobs:
|
||||
|
@ -34,22 +32,20 @@ jobs:
|
|||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Build Astro
|
||||
run: pnpm turbo build --filter astro --filter @astrojs/vercel
|
||||
|
||||
- name: Install Hosts CLIs
|
||||
run: pnpm install --global netlify-cli vercel
|
||||
|
||||
- name: Deploy Vercel
|
||||
- name: Build test project
|
||||
working-directory: ./packages/integrations/vercel/test/hosted/hosted-astro-project
|
||||
run:
|
||||
pnpm run build
|
||||
vercel --prod --prebuilt
|
||||
|
||||
- name: Deploy Netlify
|
||||
working-directory: ./packages/integrations/netlify/test/hosted/hosted-astro-project
|
||||
|
||||
- name: Deploy to Vercel
|
||||
working-directory: ./packages/integrations/vercel/test/hosted/hosted-astro-project
|
||||
run:
|
||||
pnpm run build
|
||||
netlify deploy --prod
|
||||
pnpm dlx vercel --prod --prebuilt
|
||||
|
||||
- name: Test both hosts
|
||||
- name: Test
|
||||
run:
|
||||
pnpm run test:e2e:hosts
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
---
|
||||
image:
|
||||
file: .Dockerfile
|
||||
# Commands to start on workspace startup
|
||||
tasks:
|
||||
- before: |
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
# Convert context URL to an array
|
||||
mapfile -t CONTEXT_URL_ITEMS < <(echo "$GITPOD_WORKSPACE_CONTEXT_URL" | tr '/' '\n')
|
||||
|
||||
# Install latest pnpm
|
||||
curl -fsSL https://get.pnpm.io/install.sh | SHELL=`which bash` bash -
|
||||
|
||||
# Check if Gitpod started from a specific example directory in the repository
|
||||
if [ "${CONTEXT_URL_ITEMS[7]}" = "examples" ]; then
|
||||
EXAMPLE_PROJECT=${CONTEXT_URL_ITEMS[8]}
|
||||
|
|
|
@ -52,8 +52,6 @@ Join us on [Discord](https://astro.build/chat) to meet other maintainers. We'll
|
|||
| [@astrojs/svelte](packages/integrations/svelte) | [![astro version](https://img.shields.io/npm/v/@astrojs/svelte.svg?label=%20)](packages/integrations/svelte/CHANGELOG.md) |
|
||||
| [@astrojs/vue](packages/integrations/vue) | [![astro version](https://img.shields.io/npm/v/@astrojs/vue.svg?label=%20)](packages/integrations/vue/CHANGELOG.md) |
|
||||
| [@astrojs/lit](packages/integrations/lit) | [![astro version](https://img.shields.io/npm/v/@astrojs/lit.svg?label=%20)](packages/integrations/lit/CHANGELOG.md) |
|
||||
| [@astrojs/deno](packages/integrations/deno) | [![astro version](https://img.shields.io/npm/v/@astrojs/deno.svg?label=%20)](packages/integrations/deno/CHANGELOG.md) |
|
||||
| [@astrojs/netlify](packages/integrations/netlify) | [![astro version](https://img.shields.io/npm/v/@astrojs/netlify.svg?label=%20)](packages/integrations/netlify/CHANGELOG.md) |
|
||||
| [@astrojs/node](packages/integrations/node) | [![astro version](https://img.shields.io/npm/v/@astrojs/node.svg?label=%20)](packages/integrations/node/CHANGELOG.md) |
|
||||
| [@astrojs/vercel](packages/integrations/vercel) | [![astro version](https://img.shields.io/npm/v/@astrojs/vercel.svg?label=%20)](packages/integrations/vercel/CHANGELOG.md) |
|
||||
| [@astrojs/cloudflare](packages/integrations/cloudflare) | [![astro version](https://img.shields.io/npm/v/@astrojs/cloudflare.svg?label=%20)](packages/integrations/cloudflare/CHANGELOG.md) |
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^3.1.4"
|
||||
"astro": "^3.2.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/mdx": "^1.1.0",
|
||||
"@astrojs/mdx": "^1.1.1",
|
||||
"@astrojs/rss": "^3.0.0",
|
||||
"@astrojs/sitemap": "^3.0.0",
|
||||
"astro": "^3.1.4"
|
||||
"@astrojs/sitemap": "^3.0.1",
|
||||
"astro": "^3.2.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
],
|
||||
"scripts": {},
|
||||
"devDependencies": {
|
||||
"astro": "^3.1.4"
|
||||
"astro": "^3.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"astro": "^2.0.0-beta.0"
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
FROM node:18-bullseye
|
4
examples/deno/.vscode/extensions.json
vendored
4
examples/deno/.vscode/extensions.json
vendored
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"recommendations": ["astro-build.astro-vscode"],
|
||||
"unwantedRecommendations": []
|
||||
}
|
11
examples/deno/.vscode/launch.json
vendored
11
examples/deno/.vscode/launch.json
vendored
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"command": "./node_modules/.bin/astro dev",
|
||||
"name": "Development server",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
# Astro Starter Kit: Deno
|
||||
|
||||
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/deno)
|
||||
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/deno)
|
||||
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/deno/devcontainer.json)
|
||||
|
||||
```sh
|
||||
npm create astro@latest -- --template deno
|
||||
```
|
||||
|
||||
> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
|
||||
|
||||
![basics](https://user-images.githubusercontent.com/4677417/186188965-73453154-fdec-4d6b-9c34-cb35c248ae5b.png)
|
||||
|
||||
## 🚀 Project Structure
|
||||
|
||||
Inside of your Astro project, you'll see the following folders and files:
|
||||
|
||||
```text
|
||||
/
|
||||
├── public/
|
||||
│ └── favicon.svg
|
||||
├── src/
|
||||
│ ├── components/
|
||||
│ │ └── Layout.astro
|
||||
│ └── pages/
|
||||
│ └── index.astro
|
||||
├── package.json
|
||||
└── tsconfig.json
|
||||
```
|
||||
|
||||
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
|
||||
|
||||
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
|
||||
|
||||
Any static assets, like images, can be placed in the `public/` directory.
|
||||
|
||||
## 🧞 Commands
|
||||
|
||||
All commands are run from the root of the project, from a terminal:
|
||||
|
||||
| Command | Action |
|
||||
| :------------------------ | :----------------------------------------------- |
|
||||
| `npm install` | Installs dependencies |
|
||||
| `npm run dev` | Starts local dev server at `localhost:4321` |
|
||||
| `npm run build` | Build your production site to `./dist/` |
|
||||
| `npm run preview` | Preview your build locally, before deploying |
|
||||
| | (preview uses Deno CLI) |
|
||||
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
|
||||
| `npm run astro -- --help` | Get help using the Astro CLI |
|
||||
|
||||
## 👀 Want to learn more?
|
||||
|
||||
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
"name": "@example/deno",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"start": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "deno run --allow-net --allow-read --allow-env ./dist/server/entry.mjs",
|
||||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^3.1.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/deno": "^5.0.1"
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
|
||||
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
|
||||
<style>
|
||||
path { fill: #000; }
|
||||
@media (prefers-color-scheme: dark) {
|
||||
path { fill: #FFF; }
|
||||
}
|
||||
</style>
|
||||
</svg>
|
Before Width: | Height: | Size: 749 B |
|
@ -1,61 +0,0 @@
|
|||
---
|
||||
interface Props {
|
||||
title: string;
|
||||
}
|
||||
|
||||
const { title } = Astro.props as Props;
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<title>{title}</title>
|
||||
</head>
|
||||
<body>
|
||||
<slot />
|
||||
<style>
|
||||
:root {
|
||||
--font-size-base: clamp(1rem, 0.34vw + 0.91rem, 1.19rem);
|
||||
--font-size-lg: clamp(1.2rem, 0.7vw + 1.2rem, 1.5rem);
|
||||
--font-size-xl: clamp(2.44rem, 2.38vw + 1.85rem, 3rem);
|
||||
|
||||
--color-text: hsl(12, 5%, 4%);
|
||||
--color-bg: hsl(10, 21%, 95%);
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: system-ui, sans-serif;
|
||||
font-size: var(--font-size-base);
|
||||
color: var(--color-text);
|
||||
background-color: var(--color-bg);
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
:global(h1) {
|
||||
font-size: var(--font-size-xl);
|
||||
}
|
||||
|
||||
:global(h2) {
|
||||
font-size: var(--font-size-lg);
|
||||
}
|
||||
|
||||
:global(code) {
|
||||
font-family:
|
||||
Menlo,
|
||||
Monaco,
|
||||
Lucida Console,
|
||||
Liberation Mono,
|
||||
DejaVu Sans Mono,
|
||||
Bitstream Vera Sans Mono,
|
||||
Courier New,
|
||||
monospace;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
|
@ -1,188 +0,0 @@
|
|||
---
|
||||
import Layout from '../components/Layout.astro';
|
||||
|
||||
export const prerender = true;
|
||||
---
|
||||
|
||||
<Layout title="Welcome to Astro (on Deno).">
|
||||
<main>
|
||||
<h1>Welcome to <span class="text-gradient">Astro</span> on Deno</h1>
|
||||
<p class="instructions">
|
||||
<strong>Your first mission:</strong> tweak this message to try our hot module reloading. Check
|
||||
the <code>src/pages</code> directory!
|
||||
</p>
|
||||
<ul role="list" class="link-card-grid">
|
||||
<li class="link-card">
|
||||
<a href="https://astro.build/integrations/">
|
||||
<h2>Integrations <span>→</span></h2>
|
||||
<p>Add component frameworks, Tailwind, Partytown, and more!</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="link-card">
|
||||
<a href="https://astro.build/themes/">
|
||||
<h2>Themes <span>→</span></h2>
|
||||
<p>Explore a galaxy of community-built starters.</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="link-card">
|
||||
<a href="https://docs.astro.build/">
|
||||
<h2>Docs <span>→</span></h2>
|
||||
<p>Learn our complete feature set and explore the API.</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="link-card">
|
||||
<a href="https://astro.build/chat/">
|
||||
<h2>Chat <span>→</span></h2>
|
||||
<p>
|
||||
Ask, contribute, and have fun on our community Discord
|
||||
<svg
|
||||
class="heart"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="currentColor"
|
||||
>
|
||||
<title>heart</title>
|
||||
<path
|
||||
d="M256 448l-30.164-27.211C118.718 322.442 48 258.61 48 179.095 48 114.221 97.918 64 162.4 64c36.399 0 70.717 16.742 93.6 43.947C278.882 80.742 313.199 64 349.6 64 414.082 64 464 114.221 464 179.095c0 79.516-70.719 143.348-177.836 241.694L256 448z"
|
||||
></path>
|
||||
</svg>
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</main>
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--color-border: hsl(17, 24%, 90%);
|
||||
--astro-gradient: linear-gradient(0deg, #4f39fa, #da62c4);
|
||||
--link-gradient: linear-gradient(45deg, #4f39fa, #da62c4 30%, var(--color-border) 60%);
|
||||
--night-sky-gradient: linear-gradient(
|
||||
0deg,
|
||||
#392362 -33%,
|
||||
#431f69 10%,
|
||||
#30216b 50%,
|
||||
#1f1638 100%
|
||||
);
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 0;
|
||||
transition: color 0.6s cubic-bezier(0.22, 1, 0.36, 1);
|
||||
}
|
||||
|
||||
h2 span {
|
||||
display: inline-block;
|
||||
transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 0.875em;
|
||||
border: 0.1em solid var(--color-border);
|
||||
border-radius: 4px;
|
||||
padding: 0.15em 0.25em;
|
||||
}
|
||||
|
||||
main {
|
||||
margin: auto;
|
||||
padding: 1em;
|
||||
max-width: 60ch;
|
||||
}
|
||||
|
||||
.text-gradient {
|
||||
font-weight: 900;
|
||||
background-image: var(--astro-gradient);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-size: 100% 200%;
|
||||
background-position-y: 100%;
|
||||
border-radius: 0.4rem;
|
||||
animation: pulse 4s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%,
|
||||
100% {
|
||||
background-position-y: 0%;
|
||||
}
|
||||
50% {
|
||||
background-position-y: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
.instructions {
|
||||
line-height: 1.8;
|
||||
margin-bottom: 2rem;
|
||||
background-image: var(--night-sky-gradient);
|
||||
padding: 1.5rem;
|
||||
border-radius: 0.4rem;
|
||||
color: var(--color-bg);
|
||||
}
|
||||
|
||||
.link-card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
|
||||
gap: 1rem;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.link-card {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
padding: 0.15rem;
|
||||
background-image: var(--link-gradient);
|
||||
background-size: 400%;
|
||||
border-radius: 0.5rem;
|
||||
background-position: 100%;
|
||||
transition: background-position 0.6s cubic-bezier(0.22, 1, 0.36, 1);
|
||||
}
|
||||
|
||||
.link-card > a {
|
||||
width: 100%;
|
||||
text-decoration: none;
|
||||
line-height: 1.4;
|
||||
padding: 1em 1.3em;
|
||||
border-radius: 0.35rem;
|
||||
color: var(--text-color);
|
||||
background-color: white;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.link-card:is(:hover, :focus-within) {
|
||||
background-position: 0;
|
||||
}
|
||||
|
||||
.link-card:is(:hover, :focus-within) h2 {
|
||||
color: #4f39fa;
|
||||
}
|
||||
|
||||
.link-card:is(:hover, :focus-within) h2 span {
|
||||
transform: translateX(2px);
|
||||
}
|
||||
|
||||
.heart {
|
||||
display: inline-block;
|
||||
color: #da62c4;
|
||||
animation: heartbeat 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes heartbeat {
|
||||
0%,
|
||||
50%,
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
5% {
|
||||
transform: scale(1.125);
|
||||
}
|
||||
10% {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
15% {
|
||||
transform: scale(1.25);
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base"
|
||||
}
|
|
@ -11,9 +11,9 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/alpinejs": "^0.3.0",
|
||||
"@astrojs/alpinejs": "^0.3.1",
|
||||
"@types/alpinejs": "^3.7.2",
|
||||
"alpinejs": "^3.12.3",
|
||||
"astro": "^3.1.4"
|
||||
"astro": "^3.2.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/lit": "^3.0.0",
|
||||
"@astrojs/lit": "^3.0.1",
|
||||
"@webcomponents/template-shadowroot": "^0.2.1",
|
||||
"astro": "^3.1.4",
|
||||
"astro": "^3.2.4",
|
||||
"lit": "^2.8.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,12 +11,12 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/preact": "^3.0.0",
|
||||
"@astrojs/react": "^3.0.2",
|
||||
"@astrojs/solid-js": "^3.0.1",
|
||||
"@astrojs/svelte": "^4.0.2",
|
||||
"@astrojs/vue": "^3.0.0",
|
||||
"astro": "^3.1.4",
|
||||
"@astrojs/preact": "^3.0.1",
|
||||
"@astrojs/react": "^3.0.3",
|
||||
"@astrojs/solid-js": "^3.0.2",
|
||||
"@astrojs/svelte": "^4.0.3",
|
||||
"@astrojs/vue": "^3.0.1",
|
||||
"astro": "^3.2.4",
|
||||
"preact": "^10.17.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/preact": "^3.0.0",
|
||||
"@astrojs/preact": "^3.0.1",
|
||||
"@preact/signals": "^1.2.1",
|
||||
"astro": "^3.1.4",
|
||||
"astro": "^3.2.4",
|
||||
"preact": "^10.17.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,10 +11,10 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/react": "^3.0.2",
|
||||
"@astrojs/react": "^3.0.3",
|
||||
"@types/react": "^18.2.21",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"astro": "^3.1.4",
|
||||
"astro": "^3.2.4",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/solid-js": "^3.0.1",
|
||||
"astro": "^3.1.4",
|
||||
"@astrojs/solid-js": "^3.0.2",
|
||||
"astro": "^3.2.4",
|
||||
"solid-js": "^1.7.11"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/svelte": "^4.0.2",
|
||||
"astro": "^3.1.4",
|
||||
"@astrojs/svelte": "^4.0.3",
|
||||
"astro": "^3.2.4",
|
||||
"svelte": "^4.2.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/vue": "^3.0.0",
|
||||
"astro": "^3.1.4",
|
||||
"@astrojs/vue": "^3.0.1",
|
||||
"astro": "^3.2.4",
|
||||
"vue": "^3.3.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/node": "^6.0.1",
|
||||
"astro": "^3.1.4"
|
||||
"@astrojs/node": "^6.0.3",
|
||||
"astro": "^3.2.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,9 +10,9 @@ export default function createIntegration(): AstroIntegration {
|
|||
// See the @astrojs/react integration for an example
|
||||
// https://github.com/withastro/astro/blob/main/packages/integrations/react/src/index.ts
|
||||
},
|
||||
'astro:build:setup': ({ config, updateConfig }) => {
|
||||
// See the @astrojs/netlify integration for an example
|
||||
// https://github.com/withastro/astro/blob/main/packages/integrations/netlify/src/integration-functions.ts
|
||||
'astro:build:setup': ({ pages, updateConfig }) => {
|
||||
// See the @astrojs/lit integration for an example
|
||||
// https://github.com/withastro/astro/blob/main/packages/integrations/lit/src/index.ts
|
||||
},
|
||||
'astro:build:done': ({ dir, routes }) => {
|
||||
// See the @astrojs/partytown integration for an example
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
],
|
||||
"scripts": {},
|
||||
"devDependencies": {
|
||||
"astro": "^3.1.4"
|
||||
"astro": "^3.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"astro": "^2.0.0-beta.0"
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
"server": "node dist/server/entry.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/node": "^6.0.1",
|
||||
"astro": "^3.1.4",
|
||||
"@astrojs/node": "^6.0.3",
|
||||
"astro": "^3.2.4",
|
||||
"html-minifier": "^4.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^3.1.4"
|
||||
"astro": "^3.2.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^3.1.4"
|
||||
"astro": "^3.2.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^3.1.4"
|
||||
"astro": "^3.2.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
"server": "node dist/server/entry.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/node": "^6.0.1",
|
||||
"@astrojs/svelte": "^4.0.2",
|
||||
"astro": "^3.1.4",
|
||||
"@astrojs/node": "^6.0.3",
|
||||
"@astrojs/svelte": "^4.0.3",
|
||||
"astro": "^3.2.4",
|
||||
"svelte": "^4.2.0"
|
||||
}
|
||||
}
|
||||
|
|
30
examples/view-transitions/README.md
Normal file
30
examples/view-transitions/README.md
Normal file
|
@ -0,0 +1,30 @@
|
|||
# Astro Movies View Transitions Demo
|
||||
|
||||
### 👉🏽 [Live Demo](https://astro-movies.pages.dev/)
|
||||
|
||||
![Screenshot](./screenshot.png)
|
||||
|
||||
## 🚀 Getting Started
|
||||
|
||||
1. Clone this repository and install dependencies with `npm install`.
|
||||
2. Start the project locally with npm run dev, or deploy it to your favorite server.
|
||||
3. Have fun! ✨
|
||||
|
||||
## 🧞 Commands
|
||||
|
||||
All commands are run from the root of the project, from a terminal:
|
||||
|
||||
| Command | Action |
|
||||
| :--------------------- | :----------------------------------------------- |
|
||||
| `npm install` | Installs dependencies |
|
||||
| `npm run dev` | Starts local dev server at `localhost:3000` |
|
||||
| `npm run build` | Build your production site to `./dist/` |
|
||||
| `npm run preview` | Preview your build locally, before deploying |
|
||||
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
|
||||
| `npm run astro --help` | Get help using the Astro CLI |
|
||||
|
||||
## 👀 Want to learn more?
|
||||
|
||||
Check out [Astro's documentation](https://docs.astro.build) or jump into their [Discord server](https://astro.build/chat).
|
||||
|
||||
You can also reach out to [Maxi on Twitter](https://twitter.com/charca).
|
15
examples/view-transitions/astro.config.mjs
Normal file
15
examples/view-transitions/astro.config.mjs
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import tailwind from '@astrojs/tailwind';
|
||||
import nodejs from '@astrojs/node';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [tailwind()],
|
||||
output: 'server',
|
||||
adapter: nodejs({ mode: 'standalone' }),
|
||||
vite: {
|
||||
define: {
|
||||
'process.env.TMDB_API_KEY': JSON.stringify(process.env.TMDB_API_KEY),
|
||||
},
|
||||
},
|
||||
});
|
17
examples/view-transitions/package.json
Normal file
17
examples/view-transitions/package.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "@example/view-transitions",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"start": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview",
|
||||
"astro": "astro"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/tailwind": "^5.0.2",
|
||||
"@astrojs/node": "^6.0.3",
|
||||
"astro": "^3.2.4"
|
||||
}
|
||||
}
|
BIN
examples/view-transitions/public/favicon.ico
Normal file
BIN
examples/view-transitions/public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
17
examples/view-transitions/src/components/Footer.astro
Normal file
17
examples/view-transitions/src/components/Footer.astro
Normal file
|
@ -0,0 +1,17 @@
|
|||
<footer class="border border-t border-gray-800">
|
||||
<div class="container mx-auto text-sm px-4 py-6">
|
||||
Made with ❤️ by <a
|
||||
href="https://www.twitter.com/charca"
|
||||
target="_blank"
|
||||
class="underline hover:text-gray-300">Maxi Ferreira</a
|
||||
> — Powered by <a
|
||||
href="https://astro.build"
|
||||
target="_blank"
|
||||
class="underline hover:text-gray-300">Astro</a
|
||||
> and <a
|
||||
href="https://www.themoviedb.org/documentation/api"
|
||||
target="_blank"
|
||||
class="underline hover:text-gray-300">TMDb API</a
|
||||
>.
|
||||
</div>
|
||||
</footer>
|
31
examples/view-transitions/src/components/MovieCard.astro
Normal file
31
examples/view-transitions/src/components/MovieCard.astro
Normal file
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
const { movie } = Astro.props;
|
||||
---
|
||||
|
||||
<div class="mt-8">
|
||||
<a href={`/movies/${movie.id}`}>
|
||||
<img
|
||||
src={`https://image.tmdb.org/t/p/w500${movie.poster_path}`}
|
||||
alt={`${movie.title} Poster`}
|
||||
class="thumbnail hover:opacity-75 transition ease-in-out duration-150"
|
||||
id={`movie-poster-${movie.id}`}
|
||||
transition:name={`poster-${movie.id}`}
|
||||
/>
|
||||
</a>
|
||||
<div class="mt-2">
|
||||
<a href={`/movies/${movie.id}`} class="text-lg mt-2 hover:text-gray-300">{movie.title}</a>
|
||||
<div class="flex items-center text-gray-400 text-sm mt-1">
|
||||
<svg class="fill-current text-orange-500 w-4" viewBox="0 0 24 24"
|
||||
><g data-name="Layer 2"
|
||||
><path
|
||||
d="M17.56 21a1 1 0 01-.46-.11L12 18.22l-5.1 2.67a1 1 0 01-1.45-1.06l1-5.63-4.12-4a1 1 0 01-.25-1 1 1 0 01.81-.68l5.7-.83 2.51-5.13a1 1 0 011.8 0l2.54 5.12 5.7.83a1 1 0 01.81.68 1 1 0 01-.25 1l-4.12 4 1 5.63a1 1 0 01-.4 1 1 1 0 01-.62.18z"
|
||||
data-name="star"></path></g
|
||||
></svg
|
||||
>
|
||||
<span class="ml-1">{movie.vote_average}</span>
|
||||
<span class="mx-2">|</span>
|
||||
<span>{movie.release_date}</span>
|
||||
</div>
|
||||
<div class="text-gray-400 text-sm">{movie.genres}</div>
|
||||
</div>
|
||||
</div>
|
125
examples/view-transitions/src/components/MovieDetails.astro
Normal file
125
examples/view-transitions/src/components/MovieDetails.astro
Normal file
|
@ -0,0 +1,125 @@
|
|||
---
|
||||
const { data } = Astro.props;
|
||||
|
||||
const movie = {
|
||||
...data,
|
||||
poster_path: data.poster_path
|
||||
? 'https://image.tmdb.org/t/p/w500/' + data.poster_path
|
||||
: 'https://via.placeholder.com/500x750',
|
||||
vote_average: (data.vote_average * 10).toFixed(2) + '%',
|
||||
release_date: new Date(data.release_date).toLocaleDateString('en-us', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
}),
|
||||
genres: data.genres.map((g: any) => g.name).join(', '),
|
||||
crew: data.credits.crew.slice(0, 3),
|
||||
cast: data.credits.cast.slice(0, 5).map((c: any) => ({
|
||||
...c,
|
||||
profile_path: c.profile_path
|
||||
? 'https://image.tmdb.org/t/p/w300/' + c.profile_path
|
||||
: 'https://via.placeholder.com/300x450',
|
||||
})),
|
||||
images: data.images.backdrops.slice(0, 9),
|
||||
};
|
||||
---
|
||||
|
||||
<div class="movie-info border-b border-gray-800">
|
||||
<div class="container mx-auto px-4 py-16 flex flex-col md:flex-row">
|
||||
<div class="flex-none">
|
||||
<img
|
||||
src={movie.poster_path}
|
||||
alt={`${movie.title} Poster`}
|
||||
class="movie-poster w-64 lg:w-96"
|
||||
id="movie-poster"
|
||||
transition:name={`poster-${movie.id}`}
|
||||
/>
|
||||
</div>
|
||||
<div class="md:ml-24">
|
||||
<h2 class="text-4xl mt-4 md:mt-0 mb-2 font-semibold">{movie.title}</h2>
|
||||
<div class="flex flex-wrap items-center text-gray-400 text-sm">
|
||||
<svg class="fill-current text-orange-500 w-4" viewBox="0 0 24 24"
|
||||
><g data-name="Layer 2"
|
||||
><path
|
||||
d="M17.56 21a1 1 0 01-.46-.11L12 18.22l-5.1 2.67a1 1 0 01-1.45-1.06l1-5.63-4.12-4a1 1 0 01-.25-1 1 1 0 01.81-.68l5.7-.83 2.51-5.13a1 1 0 011.8 0l2.54 5.12 5.7.83a1 1 0 01.81.68 1 1 0 01-.25 1l-4.12 4 1 5.63a1 1 0 01-.4 1 1 1 0 01-.62.18z"
|
||||
data-name="star"></path></g
|
||||
></svg
|
||||
>
|
||||
<span class="ml-1">{movie.vote_average}</span>
|
||||
<span class="mx-2">|</span>
|
||||
<span>{movie.release_date}</span>
|
||||
<span class="mx-2">|</span>
|
||||
<span>{movie.genres}</span>
|
||||
</div>
|
||||
|
||||
<p class="text-gray-300 mt-8">
|
||||
{movie.overview}
|
||||
</p>
|
||||
|
||||
<div class="mt-12">
|
||||
<h4 class="text-white font-semibold">Featured Crew</h4>
|
||||
<div class="flex mt-4">
|
||||
{
|
||||
movie.crew.map((crew: any) => (
|
||||
<div class="mr-8">
|
||||
<div>{crew.name}</div>
|
||||
<div class="text-gray-400 text-sm">{crew.job}</div>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end movie-info -->
|
||||
|
||||
<div class="movie-cast border-b border-gray-800">
|
||||
<div class="container mx-auto px-4 py-16">
|
||||
<h2 class="text-4xl font-semibold">Cast</h2>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-8">
|
||||
{
|
||||
movie.cast.map((cast: any) => (
|
||||
<div class="mt-8">
|
||||
<span>
|
||||
<img
|
||||
id={`person-photo-${cast.id}`}
|
||||
src={cast.profile_path}
|
||||
alt={cast.name}
|
||||
class="thumbnail hover:opacity-75 transition ease-in-out duration-150"
|
||||
/>
|
||||
</span>
|
||||
<div class="mt-2">
|
||||
<span class="text-lg mt-2 hover:text-gray:300">{cast.name}</span>
|
||||
<div class="text-sm text-gray-400">{cast.character}</div>
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end movie-cast -->
|
||||
|
||||
<div class="movie-images">
|
||||
<div class="container mx-auto px-4 py-16">
|
||||
<h2 class="text-4xl font-semibold">Images</h2>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-8">
|
||||
{
|
||||
movie.images.map((image: any) => (
|
||||
<div class="mt-8">
|
||||
<span>
|
||||
<img
|
||||
src={`https://image.tmdb.org/t/p/w500${image.file_path}`}
|
||||
loading="lazy"
|
||||
alt={movie.name}
|
||||
class="hover:opacity-75 transition ease-in-out duration-150"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end movie-images -->
|
15
examples/view-transitions/src/components/MovieList.astro
Normal file
15
examples/view-transitions/src/components/MovieList.astro
Normal file
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
import MovieCard from './MovieCard.astro';
|
||||
import movies from '../popular-movies.json';
|
||||
const popularMovies = movies.results;
|
||||
---
|
||||
|
||||
<div class="container mx-auto px-4 pt-16 mb-16">
|
||||
<div class="popular-movies">
|
||||
<h2 class="uppercase tracking-wider text-orange-500 text-lg font-semibold">Popular Movies</h2>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-8">
|
||||
{popularMovies.map((movie) => <MovieCard movie={movie} />)}
|
||||
</div>
|
||||
</div>
|
||||
<!-- end pouplar-movies -->
|
||||
</div>
|
18
examples/view-transitions/src/components/Nav.astro
Normal file
18
examples/view-transitions/src/components/Nav.astro
Normal file
|
@ -0,0 +1,18 @@
|
|||
<nav class="nav border-b border-gray-800 sticky top-0 z-30 bg-gray-900">
|
||||
<div
|
||||
class="container mx-auto px-4 flex flex-col md:flex-row items-center justify-between px-4 py-6"
|
||||
>
|
||||
<ul class="flex flex-col md:flex-row items-center">
|
||||
<li>
|
||||
<a href="/" class="flex items-center font-bold text-xl">
|
||||
<span>Movies</span>
|
||||
|
||||
<span class="text-orange-500">List</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="md:ml-16 mt-3 md:mt-0">
|
||||
<a href="/" class="hover:text-gray-300">Movies</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
12
examples/view-transitions/src/content/config.ts
Normal file
12
examples/view-transitions/src/content/config.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { z, defineCollection } from 'astro:content';
|
||||
|
||||
const movies = defineCollection({
|
||||
type: 'data',
|
||||
schema: z.object({
|
||||
data: z.any(),
|
||||
}),
|
||||
});
|
||||
|
||||
// Expose your defined collection to Astro
|
||||
// with the `collections` export
|
||||
export const collections = { movies };
|
4056
examples/view-transitions/src/content/movies/1008042.json
Normal file
4056
examples/view-transitions/src/content/movies/1008042.json
Normal file
File diff suppressed because it is too large
Load diff
345
examples/view-transitions/src/content/movies/1085218.json
Normal file
345
examples/view-transitions/src/content/movies/1085218.json
Normal file
|
@ -0,0 +1,345 @@
|
|||
{
|
||||
"data": {
|
||||
"adult": false,
|
||||
"backdrop_path": "/e8FyMnifoN5BMuRFE97fS1lJZ6S.jpg",
|
||||
"belongs_to_collection": {
|
||||
"id": 1153632,
|
||||
"name": "Darkland Collection",
|
||||
"poster_path": null,
|
||||
"backdrop_path": null
|
||||
},
|
||||
"budget": 0,
|
||||
"genres": [
|
||||
{ "id": 28, "name": "Action" },
|
||||
{ "id": 53, "name": "Thriller" }
|
||||
],
|
||||
"homepage": "",
|
||||
"id": 1085218,
|
||||
"imdb_id": "tt20204996",
|
||||
"original_language": "da",
|
||||
"original_title": "Underverden 2",
|
||||
"overview": "Seven years ago, Zaid went to war against the Copenhagen underworld to avenge his dead brother. His identity as a respected doctor of cardiology and life as a family man is but a fading dream, and in prison Zaid suffers the loss of his son Noah, whom he barely knows. When a police agent approaches Zaid and offers him a deal to be released in exchange for infiltrating the Copenhagen underworld, he sees his chance to reclaim the remnants of the family life he left behind. But everything has a price, and Zaid realizes that he has now seriously endangered his son's life. After all, once you become part of the underworld, is there any way out?",
|
||||
"popularity": 524.476,
|
||||
"poster_path": "/c8B4DsVcFVDLVmbpHMHU3RjLNAV.jpg",
|
||||
"production_companies": [
|
||||
{
|
||||
"id": 64293,
|
||||
"logo_path": "/lbYGnir9KeY8NyQZrUFZbf3QDej.png",
|
||||
"name": "Profile Pictures",
|
||||
"origin_country": "DK"
|
||||
}
|
||||
],
|
||||
"production_countries": [{ "iso_3166_1": "DK", "name": "Denmark" }],
|
||||
"release_date": "2023-04-13",
|
||||
"revenue": 0,
|
||||
"runtime": 110,
|
||||
"spoken_languages": [
|
||||
{ "english_name": "Arabic", "iso_639_1": "ar", "name": "العربية" },
|
||||
{ "english_name": "Danish", "iso_639_1": "da", "name": "Dansk" }
|
||||
],
|
||||
"status": "Released",
|
||||
"tagline": "",
|
||||
"title": "Darkland: The Return",
|
||||
"video": false,
|
||||
"vote_average": 6.32,
|
||||
"vote_count": 64,
|
||||
"credits": {
|
||||
"cast": [
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 234907,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Dar Salim",
|
||||
"original_name": "Dar Salim",
|
||||
"popularity": 16.442,
|
||||
"profile_path": "/oTYCqdF6nfZTsvt1fbypi54ydI.jpg",
|
||||
"cast_id": 1,
|
||||
"character": "Zaid",
|
||||
"credit_id": "6429b39701b1ca0113cc2840",
|
||||
"order": 0
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 90514,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Birgitte Hjort Sørensen",
|
||||
"original_name": "Birgitte Hjort Sørensen",
|
||||
"popularity": 9.741,
|
||||
"profile_path": "/uPak0FlCPdsc9B1pw4bBkuaMLXT.jpg",
|
||||
"cast_id": 2,
|
||||
"character": "Helle",
|
||||
"credit_id": "6429b3d101b1ca00d5e8507e",
|
||||
"order": 1
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 32682,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Stine Fischer Christensen",
|
||||
"original_name": "Stine Fischer Christensen",
|
||||
"popularity": 3.87,
|
||||
"profile_path": "/6MYODCa28L1IzfhcYTUZUYThoF2.jpg",
|
||||
"cast_id": 3,
|
||||
"character": "Stine",
|
||||
"credit_id": "6429b42c9cc67b05796bcdcc",
|
||||
"order": 2
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 1178394,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Henrik Vestergaard",
|
||||
"original_name": "Henrik Vestergaard",
|
||||
"popularity": 0.766,
|
||||
"profile_path": "/1Opgkbdkyt1x5iEOLgV3VJ29ZpA.jpg",
|
||||
"cast_id": 4,
|
||||
"character": "Lars",
|
||||
"credit_id": "6429b45401b1ca0097fdfb0f",
|
||||
"order": 3
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 3236472,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Soheil Bavi",
|
||||
"original_name": "Soheil Bavi",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"cast_id": 5,
|
||||
"character": "Muhdir",
|
||||
"credit_id": "6429b4828de0ae00b65514de",
|
||||
"order": 4
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 3991209,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Jack Pedersen",
|
||||
"original_name": "Jack Pedersen",
|
||||
"popularity": 0.648,
|
||||
"profile_path": null,
|
||||
"cast_id": 6,
|
||||
"character": "Shahin",
|
||||
"credit_id": "6429b4f4ac8e6b00d32aa4eb",
|
||||
"order": 5
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 2595279,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Mohamed Djeziri",
|
||||
"original_name": "Mohamed Djeziri",
|
||||
"popularity": 0.84,
|
||||
"profile_path": null,
|
||||
"cast_id": 11,
|
||||
"character": "",
|
||||
"credit_id": "64c14243871b340101072cf6",
|
||||
"order": 6
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 4188787,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Abud Mustafa",
|
||||
"original_name": "Abud Mustafa",
|
||||
"popularity": 0.98,
|
||||
"profile_path": null,
|
||||
"cast_id": 12,
|
||||
"character": "",
|
||||
"credit_id": "64c6c269db8a0000e3286594",
|
||||
"order": 7
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 4188788,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Ahmad Ayman",
|
||||
"original_name": "Ahmad Ayman",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"cast_id": 13,
|
||||
"character": "",
|
||||
"credit_id": "64c6c27f63aad20209a58505",
|
||||
"order": 8
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 4188789,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Sebastian Nørgaard",
|
||||
"original_name": "Sebastian Nørgaard",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"cast_id": 14,
|
||||
"character": "",
|
||||
"credit_id": "64c6c298db8a0000e32865ab",
|
||||
"order": 9
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 4188791,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Hamed \"Baloosh\" Balosha",
|
||||
"original_name": "Hamed \"Baloosh\" Balosha",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"cast_id": 15,
|
||||
"character": "",
|
||||
"credit_id": "64c6c2a3eec5b500ff5262cb",
|
||||
"order": 10
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 3549264,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Noah Carter",
|
||||
"original_name": "Noah Carter",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"cast_id": 16,
|
||||
"character": "",
|
||||
"credit_id": "64c6c2b0cadb6b00c82a2404",
|
||||
"order": 11
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 4188792,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Asgar Hansen",
|
||||
"original_name": "Asgar Hansen",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"cast_id": 17,
|
||||
"character": "",
|
||||
"credit_id": "64c6c2bc30f79c00c781a97c",
|
||||
"order": 12
|
||||
}
|
||||
],
|
||||
"crew": [
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 1183636,
|
||||
"known_for_department": "Directing",
|
||||
"name": "Fenar Ahmad",
|
||||
"original_name": "Fenar Ahmad",
|
||||
"popularity": 1.646,
|
||||
"profile_path": null,
|
||||
"credit_id": "6429b673c04429026b13a94a",
|
||||
"department": "Directing",
|
||||
"job": "Director"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 1183636,
|
||||
"known_for_department": "Directing",
|
||||
"name": "Fenar Ahmad",
|
||||
"original_name": "Fenar Ahmad",
|
||||
"popularity": 1.646,
|
||||
"profile_path": null,
|
||||
"credit_id": "642ed070158c8501263ad755",
|
||||
"department": "Writing",
|
||||
"job": "Writer"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 2405913,
|
||||
"known_for_department": "Directing",
|
||||
"name": "Behrouz Bigdeli",
|
||||
"original_name": "Behrouz Bigdeli",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"credit_id": "642ed08058361b00f2f13338",
|
||||
"department": "Writing",
|
||||
"job": "Writer"
|
||||
}
|
||||
]
|
||||
},
|
||||
"videos": { "results": [] },
|
||||
"images": {
|
||||
"backdrops": [
|
||||
{
|
||||
"aspect_ratio": 1.778,
|
||||
"height": 1080,
|
||||
"iso_639_1": "da",
|
||||
"file_path": "/4wVFtesa5YEWuAUHRcxoCN1Y1uN.jpg",
|
||||
"vote_average": 5.172,
|
||||
"vote_count": 1,
|
||||
"width": 1920
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 1.778,
|
||||
"height": 720,
|
||||
"iso_639_1": null,
|
||||
"file_path": "/e8FyMnifoN5BMuRFE97fS1lJZ6S.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1280
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 1.778,
|
||||
"height": 1116,
|
||||
"iso_639_1": null,
|
||||
"file_path": "/tDT465D3JZiABgz2uug9jCgOUlw.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1984
|
||||
}
|
||||
],
|
||||
"logos": [],
|
||||
"posters": [
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "da",
|
||||
"file_path": "/A8EPXv3SV9qiNCIttIM4ezJRmhW.jpg",
|
||||
"vote_average": 5.312,
|
||||
"vote_count": 1,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 1200,
|
||||
"iso_639_1": "da",
|
||||
"file_path": "/A0cxUcMWBruPknr5ZSePIYFfe7z.jpg",
|
||||
"vote_average": 5.172,
|
||||
"vote_count": 1,
|
||||
"width": 800
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.7,
|
||||
"height": 2834,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/c8B4DsVcFVDLVmbpHMHU3RjLNAV.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1984
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.7,
|
||||
"height": 2834,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/my1ve6HKygOVNYJBi3A0pRpPm2l.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1984
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
1547
examples/view-transitions/src/content/movies/1880.json
Normal file
1547
examples/view-transitions/src/content/movies/1880.json
Normal file
File diff suppressed because it is too large
Load diff
5708
examples/view-transitions/src/content/movies/298618.json
Normal file
5708
examples/view-transitions/src/content/movies/298618.json
Normal file
File diff suppressed because it is too large
Load diff
7685
examples/view-transitions/src/content/movies/335977.json
Normal file
7685
examples/view-transitions/src/content/movies/335977.json
Normal file
File diff suppressed because it is too large
Load diff
8064
examples/view-transitions/src/content/movies/346698.json
Normal file
8064
examples/view-transitions/src/content/movies/346698.json
Normal file
File diff suppressed because it is too large
Load diff
6835
examples/view-transitions/src/content/movies/385687.json
Normal file
6835
examples/view-transitions/src/content/movies/385687.json
Normal file
File diff suppressed because it is too large
Load diff
4628
examples/view-transitions/src/content/movies/565770.json
Normal file
4628
examples/view-transitions/src/content/movies/565770.json
Normal file
File diff suppressed because it is too large
Load diff
13946
examples/view-transitions/src/content/movies/569094.json
Normal file
13946
examples/view-transitions/src/content/movies/569094.json
Normal file
File diff suppressed because it is too large
Load diff
1141
examples/view-transitions/src/content/movies/606403.json
Normal file
1141
examples/view-transitions/src/content/movies/606403.json
Normal file
File diff suppressed because it is too large
Load diff
4687
examples/view-transitions/src/content/movies/614930.json
Normal file
4687
examples/view-transitions/src/content/movies/614930.json
Normal file
File diff suppressed because it is too large
Load diff
3698
examples/view-transitions/src/content/movies/615656.json
Normal file
3698
examples/view-transitions/src/content/movies/615656.json
Normal file
File diff suppressed because it is too large
Load diff
4848
examples/view-transitions/src/content/movies/667538.json
Normal file
4848
examples/view-transitions/src/content/movies/667538.json
Normal file
File diff suppressed because it is too large
Load diff
1226
examples/view-transitions/src/content/movies/678512.json
Normal file
1226
examples/view-transitions/src/content/movies/678512.json
Normal file
File diff suppressed because it is too large
Load diff
2546
examples/view-transitions/src/content/movies/717930.json
Normal file
2546
examples/view-transitions/src/content/movies/717930.json
Normal file
File diff suppressed because it is too large
Load diff
2181
examples/view-transitions/src/content/movies/762430.json
Normal file
2181
examples/view-transitions/src/content/movies/762430.json
Normal file
File diff suppressed because it is too large
Load diff
856
examples/view-transitions/src/content/movies/820525.json
Normal file
856
examples/view-transitions/src/content/movies/820525.json
Normal file
|
@ -0,0 +1,856 @@
|
|||
{
|
||||
"data": {
|
||||
"adult": false,
|
||||
"backdrop_path": "/jkKVLzLWjSvTnc84VzeljhSy6j8.jpg",
|
||||
"belongs_to_collection": {
|
||||
"id": 702624,
|
||||
"name": "After Collection",
|
||||
"poster_path": "/250ewaLutOJXqBBqMKxCHD1KpCL.jpg",
|
||||
"backdrop_path": "/zZTy8G3sEVZNv0yGssgc7DvPUQJ.jpg"
|
||||
},
|
||||
"budget": 14000000,
|
||||
"genres": [
|
||||
{ "id": 10749, "name": "Romance" },
|
||||
{ "id": 18, "name": "Drama" }
|
||||
],
|
||||
"homepage": "",
|
||||
"id": 820525,
|
||||
"imdb_id": "tt15334488",
|
||||
"original_language": "en",
|
||||
"original_title": "After Everything",
|
||||
"overview": "Besieged by writer’s block and the crushing breakup with Tessa, Hardin travels to Portugal in search of a woman he wronged in the past – and to find himself. Hoping to win back Tessa, he realizes he needs to change his ways before he can make the ultimate commitment.",
|
||||
"popularity": 650.272,
|
||||
"poster_path": "/gZLGCibvFY4zmt8sWUZcbBTHRtk.jpg",
|
||||
"production_companies": [
|
||||
{
|
||||
"id": 6626,
|
||||
"logo_path": "/A1BnMoWjzjOrjzpWimyBQkf84mS.png",
|
||||
"name": "Voltage Pictures",
|
||||
"origin_country": "US"
|
||||
},
|
||||
{
|
||||
"id": 107108,
|
||||
"logo_path": "/5mxc7uNtFOZm2ly0BxixxGPvPlb.png",
|
||||
"name": "Wattpad",
|
||||
"origin_country": "US"
|
||||
}
|
||||
],
|
||||
"production_countries": [{ "iso_3166_1": "US", "name": "United States of America" }],
|
||||
"release_date": "2023-09-13",
|
||||
"revenue": 962741,
|
||||
"runtime": 93,
|
||||
"spoken_languages": [
|
||||
{ "english_name": "English", "iso_639_1": "en", "name": "English" },
|
||||
{ "english_name": "Portuguese", "iso_639_1": "pt", "name": "Português" }
|
||||
],
|
||||
"status": "Released",
|
||||
"tagline": "",
|
||||
"title": "After Everything",
|
||||
"video": false,
|
||||
"vote_average": 6.407,
|
||||
"vote_count": 27,
|
||||
"credits": {
|
||||
"cast": [
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 1114487,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Hero Fiennes Tiffin",
|
||||
"original_name": "Hero Fiennes Tiffin",
|
||||
"popularity": 15.891,
|
||||
"profile_path": "/6zMrrZvOMH6uGwEFoK0Uo8sZvxL.jpg",
|
||||
"cast_id": 5,
|
||||
"character": "Hardin Scott",
|
||||
"credit_id": "60d374f40e64af0046370008",
|
||||
"order": 0
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 1694711,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Mimi Keene",
|
||||
"original_name": "Mimi Keene",
|
||||
"popularity": 7.403,
|
||||
"profile_path": "/7bUgfaycm0f6PgEn3eLo8oANByO.jpg",
|
||||
"cast_id": 24,
|
||||
"character": "Nathalie",
|
||||
"credit_id": "6441b4e7651fcf02fb9c2851",
|
||||
"order": 1
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 2849483,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Benjamin Mascolo",
|
||||
"original_name": "Benjamin Mascolo",
|
||||
"popularity": 4.235,
|
||||
"profile_path": "/zkKiB05KRFCIQdMVnseQlatMLRq.jpg",
|
||||
"cast_id": 23,
|
||||
"character": "Sebastian",
|
||||
"credit_id": "6441b4cab3f6f5055a9d8f4a",
|
||||
"order": 2
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 20805,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Louise Lombard",
|
||||
"original_name": "Louise Lombard",
|
||||
"popularity": 17.846,
|
||||
"profile_path": "/6znYbOI2Z8PfzZ6p9jHG5QdAeb2.jpg",
|
||||
"cast_id": 22,
|
||||
"character": "Trish Daniels",
|
||||
"credit_id": "63a8788e0f21c6007871434e",
|
||||
"order": 3
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 32203,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Stephen Moyer",
|
||||
"original_name": "Stephen Moyer",
|
||||
"popularity": 12.55,
|
||||
"profile_path": "/xprwOCXa2cNkjhrGtcJp0VfJMlZ.jpg",
|
||||
"cast_id": 7,
|
||||
"character": "Christian Vance",
|
||||
"credit_id": "63a638291f748b008a0a1614",
|
||||
"order": 4
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 20373,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Arielle Kebbel",
|
||||
"original_name": "Arielle Kebbel",
|
||||
"popularity": 23.827,
|
||||
"profile_path": "/dmYiAeWoeVsRdT4UBBGuW9gBfjQ.jpg",
|
||||
"cast_id": 6,
|
||||
"character": "Kim Vance",
|
||||
"credit_id": "63a638191f748b007cc00f2f",
|
||||
"order": 5
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 3009693,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Jessica Webber",
|
||||
"original_name": "Jessica Webber",
|
||||
"popularity": 1.15,
|
||||
"profile_path": null,
|
||||
"cast_id": 20,
|
||||
"character": "Maddy",
|
||||
"credit_id": "63a64fa98a84d200b4ce9858",
|
||||
"order": 6
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 3069742,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Cora Kirk",
|
||||
"original_name": "Cora Kirk",
|
||||
"popularity": 1.404,
|
||||
"profile_path": "/4av80vVFZSBuKJyzXqEXLE8Vftc.jpg",
|
||||
"cast_id": 21,
|
||||
"character": "Freya",
|
||||
"credit_id": "63a64fb1eb093200a0c1594c",
|
||||
"order": 7
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 2173697,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Rosa Escoda",
|
||||
"original_name": "Rosa Escoda",
|
||||
"popularity": 4.382,
|
||||
"profile_path": "/bnGlICypCtpuiKe5mHCnijESI3W.jpg",
|
||||
"cast_id": 27,
|
||||
"character": "Kat",
|
||||
"credit_id": "6503cbc1efea7a00e036e0f1",
|
||||
"order": 8
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 2677100,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Ella Martine",
|
||||
"original_name": "Ella Martine",
|
||||
"popularity": 0.6,
|
||||
"profile_path": "/d9uZ2tqibHTno0ZKPUc9FZNXhTn.jpg",
|
||||
"cast_id": 28,
|
||||
"character": "Naomi",
|
||||
"credit_id": "6503cbd7e0ca7f010deb819c",
|
||||
"order": 9
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 2026999,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Laura Dutra",
|
||||
"original_name": "Laura Dutra",
|
||||
"popularity": 1.8,
|
||||
"profile_path": "/ipSilYFln0N3UdiL3eboTv8XWS1.jpg",
|
||||
"cast_id": 29,
|
||||
"character": "Paloma",
|
||||
"credit_id": "6503cbedefea7a00aad915a0",
|
||||
"order": 10
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 2035329,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Chance Perdomo",
|
||||
"original_name": "Chance Perdomo",
|
||||
"popularity": 9.723,
|
||||
"profile_path": "/xRRDtdHhTewrKMj5cpcmEkPNmuP.jpg",
|
||||
"cast_id": 30,
|
||||
"character": "Landon Scott",
|
||||
"credit_id": "6503cbfed7dcd20139cc9553",
|
||||
"order": 11
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 142115,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Kiana Madeira",
|
||||
"original_name": "Kiana Madeira",
|
||||
"popularity": 19.805,
|
||||
"profile_path": "/HgCI95xnSZJaE18d15n7PykOU7.jpg",
|
||||
"cast_id": 31,
|
||||
"character": "Nora",
|
||||
"credit_id": "6503cc206a2227011a7c6353",
|
||||
"order": 12
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 20960,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Rob Estes",
|
||||
"original_name": "Rob Estes",
|
||||
"popularity": 9.434,
|
||||
"profile_path": "/b24y5Tv4A8DUjkfYpJ1l1qpkhyv.jpg",
|
||||
"cast_id": 32,
|
||||
"character": "Ken Scott",
|
||||
"credit_id": "6503cc31efea7a0137d3de3b",
|
||||
"order": 13
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 20373,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Arielle Kebbel",
|
||||
"original_name": "Arielle Kebbel",
|
||||
"popularity": 23.827,
|
||||
"profile_path": "/dmYiAeWoeVsRdT4UBBGuW9gBfjQ.jpg",
|
||||
"cast_id": 33,
|
||||
"character": "Kimberley",
|
||||
"credit_id": "6503cc596a222700abaa07d9",
|
||||
"order": 14
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 86653,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Carter Jenkins",
|
||||
"original_name": "Carter Jenkins",
|
||||
"popularity": 5.084,
|
||||
"profile_path": "/fGVndWC3hgwK1uVrhiyzTUyIaxW.jpg",
|
||||
"cast_id": 34,
|
||||
"character": "Robert Freeman",
|
||||
"credit_id": "6503cc65ffc9de0edf625db1",
|
||||
"order": 15
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 1910292,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Ana Ivanova",
|
||||
"original_name": "Ana Ivanova",
|
||||
"popularity": 1.307,
|
||||
"profile_path": "/kT9AL9N1zwi4gksDPdLXGAThbpx.jpg",
|
||||
"cast_id": 35,
|
||||
"character": "Emery",
|
||||
"credit_id": "6503cc95efea7a00c3986356",
|
||||
"order": 16
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 2916706,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Anton Kottas",
|
||||
"original_name": "Anton Kottas",
|
||||
"popularity": 3.44,
|
||||
"profile_path": "/trj5wj5Y6Tvj649tbn1a4IG6YfG.jpg",
|
||||
"cast_id": 36,
|
||||
"character": "Smith",
|
||||
"credit_id": "6503cca5ffc9de0ee20aaf80",
|
||||
"order": 17
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 1753914,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Josephine Langford",
|
||||
"original_name": "Josephine Langford",
|
||||
"popularity": 27.865,
|
||||
"profile_path": "/8Fj1UIFRJA0B5Zo22KwML5d3Mr3.jpg",
|
||||
"cast_id": 39,
|
||||
"character": "Tessa Young",
|
||||
"credit_id": "650a7334cadb6b00e11f6961",
|
||||
"order": 18
|
||||
}
|
||||
],
|
||||
"crew": [
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 20739,
|
||||
"known_for_department": "Directing",
|
||||
"name": "Adam Shankman",
|
||||
"original_name": "Adam Shankman",
|
||||
"popularity": 8.011,
|
||||
"profile_path": "/zZmZgVp5OTU2eSMCDuOXGlQ4fBR.jpg",
|
||||
"credit_id": "65072f3b42d8a5011bd6f839",
|
||||
"department": "Directing",
|
||||
"job": "Director"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 20742,
|
||||
"known_for_department": "Production",
|
||||
"name": "Jennifer Gibgot",
|
||||
"original_name": "Jennifer Gibgot",
|
||||
"popularity": 1.159,
|
||||
"profile_path": null,
|
||||
"credit_id": "63a64f171108a800bab73fcd",
|
||||
"department": "Production",
|
||||
"job": "Producer"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 46088,
|
||||
"known_for_department": "Production",
|
||||
"name": "Mark Canton",
|
||||
"original_name": "Mark Canton",
|
||||
"popularity": 2.299,
|
||||
"profile_path": "/7OiY4eak3DztX0lSj4cbmKLQuaj.jpg",
|
||||
"credit_id": "63a64f03907f2600aa7262a1",
|
||||
"department": "Production",
|
||||
"job": "Producer"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 61921,
|
||||
"known_for_department": "Production",
|
||||
"name": "Courtney Solomon",
|
||||
"original_name": "Courtney Solomon",
|
||||
"popularity": 2.006,
|
||||
"profile_path": "/xujLAPgpM1JXLqE0X4mWVrPTmqd.jpg",
|
||||
"credit_id": "63a64f35907f2600da9a63bf",
|
||||
"department": "Production",
|
||||
"job": "Producer"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 1031200,
|
||||
"known_for_department": "Production",
|
||||
"name": "Nicolas Chartier",
|
||||
"original_name": "Nicolas Chartier",
|
||||
"popularity": 1.901,
|
||||
"profile_path": "/59ptYCph60CtAtLmWuC9dASHhsp.jpg",
|
||||
"credit_id": "63a64f0d1f748b007cc01cfd",
|
||||
"department": "Production",
|
||||
"job": "Producer"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 1179667,
|
||||
"known_for_department": "Lighting",
|
||||
"name": "Diego Moyano",
|
||||
"original_name": "Diego Moyano",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"credit_id": "63a64f908a84d200d9c3b03a",
|
||||
"department": "Lighting",
|
||||
"job": "Gaffer"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 1193192,
|
||||
"known_for_department": "Production",
|
||||
"name": "Carolyn McLeod",
|
||||
"original_name": "Carolyn McLeod",
|
||||
"popularity": 0.612,
|
||||
"profile_path": null,
|
||||
"credit_id": "63a64f7404b596007d427d31",
|
||||
"department": "Production",
|
||||
"job": "Casting"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 1448492,
|
||||
"known_for_department": "Directing",
|
||||
"name": "Castille Landon",
|
||||
"original_name": "Castille Landon",
|
||||
"popularity": 5.18,
|
||||
"profile_path": "/s1oXtmqyG9X0uDfiU5HidPB6BJx.jpg",
|
||||
"credit_id": "645009ff52dc7f02dddb5ed5",
|
||||
"department": "Writing",
|
||||
"job": "Screenplay"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 1540619,
|
||||
"known_for_department": "Camera",
|
||||
"name": "Joshua Reis",
|
||||
"original_name": "Joshua Reis",
|
||||
"popularity": 0.984,
|
||||
"profile_path": null,
|
||||
"credit_id": "63a64f681108a800c60a4d19",
|
||||
"department": "Camera",
|
||||
"job": "Director of Photography"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 1551998,
|
||||
"known_for_department": "Production",
|
||||
"name": "Brian Pitt",
|
||||
"original_name": "Brian Pitt",
|
||||
"popularity": 2.997,
|
||||
"profile_path": null,
|
||||
"credit_id": "63a64f2a04b59600918423ea",
|
||||
"department": "Production",
|
||||
"job": "Producer"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 1552003,
|
||||
"known_for_department": "Production",
|
||||
"name": "David Shojai",
|
||||
"original_name": "David Shojai",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"credit_id": "63a64f592b8a43007dddfc26",
|
||||
"department": "Production",
|
||||
"job": "Co-Producer"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 1664826,
|
||||
"known_for_department": "Writing",
|
||||
"name": "Anna Todd",
|
||||
"original_name": "Anna Todd",
|
||||
"popularity": 2.633,
|
||||
"profile_path": "/b0L0Hicos8ZeEXt96Jf9wDed8FS.jpg",
|
||||
"credit_id": "6450089f2fccee02e4cebc26",
|
||||
"department": "Writing",
|
||||
"job": "Novel"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 3032242,
|
||||
"known_for_department": "Art",
|
||||
"name": "Alexandra Tibbe",
|
||||
"original_name": "Alexandra Tibbe",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"credit_id": "63a64f812b8a4300b60617fd",
|
||||
"department": "Art",
|
||||
"job": "Set Decoration"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 3055946,
|
||||
"known_for_department": "Production",
|
||||
"name": "Aron Levitz",
|
||||
"original_name": "Aron Levitz",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"credit_id": "63a64f211f748b00826608cc",
|
||||
"department": "Production",
|
||||
"job": "Producer"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 3216486,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Taylor Conrod",
|
||||
"original_name": "Taylor Conrod",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"credit_id": "63a64f4c04b596007d427cfc",
|
||||
"department": "Production",
|
||||
"job": "Co-Producer"
|
||||
}
|
||||
]
|
||||
},
|
||||
"videos": {
|
||||
"results": [
|
||||
{
|
||||
"iso_639_1": "en",
|
||||
"iso_3166_1": "US",
|
||||
"name": "Official Trailer",
|
||||
"key": "NsmopvKNSE4",
|
||||
"site": "YouTube",
|
||||
"size": 1080,
|
||||
"type": "Trailer",
|
||||
"official": true,
|
||||
"published_at": "2023-05-01T12:00:05.000Z",
|
||||
"id": "64bd958d0ed2ab00c5e3af6a"
|
||||
},
|
||||
{
|
||||
"iso_639_1": "en",
|
||||
"iso_3166_1": "US",
|
||||
"name": "Hessa (Official Clip)",
|
||||
"key": "iVg7CDtG3MQ",
|
||||
"site": "YouTube",
|
||||
"size": 1080,
|
||||
"type": "Clip",
|
||||
"official": true,
|
||||
"published_at": "2023-02-14T13:00:28.000Z",
|
||||
"id": "63ebc244813cb60096aa356a"
|
||||
},
|
||||
{
|
||||
"iso_639_1": "en",
|
||||
"iso_3166_1": "US",
|
||||
"name": "Official Teaser",
|
||||
"key": "zmgbPv7lGrk",
|
||||
"site": "YouTube",
|
||||
"size": 1080,
|
||||
"type": "Teaser",
|
||||
"official": true,
|
||||
"published_at": "2022-12-23T17:34:00.000Z",
|
||||
"id": "63c169ee23be4600d960ae6d"
|
||||
}
|
||||
]
|
||||
},
|
||||
"images": {
|
||||
"backdrops": [
|
||||
{
|
||||
"aspect_ratio": 1.778,
|
||||
"height": 720,
|
||||
"iso_639_1": null,
|
||||
"file_path": "/jkKVLzLWjSvTnc84VzeljhSy6j8.jpg",
|
||||
"vote_average": 5.384,
|
||||
"vote_count": 2,
|
||||
"width": 1280
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 1.778,
|
||||
"height": 2160,
|
||||
"iso_639_1": null,
|
||||
"file_path": "/x6y6AHY3UoCeOP6kwZain7WNLPN.jpg",
|
||||
"vote_average": 5.312,
|
||||
"vote_count": 1,
|
||||
"width": 3840
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 1.778,
|
||||
"height": 2160,
|
||||
"iso_639_1": null,
|
||||
"file_path": "/ol32sTlLzayf7y3KbJrfuQkLmT8.jpg",
|
||||
"vote_average": 5.312,
|
||||
"vote_count": 1,
|
||||
"width": 3840
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 1.778,
|
||||
"height": 2160,
|
||||
"iso_639_1": null,
|
||||
"file_path": "/jL9pvfEep0houuNFMSEjinBm6Jh.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 3840
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 1.778,
|
||||
"height": 2160,
|
||||
"iso_639_1": null,
|
||||
"file_path": "/xZuhDaKDpWDG0sE3Dx6CIR8DeaN.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 3840
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 1.778,
|
||||
"height": 2160,
|
||||
"iso_639_1": null,
|
||||
"file_path": "/zg5rp4R3RkGApxWM03jUWJQzXGg.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 3840
|
||||
}
|
||||
],
|
||||
"logos": [
|
||||
{
|
||||
"aspect_ratio": 1.81,
|
||||
"height": 749,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/r7eYlJVm3OSVBA78Wg3kSUmCKQ7.png",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1356
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 1.81,
|
||||
"height": 749,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/t3wmFD8ghWeP1EEjahgD0MtcPM9.png",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1356
|
||||
}
|
||||
],
|
||||
"posters": [
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/gZLGCibvFY4zmt8sWUZcbBTHRtk.jpg",
|
||||
"vote_average": 5.318,
|
||||
"vote_count": 3,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "ru",
|
||||
"file_path": "/qMPcBNHcgclpl4IUiriSVcyt2Xr.jpg",
|
||||
"vote_average": 5.312,
|
||||
"vote_count": 1,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "es",
|
||||
"file_path": "/jO3VGQi5sHIj2BGS963g1F74yCq.jpg",
|
||||
"vote_average": 5.312,
|
||||
"vote_count": 1,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 1020,
|
||||
"iso_639_1": "sk",
|
||||
"file_path": "/7q9Q3OFu4E2UwTUnwGTZx79fqgj.jpg",
|
||||
"vote_average": 5.312,
|
||||
"vote_count": 1,
|
||||
"width": 680
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.671,
|
||||
"height": 1176,
|
||||
"iso_639_1": "ar",
|
||||
"file_path": "/d0qw9hiNwhRmfw4yAc44pep6vhz.jpg",
|
||||
"vote_average": 5.252,
|
||||
"vote_count": 4,
|
||||
"width": 789
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 2466,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/aJbrGWjOMwguiCSAGBcpoWGgpXf.jpg",
|
||||
"vote_average": 5.246,
|
||||
"vote_count": 2,
|
||||
"width": 1644
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 2466,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/uQxjZGU6rxSPSMeAJPJQlmfV3ys.jpg",
|
||||
"vote_average": 5.246,
|
||||
"vote_count": 2,
|
||||
"width": 1644
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 1500,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/8oibiRBkwSHFDamazdrEB5fWvXN.jpg",
|
||||
"vote_average": 5.18,
|
||||
"vote_count": 3,
|
||||
"width": 1000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/3PqW0elNnj5tk4XD9o82djTknGd.jpg",
|
||||
"vote_average": 5.18,
|
||||
"vote_count": 3,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "es",
|
||||
"file_path": "/zXDnVeyWwvhLYbaQjnei0A6vohx.jpg",
|
||||
"vote_average": 5.172,
|
||||
"vote_count": 1,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/6bPnDIGG8RBncFPIUNxM6GAW0Ox.jpg",
|
||||
"vote_average": 5.172,
|
||||
"vote_count": 1,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "uk",
|
||||
"file_path": "/v9qWcfkC3nJOASotuFdJ5huqg6l.jpg",
|
||||
"vote_average": 5.172,
|
||||
"vote_count": 1,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 1714,
|
||||
"iso_639_1": "es",
|
||||
"file_path": "/nm7rgAYCdATbHgm6CjtoSNvON9k.jpg",
|
||||
"vote_average": 5.172,
|
||||
"vote_count": 1,
|
||||
"width": 1143
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.666,
|
||||
"height": 2000,
|
||||
"iso_639_1": "fr",
|
||||
"file_path": "/brIDXQSf02a09i13xvMDTkRlO7z.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1333
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.665,
|
||||
"height": 1351,
|
||||
"iso_639_1": "pt",
|
||||
"file_path": "/tRjzdNiFHda6lrXySOQPyY3OtCA.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 899
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/mhjf22NsRXY4HKRbaUlfZAt7Swb.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/gh7JdLfrjewoA00xeMr0ju0PMwd.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": null,
|
||||
"file_path": "/moIOvJIdvvwriBiaKTehcmIeOf9.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "he",
|
||||
"file_path": "/ao0uyI21djx9uLv6voAjoaetX9O.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "nl",
|
||||
"file_path": "/z7Yq7vkVts9yeHCTFqIOEJkhJbi.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 1350,
|
||||
"iso_639_1": "hr",
|
||||
"file_path": "/fZog1nBWjNPQtPtoR1AFrmdbuG5.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 900
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "bg",
|
||||
"file_path": "/naMHX4mvqEAM4UbMox0MYYoFaPd.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "sv",
|
||||
"file_path": "/afPrxdEVh9uoSSIc0RVKMXPRHWm.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "sk",
|
||||
"file_path": "/stF5ysfzd1X5xMuvOiv5k8rRiX3.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 2000
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
3200
examples/view-transitions/src/content/movies/968051.json
Normal file
3200
examples/view-transitions/src/content/movies/968051.json
Normal file
File diff suppressed because it is too large
Load diff
5005
examples/view-transitions/src/content/movies/976573.json
Normal file
5005
examples/view-transitions/src/content/movies/976573.json
Normal file
File diff suppressed because it is too large
Load diff
927
examples/view-transitions/src/content/movies/990140.json
Normal file
927
examples/view-transitions/src/content/movies/990140.json
Normal file
|
@ -0,0 +1,927 @@
|
|||
{
|
||||
"data": {
|
||||
"adult": false,
|
||||
"backdrop_path": "/rV56FkcHkzHJcBOOqoCeSDnoBff.jpg",
|
||||
"belongs_to_collection": null,
|
||||
"budget": 0,
|
||||
"genres": [
|
||||
{ "id": 28, "name": "Action" },
|
||||
{ "id": 18, "name": "Drama" }
|
||||
],
|
||||
"homepage": "",
|
||||
"id": 990140,
|
||||
"imdb_id": "tt22488024",
|
||||
"original_language": "cn",
|
||||
"original_title": "天龍八部之喬峰傳",
|
||||
"overview": "Qiao Feng is the respected leader of a roving band of martial artists. After he is wrongfully accused of murder and subsequently exiled, Qiao Feng goes on the run in search of answers about his own mysterious origin story—and the unknown enemies working to destroy him from the shadows.",
|
||||
"popularity": 522.83,
|
||||
"poster_path": "/jGKCpt3zzbGZbgoza6HCvecqElM.jpg",
|
||||
"production_companies": [
|
||||
{ "id": 155372, "logo_path": null, "name": "Wishart Media Co., Ltd.", "origin_country": "" },
|
||||
{ "id": 160005, "logo_path": null, "name": "Super Bullet Pictures", "origin_country": "HK" }
|
||||
],
|
||||
"production_countries": [
|
||||
{ "iso_3166_1": "CN", "name": "China" },
|
||||
{ "iso_3166_1": "HK", "name": "Hong Kong" }
|
||||
],
|
||||
"release_date": "2023-01-16",
|
||||
"revenue": 159959,
|
||||
"runtime": 130,
|
||||
"spoken_languages": [
|
||||
{ "english_name": "Cantonese", "iso_639_1": "cn", "name": "广州话 / 廣州話" },
|
||||
{ "english_name": "Mandarin", "iso_639_1": "zh", "name": "普通话" }
|
||||
],
|
||||
"status": "Released",
|
||||
"tagline": "When a warrior belongs nowhere, the enemy is everywhere.",
|
||||
"title": "Sakra",
|
||||
"video": false,
|
||||
"vote_average": 6.552,
|
||||
"vote_count": 87,
|
||||
"credits": {
|
||||
"cast": [
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 1341,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Donnie Yen",
|
||||
"original_name": "Donnie Yen",
|
||||
"popularity": 32.998,
|
||||
"profile_path": "/hTlhrrZMj8hZVvD17j4KyAFWBHc.jpg",
|
||||
"cast_id": 1,
|
||||
"character": "Qiao Feng / Xiao Feng",
|
||||
"credit_id": "62b0cf55ecc7e800f0fe0311",
|
||||
"order": 0
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 2085448,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Yukee Chen",
|
||||
"original_name": "Yukee Chen",
|
||||
"popularity": 7.917,
|
||||
"profile_path": "/3E8eXz1CJsE34LZsmQt1V3jH2Y5.jpg",
|
||||
"cast_id": 4,
|
||||
"character": "A Zhu",
|
||||
"credit_id": "639572ec2cefc2007c1eb3c0",
|
||||
"order": 1
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 1397017,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Liu Yase",
|
||||
"original_name": "Liu Yase",
|
||||
"popularity": 3.823,
|
||||
"profile_path": "/2UBsASN6G37pjZtjl0Zse6S74y9.jpg",
|
||||
"cast_id": 8,
|
||||
"character": "A Zi",
|
||||
"credit_id": "63980c59f5c8240083a9e015",
|
||||
"order": 2
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 84205,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Kara Hui Ying-Hung",
|
||||
"original_name": "Kara Hui Ying-Hung",
|
||||
"popularity": 17.533,
|
||||
"profile_path": "/6OV9kM62Y7M7EswtkpCThs0QAxg.jpg",
|
||||
"cast_id": 9,
|
||||
"character": "Ruan Xingzhu",
|
||||
"credit_id": "63980c70f5c824007b890cd2",
|
||||
"order": 3
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 1800792,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Wu Yue",
|
||||
"original_name": "Wu Yue",
|
||||
"popularity": 8.983,
|
||||
"profile_path": "/hRePA3mh9mfAqX7SJ4rGxrNrxT7.jpg",
|
||||
"cast_id": 7,
|
||||
"character": "Murong Fu",
|
||||
"credit_id": "63957308a0f1a200c880a34b",
|
||||
"order": 4
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 72732,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Eddie Cheung",
|
||||
"original_name": "Eddie Cheung",
|
||||
"popularity": 5.704,
|
||||
"profile_path": "/jTrBt3y43LsO8XYsQnWg8bdwsP2.jpg",
|
||||
"cast_id": 14,
|
||||
"character": "Duan Zhengchun",
|
||||
"credit_id": "63980e36d05a0300cf2afd10",
|
||||
"order": 5
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 1255467,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Grace Wong",
|
||||
"original_name": "Grace Wong",
|
||||
"popularity": 2.312,
|
||||
"profile_path": "/Ab9GO6Awb183qaSP9VxlVNWZpFg.jpg",
|
||||
"cast_id": 12,
|
||||
"character": "Mrs. Ma",
|
||||
"credit_id": "63980cd8d05a030094f1d7d3",
|
||||
"order": 6
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 1571926,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Do Yuming",
|
||||
"original_name": "Do Yuming",
|
||||
"popularity": 3.349,
|
||||
"profile_path": "/aqxa9aRrGOIiIcia0Vb3ErvXz4e.jpg",
|
||||
"cast_id": 17,
|
||||
"character": "Bai Shijing",
|
||||
"credit_id": "63980fd28a88b20091ab7208",
|
||||
"order": 7
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 78877,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Ray Lui",
|
||||
"original_name": "Ray Lui",
|
||||
"popularity": 5.367,
|
||||
"profile_path": "/v6KV1Ib7ck9noPdwL6L2lAozeak.jpg",
|
||||
"cast_id": 16,
|
||||
"character": "Murong Bo",
|
||||
"credit_id": "63980e6df5c824008bc95f42",
|
||||
"order": 8
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 1145614,
|
||||
"known_for_department": "Directing",
|
||||
"name": "Tsui Siu-Ming",
|
||||
"original_name": "Tsui Siu-Ming",
|
||||
"popularity": 1.31,
|
||||
"profile_path": "/aY9b2ucIGylE3d7a1GNALk8qwH.jpg",
|
||||
"cast_id": 15,
|
||||
"character": "Jiu Mozhi",
|
||||
"credit_id": "63980e5da1a9ba00a0003400",
|
||||
"order": 9
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 2961684,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Cai Xiangyu",
|
||||
"original_name": "Cai Xiangyu",
|
||||
"popularity": 1.631,
|
||||
"profile_path": "/9P9916rJ9SkiYBqrAckRsuO48FA.jpg",
|
||||
"cast_id": 21,
|
||||
"character": "A Bi",
|
||||
"credit_id": "63cb7e60ea394900c827848a",
|
||||
"order": 10
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 1209782,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Michelle Hu",
|
||||
"original_name": "Michelle Hu",
|
||||
"popularity": 8.5,
|
||||
"profile_path": "/oNwNoLJg707G0HSIDnNU4mpaoIu.jpg",
|
||||
"cast_id": 22,
|
||||
"character": "Mrs. Xiao",
|
||||
"credit_id": "63cb7e739a6435008def2fc7",
|
||||
"order": 11
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 3260046,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Zhao Huawei",
|
||||
"original_name": "Zhao Huawei",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"cast_id": 23,
|
||||
"character": "Duan Yu",
|
||||
"credit_id": "63cb7ea46d97e6007c9d47f2",
|
||||
"order": 12
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 1089434,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Yu Kang",
|
||||
"original_name": "Yu Kang",
|
||||
"popularity": 4.673,
|
||||
"profile_path": "/aga0SZgIsntO4ZNsOF28HBLMx3i.jpg",
|
||||
"cast_id": 24,
|
||||
"character": "You Ju",
|
||||
"credit_id": "63cb7eba9a643500872aa4a4",
|
||||
"order": 13
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 1174692,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Xu Xiangdong",
|
||||
"original_name": "Xu Xiangdong",
|
||||
"popularity": 2.684,
|
||||
"profile_path": null,
|
||||
"cast_id": 25,
|
||||
"character": "Xuannan",
|
||||
"credit_id": "63cb7ed0d363e500ba783604",
|
||||
"order": 14
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 65975,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Yuen Cheung-Yan",
|
||||
"original_name": "Yuen Cheung-Yan",
|
||||
"popularity": 3.233,
|
||||
"profile_path": "/oI1Q07u74Yod4t8K06aSvfEJIbH.jpg",
|
||||
"cast_id": 26,
|
||||
"character": "Xue Muhua",
|
||||
"credit_id": "63cf408c0d2f5301d1ef7d31",
|
||||
"order": 15
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 3998591,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Cheung Siu Fai",
|
||||
"original_name": "Cheung Siu Fai",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"cast_id": 34,
|
||||
"character": "",
|
||||
"credit_id": "642fe90e9a643506f1afb11f",
|
||||
"order": 16
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 3998593,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Cya Liu",
|
||||
"original_name": "Cya Liu",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"cast_id": 35,
|
||||
"character": "",
|
||||
"credit_id": "642fe92531032500bd55bed7",
|
||||
"order": 17
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 1113443,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Kenji Tanigaki",
|
||||
"original_name": "Kenji Tanigaki",
|
||||
"popularity": 3.134,
|
||||
"profile_path": "/4WKEFXTK233yvrRvjA6TLIQiCn0.jpg",
|
||||
"cast_id": 37,
|
||||
"character": "",
|
||||
"credit_id": "642fe970e92d83011306e9c7",
|
||||
"order": 18
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 3183831,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Hua Yan",
|
||||
"original_name": "Hua Yan",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"cast_id": 38,
|
||||
"character": "Bandit",
|
||||
"credit_id": "642fe9bae92d8300b6e41abd",
|
||||
"order": 19
|
||||
}
|
||||
],
|
||||
"crew": [
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 1341,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Donnie Yen",
|
||||
"original_name": "Donnie Yen",
|
||||
"popularity": 32.998,
|
||||
"profile_path": "/hTlhrrZMj8hZVvD17j4KyAFWBHc.jpg",
|
||||
"credit_id": "639572d2a1a9ba00a0fef209",
|
||||
"department": "Directing",
|
||||
"job": "Director"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 1341,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Donnie Yen",
|
||||
"original_name": "Donnie Yen",
|
||||
"popularity": 32.998,
|
||||
"profile_path": "/hTlhrrZMj8hZVvD17j4KyAFWBHc.jpg",
|
||||
"credit_id": "63980c9679b3d400a0bc13f1",
|
||||
"department": "Production",
|
||||
"job": "Producer"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 64430,
|
||||
"known_for_department": "Camera",
|
||||
"name": "Chi Ying Chan",
|
||||
"original_name": "Chi Ying Chan",
|
||||
"popularity": 1.204,
|
||||
"profile_path": "/yDChYg2NSVBYAmGdoyTDznaIfSv.jpg",
|
||||
"credit_id": "63981028f5c82400b783039a",
|
||||
"department": "Camera",
|
||||
"job": "Director of Photography"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 548474,
|
||||
"known_for_department": "Writing",
|
||||
"name": "Wong Jing",
|
||||
"original_name": "Wong Jing",
|
||||
"popularity": 4.649,
|
||||
"profile_path": "/gMmaDRst3OwnY1wClKt541AmslD.jpg",
|
||||
"credit_id": "63980c892cefc20084b6093a",
|
||||
"department": "Production",
|
||||
"job": "Producer"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 551565,
|
||||
"known_for_department": "Art",
|
||||
"name": "Lau Sai-Wan",
|
||||
"original_name": "Lau Sai-Wan",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"credit_id": "639810a5a1a9ba009430b5f2",
|
||||
"department": "Art",
|
||||
"job": "Art Direction"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 1,
|
||||
"id": 1006504,
|
||||
"known_for_department": "Writing",
|
||||
"name": "Chen Li",
|
||||
"original_name": "Chen Li",
|
||||
"popularity": 1.183,
|
||||
"profile_path": "/uIkAFpDNsAL5sYmlartPNoV2BWn.jpg",
|
||||
"credit_id": "64288650c5840d00d58e3c34",
|
||||
"department": "Writing",
|
||||
"job": "Writer"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 1113443,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Kenji Tanigaki",
|
||||
"original_name": "Kenji Tanigaki",
|
||||
"popularity": 3.134,
|
||||
"profile_path": "/4WKEFXTK233yvrRvjA6TLIQiCn0.jpg",
|
||||
"credit_id": "62b0cfb19c24fc0061b28020",
|
||||
"department": "Directing",
|
||||
"job": "Action Director"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 1415282,
|
||||
"known_for_department": "Directing",
|
||||
"name": "Kam Ka-Wai",
|
||||
"original_name": "Kam Ka-Wai",
|
||||
"popularity": 1.821,
|
||||
"profile_path": "/gsPOd7NYzugZJwnEI5DokM6plQC.jpg",
|
||||
"credit_id": "64288624c0442901f0024683",
|
||||
"department": "Directing",
|
||||
"job": "Director"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 2095747,
|
||||
"known_for_department": "Acting",
|
||||
"name": "Andrew Yan Hua",
|
||||
"original_name": "Andrew Yan Hua",
|
||||
"popularity": 1.052,
|
||||
"profile_path": null,
|
||||
"credit_id": "6398107bd05a0300ae5105b3",
|
||||
"department": "Directing",
|
||||
"job": "Action Director"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 2,
|
||||
"id": 2195223,
|
||||
"known_for_department": "Directing",
|
||||
"name": "Leping Shen",
|
||||
"original_name": "Leping Shen",
|
||||
"popularity": 0.6,
|
||||
"profile_path": "/ocdkTboTAdk6BkJKO2Wrq4yLoto.jpg",
|
||||
"credit_id": "6428866a960cde0103a4b5be",
|
||||
"department": "Writing",
|
||||
"job": "Writer"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 2552279,
|
||||
"known_for_department": "Directing",
|
||||
"name": "Wei Zhu",
|
||||
"original_name": "Wei Zhu",
|
||||
"popularity": 0.98,
|
||||
"profile_path": "/1hcEJ4rXam8i74RjTjfn6JKcSIo.jpg",
|
||||
"credit_id": "642886880f3655011078cc3e",
|
||||
"department": "Writing",
|
||||
"job": "Writer"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 3113929,
|
||||
"known_for_department": "Production",
|
||||
"name": "Zhu Weijie",
|
||||
"original_name": "Zhu Weijie",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"credit_id": "63980d8ed05a0300ae5103a0",
|
||||
"department": "Production",
|
||||
"job": "Executive Producer"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 3391253,
|
||||
"known_for_department": "Directing",
|
||||
"name": "Sheng Lingzhi",
|
||||
"original_name": "Sheng Lingzhi",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"credit_id": "6428865e01b1ca0097fd97c6",
|
||||
"department": "Writing",
|
||||
"job": "Writer"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 3989726,
|
||||
"known_for_department": "Writing",
|
||||
"name": "He Ben",
|
||||
"original_name": "He Ben",
|
||||
"popularity": 0.668,
|
||||
"profile_path": null,
|
||||
"credit_id": "64288644c04429026b13431a",
|
||||
"department": "Writing",
|
||||
"job": "Writer"
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"gender": 0,
|
||||
"id": 3989729,
|
||||
"known_for_department": "Writing",
|
||||
"name": "Xu Yifan",
|
||||
"original_name": "Xu Yifan",
|
||||
"popularity": 0.6,
|
||||
"profile_path": null,
|
||||
"credit_id": "6428867a960cde00e0bcdb7d",
|
||||
"department": "Writing",
|
||||
"job": "Writer"
|
||||
}
|
||||
]
|
||||
},
|
||||
"videos": {
|
||||
"results": [
|
||||
{
|
||||
"iso_639_1": "en",
|
||||
"iso_3166_1": "US",
|
||||
"name": "Official US Trailer",
|
||||
"key": "aHP_pyGtFIk",
|
||||
"site": "YouTube",
|
||||
"size": 1080,
|
||||
"type": "Trailer",
|
||||
"official": true,
|
||||
"published_at": "2023-03-23T17:09:04.000Z",
|
||||
"id": "641e49dcc613ce01031f8b85"
|
||||
},
|
||||
{
|
||||
"iso_639_1": "en",
|
||||
"iso_3166_1": "US",
|
||||
"name": "Main Trailer",
|
||||
"key": "es5NAYPdcdI",
|
||||
"site": "YouTube",
|
||||
"size": 1080,
|
||||
"type": "Trailer",
|
||||
"official": true,
|
||||
"published_at": "2023-01-12T10:00:30.000Z",
|
||||
"id": "640a298154f6eb00993d3ebf"
|
||||
}
|
||||
]
|
||||
},
|
||||
"images": {
|
||||
"backdrops": [
|
||||
{
|
||||
"aspect_ratio": 1.778,
|
||||
"height": 2160,
|
||||
"iso_639_1": null,
|
||||
"file_path": "/rV56FkcHkzHJcBOOqoCeSDnoBff.jpg",
|
||||
"vote_average": 5.312,
|
||||
"vote_count": 1,
|
||||
"width": 3840
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 1.778,
|
||||
"height": 1080,
|
||||
"iso_639_1": null,
|
||||
"file_path": "/skY1yDFcLF4h6CYDxndr5jHJNof.jpg",
|
||||
"vote_average": 5.172,
|
||||
"vote_count": 1,
|
||||
"width": 1920
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 1.778,
|
||||
"height": 1080,
|
||||
"iso_639_1": null,
|
||||
"file_path": "/zS3ngMx0IJGzSUlAJ5u40utdCFK.jpg",
|
||||
"vote_average": 5.172,
|
||||
"vote_count": 1,
|
||||
"width": 1920
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 1.778,
|
||||
"height": 1080,
|
||||
"iso_639_1": null,
|
||||
"file_path": "/oREkJ5uPIryJz0zWMASkGVLzeIc.jpg",
|
||||
"vote_average": 5.106,
|
||||
"vote_count": 2,
|
||||
"width": 1920
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 1.778,
|
||||
"height": 2160,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/qAL0fwjZCQ41TwybgERAAUp4kWA.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 3840
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 1.778,
|
||||
"height": 2160,
|
||||
"iso_639_1": null,
|
||||
"file_path": "/bBERGgCqgUPzriFxsVrXccINprn.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 3840
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 1.778,
|
||||
"height": 2160,
|
||||
"iso_639_1": "fr",
|
||||
"file_path": "/v4E3Gb7QikastXcvKzvn519bM1m.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 3840
|
||||
}
|
||||
],
|
||||
"logos": [
|
||||
{
|
||||
"aspect_ratio": 4.046,
|
||||
"height": 194,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/pqu3S5zlYRt9oPXmC4OI1r4dml5.png",
|
||||
"vote_average": 5.312,
|
||||
"vote_count": 1,
|
||||
"width": 785
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 1.733,
|
||||
"height": 288,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/jWexdriLJE0kFXG4Nct7C0tSnfJ.png",
|
||||
"vote_average": 5.106,
|
||||
"vote_count": 2,
|
||||
"width": 499
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 1.691,
|
||||
"height": 615,
|
||||
"iso_639_1": "zh",
|
||||
"file_path": "/slL3b5hNslfrjdM4qlXn3XhJcak.png",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1040
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 1.878,
|
||||
"height": 147,
|
||||
"iso_639_1": "zh",
|
||||
"file_path": "/cd24lYjAb7dQRS7l4UrIs9D81go.png",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 276
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 2.555,
|
||||
"height": 1286,
|
||||
"iso_639_1": "fr",
|
||||
"file_path": "/4heIx9YFADRbnfkSzlFS6LVGTfT.png",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 3286
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 2.497,
|
||||
"height": 1273,
|
||||
"iso_639_1": "fr",
|
||||
"file_path": "/fn2o38gQPPqqmlH2qLyk4wP9GJT.png",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 3179
|
||||
}
|
||||
],
|
||||
"posters": [
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "cn",
|
||||
"file_path": "/vvWyOCmBAND2p9UwaXZdALIDd2W.jpg",
|
||||
"vote_average": 5.384,
|
||||
"vote_count": 2,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.672,
|
||||
"height": 2048,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/jGKCpt3zzbGZbgoza6HCvecqElM.jpg",
|
||||
"vote_average": 5.318,
|
||||
"vote_count": 3,
|
||||
"width": 1376
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.71,
|
||||
"height": 1600,
|
||||
"iso_639_1": "cn",
|
||||
"file_path": "/vksLBSmHahKD9F30vIrm0S7JsSO.jpg",
|
||||
"vote_average": 5.312,
|
||||
"vote_count": 1,
|
||||
"width": 1136
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "zh",
|
||||
"file_path": "/zr28ZaTpZeB7ACFVIoa4YuxFHgh.jpg",
|
||||
"vote_average": 5.312,
|
||||
"vote_count": 1,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 2340,
|
||||
"iso_639_1": "zh",
|
||||
"file_path": "/k20PICIsiYMkD425UASSXs12M3.jpg",
|
||||
"vote_average": 5.312,
|
||||
"vote_count": 1,
|
||||
"width": 1560
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "cn",
|
||||
"file_path": "/rafCyitNRMQUHDIVh3abWZRWofO.jpg",
|
||||
"vote_average": 5.312,
|
||||
"vote_count": 1,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 2100,
|
||||
"iso_639_1": "de",
|
||||
"file_path": "/b4A9L61eJfLL2eWPjsfwhDuzDsP.jpg",
|
||||
"vote_average": 5.312,
|
||||
"vote_count": 1,
|
||||
"width": 1400
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "de",
|
||||
"file_path": "/lEWeNdbPuJIUON6qUwwvRcYNgSU.jpg",
|
||||
"vote_average": 5.246,
|
||||
"vote_count": 2,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "fr",
|
||||
"file_path": "/qGhdGdocth1csUlEnPEmYDfEmwY.jpg",
|
||||
"vote_average": 5.238,
|
||||
"vote_count": 0,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 1600,
|
||||
"iso_639_1": "de",
|
||||
"file_path": "/zFRCKPsJxuQqdtysUD7UaySnxKC.jpg",
|
||||
"vote_average": 5.106,
|
||||
"vote_count": 2,
|
||||
"width": 1067
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.705,
|
||||
"height": 1064,
|
||||
"iso_639_1": "cn",
|
||||
"file_path": "/vPRZUtW2tQZ0JzwqUcS739qDfOv.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 750
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 2815,
|
||||
"iso_639_1": "ko",
|
||||
"file_path": "/rl6lMKv6XRPPOgMTcTmZWSsEsLH.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1877
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.666,
|
||||
"height": 2067,
|
||||
"iso_639_1": "zh",
|
||||
"file_path": "/dvlaQWBoZYmgHrG9r4V5DWn7e4N.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1377
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.705,
|
||||
"height": 1532,
|
||||
"iso_639_1": "zh",
|
||||
"file_path": "/vNpAREC0oLWUx1F7NWSdGO89Qaf.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1080
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 1711,
|
||||
"iso_639_1": "ko",
|
||||
"file_path": "/fmcRd957yQnlyEFltODkScqldKr.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1141
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.672,
|
||||
"height": 2048,
|
||||
"iso_639_1": "fr",
|
||||
"file_path": "/1d4Iru6pLYESE1DsE8BVxK5OwRm.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1376
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 2400,
|
||||
"iso_639_1": "zh",
|
||||
"file_path": "/lI3gD04BXUnB9ZhPmceeAVmnwHp.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1600
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 1600,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/2vA3CqwZ01LUsEaYRz2ZY6Om9xi.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1067
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 1500,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/uSmqyGyrjP1FF5UpxryUsSdQ4w0.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 1500,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/7JzNqNnisJnKH69mYuXNedznAAH.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 1500,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/o6229QNb9FHwWBCemZxM8mCBDgV.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 1500,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/7UyeEpMQXp5zlzSVHif8ZWDE2tA.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.666,
|
||||
"height": 1367,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/xoznyg9SNXjHPwT9kMMrPr6vW34.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 911
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 2100,
|
||||
"iso_639_1": "en",
|
||||
"file_path": "/aS3mnTkt6cnPcndb0l3F0J7GTDK.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1400
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "tr",
|
||||
"file_path": "/zP9mNbn55fNGdbHOAqzMt07aN4s.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 2000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 1500,
|
||||
"iso_639_1": "fr",
|
||||
"file_path": "/tObrbSUlTGurumll1SaIeVf14TT.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 1500,
|
||||
"iso_639_1": "fr",
|
||||
"file_path": "/rvy5WHZMY8YEaCmJjNvD9DW73AR.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 1000
|
||||
},
|
||||
{
|
||||
"aspect_ratio": 0.667,
|
||||
"height": 3000,
|
||||
"iso_639_1": "fr",
|
||||
"file_path": "/hCsXU4l8NdhmQTaLknzg9em73tF.jpg",
|
||||
"vote_average": 0,
|
||||
"vote_count": 0,
|
||||
"width": 2000
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
36
examples/view-transitions/src/layouts/Layout.astro
Normal file
36
examples/view-transitions/src/layouts/Layout.astro
Normal file
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
import '../styles/styles.css';
|
||||
import { ViewTransitions } from 'astro:transitions';
|
||||
import Footer from '../components/Footer.astro';
|
||||
import Nav from '../components/Nav.astro';
|
||||
|
||||
export interface Props {
|
||||
title: string;
|
||||
}
|
||||
|
||||
const { title } = Astro.props as Props;
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<meta name="view-transition" content="same-origin" />
|
||||
<title>{title}</title>
|
||||
<ViewTransitions />
|
||||
</head>
|
||||
<body class="font-sans bg-gray-900 text-white">
|
||||
<div class="h-screen overflow-hidden flex flex-col">
|
||||
<Nav />
|
||||
<div id="container" class="h-full flex-1 overflow-y-auto">
|
||||
<div id="content">
|
||||
<slot />
|
||||
</div>
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
8
examples/view-transitions/src/pages/index.astro
Normal file
8
examples/view-transitions/src/pages/index.astro
Normal file
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
import Layout from '../layouts/Layout.astro';
|
||||
import MovieList from '../components/MovieList.astro';
|
||||
---
|
||||
|
||||
<Layout title="Movies List">
|
||||
<MovieList />
|
||||
</Layout>
|
14
examples/view-transitions/src/pages/movies/[id].astro
Normal file
14
examples/view-transitions/src/pages/movies/[id].astro
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
import Layout from '../../layouts/Layout.astro';
|
||||
import MovieDetails from '../../components/MovieDetails.astro';
|
||||
import { getDataEntryById } from 'astro:content';
|
||||
|
||||
// Data collection bug?
|
||||
const id: any = '/src/content/movies/' + Astro.params.id;
|
||||
const result = await getDataEntryById('movies', id);
|
||||
const data = result.data.data;
|
||||
---
|
||||
|
||||
<Layout title={`${data.title} on Movies List`}>
|
||||
<MovieDetails data={data} />
|
||||
</Layout>
|
327
examples/view-transitions/src/popular-movies.json
Normal file
327
examples/view-transitions/src/popular-movies.json
Normal file
|
@ -0,0 +1,327 @@
|
|||
{
|
||||
"page": 1,
|
||||
"results": [
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/iIvQnZyzgx9TkbrOgcXx0p7aLiq.jpg",
|
||||
"genre_ids": [27, 53],
|
||||
"id": 1008042,
|
||||
"original_language": "en",
|
||||
"original_title": "Talk to Me",
|
||||
"overview": "When a group of friends discover how to conjure spirits using an embalmed hand, they become hooked on the new thrill, until one of them goes too far and unleashes terrifying supernatural forces.",
|
||||
"popularity": 2292.177,
|
||||
"poster_path": "/kdPMUMJzyYAc4roD52qavX0nLIC.jpg",
|
||||
"release_date": "2023-07-26",
|
||||
"title": "Talk to Me",
|
||||
"video": false,
|
||||
"vote_average": 7.3,
|
||||
"vote_count": 686
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/ctMserH8g2SeOAnCw5gFjdQF8mo.jpg",
|
||||
"genre_ids": [35, 12, 14],
|
||||
"id": 346698,
|
||||
"original_language": "en",
|
||||
"original_title": "Barbie",
|
||||
"overview": "Barbie and Ken are having the time of their lives in the colorful and seemingly perfect world of Barbie Land. However, when they get a chance to go to the real world, they soon discover the joys and perils of living among humans.",
|
||||
"popularity": 1899.184,
|
||||
"poster_path": "/iuFNMS8U5cb6xfzi51Dbkovj7vM.jpg",
|
||||
"release_date": "2023-07-19",
|
||||
"title": "Barbie",
|
||||
"video": false,
|
||||
"vote_average": 7.3,
|
||||
"vote_count": 4757
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/4XM8DUTQb3lhLemJC51Jx4a2EuA.jpg",
|
||||
"genre_ids": [28, 80, 53],
|
||||
"id": 385687,
|
||||
"original_language": "en",
|
||||
"original_title": "Fast X",
|
||||
"overview": "Over many missions and against impossible odds, Dom Toretto and his family have outsmarted, out-nerved and outdriven every foe in their path. Now, they confront the most lethal opponent they've ever faced: A terrifying threat emerging from the shadows of the past who's fueled by blood revenge, and who is determined to shatter this family and destroy everything—and everyone—that Dom loves, forever.",
|
||||
"popularity": 1973.052,
|
||||
"poster_path": "/fiVW06jE7z9YnO4trhaMEdclSiC.jpg",
|
||||
"release_date": "2023-05-17",
|
||||
"title": "Fast X",
|
||||
"video": false,
|
||||
"vote_average": 7.3,
|
||||
"vote_count": 3749
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/8pjWz2lt29KyVGoq1mXYu6Br7dE.jpg",
|
||||
"genre_ids": [28, 878, 27],
|
||||
"id": 615656,
|
||||
"original_language": "en",
|
||||
"original_title": "Meg 2: The Trench",
|
||||
"overview": "An exploratory dive into the deepest depths of the ocean of a daring research team spirals into chaos when a malevolent mining operation threatens their mission and forces them into a high-stakes battle for survival.",
|
||||
"popularity": 1804.581,
|
||||
"poster_path": "/4m1Au3YkjqsxF8iwQy0fPYSxE0h.jpg",
|
||||
"release_date": "2023-08-02",
|
||||
"title": "Meg 2: The Trench",
|
||||
"video": false,
|
||||
"vote_average": 7,
|
||||
"vote_count": 1823
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/c6Splshb8lb2Q9OvUfhpqXl7uP0.jpg",
|
||||
"genre_ids": [28, 53],
|
||||
"id": 717930,
|
||||
"original_language": "en",
|
||||
"original_title": "Kandahar",
|
||||
"overview": "After his mission is exposed, an undercover CIA operative stuck deep in hostile territory in Afghanistan must fight his way out, alongside his Afghan translator, to an extraction point in Kandahar, all whilst avoiding elite enemy forces and foreign spies tasked with hunting them down.",
|
||||
"popularity": 1206.966,
|
||||
"poster_path": "/lCanGgsqF4xD2WA5NF8PWeT3IXd.jpg",
|
||||
"release_date": "2023-05-25",
|
||||
"title": "Kandahar",
|
||||
"video": false,
|
||||
"vote_average": 6.8,
|
||||
"vote_count": 507
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/53z2fXEKfnNg2uSOPss2unPBGX1.jpg",
|
||||
"genre_ids": [27, 9648, 53],
|
||||
"id": 968051,
|
||||
"original_language": "en",
|
||||
"original_title": "The Nun II",
|
||||
"overview": "In 1956 France, a priest is violently murdered, and Sister Irene begins to investigate. She once again comes face-to-face with a powerful evil.",
|
||||
"popularity": 1296.77,
|
||||
"poster_path": "/5gzzkR7y3hnY8AD1wXjCnVlHba5.jpg",
|
||||
"release_date": "2023-09-06",
|
||||
"title": "The Nun II",
|
||||
"video": false,
|
||||
"vote_average": 6.7,
|
||||
"vote_count": 229
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/4fLZUr1e65hKPPVw0R3PmKFKxj1.jpg",
|
||||
"genre_ids": [16, 35, 10751, 14, 10749],
|
||||
"id": 976573,
|
||||
"original_language": "en",
|
||||
"original_title": "Elemental",
|
||||
"overview": "In a city where fire, water, land and air residents live together, a fiery young woman and a go-with-the-flow guy will discover something elemental: how much they have in common.",
|
||||
"popularity": 953.333,
|
||||
"poster_path": "/4Y1WNkd88JXmGfhtWR7dmDAo1T2.jpg",
|
||||
"release_date": "2023-06-14",
|
||||
"title": "Elemental",
|
||||
"video": false,
|
||||
"vote_average": 7.8,
|
||||
"vote_count": 2182
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/H6j5smdpRqP9a8UnhWp6zfl0SC.jpg",
|
||||
"genre_ids": [28, 878, 12],
|
||||
"id": 565770,
|
||||
"original_language": "en",
|
||||
"original_title": "Blue Beetle",
|
||||
"overview": "Recent college grad Jaime Reyes returns home full of aspirations for his future, only to find that home is not quite as he left it. As he searches to find his purpose in the world, fate intervenes when Jaime unexpectedly finds himself in possession of an ancient relic of alien biotechnology: the Scarab.",
|
||||
"popularity": 1007.105,
|
||||
"poster_path": "/vNfL4DYnonltukBrrgMmw94zMYL.jpg",
|
||||
"release_date": "2023-08-16",
|
||||
"title": "Blue Beetle",
|
||||
"video": false,
|
||||
"vote_average": 7.2,
|
||||
"vote_count": 541
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/9m161GawbY3cWxe6txd1NOHTjd0.jpg",
|
||||
"genre_ids": [878, 12, 28, 14],
|
||||
"id": 335977,
|
||||
"original_language": "en",
|
||||
"original_title": "Indiana Jones and the Dial of Destiny",
|
||||
"overview": "Finding himself in a new era, and approaching retirement, Indy wrestles with fitting into a world that seems to have outgrown him. But as the tentacles of an all-too-familiar evil return in the form of an old rival, Indy must don his hat and pick up his whip once more to make sure an ancient and powerful artifact doesn't fall into the wrong hands.",
|
||||
"popularity": 804.982,
|
||||
"poster_path": "/Af4bXE63pVsb2FtbW8uYIyPBadD.jpg",
|
||||
"release_date": "2023-06-28",
|
||||
"title": "Indiana Jones and the Dial of Destiny",
|
||||
"video": false,
|
||||
"vote_average": 6.7,
|
||||
"vote_count": 1650
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/jkKVLzLWjSvTnc84VzeljhSy6j8.jpg",
|
||||
"genre_ids": [10749, 18],
|
||||
"id": 820525,
|
||||
"original_language": "en",
|
||||
"original_title": "After Everything",
|
||||
"overview": "Besieged by writer’s block and the crushing breakup with Tessa, Hardin travels to Portugal in search of a woman he wronged in the past – and to find himself. Hoping to win back Tessa, he realizes he needs to change his ways before he can make the ultimate commitment.",
|
||||
"popularity": 650.272,
|
||||
"poster_path": "/gZLGCibvFY4zmt8sWUZcbBTHRtk.jpg",
|
||||
"release_date": "2023-09-13",
|
||||
"title": "After Everything",
|
||||
"video": false,
|
||||
"vote_average": 6.4,
|
||||
"vote_count": 27
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/waBWlJlMpyFb7STkFHfFvJKgwww.jpg",
|
||||
"genre_ids": [28, 18],
|
||||
"id": 678512,
|
||||
"original_language": "en",
|
||||
"original_title": "Sound of Freedom",
|
||||
"overview": "The story of Tim Ballard, a former US government agent, who quits his job in order to devote his life to rescuing children from global sex traffickers.",
|
||||
"popularity": 668.456,
|
||||
"poster_path": "/kSf9svfL2WrKeuK8W08xeR5lTn8.jpg",
|
||||
"release_date": "2023-07-03",
|
||||
"title": "Sound of Freedom",
|
||||
"video": false,
|
||||
"vote_average": 8,
|
||||
"vote_count": 458
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/iiXliCeykkzmJ0Eg9RYJ7F2CWSz.jpg",
|
||||
"genre_ids": [28, 9648, 53, 80],
|
||||
"id": 762430,
|
||||
"original_language": "en",
|
||||
"original_title": "Retribution",
|
||||
"overview": "When a mysterious caller puts a bomb under his car seat, Matt Turner begins a high-speed chase across the city to complete a specific series of tasks. With his kids trapped in the back seat and a bomb that will explode if they get out of the car, a normal commute becomes a twisted game of life or death as Matt follows the stranger's increasingly dangerous instructions in a race against time to save his family.",
|
||||
"popularity": 702.724,
|
||||
"poster_path": "/oUmmY7QWWn7OhKlcPOnirHJpP1F.jpg",
|
||||
"release_date": "2023-08-23",
|
||||
"title": "Retribution",
|
||||
"video": false,
|
||||
"vote_average": 6.6,
|
||||
"vote_count": 130
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/2vFuG6bWGyQUzYS9d69E5l85nIz.jpg",
|
||||
"genre_ids": [28, 12, 878],
|
||||
"id": 667538,
|
||||
"original_language": "en",
|
||||
"original_title": "Transformers: Rise of the Beasts",
|
||||
"overview": "When a new threat capable of destroying the entire planet emerges, Optimus Prime and the Autobots must team up with a powerful faction known as the Maximals. With the fate of humanity hanging in the balance, humans Noah and Elena will do whatever it takes to help the Transformers as they engage in the ultimate battle to save Earth.",
|
||||
"popularity": 650.789,
|
||||
"poster_path": "/gPbM0MK8CP8A174rmUwGsADNYKD.jpg",
|
||||
"release_date": "2023-06-06",
|
||||
"title": "Transformers: Rise of the Beasts",
|
||||
"video": false,
|
||||
"vote_average": 7.5,
|
||||
"vote_count": 3189
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/w2nFc2Rsm93PDkvjY4LTn17ePO0.jpg",
|
||||
"genre_ids": [16, 35, 28],
|
||||
"id": 614930,
|
||||
"original_language": "en",
|
||||
"original_title": "Teenage Mutant Ninja Turtles: Mutant Mayhem",
|
||||
"overview": "After years of being sheltered from the human world, the Turtle brothers set out to win the hearts of New Yorkers and be accepted as normal teenagers through heroic acts. Their new friend April O'Neil helps them take on a mysterious crime syndicate, but they soon get in over their heads when an army of mutants is unleashed upon them.",
|
||||
"popularity": 644.874,
|
||||
"poster_path": "/oupWWrVuCgNEa5GcjdkpjCYbx2X.jpg",
|
||||
"release_date": "2023-07-31",
|
||||
"title": "Teenage Mutant Ninja Turtles: Mutant Mayhem",
|
||||
"video": false,
|
||||
"vote_average": 7.3,
|
||||
"vote_count": 541
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/yF1eOkaYvwiORauRCPWznV9xVvi.jpg",
|
||||
"genre_ids": [28, 12, 878],
|
||||
"id": 298618,
|
||||
"original_language": "en",
|
||||
"original_title": "The Flash",
|
||||
"overview": "When his attempt to save his family inadvertently alters the future, Barry Allen becomes trapped in a reality in which General Zod has returned and there are no Super Heroes to turn to. In order to save the world that he is in and return to the future that he knows, Barry's only hope is to race for his life. But will making the ultimate sacrifice be enough to reset the universe?",
|
||||
"popularity": 561.181,
|
||||
"poster_path": "/rktDFPbfHfUbArZ6OOOKsXcv0Bm.jpg",
|
||||
"release_date": "2023-06-13",
|
||||
"title": "The Flash",
|
||||
"video": false,
|
||||
"vote_average": 6.9,
|
||||
"vote_count": 2873
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/4HodYYKEIsGOdinkGi2Ucz6X9i0.jpg",
|
||||
"genre_ids": [16, 28, 12],
|
||||
"id": 569094,
|
||||
"original_language": "en",
|
||||
"original_title": "Spider-Man: Across the Spider-Verse",
|
||||
"overview": "After reuniting with Gwen Stacy, Brooklyn’s full-time, friendly neighborhood Spider-Man is catapulted across the Multiverse, where he encounters the Spider Society, a team of Spider-People charged with protecting the Multiverse’s very existence. But when the heroes clash on how to handle a new threat, Miles finds himself pitted against the other Spiders and must set out on his own to save those he loves most.",
|
||||
"popularity": 842.076,
|
||||
"poster_path": "/8Vt6mWEReuy4Of61Lnj5Xj704m8.jpg",
|
||||
"release_date": "2023-05-31",
|
||||
"title": "Spider-Man: Across the Spider-Verse",
|
||||
"video": false,
|
||||
"vote_average": 8.5,
|
||||
"vote_count": 4261
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/9fOfsVHZHig6MHPHczv0zMY6cKc.jpg",
|
||||
"genre_ids": [28, 53, 10752, 18],
|
||||
"id": 1880,
|
||||
"original_language": "en",
|
||||
"original_title": "Red Dawn",
|
||||
"overview": "It is the dawn of World War III. In mid-western America, a group of teenagers band together to defend their town—and their country—from invading Soviet forces.",
|
||||
"popularity": 579.024,
|
||||
"poster_path": "/a2GkHcioc2QEFJbQk1NTB85u3vD.jpg",
|
||||
"release_date": "1984-08-10",
|
||||
"title": "Red Dawn",
|
||||
"video": false,
|
||||
"vote_average": 6.3,
|
||||
"vote_count": 670
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/3mYCjwll5RG342Dz1f8HcnT8tV.jpg",
|
||||
"genre_ids": [28, 80],
|
||||
"id": 606403,
|
||||
"original_language": "ko",
|
||||
"original_title": "특송",
|
||||
"overview": "Eun-ha, who is a normal junkyard employee, secretly works as a delivery clerk that deals with unusual delivery requests. One day, Eun-ha heads to Seoul to pick up a client who is involved in a gambling crime that wants to flee overseas. However, Eun-ha meets the client's young son at the pick-up point, instead of the client himself. Kyeong-pil, a current police officer who is actually masterminding the whole gambling crime, chases after the missing child who has the security key to the bank account that holds 30 million dollars.",
|
||||
"popularity": 525.582,
|
||||
"poster_path": "/fYT7JB4sU1XXeawEXOdQ3TtkFB2.jpg",
|
||||
"release_date": "2022-01-12",
|
||||
"title": "Special Delivery",
|
||||
"video": false,
|
||||
"vote_average": 6.9,
|
||||
"vote_count": 105
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/rV56FkcHkzHJcBOOqoCeSDnoBff.jpg",
|
||||
"genre_ids": [28, 18],
|
||||
"id": 990140,
|
||||
"original_language": "cn",
|
||||
"original_title": "天龍八部之喬峰傳",
|
||||
"overview": "Qiao Feng is the respected leader of a roving band of martial artists. After he is wrongfully accused of murder and subsequently exiled, Qiao Feng goes on the run in search of answers about his own mysterious origin story—and the unknown enemies working to destroy him from the shadows.",
|
||||
"popularity": 522.83,
|
||||
"poster_path": "/jGKCpt3zzbGZbgoza6HCvecqElM.jpg",
|
||||
"release_date": "2023-01-16",
|
||||
"title": "Sakra",
|
||||
"video": false,
|
||||
"vote_average": 6.6,
|
||||
"vote_count": 86
|
||||
},
|
||||
{
|
||||
"adult": false,
|
||||
"backdrop_path": "/4wVFtesa5YEWuAUHRcxoCN1Y1uN.jpg",
|
||||
"genre_ids": [28, 53],
|
||||
"id": 1085218,
|
||||
"original_language": "da",
|
||||
"original_title": "Underverden 2",
|
||||
"overview": "Seven years ago, Zaid went to war against the Copenhagen underworld to avenge his dead brother. His identity as a respected doctor of cardiology and life as a family man is but a fading dream, and in prison Zaid suffers the loss of his son Noah, whom he barely knows. When a police agent approaches Zaid and offers him a deal to be released in exchange for infiltrating the Copenhagen underworld, he sees his chance to reclaim the remnants of the family life he left behind. But everything has a price, and Zaid realizes that he has now seriously endangered his son's life. After all, once you become part of the underworld, is there any way out?",
|
||||
"popularity": 524.476,
|
||||
"poster_path": "/c8B4DsVcFVDLVmbpHMHU3RjLNAV.jpg",
|
||||
"release_date": "2023-04-13",
|
||||
"title": "Darkland: The Return",
|
||||
"video": false,
|
||||
"vote_average": 6.2,
|
||||
"vote_count": 59
|
||||
}
|
||||
],
|
||||
"total_pages": 40154,
|
||||
"total_results": 803062
|
||||
}
|
254
examples/view-transitions/src/scripts/spa-navigation.js
Normal file
254
examples/view-transitions/src/scripts/spa-navigation.js
Normal file
|
@ -0,0 +1,254 @@
|
|||
import {
|
||||
getNavigationType,
|
||||
getPathId,
|
||||
isBackNavigation,
|
||||
shouldNotIntercept,
|
||||
updateTheDOMSomehow,
|
||||
useTvFragment,
|
||||
} from './utils';
|
||||
|
||||
// View Transitions support cross-document navigations.
|
||||
// Should compare performace.
|
||||
// https://github.com/WICG/view-transitions/blob/main/explainer.md#cross-document-same-origin-transitions
|
||||
// https://github.com/WICG/view-transitions/blob/main/explainer.md#script-events
|
||||
function shouldDisableSpa() {
|
||||
return false;
|
||||
}
|
||||
|
||||
navigation.addEventListener('navigate', (navigateEvent) => {
|
||||
if (shouldDisableSpa()) return;
|
||||
if (shouldNotIntercept(navigateEvent)) return;
|
||||
|
||||
const toUrl = new URL(navigateEvent.destination.url);
|
||||
const toPath = toUrl.pathname;
|
||||
const fromPath = location.pathname;
|
||||
const navigationType = getNavigationType(fromPath, toPath);
|
||||
|
||||
if (location.origin !== toUrl.origin) return;
|
||||
|
||||
switch (navigationType) {
|
||||
case 'home-to-movie':
|
||||
case 'tv-to-show':
|
||||
handleHomeToMovieTransition(navigateEvent, getPathId(toPath));
|
||||
break;
|
||||
case 'movie-to-home':
|
||||
case 'show-to-tv':
|
||||
handleMovieToHomeTransition(navigateEvent, getPathId(fromPath));
|
||||
break;
|
||||
case 'movie-to-person':
|
||||
handleMovieToPersonTransition(navigateEvent, getPathId(fromPath), getPathId(toPath));
|
||||
break;
|
||||
case 'person-to-movie':
|
||||
case 'person-to-show':
|
||||
handlePersonToMovieTransition(navigateEvent, getPathId(fromPath), getPathId(toPath));
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: https://developer.chrome.com/docs/web-platform/view-transitions/#transitions-as-an-enhancement
|
||||
function handleHomeToMovieTransition(navigateEvent, movieId) {
|
||||
navigateEvent.intercept({
|
||||
async handler() {
|
||||
const fragmentUrl = useTvFragment(navigateEvent)
|
||||
? '/fragments/TvDetails'
|
||||
: '/fragments/MovieDetails';
|
||||
const response = await fetch(`${fragmentUrl}/${movieId}`);
|
||||
const data = await response.text();
|
||||
|
||||
if (!document.startViewTransition) {
|
||||
updateTheDOMSomehow(data);
|
||||
return;
|
||||
}
|
||||
|
||||
const thumbnail = document.getElementById(`movie-poster-${movieId}`);
|
||||
if (thumbnail) {
|
||||
thumbnail.style.viewTransitionName = 'movie-poster';
|
||||
}
|
||||
|
||||
const transition = document.startViewTransition(() => {
|
||||
if (thumbnail) {
|
||||
thumbnail.style.viewTransitionName = '';
|
||||
}
|
||||
document.getElementById('container').scrollTop = 0;
|
||||
updateTheDOMSomehow(data);
|
||||
});
|
||||
|
||||
await transition.finished;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function handleMovieToHomeTransition(navigateEvent, movieId) {
|
||||
navigateEvent.intercept({
|
||||
scroll: 'manual',
|
||||
async handler() {
|
||||
const fragmentUrl = useTvFragment(navigateEvent)
|
||||
? '/fragments/TvList'
|
||||
: '/fragments/MovieList';
|
||||
const response = await fetch(fragmentUrl);
|
||||
const data = await response.text();
|
||||
|
||||
if (!document.startViewTransition) {
|
||||
updateTheDOMSomehow(data);
|
||||
return;
|
||||
}
|
||||
|
||||
const tempHomePage = document.createElement('div');
|
||||
const moviePoster = document.getElementById(`movie-poster`);
|
||||
let thumbnail;
|
||||
|
||||
// If the movie poster is not in the home page, removes the transition style so that
|
||||
// the poster doesn't stay on the page while transitioning
|
||||
tempHomePage.innerHTML = data;
|
||||
if (!tempHomePage.querySelector(`#movie-poster-${movieId}`)) {
|
||||
moviePoster?.classList.remove('movie-poster');
|
||||
}
|
||||
|
||||
const transition = document.startViewTransition(() => {
|
||||
updateTheDOMSomehow(data);
|
||||
|
||||
thumbnail = document.getElementById(`movie-poster-${movieId}`);
|
||||
if (thumbnail) {
|
||||
thumbnail.scrollIntoViewIfNeeded();
|
||||
thumbnail.style.viewTransitionName = 'movie-poster';
|
||||
}
|
||||
});
|
||||
|
||||
await transition.finished;
|
||||
|
||||
if (thumbnail) {
|
||||
thumbnail.style.viewTransitionName = '';
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function handleMovieToPersonTransition(navigateEvent, movieId, personId) {
|
||||
// TODO: https://developer.chrome.com/docs/web-platform/view-transitions/#not-a-polyfill
|
||||
// ...has example of `back-transition` class applied to document
|
||||
const isBack = isBackNavigation(navigateEvent);
|
||||
|
||||
navigateEvent.intercept({
|
||||
async handler() {
|
||||
const response = await fetch('/fragments/PersonDetails/' + personId);
|
||||
const data = await response.text();
|
||||
|
||||
if (!document.startViewTransition) {
|
||||
updateTheDOMSomehow(data);
|
||||
return;
|
||||
}
|
||||
|
||||
let personThumbnail;
|
||||
let moviePoster;
|
||||
let movieThumbnail;
|
||||
|
||||
if (!isBack) {
|
||||
// We're transitioning the person photo; we need to remove the transition of the poster
|
||||
// so that it doesn't stay on the page while transitioning
|
||||
moviePoster = document.getElementById(`movie-poster`);
|
||||
if (moviePoster) {
|
||||
moviePoster.classList.remove('movie-poster');
|
||||
}
|
||||
|
||||
personThumbnail = document.getElementById(`person-photo-${personId}`);
|
||||
if (personThumbnail) {
|
||||
personThumbnail.style.viewTransitionName = 'person-photo';
|
||||
}
|
||||
}
|
||||
|
||||
const transition = document.startViewTransition(() => {
|
||||
updateTheDOMSomehow(data);
|
||||
|
||||
if (personThumbnail) {
|
||||
personThumbnail.style.viewTransitionName = '';
|
||||
}
|
||||
|
||||
if (isBack) {
|
||||
// If we're coming back to the person page, we're transitioning
|
||||
// into the movie poster thumbnail, so we need to add the tag to it
|
||||
movieThumbnail = document.getElementById(`movie-poster-${movieId}`);
|
||||
if (movieThumbnail) {
|
||||
movieThumbnail.scrollIntoViewIfNeeded();
|
||||
movieThumbnail.style.viewTransitionName = 'movie-poster';
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('container').scrollTop = 0;
|
||||
});
|
||||
|
||||
await transition.finished;
|
||||
|
||||
if (movieThumbnail) {
|
||||
movieThumbnail.style.viewTransitionName = '';
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function handlePersonToMovieTransition(navigateEvent, personId, movieId) {
|
||||
const isBack = isBackNavigation(navigateEvent);
|
||||
|
||||
navigateEvent.intercept({
|
||||
scroll: 'manual',
|
||||
async handler() {
|
||||
const fragmentUrl = useTvFragment(navigateEvent)
|
||||
? '/fragments/TvDetails'
|
||||
: '/fragments/MovieDetails';
|
||||
const response = await fetch(`${fragmentUrl}/${movieId}`);
|
||||
const data = await response.text();
|
||||
|
||||
if (!document.startViewTransition) {
|
||||
updateTheDOMSomehow(data);
|
||||
return;
|
||||
}
|
||||
|
||||
let thumbnail;
|
||||
let moviePoster;
|
||||
let movieThumbnail;
|
||||
|
||||
if (!isBack) {
|
||||
movieThumbnail = document.getElementById(`movie-poster-${movieId}`);
|
||||
if (movieThumbnail) {
|
||||
movieThumbnail.style.viewTransitionName = 'movie-poster';
|
||||
}
|
||||
}
|
||||
|
||||
const transition = document.startViewTransition(() => {
|
||||
updateTheDOMSomehow(data);
|
||||
|
||||
if (isBack) {
|
||||
moviePoster = document.getElementById(`movie-poster`);
|
||||
if (moviePoster) {
|
||||
moviePoster.classList.remove('movie-poster');
|
||||
}
|
||||
|
||||
if (personId) {
|
||||
thumbnail = document.getElementById(`person-photo-${personId}`);
|
||||
if (thumbnail) {
|
||||
thumbnail.scrollIntoViewIfNeeded();
|
||||
thumbnail.style.viewTransitionName = 'person-photo';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
document.getElementById('container').scrollTop = 0;
|
||||
|
||||
if (movieThumbnail) {
|
||||
movieThumbnail.style.viewTransitionName = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
await transition.finished;
|
||||
|
||||
if (thumbnail) {
|
||||
thumbnail.style.viewTransitionName = '';
|
||||
}
|
||||
|
||||
if (moviePoster) {
|
||||
moviePoster.classList.add('movie-poster');
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
76
examples/view-transitions/src/scripts/utils.js
Normal file
76
examples/view-transitions/src/scripts/utils.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
export function getNavigationType(fromPath, toPath) {
|
||||
if (fromPath.startsWith('/movies') && toPath === '/') {
|
||||
return 'movie-to-home';
|
||||
}
|
||||
|
||||
if (fromPath === '/tv' && toPath.startsWith('/tv/')) {
|
||||
return 'tv-to-show';
|
||||
}
|
||||
|
||||
if (fromPath === '/' && toPath.startsWith('/movies')) {
|
||||
return 'home-to-movie';
|
||||
}
|
||||
|
||||
if (fromPath.startsWith('/tv/') && toPath === '/tv') {
|
||||
return 'show-to-tv';
|
||||
}
|
||||
|
||||
if (
|
||||
(fromPath.startsWith('/movies') || fromPath.startsWith('/tv')) &&
|
||||
toPath.startsWith('/people')
|
||||
) {
|
||||
return 'movie-to-person';
|
||||
}
|
||||
|
||||
if (
|
||||
fromPath.startsWith('/people') &&
|
||||
(toPath.startsWith('/movies') || toPath.startsWith('/tv/'))
|
||||
) {
|
||||
return 'person-to-movie';
|
||||
}
|
||||
|
||||
return 'other';
|
||||
}
|
||||
|
||||
export function isBackNavigation(navigateEvent) {
|
||||
if (navigateEvent.navigationType === 'push' || navigateEvent.navigationType === 'replace') {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
navigateEvent.destination.index !== -1 &&
|
||||
navigateEvent.destination.index < navigation.currentEntry.index
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function shouldNotIntercept(navigationEvent) {
|
||||
return (
|
||||
navigationEvent.canIntercept === false ||
|
||||
// If this is just a hashChange,
|
||||
// just let the browser handle scrolling to the content.
|
||||
navigationEvent.hashChange ||
|
||||
// If this is a download,
|
||||
// let the browser perform the download.
|
||||
navigationEvent.downloadRequest ||
|
||||
// If this is a form submission,
|
||||
// let that go to the server.
|
||||
navigationEvent.formData
|
||||
);
|
||||
}
|
||||
|
||||
export function useTvFragment(navigateEvent) {
|
||||
const toUrl = new URL(navigateEvent.destination.url);
|
||||
const toPath = toUrl.pathname;
|
||||
|
||||
return toPath.startsWith('/tv');
|
||||
}
|
||||
|
||||
export function getPathId(path) {
|
||||
return path.split('/')[2];
|
||||
}
|
||||
|
||||
export function updateTheDOMSomehow(data) {
|
||||
document.getElementById('content').innerHTML = data;
|
||||
}
|
63
examples/view-transitions/src/styles/styles.css
Normal file
63
examples/view-transitions/src/styles/styles.css
Normal file
|
@ -0,0 +1,63 @@
|
|||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fade-out {
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slide-from-right {
|
||||
from {
|
||||
transform: translateX(30px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slide-to-left {
|
||||
to {
|
||||
transform: translateX(-30px);
|
||||
}
|
||||
}
|
||||
|
||||
::view-transition-old(root) {
|
||||
animation:
|
||||
90ms cubic-bezier(0.4, 0, 1, 1) both fade-out,
|
||||
300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-to-left;
|
||||
}
|
||||
|
||||
::view-transition-new(root) {
|
||||
animation:
|
||||
210ms cubic-bezier(0, 0, 0.2, 1) 90ms both fade-in,
|
||||
300ms cubic-bezier(0.4, 0, 0.2, 1) both slide-from-right;
|
||||
}
|
||||
|
||||
::view-transition-old(movie-poster),
|
||||
::view-transition-new(movie-poster) {
|
||||
animation: none;
|
||||
mix-blend-mode: normal;
|
||||
}
|
||||
|
||||
::view-transition-image-pair(movie-poster) {
|
||||
isolation: none;
|
||||
}
|
||||
|
||||
.nav {
|
||||
view-transition-name: main-header;
|
||||
contain: paint;
|
||||
}
|
||||
|
||||
.movie-poster {
|
||||
contain: paint;
|
||||
}
|
||||
|
||||
.person-photo {
|
||||
view-transition-name: person-photo;
|
||||
contain: paint;
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
contain: paint;
|
||||
}
|
12
examples/view-transitions/tailwind.config.cjs
Normal file
12
examples/view-transitions/tailwind.config.cjs
Normal file
|
@ -0,0 +1,12 @@
|
|||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
|
||||
theme: {
|
||||
extend: {
|
||||
width: {
|
||||
96: '24rem',
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
6
examples/view-transitions/tsconfig.json
Normal file
6
examples/view-transitions/tsconfig.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"extends": "astro/tsconfigs/base",
|
||||
"compilerOptions": {
|
||||
"resolveJsonModule": true
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/markdoc": "^0.5.0",
|
||||
"astro": "^3.1.4"
|
||||
"@astrojs/markdoc": "^0.5.2",
|
||||
"astro": "^3.2.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/markdown-remark": "^3.2.0",
|
||||
"astro": "^3.1.4",
|
||||
"@astrojs/markdown-remark": "^3.2.1",
|
||||
"astro": "^3.2.4",
|
||||
"hast-util-select": "^5.0.5",
|
||||
"rehype-autolink-headings": "^6.1.1",
|
||||
"rehype-slug": "^5.1.0",
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^3.1.4"
|
||||
"astro": "^3.2.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/mdx": "^1.1.0",
|
||||
"@astrojs/preact": "^3.0.0",
|
||||
"astro": "^3.1.4",
|
||||
"@astrojs/mdx": "^1.1.1",
|
||||
"@astrojs/preact": "^3.0.1",
|
||||
"astro": "^3.2.4",
|
||||
"preact": "^10.17.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/preact": "^3.0.0",
|
||||
"@astrojs/preact": "^3.0.1",
|
||||
"@nanostores/preact": "^0.5.0",
|
||||
"astro": "^3.1.4",
|
||||
"astro": "^3.2.4",
|
||||
"nanostores": "^0.9.3",
|
||||
"preact": "^10.17.1"
|
||||
}
|
||||
|
|
|
@ -11,10 +11,10 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/mdx": "^1.1.0",
|
||||
"@astrojs/tailwind": "^5.0.0",
|
||||
"@astrojs/mdx": "^1.1.1",
|
||||
"@astrojs/tailwind": "^5.0.2",
|
||||
"@types/canvas-confetti": "^1.6.0",
|
||||
"astro": "^3.1.4",
|
||||
"astro": "^3.2.4",
|
||||
"autoprefixer": "^10.4.15",
|
||||
"canvas-confetti": "^1.6.0",
|
||||
"postcss": "^8.4.28",
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^3.1.4",
|
||||
"astro": "^3.2.4",
|
||||
"vite-plugin-pwa": "0.16.4",
|
||||
"workbox-window": "^7.0.0"
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"test": "vitest"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "^3.1.4",
|
||||
"astro": "^3.2.4",
|
||||
"vitest": "^0.34.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,137 @@
|
|||
# astro
|
||||
|
||||
## 3.2.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#8638](https://github.com/withastro/astro/pull/8638) [`160d1cd75`](https://github.com/withastro/astro/commit/160d1cd755e70af1d8ec294d01dd2cb32d60db50) Thanks [@florian-lefebvre](https://github.com/florian-lefebvre)! - The `@astrojs/tailwind` integration now creates a `tailwind.config.mjs` file by default
|
||||
|
||||
- [#8767](https://github.com/withastro/astro/pull/8767) [`30de32436`](https://github.com/withastro/astro/commit/30de324361bc261956eb9fc08fe60a82ff602a9b) Thanks [@martrapp](https://github.com/martrapp)! - Revert fix #8472
|
||||
|
||||
[#8472](https://github.com/withastro/astro/pull/8472) caused some style files from previous pages to not be cleanly deleted on view transitions. For a discussion of a future fix for the original issue [#8144](https://github.com/withastro/astro/issues/8114) see [#8745](https://github.com/withastro/astro/pull/8745).
|
||||
|
||||
- [#8741](https://github.com/withastro/astro/pull/8741) [`c4a7ec425`](https://github.com/withastro/astro/commit/c4a7ec4255e7acb9555cb8bb74ea13c5fbb2ac17) Thanks [@lilnasy](https://github.com/lilnasy)! - Fixed an issue on Windows where lowercase drive letters in current working directory led to missing scripts and styles.
|
||||
|
||||
- [#8772](https://github.com/withastro/astro/pull/8772) [`c24f70d91`](https://github.com/withastro/astro/commit/c24f70d91601dd3a6b5a84f04d61824e775e9b44) Thanks [@martrapp](https://github.com/martrapp)! - Fix flickering during view transitions
|
||||
|
||||
- [#8754](https://github.com/withastro/astro/pull/8754) [`93b092266`](https://github.com/withastro/astro/commit/93b092266febfad16a48575f8eee12d5910bf071) Thanks [@bluwy](https://github.com/bluwy)! - Make CSS chunk names less confusing
|
||||
|
||||
- [#8776](https://github.com/withastro/astro/pull/8776) [`29cdfa024`](https://github.com/withastro/astro/commit/29cdfa024886dd581cb207586f7dfec6966bdd4e) Thanks [@martrapp](https://github.com/martrapp)! - Fix transition attributes on islands
|
||||
|
||||
- [#8773](https://github.com/withastro/astro/pull/8773) [`eaed844ea`](https://github.com/withastro/astro/commit/eaed844ea8f2f52e0c9caa40bb3ec7377e10595f) Thanks [@sumimakito](https://github.com/sumimakito)! - Fix an issue where HTML attributes do not render if getHTMLAttributes in an image service returns a Promise
|
||||
|
||||
## 3.2.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#8737](https://github.com/withastro/astro/pull/8737) [`6f60da805`](https://github.com/withastro/astro/commit/6f60da805e0014bc50dd07bef972e91c73560c3c) Thanks [@ematipico](https://github.com/ematipico)! - Add provenance statement when publishing the library from CI
|
||||
|
||||
- [#8747](https://github.com/withastro/astro/pull/8747) [`d78806dfe`](https://github.com/withastro/astro/commit/d78806dfe0301ea7ffe6c7c1f783bd415ac7cda9) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Improve error message when user attempts to render a dynamic component reference
|
||||
|
||||
- [#8736](https://github.com/withastro/astro/pull/8736) [`d1c75fe15`](https://github.com/withastro/astro/commit/d1c75fe158839699c59728cf3a83888e8c72a459) Thanks [@bluwy](https://github.com/bluwy)! - Fix `tsconfig.json` update causing the server to crash
|
||||
|
||||
- [#8743](https://github.com/withastro/astro/pull/8743) [`aa265d730`](https://github.com/withastro/astro/commit/aa265d73024422967c1b1c68ad268c419c6c798f) Thanks [@bluwy](https://github.com/bluwy)! - Remove unused CSS output files when inlined
|
||||
|
||||
- [#8700](https://github.com/withastro/astro/pull/8700) [`78adbc443`](https://github.com/withastro/astro/commit/78adbc4433208458291e36713909762e148e1e5d) Thanks [@jacobthesheep](https://github.com/jacobthesheep)! - Update link for Netlify SSR
|
||||
|
||||
- [#8729](https://github.com/withastro/astro/pull/8729) [`21e0757ea`](https://github.com/withastro/astro/commit/21e0757ea22a57d344c934045ca19db93b684436) Thanks [@lilnasy](https://github.com/lilnasy)! - Node-based adapters now create less server-side javascript
|
||||
|
||||
- [#8730](https://github.com/withastro/astro/pull/8730) [`357270f2a`](https://github.com/withastro/astro/commit/357270f2a3d0bf2aa634ba7e52e9d17618eff4a7) Thanks [@natemoo-re](https://github.com/natemoo-re)! - Improve `astro info` copy to clipboard compatability
|
||||
|
||||
- Updated dependencies [[`21f482657`](https://github.com/withastro/astro/commit/21f4826576c2c812a1604e18717799da3470decd), [`6f60da805`](https://github.com/withastro/astro/commit/6f60da805e0014bc50dd07bef972e91c73560c3c), [`21e0757ea`](https://github.com/withastro/astro/commit/21e0757ea22a57d344c934045ca19db93b684436)]:
|
||||
- @astrojs/markdown-remark@3.2.1
|
||||
- @astrojs/internal-helpers@0.2.1
|
||||
- @astrojs/telemetry@3.0.3
|
||||
|
||||
## 3.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#8724](https://github.com/withastro/astro/pull/8724) [`455af3235`](https://github.com/withastro/astro/commit/455af3235b3268852e6988accecc796f03f6d16e) Thanks [@bluwy](https://github.com/bluwy)! - Fix CSS styles on Windows
|
||||
|
||||
- [#8710](https://github.com/withastro/astro/pull/8710) [`4c2bec681`](https://github.com/withastro/astro/commit/4c2bec681b0752e7215b8a32bd2d44bf477adac1) Thanks [@matthewp](https://github.com/matthewp)! - Fixes View transition styles being missing when component used multiple times
|
||||
|
||||
## 3.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#8680](https://github.com/withastro/astro/pull/8680) [`31c59ad8b`](https://github.com/withastro/astro/commit/31c59ad8b6a72f95c98a306ecf92d198c03110b4) Thanks [@bluwy](https://github.com/bluwy)! - Fix hydration on slow connection
|
||||
|
||||
- [#8698](https://github.com/withastro/astro/pull/8698) [`47ea310f0`](https://github.com/withastro/astro/commit/47ea310f01d06ed1562c790bec348718a2fa8277) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Use a Node-specific image endpoint to resolve images in dev and Node SSR. This should fix many issues related to getting 404 from the \_image endpoint under certain configurations
|
||||
|
||||
- [#8706](https://github.com/withastro/astro/pull/8706) [`345808170`](https://github.com/withastro/astro/commit/345808170fce783ddd3c9a4035a91fa64dcc5f46) Thanks [@bluwy](https://github.com/bluwy)! - Fix duplicated Astro and Vite injected styles
|
||||
|
||||
## 3.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#8696](https://github.com/withastro/astro/pull/8696) [`2167ffd72`](https://github.com/withastro/astro/commit/2167ffd72f58904f449ffc6e53581a2d8faf7317) Thanks [@matthewp](https://github.com/matthewp)! - Support adding integrations dynamically
|
||||
|
||||
Astro integrations can now themselves dynamically add and configure additional integrations during set-up. This makes it possible for integration authors to bundle integrations more intelligently for their users.
|
||||
|
||||
In the following example, a custom integration checks whether `@astrojs/sitemap` is already configured. If not, the integration adds Astro’s sitemap integration, passing any desired configuration options:
|
||||
|
||||
```ts
|
||||
import sitemap from '@astrojs/sitemap';
|
||||
import type { AstroIntegration } from 'astro';
|
||||
|
||||
const MyIntegration = (): AstroIntegration => {
|
||||
return {
|
||||
name: 'my-integration',
|
||||
|
||||
'astro:config:setup': ({ config, updateConfig }) => {
|
||||
// Look for sitemap in user-configured integrations.
|
||||
const userSitemap = config.integrations.find(
|
||||
({ name }) => name === '@astrojs/sitemap'
|
||||
);
|
||||
|
||||
if (!userSitemap) {
|
||||
// If sitemap wasn’t found, add it.
|
||||
updateConfig({
|
||||
integrations: [sitemap({ /* opts */ }],
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
- [#8696](https://github.com/withastro/astro/pull/8696) [`2167ffd72`](https://github.com/withastro/astro/commit/2167ffd72f58904f449ffc6e53581a2d8faf7317) Thanks [@matthewp](https://github.com/matthewp)! - View transitions can now be triggered from JavaScript!
|
||||
|
||||
Import the client-side router from "astro:transitions/client" and enjoy your new remote control for navigation:
|
||||
|
||||
```js
|
||||
import { navigate } from 'astro:transitions/client';
|
||||
|
||||
// Navigate to the selected option automatically.
|
||||
document.querySelector('select').onchange = (ev) => {
|
||||
let href = ev.target.value;
|
||||
navigate(href);
|
||||
};
|
||||
```
|
||||
|
||||
- [#8696](https://github.com/withastro/astro/pull/8696) [`2167ffd72`](https://github.com/withastro/astro/commit/2167ffd72f58904f449ffc6e53581a2d8faf7317) Thanks [@matthewp](https://github.com/matthewp)! - Route Announcer in `<ViewTransitions />`
|
||||
|
||||
The View Transitions router now does route announcement. When transitioning between pages with a traditional MPA approach, assistive technologies will announce the page title when the page finishes loading. This does not automatically happen during client-side routing, so visitors relying on these technologies to announce routes are not aware when a page has changed.
|
||||
|
||||
The view transitions route announcer runs after the `astro:page-load` event, looking for the page `<title>` to announce. If one cannot be found, the announcer falls back to the first `<h1>` it finds, or otherwise announces the pathname. We recommend you always include a `<title>` in each page for accessibility.
|
||||
|
||||
See the [View Transitions docs](https://docs.astro.build/en/guides/view-transitions/) for more on how accessibility is handled.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#8647](https://github.com/withastro/astro/pull/8647) [`408b50c5e`](https://github.com/withastro/astro/commit/408b50c5ea5aba66252424f54788557274a58571) Thanks [@lilnasy](https://github.com/lilnasy)! - Fixed an issue where configured redirects with dynamic routes did not work in dev mode.
|
||||
|
||||
- [#8696](https://github.com/withastro/astro/pull/8696) [`2167ffd72`](https://github.com/withastro/astro/commit/2167ffd72f58904f449ffc6e53581a2d8faf7317) Thanks [@matthewp](https://github.com/matthewp)! - Fix logLevel passed to Vite build
|
||||
|
||||
- [#8696](https://github.com/withastro/astro/pull/8696) [`2167ffd72`](https://github.com/withastro/astro/commit/2167ffd72f58904f449ffc6e53581a2d8faf7317) Thanks [@matthewp](https://github.com/matthewp)! - Fix NoImageMetadata image path error message
|
||||
|
||||
- [#8670](https://github.com/withastro/astro/pull/8670) [`e797b6816`](https://github.com/withastro/astro/commit/e797b6816072f63f38d9a91dd2a66765c558d46c) Thanks [@MichailiK](https://github.com/MichailiK)! - Fix asset optimization failing when outDir is outside the project directory
|
||||
|
||||
- [#8684](https://github.com/withastro/astro/pull/8684) [`824dd4670`](https://github.com/withastro/astro/commit/824dd4670a145c47337eff84a5ae412bf7443117) Thanks [@matthewp](https://github.com/matthewp)! - Support content collections with % in filename
|
||||
|
||||
- [#8648](https://github.com/withastro/astro/pull/8648) [`cfd895d87`](https://github.com/withastro/astro/commit/cfd895d877fdb7fc69e745665a374fc32cb3ef7d) Thanks [@lilnasy](https://github.com/lilnasy)! - Fixed an issue where a response with status code 404 led to an endless loop of implicit rerouting in dev mode.
|
||||
|
||||
## 3.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
// ISOMORPHIC FILE: NO TOP-LEVEL IMPORT/REQUIRE() ALLOWED
|
||||
// This file has to run as both ESM and CJS on older Node.js versions
|
||||
// Needed for Stackblitz: https://github.com/stackblitz/webcontainer-core/issues/281
|
||||
|
||||
const CI_INSTRUCTIONS = {
|
||||
NETLIFY: 'https://docs.netlify.com/configure-builds/manage-dependencies/#node-js-and-javascript',
|
||||
|
@ -16,15 +15,11 @@ const CI_INSTRUCTIONS = {
|
|||
const engines = '>=18.14.1';
|
||||
const skipSemverCheckIfAbove = 19;
|
||||
|
||||
// HACK (2023-08-18) Stackblitz does not support Node 18 yet, so we'll fake Node 16 support for some time until it's supported
|
||||
// TODO: Remove when Node 18 is supported on Stackblitz
|
||||
const isStackblitz = process.env.SHELL === '/bin/jsh' && process.versions.webcontainer != null;
|
||||
|
||||
/** `astro *` */
|
||||
async function main() {
|
||||
const version = process.versions.node;
|
||||
// Fast-path for higher Node.js versions
|
||||
if (!isStackblitz && (parseInt(version) || 0) <= skipSemverCheckIfAbove) {
|
||||
if ((parseInt(version) || 0) <= skipSemverCheckIfAbove) {
|
||||
try {
|
||||
const semver = await import('semver');
|
||||
if (!semver.satisfies(version, engines)) {
|
||||
|
@ -37,6 +32,13 @@ async function main() {
|
|||
}
|
||||
}
|
||||
|
||||
// windows drive letters can sometimes be lowercase, which vite cannot process
|
||||
if (process.platform === 'win32') {
|
||||
const cwd = process.cwd();
|
||||
const correctedCwd = cwd.slice(0, 1).toUpperCase() + cwd.slice(1);
|
||||
if (correctedCwd !== cwd) process.chdir(correctedCwd);
|
||||
}
|
||||
|
||||
return import('./dist/cli/index.js')
|
||||
.then(({ cli }) => cli(process.argv))
|
||||
.catch((error) => {
|
||||
|
|
7
packages/astro/client.d.ts
vendored
7
packages/astro/client.d.ts
vendored
|
@ -120,6 +120,13 @@ declare module 'astro:transitions' {
|
|||
export const ViewTransitions: ViewTransitionsModule['default'];
|
||||
}
|
||||
|
||||
declare module 'astro:transitions/client' {
|
||||
type TransitionRouterModule = typeof import('./dist/transitions/router.js');
|
||||
export const supportsViewTransitions: TransitionRouterModule['supportsViewTransitions'];
|
||||
export const transitionEnabledOnThisPage: TransitionRouterModule['transitionEnabledOnThisPage'];
|
||||
export const navigate: TransitionRouterModule['navigate'];
|
||||
}
|
||||
|
||||
declare module 'astro:middleware' {
|
||||
export * from 'astro/middleware/namespace';
|
||||
}
|
||||
|
|
|
@ -11,91 +11,12 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|||
<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';
|
||||
type State = {
|
||||
index: number;
|
||||
scrollX: number;
|
||||
scrollY: number;
|
||||
intraPage?: boolean;
|
||||
};
|
||||
type Events = 'astro:page-load' | 'astro:after-swap';
|
||||
|
||||
// only update history entries that are managed by us
|
||||
// leave other entries alone and do not accidently add state.
|
||||
const persistState = (state: State) => history.state && history.replaceState(state, '');
|
||||
// @ts-expect-error: startViewTransition might exist
|
||||
const supportsViewTransitions = !!document.startViewTransition;
|
||||
const transitionEnabledOnThisPage = () =>
|
||||
!!document.querySelector('[name="astro-view-transitions-enabled"]');
|
||||
const triggerEvent = (name: Events) => document.dispatchEvent(new Event(name));
|
||||
const onPageLoad = () => triggerEvent('astro:page-load');
|
||||
const PERSIST_ATTR = 'data-astro-transition-persist';
|
||||
const parser = new DOMParser();
|
||||
// explained at its usage
|
||||
let noopEl: HTMLDivElement;
|
||||
if (import.meta.env.DEV) {
|
||||
noopEl = document.createElement('div');
|
||||
}
|
||||
|
||||
// The History API does not tell you if navigation is forward or back, so
|
||||
// you can figure it using an index. On pushState the index is incremented so you
|
||||
// can use that to determine popstate if going forward or back.
|
||||
let currentHistoryIndex = 0;
|
||||
if (history.state) {
|
||||
// we reloaded a page with history state
|
||||
// (e.g. history navigation from non-transition page or browser reload)
|
||||
currentHistoryIndex = history.state.index;
|
||||
scrollTo({ left: history.state.scrollX, top: history.state.scrollY });
|
||||
} else if (transitionEnabledOnThisPage()) {
|
||||
history.replaceState({ index: currentHistoryIndex, scrollX, scrollY, intraPage: false }, '');
|
||||
}
|
||||
const throttle = (cb: (...args: any[]) => any, delay: number) => {
|
||||
let wait = false;
|
||||
// During the waiting time additional events are lost.
|
||||
// So repeat the callback at the end if we have swallowed events.
|
||||
let onceMore = false;
|
||||
return (...args: any[]) => {
|
||||
if (wait) {
|
||||
onceMore = true;
|
||||
return;
|
||||
}
|
||||
cb(...args);
|
||||
wait = true;
|
||||
setTimeout(() => {
|
||||
if (onceMore) {
|
||||
onceMore = false;
|
||||
cb(...args);
|
||||
}
|
||||
wait = false;
|
||||
}, delay);
|
||||
};
|
||||
};
|
||||
|
||||
// returns the contents of the page or null if the router can't deal with it.
|
||||
async function fetchHTML(
|
||||
href: string
|
||||
): Promise<null | { html: string; redirected?: string; mediaType: DOMParserSupportedType }> {
|
||||
try {
|
||||
const res = await fetch(href);
|
||||
// drop potential charset (+ other name/value pairs) as parser needs the mediaType
|
||||
const mediaType = res.headers.get('content-type')?.replace(/;.*$/, '');
|
||||
// the DOMParser can handle two types of HTML
|
||||
if (mediaType !== 'text/html' && mediaType !== 'application/xhtml+xml') {
|
||||
// everything else (e.g. audio/mp3) will be handled by the browser but not by us
|
||||
return null;
|
||||
}
|
||||
const html = await res.text();
|
||||
return {
|
||||
html,
|
||||
redirected: res.redirected ? res.url : undefined,
|
||||
mediaType,
|
||||
};
|
||||
} catch (err) {
|
||||
// can't fetch, let someone else deal with it.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
import {
|
||||
supportsViewTransitions,
|
||||
transitionEnabledOnThisPage,
|
||||
navigate,
|
||||
} from 'astro:transitions/client';
|
||||
export type Fallback = 'none' | 'animate' | 'swap';
|
||||
|
||||
function getFallback(): Fallback {
|
||||
const el = document.querySelector('[name="astro-view-transitions-fallback"]');
|
||||
|
@ -105,263 +26,6 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|||
return 'animate';
|
||||
}
|
||||
|
||||
function markScriptsExec() {
|
||||
for (const script of document.scripts) {
|
||||
script.dataset.astroExec = '';
|
||||
}
|
||||
}
|
||||
|
||||
function runScripts() {
|
||||
let wait = Promise.resolve();
|
||||
for (const script of Array.from(document.scripts)) {
|
||||
if (script.dataset.astroExec === '') continue;
|
||||
const newScript = document.createElement('script');
|
||||
newScript.innerHTML = script.innerHTML;
|
||||
for (const attr of script.attributes) {
|
||||
if (attr.name === 'src') {
|
||||
const p = new Promise((r) => {
|
||||
newScript.onload = r;
|
||||
});
|
||||
wait = wait.then(() => p as any);
|
||||
}
|
||||
newScript.setAttribute(attr.name, attr.value);
|
||||
}
|
||||
newScript.dataset.astroExec = '';
|
||||
script.replaceWith(newScript);
|
||||
}
|
||||
return wait;
|
||||
}
|
||||
|
||||
function isInfinite(animation: Animation) {
|
||||
const effect = animation.effect;
|
||||
if (!effect || !(effect instanceof KeyframeEffect) || !effect.target) return false;
|
||||
const style = window.getComputedStyle(effect.target, effect.pseudoElement);
|
||||
return style.animationIterationCount === 'infinite';
|
||||
}
|
||||
|
||||
const updateHistoryAndScrollPosition = (toLocation) => {
|
||||
if (toLocation.href !== location.href) {
|
||||
history.pushState(
|
||||
{ index: ++currentHistoryIndex, scrollX: 0, scrollY: 0 },
|
||||
'',
|
||||
toLocation.href
|
||||
);
|
||||
// now we are on the new page for non-history navigations!
|
||||
// (with history navigation page change happens before popstate is fired)
|
||||
}
|
||||
// freshly loaded pages start from the top
|
||||
scrollTo({ left: 0, top: 0, behavior: 'instant' });
|
||||
|
||||
if (toLocation.hash) {
|
||||
// because we are already on the target page ...
|
||||
// ... what comes next is a intra-page navigation
|
||||
// that won't reload the page but instead scroll to the fragment
|
||||
location.href = toLocation.href;
|
||||
}
|
||||
};
|
||||
|
||||
// replace head and body of the windows document with contents from newDocument
|
||||
// if !popstate, update the history entry and scroll position according to toLocation
|
||||
// if popState is given, this holds the scroll position for history navigation
|
||||
// if fallback === "animate" then simulate view transitions
|
||||
async function updateDOM(
|
||||
newDocument: Document,
|
||||
toLocation: URL,
|
||||
popState?: State,
|
||||
fallback?: Fallback
|
||||
) {
|
||||
// Check for a head element that should persist and returns it,
|
||||
// either because it has the data attribute or is a link el.
|
||||
const persistedHeadElement = (el: HTMLElement): Element | null => {
|
||||
const id = el.getAttribute(PERSIST_ATTR);
|
||||
const newEl = id && newDocument.head.querySelector(`[${PERSIST_ATTR}="${id}"]`);
|
||||
if (newEl) {
|
||||
return newEl;
|
||||
}
|
||||
if (el.matches('link[rel=stylesheet]')) {
|
||||
const href = el.getAttribute('href');
|
||||
return newDocument.head.querySelector(`link[rel=stylesheet][href="${href}"]`);
|
||||
}
|
||||
// What follows is a fix for an issue (#8472) with missing client:only styles after transition.
|
||||
// That problem exists only in dev mode where styles are injected into the page by Vite.
|
||||
// Returning a noop element ensures that the styles are not removed from the old document.
|
||||
// Guarding the code below with the dev mode check
|
||||
// allows tree shaking to remove this code in production.
|
||||
if (import.meta.env.DEV) {
|
||||
if (el.tagName === 'STYLE' && el.dataset.viteDevId) {
|
||||
const devId = el.dataset.viteDevId;
|
||||
// If this same style tag exists, remove it from the new page
|
||||
return (
|
||||
newDocument.querySelector(`style[data-astro-dev-id="${devId}"]`) ||
|
||||
// Otherwise, keep it anyways. This is client:only styles.
|
||||
noopEl
|
||||
);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const swap = () => {
|
||||
// swap attributes of the html element
|
||||
// - delete all attributes from the current document
|
||||
// - insert all attributes from doc
|
||||
// - reinsert all original attributes that are named 'data-astro-*'
|
||||
const html = document.documentElement;
|
||||
const astro = [...html.attributes].filter(
|
||||
({ name }) => (html.removeAttribute(name), name.startsWith('data-astro-'))
|
||||
);
|
||||
[...newDocument.documentElement.attributes, ...astro].forEach(({ name, value }) =>
|
||||
html.setAttribute(name, value)
|
||||
);
|
||||
|
||||
// Replace scripts in both the head and body.
|
||||
for (const s1 of document.scripts) {
|
||||
for (const s2 of newDocument.scripts) {
|
||||
if (
|
||||
// Inline
|
||||
(!s1.src && s1.textContent === s2.textContent) ||
|
||||
// External
|
||||
(s1.src && s1.type === s2.type && s1.src === s2.src)
|
||||
) {
|
||||
// the old script is in the new document: we mark it as executed to prevent re-execution
|
||||
s2.dataset.astroExec = '';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Swap head
|
||||
for (const el of Array.from(document.head.children)) {
|
||||
const newEl = persistedHeadElement(el as HTMLElement);
|
||||
// If the element exists in the document already, remove it
|
||||
// from the new document and leave the current node alone
|
||||
if (newEl) {
|
||||
newEl.remove();
|
||||
} else {
|
||||
// Otherwise remove the element in the head. It doesn't exist in the new page.
|
||||
el.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// Everything left in the new head is new, append it all.
|
||||
document.head.append(...newDocument.head.children);
|
||||
|
||||
// Persist elements in the existing body
|
||||
const oldBody = document.body;
|
||||
|
||||
// this will reset scroll Position
|
||||
document.body.replaceWith(newDocument.body);
|
||||
for (const el of oldBody.querySelectorAll(`[${PERSIST_ATTR}]`)) {
|
||||
const id = el.getAttribute(PERSIST_ATTR);
|
||||
const newEl = document.querySelector(`[${PERSIST_ATTR}="${id}"]`);
|
||||
if (newEl) {
|
||||
// The element exists in the new page, replace it with the element
|
||||
// from the old page so that state is preserved.
|
||||
newEl.replaceWith(el);
|
||||
}
|
||||
}
|
||||
|
||||
if (popState) {
|
||||
scrollTo(popState.scrollX, popState.scrollY); // usings 'auto' scrollBehavior
|
||||
} else {
|
||||
updateHistoryAndScrollPosition(toLocation);
|
||||
}
|
||||
|
||||
triggerEvent('astro:after-swap');
|
||||
};
|
||||
|
||||
// Wait on links to finish, to prevent FOUC
|
||||
const links: Promise<any>[] = [];
|
||||
for (const el of newDocument.querySelectorAll('head link[rel=stylesheet]')) {
|
||||
// Do not preload links that are already on the page.
|
||||
if (
|
||||
!document.querySelector(
|
||||
`[${PERSIST_ATTR}="${el.getAttribute(PERSIST_ATTR)}"], link[rel=stylesheet]`
|
||||
)
|
||||
) {
|
||||
const c = document.createElement('link');
|
||||
c.setAttribute('rel', 'preload');
|
||||
c.setAttribute('as', 'style');
|
||||
c.setAttribute('href', el.getAttribute('href')!);
|
||||
links.push(
|
||||
new Promise<any>((resolve) => {
|
||||
['load', 'error'].forEach((evName) => c.addEventListener(evName, resolve));
|
||||
document.head.append(c);
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
links.length && (await Promise.all(links));
|
||||
|
||||
if (fallback === 'animate') {
|
||||
// Trigger the animations
|
||||
const currentAnimations = document.getAnimations();
|
||||
document.documentElement.dataset.astroTransitionFallback = 'old';
|
||||
const newAnimations = document
|
||||
.getAnimations()
|
||||
.filter((a) => !currentAnimations.includes(a) && !isInfinite(a));
|
||||
const finished = Promise.all(newAnimations.map((a) => a.finished));
|
||||
const fallbackSwap = () => {
|
||||
swap();
|
||||
document.documentElement.dataset.astroTransitionFallback = 'new';
|
||||
};
|
||||
await finished;
|
||||
fallbackSwap();
|
||||
} else {
|
||||
swap();
|
||||
}
|
||||
}
|
||||
|
||||
async function transition(direction: Direction, toLocation: URL, popState?: State) {
|
||||
let finished: Promise<void>;
|
||||
const href = toLocation.href;
|
||||
const response = await fetchHTML(href);
|
||||
// If there is a problem fetching the new page, just do an MPA navigation to it.
|
||||
if (response === null) {
|
||||
location.href = href;
|
||||
return;
|
||||
}
|
||||
// if there was a redirection, show the final URL in the browser's address bar
|
||||
if (response.redirected) {
|
||||
toLocation = new URL(response.redirected);
|
||||
}
|
||||
|
||||
const newDocument = parser.parseFromString(response.html, response.mediaType);
|
||||
// The next line might look like a hack,
|
||||
// but it is actually necessary as noscript elements
|
||||
// and their contents are returned as markup by the parser,
|
||||
// see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString
|
||||
newDocument.querySelectorAll('noscript').forEach((el) => el.remove());
|
||||
|
||||
if (!newDocument.querySelector('[name="astro-view-transitions-enabled"]')) {
|
||||
location.href = href;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!popState) {
|
||||
// save the current scroll position before we change the DOM and transition to the new page
|
||||
history.replaceState({ ...history.state, scrollX, scrollY }, '');
|
||||
}
|
||||
document.documentElement.dataset.astroTransition = direction;
|
||||
if (supportsViewTransitions) {
|
||||
// @ts-expect-error: startViewTransition exist
|
||||
finished = document.startViewTransition(() =>
|
||||
updateDOM(newDocument, toLocation, popState)
|
||||
).finished;
|
||||
} else {
|
||||
finished = updateDOM(newDocument, toLocation, popState, getFallback());
|
||||
}
|
||||
try {
|
||||
await finished;
|
||||
} finally {
|
||||
// skip this for the moment as it tends to stop fallback animations
|
||||
// document.documentElement.removeAttribute('data-astro-transition');
|
||||
await runScripts();
|
||||
markScriptsExec();
|
||||
onPageLoad();
|
||||
}
|
||||
}
|
||||
|
||||
// Prefetching
|
||||
function maybePrefetch(pathname: string) {
|
||||
if (document.querySelector(`link[rel=prefetch][href="${pathname}"]`)) return;
|
||||
|
@ -406,83 +70,9 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|||
return;
|
||||
}
|
||||
ev.preventDefault();
|
||||
navigate(link.href);
|
||||
});
|
||||
|
||||
function navigate(href) {
|
||||
// not ours
|
||||
if (!transitionEnabledOnThisPage()) {
|
||||
location.href = href;
|
||||
return;
|
||||
}
|
||||
const toLocation = new URL(href, location.href);
|
||||
// We do not have page transitions on navigations to the same page (intra-page navigation)
|
||||
// but we want to handle prevent reload on navigation to the same page
|
||||
// Same page means same origin, path and query params (but maybe different hash)
|
||||
if (
|
||||
location.origin === toLocation.origin &&
|
||||
location.pathname === toLocation.pathname &&
|
||||
location.search === toLocation.search
|
||||
) {
|
||||
// mark current position as non transition intra-page scrolling
|
||||
if (location.href !== toLocation.href) {
|
||||
history.replaceState({ ...history.state, intraPage: true }, '');
|
||||
history.pushState(
|
||||
{ index: ++currentHistoryIndex, scrollX: 0, scrollY: 0 },
|
||||
'',
|
||||
toLocation.href
|
||||
);
|
||||
}
|
||||
if (toLocation.hash) {
|
||||
location.href = toLocation.href;
|
||||
} else {
|
||||
scrollTo({ left: 0, top: 0, behavior: 'instant' });
|
||||
}
|
||||
} else {
|
||||
transition('forward', toLocation);
|
||||
}
|
||||
}
|
||||
|
||||
addEventListener('popstate', (ev) => {
|
||||
if (!transitionEnabledOnThisPage() && ev.state) {
|
||||
// The current page doesn't have View Transitions enabled
|
||||
// but the page we navigate to does (because it set the state).
|
||||
// Do a full page refresh to reload the client-side router from the new page.
|
||||
// Scroll restauration will then happen during the reload when the router's code is re-executed
|
||||
if (history.scrollRestoration) {
|
||||
history.scrollRestoration = 'manual';
|
||||
}
|
||||
location.reload();
|
||||
return;
|
||||
}
|
||||
|
||||
// History entries without state are created by the browser (e.g. for hash links)
|
||||
// Our view transition entries always have state.
|
||||
// Just ignore stateless entries.
|
||||
// The browser will handle navigation fine without our help
|
||||
if (ev.state === null) {
|
||||
if (history.scrollRestoration) {
|
||||
history.scrollRestoration = 'auto';
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// With the default "auto", the browser will jump to the old scroll position
|
||||
// before the ViewTransition is complete.
|
||||
if (history.scrollRestoration) {
|
||||
history.scrollRestoration = 'manual';
|
||||
}
|
||||
|
||||
const state: State = history.state;
|
||||
if (state.intraPage) {
|
||||
// this is non transition intra-page scrolling
|
||||
scrollTo(state.scrollX, state.scrollY);
|
||||
} else {
|
||||
const nextIndex = state.index;
|
||||
const direction: Direction = nextIndex > currentHistoryIndex ? 'forward' : 'back';
|
||||
currentHistoryIndex = nextIndex;
|
||||
transition(direction, new URL(location.href), state);
|
||||
}
|
||||
navigate(link.href, {
|
||||
history: link.dataset.astroHistory === 'replace' ? 'replace' : 'auto',
|
||||
});
|
||||
});
|
||||
|
||||
['mouseenter', 'touchstart', 'focus'].forEach((evName) => {
|
||||
|
@ -503,17 +93,5 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|||
{ passive: true, capture: true }
|
||||
);
|
||||
});
|
||||
|
||||
addEventListener('load', onPageLoad);
|
||||
// There's not a good way to record scroll position before a back button.
|
||||
// So the way we do it is by listening to scrollend if supported, and if not continuously record the scroll position.
|
||||
const updateState = () => {
|
||||
persistState({ ...history.state, scrollX, scrollY });
|
||||
};
|
||||
|
||||
if ('onscrollend' in window) addEventListener('scrollend', updateState);
|
||||
else addEventListener('scroll', throttle(updateState, 300));
|
||||
|
||||
markScriptsExec();
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
import { expect } from '@playwright/test';
|
||||
import { testFactory } from './test-utils.js';
|
||||
|
||||
const test = testFactory({
|
||||
root: './fixtures/css/',
|
||||
});
|
||||
|
||||
let devServer;
|
||||
|
||||
test.beforeAll(async ({ astro }) => {
|
||||
devServer = await astro.startDevServer();
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
test.describe('CSS Sourcemap HMR', () => {
|
||||
test('removes Astro-injected CSS once Vite-injected CSS loads', async ({ page, astro }) => {
|
||||
const html = await astro.fetch('/').then((res) => res.text());
|
||||
|
||||
// style[data-astro-dev-id] should exist in initial SSR'd markup
|
||||
expect(html).toMatch('data-astro-dev-id');
|
||||
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
// Ensure JS has initialized
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// style[data-astro-dev-id] should NOT exist once JS runs
|
||||
expect(await page.locator('style[data-astro-dev-id]').count()).toEqual(0);
|
||||
|
||||
// style[data-vite-dev-id] should exist now
|
||||
expect(await page.locator('style[data-vite-dev-id]').count()).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
|
@ -29,21 +29,9 @@ test.describe('CSS HMR', () => {
|
|||
await expect(h).toHaveCSS('color', 'rgb(0, 128, 0)');
|
||||
});
|
||||
|
||||
test('removes Astro-injected CSS once Vite-injected CSS loads', async ({ page, astro }) => {
|
||||
test('removes Astro-injected CSS once Vite-injected CSS loads', async ({ astro }) => {
|
||||
const html = await astro.fetch('/').then((res) => res.text());
|
||||
|
||||
// style[data-astro-dev-id] should exist in initial SSR'd markup
|
||||
expect(html).toMatch('data-astro-dev-id');
|
||||
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
// Ensure JS has initialized
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// style[data-astro-dev-id] should NOT exist once JS runs
|
||||
expect(await page.locator('style[data-astro-dev-id]').count()).toEqual(0);
|
||||
|
||||
// style[data-vite-dev-id] should exist now
|
||||
expect(await page.locator('style[data-vite-dev-id]').count()).toBeGreaterThan(0);
|
||||
// style[data-vite-dev-id] should exist in initial SSR'd markup
|
||||
expect(html).toMatch('data-vite-dev-id');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
export default {
|
||||
vite: {
|
||||
css: {
|
||||
devSourcemap: true,
|
||||
}
|
||||
}
|
||||
};
|
|
@ -1 +0,0 @@
|
|||
/// <reference types="astro/client" />
|
|
@ -1,9 +0,0 @@
|
|||
<h1>hello world</h1>
|
||||
|
||||
<style>
|
||||
@import "../styles/main.css";
|
||||
|
||||
h1 {
|
||||
color: var(--h1-color);
|
||||
}
|
||||
</style>
|
|
@ -1,3 +0,0 @@
|
|||
:root {
|
||||
--h1-color: red;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
#one {
|
||||
background-color: whitesmoke;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
h1 {
|
||||
color: blue
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue