ai-design-system 0.1.13 → 0.1.15

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.
@@ -2,7 +2,23 @@
2
2
  * AIDocEditor Feature Component
3
3
  *
4
4
  * Complete document editor with inline comment annotations
5
+ * Supports both single-document and multi-tab modes
5
6
  */
6
7
 
7
8
  export { AIDocEditor } from './AIDocEditor'
8
- export type { AIDocEditorProps } from './AIDocEditor'
9
+ export type {
10
+ AIDocEditorProps,
11
+ AIDocEditorSingleProps,
12
+ AIDocEditorMultiTabProps,
13
+ } from './AIDocEditor'
14
+
15
+ export { useAIDocEditorMock, useAIMultiTabDocEditorMock } from './useAIDocEditor.mock'
16
+ export type { UseAIDocEditorReturn, UseAIMultiTabDocEditorReturn } from './useAIDocEditor'
17
+
18
+ export {
19
+ sampleContent,
20
+ currentUser,
21
+ sampleAnnotations,
22
+ sampleDocumentFiles,
23
+ sampleMultiTabDocuments,
24
+ } from './AIDocEditor.mocks'
@@ -46,9 +46,12 @@
46
46
  */
47
47
 
48
48
  import type { Annotation } from '@/types/ai-editor/annotations'
49
+ import type { DocumentFile, DocumentWithAnnotations } from '@/types/ai-editor/editor'
50
+ import type { JSONContent } from '@tiptap/core'
49
51
 
50
52
  /**
51
- * Return type for useAIDocEditor hook
53
+ * Return type for useAIDocEditor hook (single document)
54
+ * @deprecated Use UseAIMultiTabDocEditorReturn for multi-tab support
52
55
  */
