diff --git a/package-lock.json b/package-lock.json
index 174475f77..7aa7c731d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -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",
diff --git a/packages/webawesome/docs/_includes/head.njk b/packages/webawesome/docs/_includes/head.njk
index e5cd41b5c..36efab00d 100644
--- a/packages/webawesome/docs/_includes/head.njk
+++ b/packages/webawesome/docs/_includes/head.njk
@@ -26,5 +26,17 @@
{% endfor %}
+
+
{# Used by Web Awesome App to inject other assets into the head. #}
{% server "head" %}
diff --git a/packages/webawesome/docs/_includes/sidebar.njk b/packages/webawesome/docs/_includes/sidebar.njk
index 6af15e91a..18ed29c1f 100644
--- a/packages/webawesome/docs/_includes/sidebar.njk
+++ b/packages/webawesome/docs/_includes/sidebar.njk
@@ -31,16 +31,19 @@
-
- Page
-
- PRO
+
+
+ Page
+
+ PRO
+
- Animated Image
- Animation
@@ -57,12 +60,16 @@
- Callout
- Card
-
- Carousel
-
+
+ Carousel
+
+
@@ -70,8 +77,10 @@
- Color Picker
- Comparison
-
- Copy Button
-
+
+ Copy Button
+
+
- Details
- Dialog
@@ -136,9 +145,9 @@
@@ -154,9 +163,9 @@
@@ -179,15 +191,17 @@
-
- App
- PRO
+
+ App
+ PRO
+
-
- Blog & News
- PRO
+
+ Blog & News
+ PRO
+
-
- Ecommerce
- PRO
+
+ Ecommerce
+ PRO
+
-
- Layouts
- PRO
+
+ Layouts
+ PRO
+
diff --git a/packages/webawesome/docs/assets/styles/docs.css b/packages/webawesome/docs/assets/styles/docs.css
index 93ebd9527..dfd417d68 100644
--- a/packages/webawesome/docs/assets/styles/docs.css
+++ b/packages/webawesome/docs/assets/styles/docs.css
@@ -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 */
diff --git a/packages/webawesome/docs/docs/resources/changelog.md b/packages/webawesome/docs/docs/resources/changelog.md
index 7a36acb23..6fe49fdaf 100644
--- a/packages/webawesome/docs/docs/resources/changelog.md
+++ b/packages/webawesome/docs/docs/resources/changelog.md
@@ -29,6 +29,8 @@ Components with the Experimental badge sh
- Fixed a bug in `` that prevented the thumb from receiving focus when clicking/tapping [issue:1312]
- Fixed a bug in `` that caused the shadow to appear below relatively-positioned elements [issue:1326]
- Fixed a bug in `` that caused it to expand/collapse when clicking on interactive elements in the summary [issue:1252]
+- Fixed `` to have `static` positioning by default and `relative` positioning only when used with `` [pr:1346]
+- Fixed spacing in `` when both clear and password toggle icons are present [issue:1325]
## 3.0.0-beta.4
diff --git a/packages/webawesome/docs/index.md b/packages/webawesome/docs/index.md
index 0efecb8b4..49188f8fd 100644
--- a/packages/webawesome/docs/index.md
+++ b/packages/webawesome/docs/index.md
@@ -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 {
diff --git a/packages/webawesome/src/components/button/button.css b/packages/webawesome/src/components/button/button.css
index 68aa78c1a..a3b0e1783 100644
--- a/packages/webawesome/src/components/button/button.css
+++ b/packages/webawesome/src/components/button/button.css
@@ -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;
}
}
diff --git a/packages/webawesome/src/components/icon/library.system.ts b/packages/webawesome/src/components/icon/library.system.ts
index 8012a6e5c..ffbdb9d91 100644
--- a/packages/webawesome/src/components/icon/library.system.ts
+++ b/packages/webawesome/src/components/icon/library.system.ts
@@ -9,31 +9,31 @@ export const icons: { [key: string]: { [key: string]: string } } = {
// Solid variant
//
solid: {
- check: ``,
- 'chevron-down': ``,
- 'chevron-left': ``,
- 'chevron-right': ``,
- circle: ``,
- eyedropper: ``,
- 'grip-vertical': ``,
+ check: ``,
+ 'chevron-down': ``,
+ 'chevron-left': ``,
+ 'chevron-right': ``,
+ circle: ``,
+ eyedropper: ``,
+ 'grip-vertical': ``,
indeterminate: ``,
- minus: ``,
- pause: ``,
- play: ``,
- star: ``,
- user: ``,
- xmark: ``,
+ minus: ``,
+ pause: ``,
+ play: ``,
+ star: ``,
+ user: ``,
+ xmark: ``,
},
//
// Regular variant
//
regular: {
- 'circle-question': ``,
- 'circle-xmark': ``,
- copy: ``,
- eye: ``,
- 'eye-slash': ``,
- star: ``,
+ 'circle-question': ``,
+ 'circle-xmark': ``,
+ copy: ``,
+ eye: ``,
+ 'eye-slash': ``,
+ star: ``,
},
};
diff --git a/packages/webawesome/src/components/input/input.css b/packages/webawesome/src/components/input/input.css
index e0a12fe7d..6aae262f7 100644
--- a/packages/webawesome/src/components/input/input.css
+++ b/packages/webawesome/src/components/input/input.css
@@ -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 {
diff --git a/packages/webawesome/src/components/page/page.css b/packages/webawesome/src/components/page/page.css
deleted file mode 100644
index 812debb1a..000000000
--- a/packages/webawesome/src/components/page/page.css
+++ /dev/null
@@ -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);
-}
diff --git a/packages/webawesome/src/components/page/page.mobile.styles.ts b/packages/webawesome/src/components/page/page.mobile.styles.ts
deleted file mode 100644
index 6338be789..000000000
--- a/packages/webawesome/src/components/page/page.mobile.styles.ts
+++ /dev/null
@@ -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;
- }
- }
-`;
diff --git a/packages/webawesome/src/components/page/page.test.ts b/packages/webawesome/src/components/page/page.test.ts
deleted file mode 100644
index b5e049e4d..000000000
--- a/packages/webawesome/src/components/page/page.test.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { expect } from '@open-wc/testing';
-import { html } from 'lit';
-import { fixtures } from '../../internal/test/fixture.js';
-
-describe('', () => {
- for (const fixture of fixtures) {
- describe(`with "${fixture.type}" rendering`, () => {
- it('should render a component', async () => {
- const el = await fixture(html` `);
-
- expect(el).to.exist;
- });
- });
- }
-});
diff --git a/packages/webawesome/src/components/page/page.ts b/packages/webawesome/src/components/page/page.ts
deleted file mode 100644
index 55089e237..000000000
--- a/packages/webawesome/src/components/page/page.ts
+++ /dev/null
@@ -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) {}
- // eslint-disable-next-line
- observe(..._args: Parameters) {}
- // eslint-disable-next-line
- unobserve(..._args: Parameters) {}
- // eslint-disable-next-line
- disconnect(..._args: Parameters) {}
- };
-}
-
-//
-// 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: '',
- 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 ``.
- * @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 ``.
- * @slot navigation-toggle - Use this slot to slot in your own button + icon for toggling the navigation drawer. By default it is a `` + a 3 bars ``
- * @slot navigation-toggle-icon - Use this to slot in your own icon for toggling the navigation drawer. By default it is 3 bars ``.
- * @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 `