tauri-kargo-tools 0.1.5 → 0.1.7
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/package.json +3 -3
- package/{dist → src}/builder/boot-vue.ts +2 -2
- package/{dist → src}/builder/button.ts +3 -3
- package/{dist → src}/builder/custom.ts +2 -1
- package/{dist → src}/builder/dialog.ts +2 -1
- package/{dist → src}/builder/flow.ts +2 -1
- package/{dist → src}/builder/img.ts +2 -1
- package/{dist → src}/builder/input.ts +10 -10
- package/src/builder/label.ts +43 -0
- package/{dist → src}/builder/list-of-vue.ts +19 -4
- package/{dist → src}/builder/menu.ts +2 -1
- package/{dist → src}/builder/select.ts +2 -1
- package/src/builder/space.ts +13 -0
- package/{dist → src}/builder/vue.ts +4 -1
- package/{dist → src/css}/vue-darkmode.css +10 -4
- package/{dist → src/css}/vue-lightmode.css +9 -3
- package/src/model/boot-vue.ts +58 -0
- package/src/model/button.ts +48 -0
- package/src/model/custom.ts +27 -0
- package/src/model/dialog.ts +28 -0
- package/src/model/flow.ts +19 -0
- package/src/model/img.ts +21 -0
- package/src/model/input.ts +25 -0
- package/src/model/label.ts +35 -0
- package/src/model/list-of-vue.ts +25 -0
- package/src/model/menu.ts +28 -0
- package/src/model/select.ts +27 -0
- package/src/model/space.ts +5 -0
- package/src/model/vue.ts +14 -0
- package/src/test/chat.png +0 -0
- package/src/test/chien.png +0 -0
- package/src/test/edit-2-line.png +0 -0
- package/src/test/folder-add-line.png +0 -0
- package/src/test/folder-reduce-line.png +0 -0
- package/src/test/index.ts +42 -0
- package/src/test/test-model-panel.ts +3 -0
- package/src/test/test-model.ts +461 -0
- package/src/test/test-polymorphe.ts +158 -0
- package/src/test/test-table.ts +53 -0
- package/src/test/test-vue-boot.ts +91 -0
- package/src/test/test-vue-panel.ts +162 -0
- package/src/test/test-vue.ts +113 -0
- package/{dist → src}/vue-builder.ts +48 -14
- package/{dist → src}/vue-model.ts +70 -344
- package/src/vue.ts +26 -0
- package/dist/builder/label.ts +0 -31
- package/dist/vue.ts +0 -16
- /package/{dist → src}/api.ts +0 -0
- /package/{dist → src}/container.ts +0 -0
- /package/{dist → src}/listener-factory.ts +0 -0
- /package/{dist → src}/listener.ts +0 -0
- /package/{dist → src}/test.ts +0 -0
- /package/{dist → src}/types.ts +0 -0
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tauri-kargo-tools",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "",
|
|
5
|
-
"files": ["
|
|
6
|
-
"exports": { "./*": "./
|
|
5
|
+
"files": ["src"],
|
|
6
|
+
"exports": { "./*": "./src/*" },
|
|
7
7
|
"publishConfig": { "access": "public" },
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// ./builder/boot-vue.ts
|
|
2
|
+
import { BootVueNode, StaticBootVueNode } from "../model/boot-vue";
|
|
2
3
|
import {
|
|
3
4
|
Builder,
|
|
4
5
|
Ctx,
|
|
@@ -8,8 +9,7 @@ import {
|
|
|
8
9
|
bindEnabled,
|
|
9
10
|
} from "../vue-builder";
|
|
10
11
|
import {
|
|
11
|
-
|
|
12
|
-
StaticBootVueNode,
|
|
12
|
+
|
|
13
13
|
Vue,
|
|
14
14
|
} from "../vue-model";
|
|
15
15
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { ButtonNode, StaticButtonNode } from "../model/button";
|
|
2
|
+
import { applyIdAndClass, applySize, bindEnabled, bindVisible, bindVisibleEnabled, Builder, Ctx } from "../vue-builder";
|
|
3
|
+
|
|
3
4
|
|
|
4
5
|
/* ----------- Button ----------- */
|
|
5
6
|
export function buildStaticButton<T extends object>(builder: Builder, node: StaticButtonNode<T>, ctx: Ctx<T>) {
|
|
@@ -106,7 +107,6 @@ export function buildButton<T extends object>(builder: Builder, node: ButtonNode
|
|
|
106
107
|
});
|
|
107
108
|
ctx.dataUnsubs.push(offAlt);
|
|
108
109
|
}
|
|
109
|
-
|
|
110
110
|
bindVisibleEnabled(node, btn, ctx);
|
|
111
111
|
|
|
112
112
|
const onClick = () => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { CustomNode } from "../model/custom";
|
|
1
2
|
import { applyIdAndClass, applySize, bindVisibleEnabled, Builder, Ctx } from "../vue-builder";
|
|
2
|
-
|
|
3
|
+
|
|
3
4
|
|
|
4
5
|
/* ----------- Custom ----------- */
|
|
5
6
|
export function buildCustom<T extends object>(builder:Builder,node: CustomNode<T, any, any>, ctx: Ctx<T>) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { DialogNode } from "../model/dialog";
|
|
1
2
|
import { applyIdAndClass, applySize, bindVisibleEnabled, Builder, Ctx, VueRuntime } from "../vue-builder";
|
|
2
|
-
import {
|
|
3
|
+
import { Vue } from "../vue-model";
|
|
3
4
|
|
|
4
5
|
/* ----------- Dialog ----------- */
|
|
5
6
|
export function buildDialog<T extends object>(builder:Builder,node: DialogNode<T>, ctx: Ctx<T>) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { FlowNode } from "../model/flow";
|
|
1
2
|
import { applyIdAndClass, applySize, Builder, Ctx } from "../vue-builder";
|
|
2
|
-
|
|
3
|
+
|
|
3
4
|
|
|
4
5
|
/* ----------- Flow ----------- */
|
|
5
6
|
export function buildFlow<T extends object>(builder:Builder,node: FlowNode<T>, ctx: Ctx<T>) {
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
+
import { InputNode } from "../model/input";
|
|
1
2
|
import { applyIdAndClass, applySize, bindEnabled, bindVisible, Builder, Ctx } from "../vue-builder";
|
|
2
|
-
|
|
3
|
+
|
|
3
4
|
|
|
4
5
|
/* ----------- Input ----------- */
|
|
5
6
|
export function buildInput<T extends object>(builder: Builder, node: InputNode<T, any>, ctx: Ctx<T>) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (node.label) wrapper.append(document.createTextNode(node.label + ' '));
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
10
|
|
|
11
11
|
const input = document.createElement('input');
|
|
12
|
-
applySize(
|
|
13
|
-
|
|
12
|
+
applySize(input, node.width, node.height);
|
|
13
|
+
applyIdAndClass(input, node);
|
|
14
14
|
const current = (ctx.obj as any)[node.name];
|
|
15
15
|
const typeGuess =
|
|
16
16
|
node.inputType ??
|
|
@@ -31,11 +31,11 @@ export function buildInput<T extends object>(builder: Builder, node: InputNode<T
|
|
|
31
31
|
(input as HTMLInputElement).value = (current ?? '') as any as string;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
ctx.add(
|
|
34
|
+
|
|
35
|
+
ctx.add(input);
|
|
36
36
|
|
|
37
37
|
// visible / enable factorisés
|
|
38
|
-
bindVisible(node,
|
|
38
|
+
bindVisible(node, input, ctx);
|
|
39
39
|
bindEnabled(node, input, ctx);
|
|
40
40
|
|
|
41
41
|
// modèle -> UI
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { LabelNode, StaticLabelNode } from "../model/label";
|
|
2
|
+
import { applyIdAndClass, applySize, bindVisibleEnabled, Builder, Ctx } from "../vue-builder";
|
|
3
|
+
|
|
4
|
+
/* ----------- Label ----------- */
|
|
5
|
+
export function buildLabel<T extends object>(builder: Builder, node: LabelNode<T, any>, ctx: Ctx<T>) {
|
|
6
|
+
const span = document.createElement('span');
|
|
7
|
+
applyIdAndClass(span, node);
|
|
8
|
+
applySize(span, node.width, node.height);
|
|
9
|
+
|
|
10
|
+
// Multi-ligne + espace intérieur sans changer la taille totale
|
|
11
|
+
span.style.whiteSpace = 'pre-line';
|
|
12
|
+
span.style.display = 'inline-block';
|
|
13
|
+
span.style.boxSizing = 'border-box';
|
|
14
|
+
span.style.padding = '4px 6px'; // ← espace texte/bord
|
|
15
|
+
|
|
16
|
+
span.textContent = String((ctx.obj as any)[node.name] ?? '');
|
|
17
|
+
ctx.add(span);
|
|
18
|
+
|
|
19
|
+
bindVisibleEnabled(node, span, ctx);
|
|
20
|
+
|
|
21
|
+
const offData = ctx.listener.listen(node.name as keyof T, (v) => {
|
|
22
|
+
const s = String(v ?? '');
|
|
23
|
+
if (span.textContent !== s) span.textContent = s;
|
|
24
|
+
});
|
|
25
|
+
ctx.dataUnsubs.push(offData);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* ----------- Static Label ----------- */
|
|
29
|
+
export function buildStaticLabel<T extends object>(builder: Builder, node: StaticLabelNode<T>, ctx: Ctx<T>) {
|
|
30
|
+
const span = document.createElement('span');
|
|
31
|
+
applyIdAndClass(span, node);
|
|
32
|
+
applySize(span, node.width, node.height);
|
|
33
|
+
|
|
34
|
+
span.style.whiteSpace = 'pre-line';
|
|
35
|
+
span.style.display = 'inline-block';
|
|
36
|
+
span.style.boxSizing = 'border-box';
|
|
37
|
+
span.style.padding = '4px 6px';
|
|
38
|
+
|
|
39
|
+
span.textContent = node.label;
|
|
40
|
+
ctx.add(span);
|
|
41
|
+
|
|
42
|
+
bindVisibleEnabled(node, span, ctx);
|
|
43
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { ListVueNode } from "../model/list-of-vue";
|
|
2
|
+
import { applyIdAndClass, applySize, bindEnabled, bindVisible, Builder, Ctx, VueRuntime } from "../vue-builder";
|
|
3
|
+
import { Vue } from "../vue-model";
|
|
3
4
|
|
|
4
5
|
/* ----------- List UI (liste d'objets) ----------- */
|
|
5
6
|
export function buildListOfVue<T extends object>(builder: Builder, node: ListVueNode<T>, ctx: Ctx<T>) {
|
|
@@ -8,7 +9,8 @@ export function buildListOfVue<T extends object>(builder: Builder, node: ListVue
|
|
|
8
9
|
div.style.display = 'flex';
|
|
9
10
|
div.style.flexDirection = (node.orientation ?? 'column') === 'row' ? 'row' : 'column';
|
|
10
11
|
applySize(div, node.width, node.height);
|
|
11
|
-
|
|
12
|
+
// bindVisible(node, div, ctx);
|
|
13
|
+
bindEnabled(node, div, ctx);
|
|
12
14
|
if (node.gap !== undefined) (div.style as any).gap = typeof node.gap === 'number' ? `${node.gap}px` : String(node.gap);
|
|
13
15
|
const mapJustify: Record<string, string> = {
|
|
14
16
|
start: 'flex-start', end: 'flex-end', center: 'center',
|
|
@@ -36,7 +38,14 @@ export function buildListOfVue<T extends object>(builder: Builder, node: ListVue
|
|
|
36
38
|
|
|
37
39
|
const render = () => {
|
|
38
40
|
clear();
|
|
39
|
-
|
|
41
|
+
let visible = true
|
|
42
|
+
if (node.visible) {
|
|
43
|
+
visible = !!(ctx.obj as any)[node.visible]
|
|
44
|
+
}
|
|
45
|
+
let arr: any = [];
|
|
46
|
+
if (visible) {
|
|
47
|
+
arr = ((ctx.obj as any)[node.list] ?? []) as any[];
|
|
48
|
+
}
|
|
40
49
|
for (const item of arr) {
|
|
41
50
|
const ui = builder.findVueFor(item);
|
|
42
51
|
if (!ui) continue;
|
|
@@ -59,7 +68,13 @@ export function buildListOfVue<T extends object>(builder: Builder, node: ListVue
|
|
|
59
68
|
render();
|
|
60
69
|
const off = ctx.listener.listen(node.list as keyof T, () => render());
|
|
61
70
|
ctx.dataUnsubs.push(off);
|
|
71
|
+
if (node.visible) {
|
|
72
|
+
const offVisible = ctx.listener.listen(node.visible as keyof T, () => render());
|
|
73
|
+
ctx.dataUnsubs.push(offVisible);
|
|
74
|
+
}
|
|
75
|
+
|
|
62
76
|
ctx.domUnsubs.push(() => clear());
|
|
63
77
|
|
|
64
78
|
ctx.add(div);
|
|
79
|
+
|
|
65
80
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { MenuNode } from "../model/menu";
|
|
1
2
|
import { applyIdAndClass, applySize, bindVisibleEnabled, Builder, clamp, Ctx, VueRuntime } from "../vue-builder";
|
|
2
|
-
import {
|
|
3
|
+
import { Vue } from "../vue-model";
|
|
3
4
|
/* ----------- Menu (modal <dialog> top-layer, placement précis, clics transmis aux items) ----------- */
|
|
4
5
|
|
|
5
6
|
export function buildMenu<T extends object>(builder: Builder, node: MenuNode<T>, ctx: Ctx<T>) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { SelectNode } from "../model/select";
|
|
1
2
|
import { applyIdAndClass, applySize, bindVisibleEnabled, Builder, Ctx } from "../vue-builder";
|
|
2
|
-
|
|
3
|
+
|
|
3
4
|
|
|
4
5
|
/* ----------- Select ----------- */
|
|
5
6
|
export function buildSelect<T extends object>(builder: Builder, node: SelectNode<T, any, any, any, any>, ctx: Ctx<T>) {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Space } from "../model/space";
|
|
2
|
+
import { applySize, Builder, Ctx } from "../vue-builder";
|
|
3
|
+
|
|
4
|
+
/* ----------- Flow ----------- */
|
|
5
|
+
export function buildSpace<T extends object>(builder:Builder,node: Space, ctx: Ctx<T>) {
|
|
6
|
+
const div = document.createElement('div');
|
|
7
|
+
|
|
8
|
+
div.style.visibility ="hidden"
|
|
9
|
+
applySize(div, node.width, node.height);
|
|
10
|
+
ctx.add(div);
|
|
11
|
+
|
|
12
|
+
}
|
|
13
|
+
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { SingleVueNode } from "../model/vue";
|
|
1
2
|
import { applyIdAndClass, applySize, Builder, Ctx, VueRuntime } from "../vue-builder";
|
|
2
|
-
import {
|
|
3
|
+
import { Vue } from "../vue-model";
|
|
3
4
|
|
|
4
5
|
/* ----------- Single UI (champ objet) ----------- */
|
|
5
6
|
export function buildSingleVue<T extends object>(builder:Builder,node: SingleVueNode<T>, ctx: Ctx<T>) {
|
|
@@ -31,4 +32,6 @@ import { SingleVueNode, Vue } from "../vue-model";
|
|
|
31
32
|
const off = ctx.listener.listen(node.name as keyof T, (v) => mountFor(v, false));
|
|
32
33
|
ctx.dataUnsubs.push(off);
|
|
33
34
|
ctx.domUnsubs.push(() => clearHost());
|
|
35
|
+
|
|
36
|
+
|
|
34
37
|
}
|
|
@@ -111,11 +111,19 @@
|
|
|
111
111
|
radial-gradient(500px 180px at 120% -10%, rgba(192, 166, 255, .12), transparent 45%);
|
|
112
112
|
pointer-events: none;
|
|
113
113
|
}
|
|
114
|
-
|
|
114
|
+
.app span {
|
|
115
|
+
border: 1px solid var(--ui-border);
|
|
116
|
+
color: var(--ui-fg);
|
|
117
|
+
box-shadow: var(--ui-shadow);
|
|
118
|
+
border-radius: calc(var(--ui-radius) - 4px);
|
|
119
|
+
}
|
|
115
120
|
/* ---------- Typo inline ---------- */
|
|
116
121
|
.app label,
|
|
117
122
|
.app span {
|
|
118
123
|
color: var(--text);
|
|
124
|
+
border-radius: var(--radius-xs);
|
|
125
|
+
box-shadow: inset 0 0 0 1px var(--control-inset);
|
|
126
|
+
background-color: #34363a;
|
|
119
127
|
}
|
|
120
128
|
|
|
121
129
|
.app label {
|
|
@@ -402,6 +410,4 @@
|
|
|
402
410
|
transition: none !important;
|
|
403
411
|
animation: none !important;
|
|
404
412
|
}
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
|
|
413
|
+
}
|
|
@@ -32,6 +32,14 @@
|
|
|
32
32
|
font-family: var(--ui-font);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
.app span {
|
|
36
|
+
border: 1px solid var(--ui-border);
|
|
37
|
+
color: var(--ui-fg);
|
|
38
|
+
box-shadow: var(--ui-shadow);
|
|
39
|
+
border-radius: calc(var(--ui-radius) - 4px);
|
|
40
|
+
background-color: #b6c4e1;
|
|
41
|
+
}
|
|
42
|
+
|
|
35
43
|
@media (prefers-color-scheme: dark) {
|
|
36
44
|
.app {
|
|
37
45
|
--ui-fg: #e6e8ee;
|
|
@@ -396,6 +404,4 @@
|
|
|
396
404
|
transition: none;
|
|
397
405
|
animation: none;
|
|
398
406
|
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
|
|
407
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ButtonContentType, KeysOfType, KeysOfTypeFunction, MethodNames0, Objectish, VoidMethodName1 } from "../vue-model";
|
|
2
|
+
|
|
3
|
+
/** BootVue — bouton qui "boot" une Vue (label dynamique depuis T) */
|
|
4
|
+
export interface BootVueNode<
|
|
5
|
+
T extends object,
|
|
6
|
+
NK extends KeysOfType<T, Objectish | null | undefined> = KeysOfType<T, Objectish | null | undefined>,
|
|
7
|
+
LK extends KeysOfType<T, string> = KeysOfType<T, string>,
|
|
8
|
+
MN extends MethodNames0<T> = MethodNames0<T>
|
|
9
|
+
> {
|
|
10
|
+
kind: 'bootVue';
|
|
11
|
+
/** Identifiants CSS/DOM */
|
|
12
|
+
id?: string;
|
|
13
|
+
class?: string | string[];
|
|
14
|
+
|
|
15
|
+
/** Objet dont l'UI sera montée quand on clique */
|
|
16
|
+
factory: KeysOfType<T, () => object>;
|
|
17
|
+
|
|
18
|
+
/** Clé string de T utilisée comme libellé du bouton */
|
|
19
|
+
label: LK;
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
/** Rendu optionnel du bouton */
|
|
24
|
+
type?: ButtonContentType;
|
|
25
|
+
|
|
26
|
+
width?: number | string;
|
|
27
|
+
height?: number | string;
|
|
28
|
+
visible?: KeysOfType<T, boolean>;
|
|
29
|
+
enable?: KeysOfType<T, boolean>;
|
|
30
|
+
useVisibility?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/** StaticBootVue — bouton qui "boot" une Vue (label fixe) */
|
|
33
|
+
export interface StaticBootVueNode<
|
|
34
|
+
T extends object,
|
|
35
|
+
NK extends KeysOfType<T, Objectish | null | undefined> = KeysOfType<T, Objectish | null | undefined>,
|
|
36
|
+
MN extends MethodNames0<T> = MethodNames0<T>
|
|
37
|
+
> {
|
|
38
|
+
kind: 'staticBootVue';
|
|
39
|
+
/** Identifiants CSS/DOM */
|
|
40
|
+
id?: string;
|
|
41
|
+
class?: string | string[];
|
|
42
|
+
|
|
43
|
+
/** Objet dont l'UI sera montée quand on clique */
|
|
44
|
+
factory: KeysOfType<T, () => object>;
|
|
45
|
+
|
|
46
|
+
/** Libellé texte non dynamique */
|
|
47
|
+
label: string;
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
/** Rendu optionnel du bouton */
|
|
52
|
+
type?: ButtonContentType;
|
|
53
|
+
|
|
54
|
+
width?: number | string;
|
|
55
|
+
height?: number | string;
|
|
56
|
+
visible?: KeysOfType<T, boolean>;
|
|
57
|
+
enable?: KeysOfType<T, boolean>;
|
|
58
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ButtonContentType, KeysOfType, MethodNames0 } from "../vue-model";
|
|
2
|
+
|
|
3
|
+
export interface StaticButtonNode<T extends object, NK extends KeysOfType<T, string> = KeysOfType<T, string>> {
|
|
4
|
+
kind: 'staticButton';
|
|
5
|
+
/** Identifiants CSS/DOM */
|
|
6
|
+
id?: string;
|
|
7
|
+
class?: string | string[];
|
|
8
|
+
|
|
9
|
+
/** Libellé texte par défaut */
|
|
10
|
+
label: string;
|
|
11
|
+
action: MethodNames0<T>;
|
|
12
|
+
muted?: boolean;
|
|
13
|
+
width?: number | string;
|
|
14
|
+
height?: number | string;
|
|
15
|
+
visible?: KeysOfType<T, boolean>;
|
|
16
|
+
enable?: KeysOfType<T, boolean>;
|
|
17
|
+
useVisibility?: boolean;
|
|
18
|
+
|
|
19
|
+
/** Rendu optionnel : 'img' = URL d'image, 'html' = markup HTML (depuis `name` si fourni, sinon `label`). */
|
|
20
|
+
type?: ButtonContentType;
|
|
21
|
+
/** Source du contenu si `type` défini (URL/HTML) ; sinon le rendu retombe sur `label`. */
|
|
22
|
+
name?: NK;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** ButtonLabel — label typé comme une clé string de T */
|
|
26
|
+
export interface ButtonNode<
|
|
27
|
+
T extends object,
|
|
28
|
+
LK extends KeysOfType<T, string> = KeysOfType<T, string>
|
|
29
|
+
> {
|
|
30
|
+
kind: 'button';
|
|
31
|
+
/** Identifiants CSS/DOM */
|
|
32
|
+
id?: string;
|
|
33
|
+
class?: string | string[];
|
|
34
|
+
|
|
35
|
+
/** Clé d'un champ string de T utilisé comme libellé (texte par défaut) */
|
|
36
|
+
label: LK;
|
|
37
|
+
action: MethodNames0<T>;
|
|
38
|
+
muted?: boolean;
|
|
39
|
+
width?: number | string;
|
|
40
|
+
height?: number | string;
|
|
41
|
+
visible?: KeysOfType<T, boolean>;
|
|
42
|
+
enable?: KeysOfType<T, boolean>;
|
|
43
|
+
|
|
44
|
+
/** Rendu optionnel : 'img' = URL d'image, 'html' = markup HTML (depuis `name` si fourni, sinon `label`). */
|
|
45
|
+
type?: ButtonContentType;
|
|
46
|
+
/** Clé string du modèle à utiliser pour le contenu quand `type` est défini. */
|
|
47
|
+
name?: KeysOfType<T, string>;
|
|
48
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { HTMLElementFactoryName, KeysOfType, VoidMethodName } from "../vue-model";
|
|
2
|
+
|
|
3
|
+
/** CUSTOM — créé via une méthode de T (sans argument) qui retourne un HTMLElement
|
|
4
|
+
* + une méthode d'init optionnelle (() => void) exécutée par le builder.
|
|
5
|
+
*/
|
|
6
|
+
export interface CustomNode<
|
|
7
|
+
T extends object,
|
|
8
|
+
FK extends HTMLElementFactoryName<T> = HTMLElementFactoryName<T>,
|
|
9
|
+
IK extends VoidMethodName<T> = VoidMethodName<T>
|
|
10
|
+
> {
|
|
11
|
+
kind: 'custom';
|
|
12
|
+
/** Identifiants CSS/DOM */
|
|
13
|
+
id?: string;
|
|
14
|
+
class?: string | string[];
|
|
15
|
+
|
|
16
|
+
width?: number | string;
|
|
17
|
+
height?: number | string;
|
|
18
|
+
visible?: KeysOfType<T, boolean>;
|
|
19
|
+
enable?: KeysOfType<T, boolean>;
|
|
20
|
+
|
|
21
|
+
/** Nom de la méthode sur T: () => HTMLElement */
|
|
22
|
+
factory: FK;
|
|
23
|
+
|
|
24
|
+
/** Nom d'une méthode sur T: () => void (appelée après création/insert du DOM) */
|
|
25
|
+
init?: IK;
|
|
26
|
+
useVisibility?: boolean;
|
|
27
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ButtonContentType, KeysOfType, Objectish } from "../vue-model";
|
|
2
|
+
|
|
3
|
+
/** DIALOG — plus de listUI */
|
|
4
|
+
export interface DialogNode<T extends object> {
|
|
5
|
+
kind: 'dialog';
|
|
6
|
+
/** Identifiants CSS/DOM */
|
|
7
|
+
id?: string;
|
|
8
|
+
class?: string | string[];
|
|
9
|
+
|
|
10
|
+
/** Objet dont l'UI sera montée dans le dialog */
|
|
11
|
+
name: KeysOfType<T, Objectish | null | undefined>;
|
|
12
|
+
/** Libellé du bouton qui ouvre le dialog (ou source si `type` est défini) */
|
|
13
|
+
label: string;
|
|
14
|
+
buttonWidth?: number | string;
|
|
15
|
+
buttonHeight?: number | string;
|
|
16
|
+
width?: number | string;
|
|
17
|
+
height?: number | string;
|
|
18
|
+
closeOnBackdrop?: boolean;
|
|
19
|
+
closeOnEsc?: boolean;
|
|
20
|
+
modal?: boolean;
|
|
21
|
+
visible?: KeysOfType<T, boolean>;
|
|
22
|
+
enable?: KeysOfType<T, boolean>;
|
|
23
|
+
action?: KeysOfType<T, () => void>;
|
|
24
|
+
|
|
25
|
+
/** Rendu du bouton trigger : 'img' = URL (dans `label`), 'html' = markup (dans `label`). */
|
|
26
|
+
type?: ButtonContentType;
|
|
27
|
+
useVisibility?: boolean;
|
|
28
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { UINode } from "../vue-model";
|
|
2
|
+
|
|
3
|
+
export interface FlowNode<T extends object> {
|
|
4
|
+
kind: 'flow';
|
|
5
|
+
/** Identifiants CSS/DOM */
|
|
6
|
+
id?: string;
|
|
7
|
+
class?: string | string[];
|
|
8
|
+
|
|
9
|
+
orientation: 'column' | 'row';
|
|
10
|
+
gap?: number | string;
|
|
11
|
+
align?: 'start' | 'center' | 'end' | 'stretch';
|
|
12
|
+
justify?: 'start' | 'center' | 'end' | 'space-between' | 'space-around' | 'space-evenly';
|
|
13
|
+
wrap?: boolean;
|
|
14
|
+
style?: Partial<CSSStyleDeclaration>;
|
|
15
|
+
panel?: boolean;
|
|
16
|
+
width?: number | string;
|
|
17
|
+
height?: number | string;
|
|
18
|
+
children: UINode<T>[];
|
|
19
|
+
}
|
package/src/model/img.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { KeysOfType } from "../vue-model";
|
|
2
|
+
|
|
3
|
+
/** Img — URL typée comme une clé string de T */
|
|
4
|
+
export interface ImgNode<
|
|
5
|
+
T extends object,
|
|
6
|
+
NK extends KeysOfType<T, string> = KeysOfType<T, string>
|
|
7
|
+
> {
|
|
8
|
+
kind: 'img';
|
|
9
|
+
/** Identifiants CSS/DOM */
|
|
10
|
+
id?: string;
|
|
11
|
+
class?: string | string[];
|
|
12
|
+
|
|
13
|
+
/** Clé d'un champ string de T contenant l'URL de l'image */
|
|
14
|
+
url: NK;
|
|
15
|
+
alt?: string;
|
|
16
|
+
width?: number | string;
|
|
17
|
+
height?: number | string;
|
|
18
|
+
visible?: KeysOfType<T, boolean>;
|
|
19
|
+
enable?: KeysOfType<T, boolean>;
|
|
20
|
+
useVisibility?: boolean;
|
|
21
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/* ===================== Noeuds de l'AST ===================== */
|
|
2
|
+
|
|
3
|
+
import { InputType, KeysOfType, MethodNames0 } from "../vue-model";
|
|
4
|
+
|
|
5
|
+
/** Input: clé limitée à string | number | boolean */
|
|
6
|
+
export interface InputNode<
|
|
7
|
+
T extends object,
|
|
8
|
+
NK extends KeysOfType<T, string | number | boolean> = KeysOfType<T, string | number | boolean>
|
|
9
|
+
> {
|
|
10
|
+
kind: 'input';
|
|
11
|
+
/** Identifiants CSS/DOM */
|
|
12
|
+
id?: string;
|
|
13
|
+
class?: string | string[];
|
|
14
|
+
|
|
15
|
+
name: NK;
|
|
16
|
+
update?: MethodNames0<T>;
|
|
17
|
+
|
|
18
|
+
inputType?: InputType;
|
|
19
|
+
muted?: boolean;
|
|
20
|
+
width?: number | string;
|
|
21
|
+
height?: number | string;
|
|
22
|
+
visible?: KeysOfType<T, boolean>;
|
|
23
|
+
enable?: KeysOfType<T, boolean>;
|
|
24
|
+
useVisibility?: boolean;
|
|
25
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { KeysOfType } from "../vue-model";
|
|
2
|
+
|
|
3
|
+
/** Label: clé limitée à string */
|
|
4
|
+
export interface LabelNode<
|
|
5
|
+
T extends object,
|
|
6
|
+
NK extends KeysOfType<T, string|number> = KeysOfType<T, string|number>
|
|
7
|
+
> {
|
|
8
|
+
kind: 'label';
|
|
9
|
+
/** Identifiants CSS/DOM */
|
|
10
|
+
id?: string;
|
|
11
|
+
class?: string | string[];
|
|
12
|
+
|
|
13
|
+
name: NK;
|
|
14
|
+
width?: number | string;
|
|
15
|
+
height?: number | string;
|
|
16
|
+
visible?: KeysOfType<T, boolean>;
|
|
17
|
+
enable?: KeysOfType<T, boolean>;
|
|
18
|
+
useVisibility?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/** Label: clé limitée à string */
|
|
21
|
+
export interface StaticLabelNode<
|
|
22
|
+
T extends object
|
|
23
|
+
> {
|
|
24
|
+
kind: 'staticLabel';
|
|
25
|
+
/** Identifiants CSS/DOM */
|
|
26
|
+
id?: string;
|
|
27
|
+
class?: string | string[];
|
|
28
|
+
|
|
29
|
+
label: string;
|
|
30
|
+
width?: number | string;
|
|
31
|
+
height?: number | string;
|
|
32
|
+
visible?: KeysOfType<T, boolean>;
|
|
33
|
+
enable?: KeysOfType<T, boolean>;
|
|
34
|
+
useVisibility?: boolean;
|
|
35
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ArrayKeys, KeysOfType, VoidMethodName1 } from "../vue-model";
|
|
2
|
+
|
|
3
|
+
/** LIST UI — plus de listUI */
|
|
4
|
+
export interface ListVueNode<T extends object> {
|
|
5
|
+
kind: 'listOfVue';
|
|
6
|
+
/** Identifiants CSS/DOM */
|
|
7
|
+
id?: string;
|
|
8
|
+
class?: string | string[];
|
|
9
|
+
list: ArrayKeys<T>;
|
|
10
|
+
orientation?: 'row' | 'column';
|
|
11
|
+
gap?: number | string;
|
|
12
|
+
align?: 'start' | 'center' | 'end' | 'stretch';
|
|
13
|
+
justify?: 'start' | 'center' | 'end' | 'space-between' | 'space-around' | 'space-evenly';
|
|
14
|
+
wrap?: boolean;
|
|
15
|
+
style?: Partial<CSSStyleDeclaration>;
|
|
16
|
+
elementStyle?: Partial<CSSStyleDeclaration>;
|
|
17
|
+
panel?: boolean;
|
|
18
|
+
width?: number | string;
|
|
19
|
+
height?: number | string;
|
|
20
|
+
elementWidth?: number | string;
|
|
21
|
+
elementHeight?: number | string;
|
|
22
|
+
visible?: KeysOfType<T, boolean>; enable?: KeysOfType<T, boolean>;
|
|
23
|
+
useVisibility?: boolean;
|
|
24
|
+
|
|
25
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ButtonContentType, KeysOfType, Objectish } from "../vue-model";
|
|
2
|
+
|
|
3
|
+
/** MENU — mêmes paramètres que dialog, rendu différent côté renderer */
|
|
4
|
+
export interface MenuNode<T extends object> {
|
|
5
|
+
kind: 'menu';
|
|
6
|
+
/** Identifiants CSS/DOM */
|
|
7
|
+
id?: string;
|
|
8
|
+
class?: string | string[];
|
|
9
|
+
|
|
10
|
+
/** Objet dont l'UI sera montée dans le menu */
|
|
11
|
+
name: KeysOfType<T, Objectish | null | undefined>;
|
|
12
|
+
/** Libellé du bouton qui ouvre le menu (ou source si `type` est défini) */
|
|
13
|
+
label: string;
|
|
14
|
+
buttonWidth?: number | string;
|
|
15
|
+
buttonHeight?: number | string;
|
|
16
|
+
width?: number | string;
|
|
17
|
+
height?: number | string;
|
|
18
|
+
closeOnBackdrop?: boolean;
|
|
19
|
+
closeOnEsc?: boolean;
|
|
20
|
+
modal?: boolean;
|
|
21
|
+
visible?: KeysOfType<T, boolean>;
|
|
22
|
+
enable?: KeysOfType<T, boolean>;
|
|
23
|
+
action?: KeysOfType<T, () => void>;
|
|
24
|
+
|
|
25
|
+
/** Rendu du bouton trigger : 'img' = URL (dans `label`), 'html' = markup (dans `label`). */
|
|
26
|
+
type?: ButtonContentType;
|
|
27
|
+
useVisibility?: boolean;
|
|
28
|
+
}
|