From 11637df5791863cde061c52d5c2dc1654cc3f30f Mon Sep 17 00:00:00 2001 From: Drew Powers <1369770+drwpow@users.noreply.github.com> Date: Thu, 25 Mar 2021 18:23:45 -0600 Subject: [PATCH] Improve styles (#30) --- examples/snowpack/astro/components/Hero.astro | 40 +++++++++++++ examples/snowpack/astro/components/Menu.astro | 4 +- examples/snowpack/astro/components/Nav.astro | 21 ++++++- .../astro/components/PluginSearchPage.jsx | 2 +- .../components/PluginSearchPage.module.css | 10 ++++ examples/snowpack/astro/pages/index.astro | 41 ++++++------- examples/snowpack/public/css/_globals.scss | 3 - examples/snowpack/public/css/app.scss | 1 - .../snowpack/public/css/components/_logo.scss | 29 --------- src/compiler/optimize/styles.ts | 60 +++++++++++++++---- 10 files changed, 141 insertions(+), 70 deletions(-) delete mode 100644 examples/snowpack/public/css/components/_logo.scss diff --git a/examples/snowpack/astro/components/Hero.astro b/examples/snowpack/astro/components/Hero.astro index 8b287c197e..441f30f12e 100644 --- a/examples/snowpack/astro/components/Hero.astro +++ b/examples/snowpack/astro/components/Hero.astro @@ -1,5 +1,6 @@ <style lang="scss"> @use '../../public/css/var' as *; + @use '../../public/css/animations' as *; .hero { display: flex; @@ -83,6 +84,8 @@ margin: 0 auto 0.75rem; font-weight: 900; font-size: 3.5rem; + font-weight: 700; + font-family: $heading; line-height: 1; letter-spacing: -0.045em; text-align: center; @@ -99,6 +102,7 @@ margin: 0; margin: auto; font-weight: 500; + font-family: $heading; font-size: 2rem; line-height: 1; letter-spacing: -1px; @@ -108,6 +112,42 @@ font-size: 3rem; } } + + .copy-button { + display: flex; + flex: none; + align-items: center; + justify-content: center; + box-sizing: border-box; + min-width: 292px; + padding: 0.75rem 1.25rem; + padding-bottom: 0.75rem; + font-size: 100%; + font-family: Menlo, ui-monospace, SFMono-Regular, Monaco, Consolas, + Liberation Mono, Courier New, monospace; + line-height: 1.5rem; + background-color: white; + border: 1px solid #0006; + border-radius: 4px; + cursor: pointer; + @include animation-copy-button; + + svg, + .faded { + color: #ccc; + transition: color 0.1s ease-out; + } + } + + // I don't think this is used + .copy-button.active { + animation: pulse 0.5s; + animation-iteration-count: 1; + + svg { + color: #ccc; + } + } </style> <div class="hero"> diff --git a/examples/snowpack/astro/components/Menu.astro b/examples/snowpack/astro/components/Menu.astro index f96961aed8..120a8af86e 100644 --- a/examples/snowpack/astro/components/Menu.astro +++ b/examples/snowpack/astro/components/Menu.astro @@ -120,11 +120,11 @@ </li> <li class="section"> - <a class="link" href="/plugins"><span class="section-header">Plugin Catalog</span></a> + <a class="link" href="/plugins"><span class="header">Plugin Catalog</span></a> </li> <li class="section"> - <a class="link" href="/news"><span class="section-header">Community & News</span></a> + <a class="link" href="/news"><span class="header">Community & News</span></a> </li> </ol> </nav> diff --git a/examples/snowpack/astro/components/Nav.astro b/examples/snowpack/astro/components/Nav.astro index 31ef33e3d3..3582bd0a02 100644 --- a/examples/snowpack/astro/components/Nav.astro +++ b/examples/snowpack/astro/components/Nav.astro @@ -63,6 +63,7 @@ export let version: string = '3.1.2'; .logo { display: flex; + align-items: center; grid-area: logo; justify-content: center; padding: 0.5rem; @@ -76,6 +77,22 @@ export let version: string = '3.1.2'; } } + .logo-icon { + display: block; + width: 1em; + height: 1em; + margin-right: 0.25em; + margin-bottom: 0.15rem; + fill: currentColor; + } + + .logo-type { + font-weight: 700; + font-family: $heading; + letter-spacing: -0.03em; + padding-top: 0.2rem; + } + .mobile-open { display: flex; grid-area: mobile; @@ -233,8 +250,8 @@ export let version: string = '3.1.2'; </path> </svg> </button> - <a class="logo snow-logo" href="/"> - <svg class="snow-logo-icon" viewbox="0 0 640 512" version="1.1" xmlns="http://www.w3.org/2000/svg" + <a class="logo" href="/"> + <svg class="logo-icon" viewbox="0 0 640 512" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <g transform="translate(-1.000000, 0.000000)" fill-rule="nonzero"> <path diff --git a/examples/snowpack/astro/components/PluginSearchPage.jsx b/examples/snowpack/astro/components/PluginSearchPage.jsx index 8f3cd98d6e..621cbe02b3 100644 --- a/examples/snowpack/astro/components/PluginSearchPage.jsx +++ b/examples/snowpack/astro/components/PluginSearchPage.jsx @@ -1,6 +1,6 @@ import { h, Fragment } from 'preact'; import { useEffect, useState } from 'preact/hooks'; -import * as Styles from './PluginSearchPage.module.css'; +import Styles from './PluginSearchPage.module.css'; async function searchPlugins(val) { const params3 = new URLSearchParams([ diff --git a/examples/snowpack/astro/components/PluginSearchPage.module.css b/examples/snowpack/astro/components/PluginSearchPage.module.css index a36eb8ab74..d67dfd72d1 100644 --- a/examples/snowpack/astro/components/PluginSearchPage.module.css +++ b/examples/snowpack/astro/components/PluginSearchPage.module.css @@ -4,6 +4,16 @@ padding: 0.5rem 0.5rem 0.5rem 48px; flex-direction: column; position: relative; + display: flex; + grid-column: span 1; + overflow: hidden; + font-family: Open Sans, system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, + Cantarell, Noto Sans, sans-serif, BlinkMacSystemFont, Segoe UI, Roboto, + sans-serif; + color: #1a202c; + -webkit-font-smoothing: antialiased; + box-sizing: border-box; + border: 1px solid #e2e8f0; } .Card:nth-child(3n + 2) .Icon__Plugin { diff --git a/examples/snowpack/astro/pages/index.astro b/examples/snowpack/astro/pages/index.astro index 3e2adccda2..48ffa1c89a 100644 --- a/examples/snowpack/astro/pages/index.astro +++ b/examples/snowpack/astro/pages/index.astro @@ -13,7 +13,7 @@ let description = 'Snowpack is a lightning-fast frontend build tool, designed fo <head> <style lang="scss"> @use '../../public/css/var' as *; - + .top { text-align: left; } @@ -27,7 +27,7 @@ let description = 'Snowpack is a lightning-fast frontend build tool, designed fo padding: 0.1em !important; list-style: none; - h3 { + .bullet-heading { margin: 0 0 0.25em 0; font-size: 1.25em; } @@ -78,7 +78,8 @@ let description = 'Snowpack is a lightning-fast frontend build tool, designed fo </a> <div class="content markdown-body feature-list"> - <div class="feature-list-top"> + <div class="top"> + <h2 id="what-is-snowpack%3F">What is Snowpack?</h2> <p> <strong>Snowpack is a lightning-fast frontend build tool, designed for the modern web.</strong> @@ -95,38 +96,38 @@ let description = 'Snowpack is a lightning-fast frontend build tool, designed fo </p> </div> - <ul class="feature-list-bullets"> - <li class="feature-list-bullet"> - <h3>Instant startup</h3> + <ul class="bullets"> + <li class="bullet"> + <h3 class="bullet-heading">Instant startup</h3> Snowpack's unbundled web development server <strong>starts up in 50ms or less</strong> and stays fast in large projects. </li> - <li class="feature-list-bullet"> - <h3>Build once, cache forever</h3> + <li class="bullet"> + <h3 class="bullet-heading">Build once, cache forever</h3> Snowpack never builds the same file twice. Powered by JavaScript’s native module system (ESM) in the browser. </li> - <li class="feature-list-bullet"> - <h3>HMR feat. Fast Refresh</h3> + <li class="bullet"> + <h3 class="bullet-heading">HMR feat. Fast Refresh</h3> No refresh required. See changes reflected instantly in the browser with <a href="/concepts/hot-module-replacement">HMR + Fast Refresh</a> for React, Preact & Svelte. </li> - <li class="feature-list-bullet"> - <h3>Out-of-the-box support</h3> + <li class="bullet"> + <h3 class="bullet-heading">Out-of-the-box support</h3> Enjoy Snowpack's built-in support for JSX, TypeScript, React, Preact, CSS Modules <a href="/reference/supported-files">and more.</a> </li> - <li class="feature-list-bullet"> - <h3>Optimize for production</h3> + <li class="bullet"> + <h3 class="bullet-heading">Optimize for production</h3> Build for production with built-in optimizations and plugin support for your favorite bundlers. </li> - <li class="feature-list-bullet"> - <h3>Plugins? Plugins!</h3> + <li class="bullet"> + <h3 class="bullet-heading">Plugins? Plugins!</h3> Babel? Sass? MDX? Browse the entire <a href="/plugins">Snowpack Plugin Catalog</a> to connect your favorite build tool (or @@ -134,9 +135,9 @@ let description = 'Snowpack is a lightning-fast frontend build tool, designed fo </li> </ul> - <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 class="buttons"> + <a href="/tutorials/quick-start" class="button button-primary feature-button">Get started</a> + <a href="/concepts/how-snowpack-works" class="button feature-button">Learn more</a> </div> </div> </article> @@ -149,4 +150,4 @@ let description = 'Snowpack is a lightning-fast frontend build tool, designed fo <script async="async" defer="defer" src="https://buttons.github.io/buttons.js"></script> </body> -</html> \ No newline at end of file +</html> diff --git a/examples/snowpack/public/css/_globals.scss b/examples/snowpack/public/css/_globals.scss index 960ff591cc..2843a427ad 100644 --- a/examples/snowpack/public/css/_globals.scss +++ b/examples/snowpack/public/css/_globals.scss @@ -19,9 +19,6 @@ p { line-height: 1.25; } -.header-logo, -.header-snowpack, -.header-snowpack-subtitle, .pretty-font, .version-number { font-weight: 600; diff --git a/examples/snowpack/public/css/app.scss b/examples/snowpack/public/css/app.scss index 55baa62b50..c8aec88373 100644 --- a/examples/snowpack/public/css/app.scss +++ b/examples/snowpack/public/css/app.scss @@ -15,7 +15,6 @@ @use './components/card-grid'; @use './components/container'; @use './components/icon'; -@use './components/logo'; @use './components/old'; @use './components/view'; diff --git a/examples/snowpack/public/css/components/_logo.scss b/examples/snowpack/public/css/components/_logo.scss deleted file mode 100644 index 92e139fd44..0000000000 --- a/examples/snowpack/public/css/components/_logo.scss +++ /dev/null @@ -1,29 +0,0 @@ -@use '../var' as *; - -/** - * Snowpack Logo - * That iconic mountain you know and love - */ - -.snow-logo { - display: inline-flex; - align-items: center; - - // ----------- - // Components - // ----------- - - &-icon { - display: block; - width: 1em; - height: 1em; - margin-right: 0.25em; - fill: currentColor; - } - - &-type { - font-weight: 700; - font-family: $heading; - letter-spacing: -0.03em; - } -} diff --git a/src/compiler/optimize/styles.ts b/src/compiler/optimize/styles.ts index 691300067c..824f530962 100644 --- a/src/compiler/optimize/styles.ts +++ b/src/compiler/optimize/styles.ts @@ -126,6 +126,22 @@ export default function ({ filename, fileID }: { filename: string; fileID: strin html: { Element: { enter(node) { + if (node.name === 'style') { + // Same as ast.css (below) + const code = Array.isArray(node.children) ? node.children.map(({ data }: any) => data).join('\n') : ''; + if (!code) return; + const langAttr = (node.attributes || []).find(({ name }: any) => name === 'lang'); + styleNodes.push(node); + styleTransformPromises.push( + transformStyle(code, { + type: (langAttr && langAttr.value[0] && langAttr.value[0].data) || undefined, + filename, + fileID, + }) + ); + return; + } + // Find the root node to inject the <style> tag in later if (node.name === 'head') { rootNode = node; // If this is <head>, this is what we want. Always take this if found. However, this may not always exist (it won’t for Component subtrees). @@ -144,10 +160,19 @@ export default function ({ filename, fileID }: { filename: string; fileID: strin css: { Style: { enter(node) { + // Same as ast.html (above) + // Note: this is duplicated from html because of the compiler we‘re using; in a future version we should combine these + if (!node.content || !node.content.styles) return; const code = node.content.styles; - const typeAttr = (node.attributes || []).find(({ name }: { name: string }) => name === 'lang'); + const langAttr = (node.attributes || []).find(({ name }: any) => name === 'lang'); styleNodes.push(node); - styleTransformPromises.push(transformStyle(code, { type: (typeAttr && typeAttr.value[0] && typeAttr.value[0].raw) || undefined, filename, fileID })); + styleTransformPromises.push( + transformStyle(code, { + type: (langAttr && langAttr.value[0] && langAttr.value[0].data) || undefined, + filename, + fileID, + }) + ); // TODO: we should delete the old untransformed <style> node after we’re 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. @@ -167,21 +192,32 @@ export default function ({ filename, fileID }: { filename: string; fileID: strin // 1. transform <style> tags styleTransforms.forEach((result, n) => { if (styleNodes[n].attributes) { - // Add to global CSS Module class list for step 2 + // 1a. Add to global CSS Module class list for step 2 for (const [k, v] of result.cssModules) { allCssModules.set(k, v); } - // Update original <style> node with finished results - styleNodes[n].attributes = styleNodes[n].attributes.map((attr: any) => { - if (attr.name === 'type') { - attr.value[0].raw = 'text/css'; - attr.value[0].data = 'text/css'; - } - return attr; - }); + // 1b. Inject final CSS + const isHeadStyle = !styleNodes[n].content; + if (isHeadStyle) { + // Note: <style> tags in <head> have different attributes/rules, because of the parser. Unknown why + (styleNodes[n].children as any) = [{ ...(styleNodes[n].children as any)[0], data: result.css }]; + } else { + styleNodes[n].content.styles = result.css; + } + + // 3b. Update <style> attributes + const styleTypeIndex = styleNodes[n].attributes.findIndex(({ name }: any) => name === 'type'); + if (styleTypeIndex !== -1) { + console.log(styleNodes[n].attributes[styleTypeIndex]); + styleNodes[n].attributes[styleTypeIndex].value[0].raw = 'text/css'; + styleNodes[n].attributes[styleTypeIndex].value[0].data = 'text/css'; + } else { + styleNodes[n].attributes.push({ name: 'type', type: 'Attribute', value: [{ type: 'Text', raw: 'text/css', data: 'text/css' }] }); + } + const styleLangIndex = styleNodes[n].attributes.findIndex(({ name }: any) => name === 'lang'); + if (styleLangIndex !== -1) styleNodes[n].attributes.splice(styleLangIndex, 1); } - styleNodes[n].content.styles = result.css; }); // 2. inject finished <style> tags into root node