mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-19 07:29:14 +00:00
Compare commits
22 Commits
subcompone
...
fouce-clas
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bcb139dcc1 | ||
|
|
c66f241215 | ||
|
|
4ea92905e8 | ||
|
|
c64a1754d7 | ||
|
|
a2f4197098 | ||
|
|
b0cf8bffa8 | ||
|
|
65df1416dd | ||
|
|
d271929e50 | ||
|
|
70b486fa96 | ||
|
|
884e11c6d7 | ||
|
|
c0f558f52a | ||
|
|
af96d869ee | ||
|
|
d626d2c693 | ||
|
|
96013f2d55 | ||
|
|
0fcc9390f6 | ||
|
|
2a488d28b0 | ||
|
|
bcc1ccaa1c | ||
|
|
aa3cd97dde | ||
|
|
16c5489f7a | ||
|
|
02d0c1be75 | ||
|
|
db08435739 | ||
|
|
72a6d8544d |
9
.github/workflows/ssr_tests.js.yml
vendored
9
.github/workflows/ssr_tests.js.yml
vendored
@@ -1,11 +1,12 @@
|
|||||||
# # This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
|
# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
|
||||||
# # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
||||||
|
|
||||||
name: SSR Tests
|
name: SSR Tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
# push:
|
||||||
branches: [next]
|
# branches: [next]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
ssr_test:
|
ssr_test:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" data-fa-kit-code="b10bfbde90" data-cdn-url="{% cdnUrl %}">
|
<html lang="en" data-fa-kit-code="b10bfbde90" data-cdn-url="{% cdnUrl %}" class="wa-cloak">
|
||||||
<head>
|
<head>
|
||||||
{% include 'head.njk' %}
|
{% include 'head.njk' %}
|
||||||
<meta name="theme-color" content="#f36944">
|
<meta name="theme-color" content="#f36944">
|
||||||
|
|||||||
@@ -23,10 +23,9 @@
|
|||||||
<script src="/assets/scripts/hydration-errors.js"></script>
|
<script src="/assets/scripts/hydration-errors.js"></script>
|
||||||
<link rel="stylesheet" href="/assets/styles/hydration-errors.css">
|
<link rel="stylesheet" href="/assets/styles/hydration-errors.css">
|
||||||
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
||||||
<script type="module" src="https://cdn.jsdelivr.net/npm/@hotwired/turbo@8.0.10/+esm"></script>
|
|
||||||
|
|
||||||
{# Web Awesome #}
|
{# Web Awesome #}
|
||||||
<script type="module" src="/dist/webawesome.ssr-loader.js"></script>
|
<script type="module" src="/dist/webawesome.loader.js"></script>
|
||||||
|
|
||||||
<script type="module" src="/assets/scripts/theme-picker.js"></script>
|
<script type="module" src="/assets/scripts/theme-picker.js"></script>
|
||||||
{# Preset Theme #}
|
{# Preset Theme #}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
import 'https://cdn.jsdelivr.net/npm/@hotwired/turbo@8.0.10/+esm';
|
||||||
|
import { preventTurboFouce } from '/dist/webawesome.js';
|
||||||
|
|
||||||
if (!window.___turboScrollPositions___) {
|
if (!window.___turboScrollPositions___) {
|
||||||
window.___turboScrollPositions___ = {};
|
window.___turboScrollPositions___ = {};
|
||||||
}
|
}
|
||||||
@@ -70,3 +73,4 @@ function fixDSD(e) {
|
|||||||
window.addEventListener('turbo:before-cache', saveScrollPosition);
|
window.addEventListener('turbo:before-cache', saveScrollPosition);
|
||||||
window.addEventListener('turbo:before-render', restoreScrollPosition);
|
window.addEventListener('turbo:before-render', restoreScrollPosition);
|
||||||
window.addEventListener('turbo:render', restoreScrollPosition);
|
window.addEventListener('turbo:render', restoreScrollPosition);
|
||||||
|
preventTurboFouce();
|
||||||
|
|||||||
@@ -37,10 +37,6 @@ This snippet includes three parts:
|
|||||||
|
|
||||||
Now you can [start using Web Awesome!](/docs/usage)
|
Now you can [start using Web Awesome!](/docs/usage)
|
||||||
|
|
||||||
:::info
|
|
||||||
While convenient, autoloading may lead to a [Flash of Undefined Custom Elements](https://www.abeautifulsite.net/posts/flash-of-undefined-custom-elements/). The linked article describes some ways to alleviate it.
|
|
||||||
:::
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Using Font Awesome Kit Codes
|
## Using Font Awesome Kit Codes
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ During the alpha period, things might break! We take breaking changes very serio
|
|||||||
|
|
||||||
## Next
|
## Next
|
||||||
|
|
||||||
|
- Added the `wa-cloak` utility to prevent FOUCE
|
||||||
|
- Added the `allDefined()` utility for awaiting component registration
|
||||||
- Fixed `wa-pill` class for text fields
|
- Fixed `wa-pill` class for text fields
|
||||||
- Fixed `pill` style for `<wa-input>` elements
|
- Fixed `pill` style for `<wa-input>` elements
|
||||||
- Fixed a bug in `<wa-color-picker>` that prevented light dismiss from working when clicking immediately above the color picker dropdown
|
- Fixed a bug in `<wa-color-picker>` that prevented light dismiss from working when clicking immediately above the color picker dropdown
|
||||||
|
|||||||
@@ -8,6 +8,30 @@ Web Awesome components are just regular HTML elements, or [custom elements](http
|
|||||||
|
|
||||||
If you're new to custom elements, often referred to as "web components," this section will familiarize you with how to use them.
|
If you're new to custom elements, often referred to as "web components," this section will familiarize you with how to use them.
|
||||||
|
|
||||||
|
## Awaiting Registration
|
||||||
|
|
||||||
|
Unlike traditional frameworks, custom elements don't have a centralized initialization phase. This means you need to verify that a custom element has been properly registered before attempting to interact with its properties or methods.
|
||||||
|
|
||||||
|
You can use the [`customElements.whenDefined()`](https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/whenDefined) method to ensure a specific component is ready:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
await customElements.whenDefined('wa-button');
|
||||||
|
|
||||||
|
// <wa-button> is ready to use!
|
||||||
|
const button = document.querySelector('wa-button');
|
||||||
|
```
|
||||||
|
|
||||||
|
When working with multiple components, checking each one individually can become tedious. For convenience, Web Awesome provides the `allDefined()` function which automatically detects and waits for all Web Awesome components in the DOM to be initialized before resolving.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { allDefined } from '/dist/webawesome.js';
|
||||||
|
|
||||||
|
// Waits for all Web Awesome components in the DOM to be registered
|
||||||
|
await allDefined();
|
||||||
|
|
||||||
|
// All Web Awesome components on the page are ready!
|
||||||
|
```
|
||||||
|
|
||||||
## Attributes & Properties
|
## Attributes & Properties
|
||||||
|
|
||||||
Many components have properties that can be set using attributes. For example, buttons accept a `size` attribute that maps to the `size` property which dictates the button's size.
|
Many components have properties that can be set using attributes. For example, buttons accept a `size` attribute that maps to the `size` property which dictates the button's size.
|
||||||
|
|||||||
32
docs/docs/utilities/fouce.md
Normal file
32
docs/docs/utilities/fouce.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
title: Reduce FOUCE
|
||||||
|
description: Utility to improve the loading experience by hiding non-prerendered custom elements until they are registered.
|
||||||
|
file: styles/utilities/fouce.css
|
||||||
|
icon: spinner
|
||||||
|
---
|
||||||
|
|
||||||
|
While convenient, autoloading can lead to a [Flash of Undefined Custom Elements](https://www.abeautifulsite.net/posts/flash-of-undefined-custom-elements/).
|
||||||
|
The [FOUCE style utility](/docs/utilities/fouce/#opting-in) (which is automatically applied if you use the [Web Awesome utilities](/docs/utilities/)) takes care of hiding custom elements until they and their contents have been registered, up to a maximum of two seconds.
|
||||||
|
|
||||||
|
In many cases, this is not enough, and you may wish to hide a broader wrapper element or even the entire page until all WA elements within it have loaded. To do that, you can add the `wa-reduce-fouce` class to any element on the page or even apply it to the whole page by placing the class on the `<html>` element.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<html class="wa-cloak">
|
||||||
|
...
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
As soon as all elements are registered _or_ after two seconds have elapsed, the autoloader will show the page. The two-second timeout prevents blank screens from persisting on slow networks and pages that have errors.
|
||||||
|
|
||||||
|
:::details Are you using Turbo in your app?
|
||||||
|
|
||||||
|
If you're using [Turbo](https://turbo.hotwired.dev/) to serve a multi-page application (MPA) as a single page application (SPA), you might notice FOUCE when navigating from page to page. This is because Turbo renders the new page's content before the autoloader has a change to register new components.
|
||||||
|
|
||||||
|
The following function acts as a middleware to ensure components are registered _before_ the page shows, eliminating FOUCE for page-to-page navigation with Turbo.
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { preventTurboFouce } from '/dist/webawesome.js';
|
||||||
|
|
||||||
|
preventTurboFouce();
|
||||||
|
```
|
||||||
|
:::
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
---
|
|
||||||
title: Reduce FOUCE
|
|
||||||
description: Utility to improve the loading experience by hiding non-prerendered custom elements until they are registered.
|
|
||||||
file: styles/utilities/fouce.css
|
|
||||||
icon: spinner
|
|
||||||
---
|
|
||||||
{% markdown %}
|
|
||||||
No class is needed to use this utility, it will be applied automatically as long as it its CSS is included.
|
|
||||||
|
|
||||||
Here is a comparison of the loading experience with and without this utility,
|
|
||||||
with a simulated slow loading time:
|
|
||||||
|
|
||||||
{% endmarkdown %}
|
|
||||||
|
|
||||||
|
|
||||||
<div class="wa-split wa-align-items-end">
|
|
||||||
<strong>Normal loading</strong>
|
|
||||||
<wa-button onclick="document.querySelectorAll('iframe').forEach(iframe => iframe.srcdoc = iframe.srcdoc)">
|
|
||||||
<wa-icon name="refresh"></wa-icon>
|
|
||||||
Refresh
|
|
||||||
</wa-button>
|
|
||||||
<strong>With FOUCE reduction</strong>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{% set sample_card %}
|
|
||||||
<link id="theme-stylesheet" rel="stylesheet" href="/dist/styles/themes/default.css" render="blocking" fetchpriority="high">
|
|
||||||
<link rel="stylesheet" href="/dist/styles/webawesome.css">
|
|
||||||
<link rel="stylesheet" href="/dist/styles/forms.css">
|
|
||||||
<script type=module>
|
|
||||||
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
||||||
const loadScript = src => new Promise((resolve, reject) => {
|
|
||||||
const script = document.createElement("script");
|
|
||||||
script.src = src;
|
|
||||||
script.type = "module";
|
|
||||||
script.onload = resolve;
|
|
||||||
script.onerror = reject;
|
|
||||||
document.head.appendChild(script);
|
|
||||||
});
|
|
||||||
|
|
||||||
await delay(500);
|
|
||||||
await loadScript("/dist/components/button/button.js");
|
|
||||||
await delay(500);
|
|
||||||
await loadScript("/dist/components/card/card.js");
|
|
||||||
await delay(500);
|
|
||||||
await loadScript("/dist/components/rating/rating.js");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<wa-card with-footer with-image class="card-overview">
|
|
||||||
<img
|
|
||||||
slot="image"
|
|
||||||
src="https://images.unsplash.com/photo-1559209172-0ff8f6d49ff7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=80"
|
|
||||||
alt="A kitten sits patiently between a terracotta pot and decorative grasses."
|
|
||||||
/>
|
|
||||||
|
|
||||||
<strong>Mittens</strong><br />
|
|
||||||
This kitten is as cute as he is playful. Bring him home today!<br />
|
|
||||||
<small>6 weeks old</small>
|
|
||||||
|
|
||||||
<div slot="footer">
|
|
||||||
<wa-button variant="brand" pill>More Info</wa-button>
|
|
||||||
<wa-rating></wa-rating>
|
|
||||||
</div>
|
|
||||||
</wa-card>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.card-overview small {
|
|
||||||
color: var(--wa-color-text-quiet);
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-overview [slot=footer] {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endset %}
|
|
||||||
|
|
||||||
|
|
||||||
<div class="iframes">
|
|
||||||
<iframe srcdoc='<body class="wa-fouce-off">{{ sample_card }}</body>'></iframe>
|
|
||||||
<iframe srcdoc='{{ sample_card }}'></iframe>
|
|
||||||
</div>
|
|
||||||
<style>
|
|
||||||
.iframes {
|
|
||||||
display: flex;
|
|
||||||
gap: var(--wa-space-m);
|
|
||||||
margin-top: var(--wa-space-l);
|
|
||||||
|
|
||||||
iframe {
|
|
||||||
flex: 1;
|
|
||||||
height: 60ch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
{% markdown %}
|
|
||||||
## How does it work?
|
|
||||||
|
|
||||||
The utility consists of a timeout (`2s` by default) and a fade duration (`200ms` by default).
|
|
||||||
- If the element is _ready_ before the timeout, it will appear immediately.
|
|
||||||
- If it takes longer than _timeout_ + _fade_, it will fade in over the fade duration.
|
|
||||||
- If it takes somewhere between _timeout_ and _timeout_ + _fade_, you will get an interrupted fade.
|
|
||||||
|
|
||||||
An element is considered ready when both of these are true:
|
|
||||||
1. Either It has been registered or has a `did-ssr` attribute (indicating it was pre-rendered)
|
|
||||||
2. If it’s a Web Awesome component, its contents are also ready
|
|
||||||
|
|
||||||
## Customization
|
|
||||||
|
|
||||||
You can use the following CSS variables to customize the behavior:
|
|
||||||
|
|
||||||
| Variable | Description | Default |
|
|
||||||
| --- | --- | --- |
|
|
||||||
| `--wa-fouce-fade` | The transition duration for the fade effect. | `200ms` |
|
|
||||||
| `--wa-fouce-timeout` | The timeout after which elements will appear even if not registered | `2s` |
|
|
||||||
|
|
||||||
The fade duration cannot be longer than the timeout.
|
|
||||||
This means that you can disable FOUCE reduction on an element by setting `--wa-fouce-timeout: 0s`.
|
|
||||||
|
|
||||||
For example, if instead of `did-ssr` you used an `ssr` attribute to mark elements that were pre-rendered, you can do this to get them to appear immediately:
|
|
||||||
|
|
||||||
```css
|
|
||||||
[ssr] {
|
|
||||||
--wa-fouce-timeout: 0s;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also opt-out from FOUCE reduction for an element and its contents by adding the `.wa-fouce-off` class to it.
|
|
||||||
Applying this class to the root element will disable the utility for the entire page.
|
|
||||||
{% endmarkdown %}
|
|
||||||
@@ -1,20 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* Utility to minimize FOUCE and show custom elements only after they're registered
|
* Utility to minimize FOUCE and show custom elements only after they're registered
|
||||||
*/
|
*/
|
||||||
|
:not(:defined),
|
||||||
|
:state(wa-defined):has(:not(:defined)),
|
||||||
|
.wa-cloak:has(:not(:defined)) {
|
||||||
|
animation: 2s step-end wa-fouce-cloak;
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes wa-fade-in {
|
@keyframes wa-fouce-cloak {
|
||||||
from {
|
from {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
to {
|
||||||
|
opacity: 1;
|
||||||
:not(:defined),
|
|
||||||
:state(wa-defined):has(:not(:defined)) {
|
|
||||||
/* The clamp() ensures that if --wa-fouce-timeout is set to 0s, the whole effect is disabled */
|
|
||||||
--wa-fouce-animation: clamp(0s, var(--wa-fouce-fade, 200ms), var(--wa-fouce-timeout, 2s)) var(--wa-fouce-timeout, 2s)
|
|
||||||
wa-fade-in both;
|
|
||||||
|
|
||||||
&:where(:not([did-ssr], .wa-fouce-off, .wa-fouce-off *)) {
|
|
||||||
animation: var(--wa-fouce-animation);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,12 @@ export async function discover(root: Element | ShadowRoot) {
|
|||||||
console.warn(imp.reason); // eslint-disable-line no-console
|
console.warn(imp.reason); // eslint-disable-line no-console
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wait a cycle to allow the first Lit update to run
|
||||||
|
await new Promise(requestAnimationFrame);
|
||||||
|
|
||||||
|
// Dispatch an event when discovery is complete.
|
||||||
|
document.dispatchEvent(new CustomEvent('wa-discovery-complete'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,3 +75,22 @@ function register(tagName: string): Promise<void> {
|
|||||||
import(path).then(() => resolve()).catch(() => reject(new Error(`Unable to autoload <${tagName}> from ${path}`)));
|
import(path).then(() => resolve()).catch(() => reject(new Error(`Unable to autoload <${tagName}> from ${path}`)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acts as a middleware for Turbo's `turbo:before-render` event to ensure components are auto-loaded before showing the
|
||||||
|
* next page, eliminating page-to-page FOUCE in a Turbo environment.
|
||||||
|
*/
|
||||||
|
export function preventTurboFouce(timeout = 2000) {
|
||||||
|
document.addEventListener('turbo:before-render', async (event: CustomEvent) => {
|
||||||
|
const newBody = event.detail.newBody;
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Wait until all elements are registered or two seconds, whichever comes first
|
||||||
|
await Promise.race([discover(newBody), new Promise(resolve => setTimeout(resolve, timeout))]);
|
||||||
|
} finally {
|
||||||
|
event.detail.resume();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
64
src/utilities/defined.ts
Normal file
64
src/utilities/defined.ts
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
interface AllDefinedOptions {
|
||||||
|
/**
|
||||||
|
* A callback that accepts a custom element tag name and returns `true` if the custom element should be defined before
|
||||||
|
* resolving or `false` to skip it. The tag name is always in lowercase.
|
||||||
|
*/
|
||||||
|
match: (tagName: string) => boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To wait for additional custom elements that may not be on the page when the function is called, provide them here.
|
||||||
|
*/
|
||||||
|
additionalElements: string | string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The root in which to look for custom elements. Defaults to `document`. By design, shadow roots are not traversed,
|
||||||
|
* but you can call this function and set `root` to a custom element's shadow root if needed.
|
||||||
|
*/
|
||||||
|
root: Document | ShadowRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Waits for custom elements that are currently on the page to be registered before resolving. This is sugar for
|
||||||
|
* awaiting `customElements.whenDefined()` multiple times. By default, the function waits for all undefined Web Awesome
|
||||||
|
* elements, but you can pass a custom match function to wait for other custom elements instead.
|
||||||
|
*
|
||||||
|
* The function returns with `Promise.all()`, so any loading errors will cause it to reject. Make sure you handle errors
|
||||||
|
* accordingly using a try/catch block or a `.catch()`.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* // Wait for Web Awesome elements
|
||||||
|
* await allDefined();
|
||||||
|
*
|
||||||
|
* // Wait for all custom elements that start with `foo-` as well as the `<bar-button>` element
|
||||||
|
* await allDefined({
|
||||||
|
* match: tagName => tagName.startsWith('foo-'),
|
||||||
|
* additionalElements: ['bar-button', 'baz-dialog']
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export async function allDefined(options?: Partial<AllDefinedOptions>) {
|
||||||
|
const opts: AllDefinedOptions = {
|
||||||
|
match: tagName => tagName.startsWith('wa-'),
|
||||||
|
additionalElements: [],
|
||||||
|
root: document,
|
||||||
|
...options,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Ensure additional elements is an array
|
||||||
|
const additionalElements = Array.isArray(opts.additionalElements)
|
||||||
|
? opts.additionalElements
|
||||||
|
: [opts.additionalElements];
|
||||||
|
|
||||||
|
// Discover undefined elements in the document
|
||||||
|
const undefinedElements = [...opts.root.querySelectorAll(':not(:defined)')]
|
||||||
|
.map(el => el.localName)
|
||||||
|
.filter((tag, index, arr) => arr.indexOf(tag) === index) // make it unique
|
||||||
|
.filter(tag => opts.match(tag)); // make sure it matches
|
||||||
|
|
||||||
|
const tagsToAwait = [...undefinedElements, ...additionalElements];
|
||||||
|
|
||||||
|
// Wait for all to be registered
|
||||||
|
await Promise.all(tagsToAwait.map(tag => customElements.whenDefined(tag)));
|
||||||
|
|
||||||
|
// Wait a cycle for the first update
|
||||||
|
await new Promise(requestAnimationFrame);
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
export { registerIconLibrary, unregisterIconLibrary } from './components/icon/library.js';
|
export { registerIconLibrary, unregisterIconLibrary } from './components/icon/library.js';
|
||||||
export { discover, startLoader, stopLoader } from './utilities/autoloader.js';
|
export { discover, preventTurboFouce, startLoader, stopLoader } from './utilities/autoloader.js';
|
||||||
export { getBasePath, getKitCode, setBasePath, setKitCode } from './utilities/base-path.js';
|
export { getBasePath, getKitCode, setBasePath, setKitCode } from './utilities/base-path.js';
|
||||||
|
export { allDefined } from './utilities/defined.js';
|
||||||
export { registerTranslation } from './utilities/localize.js';
|
export { registerTranslation } from './utilities/localize.js';
|
||||||
|
|
||||||
// Utilities
|
// Utilities
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { litSsrPlugin } from '@lit-labs/testing/web-test-runner-ssr-plugin.js';
|
|
||||||
import { esbuildPlugin } from '@web/dev-server-esbuild';
|
import { esbuildPlugin } from '@web/dev-server-esbuild';
|
||||||
import { playwrightLauncher } from '@web/test-runner-playwright';
|
import { playwrightLauncher } from '@web/test-runner-playwright';
|
||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
@@ -53,7 +52,6 @@ export default {
|
|||||||
ts: true,
|
ts: true,
|
||||||
target: 'es2020',
|
target: 'es2020',
|
||||||
}),
|
}),
|
||||||
litSsrPlugin(),
|
|
||||||
],
|
],
|
||||||
browsers: [
|
browsers: [
|
||||||
playwrightLauncher({ product: 'chromium', concurrency }),
|
playwrightLauncher({ product: 'chromium', concurrency }),
|
||||||
@@ -78,12 +76,10 @@ export default {
|
|||||||
${componentImports.map(str => `"${str}"`).join(',\n')}
|
${componentImports.map(str => `"${str}"`).join(',\n')}
|
||||||
]
|
]
|
||||||
|
|
||||||
window.SSR_ONLY = ${process.env['SSR_ONLY'] === 'true'}
|
|
||||||
window.CSR_ONLY = ${process.env['CSR_ONLY'] === 'true'}
|
window.CSR_ONLY = ${process.env['CSR_ONLY'] === 'true'}
|
||||||
</script>
|
</script>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
;(async () => {
|
;(async () => {
|
||||||
await import('@lit-labs/ssr-client/lit-element-hydrate-support.js')
|
|
||||||
await Promise.allSettled(window.clientComponents.map(str => import(str)));
|
await Promise.allSettled(window.clientComponents.map(str => import(str)));
|
||||||
})()
|
})()
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user