another pass at head/body handling in pages

This commit is contained in:
Fred K. Schott 2021-03-21 20:34:11 -07:00
parent e03afbd980
commit 6e4367fd49
16 changed files with 374 additions and 442 deletions

View file

@ -12,7 +12,7 @@
} }
</script> </script>
<slot:head> <astro:head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" /> <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png" /> <link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png" />
@ -27,14 +27,14 @@
<!-- Open Graph / Facebook --> <!-- Open Graph / Facebook -->
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<meta property="og:url" content={context.permalink}/> <meta property="og:url" content={context.permalink} />
<meta property="og:title" content={context.title} /> <meta property="og:title" content={context.title} />
<meta property="og:description" content={context.description} /> <meta property="og:description" content={context.description} />
<meta property="og:image" content="https://www.snowpack.dev/img/social-2.jpg" /> <meta property="og:image" content="https://www.snowpack.dev/img/social-2.jpg" />
<!-- Twitter --> <!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" /> <meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content={context.permalink}/> <meta property="twitter:url" content={context.permalink} />
<meta property="twitter:title" content={context.title} /> <meta property="twitter:title" content={context.title} />
<meta property="twitter:description" content={context.description} /> <meta property="twitter:description" content={context.description} />
<meta property="twitter:image" content="https://www.snowpack.dev/img/social-2.jpg" /> <meta property="twitter:image" content="https://www.snowpack.dev/img/social-2.jpg" />
@ -42,27 +42,21 @@
<!-- Global Stylesheets --> <!-- Global Stylesheets -->
<link rel="stylesheet" href="/css/app.css" /> <link rel="stylesheet" href="/css/app.css" />
<link href="https://fonts.googleapis.com/css2?family=Overpass:wght@400;700;900&display=swap" rel="stylesheet" /> <link href="https://fonts.googleapis.com/css2?family=Overpass:wght@400;700;900&display=swap" rel="stylesheet" />
</astro:head>
<!-- Note: You can then add additional, custom things here as well. --> <Banner></Banner>
<!-- if no slot given, assume add to bottom --> <Nav version={context.currentSnowpackVersion} />
<slot></slot>
</slot:head>
<slot:body> <!-- if no slot given, assume add to bottom -->
<Banner></Banner> <slot></slot>
<Nav version={context.currentSnowpackVersion} />
<!-- if no slot given, assume add to bottom --> <!-- Global site tag (gtag.js) - Google Analytics -->
<slot></slot> <script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-130280175-9"></script>
<script>
<!-- Global site tag (gtag.js) - Google Analytics --> window.dataLayer = window.dataLayer || [];
<script async="async" src="https://www.googletagmanager.com/gtag/js?id=UA-130280175-9"></script> function gtag() {
<script> dataLayer.push(arguments);
window.dataLayer = window.dataLayer || []; }
function gtag() { gtag('js', new Date());
dataLayer.push(arguments); gtag('config', 'UA-130280175-9', { page_path: location.pathname === '/' ? (location.pathname + location.hash) : (location.pathname) });
} </script>
gtag('js', new Date());
gtag('config', 'UA-130280175-9', { page_path: location.pathname === '/' ? (location.pathname + location.hash) : (location.pathname) });
</script>
</slot:body>

View file

@ -8,50 +8,45 @@
} }
</script> </script>
<slot:head>
<style> <style>
.cover-wrapper { .cover-wrapper {
width: 100%; width: 100%;
height: 44vh; height: 44vh;
min-height: 20rem; min-height: 20rem;
max-height: 30rem; max-height: 30rem;
position: relative; position: relative;
background: #2a85ca40; background: #2a85ca40;
overflow: hidden; overflow: hidden;
} }
.cover, .cover,
.cover-blur { .cover-blur {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
bottom: 0; bottom: 0;
right: 0; right: 0;
height: 100%; height: 100%;
width: 100%; width: 100%;
} }
.cover-blur {
object-fit: cover;
filter: blur(3px) brightness(1.5);
transform: scale(1.1);
}
.cover {
object-fit: contain;
filter: brightness(1.5);
}
@media (max-width: 1200px) {
.cover-blur { .cover-blur {
object-fit: cover; object-fit: cover;
filter: blur(3px) brightness(1.5);
transform: scale(1.1);
} }
.cover { .cover {
object-fit: contain; object-fit: cover;
filter: brightness(1.5);
} }
@media (max-width: 1200px) { }
.cover-blur { </style>
object-fit: cover;
}
.cover {
object-fit: cover;
}
}
</style>
<slot></slot>
</slot:head>
<slot:body>
<div class="cover-wrapper"> <div class="cover-wrapper">
<img class="cover-blur" src={context.cover} alt=""/> <img class="cover-blur" src={context.cover} alt=""/>
@ -80,5 +75,4 @@
<Subnav title={context.title} headers={context.content.headers} /> <Subnav title={context.title} headers={context.content.headers} />
</section> </section>
</div> </div>
</slot:body>

