Inheritable size (#593)

Co-authored-by: Lindsay M <126139086+lindsaym-fa@users.noreply.github.com>
Co-authored-by: lindsaym-fa <dev@lindsaym.design>
This commit is contained in:
Lea Verou
2025-01-30 15:56:32 -08:00
committed by GitHub
parent a64cc60ad5
commit 74ecc52a15
32 changed files with 614 additions and 133 deletions

View File

@@ -40,6 +40,66 @@
</div>
<wa-divider></wa-divider>
<h3>Button Group</h3>
<div class="table-scroll">
<table>
<thead>
<th></th>
<th><code>size=""</code></th>
<th><code>.wa-size-[s|m|l]</code></th>
</thead>
<tbody>
<tr>
<th><code>small</code>/<code>s</code></th>
<td>
<wa-button-group orientation="horizontal" size="small">
<wa-button value="1">Button L</wa-button>
<wa-button value="2">Button R</wa-button>
</wa-button-group>
</td>
<td>
<wa-button-group orientation="horizontal" class="wa-size-s">
<wa-button value="1">Button L</wa-button>
<wa-button value="2">Button R</wa-button>
</wa-button-group>
</td>
</tr>
<tr>
<th><code>medium</code>/<code>m</code></th>
<td>
<wa-button-group orientation="horizontal" size="medium">
<wa-button value="1">Button L</wa-button>
<wa-button value="2">Button R</wa-button>
</wa-button-group>
</td>
<td>
<wa-button-group orientation="horizontal" class="wa-size-m">
<wa-button value="1">Button L</wa-button>
<wa-button value="2">Button R</wa-button>
</wa-button-group>
</td>
</tr>
<tr>
<th><code>large</code>/<code>l</code></th>
<td>
<wa-button-group orientation="horizontal" size="large">
<wa-button value="1">Button L</wa-button>
<wa-button value="2">Button R</wa-button>
</wa-button-group>
</td>
<td>
<wa-button-group orientation="horizontal" class="wa-size-l">
<wa-button value="1">Button L</wa-button>
<wa-button value="2">Button R</wa-button>
</wa-button-group>
</td>
</tr>
</tbody>
</table>
</div>
<wa-divider></wa-divider>
<h3>Callout</h3>
<div class="table-scroll">
@@ -100,6 +160,60 @@
</div>
<wa-divider></wa-divider>
<h3>Card</h3>
<div class="table-scroll">
<table>
<thead>
<th></th>
<th><code>size=""</code></th>
<th><code>.wa-size-[s|m|l]</code></th>
</thead>
<tbody>
<tr>
<th><code>small</code>/<code>s</code></th>
<td>
<wa-card size="small">
Card
</wa-card>
</td>
<td>
<wa-card class="wa-size-s">
Card
</wa-card>
</td>
</tr>
<tr>
<th><code>medium</code>/<code>m</code></th>
<td>
<wa-card size="medium">
Card
</wa-card>
</td>
<td>
<wa-card class="wa-size-m">
Card
</wa-card>
</td>
</tr>
<tr>
<th><code>large</code>/<code>l</code></th>
<td>
<wa-card size="large">
Card
</wa-card>
</td>
<td>
<wa-card class="wa-size-l">
Card
</wa-card>
</td>
</tr>
</tbody>
</table>
</div>
<wa-divider></wa-divider>
<h3>Checkbox</h3>
<div class="table-scroll">
@@ -184,6 +298,144 @@
</div>
<wa-divider></wa-divider>
<h3>Dropdown</h3>
<div class="table-scroll">
<table>
<thead>
<th></th>
<th><code>size=""</code></th>
<th><code>.wa-size-[s|m|l]</code></th>
</thead>
<tbody>
<tr>
<th><code>small</code>/<code>s</code></th>
<td>
<wa-dropdown size="small">
<wa-button slot="trigger" caret>Dropdown</wa-button>
<wa-menu>
<wa-menu-item>Menu Item 1</wa-menu-item>
<wa-menu-item>Menu Item 2</wa-menu-item>
</wa-menu>
</wa-dropdown>
</td>
<td>
<wa-dropdown class="wa-size-s">
<wa-button slot="trigger" caret>Dropdown</wa-button>
<wa-menu>
<wa-menu-item>Menu Item 1</wa-menu-item>
<wa-menu-item>Menu Item 2</wa-menu-item>
</wa-menu>
</wa-dropdown>
</td>
</tr>
<tr>
<th><code>medium</code>/<code>m</code></th>
<td>
<wa-dropdown size="medium">
<wa-button slot="trigger" caret>Dropdown</wa-button>
<wa-menu>
<wa-menu-item>Menu Item 1</wa-menu-item>
<wa-menu-item>Menu Item 2</wa-menu-item>
</wa-menu>
</wa-dropdown>
</td>
<td>
<wa-dropdown class="wa-size-m">
<wa-button slot="trigger" caret>Dropdown</wa-button>
<wa-menu>
<wa-menu-item>Menu Item 1</wa-menu-item>
<wa-menu-item>Menu Item 2</wa-menu-item>
</wa-menu>
</wa-dropdown>
</td>
</tr>
<tr>
<th><code>large</code>/<code>l</code></th>
<td>
<wa-dropdown size="large">
<wa-button slot="trigger" caret>Dropdown</wa-button>
<wa-menu>
<wa-menu-item>Menu Item 1</wa-menu-item>
<wa-menu-item>Menu Item 2</wa-menu-item>
</wa-menu>
</wa-dropdown>
</td>
<td>
<wa-dropdown class="wa-size-l">
<wa-button slot="trigger" caret>Dropdown</wa-button>
<wa-menu>
<wa-menu-item>Menu Item 1</wa-menu-item>
<wa-menu-item>Menu Item 2</wa-menu-item>
</wa-menu>
</wa-dropdown>
</td>
</tr>
</tbody>
</table>
</div>
<wa-divider></wa-divider>
<h3>Menu</h3>
<div class="table-scroll">
<table>
<thead>
<th></th>
<th><code>size=""</code></th>
<th><code>.wa-size-[s|m|l]</code></th>
</thead>
<tbody>
<tr>
<th><code>small</code>/<code>s</code></th>
<td>
<wa-menu size="small">
<wa-menu-item>Menu Item 1</wa-menu-item>
<wa-menu-item>Menu Item 2</wa-menu-item>
</wa-menu>
</td>
<td>
<wa-menu class="wa-size-s">
<wa-menu-item>Menu Item 1</wa-menu-item>
<wa-menu-item>Menu Item 2</wa-menu-item>
</wa-menu>
</td>
</tr>
<tr>
<th><code>medium</code>/<code>m</code></th>
<td>
<wa-menu size="medium">
<wa-menu-item>Menu Item 1</wa-menu-item>
<wa-menu-item>Menu Item 2</wa-menu-item>
</wa-menu>
</td>
<td>
<wa-menu class="wa-size-m">
<wa-menu-item>Menu Item 1</wa-menu-item>
<wa-menu-item>Menu Item 2</wa-menu-item>
</wa-menu>
</td>
</tr>
<tr>
<th><code>large</code>/<code>l</code></th>
<td>
<wa-menu size="large">
<wa-menu-item>Menu Item 1</wa-menu-item>
<wa-menu-item>Menu Item 2</wa-menu-item>
</wa-menu>
</td>
<td>
<wa-menu class="wa-size-l">
<wa-menu-item>Menu Item 1</wa-menu-item>
<wa-menu-item>Menu Item 2</wa-menu-item>
</wa-menu>
</td>
</tr>
</tbody>
</table>
</div>
<wa-divider></wa-divider>
<h3>Input</h3>
<div class="table-scroll">
@@ -274,7 +526,7 @@
<table>
<thead>
<th></th>
<th class="test-failure"><code>size=""</code></th>
<th><code>size=""</code></th>
<th><code>.wa-size-[s|m|l]</code></th>
</thead>
<tbody>
@@ -335,7 +587,7 @@
<thead>
<th></th>
<th><code>size=""</code></th>
<th class="test-failure"><code>.wa-size-[s|m|l]</code></th>
<th><code>.wa-size-[s|m|l]</code></th>
</thead>
<tbody>
<tr>
@@ -424,6 +676,48 @@
</div>
<wa-divider></wa-divider>
<h3>Rating</h3>
<div class="table-scroll">
<table>
<thead>
<th></th>
<th><code>size=""</code></th>
<th><code>.wa-size-[s|m|l]</code></th>
</thead>
<tbody>
<tr>
<th><code>small</code>/<code>s</code></th>
<td>
<wa-rating size="small"></wa-rating>
</td>
<td>
<wa-rating class="wa-size-s"></wa-rating>
</td>
</tr>
<tr>
<th><code>medium</code>/<code>m</code></th>
<td>
<wa-rating size="medium"></wa-rating>
</td>
<td>
<wa-rating class="wa-size-m"></wa-rating>
</td>
</tr>
<tr>
<th><code>large</code>/<code>l</code></th>
<td>
<wa-rating size="large"></wa-rating>
</td>
<td>
<wa-rating class="wa-size-l"></wa-rating>
</td>
</tr>
</tbody>
</table>
</div>
<wa-divider></wa-divider>
<h3>Select</h3>
<div class="table-scroll">

View File

@@ -17,32 +17,39 @@ icon: button-group
### Button Sizes
All button sizes are supported, but avoid mixing sizes within the same button group.
Unless otherwise specified,
the size of [buttons](/docs/components/button) will be determined by the Button Group's `size` attribute.
```html {.example}
<wa-button-group label="Alignment">
<wa-button size="small">Left</wa-button>
<wa-button size="small">Center</wa-button>
<wa-button size="small">Right</wa-button>
<wa-button-group size="small" label="Alignment">
<wa-button>Left</wa-button>
<wa-button>Center</wa-button>
<wa-button>Right</wa-button>
</wa-button-group>
<br /><br />
<wa-button-group label="Alignment">
<wa-button size="medium">Left</wa-button>
<wa-button size="medium">Center</wa-button>
<wa-button size="medium">Right</wa-button>
<wa-button-group size="medium" label="Alignment">
<wa-button>Left</wa-button>
<wa-button>Center</wa-button>
<wa-button>Right</wa-button>
</wa-button-group>
<br /><br />
<wa-button-group label="Alignment">
<wa-button size="large">Left</wa-button>
<wa-button size="large">Center</wa-button>
<wa-button size="large">Right</wa-button>
<wa-button-group size="large" label="Alignment">
<wa-button>Left</wa-button>
<wa-button>Center</wa-button>
<wa-button>Right</wa-button>
</wa-button-group>
```
:::info
While you can still set the size of [buttons](/docs/components/button) individually,
and it will override the inherited size,
it is rarely a good idea to mix sizes within the same button group.
:::
### Vertical button groups
Set the `orientation` attribute to `vertical` to make a vertical button group.
@@ -70,21 +77,21 @@ Set the `orientation` attribute to `vertical` to make a vertical button group.
### Theme Buttons
Theme buttons are supported through the button's `variant` attribute.
Theme buttons are supported through the button group's `variant` attribute.
```html {.example}
<wa-button-group label="Alignment">
<wa-button variant="brand">Left</wa-button>
<wa-button variant="brand">Center</wa-button>
<wa-button variant="brand">Right</wa-button>
<wa-button-group label="Alignment" variant="brand">
<wa-button>Left</wa-button>
<wa-button>Center</wa-button>
<wa-button>Right</wa-button>
</wa-button-group>
<br /><br />
<wa-button-group label="Alignment">
<wa-button variant="success">Left</wa-button>
<wa-button variant="success">Center</wa-button>
<wa-button variant="success">Right</wa-button>
<wa-button-group label="Alignment" variant="success">
<wa-button>Left</wa-button>
<wa-button>Center</wa-button>
<wa-button>Right</wa-button>
</wa-button-group>
<br /><br />
@@ -97,18 +104,28 @@ Theme buttons are supported through the button's `variant` attribute.
<br /><br />
<wa-button-group label="Alignment">
<wa-button variant="warning">Left</wa-button>
<wa-button variant="warning">Center</wa-button>
<wa-button variant="warning">Right</wa-button>
<wa-button-group label="Alignment" variant="warning">
<wa-button>Left</wa-button>
<wa-button>Center</wa-button>
<wa-button>Right</wa-button>
</wa-button-group>
<br /><br />
<wa-button-group label="Alignment">
<wa-button variant="danger">Left</wa-button>
<wa-button variant="danger">Center</wa-button>
<wa-button variant="danger">Right</wa-button>
<wa-button-group label="Alignment" variant="danger">
<wa-button>Left</wa-button>
<wa-button>Center</wa-button>
<wa-button>Right</wa-button>
</wa-button-group>
```
You can still use the buttons own `variant` attribute to override the inherited variant.
```html {.example}
<wa-button-group label="Alignment" variant="brand">
<wa-button>Left</wa-button>
<wa-button>Center</wa-button>
<wa-button variant="neutral">Right</wa-button>
</wa-button-group>
```

View File

@@ -143,3 +143,42 @@ If using SSR, you need to also use the `with-image` attribute to add an image to
}
</style>
```
### Sizing
Use the `size` attribute to change a card's size.
```html {.example}
<div class="wa-stack">
<wa-card with-footer size="small">
This is a small card.
<footer slot="footer" class="wa-flank">
<wa-button variant="brand" pill>More Info</wa-button>
<wa-rating></wa-rating>
</footer>
</wa-card>
<wa-card with-footer size="medium">
This is a medium card (default).
<footer slot="footer" class="wa-flank">
<wa-button variant="brand" pill>More Info</wa-button>
<wa-rating></wa-rating>
</footer>
</wa-card>
<wa-card with-footer size="large">
This is a large card.
<footer slot="footer" class="wa-flank">
<wa-button variant="brand" pill>More Info</wa-button>
<wa-rating></wa-rating>
</footer>
</wa-card>
</div>
```
<style>
</style>

View File

@@ -32,11 +32,11 @@ Add descriptive hint to a radio group with the `hint` attribute. For hints that
[Radio buttons](/docs/components/radio-button) offer an alternate way to display radio controls. In this case, an internal [button group](/docs/components/button-group) is used to group the buttons into a single, cohesive control.
```html {.example}
<wa-radio-group
label="Horizontal options"
hint="Select an option that makes you proud."
orientation="horizontal"
name="a"
<wa-radio-group
label="Horizontal options"
hint="Select an option that makes you proud."
orientation="horizontal"
name="a"
value="1"
>
<wa-radio-button value="1">Option 1</wa-radio-button>
@@ -46,11 +46,11 @@ Add descriptive hint to a radio group with the `hint` attribute. For hints that
<br>
<wa-radio-group
label="Vertical options"
hint="Select an option that makes you proud."
orientation="vertical"
name="a"
<wa-radio-group
label="Vertical options"
hint="Select an option that makes you proud."
orientation="vertical"
name="a"
value="1"
style="max-width: 300px;"
>
@@ -77,11 +77,11 @@ Radios and radio buttons can be disabled by adding the `disabled` attribute to t
The default orientation for radio items is `vertical`. Set the `orientation` to `horizontal` to items on the same row.
```html {.example}
<wa-radio-group
label="Select an option"
<wa-radio-group
label="Select an option"
hint="Choose the most appropriate option."
orientation="horizontal"
name="a"
orientation="horizontal"
name="a"
value="1"
>
<wa-radio value="1">Option 1</wa-radio>
@@ -92,26 +92,19 @@ The default orientation for radio items is `vertical`. Set the `orientation` to
### Sizing Options
The size of [Radios](/docs/components/radio) and [Radio Buttons](/docs/components/radio-buttons) will be determined by the Radio Group's `size` attribute.
The size of [Radios](/docs/components/radio) and [Radio Buttons](/docs/components/radio-button) will be determined by the Radio Group's `size` attribute.
```html preview
<wa-radio-group label="Select an option" size="medium" value="medium" class="radio-group-size">
```html {.example}
<wa-radio-group label="Select an option" size="medium" value="medium" onchange="this.size = this.value">
<wa-radio value="small">Small</wa-radio>
<wa-radio value="medium">Medium</wa-radio>
<wa-radio value="large">Large</wa-radio>
</wa-radio-group>
<script>
const radioGroup = document.querySelector('.radio-group-size');
radioGroup.addEventlistener('change', () => {
radioGroup.size = radioGroup.value;
});
</script>
```
:::info
[Radios](/docs/components/radio) and [Radio Buttons](/docs/components/radio-button) also have a `size` attribute. This can be useful in certain compositions, but it will be ignored when used inside of a Radio Group.
[Radios](/docs/components/radio) and [Radio Buttons](/docs/components/radio-button) also have a `size` attribute,
which will override the inherited size when used.
:::
### Validation

