Published
Edited
Feb 11, 2019
Importers
9 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof lecture = slideshow({
title: 'CSE 124 Lecture Slides',
description: 'Lecture slides of one of my classes, hosted/presented w/ Google Drive',
options: cse124Lectures.map(lecture=>({
label: lecture.name,
value: lecture.id
})),
})
Insert cell

html`<iframe src="https://drive.google.com/file/d/${lecture}/preview" style="border:0'" width=${width} height=${width/1.9}></iframe>`
Insert cell
viewof emotion = slideshow({
title: 'Feelings',
description: 'How do you feel today?',
options: [
{ label: "🤷", value: "shrug" },
{ label: "😂", value: "tears-of-joy" },
{ label: "😍", value: "loving-it" },
{ label: "🤔", value: "hmmm" },
{ label: "😱", value: "yikes" },
{ label: "😈", value: "mischievous" },
{ label: "💩", value: "poo" }
],
})
Insert cell
md`you feel **${emotion}**`
Insert cell
Insert cell
Insert cell
slideshow = function *(config={}) {
let {title, options=[], initial=0, description} = config;
if(Array.isArray(config)) options = config;
let index = initial;
const butFirst = html`<button class="first" value="first"><<</button>`;
const butPrev = html`<button class="prev" value="prev"><</button>`;
const mid = html`<select>${options.map((a,i)=>{
return Object.assign(html`<option>`, {value:`${a.value || a}`, selected:i===index, textContent:`${a.label || a}`})
})}`;
const butNext = html`<button class="next" value="next">></button>`;
const butLast = html`<button class="last" value="last">>></button>`;
const form = html`
<div class="slide" style="text-align:center;">
${(title && `<div style="font: 700 0.9rem sans-serif;">${title || ''}</div>`) || ''}
${butFirst}
${butPrev}
${mid}
${butNext}
${butLast}
${(description && `<div style="font-size: 0.85rem; font-style: italic;">${description}</div>`) || ''}
</div>
<style>

.slide button, .slide select {
cursor: pointer;
width: 30px;
padding: .2rem;
}
.slide select {
margin:1rem;
width: auto;
}</style>`; // the style at the end is painful, i know
form.value = options[index].value || options[index]
const updateAbility = ()=> {
if(options.length === 0) {
[butFirst,butPrev,butNext, butLast].map(b=>b.setAttribute('disabled', 'true'))
return
}
if (index === 0) {
butFirst.setAttribute('disabled', 'true')
butPrev.setAttribute('disabled', 'true')
}
else {
butFirst.removeAttribute('disabled')
butPrev.removeAttribute('disabled')
}
if (index === options.length -1) {
butLast.setAttribute('disabled', 'true')
butNext.setAttribute('disabled', 'true')
}
else {
butLast.removeAttribute('disabled')
butNext.removeAttribute('disabled')
}
}
updateAbility()
const updateIndexDecorator = f => {
return e => {
f(e);
updateAbility();
mid.selectedIndex = index;
form.value = options[index].value || options[index];
form.dispatchEvent(new CustomEvent('input'))
}
}
butFirst.onclick = updateIndexDecorator(e=>{
index = 0;
})
butPrev.onclick = updateIndexDecorator(e=>{
if(index <= 0) return
index--;
})
butNext.onclick = updateIndexDecorator(e=>{
if(index >= options.length - 1) return
index++;
})
butLast.onclick = updateIndexDecorator(e=>{
index = options.length - 1;
})

mid.onchange = updateIndexDecorator(e => {
index = e.target.selectedIndex
});
yield form;
}
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more