Compare commits

..

23 Commits

Author SHA1 Message Date
Lea Verou
f753dc8e76 Merge branch 'icon-properties' of https://github.com/shoelace-style/webawesome into icon-properties 2025-01-07 17:55:42 -05:00
Lea Verou
4bee37f621 Remove docs from alpha 2025-01-07 17:55:32 -05:00
Lea Verou
4103cea723 Better docs 2025-01-07 17:55:32 -05:00
Lea Verou
f12de60739 Rename to cssAttributeProperties, follow property name if specified 2025-01-07 17:55:32 -05:00
Lea Verou
b32f4d2d13 Move css property reflection stuff to base class 2025-01-07 17:55:32 -05:00
Lea Verou
e94c8b34b8 CSS-set properties should not override JS-set properties 2025-01-07 17:55:32 -05:00
Lea Verou
5ca8517acf Update icon.md 2025-01-07 17:55:31 -05:00
Lea Verou
14ca7e2bd8 Update icon.md 2025-01-07 17:55:31 -05:00
Lea Verou
01834120c9 Fix deploy 2025-01-07 17:55:31 -05:00
Lea Verou
fe1cf2d72d Start work on --wa-icon-* properties 2025-01-07 17:55:31 -05:00
Lea Verou
a66a926ce4 Remove docs from alpha 2025-01-07 17:51:49 -05:00
Lea Verou
423067c7a7 Better docs 2025-01-07 17:44:22 -05:00
Lea Verou
f31d19c249 Rename to cssAttributeProperties, follow property name if specified 2025-01-07 17:41:22 -05:00
Lea Verou
711cf99cf8 Move css property reflection stuff to base class 2025-01-07 16:55:50 -05:00
Lea Verou
e4117512f8 Harmonize updated() definitions
- Use proper type
- Use same argument name
- Ensure `super.updated()` is called
2025-01-07 16:53:08 -05:00
Lea Verou
0784f39537 CSS-set properties should not override JS-set properties 2025-01-07 15:05:18 -05:00
Lea Verou
9d2bd6108d Update icon.md 2025-01-07 14:44:51 -05:00
Lea Verou
7b91d41768 Update icon.md 2025-01-07 14:37:15 -05:00
Lea Verou
a6847886e8 Merge branch 'next' into icon-properties 2025-01-07 14:23:56 -05:00
Lea Verou
5fdfc2f1fa Merge branch 'next' into icon-properties 2025-01-07 12:10:34 -05:00
Lea Verou
cd5c8046a0 Fix deploy 2025-01-07 10:23:53 -05:00
Lea Verou
2db378cfae Merge branch 'next' into icon-properties 2025-01-07 10:17:39 -05:00
Lea Verou
7c4dc7e051 Start work on --wa-icon-* properties 2025-01-06 22:02:48 -05:00
101 changed files with 1550 additions and 1902 deletions

View File

@@ -59,8 +59,6 @@ To generate a production build, run the following command.
npm run build
```
You can also run `npm run build:serve` to start an [`http-server`](https://www.npmjs.com/package/http-server) instance on `http://localhost:4000` after the build completes, so you can preview the production build.
### Creating New Components
To scaffold a new component, run the following command, replacing `wa-tag-name` with the desired tag name.

View File

