kopia lustrzana https://github.com/shoelace-style/shoelace
Merge branch 'konnorrogers/modify-build-script-for-npm-2' into next
commit
7404e496cb
|
@ -5,3 +5,4 @@ dist
|
|||
docs/assets/images/sprite.svg
|
||||
node_modules
|
||||
src/react
|
||||
cdn
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
"CACHEABLE",
|
||||
"callout",
|
||||
"callouts",
|
||||
"cdndir",
|
||||
"chatbubble",
|
||||
"checkmark",
|
||||
"claviska",
|
||||
|
@ -104,6 +105,7 @@
|
|||
"noopener",
|
||||
"noreferrer",
|
||||
"novalidate",
|
||||
"npmdir",
|
||||
"outdir",
|
||||
"ParamagicDev",
|
||||
"peta",
|
||||
|
|
|
@ -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"><script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@{{ meta.version }}/dist/{{ component.path }}"></script></code></pre>
|
||||
<pre><code class="language-html"><script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@{{ meta.version }}/{{ meta.cdndir }}/{{ component.path }}"></script></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><{{ dependency }}></code></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
};
|
|
@ -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' +
|
||||
|
|
|
@ -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)
|
||||
});
|
||||
|
||||
//
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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('');
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -14,6 +14,16 @@ 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)
|
||||
|
|
|
@ -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 .",
|
||||
|
|
|
@ -11,18 +11,16 @@ import getPort, { portNumbers } from 'get-port';
|
|||
import ora from 'ora';
|
||||
import util from 'util';
|
||||
|
||||
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 +69,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,7 +97,7 @@ async function buildTheSource() {
|
|||
// React wrappers
|
||||
...(await globby('./src/react/**/*.ts'))
|
||||
],
|
||||
outdir,
|
||||
outdir: cdndir,
|
||||
chunkNames: 'chunks/[name].[hash]',
|
||||
incremental: serve,
|
||||
define: {
|
||||
|
@ -108,19 +111,26 @@ 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
|
||||
};
|
||||
|
||||
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.rebuild.dispose());
|
||||
|
||||
if (childProcess) {
|
||||
childProcess.kill('SIGINT');
|
||||
|
@ -150,12 +160,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,17 +192,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
|
||||
await nextTask(`Copying the build to "${sitedir}"`, async () => {
|
||||
await deleteAsync(sitedir);
|
||||
|
||||
// We copy the CDN build because that has everything bundled.
|
||||
await copy(cdndir, sitedir);
|
||||
});
|
||||
|
||||
// Launch the dev server
|
||||
if (serve) {
|
||||
|
@ -215,7 +235,7 @@ if (serve) {
|
|||
server: {
|
||||
baseDir: sitedir,
|
||||
routes: {
|
||||
'/dist': './dist'
|
||||
'/cdn': './cdn'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -243,16 +263,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();
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { registerTranslation } from '../utilities/localize';
|
||||
import { registerTranslation } from '@shoelace-style/localize';
|
||||
import type { Translation } from '../utilities/localize';
|
||||
|
||||
const translation: Translation = {
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -28,8 +28,8 @@ export default {
|
|||
<html lang="en-US">
|
||||
<head></head>
|
||||
<body>
|
||||
<link rel="stylesheet" href="dist/themes/light.css">
|
||||
<script type="module" src="dist/shoelace.js"></script>
|
||||
<link rel="stylesheet" href="cdn/themes/light.css">
|
||||
<script type="module" src="cdn/shoelace.js"></script>
|
||||
<script type="module" src="${testFramework}"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Ładowanie…
Reference in New Issue