Merge branch 'next' into dialog-drawer-focus

This commit is contained in:
Cory LaViska
2025-10-15 10:26:35 -04:00
committed by GitHub
14 changed files with 425 additions and 93 deletions

View File

@@ -0,0 +1,312 @@
---
title: Web Awesome is Undergoing Maintenance
description: We're performing routine maintenance to keep things running smoothly. Check back soon!
layout: blank
permalink: 503.html
noindex: true
unlisted: true
---
{% block head %}
<link id="site-stylesheet" rel="stylesheet" href="/assets/styles/theme-site.css" />
<link id="site-stylesheet" rel="stylesheet" href="/assets/styles/site.css" />
{% endblock %}
<style>
:root {
--scene-vertical-offset: calc(var(--wa-space-2xs) * -1);
--wa-font-family-heading: cera-round-pro;
--vehicle-offset: 25ch;
--vehicle-duration: 20s;
--vehicle-start: calc(-1 * var(--vehicle-offset));
--vehicle-end: calc(100% + var(--vehicle-offset));
}
html, wa-page {
background-color: var(--wa-color-surface-lowered);
}
wa-icon[name='traffic-cone'] {
--primary-color: var(--wa-color-brand-70);
--secondary-color: var(--wa-color-text-normal);
--secondary-opacity: 1.0;
}
wa-page.background-grid {
--grid-line-color: color-mix(in oklab, var(--wa-color-text-normal), transparent 96%);
--subgrid-line-color: color-mix(in oklab, var(--wa-color-text-normal), transparent 98%);
}
wa-page > [slot='main-footer'] {
border-block-end: var(--wa-border-style) calc(var(--wa-border-width-l) * 10) var(--wa-color-text-normal);
padding: 0;
background-color: transparent;
}
.header-content {
margin-inline: auto;
max-width: var(--content-width-l);
padding-inline: var(--content-padding-inline);
}
.icon-brand-logo {
font-size: var(--wa-font-size-xl);
color: var(--wa-brand-orange);
}
/* centering main-content */
wa-page::part(main-content) {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#content {
max-width: var(--content-width-m);
padding-inline: var(--content-padding-inline);
margin-inline: auto;
}
.heading-stacked-subtitle {
text-transform: uppercase;
letter-spacing: 0.1em;
}
.heading-stacked-subtitle wa-icon {
position: relative;
inset-block-start: calc(var(--wa-space-3xs) * -0.75);
font-size: 0.75em;
}
.heading-stacked-subtitle wa-icon[name="traffic-cone"] {
--secondary-color: var(--wa-color-text-normal);
--primary-color: var(--wa-color-brand-70);
margin-inline: calc(var(--wa-space-xs) * -1.15) calc(var(--wa-space-xs) * -0.75);
}
.copy {
code {
font-size: 0.75em;
}
strong {
text-decoration: underline;
text-decoration-color: var(--wa-color-brand-70);
text-decoration-thickness: var(--wa-border-width-m);
text-underline-offset: var(--wa-space-2xs);
}
}
.status {
width: 100%;
--min-column-size: 30ch;
wa-callout {
background-color: var(--wa-color-surface-default);
}
}
.linkies {
/* nudge those linkies left */
margin-inline-start: calc(var(--wa-space-xs) * -1);
a {
padding-inline: var(--wa-space-xs);
}
}
.scene {
width: 100%;
position: relative;
overflow-x: clip;
inset-block-end: var(--scene-vertical-offset);
.vehicle {
position: absolute;
inset-inline-start: var(--vehicle-start);
inset-block-end: 0; /* align all vehicles to bottom */
animation: driveAcross var(--vehicle-duration) linear infinite;
transform-origin: center;
z-index: 1;
}
.vehicle-with-object {
white-space: nowrap;
display: flex;
align-items: baseline;
gap: var(--wa-space-3xs);
}
.scene-left {
position: absolute;
inset-block-end: 0;
inset-inline-start: var(--wa-space-l);
}
.scene-left wa-icon[name='toilet-portable'] {
position: relative;
inset-block-start: var(--scene-vertical-offset);
margin-inline: calc(var(--wa-space-xs) * -1);
}
.scene-left wa-icon[name='traffic-cone'] {
position: relative;
inset-block-start: var(--scene-vertical-offset);
}
.blocks {
position: absolute;
inset-inline-end: calc(var(--wa-space-l) * -1);
inset-block-end: 0;
z-index: 2;
}
.blocks wa-icon[name='block-brick'] {
margin-inline: calc(var(--wa-space-xs) * -1);
}
.blocks-bottom {
margin-block-start: calc(var(--wa-space-2xs) * -1);
}
wa-icon[family='duotone'] {
--secondary-opacity: 1.0;
}
wa-icon[name='bulldozer'],
wa-icon[name='excavator'] {
--secondary-color: var(--wa-color-brand-70);
}
wa-icon[name='block-brick'],
wa-icon[name='toilet-portable'] {
--secondary-color: var(--wa-color-neutral-70);
}
}
@keyframes driveAcross {
0% {
left: var(--vehicle-start);
}
100% {
left: var(--vehicle-end);
}
}
/* Unique rumble animations for each vehicle type */
@keyframes rumble-bulldozer {
0%, 100% { transform: translateY(0px) rotate(0deg); }
25% { transform: translateY(-1px) rotate(0.5deg); }
50% { transform: translateY(1px) rotate(-0.3deg); }
75% { transform: translateY(-0.5px) rotate(0.2deg); }
}
/* Apply rumble animation to the single vehicle */
.vehicle-driving { animation: driveAcross var(--vehicle-duration) linear infinite; }
.vehicle wa-icon[name="bulldozer"] { animation: rumble-bulldozer 0.1s ease-in-out infinite; }
</style>
<wa-page disable-sticky="header" class="background-grid">
<header slot="header">
<div class="header-content wa-split" style="flex-wrap: nowrap;">
<wa-icon variant="brands" name="web-awesome" class="icon-brand-logo"></wa-icon>
<div>
<wa-button id="contact-us-button" appearance="plain" href="mailto:hello@webawesome.com?subject=Help%2C%20Web%20Awesome">
<wa-icon variant="regular" name="headset" label="Need help? Contact Us" class="icon-embiggen"></wa-icon>
</wa-button>
<wa-tooltip for="contact-us-button" aria-hidden="true">Contact Us</wa-tooltip>
</div>
</div>
</header>
<main id="content">
<div class="content-container wa-stack wa-gap-xl wa-align-items-center">
<h1 class="brand-font wa-stack wa-gap-s heading heading-stacked" style="text-align: center;">
<span class="wa-heading-m heading-stacked-subtitle">
under
<span class="wa-visually-hidden">maintenance</span>
<span aria-hidden="true">
m
<wa-icon family="duotone" variant="solid" name="traffic-cone"></wa-icon>
inten
<wa-icon family="duotone" variant="solid" name="traffic-cone"></wa-icon>
nce
</span>
</span>
<span class="wa-heading-3xl heading-stacked-title">Hey! We're Workin&apos; Here</span>
</h1>
<p class="copy wa-body-l line-length line-length-m" style="text-align: center;">Mind the <code>wa-gap</code>! webawesome.com is undergoing maintenance and will be back shortly.</p>
<div class="wa-grid wa-gap-xl status">
<wa-callout appearance="plain" variant="neutral">
<wa-icon slot="icon" family="duotone" variant="regular" name="diamond-exclamation" class="icon-embiggen" style="--secondary-opacity: 1; --secondary-color: var(--wa-color-warning-fill-normal);"></wa-icon>
<strong>Temporarily Unavailable</strong><br />
Access to Docs, Accounts, and Teams
</wa-callout>
<wa-callout appearance="plain" variant="neutral">
<wa-icon slot="icon" family="duotone" variant="regular" name="bolt" class="icon-embiggen" style="--secondary-opacity: 1; --secondary-color: var(--wa-color-success-fill-normal);"></wa-icon>
<strong>Fully Operational</strong><br />
Services (such as CDNs) and Support
</wa-callout>
</div>
<div class="wa-cluster wa-gap-xs linkies">
<h2 class="wa-visually-hidden">Web Awesome Elsewhere</h2>
<a href="https://github.com/shoelace-style/webawesome" rel="noopener noreferrer" target="_blank" class="appearance-plain">
<wa-icon family="brands" name="github" label="GitHub"></wa-icon>
</a>
<a href="https://bsky.app/profile/webawesome.com" rel="noopener noreferrer" target="_blank" class="appearance-plain">
<wa-icon family="brands" name="bluesky" label="Bluesky"></wa-icon>
</a>
<a href="https://mastodon.social/@webawesome" rel="noopener noreferrer" target="_blank" class="appearance-plain">
<wa-icon family="brands" name="mastodon" label="Mastodon"></wa-icon>
</a>
<a href="https://x.com/webawesomer" rel="noopener noreferrer" target="_blank" class="appearance-plain">
<wa-icon family="brands" name="x-twitter" label="Twitter (X)"></wa-icon>
</a>
<a href="https://www.threads.com/@web.awesome" rel="noopener noreferrer" target="_blank" class="appearance-plain">
<wa-icon family="brands" name="threads" label="Threads"></wa-icon>
</a>
<a href="mailto:hello@webawesome.com?subject=Help%2C%20Web%20Awesome" class="appearance-plain">
<wa-icon variant="regular" name="envelope" label="Email Web Awesome"></wa-icon>
</a>
</div>
</div>
</main>
<div slot="main-footer" class="footer">
<div class="scene">
<div class="scene-left wa-cluster wa-align-items-end">
<wa-icon family="duotone" variant="solid" name="traffic-cone"></wa-icon>
<div class="wa-cluster wa-gap-0">
<wa-icon family="duotone" variant="regular" name="toilet-portable" style="font-size: var(--wa-font-size-2xl);"></wa-icon>
<wa-icon family="duotone" variant="regular" name="toilet-portable" style="font-size: var(--wa-font-size-2xl);"></wa-icon>
<wa-icon family="duotone" variant="regular" name="toilet-portable" style="font-size: var(--wa-font-size-2xl);"></wa-icon>
</div>
<wa-icon family="duotone" variant="regular" name="excavator" style="font-size: var(--wa-font-size-3xl);"></wa-icon>
<wa-icon family="duotone" variant="solid" name="traffic-cone"></wa-icon>
</div>
<div class="blocks wa-stack wa-align-items-center wa-gap-0">
<div class="blocks-top wa-cluster wa-gap-0">
<wa-icon family="duotone" variant="regular" name="block-brick" style="font-size: var(--wa-font-size-2xl);"></wa-icon>
<wa-icon family="duotone" variant="regular" name="block-brick" style="font-size: var(--wa-font-size-2xl);"></wa-icon>
<wa-icon family="duotone" variant="regular" name="block-brick" style="font-size: var(--wa-font-size-2xl);"></wa-icon>
</div>
<div class="blocks-bottom wa-cluster wa-gap-0">
<wa-icon family="duotone" variant="regular" name="block-brick" style="font-size: var(--wa-font-size-2xl);"></wa-icon>
<wa-icon family="duotone" variant="regular" name="block-brick" style="font-size: var(--wa-font-size-2xl);"></wa-icon>
<wa-icon family="duotone" variant="regular" name="block-brick" style="font-size: var(--wa-font-size-2xl);"></wa-icon>
<wa-icon family="duotone" variant="regular" name="block-brick" style="font-size: var(--wa-font-size-2xl);"></wa-icon>
<wa-icon family="duotone" variant="regular" name="block-brick" style="font-size: var(--wa-font-size-2xl);"></wa-icon>
</div>
</div>
<div class="track">
<wa-icon family="duotone" variant="regular" name="bulldozer" class="spacer-dot-gif" style="font-size: var(--wa-font-size-3xl); opacity: 0;"></wa-icon>
<span class="vehicle vehicle-driving vehicle-with-object">
<wa-icon family="duotone" variant="regular" name="bulldozer" style="font-size: var(--wa-font-size-3xl);"></wa-icon>
<wa-icon family="duotone" variant="regular" name="block-brick" style="font-size: var(--wa-font-size-2xl); position: relative; inset-inline-start: calc(var(--wa-space-2xs) * -1);"></wa-icon>
</span>
</div>
</div>
</div>
</wa-page>

