Update build with HMR

This commit is contained in:
Cory LaViska
2020-06-04 10:56:44 -04:00
parent a3204b6e38
commit be45512775
7 changed files with 2071 additions and 1968 deletions

View File

@@ -16,8 +16,8 @@
<link rel="icon" href="/assets/images/logo.svg" type="image/x-icon" />
<!-- Import Shoelace -->
<link rel="stylesheet" href="/assets/dist/shoelace/shoelace.css" />
<script type="module" src="/assets/dist/shoelace/shoelace.esm.js"></script>
<link rel="stylesheet" href="/dist/shoelace/shoelace.css" />
<script type="module" src="/dist/shoelace/shoelace.esm.js"></script>
</head>
<body>
<div id="app"></div>

View File

@@ -1,4 +1,4 @@
<img id="top" class="logo" src="/assets/images/wordmark.svg" alt="Shoelace" data-no-zoom style="max-width: 24rem;">
<img id="top" class="logo" src="assets/images/wordmark.svg" alt="Shoelace" data-no-zoom style="max-width: 24rem;">
_A forward-thinking web component library for desktop and mobile._
@@ -31,7 +31,7 @@ Now you have access to all of Shoelace's components! Try adding a button to your
<sl-button>Click Me</sl-button>
```
!> Don't want to use the CDN? Check out the [installation instructions](installation.md) for more options.
?> Don't want to use the CDN? Check out the [installation instructions](overview/installation.md) for more options.
---
@@ -45,7 +45,7 @@ Unfortunately, *framework-specific* components fail us in a number of ways:
- 🔒 You can only use them in the framework they're designed for
- ⏳ Their lifespan is limited to that of the framework's
- 😭 New versions of the framework can lead to breaking changes, requiring substantial effort to update components
- 😭 New versions lead to breaking changes, requiring substantial effort to update components
Web Components solve these problems. They're [supported by all modern browsers](https://caniuse.com/#feat=custom-elementsv1), they're framework-agnostic, and they're [part of the standard](https://www.webcomponents.org/specs), so we know they'll be supported by browsers for many years to come.

View File

@@ -1,41 +0,0 @@
const { version } = require('./package.json');
const { series, task, watch } = require('gulp');
const copy = require('recursive-copy');
const del = require('del');
const fs = require('fs').promises;
const mkdirp = require('mkdirp');
const path = require('path');
// Removes all generated files from the docs folder
async function cleanFiles(cb) {
await del(['./docs/assets/data/custom.json', './docs/assets/dist']);
cb();
}
// Copies custom data and dist to docs/assets
async function copyFiles(cb) {
await mkdirp('./dist');
await copy('./dist', './docs/assets/dist', { overwrite: true });
cb();
}
// Copies custom data and dist to docs/assets and watches for changes
function watchFiles(cb) {
watch(`./dist/**/*`, copyFiles);
cb();
}
async function generateCustomData(cb) {
const filename = './docs/assets/data/custom.json';
const dir = path.dirname(filename);
const customData = JSON.stringify({ version }, null, 2);
await mkdirp(dir);
await fs.writeFile(filename, customData, 'utf8');
cb();
}
task('clean', cleanFiles);
task('copy', series(generateCustomData, copyFiles));
task('watch', series(generateCustomData, copyFiles, watchFiles));

3784
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -15,10 +15,9 @@
"loader/"
],
"scripts": {
"start": "concurrently --kill-others \"npm run dev\" \"gulp watch\" \"npm run docs\"",
"dev": "stencil build --dev --docs --watch --no-open",
"build": "stencil build --docs && gulp copy",
"docs": "docsify serve ./docs --open",
"start": "concurrently --kill-others \"npm run dev\" \"node serve.js\"",
"dev": "stencil build --dev --docs --watch --serve --port 3333 --no-open",
"build": "stencil build --docs",
"lint": "eslint src/**/*{.ts,.tsx}",
"test": "stencil test --spec --e2e",
"test.watch": "stencil test --spec --e2e --watchAll",
@@ -29,13 +28,16 @@
"@stencil/eslint-plugin": "^0.3.1",
"@typescript-eslint/eslint-plugin": "^2.28.0",
"@typescript-eslint/parser": "^2.28.0",
"browser-sync": "^2.26.7",
"chalk": "^4.0.0",
"concurrently": "^5.1.0",
"del": "^5.1.0",
"eslint": "^6.8.0",
"eslint-plugin-react": "^7.19.0",
"gulp": "^4.0.2",
"express": "^4.17.1",
"http-proxy": "^1.18.1",
"http-proxy-middleware": "^1.0.4",
"husky": "^4.2.5",
"mkdirp": "^1.0.4",
"recursive-copy": "^2.0.10",
"through2": "^3.0.1",
"workbox-build": "4.3.1"
@@ -44,7 +46,7 @@
"dependencies": {
"@popperjs/core": "^2.1.1",
"@sphinxxxx/color-conversion": "^2.2.2",
"@stencil/core": "^1.13.0",
"@stencil/core": "^1.14.0",
"@stencil/sass": "^1.1.1",
"color": "^3.1.2",
"feather-icons": "^4.28.0",

80
serve.js Normal file
View File

@@ -0,0 +1,80 @@
//
// Launches an Express app that:
//
// - Proxies Stencil's dev server (for HMR)
// - Serves dist/ and docs/ from https://localhost:3000/
// - Launches the Docsify site that reloads when the docs are modified
//
// Usage:
//
// 1. Launch Stencil: `stencil build --dev --docs --watch --serve --no-open`
//
// 2. Launch this script.
//
// Result:
//
// - Changes to components will hot reload
// - Changes to docs will refresh
//
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 proxyPort = 3000;
const browserPort = 4000;
// Proxy Stencil's dev server
app.use(
'/~dev-server',
createProxyMiddleware({
target: 'http://localhost:3333',
changeOrigin: true,
ws: true
})
);
// Inject the dev server iframe into index.html
app.use(/^\/(index.html)?$/, async (req, res, next) => {
let index = await fs.readFile('./docs/index.html', 'utf8');
index = index.replace(
'</body>',
`
<iframe src="/~dev-server" style="display: block; width: 0; height: 0; border: 0;"></iframe>
</body>
`
);
res.type('html').send(index);
});
app.use('/dist', express.static('./dist'));
app.use('/', express.static('./docs'));
app.listen(proxyPort);
// Give the dev server a few seconds to spin up, then launch the browser
setTimeout(() => {
console.log(chalk.cyan(`\nLaunching the Shoelace dev server at http://localhost:${browserPort}! 👟\n`));
bs.init({
startPath: '/',
port: browserPort,
proxy: {
target: `http://localhost:${proxyPort}`,
ws: true
},
logLevel: 'silent',
notify: false,
snippetOptions: {
ignorePaths: '/~dev-server'
}
});
// Reload when docs change
bs.watch('docs/**/*').on('change', async () => {
bs.reload();
});
}, 5000);

