@eventcatalog/core 3.0.0-beta.25 → 3.0.0-beta.27

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 (56) hide show
  1. package/dist/analytics/analytics.cjs +1 -1
  2. package/dist/analytics/analytics.js +2 -2
  3. package/dist/analytics/log-build.cjs +1 -1
  4. package/dist/analytics/log-build.js +3 -3
  5. package/dist/catalog-to-astro-content-directory.cjs +2 -19
  6. package/dist/catalog-to-astro-content-directory.d.cts +1 -2
  7. package/dist/catalog-to-astro-content-directory.d.ts +1 -2
  8. package/dist/catalog-to-astro-content-directory.js +3 -5
  9. package/dist/{chunk-NAW6EPCS.js → chunk-4CVSY4TZ.js} +1 -1
  10. package/dist/{chunk-R2BJ7MJG.js → chunk-6Z6ARMQS.js} +1 -17
  11. package/dist/{chunk-RA6AYXGJ.js → chunk-A24LNVFO.js} +1 -1
  12. package/dist/{chunk-OJA6CNVO.js → chunk-QTIXOITU.js} +1 -1
  13. package/dist/{chunk-DFHXF3VF.js → chunk-R3UXUYOX.js} +1 -1
  14. package/dist/{chunk-3SWCGDD7.js → chunk-X7U5G4IG.js} +1 -1
  15. package/dist/constants.cjs +1 -1
  16. package/dist/constants.js +1 -1
  17. package/dist/eventcatalog.cjs +1 -18
  18. package/dist/eventcatalog.js +7 -10
  19. package/dist/generate.cjs +1 -1
  20. package/dist/generate.js +3 -3
  21. package/dist/utils/cli-logger.cjs +1 -1
  22. package/dist/utils/cli-logger.js +2 -2
  23. package/eventcatalog/src/components/Grids/DomainGrid.tsx +309 -170
  24. package/eventcatalog/src/components/Grids/MessageGrid.tsx +301 -182
  25. package/eventcatalog/src/components/Grids/specification-utils.ts +106 -0
  26. package/eventcatalog/src/components/SchemaExplorer/ApiAccessSection.tsx +95 -90
  27. package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +144 -0
  28. package/eventcatalog/src/components/SchemaExplorer/Pagination.tsx +34 -8
  29. package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +2 -2
  30. package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsHeader.tsx +140 -109
  31. package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +5 -14
  32. package/eventcatalog/src/components/SchemaExplorer/SchemaExplorer.tsx +247 -59
  33. package/eventcatalog/src/components/SchemaExplorer/SchemaFilters.tsx +64 -126
  34. package/eventcatalog/src/components/SchemaExplorer/SchemaListItem.tsx +41 -43
  35. package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +42 -15
  36. package/eventcatalog/src/components/Tables/Table.tsx +96 -77
  37. package/eventcatalog/src/components/Tables/columns/ContainersTableColumns.tsx +108 -74
  38. package/eventcatalog/src/components/Tables/columns/DomainTableColumns.tsx +74 -55
  39. package/eventcatalog/src/components/Tables/columns/FlowTableColumns.tsx +36 -36
  40. package/eventcatalog/src/components/Tables/columns/MessageTableColumns.tsx +110 -77
  41. package/eventcatalog/src/components/Tables/columns/ServiceTableColumns.tsx +105 -94
  42. package/eventcatalog/src/components/Tables/columns/SharedColumns.tsx +31 -26
  43. package/eventcatalog/src/components/Tables/columns/TeamsTableColumns.tsx +115 -215
  44. package/eventcatalog/src/components/Tables/columns/UserTableColumns.tsx +145 -243
  45. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +2 -2
  46. package/eventcatalog/src/pages/_index.astro +239 -554
  47. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.ts +8 -2
  48. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +9 -5
  49. package/eventcatalog/src/pages/directory/[type]/index.astro +6 -0
  50. package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +194 -121
  51. package/eventcatalog/src/pages/docs/teams/[id]/index.astro +94 -70
  52. package/eventcatalog/src/pages/docs/users/[id]/index.astro +56 -45
  53. package/eventcatalog/src/pages/studio.astro +124 -72
  54. package/eventcatalog/src/stores/sidebar-store/builders/domain.ts +1 -1
  55. package/eventcatalog/src/stores/sidebar-store/builders/service.ts +1 -1
  56. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