View File

@@ -410,12 +410,12 @@
<div class="wa-stack wa-gap-xl" id="colophon"> <div class="wa-stack wa-gap-xl" id="colophon">
<div class="wa-stack wa-gap-xs"> <div class="wa-stack wa-gap-xs">
{% include "logo-simple.njk" %} {% include "logo-simple.njk" %}
<div class="wa-cluster wa-gap-xs"> <h2 class="wa-heading-xs">Web Awesome</h2>
<h2 class="wa-heading-xs">Web Awesome</h2> <p class="wa-caption-s wa-cluster wa-gap-xs">
<wa-badge id="version-beta-badge" variant="orange" appearance="filled" style="font-size: var(--wa-font-size-2xs);">Beta</wa-badge> Version {{ package.version }}
<wa-tooltip for="version-beta-badge" distance="2" style="font-size: var(--wa-font-size-xs);">Here be freshly made Awesome&hellip; and possible dragons</wa-tooltip> <wa-icon id="version-icon-info" family="duotone" variant="regular" name="party-horn"></wa-icon>
</div> <wa-tooltip for="version-icon-info" distance="2" style="font-size: var(--wa-font-size-xs);">Here be freshly launched Awesome and no wa-dragons</wa-tooltip>
<p class="wa-caption-s">Version {{ package.version }}</p> </p>
<p class="wa-caption-s">&copy; Fonticons, Inc.</p> <p class="wa-caption-s">&copy; Fonticons, Inc.</p>
</div> </div>

