Compare commits

...

6 Commits

Author SHA1 Message Date
Cory LaViska
270403e634 backport SL-2353 2025-02-03 12:30:19 -05:00
Cory LaViska
99f0273783 fix placeholder token (#652) 2025-02-03 17:03:34 +00:00
Cory LaViska
8e13683a30 Select tag fix (#651)
* add tag-counter part to wa-select

* on second thought
2025-02-03 16:48:46 +00:00
Cory LaViska
fd73542d2c restore slot detection for non-SSR environments (#649) 2025-02-03 16:21:53 +00:00
Cory LaViska
bde0ed7403 add orientation example and use utils for spacing (#648) 2025-02-03 15:46:51 +00:00
Cory LaViska
8dc49f7119 fix event listeners (#647) 2025-02-03 10:07:21 -05:00
11 changed files with 113 additions and 57 deletions

View File

@@ -450,7 +450,7 @@ Use the `--aspect-ratio` custom property to customize the size of the carousel's
const carousel = document.querySelector('wa-carousel.aspect-ratio');
const aspectRatio = document.querySelector('wa-select[name="aspect"]');
aspectRatio.addEventlistener('change', () => {
aspectRatio.addEventListener('change', () => {
carousel.style.setProperty('--aspect-ratio', aspectRatio.value);
});
})();

View File

@@ -82,7 +82,7 @@ Use the `setCustomValidity()` method to set a custom validation message. This wi
});
// Update validity on change
checkbox.addEventlistener('change', () => {
checkbox.addEventListener('change', () => {
checkbox.setCustomValidity(checkbox.checked ? '' : errorMessage);
});

View File

@@ -208,7 +208,7 @@ Try resizing the example below with each option and notice how the panels respon
const splitPanel = container.querySelector('wa-split-panel');
const select = container.querySelector('wa-select');
select.addEventlistener('change', () => (splitPanel.primary = select.value));
select.addEventListener('change', () => (splitPanel.primary = select.value));
</script>
```

View File

@@ -88,7 +88,7 @@ The `selection` attribute lets you change the selection behavior of the tree.
const selectionMode = document.querySelector('#selection-mode');
const tree = document.querySelector('.tree-selectable');
selectionMode.addEventlistener('change', () => {
selectionMode.addEventListener('change', () => {
tree.querySelectorAll('wa-tree-item').forEach(item => (item.selected = false));
tree.selection = selectionMode.value;
});

View File

@@ -803,7 +803,7 @@ hasOutline: false
const queue = [];
let inputTimeout;
variantInput.addEventlistener('change', () => {
variantInput.addEventListener('change', () => {
iconList.dataset.variant = variantInput.value;
});
@@ -1084,10 +1084,10 @@ hasOutline: false
el.classList.add(`wa-theme-${theme}-${colorMode}`);
}
colorModeSelect.addEventlistener('change', setColorMode);
colorModeSelect.addEventListener('change', setColorMode);
// Theme Switcher
themeSelect.addEventlistener('change', event => {
themeSelect.addEventListener('change', event => {
const theme = event.target.value
const newStylesheet = Object.assign(document.createElement("link"), {
// This media: "print" allows us to lazy load the stylesheet then hot swap it on load.
@@ -1132,14 +1132,14 @@ hasOutline: false
});
// Color Palette
colorSelect.addEventlistener('change', event => {
colorSelect.addEventListener('change', event => {
const colorPalette = event.target.value;
colorStylesheet.href = `/dist/styles/themes/color/${colorPalette}.css`;
});
// Brand Color
brandColor.addEventlistener('change', event => {
brandColor.addEventListener('change', event => {
const documentStyles = document.documentElement.style
documentStyles.setProperty('--wa-color-primary-95', `var(--wa-color-${event.target.value}-95)`);
documentStyles.setProperty('--wa-color-primary-90', `var(--wa-color-${event.target.value}-90)`);
@@ -1223,7 +1223,7 @@ hasOutline: false
})
// Pre-generated logos
logoSelector.addEventlistener('change', event => {
logoSelector.addEventListener('change', event => {
const value = event.currentTarget.value
const projectLogo = previewContainer.querySelector("#project-logo");
@@ -1279,7 +1279,7 @@ hasOutline: false
})
}
themeSelect.addEventlistener('change', setLogoIcons);
themeSelect.addEventListener('change', setLogoIcons);
// Project Name
container.querySelector('[name="project-name"]').addEventListener('input', event => {
@@ -1293,7 +1293,7 @@ hasOutline: false
});
// Heading text
fontFamilyHeading.addEventlistener('change', event => {
fontFamilyHeading.addEventListener('change', event => {
let fontFamily;
switch (event.target.value) {
case 'assistant':
@@ -1351,7 +1351,7 @@ hasOutline: false
})
// Body text
fontFamilyBody.addEventlistener('change', event => {
fontFamilyBody.addEventListener('change', event => {
let fontFamily;
switch (event.target.value) {
case 'assistant':
@@ -1580,7 +1580,7 @@ hasOutline: false
}
// Swaps icons to the preferred set for the selected theme
themeSelect.addEventlistener('change', event => {
themeSelect.addEventListener('change', event => {
setPreferredIcons();
showIconStyleOptions();
syncLogoIcon();
@@ -1599,13 +1599,13 @@ hasOutline: false
});
// Changes available Icon Styles and swaps icons based on the selected Icon Family
iconFamily.addEventlistener('change', event => {
iconFamily.addEventListener('change', event => {
useFaIcons();
showIconStyleOptions();
});
// Swaps icons based on the selected Icon Style
iconStyle.addEventlistener('change', useFaIcons);
iconStyle.addEventListener('change', useFaIcons);
// Corners

View File

@@ -9,19 +9,11 @@ elements:
file: styles/native/radio.css
---
<style>
label {
display: inline-block;
}
label + label {
margin-inline-start: var(--wa-space);
}
</style>
```html {.example}
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2"> Option 2</label>
<div class="wa-cluster">
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2"> Option 2</label>
</div>
```
## Examples
@@ -31,9 +23,11 @@ file: styles/native/radio.css
To set the initial value and checked state, use the `checked` attribute on the corresponding radio.
```html {.example}
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2"> Option 2</label>
<label><input type="radio" name="radio" value="3" checked> Option 3</label>
<div class="wa-cluster">
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2"> Option 2</label>
<label><input type="radio" name="radio" value="3" checked> Option 3</label>
</div>
```
### Disabled
@@ -41,9 +35,11 @@ To set the initial value and checked state, use the `checked` attribute on the c
Use the `disabled` attribute to disable a radio.
```html {.example}
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2" disabled> Option 2</label>
<label><input type="radio" name="radio" value="3"> Option 3</label>
<div class="wa-cluster">
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2" disabled> Option 2</label>
<label><input type="radio" name="radio" value="3"> Option 3</label>
</div>
```
### Sizes
@@ -51,27 +47,47 @@ Use the `disabled` attribute to disable a radio.
Use the [size utilities](/docs/utilities/size) to change the radios' size.
```html {.example}
<fieldset class="wa-size-s">
<legend>Small</legend>
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2"> Option 2</label>
<label><input type="radio" name="radio" value="3"> Option 3</label>
<fieldset class="wa-size-s wa-cluster">
<legend>Small</legend>
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2"> Option 2</label>
<label><input type="radio" name="radio" value="3"> Option 3</label>
</fieldset>
<br />
<fieldset class="wa-size-m">
<legend>Medium</legend>
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2"> Option 2</label>
<label><input type="radio" name="radio" value="3"> Option 3</label>
<fieldset class="wa-size-m wa-cluster">
<legend>Medium</legend>
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2"> Option 2</label>
<label><input type="radio" name="radio" value="3"> Option 3</label>
</fieldset>
<br />
<fieldset class="wa-size-l">
<legend>Large</legend>
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2"> Option 2</label>
<label><input type="radio" name="radio" value="3"> Option 3</label>
<fieldset class="wa-size-l wa-cluster">
<legend>Large</legend>
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2"> Option 2</label>
<label><input type="radio" name="radio" value="3"> Option 3</label>
</fieldset>
```
### Orientation
You can wrap native radios in a flex container to give them a horizontal or vertical orientation with even spacing. The convenience [`wa-cluster`](/docs/utilities/cluster) and [`wa-stack`](/docs/utilities/stack) utilities make this easy.
```html {.example}
<div class="wa-cluster">
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2"> Option 2</label>
<label><input type="radio" name="radio" value="3" checked> Option 3</label>
</div>
```
```html {.example}
<div class="wa-stack">
<label><input type="radio" name="radio" value="1"> Option 1</label>
<label><input type="radio" name="radio" value="2"> Option 2</label>
<label><input type="radio" name="radio" value="3" checked> Option 3</label>
</div>
```

View File

@@ -12,6 +12,16 @@ Components with the <wa-badge variant="warning" pill>Experimental</wa-badge> bad
During the alpha period, things might break! We take breaking changes very seriously, but sometimes they're necessary to make the final product that much better. We appreciate your patience!
:::
## Next
- Added an orientation example to the native radio docs
- Added the `tag` part (and associated exported parts) to `<wa-select>` to allow targeting the tag that shows when more than the max number of visible items have been selected
- Fixed a number of broken event listeners throughout the docs
- Fixed a bug in `<wa-card>` that prevented slots from showing automatically without `with-` attributes
- Fixed a bug in `<wa-select>` that prevented the placeholder color from being customized with the `--wa-form-control-placeholder-color` token
- Improved accessibility of `<wa-carousel>`
## 3.0.0-alpha.10
- 🚨 BREAKING: updated all components to use native events instead of `wa-` prefixed events. This will allow components to work more like native elements in your code, frameworks, third-party plugins, etc. To update your code, simply remove the prefix from your event listeners for the following events.

View File

@@ -1,5 +1,6 @@
import { html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { HasSlotController } from '../../internal/slot.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import sizeStyles from '../../styles/utilities/size.css';
import styles from './card.css';
@@ -28,17 +29,26 @@ import styles from './card.css';
export default class WaCard extends WebAwesomeElement {
static shadowStyle = [sizeStyles, styles];
private readonly hasSlotController = new HasSlotController(this, 'footer', 'header', 'image');
/** 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;
@property({ attribute: 'with-header', type: Boolean, reflect: true }) withHeader = false;
/** Renders the card with an image. Only needed for SSR, otherwise is automatically added. */
@property({ attribute: 'with-image', type: Boolean }) withImage = false;
@property({ attribute: 'with-image', type: Boolean, reflect: true }) withImage = false;
/** Renders the card with a footer. Only needed for SSR, otherwise is automatically added. */
@property({ attribute: 'with-footer', type: Boolean }) withFooter = false;
@property({ attribute: 'with-footer', type: Boolean, reflect: true }) withFooter = false;
updated() {
// Enable the respective slots when detected
if (!this.withHeader && this.hasSlotController.test('header')) this.withHeader = true;
if (!this.withImage && this.hasSlotController.test('image')) this.withImage = true;
if (!this.withFooter && this.hasSlotController.test('footer')) this.withFooter = true;
}
render() {
return html`

View File

@@ -378,8 +378,16 @@ export default class WaCarousel extends WebAwesomeElement {
this.getSlides({ excludeClones: false }).forEach((slide, index) => {
slide.classList.remove('--in-view');
slide.classList.remove('--is-active');
slide.setAttribute('role', 'group');
slide.setAttribute('aria-label', this.localize.term('slideNum', index + 1));
if (this.pagination) {
slide.setAttribute('role', 'tabpanel');
slide.removeAttribute('aria-label');
slide.setAttribute('aria-labelledby', `tab-${index + 1}`);
slide.setAttribute('id', `slide-${index + 1}`);
}
if (slide.hasAttribute('data-clone')) {
slide.remove();
}
@@ -633,7 +641,7 @@ export default class WaCarousel extends WebAwesomeElement {
: ''}
${this.pagination
? html`
<div part="pagination" role="tablist" class="pagination" aria-controls="scroll-container">
<div part="pagination" role="tablist" class="pagination">
${map(range(pagesCount), index => {
const isActive = index === currentPage;
return html`
@@ -644,8 +652,10 @@ export default class WaCarousel extends WebAwesomeElement {
'pagination-item--active': isActive,
})}"
role="tab"
id="tab-${index + 1}"
aria-controls="slide-${index + 1}"
aria-selected="${isActive ? 'true' : 'false'}"
aria-label="${this.localize.term('goToSlide', index + 1, pagesCount)}"
${isActive ? '' : `aria-label="${this.localize.term('goToSlide', index + 1, pagesCount)}"`}
tabindex=${isActive ? '0' : '-1'}
@click=${() => this.goToSlide(index * slidesPerMove)}
@keydown=${this.handleKeyDown}

View File

@@ -72,7 +72,7 @@
}
&::placeholder {
color: var(--wa-form-controls-placeholder-color);
color: var(--wa-form-control-placeholder-color);
}
}

View File

@@ -68,7 +68,6 @@ import styles from './select.css';
* @csspart listbox - The listbox container where options are slotted.
* @csspart tags - The container that houses option tags when `multiselect` is used.
* @csspart tag - The individual tags that represent each multiselect option.
* @csspart tag__base - The tag's base part.
* @csspart tag__content - The tag's content part.
* @csspart tag__remove-button - The tag's remove button.
* @csspart tag__remove-button__base - The tag's remove button base part.
@@ -661,7 +660,18 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement {
</div>`;
} else if (index === this.maxOptionsVisible) {
// Hit tag limit
return html`<wa-tag>+${this.selectedOptions.length - index}</wa-tag>`;
return html`
<wa-tag
part="tag"
exportparts="
base:tag__base,
content:tag__content,
remove-button:tag__remove-button,
remove-button__base:tag__remove-button__base
"
>+${this.selectedOptions.length - index}</wa-tag
>
`;
}
return html``;
});