Published
Edited
Aug 5, 2021
Fork of Slides
1 fork
Importers
16 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
slide.md("callout")`
# Draw attention to this point
`
Insert cell
slide.html('small')`
<div style="height:40vw">Code is a code example -- edit the code below to change the display
</div>
`
Insert cell
Insert cell
Insert cell
Insert cell
slide = ({
md: wrap(md, 'slide'),
html: wrap(html, 'slide')
})
Insert cell
notes = ({
md: wrap(md, 'notes'),
html: wrap(html, 'notes')
})
Insert cell
wrap = (fn, className) => (...args) => {
if (args[0].raw) return html`<div class="${className}">${fn(...args)}</div>`;
else
return (...rest) => html`
<div class="${className} ${args
.map(s => `${className}--${s}`)
.join(' ')}">${fn(...rest)}</div>
`;
}
Insert cell
// hide li elements (so they can be shown on key events)
hide_li_elements = function(slide) {
const lis = slide.querySelectorAll('.observablehq .slide li');
lis.forEach(li => li.classList.add("hidden"));
}
Insert cell
keyBindings = {
let currentSlide = 0;
let showNotes = () => {};

function keyUp(event) {
const slides = document.querySelectorAll('.observablehq .slide');
switch (event.key) {
case 'ArrowUp':
case 'ArrowLeft':
// Check if there are any more bullets to *hide*
// If there are displayed LI elements, hide them (instead of advancing slides)
let cell = slides[currentSlide].parentNode;
let hidden_lis = cell.querySelectorAll("li:not(.hidden)");
console.log(hidden_lis);
if (hidden_lis.length !== 0) {
hidden_lis[hidden_lis.length - 1].classList.add("hidden");
} else {
currentSlide = Math.max(currentSlide - 1, 0);
slides[currentSlide].scrollIntoView();
showNotes(slides[currentSlide]);
}

break;
case 'ArrowDown':
case 'ArrowRight':
// Check if there are any more bullets to move through
// If there are hidden LI elements, show them (instead of advancing slides)
currentSlide = Math.min(currentSlide, slides.length - 1);
console.log(currentSlide, slides[currentSlide]);
let current_cell = slides[currentSlide].parentNode;
const lis = current_cell.querySelectorAll("li.hidden");
if (lis.length !== 0) {
lis[0].classList.remove("hidden");
}

// Otherwise, advance
else {
currentSlide = Math.min(currentSlide + 1, slides.length - 1);
const slide = slides[currentSlide];
hide_li_elements(slide);
slide.scrollIntoView();
showNotes(slide);
}

break;
}
}

document.removeEventListener('keyup', keyUp);
document.addEventListener('keyup', keyUp);

const button = html`<button>Notes</button>`;
button.onclick = () => {
const notes = open("about:blank", "notes", "width=300,height=200").document
.body;
showNotes = slide => {
notes.innerHTML = "";
let cell = slide.parentNode;
const siblings = Array.from(document.querySelectorAll('.observablehq'));
for (const sibling of siblings.slice(siblings.indexOf(cell))) {
if (sibling.querySelector('.notes')) {
notes.innerHTML = sibling.innerHTML;
break;
}
}
};
};

return button;
}
Insert cell
divider_color = "rgb(128, 207, 156)"
Insert cell
style = html`
<link href="https://fonts.googleapis.com/css2?family=Lato:wght@300&display=swap" rel="stylesheet">
<style>
.slide,
.notes {
padding: 1% 10%;
width: calc(100% + 28px);
box-sizing: border-box;
margin: 0 -14px;
}

.slide {
min-height: 64vw;
display: flex;
align-items: center;
}
.slide{
font-size: 3vw;
}

.slide.slide--small {
padding-bottom: 1%;
min-height: auto;
}

.slide.slide--bleed {
padding: 0;
min-height: 0;
}

.slide h1,
.slide h2,
.slide p,
.slide pre,
.slide img {
max-width: 100%;
}



.slide small {
color: gray;
}

.slide blockquote,
.slide ol,
.slide ul {
max-width: none;
}

.slide > * {
width: 100%;
}
.slide > iframe {
height: 56vw;
}

.slide ul,
.slide ol {
padding-left: 3vw;
margin-bottom: 0;
}
.slide ul li::before,
.slide ol li::before {
margin-left: -2vw;
}


.slide--intro {
background-color:black;
color:white;
font-family:"Lato", sans-serif;
}
.slide--intro h1 {
border-bottom: 1px solid ${divider_color};
width: 100%;
color:white;
margin-bottom:3px;
}

.slide--intro p {
margin-top:0px;
}

.slide--feature p {
border-top: 1px solid ${divider_color};
font-size:.8em;
position: absolute;
bottom: 0px;
width: 83%;
}
.slide--feature p code {
font-size:.8em;
}

p code, li code {color: #c30771;}

li.hidden {
opacity:0;
}

.slide--bullets {
align-items:flex-start;
}
.slide--bullets h1 {
font-family:"Lato", sans-serif;
font-size:1.75em;
border-bottom: 1px solid ${divider_color};
}

.slide--bullets ul {
list-style-position: outside;
list-style-type: none;
padding:0px;
}

.slide--callout {
background-color:${divider_color};
}

.slide--feature > span {
position:relative;
height:100%;
}
.slide--feature > span > img {
max-height:calc(100% - 210px);
border: 1px solid black;
position: absolute;
top: 43%;
transform: translate(-50%, -50%);
left:50%;
}
.slide--feature > span > p {
bottom:30px;
width:100%;
}
.slide {
height: 64vw;
}
</style>`
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