mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-12 12:09:26 +00:00
add fouce utilities
This commit is contained in:
@@ -37,8 +37,30 @@ This snippet includes three parts:
|
||||
|
||||
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.
|
||||
### Reducing FOUCE
|
||||
|
||||
While convenient, autoloading can lead to a [Flash of Undefined Custom Elements](https://www.abeautifulsite.net/posts/flash-of-undefined-custom-elements/). To prevent this, you can add the `wa-reduce-fouce` class to any element on the page. Make sure to include the [FOUCE style utility](/docs/utilities/fouce/#opting-in) to get the corresponding CSS.
|
||||
|
||||
```html
|
||||
<html class="wa-reduce-fouce">
|
||||
...
|
||||
</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();
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
@@ -18,3 +18,8 @@
|
||||
animation: var(--wa-fouce-animation);
|
||||
}
|
||||
}
|
||||
|
||||
/* An opt in utility that hides any container with this class until the autoloader removes it */
|
||||
.wa-reduce-fouce {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,12 @@ export async function discover(root: Element | ShadowRoot) {
|
||||
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,19 @@ function register(tagName: string): Promise<void> {
|
||||
import(path).then(() => resolve()).catch(() => reject(new Error(`Unable to autoload <${tagName}> from ${path}`)));
|
||||
});
|
||||
}
|
||||
|
||||
/** TODO */
|
||||
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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,3 +3,15 @@ import { startLoader } from './webawesome.js';
|
||||
export * from './webawesome.js';
|
||||
|
||||
startLoader();
|
||||
|
||||
// Remove the `wa-reduce-fouce` class from all elements that have it after the autoloader finishes discovering the page
|
||||
// OR two seconds. This helps reduce FOUCE by letting users opt in to hiding containers (or the entire page) until the
|
||||
// components are ready.
|
||||
Promise.race([
|
||||
new Promise(resolve => document.addEventListener('wa-discovery-complete', resolve)),
|
||||
new Promise(resolve => setTimeout(resolve, 2000)),
|
||||
]).then(() => {
|
||||
document.querySelectorAll('.wa-reduce-fouce').forEach(el => {
|
||||
el.classList.remove('wa-reduce-fouce');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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 { registerTranslation } from './utilities/localize.js';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user