@vortexm/vjt 0.1.0 → 0.1.2
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/index.js
CHANGED
|
@@ -3895,6 +3895,18 @@ function stringifyReferenceValue(value) {
|
|
|
3895
3895
|
}
|
|
3896
3896
|
return JSON.stringify(value);
|
|
3897
3897
|
}
|
|
3898
|
+
function isReferenceValueEmpty(value) {
|
|
3899
|
+
if (value === null || value === void 0) {
|
|
3900
|
+
return true;
|
|
3901
|
+
}
|
|
3902
|
+
if (typeof value === "string") {
|
|
3903
|
+
return value.length === 0;
|
|
3904
|
+
}
|
|
3905
|
+
if (Array.isArray(value)) {
|
|
3906
|
+
return value.length === 0;
|
|
3907
|
+
}
|
|
3908
|
+
return false;
|
|
3909
|
+
}
|
|
3898
3910
|
function getCookieValue(name) {
|
|
3899
3911
|
if (typeof document === "undefined") {
|
|
3900
3912
|
return void 0;
|
|
@@ -3919,16 +3931,27 @@ function getCookieValue(name) {
|
|
|
3919
3931
|
}
|
|
3920
3932
|
return void 0;
|
|
3921
3933
|
}
|
|
3922
|
-
function setCookieValue(name, value) {
|
|
3934
|
+
function setCookieValue(name, value, ttlDays) {
|
|
3923
3935
|
if (typeof document === "undefined") {
|
|
3924
3936
|
return;
|
|
3925
3937
|
}
|
|
3926
|
-
|
|
3938
|
+
const ttlValue = typeof ttlDays === "number" && Number.isFinite(ttlDays) ? ttlDays : null;
|
|
3939
|
+
const expires = ttlValue !== null ? `; max-age=${Math.max(0, Math.round(ttlValue * 24 * 60 * 60))}` : "";
|
|
3940
|
+
document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}; path=/${expires}`;
|
|
3941
|
+
}
|
|
3942
|
+
function getUrlParamValue(name) {
|
|
3943
|
+
if (typeof window === "undefined") {
|
|
3944
|
+
return void 0;
|
|
3945
|
+
}
|
|
3946
|
+
return new URLSearchParams(window.location.search).get(name) ?? void 0;
|
|
3927
3947
|
}
|
|
3928
3948
|
var ReferenceRuntime = class {
|
|
3929
3949
|
constructor(host) {
|
|
3930
3950
|
this.host = host;
|
|
3931
3951
|
}
|
|
3952
|
+
isEmptyReference(reference, currentValue, responseValue) {
|
|
3953
|
+
return isReferenceValueEmpty(this.resolveReference(reference, currentValue, responseValue));
|
|
3954
|
+
}
|
|
3932
3955
|
resolveReference(reference, currentValue, responseValue) {
|
|
3933
3956
|
if (reference === "current") {
|
|
3934
3957
|
return currentValue;
|
|
@@ -3951,6 +3974,9 @@ var ReferenceRuntime = class {
|
|
|
3951
3974
|
if (reference.startsWith("app.")) {
|
|
3952
3975
|
return this.host.getAppValue(reference.slice(4));
|
|
3953
3976
|
}
|
|
3977
|
+
if (reference.startsWith("url.")) {
|
|
3978
|
+
return getUrlParamValue(reference.slice(4));
|
|
3979
|
+
}
|
|
3954
3980
|
const [widgetId, ...rest] = reference.split(".");
|
|
3955
3981
|
const state = this.host.stateById.get(widgetId);
|
|
3956
3982
|
if (!state) {
|
|
@@ -4064,12 +4090,12 @@ var ReferenceRuntime = class {
|
|
|
4064
4090
|
return readPath(state, field.split("."));
|
|
4065
4091
|
}
|
|
4066
4092
|
}
|
|
4067
|
-
assignReference(reference, inputValue, _currentValue) {
|
|
4093
|
+
assignReference(reference, inputValue, _currentValue, options) {
|
|
4068
4094
|
if (reference.startsWith("current.")) {
|
|
4069
4095
|
return;
|
|
4070
4096
|
}
|
|
4071
4097
|
if (reference.startsWith("cookies.")) {
|
|
4072
|
-
setCookieValue(reference.slice(8), stringifyReferenceValue(inputValue));
|
|
4098
|
+
setCookieValue(reference.slice(8), stringifyReferenceValue(inputValue), toFiniteNumber(options?.cookieTtl) ?? void 0);
|
|
4073
4099
|
return;
|
|
4074
4100
|
}
|
|
4075
4101
|
if (reference.startsWith("app.")) {
|
|
@@ -4251,6 +4277,7 @@ var ActionRuntime = class {
|
|
|
4251
4277
|
dispatchWidgetEventImpl;
|
|
4252
4278
|
executeRequest;
|
|
4253
4279
|
resolveReference;
|
|
4280
|
+
isEmptyReference;
|
|
4254
4281
|
assignReference;
|
|
4255
4282
|
resolveMappedValue;
|
|
4256
4283
|
setWidgetEnabled;
|
|
@@ -4258,6 +4285,7 @@ var ActionRuntime = class {
|
|
|
4258
4285
|
setUiReference;
|
|
4259
4286
|
refreshWidgetTree;
|
|
4260
4287
|
renderWidgetTree;
|
|
4288
|
+
navigateTo;
|
|
4261
4289
|
getContextMenuPosition;
|
|
4262
4290
|
setActiveContextMenu;
|
|
4263
4291
|
setActiveModalId;
|
|
@@ -4273,6 +4301,7 @@ var ActionRuntime = class {
|
|
|
4273
4301
|
this.dispatchWidgetEventImpl = options.dispatchWidgetEvent;
|
|
4274
4302
|
this.executeRequest = options.executeRequest;
|
|
4275
4303
|
this.resolveReference = options.resolveReference;
|
|
4304
|
+
this.isEmptyReference = options.isEmptyReference;
|
|
4276
4305
|
this.assignReference = options.assignReference;
|
|
4277
4306
|
this.resolveMappedValue = options.resolveMappedValue;
|
|
4278
4307
|
this.setWidgetEnabled = options.setWidgetEnabled;
|
|
@@ -4280,6 +4309,7 @@ var ActionRuntime = class {
|
|
|
4280
4309
|
this.setUiReference = options.setUiReference;
|
|
4281
4310
|
this.refreshWidgetTree = options.refreshWidgetTree;
|
|
4282
4311
|
this.renderWidgetTree = options.renderWidgetTree;
|
|
4312
|
+
this.navigateTo = options.navigateTo;
|
|
4283
4313
|
this.getContextMenuPosition = options.getContextMenuPosition;
|
|
4284
4314
|
this.setActiveContextMenu = options.setActiveContextMenu;
|
|
4285
4315
|
this.setActiveModalId = options.setActiveModalId;
|
|
@@ -4289,7 +4319,7 @@ var ActionRuntime = class {
|
|
|
4289
4319
|
}
|
|
4290
4320
|
async dispatchWidgetEvent(node, eventName, key, inputValue = null, pointer = null) {
|
|
4291
4321
|
try {
|
|
4292
|
-
if ((eventName === "onClick" || eventName === "onUserValueChange") && !this.isWidgetEnabled(node, key)) {
|
|
4322
|
+
if ((eventName === "onClick" || eventName === "onUserValueChange" || eventName === "onEnter" || eventName === "onShiftEnter" || eventName === "onControlEnter") && !this.isWidgetEnabled(node, key)) {
|
|
4293
4323
|
return;
|
|
4294
4324
|
}
|
|
4295
4325
|
const actions = node.events?.[eventName] ?? (eventName === "onClick" ? this.getInlineActions(node) : void 0);
|
|
@@ -4365,6 +4395,10 @@ var ActionRuntime = class {
|
|
|
4365
4395
|
const requestName = name.slice(8);
|
|
4366
4396
|
return this.executeRequest(requestName, context.currentValue);
|
|
4367
4397
|
}
|
|
4398
|
+
if (name.startsWith("navigate ")) {
|
|
4399
|
+
await this.navigateTo(name.slice(9));
|
|
4400
|
+
return null;
|
|
4401
|
+
}
|
|
4368
4402
|
if (name.startsWith("showMenu ")) {
|
|
4369
4403
|
const menuId = name.slice(9);
|
|
4370
4404
|
const menuState = this.stateById.get(menuId);
|
|
@@ -4418,8 +4452,12 @@ var ActionRuntime = class {
|
|
|
4418
4452
|
if (name.startsWith("equals ")) {
|
|
4419
4453
|
return this.resolveReference(name.slice(7), context.currentValue, context.responseValue) === action.args;
|
|
4420
4454
|
}
|
|
4455
|
+
if (name.startsWith("isEmpty ")) {
|
|
4456
|
+
return this.isEmptyReference(name.slice(8), context.currentValue, context.responseValue);
|
|
4457
|
+
}
|
|
4421
4458
|
if (name.startsWith("set ")) {
|
|
4422
|
-
|
|
4459
|
+
const args = typeof action.args === "object" && action.args !== null && !Array.isArray(action.args) ? action.args : void 0;
|
|
4460
|
+
this.assignReference(name.slice(4), inputValue, context.currentValue, args);
|
|
4423
4461
|
return inputValue;
|
|
4424
4462
|
}
|
|
4425
4463
|
if (name.startsWith("filter ")) {
|
|
@@ -5386,6 +5424,31 @@ function renderContextMenuOverlay(env, menu) {
|
|
|
5386
5424
|
}
|
|
5387
5425
|
|
|
5388
5426
|
// src/lib/widgets/bindings.ts
|
|
5427
|
+
function bindKeyboardSubmitEvents(element, node, key, env) {
|
|
5428
|
+
const hasKeyboardEvents = Boolean(
|
|
5429
|
+
node.events?.onEnter?.length || node.events?.onShiftEnter?.length || node.events?.onControlEnter?.length
|
|
5430
|
+
);
|
|
5431
|
+
if (!hasKeyboardEvents) {
|
|
5432
|
+
return;
|
|
5433
|
+
}
|
|
5434
|
+
element.addEventListener("keydown", (event) => {
|
|
5435
|
+
if (event.key !== "Enter") {
|
|
5436
|
+
return;
|
|
5437
|
+
}
|
|
5438
|
+
let eventName = null;
|
|
5439
|
+
if (event.ctrlKey) {
|
|
5440
|
+
eventName = "onControlEnter";
|
|
5441
|
+
} else if (event.shiftKey) {
|
|
5442
|
+
eventName = "onShiftEnter";
|
|
5443
|
+
} else {
|
|
5444
|
+
eventName = "onEnter";
|
|
5445
|
+
}
|
|
5446
|
+
if (!eventName || !node.events?.[eventName]?.length) {
|
|
5447
|
+
return;
|
|
5448
|
+
}
|
|
5449
|
+
void env.dispatchWidgetEvent(node, eventName, key, env.getActionInputValueForElement(element, node), null);
|
|
5450
|
+
});
|
|
5451
|
+
}
|
|
5389
5452
|
function bindWidgetInputBehavior(root, env) {
|
|
5390
5453
|
for (const input of Array.from(root.querySelectorAll(".vjt-edit"))) {
|
|
5391
5454
|
if (!(input instanceof HTMLInputElement)) {
|
|
@@ -5453,6 +5516,7 @@ function bindWidgetEvents(root, env) {
|
|
|
5453
5516
|
continue;
|
|
5454
5517
|
}
|
|
5455
5518
|
if (element instanceof HTMLInputElement && element.dataset.widget === "edit") {
|
|
5519
|
+
bindKeyboardSubmitEvents(element, node, key, env);
|
|
5456
5520
|
element.addEventListener("input", () => {
|
|
5457
5521
|
const state = env.stateByKey.get(key);
|
|
5458
5522
|
if (state) {
|
|
@@ -5470,6 +5534,7 @@ function bindWidgetEvents(root, env) {
|
|
|
5470
5534
|
continue;
|
|
5471
5535
|
}
|
|
5472
5536
|
if (element instanceof HTMLTextAreaElement && element.dataset.widget === "textarea") {
|
|
5537
|
+
bindKeyboardSubmitEvents(element, node, key, env);
|
|
5473
5538
|
element.addEventListener("input", () => {
|
|
5474
5539
|
const state = env.stateByKey.get(key);
|
|
5475
5540
|
if (state) {
|
|
@@ -5487,6 +5552,7 @@ function bindWidgetEvents(root, env) {
|
|
|
5487
5552
|
continue;
|
|
5488
5553
|
}
|
|
5489
5554
|
if (element instanceof HTMLInputElement && element.dataset.widget === "checkbox") {
|
|
5555
|
+
bindKeyboardSubmitEvents(element, node, key, env);
|
|
5490
5556
|
element.addEventListener("change", () => {
|
|
5491
5557
|
const state = env.stateByKey.get(key);
|
|
5492
5558
|
if (state) {
|
|
@@ -5504,6 +5570,7 @@ function bindWidgetEvents(root, env) {
|
|
|
5504
5570
|
continue;
|
|
5505
5571
|
}
|
|
5506
5572
|
if (element instanceof HTMLSelectElement && (element.dataset.widget === "listbox" || element.dataset.widget === "combobox")) {
|
|
5573
|
+
bindKeyboardSubmitEvents(element, node, key, env);
|
|
5507
5574
|
element.addEventListener("change", () => {
|
|
5508
5575
|
const state = env.stateByKey.get(key);
|
|
5509
5576
|
if (state) {
|
|
@@ -5521,6 +5588,7 @@ function bindWidgetEvents(root, env) {
|
|
|
5521
5588
|
continue;
|
|
5522
5589
|
}
|
|
5523
5590
|
if (element instanceof HTMLInputElement && element.dataset.widget === "radio-group") {
|
|
5591
|
+
bindKeyboardSubmitEvents(element, node, key, env);
|
|
5524
5592
|
element.addEventListener("change", () => {
|
|
5525
5593
|
const state = env.stateByKey.get(key);
|
|
5526
5594
|
if (state) {
|
|
@@ -5855,6 +5923,7 @@ var RuntimeRenderer = class {
|
|
|
5855
5923
|
actionsMap;
|
|
5856
5924
|
requestsMap;
|
|
5857
5925
|
sseConfigs;
|
|
5926
|
+
systemEvents;
|
|
5858
5927
|
resourceManager;
|
|
5859
5928
|
actionFunctions;
|
|
5860
5929
|
backendUrl;
|
|
@@ -5895,6 +5964,7 @@ var RuntimeRenderer = class {
|
|
|
5895
5964
|
this.requestsMap = options.requestsMap ?? this.resourceManager?.getRequestsMap() ?? {};
|
|
5896
5965
|
const resolvedSseConfigs = options.sseConfigs ?? this.resourceManager?.getSseConfigs() ?? [];
|
|
5897
5966
|
this.sseConfigs = Array.isArray(resolvedSseConfigs) ? resolvedSseConfigs : resolvedSseConfigs ? [resolvedSseConfigs] : [];
|
|
5967
|
+
this.systemEvents = options.systemEvents ?? this.resourceManager?.getSystemEvents() ?? {};
|
|
5898
5968
|
this.actionFunctions = options.actionFunctions ?? {};
|
|
5899
5969
|
this.backendUrl = options.backendUrl;
|
|
5900
5970
|
this.initialRuntimeSnapshot = options.runtimeSnapshot ? deepClone(options.runtimeSnapshot) : null;
|
|
@@ -5910,6 +5980,8 @@ var RuntimeRenderer = class {
|
|
|
5910
5980
|
return this.language;
|
|
5911
5981
|
case "theme":
|
|
5912
5982
|
return this.theme;
|
|
5983
|
+
case "urlPath":
|
|
5984
|
+
return typeof window === "undefined" ? "" : window.location.pathname;
|
|
5913
5985
|
default:
|
|
5914
5986
|
return void 0;
|
|
5915
5987
|
}
|
|
@@ -5923,6 +5995,15 @@ var RuntimeRenderer = class {
|
|
|
5923
5995
|
this.theme = typeof value === "boolean" ? value ? "light" : "dark" : value === "light" || value === "dark" ? value : "dark";
|
|
5924
5996
|
document.documentElement.dataset.vjtTheme = this.theme;
|
|
5925
5997
|
break;
|
|
5998
|
+
case "urlPath": {
|
|
5999
|
+
if (typeof window === "undefined") {
|
|
6000
|
+
break;
|
|
6001
|
+
}
|
|
6002
|
+
const nextPath = typeof value === "string" && value.trim() ? value.trim() : "/";
|
|
6003
|
+
const normalizedPath = nextPath.startsWith("/") ? nextPath : `/${nextPath}`;
|
|
6004
|
+
window.history.replaceState(window.history.state, "", `${normalizedPath}${window.location.search}${window.location.hash}`);
|
|
6005
|
+
break;
|
|
6006
|
+
}
|
|
5926
6007
|
default:
|
|
5927
6008
|
break;
|
|
5928
6009
|
}
|
|
@@ -5948,7 +6029,8 @@ var RuntimeRenderer = class {
|
|
|
5948
6029
|
dispatchWidgetEvent: (node, eventName, key, inputValue, pointer) => this.actionRuntime.dispatchWidgetEvent(node, eventName, key, inputValue, pointer),
|
|
5949
6030
|
executeRequest: (requestName, currentValue) => this.networkRuntime.executeRequest(requestName, currentValue),
|
|
5950
6031
|
resolveReference: (reference, currentValue, responseValue) => this.referenceRuntime.resolveReference(reference, currentValue, responseValue),
|
|
5951
|
-
|
|
6032
|
+
isEmptyReference: (reference, currentValue, responseValue) => this.referenceRuntime.isEmptyReference(reference, currentValue, responseValue),
|
|
6033
|
+
assignReference: (reference, inputValue, currentValue, options2) => this.referenceRuntime.assignReference(reference, inputValue, currentValue, options2),
|
|
5952
6034
|
resolveMappedValue: (template, currentValue, responseValue) => this.referenceRuntime.resolveMappedValue(template, currentValue, responseValue),
|
|
5953
6035
|
setWidgetEnabled: (widgetId, enabled) => this.setWidgetEnabled(widgetId, enabled),
|
|
5954
6036
|
clearWidget: (widgetId) => this.clearWidget(widgetId),
|
|
@@ -5968,6 +6050,7 @@ var RuntimeRenderer = class {
|
|
|
5968
6050
|
},
|
|
5969
6051
|
refreshWidgetTree: (widgetId) => this.refreshWidgetTree(widgetId),
|
|
5970
6052
|
renderWidgetTree: (widgetId) => this.renderWidgetTree(widgetId),
|
|
6053
|
+
navigateTo: (url) => this.navigateTo(url),
|
|
5971
6054
|
getContextMenuPosition: (menuId, pointer) => getContextMenuPosition(menuId, pointer ?? null, this.lastPointer, this.nodeById),
|
|
5972
6055
|
setActiveContextMenu: (menu) => {
|
|
5973
6056
|
this.activeContextMenu = menu;
|
|
@@ -5996,7 +6079,9 @@ var RuntimeRenderer = class {
|
|
|
5996
6079
|
this.afterRender = options.afterRender;
|
|
5997
6080
|
this.onRuntimeSnapshot = options.onRuntimeSnapshot ?? this.onRuntimeSnapshot;
|
|
5998
6081
|
const render = async () => {
|
|
6082
|
+
await this.runSystemEvent("onBeforeRender");
|
|
5999
6083
|
await this.rerenderRoot();
|
|
6084
|
+
await this.runSystemEvent("onAfterRender");
|
|
6000
6085
|
};
|
|
6001
6086
|
const renderSync = () => {
|
|
6002
6087
|
void render().catch((error) => {
|
|
@@ -6064,6 +6149,27 @@ var RuntimeRenderer = class {
|
|
|
6064
6149
|
}
|
|
6065
6150
|
return Promise.resolve();
|
|
6066
6151
|
}
|
|
6152
|
+
async runSystemEvent(eventName) {
|
|
6153
|
+
const actions = this.systemEvents[eventName];
|
|
6154
|
+
if (!actions?.length) {
|
|
6155
|
+
return;
|
|
6156
|
+
}
|
|
6157
|
+
await this.actionRuntime.runActions(actions, null, { currentValue: null });
|
|
6158
|
+
}
|
|
6159
|
+
async navigateTo(url) {
|
|
6160
|
+
if (typeof window === "undefined" || !url.trim()) {
|
|
6161
|
+
return;
|
|
6162
|
+
}
|
|
6163
|
+
const nextUrl = new URL(url, window.location.href);
|
|
6164
|
+
if (nextUrl.origin !== window.location.origin) {
|
|
6165
|
+
window.location.assign(nextUrl.toString());
|
|
6166
|
+
return;
|
|
6167
|
+
}
|
|
6168
|
+
window.history.pushState(window.history.state, "", `${nextUrl.pathname}${nextUrl.search}${nextUrl.hash}`);
|
|
6169
|
+
await this.runSystemEvent("onBeforeNavigate");
|
|
6170
|
+
await this.rerenderRoot();
|
|
6171
|
+
await this.runSystemEvent("onAfterNavigate");
|
|
6172
|
+
}
|
|
6067
6173
|
reindexStaticTree() {
|
|
6068
6174
|
this.nodeByKey.clear();
|
|
6069
6175
|
this.nodeById.clear();
|
|
@@ -7026,6 +7132,7 @@ var ResourceManager = class {
|
|
|
7026
7132
|
actions = {};
|
|
7027
7133
|
requests = {};
|
|
7028
7134
|
sse = {};
|
|
7135
|
+
systemEvents = {};
|
|
7029
7136
|
i18n = {};
|
|
7030
7137
|
styles = {};
|
|
7031
7138
|
constructor(input = {}) {
|
|
@@ -7035,6 +7142,7 @@ var ResourceManager = class {
|
|
|
7035
7142
|
this.actions = { ...input.actions ?? {} };
|
|
7036
7143
|
this.requests = { ...input.requests ?? {} };
|
|
7037
7144
|
this.sse = { ...input.sse ?? {} };
|
|
7145
|
+
this.systemEvents = { ...input.systemEvents ?? {} };
|
|
7038
7146
|
this.i18n = { ...input.i18n ?? {} };
|
|
7039
7147
|
this.styles = { ...input.styles ?? {} };
|
|
7040
7148
|
}
|
|
@@ -7053,6 +7161,9 @@ var ResourceManager = class {
|
|
|
7053
7161
|
getSseConfigs() {
|
|
7054
7162
|
return Object.values(this.sse);
|
|
7055
7163
|
}
|
|
7164
|
+
getSystemEvents() {
|
|
7165
|
+
return this.systemEvents;
|
|
7166
|
+
}
|
|
7056
7167
|
getI18n() {
|
|
7057
7168
|
return this.i18n;
|
|
7058
7169
|
}
|
|
@@ -19,13 +19,17 @@ type ActionRuntimeOptions = {
|
|
|
19
19
|
} | null) => Promise<void>;
|
|
20
20
|
executeRequest: (requestName: string, currentValue: unknown) => Promise<unknown>;
|
|
21
21
|
resolveReference: (reference: string, currentValue: unknown, responseValue: unknown) => unknown;
|
|
22
|
-
|
|
22
|
+
isEmptyReference: (reference: string, currentValue: unknown, responseValue: unknown) => boolean;
|
|
23
|
+
assignReference: (reference: string, inputValue: unknown, currentValue: unknown, options?: {
|
|
24
|
+
cookieTtl?: unknown;
|
|
25
|
+
}) => void;
|
|
23
26
|
resolveMappedValue: (template: unknown, currentValue: unknown, responseValue: unknown) => unknown;
|
|
24
27
|
setWidgetEnabled: (widgetId: string, enabled: boolean) => void;
|
|
25
28
|
clearWidget: (widgetId: string) => void;
|
|
26
29
|
setUiReference: (widgetId: string, resourceRef: string) => void;
|
|
27
30
|
refreshWidgetTree: (widgetId: string) => Promise<void>;
|
|
28
31
|
renderWidgetTree: (widgetId: string) => Promise<void>;
|
|
32
|
+
navigateTo: (url: string) => Promise<void>;
|
|
29
33
|
getContextMenuPosition: (menuId: string, pointer?: {
|
|
30
34
|
x: number;
|
|
31
35
|
y: number;
|
|
@@ -52,6 +56,7 @@ export declare class ActionRuntime {
|
|
|
52
56
|
private readonly dispatchWidgetEventImpl;
|
|
53
57
|
private readonly executeRequest;
|
|
54
58
|
private readonly resolveReference;
|
|
59
|
+
private readonly isEmptyReference;
|
|
55
60
|
private readonly assignReference;
|
|
56
61
|
private readonly resolveMappedValue;
|
|
57
62
|
private readonly setWidgetEnabled;
|
|
@@ -59,6 +64,7 @@ export declare class ActionRuntime {
|
|
|
59
64
|
private readonly setUiReference;
|
|
60
65
|
private readonly refreshWidgetTree;
|
|
61
66
|
private readonly renderWidgetTree;
|
|
67
|
+
private readonly navigateTo;
|
|
62
68
|
private readonly getContextMenuPosition;
|
|
63
69
|
private readonly setActiveContextMenu;
|
|
64
70
|
private readonly setActiveModalId;
|
package/dist/lib/references.d.ts
CHANGED
|
@@ -13,10 +13,13 @@ type ReferenceRuntimeHost = {
|
|
|
13
13
|
export declare class ReferenceRuntime {
|
|
14
14
|
private readonly host;
|
|
15
15
|
constructor(host: ReferenceRuntimeHost);
|
|
16
|
+
isEmptyReference(reference: string, currentValue: unknown, responseValue: unknown): boolean;
|
|
16
17
|
resolveReference(reference: string, currentValue: unknown, responseValue: unknown): unknown;
|
|
17
18
|
resolveCurrentReference(reference: string, currentValue: unknown): unknown;
|
|
18
19
|
readWidgetField(state: WidgetState, field: string): unknown;
|
|
19
|
-
assignReference(reference: string, inputValue: unknown, _currentValue: unknown
|
|
20
|
+
assignReference(reference: string, inputValue: unknown, _currentValue: unknown, options?: {
|
|
21
|
+
cookieTtl?: unknown;
|
|
22
|
+
}): void;
|
|
20
23
|
clearListElementState(listKey: string): void;
|
|
21
24
|
resolveMappedValue(template: unknown, currentValue: unknown, responseValue: unknown): unknown;
|
|
22
25
|
isListElementContext(value: unknown): value is ListElementContext;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { ActionMap, DescriptionNode, I18nMap, RequestMap, SseConfig, StyleMap } from './types.js';
|
|
1
|
+
import type { ActionMap, DescriptionNode, I18nMap, RequestMap, SseConfig, SystemEventsMap, StyleMap } from './types.js';
|
|
2
2
|
export type ResourceManagerInput = {
|
|
3
3
|
ui?: Record<string, DescriptionNode>;
|
|
4
4
|
actions?: ActionMap;
|
|
5
5
|
requests?: RequestMap;
|
|
6
6
|
sse?: Record<string, SseConfig>;
|
|
7
|
+
systemEvents?: SystemEventsMap;
|
|
7
8
|
i18n?: I18nMap;
|
|
8
9
|
styles?: StyleMap;
|
|
9
10
|
};
|
|
@@ -12,6 +13,7 @@ export declare class ResourceManager {
|
|
|
12
13
|
private actions;
|
|
13
14
|
private requests;
|
|
14
15
|
private sse;
|
|
16
|
+
private systemEvents;
|
|
15
17
|
private i18n;
|
|
16
18
|
private styles;
|
|
17
19
|
constructor(input?: ResourceManagerInput);
|
|
@@ -20,6 +22,7 @@ export declare class ResourceManager {
|
|
|
20
22
|
getActionsMap(): ActionMap;
|
|
21
23
|
getRequestsMap(): RequestMap;
|
|
22
24
|
getSseConfigs(): SseConfig[];
|
|
25
|
+
getSystemEvents(): SystemEventsMap;
|
|
23
26
|
getI18n(): I18nMap;
|
|
24
27
|
getStyleMap(): StyleMap;
|
|
25
28
|
}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -3,7 +3,8 @@ export type LayoutType = 'vertical' | 'horizontal' | 'grid';
|
|
|
3
3
|
export type TextAlign = 'left' | 'center' | 'right';
|
|
4
4
|
export type VerticalAlign = 'top' | 'center' | 'bottom';
|
|
5
5
|
export type HeadingTag = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
6
|
-
export type WidgetEventName = 'onClick' | 'onUserValueChange' | 'onRefresh';
|
|
6
|
+
export type WidgetEventName = 'onClick' | 'onUserValueChange' | 'onRefresh' | 'onEnter' | 'onShiftEnter' | 'onControlEnter';
|
|
7
|
+
export type SystemEventName = 'onBeforeRender' | 'onAfterRender' | 'onBeforeNavigate' | 'onAfterNavigate';
|
|
7
8
|
export type PrimitiveRequestType = 'int' | 'float' | 'boolean' | 'string';
|
|
8
9
|
export type ActionDefinition = {
|
|
9
10
|
action: string;
|
|
@@ -84,6 +85,7 @@ export type I18nMap = Record<string, Record<string, string>>;
|
|
|
84
85
|
export type ActionMap = Record<string, ActionDefinition[]>;
|
|
85
86
|
export type RequestMap = Record<string, RequestDefinition>;
|
|
86
87
|
export type SseConfigInput = SseConfig | SseConfig[];
|
|
88
|
+
export type SystemEventsMap = Partial<Record<SystemEventName, ActionDefinition[]>>;
|
|
87
89
|
export type WidgetState = {
|
|
88
90
|
key: string;
|
|
89
91
|
widget: DescriptionNode['widget'];
|
|
@@ -132,6 +134,7 @@ export type RenderJsonOptions = {
|
|
|
132
134
|
actionsMap?: ActionMap;
|
|
133
135
|
requestsMap?: RequestMap;
|
|
134
136
|
sseConfigs?: SseConfigInput;
|
|
137
|
+
systemEvents?: SystemEventsMap;
|
|
135
138
|
actionFunctions?: Record<string, () => unknown>;
|
|
136
139
|
backendUrl?: string;
|
|
137
140
|
resourceManager?: ResourceManager;
|
|
@@ -12,7 +12,7 @@ type BindingEnvironment = {
|
|
|
12
12
|
}) => void;
|
|
13
13
|
updatePointerFromEvent: (event: MouseEvent) => void;
|
|
14
14
|
updateOwningListElementDescriptor: (element: HTMLElement, mutate: (descriptor: DescriptionNode) => void) => void;
|
|
15
|
-
dispatchWidgetEvent: (node: DescriptionNode, eventName: 'onClick' | 'onUserValueChange', key: string, inputValue?: unknown, pointer?: {
|
|
15
|
+
dispatchWidgetEvent: (node: DescriptionNode, eventName: 'onClick' | 'onUserValueChange' | 'onEnter' | 'onShiftEnter' | 'onControlEnter', key: string, inputValue?: unknown, pointer?: {
|
|
16
16
|
x: number;
|
|
17
17
|
y: number;
|
|
18
18
|
} | null) => Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vortexm/vjt",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -25,12 +25,12 @@
|
|
|
25
25
|
"scripts": {
|
|
26
26
|
"build": "npm run build:lib && npm run build:examples && npm run build:types",
|
|
27
27
|
"build:lib": "esbuild src/index.ts --bundle --format=esm --outfile=dist/index.js --loader:.json=json",
|
|
28
|
-
"build:examples": "esbuild
|
|
28
|
+
"build:examples": "esbuild examples/app/examples-app.ts --bundle --format=esm --outfile=dist/examples.js --loader:.json=json",
|
|
29
29
|
"build:types": "tsc -p tsconfig.build.json",
|
|
30
|
-
"watch": "esbuild src/index.ts
|
|
30
|
+
"watch": "esbuild src/index.ts examples/app/examples-app.ts --bundle --format=esm --outdir=dist --loader:.json=json --watch",
|
|
31
31
|
"typecheck": "tsc -p tsconfig.json",
|
|
32
32
|
"lint": "eslint \"src/**/*.ts\"",
|
|
33
|
-
"serve": "
|
|
33
|
+
"serve": "node ./demo/examples-server.mjs",
|
|
34
34
|
"serve:mock-backend": "node ./mock-backend/server.mjs",
|
|
35
35
|
"dev": "concurrently \"npm:watch\" \"npm:serve\" \"npm:serve:mock-backend\"",
|
|
36
36
|
"prepack": "npm run build"
|
package/vjt-styles.css
CHANGED
|
@@ -33,6 +33,33 @@ html {
|
|
|
33
33
|
--vjt-font-heading: Georgia, "Times New Roman", serif;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
:root {
|
|
37
|
+
background: var(--vjt-bg);
|
|
38
|
+
color: var(--vjt-text);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
* {
|
|
42
|
+
box-sizing: border-box;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
html,
|
|
46
|
+
body {
|
|
47
|
+
min-height: 100%;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
body {
|
|
51
|
+
margin: 0;
|
|
52
|
+
min-height: 100vh;
|
|
53
|
+
background:
|
|
54
|
+
radial-gradient(circle at top left, var(--vjt-bg-glow), transparent 28%),
|
|
55
|
+
linear-gradient(180deg, color-mix(in srgb, var(--vjt-bg) 88%, white) 0%, var(--vjt-bg) 100%);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
#app {
|
|
59
|
+
width: 100%;
|
|
60
|
+
min-height: 100vh;
|
|
61
|
+
}
|
|
62
|
+
|
|
36
63
|
.vjt-static-text,
|
|
37
64
|
.vjt-md-text,
|
|
38
65
|
.vjt-edit,
|