Skip to content

Instantly share code, notes, and snippets.

@mattkenefick
Created August 10, 2021 22:20
Show Gist options
  • Save mattkenefick/4ef278edfcb24fd51ef102a8d0e6ecb0 to your computer and use it in GitHub Desktop.
Save mattkenefick/4ef278edfcb24fd51ef102a8d0e6ecb0 to your computer and use it in GitHub Desktop.
/**
* Attempt to attach template over the network.
* It attempts to derive an HTML tag from the filename,
* but we could do anything here.
*
* @param string filename
*/
static async attachRemote(filename) {
const filenameMatches = filename.match(/\/([^\.\/]+)\.html/i);
if (filenameMatches) {
const id = filenameMatches[1];
const response = await fetch(filename);
const text = await response.text();
const fragment = document.createElement('template');
fragment.innerHTML = text;
fragment.id = id;
this.attach(fragment);
}
}
<!DOCTYPE html>
<html>
<head>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Ubuntu:wght@300;400;700&display=swap">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" />
<style>
body {
background-color: #260C1A;
color: #fff;
font-family: Ubuntu, Helvetica, Arial, sans-serif;
}
</style>
</head>
<body>
<main>
<!--
Include our `my-form` element that includes a <slot> which
allows us to nest additional shadow-dom elements
-->
<my-form>
<my-input></my-input>
</my-form>
<hr />
<!--
Include the dynamic `my-input` element outside of
other shadow-dom elements
-->
<my-input></my-input>
</main>
<!--
Here we include templates directly on the DOM so we can pick them up
through our autoloader. It's fine for testing, but can make a mess.
This version links to an external CSS file, where as our other
example uses a directly included <style> tag.
-->
<template id="my-form">
<link rel="stylesheet" href="./style/component/my-form.css" />
<form class="my-form">
<fieldset>
<legend>My Form Element</legend>
<slot></slot>
</fieldset>
</form>
</template>
<!--
Initialize Application
-->
<script src="./script/main.js" type="module"></script>
</body>
</html>
<!--
┌──────────────────────────────────────────────────────────────────────────────┐
│ │
│ view/component/my-input.css │
│ │
│ This template is an isolated shadow dom element that would ordinarily │
│ exist in a <template> tag. As a matter of fact, it's added to a │
│ <template> tag when we load it through a `fetch` call. │
│ │
│ The style here is isolated to this component. │
│ │
│ @author Matt Kenefick <medium.com/@mattkenefick> │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
-->
<style>
label {
border: 2px solid rgba(0, 0, 0, 0.25);
border-radius: 8px;
display: block;
margin: 1rem 0;
padding: 1rem;
}
h3 {
font-size: 0.875rem;
margin: 0 0 0.5rem 0;
}
input[type=text] {
background-color: #260C1A;
border: 2px solid transparent;
border-bottom: 2px solid #5F4842;
border-radius: 4px;
color: #fff;
outline: none;
padding: 0.5rem 1.0rem;
transition: border 0.25s ease-in-out;
}
input[type=text]:hover,
input[type=text]:focus {
border-color: #5F4842
}
</style>
<label class="my-input">
<h3>Header lorem ipsum</h3>
<input type="text" placeholder="My input placeholder" />
</label>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment