@eventcatalog/core 4.3.3 → 4.3.4

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.
@@ -36,7 +36,7 @@ module.exports = __toCommonJS(analytics_exports);
36
36
  var import_os = __toESM(require("os"), 1);
37
37
 
38
38
  // package.json
39
- var version = "4.3.3";
39
+ var version = "4.3.4";
40
40
 
41
41
  // src/constants.ts
42
42
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "../chunk-UW52WRSH.js";
4
- import "../chunk-PXBG5QKU.js";
3
+ } from "../chunk-5L4FYIAY.js";
4
+ import "../chunk-OPFRJOPV.js";
5
5
  export {
6
6
  raiseEvent
7
7
  };
@@ -140,7 +140,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
140
140
  var import_os = __toESM(require("os"), 1);
141
141
 
142
142
  // package.json
143
- var version = "4.3.3";
143
+ var version = "4.3.4";
144
144
 
145
145
  // src/constants.ts
146
146
  var VERSION = version;
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  log_build_default
3
- } from "../chunk-OWE74ZHY.js";
4
- import "../chunk-UW52WRSH.js";
3
+ } from "../chunk-QFXV3GDK.js";
5
4
  import "../chunk-K2XIENVT.js";
6
- import "../chunk-PXBG5QKU.js";
5
+ import "../chunk-5L4FYIAY.js";
6
+ import "../chunk-OPFRJOPV.js";
7
7
  import "../chunk-6QENHZZP.js";
8
8
  export {
9
9
  log_build_default as default
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-PXBG5QKU.js";
3
+ } from "./chunk-OPFRJOPV.js";
4
4
 
5
5
  // src/analytics/analytics.js
6
6
  import os from "os";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-PXBG5QKU.js";
3
+ } from "./chunk-OPFRJOPV.js";
4
4
 
5
5
  // src/utils/cli-logger.ts
6
6
  import pc from "picocolors";
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "4.3.3";
2
+ var version = "4.3.4";
3
3
 
4
4
  // src/constants.ts
5
5
  var VERSION = version;
@@ -1,10 +1,10 @@
1
- import {
2
- raiseEvent
3
- } from "./chunk-UW52WRSH.js";
4
1
  import {
5
2
  countResources,
6
3
  serializeCounts
7
4
  } from "./chunk-K2XIENVT.js";
5
+ import {
6
+ raiseEvent
7
+ } from "./chunk-5L4FYIAY.js";
8
8
  import {
9
9
  getEventCatalogConfigFile,
10
10
  verifyRequiredFieldsAreInCatalogConfigFile
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  logger
3
- } from "./chunk-2IGBU3PN.js";
3
+ } from "./chunk-CQQE7NTL.js";
4
4
  import {
5
5
  cleanup,
6
6
  getEventCatalogConfigFile
@@ -25,7 +25,7 @@ __export(constants_exports, {
25
25
  module.exports = __toCommonJS(constants_exports);
26
26
 
27
27
  // package.json
28
- var version = "4.3.3";
28
+ var version = "4.3.4";
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-PXBG5QKU.js";
3
+ } from "./chunk-OPFRJOPV.js";
4
4
  export {
5
5
  VERSION
6
6
  };
@@ -144,7 +144,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
144
144
  var import_picocolors = __toESM(require("picocolors"), 1);
145
145
 
146
146
  // package.json
147
- var version = "4.3.3";
147
+ var version = "4.3.4";
148
148
 
149
149
  // src/constants.ts
150
150
  var VERSION = version;
@@ -1,8 +1,11 @@
1
1
  import {
2
2
  log_build_default
3
- } from "./chunk-OWE74ZHY.js";
4
- import "./chunk-UW52WRSH.js";
3
+ } from "./chunk-QFXV3GDK.js";
5
4
  import "./chunk-K2XIENVT.js";
5
+ import {
6
+ runMigrations
7
+ } from "./chunk-XUAF2H54.js";
8
+ import "./chunk-CA4U2JP7.js";
6
9
  import {
7
10
  getProjectOutDir,
8
11
  isAuthEnabled,
@@ -11,10 +14,10 @@ import {
11
14
  } from "./chunk-B7HCX5HM.js";
12
15
  import {
13
16
  generate
14
- } from "./chunk-HR6KK56F.js";
17
+ } from "./chunk-XTC5VFLE.js";
15
18
  import {
16
19
  logger
17
- } from "./chunk-2IGBU3PN.js";
20
+ } from "./chunk-CQQE7NTL.js";
18
21
  import {
19
22
  resolve_catalog_dependencies_default
20
23
  } from "./chunk-LHR4G2UO.js";
