Merge branch 'next' into calendar

This commit is contained in:
Cory LaViska
2023-08-11 10:51:54 -04:00
105 changed files with 1382 additions and 403 deletions

View File

@@ -3,8 +3,7 @@ name: Bug Report
about: Create a bug report to help us fix a demonstrable problem with code in the library.
title: ''
labels: bug
assignees: claviska
assignees:
---
### Describe the bug

View File

@@ -3,8 +3,6 @@ name: Feature Request
about: Suggest an idea for this project.
title: ''
labels: feature
assignees: claviska
---
### What issue are you having?

View File

@@ -51,6 +51,7 @@
"erroneou",
"errormessage",
"esbuild",
"exportmaps",
"exportparts",
"fieldsets",
"formaction",
@@ -152,6 +153,7 @@
"tinycolor",
"transitionend",
"treeitem",
"treeshaking",
"Triaging",
"turbolinks",
"typeof",

View File

@@ -1,9 +1,9 @@
import { generateCustomData } from 'cem-plugin-vs-code-custom-data-generator';
import * as path from 'path';
import { customElementVsCodePlugin } from "custom-element-vs-code-integration";
import { parse } from 'comment-parser';
import { pascalCase } from 'pascal-case';
import commandLineArgs from 'command-line-args';
import fs from 'fs';
import * as path from 'path';
const packageData = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
const { name, description, version, author, homepage, license } = packageData;
@@ -53,8 +53,10 @@ export default {
return;
}
const tagName = 'sl-' + path.basename(importPath, '.component.ts');
const tagNameWithoutPrefix = path.basename(importPath, '.component.ts');
const tagName = 'sl-' + tagNameWithoutPrefix;
classDoc.tagNameWithoutPrefix = tagNameWithoutPrefix;
classDoc.tagName = tagName;
// This used to be set to true by @customElement
@@ -167,7 +169,7 @@ export default {
//
const terms = [
{ from: /^src\//, to: '' }, // Strip the src/ prefix
{ from: /\.(t|j)sx?$/, to: '.js' } // Convert .ts to .js
{ from: /\.component.(t|j)sx?$/, to: '.js' } // Convert .ts to .js
];
mod.path = replace(mod.path, terms);
@@ -189,9 +191,13 @@ export default {
}
},
// Generate custom VS Code data
generateCustomData({
customElementVsCodePlugin({
outdir,
cssFileName: null
cssFileName: null,
referencesTemplate: (_, tag) => [{
name: "Documentation",
url: `https://shoelace.style/components/${tag.replace('sl-', '')}`
}]
})
]
};

View File

@@ -84,7 +84,7 @@
<p>
To import this component as a <a href="/frameworks/react">React component</a>:
</p>
<pre><code class="language-js">import { {{ component.name }} } from '@shoelace-style/shoelace/{{ meta.npmdir }}/react';</code></pre>
<pre><code class="language-js">import {{ component.name }} from '@shoelace-style/shoelace/{{ meta.npmdir }}/react/{{ component.tagNameWithoutPrefix }}';</code></pre>
</sl-tab-panel>
</sl-tab-group>

View File

@@ -1,9 +1,9 @@
(() => {
function convertModuleLinks(html) {
html = html
.replace(/@shoelace-style\/shoelace/g, `https://cdn.skypack.dev/@shoelace-style/shoelace@${shoelaceVersion}`)
.replace(/from 'react'/g, `from 'https://cdn.skypack.dev/react@${reactVersion}'`)
.replace(/from "react"/g, `from "https://cdn.skypack.dev/react@${reactVersion}"`);
.replace(/@shoelace-style\/shoelace/g, `https://esm.sh/@shoelace-style/shoelace@${shoelaceVersion}`)
.replace(/from 'react'/g, `from 'https://esm.sh/react@${reactVersion}'`)
.replace(/from "react"/g, `from "https://esm.sh/react@${reactVersion}"`);
return html;
}
@@ -191,12 +191,12 @@
if (isReact) {
htmlTemplate = '<div id="root"></div>';
jsTemplate =
`import React from 'https://cdn.skypack.dev/react@${reactVersion}';\n` +
`import ReactDOM from 'https://cdn.skypack.dev/react-dom@${reactVersion}';\n` +
`import { setBasePath } from 'https://cdn.skypack.dev/@shoelace-style/shoelace@${shoelaceVersion}/${cdndir}/utilities/base-path';\n` +
`import React from 'https://esm.sh/react@${reactVersion}';\n` +
`import ReactDOM from 'https://esm.sh/react-dom@${reactVersion}';\n` +
`import { setBasePath } from 'https://esm.sh/@shoelace-style/shoelace@${shoelaceVersion}/${cdndir}/utilities/base-path';\n` +
`\n` +
`// Set the base path for Shoelace assets\n` +
`setBasePath('https://cdn.skypack.dev/@shoelace-style/shoelace@${shoelaceVersion}/${npmdir}/')\n` +
`setBasePath('https://esm.sh/@shoelace-style/shoelace@${shoelaceVersion}/${npmdir}/')\n` +
`\n${convertModuleLinks(reactExample)}\n` +
`\n` +
`ReactDOM.render(<App />, document.getElementById('root'));`;

View File

@@ -58,15 +58,15 @@
const clearButton = siteSearch.querySelector('.search__clear-button');
const results = siteSearch.querySelector('.search__results');
const version = document.documentElement.getAttribute('data-shoelace-version');
const animationDuration = 150;
const key = `search_${version}`;
const searchDebounce = 50;
const animationDuration = 150;
let isShowing = false;
let searchTimeout;
let searchIndex;
let map;
const loadSearchIndex = new Promise(resolve => {
const key = `search_${version}`;
const cache = localStorage.getItem(key);
const wait = 'requestIdleCallback' in window ? requestIdleCallback : requestAnimationFrame;
@@ -357,6 +357,13 @@
}
});
// Purge cache when we press CMD+CTRL+R
document.addEventListener('keydown', event => {
if ((event.metaKey || event.ctrlKey) && event.shiftKey && event.key === 'r') {
localStorage.clear();
}
});
input.addEventListener('input', handleInput);
clearButton.addEventListener('click', handleClear);

View File

@@ -237,6 +237,7 @@ kbd {
border: solid 1px var(--sl-color-neutral-200);
box-shadow: inset 0 1px 0 0 var(--sl-color-neutral-0), inset 0 -1px 0 0 var(--sl-color-neutral-200);
font-family: var(--sl-font-mono);
font-size: 0.9125em;
border-radius: var(--docs-border-radius);
color: var(--sl-color-neutral-800);
padding: 0.125em 0.4em;
@@ -393,6 +394,10 @@ table td p:last-child {
overflow-x: auto;
}
.table-scroll code {
white-space: nowrap;
}
th.table-name,
th.table-event-detail {
min-width: 15ch;
@@ -1061,23 +1066,29 @@ html.sidebar-open #menu-toggle {
/* Hide when not defined to prevent extra wide icon toolbar while loading */
display: none;
}
#theme-selector sl-menu {
/* Set an initial size to prevent width being initally too small when first opening on small screen width */
/* Set an initial size to prevent width being too small when first opening on small screen width */
width: 140px;
}
#theme-selector sl-button {
transition: 250ms scale ease;
}
#theme-selector sl-button::part(base) {
color: var(--sl-color-neutral-0);
}
#theme-selector sl-button::part(label) {
display: flex;
padding: 0.5rem;
}
#theme-selector sl-icon {
font-size: 1.25rem;
}
.sl-theme-dark #theme-selector sl-button::part(base) {
color: var(--sl-color-neutral-1000);
}

View File

