mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-12 12:09:26 +00:00
Add orientation to radio group (#635)
* add orientation to radio group; fixes #613 * fix timing issue that prevents value from being set sometimes * gimme a break * make radio button examples horizontal --------- Co-authored-by: lindsaym-fa <dev@lindsaym.design>
This commit is contained in:
@@ -9,7 +9,7 @@ icon: radio-group
|
||||
Radio buttons are designed to be used with [radio groups](/docs/components/radio-group). When a radio button has focus, the arrow keys can be used to change the selected option just like standard radio controls.
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group label="Select an option" name="a" value="1">
|
||||
<wa-radio-group label="Select an option" orientation="horizontal" name="a" value="1">
|
||||
<wa-radio-button value="1">Option 1</wa-radio-button>
|
||||
<wa-radio-button value="2">Option 2</wa-radio-button>
|
||||
<wa-radio-button value="3">Option 3</wa-radio-button>
|
||||
@@ -23,7 +23,7 @@ Radio buttons are designed to be used with [radio groups](/docs/components/radio
|
||||
To set the initial value and checked state, use the `value` attribute on the containing radio group.
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group label="Select an option" name="a" value="1">
|
||||
<wa-radio-group label="Select an option" orientation="horizontal" name="a" value="1">
|
||||
<wa-radio-button value="1">Option 1</wa-radio-button>
|
||||
<wa-radio-button value="2">Option 2</wa-radio-button>
|
||||
<wa-radio-button value="3">Option 3</wa-radio-button>
|
||||
@@ -35,7 +35,7 @@ To set the initial value and checked state, use the `value` attribute on the con
|
||||
Use the `disabled` attribute to disable a radio button.
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group label="Select an option" name="a" value="1">
|
||||
<wa-radio-group label="Select an option" orientation="horizontal" name="a" value="1">
|
||||
<wa-radio-button value="1">Option 1</wa-radio-button>
|
||||
<wa-radio-button value="2" disabled>Option 2</wa-radio-button>
|
||||
<wa-radio-button value="3">Option 3</wa-radio-button>
|
||||
@@ -47,7 +47,7 @@ Use the `disabled` attribute to disable a radio button.
|
||||
Use the `size` attribute to change a radio button's size.
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group size="small" label="Select an option" name="a" value="1">
|
||||
<wa-radio-group size="small" label="Select an option" orientation="horizontal" name="a" value="1">
|
||||
<wa-radio-button value="1">Option 1</wa-radio-button>
|
||||
<wa-radio-button value="2">Option 2</wa-radio-button>
|
||||
<wa-radio-button value="3">Option 3</wa-radio-button>
|
||||
@@ -55,7 +55,7 @@ Use the `size` attribute to change a radio button's size.
|
||||
|
||||
<br />
|
||||
|
||||
<wa-radio-group size="medium" label="Select an option" name="a" value="1">
|
||||
<wa-radio-group size="medium" label="Select an option" orientation="horizontal" name="a" value="1">
|
||||
<wa-radio-button value="1">Option 1</wa-radio-button>
|
||||
<wa-radio-button value="2">Option 2</wa-radio-button>
|
||||
<wa-radio-button value="3">Option 3</wa-radio-button>
|
||||
@@ -63,7 +63,7 @@ Use the `size` attribute to change a radio button's size.
|
||||
|
||||
<br />
|
||||
|
||||
<wa-radio-group size="large" label="Select an option" name="a" value="1">
|
||||
<wa-radio-group size="large" label="Select an option" orientation="horizontal" name="a" value="1">
|
||||
<wa-radio-button value="1">Option 1</wa-radio-button>
|
||||
<wa-radio-button value="2">Option 2</wa-radio-button>
|
||||
<wa-radio-button value="3">Option 3</wa-radio-button>
|
||||
@@ -75,7 +75,7 @@ Use the `size` attribute to change a radio button's size.
|
||||
Use the `pill` attribute to give radio buttons rounded edges.
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group size="small" label="Select an option" name="a" value="1">
|
||||
<wa-radio-group size="small" label="Select an option" orientation="horizontal" name="a" value="1">
|
||||
<wa-radio-button pill value="1">Option 1</wa-radio-button>
|
||||
<wa-radio-button pill value="2">Option 2</wa-radio-button>
|
||||
<wa-radio-button pill value="3">Option 3</wa-radio-button>
|
||||
@@ -83,7 +83,7 @@ Use the `pill` attribute to give radio buttons rounded edges.
|
||||
|
||||
<br />
|
||||
|
||||
<wa-radio-group size="medium" label="Select an option" name="a" value="1">
|
||||
<wa-radio-group size="medium" label="Select an option" orientation="horizontal" name="a" value="1">
|
||||
<wa-radio-button pill value="1">Option 1</wa-radio-button>
|
||||
<wa-radio-button pill value="2">Option 2</wa-radio-button>
|
||||
<wa-radio-button pill value="3">Option 3</wa-radio-button>
|
||||
@@ -91,7 +91,7 @@ Use the `pill` attribute to give radio buttons rounded edges.
|
||||
|
||||
<br />
|
||||
|
||||
<wa-radio-group size="large" label="Select an option" name="a" value="1">
|
||||
<wa-radio-group size="large" label="Select an option" orientation="horizontal" name="a" value="1">
|
||||
<wa-radio-button pill value="1">Option 1</wa-radio-button>
|
||||
<wa-radio-button pill value="2">Option 2</wa-radio-button>
|
||||
<wa-radio-button pill value="3">Option 3</wa-radio-button>
|
||||
@@ -103,7 +103,7 @@ Use the `pill` attribute to give radio buttons rounded edges.
|
||||
Use the `prefix` and `suffix` slots to add icons.
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group label="Select an option" name="a" value="1">
|
||||
<wa-radio-group label="Select an option" orientation="horizontal" name="a" value="1">
|
||||
<wa-radio-button value="1">
|
||||
<wa-icon slot="prefix" name="archive" variant="solid"></wa-icon>
|
||||
Option 1
|
||||
@@ -127,7 +127,7 @@ Use the `prefix` and `suffix` slots to add icons.
|
||||
You can omit button labels and use icons instead. Make sure to set a `label` attribute on each icon so screen readers will announce each option correctly.
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group label="Select an option" name="a" value="neutral">
|
||||
<wa-radio-group label="Select an option" orientation="horizontal" name="a" value="neutral">
|
||||
<wa-radio-button value="angry">
|
||||
<wa-icon name="face-angry" variant="solid" label="Angry"></wa-icon>
|
||||
</wa-radio-button>
|
||||
|
||||
@@ -7,8 +7,8 @@ icon: radio-group
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group label="Select an option" name="a" value="1">
|
||||
<wa-radio value="1">Option 1</wa-radio><br>
|
||||
<wa-radio value="2">Option 2</wa-radio><br>
|
||||
<wa-radio value="1">Option 1</wa-radio>
|
||||
<wa-radio value="2">Option 2</wa-radio>
|
||||
<wa-radio value="3">Option 3</wa-radio>
|
||||
</wa-radio-group>
|
||||
```
|
||||
@@ -21,8 +21,8 @@ Add descriptive hint to a radio group with the `hint` attribute. For hints that
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group label="Select an option" hint="Choose the most appropriate option." name="a" value="1">
|
||||
<wa-radio value="1">Option 1</wa-radio><br>
|
||||
<wa-radio value="2">Option 2</wa-radio><br>
|
||||
<wa-radio value="1">Option 1</wa-radio>
|
||||
<wa-radio value="2">Option 2</wa-radio>
|
||||
<wa-radio value="3">Option 3</wa-radio>
|
||||
</wa-radio-group>
|
||||
```
|
||||
@@ -32,7 +32,28 @@ 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="Select an option" hint="Select an option that makes you proud." name="a" value="1">
|
||||
<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>
|
||||
<wa-radio-button value="2">Option 2</wa-radio-button>
|
||||
<wa-radio-button value="3">Option 3</wa-radio-button>
|
||||
</wa-radio-group>
|
||||
|
||||
<br>
|
||||
|
||||
<wa-radio-group
|
||||
label="Vertical options"
|
||||
hint="Select an option that makes you proud."
|
||||
orientation="vertical"
|
||||
name="a"
|
||||
value="1"
|
||||
style="max-width: 300px;"
|
||||
>
|
||||
<wa-radio-button value="1">Option 1</wa-radio-button>
|
||||
<wa-radio-button value="2">Option 2</wa-radio-button>
|
||||
<wa-radio-button value="3">Option 3</wa-radio-button>
|
||||
@@ -45,8 +66,26 @@ Radios and radio buttons can be disabled by adding the `disabled` attribute to t
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group label="Select an option" name="a" value="1">
|
||||
<wa-radio value="1">Option 1</wa-radio><br>
|
||||
<wa-radio value="2" disabled>Option 2</wa-radio><br>
|
||||
<wa-radio value="1">Option 1</wa-radio>
|
||||
<wa-radio value="2" disabled>Option 2</wa-radio>
|
||||
<wa-radio value="3">Option 3</wa-radio>
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
### Orientation
|
||||
|
||||
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"
|
||||
hint="Choose the most appropriate option."
|
||||
orientation="horizontal"
|
||||
name="a"
|
||||
value="1"
|
||||
>
|
||||
<wa-radio value="1">Option 1</wa-radio>
|
||||
<wa-radio value="2">Option 2</wa-radio>
|
||||
<wa-radio value="3">Option 3</wa-radio>
|
||||
</wa-radio-group>
|
||||
```
|
||||
@@ -57,8 +96,8 @@ The size of [Radios](/docs/components/radio) and [Radio Buttons](/docs/component
|
||||
|
||||
```html preview
|
||||
<wa-radio-group label="Select an option" size="medium" value="medium" class="radio-group-size">
|
||||
<wa-radio value="small">Small</wa-radio><br>
|
||||
<wa-radio value="medium">Medium</wa-radio><br>
|
||||
<wa-radio value="small">Small</wa-radio>
|
||||
<wa-radio value="medium">Medium</wa-radio>
|
||||
<wa-radio value="large">Large</wa-radio>
|
||||
</wa-radio-group>
|
||||
|
||||
@@ -82,8 +121,8 @@ Setting the `required` attribute to make selecting an option mandatory. If a val
|
||||
```html {.example}
|
||||
<form class="validation">
|
||||
<wa-radio-group label="Select an option" name="a" required>
|
||||
<wa-radio value="1">Option 1</wa-radio><br>
|
||||
<wa-radio value="2">Option 2</wa-radio><br>
|
||||
<wa-radio value="1">Option 1</wa-radio>
|
||||
<wa-radio value="2">Option 2</wa-radio>
|
||||
<wa-radio value="3">Option 3</wa-radio>
|
||||
</wa-radio-group>
|
||||
<br />
|
||||
@@ -108,8 +147,8 @@ Use the `setCustomValidity()` method to set a custom validation message. This wi
|
||||
```html {.example}
|
||||
<form class="custom-validity">
|
||||
<wa-radio-group label="Select an option" name="a" value="1">
|
||||
<wa-radio value="1">Not me</wa-radio><br>
|
||||
<wa-radio value="2">Me neither</wa-radio><br>
|
||||
<wa-radio value="1">Not me</wa-radio>
|
||||
<wa-radio value="2">Me neither</wa-radio>
|
||||
<wa-radio value="3">Choose me</wa-radio>
|
||||
</wa-radio-group>
|
||||
<br />
|
||||
@@ -127,7 +166,7 @@ Use the `setCustomValidity()` method to set a custom validation message. This wi
|
||||
});
|
||||
|
||||
// Update validity when a selection is made
|
||||
form.addEventlistener('change', () => {
|
||||
form.addEventListener('change', () => {
|
||||
const isValid = radioGroup.value === '3';
|
||||
radioGroup.setCustomValidity(isValid ? '' : errorMessage);
|
||||
});
|
||||
|
||||
@@ -11,8 +11,8 @@ Radios are designed to be used with [radio groups](/docs/components/radio-group)
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group label="Select an option" name="a" value="1">
|
||||
<wa-radio value="1">Option 1</wa-radio><br>
|
||||
<wa-radio value="2">Option 2</wa-radio><br>
|
||||
<wa-radio value="1">Option 1</wa-radio>
|
||||
<wa-radio value="2">Option 2</wa-radio>
|
||||
<wa-radio value="3">Option 3</wa-radio>
|
||||
</wa-radio-group>
|
||||
```
|
||||
@@ -29,8 +29,8 @@ To set the initial value and checked state, use the `value` attribute on the con
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group label="Select an option" name="a" value="3">
|
||||
<wa-radio value="1">Option 1</wa-radio><br>
|
||||
<wa-radio value="2">Option 2</wa-radio><br>
|
||||
<wa-radio value="1">Option 1</wa-radio>
|
||||
<wa-radio value="2">Option 2</wa-radio>
|
||||
<wa-radio value="3">Option 3</wa-radio>
|
||||
</wa-radio-group>
|
||||
```
|
||||
@@ -41,8 +41,8 @@ Use the `disabled` attribute to disable a radio.
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group label="Select an option" name="a" value="1">
|
||||
<wa-radio value="1">Option 1</wa-radio><br>
|
||||
<wa-radio value="2" disabled>Option 2</wa-radio><br>
|
||||
<wa-radio value="1">Option 1</wa-radio>
|
||||
<wa-radio value="2" disabled>Option 2</wa-radio>
|
||||
<wa-radio value="3">Option 3</wa-radio>
|
||||
</wa-radio-group>
|
||||
```
|
||||
@@ -53,24 +53,24 @@ Add the `size` attribute to the [Radio Group](/docs/components/radio-group) to c
|
||||
|
||||
```html {.example}
|
||||
<wa-radio-group size="small" value="1">
|
||||
<wa-radio value="1">Small 1</wa-radio><br>
|
||||
<wa-radio value="2">Small 2</wa-radio><br>
|
||||
<wa-radio value="1">Small 1</wa-radio>
|
||||
<wa-radio value="2">Small 2</wa-radio>
|
||||
<wa-radio value="3">Small 3</wa-radio>
|
||||
</wa-radio-group>
|
||||
|
||||
<br />
|
||||
|
||||
<wa-radio-group size="medium" value="1">
|
||||
<wa-radio value="1">Medium 1</wa-radio><br>
|
||||
<wa-radio value="2">Medium 2</wa-radio><br>
|
||||
<wa-radio value="1">Medium 1</wa-radio>
|
||||
<wa-radio value="2">Medium 2</wa-radio>
|
||||
<wa-radio value="3">Medium 3</wa-radio>
|
||||
</wa-radio-group>
|
||||
|
||||
<br />
|
||||
|
||||
<wa-radio-group size="large" value="1">
|
||||
<wa-radio value="1">Large 1</wa-radio><br>
|
||||
<wa-radio value="2">Large 2</wa-radio><br>
|
||||
<wa-radio value="1">Large 1</wa-radio>
|
||||
<wa-radio value="2">Large 2</wa-radio>
|
||||
<wa-radio value="3">Large 3</wa-radio>
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
@@ -20,6 +20,7 @@ During the alpha period, things might break! We take breaking changes very serio
|
||||
- `wa-blur` => `blur` (this event will no longer bubble, use `focusout` for a bubbling version)
|
||||
- `wa-focus` => `focus` (this event will no longer bubble)
|
||||
- Added `.wa-callout` utility class
|
||||
- Added the `orientation` attribute to `<wa-radio-group>` to support vertical and horizontal radio items
|
||||
- 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
|
||||
|
||||
|
||||
@@ -22,6 +22,26 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
[part~='form-control-input'] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--wa-space-s);
|
||||
margin-block-end: var(--wa-space-xs);
|
||||
}
|
||||
|
||||
/* Horizontal */
|
||||
:host([orientation='horizontal']) [part~='form-control-input'] {
|
||||
flex-direction: row;
|
||||
gap: var(--wa-space-m);
|
||||
}
|
||||
|
||||
/* When radio buttons are slotted */
|
||||
:host([orientation]) .form-control--has-radio-buttons [part~='form-control-input'] {
|
||||
gap: 0;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
/* Help text */
|
||||
[part~='hint'] {
|
||||
margin-block-start: var(--wa-space-2xs);
|
||||
|
||||
@@ -9,6 +9,7 @@ import { WebAwesomeFormAssociatedElement } from '../../internal/webawesome-form-
|
||||
import formControlStyles from '../../styles/shadow/form-control.css';
|
||||
import buttonGroupStyles from '../../styles/utilities/button-group.css';
|
||||
import sizeStyles from '../../styles/utilities/size.css';
|
||||
import '../radio-button/radio-button.js';
|
||||
import type WaRadioButton from '../radio-button/radio-button.js';
|
||||
import '../radio/radio.js';
|
||||
import type WaRadio from '../radio/radio.js';
|
||||
@@ -20,7 +21,8 @@ import styles from './radio-group.css';
|
||||
* @status stable
|
||||
* @since 2.0
|
||||
*
|
||||
* @dependency wa-button-group
|
||||
* @dependency wa-radio
|
||||
* @dependency wa-radio-button
|
||||
*
|
||||
* @slot - The default slot where `<wa-radio>` or `<wa-radio-button>` elements are placed.
|
||||
* @slot label - The radio group's label. Required for proper accessibility. Alternatively, you can use the `label`
|
||||
@@ -34,6 +36,7 @@ import styles from './radio-group.css';
|
||||
* @csspart form-control - The form control that wraps the label, input, and hint.
|
||||
* @csspart form-control-label - The label's wrapper.
|
||||
* @csspart form-control-input - The input's wrapper.
|
||||
* @csspart radios - The wrapper than surrounds radio items, styled as a flex container by default.
|
||||
* @csspart hint - The hint's wrapper.
|
||||
* @csspart button-group - The button group that wraps radio buttons.
|
||||
* @csspart button-group__base - The button group's `base` part.
|
||||
@@ -63,6 +66,7 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
@query('slot:not([name])') defaultSlot: HTMLSlotElement;
|
||||
|
||||
@state() private hasButtonGroup = false;
|
||||
@state() private hasRadioButtons = false;
|
||||
|
||||
/**
|
||||
* The radio group's label. Required for proper accessibility. If you need to display HTML, use the `label` slot
|
||||
@@ -76,6 +80,9 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
/** The name of the radio group, submitted as a name/value pair with form data. */
|
||||
@property({ reflect: true }) name: string | null = null;
|
||||
|
||||
/** The orientation in which to show radio items. */
|
||||
@property({ reflect: true }) orientation: 'horizontal' | 'vertical' = 'vertical';
|
||||
|
||||
private _value: string | null = null;
|
||||
|
||||
get value() {
|
||||
@@ -173,6 +180,9 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
private async syncRadioElements() {
|
||||
const radios = this.getAllRadios();
|
||||
|
||||
// Detect the presence of radio buttons
|
||||
this.hasRadioButtons = radios.some(radio => radio.localName === 'wa-radio-button');
|
||||
|
||||
await Promise.all(
|
||||
// Sync the checked state and size
|
||||
radios.map(async radio => {
|
||||
@@ -324,11 +334,13 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
'form-control--large': this.size === 'large',
|
||||
'form-control--radio-group': true,
|
||||
'form-control--has-label': hasLabel,
|
||||
'form-control--has-radio-buttons': this.hasRadioButtons,
|
||||
})}
|
||||
role="radiogroup"
|
||||
aria-labelledby="label"
|
||||
aria-describedby="hint"
|
||||
aria-errormessage="error-message"
|
||||
aria-orientation=${this.orientation}
|
||||
>
|
||||
<label
|
||||
part="form-control-label"
|
||||
@@ -342,7 +354,10 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
|
||||
<slot
|
||||
part="form-control-input"
|
||||
class=${classMap({ 'wa-button-group': this.hasButtonGroup })}
|
||||
class=${classMap({
|
||||
'wa-button-group': this.hasButtonGroup,
|
||||
'wa-button-group-vertical': this.orientation === 'vertical',
|
||||
})}
|
||||
@slotchange=${this.syncRadioElements}
|
||||
></slot>
|
||||
|
||||
|
||||
@@ -21,6 +21,10 @@ label:has(input[type='radio']),
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
:host {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
/* Replace native radio styles */
|
||||
input[type='radio'] {
|
||||
appearance: none;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
}
|
||||
|
||||
/* Horizontal */
|
||||
.wa-button-group:not([aria-orientation='vertical']) {
|
||||
.wa-button-group:not([aria-orientation='vertical']):not(.wa-button-group-vertical) {
|
||||
> :not(:first-child),
|
||||
&::slotted(:not(:first-child)) {
|
||||
border-start-start-radius: 0 !important;
|
||||
@@ -40,7 +40,8 @@
|
||||
}
|
||||
|
||||
/* Vertical */
|
||||
.wa-button-group[aria-orientation='vertical'] {
|
||||
.wa-button-group[aria-orientation='vertical'],
|
||||
.wa-button-group-vertical {
|
||||
flex-direction: column;
|
||||
|
||||
> :not(:first-child),
|
||||
|
||||
Reference in New Issue
Block a user