- import { ChevronUpIcon, ChevronDownIcon, ClipboardDocumentIcon } from '@heroicons/react/24/outline';
1
+ import { ChevronUpIcon, ChevronDownIcon, ClipboardDocumentIcon, CheckIcon } from '@heroicons/react/24/outline';
2
+ import { CommandLineIcon, LockClosedIcon } from '@heroicons/react/24/solid';
2
3
  import type { SchemaItem } from './types';
3
4
 
4
5
  interface ApiAccessSectionProps {
@@ -27,109 +28,113 @@ export default function ApiAccessSection({
27
28
  apiPath = `/api/schemas/${message.collection}/${message.data.id}/${message.data.version}`;
28
29
  }
29
30
 
30
- const curlCommand = typeof window !== 'undefined' ? `curl -X GET "${window.location.origin}${apiPath}"` : '';
31
+ const fullUrl = typeof window !== 'undefined' ? `${window.location.origin}${apiPath}` : apiPath;
32
+ const curlCommand = `curl ${fullUrl}`;
33
+ const isCopied = copiedId === `${message.data.id}-api`;
31
34
 
32
35
  return (
33
- <div className="flex-shrink-0 border-b border-gray-200">
36
+ <div className="flex-shrink-0 border-b border-gray-100">
34
37
  <button
35
38
  onClick={onToggle}
36
- className="w-full flex items-center justify-between px-4 py-1.5 text-left hover:bg-gray-50 transition-colors"
39
+ className="w-full flex items-center justify-between px-4 py-2 text-left hover:bg-gray-50/50 transition-colors"
37
40
  >
38
41
  <div className="flex items-center gap-2">
39
- <svg
40
- xmlns="http://www.w3.org/2000/svg"
41
- className="h-4 w-4 text-gray-600"
42
- fill="none"
43
- viewBox="0 0 24 24"
44
- stroke="currentColor"
45
- >
46
- <path
47
- strokeLinecap="round"
48
- strokeLinejoin="round"
49
- strokeWidth={2}
50
- d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
51
- />
52
- </svg>
53
- <span className="text-xs font-semibold text-gray-900">API Access</span>
54
- <span className="inline-flex items-center rounded-full bg-purple-100 px-2 py-0.5 text-xs font-medium text-purple-800">
55
- Scale
56
- </span>
42
+ <CommandLineIcon className="h-3.5 w-3.5 text-gray-700" />
43
+ <span className="text-xs font-medium text-gray-700">API</span>
44
+ {!apiAccessEnabled && (
45
+ <span className="inline-flex items-center gap-1 rounded bg-purple-50 px-1.5 py-0.5 text-[10px] font-medium text-purple-600 border border-purple-100">
46
+ <LockClosedIcon className="h-2.5 w-2.5" />
47
+ Scale
48
+ </span>
49
+ )}
57
50
  </div>
58
- {isExpanded ? <ChevronUpIcon className="h-4 w-4 text-gray-600" /> : <ChevronDownIcon className="h-4 w-4 text-gray-600" />}
51
+ {isExpanded ? (
52
+ <ChevronUpIcon className="h-3.5 w-3.5 text-gray-400" />
53
+ ) : (
54
+ <ChevronDownIcon className="h-3.5 w-3.5 text-gray-400" />
55
+ )}
59
56
  </button>
60
57
 
61
58
  {isExpanded && (
62
- <div className="px-4 pb-2 bg-gray-50">
59
+ <div className="px-4 pb-3">
63
60
  {apiAccessEnabled ? (
64
- <>
65
- <p className="text-xs text-gray-600 mb-2">Access this schema programmatically via API</p>
66
- <div className="bg-gray-900 rounded-md p-3">
67
- <div className="flex items-start justify-between mb-2">
68
- <span className="text-xs text-gray-400 font-mono">GET</span>
69
- <button
70
- onClick={() => onCopy(curlCommand, `${message.data.id}-api`)}
71
- className="inline-flex items-center gap-1 px-2 py-1 text-xs font-medium text-gray-300 hover:text-white transition-colors"
72
- title="Copy curl command"
73
- >
74
- <ClipboardDocumentIcon className="h-3.5 w-3.5" />
75
- {copiedId === `${message.data.id}-api` ? 'Copied!' : 'Copy'}
76
- </button>
77
- </div>
78
- <code className="block text-xs text-green-400 font-mono break-all">{apiPath}</code>
79
- <div className="mt-3 pt-3 border-t border-gray-700">
80
- <p className="text-xs text-gray-400 mb-2">Example:</p>
81
- <code className="block text-xs text-gray-300 font-mono whitespace-pre-wrap break-all">{curlCommand}</code>
82
- </div>
61
+ <div className="space-y-2">
62
+ {/* Endpoint */}
63
+ <div className="flex items-center gap-2 bg-gray-900 rounded-md px-3 py-2">
64
+ <span className="text-[10px] font-semibold text-emerald-400 uppercase tracking-wide">GET</span>
65
+ <code className="flex-1 text-[11px] text-gray-300 font-mono truncate">{apiPath}</code>
66
+ <button
67
+ onClick={() => onCopy(fullUrl, `${message.data.id}-api`)}
68
+ className={`flex-shrink-0 p-1 rounded transition-colors ${
69
+ isCopied ? 'text-emerald-400' : 'text-gray-500 hover:text-gray-300'
70
+ }`}
71
+ title="Copy URL"
72
+ >
73
+ {isCopied ? <CheckIcon className="h-3.5 w-3.5" /> : <ClipboardDocumentIcon className="h-3.5 w-3.5" />}
74
+ </button>
75
+ </div>
76
+
77
+ {/* Quick copy buttons */}
78
+ <div className="flex items-center gap-2">
79
+ <button
80
+ onClick={() => onCopy(curlCommand, `${message.data.id}-curl`)}
81
+ className={`inline-flex items-center gap-1.5 px-2 py-1 text-[10px] font-medium rounded border transition-colors ${
82
+ copiedId === `${message.data.id}-curl`
83
+ ? 'bg-emerald-50 text-emerald-600 border-emerald-200'
84
+ : 'text-gray-500 border-gray-200 hover:bg-gray-50 hover:text-gray-700'
85
+ }`}
86
+ >
87
+ {copiedId === `${message.data.id}-curl` ? (
88
+ <>
89
+ <CheckIcon className="h-3 w-3" />
90
+ Copied
91
+ </>
92
+ ) : (
93
+ <>
94
+ <ClipboardDocumentIcon className="h-3 w-3" />
95
+ Copy cURL
96
+ </>
97
+ )}
98
+ </button>
99
+ <button
100
+ onClick={() => onCopy(fullUrl, `${message.data.id}-url`)}
101
+ className={`inline-flex items-center gap-1.5 px-2 py-1 text-[10px] font-medium rounded border transition-colors ${
102
+ copiedId === `${message.data.id}-url`
103
+ ? 'bg-emerald-50 text-emerald-600 border-emerald-200'
104
+ : 'text-gray-500 border-gray-200 hover:bg-gray-50 hover:text-gray-700'
105
+ }`}
106
+ >
107
+ {copiedId === `${message.data.id}-url` ? (
108
+ <>
109
+ <CheckIcon className="h-3 w-3" />
110
+ Copied
111
+ </>
112
+ ) : (
113
+ <>
114
+ <ClipboardDocumentIcon className="h-3 w-3" />
115
+ Copy URL
116
+ </>
117
+ )}
118
+ </button>
83
119
  </div>
84
- </>
120
+ </div>
85
121
  ) : (
86
- <div className="bg-white border border-purple-200 rounded-md p-4">
87
- <div className="flex items-start gap-3">
88
- <div className="flex-shrink-0">
89
- <svg
90
- xmlns="http://www.w3.org/2000/svg"
91
- className="h-5 w-5 text-purple-600"
92
- fill="none"
93
- viewBox="0 0 24 24"
94
- stroke="currentColor"
95
- >
96
- <path
97
- strokeLinecap="round"
98
- strokeLinejoin="round"
99
- strokeWidth={2}
100
- d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"
101
- />
102
- </svg>
103
- </div>
104
- <div className="flex-1">
105
- <h4 className="text-sm font-semibold text-gray-900 mb-1">Upgrade to Scale</h4>
106
- <p className="text-xs text-gray-600 mb-3">
107
- Access your schemas programmatically via API. Perfect for CI/CD pipelines, automation, and integrations.
108
- </p>
109
- <a
110
- href="https://eventcatalog.cloud"
111
- target="_blank"
112
- rel="noopener noreferrer"
113
- className="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium text-white bg-purple-600 rounded-md hover:bg-purple-700 transition-colors"
114
- >
115
- Start 14-day free trial
116
- <svg
117
- xmlns="http://www.w3.org/2000/svg"
118
- className="h-3.5 w-3.5"
119
- fill="none"
120
- viewBox="0 0 24 24"
121
- stroke="currentColor"
122
- >
123
- <path
124
- strokeLinecap="round"
125
- strokeLinejoin="round"
126
- strokeWidth={2}
127
- d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
128
- />
129
- </svg>
130
- </a>
131
- </div>
122
+ <div className="flex items-center justify-between gap-3 bg-gradient-to-r from-purple-50 to-indigo-50 border border-purple-100 rounded-md px-3 py-2.5">
123
+ <div className="flex-1 min-w-0">
124
+ <p className="text-xs font-medium text-gray-700">Access schemas via API</p>
125
+ <p className="text-[10px] text-gray-500 mt-0.5">CI/CD, automation & integrations</p>
132
126
  </div>
127
+ <a
128
+ href="https://eventcatalog.cloud"
129
+ target="_blank"
130
+ rel="noopener noreferrer"
131
+ className="flex-shrink-0 inline-flex items-center gap-1 px-2.5 py-1.5 text-[11px] font-medium text-white bg-purple-600 rounded-md hover:bg-purple-700 transition-colors"
132
+ >
133
+ Try Scale
134
+ <svg xmlns="http://www.w3.org/2000/svg" className="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
135
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
136
+ </svg>
137
+ </a>
133
138
  </div>
134
139
  )}
135
140
  </div>
@@ -0,0 +1,144 @@
1
+ import { ClipboardDocumentIcon, CheckIcon } from '@heroicons/react/24/outline';
2
+ import { CommandLineIcon, LockClosedIcon } from '@heroicons/react/24/solid';
3
+ import type { SchemaItem } from './types';
4
+
5
+ interface ApiContentViewerProps {
6
+ message: SchemaItem;
7
+ onCopy: (content: string, id: string) => void;
8
+ copiedId: string | null;
9
+ apiAccessEnabled?: boolean;
10
+ }
11
+
12
+ export default function ApiContentViewer({ message, onCopy, copiedId, apiAccessEnabled = false }: ApiContentViewerProps) {
13
+ // Generate API path based on collection type
14
+ let apiPath = '';
15
+ if (message.collection === 'services') {
16
+ const specType = message.specType || 'openapi';
17
+ apiPath = `/api/schemas/services/${message.data.id}/${message.data.version}/${specType}`;
18
+ } else {
19
+ apiPath = `/api/schemas/${message.collection}/${message.data.id}/${message.data.version}`;
20
+ }
21
+
22
+ const fullUrl = typeof window !== 'undefined' ? `${window.location.origin}${apiPath}` : apiPath;
23
+ const curlCommand = `curl ${fullUrl}`;
24
+
25
+ if (!apiAccessEnabled) {
26
+ return (
27
+ <div className="h-full flex items-center justify-center p-8">
28
+ <div className="max-w-md text-center">
29
+ <div className="flex items-center justify-center w-16 h-16 mx-auto mb-4 rounded-2xl bg-gradient-to-br from-purple-100 to-indigo-100 border border-purple-200">
30
+ <LockClosedIcon className="h-8 w-8 text-purple-600" />
31
+ </div>
32
+ <h3 className="text-lg font-semibold text-gray-900 mb-2">API Access</h3>
33
+ <p className="text-sm text-gray-600 mb-6">
34
+ Access your schemas programmatically via REST API. Perfect for CI/CD pipelines, automation, and integrations with your
35
+ development workflow.
36
+ </p>
37
+ <a
38
+ href="https://eventcatalog.cloud"
39
+ target="_blank"
40
+ rel="noopener noreferrer"
41
+ className="inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-purple-600 rounded-lg hover:bg-purple-700 transition-colors"
42
+ >
43
+ Upgrade to Scale
44
+ <svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
45
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
46
+ </svg>
47
+ </a>
48
+ <p className="text-xs text-gray-500 mt-3">Start your 14-day free trial</p>
49
+ </div>
50
+ </div>
51
+ );
52
+ }
53
+
54
+ return (
55
+ <div className="h-full overflow-auto p-4">
56
+ <div className="max-w-2xl">
57
+ {/* Header */}
58
+ <div className="flex items-center gap-3 mb-6">
59
+ <div className="flex items-center justify-center w-10 h-10 rounded-lg bg-gray-100">
60
+ <CommandLineIcon className="h-5 w-5 text-gray-700" />
61
+ </div>
62
+ <div>
63
+ <h3 className="text-sm font-semibold text-gray-900">API Access</h3>
64
+ <p className="text-xs text-gray-500">Access this schema programmatically</p>
65
+ </div>
66
+ </div>
67
+
68
+ {/* Endpoint Card */}
69
+ <div className="bg-gray-900 rounded-lg overflow-hidden mb-4">
70
+ <div className="flex items-center justify-between px-4 py-2 border-b border-gray-700">
71
+ <span className="text-xs font-medium text-gray-400">Endpoint</span>
72
+ <button
73
+ onClick={() => onCopy(fullUrl, `${message.data.id}-url`)}
74
+ className={`inline-flex items-center gap-1.5 px-2 py-1 text-xs font-medium rounded transition-colors ${
75
+ copiedId === `${message.data.id}-url` ? 'text-emerald-400' : 'text-gray-400 hover:text-white'
76
+ }`}
77
+ >
78
+ {copiedId === `${message.data.id}-url` ? (
79
+ <>
80
+ <CheckIcon className="h-3.5 w-3.5" />
81
+ Copied
82
+ </>
83
+ ) : (
84
+ <>
85
+ <ClipboardDocumentIcon className="h-3.5 w-3.5" />
86
+ Copy URL
87
+ </>
88
+ )}
89
+ </button>
90
+ </div>
91
+ <div className="px-4 py-3">
92
+ <div className="flex items-center gap-3">
93
+ <span className="px-2 py-1 text-xs font-bold text-emerald-400 bg-emerald-400/10 rounded">GET</span>
94
+ <code className="text-sm text-gray-300 font-mono break-all">{apiPath}</code>
95
+ </div>
96
+ </div>
97
+ </div>
98
+
99
+ {/* cURL Example */}
100
+ <div className="bg-gray-900 rounded-lg overflow-hidden mb-6">
101
+ <div className="flex items-center justify-between px-4 py-2 border-b border-gray-700">
102
+ <span className="text-xs font-medium text-gray-400">cURL Example</span>
103
+ <button
104
+ onClick={() => onCopy(curlCommand, `${message.data.id}-curl`)}
105
+ className={`inline-flex items-center gap-1.5 px-2 py-1 text-xs font-medium rounded transition-colors ${
106
+ copiedId === `${message.data.id}-curl` ? 'text-emerald-400' : 'text-gray-400 hover:text-white'
107
+ }`}
108
+ >
109
+ {copiedId === `${message.data.id}-curl` ? (
110
+ <>
111
+ <CheckIcon className="h-3.5 w-3.5" />
112
+ Copied
113
+ </>
114
+ ) : (
115
+ <>
116
+ <ClipboardDocumentIcon className="h-3.5 w-3.5" />
117
+ Copy
118
+ </>
119
+ )}
120
+ </button>
121
+ </div>
122
+ <div className="px-4 py-3">
123
+ <code className="text-sm text-gray-300 font-mono break-all">{curlCommand}</code>
124
+ </div>
125
+ </div>
126
+
127
+ {/* Response Info */}
128
+ <div className="border border-gray-200 rounded-lg p-4">
129
+ <h4 className="text-xs font-semibold text-gray-900 mb-3">Response</h4>
130
+ <div className="space-y-2">
131
+ <div className="flex items-center justify-between text-xs">
132
+ <span className="text-gray-500">Content-Type</span>
133
+ <code className="text-gray-700 bg-gray-100 px-2 py-0.5 rounded">application/json</code>
134
+ </div>
135
+ <div className="flex items-center justify-between text-xs">
136
+ <span className="text-gray-500">Returns</span>
137
+ <span className="text-gray-700">Raw schema content</span>
138
+ </div>
139
+ </div>
140
+ </div>
141
+ </div>
142
+ </div>
143
+ );
144
+ }
@@ -1,3 +1,5 @@
1
+ import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
2
+
1
3
  interface PaginationProps {
2
4
  currentPage: number;
3
5
  totalPages: number;
@@ -8,24 +10,48 @@ export default function Pagination({ currentPage, totalPages, onPageChange }: Pa
8
10
  if (totalPages <= 1) return null;
9
11
 
10
12
  return (
11
- <div className="flex-shrink-0 border-t border-gray-200 p-3 bg-gray-50">
12
- <div className="flex items-center justify-between text-xs">
13
+ <div className="flex-shrink-0 border-t border-gray-100 px-3 py-1.5 bg-gray-50/50">
14
+ <div className="flex items-center justify-between">
13
15
  <button
14
16
  onClick={() => onPageChange(Math.max(1, currentPage - 1))}
15
17
  disabled={currentPage === 1}
16
- className="px-3 py-1.5 text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
18
+ className="inline-flex items-center gap-0.5 px-1.5 py-1 text-xs font-medium text-gray-500 hover:text-gray-700 disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
17
19
  >
18
- Previous
20
+ <ChevronLeftIcon className="h-3.5 w-3.5" />
21
+ Prev
19
22
  </button>
20
- <span className="text-gray-600">
21
- Page {currentPage} of {totalPages}
22
- </span>
23
+ <div className="flex items-center gap-0.5">
24
+ {Array.from({ length: Math.min(5, totalPages) }, (_, i) => {
25
+ let pageNum: number;
26
+ if (totalPages <= 5) {
27
+ pageNum = i + 1;
28
+ } else if (currentPage <= 3) {
29
+ pageNum = i + 1;
30
+ } else if (currentPage >= totalPages - 2) {
31
+ pageNum = totalPages - 4 + i;
32
+ } else {
33
+ pageNum = currentPage - 2 + i;
34
+ }
35
+ return (
36
+ <button
37
+ key={pageNum}
38
+ onClick={() => onPageChange(pageNum)}
39
+ className={`w-6 h-6 text-[11px] font-medium rounded transition-all tabular-nums ${
40
+ currentPage === pageNum ? 'bg-gray-900 text-white' : 'text-gray-500 hover:bg-gray-100 hover:text-gray-700'
41
+ }`}
42
+ >
43
+ {pageNum}
44
+ </button>
45
+ );
46
+ })}
47
+ </div>
23
48
  <button
24
49
  onClick={() => onPageChange(Math.min(totalPages, currentPage + 1))}
25
50
  disabled={currentPage === totalPages}
26
- className="px-3 py-1.5 text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed"
51
+ className="inline-flex items-center gap-0.5 px-1.5 py-1 text-xs font-medium text-gray-500 hover:text-gray-700 disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
27
52
  >
28
53
  Next
54
+ <ChevronRightIcon className="h-3.5 w-3.5" />
29
55
  </button>
30
56
  </div>
31
57
  </div>
@@ -115,8 +115,8 @@ export default function SchemaContentViewer({
115
115
  padding: '0.75rem',
116
116
  paddingTop: '2.5rem',
117
117
  borderRadius: '0.5rem',
118
- fontSize: '0.875rem',
119
- lineHeight: '1.6',
118
+ fontSize: '0.75rem',
119
+ lineHeight: '1.5',
120
120
  height: '100%',
121
121
  overflow: 'auto',
122
122
  }}