vasille-jsx
Version:
The same framework which is designed to build bulletproof frontends (JSX components)
94 lines (93 loc) • 2.75 kB
JavaScript
import { ArrayModel, ArrayView, Fragment, MapModel, MapView, reportError, safe, SetModel, SetView, SwitchedNode, userError, Watch as CoreWatch, } from "vasille";
export function Slot({ model, slot, ...options }, ctx, defaultSlot) {
try {
if (model) {
model(options, ctx);
}
else if (slot) {
slot({}, ctx);
}
else if (defaultSlot) {
defaultSlot(ctx);
}
}
catch (e) {
reportError(e);
}
}
export function Switch(options, ctx) {
ctx.create(new SwitchedNode(ctx.runner, options.cases, options.default));
}
export function For({ of: model, slot: _slot }, ctx, defaultSlot) {
const slot = _slot ?? defaultSlot;
if (!slot) {
return;
}
if (model instanceof ArrayModel) {
ctx.create(new ArrayView({
model,
slot: slot,
}, ctx.runner));
}
else if (model instanceof MapModel) {
ctx.create(new MapView({
model,
slot,
}, ctx.runner));
}
else if (model instanceof SetModel) {
ctx.create(new SetView({
model,
slot: slot,
}, ctx.runner));
}
// fallback if is used external Array/Map/Set
else {
const safeSlot = safe(slot);
console.warn("Vasille <For of/> fallback detected. Please provide reactive data.");
if (model instanceof Array) {
model.forEach((value) => {
safeSlot(ctx, value, value);
});
}
else if (model instanceof Map) {
model.forEach((value, key) => {
safeSlot(ctx, value, key);
});
}
else if (model instanceof Set) {
model.forEach(value => {
safeSlot(ctx, value, value);
});
}
else {
throw userError("wrong use of `<For of/>` component", "wrong-model");
}
}
}
export function Watch({ $model, slot: _slot }, ctx, defaultSlot) {
const slot = _slot ?? defaultSlot;
/* istanbul ignore else */
if (slot) {
ctx.create(new CoreWatch({ model: $model, slot: safe(slot) }, ctx.runner));
}
}
export function Delay({ time, slot: _slot }, ctx, defaultSlot) {
const fragment = new Fragment(ctx.runner);
const slot = _slot ?? defaultSlot;
let timer;
ctx.create(fragment, function (node) {
/* istanbul ignore else */
if (slot) {
timer = setTimeout(() => {
safe(slot)(node);
timer = undefined;
}, time);
}
node.runOnDestroy(() => {
if (timer !== undefined) {
clearTimeout(timer);
}
});
});
}