mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-12 04:09:12 +00:00
CSS custom properties to set certain component attributes (#447)
This commit is contained in:
@@ -24,6 +24,86 @@ Many Font Awesome Pro icon families have variants such as `thin`, `light`, `regu
|
||||
<wa-icon family="brands" name="web-awesome"></wa-icon>
|
||||
```
|
||||
|
||||
### Setting defaults via CSS
|
||||
|
||||
You can use certain CSS custom properties to set icon defaults, not just on the icon itself, but any ancestor.
|
||||
This can be useful when you want certain parameters to vary based on context, e.g. icons inside callouts or all icons for a given theme.
|
||||
|
||||
:::warning
|
||||
These CSS properties are intended to set **defaults**, and thus only make a difference when the corresponding attributes are not set.
|
||||
In future versions of Web Awesome, we may change this behavior to allow CSS properties to override attributes if `!important` is used.
|
||||
:::
|
||||
|
||||
For example, here is how you can use CSS custom properties to set a default icon for each type of callout:
|
||||
|
||||
```html {.example}
|
||||
<wa-callout>
|
||||
<!-- Look ma, no attributes! -->
|
||||
<wa-icon slot="icon"></wa-icon>
|
||||
This is a normal callout.
|
||||
</wa-callout>
|
||||
|
||||
<wa-callout variant="danger">
|
||||
<wa-icon slot="icon" name="dumpster-fire" variant="solid"></wa-icon>
|
||||
This is a callout with an explicit icon, which overrides these defaults.
|
||||
</wa-callout>
|
||||
|
||||
<wa-callout variant="warning">
|
||||
<!-- Look ma, no attributes! -->
|
||||
<wa-icon slot="icon"></wa-icon>
|
||||
Here be dragons.
|
||||
</wa-callout>
|
||||
|
||||
<wa-callout variant="danger">
|
||||
<!-- Look ma, no attributes! -->
|
||||
<wa-icon slot="icon"></wa-icon>
|
||||
Here be more dragons.
|
||||
</wa-callout>
|
||||
|
||||
<wa-callout variant="success">
|
||||
<!-- Look ma, no attributes! -->
|
||||
<wa-icon slot="icon"></wa-icon>
|
||||
Success!
|
||||
</wa-callout>
|
||||
|
||||
<style>
|
||||
wa-callout {
|
||||
--wa-icon-variant: regular;
|
||||
--wa-icon-name: info-circle;
|
||||
|
||||
&[variant="warning"] {
|
||||
--wa-icon-name: triangle-exclamation;
|
||||
}
|
||||
|
||||
&[variant="danger"] {
|
||||
--wa-icon-name: circle-exclamation;
|
||||
}
|
||||
|
||||
&[variant="success"] {
|
||||
--wa-icon-name: circle-check;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
You can even set icons dynamically, as a response to user interaction or media queries.
|
||||
For example, here's how we can change the icon on hover:
|
||||
|
||||
```html {.example}
|
||||
<wa-button class="github" href="https://github.com/webawesome/webawesome"><wa-icon slot="prefix" fixed-width></wa-icon> GitHub Repo</wa-button>
|
||||
<style>
|
||||
.github {
|
||||
--wa-icon-name: github;
|
||||
--wa-icon-family: brands;
|
||||
|
||||
&:hover {
|
||||
--wa-icon-name: arrow-up-right-from-square;
|
||||
--wa-icon-family: classic;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
### Colors
|
||||
|
||||
Icons inherit their color from the current text color. Thus, you can set the `color` property on the `<wa-icon>` element or an ancestor to change the color.
|
||||
|
||||
71
docs/docs/test/benchmark.njk
Normal file
71
docs/docs/test/benchmark.njk
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
title: CSS Properties Benchmark
|
||||
unlisted: true
|
||||
wide: true
|
||||
---
|
||||
|
||||
{% set icons = {
|
||||
check: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="14" 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>',
|
||||
'chevron-down': '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 512 512"><path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z"/></svg>',
|
||||
'chevron-left': '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="10" viewBox="0 0 320 512"><path 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" 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>',
|
||||
circle: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 512 512"><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z"/></svg>',
|
||||
'eye-dropper': '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 512 512"><path d="M341.6 29.2L240.1 130.8l-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.4L482.8 170.4c39-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.6v42.4L5.4 462.2c-8.5 12.7-6.8 29.6 4 40.4s27.7 12.5 40.4 4L89.7 480h42.4c21.2 0 41.6-8.4 56.6-23.4L309.4 335.9l-45.3-45.3L143.4 411.3c-3 3-7.1 4.7-11.3 4.7H96V379.9c0-4.2 1.7-8.3 4.7-11.3L221.4 247.9l-45.3-45.3L55.4 323.3z"/></svg>',
|
||||
'grip-vertical': '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="10" viewBox="0 0 320 512"><path d="M40 352l48 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-40l0-48c0-22.1 17.9-40 40-40zm192 0l48 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-40l0-48c0-22.1 17.9-40 40-40zM40 320c-22.1 0-40-17.9-40-40l0-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 0zM232 192l48 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-40l0-48c0-22.1 17.9-40 40-40zM40 160c-22.1 0-40-17.9-40-40L0 72C0 49.9 17.9 32 40 32l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0zM232 32l48 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-40l0-48c0-22.1 17.9-40 40-40z"/></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"></path></g></g></g></svg>',
|
||||
minus: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="14" viewBox="0 0 448 512"><path d="M432 256c0 17.7-14.3 32-32 32L48 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l352 0c17.7 0 32 14.3 32 32z"/></svg>',
|
||||
pause: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="10" viewBox="0 0 320 512"><path d="M48 64C21.5 64 0 85.5 0 112V400c0 26.5 21.5 48 48 48H80c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48H48zm192 0c-26.5 0-48 21.5-48 48V400c0 26.5 21.5 48 48 48h32c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48H240z"/></svg>',
|
||||
play: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="12" viewBox="0 0 384 512"><path d="M73 39c-14.8-9.1-33.4-9.4-48.5-.9S0 62.6 0 80V432c0 17.4 9.4 33.4 24.5 41.9s33.7 8.1 48.5-.9L361 297c14.3-8.7 23-24.2 23-41s-8.7-32.2-23-41L73 39z"/></svg>',
|
||||
star: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="18" viewBox="0 0 576 512"><path d="M316.9 18C311.6 7 300.4 0 288.1 0s-23.4 7-28.8 18L195 150.3 51.4 171.5c-12 1.8-22 10.2-25.7 21.7s-.7 24.2 7.9 32.7L137.8 329 113.2 474.7c-2 12 3 24.2 12.9 31.3s23 8 33.8 2.3l128.3-68.5 128.3 68.5c10.8 5.7 23.9 4.9 33.8-2.3s14.9-19.3 12.9-31.3L438.5 329 542.7 225.9c8.6-8.5 11.7-21.2 7.9-32.7s-13.7-19.9-25.7-21.7L381.2 150.3 316.9 18z"/></svg>',
|
||||
user: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="14" viewBox="0 0 448 512"><path d="M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512H418.3c16.4 0 29.7-13.3 29.7-29.7C448 383.8 368.2 304 269.7 304H178.3z"/></svg>',
|
||||
xmark: '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="12" viewBox="0 0 384 512"><path d="M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z"/></svg>'
|
||||
} %}
|
||||
|
||||
<style>
|
||||
.icon-tests {
|
||||
font-size: .5rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
wa-icon {
|
||||
transition: 1s font-size;
|
||||
&:hover {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
{% set repetitions = 200 %}
|
||||
|
||||
<h2>Setting everything via attributes</h2>
|
||||
|
||||
<div class="icon-tests">
|
||||
{% for icon, svg in icons %}
|
||||
{% for i in range(repetitions) %}
|
||||
<wa-icon name="{{ icon }}" variant="solid" family="classic"></wa-icon>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<h2>Setting variant & family via CSS</h2>
|
||||
|
||||
<div class="icon-tests" style="--wa-icon-variant: regular; --wa-icon-family: classic">
|
||||
{% for icon, svg in icons %}
|
||||
{% for i in range(repetitions) %}
|
||||
<wa-icon name="{{ icon }}"></wa-icon>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<h2>Setting name via CSS</h2>
|
||||
|
||||
<div class="icon-tests">
|
||||
{% for icon, svg in icons %}
|
||||
<span style="--wa-icon-name: {{ icon }}">
|
||||
{% for i in range(repetitions) %}
|
||||
<wa-icon variant="solid" family="classic"></wa-icon>
|
||||
{% endfor %}
|
||||
</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
9
package-lock.json
generated
9
package-lock.json
generated
@@ -15,7 +15,8 @@
|
||||
"@shoelace-style/localize": "^3.2.1",
|
||||
"composed-offset-position": "^0.0.6",
|
||||
"lit": "^3.2.1",
|
||||
"qr-creator": "^1.0.0"
|
||||
"qr-creator": "^1.0.0",
|
||||
"style-observer": "^0.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@11ty/eleventy": "3.0.0",
|
||||
@@ -13087,6 +13088,12 @@
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/style-observer": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/style-observer/-/style-observer-0.0.7.tgz",
|
||||
"integrity": "sha512-t75H3CRy+vd5q3yqyrf/De4tkz33hPQTiCcfh0NTesI5G7kJnZ227LEYTwqjKTtaFOCJvqZcYFHpJlF8bsk3bQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
|
||||
@@ -73,7 +73,8 @@
|
||||
"@shoelace-style/localize": "^3.2.1",
|
||||
"composed-offset-position": "^0.0.6",
|
||||
"lit": "^3.2.1",
|
||||
"qr-creator": "^1.0.0"
|
||||
"qr-creator": "^1.0.0",
|
||||
"style-observer": "^0.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@11ty/eleventy": "3.0.0",
|
||||
|
||||
@@ -48,21 +48,21 @@ export default class WaIcon extends WebAwesomeElement {
|
||||
@state() private svg: SVGElement | HTMLTemplateResult | null = null;
|
||||
|
||||
/** The name of the icon to draw. Available names depend on the icon library being used. */
|
||||
@property({ reflect: true }) name?: string;
|
||||
@property({ cssProperty: '--wa-icon-name' }) name?: string;
|
||||
|
||||
/**
|
||||
* The family of icons to choose from. For Font Awesome Free (default), valid options include `classic` and `brands`.
|
||||
* For Font Awesome Pro subscribers, valid options include, `classic`, `sharp`, `duotone`, and `brands`. Custom icon
|
||||
* libraries may or may not use this property.
|
||||
*/
|
||||
@property({ reflect: true }) family: string;
|
||||
@property({ cssProperty: '--wa-icon-family' }) family: string;
|
||||
|
||||
/**
|
||||
* The name of the icon's variant. For Font Awesome, valid options include `thin`, `light`, `regular`, and `solid` for
|
||||
* the `classic` and `sharp` families. Some variants require a Font Awesome Pro subscription. Custom icon libraries
|
||||
* may or may not use this property.
|
||||
*/
|
||||
@property({ reflect: true }) variant: string;
|
||||
@property({ cssProperty: '--wa-icon-variant' }) variant: string;
|
||||
|
||||
/** Draws the icon in a fixed-width both. */
|
||||
@property({ attribute: 'fixed-width', type: Boolean, reflect: true }) fixedWidth: false;
|
||||
@@ -80,14 +80,16 @@ export default class WaIcon extends WebAwesomeElement {
|
||||
@property() label = '';
|
||||
|
||||
/** The name of a registered custom icon library. */
|
||||
@property({ reflect: true }) library = 'default';
|
||||
@property({ cssProperty: '--wa-icon-library', default: 'default' }) library = 'default';
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
|
||||
watchIcon(this);
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
firstUpdated(changedProperties: PropertyValues<this>) {
|
||||
super.firstUpdated(changedProperties);
|
||||
this.initialRender = true;
|
||||
this.setIcon();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import type { CSSResult, CSSResultGroup, PropertyDeclaration, PropertyValues } from 'lit';
|
||||
import { LitElement, defaultConverter, isServer, unsafeCSS } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
import { ElementStyleObserver } from 'style-observer';
|
||||
import componentStyles from '../styles/shadow/component.css';
|
||||
import { getComputedStyle } from './computedStyle.js';
|
||||
|
||||
// Augment Lit's module
|
||||
declare module 'lit' {
|
||||
@@ -11,6 +13,11 @@ declare module 'lit' {
|
||||
*/
|
||||
default?: any;
|
||||
initial?: any;
|
||||
|
||||
/**
|
||||
* Indicates whether the property should reflect to a CSS custom property.
|
||||
*/
|
||||
cssProperty?: string;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +79,99 @@ export default class WebAwesomeElement extends LitElement {
|
||||
|
||||
internals: ElementInternals;
|
||||
|
||||
/** Metadata about CSS-settable props on this element */
|
||||
private cssProps: Record<PropertyKey, { setVia?: 'css' | 'attribute' | 'js'; updating?: boolean }> = {};
|
||||
private computedStyle: CSSStyleDeclaration | null = null;
|
||||
private styleObserver: ElementStyleObserver | null = null;
|
||||
|
||||
connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
|
||||
// Set the initial computed styles
|
||||
const Self = this.constructor as typeof WebAwesomeElement;
|
||||
let cssProps = Object.keys(Self.cssProps);
|
||||
|
||||
if (cssProps.length > 0) {
|
||||
let properties: string[] = [];
|
||||
|
||||
if (Object.keys(this.cssProps).length === 0) {
|
||||
// First time connected, initialize
|
||||
this.cssProps = Object.fromEntries(
|
||||
cssProps.map(property => {
|
||||
let setVia = this.getSetVia(property);
|
||||
return [property, { setVia }];
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
for (let property in this.cssProps) {
|
||||
let setVia = this.cssProps[property].setVia;
|
||||
if (!setVia || setVia === 'css') {
|
||||
// No attribute set, observe CSS property
|
||||
properties.push(property);
|
||||
}
|
||||
}
|
||||
|
||||
this.handleCSSPropertyChange(properties);
|
||||
|
||||
this.styleObserver ??= new ElementStyleObserver(this, (records: object[]) => {
|
||||
let cssProperties = new Set(records.map((record: { property: string }) => record.property));
|
||||
|
||||
// Map CSS properties to prop names
|
||||
let properties = cssProps.filter(property => {
|
||||
let cssProperty = Self.cssProps[property].cssProperty as string;
|
||||
return cssProperties.has(cssProperty);
|
||||
});
|
||||
|
||||
this.handleCSSPropertyChange(properties);
|
||||
});
|
||||
this.styleObserver.unobserve();
|
||||
this.styleObserver.observe(properties.map(property => Self.cssProps[property].cssProperty as string));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to CSS property changes for CSS properties reflecting props
|
||||
* @param [properties] - Prop names. Defaults to all CSS-reflected props.
|
||||
* @void
|
||||
*/
|
||||
handleCSSPropertyChange(properties?: PropertyKey | PropertyKey[]) {
|
||||
const Self = this.constructor as typeof WebAwesomeElement;
|
||||
|
||||
properties ??= Object.keys(Self.cssProps);
|
||||
properties = Array.isArray(properties) ? properties : [properties];
|
||||
|
||||
if (properties.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.computedStyle ??= getComputedStyle(this);
|
||||
|
||||
for (let property of properties) {
|
||||
let propOptions = Self.cssProps[property];
|
||||
let cssProperty = propOptions?.cssProperty;
|
||||
let meta = this.cssProps[property];
|
||||
|
||||
if (!cssProperty || (meta.setVia && meta.setVia !== 'css')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const value = this.computedStyle?.getPropertyValue(cssProperty);
|
||||
// if (property === 'variant' && !value) debugger;
|
||||
|
||||
if (value) {
|
||||
meta.setVia = 'css';
|
||||
meta.updating = true;
|
||||
// @ts-ignore
|
||||
this[property] = value.trim();
|
||||
|
||||
this.updateComplete.then(() => {
|
||||
meta.updating = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null) {
|
||||
if (!this.#hasRecordedInitialProperties) {
|
||||
(this.constructor as typeof WebAwesomeElement).elementProperties.forEach(
|
||||
@@ -115,6 +215,50 @@ export default class WebAwesomeElement extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get how a prop was set
|
||||
* @param property - The property to check
|
||||
*/
|
||||
private getSetVia(property: PropertyKey): 'css' | 'js' | 'attribute' | undefined {
|
||||
let Self = this.constructor as typeof WebAwesomeElement;
|
||||
let setVia;
|
||||
let propOptions = Self.cssProps[property];
|
||||
let attribute = typeof propOptions.attribute === 'string' ? propOptions.attribute : (property as string);
|
||||
|
||||
if (propOptions.attribute !== false && this.hasAttribute(attribute)) {
|
||||
setVia = 'attribute';
|
||||
} else {
|
||||
// @ts-ignore
|
||||
let value = this[property as PropertyKey];
|
||||
if (value !== undefined && value !== propOptions.default) {
|
||||
setVia = 'js';
|
||||
}
|
||||
}
|
||||
|
||||
return setVia as 'attribute' | 'js' | 'css' | undefined;
|
||||
}
|
||||
|
||||
protected updated(changedProperties: PropertyValues<this>) {
|
||||
super.updated(changedProperties);
|
||||
|
||||
let Self = this.constructor as typeof WebAwesomeElement;
|
||||
let cssProps = Object.keys(Self.cssProps);
|
||||
|
||||
if (cssProps.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let [property] of changedProperties) {
|
||||
let meta = this.cssProps[property];
|
||||
|
||||
if (meta && typeof property === 'string' && !(meta.setVia === 'css' && meta.updating)) {
|
||||
// A prop is being set via JS or an attribute that was previously set via CSS
|
||||
// and it's not because we're in the middle of an update
|
||||
meta.setVia = this.getSetVia(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected update(changedProperties: PropertyValues<this>): void {
|
||||
try {
|
||||
super.update(changedProperties);
|
||||
@@ -230,6 +374,11 @@ export default class WebAwesomeElement extends LitElement {
|
||||
*/
|
||||
static rectProxy: undefined | string;
|
||||
|
||||
/**
|
||||
* Props that can be set via CSS custom properties
|
||||
*/
|
||||
static cssProps: Record<PropertyKey, PropertyDeclaration> = {};
|
||||
|
||||
static createProperty(name: PropertyKey, options?: PropertyDeclaration): void {
|
||||
if (options) {
|
||||
if (options.initial !== undefined && options.default === undefined) {
|
||||
@@ -256,8 +405,18 @@ export default class WebAwesomeElement extends LitElement {
|
||||
|
||||
super.createProperty(name, options);
|
||||
|
||||
// Wrap the default accessor with logic to return the default value if the value is null
|
||||
if (options) {
|
||||
if (options.cssProperty) {
|
||||
// Add to the set of CSS-settable props
|
||||
if (this.cssProps === WebAwesomeElement.cssProps) {
|
||||
// Each class needs its own, otherwise they'd share the same object
|
||||
this.cssProps = {};
|
||||
}
|
||||
|
||||
this.cssProps[name] = options;
|
||||
}
|
||||
|
||||
// Wrap the default accessor with logic to return the default value if the value is null
|
||||
if (options.default !== undefined) {
|
||||
const descriptor = Object.getOwnPropertyDescriptor(this.prototype, name as string);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user