View file

@ -11,34 +11,27 @@
} }
</script> </script>
<slot:head> <div class="container">
<section class="snow-view__docs has-subnav">
<slot></slot>
</slot:head>
<slot:body> <aside id="nav-primary" class="snow-view-nav">
<div class="container"> <Menu />
<section class="snow-view__docs has-subnav"> </aside>
<aside id="nav-primary" class="snow-view-nav"> <Subnav title={context.title} headers={context.content.headers} />
<Menu />
</aside>
<Subnav title={context.title} headers={context.content.headers} /> <article class="snow-view-main">
<div class="content">
<article class="snow-view-main"> <h2 class="content-title">
<div class="content"> {context.title}
<h2 class="content-title"> </h2>
{context.title} <div class="content-layout">
</h2> <div class="content-body">
<div class="content-layout"> <slot></slot>
<div class="content-body">
<slot></slot>
</div>
</div> </div>
</div> </div>
</article> </div>
</article>
</section> </section>
</div> </div>
</slot:body>

View file

@ -6,24 +6,16 @@
} }
</script> </script>
<div class="container">
<section class="snow-view__docs is-full">
<slot:head> <aside id="nav-primary" class="snow-view-nav">
<!-- hi --> <Menu />
<slot></slot> </aside>
</slot:head>
<slot:body> <article class="snow-view-main">
<div class="container"> <slot></slot>
<section class="snow-view__docs is-full"> </article>
<aside id="nav-primary" class="snow-view-nav"> </section>
<Menu /> </div>
</aside>
<article class="snow-view-main">
<slot></slot>
</article>
</section>
</div>
</slot:body>

View file

