Modular router db and locale
This commit is contained in:
18
src/sigpro.db.js
Normal file
18
src/sigpro.db.js
Normal file
@@ -0,0 +1,18 @@
|
||||
export const db = async (url, data = {}, loading = null) => {
|
||||
if (loading) loading(true);
|
||||
try {
|
||||
const res = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data),
|
||||
credentials: 'include'
|
||||
});
|
||||
if (!res.ok) {
|
||||
const errorText = await res.text();
|
||||
throw new Error(`Error ${res.status}: ${errorText}`);
|
||||
}
|
||||
return await res.json();
|
||||
} finally {
|
||||
if (loading) loading(false);
|
||||
}
|
||||
};
|
||||
@@ -242,13 +242,13 @@ export const mount = (c, tgt) => {
|
||||
t.replaceChildren(i._cnt); MOUNTED.set(t, i); return i;
|
||||
};
|
||||
|
||||
const htmlTags = "a abbr article aside audio b blockquote br button canvas caption cite code col colgroup datalist dd del details dfn dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 header hr i iframe img input ins kbd label legend li main mark meter nav object ol optgroup option output p picture pre progress section select slot small source span strong sub summary sup svg table tbody td template textarea tfoot th thead time tr u ul video";
|
||||
// const htmlTags = "a abbr article aside audio b blockquote br button canvas caption cite code col colgroup datalist dd del details dfn dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 header hr i iframe img input ins kbd label legend li main mark meter nav object ol optgroup option output p picture pre progress section select slot small source span strong sub summary sup svg table tbody td template textarea tfoot th thead time tr u ul video";
|
||||
|
||||
export const SigPro = { $, watch, batch, h, fragment, render, mount, when, each, onUnmount, val, isA, isF, isO };
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
window.SigPro = SigPro;
|
||||
htmlTags.split(" ").forEach(tag => {
|
||||
window[tag] = (props, children) => h(tag, props, children);
|
||||
});
|
||||
// htmlTags.split(" ").forEach(tag => {
|
||||
// window[tag] = (props, children) => h(tag, props, children);
|
||||
// });
|
||||
}
|
||||
21
src/sigpro.locale.js
Normal file
21
src/sigpro.locale.js
Normal file
@@ -0,0 +1,21 @@
|
||||
const { $ } = window.SigPro;
|
||||
|
||||
const currentLocale = $("en");
|
||||
const translations = {};
|
||||
|
||||
export const addLang = obj => {
|
||||
for (const locale of Object.keys(obj)) {
|
||||
if (!translations[locale]) translations[locale] = {};
|
||||
Object.assign(translations[locale], obj[locale]);
|
||||
}
|
||||
};
|
||||
|
||||
export const setLocale = locale => {
|
||||
if (locale && translations[locale]) {
|
||||
currentLocale(locale);
|
||||
}
|
||||
};
|
||||
|
||||
export const t = key => {
|
||||
return () => translations[currentLocale()]?.[key] ?? key;
|
||||
};
|
||||
49
src/sigpro.router.js
Normal file
49
src/sigpro.router.js
Normal file
@@ -0,0 +1,49 @@
|
||||
const { $, h, watch, render, isF } = window.SigPro;
|
||||
|
||||
const getHash = () => window.location.hash.slice(1) || "/";
|
||||
const currentPath = $(getHash());
|
||||
|
||||
window.addEventListener("hashchange", () => currentPath(getHash()));
|
||||
|
||||
export const routerParams = $({});
|
||||
|
||||
export const router = routes => {
|
||||
const hook = h("div", { class: "router-hook" });
|
||||
let currentView = null;
|
||||
|
||||
watch([currentPath], () => {
|
||||
const cur = currentPath();
|
||||
|
||||
const route = routes.find(r => {
|
||||
const p1 = r.path.split("/").filter(Boolean);
|
||||
const p2 = cur.split("/").filter(Boolean);
|
||||
return p1.length === p2.length && p1.every((p, i) => p[0] === ":" || p === p2[i]);
|
||||
}) || routes.find(r => r.path === "*");
|
||||
|
||||
if (route) {
|
||||
currentView?.destroy();
|
||||
|
||||
const params = {};
|
||||
route.path.split("/").filter(Boolean).forEach((p, i) => {
|
||||
if (p[0] === ":") params[p.slice(1)] = cur.split("/").filter(Boolean)[i];
|
||||
});
|
||||
|
||||
routerParams(params);
|
||||
|
||||
currentView = render(() => isF(route.component) ? route.component(params) : route.component);
|
||||
|
||||
hook.replaceChildren(currentView.container);
|
||||
}
|
||||
});
|
||||
|
||||
hook.destroy = () => {
|
||||
currentView?.destroy();
|
||||
};
|
||||
|
||||
return hook;
|
||||
};
|
||||
|
||||
router.params = routerParams;
|
||||
router.to = p => window.location.hash = p.replace(/^#?\/?/, "#/");
|
||||
router.back = () => window.history.back();
|
||||
router.path = () => currentPath();
|
||||
@@ -1,90 +0,0 @@
|
||||
/// <reference path="../sigpro.d.ts" />
|
||||
|
||||
const { $, h, watch, render, isF } = window.SigPro;
|
||||
|
||||
// router
|
||||
export const router = routes => {
|
||||
const getHash = () => window.location.hash.slice(1) || "/";
|
||||
const path = $(getHash());
|
||||
const handler = () => path(getHash());
|
||||
window.addEventListener("hashchange", handler);
|
||||
|
||||
const hook = h("div", { class: "router-hook" });
|
||||
let currentView = null;
|
||||
|
||||
watch([path], () => {
|
||||
const cur = path();
|
||||
const route = routes.find(r => {
|
||||
const p1 = r.path.split("/").filter(Boolean);
|
||||
const p2 = cur.split("/").filter(Boolean);
|
||||
return p1.length === p2.length && p1.every((p, i) => p[0] === ":" || p === p2[i]);
|
||||
}) || routes.find(r => r.path === "*");
|
||||
|
||||
if (route) {
|
||||
currentView?.destroy();
|
||||
const params = {};
|
||||
route.path.split("/").filter(Boolean).forEach((p, i) => {
|
||||
if (p[0] === ":") params[p.slice(1)] = cur.split("/").filter(Boolean)[i];
|
||||
});
|
||||
router.params(params);
|
||||
currentView = render(() => isF(route.component) ? route.component(params) : route.component);
|
||||
hook.replaceChildren(currentView.container);
|
||||
}
|
||||
});
|
||||
|
||||
hook.destroy = () => {
|
||||
window.removeEventListener("hashchange", handler);
|
||||
currentView?.destroy();
|
||||
};
|
||||
|
||||
return hook;
|
||||
};
|
||||
|
||||
router.params = $({});
|
||||
router.to = p => window.location.hash = p.replace(/^#?\/?/, "#/");
|
||||
router.back = () => window.history.back();
|
||||
router.path = () => window.location.hash.replace(/^#/, "") || "/";
|
||||
|
||||
// db
|
||||
export const db = async (url, data = {}, loading = null) => {
|
||||
if (loading) loading(true);
|
||||
try {
|
||||
const res = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data),
|
||||
credentials: 'include'
|
||||
});
|
||||
if (!res.ok) {
|
||||
const errorText = await res.text();
|
||||
throw new Error(`Error ${res.status}: ${errorText}`);
|
||||
}
|
||||
return await res.json();
|
||||
} finally {
|
||||
if (loading) loading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const currentLocale = $('en');
|
||||
|
||||
const translations = {};
|
||||
|
||||
// addLang
|
||||
export const addLang = (obj) => {
|
||||
for (const locale of Object.keys(obj)) {
|
||||
if (!translations[locale]) translations[locale] = {};
|
||||
Object.assign(translations[locale], obj[locale]);
|
||||
}
|
||||
};
|
||||
|
||||
// setLocale
|
||||
export const setLocale = (locale) => {
|
||||
if (locale && translations[locale]) {
|
||||
currentLocale(locale);
|
||||
}
|
||||
};
|
||||
|
||||
// t
|
||||
export const t = (key) => {
|
||||
return () => translations[currentLocale()]?.[key] ?? key;
|
||||
};
|
||||
Reference in New Issue
Block a user