Published
Edited
Feb 8, 2022
Importers
3 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
bookmark = async url => {
let content;
try {
let m = await getMetaData(url, [
'og:image',
'og:description',
'og:url',
'og:title',
'twitter:image',
'twitter:description'
]);
content = m.content;
} catch {
return md`${url}`;
}
const meta = Array.from(content);
const get = pattern =>
meta.some(e => pattern.test(e[0]))
? meta.find(e => pattern.test(e[0]))[1]
: "";

// prettier-ignore
return html`<p class="c-ui-bookmark">
<style>
.c-ui-bookmark a {display: inline-block; border: 1px solid lightgrey; padding: 5px; transition: all .2s}
.c-ui-bookmark a:hover {text-decoration:none; border-color:black}
.c-ui-bookmark a:hover strong {text-decoration:underline;}
.c-ui-bookmark a::after {content:"";display:table;clear:both;}
</style>
<a href="${url}">
<img src="${get(/image/)}" style="width: auto; height: 5em;float: left;margin-right:5px;"/>
<strong style="display: block; line-height: 1.15; margin-bottom: .25em; color: black">${get(/title/)}</strong>
<span style="display:block;margin:0">${get(/description/)}</span>
<span style="float:right;font-size:.8em;color:grey;max-width: 50%;text-overflow: ellipsis;white-space:nowrap;overflow:hidden;">${url}</span>
</a>
</p>`;
}
Insert cell
Insert cell
Insert cell
// silly but terse to use a boolean like this just to avoid a function body...
notice = (node, type) => html`<style>.ui-notice {
--notice-color: hsl(225, 31%, 95%);
position:relative;
box-sizing: border-box;
border: 1px solid rgba(0,0,0,.3);
background: var(--notice-color);
padding: 3px 8px 3px 2em;
max-width: 640px;
font-size: 16px;
font-family: -apple-system, BlinkMacSystemFont, "avenir next", avenir,
helvetica, "helvetica neue", ubuntu, roboto, noto, "segoe ui", arial,
sans-serif;
}

.ui-notice:before {content: "ℹ ";position: absolute; top:50%;left:.5em; transform: translateY(-50%)}
.ui-notice-tip:before {content: "✔";}
.ui-notice-warn:before {content: "⚠";}
.ui-notice-error:before {content: "🚨 ";}
.ui-notice-tip {--notice-color: #76f023}
.ui-notice-warn {--notice-color: #ffc251}
.ui-notice-error {--notice-color: #ff7171}
.ui-notice p:first-child { margin-top: 0; }
.ui-notice p:last-child { margin-bottom: 0; }</style>
${
node.classList.add("ui-notice", type ? `ui-notice-${type}` : undefined) ||
node
}`
Insert cell
Insert cell
// silly but terse to use a boolean like this just to avoid a function body...
columns = (node, col = 2) => html`<style>
.c-col {display: grid; grid-column-gap: 20px; grid-row-gap: 20px}
.c-col--2 { grid-template-columns: repeat(2, 1fr) }
.c-col--3 { grid-template-columns: repeat(3, 1fr) }
.c-col--4 { grid-template-columns: repeat(4, 1fr) }
</style>${node.classList.add("c-col", `c-col--${col}`) || node}`
Insert cell
Insert cell
Insert cell
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