@@ -20,15 +20,6 @@ const packageData = JSON.parse(await readFile('./package.json', 'utf-8'));
const isAlpha = process.argv.includes('--alpha');
const isDev = process.argv.includes('--develop');
const globalData = {
package: packageData,
isAlpha,
layout: 'page.njk',
};
const passThroughExtensions = ['js', 'css', 'png', 'svg', 'jpg', 'mp4'];
const passThrough = [...passThroughExtensions.map(ext => 'docs/**/*.' + ext)];
export default function (eleventyConfig) {
// NOTE - alpha setting removes certain pages
if (isAlpha) {
@@ -41,9 +32,8 @@ export default function (eleventyConfig) {
}
// Add template data
for (let name in globalData) {
eleventyConfig.addGlobalData(name, globalData[name]);
}
eleventyConfig.addGlobalData('package', packageData);
eleventyConfig.addGlobalData('isAlpha', isAlpha);
// Template filters - {{ content | filter }}
eleventyConfig.addFilter('inlineMarkdown', content => markdown.renderInline(content || ''));
@@ -158,18 +148,9 @@ export default function (eleventyConfig) {
// eleventyConfig.addPlugin(formatCodePlugin());
// }
eleventyConfig.addPassthroughCopy({
'docs/assets': 'assets',
});
for (let glob of passThrough) {
eleventyConfig.addPassthroughCopy(glob);
}
return {
markdownTemplateEngine: 'njk',
dir: {
input: 'docs',
includes: '_includes',
layouts: '_layouts',
},

File diff suppressed because one or more lines are too long

View File

@@ -1,25 +1,91 @@
<!DOCTYPE html>
<html lang="en" data-fa-kit-code="b10bfbde90" data-cdn-url="{% cdnUrl %}">
<head>
{% include 'head.njk' %}
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="{{ description }}">
<meta name="theme-color" content="#f36944">
{% if noindex %}<meta name="robots" content="noindex">{% endif %}
<title>{{ title }}</title>
<link rel="icon" href="/assets/images/webawesome-logo.svg" />
<link rel="apple-touch-icon" href="/assets/images/app-icon.png">
{# Scripts #}
{# Hydration stuff #}
<script src="/assets/scripts/hydration-errors.js"></script>
<link rel="stylesheet" href="/assets/styles/hydration-errors.css">
<link rel="preconnect" href="https://cdn.jsdelivr.net">
<script type="module" src="https://cdn.jsdelivr.net/npm/@hotwired/turbo@8.0.10/+esm"></script>
<script type="module" src="/assets/scripts/code-examples.js"></script>
<script type="module" src="/assets/scripts/color-scheme.js"></script>
<script type="module" src="/assets/scripts/copy-code.js"></script>
<script type="module" src="/assets/scripts/preset-theme.js"></script>
<script type="module" src="/assets/scripts/scroll.js"></script>
<script type="module" src="/assets/scripts/turbo.js"></script>
<script type="module" src="/assets/scripts/search.js"></script>
<script type="module" src="/assets/scripts/outline.js"></script>
<script defer data-domain="backers.webawesome.com" src="https://plausible.io/js/script.js"></script>
{# Web Awesome #}
<script type="module" src="/dist/webawesome.ssr-loader.js"></script>
<link rel="stylesheet" id="theme-stylesheet" href="/dist/styles/themes/default.css" />
<link rel="stylesheet" href="/dist/styles/webawesome.css" />
<link id="color-stylesheet" rel="stylesheet" href="/dist/styles/utilities.css" />
<link rel="stylesheet" href="/dist/styles/forms.css" />
{# Docs styles #}
<link rel="stylesheet" href="/assets/styles/docs.css" />
{# Set the theme to prevent flashing #}
<script>
function getColorScheme() {
return localStorage.getItem('colorScheme') || 'auto';
}
function getPresetTheme () {
return localStorage.getItem('presetTheme') || 'default';
}
function isDark() {
const colorScheme = getColorScheme()
if (colorScheme === 'auto') {
return window.matchMedia('(prefers-color-scheme: dark)').matches;
}
return colorScheme === 'dark';
}
const oldStylesheet = document.querySelector("#theme-stylesheet")
const newStylesheet = document.createElement("link")
let preset = getPresetTheme()
newStylesheet.href = `/dist/styles/themes/${preset}.css`
newStylesheet.rel = "preload"
newStylesheet.as = "style"
document.head.append(newStylesheet)
function updateStylesheet () {
newStylesheet.rel = "stylesheet"
newStylesheet.id = "theme-stylesheet"
requestAnimationFrame(() => oldStylesheet.remove())
}
newStylesheet.addEventListener("load", updateStylesheet)
document.documentElement.classList.toggle(
`wa-theme-${preset}-dark`,
isDark()
);
</script>
</head>
<body class="layout-{{ layout | stripExtension }}">
<!-- use view="desktop" as default to reduce layout jank on desktop site. -->
<wa-page view="desktop" disable-navigation-toggle="">
<header slot="header" class="wa-split">
<header slot="header">
{# Logo #}
<div id="docs-branding">
{# Nav toggle #}
@@ -35,9 +101,9 @@
<wa-badge variant="warning" appearance="filled" class="only-desktop">Alpha</wa-badge>
</div>
<div id="docs-toolbar" class="wa-cluster wa-gap-xs">
<div id="docs-toolbar">
{# Desktop selectors #}
<div class="only-desktop wa-cluster wa-gap-xs">
<div class="only-desktop">
{% include "preset-theme-selector.njk" %}
{% include "color-scheme-selector.njk" %}
</div>
@@ -55,7 +121,7 @@
{% if hasSidebar %}
{# Mobile selectors #}
<div class="wa-mobile-only" slot="navigation-header">
<div class="wa-cluster wa-gap-xs">
<div style="display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));">
{% include "preset-theme-selector.njk" %}
{% include "color-scheme-selector.njk" %}
</div>
@@ -83,14 +149,22 @@
</details>
</nav>
{% set breadcrumbs = page.url | breadcrumbs %}
{% if breadcrumbs.length > 0 %}
<wa-breadcrumb id="docs-breadcrumbs">
{% for crumb in breadcrumbs %}
<wa-breadcrumb-item href="{{ crumb.url }}">{{ crumb.title }}</wa-breadcrumb-item>
{% endfor %}
<wa-breadcrumb-item>{# Current page #}</wa-breadcrumb-item>
</wa-breadcrumb>
{% else %}
{% endif %}
{% block header %}
{% include 'breadcrumbs.njk' %}
<h1 class="title">{{ title }}</h1>
{% endblock %}
{% block beforeContent %}{% endblock %}
{% block content %}
<h1 class="title">{{ title }}</h1>
{{ content | safe }}
{% endblock %}

View File

@@ -1,10 +0,0 @@
{% set breadcrumbs = page.url | breadcrumbs %}
{% if breadcrumbs.length > 0 %}
<wa-breadcrumb id="docs-breadcrumbs">
{% for crumb in breadcrumbs %}
<wa-breadcrumb-item href="{{ crumb.url }}">{{ crumb.title }}</wa-breadcrumb-item>
{% endfor %}
<wa-breadcrumb-item>{# Current page #}</wa-breadcrumb-item>
</wa-breadcrumb>
{% else %}
{% endif %}

View File

@@ -1,19 +1,15 @@
{# Color scheme selector #}
<wa-select class="color-scheme-selector" appearance="filled" size="small" value="auto" pill title="Press \ to toggle">
<wa-icon class="only-light" slot="prefix" name="sun" variant="regular"></wa-icon>
<wa-icon class="only-dark" slot="prefix" name="moon" variant="regular"></wa-icon>
<wa-option value="light">
<wa-icon slot="prefix" name="sun" variant="regular"></wa-icon>
Light
</wa-option>
<wa-option value="dark">
<wa-icon slot="prefix" name="moon" variant="regular"></wa-icon>
Dark
</wa-option>
<wa-divider></wa-divider>
<wa-option value="auto">
<wa-dropdown id="color-scheme-selector">
<wa-button slot="trigger" appearance="filled" size="small" pill caret title="Press \ to toggle">
<wa-icon class="only-light" slot="prefix" name="sun" variant="regular"></wa-icon>
<wa-icon class="only-dark" slot="prefix" name="moon" variant="regular"></wa-icon>
System
</wa-option>
</wa-select>
<span class="only-light">Light</span>
<span class="only-dark">Dark</span>
</wa-button>
<wa-menu>
<wa-menu-item type="checkbox" value="light">Light</wa-menu-item>
<wa-menu-item type="checkbox" value="dark">Dark</wa-menu-item>
<wa-divider></wa-divider>
<wa-menu-item type="checkbox" value="auto">System</wa-menu-item>
</wa-menu>
</wa-dropdown>

View File

@@ -1,53 +0,0 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="{{ description }}">
{% if noindex %}<meta name="robots" content="noindex">{% endif %}
<title>{{ title }}</title>
{# Dark mode #}
<script>
let colorScheme = localStorage.colorScheme;
let isDark = localStorage.colorScheme === "dark";
if (!colorScheme || colorScheme === "auto") {
isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
}
document.documentElement.classList.toggle('wa-dark', isDark);
</script>
<link rel="icon" href="/assets/images/webawesome-logo.svg" />
<link rel="apple-touch-icon" href="/assets/images/app-icon.png">
{# Scripts #}
{# Hydration stuff #}
<script src="/assets/scripts/hydration-errors.js"></script>
<link rel="stylesheet" href="/assets/styles/hydration-errors.css">
<link rel="preconnect" href="https://cdn.jsdelivr.net">
<script type="module" src="https://cdn.jsdelivr.net/npm/@hotwired/turbo@8.0.10/+esm"></script>
{# Web Awesome #}
<script type="module" src="/dist/webawesome.ssr-loader.js"></script>
<script type="module" src="/assets/scripts/theme-picker.js"></script>
{# Preset Theme #}
<link id="theme-stylesheet" rel="stylesheet" id="theme-stylesheet" href="/dist/styles/themes/{{ forceTheme or 'default' }}.css" render="blocking" fetchpriority="high" />
{% if not forceTheme %}
<script>
if (localStorage.presetTheme) {
let preset = localStorage.presetTheme;
let script = document.currentScript;
let link = script.previousElementSibling;
let newLink = link.cloneNode();
newLink.href = link.href.replace("/default.css", `/${preset}.css`);
newLink.addEventListener('load', () => {
link.remove();
});
link.after(newLink);
}
</script>
<script type="module" src="/assets/scripts/preset-theme-picker.js"></script>
{% endif %}
<link rel="stylesheet" href="/dist/styles/webawesome.css" />
<link id="color-stylesheet" rel="stylesheet" href="/dist/styles/utilities.css" />
<link rel="stylesheet" href="/dist/styles/forms.css" />

View File

@@ -1,5 +1,5 @@
<div id="page_slots_demo">
<link rel="stylesheet" href="./demo.css">
<link rel="stylesheet" href="/assets/examples/page-demo/demo.css">
{% set slots = components.page.slots %}
<fieldset id="page_slots_fieldset">
@@ -22,5 +22,5 @@
<script type="module">
const cacheBust = new Date().toString()
import(`./demo.js?${cacheBust}`)
import(`/assets/examples/page-demo/demo.js?${cacheBust}`)
</script>

View File

@@ -1,9 +1,19 @@
{# Preset theme selector #}
<wa-select appearance="filled" size="small" value="default" pill class="preset-theme-selector">
<wa-icon slot="prefix" name="paintbrush" variant="regular"></wa-icon>
{% for theme in collections.theme | sort %}
<wa-option value="{{ theme.page.fileSlug }}"{{ ' data-alpha="remove"' if theme.noAlpha }}>
{{ theme.data.title }}
</wa-option>
{% endfor %}
</wa-select>
<wa-dropdown class="preset-theme-selector">
<wa-button slot="trigger" appearance="filled" size="small" pill caret>
<wa-icon slot="prefix" name="paintbrush" variant="regular"></wa-icon>
<span class="preset-theme-selector__text">Default</span>
</wa-button>
<wa-menu>
<wa-menu-item type="checkbox" value="default">Default</wa-menu-item>
<wa-menu-item type="checkbox" value="classic">Classic</wa-menu-item>
<wa-menu-item type="checkbox" value="awesome">Awesome</wa-menu-item>
<wa-menu-item type="checkbox" value="active">Active</wa-menu-item>
<wa-menu-item type="checkbox" value="brutalist">Brutalist</wa-menu-item>
<wa-menu-item data-alpha="remove" type="checkbox" value="glassy">Glassy</wa-menu-item>
<wa-menu-item type="checkbox" value="mellow">Mellow</wa-menu-item>
<wa-menu-item type="checkbox" value="migration">Migration</wa-menu-item>
<wa-menu-item data-alpha="remove" type="checkbox" value="playful">Playful</wa-menu-item>
<wa-menu-item data-alpha="remove" type="checkbox" value="premium">Premium</wa-menu-item>
</wa-menu>
</wa-dropdown>

View File

@@ -1,6 +1,6 @@
{# Some collections (like "patterns") will not have any items in the alpha build for example. So this checks to make sure the collection exists. #}
{% if collections[tag] -%}
<wa-details {{ (tag in (tags or [])) | attr('open') }}>
<wa-details {{ (('/' + tag + '/') in page.url) | attr('open') }}>
<h2 slot="summary">
{% set groupUrl %}/docs/{{ tag }}/{% endset %}
{% if groupUrl | getCollectionItemFromUrl %}

View File

@@ -1,6 +1,6 @@
{% if not (isAlpha and page.data.noAlpha) and page.fileSlug != tag and not page.data.unlisted -%}
<li>
<a href="{{ page.url }}">{{ page.data.title }}</a>
<a href="/docs/{{ tag }}/{{ page.fileSlug }}">{{ page.data.title }}</a>
{% if page.data.status == 'experimental' %}<wa-icon name="flask"></wa-icon>{% endif %}
{% if page.data.isPro %}<wa-badge class="pro">PRO</wa-badge>{% endif %}

View File

@@ -3,6 +3,7 @@
<ul>
<li><a href="/docs/installation">Installation</a></li>
<li><a href="/docs/usage">Usage</a></li>
<li><a href="/docs/themes">Themes</a></li>
<li><a href="/docs/customizing">Customizing</a></li>
<li><a href="/docs/form-controls">Form Controls</a></li>
<li><a href="/docs/localization">Localization</a></li>
@@ -19,7 +20,6 @@
</ul>
{% for tag, title in {
'themes': 'Themes',
'components': 'Components',
'native': 'Native Styles',
'utilities': 'Style Utilities',

View File

@@ -1,25 +1,25 @@
{% if since -%}
<wa-badge variant="neutral">Since {{ since }}</wa-badge>
{% endif -%}
{%- endif %}
{%- if status %}
{% if status -%}
{%- if status == "wip" %}
<wa-badge variant="danger">
<wa-icon name="pickaxe"></wa-icon>
Work In Progress
</wa-badge>
{%- elif status == "experimental" %}
{%- elif status == "experimental" -%}
<wa-badge variant="warning">
<wa-icon name="flask"></wa-icon>
Experimental
</wa-badge>
{%- elif status == "stable" %}
{%- elif status == "stable" -%}
<wa-badge variant="brand">Stable</wa-badge>
{%- else %}
<wa-badge>{{ status}}</wa-badge>
{%- endif -%}
{%- endif %}
{%- endif %}
{%- if isPro %}
{% if isPro -%}
<wa-badge class="pro">PRO</wa-badge>
{%- endif -%}
{%- endif %}

View File

@@ -1,144 +0,0 @@
<div class="showcase-examples-wrapper" aria-hidden="true" data-no-outline>
<div class="showcase-examples">
<wa-card with-header with-footer>
<div slot="header" class="wa-split">
<h3 class="wa-heading-m">Your Cart</h3>
<wa-icon-button name="xmark" tabindex="-1"></wa-icon-button>
</div>
<div class="wa-stack wa-gap-xl">
<div class="wa-flank">
<wa-avatar shape="rounded" style="--size: 3em; --background-color: var(--wa-color-green-60); --text-color: var(--wa-color-green-95);">
<wa-icon slot="icon" name="sword-laser" family="duotone" style="font-size: 1.5em;"></wa-icon>
</wa-avatar>
<div class="wa-stack wa-gap-2xs">
<div class="wa-split wa-gap-2xs">
<strong>Initiate Saber</strong>
<strong>$179.99</strong>
</div>
<div class="wa-split wa-gap-2xs wa-caption-m">
<span>Green</span>
<a href="#" tabindex="-1">Remove</a>
</div>
</div>
</div>
<wa-divider></wa-divider>
<div class="wa-flank">
<wa-avatar shape="rounded" style="--size: 3em; --background-color: var(--wa-color-teal-60); --text-color: var(--wa-color-teal-95);">
<wa-icon slot="icon" name="robot-astromech" family="duotone" style="font-size: 1.5em;"></wa-icon>
</wa-avatar>
<div class="wa-stack wa-gap-2xs">
<div class="wa-split wa-gap-2xs">
<strong>Repair Droid</strong>
<strong>$3,049.99</strong>
</div>
<div class="wa-split wa-gap-2xs wa-caption-m">
<span>R-series</span>
<a href="#" tabindex="-1">Remove</a>
</div>
</div>
</div>
</div>
<div slot="footer" class="wa-stack">
<div class="wa-split">
<strong>Subtotal</strong>
<strong>$3,229.98</strong>
</div>
<span class="wa-caption-m">Shipping and taxes calculated at checkout.</span>
<wa-button tabindex="-1" variant="brand">
<wa-icon slot="prefix" name="shopping-bag"></wa-icon>
Checkout
</wa-button>
</div>
</wa-card>
<wa-card>
<wa-avatar shape="rounded" style="--size: 1.9lh; float: left; margin-right: var(--wa-space-m);">
<wa-icon slot="icon" name="hat-wizard" family="duotone" style="font-size: 1.75em;"></wa-icon>
</wa-avatar>
<p class="wa-body-l" style="margin: 0;">&ldquo;All we have to decide is what to do with the time that is given to us. There are other forces at work in this world, Frodo, besides the will of evil.&rdquo;</p>
</wa-card>
<wa-card>
<div class="wa-stack">
<h3 class="wa-heading-m">Sign In</h3>
<wa-input tabindex="-1" label="Email" placeholder="ddjarin@mandalore.gov">
<wa-icon slot="prefix" name="envelope" variant="regular"></wa-icon>
</wa-input>
<wa-input tabindex="-1" label="Password" type="password">
<wa-icon slot="prefix" name="lock" variant="regular"></wa-icon>
</wa-input>
<wa-button tabindex="-1" variant="brand">Sign In</wa-button>
<a href="#" tabindex="-1" class="wa-body-s">I forgot my password</a>
</div>
</wa-card>
<wa-card with-footer>
<div class="wa-stack">
<div class="wa-split">
<h3 class="wa-heading-m">To-Do</h3>
<wa-icon-button tabindex="-1" name="plus" label="Add task"></wa-icon-button>
</div>
<wa-checkbox tabindex="-1" checked>Umbrella for Adelard</wa-checkbox>
<wa-checkbox tabindex="-1" checked>Waste-paper basket for Dora</wa-checkbox>
<wa-checkbox tabindex="-1" checked>Pen and ink for Milo</wa-checkbox>
<wa-checkbox tabindex="-1">Mirror for Angelica</wa-checkbox>
<wa-checkbox tabindex="-1">Silver spoons for Lobelia</wa-checkbox>
</div>
<div slot="footer">
<a href="" tabindex="-1">View all completed</a>
</div>
</wa-card>
<wa-card>
<div class="wa-stack">
<div class="wa-frame wa-border-radius-m" style="align-self: center; max-inline-size: 25ch;">
<img src="https://images.unsplash.com/photo-1667514627762-521b1c815a89?q=20" alt="Album art">
</div>
<div class="wa-flank:end wa-align-items-start">
<div class="wa-stack wa-gap-3xs">
<div class="wa-cluster wa-gap-xs" style="height: 2.25em;">
<strong>The Stone Troll</strong>
<small><wa-badge variant="neutral" appearance="filled">E</wa-badge></small>
</div>
<span class="wa-caption-m">Samwise G</span>
</div>
<wa-icon-button tabindex="-1" name="ellipsis" label="Options"></wa-icon-button>
</div>
<div class="wa-stack wa-gap-2xs">
<wa-progress-bar value="34" style="height: 0.5em"></wa-progress-bar>
<div class="wa-split">
<span class="wa-caption-xs">1:01</span>
<span class="wa-caption-xs">-1:58</span>
</div>
</div>
<div class="wa-grid wa-align-items-center" style="--min-column-size: 1em; justify-items: center;">
<wa-icon-button tabindex="-1" name="backward" label="Skip backward"></wa-icon-button>
<wa-icon-button tabindex="-1" name="pause" style="font-size: var(--wa-font-size-2xl);" label="Pause"></wa-icon-button>
<wa-icon-button tabindex="-1" name="forward" label="Skip forward"></wa-icon-button>
</div>
</div>
</wa-card>
<wa-card>
<div class="wa-stack">
<h3 class="wa-heading-m">Chalmun's Spaceport Cantina</h3>
<div class="wa-cluster wa-gap-xs">
<wa-rating value="4.6" read-only></wa-rating>
<strong>4.6</strong>
<span>(419 reviews)</span>
</div>
<div class="wa-cluster wa-gap-xs">
<div class="wa-cluster wa-gap-3xs">
<wa-icon name="dollar" style="color: var(--wa-color-green-60);"></wa-icon>
<wa-icon name="dollar" style="color: var(--wa-color-green-60);"></wa-icon>
<wa-icon name="dollar" style="color: var(--wa-color-green-60);"></wa-icon>
</div>
<span class="wa-caption-m">&bull;</span>
<wa-tag size="small">Cocktail Bar</wa-tag>
<wa-tag size="small">Gastropub</wa-tag>
<wa-tag size="small">Local Fare</wa-tag>
<wa-tag size="small">Gluten Free</wa-tag>
</div>
<div class="wa-flank wa-gap-xs">
<wa-icon name="location-dot"></wa-icon>
<a href="#" class="wa-caption-m" tabindex="-1">Mos Eisley, Tatooine</a>
</div>
</div>
</wa-card>
</div>
</div>

View File

@@ -1,11 +1,62 @@
<!DOCTYPE html>
<html lang="en" data-fa-kit-code="b10bfbde90" data-cdn-url="{% cdnUrl %}">
<head>
{% include 'head.njk' %}
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="{{ description }}">
{% if noindex %}<meta name="robots" content="noindex">{% endif %}
<title>{{ title }}</title>
<link rel="icon" href="/assets/images/webawesome-logo.svg" />
<link rel="apple-touch-icon" href="/assets/images/app-icon.png">
{# Scripts #}
{# Hydration stuff #}
<script src="/assets/scripts/hydration-errors.js"></script>
<link rel="stylesheet" href="/assets/styles/hydration-errors.css">
<link rel="preconnect" href="https://cdn.jsdelivr.net">
<script type="module" src="https://cdn.jsdelivr.net/npm/@hotwired/turbo@8.0.10/+esm"></script>
{# Web Awesome #}
<script type="module" src="/dist/webawesome.ssr-loader.js"></script>
<link rel="stylesheet" id="theme-stylesheet" />
<link rel="stylesheet" href="/dist/styles/webawesome.css" />
<link id="color-stylesheet" rel="stylesheet" href="/dist/styles/utilities.css" />
<link rel="stylesheet" href="/dist/styles/forms.css" />
{# Set the theme to prevent flashing #}
<script>
function getColorScheme() {
return localStorage.getItem('colorScheme') || 'auto';
}
function getPresetTheme () {
return localStorage.getItem('presetTheme') || 'default';
}
function isDark() {
const colorScheme = getColorScheme()
if (colorScheme === 'auto') {
return window.matchMedia('(prefers-color-scheme: dark)').matches;
}
return colorScheme === 'dark';
}
const stylesheet = document.getElementById("theme-stylesheet")
let preset = getPresetTheme()
stylesheet.href = `/dist/styles/themes/${preset}.css`
document.documentElement.classList.toggle(
`wa-theme-${preset}-dark`,
isDark()
);
</script>
</head>
<body class="layout-{{ layout | stripExtension }}">
{% block header %}{% endblock %}
{% block beforeContent %}{% endblock %}
{% block content %}
{{ content | safe }}

View File

@@ -4,8 +4,7 @@
{% extends '../_includes/base.njk' %}
{# Component header #}
{% block header %}
{% include 'breadcrumbs.njk' %}
{% block beforeContent %}
<h1 class="title">{{ title }}</h1>
<div class="block-info">
{% set snippets = (elements or element or snippets or snippet) | dict %}

View File

@@ -0,0 +1,4 @@
{% set hasSidebar = true %}
{% set hasOutline = true %}
{% extends "../_includes/base-wide.njk" %}

View File

@@ -1,85 +0,0 @@
{% set hasSidebar = true %}
{% set hasOutline = true %}
{# {% set forceTheme = page.fileSlug %} #}
{% extends '../_includes/base.njk' %}
{% block header %}
<iframe src='{{ page.url }}demo.html'></iframe>
{% endblock %}
{% block afterContent %}
{% markdown %}
## How to use this theme
You can import this theme from the Web Awesome CDN.
<wa-tab-group>
<wa-tab panel="html">In HTML</wa-tab>
<wa-tab panel="css">In CSS</wa-tab>
<wa-tab-panel name="html">
Simply add the following code to the `<head>` of your page:
```html
<link rel="stylesheet" href="{% cdnUrl 'styles/themes/' + page.fileSlug + '.css' %}" />
```
</wa-tab-panel>
<wa-tab-panel name="css">
Simply add the following code at the top of your CSS file:
```css
@import url('{% cdnUrl 'styles/themes/' + page.fileSlug + '.css' %}');
```
</wa-tab-panel>
</wa-tab-group>
## Dark mode
To activate the dark color scheme of the theme on any element and its contents, apply the class `wa-dark` to it.
This means you can use different color schemes throughout the page.
Here, we use the default theme with a dark sidebar:
```html
<html>
<head>
<link rel="stylesheet" href="path/to/web-awesome/dist/styles/themes/default.css" />
</head>
<body>
<nav class="wa-dark">
<!-- dark-themed sidebar -->
</nav>
<!-- light-themed content -->
</body>
</html>
```
You can apply the class to the `<html>` element on your page to activate the dark color scheme for the entire page.
```html
<html class="wa-dark">
<head>
<link rel="stylesheet" href="path/to/web-awesome/dist/styles/themes/{{ page.fileSlug }}.css" />
<!-- other links, scripts, and metadata -->
</head>
<body>
<!-- page content -->
</body>
</html>
```
### Detecting Color Scheme Preference
Web Awesome's themes have both light and dark styles built in.
However, Web Awesome doesn't try to auto-detect the user's light/dark mode preference.
This should be done at the application level.
As a best practice, to provide a dark theme in your app, you should:
- Check for [`prefers-color-scheme`](https://stackoverflow.com/a/57795495/567486) and use its value by default
- Allow the user to override the setting in your app
- Remember the user's preference and restore it on subsequent logins
Web Awesome avoids using the `prefers-color-scheme` media query because not all apps support dark mode, and it would break things for the ones that don't.
{% endmarkdown %}
{% endblock %}

View File

@@ -167,9 +167,6 @@ export function sort(arr, by = { 'data.order': 1, 'data.title': '' }) {
* @returns { Object.<string, object[]> } An object with keys for each tag, and an array of items for each tag.
*/
export function groupByTags(collection, tags) {
if (!collection) {
console.error(`Empty collection passed to groupByTags() to group by ${JSON.stringify(tags)}`);
}
if (!tags) {
// Default to grouping by union of all tags
tags = Array.from(new Set(collection.flatMap(item => item.data.tags)));

View File

@@ -7,7 +7,7 @@ let stylesheets = Array.from(document.querySelectorAll("link[rel=stylesheet][hre
.join('\n');
let includes = `${stylesheets}
<script src="/dist/webawesome.loader.js" type="module"></script>
<link rel="stylesheet" href="./demo-page.css">`;
<link rel="stylesheet" href="/assets/examples/page-demo/page.css">`;
async function render() {
await customElements.whenDefined('wa-checkbox');

View File

Before

Width:  |  Height:  |  Size: 698 KiB

After

Width:  |  Height:  |  Size: 698 KiB

View File

Before

Width:  |  Height:  |  Size: 241 KiB

After

Width:  |  Height:  |  Size: 241 KiB

View File

Before

Width:  |  Height:  |  Size: 786 KiB

After

Width:  |  Height:  |  Size: 786 KiB

View File

Before

Width:  |  Height:  |  Size: 716 KiB

After

Width:  |  Height:  |  Size: 716 KiB

View File

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 148 KiB

View File

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View File

Before

Width:  |  Height:  |  Size: 438 KiB

After

Width:  |  Height:  |  Size: 438 KiB

View File

@@ -0,0 +1,59 @@
//
// Color scheme selector
//
(() => {
function setColorScheme(newColorScheme) {
colorScheme = newColorScheme;
localStorage.setItem('colorScheme', colorScheme);
const presetTheme = window.getPresetTheme();
// Update the UI
updateSelection();
// Toggle the dark mode class
document.documentElement.classList.toggle(`wa-theme-${presetTheme}-dark`, window.isDark());
}
function updateSelection() {
const menu = document.querySelector('#color-scheme-selector wa-menu');
if (!menu) return;
[...menu.querySelectorAll('wa-menu-item')].forEach(async item => {
await customElements.whenDefined(item.localName);
await item.updateComplete;
item.checked = item.getAttribute('value') === colorScheme;
});
}
let colorScheme = window.getColorScheme();
// Selection is not preserved when changing page, so update when opening dropdown
document.addEventListener('wa-show', event => {
const colorSchemeSelector = event.target.closest('#color-scheme-selector');
if (!colorSchemeSelector) return;
updateSelection();
});
// Listen for selections
document.addEventListener('wa-select', event => {
const menu = event.target.closest('#color-scheme-selector wa-menu');
if (!menu) return;
setColorScheme(event.detail.item.value);
});
// Update the color scheme when the preference changes
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => setColorScheme(colorScheme));
// Toggle with backslash
document.addEventListener('keydown', event => {
if (
event.key === '\\' &&
!event.composedPath().some(el => ['input', 'textarea'].includes(el?.tagName?.toLowerCase()))
) {
event.preventDefault();
setColorScheme(window.isDark() ? 'light' : 'dark');
}
});
// Set the initial color scheme and sync the UI
setColorScheme(colorScheme);
})();

View File

@@ -1,64 +0,0 @@
import { domChange, nextFrame, ThemeAspect } from './theme-picker.js';
const presetTheme = new ThemeAspect({
defaultValue: 'default',
key: 'presetTheme',
picker: 'wa-select.preset-theme-selector',
applyChange() {
const oldStylesheets = [...document.querySelectorAll('#theme-stylesheet')];
const oldStylesheet = oldStylesheets.pop();
if (oldStylesheets.length > 0) {
// Remove all but the last one
for (let stylesheet of oldStylesheets) {
stylesheet.remove();
}
}
const href = `/dist/styles/themes/${this.value}.css`;
if (!oldStylesheet || oldStylesheet.getAttribute('href') !== href) {
const newStylesheet = document.createElement('link');
Object.assign(newStylesheet, { href, id: 'theme-stylesheet', rel: 'preload', as: 'style' });
oldStylesheet.after(newStylesheet);
newStylesheet.addEventListener(
'load',
e => {
domChange(
async instant => {
// Swap stylesheets
newStylesheet.rel = 'stylesheet';
if (instant) {
// If no VT, delay by 1 frame to make it smoother
await nextFrame();
}
oldStylesheet.remove();
},
{ behavior: 'smooth' },
);
},
{ once: true },
);
}
},
});
/**
* Without this, there's a flash of the incorrect preset theme.
*/
function updateSelectionBeforeTurboLoad(e) {
const newElement = e.detail.newBody || e.detail.newFrame || e.detail.newStream;
if (newElement) {
presetTheme.syncUI(newElement);
}
}
['turbo:before-render', 'turbo:before-stream-render', 'turbo:before-frame-render'].forEach(eventName => {
document.addEventListener(eventName, updateSelectionBeforeTurboLoad);
});
window.presetTheme = presetTheme;

View File

@@ -0,0 +1,99 @@
(() => {
function applyThemeChange(stylesheet, newStylesheet) {
newStylesheet.rel = 'stylesheet';
newStylesheet.id = stylesheet.id;
requestAnimationFrame(() => {
stylesheet.remove();
});
}
function setPresetTheme(newPresetTheme) {
presetTheme = newPresetTheme;
localStorage.setItem('presetTheme', presetTheme);
const stylesheet = document.getElementById('theme-stylesheet');
const newStylesheet = Object.assign(document.createElement('link'), {
href: `/dist/styles/themes/${presetTheme}.css`,
rel: 'preload',
as: 'style',
});
newStylesheet.addEventListener(
'load',
() => {
const canUseViewTransitions =
document.startViewTransition && !window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (canUseViewTransitions) {
document.startViewTransition(() => applyThemeChange(stylesheet, newStylesheet));
} else {
applyThemeChange(stylesheet, newStylesheet);
}
},
{ once: true },
);
document.head.append(newStylesheet);
updateSelection();
document.documentElement.classList.toggle(`wa-theme-${presetTheme}-dark`, window.isDark());
}
function updateSelection(container = document) {
const menus = container.querySelectorAll('.preset-theme-selector wa-menu');
if (!menus) return;
[...menus].forEach(menu => {
// Clear all checked states
[...menu.querySelectorAll('wa-menu-item')].forEach(async item => {
await customElements.whenDefined(item.localName);
await item.updateComplete;
item.checked = false; // Reset all items to unchecked first
});
// Then set only the selected item as checked
const selectedItem = menu.querySelector(`wa-menu-item[value="${presetTheme}"]`);
if (selectedItem) {
customElements.whenDefined(selectedItem.localName).then(async () => {
await selectedItem.updateComplete;
selectedItem.checked = true;
container.querySelector('.preset-theme-selector__text').textContent = selectedItem.innerText;
});
}
});
}
let presetTheme = window.getPresetTheme();
// Selection is not preserved when changing page, so update when opening dropdown
document.addEventListener('wa-show', event => {
const presetThemeSelector = event.target.closest('.preset-theme-selector');
if (!presetThemeSelector) return;
updateSelection();
});
// Listen for selections
document.addEventListener('wa-select', event => {
const menu = event.target.closest('.preset-theme-selector wa-menu');
if (!menu) return;
setPresetTheme(event.detail.item.value);
});
// Update the color scheme when the preference changes
window.matchMedia('(prefers-preset-theme: dark)').addEventListener('change', () => setPresetTheme(presetTheme));
updateSelection();
/**
* Without this, there's a flash of the incorrect preset theme.
*/
function updateSelectionBeforeTurboLoad(e) {
const newElement = e.detail.newBody || e.detail.newFrame || e.detail.newStream;
if (!newElement) {
return;
}
updateSelection(newElement);
}
['turbo:before-render', 'turbo:before-stream-render', 'turbo:before-frame-render'].forEach(eventName => {
document.addEventListener(eventName, updateSelectionBeforeTurboLoad);
});
})();

View File

@@ -9,7 +9,6 @@ const icons = {
component: 'puzzle-piece',
document: 'file',
home: 'house',
native: 'code',
theme: 'palette',
};
let searchTimeout;
@@ -167,7 +166,6 @@ async function updateResults(query = '') {
li.setAttribute('data-selected', index === 0 ? 'true' : 'false');
if (page.url === '/') icon = icons.home;
if (page.url.startsWith('/docs/native')) icon = icons.native;
if (page.url.startsWith('/docs/components')) icon = icons.component;
if (page.url.startsWith('/docs/theme') || page.url.startsWith('/docs/restyle')) icon = icons.theme;

View File

@@ -1,37 +0,0 @@
/**
* Sync iframe height with its content page (for same-origin iframes)
* NOT CURRENTLY USED ANYWHERE
*/
for (let iframe of document.querySelectorAll('iframe')) {
if (iframe.contentDocument) {
// Already loaded
syncIframeHeight(iframe);
}
iframe.onload = () => {
console.log('iframe loaded');
if (iframe.contentDocument) {
// Same origin
iframe.contentWindow.iframe = iframe;
syncIframeHeight(iframe);
const resizeObserver = new ResizeObserver(entries => {
for (let entry of entries) {
if (entry.target === iframe.contentDocument.body) {
syncIframeHeight(iframe);
}
}
});
resizeObserver.observe(iframe.contentDocument.body);
window.addEventListener('turbo:render', syncIframeHeight(iframe));
}
};
}
function syncIframeHeight(iframe) {
iframe.style.height = '0px';
requestAnimationFrame(() => {
iframe.style.height = iframe.contentDocument.body.scrollHeight + 'px';
});
}

View File

@@ -1,115 +0,0 @@
// Helper for view transitions
export function domChange(fn, { behavior = 'smooth' } = {}) {
const canUseViewTransitions =
document.startViewTransition && !window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (canUseViewTransitions && behavior === 'smooth') {
document.startViewTransition(fn);
} else {
fn(true);
}
}
export function nextFrame() {
return new Promise(resolve => requestAnimationFrame(resolve));
}
export class ThemeAspect {
constructor(options) {
Object.assign(this, options);
this.set();
// Update when local storage changes.
// That way changes in one window will propagate to others (including iframes).
window.addEventListener('storage', event => {
if (event.key === this.key) {
this.set();
}
});
// Listen for selections
document.addEventListener('wa-change', event => {
const picker = event.target.closest(this.picker);
if (picker) {
this.set(picker.value);
}
});
}
get() {
return localStorage.getItem(this.key) ?? this.defaultValue;
}
computed = {};
get computedValue() {
if (this.value in this.computed) {
return this.computed[this.value];
}
return this.value;
}
set(value = this.get()) {
if (value === this.value) {
return;
}
this.value = value;
if (this.value === this.defaultValue) {
localStorage.removeItem(this.key);
} else {
localStorage.setItem(this.key, this.value);
}
this.applyChange();
this.syncUI();
}
syncUI(container = document) {
for (let picker of container.querySelectorAll(this.picker)) {
picker.setAttribute('value', this.value);
picker.value = this.value;
}
}
}
const colorScheme = new ThemeAspect({
defaultValue: 'auto',
key: 'colorScheme',
picker: 'wa-select.color-scheme-selector',
computed: {
get auto() {
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
},
},
applyChange() {
// Toggle the dark mode class
domChange(() => {
let dark = this.computedValue === 'dark';
document.documentElement.classList.toggle(`wa-dark`, dark);
for (let el of document.querySelectorAll('.wa-invert')) {
el.classList.toggle('wa-dark', !dark);
el.classList.toggle('wa-light', dark);
}
});
},
});
// Update the color scheme when the preference changes
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => colorScheme.set());
// Toggle color scheme with backslash
document.addEventListener('keydown', event => {
if (
event.key === '\\' &&
!event.composedPath().some(el => ['input', 'textarea'].includes(el?.tagName?.toLowerCase()))
) {
event.preventDefault();
colorScheme.set(theming.colorScheme.resolvedValue === 'dark' ? 'light' : 'dark');
}
});

View File

@@ -10,8 +10,8 @@
--wa-brand-grey: #30323b;
}
.wa-dark .only-light,
.only-dark:not(.wa-dark, .wa-dark *) {
html.wa-theme-default-dark .only-light,
html:not(.wa-theme-default-dark) .only-dark {
display: none;
}
@@ -34,6 +34,10 @@ wa-page::part(header-actions) {
}
wa-page > header {
flex: 1 1 auto;
display: flex;
align-items: center;
justify-content: space-between;
padding-inline: var(--wa-space-xl);
a[href='/'] {
@@ -211,20 +215,6 @@ wa-page::part(menu) {
scrollbar-width: thin;
}
wa-page[view='mobile'] :is([slot='navigation-header'], [slot='navigation']) {
padding: 0;
& wa-details::part(icon) {
padding-inline: var(--wa-space-xs); /* aligns details icons with drawer close icon */
}
}
[slot='navigation-header'] wa-menu {
font-family: var(--wa-font-family-body);
font-size: var(--wa-font-size-m);
font-weight: var(--wa-font-weight-normal);
}
/* Main content */
wa-page > main {
max-width: 80ch;
@@ -336,18 +326,16 @@ wa-page > main:has(> .index-grid) {
a {
border-radius: var(--wa-border-radius-l);
text-decoration: none;
}
wa-card {
box-shadow: none;
--box-shadow: none;
--spacing: var(--wa-space-m);
inline-size: 100%;
&:hover {
--border-color: var(--wa-color-brand-border-loud);
border-color: var(--border-color);
box-shadow: 0 0 0 var(--wa-border-width-s) var(--border-color);
--box-shadow: 0 0 0 var(--wa-border-width-s) var(--border-color);
.page-name {
color: var(--wa-color-brand-on-quiet);
@@ -455,20 +443,3 @@ wa-page > main:has(> .index-grid) {
padding: var(--wa-space-3xl);
}
}
.layout-theme {
wa-page > main {
max-width: 140ch;
.max-line-length {
max-width: 80ch;
}
}
iframe {
width: 100%;
min-height: 16lh;
height: 65vh;
max-height: 21lh;
}
}

View File

@@ -31,9 +31,6 @@
}
@media screen and (max-width: 1199px) {
wa-page [slot='aside'] {
display: none;
}
#outline {
padding-block: 0.25rem;
margin-block-end: -1rem;

View File

@@ -4,7 +4,7 @@
*/
/* #region Default */
html.wa-theme-default .preview-container {
html[class*='wa-theme-default'] .preview-container {
container-name: default-theme;
}
@@ -58,12 +58,12 @@ html.wa-theme-default .preview-container {
}
/* #endregion */
/* #region Tailspin */
html.wa-theme-tailspin .preview-container {
container-name: tailspin-theme;
/* #region Migration */
html[class*='wa-theme-migration'] .preview-container {
container-name: migration-theme;
}
@container tailspin-theme (min-width: 0) {
@container migration-theme (min-width: 0) {
.project-header {
background: var(--wa-color-surface-default);
}
@@ -139,7 +139,7 @@ html.wa-theme-tailspin .preview-container {
/* #endregion */
/* #region Brutalist */
html.wa-theme-brutalist .preview-container {
html[class*='wa-theme-brutalist'] .preview-container {
container-name: brutalist-theme;
}
@@ -268,7 +268,7 @@ html.wa-theme-brutalist .preview-container {
border: var(--wa-panel-border-width) var(--wa-panel-border-style) var(--wa-color-surface-border);
}
.wa-theme-brutalist.wa-dark {
.wa-theme-brutalist-dark {
& p a::before {
background: var(--wa-color-yellow-40);
}
@@ -332,7 +332,7 @@ html.wa-theme-brutalist .preview-container {
/* #endregion */
/* #region Playful */
html.wa-theme-playful .preview-container {
html[class*='wa-theme-playful'] .preview-container {
container-name: playful-theme;
}
@@ -416,7 +416,7 @@ html.wa-theme-playful .preview-container {
background-color: var(--wa-color-neutral-fill-quiet);
}
&:not(.wa-theme-premium.wa-dark) .message-composer wa-card {
&:not(.wa-theme-premium-dark) .message-composer wa-card {
--wa-color-neutral-fill-quiet: var(--wa-color-gray-90);
}
@@ -434,7 +434,7 @@ html.wa-theme-playful .preview-container {
}
.support-table wa-card {
background: var(--wa-color-surface-raised);
--background: var(--wa-color-surface-raised);
}
.support-table th {
@@ -469,13 +469,13 @@ html.wa-theme-playful .preview-container {
padding-block-end: var(--wa-space-xs);
}
.wa-theme-playful.wa-dark {
.wa-theme-playful-dark {
& .hero-background {
background: linear-gradient(180deg, var(--wa-color-green-60) 69.42%, var(--wa-color-green-30) 100%);
}
& .message-composer wa-card {
border-color: var(--wa-color-gray-30);
--border-color: var(--wa-color-gray-30);
}
& .message-composer wa-card::part(header) {
@@ -505,7 +505,7 @@ html.wa-theme-playful .preview-container {
/* #endregion */
/* #region Active */
html.wa-theme-active .preview-container {
html[class*='wa-theme-active'] .preview-container {
container-name: active-theme;
}
@@ -578,7 +578,7 @@ html.wa-theme-active .preview-container {
/* #endregion */
/* #region Premium */
html.wa-theme-premium .preview-container {
html[class*='wa-theme-premium'] .preview-container {
container-name: premium-theme;
}
@@ -644,7 +644,7 @@ html.wa-theme-premium .preview-container {
}
.message-composer wa-card {
background: var(--wa-color-surface-raised);
--background: var(--wa-color-surface-raised);
}
.message-composer wa-card::part(header) {
@@ -652,7 +652,7 @@ html.wa-theme-premium .preview-container {
background-color: var(--wa-color-neutral-fill-quiet);
}
&:not(.wa-theme-premium.wa-dark) .message-composer wa-card {
&:not(.wa-theme-premium-dark) .message-composer wa-card {
--wa-color-neutral-fill-quiet: var(--wa-color-base-95);
}
@@ -702,7 +702,7 @@ html.wa-theme-premium .preview-container {
font-style: italic;
}
.wa-theme-premium.wa-dark {
.wa-theme-premium-dark {
& .message-composer .tools .grouped-buttons:not(:last-of-type) {
--wa-color-neutral-border-quiet: var(--wa-color-base-40);
}

View File

@@ -45,7 +45,7 @@ table code {
}
}
</script>
<script type="module" src="./cheatsheet.js"></script>
<script type="module" src="/assets/scripts/cheatsheet.js"></script>
{% for type, all in componentsBy -%}
{% set typeTitle = "CSS custom properties" if type == "cssProperty" else ("CSS parts" if type == "cssPart" else (type | title) + "s") %}

View File

@@ -24,6 +24,49 @@ Many Font Awesome Pro icon families have variants such as `thin`, `light`, `regu
<wa-icon family="brands" name="web-awesome"></wa-icon>
```
<div data-alpha="remove">
### Setting icon info via CSS
You can set the icon's family, name, and variant via CSS custom properties. This can be useful when you want to set <!-- the icon dynamically or set --> defaults for a group of icons (e.g. icons inside callouts or all icons for a given theme):
```html {.example}
<wa-callout>
<!-- Look ma, no attributes! -->
<wa-icon slot="icon"></wa-icon>
This is a callout.
</wa-callout>
<wa-callout variant="danger">
<wa-icon slot="icon" name="dumpster-fire" variant="solid"></wa-icon>
This is a callout with an explicit icon.
</wa-callout>
<wa-callout variant="warning">
<!-- Look ma, no attributes! -->
<wa-icon slot="icon"></wa-icon>
Here be dragons.
</wa-callout>
<style>
wa-callout {
--wa-icon-variant: regular;
--wa-icon-name: info-circle;
&[variant="warning"] {
--wa-icon-name: triangle-exclamation;
}
}
</style>
```
Notes:
- If you specify attributes, they will override the CSS custom properties, which provides a way to set defaults and then override them as needed.
- CSS custom properties inherit — so if you set a `--wa-icon-*` custom property on an element, it will affect *all* icons within it that dont override these values (either via attributes or CSS custom properties).
- These CSS properties are currently not reactive and will only be read when the component is first connected.
</div>
### Colors
Icons inherit their color from the current text color. Thus, you can set the `color` property on the `<wa-icon>` element or an ancestor to change the color.

View File

@@ -127,7 +127,7 @@ eleventyExcludeFromCollections: true
</a>
</nav>
<header slot="main-header">
<div class="wa-flank:end wa-border-radius-l wa-dark" style="background-color: var(--wa-color-surface-lowered); --content-percentage: 35%; padding: var(--wa-space-m);">
<div class="wa-flank:end wa-border-radius-l wa-theme-default-dark" style="background-color: var(--wa-color-surface-lowered); --content-percentage: 35%; padding: var(--wa-space-m);">
<div class="wa-stack" style="margin: var(--wa-space-2xl);">
<h1>Great Horned Owl</h1>
<wa-divider></wa-divider>

View File

@@ -5,7 +5,7 @@ layout: blank
eleventyExcludeFromCollections: true
---
<wa-page class="wa-dark">
<wa-page class="wa-theme-default-dark">
<header slot="header">
<div class="wa-cluster">
<wa-icon-button name="bars" label="Menu" data-toggle-nav></wa-icon-button>

View File

@@ -1,7 +1,7 @@
---
title: Page
description: Pages offer an easy way to scaffold entire page layouts using minimal markup.
tags: [pro, organization, layout]
tags: [organization, layout]
isPro: true
order: 0
# icon: page
@@ -119,7 +119,7 @@ It can be opened using a button with `[data-toggle-nav]` that appears in the `su
</a>
</nav>
<header slot="main-header">
<div class="wa-flank:end wa-border-radius-l wa-dark" style="background-color: var(--wa-color-surface-lowered); --content-percentage: 35%; padding: var(--wa-space-m);">
<div class="wa-flank:end wa-border-radius-l wa-theme-default-dark" style="background-color: var(--wa-color-surface-lowered); --content-percentage: 35%; padding: var(--wa-space-m);">
<div class="wa-stack" style="margin: var(--wa-space-2xl);">
<h1>Great Horned Owl</h1>
<wa-divider></wa-divider>
@@ -299,7 +299,7 @@ It can be opened using a button with `[data-toggle-nav]` that appears in the `su
A sample media app page using `header`, `navigation-header`, `main-header`, and `main-footer` along with the default slot. The navigation menu collapses into a drawer at the default `mobile-breakpoint` and can be opened using a button with `[data-toggle-nav]` that appears in the `header` slot.
```html {.example viewport="1600"}
<wa-page class="wa-dark">
<wa-page class="wa-theme-default-dark">
<header slot="header">
<div class="wa-cluster">
<wa-icon-button name="bars" label="Menu" data-toggle-nav></wa-icon-button>

View File

@@ -15,9 +15,9 @@ Because these custom properties live at the page level, they're prefixed with `-
To customize a theme, simply override any of these custom properties in your own stylesheet by scoping your styles to `:root`, `:host`, and, if needed, the class for the specific theme you want to override. Here's an example that changes the default brand color (blue) to violet in the light theme using existing [literal colors](/docs/theming/color/#literal-colors).
```css
:where(:root),
:root,
:host,
.wa-theme-default {
.wa-theme-default-light {
/* Changes the brand color to violet across the library */
--wa-color-brand-fill-quiet: var(--wa-color-violet-95);
--wa-color-brand-fill-normal: var(--wa-color-violet-90);

View File

@@ -172,7 +172,7 @@ layout: page-outline
<div class="shadow" style="box-shadow: var(--wa-shadow-l);"></div>
```
## Alignment Tests
## Tests
```html {.example}
<style>
@@ -254,8 +254,6 @@ layout: page-outline
</div>
```
## Custom Property Tests
```html {.example}
<style>
.wa-theme-test {
@@ -321,32 +319,4 @@ layout: page-outline
</wa-select>
</div>
```
## Text Controls Tests
```html {.example}
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 2rem;">
<label>Native Input <input type="text" value="value"></label>
<wa-input label="WA Input" type="text" value="value"></wa-input>
<label>
Native Select
<select value="option-1">
<option value="option-1">Option 1</option>
<option value="option-2">Option 2</option>
<option value="option-3">Option 3</option>
<option value="option-4">Option 4</option>
</select>
</label>
<wa-select label="WA Select" value="option-1">
<wa-option value="option-1">Option 1</wa-option>
<wa-option value="option-2">Option 2</wa-option>
<wa-option value="option-3">Option 3</wa-option>
<wa-option value="option-4">Option 4</wa-option>
</wa-select>
<label>Native Textarea <textarea>value</textarea></label>
<wa-textarea label="WA Textarea" value="value"></wa-textarea>
</div>
```

View File

@@ -505,7 +505,7 @@ hasOutline: false
<wa-option data-alpha="remove" value="premium">Premium</wa-option>
<wa-option data-alpha="remove" value="playful">Playful</wa-option>
<wa-option data-alpha="remove" value="brutalist">Brutalist</wa-option>
<wa-option data-alpha="remove" value="tailspin">Tailspin</wa-option>
<wa-option data-alpha="remove" value="migration">Migration</wa-option>
<wa-option data-alpha="remove" value="glassy">Glassy</wa-option>
<wa-option data-alpha="remove" value="active">Active</wa-option>
<wa-option value="classic">Classic</wa-option>
@@ -876,7 +876,7 @@ hasOutline: false
switch(themeSelect.value) {
case 'classic':
case 'tailspin':
case 'migration':
colorPalette = 'classic';
break;
case 'awesome':
@@ -1044,7 +1044,7 @@ hasOutline: false
switch(themeSelect.value) {
case 'premium':
case 'tailspin':
case 'migration':
case 'playful':
case 'brutalist':
case 'classic':
@@ -1256,7 +1256,7 @@ hasOutline: false
case 'brutalist':
presetLogoIcons = ['leaf', 'mug-hot', 'book-open', 'landmark'];
break;
case 'tailspin':
case 'migration':
presetLogoIcons = ['wind', 'feather', 'lemon', 'wind-turbine'];
break;
case 'glassy':
@@ -1490,7 +1490,7 @@ hasOutline: false
}
});
break;
case 'tailspin':
case 'migration':
iconFamily.value = 'fa-classic';
iconStyle.value = 'solid';
useFaIcons();
@@ -1742,7 +1742,7 @@ hasOutline: false
/* strata product cards */
.products wa-card {
.products wa-card::part(base) {
height: 100%;
}
@@ -2123,7 +2123,7 @@ hasOutline: false
<h3>Ontological Shock</h3>
<p>The allegory is related to Plato's theory of Forms, which holds that the true essence of an object is not what we perceive with our senses, but rather its quality, and that most people perceive only the shadow of the object and are thus limited to false perception.</p>
<pre class="codeblock">
<code class="language-html">&lt;html class="wa-dark"&gt;
<code class="language-html">&lt;html class="wa-theme-default-dark"&gt;
&lt;head&gt;
&lt;link rel="stylesheet" href="path/to/webawesome/dist/styles/themes/dark.css" /&gt;
&lt;/head&gt;

View File

@@ -12,7 +12,7 @@ Components with the <wa-badge variant="warning" pill>Experimental</wa-badge> bad
During the alpha period, things might break! We take breaking changes very seriously, but sometimes they're necessary to make the final product that much better. We appreciate your patience!
:::
## 3.0.0-alpha.8
## Next
- Simplified the internal structure and CSS properties of `<wa-card>`, removed `base` part.
- Added `appearance` to `<wa-callout>` and `<wa-tag>`
@@ -29,7 +29,7 @@ During the alpha period, things might break! We take breaking changes very serio
- Active
- Brutalist
- Mellow
- Tailspin
- Migration
- Playful
- Renamed `--wa-form-control-resting-color` to `--wa-form-control-border-color` for familiarity and accuracy
- Removed size-based `--wa-form-control-height-*` tokens in favor of `--wa-form-control-height` (see [size utilities](/docs/utilities/size/))

139
docs/docs/themes.md Normal file
View File

@@ -0,0 +1,139 @@
---
title: Themes
description: Everything you need to know about theming Web Awesome.
layout: page-outline
---
Themes are collections of pre-defined CSS custom properties that thread through every Web Awesome component and pattern.
Web Awesome includes two pre-made themes:
- **Default** for a clean look that prioritizes accessibility and performance
- **Classic** for the look and feel of Shoelace with more accessible color pairings
## What's a Theme?
Themes are a standard collection of [CSS custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/--*) that cover all styles from colors to transitions. We use these custom properties throughout Web Awesome components to ensure a cohesive look and feel. Our [Theming pages](/docs/theming/) document these styles so that you can use them freely throughout your project and customize them as needed.
Themes are scoped to unique classes for each color scheme, such as `wa-theme-default-light` and `wa-theme-default-dark`, and the `:host` selector. Scoping to unique classes allows you to import multiple themes and use them interchangeably without collisions, while scoping to `:host` ensures the styles are applied to the shadow roots of custom elements.
Additionally, styles may be scoped to the `:root` selector to be activated automatically. For pre-made themes, *all* custom properties are scoped to both `:root` and the class for the light color scheme (`wa-theme-default-light` or `wa-theme-classic-light`), activating the light color scheme by default.
Other themes or color schemes must be activated with the corresponding class, like the dark color scheme for pre-made themes (`wa-theme-default-dark` or `wa-theme-classic-dark`), which only defines a subset of custom properties for colors. This ensures that non-color styles only need to be defined once for the theme, regardless of whether the color scheme is light or dark.
For example, the default theme is set up like this:
```css
:root,
:host,
.wa-theme-default-light {
/* all CSS custom properties for color, typography, space, etc. */
}
.wa-theme-default-dark,
.wa-theme-default-dark :host {
/* subset of CSS custom properties for color */
}
```
## Using Themes
You can import the default and classic themes from the Web Awesome CDN. Simply add the following code to the `<head>` of your page to import the **default** theme:
```html
<link rel="stylesheet" href="https://early.webawesome.com/webawesome@3.0.0-alpha.4/dist/styles/themes/default.css" />
```
Or import the **classic** theme:
```html
<link rel="stylesheet" href="https://early.webawesome.com/webawesome@3.0.0-alpha.4/dist/styles/themes/classic.css" />
```
Both the default and classic themes include both light and dark color schemes. When importing either theme, the light color scheme is activated by default. To activate the dark color scheme, apply the appropriate class (`wa-theme-default-dark` or `wa-theme-classic-dark`, depending on theme) to the `<html>` element on your page, like this example for the default theme:
```html
<html class="wa-theme-default-dark">
<head>
<link rel="stylesheet" href="path/to/web-awesome/dist/styles/themes/default.css" />
<!-- other links, scripts, and metadata -->
</head>
<body>
<!-- page content -->
</body>
</html>
```
Because themes are scoped to specific classes, you can activate different color schemes or entire themes on different containers throughout the page. This example uses the default theme with a dark sidebar.
```html
<html>
<head>
<link rel="stylesheet" href="path/to/web-awesome/dist/styles/themes/default.css" />
</head>
<body>
<nav class="wa-theme-default-dark">
<!-- dark-themed sidebar -->
</nav>
<!-- light-themed content -->
</body>
</html>
```
## Creating Themes
There are two ways to create themes. The easiest way is to customize the default theme. The advanced way is to create a new theme from scratch. Which method you choose depends on your project's requirements and the amount of effort you're willing to invest.
### Customizing a Built-in Theme
Overriding the default theme is the easiest way to customize Web Awesome. You can do this by importing the default theme as-is, then creating a separate stylesheet that overrides [the theming API](/docs/customizing#design-tokens) and adds [component styles](/docs/customizing#css-parts) to your liking. You must import your theme _after_ the default theme.
If you're customizing the default light styles, scope your styles to the following selectors.
```css
:root,
:host,
.wa-theme-default-light {
/* your custom styles here */
}
```
If you're customizing the default dark styles, scope your styles to the following selectors.
```css
:host,
.wa-theme-default-dark {
/* your custom styles here */
}
```
By customizing a built-in theme, you'll maintain a smaller stylesheet containing only the changes you've made. Contrast this to [creating a new theme](#creating-a-new-theme), where you need to explicitly define every custom property required by the library. This approach is more "future-proof," as new design tokens that emerge in subsequent versions of Web Awesome will be accounted for by built-in themes.
While this approach is easier to maintain, the drawback is that your theme can't be activated independently — it's tied to the built-in theme you're extending.
### Creating a New Theme
Creating a new theme is more of an undertaking than [customizing an existing one](#customizing-a-built-in-theme). At a minimum, you must implement all of the required custom properties. The easiest way to do this is by "forking" a built-in theme and modifying it from there.
Start by changing the selector to match your theme's name. Assuming your new theme is called "Purple Power", your theme should be scoped like this.
```css
:host,
.wa-theme-purple-power {
/* your custom styles here */
}
```
By creating a new theme, you won't be relying on a built-in theme as a foundation. Because of this, you can activate it independently as an alternative to the default theme. This is the recommended approach if you're looking to open source your theme for others to use.
You will, however, need to maintain your theme more carefully, as new versions of Web Awesome change the theming API in ways that your theme won't have accounted for. It's recommended that you clearly specify which version(s) of Web Awesome your theme is designed to work with and keep it up to date as new versions of Web Awesome are released.
## Detecting Color Scheme Preference
Web Awesome's default theme has both light and dark styles built in. However, Web Awesome doesn't try to auto-detect the user's light/dark mode preference. This should be done at the application level. As a best practice, to provide a dark theme in your app, you should:
- Check for [`prefers-color-scheme`](https://stackoverflow.com/a/57795495/567486) and use its value by default
- Allow the user to override the setting in your app
- Remember the user's preference and restore it on subsequent logins
Web Awesome avoids using the `prefers-color-scheme` media query because not all apps support dark mode, and it would break things for the ones that don't.

View File

@@ -1,6 +0,0 @@
---
title: Active
description: Energetic and tactile, always in motion.
isPro: true
tags: pro
---

View File

@@ -1,5 +0,0 @@
---
title: Awesome
description: Punchy and vibrant, the rockstar of themes.
order: 0.2
---

View File

@@ -1,6 +0,0 @@
---
title: Brutalist
description: Sharp, square, and unapologetically bold.
isPro: true
tags: pro
---

View File

@@ -1,5 +0,0 @@
---
title: Classic
description: Timeless elegance that never goes out of style.
order: 0.1
---

View File

@@ -1,59 +0,0 @@
---
title: Creating Themes
layout: page-outline
order: 999
override:tags: [themes]
---
There are two ways to create themes.
The easiest way is to customize the default theme.
The advanced way is to create a new theme from scratch.
Which method you choose depends on your project's requirements and the amount of effort you're willing to invest.
## Customizing a Built-in Theme
Overriding the default theme is the easiest way to customize Web Awesome.
You can do this by importing the default theme as-is, then creating a separate stylesheet that overrides [the theming API](/docs/customizing#design-tokens) and adds [component styles](/docs/customizing#css-parts) to your liking. You must import your theme _after_ the default theme.
If you're customizing the default light styles, scope your styles to the following selectors.
```css
:where(:root),
:host,
.wa-theme-default,
.wa-light {
/* your custom styles here */
}
```
If you're customizing the default dark styles, scope your styles to the following selectors.
```css
.wa-dark,
:is(:host-context(.wa-dark)) {
/* your custom styles here */
}
```
By customizing a built-in theme, you'll maintain a smaller stylesheet containing only your changes. Contrast this to [creating a new theme](#creating-a-new-theme), where you need to explicitly define every custom property required by the library. This approach is more "future-proof," as new design tokens that emerge in subsequent versions of Web Awesome will be accounted for by built-in themes.
While this approach is easier to maintain, the drawback is that your theme can't be activated independently — it's tied to the built-in theme you're extending.
## Creating a New Theme
Creating a new theme is more of an undertaking than [customizing an existing one](#customizing-a-built-in-theme). At a minimum, you must implement all of the required custom properties. The easiest way to do this is by "forking" a built-in theme and modifying it from there.
Start by changing the selector to match your theme's name. Assuming your new theme is called "Purple Power", your theme should be scoped like this.
```css
:where(:root),
:host,
.wa-theme-purple-power,
.wa-light {
/* your custom styles here */
}
```
By creating a new theme, you won't be relying on a built-in theme as a foundation. Because of this, you can activate it independently as an alternative to the default theme. This is the recommended approach if you're looking to open source your theme for others to use.
You will, however, need to maintain your theme more carefully, as new versions of Web Awesome change the theming API in ways that your theme won't have accounted for. It's recommended that you clearly specify which version(s) of Web Awesome your theme is designed to work with and keep it up to date as new versions of Web Awesome are released.

View File

@@ -1,5 +0,0 @@
---
title: Default
description: Your trusty companion, like a perfectly broken-in pair of jeans.
order: 0
---

View File

@@ -1,40 +0,0 @@
---
layout: blank
pagination:
data: collections.theme
size: 1
alias: theme
permalink: '/docs/themes/{{ theme.fileSlug }}/demo.html'
eleventyExcludeFromCollections: true
override:tags: []
eleventyComputed:
forceTheme: "{{ theme.fileSlug }}"
---
<script>
document.getElementById('theme-stylesheet').href = '/dist/styles/themes/{{ theme.fileSlug }}.css';
</script>
<script type=module>
document.getElementById('theme-stylesheet').href = '/dist/styles/themes/{{ theme.fileSlug }}.css';
</script>
<link rel="stylesheet" href="/dist/styles/themes/{{ theme.fileSlug }}.css" />
<link rel="stylesheet" href="/docs/themes/showcase.css" />
{% set content %}
<header>
{% include 'breadcrumbs.njk' %}
<h1 class="title">{{ theme.data.title }}</h1>
<p>{% include 'status.njk' %}</p>
<p id="theme-showcase-description">{{ theme.data.description | inlineMarkdown | safe }}</p>
</header>
{% include 'theme-showcase.njk' %}
{% endset %}
<wa-image-comparer style="width: 100%" position="90">
<div slot="after" class="theme-showcase wa-gap-xl">
{{ content | safe }}
</div>
<div slot="before" class="theme-showcase wa-gap-xl wa-invert">
{{ content | safe }}
</div>
</wa-image-comparer>

View File

@@ -1,7 +0,0 @@
---
title: Glassy
description: Smooth, sleek, and reflective.
isPro: true
tags: pro
noAlpha: true
---

View File

@@ -1,55 +0,0 @@
---
title: Themes
description: Themes are collections of pre-defined CSS custom properties that thread through every Web Awesome component and pattern.
layout: overview
override:tags: []
forTag: theme
categories:
other: Free
pro: Pro
---
<div class="max-line-length">
{% markdown %}
## What's a Theme?
Themes are a collection of standardized [CSS custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/--*) that cover a range of styles from colors to transitions. We use these custom properties throughout Web Awesome components for a cohesive look and feel. Our [Theming pages](/docs/theming/) document these styles so that you can use them freely throughout your project and customize them as needed.
Themes are scoped to unique classes, such as `wa-theme-default` or `wa-theme-classic`.
Scoping to unique classes allows you to import multiple themes and use them interchangeably without collisions.
Please note that if you import multiple themes, the last one will be the default that will apply if no class is used.
Each theme may also include both light and dark color schemes with the classes `wa-light` and `wa-dark`.
You can use these classes to apply a specific color scheme to an entire page or just a section.
In pre-made themes, we use a light color scheme by default.
Additionally, styles may be scoped to the `:root` selector to be activated automatically.
For pre-made themes, *all* custom properties are scoped to `:root`, the theme class, and `wa-light`.
Finally, we scope themes to `:host` and `:host-context()` to ensure the styles are applied to the shadow roots of custom elements.
For example, the default theme is set up like this:
```css
:where(:root),
:host,
.wa-theme-default,
.wa-light {
/* all CSS custom properties for color, typography, space, etc. */
}
.wa-dark,
:host-context(.wa-dark) {
/* subset of CSS custom properties for a dark color scheme */
}
```
## Using Themes
You can import pre-made themes from the Web Awesome CDN.
Refer to each themes page for copyable code snippets.
{% endmarkdown %}
</div>

View File

@@ -1,6 +0,0 @@
---
title: Mellow
description: Soft and soothing, like a lazy Sunday morning.
isPro: true
tags: pro
---

View File

@@ -1,7 +0,0 @@
---
title: Playful
description: Fun, colorful, and full of personality.
isPro: true
tags: pro
noAlpha: true
---

View File

@@ -1,7 +0,0 @@
---
title: Premium
description: The ultimate in sophistication and style.
isPro: true
tags: pro
noAlpha: true
---

View File

@@ -1,90 +0,0 @@
html {
background: transparent;
}
html,
body,
.theme-showcase {
height: 100vh;
overflow: hidden;
}
.theme-showcase {
background-color: var(--wa-color-surface-lowered);
border-radius: var(--wa-border-radius-l);
padding: var(--wa-space-xl);
box-sizing: border-box;
overflow: hidden;
@media (width < 500px) {
flex-flow: column;
}
header {
min-width: min(25ch, 100vw);
align-self: center;
h1 {
margin-bottom: var(--wa-space-2xs);
}
wa-breadcrumb-item:not(:first-of-type, :last-of-type) {
display: none;
}
p:empty {
display: none;
}
}
}
.showcase-examples-wrapper {
inline-size: 100%;
block-size: 100%;
}
.showcase-examples {
column-gap: var(--wa-space-xl);
& wa-card {
display: inline-block;
width: 100%;
&:has(+ wa-card) {
margin-block-end: var(--wa-space-xl);
}
}
@supports not (zoom: 1) {
column-count: 1;
@media (width > 750px) {
column-count: 2;
}
@media (width > 950px) {
column-count: 3;
}
}
@supports (zoom: 1) {
column-count: 1;
zoom: 40%;
@media (width > 350px) {
column-count: 2;
}
@media (width > 450px) {
zoom: 55%;
}
@media (width > 750px) {
zoom: 70%;
}
@media (width > 950px) {
column-count: 3;
}
}
}

View File

@@ -1,6 +0,0 @@
---
title: Tailspin
description: Like a bird in flight, guiding you from there to here.
isPro: true
tags: pro
---

View File

@@ -1,4 +0,0 @@
{
"layout": "theme.njk",
"tags": ["themes", "theme"]
}

View File

@@ -268,7 +268,7 @@ layout: page
<h1 class="brand-font">Make something <span class="emphasis">awesome</span> with open-source web components</h1>
<div class="hero-cta">
<span><em>Psst!</em> You can pre-order Web Awesome Pro at a low, guaranteed-for-life price &mdash; but not for long. Get in while the gettins good.</span>
<wa-button class="wa-dark" size="small" href="https://www.kickstarter.com/projects/fontawesome/web-awesome">
<wa-button class="wa-theme-default-dark" size="small" href="https://www.kickstarter.com/projects/fontawesome/web-awesome">
<wa-icon slot="prefix" name="person-running"></wa-icon>
Pre-order WA Pro
</wa-button>

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "@shoelace-style/webawesome",
"version": "3.0.0-alpha.8",
"version": "3.0.0-alpha.7",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@shoelace-style/webawesome",
"version": "3.0.0-alpha.8",
"version": "3.0.0-alpha.7",
"license": "MIT",
"dependencies": {
"@ctrl/tinycolor": "^4.1.0",

View File

@@ -1,7 +1,7 @@
{
"name": "@shoelace-style/webawesome",
"description": "A forward-thinking library of web components.",
"version": "3.0.0-alpha.8",
"version": "3.0.0-alpha.7",
"homepage": "https://webawesome.com/",
"author": "Web Awesome",
"license": "MIT",
@@ -46,9 +46,7 @@
"scripts": {
"start": "node scripts/build.js --develop",
"build": "node scripts/build.js",
"build:serve": "npm run build && npx http-server _site -p 4000",
"build:alpha": "node scripts/build.js --alpha",
"build:alpha:serve": "npm run build:alpha && npx http-server _site -p 4000",
"start:alpha": "node scripts/build.js --alpha --develop",
"publish-alpha-cdn": "./publish-alpha-cdn.sh",
"create": "plop --plopfile scripts/plop/plopfile.js",

View File

@@ -74,10 +74,6 @@ function generateManifest() {
execSync('cem analyze --config "custom-elements-manifest.js"');
} catch (error) {
console.error(`\n\n${error.message}`);
if (!isDeveloping) {
process.exit(1);
}
}
spinner.succeed();
@@ -95,10 +91,6 @@ function generateReactWrappers() {
execSync(`node scripts/make-react.js --outdir "${cdnDir}"`, { stdio: 'inherit' });
} catch (error) {
console.error(`\n\n${error.message}`);
if (!isDeveloping) {
process.exit(1);
}
}
spinner.succeed();
@@ -127,7 +119,7 @@ async function generateStyles() {
file.includes('themes/awesome') ||
file.includes('themes/active') ||
file.includes('themes/mellow') ||
file.includes('themes/tailspin') ||
file.includes('themes/migration') ||
file.includes('themes/brutalist')
) {
return false;
@@ -155,9 +147,6 @@ async function generateTypes() {
try {
execSync(`tsc --project ./tsconfig.prod.json --outdir "${cdnDir}"`);
} catch (error) {
if (!isDeveloping) {
process.exit(1);
}
return Promise.reject(error.stdout);
}
@@ -230,9 +219,6 @@ async function generateBundle() {
} catch (error) {
spinner.fail();
console.log(chalk.red(`\n${error}`));
if (!isDeveloping) {
process.exit(1);
}
}
spinner.succeed();
@@ -249,10 +235,6 @@ async function regenerateBundle() {
} catch (error) {
spinner.fail();
console.log(chalk.red(`\n${error}`));
if (!isDeveloping) {
process.exit(1);
}
}
spinner.succeed();
@@ -268,31 +250,24 @@ async function generateDocs() {
if (isAlpha) args.push('--alpha');
if (isDeveloping) args.push('--develop');
let output;
try {
// 11ty
output = (await runScript(join(__dirname, 'docs.js'), args))
// Cleanup the output
.replace('[11ty]', '')
.replace(' seconds', 's')
.replace(/\(.*?\)/, '')
.toLowerCase()
.trim();
// 11ty
const output = (await runScript(join(__dirname, 'docs.js'), args))
// Cleanup the output
.replace('[11ty]', '')
.replace(' seconds', 's')
.replace(/\(.*?\)/, '')
.toLowerCase()
.trim();
// Copy dist (production only)
if (!isDeveloping) {
await copy(cdnDir, join(siteDir, 'dist'));
}
// Copy assets
await copy(join(docsDir, 'assets'), join(siteDir, 'assets'), { overwrite: true });
spinner.succeed(`Writing the docs ${chalk.gray(`(${output}`)})`);
} catch (error) {
console.error('\n\n' + chalk.red(error) + '\n');
spinner.fail(chalk.red(`Error while writing the docs.`));
if (!isDeveloping) {
process.exit(1);
}
// Copy dist (production only)
if (!isDeveloping) {
await copy(cdnDir, join(siteDir, 'dist'));
}
spinner.succeed(`Writing the docs ${chalk.gray(`(${output}`)})`);
}
// Initial build
@@ -393,10 +368,6 @@ if (isDeveloping) {
reload();
} catch (err) {
console.error(chalk.red(err));
if (!isDeveloping) {
process.exit(1);
}
}
});

View File

@@ -317,8 +317,8 @@
border-radius: inherit;
background-color: currentColor;
box-shadow:
inset 0 0 0 var(--border-width) var(--wa-form-control-border-color),
inset 0 0 0 calc(var(--border-width) * 2) var(--wa-color-surface-default);
inset 0 0 0 0.0625rem var(--wa-form-control-border-color),
inset 0 0 0 0.25rem var(--wa-color-surface-default);
}
.trigger--empty:before {

View File

@@ -48,21 +48,21 @@ export default class WaIcon extends WebAwesomeElement {
@state() private svg: SVGElement | HTMLTemplateResult | null = null;
/** The name of the icon to draw. Available names depend on the icon library being used. */
@property({ reflect: true }) name?: string;
@property({ cssProperty: true }) name?: string;
/**
* The family of icons to choose from. For Font Awesome Free (default), valid options include `classic` and `brands`.
* For Font Awesome Pro subscribers, valid options include, `classic`, `sharp`, `duotone`, and `brands`. Custom icon
* libraries may or may not use this property.
*/
@property({ reflect: true }) family: string;
@property({ cssProperty: true }) family: string;
/**
* The name of the icon's variant. For Font Awesome, valid options include `thin`, `light`, `regular`, and `solid` for
* the `classic` and `sharp` families. Some variants require a Font Awesome Pro subscription. Custom icon libraries
* may or may not use this property.
*/
@property({ reflect: true }) variant: string;
@property({ cssProperty: true }) variant: string;
/** Draws the icon in a fixed-width both. */
@property({ attribute: 'fixed-width', type: Boolean, reflect: true }) fixedWidth: false;
@@ -80,10 +80,11 @@ export default class WaIcon extends WebAwesomeElement {
@property() label = '';
/** The name of a registered custom icon library. */
@property({ reflect: true }) library = 'default';
@property({ cssProperty: true }) library = 'default';
connectedCallback() {
super.connectedCallback();
watchIcon(this);
}

View File

@@ -54,7 +54,6 @@ import styles from './input.css';
* @csspart suffix - The container that wraps the suffix.
*
* @cssproperty --background-color - The input's background color.
* @cssproperty --border-color - The color of the input's borders.
* @cssproperty --border-width - The width of the input's borders. Expects a single value.
* @cssproperty --box-shadow - The shadow effects around the edges of the input.
*/

View File

@@ -34,12 +34,14 @@
*/
:host([checked]) {
--indicator-color: var(--wa-form-control-activated-color);
--background-color: var(--wa-color-brand-fill-quiet);
--background-color-hover: var(--background-color);
--border-color: var(--wa-form-control-activated-color);
--text-color: var(--wa-color-brand-on-normal);
--indicator-color: var(--border-color);
--indicator-width: var(--wa-border-width-s);
box-shadow: inset 0 0 0 var(--indicator-width) var(--indicator-color);
& button {
--border-color: var(--indicator-color);
}
box-shadow:
var(--box-shadow, 0 0 transparent),
inset 0 0 0 var(--indicator-width) var(--indicator-color);
}

View File

@@ -8,7 +8,6 @@ import { HasSlotController } from '../../internal/slot.js';
import { watch } from '../../internal/watch.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-formassociated-element.js';
import nativeStyles from '../../styles/native/button.css';
import appearanceStyles from '../../styles/utilities/appearance.css';
import sizeStyles from '../../styles/utilities/size.css';
import variantStyles from '../../styles/utilities/variants.css';
import buttonStyles from '../button/button.css';
@@ -51,7 +50,7 @@ import styles from './radio-button.css';
*/
@customElement('wa-radio-button')
export default class WaRadioButton extends WebAwesomeFormAssociatedElement {
static shadowStyle = [variantStyles, appearanceStyles, sizeStyles, nativeStyles, buttonStyles, styles];
static shadowStyle = [variantStyles, sizeStyles, nativeStyles, buttonStyles, styles];
private readonly hasSlotController = new HasSlotController(this, '[default]', 'prefix', 'suffix');

View File

@@ -81,6 +81,8 @@ import styles from './select.css';
*
* @cssproperty --background-color - The background color of the select's combobox.
* @cssproperty --border-color - The border color of the select's combobox.
* @cssproperty --border-radius - The border radius of the select's combobox.
* @cssproperty --border-style - The style of the select's borders, including the listbox.
* @cssproperty --border-width - The width of the select's borders, including the listbox.
* @cssproperty --box-shadow - The shadow effects around the edges of the select's combobox.
*/

View File

@@ -38,7 +38,7 @@
}
--inset-block: calc(50% + (var(--thumb-size) / 2) + var(--tooltip-offset));
--border-block: var(--wa-tooltip-arrow-size) solid var(--wa-tooltip-background-color);
--border-block: var(--wa-tooltip-arrow-size) solid var(--wa-color-neutral-fill-loud);
@media (forced-colors: active) {
border: solid 1px transparent;

View File

@@ -41,6 +41,8 @@ import styles from './textarea.css';
*
* @cssproperty --background-color - The textarea's background color.
* @cssproperty --border-color - The color of the textarea's borders.
* @cssproperty --border-radius - The border radius of the textarea's corners.
* @cssproperty --border-style - The style of the textarea's borders.
* @cssproperty --border-width - The width of the textarea's borders.
* @cssproperty --box-shadow - The shadow effects around the edges of the textarea.
*/

View File

@@ -1,7 +1,18 @@
import type { CSSResult, CSSResultGroup, PropertyValues } from 'lit';
import type { CSSResult, CSSResultGroup, PropertyDeclaration, PropertyValues } from 'lit';
import { LitElement, isServer, unsafeCSS } from 'lit';
import { property } from 'lit/decorators.js';
import componentStyles from '../styles/shadow/component.css';
import { getComputedStyle } from './computedStyle.js';
// Augment Lit's module
declare module 'lit' {
interface PropertyDeclaration {
/**
* Indicates whether the property should reflect to a CSS custom property.
*/
cssProperty?: true | string;
}
}
export default class WebAwesomeElement extends LitElement {
constructor() {
@@ -52,6 +63,16 @@ export default class WebAwesomeElement extends LitElement {
internals: ElementInternals;
#computedStyle: CSSStyleDeclaration | null;
#setVia: Record<PropertyKey, 'css' | 'attribute' | 'js'> = {};
#setting = new Set<PropertyKey>();
connectedCallback() {
super.connectedCallback();
this.updateCSSProperties();
}
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {
if (!this.#hasRecordedInitialProperties) {
(this.constructor as typeof WebAwesomeElement).elementProperties.forEach(
@@ -111,6 +132,21 @@ export default class WebAwesomeElement extends LitElement {
}
}
updated(changedProperties: PropertyValues<this>) {
super.updated(changedProperties);
let Self = this.constructor as typeof WebAwesomeElement;
if (Self.cssAttributeProperties.size > 0) {
for (let [name] of changedProperties) {
if (typeof name === 'string' && this.#setVia[name] === 'css' && !this.#setting.has(name)) {
// A property is being set via JS and its NOT because we're reflecting a CSS property
this.#setVia[name] = 'js';
}
}
}
}
/** Checks if states are supported by the element */
private hasStatesSupport(): boolean {
return Boolean(this.internals?.states);
@@ -148,4 +184,51 @@ export default class WebAwesomeElement extends LitElement {
hasCustomState(state: string): boolean {
return this.hasStatesSupport() ? this.internals.states.has(state) : false;
}
protected updateCSSProperties() {
const Self = this.constructor as typeof WebAwesomeElement;
if (Self.cssAttributeProperties.size === 0) {
return;
}
this.#computedStyle ??= getComputedStyle(this);
// FIXME this is currently static. It will only update when the element is connected, and not when the CSS property changes.
const tagName = this.tagName.toLowerCase();
for (let [name, cssProperty] of Self.cssAttributeProperties) {
// FIXME currently this means that CSS properties will override JS properties. This is not ideal.
if (typeof name === 'string' && !this.hasAttribute(name) && this.#setVia[name] !== 'js') {
// Check if supplied as a CSS custom property
// TODO !important should override attribute values
cssProperty = cssProperty === true ? `--${tagName}-${name}` : cssProperty;
const value = this.#computedStyle?.getPropertyValue(cssProperty);
if (value) {
this.#setVia[name] = 'css';
this.#setting.add(name);
// @ts-ignore
this[name] = value.trim();
this.updateComplete.then(() => {
this.#setting.delete(name);
});
}
}
}
}
// Subclasses will override this
protected static cssAttributeProperties = new Map<PropertyKey, true | string>();
static createProperty(name: PropertyKey, options?: PropertyDeclaration): void {
super.createProperty(name, options);
if (options?.cssProperty) {
if (this.cssAttributeProperties === WebAwesomeElement.cssAttributeProperties) {
// Each class needs its own, otherwise they'd share the same Set
this.cssAttributeProperties = new Map();
}
this.cssAttributeProperties.set(name, options.cssProperty);
}
}
}

View File

@@ -2,11 +2,12 @@ input[type='color'] {
display: block;
border-radius: calc(infinity * 1px);
background: transparent;
padding: var(--wa-form-control-border-width);
padding: 3px;
width: calc(var(--wa-form-control-height) - 2px);
height: calc(var(--wa-form-control-height) - 2px);
border: var(--wa-form-control-border-width) var(--wa-border-style) var(--wa-form-control-border-color);
border: var(--wa-border-width-s) var(--wa-border-style) var(--wa-form-control-border-color);
cursor: pointer;
margin-block-start: 3px;
forced-color-adjust: none;
&::-webkit-color-swatch-wrapper {

View File

@@ -14,22 +14,13 @@ input:where(:not(
[type='reset'],
[type='submit']
)) {
/* Styling root, i.e. excluding elements within a host.
This is so that these properties can be overridden.
*/
&:not(:host *),
/* Safari and FF don't like :host:not(:host *) or :where(:host) so we need to add :host explicitly.
However, we can't just specify :host, because then it would become & :host which matches nothing.
:host(*) is the same as :host and the & prevents it from becoming a descendant selector.
*/
:host(:is(&, *)) {
&:not(:host *) {
/* Defaults for root element. */
--outlined-background-color: var(--wa-form-control-background-color);
--outlined-border-color: var(--wa-form-control-border-color);
--outlined-text-color: var(--wa-form-control-value-color);
:where(&),
:host(:where(&, *)) {
:where(&) {
/* Defaults with 0 specificity.
* Do NOT reset --background-color and --border-color here so they trickle in from the appearance utils
* Instead we provide the fallback when setting

View File

@@ -1,51 +1,41 @@
select,
label:has(select),
:host {
/* Defaults for root element. */
--outlined-background-color: var(--wa-form-control-background-color);
--outlined-border-color: var(--wa-form-control-border-color);
--outlined-text-color: var(--wa-form-control-value-color);
/* Safari and FF don't like :where(:host) so we need to add :host explicitly.
However, we can't just specify :host, because then it would become & :host which matches nothing.
:host(*) is the same as :host and the & prevents it from becoming a descendant selector.
*/
:where(&),
:host(:where(&, *)) {
/* Defaults with 0 specificity.
* Do NOT reset --background-color and --border-color here so they trickle in from the appearance utils
* Instead we provide the fallback when setting
*/
--border-width: var(--wa-form-control-border-width);
--box-shadow: initial;
}
--background-color: var(--wa-form-control-background-color);
--border-color: var(--wa-form-control-border-color);
--border-radius: var(--wa-form-control-border-radius);
--border-style: var(--wa-form-control-border-style);
--border-width: var(--wa-form-control-border-width);
--box-shadow: initial;
}
select,
:host [part~='combobox'] {
background-color: var(--background-color, var(--wa-form-control-background-color));
border-color: var(--border-color, var(--wa-form-control-border-color));
border-radius: var(--wa-form-control-border-radius);
border-style: var(--wa-form-control-border-style);
background-color: var(--background-color);
border-color: var(--border-color);
border-radius: var(--border-radius);
border-style: var(--border-style);
border-width: var(--border-width);
box-shadow: var(--box-shadow);
width: 100%;
min-width: 0;
position: relative;
color: var(--wa-form-control-value-color);
cursor: pointer;
font-family: inherit;
font-size: var(--wa-size);
font-family: inherit;
font-weight: var(--wa-form-control-value-font-weight);
line-height: var(--wa-form-control-value-line-height);
min-width: 0;
overflow: hidden;
padding: var(--wa-space-smaller) var(--wa-space);
position: relative;
vertical-align: middle;
width: 100%;
overflow: hidden;
cursor: pointer;
transition:
background-color var(--wa-transition-normal),
background var(--wa-transition-normal),
border var(--wa-transition-normal),
box-shadow var(--wa-transition-normal),
color var(--wa-transition-normal),
outline var(--wa-transition-fast);
transition-timing-function: var(--wa-transition-easing);
padding: var(--wa-space-smaller) var(--wa-space);
}
/* Add ellipses to multi select options */
@@ -76,16 +66,15 @@ select {
}
label:has(select) {
position: relative;
--icon-caret: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 512 512"><path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z"/></svg>');
&::after {
content: '';
background-color: var(--wa-color-neutral-on-quiet);
mask: var(--icon-caret) 50% 50% no-repeat;
mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 512 512"><path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z"/></svg>')
center no-repeat;
width: 1rem;
height: var(--wa-form-control-height);
position: absolute;
bottom: var(--wa-form-control-border-width);
bottom: 0;
right: var(--wa-space);
}
}

View File

@@ -9,10 +9,9 @@
@import url('default/groups.css');
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap');
:where(:root),
:root,
:host,
.wa-theme-active,
.wa-light {
.wa-theme-active-light {
color-scheme: light;
color: var(--wa-color-text-normal);
@@ -80,7 +79,7 @@
--wa-color-neutral-on-normal: var(--wa-color-gray-30);
--wa-color-neutral-on-loud: black;
/**
/**
* Typography
*/
--wa-font-family-body: 'Inter', sans-serif;
@@ -99,8 +98,8 @@
--wa-form-control-border-color: var(--wa-color-neutral-border-normal);
}
.wa-dark,
:is(:host-context(.wa-dark)) {
.wa-theme-active-dark,
:is(:host-context(.wa-theme-active-dark)) {
color-scheme: dark;
color: var(--wa-color-text-normal);
@@ -183,61 +182,59 @@
/**
* Component Styles
*/
:where(:root),
:host,
.wa-theme-active {
:root {
--wa-theme-active-shadow-pop-out: inset 0 0.0625rem 0 0 rgb(255 255 255 / 0.2) /* shine */,
inset 0 0.0625rem 0.125rem 0 rgb(255 255 255 / 0.2) /* inner highlight */,
inset 0 -0.0625rem 0.0625rem 0 rgb(0 0 0 / 0.2) /* inner shadow */, var(--wa-shadow-s) /* outer shadow */;
--wa-theme-active-shadow-punch-in: inset 0 0 0 0 transparent /* shine */,
inset 0 0.125rem 0.125rem 0 rgb(0 0 0 / 0.1) /* inner highlight */,
inset 0 -0.0625rem 0.25rem 0 rgb(0 0 0 / 0.1) /* inner shadow */, 0 0 0 0 transparent /* outer shadow */;
}
:is(button, input:where([type='button'], [type='reset'], [type='submit']), wa-button, .wa-button):not(
[appearance='plain'],
.wa-plain
) {
box-shadow: var(--wa-theme-active-shadow-pop-out);
:is(button, input:where([type='button'], [type='reset'], [type='submit']), wa-button, .wa-button):not(
[appearance='plain'],
.wa-plain
) {
box-shadow: var(--wa-theme-active-shadow-pop-out);
&:not([disabled], [loading]):active {
box-shadow: var(--wa-theme-active-shadow-punch-in);
}
}
wa-card {
box-shadow: var(--wa-theme-active-shadow-pop-out);
}
input:not([type='button'], [type='reset'], [type='submit'], :checked),
select,
textarea,
:is(wa-checkbox, wa-radio, wa-switch):not(:state(checked)),
wa-input,
wa-select,
wa-textarea {
&:not([appearance='filled']):not([disabled]) {
--box-shadow: inset var(--wa-shadow-s);
}
}
input[type='radio'],
wa-radio {
--background-color-checked: var(--wa-form-control-activated-color);
--checked-icon-color: var(--wa-color-brand-on-loud);
--checked-icon-scale: 0.4;
}
input[type='range'],
wa-slider,
wa-switch {
--thumb-shadow: var(--wa-theme-active-shadow-pop-out);
}
wa-progress-bar {
box-shadow: inset var(--wa-shadow-s);
&::part(indicator) {
box-shadow: inset 0 -0.5em 1em -0.5em oklch(from var(--indicator-color) calc(l - 0.1) c h);
}
&:not([disabled], [loading]):active {
box-shadow: var(--wa-theme-active-shadow-punch-in);
}
}
wa-card {
--box-shadow: var(--wa-theme-active-shadow-pop-out);
}
input:not([type='button'], [type='reset'], [type='submit'], :checked),
select,
textarea,
:is(wa-checkbox, wa-radio, wa-switch):not(:state(checked)),
wa-input,
wa-select,
wa-textarea {
&:not([appearance='filled']):not([disabled]) {
--box-shadow: inset var(--wa-shadow-s);
}
}
input[type='radio'],
wa-radio {
--background-color-checked: var(--wa-form-control-activated-color);
--checked-icon-color: var(--wa-color-brand-on-loud);
--checked-icon-scale: 0.4;
}
input[type='range'],
wa-slider,
wa-switch {
--thumb-shadow: var(--wa-theme-active-shadow-pop-out);
}
wa-progress-bar {
box-shadow: inset var(--wa-shadow-s);
&::part(indicator) {
box-shadow: inset 0 -0.5em 1em -0.5em oklch(from var(--indicator-color) calc(l - 0.1) c h);
}
}

View File

@@ -9,10 +9,9 @@
@import url('default/groups.css');
@import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@300..700&display=swap');
:where(:root),
:root,
:host,
.wa-theme-awesome,
.wa-light {
.wa-theme-awesome-light {
color-scheme: light;
color: var(--wa-color-text-normal);
@@ -142,8 +141,8 @@
--wa-tooltip-line-height: var(--wa-line-height-normal);
}
.wa-dark,
:is(:host-context(.wa-dark)) {
.wa-theme-awesome-dark,
:is(:host-context(.wa-theme-awesome-dark)) {
color-scheme: dark;
color: var(--wa-color-text-normal);
@@ -152,7 +151,7 @@
*/
--wa-color-surface-raised: var(--wa-color-gray-10);
--wa-color-surface-default: var(--wa-color-gray-05);
--wa-color-surface-lowered: color-mix(in oklab, var(--wa-color-surface-default), black 20%);
--wa-color-surface-lowered: var(--wa-color-gray-05);
--wa-color-surface-border: var(--wa-color-gray-20);
--wa-color-text-normal: var(--wa-color-gray-95);
@@ -241,120 +240,119 @@
--wa-form-control-required-content-color: inherit;
}
:where(:root),
:host,
.wa-theme-awesome {
/* #region Custom Styles */
wa-badge {
border-radius: var(--wa-border-radius-m);
font-weight: var(--wa-font-weight-bold);
text-transform: uppercase;
}
:is(
button,
input:where([type='button'], [type='reset'], [type='submit']),
wa-button,
wa-radio-group > wa-radio-button,
.wa-button
):not([appearance='plain'], .wa-plain) {
--wa-transition-slow: 0;
--wa-transition-normal: 0;
--wa-transition-fast: 0;
--border-color: var(--text-color);
--border-color-hover: var(--border-color);
--border-color-active: var(--border-color);
box-shadow: var(--wa-shadow-offset-x-s) var(--wa-shadow-offset-y-s) var(--wa-shadow-blur-s)
var(--wa-shadow-spread-s) var(--border-color);
--background-color-active: var(--border-color);
--text-color-active: var(--background-color);
margin-bottom: var(--wa-shadow-offset-y-s);
&:is([appearance='outlined'], .wa-outlined) {
--background-color: var(--wa-color-surface-default);
}
&:not([disabled], [loading]):active,
&::part(checked) {
box-shadow: none;
transform: translateY(var(--wa-shadow-offset-y-s));
}
.wa-dark & {
--border-color: var(--wa-color-border-quiet);
}
}
wa-callout {
&:is([appearance~='outlined'], .wa-outlined) {
border-color: var(--wa-color-border-normal);
}
&:not([appearance~='accent'], .wa-accent) {
color: var(--wa-color-text-normal);
}
&:not([appearance~='accent'], .wa-accent) {
--icon-color: var(--wa-color-border-normal);
}
}
wa-card {
background-color: var(--wa-color-surface-raised);
}
wa-card::part(header) {
border-bottom-style: dotted;
}
wa-card::part(footer) {
border-top-style: dotted;
}
input[type='checkbox'],
wa-checkbox {
--checked-icon-color: var(--wa-color-surface-default);
}
wa-radio-group > wa-radio-button {
&::part(base):active,
&::part(checked) {
--background-color: var(--border-color);
--background-color-hover: var(--border-color);
--border-color: var(--wa-color-neutral-border-loud);
--text-color: var(--wa-color-surface-default);
}
}
wa-switch {
--height: 1.5em;
}
wa-tag {
font-weight: var(--wa-font-weight-bold);
}
:is(
input:where(
:not(
[type='button'],
[type='checkbox'],
[type='color'],
[type='file'],
[type='hidden'],
[type='image'],
[type='radio'],
[type='range'],
[type='reset'],
[type='submit']
)
),
select,
textarea,
wa-input,
wa-select,
wa-textarea,
.wa-text-field
):not(:focus, [appearance='filled'], .wa-filled) {
--box-shadow: inset var(--wa-shadow-s);
}
/* #endregion */
/* #region Custom Styles */
wa-badge {
border-radius: var(--wa-border-radius-m);
font-weight: var(--wa-font-weight-bold);
text-transform: uppercase;
}
:is(button, input:where([type='button'], [type='reset'], [type='submit']), wa-button, .wa-button):not(
[appearance='plain'],
.wa-plain
) {
--wa-transition-slow: 0;
--wa-transition-normal: 0;
--wa-transition-fast: 0;
--border-color: var(--text-color);
--border-color-hover: var(--border-color);
--border-color-active: var(--border-color);
box-shadow: var(--wa-shadow-offset-x-s) var(--wa-shadow-offset-y-s) var(--wa-shadow-blur-s) var(--wa-shadow-spread-s)
var(--border-color);
--background-color-active: var(--border-color);
--text-color-active: var(--background-color);
margin-bottom: var(--wa-shadow-offset-y-s);
&:is([appearance='outlined'], .wa-outlined) {
--background-color: var(--wa-color-surface-default);
}
&:not([disabled], [loading]):active {
box-shadow: none;
transform: translateY(var(--wa-shadow-offset-y-s));
}
.wa-theme-awesome-dark & {
--border-color: var(--wa-color-border-quiet);
}
}
wa-callout {
&:is([appearance~='outlined'], .wa-outlined) {
border-color: var(--wa-color-border-normal);
}
&:not([appearance~='accent'], .wa-accent) {
color: var(--wa-color-text-normal);
}
&:not([appearance~='accent'], .wa-accent) {
--icon-color: var(--wa-color-border-normal);
}
}
wa-card {
--background-color: var(--wa-color-surface-raised);
--border-style: none;
}
wa-card::part(header) {
border-bottom: var(--border-width) dotted var(--border-color);
}
wa-card::part(footer) {
border-top: var(--border-width) dotted var(--border-color);
}
input[type='checkbox'],
wa-checkbox {
--checked-icon-color: var(--wa-color-surface-default);
}
wa-radio-group > wa-radio-button {
--background-color-active: var(--border-color);
--border-color-active: var(--background-color-active);
--box-shadow: var(--wa-shadow-offset-x-s) var(--wa-shadow-offset-y-s) var(--wa-shadow-blur-s) var(--border-color);
--label-color-active: var(--wa-color-surface-default);
&:active,
&[checked] {
--background-color: var(--border-color);
--border-color: var(--wa-color-neutral-border-loud);
--box-shadow: none;
--label-color: var(--wa-color-surface-default);
transform: translate(var(--wa-shadow-offset-x-s), var(--wa-shadow-offset-y-s));
}
}
wa-switch {
--height: 1.5em;
}
wa-tag {
font-weight: var(--wa-font-weight-bold);
}
:is(
input:where(
:not(
[type='button'],
[type='checkbox'],
[type='color'],
[type='file'],
[type='hidden'],
[type='image'],
[type='radio'],
[type='range'],
[type='reset'],
[type='submit']
)
),
select,
textarea,
wa-input,
wa-select,
wa-textarea,
.wa-text-field
):not(:focus, [appearance='filled'], .wa-filled) {
--box-shadow: inset var(--wa-shadow-s);
}
/* #endregion */

View File

@@ -9,10 +9,9 @@
@import url('default/groups.css');
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans+Condensed:wght@100;200;300;400;500;600;700&family=Space+Grotesk:wght@300..700&family=Space+Mono:wght@400;700&display=swap');
:where(:root),
:root,
:host,
.wa-theme-brutalist,
.wa-light {
.wa-theme-brutalist-light {
color-scheme: light;
color: var(--wa-color-text-normal);
@@ -123,8 +122,8 @@
--wa-form-control-activated-color: var(--wa-color-neutral-fill-loud);
}
.wa-dark,
:is(:host-context(.wa-dark)) {
.wa-theme-brutalist-dark,
:is(:host-context(.wa-theme-brutalist-dark)) {
color-scheme: dark;
color: var(--wa-color-text-normal);
@@ -207,91 +206,87 @@
/**
* Component Styles
*/
:where(:root),
:host,
.wa-theme-brutalist {
blockquote,
pre {
border-inline-start: var(--wa-border-style) var(--wa-border-width-m) var(--wa-color-surface-border);
}
wa-badge {
text-transform: uppercase;
blockquote,
pre {
border-inline-start: var(--wa-border-style) var(--wa-border-width-m) var(--wa-color-surface-border);
}
wa-badge {
text-transform: uppercase;
}
wa-callout,
wa-tag {
border-inline-start-color: var(--border-color, var(--wa-color-border-loud));
border-inline-start-width: var(--wa-border-width-s);
&:not([appearance~='outlined'], .wa-outlined) {
border-block-start-width: 0;
border-block-end-width: 0;
border-inline-end-width: 0;
}
wa-callout,
wa-tag {
border-inline-start-color: var(--border-color, var(--wa-color-border-loud));
border-inline-start-width: var(--wa-border-width-s);
&:not([appearance~='outlined'], .wa-outlined) {
border-block-start-width: 0;
border-block-end-width: 0;
border-inline-end-width: 0;
}
&:not([appearance~='accent'], .wa-accent) {
--icon-color: var(--wa-color-fill-loud);
--text-color: var(--wa-color-text-normal);
}
}
wa-callout {
--spacing: var(--wa-space-s) var(--wa-space-m);
&::part(icon) {
--spacing: var(--wa-space-m);
}
}
wa-carousel {
--pagination-color: var(--wa-color-neutral-fill-normal);
}
wa-carousel::part(scroll-container) {
padding: var(--wa-shadow-offset-y-s) var(--wa-shadow-offset-x-s); /* make room for the box-shadow */
}
wa-carousel::part(pagination-item),
wa-image-comparer::part(handle),
wa-progress-bar::part(base),
wa-slider::part(base),
input[type='range'],
wa-switch::part(control),
wa-switch::part(thumb) {
border-radius: var(--wa-border-radius-square);
}
wa-carousel-item {
border: var(--wa-panel-border-width) var(--wa-panel-border-style) var(--wa-color-surface-border);
box-shadow: var(--wa-shadow-s);
}
:is(
input:where(
:not(
[type='button'],
[type='checkbox'],
[type='color'],
[type='file'],
[type='hidden'],
[type='image'],
[type='radio'],
[type='range'],
[type='reset'],
[type='submit']
)
),
select,
textarea,
wa-input,
wa-select,
wa-textarea,
.wa-text-field
) {
--border-width: 0 0 var(--wa-form-control-border-width) var(--wa-form-control-border-width);
}
wa-rating {
--symbol-color-active: var(--wa-color-neutral-fill-loud);
&:not([appearance~='accent'], .wa-accent) {
--icon-color: var(--wa-color-fill-loud);
--text-color: var(--wa-color-text-normal);
}
}
wa-callout {
--spacing: var(--wa-space-s) var(--wa-space-m);
&::part(icon) {
--spacing: var(--wa-space-m);
}
}
wa-carousel {
--pagination-color: var(--wa-color-neutral-fill-normal);
}
wa-carousel::part(scroll-container) {
padding: var(--wa-shadow-offset-y-s) var(--wa-shadow-offset-x-s); /* make room for the box-shadow */
}
wa-carousel::part(pagination-item),
wa-image-comparer::part(handle),
wa-progress-bar::part(base),
wa-slider::part(base),
input[type='range'],
wa-switch::part(control),
wa-switch::part(thumb) {
border-radius: var(--wa-border-radius-square);
}
wa-carousel-item {
border: var(--wa-panel-border-width) var(--wa-panel-border-style) var(--wa-color-surface-border);
box-shadow: var(--wa-shadow-s);
}
:is(
input:where(
:not(
[type='button'],
[type='checkbox'],
[type='color'],
[type='file'],
[type='hidden'],
[type='image'],
[type='radio'],
[type='range'],
[type='reset'],
[type='submit']
)
),
select,
textarea,
wa-input,
wa-select,
wa-textarea,
.wa-text-field
) {
--border-width: 0 0 var(--wa-form-control-border-width) var(--wa-form-control-border-width);
}
wa-rating {
--symbol-color-active: var(--wa-color-neutral-fill-loud);
}

View File

@@ -8,10 +8,9 @@
@import url('default/transitions.css');
@import url('default/groups.css');
:where(:root),
:root,
:host,
.wa-theme-classic,
.wa-light {
.wa-theme-classic-light {
color-scheme: light;
/**
@@ -117,8 +116,8 @@
--wa-tooltip-content-color: var(--wa-color-surface-default);
}
.wa-dark,
:is(:host-context(.wa-dark)) {
.wa-theme-classic-dark,
:is(:host-context(.wa-theme-classic-dark)) {
color-scheme: dark;
color: var(--wa-color-text-normal);
@@ -127,7 +126,7 @@
*/
--wa-color-surface-raised: var(--wa-color-gray-10);
--wa-color-surface-default: var(--wa-color-gray-05);
--wa-color-surface-lowered: color-mix(in oklab, var(--wa-color-surface-default), black 20%);
--wa-color-surface-lowered: var(--wa-color-gray-05);
--wa-color-surface-border: var(--wa-color-gray-20);
--wa-color-text-normal: var(--wa-color-gray-80);
@@ -205,136 +204,132 @@
/**
* Component Styles
*/
:where(:root),
:host,
.wa-theme-classic {
wa-avatar {
--background-color: var(--wa-color-neutral-fill-loud);
--text-color: var(--wa-color-neutral-on-loud);
}
wa-avatar {
--background-color: var(--wa-color-neutral-fill-loud);
--text-color: var(--wa-color-neutral-on-loud);
}
button,
input:where([type='button'], [type='reset'], [type='submit']),
wa-button,
.wa-button,
wa-radio-button {
font-size: var(--wa-size-smaller);
}
button,
input:where([type='button'], [type='reset'], [type='submit']),
wa-button,
.wa-button,
wa-radio-button {
font-size: var(--wa-size-smaller);
}
wa-radio-button {
--background-color-active: color-mix(in oklab, var(--background-color-hover), var(--wa-color-mix-active));
--background-color-hover: var(--wa-form-control-activated-color);
--border-color: var(--wa-form-control-border-color);
--border-color-active: var(--background-color-active);
--border-color-hover: var(--background-color-hover);
--text-color-active: var(--text-color-hover);
--text-color-hover: var(--wa-color-brand-on-loud);
--indicator-color: var(--wa-background-color);
wa-radio-button {
--background-color-active: color-mix(in oklab, var(--background-color-hover), var(--wa-color-mix-active));
--background-color-hover: var(--wa-form-control-activated-color);
--border-color: var(--wa-form-control-border-color);
--border-color-active: var(--background-color-active);
--border-color-hover: var(--background-color-hover);
--text-color-active: var(--text-color-hover);
--text-color-hover: var(--wa-color-brand-on-loud);
--indicator-color: var(--wa-background-color);
&[checked] {
--background-color: var(--wa-form-control-activated-color);
--border-color: var(--background-color);
--text-color: var(--wa-color-brand-on-loud);
}
}
wa-breadcrumb {
font-size: var(--wa-font-size-s);
}
wa-callout {
--spacing: var(--wa-space-l);
font-size: var(--wa-size-smaller);
&:is([appearance~='outlined'], .wa-outlined) {
border-width: var(--wa-border-width-l) var(--wa-border-width-s) var(--wa-border-width-s) var(--wa-border-width-s);
border-color: var(--border-color, var(--wa-color-border-loud)) var(--wa-color-surface-border)
var(--wa-color-surface-border) var(--wa-color-surface-border);
&:not([appearance~='accent'], .wa-accent) {
--border-color: var(--wa-color-fill-loud);
}
}
&:not([appearance~='accent'], .wa-accent) {
--icon-color: var(--wa-color-fill-loud);
--text-color: var(--wa-color-text-normal);
}
}
wa-card {
background-color: var(--wa-color-surface-raised);
}
wa-carousel {
--box-shadow: var(--wa-shadow-s);
--pagination-color-active: var(--wa-color-neutral-fill-loud);
}
wa-dialog,
wa-drawer {
--spacing: var(--wa-space-l);
}
:is(
input:where(
:not(
[type='button'],
[type='checkbox'],
[type='color'],
[type='file'],
[type='hidden'],
[type='image'],
[type='radio'],
[type='range'],
[type='reset'],
[type='submit']
)
),
select,
textarea,
wa-input,
wa-select,
wa-textarea,
.wa-text-field
):not([appearance='filled'], .wa-filled) {
--wa-focus-ring: var(--wa-focus-ring-style) var(--wa-focus-ring-width)
color-mix(in oklab, var(--wa-color-focus), transparent 50%);
--wa-focus-ring-offset: 0;
}
input[type='radio'],
wa-radio {
--background-color-checked: var(--border-color-checked);
--checked-icon-color: var(--wa-color-surface-default);
--checked-icon-scale: 0.4;
}
input[type='range'],
wa-slider {
--thumb-gap: 0;
}
wa-switch {
--background-color: var(--wa-color-gray-50);
&[checked] {
--background-color: var(--wa-form-control-activated-color);
--border-color: var(--background-color);
--height: calc(1em * var(--wa-form-control-value-line-height) - var(--border-width) * 2);
--thumb-color: var(--wa-color-surface-default);
--thumb-size: calc(var(--height) + 4px);
--width: calc(var(--height) * 2);
&::part(thumb) {
border: var(--wa-border-width-s) var(--wa-border-style) var(--background-color);
}
&[checked]::part(thumb) {
border-color: var(--background-color-checked);
}
}
wa-progress-bar {
--height: 1rem;
}
wa-tab {
font-size: var(--wa-font-size-s);
--text-color: var(--wa-color-brand-on-loud);
}
}
wa-breadcrumb {
font-size: var(--wa-font-size-s);
}
wa-callout {
--spacing: var(--wa-space-l);
font-size: var(--wa-size-smaller);
&:is([appearance~='outlined'], .wa-outlined) {
border-width: var(--wa-border-width-l) var(--wa-border-width-s) var(--wa-border-width-s) var(--wa-border-width-s);
border-color: var(--border-color, var(--wa-color-border-loud)) var(--wa-color-surface-border)
var(--wa-color-surface-border) var(--wa-color-surface-border);
&:not([appearance~='accent'], .wa-accent) {
--border-color: var(--wa-color-fill-loud);
}
}
&:not([appearance~='accent'], .wa-accent) {
--icon-color: var(--wa-color-fill-loud);
--text-color: var(--wa-color-text-normal);
}
}
wa-card {
--background-color: var(--wa-color-surface-raised);
}
wa-carousel {
--box-shadow: var(--wa-shadow-s);
--pagination-color-active: var(--wa-color-neutral-fill-loud);
}
wa-dialog,
wa-drawer {
--spacing: var(--wa-space-l);
}
:is(
input:where(
:not(
[type='button'],
[type='checkbox'],
[type='color'],
[type='file'],
[type='hidden'],
[type='image'],
[type='radio'],
[type='range'],
[type='reset'],
[type='submit']
)
),
select,
textarea,
wa-input,
wa-select,
wa-textarea,
.wa-text-field
):not([appearance='filled'], .wa-filled) {
--wa-focus-ring: var(--wa-focus-ring-style) var(--wa-focus-ring-width)
color-mix(in oklab, var(--wa-color-focus), transparent 50%);
--wa-focus-ring-offset: 0;
}
input[type='radio'],
wa-radio {
--background-color-checked: var(--border-color-checked);
--checked-icon-color: var(--wa-color-surface-default);
--checked-icon-scale: 0.4;
}
input[type='range'],
wa-slider {
--thumb-gap: 0;
}
wa-switch {
--background-color: var(--wa-color-gray-50);
--border-color: var(--background-color);
--height: calc(1em * var(--wa-form-control-value-line-height) - var(--border-width) * 2);
--thumb-color: var(--wa-color-surface-default);
--thumb-size: calc(var(--height) + 4px);
--width: calc(var(--height) * 2);
&::part(thumb) {
border: var(--wa-border-width-s) var(--wa-border-style) var(--background-color);
}
&[checked]::part(thumb) {
border-color: var(--background-color-checked);
}
}
wa-progress-bar {
--height: 1rem;
}
wa-tab {
font-size: var(--wa-font-size-s);
}

View File

@@ -8,16 +8,15 @@
@import url('default/transitions.css');
@import url('default/groups.css');
:where(:root),
:root,
:host,
.wa-theme-default,
.wa-light {
.wa-theme-default-light {
color-scheme: light;
color: var(--wa-color-text-normal);
}
.wa-dark,
:is(:host-context(.wa-dark)) {
.wa-theme-default-dark,
:is(:host-context(.wa-theme-migration-dark)) {
color-scheme: dark;
color: var(--wa-color-text-normal);
}

View File

@@ -1,10 +1,8 @@
/**
* Foundational Colors and Semantic Colors
*/
:where(:root),
:host,
.wa-theme-default,
.wa-light {
:where(:root, :host),
.wa-theme-default-light {
/**
* Foundational Colors
*/
@@ -104,14 +102,14 @@
}
/** need to wrap :host-context() in an :is() selector for unsupported browsers */
.wa-dark,
:is(:host-context(.wa-dark)) {
.wa-theme-default-dark,
:is(:host-context(.wa-theme-default-dark)) {
/**
* Foundational Colors
*/
--wa-color-surface-raised: var(--wa-color-gray-10);
--wa-color-surface-default: var(--wa-color-gray-05);
--wa-color-surface-lowered: color-mix(in oklab, var(--wa-color-surface-default), black 20%);
--wa-color-surface-lowered: color-mix(in oklab, var(--wa-color-surface-default), black 10%);
--wa-color-surface-border: var(--wa-color-gray-20);
--wa-color-text-normal: var(--wa-color-gray-95);

View File

@@ -6,8 +6,7 @@
* A difference of 50 between lightness values ensures a minimum 4.5:1 contrast ratio.
* A difference of 60 between lightness values ensures a minimum 7:1 contrast ratio.
*/
:where(:root),
:host {
:where(:root, :host) {
--wa-color-red-95: #ffefef;
--wa-color-red-90: #ffdddc;
--wa-color-red-80: #ffb7b6;

View File

@@ -1,10 +1,8 @@
/**
* Component Groups
*/
:where(:root),
:host,
.wa-theme-default,
.wa-light {
:where(:root, :host),
.wa-theme-default-light {
/* Form controls */
--wa-form-control-background-color: var(--wa-color-surface-default);
@@ -47,8 +45,8 @@
}
/** need to wrap :host-context() in an :is() selector for unsupported browsers */
.wa-dark,
:is(:host-context(.wa-dark)) {
.wa-theme-default-dark,
:is(:host-context(.wa-theme-default-dark)) {
/* Form controls */
--wa-form-control-background-color: var(--wa-color-surface-default);

View File

@@ -1,8 +1,7 @@
/**
* Borders and outlines
*/
:where(:root),
:host {
:where(:root, :host) {
--wa-border-style: solid;
/* A multiplier is provided to uniformly increase or decrease all border widths. */

View File

@@ -1,8 +1,7 @@
/**
* Rounding
*/
:where(:root),
:host {
:where(:root, :host) {
/* A multiplier is provided to uniformly increase or decrease all border radii. */
--wa-border-radius-scale: 1;
--wa-border-radius-s: calc(var(--wa-border-radius-scale) * 0.1875rem);

View File

@@ -3,8 +3,7 @@
* Shadow properties are highly modular to make it easy to create custom shadow effects or transform elements based on specific shadow qualities.
* A multiplier is provided for each shadow quality to uniformly scale all related values.
*/
:where(:root),
:host {
:where(:root, :host) {
--wa-shadow-offset-x-scale: 0;
--wa-shadow-offset-x-s: calc(var(--wa-shadow-offset-x-scale) * 0.125rem);
--wa-shadow-offset-x-m: calc(var(--wa-shadow-offset-x-scale) * 0.25rem);

View File

@@ -1,8 +1,7 @@
/**
* Spacing
*/
:where(:root),
:host {
:where(:root, :host) {
/* A multiplier is provided to uniformly increase or decrease all spacing. */
--wa-space-scale: 1;
--wa-space-3xs: calc(var(--wa-space-scale) * 0.125rem); /* 2px */

View File

@@ -1,8 +1,7 @@
/**
* Transitions
*/
:where(:root),
:host {
:where(:root, :host) {
--wa-transition-easing: ease;
--wa-transition-slow: 300ms;
--wa-transition-normal: 150ms;

View File

@@ -1,8 +1,7 @@
/**
* Typography
*/
:where(:root),
:host {
:where(:root, :host) {
--wa-font-family-body: ui-sans-serif, system-ui, sans-serif;
--wa-font-family-heading: var(--wa-font-family-body);
--wa-font-family-code: ui-monospace, monospace;

View File

@@ -8,10 +8,9 @@
@import url('default/transitions.css');
@import url('default/groups.css');
:where(:root),
:root,
:host,
.wa-theme-glassy,
.wa-light {
.wa-theme-glassy-light {
color-scheme: light;
color: var(--wa-color-text-normal);
@@ -34,8 +33,8 @@
--wa-shadow-blur-scale: 3;
}
.wa-dark,
:is(:host-context(.wa-dark)) {
.wa-theme-glassy-dark,
:is(:host-context(.wa-theme-glassy-dark)) {
color-scheme: dark;
color: var(--wa-color-text-normal);
@@ -118,87 +117,83 @@
/**
* Component Styles
*/
:where(:root),
:host,
.wa-theme-glassy {
wa-button:not([appearance='plain']) {
box-shadow:
inset 0 0.0625rem 0 0 rgb(255 255 255 / 0.2) /* shine */,
inset 0 0.125rem 0 0 rgb(255 255 255 / 0.1) /* top highlight */,
inset 0 1.25em 0 0 rgb(255 255 255 / 0.1) /* upper tint */,
inset 0 -1.125em 0 0 rgb(0 0 0 / 0.04) /* lower shade */,
inset 0 -0.0625rem 0 0 rgb(0 0 0 / 0.2) /* bottom highlight */,
var(--wa-shadow-s) /* outer shadow */;
wa-button:not([appearance='plain']) {
box-shadow:
inset 0 0.0625rem 0 0 rgb(255 255 255 / 0.2) /* shine */,
inset 0 0.125rem 0 0 rgb(255 255 255 / 0.1) /* top highlight */,
inset 0 1.25em 0 0 rgb(255 255 255 / 0.1) /* upper tint */,
inset 0 -1.125em 0 0 rgb(0 0 0 / 0.04) /* lower shade */,
inset 0 -0.0625rem 0 0 rgb(0 0 0 / 0.2) /* bottom highlight */,
var(--wa-shadow-s) /* outer shadow */;
margin-bottom: var(--wa-shadow-offset-y-s);
transition: transform var(--wa-transition-fast);
margin-bottom: var(--wa-shadow-offset-y-s);
transition: transform var(--wa-transition-fast);
&:not([disabled]) {
&:hover {
box-shadow:
inset 0 0.0625rem 0 0 rgb(255 255 255 / 0.2) /* shine */,
inset 0 0.125rem 0 0 rgb(255 255 255 / 0.1) /* top highlight */,
inset 0 1.25em 0 0 rgb(255 255 255 / 0.1) /* upper tint */,
inset 0 -1.125em 0 0 rgb(0 0 0 / 0.04) /* lower shade */,
inset 0 -0.0625rem 0 0 rgb(0 0 0 / 0.1) /* bottom highlight */,
var(--wa-shadow-m) /* outer shadow */;
}
&:active {
box-shadow:
inset 0 -0.0625rem 0 0 rgb(255 255 255 / 0.1) /* shine */,
inset 0 0.125rem 0 0 rgb(0 0 0 / 0.1) /* top highlight */,
inset 0 1.25em 0 0 rgb(255 255 255 / 0.08) /* upper tint */,
inset 0 -1.125em 0 0 rgb(0 0 0 / 0.04) /* lower shade */,
inset 0 -0.125rem 0 0 rgb(255 255 255 / 0.04) /* bottom highlight */,
0 0 0 0 transparent /* outer shadow */;
transform: translateY(var(--wa-shadow-offset-y-s));
}
}
}
wa-checkbox,
wa-input:not(:focus),
wa-radio,
wa-select {
--box-shadow: inset var(--wa-shadow-s), inset 0 1.25em 0 0 rgb(0 0 0 / 0.02) /* upper tint */,
inset 0 -1.125em 0 0 rgb(255 255 255 / 0.05) /* lower shade */;
}
wa-checkbox:state(checked),
wa-radio:state(checked) {
--box-shadow: inset 0 0.0625rem 0 0 rgb(255 255 255 / 0.2) /* shine */,
inset 0 0.125rem 0 0 rgb(255 255 255 / 0.05) /* top highlight */,
inset 0 -0.0625rem 0 0 rgb(0 0 0 / 0.2) /* bottom highlight */, var(--wa-shadow-s) /* outer shadow */;
}
wa-textarea:not(:focus) {
&:not([appearance='filled']):not([disabled]) {
--box-shadow: var(--wa-shadow-s);
}
}
wa-switch {
--box-shadow: inset var(--wa-shadow-s);
--thumb-shadow: inset 0 0.0625rem 0 0 rgb(255 255 255 / 0.2) /* shine */,
inset 0 0.125rem 0 0 rgb(255 255 255 / 0.05) /* top highlight */,
inset 0 calc(var(--height) * 0.25) 0 0 rgb(255 255 255 / 0.04) /* upper tint */,
inset 0 calc(var(--height) * -0.25) 0 0 rgb(0 0 0 / 0.04) /* lower shade */,
inset 0 -0.0625rem 0 0 rgb(0 0 0 / 0.2) /* bottom highlight */, var(--wa-shadow-s) /* outer shadow */;
}
wa-progress-bar {
box-shadow: inset var(--wa-shadow-s);
&::part(indicator) {
&:not([disabled]) {
&:hover {
box-shadow:
inset 0 0.0625rem 0 0 rgb(255 255 255 / 0.2) /* shine */,
inset 0 0.125rem 0 0 rgb(255 255 255 / 0.1) /* top highlight */,
inset 0 0.625rem 0 0 rgb(255 255 255 / 0.1) /* upper tint */,
inset 0 -0.5rem 0 0 rgb(0 0 0 / 0.04) /* lower shade */,
inset 0 -0.0625rem 0 0 rgb(0 0 0 / 0.2) /* bottom highlight */,
var(--wa-shadow-s) /* outer shadow */;
inset 0 1.25em 0 0 rgb(255 255 255 / 0.1) /* upper tint */,
inset 0 -1.125em 0 0 rgb(0 0 0 / 0.04) /* lower shade */,
inset 0 -0.0625rem 0 0 rgb(0 0 0 / 0.1) /* bottom highlight */,
var(--wa-shadow-m) /* outer shadow */;
}
&:active {
box-shadow:
inset 0 -0.0625rem 0 0 rgb(255 255 255 / 0.1) /* shine */,
inset 0 0.125rem 0 0 rgb(0 0 0 / 0.1) /* top highlight */,
inset 0 1.25em 0 0 rgb(255 255 255 / 0.08) /* upper tint */,
inset 0 -1.125em 0 0 rgb(0 0 0 / 0.04) /* lower shade */,
inset 0 -0.125rem 0 0 rgb(255 255 255 / 0.04) /* bottom highlight */,
0 0 0 0 transparent /* outer shadow */;
transform: translateY(var(--wa-shadow-offset-y-s));
}
}
}
wa-checkbox,
wa-input:not(:focus),
wa-radio,
wa-select {
--box-shadow: inset var(--wa-shadow-s), inset 0 1.25em 0 0 rgb(0 0 0 / 0.02) /* upper tint */,
inset 0 -1.125em 0 0 rgb(255 255 255 / 0.05) /* lower shade */;
}
wa-checkbox:state(checked),
wa-radio:state(checked) {
--box-shadow: inset 0 0.0625rem 0 0 rgb(255 255 255 / 0.2) /* shine */,
inset 0 0.125rem 0 0 rgb(255 255 255 / 0.05) /* top highlight */,
inset 0 -0.0625rem 0 0 rgb(0 0 0 / 0.2) /* bottom highlight */, var(--wa-shadow-s) /* outer shadow */;
}
wa-textarea:not(:focus) {
&:not([appearance='filled']):not([disabled]) {
--box-shadow: var(--wa-shadow-s);
}
}
wa-switch {
--box-shadow: inset var(--wa-shadow-s);
--thumb-shadow: inset 0 0.0625rem 0 0 rgb(255 255 255 / 0.2) /* shine */,
inset 0 0.125rem 0 0 rgb(255 255 255 / 0.05) /* top highlight */,
inset 0 calc(var(--height) * 0.25) 0 0 rgb(255 255 255 / 0.04) /* upper tint */,
inset 0 calc(var(--height) * -0.25) 0 0 rgb(0 0 0 / 0.04) /* lower shade */,
inset 0 -0.0625rem 0 0 rgb(0 0 0 / 0.2) /* bottom highlight */, var(--wa-shadow-s) /* outer shadow */;
}
wa-progress-bar {
box-shadow: inset var(--wa-shadow-s);
&::part(indicator) {
box-shadow:
inset 0 0.0625rem 0 0 rgb(255 255 255 / 0.2) /* shine */,
inset 0 0.125rem 0 0 rgb(255 255 255 / 0.1) /* top highlight */,
inset 0 0.625rem 0 0 rgb(255 255 255 / 0.1) /* upper tint */,
inset 0 -0.5rem 0 0 rgb(0 0 0 / 0.04) /* lower shade */,
inset 0 -0.0625rem 0 0 rgb(0 0 0 / 0.2) /* bottom highlight */,
var(--wa-shadow-s) /* outer shadow */;
}
}

View File

@@ -9,10 +9,9 @@
@import url('default/groups.css');
@import url('https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400..700;1,400..700&family=Mulish:ital,wght@0,200..1000;1,200..1000&display=swap');
:where(:root),
:root,
:host,
.wa-theme-mellow,
.wa-light {
.wa-theme-mellow-light {
color-scheme: light;
color: var(--wa-color-text-normal);
@@ -120,8 +119,8 @@
--wa-form-control-border-color: var(--wa-color-neutral-border-normal);
}
.wa-dark,
:is(:host-context(.wa-dark)) {
.wa-theme-mellow-dark,
:is(:host-context(.wa-theme-mellow-dark)) {
color-scheme: dark;
color: var(--wa-color-text-normal);
@@ -130,7 +129,7 @@
*/
--wa-color-surface-raised: var(--wa-color-gray-10);
--wa-color-surface-default: var(--wa-color-gray-05);
--wa-color-surface-lowered: color-mix(in oklab, var(--wa-color-surface-default), black 20%);
--wa-color-surface-lowered: var(--wa-color-gray-05);
--wa-color-surface-border: color-mix(in oklab, var(--wa-color-gray-30), transparent);
--wa-color-text-normal: var(--wa-color-blue-90);
@@ -202,32 +201,28 @@
/**
* Component Styles
*/
:where(:root),
:host,
.wa-theme-mellow {
h1,
h2,
h3,
h4,
h5,
h6 {
letter-spacing: calc(1em * -0.02);
}
wa-callout {
border-width: var(--wa-panel-border-width) var(--wa-panel-border-width) var(--wa-panel-border-width)
calc(var(--wa-panel-border-width) * 4);
}
wa-card::part(header) {
border-bottom-style: dotted;
}
wa-card::part(footer) {
border-top-style: dotted;
}
input[type='radio'],
wa-radio {
--checked-icon-scale: 0.6;
}
h1,
h2,
h3,
h4,
h5,
h6 {
letter-spacing: calc(1em * -0.02);
}
wa-callout {
border-width: var(--wa-panel-border-width) var(--wa-panel-border-width) var(--wa-panel-border-width)
calc(var(--wa-panel-border-width) * 4);
}
wa-card::part(header) {
border-bottom: var(--border-width) dotted var(--border-color);
}
wa-card::part(footer) {
border-top: var(--border-width) dotted var(--border-color);
}
input[type='radio'],
wa-radio {
--checked-icon-scale: 0.6;
}

View File

@@ -9,10 +9,9 @@
@import url('default/groups.css');
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap');
:where(:root),
:root,
:host,
.wa-theme-tailspin,
.wa-light {
.wa-theme-migration-light {
color-scheme: light;
color: var(--wa-color-text-normal);
@@ -125,8 +124,8 @@
--wa-form-control-label-line-height: var(--wa-line-height-normal);
}
.wa-dark,
:is(:host-context(.wa-dark)) {
.wa-theme-migration-dark,
:is(:host-context(.wa-theme-migration-dark)) {
color-scheme: dark;
color: var(--wa-color-text-normal);
@@ -135,7 +134,7 @@
*/
--wa-color-surface-raised: var(--wa-color-gray-10);
--wa-color-surface-default: var(--wa-color-gray-05);
--wa-color-surface-lowered: color-mix(in oklab, var(--wa-color-surface-default), black 20%);
--wa-color-surface-lowered: color-mix(in oklab, var(--wa-color-surface-default), black 10%);
--wa-color-surface-border: rgb(255 255 255 / 0.1);
--wa-color-text-normal: white;
@@ -209,62 +208,57 @@
/**
* Component Styles
*/
:where(:root),
:host,
.wa-theme-tailspin,
:is(:host-context(.wa-theme-tailspin)) {
h1,
h2,
h3,
h4 {
letter-spacing: calc(1em * -0.03);
}
h1,
h2,
h3,
h4 {
letter-spacing: calc(1em * -0.03);
}
wa-avatar {
--background-color: var(--wa-color-neutral-fill-quiet);
--text-color: var(--wa-color-neutral-on-quiet);
}
wa-avatar {
--background-color: var(--wa-color-neutral-fill-quiet);
--text-color: var(--wa-color-neutral-on-quiet);
}
a,
wa-badge,
wa-tag {
font-weight: var(--wa-font-weight-semibold);
}
a,
wa-badge,
wa-tag {
font-weight: var(--wa-font-weight-semibold);
}
:is(button, input:where([type='button'], [type='reset'], [type='submit']), wa-button, .wa-button):not(
[appearance='plain'],
.wa-plain
) {
box-shadow: var(--wa-shadow-s);
}
:is(button, input:where([type='button'], [type='reset'], [type='submit']), wa-button, .wa-button):not(
[appearance='plain'],
.wa-plain
) {
box-shadow: var(--wa-shadow-s);
}
wa-callout {
border-radius: var(--wa-border-radius-m);
wa-callout {
border-radius: var(--wa-border-radius-m);
&::part(icon) {
opacity: 0.6;
}
}
input[type='radio'],
wa-radio {
--background-color-checked: var(--wa-form-control-activated-color);
--checked-icon-color: var(--wa-color-brand-on-loud);
--checked-icon-scale: 0.4;
}
wa-switch {
--background-color: var(--wa-color-neutral-fill-normal);
--border-color: transparent;
--height: calc(var(--thumb-size) * (18 / 14));
--thumb-color: white;
--thumb-color-checked: var(--thumb-color);
--thumb-size: 1.25em;
--thumb-shadow: var(--wa-shadow-s);
--width: calc(var(--thumb-size) * (32 / 14));
}
wa-tab {
color: var(--wa-color-text-quiet);
&::part(icon) {
opacity: 0.6;
}
}
input[type='radio'],
wa-radio {
--background-color-checked: var(--wa-form-control-activated-color);
--checked-icon-color: var(--wa-color-brand-on-loud);
--checked-icon-scale: 0.4;
}
wa-switch {
--background-color: var(--wa-color-neutral-fill-normal);
--border-color: transparent;
--height: calc(var(--thumb-size) * (18 / 14));
--thumb-color: white;
--thumb-color-checked: var(--thumb-color);
--thumb-size: 1.25em;
--thumb-shadow: var(--wa-shadow-s);
--width: calc(var(--thumb-size) * (32 / 14));
}
wa-tab {
color: var(--wa-color-text-quiet);
}

View File

@@ -8,10 +8,9 @@
@import url('default/groups.css');
@import url('https://fonts.googleapis.com/css2?family=Azeret+Mono:ital@0;1&family=Fredoka:wght@300..700&family=Nunito:ital,wght@0,200..1000;1,200..1000&display=swap');
:where(:root),
:root,
:host,
.wa-theme-playful,
.wa-light {
.wa-theme-playful-light {
color-scheme: light;
color: var(--wa-color-text-normal);
@@ -204,8 +203,8 @@
--wa-form-control-border-color: var(--wa-color-neutral-border-normal);
}
.wa-dark,
:is(:host-context(.wa-dark)) {
.wa-theme-playful-dark,
:is(:host-context(.wa-theme-playful-dark)) {
color-scheme: dark;
color: var(--wa-color-text-normal);
@@ -288,97 +287,93 @@
/**
* Component Styles
*/
:where(:root),
:host,
.wa-theme-playful {
wa-button:not([disabled]) {
transition-property: all;
wa-button:not([disabled]) {
transition-property: all;
&:hover {
transform: scale(1.02, 1.02);
}
&:active {
transform: scale(0.98, 0.98);
}
}
wa-button:is([appearance~='accent'], [appearance~='filled']) {
--button-gradient-top: oklch(from var(--background-color) calc(l - 0.1) c h);
--button-gradient-middle: var(--background-color);
--button-gradient-bottom: oklch(from var(--background-color) calc(l + 0.1) c h);
--button-shadow-outer: oklch(from var(--background-color) calc(l + 0.1) c h);
--button-shadow-inner-a: oklch(from var(--background-color) calc(l - 0.2) c h);
--button-shadow-inner-b: oklch(from var(--background-color) calc(l + 0.3) c h);
--button-text-shadow: oklch(from var(--background-color) calc(l - 0.1) c h);
--border-color: var(--button-gradient-middle);
--border-width: 1px;
--border-color-hover: var(--button-gradient-middle);
--border-color-active: var(--button-gradient-middle);
&::part(base) {
background: linear-gradient(
180deg,
var(--button-gradient-top) 0%,
var(--button-gradient-middle) 51.88%,
var(--button-gradient-bottom) 100%
);
box-shadow:
0px 6px 16px var(--button-shadow-outer),
inset 0 -2px 8px var(--button-shadow-inner-a),
inset 0 2px 8px var(--button-shadow-inner-b);
}
&:not([disabled])::part(base):hover {
background: linear-gradient(
180deg,
var(--button-gradient-bottom) 0%,
var(--button-gradient-middle) 51.88%,
var(--button-gradient-top) 100%
);
}
&:not([disabled])::part(base):active {
background: linear-gradient(
180deg,
color-mix(in oklab, var(--button-gradient-top), var(--wa-color-mix-active)) 0%,
color-mix(in oklab, var(--button-gradient-middle), var(--wa-color-mix-active)) 51.88%,
color-mix(in oklab, var(--button-gradient-bottom), var(--wa-color-mix-active)) 100%
);
box-shadow:
inset 0 -2px 8px var(--button-shadow-inner-a),
inset 0 2px 8px var(--button-shadow-inner-b);
}
&:hover {
transform: scale(1.02, 1.02);
}
wa-button::part(label) {
font-weight: var(--wa-font-weight-bold);
text-shadow: 0 2px 2px var(--button-text-shadow);
}
wa-callout {
border-style: dashed;
}
wa-checkbox::part(check-icon) {
filter: drop-shadow(var(--wa-shadow-offset-x-s) var(--wa-shadow-offset-y-s) 0.125em var(--wa-color-shadow));
}
wa-rating {
--symbol-color: color-mix(in oklab, var(--symbol-color-active), transparent);
}
wa-switch {
--thumb-size: 0.8em;
--height: 1.5em;
--width: calc(var(--thumb-size) * 3);
}
wa-switch[checked]::part(thumb) {
box-shadow: var(--wa-shadow-s);
}
wa-tag {
border-style: dashed;
border-color: var(--wa-color-border-quiet);
&:active {
transform: scale(0.98, 0.98);
}
}
wa-button:is([appearance~='accent'], [appearance~='filled']) {
--button-gradient-top: oklch(from var(--background-color) calc(l - 0.1) c h);
--button-gradient-middle: var(--background-color);
--button-gradient-bottom: oklch(from var(--background-color) calc(l + 0.1) c h);
--button-shadow-outer: oklch(from var(--background-color) calc(l + 0.1) c h);
--button-shadow-inner-a: oklch(from var(--background-color) calc(l - 0.2) c h);
--button-shadow-inner-b: oklch(from var(--background-color) calc(l + 0.3) c h);
--button-text-shadow: oklch(from var(--background-color) calc(l - 0.1) c h);
--border-color: var(--button-gradient-middle);
--border-width: 1px;
--border-color-hover: var(--button-gradient-middle);
--border-color-active: var(--button-gradient-middle);
&::part(base) {
background: linear-gradient(
180deg,
var(--button-gradient-top) 0%,
var(--button-gradient-middle) 51.88%,
var(--button-gradient-bottom) 100%
);
box-shadow:
0px 6px 16px var(--button-shadow-outer),
inset 0 -2px 8px var(--button-shadow-inner-a),
inset 0 2px 8px var(--button-shadow-inner-b);
}
&:not([disabled])::part(base):hover {
background: linear-gradient(
180deg,
var(--button-gradient-bottom) 0%,
var(--button-gradient-middle) 51.88%,
var(--button-gradient-top) 100%
);
}
&:not([disabled])::part(base):active {
background: linear-gradient(
180deg,
color-mix(in oklab, var(--button-gradient-top), var(--wa-color-mix-active)) 0%,
color-mix(in oklab, var(--button-gradient-middle), var(--wa-color-mix-active)) 51.88%,
color-mix(in oklab, var(--button-gradient-bottom), var(--wa-color-mix-active)) 100%
);
box-shadow:
inset 0 -2px 8px var(--button-shadow-inner-a),
inset 0 2px 8px var(--button-shadow-inner-b);
}
}
wa-button::part(label) {
font-weight: var(--wa-font-weight-bold);
text-shadow: 0 2px 2px var(--button-text-shadow);
}
wa-callout {
border-style: dashed;
}
wa-checkbox::part(check-icon) {
filter: drop-shadow(var(--wa-shadow-offset-x-s) var(--wa-shadow-offset-y-s) 0.125em var(--wa-color-shadow));
}
wa-rating {
--symbol-color: color-mix(in oklab, var(--symbol-color-active), transparent);
}
wa-switch {
--thumb-size: 0.8em;
--height: 1.5em;
--width: calc(var(--thumb-size) * 3);
}
wa-switch[checked]::part(thumb) {
box-shadow: var(--wa-shadow-s);
}
wa-tag {
border-style: dashed;
border-color: var(--wa-color-border-quiet);
}

View File

@@ -10,10 +10,9 @@
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&display=swap');
:where(:root),
:root,
:host,
.wa-theme-premium,
.wa-light {
.wa-theme-premium-light {
color-scheme: light;
color: var(--wa-color-text-normal);
@@ -105,8 +104,8 @@
--wa-form-control-border-color: var(--wa-color-neutral-border-normal);
}
.wa-dark,
:is(:host-context(.wa-dark)) {
.wa-theme-premium-dark,
:is(:host-context(.wa-theme-premium-dark)) {
color-scheme: dark;
color: var(--wa-color-text-normal);
@@ -189,91 +188,89 @@
/**
* Component Styles
*/
.wa-theme-premium {
wa-rating {
--symbol-size: var(--wa-font-size-l);
--symbol-color-active: var(--wa-color-text-quiet);
}
wa-rating {
--symbol-size: var(--wa-font-size-l);
--symbol-color-active: var(--wa-color-text-quiet);
}
wa-switch {
--background: transparent;
--border-color: var(--wa-color-neutral-border-normal);
--thumb-color: var(--border-color);
--thumb-color-checked: var(--wa-color-brand-fill-quiet);
--thumb-size: 1em;
--height: 1.5em;
--width: calc(var(--thumb-size) * 2.5);
}
wa-switch {
--background: transparent;
--border-color: var(--wa-color-neutral-border-normal);
--thumb-color: var(--border-color);
--thumb-color-checked: var(--wa-color-brand-fill-quiet);
--thumb-size: 1em;
--height: 1.5em;
--width: calc(var(--thumb-size) * 2.5);
}
wa-button {
--box-shadow: inset 0 0.03125rem 0 0 rgb(255 255 255 / 0.5), inset 0 0.125rem 0 0 rgb(255 255 255 / 0.1),
inset 0 -0.0625rem 0 0 rgb(0 0 0 / 0.2), var(--wa-shadow-s);
}
wa-button {
--box-shadow: inset 0 0.03125rem 0 0 rgb(255 255 255 / 0.5), inset 0 0.125rem 0 0 rgb(255 255 255 / 0.1),
inset 0 -0.0625rem 0 0 rgb(0 0 0 / 0.2), var(--wa-shadow-s);
}
wa-button[appearance='outlined'] {
--box-shadow: none;
}
wa-button[appearance='outlined'] {
--box-shadow: none;
}
wa-card {
border-radius: var(--wa-border-radius-l);
}
wa-card {
--border-radius: var(--wa-border-radius-l);
}
wa-alert {
font-size: var(--wa-font-size-s);
--border-color: var(--background);
}
wa-alert {
font-size: var(--wa-font-size-s);
--border-color: var(--background);
}
wa-carousel {
--pagination-color-active: var(--wa-color-brand-fill-loud);
--pagination-color: var(--wa-color-neutral-fill-normal);
}
wa-carousel {
--pagination-color-active: var(--wa-color-brand-fill-loud);
--pagination-color: var(--wa-color-neutral-fill-normal);
}
wa-badge,
wa-button::part(label),
wa-tag {
text-transform: uppercase;
}
wa-badge,
wa-button::part(label),
wa-tag {
text-transform: uppercase;
}
wa-badge,
wa-tag {
border-width: 0;
}
wa-badge,
wa-tag {
border-width: 0;
}
&:not(.wa-dark) wa-alert {
&[variant='brand'] {
--background: var(--wa-color-primary-95);
}
&[variant='success'] {
--background: var(--wa-color-green-95);
}
&[variant='warning'] {
--background: var(--wa-color-yellow-95);
}
&[variant='danger'] {
--background: var(--wa-color-red-95);
}
&:not(.wa-theme-premium-dark) wa-alert {
&[variant='brand'] {
--background: var(--wa-color-primary-95);
}
wa-badge {
&[variant='brand'] {
--background: var(--wa-color-primary-80);
--text-color: var(--wa-color-primary-20);
}
&[variant='success'] {
--background: var(--wa-color-green-80);
--text-color: var(--wa-color-green-20);
}
&[variant='warning'] {
--background: var(--wa-color-yellow-80);
--text-color: var(--wa-color-yellow-20);
}
&[variant='danger'] {
--background: var(--wa-color-red-80);
--text-color: var(--wa-color-red-20);
}
&[variant='neutral'] {
--background: white;
--text-color: var(--wa-color-base-30);
}
&[variant='success'] {
--background: var(--wa-color-green-95);
}
&[variant='warning'] {
--background: var(--wa-color-yellow-95);
}
&[variant='danger'] {
--background: var(--wa-color-red-95);
}
}
wa-badge {
&[variant='brand'] {
--background: var(--wa-color-primary-80);
--text-color: var(--wa-color-primary-20);
}
&[variant='success'] {
--background: var(--wa-color-green-80);
--text-color: var(--wa-color-green-20);
}
&[variant='warning'] {
--background: var(--wa-color-yellow-80);
--text-color: var(--wa-color-yellow-20);
}
&[variant='danger'] {
--background: var(--wa-color-red-80);
--text-color: var(--wa-color-red-20);
}
&[variant='neutral'] {
--background: white;
--text-color: var(--wa-color-base-30);
}
}

View File

@@ -36,12 +36,6 @@
--text-color: var(--wa-color-on-normal, var(--wa-color-neutral-on-normal));
}
/* 0 specificity. Safari doesn't like :where(:host()) so we need a separate rule. */
:where(.wa-filled),
:host(:where([appearance~='filled'])) {
--border-color: transparent;
}
.wa-plain,
:host([appearance~='plain']) {
--background-color: transparent;

Some files were not shown because too many files have changed in this diff Show More