53
56
  export interface UseAIDocEditorReturn {
54
57
  /**
@@ -81,8 +84,73 @@ export interface UseAIDocEditorReturn {
81
84
  }
82
85
 
83
86
  /**
84
- * Hook for managing document annotations
87
+ * Return type for multi-tab document editor hook
88
+ */
89
+ export interface UseAIMultiTabDocEditorReturn {
90
+ /**
91
+ * Array of open documents
92
+ */
93
+ documents: DocumentWithAnnotations[]
94
+
95
+ /**
96
+ * ID of currently active document
97
+ */
98
+ activeDocumentId?: string
99
+
100
+ /**
101
+ * Add a new document tab
102
+ * @param file - Document metadata
103
+ * @param content - Initial document content
104
+ */
105
+ addDocument: (file: DocumentFile, content: JSONContent | string) => void,
106
+
107
+ /**
108
+ * Close a document tab
109
+ * @param documentId - ID of the document to close
110
+ */
111
+ closeDocument: (documentId: string) => void
112
+
113
+ /**
114
+ * Switch to a different document tab
115
+ * @param documentId - ID of the document to switch to
116
+ */
117
+ switchDocument: (documentId: string) => void
118
+
119
+ /**
120
+ * Add annotation to the currently active document
121
+ * @param annotation - The annotation to add
122
+ */
123
+ addAnnotation: (annotation: Annotation) => Promise<void> | void
124
+
125
+ /**
126
+ * Update annotation in the currently active document
127
+ * @param annotation - The updated annotation
128
+ */
129
+ updateAnnotation: (annotation: Annotation) => Promise<void> | void
130
+
131
+ /**
132
+ * Delete annotation from the currently active document
133
+ * @param annotationId - ID of the annotation to delete
134
+ */
135
+ deleteAnnotation: (annotationId: string) => Promise<void> | void
136
+
137
+ /**
138
+ * Mark document as dirty
139
+ * @param documentId - ID of the document
140
+ * @param isDirty - Whether document has unsaved changes
141
+ */
142
+ setDocumentDirty: (documentId: string, isDirty: boolean) => void
143
+
144
+ /**
145
+ * Loading state for async operations
146
+ */
147
+ loading: boolean
148
+ }
149
+
150
+ /**
151
+ * Hook for managing document annotations (single document, backward compatible)
85
152
  *
153
+ * @deprecated Use useAIMultiTabDocEditor for multi-tab support
86
154
  * Applications must implement this hook to provide real data management.
87
155
  * The hook should handle:
88
156
  * - Fetching annotations from API
@@ -95,3 +163,18 @@ export interface UseAIDocEditorReturn {
95
163
  * @returns Object containing annotations array and mutation methods
96
164
  */
97
165
  export function useAIDocEditor(documentId: string): UseAIDocEditorReturn
166
+
167
+ /**
168
+ * Hook for managing multi-tab documents with annotations
169
+ *
170
+ * Applications must implement this hook to provide real data management.
171
+ * The hook should handle:
172
+ * - Managing multiple open documents
173
+ * - Tracking active document
174
+ * - Fetching/creating annotations per document
175
+ * - Document dirty state tracking
176
+ * - Adding/removing document tabs
177
+ *
178
+ * @returns Object containing documents array, active document ID, and mutation methods
179
+ */
180
+ export function useAIMultiTabDocEditor(): UseAIMultiTabDocEditorReturn
@@ -7,33 +7,26 @@
7
7
 
8
8
  import { useState, useCallback } from 'react'
9
9
  import type { Annotation } from '@/types/ai-editor/annotations'
10
- import type { UseAIDocEditorReturn } from './useAIDocEditor'
10
+ import type { DocumentFile, DocumentWithAnnotations } from '@/types/ai-editor'
11
+ import type { UseAIDocEditorReturn, UseAIMultiTabDocEditorReturn } from './useAIDocEditor'
11
12
 
12
- /**
13
- * Mock hook for managing document annotations in Storybook
14
- *
15
- * Simulates async operations with setTimeout to demonstrate loading states
16
- * and realistic user interactions.
17
- *
18
- * @param initialAnnotations - Initial annotations to display
19
- * @returns Mock implementation of UseAIDocEditorReturn
20
- */
21
- export function useAIDocEditorMock(
22
- initialAnnotations: Annotation[] = []
13
+ type MultiDocMockConfig = {
14
+ multiDoc: true
15
+ initialDocuments?: DocumentWithAnnotations[]
16
+ }
17
+
18
+ function useSingleDocEditorMockState(
19
+ initialAnnotations: Annotation[]
23
20
  ): UseAIDocEditorReturn {
24
21
  const [annotations, setAnnotations] = useState<Annotation[]>(initialAnnotations)
25
22
  const [loading, setLoading] = useState(false)
26
23
 
27
- /**
28
- * Add a new annotation with simulated async delay
29
- */
30
24
  const addAnnotation = useCallback(async (annotation: Annotation) => {
31
25
  console.log('[AIDocEditor Mock] Adding annotation:', annotation)
32
26
  setLoading(true)
33
-
34
- // Simulate API call delay
27
+
35
28
  await new Promise(resolve => setTimeout(resolve, 500))
36
-
29
+
37
30
  setAnnotations(prev => {
38
31
  const updated = [...prev, annotation]
39
32
  console.log('[AIDocEditor Mock] Annotations after add:', updated)
@@ -42,16 +35,12 @@ export function useAIDocEditorMock(
42
35
  setLoading(false)
43
36
  }, [])
44
37
 
45
- /**
46
- * Update an existing annotation with simulated async delay
47
- */
48
38
  const updateAnnotation = useCallback(async (annotation: Annotation) => {
49
39
  console.log('[AIDocEditor Mock] Updating annotation:', annotation)
50
40
  setLoading(true)
51
-
52
- // Simulate API call delay
41
+
53
42
  await new Promise(resolve => setTimeout(resolve, 500))
54
-
43
+
55
44
  setAnnotations(prev => {
56
45
  const updated = prev.map(a => (a.id === annotation.id ? annotation : a))
57
46
  console.log('[AIDocEditor Mock] Annotations after update:', updated)
@@ -60,15 +49,11 @@ export function useAIDocEditorMock(
60
49
  setLoading(false)
61
50
  }, [])
62
51
 
63
- /**
64
- * Delete an annotation with simulated async delay
65
- */
66
52
  const deleteAnnotation = useCallback(async (annotationId: string) => {
67
53
  setLoading(true)
68
-
69
- // Simulate API call delay
54
+
70
55
  await new Promise(resolve => setTimeout(resolve, 500))
71
-
56
+
72
57
  setAnnotations(prev => prev.filter(a => a.id !== annotationId))
73
58
  setLoading(false)
74
59
  }, [])
@@ -81,3 +66,167 @@ export function useAIDocEditorMock(
81
66
  loading,
82
67
  }
83
68
  }
69
+
70
+ function useMultiTabDocEditorMockState(
71
+ initialDocuments: DocumentWithAnnotations[]
72
+ ): UseAIMultiTabDocEditorReturn {
73
+ const [documents, setDocuments] = useState(initialDocuments)
74
+ const [activeDocumentId, setActiveDocumentId] = useState<string | undefined>(
75
+ initialDocuments[0]?.file.id
76
+ )
77
+ const [loading, setLoading] = useState(false)
78
+
79
+ const addDocument = useCallback((file: DocumentFile, content: any) => {
80
+ console.log('[Multi-Tab Mock] Adding document:', file.name)
81
+ setDocuments(prev => [...prev, { file, content, annotations: [] }])
82
+ setActiveDocumentId(file.id)
83
+ }, [])
84
+
85
+ const closeDocument = useCallback((documentId: string) => {
86
+ console.log('[Multi-Tab Mock] Closing document:', documentId)
87
+ setDocuments(prev => {
88
+ const filtered = prev.filter(doc => doc.file.id !== documentId)
89
+ if (activeDocumentId === documentId && filtered.length > 0) {
90
+ setActiveDocumentId(filtered[0].file.id)
91
+ }
92
+ if (filtered.length === 0) {
93
+ setActiveDocumentId(undefined)
94
+ }
95
+ return filtered
96
+ })
97
+ }, [activeDocumentId])
98
+
99
+ const switchDocument = useCallback((documentId: string) => {
100
+ console.log('[Multi-Tab Mock] Switching to document:', documentId)
101
+ setActiveDocumentId(documentId)
102
+ }, [])
103
+
104
+ const addAnnotation = useCallback(async (annotation: Annotation) => {
105
+ if (!activeDocumentId) {
106
+ return
107
+ }
108
+
109
+ setLoading(true)
110
+ await new Promise(resolve => setTimeout(resolve, 500))
111
+
112
+ setDocuments(prev =>
113
+ prev.map(doc =>
114
+ doc.file.id === activeDocumentId
115
+ ? { ...doc, annotations: [...doc.annotations, annotation] }
116
+ : doc
117
+ )
118
+ )
119
+ setLoading(false)
120
+ }, [activeDocumentId])
121
+
122
+ const updateAnnotation = useCallback(async (annotation: Annotation) => {
123
+ if (!activeDocumentId) {
124
+ return
125
+ }
126
+
127
+ setLoading(true)
128
+ await new Promise(resolve => setTimeout(resolve, 500))
129
+
130
+ setDocuments(prev =>
131
+ prev.map(doc =>
132
+ doc.file.id === activeDocumentId
133
+ ? {
134
+ ...doc,
135
+ annotations: doc.annotations.map(a =>
136
+ a.id === annotation.id ? annotation : a
137
+ ),
138
+ }
139
+ : doc
140
+ )
141
+ )
142
+ setLoading(false)
143
+ }, [activeDocumentId])
144
+
145
+ const deleteAnnotation = useCallback(async (annotationId: string) => {
146
+ if (!activeDocumentId) {
147
+ return
148
+ }
149
+
150
+ setLoading(true)
151
+ await new Promise(resolve => setTimeout(resolve, 500))
152
+
153
+ setDocuments(prev =>
154
+ prev.map(doc =>
155
+ doc.file.id === activeDocumentId
156
+ ? {
157
+ ...doc,
158
+ annotations: doc.annotations.filter(a => a.id !== annotationId),
159
+ }
160
+ : doc
161
+ )
162
+ )
163
+ setLoading(false)
164
+ }, [activeDocumentId])
165
+
166
+ const setDocumentDirty = useCallback((documentId: string, isDirty: boolean) => {
167
+ setDocuments(prev =>
168
+ prev.map(doc =>
169
+ doc.file.id === documentId
170
+ ? { ...doc, file: { ...doc.file, isDirty } }
171
+ : doc
172
+ )
173
+ )
174
+ }, [])
175
+
176
+ return {
177
+ documents,
178
+ activeDocumentId,
179
+ addDocument,
180
+ closeDocument,
181
+ switchDocument,
182
+ addAnnotation,
183
+ updateAnnotation,
184
+ deleteAnnotation,
185
+ setDocumentDirty,
186
+ loading,
187
+ }
188
+ }
189
+
190
+ /**
191
+ * Mock hook for managing document annotations in Storybook
192
+ *
193
+ * Simulates async operations with setTimeout to demonstrate loading states
194
+ * and realistic user interactions.
195
+ *
196
+ * @param initialAnnotations - Initial annotations to display
197
+ * @returns Mock implementation of UseAIDocEditorReturn
198
+ */
199
+ export function useAIDocEditorMock(
200
+ initialAnnotations: Annotation[]
201
+ ): UseAIDocEditorReturn
202
+ export function useAIDocEditorMock(config: MultiDocMockConfig): UseAIMultiTabDocEditorReturn
203
+ export function useAIDocEditorMock(
204
+ initialAnnotationsOrConfig: Annotation[] | MultiDocMockConfig = []
205
+ ): UseAIDocEditorReturn | UseAIMultiTabDocEditorReturn {
206
+ const isMultiDoc = !Array.isArray(initialAnnotationsOrConfig) && initialAnnotationsOrConfig.multiDoc === true
207
+ const singleInitialAnnotations = Array.isArray(initialAnnotationsOrConfig) ? initialAnnotationsOrConfig : []
208
+ const multiInitialDocuments = !Array.isArray(initialAnnotationsOrConfig)
209
+ ? (initialAnnotationsOrConfig.initialDocuments ?? [])
210
+ : []
211
+
212
+ const singleState = useSingleDocEditorMockState(singleInitialAnnotations)
213
+ const multiState = useMultiTabDocEditorMockState(multiInitialDocuments)
214
+
215
+ if (isMultiDoc) {
216
+ return multiState
217
+ }
218
+
219
+ return singleState
220
+ }
221
+
222
+ /**
223
+ * Mock hook for managing multi-tab documents in Storybook
224
+ *
225
+ * Simulates multi-document state management with tab switching, closing, and annotation updates.
226
+ *
227
+ * @param initialDocuments - Initial documents to display
228
+ * @returns Mock implementation of UseAIMultiTabDocEditorReturn
229
+ */
230
+ export function useAIMultiTabDocEditorMock(initialDocuments: any[] = []): UseAIMultiTabDocEditorReturn {
231
+ return useMultiTabDocEditorMockState(initialDocuments as DocumentWithAnnotations[])
232
+ }
package/dist/index.cjs CHANGED
@@ -6479,6 +6479,85 @@ var ModeToggle = React33__namespace.memo(({ className }) => {
6479
6479
  ] });
6480
6480
  });
6481
6481
  ModeToggle.displayName = "ModeToggle";
6482
+ var DocumentTabBar = React33__namespace.default.memo(
6483
+ ({ tabs, activeTabId, onTabSelect, onTabClose, className }) => {
6484
+ var _a;
6485
+ if (tabs.length === 0) {
6486
+ return null;
6487
+ }
6488
+ return /* @__PURE__ */ jsxRuntime.jsx(
6489
+ "div",
6490
+ {
6491
+ className: cn(
6492
+ "flex items-center border-b border-border bg-background",
6493
+ className
6494
+ ),
6495
+ "data-slot": "document-tab-bar",
6496
+ children: /* @__PURE__ */ jsxRuntime.jsx(ScrollArea2, { orientation: "horizontal", className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
6497
+ Tabs2,
6498
+ {
6499
+ value: activeTabId || ((_a = tabs[0]) == null ? void 0 : _a.id),
6500
+ onValueChange: onTabSelect,
6501
+ className: "h-auto flex-1",
6502
+ children: /* @__PURE__ */ jsxRuntime.jsx(TabsList, { className: "h-10 rounded-none border-none bg-transparent p-0 w-full justify-start gap-0", children: tabs.map((tab) => /* @__PURE__ */ jsxRuntime.jsxs(
6503
+ "div",
6504
+ {
6505
+ className: "flex items-center border-r border-border/50 last:border-r-0",
6506
+ children: [
6507
+ /* @__PURE__ */ jsxRuntime.jsx(
6508
+ TabsTrigger,
6509
+ {
6510
+ value: tab.id,
6511
+ className: cn(
6512
+ "data-[state=inactive]:bg-muted/20 data-[state=inactive]:text-muted-foreground",
6513
+ "rounded-none border-b-2 border-transparent data-[state=active]:border-primary",
6514
+ "px-3 py-2 text-sm font-medium whitespace-nowrap",
6515
+ "flex items-center gap-2 h-10",
6516
+ "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-0",
6517
+ "transition-colors"
6518
+ ),
6519
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
6520
+ tab.isDirty && /* @__PURE__ */ jsxRuntime.jsx(
6521
+ lucideReact.Circle,
6522
+ {
6523
+ className: "size-2 fill-primary text-primary flex-shrink-0",
6524
+ "aria-label": "unsaved changes"
6525
+ }
6526
+ ),
6527
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate max-w-[200px]", children: tab.name })
6528
+ ] })
6529
+ }
6530
+ ),
6531
+ /* @__PURE__ */ jsxRuntime.jsx(
6532
+ Button2,
6533
+ {
6534
+ variant: "ghost",
6535
+ size: "icon-sm",
6536
+ onClick: (e) => {
6537
+ e.stopPropagation();
6538
+ onTabClose == null ? void 0 : onTabClose(tab.id);
6539
+ },
6540
+ className: cn(
6541
+ "h-8 w-8 mr-0.5",
6542
+ "hover:bg-destructive/10 hover:text-destructive",
6543
+ "focus-visible:ring-2 focus-visible:ring-ring",
6544
+ "transition-colors"
6545
+ ),
6546
+ "aria-label": `Close ${tab.name}`,
6547
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-3" })
6548
+ }
6549
+ )
6550
+ ]
6551
+ },
6552
+ tab.id
6553
+ )) })
6554
+ }
6555
+ ) })
6556
+ }
6557
+ );
6558
+ }
6559
+ );
6560
+ DocumentTabBar.displayName = "DocumentTabBar";
6482
6561
  var ThemeSelector = React33__namespace.memo(
6483
6562
  ({ themes, value, onValueChange, placeholder = "Select theme", className }) => {
6484
6563
  return /* @__PURE__ */ jsxRuntime.jsxs(Select2, { value, onValueChange, children: [
@@ -6797,25 +6876,27 @@ var AdjustableLayout = React33__namespace.memo(
6797
6876
  muted: "group-hover:bg-muted/30"
6798
6877
  };
6799
6878
  const containerRef = React33__namespace.useRef(null);
6800
- const [sizes, setSizes] = React33__namespace.useState(() => {
6801
- if (storageKey && typeof window !== "undefined") {
6802
- const saved = localStorage.getItem(storageKey);
6803
- if (saved) {
6804
- try {
6805
- return JSON.parse(saved);
6806
- } catch (e) {
6807
- }
6879
+ const defaultSizes = React33__namespace.useMemo(() => {
6880
+ const raw = sections.map((section) => {
6881
+ var _a2;
6882
+ return (_a2 = section.defaultSize) != null ? _a2 : 100 / sections.length;
6883
+ });
6884
+ const total = raw.reduce((sum, size) => sum + size, 0);
6885
+ return raw.map((size) => size / total * 100);
6886
+ }, [sections]);
6887
+ const [sizes, setSizes] = React33__namespace.useState(defaultSizes);
6888
+ React33__namespace.useEffect(() => {
6889
+ if (!storageKey) return;
6890
+ const saved = localStorage.getItem(storageKey);
6891
+ if (!saved) return;
6892
+ try {
6893
+ const parsed = JSON.parse(saved);
6894
+ if (Array.isArray(parsed) && parsed.length === sections.length) {
6895
+ setSizes(parsed);
6808
6896
  }
6897
+ } catch (e) {
6809
6898
  }
6810
- const defaultSizes = sections.map(
6811
- (section) => {
6812
- var _a2;
6813
- return (_a2 = section.defaultSize) != null ? _a2 : 100 / sections.length;
6814
- }
6815
- );
6816
- const total = defaultSizes.reduce((sum, size) => sum + size, 0);
6817
- return defaultSizes.map((size) => size / total * 100);
6818
- });
6899
+ }, [storageKey]);
6819
6900
  const [draggingIndex, setDraggingIndex] = React33__namespace.useState(null);
6820
6901
  const [startX, setStartX] = React33__namespace.useState(0);
6821
6902
  const [startSizes, setStartSizes] = React33__namespace.useState([]);
@@ -8065,18 +8146,28 @@ var SpecNavigator = React33__namespace.memo(
8065
8146
  }
8066
8147
  );
8067
8148
  SpecNavigator.displayName = "SpecNavigator";
8149
+ function isMultiTabMode(props) {
8150
+ return "documents" in props && props.documents !== void 0;
8151
+ }
8068
8152
  var AIDocEditor = React33__namespace.default.memo(
8069
- ({
8070
- content,
8071
- format = "json",
8072
- annotations,
8073
- selectedAnnotationId,
8074
- currentUser,
8075
- mode,
8076
- onAnnotationAdd,
8077
- onAnnotationUpdate,
8078
- className
8079
- }) => {
8153
+ (props) => {
8154
+ var _a, _b;
8155
+ const {
8156
+ currentUser: currentUser2,
8157
+ mode,
8158
+ onAnnotationAdd,
8159
+ onAnnotationUpdate,
8160
+ onAnnotationDelete: _onAnnotationDelete,
8161
+ // Callback for consumers; passed through on demand
8162
+ className
8163
+ } = props;
8164
+ const isMultiTab = isMultiTabMode(props);
8165
+ const currentDocument = React33.useMemo(() => {
8166
+ if (isMultiTab && props.documents) {
8167
+ return props.documents.find((doc) => doc.file.id === props.activeDocumentId) || props.documents[0];
8168
+ }
8169
+ return null;
8170
+ }, [isMultiTab, props]);
8080
8171
  const handleAnnotationAdd = React33.useCallback(
8081
8172
  (annotation) => {
8082
8173
  onAnnotationAdd == null ? void 0 : onAnnotationAdd(annotation);
@@ -8089,21 +8180,62 @@ var AIDocEditor = React33__namespace.default.memo(
8089
8180
  },
8090
8181
  [onAnnotationUpdate]
8091
8182
  );
8092
- return /* @__PURE__ */ jsxRuntime.jsx(
8093
- DocumentEditorWithComments,
8094
- {
8095
- content,
8096
- format,
8097
- annotations,
8098
- selectedAnnotationId,
8099
- currentUserId: currentUser.id,
8100
- currentUserName: currentUser.name,
8101
- readOnly: mode === "readonly",
8102
- onAnnotationAdd: handleAnnotationAdd,
8103
- onAnnotationUpdate: handleAnnotationUpdate,
8104
- className: cn("ai-doc-editor p-6", className)
8105
- }
8106
- );
8183
+ if (!isMultiTab) {
8184
+ return /* @__PURE__ */ jsxRuntime.jsx(
8185
+ DocumentEditorWithComments,
8186
+ {
8187
+ content: props.content,
8188
+ format: props.format,
8189
+ annotations: props.annotations,
8190
+ selectedAnnotationId: props.selectedAnnotationId,
8191
+ currentUserId: currentUser2.id,
8192
+ currentUserName: currentUser2.name,
8193
+ readOnly: mode === "readonly",
8194
+ onAnnotationAdd: handleAnnotationAdd,
8195
+ onAnnotationUpdate: handleAnnotationUpdate,
8196
+ className: cn("ai-doc-editor p-6", className)
8197
+ }
8198
+ );
8199
+ }
8200
+ if (!currentDocument) {
8201
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("ai-doc-editor flex flex-col h-full", className), children: [
8202
+ /* @__PURE__ */ jsxRuntime.jsx(
8203
+ DocumentTabBar,
8204
+ {
8205
+ tabs: ((_a = props.documents) == null ? void 0 : _a.map((doc) => doc.file)) || [],
8206
+ activeTabId: props.activeDocumentId,
8207
+ onTabSelect: props.onTabSelect,
8208
+ onTabClose: props.onTabClose
8209
+ }
8210
+ ),
8211
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex items-center justify-center p-6 text-muted-foreground", children: "No documents open" })
8212
+ ] });
8213
+ }
8214
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("ai-doc-editor flex flex-col h-full", className), children: [
8215
+ /* @__PURE__ */ jsxRuntime.jsx(
8216
+ DocumentTabBar,
8217
+ {
8218
+ tabs: ((_b = props.documents) == null ? void 0 : _b.map((doc) => doc.file)) || [],
8219
+ activeTabId: props.activeDocumentId,
8220
+ onTabSelect: props.onTabSelect,
8221
+ onTabClose: props.onTabClose
8222
+ }
8223
+ ),
8224
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
8225
+ DocumentEditorWithComments,
8226
+ {
8227
+ content: currentDocument.content,
8228
+ format: currentDocument.file.format,
8229
+ annotations: currentDocument.annotations,
8230
+ currentUserId: currentUser2.id,
8231
+ currentUserName: currentUser2.name,
8232
+ readOnly: mode === "readonly",
8233
+ onAnnotationAdd: handleAnnotationAdd,
8234
+ onAnnotationUpdate: handleAnnotationUpdate,
8235
+ className: "p-6"
8236
+ }
8237
+ ) })
8238
+ ] });
8107
8239
  }
8108
8240
  );
8109
8241
  AIDocEditor.displayName = "AIDocEditor";
@@ -8244,6 +8376,7 @@ exports.DialogTitle = DialogTitle;
8244
8376
  exports.DialogTrigger = DialogTrigger;
8245
8377
  exports.DocumentEditor = DocumentEditor;
8246
8378
  exports.DocumentEditorWithComments = DocumentEditorWithComments;
8379
+ exports.DocumentTabBar = DocumentTabBar;
8247
8380
  exports.Drawer = Drawer2;
8248
8381
  exports.DrawerClose = DrawerClose2;
8249
8382
  exports.DrawerContent = DrawerContent2;