svelte-ux
Version:
- Increment version in `package.json` and commit as `Version bump to x.y.z` - `npm run publish`
77 lines (76 loc) • 3.17 kB
JavaScript
import { scaleLinear } from 'd3-scale';
import { tweened } from 'svelte/motion';
export function dataBackground(node, options) {
// Set duration to 0 by default to be instantaneous
const baseline = tweened(0, { duration: 0, ...options.tweened });
const barStart = tweened(0, { duration: 0, ...options.tweened });
const barEnd = tweened(0, { duration: 0, ...options.tweened });
function update(options) {
var _a, _b, _c;
if (options.enabled === false) {
// remove styles
node.style.backgroundImage = '';
node.style.backgroundRepeat = '';
node.style.backgroundSize = '';
}
else {
// Map values from 0% to 100%
const scale = scaleLinear()
.domain((_a = options.domain) !== null && _a !== void 0 ? _a : [-100, 100])
.range([0, 100]);
baseline.set(scale(0));
baseline.subscribe((value) => {
node.style.setProperty('--baseline', `${value}%`);
});
barStart.set(scale(Math.min(0, options.value)));
barStart.subscribe((value) => {
node.style.setProperty('--barStart', `${value}%`);
});
barEnd.set(scale(Math.max(0, options.value)));
barEnd.subscribe((value) => {
node.style.setProperty('--barEnd', `${value}%`);
});
node.style.setProperty('--color-from', (_b = options.color) !== null && _b !== void 0 ? _b : 'var(--tw-gradient-from)');
node.style.setProperty('--color-to', (_c = options.color) !== null && _c !== void 0 ? _c : 'var(--tw-gradient-to)');
const insetX = Array.isArray(options.inset) ? options.inset[0] : options.inset;
const insetY = Array.isArray(options.inset) ? options.inset[1] : options.inset;
node.style.backgroundSize = `
calc(100% - (${insetX}px * 2))
calc(100% - (${insetY}px * 2))`;
node.style.backgroundPosition = `${insetX}px ${insetY}px`;
// Show black baseline at `0` first, then value bar
// TODO: Handle baseline at `100%` (only negative numbers)
node.style.backgroundImage = options.bar
? `${options.baseline
? `
linear-gradient(
to right,
transparent var(--baseline),
#999 var(--baseline),
#999 calc(var(--baseline) + 1px),
transparent 0%,
transparent 100%
),
`
: ''}
linear-gradient(
to right,
transparent var(--barStart),
var(--color-from) var(--barStart),
var(--color-to) var(--barEnd),
transparent 0%,
transparent 100%
)
`
: `linear-gradient(
to right,
var(--color-from),
var(--color-to)
)`;
// Add `no-repeat` to fix small gap on 100% and also support `background-origin` setting (inset)
node.style.backgroundRepeat = 'no-repeat';
}
}
update(options);
return { update };
}