mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-12 04:09:12 +00:00
Viewport demo fixes (#996)
* fix viewports in code demo * sync color schemes in viewport demos * add terms * fix viewport styles in dark mode
This commit is contained in:
@@ -58,6 +58,8 @@
|
||||
"exportmaps",
|
||||
"exportparts",
|
||||
"fieldsets",
|
||||
"focusin",
|
||||
"focusout",
|
||||
"fontawesome",
|
||||
"formaction",
|
||||
"formdata",
|
||||
|
||||
@@ -35,8 +35,8 @@ const globalData = {
|
||||
|
||||
export default function (eleventyConfig) {
|
||||
/**
|
||||
* If you plan to add or remove any of these extensions, make sure to let either Konnor or Cory know as these passthrough extensions
|
||||
* will also need to be updated in the Web Awesome App.
|
||||
* If you plan to add or remove any of these extensions, make sure to let either Konnor or Cory know as these
|
||||
* passthrough extensions will also need to be updated in the Web Awesome App.
|
||||
*/
|
||||
const passThroughExtensions = ['js', 'css', 'png', 'svg', 'jpg', 'mp4'];
|
||||
|
||||
@@ -44,11 +44,11 @@ export default function (eleventyConfig) {
|
||||
const passThrough = [...passThroughExtensions.map(ext => path.join(baseDir, '**/*.' + ext))];
|
||||
|
||||
/**
|
||||
* This is the guard we use for now to make sure our final built files dont need a 2nd pass by the server. This keeps us able to still deploy the bare HTML files on Vercel until the app is ready.
|
||||
* This is the guard we use for now to make sure our final built files don't need a 2nd pass by the server. This keeps
|
||||
* us able to still deploy the bare HTML files on Vercel until the app is ready.
|
||||
*/
|
||||
const serverBuild = process.env.WEBAWESOME_SERVER === 'true';
|
||||
|
||||
// Add template data
|
||||
for (let name in globalData) {
|
||||
eleventyConfig.addGlobalData(name, globalData[name]);
|
||||
}
|
||||
@@ -135,6 +135,10 @@ export default function (eleventyConfig) {
|
||||
// Various text replacements
|
||||
eleventyConfig.addPlugin(
|
||||
replaceTextPlugin([
|
||||
{
|
||||
replace: /\[version\]/gs,
|
||||
replaceWith: packageData.version,
|
||||
},
|
||||
// Replace [issue:1234] with a link to the issue on GitHub
|
||||
{
|
||||
replace: /\[pr:([0-9]+)\]/gs,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { parse } from 'node-html-parser';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { markdown } from '../_utils/markdown.js';
|
||||
|
||||
/**
|
||||
* Eleventy plugin to turn `<code class="example">` blocks into live examples.
|
||||
@@ -24,6 +25,7 @@ export function codeExamplesPlugin(options = {}) {
|
||||
const pre = code.closest('pre');
|
||||
const hasButtons = !code.classList.contains('no-buttons');
|
||||
const isOpen = code.classList.contains('open') || !hasButtons;
|
||||
const isViewportDemo = code.classList.contains('viewport');
|
||||
const noEdit = code.classList.contains('no-edit');
|
||||
const id = `code-example-${uuid().slice(-12)}`;
|
||||
let preview = pre.textContent;
|
||||
@@ -33,10 +35,29 @@ export function codeExamplesPlugin(options = {}) {
|
||||
root.querySelectorAll('script').forEach(script => script.setAttribute('type', 'module'));
|
||||
preview = root.toString();
|
||||
|
||||
const escapedHtml = markdown.utils.escapeHtml(`
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Web Awesome Demo</title>
|
||||
<link rel="stylesheet" href="https://early.webawesome.com/webawesome@[version]/dist/styles/themes/default.css" />
|
||||
<link rel="stylesheet" href="https://early.webawesome.com/webawesome@[version]/dist/styles/webawesome.css" />
|
||||
<script type="module" src="https://early.webawesome.com/webawesome@[version]/dist/webawesome.loader.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
${preview}
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
|
||||
const codeExample = parse(`
|
||||
<div class="code-example ${isOpen ? 'open' : ''}">
|
||||
<div class="code-example ${isOpen ? 'open' : ''} ${isViewportDemo ? 'is-viewport-demo' : ''}">
|
||||
<div class="code-example-preview">
|
||||
${preview}
|
||||
|
||||
${isViewportDemo ? ` <wa-viewport-demo><iframe srcdoc="${escapedHtml}"></iframe></wa-viewport-demo>` : preview}
|
||||
|
||||
<div class="code-example-resizer" aria-hidden="true">
|
||||
<wa-icon name="grip-lines-vertical"></wa-icon>
|
||||
</div>
|
||||
|
||||
@@ -92,10 +92,22 @@ const colorScheme = new ThemeAspect({
|
||||
let dark = this.computedValue === 'dark';
|
||||
document.documentElement.classList.toggle(`wa-dark`, dark);
|
||||
document.documentElement.dispatchEvent(new CustomEvent('wa-color-scheme-change', { detail: { dark } }));
|
||||
syncViewportDemoColorSchemes();
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
function syncViewportDemoColorSchemes() {
|
||||
const isDark = document.documentElement.classList.contains('wa-dark');
|
||||
|
||||
// Update viewport demo color schemes in code examples
|
||||
document.querySelectorAll('.code-example.is-viewport-demo wa-viewport-demo').forEach(demo => {
|
||||
demo.querySelectorAll('iframe').forEach(iframe => {
|
||||
iframe.contentWindow.document.documentElement?.classList?.toggle('wa-dark', isDark);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Update the color scheme when the preference changes
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => colorScheme.set());
|
||||
|
||||
@@ -109,3 +121,12 @@ document.addEventListener('keydown', event => {
|
||||
colorScheme.set(colorScheme.get() === 'dark' ? 'light' : 'dark');
|
||||
}
|
||||
});
|
||||
|
||||
// When rendering a code example with a viewport demo, set the theme to match initially
|
||||
document.querySelectorAll('.code-example.is-viewport-demo wa-viewport-demo iframe').forEach(iframe => {
|
||||
const isDark = document.documentElement.classList.contains('wa-dark');
|
||||
|
||||
iframe.addEventListener('load', () => {
|
||||
iframe.contentWindow.document.documentElement?.classList?.toggle('wa-dark', isDark);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -31,7 +31,7 @@ tags: blog-news
|
||||
|
||||
## Modal
|
||||
|
||||
```html {.example viewport}
|
||||
```html {.example .viewport}
|
||||
<wa-dialog without-header label="Subscribe or continue with ads" class="dialog-deny-close" style="--width: 90ch;" open>
|
||||
<div class="wa-stack wa-gap-xl">
|
||||
<h2 class="wa-heading-m">Want to subscribe or continue using our Products for free with ads?</h2>
|
||||
@@ -74,7 +74,7 @@ tags: blog-news
|
||||
|
||||
## Footer
|
||||
|
||||
```html {.example viewport}
|
||||
```html {.example .viewport}
|
||||
<wa-drawer
|
||||
without-header
|
||||
label="Free article limit reached"
|
||||
|
||||
@@ -201,7 +201,7 @@ isPro: true
|
||||
|
||||
## Drawer
|
||||
|
||||
```html {.example viewport}
|
||||
```html {.example .viewport}
|
||||
<wa-drawer label="Shopping Cart" open>
|
||||
<div class="wa-stack">
|
||||
<article class="wa-flank" style="--flank-size: 6rem">
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
/* Style frame like a window */
|
||||
border: var(--viewport-bezel-width) solid transparent;
|
||||
border-radius: calc(var(--wa-border-radius-m));
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
|
||||
/* Window-like frame styling */
|
||||
--button-params: 0.4em / 0.5em 0.5em border-box;
|
||||
@@ -49,14 +49,13 @@
|
||||
var(--button-params),
|
||||
var(--wa-color-gray-95);
|
||||
background-repeat: no-repeat;
|
||||
box-shadow:
|
||||
0 0 0 1px var(--wa-color-gray-90),
|
||||
var(--wa-shadow-m);
|
||||
|
||||
&.resized {
|
||||
aspect-ratio: var(--iframe-manual-aspect-ratio);
|
||||
}
|
||||
|
||||
background-color: var(--wa-color-neutral-fill-normal);
|
||||
|
||||
/* User has not yet resized the viewport */
|
||||
&:not(.resized) ::slotted(iframe),
|
||||
&:not(.resized) slot {
|
||||
@@ -79,6 +78,7 @@ slot {
|
||||
scale: var(--zoom);
|
||||
transform-origin: top left;
|
||||
resize: var(--viewport-resize);
|
||||
border-radius: var(--wa-border-radius-m);
|
||||
overflow: auto;
|
||||
|
||||
/* The width and height specified here are only applied if the iframe is not manually resized */
|
||||
@@ -91,7 +91,6 @@ slot {
|
||||
|
||||
/* Divide with var(--zoom) to get lengths that stay constant regardless of zoom level */
|
||||
border: calc(1px / var(--zoom)) solid var(--wa-color-gray-90);
|
||||
background: var(--viewport-background-color);
|
||||
}
|
||||
|
||||
[part~='controls'] {
|
||||
@@ -120,14 +119,9 @@ slot {
|
||||
display: none;
|
||||
vertical-align: -0.1em;
|
||||
font-size: 85%;
|
||||
color: var(--wa-color-gray-70);
|
||||
}
|
||||
|
||||
wa-icon-button {
|
||||
&:not(:hover, :focus) {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&::part(base) {
|
||||
padding: 0;
|
||||
}
|
||||
@@ -137,9 +131,6 @@ slot {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.3em;
|
||||
font-weight: 600;
|
||||
color: var(--wa-color-text-quiet);
|
||||
opacity: 80%;
|
||||
}
|
||||
|
||||
[part~='zoom-in'],
|
||||
|
||||
Reference in New Issue
Block a user