diff --git a/docs/pages/examples.md b/docs/pages/examples.md
index 7dcf17f..d366dc5 100644
--- a/docs/pages/examples.md
+++ b/docs/pages/examples.md
@@ -116,6 +116,41 @@ class Layout extends HTMLElement {
export default Layout;
```
+## HTML (Light DOM) Web Components
+
+As detailed in this excellent blog post, HTML Web Components are a strategy for transcluding content into the Light DOM of a custom element instead of (or in addition to) setting attributes. This can be useful for providing a set of styles to a block of content.
+
+So instead of setting attributes:
+
+```html
+
+```
+
+Pass HTML as children:
+
+```html
+
+
My Image
+
+
+```
+
+With a custom element definition like so:
+
+```js
+export default class PictureFrame extends HTMLElement {
+ connectedCallback() {
+ this.innerHTML = `
+
+ ${this.innerHTML}
+
+ `;
+ }
+}
+
+customElements.define('picture-frame', PictureFrame);
+```
+
## Progressive Hydration
Using the `metadata` information from a custom element with the `hydrate=true` attribute, you can use use the metadata with an [`IntersectionObserver`](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) to progressively load a custom element. In this case, _handler.js_ builds `SliderComponent` from HTML and not only uses the `hydrate` attribute and metadata for lazy hydration, but also passes in the animated color via a CSS custom property set at build time! 🤯
diff --git a/sandbox/components/card.js b/sandbox/components/card.js
index d2c05ae..a3dfe39 100644
--- a/sandbox/components/card.js
+++ b/sandbox/components/card.js
@@ -15,6 +15,7 @@ export default class Card extends HTMLElement {
:host .card {
width: 30%;
margin: 0 auto;
+ text-align: center;
}
:host h3 {
@@ -28,7 +29,7 @@ export default class Card extends HTMLElement {
+ `;
+ }
+}
\ No newline at end of file
diff --git a/test/cases/no-define/no-define.spec.js b/test/cases/no-define/no-define.spec.js
new file mode 100644
index 0000000..599b00b
--- /dev/null
+++ b/test/cases/no-define/no-define.spec.js
@@ -0,0 +1,80 @@
+/*
+ * Use Case
+ * Run wcc against a single custom element using with no customElements.define
+ *
+ * User Result
+ * Should run without any errors from the DOM shim.
+ *
+ * User Workspace
+ * src/
+ * no-define.js
+ * footer.js
+ * header.js
+ */
+
+import chai from 'chai';
+import { renderToString, renderFromHTML } from '../../../src/wcc.js';
+
+const expect = chai.expect;
+
+describe('Run WCC For ', function() {
+ const LABEL = 'Single Custom Element with no customElements.define';
+
+ describe(LABEL, function() {
+ describe('renderToString', () => {
+ let rawHtml;
+ let meta;
+
+ before(async function() {
+ const { html, metadata } = await renderToString(new URL('./src/no-define.js', import.meta.url));
+
+ rawHtml = html;
+ meta = metadata;
+ });
+
+ it('should not throw an error', function() {
+ expect(rawHtml).to.equal(undefined);
+ });
+
+ it('should not have any definition', function() {
+ expect(meta.length).to.equal(0);
+ });
+ });
+
+ describe('renderFromHTML', () => {
+ let rawHtml;
+ let meta;
+ const contents = `
+
+
+ No Export Test
+
+
+
+
Hello World
+
+
+
+ `;
+
+ before(async function() {
+ const { html, metadata } = await renderFromHTML(contents, [
+ new URL('./src/footer.js', import.meta.url),
+ new URL('./src/header.js', import.meta.url)
+ ]);
+
+ rawHtml = html;
+ meta = metadata;
+ });
+
+ it('should not throw an error and return the expected contents', function() {
+ expect(rawHtml.replace(/ /g, '').replace(/\n/g, '')).to.equal(contents.replace(/ /g, '').replace(/\n/g, ''));
+ });
+
+ // I think this is broken, should actually be equal to 2?
+ it('should not have any definition', function() {
+ expect(meta.length).to.equal(0);
+ });
+ });
+ });
+});
\ No newline at end of file
diff --git a/test/cases/no-define/src/footer.js b/test/cases/no-define/src/footer.js
new file mode 100644
index 0000000..9763459
--- /dev/null
+++ b/test/cases/no-define/src/footer.js
@@ -0,0 +1,16 @@
+const template = document.createElement('template');
+
+template.innerHTML = '';
+
+class FooterComponent extends HTMLElement {
+ constructor() {
+ super();
+ this.attachShadow({ mode: 'open' });
+ }
+
+ connectedCallback() {
+ this.shadowRoot.appendChild(template.content.cloneNode(true));
+ }
+}
+
+customElements.define('app-no-define-footer', FooterComponent);
\ No newline at end of file
diff --git a/test/cases/no-define/src/header.js b/test/cases/no-define/src/header.js
new file mode 100644
index 0000000..cc0b9ee
--- /dev/null
+++ b/test/cases/no-define/src/header.js
@@ -0,0 +1,18 @@
+const template = document.createElement('template');
+
+template.innerHTML = `
+ This is the header component.
+`;
+
+class HeaderComponent extends HTMLElement {
+ constructor() {
+ super();
+ this.attachShadow({ mode: 'open' });
+ }
+
+ connectedCallback() {
+ this.shadowRoot.appendChild(template.content.cloneNode(true));
+ }
+}
+
+customElements.define('app-no-define-header', HeaderComponent);
\ No newline at end of file
diff --git a/test/cases/no-define/src/no-define.js b/test/cases/no-define/src/no-define.js
new file mode 100644
index 0000000..a00f0f5
--- /dev/null
+++ b/test/cases/no-define/src/no-define.js
@@ -0,0 +1,15 @@
+const template = document.createElement('template');
+
+template.innerHTML = '
This is the NoDefineComponent component.
';
+
+// eslint-disable-next-line no-unused-vars
+class NoDefineComponent extends HTMLElement {
+ constructor() {
+ super();
+ this.attachShadow({ mode: 'open' });
+ }
+
+ connectedCallback() {
+ this.shadowRoot.appendChild(template.content.cloneNode(true));
+ }
+}
\ No newline at end of file
diff --git a/test/cases/no-export/no-export.spec.js b/test/cases/no-export/no-export.spec.js
index d3257ca..1629f9d 100644
--- a/test/cases/no-export/no-export.spec.js
+++ b/test/cases/no-export/no-export.spec.js
@@ -1,40 +1,80 @@
/*
* Use Case
- * Run wcc against a single custom element using with no internal definitions
+ * Run wcc against a single custom element using with no default export
*
* User Result
* Should run without any errors from the DOM shim.
*
* User Workspace
* src/
- * empty.js
+ * no-export.js
+ * header.js
+ * footer.js
*/
import chai from 'chai';
-import { renderToString } from '../../../src/wcc.js';
+import { renderToString, renderFromHTML } from '../../../src/wcc.js';
const expect = chai.expect;
describe('Run WCC For ', function() {
const LABEL = 'Single Custom Element with no default export';
- let rawHtml;
- let meta;
-
- before(async function() {
- const { html, metadata } = await renderToString(new URL('./src/no-export.js', import.meta.url));
-
- rawHtml = html;
- meta = metadata;
- });
describe(LABEL, function() {
- it('should not throw an error', function() {
- expect(rawHtml).to.equal(undefined);
+ describe('renderToString', () => {
+ let rawHtml;
+ let meta;
+
+ before(async function() {
+ const { html, metadata } = await renderToString(new URL('./src/no-export.js', import.meta.url));
+
+ rawHtml = html;
+ meta = metadata;
+ });
+
+ it('should not throw an error', function() {
+ expect(rawHtml).to.equal(undefined);
+ });
+
+ it('should not have any definition', function() {
+ expect(meta.length).to.equal(0);
+ });
});
+
+ describe('renderFromHTML', () => {
+ let rawHtml;
+ let meta;
+ const contents = `
+
+
+ No Export Test
+
+
+
+
Hello World
+
+
+
+ `;
- it('should not have any definition', function() {
- expect(meta.length).to.equal(0);
+ before(async function() {
+ const { html, metadata } = await renderFromHTML(contents, [
+ new URL('./src/footer.js', import.meta.url),
+ new URL('./src/header.js', import.meta.url)
+ ]);
+
+ rawHtml = html;
+ meta = metadata;
+ });
+
+ it('should not throw an error and return the expected contents', function() {
+ expect(rawHtml.replace(/ /g, '').replace(/\n/g, '')).to.equal(contents.replace(/ /g, '').replace(/\n/g, ''));
+ });
+
+ // I think this is broken, should actually be equal to 2?
+ it('should not have any definition', function() {
+ expect(meta.length).to.equal(0);
+ });
});
});
-
});
\ No newline at end of file
diff --git a/test/cases/no-export/src/footer.js b/test/cases/no-export/src/footer.js
new file mode 100644
index 0000000..5d86479
--- /dev/null
+++ b/test/cases/no-export/src/footer.js
@@ -0,0 +1,16 @@
+const template = document.createElement('template');
+
+template.innerHTML = '';
+
+class FooterComponent extends HTMLElement {
+ constructor() {
+ super();
+ this.attachShadow({ mode: 'open' });
+ }
+
+ connectedCallback() {
+ this.shadowRoot.appendChild(template.content.cloneNode(true));
+ }
+}
+
+customElements.define('app-no-export-footer', FooterComponent);
\ No newline at end of file
diff --git a/test/cases/no-export/src/header.js b/test/cases/no-export/src/header.js
new file mode 100644
index 0000000..3ee4ab5
--- /dev/null
+++ b/test/cases/no-export/src/header.js
@@ -0,0 +1,18 @@
+const template = document.createElement('template');
+
+template.innerHTML = `
+ This is the header component.
+`;
+
+class HeaderComponent extends HTMLElement {
+ constructor() {
+ super();
+ this.attachShadow({ mode: 'open' });
+ }
+
+ connectedCallback() {
+ this.shadowRoot.appendChild(template.content.cloneNode(true));
+ }
+}
+
+customElements.define('app-no-export-header', HeaderComponent);
\ No newline at end of file
diff --git a/test/cases/no-export/src/no-export.js b/test/cases/no-export/src/no-export.js
index 6a6222f..2caeda7 100644
--- a/test/cases/no-export/src/no-export.js
+++ b/test/cases/no-export/src/no-export.js
@@ -1,2 +1,17 @@
+const template = document.createElement('template');
+
+template.innerHTML = '
This is the NoExportComponent component.
';
+
// eslint-disable-next-line no-unused-vars
-class EmptyComponent extends HTMLElement { }
\ No newline at end of file
+class NoExportComponent extends HTMLElement {
+ constructor() {
+ super();
+ this.attachShadow({ mode: 'open' });
+ }
+
+ connectedCallback() {
+ this.shadowRoot.appendChild(template.content.cloneNode(true));
+ }
+}
+
+customElements.define('app-no-export-example', NoExportComponent);
\ No newline at end of file