Published
Edited
Mar 9, 2021
1 star
Insert cell
Insert cell
Insert cell
Insert cell
html`
<template>
<p>The Zombies are coming!</p>
</template>
`
Insert cell
Insert cell
html`
<template>
<p>The <slot>Zombies</slot> are coming!</p>
</template>
`
Insert cell
Insert cell
html`
<template>
<p>The <slot name="whats-coming">Zombies</slot> are coming!</p>
</template>
`
Insert cell
md`The complete markup.`
Insert cell
html`
<apocalyptic-warning>
<span slot="whats-coming">Halitosis Laden Undead Minions</span>
</apocalyptic-warning>

<template>
<p>The <slot name="whats-coming">Zombies</slot> are coming!</p>
</template>
`
Insert cell
md`Now some JS to pull things together ( moved further below because Observable needs to await for the html to show up.)`
Insert cell
html`
<p>The Apocalypse will never happen!</p>
<apocalyptic-warning>
<span slot="whats-coming">Undead</span>
</apocalyptic-warning>
<apocalyptic-warning>
<span slot="whats-coming">Halitosis Laden Zombie Minions</span>
</apocalyptic-warning>
<template id="warningtemplate">
<style>
p {
background-color: pink;
padding: 0.5em;
border: 1px solid red;
}
</style>
<p>The <slot name="whats-coming">Zombies</slot> are coming!</p>
</template>
`
Insert cell
await visibility(), (
// Defines the custom element with our appropriate name, <apocalyptic-warning>
customElements.define("apocalyptic-warning",

// Ensures that we have all the default properties and methods of a built in HTML element
class extends HTMLElement {

// Called anytime a new custom element is created
constructor() {

// Calls the parent constructor, i.e. the constructor for 'HTMLElement',
// so that everything is set up exactly as we would for creating a built in HTML element
super();

// Grabs the <template> and stores it in 'warning'
let warning = document.getElementById("warningtemplate");

// Stores the contents of the template in 'mywarning'
let mywarning = warning.content;

const shadowRoot = this.attachShadow({mode: "open"}).appendChild(mywarning.cloneNode(true));
}
})


)
Insert cell
Insert cell
html`
<style>
apocalyptic-warning span {
color: blue;
}
</style>
`
Insert cell
Insert cell
html`
<template id="zprofiletemplate">
<style>
img {
width: 100%;
max-width: 300px;
height: auto;
margin: 0 1em 0 0;
}
h2 {
font-size: 3em;
margin: 0 0 0.25em 0;
line-height: 0.8;
}
h3 {
margin: 0.5em 0 0 0;
font-weight: normal;
}
.age, .infection-date {
display: block;
}
span {
line-height: 1.4;
}
.label {
color: #555;
}
li, ul {
display: inline;
padding: 0;
}
li::after {
content: ', ';
}
li:last-child::after {
content: '';
}
li:last-child::before {
content: ' and ';
}
</style>

<div class="profilepic">
<slot name="profile-image"><img src="${await FileAttachment("default.webp").url()}" alt=""></slot>
</div>

<div class="info">
<h2><slot name="zombie-name" part="zname">Zombie Bob</slot></h2>

<span class="age"><span class="label">Age:</span> <slot name="z-age">37</slot></span>
<span class="infection-date"><span class="label">Infection Date:</span> <slot name="idate">September 12, 2025</slot></span>

<div class="interests">
<span class="label">Interests: </span>
<slot name="z-interests">
<ul>
<li>Long Walks on Beach</li>
<li>brains</li>
<li>defeating humanity</li>
</ul>
</slot>
</div>

<span class="z-statement"><span class="label">Apocalyptic Statement: </span> <slot name="statement">Moooooooan!</slot></span>

</div>
</template>


`
Insert cell
html`
<style>
zombie-profile {
width: calc(50% - 1em);
border: 1px solid red;
padding: 1em;
margin-bottom: 2em;
display: grid;
grid-template-columns: 2fr 4fr;
column-gap: 20px;
}
zombie-profile img {
width: 100%;
max-width: 300px;
height: auto;
margin: 0 1em 0 0;
}
zombie-profile li, zombie-profile ul {
display: inline;
padding: 0;
}
zombie-profile li::after {
content: ', ';
}
zombie-profile li:last-child::after {
content: '';
}
zombie-profile li:last-child::before {
content: ' and ';
}

</style>

`
Insert cell
await visibility(),(
customElements.define("zombie-profile",
class extends HTMLElement {
constructor() {
super();
let profile = document.getElementById("zprofiletemplate");
let myprofile = profile.content;
const shadowRoot = this.attachShadow({mode: "open"}).appendChild(myprofile.cloneNode(true));
}
}
)

)
Insert cell
html`
<h1>Undying Love: A Zombie Dating Service</h1>
<div class="profiles">
<zombie-profile>
<img slot="profile-image" src="${await FileAttachment("moana.webp").url()}" />
<span slot="zombie-name" part="zname">Mooana</span>
<span slot="z-age">25</span>
<span slot="idate">October 15, 2027</span>
<ul slot="z-interests">
<li>rotary phones</li>
<li>human sports</li>
<li>brains</li>
</ul>
<span slot="statement">Fun and fancy free lady looking for a zombie with all its limbs.</span>
</zombie-profile>
<zombie-profile>
<img slot="profile-image" src="${await FileAttachment("leroy.webp").url()}" />
<span slot="zombie-name">Leroy</span>
<span slot="z-age">29</span>
<span slot="idate">March 1, 2026</span>
<ul slot="z-interests">
<li>disco</li>
<li>leisure suits</li>
<li>brains</li>
</ul>
<span slot="statement">Disco daddy who won't stop dancing your heart away.</span>
</zombie-profile>
<zombie-profile>
<img slot="profile-image" src="${await FileAttachment("phil.webp").url()}" />
<span slot="zombie-name">Phil</span>
<span slot="z-age">31</span>
<span slot="idate">December 22, 2025</span>
<ul slot="z-interests">
<li>brains</li>
<li>selfies</li>
</ul>
<span slot="statement">I'm out of this world! You know... because of the spacesuit... get it?</span>
</zombie-profile>
<zombie-profile>
<img slot="profile-image" src="${await FileAttachment("ahabcshanty.webp").url()}" />
<span slot="zombie-name">A. C. Shanty</span>
<span slot="z-age">41</span>
<span slot="idate">November 7, 2026</span>
<ul slot="z-interests">
<li>sea shanties</li>
<li>reality tv</li>
<li>brains</li>
<li>more brains</li>
</ul>
<span slot="statement">What's a pirate's favorite letter?<br>Rrrrrrr!<br>Aye! But his first love be the C</span>
</zombie-profile>
<zombie-profile>
<img slot="profile-image" src="${await FileAttachment("helga.webp").url()}" />
<span slot="zombie-name">Helga</span>
<span slot="z-age">39</span>
<span slot="idate">February 14, 2028</span>
<ul slot="z-interests">
<li>puns</li>
<li>rhubarb</li>
<li>brains</li>
<li>space lasers</li>
</ul>
<span slot="statement">The hostess with the mostest!</span>
</zombie-profile>
<zombie-profile>
</zombie-profile>
</div>

`
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more