View File

@@ -35,12 +35,20 @@ Use the `precision` attribute to let users select fractional ratings.
<wa-rating label="Rating" precision="0.5" value="2.5"></wa-rating>
```
### Symbol Sizes
### Sizing
Set the `--symbol-size` custom property to adjust the size.
Use the `size` attribute to adjust the size of the rating.
```html {.example}
<wa-rating label="Rating" style="--symbol-size: 2rem;"></wa-rating>
<wa-rating label="Rating" size="small"></wa-rating><br>
<wa-rating label="Rating" size="medium"></wa-rating><br>
<wa-rating label="Rating" size="large"></wa-rating>
```
For more granular sizing, you can use the `font-size` property.
```html {.example}
<wa-rating label="Rating" style="font-size: 2rem;"></wa-rating>
```
### Readonly

View File

@@ -0,0 +1,75 @@
---
title: Size tests
---
Button size should default to `medium`:
```html {.example}
<wa-button size=small>Small</wa-button>
<wa-button>Medium</wa-button>
<wa-button size=medium>Medium</wa-button>
<wa-button size=large>Large</wa-button>
```
If no button size is specified, it should default to that of its ancestor:
```html {.example}
<wa-button-group size="small">
<wa-button>Small 1</wa-button>
<wa-button>Small 2</wa-button>
<wa-button>Small 3</wa-button>
</wa-button-group>
<br><br>
<wa-button-group>
<wa-button>Medium 1</wa-button>
<wa-button>Medium 2</wa-button>
<wa-button>Medium 3</wa-button>
</wa-button-group>
<br><br>
<wa-button-group size="large">
<wa-button>Large 1</wa-button>
<wa-button>Large 2</wa-button>
<wa-button>Large 3</wa-button>
</wa-button-group>
```
Dropdown:
```html {.example}
<p>Small dropdown:
<wa-dropdown size="small">
<wa-button slot="trigger" caret>Dropdown</wa-button>
<wa-menu>
<wa-menu-item>Dropdown Item 1</wa-menu-item>
<wa-menu-item>Dropdown Item 2</wa-menu-item>
<wa-menu-item>Dropdown Item 3</wa-menu-item>
</wa-menu>
</wa-dropdown>
<p>Small menu:
<wa-dropdown>
<wa-button slot="trigger" caret>Dropdown</wa-button>
<wa-menu size="small">
<wa-menu-item>Dropdown Item 1</wa-menu-item>
<wa-menu-item>Dropdown Item 2</wa-menu-item>
<wa-menu-item>Dropdown Item 3</wa-menu-item>
</wa-menu>
</wa-dropdown>
<p>Small menu item:
<wa-dropdown>
<wa-button slot="trigger" caret>Dropdown</wa-button>
<wa-menu>
<wa-menu-item size="small">Dropdown Item 1</wa-menu-item>
<wa-menu-item size="small">Dropdown Item 2</wa-menu-item>
<wa-menu-item size="small">Dropdown Item 3</wa-menu-item>
</wa-menu>
</wa-dropdown>
<p>No size:
<wa-dropdown>
<wa-button slot="trigger" caret>Dropdown</wa-button>
<wa-menu>
<wa-menu-item>Dropdown Item 1</wa-menu-item>
<wa-menu-item>Dropdown Item 2</wa-menu-item>
<wa-menu-item>Dropdown Item 3</wa-menu-item>
</wa-menu>
</wa-dropdown>
```

View File

@@ -18,12 +18,14 @@ During the alpha period, things might break! We take breaking changes very serio
- `wa-input` => `input`
- `wa-change` => `change`
- `wa-blur` => `blur` (this event will no longer bubble, use `focusout` for a bubbling version)
- `wa-focus` => `focus` (this event will no longer bubble)
- `wa-focus` => `focus` (this event will no longer bubble, use `focusin` for a bubbling version)
- Added `.wa-callout` utility class
- Added the `orientation` attribute to `<wa-radio-group>` to support vertical and horizontal radio items
- Added docs for visual tests
- Added docs on how to cherry-pick native styles
- Changed `variant` behavior so that nested components with `variant` support inherit the `variant` set on their ancestor
- Changed the behavior of the `variant` and `size` attributes so that nested components that support these attributes but do not have them set inherit the values set on their ancestors. Additionally:
- Added `size` attribute to `<wa-dropdown>`, `<wa-button-group>`, `<wa-menu>`, `<wa-rating>`, `<wa-card>`
- Added `variant` attribute to `<wa-button-group>`
- Fixed a bug in `<wa-tab-group>` that prevented nested tab groups from working properly
- Fixed slot names for `show-password-icon` and `hide-password-icon` in `<wa-input>` to more intuitively represent their functions
- Fixed a bug in `<wa-textarea>` that caused empty controls to submit a value if the initial value was deleted a certain way

View File

@@ -3,6 +3,8 @@ import { html } from 'lit';
import { customElement, property, query, state } from 'lit/decorators.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import buttonGroupStyles from '../../styles/utilities/button-group.css';
import sizeStyles from '../../styles/utilities/size.css';
import variantStyles from '../../styles/utilities/variants.css';
import styles from './button-group.css';
/**
@@ -17,7 +19,7 @@ import styles from './button-group.css';
*/
@customElement('wa-button-group')
export default class WaButtonGroup extends WebAwesomeElement {
static shadowStyle = [buttonGroupStyles, styles];
static shadowStyle = [sizeStyles, variantStyles, buttonGroupStyles, styles];
@query('slot') defaultSlot: HTMLSlotElement;
@@ -33,6 +35,13 @@ export default class WaButtonGroup extends WebAwesomeElement {
/** The button group's orientation. */
@property({ reflect: true }) orientation: 'horizontal' | 'vertical' = 'horizontal';
/** The component's size. */
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
/** The button group's theme variant. Defaults to `neutral` if not within another element with a variant. */
@property({ reflect: true, initial: 'neutral' })
variant: 'neutral' | 'brand' | 'success' | 'warning' | 'danger' | 'inherit' = 'inherit';
updated(changedProperties: PropertyValues<this>) {
super.updated(changedProperties);

View File

@@ -114,7 +114,7 @@ describe('<wa-button>', () => {
expect(el.title).to.equal('');
expect(el.variant).to.equal('inherit');
expect(el.appearance).to.equal('accent');
expect(el.size).to.equal('medium');
expect(el.size).to.equal('inherit');
expect(el.disabled).to.equal(false);
expect(el.caret).to.equal(false);
expect(el.loading).to.equal(false);

View File

@@ -75,7 +75,7 @@ export default class WaButton extends WebAwesomeFormAssociatedElement {
appearance: 'accent' | 'filled' | 'outlined' | 'plain' = 'accent';
/** The button's size. */
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
/** Draws the button with a caret. Used to indicate that the button triggers a dropdown menu or similar behavior. */
@property({ type: Boolean, reflect: true }) caret = false;

View File

@@ -46,7 +46,7 @@ export default class WaCallout extends WebAwesomeElement {
| 'outlined accent' = 'outlined filled';
/** The callout's size. */
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
render() {
return html`