@@ -13,7 +13,8 @@ layout: component
```
```jsx:react
import { SlAlert, SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlAlert from '@shoelace-style/shoelace/dist/react/sl-alert';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
const App = () => (
<SlAlert open>
@@ -74,7 +75,8 @@ Set the `variant` attribute to change the alert's variant.
```
```jsx:react
import { SlAlert, SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlAlert from '@shoelace-style/shoelace/dist/react/sl-alert';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
const App = () => (
<>
@@ -144,7 +146,8 @@ Add the `closable` attribute to show a close button that will hide the alert.
```jsx:react
import { useState } from 'react';
import { SlAlert, SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlAlert from '@shoelace-style/shoelace/dist/react/sl-alert';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
const App = () => {
const [open, setOpen] = useState(true);
@@ -172,7 +175,7 @@ Icons are optional. Simply omit the `icon` slot if you don't want them.
```
```jsx:react
import { SlAlert } from '@shoelace-style/shoelace/dist/react';
import SlAlert from '@shoelace-style/shoelace/dist/react/sl-alert';
const App = () => (
<SlAlert variant="primary" open>
@@ -212,7 +215,9 @@ Set the `duration` attribute to automatically hide an alert after a period of ti
```jsx:react
import { useState } from 'react';
import { SlAlert, SlButton, SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlAlert from '@shoelace-style/shoelace/dist/react/sl-alert';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
const css = `
.alert-duration sl-alert {
@@ -301,7 +306,9 @@ You should always use the `closable` attribute so users can dismiss the notifica
```jsx:react
import { useRef } from 'react';
import { SlAlert, SlButton, SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlAlert from '@shoelace-style/shoelace/dist/react/sl-alert';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
function showToast(alert) {
alert.toast();

View File

@@ -13,7 +13,7 @@ layout: component
```
```jsx:react
import { SlAnimatedImage } from '@shoelace-style/shoelace/dist/react';
import SlAnimatedImage from '@shoelace-style/shoelace/dist/react/sl-animated-image';
const App = () => (
<SlAnimatedImage
@@ -41,7 +41,7 @@ Both GIF and WEBP images are supported.
```
```jsx:react
import { SlAnimatedImage } from '@shoelace-style/shoelace/dist/react';
import SlAnimatedImage from '@shoelace-style/shoelace/dist/react/sl-animated-image';
const App = () => (
<SlAnimatedImage src="https://shoelace.style/assets/images/tie.webp" alt="Animation of a shoe being tied" />
@@ -64,7 +64,7 @@ To set a custom size, apply a width and/or height to the host element.
{% raw %}
```jsx:react
import { SlAnimatedImage } from '@shoelace-style/shoelace/dist/react';
import SlAnimatedImage from '@shoelace-style/shoelace/dist/react/sl-animated-image';
const App = () => (
<SlAnimatedImage
@@ -102,7 +102,7 @@ You can change the appearance and location of the control box by targeting the `
```
```jsx:react
import { SlAnimatedImage } from '@shoelace-style/shoelace/dist/react';
import SlAnimatedImage from '@shoelace-style/shoelace/dist/react/sl-animated-image';
const css = `
.animated-image-custom-control-box::part(control-box) {

View File

@@ -27,7 +27,7 @@ To animate an element, wrap it in `<sl-animation>` and set an animation `name`.
```
```jsx:react
import { SlAnimation } from '@shoelace-style/shoelace/dist/react';
import SlAnimation from '@shoelace-style/shoelace/dist/react/sl-animation';
const css = `
.animation-overview .box {
@@ -173,7 +173,7 @@ Use an [Intersection Observer](https://developer.mozilla.org/en-US/docs/Web/API/
```jsx:react
import { useEffect, useRef, useState } from 'react';
import { SlAnimation } from '@shoelace-style/shoelace/dist/react';
import SlAnimation from '@shoelace-style/shoelace/dist/react/sl-animation';
const css = `
.animation-scroll {
@@ -262,7 +262,7 @@ Supply your own [keyframe formats](https://developer.mozilla.org/en-US/docs/Web/
```
```jsx:react
import { SlAnimation } from '@shoelace-style/shoelace/dist/react';
import SlAnimation from '@shoelace-style/shoelace/dist/react/sl-animation';
const css = `
.animation-keyframes .box {
@@ -329,7 +329,8 @@ Animations won't play until you apply the `play` attribute. You can omit it init
```jsx:react
import { useState } from 'react';
import { SlAnimation, SlButton } from '@shoelace-style/shoelace/dist/react';
import SlAnimation from '@shoelace-style/shoelace/dist/react/sl-animation';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
const App = () => {
const [play, setPlay] = useState(false);

View File

@@ -12,7 +12,7 @@ By default, a generic icon will be shown. You can personalize avatars by adding
```
```jsx:react
import { SlAvatar } from '@shoelace-style/shoelace/dist/react';
import SlAvatar from '@shoelace-style/shoelace/dist/react/sl-avatar';
const App = () => <SlAvatar label="User avatar" />;
```
@@ -37,7 +37,7 @@ Avatar images can be lazily loaded by setting the `loading` attribute to `lazy`.
```
```jsx:react
import { SlAvatar } from '@shoelace-style/shoelace/dist/react';
import SlAvatar from '@shoelace-style/shoelace/dist/react/sl-avatar';
const App = () => (
<SlAvatar
@@ -61,7 +61,7 @@ When you don't have an image to use, you can set the `initials` attribute to sho
```
```jsx:react
import { SlAvatar } from '@shoelace-style/shoelace/dist/react';
import SlAvatar from '@shoelace-style/shoelace/dist/react/sl-avatar';
const App = () => <SlAvatar initials="SL" label="Avatar with initials: SL" />;
```
@@ -85,7 +85,8 @@ When no image or initials are set, an icon will be shown. The default avatar sho
```
```jsx:react
import { SlAvatar, SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlAvatar from '@shoelace-style/shoelace/dist/react/sl-avatar';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
const App = () => (
<>
@@ -115,7 +116,8 @@ Avatars can be shaped using the `shape` attribute.
```
```jsx:react
import { SlAvatar, SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlAvatar from '@shoelace-style/shoelace/dist/react/sl-avatar';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
const App = () => (
<>
@@ -165,7 +167,8 @@ You can group avatars with a few lines of CSS.
```
```jsx:react
import { SlAvatar, SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlAvatar from '@shoelace-style/shoelace/dist/react/sl-avatar';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
const css = `
.avatar-group sl-avatar:not(:first-of-type) {

View File

@@ -10,7 +10,7 @@ layout: component
```
```jsx:react
import { SlBadge } from '@shoelace-style/shoelace/dist/react';
import SlBadge from '@shoelace-style/shoelace/dist/react/sl-badge';
const App = () => <SlBadge>Badge</SlBadge>;
```
@@ -30,7 +30,7 @@ Set the `variant` attribute to change the badge's variant.
```
```jsx:react
import { SlBadge } from '@shoelace-style/shoelace/dist/react';
import SlBadge from '@shoelace-style/shoelace/dist/react/sl-badge';
const App = () => (
<>
@@ -56,7 +56,7 @@ Use the `pill` attribute to give badges rounded edges.
```
```jsx:react
import { SlBadge } from '@shoelace-style/shoelace/dist/react';
import SlBadge from '@shoelace-style/shoelace/dist/react/sl-badge';
const App = () => (
<>
@@ -100,7 +100,7 @@ Use the `pulse` attribute to draw attention to the badge with a subtle animation
```
```jsx:react
import { SlBadge } from '@shoelace-style/shoelace/dist/react';
import SlBadge from '@shoelace-style/shoelace/dist/react/sl-badge';
const css = `
.badge-pulse sl-badge:not(:last-of-type) {
@@ -157,7 +157,8 @@ One of the most common use cases for badges is attaching them to buttons. To mak
{% raw %}
```jsx:react
import { SlBadge, SlButton } from '@shoelace-style/shoelace/dist/react';
import SlBadge from '@shoelace-style/shoelace/dist/react/sl-badge';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
const App = () => (
<>
@@ -200,7 +201,11 @@ When including badges in menu items, use the `suffix` slot to make sure they're
{% raw %}
```jsx:react
import { SlBadge, SlButton, SlMenu, SlMenuItem, SlMenuLabel } from '@shoelace-style/shoelace/dist/react';
import SlBadge from '@shoelace-style/shoelace/dist/react/sl-badge';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlMenu from '@shoelace-style/shoelace/dist/react/sl-menu';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
import SlMenuLabel from '@shoelace-style/shoelace/dist/react/sl-menu-label';
const App = () => (
<SlMenu

View File

@@ -17,7 +17,9 @@ layout: component
```
```jsx:react
import { SlBreadcrumb, SlBreadcrumbItem, SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlBreadcrumb from '@shoelace-style/shoelace/dist/react/sl-breadcrumb';
import SlBreadcrumbItem from '@shoelace-style/shoelace/dist/react/sl-breadcrumb-item';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
const App = () => (
<SlBreadcrumb>

View File

@@ -17,7 +17,8 @@ Breadcrumbs are usually placed before a page's main content with the current pag
```
```jsx:react
import { SlBreadcrumb, SlBreadcrumbItem } from '@shoelace-style/shoelace/dist/react';
import SlBreadcrumb from '@shoelace-style/shoelace/dist/react/sl-breadcrumb';
import SlBreadcrumbItem from '@shoelace-style/shoelace/dist/react/sl-breadcrumb-item';
const App = () => (
<SlBreadcrumb>
@@ -50,7 +51,8 @@ For websites, you'll probably want to use links instead. You can make any breadc
```
```jsx:react
import { SlBreadcrumb, SlBreadcrumbItem } from '@shoelace-style/shoelace/dist/react';
import SlBreadcrumb from '@shoelace-style/shoelace/dist/react/sl-breadcrumb';
import SlBreadcrumbItem from '@shoelace-style/shoelace/dist/react/sl-breadcrumb-item';
const App = () => (
<SlBreadcrumb>
@@ -98,7 +100,8 @@ Use the `separator` slot to change the separator that goes between breadcrumb it
```jsx:react
import '@shoelace-style/shoelace/dist/components/icon/icon.js';
import { SlBreadcrumb, SlBreadcrumbItem } from '@shoelace-style/shoelace/dist/react';
import SlBreadcrumb from '@shoelace-style/shoelace/dist/react/sl-breadcrumb';
import SlBreadcrumbItem from '@shoelace-style/shoelace/dist/react/sl-breadcrumb-item';
const App = () => (
<>
@@ -146,7 +149,9 @@ Use the `prefix` slot to add content before any breadcrumb item.
```
```jsx:react
import { SlBreadcrumb, SlBreadcrumbItem, SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlBreadcrumb from '@shoelace-style/shoelace/dist/react/sl-breadcrumb';
import SlBreadcrumbItem from '@shoelace-style/shoelace/dist/react/sl-breadcrumb-item';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
const App = () => (
<SlBreadcrumb>
@@ -176,7 +181,9 @@ Use the `suffix` slot to add content after any breadcrumb item.
```
```jsx:react
import { SlBreadcrumb, SlBreadcrumbItem, SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlBreadcrumb from '@shoelace-style/shoelace/dist/react/sl-breadcrumb';
import SlBreadcrumbItem from '@shoelace-style/shoelace/dist/react/sl-breadcrumb-item';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
const App = () => (
<SlBreadcrumb>

View File

@@ -14,7 +14,8 @@ layout: component
```
```jsx:react
import { SlButton, SlButtonGroup } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlButtonGroup from '@shoelace-style/shoelace/dist/react/sl-button-group';
const App = () => (
<SlButtonGroup label="Alignment">
@@ -56,7 +57,8 @@ All button sizes are supported, but avoid mixing sizes within the same button gr
```
```jsx:react
import { SlButton, SlButtonGroup } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlButtonGroup from '@shoelace-style/shoelace/dist/react/sl-button-group';
const App = () => (
<>
@@ -132,7 +134,8 @@ Theme buttons are supported through the button's `variant` attribute.
```
```jsx:react
import { SlButton, SlButtonGroup } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlButtonGroup from '@shoelace-style/shoelace/dist/react/sl-button-group';
const App = () => (
<>
@@ -210,7 +213,8 @@ Pill buttons are supported through the button's `pill` attribute.
```
```jsx:react
import { SlButton, SlButtonGroup } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlButtonGroup from '@shoelace-style/shoelace/dist/react/sl-button-group';
const App = () => (
<>
@@ -279,7 +283,11 @@ Dropdowns can be placed inside button groups as long as the trigger is an `<sl-b
```
```jsx:react
import { SlButton, SlButtonGroup, SlDropdown, SlMenu, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlButtonGroup from '@shoelace-style/shoelace/dist/react/sl-button-group';
import SlDropdown from '@shoelace-style/shoelace/dist/react/sl-dropdown';
import SlMenu from '@shoelace-style/shoelace/dist/react/sl-menu';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const App = () => (
<SlButtonGroup label="Example Button Group">
@@ -320,7 +328,11 @@ Create a split button using a button and a dropdown. Use a [visually hidden](/co
```
```jsx:react
import { SlButton, SlButtonGroup, SlDropdown, SlMenu, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlButtonGroup from '@shoelace-style/shoelace/dist/react/sl-button-group';
import SlDropdown from '@shoelace-style/shoelace/dist/react/sl-dropdown';
import SlMenu from '@shoelace-style/shoelace/dist/react/sl-menu';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const App = () => (
<SlButtonGroup label="Example Button Group">
@@ -358,7 +370,9 @@ Buttons can be wrapped in tooltips to provide more detail when the user interact
```
```jsx:react
import { SlButton, SlButtonGroup, SlTooltip } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlButtonGroup from '@shoelace-style/shoelace/dist/react/sl-button-group';
import SlTooltip from '@shoelace-style/shoelace/dist/react/sl-tooltip';
const App = () => (
<>
@@ -427,7 +441,10 @@ Create interactive toolbars with button groups.
```
```jsx:react
import { SlButton, SlButtonGroup, SlIcon, SlTooltip } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlButtonGroup from '@shoelace-style/shoelace/dist/react/sl-button-group';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
import SlTooltip from '@shoelace-style/shoelace/dist/react/sl-tooltip';
const css = `
.button-group-toolbar sl-button-group:not(:last-of-type) {

View File

@@ -10,7 +10,7 @@ layout: component
```
```jsx:react
import { SlButton } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
const App = () => <SlButton>Button</SlButton>;
```
@@ -31,7 +31,7 @@ Use the `variant` attribute to set the button's variant.
```
```jsx:react
import { SlButton } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
const App = () => (
<>
@@ -56,7 +56,7 @@ Use the `size` attribute to change a button's size.
```
```jsx:react
import { SlButton } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
const App = () => (
<>
@@ -81,7 +81,7 @@ Use the `outline` attribute to draw outlined buttons with transparent background
```
```jsx:react
import { SlButton } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
const App = () => (
<>
@@ -118,7 +118,7 @@ Use the `pill` attribute to give buttons rounded edges.
```
```jsx:react
import { SlButton } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
const App = () => (
<>
@@ -154,7 +154,8 @@ Use the `circle` attribute to create circular icon buttons. When this attribute
```
```jsx:react
import { SlButton, SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
const App = () => (
<>
@@ -182,7 +183,7 @@ Use the `text` variant to create text buttons that share the same size as regula
```
```jsx:react
import { SlButton } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
const App = () => (
<>
@@ -211,7 +212,7 @@ It's often helpful to have a button that works like a link. This is possible by
```
```jsx:react
import { SlButton } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
const App = () => (
<>
@@ -246,7 +247,7 @@ As expected, buttons can be given a custom width by setting the `width` attribut
{% raw %}
```jsx:react
import { SlButton } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
const App = () => (
<>
@@ -324,7 +325,8 @@ Use the `prefix` and `suffix` slots to add icons.
```
```jsx:react
import { SlButton, SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
const App = () => (
<>
@@ -396,7 +398,7 @@ Use the `caret` attribute to add a dropdown indicator when a button will trigger
```
```jsx:react
import { SlButton } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
const App = () => (
<>
@@ -427,7 +429,7 @@ Use the `loading` attribute to make a button busy. The width will remain the sam
```
```jsx:react
import { SlButton } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
const App = () => (
<>
@@ -467,7 +469,7 @@ Use the `disabled` attribute to disable a button.
```
```jsx:react
import { SlButton } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
const App = () => (
<>

View File

@@ -41,7 +41,9 @@ layout: component
```
```jsx:react
import { SlButton, SlCard, SlRating } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlCard from '@shoelace-style/shoelace/dist/react/sl-card';
import SlRating from '@shoelace-style/shoelace/dist/react/sl-rating';
const css = `
.card-overview {
@@ -104,7 +106,7 @@ Basic cards aren't very exciting, but they can display any content you want them
```
```jsx:react
import { SlCard } from '@shoelace-style/shoelace/dist/react';
import SlCard from '@shoelace-style/shoelace/dist/react/sl-card';
const css = `
.card-basic {
@@ -159,7 +161,8 @@ Headers can be used to display titles and more.
```
```jsx:react
import { SlCard, SlIconButton } from '@shoelace-style/shoelace/dist/react';
import SlCard from '@shoelace-style/shoelace/dist/react/sl-card';
import SlIconButton from '@shoelace-style/shoelace/dist/react/sl-icon-button';
const css = `
.card-header {
@@ -224,7 +227,9 @@ Footers can be used to display actions, summaries, or other relevant content.
```
```jsx:react
import { SlButton, SlCard, SlRating } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlCard from '@shoelace-style/shoelace/dist/react/sl-card';
import SlRating from '@shoelace-style/shoelace/dist/react/sl-rating';
const css = `
.card-footer {
@@ -277,7 +282,7 @@ Cards accept an `image` slot. The image is displayed atop the card and stretches
```
```jsx:react
import { SlCard } from '@shoelace-style/shoelace/dist/react';
import SlCard from '@shoelace-style/shoelace/dist/react/sl-card';
const css = `
.card-image {

View File

@@ -41,7 +41,8 @@ layout: component
```
```jsx:react
import { SlCarousel, SlCarouselItem } from '@shoelace-style/shoelace/dist/react';
import SlCarousel from '@shoelace-style/shoelace/dist/react/sl-carousel';
import SlCarouselItem from '@shoelace-style/shoelace/dist/react/sl-carousel-item';
const App = () => (
<SlCarousel pagination>

View File

@@ -41,7 +41,8 @@ layout: component
```
```jsx:react
import { SlCarousel, SlCarouselItem } from '@shoelace-style/shoelace/dist/react';
import SlCarousel from '@shoelace-style/shoelace/dist/react/sl-carousel';
import SlCarouselItem from '@shoelace-style/shoelace/dist/react/sl-carousel-item';
const App = () => (
<>
@@ -123,7 +124,8 @@ Use the `pagination` attribute to show the total number of slides and the curren
```
```jsx:react
import { SlCarousel, SlCarouselItem } from '@shoelace-style/shoelace/dist/react';
import SlCarousel from '@shoelace-style/shoelace/dist/react/sl-carousel';
import SlCarouselItem from '@shoelace-style/shoelace/dist/react/sl-carousel-item';
const App = () => (
<SlCarousel pagination>
@@ -201,7 +203,8 @@ Use the `navigation` attribute to show previous and next buttons.
```
```jsx:react
import { SlCarousel, SlCarouselItem } from '@shoelace-style/shoelace/dist/react';
import SlCarousel from '@shoelace-style/shoelace/dist/react/sl-carousel';
import SlCarouselItem from '@shoelace-style/shoelace/dist/react/sl-carousel-item';
const App = () => (
<SlCarousel navigation>
@@ -279,7 +282,8 @@ By default, the carousel will not advanced beyond the first and last slides. You
```
```jsx:react
import { SlCarousel, SlCarouselItem } from '@shoelace-style/shoelace/dist/react';
import SlCarousel from '@shoelace-style/shoelace/dist/react/sl-carousel';
import SlCarouselItem from '@shoelace-style/shoelace/dist/react/sl-carousel-item';
const App = () => (
<SlCarousel loop navigation pagination>
@@ -357,7 +361,8 @@ The carousel will automatically advance when the `autoplay` attribute is used. T
```
```jsx:react
import { SlCarousel, SlCarouselItem } from '@shoelace-style/shoelace/dist/react';
import SlCarousel from '@shoelace-style/shoelace/dist/react/sl-carousel';
import SlCarouselItem from '@shoelace-style/shoelace/dist/react/sl-carousel-item';
const App = () => (
<SlCarousel autoplay loop pagination>
@@ -454,7 +459,10 @@ This example is best demonstrated using a mouse. Try clicking and dragging the s
```jsx:react
import { useState } from 'react';
import { SlCarousel, SlCarouselItem, SlDivider, SlSwitch } from '@shoelace-style/shoelace/dist/react';
import SlCarousel from '@shoelace-style/shoelace/dist/react/sl-carousel';
import SlCarouselItem from '@shoelace-style/shoelace/dist/react/sl-carousel-item';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
import SlSwitch from '@shoelace-style/shoelace/dist/react/sl-switch';
const App = () => {
const [isEnabled, setIsEnabled] = useState(false);
@@ -522,7 +530,8 @@ The `slides-per-page` attribute makes it possible to display multiple slides at
{% raw %}
```jsx:react
import { SlCarousel, SlCarouselItem } from '@shoelace-style/shoelace/dist/react';
import SlCarousel from '@shoelace-style/shoelace/dist/react/sl-carousel';
import SlCarouselItem from '@shoelace-style/shoelace/dist/react/sl-carousel-item';
const App = () => (
<SlCarousel navigation pagination slidesPerPage={2} slidesPerMove={2}>
@@ -614,7 +623,8 @@ The content of the carousel can be changed by adding or removing carousel items.
```jsx:react
import { useState } from 'react';
import { SlCarousel, SlCarouselItem } from '@shoelace-style/shoelace/dist/react';
import SlCarousel from '@shoelace-style/shoelace/dist/react/sl-carousel';
import SlCarouselItem from '@shoelace-style/shoelace/dist/react/sl-carousel-item';
const css = `
.dynamic-carousel {
@@ -730,7 +740,8 @@ Setting the `orientation` attribute to `vertical` will render the carousel in a
```
```jsx:react
import { SlCarousel, SlCarouselItem } from '@shoelace-style/shoelace/dist/react';
import SlCarousel from '@shoelace-style/shoelace/dist/react/sl-carousel';
import SlCarouselItem from '@shoelace-style/shoelace/dist/react/sl-carousel-item';
const css = `
.vertical {
@@ -852,7 +863,11 @@ Use the `--aspect-ratio` custom property to customize the size of the carousel's
```jsx:react
import { useState } from 'react';
import { SlCarousel, SlCarouselItem, SlDivider, SlSelect, SlOption } from '@shoelace-style/shoelace/dist/react';
import SlCarousel from '@shoelace-style/shoelace/dist/react/sl-carousel';
import SlCarouselItem from '@shoelace-style/shoelace/dist/react/sl-carousel-item';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
import SlOption from '@shoelace-style/shoelace/dist/react/sl-option';
const App = () => {
const [aspectRatio, setAspectRatio] = useState('3/2');
@@ -956,7 +971,10 @@ Use the `--scroll-hint` custom property to add inline padding in horizontal caro
```jsx:react
import { useState } from 'react';
import { SlCarousel, SlCarouselItem, SlDivider, SlRange } from '@shoelace-style/shoelace/dist/react';
import SlCarousel from '@shoelace-style/shoelace/dist/react/sl-carousel';
import SlCarouselItem from '@shoelace-style/shoelace/dist/react/sl-carousel-item';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
import SlRange from '@shoelace-style/shoelace/dist/react/sl-range';
const App = () => (
<>
@@ -1119,7 +1137,10 @@ The carousel has a robust API that makes it possible to extend and customize. Th
```jsx:react
import { useRef } from 'react';
import { SlCarousel, SlCarouselItem, SlDivider, SlRange } from '@shoelace-style/shoelace/dist/react';
import SlCarousel from '@shoelace-style/shoelace/dist/react/sl-carousel';
import SlCarouselItem from '@shoelace-style/shoelace/dist/react/sl-carousel-item';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
import SlRange from '@shoelace-style/shoelace/dist/react/sl-range';
const css = `
.carousel-thumbnails {

View File

@@ -10,7 +10,7 @@ layout: component
```
```jsx:react
import { SlCheckbox } from '@shoelace-style/shoelace/dist/react';
import SlCheckbox from '@shoelace-style/shoelace/dist/react/sl-checkbox';
const App = () => <SlCheckbox>Checkbox</SlCheckbox>;
```
@@ -30,7 +30,7 @@ Use the `checked` attribute to activate the checkbox.
```
```jsx:react
import { SlCheckbox } from '@shoelace-style/shoelace/dist/react';
import SlCheckbox from '@shoelace-style/shoelace/dist/react/sl-checkbox';
const App = () => <SlCheckbox checked>Checked</SlCheckbox>;
```
@@ -44,7 +44,7 @@ Use the `indeterminate` attribute to make the checkbox indeterminate.
```
```jsx:react
import { SlCheckbox } from '@shoelace-style/shoelace/dist/react';
import SlCheckbox from '@shoelace-style/shoelace/dist/react/sl-checkbox';
const App = () => <SlCheckbox indeterminate>Indeterminate</SlCheckbox>;
```
@@ -58,7 +58,7 @@ Use the `disabled` attribute to disable the checkbox.
```
```jsx:react
import { SlCheckbox } from '@shoelace-style/shoelace/dist/react';
import SlCheckbox from '@shoelace-style/shoelace/dist/react/sl-checkbox';
const App = () => <SlCheckbox disabled>Disabled</SlCheckbox>;
```
@@ -76,7 +76,7 @@ Use the `size` attribute to change a checkbox's size.
```
```jsx:react
import { SlCheckbox } from '@shoelace-style/shoelace/dist/react';
import SlCheckbox from '@shoelace-style/shoelace/dist/react/sl-checkbox';
const App = () => (
<>
@@ -127,7 +127,8 @@ Use the `setCustomValidity()` method to set a custom validation message. This wi
```jsx:react
import { useEffect, useRef } from 'react';
import { SlButton, SlCheckbox } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlCheckbox from '@shoelace-style/shoelace/dist/react/sl-checkbox';
const App = () => {
const checkbox = useRef(null);

View File

@@ -10,7 +10,7 @@ layout: component
```
```jsx:react
import { SlColorPicker } from '@shoelace-style/shoelace/dist/react';
import SlColorPicker from '@shoelace-style/shoelace/dist/react/sl-color-picker';
const App = () => <SlColorPicker label="Select a color" />;
```
@@ -30,7 +30,7 @@ Use the `value` attribute to set an initial value for the color picker.
```
```jsx:react
import { SlColorPicker } from '@shoelace-style/shoelace/dist/react';
import SlColorPicker from '@shoelace-style/shoelace/dist/react/sl-color-picker';
const App = () => <SlColorPicker value="#4a90e2" label="Select a color" />;
```
@@ -44,7 +44,7 @@ Use the `opacity` attribute to enable the opacity slider. When this is enabled,
```
```jsx:react
import { SlColorPicker } from '@shoelace-style/shoelace/dist/react';
import SlColorPicker from '@shoelace-style/shoelace/dist/react/sl-color-picker';
const App = () => <SlColorPicker opacity label="Select a color" />;
```
@@ -63,7 +63,7 @@ To prevent users from toggling the format themselves, add the `no-format-toggle`
```
```jsx:react
import { SlColorPicker } from '@shoelace-style/shoelace/dist/react';
import SlColorPicker from '@shoelace-style/shoelace/dist/react/sl-color-picker';
const App = () => (
<>
@@ -90,7 +90,7 @@ Use the `swatches` attribute to add convenient presets to the color picker. Any
```
```jsx:react
import { SlColorPicker } from '@shoelace-style/shoelace/dist/react';
import SlColorPicker from '@shoelace-style/shoelace/dist/react/sl-color-picker';
const App = () => (
<SlColorPicker
@@ -114,7 +114,7 @@ Use the `size` attribute to change the color picker's trigger size.
```
```jsx:react
import { SlColorPicker } from '@shoelace-style/shoelace/dist/react';
import SlColorPicker from '@shoelace-style/shoelace/dist/react/sl-color-picker';
const App = () => (
<>
@@ -134,7 +134,7 @@ The color picker can be rendered inline instead of in a dropdown using the `inli
```
```jsx:react
import { SlColorPicker } from '@shoelace-style/shoelace/dist/react';
import SlColorPicker from '@shoelace-style/shoelace/dist/react/sl-color-picker';
const App = () => <SlColorPicker inline label="Select a color" />;
```

View File

@@ -0,0 +1,258 @@
---
meta:
title: Copy Button
description: Copies data to the clipboard when the user clicks the button.
layout: component
---
```html:preview
<sl-copy-button value="Shoelace rocks!"></sl-copy-button>
```
```jsx:react
import { SlCopyButton } from '@shoelace-style/shoelace/dist/react/sl-copy-button';
const App = () => (
<SlCopyButton value="Shoelace rocks!" />
);
```
## Examples
### Custom Labels
Copy Buttons display feedback in a tooltip. You can customize the labels using the `copy-label`, `success-label`, and `error-label` attributes.
```html:preview
<sl-copy-button
value="Custom labels are easy"
copy-label="Click to copy"
success-label="You did it!"
error-label="Whoops, your browser doesn't support this!"
></sl-copy-button>
```
```jsx:react
import { SlCopyButton } from '@shoelace-style/shoelace/dist/react/sl-copy-button';
const App = () => (
<SlCopyButton
value="Custom labels are easy"
copy-label="Click to copy"
success-label="You did it!"
error-label="Whoops, your browser doesn't support this!"
/>
);
```
### 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 [`<sl-icon>`](/components/icon) or your own images.
```html:preview
<sl-copy-button value="Copied from a custom button">
<sl-icon slot="copy-icon" name="clipboard"></sl-icon>
<sl-icon slot="success-icon" name="clipboard-check"></sl-icon>
<sl-icon slot="error-icon" name="clipboard-x"></sl-icon>
</sl-copy-button>
```
```jsx:react
import { SlCopyButton } from '@shoelace-style/shoelace/dist/react/sl-copy-button';
import { SlIcon } from '@shoelace-style/shoelace/dist/react/sl-icon';
const App = () => (
<>
<SlCopyButton value="Copied from a custom button">
<SlIcon slot="copy-icon" name="clipboard" />
<SlIcon slot="success-icon" name="clipboard-check" />
<SlIcon slot="error-icon" name="clipboard-x" />
</SlCopyButton>
</>
);
```
### 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.
When using the `from` attribute, the element's [`textContent`](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent) will be copied by default. Passing an attribute or property modifier will let you copy data from one of the element's attributes or properties instead.
To copy data from an attribute, use `from="id[attr]"` where `id` is the id of the target element and `attr` is the name of the attribute you'd like to copy. To copy data from a property, use `from="id.prop"` where `id` is the id of the target element and `prop` is the name of the property you'd like to copy.
```html:preview
<!-- Copies the span's textContent -->
<span id="my-phone">+1 (234) 456-7890</span>
<sl-copy-button from="my-phone"></sl-copy-button>
<br><br>
<!-- Copies the input's "value" property -->
<sl-input id="my-input" type="text" value="User input" style="display: inline-block; max-width: 300px;"></sl-input>
<sl-copy-button from="my-input.value"></sl-copy-button>
<br><br>
<!-- Copies the link's "href" attribute -->
<a id="my-link" href="https://shoelace.style/">Shoelace Website</a>
<sl-copy-button from="my-link[href]"></sl-copy-button>
```
```jsx:react
import { SlCopyButton } from '@shoelace-style/shoelace/dist/react/sl-copy-button';
import { SlInput } from '@shoelace-style/shoelace/dist/react/sl-input';
const App = () => (
<>
{/* Copies the span's textContent */}
<span id="my-phone">+1 (234) 456-7890</span>
<SlCopyButton from="my-phone" />
<br /><br />
{/* Copies the input's "value" property */}
<SlInput id="my-input" type="text" />
<SlCopyButton from="my-input.value" />
<br /><br />
{/* Copies the link's "href" attribute */}
<a id="my-link" href="https://shoelace.style/">Shoelace Website</a>
<SlCopyButton from="my-link[href]" />
</>
);
```
### 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 `sl-error` event will be emitted.
This example demonstrates what happens when a copy error occurs. You can customize the error label and icon using the `error-label` attribute and the `error-icon` slot, respectively.
```html:preview
<sl-copy-button from="i-do-not-exist"></sl-copy-button>
```
```jsx:react
import { SlCopyButton } from '@shoelace-style/shoelace/dist/react/sl-copy-button';
const App = () => (
<SlCopyButton from="i-do-not-exist" />
);
```
### Disabled
Copy buttons can be disabled by adding the `disabled` attribute.
```html:preview
<sl-copy-button value="You can't copy me" disabled></sl-copy-button>
```
```jsx:react
import { SlCopyButton } from '@shoelace-style/shoelace/dist/react/sl-copy-button';
const App = () => (
<SlCopyButton value="You can't copy me" disabled />
);
```
### 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.
```html:preview
<sl-copy-button value="Shoelace rocks!" feedback-duration="250"></sl-copy-button>
```
```jsx:react
import { SlCopyButton } from '@shoelace-style/shoelace/dist/react/sl-copy-button';
const App = () => (
<SlCopyButton value="Shoelace rocks!" feedback-duration={250} />
);
```
### Custom Styles
You can customize the button to your liking with CSS.
```html:preview
<sl-copy-button value="I'm so stylish" class="custom-styles">
<sl-icon slot="copy-icon" name="asterisk"></sl-icon>
<sl-icon slot="success-icon" name="check-lg"></sl-icon>
<sl-icon slot="error-icon" name="x-lg"></sl-icon>
</sl-copy-button>
<style>
.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;
}
</style>
```
```jsx:react
import { SlCopyButton } from '@shoelace-style/shoelace/dist/react/sl-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 = () => (
<>
<SlCopyButton value="I'm so stylish" className="custom-styles" />
<style>{css}</style>
</>
);
```

View File

@@ -15,7 +15,7 @@ layout: component
```
```jsx:react
import { SlDetails } from '@shoelace-style/shoelace/dist/react';
import SlDetails from '@shoelace-style/shoelace/dist/react/sl-details';
const App = () => (
<SlDetails summary="Toggle Me">
@@ -39,7 +39,7 @@ Use the `disable` attribute to prevent the details from expanding.
```
```jsx:react
import { SlDetails } from '@shoelace-style/shoelace/dist/react';
import SlDetails from '@shoelace-style/shoelace/dist/react/sl-details';
const App = () => (
<SlDetails summary="Disabled" disabled>
@@ -71,7 +71,8 @@ Use the `expand-icon` and `collapse-icon` slots to change the expand and collaps
```
```jsx:react
import { SlDetails, SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlDetails from '@shoelace-style/shoelace/dist/react/sl-details';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
const css = `
sl-details.custom-icon::part(summary-icon) {

View File

@@ -27,7 +27,8 @@ layout: component
```jsx:react
import { useState } from 'react';
import { SlButton, SlDialog } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDialog from '@shoelace-style/shoelace/dist/react/sl-dialog';
const App = () => {
const [open, setOpen] = useState(false);
@@ -75,7 +76,8 @@ Use the `--width` custom property to set the dialog's width.
```jsx:react
import { useState } from 'react';
import { SlButton, SlDialog } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDialog from '@shoelace-style/shoelace/dist/react/sl-dialog';
const App = () => {
const [open, setOpen] = useState(false);
@@ -125,7 +127,8 @@ By design, a dialog's height will never exceed that of the viewport. As such, di
```jsx:react
import { useState } from 'react';
import { SlButton, SlDialog } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDialog from '@shoelace-style/shoelace/dist/react/sl-dialog';
const App = () => {
const [open, setOpen] = useState(false);
@@ -183,7 +186,9 @@ The header shows a functional close button by default. You can use the `header-a
```jsx:react
import { useState } from 'react';
import { SlButton, SlDialog, SlIconButton } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDialog from '@shoelace-style/shoelace/dist/react/sl-dialog';
import SlIconButton from '@shoelace-style/shoelace/dist/react/sl-icon-button';
const App = () => {
const [open, setOpen] = useState(false);
@@ -244,7 +249,8 @@ You can use `event.detail.source` to determine what triggered the request to clo
```jsx:react
import { useState } from 'react';
import { SlButton, SlDialog } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDialog from '@shoelace-style/shoelace/dist/react/sl-dialog';
const App = () => {
const [open, setOpen] = useState(false);
@@ -296,7 +302,9 @@ By default, the dialog's panel will gain focus when opened. This allows a subseq
```jsx:react
import { useState } from 'react';
import { SlButton, SlDialog, SlInput } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDialog from '@shoelace-style/shoelace/dist/react/sl-dialog';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
const App = () => {
const [open, setOpen] = useState(false);

View File

@@ -10,7 +10,7 @@ layout: component
```
```jsx:react
import { SlDivider } from '@shoelace-style/shoelace/dist/react';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
const App = () => <SlDivider />;
```
@@ -28,7 +28,7 @@ Use the `--width` custom property to change the width of the divider.
{% raw %}
```jsx:react
import { SlDivider } from '@shoelace-style/shoelace/dist/react';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
const App = () => <SlDivider style={{ '--width': '4px' }} />;
```
@@ -46,7 +46,7 @@ Use the `--color` custom property to change the color of the divider.
{% raw %}
```jsx:react
import { SlDivider } from '@shoelace-style/shoelace/dist/react';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
const App = () => <SlDivider style={{ '--color': 'tomato' }} />;
```
@@ -68,7 +68,7 @@ Use the `--spacing` custom property to change the amount of space between the di
{% raw %}
```jsx:react
import { SlDivider } from '@shoelace-style/shoelace/dist/react';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
const App = () => (
<>
@@ -98,7 +98,7 @@ Add the `vertical` attribute to draw the divider in a vertical orientation. The
{% raw %}
```jsx:react
import { SlDivider } from '@shoelace-style/shoelace/dist/react';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
const App = () => (
<div
@@ -138,7 +138,9 @@ Use dividers in [menus](/components/menu) to visually group menu items.
{% raw %}
```jsx:react
import { SlDivider, SlMenu, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
import SlMenu from '@shoelace-style/shoelace/dist/react/sl-menu';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const App = () => (
<SlMenu style={{ maxWidth: '200px' }}>

View File

@@ -27,7 +27,8 @@ layout: component
```jsx:react
import { useState } from 'react';
import { SlButton, SlDrawer } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDrawer from '@shoelace-style/shoelace/dist/react/sl-drawer';
const App = () => {
const [open, setOpen] = useState(false);
@@ -73,7 +74,8 @@ By default, drawers slide in from the end. To make the drawer slide in from the
```jsx:react
import { useState } from 'react';
import { SlButton, SlDrawer } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDrawer from '@shoelace-style/shoelace/dist/react/sl-drawer';
const App = () => {
const [open, setOpen] = useState(false);
@@ -117,7 +119,8 @@ To make the drawer slide in from the top, set the `placement` attribute to `top`
```jsx:react
import { useState } from 'react';
import { SlButton, SlDrawer } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDrawer from '@shoelace-style/shoelace/dist/react/sl-drawer';
const App = () => {
const [open, setOpen] = useState(false);
@@ -161,7 +164,8 @@ To make the drawer slide in from the bottom, set the `placement` attribute to `b
```jsx:react
import { useState } from 'react';
import { SlButton, SlDrawer } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDrawer from '@shoelace-style/shoelace/dist/react/sl-drawer';
const App = () => {
const [open, setOpen] = useState(false);
@@ -215,7 +219,8 @@ Unlike normal drawers, contained drawers are not modal. This means they do not s
```jsx:react
import { useState } from 'react';
import { SlButton, SlDrawer } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDrawer from '@shoelace-style/shoelace/dist/react/sl-drawer';
const App = () => {
const [open, setOpen] = useState(false);
@@ -282,7 +287,8 @@ Use the `--size` custom property to set the drawer's size. This will be applied
```jsx:react
import { useState } from 'react';
import { SlButton, SlDrawer } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDrawer from '@shoelace-style/shoelace/dist/react/sl-drawer';
const App = () => {
const [open, setOpen] = useState(false);
@@ -332,7 +338,8 @@ By design, a drawer's height will never exceed 100% of its container. As such, d
```jsx:react
import { useState } from 'react';
import { SlButton, SlDrawer } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDrawer from '@shoelace-style/shoelace/dist/react/sl-drawer';
const App = () => {
const [open, setOpen] = useState(false);
@@ -389,7 +396,9 @@ The header shows a functional close button by default. You can use the `header-a
```jsx:react
import { useState } from 'react';
import { SlButton, SlDrawer, SlIconButton } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDrawer from '@shoelace-style/shoelace/dist/react/sl-drawer';
import SlIconButton from '@shoelace-style/shoelace/dist/react/sl-icon-button';
const App = () => {
const [open, setOpen] = useState(false);
@@ -445,7 +454,8 @@ You can use `event.detail.source` to determine what triggered the request to clo
```jsx:react
import { useState } from 'react';
import { SlButton, SlDrawer } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDrawer from '@shoelace-style/shoelace/dist/react/sl-drawer';
const App = () => {
const [open, setOpen] = useState(false);
@@ -497,7 +507,9 @@ By default, the drawer's panel will gain focus when opened. This allows a subseq
```jsx:react
import { useState } from 'react';
import { SlButton, SlDrawer, SlInput } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDrawer from '@shoelace-style/shoelace/dist/react/sl-drawer';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
const App = () => {
const [open, setOpen] = useState(false);

View File

@@ -33,7 +33,12 @@ Dropdowns are designed to work well with [menus](/components/menu) to provide a
```
```jsx:react
import { SlButton, SlDivider, SlDropdown, SlIcon, SlMenu, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
import SlDropdown from '@shoelace-style/shoelace/dist/react/sl-dropdown';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
import SlMenu from '@shoelace-style/shoelace/dist/react/sl-menu';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const App = () => (
<SlDropdown>
@@ -93,7 +98,10 @@ When dropdowns are used with [menus](/components/menu), you can listen for the [
```
```jsx:react
import { SlButton, SlDropdown, SlMenu, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDropdown from '@shoelace-style/shoelace/dist/react/sl-dropdown';
import SlMenu from '@shoelace-style/shoelace/dist/react/sl-menu';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const App = () => {
function handleSelect(event) {
@@ -143,7 +151,10 @@ Alternatively, you can listen for the `click` event on individual menu items. No
```
```jsx:react
import { SlButton, SlDropdown, SlMenu, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDropdown from '@shoelace-style/shoelace/dist/react/sl-dropdown';
import SlMenu from '@shoelace-style/shoelace/dist/react/sl-menu';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const App = () => {
function handleCut() {
@@ -192,7 +203,11 @@ The preferred placement of the dropdown can be set with the `placement` attribut
```
```jsx:react
import { SlButton, SlDivider, SlDropdown, SlMenu, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
import SlDropdown from '@shoelace-style/shoelace/dist/react/sl-dropdown';
import SlMenu from '@shoelace-style/shoelace/dist/react/sl-menu';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const App = () => (
<SlDropdown placement="top-start">
@@ -230,7 +245,11 @@ The distance from the panel to the trigger can be customized using the `distance
```
```jsx:react
import { SlButton, SlDivider, SlDropdown, SlMenu, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
import SlDropdown from '@shoelace-style/shoelace/dist/react/sl-dropdown';
import SlMenu from '@shoelace-style/shoelace/dist/react/sl-menu';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const App = () => (
<SlDropdown distance={30}>
@@ -268,7 +287,11 @@ The offset of the panel along the trigger can be customized using the `skidding`
```
```jsx:react
import { SlButton, SlDivider, SlDropdown, SlMenu, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
import SlDropdown from '@shoelace-style/shoelace/dist/react/sl-dropdown';
import SlMenu from '@shoelace-style/shoelace/dist/react/sl-menu';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const App = () => (
<SlDropdown skidding={30}>
@@ -323,7 +346,12 @@ Dropdown panels will be clipped if they're inside a container that has `overflow
```
```jsx:react
import { SlButton, SlDivider, SlDropdown, SlIcon, SlMenu, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
import SlDropdown from '@shoelace-style/shoelace/dist/react/sl-dropdown';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
import SlMenu from '@shoelace-style/shoelace/dist/react/sl-menu';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const css = `
.dropdown-hoist {

View File

@@ -24,7 +24,9 @@ layout: component
```jsx:react
import { useState } from 'react';
import { SlButton, SlFormatBytes, SlInput } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlFormatBytes from '@shoelace-style/shoelace/dist/react/sl-format-bytes';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
const App = () => {
const [value, setValue] = useState(1000);
@@ -62,7 +64,7 @@ Set the `value` attribute to a number to get the value in bytes.
```
```jsx:react
import { SlFormatBytes } from '@shoelace-style/shoelace/dist/react';
import SlFormatBytes from '@shoelace-style/shoelace/dist/react/sl-format-bytes';
const App = () => (
<>
@@ -89,7 +91,7 @@ To get the value in bits, set the `unit` attribute to `bit`.
```
```jsx:react
import { SlFormatBytes } from '@shoelace-style/shoelace/dist/react';
import SlFormatBytes from '@shoelace-style/shoelace/dist/react/sl-format-bytes';
const App = () => (
<>
@@ -116,7 +118,7 @@ Use the `lang` attribute to set the number formatting locale.
```
```jsx:react
import { SlFormatBytes } from '@shoelace-style/shoelace/dist/react';
import SlFormatBytes from '@shoelace-style/shoelace/dist/react/sl-format-bytes';
const App = () => (
<>

View File

@@ -13,7 +13,7 @@ Localization is handled by the browser's [`Intl.DateTimeFormat` API](https://dev
```
```jsx:react
import { SlFormatDate } from '@shoelace-style/shoelace/dist/react';
import SlFormatDate from '@shoelace-style/shoelace/dist/react/sl-format-date';
const App = () => <SlFormatDate date="2020-07-15T09:17:00-04:00" />;
```
@@ -51,7 +51,7 @@ Formatting options are based on those found in the [`Intl.DateTimeFormat` API](h
```
```jsx:react
import { SlFormatDate } from '@shoelace-style/shoelace/dist/react';
import SlFormatDate from '@shoelace-style/shoelace/dist/react/sl-format-date';
const App = () => (
<>
@@ -91,7 +91,7 @@ By default, the browser will determine whether to use 12-hour or 24-hour time. T
```
```jsx:react
import { SlFormatDate } from '@shoelace-style/shoelace/dist/react';
import SlFormatDate from '@shoelace-style/shoelace/dist/react/sl-format-date';
const App = () => (
<>
@@ -113,7 +113,7 @@ Russian: <sl-format-date lang="ru"></sl-format-date>
```
```jsx:react
import { SlFormatDate } from '@shoelace-style/shoelace/dist/react';
import SlFormatDate from '@shoelace-style/shoelace/dist/react/sl-format-date';
const App = () => (
<>

View File

@@ -27,7 +27,8 @@ Localization is handled by the browser's [`Intl.NumberFormat` API](https://devel
```jsx:react
import { useState } from 'react';
import { SlFormatNumber, SlInput } from '@shoelace-style/shoelace/dist/react';
import SlFormatNumber from '@shoelace-style/shoelace/dist/react/format-number';
import SlInput from '@shoelace-style/shoelace/dist/react/input';
const App = () => {
const [value, setValue] = useState(1000);
@@ -66,7 +67,7 @@ To get the value as a percent, set the `type` attribute to `percent`.
```
```jsx:react
import { SlFormatNumber } from '@shoelace-style/shoelace/dist/react';
import SlFormatNumber from '@shoelace-style/shoelace/dist/react/format-number';
const App = () => (
<>
@@ -94,7 +95,7 @@ Russian: <sl-format-number value="2000" lang="ru" minimum-fraction-digits="2"></
```
```jsx:react
import { SlFormatNumber } from '@shoelace-style/shoelace/dist/react';
import SlFormatNumber from '@shoelace-style/shoelace/dist/react/sl-format-number';
const App = () => (
<>
@@ -120,7 +121,7 @@ To format a number as a monetary value, set the `type` attribute to `currency` a
```
```jsx:react
import { SlFormatNumber } from '@shoelace-style/shoelace/dist/react';
import SlFormatNumber from '@shoelace-style/shoelace/dist/react/sl-format-number';
const App = () => (
<>

View File

@@ -12,7 +12,7 @@ For a full list of icons that come bundled with Shoelace, refer to the [icon com
```
```jsx:react
import { SlIconButton } from '@shoelace-style/shoelace/dist/react';
import SlIconButton from '@shoelace-style/shoelace/dist/react/sl-icon-button';
const App = () => <SlIconButton name="gear" label="Settings" />;
```
@@ -32,7 +32,7 @@ Icon buttons inherit their parent element's `font-size`.
{% raw %}
```jsx:react
import { SlIconButton } from '@shoelace-style/shoelace/dist/react';
import SlIconButton from '@shoelace-style/shoelace/dist/react/sl-icon-button';
const App = () => (
<>
@@ -73,7 +73,7 @@ Icon buttons are designed to have a uniform appearance, so their color is not in
```
```jsx:react
import { SlIconButton } from '@shoelace-style/shoelace/dist/react';
import SlIconButton from '@shoelace-style/shoelace/dist/react/sl-icon-button';
const css = `
.icon-button-color sl-icon-button::part(base) {
@@ -112,7 +112,7 @@ Use the `href` attribute to convert the button to a link.
```
```jsx:react
import { SlIconButton } from '@shoelace-style/shoelace/dist/react';
import SlIconButton from '@shoelace-style/shoelace/dist/react/sl-icon-button';
const App = () => <SlIconButton name="gear" label="Settings" href="https://example.com" target="_blank" />;
```
@@ -128,7 +128,8 @@ Wrap a tooltip around an icon button to provide contextual information to the us
```
```jsx:react
import { SlIconButton, SlTooltip } from '@shoelace-style/shoelace/dist/react';
import SlIconButton from '@shoelace-style/shoelace/dist/react/sl-icon-button';
import SlTooltip from '@shoelace-style/shoelace/dist/react/sl-tooltip';
const App = () => (
<SlTooltip content="Settings">
@@ -146,7 +147,7 @@ Use the `disabled` attribute to disable the icon button.
```
```jsx:react
import { SlIconButton } from '@shoelace-style/shoelace/dist/react';
import SlIconButton from '@shoelace-style/shoelace/dist/react/sl-icon-button';
const App = () => <SlIconButton name="gear" label="Settings" disabled />;
```

View File

@@ -70,7 +70,7 @@ Icons inherit their color from the current text color. Thus, you can set the `co
{% raw %}
```jsx:react
import { SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
const App = () => (
<>
@@ -132,7 +132,7 @@ Icons are sized relative to the current font size. To change their size, set the
{% raw %}
```jsx:react
import { SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
const App = () => (
<div style={{ fontSize: '32px' }}>
@@ -167,7 +167,7 @@ For non-decorative icons, use the `label` attribute to announce it to assistive
```
```jsx:react
import { SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
const App = () => <SlIcon name="star-fill" label="Add to favorites" />;
```
@@ -183,7 +183,7 @@ Custom icons can be loaded individually with the `src` attribute. Only SVGs on a
{% raw %}
```jsx:react
import { SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
const App = () => <SlIcon src="https://shoelace.style/assets/images/shoe.svg" style={{ fontSize: '8rem' }}></SlIcon>;
```
@@ -645,9 +645,7 @@ When using sprite sheets, the `sl-load` and `sl-error` events will not fire.
:::
:::danger
For security reasons, browsers may apply the same-origin policy on `<use>` elements located in the `<sl-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.
For security reasons, browsers may apply the same-origin policy on `<use>` elements located in the `<sl-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:preview

View File

@@ -23,7 +23,7 @@ For best results, use images that share the same dimensions. The slider can be c
```
```jsx:react
import { SlImageComparer } from '@shoelace-style/shoelace/dist/react';
import SlImageComparer from '@shoelace-style/shoelace/dist/react/sl-image-comparer';
const App = () => (
<SlImageComparer>
@@ -63,7 +63,7 @@ Use the `position` attribute to set the initial position of the slider. This is
```
```jsx:react
import { SlImageComparer } from '@shoelace-style/shoelace/dist/react';
import SlImageComparer from '@shoelace-style/shoelace/dist/react/sl-image-comparer';
const App = () => (
<SlImageComparer position={25}>

View File

@@ -14,7 +14,7 @@ The included content will be inserted into the `<sl-include>` element's default
```
```jsx:react
import { SlInclude } from '@shoelace-style/shoelace/dist/react';
import SlInclude from '@shoelace-style/shoelace/dist/react/sl-include';
const App = () => <SlInclude src="https://shoelace.style/assets/examples/include.html" />;
```

View File

@@ -10,7 +10,7 @@ layout: component
```
```jsx:react
import { SlInput } from '@shoelace-style/shoelace/dist/react';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
const App = () => <SlInput />;
```
@@ -30,7 +30,8 @@ Use the `label` attribute to give the input an accessible label. For labels that
```
```jsx:react
import { SlIcon, SlInput } from '@shoelace-style/shoelace/dist/react';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
const App = () => <SlInput label="What is your name?" />;
```
@@ -44,7 +45,8 @@ Add descriptive help text to an input with the `help-text` attribute. For help t
```
```jsx:react
import { SlIcon, SlInput } from '@shoelace-style/shoelace/dist/react';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
const App = () => <SlInput label="Nickname" help-text="What would you like people to call you?" />;
```
@@ -58,7 +60,7 @@ Use the `placeholder` attribute to add a placeholder.
```
```jsx:react
import { SlInput } from '@shoelace-style/shoelace/dist/react';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
const App = () => <SlInput placeholder="Type something" />;
```
@@ -72,7 +74,7 @@ Add the `clearable` attribute to add a clear button when the input has content.
```
```jsx:react
import { SlInput } from '@shoelace-style/shoelace/dist/react';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
const App = () => <SlInput placeholder="Clearable" clearable />;
```
@@ -86,7 +88,7 @@ Add the `password-toggle` attribute to add a toggle button that will show the pa
```
```jsx:react
import { SlInput } from '@shoelace-style/shoelace/dist/react';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
const App = () => <SlInput type="password" placeholder="Password Toggle" size="medium" password-toggle />;
```
@@ -100,7 +102,7 @@ Add the `filled` attribute to draw a filled input.
```
```jsx:react
import { SlInput } from '@shoelace-style/shoelace/dist/react';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
const App = () => <SlInput placeholder="Type something" filled />;
```
@@ -114,7 +116,7 @@ Use the `disabled` attribute to disable an input.
```
```jsx:react
import { SlInput } from '@shoelace-style/shoelace/dist/react';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
const App = () => <SlInput placeholder="Disabled" disabled />;
```
@@ -132,7 +134,7 @@ Use the `size` attribute to change an input's size.
```
```jsx:react
import { SlInput } from '@shoelace-style/shoelace/dist/react';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
const App = () => (
<>
@@ -158,7 +160,7 @@ Use the `pill` attribute to give inputs rounded edges.
```
```jsx:react
import { SlInput } from '@shoelace-style/shoelace/dist/react';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
const App = () => (
<>
@@ -184,7 +186,7 @@ The `type` attribute controls the type of input the browser renders.
```
```jsx:react
import { SlInput } from '@shoelace-style/shoelace/dist/react';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
const App = () => (
<>
@@ -219,7 +221,8 @@ Use the `prefix` and `suffix` slots to add icons.
```
```jsx:react
import { SlIcon, SlInput } from '@shoelace-style/shoelace/dist/react';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
const App = () => (
<>

View File

@@ -28,7 +28,10 @@ layout: component
{% raw %}
```jsx:react
import { SlDivider, SlIcon, SlMenu, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
import SlMenu from '@shoelace-style/shoelace/dist/react/sl-menu';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const App = () => (
<SlMenu style={{ maxWidth: '200px' }}>
@@ -72,7 +75,8 @@ Add the `disabled` attribute to disable the menu item so it cannot be selected.
{% raw %}
```jsx:react
import { SlMenu, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlMenu from '@shoelace-style/shoelace/dist/react/sl-menu';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const App = () => (
<SlMenu style={{ maxWidth: '200px' }}>
@@ -114,7 +118,11 @@ Add content to the start and end of menu items using the `prefix` and `suffix` s
{% raw %}
```jsx:react
import { SlBadge, SlDivider, SlIcon, SlMenu, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlBadge from '@shoelace-style/shoelace/dist/react/sl-badge';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
import SlMenu from '@shoelace-style/shoelace/dist/react/sl-menu';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const App = () => (
<SlMenu style={{ maxWidth: '200px' }}>
@@ -160,7 +168,8 @@ Checkbox menu items are visually indistinguishable from regular menu items. Thei
{% raw %}
```jsx:react
import { SlMenu, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlMenu from '@shoelace-style/shoelace/dist/react/sl-menu';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const App = () => (
<SlMenu style={{ maxWidth: '200px' }}>
@@ -209,7 +218,8 @@ The `value` attribute can be used to assign a hidden value, such as a unique ide
{% raw %}
```jsx:react
import { SlMenu, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlMenu from '@shoelace-style/shoelace/dist/react/sl-menu';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const App = () => {
function handleSelect(event) {

View File

@@ -22,7 +22,10 @@ layout: component
{% raw %}
```jsx:react
import { SlDivider, SlMenu, SlMenuLabel, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
import SlMenu from '@shoelace-style/shoelace/dist/react/sl-menu';
import SlMenuLabel from '@shoelace-style/shoelace/dist/react/sl-menu-label';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const App = () => (
<SlMenu style={{ maxWidth: '200px' }}>

View File

@@ -22,7 +22,9 @@ You can use [menu items](/components/menu-item), [menu labels](/components/menu-
{% raw %}
```jsx:react
import { SlDivider, SlMenu, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
import SlMenu from '@shoelace-style/shoelace/dist/react/sl-menu';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const App = () => (
<SlMenu style={{ maxWidth: '200px' }}>

View File

@@ -45,7 +45,8 @@ The mutation observer will report changes to the content it wraps through the `s
```jsx:react
import { useState } from 'react';
import { SlButton, SlMutationObserver } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlMutationObserver from '@shoelace-style/shoelace/dist/react/sl-mutation-observer';
const css = `
.resize-observer-overview div {
@@ -146,7 +147,8 @@ Use the `child-list` attribute to watch for new child elements that are added or
```jsx:react
import { useState } from 'react';
import { SlButton, SlMutationObserver } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlMutationObserver from '@shoelace-style/shoelace/dist/react/sl-mutation-observer';
const css = `
.mutation-child-list .buttons {

View File

@@ -14,7 +14,8 @@ layout: component
```
```jsx:react
import { SlOption, SlSelect } from '@shoelace-style/shoelace/dist/react';
import SlOption from '@shoelace-style/shoelace/dist/react/sl-option';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
const App = () => (
<SlSelect>
@@ -40,7 +41,8 @@ Use the `disabled` attribute to disable an option and prevent it from being sele
```
```jsx:react
import { SlOption, SlSelect } from '@shoelace-style/shoelace/dist/react';
import SlOption from '@shoelace-style/shoelace/dist/react/sl-option';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
const App = () => (
<SlSelect>

View File

@@ -104,7 +104,11 @@ Popup is a low-level utility built specifically for positioning elements. Do not
```jsx:react
import { useState } from 'react';
import { SlPopup, SlSelect, SlMenuItem, SlInput, SlSwitch } from '@shoelace-style/shoelace/dist/react';
import SlPopup from '@shoelace-style/shoelace/dist/react/sl-popup';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
import SlSwitch from '@shoelace-style/shoelace/dist/react/sl-switch';
const css = `
.popup-overview sl-popup {
@@ -269,7 +273,8 @@ Popups are inactive and hidden until the `active` attribute is applied. Removing
```jsx:react
import { useState } from 'react';
import { SlPopup, SlSwitch } from '@shoelace-style/shoelace/dist/react';
import SlPopup from '@shoelace-style/shoelace/dist/react/sl-popup';
import SlSwitch from '@shoelace-style/shoelace/dist/react/sl-switch';
const css = `
.popup-active span[slot='anchor'] {
@@ -341,7 +346,7 @@ By default, anchors are slotted into the popup using the `anchor` slot. If your
```
```jsx:react
import { SlPopup } from '@shoelace-style/shoelace/dist/react';
import SlPopup from '@shoelace-style/shoelace/dist/react/sl-popup';
const css = `
#external-anchor {
@@ -436,7 +441,9 @@ Since placement is preferred when using `flip`, you can observe the popup's curr
```jsx:react
import { useState } from 'react';
import { SlPopup, SlSelect, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlPopup from '@shoelace-style/shoelace/dist/react/sl-popup';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const css = `
.popup-placement span[slot='anchor'] {
@@ -538,7 +545,8 @@ Use the `distance` attribute to change the distance between the popup and its an
```jsx:react
import { useState } from 'react';
import { SlPopup, SlRange } from '@shoelace-style/shoelace/dist/react';
import SlPopup from '@shoelace-style/shoelace/dist/react/sl-popup';
import SlRange from '@shoelace-style/shoelace/dist/react/sl-range';
const css = `
.popup-distance span[slot='anchor'] {
@@ -634,7 +642,8 @@ The `skidding` attribute is similar to `distance`, but instead allows you to off
```jsx:react
import { useState } from 'react';
import { SlPopup, SlRange } from '@shoelace-style/shoelace/dist/react';
import SlPopup from '@shoelace-style/shoelace/dist/react/sl-popup';
import SlRange from '@shoelace-style/shoelace/dist/react/sl-range';
const css = `
.popup-skidding span[slot='anchor'] {
@@ -777,7 +786,10 @@ By default, the arrow will be aligned as close to the center of the _anchor_ as
```jsx:react
import { useState } from 'react';
import { SlPopup, SlSelect, SlMenuItem, SlSwitch } from '@shoelace-style/shoelace/dist/react';
import SlPopup from '@shoelace-style/shoelace/dist/react/sl-popup';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
import SlSwitch from '@shoelace-style/shoelace/dist/react/sl-switch';
const css = `
.popup-arrow sl-popup {
@@ -930,7 +942,9 @@ Use the `sync` attribute to make the popup the same width or height as the ancho
```jsx:react
import { useState } from 'react';
import { SlPopup, SlSelect, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlPopup from '@shoelace-style/shoelace/dist/react/sl-popup';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const css = `
.popup-sync span[slot='anchor'] {
@@ -1041,7 +1055,8 @@ Toggle the switch and scroll the container to see the difference.
```jsx:react
import { useState } from 'react';
import { SlPopup, SlSwitch } from '@shoelace-style/shoelace/dist/react';
import SlPopup from '@shoelace-style/shoelace/dist/react/sl-popup';
import SlSwitch from '@shoelace-style/shoelace/dist/react/sl-switch';
const css = `
.popup-strategy .overflow {
@@ -1149,7 +1164,8 @@ Scroll the container to see how the popup flips to prevent clipping.
```jsx:react
import { useState } from 'react';
import { SlPopup, SlSwitch } from '@shoelace-style/shoelace/dist/react';
import SlPopup from '@shoelace-style/shoelace/dist/react/sl-popup';
import SlSwitch from '@shoelace-style/shoelace/dist/react/sl-switch';
const css = `
.popup-flip .overflow {
@@ -1246,7 +1262,7 @@ Scroll the container to see how the popup changes it's fallback placement to pre
```
```jsx:react
import { SlPopup } from '@shoelace-style/shoelace/dist/react';
import SlPopup from '@shoelace-style/shoelace/dist/react/sl-popup';
const css = `
.popup-flip-fallbacks .overflow {
@@ -1342,7 +1358,8 @@ Toggle the switch to see the difference.
```jsx:react
import { useState } from 'react';
import { SlPopup, SlSwitch } from '@shoelace-style/shoelace/dist/react';
import SlPopup from '@shoelace-style/shoelace/dist/react/sl-popup';
import SlSwitch from '@shoelace-style/shoelace/dist/react/sl-switch';
const css = `
.popup-shift .overflow {
@@ -1454,7 +1471,8 @@ Scroll the container to see the popup resize as its available space changes.
```jsx:react
import { useState } from 'react';
import { SlPopup, SlSwitch } from '@shoelace-style/shoelace/dist/react';
import SlPopup from '@shoelace-style/shoelace/dist/react/sl-popup';
import SlSwitch from '@shoelace-style/shoelace/dist/react/sl-switch';
const css = `
.popup-auto-size .overflow {
@@ -1605,7 +1623,8 @@ This example anchors a popup to the mouse cursor using a virtual element. As suc
```jsx:react
import { useRef, useState } from 'react';
import { SlPopup, SlSwitch } from '@shoelace-style/shoelace/dist/react';
import SlPopup from '@shoelace-style/shoelace/dist/react/sl-popup';
import SlSwitch from '@shoelace-style/shoelace/dist/react/sl-switch';
const css = `
/* If you need to set a z-index, set it on the popup part like this */

View File

@@ -10,7 +10,7 @@ layout: component
```
```jsx:react
import { SlProgressBar } from '@shoelace-style/shoelace/dist/react';
import SlProgressBar from '@shoelace-style/shoelace/dist/react/sl-progress-bar';
const App = () => <SlProgressBar value={50} />;
```
@@ -26,7 +26,7 @@ Use the `label` attribute to label the progress bar and tell assistive devices h
```
```jsx:react
import { SlProgressBar } from '@shoelace-style/shoelace/dist/react';
import SlProgressBar from '@shoelace-style/shoelace/dist/react/sl-progress-bar';
const App = () => <SlProgressBar value="50" label="Upload progress" />;
```
@@ -42,7 +42,7 @@ Use the `--height` custom property to set the progress bar's height.
{% raw %}
```jsx:react
import { SlProgressBar } from '@shoelace-style/shoelace/dist/react';
import SlProgressBar from '@shoelace-style/shoelace/dist/react/sl-progress-bar';
const App = () => <SlProgressBar value={50} style={{ '--height': '6px' }} />;
```
@@ -82,7 +82,9 @@ Use the default slot to show a value.
```jsx:react
import { useState } from 'react';
import { SlButton, SlIcon, SlProgressBar } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
import SlProgressBar from '@shoelace-style/shoelace/dist/react/sl-progress-bar';
const App = () => {
const [value, setValue] = useState(50);
@@ -121,7 +123,7 @@ The `indeterminate` attribute can be used to inform the user that the operation
```
```jsx:react
import { SlProgressBar } from '@shoelace-style/shoelace/dist/react';
import SlProgressBar from '@shoelace-style/shoelace/dist/react/sl-progress-bar';
const App = () => <SlProgressBar indeterminate />;
```

View File

@@ -10,7 +10,7 @@ layout: component
```
```jsx:react
import { SlProgressRing } from '@shoelace-style/shoelace/dist/react';
import SlProgressRing from '@shoelace-style/shoelace/dist/react/sl-progress-ring';
const App = () => <SlProgressRing value="25" />;
```
@@ -28,7 +28,7 @@ Use the `--size` custom property to set the diameter of the progress ring.
{% raw %}
```jsx:react
import { SlProgressRing } from '@shoelace-style/shoelace/dist/react';
import SlProgressRing from '@shoelace-style/shoelace/dist/react/sl-progress-ring';
const App = () => <SlProgressRing value="50" style={{ '--size': '200px' }} />;
```
@@ -46,7 +46,7 @@ Use the `--track-width` and `--indicator-width` custom properties to set the wid
{% raw %}
```jsx:react
import { SlProgressRing } from '@shoelace-style/shoelace/dist/react';
import SlProgressRing from '@shoelace-style/shoelace/dist/react/sl-progress-ring';
const App = () => <SlProgressRing value="50" style={{ '--track-width': '6px', '--indicator-width': '12px' }} />;
```
@@ -70,7 +70,7 @@ To change the color, use the `--track-color` and `--indicator-color` custom prop
{% raw %}
```jsx:react
import { SlProgressRing } from '@shoelace-style/shoelace/dist/react';
import SlProgressRing from '@shoelace-style/shoelace/dist/react/sl-progress-ring';
const App = () => (
<SlProgressRing
@@ -94,7 +94,7 @@ Use the `label` attribute to label the progress ring and tell assistive devices
```
```jsx:react
import { SlProgressRing } from '@shoelace-style/shoelace/dist/react';
import SlProgressRing from '@shoelace-style/shoelace/dist/react/sl-progress-ring';
const App = () => <SlProgressRing value="50" label="Upload progress" />;
```
@@ -134,7 +134,9 @@ Use the default slot to show a label inside the progress ring.
```jsx:react
import { useState } from 'react';
import { SlButton, SlIcon, SlProgressRing } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
import SlProgressRing from '@shoelace-style/shoelace/dist/react/sl-progress-ring';
const App = () => {
const [value, setValue] = useState(50);

View File

@@ -39,7 +39,8 @@ QR codes are useful for providing small pieces of information to users who can q
```jsx:react
import { useState } from 'react';
import { SlQrCode, SlInput } from '@shoelace-style/shoelace/dist/react';
import SlQrCode from '@shoelace-style/shoelace/dist/react/sl-qr-code';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
const css = `
.qr-overview {
@@ -80,7 +81,7 @@ Use the `fill` and `background` attributes to modify the QR code's colors. You s
```
```jsx:react
import { SlQrCode } from '@shoelace-style/shoelace/dist/react';
import SlQrCode from '@shoelace-style/shoelace/dist/react/sl-qr-code';
const App = () => <SlQrCode value="https://shoelace.style/" fill="deeppink" background="white" />;
```
@@ -94,7 +95,7 @@ Use the `size` attribute to change the size of the QR code.
```
```jsx:react
import { SlQrCode } from '@shoelace-style/shoelace/dist/react';
import SlQrCode from '@shoelace-style/shoelace/dist/react/sl-qr-code';
const App = () => <SlQrCode value="https://shoelace.style/" size="64" />;
```
@@ -108,7 +109,7 @@ Create a rounded effect with the `radius` attribute.
```
```jsx:react
import { SlQrCode } from '@shoelace-style/shoelace/dist/react';
import SlQrCode from '@shoelace-style/shoelace/dist/react/sl-qr-code';
const App = () => <SlQrCode value="https://shoelace.style/" radius="0.5" />;
```
@@ -135,7 +136,7 @@ QR codes can be rendered with various levels of [error correction](https://www.q
```
```jsx:react
import { SlQrCode } from '@shoelace-style/shoelace/dist/react';
import SlQrCode from '@shoelace-style/shoelace/dist/react/sl-qr-code';
const css = `
.qr-error-correction {

View File

@@ -16,7 +16,8 @@ Radio buttons are designed to be used with [radio groups](/components/radio-grou
```
```jsx:react
import { SlRadioButton, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
import SlRadioButton from '@shoelace-style/shoelace/dist/react/sl-radio-button';
import SlRadioGroup from '@shoelace-style/shoelace/dist/react/sl-radio-group';
const App = () => (
<SlRadioGroup label="Select an option" name="a" value="1">
@@ -42,7 +43,8 @@ To set the initial value and checked state, use the `value` attribute on the con
```
```jsx:react
import { SlRadioButton, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
import SlRadioButton from '@shoelace-style/shoelace/dist/react/sl-radio-button';
import SlRadioGroup from '@shoelace-style/shoelace/dist/react/sl-radio-group';
const App = () => (
<SlRadioGroup label="Select an option" name="a" value="1">
@@ -66,7 +68,8 @@ Use the `disabled` attribute to disable a radio button.
```
```jsx:react
import { SlRadioButton, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
import SlRadioButton from '@shoelace-style/shoelace/dist/react/sl-radio-button';
import SlRadioGroup from '@shoelace-style/shoelace/dist/react/sl-radio-group';
const App = () => (
<SlRadioGroup label="Select an option" name="a" value="1">
@@ -108,7 +111,8 @@ Use the `size` attribute to change a radio button's size.
```
```jsx:react
import { SlRadioButton, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
import SlRadioButton from '@shoelace-style/shoelace/dist/react/sl-radio-button';
import SlRadioGroup from '@shoelace-style/shoelace/dist/react/sl-radio-group';
const App = () => (
<SlRadioGroup label="Select an option" name="a" value="1">
@@ -164,7 +168,8 @@ Use the `pill` attribute to give radio buttons rounded edges.
```
```jsx:react
import { SlRadioButton, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
import SlRadioButton from '@shoelace-style/shoelace/dist/react/sl-radio-button';
import SlRadioGroup from '@shoelace-style/shoelace/dist/react/sl-radio-group';
const App = () => (
<SlRadioGroup label="Select an option" name="a" value="1">
@@ -216,7 +221,9 @@ Use the `prefix` and `suffix` slots to add icons.
```
```jsx:react
import { SlIcon, SlRadioButton, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
import SlRadioButton from '@shoelace-style/shoelace/dist/react/sl-radio-button';
import SlRadioGroup from '@shoelace-style/shoelace/dist/react/sl-radio-group';
const App = () => (
<SlRadioGroup label="Select an option" name="a" value="1">
@@ -268,7 +275,9 @@ You can omit button labels and use icons instead. Make sure to set a `label` att
```
```jsx:react
import { SlIcon, SlRadioButton, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
import SlRadioButton from '@shoelace-style/shoelace/dist/react/sl-radio-button';
import SlRadioGroup from '@shoelace-style/shoelace/dist/react/sl-radio-group';
const App = () => (
<SlRadioGroup label="Select an option" name="a" value="neutral">

View File

@@ -14,7 +14,8 @@ layout: component
```
```jsx:react
import { SlRadio, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
import SlRadio from '@shoelace-style/shoelace/dist/react/sl-radio';
import SlRadioGroup from '@shoelace-style/shoelace/dist/react/sl-radio-group';
const App = () => (
<SlRadioGroup label="Select an option" name="a" value="1">
@@ -40,7 +41,8 @@ Add descriptive help text to a radio group with the `help-text` attribute. For h
```
```jsx:react
import { SlRadio, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
import SlRadio from '@shoelace-style/shoelace/dist/react/sl-radio';
import SlRadioGroup from '@shoelace-style/shoelace/dist/react/sl-radio-group';
const App = () => (
<SlRadioGroup label="Select an option" help-text="Choose the most appropriate option." name="a" value="1">
@@ -64,7 +66,8 @@ const App = () => (
```
```jsx:react
import { SlRadioButton, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
import SlRadioButton from '@shoelace-style/shoelace/dist/react/sl-radio-button';
import SlRadioGroup from '@shoelace-style/shoelace/dist/react/sl-radio-group';
const App = () => (
<SlRadioGroup label="Select an option" name="a" value="1">
@@ -88,7 +91,8 @@ Radios and radio buttons can be disabled by adding the `disabled` attribute to t
```
```jsx:react
import { SlRadio, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
import SlRadio from '@shoelace-style/shoelace/dist/react/sl-radio';
import SlRadioGroup from '@shoelace-style/shoelace/dist/react/sl-radio-group';
const App = () => (
<SlRadioGroup label="Select an option" name="a" value="1">
@@ -123,7 +127,8 @@ The size of [Radios](/components/radio) and [Radio Buttons](/components/radio-bu
```jsx react
import { useState } from 'react';
import { SlRadio, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
import SlRadio from '@shoelace-style/shoelace/dist/react/sl-radio';
import SlRadioGroup from '@shoelace-style/shoelace/dist/react/sl-radio-group';
const App = () => {
const [size, setSize] = useState('medium');
@@ -177,7 +182,10 @@ Setting the `required` attribute to make selecting an option mandatory. If a val
```
```jsx:react
import { SlButton, SlIcon, SlRadio, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
import SlRadio from '@shoelace-style/shoelace/dist/react/sl-radio';
import SlRadioGroup from '@shoelace-style/shoelace/dist/react/sl-radio-group';
const App = () => {
function handleSubmit(event) {
event.preventDefault();
@@ -247,7 +255,10 @@ Use the `setCustomValidity()` method to set a custom validation message. This wi
```jsx:react
import { useEffect, useRef } from 'react';
import { SlButton, SlIcon, SlRadio, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
import SlRadio from '@shoelace-style/shoelace/dist/react/sl-radio';
import SlRadioGroup from '@shoelace-style/shoelace/dist/react/sl-radio-group';
const App = () => {
const radioGroup = useRef(null);
const errorMessage = 'You must choose this option';

View File

@@ -16,7 +16,8 @@ Radios are designed to be used with [radio groups](/components/radio-group).
```
```jsx:react
import { SlRadio, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
import SlRadio from '@shoelace-style/shoelace/dist/react/radio';
import SlRadioGroup from '@shoelace-style/shoelace/dist/react/radio-group';
const App = () => (
<SlRadioGroup label="Select an option" name="a" value="1">
@@ -46,7 +47,8 @@ To set the initial value and checked state, use the `value` attribute on the con
```
```jsx:react
import { SlRadio, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
import SlRadio from '@shoelace-style/shoelace/dist/react/sl-radio';
import SlRadioGroup from '@shoelace-style/shoelace/dist/react/sl-radio-group';
const App = () => (
<SlRadioGroup label="Select an option" name="a" value="3">
@@ -70,7 +72,8 @@ Use the `disabled` attribute to disable a radio.
```
```jsx:react
import { SlRadio, SlRadioGroup } from '@shoelace-style/shoelace/dist/react';
import SlRadio from '@shoelace-style/shoelace/dist/react/sl-radio';
import SlRadioGroup from '@shoelace-style/shoelace/dist/react/sl-radio-group';
const App = () => (
<SlRadioGroup label="Select an option" name="a" value="1">
@@ -112,7 +115,7 @@ Add the `size` attribute to the [Radio Group](/components/radio-group) to change
```
```jsx react
import { SlRadio } from '@shoelace-style/shoelace/dist/react';
import SlRadio from '@shoelace-style/shoelace/dist/react/sl-radio';
const App = () => (
<>

View File

@@ -10,7 +10,7 @@ layout: component
```
```jsx:react
import { SlRange } from '@shoelace-style/shoelace/dist/react';
import SlRange from '@shoelace-style/shoelace/dist/react/sl-range';
const App = () => <SlRange />;
```
@@ -30,7 +30,7 @@ Use the `label` attribute to give the range an accessible label. For labels that
```
```jsx:react
import { SlRange } from '@shoelace-style/shoelace/dist/react';
import SlRange from '@shoelace-style/shoelace/dist/react/sl-range';
const App = () => <SlRange label="Volume" min={0} max={100} />;
```
@@ -44,7 +44,7 @@ Add descriptive help text to a range with the `help-text` attribute. For help te
```
```jsx:react
import { SlRange } from '@shoelace-style/shoelace/dist/react';
import SlRange from '@shoelace-style/shoelace/dist/react/sl-range';
const App = () => <SlRange label="Volume" help-text="Controls the volume of the current song." min={0} max={100} />;
```
@@ -58,7 +58,7 @@ Use the `min` and `max` attributes to set the range's minimum and maximum values
```
```jsx:react
import { SlRange } from '@shoelace-style/shoelace/dist/react';
import SlRange from '@shoelace-style/shoelace/dist/react/sl-range';
const App = () => <SlRange min={0} max={10} step={1} />;
```
@@ -72,7 +72,7 @@ Use the `disabled` attribute to disable a slider.
```
```jsx:react
import { SlRange } from '@shoelace-style/shoelace/dist/react';
import SlRange from '@shoelace-style/shoelace/dist/react/sl-range';
const App = () => <SlRange disabled />;
```
@@ -86,7 +86,7 @@ By default, the tooltip is shown on top. Set `tooltip` to `bottom` to show it be
```
```jsx:react
import { SlRange } from '@shoelace-style/shoelace/dist/react';
import SlRange from '@shoelace-style/shoelace/dist/react/sl-range';
const App = () => <SlRange tooltip="bottom" />;
```
@@ -100,7 +100,7 @@ To disable the tooltip, set `tooltip` to `none`.
```
```jsx:react
import { SlRange } from '@shoelace-style/shoelace/dist/react';
import SlRange from '@shoelace-style/shoelace/dist/react/sl-range';
const App = () => <SlRange tooltip="none" />;
```
@@ -121,7 +121,7 @@ You can customize the active and inactive portions of the track using the `--tra
{% raw %}
```jsx:react
import { SlRange } from '@shoelace-style/shoelace/dist/react';
import SlRange from '@shoelace-style/shoelace/dist/react/sl-range';
const App = () => (
<SlRange
@@ -154,7 +154,7 @@ You can customize the initial offset of the active track using the `--track-acti
{% raw %}
```jsx:react
import { SlRange } from '@shoelace-style/shoelace/dist/react';
import SlRange from '@shoelace-style/shoelace/dist/react/sl-range';
const App = () => (
<SlRange
@@ -185,7 +185,7 @@ You can change the tooltip's content by setting the `tooltipFormatter` property
```
```jsx:react
import { SlRange } from '@shoelace-style/shoelace/dist/react';
import SlRange from '@shoelace-style/shoelace/dist/react/sl-range';
const App = () => <SlRange min={0} max={100} step={1} tooltipFormatter={value => `Total - ${value}%`} />;
```

View File

@@ -10,7 +10,7 @@ layout: component
```
```jsx:react
import { SlRating } from '@shoelace-style/shoelace/dist/react';
import SlRating from '@shoelace-style/shoelace/dist/react/sl-rating';
const App = () => <SlRating label="Rating" />;
```
@@ -26,7 +26,7 @@ Ratings are commonly identified contextually, so labels aren't displayed. Howeve
```
```jsx:react
import { SlRating } from '@shoelace-style/shoelace/dist/react';
import SlRating from '@shoelace-style/shoelace/dist/react/sl-rating';
const App = () => <SlRating label="Rate this component" />;
```
@@ -40,7 +40,7 @@ Ratings are 0-5 by default. To change the maximum possible value, use the `max`
```
```jsx:react
import { SlRating } from '@shoelace-style/shoelace/dist/react';
import SlRating from '@shoelace-style/shoelace/dist/react/sl-rating';
const App = () => <SlRating label="Rating" max={3} />;
```
@@ -54,7 +54,7 @@ Use the `precision` attribute to let users select fractional ratings.
```
```jsx:react
import { SlRating } from '@shoelace-style/shoelace/dist/react';
import SlRating from '@shoelace-style/shoelace/dist/react/sl-rating';
const App = () => <SlRating label="Rating" precision={0.5} value={2.5} />;
```
@@ -70,7 +70,7 @@ Set the `--symbol-size` custom property to adjust the size.
{% raw %}
```jsx:react
import { SlRating } from '@shoelace-style/shoelace/dist/react';
import SlRating from '@shoelace-style/shoelace/dist/react/sl-rating';
const App = () => <SlRating label="Rating" style={{ '--symbol-size': '2rem' }} />;
```
@@ -86,7 +86,7 @@ Use the `readonly` attribute to display a rating that users can't change.
```
```jsx:react
import { SlRating } from '@shoelace-style/shoelace/dist/react';
import SlRating from '@shoelace-style/shoelace/dist/react/sl-rating';
const App = () => <SlRating label="Rating" readonly value={3} />;
```
@@ -100,7 +100,7 @@ Use the `disable` attribute to disable the rating.
```
```jsx:react
import { SlRating } from '@shoelace-style/shoelace/dist/react';
import SlRating from '@shoelace-style/shoelace/dist/react/sl-rating';
const App = () => <SlRating label="Rating" disabled value={3} />;
```
@@ -152,7 +152,7 @@ The event has a payload with `phase` and `value` properties. The `phase` propert
```jsx:react
import { useState } from 'react';
import { SlRating } from '@shoelace-style/shoelace/dist/react';
import SlRating from '@shoelace-style/shoelace/dist/react/sl-rating';
const terms = ['No rating', 'Terrible', 'Bad', 'OK', 'Good', 'Excellent'];
const css = `
@@ -214,7 +214,7 @@ You can provide custom icons by passing a function to the `getSymbol` property.
{% raw %}
```jsx:react
import { SlRating } from '@shoelace-style/shoelace/dist/react';
import SlRating from '@shoelace-style/shoelace/dist/react/sl-rating';
const App = () => (
<SlRating
@@ -245,7 +245,7 @@ You can also use the `getSymbol` property to render different icons based on val
```
```jsx:react
import { SlRating } from '@shoelace-style/shoelace/dist/react';
import SlRating from '@shoelace-style/shoelace/dist/react/sl-rating';
function getSymbol(value) {
const icons = ['emoji-angry', 'emoji-frown', 'emoji-expressionless', 'emoji-smile', 'emoji-laughing'];

View File

@@ -13,7 +13,7 @@ Localization is handled by the browser's [`Intl.RelativeTimeFormat` API](https:/
```
```jsx:react
import { SlRelativeTime } from '@shoelace-style/shoelace/dist/react';
import SlRelativeTime from '@shoelace-style/shoelace/dist/react/sl-relative-time';
const App = () => <SlRelativeTime date="2020-07-15T09:17:00-04:00" />;
```
@@ -44,7 +44,7 @@ Use the `sync` attribute to update the displayed value automatically as time pas
```
```jsx:react
import { SlRelativeTime } from '@shoelace-style/shoelace/dist/react';
import SlRelativeTime from '@shoelace-style/shoelace/dist/react/sl-relative-time';
const date = new Date(new Date().getTime() - 60000);
@@ -62,7 +62,7 @@ You can change how the time is displayed using the `format` attribute. Note that
```
```jsx:react
import { SlRelativeTime } from '@shoelace-style/shoelace/dist/react';
import SlRelativeTime from '@shoelace-style/shoelace/dist/react/sl-relative-time';
const App = () => (
<>
@@ -88,7 +88,7 @@ Russian: <sl-relative-time date="2020-07-15T09:17:00-04:00" lang="ru"></sl-relat
```
```jsx:react
import { SlRelativeTime } from '@shoelace-style/shoelace/dist/react';
import SlRelativeTime from '@shoelace-style/shoelace/dist/react/sl-relative-time';
const App = () => (
<>

View File

@@ -36,7 +36,7 @@ The resize observer will report changes to the dimensions of the elements it wra
```
```jsx:react
import { SlResizeObserver } from '@shoelace-style/shoelace/dist/react';
import SlResizeObserver from '@shoelace-style/shoelace/dist/react/sl-resize-observer';
const css = `
.resize-observer-overview div {

View File

@@ -17,7 +17,8 @@ layout: component
```
```jsx:react
import { SlOption, SlSelect } from '@shoelace-style/shoelace/dist/react';
import SlOption from '@shoelace-style/shoelace/dist/react/sl-option';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
const App = () => (
<SlSelect>
@@ -50,7 +51,8 @@ Use the `label` attribute to give the select an accessible label. For labels tha
```
```jsx:react
import { SlOption, SlSelect } from '@shoelace-style/shoelace/dist/react';
import SlOption from '@shoelace-style/shoelace/dist/react/sl-option';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
const App = () => (
<SlSelect label="Select one">
@@ -74,7 +76,8 @@ Add descriptive help text to a select with the `help-text` attribute. For help t
```
```jsx:react
import { SlOption, SlSelect } from '@shoelace-style/shoelace/dist/react';
import SlOption from '@shoelace-style/shoelace/dist/react/sl-option';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
const App = () => (
<SlSelect label="Experience" help-text="Please tell us your skill level.">
@@ -98,7 +101,8 @@ Use the `placeholder` attribute to add a placeholder.
```
```jsx:react
import { SlOption, SlSelect } from '@shoelace-style/shoelace/dist/react';
import SlOption from '@shoelace-style/shoelace/dist/react/sl-option';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
const App = () => (
<SlSelect placeholder="Select one">
@@ -122,7 +126,8 @@ Use the `clearable` attribute to make the control clearable. The clear button on
```
```jsx:react
import { SlOption, SlSelect } from '@shoelace-style/shoelace/dist/react';
import SlOption from '@shoelace-style/shoelace/dist/react/sl-option';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
const App = () => (
<SlSelect placeholder="Clearable" clearable>
@@ -146,7 +151,8 @@ Add the `filled` attribute to draw a filled select.
```
```jsx:react
import { SlOption, SlSelect } from '@shoelace-style/shoelace/dist/react';
import SlOption from '@shoelace-style/shoelace/dist/react/sl-option';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
const App = () => (
<SlSelect filled>
@@ -170,7 +176,8 @@ Use the `pill` attribute to give selects rounded edges.
```
```jsx:react
import { SlOption, SlSelect } from '@shoelace-style/shoelace/dist/react';
import SlOption from '@shoelace-style/shoelace/dist/react/sl-option';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
const App = () => (
<SlSelect pill>
@@ -194,7 +201,8 @@ Use the `disabled` attribute to disable a select.
```
```jsx:react
import { SlOption, SlSelect } from '@shoelace-style/shoelace/dist/react';
import SlOption from '@shoelace-style/shoelace/dist/react/sl-option';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
const App = () => (
<SlSelect placeholder="Disabled" disabled>
@@ -221,7 +229,8 @@ To allow multiple options to be selected, use the `multiple` attribute. It's a g
```
```jsx:react
import { SlOption, SlSelect } from '@shoelace-style/shoelace/dist/react';
import SlOption from '@shoelace-style/shoelace/dist/react/sl-option';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
const App = () => (
<SlSelect label="Select a Few" value="option-1 option-2 option-3" multiple clearable>
@@ -253,7 +262,9 @@ Use the `value` attribute to set the initial selection. When using `multiple`, u
```
```jsx:react
import { SlDivider, SlOption, SlSelect } from '@shoelace-style/shoelace/dist/react';
import SlDivider from '@shoelace-style/shoelace/dist/react/sl-divider';
import SlOption from '@shoelace-style/shoelace/dist/react/sl-option';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
const App = () => (
<SlSelect value="option-1 option-2" multiple clearable>
@@ -283,7 +294,8 @@ Use `<sl-divider>` to group listbox items visually. You can also use `<small>` t
```
```jsx:react
import { SlOption, SlSelect } from '@shoelace-style/shoelace/dist/react';
import SlOption from '@shoelace-style/shoelace/dist/react/sl-option';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
const App = () => (
<SlSelect>
@@ -326,7 +338,8 @@ Use the `size` attribute to change a select's size. Note that size does not appl
```
```jsx:react
import { SlOption, SlSelect } from '@shoelace-style/shoelace/dist/react';
import SlOption from '@shoelace-style/shoelace/dist/react/sl-option';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
const App = () => (
<>
@@ -410,7 +423,9 @@ Use the `prefix` slot to prepend an icon to the control.
```
```jsx:react
import { SlIcon, SlOption, SlSelect } from '@shoelace-style/shoelace/dist/react';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
import SlOption from '@shoelace-style/shoelace/dist/react/sl-option';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
const App = () => (
<>

View File

@@ -56,7 +56,7 @@ Skeletons try not to be opinionated, as there are endless possibilities for desi
```
```jsx:react
import { SlSkeleton } from '@shoelace-style/shoelace/dist/react';
import SlSkeleton from '@shoelace-style/shoelace/dist/react/sl-skeleton';
const css = `
.skeleton-overview header {
@@ -139,7 +139,7 @@ There are two built-in effects, `sheen` and `pulse`. Effects are intentionally s
```
```jsx:react
import { SlSkeleton } from '@shoelace-style/shoelace/dist/react';
import SlSkeleton from '@shoelace-style/shoelace/dist/react/sl-skeleton';
const css = `
.skeleton-effects {
@@ -200,7 +200,7 @@ Use multiple skeletons and some clever styles to simulate paragraphs.
```
```jsx:react
import { SlSkeleton } from '@shoelace-style/shoelace/dist/react';
import SlSkeleton from '@shoelace-style/shoelace/dist/react/sl-skeleton';
const css = `
.skeleton-paragraphs sl-skeleton {
@@ -265,7 +265,7 @@ Set a matching width and height to make a circle, square, or rounded avatar skel
```
```jsx:react
import { SlSkeleton } from '@shoelace-style/shoelace/dist/react';
import SlSkeleton from '@shoelace-style/shoelace/dist/react/sl-skeleton';
const css = `
.skeleton-avatars sl-skeleton {
@@ -360,7 +360,7 @@ Use the `--border-radius` custom property to make circles, squares, and rectangl
```
```jsx:react
import { SlSkeleton } from '@shoelace-style/shoelace/dist/react';
import SlSkeleton from '@shoelace-style/shoelace/dist/react/sl-skeleton';
const css = `
.skeleton-shapes sl-skeleton {
@@ -423,7 +423,7 @@ Set the `--color` and `--sheen-color` custom properties to adjust the skeleton's
{% raw %}
```jsx:react
import { SlSkeleton } from '@shoelace-style/shoelace/dist/react';
import SlSkeleton from '@shoelace-style/shoelace/dist/react/sl-skeleton';
const css = `
.skeleton-avatars sl-skeleton {

View File

@@ -10,7 +10,7 @@ layout: component
```
```jsx:react
import { SlSpinner } from '@shoelace-style/shoelace/dist/react';
import SlSpinner from '@shoelace-style/shoelace/dist/react/sl-spinner';
const App = () => <SlSpinner />;
```
@@ -30,7 +30,7 @@ Spinners are sized based on the current font size. To change their size, set the
{% raw %}
```jsx:react
import { SlSpinner } from '@shoelace-style/shoelace/dist/react';
import SlSpinner from '@shoelace-style/shoelace/dist/react/sl-spinner';
const App = () => (
<>
@@ -54,7 +54,7 @@ The width of the spinner's track can be changed by setting the `--track-width` c
{% raw %}
```jsx:react
import { SlSpinner } from '@shoelace-style/shoelace/dist/react';
import SlSpinner from '@shoelace-style/shoelace/dist/react/sl-spinner';
const App = () => (
<SlSpinner
@@ -79,7 +79,7 @@ The spinner's colors can be changed by setting the `--indicator-color` and `--tr
{% raw %}
```jsx:react
import { SlSpinner } from '@shoelace-style/shoelace/dist/react';
import SlSpinner from '@shoelace-style/shoelace/dist/react/sl-spinner';
const App = () => (
<SlSpinner

View File

@@ -25,7 +25,7 @@ layout: component
{% raw %}
```jsx:react
import { SlSplitPanel } from '@shoelace-style/shoelace/dist/react';
import SlSplitPanel from '@shoelace-style/shoelace/dist/react/sl-split-panel';
const App = () => (
<SlSplitPanel>
@@ -106,7 +106,7 @@ To set the initial position in pixels instead of a percentage, use the `position
{% raw %}
```jsx:react
import { SlSplitPanel } from '@shoelace-style/shoelace/dist/react';
import SlSplitPanel from '@shoelace-style/shoelace/dist/react/sl-split-panel';
const App = () => (
<SlSplitPanel position="200">
@@ -164,7 +164,7 @@ Add the `vertical` attribute to render the split panel in a vertical orientation
{% raw %}
```jsx:react
import { SlSplitPanel } from '@shoelace-style/shoelace/dist/react';
import SlSplitPanel from '@shoelace-style/shoelace/dist/react/sl-split-panel';
const App = () => (
<SlSplitPanel vertical style={{ height: '400px' }}>
@@ -252,7 +252,7 @@ To snap panels at specific positions while dragging, add the `snap` attribute wi
{% raw %}
```jsx:react
import { SlSplitPanel } from '@shoelace-style/shoelace/dist/react';
import SlSplitPanel from '@shoelace-style/shoelace/dist/react/sl-split-panel';
const css = `
.split-panel-snapping {
@@ -344,7 +344,7 @@ Add the `disabled` attribute to prevent the divider from being repositioned.
{% raw %}
```jsx:react
import { SlSplitPanel } from '@shoelace-style/shoelace/dist/react';
import SlSplitPanel from '@shoelace-style/shoelace/dist/react/sl-split-panel';
const App = () => (
<SlSplitPanel disabled>
@@ -421,7 +421,9 @@ Try resizing the example below with each option and notice how the panels respon
```jsx:react
import { useState } from 'react';
import { SlSplitPanel, SlSelect, SlMenuItem } from '@shoelace-style/shoelace/dist/react';
import SlSplitPanel from '@shoelace-style/shoelace/dist/react/sl-split-panel';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
const App = () => {
const [primary, setPrimary] = useState('');
@@ -498,7 +500,7 @@ This examples demonstrates how you can ensure both panels are at least 150px usi
{% raw %}
```jsx:react
import { SlSplitPanel } from '@shoelace-style/shoelace/dist/react';
import SlSplitPanel from '@shoelace-style/shoelace/dist/react/sl-split-panel';
const App = () => (
<SlSplitPanel style={{ '--min': '150px', '--max': 'calc(100% - 150px)' }}>
@@ -566,7 +568,7 @@ Create complex layouts that can be repositioned independently by nesting split p
{% raw %}
```jsx:react
import { SlSplitPanel } from '@shoelace-style/shoelace/dist/react';
import SlSplitPanel from '@shoelace-style/shoelace/dist/react/sl-split-panel';
const App = () => (
<SlSplitPanel>
@@ -641,7 +643,8 @@ You can target the `divider` part to apply CSS properties to the divider. To add
{% raw %}
```jsx:react
import { SlSplitPanel, SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlSplitPanel from '@shoelace-style/shoelace/dist/react/sl-split-panel';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
const App = () => (
<SlSplitPanel style={{ '--divider-width': '20px' }}>
@@ -728,7 +731,8 @@ Here's a more elaborate example that changes the divider's color and width and a
{% raw %}
```jsx:react
import { SlSplitPanel, SlIcon } from '@shoelace-style/shoelace/dist/react';
import SlSplitPanel from '@shoelace-style/shoelace/dist/react/sl-split-panel';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
const css = `
.split-panel-divider sl-split-panel {

View File

@@ -10,7 +10,7 @@ layout: component
```
```jsx:react
import { SlSwitch } from '@shoelace-style/shoelace/dist/react';
import SlSwitch from '@shoelace-style/shoelace/dist/react/sl-switch';
const App = () => <SlSwitch>Switch</SlSwitch>;
```
@@ -30,7 +30,7 @@ Use the `checked` attribute to activate the switch.
```
```jsx:react
import { SlSwitch } from '@shoelace-style/shoelace/dist/react';
import SlSwitch from '@shoelace-style/shoelace/dist/react/sl-switch';
const App = () => <SlSwitch checked>Checked</SlSwitch>;
```
@@ -44,7 +44,7 @@ Use the `disabled` attribute to disable the switch.
```
```jsx:react
import { SlSwitch } from '@shoelace-style/shoelace/dist/react';
import SlSwitch from '@shoelace-style/shoelace/dist/react/sl-switch';
const App = () => <SlSwitch disabled>Disabled</SlSwitch>;
```
@@ -62,7 +62,7 @@ Use the `size` attribute to change a switch's size.
```
```jsx:react
import { SlSwitch } from '@shoelace-style/shoelace/dist/react';
import SlSwitch from '@shoelace-style/shoelace/dist/react/sl-switch';
const App = () => (
<>
@@ -86,7 +86,7 @@ Use the available custom properties to change how the switch is styled.
{% raw %}
```jsx:react
import { SlSwitch } from '@shoelace-style/shoelace/dist/react';
import SlSwitch from '@shoelace-style/shoelace/dist/react/sl-switch';
const App = () => (
<SlSwitch

View File

@@ -22,7 +22,9 @@ Tab groups make use of [tabs](/components/tab) and [tab panels](/components/tab-
```
```jsx:react
import { SlTab, SlTabGroup, SlTabPanel } from '@shoelace-style/shoelace/dist/react';
import SlTab from '@shoelace-style/shoelace/dist/react/sl-tab';
import SlTabGroup from '@shoelace-style/shoelace/dist/react/sl-tab-group';
import SlTabPanel from '@shoelace-style/shoelace/dist/react/sl-tab-panel';
const App = () => (
<SlTabGroup>
@@ -68,7 +70,9 @@ Tabs can be shown on the bottom by setting `placement` to `bottom`.
```
```jsx:react
import { SlTab, SlTabGroup, SlTabPanel } from '@shoelace-style/shoelace/dist/react';
import SlTab from '@shoelace-style/shoelace/dist/react/sl-tab';
import SlTabGroup from '@shoelace-style/shoelace/dist/react/sl-tab-group';
import SlTabPanel from '@shoelace-style/shoelace/dist/react/sl-tab-panel';
const App = () => (
<SlTabGroup placement="bottom">
@@ -112,7 +116,9 @@ Tabs can be shown on the starting side by setting `placement` to `start`.
```
```jsx:react
import { SlTab, SlTabGroup, SlTabPanel } from '@shoelace-style/shoelace/dist/react';
import SlTab from '@shoelace-style/shoelace/dist/react/sl-tab';
import SlTabGroup from '@shoelace-style/shoelace/dist/react/sl-tab-group';
import SlTabPanel from '@shoelace-style/shoelace/dist/react/sl-tab-panel';
const App = () => (
<SlTabGroup placement="start">
@@ -156,7 +162,9 @@ Tabs can be shown on the ending side by setting `placement` to `end`.
```
```jsx:react
import { SlTab, SlTabGroup, SlTabPanel } from '@shoelace-style/shoelace/dist/react';
import SlTab from '@shoelace-style/shoelace/dist/react/sl-tab';
import SlTabGroup from '@shoelace-style/shoelace/dist/react/sl-tab-group';
import SlTabPanel from '@shoelace-style/shoelace/dist/react/sl-tab-panel';
const App = () => (
<SlTabGroup placement="end">
@@ -218,7 +226,9 @@ Add the `closable` attribute to a tab to show a close button. This example shows
```
```jsx:react
import { SlTab, SlTabGroup, SlTabPanel } from '@shoelace-style/shoelace/dist/react';
import SlTab from '@shoelace-style/shoelace/dist/react/sl-tab';
import SlTabGroup from '@shoelace-style/shoelace/dist/react/sl-tab-group';
import SlTabPanel from '@shoelace-style/shoelace/dist/react/sl-tab-panel';
const App = () => {
function handleClose(event) {
@@ -310,7 +320,9 @@ When there are more tabs than horizontal space allows, the nav will be scrollabl
```
```jsx:react
import { SlTab, SlTabGroup, SlTabPanel } from '@shoelace-style/shoelace/dist/react';
import SlTab from '@shoelace-style/shoelace/dist/react/sl-tab';
import SlTabGroup from '@shoelace-style/shoelace/dist/react/sl-tab-group';
import SlTabPanel from '@shoelace-style/shoelace/dist/react/sl-tab-panel';
const App = () => (
<SlTabGroup>
@@ -418,7 +430,9 @@ When focused, keyboard users can press [[Left]] or [[Right]] to select the desir
```
```jsx:react
import { SlTab, SlTabGroup, SlTabPanel } from '@shoelace-style/shoelace/dist/react';
import SlTab from '@shoelace-style/shoelace/dist/react/sl-tab';
import SlTabGroup from '@shoelace-style/shoelace/dist/react/sl-tab-group';
import SlTabPanel from '@shoelace-style/shoelace/dist/react/sl-tab-panel';
const App = () => (
<SlTabGroup activation="manual">

View File

@@ -20,7 +20,9 @@ layout: component
```
```jsx:react
import { SlTab, SlTabGroup, SlTabPanel } from '@shoelace-style/shoelace/dist/react';
import SlTab from '@shoelace-style/shoelace/dist/react/sl-tab';
import SlTabGroup from '@shoelace-style/shoelace/dist/react/sl-tab-group';
import SlTabPanel from '@shoelace-style/shoelace/dist/react/sl-tab-panel';
const App = () => (
<SlTabGroup>

View File

@@ -13,7 +13,7 @@ layout: component
```
```jsx:react
import { SlTab } from '@shoelace-style/shoelace/dist/react';
import SlTab from '@shoelace-style/shoelace/dist/react/sl-tab';
const App = () => (
<>

View File

@@ -14,7 +14,7 @@ layout: component
```
```jsx:react
import { SlTag } from '@shoelace-style/shoelace/dist/react';
import SlTag from '@shoelace-style/shoelace/dist/react/sl-tag';
const App = () => (
<>
@@ -40,7 +40,7 @@ Use the `size` attribute to change a tab's size.
```
```jsx:react
import { SlTag } from '@shoelace-style/shoelace/dist/react';
import SlTag from '@shoelace-style/shoelace/dist/react/sl-tag';
const App = () => (
<>
@@ -62,7 +62,7 @@ Use the `pill` attribute to give tabs rounded edges.
```
```jsx:react
import { SlTag } from '@shoelace-style/shoelace/dist/react';
import SlTag from '@shoelace-style/shoelace/dist/react/sl-tag';
const App = () => (
<>
@@ -108,7 +108,7 @@ Use the `removable` attribute to add a remove button to the tag.
```
```jsx:react
import { SlTag } from '@shoelace-style/shoelace/dist/react';
import SlTag from '@shoelace-style/shoelace/dist/react/sl-tag';
const css = `
.tags-removable sl-tag {

View File

@@ -10,7 +10,7 @@ layout: component
```
```jsx:react
import { SlTextarea } from '@shoelace-style/shoelace/dist/react';
import SlTextarea from '@shoelace-style/shoelace/dist/react/sl-textarea';
const App = () => <SlTextarea />;
```
@@ -30,7 +30,7 @@ Use the `label` attribute to give the textarea an accessible label. For labels t
```
```jsx:react
import { SlTextarea } from '@shoelace-style/shoelace/dist/react';
import SlTextarea from '@shoelace-style/shoelace/dist/react/sl-textarea';
const App = () => <SlTextarea label="Comments" />;
```
@@ -44,7 +44,7 @@ Add descriptive help text to a textarea with the `help-text` attribute. For help
```
```jsx:react
import { SlTextarea } from '@shoelace-style/shoelace/dist/react';
import SlTextarea from '@shoelace-style/shoelace/dist/react/sl-textarea';
const App = () => <SlTextarea label="Feedback" help-text="Please tell us what you think." />;
```
@@ -58,7 +58,7 @@ Use the `rows` attribute to change the number of text rows that get shown.
```
```jsx:react
import { SlTextarea } from '@shoelace-style/shoelace/dist/react';
import SlTextarea from '@shoelace-style/shoelace/dist/react/sl-textarea';
const App = () => <SlTextarea rows={2} />;
```
@@ -72,7 +72,7 @@ Use the `placeholder` attribute to add a placeholder.
```
```jsx:react
import { SlTextarea } from '@shoelace-style/shoelace/dist/react';
import SlTextarea from '@shoelace-style/shoelace/dist/react/sl-textarea';
const App = () => <SlTextarea placeholder="Type something" />;
```
@@ -86,7 +86,7 @@ Add the `filled` attribute to draw a filled textarea.
```
```jsx:react
import { SlTextarea } from '@shoelace-style/shoelace/dist/react';
import SlTextarea from '@shoelace-style/shoelace/dist/react/sl-textarea';
const App = () => <SlTextarea placeholder="Type something" filled />;
```
@@ -100,7 +100,7 @@ Use the `disabled` attribute to disable a textarea.
```
```jsx:react
import { SlTextarea } from '@shoelace-style/shoelace/dist/react';
import SlTextarea from '@shoelace-style/shoelace/dist/react/sl-textarea';
const App = () => <SlTextarea placeholder="Textarea" disabled />;
```
@@ -118,7 +118,7 @@ Use the `size` attribute to change a textarea's size.
```
```jsx:react
import { SlTextarea } from '@shoelace-style/shoelace/dist/react';
import SlTextarea from '@shoelace-style/shoelace/dist/react/sl-textarea';
const App = () => (
<>
@@ -140,7 +140,7 @@ By default, textareas can be resized vertically by the user. To prevent resizing
```
```jsx:react
import { SlTextarea } from '@shoelace-style/shoelace/dist/react';
import SlTextarea from '@shoelace-style/shoelace/dist/react/sl-textarea';
const App = () => <SlTextarea resize="none" />;
```
@@ -154,7 +154,7 @@ Textareas will automatically resize to expand to fit their content when `resize`
```
```jsx:react
import { SlTextarea } from '@shoelace-style/shoelace/dist/react';
import SlTextarea from '@shoelace-style/shoelace/dist/react/sl-textarea';
const App = () => <SlTextarea resize="auto" />;
```

View File

@@ -16,7 +16,8 @@ Tooltips use `display: contents` so they won't interfere with how elements are p
```
```jsx:react
import { SlButton, SlTooltip } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlTooltip from '@shoelace-style/shoelace/dist/react/sl-tooltip';
const App = () => (
<SlTooltip content="This is a tooltip">
@@ -125,7 +126,8 @@ Use the `placement` attribute to set the preferred placement of the tooltip.
```
```jsx:react
import { SlButton, SlTooltip } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlTooltip from '@shoelace-style/shoelace/dist/react/sl-tooltip';
const css = `
.tooltip-placement-example {
@@ -235,7 +237,8 @@ Set the `trigger` attribute to `click` to toggle the tooltip on click instead of
```
```jsx:react
import { SlButton, SlTooltip } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlTooltip from '@shoelace-style/shoelace/dist/react/sl-tooltip';
const App = () => (
<SlTooltip content="Click again to dismiss" trigger="click">
@@ -267,7 +270,9 @@ Tooltips can be controller programmatically by setting the `trigger` attribute t
```jsx:react
import { useState } from 'react';
import { SlAvatar, SlButton, SlTooltip } from '@shoelace-style/shoelace/dist/react';
import SlAvatar from '@shoelace-style/shoelace/dist/react/sl-avatar';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlTooltip from '@shoelace-style/shoelace/dist/react/sl-tooltip';
const App = () => {
const [open, setOpen] = useState(false);
@@ -301,7 +306,8 @@ You can control the size of tooltip arrows by overriding the `--sl-tooltip-arrow
{% raw %}
```jsx:react
import { SlButton, SlTooltip } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlTooltip from '@shoelace-style/shoelace/dist/react/sl-tooltip';
const App = () => (
<div style={{ '--sl-tooltip-arrow-size': '0' }}>
@@ -339,7 +345,8 @@ Use the `content` slot to create tooltips with HTML content. Tooltips are design
```
```jsx:react
import { SlButton, SlTooltip } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlTooltip from '@shoelace-style/shoelace/dist/react/sl-tooltip';
const App = () => (
<SlTooltip>
@@ -365,7 +372,8 @@ Use the `--max-width` custom property to change the width the tooltip can grow t
{% raw %}
```jsx:react
import { SlButton, SlTooltip } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlTooltip from '@shoelace-style/shoelace/dist/react/sl-tooltip';
const App = () => (
<SlTooltip style={{ '--max-width': '80px' }} content="This tooltip will wrap after only 80 pixels.">
@@ -402,7 +410,8 @@ Tooltips will be clipped if they're inside a container that has `overflow: auto|
```
```jsx:react
import { SlButton, SlTooltip } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlTooltip from '@shoelace-style/shoelace/dist/react/sl-tooltip';
const css = `
.tooltip-hoist {

View File

@@ -20,7 +20,8 @@ layout: component
<!-- prettier-ignore -->
```jsx:react
import { SlTree, SlTreeItem } from '@shoelace-style/shoelace/dist/react';
import SlTree from '@shoelace-style/shoelace/dist/react/sl-tree';
import SlTreeItem from '@shoelace-style/shoelace/dist/react/sl-tree-item';
const App = () => (
<SlTree>
@@ -62,7 +63,8 @@ A tree item can contain other tree items. This allows the node to be expanded or
<!-- prettier-ignore -->
```jsx:react
import { SlTree, SlTreeItem } from '@shoelace-style/shoelace/dist/react';
import SlTree from '@shoelace-style/shoelace/dist/react/sl-tree';
import SlTreeItem from '@shoelace-style/shoelace/dist/react/sl-tree-item';
const App = () => (
<SlTree>
@@ -102,7 +104,8 @@ Use the `selected` attribute to select a tree item initially.
<!-- prettier-ignore -->
```jsx:react
import { SlTree, SlTreeItem } from '@shoelace-style/shoelace/dist/react';
import SlTree from '@shoelace-style/shoelace/dist/react/sl-tree';
import SlTreeItem from '@shoelace-style/shoelace/dist/react/sl-tree-item';
const App = () => (
<SlTree>
@@ -142,7 +145,8 @@ Use the `expanded` attribute to expand a tree item initially.
<!-- prettier-ignore -->
```jsx:react
import { SlTree, SlTreeItem } from '@shoelace-style/shoelace/dist/react';
import SlTree from '@shoelace-style/shoelace/dist/react/sl-tree';
import SlTreeItem from '@shoelace-style/shoelace/dist/react/sl-tree-item';
const App = () => (
<SlTree>

View File

@@ -37,7 +37,8 @@ layout: component
<!-- prettier-ignore -->
```jsx:react
import { SlTree, SlTreeItem } from '@shoelace-style/shoelace/dist/react';
import SlTree from '@shoelace-style/shoelace/dist/react/sl-tree';
import SlTreeItem from '@shoelace-style/shoelace/dist/react/sl-tree-item';
const App = () => (
<SlTree>
@@ -118,7 +119,8 @@ The `selection` attribute lets you change the selection behavior of the tree.
<!-- prettier-ignore -->
```jsx:react
import { SlTree, SlTreeItem } from '@shoelace-style/shoelace/dist/react';
import SlTree from '@shoelace-style/shoelace/dist/react/sl-tree';
import SlTreeItem from '@shoelace-style/shoelace/dist/react/sl-tree-item';
const App = () => {
const [selection, setSelection] = useState('single');
@@ -197,7 +199,8 @@ Indent guides can be drawn by setting `--indent-guide-width`. You can also chang
<!-- prettier-ignore -->
```jsx:react
import { SlTree, SlTreeItem } from '@shoelace-style/shoelace/dist/react';
import SlTree from '@shoelace-style/shoelace/dist/react/sl-tree';
import SlTreeItem from '@shoelace-style/shoelace/dist/react/sl-tree-item';
const App = () => (
<SlTree class="tree-with-lines" style={{ '--indent-guide-width': '1px' }}>
@@ -265,7 +268,8 @@ If you want to disable this behavior after the first load, simply remove the `la
```
```jsx:react
import { SlTree, SlTreeItem } from '@shoelace-style/shoelace/dist/react';
import SlTree from '@shoelace-style/shoelace/dist/react/sl-tree';
import SlTreeItem from '@shoelace-style/shoelace/dist/react/sl-tree-item';
const App = () => {
const [childItems, setChildItems] = useState([]);
@@ -340,7 +344,8 @@ Use the `expand-icon` and `collapse-icon` slots to change the expand and collaps
<!-- prettier-ignore -->
```jsx:react
import { SlTree, SlTreeItem } from '@shoelace-style/shoelace/dist/react';
import SlTree from '@shoelace-style/shoelace/dist/react/sl-tree';
import SlTreeItem from '@shoelace-style/shoelace/dist/react/sl-tree-item';
const App = () => (
<SlTree>
@@ -424,7 +429,9 @@ Decorative icons can be used before labels to provide hints for each node.
```
```jsx:react
import { SlIcon, SlTree, SlTreeItem } from '@shoelace-style/shoelace/dist/react';
import SlIcon from '@shoelace-style/shoelace/dist/react/sl-icon';
import SlTree from '@shoelace-style/shoelace/dist/react/sl-tree';
import SlTreeItem from '@shoelace-style/shoelace/dist/react/sl-tree-item';
const App = () => {
return (

View File

@@ -39,13 +39,28 @@ Now you can start using components!
Every Shoelace component is available to import as a React component. Note that we're importing the `<SlButton>` _React component_ instead of the `<sl-button>` _custom element_ in the example below.
```jsx
import { SlButton } from '@shoelace-style/shoelace/%NPMDIR%/react';
import SlButton from '@shoelace-style/shoelace/%NPMDIR%/react/button';
const MyComponent = () => <SlButton variant="primary">Click me</SlButton>;
export default MyComponent;
```
#### Notes about tree shaking
Previously, it was recommended to import from a single entrypoint like so:
```jsx
import { SlButton } from '@shoelace-style/shoelace/%NPMDIR%/react';
```
However, tree-shaking extra Shoelace components proved to be a challenge. As a result, we now recommend cherry-picking components you want to use, rather than importing from a single entrypoint.
```diff
- import { SlButton } from '@shoelace-style/shoelace/%NPMDIR%/react';
+ import SlButton from '@shoelace-style/shoelace/%NPMDIR%/react/button';
```
You can find a copy + paste import for each component in the "importing" section of its documentation.
### Event Handling
@@ -56,7 +71,7 @@ Here's how you can bind the input's value to a state variable.
```jsx
import { useState } from 'react';
import { SlInput } from '@shoelace-style/shoelace/%NPMDIR%/react';
import SlInput from '@shoelace-style/shoelace/%NPMDIR%/react/input';
function MyComponent() {
const [value, setValue] = useState('');
@@ -71,7 +86,7 @@ If you're using TypeScript, it's important to note that `event.target` will be a
```tsx
import { useState } from 'react';
import { SlInput } from '@shoelace-style/shoelace/%NPMDIR%/react';
import SlInput from '@shoelace-style/shoelace/%NPMDIR%/react/input';
import type SlInputElement from '@shoelace-style/shoelace/%NPMDIR%/components/input/input';
function MyComponent() {
@@ -87,7 +102,7 @@ You can also import the event type for use in your callbacks, shown below.
```tsx
import { useCallback, useState } from 'react';
import { SlInput, SlInputEvent } from '@shoelace-style/shoelace/%NPMDIR%/react';
import SlInput, { type SlInputEvent } from '@shoelace-style/shoelace/%NPMDIR%/react/input';
import type SlInputElement from '@shoelace-style/shoelace/%NPMDIR%/components/input/input';
function MyComponent() {
@@ -159,7 +174,7 @@ To fix this, add the following to your `package.json` which tells the transpiler
```js
{
"jest": {
"transformIgnorePatterns": ["node_modules/?!(@shoelace)"]
"transformIgnorePatterns": ["node_modules/(?!(@shoelace))"]
}
}
```

View File

@@ -99,7 +99,12 @@ The form will not be submitted if a required field is incomplete.
```
```jsx:react
import { SlButton, SlCheckbox, SlInput, SlMenuItem, SlSelect, SlTextarea } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlCheckbox from '@shoelace-style/shoelace/dist/react/sl-checkbox';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
import SlMenuItem from '@shoelace-style/shoelace/dist/react/sl-menu-item';
import SlSelect from '@shoelace-style/shoelace/dist/react/sl-select';
import SlTextarea from '@shoelace-style/shoelace/dist/react/sl-textarea';
const App = () => {
function handleSubmit(event) {
@@ -160,7 +165,8 @@ To restrict a value to a specific [pattern](https://developer.mozilla.org/en-US/
```
```jsx:react
import { SlButton, SlInput } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
const App = () => {
function handleSubmit(event) {
@@ -211,7 +217,8 @@ Some input types will automatically trigger constraints, such as `email` and `ur
```
```jsx:react
import { SlButton, SlInput } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
const App = () => {
function handleSubmit(event) {
@@ -272,7 +279,8 @@ To create a custom validation error, pass a non-empty string to the `setCustomVa
```jsx:react
import { useRef, useState } from 'react';
import { SlButton, SlInput } from '@shoelace-style/shoelace/dist/react';
import SlButton from '@shoelace-style/shoelace/dist/react/sl-button';
import SlInput from '@shoelace-style/shoelace/dist/react/sl-input';
const App = () => {
const input = useRef(null);

View File

@@ -196,7 +196,7 @@ setBasePath('/path/to/shoelace/%NPMDIR%
Component modules include side effects for registration purposes. Because of this, importing directly from `@shoelace-style/shoelace` may result in a larger bundle size than necessary. For optimal tree shaking, always cherry pick, i.e. import components and utilities from their respective files, as shown above.
:::
### Avoiding side-effect imports
### Avoiding auto-registering imports
By default, imports to components will auto-register themselves. This may not be ideal in all cases. To import just the component's class without auto-registering it's tag we can do the following:

View File

@@ -14,6 +14,15 @@ New versions of Shoelace are released as-needed and generally occur when a criti
## Next
- Added the `<sl-copy-button>` component [#1473]
- Fixed a bug in `<sl-dropdown>` where pressing [[Up]] or [[Down]] when focused on the trigger wouldn't focus the first/last menu items [#1472]
- Improved the behavior of the clear button in `<sl-input>` to prevent the component's width from shifting when toggled [#1496]
- Improved `<sl-tooltip>` to prevent user selection so the tooltip doesn't get highlighted when dragging selections
- Removed `sideEffects` key from `package.json`. Update React docs to use cherry-picking. [#1485]
- Updated Bootstrap Icons to 1.10.5
## 2.6.0
- Added JSDoc comments to React Wrappers for better documentation when hovering a component. [#1450]
- Added `displayName` to React Wrappers for better debugging. [#1450]
- Added non-auto-registering routes for Components to fix a number of issues around auto-registration. [#1450]

68
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "@shoelace-style/shoelace",
"version": "2.5.2",
"version": "2.6.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@shoelace-style/shoelace",
"version": "2.5.2",
"version": "2.6.0",
"license": "MIT",
"dependencies": {
"@ctrl/tinycolor": "^3.5.0",
@@ -30,14 +30,14 @@
"@web/test-runner": "^0.15.0",
"@web/test-runner-commands": "^0.6.5",
"@web/test-runner-playwright": "^0.9.0",
"bootstrap-icons": "^1.10.3",
"bootstrap-icons": "^1.10.5",
"browser-sync": "^2.29.3",
"cem-plugin-vs-code-custom-data-generator": "^1.4.1",
"chalk": "^5.2.0",
"change-case": "^4.1.2",
"command-line-args": "^5.2.1",
"comment-parser": "^1.3.1",
"cspell": "^6.18.1",
"custom-element-vs-code-integration": "^1.1.0",
"del": "^7.0.0",
"download": "^8.0.0",
"esbuild": "^0.18.2",
@@ -3987,10 +3987,20 @@
}
},
"node_modules/bootstrap-icons": {
"version": "1.10.3",
"resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.10.3.tgz",
"integrity": "sha512-7Qvj0j0idEm/DdX9Q0CpxAnJYqBCFCiUI6qzSPYfERMcokVuV9Mdm/AJiVZI8+Gawe4h/l6zFcOzvV7oXCZArw==",
"dev": true
"version": "1.10.5",
"resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.10.5.tgz",
"integrity": "sha512-oSX26F37V7QV7NCE53PPEL45d7EGXmBgHG3pDpZvcRaKVzWMqIRL9wcqJUyEha1esFtM3NJzvmxFXDxjJYD0jQ==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/twbs"
},
{
"type": "opencollective",
"url": "https://opencollective.com/bootstrap"
}
]
},
"node_modules/boxen": {
"version": "7.0.0",
@@ -4535,15 +4545,6 @@
"upper-case-first": "^2.0.2"
}
},
"node_modules/cem-plugin-vs-code-custom-data-generator": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/cem-plugin-vs-code-custom-data-generator/-/cem-plugin-vs-code-custom-data-generator-1.4.1.tgz",
"integrity": "sha512-mulzg6I2wJVNKCM9ml4ttxTnGK25kHHdkhX979vbrKwSIIplFnPOgGa0Sj14pQWnfDwbGr6pSbLgBmi4nVHFxA==",
"dev": true,
"dependencies": {
"prettier": "^2.7.1"
}
},
"node_modules/chai-a11y-axe": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/chai-a11y-axe/-/chai-a11y-axe-1.4.0.tgz",
@@ -5686,6 +5687,15 @@
"integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==",
"dev": true
},
"node_modules/custom-element-vs-code-integration": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/custom-element-vs-code-integration/-/custom-element-vs-code-integration-1.1.0.tgz",
"integrity": "sha512-M7f4zQIAzpdZGRcZpWmpONyf8zpiGZCU8U7z7s5q6460deIebLLQP/klTLLcI3XyWoCjUhwDwGJiZz9he8Y2ig==",
"dev": true,
"dependencies": {
"prettier": "^2.7.1"
}
},
"node_modules/custom-elements-manifest": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/custom-elements-manifest/-/custom-elements-manifest-1.0.0.tgz",
@@ -20196,9 +20206,9 @@
}
},
"bootstrap-icons": {
"version": "1.10.3",
"resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.10.3.tgz",
"integrity": "sha512-7Qvj0j0idEm/DdX9Q0CpxAnJYqBCFCiUI6qzSPYfERMcokVuV9Mdm/AJiVZI8+Gawe4h/l6zFcOzvV7oXCZArw==",
"version": "1.10.5",
"resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.10.5.tgz",
"integrity": "sha512-oSX26F37V7QV7NCE53PPEL45d7EGXmBgHG3pDpZvcRaKVzWMqIRL9wcqJUyEha1esFtM3NJzvmxFXDxjJYD0jQ==",
"dev": true
},
"boxen": {
@@ -20611,15 +20621,6 @@
"upper-case-first": "^2.0.2"
}
},
"cem-plugin-vs-code-custom-data-generator": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/cem-plugin-vs-code-custom-data-generator/-/cem-plugin-vs-code-custom-data-generator-1.4.1.tgz",
"integrity": "sha512-mulzg6I2wJVNKCM9ml4ttxTnGK25kHHdkhX979vbrKwSIIplFnPOgGa0Sj14pQWnfDwbGr6pSbLgBmi4nVHFxA==",
"dev": true,
"requires": {
"prettier": "^2.7.1"
}
},
"chai-a11y-axe": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/chai-a11y-axe/-/chai-a11y-axe-1.4.0.tgz",
@@ -21506,6 +21507,15 @@
"integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==",
"dev": true
},
"custom-element-vs-code-integration": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/custom-element-vs-code-integration/-/custom-element-vs-code-integration-1.1.0.tgz",
"integrity": "sha512-M7f4zQIAzpdZGRcZpWmpONyf8zpiGZCU8U7z7s5q6460deIebLLQP/klTLLcI3XyWoCjUhwDwGJiZz9he8Y2ig==",
"dev": true,
"requires": {
"prettier": "^2.7.1"
}
},
"custom-elements-manifest": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/custom-elements-manifest/-/custom-elements-manifest-1.0.0.tgz",

View File

@@ -1,7 +1,7 @@
{
"name": "@shoelace-style/shoelace",
"description": "A forward-thinking library of web components.",
"version": "2.5.2",
"version": "2.6.0",
"homepage": "https://github.com/shoelace-style/shoelace",
"author": "Cory LaViska",
"license": "MIT",
@@ -10,15 +10,6 @@
"type": "module",
"types": "dist/shoelace.d.ts",
"jsdelivr": "./cdn/shoelace-autoloader.js",
"sideEffects": [
"./dist/shoelace.js",
"./dist/shoelace-autoloader.js",
"./dist/components/**/*.js",
"./dist/translations/**/*.*",
"./src/translations/**/*.*",
"// COMMENT: This monstrosity below isn't perfect, but its like 99% to get bundlers to recognize 'thing.component.ts' as having no side effects. Example: https://regexr.com/7grof",
"./dist/components/**/*((?<!(\\.component|\\.styles)))\\.js"
],
"exports": {
".": {
"types": "./dist/shoelace.d.ts",
@@ -97,14 +88,14 @@
"@web/test-runner": "^0.15.0",
"@web/test-runner-commands": "^0.6.5",
"@web/test-runner-playwright": "^0.9.0",
"bootstrap-icons": "^1.10.3",
"bootstrap-icons": "^1.10.5",
"browser-sync": "^2.29.3",
"cem-plugin-vs-code-custom-data-generator": "^1.4.1",
"chalk": "^5.2.0",
"change-case": "^4.1.2",
"command-line-args": "^5.2.1",
"comment-parser": "^1.3.1",
"cspell": "^6.18.1",
"custom-element-vs-code-integration": "^1.1.0",
"del": "^7.0.0",
"download": "^8.0.0",
"esbuild": "^0.18.2",

View File

@@ -32,7 +32,7 @@ await deleteAsync([iconDir]);
await fs.mkdir(iconDir, { recursive: true });
await Promise.all([
copy(`${srcPath}/icons`, iconDir),
copy(`${srcPath}/LICENSE.md`, path.join(iconDir, 'LICENSE.md')),
copy(`${srcPath}/LICENSE`, path.join(iconDir, 'LICENSE')),
copy(`${srcPath}/bootstrap-icons.svg`, './docs/assets/images/sprite.svg', { overwrite: true })
]);

View File

@@ -24,9 +24,12 @@ components.map(component => {
const tagWithoutPrefix = component.tagName.replace(/^sl-/, '');
const componentDir = path.join(reactDir, tagWithoutPrefix);
const componentFile = path.join(componentDir, 'index.ts');
const importPath = component.path;
const importPath = component.path.replace(/\.js$/, '.component.js');
const eventImports = (component.events || [])
.map(event => `import { ${event.eventName} } from '../../../src/events/events';`)
.map(event => `import type { ${event.eventName} } from '../../../src/events/events';`)
.join('\n');
const eventExports = (component.events || [])
.map(event => `export type { ${event.eventName} } from '../../../src/events/events';`)
.join('\n');
const eventNameImport =
(component.events || []).length > 0 ? `import { type EventName } from '@lit-labs/react';` : ``;
@@ -46,6 +49,7 @@ components.map(component => {
${eventNameImport}
${eventImports}
${eventExports}
const tagName = '${component.tagName}'

View File

@@ -0,0 +1,257 @@
import { classMap } from 'lit/directives/class-map.js';
import { getAnimation, setDefaultAnimation } from '../../utilities/animation-registry.js';
import { html } from 'lit';
import { LocalizeController } from '../../utilities/localize.js';
import { property, query, state } from 'lit/decorators.js';
import ShoelaceElement from '../../internal/shoelace-element.js';
import SlIcon from '../icon/icon.component.js';
import SlTooltip from '../tooltip/tooltip.component.js';
import styles from './copy-button.styles.js';
import type { CSSResultGroup } from 'lit';
/**
* @summary Copies text data to the clipboard when the user clicks the trigger.
* @documentation https://shoelace.style/components/copy
* @status experimental
* @since 2.7
*
* @dependency sl-icon
* @dependency sl-tooltip
*
* @event sl-copy - Emitted when the data has been copied.
* @event sl-error - Emitted when the data could not be copied.
*
* @slot copy-icon - The icon to show in the default copy state. Works best with `<sl-icon>`.
* @slot success-icon - The icon to show when the content is copied. Works best with `<sl-icon>`.
* @slot error-icon - The icon to show when a copy error occurs. Works best with `<sl-icon>`.
*
* @csspart button - The internal `<button>` element.
* @csspart copy-icon - The container that holds the copy icon.
* @csspart success-icon - The container that holds the success icon.
* @csspart error-icon - The container that holds the error icon.
* @csspart tooltip__base - The tooltip's exported `base` part.
* @csspart tooltip__base__popup - The tooltip's exported `popup` part.
* @csspart tooltip__base__arrow - The tooltip's exported `arrow` part.
* @csspart tooltip__body - The tooltip's exported `body` part.
*
* @cssproperty --success-color - The color to use for success feedback.
* @cssproperty --error-color - The color to use for error feedback.
*
* @animation copy.in - The animation to use when feedback icons animate in.
* @animation copy.out - The animation to use when feedback icons animate out.
*/
export default class SlCopyButton extends ShoelaceElement {
static styles: CSSResultGroup = styles;
static dependencies = {
'sl-icon': SlIcon,
'sl-tooltip': SlTooltip
};
private readonly localize = new LocalizeController(this);
@query('slot[name="copy-icon"]') copyIcon: HTMLSlotElement;
@query('slot[name="success-icon"]') successIcon: HTMLSlotElement;
@query('slot[name="error-icon"]') errorIcon: HTMLSlotElement;
@query('sl-tooltip') tooltip: SlTooltip;
@state() isCopying = false;
@state() status: 'rest' | 'success' | 'error' = 'rest';
/** The text value to copy. */
@property() value = '';
/**
* An id that references an element in the same document from which data will be copied. If both this and `value` are
* present, this value will take precedence. By default, the target element's `textContent` will be copied. To copy an
* attribute, append the attribute name wrapped in square brackets, e.g. `from="el[value]"`. To copy a property,
* append a dot and the property name, e.g. `from="el.value"`.
*/
@property() from = '';
/** Disables the copy button. */
@property({ type: Boolean, reflect: true }) disabled = false;
/** A custom label to show in the tooltip. */
@property({ attribute: 'copy-label' }) copyLabel = '';
/** A custom label to show in the tooltip after copying. */
@property({ attribute: 'success-label' }) successLabel = '';
/** A custom label to show in the tooltip when a copy error occurs. */
@property({ attribute: 'error-label' }) errorLabel = '';
/** The length of time to show feedback before restoring the default trigger. */
@property({ attribute: 'feedback-duration', type: Number }) feedbackDuration = 1000;
/** The preferred placement of the tooltip. */
@property({ attribute: 'tooltip-placement' }) tooltipPlacement: 'top' | 'right' | 'bottom' | 'left' = 'top';
/**
* Enable this option to prevent the tooltip from being clipped when the component is placed inside a container with
* `overflow: auto|hidden|scroll`. Hoisting uses a fixed positioning strategy that works in many, but not all,
* scenarios.
*/
@property({ type: Boolean }) hoist = false;
private async handleCopy() {
if (this.disabled || this.isCopying) {
return;
}
this.isCopying = true;
// Copy the value by default
let valueToCopy = this.value;
// If an element is specified, copy from that instead
if (this.from) {
const root = this.getRootNode() as ShadowRoot | Document;
// Simple way to parse ids, properties, and attributes
const isProperty = this.from.includes('.');
const isAttribute = this.from.includes('[') && this.from.includes(']');
let id = this.from;
let field = '';
if (isProperty) {
// Split at the dot
[id, field] = this.from.trim().split('.');
} else if (isAttribute) {
// Trim the ] and split at the [
[id, field] = this.from.trim().replace(/\]$/, '').split('[');
}
// Locate the target element by id
const target = 'getElementById' in root ? root.getElementById(id) : null;
if (target) {
if (isAttribute) {
valueToCopy = target.getAttribute(field) || '';
} else if (isProperty) {
// @ts-expect-error - deal with it
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
valueToCopy = target[field] || '';
} else {
valueToCopy = target.textContent || '';
}
} else {
// No target
this.showStatus('error');
this.emit('sl-error');
}
}
// No value
if (!valueToCopy) {
this.showStatus('error');
this.emit('sl-error');
} else {
try {
await navigator.clipboard.writeText(valueToCopy);
this.showStatus('success');
this.emit('sl-copy', {
detail: {
value: valueToCopy
}
});
} catch (error) {
// Rejected by browser
this.showStatus('error');
this.emit('sl-error');
}
}
}
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;
const showAnimation = getAnimation(this, 'copy.in', { dir: 'ltr' });
const hideAnimation = getAnimation(this, 'copy.out', { dir: 'ltr' });
this.tooltip.content = status === 'success' ? successLabel : errorLabel;
// Show the feedback icon
await this.copyIcon.animate(hideAnimation.keyframes, hideAnimation.options).finished;
this.copyIcon.hidden = true;
this.status = status;
iconToShow.hidden = false;
await iconToShow.animate(showAnimation.keyframes, showAnimation.options).finished;
// After a brief delay, restore the original state
setTimeout(async () => {
await iconToShow.animate(hideAnimation.keyframes, hideAnimation.options).finished;
iconToShow.hidden = true;
this.status = 'rest';
this.copyIcon.hidden = false;
await this.copyIcon.animate(showAnimation.keyframes, showAnimation.options).finished;
this.tooltip.content = copyLabel;
this.isCopying = false;
}, this.feedbackDuration);
}
render() {
const copyLabel = this.copyLabel || this.localize.term('copy');
return html`
<sl-tooltip
class=${classMap({
'copy-button': true,
'copy-button--success': this.status === 'success',
'copy-button--error': this.status === 'error'
})}
content=${copyLabel}
placement=${this.tooltipPlacement}
?disabled=${this.disabled}
?hoist=${this.hoist}
exportparts="
base:tooltip__base
base__popup:tooltip__base__popup
base__arrow:tooltip__base__arrow
body:tooltip__body
"
>
<button
class="copy-button__button"
part="button"
type="button"
?disabled=${this.disabled}
@click=${this.handleCopy}
>
<slot part="copy-icon" name="copy-icon">
<sl-icon library="system" name="copy"></sl-icon>
</slot>
<slot part="success-icon" name="success-icon" hidden>
<sl-icon library="system" name="check"></sl-icon>
</slot>
<slot part="error-icon" name="error-icon" hidden>
<sl-icon library="system" name="x-lg"></sl-icon>
</slot>
</button>
</sl-tooltip>
`;
}
}
setDefaultAnimation('copy.in', {
keyframes: [
{ scale: '.25', opacity: '.25' },
{ scale: '1', opacity: '1' }
],
options: { duration: 100 }
});
setDefaultAnimation('copy.out', {
keyframes: [
{ scale: '1', opacity: '1' },
{ scale: '.25', opacity: '0' }
],
options: { duration: 100 }
});
declare global {
interface HTMLElementTagNameMap {
'sl-copy-button': SlCopyButton;
}
}

View File

@@ -0,0 +1,49 @@
import { css } from 'lit';
import componentStyles from '../../styles/component.styles.js';
export default css`
${componentStyles}
:host {
--error-color: var(--sl-color-danger-600);
--success-color: var(--sl-color-success-600);
display: inline-block;
}
.copy-button__button {
flex: 0 0 auto;
display: flex;
align-items: center;
background: none;
border: none;
border-radius: var(--sl-border-radius-medium);
font-size: inherit;
color: inherit;
padding: var(--sl-spacing-x-small);
cursor: pointer;
transition: var(--sl-transition-x-fast) color;
}
.copy-button--success .copy-button__button {
color: var(--success-color);
}
.copy-button--error .copy-button__button {
color: var(--error-color);
}
.copy-button__button:focus-visible {
outline: var(--sl-focus-ring);
outline-offset: var(--sl-focus-ring-offset);
}
.copy-button__button[disabled] {
opacity: 0.5;
cursor: not-allowed !important;
}
slot {
display: inline-flex;
}
`;

View File

@@ -0,0 +1,20 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
import type SlCopyButton from './copy-button.js';
// We use aria-live to announce labels via tooltips
const ignoredRules = ['button-name'];
describe('<sl-copy-button>', () => {
let el: SlCopyButton;
describe('when provided no parameters', () => {
before(async () => {
el = await fixture(html`<sl-copy-button value="something"></sl-copy-button> `);
});
it('should pass accessibility tests', async () => {
await expect(el).to.be.accessible({ ignoredRules });
});
});
});

View File

@@ -0,0 +1,4 @@
import SlCopyButton from './copy-button.component.js';
export * from './copy-button.component.js';
export default SlCopyButton;
SlCopyButton.define('sl-copy-button');

View File

@@ -213,7 +213,7 @@ export default class SlDropdown extends ShoelaceElement {
}
}
handleTriggerKeyDown(event: KeyboardEvent) {
async handleTriggerKeyDown(event: KeyboardEvent) {
// When spacebar/enter is pressed, show the panel but don't focus on the menu. This let's the user press the same
// key again to hide the menu in case they don't want to make a selection.
if ([' ', 'Enter'].includes(event.key)) {
@@ -238,6 +238,9 @@ export default class SlDropdown extends ShoelaceElement {
// Show the menu if it's not already open
if (!this.open) {
this.show();
// Wait for the dropdown to open before focusing, but not the animation
await this.updateComplete;
}
if (menuItems.length > 0) {

View File

@@ -162,7 +162,7 @@ describe('<sl-dropdown>', () => {
expect(el.open).to.be.true;
});
it('should open on arrow navigation', async () => {
it('should open on arrow down navigation', async () => {
const el = await fixture<SlDropdown>(html`
<sl-dropdown>
<sl-button slot="trigger" caret>Toggle</sl-button>
@@ -173,12 +173,35 @@ describe('<sl-dropdown>', () => {
</sl-dropdown>
`);
const trigger = el.querySelector('sl-button')!;
const firstMenuItem = el.querySelectorAll('sl-menu-item')[0];
trigger.focus();
await sendKeys({ press: 'ArrowDown' });
await el.updateComplete;
expect(el.open).to.be.true;
expect(document.activeElement).to.equal(firstMenuItem);
});
it('should open on arrow up navigation', async () => {
const el = await fixture<SlDropdown>(html`
<sl-dropdown>
<sl-button slot="trigger" caret>Toggle</sl-button>
<sl-menu>
<sl-menu-item>Item 1</sl-menu-item>
<sl-menu-item>Item 2</sl-menu-item>
</sl-menu>
</sl-dropdown>
`);
const trigger = el.querySelector('sl-button')!;
const secondMenuItem = el.querySelectorAll('sl-menu-item')[1];
trigger.focus();
await sendKeys({ press: 'ArrowUp' });
await el.updateComplete;
expect(el.open).to.be.true;
expect(document.activeElement).to.equal(secondMenuItem);
});
it('should navigate to first focusable item on arrow navigation', async () => {

View File

@@ -16,7 +16,7 @@ const icons = {
check: `
<svg part="checked-icon" class="checkbox__icon" viewBox="0 0 16 16">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round">
<g stroke="currentColor" stroke-width="2">
<g stroke="currentColor">
<g transform="translate(3.428571, 3.428571)">
<path d="M0,5.71428571 L3.42857143,9.14285714"></path>
<path d="M9.14285714,0 L3.42857143,9.14285714"></path>
@@ -40,6 +40,11 @@ const icons = {
<path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/>
</svg>
`,
copy: `
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-files" viewBox="0 0 16 16" part="svg">
<path d="M13 0H6a2 2 0 0 0-2 2 2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h7a2 2 0 0 0 2-2 2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm0 13V4a2 2 0 0 0-2-2H5a1 1 0 0 1 1-1h7a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1zM3 4a1 1 0 0 1 1-1h7a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4z"></path>
</svg>
`,
eye: `
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16">
<path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/>

View File

@@ -406,8 +406,8 @@ export default class SlInput extends ShoelaceElement implements ShoelaceFormCont
const hasHelpTextSlot = this.hasSlotController.test('help-text');
const hasLabel = this.label ? true : !!hasLabelSlot;
const hasHelpText = this.helpText ? true : !!hasHelpTextSlot;
const hasClearIcon =
this.clearable && !this.disabled && !this.readonly && (typeof this.value === 'number' || this.value.length > 0);
const hasClearIcon = this.clearable && !this.disabled && !this.readonly;
const isClearIconVisible = hasClearIcon && (typeof this.value === 'number' || this.value.length > 0);
return html`
<div
@@ -493,7 +493,10 @@ export default class SlInput extends ShoelaceElement implements ShoelaceFormCont
? html`
<button
part="clear-button"
class="input__clear"
class=${classMap({
input__clear: true,
'input__clear--visible': isClearIconVisible
})}
type="button"
aria-label=${this.localize.term('clearEntry')}
@click=${this.handleClearClick}

View File

@@ -248,6 +248,10 @@ export default css`
* Clearable + Password Toggle
*/
.input__clear:not(.input__clear--visible) {
visibility: hidden;
}
.input__clear,
.input__password-toggle {
display: inline-flex;

View File

@@ -99,8 +99,6 @@ export default class SlTooltip extends ShoelaceElement {
constructor() {
super();
// TODO (justinfagnani): does this need to be done in firstUpdated for some
// reason? If so, document why in a comment.
this.addEventListener('blur', this.handleBlur, true);
this.addEventListener('focus', this.handleFocus, true);
this.addEventListener('click', this.handleClick);

View File

@@ -51,5 +51,6 @@ export default css`
color: var(--sl-tooltip-color);
padding: var(--sl-tooltip-padding);
pointer-events: none;
user-select: none;
}
`;

View File

@@ -8,6 +8,7 @@ export type { default as SlChangeEvent } from './sl-change';
export type { default as SlClearEvent } from './sl-clear';
export type { default as SlCloseEvent } from './sl-close';
export type { default as SlCollapseEvent } from './sl-collapse';
export type { default as SlCopyEvent } from './sl-copy';
export type { default as SlErrorEvent } from './sl-error';
export type { default as SlExpandEvent } from './sl-expand';
export type { default as SlFinishEvent } from './sl-finish';

9
src/events/sl-copy.ts Normal file
View File

@@ -0,0 +1,9 @@
type SlCopyEvent = CustomEvent<{ value: string }>;
declare global {
interface GlobalEventHandlersEventMap {
'sl-copy': SlCopyEvent;
}
}
export default SlCopyEvent;

View File

@@ -33,7 +33,7 @@ function stubCustomElements() {
return;
}
// Assign it a random string so it doesnt pollute globally.
// Assign it a random string so it doesn't pollute globally.
const randomTagName = str + '-' + counter.toString();
counter++;
stub.wrappedMethod.apply(window.customElements, [randomTagName, ctor]);

View File

@@ -14,6 +14,7 @@ export { default as SlCarousel } from './components/carousel/carousel.js';
export { default as SlCarouselItem } from './components/carousel-item/carousel-item.js';
export { default as SlCheckbox } from './components/checkbox/checkbox.js';
export { default as SlColorPicker } from './components/color-picker/color-picker.js';
export { default as SlCopyButton } from './components/copy-button/copy-button.js';
export { default as SlDetails } from './components/details/details.js';
export { default as SlDialog } from './components/dialog/dialog.js';
export { default as SlDivider } from './components/divider/divider.js';

View File

@@ -9,8 +9,10 @@ const translation: Translation = {
carousel: 'Karrusel',
clearEntry: 'Ryd indtastning',
close: 'Luk',
copied: 'Kopieret',
copy: 'Kopier',
currentValue: 'Nuværende værdi',
error: 'Fejl',
goToSlide: (slide, count) => `Gå til dias ${slide} af ${count}`,
hidePassword: 'Skjul adgangskode',
loading: 'Indlæser',

View File

@@ -9,8 +9,10 @@ const translation: Translation = {
carousel: 'Karussell',
clearEntry: 'Eingabe löschen',
close: 'Schließen',
copied: 'Kopiert',
copy: 'Kopieren',
currentValue: 'Aktueller Wert',
error: 'Fehler',
goToSlide: (slide, count) => `Gehen Sie zu Folie ${slide} von ${count}`,
hidePassword: 'Passwort verbergen',
loading: 'Wird geladen',

View File

@@ -9,8 +9,10 @@ const translation: Translation = {
carousel: 'Carousel',
clearEntry: 'Clear entry',
close: 'Close',
copied: 'Copied',
copy: 'Copy',
currentValue: 'Current value',
error: 'Error',
goToSlide: (slide, count) => `Go to slide ${slide} of ${count}`,
hidePassword: 'Hide password',
loading: 'Loading',

View File

@@ -9,8 +9,10 @@ const translation: Translation = {
carousel: 'Carrusel',
clearEntry: 'Borrar entrada',
close: 'Cerrar',
copied: 'Copiado',
copy: 'Copiar',
currentValue: 'Valor actual',
error: 'Error',
goToSlide: (slide, count) => `Ir a la diapositiva ${slide} de ${count}`,
hidePassword: 'Ocultar contraseña',
loading: 'Cargando',

View File

@@ -9,8 +9,10 @@ const translation: Translation = {
carousel: 'چرخ فلک',
clearEntry: 'پاک کردن ورودی',
close: 'بستن',
copied: 'کپی شد',
copy: 'رونوشت',
currentValue: 'مقدار فعلی',
error: 'خطا',
goToSlide: (slide, count) => `رفتن به اسلاید ${slide} از ${count}`,
hidePassword: 'پنهان کردن رمز',
loading: 'بارگذاری',

View File

@@ -9,8 +9,10 @@ const translation: Translation = {
carousel: 'Carrousel',
clearEntry: `Effacer l'entrée`,
close: 'Fermer',
copied: 'Copié',
copy: 'Copier',
currentValue: 'Valeur actuelle',
error: 'Erreur',
goToSlide: (slide, count) => `Aller à la diapositive ${slide} de ${count}`,
hidePassword: 'Masquer le mot de passe',
loading: 'Chargement',

View File

@@ -9,8 +9,10 @@ const translation: Translation = {
carousel: 'קרוסלה',
clearEntry: 'נקה קלט',
close: 'סגור',
copied: 'מוּעֲתָק',
copy: 'העתק',
currentValue: 'ערך נוכחי',
error: 'שְׁגִיאָה',
goToSlide: (slide, count) => `עבור לשקופית ${slide} של ${count}`,
hidePassword: 'הסתר סיסמא',
loading: 'טוען',

View File

@@ -9,8 +9,10 @@ const translation: Translation = {
carousel: 'Körhinta',
clearEntry: 'Bejegyzés törlése',
close: 'Bezárás',
copied: 'Másolva',
copy: 'Másolás',
currentValue: 'Aktuális érték',
error: 'Hiba',
goToSlide: (slide, count) => `Ugrás a ${count}/${slide}. diára`,
hidePassword: 'Jelszó elrejtése',
loading: 'Betöltés',

View File

@@ -9,8 +9,10 @@ const translation: Translation = {
carousel: 'カルーセル',
clearEntry: 'クリアエントリ',
close: '閉じる',
copied: 'コピーされました',
copy: 'コピー',
currentValue: '現在の価値',
error: 'エラー',
goToSlide: (slide, count) => `${count} 枚中 ${slide} 枚のスライドに移動`,
hidePassword: 'パスワードを隠す',
loading: '読み込み中',

View File

@@ -9,8 +9,10 @@ const translation: Translation = {
carousel: 'Carrousel',
clearEntry: 'Invoer wissen',
close: 'Sluiten',
copied: 'Gekopieerd',
copy: 'Kopiëren',
currentValue: 'Huidige waarde',
error: 'Fout',
goToSlide: (slide, count) => `Ga naar slide ${slide} van ${count}`,
hidePassword: 'Verberg wachtwoord',
loading: 'Bezig met laden',

View File

@@ -9,8 +9,10 @@ const translation: Translation = {
carousel: 'Karuzela',
clearEntry: 'Wyczyść wpis',
close: 'Zamknij',
copied: 'Skopiowane',
copy: 'Kopiuj',
currentValue: 'Aktualna wartość',
error: 'Błąd',
goToSlide: (slide, count) => `Przejdź do slajdu ${slide} z ${count}`,
hidePassword: 'Ukryj hasło',
loading: 'Ładowanie',

View File

@@ -9,8 +9,10 @@ const translation: Translation = {
carousel: 'Carrossel',
clearEntry: 'Limpar entrada',
close: 'Fechar',
copied: 'Copiado',
copy: 'Copiar',
currentValue: 'Valor atual',
error: 'Erro',
goToSlide: (slide, count) => `Vá para o slide ${slide} de ${count}`,
hidePassword: 'Esconder a senha',
loading: 'Carregando',

Some files were not shown because too many files have changed in this diff Show More