@floegence/floe-webapp-core 0.36.3 → 0.36.5

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.
@@ -1,208 +1,229 @@
1
- import { createSignal as _, createMemo as s } from "solid-js";
2
- import { ArrowUp as gt, Copy as ut, Trash as ht } from "../icons/index.js";
3
- import { getTopZIndex as ft, createContextMenuPosition as wt, createWorkbenchId as mt, findNearestWidget as Wt, clampScale as xt, WORKBENCH_CANVAS_ZOOM_STEP as R, WORKBENCH_CONTEXT_MENU_WIDTH_PX as St, estimateContextMenuHeight as pt } from "./workbenchHelpers.js";
4
- import { resolveWorkbenchWidgetDefinitions as Ct, getWidgetEntry as q, createWorkbenchFilterState as kt } from "./widgets/widgetRegistry.js";
5
- function At(c) {
6
- const [f, w] = _(null), [B, A] = _(null), [S, P] = _({ width: 0, height: 0 }), l = c.state, u = s(() => l().widgets), a = s(() => l().viewport), v = s(() => l().locked), D = s(() => l().filters), p = s(() => l().selectedWidgetId), C = s(() => ft(u())), Z = s(() => `${Math.round(a().scale * 100)}%`), $ = () => typeof c.widgetDefinitions == "function" ? c.widgetDefinitions() : c.widgetDefinitions, h = s(
7
- () => Ct($())
8
- ), j = (t) => {
9
- t && P({ width: t.clientWidth, height: t.clientHeight });
10
- }, K = (t) => {
11
- w({
1
+ import { createSignal as _, createMemo as d, onCleanup as mt } from "solid-js";
2
+ import { ArrowUp as Wt, Copy as xt, Trash as St } from "../icons/index.js";
3
+ import { getTopZIndex as Ct, createContextMenuPosition as pt, createWorkbenchId as kt, findNearestWidget as Ft, clampScale as Xt, WORKBENCH_CANVAS_ZOOM_STEP as P, WORKBENCH_CONTEXT_MENU_WIDTH_PX as bt, estimateContextMenuHeight as Mt } from "./workbenchHelpers.js";
4
+ import { resolveWorkbenchWidgetDefinitions as Yt, getWidgetEntry as Z, createWorkbenchFilterState as yt } from "./widgets/widgetRegistry.js";
5
+ function Nt(s) {
6
+ const [m, W] = _(null), [$, A] = _(null), [j, K] = _({ width: 0, height: 0 });
7
+ let r = null, x = null;
8
+ const a = s.state, h = d(() => a().widgets), u = d(() => a().viewport), L = d(() => a().locked), D = d(() => a().filters), k = d(() => a().selectedWidgetId), F = d(() => Ct(h())), U = d(() => `${Math.round(u().scale * 100)}%`), G = () => typeof s.widgetDefinitions == "function" ? s.widgetDefinitions() : s.widgetDefinitions, f = d(
9
+ () => Yt(G())
10
+ ), X = (t, e) => {
11
+ const n = Number.isFinite(t) && t > 0 ? t : 0, i = Number.isFinite(e) && e > 0 ? e : 0, o = { width: n, height: i }, c = j();
12
+ return c.width === n && c.height === i ? c : (K(o), o);
13
+ }, T = () => {
14
+ x?.disconnect(), x = null;
15
+ }, w = () => r ? X(r.clientWidth, r.clientHeight) : X(0, 0), J = (t) => {
16
+ if (r === (t ?? null)) {
17
+ w();
18
+ return;
19
+ }
20
+ T(), r = t ?? null, w(), !(!r || typeof ResizeObserver > "u") && (x = new ResizeObserver((e) => {
21
+ const n = e[0];
22
+ X(
23
+ n?.contentRect.width ?? r?.clientWidth ?? 0,
24
+ n?.contentRect.height ?? r?.clientHeight ?? 0
25
+ );
26
+ }), x.observe(r));
27
+ };
28
+ mt(() => {
29
+ T(), r = null;
30
+ });
31
+ const Q = (t) => {
32
+ W({
12
33
  clientX: t.clientX,
13
34
  clientY: t.clientY,
14
35
  worldX: t.worldX,
15
36
  worldY: t.worldY
16
37
  });
17
- }, L = (t, e) => {
18
- m(e.id), w({
38
+ }, tt = (t, e) => {
39
+ S(e.id), W({
19
40
  clientX: t.clientX,
20
41
  clientY: t.clientY,
21
42
  worldX: e.x,
22
43
  worldY: e.y,
23
44
  widgetId: e.id
24
45
  });
25
- }, g = () => w(null), U = (t) => l().widgets.find((e) => e.id === t) ?? null, k = (t) => l().widgets.find((e) => e.type === t) ?? null, T = s(() => {
26
- const t = f();
46
+ }, g = () => W(null), et = (t) => a().widgets.find((e) => e.id === t) ?? null, b = (t) => a().widgets.find((e) => e.type === t) ?? null, N = d(() => {
47
+ const t = m();
27
48
  if (!t) return [];
28
49
  if (t.widgetId) {
29
- const e = u().find((i) => i.id === t.widgetId), n = [];
50
+ const e = h().find((i) => i.id === t.widgetId), n = [];
30
51
  return e && (n.push({
31
52
  id: "bring-to-front",
32
53
  kind: "action",
33
54
  label: "Bring to Front",
34
- icon: gt,
55
+ icon: Wt,
35
56
  onSelect: () => {
36
- m(e.id), g();
57
+ S(e.id), g();
37
58
  }
38
59
  }), n.push({
39
60
  id: "duplicate",
40
61
  kind: "action",
41
62
  label: "Duplicate",
42
- icon: ut,
63
+ icon: xt,
43
64
  onSelect: () => {
44
- z(e.type, e.x + 32, e.y + 32), g();
65
+ R(e.type, e.x + 32, e.y + 32), g();
45
66
  }
46
67
  })), n.push({ id: "separator-delete", kind: "separator" }), n.push({
47
68
  id: "delete",
48
69
  kind: "action",
49
70
  label: "Delete",
50
- icon: ht,
71
+ icon: St,
51
72
  destructive: !0,
52
73
  onSelect: () => {
53
- t.widgetId && Y(t.widgetId), g();
74
+ t.widgetId && y(t.widgetId), g();
54
75
  }
55
76
  }), n;
56
77
  }
57
- return h().map((e) => ({
78
+ return f().map((e) => ({
58
79
  id: `add-${e.type}`,
59
80
  kind: "action",
60
81
  label: `Add ${e.label}`,
61
82
  icon: e.icon,
62
83
  onSelect: () => {
63
- M(e.type, t.worldX, t.worldY), g();
84
+ Y(e.type, t.worldX, t.worldY), g();
64
85
  }
65
86
  }));
66
- }), G = s(() => {
67
- const t = f();
87
+ }), nt = d(() => {
88
+ const t = m();
68
89
  if (!t) return;
69
- const e = T(), n = e.filter((o) => o.kind === "action").length, i = e.filter((o) => o.kind === "separator").length;
70
- return wt({
90
+ const e = N(), n = e.filter((o) => o.kind === "action").length, i = e.filter((o) => o.kind === "separator").length;
91
+ return pt({
71
92
  clientX: t.clientX,
72
93
  clientY: t.clientY,
73
- menuWidth: St,
74
- menuHeight: pt(n, i)
94
+ menuWidth: bt,
95
+ menuHeight: Mt(n, i)
75
96
  });
76
- }), X = (t, e, n) => {
77
- const i = q(t, h()), o = i.singleton ? k(t) : null;
97
+ }), M = (t, e, n) => {
98
+ const i = Z(t, f()), o = i.singleton ? b(t) : null;
78
99
  if (o)
79
- return W(o, { centerViewport: !0 });
80
- const d = i.defaultSize, r = {
81
- id: mt(),
100
+ return C(o, { centerViewport: !0 });
101
+ const c = i.defaultSize, l = {
102
+ id: kt(),
82
103
  type: t,
83
104
  title: i.defaultTitle,
84
105
  x: e,
85
106
  y: n,
86
- width: d.width,
87
- height: d.height,
88
- z_index: C() + 1,
107
+ width: c.width,
108
+ height: c.height,
109
+ z_index: F() + 1,
89
110
  created_at_unix_ms: Date.now()
90
111
  };
91
- return c.setState((x) => ({
92
- ...x,
93
- widgets: [...x.widgets, r],
94
- selectedWidgetId: r.id
95
- })), r;
96
- }, M = (t, e, n) => {
97
- const i = q(t, h()).defaultSize;
98
- return X(t, e - i.width / 2, n - i.height / 2);
99
- }, z = (t, e, n) => X(t, e, n), Y = (t) => {
100
- c.setState((e) => ({
112
+ return s.setState((p) => ({
113
+ ...p,
114
+ widgets: [...p.widgets, l],
115
+ selectedWidgetId: l.id
116
+ })), l;
117
+ }, Y = (t, e, n) => {
118
+ const i = Z(t, f()).defaultSize;
119
+ return M(t, e - i.width / 2, n - i.height / 2);
120
+ }, R = (t, e, n) => M(t, e, n), y = (t) => {
121
+ s.setState((e) => ({
101
122
  ...e,
102
123
  widgets: e.widgets.filter((n) => n.id !== t),
103
124
  selectedWidgetId: e.selectedWidgetId === t ? null : e.selectedWidgetId
104
125
  }));
105
- }, J = (t) => {
126
+ }, it = (t) => {
106
127
  A(t);
107
- }, m = (t) => {
128
+ }, S = (t) => {
108
129
  A(t);
109
- const e = C(), n = u().find((i) => i.id === t);
110
- n && n.z_index < e && c.setState((i) => ({
130
+ const e = F(), n = h().find((i) => i.id === t);
131
+ n && n.z_index < e && s.setState((i) => ({
111
132
  ...i,
112
133
  widgets: i.widgets.map(
113
134
  (o) => o.id === t ? { ...o, z_index: e + 1 } : o
114
135
  )
115
136
  }));
116
- }, Q = (t, e) => {
117
- c.setState((n) => ({
137
+ }, ot = (t, e) => {
138
+ s.setState((n) => ({
118
139
  ...n,
119
140
  widgets: n.widgets.map(
120
141
  (i) => i.id === t ? { ...i, x: e.x, y: e.y } : i
121
142
  )
122
143
  }));
123
- }, tt = (t, e) => {
124
- c.setState((n) => ({
144
+ }, st = (t, e) => {
145
+ s.setState((n) => ({
125
146
  ...n,
126
147
  widgets: n.widgets.map(
127
148
  (i) => i.id === t ? { ...i, width: e.width, height: e.height } : i
128
149
  )
129
150
  }));
130
151
  }, I = (t) => {
131
- c.setState((e) => ({ ...e, viewport: t }));
132
- }, O = (t) => {
133
- const e = a(), n = S(), i = (n.width / 2 - e.x) / e.scale, o = (n.height / 2 - e.y) / e.scale, d = xt(
134
- t === "in" ? e.scale * R : e.scale / R
135
- ), r = {
136
- x: n.width / 2 - i * d,
137
- y: n.height / 2 - o * d,
138
- scale: d
152
+ s.setState((e) => ({ ...e, viewport: t }));
153
+ }, V = (t) => {
154
+ const e = u(), n = w(), i = (n.width / 2 - e.x) / e.scale, o = (n.height / 2 - e.y) / e.scale, c = Xt(
155
+ t === "in" ? e.scale * P : e.scale / P
156
+ ), l = {
157
+ x: n.width / 2 - i * c,
158
+ y: n.height / 2 - o * c,
159
+ scale: c
139
160
  };
140
- I(r);
141
- }, et = () => {
142
- c.setState((t) => ({ ...t, locked: !t.locked }));
143
- }, nt = (t) => {
144
- c.setState((e) => ({
161
+ I(l);
162
+ }, ct = () => {
163
+ s.setState((t) => ({ ...t, locked: !t.locked }));
164
+ }, rt = (t) => {
165
+ s.setState((e) => ({
145
166
  ...e,
146
167
  filters: { ...e.filters, [t]: !e.filters[t] }
147
168
  }));
148
- }, it = (t) => {
149
- c.setState((e) => {
169
+ }, dt = (t) => {
170
+ s.setState((e) => {
150
171
  const n = { ...e.filters };
151
172
  for (const i of Object.keys(n))
152
173
  n[i] = i === t;
153
174
  return { ...e, filters: n };
154
175
  });
155
- }, ot = () => {
156
- const t = kt(h());
157
- c.setState((e) => ({
176
+ }, lt = () => {
177
+ const t = yt(f());
178
+ s.setState((e) => ({
158
179
  ...e,
159
180
  filters: t
160
181
  }));
161
- }, V = (t) => {
162
- c.setState((e) => ({ ...e, selectedWidgetId: t }));
163
- }, ct = () => {
164
- const t = S(), e = a();
182
+ }, H = (t) => {
183
+ s.setState((e) => ({ ...e, selectedWidgetId: t }));
184
+ }, at = () => {
185
+ const t = w(), e = u();
165
186
  return {
166
187
  worldX: t.width > 0 ? (t.width / 2 - e.x) / e.scale : 240,
167
188
  worldY: t.height > 0 ? (t.height / 2 - e.y) / e.scale : 180
168
189
  };
169
190
  };
170
- let N = 0;
171
- const st = (t, e, n) => {
172
- const i = a(), o = i.x, d = i.y, r = i.scale, x = performance.now(), dt = 360, rt = ++N, lt = (F) => 1 - Math.pow(1 - F, 3), E = (F) => {
173
- if (rt !== N) return;
174
- const at = F - x, H = Math.min(Math.max(at / dt, 0), 1), b = lt(H);
191
+ let E = 0;
192
+ const ut = (t, e, n) => {
193
+ const i = u(), o = i.x, c = i.y, l = i.scale, p = performance.now(), gt = 360, ht = ++E, ft = (v) => 1 - Math.pow(1 - v, 3), q = (v) => {
194
+ if (ht !== E) return;
195
+ const wt = v - p, B = Math.min(Math.max(wt / gt, 0), 1), O = ft(B);
175
196
  I({
176
- x: o + (t - o) * b,
177
- y: d + (e - d) * b,
178
- scale: r + (n - r) * b
179
- }), H < 1 && requestAnimationFrame(E);
197
+ x: o + (t - o) * O,
198
+ y: c + (e - c) * O,
199
+ scale: l + (n - l) * O
200
+ }), B < 1 && requestAnimationFrame(q);
180
201
  };
181
- requestAnimationFrame(E);
182
- }, y = (t) => {
183
- const e = S();
202
+ requestAnimationFrame(q);
203
+ }, z = (t) => {
204
+ const e = w();
184
205
  if (e.width === 0 || e.height === 0) return;
185
- const n = a(), i = e.width / 2 - (t.x + t.width / 2) * n.scale, o = e.height / 2 - (t.y + t.height / 2) * n.scale;
186
- st(i, o, n.scale);
187
- }, W = (t, e = {}) => (V(t.id), m(t.id), e.centerViewport !== !1 && y(t), t);
206
+ const n = u(), i = e.width / 2 - (t.x + t.width / 2) * n.scale, o = e.height / 2 - (t.y + t.height / 2) * n.scale;
207
+ ut(i, o, n.scale);
208
+ }, C = (t, e = {}) => (H(t.id), S(t.id), e.centerViewport !== !1 && z(t), t);
188
209
  return {
189
- widgets: u,
190
- viewport: a,
191
- locked: v,
210
+ widgets: h,
211
+ viewport: u,
212
+ locked: L,
192
213
  filters: D,
193
- selectedWidgetId: p,
194
- topZIndex: C,
195
- scaleLabel: Z,
196
- optimisticFrontWidgetId: B,
197
- widgetDefinitions: h,
198
- setCanvasFrameRef: j,
214
+ selectedWidgetId: k,
215
+ topZIndex: F,
216
+ scaleLabel: U,
217
+ optimisticFrontWidgetId: $,
218
+ widgetDefinitions: f,
219
+ setCanvasFrameRef: J,
199
220
  contextMenu: {
200
- state: f,
201
- items: T,
202
- position: G,
221
+ state: m,
222
+ items: N,
223
+ position: nt,
203
224
  close: g,
204
225
  retarget: (t) => {
205
- t.preventDefault(), t.stopPropagation(), w({
226
+ t.preventDefault(), t.stopPropagation(), W({
206
227
  clientX: t.clientX,
207
228
  clientY: t.clientY,
208
229
  worldX: 0,
@@ -211,74 +232,74 @@ function At(c) {
211
232
  }
212
233
  },
213
234
  canvas: {
214
- openCanvasContextMenu: K,
215
- openWidgetContextMenu: L,
216
- selectWidget: V,
217
- startOptimisticFront: J,
218
- commitFront: m,
219
- commitMove: Q,
220
- commitResize: tt,
235
+ openCanvasContextMenu: Q,
236
+ openWidgetContextMenu: tt,
237
+ selectWidget: H,
238
+ startOptimisticFront: it,
239
+ commitFront: S,
240
+ commitMove: ot,
241
+ commitResize: st,
221
242
  commitViewport: I
222
243
  },
223
244
  hud: {
224
- zoomIn: () => O("in"),
225
- zoomOut: () => O("out")
245
+ zoomIn: () => V("in"),
246
+ zoomOut: () => V("out")
226
247
  },
227
248
  lock: {
228
- toggle: et
249
+ toggle: ct
229
250
  },
230
251
  filter: {
231
- toggle: nt,
232
- solo: it,
233
- showAll: ot
252
+ toggle: rt,
253
+ solo: dt,
254
+ showAll: lt
234
255
  },
235
256
  navigation: {
236
257
  handleArrowNavigation: (t) => {
237
- const e = Wt(
238
- u(),
239
- p(),
258
+ const e = Ft(
259
+ h(),
260
+ k(),
240
261
  t,
241
262
  D()
242
263
  );
243
- e && W(e);
264
+ e && C(e);
244
265
  },
245
- centerOnWidget: y,
246
- focusWidget: W
266
+ centerOnWidget: z,
267
+ focusWidget: C
247
268
  },
248
269
  widgetActions: {
249
270
  deleteSelected: () => {
250
- const t = p();
251
- t && Y(t);
271
+ const t = k();
272
+ t && y(t);
252
273
  },
253
- deleteWidget: Y,
254
- addWidget: X,
255
- addWidgetAtCursor: M,
256
- addWidgetCentered: z,
274
+ deleteWidget: y,
275
+ addWidget: M,
276
+ addWidgetAtCursor: Y,
277
+ addWidgetCentered: R,
257
278
  ensureWidget: (t, e) => {
258
- const n = k(t);
279
+ const n = b(t);
259
280
  if (n)
260
- return W(n, { centerViewport: e?.centerViewport ?? !0 });
261
- const i = ct(), o = M(
281
+ return C(n, { centerViewport: e?.centerViewport ?? !0 });
282
+ const i = at(), o = Y(
262
283
  t,
263
284
  e?.worldX ?? i.worldX,
264
285
  e?.worldY ?? i.worldY
265
286
  );
266
- return (e?.centerViewport ?? !0) && o && y(o), o;
287
+ return (e?.centerViewport ?? !0) && o && z(o), o;
267
288
  }
268
289
  },
269
290
  queries: {
270
- findWidgetByType: k,
271
- findWidgetById: U
291
+ findWidgetByType: b,
292
+ findWidgetById: et
272
293
  },
273
294
  handleCloseRequest: () => {
274
- if (f()) {
295
+ if (m()) {
275
296
  g();
276
297
  return;
277
298
  }
278
- c.onClose();
299
+ s.onClose();
279
300
  }
280
301
  };
281
302
  }
282
303
  export {
283
- At as useWorkbenchModel
304
+ Nt as useWorkbenchModel
284
305
  };
@@ -10,6 +10,11 @@ export declare function sanitizeWorkbenchState(input: unknown, options?: Sanitiz
10
10
  export declare function createDefaultWorkbenchState(widgetDefinitions?: readonly WorkbenchWidgetDefinition[]): WorkbenchState;
11
11
  export declare const WORKBENCH_CANVAS_ZOOM_STEP = 1.18;
12
12
  export declare const WORKBENCH_CONTEXT_MENU_WIDTH_PX = 200;
13
+ export interface WorkbenchRenderLayerMap {
14
+ byWidgetId: ReadonlyMap<string, number>;
15
+ topRenderLayer: number;
16
+ }
17
+ export declare function createWorkbenchRenderLayerMap(widgets: readonly WorkbenchWidgetItem[]): WorkbenchRenderLayerMap;
13
18
  export declare function createContextMenuPosition(options: {
14
19
  clientX: number;
15
20
  clientY: number;