@ -1,143 +1,141 @@
<script astro> <script astro>
import {format as formatDate, parseISO} from 'date-fns'; import { format as formatDate, parseISO } from 'date-fns';
export const layout = 'layouts/base.hmx'; export const layout = 'layouts/base.hmx';
export function setup({ context }) { export function setup({ context }) {
return {}; return {};
} }
</script> </script>
<slot:head> <astro:head>
<link rel="stylesheet" href="/css/legacy-post.css" /> <link rel="stylesheet" href="/css/legacy-post.css" />
<style> </astro:head>
<style>
.markdown-body img,
.markdown-body video,
.markdown-body iframe {
box-shadow: 0px 5px 12px 0 #CCC;
border-radius: 3px;
min-width: 130%;
width: 130%;
margin-left: -15%;
margin-right: -15%;
margin-top: 4rem;
margin-bottom: -1rem;
}
@media (max-width: 860px) {
.markdown-body img, .markdown-body img,
.markdown-body video, .markdown-body video,
.markdown-body iframe { .markdown-body iframe {
box-shadow: 0px 5px 12px 0 #CCC; min-width: 100%;
border-radius: 3px; margin-left: 0;
min-width: 130%; margin-right: 0;
width: 130%; margin-bottom: -2rem;
margin-left: -15%;
margin-right: -15%;
margin-top: 4rem;
margin-bottom: -1rem;
} }
}
@media (max-width: 860px) {
.markdown-body img,
.markdown-body video,
.markdown-body iframe { .markdown-body table td:nth-child(1) {
min-width: 100%; white-space: nowrap;
margin-left: 0; }
margin-right: 0;
margin-bottom: -2rem; .grid-body {
} padding: 4rem 0;
}
.grid-body-header h1 {
margin-bottom: 1rem;
margin-top: 1rem;
}
.markdown-body,
.fbody-header {
max-width: 840px;
}
.markdown-body {
font-size: 18px;
margin-bottom: 20vh;
}
.markdown-body h2 {
font-size: 1.8em;
}
@media (max-width: 860px) {
.markdown-body,
.toc {
padding: 1em;
} }
}
@media (max-width: 740px) {
.markdown-body img,
.markdown-body iframe {
.markdown-body table td:nth-child(1) { max-width: 108%;
white-space: nowrap; margin-left: -4%;
margin-right: -4%;
} }
.grid-body { .grid-body {
padding: 4rem 0; padding: 20px 0 0 0;
} }
.grid-body-header h1 { .header-snowpack {
margin-bottom: 1rem; font-size: 3.5rem;
margin-top: 1rem; text-align: center;
} }
.markdown-body, .markdown-body h1 {
.fbody-header { font-size: 3.5em;
max-width: 840px;
} }
.markdown-body { .markdown-body h3 .header-link {
font-size: 18px; opacity: 1;
margin-bottom: 20vh;
} }
}
</style>
.markdown-body h2 { <div class="grid-extra-space">
font-size: 1.8em; <div class="grid-body-header">
} <svg height="80px" style="padding-left: 8px;" viewBox="0 0 640 512" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
@media (max-width: 860px) { <g id="Page-1" stroke="none" stroke-width="1" fill="currentColor" fill-rule="evenodd">
<g id="mountain-solid" transform="translate(-1.000000, 0.000000)" fill-rule="nonzero">
.markdown-body, <path
.toc { d="M635.92,462.7 L347.92,14.7 C342.03,5.54 331.89,0 321,0 C310.11,0 299.97,5.54 294.08,14.7 L6.08,462.7 C-0.250773249,472.547007 -0.699487627,485.064987 4.91,495.34 C10.522069,505.612419 21.2945349,512 33,512 L609,512 C620.71,512 631.48,505.61 637.09,495.33 C642.699457,485.058495 642.250708,472.543372 635.92,462.7 Z M321,91.18 L406.39,224 L321,224 L257,288 L218.94,249.94 L321,91.18 Z"
padding: 1em; id="Shape"></path>
}
}
@media (max-width: 740px) {
.markdown-body img,
.markdown-body iframe {
max-width: 108%;
margin-left: -4%;
margin-right: -4%;
}
.grid-body {
padding: 20px 0 0 0;
}
.header-snowpack {
font-size: 3.5rem;
text-align: center;
}
.markdown-body h1 {
font-size: 3.5em;
}
.markdown-body h3 .header-link {
opacity: 1;
}
}
</style>
<slot></slot>
</slot:head>
<slot:body>
<div class="grid-extra-space">
<div class="grid-body-header">
<svg height="80px" style="padding-left: 8px;" viewBox="0 0 640 512" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Page-1" stroke="none" stroke-width="1" fill="currentColor" fill-rule="evenodd">
<g id="mountain-solid" transform="translate(-1.000000, 0.000000)" fill-rule="nonzero">
<path
d="M635.92,462.7 L347.92,14.7 C342.03,5.54 331.89,0 321,0 C310.11,0 299.97,5.54 294.08,14.7 L6.08,462.7 C-0.250773249,472.547007 -0.699487627,485.064987 4.91,495.34 C10.522069,505.612419 21.2945349,512 33,512 L609,512 C620.71,512 631.48,505.61 637.09,495.33 C642.699457,485.058495 642.250708,472.543372 635.92,462.7 Z M321,91.18 L406.39,224 L321,224 L257,288 L218.94,249.94 L321,91.18 Z"
id="Shape"></path>
</g>
</g> </g>
</svg> </g>
<h1 class="header-snowpack">{context.title}</h1> </svg>
<h1 class="header-snowpack">{context.title}</h1>
<div>
{context.tagline && <div style="margin-bottom: 1rem;">{context.tagline}</div>}
<div> <div>
{context.tagline && <div style="margin-bottom: 1rem;">{context.tagline}</div>} Published <a href='#published-at'>{formatDate(parseISO(context.date), 'MMMM d, yyyy')}</a>
<div> by <a href="https://twitter.com/FredKSchott">Fred K. Schott</a>
Published <a href='#published-at'>{formatDate(parseISO(context.date), 'MMMM d, yyyy')}</a>
by <a href="https://twitter.com/FredKSchott">Fred K. Schott</a>
</div>
</div> </div>
</div>
<!-- Place this tag where you want the button to render. --> <!-- Place this tag where you want the button to render. -->
<div class="hidden-mobile" style="text-align: center; margin-top: 0.5rem; filter: scale(2);"> <div class="hidden-mobile" style="text-align: center; margin-top: 0.5rem; filter: scale(2);">
<a class="github-button" href="https://github.com/snowpackjs/snowpack" data-icon="octicon-star" <a class="github-button" href="https://github.com/snowpackjs/snowpack" data-icon="octicon-star" data-size="large"
data-size="large" data-show-count="true" aria-label="Star snowpackjs/snowpack on GitHub">Star</a> data-show-count="true" aria-label="Star snowpackjs/snowpack on GitHub">Star</a>
</div>
<!-- Place this tag in your head or just before your close body tag. -->
<script defer src="https://buttons.github.io/buttons.js"></script>
</div>
</div> </div>
<div class="grid-body"> <!-- Place this tag in your head or just before your close body tag. -->
<article class="markdown-body"> <script defer src="https://buttons.github.io/buttons.js"></script>
<slot></slot> </div>
</article> </div>
</div> <div class="grid-body">
</slot:body> <article class="markdown-body">
<slot></slot>
</article>
</div>

