mirror of
https://github.com/shoelace-style/shoelace.git
synced 2026-01-12 11:09:13 +00:00
Merge branch 'next' into calendar
This commit is contained in:
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -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
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -3,8 +3,6 @@ name: Feature Request
|
||||
about: Suggest an idea for this project.
|
||||
title: ''
|
||||
labels: feature
|
||||
assignees: claviska
|
||||
|
||||
---
|
||||
|
||||
### What issue are you having?
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
"erroneou",
|
||||
"errormessage",
|
||||
"esbuild",
|
||||
"exportmaps",
|
||||
"exportparts",
|
||||
"fieldsets",
|
||||
"formaction",
|
||||
@@ -152,6 +153,7 @@
|
||||
"tinycolor",
|
||||
"transitionend",
|
||||
"treeitem",
|
||||
"treeshaking",
|
||||
"Triaging",
|
||||
"turbolinks",
|
||||
"typeof",
|
||||
|
||||
@@ -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-', '')}`
|
||||
}]
|
||||
})
|
||||
]
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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'));`;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 = () => (
|
||||
<>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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" />;
|
||||
```
|
||||
|
||||
258
docs/pages/components/copy-button.md
Normal file
258
docs/pages/components/copy-button.md
Normal 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>
|
||||
</>
|
||||
);
|
||||
```
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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' }}>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 = () => (
|
||||
<>
|
||||
|
||||
@@ -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 = () => (
|
||||
<>
|
||||
|
||||
@@ -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 = () => (
|
||||
<>
|
||||
|
||||
@@ -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 />;
|
||||
```
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}>
|
||||
|
||||
@@ -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" />;
|
||||
```
|
||||
|
||||
@@ -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 = () => (
|
||||
<>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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' }}>
|
||||
|
||||
@@ -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' }}>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 />;
|
||||
```
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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 = () => (
|
||||
<>
|
||||
|
||||
@@ -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}%`} />;
|
||||
```
|
||||
|
||||
@@ -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'];
|
||||
|
||||
@@ -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 = () => (
|
||||
<>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 = () => (
|
||||
<>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 = () => (
|
||||
<>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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" />;
|
||||
```
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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))"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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
68
package-lock.json
generated
@@ -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",
|
||||
|
||||
15
package.json
15
package.json
@@ -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",
|
||||
|
||||
@@ -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 })
|
||||
]);
|
||||
|
||||
|
||||
@@ -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}'
|
||||
|
||||
|
||||
257
src/components/copy-button/copy-button.component.ts
Normal file
257
src/components/copy-button/copy-button.component.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
49
src/components/copy-button/copy-button.styles.ts
Normal file
49
src/components/copy-button/copy-button.styles.ts
Normal 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;
|
||||
}
|
||||
`;
|
||||
20
src/components/copy-button/copy-button.test.ts
Normal file
20
src/components/copy-button/copy-button.test.ts
Normal 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 });
|
||||
});
|
||||
});
|
||||
});
|
||||
4
src/components/copy-button/copy-button.ts
Normal file
4
src/components/copy-button/copy-button.ts
Normal 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');
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 () => {
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -51,5 +51,6 @@ export default css`
|
||||
color: var(--sl-tooltip-color);
|
||||
padding: var(--sl-tooltip-padding);
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -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
9
src/events/sl-copy.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
type SlCopyEvent = CustomEvent<{ value: string }>;
|
||||
|
||||
declare global {
|
||||
interface GlobalEventHandlersEventMap {
|
||||
'sl-copy': SlCopyEvent;
|
||||
}
|
||||
}
|
||||
|
||||
export default SlCopyEvent;
|
||||
@@ -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]);
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -9,8 +9,10 @@ const translation: Translation = {
|
||||
carousel: 'چرخ فلک',
|
||||
clearEntry: 'پاک کردن ورودی',
|
||||
close: 'بستن',
|
||||
copied: 'کپی شد',
|
||||
copy: 'رونوشت',
|
||||
currentValue: 'مقدار فعلی',
|
||||
error: 'خطا',
|
||||
goToSlide: (slide, count) => `رفتن به اسلاید ${slide} از ${count}`,
|
||||
hidePassword: 'پنهان کردن رمز',
|
||||
loading: 'بارگذاری',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -9,8 +9,10 @@ const translation: Translation = {
|
||||
carousel: 'קרוסלה',
|
||||
clearEntry: 'נקה קלט',
|
||||
close: 'סגור',
|
||||
copied: 'מוּעֲתָק',
|
||||
copy: 'העתק',
|
||||
currentValue: 'ערך נוכחי',
|
||||
error: 'שְׁגִיאָה',
|
||||
goToSlide: (slide, count) => `עבור לשקופית ${slide} של ${count}`,
|
||||
hidePassword: 'הסתר סיסמא',
|
||||
loading: 'טוען',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -9,8 +9,10 @@ const translation: Translation = {
|
||||
carousel: 'カルーセル',
|
||||
clearEntry: 'クリアエントリ',
|
||||
close: '閉じる',
|
||||
copied: 'コピーされました',
|
||||
copy: 'コピー',
|
||||
currentValue: '現在の価値',
|
||||
error: 'エラー',
|
||||
goToSlide: (slide, count) => `${count} 枚中 ${slide} 枚のスライドに移動`,
|
||||
hidePassword: 'パスワードを隠す',
|
||||
loading: '読み込み中',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user