mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-21 00:04:15 +00:00
Compare commits
34 Commits
konnorroge
...
react-exam
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a884a0c1f0 | ||
|
|
847ad26814 | ||
|
|
e943572d36 | ||
|
|
62f2b1c0fb | ||
|
|
c98945a885 | ||
|
|
e42ac799af | ||
|
|
dbbe580ef1 | ||
|
|
fb33dd7036 | ||
|
|
dc12e16d83 | ||
|
|
2e7096c66f | ||
|
|
700ccff3cd | ||
|
|
530673dcd1 | ||
|
|
5d5ac5576e | ||
|
|
39b5737a7f | ||
|
|
2157b209a2 | ||
|
|
4942eaedb3 | ||
|
|
ca6ebecfdc | ||
|
|
77e1708657 | ||
|
|
42b711b45a | ||
|
|
ca524a03f3 | ||
|
|
4ee831f18a | ||
|
|
8430d6076b | ||
|
|
9c17b0e16b | ||
|
|
1d1080f2e4 | ||
|
|
a715e0c1b6 | ||
|
|
a134b1a359 | ||
|
|
d0b673c99d | ||
|
|
55ba270b83 | ||
|
|
db94c609bd | ||
|
|
823bac0174 | ||
|
|
2423af3da2 | ||
|
|
81a3f29650 | ||
|
|
1b509dd44b | ||
|
|
a326671a21 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,7 +4,6 @@ _site
|
||||
package.json
|
||||
package-lock.json
|
||||
dist
|
||||
docs/assets/images/sprite.svg
|
||||
docs/public/pagefind
|
||||
node_modules
|
||||
src/react
|
||||
|
||||
@@ -22,8 +22,6 @@ export function codeExamplesPlugin(options = {}) {
|
||||
// Look for external links
|
||||
container.querySelectorAll('code.example').forEach(code => {
|
||||
const pre = code.closest('pre');
|
||||
const adjacentPre = pre.nextElementSibling?.localName === 'pre' ? pre.nextElementSibling : null;
|
||||
const adjacentPreForReact = adjacentPre?.querySelector('code.react') ? adjacentPre.querySelector('code') : null;
|
||||
const hasButtons = !code.classList.contains('no-buttons');
|
||||
const isOpen = code.classList.contains('open') || !hasButtons;
|
||||
const noEdit = code.classList.contains('no-edit');
|
||||
@@ -41,18 +39,7 @@ export function codeExamplesPlugin(options = {}) {
|
||||
${preview}
|
||||
</div>
|
||||
<div class="code-example-source" id="${id}">
|
||||
<wa-tab-group>
|
||||
<wa-tab slot="nav" panel="html">HTML</wa-tab>
|
||||
<wa-tab-panel name="html">${pre.outerHTML}</wa-tab-panel>
|
||||
${
|
||||
adjacentPreForReact
|
||||
? `
|
||||
<wa-tab slot="nav" panel="react">React</wa-tab>
|
||||
<wa-tab-panel name="react">${adjacentPre.outerHTML}</wa-tab-panel>
|
||||
`
|
||||
: ''
|
||||
}
|
||||
</wa-tab-group>
|
||||
${pre.outerHTML}
|
||||
</div>
|
||||
${
|
||||
hasButtons
|
||||
@@ -87,7 +74,6 @@ export function codeExamplesPlugin(options = {}) {
|
||||
`);
|
||||
|
||||
pre.replaceWith(codeExample);
|
||||
adjacentPre?.remove();
|
||||
});
|
||||
|
||||
return doc.toString();
|
||||
|
||||
@@ -11,19 +11,6 @@ layout: component.njk
|
||||
></wa-animated-image>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaAnimatedImage from '@shoelace-style/shoelace/dist/react/animated-image';
|
||||
|
||||
const App = () => (
|
||||
<WaAnimatedImage
|
||||
src="https://shoelace.style/assets/images/walk.gif"
|
||||
alt="Animation of untied shoes walking on pavement"
|
||||
/>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::info
|
||||
This component uses `<canvas>` to draw freeze frames, so images are subject to [cross-origin restrictions](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image).
|
||||
:::
|
||||
@@ -41,16 +28,6 @@ Both GIF and WEBP images are supported.
|
||||
></wa-animated-image>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaAnimatedImage from '@shoelace-style/shoelace/dist/react/animated-image';
|
||||
|
||||
const App = () => (
|
||||
<WaAnimatedImage src="https://shoelace.style/assets/images/tie.webp" alt="Animation of a shoe being tied" />
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Setting a Width and Height
|
||||
|
||||
To set a custom size, apply a width and/or height to the host element.
|
||||
@@ -64,20 +41,6 @@ To set a custom size, apply a width and/or height to the host element.
|
||||
</wa-animated-image>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaAnimatedImage from '@shoelace-style/shoelace/dist/react/animated-image';
|
||||
|
||||
const App = () => (
|
||||
<WaAnimatedImage
|
||||
src="https://shoelace.style/assets/images/walk.gif"
|
||||
alt="Animation of untied shoes walking on pavement"
|
||||
style={{ width: '150px', height: '200px' }}
|
||||
/>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Customizing the Control Box
|
||||
|
||||
You can change the appearance and location of the control box by targeting the `control-box` part in your styles.
|
||||
@@ -101,33 +64,3 @@ You can change the appearance and location of the control box by targeting the `
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaAnimatedImage from '@shoelace-style/shoelace/dist/react/animated-image';
|
||||
|
||||
const css = `
|
||||
.animated-image-custom-control-box::part(control-box) {
|
||||
top: auto;
|
||||
right: auto;
|
||||
bottom: 1rem;
|
||||
left: 1rem;
|
||||
background-color: deeppink;
|
||||
border: none;
|
||||
color: pink;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaAnimatedImage
|
||||
className="animated-image-custom-control-box"
|
||||
src="https://shoelace.style/assets/images/walk.gif"
|
||||
alt="Animation of untied shoes walking on pavement"
|
||||
/>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -25,43 +25,6 @@ To animate an element, wrap it in `<wa-animation>` and set an animation `name`.
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaAnimation from '@shoelace-style/shoelace/dist/react/animation';
|
||||
|
||||
const css = `
|
||||
.animation-overview .box {
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: var(--wa-color-brand-spot);
|
||||
margin: 1.5rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<div class="animation-overview">
|
||||
<WaAnimation name="bounce" duration={2000} play>
|
||||
<div class="box" />
|
||||
</WaAnimation>
|
||||
<WaAnimation name="jello" duration={2000} play>
|
||||
<div class="box" />
|
||||
</WaAnimation>
|
||||
<WaAnimation name="heartBeat" duration={2000} play>
|
||||
<div class="box" />
|
||||
</WaAnimation>
|
||||
<WaAnimation name="flip" duration={2000} play>
|
||||
<div class="box" />
|
||||
</WaAnimation>
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::info
|
||||
The animation will only be applied to the first child element found in `<wa-animation>`.
|
||||
:::
|
||||
@@ -136,12 +99,6 @@ This example demonstrates all of the baked-in animations and easings. Animations
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Using Intersection Observer
|
||||
|
||||
Use an [Intersection Observer](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) to control the animation when an element enters or exits the viewport. For example, scroll the box below in and out of your screen. The animation stops when the box exits the viewport and restarts each time it enters the viewport.
|
||||
@@ -179,58 +136,6 @@ Use an [Intersection Observer](https://developer.mozilla.org/en-US/docs/Web/API/
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import WaAnimation from '@shoelace-style/shoelace/dist/react/animation';
|
||||
|
||||
const css = `
|
||||
.animation-scroll {
|
||||
height: calc(100vh + 100px);
|
||||
}
|
||||
|
||||
.animation-scroll .box {
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: var(--wa-color-brand-spot);
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => {
|
||||
const animation = useRef(null);
|
||||
const box = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(entries => {
|
||||
if (entries[0].isIntersecting) {
|
||||
animation.current.play = true;
|
||||
} else {
|
||||
animation.current.play = false;
|
||||
animation.current.currentTime = 0;
|
||||
}
|
||||
});
|
||||
|
||||
if (box.current) {
|
||||
observer.observe(box.current);
|
||||
}
|
||||
}, [box]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div class="animation-scroll">
|
||||
<WaAnimation ref={animation} name="jackInTheBox" duration={2000} iterations={1}>
|
||||
<div ref={box} class="box" />
|
||||
</WaAnimation>
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Custom Keyframe Formats
|
||||
|
||||
Supply your own [keyframe formats](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API/Keyframe_Formats) to build custom animations.
|
||||
@@ -271,52 +176,6 @@ Supply your own [keyframe formats](https://developer.mozilla.org/en-US/docs/Web/
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaAnimation from '@shoelace-style/shoelace/dist/react/animation';
|
||||
|
||||
const css = `
|
||||
.animation-keyframes .box {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: var(--wa-color-brand-spot);
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<div class="animation-keyframes">
|
||||
<WaAnimation
|
||||
easing="ease-in-out"
|
||||
duration={2000}
|
||||
play
|
||||
keyframes={[
|
||||
{
|
||||
offset: 0,
|
||||
easing: 'cubic-bezier(0.250, 0.460, 0.450, 0.940)',
|
||||
fillMode: 'both',
|
||||
transformOrigin: 'center center',
|
||||
transform: 'rotate(0)'
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
easing: 'cubic-bezier(0.250, 0.460, 0.450, 0.940)',
|
||||
fillMode: 'both',
|
||||
transformOrigin: 'center center',
|
||||
transform: 'rotate(90deg)'
|
||||
}
|
||||
]}
|
||||
>
|
||||
<div class="box" />
|
||||
</WaAnimation>
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Playing Animations on Demand
|
||||
|
||||
Animations won't play until you apply the `play` attribute. You can omit it initially, then apply it on demand such as after a user interaction. In this example, the button will animate once every time the button is clicked.
|
||||
@@ -338,25 +197,3 @@ Animations won't play until you apply the `play` attribute. You can omit it init
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaAnimation from '@shoelace-style/shoelace/dist/react/animation';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
|
||||
const App = () => {
|
||||
const [play, setPlay] = useState(false);
|
||||
|
||||
return (
|
||||
<div class="animation-form">
|
||||
<WaAnimation name="rubberBand" duration={1000} iterations={1} play={play} onWaFinish={() => setPlay(false)}>
|
||||
<WaButton variant="brand" onClick={() => setPlay(true)}>
|
||||
Click me
|
||||
</WaButton>
|
||||
</WaAnimation>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -10,14 +10,6 @@ By default, a generic icon will be shown. You can personalize avatars by adding
|
||||
<wa-avatar label="User avatar"></wa-avatar>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaAvatar from '@shoelace-style/shoelace/dist/react/avatar';
|
||||
|
||||
const App = () => <WaAvatar label="User avatar" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Images
|
||||
@@ -37,24 +29,6 @@ Avatar images can be lazily loaded by setting the `loading` attribute to `lazy`.
|
||||
></wa-avatar>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaAvatar from '@shoelace-style/shoelace/dist/react/avatar';
|
||||
|
||||
const App = () => (
|
||||
<WaAvatar
|
||||
image="https://images.unsplash.com/photo-1529778873920-4da4926a72c2?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80"
|
||||
label="Avatar of a gray tabby kitten looking down"
|
||||
/>
|
||||
<WaAvatar
|
||||
image="https://images.unsplash.com/photo-1591871937573-74dbba515c4c?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80"
|
||||
label="Avatar of a white and grey kitten on grey textile"
|
||||
loading="lazy"
|
||||
/>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Initials
|
||||
|
||||
When you don't have an image to use, you can set the `initials` attribute to show something more personalized than an icon.
|
||||
@@ -63,14 +37,6 @@ When you don't have an image to use, you can set the `initials` attribute to sho
|
||||
<wa-avatar initials="WA" label="Avatar with initials: SL"></wa-avatar>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaAvatar from '@shoelace-style/shoelace/dist/react/avatar';
|
||||
|
||||
const App = () => <WaAvatar initials="WA" label="Avatar with initials: SL" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Custom Icons
|
||||
|
||||
When no image or initials are set, an icon will be shown. The default avatar shows a generic "user" icon, but you can customize this with the `icon` slot.
|
||||
@@ -89,29 +55,6 @@ When no image or initials are set, an icon will be shown. The default avatar sho
|
||||
</wa-avatar>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaAvatar from '@shoelace-style/shoelace/dist/react/avatar';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaAvatar label="Avatar with an image icon">
|
||||
<WaIcon slot="icon" name="image" />
|
||||
</WaAvatar>
|
||||
|
||||
<WaAvatar label="Avatar with an archive icon">
|
||||
<WaIcon slot="icon" name="archive" />
|
||||
</WaAvatar>
|
||||
|
||||
<WaAvatar label="Avatar with a briefcase icon">
|
||||
<WaIcon slot="icon" name="briefcase" />
|
||||
</WaAvatar>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Shapes
|
||||
|
||||
Avatars can be shaped using the `shape` attribute.
|
||||
@@ -122,21 +65,6 @@ Avatars can be shaped using the `shape` attribute.
|
||||
<wa-avatar shape="circle" label="Circle avatar"></wa-avatar>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaAvatar from '@shoelace-style/shoelace/dist/react/avatar';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaAvatar shape="square" label="Square avatar" />
|
||||
<WaAvatar shape="rounded" label="Rounded avatar" />
|
||||
<WaAvatar shape="circle" label="Circle avatar" />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Avatar Groups
|
||||
|
||||
You can group avatars with a few lines of CSS.
|
||||
@@ -174,48 +102,3 @@ You can group avatars with a few lines of CSS.
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaAvatar from '@shoelace-style/shoelace/dist/react/avatar';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
|
||||
const css = `
|
||||
.avatar-group wa-avatar:not(:first-of-type) {
|
||||
margin-left: calc(-1 * var(--wa-space-m));
|
||||
}
|
||||
|
||||
.avatar-group wa-avatar::part(base) {
|
||||
border: solid 2px var(--wa-color-surface-default);
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<div className="avatar-group">
|
||||
<WaAvatar
|
||||
image="https://images.unsplash.com/photo-1490150028299-bf57d78394e0?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=256&h=256&q=80&crop=right"
|
||||
label="Avatar 1 of 4"
|
||||
/>
|
||||
|
||||
<WaAvatar
|
||||
image="https://images.unsplash.com/photo-1503454537195-1dcabb73ffb9?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=256&h=256&crop=left&q=80"
|
||||
label="Avatar 2 of 4"
|
||||
/>
|
||||
|
||||
<WaAvatar
|
||||
image="https://images.unsplash.com/photo-1456439663599-95b042d50252?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=256&h=256&crop=left&q=80"
|
||||
label="Avatar 3 of 4"
|
||||
/>
|
||||
|
||||
<WaAvatar
|
||||
image="https://images.unsplash.com/flagged/photo-1554078875-e37cb8b0e27d?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=256&h=256&crop=top&q=80"
|
||||
label="Avatar 4 of 4"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -8,14 +8,6 @@ layout: component.njk
|
||||
<wa-badge>Badge</wa-badge>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaBadge from '@shoelace-style/shoelace/dist/react/badge';
|
||||
|
||||
const App = () => <WaBadge>Badge</WaBadge>;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Variants
|
||||
@@ -30,22 +22,6 @@ Set the `variant` attribute to change the badge's variant.
|
||||
<wa-badge variant="danger">Danger</wa-badge>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaBadge from '@shoelace-style/shoelace/dist/react/badge';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaBadge variant="brand">Brand</WaBadge>
|
||||
<WaBadge variant="success">Success</WaBadge>
|
||||
<WaBadge variant="neutral">Neutral</WaBadge>
|
||||
<WaBadge variant="warning">Warning</WaBadge>
|
||||
<WaBadge variant="danger">Danger</WaBadge>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Pill Badges
|
||||
|
||||
Use the `pill` attribute to give badges rounded edges.
|
||||
@@ -58,32 +34,6 @@ Use the `pill` attribute to give badges rounded edges.
|
||||
<wa-badge variant="danger" pill>Danger</wa-badge>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaBadge from '@shoelace-style/shoelace/dist/react/badge';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaBadge variant="brand" pill>
|
||||
Brand
|
||||
</WaBadge>
|
||||
<WaBadge variant="success" pill>
|
||||
Success
|
||||
</WaBadge>
|
||||
<WaBadge variant="neutral" pill>
|
||||
Neutral
|
||||
</WaBadge>
|
||||
<WaBadge variant="warning" pill>
|
||||
Warning
|
||||
</WaBadge>
|
||||
<WaBadge variant="danger" pill>
|
||||
Danger
|
||||
</WaBadge>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Pulsating Badges
|
||||
|
||||
Use the `pulse` attribute to draw attention to the badge with a subtle animation.
|
||||
@@ -104,42 +54,6 @@ Use the `pulse` attribute to draw attention to the badge with a subtle animation
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaBadge from '@shoelace-style/shoelace/dist/react/badge';
|
||||
|
||||
const css = `
|
||||
.badge-pulse wa-badge:not(:last-of-type) {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<div className="badge-pulse">
|
||||
<WaBadge variant="brand" pill pulse>
|
||||
1
|
||||
</WaBadge>
|
||||
<WaBadge variant="success" pill pulse>
|
||||
1
|
||||
</WaBadge>
|
||||
<WaBadge variant="neutral" pill pulse>
|
||||
1
|
||||
</WaBadge>
|
||||
<WaBadge variant="warning" pill pulse>
|
||||
1
|
||||
</WaBadge>
|
||||
<WaBadge variant="danger" pill pulse>
|
||||
1
|
||||
</WaBadge>
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### With Buttons
|
||||
|
||||
One of the most common use cases for badges is attaching them to buttons. To make this easier, badges will be automatically positioned at the top-right when they're a child of a button.
|
||||
@@ -161,36 +75,6 @@ One of the most common use cases for badges is attaching them to buttons. To mak
|
||||
</wa-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaBadge from '@shoelace-style/shoelace/dist/react/badge';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaButton>
|
||||
Requests
|
||||
<WaBadge pill>30</WaBadge>
|
||||
</WaButton>
|
||||
|
||||
<WaButton style={{ marginInlineStart: '1rem' }}>
|
||||
Warnings
|
||||
<WaBadge variant="warning" pill>
|
||||
8
|
||||
</WaBadge>
|
||||
</WaButton>
|
||||
|
||||
<WaButton style={{ marginInlineStart: '1rem' }}>
|
||||
Errors
|
||||
<WaBadge variant="danger" pill>
|
||||
6
|
||||
</WaBadge>
|
||||
</WaButton>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### With Menu Items
|
||||
|
||||
When including badges in menu items, use the `suffix` slot to make sure they're aligned correctly.
|
||||
@@ -202,33 +86,3 @@ When including badges in menu items, use the `suffix` slot to make sure they're
|
||||
<wa-menu-item>Replies <wa-badge slot="suffix" variant="neutral" pill>12</wa-badge></wa-menu-item>
|
||||
</wa-menu>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaBadge from '@shoelace-style/shoelace/dist/react/badge';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
import WaMenuLabel from '@shoelace-style/shoelace/dist/react/menu-label';
|
||||
|
||||
const App = () => (
|
||||
<WaMenu
|
||||
style={{ maxWidth: '240px' }}
|
||||
>
|
||||
<WaMenuLabel>Messages</WaMenuLabel>
|
||||
<WaMenuItem>
|
||||
Comments
|
||||
<WaBadge slot="suffix" variant="neutral" pill>
|
||||
4
|
||||
</WaBadge>
|
||||
</WaMenuItem>
|
||||
<WaMenuItem>
|
||||
Replies
|
||||
<WaBadge slot="suffix" variant="neutral" pill>
|
||||
12
|
||||
</WaBadge>
|
||||
</WaMenuItem>
|
||||
</WaMenu>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -15,25 +15,6 @@ layout: component.njk
|
||||
</wa-breadcrumb>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaBreadcrumb from '@shoelace-style/shoelace/dist/react/breadcrumb';
|
||||
import WaBreadcrumbItem from '@shoelace-style/shoelace/dist/react/breadcrumb-item';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
|
||||
const App = () => (
|
||||
<WaBreadcrumb>
|
||||
<WaBreadcrumbItem>
|
||||
<WaIcon slot="prefix" name="house"></WaIcon>
|
||||
Home
|
||||
</WaBreadcrumbItem>
|
||||
<WaBreadcrumbItem>Clothing</WaBreadcrumbItem>
|
||||
<WaBreadcrumbItem>Shirts</WaBreadcrumbItem>
|
||||
</WaBreadcrumb>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::info
|
||||
Additional demonstrations can be found in the [breadcrumb examples](/components/breadcrumb).
|
||||
:::
|
||||
|
||||
@@ -15,22 +15,6 @@ Breadcrumbs are usually placed before a page's main content with the current pag
|
||||
</wa-breadcrumb>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaBreadcrumb from '@shoelace-style/shoelace/dist/react/breadcrumb';
|
||||
import WaBreadcrumbItem from '@shoelace-style/shoelace/dist/react/breadcrumb-item';
|
||||
|
||||
const App = () => (
|
||||
<WaBreadcrumb>
|
||||
<WaBreadcrumbItem>Catalog</WaBreadcrumbItem>
|
||||
<WaBreadcrumbItem>Clothing</WaBreadcrumbItem>
|
||||
<WaBreadcrumbItem>Women's</WaBreadcrumbItem>
|
||||
<WaBreadcrumbItem>Shirts & Tops</WaBreadcrumbItem>
|
||||
</WaBreadcrumb>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Breadcrumb Links
|
||||
@@ -51,25 +35,6 @@ For websites, you'll probably want to use links instead. You can make any breadc
|
||||
</wa-breadcrumb>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaBreadcrumb from '@shoelace-style/shoelace/dist/react/breadcrumb';
|
||||
import WaBreadcrumbItem from '@shoelace-style/shoelace/dist/react/breadcrumb-item';
|
||||
|
||||
const App = () => (
|
||||
<WaBreadcrumb>
|
||||
<WaBreadcrumbItem href="https://example.com/home">Homepage</WaBreadcrumbItem>
|
||||
|
||||
<WaBreadcrumbItem href="https://example.com/home/services">Our Services</WaBreadcrumbItem>
|
||||
|
||||
<WaBreadcrumbItem href="https://example.com/home/services/digital">Digital Media</WaBreadcrumbItem>
|
||||
|
||||
<WaBreadcrumbItem href="https://example.com/home/services/digital/web-design">Web Design</WaBreadcrumbItem>
|
||||
</WaBreadcrumb>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Custom Separators
|
||||
|
||||
Use the `separator` slot to change the separator that goes between breadcrumb items. Icons work well, but you can also use text or an image.
|
||||
@@ -101,43 +66,6 @@ Use the `separator` slot to change the separator that goes between breadcrumb it
|
||||
</wa-breadcrumb>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import '@shoelace-style/shoelace/dist/components/icon/icon.js';
|
||||
import WaBreadcrumb from '@shoelace-style/shoelace/dist/react/breadcrumb';
|
||||
import WaBreadcrumbItem from '@shoelace-style/shoelace/dist/react/breadcrumb-item';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaBreadcrumb>
|
||||
<wa-icon slot="separator" name="angles-right" variant="solid" />
|
||||
<WaBreadcrumbItem>First</WaBreadcrumbItem>
|
||||
<WaBreadcrumbItem>Second</WaBreadcrumbItem>
|
||||
<WaBreadcrumbItem>Third</WaBreadcrumbItem>
|
||||
</WaBreadcrumb>
|
||||
|
||||
<br />
|
||||
|
||||
<WaBreadcrumb>
|
||||
<wa-icon slot="separator" name="arrow-right" variant="solid" />
|
||||
<WaBreadcrumbItem>First</WaBreadcrumbItem>
|
||||
<WaBreadcrumbItem>Second</WaBreadcrumbItem>
|
||||
<WaBreadcrumbItem>Third</WaBreadcrumbItem>
|
||||
</WaBreadcrumb>
|
||||
|
||||
<br />
|
||||
|
||||
<WaBreadcrumb>
|
||||
<span slot="separator">/</span>
|
||||
<WaBreadcrumbItem>First</WaBreadcrumbItem>
|
||||
<WaBreadcrumbItem>Second</WaBreadcrumbItem>
|
||||
<WaBreadcrumbItem>Third</WaBreadcrumbItem>
|
||||
</WaBreadcrumb>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Prefixes
|
||||
|
||||
Use the `prefix` slot to add content before any breadcrumb item.
|
||||
@@ -153,25 +81,6 @@ Use the `prefix` slot to add content before any breadcrumb item.
|
||||
</wa-breadcrumb>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaBreadcrumb from '@shoelace-style/shoelace/dist/react/breadcrumb';
|
||||
import WaBreadcrumbItem from '@shoelace-style/shoelace/dist/react/breadcrumb-item';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
|
||||
const App = () => (
|
||||
<WaBreadcrumb>
|
||||
<WaBreadcrumbItem>
|
||||
<WaIcon slot="prefix" name="house" variant="solid" />
|
||||
Home
|
||||
</WaBreadcrumbItem>
|
||||
<WaBreadcrumbItem>Articles</WaBreadcrumbItem>
|
||||
<WaBreadcrumbItem>Traveling</WaBreadcrumbItem>
|
||||
</WaBreadcrumb>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Suffixes
|
||||
|
||||
Use the `suffix` slot to add content after any breadcrumb item.
|
||||
@@ -187,25 +96,6 @@ Use the `suffix` slot to add content after any breadcrumb item.
|
||||
</wa-breadcrumb>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaBreadcrumb from '@shoelace-style/shoelace/dist/react/breadcrumb';
|
||||
import WaBreadcrumbItem from '@shoelace-style/shoelace/dist/react/breadcrumb-item';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
|
||||
const App = () => (
|
||||
<WaBreadcrumb>
|
||||
<WaBreadcrumbItem>Documents</WaBreadcrumbItem>
|
||||
<WaBreadcrumbItem>Policies</WaBreadcrumbItem>
|
||||
<WaBreadcrumbItem>
|
||||
Security
|
||||
<WaIcon slot="suffix" name="shield" variant="solid"></WaIcon>
|
||||
</WaBreadcrumbItem>
|
||||
</WaBreadcrumb>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### With Dropdowns
|
||||
|
||||
Dropdown menus can be placed in a prefix or suffix slot to provide additional options.
|
||||
@@ -230,40 +120,3 @@ Dropdown menus can be placed in a prefix or suffix slot to provide additional op
|
||||
</wa-breadcrumb-item>
|
||||
</wa-breadcrumb>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import {
|
||||
WaBreadcrumb,
|
||||
WaBreadcrumbItem,
|
||||
WaButton,
|
||||
WaDropdown,
|
||||
WaIcon,
|
||||
WaMenu,
|
||||
WaMenuItem
|
||||
} from '@shoelace-style/shoelace/dist/react';
|
||||
|
||||
const App = () => (
|
||||
<WaBreadcrumb>
|
||||
<WaBreadcrumbItem>Homepage</WaBreadcrumbItem>
|
||||
<WaBreadcrumbItem>Our Services</WaBreadcrumbItem>
|
||||
<WaBreadcrumbItem>Digital Media</WaBreadcrumbItem>
|
||||
<WaBreadcrumbItem>
|
||||
Web Design
|
||||
<WaDropdown slot="suffix">
|
||||
<WaButton slot="trigger" size="small" pill>
|
||||
<WaIcon label="More options" name="ellipsis"></WaIcon>
|
||||
</WaButton>
|
||||
<WaMenu>
|
||||
<WaMenuItem type="checkbox" checked>
|
||||
Web Design
|
||||
</WaMenuItem>
|
||||
<WaMenuItem type="checkbox">Web Development</WaMenuItem>
|
||||
<WaMenuItem type="checkbox">Marketing</WaMenuItem>
|
||||
</WaMenu>
|
||||
</WaDropdown>
|
||||
</WaBreadcrumbItem>
|
||||
</WaBreadcrumb>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -12,21 +12,6 @@ layout: component.njk
|
||||
</wa-button-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaButtonGroup from '@shoelace-style/shoelace/dist/react/button-group';
|
||||
|
||||
const App = () => (
|
||||
<WaButtonGroup label="Alignment">
|
||||
<WaButton>Left</WaButton>
|
||||
<WaButton>Center</WaButton>
|
||||
<WaButton>Right</WaButton>
|
||||
</WaButtonGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Button Sizes
|
||||
@@ -57,41 +42,6 @@ All button sizes are supported, but avoid mixing sizes within the same button gr
|
||||
</wa-button-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaButtonGroup from '@shoelace-style/shoelace/dist/react/button-group';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaButtonGroup label="Alignment">
|
||||
<WaButton size="small">Left</WaButton>
|
||||
<WaButton size="small">Center</WaButton>
|
||||
<WaButton size="small">Right</WaButton>
|
||||
</WaButtonGroup>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<WaButtonGroup label="Alignment">
|
||||
<WaButton size="medium">Left</WaButton>
|
||||
<WaButton size="medium">Center</WaButton>
|
||||
<WaButton size="medium">Right</WaButton>
|
||||
</WaButtonGroup>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<WaButtonGroup label="Alignment">
|
||||
<WaButton size="large">Left</WaButton>
|
||||
<WaButton size="large">Center</WaButton>
|
||||
<WaButton size="large">Right</WaButton>
|
||||
</WaButtonGroup>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Theme Buttons
|
||||
|
||||
Theme buttons are supported through the button's `variant` attribute.
|
||||
@@ -136,59 +86,6 @@ Theme buttons are supported through the button's `variant` attribute.
|
||||
</wa-button-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaButtonGroup from '@shoelace-style/shoelace/dist/react/button-group';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaButtonGroup label="Alignment">
|
||||
<WaButton variant="brand">Left</WaButton>
|
||||
<WaButton variant="brand">Center</WaButton>
|
||||
<WaButton variant="brand">Right</WaButton>
|
||||
</WaButtonGroup>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<WaButtonGroup label="Alignment">
|
||||
<WaButton variant="success">Left</WaButton>
|
||||
<WaButton variant="success">Center</WaButton>
|
||||
<WaButton variant="success">Right</WaButton>
|
||||
</WaButtonGroup>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<WaButtonGroup label="Alignment">
|
||||
<WaButton>Left</WaButton>
|
||||
<WaButton>Center</WaButton>
|
||||
<WaButton>Right</WaButton>
|
||||
</WaButtonGroup>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<WaButtonGroup label="Alignment">
|
||||
<WaButton variant="warning">Left</WaButton>
|
||||
<WaButton variant="warning">Center</WaButton>
|
||||
<WaButton variant="warning">Right</WaButton>
|
||||
</WaButtonGroup>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<WaButtonGroup label="Alignment">
|
||||
<WaButton variant="danger">Left</WaButton>
|
||||
<WaButton variant="danger">Center</WaButton>
|
||||
<WaButton variant="danger">Right</WaButton>
|
||||
</WaButtonGroup>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Pill Buttons
|
||||
|
||||
Pill buttons are supported through the button's `pill` attribute.
|
||||
@@ -217,59 +114,6 @@ Pill buttons are supported through the button's `pill` attribute.
|
||||
</wa-button-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaButtonGroup from '@shoelace-style/shoelace/dist/react/button-group';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaButtonGroup label="Alignment">
|
||||
<WaButton size="small" pill>
|
||||
Left
|
||||
</WaButton>
|
||||
<WaButton size="small" pill>
|
||||
Center
|
||||
</WaButton>
|
||||
<WaButton size="small" pill>
|
||||
Right
|
||||
</WaButton>
|
||||
</WaButtonGroup>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<WaButtonGroup label="Alignment">
|
||||
<WaButton size="medium" pill>
|
||||
Left
|
||||
</WaButton>
|
||||
<WaButton size="medium" pill>
|
||||
Center
|
||||
</WaButton>
|
||||
<WaButton size="medium" pill>
|
||||
Right
|
||||
</WaButton>
|
||||
</WaButtonGroup>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<WaButtonGroup label="Alignment">
|
||||
<WaButton size="large" pill>
|
||||
Left
|
||||
</WaButton>
|
||||
<WaButton size="large" pill>
|
||||
Center
|
||||
</WaButton>
|
||||
<WaButton size="large" pill>
|
||||
Right
|
||||
</WaButton>
|
||||
</WaButtonGroup>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Dropdowns in Button Groups
|
||||
|
||||
Dropdowns can be placed inside button groups as long as the trigger is an `<wa-button>` element.
|
||||
@@ -289,33 +133,6 @@ Dropdowns can be placed inside button groups as long as the trigger is an `<wa-b
|
||||
</wa-button-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaButtonGroup from '@shoelace-style/shoelace/dist/react/button-group';
|
||||
import WaDropdown from '@shoelace-style/shoelace/dist/react/dropdown';
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => (
|
||||
<WaButtonGroup label="Example Button Group">
|
||||
<WaButton>Button</WaButton>
|
||||
<WaButton>Button</WaButton>
|
||||
<WaDropdown>
|
||||
<WaButton slot="trigger" caret>
|
||||
Dropdown
|
||||
</WaButton>
|
||||
<WaMenu>
|
||||
<WaMenuItem>Item 1</WaMenuItem>
|
||||
<WaMenuItem>Item 2</WaMenuItem>
|
||||
<WaMenuItem>Item 3</WaMenuItem>
|
||||
</WaMenu>
|
||||
</WaDropdown>
|
||||
</WaButtonGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Split Buttons
|
||||
|
||||
Create a split button using a button and a dropdown. Use a [visually hidden](/components/visually-hidden) label to ensure the dropdown is accessible to users with assistive devices.
|
||||
@@ -336,76 +153,22 @@ Create a split button using a button and a dropdown. Use a [visually hidden](/co
|
||||
</wa-button-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaButtonGroup from '@shoelace-style/shoelace/dist/react/button-group';
|
||||
import WaDropdown from '@shoelace-style/shoelace/dist/react/dropdown';
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => (
|
||||
<WaButtonGroup label="Example Button Group">
|
||||
<WaButton variant="brand">Save</WaButton>
|
||||
<WaDropdown placement="bottom-end">
|
||||
<WaButton slot="trigger" variant="brand" caret></WaButton>
|
||||
<WaMenu>
|
||||
<WaMenuItem>Save</WaMenuItem>
|
||||
<WaMenuItem>Save as…</WaMenuItem>
|
||||
<WaMenuItem>Save all</WaMenuItem>
|
||||
</WaMenu>
|
||||
</WaDropdown>
|
||||
</WaButtonGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Tooltips in Button Groups
|
||||
|
||||
Buttons can be wrapped in tooltips to provide more detail when the user interacts with them.
|
||||
|
||||
```html {.example}
|
||||
<wa-button-group label="Alignment">
|
||||
<wa-tooltip content="I'm on the left">
|
||||
<wa-button>Left</wa-button>
|
||||
</wa-tooltip>
|
||||
|
||||
<wa-tooltip content="I'm in the middle">
|
||||
<wa-button>Center</wa-button>
|
||||
</wa-tooltip>
|
||||
|
||||
<wa-tooltip content="I'm on the right">
|
||||
<wa-button>Right</wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-button id="button-left">Left</wa-button>
|
||||
<wa-button id="button-center">Center</wa-button>
|
||||
<wa-button id="button-right">Right</wa-button>
|
||||
</wa-button-group>
|
||||
|
||||
<wa-tooltip for="button-left">I'm on the left</wa-tooltip>
|
||||
<wa-tooltip for="button-center">I'm in the middle</wa-tooltip>
|
||||
<wa-tooltip for="button-right">I'm on the right</wa-tooltip>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaButtonGroup from '@shoelace-style/shoelace/dist/react/button-group';
|
||||
import WaTooltip from '@shoelace-style/shoelace/dist/react/tooltip';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaButtonGroup label="Alignment">
|
||||
<WaTooltip content="I'm on the left">
|
||||
<WaButton>Left</WaButton>
|
||||
</WaTooltip>
|
||||
|
||||
<WaTooltip content="I'm in the middle">
|
||||
<WaButton>Center</WaButton>
|
||||
</WaTooltip>
|
||||
|
||||
<WaTooltip content="I'm on the right">
|
||||
<WaButton>Right</WaButton>
|
||||
</WaTooltip>
|
||||
</WaButtonGroup>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Toolbar Example
|
||||
|
||||
Create interactive toolbars with button groups.
|
||||
@@ -413,114 +176,36 @@ Create interactive toolbars with button groups.
|
||||
```html {.example}
|
||||
<div class="button-group-toolbar">
|
||||
<wa-button-group label="History">
|
||||
<wa-tooltip content="Undo">
|
||||
<wa-button><wa-icon name="undo" variant="solid" label="Undo"></wa-icon></wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip content="Redo">
|
||||
<wa-button><wa-icon name="redo" variant="solid" label="Redo"></wa-icon></wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-button id="undo-button"><wa-icon name="undo" variant="solid" label="Undo"></wa-icon></wa-button>
|
||||
<wa-button id="redo-button"><wa-icon name="redo" variant="solid" label="Redo"></wa-icon></wa-button>
|
||||
</wa-button-group>
|
||||
|
||||
<wa-button-group label="Formatting">
|
||||
<wa-tooltip content="Bold">
|
||||
<wa-button><wa-icon name="bold" variant="solid" label="Bold"></wa-icon></wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip content="Italic">
|
||||
<wa-button><wa-icon name="italic" variant="solid" label="Italic"></wa-icon></wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip content="Underline">
|
||||
<wa-button><wa-icon name="underline" variant="solid" label="Underline"></wa-icon></wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-button id="button-bold"><wa-icon name="bold" variant="solid" label="Bold"></wa-icon></wa-button>
|
||||
<wa-button id="button-italic"><wa-icon name="italic" variant="solid" label="Italic"></wa-icon></wa-button>
|
||||
<wa-button id="button-underline"><wa-icon name="underline" variant="solid" label="Underline"></wa-icon></wa-button>
|
||||
</wa-button-group>
|
||||
|
||||
<wa-button-group label="Alignment">
|
||||
<wa-tooltip content="Align Left">
|
||||
<wa-button><wa-icon name="align-left" variant="solid" label="Align Left"></wa-icon></wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip content="Align Center">
|
||||
<wa-button><wa-icon name="align-center" variant="solid" label="Align Center"></wa-icon></wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip content="Align Right">
|
||||
<wa-button><wa-icon name="align-right" variant="solid" label="Align Right"></wa-icon></wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-button id="button-align-left"><wa-icon name="align-left" variant="solid" label="Align Left"></wa-icon></wa-button>
|
||||
<wa-button id="button-align-center"><wa-icon name="align-center" variant="solid" label="Align Center"></wa-icon></wa-button>
|
||||
<wa-button id="button-align-right"><wa-icon name="align-right" variant="solid" label="Align Right"></wa-icon></wa-button>
|
||||
</wa-button-group>
|
||||
</div>
|
||||
|
||||
<wa-tooltip for="undo-button">Undo</wa-tooltip>
|
||||
<wa-tooltip for="redo-button">Redo</wa-tooltip>
|
||||
<wa-tooltip for="button-bold">Bold</wa-tooltip>
|
||||
<wa-tooltip for="button-italic">Italic</wa-tooltip>
|
||||
<wa-tooltip for="button-underline">Underline</wa-tooltip>
|
||||
|
||||
<wa-tooltip for="button-align-left">Align Left</wa-tooltip>
|
||||
<wa-tooltip for="button-align-center">Align Center</wa-tooltip>
|
||||
<wa-tooltip for="button-align-right">Align Right</wa-tooltip>
|
||||
|
||||
<style>
|
||||
.button-group-toolbar wa-button-group:not(:last-of-type) {
|
||||
margin-right: var(--wa-space-xs);
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaButtonGroup from '@shoelace-style/shoelace/dist/react/button-group';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
import WaTooltip from '@shoelace-style/shoelace/dist/react/tooltip';
|
||||
|
||||
const css = `
|
||||
.button-group-toolbar wa-button-group:not(:last-of-type) {
|
||||
margin-right: var(--wa-space-xs);
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<div className="button-group-toolbar">
|
||||
<WaButtonGroup label="History">
|
||||
<WaTooltip content="Undo">
|
||||
<WaButton>
|
||||
<WaIcon name="undo" variant="solid"></WaIcon>
|
||||
</WaButton>
|
||||
</WaTooltip>
|
||||
<WaTooltip content="Redo">
|
||||
<WaButton>
|
||||
<WaIcon name="redo" variant="solid"></WaIcon>
|
||||
</WaButton>
|
||||
</WaTooltip>
|
||||
</WaButtonGroup>
|
||||
|
||||
<WaButtonGroup label="Formatting">
|
||||
<WaTooltip content="Bold">
|
||||
<WaButton>
|
||||
<WaIcon name="bold" variant="solid"></WaIcon>
|
||||
</WaButton>
|
||||
</WaTooltip>
|
||||
<WaTooltip content="Italic">
|
||||
<WaButton>
|
||||
<WaIcon name="italic" variant="solid"></WaIcon>
|
||||
</WaButton>
|
||||
</WaTooltip>
|
||||
<WaTooltip content="Underline">
|
||||
<WaButton>
|
||||
<WaIcon name="underline" variant="solid"></WaIcon>
|
||||
</WaButton>
|
||||
</WaTooltip>
|
||||
</WaButtonGroup>
|
||||
|
||||
<WaButtonGroup label="Alignment">
|
||||
<WaTooltip content="Align Left">
|
||||
<WaButton>
|
||||
<WaIcon name="align-left" variant="solid"></WaIcon>
|
||||
</WaButton>
|
||||
</WaTooltip>
|
||||
<WaTooltip content="Align Center">
|
||||
<WaButton>
|
||||
<WaIcon name="align-center" variant="solid"></WaIcon>
|
||||
</WaButton>
|
||||
</WaTooltip>
|
||||
<WaTooltip content="Align Right">
|
||||
<WaButton>
|
||||
<WaIcon name="align-right" variant="solid"></WaIcon>
|
||||
</WaButton>
|
||||
</WaTooltip>
|
||||
</WaButtonGroup>
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -8,14 +8,6 @@ layout: component.njk
|
||||
<wa-button>Button</wa-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
|
||||
const App = () => <WaButton>Button</WaButton>;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Variants
|
||||
@@ -30,22 +22,6 @@ Use the `variant` attribute to set the button's variant.
|
||||
<wa-button variant="danger">Danger</wa-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaButton variant="brand">Brand</WaButton>
|
||||
<WaButton variant="success">Success</WaButton>
|
||||
<WaButton variant="neutral">Neutral</WaButton>
|
||||
<WaButton variant="warning">Warning</WaButton>
|
||||
<WaButton variant="danger">Danger</WaButton>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Sizes
|
||||
|
||||
Use the `size` attribute to change a button's size.
|
||||
@@ -56,20 +32,6 @@ Use the `size` attribute to change a button's size.
|
||||
<wa-button size="large">Large</wa-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaButton size="small">Small</WaButton>
|
||||
<WaButton size="medium">Medium</WaButton>
|
||||
<WaButton size="large">Large</WaButton>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Outline Buttons
|
||||
|
||||
Use the `outline` attribute to draw outlined buttons with transparent backgrounds.
|
||||
@@ -82,32 +44,6 @@ Use the `outline` attribute to draw outlined buttons with transparent background
|
||||
<wa-button variant="danger" outline>Danger</wa-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaButton variant="brand" outline>
|
||||
Brand
|
||||
</WaButton>
|
||||
<WaButton variant="success" outline>
|
||||
Success
|
||||
</WaButton>
|
||||
<WaButton variant="neutral" outline>
|
||||
Neutral
|
||||
</WaButton>
|
||||
<WaButton variant="warning" outline>
|
||||
Warning
|
||||
</WaButton>
|
||||
<WaButton variant="danger" outline>
|
||||
Danger
|
||||
</WaButton>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Pill Buttons
|
||||
|
||||
Use the `pill` attribute to give buttons rounded edges.
|
||||
@@ -118,26 +54,6 @@ Use the `pill` attribute to give buttons rounded edges.
|
||||
<wa-button size="large" pill>Large</wa-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaButton size="small" pill>
|
||||
Small
|
||||
</WaButton>
|
||||
<WaButton size="medium" pill>
|
||||
Medium
|
||||
</WaButton>
|
||||
<WaButton size="large" pill>
|
||||
Large
|
||||
</WaButton>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Text Buttons
|
||||
|
||||
Use the `text` variant to create text buttons that share the same size as regular buttons but don't have backgrounds or borders.
|
||||
@@ -148,26 +64,6 @@ Use the `text` variant to create text buttons that share the same size as regula
|
||||
<wa-button variant="text" size="large">Text</wa-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaButton variant="text" size="small">
|
||||
Text
|
||||
</WaButton>
|
||||
<WaButton variant="text" size="medium">
|
||||
Text
|
||||
</WaButton>
|
||||
<WaButton variant="text" size="large">
|
||||
Text
|
||||
</WaButton>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Link Buttons
|
||||
|
||||
It's often helpful to have a button that works like a link. This is possible by setting the `href` attribute, which will make the component render an `<a>` under the hood. This gives you all the default link behavior the browser provides (e.g. [[CMD/CTRL/SHIFT]] + [[CLICK]]) and exposes the `target` and `download` attributes.
|
||||
@@ -179,27 +75,6 @@ It's often helpful to have a button that works like a link. This is possible by
|
||||
<wa-button href="https://example.com/" disabled>Disabled</wa-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaButton href="https://example.com/">Link</WaButton>
|
||||
<WaButton href="https://example.com/" target="_blank">
|
||||
New Window
|
||||
</WaButton>
|
||||
<WaButton href="/assets/images/logo.svg" download="shoelace.svg">
|
||||
Download
|
||||
</WaButton>
|
||||
<WaButton href="https://example.com/" disabled>
|
||||
Disabled
|
||||
</WaButton>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::info
|
||||
When a `target` is set, the link will receive `rel="noreferrer noopener"` for [security reasons](https://mathiasbynens.github.io/rel-noopener/).
|
||||
:::
|
||||
@@ -214,26 +89,6 @@ As expected, buttons can be given a custom width by setting the `width` attribut
|
||||
<wa-button size="large" style="width: 100%;">Large</wa-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaButton size="small" style={{ width: '100%', marginBottom: '1rem' }}>
|
||||
Small
|
||||
</WaButton>
|
||||
<WaButton size="medium" style={{ width: '100%', marginBottom: '1rem' }}>
|
||||
Medium
|
||||
</WaButton>
|
||||
<WaButton size="large" style={{ width: '100%' }}>
|
||||
Large
|
||||
</WaButton>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Prefix and Suffix Icons
|
||||
|
||||
Use the `prefix` and `suffix` slots to add icons.
|
||||
@@ -292,71 +147,6 @@ Use the `prefix` and `suffix` slots to add icons.
|
||||
</wa-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaButton size="small">
|
||||
<WaIcon slot="prefix" name="gear" variant="solid"></WaIcon>
|
||||
Settings
|
||||
</WaButton>
|
||||
|
||||
<WaButton size="small">
|
||||
<WaIcon slot="suffix" name="undo" variant="solid"></WaIcon>
|
||||
Refresh
|
||||
</WaButton>
|
||||
|
||||
<WaButton size="small">
|
||||
<WaIcon slot="prefix" name="link" variant="solid"></WaIcon>
|
||||
<WaIcon slot="suffix" name="arrow-up-right-from-square" variant="solid"></WaIcon>
|
||||
Open
|
||||
</WaButton>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<WaButton>
|
||||
<WaIcon slot="prefix" name="gear" variant="solid"></WaIcon>
|
||||
Settings
|
||||
</WaButton>
|
||||
|
||||
<WaButton>
|
||||
<WaIcon slot="suffix" name="undo" variant="solid"></WaIcon>
|
||||
Refresh
|
||||
</WaButton>
|
||||
|
||||
<WaButton>
|
||||
<WaIcon slot="prefix" name="link" variant="solid"></WaIcon>
|
||||
<WaIcon slot="suffix" name="arrow-up-right-from-square" variant="solid"></WaIcon>
|
||||
Open
|
||||
</WaButton>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<WaButton size="large">
|
||||
<WaIcon slot="prefix" name="gear" variant="solid"></WaIcon>
|
||||
Settings
|
||||
</WaButton>
|
||||
|
||||
<WaButton size="large">
|
||||
<WaIcon slot="suffix" name="undo" variant="solid"></WaIcon>
|
||||
Refresh
|
||||
</WaButton>
|
||||
|
||||
<WaButton size="large">
|
||||
<WaIcon slot="prefix" name="link" variant="solid"></WaIcon>
|
||||
<WaIcon slot="suffix" name="arrow-up-right-from-square" variant="solid"></WaIcon>
|
||||
Open
|
||||
</WaButton>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Caret
|
||||
|
||||
Use the `caret` attribute to add a dropdown indicator when a button will trigger a dropdown, menu, or popover.
|
||||
@@ -367,26 +157,6 @@ Use the `caret` attribute to add a dropdown indicator when a button will trigger
|
||||
<wa-button size="large" caret>Large</wa-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaButton size="small" caret>
|
||||
Small
|
||||
</WaButton>
|
||||
<WaButton size="medium" caret>
|
||||
Medium
|
||||
</WaButton>
|
||||
<WaButton size="large" caret>
|
||||
Large
|
||||
</WaButton>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Loading
|
||||
|
||||
Use the `loading` attribute to make a button busy. The width will remain the same as before, preventing adjacent elements from moving around.
|
||||
@@ -399,32 +169,6 @@ Use the `loading` attribute to make a button busy. The width will remain the sam
|
||||
<wa-button variant="danger" loading>Danger</wa-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaButton variant="brand" loading>
|
||||
Brand
|
||||
</WaButton>
|
||||
<WaButton variant="success" loading>
|
||||
Success
|
||||
</WaButton>
|
||||
<WaButton variant="neutral" loading>
|
||||
Neutral
|
||||
</WaButton>
|
||||
<WaButton variant="warning" loading>
|
||||
Warning
|
||||
</WaButton>
|
||||
<WaButton variant="danger" loading>
|
||||
Danger
|
||||
</WaButton>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` attribute to disable a button.
|
||||
@@ -437,36 +181,6 @@ Use the `disabled` attribute to disable a button.
|
||||
<wa-button variant="danger" disabled>Danger</wa-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaButton variant="brand" disabled>
|
||||
Brand
|
||||
</WaButton>
|
||||
|
||||
<WaButton variant="success" disabled>
|
||||
Success
|
||||
</WaButton>
|
||||
|
||||
<WaButton variant="neutral" disabled>
|
||||
Neutral
|
||||
</WaButton>
|
||||
|
||||
<WaButton variant="warning" disabled>
|
||||
Warning
|
||||
</WaButton>
|
||||
|
||||
<WaButton variant="danger" disabled>
|
||||
Danger
|
||||
</WaButton>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Styling Buttons
|
||||
|
||||
This example demonstrates how to style buttons using a custom class. This is the recommended approach if you need to add additional variations. To customize an existing variation, modify the selector to target the button's `variant` attribute instead of a class (e.g. `wa-button[variant="brand"]`).
|
||||
|
||||
@@ -11,20 +11,6 @@ layout: component.njk
|
||||
</wa-callout>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCallout from '@shoelace-style/shoelace/dist/react/callout';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
|
||||
const App = () => (
|
||||
<WaCallout>
|
||||
<WaIcon slot="icon" name="circle-info" variant="regular" />
|
||||
This is a standard callout. You can customize its content and even the icon.
|
||||
</WaCallout>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Variants
|
||||
@@ -71,60 +57,6 @@ Set the `variant` attribute to change the callout's variant.
|
||||
</wa-callout>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCallout from '@shoelace-style/shoelace/dist/react/callout';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaCallout variant="brand">
|
||||
<WaIcon slot="icon" name="circle-info" variant="regular" />
|
||||
<strong>This is super informative</strong>
|
||||
<br />
|
||||
You can tell by how pretty the callout is.
|
||||
</WaCallout>
|
||||
|
||||
<br />
|
||||
|
||||
<WaCallout variant="success">
|
||||
<WaIcon slot="icon" name="circle-check" variant="regular" />
|
||||
<strong>Your changes have been saved</strong>
|
||||
<br />
|
||||
You can safely exit the app now.
|
||||
</WaCallout>
|
||||
|
||||
<br />
|
||||
|
||||
<WaCallout variant="neutral">
|
||||
<WaIcon slot="icon" name="gear" variant="regular" />
|
||||
<strong>Your settings have been updated</strong>
|
||||
<br />
|
||||
Settings will take effect on next login.
|
||||
</WaCallout>
|
||||
|
||||
<br />
|
||||
|
||||
<WaCallout variant="warning">
|
||||
<WaIcon slot="icon" name="triangle-exclamation" variant="regular" />
|
||||
<strong>Your session has ended</strong>
|
||||
<br />
|
||||
Please login again to continue.
|
||||
</WaCallout>
|
||||
|
||||
<br />
|
||||
|
||||
<WaCallout variant="danger">
|
||||
<WaIcon slot="icon" name="circle-exclamation" variant="regular" />
|
||||
<strong>Your account has been deleted</strong>
|
||||
<br />
|
||||
We're very sorry to see you go!
|
||||
</WaCallout>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Without Icons
|
||||
|
||||
Icons are optional. Simply omit the `icon` slot if you don't want them.
|
||||
@@ -132,16 +64,3 @@ Icons are optional. Simply omit the `icon` slot if you don't want them.
|
||||
```html {.example}
|
||||
<wa-callout variant="brand"> Nothing fancy here, just a simple callout. </wa-callout>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCallout from '@shoelace-style/shoelace/dist/react/callout';
|
||||
|
||||
const App = () => (
|
||||
<WaCallout variant="brand">
|
||||
Nothing fancy here, just a simple callout.
|
||||
</WaCallout>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
|
||||
@@ -39,55 +39,6 @@ layout: component.njk
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaCard from '@shoelace-style/shoelace/dist/react/card';
|
||||
import WaRating from '@shoelace-style/shoelace/dist/react/rating';
|
||||
|
||||
const css = `
|
||||
.card-overview {
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.card-overview small {
|
||||
color: var(--wa-color-text-quiet);
|
||||
}
|
||||
|
||||
.card-overview [slot="footer"] {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaCard with-image with-footer className="card-overview">
|
||||
<img
|
||||
slot="image"
|
||||
src="https://images.unsplash.com/photo-1559209172-0ff8f6d49ff7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80"
|
||||
alt="A kitten sits patiently between a terracotta pot and decorative grasses."
|
||||
/>
|
||||
<strong>Mittens</strong>
|
||||
<br />
|
||||
This kitten is as cute as he is playful. Bring him home today!
|
||||
<br />
|
||||
<small>6 weeks old</small>
|
||||
<div slot="footer">
|
||||
<WaButton variant="brand" pill>
|
||||
More Info
|
||||
</WaButton>
|
||||
<WaRating></WaRating>
|
||||
</div>
|
||||
</WaCard>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Card
|
||||
@@ -106,28 +57,6 @@ Basic cards aren't very exciting, but they can display any content you want them
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCard from '@shoelace-style/shoelace/dist/react/card';
|
||||
|
||||
const css = `
|
||||
.card-basic {
|
||||
max-width: 300px;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaCard className="card-basic">
|
||||
This is just a basic card. No image, no header, and no footer. Just your content.
|
||||
</WaCard>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Card with Header
|
||||
|
||||
Headers can be used to display titles and more. Use the `with-header` attribute to add a header to the card.
|
||||
@@ -163,47 +92,6 @@ Headers can be used to display titles and more. Use the `with-header` attribute
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCard from '@shoelace-style/shoelace/dist/react/card';
|
||||
import WaIconButton from '@shoelace-style/shoelace/dist/react/icon-button';
|
||||
|
||||
const css = `
|
||||
.card-header {
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.card-header [slot="header"] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.card-header h3 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.card-header wa-icon-button {
|
||||
font-size: var(--wa-font-size-m);
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaCard with-header className="card-header">
|
||||
<div slot="header">
|
||||
Header Title
|
||||
<WaIconButton name="gear" variant="solid"></WaIconButton>
|
||||
</div>
|
||||
This card has a header. You can put all sorts of things in it!
|
||||
</WaCard>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Card with Footer
|
||||
|
||||
Footers can be used to display actions, summaries, or other relevant content. Use the `with-footer` attribute to add a footer to the card.
|
||||
@@ -231,42 +119,6 @@ Footers can be used to display actions, summaries, or other relevant content. Us
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaCard from '@shoelace-style/shoelace/dist/react/card';
|
||||
import WaRating from '@shoelace-style/shoelace/dist/react/rating';
|
||||
|
||||
const css = `
|
||||
.card-footer {
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.card-footer [slot="footer"] {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaCard with-footer className="card-footer">
|
||||
This card has a footer. You can put all sorts of things in it!
|
||||
<div slot="footer">
|
||||
<WaRating></WaRating>
|
||||
<WaButton slot="footer" variant="brand">
|
||||
Preview
|
||||
</WaButton>
|
||||
</div>
|
||||
</WaCard>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Images
|
||||
|
||||
Card images are displayed atop the card and will stretch to fit. Use the `with-image` attribute to add an image to the card.
|
||||
@@ -287,30 +139,3 @@ Card images are displayed atop the card and will stretch to fit. Use the `with-i
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCard from '@shoelace-style/shoelace/dist/react/card';
|
||||
|
||||
const css = `
|
||||
.card-image {
|
||||
max-width: 300px;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaCard with-image className="card-image">
|
||||
<img
|
||||
slot="image"
|
||||
src="https://images.unsplash.com/photo-1547191783-94d5f8f6d8b1?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=400&q=80"
|
||||
alt="A kitten walks towards camera on top of pallet."
|
||||
/>
|
||||
This is a kitten, but not just any kitten. This kitten likes walking along pallets.
|
||||
</WaCard>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -39,48 +39,6 @@ layout: component.njk
|
||||
</wa-carousel>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCarousel from '@shoelace-style/shoelace/dist/react/carousel';
|
||||
import WaCarouselItem from '@shoelace-style/shoelace/dist/react/carousel-item';
|
||||
|
||||
const App = () => (
|
||||
<WaCarousel pagination>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun shines on the mountains and trees - Photo by Adam Kool on Unsplash"
|
||||
src="/assets/examples/carousel/mountains.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A waterfall in the middle of a forest - Photo by Thomas Kelly on Unsplash"
|
||||
src="/assets/examples/carousel/waterfall.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun is setting over a lavender field - Photo by Leonard Cotte on Unsplash"
|
||||
src="/assets/examples/carousel/sunset.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A field of grass with the sun setting in the background - Photo by Sapan Patel on Unsplash"
|
||||
src="/assets/examples/carousel/field.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A scenic view of a mountain with clouds rolling in - Photo by V2osk on Unsplash"
|
||||
src="/assets/examples/carousel/valley.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
</WaCarousel>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::info
|
||||
Additional demonstrations can be found in the [carousel examples](/components/carousel).
|
||||
:::
|
||||
|
||||
@@ -39,50 +39,6 @@ layout: component.njk
|
||||
</wa-carousel>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCarousel from '@shoelace-style/shoelace/dist/react/carousel';
|
||||
import WaCarouselItem from '@shoelace-style/shoelace/dist/react/carousel-item';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaCarousel pagination mouse-dragging>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)"
|
||||
src="/assets/examples/carousel/mountains.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)"
|
||||
src="/assets/examples/carousel/waterfall.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)"
|
||||
src="/assets/examples/carousel/sunset.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)"
|
||||
src="/assets/examples/carousel/field.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)"
|
||||
src="/assets/examples/carousel/valley.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
</WaCarousel>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Pagination
|
||||
@@ -124,48 +80,6 @@ Use the `pagination` attribute to show the total number of slides and the curren
|
||||
</wa-carousel>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCarousel from '@shoelace-style/shoelace/dist/react/carousel';
|
||||
import WaCarouselItem from '@shoelace-style/shoelace/dist/react/carousel-item';
|
||||
|
||||
const App = () => (
|
||||
<WaCarousel pagination>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)"
|
||||
src="/assets/examples/carousel/mountains.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)"
|
||||
src="/assets/examples/carousel/waterfall.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)"
|
||||
src="/assets/examples/carousel/sunset.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)"
|
||||
src="/assets/examples/carousel/field.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)"
|
||||
src="/assets/examples/carousel/valley.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
</WaCarousel>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Navigation
|
||||
|
||||
Use the `navigation` attribute to show previous and next buttons.
|
||||
@@ -205,48 +119,6 @@ Use the `navigation` attribute to show previous and next buttons.
|
||||
</wa-carousel>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCarousel from '@shoelace-style/shoelace/dist/react/carousel';
|
||||
import WaCarouselItem from '@shoelace-style/shoelace/dist/react/carousel-item';
|
||||
|
||||
const App = () => (
|
||||
<WaCarousel navigation>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)"
|
||||
src="/assets/examples/carousel/mountains.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)"
|
||||
src="/assets/examples/carousel/waterfall.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)"
|
||||
src="/assets/examples/carousel/sunset.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)"
|
||||
src="/assets/examples/carousel/field.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)"
|
||||
src="/assets/examples/carousel/valley.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
</WaCarousel>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Looping
|
||||
|
||||
By default, the carousel will not advanced beyond the first and last slides. You can change this behavior and force the carousel to "wrap" with the `loop` attribute.
|
||||
@@ -286,48 +158,6 @@ By default, the carousel will not advanced beyond the first and last slides. You
|
||||
</wa-carousel>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCarousel from '@shoelace-style/shoelace/dist/react/carousel';
|
||||
import WaCarouselItem from '@shoelace-style/shoelace/dist/react/carousel-item';
|
||||
|
||||
const App = () => (
|
||||
<WaCarousel loop navigation pagination>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)"
|
||||
src="/assets/examples/carousel/mountains.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)"
|
||||
src="/assets/examples/carousel/waterfall.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)"
|
||||
src="/assets/examples/carousel/sunset.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)"
|
||||
src="/assets/examples/carousel/field.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)"
|
||||
src="/assets/examples/carousel/valley.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
</WaCarousel>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Autoplay
|
||||
|
||||
The carousel will automatically advance when the `autoplay` attribute is used. To change how long a slide is shown before advancing, set `autoplay-interval` to the desired number of milliseconds. For best results, use the `loop` attribute when autoplay is enabled. Note that autoplay will pause while the user interacts with the carousel.
|
||||
@@ -367,48 +197,6 @@ The carousel will automatically advance when the `autoplay` attribute is used. T
|
||||
</wa-carousel>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCarousel from '@shoelace-style/shoelace/dist/react/carousel';
|
||||
import WaCarouselItem from '@shoelace-style/shoelace/dist/react/carousel-item';
|
||||
|
||||
const App = () => (
|
||||
<WaCarousel autoplay loop pagination>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)"
|
||||
src="/assets/examples/carousel/mountains.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)"
|
||||
src="/assets/examples/carousel/waterfall.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)"
|
||||
src="/assets/examples/carousel/sunset.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)"
|
||||
src="/assets/examples/carousel/field.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)"
|
||||
src="/assets/examples/carousel/valley.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
</WaCarousel>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Mouse Dragging
|
||||
|
||||
The carousel uses [scroll snap](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Scroll_Snap) to position slides at various snap positions. This allows users to scroll through the slides very naturally, especially on touch devices. Unfortunately, desktop users won't be able to click and drag with a mouse, which can feel unnatural. Adding the `mouse-dragging` attribute can help with this.
|
||||
@@ -466,63 +254,6 @@ This example is best demonstrated using a mouse. Try clicking and dragging the s
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaCarousel from '@shoelace-style/shoelace/dist/react/carousel';
|
||||
import WaCarouselItem from '@shoelace-style/shoelace/dist/react/carousel-item';
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
import WaSwitch from '@shoelace-style/shoelace/dist/react/switch';
|
||||
|
||||
const App = () => {
|
||||
const [isEnabled, setIsEnabled] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaCarousel navigation mouseDragging={isEnabled}>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)"
|
||||
src="/assets/examples/carousel/mountains.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)"
|
||||
src="/assets/examples/carousel/waterfall.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)"
|
||||
src="/assets/examples/carousel/sunset.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)"
|
||||
src="/assets/examples/carousel/field.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)"
|
||||
src="/assets/examples/carousel/valley.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
</WaCarousel>
|
||||
|
||||
<WaDivider></WaDivider>
|
||||
|
||||
<WaSwitch checked={isEnabled} onWaInput={() => setIsEnabled(!isEnabled)}>
|
||||
Enable mouse dragging
|
||||
</WaSwitch>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Multiple Slides Per View
|
||||
|
||||
The `slides-per-page` attribute makes it possible to display multiple slides at a time. You can also use the `slides-per-move` attribute to advance more than once slide at a time, if desired.
|
||||
@@ -538,24 +269,6 @@ The `slides-per-page` attribute makes it possible to display multiple slides at
|
||||
</wa-carousel>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCarousel from '@shoelace-style/shoelace/dist/react/carousel';
|
||||
import WaCarouselItem from '@shoelace-style/shoelace/dist/react/carousel-item';
|
||||
|
||||
const App = () => (
|
||||
<WaCarousel navigation pagination slidesPerPage={2} slidesPerMove={2}>
|
||||
<WaCarouselItem style={{ background: 'red' }}>Slide 1</WaCarouselItem>
|
||||
<WaCarouselItem style={{ background: 'orange' }}>Slide 2</WaCarouselItem>
|
||||
<WaCarouselItem style={{ background: 'yellow' }}>Slide 3</WaCarouselItem>
|
||||
<WaCarouselItem style={{ background: 'green' }}>Slide 4</WaCarouselItem>
|
||||
<WaCarouselItem style={{ background: 'blue' }}>Slide 5</WaCarouselItem>
|
||||
<WaCarouselItem style={{ background: 'purple' }}>Slide 6</WaCarouselItem>
|
||||
</WaCarousel>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Adding and Removing Slides
|
||||
|
||||
The content of the carousel can be changed by adding or removing carousel items. The carousel will update itself automatically.
|
||||
@@ -628,67 +341,6 @@ The content of the carousel can be changed by adding or removing carousel items.
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaCarousel from '@shoelace-style/shoelace/dist/react/carousel';
|
||||
import WaCarouselItem from '@shoelace-style/shoelace/dist/react/carousel-item';
|
||||
|
||||
const css = `
|
||||
.dynamic-carousel {
|
||||
--aspect-ratio: 3 / 2;
|
||||
}
|
||||
|
||||
.dynamic-carousel ~ .carousel-options {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: var(--wa-space-l);
|
||||
}
|
||||
|
||||
.dynamic-carousel wa-carousel-item {
|
||||
flex: 0 0 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
font-size: var(--wa-font-size-2xl);
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => {
|
||||
const [slides, setSlides] = useState(['#204ed8', '#be133d', '#6e28d9']);
|
||||
const colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple'];
|
||||
|
||||
const addSlide = () => {
|
||||
setSlides([...slides, getRandomColor()]);
|
||||
};
|
||||
|
||||
const removeSlide = () => {
|
||||
setSlides(slides.slice(0, -1));
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaCarousel className="dynamic-carousel" pagination navigation>
|
||||
{slides.map((color, i) => (
|
||||
<WaCarouselItem style={{ background: colors[i % colors.length }}>
|
||||
Slide {i}
|
||||
</WaCarouselItem>
|
||||
))}
|
||||
</WaCarousel>
|
||||
|
||||
<div className="carousel-options">
|
||||
<WaButton onClick={addSlide}>Add slide</WaButton>
|
||||
<WaButton onClick={removeSlide}>Remove slide</WaButton>
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Vertical Scrolling
|
||||
|
||||
Setting the `orientation` attribute to `vertical` will render the carousel in a vertical layout. If the content of your slides vary in height, you will need to set amn explicit `height` or `max-height` on the carousel using CSS.
|
||||
@@ -746,70 +398,6 @@ Setting the `orientation` attribute to `vertical` will render the carousel in a
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCarousel from '@shoelace-style/shoelace/dist/react/carousel';
|
||||
import WaCarouselItem from '@shoelace-style/shoelace/dist/react/carousel-item';
|
||||
|
||||
const css = `
|
||||
.vertical {
|
||||
max-height: 400px;
|
||||
}
|
||||
|
||||
.vertical::part(base) {
|
||||
grid-template-areas: 'slides slides pagination';
|
||||
}
|
||||
|
||||
.vertical::part(pagination) {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.vertical::part(navigation) {
|
||||
transform: rotate(90deg);
|
||||
display: flex;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaCarousel className="vertical" loop pagination orientation="vertical">
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)"
|
||||
src="/assets/examples/carousel/mountains.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)"
|
||||
src="/assets/examples/carousel/waterfall.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)"
|
||||
src="/assets/examples/carousel/sunset.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)"
|
||||
src="/assets/examples/carousel/field.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)"
|
||||
src="/assets/examples/carousel/valley.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
</WaCarousel>
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Aspect Ratio
|
||||
|
||||
Use the `--aspect-ratio` custom property to customize the size of the carousel's viewport from the default value of 16/9.
|
||||
@@ -868,73 +456,6 @@ Use the `--aspect-ratio` custom property to customize the size of the carousel's
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaCarousel from '@shoelace-style/shoelace/dist/react/carousel';
|
||||
import WaCarouselItem from '@shoelace-style/shoelace/dist/react/carousel-item';
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
import WaSelect from '@shoelace-style/shoelace/dist/react/select';
|
||||
import WaOption from '@shoelace-style/shoelace/dist/react/option';
|
||||
|
||||
const App = () => {
|
||||
const [aspectRatio, setAspectRatio] = useState('3/2');
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaCarousel className="aspect-ratio" navigation pagination style={{ '--aspect-ratio': aspectRatio }}>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)"
|
||||
src="/assets/examples/carousel/mountains.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)"
|
||||
src="/assets/examples/carousel/waterfall.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)"
|
||||
src="/assets/examples/carousel/sunset.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)"
|
||||
src="/assets/examples/carousel/field.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)"
|
||||
src="/assets/examples/carousel/valley.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
</WaCarousel>
|
||||
|
||||
<WaDivider />
|
||||
|
||||
<WaSelect
|
||||
label="Aspect ratio"
|
||||
name="aspect"
|
||||
value={aspectRatio}
|
||||
onWaChange={event => setAspectRatio(event.target.value)}
|
||||
>
|
||||
<WaOption value="1 / 1">1 / 1</WaOption>
|
||||
<WaOption value="3 / 2">3 / 2</WaOption>
|
||||
<WaOption value="16 / 9">16 / 9</WaOption>
|
||||
</WaSelect>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Scroll Hint
|
||||
|
||||
Use the `--scroll-hint` custom property to add inline padding in horizontal carousels and block padding in vertical carousels. This will make the closest slides slightly visible, hinting that there are more items in the carousel.
|
||||
@@ -974,53 +495,6 @@ Use the `--scroll-hint` custom property to add inline padding in horizontal caro
|
||||
</wa-carousel>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaCarousel from '@shoelace-style/shoelace/dist/react/carousel';
|
||||
import WaCarouselItem from '@shoelace-style/shoelace/dist/react/carousel-item';
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
import WaRange from '@shoelace-style/shoelace/dist/react/range';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaCarousel className="scroll-hint" pagination style={{ '--scroll-hint': '10%' }}>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun shines on the mountains and trees (by Adam Kool on Unsplash)"
|
||||
src="/assets/examples/carousel/mountains.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A waterfall in the middle of a forest (by Thomas Kelly on Unsplash)"
|
||||
src="/assets/examples/carousel/waterfall.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="The sun is setting over a lavender field (by Leonard Cotte on Unsplash)"
|
||||
src="/assets/examples/carousel/sunset.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A field of grass with the sun setting in the background (by Sapan Patel on Unsplash)"
|
||||
src="/assets/examples/carousel/field.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt="A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash)"
|
||||
src="/assets/examples/carousel/valley.jpg"
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
</WaCarousel>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Gallery Example
|
||||
|
||||
The carousel has a robust API that makes it possible to extend and customize. This example syncs the active slide with a set of thumbnails, effectively creating a gallery-style carousel.
|
||||
@@ -1139,128 +613,3 @@ The carousel has a robust API that makes it possible to extend and customize. Th
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useRef } from 'react';
|
||||
import WaCarousel from '@shoelace-style/shoelace/dist/react/carousel';
|
||||
import WaCarouselItem from '@shoelace-style/shoelace/dist/react/carousel-item';
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
import WaRange from '@shoelace-style/shoelace/dist/react/range';
|
||||
|
||||
const css = `
|
||||
.carousel-thumbnails {
|
||||
--slide-aspect-ratio: 3 / 2;
|
||||
}
|
||||
|
||||
.thumbnails {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.thumbnails__scroller {
|
||||
display: flex;
|
||||
gap: var(--wa-space-s);
|
||||
overflow-x: auto;
|
||||
scrollbar-width: none;
|
||||
scroll-behavior: smooth;
|
||||
scroll-padding: var(--wa-space-s);
|
||||
}
|
||||
|
||||
.thumbnails__scroller::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.thumbnails__image {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
object-fit: cover;
|
||||
|
||||
opacity: 0.3;
|
||||
will-change: opacity;
|
||||
transition: 250ms opacity;
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.thumbnails__image.active {
|
||||
opacity: 1;
|
||||
}
|
||||
`;
|
||||
|
||||
const images = [
|
||||
{
|
||||
src: '/assets/examples/carousel/mountains.jpg',
|
||||
alt: 'The sun shines on the mountains and trees (by Adam Kool on Unsplash'
|
||||
},
|
||||
{
|
||||
src: '/assets/examples/carousel/waterfall.jpg',
|
||||
alt: 'A waterfall in the middle of a forest (by Thomas Kelly on Unsplash'
|
||||
},
|
||||
{
|
||||
src: '/assets/examples/carousel/sunset.jpg',
|
||||
alt: 'The sun is setting over a lavender field (by Leonard Cotte on Unsplash'
|
||||
},
|
||||
{
|
||||
src: '/assets/examples/carousel/field.jpg',
|
||||
alt: 'A field of grass with the sun setting in the background (by Sapan Patel on Unsplash'
|
||||
},
|
||||
{
|
||||
src: '/assets/examples/carousel/valley.jpg',
|
||||
alt: 'A scenic view of a mountain with clouds rolling in (by V2osk on Unsplash'
|
||||
}
|
||||
];
|
||||
|
||||
const App = () => {
|
||||
const carouselRef = useRef();
|
||||
const thumbnailsRef = useRef();
|
||||
const [currentSlide, setCurrentSlide] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const thumbnails = Array.from(thumbnailsRef.current.querySelectorAll('.thumbnails__image'));
|
||||
|
||||
thumbnails[currentSlide]..scrollIntoView({
|
||||
block: 'nearest'
|
||||
});
|
||||
}, [currentSlide]);
|
||||
|
||||
const handleThumbnailClick = (index) => {
|
||||
carouselRef.current.goToSlide(index);
|
||||
}
|
||||
|
||||
const handleSlideChange = (event) => {
|
||||
const slideIndex = e.detail.index;
|
||||
setCurrentSlide(slideIndex);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaCarousel className="carousel-thumbnails" navigation loop onWaSlideChange={handleSlideChange}>
|
||||
{images.map({ src, alt }) => (
|
||||
<WaCarouselItem>
|
||||
<img
|
||||
alt={alt}
|
||||
src={src}
|
||||
/>
|
||||
</WaCarouselItem>
|
||||
)}
|
||||
</WaCarousel>
|
||||
|
||||
<div class="thumbnails">
|
||||
<div class="thumbnails__scroller">
|
||||
{images.map({ src, alt }, i) => (
|
||||
<img
|
||||
alt={`Thumbnail by ${i + 1}`}
|
||||
className={`thumbnails__image ${i === currentSlide ? 'active' : ''}`}
|
||||
onCLick={() => handleThumbnailClick(i)}
|
||||
src={src}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -8,14 +8,6 @@ layout: component.njk
|
||||
<wa-checkbox>Checkbox</wa-checkbox>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCheckbox from '@shoelace-style/shoelace/dist/react/checkbox';
|
||||
|
||||
const App = () => <WaCheckbox>Checkbox</WaCheckbox>;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::info
|
||||
This component works with standard `<form>` elements. Please refer to the section on [form controls](/getting-started/form-controls) to learn more about form submission and client-side validation.
|
||||
:::
|
||||
@@ -30,14 +22,6 @@ Use the `checked` attribute to activate the checkbox.
|
||||
<wa-checkbox checked>Checked</wa-checkbox>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCheckbox from '@shoelace-style/shoelace/dist/react/checkbox';
|
||||
|
||||
const App = () => <WaCheckbox checked>Checked</WaCheckbox>;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Indeterminate
|
||||
|
||||
Use the `indeterminate` attribute to make the checkbox indeterminate.
|
||||
@@ -46,14 +30,6 @@ Use the `indeterminate` attribute to make the checkbox indeterminate.
|
||||
<wa-checkbox indeterminate>Indeterminate</wa-checkbox>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCheckbox from '@shoelace-style/shoelace/dist/react/checkbox';
|
||||
|
||||
const App = () => <WaCheckbox indeterminate>Indeterminate</WaCheckbox>;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` attribute to disable the checkbox.
|
||||
@@ -62,14 +38,6 @@ Use the `disabled` attribute to disable the checkbox.
|
||||
<wa-checkbox disabled>Disabled</wa-checkbox>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCheckbox from '@shoelace-style/shoelace/dist/react/checkbox';
|
||||
|
||||
const App = () => <WaCheckbox disabled>Disabled</WaCheckbox>;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Sizes
|
||||
|
||||
Use the `size` attribute to change a checkbox's size.
|
||||
@@ -82,22 +50,6 @@ Use the `size` attribute to change a checkbox's size.
|
||||
<wa-checkbox size="large">Large</wa-checkbox>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCheckbox from '@shoelace-style/shoelace/dist/react/checkbox';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaCheckbox size="small">Small</WaCheckbox>
|
||||
<br />
|
||||
<WaCheckbox size="medium">Medium</WaCheckbox>
|
||||
<br />
|
||||
<WaCheckbox size="large">Large</WaCheckbox>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Help Text
|
||||
|
||||
Add descriptive help text to a switch with the `help-text` attribute. For help texts that contain HTML, use the `help-text` slot instead.
|
||||
@@ -106,18 +58,10 @@ Add descriptive help text to a switch with the `help-text` attribute. For help t
|
||||
<wa-checkbox help-text="What should the user know about the checkbox?">Label</wa-checkbox>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaCheckbox from '@shoelace-style/shoelace/dist/react/checkbox';
|
||||
const App = () => <WaCheckbox help-text="What should the user know about the switch?">Label</WaCheckbox>;
|
||||
|
||||
### Custom Validity
|
||||
|
||||
Use the `setCustomValidity()` method to set a custom validation message. This will prevent the form from submitting and make the browser display the error message you provide. To clear the error, call this function with an empty string.
|
||||
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
```html {.example}
|
||||
<form class="custom-validity">
|
||||
<wa-checkbox>Check me</wa-checkbox>
|
||||
@@ -148,42 +92,4 @@ Use the `setCustomValidity()` method to set a custom validation message. This wi
|
||||
});
|
||||
});
|
||||
</script>
|
||||
````
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useEffect, useRef } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaCheckbox from '@shoelace-style/shoelace/dist/react/checkbox';
|
||||
|
||||
const App = () => {
|
||||
const checkbox = useRef(null);
|
||||
const errorMessage = `Don't forget to check me!`;
|
||||
|
||||
function handleChange() {
|
||||
checkbox.current.setCustomValidity(checkbox.current.checked ? '' : errorMessage);
|
||||
}
|
||||
|
||||
function handleSubmit(event) {
|
||||
event.preventDefault();
|
||||
alert('All fields are valid!');
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
checkbox.current.setCustomValidity(errorMessage);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<form class="custom-validity" onSubmit={handleSubmit}>
|
||||
<WaCheckbox ref={checkbox} onWaChange={handleChange}>
|
||||
Check me
|
||||
</WaCheckbox>
|
||||
<br />
|
||||
<WaButton type="submit" variant="brand" style={{ marginTop: '1rem' }}>
|
||||
Submit
|
||||
</WaButton>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -11,14 +11,6 @@ layout: component.njk
|
||||
</form>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaColorPicker from '@shoelace-style/shoelace/dist/react/color-picker';
|
||||
|
||||
const App = () => <WaColorPicker label="Select a color" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::info
|
||||
This component works with standard `<form>` elements. Please refer to the section on [form controls](/getting-started/form-controls) to learn more about form submission and client-side validation.
|
||||
:::
|
||||
@@ -33,14 +25,6 @@ Use the `value` attribute to set an initial value for the color picker.
|
||||
<wa-color-picker value="#4a90e2" label="Select a color"></wa-color-picker>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaColorPicker from '@shoelace-style/shoelace/dist/react/color-picker';
|
||||
|
||||
const App = () => <WaColorPicker value="#4a90e2" label="Select a color" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Opacity
|
||||
|
||||
Use the `opacity` attribute to enable the opacity slider. When this is enabled, the value will be displayed as HEXA, RGBA, HSLA, or HSVA based on `format`.
|
||||
@@ -49,14 +33,6 @@ Use the `opacity` attribute to enable the opacity slider. When this is enabled,
|
||||
<wa-color-picker value="#f5a623ff" opacity label="Select a color"></wa-color-picker>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaColorPicker from '@shoelace-style/shoelace/dist/react/color-picker';
|
||||
|
||||
const App = () => <WaColorPicker opacity label="Select a color" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Formats
|
||||
|
||||
Set the color picker's format with the `format` attribute. Valid options include `hex`, `rgb`, `hsl`, and `hsv`. Note that the color picker's input will accept any parsable format (including CSS color names) regardless of this option.
|
||||
@@ -70,21 +46,6 @@ To prevent users from toggling the format themselves, add the `no-format-toggle`
|
||||
<wa-color-picker format="hsv" value="hsv(55, 89%, 97%)" label="Select a color"></wa-color-picker>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaColorPicker from '@shoelace-style/shoelace/dist/react/color-picker';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaColorPicker format="hex" value="#4a90e2" />
|
||||
<WaColorPicker format="rgb" value="rgb(80, 227, 194)" />
|
||||
<WaColorPicker format="hsl" value="hsl(290, 87%, 47%)" />
|
||||
<WaColorPicker format="hsv" value="hsv(55, 89%, 97%)" />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Swatches
|
||||
|
||||
Use the `swatches` attribute to add convenient presets to the color picker. Any format the color picker can parse is acceptable (including CSS color names), but each value must be separated by a semicolon (`;`). Alternatively, you can pass an array of color values to this property using JavaScript.
|
||||
@@ -99,22 +60,6 @@ Use the `swatches` attribute to add convenient presets to the color picker. Any
|
||||
></wa-color-picker>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaColorPicker from '@shoelace-style/shoelace/dist/react/color-picker';
|
||||
|
||||
const App = () => (
|
||||
<WaColorPicker
|
||||
label="Select a color"
|
||||
swatches="
|
||||
#d0021b; #f5a623; #f8e71c; #8b572a; #7ed321; #417505; #bd10e0; #9013fe;
|
||||
#4a90e2; #50e3c2; #b8e986; #000; #444; #888; #ccc; #fff;
|
||||
"
|
||||
/>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Sizes
|
||||
|
||||
Use the `size` attribute to change the color picker's trigger size.
|
||||
@@ -125,20 +70,6 @@ Use the `size` attribute to change the color picker's trigger size.
|
||||
<wa-color-picker size="large" label="Select a color"></wa-color-picker>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaColorPicker from '@shoelace-style/shoelace/dist/react/color-picker';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaColorPicker size="small" label="Select a color" />
|
||||
<WaColorPicker size="medium" label="Select a color" />
|
||||
<WaColorPicker size="large" label="Select a color" />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Inline
|
||||
|
||||
The color picker can be rendered inline instead of in a dropdown using the `inline` attribute.
|
||||
@@ -146,11 +77,3 @@ The color picker can be rendered inline instead of in a dropdown using the `inli
|
||||
```html {.example}
|
||||
<wa-color-picker inline label="Select a color"></wa-color-picker>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaColorPicker from '@shoelace-style/shoelace/dist/react/color-picker';
|
||||
|
||||
const App = () => <WaColorPicker inline label="Select a color" />;
|
||||
```
|
||||
{% endraw %}
|
||||
@@ -8,16 +8,6 @@ layout: component.njk
|
||||
<wa-copy-button value="Web Awesome rocks!"></wa-copy-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { WaCopyButton } from '@shoelace-style/shoelace/dist/react/copy-button';
|
||||
|
||||
const App = () => (
|
||||
<WaCopyButton value="Web Awesome rocks!" />
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Custom Labels
|
||||
@@ -33,21 +23,6 @@ Copy Buttons display feedback in a tooltip. You can customize the labels using t
|
||||
></wa-copy-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { WaCopyButton } from '@shoelace-style/shoelace/dist/react/copy-button';
|
||||
|
||||
const App = () => (
|
||||
<WaCopyButton
|
||||
value="Custom labels are easy"
|
||||
copy-label="Click to copy"
|
||||
success-label="You did it!"
|
||||
error-label="Whoops, your browser doesn't support this!"
|
||||
/>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Custom Icons
|
||||
|
||||
Use the `copy-icon`, `success-icon`, and `error-icon` slots to customize the icons that get displayed for each state. You can use [`<wa-icon>`](/components/icon) or your own images.
|
||||
@@ -60,23 +35,6 @@ Use the `copy-icon`, `success-icon`, and `error-icon` slots to customize the ico
|
||||
</wa-copy-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { WaCopyButton } from '@shoelace-style/shoelace/dist/react/copy-button';
|
||||
import { WaIcon } from '@shoelace-style/shoelace/dist/react/icon';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaCopyButton value="Copied from a custom button">
|
||||
<WaIcon slot="copy-icon" name="clipboard" variant="regular" />
|
||||
<WaIcon slot="success-icon" name="check" variant="solid" />
|
||||
<WaIcon slot="error-icon" name="xmark" variant="solid" />
|
||||
</WaCopyButton>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Copying Values From Other Elements
|
||||
|
||||
Normally, the data that gets copied will come from the component's `value` attribute, but you can copy data from any element within the same document by providing its `id` to the `from` attribute.
|
||||
@@ -103,33 +61,6 @@ To copy data from an attribute, use `from="id[attr]"` where `id` is the id of th
|
||||
<wa-copy-button from="my-link[href]"></wa-copy-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { WaCopyButton } from '@shoelace-style/shoelace/dist/react/copy-button';
|
||||
import { WaInput } from '@shoelace-style/shoelace/dist/react/input';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
{/* Copies the span's textContent */}
|
||||
<span id="my-phone">+1 (234) 456-7890</span>
|
||||
<WaCopyButton from="my-phone" />
|
||||
|
||||
<br /><br />
|
||||
|
||||
{/* Copies the input's "value" property */}
|
||||
<WaInput id="my-input" type="text" />
|
||||
<WaCopyButton from="my-input.value" />
|
||||
|
||||
<br /><br />
|
||||
|
||||
{/* Copies the link's "href" attribute */}
|
||||
<a id="my-link" href="https://shoelace.style/">Web Awesome Website</a>
|
||||
<WaCopyButton from="my-link[href]" />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Handling Errors
|
||||
|
||||
A copy error will occur if the value is an empty string, if the `from` attribute points to an id that doesn't exist, or if the browser rejects the operation for any reason. When this happens, the `wa-error` event will be emitted.
|
||||
@@ -140,16 +71,6 @@ This example demonstrates what happens when a copy error occurs. You can customi
|
||||
<wa-copy-button from="i-do-not-exist"></wa-copy-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { WaCopyButton } from '@shoelace-style/shoelace/dist/react/copy-button';
|
||||
|
||||
const App = () => (
|
||||
<WaCopyButton from="i-do-not-exist" />
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Disabled
|
||||
|
||||
Copy buttons can be disabled by adding the `disabled` attribute.
|
||||
@@ -158,16 +79,6 @@ Copy buttons can be disabled by adding the `disabled` attribute.
|
||||
<wa-copy-button value="You can't copy me" disabled></wa-copy-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { WaCopyButton } from '@shoelace-style/shoelace/dist/react/copy-button';
|
||||
|
||||
const App = () => (
|
||||
<WaCopyButton value="You can't copy me" disabled />
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Changing Feedback Duration
|
||||
|
||||
A success indicator is briefly shown after copying. You can customize the length of time the indicator is shown using the `feedback-duration` attribute.
|
||||
@@ -176,16 +87,6 @@ A success indicator is briefly shown after copying. You can customize the length
|
||||
<wa-copy-button value="Web Awesome rocks!" feedback-duration="250"></wa-copy-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { WaCopyButton } from '@shoelace-style/shoelace/dist/react/copy-button';
|
||||
|
||||
const App = () => (
|
||||
<WaCopyButton value="Web Awesome rocks!" feedback-duration={250} />
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Custom Styles
|
||||
|
||||
You can customize the button to your liking with CSS.
|
||||
@@ -227,47 +128,3 @@ You can customize the button to your liking with CSS.
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { WaCopyButton } from '@shoelace-style/shoelace/dist/react/copy-button';
|
||||
|
||||
const css = `
|
||||
.custom-styles {
|
||||
--success-color: white;
|
||||
--error-color: white;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.custom-styles::part(button) {
|
||||
background-color: #ff1493;
|
||||
border: solid 4px #ff7ac1;
|
||||
border-right-color: #ad005c;
|
||||
border-bottom-color: #ad005c;
|
||||
border-radius: 0;
|
||||
transition: 100ms scale ease-in-out, 100ms translate ease-in-out;
|
||||
}
|
||||
|
||||
.custom-styles::part(button):hover {
|
||||
scale: 1.1;
|
||||
}
|
||||
|
||||
.custom-styles::part(button):active {
|
||||
translate: 0 2px;
|
||||
}
|
||||
|
||||
.custom-styles::part(button):focus-visible {
|
||||
outline: dashed 2px deeppink;
|
||||
outline-offset: 4px;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaCopyButton value="I'm so stylish" className="custom-styles" />
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -13,19 +13,6 @@ layout: component.njk
|
||||
</wa-details>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaDetails from '@shoelace-style/shoelace/dist/react/details';
|
||||
|
||||
const App = () => (
|
||||
<WaDetails summary="Toggle Me">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
|
||||
aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
||||
</WaDetails>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Disabled
|
||||
@@ -39,19 +26,6 @@ Use the `disable` attribute to prevent the details from expanding.
|
||||
</wa-details>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaDetails from '@shoelace-style/shoelace/dist/react/details';
|
||||
|
||||
const App = () => (
|
||||
<WaDetails summary="Disabled" disabled>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
|
||||
aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
||||
</WaDetails>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Customizing the Summary Icon
|
||||
|
||||
Use the `expand-icon` and `collapse-icon` slots to change the expand and collapse icons, respectively. To disable the animation, override the `rotate` property on the `summary-icon` part as shown below.
|
||||
@@ -73,34 +47,6 @@ Use the `expand-icon` and `collapse-icon` slots to change the expand and collaps
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaDetails from '@shoelace-style/shoelace/dist/react/details';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
|
||||
const css = `
|
||||
wa-details.custom-icon::part(summary-icon) {
|
||||
/* Disable the expand/collapse animation */
|
||||
rotate: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaDetails summary="Toggle Me" class="custom-icon">
|
||||
<WaIcon name="square-plus" slot="expand-icon" />
|
||||
<WaIcon name="square-minus" slot="collapse-icon" />
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
|
||||
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat.
|
||||
</WaDetails>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Grouping Details
|
||||
|
||||
Details are designed to function independently, but you can simulate a group or "accordion" where only one is shown at a time by listening for the `wa-show` event.
|
||||
|
||||
@@ -22,31 +22,6 @@ layout: component.njk
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDialog from '@shoelace-style/shoelace/dist/react/dialog';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDialog label="Dialog" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<WaButton slot="footer" variant="brand" data-dialog="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDialog>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Dialog</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Dialog with Header
|
||||
@@ -68,28 +43,6 @@ Headers can be used to display titles and more. Use the `with-header` attribute
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDialog from '@shoelace-style/shoelace/dist/react/dialog';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDialog label="Dialog" with-header open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
</WaDialog>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Dialog</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Dialog with Footer
|
||||
|
||||
Footers can be used to display titles and more. Use the `with-footer` attribute to add a footer to the dialog.
|
||||
@@ -110,31 +63,6 @@ Footers can be used to display titles and more. Use the `with-footer` attribute
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDialog from '@shoelace-style/shoelace/dist/react/dialog';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDialog label="Dialog" with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<WaButton slot="footer" variant="brand" data-dialog="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDialog>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Dialog</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Dismissing Dialogs
|
||||
|
||||
You can add the special `data-dialog="dismiss"` attribute to a button inside the dialog to tell it to close without additional JavaScript. Alternatively, you can set the `open` property to `false` to close the dialog programmatically.
|
||||
@@ -155,31 +83,6 @@ You can add the special `data-dialog="dismiss"` attribute to a button inside the
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDialog from '@shoelace-style/shoelace/dist/react/dialog';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDialog label="Dialog" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<WaButton slot="footer" variant="brand" data-dialog="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDialog>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Dialog</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Custom Width
|
||||
|
||||
Use the `--width` custom property to set the dialog's width.
|
||||
@@ -200,31 +103,6 @@ Use the `--width` custom property to set the dialog's width.
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDialog from '@shoelace-style/shoelace/dist/react/dialog';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDialog label="Dialog" with-header with-footer open={open} style={{ '--width': '50vw' }} onWaAfterHide={() => setOpen(false)}>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<WaButton slot="footer" variant="brand" data-dialog="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDialog>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Dialog</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Scrolling
|
||||
|
||||
By design, a dialog's height will never exceed that of the viewport. As such, dialogs will not scroll with the page ensuring the header and footer are always accessible to the user.
|
||||
@@ -247,40 +125,6 @@ By design, a dialog's height will never exceed that of the viewport. As such, di
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDialog from '@shoelace-style/shoelace/dist/react/dialog';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDialog label="Dialog" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<div
|
||||
style={{
|
||||
height: '150vh',
|
||||
border: 'dashed 2px var(--wa-color-surface-border)',
|
||||
padding: '0 1rem'
|
||||
}}
|
||||
>
|
||||
<p>Scroll down and give it a try! 👇</p>
|
||||
</div>
|
||||
|
||||
<WaButton slot="footer" variant="brand" data-dialog="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDialog>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Dialog</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Header Actions
|
||||
|
||||
The header shows a functional close button by default. You can use the `header-actions` slot to add additional [icon buttons](/components/icon-button) if needed.
|
||||
@@ -304,38 +148,6 @@ The header shows a functional close button by default. You can use the `header-a
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDialog from '@shoelace-style/shoelace/dist/react/dialog';
|
||||
import WaIconButton from '@shoelace-style/shoelace/dist/react/icon-button';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDialog label="Dialog" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaIconButton
|
||||
class="new-window"
|
||||
slot="header-actions"
|
||||
name="arrow-up-right-from-square"
|
||||
onClick={() => window.open(location.href)}
|
||||
/>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<WaButton slot="footer" variant="brand" data-dialog="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDialog>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Dialog</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Light Dismissal
|
||||
|
||||
If you want the dialog to close when the user clicks on the overlay, add the `light-dismiss` attribute.
|
||||
@@ -356,38 +168,6 @@ If you want the dialog to close when the user clicks on the overlay, add the `li
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDialog from '@shoelace-style/shoelace/dist/react/dialog';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDialog
|
||||
label="Dialog"
|
||||
light-dismiss
|
||||
with-header
|
||||
with-footer
|
||||
open={open}
|
||||
onWaAfterHide={() => setOpen(false)}
|
||||
>
|
||||
This dialog will close when you click on the overlay.
|
||||
<WaButton ref={closeButton} slot="footer" variant="brand" data-dialog="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDialog>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Dialog</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Preventing the Dialog from Closing
|
||||
|
||||
By default, dialogs will close when the user clicks the close button, clicks the overlay, or presses the [[Escape]] key. In most cases, the default behavior is the best behavior in terms of UX. However, there are situations where this may be undesirable, such as when data loss will occur.
|
||||
@@ -420,47 +200,6 @@ You can use `event.detail.source` to determine which element triggered the reque
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useRef, useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDialog from '@shoelace-style/shoelace/dist/react/dialog';
|
||||
|
||||
const App = () => {
|
||||
const closeButton = useRef(null);
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
// Prevent the dialog from closing when the user clicks on the overlay
|
||||
function handleRequestClose(event) {
|
||||
if (event.detail.source !== closeButton) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDialog
|
||||
label="Dialog"
|
||||
with-header
|
||||
with-footer
|
||||
open={open}
|
||||
onWaRequestClose={handleRequestClose}
|
||||
onWaAfterHide={() => setOpen(false)}
|
||||
>
|
||||
This dialog will only close when you click the right button.
|
||||
<WaButton ref={closeButton} slot="footer" variant="brand" data-dialog="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDialog>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Dialog</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Setting Initial Focus
|
||||
|
||||
To give focus to a specific element when the dialog opens, use the `autofocus` attribute.
|
||||
@@ -481,30 +220,3 @@ To give focus to a specific element when the dialog opens, use the `autofocus` a
|
||||
openButton.addEventListener('click', () => dialog.open = true);
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDialog from '@shoelace-style/shoelace/dist/react/dialog';
|
||||
import WaInput from '@shoelace-style/shoelace/dist/react/input';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDialog label="Dialog" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaInput autofocus placeholder="I will have focus when the dialog is opened" />
|
||||
<WaButton slot="footer" variant="brand" data-dialog="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDialog>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Dialog</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
|
||||
@@ -8,14 +8,6 @@ layout: component.njk
|
||||
<wa-divider></wa-divider>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
|
||||
const App = () => <WaDivider />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Width
|
||||
@@ -26,14 +18,6 @@ Use the `--width` custom property to change the width of the divider.
|
||||
<wa-divider style="--width: 4px;"></wa-divider>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
|
||||
const App = () => <WaDivider style={{ '--width': '4px' }} />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Color
|
||||
|
||||
Use the `--color` custom property to change the color of the divider.
|
||||
@@ -42,14 +26,6 @@ Use the `--color` custom property to change the color of the divider.
|
||||
<wa-divider style="--color: tomato;"></wa-divider>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
|
||||
const App = () => <WaDivider style={{ '--color': 'tomato' }} />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Spacing
|
||||
|
||||
Use the `--spacing` custom property to change the amount of space between the divider and it's neighboring elements.
|
||||
@@ -76,28 +52,6 @@ Add the `vertical` attribute to draw the divider in a vertical orientation. The
|
||||
</div>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
|
||||
const App = () => (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
height: '2rem'
|
||||
}}
|
||||
>
|
||||
First
|
||||
<WaDivider vertical />
|
||||
Middle
|
||||
<WaDivider vertical />
|
||||
Last
|
||||
</div>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Menu Dividers
|
||||
|
||||
Use dividers in [menus](/components/menu) to visually group menu items.
|
||||
@@ -113,23 +67,3 @@ Use dividers in [menus](/components/menu) to visually group menu items.
|
||||
<wa-menu-item value="6">Option 6</wa-menu-item>
|
||||
</wa-menu>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => (
|
||||
<WaMenu style={{ maxWidth: '200px' }}>
|
||||
<WaMenuItem value="1">Option 1</WaMenuItem>
|
||||
<WaMenuItem value="2">Option 2</WaMenuItem>
|
||||
<WaMenuItem value="3">Option 3</WaMenuItem>
|
||||
<wa-divider />
|
||||
<WaMenuItem value="4">Option 4</WaMenuItem>
|
||||
<WaMenuItem value="5">Option 5</WaMenuItem>
|
||||
<WaMenuItem value="6">Option 6</WaMenuItem>
|
||||
</WaMenu>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -22,31 +22,6 @@ layout: component.njk
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDrawer from '@shoelace-style/shoelace/dist/react/drawer';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<WaButton slot="footer" variant="brand" data-drawer="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDrawer>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Drawer</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Drawer with Header
|
||||
@@ -68,28 +43,6 @@ Headers can be used to display titles and more. Use the `with-header` attribute
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDrawer from '@shoelace-style/shoelace/dist/react/drawer';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" with-header open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
</WaDrawer>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Drawer</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Drawer with Footer
|
||||
|
||||
Footers can be used to display titles and more. Use the `with-footer` attribute to add a footer to the drawer.
|
||||
@@ -110,31 +63,6 @@ Footers can be used to display titles and more. Use the `with-footer` attribute
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDrawer from '@shoelace-style/shoelace/dist/react/drawer';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<WaButton slot="footer" variant="brand" data-drawer="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDrawer>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Drawer</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Dismissing Drawers
|
||||
|
||||
You can add the special `data-drawer="dismiss"` attribute to a button inside the drawer to tell it to close without additional JavaScript. Alternatively, you can set the `open` property to `false` to close the drawer programmatically.
|
||||
@@ -155,31 +83,6 @@ You can add the special `data-drawer="dismiss"` attribute to a button inside the
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDrawer from '@shoelace-style/shoelace/dist/react/drawer';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<WaButton slot="footer" variant="brand" data-drawer="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDrawer>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Drawer</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Slide in From Start
|
||||
|
||||
By default, drawers slide in from the end. To make the drawer slide in from the start, set the `placement` attribute to `start`.
|
||||
@@ -200,31 +103,6 @@ By default, drawers slide in from the end. To make the drawer slide in from the
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDrawer from '@shoelace-style/shoelace/dist/react/drawer';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" with-header with-footer placement="start" open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
This drawer slides in from the start.
|
||||
<WaButton slot="footer" variant="brand" data-drawer="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDrawer>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Drawer</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Slide in From Top
|
||||
|
||||
To make the drawer slide in from the top, set the `placement` attribute to `top`.
|
||||
@@ -245,31 +123,6 @@ To make the drawer slide in from the top, set the `placement` attribute to `top`
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDrawer from '@shoelace-style/shoelace/dist/react/drawer';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" with-header with-footer placement="top" open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
This drawer slides in from the top.
|
||||
<WaButton slot="footer" variant="brand" data-drawer="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDrawer>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Drawer</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Slide in From Bottom
|
||||
|
||||
To make the drawer slide in from the bottom, set the `placement` attribute to `bottom`.
|
||||
@@ -290,31 +143,6 @@ To make the drawer slide in from the bottom, set the `placement` attribute to `b
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDrawer from '@shoelace-style/shoelace/dist/react/drawer';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" with-header with-footer placement="bottom" open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
This drawer slides in from the bottom.
|
||||
<WaButton slot="footer" variant="brand" data-drawer="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDrawer>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Drawer</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Custom Size
|
||||
|
||||
Use the `--size` custom property to set the drawer's size. This will be applied to the drawer's width or height depending on its `placement`.
|
||||
@@ -335,31 +163,6 @@ Use the `--size` custom property to set the drawer's size. This will be applied
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDrawer from '@shoelace-style/shoelace/dist/react/drawer';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)} style={{ '--size': '50vw' }}>
|
||||
This drawer is always 50% of the viewport.
|
||||
<WaButton slot="footer" variant="brand" data-drawer="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDrawer>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Drawer</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Scrolling
|
||||
|
||||
By design, a drawer's height will never exceed 100% of its container. As such, drawers will not scroll with the page to ensure the header and footer are always accessible to the user.
|
||||
@@ -382,39 +185,6 @@ By design, a drawer's height will never exceed 100% of its container. As such, d
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDrawer from '@shoelace-style/shoelace/dist/react/drawer';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<div
|
||||
style={{
|
||||
height: '150vh',
|
||||
border: 'dashed 2px var(--wa-color-surface-border)',
|
||||
padding: '0 1rem'
|
||||
}}
|
||||
>
|
||||
<p>Scroll down and give it a try! 👇</p>
|
||||
</div>
|
||||
<WaButton slot="footer" variant="brand" data-drawer="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDrawer>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Drawer</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Header Actions
|
||||
|
||||
The header shows a functional close button by default. You can use the `header-actions` slot to add additional [icon buttons](/components/icon-button) if needed.
|
||||
@@ -438,33 +208,6 @@ The header shows a functional close button by default. You can use the `header-a
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDrawer from '@shoelace-style/shoelace/dist/react/drawer';
|
||||
import WaIconButton from '@shoelace-style/shoelace/dist/react/icon-button';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaIconButton slot="header-actions" name="arrow-up-right-from-square" onClick={() => window.open(location.href)} />
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
||||
<WaButton slot="footer" variant="brand" data-drawer="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDrawer>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Drawer</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Light Dismissal
|
||||
|
||||
If you want the drawer to close when the user clicks on the overlay, add the `light-dismiss` attribute.
|
||||
@@ -485,38 +228,6 @@ If you want the drawer to close when the user clicks on the overlay, add the `li
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDrawer from '@shoelace-style/shoelace/dist/react/drawer';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer
|
||||
label="Drawer"
|
||||
light-dismiss
|
||||
with-header
|
||||
with-footer
|
||||
open={open}
|
||||
onWaAfterHide={() => setOpen(false)}
|
||||
>
|
||||
This drawer will close when you click on the overlay.
|
||||
<WaButton ref={closeButton} slot="footer" variant="brand" data-drawer="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDrawer>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Drawer</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Preventing the Drawer from Closing
|
||||
|
||||
By default, drawers will close when the user clicks the close button, clicks the overlay, or presses the [[Escape]] key. In most cases, the default behavior is the best behavior in terms of UX. However, there are situations where this may be undesirable, such as when data loss will occur.
|
||||
@@ -549,38 +260,6 @@ You can use `event.detail.source` to determine what triggered the request to clo
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDrawer from '@shoelace-style/shoelace/dist/react/drawer';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
// Prevent the drawer from closing when the user clicks on the overlay
|
||||
function handleRequestClose(event) {
|
||||
if (event.detail.source === 'overlay') {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" with-header with-footer open={open} onWaRequestClose={handleRequestClose} onWaAfterHide={() => setOpen(false)}>
|
||||
This drawer will not close when you click on the overlay.
|
||||
<WaButton slot="footer" variant="brand" data-drawer="dismiss">
|
||||
Save & Close
|
||||
</WaButton>
|
||||
</WaDrawer>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Drawer</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Customizing Initial Focus
|
||||
|
||||
By default, the drawer's panel will gain focus when opened. This allows a subsequent tab press to focus on the first tabbable element in the drawer. If you want a different element to have focus, add the `autofocus` attribute to it as shown below.
|
||||
@@ -601,30 +280,3 @@ By default, the drawer's panel will gain focus when opened. This allows a subseq
|
||||
openButton.addEventListener('click', () => drawer.open = true);
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDrawer from '@shoelace-style/shoelace/dist/react/drawer';
|
||||
import WaInput from '@shoelace-style/shoelace/dist/react/input';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaDrawer label="Drawer" with-header with-footer open={open} onWaAfterHide={() => setOpen(false)}>
|
||||
<WaInput autofocus placeholder="I will have focus when the drawer is opened" />
|
||||
<WaButton slot="footer" variant="brand" data-drawer="dismiss">
|
||||
Close
|
||||
</WaButton>
|
||||
</WaDrawer>
|
||||
|
||||
<WaButton onClick={() => setOpen(true)}>Open Drawer</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
|
||||
@@ -31,44 +31,6 @@ Dropdowns are designed to work well with [menus](/components/menu) to provide a
|
||||
</wa-dropdown>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
import WaDropdown from '@shoelace-style/shoelace/dist/react/dropdown';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => (
|
||||
<WaDropdown>
|
||||
<WaButton slot="trigger" caret>
|
||||
Dropdown
|
||||
</WaButton>
|
||||
<WaMenu>
|
||||
<WaMenuItem>Dropdown Item 1</WaMenuItem>
|
||||
<WaMenuItem>Dropdown Item 2</WaMenuItem>
|
||||
<WaMenuItem>Dropdown Item 3</WaMenuItem>
|
||||
<WaDivider />
|
||||
<WaMenuItem type="checkbox" checked>
|
||||
Checkbox
|
||||
</WaMenuItem>
|
||||
<WaMenuItem disabled>Disabled</WaMenuItem>
|
||||
<WaDivider />
|
||||
<WaMenuItem>
|
||||
Prefix
|
||||
<WaIcon slot="prefix" name="gift" />
|
||||
</WaMenuItem>
|
||||
<WaMenuItem>
|
||||
Suffix Icon
|
||||
<WaIcon slot="suffix" name="heart" />
|
||||
</WaMenuItem>
|
||||
</WaMenu>
|
||||
</WaDropdown>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Getting the Selected Item
|
||||
@@ -98,35 +60,6 @@ When dropdowns are used with [menus](/components/menu), you can listen for the [
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDropdown from '@shoelace-style/shoelace/dist/react/dropdown';
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => {
|
||||
function handleSelect(event) {
|
||||
const selectedItem = event.detail.item;
|
||||
console.log(selectedItem.value);
|
||||
}
|
||||
|
||||
return (
|
||||
<WaDropdown>
|
||||
<WaButton slot="trigger" caret>
|
||||
Edit
|
||||
</WaButton>
|
||||
<WaMenu onWaSelect={handleSelect}>
|
||||
<WaMenuItem value="cut">Cut</WaMenuItem>
|
||||
<WaMenuItem value="copy">Copy</WaMenuItem>
|
||||
<WaMenuItem value="paste">Paste</WaMenuItem>
|
||||
</WaMenu>
|
||||
</WaDropdown>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
Alternatively, you can listen for the `click` event on individual menu items. Note that, using this approach, disabled menu items will still emit a `click` event.
|
||||
|
||||
```html {.example}
|
||||
@@ -153,42 +86,6 @@ Alternatively, you can listen for the `click` event on individual menu items. No
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDropdown from '@shoelace-style/shoelace/dist/react/dropdown';
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => {
|
||||
function handleCut() {
|
||||
console.log('cut');
|
||||
}
|
||||
|
||||
function handleCopy() {
|
||||
console.log('copy');
|
||||
}
|
||||
|
||||
function handlePaste() {
|
||||
console.log('paste');
|
||||
}
|
||||
|
||||
return (
|
||||
<WaDropdown>
|
||||
<WaButton slot="trigger" caret>
|
||||
Edit
|
||||
</WaButton>
|
||||
<WaMenu>
|
||||
<WaMenuItem onClick={handleCut}>Cut</WaMenuItem>
|
||||
<WaMenuItem onClick={handleCopy}>Copy</WaMenuItem>
|
||||
<WaMenuItem onClick={handlePaste}>Paste</WaMenuItem>
|
||||
</WaMenu>
|
||||
</WaDropdown>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Placement
|
||||
|
||||
The preferred placement of the dropdown can be set with the `placement` attribute. Note that the actual position may vary to ensure the panel remains in the viewport.
|
||||
@@ -207,32 +104,6 @@ The preferred placement of the dropdown can be set with the `placement` attribut
|
||||
</wa-dropdown>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
import WaDropdown from '@shoelace-style/shoelace/dist/react/dropdown';
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => (
|
||||
<WaDropdown placement="top-start">
|
||||
<WaButton slot="trigger" caret>
|
||||
Edit
|
||||
</WaButton>
|
||||
<WaMenu>
|
||||
<WaMenuItem>Cut</WaMenuItem>
|
||||
<WaMenuItem>Copy</WaMenuItem>
|
||||
<WaMenuItem>Paste</WaMenuItem>
|
||||
<WaDivider />
|
||||
<WaMenuItem>Find</WaMenuItem>
|
||||
<WaMenuItem>Replace</WaMenuItem>
|
||||
</WaMenu>
|
||||
</WaDropdown>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Distance
|
||||
|
||||
The distance from the panel to the trigger can be customized using the `distance` attribute. This value is specified in pixels.
|
||||
@@ -251,32 +122,6 @@ The distance from the panel to the trigger can be customized using the `distance
|
||||
</wa-dropdown>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
import WaDropdown from '@shoelace-style/shoelace/dist/react/dropdown';
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => (
|
||||
<WaDropdown distance={30}>
|
||||
<WaButton slot="trigger" caret>
|
||||
Edit
|
||||
</WaButton>
|
||||
<WaMenu>
|
||||
<WaMenuItem>Cut</WaMenuItem>
|
||||
<WaMenuItem>Copy</WaMenuItem>
|
||||
<WaMenuItem>Paste</WaMenuItem>
|
||||
<WaDivider />
|
||||
<WaMenuItem>Find</WaMenuItem>
|
||||
<WaMenuItem>Replace</WaMenuItem>
|
||||
</WaMenu>
|
||||
</WaDropdown>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Skidding
|
||||
|
||||
The offset of the panel along the trigger can be customized using the `skidding` attribute. This value is specified in pixels.
|
||||
@@ -295,32 +140,6 @@ The offset of the panel along the trigger can be customized using the `skidding`
|
||||
</wa-dropdown>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
import WaDropdown from '@shoelace-style/shoelace/dist/react/dropdown';
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => (
|
||||
<WaDropdown skidding={30}>
|
||||
<WaButton slot="trigger" caret>
|
||||
Edit
|
||||
</WaButton>
|
||||
<WaMenu>
|
||||
<WaMenuItem>Cut</WaMenuItem>
|
||||
<WaMenuItem>Copy</WaMenuItem>
|
||||
<WaMenuItem>Paste</WaMenuItem>
|
||||
<WaDivider />
|
||||
<WaMenuItem>Find</WaMenuItem>
|
||||
<WaMenuItem>Replace</WaMenuItem>
|
||||
</WaMenu>
|
||||
</WaDropdown>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Submenus
|
||||
|
||||
To create a submenu, nest an `<wa-menu slot="submenu">` element in a [menu item](/components/menu-item).
|
||||
@@ -357,58 +176,6 @@ To create a submenu, nest an `<wa-menu slot="submenu">` element in a [menu item]
|
||||
</wa-dropdown>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
import WaDropdown from '@shoelace-style/shoelace/dist/react/dropdown';
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const css = `
|
||||
.dropdown-hoist {
|
||||
border: solid 2px var(--wa-color-surface-border);
|
||||
padding: var(--wa-space-m);
|
||||
overflow: hidden;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaDropdown>
|
||||
<WaButton slot="trigger" caret>Edit</WaButton>
|
||||
|
||||
<WaMenu style="max-width: 200px;">
|
||||
<WaMenuItem value="undo">Undo</WaMenuItem>
|
||||
<WaMenuItem value="redo">Redo</WaMenuItem>
|
||||
<WaDivider />
|
||||
<WaMenuItem value="cut">Cut</WaMenuItem>
|
||||
<WaMenuItem value="copy">Copy</WaMenuItem>
|
||||
<WaMenuItem value="paste">Paste</WaMenuItem>
|
||||
<WaDivider />
|
||||
<WaMenuItem>
|
||||
Find
|
||||
<WaMenu slot="submenu">
|
||||
<WaMenuItem value="find">Find…</WaMenuItem>
|
||||
<WaMenuItem value="find-previous">Find Next</WaMenuItem>
|
||||
<WaMenuItem value="find-next">Find Previous</WaMenuItem>
|
||||
</WaMenu>
|
||||
</WaMenuItem>
|
||||
<WaMenuItem>
|
||||
Transformations
|
||||
<WaMenu slot="submenu">
|
||||
<WaMenuItem value="uppercase">Make uppercase</WaMenuItem>
|
||||
<WaMenuItem value="lowercase">Make lowercase</WaMenuItem>
|
||||
<WaMenuItem value="capitalize">Capitalize</WaMenuItem>
|
||||
</WaMenu>
|
||||
</WaMenuItem>
|
||||
</WaMenu>
|
||||
</WaDropdown>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::warning
|
||||
As a UX best practice, avoid using more than one level of submenu when possible.
|
||||
:::
|
||||
@@ -447,51 +214,3 @@ Dropdown panels will be clipped if they're inside a container that has `overflow
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
import WaDropdown from '@shoelace-style/shoelace/dist/react/dropdown';
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const css = `
|
||||
.dropdown-hoist {
|
||||
border: solid 2px var(--wa-color-surface-border);
|
||||
padding: var(--wa-space-m);
|
||||
overflow: hidden;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<div className="dropdown-hoist">
|
||||
<WaDropdown>
|
||||
<WaButton slot="trigger" caret>
|
||||
No Hoist
|
||||
</WaButton>
|
||||
<WaMenu>
|
||||
<WaMenuItem>Item 1</WaMenuItem>
|
||||
<WaMenuItem>Item 2</WaMenuItem>
|
||||
<WaMenuItem>Item 3</WaMenuItem>
|
||||
</WaMenu>
|
||||
</WaDropdown>
|
||||
|
||||
<WaDropdown hoist>
|
||||
<WaButton slot="trigger" caret>
|
||||
Hoist
|
||||
</WaButton>
|
||||
<WaMenu>
|
||||
<WaMenuItem>Item 1</WaMenuItem>
|
||||
<WaMenuItem>Item 2</WaMenuItem>
|
||||
<WaMenuItem>Item 3</WaMenuItem>
|
||||
</WaMenu>
|
||||
</WaDropdown>
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -19,34 +19,6 @@ layout: component.njk
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaFormatBytes from '@shoelace-style/shoelace/dist/react/format-bytes';
|
||||
import WaInput from '@shoelace-style/shoelace/dist/react/input';
|
||||
|
||||
const App = () => {
|
||||
const [value, setValue] = useState(1000);
|
||||
|
||||
return (
|
||||
<>
|
||||
The file is <WaFormatBytes value={value} /> in size.
|
||||
<br />
|
||||
<br />
|
||||
<WaInput
|
||||
type="number"
|
||||
value={value}
|
||||
label="Number to Format"
|
||||
style={{ maxWidth: '180px' }}
|
||||
onWaInput={event => setValue(event.target.value)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Formatting Bytes
|
||||
@@ -60,24 +32,6 @@ Set the `value` attribute to a number to get the value in bytes.
|
||||
<wa-format-bytes value="1200000000"></wa-format-bytes>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaFormatBytes from '@shoelace-style/shoelace/dist/react/format-bytes';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaFormatBytes value="12" />
|
||||
<br />
|
||||
<WaFormatBytes value="1200" />
|
||||
<br />
|
||||
<WaFormatBytes value="1200000" />
|
||||
<br />
|
||||
<WaFormatBytes value="1200000000" />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Formatting Bits
|
||||
|
||||
To get the value in bits, set the `unit` attribute to `bit`.
|
||||
@@ -89,24 +43,6 @@ To get the value in bits, set the `unit` attribute to `bit`.
|
||||
<wa-format-bytes value="1200000000" unit="bit"></wa-format-bytes>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaFormatBytes from '@shoelace-style/shoelace/dist/react/format-bytes';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaFormatBytes value="12" unit="bit" />
|
||||
<br />
|
||||
<WaFormatBytes value="1200" unit="bit" />
|
||||
<br />
|
||||
<WaFormatBytes value="1200000" unit="bit" />
|
||||
<br />
|
||||
<WaFormatBytes value="1200000000" unit="bit" />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Localization
|
||||
|
||||
Use the `lang` attribute to set the number formatting locale.
|
||||
@@ -117,21 +53,3 @@ Use the `lang` attribute to set the number formatting locale.
|
||||
<wa-format-bytes value="1200000" lang="de"></wa-format-bytes><br />
|
||||
<wa-format-bytes value="1200000000" lang="de"></wa-format-bytes>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaFormatBytes from '@shoelace-style/shoelace/dist/react/format-bytes';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaFormatBytes value="12" lang="de" />
|
||||
<br />
|
||||
<WaFormatBytes value="1200" lang="de" />
|
||||
<br />
|
||||
<WaFormatBytes value="1200000" lang="de" />
|
||||
<br />
|
||||
<WaFormatBytes value="1200000000" lang="de" />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -11,14 +11,6 @@ Localization is handled by the browser's [`Intl.DateTimeFormat` API](https://dev
|
||||
<wa-format-date date="2020-07-15T09:17:00-04:00"></wa-format-date>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaFormatDate from '@shoelace-style/shoelace/dist/react/format-date';
|
||||
|
||||
const App = () => <WaFormatDate date="2020-07-15T09:17:00-04:00" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
The `date` attribute determines the date/time to use when formatting. It must be a string that [`Date.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse) can interpret or a [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object set via JavaScript. If omitted, the current date/time will be assumed.
|
||||
|
||||
:::info
|
||||
@@ -51,39 +43,6 @@ Formatting options are based on those found in the [`Intl.DateTimeFormat` API](h
|
||||
<wa-format-date></wa-format-date>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaFormatDate from '@shoelace-style/shoelace/dist/react/format-date';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
{/* Human-readable date */}
|
||||
<WaFormatDate month="long" day="numeric" year="numeric" />
|
||||
<br />
|
||||
|
||||
{/* Time */}
|
||||
<WaFormatDate hour="numeric" minute="numeric" />
|
||||
<br />
|
||||
|
||||
{/* Weekday */}
|
||||
<WaFormatDate weekday="long" />
|
||||
<br />
|
||||
|
||||
{/* Month */}
|
||||
<WaFormatDate month="long" />
|
||||
<br />
|
||||
|
||||
{/* Year */}
|
||||
<WaFormatDate year="numeric" />
|
||||
<br />
|
||||
|
||||
{/* No formatting options */}
|
||||
<WaFormatDate />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Hour Formatting
|
||||
|
||||
By default, the browser will determine whether to use 12-hour or 24-hour time. To force one or the other, set the `hour-format` attribute to `12` or `24`.
|
||||
@@ -93,20 +52,6 @@ By default, the browser will determine whether to use 12-hour or 24-hour time. T
|
||||
<wa-format-date hour="numeric" minute="numeric" hour-format="24"></wa-format-date>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaFormatDate from '@shoelace-style/shoelace/dist/react/format-date';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaFormatDate hour="numeric" minute="numeric" hour-format="12" />
|
||||
<br />
|
||||
<WaFormatDate hour="numeric" minute="numeric" hour-format="24" />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Localization
|
||||
|
||||
Use the `lang` attribute to set the date/time formatting locale.
|
||||
@@ -116,19 +61,3 @@ English: <wa-format-date lang="en"></wa-format-date><br />
|
||||
French: <wa-format-date lang="fr"></wa-format-date><br />
|
||||
Russian: <wa-format-date lang="ru"></wa-format-date>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaFormatDate from '@shoelace-style/shoelace/dist/react/format-date';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
English: <WaFormatDate lang="en" />
|
||||
<br />
|
||||
French: <WaFormatDate lang="fr" />
|
||||
<br />
|
||||
Russian: <WaFormatDate lang="ru" />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -22,33 +22,6 @@ Localization is handled by the browser's [`Intl.NumberFormat` API](https://devel
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaFormatNumber from '@shoelace-style/shoelace/dist/react/format-number';
|
||||
import WaInput from '@shoelace-style/shoelace/dist/react/input';
|
||||
|
||||
const App = () => {
|
||||
const [value, setValue] = useState(1000);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaFormatNumber value={value} />
|
||||
<br />
|
||||
<br />
|
||||
<WaInput
|
||||
type="number"
|
||||
value={value}
|
||||
label="Number to Format"
|
||||
style={{ maxWidth: '180px' }}
|
||||
onWaInput={event => setValue(event.target.value)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Percentages
|
||||
@@ -63,26 +36,6 @@ To get the value as a percent, set the `type` attribute to `percent`.
|
||||
<wa-format-number type="percent" value="1"></wa-format-number>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaFormatNumber from '@shoelace-style/shoelace/dist/react/format-number';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaFormatNumber type="percent" value={0} />
|
||||
<br />
|
||||
<WaFormatNumber type="percent" value={0.25} />
|
||||
<br />
|
||||
<WaFormatNumber type="percent" value={0.5} />
|
||||
<br />
|
||||
<WaFormatNumber type="percent" value={0.75} />
|
||||
<br />
|
||||
<WaFormatNumber type="percent" value={1} />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Localization
|
||||
|
||||
Use the `lang` attribute to set the number formatting locale.
|
||||
@@ -93,22 +46,6 @@ German: <wa-format-number value="2000" lang="de" minimum-fraction-digits="2"></w
|
||||
Russian: <wa-format-number value="2000" lang="ru" minimum-fraction-digits="2"></wa-format-number>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaFormatNumber from '@shoelace-style/shoelace/dist/react/format-number';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
English: <WaFormatNumber value="2000" lang="en" minimum-fraction-digits="2" />
|
||||
<br />
|
||||
German: <WaFormatNumber value="2000" lang="de" minimum-fraction-digits="2" />
|
||||
<br />
|
||||
Russian: <WaFormatNumber value="2000" lang="ru" minimum-fraction-digits="2" />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Currency
|
||||
|
||||
To format a number as a monetary value, set the `type` attribute to `currency` and set the `currency` attribute to the desired ISO 4217 currency code. You should also specify `lang` to ensure the the number is formatted correctly for the target locale.
|
||||
@@ -120,23 +57,3 @@ To format a number as a monetary value, set the `type` attribute to `currency` a
|
||||
<wa-format-number type="currency" currency="RUB" value="2000" lang="ru"></wa-format-number><br />
|
||||
<wa-format-number type="currency" currency="CNY" value="2000" lang="zh-cn"></wa-format-number>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaFormatNumber from '@shoelace-style/shoelace/dist/react/format-number';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaFormatNumber type="currency" currency="USD" value="2000" lang="en-US" />
|
||||
<br />
|
||||
<WaFormatNumber type="currency" currency="GBP" value="2000" lang="en-GB" />
|
||||
<br />
|
||||
<WaFormatNumber type="currency" currency="EUR" value="2000" lang="de" />
|
||||
<br />
|
||||
<WaFormatNumber type="currency" currency="RUB" value="2000" lang="ru" />
|
||||
<br />
|
||||
<WaFormatNumber type="currency" currency="CNY" value="2000" lang="zh-cn" />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -10,14 +10,6 @@ For a full list of icons that come bundled with Web Awesome, refer to the [icon
|
||||
<wa-icon-button name="gear" label="Settings"></wa-icon-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaIconButton from '@shoelace-style/shoelace/dist/react/icon-button';
|
||||
|
||||
const App = () => <WaIconButton name="gear" label="Settings" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Sizes
|
||||
@@ -30,20 +22,6 @@ Icon buttons inherit their parent element's `font-size`.
|
||||
<wa-icon-button name="pen-to-square" variant="solid" label="Edit" style="font-size: 2.5rem;"></wa-icon-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaIconButton from '@shoelace-style/shoelace/dist/react/icon-button';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaIconButton name="pen-to-square" variant="solid" label="Edit" style={{ fontSize: '1.5rem' }} />
|
||||
<WaIconButton name="pen-to-square" variant="solid" label="Edit" style={{ fontSize: '2rem' }} />
|
||||
<WaIconButton name="pen-to-square" variant="solid" label="Edit" style={{ fontSize: '2.5rem' }} />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Colors
|
||||
|
||||
Icon buttons are designed to have a uniform appearance, so their color is not inherited. However, you can still customize them by styling the `base` part.
|
||||
@@ -71,39 +49,6 @@ Icon buttons are designed to have a uniform appearance, so their color is not in
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaIconButton from '@shoelace-style/shoelace/dist/react/icon-button';
|
||||
|
||||
const css = `
|
||||
.icon-button-color wa-icon-button::part(base) {
|
||||
color: #b00091;
|
||||
}
|
||||
|
||||
.icon-button-color wa-icon-button::part(base):hover,
|
||||
.icon-button-color wa-icon-button::part(base):focus {
|
||||
color: #c913aa;
|
||||
}
|
||||
|
||||
.icon-button-color wa-icon-button::part(base):active {
|
||||
color: #960077;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<div className="icon-button-color">
|
||||
<WaIconButton name="type-bold" variant="solid" label="Bold" />
|
||||
<WaIconButton name="type-italic" variant="solid" label="Italic" />
|
||||
<WaIconButton name="type-underline" variant="solid" label="Underline" />
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Link Buttons
|
||||
|
||||
Use the `href` attribute to convert the button to a link.
|
||||
@@ -112,37 +57,15 @@ Use the `href` attribute to convert the button to a link.
|
||||
<wa-icon-button name="gear" variant="solid" label="Settings" href="https://example.com" target="_blank"></wa-icon-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaIconButton from '@shoelace-style/shoelace/dist/react/icon-button';
|
||||
|
||||
const App = () => <WaIconButton name="gear" variant="solid" label="Settings" href="https://example.com" target="_blank" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Icon Button with Tooltip
|
||||
|
||||
Wrap a tooltip around an icon button to provide contextual information to the user.
|
||||
|
||||
```html {.example}
|
||||
<wa-tooltip content="Settings">
|
||||
<wa-icon-button name="gear" variant="solid" label="Settings"></wa-icon-button>
|
||||
</wa-tooltip>
|
||||
<wa-icon-button id="icon-button" name="gear" variant="solid" label="Settings"></wa-icon-button>
|
||||
<wa-tooltip for="icon-button">Settings</wa-tooltip>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaIconButton from '@shoelace-style/shoelace/dist/react/icon-button';
|
||||
import WaTooltip from '@shoelace-style/shoelace/dist/react/tooltip';
|
||||
|
||||
const App = () => (
|
||||
<WaTooltip content="Settings">
|
||||
<WaIconButton name="gear" variant="solid" label="Settings" />
|
||||
</WaTooltip>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` attribute to disable the icon button.
|
||||
@@ -150,11 +73,3 @@ Use the `disabled` attribute to disable the icon button.
|
||||
```html {.example}
|
||||
<wa-icon-button name="gear" variant="solid" label="Settings" disabled></wa-icon-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaIconButton from '@shoelace-style/shoelace/dist/react/icon-button';
|
||||
|
||||
const App = () => <WaIconButton name="gear" variant="solid" label="Settings" disabled />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -4,24 +4,24 @@ description: Icons are symbols that can be used to represent various options wit
|
||||
layout: component.njk
|
||||
---
|
||||
|
||||
Web Awesome comes bundled with over 1,500 icons courtesy of the [Bootstrap Icons](https://icons.getbootstrap.com/) project. These icons are part of the `default` icon library. If you prefer, you can register [custom icon libraries](#icon-libraries) as well.
|
||||
Web Awesome comes bundled with over 2,000 free icons courtesy of [Font Awesome](https://fontawesome.com/). These icons are part of the `default` icon library. Font Awesome Pro users can unlock additional icon families. Or, if you prefer, you can register your own [custom icon library](#icon-library).
|
||||
|
||||
:::info
|
||||
Depending on how you're loading Web Awesome, you may need to copy icon assets and/or [set the base path](/getting-started/installation/#setting-the-base-path) so Web Awesome knows where to load them from. Otherwise, icons may not appear and you'll see 404 Not Found errors in the dev console.
|
||||
Not sure which icon to use? [Find the perfect icon over at Font Awesome!](https://fontawesome.com/search?o=r&m=free&f=brands%2Cclassic)
|
||||
:::
|
||||
|
||||
## Default Icons
|
||||
|
||||
All available icons in the `default` icon library are shown below. Click or tap on any icon to copy its name, then you can use it in your HTML like this.
|
||||
|
||||
```html
|
||||
<wa-icon name="icon-name-here"></wa-icon>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
TODO - show how to use `family` and `variant` attributes.
|
||||
TODO - show how to use FA pro via `data-webawesome-kit="..."`
|
||||
### Families & Variants
|
||||
|
||||
The default icon library is Font Awesome Free, which comes with two icon families: `classic` and `brands`. Use the `family` attribute to set the icon family.
|
||||
|
||||
Many Font Awesome Pro icon families have variants such as `thin`, `light`, `regular`, and `solid`. Font Awesome Pro users can [provide their kit code](/docs/installation) to unlock additional families, including `sharp` and `duotone`. For these icon families, use the `variant` attribute to set the variant.
|
||||
|
||||
```html {.example}
|
||||
<wa-icon family="brands" name="font-awesome"></wa-icon>
|
||||
<wa-icon family="brands" name="web-awesome"></wa-icon>
|
||||
```
|
||||
|
||||
### Colors
|
||||
|
||||
@@ -54,92 +54,33 @@ Icons inherit their color from the current text color. Thus, you can set the `co
|
||||
</div>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<div style={{ color: '#4a90e2' }}>
|
||||
<WaIcon name="exclamation-triangle"></WaIcon>
|
||||
<WaIcon name="archive"></WaIcon>
|
||||
<WaIcon name="battery-three-quarters"></WaIcon>
|
||||
<WaIcon name="bell"></WaIcon>
|
||||
</div>
|
||||
<div style={{ color: '#9013fe' }}>
|
||||
<WaIcon name="clock"></WaIcon>
|
||||
<WaIcon name="cloud"></WaIcon>
|
||||
<WaIcon name="download"></WaIcon>
|
||||
<WaIcon name="file"></WaIcon>
|
||||
</div>
|
||||
<div style={{ color: '#417505' }}>
|
||||
<WaIcon name="flag"></WaIcon>
|
||||
<WaIcon name="heart"></WaIcon>
|
||||
<WaIcon name="image"></WaIcon>
|
||||
<WaIcon name="bolt-lightning"></WaIcon>
|
||||
</div>
|
||||
<div style={{ color: '#f5a623' }}>
|
||||
<WaIcon name="microphone"></WaIcon>
|
||||
<WaIcon name="search"></WaIcon>
|
||||
<WaIcon name="star"></WaIcon>
|
||||
<WaIcon name="trash"></WaIcon>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Sizing
|
||||
|
||||
Icons are sized relative to the current font size. To change their size, set the `font-size` property on the icon itself or on a parent element as shown below.
|
||||
|
||||
```html {.example}
|
||||
<div style="font-size: 32px;">
|
||||
<wa-icon name="exclamation-triangle"></wa-icon>
|
||||
<wa-icon name="archive"></wa-icon>
|
||||
<wa-icon name="battery-three-quarters"></wa-icon>
|
||||
<wa-icon name="bell"></wa-icon>
|
||||
<wa-icon name="clock"></wa-icon>
|
||||
<wa-icon name="cloud"></wa-icon>
|
||||
<wa-icon name="download"></wa-icon>
|
||||
<wa-icon name="file"></wa-icon>
|
||||
<wa-icon name="flag"></wa-icon>
|
||||
<wa-icon name="heart"></wa-icon>
|
||||
<wa-icon name="image"></wa-icon>
|
||||
<wa-icon name="bolt-lightning"></wa-icon>
|
||||
<wa-icon name="microphone"></wa-icon>
|
||||
<wa-icon name="search"></wa-icon>
|
||||
<wa-icon name="star"></wa-icon>
|
||||
<wa-icon name="trash"></wa-icon>
|
||||
</div>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
### Fixed Width Icons
|
||||
|
||||
const App = () => (
|
||||
<div style={{ fontSize: '32px' }}>
|
||||
<WaIcon name="exclamation-triangle" />
|
||||
<WaIcon name="archive" />
|
||||
<WaIcon name="battery-three-quarters" />
|
||||
<WaIcon name="bell" />
|
||||
<WaIcon name="clock" />
|
||||
<WaIcon name="cloud" />
|
||||
<WaIcon name="download" />
|
||||
<WaIcon name="file" />
|
||||
<WaIcon name="flag" />
|
||||
<WaIcon name="heart" />
|
||||
<WaIcon name="image" />
|
||||
<WaIcon name="bolt-lightning" />
|
||||
<WaIcon name="microphone" />
|
||||
<WaIcon name="search" />
|
||||
<WaIcon name="star" />
|
||||
<WaIcon name="trash" />
|
||||
</div>
|
||||
);
|
||||
By default, icons have a 1em height and a variable width. Use the `fixed-width` attribute to render the host element in a 1em by 1em box.
|
||||
|
||||
```html {.example}
|
||||
<wa-icon fixed-width name="cloud"></wa-icon>
|
||||
<wa-icon fixed-width name="user"></wa-icon>
|
||||
<wa-icon fixed-width name="truck"></wa-icon>
|
||||
<wa-icon fixed-width name="file"></wa-icon>
|
||||
<wa-icon fixed-width name="skating"></wa-icon>
|
||||
<wa-icon fixed-width name="snowplow"></wa-icon>
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Labels
|
||||
|
||||
@@ -149,37 +90,21 @@ For non-decorative icons, use the `label` attribute to announce it to assistive
|
||||
<wa-icon name="star" label="Add to favorites"></wa-icon>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
|
||||
const App = () => <WaIcon name="star" label="Add to favorites" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Custom Icons
|
||||
|
||||
Custom icons can be loaded individually with the `src` attribute. Only SVGs on a local or CORS-enabled endpoint are supported. If you're using more than one custom icon, it might make sense to register a [custom icon library](#icon-libraries).
|
||||
|
||||
```html {.example}
|
||||
<wa-icon src="https://shoelace.style/assets/images/shoe.svg" style="font-size: 8rem;"></wa-icon>
|
||||
<wa-icon src="https://shoelace.style/assets/images/shoe.svg" style="font-size: 4rem;"></wa-icon>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
|
||||
const App = () => <WaIcon src="https://shoelace.style/assets/images/shoe.svg" style={{ fontSize: '8rem' }}></WaIcon>;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Icon Libraries
|
||||
|
||||
You can register additional icons to use with the `<wa-icon>` component through icon libraries. Icon files can exist locally or on a CORS-enabled endpoint (e.g. a CDN). There is no limit to how many icon libraries you can register and there is no cost associated with registering them, as individual icons are only requested when they're used.
|
||||
|
||||
Web Awesome ships with two built-in icon libraries, `default` and `system`. The [default icon library](#customizing-the-default-library) contains all of the icons in the Bootstrap Icons project. The [system icon library](#customizing-the-system-library) contains only a small subset of icons that are used internally by Web Awesome components.
|
||||
Web Awesome ships with two built-in icon libraries, `default` and `system`. The [default icon library](#customizing-the-default-library) is provided courtesy of [Font Awesome](https://fontawesome.com/). The [system icon library](#customizing-the-system-library) contains only a small subset of icons that are used internally by Web Awesome components.
|
||||
|
||||
To register an additional icon library, use the `registerIconLibrary()` function that's exported from `utilities/icon-library.js`. At a minimum, you must provide a name and a resolver function. The resolver function translates an icon name to a URL where the corresponding SVG file exists. Refer to the examples below to better understand how it works.
|
||||
To register an additional icon library, use the `registerIconLibrary()` function that's exported from `dist/webawesome.js`. At a minimum, you must provide a name and a resolver function. The resolver function translates an icon name to a URL where the corresponding SVG file exists. Refer to the examples below to better understand how it works.
|
||||
|
||||
If necessary, a mutator function can be used to mutate the SVG element before rendering. This is necessary for some libraries due to the many possible ways SVGs are crafted. For example, icons should ideally inherit the current text color via `currentColor`, so you may need to apply `fill="currentColor` or `stroke="currentColor"` to the SVG element using this function.
|
||||
|
||||
@@ -187,10 +112,10 @@ Here's an example that registers an icon library located in the `/assets/icons`
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
|
||||
import { registerIconLibrary } from '/dist/webawesome.js';
|
||||
|
||||
registerIconLibrary('my-icons', {
|
||||
resolver: name => `/assets/icons/${name}.svg`,
|
||||
resolver: (name, family, variant) => `/assets/icons/${name}.svg`,
|
||||
mutator: svg => svg.setAttribute('fill', 'currentColor')
|
||||
});
|
||||
</script>
|
||||
@@ -207,6 +132,25 @@ If an icon is used before registration occurs, it will be empty initially but sh
|
||||
|
||||
The following examples demonstrate how to register a number of popular, open source icon libraries via CDN. Feel free to adapt the code as you see fit to use your own origin or naming conventions.
|
||||
|
||||
### Bootstrap Icons
|
||||
|
||||
This will register the [Bootstrap Icons](https://icons.getbootstrap.com/) library using the jsDelivr CDN. This library has two families: `regular` and `filled`.
|
||||
|
||||
Icons in this library are licensed under the [MIT License](https://github.com/twbs/icons/blob/main/LICENSE).
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import { registerIconLibrary } from '/dist/webawesome.js';
|
||||
|
||||
registerIconLibrary('default', {
|
||||
resolver: (name, family) => {
|
||||
const suffix = family === 'filled' ? '-fill' : '';
|
||||
return `https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/icons/${name}${suffix}.svg`
|
||||
}
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
### Boxicons
|
||||
|
||||
This will register the [Boxicons](https://boxicons.com/) library using the jsDelivr CDN. This library has three variations: regular (`bx-*`), solid (`bxs-*`), and logos (`bxl-*`). A mutator function is required to set the SVG's `fill` to `currentColor`.
|
||||
@@ -215,9 +159,9 @@ Icons in this library are licensed under the [Creative Commons 4.0 License](http
|
||||
|
||||
```html {.example}
|
||||
<script type="module">
|
||||
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
|
||||
import { registerIconLibrary } from '/dist/webawesome.js';
|
||||
|
||||
registerIconLibrary('boxicons', {
|
||||
registerIconLibrary('boxicons', {
|
||||
resolver: name => {
|
||||
let folder = 'regular';
|
||||
if (name.substring(0, 4) === 'bxs-') folder = 'solid';
|
||||
@@ -269,7 +213,7 @@ Icons in this library are licensed under the [MIT License](https://github.com/lu
|
||||
</div>
|
||||
|
||||
<script type="module">
|
||||
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
|
||||
import { registerIconLibrary } from '/dist/webawesome.js';
|
||||
|
||||
registerIconLibrary('lucide', {
|
||||
resolver: name => `https://cdn.jsdelivr.net/npm/lucide-static@0.16.29/icons/${name}.svg`
|
||||
@@ -277,52 +221,6 @@ Icons in this library are licensed under the [MIT License](https://github.com/lu
|
||||
</script>
|
||||
```
|
||||
|
||||
### Font Awesome
|
||||
|
||||
This will register the [Font Awesome Free](https://fontawesome.com/) library using the jsDelivr CDN. This library has three variations: regular (`far-*`), solid (`fas-*`), and brands (`fab-*`). A mutator function is required to set the SVG's `fill` to `currentColor`.
|
||||
|
||||
Icons in this library are licensed under the [Font Awesome Free License](https://github.com/FortAwesome/Font-Awesome/blob/master/LICENSE.txt). Some of the icons that appear on the Font Awesome website require a license and are therefore not available in the CDN.
|
||||
|
||||
```html {.example}
|
||||
<script type="module">
|
||||
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
|
||||
|
||||
registerIconLibrary('fa', {
|
||||
resolver: name => {
|
||||
const filename = name.replace(/^fa[rbs]-/, '');
|
||||
let folder = 'regular';
|
||||
if (name.substring(0, 4) === 'fas-') folder = 'solid';
|
||||
if (name.substring(0, 4) === 'fab-') folder = 'brands';
|
||||
return `https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.1/svgs/${folder}/${filename}.svg`;
|
||||
},
|
||||
mutator: svg => svg.setAttribute('fill', 'currentColor')
|
||||
});
|
||||
</script>
|
||||
|
||||
<div style="font-size: 24px;">
|
||||
<wa-icon library="fa" name="far-bell"></wa-icon>
|
||||
<wa-icon library="fa" name="far-comment"></wa-icon>
|
||||
<wa-icon library="fa" name="far-hand-point-right"></wa-icon>
|
||||
<wa-icon library="fa" name="far-hdd"></wa-icon>
|
||||
<wa-icon library="fa" name="far-heart"></wa-icon>
|
||||
<wa-icon library="fa" name="far-star"></wa-icon>
|
||||
<br />
|
||||
<wa-icon library="fa" name="fas-archive"></wa-icon>
|
||||
<wa-icon library="fa" name="fas-book"></wa-icon>
|
||||
<wa-icon library="fa" name="fas-chess-knight"></wa-icon>
|
||||
<wa-icon library="fa" name="fas-dice"></wa-icon>
|
||||
<wa-icon library="fa" name="fas-pizza-slice"></wa-icon>
|
||||
<wa-icon library="fa" name="fas-scroll"></wa-icon>
|
||||
<br />
|
||||
<wa-icon library="fa" name="fab-apple"></wa-icon>
|
||||
<wa-icon library="fa" name="fab-chrome"></wa-icon>
|
||||
<wa-icon library="fa" name="fab-edge"></wa-icon>
|
||||
<wa-icon library="fa" name="fab-firefox"></wa-icon>
|
||||
<wa-icon library="fa" name="fab-opera"></wa-icon>
|
||||
<wa-icon library="fa" name="fab-microsoft"></wa-icon>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Heroicons
|
||||
|
||||
This will register the [Heroicons](https://heroicons.com/) library using the jsDelivr CDN.
|
||||
@@ -331,7 +229,7 @@ Icons in this library are licensed under the [MIT License](https://github.com/ta
|
||||
|
||||
```html {.example}
|
||||
<script type="module">
|
||||
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
|
||||
import { registerIconLibrary } from '/dist/webawesome.js';
|
||||
|
||||
registerIconLibrary('heroicons', {
|
||||
resolver: name => `https://cdn.jsdelivr.net/npm/heroicons@2.0.1/24/outline/${name}.svg`
|
||||
@@ -356,7 +254,7 @@ Icons in this library are licensed under the [MIT License](https://github.com/lu
|
||||
|
||||
```html {.example}
|
||||
<script type="module">
|
||||
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
|
||||
import { registerIconLibrary } from '/dist/webawesome.js';
|
||||
|
||||
registerIconLibrary('iconoir', {
|
||||
resolver: name => `https://cdn.jsdelivr.net/gh/lucaburgio/iconoir@latest/icons/${name}.svg`
|
||||
@@ -381,7 +279,7 @@ Icons in this library are licensed under the [MIT License](https://github.com/io
|
||||
|
||||
```html {.example}
|
||||
<script type="module">
|
||||
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
|
||||
import { registerIconLibrary } from '/dist/webawesome.js';
|
||||
|
||||
registerIconLibrary('ionicons', {
|
||||
resolver: name => `https://cdn.jsdelivr.net/npm/ionicons@5.1.2/dist/ionicons/svg/${name}.svg`,
|
||||
@@ -426,7 +324,7 @@ Icons in this library are licensed under the [MIT License](https://github.com/mi
|
||||
|
||||
```html {.example}
|
||||
<script type="module">
|
||||
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
|
||||
import { registerIconLibrary } from '/dist/webawesome.js';
|
||||
|
||||
registerIconLibrary('jam', {
|
||||
resolver: name => `https://cdn.jsdelivr.net/npm/jam-icons@2.0.0/svg/${name}.svg`,
|
||||
@@ -459,7 +357,7 @@ Icons in this library are licensed under the [Apache 2.0 License](https://github
|
||||
|
||||
```html {.example}
|
||||
<script type="module">
|
||||
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
|
||||
import { registerIconLibrary } from '/dist/webawesome.js';
|
||||
|
||||
registerIconLibrary('material', {
|
||||
resolver: name => {
|
||||
@@ -502,7 +400,7 @@ Icons in this library are licensed under the [Apache 2.0 License](https://github
|
||||
|
||||
```html {.example}
|
||||
<script type="module">
|
||||
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
|
||||
import { registerIconLibrary } from '/dist/webawesome.js';
|
||||
|
||||
registerIconLibrary('remixicon', {
|
||||
resolver: name => {
|
||||
@@ -539,7 +437,7 @@ Icons in this library are licensed under the [MIT License](https://github.com/ta
|
||||
|
||||
```html {.example}
|
||||
<script type="module">
|
||||
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
|
||||
import { registerIconLibrary } from '/dist/webawesome.js';
|
||||
|
||||
registerIconLibrary('tabler', {
|
||||
resolver: name => `https://cdn.jsdelivr.net/npm/@tabler/icons@1.68.0/icons/${name}.svg`
|
||||
@@ -571,7 +469,7 @@ Icons in this library are licensed under the [Apache 2.0 License](https://github
|
||||
|
||||
```html {.example}
|
||||
<script type="module">
|
||||
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
|
||||
import { registerIconLibrary } from '/dist/webawesome.js';
|
||||
|
||||
registerIconLibrary('unicons', {
|
||||
resolver: name => {
|
||||
@@ -603,16 +501,19 @@ Icons in this library are licensed under the [Apache 2.0 License](https://github
|
||||
|
||||
### Customizing the Default Library
|
||||
|
||||
The default icon library contains over 1,300 icons courtesy of the [Bootstrap Icons](https://icons.getbootstrap.com/) project. These are the icons that display when you use `<wa-icon>` without the `library` attribute. If you prefer to have these icons resolve elsewhere or to a different icon library, register an icon library using the `default` name and a custom resolver.
|
||||
The default icon library contains over 2,000 icons courtesy of [Font Awesome](https://fontawesome.com/). These are the icons that display when you use `<wa-icon>` without the `library` attribute. If you prefer to have these icons resolve elsewhere or to a different icon library, register an icon library using the `default` name and a custom resolver.
|
||||
|
||||
This example will load the same set of icons from the jsDelivr CDN instead of your local assets folder.
|
||||
For example, this will change the default icon library to use [Bootstrap Icons](https://icons.getbootstrap.com/) loaded from the jsDelivr CDN.
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
|
||||
import { registerIconLibrary } from '/dist/webawesome.js';
|
||||
|
||||
registerIconLibrary('default', {
|
||||
resolver: name => `https://cdn.jsdelivr.net/npm/bootstrap-icons@1.0.0/icons/${name}.svg`
|
||||
resolver: (name, family) => {
|
||||
const suffix = family === 'filled' ? '-fill' : '';
|
||||
return `https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/icons/${name}${suffix}.svg`
|
||||
}
|
||||
});
|
||||
</script>
|
||||
```
|
||||
@@ -623,15 +524,15 @@ To improve performance you can use a SVG sprites to avoid multiple trips for eac
|
||||
|
||||
As always, make sure to benchmark these changes. When using HTTP/2, it may in fact be more bandwidth-friendly to use multiple small requests instead of 1 large sprite sheet.
|
||||
|
||||
:::danger
|
||||
:::warning
|
||||
When using sprite sheets, the `wa-load` and `wa-error` events will not fire.
|
||||
|
||||
For security reasons, browsers may apply the same-origin policy on `<use>` elements located in the `<wa-icon>` shadow DOM and may refuse to load a cross-origin URL. There is currently no defined way to set a cross-origin policy for `<use>` elements. For this reason, sprite sheets should only be used if you're self-hosting them.
|
||||
:::
|
||||
|
||||
```html {.example}
|
||||
```html
|
||||
<script type="module">
|
||||
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
|
||||
import { registerIconLibrary } from '/dist/webawesome.js';
|
||||
|
||||
registerIconLibrary('sprite', {
|
||||
resolver: name => `/assets/images/sprite.svg#${name}`,
|
||||
@@ -639,11 +540,6 @@ For security reasons, browsers may apply the same-origin policy on `<use>` eleme
|
||||
spriteSheet: true
|
||||
});
|
||||
</script>
|
||||
|
||||
<div style="font-size: 24px;">
|
||||
<wa-icon library="sprite" name="clock"></wa-icon>
|
||||
<wa-icon library="sprite" name="speedometer"></wa-icon>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Customizing the System Library
|
||||
@@ -654,7 +550,7 @@ If you want to change the icons Web Awesome uses internally, you can register an
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import { registerIconLibrary } from '/dist/utilities/icon-library.js';
|
||||
import { registerIconLibrary } from '/dist/webawesome.js';
|
||||
|
||||
registerIconLibrary('system', {
|
||||
resolver: name => `/path/to/custom/icons/${name}.svg`
|
||||
|
||||
@@ -21,27 +21,6 @@ For best results, use images that share the same dimensions. The slider can be c
|
||||
</wa-image-comparer>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaImageComparer from '@shoelace-style/shoelace/dist/react/image-comparer';
|
||||
|
||||
const App = () => (
|
||||
<WaImageComparer>
|
||||
<img
|
||||
slot="before"
|
||||
src="https://images.unsplash.com/photo-1517331156700-3c241d2b4d83?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=80&sat=-100&bri=-5"
|
||||
alt="Grayscale version of kittens in a basket looking around."
|
||||
/>
|
||||
<img
|
||||
slot="after"
|
||||
src="https://images.unsplash.com/photo-1517331156700-3c241d2b4d83?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=80"
|
||||
alt="Color version of kittens in a basket looking around."
|
||||
/>
|
||||
</WaImageComparer>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Initial Position
|
||||
@@ -62,24 +41,3 @@ Use the `position` attribute to set the initial position of the slider. This is
|
||||
/>
|
||||
</wa-image-comparer>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaImageComparer from '@shoelace-style/shoelace/dist/react/image-comparer';
|
||||
|
||||
const App = () => (
|
||||
<WaImageComparer position={25}>
|
||||
<img
|
||||
slot="before"
|
||||
src="https://images.unsplash.com/photo-1520903074185-8eca362b3dce?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1200&q=80"
|
||||
alt="A person sitting on bricks wearing untied boots."
|
||||
/>
|
||||
<img
|
||||
slot="after"
|
||||
src="https://images.unsplash.com/photo-1520640023173-50a135e35804?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2250&q=80"
|
||||
alt="A person sitting on a yellow curb tying shoelaces on a boot."
|
||||
/>
|
||||
</WaImageComparer>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -12,14 +12,6 @@ The included content will be inserted into the `<wa-include>` element's default
|
||||
<wa-include src="https://shoelace.style/assets/examples/include.html"></wa-include>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaInclude from '@shoelace-style/shoelace/dist/react/include';
|
||||
|
||||
const App = () => <WaInclude src="https://shoelace.style/assets/examples/include.html" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Listening for Events
|
||||
|
||||
@@ -8,14 +8,6 @@ layout: component.njk
|
||||
<form><wa-input></wa-input></form>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaInput from '@shoelace-style/shoelace/dist/react/input';
|
||||
|
||||
const App = () => <WaInput />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::info
|
||||
This component works with standard `<form>` elements. Please refer to the section on [form controls](/getting-started/form-controls) to learn more about form submission and client-side validation.
|
||||
:::
|
||||
@@ -30,15 +22,6 @@ Use the `label` attribute to give the input an accessible label. For labels that
|
||||
<wa-input label="What is your name?"></wa-input>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
import WaInput from '@shoelace-style/shoelace/dist/react/input';
|
||||
|
||||
const App = () => <WaInput label="What is your name?" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Help Text
|
||||
|
||||
Add descriptive help text to an input with the `help-text` attribute. For help texts that contain HTML, use the `help-text` slot instead.
|
||||
@@ -47,15 +30,6 @@ Add descriptive help text to an input with the `help-text` attribute. For help t
|
||||
<wa-input label="Nickname" help-text="What would you like people to call you?"></wa-input>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
import WaInput from '@shoelace-style/shoelace/dist/react/input';
|
||||
|
||||
const App = () => <WaInput label="Nickname" help-text="What would you like people to call you?" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Placeholders
|
||||
|
||||
Use the `placeholder` attribute to add a placeholder.
|
||||
@@ -64,14 +38,6 @@ Use the `placeholder` attribute to add a placeholder.
|
||||
<wa-input placeholder="Type something"></wa-input>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaInput from '@shoelace-style/shoelace/dist/react/input';
|
||||
|
||||
const App = () => <WaInput placeholder="Type something" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Clearable
|
||||
|
||||
Add the `clearable` attribute to add a clear button when the input has content.
|
||||
@@ -80,14 +46,6 @@ Add the `clearable` attribute to add a clear button when the input has content.
|
||||
<wa-input placeholder="Clearable" clearable></wa-input>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaInput from '@shoelace-style/shoelace/dist/react/input';
|
||||
|
||||
const App = () => <WaInput placeholder="Clearable" clearable />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Toggle Password
|
||||
|
||||
Add the `password-toggle` attribute to add a toggle button that will show the password when activated.
|
||||
@@ -96,14 +54,6 @@ Add the `password-toggle` attribute to add a toggle button that will show the pa
|
||||
<wa-input type="password" placeholder="Password Toggle" password-toggle></wa-input>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaInput from '@shoelace-style/shoelace/dist/react/input';
|
||||
|
||||
const App = () => <WaInput type="password" placeholder="Password Toggle" size="medium" password-toggle />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Filled Inputs
|
||||
|
||||
Add the `filled` attribute to draw a filled input.
|
||||
@@ -112,14 +62,6 @@ Add the `filled` attribute to draw a filled input.
|
||||
<wa-input placeholder="Type something" filled></wa-input>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaInput from '@shoelace-style/shoelace/dist/react/input';
|
||||
|
||||
const App = () => <WaInput placeholder="Type something" filled />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` attribute to disable an input.
|
||||
@@ -128,14 +70,6 @@ Use the `disabled` attribute to disable an input.
|
||||
<wa-input placeholder="Disabled" disabled></wa-input>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaInput from '@shoelace-style/shoelace/dist/react/input';
|
||||
|
||||
const App = () => <WaInput placeholder="Disabled" disabled />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Sizes
|
||||
|
||||
Use the `size` attribute to change an input's size.
|
||||
@@ -148,22 +82,6 @@ Use the `size` attribute to change an input's size.
|
||||
<wa-input placeholder="Large" size="large"></wa-input>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaInput from '@shoelace-style/shoelace/dist/react/input';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaInput placeholder="Small" size="small" />
|
||||
<br />
|
||||
<WaInput placeholder="Medium" size="medium" />
|
||||
<br />
|
||||
<WaInput placeholder="Large" size="large" />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Pill
|
||||
|
||||
Use the `pill` attribute to give inputs rounded edges.
|
||||
@@ -176,22 +94,6 @@ Use the `pill` attribute to give inputs rounded edges.
|
||||
<wa-input placeholder="Large" size="large" pill></wa-input>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaInput from '@shoelace-style/shoelace/dist/react/input';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaInput placeholder="Small" size="small" pill />
|
||||
<br />
|
||||
<WaInput placeholder="Medium" size="medium" pill />
|
||||
<br />
|
||||
<WaInput placeholder="Large" size="large" pill />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Input Types
|
||||
|
||||
The `type` attribute controls the type of input the browser renders.
|
||||
@@ -204,22 +106,6 @@ The `type` attribute controls the type of input the browser renders.
|
||||
<wa-input type="date" placeholder="Date"></wa-input>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaInput from '@shoelace-style/shoelace/dist/react/input';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaInput type="email" placeholder="Email" />
|
||||
<br />
|
||||
<WaInput type="number" placeholder="Number" />
|
||||
<br />
|
||||
<WaInput type="date" placeholder="Date" />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Prefix & Suffix Icons
|
||||
|
||||
Use the `prefix` and `suffix` slots to add icons.
|
||||
@@ -241,32 +127,6 @@ Use the `prefix` and `suffix` slots to add icons.
|
||||
</wa-input>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
import WaInput from '@shoelace-style/shoelace/dist/react/input';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaInput placeholder="Small" size="small">
|
||||
<WaIcon name="house" variant="solid" slot="prefix"></WaIcon>
|
||||
<WaIcon name="comment" variant="solid" slot="suffix"></WaIcon>
|
||||
</WaInput>
|
||||
<br />
|
||||
<WaInput placeholder="Medium" size="medium">
|
||||
<WaIcon name="house" variant="solid" slot="prefix"></WaIcon>
|
||||
<WaIcon name="comment" variant="solid" slot="suffix"></WaIcon>
|
||||
</WaInput>
|
||||
<br />
|
||||
<WaInput placeholder="Large" size="large">
|
||||
<WaIcon name="house" variant="solid" slot="prefix"></WaIcon>
|
||||
<WaIcon name="comment" variant="solid" slot="suffix"></WaIcon>
|
||||
</WaInput>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Customizing Label Position
|
||||
|
||||
Use [CSS parts](#css-parts) to customize the way form controls are drawn. This example uses CSS grid to position the label to the left of the control, but the possible orientations are nearly endless. The same technique works for inputs, textareas, radio groups, and similar form controls.
|
||||
|
||||
@@ -24,37 +24,6 @@ layout: component.njk
|
||||
</wa-menu>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => (
|
||||
<WaMenu style={{ maxWidth: '200px' }}>
|
||||
<WaMenuItem>Option 1</WaMenuItem>
|
||||
<WaMenuItem>Option 2</WaMenuItem>
|
||||
<WaMenuItem>Option 3</WaMenuItem>
|
||||
<WaDivider />
|
||||
<WaMenuItem type="checkbox" checked>
|
||||
Checkbox
|
||||
</WaMenuItem>
|
||||
<WaMenuItem disabled>Disabled</WaMenuItem>
|
||||
<WaDivider />
|
||||
<WaMenuItem>
|
||||
Prefix Icon
|
||||
<WaIcon slot="prefix" name="gift" variant="solid" />
|
||||
</WaMenuItem>
|
||||
<WaMenuItem>
|
||||
Suffix Icon
|
||||
<WaIcon slot="suffix" name="heart" variant="solid" />
|
||||
</WaMenuItem>
|
||||
</WaMenu>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Prefix & Suffix
|
||||
@@ -83,40 +52,6 @@ Add content to the start and end of menu items using the `prefix` and `suffix` s
|
||||
</wa-menu>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaBadge from '@shoelace-style/shoelace/dist/react/badge';
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => (
|
||||
<WaMenu style={{ maxWidth: '200px' }}>
|
||||
<WaMenuItem>
|
||||
<WaIcon slot="prefix" name="house" variant="solid" />
|
||||
Home
|
||||
</WaMenuItem>
|
||||
|
||||
<WaMenuItem>
|
||||
<WaIcon slot="prefix" name="envelope" variant="solid" />
|
||||
Messages
|
||||
<WaBadge slot="suffix" variant="brand" pill>
|
||||
12
|
||||
</WaBadge>
|
||||
</WaMenuItem>
|
||||
|
||||
<WaDivider />
|
||||
|
||||
<WaMenuItem>
|
||||
<WaIcon slot="prefix" name="gear" variant="solid" />
|
||||
Settings
|
||||
</WaMenuItem>
|
||||
</WaMenu>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Disabled
|
||||
|
||||
Add the `disabled` attribute to disable the menu item so it cannot be selected.
|
||||
@@ -129,21 +64,6 @@ Add the `disabled` attribute to disable the menu item so it cannot be selected.
|
||||
</wa-menu>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => (
|
||||
<WaMenu style={{ maxWidth: '200px' }}>
|
||||
<WaMenuItem>Option 1</WaMenuItem>
|
||||
<WaMenuItem disabled>Option 2</WaMenuItem>
|
||||
<WaMenuItem>Option 3</WaMenuItem>
|
||||
</WaMenu>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Loading
|
||||
|
||||
Use the `loading` attribute to indicate that a menu item is busy. Like a disabled menu item, clicks will be suppressed until the loading state is removed.
|
||||
@@ -156,21 +76,6 @@ Use the `loading` attribute to indicate that a menu item is busy. Like a disable
|
||||
</wa-menu>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => (
|
||||
<WaMenu style={{ maxWidth: '200px' }}>
|
||||
<WaMenuItem>Option 1</WaMenuItem>
|
||||
<WaMenuItem loading>Option 2</WaMenuItem>
|
||||
<WaMenuItem>Option 3</WaMenuItem>
|
||||
</WaMenu>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Checkbox Menu Items
|
||||
|
||||
Set the `type` attribute to `checkbox` to create a menu item that will toggle on and off when selected. You can use the `checked` attribute to set the initial state.
|
||||
@@ -185,23 +90,6 @@ Checkbox menu items are visually indistinguishable from regular menu items. Thei
|
||||
</wa-menu>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => (
|
||||
<WaMenu style={{ maxWidth: '200px' }}>
|
||||
<WaMenuItem type="checkbox">Autosave</WaMenuItem>
|
||||
<WaMenuItem type="checkbox" checked>
|
||||
Check Spelling
|
||||
</WaMenuItem>
|
||||
<WaMenuItem type="checkbox">Word Wrap</WaMenuItem>
|
||||
</WaMenu>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Value & Selection
|
||||
|
||||
The `value` attribute can be used to assign a hidden value, such as a unique identifier, to a menu item. When an item is selected, the `wa-select` event will be emitted and a reference to the item will be available at `event.detail.item`. You can use this reference to access the selected item's value, its checked state, and more.
|
||||
@@ -233,29 +121,3 @@ The `value` attribute can be used to assign a hidden value, such as a unique ide
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => {
|
||||
function handleSelect(event) {
|
||||
const item = event.detail.item;
|
||||
|
||||
// Toggle checked state
|
||||
item.checked = !item.checked;
|
||||
|
||||
// Log value
|
||||
console.log(`Selected value: ${item.value}`);
|
||||
}
|
||||
|
||||
return (
|
||||
<WaMenu style={{ maxWidth: '200px' }} onWaSelect={handleSelect}>
|
||||
<WaMenuItem value="opt-1">Option 1</WaMenuItem>
|
||||
<WaMenuItem value="opt-2">Option 2</WaMenuItem>
|
||||
<WaMenuItem value="opt-3">Option 3</WaMenuItem>
|
||||
</WaMenu>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -17,26 +17,3 @@ layout: component.njk
|
||||
<wa-menu-item value="zucchini">Zucchini</wa-menu-item>
|
||||
</wa-menu>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuLabel from '@shoelace-style/shoelace/dist/react/menu-label';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => (
|
||||
<WaMenu style={{ maxWidth: '200px' }}>
|
||||
<WaMenuLabel>Fruits</WaMenuLabel>
|
||||
<WaMenuItem value="apple">Apple</WaMenuItem>
|
||||
<WaMenuItem value="banana">Banana</WaMenuItem>
|
||||
<WaMenuItem value="orange">Orange</WaMenuItem>
|
||||
<WaDivider />
|
||||
<WaMenuLabel>Vegetables</WaMenuLabel>
|
||||
<WaMenuItem value="broccoli">Broccoli</WaMenuItem>
|
||||
<WaMenuItem value="carrot">Carrot</WaMenuItem>
|
||||
<WaMenuItem value="zucchini">Zucchini</WaMenuItem>
|
||||
</WaMenu>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -18,26 +18,6 @@ You can use [menu items](/components/menu-item), [menu labels](/components/menu-
|
||||
</wa-menu>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => (
|
||||
<WaMenu style={{ maxWidth: '200px' }}>
|
||||
<WaMenuItem value="undo">Undo</WaMenuItem>
|
||||
<WaMenuItem value="redo">Redo</WaMenuItem>
|
||||
<WaDivider />
|
||||
<WaMenuItem value="cut">Cut</WaMenuItem>
|
||||
<WaMenuItem value="copy">Copy</WaMenuItem>
|
||||
<WaMenuItem value="paste">Paste</WaMenuItem>
|
||||
<WaMenuItem value="delete">Delete</WaMenuItem>
|
||||
</WaMenu>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::info
|
||||
Menus are intended for system menus (dropdown menus, select menus, context menus, etc.). They should not be mistaken for navigation menus which serve a different purpose and have a different semantic meaning. If you're building navigation, use `<nav>` and `<a>` elements instead.
|
||||
:::
|
||||
@@ -59,26 +39,6 @@ Menus work really well when used inside [dropdowns](/components/dropdown).
|
||||
</wa-dropdown>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaDropdown from '@shoelace-style/shoelace/dist/react/dropdown';
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => (
|
||||
<WaDropdown>
|
||||
<WaButton slot="trigger" caret>Edit</WaButton>
|
||||
<WaMenu>
|
||||
<WaMenuItem value="cut">Cut</WaMenuItem>
|
||||
<WaMenuItem value="copy">Copy</WaMenuItem>
|
||||
<WaMenuItem value="paste">Paste</WaMenuItem>
|
||||
</WaMenu>
|
||||
</WaDropdown>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Submenus
|
||||
|
||||
To create a submenu, nest an `<wa-menu slot="submenu">` in any [menu item](/components/menu-item).
|
||||
@@ -111,42 +71,6 @@ To create a submenu, nest an `<wa-menu slot="submenu">` in any [menu item](/comp
|
||||
</wa-menu>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => (
|
||||
<WaMenu style={{ maxWidth: '200px' }}>
|
||||
<WaMenuItem value="undo">Undo</WaMenuItem>
|
||||
<WaMenuItem value="redo">Redo</WaMenuItem>
|
||||
<WaDivider />
|
||||
<WaMenuItem value="cut">Cut</WaMenuItem>
|
||||
<WaMenuItem value="copy">Copy</WaMenuItem>
|
||||
<WaMenuItem value="paste">Paste</WaMenuItem>
|
||||
<WaDivider />
|
||||
<WaMenuItem>
|
||||
Find
|
||||
<WaMenu slot="submenu">
|
||||
<WaMenuItem value="find">Find…</WaMenuItem>
|
||||
<WaMenuItem value="find-previous">Find Next</WaMenuItem>
|
||||
<WaMenuItem value="find-next">Find Previous</WaMenuItem>
|
||||
</WaMenu>
|
||||
</WaMenuItem>
|
||||
<WaMenuItem>
|
||||
Transformations
|
||||
<WaMenu slot="submenu">
|
||||
<WaMenuItem value="uppercase">Make uppercase</WaMenuItem>
|
||||
<WaMenuItem value="lowercase">Make lowercase</WaMenuItem>
|
||||
<WaMenuItem value="capitalize">Capitalize</WaMenuItem>
|
||||
</WaMenu>
|
||||
</WaMenuItem>
|
||||
</WaMenu>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::warning
|
||||
As a UX best practice, avoid using more than one level of submenus when possible.
|
||||
:::
|
||||
|
||||
@@ -42,47 +42,6 @@ The mutation observer will report changes to the content it wraps through the `w
|
||||
</div>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaMutationObserver from '@shoelace-style/shoelace/dist/react/mutation-observer';
|
||||
|
||||
const css = `
|
||||
.mutation-overview wa-button {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const variants = ['brand', 'success', 'neutral', 'warning', 'danger'];
|
||||
let clicks = 0;
|
||||
|
||||
const App = () => {
|
||||
const [variant, setVariant] = useState('brand');
|
||||
|
||||
function handleClick() {
|
||||
clicks++;
|
||||
setVariant(variants[clicks % variants.length]);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaMutationObserver attr="*" onWaMutation={event => console.log(event.detail)}>
|
||||
<WaButton variant={variant} onClick={handleClick}>
|
||||
Click to mutate
|
||||
</WaButton>
|
||||
</WaMutationObserver>
|
||||
|
||||
<br />
|
||||
👆 Click the button and watch the console
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::info
|
||||
When you create a mutation observer, you must indicate what changes it should respond to by including at least one of `attr`, `child-list`, or `char-data`. If you don't specify at least one of these attributes, no mutation events will be emitted.
|
||||
:::
|
||||
@@ -143,55 +102,3 @@ Use the `child-list` attribute to watch for new child elements that are added or
|
||||
</style>
|
||||
</div>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaMutationObserver from '@shoelace-style/shoelace/dist/react/mutation-observer';
|
||||
|
||||
const css = `
|
||||
.mutation-child-list .buttons {
|
||||
display: flex;
|
||||
gap: .25rem;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
`;
|
||||
|
||||
let buttonCount = 0;
|
||||
|
||||
const App = () => {
|
||||
const [buttonIds, setButtonIds] = useState([]);
|
||||
|
||||
function addButton() {
|
||||
setButtonIds([...buttonIds, ++buttonCount]);
|
||||
}
|
||||
|
||||
function removeButton(id) {
|
||||
setButtonIds(buttonIds.filter(i => i !== id));
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mutation-child-list">
|
||||
<WaMutationObserver child-list onWaMutation={event => console.log(event.detail)}>
|
||||
<div className="buttons">
|
||||
<WaButton variant="brand" onClick={addButton}>
|
||||
Add button
|
||||
</WaButton>
|
||||
{buttonIds.map(id => (
|
||||
<WaButton key={id} variant="default" onClick={() => removeButton(id)}>
|
||||
{id}
|
||||
</WaButton>
|
||||
))}
|
||||
</div>
|
||||
</WaMutationObserver>
|
||||
</div>
|
||||
👆 Add and remove buttons and watch the console
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -12,21 +12,6 @@ layout: component.njk
|
||||
</wa-select>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaOption from '@shoelace-style/shoelace/dist/react/option';
|
||||
import WaSelect from '@shoelace-style/shoelace/dist/react/select';
|
||||
|
||||
const App = () => (
|
||||
<WaSelect>
|
||||
<WaOption value="option-1">Option 1</WaOption>
|
||||
<WaOption value="option-2">Option 2</WaOption>
|
||||
<WaOption value="option-3">Option 3</WaOption>
|
||||
</WaSelect>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Disabled
|
||||
@@ -41,23 +26,6 @@ Use the `disabled` attribute to disable an option and prevent it from being sele
|
||||
</wa-select>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaOption from '@shoelace-style/shoelace/dist/react/option';
|
||||
import WaSelect from '@shoelace-style/shoelace/dist/react/select';
|
||||
|
||||
const App = () => (
|
||||
<WaSelect>
|
||||
<WaOption value="option-1">Option 1</WaOption>
|
||||
<WaOption value="option-2" disabled>
|
||||
Option 2
|
||||
</WaOption>
|
||||
<WaOption value="option-3">Option 3</WaOption>
|
||||
</WaSelect>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Prefix & Suffix
|
||||
|
||||
Add icons to the start and end of menu items using the `prefix` and `suffix` slots.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,14 +8,6 @@ layout: component.njk
|
||||
<wa-progress-bar value="50"></wa-progress-bar>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaProgressBar from '@shoelace-style/shoelace/dist/react/progress-bar';
|
||||
|
||||
const App = () => <WaProgressBar value={50} />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Labels
|
||||
@@ -26,14 +18,6 @@ Use the `label` attribute to label the progress bar and tell assistive devices h
|
||||
<wa-progress-bar value="50" label="Upload progress"></wa-progress-bar>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaProgressBar from '@shoelace-style/shoelace/dist/react/progress-bar';
|
||||
|
||||
const App = () => <WaProgressBar value="50" label="Upload progress" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Custom Height
|
||||
|
||||
Use the `--height` custom property to set the progress bar's height.
|
||||
@@ -42,14 +26,6 @@ Use the `--height` custom property to set the progress bar's height.
|
||||
<wa-progress-bar value="50" style="--height: 6px;"></wa-progress-bar>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaProgressBar from '@shoelace-style/shoelace/dist/react/progress-bar';
|
||||
|
||||
const App = () => <WaProgressBar value={50} style={{ '--height': '6px' }} />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Showing Values
|
||||
|
||||
Use the default slot to show a value.
|
||||
@@ -81,42 +57,6 @@ Use the default slot to show a value.
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
import WaProgressBar from '@shoelace-style/shoelace/dist/react/progress-bar';
|
||||
|
||||
const App = () => {
|
||||
const [value, setValue] = useState(50);
|
||||
|
||||
function adjustValue(amount) {
|
||||
let newValue = value + amount;
|
||||
if (newValue < 0) newValue = 0;
|
||||
if (newValue > 100) newValue = 100;
|
||||
setValue(newValue);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaProgressBar value={value}>{value}%</WaProgressBar>
|
||||
|
||||
<br />
|
||||
|
||||
<WaButton circle onClick={() => adjustValue(-10)}>
|
||||
<WaIcon name="minus" variant="solid" label="Decrease" />
|
||||
</WaButton>
|
||||
|
||||
<WaButton circle onClick={() => adjustValue(10)}>
|
||||
<WaIcon name="plus" variant="solid" label="Increase" />
|
||||
</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Indeterminate
|
||||
|
||||
The `indeterminate` attribute can be used to inform the user that the operation is pending, but its status cannot currently be determined. In this state, `value` is ignored and the label, if present, will not be shown.
|
||||
@@ -124,11 +64,3 @@ The `indeterminate` attribute can be used to inform the user that the operation
|
||||
```html {.example}
|
||||
<wa-progress-bar indeterminate></wa-progress-bar>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaProgressBar from '@shoelace-style/shoelace/dist/react/progress-bar';
|
||||
|
||||
const App = () => <WaProgressBar indeterminate />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -8,14 +8,6 @@ layout: component.njk
|
||||
<wa-progress-ring value="25"></wa-progress-ring>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaProgressRing from '@shoelace-style/shoelace/dist/react/progress-ring';
|
||||
|
||||
const App = () => <WaProgressRing value="25" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Size
|
||||
@@ -26,14 +18,6 @@ Use the `--size` custom property to set the diameter of the progress ring.
|
||||
<wa-progress-ring value="50" style="--size: 200px;"></wa-progress-ring>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaProgressRing from '@shoelace-style/shoelace/dist/react/progress-ring';
|
||||
|
||||
const App = () => <WaProgressRing value="50" style={{ '--size': '200px' }} />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Track and Indicator Width
|
||||
|
||||
Use the `--track-width` and `--indicator-width` custom properties to set the width of the progress ring's track and indicator.
|
||||
@@ -42,14 +26,6 @@ Use the `--track-width` and `--indicator-width` custom properties to set the wid
|
||||
<wa-progress-ring value="50" style="--track-width: 6px; --indicator-width: 12px;"></wa-progress-ring>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaProgressRing from '@shoelace-style/shoelace/dist/react/progress-ring';
|
||||
|
||||
const App = () => <WaProgressRing value="50" style={{ '--track-width': '6px', '--indicator-width': '12px' }} />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Colors
|
||||
|
||||
To change the color, use the `--track-color` and `--indicator-color` custom properties.
|
||||
@@ -64,22 +40,6 @@ To change the color, use the `--track-color` and `--indicator-color` custom prop
|
||||
></wa-progress-ring>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaProgressRing from '@shoelace-style/shoelace/dist/react/progress-ring';
|
||||
|
||||
const App = () => (
|
||||
<WaProgressRing
|
||||
value="50"
|
||||
style={{
|
||||
'--track-color': 'pink',
|
||||
'--indicator-color': 'deeppink'
|
||||
}}
|
||||
/>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Labels
|
||||
|
||||
Use the `label` attribute to label the progress ring and tell assistive devices how to announce it.
|
||||
@@ -88,14 +48,6 @@ Use the `label` attribute to label the progress ring and tell assistive devices
|
||||
<wa-progress-ring value="50" label="Upload progress"></wa-progress-ring>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaProgressRing from '@shoelace-style/shoelace/dist/react/progress-ring';
|
||||
|
||||
const App = () => <WaProgressRing value="50" label="Upload progress" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Showing Values
|
||||
|
||||
Use the default slot to show a label inside the progress ring.
|
||||
@@ -126,41 +78,3 @@ Use the default slot to show a label inside the progress ring.
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
import WaProgressRing from '@shoelace-style/shoelace/dist/react/progress-ring';
|
||||
|
||||
const App = () => {
|
||||
const [value, setValue] = useState(50);
|
||||
|
||||
function adjustValue(amount) {
|
||||
let newValue = value + amount;
|
||||
if (newValue < 0) newValue = 0;
|
||||
if (newValue > 100) newValue = 100;
|
||||
setValue(newValue);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaProgressRing value={value} style={{ marginBottom: '.5rem' }}>
|
||||
{value}%
|
||||
</WaProgressRing>
|
||||
|
||||
<br />
|
||||
|
||||
<WaButton circle onClick={() => adjustValue(-10)}>
|
||||
<WaIcon name="minus" variant="solid" label="Decrease" />
|
||||
</WaButton>
|
||||
|
||||
<WaButton circle onClick={() => adjustValue(10)}>
|
||||
<WaIcon name="plus" variant="solid" label="Increase" />
|
||||
</WaButton>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -36,41 +36,6 @@ QR codes are useful for providing small pieces of information to users who can q
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaQrCode from '@shoelace-style/shoelace/dist/react/qr-code';
|
||||
import WaInput from '@shoelace-style/shoelace/dist/react/input';
|
||||
|
||||
const css = `
|
||||
.qr-overview {
|
||||
max-width: 256px;
|
||||
}
|
||||
|
||||
.qr-overview wa-input {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => {
|
||||
const [value, setValue] = useState('https://shoelace.style/');
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="qr-overview">
|
||||
<WaQrCode value={value} label="Scan this code to visit Web Awesome on the web!" />
|
||||
<br />
|
||||
|
||||
<WaInput maxlength="255" clearable onInput={event => setValue(event.target.value)} />
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Colors
|
||||
@@ -81,14 +46,6 @@ Use the `fill` and `background` attributes to modify the QR code's colors. You s
|
||||
<wa-qr-code value="https://shoelace.style/" fill="deeppink" background="white"></wa-qr-code>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaQrCode from '@shoelace-style/shoelace/dist/react/qr-code';
|
||||
|
||||
const App = () => <WaQrCode value="https://shoelace.style/" fill="deeppink" background="white" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Size
|
||||
|
||||
Use the `size` attribute to change the size of the QR code.
|
||||
@@ -97,14 +54,6 @@ Use the `size` attribute to change the size of the QR code.
|
||||
<wa-qr-code value="https://shoelace.style/" size="64"></wa-qr-code>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaQrCode from '@shoelace-style/shoelace/dist/react/qr-code';
|
||||
|
||||
const App = () => <WaQrCode value="https://shoelace.style/" size="64" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Radius
|
||||
|
||||
Create a rounded effect with the `radius` attribute.
|
||||
@@ -113,14 +62,6 @@ Create a rounded effect with the `radius` attribute.
|
||||
<wa-qr-code value="https://shoelace.style/" radius="0.5"></wa-qr-code>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaQrCode from '@shoelace-style/shoelace/dist/react/qr-code';
|
||||
|
||||
const App = () => <WaQrCode value="https://shoelace.style/" radius="0.5" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Error Correction
|
||||
|
||||
QR codes can be rendered with various levels of [error correction](https://www.qrcode.com/en/about/error_correction.html) that can be set using the `error-correction` attribute. This example generates four codes with the same value using different error correction levels.
|
||||
@@ -141,32 +82,3 @@ QR codes can be rendered with various levels of [error correction](https://www.q
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaQrCode from '@shoelace-style/shoelace/dist/react/qr-code';
|
||||
|
||||
const css = `
|
||||
.qr-error-correction {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<>
|
||||
<div className="qr-error-correction">
|
||||
<WaQrCode value="https://shoelace.style/" error-correction="L" />
|
||||
<WaQrCode value="https://shoelace.style/" error-correction="M" />
|
||||
<WaQrCode value="https://shoelace.style/" error-correction="Q" />
|
||||
<WaQrCode value="https://shoelace.style/" error-correction="H" />
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -14,21 +14,6 @@ Radio buttons are designed to be used with [radio groups](/components/radio-grou
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRadioButton from '@shoelace-style/shoelace/dist/react/radio-button';
|
||||
import WaRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group';
|
||||
|
||||
const App = () => (
|
||||
<WaRadioGroup label="Select an option" name="a" value="1">
|
||||
<WaRadioButton value="1">Option 1</WaRadioButton>
|
||||
<WaRadioButton value="2">Option 2</WaRadioButton>
|
||||
<WaRadioButton value="3">Option 3</WaRadioButton>
|
||||
</WaRadioGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Checked States
|
||||
@@ -43,21 +28,6 @@ To set the initial value and checked state, use the `value` attribute on the con
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRadioButton from '@shoelace-style/shoelace/dist/react/radio-button';
|
||||
import WaRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group';
|
||||
|
||||
const App = () => (
|
||||
<WaRadioGroup label="Select an option" name="a" value="1">
|
||||
<WaRadioButton value="1">Option 1</WaRadioButton>
|
||||
<WaRadioButton value="2">Option 2</WaRadioButton>
|
||||
<WaRadioButton value="3">Option 3</WaRadioButton>
|
||||
</WaRadioGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` attribute to disable a radio button.
|
||||
@@ -70,23 +40,6 @@ Use the `disabled` attribute to disable a radio button.
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRadioButton from '@shoelace-style/shoelace/dist/react/radio-button';
|
||||
import WaRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group';
|
||||
|
||||
const App = () => (
|
||||
<WaRadioGroup label="Select an option" name="a" value="1">
|
||||
<WaRadioButton value="1">Option 1</WaRadioButton>
|
||||
<WaRadioButton value="2" disabled>
|
||||
Option 2
|
||||
</WaRadioButton>
|
||||
<WaRadioButton value="3">Option 3</WaRadioButton>
|
||||
</WaRadioGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Sizes
|
||||
|
||||
Use the `size` attribute to change a radio button's size.
|
||||
@@ -115,37 +68,6 @@ Use the `size` attribute to change a radio button's size.
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRadioButton from '@shoelace-style/shoelace/dist/react/radio-button';
|
||||
import WaRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group';
|
||||
|
||||
const App = () => (
|
||||
<WaRadioGroup size="small" label="Select an option" name="a" value="1">
|
||||
<WaRadioButton value="1">Option 1</WaRadioButton>
|
||||
<WaRadioButton value="2">Option 2</WaRadioButton>
|
||||
<WaRadioButton value="3">Option 3</WaRadioButton>
|
||||
</WaRadioGroup>
|
||||
|
||||
<br />
|
||||
|
||||
<WaRadioGroup size="medium" label="Select an option" name="a" value="1">
|
||||
<WaRadioButton value="1">Option 1</WaRadioButton>
|
||||
<WaRadioButton value="2">Option 2</WaRadioButton>
|
||||
<WaRadioButton value="3">Option 3</WaRadioButton>
|
||||
</WaRadioGroup>
|
||||
|
||||
<br />
|
||||
|
||||
<WaRadioGroup size="large" label="Select an option" name="a" value="1">
|
||||
<WaRadioButton value="1">Option 1</WaRadioButton>
|
||||
<WaRadioButton value="2">Option 2</WaRadioButton>
|
||||
<WaRadioButton value="3">Option 3</WaRadioButton>
|
||||
</WaRadioGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Pill Buttons
|
||||
|
||||
Use the `pill` attribute to give radio buttons rounded edges.
|
||||
@@ -174,37 +96,6 @@ Use the `pill` attribute to give radio buttons rounded edges.
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRadioButton from '@shoelace-style/shoelace/dist/react/radio-button';
|
||||
import WaRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group';
|
||||
|
||||
const App = () => (
|
||||
<WaRadioGroup size="small" label="Select an option" name="a" value="1">
|
||||
<WaRadioButton pill value="1">Option 1</WaRadioButton>
|
||||
<WaRadioButton pill value="2">Option 2</WaRadioButton>
|
||||
<WaRadioButton pill value="3">Option 3</WaRadioButton>
|
||||
</WaRadioGroup>
|
||||
|
||||
<br />
|
||||
|
||||
<WaRadioGroup size="medium" label="Select an option" name="a" value="1">
|
||||
<WaRadioButton pill value="1">Option 1</WaRadioButton>
|
||||
<WaRadioButton pill value="2">Option 2</WaRadioButton>
|
||||
<WaRadioButton pill value="3">Option 3</WaRadioButton>
|
||||
</WaRadioGroup>
|
||||
|
||||
<br />
|
||||
|
||||
<WaRadioGroup size="large" label="Select an option" name="a" value="1">
|
||||
<WaRadioButton pill value="1">Option 1</WaRadioButton>
|
||||
<WaRadioButton pill value="2">Option 2</WaRadioButton>
|
||||
<WaRadioButton pill value="3">Option 3</WaRadioButton>
|
||||
</WaRadioGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Prefix and Suffix Icons
|
||||
|
||||
Use the `prefix` and `suffix` slots to add icons.
|
||||
@@ -229,34 +120,6 @@ Use the `prefix` and `suffix` slots to add icons.
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
import WaRadioButton from '@shoelace-style/shoelace/dist/react/radio-button';
|
||||
import WaRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group';
|
||||
|
||||
const App = () => (
|
||||
<WaRadioGroup label="Select an option" name="a" value="1">
|
||||
<WaRadioButton value="1">
|
||||
<WaIcon slot="prefix" name="archive" variant="solid" />
|
||||
Option 1
|
||||
</WaRadioButton>
|
||||
|
||||
<WaRadioButton value="2">
|
||||
<WaIcon slot="suffix" name="bag" variant="solid" />
|
||||
Option 2
|
||||
</WaRadioButton>
|
||||
|
||||
<WaRadioButton value="3">
|
||||
<WaIcon slot="prefix" name="gift" variant="solid" />
|
||||
<WaIcon slot="suffix" name="cart" variant="solid" />
|
||||
Option 3
|
||||
</WaRadioButton>
|
||||
</WaRadioGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Buttons with 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.
|
||||
@@ -284,35 +147,3 @@ You can omit button labels and use icons instead. Make sure to set a `label` att
|
||||
</wa-radio-button>
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
import WaRadioButton from '@shoelace-style/shoelace/dist/react/radio-button';
|
||||
import WaRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group';
|
||||
|
||||
const App = () => (
|
||||
<WaRadioGroup label="Select an option" name="a" value="neutral">
|
||||
<WaRadioButton value="angry">
|
||||
<WaIcon name="face-angry" label="Angry" />
|
||||
</WaRadioButton>
|
||||
|
||||
<WaRadioButton value="sad">
|
||||
<WaIcon name="face-frown" label="Sad" />
|
||||
</WaRadioButton>
|
||||
|
||||
<WaRadioButton value="neutral">
|
||||
<WaIcon name="face-neutral" label="Neutral" />
|
||||
</WaRadioButton>
|
||||
|
||||
<WaRadioButton value="happy">
|
||||
<WaIcon name="face-smile" label="Happy" />
|
||||
</WaRadioButton>
|
||||
|
||||
<WaRadioButton value="laughing">
|
||||
<WaIcon name="face-laughing" label="Laughing" />
|
||||
</WaRadioButton>
|
||||
</WaRadioGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
@@ -12,21 +12,6 @@ layout: component.njk
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRadio from '@shoelace-style/shoelace/dist/react/radio';
|
||||
import WaRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group';
|
||||
|
||||
const App = () => (
|
||||
<WaRadioGroup label="Select an option" name="a" value="1">
|
||||
<WaRadio value="1">Option 1</WaRadio>
|
||||
<WaRadio value="2">Option 2</WaRadio>
|
||||
<WaRadio value="3">Option 3</WaRadio>
|
||||
</WaRadioGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Help Text
|
||||
@@ -41,21 +26,6 @@ Add descriptive help text to a radio group with the `help-text` attribute. For h
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRadio from '@shoelace-style/shoelace/dist/react/radio';
|
||||
import WaRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group';
|
||||
|
||||
const App = () => (
|
||||
<WaRadioGroup label="Select an option" help-text="Choose the most appropriate option." name="a" value="1">
|
||||
<WaRadio value="1">Option 1</WaRadio>
|
||||
<WaRadio value="2">Option 2</WaRadio>
|
||||
<WaRadio value="3">Option 3</WaRadio>
|
||||
</WaRadioGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Radio Buttons
|
||||
|
||||
[Radio buttons](/components/radio-button) offer an alternate way to display radio controls. In this case, an internal [button group](/components/button-group) is used to group the buttons into a single, cohesive control.
|
||||
@@ -68,21 +38,6 @@ const App = () => (
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRadioButton from '@shoelace-style/shoelace/dist/react/radio-button';
|
||||
import WaRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group';
|
||||
|
||||
const App = () => (
|
||||
<WaRadioGroup label="Select an option" name="a" value="1">
|
||||
<WaRadioButton value="1">Option 1</WaRadioButton>
|
||||
<WaRadioButton value="2">Option 2</WaRadioButton>
|
||||
<WaRadioButton value="3">Option 3</WaRadioButton>
|
||||
</WaRadioGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Disabling Options
|
||||
|
||||
Radios and radio buttons can be disabled by adding the `disabled` attribute to the respective options inside the radio group.
|
||||
@@ -95,23 +50,6 @@ Radios and radio buttons can be disabled by adding the `disabled` attribute to t
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRadio from '@shoelace-style/shoelace/dist/react/radio';
|
||||
import WaRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group';
|
||||
|
||||
const App = () => (
|
||||
<WaRadioGroup label="Select an option" name="a" value="1">
|
||||
<WaRadio value="1">Option 1</WaRadio>
|
||||
<WaRadio value="2" disabled>
|
||||
Option 2
|
||||
</WaRadio>
|
||||
<WaRadio value="3">Option 3</WaRadio>
|
||||
</WaRadioGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Sizing Options
|
||||
|
||||
The size of [Radios](/components/radio) and [Radio Buttons](/components/radio-buttons) will be determined by the Radio Group's `size` attribute.
|
||||
@@ -132,34 +70,6 @@ The size of [Radios](/components/radio) and [Radio Buttons](/components/radio-bu
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx react
|
||||
import { useState } from 'react';
|
||||
import WaRadio from '@shoelace-style/shoelace/dist/react/radio';
|
||||
import WaRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group';
|
||||
|
||||
const App = () => {
|
||||
const [size, setSize] = useState('medium');
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaRadioGroup
|
||||
label="Select an option"
|
||||
size={size}
|
||||
value={size}
|
||||
class="radio-group-size"
|
||||
onWaChange={event => setSize(event.target.value)}
|
||||
>
|
||||
<WaRadio value="small">Small</WaRadio>
|
||||
<WaRadio value="medium">Medium</WaRadio>
|
||||
<WaRadio value="large">Large</WaRadio>
|
||||
</WaRadioGroup>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::info
|
||||
[Radios](/components/radio) and [Radio Buttons](/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.
|
||||
:::
|
||||
@@ -190,41 +100,6 @@ Setting the `required` attribute to make selecting an option mandatory. If a val
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
import WaRadio from '@shoelace-style/shoelace/dist/react/radio';
|
||||
import WaRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group';
|
||||
const App = () => {
|
||||
function handleSubmit(event) {
|
||||
event.preventDefault();
|
||||
alert('All fields are valid!');
|
||||
}
|
||||
|
||||
return (
|
||||
<form class="custom-validity" onSubmit={handleSubmit}>
|
||||
<WaRadioGroup label="Select an option" name="a" required onWaChange={handleChange}>
|
||||
<WaRadio value="1">
|
||||
Option 1
|
||||
</WaRadio>
|
||||
<WaRadiovalue="2">
|
||||
Option 2
|
||||
</WaRadio>
|
||||
<WaRadio value="3">
|
||||
Option 3
|
||||
</WaRadio>
|
||||
</WaRadioGroup>
|
||||
<br />
|
||||
<WaButton type="submit" variant="brand">
|
||||
Submit
|
||||
</WaButton>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Custom Validity
|
||||
|
||||
Use the `setCustomValidity()` method to set a custom validation message. This will prevent the form from submitting and make the browser display the error message you provide. To clear the error, call this function with an empty string.
|
||||
@@ -263,44 +138,3 @@ Use the `setCustomValidity()` method to set a custom validation message. This wi
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useEffect, useRef } from 'react';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
import WaRadio from '@shoelace-style/shoelace/dist/react/radio';
|
||||
import WaRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group';
|
||||
const App = () => {
|
||||
const radioGroup = useRef(null);
|
||||
const errorMessage = 'You must choose this option';
|
||||
|
||||
function handleChange() {
|
||||
radioGroup.current.setCustomValidity(radioGroup.current.value === '3' ? '' : errorMessage);
|
||||
}
|
||||
|
||||
function handleSubmit(event) {
|
||||
event.preventDefault();
|
||||
alert('All fields are valid!');
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
radio.current.setCustomValidity(errorMessage);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<form class="custom-validity" onSubmit={handleSubmit}>
|
||||
<WaRadioGroup ref={radioGroup} label="Select an option" name="a" value="1" onWaChange={handleChange}>
|
||||
<WaRadio value="1">Not me</WaRadio>
|
||||
<WaRadio value="2">Me neither</WaRadio>
|
||||
<WaRadio value="3">Choose me</WaRadio>
|
||||
</WaRadioGroup>
|
||||
<br />
|
||||
<WaButton type="submit" variant="brand">
|
||||
Submit
|
||||
</WaButton>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -14,21 +14,6 @@ Radios are designed to be used with [radio groups](/components/radio-group).
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRadio from '@shoelace-style/shoelace/dist/react/radio';
|
||||
import WaRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group';
|
||||
|
||||
const App = () => (
|
||||
<WaRadioGroup label="Select an option" name="a" value="1">
|
||||
<WaRadio value="1">Option 1</WaRadio><br />
|
||||
<WaRadio value="2">Option 2</WaRadio><br />
|
||||
<WaRadio value="3">Option 3</WaRadio>
|
||||
</WaRadioGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::info
|
||||
This component works with standard `<form>` elements. Please refer to the section on [form controls](/getting-started/form-controls) to learn more about form submission and client-side validation.
|
||||
:::
|
||||
@@ -47,21 +32,6 @@ To set the initial value and checked state, use the `value` attribute on the con
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRadio from '@shoelace-style/shoelace/dist/react/radio';
|
||||
import WaRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group';
|
||||
|
||||
const App = () => (
|
||||
<WaRadioGroup label="Select an option" name="a" value="3">
|
||||
<WaRadio value="1">Option 1</WaRadio><br />
|
||||
<WaRadio value="2">Option 2</WaRadio><br />
|
||||
<WaRadio value="3">Option 3</WaRadio>
|
||||
</WaRadioGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` attribute to disable a radio.
|
||||
@@ -74,21 +44,6 @@ Use the `disabled` attribute to disable a radio.
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRadio from '@shoelace-style/shoelace/dist/react/radio';
|
||||
import WaRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group';
|
||||
|
||||
const App = () => (
|
||||
<WaRadioGroup label="Select an option" name="a" value="1">
|
||||
<WaRadio value="1">Option 1</WaRadio><br />
|
||||
<WaRadio value="2" disabled>Option 2</WaRadio><br />
|
||||
<WaRadio value="3">Option 3</WaRadio>
|
||||
</WaRadioGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Sizes
|
||||
|
||||
Add the `size` attribute to the [Radio Group](/components/radio-group) to change the radios' size.
|
||||
@@ -116,33 +71,3 @@ Add the `size` attribute to the [Radio Group](/components/radio-group) to change
|
||||
<wa-radio value="3">Large 3</wa-radio>
|
||||
</wa-radio-group>
|
||||
```
|
||||
|
||||
```jsx react
|
||||
import WaRadio from '@shoelace-style/shoelace/dist/react/radio';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaRadioGroup size="small" value="1">
|
||||
<WaRadio value="1">Small 1</WaRadio><br />
|
||||
<WaRadio value="2">Small 2</WaRadio><br />
|
||||
<WaRadio value="3">Small 3</WaRadio>
|
||||
</WaRadioGroup>
|
||||
|
||||
<br />
|
||||
|
||||
<WaRadioGroup size="medium" value="1">
|
||||
<WaRadio value="1">Medium 1</WaRadio><br />
|
||||
<WaRadio value="2">Medium 2</WaRadio><br />
|
||||
<WaRadio value="3">Medium 3</WaRadio>
|
||||
</WaRadioGroup>
|
||||
|
||||
<br />
|
||||
|
||||
<WaRadioGroup size="large" value="1">
|
||||
<WaRadio value="1">Large 1</WaRadio><br />
|
||||
<WaRadio value="2">Large 2</WaRadio><br />
|
||||
<WaRadio value="3">Large 3</WaRadio>
|
||||
</WaRadioGroup>
|
||||
</>
|
||||
);
|
||||
```
|
||||
@@ -8,14 +8,6 @@ layout: component.njk
|
||||
<wa-range></wa-range>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRange from '@shoelace-style/shoelace/dist/react/range';
|
||||
|
||||
const App = () => <WaRange />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::info
|
||||
This component works with standard `<form>` elements. Please refer to the section on [form controls](/getting-started/form-controls) to learn more about form submission and client-side validation.
|
||||
:::
|
||||
@@ -30,14 +22,6 @@ Use the `label` attribute to give the range an accessible label. For labels that
|
||||
<wa-range label="Volume" min="0" max="100"></wa-range>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRange from '@shoelace-style/shoelace/dist/react/range';
|
||||
|
||||
const App = () => <WaRange label="Volume" min={0} max={100} />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Help Text
|
||||
|
||||
Add descriptive help text to a range with the `help-text` attribute. For help texts that contain HTML, use the `help-text` slot instead.
|
||||
@@ -46,14 +30,6 @@ Add descriptive help text to a range with the `help-text` attribute. For help te
|
||||
<wa-range label="Volume" help-text="Controls the volume of the current song." min="0" max="100"></wa-range>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRange from '@shoelace-style/shoelace/dist/react/range';
|
||||
|
||||
const App = () => <WaRange label="Volume" help-text="Controls the volume of the current song." min={0} max={100} />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Min, Max, and Step
|
||||
|
||||
Use the `min` and `max` attributes to set the range's minimum and maximum values, respectively. The `step` attribute determines the value's interval when increasing and decreasing.
|
||||
@@ -62,14 +38,6 @@ Use the `min` and `max` attributes to set the range's minimum and maximum values
|
||||
<wa-range min="0" max="10" step="1"></wa-range>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRange from '@shoelace-style/shoelace/dist/react/range';
|
||||
|
||||
const App = () => <WaRange min={0} max={10} step={1} />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` attribute to disable a slider.
|
||||
@@ -78,14 +46,6 @@ Use the `disabled` attribute to disable a slider.
|
||||
<wa-range disabled></wa-range>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRange from '@shoelace-style/shoelace/dist/react/range';
|
||||
|
||||
const App = () => <WaRange disabled />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Tooltip Placement
|
||||
|
||||
By default, the tooltip is shown on top. Set `tooltip` to `bottom` to show it below the slider.
|
||||
@@ -94,14 +54,6 @@ By default, the tooltip is shown on top. Set `tooltip` to `bottom` to show it be
|
||||
<wa-range tooltip="bottom"></wa-range>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRange from '@shoelace-style/shoelace/dist/react/range';
|
||||
|
||||
const App = () => <WaRange tooltip="bottom" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Disable the Tooltip
|
||||
|
||||
To disable the tooltip, set `tooltip` to `none`.
|
||||
@@ -110,14 +62,6 @@ To disable the tooltip, set `tooltip` to `none`.
|
||||
<wa-range tooltip="none"></wa-range>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRange from '@shoelace-style/shoelace/dist/react/range';
|
||||
|
||||
const App = () => <WaRange tooltip="none" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Custom Track Colors
|
||||
|
||||
You can customize the active and inactive portions of the track using the `--track-color-active` and `--track-color-inactive` custom properties.
|
||||
@@ -131,21 +75,6 @@ You can customize the active and inactive portions of the track using the `--tra
|
||||
></wa-range>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRange from '@shoelace-style/shoelace/dist/react/range';
|
||||
|
||||
const App = () => (
|
||||
<WaRange
|
||||
style={{
|
||||
'--track-color-active': 'var(--wa-color-brand-spot)',
|
||||
'--track-color-inactive': 'var(--wa-color-brand-fill-highlight)'
|
||||
}}
|
||||
/>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Custom Track Offset
|
||||
|
||||
You can customize the initial offset of the active track using the `--track-active-offset` custom property.
|
||||
@@ -162,24 +91,6 @@ You can customize the initial offset of the active track using the `--track-acti
|
||||
></wa-range>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRange from '@shoelace-style/shoelace/dist/react/range';
|
||||
|
||||
const App = () => (
|
||||
<WaRange
|
||||
min={-100}
|
||||
max={100}
|
||||
style={{
|
||||
'--track-color-active': 'var(--wa-color-brand-spot)',
|
||||
'--track-color-inactive': 'var(--wa-color-brand-fill-highlight)',
|
||||
'--track-active-offset': '50%'
|
||||
}}
|
||||
/>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Custom Tooltip Formatter
|
||||
|
||||
You can change the tooltip's content by setting the `tooltipFormatter` property to a function that accepts the range's value as an argument.
|
||||
@@ -192,11 +103,3 @@ You can change the tooltip's content by setting the `tooltipFormatter` property
|
||||
range.tooltipFormatter = value => `Total - ${value}%`;
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRange from '@shoelace-style/shoelace/dist/react/range';
|
||||
|
||||
const App = () => <WaRange min={0} max={100} step={1} tooltipFormatter={value => `Total - ${value}%`} />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -8,14 +8,6 @@ layout: component.njk
|
||||
<wa-rating label="Rating"></wa-rating>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRating from '@shoelace-style/shoelace/dist/react/rating';
|
||||
|
||||
const App = () => <WaRating label="Rating" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Labels
|
||||
@@ -26,14 +18,6 @@ Ratings are commonly identified contextually, so labels aren't displayed. Howeve
|
||||
<wa-rating label="Rate this component"></wa-rating>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRating from '@shoelace-style/shoelace/dist/react/rating';
|
||||
|
||||
const App = () => <WaRating label="Rate this component" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Maximum Value
|
||||
|
||||
Ratings are 0-5 by default. To change the maximum possible value, use the `max` attribute.
|
||||
@@ -42,14 +26,6 @@ Ratings are 0-5 by default. To change the maximum possible value, use the `max`
|
||||
<wa-rating label="Rating" max="3"></wa-rating>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRating from '@shoelace-style/shoelace/dist/react/rating';
|
||||
|
||||
const App = () => <WaRating label="Rating" max={3} />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Precision
|
||||
|
||||
Use the `precision` attribute to let users select fractional ratings.
|
||||
@@ -58,14 +34,6 @@ Use the `precision` attribute to let users select fractional ratings.
|
||||
<wa-rating label="Rating" precision="0.5" value="2.5"></wa-rating>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRating from '@shoelace-style/shoelace/dist/react/rating';
|
||||
|
||||
const App = () => <WaRating label="Rating" precision={0.5} value={2.5} />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Symbol Sizes
|
||||
|
||||
Set the `--symbol-size` custom property to adjust the size.
|
||||
@@ -74,14 +42,6 @@ Set the `--symbol-size` custom property to adjust the size.
|
||||
<wa-rating label="Rating" style="--symbol-size: 2rem;"></wa-rating>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRating from '@shoelace-style/shoelace/dist/react/rating';
|
||||
|
||||
const App = () => <WaRating label="Rating" style={{ '--symbol-size': '2rem' }} />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Readonly
|
||||
|
||||
Use the `readonly` attribute to display a rating that users can't change.
|
||||
@@ -90,14 +50,6 @@ Use the `readonly` attribute to display a rating that users can't change.
|
||||
<wa-rating label="Rating" readonly value="3"></wa-rating>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRating from '@shoelace-style/shoelace/dist/react/rating';
|
||||
|
||||
const App = () => <WaRating label="Rating" readonly value={3} />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disable` attribute to disable the rating.
|
||||
@@ -106,14 +58,6 @@ Use the `disable` attribute to disable the rating.
|
||||
<wa-rating label="Rating" disabled value="3"></wa-rating>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRating from '@shoelace-style/shoelace/dist/react/rating';
|
||||
|
||||
const App = () => <WaRating label="Rating" disabled value={3} />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Detecting Hover
|
||||
|
||||
Use the `wa-hover` event to detect when the user hovers over (or touch and drag) the rating. This lets you hook into values as the user interacts with the rating, but before they select a value.
|
||||
@@ -159,56 +103,6 @@ The event has a payload with `phase` and `value` properties. The `phase` propert
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaRating from '@shoelace-style/shoelace/dist/react/rating';
|
||||
|
||||
const terms = ['No rating', 'Terrible', 'Bad', 'OK', 'Good', 'Excellent'];
|
||||
const css = `
|
||||
.detect-hover span {
|
||||
position: relative;
|
||||
top: -4px;
|
||||
left: 8px;
|
||||
border-radius: var(--wa-corners-s);
|
||||
background: var(--wa-color-neutral-spot);
|
||||
color: var(--wa-color-neutral-text-on-spot);
|
||||
text-align: center;
|
||||
padding: 4px 6px;
|
||||
}
|
||||
|
||||
.detect-hover span:empty {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
function handleHover(event) {
|
||||
rating.addEventListener('wa-hover', event => {
|
||||
setFeedback(terms[event.detail.value]);
|
||||
|
||||
// Clear feedback when hovering stops
|
||||
if (event.detail.phase === 'end') {
|
||||
setFeedback('');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const App = () => {
|
||||
const [feedback, setFeedback] = useState(true);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div class="detect-hover">
|
||||
<WaRating label="Rating" onWaHover={handleHover} />
|
||||
<span>{feedback}</span>
|
||||
</div>
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Custom Icons
|
||||
|
||||
You can provide custom icons by passing a function to the `getSymbol` property.
|
||||
@@ -222,20 +116,6 @@ You can provide custom icons by passing a function to the `getSymbol` property.
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRating from '@shoelace-style/shoelace/dist/react/rating';
|
||||
|
||||
const App = () => (
|
||||
<WaRating
|
||||
label="Rating"
|
||||
getSymbol={() => '<wa-icon name="heart" variant="solid"></wa-icon>'}
|
||||
style={{ '--symbol-color-active': '#ff4136' }}
|
||||
/>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Value-based Icons
|
||||
|
||||
You can also use the `getSymbol` property to render different icons based on value.
|
||||
@@ -252,16 +132,3 @@ You can also use the `getSymbol` property to render different icons based on val
|
||||
};
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRating from '@shoelace-style/shoelace/dist/react/rating';
|
||||
|
||||
function getSymbol(value) {
|
||||
const icons = ['face-angry', 'face-frown', 'face-meh', 'face-smile', 'face-laugh'];
|
||||
return `<wa-icon name="${icons[value - 1]}"></wa-icon>`;
|
||||
}
|
||||
|
||||
const App = () => <WaRating label="Rating" getSymbol={getSymbol} />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -11,14 +11,6 @@ Localization is handled by the browser's [`Intl.RelativeTimeFormat` API](https:/
|
||||
<wa-relative-time date="2020-07-15T09:17:00-04:00"></wa-relative-time>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRelativeTime from '@shoelace-style/shoelace/dist/react/relative-time';
|
||||
|
||||
const App = () => <WaRelativeTime date="2020-07-15T09:17:00-04:00" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
The `date` attribute determines when the date/time is calculated from. It must be a string that [`Date.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse) can interpret or a [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object set via JavaScript.
|
||||
|
||||
:::info
|
||||
@@ -44,16 +36,6 @@ Use the `sync` attribute to update the displayed value automatically as time pas
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRelativeTime from '@shoelace-style/shoelace/dist/react/relative-time';
|
||||
|
||||
const date = new Date(new Date().getTime() - 60000);
|
||||
|
||||
const App = () => <WaRelativeTime date={date} sync />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Formatting Styles
|
||||
|
||||
You can change how the time is displayed using the `format` attribute. Note that some locales may display the same values for `narrow` and `short` formats.
|
||||
@@ -64,22 +46,6 @@ You can change how the time is displayed using the `format` attribute. Note that
|
||||
<wa-relative-time date="2020-07-15T09:17:00-04:00" format="long"></wa-relative-time>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRelativeTime from '@shoelace-style/shoelace/dist/react/relative-time';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaRelativeTime date="2020-07-15T09:17:00-04:00" format="narrow" />
|
||||
<br />
|
||||
<WaRelativeTime date="2020-07-15T09:17:00-04:00" format="short" />
|
||||
<br />
|
||||
<WaRelativeTime date="2020-07-15T09:17:00-04:00" format="long" />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Localization
|
||||
|
||||
Use the `lang` attribute to set the desired locale.
|
||||
@@ -91,23 +57,3 @@ German: <wa-relative-time date="2020-07-15T09:17:00-04:00" lang="de"></wa-relati
|
||||
Greek: <wa-relative-time date="2020-07-15T09:17:00-04:00" lang="el"></wa-relative-time><br />
|
||||
Russian: <wa-relative-time date="2020-07-15T09:17:00-04:00" lang="ru"></wa-relative-time>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaRelativeTime from '@shoelace-style/shoelace/dist/react/relative-time';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
English: <WaRelativeTime date="2020-07-15T09:17:00-04:00" lang="en-US" />
|
||||
<br />
|
||||
Chinese: <WaRelativeTime date="2020-07-15T09:17:00-04:00" lang="zh-CN" />
|
||||
<br />
|
||||
German: <WaRelativeTime date="2020-07-15T09:17:00-04:00" lang="de" />
|
||||
<br />
|
||||
Greek: <WaRelativeTime date="2020-07-15T09:17:00-04:00" lang="el" />
|
||||
<br />
|
||||
Russian: <WaRelativeTime date="2020-07-15T09:17:00-04:00" lang="ru" />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -33,32 +33,3 @@ The resize observer will report changes to the dimensions of the elements it wra
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaResizeObserver from '@shoelace-style/shoelace/dist/react/resize-observer';
|
||||
|
||||
const css = `
|
||||
.resize-observer-overview div {
|
||||
display: flex;
|
||||
border: solid 2px var(--wa-color-surface-border);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
padding: 4rem 2rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<div className="resize-observer-overview">
|
||||
<WaResizeObserver onWaResize={event => console.log(event.detail)}>
|
||||
<div>Resize this box and watch the console 👉</div>
|
||||
</WaResizeObserver>
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -15,24 +15,6 @@ layout: component.njk
|
||||
</wa-select>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaOption from '@shoelace-style/shoelace/dist/react/option';
|
||||
import WaSelect from '@shoelace-style/shoelace/dist/react/select';
|
||||
|
||||
const App = () => (
|
||||
<WaSelect>
|
||||
<WaOption value="option-1">Option 1</WaOption>
|
||||
<WaOption value="option-2">Option 2</WaOption>
|
||||
<WaOption value="option-3">Option 3</WaOption>
|
||||
<WaOption value="option-4">Option 4</WaOption>
|
||||
<WaOption value="option-5">Option 5</WaOption>
|
||||
<WaOption value="option-6">Option 6</WaOption>
|
||||
</WaSelect>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::info
|
||||
This component works with standard `<form>` elements. Please refer to the section on [form controls](/getting-started/form-controls) to learn more about form submission and client-side validation.
|
||||
:::
|
||||
@@ -51,21 +33,6 @@ Use the `label` attribute to give the select an accessible label. For labels tha
|
||||
</wa-select>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaOption from '@shoelace-style/shoelace/dist/react/option';
|
||||
import WaSelect from '@shoelace-style/shoelace/dist/react/select';
|
||||
|
||||
const App = () => (
|
||||
<WaSelect label="Select one">
|
||||
<WaOption value="option-1">Option 1</WaOption>
|
||||
<WaOption value="option-2">Option 2</WaOption>
|
||||
<WaOption value="option-3">Option 3</WaOption>
|
||||
</WaSelect>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Help Text
|
||||
|
||||
Add descriptive help text to a select with the `help-text` attribute. For help texts that contain HTML, use the `help-text` slot instead.
|
||||
@@ -78,21 +45,6 @@ Add descriptive help text to a select with the `help-text` attribute. For help t
|
||||
</wa-select>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaOption from '@shoelace-style/shoelace/dist/react/option';
|
||||
import WaSelect from '@shoelace-style/shoelace/dist/react/select';
|
||||
|
||||
const App = () => (
|
||||
<WaSelect label="Experience" help-text="Please tell us your skill level.">
|
||||
<WaOption value="1">Novice</WaOption>
|
||||
<WaOption value="2">Intermediate</WaOption>
|
||||
<WaOption value="3">Advanced</WaOption>
|
||||
</WaSelect>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Placeholders
|
||||
|
||||
Use the `placeholder` attribute to add a placeholder.
|
||||
@@ -105,21 +57,6 @@ Use the `placeholder` attribute to add a placeholder.
|
||||
</wa-select>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaOption from '@shoelace-style/shoelace/dist/react/option';
|
||||
import WaSelect from '@shoelace-style/shoelace/dist/react/select';
|
||||
|
||||
const App = () => (
|
||||
<WaSelect placeholder="Select one">
|
||||
<WaOption value="option-1">Option 1</WaOption>
|
||||
<WaOption value="option-2">Option 2</WaOption>
|
||||
<WaOption value="option-3">Option 3</WaOption>
|
||||
</WaSelect>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Clearable
|
||||
|
||||
Use the `clearable` attribute to make the control clearable. The clear button only appears when an option is selected.
|
||||
@@ -132,21 +69,6 @@ Use the `clearable` attribute to make the control clearable. The clear button on
|
||||
</wa-select>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaOption from '@shoelace-style/shoelace/dist/react/option';
|
||||
import WaSelect from '@shoelace-style/shoelace/dist/react/select';
|
||||
|
||||
const App = () => (
|
||||
<WaSelect placeholder="Clearable" clearable>
|
||||
<WaOption value="option-1">Option 1</WaOption>
|
||||
<WaOption value="option-2">Option 2</WaOption>
|
||||
<WaOption value="option-3">Option 3</WaOption>
|
||||
</WaSelect>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Filled Selects
|
||||
|
||||
Add the `filled` attribute to draw a filled select.
|
||||
@@ -159,21 +81,6 @@ Add the `filled` attribute to draw a filled select.
|
||||
</wa-select>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaOption from '@shoelace-style/shoelace/dist/react/option';
|
||||
import WaSelect from '@shoelace-style/shoelace/dist/react/select';
|
||||
|
||||
const App = () => (
|
||||
<WaSelect filled>
|
||||
<WaOption value="option-1">Option 1</WaOption>
|
||||
<WaOption value="option-2">Option 2</WaOption>
|
||||
<WaOption value="option-3">Option 3</WaOption>
|
||||
</WaSelect>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Pill
|
||||
|
||||
Use the `pill` attribute to give selects rounded edges.
|
||||
@@ -186,21 +93,6 @@ Use the `pill` attribute to give selects rounded edges.
|
||||
</wa-select>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaOption from '@shoelace-style/shoelace/dist/react/option';
|
||||
import WaSelect from '@shoelace-style/shoelace/dist/react/select';
|
||||
|
||||
const App = () => (
|
||||
<WaSelect pill>
|
||||
<WaOption value="option-1">Option 1</WaOption>
|
||||
<WaOption value="option-2">Option 2</WaOption>
|
||||
<WaOption value="option-3">Option 3</WaOption>
|
||||
</WaSelect>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` attribute to disable a select.
|
||||
@@ -213,21 +105,6 @@ Use the `disabled` attribute to disable a select.
|
||||
</wa-select>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaOption from '@shoelace-style/shoelace/dist/react/option';
|
||||
import WaSelect from '@shoelace-style/shoelace/dist/react/select';
|
||||
|
||||
const App = () => (
|
||||
<WaSelect placeholder="Disabled" disabled>
|
||||
<WaOption value="option-1">Option 1</WaOption>
|
||||
<WaOption value="option-2">Option 2</WaOption>
|
||||
<WaOption value="option-3">Option 3</WaOption>
|
||||
</WaSelect>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Multiple
|
||||
|
||||
To allow multiple options to be selected, use the `multiple` attribute. It's a good practice to use `clearable` when this option is enabled. To set multiple values at once, set `value` to a space-delimited list of values.
|
||||
@@ -243,24 +120,6 @@ To allow multiple options to be selected, use the `multiple` attribute. It's a g
|
||||
</wa-select>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaOption from '@shoelace-style/shoelace/dist/react/option';
|
||||
import WaSelect from '@shoelace-style/shoelace/dist/react/select';
|
||||
|
||||
const App = () => (
|
||||
<WaSelect label="Select a Few" value="option-1 option-2 option-3" multiple clearable>
|
||||
<WaOption value="option-1">Option 1</WaOption>
|
||||
<WaOption value="option-2">Option 2</WaOption>
|
||||
<WaOption value="option-3">Option 3</WaOption>
|
||||
<WaOption value="option-4">Option 4</WaOption>
|
||||
<WaOption value="option-5">Option 5</WaOption>
|
||||
<WaOption value="option-6">Option 6</WaOption>
|
||||
</WaSelect>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::info
|
||||
Note that multi-select options may wrap, causing the control to expand vertically. You can use the `max-options-visible` attribute to control the maximum number of selected options to show at once.
|
||||
:::
|
||||
@@ -280,22 +139,6 @@ When using `multiple`, the `value` _attribute_ uses space-delimited values to se
|
||||
</wa-select>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaDivider from '@shoelace-style/shoelace/dist/react/divider';
|
||||
import WaOption from '@shoelace-style/shoelace/dist/react/option';
|
||||
import WaSelect from '@shoelace-style/shoelace/dist/react/select';
|
||||
|
||||
const App = () => (
|
||||
<WaSelect value="option-1 option-2" multiple clearable>
|
||||
<WaOption value="option-1">Option 1</WaOption>
|
||||
<WaOption value="option-2">Option 2</WaOption>
|
||||
<WaOption value="option-3">Option 3</WaOption>
|
||||
</WaSelect>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Grouping Options
|
||||
|
||||
Use `<wa-divider>` to group listbox items visually. You can also use `<small>` to provide labels, but they won't be announced by most assistive devices.
|
||||
@@ -314,24 +157,6 @@ Use `<wa-divider>` to group listbox items visually. You can also use `<small>` t
|
||||
</wa-select>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaOption from '@shoelace-style/shoelace/dist/react/option';
|
||||
import WaSelect from '@shoelace-style/shoelace/dist/react/select';
|
||||
|
||||
const App = () => (
|
||||
<WaSelect>
|
||||
<WaOption value="option-1">Option 1</WaOption>
|
||||
<WaOption value="option-2">Option 2</WaOption>
|
||||
<WaOption value="option-3">Option 3</WaOption>
|
||||
<WaOption value="option-4">Option 4</WaOption>
|
||||
<WaOption value="option-5">Option 5</WaOption>
|
||||
<WaOption value="option-6">Option 6</WaOption>
|
||||
</WaSelect>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Sizes
|
||||
|
||||
Use the `size` attribute to change a select's size. Note that size does not apply to listbox options.
|
||||
@@ -360,39 +185,6 @@ Use the `size` attribute to change a select's size. Note that size does not appl
|
||||
</wa-select>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaOption from '@shoelace-style/shoelace/dist/react/option';
|
||||
import WaSelect from '@shoelace-style/shoelace/dist/react/select';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaSelect placeholder="Small" size="small">
|
||||
<WaOption value="option-1">Option 1</WaOption>
|
||||
<WaOption value="option-2">Option 2</WaOption>
|
||||
<WaOption value="option-3">Option 3</WaOption>
|
||||
</WaSelect>
|
||||
|
||||
<br />
|
||||
|
||||
<WaSelect placeholder="Medium" size="medium">
|
||||
<WaOption value="option-1">Option 1</WaOption>
|
||||
<WaOption value="option-2">Option 2</WaOption>
|
||||
<WaOption value="option-3">Option 3</WaOption>
|
||||
</WaSelect>
|
||||
|
||||
<br />
|
||||
|
||||
<WaSelect placeholder="Large" size="large">
|
||||
<WaOption value="option-1">Option 1</WaOption>
|
||||
<WaOption value="option-2">Option 2</WaOption>
|
||||
<WaOption value="option-3">Option 3</WaOption>
|
||||
</WaSelect>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Placement
|
||||
|
||||
The preferred placement of the select's listbox can be set with the `placement` attribute. Note that the actual position may vary to ensure the panel remains in the viewport. Valid placements are `top` and `bottom`.
|
||||
@@ -405,21 +197,6 @@ The preferred placement of the select's listbox can be set with the `placement`
|
||||
</wa-select>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaOption from '@shoelace-style/shoelace/dist/react/option';
|
||||
import WaSelect from '@shoelace-style/shoelace/dist/react/select';
|
||||
|
||||
const App = () => (
|
||||
<WaSelect placement="top">
|
||||
<WaOption value="option-1">Option 1</WaOption>
|
||||
<WaOption value="option-2">Option 2</WaOption>
|
||||
<WaOption value="option-3">Option 3</WaOption>
|
||||
</WaDropdown>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Prefix Icons
|
||||
|
||||
Use the `prefix` slot to prepend an icon to the control.
|
||||
@@ -447,39 +224,6 @@ Use the `prefix` slot to prepend an icon to the control.
|
||||
</wa-select>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
import WaOption from '@shoelace-style/shoelace/dist/react/option';
|
||||
import WaSelect from '@shoelace-style/shoelace/dist/react/select';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaSelect placeholder="Small" size="small">
|
||||
<WaIcon slot="prefix" name="house" variant="solid"></WaIcon>
|
||||
<WaOption value="option-1">Option 1</WaOption>
|
||||
<WaOption value="option-2">Option 2</WaOption>
|
||||
<WaOption value="option-3">Option 3</WaOption>
|
||||
</WaSelect>
|
||||
<br />
|
||||
<WaSelect placeholder="Medium" size="medium">
|
||||
<WaIcon slot="prefix" name="house" variant="solid"></WaIcon>
|
||||
<WaOption value="option-1">Option 1</WaOption>
|
||||
<WaOption value="option-2">Option 2</WaOption>
|
||||
<WaOption value="option-3">Option 3</WaOption>
|
||||
</WaSelect>
|
||||
<br />
|
||||
<WaSelect placeholder="Large" size="large">
|
||||
<WaIcon slot="prefix" name="house" variant="solid"></WaIcon>
|
||||
<WaOption value="option-1">Option 1</WaOption>
|
||||
<WaOption value="option-2">Option 2</WaOption>
|
||||
<WaOption value="option-3">Option 3</WaOption>
|
||||
</WaSelect>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Custom Tags
|
||||
|
||||
When multiple options can be selected, you can provide custom tags by passing a function to the `getTag` property. Your function can return a string of HTML, a <a href="https://lit.dev/docs/templates/overview/">Lit Template</a>, or an [`HTMLElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement). The `getTag()` function will be called for each option. The first argument is an `<wa-option>` element and the second argument is the tag's index (its position in the tag list).
|
||||
|
||||
@@ -54,62 +54,6 @@ Skeletons try not to be opinionated, as there are endless possibilities for desi
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSkeleton from '@shoelace-style/shoelace/dist/react/skeleton';
|
||||
|
||||
const css = `
|
||||
.skeleton-overview header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.skeleton-overview header wa-skeleton:last-child {
|
||||
flex: 0 0 auto;
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.skeleton-overview wa-skeleton {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.skeleton-overview wa-skeleton:nth-child(1) {
|
||||
float: left;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
margin-right: 1rem;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.skeleton-overview wa-skeleton:nth-child(3) {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
.skeleton-overview wa-skeleton:nth-child(4) {
|
||||
width: 80%;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<div className="skeleton-overview">
|
||||
<header>
|
||||
<WaSkeleton />
|
||||
<WaSkeleton />
|
||||
</header>
|
||||
|
||||
<WaSkeleton />
|
||||
<WaSkeleton />
|
||||
<WaSkeleton />
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Effects
|
||||
@@ -139,37 +83,6 @@ There are two built-in effects, `sheen` and `pulse`. Effects are intentionally s
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSkeleton from '@shoelace-style/shoelace/dist/react/skeleton';
|
||||
|
||||
const css = `
|
||||
.skeleton-effects {
|
||||
font-size: var(--wa-font-size-s);
|
||||
}
|
||||
|
||||
.skeleton-effects wa-skeleton:not(:first-child) {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<div className="skeleton-effects">
|
||||
<WaSkeleton effect="none" />
|
||||
None
|
||||
<WaSkeleton effect="sheen" />
|
||||
Sheen
|
||||
<WaSkeleton effect="pulse" />
|
||||
Pulse
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Paragraphs
|
||||
|
||||
Use multiple skeletons and some clever styles to simulate paragraphs.
|
||||
@@ -202,44 +115,6 @@ Use multiple skeletons and some clever styles to simulate paragraphs.
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSkeleton from '@shoelace-style/shoelace/dist/react/skeleton';
|
||||
|
||||
const css = `
|
||||
.skeleton-paragraphs wa-skeleton {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.skeleton-paragraphs wa-skeleton:nth-child(2) {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
.skeleton-paragraphs wa-skeleton:nth-child(4) {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.skeleton-paragraphs wa-skeleton:last-child {
|
||||
width: 50%;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<div className="skeleton-paragraphs">
|
||||
<WaSkeleton />
|
||||
<WaSkeleton />
|
||||
<WaSkeleton />
|
||||
<WaSkeleton />
|
||||
<WaSkeleton />
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Avatars
|
||||
|
||||
Set a matching width and height to make a circle, square, or rounded avatar skeleton.
|
||||
@@ -269,41 +144,6 @@ Set a matching width and height to make a circle, square, or rounded avatar skel
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSkeleton from '@shoelace-style/shoelace/dist/react/skeleton';
|
||||
|
||||
const css = `
|
||||
.skeleton-avatars wa-skeleton {
|
||||
display: inline-block;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
margin-right: .5rem;
|
||||
}
|
||||
|
||||
.skeleton-avatars wa-skeleton:nth-child(1) {
|
||||
--border-radius: 0;
|
||||
}
|
||||
|
||||
.skeleton-avatars wa-skeleton:nth-child(2) {
|
||||
--border-radius: var(--wa-corners-s);
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<div className="skeleton-avatars">
|
||||
<WaSkeleton />
|
||||
<WaSkeleton />
|
||||
<WaSkeleton />
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Custom Shapes
|
||||
|
||||
Use the `--border-radius` custom property to make circles, squares, and rectangles. For more complex shapes, you can apply `clip-path` to the `indicator` part. [Try Clippy](https://bennettfeely.com/clippy/) if you need help generating custom shapes.
|
||||
@@ -366,61 +206,6 @@ Use the `--border-radius` custom property to make circles, squares, and rectangl
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSkeleton from '@shoelace-style/shoelace/dist/react/skeleton';
|
||||
|
||||
const css = `
|
||||
.skeleton-shapes wa-skeleton {
|
||||
display: inline-flex;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.skeleton-shapes .square::part(indicator) {
|
||||
--border-radius: var(--wa-corners-s);
|
||||
}
|
||||
|
||||
.skeleton-shapes .circle::part(indicator) {
|
||||
--border-radius: var(--wa-corners-circle);
|
||||
}
|
||||
|
||||
.skeleton-shapes .triangle::part(indicator) {
|
||||
--border-radius: 0;
|
||||
clip-path: polygon(50% 0, 0 100%, 100% 100%);
|
||||
}
|
||||
|
||||
.skeleton-shapes .cross::part(indicator) {
|
||||
--border-radius: 0;
|
||||
clip-path: polygon(20% 0%, 0% 20%, 30% 50%, 0% 80%, 20% 100%, 50% 70%, 80% 100%, 100% 80%, 70% 50%, 100% 20%, 80% 0%, 50% 30%);
|
||||
}
|
||||
|
||||
.skeleton-shapes .comment::part(indicator) {
|
||||
--border-radius: 0;
|
||||
clip-path: polygon(0% 0%, 100% 0%, 100% 75%, 75% 75%, 75% 100%, 50% 75%, 0% 75%);
|
||||
}
|
||||
|
||||
.skeleton-shapes wa-skeleton:not(:last-child) {
|
||||
margin-right: .5rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<div className="skeleton-shapes">
|
||||
<WaSkeleton className="square" />
|
||||
<WaSkeleton className="circle" />
|
||||
<WaSkeleton className="triangle" />
|
||||
<WaSkeleton className="cross" />
|
||||
<WaSkeleton className="comment" />
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Custom Colors
|
||||
|
||||
Set the `--color` and `--sheen-color` custom properties to adjust the skeleton's color.
|
||||
@@ -428,28 +213,3 @@ Set the `--color` and `--sheen-color` custom properties to adjust the skeleton's
|
||||
```html {.example}
|
||||
<wa-skeleton effect="sheen" style="--color: tomato; --sheen-color: #ffb094;"></wa-skeleton>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSkeleton from '@shoelace-style/shoelace/dist/react/skeleton';
|
||||
|
||||
const css = `
|
||||
.skeleton-avatars wa-skeleton {
|
||||
display: inline-block;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
margin-right: .5rem;
|
||||
}
|
||||
|
||||
.skeleton-avatars wa-skeleton:nth-child(1) {
|
||||
--border-radius: 0;
|
||||
}
|
||||
|
||||
.skeleton-avatars wa-skeleton:nth-child(2) {
|
||||
--border-radius: var(--wa-corners-s);
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => <WaSkeleton effect="sheen" style={{ '--color': 'tomato', '--sheen-color': '#ffb094' }} />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -8,14 +8,6 @@ layout: component.njk
|
||||
<wa-spinner></wa-spinner>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSpinner from '@shoelace-style/shoelace/dist/react/spinner';
|
||||
|
||||
const App = () => <WaSpinner />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Size
|
||||
@@ -28,20 +20,6 @@ Spinners are sized based on the current font size. To change their size, set the
|
||||
<wa-spinner style="font-size: 3rem;"></wa-spinner>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSpinner from '@shoelace-style/shoelace/dist/react/spinner';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaSpinner />
|
||||
<WaSpinner style={{ fontSize: '2rem' }} />
|
||||
<WaSpinner style={{ fontSize: '3rem' }} />
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Track Width
|
||||
|
||||
The width of the spinner's track can be changed by setting the `--track-width` custom property.
|
||||
@@ -50,21 +28,6 @@ The width of the spinner's track can be changed by setting the `--track-width` c
|
||||
<wa-spinner style="font-size: 50px; --track-width: 10px;"></wa-spinner>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSpinner from '@shoelace-style/shoelace/dist/react/spinner';
|
||||
|
||||
const App = () => (
|
||||
<WaSpinner
|
||||
style={{
|
||||
fontSize: '3rem',
|
||||
'--track-width': '6px'
|
||||
}}
|
||||
/>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Color
|
||||
|
||||
The spinner's colors can be changed by setting the `--indicator-color` and `--track-color` custom properties.
|
||||
@@ -72,19 +35,3 @@ The spinner's colors can be changed by setting the `--indicator-color` and `--tr
|
||||
```html {.example}
|
||||
<wa-spinner style="font-size: 3rem; --indicator-color: deeppink; --track-color: pink;"></wa-spinner>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSpinner from '@shoelace-style/shoelace/dist/react/spinner';
|
||||
|
||||
const App = () => (
|
||||
<WaSpinner
|
||||
style={{
|
||||
fontSize: '3rem',
|
||||
'--indicator-color': 'deeppink',
|
||||
'--track-color': 'pink'
|
||||
}}
|
||||
/>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -21,41 +21,6 @@ layout: component.njk
|
||||
</wa-split-panel>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSplitPanel from '@shoelace-style/shoelace/dist/react/split-panel';
|
||||
|
||||
const App = () => (
|
||||
<WaSplitPanel>
|
||||
<div
|
||||
slot="start"
|
||||
style={{
|
||||
height: '200px',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
Start
|
||||
</div>
|
||||
<div
|
||||
slot="end"
|
||||
style={{
|
||||
height: '200px',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
End
|
||||
</div>
|
||||
</WaSplitPanel>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Initial Position
|
||||
@@ -114,41 +79,6 @@ To set the initial position in pixels instead of a percentage, use the `position
|
||||
</wa-split-panel>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSplitPanel from '@shoelace-style/shoelace/dist/react/split-panel';
|
||||
|
||||
const App = () => (
|
||||
<WaSplitPanel position="200">
|
||||
<div
|
||||
slot="start"
|
||||
style={{
|
||||
height: '200px',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
Start
|
||||
</div>
|
||||
<div
|
||||
slot="end"
|
||||
style={{
|
||||
height: '200px',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
End
|
||||
</div>
|
||||
</WaSplitPanel>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Vertical
|
||||
|
||||
Add the `vertical` attribute to render the split panel in a vertical orientation where the start and end panels are stacked. You also need to set a height when using the vertical orientation.
|
||||
@@ -170,41 +100,6 @@ Add the `vertical` attribute to render the split panel in a vertical orientation
|
||||
</wa-split-panel>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSplitPanel from '@shoelace-style/shoelace/dist/react/split-panel';
|
||||
|
||||
const App = () => (
|
||||
<WaSplitPanel vertical style={{ height: '400px' }}>
|
||||
<div
|
||||
slot="start"
|
||||
style={{
|
||||
height: '100%',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
Start
|
||||
</div>
|
||||
<div
|
||||
slot="end"
|
||||
style={{
|
||||
height: '100%',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
End
|
||||
</div>
|
||||
</WaSplitPanel>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Snapping
|
||||
|
||||
To snap panels at specific positions while dragging, add the `snap` attribute with one or more space-separated values. Values must be in pixels or percentages. For example, to snap the panel at `100px` and `50%`, use `snap="100px 50%"`. You can also customize how close the divider must be before snapping with the `snap-threshold` attribute.
|
||||
@@ -256,75 +151,6 @@ To snap panels at specific positions while dragging, add the `snap` attribute wi
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSplitPanel from '@shoelace-style/shoelace/dist/react/split-panel';
|
||||
|
||||
const css = `
|
||||
.split-panel-snapping {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.split-panel-snapping-dots::before,
|
||||
.split-panel-snapping-dots::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -12px;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--wa-color-neutral-spot);
|
||||
transform: translateX(-3px);
|
||||
}
|
||||
|
||||
.split-panel-snapping-dots::before {
|
||||
left: 100px;
|
||||
}
|
||||
|
||||
.split-panel-snapping-dots::after {
|
||||
left: 50%;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<div className="split-panel-snapping">
|
||||
<WaSplitPanel snap="100px 50%">
|
||||
<div
|
||||
slot="start"
|
||||
style={{
|
||||
height: '200px',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
Start
|
||||
</div>
|
||||
<div
|
||||
slot="end"
|
||||
style={{
|
||||
height: '200px',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
End
|
||||
</div>
|
||||
</WaSplitPanel>
|
||||
|
||||
<div className="split-panel-snapping-dots" />
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Disabled
|
||||
|
||||
Add the `disabled` attribute to prevent the divider from being repositioned.
|
||||
@@ -346,41 +172,6 @@ Add the `disabled` attribute to prevent the divider from being repositioned.
|
||||
</wa-split-panel>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSplitPanel from '@shoelace-style/shoelace/dist/react/split-panel';
|
||||
|
||||
const App = () => (
|
||||
<WaSplitPanel disabled>
|
||||
<div
|
||||
slot="start"
|
||||
style={{
|
||||
height: '200px',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
Start
|
||||
</div>
|
||||
<div
|
||||
slot="end"
|
||||
style={{
|
||||
height: '200px',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
End
|
||||
</div>
|
||||
</WaSplitPanel>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Setting the Primary Panel
|
||||
|
||||
By default, both panels will grow or shrink proportionally when the host element is resized. If a primary panel is designated, it will maintain its size and the secondary panel will grow or shrink to fit the remaining space. You can set the primary panel to `start` or `end` using the `primary` attribute.
|
||||
@@ -420,61 +211,6 @@ Try resizing the example below with each option and notice how the panels respon
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaSplitPanel from '@shoelace-style/shoelace/dist/react/split-panel';
|
||||
import WaSelect from '@shoelace-style/shoelace/dist/react/select';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => {
|
||||
const [primary, setPrimary] = useState('');
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaSplitPanel primary={primary}>
|
||||
<div
|
||||
slot="start"
|
||||
style={{
|
||||
height: '200px',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
Start
|
||||
</div>
|
||||
<div
|
||||
slot="end"
|
||||
style={{
|
||||
height: '200px',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
End
|
||||
</div>
|
||||
</WaSplitPanel>
|
||||
|
||||
<WaSelect
|
||||
label="Primary Panel"
|
||||
value={primary}
|
||||
style={{ maxWidth: '200px', marginTop: '1rem' }}
|
||||
onWaChange={event => setPrimary(event.target.value)}
|
||||
>
|
||||
<WaMenuItem value="">None</WaMenuItem>
|
||||
<WaMenuItem value="start">Start</WaMenuItem>
|
||||
<WaMenuItem value="end">End</WaMenuItem>
|
||||
</WaSelect>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Min & Max
|
||||
|
||||
To set a minimum or maximum size of the primary panel, use the `--min` and `--max` custom properties. Since the secondary panel is flexible, size constraints can only be applied to the primary panel. If no primary panel is designated, these constraints will be applied to the `start` panel.
|
||||
@@ -498,41 +234,6 @@ This examples demonstrates how you can ensure both panels are at least 150px usi
|
||||
</wa-split-panel>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSplitPanel from '@shoelace-style/shoelace/dist/react/split-panel';
|
||||
|
||||
const App = () => (
|
||||
<WaSplitPanel style={{ '--min': '150px', '--max': 'calc(100% - 150px)' }}>
|
||||
<div
|
||||
slot="start"
|
||||
style={{
|
||||
height: '200px',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
Start
|
||||
</div>
|
||||
<div
|
||||
slot="end"
|
||||
style={{
|
||||
height: '200px',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
End
|
||||
</div>
|
||||
</WaSplitPanel>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Nested Split Panels
|
||||
|
||||
Create complex layouts that can be repositioned independently by nesting split panels.
|
||||
@@ -564,57 +265,6 @@ Create complex layouts that can be repositioned independently by nesting split p
|
||||
</wa-split-panel>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSplitPanel from '@shoelace-style/shoelace/dist/react/split-panel';
|
||||
|
||||
const App = () => (
|
||||
<WaSplitPanel>
|
||||
<div
|
||||
slot="start"
|
||||
style={{
|
||||
height: '400px',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
Start
|
||||
</div>
|
||||
<div slot="end">
|
||||
<WaSplitPanel vertical style={{ height: '400px' }}>
|
||||
<div
|
||||
slot="start"
|
||||
style={{
|
||||
height: '100%',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
Start
|
||||
</div>
|
||||
<div
|
||||
slot="end"
|
||||
style={{
|
||||
height: '100%',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
End
|
||||
</div>
|
||||
</WaSplitPanel>
|
||||
</div>
|
||||
</WaSplitPanel>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Customizing the Divider
|
||||
|
||||
You can target the `divider` part to apply CSS properties to the divider. To add a custom handle, slot an icon into the `divider` slot. When customizing the divider, make sure to think about focus styles for keyboard users.
|
||||
@@ -651,43 +301,6 @@ You can target the `divider` part to apply CSS properties to the divider. To add
|
||||
</wa-split-panel>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSplitPanel from '@shoelace-style/shoelace/dist/react/split-panel';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
|
||||
const App = () => (
|
||||
<WaSplitPanel style={{ '--divider-width': '20px' }}>
|
||||
<WaIcon slot="divider" name="grip-vertical" variant="solid" />
|
||||
<div
|
||||
slot="start"
|
||||
style={{
|
||||
height: '200px',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
Start
|
||||
</div>
|
||||
<div
|
||||
slot="end"
|
||||
style={{
|
||||
height: '200px',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
End
|
||||
</div>
|
||||
</WaSplitPanel>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
Here's a more elaborate example that changes the divider's color and width and adds a styled handle.
|
||||
|
||||
```html {.example}
|
||||
@@ -750,73 +363,3 @@ Here's a more elaborate example that changes the divider's color and width and a
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSplitPanel from '@shoelace-style/shoelace/dist/react/split-panel';
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
|
||||
const css = `
|
||||
.split-panel-divider wa-split-panel {
|
||||
--divider-width: 4px;
|
||||
}
|
||||
|
||||
.split-panel-divider wa-split-panel::part(divider) {
|
||||
background-color: var(--wa-color-red-50);
|
||||
}
|
||||
|
||||
.split-panel-divider wa-icon {
|
||||
position: absolute;
|
||||
border-radius: var(--wa-corners-xs);
|
||||
background: var(--wa-color-red-50);
|
||||
color: white;
|
||||
padding: .5rem .25rem;
|
||||
}
|
||||
|
||||
.split-panel-divider wa-split-panel::part(divider):focus-visible {
|
||||
background-color: var(--wa-color-blue-50);
|
||||
}
|
||||
|
||||
.split-panel-divider wa-split-panel:focus-within wa-icon {
|
||||
background-color: var(--wa-color-blue-50);
|
||||
color: white;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<div className="split-panel-divider">
|
||||
<WaSplitPanel>
|
||||
<WaIcon slot="divider" name="grip-vertical" variant="solid" />
|
||||
<div
|
||||
slot="start"
|
||||
style={{
|
||||
height: '200px',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
Start
|
||||
</div>
|
||||
<div
|
||||
slot="end"
|
||||
style={{
|
||||
height: '200px',
|
||||
background: 'var(--wa-color-surface-lowered)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
End
|
||||
</div>
|
||||
</WaSplitPanel>
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -8,14 +8,6 @@ layout: component.njk
|
||||
<wa-switch>Switch</wa-switch>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSwitch from '@shoelace-style/shoelace/dist/react/switch';
|
||||
|
||||
const App = () => <WaSwitch>Switch</WaSwitch>;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::info
|
||||
This component works with standard `<form>` elements. Please refer to the section on [form controls](/getting-started/form-controls) to learn more about form submission and client-side validation.
|
||||
:::
|
||||
@@ -30,14 +22,6 @@ Use the `checked` attribute to activate the switch.
|
||||
<wa-switch checked>Checked</wa-switch>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSwitch from '@shoelace-style/shoelace/dist/react/switch';
|
||||
|
||||
const App = () => <WaSwitch checked>Checked</WaSwitch>;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` attribute to disable the switch.
|
||||
@@ -46,14 +30,6 @@ Use the `disabled` attribute to disable the switch.
|
||||
<wa-switch disabled>Disabled</wa-switch>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSwitch from '@shoelace-style/shoelace/dist/react/switch';
|
||||
|
||||
const App = () => <WaSwitch disabled>Disabled</WaSwitch>;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Sizes
|
||||
|
||||
Use the `size` attribute to change a switch's size.
|
||||
@@ -66,22 +42,6 @@ Use the `size` attribute to change a switch's size.
|
||||
<wa-switch size="large">Large</wa-switch>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSwitch from '@shoelace-style/shoelace/dist/react/switch';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaSwitch size="small">Small</WaSwitch>
|
||||
<br />
|
||||
<WaSwitch size="medium">Medium</WaSwitch>
|
||||
<br />
|
||||
<WaSwitch size="large">Large</WaSwitch>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Help Text
|
||||
|
||||
Add descriptive help text to a switch with the `help-text` attribute. For help texts that contain HTML, use the `help-text` slot instead.
|
||||
@@ -90,14 +50,6 @@ Add descriptive help text to a switch with the `help-text` attribute. For help t
|
||||
<wa-switch help-text="What should the user know about the switch?">Label</wa-switch>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSwitch from '@shoelace-style/shoelace/dist/react/checkbox';
|
||||
|
||||
const App = () => <WaSwitch help-text="What should the user know about the switch?">Label</WaSwitch>;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Custom Styles
|
||||
|
||||
Use the available custom properties to change how the switch is styled.
|
||||
@@ -105,19 +57,3 @@ Use the available custom properties to change how the switch is styled.
|
||||
```html {.example}
|
||||
<wa-switch style="--width: 80px; --height: 40px; --thumb-size: 36px;">Really big</wa-switch>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaSwitch from '@shoelace-style/shoelace/dist/react/switch';
|
||||
|
||||
const App = () => (
|
||||
<WaSwitch
|
||||
style={{
|
||||
'--width': '80px',
|
||||
'--height': '32px',
|
||||
'--thumb-size': '26px'
|
||||
}}
|
||||
/>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
@@ -20,36 +20,6 @@ Tab groups make use of [tabs](/components/tab) and [tab panels](/components/tab-
|
||||
</wa-tab-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTab from '@shoelace-style/shoelace/dist/react/tab';
|
||||
import WaTabGroup from '@shoelace-style/shoelace/dist/react/tab-group';
|
||||
import WaTabPanel from '@shoelace-style/shoelace/dist/react/tab-panel';
|
||||
|
||||
const App = () => (
|
||||
<WaTabGroup>
|
||||
<WaTab slot="nav" panel="general">
|
||||
General
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="custom">
|
||||
Custom
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="advanced">
|
||||
Advanced
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="disabled" disabled>
|
||||
Disabled
|
||||
</WaTab>
|
||||
|
||||
<WaTabPanel name="general">This is the general tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="custom">This is the custom tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="advanced">This is the advanced tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="disabled">This is a disabled tab panel.</WaTabPanel>
|
||||
</WaTabGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Setting the Active Tab
|
||||
@@ -86,36 +56,6 @@ Tabs can be shown on the bottom by setting `placement` to `bottom`.
|
||||
</wa-tab-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTab from '@shoelace-style/shoelace/dist/react/tab';
|
||||
import WaTabGroup from '@shoelace-style/shoelace/dist/react/tab-group';
|
||||
import WaTabPanel from '@shoelace-style/shoelace/dist/react/tab-panel';
|
||||
|
||||
const App = () => (
|
||||
<WaTabGroup placement="bottom">
|
||||
<WaTab slot="nav" panel="general">
|
||||
General
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="custom">
|
||||
Custom
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="advanced">
|
||||
Advanced
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="disabled" disabled>
|
||||
Disabled
|
||||
</WaTab>
|
||||
|
||||
<WaTabPanel name="general">This is the general tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="custom">This is the custom tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="advanced">This is the advanced tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="disabled">This is a disabled tab panel.</WaTabPanel>
|
||||
</WaTabGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Tabs on Start
|
||||
|
||||
Tabs can be shown on the starting side by setting `placement` to `start`.
|
||||
@@ -134,36 +74,6 @@ Tabs can be shown on the starting side by setting `placement` to `start`.
|
||||
</wa-tab-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTab from '@shoelace-style/shoelace/dist/react/tab';
|
||||
import WaTabGroup from '@shoelace-style/shoelace/dist/react/tab-group';
|
||||
import WaTabPanel from '@shoelace-style/shoelace/dist/react/tab-panel';
|
||||
|
||||
const App = () => (
|
||||
<WaTabGroup placement="start">
|
||||
<WaTab slot="nav" panel="general">
|
||||
General
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="custom">
|
||||
Custom
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="advanced">
|
||||
Advanced
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="disabled" disabled>
|
||||
Disabled
|
||||
</WaTab>
|
||||
|
||||
<WaTabPanel name="general">This is the general tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="custom">This is the custom tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="advanced">This is the advanced tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="disabled">This is a disabled tab panel.</WaTabPanel>
|
||||
</WaTabGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Tabs on End
|
||||
|
||||
Tabs can be shown on the ending side by setting `placement` to `end`.
|
||||
@@ -182,36 +92,6 @@ Tabs can be shown on the ending side by setting `placement` to `end`.
|
||||
</wa-tab-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTab from '@shoelace-style/shoelace/dist/react/tab';
|
||||
import WaTabGroup from '@shoelace-style/shoelace/dist/react/tab-group';
|
||||
import WaTabPanel from '@shoelace-style/shoelace/dist/react/tab-panel';
|
||||
|
||||
const App = () => (
|
||||
<WaTabGroup placement="end">
|
||||
<WaTab slot="nav" panel="general">
|
||||
General
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="custom">
|
||||
Custom
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="advanced">
|
||||
Advanced
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="disabled" disabled>
|
||||
Disabled
|
||||
</WaTab>
|
||||
|
||||
<WaTabPanel name="general">This is the general tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="custom">This is the custom tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="advanced">This is the advanced tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="disabled">This is a disabled tab panel.</WaTabPanel>
|
||||
</WaTabGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Closable Tabs
|
||||
|
||||
You can make a tab closable by adding a close button next to the tab and inside the `nav` slot. You can position the button to your liking with CSS and handle close/restore behaviors by removing/appending the tab as desired. Note the use of `tabindex="-1"`, which prevents the close button from interfering with the tab order. The close button is still recognizable to the virtual cursor in screen readers.
|
||||
@@ -262,52 +142,6 @@ You can make a tab closable by adding a close button next to the tab and inside
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTab from '@shoelace-style/shoelace/dist/react/tab';
|
||||
import WaTabGroup from '@shoelace-style/shoelace/dist/react/tab-group';
|
||||
import WaTabPanel from '@shoelace-style/shoelace/dist/react/tab-panel';
|
||||
|
||||
const App = () => {
|
||||
function handleClose(event) {
|
||||
//
|
||||
// This is a crude example that removes the tab and its panel from the DOM.
|
||||
// There are better ways to manage tab creation/removal in React, but that
|
||||
// would significantly complicate the example.
|
||||
//
|
||||
const tab = event.target;
|
||||
const tabGroup = tab.closest('wa-tab-group');
|
||||
const tabPanel = tabGroup.querySelector(`[aria-labelledby="${tab.id}"]`);
|
||||
|
||||
tab.remove();
|
||||
tabPanel.remove();
|
||||
}
|
||||
|
||||
return (
|
||||
<WaTabGroup className="tabs-closable" onWaClose={handleClose}>
|
||||
<WaTab slot="nav" panel="general">
|
||||
General
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="closable-1" closable onWaClose={handleClose}>
|
||||
Closable 1
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="closable-2" closable onWaClose={handleClose}>
|
||||
Closable 2
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="closable-3" closable onWaClose={handleClose}>
|
||||
Closable 3
|
||||
</WaTab>
|
||||
|
||||
<WaTabPanel name="general">This is the general tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="closable-1">This is the first closable tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="closable-2">This is the second closable tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="closable-3">This is the third closable tab panel.</WaTabPanel>
|
||||
</WaTabGroup>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Scrolling Tabs
|
||||
|
||||
When there are more tabs than horizontal space allows, the nav will be scrollable.
|
||||
@@ -358,100 +192,6 @@ When there are more tabs than horizontal space allows, the nav will be scrollabl
|
||||
</wa-tab-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTab from '@shoelace-style/shoelace/dist/react/tab';
|
||||
import WaTabGroup from '@shoelace-style/shoelace/dist/react/tab-group';
|
||||
import WaTabPanel from '@shoelace-style/shoelace/dist/react/tab-panel';
|
||||
|
||||
const App = () => (
|
||||
<WaTabGroup>
|
||||
<WaTab slot="nav" panel="tab-1">
|
||||
Tab 1
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="tab-2">
|
||||
Tab 2
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="tab-3">
|
||||
Tab 3
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="tab-4">
|
||||
Tab 4
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="tab-5">
|
||||
Tab 5
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="tab-6">
|
||||
Tab 6
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="tab-7">
|
||||
Tab 7
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="tab-8">
|
||||
Tab 8
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="tab-9">
|
||||
Tab 9
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="tab-10">
|
||||
Tab 10
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="tab-11">
|
||||
Tab 11
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="tab-12">
|
||||
Tab 12
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="tab-13">
|
||||
Tab 13
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="tab-14">
|
||||
Tab 14
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="tab-15">
|
||||
Tab 15
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="tab-16">
|
||||
Tab 16
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="tab-17">
|
||||
Tab 17
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="tab-18">
|
||||
Tab 18
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="tab-19">
|
||||
Tab 19
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="tab-20">
|
||||
Tab 20
|
||||
</WaTab>
|
||||
|
||||
<WaTabPanel name="tab-1">Tab panel 1</WaTabPanel>
|
||||
<WaTabPanel name="tab-2">Tab panel 2</WaTabPanel>
|
||||
<WaTabPanel name="tab-3">Tab panel 3</WaTabPanel>
|
||||
<WaTabPanel name="tab-4">Tab panel 4</WaTabPanel>
|
||||
<WaTabPanel name="tab-5">Tab panel 5</WaTabPanel>
|
||||
<WaTabPanel name="tab-6">Tab panel 6</WaTabPanel>
|
||||
<WaTabPanel name="tab-7">Tab panel 7</WaTabPanel>
|
||||
<WaTabPanel name="tab-8">Tab panel 8</WaTabPanel>
|
||||
<WaTabPanel name="tab-9">Tab panel 9</WaTabPanel>
|
||||
<WaTabPanel name="tab-10">Tab panel 10</WaTabPanel>
|
||||
<WaTabPanel name="tab-11">Tab panel 11</WaTabPanel>
|
||||
<WaTabPanel name="tab-12">Tab panel 12</WaTabPanel>
|
||||
<WaTabPanel name="tab-13">Tab panel 13</WaTabPanel>
|
||||
<WaTabPanel name="tab-14">Tab panel 14</WaTabPanel>
|
||||
<WaTabPanel name="tab-15">Tab panel 15</WaTabPanel>
|
||||
<WaTabPanel name="tab-16">Tab panel 16</WaTabPanel>
|
||||
<WaTabPanel name="tab-17">Tab panel 17</WaTabPanel>
|
||||
<WaTabPanel name="tab-18">Tab panel 18</WaTabPanel>
|
||||
<WaTabPanel name="tab-19">Tab panel 19</WaTabPanel>
|
||||
<WaTabPanel name="tab-20">Tab panel 20</WaTabPanel>
|
||||
</WaTabGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Manual Activation
|
||||
|
||||
When focused, keyboard users can press [[Left]] or [[Right]] to select the desired tab. By default, the corresponding tab panel will be shown immediately (automatic activation). You can change this behavior by setting `activation="manual"` which will require the user to press [[Space]] or [[Enter]] before showing the tab panel (manual activation).
|
||||
@@ -469,33 +209,3 @@ When focused, keyboard users can press [[Left]] or [[Right]] to select the desir
|
||||
<wa-tab-panel name="disabled">This is a disabled tab panel.</wa-tab-panel>
|
||||
</wa-tab-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTab from '@shoelace-style/shoelace/dist/react/tab';
|
||||
import WaTabGroup from '@shoelace-style/shoelace/dist/react/tab-group';
|
||||
import WaTabPanel from '@shoelace-style/shoelace/dist/react/tab-panel';
|
||||
|
||||
const App = () => (
|
||||
<WaTabGroup activation="manual">
|
||||
<WaTab slot="nav" panel="general">
|
||||
General
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="custom">
|
||||
Custom
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="advanced">
|
||||
Advanced
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="disabled" disabled>
|
||||
Disabled
|
||||
</WaTab>
|
||||
|
||||
<WaTabPanel name="general">This is the general tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="custom">This is the custom tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="advanced">This is the advanced tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="disabled">This is a disabled tab panel.</WaTabPanel>
|
||||
</WaTabGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -18,36 +18,6 @@ layout: component.njk
|
||||
</wa-tab-group>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTab from '@shoelace-style/shoelace/dist/react/tab';
|
||||
import WaTabGroup from '@shoelace-style/shoelace/dist/react/tab-group';
|
||||
import WaTabPanel from '@shoelace-style/shoelace/dist/react/tab-panel';
|
||||
|
||||
const App = () => (
|
||||
<WaTabGroup>
|
||||
<WaTab slot="nav" panel="general">
|
||||
General
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="custom">
|
||||
Custom
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="advanced">
|
||||
Advanced
|
||||
</WaTab>
|
||||
<WaTab slot="nav" panel="disabled" disabled>
|
||||
Disabled
|
||||
</WaTab>
|
||||
|
||||
<WaTabPanel name="general">This is the general tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="custom">This is the custom tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="advanced">This is the advanced tab panel.</WaTabPanel>
|
||||
<WaTabPanel name="disabled">This is a disabled tab panel.</WaTabPanel>
|
||||
</WaTabGroup>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::info
|
||||
Additional demonstrations can be found in the [tab group examples](/components/tab-group).
|
||||
:::
|
||||
|
||||
@@ -4,28 +4,6 @@ description: Tabs are used inside tab groups to represent and activate tab panel
|
||||
layout: component.njk
|
||||
---
|
||||
|
||||
```html {.example}
|
||||
<wa-tab>Tab</wa-tab>
|
||||
<wa-tab active>Active</wa-tab>
|
||||
<wa-tab closable>Closable</wa-tab>
|
||||
<wa-tab disabled>Disabled</wa-tab>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTab from '@shoelace-style/shoelace/dist/react/tab';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaTab>Tab</WaTab>
|
||||
<WaTab active>Active</WaTab>
|
||||
<WaTab closable>Closable</WaTab>
|
||||
<WaTab disabled>Disabled</WaTab>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::info
|
||||
Additional demonstrations can be found in the [tab group examples](/components/tab-group).
|
||||
:::
|
||||
:::
|
||||
@@ -12,22 +12,6 @@ layout: component.njk
|
||||
<wa-tag variant="danger">Danger</wa-tag>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTag from '@shoelace-style/shoelace/dist/react/tag';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaTag variant="brand">Brand</WaTag>
|
||||
<WaTag variant="success">Success</WaTag>
|
||||
<WaTag variant="neutral">Neutral</WaTag>
|
||||
<WaTag variant="warning">Warning</WaTag>
|
||||
<WaTag variant="danger">Danger</WaTag>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Sizes
|
||||
@@ -40,20 +24,6 @@ Use the `size` attribute to change a tab's size.
|
||||
<wa-tag size="large">Large</wa-tag>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTag from '@shoelace-style/shoelace/dist/react/tag';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaTag size="small">Small</WaTag>
|
||||
<WaTag size="medium">Medium</WaTag>
|
||||
<WaTag size="large">Large</WaTag>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Pill
|
||||
|
||||
Use the `pill` attribute to give tabs rounded edges.
|
||||
@@ -64,26 +34,6 @@ Use the `pill` attribute to give tabs rounded edges.
|
||||
<wa-tag size="large" pill>Large</wa-tag>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTag from '@shoelace-style/shoelace/dist/react/tag';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaTag size="small" pill>
|
||||
Small
|
||||
</WaTag>
|
||||
<WaTag size="medium" pill>
|
||||
Medium
|
||||
</WaTag>
|
||||
<WaTag size="large" pill>
|
||||
Large
|
||||
</WaTag>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Removable
|
||||
|
||||
Use the `removable` attribute to add a remove button to the tag.
|
||||
@@ -111,43 +61,3 @@ Use the `removable` attribute to add a remove button to the tag.
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTag from '@shoelace-style/shoelace/dist/react/tag';
|
||||
|
||||
const css = `
|
||||
.tags-removable wa-tag {
|
||||
transition: var(--wa-transition-fast) opacity;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => {
|
||||
function handleRemove(event) {
|
||||
const tag = event.target;
|
||||
tag.style.opacity = '0';
|
||||
setTimeout(() => (tag.style.opacity = '1'), 2000);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="tags-removable">
|
||||
<WaTag size="small" removable onWaRemove={handleRemove}>
|
||||
Small
|
||||
</WaTag>
|
||||
|
||||
<WaTag size="medium" removable onWaRemove={handleRemove}>
|
||||
Medium
|
||||
</WaTag>
|
||||
|
||||
<WaTag size="large" removable onWaRemove={handleRemove}>
|
||||
Large
|
||||
</WaTag>
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -8,14 +8,6 @@ layout: component.njk
|
||||
<wa-textarea></wa-textarea>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTextarea from '@shoelace-style/shoelace/dist/react/textarea';
|
||||
|
||||
const App = () => <WaTextarea />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
:::info
|
||||
This component works with standard `<form>` elements. Please refer to the section on [form controls](/getting-started/form-controls) to learn more about form submission and client-side validation.
|
||||
:::
|
||||
@@ -30,14 +22,6 @@ Use the `label` attribute to give the textarea an accessible label. For labels t
|
||||
<wa-textarea label="Comments"></wa-textarea>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTextarea from '@shoelace-style/shoelace/dist/react/textarea';
|
||||
|
||||
const App = () => <WaTextarea label="Comments" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Help Text
|
||||
|
||||
Add descriptive help text to a textarea with the `help-text` attribute. For help texts that contain HTML, use the `help-text` slot instead.
|
||||
@@ -46,14 +30,6 @@ Add descriptive help text to a textarea with the `help-text` attribute. For help
|
||||
<wa-textarea label="Feedback" help-text="Please tell us what you think."> </wa-textarea>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTextarea from '@shoelace-style/shoelace/dist/react/textarea';
|
||||
|
||||
const App = () => <WaTextarea label="Feedback" help-text="Please tell us what you think." />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Rows
|
||||
|
||||
Use the `rows` attribute to change the number of text rows that get shown.
|
||||
@@ -62,14 +38,6 @@ Use the `rows` attribute to change the number of text rows that get shown.
|
||||
<wa-textarea rows="2"></wa-textarea>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTextarea from '@shoelace-style/shoelace/dist/react/textarea';
|
||||
|
||||
const App = () => <WaTextarea rows={2} />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Placeholders
|
||||
|
||||
Use the `placeholder` attribute to add a placeholder.
|
||||
@@ -78,14 +46,6 @@ Use the `placeholder` attribute to add a placeholder.
|
||||
<wa-textarea placeholder="Type something"></wa-textarea>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTextarea from '@shoelace-style/shoelace/dist/react/textarea';
|
||||
|
||||
const App = () => <WaTextarea placeholder="Type something" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Filled Textareas
|
||||
|
||||
Add the `filled` attribute to draw a filled textarea.
|
||||
@@ -94,14 +54,6 @@ Add the `filled` attribute to draw a filled textarea.
|
||||
<wa-textarea placeholder="Type something" filled></wa-textarea>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTextarea from '@shoelace-style/shoelace/dist/react/textarea';
|
||||
|
||||
const App = () => <WaTextarea placeholder="Type something" filled />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` attribute to disable a textarea.
|
||||
@@ -110,14 +62,6 @@ Use the `disabled` attribute to disable a textarea.
|
||||
<wa-textarea placeholder="Textarea" disabled></wa-textarea>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTextarea from '@shoelace-style/shoelace/dist/react/textarea';
|
||||
|
||||
const App = () => <WaTextarea placeholder="Textarea" disabled />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Sizes
|
||||
|
||||
Use the `size` attribute to change a textarea's size.
|
||||
@@ -130,22 +74,6 @@ Use the `size` attribute to change a textarea's size.
|
||||
<wa-textarea placeholder="Large" size="large"></wa-textarea>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTextarea from '@shoelace-style/shoelace/dist/react/textarea';
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<WaTextarea placeholder="Small" size="small"></WaTextarea>
|
||||
<br />
|
||||
<WaTextarea placeholder="Medium" size="medium"></WaTextarea>
|
||||
<br />
|
||||
<WaTextarea placeholder="Large" size="large"></WaTextarea>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Prevent Resizing
|
||||
|
||||
By default, textareas can be resized vertically by the user. To prevent resizing, set the `resize` attribute to `none`.
|
||||
@@ -154,14 +82,6 @@ By default, textareas can be resized vertically by the user. To prevent resizing
|
||||
<wa-textarea resize="none"></wa-textarea>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTextarea from '@shoelace-style/shoelace/dist/react/textarea';
|
||||
|
||||
const App = () => <WaTextarea resize="none" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Expand with Content
|
||||
|
||||
Textareas will automatically resize to expand to fit their content when `resize` is set to `auto`.
|
||||
@@ -169,11 +89,3 @@ Textareas will automatically resize to expand to fit their content when `resize`
|
||||
```html {.example}
|
||||
<wa-textarea resize="auto"></wa-textarea>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTextarea from '@shoelace-style/shoelace/dist/react/textarea';
|
||||
|
||||
const App = () => <WaTextarea resize="auto" />;
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -4,29 +4,14 @@ description: Tooltips display additional information based on a specific action.
|
||||
layout: component.njk
|
||||
---
|
||||
|
||||
A tooltip's target is its _first child element_, so you should only wrap one element inside of the tooltip. If you need the tooltip to show up for multiple elements, nest them inside a container first.
|
||||
|
||||
Tooltips use `display: contents` so they won't interfere with how elements are positioned in a flex or grid layout.
|
||||
A tooltip's target is based on the `for` attribute which points to an element id.
|
||||
|
||||
```html {.example}
|
||||
<wa-tooltip content="This is a tooltip">
|
||||
<wa-button>Hover Me</wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip for="my-button">This is a tooltip</wa-tooltip>
|
||||
<wa-button id="my-button">Hover Me</wa-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaTooltip from '@shoelace-style/shoelace/dist/react/tooltip';
|
||||
|
||||
const App = () => (
|
||||
<WaTooltip content="This is a tooltip">
|
||||
<WaButton>Hover Me</WaButton>
|
||||
</WaTooltip>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Placement
|
||||
@@ -36,222 +21,79 @@ Use the `placement` attribute to set the preferred placement of the tooltip.
|
||||
```html {.example}
|
||||
<div class="tooltip-placement-example">
|
||||
<div class="tooltip-placement-example-row">
|
||||
<wa-tooltip content="top-start" placement="top-start">
|
||||
<wa-button></wa-button>
|
||||
</wa-tooltip>
|
||||
|
||||
<wa-tooltip content="top" placement="top">
|
||||
<wa-button></wa-button>
|
||||
</wa-tooltip>
|
||||
|
||||
<wa-tooltip content="top-end" placement="top-end">
|
||||
<wa-button></wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-button id="tooltip-top-start"></wa-button>
|
||||
<wa-button id="tooltip-top"></wa-button>
|
||||
<wa-button id="tooltip-top-end"></wa-button>
|
||||
</div>
|
||||
|
||||
<div class="tooltip-placement-example-row">
|
||||
<wa-tooltip content="left-start" placement="left-start">
|
||||
<wa-button></wa-button>
|
||||
</wa-tooltip>
|
||||
|
||||
<wa-tooltip content="right-start" placement="right-start">
|
||||
<wa-button></wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-button id="tooltip-left-start"></wa-button>
|
||||
<wa-button id="tooltip-right-start"></wa-button>
|
||||
</div>
|
||||
|
||||
<div class="tooltip-placement-example-row">
|
||||
<wa-tooltip content="left" placement="left">
|
||||
<wa-button></wa-button>
|
||||
</wa-tooltip>
|
||||
|
||||
<wa-tooltip content="right" placement="right">
|
||||
<wa-button></wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-button id="tooltip-left"></wa-button>
|
||||
<wa-button id="tooltip-right"></wa-button>
|
||||
</div>
|
||||
|
||||
<div class="tooltip-placement-example-row">
|
||||
<wa-tooltip content="left-end" placement="left-end">
|
||||
<wa-button></wa-button>
|
||||
</wa-tooltip>
|
||||
|
||||
<wa-tooltip content="right-end" placement="right-end">
|
||||
<wa-button></wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-button id="tooltip-left-end"></wa-button>
|
||||
<wa-button id="tooltip-right-end"></wa-button>
|
||||
</div>
|
||||
|
||||
<div class="tooltip-placement-example-row">
|
||||
<wa-tooltip content="bottom-start" placement="bottom-start">
|
||||
<wa-button></wa-button>
|
||||
</wa-tooltip>
|
||||
|
||||
<wa-tooltip content="bottom" placement="bottom">
|
||||
<wa-button></wa-button>
|
||||
</wa-tooltip>
|
||||
|
||||
<wa-tooltip content="bottom-end" placement="bottom-end">
|
||||
<wa-button></wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-button id="tooltip-bottom-start"></wa-button>
|
||||
<wa-button id="tooltip-bottom"></wa-button>
|
||||
<wa-button id="tooltip-bottom-end"></wa-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<wa-tooltip for="tooltip-top-start" placement="top-start">top-start</wa-tooltip>
|
||||
<wa-tooltip for="tooltip-top" placement="top">top</wa-tooltip>
|
||||
<wa-tooltip for="tooltip-top-end" placement="top-end">top-end</wa-tooltip>
|
||||
<wa-tooltip for="tooltip-left-start" placement="left-start">left-start</wa-tooltip>
|
||||
<wa-tooltip for="tooltip-right-start" placement="right-start">right-start</wa-tooltip>
|
||||
<wa-tooltip for="tooltip-left" placement="left">left</wa-tooltip>
|
||||
<wa-tooltip for="tooltip-right" placement="right">right</wa-tooltip>
|
||||
<wa-tooltip for="tooltip-left-end" placement="left-end">left-end</wa-tooltip>
|
||||
<wa-tooltip for="tooltip-right-end" placement="right-end">right-end</wa-tooltip>
|
||||
<wa-tooltip for="tooltip-bottom-start" placement="bottom-start">bottom-start</wa-tooltip>
|
||||
<wa-tooltip for="tooltip-bottom" placement="bottom">bottom</wa-tooltip>
|
||||
<wa-tooltip for="tooltip-bottom-end" placement="bottom-end">bottom-end</wa-tooltip>
|
||||
|
||||
<style>
|
||||
.tooltip-placement-example {
|
||||
width: 250px;
|
||||
margin: 1rem;
|
||||
}
|
||||
|
||||
.tooltip-placement-example-row:after {
|
||||
content: '';
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.tooltip-placement-example wa-button {
|
||||
float: left;
|
||||
width: 2.5rem;
|
||||
margin-right: 0.25rem;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.tooltip-placement-example-row:nth-child(1) wa-tooltip:first-child wa-button,
|
||||
.tooltip-placement-example-row:nth-child(5) wa-tooltip:first-child wa-button {
|
||||
margin-left: calc(40px + 0.25rem);
|
||||
.tooltip-placement-example-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.tooltip-placement-example-row:nth-child(2) wa-tooltip:nth-child(2) wa-button,
|
||||
.tooltip-placement-example-row:nth-child(3) wa-tooltip:nth-child(2) wa-button,
|
||||
.tooltip-placement-example-row:nth-child(4) wa-tooltip:nth-child(2) wa-button {
|
||||
margin-left: calc((40px * 3) + (0.25rem * 3));
|
||||
.tooltip-placement-example-row:nth-child(1),
|
||||
.tooltip-placement-example-row:nth-child(5) {
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaTooltip from '@shoelace-style/shoelace/dist/react/tooltip';
|
||||
|
||||
const css = `
|
||||
.tooltip-placement-example {
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.tooltip-placement-example-row:after {
|
||||
content: '';
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.tooltip-placement-example wa-button {
|
||||
float: left;
|
||||
width: 2.5rem;
|
||||
margin-right: 0.25rem;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.tooltip-placement-example-row:nth-child(1) wa-tooltip:first-child wa-button,
|
||||
.tooltip-placement-example-row:nth-child(5) wa-tooltip:first-child wa-button {
|
||||
margin-left: calc(40px + 0.25rem);
|
||||
}
|
||||
|
||||
.tooltip-placement-example-row:nth-child(2) wa-tooltip:nth-child(2) wa-button,
|
||||
.tooltip-placement-example-row:nth-child(3) wa-tooltip:nth-child(2) wa-button,
|
||||
.tooltip-placement-example-row:nth-child(4) wa-tooltip:nth-child(2) wa-button {
|
||||
margin-left: calc((40px * 3) + (0.25rem * 3));
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<div className="tooltip-placement-example">
|
||||
<div className="tooltip-placement-example-row">
|
||||
<WaTooltip content="top-start" placement="top-start">
|
||||
<WaButton />
|
||||
</WaTooltip>
|
||||
|
||||
<WaTooltip content="top" placement="top">
|
||||
<WaButton />
|
||||
</WaTooltip>
|
||||
|
||||
<WaTooltip content="top-end" placement="top-end">
|
||||
<WaButton />
|
||||
</WaTooltip>
|
||||
</div>
|
||||
|
||||
<div className="tooltip-placement-example-row">
|
||||
<WaTooltip content="left-start" placement="left-start">
|
||||
<WaButton />
|
||||
</WaTooltip>
|
||||
|
||||
<WaTooltip content="right-start" placement="right-start">
|
||||
<WaButton />
|
||||
</WaTooltip>
|
||||
</div>
|
||||
|
||||
<div className="tooltip-placement-example-row">
|
||||
<WaTooltip content="left" placement="left">
|
||||
<WaButton />
|
||||
</WaTooltip>
|
||||
|
||||
<WaTooltip content="right" placement="right">
|
||||
<WaButton />
|
||||
</WaTooltip>
|
||||
</div>
|
||||
|
||||
<div className="tooltip-placement-example-row">
|
||||
<WaTooltip content="left-end" placement="left-end">
|
||||
<WaButton />
|
||||
</WaTooltip>
|
||||
|
||||
<WaTooltip content="right-end" placement="right-end">
|
||||
<WaButton />
|
||||
</WaTooltip>
|
||||
</div>
|
||||
|
||||
<div className="tooltip-placement-example-row">
|
||||
<WaTooltip content="bottom-start" placement="bottom-start">
|
||||
<WaButton />
|
||||
</WaTooltip>
|
||||
|
||||
<WaTooltip content="bottom" placement="bottom">
|
||||
<WaButton />
|
||||
</WaTooltip>
|
||||
|
||||
<WaTooltip content="bottom-end" placement="bottom-end">
|
||||
<WaButton />
|
||||
</WaTooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Click Trigger
|
||||
|
||||
Set the `trigger` attribute to `click` to toggle the tooltip on click instead of hover.
|
||||
|
||||
```html {.example}
|
||||
<wa-tooltip content="Click again to dismiss" trigger="click">
|
||||
<wa-button>Click to Toggle</wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-button id="toggle-button">Click to Toggle</wa-button>
|
||||
<wa-tooltip for="toggle-button" trigger="click">Click again to dismiss</wa-tooltip>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaTooltip from '@shoelace-style/shoelace/dist/react/tooltip';
|
||||
|
||||
const App = () => (
|
||||
<WaTooltip content="Click again to dismiss" trigger="click">
|
||||
<WaButton>Click to Toggle</WaButton>
|
||||
</WaTooltip>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Manual Trigger
|
||||
|
||||
Tooltips can be controller programmatically by setting the `trigger` attribute to `manual`. Use the `open` attribute to control when the tooltip is shown.
|
||||
@@ -259,9 +101,8 @@ Tooltips can be controller programmatically by setting the `trigger` attribute t
|
||||
```html {.example}
|
||||
<wa-button style="margin-right: 4rem;">Toggle Manually</wa-button>
|
||||
|
||||
<wa-tooltip content="This is an avatar" trigger="manual" class="manual-tooltip">
|
||||
<wa-avatar label="User"></wa-avatar>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip for="manual-trigger-tooltip" trigger="manual" class="manual-tooltip">This is an avatar!</wa-tooltip>
|
||||
<wa-avatar id="manual-trigger-tooltip" label="User"></wa-avatar>
|
||||
|
||||
<script>
|
||||
const tooltip = document.querySelector('.manual-tooltip');
|
||||
@@ -271,60 +112,15 @@ Tooltips can be controller programmatically by setting the `trigger` attribute t
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import { useState } from 'react';
|
||||
import WaAvatar from '@shoelace-style/shoelace/dist/react/avatar';
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaTooltip from '@shoelace-style/shoelace/dist/react/tooltip';
|
||||
|
||||
const App = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaButton style={{ marginRight: '4rem' }} onClick={() => setOpen(!open)}>
|
||||
Toggle Manually
|
||||
</WaButton>
|
||||
|
||||
<WaTooltip open={open} content="This is an avatar" trigger="manual">
|
||||
<WaAvatar />
|
||||
</WaTooltip>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Removing Arrows
|
||||
|
||||
You can control the size of tooltip arrows by overriding the `--wa-tooltip-arrow-size` design token. To remove them, set the value to `0` as shown below.
|
||||
|
||||
```html {.example}
|
||||
<wa-tooltip content="This is a tooltip" style="--wa-tooltip-arrow-size: 0;">
|
||||
<wa-button>No Arrow</wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-button id="no-arrow">No Arrow</wa-button>
|
||||
<wa-tooltip for="no-arrow" style="--wa-tooltip-arrow-size: 0;">This is a tooltip with no arrow</wa-tooltip>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaTooltip from '@shoelace-style/shoelace/dist/react/tooltip';
|
||||
|
||||
const App = () => (
|
||||
<div style={{ '--wa-tooltip-arrow-size': '0' }}>
|
||||
<WaTooltip content="This is a tooltip">
|
||||
<WaButton>Above</WaButton>
|
||||
</WaTooltip>
|
||||
|
||||
<WaTooltip content="This is a tooltip" placement="bottom">
|
||||
<WaButton>Below</WaButton>
|
||||
</WaTooltip>
|
||||
</div>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
To override it globally, set it in a root block in your stylesheet after the Web Awesome stylesheet is loaded.
|
||||
|
||||
```css
|
||||
@@ -335,109 +131,45 @@ To override it globally, set it in a root block in your stylesheet after the Web
|
||||
|
||||
### HTML in Tooltips
|
||||
|
||||
Use the `content` slot to create tooltips with HTML content. Tooltips are designed only for text and presentational elements. Avoid placing interactive content, such as buttons, links, and form controls, in a tooltip.
|
||||
Use the default slot to create tooltips with HTML content. Tooltips are designed only for text and presentational elements. Avoid placing interactive content, such as buttons, links, and form controls, in a tooltip.
|
||||
|
||||
```html {.example}
|
||||
<wa-tooltip>
|
||||
<div slot="content">I'm not <strong>just</strong> a tooltip, I'm a <em>tooltip</em> with HTML!</div>
|
||||
|
||||
<wa-button>Hover me</wa-button>
|
||||
<wa-button id="rich-tooltip">Hover me</wa-button>
|
||||
<wa-tooltip for="rich-tooltip">
|
||||
<div>I'm not <strong>just</strong> a tooltip, I'm a <em>tooltip</em> with HTML!</div>
|
||||
</wa-tooltip>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaTooltip from '@shoelace-style/shoelace/dist/react/tooltip';
|
||||
|
||||
const App = () => (
|
||||
<WaTooltip>
|
||||
<div slot="content">
|
||||
I'm not <strong>just</strong> a tooltip, I'm a <em>tooltip</em> with HTML!
|
||||
</div>
|
||||
|
||||
<WaButton>Hover Me</WaButton>
|
||||
</WaTooltip>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Setting a Maximum Width
|
||||
|
||||
Use the `--max-width` custom property to change the width the tooltip can grow to before wrapping occurs.
|
||||
|
||||
```html {.example}
|
||||
<wa-tooltip style="--max-width: 80px;" content="This tooltip will wrap after only 80 pixels.">
|
||||
<wa-button>Hover me</wa-button>
|
||||
<wa-tooltip for="wrapping-tooltip" style="--max-width: 80px;">
|
||||
This tooltip will wrap after only 80 pixels.
|
||||
</wa-tooltip>
|
||||
<wa-button id="wrapping-tooltip">Hover me</wa-button>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaTooltip from '@shoelace-style/shoelace/dist/react/tooltip';
|
||||
|
||||
const App = () => (
|
||||
<WaTooltip style={{ '--max-width': '80px' }} content="This tooltip will wrap after only 80 pixels.">
|
||||
<WaButton>Hover Me</WaButton>
|
||||
</WaTooltip>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Hoisting
|
||||
|
||||
Tooltips will be clipped if they're inside a container that has `overflow: auto|hidden|scroll`. The `hoist` attribute forces the tooltip to use a fixed positioning strategy, allowing it to break out of the container. In this case, the tooltip will be positioned relative to its [containing block](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#Identifying_the_containing_block), which is usually the viewport unless an ancestor uses a `transform`, `perspective`, or `filter`. [Refer to this page](https://developer.mozilla.org/en-US/docs/Web/CSS/position#fixed) for more details.
|
||||
|
||||
```html {.example}
|
||||
<div class="tooltip-hoist">
|
||||
<wa-tooltip content="This is a tooltip">
|
||||
<wa-button>No Hoist</wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip for="no-hoist">This is a tooltip</wa-tooltip>
|
||||
<wa-button id="no-hoist">No Hoist</wa-button>
|
||||
|
||||
<wa-tooltip content="This is a tooltip" hoist>
|
||||
<wa-button>Hoist</wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip for="hoist" hoist>This is a tooltip</wa-tooltip>
|
||||
<wa-button id="hoist">Hoist</wa-button>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.tooltip-hoist {
|
||||
position: relative;
|
||||
border: solid 2px var(--wa-color-surface-border);
|
||||
overflow: hidden;
|
||||
border: solid 2px var(--wa-color-surface-border);
|
||||
padding: var(--wa-space-m);
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaButton from '@shoelace-style/shoelace/dist/react/button';
|
||||
import WaTooltip from '@shoelace-style/shoelace/dist/react/tooltip';
|
||||
|
||||
const css = `
|
||||
.tooltip-hoist {
|
||||
border: solid 2px var(--wa-color-surface-border);
|
||||
overflow: hidden;
|
||||
padding: var(--wa-space-m);
|
||||
position: relative;
|
||||
}
|
||||
`;
|
||||
|
||||
const App = () => (
|
||||
<>
|
||||
<div class="tooltip-hoist">
|
||||
<WaTooltip content="This is a tooltip">
|
||||
<WaButton>No Hoist</WaButton>
|
||||
</WaTooltip>
|
||||
|
||||
<WaTooltip content="This is a tooltip" hoist>
|
||||
<WaButton>Hoist</WaButton>
|
||||
</WaTooltip>
|
||||
</div>
|
||||
|
||||
<style>{css}</style>
|
||||
</>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -17,27 +17,6 @@ layout: component.njk
|
||||
</wa-tree>
|
||||
```
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTree from '@shoelace-style/shoelace/dist/react/tree';
|
||||
import WaTreeItem from '@shoelace-style/shoelace/dist/react/tree-item';
|
||||
|
||||
const App = () => (
|
||||
<WaTree>
|
||||
<WaTreeItem>
|
||||
Item 1
|
||||
<WaTreeItem>Item A</WaTreeItem>
|
||||
<WaTreeItem>Item B</WaTreeItem>
|
||||
<WaTreeItem>Item C</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
<WaTreeItem>Item 2</WaTreeItem>
|
||||
<WaTreeItem>Item 3</WaTreeItem>
|
||||
</WaTree>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Nested tree items
|
||||
@@ -62,32 +41,6 @@ A tree item can contain other tree items. This allows the node to be expanded or
|
||||
</wa-tree>
|
||||
```
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTree from '@shoelace-style/shoelace/dist/react/tree';
|
||||
import WaTreeItem from '@shoelace-style/shoelace/dist/react/tree-item';
|
||||
|
||||
const App = () => (
|
||||
<WaTree>
|
||||
<WaTreeItem>
|
||||
Item 1
|
||||
<WaTreeItem>
|
||||
Item A
|
||||
<WaTreeItem>Item Z</WaTreeItem>
|
||||
<WaTreeItem>Item Y</WaTreeItem>
|
||||
<WaTreeItem>Item X</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
<WaTreeItem>Item B</WaTreeItem>
|
||||
<WaTreeItem>Item C</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
<WaTreeItem>Item 2</WaTreeItem>
|
||||
<WaTreeItem>Item 3</WaTreeItem>
|
||||
</WaTree>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Selected
|
||||
|
||||
Use the `selected` attribute to select a tree item initially.
|
||||
@@ -105,27 +58,6 @@ Use the `selected` attribute to select a tree item initially.
|
||||
</wa-tree>
|
||||
```
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTree from '@shoelace-style/shoelace/dist/react/tree';
|
||||
import WaTreeItem from '@shoelace-style/shoelace/dist/react/tree-item';
|
||||
|
||||
const App = () => (
|
||||
<WaTree>
|
||||
<WaTreeItem selected>
|
||||
Item 1
|
||||
<WaTreeItem>Item A</WaTreeItem>
|
||||
<WaTreeItem>Item B</WaTreeItem>
|
||||
<WaTreeItem>Item C</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
<WaTreeItem>Item 2</WaTreeItem>
|
||||
<WaTreeItem>Item 3</WaTreeItem>
|
||||
</WaTree>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Expanded
|
||||
|
||||
Use the `expanded` attribute to expand a tree item initially.
|
||||
@@ -147,29 +79,3 @@ Use the `expanded` attribute to expand a tree item initially.
|
||||
<wa-tree-item>Item 3</wa-tree-item>
|
||||
</wa-tree>
|
||||
```
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTree from '@shoelace-style/shoelace/dist/react/tree';
|
||||
import WaTreeItem from '@shoelace-style/shoelace/dist/react/tree-item';
|
||||
|
||||
const App = () => (
|
||||
<WaTree>
|
||||
<WaTreeItem expanded>
|
||||
Item 1
|
||||
<WaTreeItem expanded>
|
||||
Item A
|
||||
<WaTreeItem>Item Z</WaTreeItem>
|
||||
<WaTreeItem>Item Y</WaTreeItem>
|
||||
<WaTreeItem>Item X</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
<WaTreeItem>Item B</WaTreeItem>
|
||||
<WaTreeItem>Item C</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
<WaTreeItem>Item 2</WaTreeItem>
|
||||
<WaTreeItem>Item 3</WaTreeItem>
|
||||
</WaTree>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -34,44 +34,6 @@ layout: component.njk
|
||||
</wa-tree>
|
||||
```
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTree from '@shoelace-style/shoelace/dist/react/tree';
|
||||
import WaTreeItem from '@shoelace-style/shoelace/dist/react/tree-item';
|
||||
|
||||
const App = () => (
|
||||
<WaTree>
|
||||
<WaTreeItem>
|
||||
Deciduous
|
||||
<WaTreeItem>Birch</WaTreeItem>
|
||||
<WaTreeItem>
|
||||
Maple
|
||||
<WaTreeItem>Field maple</WaTreeItem>
|
||||
<WaTreeItem>Red maple</WaTreeItem>
|
||||
<WaTreeItem>Sugar maple</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
<WaTreeItem>Oak</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
|
||||
<WaTreeItem>
|
||||
Coniferous
|
||||
<WaTreeItem>Cedar</WaTreeItem>
|
||||
<WaTreeItem>Pine</WaTreeItem>
|
||||
<WaTreeItem>Spruce</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
|
||||
<WaTreeItem>
|
||||
Non-trees
|
||||
<WaTreeItem>Bamboo</WaTreeItem>
|
||||
<WaTreeItem>Cactus</WaTreeItem>
|
||||
<WaTreeItem>Fern</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
</WaTree>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
## Examples
|
||||
|
||||
### Selection Modes
|
||||
@@ -118,46 +80,6 @@ The `selection` attribute lets you change the selection behavior of the tree.
|
||||
</script>
|
||||
```
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTree from '@shoelace-style/shoelace/dist/react/tree';
|
||||
import WaTreeItem from '@shoelace-style/shoelace/dist/react/tree-item';
|
||||
|
||||
const App = () => {
|
||||
const [selection, setSelection] = useState('single');
|
||||
|
||||
return (
|
||||
<>
|
||||
<WaSelect label="Selection" value={selection} onWaChange={event => setSelection(event.target.value)}>
|
||||
<WaMenuItem value="single">single</WaMenuItem>
|
||||
<WaMenuItem value="multiple">multiple</WaMenuItem>
|
||||
<WaMenuItem value="leaf">leaf</WaMenuItem>
|
||||
</WaSelect>
|
||||
|
||||
<br />
|
||||
|
||||
<WaTree selection={selection}>
|
||||
<WaTreeItem>
|
||||
Item 1
|
||||
<WaTreeItem>
|
||||
Item A
|
||||
<WaTreeItem>Item Z</WaTreeItem>
|
||||
<WaTreeItem>Item Y</WaTreeItem>
|
||||
<WaTreeItem>Item X</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
<WaTreeItem>Item B</WaTreeItem>
|
||||
<WaTreeItem>Item C</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
<WaTreeItem>Item 2</WaTreeItem>
|
||||
<WaTreeItem>Item 3</WaTreeItem>
|
||||
</WaTree>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Showing Indent Guides
|
||||
|
||||
Indent guides can be drawn by setting `--indent-guide-width`. You can also change the color, offset, and style, using `--indent-guide-color`, `--indent-guide-style`, and `--indent-guide-offset`, respectively.
|
||||
@@ -198,44 +120,6 @@ Indent guides can be drawn by setting `--indent-guide-width`. You can also chang
|
||||
</style>
|
||||
```
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTree from '@shoelace-style/shoelace/dist/react/tree';
|
||||
import WaTreeItem from '@shoelace-style/shoelace/dist/react/tree-item';
|
||||
|
||||
const App = () => (
|
||||
<WaTree class="tree-with-lines" style={{ '--indent-guide-width': '1px' }}>
|
||||
<WaTreeItem expanded>
|
||||
Deciduous
|
||||
<WaTreeItem>Birch</WaTreeItem>
|
||||
<WaTreeItem expanded>
|
||||
Maple
|
||||
<WaTreeItem>Field maple</WaTreeItem>
|
||||
<WaTreeItem>Red maple</WaTreeItem>
|
||||
<WaTreeItem>Sugar maple</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
<WaTreeItem>Oak</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
|
||||
<WaTreeItem>
|
||||
Coniferous
|
||||
<WaTreeItem>Cedar</WaTreeItem>
|
||||
<WaTreeItem>Pine</WaTreeItem>
|
||||
<WaTreeItem>Spruce</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
|
||||
<WaTreeItem>
|
||||
Non-trees
|
||||
<WaTreeItem>Bamboo</WaTreeItem>
|
||||
<WaTreeItem>Cactus</WaTreeItem>
|
||||
<WaTreeItem>Fern</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
</WaTree>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Lazy Loading
|
||||
|
||||
Use the `lazy` attribute on a tree item to indicate that the content is not yet present and will be loaded later. When the user tries to expand the node, the `loading` state is set to `true` and the `wa-lazy-load` event will be emitted to allow you to load data asynchronously. The item will remain in a loading state until its content is changed.
|
||||
@@ -268,39 +152,6 @@ If you want to disable this behavior after the first load, simply remove the `la
|
||||
</script>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTree from '@shoelace-style/shoelace/dist/react/tree';
|
||||
import WaTreeItem from '@shoelace-style/shoelace/dist/react/tree-item';
|
||||
|
||||
const App = () => {
|
||||
const [childItems, setChildItems] = useState([]);
|
||||
const [lazy, setLazy] = useState(true);
|
||||
|
||||
const handleLazyLoad = () => {
|
||||
// Simulate asynchronous loading
|
||||
setTimeout(() => {
|
||||
setChildItems(['Birch', 'Cedar', 'Maple', 'Pine']);
|
||||
|
||||
// Disable lazy mode once the content has been loaded
|
||||
setLazy(false);
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
return (
|
||||
<WaTree>
|
||||
<WaTreeItem lazy={lazy} onWaLazyLoad={handleLazyLoad}>
|
||||
Available Trees
|
||||
{childItems.map(item => (
|
||||
<WaTreeItem>{item}</WaTreeItem>
|
||||
))}
|
||||
</WaTreeItem>
|
||||
</WaTree>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### Customizing the Expand and Collapse Icons
|
||||
|
||||
Use the `expand-icon` and `collapse-icon` slots to change the expand and collapse icons, respectively. To disable the animation, override the `rotate` property on the `expand-button` part as shown below.
|
||||
@@ -345,47 +196,6 @@ Use the `expand-icon` and `collapse-icon` slots to change the expand and collaps
|
||||
</style>
|
||||
```
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaTree from '@shoelace-style/shoelace/dist/react/tree';
|
||||
import WaTreeItem from '@shoelace-style/shoelace/dist/react/tree-item';
|
||||
|
||||
const App = () => (
|
||||
<WaTree>
|
||||
<WaIcon name="square-plus" variant="solid" slot="expand-icon"></WaIcon>
|
||||
<WaIcon name="square-minus" variant="solid" slot="collapse-icon"></WaIcon>
|
||||
|
||||
<WaTreeItem>
|
||||
Deciduous
|
||||
<WaTreeItem>Birch</WaTreeItem>
|
||||
<WaTreeItem>
|
||||
Maple
|
||||
<WaTreeItem>Field maple</WaTreeItem>
|
||||
<WaTreeItem>Red maple</WaTreeItem>
|
||||
<WaTreeItem>Sugar maple</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
<WaTreeItem>Oak</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
|
||||
<WaTreeItem>
|
||||
Coniferous
|
||||
<WaTreeItem>Cedar</WaTreeItem>
|
||||
<WaTreeItem>Pine</WaTreeItem>
|
||||
<WaTreeItem>Spruce</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
|
||||
<WaTreeItem>
|
||||
Non-trees
|
||||
<WaTreeItem>Bamboo</WaTreeItem>
|
||||
<WaTreeItem>Cactus</WaTreeItem>
|
||||
<WaTreeItem>Fern</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
</WaTree>
|
||||
);
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
### With Icons
|
||||
|
||||
Decorative icons can be used before labels to provide hints for each node.
|
||||
@@ -432,52 +242,3 @@ Decorative icons can be used before labels to provide hints for each node.
|
||||
</wa-tree-item>
|
||||
</wa-tree>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
```jsx {.react}
|
||||
import WaIcon from '@shoelace-style/shoelace/dist/react/icon';
|
||||
import WaTree from '@shoelace-style/shoelace/dist/react/tree';
|
||||
import WaTreeItem from '@shoelace-style/shoelace/dist/react/tree-item';
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<WaTree class="tree-with-icons">
|
||||
<WaTreeItem expanded>
|
||||
<WaIcon name="folder" />
|
||||
Root
|
||||
<WaTreeItem>
|
||||
<WaIcon name="folder" />
|
||||
Folder 1<WaTreeItem>
|
||||
<WaIcon name="files" />
|
||||
File 1 - 1
|
||||
</WaTreeItem>
|
||||
<WaTreeItem disabled>
|
||||
<WaIcon name="files" />
|
||||
File 1 - 2
|
||||
</WaTreeItem>
|
||||
<WaTreeItem>
|
||||
<WaIcon name="files" />
|
||||
File 1 - 3
|
||||
</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
<WaTreeItem>
|
||||
<WaIcon name="files" />
|
||||
Folder 2<WaTreeItem>
|
||||
<WaIcon name="files" />
|
||||
File 2 - 1
|
||||
</WaTreeItem>
|
||||
<WaTreeItem>
|
||||
<WaIcon name="files" />
|
||||
File 2 - 2
|
||||
</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
<WaTreeItem>
|
||||
<WaIcon name="files" />
|
||||
File 1
|
||||
</WaTreeItem>
|
||||
</WaTreeItem>
|
||||
</WaTree>
|
||||
);
|
||||
};
|
||||
```
|
||||
{% endraw %}
|
||||
|
||||
@@ -38,12 +38,12 @@ hasOutline: false
|
||||
scrollbar-color: var(--wa-color-neutral-border-highlight) var(--wa-color-surface-raised);
|
||||
}
|
||||
|
||||
/* #region Lock theme styles */
|
||||
/* #region Lock theme styles */
|
||||
#knobs,
|
||||
#knobs :host,
|
||||
#knobs :host *,
|
||||
#color-mode-selector,
|
||||
#icon-chooser {
|
||||
#icon-chooser {
|
||||
--wa-color-surface-border: color-mix(in oklab, var(--wa-color-text-normal), transparent 90%);
|
||||
|
||||
--wa-color-shadow: rgb(0 0 0 / 0.1);
|
||||
@@ -537,13 +537,12 @@ hasOutline: false
|
||||
<wa-radio-button value="meteor"><wa-icon name="meteor"></wa-icon></wa-radio-button>
|
||||
<wa-radio-button value="cat-space"><wa-icon name="cat-space"></wa-icon></wa-radio-button>
|
||||
<wa-radio-button value="puzzle-piece"><wa-icon name="puzzle-piece"></wa-icon></wa-radio-button>
|
||||
<wa-tooltip content="Browse icons" distance="-3" hoist>
|
||||
<wa-button value="[choose]" variant="text" id="icon-chooser-trigger" class="logo-chooser">
|
||||
<wa-tooltip for="icon-chooser-trigger" distance="-3" hoist>Browse Icons</wa-tooltip>
|
||||
<wa-icon name="ellipsis" library="fa-classic-regular"></wa-icon>
|
||||
<wa-visually-hidden>Browse icons</wa-visually-hidden>
|
||||
</wa-button>
|
||||
</wa-tooltip>
|
||||
<small slot="help-text" style="display: inline-block; line-height: var(--wa-font-line-height-compact);">It's dangerous to go alone. Take these!</small>
|
||||
<small slot="help-text" style="display: inline-block; line-height: var(--wa-font-line-height-compact);">It's dangerous to go alone. Take these!</small>
|
||||
</wa-radio-group>
|
||||
</div>
|
||||
</wa-details>
|
||||
@@ -853,7 +852,7 @@ hasOutline: false
|
||||
});
|
||||
|
||||
document.querySelector("#icon-chooser-trigger").addEventListener("click", () => {
|
||||
document.querySelector("#icon-chooser").show()
|
||||
document.querySelector("#icon-chooser").open = true
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -910,7 +909,7 @@ hasOutline: false
|
||||
colorStylesheet.href = `/dist/themes/color_${colorPalette}.css`;
|
||||
colorSelect.value = colorPalette;
|
||||
}
|
||||
|
||||
|
||||
function resetHeadingFontWeightValue() {
|
||||
document.documentElement.style.removeProperty('--wa-font-weight-heading')
|
||||
fontWeightHeading.value = getComputedStyle(previewContainer).getPropertyValue('--wa-font-weight-heading')
|
||||
@@ -1141,7 +1140,7 @@ hasOutline: false
|
||||
document.head.prepend(newStylesheet);
|
||||
});
|
||||
|
||||
// Color Palette
|
||||
// Color Palette
|
||||
colorSelect.addEventListener('wa-change', event => {
|
||||
const colorPalette = event.target.value;
|
||||
|
||||
@@ -1229,7 +1228,7 @@ hasOutline: false
|
||||
// Depending on how we plan to store the logos, we can also do <img src="" height="36" width="36">
|
||||
projectLogo.replaceWith(element);
|
||||
logoSelector.value = "";
|
||||
event.currentTarget.closest("wa-dialog").hide();
|
||||
event.currentTarget.closest("wa-dialog").open = false;
|
||||
})
|
||||
|
||||
// Pre-generated logos
|
||||
@@ -1600,11 +1599,11 @@ hasOutline: false
|
||||
|
||||
if (iconFamily.value === 'custom') {
|
||||
iconChooserTrigger.setAttribute('disabled', 'true');
|
||||
iconChooserTriggerTooltip.setAttribute('content', 'Choose a Font Awesome icon family to browse more icons');
|
||||
iconChooserTriggerTooltip.textContent = 'Choose a Font Awesome icon family to browse more icons';
|
||||
}
|
||||
else {
|
||||
iconChooserTrigger.removeAttribute('disabled');
|
||||
iconChooserTriggerTooltip.setAttribute('content', 'Browse icons');
|
||||
iconChooserTriggerTooltip.textContent = 'Browse icons'
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2133,10 +2132,10 @@ hasOutline: false
|
||||
<code class="language-css">:host,
|
||||
.wa-theme-purple-power {
|
||||
/* ... */
|
||||
}</code>
|
||||
</pre>
|
||||
<h3>Ontological Shock</h3>
|
||||
<p>The allegory is related to Plato's theory of Forms, which holds that the true essence of an object is not what we perceive with our senses, but rather its quality, and that most people perceive only the shadow of the object and are thus limited to false perception.</p>
|
||||
}</code></pre>
|
||||
|
||||
<h3>Ontological Shock</h3>
|
||||
<p>The allegory is related to Plato's theory of Forms, which holds that the true essence of an object is not what we perceive with our senses, but rather its quality, and that most people perceive only the shadow of the object and are thus limited to false perception.</p>
|
||||
<pre class="codeblock">
|
||||
<code class="language-html"><html class="wa-theme-default-dark">
|
||||
<head>
|
||||
@@ -2154,44 +2153,35 @@ hasOutline: false
|
||||
</div>
|
||||
</section>
|
||||
<section class="strata message-composer">
|
||||
<wa-card class="card-header card-footer">
|
||||
<wa-card with-header with-footer class="card-header card-footer">
|
||||
<div slot="header">
|
||||
<div class="grouped-buttons">
|
||||
<wa-tooltip content="Bold">
|
||||
<wa-icon-button name="bold" label="Bold"></wa-icon-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip content="Italic">
|
||||
<wa-icon-button name="italic" label="Italic"></wa-icon-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip content="Strikethrough">
|
||||
<wa-icon-button name="strikethrough" label="strikethrough"></wa-icon-button>
|
||||
</wa-tooltip>
|
||||
<wa-icon-button id="bold" name="bold" label="Bold"></wa-icon-button>
|
||||
<wa-tooltip for="bold">Bold</wa-tooltip>
|
||||
<wa-icon-button id="italic" name="italic" label="Italic"></wa-icon-button>
|
||||
<wa-tooltip for="italic">Italic</wa-tooltip>
|
||||
<wa-icon-button id="strikethrough" name="strikethrough" label="strikethrough"></wa-icon-button>
|
||||
<wa-tooltip for="strikethrough">Strikethrough</wa-tooltip>
|
||||
</div>
|
||||
<div class="grouped-buttons">
|
||||
<wa-tooltip content="Link">
|
||||
<wa-icon-button name="link" label="Link"></wa-icon-button>
|
||||
</wa-tooltip>
|
||||
<wa-icon-button id="link" name="link" label="Link"></wa-icon-button>
|
||||
<wa-tooltip for="link">Link</wa-tooltip>
|
||||
</div>
|
||||
<div class="grouped-buttons">
|
||||
<wa-tooltip content="Unordered List">
|
||||
<wa-icon-button name="list" label="Unordered List"></wa-icon-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip content="Ordered List">
|
||||
<wa-icon-button name="list-ol" label="Ordered List"></wa-icon-button>
|
||||
</wa-tooltip>
|
||||
<wa-icon-button id="list" name="list" label="Unordered List"></wa-icon-button>
|
||||
<wa-tooltip for="list">Unordered List</wa-tooltip>
|
||||
<wa-icon-button id="list-ol" name="list-ol" label="Ordered List"></wa-icon-button>
|
||||
<wa-tooltip for="list-ol">Ordered List</wa-tooltip>
|
||||
</div>
|
||||
<div class="grouped-buttons">
|
||||
<wa-tooltip content="Block Quote">
|
||||
<wa-icon-button name="block-quote" label="Block Quote"></wa-icon-button>
|
||||
</wa-tooltip>
|
||||
<wa-icon-button id="block-quote" name="block-quote" label="Block Quote"></wa-icon-button>
|
||||
<wa-tooltip for="block-quote">Block Quote</wa-tooltip>
|
||||
</div>
|
||||
<div class="grouped-buttons">
|
||||
<wa-tooltip content="Code">
|
||||
<wa-icon-button name="code" label="Code"></wa-icon-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip content="Inline Code">
|
||||
<wa-icon-button name="terminal" label="Inline Code"></wa-icon-button>
|
||||
</wa-tooltip>
|
||||
<wa-icon-button id="code" name="code" label="Code"></wa-icon-button>
|
||||
<wa-tooltip for="code">Code</wa-tooltip>
|
||||
<wa-icon-button id="inline-code" name="terminal" label="Inline Code"></wa-icon-button>
|
||||
<wa-tooltip for="inline-code">Inline Code</wa-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
@@ -2200,31 +2190,24 @@ hasOutline: false
|
||||
<div slot="footer">
|
||||
<div class="tools">
|
||||
<div class="grouped-buttons">
|
||||
<wa-tooltip content="Add File">
|
||||
<wa-icon-button name="circle-plus" label="Add File"></wa-icon-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip content="Formatting">
|
||||
<wa-icon-button name="font-case" label="Open Formatting"></wa-icon-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip content="Emojis">
|
||||
<wa-icon-button name="face-smile" label="Emoji"></wa-icon-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip content="Mention">
|
||||
<wa-icon-button name="at" label="Mention"></wa-icon-button>
|
||||
</wa-tooltip>
|
||||
<wa-icon-button id="add-file" name="circle-plus" label="Add File"></wa-icon-button>
|
||||
<wa-tooltip for="add-file">Add File</wa-tooltip>
|
||||
<wa-icon-button id="formatting" name="font-case" label="Open Formatting"></wa-icon-button>
|
||||
<wa-tooltip for="formatting">Formatting</wa-tooltip>
|
||||
<wa-icon-button id="emojis" name="face-smile" label="Emoji"></wa-icon-button>
|
||||
<wa-tooltip for="emojis">Emojis</wa-tooltip>
|
||||
<wa-icon-button id="mention" name="at" label="Mention"></wa-icon-button>
|
||||
<wa-tooltip for="mention">Mention</wa-tooltip>
|
||||
</div>
|
||||
<div class="grouped-buttons">
|
||||
<wa-tooltip content="Record Video">
|
||||
<wa-icon-button name="video" label="Video"></wa-icon-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip content="Record Audio Clip">
|
||||
<wa-icon-button name="microphone" label="Microphone"></wa-icon-button>
|
||||
</wa-tooltip>
|
||||
<wa-icon-button id="record-video" name="video" label="Video"></wa-icon-button>
|
||||
<wa-tooltip for="record-video">Record Video</wa-tooltip>
|
||||
<wa-icon-button id="record-audio" name="microphone" label="Microphone"></wa-icon-button>
|
||||
<wa-tooltip for="record-audio">Record Audio Clip</wa-tooltip>
|
||||
</div>
|
||||
<div class="grouped-buttons">
|
||||
<wa-tooltip content="Add Magic">
|
||||
<wa-icon-button name="sparkles" label="Magic"></wa-icon-button>
|
||||
</wa-tooltip>
|
||||
<wa-icon-button id="add-magic" name="sparkles" label="Magic"></wa-icon-button>
|
||||
<wa-tooltip for="add-magic">Add Magic</wa-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<div class="send">
|
||||
@@ -2549,4 +2532,4 @@ hasOutline: false
|
||||
</section>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
@@ -96,13 +96,12 @@ However, if you're [cherry picking](#cherry-picking) or [bundling](#bundling) We
|
||||
|
||||
```html
|
||||
<!-- Option 1: the data-webawesome attribute -->
|
||||
<script src="bundle.js" data-webawesome="/path/to/shoelace/%NPMDIR%"></script>
|
||||
<script src="bundle.js" data-webawesome="/path/to/web-awesome/%NPMDIR%"></script>
|
||||
|
||||
<!-- Option 2: the setBasePath() method -->
|
||||
<script src="bundle.js"></script>
|
||||
<script type="module">
|
||||
import { setBasePath } from '@shoelace-style/shoelace/%NPMDIR%/utilities/base-path.js';
|
||||
setBasePath('/path/to/shoelace/%NPMDIR%');
|
||||
import { setBasePath } from '/path/to/web-awesome/%NPMDIR%/webawesome.js';
|
||||
setBasePath('/path/to/web-awesome/%NPMDIR%');
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -116,7 +115,7 @@ Most of the magic behind assets is handled internally by Web Awesome, but if you
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import { getBasePath, setBasePath } from '@shoelace-style/shoelace/%NPMDIR%/utilities/base-path.js';
|
||||
import { getBasePath, setBasePath } from '/path/to/web-awesome/%NPMDIR%/webawesome.js';
|
||||
|
||||
setBasePath('/path/to/assets');
|
||||
|
||||
@@ -130,6 +129,21 @@ Most of the magic behind assets is handled internally by Web Awesome, but if you
|
||||
</script>
|
||||
```
|
||||
|
||||
## Setting a Kit Code
|
||||
|
||||
Font Awesome users can set their kit code to unlock Font Awesome Pro icons. You can provide it through the `data-fa-kit-code` attribute or by calling the `setKitCode()` method.
|
||||
|
||||
```html
|
||||
<!-- Option 1: the data-fa-kit-code attribute -->
|
||||
<script src="bundle.js" data-fa-kit-code="abc123"></script>
|
||||
|
||||
<!-- Option 2: the setKitCode() method -->
|
||||
<script type="module">
|
||||
import { setKitCode } from '/path/to/web-awesome/%NPMDIR%/webawesome.js';
|
||||
setBasePath('/path/to/web-awesome/%NPMDIR%');
|
||||
</script>
|
||||
```
|
||||
|
||||
## Cherry Picking
|
||||
|
||||
Cherry picking can be done from [the CDN](#cdn-installation-easiest) or from [npm](#npm-installation). This approach will load only the components you need up front, while limiting the number of files the browser has to download. The disadvantage is that you need to import each individual component.
|
||||
@@ -137,10 +151,10 @@ Cherry picking can be done from [the CDN](#cdn-installation-easiest) or from [np
|
||||
Here's an example that loads only the button component. Again, if you're not using a module resolver, you'll need to adjust the path to point to the folder Web Awesome is in.
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="/path/to/shoelace/%NPMDIR%/themes/default.css" />
|
||||
<link rel="stylesheet" href="/path/to/web-awesome/%NPMDIR%/themes/default.css" />
|
||||
|
||||
<script type="module" data-webawesome="/path/to/shoelace/%NPMDIR%">
|
||||
import '@shoelace-style/shoelace/%NPMDIR%/components/button/button.js';
|
||||
<script type="module" data-webawesome="/path/to/web-awesome/%NPMDIR%">
|
||||
import '/path/to/web-awesome/%NPMDIR%/components/button/button.js';
|
||||
|
||||
// <wa-button> is ready to use!
|
||||
</script>
|
||||
@@ -170,15 +184,15 @@ Now it's time to configure your bundler. Configurations vary for each tool, but
|
||||
Once your bundler is configured, you'll be able to import Web Awesome components and utilities.
|
||||
|
||||
```js
|
||||
import '@shoelace-style/webawesome/%NPMDIR%/themes/default.css';
|
||||
import '@shoelace-style/webawesome/%NPMDIR%/components/button/button.js';
|
||||
import '@shoelace-style/webawesome/%NPMDIR%/components/icon/icon.js';
|
||||
import '@shoelace-style/webawesome/%NPMDIR%/components/input/input.js';
|
||||
import '@shoelace-style/webawesome/%NPMDIR%/components/rating/rating.js';
|
||||
import { setBasePath } from '@shoelace-style/webawesome/%NPMDIR%/utilities/base-path.js';
|
||||
import '/path/to/web-awesome/%NPMDIR%/themes/default.css';
|
||||
import '/path/to/web-awesome/%NPMDIR%/components/button/button.js';
|
||||
import '/path/to/web-awesome/%NPMDIR%/components/icon/icon.js';
|
||||
import '/path/to/web-awesome/%NPMDIR%/components/input/input.js';
|
||||
import '/path/to/web-awesome/%NPMDIR%/components/rating/rating.js';
|
||||
import { setBasePath } from '/path/to/web-awesome/%NPMDIR%/webawesome.js';
|
||||
|
||||
// Set the base path to the folder you copied Web Awesome's assets to
|
||||
setBasePath('/path/to/webawesome/%NPMDIR%');
|
||||
setBasePath('/path/to/web-awesome/%NPMDIR%');
|
||||
|
||||
// <wa-button>, <wa-icon>, <wa-input>, and <wa-rating> are ready to use!
|
||||
```
|
||||
@@ -189,7 +203,7 @@ You'll notice that the CDN links all start with `/%CDNDIR%/<path>` and npm impor
|
||||
|
||||
TL;DR:
|
||||
|
||||
- `@shoelace-style/webawesome/%CDNDIR%` is for CDN users
|
||||
- `@shoelace-style/webawesome/%NPMDIR%` is for npm users
|
||||
- `/path/to/web-awesome/%CDNDIR%` is for CDN users
|
||||
- `/path/to/web-awesome/%NPMDIR%` is for npm users
|
||||
|
||||
This change was introduced in `v2.5.0` to address issues around installations from npm loading multiple versions of libraries (such as the Lit) that Web Awesome uses internally.
|
||||
|
||||
@@ -29,6 +29,8 @@ New versions of Web Awesome are released as-needed and generally occur when a cr
|
||||
- Changed the `sl` prefix to `wa` for Web Awesome, including tags, events, etc.
|
||||
- Changed `primary` variants to `brand` in all components
|
||||
- Changed the internal structure of `<wa-checkbox>` so that the internal checkbox now takes up the full height and width of its wrapping container.
|
||||
- Changed `<wa-tab-group>` to implement a "roving tabindex" and `<wa-tab>` is no longer tabbable by default. This aligns closer to the APG pattern for tabs. [#2041]
|
||||
- Changed `<wa-tooltip>` to no longer wrap content due to accessibility and styling issues. Tooltips are now associated using the `for` attribute + an `id` on the trigger [#123]
|
||||
- Fixed a bug in `<wa-spinner>` that caused it to display incorrectly when zooming in Safari
|
||||
- Improved submenu selection by implementing the [safe triangle](https://www.smashingmagazine.com/2023/08/better-context-menus-safe-triangles/) method [#1550]
|
||||
- Improved tabbing in `<wa-tab-group>` so it uses a roving tab index instead of being able to cycle through each tab
|
||||
|
||||
@@ -201,10 +201,6 @@ This is a tip/informational callout
|
||||
:::warning
|
||||
This is a caution callout
|
||||
:::
|
||||
|
||||
:::danger
|
||||
This is a danger callout
|
||||
:::
|
||||
```
|
||||
|
||||
#### GitHub Issues
|
||||
|
||||
@@ -55,6 +55,18 @@ export default class WaCopyButton extends WebAwesomeElement {
|
||||
@state() isCopying = false;
|
||||
@state() status: 'rest' | 'success' | 'error' = 'rest';
|
||||
|
||||
private get currentLabel() {
|
||||
if (this.status === 'success') {
|
||||
return this.successLabel || this.localize.term('copied');
|
||||
}
|
||||
|
||||
if (this.status === 'error') {
|
||||
return this.errorLabel || this.localize.term('error');
|
||||
}
|
||||
|
||||
return this.copyLabel || this.localize.term('copy');
|
||||
}
|
||||
|
||||
/** The text value to copy. */
|
||||
@property() value = '';
|
||||
|
||||
@@ -156,13 +168,8 @@ export default class WaCopyButton extends WebAwesomeElement {
|
||||
}
|
||||
|
||||
private async showStatus(status: 'success' | 'error') {
|
||||
const copyLabel = this.copyLabel || this.localize.term('copy');
|
||||
const successLabel = this.successLabel || this.localize.term('copied');
|
||||
const errorLabel = this.errorLabel || this.localize.term('error');
|
||||
const iconToShow = status === 'success' ? this.successIcon : this.errorIcon;
|
||||
|
||||
this.tooltip.content = status === 'success' ? successLabel : errorLabel;
|
||||
|
||||
// Show the feedback icon
|
||||
await animateWithClass(this.copyIcon, 'hide');
|
||||
this.copyIcon.hidden = true;
|
||||
@@ -178,50 +185,48 @@ export default class WaCopyButton extends WebAwesomeElement {
|
||||
this.copyIcon.hidden = false;
|
||||
await animateWithClass(this.copyIcon, 'show');
|
||||
|
||||
this.tooltip.content = copyLabel;
|
||||
this.isCopying = false;
|
||||
}, this.feedbackDuration);
|
||||
}
|
||||
|
||||
render() {
|
||||
const copyLabel = this.copyLabel || this.localize.term('copy');
|
||||
|
||||
return html`
|
||||
<wa-tooltip
|
||||
class=${classMap({
|
||||
'copy-button': true,
|
||||
'copy-button--success': this.status === 'success',
|
||||
'copy-button--error': this.status === 'error'
|
||||
})}
|
||||
content=${copyLabel}
|
||||
placement=${this.tooltipPlacement}
|
||||
<button
|
||||
class="copy-button__button"
|
||||
part="button"
|
||||
type="button"
|
||||
id="copy-button"
|
||||
?disabled=${this.disabled}
|
||||
?hoist=${this.hoist}
|
||||
exportparts="
|
||||
base:tooltip__base,
|
||||
base__popup:tooltip__base__popup,
|
||||
base__arrow:tooltip__base__arrow,
|
||||
body:tooltip__body
|
||||
"
|
||||
@click=${this.handleCopy}
|
||||
>
|
||||
<button
|
||||
class="copy-button__button"
|
||||
part="button"
|
||||
type="button"
|
||||
<slot part="copy-icon" name="copy-icon">
|
||||
<wa-icon library="system" name="copy" variant="regular"></wa-icon>
|
||||
</slot>
|
||||
<slot part="success-icon" name="success-icon" variant="solid" hidden>
|
||||
<wa-icon library="system" name="check"></wa-icon>
|
||||
</slot>
|
||||
<slot part="error-icon" name="error-icon" variant="solid" hidden>
|
||||
<wa-icon library="system" name="xmark"></wa-icon>
|
||||
</slot>
|
||||
<wa-tooltip
|
||||
class=${classMap({
|
||||
'copy-button': true,
|
||||
'copy-button--success': this.status === 'success',
|
||||
'copy-button--error': this.status === 'error'
|
||||
})}
|
||||
for="copy-button"
|
||||
placement=${this.tooltipPlacement}
|
||||
?disabled=${this.disabled}
|
||||
@click=${this.handleCopy}
|
||||
?hoist=${this.hoist}
|
||||
exportparts="
|
||||
base:tooltip__base,
|
||||
base__popup:tooltip__base__popup,
|
||||
base__arrow:tooltip__base__arrow,
|
||||
body:tooltip__body
|
||||
"
|
||||
>${this.currentLabel}</wa-tooltip
|
||||
>
|
||||
<slot part="copy-icon" name="copy-icon">
|
||||
<wa-icon library="system" name="copy" variant="regular"></wa-icon>
|
||||
</slot>
|
||||
<slot part="success-icon" name="success-icon" variant="solid" hidden>
|
||||
<wa-icon library="system" name="check"></wa-icon>
|
||||
</slot>
|
||||
<slot part="error-icon" name="error-icon" variant="solid" hidden>
|
||||
<wa-icon library="system" name="xmark"></wa-icon>
|
||||
</slot>
|
||||
</button>
|
||||
</wa-tooltip>
|
||||
</button>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import '../icon/icon.js';
|
||||
import { animate, parseDuration, stopAnimations } from '../../internal/animate.js';
|
||||
import { animate, parseDuration } from '../../internal/animate.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { customElement, property, query } from 'lit/decorators.js';
|
||||
import { html } from 'lit';
|
||||
@@ -144,7 +144,6 @@ export default class WaDetails extends WebAwesomeElement {
|
||||
return;
|
||||
}
|
||||
|
||||
await stopAnimations(this.body);
|
||||
const duration = parseDuration(getComputedStyle(this.body).getPropertyValue('--show-duration'));
|
||||
// We can't animate to 'auto', so use the scroll height for now
|
||||
await animate(
|
||||
@@ -171,7 +170,6 @@ export default class WaDetails extends WebAwesomeElement {
|
||||
return;
|
||||
}
|
||||
|
||||
await stopAnimations(this.body);
|
||||
const duration = parseDuration(getComputedStyle(this.body).getPropertyValue('--hide-duration'));
|
||||
// We can't animate from 'auto', so use the scroll height for now
|
||||
await animate(
|
||||
|
||||
@@ -2,16 +2,49 @@ import { css } from 'lit';
|
||||
|
||||
export default css`
|
||||
:host {
|
||||
--primary-color: currentColor;
|
||||
--primary-opacity: 1;
|
||||
--secondary-color: currentColor;
|
||||
--secondary-opacity: 0.4;
|
||||
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
height: 1em;
|
||||
box-sizing: content-box !important;
|
||||
}
|
||||
|
||||
svg {
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: auto;
|
||||
fill: currentColor;
|
||||
|
||||
.fa-primary {
|
||||
color: var(--primary-color);
|
||||
opacity: var(--primary-opacity);
|
||||
}
|
||||
|
||||
.fa-secondary {
|
||||
color: var(--secondary-color);
|
||||
opacity: var(--secondary-opacity);
|
||||
}
|
||||
}
|
||||
|
||||
/* Normal width */
|
||||
:host(:not([fixed-width])) {
|
||||
max-width: auto;
|
||||
height: 1em;
|
||||
|
||||
svg {
|
||||
width: auto;
|
||||
height: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fixed width */
|
||||
:host([fixed-width]) {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
|
||||
svg {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -34,6 +34,11 @@ interface IconSource {
|
||||
*
|
||||
* @csspart svg - The internal SVG element.
|
||||
* @csspart use - The `<use>` element generated when using `spriteSheet: true`
|
||||
*
|
||||
* @cssproperty [--primary-color=currentColor] - Sets a duotone icon's primary color.
|
||||
* @cssproperty [--primary-opacity=1] - Sets a duotone icon's primary opacity.
|
||||
* @cssproperty [--secondary-color=currentColor] - Sets a duotone icon's secondary color.
|
||||
* @cssproperty [--secondary-opacity=0.4] - Sets a duotone icon's secondary opacity.
|
||||
*/
|
||||
@customElement('wa-icon')
|
||||
export default class WaIcon extends WebAwesomeElement {
|
||||
@@ -41,6 +46,73 @@ export default class WaIcon extends WebAwesomeElement {
|
||||
|
||||
private initialRender = false;
|
||||
|
||||
@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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/** Draws the icon in a fixed-width both. */
|
||||
@property({ attribute: 'fixed-width', type: Boolean, reflect: true }) fixedWidth: false;
|
||||
|
||||
/**
|
||||
* An external URL of an SVG file. Be sure you trust the content you are including, as it will be executed as code and
|
||||
* can result in XSS attacks.
|
||||
*/
|
||||
@property() src?: string;
|
||||
|
||||
/**
|
||||
* An alternate description to use for assistive devices. If omitted, the icon will be considered presentational and
|
||||
* ignored by assistive devices.
|
||||
*/
|
||||
@property() label = '';
|
||||
|
||||
/** The name of a registered custom icon library. */
|
||||
@property({ reflect: true }) library = 'default';
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
watchIcon(this);
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
this.initialRender = true;
|
||||
this.setIcon();
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
unwatchIcon(this);
|
||||
}
|
||||
|
||||
private getIconSource(): IconSource {
|
||||
const library = getIconLibrary(this.library);
|
||||
if (this.name && library) {
|
||||
return {
|
||||
url: library.resolver(this.name, this.family, this.variant),
|
||||
fromLibrary: true
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
url: this.src,
|
||||
fromLibrary: false
|
||||
};
|
||||
}
|
||||
|
||||
/** Given a URL, this function returns the resulting SVG element or an appropriate error symbol. */
|
||||
private async resolveIcon(url: string, library?: IconLibrary): Promise<SVGResult> {
|
||||
let fileData: Response;
|
||||
@@ -90,68 +162,6 @@ 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;
|
||||
|
||||
/**
|
||||
* The family of icons to choose from. For Font Awesome, valid options include `classic`, `sharp`, `duotone`, and
|
||||
* `brands`. Custom icon libraries may or may not use this property.
|
||||
*/
|
||||
@property({ reflect: true }) 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. Custom icon libraries may or may not use this property.
|
||||
*/
|
||||
@property({ reflect: true }) variant: string;
|
||||
|
||||
/**
|
||||
* An external URL of an SVG file. Be sure you trust the content you are including, as it will be executed as code and
|
||||
* can result in XSS attacks.
|
||||
*/
|
||||
@property() src?: string;
|
||||
|
||||
/**
|
||||
* An alternate description to use for assistive devices. If omitted, the icon will be considered presentational and
|
||||
* ignored by assistive devices.
|
||||
*/
|
||||
@property() label = '';
|
||||
|
||||
/** The name of a registered custom icon library. */
|
||||
@property({ reflect: true }) library = 'default';
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
watchIcon(this);
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
this.initialRender = true;
|
||||
this.setIcon();
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
unwatchIcon(this);
|
||||
}
|
||||
|
||||
private getIconSource(): IconSource {
|
||||
const library = getIconLibrary(this.library);
|
||||
if (this.name && library) {
|
||||
return {
|
||||
url: library.resolver(this.name, this.family, this.variant),
|
||||
fromLibrary: true
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
url: this.src,
|
||||
fromLibrary: false
|
||||
};
|
||||
}
|
||||
|
||||
@watch('label')
|
||||
handleLabelChange() {
|
||||
const hasLabel = typeof this.label === 'string' && this.label.length > 0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
|
||||
import { aTimeout, elementUpdated, expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
|
||||
import { aTimeout, expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
|
||||
import { isSafari } from '../../internal/test.js';
|
||||
import { runFormControlBaseTests } from '../../internal/test/form-control-base-tests.js';
|
||||
import { sendKeys } from '@web/test-runner-commands'; // must come from the same module
|
||||
@@ -47,8 +47,6 @@ describe('<wa-input>', async () => {
|
||||
expect(el.enterkeyhint).to.be.undefined;
|
||||
expect(el.spellcheck).to.be.true;
|
||||
expect(el.inputmode).to.be.undefined;
|
||||
expect(el.valueAsDate).to.be.null;
|
||||
expect(isNaN(el.valueAsNumber)).to.be.true;
|
||||
});
|
||||
|
||||
it('should have title if title attribute is set', async () => {
|
||||
@@ -65,74 +63,6 @@ describe('<wa-input>', async () => {
|
||||
expect(input.disabled).to.be.true;
|
||||
});
|
||||
|
||||
describe('value methods', () => {
|
||||
it('should set the value as a date when using valueAsDate', async () => {
|
||||
const el = document.createElement(`wa-input`);
|
||||
el.type = 'date';
|
||||
const today = new Date();
|
||||
|
||||
el.valueAsDate = today;
|
||||
|
||||
// Test before we render in the dom
|
||||
expect(el.value).to.equal(today.toISOString().split('T')[0]);
|
||||
expect(el.valueAsDate.toISOString().split('T')[0]).to.equal(today.toISOString().split('T')[0]);
|
||||
|
||||
document.body.appendChild(el);
|
||||
|
||||
await elementUpdated(el);
|
||||
|
||||
// Update valueAsDate after we render to make sure it reflects properly
|
||||
el.valueAsDate = null;
|
||||
|
||||
await elementUpdated(el);
|
||||
|
||||
expect(el.value).to.equal('');
|
||||
expect(el.valueAsDate).to.equal(null);
|
||||
|
||||
// Update again with a real date to make sure it works
|
||||
el.valueAsDate = today;
|
||||
|
||||
await elementUpdated(el);
|
||||
|
||||
expect(el.value).to.equal(today.toISOString().split('T')[0]);
|
||||
expect(el.valueAsDate.toISOString().split('T')[0]).to.equal(today.toISOString().split('T')[0]);
|
||||
|
||||
el.remove();
|
||||
});
|
||||
|
||||
it('should set the value as a number when using valueAsNumber', async () => {
|
||||
const el = document.createElement(`wa-input`);
|
||||
el.type = 'number';
|
||||
const num = 12345;
|
||||
|
||||
el.valueAsNumber = num;
|
||||
|
||||
expect(el.value).to.equal(num.toString());
|
||||
expect(el.valueAsNumber).to.equal(num);
|
||||
|
||||
document.body.appendChild(el);
|
||||
|
||||
await elementUpdated(el);
|
||||
|
||||
// Wait for render, then update the value
|
||||
const otherNum = 4567;
|
||||
el.valueAsNumber = otherNum;
|
||||
|
||||
await elementUpdated(el);
|
||||
|
||||
expect(el.value).to.equal(otherNum.toString());
|
||||
expect(el.valueAsNumber).to.equal(otherNum);
|
||||
|
||||
// Re-set valueAsNumber and make sure it updates.
|
||||
el.valueAsNumber = num;
|
||||
await elementUpdated(el);
|
||||
expect(el.value).to.equal(num.toString());
|
||||
expect(el.valueAsNumber).to.equal(num);
|
||||
|
||||
el.remove();
|
||||
});
|
||||
});
|
||||
|
||||
it('should focus the input when clicking on the label', async () => {
|
||||
const el = await fixture<WaInput>(html` <wa-input label="Name"></wa-input> `);
|
||||
const label = el.shadowRoot!.querySelector('[part~="form-control-label"]')!;
|
||||
|
||||
@@ -137,7 +137,6 @@ export default class WaRadioButton extends WebAwesomeFormAssociatedElement {
|
||||
aria-disabled=${this.disabled}
|
||||
type="button"
|
||||
value=${ifDefined(this.value)}
|
||||
tabindex="${this.checked ? '0' : '-1'}"
|
||||
@blur=${this.handleBlur}
|
||||
@focus=${this.handleFocus}
|
||||
@click=${this.handleClick}
|
||||
|
||||
@@ -120,7 +120,7 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
radio.checked = false;
|
||||
|
||||
if (!hasButtonGroup) {
|
||||
radio.tabIndex = -1;
|
||||
radio.setAttribute('tabindex', '-1');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,10 +169,10 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
const buttonRadio = radios[0].shadowRoot?.querySelector('button');
|
||||
|
||||
if (buttonRadio) {
|
||||
buttonRadio.tabIndex = 0;
|
||||
buttonRadio.setAttribute('tabindex', '0');
|
||||
}
|
||||
} else {
|
||||
radios[0].tabIndex = 0;
|
||||
radios[0].setAttribute('tabindex', '0');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
radio.checked = false;
|
||||
|
||||
if (!hasButtonGroup) {
|
||||
radio.tabIndex = -1;
|
||||
radio.setAttribute('tabindex', '-1');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -254,7 +254,7 @@ export default class WaRadioGroup extends WebAwesomeFormAssociatedElement {
|
||||
radios[index].checked = true;
|
||||
|
||||
if (!hasButtonGroup) {
|
||||
radios[index].tabIndex = 0;
|
||||
radios[index].setAttribute('tabindex', '0');
|
||||
radios[index].focus();
|
||||
} else {
|
||||
radios[index].shadowRoot!.querySelector('button')!.focus();
|
||||
|
||||
@@ -55,6 +55,7 @@ export default class WaTabGroup extends WebAwesomeElement {
|
||||
private mutationObserver: MutationObserver;
|
||||
private resizeObserver: ResizeObserver;
|
||||
private tabs: WaTab[] = [];
|
||||
private focusableTabs: WaTab[] = [];
|
||||
private panels: WaTabPanel[] = [];
|
||||
|
||||
@query('.tab-group') tabGroup: HTMLElement;
|
||||
@@ -131,13 +132,11 @@ export default class WaTabGroup extends WebAwesomeElement {
|
||||
this.resizeObserver.unobserve(this.nav);
|
||||
}
|
||||
|
||||
private getAllTabs(options: { includeDisabled: boolean } = { includeDisabled: true }) {
|
||||
private getAllTabs() {
|
||||
const slot = this.shadowRoot!.querySelector<HTMLSlotElement>('slot[name="nav"]')!;
|
||||
|
||||
return [...(slot.assignedElements() as WaTab[])].filter(el => {
|
||||
return options.includeDisabled
|
||||
? el.tagName.toLowerCase() === 'wa-tab'
|
||||
: el.tagName.toLowerCase() === 'wa-tab' && !el.disabled;
|
||||
return el.tagName.toLowerCase() === 'wa-tab';
|
||||
});
|
||||
}
|
||||
|
||||
@@ -180,48 +179,51 @@ export default class WaTabGroup extends WebAwesomeElement {
|
||||
this.setActiveTab(tab, { scrollBehavior: 'smooth' });
|
||||
event.preventDefault();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Move focus left or right
|
||||
if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End'].includes(event.key)) {
|
||||
const activeEl = this.tabs.find(t => t.matches(':focus'));
|
||||
const isRtl = this.matches(':dir(rtl)');
|
||||
let nextTab: null | WaTab = null;
|
||||
|
||||
if (activeEl?.tagName.toLowerCase() === 'wa-tab') {
|
||||
let index = this.tabs.indexOf(activeEl);
|
||||
|
||||
if (event.key === 'Home') {
|
||||
index = 0;
|
||||
nextTab = this.focusableTabs[0];
|
||||
} else if (event.key === 'End') {
|
||||
index = this.tabs.length - 1;
|
||||
nextTab = this.focusableTabs[this.focusableTabs.length - 1];
|
||||
} else if (
|
||||
(['top', 'bottom'].includes(this.placement) && event.key === (isRtl ? 'ArrowRight' : 'ArrowLeft')) ||
|
||||
(['start', 'end'].includes(this.placement) && event.key === 'ArrowUp')
|
||||
) {
|
||||
index--;
|
||||
const currentIndex = this.tabs.findIndex(el => el === activeEl);
|
||||
nextTab = this.findNextFocusableTab(currentIndex, 'backward');
|
||||
} else if (
|
||||
(['top', 'bottom'].includes(this.placement) && event.key === (isRtl ? 'ArrowLeft' : 'ArrowRight')) ||
|
||||
(['start', 'end'].includes(this.placement) && event.key === 'ArrowDown')
|
||||
) {
|
||||
index++;
|
||||
const currentIndex = this.tabs.findIndex(el => el === activeEl);
|
||||
nextTab = this.findNextFocusableTab(currentIndex, 'forward');
|
||||
}
|
||||
|
||||
if (index < 0) {
|
||||
index = this.tabs.length - 1;
|
||||
if (!nextTab) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (index > this.tabs.length - 1) {
|
||||
index = 0;
|
||||
}
|
||||
|
||||
this.tabs[index].focus({ preventScroll: true });
|
||||
nextTab.tabIndex = 0;
|
||||
nextTab.focus({ preventScroll: true });
|
||||
|
||||
if (this.activation === 'auto') {
|
||||
this.setActiveTab(this.tabs[index], { scrollBehavior: 'smooth' });
|
||||
this.setActiveTab(nextTab, { scrollBehavior: 'smooth' });
|
||||
} else {
|
||||
this.tabs.forEach(tabEl => {
|
||||
tabEl.tabIndex = tabEl === nextTab ? 0 : -1;
|
||||
});
|
||||
}
|
||||
|
||||
if (['top', 'bottom'].includes(this.placement)) {
|
||||
scrollIntoView(this.tabs[index], this.nav, 'horizontal');
|
||||
scrollIntoView(nextTab, this.nav, 'horizontal');
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
@@ -229,6 +231,34 @@ export default class WaTabGroup extends WebAwesomeElement {
|
||||
}
|
||||
}
|
||||
|
||||
private findNextFocusableTab(currentIndex: number, direction: 'forward' | 'backward') {
|
||||
let nextTab = null;
|
||||
const iterator = direction === 'forward' ? 1 : -1;
|
||||
let nextIndex = currentIndex + iterator;
|
||||
|
||||
while (currentIndex < this.tabs.length) {
|
||||
nextTab = this.tabs[nextIndex] || null;
|
||||
|
||||
if (nextTab === null) {
|
||||
// This is where wrapping happens. If we're moving forward and get to the end, then we jump to the beginning. If we're moving backward and get to the start, then we jump to the end.
|
||||
if (direction === 'forward') {
|
||||
nextTab = this.focusableTabs[0];
|
||||
} else {
|
||||
nextTab = this.focusableTabs[this.focusableTabs.length - 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!nextTab.disabled) {
|
||||
break;
|
||||
}
|
||||
|
||||
nextIndex += iterator;
|
||||
}
|
||||
|
||||
return nextTab;
|
||||
}
|
||||
|
||||
private handleScrollToStart() {
|
||||
this.nav.scroll({
|
||||
left:
|
||||
@@ -262,7 +292,11 @@ export default class WaTabGroup extends WebAwesomeElement {
|
||||
this.activeTab = tab;
|
||||
|
||||
// Sync active tab and panel
|
||||
this.tabs.forEach(el => (el.active = el === this.activeTab));
|
||||
this.tabs.forEach(el => {
|
||||
el.active = el === this.activeTab;
|
||||
el.tabIndex = el === this.activeTab ? 0 : -1;
|
||||
});
|
||||
|
||||
this.panels.forEach(el => (el.active = el.name === this.activeTab?.panel));
|
||||
|
||||
if (['top', 'bottom'].includes(this.placement)) {
|
||||
@@ -293,7 +327,8 @@ export default class WaTabGroup extends WebAwesomeElement {
|
||||
|
||||
// This stores tabs and panels so we can refer to a cache instead of calling querySelectorAll() multiple times.
|
||||
private syncTabsAndPanels() {
|
||||
this.tabs = this.getAllTabs({ includeDisabled: false });
|
||||
this.tabs = this.getAllTabs();
|
||||
this.focusableTabs = this.tabs.filter(el => !el.disabled);
|
||||
this.panels = this.getAllPanels();
|
||||
|
||||
// After updating, show or hide scroll controls as needed
|
||||
@@ -391,9 +426,3 @@ declare global {
|
||||
'wa-tab-group': WaTabGroup;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'wa-tab-group': WaTabGroup;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,43 +21,30 @@ export default css`
|
||||
var(--transition-speed) color;
|
||||
}
|
||||
|
||||
.tab:hover:not(.tab--disabled) {
|
||||
:host(:hover:not([disabled])) .tab {
|
||||
color: var(--wa-color-neutral-text-on-surface);
|
||||
}
|
||||
|
||||
.tab:focus {
|
||||
outline: none;
|
||||
:host(:focus) {
|
||||
outline: transparent;
|
||||
}
|
||||
|
||||
.tab:focus-visible {
|
||||
:host(:focus-visible) .tab {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: calc(-1 * var(--wa-border-width-l) - var(--wa-focus-ring-offset));
|
||||
}
|
||||
|
||||
.tab.tab--active:not(.tab--disabled) {
|
||||
:host([active]:not([disabled])) .tab {
|
||||
color: var(--wa-color-brand-text-on-surface);
|
||||
}
|
||||
|
||||
.tab.tab--closable {
|
||||
padding-inline-end: var(--wa-space-s);
|
||||
}
|
||||
|
||||
.tab.tab--disabled {
|
||||
:host([disabled]) .tab {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.tab__close-button {
|
||||
font-size: var(--wa-font-size-m);
|
||||
margin-inline-start: var(--wa-space-s);
|
||||
}
|
||||
|
||||
.tab__close-button::part(base) {
|
||||
padding: var(--wa-space-3xs);
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.tab.tab--active:not(.tab--disabled) {
|
||||
:host([active]:not([disabled])) {
|
||||
outline: solid 1px transparent;
|
||||
outline-offset: -3px;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ describe('<wa-tab>', () => {
|
||||
expect(el.getAttribute('role')).to.equal('tab');
|
||||
expect(el.getAttribute('aria-disabled')).to.equal('false');
|
||||
expect(el.getAttribute('aria-selected')).to.equal('false');
|
||||
expect(base.getAttribute('tabindex')).to.equal('-1');
|
||||
expect(el.getAttribute('tabindex')).to.equal('0');
|
||||
expect(base.getAttribute('class')).to.equal(' tab ');
|
||||
expect(el.active).to.equal(false);
|
||||
expect(el.disabled).to.equal(false);
|
||||
@@ -33,7 +33,7 @@ describe('<wa-tab>', () => {
|
||||
expect(el.disabled).to.equal(true);
|
||||
expect(el.getAttribute('aria-disabled')).to.equal('true');
|
||||
expect(base.getAttribute('class')).to.equal(' tab tab--disabled ');
|
||||
expect(base.getAttribute('tabindex')).to.equal('-1');
|
||||
expect(el.getAttribute('tabindex')).to.equal('-1');
|
||||
});
|
||||
|
||||
it('should set active tab by attribute', async () => {
|
||||
@@ -44,33 +44,6 @@ describe('<wa-tab>', () => {
|
||||
expect(el.active).to.equal(true);
|
||||
expect(el.getAttribute('aria-selected')).to.equal('true');
|
||||
expect(base.getAttribute('class')).to.equal(' tab tab--active ');
|
||||
expect(base.getAttribute('tabindex')).to.equal('0');
|
||||
});
|
||||
|
||||
describe('focus', () => {
|
||||
it('should focus inner div', async () => {
|
||||
const el = await fixture<WaTab>(html` <wa-tab>Test</wa-tab> `);
|
||||
|
||||
const base = el.shadowRoot!.querySelector<HTMLElement>('[part~="base"]')!;
|
||||
|
||||
el.focus();
|
||||
await el.updateComplete;
|
||||
|
||||
expect(el.shadowRoot!.activeElement).to.equal(base);
|
||||
});
|
||||
});
|
||||
|
||||
describe('blur', () => {
|
||||
it('should blur inner div', async () => {
|
||||
const el = await fixture<WaTab>(html` <wa-tab>Test</wa-tab> `);
|
||||
|
||||
el.focus();
|
||||
await el.updateComplete;
|
||||
|
||||
el.blur();
|
||||
await el.updateComplete;
|
||||
|
||||
expect(el.shadowRoot!.activeElement).to.equal(null);
|
||||
});
|
||||
expect(el.getAttribute('tabindex')).to.equal('0');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -39,6 +39,8 @@ export default class WaTab extends WebAwesomeElement {
|
||||
/** Disables the tab and prevents selection. */
|
||||
@property({ type: Boolean, reflect: true }) disabled = false;
|
||||
|
||||
tabIndex = 0;
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.setAttribute('role', 'tab');
|
||||
@@ -52,16 +54,12 @@ export default class WaTab extends WebAwesomeElement {
|
||||
@watch('disabled')
|
||||
handleDisabledChange() {
|
||||
this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
|
||||
}
|
||||
|
||||
/** Sets focus to the tab. */
|
||||
focus(options?: FocusOptions) {
|
||||
this.tab.focus(options);
|
||||
}
|
||||
|
||||
/** Removes focus from the tab. */
|
||||
blur() {
|
||||
this.tab.blur();
|
||||
if (this.disabled && !this.active) {
|
||||
this.tabIndex = -1;
|
||||
} else {
|
||||
this.tabIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -76,7 +74,6 @@ export default class WaTab extends WebAwesomeElement {
|
||||
'tab--active': this.active,
|
||||
'tab--disabled': this.disabled
|
||||
})}
|
||||
tabindex=${this.active && !this.disabled ? '0' : '-1'}
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
@@ -89,9 +86,3 @@ declare global {
|
||||
'wa-tab': WaTab;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'wa-tab': WaTab;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@ export default css`
|
||||
:host {
|
||||
--max-width: 20rem;
|
||||
|
||||
display: contents;
|
||||
display: inline-block;
|
||||
|
||||
/** These styles are added so we dont interfere in the DOM. */
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
|
||||
@@ -5,9 +5,8 @@ import type WaTooltip from './tooltip.js';
|
||||
describe('<wa-tooltip>', () => {
|
||||
it('should be visible with the open attribute', async () => {
|
||||
const el = await fixture<WaTooltip>(html`
|
||||
<wa-tooltip content="This is a tooltip" open>
|
||||
<wa-button>Hover Me</wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip open for="wa-button">This is a tooltip</wa-tooltip>
|
||||
<wa-button id="wa-button">Hover Me</wa-button>
|
||||
`);
|
||||
const body = el.shadowRoot!.querySelector<HTMLElement>('[part~="body"]')!;
|
||||
|
||||
@@ -16,9 +15,8 @@ describe('<wa-tooltip>', () => {
|
||||
|
||||
it('should not be visible without the open attribute', async () => {
|
||||
const el = await fixture<WaTooltip>(html`
|
||||
<wa-tooltip content="This is a tooltip">
|
||||
<wa-button>Hover Me</wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip for="wa-button">This is a tooltip</wa-tooltip>
|
||||
<wa-button id="wa-button">Hover Me</wa-button>
|
||||
`);
|
||||
const body = el.shadowRoot!.querySelector<HTMLElement>('[part~="body"]')!;
|
||||
|
||||
@@ -27,9 +25,8 @@ describe('<wa-tooltip>', () => {
|
||||
|
||||
it('should emit wa-show and wa-after-show when calling show()', async () => {
|
||||
const el = await fixture<WaTooltip>(html`
|
||||
<wa-tooltip content="This is a tooltip">
|
||||
<wa-button>Hover Me</wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip for="wa-button">This is a tooltip</wa-tooltip>
|
||||
<wa-button id="wa-button">Hover Me</wa-button>
|
||||
`);
|
||||
const body = el.shadowRoot!.querySelector<HTMLElement>('[part~="body"]')!;
|
||||
const showHandler = sinon.spy();
|
||||
@@ -49,9 +46,8 @@ describe('<wa-tooltip>', () => {
|
||||
|
||||
it('should emit wa-hide and wa-after-hide when calling hide()', async () => {
|
||||
const el = await fixture<WaTooltip>(html`
|
||||
<wa-tooltip content="This is a tooltip" open>
|
||||
<wa-button>Hover Me</wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip for="wa-button" open>This is a tooltip</wa-tooltip>
|
||||
<wa-button id="wa-button">Hover Me</wa-button>
|
||||
`);
|
||||
const body = el.shadowRoot!.querySelector<HTMLElement>('[part~="body"]')!;
|
||||
const hideHandler = sinon.spy();
|
||||
@@ -71,9 +67,8 @@ describe('<wa-tooltip>', () => {
|
||||
|
||||
it('should emit wa-show and wa-after-show when setting open = true', async () => {
|
||||
const el = await fixture<WaTooltip>(html`
|
||||
<wa-tooltip content="This is a tooltip">
|
||||
<wa-button>Hover Me</wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip for="wa-button">This is a tooltip</wa-tooltip>
|
||||
<wa-button id="wa-button">Hover Me</wa-button>
|
||||
`);
|
||||
const body = el.shadowRoot!.querySelector<HTMLElement>('[part~="body"]')!;
|
||||
const showHandler = sinon.spy();
|
||||
@@ -93,9 +88,8 @@ describe('<wa-tooltip>', () => {
|
||||
|
||||
it('should emit wa-hide and wa-after-hide when setting open = false', async () => {
|
||||
const el = await fixture<WaTooltip>(html`
|
||||
<wa-tooltip content="This is a tooltip" open>
|
||||
<wa-button>Hover Me</wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip for="wa-button" open>This is a tooltip</wa-tooltip>
|
||||
<wa-button id="wa-button">Hover Me</wa-button>
|
||||
`);
|
||||
const body = el.shadowRoot!.querySelector<HTMLElement>('[part~="body"]')!;
|
||||
const hideHandler = sinon.spy();
|
||||
@@ -115,9 +109,8 @@ describe('<wa-tooltip>', () => {
|
||||
|
||||
it('should hide the tooltip when tooltip is visible and disabled becomes true', async () => {
|
||||
const el = await fixture<WaTooltip>(html`
|
||||
<wa-tooltip content="This is a tooltip" open>
|
||||
<wa-button>Hover Me</wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip for="wa-button" open>This is a tooltip</wa-tooltip>
|
||||
<wa-button id="wa-button">Hover Me</wa-button>
|
||||
`);
|
||||
const body = el.shadowRoot!.querySelector<HTMLElement>('[part~="body"]')!;
|
||||
const hideHandler = sinon.spy();
|
||||
@@ -137,9 +130,8 @@ describe('<wa-tooltip>', () => {
|
||||
|
||||
it('should show when open initially', async () => {
|
||||
const el = await fixture<WaTooltip>(html`
|
||||
<wa-tooltip content="This is a tooltip" open>
|
||||
<wa-button>Hover Me</wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip for="wa-button" open>This is a tooltip</wa-tooltip>
|
||||
<wa-button id="wa-button">Hover Me</wa-button>
|
||||
`);
|
||||
const body = el.shadowRoot!.querySelector<HTMLElement>('[part~="body"]')!;
|
||||
await el.updateComplete;
|
||||
@@ -149,9 +141,8 @@ describe('<wa-tooltip>', () => {
|
||||
|
||||
it('should not accept user selection on the tooltip', async () => {
|
||||
const el = await fixture<WaTooltip>(html`
|
||||
<wa-tooltip content="This is a tooltip" open>
|
||||
<wa-button>Hover Me</wa-button>
|
||||
</wa-tooltip>
|
||||
<wa-tooltip for="wa-button" open>This is a tooltip</wa-tooltip>
|
||||
<wa-button id="wa-button">Hover Me</wa-button>
|
||||
`);
|
||||
|
||||
const tooltipBody = el.shadowRoot!.querySelector('.tooltip__body')!;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { animateWithClass, stopAnimations } from '../../internal/animate.js';
|
||||
import { animateWithClass } from '../../internal/animate.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { customElement, property, query } from 'lit/decorators.js';
|
||||
import { customElement, property, query, state } from 'lit/decorators.js';
|
||||
import { html } from 'lit';
|
||||
import { uniqueId } from '../../internal/math.js';
|
||||
import { WaAfterHideEvent } from '../../events/after-hide.js';
|
||||
import { WaAfterShowEvent } from '../../events/after-show.js';
|
||||
import { WaHideEvent } from '../../events/hide.js';
|
||||
@@ -22,8 +23,7 @@ import type { CSSResultGroup } from 'lit';
|
||||
*
|
||||
* @dependency wa-popup
|
||||
*
|
||||
* @slot - The tooltip's target element. Avoid slotting in more than one element, as subsequent ones will be ignored.
|
||||
* @slot content - The content to render in the tooltip. Alternatively, you can use the `content` attribute.
|
||||
* @slot - The tooltip's default slot where any content should live. Interactive content should be avoided.
|
||||
*
|
||||
* @event wa-show - Emitted when the tooltip begins to show.
|
||||
* @event wa-after-show - Emitted after the tooltip has shown and all animations are complete.
|
||||
@@ -51,9 +51,6 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
@query('.tooltip__body') body: HTMLElement;
|
||||
@query('wa-popup') popup: WaPopup;
|
||||
|
||||
/** The tooltip's content. If you need to display HTML, use the `content` slot instead. */
|
||||
@property() content = '';
|
||||
|
||||
/**
|
||||
* The preferred placement of the tooltip. Note that the actual placement may vary as needed to keep the tooltip
|
||||
* inside of the viewport.
|
||||
@@ -104,19 +101,31 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
*/
|
||||
@property({ type: Boolean }) hoist = false;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.addEventListener('blur', this.handleBlur, true);
|
||||
this.addEventListener('focus', this.handleFocus, true);
|
||||
this.addEventListener('click', this.handleClick);
|
||||
this.addEventListener('mouseover', this.handleMouseOver);
|
||||
this.addEventListener('mouseout', this.handleMouseOut);
|
||||
@property() for: null | string = null;
|
||||
|
||||
@state() anchor: null | Element = null;
|
||||
|
||||
private eventController = new AbortController();
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
|
||||
// If the user doesn't give us an id, generate one.
|
||||
if (!this.id) {
|
||||
this.id = uniqueId('wa-tooltip-');
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
// Cleanup this event in case the tooltip is removed while open
|
||||
this.closeWatcher?.destroy();
|
||||
document.removeEventListener('keydown', this.handleDocumentKeyDown);
|
||||
this.eventController.abort();
|
||||
|
||||
if (this.anchor) {
|
||||
const label = this.anchor.getAttribute('aria-labelledby') || '';
|
||||
this.anchor.setAttribute('aria-labelledby', label.replace(this.id, ''));
|
||||
}
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
@@ -162,6 +171,7 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
private handleMouseOver = () => {
|
||||
if (this.hasTrigger('hover')) {
|
||||
clearTimeout(this.hoverTimeout);
|
||||
|
||||
this.hoverTimeout = window.setTimeout(() => this.show(), this.showDelay);
|
||||
}
|
||||
};
|
||||
@@ -200,12 +210,11 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
this.hide();
|
||||
};
|
||||
} else {
|
||||
document.addEventListener('keydown', this.handleDocumentKeyDown);
|
||||
document.addEventListener('keydown', this.handleDocumentKeyDown, { signal: this.eventController.signal });
|
||||
}
|
||||
|
||||
this.body.hidden = false;
|
||||
this.popup.active = true;
|
||||
await stopAnimations(this.popup.popup);
|
||||
await animateWithClass(this.popup.popup, 'show-with-scale');
|
||||
this.popup.reposition();
|
||||
|
||||
@@ -222,7 +231,6 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
this.closeWatcher?.destroy();
|
||||
document.removeEventListener('keydown', this.handleDocumentKeyDown);
|
||||
|
||||
await stopAnimations(this.popup.popup);
|
||||
await animateWithClass(this.popup.popup, 'hide-with-scale');
|
||||
this.popup.active = false;
|
||||
this.body.hidden = true;
|
||||
@@ -231,7 +239,60 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
}
|
||||
}
|
||||
|
||||
@watch(['content', 'distance', 'hoist', 'placement', 'skidding'])
|
||||
@watch('for')
|
||||
handleForChange() {
|
||||
const rootNode = this.getRootNode() as Document | ShadowRoot | null;
|
||||
|
||||
if (!rootNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newAnchor = this.for ? rootNode.querySelector(`#${this.for}`) : null;
|
||||
const oldAnchor = this.anchor;
|
||||
|
||||
if (newAnchor === oldAnchor) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { signal } = this.eventController;
|
||||
|
||||
// "\\b" is a space boundary, used for making sure we dont add the tooltip to aria-labelledby twice.
|
||||
const labelRegex = new RegExp(`\\b${this.id}\\b`);
|
||||
|
||||
if (newAnchor) {
|
||||
/**
|
||||
* We use `aria-labelledby` because it seems to have the most consistent screenreader experience.
|
||||
* Particularly for our "special" focusable elements like `<wa-button>`, `<wa-input>` etc.
|
||||
* aria-describedby usually in some screenreaders is required to be on the actually focusable element,
|
||||
* whereas with `aria-labelledby` it'll still read on first focus. The APG does and WAI-ARIA does recommend aria-describedby
|
||||
* so perhaps once we have cross-root aria, we can revisit this decision.
|
||||
*/
|
||||
const currentLabel = newAnchor.getAttribute('aria-labelledby') || '';
|
||||
if (!currentLabel.match(labelRegex)) {
|
||||
newAnchor.setAttribute('aria-labelledby', currentLabel + ' ' + this.id);
|
||||
}
|
||||
|
||||
newAnchor.addEventListener('blur', this.handleBlur, { capture: true, signal });
|
||||
newAnchor.addEventListener('focus', this.handleFocus, { capture: true, signal });
|
||||
newAnchor.addEventListener('click', this.handleClick, { signal });
|
||||
newAnchor.addEventListener('mouseover', this.handleMouseOver, { signal });
|
||||
newAnchor.addEventListener('mouseout', this.handleMouseOut, { signal });
|
||||
}
|
||||
|
||||
if (oldAnchor) {
|
||||
const label = oldAnchor.getAttribute('aria-labelledby') || '';
|
||||
oldAnchor.setAttribute('aria-labelledby', label.replace(labelRegex, ''));
|
||||
oldAnchor.removeEventListener('blur', this.handleBlur, { capture: true });
|
||||
oldAnchor.removeEventListener('focus', this.handleFocus, { capture: true });
|
||||
oldAnchor.removeEventListener('click', this.handleClick);
|
||||
oldAnchor.removeEventListener('mouseover', this.handleMouseOver);
|
||||
oldAnchor.removeEventListener('mouseout', this.handleMouseOut);
|
||||
}
|
||||
|
||||
this.anchor = newAnchor;
|
||||
}
|
||||
|
||||
@watch(['distance', 'hoist', 'placement', 'skidding'])
|
||||
async handleOptionsChange() {
|
||||
if (this.hasUpdated) {
|
||||
await this.updateComplete;
|
||||
@@ -266,12 +327,6 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
return waitForEvent(this, 'wa-after-hide');
|
||||
}
|
||||
|
||||
//
|
||||
// NOTE: Tooltip is a bit unique in that we're using aria-live instead of aria-labelledby to trick screen readers into
|
||||
// announcing the content. It works really well, but it violates an accessibility rule. We're also adding the
|
||||
// aria-describedby attribute to a slot, which is required by `<wa-popup>` to correctly locate the first assigned
|
||||
// element, otherwise positioning is incorrect.
|
||||
//
|
||||
render() {
|
||||
return html`
|
||||
<wa-popup
|
||||
@@ -292,13 +347,10 @@ export default class WaTooltip extends WebAwesomeElement {
|
||||
shift
|
||||
arrow
|
||||
hover-bridge
|
||||
.anchor=${this.anchor}
|
||||
>
|
||||
${'' /* eslint-disable-next-line lit-a11y/no-aria-slot */}
|
||||
<slot slot="anchor" aria-describedby="tooltip"></slot>
|
||||
|
||||
${'' /* eslint-disable-next-line lit-a11y/accessible-name */}
|
||||
<div part="body" id="tooltip" class="tooltip__body" role="tooltip" aria-live=${this.open ? 'polite' : 'off'}>
|
||||
<slot name="content">${this.content}</slot>
|
||||
<div part="body" class="tooltip__body">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</wa-popup>
|
||||
`;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import '../checkbox/checkbox.js';
|
||||
import '../icon/icon.js';
|
||||
import '../spinner/spinner.js';
|
||||
import { animate, parseDuration, stopAnimations } from '../../internal/animate.js';
|
||||
import { animate, parseDuration } from '../../internal/animate.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { customElement, property, query, state } from 'lit/decorators.js';
|
||||
import { html } from 'lit';
|
||||
@@ -122,8 +122,6 @@ export default class WaTreeItem extends WebAwesomeElement {
|
||||
private async animateCollapse() {
|
||||
this.dispatchEvent(new WaCollapseEvent());
|
||||
|
||||
await stopAnimations(this.childrenContainer);
|
||||
|
||||
const duration = parseDuration(getComputedStyle(this.childrenContainer).getPropertyValue('--hide-duration'));
|
||||
await animate(
|
||||
this.childrenContainer,
|
||||
@@ -159,7 +157,6 @@ export default class WaTreeItem extends WebAwesomeElement {
|
||||
private async animateExpand() {
|
||||
this.dispatchEvent(new WaExpandEvent());
|
||||
|
||||
await stopAnimations(this.childrenContainer);
|
||||
this.childrenContainer.hidden = false;
|
||||
// We can't animate to 'auto', so use the scroll height for now
|
||||
const duration = parseDuration(getComputedStyle(this.childrenContainer).getPropertyValue('--show-duration'));
|
||||
|
||||
@@ -11,31 +11,46 @@ export async function animate(el: Element, keyframes: Keyframe[], options?: Keyf
|
||||
*/
|
||||
export function animateWithClass(el: Element, className: string) {
|
||||
return new Promise<void>(resolve => {
|
||||
el.classList.remove(className);
|
||||
const controller = new AbortController();
|
||||
const { signal } = controller;
|
||||
|
||||
el.classList.add(className);
|
||||
el.addEventListener(
|
||||
'animationend',
|
||||
() => {
|
||||
el.classList.remove(className);
|
||||
resolve();
|
||||
controller.abort();
|
||||
},
|
||||
{ once: true }
|
||||
{ once: true, signal }
|
||||
);
|
||||
|
||||
el.addEventListener(
|
||||
'animationcancel',
|
||||
() => {
|
||||
el.classList.remove(className);
|
||||
resolve();
|
||||
controller.abort();
|
||||
},
|
||||
{ once: true, signal }
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/** Parses a CSS duration and returns the number of milliseconds. */
|
||||
export function parseDuration(delay: number | string) {
|
||||
delay = delay.toString().toLowerCase();
|
||||
export function parseDuration(duration: number | string) {
|
||||
duration = duration.toString().toLowerCase();
|
||||
|
||||
if (delay.indexOf('ms') > -1) {
|
||||
return parseFloat(delay);
|
||||
if (duration.indexOf('ms') > -1) {
|
||||
return parseFloat(duration) || 0;
|
||||
}
|
||||
|
||||
if (delay.indexOf('s') > -1) {
|
||||
return parseFloat(delay) * 1000;
|
||||
if (duration.indexOf('s') > -1) {
|
||||
return (parseFloat(duration) || 0) * 1000;
|
||||
}
|
||||
|
||||
return parseFloat(delay);
|
||||
return parseFloat(duration) || 0;
|
||||
}
|
||||
|
||||
/** Tells if the user has enabled the "reduced motion" setting in their browser or OS. */
|
||||
@@ -43,20 +58,3 @@ export function prefersReducedMotion() {
|
||||
const query = window.matchMedia('(prefers-reduced-motion: reduce)');
|
||||
return query.matches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops all active animations on the target element. Returns a promise that resolves after all animations are canceled.
|
||||
*/
|
||||
export function stopAnimations(el: HTMLElement) {
|
||||
return Promise.all(
|
||||
el.getAnimations().map(animation => {
|
||||
return new Promise(resolve => {
|
||||
const handleAnimationEvent = requestAnimationFrame(resolve);
|
||||
|
||||
animation.addEventListener('cancel', () => handleAnimationEvent, { once: true });
|
||||
animation.addEventListener('finish', () => handleAnimationEvent, { once: true });
|
||||
animation.cancel();
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -291,7 +291,8 @@
|
||||
--wa-corners-l: calc(var(--wa-corners-base) * 3rem);
|
||||
|
||||
/* Semantic corner properties create specific shapes beyond the theme's preferred corner styles. */
|
||||
--wa-corners-pill: 9999 --wa-corners-circle: 50%;
|
||||
--wa-corners-pill: 9999px;
|
||||
--wa-corners-circle: 50%;
|
||||
--wa-corners-sharp: 0;
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,10 +6,10 @@ const translation: Translation = {
|
||||
$name: '正體中文',
|
||||
$dir: 'ltr',
|
||||
|
||||
carousel: '旋轉木馬',
|
||||
carousel: '幻燈片',
|
||||
clearEntry: '清空',
|
||||
close: '關閉',
|
||||
copied: '已復制',
|
||||
copied: '已複製',
|
||||
copy: '複製',
|
||||
currentValue: '當前值',
|
||||
error: '錯誤',
|
||||
|
||||
@@ -55,20 +55,20 @@ export function setKitCode(code: string) {
|
||||
* Gets the library's Web Awesome kit code.
|
||||
*
|
||||
* The kit code is used to fetch premium assets, so it needs to be set for certain components to work correctly. This
|
||||
* isn't something we can infer, so the user will need to provide it using the `data-webawesome-kit` attribute. This can
|
||||
* isn't something we can infer, so the user will need to provide it using the `data-fa-kit-code` attribute. This can
|
||||
* be on any element, but ideally it should exist on the script that imports Web Awesome.
|
||||
*
|
||||
* <script src="bundle.js" data-webawesome-kit="abc123"></script>
|
||||
* <script src="bundle.js" data-fa-kit-code="abc123"></script>
|
||||
*
|
||||
* Alternatively, you can set the kit code manually using the exported `setKitCode()` function.
|
||||
*
|
||||
*/
|
||||
export function getKitCode() {
|
||||
if (!kitCode) {
|
||||
const el = document.querySelector('[data-webawesome-kit]');
|
||||
const el = document.querySelector('[data-fa-kit-code]');
|
||||
|
||||
if (el) {
|
||||
setKitCode(el.getAttribute('data-webawesome-kit') || '');
|
||||
setKitCode(el.getAttribute('data-fa-kit-code') || '');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export { registerIconLibrary, unregisterIconLibrary } from '../components/icon/library.js';
|
||||
@@ -1,11 +1,10 @@
|
||||
export { getBasePath, setBasePath } from './utilities/base-path.js';
|
||||
export { registerIconLibrary, unregisterIconLibrary } from './utilities/icon-library.js';
|
||||
export { getBasePath, setBasePath, getKitCode, setKitCode } from './utilities/base-path.js';
|
||||
export { registerIconLibrary, unregisterIconLibrary } from './components/icon/library.js';
|
||||
export { discover } from './utilities/autoloader.js';
|
||||
|
||||
// Utilities
|
||||
export * from './utilities/animation.js';
|
||||
export * from './utilities/base-path.js';
|
||||
export * from './utilities/icon-library.js';
|
||||
export * from './utilities/form.js';
|
||||
|
||||
// Events
|
||||
|
||||
Reference in New Issue
Block a user