Compare commits

...

50 Commits

Author SHA1 Message Date
konnorrogers
ac4826a93a fix exports 2023-06-15 15:01:18 -04:00
konnorrogers
74d78df23c fix exports 2023-06-15 14:59:26 -04:00
konnorrogers
b8d84b7962 dont export twice 2023-06-15 14:54:45 -04:00
konnorrogers
ac03167451 prototype: scoped elements 2023-06-15 14:51:13 -04:00
konnorrogers
114b20ad98 prototype: scoped elements 2023-06-15 14:47:50 -04:00
konnorrogers
c6222230e3 prototype: scoped elements 2023-06-15 14:01:29 -04:00
konnorrogers
b4a09d0fa7 prototype: scoped elements 2023-06-15 14:00:17 -04:00
Konnor Rogers
f4b2623c8f Merge pull request #1371 from shoelace-style/konnorrogers/fix-the-tests
fix the tests
2023-06-13 16:11:54 -04:00
konnorrogers
af8426579e prettier 2023-06-13 15:59:16 -04:00
konnorrogers
6b9ba9becf eslint 2023-06-13 15:54:09 -04:00
konnorrogers
c6cc7b6983 prettier 2023-06-13 15:43:21 -04:00
konnorrogers
0e869ec18d fix the tests 2023-06-13 15:40:04 -04:00
Cory LaViska
1b347874ef fix tests 2023-06-13 14:22:56 -04:00
Cory LaViska
ff5b1e8573 fix imports 2023-06-13 14:06:37 -04:00
Cory LaViska
73ad76a2fa fix serve 2023-06-13 13:48:50 -04:00
Konnor Rogers
aadcb486a9 fix broken build (#1370)
* fix broken build

* prettier
2023-06-13 12:30:32 -04:00
Cory LaViska
4c854d64a7 upgrade lit 2023-06-13 12:19:39 -04:00
Cory LaViska
c2e02d34ad remove log 2023-06-13 12:19:34 -04:00
Cory LaViska
8c8977549c fix dispose 2023-06-13 12:19:25 -04:00
Cory LaViska
24ef154d42 update esbuild 2023-06-13 11:48:17 -04:00
Cory LaViska
b5a3045bae update typescript 2023-06-13 11:37:33 -04:00
Cory LaViska
7404e496cb Merge branch 'konnorrogers/modify-build-script-for-npm-2' into next 2023-06-13 10:05:00 -04:00
konnorrogers
5ba2c7eeec watch cdn, not dist 2023-06-13 09:31:02 -04:00
Cory LaViska
514a7f3d51 Merge branch 'konnorrogers/modify-build-script-for-npm-2' of https://github.com/shoelace-style/shoelace into konnorrogers/modify-build-script-for-npm-2 2023-06-12 16:24:24 -04:00
Cory LaViska
15474b83b1 update 2023-06-12 16:24:21 -04:00
konnorrogers
a5f1bc6c82 fix circular dependency 2023-06-12 16:23:47 -04:00
Cory LaViska
834d44e0e4 npm 2023-06-12 16:22:20 -04:00
Cory LaViska
c070149ae6 update + formatting 2023-06-12 16:22:08 -04:00
Cory LaViska
b0b6ea943e use cdn bundle for docs 2023-06-12 16:15:52 -04:00
Cory LaViska
65b72217ea remove copydir and fix virtual path for serve 2023-06-12 16:15:29 -04:00
Cory LaViska
c4c2e8e3a9 make esbuild happy again 2023-06-12 15:36:35 -04:00
Cory LaViska
47018d61cd don't bundle anything for npm 2023-06-12 15:32:45 -04:00
konnorrogers
d18db9adfa prettier 2023-06-12 14:20:11 -04:00
konnorrogers
41913c8c58 update docs with cdn / npm paths 2023-06-12 13:45:27 -04:00
konnorrogers
68b982a744 update docs 2023-06-12 12:48:15 -04:00
Cory LaViska
a582302a79 update changelog 2023-06-12 12:13:18 -04:00
Brendon Muir
bd3b2c93ee Fix sl-input[type="date|time"] placeholder on macOS Safari (#1341)
Allowing the background to inherit rather than removing it allows the weird date and time placeholder text opacity to work on macOS Safari.
2023-06-12 12:09:20 -04:00
konnorrogers
4704d63791 Merge branch 'konnorrogers/modify-build-script-for-npm-2' of https://github.com/shoelace-style/shoelace into konnorrogers/modify-build-script-for-npm-2 2023-06-12 11:40:01 -04:00
konnorrogers
415a1477bb changelog, prettier 2023-06-12 11:39:56 -04:00
Cory LaViska
f363d5e187 Merge branch 'next' into konnorrogers/modify-build-script-for-npm-2 2023-06-12 11:36:23 -04:00
Cory LaViska
efb0ee9c48 fix spelling 2023-06-12 11:36:08 -04:00
konnorrogers
96daee5e1a use cdn dir for testing 2023-06-12 11:18:24 -04:00
konnorrogers
d236206cce remove unneeded CLI args 2023-06-12 10:54:33 -04:00
Konnor Rogers
1ef8e1cf73 fix: radio group race condition (#1364)
* fix: radio group race condition

* update changelog

* prettier

* fix changelog
2023-06-08 15:45:34 -04:00
Cory LaViska
dc63f858b0 fix typo 2023-06-08 15:41:03 -04:00
Cory LaViska
b8a3952153 show next/dev versiosn 2023-06-08 15:33:36 -04:00
Cory LaViska
4b2a62f660 prettier 2023-06-08 15:27:32 -04:00
Cory LaViska
08c074e44b prettier 2023-06-08 15:24:56 -04:00
Cory LaViska
d1953b0215 Merge branch 'new-docs' into next 2023-06-08 15:22:02 -04:00
Scott Martin
7cbb26cbdb Correct import statement for all React components (#1363)
The current statement is incorrect and will result in
`Module not found: Package path ./dist/shoelace is not exported from package /your/path/to/node_modules/@shoelace-style/shoelace (see exports field in /your/path/to/node_modules/@shoelace-style/shoelace/package.json)`
2023-06-06 15:27:54 -04:00
95 changed files with 1049 additions and 801 deletions

1
.gitignore vendored
View File

@@ -5,3 +5,4 @@ dist
docs/assets/images/sprite.svg
node_modules
src/react
cdn

View File

@@ -18,6 +18,7 @@
"CACHEABLE",
"callout",
"callouts",
"cdndir",
"chatbubble",
"checkmark",
"claviska",
@@ -27,6 +28,7 @@
"colocated",
"colour",
"combobox",
"Commonmark",
"Composability",
"Consolas",
"contenteditable",
@@ -43,6 +45,7 @@
"dogfood",
"dropdowns",
"easings",
"endraw",
"enterkeyhint",
"eqeqeq",
"erroneou",
@@ -102,6 +105,8 @@
"noopener",
"noreferrer",
"novalidate",
"npmdir",
"Numberish",
"outdir",
"ParamagicDev",
"peta",

View File

@@ -39,15 +39,15 @@
{% if component.summary %}
{{ component.summary | markdownInline | safe }}
{% endif %}
</p>
</p>
{# Markdown content #}
{{ content | safe }}
{# Importing #}
<h2>Importing</h2>
<p>
If you're using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use
If you're using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use
any of the following snippets to <a href="/getting-started/installation#cherry-picking">cherry pick</a> this component.
</p>
@@ -59,32 +59,32 @@
<sl-tab-panel name="script">
<p>
To import this component from <a href="https://www.jsdelivr.com/package/npm/@shoelace-style/shoelace">the CDN</a>
To import this component from <a href="https://www.jsdelivr.com/package/npm/@shoelace-style/shoelace">the CDN</a>
using a script tag:
</p>
<pre><code class="language-html">&lt;script type=&quot;module&quot; src=&quot;https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@{{ meta.version }}/dist/{{ component.path }}&quot;&gt;&lt;/script&gt;</code></pre>
<pre><code class="language-html">&lt;script type=&quot;module&quot; src=&quot;https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@{{ meta.version }}/{{ meta.cdndir }}/{{ component.path }}&quot;&gt;&lt;/script&gt;</code></pre>
</sl-tab-panel>
<sl-tab-panel name="import">
<p>
To import this component from <a href="https://www.jsdelivr.com/package/npm/@shoelace-style/shoelace">the CDN</a>
To import this component from <a href="https://www.jsdelivr.com/package/npm/@shoelace-style/shoelace">the CDN</a>
using a JavaScript import:
</p>
<pre><code class="language-js">import 'https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@{{ meta.version }}/dist/{{ component.path }}';</code></pre>
<pre><code class="language-js">import 'https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@{{ meta.version }}/{{ meta.cdndir }}/{{ component.path }}';</code></pre>
</sl-tab-panel>
<sl-tab-panel name="bundler">
<p>
To import this component using <a href="{{ rootUrl('/getting-started/installation#bundling') }}">a bundler</a>:
</p>
<pre><code class="language-js">import '@shoelace-style/shoelace/dist/{{ component.path }}';</code></pre>
<pre><code class="language-js">import '@shoelace-style/shoelace/{{ meta.npmdir }}/{{ component.path }}';</code></pre>
</sl-tab-panel>
<sl-tab-panel name="react">
<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/dist/react';</code></pre>
<pre><code class="language-js">import { {{ component.name }} } from '@shoelace-style/shoelace/{{ meta.npmdir }}/react';</code></pre>
</sl-tab-panel>
</sl-tab-group>
@@ -337,11 +337,11 @@
<h2>Dependencies</h2>
<p>This component automatically imports the following dependencies.</p>
<ul>
{% for dependency in component.dependencies %}
<li><code>&lt;{{ dependency }}&gt;</code></li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}
{% endblock %}

View File

@@ -34,9 +34,9 @@
<meta property="og:image" content="{{ assetUrl(meta.image, true) }}" />
{# Shoelace #}
<link rel="stylesheet" href="/dist/themes/light.css" />
<link rel="stylesheet" href="/dist/themes/dark.css" />
<script type="module" src="/dist/shoelace-autoloader.js"></script>
<link rel="stylesheet" href="/cdn/themes/light.css" />
<link rel="stylesheet" href="/cdn/themes/dark.css" />
<script type="module" src="/cdn/shoelace-autoloader.js"></script>
{# Set the initial theme and menu states here to prevent flashing #}
<script>

View File

@@ -23,4 +23,4 @@ module.exports = function (content, options) {
};
return format(content, options);
}
};

View File

@@ -0,0 +1,19 @@
/**
* @typedef {object} Replacement
* @property {string | RegExp} pattern
* @property {string} replacement
*/
/**
* @typedef {Array<Replacement>} Replacements
*/
/**
* @param {Document} content
* @param {Replacements} replacements
*/
module.exports = function (content, replacements) {
replacements.forEach(replacement => {
content.body.innerHTML = content.body.innerHTML.replaceAll(replacement.pattern, replacement.replacement);
});
};

View File

@@ -180,7 +180,7 @@
// HTML templates
if (!isReact) {
htmlTemplate =
`<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@${shoelaceVersion}/dist/shoelace.js"></script>\n` +
`<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@${shoelaceVersion}/%CDNDIR%/shoelace.js"></script>\n` +
`\n${htmlExample}`;
jsTemplate = '';
}
@@ -191,10 +191,10 @@
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}/dist/utilities/base-path';\n` +
`import { setBasePath } from 'https://cdn.skypack.dev/@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}/dist/')\n` +
`setBasePath('https://cdn.skypack.dev/@shoelace-style/shoelace@${shoelaceVersion}/%NPMDIR%/')\n` +
`\n${convertModuleLinks(reactExample)}\n` +
`\n` +
`ReactDOM.render(<App />, document.getElementById('root'));`;
@@ -202,7 +202,7 @@
// CSS templates
cssTemplate =
`@import 'https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@${shoelaceVersion}/dist/themes/${
`@import 'https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@${shoelaceVersion}/%CDNDIR%/themes/${
isDark ? 'dark' : 'light'
}.css';\n` +
'\n' +

View File

@@ -30,7 +30,6 @@
// Toggle the menu
document.addEventListener('click', event => {
const menuToggle = event.target.closest('#menu-toggle');
console.log(event.target, menuToggle);
if (!menuToggle) return;
toggleSidebar();
});
@@ -211,7 +210,7 @@
}
function updateActiveLinks() {
const links = getLinks()
const links = getLinks();
// Find the first visible target and activate the respective link
links.find(link => {
const target = linkTargets.get(link);
@@ -226,7 +225,7 @@
}
// Observe link targets
function observeLinks () {
function observeLinks() {
getLinks().forEach(link => {
const hash = link.hash.slice(1);
const target = hash ? document.querySelector(`.content__body #${hash}`) : null;
@@ -238,8 +237,25 @@
});
}
observeLinks()
observeLinks();
document.addEventListener("turbo:load", updateActiveLinks)
document.addEventListener("turbo:load", observeLinks)
document.addEventListener('turbo:load', updateActiveLinks);
document.addEventListener('turbo:load', observeLinks);
})();
//
// Show custom versions in the sidebar
//
(() => {
function updateVersion() {
const el = document.querySelector('.sidebar-version');
if (!el) return;
if (location.hostname === 'next.shoelace.style') el.textContent = 'Next';
if (location.hostname === 'localhost') el.textContent = 'Development';
}
updateVersion();
document.addEventListener('turbo:load', updateVersion);
})();

View File

@@ -267,7 +267,7 @@ hr {
margin: calc(var(--docs-content-vertical-spacing) * 2) 0;
}
/* Blockquotes */
/* Block quotes */
blockquote {
position: relative;
font-family: var(--sl-font-serif);

View File

@@ -16,8 +16,11 @@ const tableOfContents = require('./_utilities/table-of-contents.cjs');
const prettier = require('./_utilities/prettier.cjs');
const scrollingTables = require('./_utilities/scrolling-tables.cjs');
const typography = require('./_utilities/typography.cjs');
const replacer = require('./_utilities/replacer.cjs');
const assetsDir = 'assets';
const cdndir = 'cdn';
const npmdir = 'dist';
const allComponents = getAllComponents();
let hasBuiltSearchIndex = false;
@@ -33,7 +36,9 @@ module.exports = function (eleventyConfig) {
description: 'A forward-thinking library of web components.',
image: 'images/og-image.png',
version: customElementsManifest.package.version,
components: allComponents
components: allComponents,
cdndir,
npmdir
});
//
@@ -129,6 +134,11 @@ module.exports = function (eleventyConfig) {
scrollingTables(doc);
copyCodeButtons(doc); // must be after codePreviews + highlightCodeBlocks
typography(doc, '#content');
replacer(doc, [
{ pattern: '%VERSION%', replacement: customElementsManifest.package.version },
{ pattern: '%CDNDIR%', replacement: cdndir },
{ pattern: '%NPMDIR%', replacement: npmdir }
]);
// Serialize the Document object to an HTML string and prepend the doctype
content = `<!DOCTYPE html>\n${doc.documentElement.outerHTML}`;
@@ -208,7 +218,7 @@ module.exports = function (eleventyConfig) {
eleventyConfig.setServerOptions({
domDiff: false, // disable dom diffing so custom elements don't break on reload,
port: 4000, // if port 4000 is taken, 11ty will use the next one available
watch: ['dist/**/*'] // additional files to watch that will trigger server updates (array of paths or globs)
watch: ['cdn/**/*'] // additional files to watch that will trigger server updates (array of paths or globs)
});
//

View File

@@ -7,7 +7,7 @@ layout: component
According to [The A11Y Project](https://www.a11yproject.com/posts/2013-01-11-how-to-hide-content/), "there are real world situations where visually hiding content may be appropriate, while the content should remain available to assistive technologies, such as screen readers. For instance, hiding a search field's label as a common magnifying glass icon is used in its stead."
Since visually hidden content can receive focus when tabbing, the element will become visible when something inside receives focus. This behavior is intentional, as sighted keyboards user won't be able to determine where the focus indicator is without it.
Since visually hidden content can receive focus when tabbing, the element will become visible when something inside receives focus. This behavior is intentional, as sighted keyboard user won't be able to determine where the focus indicator is without it.
```html:preview
<div style="min-height: 1.875rem;">

View File

@@ -19,14 +19,14 @@ npm install @shoelace-style/shoelace
Next, [include a theme](/getting-started/themes) and set the [base path](/getting-started/installation#setting-the-base-path) for icons and other assets. In this example, we'll import the light theme and use the CDN as a base path.
```jsx
import '@shoelace-style/shoelace/dist/themes/light.css';
import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path';
import '@shoelace-style/shoelace/%NPMDIR%/themes/light.css';
import { setBasePath } from '@shoelace-style/shoelace/%NPMDIR%/utilities/base-path';
setBasePath('https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/');
setBasePath('https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/%CDNDIR%/');
```
:::tip
If you'd rather not use the CDN for assets, you can create a build task that copies `node_modules/@shoelace-style/shoelace/dist/assets` into a public folder in your app. Then you can point the base path to that folder instead.
If you'd rather not use the CDN for assets, you can create a build task that copies `node_modules/@shoelace-style/shoelace/%NPMDIR%/assets` into a public folder in your app. Then you can point the base path to that folder instead.
:::
## Configuration

View File

@@ -20,14 +20,14 @@ Next, [include a theme](/getting-started/themes) and set the [base path](/gettin
```jsx
// App.jsx
import '@shoelace-style/shoelace/dist/themes/light.css';
import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path';
import '@shoelace-style/shoelace/%NPMDIR%/themes/light.css';
import { setBasePath } from '@shoelace-style/shoelace/%NPMDIR%/utilities/base-path';
setBasePath('https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/');
setBasePath('https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/%CDNDIR%/');
```
:::tip
If you'd rather not use the CDN for assets, you can create a [build task](https://webpack.js.org/plugins/copy-webpack-plugin/) that copies `node_modules/@shoelace-style/shoelace/dist/assets` into your app's `public` directory. Then you can point the base path to that folder instead.
If you'd rather not use the CDN for assets, you can create a [build task](https://webpack.js.org/plugins/copy-webpack-plugin/) that copies `node_modules/@shoelace-style/shoelace/%NPMDIR%/assets` into your app's `public` directory. Then you can point the base path to that folder instead.
:::
Now you can start using components!
@@ -39,7 +39,7 @@ 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/dist/react';
import { SlButton } from '@shoelace-style/shoelace/%NPMDIR%/react';
const MyComponent = () => <SlButton variant="primary">Click me</SlButton>;
@@ -56,7 +56,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/dist/react';
import { SlInput } from '@shoelace-style/shoelace/%NPMDIR%/react';
function MyComponent() {
const [value, setValue] = useState('');
@@ -71,8 +71,8 @@ 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/dist/react';
import type SlInputElement from '@shoelace-style/shoelace/dist/components/input/input';
import { SlInput } from '@shoelace-style/shoelace/%NPMDIR%/react';
import type SlInputElement from '@shoelace-style/shoelace/%NPMDIR%/components/input/input';
function MyComponent() {
const [value, setValue] = useState('');

View File

@@ -23,10 +23,10 @@ npm install @shoelace-style/shoelace
Next, [include a theme](/getting-started/themes) and set the [base path](/getting-started/installation#setting-the-base-path) for icons and other assets. In this example, we'll import the light theme and use the CDN as a base path.
```jsx
import '@shoelace-style/shoelace/dist/themes/light.css';
import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path';
import '@shoelace-style/shoelace/%NPMDIR%/themes/light.css';
import { setBasePath } from '@shoelace-style/shoelace/%NPMDIR%/utilities/base-path';
setBasePath('https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/');
setBasePath('https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/%CDNDIR%/');
```
:::tip

View File

@@ -26,7 +26,7 @@ Next, [include a theme](/getting-started/themes) and set the [base path](/gettin
import '@shoelace-style/shoelace/dist/themes/light.css';
import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path';
setBasePath('https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/');
setBasePath('https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/%CDNDIR%/');
```
:::tip

View File

@@ -22,8 +22,8 @@ While convenient, autoloading may lead to a [Flash of Undefined Custom Elements]
<!-- prettier-ignore -->
```html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/themes/light.css" />
<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/shoelace-autoloader.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/%CDNDIR%/themes/light.css" />
<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/%CDNDIR%/shoelace-autoloader.js"></script>
```
</sl-tab-panel>
@@ -32,9 +32,10 @@ While convenient, autoloading may lead to a [Flash of Undefined Custom Elements]
The traditional CDN loader registers all Shoelace elements up front. Note that, if you're only using a handful of components, it will be much more efficient to stick with the autoloader. However, you can also [cherry pick](#cherry-picking) components if you want to load specific ones up front.
<!-- prettier-ignore -->
```html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/themes/light.css" />
<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/shoelace.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/%CDNDIR%/themes/light.css" />
<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/%CDNDIR%/shoelace.js" ></script>
```
</sl-tab-panel>
@@ -44,8 +45,9 @@ The traditional CDN loader registers all Shoelace elements up front. Note that,
The code above will load the light theme. If you want to use the [dark theme](/getting-started/themes#dark-theme) instead, update the stylesheet as shown below and add `<html class="sl-theme-dark">` to your page.
<!-- prettier-ignore -->
```html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/themes/dark.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/%CDNDIR%/themes/dark.css" />
```
### Light & Dark Theme
@@ -56,21 +58,21 @@ If you want to load the light or dark theme based on the user's `prefers-color-s
<link
rel="stylesheet"
media="(prefers-color-scheme:light)"
href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/themes/light.css"
href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/%CDNDIR%/themes/light.css"
/>
<link
rel="stylesheet"
media="(prefers-color-scheme:dark)"
href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/themes/dark.css"
href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/%CDNDIR%/themes/dark.css"
onload="document.documentElement.classList.add('sl-theme-dark');"
/>
```
Now you can [start using Shoelace!](/getting-started/usage)
## Local Installation
## npm installation
If you don't want to use the CDN, you can install Shoelace locally with the following command.
If you don't want to use the CDN, you can install Shoelace from npm with the following command.
```bash
npm install @shoelace-style/shoelace
@@ -81,8 +83,8 @@ It's up to you to make the source files available to your app. One way to do thi
Once you've done that, add the following tags to your page. Make sure to update `href` and `src` so they point to the route you created.
```html
<link rel="stylesheet" href="/shoelace/dist/themes/light.css" />
<script type="module" src="/shoelace/dist/shoelace.js"></script>
<link rel="stylesheet" href="/shoelace/%NPMDIR%/themes/light.css" />
<script type="module" src="/shoelace/%NPMDIR%/shoelace.js"></script>
```
Alternatively, [you can use a bundler](#bundling).
@@ -99,31 +101,37 @@ However, if you're [cherry picking](#cherry-picking) or [bundling](#bundling) Sh
```html
<!-- Option 1: the data-shoelace attribute -->
<script src="bundle.js" data-shoelace="/path/to/shoelace/dist"></script>
<script src="bundle.js" data-shoelace="/path/to/shoelace/%NPMDIR%"></script>
<!-- Option 2: the setBasePath() method -->
<script src="bundle.js"></script>
<script type="module">
import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path.js';
setBasePath('/path/to/shoelace/dist');
import { setBasePath } from '@shoelace-style/shoelace/%NPMDIR%/utilities/base-path.js';
setBasePath('/path/to/shoelace/%NPMDIR%');
</script>
```
:::tip
The library also exports a `getBasePath()` method you can use to reference assets.
When setting a basePath, and easy way to check if it was down properly is by checking if an icon exists.
For example, if I set the basePath to `/dist`, I should be able to go to:
`https://<my-site>/dist/assets/icons/arrow-left.svg` and the browser should show me the SVG.
Shoelace also exports a `getBasePath()` method you can use to reference assets.
:::
## Cherry Picking
Cherry picking can be done from [the CDN](#cdn-installation-easiest) or your [local installation](#local-installation). This approach will load only the components you need up front, while limiting the number of files the browser has to download. The disadvantage is that you need to import each individual component.
Cherry picking can be done from [the CDN](#cdn-installation-easiest) or from [npm](#npm-installation). This approach will load only the components you need up front, while limiting the number of files the browser has to download. The disadvantage is that you need to import each individual component.
Here's an example that loads only the button component. Again, if you're not using a module resolver, you'll need to adjust the path to point to the folder Shoelace is in.
```html
<link rel="stylesheet" href="/path/to/shoelace/dist/themes/light.css" />
<link rel="stylesheet" href="/path/to/shoelace/%NPMDIR%/themes/light.css" />
<script type="module" data-shoelace="/path/to/shoelace/dist">
import '@shoelace-style/shoelace/dist/components/button/button.js';
<script type="module" data-shoelace="/path/to/shoelace/%NPMDIR%">
import '@shoelace-style/shoelace/%NPMDIR%/components/button/button.js';
// <sl-button> is ready to use!
</script>
@@ -157,15 +165,15 @@ Now it's time to configure your bundler. Configurations vary for each tool, but
Once your bundler is configured, you'll be able to import Shoelace components and utilities.
```js
import '@shoelace-style/shoelace/dist/themes/light.css';
import '@shoelace-style/shoelace/dist/components/button/button.js';
import '@shoelace-style/shoelace/dist/components/icon/icon.js';
import '@shoelace-style/shoelace/dist/components/input/input.js';
import '@shoelace-style/shoelace/dist/components/rating/rating.js';
import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path.js';
import '@shoelace-style/shoelace/%NPMDIR%/themes/light.css';
import '@shoelace-style/shoelace/%NPMDIR%/components/button/button.js';
import '@shoelace-style/shoelace/%NPMDIR%/components/icon/icon.js';
import '@shoelace-style/shoelace/%NPMDIR%/components/input/input.js';
import '@shoelace-style/shoelace/%NPMDIR%/components/rating/rating.js';
import { setBasePath } from '@shoelace-style/shoelace/%NPMDIR%/utilities/base-path.js';
// Set the base path to the folder you copied Shoelace's assets to
setBasePath('/path/to/shoelace/dist');
setBasePath('/path/to/shoelace/%NPMDIR%
// <sl-button>, <sl-icon>, <sl-input>, and <sl-rating> are ready to use!
```
@@ -173,3 +181,14 @@ setBasePath('/path/to/shoelace/dist');
:::warning
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.
:::
## The difference between CDN and npm
You'll notice that the CDN links all start with `/%CDNDIR%/<path>` and npm imports use `/%NPMDIR%/<path>`. The `/%CDNDIR%` files are bundled separately from the `/%NPMDIR%` files. The `/%CDNDIR%` files come pre-bundled, which means all dependencies are inlined so you do not need to worry about loading additional libraries. The `/%NPMDIR%` files **DO NOT** come pre-bundled, allowing your bundler of choice to more efficiently deduplicate dependencies, resulting in smaller bundles and optimal code sharing.
TL;DR:
- `@shoelace-style/shoelace/%CDNDIR%` is for CDN users
- `@shoelace-style/shoelace/%NPMDIR%` is for npm users
This change was introduced in `v2.5.0` to address issues around installations from npm loading multiple versions of libraries (such as the Lit) that Shoelace uses internally.

View File

@@ -28,8 +28,8 @@ Shoelace ships with a number of translations. The default is English (US), which
The location of translations depends on how you're consuming Shoelace.
- If you're using the CDN, [import them from the CDN](https://www.jsdelivr.com/package/npm/@shoelace-style/shoelace?path=dist%2Ftranslations)
- If you're using a bundler, import them from `@shoelace-style/shoelace/dist/translations/[lang].js`
- If you're using the CDN, [import them from the CDN](https://www.jsdelivr.com/package/npm/@shoelace-style/shoelace?path=%CDNDIR%%2Ftranslations)
- If you're using a bundler, import them from `@shoelace-style/shoelace/%NPMDIR%/translations/[lang].js`
You do not need to load translations up front. You can import them dynamically even after updating the `lang` attribute. Once a translation is registered, localized components will update automatically.

View File

@@ -11,7 +11,7 @@ Shoelace is designed to be highly customizable through pure CSS. Out of the box,
A theme is nothing more than a stylesheet that uses the Shoelace API to define design tokens and apply custom styles to components. To create a theme, you will need a decent understanding of CSS, including [CSS Custom Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/--*) and the [`::part` selector](https://developer.mozilla.org/en-US/docs/Web/CSS/::part).
:::tip
For component developers, built-in themes are also available as JavaScript modules that export [Lit CSSResult](https://lit.dev/docs/api/styles/#CSSResult) objects. You can find them in `dist/themes/*.styles.js`.
For component developers, built-in themes are also available as JavaScript modules that export [Lit CSSResult](https://lit.dev/docs/api/styles/#CSSResult) objects. You can find them in `%NPMDIR%/themes/*.styles.js`.
:::
## Theme Basics
@@ -34,7 +34,7 @@ To activate a theme, import it and apply the theme's class to the `<html>` eleme
```html
<html class="sl-theme-dark">
<head>
<link rel="stylesheet" href="path/to/shoelace/dist/themes/dark.css" />
<link rel="stylesheet" href="path/to/shoelace/%NPMDIR%/themes/dark.css" />
</head>
<body>
@@ -54,8 +54,8 @@ You can activate themes on various containers throughout the page. This example
```html
<html>
<head>
<link rel="stylesheet" href="path/to/shoelace/dist/themes/light.css" />
<link rel="stylesheet" href="path/to/shoelace/dist/themes/dark.css" />
<link rel="stylesheet" href="path/to/shoelace/%NPMDIR%/themes/light.css" />
<link rel="stylesheet" href="path/to/shoelace/%NPMDIR%/themes/dark.css" />
</head>
<body>
@@ -127,7 +127,10 @@ The dark theme works by taking the light theme's [color tokens](/tokens/color) a
To install the dark theme, add the following to the `<head>` section of your page.
```html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/themes/dark.css" />
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/%CDNDIR%/themes/dark.css"
/>
```
To activate the theme, apply the `sl-theme-dark` class to the `<html>` element.

View File

@@ -41,8 +41,8 @@ Add the following code to your page.
<!-- prettier-ignore -->
```html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/themes/light.css" />
<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/dist/shoelace-autoloader.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/%CDNDIR%/themes/light.css" />
<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/%CDNDIR%/shoelace-autoloader.js"></script>
```
Now you have access to all of Shoelace's components! Try adding a button:

View File

@@ -14,11 +14,23 @@ New versions of Shoelace are released as-needed and generally occur when a criti
## Next
This release [unbundles Lit](https://github.com/shoelace-style/shoelace/issues/559) (and other dependencies) from Shoelace. There are now two distributions for the project:
1. `cdn/`  a bundled, CDN-ready distribution
2. `dist/` an unbundled, npm-ready distribution
:::warning
If you're a CDN user, you must update your path to point to `cdn/` instead of `dist/`. You can copy and paste the latest paths from the [installation page](/getting-started/installation).
:::
- Added a `cdn/` distribution for bundled dependencies (imports for npm users remain the same) [#1369](https://github.com/shoelace-style/shoelace/pull/1369)
- Added the `checkbox` part and related exported parts to `<sl-tree-item>` so you can target it with CSS [#1318](https://github.com/shoelace-style/shoelace/discussions/1318)
- Added the `submenu-icon` part to `<sl-menu-item>` (submenus have not been implemented yet, but this part is required to allow customizations)
- Added tests for `<sl-split-panel>` [#1343](https://github.com/shoelace-style/shoelace/pull/1343)
- Fixed a bug where changing the size of `<sl-radio-group>` wouldn't update the size of child elements
- Fixed a bug in `<sl-select>` and `<sl-color-picker>` where the `size` attribute wasn't being reflected [#1318](https://github.com/shoelace-style/shoelace/issues/1348)
- Fixed a bug in `<sl-radio-group>` where `<sl-radio>` would not get checked if `<sl-radio-group>` was defined first. [#1364](https://github.com/shoelace-style/shoelace/pull/1364/)
- Fixed a bug in `<sl-input>` that caused date pickers to look filled in even when empty in Safari [#1341](https://github.com/shoelace-style/shoelace/pull/1341)
- Improved `<sl-button>` so it can accept children of variable heights [#1317](https://github.com/shoelace-style/shoelace/pull/1317)
- Improved the docs to more clearly explain sizing radios and radio buttons
- Improved the performance of `<sl-rating>` by partially rendering unseen icons [#1310](https://github.com/shoelace-style/shoelace/pull/1310)
@@ -26,6 +38,10 @@ New versions of Shoelace are released as-needed and generally occur when a criti
- Improved the German translation [#1339](https://github.com/shoelace-style/shoelace/pull/1339)
- Improved the autoloader so it watches `<html>` instead of `<body>` since the latter gets replaced by some frameworks [#1338](https://github.com/shoelace-style/shoelace/pull/1338)
- Improved the Rails documentation [#1258](https://github.com/shoelace-style/shoelace/pull/1258)
- Replaced Docsify with Eleventy to generate a static HTML version of the docs
- Updated esbuild to 0.18.2
- Updated Lit to 2.7.5
- Updated TypeScript to 5.1.3
## 2.4.0

View File

@@ -67,7 +67,7 @@ function CustomEls({ URL }) {
setBasePath(`${URL}/static/static`);
// This imports all components
import('@shoelace-style/shoelace/dist/shoelace');
import('@shoelace-style/shoelace/dist/react');
// If you're wanting to selectively import components, replace this line with your own definitions
// import("@shoelace-style/shoelace/dist/components/button/button");

493
package-lock.json generated
View File

@@ -12,10 +12,11 @@
"@ctrl/tinycolor": "^3.5.0",
"@floating-ui/dom": "^1.2.1",
"@lit-labs/react": "^1.1.1",
"@open-wc/scoped-elements": "^2.2.0",
"@shoelace-style/animations": "^1.1.0",
"@shoelace-style/localize": "^3.1.0",
"@shoelace-style/localize": "^3.1.1",
"composed-offset-position": "^0.0.4",
"lit": "^2.6.1",
"lit": "^2.7.5",
"qr-creator": "^1.0.0"
},
"devDependencies": {
@@ -40,7 +41,7 @@
"cspell": "^6.18.1",
"del": "^7.0.0",
"download": "^8.0.0",
"esbuild": "^0.16.17",
"esbuild": "^0.18.2",
"eslint": "^8.31.0",
"eslint-plugin-chai-expect": "^3.0.0",
"eslint-plugin-chai-friendly": "^0.7.2",
@@ -76,7 +77,7 @@
"source-map": "^0.7.4",
"strip-css-comments": "^5.0.0",
"tslib": "^2.4.1",
"typescript": "4.9.4",
"typescript": "^5.1.3",
"user-agent-data-types": "^0.3.0"
},
"engines": {
@@ -957,9 +958,9 @@
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.17.tgz",
"integrity": "sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.2.tgz",
"integrity": "sha512-YAnQBHlY0IvYtvY0avnXjI8ywW23emEjk5XExqbFmypath+Snq9MgY1IS47rnqBKVSqnl0ElDt221ZgaeRrkXg==",
"cpu": [
"arm"
],
@@ -973,9 +974,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz",
"integrity": "sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.2.tgz",
"integrity": "sha512-1Y2pb0hLdmji8I0zBwNsYSDN7zJSQqufgLOuOsrrod00WEAgKywQR5MB/E046Is/YTP4bgcPS4BioaSDBaLaTg==",
"cpu": [
"arm64"
],
@@ -989,9 +990,9 @@
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.16.17.tgz",
"integrity": "sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.2.tgz",
"integrity": "sha512-P047Mh3pj8uYVE3A/B3QDX6nG8dKbHLJ+48R6Y0CRXCJ5PkXJxdHOTaS8SYs6eSR3FFU6/YQ5TishQXVHX7F5A==",
"cpu": [
"x64"
],
@@ -1005,9 +1006,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.16.17.tgz",
"integrity": "sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.2.tgz",
"integrity": "sha512-a3Rkqd0tGVYMEKNy9SstWEdeBmM60l8FVD5o4rmwHr3xO1LbLqtCJSrWGbnf37hevo6m437mURVmpEHOmkXeTA==",
"cpu": [
"arm64"
],
@@ -1021,9 +1022,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz",
"integrity": "sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.2.tgz",
"integrity": "sha512-cvH58adz9L10JNsIcgtkWNS/1eutjRTi3rtWz1s3ZhR64BpdmkxJBAXE/UjqybyNAWLhaN8mPJdlYI2f+tQA7g==",
"cpu": [
"x64"
],
@@ -1037,9 +1038,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.17.tgz",
"integrity": "sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.2.tgz",
"integrity": "sha512-68rGMGUdgmq+c5IvseCMqY4yaa2CAY/DIILMBA6bEU1caISF7fXnV69B1uU4s3ERuVDcasVVwiAFyNxCtkS6Zg==",
"cpu": [
"arm64"
],
@@ -1053,9 +1054,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.16.17.tgz",
"integrity": "sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.2.tgz",
"integrity": "sha512-ZSR9On/rXoYuAtrXo5hYKy7OuZwKZyFh2rr6L3TX4UeR1tWLf84aLyAFt7e0tlRbh4zNgqFx+ePWmsSHw7L9Bw==",
"cpu": [
"x64"
],
@@ -1069,9 +1070,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.16.17.tgz",
"integrity": "sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.2.tgz",
"integrity": "sha512-jAbA75qJ70T5AOdmw9X8675ppeRfj7j57sOypoZ4mQlfQ/LKF8eoeLzTYVo8+aqLKqeIIl0vQ4hKOB0FyG98Zg==",
"cpu": [
"arm"
],
@@ -1085,9 +1086,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.16.17.tgz",
"integrity": "sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.2.tgz",
"integrity": "sha512-DFKavAzbu/n9HXWuetxmYN10XnfzW7FgOgpcrGD8eXaiu77KdgB+OVWA83x9FtDYtsoFpfdlDuVFAQFfrhu77A==",
"cpu": [
"arm64"
],
@@ -1101,9 +1102,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.16.17.tgz",
"integrity": "sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.2.tgz",
"integrity": "sha512-VEaK3Z+vJyDwwPsP0sovaEw1foDzrMs7XQNYEIFkOwMjSe2BipKRKUUyrznil0p8qqsK7U8W+T7oNqZpgdnD2Q==",
"cpu": [
"ia32"
],
@@ -1117,9 +1118,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.16.17.tgz",
"integrity": "sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.2.tgz",
"integrity": "sha512-Af1uZdB0oeJo4PW67l9aw94oakSamFxhC6ltC2eDkndozd9QygVNMTF7s7uxTLjo+BJqyVqG9wjmLCYF1o4NmA==",
"cpu": [
"loong64"
],
@@ -1133,9 +1134,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.16.17.tgz",
"integrity": "sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.2.tgz",
"integrity": "sha512-WcTbt61+9dREuOFKXac4Qg+3OuRhLxPL9lmkI2P7fGuq/fWS2qq+AvGGVLMyk+OtXGDjyQolcEDeYlRoOmjRYQ==",
"cpu": [
"mips64el"
],
@@ -1149,9 +1150,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.16.17.tgz",
"integrity": "sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.2.tgz",
"integrity": "sha512-Ov+VHayvCPb52axma6+xm8QDawRjwHscPXedHg4U92DxlhKQ0H+6onRiC3J9kKI50p8pKKypprpCWrRrXjZN7Q==",
"cpu": [
"ppc64"
],
@@ -1165,9 +1166,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.16.17.tgz",
"integrity": "sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.2.tgz",
"integrity": "sha512-qW37zzKKN9C5l5LnVDriOK0eZRzQeixhtrfd5C78PAsTE15GeHU9G0oyT/u/IkNjEBjXWpTZOOHKNbjhrvuL9g==",
"cpu": [
"riscv64"
],
@@ -1181,9 +1182,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.16.17.tgz",
"integrity": "sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.2.tgz",
"integrity": "sha512-izzEFMRO8LaQIlX22+fTgP5I7Os3T51mtAWsRNpZ5pMfQIa9PqtgFAoRcb10DV+/YkH/TMMxQIlevUvDS6E4vw==",
"cpu": [
"s390x"
],
@@ -1197,9 +1198,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.16.17.tgz",
"integrity": "sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.2.tgz",
"integrity": "sha512-y5yqQ1ww4FfI9bQ1ZP/0k1rcgA6Ql2/AgzvqpowN0Q5tXDZkCavPdJbFXKrqA43vd1UTXt+AutTHYJ7km6e2Eg==",
"cpu": [
"x64"
],
@@ -1213,9 +1214,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.16.17.tgz",
"integrity": "sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.2.tgz",
"integrity": "sha512-usNjpKFf83X4o60gdMD47NCblaSZ6DARf31/FyCzxOgnF80mJ+RhDs9RTqgyfH8KyduO5mjgInw9+ct286ayYA==",
"cpu": [
"x64"
],
@@ -1229,9 +1230,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.16.17.tgz",
"integrity": "sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.2.tgz",
"integrity": "sha512-6urzy1+VwcPuhG+5jwHA8lD9E87E5+ey3qKw2EhRS+qUmMxLvfwP8szWC2JHVGZDPEDge6fgn0pBj+y9rxDLwQ==",
"cpu": [
"x64"
],
@@ -1245,9 +1246,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.16.17.tgz",
"integrity": "sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.2.tgz",
"integrity": "sha512-SMZPTACsvpKYAIl9o8nhnmMn6/lp62iMeV/2EBMtj+sW6dXwW9b0cLjihkBv4PG1CCRlwWKPZo43imqZxC95ZA==",
"cpu": [
"x64"
],
@@ -1261,9 +1262,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.16.17.tgz",
"integrity": "sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.2.tgz",
"integrity": "sha512-H2zzjPdzSDNwUnZdZf9/xfm0CYqHFXuenCMAx+tRzIRqWUT6MmZ9/q7722KnAZ6uPpq0RLs7EjCIIfmt6CaRGg==",
"cpu": [
"arm64"
],
@@ -1277,9 +1278,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.16.17.tgz",
"integrity": "sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.2.tgz",
"integrity": "sha512-lfyjTN+FrKgvNvrH7nOLtaz58J/8coZOo4LQwgBMP4D7ZOurhvluXS3GjePLzq9GbWnJDZdKCKbMKhZPPcdJJA==",
"cpu": [
"ia32"
],
@@ -1293,9 +1294,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz",
"integrity": "sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.2.tgz",
"integrity": "sha512-Q4nIjqWXjxkELwd7kVepsJxbQ/6ERNsHpjz1j+IKjwSYw+g06U0RQOy5xh848AHvgr9itnGLa3cT2G5t0dBFsw==",
"cpu": [
"x64"
],
@@ -1435,9 +1436,9 @@
"integrity": "sha512-9TC+/ZWb6BJlWCyUr14FKFlaGnyKpeEDorufXozQgke/VoVrslUQNaL7nBmrAWdNrmzx5jWgi8lFmWwrxMjnlA=="
},
"node_modules/@lit-labs/ssr-dom-shim": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.0.0.tgz",
"integrity": "sha512-ic93MBXfApIFTrup4a70M/+ddD8xdt2zxxj9sRwHQzhS9ag/syqkD8JPdTXsc1gUy2K8TTirhlCqyTEM/sifNw=="
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.1.1.tgz",
"integrity": "sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ=="
},
"node_modules/@lit/reactive-element": {
"version": "1.6.1",
@@ -1658,19 +1659,17 @@
"dev": true
},
"node_modules/@open-wc/dedupe-mixin": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@open-wc/dedupe-mixin/-/dedupe-mixin-1.3.1.tgz",
"integrity": "sha512-ukowSvzpZQDUH0Y3znJTsY88HkiGk3Khc0WGpIPhap1xlerieYi27QBg6wx/nTurpWfU6XXXsx9ocxDYCdtw0Q==",
"dev": true
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@open-wc/dedupe-mixin/-/dedupe-mixin-1.4.0.tgz",
"integrity": "sha512-Sj7gKl1TLcDbF7B6KUhtvr+1UCxdhMbNY5KxdU5IfMFWqL8oy1ZeAcCANjoB1TL0AJTcPmcCFsCbHf8X2jGDUA=="
},
"node_modules/@open-wc/scoped-elements": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/@open-wc/scoped-elements/-/scoped-elements-2.1.3.tgz",
"integrity": "sha512-WoQD5T8Me9obek+iyjgrAMw9wxZZg4ytIteIN1i9LXW2KohezUp0LTOlWgBajWJo0/bpjUKiODX73cMYL2i3hw==",
"dev": true,
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@open-wc/scoped-elements/-/scoped-elements-2.2.0.tgz",
"integrity": "sha512-Qe+vWsuVHFzUkdChwlmJGuQf9cA3I+QOsSHULV/6qf6wsqLM2/32svNRH+rbBIMwiPEwzZprZlkvkqQRucYnVA==",
"dependencies": {
"@lit/reactive-element": "^1.0.0",
"@open-wc/dedupe-mixin": "^1.3.0"
"@open-wc/dedupe-mixin": "^1.4.0"
}
},
"node_modules/@open-wc/semantic-dom-diff": {
@@ -1782,9 +1781,9 @@
}
},
"node_modules/@shoelace-style/localize": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@shoelace-style/localize/-/localize-3.1.0.tgz",
"integrity": "sha512-evGxn5wIQh1/Ks1RbZm7rY4DxPKAUnXKTixZNgnYV/N2V8Bbbvsi+S14gNa42SQNUJK5WooNtlar2B8cehEwZQ=="
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@shoelace-style/localize/-/localize-3.1.1.tgz",
"integrity": "sha512-NkM/hj3Js6yXCU9WxhsyxRUdyqUUUl/BSvIluUMptQteUWGOJaoyP1iMbOMqO544DYMzBfnoCw66ZHkGuTdKgA=="
},
"node_modules/@sindresorhus/is": {
"version": "0.7.0",
@@ -6794,9 +6793,9 @@
}
},
"node_modules/esbuild": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.17.tgz",
"integrity": "sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.2.tgz",
"integrity": "sha512-1P4sK9gXVcjvrrUjE94Hbo9goU+T6U1sdzLf+JJ+3uI6GEb4e4n3Wrqto9hZHUWabblpT2ifmC61LhZnLyTNFw==",
"dev": true,
"hasInstallScript": true,
"bin": {
@@ -6806,28 +6805,28 @@
"node": ">=12"
},
"optionalDependencies": {
"@esbuild/android-arm": "0.16.17",
"@esbuild/android-arm64": "0.16.17",
"@esbuild/android-x64": "0.16.17",
"@esbuild/darwin-arm64": "0.16.17",
"@esbuild/darwin-x64": "0.16.17",
"@esbuild/freebsd-arm64": "0.16.17",
"@esbuild/freebsd-x64": "0.16.17",
"@esbuild/linux-arm": "0.16.17",
"@esbuild/linux-arm64": "0.16.17",
"@esbuild/linux-ia32": "0.16.17",
"@esbuild/linux-loong64": "0.16.17",
"@esbuild/linux-mips64el": "0.16.17",
"@esbuild/linux-ppc64": "0.16.17",
"@esbuild/linux-riscv64": "0.16.17",
"@esbuild/linux-s390x": "0.16.17",
"@esbuild/linux-x64": "0.16.17",
"@esbuild/netbsd-x64": "0.16.17",
"@esbuild/openbsd-x64": "0.16.17",
"@esbuild/sunos-x64": "0.16.17",
"@esbuild/win32-arm64": "0.16.17",
"@esbuild/win32-ia32": "0.16.17",
"@esbuild/win32-x64": "0.16.17"
"@esbuild/android-arm": "0.18.2",
"@esbuild/android-arm64": "0.18.2",
"@esbuild/android-x64": "0.18.2",
"@esbuild/darwin-arm64": "0.18.2",
"@esbuild/darwin-x64": "0.18.2",
"@esbuild/freebsd-arm64": "0.18.2",
"@esbuild/freebsd-x64": "0.18.2",
"@esbuild/linux-arm": "0.18.2",
"@esbuild/linux-arm64": "0.18.2",
"@esbuild/linux-ia32": "0.18.2",
"@esbuild/linux-loong64": "0.18.2",
"@esbuild/linux-mips64el": "0.18.2",
"@esbuild/linux-ppc64": "0.18.2",
"@esbuild/linux-riscv64": "0.18.2",
"@esbuild/linux-s390x": "0.18.2",
"@esbuild/linux-x64": "0.18.2",
"@esbuild/netbsd-x64": "0.18.2",
"@esbuild/openbsd-x64": "0.18.2",
"@esbuild/sunos-x64": "0.18.2",
"@esbuild/win32-arm64": "0.18.2",
"@esbuild/win32-ia32": "0.18.2",
"@esbuild/win32-x64": "0.18.2"
}
},
"node_modules/escalade": {
@@ -10847,28 +10846,29 @@
}
},
"node_modules/lit": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/lit/-/lit-2.6.1.tgz",
"integrity": "sha512-DT87LD64f8acR7uVp7kZfhLRrHkfC/N4BVzAtnw9Yg8087mbBJ//qedwdwX0kzDbxgPccWRW6mFwGbRQIxy0pw==",
"version": "2.7.5",
"resolved": "https://registry.npmjs.org/lit/-/lit-2.7.5.tgz",
"integrity": "sha512-i/cH7Ye6nBDUASMnfwcictBnsTN91+aBjXoTHF2xARghXScKxpD4F4WYI+VLXg9lqbMinDfvoI7VnZXjyHgdfQ==",
"dependencies": {
"@lit/reactive-element": "^1.6.0",
"lit-element": "^3.2.0",
"lit-html": "^2.6.0"
"lit-element": "^3.3.0",
"lit-html": "^2.7.0"
}
},
"node_modules/lit-element": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.2.0.tgz",
"integrity": "sha512-HbE7yt2SnUtg5DCrWt028oaU4D5F4k/1cntAFHTkzY8ZIa8N0Wmu92PxSxucsQSOXlODFrICkQ5x/tEshKi13g==",
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.2.tgz",
"integrity": "sha512-xXAeVWKGr4/njq0rGC9dethMnYCq5hpKYrgQZYTzawt9YQhMiXfD+T1RgrdY3NamOxwq2aXlb0vOI6e29CKgVQ==",
"dependencies": {
"@lit-labs/ssr-dom-shim": "^1.1.0",
"@lit/reactive-element": "^1.3.0",
"lit-html": "^2.2.0"
"lit-html": "^2.7.0"
}
},
"node_modules/lit-html": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.6.1.tgz",
"integrity": "sha512-Z3iw+E+3KKFn9t2YKNjsXNEu/LRLI98mtH/C6lnFg7kvaqPIzPn124Yd4eT/43lyqrejpc5Wb6BHq3fdv4S8Rw==",
"version": "2.7.4",
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.7.4.tgz",
"integrity": "sha512-/Jw+FBpeEN+z8X6PJva5n7+0MzCVAH2yypN99qHYYkq8bI+j7I39GH+68Z/MZD6rGKDK9RpzBw7CocfmHfq6+g==",
"dependencies": {
"@types/trusted-types": "^2.0.2"
}
@@ -16259,16 +16259,16 @@
}
},
"node_modules/typescript": {
"version": "4.9.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz",
"integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==",
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz",
"integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
"node": ">=14.17"
}
},
"node_modules/typical": {
@@ -17941,156 +17941,156 @@
}
},
"@esbuild/android-arm": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.17.tgz",
"integrity": "sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.2.tgz",
"integrity": "sha512-YAnQBHlY0IvYtvY0avnXjI8ywW23emEjk5XExqbFmypath+Snq9MgY1IS47rnqBKVSqnl0ElDt221ZgaeRrkXg==",
"dev": true,
"optional": true
},
"@esbuild/android-arm64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz",
"integrity": "sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.2.tgz",
"integrity": "sha512-1Y2pb0hLdmji8I0zBwNsYSDN7zJSQqufgLOuOsrrod00WEAgKywQR5MB/E046Is/YTP4bgcPS4BioaSDBaLaTg==",
"dev": true,
"optional": true
},
"@esbuild/android-x64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.16.17.tgz",
"integrity": "sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.2.tgz",
"integrity": "sha512-P047Mh3pj8uYVE3A/B3QDX6nG8dKbHLJ+48R6Y0CRXCJ5PkXJxdHOTaS8SYs6eSR3FFU6/YQ5TishQXVHX7F5A==",
"dev": true,
"optional": true
},
"@esbuild/darwin-arm64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.16.17.tgz",
"integrity": "sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.2.tgz",
"integrity": "sha512-a3Rkqd0tGVYMEKNy9SstWEdeBmM60l8FVD5o4rmwHr3xO1LbLqtCJSrWGbnf37hevo6m437mURVmpEHOmkXeTA==",
"dev": true,
"optional": true
},
"@esbuild/darwin-x64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz",
"integrity": "sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.2.tgz",
"integrity": "sha512-cvH58adz9L10JNsIcgtkWNS/1eutjRTi3rtWz1s3ZhR64BpdmkxJBAXE/UjqybyNAWLhaN8mPJdlYI2f+tQA7g==",
"dev": true,
"optional": true
},
"@esbuild/freebsd-arm64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.17.tgz",
"integrity": "sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.2.tgz",
"integrity": "sha512-68rGMGUdgmq+c5IvseCMqY4yaa2CAY/DIILMBA6bEU1caISF7fXnV69B1uU4s3ERuVDcasVVwiAFyNxCtkS6Zg==",
"dev": true,
"optional": true
},
"@esbuild/freebsd-x64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.16.17.tgz",
"integrity": "sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.2.tgz",
"integrity": "sha512-ZSR9On/rXoYuAtrXo5hYKy7OuZwKZyFh2rr6L3TX4UeR1tWLf84aLyAFt7e0tlRbh4zNgqFx+ePWmsSHw7L9Bw==",
"dev": true,
"optional": true
},
"@esbuild/linux-arm": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.16.17.tgz",
"integrity": "sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.2.tgz",
"integrity": "sha512-jAbA75qJ70T5AOdmw9X8675ppeRfj7j57sOypoZ4mQlfQ/LKF8eoeLzTYVo8+aqLKqeIIl0vQ4hKOB0FyG98Zg==",
"dev": true,
"optional": true
},
"@esbuild/linux-arm64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.16.17.tgz",
"integrity": "sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.2.tgz",
"integrity": "sha512-DFKavAzbu/n9HXWuetxmYN10XnfzW7FgOgpcrGD8eXaiu77KdgB+OVWA83x9FtDYtsoFpfdlDuVFAQFfrhu77A==",
"dev": true,
"optional": true
},
"@esbuild/linux-ia32": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.16.17.tgz",
"integrity": "sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.2.tgz",
"integrity": "sha512-VEaK3Z+vJyDwwPsP0sovaEw1foDzrMs7XQNYEIFkOwMjSe2BipKRKUUyrznil0p8qqsK7U8W+T7oNqZpgdnD2Q==",
"dev": true,
"optional": true
},
"@esbuild/linux-loong64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.16.17.tgz",
"integrity": "sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.2.tgz",
"integrity": "sha512-Af1uZdB0oeJo4PW67l9aw94oakSamFxhC6ltC2eDkndozd9QygVNMTF7s7uxTLjo+BJqyVqG9wjmLCYF1o4NmA==",
"dev": true,
"optional": true
},
"@esbuild/linux-mips64el": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.16.17.tgz",
"integrity": "sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.2.tgz",
"integrity": "sha512-WcTbt61+9dREuOFKXac4Qg+3OuRhLxPL9lmkI2P7fGuq/fWS2qq+AvGGVLMyk+OtXGDjyQolcEDeYlRoOmjRYQ==",
"dev": true,
"optional": true
},
"@esbuild/linux-ppc64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.16.17.tgz",
"integrity": "sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.2.tgz",
"integrity": "sha512-Ov+VHayvCPb52axma6+xm8QDawRjwHscPXedHg4U92DxlhKQ0H+6onRiC3J9kKI50p8pKKypprpCWrRrXjZN7Q==",
"dev": true,
"optional": true
},
"@esbuild/linux-riscv64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.16.17.tgz",
"integrity": "sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.2.tgz",
"integrity": "sha512-qW37zzKKN9C5l5LnVDriOK0eZRzQeixhtrfd5C78PAsTE15GeHU9G0oyT/u/IkNjEBjXWpTZOOHKNbjhrvuL9g==",
"dev": true,
"optional": true
},
"@esbuild/linux-s390x": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.16.17.tgz",
"integrity": "sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.2.tgz",
"integrity": "sha512-izzEFMRO8LaQIlX22+fTgP5I7Os3T51mtAWsRNpZ5pMfQIa9PqtgFAoRcb10DV+/YkH/TMMxQIlevUvDS6E4vw==",
"dev": true,
"optional": true
},
"@esbuild/linux-x64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.16.17.tgz",
"integrity": "sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.2.tgz",
"integrity": "sha512-y5yqQ1ww4FfI9bQ1ZP/0k1rcgA6Ql2/AgzvqpowN0Q5tXDZkCavPdJbFXKrqA43vd1UTXt+AutTHYJ7km6e2Eg==",
"dev": true,
"optional": true
},
"@esbuild/netbsd-x64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.16.17.tgz",
"integrity": "sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.2.tgz",
"integrity": "sha512-usNjpKFf83X4o60gdMD47NCblaSZ6DARf31/FyCzxOgnF80mJ+RhDs9RTqgyfH8KyduO5mjgInw9+ct286ayYA==",
"dev": true,
"optional": true
},
"@esbuild/openbsd-x64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.16.17.tgz",
"integrity": "sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.2.tgz",
"integrity": "sha512-6urzy1+VwcPuhG+5jwHA8lD9E87E5+ey3qKw2EhRS+qUmMxLvfwP8szWC2JHVGZDPEDge6fgn0pBj+y9rxDLwQ==",
"dev": true,
"optional": true
},
"@esbuild/sunos-x64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.16.17.tgz",
"integrity": "sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.2.tgz",
"integrity": "sha512-SMZPTACsvpKYAIl9o8nhnmMn6/lp62iMeV/2EBMtj+sW6dXwW9b0cLjihkBv4PG1CCRlwWKPZo43imqZxC95ZA==",
"dev": true,
"optional": true
},
"@esbuild/win32-arm64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.16.17.tgz",
"integrity": "sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.2.tgz",
"integrity": "sha512-H2zzjPdzSDNwUnZdZf9/xfm0CYqHFXuenCMAx+tRzIRqWUT6MmZ9/q7722KnAZ6uPpq0RLs7EjCIIfmt6CaRGg==",
"dev": true,
"optional": true
},
"@esbuild/win32-ia32": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.16.17.tgz",
"integrity": "sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.2.tgz",
"integrity": "sha512-lfyjTN+FrKgvNvrH7nOLtaz58J/8coZOo4LQwgBMP4D7ZOurhvluXS3GjePLzq9GbWnJDZdKCKbMKhZPPcdJJA==",
"dev": true,
"optional": true
},
"@esbuild/win32-x64": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz",
"integrity": "sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.2.tgz",
"integrity": "sha512-Q4nIjqWXjxkELwd7kVepsJxbQ/6ERNsHpjz1j+IKjwSYw+g06U0RQOy5xh848AHvgr9itnGLa3cT2G5t0dBFsw==",
"dev": true,
"optional": true
},
@@ -18202,9 +18202,9 @@
"integrity": "sha512-9TC+/ZWb6BJlWCyUr14FKFlaGnyKpeEDorufXozQgke/VoVrslUQNaL7nBmrAWdNrmzx5jWgi8lFmWwrxMjnlA=="
},
"@lit-labs/ssr-dom-shim": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.0.0.tgz",
"integrity": "sha512-ic93MBXfApIFTrup4a70M/+ddD8xdt2zxxj9sRwHQzhS9ag/syqkD8JPdTXsc1gUy2K8TTirhlCqyTEM/sifNw=="
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.1.1.tgz",
"integrity": "sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ=="
},
"@lit/reactive-element": {
"version": "1.6.1",
@@ -18378,19 +18378,17 @@
}
},
"@open-wc/dedupe-mixin": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@open-wc/dedupe-mixin/-/dedupe-mixin-1.3.1.tgz",
"integrity": "sha512-ukowSvzpZQDUH0Y3znJTsY88HkiGk3Khc0WGpIPhap1xlerieYi27QBg6wx/nTurpWfU6XXXsx9ocxDYCdtw0Q==",
"dev": true
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@open-wc/dedupe-mixin/-/dedupe-mixin-1.4.0.tgz",
"integrity": "sha512-Sj7gKl1TLcDbF7B6KUhtvr+1UCxdhMbNY5KxdU5IfMFWqL8oy1ZeAcCANjoB1TL0AJTcPmcCFsCbHf8X2jGDUA=="
},
"@open-wc/scoped-elements": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/@open-wc/scoped-elements/-/scoped-elements-2.1.3.tgz",
"integrity": "sha512-WoQD5T8Me9obek+iyjgrAMw9wxZZg4ytIteIN1i9LXW2KohezUp0LTOlWgBajWJo0/bpjUKiODX73cMYL2i3hw==",
"dev": true,
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@open-wc/scoped-elements/-/scoped-elements-2.2.0.tgz",
"integrity": "sha512-Qe+vWsuVHFzUkdChwlmJGuQf9cA3I+QOsSHULV/6qf6wsqLM2/32svNRH+rbBIMwiPEwzZprZlkvkqQRucYnVA==",
"requires": {
"@lit/reactive-element": "^1.0.0",
"@open-wc/dedupe-mixin": "^1.3.0"
"@open-wc/dedupe-mixin": "^1.4.0"
}
},
"@open-wc/semantic-dom-diff": {
@@ -18480,9 +18478,9 @@
"integrity": "sha512-Be+cahtZyI2dPKRm8EZSx3YJQ+jLvEcn3xzRP7tM4tqBnvd/eW/64Xh0iOf0t2w5P8iJKfdBbpVNE9naCaOf2g=="
},
"@shoelace-style/localize": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@shoelace-style/localize/-/localize-3.1.0.tgz",
"integrity": "sha512-evGxn5wIQh1/Ks1RbZm7rY4DxPKAUnXKTixZNgnYV/N2V8Bbbvsi+S14gNa42SQNUJK5WooNtlar2B8cehEwZQ=="
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@shoelace-style/localize/-/localize-3.1.1.tgz",
"integrity": "sha512-NkM/hj3Js6yXCU9WxhsyxRUdyqUUUl/BSvIluUMptQteUWGOJaoyP1iMbOMqO544DYMzBfnoCw66ZHkGuTdKgA=="
},
"@sindresorhus/is": {
"version": "0.7.0",
@@ -22311,33 +22309,33 @@
}
},
"esbuild": {
"version": "0.16.17",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.17.tgz",
"integrity": "sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==",
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.2.tgz",
"integrity": "sha512-1P4sK9gXVcjvrrUjE94Hbo9goU+T6U1sdzLf+JJ+3uI6GEb4e4n3Wrqto9hZHUWabblpT2ifmC61LhZnLyTNFw==",
"dev": true,
"requires": {
"@esbuild/android-arm": "0.16.17",
"@esbuild/android-arm64": "0.16.17",
"@esbuild/android-x64": "0.16.17",
"@esbuild/darwin-arm64": "0.16.17",
"@esbuild/darwin-x64": "0.16.17",
"@esbuild/freebsd-arm64": "0.16.17",
"@esbuild/freebsd-x64": "0.16.17",
"@esbuild/linux-arm": "0.16.17",
"@esbuild/linux-arm64": "0.16.17",
"@esbuild/linux-ia32": "0.16.17",
"@esbuild/linux-loong64": "0.16.17",
"@esbuild/linux-mips64el": "0.16.17",
"@esbuild/linux-ppc64": "0.16.17",
"@esbuild/linux-riscv64": "0.16.17",
"@esbuild/linux-s390x": "0.16.17",
"@esbuild/linux-x64": "0.16.17",
"@esbuild/netbsd-x64": "0.16.17",
"@esbuild/openbsd-x64": "0.16.17",
"@esbuild/sunos-x64": "0.16.17",
"@esbuild/win32-arm64": "0.16.17",
"@esbuild/win32-ia32": "0.16.17",
"@esbuild/win32-x64": "0.16.17"
"@esbuild/android-arm": "0.18.2",
"@esbuild/android-arm64": "0.18.2",
"@esbuild/android-x64": "0.18.2",
"@esbuild/darwin-arm64": "0.18.2",
"@esbuild/darwin-x64": "0.18.2",
"@esbuild/freebsd-arm64": "0.18.2",
"@esbuild/freebsd-x64": "0.18.2",
"@esbuild/linux-arm": "0.18.2",
"@esbuild/linux-arm64": "0.18.2",
"@esbuild/linux-ia32": "0.18.2",
"@esbuild/linux-loong64": "0.18.2",
"@esbuild/linux-mips64el": "0.18.2",
"@esbuild/linux-ppc64": "0.18.2",
"@esbuild/linux-riscv64": "0.18.2",
"@esbuild/linux-s390x": "0.18.2",
"@esbuild/linux-x64": "0.18.2",
"@esbuild/netbsd-x64": "0.18.2",
"@esbuild/openbsd-x64": "0.18.2",
"@esbuild/sunos-x64": "0.18.2",
"@esbuild/win32-arm64": "0.18.2",
"@esbuild/win32-ia32": "0.18.2",
"@esbuild/win32-x64": "0.18.2"
}
},
"escalade": {
@@ -25337,28 +25335,29 @@
}
},
"lit": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/lit/-/lit-2.6.1.tgz",
"integrity": "sha512-DT87LD64f8acR7uVp7kZfhLRrHkfC/N4BVzAtnw9Yg8087mbBJ//qedwdwX0kzDbxgPccWRW6mFwGbRQIxy0pw==",
"version": "2.7.5",
"resolved": "https://registry.npmjs.org/lit/-/lit-2.7.5.tgz",
"integrity": "sha512-i/cH7Ye6nBDUASMnfwcictBnsTN91+aBjXoTHF2xARghXScKxpD4F4WYI+VLXg9lqbMinDfvoI7VnZXjyHgdfQ==",
"requires": {
"@lit/reactive-element": "^1.6.0",
"lit-element": "^3.2.0",
"lit-html": "^2.6.0"
"lit-element": "^3.3.0",
"lit-html": "^2.7.0"
}
},
"lit-element": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.2.0.tgz",
"integrity": "sha512-HbE7yt2SnUtg5DCrWt028oaU4D5F4k/1cntAFHTkzY8ZIa8N0Wmu92PxSxucsQSOXlODFrICkQ5x/tEshKi13g==",
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.2.tgz",
"integrity": "sha512-xXAeVWKGr4/njq0rGC9dethMnYCq5hpKYrgQZYTzawt9YQhMiXfD+T1RgrdY3NamOxwq2aXlb0vOI6e29CKgVQ==",
"requires": {
"@lit-labs/ssr-dom-shim": "^1.1.0",
"@lit/reactive-element": "^1.3.0",
"lit-html": "^2.2.0"
"lit-html": "^2.7.0"
}
},
"lit-html": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.6.1.tgz",
"integrity": "sha512-Z3iw+E+3KKFn9t2YKNjsXNEu/LRLI98mtH/C6lnFg7kvaqPIzPn124Yd4eT/43lyqrejpc5Wb6BHq3fdv4S8Rw==",
"version": "2.7.4",
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.7.4.tgz",
"integrity": "sha512-/Jw+FBpeEN+z8X6PJva5n7+0MzCVAH2yypN99qHYYkq8bI+j7I39GH+68Z/MZD6rGKDK9RpzBw7CocfmHfq6+g==",
"requires": {
"@types/trusted-types": "^2.0.2"
}
@@ -29549,9 +29548,9 @@
}
},
"typescript": {
"version": "4.9.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz",
"integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==",
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz",
"integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==",
"dev": true
},
"typical": {

View File

@@ -23,7 +23,8 @@
"./dist/translations/*": "./dist/translations/*"
},
"files": [
"dist"
"dist",
"cdn"
],
"keywords": [
"web components",
@@ -42,8 +43,8 @@
"url": "https://github.com/sponsors/claviska"
},
"scripts": {
"start": "node scripts/build.js --bundle --serve",
"build": "node scripts/build.js --bundle --types --copydir \"_site/dist\"",
"start": "node scripts/build.js --serve",
"build": "node scripts/build.js",
"verify": "npm run prettier:check && npm run lint && npm run build && npm run test",
"prepublishOnly": "npm run verify",
"prettier": "prettier --write --loglevel warn .",
@@ -66,10 +67,11 @@
"@ctrl/tinycolor": "^3.5.0",
"@floating-ui/dom": "^1.2.1",
"@lit-labs/react": "^1.1.1",
"@open-wc/scoped-elements": "^2.2.0",
"@shoelace-style/animations": "^1.1.0",
"@shoelace-style/localize": "^3.1.0",
"@shoelace-style/localize": "^3.1.1",
"composed-offset-position": "^0.0.4",
"lit": "^2.6.1",
"lit": "^2.7.5",
"qr-creator": "^1.0.0"
},
"devDependencies": {
@@ -94,7 +96,7 @@
"cspell": "^6.18.1",
"del": "^7.0.0",
"download": "^8.0.0",
"esbuild": "^0.16.17",
"esbuild": "^0.18.2",
"eslint": "^8.31.0",
"eslint-plugin-chai-expect": "^3.0.0",
"eslint-plugin-chai-friendly": "^0.7.2",
@@ -130,7 +132,7 @@
"source-map": "^0.7.4",
"strip-css-comments": "^5.0.0",
"tslib": "^2.4.1",
"typescript": "4.9.4",
"typescript": "^5.1.3",
"user-agent-data-types": "^0.3.0"
},
"lint-staged": {

View File

@@ -10,19 +10,18 @@ import fs from 'fs/promises';
import getPort, { portNumbers } from 'get-port';
import ora from 'ora';
import util from 'util';
import * as path from 'path';
const { bundle, copydir, dir, serve, types } = commandLineArgs([
{ name: 'bundle', type: Boolean },
{ name: 'copydir', type: String },
{ name: 'serve', type: Boolean },
{ name: 'types', type: Boolean }
]);
const { serve } = commandLineArgs([{ name: 'serve', type: Boolean }]);
const outdir = 'dist';
const cdndir = 'cdn';
const sitedir = '_site';
const spinner = ora({ hideCursor: false }).start();
const execPromise = util.promisify(exec);
let childProcess;
let buildResult;
let buildResults;
const bundleDirectories = [cdndir, outdir];
//
// Runs 11ty and builds the docs. The returned promise resolves after the initial publish has completed. The child
@@ -71,8 +70,13 @@ async function buildTheDocs(watch = false) {
//
async function buildTheSource() {
const alwaysExternal = ['@lit-labs/react', 'react'];
const packageJSON = await fs.readFile('./package.json');
const dependencies = [
...Object.keys(packageJSON.dependencies || {}),
...Object.keys(packageJSON.peerDependencies || {})
];
return await esbuild.build({
const cdnConfig = {
format: 'esm',
target: 'es2017',
entryPoints: [
@@ -94,9 +98,8 @@ async function buildTheSource() {
// React wrappers
...(await globby('./src/react/**/*.ts'))
],
outdir,
outdir: cdndir,
chunkNames: 'chunks/[name].[hash]',
incremental: serve,
define: {
// Floating UI requires this to be set
'process.env.NODE_ENV': '"production"'
@@ -108,19 +111,34 @@ async function buildTheSource() {
//
// We never bundle React or @lit-labs/react though!
//
external: bundle
? alwaysExternal
: [...alwaysExternal, '@floating-ui/dom', '@shoelace-style/animations', 'lit', 'qr-creator'],
external: alwaysExternal,
splitting: true,
plugins: []
});
};
const npmConfig = {
...cdnConfig,
bundle: false,
external: undefined,
outdir
};
if (serve) {
// Use the context API to allow incremental dev builds
const contexts = await Promise.all([esbuild.context(cdnConfig), esbuild.context(npmConfig)]);
await Promise.all(contexts.map(context => context.rebuild()));
return contexts;
} else {
// Use the standard API for production builds
return await Promise.all([esbuild.build(cdnConfig), esbuild.build(npmConfig)]);
}
}
//
// Called on SIGINT or SIGTERM to cleanup the build and child processes.
//
function handleCleanup() {
buildResult.rebuild.dispose();
buildResults.forEach(result => result.dispose());
if (childProcess) {
childProcess.kill('SIGINT');
@@ -150,12 +168,16 @@ async function nextTask(label, action) {
}
await nextTask('Cleaning up the previous build', async () => {
await Promise.all([deleteAsync(outdir), deleteAsync(sitedir)]);
await Promise.all([deleteAsync(sitedir), ...bundleDirectories.map(dir => deleteAsync(dir))]);
await fs.mkdir(outdir, { recursive: true });
});
await nextTask('Generating component metadata', () => {
return execPromise(`node scripts/make-metadata.js --outdir "${outdir}"`, { stdio: 'inherit' });
return Promise.all(
bundleDirectories.map(dir => {
return execPromise(`node scripts/make-metadata.js --outdir "${dir}"`, { stdio: 'inherit' });
})
);
});
await nextTask('Wrapping components for React', () => {
@@ -178,15 +200,23 @@ await nextTask('Running the TypeScript compiler', () => {
return execPromise(`tsc --project ./tsconfig.prod.json --outdir "${outdir}"`, { stdio: 'inherit' });
});
await nextTask('Building source files', async () => {
buildResult = await buildTheSource();
// Copy the above steps to the CDN directory directly so we don't need to twice the work for nothing.
await nextTask(`Copying Web Types, Themes, Icons, and TS Types to "${cdndir}"`, async () => {
await deleteAsync(cdndir);
await copy(outdir, cdndir);
});
if (copydir) {
// Copy the build output to an additional directory
await nextTask(`Copying the build to "${copydir}"`, async () => {
await deleteAsync(copydir);
await copy(outdir, copydir);
await nextTask('Building source files', async () => {
buildResults = await buildTheSource();
});
// Copy the CDN build to the docs (prod only; we use a virtual directory in dev)
if (!serve) {
await nextTask(`Copying the build to "${sitedir}"`, async () => {
await deleteAsync(sitedir);
// We copy the CDN build because that has everything bundled.
await copy(cdndir, path.join(sitedir, 'cdn'));
});
}
@@ -215,7 +245,7 @@ if (serve) {
server: {
baseDir: sitedir,
routes: {
'/dist': './dist'
'/cdn': './cdn'
}
}
};
@@ -243,16 +273,24 @@ if (serve) {
const isStylesheet = /(\.css|\.styles\.ts)$/.test(filename);
// Rebuild the source
await buildResult.rebuild();
await Promise.all([buildResults.map(result => result.rebuild())]);
// Rebuild stylesheets when a theme file changes
if (isTheme) {
await execPromise(`node scripts/make-themes.js --outdir "${outdir}"`, { stdio: 'inherit' });
await Promise.all(
bundleDirectories.map(dir => {
execPromise(`node scripts/make-themes.js --outdir "${dir}"`, { stdio: 'inherit' });
})
);
}
// Rebuild metadata (but not when styles are changed)
if (!isStylesheet) {
await execPromise(`node scripts/make-metadata.js --outdir "${outdir}"`, { stdio: 'inherit' });
await Promise.all(
bundleDirectories.map(dir => {
return execPromise(`node scripts/make-metadata.js --outdir "${dir}"`, { stdio: 'inherit' });
})
);
}
bs.reload();

View File

@@ -23,7 +23,7 @@ const url = `https://github.com/twbs/icons/archive/v${version}.zip`;
try {
await fs.stat(`${srcPath}/LICENSE.md`);
} catch {
// Download the source from GitHub (since not everything is published to NPM)
// Download the source from GitHub (since not everything is published to npm)
await download(url, './.cache/icons', { extract: true });
}

View File

@@ -0,0 +1,248 @@
import { animateTo, stopAnimations } from '../../internal/animate';
import { classMap } from 'lit/directives/class-map.js';
import { getAnimation, setDefaultAnimation } from '../../utilities/animation-registry';
import { HasSlotController } from '../../internal/slot';
import { html } from 'lit';
import { LocalizeController } from '../../utilities/localize';
import { property, query } from 'lit/decorators.js';
import { waitForEvent } from '../../internal/event';
import { watch } from '../../internal/watch';
import ShoelaceElement from '../../internal/shoelace-element';
import SlIconButton from '../icon-button/icon-button';
import styles from './alert.styles';
import type { CSSResultGroup } from 'lit';
const toastStack = Object.assign(document.createElement('div'), { className: 'sl-toast-stack' });
/**
* @summary Alerts are used to display important messages inline or as toast notifications.
* @documentation https://shoelace.style/components/alert
* @status stable
* @since 2.0
*
* @dependency sl-icon-button
*
* @slot - The alert's main content.
* @slot icon - An icon to show in the alert. Works best with `<sl-icon>`.
*
* @event sl-show - Emitted when the alert opens.
* @event sl-after-show - Emitted after the alert opens and all animations are complete.
* @event sl-hide - Emitted when the alert closes.
* @event sl-after-hide - Emitted after the alert closes and all animations are complete.
*
* @csspart base - The component's base wrapper.
* @csspart icon - The container that wraps the optional icon.
* @csspart message - The container that wraps the alert's main content.
* @csspart close-button - The close button, an `<sl-icon-button>`.
* @csspart close-button__base - The close button's exported `base` part.
*
* @animation alert.show - The animation to use when showing the alert.
* @animation alert.hide - The animation to use when hiding the alert.
*/
export default class SlAlert extends ShoelaceElement {
static styles: CSSResultGroup = styles;
static get scopedElements() {
return {
'sl-icon-button': SlIconButton
};
}
private autoHideTimeout: number;
private readonly hasSlotController = new HasSlotController(this, 'icon', 'suffix');
private readonly localize = new LocalizeController(this);
@query('[part~="base"]') base: HTMLElement;
/**
* Indicates whether or not the alert is open. You can toggle this attribute to show and hide the alert, or you can
* use the `show()` and `hide()` methods and this attribute will reflect the alert's open state.
*/
@property({ type: Boolean, reflect: true }) open = false;
/** Enables a close button that allows the user to dismiss the alert. */
@property({ type: Boolean, reflect: true }) closable = false;
/** The alert's theme variant. */
@property({ reflect: true }) variant: 'primary' | 'success' | 'neutral' | 'warning' | 'danger' = 'primary';
/**
* The length of time, in milliseconds, the alert will show before closing itself. If the user interacts with
* the alert before it closes (e.g. moves the mouse over it), the timer will restart. Defaults to `Infinity`, meaning
* the alert will not close on its own.
*/
@property({ type: Number }) duration = Infinity;
firstUpdated() {
this.base.hidden = !this.open;
}
private restartAutoHide() {
clearTimeout(this.autoHideTimeout);
if (this.open && this.duration < Infinity) {
this.autoHideTimeout = window.setTimeout(() => this.hide(), this.duration);
}
}
private handleCloseClick() {
this.hide();
}
private handleMouseMove() {
this.restartAutoHide();
}
@watch('open', { waitUntilFirstUpdate: true })
async handleOpenChange() {
if (this.open) {
// Show
this.emit('sl-show');
if (this.duration < Infinity) {
this.restartAutoHide();
}
await stopAnimations(this.base);
this.base.hidden = false;
const { keyframes, options } = getAnimation(this, 'alert.show', { dir: this.localize.dir() });
await animateTo(this.base, keyframes, options);
this.emit('sl-after-show');
} else {
// Hide
this.emit('sl-hide');
clearTimeout(this.autoHideTimeout);
await stopAnimations(this.base);
const { keyframes, options } = getAnimation(this, 'alert.hide', { dir: this.localize.dir() });
await animateTo(this.base, keyframes, options);
this.base.hidden = true;
this.emit('sl-after-hide');
}
}
@watch('duration')
handleDurationChange() {
this.restartAutoHide();
}
/** Shows the alert. */
async show() {
if (this.open) {
return undefined;
}
this.open = true;
return waitForEvent(this, 'sl-after-show');
}
/** Hides the alert */
async hide() {
if (!this.open) {
return undefined;
}
this.open = false;
return waitForEvent(this, 'sl-after-hide');
}
/**
* Displays the alert as a toast notification. This will move the alert out of its position in the DOM and, when
* dismissed, it will be removed from the DOM completely. By storing a reference to the alert, you can reuse it by
* calling this method again. The returned promise will resolve after the alert is hidden.
*/
async toast() {
return new Promise<void>(resolve => {
if (toastStack.parentElement === null) {
document.body.append(toastStack);
}
toastStack.appendChild(this);
// Wait for the toast stack to render
requestAnimationFrame(() => {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- force a reflow for the initial transition
this.clientWidth;
this.show();
});
this.addEventListener(
'sl-after-hide',
() => {
toastStack.removeChild(this);
resolve();
// Remove the toast stack from the DOM when there are no more alerts
if (toastStack.querySelector('sl-alert') === null) {
toastStack.remove();
}
},
{ once: true }
);
});
}
render() {
return html`
<div
part="base"
class=${classMap({
alert: true,
'alert--open': this.open,
'alert--closable': this.closable,
'alert--has-icon': this.hasSlotController.test('icon'),
'alert--primary': this.variant === 'primary',
'alert--success': this.variant === 'success',
'alert--neutral': this.variant === 'neutral',
'alert--warning': this.variant === 'warning',
'alert--danger': this.variant === 'danger'
})}
role="alert"
aria-hidden=${this.open ? 'false' : 'true'}
@mousemove=${this.handleMouseMove}
>
<slot name="icon" part="icon" class="alert__icon"></slot>
<slot part="message" class="alert__message" aria-live="polite"></slot>
${this.closable
? html`
<sl-icon-button
part="close-button"
exportparts="base:close-button__base"
class="alert__close-button"
name="x-lg"
library="system"
label=${this.localize.term('close')}
@click=${this.handleCloseClick}
></sl-icon-button>
`
: ''}
</div>
`;
}
}
setDefaultAnimation('alert.show', {
keyframes: [
{ opacity: 0, scale: 0.8 },
{ opacity: 1, scale: 1 }
],
options: { duration: 250, easing: 'ease' }
});
setDefaultAnimation('alert.hide', {
keyframes: [
{ opacity: 1, scale: 1 },
{ opacity: 0, scale: 0.8 }
],
options: { duration: 250, easing: 'ease' }
});
declare global {
interface HTMLElementTagNameMap {
'sl-alert': SlAlert;
}
}

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { aTimeout, expect, fixture, html, oneEvent } from '@open-wc/testing';
import { clickOnElement, moveMouseOnElement } from '../../internal/test';
import { queryByTestId } from '../../internal/test/data-testid-helpers';

View File

@@ -1,244 +1,3 @@
import '../icon-button/icon-button';
import { animateTo, stopAnimations } from '../../internal/animate';
import { classMap } from 'lit/directives/class-map.js';
import { customElement, property, query } from 'lit/decorators.js';
import { getAnimation, setDefaultAnimation } from '../../utilities/animation-registry';
import { HasSlotController } from '../../internal/slot';
import { html } from 'lit';
import { LocalizeController } from '../../utilities/localize';
import { waitForEvent } from '../../internal/event';
import { watch } from '../../internal/watch';
import ShoelaceElement from '../../internal/shoelace-element';
import styles from './alert.styles';
import type { CSSResultGroup } from 'lit';
const toastStack = Object.assign(document.createElement('div'), { className: 'sl-toast-stack' });
/**
* @summary Alerts are used to display important messages inline or as toast notifications.
* @documentation https://shoelace.style/components/alert
* @status stable
* @since 2.0
*
* @dependency sl-icon-button
*
* @slot - The alert's main content.
* @slot icon - An icon to show in the alert. Works best with `<sl-icon>`.
*
* @event sl-show - Emitted when the alert opens.
* @event sl-after-show - Emitted after the alert opens and all animations are complete.
* @event sl-hide - Emitted when the alert closes.
* @event sl-after-hide - Emitted after the alert closes and all animations are complete.
*
* @csspart base - The component's base wrapper.
* @csspart icon - The container that wraps the optional icon.
* @csspart message - The container that wraps the alert's main content.
* @csspart close-button - The close button, an `<sl-icon-button>`.
* @csspart close-button__base - The close button's exported `base` part.
*
* @animation alert.show - The animation to use when showing the alert.
* @animation alert.hide - The animation to use when hiding the alert.
*/
@customElement('sl-alert')
export default class SlAlert extends ShoelaceElement {
static styles: CSSResultGroup = styles;
private autoHideTimeout: number;
private readonly hasSlotController = new HasSlotController(this, 'icon', 'suffix');
private readonly localize = new LocalizeController(this);
@query('[part~="base"]') base: HTMLElement;
/**
* Indicates whether or not the alert is open. You can toggle this attribute to show and hide the alert, or you can
* use the `show()` and `hide()` methods and this attribute will reflect the alert's open state.
*/
@property({ type: Boolean, reflect: true }) open = false;
/** Enables a close button that allows the user to dismiss the alert. */
@property({ type: Boolean, reflect: true }) closable = false;
/** The alert's theme variant. */
@property({ reflect: true }) variant: 'primary' | 'success' | 'neutral' | 'warning' | 'danger' = 'primary';
/**
* The length of time, in milliseconds, the alert will show before closing itself. If the user interacts with
* the alert before it closes (e.g. moves the mouse over it), the timer will restart. Defaults to `Infinity`, meaning
* the alert will not close on its own.
*/
@property({ type: Number }) duration = Infinity;
firstUpdated() {
this.base.hidden = !this.open;
}
private restartAutoHide() {
clearTimeout(this.autoHideTimeout);
if (this.open && this.duration < Infinity) {
this.autoHideTimeout = window.setTimeout(() => this.hide(), this.duration);
}
}
private handleCloseClick() {
this.hide();
}
private handleMouseMove() {
this.restartAutoHide();
}
@watch('open', { waitUntilFirstUpdate: true })
async handleOpenChange() {
if (this.open) {
// Show
this.emit('sl-show');
if (this.duration < Infinity) {
this.restartAutoHide();
}
await stopAnimations(this.base);
this.base.hidden = false;
const { keyframes, options } = getAnimation(this, 'alert.show', { dir: this.localize.dir() });
await animateTo(this.base, keyframes, options);
this.emit('sl-after-show');
} else {
// Hide
this.emit('sl-hide');
clearTimeout(this.autoHideTimeout);
await stopAnimations(this.base);
const { keyframes, options } = getAnimation(this, 'alert.hide', { dir: this.localize.dir() });
await animateTo(this.base, keyframes, options);
this.base.hidden = true;
this.emit('sl-after-hide');
}
}
@watch('duration')
handleDurationChange() {
this.restartAutoHide();
}
/** Shows the alert. */
async show() {
if (this.open) {
return undefined;
}
this.open = true;
return waitForEvent(this, 'sl-after-show');
}
/** Hides the alert */
async hide() {
if (!this.open) {
return undefined;
}
this.open = false;
return waitForEvent(this, 'sl-after-hide');
}
/**
* Displays the alert as a toast notification. This will move the alert out of its position in the DOM and, when
* dismissed, it will be removed from the DOM completely. By storing a reference to the alert, you can reuse it by
* calling this method again. The returned promise will resolve after the alert is hidden.
*/
async toast() {
return new Promise<void>(resolve => {
if (toastStack.parentElement === null) {
document.body.append(toastStack);
}
toastStack.appendChild(this);
// Wait for the toast stack to render
requestAnimationFrame(() => {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- force a reflow for the initial transition
this.clientWidth;
this.show();
});
this.addEventListener(
'sl-after-hide',
() => {
toastStack.removeChild(this);
resolve();
// Remove the toast stack from the DOM when there are no more alerts
if (toastStack.querySelector('sl-alert') === null) {
toastStack.remove();
}
},
{ once: true }
);
});
}
render() {
return html`
<div
part="base"
class=${classMap({
alert: true,
'alert--open': this.open,
'alert--closable': this.closable,
'alert--has-icon': this.hasSlotController.test('icon'),
'alert--primary': this.variant === 'primary',
'alert--success': this.variant === 'success',
'alert--neutral': this.variant === 'neutral',
'alert--warning': this.variant === 'warning',
'alert--danger': this.variant === 'danger'
})}
role="alert"
aria-hidden=${this.open ? 'false' : 'true'}
@mousemove=${this.handleMouseMove}
>
<slot name="icon" part="icon" class="alert__icon"></slot>
<slot part="message" class="alert__message" aria-live="polite"></slot>
${this.closable
? html`
<sl-icon-button
part="close-button"
exportparts="base:close-button__base"
class="alert__close-button"
name="x-lg"
library="system"
label=${this.localize.term('close')}
@click=${this.handleCloseClick}
></sl-icon-button>
`
: ''}
</div>
`;
}
}
setDefaultAnimation('alert.show', {
keyframes: [
{ opacity: 0, scale: 0.8 },
{ opacity: 1, scale: 1 }
],
options: { duration: 250, easing: 'ease' }
});
setDefaultAnimation('alert.hide', {
keyframes: [
{ opacity: 1, scale: 1 },
{ opacity: 0, scale: 0.8 }
],
options: { duration: 250, easing: 'ease' }
});
declare global {
interface HTMLElementTagNameMap {
'sl-alert': SlAlert;
}
}
import SlAlert from './alert.component';
export default SlAlert;
window.customElements.define('sl-alert', class extends SlAlert {});

View File

@@ -0,0 +1,124 @@
import { html } from 'lit';
import { property, query, state } from 'lit/decorators.js';
import { watch } from '../../internal/watch';
import ShoelaceElement from '../../internal/shoelace-element';
import SlIcon from '../icon/icon';
import styles from './animated-image.styles';
import type { CSSResultGroup } from 'lit';
/**
* @summary A component for displaying animated GIFs and WEBPs that play and pause on interaction.
* @documentation https://shoelace.style/components/animated-image
* @status stable
* @since 2.0
*
* @dependency sl-icon
*
* @event sl-load - Emitted when the image loads successfully.
* @event sl-error - Emitted when the image fails to load.
*
* @slot play-icon - Optional play icon to use instead of the default. Works best with `<sl-icon>`.
* @slot pause-icon - Optional pause icon to use instead of the default. Works best with `<sl-icon>`.
*
* @part - control-box - The container that surrounds the pause/play icons and provides their background.
*
* @cssproperty --control-box-size - The size of the icon box.
* @cssproperty --icon-size - The size of the play/pause icons.
*/
export default class SlAnimatedImage extends ShoelaceElement {
static styles: CSSResultGroup = styles;
static get scopedElements() {
return { 'sl-icon': SlIcon };
}
@query('.animated-image__animated') animatedImage: HTMLImageElement;
@state() frozenFrame: string;
@state() isLoaded = false;
/** The path to the image to load. */
@property() src: string;
/** A description of the image used by assistive devices. */
@property() alt: string;
/** Plays the animation. When this attribute is remove, the animation will pause. */
@property({ type: Boolean, reflect: true }) play: boolean;
private handleClick() {
this.play = !this.play;
}
private handleLoad() {
const canvas = document.createElement('canvas');
const { width, height } = this.animatedImage;
canvas.width = width;
canvas.height = height;
canvas.getContext('2d')!.drawImage(this.animatedImage, 0, 0, width, height);
this.frozenFrame = canvas.toDataURL('image/gif');
if (!this.isLoaded) {
this.emit('sl-load');
this.isLoaded = true;
}
}
private handleError() {
this.emit('sl-error');
}
@watch('play', { waitUntilFirstUpdate: true })
handlePlayChange() {
// When the animation starts playing, reset the src so it plays from the beginning. Since the src is cached, this
// won't trigger another request.
if (this.play) {
this.animatedImage.src = '';
this.animatedImage.src = this.src;
}
}
@watch('src')
handleSrcChange() {
this.isLoaded = false;
}
render() {
return html`
<div class="animated-image">
<img
class="animated-image__animated"
src=${this.src}
alt=${this.alt}
crossorigin="anonymous"
aria-hidden=${this.play ? 'false' : 'true'}
@click=${this.handleClick}
@load=${this.handleLoad}
@error=${this.handleError}
/>
${this.isLoaded
? html`
<img
class="animated-image__frozen"
src=${this.frozenFrame}
alt=${this.alt}
aria-hidden=${this.play ? 'true' : 'false'}
@click=${this.handleClick}
/>
<div part="control-box" class="animated-image__control-box">
<slot name="play-icon"><sl-icon name="play-fill" library="system"></sl-icon></slot>
<slot name="pause-icon"><sl-icon name="pause-fill" library="system"></sl-icon></slot>
</div>
`
: ''}
</div>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
'sl-animated-image': SlAnimatedImage;
}
}

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { clickOnElement } from '../../internal/test';
import { expect, fixture, html, oneEvent } from '@open-wc/testing';
import type SlAnimatedImage from './animated-image';

View File

@@ -1,122 +1,3 @@
import '../icon/icon';
import { customElement, property, query, state } from 'lit/decorators.js';
import { html } from 'lit';
import { watch } from '../../internal/watch';
import ShoelaceElement from '../../internal/shoelace-element';
import styles from './animated-image.styles';
import type { CSSResultGroup } from 'lit';
/**
* @summary A component for displaying animated GIFs and WEBPs that play and pause on interaction.
* @documentation https://shoelace.style/components/animated-image
* @status stable
* @since 2.0
*
* @dependency sl-icon
*
* @event sl-load - Emitted when the image loads successfully.
* @event sl-error - Emitted when the image fails to load.
*
* @slot play-icon - Optional play icon to use instead of the default. Works best with `<sl-icon>`.
* @slot pause-icon - Optional pause icon to use instead of the default. Works best with `<sl-icon>`.
*
* @part - control-box - The container that surrounds the pause/play icons and provides their background.
*
* @cssproperty --control-box-size - The size of the icon box.
* @cssproperty --icon-size - The size of the play/pause icons.
*/
@customElement('sl-animated-image')
export default class SlAnimatedImage extends ShoelaceElement {
static styles: CSSResultGroup = styles;
@query('.animated-image__animated') animatedImage: HTMLImageElement;
@state() frozenFrame: string;
@state() isLoaded = false;
/** The path to the image to load. */
@property() src: string;
/** A description of the image used by assistive devices. */
@property() alt: string;
/** Plays the animation. When this attribute is remove, the animation will pause. */
@property({ type: Boolean, reflect: true }) play: boolean;
private handleClick() {
this.play = !this.play;
}
private handleLoad() {
const canvas = document.createElement('canvas');
const { width, height } = this.animatedImage;
canvas.width = width;
canvas.height = height;
canvas.getContext('2d')!.drawImage(this.animatedImage, 0, 0, width, height);
this.frozenFrame = canvas.toDataURL('image/gif');
if (!this.isLoaded) {
this.emit('sl-load');
this.isLoaded = true;
}
}
private handleError() {
this.emit('sl-error');
}
@watch('play', { waitUntilFirstUpdate: true })
handlePlayChange() {
// When the animation starts playing, reset the src so it plays from the beginning. Since the src is cached, this
// won't trigger another request.
if (this.play) {
this.animatedImage.src = '';
this.animatedImage.src = this.src;
}
}
@watch('src')
handleSrcChange() {
this.isLoaded = false;
}
render() {
return html`
<div class="animated-image">
<img
class="animated-image__animated"
src=${this.src}
alt=${this.alt}
crossorigin="anonymous"
aria-hidden=${this.play ? 'false' : 'true'}
@click=${this.handleClick}
@load=${this.handleLoad}
@error=${this.handleError}
/>
${this.isLoaded
? html`
<img
class="animated-image__frozen"
src=${this.frozenFrame}
alt=${this.alt}
aria-hidden=${this.play ? 'true' : 'false'}
@click=${this.handleClick}
/>
<div part="control-box" class="animated-image__control-box">
<slot name="play-icon"><sl-icon name="play-fill" library="system"></sl-icon></slot>
<slot name="pause-icon"><sl-icon name="pause-fill" library="system"></sl-icon></slot>
</div>
`
: ''}
</div>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
'sl-animated-image': SlAnimatedImage;
}
}
import SlAnimatedImage from './animated-image.component';
export default SlAnimatedImage;
window.customElements.define('sl-animated-image', class extends SlAnimatedImage {});

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { aTimeout, expect, fixture, html, oneEvent } from '@open-wc/testing';
import type SlAnimation from './animation';

View File

@@ -78,7 +78,7 @@ export default class SlAnimation extends ShoelaceElement {
@property({ attribute: 'playback-rate', type: Number }) playbackRate = 1;
/** Gets and sets the current animation time. */
get currentTime(): number {
get currentTime(): CSSNumberish {
return this.animation?.currentTime ?? 0;
}

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { aTimeout, expect, fixture, html, waitUntil } from '@open-wc/testing';
import type SlAvatar from './avatar';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
import type SlBadge from './badge';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
import type SlBreadcrumbItem from './breadcrumb-item';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
import type SlBreadcrumb from './breadcrumb';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
import type SlButtonGroup from './button-group';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html, waitUntil } from '@open-wc/testing';
import { runFormControlBaseTests } from '../../internal/test/form-control-base-tests';
import sinon from 'sinon';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
import type SlCard from './card';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
describe('<sl-carousel-item>', () => {

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { clickOnElement } from '../../internal/test';
import { expect, fixture, html, oneEvent } from '@open-wc/testing';
import sinon from 'sinon';

View File

@@ -1,6 +1,6 @@
import '../icon/icon';
import { AutoplayController } from './autoplay-controller';
import { clamp } from 'src/internal/math';
import { clamp } from '../../internal/math';
import { classMap } from 'lit/directives/class-map.js';
import { customElement, property, query, state } from 'lit/decorators.js';
import { html } from 'lit';

View File

@@ -1,6 +1,6 @@
import { debounce } from 'src/internal/debounce';
import { prefersReducedMotion } from 'src/internal/animate';
import { waitForEvent } from 'src/internal/event';
import { debounce } from '../../internal/debounce';
import { prefersReducedMotion } from '../../internal/animate';
import { waitForEvent } from '../../internal/event';
import type { ReactiveController, ReactiveElement } from 'lit';
interface ScrollHost extends ReactiveElement {

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { aTimeout, expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
import { clickOnElement } from '../../internal/test';
import { runFormControlBaseTests } from '../../internal/test/form-control-base-tests';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { aTimeout, expect, fixture, html, oneEvent } from '@open-wc/testing';
import { clickOnElement } from '../../internal/test';
import { runFormControlBaseTests } from '../../internal/test/form-control-base-tests';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
// cspell:dictionaries lorem-ipsum
import { expect, fixture, html, waitUntil } from '@open-wc/testing';
import sinon from 'sinon';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
// cspell:dictionaries lorem-ipsum
import { expect, fixture, html, waitUntil } from '@open-wc/testing';
import { sendKeys } from '@web/test-runner-commands';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
import type SlDivider from './divider';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
// cspell:dictionaries lorem-ipsum
import { expect, fixture, html, waitUntil } from '@open-wc/testing';
import { sendKeys } from '@web/test-runner-commands';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { clickOnElement } from '../../internal/test';
import { expect, fixture, html, waitUntil } from '@open-wc/testing';
import { sendKeys, sendMouse } from '@web/test-runner-commands';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
import type SlFormatBytes from './format-bytes';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
import sinon from 'sinon';
import type SlFormatDate from './format-date';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
import type SlFormatNumber from './format-number';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html, waitUntil } from '@open-wc/testing';
import sinon from 'sinon';
import type SlIconButton from './icon-button';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
import sinon from 'sinon';
import type SlImageComparer from './image-comparer';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { aTimeout, expect, fixture, html, waitUntil } from '@open-wc/testing';
import sinon from 'sinon';
import type SlInclude from './include';

View File

@@ -95,7 +95,7 @@ export default css`
height: 100%;
color: var(--sl-input-color);
border: none;
background: none;
background: inherit;
box-shadow: none;
padding: 0;
margin: 0;

View File

@@ -1,9 +1,8 @@
// eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
import { expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
import { getFormControls } from '../../../dist/utilities/form.js';
import { getFormControls, serialize } from '../../../dist/shoelace.js';
import { runFormControlBaseTests } from '../../internal/test/form-control-base-tests';
import { sendKeys } from '@web/test-runner-commands'; // must come from the same module
import { serialize } from '../../utilities/form';
import sinon from 'sinon';
import type SlInput from './input';
@@ -183,7 +182,7 @@ describe('<sl-input>', () => {
it('should serialize its name and value with JSON', async () => {
const form = await fixture<HTMLFormElement>(html` <form><sl-input name="a" value="1"></sl-input></form> `);
const json = serialize(form);
const json = serialize(form) as { a: '1' };
expect(json.a).to.equal('1');
});

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { clickOnElement } from '../../internal/test';
import { expect, fixture, html, waitUntil } from '@open-wc/testing';
import sinon from 'sinon';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
import type SlMenuLabel from './menu-label';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { clickOnElement } from '../../internal/test';
import { expect, fixture } from '@open-wc/testing';
import { html } from 'lit';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
describe('<sl-mutation-observer>', () => {

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { aTimeout, expect, fixture, html, waitUntil } from '@open-wc/testing';
import sinon from 'sinon';
import type SlOption from './option';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
describe('<sl-popup>', () => {

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
import type SlProgressBar from './progress-bar';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
import type SlProgressRing from './progress-ring';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
import type SlRadioButton from './radio-button';
import type SlRadioGroup from '../radio-group/radio-group';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { aTimeout, expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
import { clickOnElement } from '../../internal/test';
import { runFormControlBaseTests } from '../../internal/test/form-control-base-tests';
@@ -365,5 +366,36 @@ describe('when the value changes', () => {
await radioGroup.updateComplete;
});
/**
* @see https://github.com/shoelace-style/shoelace/issues/1361
* This isn't really possible to test right now due to importing "shoelace.js" which
* auto-defines all of our components up front. This should be tested if we ever split
* to non-auto-defining components and not auto-defining for tests.
*/
it.skip('should sync up radios and radio buttons if defined after radio group', async () => {
// customElements.define("sl-radio-group", SlRadioGroup)
//
// const radioGroup = await fixture<SlRadioGroup>(html`
// <sl-radio-group value="1">
// <sl-radio id="radio-1" value="1"></sl-radio>
// <sl-radio id="radio-2" value="2"></sl-radio>
// </sl-radio-group>
// `);
//
// await aTimeout(1)
//
// customElements.define("sl-radio-button", SlRadioButton)
//
// expect(radioGroup.querySelector("sl-radio")?.getAttribute("aria-checked")).to.equal("false")
//
// await aTimeout(1)
//
// customElements.define("sl-radio", SlRadio)
//
// await aTimeout(1)
//
// expect(radioGroup.querySelector("sl-radio")?.getAttribute("aria-checked")).to.equal("true")
});
runFormControlBaseTests('sl-radio-group');
});

View File

@@ -204,40 +204,57 @@ export default class SlRadioGroup extends ShoelaceElement implements ShoelaceFor
this.formControlController.emitInvalidEvent(event);
}
private syncRadios() {
if (customElements.get('sl-radio') || customElements.get('sl-radio-button')) {
const radios = this.getAllRadios();
private async syncRadioElements() {
const radios = this.getAllRadios();
await Promise.all(
// Sync the checked state and size
radios.forEach(radio => {
radios.map(async radio => {
await radio.updateComplete;
radio.checked = radio.value === this.value;
radio.size = this.size;
});
})
);
this.hasButtonGroup = radios.some(radio => radio.tagName.toLowerCase() === 'sl-radio-button');
if (!radios.some(radio => radio.checked)) {
if (this.hasButtonGroup) {
const buttonRadio = radios[0].shadowRoot?.querySelector('button');
if (buttonRadio) {
buttonRadio.tabIndex = 0;
}
} else {
radios[0].tabIndex = 0;
}
}
this.hasButtonGroup = radios.some(radio => radio.tagName.toLowerCase() === 'sl-radio-button');
if (!radios.some(radio => radio.checked)) {
if (this.hasButtonGroup) {
const buttonGroup = this.shadowRoot?.querySelector('sl-button-group');
const buttonRadio = radios[0].shadowRoot?.querySelector('button');
if (buttonGroup) {
buttonGroup.disableRole = true;
if (buttonRadio) {
buttonRadio.tabIndex = 0;
}
} else {
radios[0].tabIndex = 0;
}
}
if (this.hasButtonGroup) {
const buttonGroup = this.shadowRoot?.querySelector('sl-button-group');
if (buttonGroup) {
buttonGroup.disableRole = true;
}
}
}
private syncRadios() {
if (customElements.get('sl-radio') && customElements.get('sl-radio-button')) {
this.syncRadioElements();
return;
}
if (customElements.get('sl-radio')) {
this.syncRadioElements();
} else {
customElements.whenDefined('sl-radio').then(() => this.syncRadios());
}
if (customElements.get('sl-radio-button')) {
this.syncRadioElements();
} else {
// Rerun this handler when <sl-radio> or <sl-radio-button> is registered
customElements.whenDefined('sl-radio').then(() => this.syncRadios());
customElements.whenDefined('sl-radio-button').then(() => this.syncRadios());
}
}

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
import type SlRadio from './radio';
import type SlRadioGroup from '../radio-group/radio-group';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { clickOnElement } from '../../internal/test';
import { expect, fixture, html, oneEvent } from '@open-wc/testing';
import { runFormControlBaseTests } from '../../internal/test/form-control-base-tests';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { clickOnElement } from '../../internal/test';
import { expect, fixture, html } from '@open-wc/testing';
import { sendKeys } from '@web/test-runner-commands';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
import { LocalizeController } from '@shoelace-style/localize';
import sinon from 'sinon';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { aTimeout, expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
import { clickOnElement } from '../../internal/test';
import { runFormControlBaseTests } from '../../internal/test/form-control-base-tests';

View File

@@ -10,7 +10,7 @@ import { getAnimation, setDefaultAnimation } from '../../utilities/animation-reg
import { HasSlotController } from '../../internal/slot';
import { html } from 'lit';
import { LocalizeController } from '../../utilities/localize';
import { scrollIntoView } from 'src/internal/scroll';
import { scrollIntoView } from '../../internal/scroll';
import { waitForEvent } from '../../internal/event';
import { watch } from '../../internal/watch';
import ShoelaceElement from '../../internal/shoelace-element';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
import type SlSkeleton from './skeleton';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
import type SlSpinner from './spinner';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { dragElement } from '../../internal/test';
import { expect, fixture, html, oneEvent } from '@open-wc/testing';
import { queryByTestId } from '../../internal/test/data-testid-helpers';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { aTimeout, expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
import { runFormControlBaseTests } from '../../internal/test/form-control-base-tests';
import { sendKeys } from '@web/test-runner-commands';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { aTimeout, elementUpdated, expect, fixture, oneEvent, waitUntil } from '@open-wc/testing';
import { clickOnElement } from '../../internal/test';
import { html } from 'lit';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { aTimeout, expect, fixture, html } from '@open-wc/testing';
import type SlTabPanel from './tab-panel';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
import sinon from 'sinon';
import type SlIconButton from '../icon-button/icon-button';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
import sinon from 'sinon';
import type SlTag from './tag';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
import { runFormControlBaseTests } from '../../internal/test/form-control-base-tests';
import { sendKeys } from '@web/test-runner-commands';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html, waitUntil } from '@open-wc/testing';
import sinon from 'sinon';
import type SlPopup from '../popup/popup';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html, oneEvent, waitUntil } from '@open-wc/testing';
import sinon from 'sinon';
import type SlTreeItem from './tree-item';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { aTimeout, expect, fixture, html, triggerBlurFor, triggerFocusFor } from '@open-wc/testing';
import { clickOnElement } from '../../internal/test';
import { sendKeys } from '@web/test-runner-commands';

View File

@@ -1,3 +1,4 @@
import '../../../dist/shoelace.js';
import { expect, fixture, html } from '@open-wc/testing';
describe('<sl-visually-hidden>', () => {

View File

@@ -1,34 +1,34 @@
export { default as SlAfterCollapseEvent } from './sl-after-collapse';
export { default as SlAfterExpandEvent } from './sl-after-expand';
export { default as SlAfterHideEvent } from './sl-after-hide';
export { default as SlAfterShowEvent } from './sl-after-show';
export { default as SlBlurEvent } from './sl-blur';
export { default as SlCancelEvent } from './sl-cancel';
export { default as SlChangeEvent } from './sl-change';
export { default as SlClearEvent } from './sl-clear';
export { default as SlCloseEvent } from './sl-close';
export { default as SlCollapseEvent } from './sl-collapse';
export { default as SlErrorEvent } from './sl-error';
export { default as SlExpandEvent } from './sl-expand';
export { default as SlFinishEvent } from './sl-finish';
export { default as SlFocusEvent } from './sl-focus';
export { default as SlHideEvent } from './sl-hide';
export { default as SlHoverEvent } from './sl-hover';
export { default as SlInitialFocusEvent } from './sl-initial-focus';
export { default as SlInputEvent } from './sl-input';
export { default as SlInvalidEvent } from './sl-invalid';
export { default as SlLazyChangeEvent } from './sl-lazy-change';
export { default as SlLazyLoadEvent } from './sl-lazy-load';
export { default as SlLoadEvent } from './sl-load';
export { default as SlMutationEvent } from './sl-mutation';
export { default as SlRemoveEvent } from './sl-remove';
export { default as SlRepositionEvent } from './sl-reposition';
export { default as SlRequestCloseEvent } from './sl-request-close';
export { default as SlResizeEvent } from './sl-resize';
export { default as SlSelectEvent } from './sl-select';
export { default as SlSelectionChangeEvent } from './sl-selection-change';
export { default as SlShowEvent } from './sl-show';
export { default as SlSlideChange } from './sl-slide-change';
export { default as SlStartEvent } from './sl-start';
export { default as SlTabHideEvent } from './sl-tab-hide';
export { default as SlTabShowEvent } from './sl-tab-show';
export type { default as SlAfterCollapseEvent } from './sl-after-collapse';
export type { default as SlAfterExpandEvent } from './sl-after-expand';
export type { default as SlAfterHideEvent } from './sl-after-hide';
export type { default as SlAfterShowEvent } from './sl-after-show';
export type { default as SlBlurEvent } from './sl-blur';
export type { default as SlCancelEvent } from './sl-cancel';
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 SlErrorEvent } from './sl-error';
export type { default as SlExpandEvent } from './sl-expand';
export type { default as SlFinishEvent } from './sl-finish';
export type { default as SlFocusEvent } from './sl-focus';
export type { default as SlHideEvent } from './sl-hide';
export type { default as SlHoverEvent } from './sl-hover';
export type { default as SlInitialFocusEvent } from './sl-initial-focus';
export type { default as SlInputEvent } from './sl-input';
export type { default as SlInvalidEvent } from './sl-invalid';
export type { default as SlLazyChangeEvent } from './sl-lazy-change';
export type { default as SlLazyLoadEvent } from './sl-lazy-load';
export type { default as SlLoadEvent } from './sl-load';
export type { default as SlMutationEvent } from './sl-mutation';
export type { default as SlRemoveEvent } from './sl-remove';
export type { default as SlRepositionEvent } from './sl-reposition';
export type { default as SlRequestCloseEvent } from './sl-request-close';
export type { default as SlResizeEvent } from './sl-resize';
export type { default as SlSelectEvent } from './sl-select';
export type { default as SlSelectionChangeEvent } from './sl-selection-change';
export type { default as SlShowEvent } from './sl-show';
export type { default as SlSlideChange } from './sl-slide-change';
export type { default as SlStartEvent } from './sl-start';
export type { default as SlTabHideEvent } from './sl-tab-hide';
export type { default as SlTabShowEvent } from './sl-tab-show';

View File

@@ -1,5 +1,6 @@
import { LitElement } from 'lit';
import { property } from 'lit/decorators.js';
import { ScopedElementsMixin } from '@open-wc/scoped-elements';
// Match event type name strings that are registered on GlobalEventHandlersEventMap...
type EventTypeRequiresDetail<T> = T extends keyof GlobalEventHandlersEventMap
@@ -62,11 +63,15 @@ type GetCustomEventType<T> = T extends keyof GlobalEventHandlersEventMap
// `keyof ValidEventTypeMap` is equivalent to `keyof GlobalEventHandlersEventMap` but gives a nicer error message
type ValidEventTypeMap = EventTypesWithRequiredDetail | EventTypesWithoutRequiredDetail;
export default class ShoelaceElement extends LitElement {
export default class ShoelaceElement extends ScopedElementsMixin(LitElement) {
// Make localization attributes reactive
@property() dir: string;
@property() lang: string;
static get scopedElements(): Record<string, typeof LitElement> {
return {};
}
/** Emits a custom event with more convenient defaults. */
emit<T extends string & keyof EventTypesWithoutRequiredDetail>(
name: EventTypeDoesNotRequireDetail<T>,

View File

@@ -62,6 +62,7 @@ export { default as SlVisuallyHidden } from './components/visually-hidden/visual
export * from './utilities/animation';
export * from './utilities/base-path';
export * from './utilities/icon-library';
export * from './utilities/form';
// Events
export * from './events/events';

View File

@@ -1,4 +1,4 @@
import { registerTranslation } from '../utilities/localize';
import { registerTranslation } from '@shoelace-style/localize';
import type { Translation } from '../utilities/localize';
const translation: Translation = {

View File

@@ -1,4 +1,4 @@
import '../translations/en';
import '../translations/en.js';
import { LocalizeController as DefaultLocalizationController } from '@shoelace-style/localize'; // Register English as the default/fallback language
import type { Translation as DefaultTranslation } from '@shoelace-style/localize';

View File

@@ -16,7 +16,7 @@ export default {
plugins: [
esbuildPlugin({
ts: true,
target: 'auto'
target: 'es2020'
})
],
browsers: [
@@ -29,7 +29,9 @@ export default {
<head></head>
<body>
<link rel="stylesheet" href="dist/themes/light.css">
<script type="module" src="dist/shoelace.js"></script>
<script>
window.process = {env: { NODE_ENV: "production" }}
</script>
<script type="module" src="${testFramework}"></script>
</body>
</html>