@octane-xplat/ui 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/native/octane-client-build.json +1 -1
- package/dist/native/ui.js +40 -19
- package/dist/native/ui10.js +19 -48
- package/dist/native/ui11.js +118 -56
- package/dist/native/ui12.js +114 -16
- package/dist/native/ui13.js +54 -18
- package/dist/native/ui14.js +76 -13
- package/dist/native/ui15.js +128 -18
- package/dist/native/ui16.js +48 -136
- package/dist/native/ui17.js +42 -19
- package/dist/native/ui18.js +50 -9
- package/dist/native/ui19.js +34 -12
- package/dist/native/ui2.js +10 -48
- package/dist/native/ui20.js +17 -0
- package/dist/native/ui21.js +93 -0
- package/dist/native/ui22.js +124 -0
- package/dist/native/ui23.js +103 -0
- package/dist/native/ui24.js +58 -0
- package/dist/native/ui25.js +19 -0
- package/dist/native/ui26.js +27 -0
- package/dist/native/ui27.js +35 -0
- package/dist/native/ui28.js +146 -0
- package/dist/native/ui29.js +28 -0
- package/dist/native/ui3.js +17 -20
- package/dist/native/ui30.js +35 -0
- package/dist/native/ui31.js +39 -0
- package/dist/native/ui32.js +70 -0
- package/dist/native/ui33.js +30 -0
- package/dist/native/ui34.js +10 -0
- package/dist/native/ui35.js +27 -0
- package/dist/native/ui36.js +34 -0
- package/dist/native/ui37.js +17 -0
- package/dist/native/ui38.js +68 -0
- package/dist/native/ui39.js +33 -0
- package/dist/native/ui4.js +21 -48
- package/dist/native/ui40.js +14 -0
- package/dist/native/ui41.js +104 -0
- package/dist/native/ui42.js +148 -0
- package/dist/native/ui43.js +22 -0
- package/dist/native/ui44.js +8 -0
- package/dist/native/ui5.js +70 -27
- package/dist/native/ui6.js +36 -20
- package/dist/native/ui7.js +24 -61
- package/dist/native/ui8.js +16 -18
- package/dist/native/ui9.js +16 -13
- package/dist/web/octane-client-build.json +1 -1
- package/dist/web/ui.js +40 -19
- package/dist/web/ui10.js +187 -31
- package/dist/web/ui11.js +419 -53
- package/dist/web/ui12.js +83 -15
- package/dist/web/ui13.js +107 -19
- package/dist/web/ui14.js +98 -18
- package/dist/web/ui15.js +83 -47
- package/dist/web/ui16.js +100 -93
- package/dist/web/ui17.js +36 -22
- package/dist/web/ui18.js +29 -15
- package/dist/web/ui19.js +9 -7
- package/dist/web/ui2.js +15 -103
- package/dist/web/ui20.js +114 -0
- package/dist/web/ui21.js +82 -0
- package/dist/web/ui22.js +68 -0
- package/dist/web/ui23.js +57 -0
- package/dist/web/ui24.js +16 -0
- package/dist/web/ui25.js +22 -0
- package/dist/web/ui26.js +39 -0
- package/dist/web/ui27.js +127 -0
- package/dist/web/ui28.js +112 -0
- package/dist/web/ui29.js +108 -0
- package/dist/web/ui3.js +19 -27
- package/dist/web/ui30.js +43 -0
- package/dist/web/ui31.js +42 -0
- package/dist/web/ui32.js +77 -0
- package/dist/web/ui33.js +43 -0
- package/dist/web/ui34.js +67 -0
- package/dist/web/ui35.js +9 -0
- package/dist/web/ui36.js +45 -0
- package/dist/web/ui37.js +47 -0
- package/dist/web/ui38.js +17 -0
- package/dist/web/ui39.js +100 -0
- package/dist/web/ui4.js +145 -17
- package/dist/web/ui40.js +41 -0
- package/dist/web/ui41.js +17 -0
- package/dist/web/ui42.js +9 -0
- package/dist/web/ui43.js +22 -0
- package/dist/web/ui44.js +8 -0
- package/dist/web/ui5.js +54 -52
- package/dist/web/ui6.js +43 -16
- package/dist/web/ui7.js +29 -46
- package/dist/web/ui8.js +29 -18
- package/dist/web/ui9.js +24 -16
- package/package.json +6 -3
- package/src/theme/tokens.css +166 -0
- package/types/index.d.ts +108 -1
- package/types/props.d.ts +333 -8
package/dist/web/ui22.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { cx } from "./ui19.js";
|
|
2
|
+
import { __s, bag1, bag3, clone, componentSlot, createRoot, ifBlock, template } from "octane";
|
|
3
|
+
import { childTextHoleUpdate } from "octane/internal/client";
|
|
4
|
+
//#region src/toast.web.tsrx
|
|
5
|
+
var _t$0 = /* @__PURE__ */ template("<div class=\"vx-toast\"></div>");
|
|
6
|
+
function __then$0(__props, __s, __extra) {
|
|
7
|
+
const props = __extra[0];
|
|
8
|
+
let _b = __s.slots[0];
|
|
9
|
+
if (_b === void 0) {
|
|
10
|
+
let _m0;
|
|
11
|
+
const _root = clone(_t$0);
|
|
12
|
+
_m0 = _root;
|
|
13
|
+
_b = bag3(__s, _root, _m0, null, void 0);
|
|
14
|
+
}
|
|
15
|
+
{
|
|
16
|
+
const _v = props.content;
|
|
17
|
+
_b.b = childTextHoleUpdate(__s, 1, _b.a, _v, _b.b, _b.c);
|
|
18
|
+
_b.c = _v;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function __else$2(__props, __s, __extra) {
|
|
22
|
+
const Component = __extra[0].content;
|
|
23
|
+
let _b = __s.slots[0];
|
|
24
|
+
if (_b === void 0) {
|
|
25
|
+
let _m0;
|
|
26
|
+
const _root = clone(_t$0);
|
|
27
|
+
_m0 = _root;
|
|
28
|
+
_b = bag1(__s, _root, _m0);
|
|
29
|
+
}
|
|
30
|
+
componentSlot(__s, 1, _b.a, Component, {}, void 0, void 0, void 0, void 0, void 0, "c:1427a872");
|
|
31
|
+
}
|
|
32
|
+
var queue = [];
|
|
33
|
+
var active = false;
|
|
34
|
+
var ToastBody = /* @__PURE__ */ __s(function ToastBody(props, __s, __extra) {
|
|
35
|
+
const __block = __s.block;
|
|
36
|
+
ifBlock(__s, 0, __block.parentNode, typeof props.content === "string", __then$0, __else$2, __block.endMarker, [props]);
|
|
37
|
+
});
|
|
38
|
+
function applyWebProps(host, props) {
|
|
39
|
+
if (!props) return;
|
|
40
|
+
for (const [key, value] of Object.entries(props)) if (key.includes("-")) host.setAttribute(key, String(value));
|
|
41
|
+
else host[key] = value;
|
|
42
|
+
}
|
|
43
|
+
function showNext() {
|
|
44
|
+
if (active || queue.length === 0) return;
|
|
45
|
+
active = true;
|
|
46
|
+
const entry = queue.shift();
|
|
47
|
+
const host = document.createElement("div");
|
|
48
|
+
host.className = cx("vx-toast-host", entry.options.position === "top" ? "vx-toast-top" : "vx-toast-bottom");
|
|
49
|
+
applyWebProps(host, entry.options.web);
|
|
50
|
+
document.body.appendChild(host);
|
|
51
|
+
const root = createRoot(host);
|
|
52
|
+
root.render(ToastBody, { content: entry.content });
|
|
53
|
+
setTimeout(() => {
|
|
54
|
+
root.unmount();
|
|
55
|
+
host.remove();
|
|
56
|
+
active = false;
|
|
57
|
+
showNext();
|
|
58
|
+
}, Math.max(0, entry.options.duration ?? 3e3));
|
|
59
|
+
}
|
|
60
|
+
function showToast(content, options = {}) {
|
|
61
|
+
queue.push({
|
|
62
|
+
content,
|
|
63
|
+
options
|
|
64
|
+
});
|
|
65
|
+
showNext();
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
export { showToast };
|
package/dist/web/ui23.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { hookSlots, useRef } from "octane";
|
|
2
|
+
//#region src/anim.web.tsrx
|
|
3
|
+
var _h$0 = /* @__PURE__ */ Symbol(/* @__PURE__ */ hookSlots(1));
|
|
4
|
+
function createAnimated(initial, prop) {
|
|
5
|
+
let el = null;
|
|
6
|
+
let current = initial;
|
|
7
|
+
let raf = 0;
|
|
8
|
+
const apply = (v) => {
|
|
9
|
+
current = v;
|
|
10
|
+
if (el) el.style.transform = `translateX(${v}px)`;
|
|
11
|
+
};
|
|
12
|
+
const run = (step) => {
|
|
13
|
+
cancelAnimationFrame(raf);
|
|
14
|
+
const start = Date.now();
|
|
15
|
+
const tick = () => {
|
|
16
|
+
const v = step(Date.now() - start);
|
|
17
|
+
if (v === null) return;
|
|
18
|
+
apply(v);
|
|
19
|
+
raf = requestAnimationFrame(tick);
|
|
20
|
+
};
|
|
21
|
+
raf = requestAnimationFrame(tick);
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
get value() {
|
|
25
|
+
return current;
|
|
26
|
+
},
|
|
27
|
+
bind(e) {
|
|
28
|
+
el = e;
|
|
29
|
+
if (el) el.style.transform = `translateX(${current}px)`;
|
|
30
|
+
},
|
|
31
|
+
to(target, opts) {
|
|
32
|
+
const dur = opts?.duration ?? 300;
|
|
33
|
+
const from = current;
|
|
34
|
+
run((t) => t >= dur ? (apply(target), null) : from + (target - from) * (t / dur));
|
|
35
|
+
},
|
|
36
|
+
spring(target, opts) {
|
|
37
|
+
const damping = opts?.damping ?? 14, stiffness = opts?.stiffness ?? 120;
|
|
38
|
+
let v = 0, x = current;
|
|
39
|
+
run(() => {
|
|
40
|
+
const dt = 1 / 60;
|
|
41
|
+
v += (-stiffness * (x - target) - damping * v) * dt;
|
|
42
|
+
x += v * dt;
|
|
43
|
+
return Math.abs(v) < .5 && Math.abs(x - target) < .5 ? (apply(target), null) : x;
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
stop() {
|
|
47
|
+
cancelAnimationFrame(raf);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function useAnimation(initial = 0, prop = "translateX") {
|
|
52
|
+
const c = useRef(null, _h$0);
|
|
53
|
+
if (!c.current) c.current = createAnimated(initial, prop);
|
|
54
|
+
return c.current;
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
export { useAnimation };
|
package/dist/web/ui24.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { hookSlots, useSyncExternalStore } from "octane";
|
|
2
|
+
//#region src/theme/colorScheme.web.tsrx
|
|
3
|
+
var _h$0 = /* @__PURE__ */ Symbol(/* @__PURE__ */ hookSlots(1));
|
|
4
|
+
function getColorScheme() {
|
|
5
|
+
return typeof matchMedia === "function" && matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
6
|
+
}
|
|
7
|
+
function subscribe(cb) {
|
|
8
|
+
const mq = matchMedia("(prefers-color-scheme: dark)");
|
|
9
|
+
mq.addEventListener("change", cb);
|
|
10
|
+
return () => mq.removeEventListener("change", cb);
|
|
11
|
+
}
|
|
12
|
+
function useColorScheme() {
|
|
13
|
+
return useSyncExternalStore(subscribe, getColorScheme, _h$0);
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { getColorScheme, useColorScheme };
|
package/dist/web/ui25.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { componentSlot } from "octane";
|
|
2
|
+
//#region src/styled.web.tsrx
|
|
3
|
+
function styled(Base, def) {
|
|
4
|
+
function Styled(props, __s, __extra) {
|
|
5
|
+
const __block = __s.block;
|
|
6
|
+
const cls = [def.base];
|
|
7
|
+
const rest = { ...props };
|
|
8
|
+
for (const k of Object.keys(def.variants ?? {})) {
|
|
9
|
+
if (props[k]) cls.push(def.variants[k]);
|
|
10
|
+
delete rest[k];
|
|
11
|
+
}
|
|
12
|
+
if (props.className) cls.push(props.className);
|
|
13
|
+
if (__s.block.pending && !__s.block.crossRenderUpdate) return;
|
|
14
|
+
componentSlot(__s, 0, __block.parentNode, Base, {
|
|
15
|
+
...rest,
|
|
16
|
+
"className": cls
|
|
17
|
+
}, __block.endMarker, void 0, void 0, true, void 0, "c:5d3d2b58");
|
|
18
|
+
}
|
|
19
|
+
return Styled;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { styled };
|
package/dist/web/ui26.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { applyEscapeProps } from "./ui2.js";
|
|
2
|
+
import { __s, bag6, clone, queueRefAttach, queueRefDetach, setStyle, template } from "octane";
|
|
3
|
+
import { childTextHoleUpdate, replaceRef, updateFreshClassName } from "octane/internal/client";
|
|
4
|
+
//#region src/Screen.web.tsrx
|
|
5
|
+
var _t$0 = /* @__PURE__ */ template("<div></div>");
|
|
6
|
+
var _rm$1 = [
|
|
7
|
+
"r",
|
|
8
|
+
"b",
|
|
9
|
+
"a"
|
|
10
|
+
];
|
|
11
|
+
var Screen = /* @__PURE__ */ __s(function Screen(props, __s, __extra) {
|
|
12
|
+
let _b = __s.slots[0];
|
|
13
|
+
if (_b === void 0) {
|
|
14
|
+
let _m0, _m1;
|
|
15
|
+
const _root = clone(_t$0);
|
|
16
|
+
queueRefAttach(__s, _m1 = (e) => applyEscapeProps(e, props), _m0 = _root);
|
|
17
|
+
(__s.cleanups ??= []).push(() => _b && queueRefDetach(_b.b, _b.a));
|
|
18
|
+
_b = bag6(__s, _root, _m0, _m1, void 0, void 0, null, void 0);
|
|
19
|
+
__s.refFields = _rm$1;
|
|
20
|
+
} else {
|
|
21
|
+
const _r = (e) => applyEscapeProps(e, props);
|
|
22
|
+
if (_r !== _b.b) _b.b = replaceRef(__s, _b.b, _r, _b.a);
|
|
23
|
+
}
|
|
24
|
+
_b.c = updateFreshClassName(["vx-screen", props.className], _b.c, _b.a);
|
|
25
|
+
{
|
|
26
|
+
const _v = props.style;
|
|
27
|
+
if (_b.d !== _v) {
|
|
28
|
+
setStyle(_b.a, _v, _b.d);
|
|
29
|
+
_b.d = _v;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
{
|
|
33
|
+
const _v = props.children;
|
|
34
|
+
_b.e = childTextHoleUpdate(__s, 1, _b.a, _v, _b.e, _b.f);
|
|
35
|
+
_b.f = _v;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
//#endregion
|
|
39
|
+
export { Screen };
|
package/dist/web/ui27.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
//#region src/route-table.ts
|
|
2
|
+
var EXT = /\.(tsrx|tsx|ts|mts|cts|js|mjs|cjs|jsx)$/;
|
|
3
|
+
var SUFFIX = /\.(web|native|ios|android)$/;
|
|
4
|
+
var PARAM = /^\[(.+)\]$/;
|
|
5
|
+
/** Component pick rule for route/layout modules: default export, then a
|
|
6
|
+
* `screen` named export, then a single function export. Route files use
|
|
7
|
+
* named exports (decision #13) — a lone component is unambiguous. */
|
|
8
|
+
function pick(mod, file) {
|
|
9
|
+
if (typeof mod?.default === "function") return mod.default;
|
|
10
|
+
if (typeof mod?.screen === "function") return mod.screen;
|
|
11
|
+
const fns = Object.keys(mod ?? {}).filter((k) => typeof mod[k] === "function");
|
|
12
|
+
if (fns.length === 1) return mod[fns[0]];
|
|
13
|
+
console.warn("[octane-xplat] route file " + file + (fns.length ? ` has ${fns.length} component-shaped exports (${fns.join(", ")}) — add a default or 'screen' export` : " has no component export") + " — skipped");
|
|
14
|
+
}
|
|
15
|
+
function deriveRouteManifest(files, prefer, dir = "app") {
|
|
16
|
+
const prefix = dir.replace(/^\.?\/?/, "").replace(/\/+$/, "") + "/";
|
|
17
|
+
const seen = /* @__PURE__ */ new Map();
|
|
18
|
+
const layoutRank = /* @__PURE__ */ new Map();
|
|
19
|
+
const layouts = {};
|
|
20
|
+
const warned = /* @__PURE__ */ new Set();
|
|
21
|
+
for (const key of Object.keys(files).sort()) {
|
|
22
|
+
let rel = key.replace(/^\.?\//, "");
|
|
23
|
+
if (rel.startsWith(prefix)) rel = rel.slice(prefix.length);
|
|
24
|
+
rel = rel.replace(EXT, "");
|
|
25
|
+
const parts = rel.split("/");
|
|
26
|
+
let base = parts[parts.length - 1];
|
|
27
|
+
const sm = SUFFIX.exec(base);
|
|
28
|
+
const suffix = sm?.[1];
|
|
29
|
+
if (sm) base = base.slice(0, base.length - sm[0].length);
|
|
30
|
+
if (suffix && !prefer.includes(suffix)) continue;
|
|
31
|
+
const rank = suffix ? prefer.indexOf(suffix) : prefer.length;
|
|
32
|
+
if (base === "_layout") {
|
|
33
|
+
const d = parts.slice(0, -1).join("/");
|
|
34
|
+
const prev = layoutRank.get(d);
|
|
35
|
+
if (prev !== void 0 && prev <= rank) continue;
|
|
36
|
+
const component = pick(files[key], key);
|
|
37
|
+
if (component) {
|
|
38
|
+
layouts[d] = component;
|
|
39
|
+
layoutRank.set(d, rank);
|
|
40
|
+
}
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
const segs = parts.slice(0, -1).concat(base);
|
|
44
|
+
if (segs[segs.length - 1] === "index") segs.pop();
|
|
45
|
+
const segments = segs.map((s) => {
|
|
46
|
+
const p = PARAM.exec(s);
|
|
47
|
+
return p ? ":" + p[1] : s;
|
|
48
|
+
});
|
|
49
|
+
const name = segments.join("/") || "index";
|
|
50
|
+
const meta = {
|
|
51
|
+
name,
|
|
52
|
+
segments,
|
|
53
|
+
params: segments.filter((s) => s.startsWith(":")).map((s) => s.slice(1)),
|
|
54
|
+
file: key
|
|
55
|
+
};
|
|
56
|
+
const prev = seen.get(name);
|
|
57
|
+
if (prev && prev.rank <= rank) {
|
|
58
|
+
if (prev.rank === rank && !warned.has(name)) {
|
|
59
|
+
warned.add(name);
|
|
60
|
+
console.warn(`[octane-xplat] route '${name}' is defined by both ${prev.meta.file} and ${key} — keeping ${prev.meta.file}`);
|
|
61
|
+
}
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const component = pick(files[key], key);
|
|
65
|
+
if (component) seen.set(name, {
|
|
66
|
+
rank,
|
|
67
|
+
meta,
|
|
68
|
+
component
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
const screens = {};
|
|
72
|
+
const routes = [];
|
|
73
|
+
for (const { meta, component } of seen.values()) {
|
|
74
|
+
screens[meta.name] = component;
|
|
75
|
+
routes.push(meta);
|
|
76
|
+
}
|
|
77
|
+
routes.sort((a, b) => b.segments.reduce((n, s) => n + (s.startsWith(":") ? 1 : 2), 0) - a.segments.reduce((n, s) => n + (s.startsWith(":") ? 1 : 2), 0) || a.name.localeCompare(b.name));
|
|
78
|
+
return {
|
|
79
|
+
screens,
|
|
80
|
+
routes,
|
|
81
|
+
layouts
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/** Match URL path segments against a manifest — returns the winning meta
|
|
85
|
+
* plus extracted params, or null. First hit wins (routes are pre-sorted
|
|
86
|
+
* by specificity). */
|
|
87
|
+
function matchRoute(routes, segs) {
|
|
88
|
+
for (const meta of routes) {
|
|
89
|
+
if (meta.segments.length !== segs.length) continue;
|
|
90
|
+
const params = {};
|
|
91
|
+
let ok = true;
|
|
92
|
+
for (let i = 0; i < segs.length; i++) {
|
|
93
|
+
const p = meta.segments[i];
|
|
94
|
+
if (p.startsWith(":")) params[p.slice(1)] = decodeURIComponent(segs[i]);
|
|
95
|
+
else if (p !== segs[i]) {
|
|
96
|
+
ok = false;
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (ok) return {
|
|
101
|
+
meta,
|
|
102
|
+
params
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
/** Serialize a Route to a URL path (no origin): manifest routes substitute
|
|
108
|
+
* `:param` segments from params (leftover params → query string);
|
|
109
|
+
* non-manifest names keep the legacy `/<stack>/<name>?params` shape. */
|
|
110
|
+
function buildRoutePath(routes, r) {
|
|
111
|
+
const meta = routes.find((m) => m.name === r.name);
|
|
112
|
+
let segs;
|
|
113
|
+
let rest = r.params;
|
|
114
|
+
if (meta) {
|
|
115
|
+
segs = meta.segments.map((s) => {
|
|
116
|
+
if (!s.startsWith(":")) return s;
|
|
117
|
+
const v = r.params[s.slice(1)];
|
|
118
|
+
if (v === void 0) console.warn(`[octane-xplat] route '${r.name}' pushed without path param ${s}`);
|
|
119
|
+
return encodeURIComponent(String(v ?? ""));
|
|
120
|
+
});
|
|
121
|
+
rest = Object.fromEntries(Object.entries(r.params).filter(([k]) => !meta.params.includes(k)));
|
|
122
|
+
} else segs = [r.name];
|
|
123
|
+
const q = Object.entries(rest).map(([k, v]) => encodeURIComponent(k) + "=" + encodeURIComponent(String(v))).join("&");
|
|
124
|
+
return (((r.stack === "root" ? "" : "/" + r.stack) + "/" + segs.join("/")).replace(/\/+$/, "") || "/") + (q ? "?" + q : "");
|
|
125
|
+
}
|
|
126
|
+
//#endregion
|
|
127
|
+
export { buildRoutePath, deriveRouteManifest, matchRoute };
|
package/dist/web/ui28.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { buildRoutePath, matchRoute } from "./ui27.js";
|
|
2
|
+
import { hookSlots, useSyncExternalStore } from "octane";
|
|
3
|
+
//#region src/route.web.ts
|
|
4
|
+
var screens = {};
|
|
5
|
+
var routes = [];
|
|
6
|
+
/** Register the app's name → screen table. On web the table feeds
|
|
7
|
+
* `screenFor` — the fallback outlet resolution in Tabs when no
|
|
8
|
+
* `resolveScreen` prop is given; on native `pushRoute` resolves
|
|
9
|
+
* `route.name` through it. `manifest` (from deriveRouteManifest) enables
|
|
10
|
+
* path-param matching — call once from the shared routes module. */
|
|
11
|
+
function registerScreens(table, manifest) {
|
|
12
|
+
screens = table;
|
|
13
|
+
routes = manifest ?? [];
|
|
14
|
+
if (current !== void 0) {
|
|
15
|
+
current = parse();
|
|
16
|
+
emit();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** One-call registration for route-dir apps — screens + URL patterns +
|
|
20
|
+
* layouts all come from deriveRouteManifest. */
|
|
21
|
+
function registerRoutes(manifest) {
|
|
22
|
+
registerScreens(manifest.screens, manifest.routes);
|
|
23
|
+
}
|
|
24
|
+
function screenFor(name) {
|
|
25
|
+
return screens[name];
|
|
26
|
+
}
|
|
27
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
28
|
+
var current;
|
|
29
|
+
function queryParams() {
|
|
30
|
+
const params = {};
|
|
31
|
+
new URLSearchParams(location.search).forEach((v, k) => params[k] = v);
|
|
32
|
+
return params;
|
|
33
|
+
}
|
|
34
|
+
function parse() {
|
|
35
|
+
const segs = location.pathname.split("/").filter(Boolean);
|
|
36
|
+
if (!segs.length) return null;
|
|
37
|
+
const query = queryParams();
|
|
38
|
+
const root = matchRoute(routes, segs);
|
|
39
|
+
if (root) return {
|
|
40
|
+
stack: "root",
|
|
41
|
+
name: root.meta.name,
|
|
42
|
+
params: {
|
|
43
|
+
...query,
|
|
44
|
+
...root.params
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
if (segs.length > 1) {
|
|
48
|
+
const named = matchRoute(routes, segs.slice(1));
|
|
49
|
+
if (named) return {
|
|
50
|
+
stack: segs[0],
|
|
51
|
+
name: named.meta.name,
|
|
52
|
+
params: {
|
|
53
|
+
...query,
|
|
54
|
+
...named.params
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
return {
|
|
58
|
+
stack: segs[0],
|
|
59
|
+
name: segs[1],
|
|
60
|
+
params: query
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
stack: "root",
|
|
65
|
+
name: segs[0],
|
|
66
|
+
params: query
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function read() {
|
|
70
|
+
if (current === void 0) current = parse();
|
|
71
|
+
return current;
|
|
72
|
+
}
|
|
73
|
+
function emit() {
|
|
74
|
+
listeners.forEach((l) => l());
|
|
75
|
+
}
|
|
76
|
+
function pushRoute(r) {
|
|
77
|
+
history.pushState(null, "", buildRoutePath(routes, r));
|
|
78
|
+
current = r;
|
|
79
|
+
emit();
|
|
80
|
+
}
|
|
81
|
+
/** Web history is one linear stack — back pops whatever route is current;
|
|
82
|
+
* per-stack pops aren't expressible, so `stack` is accepted for parity
|
|
83
|
+
* and ignored. */
|
|
84
|
+
function popRoute(_stack = "root") {
|
|
85
|
+
history.back();
|
|
86
|
+
}
|
|
87
|
+
window.addEventListener("popstate", () => {
|
|
88
|
+
current = parse();
|
|
89
|
+
emit();
|
|
90
|
+
});
|
|
91
|
+
/** Current route if it targets `stack`, else null. */
|
|
92
|
+
function routeFor(stack) {
|
|
93
|
+
const c = read();
|
|
94
|
+
return c && c.stack === stack ? c : null;
|
|
95
|
+
}
|
|
96
|
+
/** The route active at boot — for deep-link tab selection. */
|
|
97
|
+
function currentRoute() {
|
|
98
|
+
return read();
|
|
99
|
+
}
|
|
100
|
+
/** URL for a Route — Link's href and shareable-path helper. */
|
|
101
|
+
function hrefFor(r) {
|
|
102
|
+
return buildRoutePath(routes, r);
|
|
103
|
+
}
|
|
104
|
+
function useRoute(stack) {
|
|
105
|
+
return useSyncExternalStore((cb) => {
|
|
106
|
+
listeners.add(cb);
|
|
107
|
+
return () => listeners.delete(cb);
|
|
108
|
+
}, () => routeFor(stack), _h$0);
|
|
109
|
+
}
|
|
110
|
+
var _h$0 = /* @__PURE__ */ Symbol(/* @__PURE__ */ hookSlots(1));
|
|
111
|
+
//#endregion
|
|
112
|
+
export { currentRoute, hrefFor, popRoute, pushRoute, registerRoutes, registerScreens, routeFor, screenFor, useRoute };
|
package/dist/web/ui29.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { screenFor, useRoute } from "./ui28.js";
|
|
2
|
+
import { __s, bag3, bag4, bag9, child, clone, createScopedValue, delegateEvents, forBlock, hookSlots, ifBlock, setEventHandler, setStyle, sibling, template, useState, withSlot } from "octane";
|
|
3
|
+
import { bindSignalAttribute, bindSignalChild, childTextHoleUpdate, createElementFromConfig, enableSignalBindings, updateFreshClassName } from "octane/internal/client";
|
|
4
|
+
//#region src/Tabs.web.tsrx
|
|
5
|
+
enableSignalBindings(1, true);
|
|
6
|
+
delegateEvents(["click"]);
|
|
7
|
+
var _t$0 = /* @__PURE__ */ template("<div class=\"vx-route\"></div>");
|
|
8
|
+
var _t$1 = /* @__PURE__ */ template("<button></button>");
|
|
9
|
+
var _t$2 = /* @__PURE__ */ template("<div><div class=\"vx-tabbar\"><!></div><div class=\"vx-tabpane\"></div></div>");
|
|
10
|
+
var _hs$ = /* @__PURE__ */ hookSlots(4);
|
|
11
|
+
var _h$1 = /* @__PURE__ */ Symbol(_hs$ + 1);
|
|
12
|
+
var _h$2 = /* @__PURE__ */ Symbol(_hs$ + 2);
|
|
13
|
+
function __then$0(__props, __s, __extra) {
|
|
14
|
+
const routed = __extra[4];
|
|
15
|
+
let _b = __s.slots[0];
|
|
16
|
+
if (_b === void 0) {
|
|
17
|
+
let _m0;
|
|
18
|
+
const _root = clone(_t$0);
|
|
19
|
+
_m0 = _root;
|
|
20
|
+
_b = bag3(__s, _root, _m0, null, void 0);
|
|
21
|
+
}
|
|
22
|
+
{
|
|
23
|
+
const _v = routed;
|
|
24
|
+
_b.b = childTextHoleUpdate(__s, 1, _b.a, _v, _b.b, _b.c);
|
|
25
|
+
_b.c = _v;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
var _key$3 = (t) => t.title;
|
|
29
|
+
function __item$4(t, __s, __extra) {
|
|
30
|
+
const active = __extra[0];
|
|
31
|
+
const props = __extra[1];
|
|
32
|
+
const setInternal = __extra[2];
|
|
33
|
+
let _b = __s.slots[0];
|
|
34
|
+
if (_b === void 0) {
|
|
35
|
+
let _m1;
|
|
36
|
+
const _root = clone(_t$1);
|
|
37
|
+
_m1 = _root;
|
|
38
|
+
setEventHandler(_root, "$$click", () => {
|
|
39
|
+
const i = props.tabs.indexOf(t);
|
|
40
|
+
setInternal(i);
|
|
41
|
+
props.onSelectedIndexChanged?.(i);
|
|
42
|
+
});
|
|
43
|
+
_b = bag4(__s, _root, void 0, _m1, null, void 0);
|
|
44
|
+
} else setEventHandler(_b.b, "$$click", () => {
|
|
45
|
+
const i = props.tabs.indexOf(t);
|
|
46
|
+
setInternal(i);
|
|
47
|
+
props.onSelectedIndexChanged?.(i);
|
|
48
|
+
});
|
|
49
|
+
_b.a = updateFreshClassName(["vx-tab", active === props.tabs.indexOf(t) ? "active" : ""], _b.a, _b.b);
|
|
50
|
+
_b.e = bindSignalChild(__s, _b.e, 1, _b.b, t.title, "b:7ce48fd2", null, void 0, void 0, void 0, true);
|
|
51
|
+
}
|
|
52
|
+
function __else$2(__props, __s, __extra) {
|
|
53
|
+
const active = __extra[0];
|
|
54
|
+
const paneRoute = __extra[1];
|
|
55
|
+
const props = __extra[2];
|
|
56
|
+
const resolve = __extra[3];
|
|
57
|
+
const setInternal = __extra[5];
|
|
58
|
+
let _b = __s.slots[0];
|
|
59
|
+
if (_b === void 0) {
|
|
60
|
+
let _m1, _m4, _m5, _m6;
|
|
61
|
+
const _root = clone(_t$2);
|
|
62
|
+
_m1 = _root;
|
|
63
|
+
const _el0 = child(_root);
|
|
64
|
+
_m4 = _el0;
|
|
65
|
+
_m5 = child(_el0);
|
|
66
|
+
_m6 = sibling(_el0, 1);
|
|
67
|
+
_b = bag9(__s, _root, void 0, _m1, void 0, void 0, _m4, _m5, _m6, null, void 0);
|
|
68
|
+
}
|
|
69
|
+
_b.a = bindSignalAttribute(__s, _b.a, _b.b, "id", props.id, "b:7404e316", "attr");
|
|
70
|
+
_b.c = updateFreshClassName(["vx-tabs", props.className], _b.c, _b.b);
|
|
71
|
+
{
|
|
72
|
+
const _v = props.style;
|
|
73
|
+
if (_b.d !== _v) {
|
|
74
|
+
setStyle(_b.b, _v, _b.d);
|
|
75
|
+
_b.d = _v;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
forBlock(__s, 1, _b.e, props.tabs, _key$3, __item$4, 26, [
|
|
79
|
+
active,
|
|
80
|
+
props,
|
|
81
|
+
setInternal
|
|
82
|
+
], null, _b.f, true);
|
|
83
|
+
_b.j = bindSignalChild(__s, _b.j, 2, _b.g, (paneRoute ? resolve(paneRoute.name, paneRoute.params) : null) ?? props.tabs[active]?.render(), "b:a696350b", null, void 0, void 0, void 0, true);
|
|
84
|
+
}
|
|
85
|
+
var Tabs = /* @__PURE__ */ __s(function Tabs(props, __s, __extra) {
|
|
86
|
+
const __block = __s.block;
|
|
87
|
+
const [internal, setInternal] = useState(0, _hs$ + 0);
|
|
88
|
+
const active = props.selectedIndex ?? internal;
|
|
89
|
+
const rootRoute = withSlot(_h$1, useRoute, "root");
|
|
90
|
+
const paneRoute = withSlot(_h$2, useRoute, props.tabs[active]?.stack ?? "");
|
|
91
|
+
const resolve = (name, params) => {
|
|
92
|
+
if (props.resolveScreen) return props.resolveScreen(name, params);
|
|
93
|
+
const C = screenFor(name);
|
|
94
|
+
return C ? createScopedValue(() => createElementFromConfig("c:beeccfd6", C, { ...params })) : null;
|
|
95
|
+
};
|
|
96
|
+
const routed = rootRoute ? resolve(rootRoute.name, rootRoute.params) : null;
|
|
97
|
+
if (__s.block.pending && !__s.block.crossRenderUpdate) return;
|
|
98
|
+
ifBlock(__s, 0, __block.parentNode, routed, __then$0, __else$2, __block.endMarker, [
|
|
99
|
+
active,
|
|
100
|
+
paneRoute,
|
|
101
|
+
props,
|
|
102
|
+
resolve,
|
|
103
|
+
routed,
|
|
104
|
+
setInternal
|
|
105
|
+
]);
|
|
106
|
+
});
|
|
107
|
+
//#endregion
|
|
108
|
+
export { Tabs };
|
package/dist/web/ui3.js
CHANGED
|
@@ -1,28 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
if (
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
{
|
|
22
|
-
const _v = props.children;
|
|
23
|
-
_b.d = childTextHoleUpdate(__s, 1, _b.b, _v, _b.d, _b.e);
|
|
24
|
-
_b.e = _v;
|
|
25
|
-
}
|
|
26
|
-
});
|
|
1
|
+
//#region src/layout-child.web.ts
|
|
2
|
+
/** Convert parent-layout metadata to CSS on the web leaf. Native's `dock`
|
|
3
|
+
* attribute has no CSS equivalent and is ignored on web. Grid indices are
|
|
4
|
+
* zero-based in the shared API, matching NativeScript. */
|
|
5
|
+
function layoutChildProps(props, baseStyle = props.style) {
|
|
6
|
+
const style = { ...baseStyle ?? {} };
|
|
7
|
+
if (props.row !== void 0) style.gridRow = `${props.row + 1} / span ${props.rowSpan ?? 1}`;
|
|
8
|
+
else if (props.rowSpan !== void 0) style.gridRow = `span ${props.rowSpan}`;
|
|
9
|
+
if (props.col !== void 0) style.gridColumn = `${props.col + 1} / span ${props.colSpan ?? 1}`;
|
|
10
|
+
else if (props.colSpan !== void 0) style.gridColumn = `span ${props.colSpan}`;
|
|
11
|
+
if (props.left !== void 0) style.left = props.left;
|
|
12
|
+
if (props.top !== void 0) style.top = props.top;
|
|
13
|
+
if (props.flexGrow !== void 0) style.flexGrow = props.flexGrow;
|
|
14
|
+
if (props.flexShrink !== void 0) style.flexShrink = props.flexShrink;
|
|
15
|
+
if (props.alignSelf !== void 0) style.alignSelf = props.alignSelf;
|
|
16
|
+
if (props.order !== void 0) style.order = props.order;
|
|
17
|
+
return { style };
|
|
18
|
+
}
|
|
27
19
|
//#endregion
|
|
28
|
-
export {
|
|
20
|
+
export { layoutChildProps };
|
package/dist/web/ui30.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { applyEscapeProps } from "./ui2.js";
|
|
2
|
+
import { __s, bag6, clone, delegateEvents, queueRefAttach, queueRefDetach, setEventHandler, setStyle, template } from "octane";
|
|
3
|
+
import { bindSignalAttribute, bindSignalChecked, enableSignalBindings, replaceRef, updateFreshClassName } from "octane/internal/client";
|
|
4
|
+
//#region src/Switch.web.tsrx
|
|
5
|
+
enableSignalBindings(1, true);
|
|
6
|
+
delegateEvents(["change"]);
|
|
7
|
+
var _t$0 = /* @__PURE__ */ template("<input type=\"checkbox\" data-octane-input=\"i:0400e5c1\"/>");
|
|
8
|
+
var _rm$0 = [
|
|
9
|
+
"r",
|
|
10
|
+
"b",
|
|
11
|
+
"a"
|
|
12
|
+
];
|
|
13
|
+
var Switch = /* @__PURE__ */ __s(function Switch(props, __s, __extra) {
|
|
14
|
+
let _b = __s.slots[0];
|
|
15
|
+
if (_b === void 0) {
|
|
16
|
+
let _m0, _m1, _m5;
|
|
17
|
+
const _root = clone(_t$0);
|
|
18
|
+
queueRefAttach(__s, _m1 = (e) => applyEscapeProps(e, props), _m0 = _root);
|
|
19
|
+
(__s.cleanups ??= []).push(() => _b && queueRefDetach(_b.b, _b.a));
|
|
20
|
+
_m5 = bindSignalChecked(__s, void 0, _root, props.checked, "i:0400e5c1");
|
|
21
|
+
setEventHandler(_root, "$$change", (e) => props.onCheckedChange?.(e.target.checked));
|
|
22
|
+
_b = bag6(__s, _root, _m0, _m1, void 0, void 0, void 0, _m5);
|
|
23
|
+
__s.refFields = _rm$0;
|
|
24
|
+
} else {
|
|
25
|
+
{
|
|
26
|
+
const _r = (e) => applyEscapeProps(e, props);
|
|
27
|
+
if (_r !== _b.b) _b.b = replaceRef(__s, _b.b, _r, _b.a);
|
|
28
|
+
}
|
|
29
|
+
_b.f = bindSignalChecked(__s, _b.f, _b.a, props.checked, "i:0400e5c1");
|
|
30
|
+
setEventHandler(_b.a, "$$change", (e) => props.onCheckedChange?.(e.target.checked));
|
|
31
|
+
}
|
|
32
|
+
_b.c = bindSignalAttribute(__s, _b.c, _b.a, "id", props.id, "b:18b5d0ad", "attr");
|
|
33
|
+
_b.d = updateFreshClassName(["vx-switch", props.className], _b.d, _b.a);
|
|
34
|
+
{
|
|
35
|
+
const _v = props.style;
|
|
36
|
+
if (_b.e !== _v) {
|
|
37
|
+
setStyle(_b.a, _v, _b.e);
|
|
38
|
+
_b.e = _v;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
//#endregion
|
|
43
|
+
export { Switch };
|