@eventcatalog/core 2.65.1 → 3.0.0-beta.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.
Files changed (123) hide show
  1. package/README.md +1 -1
  2. package/dist/analytics/analytics.cjs +1 -1
  3. package/dist/analytics/analytics.js +2 -2
  4. package/dist/analytics/log-build.cjs +1 -1
  5. package/dist/analytics/log-build.js +3 -3
  6. package/dist/{chunk-2TTD2MLE.js → chunk-JB4YT5JY.js} +1 -1
  7. package/dist/{chunk-BTS6L3KY.js → chunk-TQ4HZREX.js} +1 -1
  8. package/dist/{chunk-XB4SZX3I.js → chunk-X4W4YC3U.js} +1 -1
  9. package/dist/constants.cjs +1 -1
  10. package/dist/constants.js +1 -1
  11. package/dist/eventcatalog.cjs +1 -21
  12. package/dist/eventcatalog.config.d.cts +9 -0
  13. package/dist/eventcatalog.config.d.ts +9 -0
  14. package/dist/eventcatalog.js +3 -20
  15. package/eventcatalog/src/components/CopyAsMarkdown.tsx +19 -1
  16. package/eventcatalog/src/components/FavoriteButton.tsx +54 -0
  17. package/eventcatalog/src/components/Grids/DomainGrid.tsx +386 -362
  18. package/eventcatalog/src/components/Grids/MessageGrid.tsx +166 -523
  19. package/eventcatalog/src/components/Header.astro +48 -23
  20. package/eventcatalog/src/components/Lists/VersionList.astro +2 -2
  21. package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +8 -2
  22. package/eventcatalog/src/components/SchemaExplorer/SchemaPageViewer.tsx +37 -0
  23. package/eventcatalog/src/components/Search/Search.astro +48 -28
  24. package/eventcatalog/src/components/Search/SearchModal.tsx +393 -702
  25. package/eventcatalog/src/components/SideNav/NestedSideBar/SearchBar.tsx +298 -0
  26. package/eventcatalog/src/components/SideNav/NestedSideBar/builders/container.ts +66 -0
  27. package/eventcatalog/src/components/SideNav/NestedSideBar/builders/domain.ts +101 -0
  28. package/eventcatalog/src/components/SideNav/NestedSideBar/builders/flow.ts +29 -0
  29. package/eventcatalog/src/components/SideNav/NestedSideBar/builders/message.ts +84 -0
  30. package/eventcatalog/src/components/SideNav/NestedSideBar/builders/service.ts +147 -0
  31. package/eventcatalog/src/components/SideNav/NestedSideBar/builders/shared.ts +146 -0
  32. package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +1073 -0
  33. package/eventcatalog/src/components/SideNav/NestedSideBar/sidebar-builder.ts +365 -0
  34. package/eventcatalog/src/components/SideNav/NestedSideBar/storage.ts +90 -0
  35. package/eventcatalog/src/components/SideNav/SideNav.astro +18 -28
  36. package/eventcatalog/src/content.config.ts +2 -0
  37. package/eventcatalog/src/enterprise/eventcatalog-chat/pages/chat/index.astro +3 -3
  38. package/eventcatalog/src/layouts/DirectoryLayout.astro +2 -2
  39. package/eventcatalog/src/layouts/DiscoverLayout.astro +3 -3
  40. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +83 -64
  41. package/eventcatalog/src/layouts/VisualiserLayout.astro +3 -3
  42. package/eventcatalog/src/pages/_index.astro +530 -110
  43. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.ts +64 -0
  44. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +29 -0
  45. package/eventcatalog/src/pages/directory/[type]/_index.data.ts +4 -4
  46. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/_index.data.ts +1 -4
  47. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/_index.data.ts +3 -3
  48. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +1 -5
  49. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +354 -186
  50. package/eventcatalog/src/pages/docs/[type]/[id]/[version].md.ts +1 -1
  51. package/eventcatalog/src/pages/docs/[type]/[id]/index.astro +4 -4
  52. package/eventcatalog/src/pages/docs/[type]/[id]/language/_index.data.ts +1 -4
  53. package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +3 -27
  54. package/eventcatalog/src/pages/docs/teams/[id]/_index.data.ts +2 -2
  55. package/eventcatalog/src/pages/docs/users/[id]/_index.data.ts +2 -2
  56. package/eventcatalog/src/pages/nav-index.json.ts +30 -0
  57. package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/_index.data.ts +77 -0
  58. package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/index.astro +90 -0
  59. package/eventcatalog/src/pages/schemas/{index.astro → explorer/index.astro} +3 -3
  60. package/eventcatalog/src/pages/studio.astro +3 -3
  61. package/eventcatalog/src/pages/visualiser/[type]/[id]/index.astro +2 -2
  62. package/eventcatalog/src/stores/favorites-store.ts +83 -0
  63. package/eventcatalog/src/stores/sidebar-store.ts +8 -0
  64. package/eventcatalog/src/utils/collections/changelogs.ts +7 -4
  65. package/eventcatalog/src/utils/{channels.ts → collections/channels.ts} +81 -31
  66. package/eventcatalog/src/utils/collections/commands.ts +134 -0
  67. package/eventcatalog/src/utils/collections/containers.ts +44 -33
  68. package/eventcatalog/src/utils/collections/domains.ts +204 -62
  69. package/eventcatalog/src/utils/{entities.ts → collections/entities.ts} +44 -24
  70. package/eventcatalog/src/utils/collections/events.ts +136 -0
  71. package/eventcatalog/src/utils/collections/flows.ts +59 -25
  72. package/eventcatalog/src/utils/{messages.ts → collections/messages.ts} +13 -4
  73. package/eventcatalog/src/utils/{queries.ts → collections/queries.ts} +49 -28
  74. package/eventcatalog/src/utils/collections/services.ts +100 -68
  75. package/eventcatalog/src/utils/collections/teams.ts +94 -0
  76. package/eventcatalog/src/utils/collections/users.ts +122 -0
  77. package/eventcatalog/src/utils/collections/util.ts +57 -1
  78. package/eventcatalog/src/utils/feature.ts +2 -2
  79. package/eventcatalog/src/utils/{collections/file-diffs.ts → file-diffs.ts} +1 -1
  80. package/eventcatalog/src/utils/node-graphs/container-node-graph.ts +2 -0
  81. package/eventcatalog/src/utils/node-graphs/domain-entity-map.ts +16 -6
  82. package/eventcatalog/src/utils/node-graphs/domains-canvas.ts +14 -10
  83. package/eventcatalog/src/utils/node-graphs/domains-node-graph.ts +36 -64
  84. package/eventcatalog/src/utils/node-graphs/flows-node-graph.ts +23 -19
  85. package/eventcatalog/src/utils/node-graphs/message-node-graph.ts +36 -49
  86. package/eventcatalog/src/utils/node-graphs/services-node-graph.ts +22 -18
  87. package/eventcatalog/src/utils/page-loaders/page-data-loader.ts +4 -4
  88. package/eventcatalog/tailwind.config.mjs +14 -0
  89. package/eventcatalog/tsconfig.json +2 -1
  90. package/package.json +7 -4
  91. package/eventcatalog/public/logo_old.png +0 -0
  92. package/eventcatalog/src/components/DiscoverInsight.astro +0 -61
  93. package/eventcatalog/src/components/Grids/ServiceGrid.tsx +0 -540
  94. package/eventcatalog/src/components/Lists/CustomSideBarSectionList.astro +0 -55
  95. package/eventcatalog/src/components/Lists/ProtocolList.tsx +0 -74
  96. package/eventcatalog/src/components/Lists/RepositoryList.astro +0 -37
  97. package/eventcatalog/src/components/Lists/SpecificationsList.astro +0 -67
  98. package/eventcatalog/src/components/SideBars/ChannelSideBar.astro +0 -204
  99. package/eventcatalog/src/components/SideBars/ContainerSideBar.astro +0 -183
  100. package/eventcatalog/src/components/SideBars/DomainSideBar.astro +0 -277
  101. package/eventcatalog/src/components/SideBars/EntitySideBar.astro +0 -139
  102. package/eventcatalog/src/components/SideBars/FlowSideBar.astro +0 -132
  103. package/eventcatalog/src/components/SideBars/MessageSideBar.astro +0 -251
  104. package/eventcatalog/src/components/SideBars/ServiceSideBar.astro +0 -298
  105. package/eventcatalog/src/components/SideNav/ListViewSideBar/components/CollapsibleGroup.tsx +0 -46
  106. package/eventcatalog/src/components/SideNav/ListViewSideBar/components/MessageList.tsx +0 -78
  107. package/eventcatalog/src/components/SideNav/ListViewSideBar/components/SpecificationList.tsx +0 -83
  108. package/eventcatalog/src/components/SideNav/ListViewSideBar/index.tsx +0 -1250
  109. package/eventcatalog/src/components/SideNav/ListViewSideBar/types.ts +0 -91
  110. package/eventcatalog/src/components/SideNav/ListViewSideBar/utils.ts +0 -201
  111. package/eventcatalog/src/components/SideNav/TreeView/getTreeView.ts +0 -190
  112. package/eventcatalog/src/components/SideNav/TreeView/index.tsx +0 -94
  113. package/eventcatalog/src/components/TreeView/index.tsx +0 -328
  114. package/eventcatalog/src/components/TreeView/styles.module.css +0 -264
  115. package/eventcatalog/src/components/TreeView/useSlots.ts +0 -95
  116. package/eventcatalog/src/pages/architecture/[type]/index.astro +0 -14
  117. package/eventcatalog/src/pages/architecture/architecture.astro +0 -110
  118. package/eventcatalog/src/pages/architecture/docs/[type]/index.astro +0 -14
  119. package/eventcatalog/src/utils/commands.ts +0 -112
  120. package/eventcatalog/src/utils/events.ts +0 -108
  121. package/eventcatalog/src/utils/generators/index.ts +0 -10
  122. package/eventcatalog/src/utils/teams.ts +0 -72
  123. package/eventcatalog/src/utils/users.ts +0 -72