View file

@ -42,38 +42,32 @@
} }
</script> </script>
<slot:head> <h2 class="content-title">
{context.title}
</h2>
</slot:head> <h3 class="content-title">
Using Snowpack
</h3>
<slot:body> <div class="content">
<h2 class="content-title"> <ul>
{context.title} {context.guides.map((post) => {
</h2> return <li><a href={post.href}>{post.title}</a></li>;
<h3 class="content-title">
Using Snowpack
</h3>
<div class="content">
<ul>
{context.guides.map((post) => {
return <li><a href={post.href}>{post.title}</a></li>;
})}
</ul>
</div>
<br />
<br />
<h3 class="content-title">
Popular Integration Guides
</h3>
<div class="card-grid card-grid-4">
{context.communityGuides.map((post) => {
return
<Card item={post} />;
})} })}
</div> </ul>
</slot:body> </div>
<br />
<br />
<h3 class="content-title">
Popular Integration Guides
</h3>
<div class="card-grid card-grid-4">
{context.communityGuides.map((post) => {
return
<Card item={post} />;
})}
</div>

View file

@ -3,95 +3,91 @@
import Hero from '../components/Hero.hmx'; import Hero from '../components/Hero.hmx';
export const layout = 'layouts/base.hmx'; export const layout = 'layouts/base.hmx';
export function setup({context}) { export function setup({ context }) {
return {} return {}
} }
</script> </script>
<slot:head> <astro:head>
<meta charset="AAA" /> <meta charset="AAA" />
</slot:head> </astro:head>
<Hero bar={context.title}></Hero>
<slot:body> <div foo={context.title} class="container" style="margin: 0 auto">
<Hero bar={context.title}></Hero> <section class="snow-view__docs is-full is-home">
<div foo={context.title} class="container" style="margin: 0 auto"> <aside id="nav-primary" class="snow-view-nav">
<section class="snow-view__docs is-full is-home"> <Menu></Menu>
</aside>
<aside id="nav-primary" class="snow-view-nav">
<Menu></Menu> <article class="snow-view-main">
</aside> <div class="content">
<article class="grid-body">
<article class="snow-view-main"> <a class="img-banner" href="https://osawards.com/javascript/2020" target="_blank" rel="noopener noreferrer">
<div class="content"> <img src="/img/JSAwardWinner.png" alt="2020 JavaScript Open Source Award Winner banner" />
<article class="grid-body"> </a>
<a class="img-banner" href="https://osawards.com/javascript/2020" target="_blank"
rel="noopener noreferrer"> <div class="content markdown-body feature-list">
<img src="/img/JSAwardWinner.png" alt="2020 JavaScript Open Source Award Winner banner" /> <div class="feature-list-top">
</a> <p>
<strong>Snowpack is a lightning-fast frontend build tool, designed for the modern web.</strong>
<div class="content markdown-body feature-list"> It is an alternative to heavier, more complex bundlers like webpack or Parcel in your development
<div class="feature-list-top"> workflow. Snowpack leverages JavaScript's native module system (<a
<p> href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import">known
<strong>Snowpack is a lightning-fast frontend build tool, designed for the modern web.</strong> as
It is an alternative to heavier, more complex bundlers like webpack or Parcel in your development ESM</a>) to avoid unnecessary work and stay fast no matter how big your project grows.
workflow. Snowpack leverages JavaScript's native module system (<a </p>
href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import">known <p>Once you try it, it's impossible to go back to anything else.</p>
as </div>
ESM</a>) to avoid unnecessary work and stay fast no matter how big your project grows.
</p> <ul class="feature-list-bullets">
<p>Once you try it, it's impossible to go back to anything else.</p> <li class="feature-list-bullet">
</div> <h3>Instant startup</h3>
Snowpack's unbundled web development server
<ul class="feature-list-bullets"> <strong>starts up in 50ms or less</strong>
<li class="feature-list-bullet"> and stays fast in large projects.
<h3>Instant startup</h3> </li>
Snowpack's unbundled web development server <li class="feature-list-bullet">
<strong>starts up in 50ms or less</strong> <h3>Build once, cache forever</h3>
and stays fast in large projects. Snowpack never builds the same file twice. Powered by JavaScripts native module system (ESM) in the
</li> browser.
<li class="feature-list-bullet"> </li>
<h3>Build once, cache forever</h3> <li class="feature-list-bullet">
Snowpack never builds the same file twice. Powered by JavaScripts native module system (ESM) in the <h3>HMR feat. Fast Refresh</h3>
browser. No refresh required. See changes reflected instantly in the browser with
</li> <a href="/concepts/hot-module-replacement">HMR + Fast Refresh</a>
<li class="feature-list-bullet"> for React, Preact & Svelte.
<h3>HMR feat. Fast Refresh</h3> </li>
No refresh required. See changes reflected instantly in the browser with <li class="feature-list-bullet">
<a href="/concepts/hot-module-replacement">HMR + Fast Refresh</a> <h3>Out-of-the-box support</h3>
for React, Preact & Svelte. Enjoy Snowpack's built-in support for JSX, TypeScript, React, Preact, CSS Modules
</li> <a href="/reference/supported-files">and more.</a>
<li class="feature-list-bullet"> </li>
<h3>Out-of-the-box support</h3> <li class="feature-list-bullet">
Enjoy Snowpack's built-in support for JSX, TypeScript, React, Preact, CSS Modules <h3>Optimize for production</h3>
<a href="/reference/supported-files">and more.</a> Build for production with built-in optimizations and plugin support for your favorite bundlers.
</li> </li>
<li class="feature-list-bullet"> <li class="feature-list-bullet">
<h3>Optimize for production</h3> <h3>Plugins? Plugins!</h3>
Build for production with built-in optimizations and plugin support for your favorite bundlers. Babel? Sass? MDX? Browse the entire
</li> <a href="/plugins">Snowpack Plugin Catalog</a>
<li class="feature-list-bullet"> to connect your favorite build tool (or
<h3>Plugins? Plugins!</h3> <a href="/reference/plugins">create your own!</a>)
Babel? Sass? MDX? Browse the entire </li>
<a href="/plugins">Snowpack Plugin Catalog</a> </ul>
to connect your favorite build tool (or
<a href="/reference/plugins">create your own!</a>) <div class="feature-list-buttons">
</li> <a href="/tutorials/quick-start" class="button button-primary feature-list-button">Get started</a>
</ul> <a href="/concepts/how-snowpack-works" class="button feature-list-button">Learn more</a>
</div>
<div class="feature-list-buttons">
<a href="/tutorials/quick-start" class="button button-primary feature-list-button">Get started</a>
<a href="/concepts/how-snowpack-works" class="button feature-list-button">Learn more</a>
</div>
</div>
</article>
</div> </div>
</article> </article>
</section> </div>
</div>
</article>
<!-- Place this tag in your head or just before your close body tag. --> </section>
<script async="async" defer="defer" src="https://buttons.github.io/buttons.js"></script> </div>
</slot:body>
<!-- Place this tag in your head or just before your close body tag. -->
<script async="async" defer="defer" src="https://buttons.github.io/buttons.js"></script>

