tauri-kargo-tools 0.1.4 → 0.1.6

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.
Files changed (52) hide show
  1. package/package.json +3 -3
  2. package/{dist → src}/builder/boot-vue.ts +2 -2
  3. package/{dist → src}/builder/button.ts +3 -3
  4. package/{dist → src}/builder/custom.ts +2 -1
  5. package/{dist → src}/builder/dialog.ts +2 -1
  6. package/{dist → src}/builder/flow.ts +2 -1
  7. package/{dist → src}/builder/img.ts +2 -1
  8. package/src/builder/input.ts +80 -0
  9. package/src/builder/label.ts +43 -0
  10. package/{dist → src}/builder/list-of-vue.ts +19 -4
  11. package/{dist → src}/builder/menu.ts +2 -1
  12. package/{dist → src}/builder/select.ts +2 -1
  13. package/{dist → src}/builder/vue.ts +4 -1
  14. package/{dist → src/css}/vue-darkmode.css +10 -4
  15. package/{dist → src/css}/vue-lightmode.css +9 -3
  16. package/src/model/boot-vue.ts +58 -0
  17. package/src/model/button.ts +48 -0
  18. package/src/model/custom.ts +27 -0
  19. package/src/model/dialog.ts +28 -0
  20. package/src/model/flow.ts +19 -0
  21. package/src/model/img.ts +21 -0
  22. package/src/model/input.ts +25 -0
  23. package/src/model/label.ts +35 -0
  24. package/src/model/list-of-vue.ts +25 -0
  25. package/src/model/menu.ts +28 -0
  26. package/src/model/select.ts +27 -0
  27. package/src/model/vue.ts +14 -0
  28. package/src/test/chat.png +0 -0
  29. package/src/test/chien.png +0 -0
  30. package/src/test/edit-2-line.png +0 -0
  31. package/src/test/folder-add-line.png +0 -0
  32. package/src/test/folder-reduce-line.png +0 -0
  33. package/src/test/index.ts +42 -0
  34. package/src/test/test-model-panel.ts +3 -0
  35. package/src/test/test-model.ts +461 -0
  36. package/src/test/test-polymorphe.ts +154 -0
  37. package/src/test/test-table.ts +53 -0
  38. package/src/test/test-vue-boot.ts +91 -0
  39. package/src/test/test-vue-panel.ts +162 -0
  40. package/src/test/test-vue.ts +113 -0
  41. package/{dist → src}/vue-builder.ts +45 -14
  42. package/{dist → src}/vue-model.ts +62 -344
  43. package/src/vue.ts +26 -0
  44. package/dist/builder/input.ts +0 -80
  45. package/dist/builder/label.ts +0 -31
  46. package/dist/vue.ts +0 -16
  47. /package/{dist → src}/api.ts +0 -0
  48. /package/{dist → src}/container.ts +0 -0
  49. /package/{dist → src}/listener-factory.ts +0 -0
  50. /package/{dist → src}/listener.ts +0 -0
  51. /package/{dist → src}/test.ts +0 -0
  52. /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.4",
3
+ "version": "0.1.6",
4
4
  "description": "",
5
- "files": ["dist"],
6
- "exports": { "./*": "./dist/*" },
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
- BootVueNode,
12
- StaticBootVueNode,
12
+
13
13
  Vue,
14
14
  } from "../vue-model";
15
15
 
@@ -1,5 +1,6 @@
1
- import { applyIdAndClass, applySize, bindVisibleEnabled, Builder, Ctx } from "../vue-builder";
2
- import { ButtonNode, StaticButtonNode } from "../vue-model";
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
- import { CustomNode } from "../vue-model";
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 { DialogNode, Vue } from "../vue-model";
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
- import { FlowNode } from "../vue-model";
3
+
3
4
 
4
5
  /* ----------- Flow ----------- */
