Fix broken demo, improve passthrough CSS (#879)

Fixes several issues for components using the `display: contents` technique:
- Introduce `--display` CSS property to make it possible to override internal display value of base part.
- Ensure `display: contents` is always applied with `!important` to avoid rendering glitches like the one here
- Ensure non-inherited custom properties are also inherited
- Ensure the `hidden` attribute still works.
This commit is contained in:
Lea Verou
2025-04-23 11:52:23 -04:00
committed by GitHub
parent 7545f04c46
commit cfc3f181a3
10 changed files with 43 additions and 23 deletions

View File

@@ -27,6 +27,7 @@ See your theme's focus ring in action by navigating this form example with your
<style>
form > * + * {
display: block;
--display: block;
width: fit-content;
margin-block-start: var(--wa-space-m);
}

View File

@@ -1,11 +1,7 @@
:host {
display: contents;
position: relative;
}
--display: inline-flex;
:where([part~='base']) {
all: inherit;
display: inline-flex;
position: relative;
}
/*

View File

@@ -7,6 +7,7 @@ import { MirrorValidator } from '../../internal/validators/mirror-validator.js';
import { watch } from '../../internal/watch.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
import nativeStyles from '../../styles/native/button.css';
import passthroughStyles from '../../styles/shadow/passthrough.css';
import appearanceStyles from '../../styles/utilities/appearance.css';
import sizeStyles from '../../styles/utilities/size.css';
import variantStyles from '../../styles/utilities/variants.css';
@@ -39,6 +40,7 @@ import styles from './button.css';
* @csspart caret - The button's caret icon, a `<wa-icon>` element.
* @csspart spinner - The spinner that shows when the button is in the loading state.
*
* @cssproperty --display - Set to `none` to hide the element, or any other valid `display` value to override the internal `display` value of the `base` part.
* @cssproperty --background-color - The button's background color when the button is not being interacted with.
* @cssproperty --background-color-active - The button's background color when active.
* @cssproperty --background-color-hover - The button's background color on hover.
@@ -51,7 +53,7 @@ import styles from './button.css';
*/
@customElement('wa-button')
export default class WaButton extends WebAwesomeFormAssociatedElement {
static shadowStyle = [variantStyles, appearanceStyles, sizeStyles, nativeStyles, styles];
static shadowStyle = [passthroughStyles, variantStyles, appearanceStyles, sizeStyles, nativeStyles, styles];
static rectProxy = 'button';
static get validators() {

View File

@@ -1,13 +1,10 @@
:host {
--show-duration: 200ms;
--hide-duration: 200ms;
display: contents !important;
--display: block;
}
details {
all: inherit;
display: block;
overflow-anchor: none;
}

View File

@@ -9,6 +9,7 @@ import { getTargetElement, waitForEvent } from '../../internal/event.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import nativeStyles from '../../styles/native/details.css';
import passthroughStyles from '../../styles/shadow/passthrough.css';
import appearanceStyles from '../../styles/utilities/appearance.css';
import { LocalizeController } from '../../utilities/localize.js';
import '../icon/icon.js';
@@ -43,10 +44,11 @@ import styles from './details.css';
* @cssproperty --spacing - The amount of space around and between the details' content. Expects a single value.
* @cssproperty [--show-duration=200ms] - The show duration to use when applying built-in animation classes.
* @cssproperty [--hide-duration=200ms] - The hide duration to use when applying built-in animation classes.
* @cssproperty --display - Set to `none` to hide the element, or any other valid `display` value to override the internal `display` value of the `base` part.
*/
@customElement('wa-details')
export default class WaDetails extends WebAwesomeElement {
static shadowStyle = [appearanceStyles, nativeStyles, styles];
static shadowStyle = [passthroughStyles, appearanceStyles, nativeStyles, styles];
private detailsObserver: MutationObserver;
private readonly localize = new LocalizeController(this);

View File

@@ -1,7 +1,7 @@
:host {
--indicator-color: var(--wa-color-brand-fill-loud);
--display: flex;
display: contents;
height: 1.25rem;
border-radius: var(--wa-border-radius-pill);
background-color: var(--wa-color-neutral-fill-normal);
@@ -9,8 +9,6 @@
}
.progress-bar {
all: inherit;
display: flex;
position: relative;
overflow: hidden;
}

View File

@@ -4,6 +4,7 @@ import { customElement, property } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { clamp } from '../../internal/math.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import passthroughStyles from '../../styles/shadow/passthrough.css';
import { LocalizeController } from '../../utilities/localize.js';
import styles from './progress-bar.css';
@@ -20,10 +21,11 @@ import styles from './progress-bar.css';
* @csspart label - The progress bar's label.
*
* @cssproperty --indicator-color - The color of the indicator.
* @cssproperty --display - Set to `none` to hide the element, or any other valid `display` value to override the internal `display` value of the `base` part.
*/
@customElement('wa-progress-bar')
export default class WaProgressBar extends WebAwesomeElement {
static shadowStyle = styles;
static shadowStyle = [passthroughStyles, styles];
private readonly localize = new LocalizeController(this);
/** The current progress as a percentage, 0 to 100. */

View File

@@ -1,10 +1,5 @@
:host {
display: contents;
}
:where([part~='base']) {
all: inherit;
display: inline-flex;
--display: inline-flex;
}
.prefix,

View File

@@ -6,6 +6,7 @@ import { HasSlotController } from '../../internal/slot.js';
import { watch } from '../../internal/watch.js';
import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-associated-element.js';
import nativeStyles from '../../styles/native/button.css';
import passthroughStyles from '../../styles/shadow/passthrough.css';
import appearanceStyles from '../../styles/utilities/appearance.css';
import sizeStyles from '../../styles/utilities/size.css';
import variantStyles from '../../styles/utilities/variants.css';
@@ -45,10 +46,11 @@ import styles from './radio-button.css';
* @csspart prefix - The container that wraps the prefix.
* @csspart label - The container that wraps the radio button's label.
* @csspart suffix - The container that wraps the suffix.
* @cssproperty --display - Set to `none` to hide the element, or any other valid `display` value to override the internal `display` value of the `base` part.
*/
@customElement('wa-radio-button')
export default class WaRadioButton extends WebAwesomeFormAssociatedElement {
static shadowStyle = [variantStyles, appearanceStyles, sizeStyles, nativeStyles, styles];
static shadowStyle = [passthroughStyles, variantStyles, appearanceStyles, sizeStyles, nativeStyles, styles];
static rectProxy = 'input';
private readonly hasSlotController = new HasSlotController(this, '[default]', 'prefix', 'suffix');

View File

@@ -0,0 +1,25 @@
/**
* Styles for elements that need to use display: contents on the host to enable styling with regular CSS properties (see #207, #259).
* To use, make sure that the element that needs to inherit properties set on the host has a part of base or a class of .styling-host.
*/
@property --display {
syntax: '*';
inherits: false;
}
:host {
display: contents !important;
}
:where([part~='base'], .styling-host) {
all: inherit;
/* Add any non-inherited custom properties here, as all: inherit won't cover them */
--display: inherit;
display: var(--display, inline);
}
:host([hidden]) {
display: none !important;
}