vasille-jsx
Version:
The first Developer eXperience Orientated front-end framework (JSX components)
134 lines (133 loc) • 4.36 kB
JavaScript
import { ArrayModel, ArrayView, Fragment, IValue, MapModel, MapView, SetModel, SetView, userError, Watch as CoreWatch, } from "vasille";
export function readValue(v) {
return v instanceof IValue ? v.$ : v;
}
export function Slot(options, ctx, defaultSlot) {
const model = readValue(options.model);
if (model) {
if (model.length <= 1) {
for (const key in options) {
if (options[key] instanceof IValue) {
options[key] = options[key].$;
}
}
}
else {
for (const key in options) {
/* istanbul ignore else */
if (!(options[key] instanceof IValue)) {
options[key] = ctx.ref(options[key]);
}
}
}
model(options, ctx);
}
else {
(readValue(options.slot) ?? defaultSlot)?.(ctx);
}
}
export function If({ condition, slot: magicSlot }, ctx, defaultSlot) {
const slot = readValue(magicSlot) ?? defaultSlot;
ctx.if(condition instanceof IValue ? condition : ctx.ref(condition), slot ?? (() => { }));
}
export function ElseIf({ condition, slot: magicSlot }, ctx, defaultSlot) {
const slot = readValue(magicSlot) ?? defaultSlot;
ctx.elif(condition instanceof IValue ? condition : ctx.ref(condition), slot ?? (() => { }));
}
export function Else({ slot: magicSlot }, ctx, defaultSlot) {
const slot = readValue(magicSlot) ?? defaultSlot;
/* istanbul ignore else */
if (slot) {
ctx.else(slot);
}
}
export function For({ of, slot: magicSlot }, ctx, defaultSlot) {
const slot = readValue(magicSlot) ?? defaultSlot;
/* istanbul ignore else */
if (of instanceof IValue) {
ctx.create(new CoreWatch({
model: of,
slot: function (ctx, model) {
create(model, ctx);
},
}, ctx.runner));
}
else if (of) {
create(of, ctx);
}
function create(model, node) {
if (!slot) {
return;
}
if (model instanceof ArrayModel) {
node.create(new ArrayView({
model,
slot: slot,
}, node.runner));
}
else if (model instanceof MapModel) {
node.create(new MapView({
model,
slot,
}, node.runner));
}
else if (model instanceof SetModel) {
node.create(new SetView({
model,
slot: slot,
}, node.runner));
}
// fallback if is used external Array/Map/Set
else {
console.warn("Vasille <For of/> fallback detected. Please provide reactive data.");
if (model instanceof Array) {
model.forEach((value) => {
slot(node, value, value);
});
}
else if (model instanceof Map) {
for (const [key, value] of model) {
slot(node, value, key);
}
}
else if (model instanceof Set) {
for (const value of model) {
slot(node, value, value);
}
}
else {
throw userError("wrong use of `<For of/>` component", "wrong-model");
}
}
}
}
export function Watch({ model, slot: magicSlot }, ctx, defaultSlot) {
const slot = readValue(magicSlot) ?? defaultSlot;
/* istanbul ignore else */
if (slot && model instanceof IValue) {
ctx.create(new CoreWatch({ model, slot }, ctx.runner));
}
}
export function Debug({ model }, ctx) {
const value = model instanceof IValue ? model : ctx.ref(model);
ctx.debug(value);
}
export function Delay({ time, slot }, ctx, defaultSlot) {
const fragment = new Fragment({}, ctx.runner, ":timer");
const dSlot = readValue(slot) ?? defaultSlot;
let timer;
ctx.create(fragment, function (node) {
/* istanbul ignore else */
if (dSlot) {
timer = setTimeout(() => {
dSlot(node);
timer = undefined;
}, readValue(time));
}
node.runOnDestroy(() => {
if (timer !== undefined) {
clearTimeout(timer);
}
});
});
}