diff --git a/docs/_includes/import-stylesheet-code.md.njk b/docs/_includes/import-stylesheet-code.md.njk
index c70314b46..69adea334 100644
--- a/docs/_includes/import-stylesheet-code.md.njk
+++ b/docs/_includes/import-stylesheet-code.md.njk
@@ -1,3 +1,5 @@
+{%- if not stylesheets %}{% set stylesheets = [stylesheet] %}{% endif -%}
+
In HTML
In CSS
@@ -5,14 +7,18 @@
Simply add the following code to the `` of your page:
```html
-
+{% for stylesheet in stylesheets -%}
+{% if not loop.last %}
+{% endif %}{% endfor %}
```
Simply add the following code at the top of your CSS file:
```css
-@import url('{% cdnUrl stylesheet %}');
+{% for stylesheet in stylesheets -%}
+@import url('{% cdnUrl stylesheet %}');{% if not loop.last %}
+{% endif %}{% endfor %}
```
diff --git a/docs/_layouts/theme.njk b/docs/_layouts/theme.njk
index dfa90a01c..8858dd0a3 100644
--- a/docs/_layouts/theme.njk
+++ b/docs/_layouts/theme.njk
@@ -3,64 +3,15 @@
{# {% set forceTheme = page.fileSlug %} #}
{% extends '../_includes/base.njk' %}
+{% set themeId = page.fileSlug %}
+{% if themeId == 'remixed' -%}
+ {% set themeId = 'default' %}
+{% endif -%}
{% block header %}
-
-
-
-
-
- Remix
-
-
-
-
- (Theme default)
-
- {% for theme in collections.theme | sort %}
- {% if theme.fileSlug !== page.fileSlug %}
- {{ theme.data.title }}
- {% endif %}
- {% endfor %}
-
-
-
-
- (Theme default)
-
- {% for p in collections.palette | sort %}
- {% if p.fileSlug !== palette %}
- {{ p.data.title }}
- {% endif %}
- {% endfor %}
-
-
-
-
- (Theme default)
-
- {% for theme in collections.theme | sort %}
- {% if theme.fileSlug !== page.fileSlug %}
- {{ theme.data.title }}
- {% endif %}
- {% endfor %}
-
-
-
-
-
+
+{% if palette -%}
Default Color Palette
{% set paletteURL = '/docs/palettes/' + palette + '/' %}
{% set themePage = page %}
@@ -69,34 +20,20 @@
{% include 'page-card.njk' %}
{% set page = themePage %}
+{% endif %}
{% endblock %}
{% block afterContent %}
{% markdown %}
+{%- if page.fileSlug != 'remixed' %}
## How to use this theme
You can import this theme from the Web Awesome CDN.
-{% set stylesheet = 'styles/themes/' + page.fileSlug + '.css' %}
+{% set stylesheet = 'styles/themes/' + themeId + '.css' %}
{% include 'import-stylesheet-code.md.njk' %}
-
-### Remixing { #remixing }
-
-If you want to combine the **colors** from this theme with another theme, you can import this CSS file *after* the other theme’s CSS file:
-
-{% set stylesheet = 'styles/themes/' + page.fileSlug + '/color.css' %}
-{% include 'import-stylesheet-code.md.njk' %}
-
-To use the **typography** from this theme with another theme, you can import this CSS file *after* the other theme’s CSS file:
-
-{% set stylesheet = 'styles/themes/' + page.fileSlug + '/typography.css' %}
-{% include 'import-stylesheet-code.md.njk' %}
-
-
-
- Please note that not all combinations will look good — once you’re mixing and matching, you’re on your own!
-
+{% endif %}
## Dark mode
diff --git a/docs/assets/styles/docs.css b/docs/assets/styles/docs.css
index b98b5bc8f..56a0e72a5 100644
--- a/docs/assets/styles/docs.css
+++ b/docs/assets/styles/docs.css
@@ -538,23 +538,4 @@ table.colors {
height: 65vh;
max-height: 21lh;
}
-
- #mix_and_match {
- strong {
- display: flex;
- align-items: center;
- gap: var(--wa-space-2xs);
- margin-top: 1.2em;
- }
-
- wa-select::part(label) {
- margin-block-end: 0;
- }
-
- wa-select[value='']::part(display-input),
- wa-option[value=''] {
- font-style: italic;
- color: var(--wa-color-text-quiet);
- }
- }
}
diff --git a/docs/docs/themes/demo.njk b/docs/docs/themes/demo.njk
index c511f639b..ec7885ed0 100644
--- a/docs/docs/themes/demo.njk
+++ b/docs/docs/themes/demo.njk
@@ -19,6 +19,10 @@ eleventyComputed:
{% include 'breadcrumbs.njk' %}
{{ theme.data.title }}
+
+
+ Remix
+
{% include 'status.njk' %}
{{ theme.data.description | inlineMarkdown | safe }}
@@ -39,12 +43,12 @@ function updateTheme() {
let params = new URLSearchParams(window.location.search);
let script = document.currentScript;
const stylesheetURLs = {
- colors: id => `/dist/styles/themes/${ id }/color.css`,
+ color: id => `/dist/styles/themes/${ id }/color.css`,
palette: id => `/dist/styles/color/${ id }.css`,
typography: id => `/dist/styles/themes/${ id }/typography.css`
};
const icons = {
- colors: 'palette',
+ color: 'palette',
palette: 'swatchbook',
typography: 'font-case'
}
@@ -66,11 +70,14 @@ function updateTheme() {
}
}
+ let isRemixed = msgs.length > 0;
+ document.documentElement.classList.toggle("remixed", isRemixed);
+
for (let p of mix_and_match) {
- p.hidden = msgs.length === 0;
- if (msgs.length) {
+ p.hidden = !isRemixed;
+ if (isRemixed) {
let icon =
- p.innerHTML = ` Remixed ` + msgs.map(msg => `
+ p.innerHTML = ` Remixed
` + msgs.map(msg => `
${ msg }`).join(' ');
}
}
diff --git a/docs/docs/themes/remixed/index.js b/docs/docs/themes/remixed/index.js
new file mode 100644
index 000000000..23fb84e78
--- /dev/null
+++ b/docs/docs/themes/remixed/index.js
@@ -0,0 +1,138 @@
+let params = { base: 'default', palette: '', color: '', typography: '' };
+
+// Find usage code snippet and prepare it
+let snippets = document.querySelectorAll('#remixed-usage ~ wa-tab-group pre > code');
+let copyButtons = document.querySelectorAll('#remixed-usage ~ wa-tab-group pre > wa-copy-button');
+let codeExamples = [];
+
+for (let snippet of snippets) {
+ let tokens = [...snippet.children];
+ let base = tokens.shift();
+ let [palette, color, typography] = tokens;
+
+ codeExamples.push({ snippet, base, palette, color, typography });
+
+ // Remove non-base tokens
+ for (let token of tokens) {
+ let whitespace = token.previousSibling;
+
+ if (whitespace.nodeType === Node.TEXT_NODE) {
+ // Move whitespace to beginning of node
+ token.prepend(token.previousSibling);
+ }
+ }
+}
+
+// Read URL params and apply them. This facilitates permalinks.
+if (location.search) {
+ let urlParams = new URLSearchParams(location.search);
+
+ for (let aspect in params) {
+ if (urlParams.has(aspect)) {
+ params[aspect] = urlParams.get(aspect);
+ }
+ }
+}
+
+const selects = Object.fromEntries(
+ [...document.querySelectorAll('#mix_and_match wa-select')].map(select => [select.getAttribute('name'), select]),
+);
+
+document.querySelector('#mix_and_match').addEventListener(
+ 'change',
+ function (event) {
+ for (let name in selects) {
+ params[name] = selects[name].value;
+ }
+
+ render();
+ },
+ { capture: true },
+);
+
+function hasOverride(name) {
+ if (!params[name]) {
+ return false;
+ }
+
+ if (name === 'palette') {
+ return params[name] !== defaultPalettes[params.base];
+ }
+
+ if (name !== 'base') {
+ return params[name] !== params.base;
+ }
+
+ return true;
+}
+
+function render() {
+ let demoUrl = new URL(`/docs/themes/${params.base}/demo.html`, location);
+ let pageParams = new URLSearchParams(params);
+
+ for (let aspect in params) {
+ if (aspect !== 'base' && params[aspect]) {
+ demoUrl.searchParams.set(aspect, params[aspect]);
+ }
+
+ if (!params[aspect] || (aspect === 'base' && params[aspect] === 'default') || !hasOverride(aspect)) {
+ pageParams.delete(aspect);
+ }
+
+ // Output code snippet
+ if (aspect !== 'base') {
+ for (let codeExample of codeExamples) {
+ let token = codeExample[aspect];
+ let value = params[aspect];
+
+ if (hasOverride(aspect)) {
+ // Update code example
+ let valueToken = [...token.querySelectorAll('.code-attr-value, .code-url')].pop();
+ valueToken.textContent = replaceStyleSheetURL(valueToken.textContent, aspect, value);
+
+ // Add code example to
+ codeExample.snippet.append(token);
+ } else {
+ token.remove();
+ }
+ }
+ }
+
+ // Update selects
+ if (selects[aspect].value === undefined) {
+ selects[aspect].setAttribute('value', params[aspect]);
+ } else {
+ selects[aspect].value = params[aspect];
+ }
+ }
+
+ // Update code snippet copy buttons
+ for (let copyButton of copyButtons) {
+ copyButton.value = copyButton.nextElementSibling.textContent;
+ }
+
+ // Update demo URL
+ demo.src = demoUrl;
+
+ // Update page URL. If there’s already a search, replace it.
+ // We don’t want to clog the user’s history while they iterate
+ let historyAction = location.search ? 'replaceState' : 'pushState';
+ history[historyAction](null, '', `?${pageParams}`);
+}
+
+const regexes = {
+ base: /\/themes\/([a-z-]+)\.css/,
+ palette: /\/color\/([a-z-]+)\.css/,
+ color: /\/themes\/([a-z-]+)\/color\.css/,
+ typography: /\/themes\/([a-z-]+)\/typography\.css/,
+};
+
+function replaceStyleSheetURL(url, name, value) {
+ let regex = regexes[name];
+ return url.replace(regex, (match, oldValue) => {
+ return match.replace(oldValue, value);
+ });
+}
+
+globalThis.params = params;
+render();
diff --git a/docs/docs/themes/remixed/index.njk b/docs/docs/themes/remixed/index.njk
new file mode 100644
index 000000000..ac790c6f3
--- /dev/null
+++ b/docs/docs/themes/remixed/index.njk
@@ -0,0 +1,84 @@
+---
+title: Remixed
+description: TODO
+isPro: true
+tags: pro
+---
+
+{% block header %}
+
+
+ {#
+
+ Remix
+
+ #}
+
+
+ {% for theme in collections.theme | sort %}
+ {% if theme.fileSlug !== page.fileSlug %}
+ {{ theme.data.title }}
+ {% endif %}
+ {% endfor %}
+
+
+
+
+ (Theme default)
+
+ {% for p in collections.palette | sort %}
+ {{ p.data.title }}
+ {% endfor %}
+
+
+
+
+ (Theme default)
+
+ {% for theme in collections.theme | sort %}
+ {{ theme.data.title }}
+ {% endfor %}
+
+
+
+
+ (Theme default)
+
+ {% for theme in collections.theme | sort %}
+ {{ theme.data.title }}
+ {% endfor %}
+
+
+
+
+
+
+ Please note that not all combinations will look good — once you’re mixing and matching, you’re on your own!
+
+{% endblock %}
+
+{% block afterContent %}
+{% markdown %}
+
+## How to use your remixed theme { #remixed-usage }
+
+You can import your remixed theme by importing the individual theme files from the Web Awesome CDN.
+{# Note: If you change the order here, you need to update index.js too #}
+{% set stylesheets = [
+ 'styles/themes/default.css',
+ 'styles/color/default.css',
+ 'styles/themes/default/color.css',
+ 'styles/themes/default/typography.css'
+] %}
+{% set stylesheet = 'styles/themes/default/color.css' %}
+{% include 'import-stylesheet-code.md.njk' %}
+
+
+{% endmarkdown %}
+{% endblock %}
diff --git a/docs/docs/themes/remixed/style.css b/docs/docs/themes/remixed/style.css
new file mode 100644
index 000000000..1584aa9ce
--- /dev/null
+++ b/docs/docs/themes/remixed/style.css
@@ -0,0 +1,18 @@
+#mix_and_match {
+ strong {
+ display: flex;
+ align-items: center;
+ gap: var(--wa-space-2xs);
+ margin-top: 1.2em;
+ }
+
+ wa-select::part(label) {
+ margin-block-end: 0;
+ }
+
+ wa-select[value='']::part(display-input),
+ wa-option[value=''] {
+ font-style: italic;
+ color: var(--wa-color-text-quiet);
+ }
+}
diff --git a/docs/docs/themes/showcase.css b/docs/docs/themes/showcase.css
index d073cf0f8..437fdcabd 100644
--- a/docs/docs/themes/showcase.css
+++ b/docs/docs/themes/showcase.css
@@ -9,6 +9,18 @@ body,
overflow: hidden;
}
+html.remixed {
+ .remix-link {
+ display: none;
+ }
+}
+
+html:not(.remixed) {
+ #mix_and_match {
+ display: none;
+ }
+}
+
#mix_and_match {
font-weight: var(--wa-font-weight-semibold);
color: var(--wa-color-text-quiet);