this.gui 1.1.23 → 1.1.25

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "this.gui",
3
3
  "private": false,
4
- "version": "1.1.23",
4
+ "version": "1.1.25",
5
5
  "type": "module",
6
6
  "main": "dist/this-gui.umd.js",
7
7
  "module": "dist/this-gui.es.js",
@@ -17,7 +17,7 @@
17
17
  "gui": "./dist/bin/cli.js"
18
18
  },
19
19
  "scripts": {
20
- "build": "vite build",
20
+ "build": "vite build && node -e \"import('./vite.config.js').then(m => m.buildFinished())\"",
21
21
  "lint": "eslint .",
22
22
  "dev": "vite",
23
23
  "dev:lib": "vite build --watch",
@@ -1,109 +0,0 @@
1
- Ocultar/mostrar barras, dar pantalla completa al lienzo, y encima montar un sistema de colocación (2D/3D) que se hidrate desde JSON.
2
-
3
- Aquí te dejo un plan claro (sin código) para que lo aterricemos paso a paso:
4
-
5
- 1) API del Shell (layout declarativo)
6
-
7
- Define un spec de layout que controle visibilidad, posición y estilo de las barras (y que sea mutable en runtime):
8
-
9
- {
10
- "layout": {
11
- "navbar": { "visible": true, "position": "fixed" },
12
- "leftDrawer": { "visible": true, "width": 260 },
13
- "rightDrawer": { "visible": false, "width": 280 },
14
- "stickyOptions": { "visible": false },
15
- "footer": { "visible": true },
16
- "canvas": {
17
- "mode": "2d", // "2d" | "3d"
18
- "fullscreen": false, // si true, el shell oculta barras y expande el lienzo
19
- "bg": "transparent"
20
- }
21
- }
22
- }
23
-
24
- • El shell aplica el spec y actualiza insets (como ya haces) cuando algo es permanente.
25
- • Si canvas.fullscreen = true, el shell oculta NavBar/Drawers/Sticky/Footer y setea insets a 0 → el “campo” queda a pantalla completa.
26
-
27
- 2) Motor de colocación (2D primero, 3D después)
28
-
29
- Para el colocador 2D, usa una cuadrícula declarativa. Piensa en áreas CSS Grid con responsive:
30
-
31
- {
32
- "canvas2D": {
33
- "grid": {
34
- "template": {
35
- "xs": { "cols": "1fr", "rows": "auto 1fr auto", "areas": ["header","content","hud"] },
36
- "md": { "cols": "240px 1fr", "rows": "auto 1fr", "areas": ["sidebar header","sidebar content"] }
37
- },
38
- "gap": 8
39
- },
40
- "items": [
41
- { "id": "header", "component": { "type": "Text", "props": { "variant": "h4", "children": "Scene" } } },
42
- { "id": "sidebar", "component": { "type": "Panel", "props": { "title": "Layers" } } },
43
- { "id": "content", "component": { "type": "Viewport2D", "props": { "controls": true } } },
44
- { "id": "hud", "component": { "type": "StickyOptionsTop", "props": { "items": [/* … */] } } }
45
- ]
46
- }
47
- }
48
-
49
- • template define áreas por breakpoint (xs/md/etc.).
50
- • items asigna qué se renderiza en cada área (resuelto por tu registry + resolvers).
51
- • Esto te da un “layout engine” 2D declarativo, perfecto para AR-lite (HUDs, overlays).
52
-
53
- Para 3D, la misma idea, pero con un Viewport3D (three.js/Babylon) como componente. El grid sigue sirviendo para HUDs y paneles laterales mientras el lienzo 3D ocupa el área content.
54
-
55
- 3) Controles de visibilidad y modos (runtime)
56
-
57
- Agrega un canal simple de acciones declarativas para mutar el spec:
58
-
59
- {
60
- "actions": [
61
- { "id": "toggleFull", "type": "toggle", "path": "layout.canvas.fullscreen" },
62
- { "id": "showRight", "type": "set", "path": "layout.rightDrawer.visible", "value": true }
63
- ],
64
- "bindings": [
65
- { "event": "kbd:F", "action": "toggleFull" },
66
- { "event": "ui:openContext", "action": "showRight" }
67
- ]
68
- }
69
-
70
- • El shell expone un dispatcher que entiende toggle/set sobre rutas JSON (path).
71
- • Permite atajos (teclado), botones de UI, o señales externas (servidor/IA).
72
-
73
- 4) Resolver genérico + resolvers por componente
74
- • Mantén los resolvers por componente (Button, Link, NavBar, Viewport2D/3D, etc.) para mapear JSON → props reales.
75
- • El resolver genérico (inyector) toma el árbol JSON y delega por type al resolver adecuado (registrado en tu GuiRegistry).
76
- • Así puedes hidratar todo el shell (barras + canvas + grid + items) desde un único spec.
77
-
78
- 5) Slots y Portal (overlay HUD)
79
- • Define “slots” especiales (ej. overlay, hud, notifications) que rendericen vía portal encima del canvas.
80
- • Tus StickyOptionsTop u otras capas pueden vivir ahí sin afectar insets del shell.
81
-
82
- 6) Persistencia + Replay
83
- • Guarda el spec actual (y su historial) en localStorage o en backend para reproducir estados y compartir escenas/pantallas.
84
- • Útil para AR colaborativo y “deep links” a UIs derivadas por IA.
85
-
86
- 7) Rendimiento
87
- • Evita re-render global del shell: cuando mutas visibilidad o áreas, memoriza subárboles.
88
- • Para 3D, desacopla el ciclo de render del estado de React cuando sea necesario.
89
-
90
- 8) Roadmap chiquito (prioridades)
91
- 1. Spec de layout con visibilidad + fullscreen (ya puedes hacerlo con tu shell actual).
92
- 2. Grid 2D declarativo con áreas responsive (pequeño motor CSS Grid).
93
- 3. Slots/Portal para HUD/Overlay.
94
- 4. Registry + resolvers para los componentes que entren al grid (ya lo estás haciendo).
95
- 5. Acciones declarativas (toggle/set) + bindings básicos.
96
- 6. Viewport3D como primitivo (después).
97
-
98
-
99
-
100
- Con esto:
101
- • Puedes ocultar/mostrar barras a voluntad o entrar en fullscreen.
102
- • Tienes un lienzo central controlado por spec.
103
- • Puedes colocar elementos 2D (y luego 3D) de forma declarativa y responsive.
104
- • Todo eso conversando con tu registry y los resolvers que ya estás construyendo.
105
-
106
- Cuando quieras, te redacto un spec mínimo de ejemplo (end-to-end) que tu shell pueda consumir hoy mismo para:
107
- 1. navbar visible, leftDrawer visible, rightDrawer oculto;
108
- 2. grid 2D con sidebar/header/content;
109
- 3. botón que activa fullscreen.
@@ -1,93 +0,0 @@
1
- compact technical brief of the overall approach (props vs config vs viewported configs), with structure, versatility, declarativity, and scope.
2
-
3
- 1) Plain React props (current/“classic”)
4
-
5
- Structure: <Footer title="…" links={[…]} socialLinks={[…]} />
6
- Pros
7
- • Familiar React ergonomics.
8
- • Strong TypeScript IntelliSense on each prop.
9
- • Easy to tree-shake and to reason about in component code.
10
-
11
- Cons
12
- • Gets verbose as components grow.
13
- • Hard to switch “modes” (desktop/mobile/minimal/full) without duplicating prop sets.
14
- • Not naturally serializable (harder to hydrate from pure JSON or an external CMS).
15
-
16
- Use when
17
- • App code writes JSX directly.
18
- • Variations are small and local.
19
-
20
- 2) Single config object
21
-
22
- Structure: <Footer config={{ title:"…", links:[…], socialLinks:[…] }} />
23
- Pros
24
- • Declarative & serializable: perfect for JSON-driven UIs, CMS/Llama/Lego-style composition.
25
- • One entrypoint for “shape evolution”: adding/removing options doesn’t churn the JSX signature.
26
- • Easier to diff/patch at runtime (hot updates, remote editing, A/B tests).
27
-
28
- Cons
29
- • Slightly less IDE precision unless you type config well (e.g., FooterConfig).
30
- • If you mix both props and config, you need clear precedence rules.
31
-
32
- Use when
33
- • You want to drive UI from data (JSON), live-edit, or swap configurations on the fly.
34
- • You’re aiming at a “player” model later (render UIs from configs).
35
-
36
- Recommended pattern
37
- • Support both: keep top-level props for ergonomics, plus an optional config. Component merges: final = { ...defaults, ...config, ...propsOverrides }.
38
-
39
- 3) Viewport-aware configs (declarative responsiveness)
40
-
41
- Structure A (per-prop):
42
- size="pill" or size={{ xs: "icons", md: "pill" }}
43
-
44
- Structure B (whole-config overrides):
45
-
46
- <StickyOptionsTop
47
- config={{ items: desktopItems }}
48
- viewport={{
49
- xs: { config: { items: mobileItems } },
50
- sm: { config: { items: mobileItems } }
51
- }}
52
- />
53
-
54
- (Resolved by your viewport.ts: resolveViewportProp / resolveResponsiveConfig.)
55
-
56
- Pros
57
- • Responsiveness is data, not scattered useMediaQuery logic.
58
- • Plays great with JSON: one base config + sparse overrides per breakpoint.
59
- • Testable & SSR-friendly (you can inject a width override).
60
-
61
- Cons
62
- • Slightly more indirection; you need a tiny resolver layer (which you now have).
63
- • Authors must learn the pattern (base + per-breakpoint overrides).
64
-
65
- Use when
66
- • The same component must present different variants by viewport.
67
- • You want a single source of truth for mobile/desktop/XL differences.
68
-
69
- Putting it together (recommended architecture)
70
- • Component API supports both:
71
- • Classic props (ergonomic for app devs).
72
- • config (for JSON-driven/declarative scenarios).
73
- • Optional viewport to override either specific props or the whole config per breakpoint.
74
- • Resolver layer (inside each component):
75
- 1. Gather defaults.
76
- 2. Merge config.
77
- 3. Apply classic prop overrides (if both exist, props win).
78
- 4. Apply viewport overrides using your resolveViewportProp/resolveResponsiveConfig.
79
- 5. Render.
80
-
81
- This yields:
82
- • Versatility: JSX convenience and data-driven control.
83
- • Declarativity: All variants can be expressed as JSON and swapped live.
84
- • Scope/Future-proofing: Same pattern works for a headless “GUI Player,” CMS, LLM emitters, or Web Components later (just feed the same config/viewport JSON).
85
- • Low coupling: Components don’t import useMediaQuery everywhere; the viewport resolver centralizes responsive decisions.
86
-
87
- Migration strategy (quick)
88
- 1. Keep your existing props as-is.
89
- 2. Add optional config and viewport to priority-merge.
90
- 3. Start using viewport.ts in 1–2 components (e.g., StickyOptionsTop, Footer) to prove the flow.
91
- 4. Document the precedence rule: defaults < config < props < viewport overrides.
92
-
93
- This gives you the best of all worlds: ergonomic props for developers, clean JSON for declarative UIs, and a compact, testable way to express responsive variants without scattering logic.
@@ -1,109 +0,0 @@
1
- Ocultar/mostrar barras, dar pantalla completa al lienzo, y encima montar un sistema de colocación (2D/3D) que se hidrate desde JSON.
2
-
3
- Aquí te dejo un plan claro (sin código) para que lo aterricemos paso a paso:
4
-
5
- 1) API del Shell (layout declarativo)
6
-
7
- Define un spec de layout que controle visibilidad, posición y estilo de las barras (y que sea mutable en runtime):
8
-
9
- {
10
- "layout": {
11
- "navbar": { "visible": true, "position": "fixed" },
12
- "leftDrawer": { "visible": true, "width": 260 },
13
- "rightDrawer": { "visible": false, "width": 280 },
14
- "stickyOptions": { "visible": false },
15
- "footer": { "visible": true },
16
- "canvas": {
17
- "mode": "2d", // "2d" | "3d"
18
- "fullscreen": false, // si true, el shell oculta barras y expande el lienzo
19
- "bg": "transparent"
20
- }
21
- }
22
- }
23
-
24
- • El shell aplica el spec y actualiza insets (como ya haces) cuando algo es permanente.
25
- • Si canvas.fullscreen = true, el shell oculta NavBar/Drawers/Sticky/Footer y setea insets a 0 → el “campo” queda a pantalla completa.
26
-
27
- 2) Motor de colocación (2D primero, 3D después)
28
-
29
- Para el colocador 2D, usa una cuadrícula declarativa. Piensa en áreas CSS Grid con responsive:
30
-
31
- {
32
- "canvas2D": {
33
- "grid": {
34
- "template": {
35
- "xs": { "cols": "1fr", "rows": "auto 1fr auto", "areas": ["header","content","hud"] },
36
- "md": { "cols": "240px 1fr", "rows": "auto 1fr", "areas": ["sidebar header","sidebar content"] }
37
- },
38
- "gap": 8
39
- },
40
- "items": [
41
- { "id": "header", "component": { "type": "Text", "props": { "variant": "h4", "children": "Scene" } } },
42
- { "id": "sidebar", "component": { "type": "Panel", "props": { "title": "Layers" } } },
43
- { "id": "content", "component": { "type": "Viewport2D", "props": { "controls": true } } },
44
- { "id": "hud", "component": { "type": "StickyOptionsTop", "props": { "items": [/* … */] } } }
45
- ]
46
- }
47
- }
48
-
49
- • template define áreas por breakpoint (xs/md/etc.).
50
- • items asigna qué se renderiza en cada área (resuelto por tu registry + resolvers).
51
- • Esto te da un “layout engine” 2D declarativo, perfecto para AR-lite (HUDs, overlays).
52
-
53
- Para 3D, la misma idea, pero con un Viewport3D (three.js/Babylon) como componente. El grid sigue sirviendo para HUDs y paneles laterales mientras el lienzo 3D ocupa el área content.
54
-
55
- 3) Controles de visibilidad y modos (runtime)
56
-
57
- Agrega un canal simple de acciones declarativas para mutar el spec:
58
-
59
- {
60
- "actions": [
61
- { "id": "toggleFull", "type": "toggle", "path": "layout.canvas.fullscreen" },
62
- { "id": "showRight", "type": "set", "path": "layout.rightDrawer.visible", "value": true }
63
- ],
64
- "bindings": [
65
- { "event": "kbd:F", "action": "toggleFull" },
66
- { "event": "ui:openContext", "action": "showRight" }
67
- ]
68
- }
69
-
70
- • El shell expone un dispatcher que entiende toggle/set sobre rutas JSON (path).
71
- • Permite atajos (teclado), botones de UI, o señales externas (servidor/IA).
72
-
73
- 4) Resolver genérico + resolvers por componente
74
- • Mantén los resolvers por componente (Button, Link, NavBar, Viewport2D/3D, etc.) para mapear JSON → props reales.
75
- • El resolver genérico (inyector) toma el árbol JSON y delega por type al resolver adecuado (registrado en tu GuiRegistry).
76
- • Así puedes hidratar todo el shell (barras + canvas + grid + items) desde un único spec.
77
-
78
- 5) Slots y Portal (overlay HUD)
79
- • Define “slots” especiales (ej. overlay, hud, notifications) que rendericen vía portal encima del canvas.
80
- • Tus StickyOptionsTop u otras capas pueden vivir ahí sin afectar insets del shell.
81
-
82
- 6) Persistencia + Replay
83
- • Guarda el spec actual (y su historial) en localStorage o en backend para reproducir estados y compartir escenas/pantallas.
84
- • Útil para AR colaborativo y “deep links” a UIs derivadas por IA.
85
-
86
- 7) Rendimiento
87
- • Evita re-render global del shell: cuando mutas visibilidad o áreas, memoriza subárboles.
88
- • Para 3D, desacopla el ciclo de render del estado de React cuando sea necesario.
89
-
90
- 8) Roadmap chiquito (prioridades)
91
- 1. Spec de layout con visibilidad + fullscreen (ya puedes hacerlo con tu shell actual).
92
- 2. Grid 2D declarativo con áreas responsive (pequeño motor CSS Grid).
93
- 3. Slots/Portal para HUD/Overlay.
94
- 4. Registry + resolvers para los componentes que entren al grid (ya lo estás haciendo).
95
- 5. Acciones declarativas (toggle/set) + bindings básicos.
96
- 6. Viewport3D como primitivo (después).
97
-
98
-
99
-
100
- Con esto:
101
- • Puedes ocultar/mostrar barras a voluntad o entrar en fullscreen.
102
- • Tienes un lienzo central controlado por spec.
103
- • Puedes colocar elementos 2D (y luego 3D) de forma declarativa y responsive.
104
- • Todo eso conversando con tu registry y los resolvers que ya estás construyendo.
105
-
106
- Cuando quieras, te redacto un spec mínimo de ejemplo (end-to-end) que tu shell pueda consumir hoy mismo para:
107
- 1. navbar visible, leftDrawer visible, rightDrawer oculto;
108
- 2. grid 2D con sidebar/header/content;
109
- 3. botón que activa fullscreen.
@@ -1,93 +0,0 @@
1
- compact technical brief of the overall approach (props vs config vs viewported configs), with structure, versatility, declarativity, and scope.
2
-
3
- 1) Plain React props (current/“classic”)
4
-
5
- Structure: <Footer title="…" links={[…]} socialLinks={[…]} />
6
- Pros
7
- • Familiar React ergonomics.
8
- • Strong TypeScript IntelliSense on each prop.
9
- • Easy to tree-shake and to reason about in component code.
10
-
11
- Cons
12
- • Gets verbose as components grow.
13
- • Hard to switch “modes” (desktop/mobile/minimal/full) without duplicating prop sets.
14
- • Not naturally serializable (harder to hydrate from pure JSON or an external CMS).
15
-
16
- Use when
17
- • App code writes JSX directly.
18
- • Variations are small and local.
19
-
20
- 2) Single config object
21
-
22
- Structure: <Footer config={{ title:"…", links:[…], socialLinks:[…] }} />
23
- Pros
24
- • Declarative & serializable: perfect for JSON-driven UIs, CMS/Llama/Lego-style composition.
25
- • One entrypoint for “shape evolution”: adding/removing options doesn’t churn the JSX signature.
26
- • Easier to diff/patch at runtime (hot updates, remote editing, A/B tests).
27
-
28
- Cons
29
- • Slightly less IDE precision unless you type config well (e.g., FooterConfig).
30
- • If you mix both props and config, you need clear precedence rules.
31
-
32
- Use when
33
- • You want to drive UI from data (JSON), live-edit, or swap configurations on the fly.
34
- • You’re aiming at a “player” model later (render UIs from configs).
35
-
36
- Recommended pattern
37
- • Support both: keep top-level props for ergonomics, plus an optional config. Component merges: final = { ...defaults, ...config, ...propsOverrides }.
38
-
39
- 3) Viewport-aware configs (declarative responsiveness)
40
-
41
- Structure A (per-prop):
42
- size="pill" or size={{ xs: "icons", md: "pill" }}
43
-
44
- Structure B (whole-config overrides):
45
-
46
- <StickyOptionsTop
47
- config={{ items: desktopItems }}
48
- viewport={{
49
- xs: { config: { items: mobileItems } },
50
- sm: { config: { items: mobileItems } }
51
- }}
52
- />
53
-
54
- (Resolved by your viewport.ts: resolveViewportProp / resolveResponsiveConfig.)
55
-
56
- Pros
57
- • Responsiveness is data, not scattered useMediaQuery logic.
58
- • Plays great with JSON: one base config + sparse overrides per breakpoint.
59
- • Testable & SSR-friendly (you can inject a width override).
60
-
61
- Cons
62
- • Slightly more indirection; you need a tiny resolver layer (which you now have).
63
- • Authors must learn the pattern (base + per-breakpoint overrides).
64
-
65
- Use when
66
- • The same component must present different variants by viewport.
67
- • You want a single source of truth for mobile/desktop/XL differences.
68
-
69
- Putting it together (recommended architecture)
70
- • Component API supports both:
71
- • Classic props (ergonomic for app devs).
72
- • config (for JSON-driven/declarative scenarios).
73
- • Optional viewport to override either specific props or the whole config per breakpoint.
74
- • Resolver layer (inside each component):
75
- 1. Gather defaults.
76
- 2. Merge config.
77
- 3. Apply classic prop overrides (if both exist, props win).
78
- 4. Apply viewport overrides using your resolveViewportProp/resolveResponsiveConfig.
79
- 5. Render.
80
-
81
- This yields:
82
- • Versatility: JSX convenience and data-driven control.
83
- • Declarativity: All variants can be expressed as JSON and swapped live.
84
- • Scope/Future-proofing: Same pattern works for a headless “GUI Player,” CMS, LLM emitters, or Web Components later (just feed the same config/viewport JSON).
85
- • Low coupling: Components don’t import useMediaQuery everywhere; the viewport resolver centralizes responsive decisions.
86
-
87
- Migration strategy (quick)
88
- 1. Keep your existing props as-is.
89
- 2. Add optional config and viewport to priority-merge.
90
- 3. Start using viewport.ts in 1–2 components (e.g., StickyOptionsTop, Footer) to prove the flow.
91
- 4. Document the precedence rule: defaults < config < props < viewport overrides.
92
-
93
- This gives you the best of all worlds: ergonomic props for developers, clean JSON for declarative UIs, and a compact, testable way to express responsive variants without scattering logic.
File without changes