@cwygoda/service-catalog-ui 1.5.1 → 1.6.0

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.

Potentially problematic release.


This version of @cwygoda/service-catalog-ui might be problematic. Click here for more details.

@@ -54,18 +54,29 @@
54
54
  // Fullscreen state
55
55
  let isFullscreen = $state(false);
56
56
 
57
+ function setBodyOverflow(hidden: boolean) {
58
+ if (!browser) return;
59
+ document.body.style.overflow = hidden ? 'hidden' : '';
60
+ }
61
+
62
+ function handleEscapeKey(e: KeyboardEvent) {
63
+ if (e.key === 'Escape' && isFullscreen) {
64
+ toggleFullscreen();
65
+ }
66
+ }
67
+
57
68
  function toggleFullscreen() {
58
69
  if (!browser) return;
59
- if (!document.fullscreenElement) {
60
- void wrapper.requestFullscreen();
70
+ isFullscreen = !isFullscreen;
71
+ setBodyOverflow(isFullscreen);
72
+
73
+ if (isFullscreen) {
74
+ document.addEventListener('keydown', handleEscapeKey);
61
75
  } else {
62
- void document.exitFullscreen();
76
+ document.removeEventListener('keydown', handleEscapeKey);
63
77
  }
64
- }
65
78
 
66
- function handleFullscreenChange() {
67
- isFullscreen = !!document.fullscreenElement;
68
- // Re-fit diagram when entering/exiting fullscreen
79
+ // Re-fit diagram after layout settles
69
80
  if (ready) {
70
81
  setTimeout(fitWithPadding, FULLSCREEN_TRANSITION_MS);
71
82
  }
@@ -129,11 +140,53 @@
129
140
  fitWithPadding();
130
141
  }
131
142
 
143
+ /**
144
+ * Re-center inline message-flow labels rendered by bpmn-js.
145
+ * bpmn-js positions these labels using getBBox() which can return
146
+ * incorrect widths before fonts are loaded, causing left-aligned labels.
147
+ */
148
+ function fixMessageFlowLabels() {
149
+ if (!viewer) return;
150
+
151
+ const elementRegistry = viewer.get('elementRegistry') as {
152
+ forEach: (cb: (el: { id: string; type: string }) => void) => void;
153
+ getGraphics: (el: { id: string }) => SVGElement | null;
154
+ };
155
+
156
+ elementRegistry.forEach((el) => {
157
+ if (el.type !== 'bpmn:MessageFlow') return;
158
+
159
+ const gfx = elementRegistry.getGraphics(el);
160
+ if (!gfx) return;
161
+
162
+ const visual = gfx.querySelector('.djs-visual');
163
+ if (!visual) return;
164
+
165
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion -- needed for svelte-check
166
+ const label = visual.querySelector('text.djs-label') as SVGTextElement | null;
167
+ if (!label) return;
168
+
169
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion -- needed for svelte-check
170
+ const pathEl = visual.querySelector('path') as SVGPathElement | null;
171
+ if (!pathEl?.getTotalLength) return;
172
+
173
+ const midPoint = pathEl.getPointAtLength(pathEl.getTotalLength() / 2);
174
+ const bbox = label.getBBox();
175
+ if (bbox.width <= 0) return;
176
+
177
+ // Preserve current Y from the existing translate transform
178
+ const { baseVal } = label.transform;
179
+ if (baseVal.numberOfItems < 1) return;
180
+
181
+ const t = baseVal.getItem(0);
182
+ const newTx = midPoint.x - bbox.width / 2;
183
+ t.setTranslate(newTx, t.matrix.f);
184
+ });
185
+ }
186
+
132
187
  onMount(async () => {
133
188
  if (!browser || !xml) return;
134
189
 
135
- document.addEventListener('fullscreenchange', handleFullscreenChange);
136
-
137
190
  try {
138
191
  // Dynamic import to avoid SSR issues
139
192
  const { default: BpmnViewer } = await import('bpmn-js/lib/NavigatedViewer');
@@ -144,6 +197,7 @@
144
197
  }) as BpmnViewer;
145
198
 
146
199
  await viewer.importXML(xml);
200
+ fixMessageFlowLabels();
147
201
 
148
202
  // Register click handler for doc links
149
203
  if (onElementClick) {
@@ -192,7 +246,8 @@
192
246
 
193
247
  onDestroy(() => {
194
248
  if (browser) {
195
- document.removeEventListener('fullscreenchange', handleFullscreenChange);
249
+ document.removeEventListener('keydown', handleEscapeKey);
250
+ setBodyOverflow(false);
196
251
  }
197
252
  resizeObserver?.disconnect();
198
253
  if (viewer?.destroy) {
@@ -206,6 +261,7 @@
206
261
  viewer
207
262
  .importXML(xml)
208
263
  .then(() => {
264
+ fixMessageFlowLabels();
209
265
  fitWithPadding();
210
266
  })
211
267
  .catch((e: unknown) => {
@@ -225,13 +281,15 @@
225
281
  {:else}
226
282
  <div
227
283
  bind:this={wrapper}
228
- class="bpmn-wrapper relative {isFullscreen ? 'bg-white dark:bg-gray-900' : ''}"
284
+ class="bpmn-wrapper relative {isFullscreen
285
+ ? 'fixed inset-0 z-50 bg-white dark:bg-gray-900'
286
+ : ''}"
229
287
  >
230
288
  <div
231
289
  bind:this={container}
232
- class="bpmn-container w-full rounded-lg border border-gray-200 bg-white {isFullscreen
233
- ? 'h-screen'
234
- : 'h-64 sm:h-80 md:h-96'} dark:border-gray-700 dark:bg-gray-800"
290
+ class="bpmn-container w-full {isFullscreen
291
+ ? 'h-full bg-white dark:bg-gray-900'
292
+ : 'h-64 rounded-lg border border-gray-200 bg-white sm:h-80 md:h-96 dark:border-gray-700 dark:bg-gray-800'}"
235
293
  class:cursor-grab={interactive}
236
294
  role="img"
237
295
  aria-label="BPMN process diagram"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cwygoda/service-catalog-ui",
3
- "version": "1.5.1",
3
+ "version": "1.6.0",
4
4
  "type": "module",
5
5
  "svelte": "./dist/index.js",
6
6
  "exports": {
@@ -25,7 +25,7 @@
25
25
  ],
26
26
  "dependencies": {
27
27
  "@sinclair/typebox": "^0.34.0",
28
- "@cwygoda/service-catalog-core": "1.5.1"
28
+ "@cwygoda/service-catalog-core": "1.6.0"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "@sveltejs/kit": "^2.0.0",