View File

@@ -1,5 +1,9 @@
:host {
--spacing: var(--wa-space-xl);
--space-s: var(--wa-space-l);
--space-m: var(--wa-space-xl);
--space-l: var(--wa-space-2xl);
--spacing: var(--wa-space);
--border-width: var(--wa-panel-border-width);
--border-radius: var(--wa-panel-border-radius);

View File

@@ -1,6 +1,7 @@
import { html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import sizeStyles from '../../styles/utilities/size.css';
import styles from './card.css';
/**
@@ -21,11 +22,14 @@ import styles from './card.css';
*
* @cssproperty --border-radius - The radius for the card's corners. Expects a single value. Defaults to `var(--wa-panel-border-radius)`.
* @cssproperty --border-width - The width of the card's borders. Expects a single value. Defaults to `var(--wa-panel-border-width)`.
* @cssproperty --spacing - The amount of space around and between sections of the card. Expects a single value.
* @cssproperty --spacing - The amount of space around and between sections of the card. Expects a single value. Defaults to `var(--wa-space)`.
*/
@customElement('wa-card')
export default class WaCard extends WebAwesomeElement {
static shadowStyle = styles;
static shadowStyle = [sizeStyles, styles];
/** The component's size. Will be inherited by any descendants with a `size` attribute. */
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
/** Renders the card with a header. Only needed for SSR, otherwise is automatically added. */
@property({ attribute: 'with-header', type: Boolean }) withHeader = false;

View File

@@ -98,7 +98,7 @@ export default class WaCheckbox extends WebAwesomeFormAssociatedElement {
}
/** The checkbox's size. */
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
/** Disables the checkbox. */
@property({ type: Boolean }) disabled = false;

View File

@@ -199,7 +199,7 @@ export default class WaColorPicker extends WebAwesomeFormAssociatedElement {
@property() format: 'hex' | 'rgb' | 'hsl' | 'hsv' = 'hex';
/** Determines the size of the color picker's trigger */
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
/** Removes the button that lets users toggle between format. */
@property({ attribute: 'no-format-toggle', type: Boolean }) noFormatToggle = false;

View File

@@ -11,6 +11,7 @@ import { animateWithClass } from '../../internal/animate.js';
import { waitForEvent } from '../../internal/event.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import sizeStyles from '../../styles/utilities/size.css';
import type WaButton from '../button/button.js';
import type WaIconButton from '../icon-button/icon-button.js';
import type WaMenu from '../menu/menu.js';
@@ -43,7 +44,7 @@ import styles from './dropdown.css';
*/
@customElement('wa-dropdown')
export default class WaDropdown extends WebAwesomeElement {
static shadowStyle = styles;
static shadowStyle = [sizeStyles, styles];
@query('.dropdown') popup: WaPopup;
@query('#trigger') trigger: HTMLSlotElement;

View File

@@ -23,7 +23,7 @@ describe('<wa-input>', () => {
const el = await fixture<WaInput>(html` <wa-input></wa-input> `);
expect(el.type).to.equal('text');
expect(el.size).to.equal('medium');
expect(el.size).to.equal('inherit');
expect(el.name).to.equal(null);
expect(el.value).to.equal(null);
expect(el.defaultValue).to.equal(null);

View File

@@ -115,7 +115,7 @@ export default class WaInput extends WebAwesomeFormAssociatedElement {
@property({ attribute: 'value', reflect: true }) defaultValue: string | null = this.getAttribute('value') || null;
/** The input's size. */
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
/** The input's visual appearance. */
@property({ reflect: true }) appearance: 'filled' | 'outlined' = 'outlined';

View File

@@ -1,7 +1,8 @@
import { html } from 'lit';
import { customElement, query } from 'lit/decorators.js';
import { customElement, property, query } from 'lit/decorators.js';
import { WaSelectEvent } from '../../events/select.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import sizeStyles from '../../styles/utilities/size.css';
import '../menu-item/menu-item.js';
import type WaMenuItem from '../menu-item/menu-item.js';
import styles from './menu.css';
@@ -24,7 +25,10 @@ export interface MenuSelectEventDetail {
*/
@customElement('wa-menu')
export default class WaMenu extends WebAwesomeElement {
static shadowStyle = styles;
static shadowStyle = [sizeStyles, styles];
/** The component's size. */
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
@query('slot') defaultSlot: HTMLSlotElement;

View File

@@ -72,7 +72,7 @@ export default class WaRadioButton extends WebAwesomeFormAssociatedElement {
* The radio button's size. When used inside a radio group, the size will be determined by the radio group's size so
* this attribute can typically be omitted.
*/
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
/** Draws a pill-style radio button with rounded edges. */
@property({ type: Boolean, reflect: true }) pill = false;

View File

@@ -259,8 +259,10 @@ describe('<wa-radio-group>', () => {
`);
const [radio1, radio2] = radioGroup.querySelectorAll('wa-radio');
expect(radio1.size).to.equal('large');
expect(radio2.size).to.equal('large');
expect(radio1.size).to.equal('inherit');
expect(radio1.getComputed('size')).to.equal('large');
expect(radio2.size).to.equal('inherit');
expect(radio2.getComputed('size')).to.equal('large');
});
it('should apply the same size to all radio buttons', async () => {
@@ -272,11 +274,13 @@ describe('<wa-radio-group>', () => {
`);
const [radio1, radio2] = radioGroup.querySelectorAll('wa-radio-button');
expect(radio1.size).to.equal('large');
expect(radio2.size).to.equal('large');
expect(radio1.size).to.equal('inherit');
expect(radio1.getComputed('size')).to.equal('large');
expect(radio2.size).to.equal('inherit');
expect(radio2.getComputed('size')).to.equal('large');
});
it('should update the size of all radio buttons when size changes', async () => {
it('should update the computed size of all radio buttons when size changes', async () => {
const radioGroup = await fixture<WaRadioGroup>(html`
<wa-radio-group size="small">
<wa-radio-button id="radio-1" value="1"></wa-radio-button>
@@ -285,14 +289,18 @@ describe('<wa-radio-group>', () => {
`);
const [radio1, radio2] = radioGroup.querySelectorAll('wa-radio-button');
expect(radio1.size).to.equal('small');
expect(radio2.size).to.equal('small');
expect(radio1.size).to.equal('inherit');
expect(radio1.getComputed('size')).to.equal('small');
expect(radio2.size).to.equal('inherit');
expect(radio2.getComputed('size')).to.equal('small');
radioGroup.size = 'large';
await radioGroup.updateComplete;
expect(radio1.size).to.equal('large');
expect(radio2.size).to.equal('large');
expect(radio1.size).to.equal('inherit');
expect(radio1.getComputed('size')).to.equal('large');
expect(radio2.size).to.equal('inherit');
expect(radio2.getComputed('size')).to.equal('large');
});
});

View File

@@ -107,8 +107,8 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
/** The default value of the form control. Primarily used for resetting the form control. */
@property({ attribute: 'value', reflect: true }) defaultValue: string | null = this.getAttribute('value') || null;
/** The radio group's size. This size will be applied to all child radios and radio buttons. */
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
/** The radio group's size. This size will be applied to all child radios and radio buttons, except when explicitly overridden. */
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
/** Ensures a child radio is checked before allowing the containing form to submit. */
@property({ type: Boolean, reflect: true }) required = false;
@@ -187,7 +187,6 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
// Sync the checked state and size
radios.map(async radio => {
await radio.updateComplete;
radio.size = this.size;
if (!radio.disabled && radio.value === this.value) {
radio.checked = true;
@@ -329,9 +328,6 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
part="form-control"
class=${classMap({
'form-control': true,
'form-control--small': this.size === 'small',
'form-control--medium': this.size === 'medium',
'form-control--large': this.size === 'large',
'form-control--radio-group': true,
'form-control--has-label': hasLabel,
'form-control--has-radio-buttons': this.hasRadioButtons,

View File

@@ -58,7 +58,7 @@ export default class WaRadio extends WebAwesomeFormAssociatedElement {
* The radio's size. When used inside a radio group, the size will be determined by the radio group's size so this
* attribute can typically be omitted.
*/
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
/** Disables the radio. */
@property({ type: Boolean }) disabled = false;

View File

@@ -1,7 +1,12 @@
:host {
--size-xs: var(--wa-space-s);
--size-s: var(--wa-space-m);
--size-m: var(--wa-space-l);
--size-l: var(--wa-space-xl);
--symbol-color: var(--wa-color-neutral-fill-normal);
--symbol-color-active: var(--wa-color-yellow-70);
--symbol-size: var(--wa-font-size-l);
--symbol-size: var(--wa-size);
--symbol-spacing: var(--wa-space-3xs);
display: inline-flex;
@@ -26,7 +31,6 @@
.symbols {
display: inline-flex;
position: relative;
font-size: var(--symbol-size);
line-height: 0;
color: var(--symbol-color);
white-space: nowrap;

View File

@@ -7,6 +7,7 @@ import { WaHoverEvent } from '../../events/hover.js';
import { clamp } from '../../internal/math.js';
import { watch } from '../../internal/watch.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import sizeStyles from '../../styles/utilities/size.css';
import { LocalizeController } from '../../utilities/localize.js';
import '../icon/icon.js';
import styles from './rating.css';
@@ -28,12 +29,11 @@ import styles from './rating.css';
*
* @cssproperty --symbol-color - The inactive color for symbols.
* @cssproperty --symbol-color-active - The active color for symbols.
* @cssproperty --symbol-size - The size of symbols.
* @cssproperty --symbol-spacing - The spacing to use around symbols.
*/
@customElement('wa-rating')
export default class WaRating extends WebAwesomeElement {
static shadowStyle = styles;
static shadowStyle = [sizeStyles, styles];
private readonly localize = new LocalizeController(this);
@@ -71,6 +71,9 @@ export default class WaRating extends WebAwesomeElement {
@property() getSymbol: (value: number) => string = () =>
'<wa-icon name="star" library="system" variant="solid"></wa-icon>';
/** The component's size. */
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
private getValueFromMousePosition(event: MouseEvent) {
return this.getValueFromXCoordinate(event.clientX);
}

View File

@@ -162,7 +162,7 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
@property({ attribute: false }) value: string | string[] | null = null;
/** The select's size. */
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
/** Placeholder text to show as a hint when the select is empty. */
@property() placeholder = '';

View File

@@ -77,7 +77,7 @@ export default class WaSwitch extends WebAwesomeFormAssociatedElement {
}
/** The switch's size. */
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
/** Disables the switch. */
@property({ type: Boolean }) disabled = false;

View File

@@ -9,7 +9,7 @@ describe('<wa-tag>', () => {
describe(`with "${fixture.type}" rendering`, () => {
it('should render default tag', async () => {
const el = await fixture<WaTag>(html` <wa-tag>Test</wa-tag> `);
expect(el.getAttribute('size')).to.equal('medium');
expect(el.getAttribute('size')).to.equal(null);
expect(el.getAttribute('variant')).to.equal(null);
expect(el.variant).to.equal('inherit');
});

View File

@@ -46,7 +46,7 @@ export default class WaTag extends WebAwesomeElement {
'outlined filled';
/** The tag's size. */
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
/** Draws a pill-style tag with rounded edges. */
@property({ type: Boolean, reflect: true }) pill = false;

View File

@@ -20,7 +20,7 @@ describe('<wa-textarea>', () => {
it('default properties', async () => {
const el = await fixture<WaTextarea>(html` <wa-textarea></wa-textarea> `);
expect(el.size).to.equal('medium');
expect(el.size).to.equal('inherit');
expect(el.name).to.equal(null);
expect(el.value).to.equal('');
expect(el.defaultValue).to.equal('');

View File

@@ -88,7 +88,7 @@ export default class WaTextarea extends WebAwesomeFormAssociatedElement {
@property({ attribute: 'value', reflect: true }) defaultValue: string = this.getAttribute('value') ?? '';
/** The textarea's size. */
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
@property({ reflect: true, initial: 'medium' }) size: 'small' | 'medium' | 'large' | 'inherit' = 'inherit';
/** The textarea's visual appearance. */
@property({ reflect: true }) appearance: 'filled' | 'outlined' = 'outlined';

View File

@@ -1,19 +1,10 @@
/* Shadow styles for elements that have a size attribute. */
/**
* Shadow styles for elements that have a size attribute and for the size utility classes.
*/
:host,
:where(.wa-size-s, .wa-size-m, .wa-size-l) {
/* Defaults. Components are expected to override these */
--size-xs: var(--wa-font-size-xs, 0.75rem); /* Used for hints etc */
--size-s: var(--wa-font-size-s, 0.875rem); /* size=small */
--size-m: var(--wa-font-size-m, 1rem); /* default */
--size-l: var(--wa-font-size-l, 1.25rem); /* size=large */
--space-xs: var(--wa-space-xs, 0.5rem);
--space-s: var(--wa-space-s, 0.75rem);
--space-m: var(--wa-space-m, 1rem);
--space-l: var(--wa-space-l, 1.25rem);
font-size: var(--wa-size);
font-size: var(--wa-size, var(--wa-font-size-m));
}
:where(:root),
@@ -21,6 +12,35 @@
.wa-size-s,
.wa-size-m,
.wa-size-l {
--_wa-is-small: var(--wa-is-small, 0);
--_wa-is-medium: var(--wa-is-medium, 1);
--_wa-is-large: var(--wa-is-large, 0);
--_size-xs: var(--size-xs, var(--wa-font-size-xs));
--_size-s: var(--size-s, var(--wa-font-size-s));
--_size-m: var(--size-m, var(--wa-font-size-m));
--_size-l: var(--size-l, var(--wa-font-size-l));
--_space-xs: var(--space-xs, var(--wa-space-xs));
--_space-s: var(--space-s, var(--wa-space-s));
--_space-m: var(--space-m, var(--wa-space-m));
--_space-l: var(--space-l, var(--wa-space-l));
--wa-size: calc(
var(--_wa-is-small) * var(--_size-s) + var(--_wa-is-medium) * var(--_size-m) + var(--_wa-is-large) * var(--_size-l)
);
--wa-size-smaller: calc(
var(--_wa-is-small) * var(--_size-xs) + var(--_wa-is-medium) * var(--_size-s) + var(--_wa-is-large) * var(--_size-m)
);
--wa-space: calc(
var(--_wa-is-small) * var(--_space-s) + var(--_wa-is-medium) * var(--_space-m) + var(--_wa-is-large) *
var(--_space-l)
);
--wa-space-smaller: calc(
var(--_wa-is-small) * var(--_space-xs) + var(--_wa-is-medium) * var(--_space-s) + var(--_wa-is-large) *
var(--_space-m)
);
--_wa-form-control-height: calc(2 * var(--wa-space-smaller) + 1em * var(--wa-form-control-value-line-height));
--wa-form-control-height: var(--_wa-form-control-height);
@@ -29,27 +49,27 @@
}
}
:host([size='small']),
.wa-size-s {
--wa-size: var(--size-s);
--wa-size-smaller: var(--size-xs);
--wa-space: var(--space-s);
--wa-space-smaller: var(--space-xs);
:host([size]),
.wa-size-s,
.wa-size-m,
.wa-size-l {
--wa-is-small: 0;
--wa-is-medium: 0;
--wa-is-large: 0;
}
:root, /* Medium size is the default */
:host,
:host([size='small']),
.wa-size-s {
--wa-is-small: 1;
}
:where(:root), /* Medium size is the default */
:host([size='medium']),
.wa-size-m {
--wa-size: var(--size-m, var(--wa-font-size-m));
--wa-size-smaller: var(--size-s, var(--wa-font-size-s));
--wa-space: var(--space-m, var(--wa-space-m));
--wa-space-smaller: var(--space-s, var(--wa-space-s));
--wa-is-medium: 1;
}
:host([size='large']),
.wa-size-l {
--wa-size: var(--size-l);
--wa-size-smaller: var(--size-m);
--wa-space: var(--space-l);
--wa-space-smaller: var(--space-m);
--wa-is-large: 1;
}