View file

@ -25,58 +25,54 @@
} }
</script> </script>
<slot:head> </slot:head> <NewsTitle title={context.title} />
<slot:body> <p>
<NewsTitle title={context.title} /> Get the latest news, blog posts, and tutorials on Snowpack. <a href="/feed.xml">Also available via RSS.</a>
</p>
<p> <p>
Get the latest news, blog posts, and tutorials on Snowpack. <a href="/feed.xml">Also available via RSS.</a> Got something that you think we should feature?
</p> <a href="https://github.com/snowpackjs/snowpack/edit/main/www/_data/news.js">Submit it!</a>
</p>
<p> <p>
Got something that you think we should feature? In case you're curious, the best pokemon is <strong>{context.pokemonData.name}.</strong>
<a href="https://github.com/snowpackjs/snowpack/edit/main/www/_data/news.js">Submit it!</a> </p>
</p>
<p> <div class="card-grid card-grid-3">
In case you're curious, the best pokemon is <strong>{context.pokemonData.name}.</strong> <article class="discord-banner">
</p> <a href="https://discord.gg/snowpack" style="flex-shrink: 0; height: 48px;"><img alt="Join us on Discord!"
src="https://img.shields.io/discord/712696926406967308.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2"
style="height: 48px; border: none; margin-right: 1rem; filter: brightness(1.2) contrast(1.5);" /></a>
<div>Join us on Discord to discuss Snowpack, meet other developers in our community, and show off what youre
working on!</div>
</article>
<div class="card-grid card-grid-3"> {context.news.reverse().map((item) =>
<article class="discord-banner"> <Card:dynamic item={item} />)}
<a href="https://discord.gg/snowpack" style="flex-shrink: 0; height: 48px;"><img alt="Join us on Discord!" </div>
src="https://img.shields.io/discord/712696926406967308.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2"
style="height: 48px; border: none; margin-right: 1rem; filter: brightness(1.2) contrast(1.5);" /></a>
<div>Join us on Discord to discuss Snowpack, meet other developers in our community, and show off what youre
working on!</div>
</article>
{context.news.reverse().map((item) => <div class="content">
<Card:dynamic item={item} />)}
<h3>Who's Using Snowpack?</h3>
<div class="company-logos">
{context.users.map((user) =>
<CompanyLogo user={user} />)}
<a href="https://github.com/snowpackjs/snowpack/edit/main/www/_template/news.md" target="_blank"
title="Add Your Project/Company!" class="add-company-button">
<svg style="height: 22px; margin-right: 8px;" aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="plus" class="company-logo" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path fill="currentColor"
d="M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z">
</path>
</svg>
Add your logo
</a>
</div> </div>
<div class="content"> <NewsAssets />
</div>
<h3>Who's Using Snowpack?</h3>
<div class="company-logos">
{context.users.map((user) =>
<CompanyLogo user={user} />)}
<a href="https://github.com/snowpackjs/snowpack/edit/main/www/_template/news.md" target="_blank"
title="Add Your Project/Company!" class="add-company-button">
<svg style="height: 22px; margin-right: 8px;" aria-hidden="true" focusable="false" data-prefix="fas"
data-icon="plus" class="company-logo" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path fill="currentColor"
d="M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z">
</path>
</svg>
Add your logo
</a>
</div>
<NewsAssets />
</div>
</slot:body>

