jsswift 2.0.0 → 2.1.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/AI.md +38 -73
- package/README.md +2 -0
- package/dist/build/build-configured-runtime.d.mts +29 -0
- package/dist/build/build-configured-runtime.mjs +92 -0
- package/dist/build/runtime-layout.mjs +13 -0
- package/dist/build/select-ui.mjs +167 -0
- package/dist/build/vite-jss.d.mts +2 -0
- package/dist/build/vite-jss.mjs +73 -0
- package/dist/cms.js +3522 -0
- package/dist/documentions/AI.md +38 -73
- package/dist/documentions/README.md +4 -2
- package/dist/documentions/components/table.md +13 -0
- package/dist/documentions/configured-runtime.md +82 -0
- package/dist/documentions/examples/crud.md +18 -7
- package/dist/documentions/getting-started.md +2 -0
- package/dist/documentions/knowledge-map.json +20 -1
- package/dist/documentions/ui/data-feedback-overlays.md +2 -0
- package/dist/documentions/ui/forms.md +2 -0
- package/dist/ui-src/00-bootstrap.js +330 -0
- package/dist/ui-src/01-foundation-helpers.js +809 -0
- package/dist/ui-src/10-primitives-layout.js +5091 -0
- package/dist/ui-src/20-display-content.js +780 -0
- package/dist/ui-src/21-list-content.js +246 -0
- package/dist/ui-src/22-banner-content.js +376 -0
- package/dist/ui-src/23-tooltip.js +276 -0
- package/dist/ui-src/31-form-advanced.js +2784 -0
- package/dist/ui-src/40-navigation.js +1262 -0
- package/dist/ui-src/41-tab-panel.js +896 -0
- package/dist/ui-src/50-feedback.js +999 -0
- package/dist/ui-src/51-feedback-service.js +166 -0
- package/dist/ui-src/60-shell-app.js +1223 -0
- package/dist/ui-src/61-form-service.js +368 -0
- package/dist/ui-src/70-dialog.js +333 -0
- package/dist/ui-src/71-menu-overlays.js +1217 -0
- package/dist/ui-src/80-data.js +437 -0
- package/dist/ui-src/modules.json +212 -0
- package/dist/ui.js +12565 -0
- package/package.json +26 -2
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
// ===============================
|
|
2
|
+
// JSswift UI Kit MVP
|
|
3
|
+
// ===============================
|
|
4
|
+
(function initJSswiftUI(app) {
|
|
5
|
+
app.ui = app.ui || {};
|
|
6
|
+
app.services = app.services || {};
|
|
7
|
+
app.services.notify = app.services.notify || {};
|
|
8
|
+
|
|
9
|
+
const uiRodPathRaw = Symbol("jss.ui.rodPathRaw");
|
|
10
|
+
const uiRodPathEnhanced = Symbol("jss.ui.rodPathEnhanced");
|
|
11
|
+
const uiRodPathPatchedH = Symbol("jss.ui.rodPathPatchedH");
|
|
12
|
+
const uiRodPathWrappedUI = Symbol("jss.ui.rodPathWrappedUI");
|
|
13
|
+
const uiRodPathAccess = new WeakMap();
|
|
14
|
+
const uiRodPathProxyCache = new WeakMap();
|
|
15
|
+
const uiWrappedFunctionCache = new WeakMap();
|
|
16
|
+
const uiRodPathReadBuffer = [];
|
|
17
|
+
const uiIsIndexKey = (key) => {
|
|
18
|
+
if (typeof key === "number") return Number.isInteger(key) && key >= 0;
|
|
19
|
+
if (typeof key !== "string" || key === "") return false;
|
|
20
|
+
if (key[0] === "-" || key.includes(".")) return false;
|
|
21
|
+
const num = Number(key);
|
|
22
|
+
return Number.isInteger(num) && num >= 0 && String(num) === key;
|
|
23
|
+
};
|
|
24
|
+
const uiTrackablePrimitive = (v) => {
|
|
25
|
+
const t = typeof v;
|
|
26
|
+
return t === "string" || t === "number" || t === "boolean" || t === "bigint";
|
|
27
|
+
};
|
|
28
|
+
const uiIsPlainObject = (v) => {
|
|
29
|
+
if (!v || typeof v !== "object") return false;
|
|
30
|
+
const p = Object.getPrototypeOf(v);
|
|
31
|
+
return p === Object.prototype || p === null;
|
|
32
|
+
};
|
|
33
|
+
let uiRodPathReadFlushQueued = false;
|
|
34
|
+
const uiScheduleRodPathReadFlush = () => {
|
|
35
|
+
if (uiRodPathReadFlushQueued) return;
|
|
36
|
+
uiRodPathReadFlushQueued = true;
|
|
37
|
+
queueMicrotask(() => {
|
|
38
|
+
uiRodPathReadFlushQueued = false;
|
|
39
|
+
uiRodPathReadBuffer.length = 0;
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
const uiPushRodPathRead = (entry) => {
|
|
43
|
+
uiRodPathReadBuffer.push(entry);
|
|
44
|
+
if (uiRodPathReadBuffer.length > 128) {
|
|
45
|
+
uiRodPathReadBuffer.splice(0, uiRodPathReadBuffer.length - 128);
|
|
46
|
+
}
|
|
47
|
+
uiScheduleRodPathReadFlush();
|
|
48
|
+
};
|
|
49
|
+
const uiCreateRodPathCursor = () => {
|
|
50
|
+
if (!uiRodPathReadBuffer.length) return null;
|
|
51
|
+
const items = uiRodPathReadBuffer.slice();
|
|
52
|
+
uiRodPathReadBuffer.length = 0;
|
|
53
|
+
return { items, index: 0 };
|
|
54
|
+
};
|
|
55
|
+
const uiTakeRodPathMatch = (cursor, value) => {
|
|
56
|
+
if (!cursor) return null;
|
|
57
|
+
const entry = cursor.items[cursor.index];
|
|
58
|
+
if (!entry) return null;
|
|
59
|
+
if (!Object.is(entry.value, value)) return null;
|
|
60
|
+
cursor.index += 1;
|
|
61
|
+
return entry;
|
|
62
|
+
};
|
|
63
|
+
const uiUnwrapRodPathValue = (v) => {
|
|
64
|
+
if (v && typeof v === "object" && v[uiRodPathRaw]) return v[uiRodPathRaw];
|
|
65
|
+
return v;
|
|
66
|
+
};
|
|
67
|
+
const uiReadRodPath = (rod, path) => {
|
|
68
|
+
const access = uiRodPathAccess.get(rod);
|
|
69
|
+
if (!access) return undefined;
|
|
70
|
+
let cur = access.rawGet();
|
|
71
|
+
for (const key of path) {
|
|
72
|
+
if (cur == null) return undefined;
|
|
73
|
+
cur = cur[key];
|
|
74
|
+
}
|
|
75
|
+
return cur;
|
|
76
|
+
};
|
|
77
|
+
const uiWriteRodPath = (rod, path, nextValue) => {
|
|
78
|
+
const access = uiRodPathAccess.get(rod);
|
|
79
|
+
if (!access) return;
|
|
80
|
+
const unwrapped = uiUnwrapRodPathValue(nextValue);
|
|
81
|
+
if (!path.length) {
|
|
82
|
+
if (Object.is(access.rawGet(), unwrapped)) return;
|
|
83
|
+
access.rawSet(unwrapped);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
let root = access.rawGet();
|
|
87
|
+
if (!root || typeof root !== "object") {
|
|
88
|
+
root = uiIsIndexKey(path[0]) ? [] : {};
|
|
89
|
+
}
|
|
90
|
+
let cur = root;
|
|
91
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
92
|
+
const key = path[i];
|
|
93
|
+
let child = cur[key];
|
|
94
|
+
if (!child || typeof child !== "object") {
|
|
95
|
+
const nextKey = path[i + 1];
|
|
96
|
+
child = uiIsIndexKey(nextKey) ? [] : {};
|
|
97
|
+
cur[key] = child;
|
|
98
|
+
}
|
|
99
|
+
cur = child;
|
|
100
|
+
}
|
|
101
|
+
if (Object.is(cur[path[path.length - 1]], unwrapped)) return;
|
|
102
|
+
cur[path[path.length - 1]] = unwrapped;
|
|
103
|
+
access.rawSet(root);
|
|
104
|
+
};
|
|
105
|
+
const uiCreateRodPathModel = (rod, path) => [
|
|
106
|
+
() => uiReadRodPath(rod, path),
|
|
107
|
+
(nextValue) => uiWriteRodPath(rod, path, nextValue)
|
|
108
|
+
];
|
|
109
|
+
const uiCreateRodPathProxy = (rod, target, path = []) => {
|
|
110
|
+
if (!target || typeof target !== "object") return target;
|
|
111
|
+
let byTarget = uiRodPathProxyCache.get(rod);
|
|
112
|
+
if (!byTarget) {
|
|
113
|
+
byTarget = new WeakMap();
|
|
114
|
+
uiRodPathProxyCache.set(rod, byTarget);
|
|
115
|
+
}
|
|
116
|
+
const cached = byTarget.get(target);
|
|
117
|
+
if (cached) return cached;
|
|
118
|
+
const proxy = new Proxy(target, {
|
|
119
|
+
get(obj, prop, receiver) {
|
|
120
|
+
if (prop === uiRodPathRaw) return obj;
|
|
121
|
+
const value = Reflect.get(obj, prop, receiver);
|
|
122
|
+
if (typeof prop === "symbol") return value;
|
|
123
|
+
const nextPath = path.concat(prop);
|
|
124
|
+
if (value && typeof value === "object") {
|
|
125
|
+
return uiCreateRodPathProxy(rod, value, nextPath);
|
|
126
|
+
}
|
|
127
|
+
if (typeof value === "function") {
|
|
128
|
+
return value.bind(receiver);
|
|
129
|
+
}
|
|
130
|
+
if (uiTrackablePrimitive(value)) {
|
|
131
|
+
uiPushRodPathRead({ rod, path: nextPath, value });
|
|
132
|
+
}
|
|
133
|
+
return value;
|
|
134
|
+
},
|
|
135
|
+
set(obj, prop, value, receiver) {
|
|
136
|
+
const nextValue = uiUnwrapRodPathValue(value);
|
|
137
|
+
const prevValue = Reflect.get(obj, prop, receiver);
|
|
138
|
+
if (Object.is(prevValue, nextValue)) return true;
|
|
139
|
+
const ok = Reflect.set(obj, prop, nextValue, receiver);
|
|
140
|
+
if (ok) {
|
|
141
|
+
const access = uiRodPathAccess.get(rod);
|
|
142
|
+
access?.rawSet(access.rawGet());
|
|
143
|
+
}
|
|
144
|
+
return ok;
|
|
145
|
+
},
|
|
146
|
+
deleteProperty(obj, prop) {
|
|
147
|
+
const hadKey = Reflect.has(obj, prop);
|
|
148
|
+
const ok = Reflect.deleteProperty(obj, prop);
|
|
149
|
+
if (ok && hadKey) {
|
|
150
|
+
const access = uiRodPathAccess.get(rod);
|
|
151
|
+
access?.rawSet(access.rawGet());
|
|
152
|
+
}
|
|
153
|
+
return ok;
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
byTarget.set(target, proxy);
|
|
157
|
+
return proxy;
|
|
158
|
+
};
|
|
159
|
+
const uiEnhanceRodPath = (rod) => {
|
|
160
|
+
if (!rod || typeof rod !== "object" || rod.type !== "rod" || rod[uiRodPathEnhanced]) return rod;
|
|
161
|
+
const desc = Object.getOwnPropertyDescriptor(rod, "value");
|
|
162
|
+
if (!desc || typeof desc.get !== "function" || typeof desc.set !== "function") return rod;
|
|
163
|
+
const rawGet = () => desc.get.call(rod);
|
|
164
|
+
const rawSet = (v) => desc.set.call(rod, uiUnwrapRodPathValue(v));
|
|
165
|
+
uiRodPathAccess.set(rod, { rawGet, rawSet });
|
|
166
|
+
Object.defineProperty(rod, "value", {
|
|
167
|
+
get() {
|
|
168
|
+
const raw = rawGet();
|
|
169
|
+
if (!raw || typeof raw !== "object") return raw;
|
|
170
|
+
return uiCreateRodPathProxy(rod, raw, []);
|
|
171
|
+
},
|
|
172
|
+
set(v) {
|
|
173
|
+
rawSet(v);
|
|
174
|
+
},
|
|
175
|
+
configurable: true
|
|
176
|
+
});
|
|
177
|
+
Object.defineProperty(rod, uiRodPathEnhanced, { value: true, configurable: false });
|
|
178
|
+
return rod;
|
|
179
|
+
};
|
|
180
|
+
const uiPatchRodFactory = () => {
|
|
181
|
+
if (typeof window._.rod !== "function" || window._.rod[uiRodPathEnhanced]) return;
|
|
182
|
+
const baseRod = window._.rod;
|
|
183
|
+
const patchedRod = function patchedRod(...args) {
|
|
184
|
+
return uiEnhanceRodPath(baseRod(...args));
|
|
185
|
+
};
|
|
186
|
+
Object.defineProperty(patchedRod, uiRodPathEnhanced, { value: true, configurable: false });
|
|
187
|
+
window._.rod = patchedRod;
|
|
188
|
+
};
|
|
189
|
+
app.ui.withoutRodPathCapture = (fn) => {
|
|
190
|
+
const length = uiRodPathReadBuffer.length;
|
|
191
|
+
try {
|
|
192
|
+
return fn();
|
|
193
|
+
} finally {
|
|
194
|
+
uiRodPathReadBuffer.length = length;
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
const uiPatchValueForH = (value, cursor, keyHint = "") => {
|
|
198
|
+
if (Array.isArray(value)) {
|
|
199
|
+
let changed = false;
|
|
200
|
+
const next = value.map((item) => {
|
|
201
|
+
const out = uiPatchValueForH(item, cursor, "");
|
|
202
|
+
if (out !== item) changed = true;
|
|
203
|
+
return out;
|
|
204
|
+
});
|
|
205
|
+
return changed ? next : value;
|
|
206
|
+
}
|
|
207
|
+
if (uiTrackablePrimitive(value)) {
|
|
208
|
+
const entry = uiTakeRodPathMatch(cursor, value);
|
|
209
|
+
if (!entry) return value;
|
|
210
|
+
if (keyHint === "model") return uiCreateRodPathModel(entry.rod, entry.path);
|
|
211
|
+
return () => uiReadRodPath(entry.rod, entry.path);
|
|
212
|
+
}
|
|
213
|
+
if (!uiIsPlainObject(value)) return value;
|
|
214
|
+
let changed = false;
|
|
215
|
+
const out = {};
|
|
216
|
+
for (const key of Object.keys(value)) {
|
|
217
|
+
const next = uiPatchValueForH(value[key], cursor, key);
|
|
218
|
+
out[key] = next;
|
|
219
|
+
if (next !== value[key]) changed = true;
|
|
220
|
+
}
|
|
221
|
+
return changed ? out : value;
|
|
222
|
+
};
|
|
223
|
+
const uiPatchValueForUI = (value, cursor, keyHint = "") => {
|
|
224
|
+
if (Array.isArray(value)) {
|
|
225
|
+
let changed = false;
|
|
226
|
+
const next = value.map((item) => {
|
|
227
|
+
const out = uiPatchValueForUI(item, cursor, "");
|
|
228
|
+
if (out !== item) changed = true;
|
|
229
|
+
return out;
|
|
230
|
+
});
|
|
231
|
+
return changed ? next : value;
|
|
232
|
+
}
|
|
233
|
+
if (uiTrackablePrimitive(value)) {
|
|
234
|
+
const entry = uiTakeRodPathMatch(cursor, value);
|
|
235
|
+
if (!entry) return value;
|
|
236
|
+
if (keyHint === "model") return uiCreateRodPathModel(entry.rod, entry.path);
|
|
237
|
+
return () => uiReadRodPath(entry.rod, entry.path);
|
|
238
|
+
}
|
|
239
|
+
if (!uiIsPlainObject(value)) return value;
|
|
240
|
+
let changed = false;
|
|
241
|
+
const out = {};
|
|
242
|
+
for (const key of Object.keys(value)) {
|
|
243
|
+
const shouldPatch = key === "model" || key === "children";
|
|
244
|
+
const next = shouldPatch ? uiPatchValueForUI(value[key], cursor, key) : value[key];
|
|
245
|
+
out[key] = next;
|
|
246
|
+
if (next !== value[key]) changed = true;
|
|
247
|
+
}
|
|
248
|
+
return changed ? out : value;
|
|
249
|
+
};
|
|
250
|
+
const uiWrapUIFunction = (fn) => {
|
|
251
|
+
if (typeof fn !== "function" || fn[uiRodPathWrappedUI]) return fn;
|
|
252
|
+
const cached = uiWrappedFunctionCache.get(fn);
|
|
253
|
+
if (cached) return cached;
|
|
254
|
+
const wrapped = function uiWrappedComponent(...args) {
|
|
255
|
+
const cursor = uiCreateRodPathCursor();
|
|
256
|
+
if (!cursor) return fn.apply(this, args);
|
|
257
|
+
let changed = false;
|
|
258
|
+
const patchedArgs = args.map((arg) => {
|
|
259
|
+
const out = uiPatchValueForUI(arg, cursor, "");
|
|
260
|
+
if (out !== arg) changed = true;
|
|
261
|
+
return out;
|
|
262
|
+
});
|
|
263
|
+
return fn.apply(this, changed ? patchedArgs : args);
|
|
264
|
+
};
|
|
265
|
+
Object.defineProperty(wrapped, uiRodPathWrappedUI, { value: true, configurable: false });
|
|
266
|
+
uiWrappedFunctionCache.set(fn, wrapped);
|
|
267
|
+
return wrapped;
|
|
268
|
+
};
|
|
269
|
+
const uiInstallUIProxy = () => {
|
|
270
|
+
const uiTarget = app.ui;
|
|
271
|
+
if (!uiTarget || uiTarget[uiRodPathWrappedUI]) return;
|
|
272
|
+
Object.defineProperty(uiTarget, uiRodPathWrappedUI, { value: true, configurable: false });
|
|
273
|
+
for (const key of Object.keys(uiTarget)) {
|
|
274
|
+
if (typeof uiTarget[key] === "function") {
|
|
275
|
+
uiTarget[key] = uiWrapUIFunction(uiTarget[key]);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
app.ui = new Proxy(uiTarget, {
|
|
279
|
+
get(target, prop, receiver) {
|
|
280
|
+
return Reflect.get(target, prop, receiver);
|
|
281
|
+
},
|
|
282
|
+
set(target, prop, value, receiver) {
|
|
283
|
+
const next = typeof value === "function" ? uiWrapUIFunction(value) : value;
|
|
284
|
+
return Reflect.set(target, prop, next, receiver);
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
};
|
|
288
|
+
const uiPatchHyperscript = () => {
|
|
289
|
+
if (!window._ || window._[uiRodPathPatchedH]) return;
|
|
290
|
+
Object.defineProperty(window._, uiRodPathPatchedH, { value: true, configurable: false });
|
|
291
|
+
const skipKeys = new Set(["rod", "rodBind", "rodFromSignal"]);
|
|
292
|
+
for (const key of Object.keys(window._)) {
|
|
293
|
+
if (skipKeys.has(key)) continue;
|
|
294
|
+
const base = window._[key];
|
|
295
|
+
if (typeof base !== "function") continue;
|
|
296
|
+
window._[key] = function uiWrappedHyperscript(...args) {
|
|
297
|
+
const cursor = uiCreateRodPathCursor();
|
|
298
|
+
if (!cursor) return base.apply(this, args);
|
|
299
|
+
let changed = false;
|
|
300
|
+
const patchedArgs = args.map((arg) => {
|
|
301
|
+
const out = uiPatchValueForH(arg, cursor, "");
|
|
302
|
+
if (out !== arg) changed = true;
|
|
303
|
+
return out;
|
|
304
|
+
});
|
|
305
|
+
return base.apply(this, changed ? patchedArgs : args);
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
uiPatchRodFactory();
|
|
311
|
+
if (JSswift.rod?._all instanceof Set) {
|
|
312
|
+
JSswift.rod._all.forEach((rod) => uiEnhanceRodPath(rod));
|
|
313
|
+
}
|
|
314
|
+
uiPatchHyperscript();
|
|
315
|
+
uiInstallUIProxy();
|
|
316
|
+
|
|
317
|
+
const UI_STATE_ALIASES = {
|
|
318
|
+
error: "danger",
|
|
319
|
+
danger: "danger",
|
|
320
|
+
warn: "warning",
|
|
321
|
+
warning: "warning",
|
|
322
|
+
success: "success",
|
|
323
|
+
info: "info",
|
|
324
|
+
primary: "primary",
|
|
325
|
+
secondary: "secondary",
|
|
326
|
+
light: "light",
|
|
327
|
+
dark: "dark"
|
|
328
|
+
};
|
|
329
|
+
const UI_STATE_TOKENS = new Set(Object.values(UI_STATE_ALIASES));
|
|
330
|
+
const UI_RADIUS_TOKENS = new Set(["none", "xxs", "xs", "sm", "md", "lg", "xl", "xxl", "xxxl", "full"]);
|