@cratis/event-models 0.239.1 → 0.239.2

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