From 99704faeb478a96b162753062f5b9fd024ae8a8d Mon Sep 17 00:00:00 2001 From: Lea Verou Date: Tue, 10 Dec 2024 11:53:39 -0500 Subject: [PATCH] Page demo draft --- docs/_includes/page-demo.njk | 22 +++++++++ docs/assets/examples/page-demo/demo.css | 23 +++++++++ docs/assets/examples/page-demo/demo.js | 42 +++++++++++++++++ docs/assets/examples/page-demo/page.css | 62 +++++++++++++++++++++++++ docs/docs/components/page.md | 8 ++-- 5 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 docs/_includes/page-demo.njk create mode 100644 docs/assets/examples/page-demo/demo.css create mode 100644 docs/assets/examples/page-demo/demo.js create mode 100644 docs/assets/examples/page-demo/page.css diff --git a/docs/_includes/page-demo.njk b/docs/_includes/page-demo.njk new file mode 100644 index 000000000..ccbd1fda9 --- /dev/null +++ b/docs/_includes/page-demo.njk @@ -0,0 +1,22 @@ +
+ +{% set slots = components.page.slots %} + +
+ Slots +
+ {% for slot in slots %} + {% if slot.name != "skip-to-content" %} + + {{ slot.name or "(default)" }} + + {% endif %} + {% endfor %} +
+
+ + + +
+ diff --git a/docs/assets/examples/page-demo/demo.css b/docs/assets/examples/page-demo/demo.css new file mode 100644 index 000000000..d1ae167ba --- /dev/null +++ b/docs/assets/examples/page-demo/demo.css @@ -0,0 +1,23 @@ +#page_slots_demo { + display: flex; + flex-flow: column; + gap: 1em; + margin-bottom: var(--wa-space-xl); + + fieldset .options { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(9em, 1fr)); + gap: 0.2em 1em; + + wa-checkbox { + white-space: nowrap; + } + + p { + display: contents; + } + } + + wa-viewport-demo { + } +} diff --git a/docs/assets/examples/page-demo/demo.js b/docs/assets/examples/page-demo/demo.js new file mode 100644 index 000000000..368ef481a --- /dev/null +++ b/docs/assets/examples/page-demo/demo.js @@ -0,0 +1,42 @@ +await customElements.whenDefined('wa-checkbox'); +let container = document.getElementById('page_slots_demo'); +let fieldset = container.querySelector('fieldset'); +let iframe = container.querySelector('iframe'); +let stylesheets = Array.from(document.querySelectorAll("link[rel=stylesheet][href^='/dist/']")) + .map(i => i.outerHTML) + .join('\n'); +let includes = `${stylesheets} + + `; + +function render() { + let slots = Array.from(fieldset.querySelectorAll('wa-checkbox[name=slot]:is([data-wa-checked])')); + let slotsHTML = slots + .map(slot => { + let name = slot.getAttribute('value'); + let description = slot.getAttribute('data-description'); + + let tag = 'div'; + if (name.endsWith('header')) { + tag = 'header'; + } + if (name.endsWith('footer')) { + tag = 'footer'; + } + + return `<${tag} class="slot-content" slot="${name}"> + ${name || 'main (default)'} +

${description}

+ `; + }) + .join('\n'); + let page = iframe.contentDocument?.querySelector('wa-page'); + + if (page) { + page.innerHTML = slotsHTML; + } else { + iframe.srcdoc = `${includes}${slotsHTML}`; + } +} +fieldset?.addEventListener('input', render); +render(); diff --git a/docs/assets/examples/page-demo/page.css b/docs/assets/examples/page-demo/page.css new file mode 100644 index 000000000..cc0c24e6d --- /dev/null +++ b/docs/assets/examples/page-demo/page.css @@ -0,0 +1,62 @@ +body { + padding: 0; + margin: 0; +} + +wa-page { + margin: var(--wa-space-xs); + &::part(base), + &::part(main), + &::part(navigation), + &::part(body) { + gap: var(--wa-space-xs); + } +} + +.slot-content[slot='banner'], +.slot-content[slot='header'], +.slot-content[slot='subheader'], +.slot-content[slot='footer'] { + xmargin-inline: var(--wa-space-m); +} + +.slot-content { + padding: var(--wa-space-m); + border-radius: var(--wa-border-radius-m); + align-content: center; + justify-content: center; + text-align: center; + height: 100%; + box-sizing: border-box; + background: var(--wa-color-blue-80); + color: var(--wa-color-blue-20); + + &[slot='banner'] { + background: var(--wa-color-blue-50); + color: white; + } + + &[slot='header'] { + background: var(--wa-color-blue-60); + color: var(--wa-color-blue-10); + } + + &[slot^='main'], + &[slot=''] { + background: var(--wa-color-gray-80); + color: var(--wa-color-gray-20); + } + + &[slot^='navigation'] { + background: var(--wa-color-violet-80); + color: var(--wa-color-violet-20); + } + + strong { + display: block; + } + + &:not([slot='']) p { + display: none; + } +} diff --git a/docs/docs/components/page.md b/docs/docs/components/page.md index b047cb3b9..928e29633 100644 --- a/docs/docs/components/page.md +++ b/docs/docs/components/page.md @@ -31,7 +31,9 @@ This image depicts a page's anatomy, including the default positions of each sec Most slots are optional. Slots that have no content will not be shown, allowing you to opt-in to just the sections you actually need. -![Screenshot of Layout Anatomy showing various slots](/assets/images/layout-anatomy.svg) +{% include "page-demo.njk" %} + + :::info If you're not familiar with how slots work in HTML, you might want to [learn more about slots](/docs/usage/#slots) before using this component. @@ -125,7 +127,7 @@ wa-page[view='desktop'] [data-toggle-nav] { ### Widths and Heights -There are a number of [CSS custom properties](#css-custom-properties) you can use to set specific widths and heights for many slots on your page. +There are a number of [CSS custom properties](#css-custom-properties) you can use to set specific widths and heights for many slots on your page. If you specify `--menu-width` to apply a specific width to your `navigation` slot, space will still be reserved on the page even below the `mobile-breakpoint`. To collapse this space on smaller screens, add the following code to your styles: ```css @@ -793,4 +795,4 @@ A sample media app page using `header`, `navigation-header`, `main-header`, and padding: 1.5rem; } -``` \ No newline at end of file +```