kopia lustrzana https://github.com/shoelace-style/shoelace
fix rating a11y
rodzic
578a58042b
commit
c94db27f07
|
@ -5,29 +5,43 @@
|
||||||
Ratings give users a way to quickly view and provide feedback.
|
Ratings give users a way to quickly view and provide feedback.
|
||||||
|
|
||||||
```html preview
|
```html preview
|
||||||
<sl-rating></sl-rating>
|
<sl-rating label="Rating"></sl-rating>
|
||||||
```
|
```
|
||||||
|
|
||||||
```jsx react
|
```jsx react
|
||||||
import { SlRating } from '@shoelace-style/shoelace/dist/react';
|
import { SlRating } from '@shoelace-style/shoelace/dist/react';
|
||||||
|
|
||||||
const App = () => <SlRating />;
|
const App = () => <SlRating label="Rating" />;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
### Labels
|
||||||
|
|
||||||
|
Ratings are commonly identified in context, so a visual label isn't typically necessary. However, you should always provide a label for assistive devices.
|
||||||
|
|
||||||
|
```html preview
|
||||||
|
<sl-rating label="Rate this component"></sl-rating>
|
||||||
|
```
|
||||||
|
|
||||||
|
```jsx react
|
||||||
|
import { SlRating } from '@shoelace-style/shoelace/dist/react';
|
||||||
|
|
||||||
|
const App = () => <SlRating label="Rate this component" />;
|
||||||
|
```
|
||||||
|
|
||||||
### Maximum Value
|
### Maximum Value
|
||||||
|
|
||||||
Ratings are 0-5 by default. To change the maximum possible value, use the `max` attribute.
|
Ratings are 0-5 by default. To change the maximum possible value, use the `max` attribute.
|
||||||
|
|
||||||
```html preview
|
```html preview
|
||||||
<sl-rating max="3"></sl-rating>
|
<sl-rating label="Rating" max="3"></sl-rating>
|
||||||
```
|
```
|
||||||
|
|
||||||
```jsx react
|
```jsx react
|
||||||
import { SlRating } from '@shoelace-style/shoelace/dist/react';
|
import { SlRating } from '@shoelace-style/shoelace/dist/react';
|
||||||
|
|
||||||
const App = () => <SlRating max={3} />;
|
const App = () => <SlRating label="Rating" max={3} />;
|
||||||
```
|
```
|
||||||
|
|
||||||
### Precision
|
### Precision
|
||||||
|
@ -35,13 +49,13 @@ const App = () => <SlRating max={3} />;
|
||||||
Use the `precision` attribute to let users select fractional ratings.
|
Use the `precision` attribute to let users select fractional ratings.
|
||||||
|
|
||||||
```html preview
|
```html preview
|
||||||
<sl-rating precision="0.5" value="2.5"></sl-rating>
|
<sl-rating label="Rating" precision="0.5" value="2.5"></sl-rating>
|
||||||
```
|
```
|
||||||
|
|
||||||
```jsx react
|
```jsx react
|
||||||
import { SlRating } from '@shoelace-style/shoelace/dist/react';
|
import { SlRating } from '@shoelace-style/shoelace/dist/react';
|
||||||
|
|
||||||
const App = () => <SlRating precision={0.5} value={2.5} />;
|
const App = () => <SlRating label="Rating" precision={0.5} value={2.5} />;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Symbol Sizes
|
## Symbol Sizes
|
||||||
|
@ -49,13 +63,13 @@ const App = () => <SlRating precision={0.5} value={2.5} />;
|
||||||
Set the `--symbol-size` custom property to adjust the size.
|
Set the `--symbol-size` custom property to adjust the size.
|
||||||
|
|
||||||
```html preview
|
```html preview
|
||||||
<sl-rating style="--symbol-size: 2rem;"></sl-rating>
|
<sl-rating label="Rating" style="--symbol-size: 2rem;"></sl-rating>
|
||||||
```
|
```
|
||||||
|
|
||||||
```jsx react
|
```jsx react
|
||||||
import { SlRating } from '@shoelace-style/shoelace/dist/react';
|
import { SlRating } from '@shoelace-style/shoelace/dist/react';
|
||||||
|
|
||||||
const App = () => <SlRating style={{ '--symbol-size': '2rem' }} />;
|
const App = () => <SlRating label="Rating" style={{ '--symbol-size': '2rem' }} />;
|
||||||
```
|
```
|
||||||
|
|
||||||
### Readonly
|
### Readonly
|
||||||
|
@ -63,13 +77,13 @@ const App = () => <SlRating style={{ '--symbol-size': '2rem' }} />;
|
||||||
Use the `readonly` attribute to display a rating that users can't change.
|
Use the `readonly` attribute to display a rating that users can't change.
|
||||||
|
|
||||||
```html preview
|
```html preview
|
||||||
<sl-rating readonly value="3"></sl-rating>
|
<sl-rating label="Rating" readonly value="3"></sl-rating>
|
||||||
```
|
```
|
||||||
|
|
||||||
```jsx react
|
```jsx react
|
||||||
import { SlRating } from '@shoelace-style/shoelace/dist/react';
|
import { SlRating } from '@shoelace-style/shoelace/dist/react';
|
||||||
|
|
||||||
const App = () => <SlRating readonly value={3} />;
|
const App = () => <SlRating label="Rating" readonly value={3} />;
|
||||||
```
|
```
|
||||||
|
|
||||||
### Disabled
|
### Disabled
|
||||||
|
@ -77,13 +91,13 @@ const App = () => <SlRating readonly value={3} />;
|
||||||
Use the `disable` attribute to disable the rating.
|
Use the `disable` attribute to disable the rating.
|
||||||
|
|
||||||
```html preview
|
```html preview
|
||||||
<sl-rating disabled value="3"></sl-rating>
|
<sl-rating label="Rating" disabled value="3"></sl-rating>
|
||||||
```
|
```
|
||||||
|
|
||||||
```jsx react
|
```jsx react
|
||||||
import { SlRating } from '@shoelace-style/shoelace/dist/react';
|
import { SlRating } from '@shoelace-style/shoelace/dist/react';
|
||||||
|
|
||||||
const App = () => <SlRating disabled value={3} />;
|
const App = () => <SlRating label="Rating" disabled value={3} />;
|
||||||
```
|
```
|
||||||
|
|
||||||
### Custom Icons
|
### Custom Icons
|
||||||
|
@ -91,7 +105,7 @@ const App = () => <SlRating disabled value={3} />;
|
||||||
You can provide custom icons by passing a function to the `getSymbol` property.
|
You can provide custom icons by passing a function to the `getSymbol` property.
|
||||||
|
|
||||||
```html preview
|
```html preview
|
||||||
<sl-rating class="rating-hearts" style="--symbol-color-active: #ff4136;"></sl-rating>
|
<sl-rating label="Rating" class="rating-hearts" style="--symbol-color-active: #ff4136;"></sl-rating>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const rating = document.querySelector('.rating-hearts');
|
const rating = document.querySelector('.rating-hearts');
|
||||||
|
@ -104,7 +118,11 @@ import '@shoelace-style/shoelace/dist/components/icon/icon';
|
||||||
import { SlRating } from '@shoelace-style/shoelace/dist/react';
|
import { SlRating } from '@shoelace-style/shoelace/dist/react';
|
||||||
|
|
||||||
const App = () => (
|
const App = () => (
|
||||||
<SlRating getSymbol={() => '<sl-icon name="heart-fill"></sl-icon>'} style={{ '--symbol-color-active': '#ff4136' }} />
|
<SlRating
|
||||||
|
label="Rating"
|
||||||
|
getSymbol={() => '<sl-icon name="heart-fill"></sl-icon>'}
|
||||||
|
style={{ '--symbol-color-active': '#ff4136' }}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -113,7 +131,7 @@ const App = () => (
|
||||||
You can also use the `getSymbol` property to render different icons based on value.
|
You can also use the `getSymbol` property to render different icons based on value.
|
||||||
|
|
||||||
```html preview
|
```html preview
|
||||||
<sl-rating class="rating-emojis"></sl-rating>
|
<sl-rating label="Rating" class="rating-emojis"></sl-rating>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const rating = document.querySelector('.rating-emojis');
|
const rating = document.querySelector('.rating-emojis');
|
||||||
|
@ -134,7 +152,7 @@ function getSymbol(value) {
|
||||||
return `<sl-icon name="${icons[value - 1]}"></sl-icon>`;
|
return `<sl-icon name="${icons[value - 1]}"></sl-icon>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const App = () => <SlRating getSymbol={getSymbol} />;
|
const App = () => <SlRating label="Rating" getSymbol={getSymbol} />;
|
||||||
```
|
```
|
||||||
|
|
||||||
[component-metadata:sl-rating]
|
[component-metadata:sl-rating]
|
||||||
|
|
|
@ -12,9 +12,11 @@ _During the beta period, these restrictions may be relaxed in the event of a mis
|
||||||
|
|
||||||
- 🚨 BREAKING: removed the `base` part from `<sl-menu>` and removed an unnecessary `<div>` that made styling more difficult
|
- 🚨 BREAKING: removed the `base` part from `<sl-menu>` and removed an unnecessary `<div>` that made styling more difficult
|
||||||
- Added read-only custom properties `--auto-size-available-width` and `--auto-size-available-height` to `<sl-popup>` to improve support for overflowing popup content
|
- Added read-only custom properties `--auto-size-available-width` and `--auto-size-available-height` to `<sl-popup>` to improve support for overflowing popup content
|
||||||
|
- Added `label` to `<sl-rating>` to improve accessibility for screen readers
|
||||||
- Fixed a bug where auto-size wasn't being applied to `<sl-dropdown>` and `<sl-select>`
|
- Fixed a bug where auto-size wasn't being applied to `<sl-dropdown>` and `<sl-select>`
|
||||||
- Fixed a bug in `<sl-popup>` that caused auto-size to kick in before flip
|
- Fixed a bug in `<sl-popup>` that caused auto-size to kick in before flip
|
||||||
- Fixed a bug in `<sl-popup>` that prevented the `arrow-padding` attribute from working as expected
|
- Fixed a bug in `<sl-popup>` that prevented the `arrow-padding` attribute from working as expected
|
||||||
|
- Improved accessibility of `<sl-rating>` so keyboard nav works better and screen readers announce it properly
|
||||||
- Improved accessibility of `<sl-spinner>` so screen readers no longer skip over it
|
- Improved accessibility of `<sl-spinner>` so screen readers no longer skip over it
|
||||||
- Removed the default hover effect in `<sl-tree-items>` to make selections more obvious
|
- Removed the default hover effect in `<sl-tree-items>` to make selections more obvious
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,9 @@ export default class SlRating extends LitElement {
|
||||||
@state() private hoverValue = 0;
|
@state() private hoverValue = 0;
|
||||||
@state() private isHovering = false;
|
@state() private isHovering = false;
|
||||||
|
|
||||||
|
/** A label to describe the rating to assistive devices. */
|
||||||
|
@property() label = '';
|
||||||
|
|
||||||
/** The current rating. */
|
/** The current rating. */
|
||||||
@property({ type: Number }) value = 0;
|
@property({ type: Number }) value = 0;
|
||||||
|
|
||||||
|
@ -104,13 +107,13 @@ export default class SlRating extends LitElement {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((isLtr && event.key === 'ArrowLeft') || (isRtl && event.key === 'ArrowRight')) {
|
if (event.key === 'ArrowDown' || (isLtr && event.key === 'ArrowLeft') || (isRtl && event.key === 'ArrowRight')) {
|
||||||
const decrement = event.shiftKey ? 1 : this.precision;
|
const decrement = event.shiftKey ? 1 : this.precision;
|
||||||
this.value = Math.max(0, this.value - decrement);
|
this.value = Math.max(0, this.value - decrement);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((isLtr && event.key === 'ArrowRight') || (isRtl && event.key === 'ArrowLeft')) {
|
if (event.key === 'ArrowUp' || (isLtr && event.key === 'ArrowRight') || (isRtl && event.key === 'ArrowLeft')) {
|
||||||
const increment = event.shiftKey ? 1 : this.precision;
|
const increment = event.shiftKey ? 1 : this.precision;
|
||||||
this.value = Math.min(this.max, this.value + increment);
|
this.value = Math.min(this.max, this.value + increment);
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
@ -189,6 +192,8 @@ export default class SlRating extends LitElement {
|
||||||
'rating--disabled': this.disabled,
|
'rating--disabled': this.disabled,
|
||||||
'rating--rtl': isRtl
|
'rating--rtl': isRtl
|
||||||
})}
|
})}
|
||||||
|
role="slider"
|
||||||
|
aria-label=${this.label}
|
||||||
aria-disabled=${this.disabled ? 'true' : 'false'}
|
aria-disabled=${this.disabled ? 'true' : 'false'}
|
||||||
aria-readonly=${this.readonly ? 'true' : 'false'}
|
aria-readonly=${this.readonly ? 'true' : 'false'}
|
||||||
aria-valuenow=${this.value}
|
aria-valuenow=${this.value}
|
||||||
|
|
Ładowanie…
Reference in New Issue