Merge branch 'next' into select-event-fix

This commit is contained in:
Cory LaViska
2025-08-25 11:08:18 -04:00
committed by GitHub
14 changed files with 114 additions and 806 deletions

2
package-lock.json generated
View File

@@ -14000,7 +14000,7 @@
},
"packages/webawesome-pro": {
"name": "@shoelace-style/webawesome-pro",
"version": "3.0.0-beta.3",
"version": "3.0.0-beta.4",
"dependencies": {
"@ctrl/tinycolor": "^4.1.0",
"@floating-ui/dom": "^1.6.13",

View File

@@ -26,5 +26,17 @@
{% endfor %}
<link rel="stylesheet" href="/dist/styles/webawesome.css" />
<script type="module">
document.addEventListener("wa-discovery-complete", loadLayout)
function loadLayout () {
if (!customElements.get("wa-layout")) {
import("{% cdnUrl 'components/page/page.js' %}")
.catch((e) => {
// known errors with dual registration. This is only a thing in the free repo.
})
}
}
</script>
{# Used by Web Awesome App to inject other assets into the head. #}
{% server "head" %}

View File

@@ -31,16 +31,19 @@
<!-- Components -->
<wa-details appearance="outlined">
<h2 slot="summary">
<a href="/docs/components/" title="Overview">
Components
<a class="wa-cluster wa-gap-xs" href="/docs/components/" title="Overview">
<wa-icon name="grid-2" aria-hidden="true"></wa-icon>
Components
</a>
</h2>
<ul>
<li>
<a href="/docs/components/page/">Page</a>
<wa-icon name="flask" aria-hidden="true"></wa-icon>
<wa-badge class="pro" appearance="accent" attention="none">PRO</wa-badge>
<span class="wa-split">
<a class="wa-cluster wa-gap-xs" href="/docs/components/page/">
Page <wa-icon name="flask" aria-hidden="true"></wa-icon>
</a>
<wa-badge class="pro" appearance="accent" attention="none">PRO</wa-badge>
</span>
</li>
<li><a href="/docs/components/animated-image/">Animated Image</a></li>
<li><a href="/docs/components/animation/">Animation</a></li>
@@ -57,12 +60,16 @@
<li><a href="/docs/components/callout/">Callout</a></li>
<li><a href="/docs/components/card/">Card</a></li>
<li>
<a href="/docs/components/carousel/">Carousel</a>
<wa-icon name="flask" aria-hidden="true"></wa-icon>
<a class="wa-cluster wa-gap-xs" href="/docs/components/carousel/">
Carousel
<wa-icon name="flask" aria-hidden="true"></wa-icon>
</a>
<ul>
<li>
<a href="/docs/components/carousel-item/">Carousel Item</a>
<wa-icon name="flask" aria-hidden="true"></wa-icon>
<a class="wa-cluster wa-gap-xs" href="/docs/components/carousel-item/">
Carousel Item
<wa-icon name="flask" aria-hidden="true"></wa-icon>
</a>
</li>
</ul>
</li>
@@ -70,8 +77,10 @@
<li><a href="/docs/components/color-picker/">Color Picker</a></li>
<li><a href="/docs/components/comparison/">Comparison</a></li>
<li>
<a href="/docs/components/copy-button/">Copy Button</a>
<wa-icon name="flask" aria-hidden="true"></wa-icon>
<a class="wa-cluster wa-gap-xs" href="/docs/components/copy-button/">
Copy Button
<wa-icon name="flask" aria-hidden="true"></wa-icon>
</a>
</li>
<li><a href="/docs/components/details/">Details</a></li>
<li><a href="/docs/components/dialog/">Dialog</a></li>
@@ -136,9 +145,9 @@
<!-- Style utilities -->
<wa-details appearance="outlined">
<h2 slot="summary">
<a href="/docs/utilities/" title="Overview">
Style Utilities
<a class="wa-cluster wa-gap-xs" href="/docs/utilities/" title="Overview">
<wa-icon name="grid-2" aria-hidden="true"></wa-icon>
Style Utilities
</a>
</h2>
<ul>
@@ -154,9 +163,9 @@
<!-- Layout -->
<wa-details appearance="outlined">
<h2 slot="summary">
<a href="/docs/layout/" title="Overview">
Layout
<a class="wa-cluster wa-gap-xs" href="/docs/layout/" title="Overview">
<wa-icon name="grid-2" aria-hidden="true"></wa-icon>
Layout
</a>
</h2>
<ul>
@@ -169,9 +178,12 @@
<li><a href="/docs/utilities/split/">Split</a></li>
<li><a href="/docs/utilities/stack/">Stack</a></li>
<li>
<a href="/docs/components/page/">Page</a>
<wa-icon name="flask" aria-hidden="true"></wa-icon>
<wa-badge class="pro" appearance="accent" attention="none">PRO</wa-badge>
<span class="wa-split">
<a class="wa-cluster wa-gap-xs" href="/docs/components/page/">
Page <wa-icon name="flask" aria-hidden="true"></wa-icon>
</a>
<wa-badge class="pro" appearance="accent" attention="none">PRO</wa-badge>
</span>
</li>
</ul>
</wa-details>
@@ -179,15 +191,17 @@
<!-- Patterns -->
<wa-details appearance="outlined">
<h2 slot="summary">
<a href="/docs/patterns/" title="Overview">
Patterns
<a class="wa-cluster wa-gap-xs" href="/docs/patterns/" title="Overview">
<wa-icon name="grid-2" aria-hidden="true"></wa-icon>
Patterns
</a>
</h2>
<ul>
<li>
<a href="/docs/patterns/app/">App</a>
<wa-badge class="pro" appearance="accent" attention="none">PRO</wa-badge>
<span class="wa-split">
<a href="/docs/patterns/app/">App</a>
<wa-badge class="pro" appearance="accent" attention="none">PRO</wa-badge>
</span>
<ul>
<li>
<a href="/docs/patterns/app/action-panel/">Action Panel</a>
@@ -230,8 +244,10 @@
</ul>
</li>
<li>
<a href="/docs/patterns/blog-news/">Blog &amp; News</a>
<wa-badge class="pro" appearance="accent" attention="none">PRO</wa-badge>
<span class="wa-split">
<a href="/docs/patterns/blog-news/">Blog &amp; News</a>
<wa-badge class="pro" appearance="accent" attention="none">PRO</wa-badge>
</span>
<ul>
<li>
<a href="/docs/patterns/blog-news/banners/">Banners</a>
@@ -275,7 +291,7 @@
<li>
<a href="/docs/patterns/blog-news/login/">Sign Up &amp; Login</a>
</li>
<li>
<li>
<a href="/docs/patterns/blog-news/numbers/">Numbers</a>
</li>
<li>
@@ -284,14 +300,16 @@
<li>
<a href="/docs/patterns/blog-news/teams/">Teams</a>
</li>
<li>
<li>
<a href="/docs/patterns/blog-news/testimonials/">Testimonials</a>
</li>
</ul>
</li>
<li>
<a href="/docs/patterns/ecommerce/">Ecommerce</a>
<wa-badge class="pro" appearance="accent" attention="none">PRO</wa-badge>
<span class="wa-split">
<a href="/docs/patterns/ecommerce/">Ecommerce</a>
<wa-badge class="pro" appearance="accent" attention="none">PRO</wa-badge>
</span>
<ul>
<li>
<a href="/docs/patterns/ecommerce/category-filter/">Category Filter</a>
@@ -329,8 +347,10 @@
</ul>
</li>
<li>
<a href="/docs/patterns/layouts/">Layouts</a>
<wa-badge class="pro" appearance="accent" attention="none">PRO</wa-badge>
<span class="wa-split">
<a href="/docs/patterns/layouts/">Layouts</a>
<wa-badge class="pro" appearance="accent" attention="none">PRO</wa-badge>
</span>
<ul>
<li>
<a href="/docs/patterns/layouts/ecommerce/">Ecommerce</a>
@@ -352,17 +372,19 @@
<li><a href="/docs/color-palettes">Color Palettes</a></li>
<li><a href="/docs/themes">Themes</a></li>
<li>
<a href="/themer" data-turbo="false">Theme Builder</a>
<wa-badge class="pro" appearance="accent" attention="none">PRO</wa-badge>
<span class="wa-split">
<a href="/themer" data-turbo="false">Theme Builder</a>
<wa-badge class="pro" appearance="accent" attention="none">PRO</wa-badge>
</span>
</li>
</ul>
<!-- Design tokens -->
<wa-details appearance="outlined">
<h2 slot="summary">
<a href="/docs/tokens/" title="Overview">
Design Tokens
<a class="wa-cluster wa-gap-xs" href="/docs/tokens/" title="Overview">
<wa-icon name="grid-2" aria-hidden="true"></wa-icon>
Design Tokens
</a>
</h2>
<ul>

View File

@@ -181,11 +181,6 @@ wa-page > header {
li wa-icon {
color: var(--wa-color-text-quiet);
vertical-align: middle;
&[name='flask'] {
margin-inline: 0.125em;
}
}
}
@@ -205,25 +200,16 @@ wa-badge.pro {
color: var(--wa-color-text-quiet);
a {
display: flex;
align-items: center;
gap: 0.4em;
color: var(--wa-color-text-normal);
text-decoration: none;
wa-icon {
margin-block-end: -0.15em;
font-size: var(--wa-font-size-s);
font-weight: var(--wa-font-weight-action);
color: var(--wa-color-gray-70);
}
&:hover {
color: var(--wa-color-brand-on-normal);
wa-icon {
color: var(--wa-color-brand-on-quiet);
}
text-decoration: underline;
}
}
}
@@ -415,6 +401,7 @@ wa-button#search-trigger {
#search-trigger kbd {
font-size: var(--wa-font-size-2xs);
line-height: var(--wa-form-control-value-line-height);
padding-inline: 0.33em;
}
/* Search list pages */

View File

@@ -29,6 +29,8 @@ Components with the <wa-badge variant="warning">Experimental</wa-badge> badge sh
- Fixed a bug in `<wa-slider>` that prevented the thumb from receiving focus when clicking/tapping [issue:1312]
- Fixed a bug in `<wa-scroller>` that caused the shadow to appear below relatively-positioned elements [issue:1326]
- Fixed a bug in `<wa-details>` that caused it to expand/collapse when clicking on interactive elements in the summary [issue:1252]
- Fixed `<wa-button>` to have `static` positioning by default and `relative` positioning only when used with `<wa-badge>` [pr:1346]
- Fixed spacing in `<wa-input>` when both clear and password toggle icons are present [issue:1325]
## 3.0.0-beta.4

View File

@@ -141,10 +141,11 @@ layout: page
display: flex;
align-items: center;
justify-content: center;
block-size: 2em;
inline-size: 2em;
background-color: var(--wa-color-neutral-fill-loud);
color: var(--wa-color-neutral-on-loud);
border-radius: 0.25rem;
aspect-ratio: 1;
padding: 0.5em;
&.brand-orange {

View File

@@ -1,6 +1,18 @@
@layer wa-component {
:host {
display: inline-block;
/* Workaround because Chrome doesn't like :host(:has()) below
* https://issues.chromium.org/issues/40062355
* Firefox doesn't like this nested rule, so both are needed */
&:has(wa-badge) {
position: relative;
}
}
/* Apply relative positioning only when needed to position wa-badge
* This avoids creating a new stacking context for every button */
:host(:has(wa-badge)) {
position: relative;
}
}

View File

@@ -9,31 +9,31 @@ export const icons: { [key: string]: { [key: string]: string } } = {
// Solid variant
//
solid: {
check: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M530.8 134.1C545.1 144.5 548.3 164.5 537.9 178.8L281.9 530.8C276.4 538.4 267.9 543.1 258.5 543.9C249.1 544.7 240 541.2 233.4 534.6L105.4 406.6C92.9 394.1 92.9 373.8 105.4 361.3C117.9 348.8 138.2 348.8 150.7 361.3L252.2 462.8L486.2 141.1C496.6 126.8 516.6 123.6 530.9 134z"/></svg>`,
'chevron-down': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M297.4 470.6C309.9 483.1 330.2 483.1 342.7 470.6L534.7 278.6C547.2 266.1 547.2 245.8 534.7 233.3C522.2 220.8 501.9 220.8 489.4 233.3L320 402.7L150.6 233.4C138.1 220.9 117.8 220.9 105.3 233.4C92.8 245.9 92.8 266.2 105.3 278.7L297.3 470.7z"/></svg>`,
'chevron-left': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M169.4 297.4C156.9 309.9 156.9 330.2 169.4 342.7L361.4 534.7C373.9 547.2 394.2 547.2 406.7 534.7C419.2 522.2 419.2 501.9 406.7 489.4L237.3 320L406.6 150.6C419.1 138.1 419.1 117.8 406.6 105.3C394.1 92.8 373.8 92.8 361.3 105.3L169.3 297.3z"/></svg>`,
'chevron-right': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M471.1 297.4C483.6 309.9 483.6 330.2 471.1 342.7L279.1 534.7C266.6 547.2 246.3 547.2 233.8 534.7C221.3 522.2 221.3 501.9 233.8 489.4L403.2 320L233.9 150.6C221.4 138.1 221.4 117.8 233.9 105.3C246.4 92.8 266.7 92.8 279.2 105.3L471.2 297.3z"/></svg>`,
circle: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M64 320C64 178.6 178.6 64 320 64C461.4 64 576 178.6 576 320C576 461.4 461.4 576 320 576C178.6 576 64 461.4 64 320z"/></svg>`,
eyedropper: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M405.6 93.2L304 194.8L294.6 185.4C282.1 172.9 261.8 172.9 249.3 185.4C236.8 197.9 236.8 218.2 249.3 230.7L409.3 390.7C421.8 403.2 442.1 403.2 454.6 390.7C467.1 378.2 467.1 357.9 454.6 345.4L445.2 336L546.8 234.4C585.8 195.4 585.8 132.2 546.8 93.3C507.8 54.4 444.6 54.3 405.7 93.3zM119.4 387.3C104.4 402.3 96 422.7 96 443.9L96 486.3L69.4 526.2C60.9 538.9 62.6 555.8 73.4 566.6C84.2 577.4 101.1 579.1 113.8 570.6L153.7 544L196.1 544C217.3 544 237.7 535.6 252.7 520.6L362.1 411.2L316.8 365.9L207.4 475.3C204.4 478.3 200.3 480 196.1 480L160 480L160 443.9C160 439.7 161.7 435.6 164.7 432.6L274.1 323.2L228.8 277.9L119.4 387.3z"/></svg>`,
'grip-vertical': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M288 104C288 81.9 270.1 64 248 64L200 64C177.9 64 160 81.9 160 104L160 152C160 174.1 177.9 192 200 192L248 192C270.1 192 288 174.1 288 152L288 104zM288 296C288 273.9 270.1 256 248 256L200 256C177.9 256 160 273.9 160 296L160 344C160 366.1 177.9 384 200 384L248 384C270.1 384 288 366.1 288 344L288 296zM160 488L160 536C160 558.1 177.9 576 200 576L248 576C270.1 576 288 558.1 288 536L288 488C288 465.9 270.1 448 248 448L200 448C177.9 448 160 465.9 160 488zM480 104C480 81.9 462.1 64 440 64L392 64C369.9 64 352 81.9 352 104L352 152C352 174.1 369.9 192 392 192L440 192C462.1 192 480 174.1 480 152L480 104zM352 296L352 344C352 366.1 369.9 384 392 384L440 384C462.1 384 480 366.1 480 344L480 296C480 273.9 462.1 256 440 256L392 256C369.9 256 352 273.9 352 296zM480 488C480 465.9 462.1 448 440 448L392 448C369.9 448 352 465.9 352 488L352 536C352 558.1 369.9 576 392 576L440 576C462.1 576 480 558.1 480 536L480 488z"/></svg>`,
check: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M434.8 70.1c14.3 10.4 17.5 30.4 7.1 44.7l-256 352c-5.5 7.6-14 12.3-23.4 13.1s-18.5-2.7-25.1-9.3l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l101.5 101.5 234-321.7c10.4-14.3 30.4-17.5 44.7-7.1z"/></svg>`,
'chevron-down': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M201.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 0L224 338.7 54.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z"/></svg>`,
'chevron-left': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l192 192c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256 246.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-192 192z"/></svg>`,
'chevron-right': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M311.1 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L243.2 256 73.9 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z"/></svg>`,
circle: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M0 256a256 256 0 1 1 512 0 256 256 0 1 1 -512 0z"/></svg>`,
eyedropper: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M341.6 29.2l-101.6 101.6-9.4-9.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-9.4-9.4 101.6-101.6c39-39 39-102.2 0-141.1s-102.2-39-141.1 0zM55.4 323.3c-15 15-23.4 35.4-23.4 56.6l0 42.4-26.6 39.9c-8.5 12.7-6.8 29.6 4 40.4s27.7 12.5 40.4 4l39.9-26.6 42.4 0c21.2 0 41.6-8.4 56.6-23.4l109.4-109.4-45.3-45.3-109.4 109.4c-3 3-7.1 4.7-11.3 4.7l-36.1 0 0-36.1c0-4.2 1.7-8.3 4.7-11.3l109.4-109.4-45.3-45.3-109.4 109.4z"/></svg>`,
'grip-vertical': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M128 40c0-22.1-17.9-40-40-40L40 0C17.9 0 0 17.9 0 40L0 88c0 22.1 17.9 40 40 40l48 0c22.1 0 40-17.9 40-40l0-48zm0 192c0-22.1-17.9-40-40-40l-48 0c-22.1 0-40 17.9-40 40l0 48c0 22.1 17.9 40 40 40l48 0c22.1 0 40-17.9 40-40l0-48zM0 424l0 48c0 22.1 17.9 40 40 40l48 0c22.1 0 40-17.9 40-40l0-48c0-22.1-17.9-40-40-40l-48 0c-22.1 0-40 17.9-40 40zM320 40c0-22.1-17.9-40-40-40L232 0c-22.1 0-40 17.9-40 40l0 48c0 22.1 17.9 40 40 40l48 0c22.1 0 40-17.9 40-40l0-48zM192 232l0 48c0 22.1 17.9 40 40 40l48 0c22.1 0 40-17.9 40-40l0-48c0-22.1-17.9-40-40-40l-48 0c-22.1 0-40 17.9-40 40zM320 424c0-22.1-17.9-40-40-40l-48 0c-22.1 0-40 17.9-40 40l0 48c0 22.1 17.9 40 40 40l48 0c22.1 0 40-17.9 40-40l0-48z"/></svg>`,
indeterminate: `<svg part="indeterminate-icon" class="icon" viewBox="0 0 16 16"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round"><g stroke="currentColor" stroke-width="2"><g transform="translate(2.285714 6.857143)"><path d="M10.2857143,1.14285714 L1.14285714,1.14285714"/></g></g></g></svg>`,
minus: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M96 320C96 302.3 110.3 288 128 288L512 288C529.7 288 544 302.3 544 320C544 337.7 529.7 352 512 352L128 352C110.3 352 96 337.7 96 320z"/></svg>`,
pause: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M176 96C149.5 96 128 117.5 128 144L128 496C128 522.5 149.5 544 176 544L240 544C266.5 544 288 522.5 288 496L288 144C288 117.5 266.5 96 240 96L176 96zM400 96C373.5 96 352 117.5 352 144L352 496C352 522.5 373.5 544 400 544L464 544C490.5 544 512 522.5 512 496L512 144C512 117.5 490.5 96 464 96L400 96z"/></svg>`,
play: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M187.2 100.9C174.8 94.1 159.8 94.4 147.6 101.6C135.4 108.8 128 121.9 128 136L128 504C128 518.1 135.5 531.2 147.6 538.4C159.7 545.6 174.8 545.9 187.2 539.1L523.2 355.1C536 348.1 544 334.6 544 320C544 305.4 536 291.9 523.2 284.9L187.2 100.9z"/></svg>`,
star: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M341.5 45.1C337.4 37.1 329.1 32 320.1 32C311.1 32 302.8 37.1 298.7 45.1L225.1 189.3L65.2 214.7C56.3 216.1 48.9 222.4 46.1 231C43.3 239.6 45.6 249 51.9 255.4L166.3 369.9L141.1 529.8C139.7 538.7 143.4 547.7 150.7 553C158 558.3 167.6 559.1 175.7 555L320.1 481.6L464.4 555C472.4 559.1 482.1 558.3 489.4 553C496.7 547.7 500.4 538.8 499 529.8L473.7 369.9L588.1 255.4C594.5 249 596.7 239.6 593.9 231C591.1 222.4 583.8 216.1 574.8 214.7L415 189.3L341.5 45.1z"/></svg>`,
user: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M320 312C386.3 312 440 258.3 440 192C440 125.7 386.3 72 320 72C253.7 72 200 125.7 200 192C200 258.3 253.7 312 320 312zM290.3 368C191.8 368 112 447.8 112 546.3C112 562.7 125.3 576 141.7 576L498.3 576C514.7 576 528 562.7 528 546.3C528 447.8 448.2 368 349.7 368L290.3 368z"/></svg>`,
xmark: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M183.1 137.4C170.6 124.9 150.3 124.9 137.8 137.4C125.3 149.9 125.3 170.2 137.8 182.7L275.2 320L137.9 457.4C125.4 469.9 125.4 490.2 137.9 502.7C150.4 515.2 170.7 515.2 183.2 502.7L320.5 365.3L457.9 502.6C470.4 515.1 490.7 515.1 503.2 502.6C515.7 490.1 515.7 469.8 503.2 457.3L365.8 320L503.1 182.6C515.6 170.1 515.6 149.8 503.1 137.3C490.6 124.8 470.3 124.8 457.8 137.3L320.5 274.7L183.1 137.4z"/></svg>`,
minus: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M0 256c0-17.7 14.3-32 32-32l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 288c-17.7 0-32-14.3-32-32z"/></svg>`,
pause: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M48 32C21.5 32 0 53.5 0 80L0 432c0 26.5 21.5 48 48 48l64 0c26.5 0 48-21.5 48-48l0-352c0-26.5-21.5-48-48-48L48 32zm224 0c-26.5 0-48 21.5-48 48l0 352c0 26.5 21.5 48 48 48l64 0c26.5 0 48-21.5 48-48l0-352c0-26.5-21.5-48-48-48l-64 0z"/></svg>`,
play: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M91.2 36.9c-12.4-6.8-27.4-6.5-39.6 .7S32 57.9 32 72l0 368c0 14.1 7.5 27.2 19.6 34.4s27.2 7.5 39.6 .7l336-184c12.8-7 20.8-20.5 20.8-35.1s-8-28.1-20.8-35.1l-336-184z"/></svg>`,
star: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M309.5-18.9c-4.1-8-12.4-13.1-21.4-13.1s-17.3 5.1-21.4 13.1L193.1 125.3 33.2 150.7c-8.9 1.4-16.3 7.7-19.1 16.3s-.5 18 5.8 24.4l114.4 114.5-25.2 159.9c-1.4 8.9 2.3 17.9 9.6 23.2s16.9 6.1 25 2L288.1 417.6 432.4 491c8 4.1 17.7 3.3 25-2s11-14.2 9.6-23.2L441.7 305.9 556.1 191.4c6.4-6.4 8.6-15.8 5.8-24.4s-10.1-14.9-19.1-16.3L383 125.3 309.5-18.9z"/></svg>`,
user: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M224 248a120 120 0 1 0 0-240 120 120 0 1 0 0 240zm-29.7 56C95.8 304 16 383.8 16 482.3 16 498.7 29.3 512 45.7 512l356.6 0c16.4 0 29.7-13.3 29.7-29.7 0-98.5-79.8-178.3-178.3-178.3l-59.4 0z"/></svg>`,
xmark: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M55.1 73.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L147.2 256 9.9 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192.5 301.3 329.9 438.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.8 256 375.1 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192.5 210.7 55.1 73.4z"/></svg>`,
},
//
// Regular variant
//
regular: {
'circle-question': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M528 320C528 205.1 434.9 112 320 112C205.1 112 112 205.1 112 320C112 434.9 205.1 528 320 528C434.9 528 528 434.9 528 320zM64 320C64 178.6 178.6 64 320 64C461.4 64 576 178.6 576 320C576 461.4 461.4 576 320 576C178.6 576 64 461.4 64 320zM320 240C302.3 240 288 254.3 288 272C288 285.3 277.3 296 264 296C250.7 296 240 285.3 240 272C240 227.8 275.8 192 320 192C364.2 192 400 227.8 400 272C400 319.2 364 339.2 344 346.5L344 350.3C344 363.6 333.3 374.3 320 374.3C306.7 374.3 296 363.6 296 350.3L296 342.2C296 321.7 310.8 307 326.1 302C332.5 299.9 339.3 296.5 344.3 291.7C348.6 287.5 352 281.7 352 272.1C352 254.4 337.7 240.1 320 240.1zM288 432C288 414.3 302.3 400 320 400C337.7 400 352 414.3 352 432C352 449.7 337.7 464 320 464C302.3 464 288 449.7 288 432z"/></svg>`,
'circle-xmark': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M320 112C434.9 112 528 205.1 528 320C528 434.9 434.9 528 320 528C205.1 528 112 434.9 112 320C112 205.1 205.1 112 320 112zM320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM231 231C221.6 240.4 221.6 255.6 231 264.9L286 319.9L231 374.9C221.6 384.3 221.6 399.5 231 408.8C240.4 418.1 255.6 418.2 264.9 408.8L319.9 353.8L374.9 408.8C384.3 418.2 399.5 418.2 408.8 408.8C418.1 399.4 418.2 384.2 408.8 374.9L353.8 319.9L408.8 264.9C418.2 255.5 418.2 240.3 408.8 231C399.4 221.7 384.2 221.6 374.9 231L319.9 286L264.9 231C255.5 221.6 240.3 221.6 231 231z"/></svg>`,
copy: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M480 400L288 400C279.2 400 272 392.8 272 384L272 128C272 119.2 279.2 112 288 112L421.5 112C425.7 112 429.8 113.7 432.8 116.7L491.3 175.2C494.3 178.2 496 182.3 496 186.5L496 384C496 392.8 488.8 400 480 400zM288 448L480 448C515.3 448 544 419.3 544 384L544 186.5C544 169.5 537.3 153.2 525.3 141.2L466.7 82.7C454.7 70.7 438.5 64 421.5 64L288 64C252.7 64 224 92.7 224 128L224 384C224 419.3 252.7 448 288 448zM160 192C124.7 192 96 220.7 96 256L96 512C96 547.3 124.7 576 160 576L352 576C387.3 576 416 547.3 416 512L416 496L368 496L368 512C368 520.8 360.8 528 352 528L160 528C151.2 528 144 520.8 144 512L144 256C144 247.2 151.2 240 160 240L176 240L176 192L160 192z"/></svg>`,
eye: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M320 144C254.8 144 201.2 173.6 160.1 211.7C121.6 247.5 95 290 81.4 320C95 350 121.6 392.5 160.1 428.3C201.2 466.4 254.8 496 320 496C385.2 496 438.8 466.4 479.9 428.3C518.4 392.5 545 350 558.6 320C545 290 518.4 247.5 479.9 211.7C438.8 173.6 385.2 144 320 144zM127.4 176.6C174.5 132.8 239.2 96 320 96C400.8 96 465.5 132.8 512.6 176.6C559.4 220.1 590.7 272 605.6 307.7C608.9 315.6 608.9 324.4 605.6 332.3C590.7 368 559.4 420 512.6 463.4C465.5 507.1 400.8 544 320 544C239.2 544 174.5 507.2 127.4 463.4C80.6 419.9 49.3 368 34.4 332.3C31.1 324.4 31.1 315.6 34.4 307.7C49.3 272 80.6 220 127.4 176.6zM320 400C364.2 400 400 364.2 400 320C400 290.4 383.9 264.5 360 250.7C358.6 310.4 310.4 358.6 250.7 360C264.5 383.9 290.4 400 320 400zM240.4 311.6C242.9 311.9 245.4 312 248 312C283.3 312 312 283.3 312 248C312 245.4 311.8 242.9 311.6 240.4C274.2 244.3 244.4 274.1 240.5 311.5zM286 196.6C296.8 193.6 308.2 192.1 319.9 192.1C328.7 192.1 337.4 193 345.7 194.7C346 194.8 346.2 194.8 346.5 194.9C404.4 207.1 447.9 258.6 447.9 320.1C447.9 390.8 390.6 448.1 319.9 448.1C258.3 448.1 206.9 404.6 194.7 346.7C192.9 338.1 191.9 329.2 191.9 320.1C191.9 309.1 193.3 298.3 195.9 288.1C196.1 287.4 196.2 286.8 196.4 286.2C208.3 242.8 242.5 208.6 285.9 196.7z"/></svg>`,
'eye-slash': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M73 39.1C63.6 29.7 48.4 29.7 39.1 39.1C29.8 48.5 29.7 63.7 39 73.1L567 601.1C576.4 610.5 591.6 610.5 600.9 601.1C610.2 591.7 610.3 576.5 600.9 567.2L504.5 470.8C507.2 468.4 509.9 466 512.5 463.6C559.3 420.1 590.6 368.2 605.5 332.5C608.8 324.6 608.8 315.8 605.5 307.9C590.6 272.2 559.3 220.2 512.5 176.8C465.4 133.1 400.7 96.2 319.9 96.2C263.1 96.2 214.3 114.4 173.9 140.4L73 39.1zM208.9 175.1C241 156.2 278.1 144 320 144C385.2 144 438.8 173.6 479.9 211.7C518.4 247.4 545 290 558.5 320C544.9 350 518.3 392.5 479.9 428.3C476.8 431.1 473.7 433.9 470.5 436.7L425.8 392C439.8 371.5 448 346.7 448 320C448 249.3 390.7 192 320 192C293.3 192 268.5 200.2 248 214.2L208.9 175.1zM390.9 357.1L282.9 249.1C294 243.3 306.6 240 320 240C364.2 240 400 275.8 400 320C400 333.4 396.7 346 390.9 357.1zM135.4 237.2L101.4 203.2C68.8 240 46.4 279 34.5 307.7C31.2 315.6 31.2 324.4 34.5 332.3C49.4 368 80.7 420 127.5 463.4C174.6 507.1 239.3 544 320.1 544C357.4 544 391.3 536.1 421.6 523.4L384.2 486C364.2 492.4 342.8 496 320 496C254.8 496 201.2 466.4 160.1 428.3C121.6 392.6 95 350 81.5 320C91.9 296.9 110.1 266.4 135.5 237.2z"/></svg>`,
star: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M320.1 32C329.1 32 337.4 37.1 341.5 45.1L415 189.3L574.9 214.7C583.8 216.1 591.2 222.4 594 231C596.8 239.6 594.5 249 588.2 255.4L473.7 369.9L499 529.8C500.4 538.7 496.7 547.7 489.4 553C482.1 558.3 472.4 559.1 464.4 555L320.1 481.6L175.8 555C167.8 559.1 158.1 558.3 150.8 553C143.5 547.7 139.8 538.8 141.2 529.8L166.4 369.9L52 255.4C45.6 249 43.4 239.6 46.2 231C49 222.4 56.3 216.1 65.3 214.7L225.2 189.3L298.8 45.1C302.9 37.1 311.2 32 320.2 32zM320.1 108.8L262.3 222C258.8 228.8 252.3 233.6 244.7 234.8L119.2 254.8L209 344.7C214.4 350.1 216.9 357.8 215.7 365.4L195.9 490.9L309.2 433.3C316 429.8 324.1 429.8 331 433.3L444.3 490.9L424.5 365.4C423.3 357.8 425.8 350.1 431.2 344.7L521 254.8L395.5 234.8C387.9 233.6 381.4 228.8 377.9 222L320.1 108.8z"/></svg>`,
'circle-question': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M464 256a208 208 0 1 0 -416 0 208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0 256 256 0 1 1 -512 0zm256-80c-17.7 0-32 14.3-32 32 0 13.3-10.7 24-24 24s-24-10.7-24-24c0-44.2 35.8-80 80-80s80 35.8 80 80c0 47.2-36 67.2-56 74.5l0 3.8c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-8.1c0-20.5 14.8-35.2 30.1-40.2 6.4-2.1 13.2-5.5 18.2-10.3 4.3-4.2 7.7-10 7.7-19.6 0-17.7-14.3-32-32-32zM224 368a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"/></svg>`,
'circle-xmark': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464a256 256 0 1 0 0-512 256 256 0 1 0 0 512zM167 167c-9.4 9.4-9.4 24.6 0 33.9l55 55-55 55c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l55-55 55 55c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-55-55 55-55c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-55 55-55-55c-9.4-9.4-24.6-9.4-33.9 0z"/></svg>`,
copy: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M384 336l-192 0c-8.8 0-16-7.2-16-16l0-256c0-8.8 7.2-16 16-16l133.5 0c4.2 0 8.3 1.7 11.3 4.7l58.5 58.5c3 3 4.7 7.1 4.7 11.3L400 320c0 8.8-7.2 16-16 16zM192 384l192 0c35.3 0 64-28.7 64-64l0-197.5c0-17-6.7-33.3-18.7-45.3L370.7 18.7C358.7 6.7 342.5 0 325.5 0L192 0c-35.3 0-64 28.7-64 64l0 256c0 35.3 28.7 64 64 64zM64 128c-35.3 0-64 28.7-64 64L0 448c0 35.3 28.7 64 64 64l192 0c35.3 0 64-28.7 64-64l0-16-48 0 0 16c0 8.8-7.2 16-16 16L64 464c-8.8 0-16-7.2-16-16l0-256c0-8.8 7.2-16 16-16l16 0 0-48-16 0z"/></svg>`,
eye: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M288 80C222.8 80 169.2 109.6 128.1 147.7 89.6 183.5 63 226 49.4 256 63 286 89.6 328.5 128.1 364.3 169.2 402.4 222.8 432 288 432s118.8-29.6 159.9-67.7C486.4 328.5 513 286 526.6 256 513 226 486.4 183.5 447.9 147.7 406.8 109.6 353.2 80 288 80zM95.4 112.6C142.5 68.8 207.2 32 288 32s145.5 36.8 192.6 80.6c46.8 43.5 78.1 95.4 93 131.1 3.3 7.9 3.3 16.7 0 24.6-14.9 35.7-46.2 87.7-93 131.1-47.1 43.7-111.8 80.6-192.6 80.6S142.5 443.2 95.4 399.4c-46.8-43.5-78.1-95.4-93-131.1-3.3-7.9-3.3-16.7 0-24.6 14.9-35.7 46.2-87.7 93-131.1zM288 336c44.2 0 80-35.8 80-80 0-29.6-16.1-55.5-40-69.3-1.4 59.7-49.6 107.9-109.3 109.3 13.8 23.9 39.7 40 69.3 40zm-79.6-88.4c2.5 .3 5 .4 7.6 .4 35.3 0 64-28.7 64-64 0-2.6-.2-5.1-.4-7.6-37.4 3.9-67.2 33.7-71.1 71.1zm45.6-115c10.8-3 22.2-4.5 33.9-4.5 8.8 0 17.5 .9 25.8 2.6 .3 .1 .5 .1 .8 .2 57.9 12.2 101.4 63.7 101.4 125.2 0 70.7-57.3 128-128 128-61.6 0-113-43.5-125.2-101.4-1.8-8.6-2.8-17.5-2.8-26.6 0-11 1.4-21.8 4-32 .2-.7 .3-1.3 .5-1.9 11.9-43.4 46.1-77.6 89.5-89.5z"/></svg>`,
'eye-slash': `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M41-24.9c-9.4-9.4-24.6-9.4-33.9 0S-2.3-.3 7 9.1l528 528c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-96.4-96.4c2.7-2.4 5.4-4.8 8-7.2 46.8-43.5 78.1-95.4 93-131.1 3.3-7.9 3.3-16.7 0-24.6-14.9-35.7-46.2-87.7-93-131.1-47.1-43.7-111.8-80.6-192.6-80.6-56.8 0-105.6 18.2-146 44.2L41-24.9zM176.9 111.1c32.1-18.9 69.2-31.1 111.1-31.1 65.2 0 118.8 29.6 159.9 67.7 38.5 35.7 65.1 78.3 78.6 108.3-13.6 30-40.2 72.5-78.6 108.3-3.1 2.8-6.2 5.6-9.4 8.4L393.8 328c14-20.5 22.2-45.3 22.2-72 0-70.7-57.3-128-128-128-26.7 0-51.5 8.2-72 22.2l-39.1-39.1zm182 182l-108-108c11.1-5.8 23.7-9.1 37.1-9.1 44.2 0 80 35.8 80 80 0 13.4-3.3 26-9.1 37.1zM103.4 173.2l-34-34c-32.6 36.8-55 75.8-66.9 104.5-3.3 7.9-3.3 16.7 0 24.6 14.9 35.7 46.2 87.7 93 131.1 47.1 43.7 111.8 80.6 192.6 80.6 37.3 0 71.2-7.9 101.5-20.6L352.2 422c-20 6.4-41.4 10-64.2 10-65.2 0-118.8-29.6-159.9-67.7-38.5-35.7-65.1-78.3-78.6-108.3 10.4-23.1 28.6-53.6 54-82.8z"/></svg>`,
star: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M288.1-32c9 0 17.3 5.1 21.4 13.1L383 125.3 542.9 150.7c8.9 1.4 16.3 7.7 19.1 16.3s.5 18-5.8 24.4L441.7 305.9 467 465.8c1.4 8.9-2.3 17.9-9.6 23.2s-17 6.1-25 2L288.1 417.6 143.8 491c-8 4.1-17.7 3.3-25-2s-11-14.2-9.6-23.2L134.4 305.9 20 191.4c-6.4-6.4-8.6-15.8-5.8-24.4s10.1-14.9 19.1-16.3l159.9-25.4 73.6-144.2c4.1-8 12.4-13.1 21.4-13.1zm0 76.8L230.3 158c-3.5 6.8-10 11.6-17.6 12.8l-125.5 20 89.8 89.9c5.4 5.4 7.9 13.1 6.7 20.7l-19.8 125.5 113.3-57.6c6.8-3.5 14.9-3.5 21.8 0l113.3 57.6-19.8-125.5c-1.2-7.6 1.3-15.3 6.7-20.7l89.8-89.9-125.5-20c-7.6-1.2-14.1-6-17.6-12.8L288.1 44.8z"/></svg>`,
},
};

View File

@@ -174,6 +174,7 @@ textarea {
padding: 0;
transition: var(--wa-transition-normal) color;
cursor: pointer;
margin-inline-start: var(--wa-form-control-padding-inline);
@media (hover: hover) {
&:hover {

View File

@@ -1,250 +0,0 @@
:host {
display: block;
background-color: var(--wa-color-surface-default);
box-sizing: border-box;
height: 100%;
--menu-width: auto;
--main-width: 1fr;
--aside-width: auto;
--banner-height: 0px;
--header-height: 0px;
--subheader-height: 0px;
--scroll-margin-top: calc(var(--header-height, 0px) + var(--subheader-height, 0px) + 0.5em);
}
slot[name]:not([name='skip-to-content'], [name='navigation-toggle'])::slotted(*) {
display: flex;
background-color: var(--wa-color-surface-default);
}
::slotted([slot='banner']) {
align-items: center;
justify-content: center;
gap: var(--wa-space-m);
padding: var(--wa-space-xs) var(--wa-space-m);
}
::slotted([slot='header']) {
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: var(--wa-space-m);
padding: var(--wa-space-m);
flex: auto;
}
::slotted([slot='subheader']) {
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: var(--wa-space-m);
padding: var(--wa-space-xs) var(--wa-space-m);
}
::slotted([slot*='navigation']),
::slotted([slot='menu']),
::slotted([slot='aside']) {
flex-direction: column;
gap: var(--wa-space-m);
padding: var(--wa-space-m);
}
::slotted([slot='main-header']) {
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: var(--wa-space-m);
padding: var(--wa-space-m) var(--wa-space-3xl);
}
slot:not([name]) {
/* See #331 */
&::slotted(main),
&::slotted(section) {
padding: var(--wa-space-3xl);
}
}
::slotted([slot='main-footer']),
::slotted([slot='footer']) {
align-items: start;
justify-content: space-between;
flex-wrap: wrap;
gap: var(--wa-space-m);
padding: var(--wa-space-3xl);
}
:host([disable-sticky~='banner']) :is([part~='header'], [part~='subheader']) {
--banner-height: 0px !important;
}
:host([disable-sticky~='header']) [part~='subheader'] {
--header-height: 0px !important;
}
/* Nothing else depends on subheader-height. */
:host([disable-sticky~='subheader']) {
}
:host([disable-sticky~='aside']) [part~='aside'],
:host([disable-sticky~='menu']) [part~='menu'] {
height: unset;
max-height: unset;
}
:host([disable-sticky~='banner']) [part~='banner'],
:host([disable-sticky~='header']) [part~='header'],
:host([disable-sticky~='subheader']) [part~='subheader'],
:host([disable-sticky~='aside']) [part~='aside'],
:host([disable-sticky~='menu']) [part~='menu'] {
position: static;
overflow: unset;
z-index: unset;
}
:host([disable-sticky~='aside']) [part~='aside'],
:host([disable-sticky~='menu']) [part~='menu'] {
height: auto;
max-height: auto;
}
[part~='base'] {
min-height: 100%;
display: grid;
grid-template-rows: repeat(3, minmax(0, auto)) minmax(0, 1fr) minmax(0, auto);
grid-template-columns: 100%;
width: 100%;
grid-template-areas:
'banner'
'header'
'subheader'
'body'
'footer';
}
/* Grid areas */
[part~='banner'] {
grid-area: banner;
}
[part~='header'] {
grid-area: header;
}
[part~='subheader'] {
grid-area: subheader;
}
[part~='menu'] {
grid-area: menu;
}
[part~='body'] {
grid-area: body;
}
[part~='main'] {
grid-area: main;
}
[part~='aside'] {
grid-area: aside;
}
[part~='footer'] {
grid-area: footer;
}
/* Z-indexes */
[part~='banner'],
[part~='header'],
[part~='subheader'] {
position: sticky;
z-index: 5;
}
[part~='banner'] {
top: 0px;
}
[part~='header'] {
top: var(--banner-height);
/** Make the header flex so that you don't unexpectedly have the default toggle button appearing above a slotted div because block elements are fun. */
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
}
[part~='subheader'] {
top: calc(var(--header-height) + var(--banner-height));
}
[part~='body'] {
display: grid;
height: 100%;
align-items: flex-start;
grid-template-columns: minmax(0, var(--menu-width)) minmax(0, var(--main-width)) minmax(0, var(--aside-width));
grid-template-rows: minmax(0, 1fr);
grid-template-areas: 'menu main aside';
}
[part~='main'] {
display: grid;
min-height: 100%;
grid-template-columns: minmax(0, 1fr);
grid-template-rows: minmax(0, auto) minmax(0, 1fr) minmax(0, auto);
grid-template-areas:
'main-header'
'main-content'
'main-footer';
}
[part~='main-header'] {
grid-area: main-header;
}
[part~='main-content'] {
grid-area: main-content;
}
[part~='main-footer'] {
grid-area: main-footer;
}
.skip-to-content {
position: absolute;
top: var(--wa-space-m);
left: var(--wa-space-m);
z-index: 6;
border-radius: var(--wa-corners-1x);
background-color: var(--wa-color-surface-default);
color: var(--wa-color-text-link);
text-decoration: none;
padding: var(--wa-space-s) var(--wa-space-m);
box-shadow: var(--wa-shadow-l);
outline: var(--wa-focus-ring);
outline-offset: var(--wa-focus-ring-offset);
}
[part~='menu'],
[part~='aside'] {
position: sticky;
top: calc(var(--banner-height) + var(--header-height) + var(--subheader-height));
z-index: 4;
height: calc(100dvh - var(--header-height) - var(--banner-height) - var(--subheader-height));
max-height: calc(100dvh - var(--header-height) - var(--banner-height) - var(--subheader-height));
overflow: auto;
}
[part~='navigation'] {
height: 100%;
display: grid;
grid-template-columns: minmax(0, 1fr);
grid-template-rows: minmax(0, auto) minmax(0, 1fr) minmax(0, auto);
}
[part~='drawer']::part(dialog) {
background-color: var(--wa-color-surface-default);
}
/* Set these on the slot because we don't always control the navigation-toggle since that may be slotted. */
slot[name~='navigation-toggle'],
:host([disable-navigation-toggle]) slot[name~='navigation-toggle'] {
display: none;
}
/* Sometimes the media query in the viewport is stubborn in iframes. This is an extra check to make it behave properly. */
:host(:not([disable-navigation-toggle])[view='mobile']) slot[name~='navigation-toggle'] {
display: contents;
}
[part~='navigation-toggle'] {
/* Use only a margin-inline-start because the slotted header is expected to have default padding
so it looks really awkward if this sets a margin-inline-end and the slotted header has a padding-inline-start. */
margin-inline-start: var(--wa-space-m);
}

View File

@@ -1,11 +0,0 @@
export default (breakpoint: string = '768px') => `
@media screen and (width < ${breakpoint}) {
[part~='navigation'] {
display: none;
}
:host(:not([disable-navigation-toggle])) slot[name~='navigation-toggle'] {
display: contents;
}
}
`;

View File

@@ -1,15 +0,0 @@
import { expect } from '@open-wc/testing';
import { html } from 'lit';
import { fixtures } from '../../internal/test/fixture.js';
describe('<wa-page>', () => {
for (const fixture of fixtures) {
describe(`with "${fixture.type}" rendering`, () => {
it('should render a component', async () => {
const el = await fixture(html` <wa-page></wa-page> `);
expect(el).to.exist;
});
});
}
});

View File

@@ -1,455 +0,0 @@
import type { PropertyValues } from 'lit';
import { html, isServer } from 'lit';
import { customElement, property, query } from 'lit/decorators.js';
import { live } from 'lit/directives/live.js';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import visuallyHidden from '../../styles/utilities/visually-hidden.css';
import '../button/button.js';
import '../drawer/drawer.js';
import type WaDrawer from '../drawer/drawer.js';
import '../icon/icon.js';
import styles from './page.css';
import mobileStyles from './page.mobile.styles.js';
if (typeof ResizeObserver === 'undefined') {
globalThis.ResizeObserver = class {
// eslint-disable-next-line
constructor(..._args: ConstructorParameters<typeof ResizeObserver>) {}
// eslint-disable-next-line
observe(..._args: Parameters<ResizeObserver['observe']>) {}
// eslint-disable-next-line
unobserve(..._args: Parameters<ResizeObserver['unobserve']>) {}
// eslint-disable-next-line
disconnect(..._args: Parameters<ResizeObserver['disconnect']>) {}
};
}
//
// TODO - the toPx and toLength functions aren't used anywhere else, and they're not named or documented well enough to
// abstract into a utility as-is.
//
/** Converts a non-pixel value to a pixel value. */
function toPx(value: string | number, element: HTMLElement | SVGElement = document.documentElement): number {
if (!Number.isNaN(Number(value))) {
return Number(value);
}
// If CSS.registerProperty isn't supported, try to parse as-is
if (!window.CSS || !CSS.registerProperty) {
if (typeof value === 'string' && value.endsWith('px')) {
return parseFloat(value);
}
return Number(value) || 0;
}
const resolver = '--wa-length-resolver';
// Register the property if not already done
if (!CSS.registerProperty.toString().includes(resolver)) {
try {
CSS.registerProperty({
name: resolver,
syntax: '<length>',
inherits: false,
initialValue: '0px',
});
} catch (e) {
// Property might already be registered
}
}
const previousValue = element.style.getPropertyValue(resolver);
element.style.setProperty(resolver, value as string);
const computedValue = getComputedStyle(element)?.getPropertyValue(resolver);
element.style.setProperty(resolver, previousValue);
if (computedValue?.endsWith('px')) {
return parseFloat(computedValue);
}
return Number(computedValue) || 0;
}
/** Converts a number or string to a CSS px value. Not used anywhere else, so consolidated here for the time being. */
function toLength(px: number | string): string {
return Number.isNaN(Number(px)) ? (px as string) : `${px}px`;
}
/**
* @summary Pages offer an easy way to scaffold entire page layouts using minimal markup.
* @documentation https://webawesome.com/docs/components/page
* @status experimental
* @since 3.0
*
* @slot - The page's main content.
* @slot banner - The banner that gets display above the header. The banner will not be shown if no content is provided.
* @slot header - The header to display at the top of the page. If a banner is present, the header will appear below the banner. The header will not be shown if there is no content.
* @slot subheader - A subheader to display below the `header`. This is a good place to put things like breadcrumbs.
* @slot menu - The left side of the page. If you slot an element in here, you will override the default `navigation` slot and will be handling navigation on your own. This also will not disable the fallback behavior of the navigation button. This section "sticks" to the top as the page scrolls.
* @slot navigation-header - The header for a navigation area. On mobile this will be the header for `<wa-drawer>`.
* @slot navigation - The main content to display in the navigation area. This is displayed on the left side of the page, if `menu` is not used. This section "sticks" to the top as the page scrolls.
* @slot navigation-footer - The footer for a navigation area. On mobile this will be the footer for `<wa-drawer>`.
* @slot navigation-toggle - Use this slot to slot in your own button + icon for toggling the navigation drawer. By default it is a `<wa-button>` + a 3 bars `<wa-icon>`
* @slot navigation-toggle-icon - Use this to slot in your own icon for toggling the navigation drawer. By default it is 3 bars `<wa-icon>`.
* @slot main-header - Header to display inline above the main content.
* @slot main-footer - Footer to display inline below the main content.
* @slot aside - Content to be shown on the right side of the page. Typically contains a table of contents, ads, etc. This section "sticks" to the top as the page scrolls.
* @slot skip-to-content - The "skip to content" slot. You can override this If you would like to override the `Skip to content` button and add additional "Skip to X", they can be inserted here.
* @slot footer - The content to display in the footer. This is always displayed underneath the viewport so will always make the page "scrollable".
*
* @csspart base - The component's base wrapper.
* @csspart banner - The banner to show above header.
* @csspart header - The header, usually for top level navigation / branding.
* @csspart subheader - Shown below the header, usually intended for things like breadcrumbs and other page level navigation.
* @csspart body - The wrapper around menu, main, and aside.
* @csspart menu - The left hand side of the page. Generally intended for navigation.
* @csspart navigation - The `<nav>` that wraps the navigation slots on desktop viewports.
* @csspart navigation-header - The header for a navigation area. On mobile this will be the header for `<wa-drawer>`.
* @csspart navigation-footer - The footer for a navigation area. On mobile this will be the footer for `<wa-drawer>`.
* @csspart navigation-toggle - The default `<wa-button>` that will toggle the `<wa-drawer>` for mobile viewports.
* @csspart navigation-toggle-icon - The default `<wa-icon>` displayed inside of the navigation-toggle button.
* @csspart main-header - The header above main content.
* @csspart main-content - The main content.
* @csspart main-footer - The footer below main content.
* @csspart aside - The right hand side of the page. Used for things like table of contents, ads, etc.
* @csspart skip-links - Wrapper around skip-link
* @csspart skip-link - The "skip to main content" link
* @csspart footer - The footer of the page. This is always below the initial viewport size.
* @csspart dialog-wrapper - A wrapper around elements such as dialogs or other modal-like elements.
*
* @cssproperty [--menu-width=auto] - The width of the page's "menu" section.
* @cssproperty [--main-width=1fr] - The width of the page's "main" section.
* @cssproperty [--aside-width=auto] - The wide of the page's "aside" section.
* @cssproperty [--banner-height=0px] - The height of the banner. This gets calculated when the page initializes. If the height is known, you can set it here to prevent shifting when the page loads.
* @cssproperty [--header-height=0px] - The height of the header. This gets calculated when the page initializes. If the height is known, you can set it here to prevent shifting when the page loads.
* @cssproperty [--subheader-height=0px] - The height of the subheader. This gets calculated when the page initializes. If the height is known, you can set it here to prevent shifting when the page loads.
*/
@customElement('wa-page')
export default class WaPage extends WebAwesomeElement {
static css = [visuallyHidden, styles];
private headerResizeObserver = this.slotResizeObserver('header');
private subheaderResizeObserver = this.slotResizeObserver('subheader');
private bannerResizeObserver = this.slotResizeObserver('banner');
private footerResizeObserver = this.slotResizeObserver('footer');
private slotResizeObserver(slot: string) {
return new ResizeObserver(entries => {
for (const entry of entries) {
if (entry.contentBoxSize) {
const contentBoxSize = entry.borderBoxSize[0];
this.style.setProperty(`--${slot}-height`, `${contentBoxSize.blockSize}px`);
}
}
});
}
private handleNavigationToggle = (e: Event) => {
// Don't toggle the nav when we're in desktop mode
if (this.view === 'desktop') {
// Just in case, try to hide the navigation.
this.hideNavigation();
return;
}
const path = e.composedPath();
const navigationToggleSlot = this.navigationToggleSlot;
if (
path.find((el: Element) => {
return (
el.hasAttribute?.('data-toggle-nav') ||
el.assignedSlot === navigationToggleSlot ||
el === navigationToggleSlot
);
})
) {
e.preventDefault();
this.toggleNavigation();
}
};
@query("[part~='header']") header: HTMLElement;
@query("[part~='subheader']") subheader: HTMLElement;
@query("[part~='footer']") footer: HTMLElement;
@query("[part~='banner']") banner: HTMLElement;
@query("[part~='drawer']") navigationDrawer: WaDrawer;
@query("slot[name~='navigation-toggle']") navigationToggleSlot: HTMLSlotElement;
/**
* The view is a reflection of the "mobileBreakpoint", when the page is larger than the `mobile-breakpoint` (768px by
* default), it is considered to be a "desktop" view. The view is merely a way to distinguish when to show/hide the
* navigation. You can use additional media queries to make other adjustments to content as necessary.
* The default is "desktop" because the "mobile navigation drawer" isn't accessible via SSR due to drawer requiring JS.
*/
@property({ attribute: 'view', reflect: true }) view: 'mobile' | 'desktop' = 'desktop';
/**
* Whether or not the navigation drawer is open. Note, the navigation drawer is only "open" on mobile views.
*/
@property({ attribute: 'nav-open', reflect: true, type: Boolean }) navOpen = false;
/**
* At what page width to hide the "navigation" slot and collapse into a hamburger button.
* Accepts both numbers (interpreted as px) and CSS lengths (e.g. `50em`), which are resolved based on the root element.
*/
@property({ attribute: 'mobile-breakpoint', type: String })
mobileBreakpoint = '768px';
/**
* Where to place the navigation when in the mobile viewport.
*/
@property({ attribute: 'navigation-placement', reflect: true }) navigationPlacement: 'start' | 'end' = 'start';
/**
* Determines whether or not to hide the default hamburger button.
* This will automatically flip to "true" if you add an element with `data-toggle-nav` anywhere in the element light DOM.
* Generally this will be set for you and you don't need to do anything, unless you're using SSR, in which case you should set this manually for initial page loads.
*/
@property({ attribute: 'disable-navigation-toggle', reflect: true, type: Boolean }) disableNavigationToggle: boolean =
false;
pageResizeObserver = new ResizeObserver(entries => {
for (const entry of entries) {
if (entry.contentBoxSize) {
const contentBoxSize = entry.borderBoxSize[0];
const pageWidth = contentBoxSize.inlineSize;
const oldView = this.view;
if (pageWidth >= toPx(this.mobileBreakpoint)) {
this.view = 'desktop';
} else {
this.view = 'mobile';
}
this.requestUpdate('view', oldView);
}
}
});
protected update(changedProperties: PropertyValues<this>): void {
if (changedProperties.has('view')) {
this.hideNavigation();
}
super.update(changedProperties);
}
constructor() {
super();
if (!isServer) {
this.addEventListener('click', this.handleNavigationToggle);
}
}
connectedCallback() {
super.connectedCallback();
this.pageResizeObserver.observe(this);
const navQuery = ":not([slot='toggle-navigation']) [data-toggle-nav]";
// check once on initial connect
// eslint-disable-next-line
this.disableNavigationToggle = Boolean(this.querySelector(navQuery));
setTimeout(() => {
this.headerResizeObserver.observe(this.header);
this.subheaderResizeObserver.observe(this.subheader);
this.bannerResizeObserver.observe(this.banner);
this.footerResizeObserver.observe(this.footer);
// Check again when the element updates
// eslint-disable-next-line
this.disableNavigationToggle = Boolean(this.querySelector(navQuery));
});
}
firstUpdated() {
// If the user provides a #main-content id, it should be present in the default slot and the "skip to
// content" link will point to it. If not, we'll prepend an empty element for them so things just work.
if (!document.getElementById('main-content')) {
const div = document.createElement('div');
div.id = 'main-content';
div.slot = 'skip-to-content-target';
this.prepend(div);
}
}
disconnectedCallback() {
super.disconnectedCallback();
this.pageResizeObserver.unobserve(this);
this.headerResizeObserver.unobserve(this.header);
this.subheaderResizeObserver.unobserve(this.subheader);
this.footerResizeObserver.unobserve(this.footer);
this.bannerResizeObserver.unobserve(this.banner);
}
/**
* Shows the mobile navigation drawer
*/
showNavigation() {
this.navOpen = true;
}
/**
* Hides the mobile navigation drawer
*/
hideNavigation() {
this.navOpen = false;
}
/**
* Toggles the mobile navigation drawer
*/
toggleNavigation() {
this.navOpen = !this.navOpen;
}
render() {
return html`
<a href="#main-content" part="skip-to-content" class="wa-visually-hidden">
<slot name="skip-to-content">Skip to content</slot>
</a>
<!-- unsafeHTML needed for SSR until this is solved: https://github.com/lit/lit/issues/4696 -->
${unsafeHTML(`
<style id="mobile-styles">
${mobileStyles(toLength(this.mobileBreakpoint))}
</style>
`)}
<div class="base" part="base">
<div class="banner" part="banner">
<slot name="banner"></slot>
</div>
<div class="header" part="header">
<slot name="navigation-toggle">
<wa-button part="navigation-toggle" size="small" appearance="plain" variant="neutral">
<slot name="navigation-toggle-icon">
<wa-icon name="bars" part="navigation-toggle-icon" label="Toggle navigation drawer"></wa-icon>
</slot>
</wa-button>
</slot>
<slot name="header"></slot>
</div>
<div class="subheader" part="subheader">
<slot name="subheader"></slot>
</div>
<div class="body" part="body">
<div class="menu" part="menu">
<slot name="menu">
<nav name="navigation" class="navigation" part="navigation navigation-desktop">
<!-- Add fallback divs so that CSS grid works properly. -->
<slot name="desktop-navigation-header">
<slot name=${this.view === 'desktop' ? 'navigation-header' : '___'}><div></div></slot>
</slot>
<slot name="desktop-navigation">
<slot name=${this.view === 'desktop' ? 'navigation' : '____'}><div></div></slot>
</slot>
<slot name="desktop-navigation-footer">
<slot name=${this.view === 'desktop' ? 'navigation-footer' : '___'}><div></div></slot>
</slot>
</nav>
</slot>
</div>
<div class="main" part="main">
<div class="main-header" part="main-header">
<slot name="main-header"></slot>
</div>
<div class="main-content" part="main-content">
<slot name="skip-to-content-target"></slot>
<slot></slot>
</div>
<div class="main-footer" part="main-footer">
<slot name="main-footer"></slot>
</div>
</div>
<div class="aside" part="aside">
<slot name="aside"></slot>
</div>
</div>
<div class="footer" part="footer">
<slot name="footer"></slot>
</div>
</div>
<wa-drawer
part="drawer"
placement=${this.navigationPlacement}
light-dismiss
?open=${live(this.navOpen)}
@wa-after-show=${() => (this.navOpen = this.navigationDrawer.open)}
@wa-after-hide=${() => (this.navOpen = this.navigationDrawer.open)}
exportparts="
dialog:drawer__dialog,
overlay:drawer__overlay,
panel:drawer__panel,
header:drawer__header,
header-actions:drawer__header-actions,
title:drawer__title,
close-button:drawer__close-button,
close-button__base:drawer__close-button__base,
body:drawer__body,
footer:drawer__footer
"
class="navigation-drawer"
>
<slot slot="label" part="navigation-header" name="mobile-navigation-header">
<slot name=${this.view === 'mobile' ? 'navigation-header' : '___'}></slot>
</slot>
<slot name="mobile-navigation">
<slot name=${this.view === 'mobile' ? 'navigation' : '____'}></slot>
</slot>
<slot name="mobile-navigation-footer">
<slot
part="navigation-footer"
slot="footer"
name=${this.view === 'mobile' ? 'navigation-footer' : '___'}
></slot>
</slot>
</wa-drawer>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
'wa-page': WaPage;
}
}
//
// Append a supporting light DOM styles for <wa-page>
//
const stylesheet = new CSSStyleSheet();
stylesheet.replaceSync(`
:is(html, body):has(wa-page) {
min-height: 100%;
height: 100%;
padding: 0;
margin: 0;
}
/**
Because headers are sticky, this is needed to make sure page fragment anchors scroll down past the headers / subheaders and are visible.
IE: \`<a href="#id-for-h2">\` anchors.
*/
wa-page :is(*, *:after, *:before) {
scroll-margin-top: var(--scroll-margin-top);
}
wa-page[view='desktop'] [data-toggle-nav] {
display: none;
}
wa-page[view='mobile'] .wa-desktop-only, wa-page[view='desktop'] .wa-mobile-only {
display: none !important;
}
`);
document.adoptedStyleSheets = [...document.adoptedStyleSheets, stylesheet];

View File

@@ -454,7 +454,7 @@
&::after {
content: '';
background-color: var(--wa-color-text-quiet);
mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="16" width="10" viewBox="0 0 320 512"><path d="M310.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 256 73.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z"/></svg>')
mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="16" width="10" viewBox="0 0 320 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M311.1 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L243.2 256 73.9 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z"/></svg>')
center no-repeat;
width: 1rem;
height: 1rem;
@@ -916,8 +916,8 @@
&:indeterminate::after {
position: absolute;
width: 100%;
height: 100%;
width: round(calc(100% - var(--wa-form-control-border-width) * 2), 1px);
height: round(calc(100% - var(--wa-form-control-border-width) * 2), 1px);
content: '';
@@ -927,7 +927,7 @@
}
&:checked::after {
mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M438.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 338.7 393.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"/></svg>')
mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="currentColor" d="M434.8 70.1c14.3 10.4 17.5 30.4 7.1 44.7l-256 352c-5.5 7.6-14 12.3-23.4 13.1s-18.5-2.7-25.1-9.3l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l101.5 101.5 234-321.7c10.4-14.3 30.4-17.5 44.7-7.1z"/></svg>')
center no-repeat;
}
@@ -940,7 +940,7 @@
/* Radio */
input[type='radio'] {
--checked-icon-color: var(--wa-form-control-activated-color);
--checked-icon-scale: 0.75;
--checked-icon-scale: 0.7;
color: transparent;
@@ -1059,6 +1059,8 @@
select {
--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 fill="rgb(180 180 200)" 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>');
--icon-caret: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 448 512"><!--! Font Awesome Pro 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2025 Fonticons, Inc. --><path fill="rgb(180 180 200)" d="M201.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 0L224 338.7 54.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z"/></svg>');
appearance: none;
position: relative;