@eventcatalog/core 2.61.3 → 2.61.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.
@@ -37,7 +37,7 @@ var import_axios = __toESM(require("axios"), 1);
37
37
  var import_os = __toESM(require("os"), 1);
38
38
 
39
39
  // package.json
40
- var version = "2.61.3";
40
+ var version = "2.61.5";
41
41
 
42
42
  // src/constants.ts
43
43
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "../chunk-BMTNHR7C.js";
4
- import "../chunk-LLJZTUOG.js";
3
+ } from "../chunk-PK7HK42H.js";
4
+ import "../chunk-3DQC6REX.js";
5
5
  export {
6
6
  raiseEvent
7
7
  };
@@ -106,7 +106,7 @@ var import_axios = __toESM(require("axios"), 1);
106
106
  var import_os = __toESM(require("os"), 1);
107
107
 
108
108
  // package.json
109
- var version = "2.61.3";
109
+ var version = "2.61.5";
110
110
 
111
111
  // src/constants.ts
112
112
  var VERSION = version;
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  log_build_default
3
- } from "../chunk-EICO7E3X.js";
4
- import "../chunk-BMTNHR7C.js";
5
- import "../chunk-LLJZTUOG.js";
3
+ } from "../chunk-25B6QU5B.js";
4
+ import "../chunk-PK7HK42H.js";
5
+ import "../chunk-3DQC6REX.js";
6
6
  import "../chunk-UPONRQSN.js";
7
7
  export {
8
8
  log_build_default as default
@@ -35,7 +35,7 @@ __export(catalog_to_astro_content_directory_exports, {
35
35
  });
36
36
  module.exports = __toCommonJS(catalog_to_astro_content_directory_exports);
37
37
 
38
- // node_modules/.pnpm/tsup@8.5.0_jiti@1.21.7_postcss@8.5.6_typescript@5.9.2_yaml@2.8.1/node_modules/tsup/assets/cjs_shims.js
38
+ // node_modules/.pnpm/tsup@8.5.0_jiti@1.21.7_postcss@8.5.6_typescript@5.9.3_yaml@2.8.1/node_modules/tsup/assets/cjs_shims.js
39
39
  var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
40
40
  var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
41
41
 
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "./chunk-BMTNHR7C.js";
3
+ } from "./chunk-PK7HK42H.js";
4
4
  import {
5
5
  getEventCatalogConfigFile,
6
6
  verifyRequiredFieldsAreInCatalogConfigFile
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "2.61.3";
2
+ var version = "2.61.5";
3
3
 
4
4
  // src/constants.ts
5
5
  var VERSION = version;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-LLJZTUOG.js";
3
+ } from "./chunk-3DQC6REX.js";
4
4
 
5
5
  // src/analytics/analytics.js
6
6
  import axios from "axios";
@@ -25,7 +25,7 @@ __export(constants_exports, {
25
25
  module.exports = __toCommonJS(constants_exports);
26
26
 
27
27
  // package.json
28
- var version = "2.61.3";
28
+ var version = "2.61.5";
29
29
 
30
30
  // src/constants.ts
31
31
  var VERSION = version;
package/dist/constants.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-LLJZTUOG.js";
3
+ } from "./chunk-3DQC6REX.js";
4
4
  export {
5
5
  VERSION
6
6
  };
@@ -22,7 +22,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  mod
23
23
  ));
24
24
 
25
- // node_modules/.pnpm/tsup@8.5.0_jiti@1.21.7_postcss@8.5.6_typescript@5.9.2_yaml@2.8.1/node_modules/tsup/assets/cjs_shims.js
25
+ // node_modules/.pnpm/tsup@8.5.0_jiti@1.21.7_postcss@8.5.6_typescript@5.9.3_yaml@2.8.1/node_modules/tsup/assets/cjs_shims.js
26
26
  var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
27
27
  var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
28
28
 
@@ -157,7 +157,7 @@ var import_axios = __toESM(require("axios"), 1);
157
157
  var import_os = __toESM(require("os"), 1);
158
158
 
159
159
  // package.json
160
- var version = "2.61.3";
160
+ var version = "2.61.5";
161
161
 
162
162
  // src/constants.ts
163
163
  var VERSION = version;