5
6
  export function buildFlow<T extends object>(builder:Builder,node: FlowNode<T>, ctx: Ctx<T>) {
@@ -1,5 +1,6 @@
1
+ import { ImgNode } from "../model/img";
1
2
  import { applyIdAndClass, applySize, bindVisibleEnabled, Builder, Ctx } from "../vue-builder";
2
- import { ImgNode } from "../vue-model";
3
+
3
4
 
4
5
 
5
6
  /* ----------- Img ----------- */
@@ -0,0 +1,80 @@
1
+ import { InputNode } from "../model/input";
2
+ import { applyIdAndClass, applySize, bindEnabled, bindVisible, Builder, Ctx } from "../vue-builder";
3
+
4
+
5
+ /* ----------- Input ----------- */
6
+ export function buildInput<T extends object>(builder: Builder, node: InputNode<T, any>, ctx: Ctx<T>) {
7
+
8
+
9
+
10
+
11
+ const input = document.createElement('input');
12
+ applySize(input, node.width, node.height);
13
+ applyIdAndClass(input, node);
14
+ const current = (ctx.obj as any)[node.name];
15
+ const typeGuess =
16
+ node.inputType ??
17
+ (typeof current === 'boolean' ? 'checkbox'
18
+ : typeof current === 'number' ? 'number'
19
+ : 'text');
20
+
21
+ input.type = typeGuess === 'checkbox' ? 'checkbox'
22
+ : typeGuess === 'number' ? 'number'
23
+ : 'text';
24
+
25
+ if (typeGuess === 'checkbox') {
26
+ (input as HTMLInputElement).checked = Boolean(current);
27
+ } else if (typeGuess === 'number') {
28
+ (input as HTMLInputElement).valueAsNumber =
29
+ Number.isFinite(Number(current)) ? Number(current) : 0;
30
+ } else {
31
+ (input as HTMLInputElement).value = (current ?? '') as any as string;
32
+ }
33
+
34
+
35
+ ctx.add(input);
36
+
37
+ // visible / enable factorisés
38
+ bindVisible(node, input, ctx);
39
+ bindEnabled(node, input, ctx);
40
+
41
+ // modèle -> UI
42
+ const offData = ctx.listener.listen(node.name as keyof T, (v) => {
43
+ if (typeGuess === 'checkbox') {
44
+ const nv = Boolean(v);
45
+ if ((input as HTMLInputElement).checked !== nv) (input as HTMLInputElement).checked = nv;
46
+ } else if (typeGuess === 'number') {
47
+ const nv = Number(v ?? 0);
48
+ if ((input as HTMLInputElement).valueAsNumber !== nv) (input as HTMLInputElement).valueAsNumber = nv;
49
+ } else {
50
+ const s = (v as any as string) ?? '';
51
+ if ((input as HTMLInputElement).value !== s) (input as HTMLInputElement).value = s;
52
+ }
53
+ });
54
+ ctx.dataUnsubs.push(offData);
55
+
56
+ // UI -> modèle + update
57
+ const onUser = () => {
58
+ const el = input as HTMLInputElement;
59
+ let next: any;
60
+ if (typeGuess === 'checkbox') next = el.checked;
61
+ else if (typeGuess === 'number') next = Number.isFinite(el.valueAsNumber) ? el.valueAsNumber : Number(el.value);
62
+ else next = el.value;
63
+
64
+ if (node.muted) {
65
+ ctx.listener.setSilently(node.name as keyof T, next);
66
+ if (node.update) {
67
+ (ctx.listener as any).withAllMuted
68
+ ? (ctx.listener as any).withAllMuted(() => { (ctx.obj as any)[node.update]!(); })
69
+ : (ctx.obj as any)[node.update]!();
70
+
71
+ }
72
+ } else {
73
+ (ctx.obj as any)[node.name] = next;
74
+ if (node.update) { (ctx.obj as any)[node.update]!(); }
75
+ }
76
+ };
77
+ const evt = typeGuess === 'checkbox' ? 'change' : 'input';
78
+ input.addEventListener(evt, onUser);
79
+ ctx.domUnsubs.push(() => input.removeEventListener(evt, onUser));
80
+ }
@@ -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 { applyIdAndClass, applySize, Builder, Ctx, VueRuntime } from "../vue-builder";
2
- import { ListVueNode, Vue } from "../vue-model";
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
- const arr = ((ctx.obj as any)[node.list] ?? []) as any[];
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 { MenuNode, Vue } from "../vue-model";
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
- import { SelectNode } from "../vue-model";
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>) {
@@ -1,5 +1,6 @@
1
+ import { SingleVueNode } from "../model/vue";
1
2
  import { applyIdAndClass, applySize, Builder, Ctx, VueRuntime } from "../vue-builder";
2
- import { SingleVueNode, Vue } from "../vue-model";
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
+ }
@@ -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
+ }