import { {{ component.name }} } from '@shoelace-style/shoelace/dist/react';
+
import { {{ component.name }} } from '@shoelace-style/shoelace/{{ meta.npmdir }}/react';
diff --git a/docs/_utilities/replacer.cjs b/docs/_utilities/replacer.cjs
new file mode 100644
index 000000000..b9dc588e7
--- /dev/null
+++ b/docs/_utilities/replacer.cjs
@@ -0,0 +1,20 @@
+/**
+ * @typedef {object} Replacement
+ * @property {string | RegExp} pattern
+ * @property {string} replacement
+ */
+
+/**
+ * @typedef {Array} 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)
+ })
+}
diff --git a/docs/assets/scripts/code-previews.js b/docs/assets/scripts/code-previews.js
index b7c262331..1995c4084 100644
--- a/docs/assets/scripts/code-previews.js
+++ b/docs/assets/scripts/code-previews.js
@@ -180,7 +180,7 @@
// HTML templates
if (!isReact) {
htmlTemplate =
- `\n` +
+ `\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}/cdn/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(, document.getElementById('root'));`;
@@ -202,7 +202,7 @@
// CSS templates
cssTemplate =
- `@import 'https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@${shoelaceVersion}/cdn/themes/${
+ `@import 'https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@${shoelaceVersion}/%CDNDIR%/themes/${
isDark ? 'dark' : 'light'
}.css';\n` +
'\n' +
diff --git a/docs/eleventy.config.cjs b/docs/eleventy.config.cjs
index a1df2e605..f165bd6c1 100644
--- a/docs/eleventy.config.cjs
+++ b/docs/eleventy.config.cjs
@@ -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 = `\n${doc.documentElement.outerHTML}`;
diff --git a/docs/pages/frameworks/angular.md b/docs/pages/frameworks/angular.md
index b1ce5675d..8b651132c 100644
--- a/docs/pages/frameworks/angular.md
+++ b/docs/pages/frameworks/angular.md
@@ -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%/cdn/');
+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
diff --git a/docs/pages/frameworks/react.md b/docs/pages/frameworks/react.md
index bab6d59e5..080a77c04 100644
--- a/docs/pages/frameworks/react.md
+++ b/docs/pages/frameworks/react.md
@@ -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%/cdn/');
+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 `` _React component_ instead of the `` _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 = () => Click me;
@@ -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('');
diff --git a/docs/pages/frameworks/vue-2.md b/docs/pages/frameworks/vue-2.md
index c099c5def..992f6d6ed 100644
--- a/docs/pages/frameworks/vue-2.md
+++ b/docs/pages/frameworks/vue-2.md
@@ -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%/cdn/');
+setBasePath('https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/%CDNDIR%/');
```
:::tip
diff --git a/docs/pages/frameworks/vue.md b/docs/pages/frameworks/vue.md
index 3284a44fc..08dae60ee 100644
--- a/docs/pages/frameworks/vue.md
+++ b/docs/pages/frameworks/vue.md
@@ -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%/cdn/');
+setBasePath('https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@%VERSION%/%CDNDIR%/');
```
:::tip
diff --git a/docs/pages/getting-started/installation.md b/docs/pages/getting-started/installation.md
index a1441dfac..056cec41b 100644
--- a/docs/pages/getting-started/installation.md
+++ b/docs/pages/getting-started/installation.md
@@ -22,8 +22,8 @@ While convenient, autoloading may lead to a [Flash of Undefined Custom Elements]
```html
-
-
+
+
```
@@ -33,8 +33,8 @@ 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.
```html
-
-
+
+
```
@@ -45,7 +45,7 @@ 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 `` to your page.
```html
-
+
```
### Light & Dark Theme
@@ -56,12 +56,12 @@ If you want to load the light or dark theme based on the user's `prefers-color-s
```
@@ -81,8 +81,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
-
-
+
+
```
Alternatively, [you can use a bundler](#bundling).
@@ -99,13 +99,13 @@ However, if you're [cherry picking](#cherry-picking) or [bundling](#bundling) Sh
```html
-
+
```
@@ -126,10 +126,10 @@ Cherry picking can be done from [the CDN](#cdn-installation-easiest) or from [NP
Here's an example that loads only the button component. Again, if you're not using a module resolver, you'll need to adjust the path to point to the folder Shoelace is in.
```html
-
+
-
@@ -163,15 +163,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%
// , , , and are ready to use!
```
@@ -182,16 +182,16 @@ Component modules include side effects for registration purposes. Because of thi
## The difference between CDN and NPM
-You'll notice above that the CDN links all start with `/cdn/` and imports using NPM use `/dist/`.
-The `/cdn` files use a different bundle from `/dist`. `/cdn` files come "prebundled" which means all dependencies are
-inlined so you do not need to worry about loading any additional libraries. `/dist` does **NOT** prebundle dependencies
+You'll notice above that the CDN links all start with `/%CDNDIR%/` and imports using NPM use `/%NPMDIR%/`.
+The `/%CDNDIR%` files use a different bundle from `/%NPMDIR%`. `/%CDNDIR%` files come "pre-bundled" which means all dependencies are
+inlined so you do not need to worry about loading any additional libraries. `/%NPMDIR%` does **NOT** pre-bundle dependencies
allowing for your bundler of choice to more efficiently deduplicate dependencies resulting in smaller overall bundles
and greater code sharing.
TLDR:
-- `@shoelace-style/shoelace/cdn` is for CDN
-- `@shoelace-style/shoelace/dist` is for NPM
+- `@shoelace-style/shoelace/%CDNDIR%` is for CDN
+- `@shoelace-style/shoelace/%NPMDIR%` is for NPM
This change was introduced in `v2.5.0` to address issues around installations from NPM
loading multiple versions of libraries such as the Lit web component library which Shoelace uses internally.
\ No newline at end of file
diff --git a/docs/pages/getting-started/localization.md b/docs/pages/getting-started/localization.md
index 6dcdfcfb9..2470558d4 100644
--- a/docs/pages/getting-started/localization.md
+++ b/docs/pages/getting-started/localization.md
@@ -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.
@@ -135,4 +135,4 @@ Once your translation has been compiled to JavaScript, import it and activate it
:::tip
If your translation isn't working, make sure you're using the same localize module when importing `registerTranslation`. If you're using a different module, your translation won't be recognized.
-:::
+:::
\ No newline at end of file
diff --git a/docs/pages/getting-started/themes.md b/docs/pages/getting-started/themes.md
index da35aa93c..e139d6a75 100644
--- a/docs/pages/getting-started/themes.md
+++ b/docs/pages/getting-started/themes.md
@@ -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 `` eleme
```html
-
+
@@ -54,8 +54,8 @@ You can activate themes on various containers throughout the page. This example
```html
-
-
+
+
@@ -127,7 +127,7 @@ 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 `` section of your page.
```html
-
+
```
To activate the theme, apply the `sl-theme-dark` class to the `` element.
diff --git a/docs/pages/index.md b/docs/pages/index.md
index c59e01d91..1e09273a8 100644
--- a/docs/pages/index.md
+++ b/docs/pages/index.md
@@ -41,8 +41,8 @@ Add the following code to your page.
```html
-
-
+
+
```
Now you have access to all of Shoelace's components! Try adding a button:
diff --git a/scripts/build.js b/scripts/build.js
index 179a1a2bb..7daa28fee 100644
--- a/scripts/build.js
+++ b/scripts/build.js
@@ -197,7 +197,7 @@ await nextTask('Running the TypeScript compiler', () => {
return execPromise(`tsc --project ./tsconfig.prod.json --outdir "${outdir}"`, { stdio: 'inherit' });
});
-// Copy the above steps to the CDN directory directly so we dont need to twice the work for nothing.
+// 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);