diff --git a/.eslintrc.json b/.eslintrc.json
deleted file mode 100644
index bb790113b..000000000
--- a/.eslintrc.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
- "parserOptions": {
- "project": "./tsconfig.json"
- },
- "extends": ["plugin:@stencil/recommended"],
- "rules": {
- "@stencil/async-methods": "error",
- "@stencil/ban-prefix": ["error", ["stencil", "stnl", "st"]],
- "@stencil/decorators-context": "error",
- "@stencil/decorators-style": [
- "error",
- {
- "prop": "inline",
- "state": "inline",
- "element": "inline",
- "event": "inline",
- "method": "multiline",
- "watch": "multiline",
- "listen": "multiline"
- }
- ],
- "@stencil/element-type": "error",
- "@stencil/host-data-deprecated": "error",
- "@stencil/methods-must-be-public": "error",
- "@stencil/no-unused-watch": "error",
- "@stencil/own-methods-must-be-private": "off",
- "@stencil/own-props-must-be-private": "off",
- "@stencil/prefer-vdom-listener": "error",
- "@stencil/props-must-be-public": "off",
- "@stencil/props-must-be-readonly": "off",
- "@stencil/render-returns-host": "error",
- "@stencil/required-jsdoc": "error",
- "@stencil/reserved-member-names": "error",
- "@stencil/single-export": "error",
- "@stencil/strict-boolean-conditions": "off",
- "@stencil/strict-mutable": "off",
- "react/jsx-no-bind": "off"
- }
-}
diff --git a/.gitignore b/.gitignore
index 5ea805194..c4f61d9a5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,34 +1,6 @@
-src/components/*/readme.md
-src/components/icon/icons
-docs/assets/data/custom.json
-docs/assets/icons/sprite.svg
-
-dist/
-docs/dist/
-docs/themes/
-loader/
-temp/
-
-*~
-*.sw[mnpcod]
-*.log
-*.lock
-*.tmp
-*.tmp.*
-log.txt
-*.sublime-project
-*.sublime-workspace
-
-.cache/
-.stencil/
-.idea/
-.vscode/
-.sass-cache/
-.versions/
-node_modules/
-$RECYCLE.BIN/
-
.DS_Store
-Thumbs.db
-UserInterfaceState.xcuserstate
-.env
+.cache
+docs/dist
+dist
+examples
+node_modules
diff --git a/.prettierignore b/.prettierignore
index fc0a3a758..671be3eac 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,11 +1,9 @@
-.github
+*.md
.cache
-.stencil
+.github
dist
-docs/assets
-docs/**/*.md
-loader
+docs/*.md
+src/components/icon/icons
node_modules
-src/components/**/readme.md
-src/components.d.ts
package-lock.json
+tsconfig.json
diff --git a/README.md b/README.md
index 50d1f1ef5..5160a45fb 100644
--- a/README.md
+++ b/README.md
@@ -31,9 +31,7 @@ If that's not what you're trying to do, the [documentation website](https://shoe
### What are you using to build Shoelace?
-Components are built with [Stencil](https://stenciljs.com/), a compiler that generates standards-based web components. The source code is a combination of TypeScript + JSX (TSX). Stylesheets are written in SCSS.
-
-The build is done through a combination of Stencil's CLI and a handful of custom scripts.
+Components are built with [Shoemaker](https://github.com/shoelace-style/shoemaker), a lightweight utility that provides an elegant API and reactive data binding. The build is a custom script with bundling powered by [esbuild](https://esbuild.github.io/).
### Forking the Repo
@@ -50,14 +48,14 @@ npm install
Once you've cloned the repo, run the following command.
```bash
-npm run start
+npm start
```
-This will spin up the Shoelace dev server. Note that the dev server requires ports 4000, 4001, and 4002 to be available.
+This will spin up the Shoelace dev server. After the initial build, a browser will open automatically.
-After the initial build, a browser will open at `http://localhost:4000`.
+There is currently no hot module reloading (HMR), as browser's don't provide a way to reregister custom elements, but most changes to the source will reload the browser automatically. The exception is component metadata used by the docs, which is generated by TypeDoc. This tool takes a few seconds to run so, to prevent long reload delays, it only runs once at startup.
-Hot module reloading (HMR) is enabled for components, so changes will instantly reflect in the browser as you work. The documentation is powered by Docsify, which uses raw markdown files to generate pages. As such, no static files are built for the docs. Unfortunately, changes to _documentation pages_ will trigger a page refresh (no HMR).
+The documentation is powered by Docsify, which uses raw markdown files to generate pages. As such, no static files are built for the docs.
### Building
diff --git a/dev-server.js b/dev-server.js
deleted file mode 100644
index d3b83b53c..000000000
--- a/dev-server.js
+++ /dev/null
@@ -1,77 +0,0 @@
-//
-// The Shoelace dev server! 🥾
-//
-// This is an Express + Browsersync script that:
-//
-// - Proxies Stencil's dev server (for HMR of components)
-// - Serves dist/ and docs/ from https://localhost:3000/
-// - Launches the docs site and reloads the page when pages are modified
-//
-// Usage:
-//
-// 1. Run Stencil: `stencil build --dev --docs --watch --serve --no-open`
-//
-// 2. Run this script at the same time as Stencil
-//
-
-const bs = require('browser-sync').create();
-const chalk = require('chalk');
-const express = require('express');
-const fs = require('fs').promises;
-const path = require('path');
-const { createProxyMiddleware } = require('http-proxy-middleware');
-
-const app = express();
-const browserPort = 4000;
-const stencilPort = 4001;
-const proxyPort = 4002;
-
-// Proxy Stencil's dev server
-app.use(
- '/~dev-server',
- createProxyMiddleware({
- target: `http://localhost:${stencilPort}`,
- changeOrigin: true,
- ws: true
- })
-);
-
-// Inject Stencil's dev server iframe into the main entry point
-app.use(/^\/$/, async (req, res, next) => {
- let index = await fs.readFile('./docs/index.html', 'utf8');
- index = index
- .replace('
- The content in this example was included from a separate file. 🤯
+
+ The content in this example was included from
+ a separate file. 🤯
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua. Lectus vestibulum mattis ullamcorper velit sed ullamcorper morbi. Fringilla urna porttitor rhoncus dolor purus
+ non enim. Nullam vehicula ipsum a arcu cursus vitae congue mauris. Gravida in fermentum et sollicitudin.
+
+
+ Cursus sit amet dictum sit amet justo donec enim. Sed id semper risus in hendrerit gravida. Viverra accumsan in nisl
+ nisi scelerisque eu ultrices vitae. Et molestie ac feugiat sed lectus vestibulum mattis ullamcorper velit. Nec
+ ullamcorper sit amet risus nullam. Et egestas quis ipsum suspendisse ultrices gravida dictum. Lorem donec massa sapien
+ faucibus et molestie. A cras semper auctor neque vitae.
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lectus vestibulum mattis ullamcorper velit sed ullamcorper morbi. Fringilla urna porttitor rhoncus dolor purus non enim. Nullam vehicula ipsum a arcu cursus vitae congue mauris. Gravida in fermentum et sollicitudin.
-
Cursus sit amet dictum sit amet justo donec enim. Sed id semper risus in hendrerit gravida. Viverra accumsan in nisl nisi scelerisque eu ultrices vitae. Et molestie ac feugiat sed lectus vestibulum mattis ullamcorper velit. Nec ullamcorper sit amet risus nullam. Et egestas quis ipsum suspendisse ultrices gravida dictum. Lorem donec massa sapien faucibus et molestie. A cras semper auctor neque vitae.
-```
-
-To display an icon, set the `library` and `name` attributes of an `` element.
-
-```html
-
-
-```
-
-The location of the icon library in the DOM doesn't matter as long as it's within the `` element. If an icon is used before registration, it will be empty until registration has completed. It's perfectly acceptable to place all `` elements before the `` tag if you prefer to organize them that way.
-
-## Examples
-
-The following examples demonstrate how to register a number of popular, open source icon libraries via CDN. Feel free to adapt the code as you see fit to use your own origin or naming conventions.
-
-### Boxicons
-
-This will register the [Boxicons](https://boxicons.com/) library using the jsDelivr CDN. This library has three variations: regular (`bx-*`), solid (`bxs-*`), and logos (`bxl-*`). A mutator function is required to set the SVG's `fill` to `currentColor`.
-
-Icons in this library are licensed under the [Creative Commons 4.0 License](https://github.com/atisawd/boxicons#license).
-
-```html preview
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
-### Feather Icons
-
-This will register the [Feather Icons](https://feathericons.com/) library using the jsDelivr CDN.
-
-Icons in this library are licensed under the [MIT License](https://github.com/feathericons/feather/blob/master/LICENSE).
-
-```html preview
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
-### Font Awesome
-
-This will register the [Font Awesome Free](https://fontawesome.com/) library using the jsDelivr CDN. This library has three variations: regular (`far-*`), solid (`fas-*`), and brands (`fab-*`). A mutator function is required to set the SVG's `fill` to `currentColor`.
-
-Icons in this library are licensed under the [Font Awesome Free License](https://github.com/FortAwesome/Font-Awesome/blob/master/LICENSE.txt). Some of the icons that appear on the Font Awesome website require a license and are therefore not available in the CDN.
-
-```html preview
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
-### Heroicons
-
-This will register the [Heroicons](https://heroicons.com/) library using the jsDelivr CDN.
-
-Icons in this library are licensed under the [MIT License](https://github.com/tailwindlabs/heroicons/blob/master/LICENSE).
-
-```html preview
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
-### Ionicons
-
-This will register the [Ionicons](https://ionicons.com/) library using the jsDelivr CDN. This library has three variations: outline (default), filled (`*-filled`), and sharp (`*-sharp`). A mutator function is required to polyfill a handful of styles we're not including.
-
-Icons in this library are licensed under the [MIT License](https://github.com/ionic-team/ionicons/blob/master/LICENSE).
-
-```html preview
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
-### Jam Icons
-
-This will register the [Jam Icons](https://jam-icons.com/) library using the jsDelivr CDN. This library has two variations: regular (default) and filled (`*-f`). A mutator function is required to set the SVG's `fill` to `currentColor`.
-
-Icons in this library are licensed under the [MIT License](https://github.com/michaelampr/jam/blob/master/LICENSE).
-
-```html preview
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
-### Material Icons
-
-This will register the [Material Icons](https://material.io/resources/icons/?style=baseline) library using the jsDelivr CDN. This library has three variations: outline (default), round (`*_round`), and sharp (`*_sharp`). A mutator function is required to set the SVG's `fill` to `currentColor`.
-
-Icons in this library are licensed under the [Apache 2.0 License](https://github.com/google/material-design-icons/blob/master/LICENSE).
-
-```html preview
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
-### Remix Icon
-
-This will register the [Remix Icon](https://remixicon.com/) library using the jsDelivr CDN. This library has two variations: line (default) and fill (`*-fill`). It also groups icons by categories, so the name must include the category and icon separated by a slash. A mutator function is required to set the SVG's `fill` to `currentColor`.
-
-Icons in this library are licensed under the [Apache 2.0 License](https://github.com/Remix-Design/RemixIcon/blob/master/License).
-
-```html preview
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
-### Unicons
-
-This will register the [Unicons](https://iconscout.com/unicons) library using the jsDelivr CDN. This library has two variations: line (default) and solid (`*-s`). A mutator function is required to set the SVG's `fill` to `currentColor`.
-
-Icons in this library are licensed under the [Apache 2.0 License](https://github.com/Iconscout/unicons/blob/master/LICENSE). Some of the icons that appear on the Unicons website, particularly many of the solid variations, require a license and are therefore not available in the CDN.
-
-```html preview
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
-### Customizing the Default Library
-
-Shoelace comes bundled with over 1,200 icons courtesy of the [Bootstrap Icons](https://icons.getbootstrap.com/) project. These are the default icons that display when you use `` without a `name` attribute. If you prefer to have these icons resolve elsewhere, you can register an icon library with the `default` name and a custom resolver.
-
-This example will load the same set of icons from the jsDelivr CDN instead of your local assets folder.
-
-```html
-
-
-
-```
-
-Alternatively, you can replace the default icons with a completely different icon set.
-
-```html
-
-
-
-```
-
-[component-metadata:sl-icon-library]
diff --git a/docs/components/icon.md b/docs/components/icon.md
index 033234ef7..f52b0f2b7 100644
--- a/docs/components/icon.md
+++ b/docs/components/icon.md
@@ -4,7 +4,7 @@
Icons are symbols that can be used to represent various options within an application.
-Shoelace comes bundled with over 1,200 icons courtesy of the [Bootstrap Icons](https://icons.getbootstrap.com/) project. If you prefer, you can also register [custom icon libraries](/components/icon-library.md).
+Shoelace comes bundled with over 1,300 icons courtesy of the [Bootstrap Icons](https://icons.getbootstrap.com/) project. If you prefer, you can also register a [custom icon library](#icon-libraries).
Click or tap on an icon below to copy its name and use it like this.
@@ -56,15 +56,410 @@ Icons are sized relative to the current font size. To change their size, set the
### Custom Icons
-Custom icons can be loaded individually with the `src` attribute. Only SVGs on a local or CORS-enabled endpoint are supported. If you're using more than one custom icon, it might make sense to register a [custom icon library](/components/icon-library.md).
+Custom icons can be loaded individually with the `src` attribute. Only SVGs on a local or CORS-enabled endpoint are supported. If you're using more than one custom icon, it might make sense to register a [custom icon library](#icon-libraries).
```html preview
```
+## Icon Libraries
+
+Shoelace lets you register additional icons to use with the `` component through icon libraries. The icon files can exist locally or on a CORS-enabled endpoint (e.g. a CDN). There is no limit to how many icon libraries you can register and there is no cost associated with registering them, as individual icons are only requested when they're used.
+
+To register an icon library, use the `registerIconLibrary()` function that's exported from `utilities/icon-library.js`. At a minimum, you must provide a name and a resolver function. The resolver function translates an icon name to a URL where the corresponding SVG file exists. Refer to the examples below to better understand how it works.
+
+If necessary, a mutator function can be used to mutate the SVG element before rendering. This is necessary for some libraries due to the many possible ways SVGs are crafted. For example, icons should ideally inherit the current text color via `currentColor`, so you may need to apply `fill="currentColor` or `stroke="currentColor"` to the SVG element using this function.
+
+Here's an example that registers an icon library located in the `/assets/icons` directory.
+
+```html
+
+```
+
+To display an icon, set the `library` and `name` attributes of an `` element.
+
+```html
+
+
+```
+
+If an icon is used before registration occurs, it will be empty initially but shown when registered.
+
+The following examples demonstrate how to register a number of popular, open source icon libraries via CDN. Feel free to adapt the code as you see fit to use your own origin or naming conventions.
+
+### Boxicons
+
+This will register the [Boxicons](https://boxicons.com/) library using the jsDelivr CDN. This library has three variations: regular (`bx-*`), solid (`bxs-*`), and logos (`bxl-*`). A mutator function is required to set the SVG's `fill` to `currentColor`.
+
+Icons in this library are licensed under the [Creative Commons 4.0 License](https://github.com/atisawd/boxicons#license).
+
+```html preview
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### Feather Icons
+
+This will register the [Feather Icons](https://feathericons.com/) library using the jsDelivr CDN.
+
+Icons in this library are licensed under the [MIT License](https://github.com/feathericons/feather/blob/master/LICENSE).
+
+```html preview
+
+
+
+
+
+
+
+
+
+
+```
+
+### Font Awesome
+
+This will register the [Font Awesome Free](https://fontawesome.com/) library using the jsDelivr CDN. This library has three variations: regular (`far-*`), solid (`fas-*`), and brands (`fab-*`). A mutator function is required to set the SVG's `fill` to `currentColor`.
+
+Icons in this library are licensed under the [Font Awesome Free License](https://github.com/FortAwesome/Font-Awesome/blob/master/LICENSE.txt). Some of the icons that appear on the Font Awesome website require a license and are therefore not available in the CDN.
+
+```html preview
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### Heroicons
+
+This will register the [Heroicons](https://heroicons.com/) library using the jsDelivr CDN.
+
+Icons in this library are licensed under the [MIT License](https://github.com/tailwindlabs/heroicons/blob/master/LICENSE).
+
+```html preview
+
+
+
+
+
+
+
+
+
+
+```
+
+### Ionicons
+
+This will register the [Ionicons](https://ionicons.com/) library using the jsDelivr CDN. This library has three variations: outline (default), filled (`*-filled`), and sharp (`*-sharp`). A mutator function is required to polyfill a handful of styles we're not including.
+
+Icons in this library are licensed under the [MIT License](https://github.com/ionic-team/ionicons/blob/master/LICENSE).
+
+```html preview
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### Jam Icons
+
+This will register the [Jam Icons](https://jam-icons.com/) library using the jsDelivr CDN. This library has two variations: regular (default) and filled (`*-f`). A mutator function is required to set the SVG's `fill` to `currentColor`.
+
+Icons in this library are licensed under the [MIT License](https://github.com/michaelampr/jam/blob/master/LICENSE).
+
+```html preview
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### Material Icons
+
+This will register the [Material Icons](https://material.io/resources/icons/?style=baseline) library using the jsDelivr CDN. This library has three variations: outline (default), round (`*_round`), and sharp (`*_sharp`). A mutator function is required to set the SVG's `fill` to `currentColor`.
+
+Icons in this library are licensed under the [Apache 2.0 License](https://github.com/google/material-design-icons/blob/master/LICENSE).
+
+```html preview
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### Remix Icon
+
+This will register the [Remix Icon](https://remixicon.com/) library using the jsDelivr CDN. This library has two variations: line (default) and fill (`*-fill`). It also groups icons by categories, so the name must include the category and icon separated by a slash. A mutator function is required to set the SVG's `fill` to `currentColor`.
+
+Icons in this library are licensed under the [Apache 2.0 License](https://github.com/Remix-Design/RemixIcon/blob/master/License).
+
+```html preview
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### Unicons
+
+This will register the [Unicons](https://iconscout.com/unicons) library using the jsDelivr CDN. This library has two variations: line (default) and solid (`*-s`). A mutator function is required to set the SVG's `fill` to `currentColor`.
+
+Icons in this library are licensed under the [Apache 2.0 License](https://github.com/Iconscout/unicons/blob/master/LICENSE). Some of the icons that appear on the Unicons website, particularly many of the solid variations, require a license and are therefore not available in the CDN.
+
+```html preview
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+### Customizing the Default Library
+
+Shoelace comes bundled with over 1,300 icons courtesy of the [Bootstrap Icons](https://icons.getbootstrap.com/) project. These are the default icons that display when you use `` without a `name` attribute. If you prefer to have these icons resolve elsewhere, you can register an icon library with the `default` name and a custom resolver.
+
+This example will load the same set of icons from the jsDelivr CDN instead of your local assets folder.
+
+```html
+
+```
+
+Alternatively, you can replace the default icons with a completely different icon set. Just keep in mind that some of the default icons are used by components so you'll want to make sure those names resolve to an appropriate alternative.
+
+```html
+
+```
+
+
```
### Value-based Icons
@@ -70,9 +64,9 @@ Use the `disable` attribute to disable the rating.
```
diff --git a/docs/components/theme.md b/docs/components/theme.md
deleted file mode 100644
index 0efdca087..000000000
--- a/docs/components/theme.md
+++ /dev/null
@@ -1,67 +0,0 @@
-# Theme
-
-[component-header:sl-theme]
-
-Themes change the visual appearance of components.
-
-This component will activate a theme and apply its styles to everything inside. All themes must adhere to [theming guidelines](/getting-started/themes) and expose a class that follows the `sl-theme-{name}` convention.
-
-To activate a theme, include the necessary stylesheet(s) and wrap your content in an `` element. The theme to use is specified by the `name` prop.
-
-```html
-
-
-
-
-
-```
-
-?> It's important to note that the default "light" theme isn't actually a theme — it's a set of design tokens and base styles that themes can use as a foundation to build upon. As such, it's not possible to opt in to the default theme using this component.
-
-## Examples
-
-### Dark Theme
-
-To use the official dark theme, include its stylesheet per the instructions on the [themes page](/getting-started/themes) and activate it as shown in the example below. All design tokens and components will render accordingly.
-
-```html preview
-
-
-
-
-
-
-
- Dropdown
-
- Item 1
- Item 2
- Item 3
-
-
-
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit.
- Close
-
- Open Dialog
-
- Check me
-