Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: playgrounds performance improvements #1254

Merged
merged 10 commits into from
Oct 11, 2023
Merged
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -37,6 +37,7 @@ docs/pfe.min.js
docs/bundle.js
docs/core
docs/components
docs/assets/playgrounds
node_modules

core/pfe-sass/docs/index.html
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# Dependencies
node_modules
.wireit
.rollup.cache

# Ignore compiled files in webroot
_site
docs/pfe.min*
docs/assets/playgrounds/

# Build artifacts
elements/*/*.js
15 changes: 15 additions & 0 deletions docs/_plugins/shortcodes/playground.cjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const { readFile } = require('node:fs/promises');
const { join } = require('node:path');

/** @typedef {import('@patternfly/pfe-tools/11ty/DocsPage').DocsPage} DocsPage */

@@ -40,4 +41,18 @@ ${content}

module.exports = function(eleventyConfig) {
eleventyConfig.addPairedShortcode('playground', playground);
eleventyConfig.on('eleventy.before', async function() {
const { rollup } = await import('rollup');
const { importMetaAssets } = await import('@web/rollup-plugin-import-meta-assets');
const { nodeResolve } = await import('@rollup/plugin-node-resolve');
const outdir = join(__dirname, `../../assets/playgrounds/`);
const bundle = await rollup({
input: join(__dirname, 'rh-playground.js'),
plugins: [
nodeResolve(),
importMetaAssets(),
],
});
await bundle.write({ dir: outdir });
});
};
135 changes: 135 additions & 0 deletions docs/_plugins/shortcodes/rh-playground.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { LitElement, html, css } from 'lit';
import { classMap } from 'lit/directives/class-map.js';

import 'playground-elements';
import '@rhds/elements/rh-button/rh-button.js';
import '@rhds/elements/rh-spinner/rh-spinner.js';

class RhPlayground extends LitElement {
static styles = css`
:host {
max-height: 785px;
zeroedin marked this conversation as resolved.
Show resolved Hide resolved
position: relative;
display: block;
}
::slotted(pre) {
margin: 0 !important;
margin-block-end: -36px !important;
}
[hidden],
div.showing {
display: none !important;
}
div {
max-height: 785px;
overflow-y: scroll;
}
rh-button {
position: absolute;
inset-block-end: 5px;
inset-inline-end: 5px;
display: block;
}
rh-spinner {
opacity: 0;
transition: opacity 0.5s ease;
position: sticky;
inset-block: 0 40%;
inset-inline: 41%;
}
.loading rh-spinner {
opacity: 1;
}
.loading ::slotted(pre) {
opacity: .3;
}
playground-project {
display: block;
border: var(--rh-border-width-md, 2px) solid var(--rh-color-border-subtle-on-light, #c7c7c7);
border-radius: var(--rh-border-radius-default, 3px);
overflow: hidden;
}
playground-preview {
resize: vertical;
overflow: hidden;
}
`;

static properties = {
loading: { type: Boolean, state: true },
showing: { type: Boolean, state: true },
tagName: { attribute: 'tag-name' },
};

constructor() {
super();
/** Is the demo code loading? */
this.loading = false;
/** Is the demo displayed? */
this.showing = false;
this.project; // ?: PlaygroundProject | null;
this.tabBar; // ?: PlaygroundTabBar | null;
this.fileEditor; // ?: PlaygroundFileEditor | null;
this.preview; // ?: PlaygroundPreview | null;
}

render() {
const { showing, loading } = this;
return html`
<div id="snippet" class="${classMap({ showing, loading })}">
<slot></slot>
<rh-spinner>Loading demo...</rh-spinner>
</div>
<rh-button ?hidden="${showing}" @click="${this.load}">Load Demo</rh-button>
<playground-project ?hidden="${!showing}">
<playground-tab-bar @click="${this.onChange}"></playground-tab-bar>
<playground-file-editor @click="${this.onChange}" @keydown="${this.onChange}"></playground-file-editor>
<playground-preview></playground-preview>
</playground-project>
`;
}

firstUpdated() {
this.project = this.shadowRoot?.querySelector('playground-project');
this.tabBar = this.shadowRoot?.querySelector('playground-tab-bar');
this.fileEditor = this.shadowRoot?.querySelector('playground-file-editor');
this.preview = this.shadowRoot?.querySelector('playground-preview');
if (this.project && this.tabBar && this.fileEditor && this.preview) {
this.tabBar.project = this.project;
this.fileEditor.project = this.project;
this.preview.project = this.project;
}
}

onChange(event) {
if (event.target === this.tabBar) {
// @ts-expect-error: need a better way to handle this, but works for now
this.switch((event.target)._activeFileName);
} else {
this.switch((event.target).filename);
}
}

switch(filename) {
if (filename && this.preview && this.fileEditor) {
this.preview.htmlFile = filename;
this.fileEditor.filename = filename;
}
}

async load() {
this.loading = true;
this.switch('demo/index.html');
const { configure } = await import(`/assets/playgrounds/${this.tagName}-playground.js`);
configure(this.project);
await import('playground-elements');
this.show();
}

show() {
this.loading = false;
this.showing = true;
}
}

customElements.define('rh-playground', RhPlayground);
Loading