@@ -24,10 +27,7 @@ import {
24
27
  import {
25
28
  watch
26
29
  } from "./chunk-CAJUIMDJ.js";
27
- import {
28
- runMigrations
29
- } from "./chunk-XUAF2H54.js";
30
- import "./chunk-CA4U2JP7.js";
30
+ import "./chunk-5L4FYIAY.js";
31
31
  import {
32
32
  createAstroDevLineFilter,
33
33
  createAstroLineFilter
@@ -38,7 +38,7 @@ import {
38
38
  import "./chunk-W5JQON7Z.js";
39
39
  import {
40
40
  VERSION
41
- } from "./chunk-PXBG5QKU.js";
41
+ } from "./chunk-OPFRJOPV.js";
42
42
  import {
43
43
  linkCoreNodeModules,
44
44
  resolveInstalledCoreNodeModules
package/dist/generate.cjs CHANGED
@@ -108,7 +108,7 @@ var getEventCatalogConfigFile = async (projectDirectory) => {
108
108
  var import_picocolors = __toESM(require("picocolors"), 1);
109
109
 
110
110
  // package.json
111
- var version = "4.3.3";
111
+ var version = "4.3.4";
112
112
 
113
113
  // src/constants.ts
114
114
  var VERSION = version;
package/dist/generate.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  generate
3
- } from "./chunk-HR6KK56F.js";
4
- import "./chunk-2IGBU3PN.js";
5
- import "./chunk-PXBG5QKU.js";
3
+ } from "./chunk-XTC5VFLE.js";
4
+ import "./chunk-CQQE7NTL.js";
5
+ import "./chunk-OPFRJOPV.js";
6
6
  import "./chunk-6QENHZZP.js";
7
7
  export {
8
8
  generate
@@ -36,7 +36,7 @@ module.exports = __toCommonJS(cli_logger_exports);
36
36
  var import_picocolors = __toESM(require("picocolors"), 1);
37
37
 
38
38
  // package.json
39
- var version = "4.3.3";
39
+ var version = "4.3.4";
40
40
 
41
41
  // src/constants.ts
42
42
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  logger
3
- } from "../chunk-2IGBU3PN.js";
4
- import "../chunk-PXBG5QKU.js";
3
+ } from "../chunk-CQQE7NTL.js";
4
+ import "../chunk-OPFRJOPV.js";
5
5
  export {
6
6
  logger
7
7
  };
@@ -13,7 +13,7 @@ import {
13
13
  removeFavorite as removeFavoriteAction,
14
14
  type FavoriteItem,
15
15
  } from '@stores/favorites-store';
16
- import { getBadgeClasses, isGroupCollapsed } from './utils';
16
+ import { canCollapseGroup, getBadgeClasses, getGroupLabel, isGroupCollapsed } from './utils';
17
17
  import { resolveIconUrl } from '@utils/icon';
18
18
 
19
19
  const cn = (...classes: (string | false | undefined)[]) => classes.filter(Boolean).join(' ');
@@ -57,7 +57,7 @@ export default function NestedSideBar() {
57
57
  const [slideDirection, setSlideDirection] = useState<'forward' | 'backward' | null>(null);
58
58
  const [isInitialized, setIsInitialized] = useState(false);
59
59
  const [currentPath, setCurrentPath] = useState<string>('');
60
- const [collapsedSections, setCollapsedSections] = useState<Set<string>>(new Set());
60
+ const [sectionCollapsePreferences, setSectionCollapsePreferences] = useState(loadCollapsedSections);
61
61
  const [showPathPreview, setShowPathPreview] = useState(false);
62
62
  const [showFullPath, setShowFullPath] = useState(false);
63
63
 
@@ -95,29 +95,23 @@ export default function NestedSideBar() {
95
95
  * Toggle section collapse state
96
96
  */
97
97
  const toggleSectionCollapse = (sectionId: string) => {
98
- setCollapsedSections((prev) => {
99
- const next = new Set(prev);
100
- if (next.has(sectionId)) {
101
- next.delete(sectionId);
98
+ setSectionCollapsePreferences((previousPreferences) => {
99
+ const nextPreferences = {
100
+ expanded: new Set(previousPreferences.expanded),
101
+ };
102
+ const isCurrentlyCollapsed = isGroupCollapsed(true, sectionId, previousPreferences);
103
+
104
+ if (isCurrentlyCollapsed) {
105
+ nextPreferences.expanded.add(sectionId);
102
106
  } else {
103
- next.add(sectionId);
107
+ nextPreferences.expanded.delete(sectionId);
104
108
  }
105
- // Save to localStorage
106
- saveCollapsedSections(next);
107
- return next;
109
+
110
+ saveCollapsedSections(nextPreferences);
111
+ return nextPreferences;
108
112
  });
109
113
  };
110
114
 
111
- /**
112
- * Load collapsed sections from localStorage on mount
113
- */
114
- useEffect(() => {
115
- const saved = loadCollapsedSections();
116
- if (saved.size > 0) {
117
- setCollapsedSections(saved);
118
- }
119
- }, []);
120
-
121
115
  /**
122
116
  * Update navigation stack when roots become available
123
117
  */
@@ -521,7 +515,7 @@ export default function NestedSideBar() {
521
515
  // Show loading state if no data yet
522
516
  if (!data || roots.length === 0) {
523
517
  return (
524
- <aside className="w-full min-h-full flex-1 flex flex-col font-sans bg-[rgb(var(--ec-rail-bg))]">
518
+ <aside className="flex h-full min-h-0 w-full flex-1 flex-col bg-[rgb(var(--ec-rail-bg))] font-sans">
525
519
  {/* Search skeleton */}
526
520
  <div className="px-4 py-3 border-b border-[rgb(var(--ec-content-border))] bg-[rgb(var(--ec-rail-bg))]">
527
521
  <div className="h-10 bg-[rgb(var(--ec-content-hover))] rounded-xl animate-pulse" />
@@ -754,9 +748,9 @@ export default function NestedSideBar() {
754
748
  return child && isVisible(child);
755
749
  }) ?? [];
756
750
 
757
- const groupId = groupKey || group.collapseKey || `group-${index}`;
758
- const canCollapse = visibleChildren.length > 3;
759
- const isCollapsed = isGroupCollapsed(canCollapse, groupId, collapsedSections);
751
+ const groupId = groupKey || group.collapseKey || `${currentLevel.key ?? 'root'}:group:${group.title}`;
752
+ const canCollapse = canCollapseGroup(visibleChildren.length);
753
+ const isCollapsed = isGroupCollapsed(canCollapse, groupId, sectionCollapsePreferences);
760
754
 
761
755
  // When a group's children are subtle subgroups (e.g. Resources > Services/Flows/Data Stores),
762
756
  // they render flush under the parent icon instead of inside the indented border guide.
@@ -787,7 +781,7 @@ export default function NestedSideBar() {
787
781
  : 'text-[12px] font-semibold tracking-tight text-[rgb(var(--ec-content-text))]'
788
782
  )}
789
783
  >
790
- {group.title}
784
+ {getGroupLabel(group.title, visibleChildren.length)}
791
785
  </span>
792
786
  </div>
793
787
  {canCollapse && (
@@ -973,7 +967,7 @@ export default function NestedSideBar() {
973
967
  };
974
968
 
975
969
  return (
976
- <aside className="w-full min-h-full flex-1 flex flex-col font-sans bg-[rgb(var(--ec-rail-bg))]">
970
+ <aside className="flex h-full min-h-0 w-full flex-1 flex-col bg-[rgb(var(--ec-rail-bg))] font-sans">
977
971
  {isTopLevel && (
978
972
  <div className="flex h-[60px] items-center px-6 bg-[rgb(var(--ec-rail-bg)/0.98)] backdrop-blur-sm border-b border-[rgb(var(--ec-content-border))] sticky top-0 z-10">
979
973
  <span className="text-[0.65rem] font-semibold uppercase tracking-[0.18em] text-[rgb(var(--ec-sidebar-text)/0.5)] truncate">
@@ -1128,7 +1122,7 @@ export default function NestedSideBar() {
1128
1122
  {/* Navigation Content */}
1129
1123
  <nav
1130
1124
  key={animationKey}
1131
- className={cn('flex-1 overflow-y-auto overflow-x-hidden p-4 px-2', getAnimationClass())}
1125
+ className={cn('min-h-0 flex-1 overflow-y-auto overflow-x-hidden p-4 px-2', getAnimationClass())}
1132
1126
  style={{
1133
1127
  scrollbarWidth: 'thin',
1134
1128
  scrollbarColor: 'rgb(var(--ec-content-border)) transparent',
@@ -1,9 +1,11 @@
1
+ import type { SectionCollapsePreferences } from './utils';
2
+
1
3
  // ============================================
2
4
  // Local Storage Persistence
3
5
  // ============================================
4
6
 
5
7
  const STORAGE_KEY = 'eventcatalog-sidebar-nav';
6
- const COLLAPSED_SECTIONS_KEY = 'eventcatalog-sidebar-collapsed';
8
+ const SECTION_PREFERENCES_KEY = 'eventcatalog-sidebar-sections:v2';
7
9
  const FAVORITES_KEY = 'eventcatalog-sidebar-favorites';
8
10
 
9
11
  // ============================================
@@ -49,21 +51,28 @@ export const loadState = (): PersistedState | null => {
49
51
  // Collapsed Sections
50
52
  // ============================================
51
53
 
52
- export const saveCollapsedSections = (sections: Set<string>): void => {
54
+ export const saveCollapsedSections = (preferences: SectionCollapsePreferences): void => {
53
55
  try {
54
- localStorage.setItem(COLLAPSED_SECTIONS_KEY, JSON.stringify([...sections]));
56
+ localStorage.setItem(SECTION_PREFERENCES_KEY, JSON.stringify({ expanded: [...preferences.expanded] }));
55
57
  } catch (e) {
56
58
  console.warn('Failed to save collapsed sections:', e);
57
59
  }
58
60
  };
59
61
 
60
- export const loadCollapsedSections = (): Set<string> => {
62
+ export const loadCollapsedSections = (): SectionCollapsePreferences => {
61
63
  try {
62
- const stored = localStorage.getItem(COLLAPSED_SECTIONS_KEY);
63
- return stored ? new Set(JSON.parse(stored)) : new Set();
64
+ const stored = localStorage.getItem(SECTION_PREFERENCES_KEY);
65
+ if (stored) {
66
+ const preferences = JSON.parse(stored);
67
+ return {
68
+ expanded: new Set(Array.isArray(preferences.expanded) ? preferences.expanded : []),
69
+ };
70
+ }
71
+
72
+ return { expanded: new Set() };
64
73
  } catch (e) {
65
74
  console.warn('Failed to load collapsed sections:', e);
66
- return new Set();
75
+ return { expanded: new Set() };
67
76
  }
68
77
  };
69
78
 
@@ -1,12 +1,35 @@
1
1
  import { describe, expect, it } from 'vitest';
2
- import { isGroupCollapsed } from './utils';
2
+ import { canCollapseGroup, getGroupLabel, isGroupCollapsed } from './utils';
3
+
4
+ const preferences = (expanded: string[] = []) => ({
5
+ expanded: new Set(expanded),
6
+ });
7
+
8
+ describe('sidebar group presentation', () => {
9
+ it('includes the visible child count in the group label', () => {
10
+ expect(getGroupLabel('Outbound Messages', 10)).toBe('Outbound Messages (10)');
11
+ });
12
+
13
+ it.each(['Quick Reference', 'Architecture', 'Resources'])('does not include the child count for %s', (title) => {
14
+ expect(getGroupLabel(title, 10)).toBe(title);
15
+ });
16
+
17
+ it('only allows groups with more than five children to collapse', () => {
18
+ expect(canCollapseGroup(5)).toBe(false);
19
+ expect(canCollapseGroup(6)).toBe(true);
20
+ });
21
+ });
3
22
 
4
23
  describe('isGroupCollapsed', () => {
5
- it('ignores persisted collapse state when the group cannot be expanded', () => {
6
- expect(isGroupCollapsed(false, 'group-1', new Set(['group-1']))).toBe(false);
24
+ it('keeps groups without a caret expanded', () => {
25
+ expect(isGroupCollapsed(false, 'group-1', preferences())).toBe(false);
26
+ });
27
+
28
+ it('collapses expandable groups by default', () => {
29
+ expect(isGroupCollapsed(true, 'outbound-messages', preferences())).toBe(true);
7
30
  });
8
31
 
9
- it('uses persisted collapse state when the group can be expanded', () => {
10
- expect(isGroupCollapsed(true, 'adrs:status:superseded', new Set(['adrs:status:superseded']))).toBe(true);
32
+ it('uses an explicit expanded preference', () => {
33
+ expect(isGroupCollapsed(true, 'outbound-messages', preferences(['outbound-messages']))).toBe(false);
11
34
  });
12
35
  });
@@ -1,7 +1,20 @@
1
1
  // Shared utilities for NestedSideBar components
2
2
 
3
- export const isGroupCollapsed = (canCollapse: boolean, groupId: string, collapsedSections: Set<string>): boolean =>
4
- canCollapse && collapsedSections.has(groupId);
3
+ export const SIDEBAR_GROUP_COLLAPSE_THRESHOLD = 5;
4
+ const GROUP_TITLES_WITHOUT_COUNT = new Set(['Quick Reference', 'Architecture', 'Resources']);
5
+
6
+ export type SectionCollapsePreferences = {
7
+ expanded: Set<string>;
8
+ };
9
+
10
+ export const canCollapseGroup = (childCount: number): boolean => childCount > SIDEBAR_GROUP_COLLAPSE_THRESHOLD;
11
+
12
+ export const getGroupLabel = (title: string, childCount: number): string =>
13
+ GROUP_TITLES_WITHOUT_COUNT.has(title) ? title : `${title} (${childCount})`;
14
+
15
+ export const isGroupCollapsed = (canCollapse: boolean, groupId: string, preferences: SectionCollapsePreferences): boolean => {
16
+ return canCollapse && !preferences.expanded.has(groupId);
17
+ };
5
18
 
6
19
  /**
7
20
  * Returns Tailwind classes for badge styling based on badge type.
@@ -93,18 +93,15 @@ const editUrl =
93
93
  (config.editUrl && (props as any)?.filePath ? buildEditUrlForResource(config.editUrl, (props as any).filePath) : '');
94
94
  ---
95
95
 
96
- <VerticalSideBarLayout title={doc.title || 'Documentation'} showNestedSideBar={false}>
96
+ <VerticalSideBarLayout title={doc.title || 'Documentation'}>
97
+ <Fragment slot="sidebar-content">
98
+ <div class="h-full min-h-0">
99
+ <CustomDocsNav />
100
+ </div>
101
+ </Fragment>
102
+
97
103
  <div class="custom-docs-shell flex w-full" data-pagefind-body data-pagefind-meta={`title:${doc.title}`}>
98
- <!-- Left Sidebar Navigation -->
99
- <aside
100
- class="sidebar-transition fixed top-0 bottom-0 left-[var(--ec-vertical-nav-width,14rem)] z-10 w-[var(--ec-custom-docs-sidebar-width,20rem)] overflow-hidden border-r border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-rail-bg))]"
101
- >
102
- <div class="h-full">
103
- <CustomDocsNav />
104
- </div>
105
- </aside>
106
-
107
- <div class="sidebar-transition flex w-full min-w-0" style="margin-left: var(--ec-custom-docs-sidebar-width, 20rem);">
104
+ <div class="flex w-full min-w-0">
108
105
  <main class="min-w-0 flex-1">
109
106
  <div
110
107
  class="w-full lg:mr-2 pr-10 py-10 bg-[rgb(var(--ec-page-bg))]"
@@ -275,19 +272,6 @@ const editUrl =
275
272
  </VerticalSideBarLayout>
276
273
 
277
274
  <style is:global>
278
- :root {
279
- --ec-custom-docs-sidebar-width: 20rem;
280
- }
281
-
282
- #eventcatalog-header {
283
- left: calc(var(--ec-vertical-nav-width, 14rem) + var(--ec-custom-docs-sidebar-width, 20rem)) !important;
284
- }
285
-
286
- .custom-docs-shell {
287
- margin-left: calc(var(--ec-app-content-padding-left, 5rem) * -1);
288
- margin-right: calc(var(--ec-app-content-padding-right, 5rem) * -1);
289
- }
290
-
291
275
  .mermaid svg {
292
276
  margin: 1em auto 2em;
293
277
  }
@@ -449,9 +449,25 @@ const verticalNavAutoCollapsePaths = [buildUrl('/discover', true), buildUrl('/do
449
449
  }
450
450
  })();
451
451
  </script>
452
+ <script is:inline>
453
+ (() => {
454
+ const sidebarWidthStorageKey = 'eventcatalog-sidebar-width:v1';
455
+ const minimumSidebarWidth = 224;
456
+ const maximumSidebarWidth = 576;
457
+
458
+ try {
459
+ const savedWidth = Number(localStorage.getItem(sidebarWidthStorageKey));
460
+ if (Number.isFinite(savedWidth) && savedWidth > 0) {
461
+ const width = Math.min(maximumSidebarWidth, Math.max(minimumSidebarWidth, savedWidth));
462
+ document.documentElement.style.setProperty('--ec-sidebar-panel-width', `${width}px`);
463
+ }
464
+ } catch (error) {}
465
+ })();
466
+ </script>
452
467
  <style is:global>
453
468
  :root {
454
469
  --ec-vertical-nav-width: 14rem;
470
+ --ec-sidebar-panel-width: 17rem;
455
471
  }
456
472
 
457
473
  :root[data-vertical-nav-collapsed='true'] {
@@ -472,7 +488,6 @@ const verticalNavAutoCollapsePaths = [buildUrl('/discover', true), buildUrl('/do
472
488
  min-height: 100vh;
473
489
  min-height: 100dvh;
474
490
  background-color: rgb(var(--ec-page-bg));
475
- --ec-sidebar-panel-width: 17rem;
476
491
  display: flex;
477
492
  flex-direction: column;
478
493
  }
@@ -580,7 +595,44 @@ const verticalNavAutoCollapsePaths = [buildUrl('/discover', true), buildUrl('/do
580
595
  top: 0;
581
596
  left: var(--ec-vertical-nav-width);
582
597
  z-index: 20;
583
- overflow-y: auto;
598
+ overflow: hidden;
599
+ }
600
+ .sidebar-resize-handle {
601
+ position: absolute;
602
+ top: 0;
603
+ right: 0;
604
+ z-index: 30;
605
+ width: 8px;
606
+ height: 100%;
607
+ cursor: col-resize;
608
+ touch-action: none;
609
+ }
610
+ .sidebar-resize-handle::after {
611
+ position: absolute;
612
+ top: 0;
613
+ bottom: 0;
614
+ left: 50%;
615
+ width: 2px;
616
+ content: '';
617
+ background: rgb(var(--ec-accent) / 0.65);
618
+ opacity: 0;
619
+ transform: translateX(-50%);
620
+ transition: opacity 150ms ease;
621
+ }
622
+ .sidebar-resize-handle:hover::after,
623
+ .sidebar-resize-handle:focus-visible::after,
624
+ body.sidebar-is-resizing .sidebar-resize-handle::after {
625
+ opacity: 1;
626
+ }
627
+ .sidebar-resize-handle:focus-visible {
628
+ outline: none;
629
+ }
630
+ body.sidebar-is-resizing {
631
+ cursor: col-resize;
632
+ user-select: none;
633
+ }
634
+ body.sidebar-is-resizing .sidebar-transition {
635
+ transition: none;
584
636
  }
585
637
  .content-panel {
586
638
  min-width: 0;
@@ -754,14 +806,22 @@ const verticalNavAutoCollapsePaths = [buildUrl('/discover', true), buildUrl('/do
754
806
  </div>
755
807
  </aside>
756
808
  {
757
- showNestedSideBar &&
758
- (Astro.slots.has('sidebar-content') ? (
759
- <aside id="sidebar" class="sidebar-panel sidebar-transition">
760
- <slot name="sidebar-content" />
761
- </aside>
762
- ) : (
763
- <SideNav id="sidebar" class={`sidebar-panel sidebar-transition`} />
764
- ))
809
+ showNestedSideBar && (
810
+ <aside id="sidebar" class="sidebar-panel sidebar-transition">
811
+ {Astro.slots.has('sidebar-content') ? <slot name="sidebar-content" /> : <SideNav class="h-full min-h-0" />}
812
+ <div
813
+ id="sidebar-resize-handle"
814
+ class="sidebar-resize-handle"
815
+ role="separator"
816
+ aria-label="Resize sidebar"
817
+ aria-orientation="vertical"
818
+ aria-valuemin="224"
819
+ aria-valuemax="576"
820
+ aria-valuenow="272"
821
+ tabindex="0"
822
+ />
823
+ </aside>
824
+ )
765
825
  }
766
826
  <main class="content-panel sidebar-transition w-full bg-[rgb(var(--ec-page-bg))]" id="content">
767
827
  {
@@ -803,6 +863,9 @@ const verticalNavAutoCollapsePaths = [buildUrl('/discover', true), buildUrl('/do
803
863
  }}
804
864
  >
805
865
  const VERTICAL_NAV_STORAGE_KEY = 'eventcatalog-vertical-nav-collapsed';
866
+ const SIDEBAR_WIDTH_STORAGE_KEY = 'eventcatalog-sidebar-width:v1';
867
+ const MINIMUM_SIDEBAR_WIDTH = 224;
868
+ const MAXIMUM_SIDEBAR_WIDTH = 576;
806
869
  const ACTIVE_NAV_CLASSES = [
807
870
  'border-[rgb(var(--ec-accent)/0.2)]',
808
871
  'bg-[rgb(var(--ec-page-bg)/0.88)]',
@@ -926,6 +989,80 @@ const verticalNavAutoCollapsePaths = [buildUrl('/discover', true), buildUrl('/do
926
989
  }
927
990
  };
928
991
 
992
+ const clampSidebarWidth = (width) => Math.min(MAXIMUM_SIDEBAR_WIDTH, Math.max(MINIMUM_SIDEBAR_WIDTH, width));
993
+
994
+ const applySidebarWidth = (width) => {
995
+ const nextWidth = clampSidebarWidth(width);
996
+ document.documentElement.style.setProperty('--ec-sidebar-panel-width', `${nextWidth}px`);
997
+
998
+ const resizeHandle = document.getElementById('sidebar-resize-handle');
999
+ resizeHandle?.setAttribute('aria-valuenow', String(Math.round(nextWidth)));
1000
+ return nextWidth;
1001
+ };
1002
+
1003
+ const persistSidebarWidth = (width) => {
1004
+ try {
1005
+ localStorage.setItem(SIDEBAR_WIDTH_STORAGE_KEY, String(Math.round(width)));
1006
+ } catch (error) {}
1007
+ };
1008
+
1009
+ const getPersistedSidebarWidth = () => {
1010
+ try {
1011
+ const savedWidth = Number(localStorage.getItem(SIDEBAR_WIDTH_STORAGE_KEY));
1012
+ return Number.isFinite(savedWidth) && savedWidth > 0 ? clampSidebarWidth(savedWidth) : null;
1013
+ } catch (error) {
1014
+ return null;
1015
+ }
1016
+ };
1017
+
1018
+ const setupSidebarResize = () => {
1019
+ const sidebar = document.getElementById('sidebar');
1020
+ const resizeHandle = document.getElementById('sidebar-resize-handle');
1021
+ if (!sidebar || !resizeHandle) return;
1022
+
1023
+ const persistedWidth = getPersistedSidebarWidth();
1024
+ const currentWidth = persistedWidth ?? sidebar.getBoundingClientRect().width;
1025
+ applySidebarWidth(currentWidth);
1026
+
1027
+ resizeHandle.onpointerdown = (event) => {
1028
+ if (event.button !== 0) return;
1029
+
1030
+ const startX = event.clientX;
1031
+ const startWidth = sidebar.getBoundingClientRect().width;
1032
+ document.body.classList.add('sidebar-is-resizing');
1033
+ resizeHandle.setPointerCapture(event.pointerId);
1034
+
1035
+ resizeHandle.onpointermove = (moveEvent) => {
1036
+ applySidebarWidth(startWidth + moveEvent.clientX - startX);
1037
+ };
1038
+
1039
+ const finishResize = (upEvent) => {
1040
+ const finalWidth = applySidebarWidth(startWidth + upEvent.clientX - startX);
1041
+ persistSidebarWidth(finalWidth);
1042
+ document.body.classList.remove('sidebar-is-resizing');
1043
+ if (resizeHandle.hasPointerCapture(upEvent.pointerId)) {
1044
+ resizeHandle.releasePointerCapture(upEvent.pointerId);
1045
+ }
1046
+ resizeHandle.onpointermove = null;
1047
+ resizeHandle.onpointerup = null;
1048
+ resizeHandle.onpointercancel = null;
1049
+ };
1050
+
1051
+ resizeHandle.onpointerup = finishResize;
1052
+ resizeHandle.onpointercancel = finishResize;
1053
+ };
1054
+
1055
+ resizeHandle.onkeydown = (event) => {
1056
+ if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') return;
1057
+
1058
+ event.preventDefault();
1059
+ const direction = event.key === 'ArrowLeft' ? -1 : 1;
1060
+ const step = event.shiftKey ? 32 : 16;
1061
+ const nextWidth = applySidebarWidth(sidebar.getBoundingClientRect().width + direction * step);
1062
+ persistSidebarWidth(nextWidth);
1063
+ };
1064
+ };
1065
+
929
1066
  // Apply immediately when this script executes so transitions don't briefly re-open the rail.
930
1067
  applyPersistedVerticalNavState();
931
1068
 
@@ -1015,6 +1152,7 @@ const verticalNavAutoCollapsePaths = [buildUrl('/discover', true), buildUrl('/do
1015
1152
  }
1016
1153
 
1017
1154
  setVerticalNavCollapsedState(getPersistedVerticalNavCollapsedState());
1155
+ setupSidebarResize();
1018
1156
 
1019
1157
  syncNavItemStates();
1020
1158
 
@@ -68,7 +68,7 @@ const groupAdrsByStatus = (adrs: Adr[]): NavNode[] =>
68
68
 
69
69
  groups.push({
70
70
  type: 'group',
71
- title: `${formatAdrStatus(status)} (${adrsForStatus.length})`,
71
+ title: formatAdrStatus(status),
72
72
  collapseKey: `adrs:status:${status}`,
73
73
  subtle: true,
74
74
  pages: [...adrsForStatus].sort(byResourceName).map(getAdrNodeKey),
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "license": "SEE LICENSE IN LICENSE",
9
9
  "type": "module",
10
- "version": "4.3.3",
10
+ "version": "4.3.4",
11
11
  "publishConfig": {
12
12
  "access": "public"
13
13
  },
@@ -116,9 +116,9 @@
116
116
  "update-notifier": "^7.3.1",
117
117
  "uuid": "^10.0.0",
118
118
  "zod": "^4.3.6",
119
- "@eventcatalog/linter": "1.1.8",
120
119
  "@eventcatalog/sdk": "2.26.3",
121
- "@eventcatalog/visualiser": "^4.1.1"
120
+ "@eventcatalog/visualiser": "^4.1.1",
121
+ "@eventcatalog/linter": "1.1.8"
122
122
  },
123
123
  "devDependencies": {
124
124
  "@astrojs/check": "^0.9.9",