@cratis/event-models 0.195.0 → 0.195.1

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.
@@ -0,0 +1,501 @@
1
+ import { useCallback as R, useEffect as x, useLayoutEffect as F, useMemo as q, useRef as L, useState as T } from "react";
2
+ import { TemplateReferenceSource as O, TemplateScope as U } from "@cratis/scene.model";
3
+ import { Fragment as j, jsx as c, jsxs as N } from "react/jsx-runtime";
4
+ import { createPortal as W } from "react-dom";
5
+ function G(e, a, o) {
6
+ const n = o.trim().toLocaleLowerCase();
7
+ return n.length === 0 ? !0 : [
8
+ e.displayName,
9
+ e.name,
10
+ e.description,
11
+ e.metadata?.category,
12
+ e.metadata?.type,
13
+ a
14
+ ].some((r) => r?.toLocaleLowerCase().includes(n));
15
+ }
16
+ var l = /* @__PURE__ */ (function(e) {
17
+ return e.Heading = "heading", e.Subheading = "subheading", e.Item = "item", e.Submenu = "submenu", e.Separator = "separator", e.Note = "note", e;
18
+ })({}), M = 8, S = 4;
19
+ function J(e, a, o) {
20
+ const n = Math.max(M, Math.min(e.left, o.width - a.width - M)), r = e.top + e.height + S;
21
+ return {
22
+ left: n,
23
+ top: r + a.height <= o.height - M ? r : Math.max(M, e.top - a.height - S)
24
+ };
25
+ }
26
+ function K(e, a, o) {
27
+ const n = e.left + e.width + S;
28
+ return {
29
+ left: n + a.width <= o.width - M ? n : Math.max(M, e.left - a.width - S),
30
+ top: Math.max(M, Math.min(e.top - 4, o.height - a.height - M))
31
+ };
32
+ }
33
+ var H = ({ entries: e, depth: a, anchor: o, openPath: n, label: r, filter: u, onOpen: d, onCollapse: h, onChosen: m }) => {
34
+ const p = L(null), [f, _] = T();
35
+ F(() => {
36
+ const t = p.current?.getBoundingClientRect();
37
+ if (!t) return;
38
+ const s = {
39
+ width: window.innerWidth,
40
+ height: window.innerHeight
41
+ };
42
+ _(a === 0 ? J(o, t, s) : K(o, t, s));
43
+ }, [
44
+ o,
45
+ a,
46
+ e
47
+ ]), x(() => {
48
+ a === 0 && f && p.current?.querySelector("[data-cascade-focusable]")?.focus();
49
+ }, [a, f === void 0]);
50
+ const k = n[a], i = k ? e.find((t) => t.kind === l.Submenu && t.id === k.id) : void 0;
51
+ return /* @__PURE__ */ N(j, { children: [/* @__PURE__ */ N("div", {
52
+ ref: p,
53
+ className: "studio-cascade-menu__panel",
54
+ role: "menu",
55
+ "aria-label": r,
56
+ "data-cascade-depth": a,
57
+ style: {
58
+ top: f?.top ?? 0,
59
+ left: f?.left ?? 0,
60
+ visibility: f ? "visible" : "hidden"
61
+ },
62
+ children: [u && /* @__PURE__ */ c("input", {
63
+ type: "search",
64
+ className: "studio-cascade-menu__filter",
65
+ role: "searchbox",
66
+ "aria-label": u.placeholder,
67
+ placeholder: u.placeholder,
68
+ value: u.value,
69
+ "data-cascade-focusable": "",
70
+ onChange: (t) => u.onChange(t.target.value)
71
+ }), e.map((t) => {
72
+ switch (t.kind) {
73
+ case l.Heading:
74
+ return /* @__PURE__ */ c("div", {
75
+ className: "studio-cascade-menu__heading",
76
+ role: "presentation",
77
+ "data-cascade-entry": t.id,
78
+ children: t.label
79
+ }, t.id);
80
+ case l.Subheading:
81
+ return /* @__PURE__ */ c("div", {
82
+ className: "studio-cascade-menu__subheading",
83
+ role: "presentation",
84
+ "data-cascade-entry": t.id,
85
+ children: t.label
86
+ }, t.id);
87
+ case l.Separator:
88
+ return /* @__PURE__ */ c("div", {
89
+ className: "studio-cascade-menu__separator",
90
+ role: "separator"
91
+ }, t.id);
92
+ case l.Note:
93
+ return /* @__PURE__ */ c("div", {
94
+ className: "studio-cascade-menu__note",
95
+ role: "presentation",
96
+ "data-cascade-entry": t.id,
97
+ children: t.label
98
+ }, t.id);
99
+ case l.Submenu:
100
+ return /* @__PURE__ */ N("button", {
101
+ type: "button",
102
+ role: "menuitem",
103
+ "aria-haspopup": "menu",
104
+ "aria-expanded": k?.id === t.id,
105
+ className: `studio-cascade-menu__row studio-cascade-menu__row--submenu${k?.id === t.id ? " studio-cascade-menu__row--open" : ""}`,
106
+ "data-cascade-focusable": "",
107
+ "data-cascade-entry": t.id,
108
+ onMouseEnter: (s) => d(a, {
109
+ id: t.id,
110
+ rect: D(s.currentTarget)
111
+ }),
112
+ onClick: (s) => d(a, {
113
+ id: t.id,
114
+ rect: D(s.currentTarget)
115
+ }),
116
+ children: [/* @__PURE__ */ c("span", {
117
+ className: "studio-cascade-menu__label",
118
+ children: t.label
119
+ }), /* @__PURE__ */ c("span", {
120
+ className: "studio-cascade-menu__chevron",
121
+ "aria-hidden": "true",
122
+ children: "▸"
123
+ })]
124
+ }, t.id);
125
+ default:
126
+ return /* @__PURE__ */ N("div", {
127
+ className: "studio-cascade-menu__line",
128
+ role: "presentation",
129
+ onMouseEnter: () => h(a),
130
+ children: [/* @__PURE__ */ N("button", {
131
+ type: "button",
132
+ role: t.checked === void 0 ? "menuitem" : "menuitemradio",
133
+ "aria-checked": t.checked,
134
+ "aria-disabled": t.disabledReason !== void 0,
135
+ title: t.disabledReason,
136
+ className: `studio-cascade-menu__row${t.checked ? " studio-cascade-menu__row--current" : ""}${t.disabledReason ? " studio-cascade-menu__row--disabled" : ""}`,
137
+ "data-cascade-focusable": "",
138
+ "data-cascade-entry": t.id,
139
+ onClick: () => {
140
+ t.disabledReason || (t.onActivate(), m());
141
+ },
142
+ children: [
143
+ /* @__PURE__ */ c("span", {
144
+ className: "studio-cascade-menu__check",
145
+ "aria-hidden": "true",
146
+ children: t.checked ? "✓" : ""
147
+ }),
148
+ /* @__PURE__ */ N("span", {
149
+ className: "studio-cascade-menu__text",
150
+ children: [/* @__PURE__ */ c("span", {
151
+ className: "studio-cascade-menu__label",
152
+ children: t.label
153
+ }), t.description && /* @__PURE__ */ c("span", {
154
+ className: "studio-cascade-menu__description",
155
+ children: t.description
156
+ })]
157
+ }),
158
+ t.trailing && /* @__PURE__ */ c("span", {
159
+ className: "studio-cascade-menu__trailing",
160
+ children: t.trailing
161
+ })
162
+ ]
163
+ }), t.actions?.map((s, g) => /* @__PURE__ */ c("button", {
164
+ type: "button",
165
+ className: "studio-cascade-menu__secondary",
166
+ "data-cascade-focusable": "",
167
+ "data-cascade-entry": `${t.id}:action-${g}`,
168
+ title: s.label,
169
+ "aria-label": `${s.label}: ${t.label}`,
170
+ onClick: () => {
171
+ s.onActivate(), s.closes && m();
172
+ },
173
+ children: s.label
174
+ }, g))]
175
+ }, t.id);
176
+ }
177
+ })]
178
+ }), i && i.kind === l.Submenu && /* @__PURE__ */ c(H, {
179
+ entries: i.entries,
180
+ depth: a + 1,
181
+ anchor: k.rect,
182
+ openPath: n,
183
+ label: i.label,
184
+ onOpen: d,
185
+ onCollapse: h,
186
+ onChosen: m
187
+ })] });
188
+ };
189
+ function D(e) {
190
+ const { top: a, left: o, width: n, height: r } = e.getBoundingClientRect();
191
+ return {
192
+ top: a,
193
+ left: o,
194
+ width: n,
195
+ height: r
196
+ };
197
+ }
198
+ var w = /* @__PURE__ */ (function(e) {
199
+ return e.Previous = "previous", e.Next = "next", e.First = "first", e.Last = "last", e.Into = "into", e.Out = "out", e;
200
+ })({});
201
+ function Q(e, a) {
202
+ switch (e) {
203
+ case "ArrowDown":
204
+ return w.Next;
205
+ case "ArrowUp":
206
+ return w.Previous;
207
+ case "ArrowRight":
208
+ return a ? void 0 : w.Into;
209
+ case "ArrowLeft":
210
+ return a ? void 0 : w.Out;
211
+ case "Home":
212
+ return a ? void 0 : w.First;
213
+ case "End":
214
+ return a ? void 0 : w.Last;
215
+ default:
216
+ return;
217
+ }
218
+ }
219
+ function V(e, a, o) {
220
+ if (o === 0) return -1;
221
+ switch (e) {
222
+ case w.First:
223
+ return 0;
224
+ case w.Last:
225
+ return o - 1;
226
+ case w.Previous:
227
+ return a <= 0 ? o - 1 : a - 1;
228
+ default:
229
+ return a < 0 || a >= o - 1 ? 0 : a + 1;
230
+ }
231
+ }
232
+ var v = (e) => {
233
+ e.isPropagationStopped = () => !0;
234
+ }, X = {
235
+ onPointerDown: v,
236
+ onPointerUp: v,
237
+ onMouseDown: v,
238
+ onMouseUp: v,
239
+ onClick: v,
240
+ onDoubleClick: v,
241
+ onContextMenu: v,
242
+ onWheel: v,
243
+ onKeyUp: v,
244
+ onDragStart: v
245
+ }, Y = v, C = (e) => [...e.querySelectorAll('[data-cascade-focusable]:not([aria-disabled="true"])')], Z = ({ anchor: e, trigger: a, entries: o, label: n, filter: r, onClose: u }) => {
246
+ const d = L(null), [h, m] = T([]), [p] = T(() => ({
247
+ top: e.top,
248
+ left: e.left,
249
+ width: e.width,
250
+ height: e.height
251
+ }));
252
+ x(() => {
253
+ const i = a ?? (document.activeElement instanceof HTMLElement ? document.activeElement : null);
254
+ return () => i?.focus?.();
255
+ }, [a]), x(() => {
256
+ const i = (t) => {
257
+ const s = t.target;
258
+ !d.current?.contains(s) && !a?.contains(s) && u();
259
+ };
260
+ return document.addEventListener("pointerdown", i, !0), () => document.removeEventListener("pointerdown", i, !0);
261
+ }, [u, a]);
262
+ const f = R((i, t) => m((s) => [...s.slice(0, i), t]), []), _ = R((i) => m((t) => t.length > i ? t.slice(0, i) : t), []);
263
+ return W(/* @__PURE__ */ c("div", {
264
+ ...X,
265
+ ref: d,
266
+ className: "studio-cascade-menu",
267
+ onKeyDown: (i) => {
268
+ Y(i);
269
+ const t = document.activeElement, s = t?.closest(".studio-cascade-menu__panel"), g = Number(s?.dataset.cascadeDepth ?? 0);
270
+ if (i.key === "Escape") {
271
+ if (i.preventDefault(), i.stopPropagation(), g > 0) {
272
+ const b = d.current?.querySelector(`[data-cascade-depth="${g - 1}"] [aria-expanded="true"]`);
273
+ _(g - 1), b?.focus();
274
+ } else u();
275
+ return;
276
+ }
277
+ if (i.key === "Tab" && s) {
278
+ const b = C(s);
279
+ if (b.length === 0) return;
280
+ i.preventDefault();
281
+ const $ = b.indexOf(t);
282
+ b[i.shiftKey ? $ <= 0 ? b.length - 1 : $ - 1 : ($ + 1) % b.length]?.focus();
283
+ return;
284
+ }
285
+ const A = Q(i.key, t instanceof HTMLInputElement);
286
+ if (!A || !s) return;
287
+ if (i.preventDefault(), A === w.Into) {
288
+ if (t?.getAttribute("aria-haspopup") !== "menu") return;
289
+ t.click(), requestAnimationFrame(() => {
290
+ const b = d.current?.querySelector(`[data-cascade-depth="${g + 1}"]`);
291
+ b && C(b)[0]?.focus();
292
+ });
293
+ return;
294
+ }
295
+ if (A === w.Out) {
296
+ if (g === 0) return;
297
+ const b = d.current?.querySelector(`[data-cascade-depth="${g - 1}"] [aria-expanded="true"]`);
298
+ _(g - 1), b?.focus();
299
+ return;
300
+ }
301
+ const P = C(s);
302
+ P[V(A, P.indexOf(t), P.length)]?.focus();
303
+ },
304
+ children: /* @__PURE__ */ c(H, {
305
+ entries: o,
306
+ depth: 0,
307
+ anchor: p,
308
+ openPath: h,
309
+ label: n,
310
+ filter: r,
311
+ onOpen: f,
312
+ onCollapse: _,
313
+ onChosen: u
314
+ })
315
+ }), document.body);
316
+ }, I = /* @__PURE__ */ (function(e) {
317
+ return e.Blueprint = "blueprint", e.Application = "application", e;
318
+ })({}), y = (e) => ({
319
+ kind: l.Separator,
320
+ id: e,
321
+ label: ""
322
+ }), z = " · ";
323
+ function ee(e, a) {
324
+ return a ? (e.reference.source === O.Own ? I.Application : I.Blueprint) === a.kind && e.reference.id.toLowerCase() === a.id.toLowerCase() : !1;
325
+ }
326
+ function te(e, a, o, n, r) {
327
+ const u = (i, t, s) => ({
328
+ kind: l.Item,
329
+ id: t,
330
+ label: i.displayName ?? i.name,
331
+ checked: ee(i, a),
332
+ actions: [...r.onPreview ? [{
333
+ label: n.preview,
334
+ closes: !0,
335
+ onActivate: () => r.onPreview(i)
336
+ }] : [], ...s !== void 0 && r.onCopyToMine ? [{
337
+ label: n.copyToMine,
338
+ closes: !0,
339
+ onActivate: () => r.onCopyToMine(i)
340
+ }] : []],
341
+ onActivate: () => r.onChoose(i)
342
+ }), d = E(e.own, void 0, o), h = d.length > 1 || d.some((i) => i.category !== void 0), m = d.flatMap((i, t) => [...h ? [{
343
+ kind: l.Subheading,
344
+ id: `own-category-${t}`,
345
+ label: i.category ?? n.uncategorized
346
+ }] : [], ...i.templates.map((s) => u(s, `own:${s.reference.id}`))]), p = e.blueprints.map((i) => ({
347
+ blueprint: i,
348
+ categories: E(i.categories, i.blueprint, o)
349
+ })).filter((i) => i.categories.length > 0), f = p.length === 0 ? [] : [{
350
+ kind: l.Submenu,
351
+ id: "blueprints",
352
+ label: n.blueprints,
353
+ entries: [{
354
+ kind: l.Heading,
355
+ id: "blueprints-heading",
356
+ label: n.blueprints
357
+ }, ...p.map(({ blueprint: i, categories: t }) => ({
358
+ kind: l.Submenu,
359
+ id: `blueprint:${i.blueprint}`,
360
+ label: B(i),
361
+ entries: t.flatMap((s, g) => [{
362
+ kind: l.Heading,
363
+ id: `blueprint:${i.blueprint}:category-${g}`,
364
+ label: [B(i), s.category ?? n.uncategorized].join(z)
365
+ }, ...s.templates.map((A) => u(A, `blueprint:${i.blueprint}:${A.reference.id}`, i.blueprint))])
366
+ }))]
367
+ }], _ = [
368
+ ...r.onBrowseAll ? [{
369
+ kind: l.Item,
370
+ id: "browse-all",
371
+ label: n.browseAll,
372
+ onActivate: r.onBrowseAll
373
+ }] : [],
374
+ ...r.onNewFromCurrent ? [{
375
+ kind: l.Item,
376
+ id: "new-from-current",
377
+ label: `+ ${n.newFromCurrent}`,
378
+ onActivate: r.onNewFromCurrent
379
+ }] : [],
380
+ ...r.onClear ? [{
381
+ kind: l.Item,
382
+ id: "clear",
383
+ label: n.clear,
384
+ onActivate: r.onClear
385
+ }] : []
386
+ ], k = m.length === 0 && p.length === 0;
387
+ return [
388
+ ...m.length > 0 ? [{
389
+ kind: l.Heading,
390
+ id: "my-templates",
391
+ label: n.myTemplates
392
+ }, ...m] : [],
393
+ ...k ? [{
394
+ kind: l.Note,
395
+ id: "nothing-applies",
396
+ label: n.nothingApplies
397
+ }] : [],
398
+ ...f.length > 0 ? [...m.length > 0 ? [y("blueprints-separator")] : [], ...f] : [],
399
+ ..._.length > 0 ? [y("footer-separator"), ..._] : []
400
+ ];
401
+ }
402
+ function B(e) {
403
+ return e.displayName ?? e.blueprint;
404
+ }
405
+ function E(e, a, o) {
406
+ return e.map((n) => ({
407
+ ...n,
408
+ templates: n.templates.filter((r) => G(r, a, o))
409
+ })).filter((n) => n.templates.length > 0);
410
+ }
411
+ var ae = ({ anchor: e, trigger: a, applicable: o, current: n, labels: r, handlers: u, onClose: d }) => {
412
+ const [h, m] = T(""), p = q(() => te(o, n, h, r, u), [
413
+ o,
414
+ n,
415
+ h,
416
+ r,
417
+ u
418
+ ]);
419
+ return /* @__PURE__ */ c(Z, {
420
+ anchor: e,
421
+ trigger: a,
422
+ entries: p,
423
+ label: r.menu,
424
+ onClose: d,
425
+ filter: {
426
+ value: h,
427
+ placeholder: r.filter,
428
+ onChange: m
429
+ }
430
+ });
431
+ }, se = ({ applicable: e, current: a, currentLabel: o, status: n, labels: r, handlers: u, ariaLabel: d, disabled: h = !1 }) => {
432
+ const m = L(null), [p, f] = T();
433
+ return /* @__PURE__ */ N("div", {
434
+ className: "studio-template-picker",
435
+ children: [
436
+ /* @__PURE__ */ N("button", {
437
+ ref: m,
438
+ type: "button",
439
+ className: "studio-template-picker__select",
440
+ "aria-haspopup": "menu",
441
+ "aria-expanded": p !== void 0,
442
+ "aria-label": d,
443
+ disabled: h,
444
+ onClick: () => f((_) => _ ? void 0 : m.current?.getBoundingClientRect()),
445
+ children: [/* @__PURE__ */ c("span", {
446
+ className: "studio-template-picker__value",
447
+ children: o ?? r.noTemplate
448
+ }), /* @__PURE__ */ c("span", {
449
+ className: "studio-template-picker__caret",
450
+ "aria-hidden": "true",
451
+ children: "▾"
452
+ })]
453
+ }),
454
+ n && /* @__PURE__ */ c("span", {
455
+ className: "studio-template-picker__status",
456
+ children: n
457
+ }),
458
+ p && /* @__PURE__ */ c(ae, {
459
+ anchor: p,
460
+ trigger: m.current,
461
+ applicable: e,
462
+ current: a,
463
+ labels: r,
464
+ handlers: u,
465
+ onClose: () => f(void 0)
466
+ })
467
+ ]
468
+ });
469
+ };
470
+ function ce({ bundles: e, profile: a, scope: o }) {
471
+ const n = a.layout ? [...e].reverse().flatMap((r) => [...r.layouts ?? []]).find((r) => r.name === a.layout) : void 0;
472
+ return {
473
+ scope: o ?? U.Slice,
474
+ ...n ? { container: {
475
+ name: n.name,
476
+ slots: n.slots
477
+ } } : {}
478
+ };
479
+ }
480
+ function le(e) {
481
+ const a = {
482
+ screen: /* @__PURE__ */ new Map(),
483
+ dialog: /* @__PURE__ */ new Map()
484
+ };
485
+ for (const o of e) {
486
+ for (const n of o.screenTemplates ?? []) a.screen.set(n.name, o.manifest.name);
487
+ for (const n of o.dialogTemplates ?? []) a.dialog.set(n.name, o.manifest.name);
488
+ }
489
+ return e.map((o) => ({
490
+ manifest: o.manifest,
491
+ layouts: o.layouts,
492
+ screenTemplates: o.screenTemplates?.filter((n) => a.screen.get(n.name) === o.manifest.name),
493
+ dialogTemplates: o.dialogTemplates?.filter((n) => a.dialog.get(n.name) === o.manifest.name)
494
+ }));
495
+ }
496
+ export {
497
+ I as i,
498
+ ce as n,
499
+ se as r,
500
+ le as t
501
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cratis/event-models",
3
- "version": "0.195.0",
3
+ "version": "0.195.1",
4
4
  "description": "The Cratis event model board as a configurable React component.",
5
5
  "license": "MIT",
6
6
  "author": "Cratis",
@@ -68,7 +68,7 @@
68
68
  "peerDependencies": {
69
69
  "@cratis/components": "^4.26.2",
70
70
  "@cratis/fundamentals": "^7.22.0",
71
- "@cratis/scene": "^0.195.0",
71
+ "@cratis/scene": "^0.195.1",
72
72
  "@cratis/scene.blueprint.approvals": "^4.12.0",
73
73
  "@cratis/scene.blueprint.components": "^4.12.0",
74
74
  "@cratis/scene.blueprint.crm": "^4.12.0",
@@ -96,7 +96,7 @@
96
96
  "devDependencies": {
97
97
  "@cratis/components": "^4.26.2",
98
98
  "@cratis/fundamentals": "^7.22.0",
99
- "@cratis/scene": "0.195.0",
99
+ "@cratis/scene": "0.195.1",
100
100
  "@cratis/scene.blueprint.approvals": "4.53.0",
101
101
  "@cratis/scene.blueprint.components": "4.53.0",
102
102
  "@cratis/scene.blueprint.crm": "4.53.0",