anentrypoint-design 0.0.72 → 0.0.73

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 (2) hide show
  1. package/package.json +2 -1
  2. package/src/desktop/wm.js +111 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anentrypoint-design",
3
- "version": "0.0.72",
3
+ "version": "0.0.73",
4
4
  "description": "247420 design system SDK — webjsx + modified ripple-ui, single-file ESM bundle for reproducible use of the AnEntrypoint design.",
5
5
  "type": "module",
6
6
  "main": "./dist/247420.js",
@@ -18,6 +18,7 @@
18
18
  },
19
19
  "./desktop/theme.css": "./src/desktop/theme.css",
20
20
  "./desktop/wm.css": "./src/desktop/wm.css",
21
+ "./desktop/wm.js": "./src/desktop/wm.js",
21
22
  "./desktop/launcher.css": "./src/desktop/launcher.css",
22
23
  "./desktop/validate.css": "./src/desktop/validate.css",
23
24
  "./desktop/icons.js": "./src/desktop/icons.js",
@@ -0,0 +1,111 @@
1
+ // Window manager paint surface — pure DOM rendering, no state machine.
2
+ // Consumer (thebird) owns z-order, focus stack, alt-tab, drag/resize math.
3
+ // renderWindow returns a handle whose setBounds is called from pointermove.
4
+ //
5
+ // Visuals are bible-aligned: mac-less chip buttons (-+x in mono),
6
+ // inset 4px rail for focus, low-opacity \25E2 glyph for resize affordance,
7
+ // pointer-events:none on .wm-bar with auto on title+close so phone @media
8
+ // auto-maximize can suppress drag without a JS branch.
9
+
10
+ export function renderWindow(opts = {}) {
11
+ const {
12
+ title = 'window',
13
+ body = null,
14
+ bounds = { x: 60, y: 60, w: 480, h: 320 },
15
+ focused = false,
16
+ maximized = false,
17
+ minimized = false,
18
+ instanceId = '',
19
+ kind = 'div',
20
+ callbacks = {},
21
+ } = opts;
22
+
23
+ const el = document.createElement('div');
24
+ el.className = 'wm-win';
25
+ el.dataset.kind = kind;
26
+ if (instanceId) el.dataset.instanceId = instanceId;
27
+ el.style.left = bounds.x + 'px';
28
+ el.style.top = bounds.y + 'px';
29
+ el.style.width = bounds.w + 'px';
30
+ el.style.height = bounds.h + 'px';
31
+
32
+ const bar = document.createElement('div');
33
+ bar.className = 'wm-bar';
34
+ const titleEl = document.createElement('span');
35
+ titleEl.className = 'wm-title';
36
+ titleEl.textContent = title;
37
+ const btns = document.createElement('div');
38
+ btns.className = 'wm-btns';
39
+ const minBtn = mkBtn('-', 'minimize');
40
+ const maxBtn = mkBtn('+', 'maximize');
41
+ const closeBtn = mkBtn('x', 'close');
42
+ btns.append(minBtn, maxBtn, closeBtn);
43
+ bar.append(titleEl, btns);
44
+
45
+ const bodyEl = document.createElement('div');
46
+ bodyEl.className = 'wm-body';
47
+ setBodyContent(bodyEl, body);
48
+
49
+ const resize = document.createElement('div');
50
+ resize.className = 'wm-resize';
51
+
52
+ el.append(bar, bodyEl, resize);
53
+
54
+ minBtn.addEventListener('click', e => { e.stopPropagation(); callbacks.onMinimize && callbacks.onMinimize(); });
55
+ maxBtn.addEventListener('click', e => { e.stopPropagation(); callbacks.onMaximize && callbacks.onMaximize(); });
56
+ closeBtn.addEventListener('click', e => { e.stopPropagation(); callbacks.onClose && callbacks.onClose(); });
57
+
58
+ el.addEventListener('pointerdown', () => callbacks.onFocus && callbacks.onFocus());
59
+
60
+ bar.addEventListener('pointerdown', e => {
61
+ if (e.target.closest('.wm-btn')) return;
62
+ callbacks.onFocus && callbacks.onFocus();
63
+ if (callbacks.onDragStart) callbacks.onDragStart(e, { x: el.offsetLeft, y: el.offsetTop, w: el.offsetWidth, h: el.offsetHeight });
64
+ });
65
+
66
+ resize.addEventListener('pointerdown', e => {
67
+ callbacks.onFocus && callbacks.onFocus();
68
+ if (callbacks.onResizeStart) callbacks.onResizeStart(e, { x: el.offsetLeft, y: el.offsetTop, w: el.offsetWidth, h: el.offsetHeight });
69
+ });
70
+
71
+ applyFocused(el, focused);
72
+ applyMaximized(el, maximized);
73
+ applyMinimized(el, minimized);
74
+
75
+ return {
76
+ el,
77
+ setTitle(t) { titleEl.textContent = t; },
78
+ setBody(b) { setBodyContent(bodyEl, b); },
79
+ setBounds(b) {
80
+ if (typeof b.x === 'number') el.style.left = b.x + 'px';
81
+ if (typeof b.y === 'number') el.style.top = b.y + 'px';
82
+ if (typeof b.w === 'number') el.style.width = b.w + 'px';
83
+ if (typeof b.h === 'number') el.style.height = b.h + 'px';
84
+ },
85
+ setFocused(v) { applyFocused(el, v); },
86
+ setMaximized(v) { applyMaximized(el, v); },
87
+ setMinimized(v) { applyMinimized(el, v); },
88
+ setInstanceId(id) { if (id) el.dataset.instanceId = id; else delete el.dataset.instanceId; },
89
+ setZIndex(z) { el.style.zIndex = String(z); },
90
+ getBounds() { return { x: el.offsetLeft, y: el.offsetTop, w: el.offsetWidth, h: el.offsetHeight }; },
91
+ dispose() { el.remove(); },
92
+ };
93
+ }
94
+
95
+ function mkBtn(label, ttl) {
96
+ const b = document.createElement('button');
97
+ b.className = 'wm-btn';
98
+ b.textContent = label;
99
+ b.title = ttl;
100
+ return b;
101
+ }
102
+
103
+ function setBodyContent(host, body) {
104
+ while (host.firstChild) host.removeChild(host.firstChild);
105
+ if (body instanceof Node) host.appendChild(body);
106
+ else if (typeof body === 'string') host.innerHTML = body;
107
+ }
108
+
109
+ function applyFocused(el, v) { el.classList.toggle('wm-focused', !!v); }
110
+ function applyMaximized(el, v) { el.classList.toggle('wm-max', !!v); }
111
+ function applyMinimized(el, v) { el.classList.toggle('wm-min', !!v); }