@@ -6,8 +6,8 @@ import {
6
6
  } from "./chunk-PLNJC7NZ.js";
7
7
  import {
8
8
  log_build_default
9
- } from "./chunk-EICO7E3X.js";
10
- import "./chunk-BMTNHR7C.js";
9
+ } from "./chunk-25B6QU5B.js";
10
+ import "./chunk-PK7HK42H.js";
11
11
  import {
12
12
  catalogToAstro,
13
13
  checkAndConvertMdToMdx
@@ -15,7 +15,7 @@ import {
15
15
  import "./chunk-55D645EH.js";
16
16
  import {
17
17
  VERSION
18
- } from "./chunk-LLJZTUOG.js";
18
+ } from "./chunk-3DQC6REX.js";
19
19
  import {
20
20
  getProjectOutDir,
21
21
  isAuthEnabled,
@@ -0,0 +1,150 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import * as Dialog from '@radix-ui/react-dialog';
3
+ import { ExternalLinkIcon, CheckIcon, ClipboardIcon, Loader2 } from 'lucide-react';
4
+
5
+ const StudioPageModal: React.FC = () => {
6
+ const [isOpen, setIsOpen] = useState(false);
7
+ const [copySuccess, setCopySuccess] = useState(false);
8
+ const [hasCopied, setHasCopied] = useState(false);
9
+ const [isLoading, setIsLoading] = useState(false);
10
+ const [error, setError] = useState<string | null>(null);
11
+
12
+ useEffect(() => {
13
+ const handleOpen = () => setIsOpen(true);
14
+ window.addEventListener('openStudioModal', handleOpen);
15
+ return () => window.removeEventListener('openStudioModal', handleOpen);
16
+ }, []);
17
+
18
+ const handleCopyResources = async () => {
19
+ setIsLoading(true);
20
+ setError(null);
21
+
22
+ try {
23
+ const response = await fetch('/api/catalog');
24
+
25
+ if (!response.ok) {
26
+ throw new Error('Failed to fetch catalog data');
27
+ }
28
+
29
+ const catalogData = await response.json();
30
+
31
+ await navigator.clipboard.writeText(JSON.stringify(catalogData, null, 2));
32
+ setCopySuccess(true);
33
+ setHasCopied(true);
34
+ setTimeout(() => setCopySuccess(false), 2000);
35
+ } catch (err) {
36
+ console.error('Failed to copy resources:', err);
37
+ setError('Failed to copy resources. Please try again.');
38
+ } finally {
39
+ setIsLoading(false);
40
+ }
41
+ };
42
+
43
+ const handleOpenStudio = () => {
44
+ window.open(
45
+ 'https://app.eventcatalog.studio/playground?import-resources=true&utm_source=eventcatalog&utm_medium=referral&utm_campaign=studio-page',
46
+ '_blank'
47
+ );
48
+ setIsOpen(false);
49
+ };
50
+
51
+ return (
52
+ <Dialog.Root open={isOpen} onOpenChange={setIsOpen}>
53
+ <Dialog.Portal>
54
+ <Dialog.Overlay className="fixed inset-0 bg-black/50 data-[state=open]:animate-overlayShow z-50" />
55
+ <Dialog.Content className="fixed top-1/2 left-1/2 w-[90vw] max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-6 shadow-xl focus:outline-none data-[state=open]:animate-contentShow z-[100]">
56
+ <Dialog.Title className="text-lg font-semibold text-gray-900 mb-3">Open EventCatalog Studio</Dialog.Title>
57
+
58
+ <Dialog.Description className="text-sm text-gray-600 mb-6">
59
+ Import your catalog resources into{' '}
60
+ <a
61
+ href="https://eventcatalog.studio"
62
+ className="text-gray-900 hover:text-gray-700 underline font-semibold"
63
+ target="_blank"
64
+ rel="noopener noreferrer"
65
+ >
66
+ EventCatalog Studio
67
+ </a>{' '}
68
+ to create architecture diagrams.
69
+ </Dialog.Description>
70
+
71
+ <div className="space-y-4">
72
+ {/* Step 1: Copy Resources */}
73
+ <div className="bg-gray-50 rounded-lg p-4 border border-gray-200">
74
+ <h4 className="text-sm font-bold text-gray-900 mb-2">Step 1: Copy your resources</h4>
75
+ <p className="text-xs text-gray-600 mb-3">Copy your EventCatalog resources to your clipboard.</p>
76
+
77
+ <button
78
+ onClick={handleCopyResources}
79
+ disabled={isLoading}
80
+ className={`w-full flex items-center justify-center space-x-2 px-4 py-2 text-sm font-medium rounded-md border transition-colors ${
81
+ copySuccess
82
+ ? 'bg-green-50 border-green-200 text-green-700'
83
+ : isLoading
84
+ ? 'bg-gray-100 border-gray-300 text-gray-400 cursor-not-allowed'
85
+ : 'bg-white border-gray-300 text-gray-700 hover:bg-gray-50'
86
+ }`}
87
+ >
88
+ {isLoading ? (
89
+ <>
90
+ <Loader2 className="w-4 h-4 animate-spin" />
91
+ <span>Loading resources...</span>
92
+ </>
93
+ ) : copySuccess ? (
94
+ <>
95
+ <CheckIcon className="w-4 h-4" />
96
+ <span>Copied!</span>
97
+ </>
98
+ ) : (
99
+ <>
100
+ <ClipboardIcon className="w-4 h-4" />
101
+ <span>Copy resources to clipboard</span>
102
+ </>
103
+ )}
104
+ </button>
105
+
106
+ {error && <p className="text-xs text-red-600 mt-2">{error}</p>}
107
+ </div>
108
+
109
+ {/* Step 2: Open Studio */}
110
+ <div className="bg-gray-50 rounded-lg p-4 border border-gray-200">
111
+ <h4 className="text-sm font-bold text-gray-900 mb-2">Step 2: Open EventCatalog Studio</h4>
112
+ <p className="text-xs text-gray-600 mb-3">
113
+ Go to EventCatalog Studio and paste your resources into the modal dialog.
114
+ </p>
115
+
116
+ <button
117
+ onClick={handleOpenStudio}
118
+ disabled={!hasCopied}
119
+ className={`w-full flex items-center justify-center space-x-2 px-4 py-2 text-sm font-medium rounded-md transition-colors ${
120
+ hasCopied ? 'bg-gray-900 text-white hover:bg-gray-800' : 'bg-gray-300 text-gray-500 cursor-not-allowed'
121
+ }`}
122
+ >
123
+ <ExternalLinkIcon className="w-4 h-4" />
124
+ <span>Open EventCatalog Studio</span>
125
+ </button>
126
+
127
+ <p className="text-[12px] text-gray-500 italic mt-4 mb-0">
128
+ All data is stored locally in your browser. Nothing is sent to external servers.
129
+ </p>
130
+ </div>
131
+ </div>
132
+
133
+ <div className="mt-6 flex justify-end">
134
+ <Dialog.Close asChild>
135
+ <button
136
+ type="button"
137
+ className="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 transition-colors"
138
+ onClick={() => setIsOpen(false)}
139
+ >
140
+ Close
141
+ </button>
142
+ </Dialog.Close>
143
+ </div>
144
+ </Dialog.Content>
145
+ </Dialog.Portal>
146
+ </Dialog.Root>
147
+ );
148
+ };
149
+
150
+ export default StudioPageModal;
@@ -363,7 +363,7 @@ const badges = doc?.badges || [];
363
363
 
364
364
  if (window.eventcatalog.mermaid) {
365
365
  const { icons } = await import('@iconify-json/logos');
366
- const { iconPacks = [] } = window.eventcatalog.mermaid ?? {};
366
+ const { iconPacks = [], enableSupportForElkLayout = false } = window.eventcatalog.mermaid ?? {};
367
367
 
368
368
  if (iconPacks.length > 0) {
369
369
  const iconPacksToRegister = iconPacks.map((name: string) => {
@@ -375,6 +375,11 @@ const badges = doc?.badges || [];
375
375
 
376
376
  mermaid.registerIconPacks(iconPacksToRegister);
377
377
  }
378
+
379
+ if (enableSupportForElkLayout) {
380
+ const { default: elkLayouts } = await import('@mermaid-js/layout-elk/dist/mermaid-layout-elk.core.mjs');
381
+ mermaid.registerLayoutLoaders(elkLayouts);
382
+ }
378
383
  }
379
384
 
380
385
  mermaid.initialize({
@@ -16,6 +16,7 @@ import {
16
16
  Sparkles,
17
17
  Rocket,
18
18
  FileText,
19
+ SquareDashedMousePointerIcon,
19
20
  } from 'lucide-react';
20
21
  import Header from '../components/Header.astro';
21
22
  import SEO from '../components/Seo.astro';
@@ -35,6 +36,7 @@ import { isCollectionVisibleInCatalog } from '@eventcatalog';
35
36
  import { buildUrl } from '@utils/url-builder';
36
37
  import { getQueries } from '@utils/queries';
37
38
  import { hasLandingPageForDocs } from '@utils/pages';
39
+
38
40
  const events = await getEvents({ getAllVersions: false });
39
41
  const commands = await getCommands({ getAllVersions: false });
40
42
  const queries = await getQueries({ getAllVersions: false });
@@ -110,6 +112,7 @@ const navigationItems = [
110
112
  current: currentPath.includes('/visualiser'),
111
113
  sidebar: true,
112
114
  },
115
+
113
116
  {
114
117
  id: '/discover',
115
118
  label: 'Explore',
@@ -140,6 +143,15 @@ const navigationItems = [
140
143
  return userSideBarOption ? userSideBarOption.visible : true;
141
144
  });
142
145
 
146
+ const studioNavigationItem = {
147
+ id: '/studio',
148
+ label: 'EventCatalog Studio',
149
+ icon: SquareDashedMousePointerIcon,
150
+ href: buildUrl('/studio'),
151
+ current: currentPath.includes('/studio'),
152
+ sidebar: false,
153
+ };
154
+
143
155
  const premiumFeatures = [
144
156
  {
145
157
  id: '/docs/custom',
@@ -163,7 +175,7 @@ const premiumFeatures = [
163
175
  return userSideBarOption ? userSideBarOption.visible : true;
164
176
  });
165
177
 
166
- const currentNavigationItem = [...navigationItems, ...premiumFeatures].find((item) => item.current);
178
+ const currentNavigationItem = [...navigationItems, ...[studioNavigationItem], ...premiumFeatures].find((item) => item.current);
167
179
  const { title, description } = Astro.props;
168
180
 
169
181
  const showSideBarOnLoad = currentNavigationItem?.sidebar;
@@ -232,7 +244,7 @@ const canPageBeEmbedded = process.env.ENABLE_EMBED === 'true';
232
244
  class="fixed flex flex-col items-center w-16 h-screen py-4 bg-white bg-gradient-to-b from-white to-gray-100 border-r border-gray-200 z-20 shadow-md justify-between"
233
245
  >
234
246
  <nav class="flex flex-col h-[calc(100vh-70px)] justify-between">
235
- <div class="flex flex-col items-center flex-1 space-y-8">
247
+ <div class="flex flex-col items-center flex-1 space-y-6">
236
248
  {
237
249
  navigationItems
238
250
  .filter((item) => !item.hidden)
@@ -261,6 +273,24 @@ const canPageBeEmbedded = process.env.ENABLE_EMBED === 'true';
261
273
 
262
274
  <hr class="w-8 border-t border-gray-200" />
263
275
 
276
+ <a
277
+ id={studioNavigationItem.id}
278
+ data-role="nav-item"
279
+ href={studioNavigationItem.href}
280
+ class={`p-1.5 inline-block pt-1 pb-1 mt-0 mb-0 transition-colors duration-200 rounded-lg relative ${studioNavigationItem.current ? 'text-white bg-gradient-to-b from-purple-500 to-purple-700' : 'hover:bg-gradient-to-r hover:from-purple-500 hover:to-purple-700 hover:text-white text-gray-700'}`}
281
+ >
282
+ <div class="has-tooltip">
283
+ <span
284
+ class="tooltip rounded shadow-lg p-1 text-xs bg-gradient-to-l from-purple-500 to-purple-700 text-white ml-10"
285
+ >
286
+ {studioNavigationItem.label}
287
+ </span>
288
+ <studioNavigationItem.icon className="h-6 w-6" />
289
+ </div>
290
+ </a>
291
+
292
+ <hr class="w-8 border-t border-gray-200" />
293
+
264
294
  {
265
295
  premiumFeatures.map((item) => (
266
296
  <a
@@ -534,7 +534,7 @@ nodeGraphs.push({
534
534
 
535
535
  if (window.eventcatalog.mermaid) {
536
536
  const { icons } = await import('@iconify-json/logos');
537
- const { iconPacks = [] } = window.eventcatalog.mermaid ?? {};
537
+ const { iconPacks = [], enableSupportForElkLayout = false } = window.eventcatalog.mermaid ?? {};
538
538
 
539
539
  if (iconPacks.length > 0) {
540
540
  const iconPacksToRegister = iconPacks.map((name: any) => {
@@ -546,6 +546,11 @@ nodeGraphs.push({
546
546
 
547
547
  mermaid.registerIconPacks(iconPacksToRegister);
548
548
  }
549
+
550
+ if (enableSupportForElkLayout) {
551
+ const { default: elkLayouts } = await import('@mermaid-js/layout-elk/dist/mermaid-layout-elk.core.mjs');
552
+ mermaid.registerLayoutLoaders(elkLayouts);
553
+ }
549
554
  }
550
555
 
551
556
  mermaid.initialize({
@@ -0,0 +1,234 @@
1
+ ---
2
+ import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
3
+ import { getEvents } from '@utils/events';
4
+ import { getCommands } from '@utils/commands';
5
+ import { getServices } from '@utils/collections/services';
6
+ import { BoltIcon, ServerIcon, RectangleGroupIcon } from '@heroicons/react/24/outline';
7
+ import { SquareDashedMousePointerIcon, ArrowLeftRightIcon } from 'lucide-react';
8
+ import StudioPageModal from '@components/Studio/StudioPageModal';
9
+ import { getChannels } from '@utils/channels';
10
+
11
+ const [events, commands, services, channels] = await Promise.all([
12
+ getEvents().catch(() => []),
13
+ getCommands().catch(() => []),
14
+ getServices().catch(() => []),
15
+ getChannels().catch(() => []),
16
+ ]);
17
+
18
+ // Get counts
19
+ const eventCount = events.length;
20
+ const serviceCount = services.length;
21
+ const commandCount = commands.length;
22
+ const channelCount = channels.length;
23
+
24
+ // Get a few sample resources to display
25
+ const sampleEvents = events.slice(0, 2);
26
+ const sampleServices = services.slice(0, 2);
27
+ const sampleChannels = channels.slice(0, 1);
28
+
29
+ // Determine which resources to show (fallback if some are missing)
30
+ const resourcesToShow = [
31
+ ...sampleEvents.map((event, index) => ({ type: 'event', data: event, index })),
32
+ ...sampleServices.map((service, index) => ({ type: 'service', data: service, index: index + 2 })),
33
+ ...sampleChannels.map((channel, index) => ({ type: 'channel', data: channel, index: index + 4 })),
34
+ ].slice(0, 5); // Max 5 resources
35
+ ---
36
+
37
+ <!doctype html>
38
+ <html lang="en">
39
+ <head>
40
+ <meta charset="UTF-8" />
41
+ <meta name="viewport" content="width=device-width" />
42
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
43
+ <meta name="generator" content={Astro.generator} />
44
+ <title>EventCatalog Studio</title>
45
+ </head>
46
+ <body>
47
+ <VerticalSideBarLayout title="EventCatalog Studio">
48
+ <div class="min-h-[calc(100vh-60px)] bg-white">
49
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
50
+ {/* Hero Section */}
51
+ <div class="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center mb-16">
52
+ <div>
53
+ <div class="inline-flex items-center px-4 py-2 rounded-full bg-gray-100 text-gray-900 font-medium text-sm mb-6">
54
+ <SquareDashedMousePointerIcon className="w-4 h-4 mr-2" />
55
+ EventCatalog Studio
56
+ </div>
57
+ <h1 class="text-4xl font-bold text-gray-900 tracking-tight mb-4">Turn your resources into designs</h1>
58
+ <p class="text-xl text-gray-600 mb-8">
59
+ Transform your documented messages, services, and domains into architecture diagrams. Drag, drop, and design with
60
+ what you already have.
61
+ </p>
62
+ <div class="flex flex-col sm:flex-row gap-4 mb-2">
63
+ <button
64
+ id="design-button"
65
+ class="inline-flex items-center justify-center px-6 py-3 border border-transparent text-base font-medium rounded-lg text-white bg-gray-900 hover:bg-gray-800 transition-colors duration-150"
66
+ >
67
+ <SquareDashedMousePointerIcon className="w-4 h-4 mr-2" />
68
+ Open EventCatalog Studio
69
+ </button>
70
+ </div>
71
+
72
+ <p class="text-sm text-gray-500 italic mb-6">
73
+ {eventCount + serviceCount + channelCount + commandCount} resources ready to design with
74
+ </p>
75
+ </div>
76
+
77
+ <div class="relative">
78
+ <div class="relative">
79
+ {/* Animation container */}
80
+ <div class="relative h-[400px] flex items-center justify-center">
81
+ {/* Resource cards that animate in */}
82
+ <div class="absolute left-0 top-1/2 -translate-y-1/2 space-y-3">
83
+ {
84
+ resourcesToShow.map((resource) => {
85
+ if (resource.type === 'event') {
86
+ return (
87
+ <div
88
+ class="animate-float-in flex items-center gap-2 text-sm text-gray-700 px-4 py-3 bg-orange-50 rounded-lg border border-orange-200 shadow-sm"
89
+ style={`animation-delay: ${resource.index * 0.4}s;`}
90
+ >
91
+ <BoltIcon className="w-4 h-4 text-orange-600" />
92
+ {resource.data.data.name}
93
+ </div>
94
+ );
95
+ } else if (resource.type === 'service') {
96
+ return (
97
+ <div
98
+ class="animate-float-in flex items-center gap-2 text-sm text-gray-700 px-4 py-3 bg-pink-50 rounded-lg border border-pink-200 shadow-sm"
99
+ style={`animation-delay: ${resource.index * 0.4}s;`}
100
+ >
101
+ <ServerIcon className="w-4 h-4 text-gray-600" />
102
+ {resource.data.data.name}
103
+ </div>
104
+ );
105
+ } else if (resource.type === 'channel') {
106
+ return (
107
+ <div
108
+ class="animate-float-in flex items-center gap-2 text-sm text-gray-700 px-4 py-3 bg-gray-50 rounded-lg border border-gray-200 shadow-sm"
109
+ style={`animation-delay: ${resource.index * 0.4}s;`}
110
+ >
111
+ <ArrowLeftRightIcon className="w-4 h-4 text-gray-600" />
112
+ {resource.data.data.name}
113
+ </div>
114
+ );
115
+ }
116
+ })
117
+ }
118
+ </div>
119
+
120
+ {/* Arrow indicator */}
121
+ <div class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 animate-pulse">
122
+ <svg class="w-12 h-12 text-gray-400" viewBox="0 0 24 24" fill="none" stroke="currentColor">
123
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7l5 5m0 0l-5 5m5-5H6"></path>
124
+ </svg>
125
+ </div>
126
+
127
+ {/* Design preview */}
128
+ <div class="absolute right-0 top-1/2 -translate-y-1/2 animate-fade-in-scale" style="animation-delay: 2s;">
129
+ <img
130
+ src="/studio-bg.png"
131
+ alt="Studio Design Preview"
132
+ class="rounded-xl shadow-xl border border-gray-200 w-64 h-auto"
133
+ />
134
+ </div>
135
+ </div>
136
+ </div>
137
+ </div>
138
+ </div>
139
+
140
+ {/* Features Section */}
141
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-8">
142
+ <div class="bg-white rounded-xl p-6 shadow-sm border border-gray-200">
143
+ <div class="w-12 h-12 bg-gray-100 rounded-lg flex items-center justify-center mb-4">
144
+ <svg class="w-6 h-6 text-gray-900" viewBox="0 0 24 24" fill="none" stroke="currentColor">
145
+ <rect width="8" height="8" x="3" y="3" rx="2"></rect>
146
+ <path d="M7 11v4a2 2 0 0 0 2 2h4"></path>
147
+ <rect width="8" height="8" x="13" y="13" rx="2"></rect>
148
+ </svg>
149
+ </div>
150
+ <h3 class="text-lg font-semibold text-gray-900 mb-2">Real Resources</h3>
151
+ <p class="text-gray-600">
152
+ Drag and drop messages, services, and domains from your catalog. No more copying names or keeping things manually
153
+ in sync.
154
+ </p>
155
+ </div>
156
+
157
+ <div class="bg-white rounded-xl p-6 shadow-sm border border-gray-200">
158
+ <div class="w-12 h-12 bg-gray-100 rounded-lg flex items-center justify-center mb-4">
159
+ <svg class="w-6 h-6 text-gray-900" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
160
+ <path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"></path>
161
+ <polyline points="17 21 17 13 7 13 7 21"></polyline>
162
+ <polyline points="7 3 7 8 15 8"></polyline>
163
+ </svg>
164
+ </div>
165
+ <h3 class="text-lg font-semibold text-gray-900 mb-2">Save & Version</h3>
166
+ <p class="text-gray-600">Save designs locally and store in Git. All designs and data is owned by you.</p>
167
+ </div>
168
+
169
+ <div class="bg-white rounded-xl p-6 shadow-sm border border-gray-200">
170
+ <div class="w-12 h-12 bg-gray-100 rounded-lg flex items-center justify-center mb-4">
171
+ <svg class="w-6 h-6 text-gray-900" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
172
+ <polyline points="16 18 22 12 16 6"></polyline>
173
+ <polyline points="8 6 2 12 8 18"></polyline>
174
+ </svg>
175
+ </div>
176
+ <h3 class="text-lg font-semibold text-gray-900 mb-2">Embed Anywhere</h3>
177
+ <p class="text-gray-600">
178
+ Drop diagrams directly into documentation pages. One source of truth for your architecture.
179
+ </p>
180
+ </div>
181
+ </div>
182
+ </div>
183
+ </div>
184
+
185
+ {/* Studio Modal */}
186
+ <StudioPageModal client:only="react" />
187
+ </VerticalSideBarLayout>
188
+
189
+ <script>
190
+ // Handle opening the studio modal
191
+ const button = document.getElementById('design-button');
192
+ if (button) {
193
+ button.addEventListener('click', () => {
194
+ // Trigger the modal to open
195
+ window.dispatchEvent(new CustomEvent('openStudioModal'));
196
+ });
197
+ }
198
+ </script>
199
+
200
+ <style>
201
+ @keyframes float-in {
202
+ 0% {
203
+ opacity: 0;
204
+ transform: translateX(-30px);
205
+ }
206
+ 100% {
207
+ opacity: 1;
208
+ transform: translateX(0);
209
+ }
210
+ }
211
+
212
+ @keyframes fade-in-scale {
213
+ 0% {
214
+ opacity: 0;
215
+ transform: translateY(-50%) scale(0.9);
216
+ }
217
+ 100% {
218
+ opacity: 1;
219
+ transform: translateY(-50%) scale(1);
220
+ }
221
+ }
222
+
223
+ .animate-float-in {
224
+ animation: float-in 0.6s ease-out forwards;
225
+ opacity: 0;
226
+ }
227
+
228
+ .animate-fade-in-scale {
229
+ animation: fade-in-scale 0.8s ease-out forwards;
230
+ opacity: 0;
231
+ }
232
+ </style>
233
+ </body>
234
+ </html>
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "https://github.com/event-catalog/eventcatalog.git"
7
7
  },
8
8
  "type": "module",
9
- "version": "2.61.3",
9
+ "version": "2.61.5",
10
10
  "publishConfig": {
11
11
  "access": "public"
12
12
  },
@@ -45,6 +45,7 @@
45
45
  "@headlessui/react": "^2.0.3",
46
46
  "@heroicons/react": "^2.1.3",
47
47
  "@iconify-json/logos": "^1.2.4",
48
+ "@mermaid-js/layout-elk": "^0.2.0",
48
49
  "@parcel/watcher": "^2.4.1",
49
50
  "@radix-ui/react-context-menu": "^2.2.6",
50
51
  "@radix-ui/react-dialog": "^1.1.6",