View File

@@ -205,6 +205,12 @@ wa-page > header {
} }
} }
} }
#version-icon-info {
--secondary-opacity: 1;
--secondary-color: var(--wa-brand-orange);
padding-inline: var(--wa-space-xs);
}
} }
wa-button.delete { wa-button.delete {

View File

@@ -111,7 +111,49 @@
} }
/* #endregion */ /* #endregion */
/* #region funsies */ /* #region funsies + cosmetics */
/* grid background */
.background-grid {
--grid-spacing: var(--wa-space-2xl);
--grid-line-color: color-mix(in oklab, var(--wa-color-text-normal), transparent 90%);
--grid-line-width: var(--wa-border-width-s);
--subgrid-spacing: calc(var(--grid-spacing) / 2);
--subgrid-line-color: color-mix(in oklab, var(--wa-color-text-normal), transparent 95%);
--subgrid-line-width: var(--wa-border-width-s);
background-image:
/* main grid - vertical lines */
linear-gradient(to right, var(--grid-line-color) var(--grid-line-width), transparent var(--grid-line-width)),
/* main grid - horizontal lines */
linear-gradient(to bottom, var(--grid-line-color) var(--grid-line-width), transparent var(--grid-line-width)),
/* sub-grid - vertical lines (offset by half the main grid spacing) */
linear-gradient(
to right,
var(--subgrid-line-color) var(--subgrid-line-width),
transparent var(--subgrid-line-width)
),
/* sub-grid - horizontal lines (offset by half the main grid spacing) */
linear-gradient(
to bottom,
var(--subgrid-line-color) var(--subgrid-line-width),
transparent var(--subgrid-line-width)
);
background-size:
var(--grid-spacing) var(--grid-spacing),
var(--grid-spacing) var(--grid-spacing),
var(--subgrid-spacing) var(--subgrid-spacing),
var(--subgrid-spacing) var(--subgrid-spacing);
background-position:
0 0,
0 0,
calc(var(--grid-spacing) / 2) calc(var(--grid-spacing) / 2),
calc(var(--grid-spacing) / 2) calc(var(--grid-spacing) / 2);
}
/* #endregion */
/* buttons with icon toggle on hover */ /* buttons with icon toggle on hover */
wa-button .icon-hover { wa-button .icon-hover {
display: none; display: none;

View File

@@ -52,7 +52,7 @@ To make a field required, use the `required` attribute. Required fields will aut
customElements.whenDefined('wa-input'), customElements.whenDefined('wa-input'),
customElements.whenDefined('wa-option'), customElements.whenDefined('wa-option'),
customElements.whenDefined('wa-select'), customElements.whenDefined('wa-select'),
customElements.whenDefined('wa-textarea') customElements.whenDefined('wa-textarea'),
]).then(() => { ]).then(() => {
form.addEventListener('submit', event => { form.addEventListener('submit', event => {
event.preventDefault(); event.preventDefault();
@@ -78,10 +78,7 @@ To restrict a value to a specific [pattern](https://developer.mozilla.org/en-US/
const form = document.querySelector('.input-validation-pattern'); const form = document.querySelector('.input-validation-pattern');
// Wait for controls to be defined before attaching form listeners // Wait for controls to be defined before attaching form listeners
await Promise.all([ await Promise.all([customElements.whenDefined('wa-button'), customElements.whenDefined('wa-input')]).then(() => {
customElements.whenDefined('wa-button'),
customElements.whenDefined('wa-input')
]).then(() => {
form.addEventListener('submit', event => { form.addEventListener('submit', event => {
event.preventDefault(); event.preventDefault();
alert('All fields are valid!'); alert('All fields are valid!');
@@ -108,10 +105,7 @@ Some input types will automatically trigger constraints, such as `email` and `ur
const form = document.querySelector('.input-validation-type'); const form = document.querySelector('.input-validation-type');
// Wait for controls to be defined before attaching form listeners // Wait for controls to be defined before attaching form listeners
await Promise.all([ await Promise.all([customElements.whenDefined('wa-button'), customElements.whenDefined('wa-input')]).then(() => {
customElements.whenDefined('wa-button'),
customElements.whenDefined('wa-input')
]).then(() => {
form.addEventListener('submit', event => { form.addEventListener('submit', event => {
event.preventDefault(); event.preventDefault();
alert('All fields are valid!'); alert('All fields are valid!');
@@ -137,10 +131,7 @@ To create a custom validation error, pass a non-empty string to the `setCustomVa
const input = form.querySelector('wa-input'); const input = form.querySelector('wa-input');
// Wait for controls to be defined before attaching form listeners // Wait for controls to be defined before attaching form listeners
await Promise.all([ await Promise.all([customElements.whenDefined('wa-button'), customElements.whenDefined('wa-input')]).then(() => {
customElements.whenDefined('wa-button'),
customElements.whenDefined('wa-input')
]).then(() => {
form.addEventListener('submit', event => { form.addEventListener('submit', event => {
event.preventDefault(); event.preventDefault();
alert('All fields are valid!'); alert('All fields are valid!');
@@ -163,17 +154,15 @@ Custom validation can be applied to any form control that supports the `setCusto
## Custom Validation Styles ## Custom Validation Styles
Due to the many ways form controls are used, Web Awesome doesn't provide out of the box validation styles for form controls as part of its default theme. Instead, the following attributes will be applied to reflect a control's validity as users interact with it. You can use them to create custom styles for any of the validation states you're interested in. Due to the many ways form controls are used, Web Awesome doesn't provide out of the box validation styles for form controls as part of its default theme.
- `required` - the form control is required Instead, the following [custom states](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/states) will be applied to reflect a control's validity as users interact with it. You can use them to create custom styles for any of the validation states you're interested in.
- `optional` - the form control is optional
- `invalid` - the form control is invalid
- `valid` - the form control is valid
- `user-invalid` - the form control is invalid and the user has interacted with it
- `user-valid` - the form control is valid and the user has interacted with it
These attributes map to the browser's built-in pseudo classes for validation: [`:required`](https://developer.mozilla.org/en-US/docs/Web/CSS/:required), [`:optional`](https://developer.mozilla.org/en-US/docs/Web/CSS/:optional), [`:invalid`](https://developer.mozilla.org/en-US/docs/Web/CSS/:invalid), [`:valid`](https://developer.mozilla.org/en-US/docs/Web/CSS/:valid), [`:user-invalid`](https://developer.mozilla.org/en-US/docs/Web/CSS/:user-invalid), and [`:user-valid`](https://developer.mozilla.org/en-US/docs/Web/CSS/:user-valid). - `:state(required)` - the form control is required
- `:state(optional)` - the form control is optional
- `:state(invalid)` - the form control is invalid
- `:state(valid)` - the form control is valid
- `:state(user-invalid)` - the form control is invalid and the user has interacted with it
- `:state(user-valid)` - the form control is valid and the user has interacted with it
:::info These custom states work alongside the browser's built-in pseudo classes for validation: [`:required`](https://developer.mozilla.org/en-US/docs/Web/CSS/:required), [`:optional`](https://developer.mozilla.org/en-US/docs/Web/CSS/:optional), [`:invalid`](https://developer.mozilla.org/en-US/docs/Web/CSS/:invalid), [`:valid`](https://developer.mozilla.org/en-US/docs/Web/CSS/:valid), [`:user-invalid`](https://developer.mozilla.org/en-US/docs/Web/CSS/:user-invalid), and [`:user-valid`](https://developer.mozilla.org/en-US/docs/Web/CSS/:user-valid).
In the future, data attribute selectors will be replaced with custom states such as `:state(valid)` and `:state(invalid)`. Web Awesome is using data attributes as a workaround until browsers fully support [custom states](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/states).
:::

View File

@@ -4,7 +4,7 @@ description: Choose the installation method that works best for you.
layout: page-outline layout: page-outline
--- ---
Welcome to Web Awesome beta! [Learn more](https://webawesome.com/) about this project and [how to contribute to it](https://webawesome.com/docs/resources/contributing). Welcome to Web Awesome! [Learn more](https://webawesome.com/) about this project and [how to contribute to it](https://webawesome.com/docs/resources/contributing).
- [Report a bug](https://github.com/shoelace-style/webawesome/issues) - [Report a bug](https://github.com/shoelace-style/webawesome/issues)
- [Get help / ask a question](https://github.com/shoelace-style/webawesome/discussions) - [Get help / ask a question](https://github.com/shoelace-style/webawesome/discussions)
@@ -212,4 +212,4 @@ declare module 'react' {
:::details React 18 and below :::details React 18 and below
React 18 and below have [poor support](https://custom-elements-everywhere.com/#react) for custom elements. For legacy versions of React, we provide React wrappers for every component. You can find the import instructions by selecting the _React_ tab from the _Importing_ section of each React 18 and below have [poor support](https://custom-elements-everywhere.com/#react) for custom elements. For legacy versions of React, we provide React wrappers for every component. You can find the import instructions by selecting the _React_ tab from the _Importing_ section of each
component's documentation. component's documentation.
::: :::

View File

@@ -18,9 +18,12 @@ Components with the <wa-badge variant="warning">Experimental</wa-badge> badge sh
- Fixed a bug in `<wa-button>` where slotted badges weren't properly positioned in buttons with an `href` [issue:1377] - Fixed a bug in `<wa-button>` where slotted badges weren't properly positioned in buttons with an `href` [issue:1377]
- Fixed focus outline styles in `<wa-details>` and native `<details>` [issue:1456] - Fixed focus outline styles in `<wa-details>` and native `<details>` [issue:1456]
- Fixed focus outline styles in `<wa-scroller>`, `<wa-dialog>`, and `<wa-drawer>` [issue:1484] - Fixed focus outline styles in `<wa-scroller>`, `<wa-dialog>`, and `<wa-drawer>` [issue:1484]
- Fixed a bug in `<wa-checkbox>` where its value would revert to `""` when checked / unchecked [pr:1547]
- Fixed a bug that caused icon button labels to not render in frameworks [issue:1542] - Fixed a bug that caused icon button labels to not render in frameworks [issue:1542]
- Fixed a bug in `<wa-details>` that caused the `name` property not to reflect [pr:1538] - Fixed a bug in `<wa-details>` that caused the `name` property not to reflect [pr:1538]
- Fixed a bug in `<wa-dialog>` and `<wa-drawer>` that prevented focus from being set on the dialog/drawer when opened [issue:1302] - Fixed a bug in `<wa-dialog>` and `<wa-drawer>` that prevented focus from being set on the dialog/drawer when opened [issue:1302]
- Fixed an overflow style that was causing tab group content to be unnecessarily truncated [issue:1401]
- Fixed a bug in `<wa-icon>` that caused icon buttons to render when non-text nodes were slotted in [issue:1475]
## 3.0.0-beta.6 ## 3.0.0-beta.6
@@ -464,4 +467,4 @@ Many of these changes and improvements were the direct result of feedback from u
</details> </details>
Did we miss something? [Let us know!](https://github.com/shoelace-style/webawesome/discussions) Did we miss something? [Let us know!](https://github.com/shoelace-style/webawesome/discussions)

View File

@@ -182,25 +182,6 @@ layout: page
} }
} }
} }
.beta-notice {
display: flex;
flex-wrap: wrap;
gap: 1rem;
& > * {
flex-basis: calc(((30ch * 2 + 1rem) - 100%) * 999);
}
& > * {
flex-grow: 2;
}
& > * + * {
flex-grow: 1;
}
& wa-callout,
& wa-button::part(base) {
height: 100%;
width: 100%;
}
}
wa-button.tile::part(base) { wa-button.tile::part(base) {
border-color: var(--wa-color-surface-border); border-color: var(--wa-color-surface-border);
border-radius: 0.75rem; border-radius: 0.75rem;
@@ -280,33 +261,18 @@ layout: page
</div> </div>
<div class="home-wrapper"> <div class="home-wrapper">
<div class="beta-notice"> <wa-button href="/docs/" appearance="outlined" class="tile">
<div> <div class="wa-stack">
<wa-callout variant="brand"> <div class="wa-split">
<div class="wa-stack"> <div class="wa-cluster icon-heading">
<div class="wa-cluster icon-heading"> <wa-icon name="pen-ruler" class="brand-orange"></wa-icon>
<wa-icon name="sparkles" variant="regular"></wa-icon> <h3>Get started</h3>
<h3>Bigger and beta than ever</h3>
</div>
<p>This beta is battle-tested and built to last, but if you see something, say something. Please <a href="https://github.com/shoelace-style/webawesome/issues">report bugs</a> or <a href="https://github.com/shoelace-style/webawesome/discussions">ask for help</a>!</p>
</div> </div>
</wa-callout> <wa-icon name="arrow-right"></wa-icon>
</div>
<p>Check out our installation guide to start building with Web Awesome.</p>
</div> </div>
<div> </wa-button>
<wa-button href="/docs/" appearance="outlined" class="tile">
<div class="wa-stack">
<div class="wa-split">
<div class="wa-cluster icon-heading">
<wa-icon name="pen-ruler" class="brand-orange"></wa-icon>
<h3>Get started</h3>
</div>
<wa-icon name="arrow-right"></wa-icon>
</div>
<p>Check out our installation guide to start building with Web Awesome.</p>
</div>
</wa-button>
</div>
</div>
<wa-divider></wa-divider> <wa-divider></wa-divider>
<div class="summary"> <div class="summary">
<h2 class="brand-font">What's <span class="emphasis">Web</span> Awesome?</h2> <h2 class="brand-font">What's <span class="emphasis">Web</span> Awesome?</h2>

View File

@@ -18,6 +18,7 @@ import { getCdnDir, getDistDir, getDocsDir, getRootDir, getSiteDir } from './uti
const __dirname = dirname(fileURLToPath(import.meta.url)); const __dirname = dirname(fileURLToPath(import.meta.url));
const currentYear = new Date().getFullYear();
const spinner = ora({ text: 'Web Awesome', color: 'cyan' }).start(); const spinner = ora({ text: 'Web Awesome', color: 'cyan' }).start();
const getPackageData = async () => JSON.parse(await readFile(join(getRootDir(), 'package.json'), 'utf-8')); const getPackageData = async () => JSON.parse(await readFile(join(getRootDir(), 'package.json'), 'utf-8'));
const getVersion = async () => JSON.stringify((await getPackageData()).version.toString()); const getVersion = async () => JSON.stringify((await getPackageData()).version.toString());
@@ -225,6 +226,9 @@ export async function build(options = {}) {
bundle: true, bundle: true,
splitting: true, splitting: true,
minify: false, minify: false,
banner: {
js: `/*! Copyright ${currentYear} Fonticons, Inc. - https://webawesome.com/license */`,
},
plugins: [replace({ __WEBAWESOME_VERSION__: await getVersion() })], plugins: [replace({ __WEBAWESOME_VERSION__: await getVersion() })],
loader: { loader: {
'.css': 'text', '.css': 'text',

View File

@@ -176,22 +176,32 @@ export default class WaButton extends WebAwesomeFormAssociatedElement {
const nodes = this.labelSlot.assignedNodes({ flatten: true }); const nodes = this.labelSlot.assignedNodes({ flatten: true });
let hasIconLabel = false; let hasIconLabel = false;
let hasIcon = false; let hasIcon = false;
let text = ''; let hasText = false;
let hasOtherElements = false;
// If there's only an icon and no text, it's an icon button // Check all slotted nodes
[...nodes].forEach(node => { [...nodes].forEach(node => {
if (node.nodeType === Node.ELEMENT_NODE && (node as WaIcon).localName === 'wa-icon') { if (node.nodeType === Node.ELEMENT_NODE) {
hasIcon = true; const element = node as HTMLElement;
if (!hasIconLabel) hasIconLabel = (node as WaIcon).label !== undefined;
}
// Concatenate text nodes if (element.localName === 'wa-icon') {
if (node.nodeType === Node.TEXT_NODE) { hasIcon = true;
text += node.textContent; if (!hasIconLabel) hasIconLabel = (element as WaIcon).label !== undefined;
} else {
// Any other element type means it's not an icon button
hasOtherElements = true;
}
} else if (node.nodeType === Node.TEXT_NODE) {
// Check if text node has actual content
const text = node.textContent?.trim() || '';
if (text.length > 0) {
hasText = true;
}
} }
}); });
this.isIconButton = text.trim() === '' && hasIcon; // It's only an icon button if there's an icon and nothing else
this.isIconButton = hasIcon && !hasText && !hasOtherElements;
if (this.isIconButton && !hasIconLabel) { if (this.isIconButton && !hasIconLabel) {
console.warn( console.warn(

View File

@@ -21,7 +21,7 @@ describe('<wa-checkbox>', () => {
const el = await fixture<WaCheckbox>(html` <wa-checkbox></wa-checkbox> `); const el = await fixture<WaCheckbox>(html` <wa-checkbox></wa-checkbox> `);
expect(el.name).to.equal(''); expect(el.name).to.equal('');
expect(el.value).to.equal('on'); expect(el.value).to.equal(null);
expect(el.title).to.equal(''); expect(el.title).to.equal('');
expect(el.disabled).to.be.false; expect(el.disabled).to.be.false;
expect(el.required).to.be.false; expect(el.required).to.be.false;
@@ -134,7 +134,7 @@ describe('<wa-checkbox>', () => {
await checkbox.updateComplete; await checkbox.updateComplete;
expect(checkbox.checked).to.equal(false); expect(checkbox.checked).to.equal(false);
expect(checkbox.value).to.equal('myvalue'); expect(checkbox.value).to.equal(null);
expect(new FormData(form).get('test')).to.equal(null); expect(new FormData(form).get('test')).to.equal(null);
checkbox.checked = true; checkbox.checked = true;

View File

@@ -80,7 +80,8 @@ export default class WaCheckbox extends WebAwesomeFormAssociatedElement {
/** The value of the checkbox, submitted as a name/value pair with form data. */ /** The value of the checkbox, submitted as a name/value pair with form data. */
get value(): string | null { get value(): string | null {
return this._value ?? 'on'; const val = this._value || 'on';
return this.checked ? val : null;
} }
@property({ reflect: true }) @property({ reflect: true })

View File

@@ -47,7 +47,7 @@ export default class WaRadio extends WebAwesomeFormAssociatedElement {
/** The radio's value. When selected, the radio group will receive this value. */ /** The radio's value. When selected, the radio group will receive this value. */
@property({ reflect: true }) value: string; @property({ reflect: true }) value: string;
/** The radio's value. When selected, the radio group will receive this value. */ /** The radio's visual appearance. */
@property({ reflect: true }) appearance: 'default' | 'button' = 'default'; @property({ reflect: true }) appearance: 'default' | 'button' = 'default';
/** /**

View File

@@ -27,7 +27,6 @@
.body { .body {
display: block; display: block;
overflow: auto;
} }
.scroll-button { .scroll-button {