package/README.md CHANGED
@@ -101,7 +101,7 @@ You can read more on [how it works on GitHub](https://github.com/event-catalog/e
101
101
 
102
102
  You should be able to get setup within minutes if you head over to our documentation to get started 👇
103
103
 
104
- ➡️ [Get Started](https://www.eventcatalog.dev/docs/development/getting-started/installation)
104
+ ➡️ [Get Started](https://www.eventcatalog.dev/docs/development/getting-started)
105
105
 
106
106
  Or run this command to build a new catalog
107
107
 
@@ -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.65.1";
40
+ var version = "3.0.0-beta.0";
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-2TTD2MLE.js";
4
- import "../chunk-BTS6L3KY.js";
3
+ } from "../chunk-JB4YT5JY.js";
4
+ import "../chunk-TQ4HZREX.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.65.1";
109
+ var version = "3.0.0-beta.0";
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-XB4SZX3I.js";
4
- import "../chunk-2TTD2MLE.js";
5
- import "../chunk-BTS6L3KY.js";
3
+ } from "../chunk-X4W4YC3U.js";
4
+ import "../chunk-JB4YT5JY.js";
5
+ import "../chunk-TQ4HZREX.js";
6
6
  import "../chunk-UPONRQSN.js";
7
7
  export {
8
8
  log_build_default as default
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-BTS6L3KY.js";
3
+ } from "./chunk-TQ4HZREX.js";
4
4
 
5
5
  // src/analytics/analytics.js
6
6
  import axios from "axios";
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "2.65.1";
2
+ var version = "3.0.0-beta.0";
3
3
 
4
4
  // src/constants.ts
5
5
  var VERSION = version;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "./chunk-2TTD2MLE.js";
3
+ } from "./chunk-JB4YT5JY.js";
4
4
  import {
5
5
  getEventCatalogConfigFile,
6
6
  verifyRequiredFieldsAreInCatalogConfigFile
@@ -25,7 +25,7 @@ __export(constants_exports, {
25
25
  module.exports = __toCommonJS(constants_exports);
26
26
 
27
27
  // package.json
28
- var version = "2.65.1";
28
+ var version = "3.0.0-beta.0";
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-BTS6L3KY.js";
3
+ } from "./chunk-TQ4HZREX.js";
4
4
  export {
5
5
  VERSION
6
6
  };
@@ -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.65.1";
160
+ var version = "3.0.0-beta.0";
161
161
 
162
162
  // src/constants.ts
163
163
  var VERSION = version;
@@ -505,10 +505,6 @@ var import_boxen = __toESM(require("boxen"), 1);
505
505
  // src/features.ts
506
506
  var import_node_path5 = require("path");
507
507
  var import_node_fs4 = __toESM(require("fs"), 1);
508
- var getProjectOutDir = async () => {
509
- const config = await getEventCatalogConfigFile(process.env.PROJECT_DIR || "");
510
- return config?.outDir || "dist";
511
- };
512
508
  var isOutputServer = async () => {
513
509
  const config = await getEventCatalogConfigFile(process.env.PROJECT_DIR || "");
514
510
  return config?.output === "server";
@@ -824,22 +820,6 @@ program.command("build").description("Run build of EventCatalog").action(async (
824
820
  stdio: "inherit"
825
821
  }
826
822
  );
827
- if (!isServerOutput) {
828
- const outDir = await getProjectOutDir();
829
- const windowsCommand2 = `npx -y pagefind --site ${outDir}`;
830
- const unixCommand2 = `npx -y pagefind --site ${outDir}`;
831
- const pagefindCommand = process.platform === "win32" ? windowsCommand2 : unixCommand2;
832
- (0, import_node_child_process.execSync)(
833
- `cross-env PROJECT_DIR='${dir}' CATALOG_DIR='${core}' ENABLE_EMBED=${canEmbedPages} EVENTCATALOG_STARTER=${isEventCatalogStarter} EVENTCATALOG_SCALE=${isEventCatalogScale} ${pagefindCommand}`,
834
- {
835
- cwd: dir,
836
- stdio: "inherit"
837
- }
838
- );
839
- if (import_fs2.default.existsSync((0, import_node_path7.join)(dir, outDir, "pagefind"))) {
840
- import_fs2.default.cpSync((0, import_node_path7.join)(dir, outDir, "pagefind"), (0, import_node_path7.join)(dir, "public", "pagefind"), { recursive: true });
841
- }
842
- }
843
823
  });
844
824
  var previewCatalog = ({
845
825
  command,
@@ -38,6 +38,12 @@ type TableConfiguration = {
38
38
  };
39
39
  };
40
40
  };
41
+ type PagesConfiguration = {
42
+ type: 'item' | 'group';
43
+ title: string;
44
+ icon?: string;
45
+ pages?: string[];
46
+ };
41
47
  interface Config {
42
48
  title: string;
43
49
  tagline: false;
@@ -69,6 +75,9 @@ interface Config {
69
75
  mdxOptimize?: boolean;
70
76
  compress?: boolean;
71
77
  sidebar?: SideBarConfig[];
78
+ navigation?: {
79
+ pages: PagesConfiguration[];
80
+ };
72
81
  docs: {
73
82
  sidebar: {
74
83
  type?: 'TREE_VIEW' | 'LIST_VIEW';
@@ -38,6 +38,12 @@ type TableConfiguration = {
38
38
  };
39
39
  };
40
40
  };
41
+ type PagesConfiguration = {
42
+ type: 'item' | 'group';
43
+ title: string;
44
+ icon?: string;
45
+ pages?: string[];
46
+ };
41
47
  interface Config {
42
48
  title: string;
43
49
  tagline: false;
@@ -69,6 +75,9 @@ interface Config {
69
75
  mdxOptimize?: boolean;
70
76
  compress?: boolean;
71
77
  sidebar?: SideBarConfig[];
78
+ navigation?: {
79
+ pages: PagesConfiguration[];
80
+ };
72
81
  docs: {
73
82
  sidebar: {
74
83
  type?: 'TREE_VIEW' | 'LIST_VIEW';
@@ -6,8 +6,8 @@ import {
6
6
  } from "./chunk-PLNJC7NZ.js";
7
7
  import {
8
8
  log_build_default
9
- } from "./chunk-XB4SZX3I.js";
10
- import "./chunk-2TTD2MLE.js";
9
+ } from "./chunk-X4W4YC3U.js";
10
+ import "./chunk-JB4YT5JY.js";
11
11
  import {
12
12
  runMigrations
13
13
  } from "./chunk-BH3JMNAV.js";
@@ -19,9 +19,8 @@ import {
19
19
  import "./chunk-55D645EH.js";
20
20
  import {
21
21
  VERSION
22
- } from "./chunk-BTS6L3KY.js";
22
+ } from "./chunk-TQ4HZREX.js";
23
23
  import {
24
- getProjectOutDir,
25
24
  isAuthEnabled,
26
25
  isOutputServer
27
26
  } from "./chunk-5VBIXL6C.js";
@@ -230,22 +229,6 @@ program.command("build").description("Run build of EventCatalog").action(async (
230
229
  stdio: "inherit"
231
230
  }
232
231
  );
233
- if (!isServerOutput) {
234
- const outDir = await getProjectOutDir();
235
- const windowsCommand2 = `npx -y pagefind --site ${outDir}`;
236
- const unixCommand2 = `npx -y pagefind --site ${outDir}`;
237
- const pagefindCommand = process.platform === "win32" ? windowsCommand2 : unixCommand2;
238
- execSync(
239
- `cross-env PROJECT_DIR='${dir}' CATALOG_DIR='${core}' ENABLE_EMBED=${canEmbedPages} EVENTCATALOG_STARTER=${isEventCatalogStarter} EVENTCATALOG_SCALE=${isEventCatalogScale} ${pagefindCommand}`,
240
- {
241
- cwd: dir,
242
- stdio: "inherit"
243
- }
244
- );
245
- if (fs.existsSync(join(dir, outDir, "pagefind"))) {
246
- fs.cpSync(join(dir, outDir, "pagefind"), join(dir, "public", "pagefind"), { recursive: true });
247
- }
248
- }
249
232
  });
250
233
  var previewCatalog = ({
251
234
  command,
@@ -1,5 +1,5 @@
1
1
  import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
2
- import { Copy, FileText, MessageCircleQuestion, ChevronDownIcon, ExternalLink, PenSquareIcon } from 'lucide-react';
2
+ import { Copy, FileText, MessageCircleQuestion, ChevronDownIcon, ExternalLink, PenSquareIcon, RssIcon } from 'lucide-react';
3
3
  import React, { useState, isValidElement } from 'react';
4
4
  import type { Schema } from '@utils/collections/schemas';
5
5
  import { buildUrl, toMarkdownUrl } from '@utils/url-builder';
@@ -48,12 +48,14 @@ export function CopyPageMenu({
48
48
  chatEnabled = false,
49
49
  editUrl,
50
50
  markdownDownloadEnabled = false,
51
+ rssFeedEnabled = false,
51
52
  }: {
52
53
  schemas: Schema[];
53
54
  chatQuery?: string;
54
55
  chatEnabled: boolean;
55
56
  editUrl: string;
56
57
  markdownDownloadEnabled: boolean;
58
+ rssFeedEnabled: boolean;
57
59
  }) {
58
60
  // Define available actions
59
61
  const availableActions = {
@@ -62,6 +64,7 @@ export function CopyPageMenu({
62
64
  copySchemas: schemas.length > 0,
63
65
  viewMarkdown: markdownDownloadEnabled,
64
66
  chat: chatEnabled,
67
+ rssFeed: rssFeedEnabled,
65
68
  };
66
69
 
67
70
  // Check if any actions are available
@@ -113,6 +116,13 @@ export function CopyPageMenu({
113
116
  icon: MessageCircleQuestion,
114
117
  };
115
118
  }
119
+ if (availableActions.rssFeed) {
120
+ return {
121
+ type: 'rssFeed',
122
+ text: 'RSS Feed',
123
+ icon: RssIcon,
124
+ };
125
+ }
116
126
  return null;
117
127
  };
118
128
 
@@ -287,6 +297,14 @@ export function CopyPageMenu({
287
297
  </DropdownMenu.Item>
288
298
  )}
289
299
 
300
+ {availableActions.rssFeed && (
301
+ <DropdownMenu.Item
302
+ className="cursor-pointer hover:bg-gray-100 focus:outline-none focus:bg-gray-100"
303
+ onSelect={() => window.open(buildUrl(`/rss/all/rss.xml`), '_blank')}
304
+ >
305
+ <MenuItemContent icon={RssIcon} title="RSS Feed" description="View this page as RSS feed" external={true} />
306
+ </DropdownMenu.Item>
307
+ )}
290
308
  {availableActions.chat && (
291
309
  <DropdownMenu.Item
292
310
  className="cursor-pointer hover:bg-gray-100 focus:outline-none focus:bg-gray-100"
@@ -0,0 +1,54 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { StarIcon as StarIconOutline } from '@heroicons/react/24/outline';
3
+ import { StarIcon as StarIconSolid } from '@heroicons/react/24/solid';
4
+ import { useStore } from '@nanostores/react';
5
+ import { favoritesStore, toggleFavorite, type FavoriteItem } from '../stores/favorites-store';
6
+
7
+ interface FavoriteButtonProps {
8
+ nodeKey: string;
9
+ title: string;
10
+ badge?: string;
11
+ href?: string;
12
+ size?: 'sm' | 'md' | 'lg';
13
+ }
14
+
15
+ export default function FavoriteButton({ nodeKey, title, badge, href, size = 'md' }: FavoriteButtonProps) {
16
+ const favorites = useStore(favoritesStore);
17
+ const [isClient, setIsClient] = useState(false);
18
+
19
+ useEffect(() => {
20
+ setIsClient(true);
21
+ }, []);
22
+
23
+ const isFavorite = isClient && favorites.some((fav) => fav.nodeKey === nodeKey);
24
+
25
+ const sizeClasses = {
26
+ sm: 'h-4 w-4',
27
+ md: 'h-6 w-6',
28
+ lg: 'h-8 w-8',
29
+ };
30
+
31
+ const handleToggleFavorite = () => {
32
+ const favoriteItem: FavoriteItem = {
33
+ nodeKey,
34
+ path: [],
35
+ title,
36
+ badge,
37
+ href,
38
+ };
39
+ toggleFavorite(favoriteItem);
40
+ };
41
+
42
+ return (
43
+ <button
44
+ onClick={handleToggleFavorite}
45
+ className={`p-2 rounded-md transition-colors ${
46
+ isFavorite ? 'text-amber-400 hover:text-amber-500' : 'text-gray-300 hover:text-amber-400'
47
+ }`}
48
+ aria-label={isFavorite ? 'Remove from favorites' : 'Add to favorites'}
49
+ title={isFavorite ? 'Remove from favorites' : 'Add to favorites'}
50
+ >
51
+ {isFavorite ? <StarIconSolid className={sizeClasses[size]} /> : <StarIconOutline className={sizeClasses[size]} />}
52
+ </button>
53
+ );
54
+ }