108
src/components.d.ts vendored
View File

@@ -26,7 +26,7 @@ export namespace Components {
/**
* The type of alert.
*/
"type": "primary" | "success" | "info" | "warning" | "danger";
"type": 'primary' | 'success' | 'info' | 'warning' | 'danger';
}
interface SlButton {
/**
@@ -60,11 +60,11 @@ export namespace Components {
/**
* The button's size.
*/
"size": "small" | "medium" | "large";
"size": 'small' | 'medium' | 'large';
/**
* The button's type.
*/
"type": "default" | "primary" | "success" | "info" | "warning" | "danger" | "text";
"type": 'default' | 'primary' | 'success' | 'info' | 'warning' | 'danger' | 'text';
}
interface SlCheckbox {
/**
@@ -104,7 +104,7 @@ export namespace Components {
/**
* The format to use for the generated color `value`. If opacity is enabled, these will translate to HEXA, RGBA, and HSLA respectively. Note that browser support for HEXA doesn't include pre-Chromium Edge, so it's usually safer to use RGBA or HSLA when using opacity.
*/
"format": "hex" | "rgb" | "hsl";
"format": 'hex' | 'rgb' | 'hsl';
/**
* Set to true to render the color picker inline rather than inside a dropdown.
*/
@@ -116,7 +116,7 @@ export namespace Components {
/**
* When `inline` is true, this determines the size of the color picker's trigger.
*/
"size": "small" | "medium" | "large";
"size": 'small' | 'medium' | 'large';
/**
* An array of predefined color swatches to display. Can include any format the color picker can parse, including HEX(A), RGB(A), HSL(A), and CSS color names.
*/
@@ -176,7 +176,18 @@ export namespace Components {
/**
* The preferred placement of the dropdown menu. Note that the actual placement may vary as needed to keep the menu inside of the viewport.
*/
"placement": "top" | "top-start" | "top-end" | "bottom" | "bottom-start" | "bottom-end" | "right" | "right-start" | "right-end" | "left" | "left-start" | "left-end";
"placement": | 'top'
| 'top-start'
| 'top-end'
| 'bottom'
| 'bottom-start'
| 'bottom-end'
| 'right'
| 'right-start'
| 'right-end'
| 'left'
| 'left-start'
| 'left-end';
/**
* Shows the dropdown menu
*/
@@ -244,7 +255,7 @@ export namespace Components {
/**
* The input's inputmode attribute.
*/
"inputmode": "none" | "text" | "decimal" | "numeric" | "tel" | "search" | "email" | "url";
"inputmode": 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';
/**
* The input's max attribute.
*/
@@ -296,11 +307,11 @@ export namespace Components {
/**
* Replaces a range of text with a new string.
*/
"setRangeText": (replacement: string, start: number, end: number, selectMode?: SelectionMode) => Promise<void>;
"setRangeText": (replacement: string, start: number, end: number, selectMode?: 'select' | 'start' | 'end' | 'preserve') => Promise<void>;
/**
* Sets the start and end positions of the text selection (0-based).
*/
"setSelectionRange": (selectionStart: number, selectionEnd: number, selectionDirection?: "none" | "forward" | "backward") => Promise<void>;
"setSelectionRange": (selectionStart: number, selectionEnd: number, selectionDirection?: 'forward' | 'backward' | 'none') => Promise<void>;
/**
* The input's size, one of `small`, `medium`, or `large`.
*/
@@ -316,7 +327,7 @@ export namespace Components {
/**
* The input's type, one of `text`, `number`, `email`, etc.
*/
"type": "email" | "number" | "password" | "search" | "tel" | "text" | "url";
"type": 'email' | 'number' | 'password' | 'search' | 'tel' | 'text' | 'url';
/**
* The input's value attribute.
*/
@@ -408,7 +419,7 @@ export namespace Components {
/**
* The preferred placedment of the tooltip.
*/
"tooltipPlacement": "top" | "bottom" | "hidden";
"tooltipPlacement": 'top' | 'bottom' | 'hidden';
/**
* The input's value attribute.
*/
@@ -476,7 +487,7 @@ export namespace Components {
/**
* The placement of the tabs.
*/
"placement": "top" | "bottom" | "left" | "right";
"placement": 'top' | 'bottom' | 'left' | 'right';
/**
* Shows the specified tab panel.
*/
@@ -516,7 +527,7 @@ export namespace Components {
/**
* The textarea's inputmode attribute.
*/
"inputmode": "none" | "text" | "decimal" | "numeric" | "tel" | "search" | "email" | "url";
"inputmode": 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';
/**
* The textarea's maxlength attribute.
*/
@@ -544,7 +555,7 @@ export namespace Components {
/**
* Controls how the textarea can be resized.
*/
"resize": "none" | "vertical" | "auto";
"resize": 'none' | 'vertical' | 'auto';
/**
* The number of rows to display by default.
*/
@@ -560,15 +571,15 @@ export namespace Components {
/**
* Replaces a range of text with a new string.
*/
"setRangeText": (replacement: string, start: number, end: number, selectMode?: SelectionMode) => Promise<void>;
"setRangeText": (replacement: string, start: number, end: number, selectMode?: 'select' | 'start' | 'end' | 'preserve') => Promise<void>;
/**
* Sets the start and end positions of the text selection (0-based).
*/
"setSelectionRange": (selectionStart: number, selectionEnd: number, selectionDirection?: "none" | "forward" | "backward") => Promise<void>;
"setSelectionRange": (selectionStart: number, selectionEnd: number, selectionDirection?: 'forward' | 'backward' | 'none') => Promise<void>;
/**
* The textarea's size.
*/
"size": "small" | "medium" | "large";
"size": 'small' | 'medium' | 'large';
/**
* The textarea's value attribute.
*/
@@ -606,7 +617,18 @@ export namespace Components {
/**
* The preferred placement of the tooltip. Note that the actual placement may vary as needed to keep the tooltip inside of the viewport.
*/
"placement": "top" | "top-start" | "top-end" | "right" | "right-start" | "right-end" | "bottom" | "bottom-start" | "bottom-end" | "left" | "left-start" | "left-end";
"placement": | 'top'
| 'top-start'
| 'top-end'
| 'right'
| 'right-start'
| 'right-end'
| 'bottom'
| 'bottom-start'
| 'bottom-end'
| 'left'
| 'left-start'
| 'left-end';
/**
* Shows the tooltip.
*/
@@ -809,7 +831,7 @@ declare namespace LocalJSX {
/**
* The type of alert.
*/
"type"?: "primary" | "success" | "info" | "warning" | "danger";
"type"?: 'primary' | 'success' | 'info' | 'warning' | 'danger';
}
interface SlButton {
/**
@@ -843,11 +865,11 @@ declare namespace LocalJSX {
/**
* The button's size.
*/
"size"?: "small" | "medium" | "large";
"size"?: 'small' | 'medium' | 'large';
/**
* The button's type.
*/
"type"?: "default" | "primary" | "success" | "info" | "warning" | "danger" | "text";
"type"?: 'default' | 'primary' | 'success' | 'info' | 'warning' | 'danger' | 'text';
}
interface SlCheckbox {
/**
@@ -891,7 +913,7 @@ declare namespace LocalJSX {
/**
* The format to use for the generated color `value`. If opacity is enabled, these will translate to HEXA, RGBA, and HSLA respectively. Note that browser support for HEXA doesn't include pre-Chromium Edge, so it's usually safer to use RGBA or HSLA when using opacity.
*/
"format"?: "hex" | "rgb" | "hsl";
"format"?: 'hex' | 'rgb' | 'hsl';
/**
* Set to true to render the color picker inline rather than inside a dropdown.
*/
@@ -923,7 +945,7 @@ declare namespace LocalJSX {
/**
* When `inline` is true, this determines the size of the color picker's trigger.
*/
"size"?: "small" | "medium" | "large";
"size"?: 'small' | 'medium' | 'large';
/**
* An array of predefined color swatches to display. Can include any format the color picker can parse, including HEX(A), RGB(A), HSL(A), and CSS color names.
*/
@@ -1003,7 +1025,18 @@ declare namespace LocalJSX {
/**
* The preferred placement of the dropdown menu. Note that the actual placement may vary as needed to keep the menu inside of the viewport.
*/
"placement"?: "top" | "top-start" | "top-end" | "bottom" | "bottom-start" | "bottom-end" | "right" | "right-start" | "right-end" | "left" | "left-start" | "left-end";
"placement"?: | 'top'
| 'top-start'
| 'top-end'
| 'bottom'
| 'bottom-start'
| 'bottom-end'
| 'right'
| 'right-start'
| 'right-end'
| 'left'
| 'left-start'
| 'left-end';
}
interface SlDropdownDivider {
}
@@ -1071,7 +1104,7 @@ declare namespace LocalJSX {
/**
* The input's inputmode attribute.
*/
"inputmode"?: "none" | "text" | "decimal" | "numeric" | "tel" | "search" | "email" | "url";
"inputmode"?: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';
/**
* The input's max attribute.
*/
@@ -1139,7 +1172,7 @@ declare namespace LocalJSX {
/**
* The input's type, one of `text`, `number`, `email`, etc.
*/
"type"?: "email" | "number" | "password" | "search" | "tel" | "text" | "url";
"type"?: 'email' | 'number' | 'password' | 'search' | 'tel' | 'text' | 'url';
/**
* The input's value attribute.
*/
@@ -1239,7 +1272,7 @@ declare namespace LocalJSX {
/**
* The preferred placedment of the tooltip.
*/
"tooltipPlacement"?: "top" | "bottom" | "hidden";
"tooltipPlacement"?: 'top' | 'bottom' | 'hidden';
/**
* The input's value attribute.
*/
@@ -1311,7 +1344,7 @@ declare namespace LocalJSX {
/**
* The placement of the tabs.
*/
"placement"?: "top" | "bottom" | "left" | "right";
"placement"?: 'top' | 'bottom' | 'left' | 'right';
}
interface SlTabPanel {
/**
@@ -1347,7 +1380,7 @@ declare namespace LocalJSX {
/**
* The textarea's inputmode attribute.
*/
"inputmode"?: "none" | "text" | "decimal" | "numeric" | "tel" | "search" | "email" | "url";
"inputmode"?: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';
/**
* The textarea's maxlength attribute.
*/
@@ -1387,7 +1420,7 @@ declare namespace LocalJSX {
/**
* Controls how the textarea can be resized.
*/
"resize"?: "none" | "vertical" | "auto";
"resize"?: 'none' | 'vertical' | 'auto';
/**
* The number of rows to display by default.
*/
@@ -1395,7 +1428,7 @@ declare namespace LocalJSX {
/**
* The textarea's size.
*/
"size"?: "small" | "medium" | "large";
"size"?: 'small' | 'medium' | 'large';
/**
* The textarea's value attribute.
*/
@@ -1445,7 +1478,18 @@ declare namespace LocalJSX {
/**
* The preferred placement of the tooltip. Note that the actual placement may vary as needed to keep the tooltip inside of the viewport.
*/
"placement"?: "top" | "top-start" | "top-end" | "right" | "right-start" | "right-end" | "bottom" | "bottom-start" | "bottom-end" | "left" | "left-start" | "left-end";
"placement"?: | 'top'
| 'top-start'
| 'top-end'
| 'right'
| 'right-start'
| 'right-end'
| 'bottom'
| 'bottom-start'
| 'bottom-end'
| 'left'
| 'left-start'
| 'left-end';
/**
* The delay in ms before showing the tooltip.
*/