View file

@ -13,19 +13,14 @@
} }
</script> </script>
<slot:head> <h2 class="content-title">
</slot:head> { context.title }
</h2>
<slot:body> <h3 class="pluginPage-subheading">Customize Snowpack with optimized build plugins.</h3>
<h2 class="content-title"> <p class="pluginPage-intro">To learn more about our plugin system, check out the
{ context.title } <a href="/reference/plugins">Plugin API.</a><br />Can't find what you need?
</h2> <a href="/reference/plugins">Creating your own plugin is easy!</a>
</p>
<h3 class="pluginPage-subheading">Customize Snowpack with optimized build plugins.</h3> <PluginSearchPage:dynamic />
<p class="pluginPage-intro">To learn more about our plugin system, check out the
<a href="/reference/plugins">Plugin API.</a><br />Can't find what you need?
<a href="/reference/plugins">Creating your own plugin is easy!</a>
</p>
<PluginSearchPage:dynamic />
</slot:body>

View file

@ -18,7 +18,6 @@ export interface JsxItem {
export interface TransformResult { export interface TransformResult {
script: string; script: string;
head: JsxItem | undefined; head: JsxItem | undefined;
body: JsxItem | undefined;
items: JsxItem[]; items: JsxItem[];
} }

View file

@ -189,9 +189,7 @@ export async function codegen(ast: Ast, { compileOptions }: CodeGenOptions): Pro
const additionalImports = new Set<string>(); const additionalImports = new Set<string>();
let headItem: JsxItem | undefined; let headItem: JsxItem | undefined;
let bodyItem: JsxItem | undefined;
let items: JsxItem[] = []; let items: JsxItem[] = [];
let mode: 'JSX' | 'SCRIPT' | 'SLOT' = 'JSX';
let collectionItem: JsxItem | undefined; let collectionItem: JsxItem | undefined;
let currentItemName: string | undefined; let currentItemName: string | undefined;
let currentDepth = 0; let currentDepth = 0;
@ -225,10 +223,6 @@ export async function codegen(ast: Ast, { compileOptions }: CodeGenOptions): Pro
} }
collectionItem!.jsx += `,(${code.trim().replace(/\;$/, '')})`; collectionItem!.jsx += `,(${code.trim().replace(/\;$/, '')})`;
return; return;
case 'Slot':
mode = 'SLOT';
collectionItem!.jsx += `,child`;
return;
case 'Comment': case 'Comment':
return; return;
case 'Fragment': case 'Fragment':
@ -239,8 +233,8 @@ export async function codegen(ast: Ast, { compileOptions }: CodeGenOptions): Pro
} }
break; break;
case 'Slot':
case 'Head': case 'Head':
case 'Body':
case 'InlineComponent': case 'InlineComponent':
case 'Title': case 'Title':
case 'Element': { case 'Element': {
@ -251,7 +245,6 @@ export async function codegen(ast: Ast, { compileOptions }: CodeGenOptions): Pro
const attributes = getAttributes(node.attributes); const attributes = getAttributes(node.attributes);
currentDepth++; currentDepth++;
currentItemName = name; currentItemName = name;
if (!collectionItem) { if (!collectionItem) {
collectionItem = { name, jsx: '' }; collectionItem = { name, jsx: '' };
if (node.type === 'Head') { if (node.type === 'Head') {
@ -259,14 +252,13 @@ export async function codegen(ast: Ast, { compileOptions }: CodeGenOptions): Pro
headItem = collectionItem; headItem = collectionItem;
return; return;
} }
if (node.type === 'Body') {
collectionItem.jsx += `h(Fragment, null`;
bodyItem = collectionItem;
return;
}
items.push(collectionItem); items.push(collectionItem);
} }
collectionItem.jsx += collectionItem.jsx === '' ? '' : ','; collectionItem.jsx += collectionItem.jsx === '' ? '' : ',';
if (node.type === 'Slot') {
collectionItem.jsx += `(children`;
return;
}
const COMPONENT_NAME_SCANNER = /^[A-Z]/; const COMPONENT_NAME_SCANNER = /^[A-Z]/;
if (!COMPONENT_NAME_SCANNER.test(name)) { if (!COMPONENT_NAME_SCANNER.test(name)) {
collectionItem.jsx += `h("${name}", ${attributes ? generateAttributes(attributes) : 'null'}`; collectionItem.jsx += `h("${name}", ${attributes ? generateAttributes(attributes) : 'null'}`;
@ -296,9 +288,6 @@ export async function codegen(ast: Ast, { compileOptions }: CodeGenOptions): Pro
} }
case 'Text': { case 'Text': {
const text = getTextFromAttribute(node); const text = getTextFromAttribute(node);
if (mode === 'SLOT') {
return;
}
if (!text.trim()) { if (!text.trim()) {
return; return;
} }
@ -323,17 +312,11 @@ export async function codegen(ast: Ast, { compileOptions }: CodeGenOptions): Pro
case 'Attribute': case 'Attribute':
case 'Comment': case 'Comment':
return; return;
case 'Slot': {
const name = node.name;
if (name === 'slot') {
mode = 'JSX';
}
return;
}
case 'Fragment': case 'Fragment':
if (!collectionItem) { if (!collectionItem) {
return; return;
} }
case 'Slot':
case 'Head': case 'Head':
case 'Body': case 'Body':
case 'Title': case 'Title':
@ -360,7 +343,6 @@ export async function codegen(ast: Ast, { compileOptions }: CodeGenOptions): Pro
return { return {
script: script + '\n' + Array.from(additionalImports).join('\n'), script: script + '\n' + Array.from(additionalImports).join('\n'),
head: headItem, head: headItem,
body: bodyItem,
items, items,
}; };
} }

View file

@ -14,8 +14,8 @@ import list from '../../utils/list.js';
const valid_tag_name = /^\!?[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/; const valid_tag_name = /^\!?[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/;
const meta_tags = new Map([ const meta_tags = new Map([
['slot:head', 'Head'], ['astro:head', 'Head'],
['slot:body', 'Body'], // ['slot:body', 'Body'],
// ['astro:options', 'Options'], // ['astro:options', 'Options'],
// ['astro:window', 'Window'], // ['astro:window', 'Window'],
// ['astro:body', 'Body'], // ['astro:body', 'Body'],

View file

@ -134,7 +134,7 @@ export default function ({ filename, fileID }: { filename: string; fileID: strin
const code = node.content.styles; const code = node.content.styles;
const typeAttr = (node.attributes || []).find(({ name }: { name: string }) => name === 'type'); const typeAttr = (node.attributes || []).find(({ name }: { name: string }) => name === 'type');
styleNodes.push(node); styleNodes.push(node);
styleTransformPromises.push(transformStyle(code, { type: (typeAttr.value[0] && typeAttr.value[0].raw) || undefined, filename, fileID })); styleTransformPromises.push(transformStyle(code, { type: (typeAttr && typeAttr.value[0] && typeAttr.value[0].raw) || undefined, filename, fileID }));
// TODO: we should delete the old untransformed <style> node after were done. // TODO: we should delete the old untransformed <style> node after were done.
// However, the svelte parser left it in ast.css, not ast.html. At the final step, this just gets ignored, so it will be deleted, in a sense. // However, the svelte parser left it in ast.css, not ast.html. At the final step, this just gets ignored, so it will be deleted, in a sense.

View file

@ -78,7 +78,7 @@ async function convertMdToJsx(
export function setup({context}) { export function setup({context}) {
return {context: ${stringifiedSetupContext} }; return {context: ${stringifiedSetupContext} };
} }
</script><slot:head></slot:head><slot:body><section>{${JSON.stringify(mdHtml)}}</section></slot:body>`, </script><section>{${JSON.stringify(mdHtml)}}</section>`,
{ compileOptions, filename, fileID } { compileOptions, filename, fileID }
); );
} }
@ -104,9 +104,7 @@ export async function compileComponent(
): Promise<CompileResult> { ): Promise<CompileResult> {
const sourceJsx = await transformFromSource(source, { compileOptions, filename, projectRoot }); const sourceJsx = await transformFromSource(source, { compileOptions, filename, projectRoot });
const headItem = sourceJsx.head; const headItem = sourceJsx.head;
const bodyItem = sourceJsx.body;
const headItemJsx = !headItem ? 'null' : headItem.jsx; const headItemJsx = !headItem ? 'null' : headItem.jsx;
const bodyItemJsx = !bodyItem ? 'null' : bodyItem.jsx;
// sort <style> tags first // sort <style> tags first
// TODO: remove these and inject in <head> // TODO: remove these and inject in <head>
@ -120,23 +118,21 @@ ${sourceJsx.script}
// \`__render()\`: Render the contents of the HMX module. "<slot:*>" elements are not // \`__render()\`: Render the contents of the HMX module. "<slot:*>" elements are not
// included (see below). // included (see below).
import { h, Fragment } from '${internalImport('h.js')}'; import { h, Fragment } from '${internalImport('h.js')}';
export default function __render(props) { return h(Fragment, null, ${sourceJsx.items.map(({ jsx }) => jsx).join(',')}); } export function __slothead(children, context) { return h(Fragment, null, ${headItemJsx}); }
function __render(props, children, context) { return h(Fragment, null, ${sourceJsx.items.map(({ jsx }) => jsx).join(',')}); }
// <slot:*> render functions export default __render;
export function __slothead(context, child) { return h(Fragment, null, ${headItemJsx}); }
export function __slotbody(context, child) { return h(Fragment, null, ${bodyItemJsx}); }
`; `;
if (headItemJsx || bodyItemJsx) { if (headItemJsx) {
modJsx += ` modJsx += `
// \`__renderPage()\`: Render the contents of the HMX module as a page. This is a special flow, // \`__renderPage()\`: Render the contents of the HMX module as a page. This is a special flow,
// triggered by loading a component directly by URL. // triggered by loading a component directly by URL.
// If the page exports a defined "layout", then load + render those first. "context", "slot:head", // If the page exports a defined "layout", then load + render those first. "context", "astro:head",
// and "slot:body" should all inherit from parent layouts, merging together in the correct order. // and "slot:body" should all inherit from parent layouts, merging together in the correct order.
export async function __renderPage({request, children}) { export async function __renderPage({request, children}) {
const currentChild = { const currentChild = {
__slothead, __slothead,
__slotbody, __render,
setup: typeof setup === 'undefined' ? (passthrough) => passthrough : setup, setup: typeof setup === 'undefined' ? (passthrough) => passthrough : setup,
layout: typeof layout === 'undefined' ? undefined : layout, layout: typeof layout === 'undefined' ? undefined : layout,
}; };
@ -166,12 +162,12 @@ export async function __renderPage({request, children}) {
let headResult; let headResult;
let bodyResult; let bodyResult;
for (const child of children.reverse()) { for (const child of children.reverse()) {
headResult = await child.__slothead(mergedContext, headResult); headResult = await child.__slothead([headResult], mergedContext);
bodyResult = await child.__slotbody(mergedContext, bodyResult); bodyResult = await child.__render(undefined, [bodyResult], mergedContext);
} }
return h(Fragment, null, [ return h(Fragment, null, [
h("head", null, currentChild.__slothead(mergedContext, headResult)), h("head", null, currentChild.__slothead([headResult], mergedContext)),
h("body", null, currentChild.__slotbody(mergedContext, bodyResult)), h("body", null, currentChild.__render(undefined, [bodyResult], mergedContext)),
]); ]);
};\n`; };\n`;
} }

View file

@ -6,10 +6,8 @@
} }
</script> </script>
<slot:head> <astro:head>
<!-- Head Stuff --> <!-- Head Stuff -->
</slot:head> </astro:head>
<slot:body> <h1>Hello world!</h1>
<h1>Hello world!</h1>
</slot:body>

View file

@ -7,6 +7,9 @@ import { doc } from './test-utils.js';
const { readdir, stat } = fsPromises; const { readdir, stat } = fsPromises;
// Bug: Snowpack config is still loaded relative to the current working directory.
process.chdir(new URL('../examples/snowpack/', import.meta.url).pathname);
const SnowpackDev = suite('snowpack.dev'); const SnowpackDev = suite('snowpack.dev');
let runtime; let runtime;
@ -67,8 +70,10 @@ SnowpackDev('Can load every page', async () => {
assert.equal(result.statusCode, 200, `Loading ${pathname}`); assert.equal(result.statusCode, 200, `Loading ${pathname}`);
} }
console.error(failed); if (failed.length > 0) {
assert.equal(failed.length, 1, 'Failed pages (1 expected)'); console.error(failed);
}
assert.equal(failed.length, 0, 'Failed pages');
}); });
SnowpackDev.run(); SnowpackDev.run();