Public
Edited
Jul 8, 2024
1 fork
Importers
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof textNodeViewExample = textNodeView("hi")
Insert cell
textNodeViewExample
Insert cell
Inputs.button("Randomize textNodeViewExample", {
reduce: () => {
viewof textNodeViewExample.value = Math.random();
viewof textNodeViewExample.dispatchEvent(new Event('input', {bubbles: true}))
}
})
Insert cell
textNodeView = (value = '') => {
const node = document.createTextNode(value)
return Object.defineProperty(node, 'value', {
get: () => node.textContent,
set: (val) => node.textContent = val,
enumerable: true
});
}
Insert cell
Insert cell
Insert cell
logotype = (name = "Survey Slate") => html`<div class="[ pa2 flex items-center w3 h3 ][ f6 lh-title b tracked-light ][ text-on-brand bg-accent ]">${name}`
Insert cell
Insert cell
Insert cell
Insert cell
## Page Footer

${pageFooter()}
Insert cell
Insert cell
Insert cell
spinner()
Insert cell
spinner = () => {
return html`<span class="spinner">${getIconHtml("loader")}</span>`
}
Insert cell
Insert cell
Insert cell
buttonLabel = ({label, iconLeft, iconRight, iconRightClass, iconLeftClass, ariaLabel}) => {
let labelHtml = "";
if (iconLeft) {
labelHtml += `${getIconHtml(iconLeft, `icon--sm ${iconLeftClass || ""}`)} `;
}

if(label) {
labelHtml += `<span class="button-label__text">${label}</span>`;
}

if (iconRight) {
labelHtml += `${getIconHtml(iconRight, `icon--sm ${iconRightClass || ""}`)} `;
}

if (ariaLabel) {
labelHtml += `<span class="clip">${ariaLabel}</span>`;
}
return html`<span class="button-label">${labelHtml}</span>`
}
Insert cell
getIconHtml = (name, klasses = "") => `<span class="icon ${klasses}">${getIconSvg(name, 24, {role: 'img'})}</span>`
Insert cell
Insert cell
// Thanks @mootari, https://observablehq.com/@saneef/is-observable-inputs-style-able
ns = Inputs.text().classList[0]
Insert cell
styles = html`<style>
:root {
--button-border-radius: var(--border-radius-2, 0.25rem);
--border-color: #aaa; /* tachyons's light-silver */
--border-color-light: #eee; /* tachyons's light-gray */
}

/* https://observablehq.com/@saneef/is-observable-inputs-style-able */
form.${ns} {
width: auto;
}

.${ns} input,
.${ns} textarea,
.${ns} select,
.${ns} button {
font-family: var(--brand-font);
}

.${ns} input[type="text"],
.${ns} textarea,
.${ns} select,
.${ns} button {
background-color: white;
border: 1px solid var(--border-color);
border-radius: var(--button-border-radius);
}

.${ns} input[type="text"],
.${ns} textarea,
.${ns} button {
padding: var(--spacing-extra-small) var(--spacing-small);
}

.${ns} select {
padding-top: var(--spacing-extra-small);
padding-bottom: var(--spacing-extra-small);
}

.${ns} button:hover,
.${ns} button:focus,
.${ns} button:active {
background-color: var(--light-gray, #eee);
}

/* Icon */

.icon {
display: inline-block;
position: relative;
vertical-align: middle;
width: 1.5rem;
height: 1.5rem;
color: var(--gray, #777)
}

.icon svg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}

.icon--sm {
width: 1rem;
height: 1rem;
}
.icon--danger {
color: var(--red, #ff4136)
}

.icon--success {
color: var(--green, #19a974)
}

/* Button Group*/

.button-group {
display: flex;
}

.button-group form.${ns} + form.${ns} {
margin-left: -1px;
}

.button-group form.${ns} button {
border-radius: 0;
}

.button-group form.${ns}:first-child button {
border-top-left-radius: var(--button-border-radius);
border-bottom-left-radius: var(--button-border-radius);
}

.button-group form.${ns}:last-child button {
border-top-right-radius: var(--button-border-radius);
border-bottom-right-radius: var(--button-border-radius);
}

/* Button Label */
.button-label {
display: inline-flex;
align-items: center;
vertical-align: middle;
}

.button-label > * + * {
margin-left: var(--spacing-extra-small, 0.25rem);
}
.button-label__text {}

/* Card */

.card {
display: block;
background: white;
padding: 1rem; /* pa3 or --spacing-medium */
border: 1px solid var(--border-color-light);
border-radius: var(--border-radius-3);
}

.card--compact {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
}

/* Loader */
@keyframes rotate {
to {
transform: rotate(360deg);
}
}
.spinner .icon {
color: var(--brand);
}
.spinner svg {
animation: rotate ease-out 1.2s infinite;
}
</style>`
Insert cell
Insert cell
html`
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet">
<style type="text/css" media="screen, print">
body {
font-family: var(--brand-font);
}
</style>
`
Insert cell
tachyonsExt({
colors: {
brand: mainColors[900], // or, provide and color hex code
accent: accentColors[900], // or, provide and color hex code
// The color of text which are usually displayed on top of the brand or accent colors.
"text-on-brand": "#ffffff",
},
fonts: {
"brand-font": `"Roboto", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"`
}
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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