@cou.sh/nuxt 1.0.1

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 (151) hide show
  1. package/README.md +84 -0
  2. package/dist/module.d.mts +49 -0
  3. package/dist/module.json +12 -0
  4. package/dist/module.mjs +126 -0
  5. package/dist/runtime/components/ActivityTimeline.d.vue.ts +17 -0
  6. package/dist/runtime/components/ActivityTimeline.vue +108 -0
  7. package/dist/runtime/components/ActivityTimeline.vue.d.ts +17 -0
  8. package/dist/runtime/components/AuthForm.d.vue.ts +20 -0
  9. package/dist/runtime/components/AuthForm.vue +78 -0
  10. package/dist/runtime/components/AuthForm.vue.d.ts +20 -0
  11. package/dist/runtime/components/CommentThread.d.vue.ts +10 -0
  12. package/dist/runtime/components/CommentThread.vue +149 -0
  13. package/dist/runtime/components/CommentThread.vue.d.ts +10 -0
  14. package/dist/runtime/components/ConnectionStatus.d.vue.ts +13 -0
  15. package/dist/runtime/components/ConnectionStatus.vue +27 -0
  16. package/dist/runtime/components/ConnectionStatus.vue.d.ts +13 -0
  17. package/dist/runtime/components/DocumentBreadcrumb.d.vue.ts +13 -0
  18. package/dist/runtime/components/DocumentBreadcrumb.vue +38 -0
  19. package/dist/runtime/components/DocumentBreadcrumb.vue.d.ts +13 -0
  20. package/dist/runtime/components/DocumentCard.d.vue.ts +30 -0
  21. package/dist/runtime/components/DocumentCard.vue +88 -0
  22. package/dist/runtime/components/DocumentCard.vue.d.ts +30 -0
  23. package/dist/runtime/components/DocumentSearchPalette.d.vue.ts +22 -0
  24. package/dist/runtime/components/DocumentSearchPalette.vue +99 -0
  25. package/dist/runtime/components/DocumentSearchPalette.vue.d.ts +22 -0
  26. package/dist/runtime/components/DocumentTree.d.vue.ts +32 -0
  27. package/dist/runtime/components/DocumentTree.vue +497 -0
  28. package/dist/runtime/components/DocumentTree.vue.d.ts +32 -0
  29. package/dist/runtime/components/Editor.d.vue.ts +11 -0
  30. package/dist/runtime/components/Editor.vue +328 -0
  31. package/dist/runtime/components/Editor.vue.d.ts +11 -0
  32. package/dist/runtime/components/ExportMenu.d.vue.ts +9 -0
  33. package/dist/runtime/components/ExportMenu.vue +55 -0
  34. package/dist/runtime/components/ExportMenu.vue.d.ts +9 -0
  35. package/dist/runtime/components/FileUploader.d.vue.ts +22 -0
  36. package/dist/runtime/components/FileUploader.vue +148 -0
  37. package/dist/runtime/components/FileUploader.vue.d.ts +22 -0
  38. package/dist/runtime/components/MemberManager.d.vue.ts +9 -0
  39. package/dist/runtime/components/MemberManager.vue +153 -0
  40. package/dist/runtime/components/MemberManager.vue.d.ts +9 -0
  41. package/dist/runtime/components/OfflineIndicator.d.vue.ts +9 -0
  42. package/dist/runtime/components/OfflineIndicator.vue +44 -0
  43. package/dist/runtime/components/OfflineIndicator.vue.d.ts +9 -0
  44. package/dist/runtime/components/PermissionGuard.d.vue.ts +25 -0
  45. package/dist/runtime/components/PermissionGuard.vue +16 -0
  46. package/dist/runtime/components/PermissionGuard.vue.d.ts +25 -0
  47. package/dist/runtime/components/RoleBadge.d.vue.ts +11 -0
  48. package/dist/runtime/components/RoleBadge.vue +30 -0
  49. package/dist/runtime/components/RoleBadge.vue.d.ts +11 -0
  50. package/dist/runtime/components/ShareDialog.d.vue.ts +15 -0
  51. package/dist/runtime/components/ShareDialog.vue +119 -0
  52. package/dist/runtime/components/ShareDialog.vue.d.ts +15 -0
  53. package/dist/runtime/components/SnapshotTimeline.d.vue.ts +15 -0
  54. package/dist/runtime/components/SnapshotTimeline.vue +118 -0
  55. package/dist/runtime/components/SnapshotTimeline.vue.d.ts +15 -0
  56. package/dist/runtime/components/SpaceSettings.d.vue.ts +7 -0
  57. package/dist/runtime/components/SpaceSettings.vue +105 -0
  58. package/dist/runtime/components/SpaceSettings.vue.d.ts +7 -0
  59. package/dist/runtime/components/SpaceSwitcher.d.vue.ts +18 -0
  60. package/dist/runtime/components/SpaceSwitcher.vue +104 -0
  61. package/dist/runtime/components/SpaceSwitcher.vue.d.ts +18 -0
  62. package/dist/runtime/components/TrashBin.d.vue.ts +7 -0
  63. package/dist/runtime/components/TrashBin.vue +159 -0
  64. package/dist/runtime/components/TrashBin.vue.d.ts +7 -0
  65. package/dist/runtime/components/UserMenu.d.vue.ts +13 -0
  66. package/dist/runtime/components/UserMenu.vue +50 -0
  67. package/dist/runtime/components/UserMenu.vue.d.ts +13 -0
  68. package/dist/runtime/components/UserPresence.d.vue.ts +13 -0
  69. package/dist/runtime/components/UserPresence.vue +34 -0
  70. package/dist/runtime/components/UserPresence.vue.d.ts +13 -0
  71. package/dist/runtime/components/editor/CollaborationUsers.d.vue.ts +7 -0
  72. package/dist/runtime/components/editor/CollaborationUsers.vue +31 -0
  73. package/dist/runtime/components/editor/CollaborationUsers.vue.d.ts +7 -0
  74. package/dist/runtime/components/editor/CompletionExtension.d.ts +43 -0
  75. package/dist/runtime/components/editor/CompletionExtension.js +133 -0
  76. package/dist/runtime/components/editor/ImageUploadExtension.d.ts +10 -0
  77. package/dist/runtime/components/editor/ImageUploadExtension.js +31 -0
  78. package/dist/runtime/components/editor/ImageUploadNode.d.vue.ts +4 -0
  79. package/dist/runtime/components/editor/ImageUploadNode.vue +59 -0
  80. package/dist/runtime/components/editor/ImageUploadNode.vue.d.ts +4 -0
  81. package/dist/runtime/components/editor/LinkPopover.d.vue.ts +8 -0
  82. package/dist/runtime/components/editor/LinkPopover.vue +131 -0
  83. package/dist/runtime/components/editor/LinkPopover.vue.d.ts +8 -0
  84. package/dist/runtime/components/widgets/ButtonWidget.d.vue.ts +4 -0
  85. package/dist/runtime/components/widgets/ButtonWidget.vue +32 -0
  86. package/dist/runtime/components/widgets/ButtonWidget.vue.d.ts +4 -0
  87. package/dist/runtime/components/widgets/CalendarWidget.d.vue.ts +4 -0
  88. package/dist/runtime/components/widgets/CalendarWidget.vue +36 -0
  89. package/dist/runtime/components/widgets/CalendarWidget.vue.d.ts +4 -0
  90. package/dist/runtime/components/widgets/CheckboxWidget.d.vue.ts +4 -0
  91. package/dist/runtime/components/widgets/CheckboxWidget.vue +32 -0
  92. package/dist/runtime/components/widgets/CheckboxWidget.vue.d.ts +4 -0
  93. package/dist/runtime/components/widgets/ColorPickerWidget.d.vue.ts +4 -0
  94. package/dist/runtime/components/widgets/ColorPickerWidget.vue +30 -0
  95. package/dist/runtime/components/widgets/ColorPickerWidget.vue.d.ts +4 -0
  96. package/dist/runtime/components/widgets/IconWidget.d.vue.ts +4 -0
  97. package/dist/runtime/components/widgets/IconWidget.vue +102 -0
  98. package/dist/runtime/components/widgets/IconWidget.vue.d.ts +4 -0
  99. package/dist/runtime/components/widgets/InputDateWidget.d.vue.ts +4 -0
  100. package/dist/runtime/components/widgets/InputDateWidget.vue +38 -0
  101. package/dist/runtime/components/widgets/InputDateWidget.vue.d.ts +4 -0
  102. package/dist/runtime/components/widgets/ScrollAreaWidget.d.vue.ts +4 -0
  103. package/dist/runtime/components/widgets/ScrollAreaWidget.vue +41 -0
  104. package/dist/runtime/components/widgets/ScrollAreaWidget.vue.d.ts +4 -0
  105. package/dist/runtime/components/widgets/SliderWidget.d.vue.ts +4 -0
  106. package/dist/runtime/components/widgets/SliderWidget.vue +42 -0
  107. package/dist/runtime/components/widgets/SliderWidget.vue.d.ts +4 -0
  108. package/dist/runtime/components/widgets/SwitchWidget.d.vue.ts +4 -0
  109. package/dist/runtime/components/widgets/SwitchWidget.vue +35 -0
  110. package/dist/runtime/components/widgets/SwitchWidget.vue.d.ts +4 -0
  111. package/dist/runtime/components/widgets/TabPanelWidget.d.vue.ts +4 -0
  112. package/dist/runtime/components/widgets/TabPanelWidget.vue +22 -0
  113. package/dist/runtime/components/widgets/TabPanelWidget.vue.d.ts +4 -0
  114. package/dist/runtime/components/widgets/TabsWidget.d.vue.ts +4 -0
  115. package/dist/runtime/components/widgets/TabsWidget.vue +109 -0
  116. package/dist/runtime/components/widgets/TabsWidget.vue.d.ts +4 -0
  117. package/dist/runtime/components/widgets/index.d.ts +13 -0
  118. package/dist/runtime/components/widgets/index.js +278 -0
  119. package/dist/runtime/composables/index.d.ts +14 -0
  120. package/dist/runtime/composables/index.js +13 -0
  121. package/dist/runtime/composables/useCollabStatus.d.ts +10 -0
  122. package/dist/runtime/composables/useCollabStatus.js +23 -0
  123. package/dist/runtime/composables/useDocumentPermissions.d.ts +11 -0
  124. package/dist/runtime/composables/useDocumentPermissions.js +44 -0
  125. package/dist/runtime/composables/useEditorCollaboration.d.ts +25 -0
  126. package/dist/runtime/composables/useEditorCollaboration.js +141 -0
  127. package/dist/runtime/composables/useEditorCompletion.d.ts +60 -0
  128. package/dist/runtime/composables/useEditorCompletion.js +42 -0
  129. package/dist/runtime/composables/useEditorDragHandle.d.ts +10 -0
  130. package/dist/runtime/composables/useEditorDragHandle.js +130 -0
  131. package/dist/runtime/composables/useEditorEmojis.d.ts +4 -0
  132. package/dist/runtime/composables/useEditorEmojis.js +9 -0
  133. package/dist/runtime/composables/useEditorMentions.d.ts +4 -0
  134. package/dist/runtime/composables/useEditorMentions.js +27 -0
  135. package/dist/runtime/composables/useEditorSuggestions.d.ts +149 -0
  136. package/dist/runtime/composables/useEditorSuggestions.js +114 -0
  137. package/dist/runtime/composables/useEditorToolbar.d.ts +12 -0
  138. package/dist/runtime/composables/useEditorToolbar.js +194 -0
  139. package/dist/runtime/composables/useLucideIcons.d.ts +4 -0
  140. package/dist/runtime/composables/useLucideIcons.js +16 -0
  141. package/dist/runtime/composables/useOnlineStatus.d.ts +6 -0
  142. package/dist/runtime/composables/useOnlineStatus.js +44 -0
  143. package/dist/runtime/composables/useSpaces.d.ts +36 -0
  144. package/dist/runtime/composables/useSpaces.js +29 -0
  145. package/dist/runtime/middleware/collab-auth.d.ts +2 -0
  146. package/dist/runtime/middleware/collab-auth.js +18 -0
  147. package/dist/runtime/plugin.d.ts +7 -0
  148. package/dist/runtime/plugin.js +39 -0
  149. package/dist/runtime/server/tsconfig.json +3 -0
  150. package/dist/types.d.mts +3 -0
  151. package/package.json +66 -0
@@ -0,0 +1,149 @@
1
+ <script setup>
2
+ const props = defineProps({
3
+ spaceId: { type: String, required: true },
4
+ documentId: { type: String, required: true },
5
+ provider: { type: null, required: true }
6
+ });
7
+ const client = useCollabClient();
8
+ const toast = useToast();
9
+ const providerRef = computed(() => {
10
+ if (!props.provider) return null;
11
+ if ("value" in props.provider) return props.provider.value;
12
+ return props.provider;
13
+ });
14
+ const { threads, loading, createComment, refresh } = useLiveComments(
15
+ providerRef,
16
+ props.spaceId,
17
+ props.documentId
18
+ );
19
+ const input = ref("");
20
+ const submitting = ref(false);
21
+ async function onSubmit() {
22
+ if (!input.value.trim()) return;
23
+ submitting.value = true;
24
+ try {
25
+ await createComment(input.value.trim());
26
+ input.value = "";
27
+ } catch {
28
+ toast.add({ title: "Failed to post comment", color: "error" });
29
+ } finally {
30
+ submitting.value = false;
31
+ }
32
+ }
33
+ async function toggleResolve(thread) {
34
+ try {
35
+ await client.comments.resolve(
36
+ props.spaceId,
37
+ props.documentId,
38
+ thread.id,
39
+ !thread.resolved
40
+ );
41
+ await refresh();
42
+ } catch {
43
+ toast.add({ title: "Failed to update comment", color: "error" });
44
+ }
45
+ }
46
+ async function deleteComment(commentId) {
47
+ try {
48
+ await client.comments.delete(props.spaceId, props.documentId, commentId);
49
+ await refresh();
50
+ } catch {
51
+ toast.add({ title: "Failed to delete comment", color: "error" });
52
+ }
53
+ }
54
+ </script>
55
+
56
+ <template>
57
+ <div class="flex flex-col h-full">
58
+ <div class="flex items-center justify-between px-3 py-2">
59
+ <span class="text-sm font-medium">Comments</span>
60
+ <UBadge v-if="threads.length > 0" :label="String(threads.length)" variant="subtle" size="xs" />
61
+ </div>
62
+
63
+ <div class="flex-1 overflow-y-auto">
64
+ <USkeleton v-if="loading" class="h-20 m-3" />
65
+
66
+ <UEmpty
67
+ v-else-if="threads.length === 0"
68
+ icon="i-lucide-message-circle"
69
+ title="No comments"
70
+ description="Start a conversation"
71
+ size="sm"
72
+ />
73
+
74
+ <div v-else class="divide-y divide-(--ui-border)">
75
+ <div
76
+ v-for="thread in threads"
77
+ :key="thread.id"
78
+ class="p-3 space-y-3"
79
+ :class="{ 'opacity-50': thread.resolved }"
80
+ >
81
+ <!-- Thread root -->
82
+ <div class="flex gap-2">
83
+ <UAvatar :alt="thread.authorName" size="xs" />
84
+ <div class="flex-1 min-w-0 space-y-1">
85
+ <div class="flex items-center gap-1.5">
86
+ <span class="text-xs font-medium">{{ thread.authorName }}</span>
87
+ <span class="text-xs text-(--ui-text-muted)">{{ new Date(thread.createdAt).toLocaleString() }}</span>
88
+ </div>
89
+
90
+ <div
91
+ v-if="thread.anchor"
92
+ class="px-2 py-0.5 text-xs bg-(--ui-bg-elevated) border-l-2 border-(--ui-border-accented) rounded-sm text-(--ui-text-muted)"
93
+ >
94
+ "{{ thread.anchor.text }}"
95
+ </div>
96
+
97
+ <p class="text-sm">{{ thread.content }}</p>
98
+
99
+ <div class="flex items-center gap-0.5">
100
+ <UDropdownMenu :items="[
101
+ [
102
+ { label: thread.resolved ? 'Unresolve' : 'Resolve', icon: thread.resolved ? 'i-lucide-circle' : 'i-lucide-circle-check', onSelect: () => toggleResolve(thread) }
103
+ ],
104
+ [
105
+ { label: 'Delete', icon: 'i-lucide-trash-2', color: 'error', onSelect: () => deleteComment(thread.id) }
106
+ ]
107
+ ]">
108
+ <UButton icon="i-lucide-ellipsis" variant="ghost" color="neutral" size="2xs" />
109
+ </UDropdownMenu>
110
+
111
+ <UBadge v-if="thread.resolved" label="Resolved" color="success" variant="subtle" size="xs" />
112
+ </div>
113
+ </div>
114
+ </div>
115
+
116
+ <!-- Replies -->
117
+ <div
118
+ v-for="reply in thread.replies"
119
+ :key="reply.id"
120
+ class="flex gap-2 ml-7"
121
+ >
122
+ <UAvatar :alt="reply.authorName" size="2xs" />
123
+ <div class="flex-1 min-w-0 space-y-0.5">
124
+ <div class="flex items-center gap-1.5">
125
+ <span class="text-xs font-medium">{{ reply.authorName }}</span>
126
+ <span class="text-xs text-(--ui-text-muted)">{{ new Date(reply.createdAt).toLocaleString() }}</span>
127
+ </div>
128
+ <p class="text-sm">{{ reply.content }}</p>
129
+ </div>
130
+ </div>
131
+ </div>
132
+ </div>
133
+ </div>
134
+
135
+ <!-- Input -->
136
+ <div class="border-t border-(--ui-border)">
137
+ <UChatPrompt
138
+ v-model="input"
139
+ placeholder="Add a comment..."
140
+ variant="none"
141
+ :rows="1"
142
+ autoresize
143
+ @submit="onSubmit"
144
+ >
145
+ <UChatPromptSubmit :status="submitting ? 'submitted' : 'ready'" />
146
+ </UChatPrompt>
147
+ </div>
148
+ </div>
149
+ </template>
@@ -0,0 +1,10 @@
1
+ import type { ShallowRef } from "vue";
2
+ import type { CollabProvider } from "@rgby/collab-core";
3
+ type __VLS_Props = {
4
+ spaceId: string;
5
+ documentId: string;
6
+ provider: ShallowRef<CollabProvider | null> | CollabProvider | null;
7
+ };
8
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
9
+ declare const _default: typeof __VLS_export;
10
+ export default _default;
@@ -0,0 +1,13 @@
1
+ type __VLS_Props = {
2
+ /** WebSocket connection status */
3
+ status: "disconnected" | "connecting" | "connected";
4
+ /** Whether document is synced with server */
5
+ synced: boolean;
6
+ /** Display variant */
7
+ variant?: "badge" | "chip" | "dot";
8
+ };
9
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
10
+ variant: "badge" | "chip" | "dot";
11
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
+ declare const _default: typeof __VLS_export;
13
+ export default _default;
@@ -0,0 +1,27 @@
1
+ <script setup>
2
+ const props = defineProps({
3
+ status: { type: String, required: true },
4
+ synced: { type: Boolean, required: true },
5
+ variant: { type: String, required: false, default: "badge" }
6
+ });
7
+ const statusRef = computed(() => props.status);
8
+ const syncedRef = computed(() => props.synced);
9
+ const { label, color, icon } = useCollabStatus(statusRef, syncedRef);
10
+ </script>
11
+
12
+ <template>
13
+ <UBadge v-if="variant === 'badge'" :color="color" variant="subtle" size="sm">
14
+ <UIcon :name="icon" class="size-3.5" />
15
+ {{ label }}
16
+ </UBadge>
17
+
18
+ <UChip v-else-if="variant === 'chip'" :color="color" size="md">
19
+ <UTooltip :text="label">
20
+ <UIcon :name="icon" class="size-4" />
21
+ </UTooltip>
22
+ </UChip>
23
+
24
+ <UTooltip v-else :text="label">
25
+ <UChip :color="color" standalone />
26
+ </UTooltip>
27
+ </template>
@@ -0,0 +1,13 @@
1
+ type __VLS_Props = {
2
+ /** WebSocket connection status */
3
+ status: "disconnected" | "connecting" | "connected";
4
+ /** Whether document is synced with server */
5
+ synced: boolean;
6
+ /** Display variant */
7
+ variant?: "badge" | "chip" | "dot";
8
+ };
9
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
10
+ variant: "badge" | "chip" | "dot";
11
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
+ declare const _default: typeof __VLS_export;
13
+ export default _default;
@@ -0,0 +1,13 @@
1
+ type __VLS_Props = {
2
+ /** Space ID */
3
+ spaceId: string;
4
+ /** Current document ID */
5
+ documentId: string;
6
+ };
7
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
8
+ navigate: (docId: string) => any;
9
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
10
+ onNavigate?: ((docId: string) => any) | undefined;
11
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
+ declare const _default: typeof __VLS_export;
13
+ export default _default;
@@ -0,0 +1,38 @@
1
+ <script setup>
2
+ const props = defineProps({
3
+ spaceId: { type: String, required: true },
4
+ documentId: { type: String, required: true }
5
+ });
6
+ const emit = defineEmits(["navigate"]);
7
+ const client = useCollabClient();
8
+ const ancestors = ref([]);
9
+ const loading = ref(true);
10
+ const breadcrumbItems = computed(() => {
11
+ const items = ancestors.value.map((doc) => ({
12
+ label: doc.name || "Untitled",
13
+ icon: "i-lucide-file-text",
14
+ click: () => emit("navigate", doc.id)
15
+ }));
16
+ return items;
17
+ });
18
+ async function loadAncestors() {
19
+ loading.value = true;
20
+ try {
21
+ ancestors.value = await client.documents.ancestors(props.spaceId, props.documentId);
22
+ } catch {
23
+ ancestors.value = [];
24
+ } finally {
25
+ loading.value = false;
26
+ }
27
+ }
28
+ watch(
29
+ () => [props.spaceId, props.documentId],
30
+ loadAncestors,
31
+ { immediate: true }
32
+ );
33
+ </script>
34
+
35
+ <template>
36
+ <USkeleton v-if="loading" class="h-5 w-48" />
37
+ <UBreadcrumb v-else :items="breadcrumbItems" />
38
+ </template>
@@ -0,0 +1,13 @@
1
+ type __VLS_Props = {
2
+ /** Space ID */
3
+ spaceId: string;
4
+ /** Current document ID */
5
+ documentId: string;
6
+ };
7
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
8
+ navigate: (docId: string) => any;
9
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
10
+ onNavigate?: ((docId: string) => any) | undefined;
11
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
+ declare const _default: typeof __VLS_export;
13
+ export default _default;
@@ -0,0 +1,30 @@
1
+ import type { Document } from "@rgby/collab-core";
2
+ export interface DocumentCardAction {
3
+ label: string;
4
+ icon?: string;
5
+ color?: "primary" | "secondary" | "success" | "info" | "warning" | "error" | "neutral";
6
+ onSelect?: () => void;
7
+ }
8
+ type __VLS_Props = {
9
+ /** Document object */
10
+ document: Document;
11
+ /** Space ID the document belongs to */
12
+ spaceId: string;
13
+ /** Custom actions for context menu */
14
+ actions?: DocumentCardAction[];
15
+ };
16
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
17
+ open: (doc: Document) => any;
18
+ rename: (doc: Document) => any;
19
+ duplicate: (doc: Document) => any;
20
+ delete: (doc: Document) => any;
21
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
22
+ onOpen?: ((doc: Document) => any) | undefined;
23
+ onRename?: ((doc: Document) => any) | undefined;
24
+ onDuplicate?: ((doc: Document) => any) | undefined;
25
+ onDelete?: ((doc: Document) => any) | undefined;
26
+ }>, {
27
+ actions: DocumentCardAction[];
28
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
29
+ declare const _default: typeof __VLS_export;
30
+ export default _default;
@@ -0,0 +1,88 @@
1
+ <script setup>
2
+ const props = defineProps({
3
+ document: { type: Object, required: true },
4
+ spaceId: { type: String, required: true },
5
+ actions: { type: Array, required: false, default: () => [] }
6
+ });
7
+ const emit = defineEmits(["open", "rename", "duplicate", "delete"]);
8
+ const defaultActions = computed(() => [
9
+ [
10
+ {
11
+ label: "Open",
12
+ icon: "i-lucide-external-link",
13
+ onSelect: () => emit("open", props.document)
14
+ },
15
+ {
16
+ label: "Rename",
17
+ icon: "i-lucide-pencil",
18
+ onSelect: () => emit("rename", props.document)
19
+ },
20
+ {
21
+ label: "Duplicate",
22
+ icon: "i-lucide-copy",
23
+ onSelect: () => emit("duplicate", props.document)
24
+ }
25
+ ],
26
+ [
27
+ {
28
+ label: "Delete",
29
+ icon: "i-lucide-trash-2",
30
+ color: "error",
31
+ onSelect: () => emit("delete", props.document)
32
+ }
33
+ ]
34
+ ]);
35
+ const menuItems = computed(() => {
36
+ if (props.actions.length > 0) {
37
+ return props.actions;
38
+ }
39
+ return defaultActions.value;
40
+ });
41
+ const timeAgo = computed(() => {
42
+ if (!props.document.updatedAt) return "";
43
+ const date = new Date(props.document.updatedAt);
44
+ const now = /* @__PURE__ */ new Date();
45
+ const diffMs = now.getTime() - date.getTime();
46
+ const diffMins = Math.floor(diffMs / 6e4);
47
+ if (diffMins < 1) return "Just now";
48
+ if (diffMins < 60) return `${diffMins}m ago`;
49
+ const diffHours = Math.floor(diffMins / 60);
50
+ if (diffHours < 24) return `${diffHours}h ago`;
51
+ const diffDays = Math.floor(diffHours / 24);
52
+ if (diffDays < 30) return `${diffDays}d ago`;
53
+ return date.toLocaleDateString();
54
+ });
55
+ </script>
56
+
57
+ <template>
58
+ <UCard class="cursor-pointer" @click="emit('open', document)">
59
+ <template #header>
60
+ <div class="flex items-center justify-between">
61
+ <div class="flex items-center gap-2 min-w-0">
62
+ <UIcon name="i-lucide-file-text" class="size-4 shrink-0 text-(--ui-text-muted)" />
63
+ <span class="font-medium text-sm truncate">
64
+ {{ document.name || "Untitled" }}
65
+ </span>
66
+ </div>
67
+
68
+ <UDropdownMenu :items="menuItems">
69
+ <UButton
70
+ icon="i-lucide-ellipsis-vertical"
71
+ variant="ghost"
72
+ color="neutral"
73
+ size="xs"
74
+ @click.stop
75
+ />
76
+ </UDropdownMenu>
77
+ </div>
78
+ </template>
79
+
80
+ <div class="flex items-center justify-between text-xs text-(--ui-text-muted)">
81
+ <span v-if="timeAgo">{{ timeAgo }}</span>
82
+ <span v-if="document.childrenCount" class="flex items-center gap-1">
83
+ <UIcon name="i-lucide-folder" class="size-3" />
84
+ {{ document.childrenCount }}
85
+ </span>
86
+ </div>
87
+ </UCard>
88
+ </template>
@@ -0,0 +1,30 @@
1
+ import type { Document } from "@rgby/collab-core";
2
+ export interface DocumentCardAction {
3
+ label: string;
4
+ icon?: string;
5
+ color?: "primary" | "secondary" | "success" | "info" | "warning" | "error" | "neutral";
6
+ onSelect?: () => void;
7
+ }
8
+ type __VLS_Props = {
9
+ /** Document object */
10
+ document: Document;
11
+ /** Space ID the document belongs to */
12
+ spaceId: string;
13
+ /** Custom actions for context menu */
14
+ actions?: DocumentCardAction[];
15
+ };
16
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
17
+ open: (doc: Document) => any;
18
+ rename: (doc: Document) => any;
19
+ duplicate: (doc: Document) => any;
20
+ delete: (doc: Document) => any;
21
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
22
+ onOpen?: ((doc: Document) => any) | undefined;
23
+ onRename?: ((doc: Document) => any) | undefined;
24
+ onDuplicate?: ((doc: Document) => any) | undefined;
25
+ onDelete?: ((doc: Document) => any) | undefined;
26
+ }>, {
27
+ actions: DocumentCardAction[];
28
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
29
+ declare const _default: typeof __VLS_export;
30
+ export default _default;
@@ -0,0 +1,22 @@
1
+ import type { Document } from "@rgby/collab-core";
2
+ type __VLS_Props = {
3
+ /** Optional space ID — searches across all spaces if omitted */
4
+ spaceId?: string;
5
+ /** Control open state */
6
+ open: boolean;
7
+ };
8
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
9
+ select: (doc: Document & {
10
+ spaceId: string;
11
+ }) => any;
12
+ "update:open": (value: boolean) => any;
13
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
14
+ onSelect?: ((doc: Document & {
15
+ spaceId: string;
16
+ }) => any) | undefined;
17
+ "onUpdate:open"?: ((value: boolean) => any) | undefined;
18
+ }>, {
19
+ spaceId: string;
20
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
21
+ declare const _default: typeof __VLS_export;
22
+ export default _default;
@@ -0,0 +1,99 @@
1
+ <script setup>
2
+ const props = defineProps({
3
+ spaceId: { type: String, required: false, default: void 0 },
4
+ open: { type: Boolean, required: true }
5
+ });
6
+ const emit = defineEmits(["update:open", "select"]);
7
+ const client = useCollabClient();
8
+ const isOpen = computed({
9
+ get: () => props.open,
10
+ set: (val) => emit("update:open", val)
11
+ });
12
+ const allDocs = ref([]);
13
+ const loading = ref(false);
14
+ const groups = computed(() => {
15
+ if (allDocs.value.length === 0) return [];
16
+ const bySpace = /* @__PURE__ */ new Map();
17
+ for (const doc of allDocs.value) {
18
+ const key = doc.spaceId;
19
+ if (!bySpace.has(key)) bySpace.set(key, []);
20
+ bySpace.get(key).push(doc);
21
+ }
22
+ return Array.from(bySpace.entries()).map(([spaceId, docs]) => ({
23
+ id: spaceId,
24
+ label: props.spaceId ? void 0 : spaceId,
25
+ items: docs.map((doc) => ({
26
+ label: doc.name || "Untitled",
27
+ icon: "i-lucide-file-text",
28
+ value: doc.id,
29
+ onSelect: () => {
30
+ emit("select", doc);
31
+ isOpen.value = false;
32
+ }
33
+ }))
34
+ }));
35
+ });
36
+ async function loadDocuments() {
37
+ loading.value = true;
38
+ try {
39
+ if (props.spaceId) {
40
+ const tree = await client.documents.tree(props.spaceId);
41
+ allDocs.value = flattenTree(tree, props.spaceId);
42
+ } else {
43
+ const spaces = await client.spaces.list();
44
+ const results = [];
45
+ for (const space of spaces) {
46
+ try {
47
+ const tree = await client.documents.tree(space.id);
48
+ results.push(...flattenTree(tree, space.id));
49
+ } catch {
50
+ }
51
+ }
52
+ allDocs.value = results;
53
+ }
54
+ } finally {
55
+ loading.value = false;
56
+ }
57
+ }
58
+ function flattenTree(nodes, spaceId) {
59
+ const result = [];
60
+ function walk(items) {
61
+ for (const item of items) {
62
+ result.push({ ...item, spaceId });
63
+ if (item.children?.length) walk(item.children);
64
+ }
65
+ }
66
+ walk(nodes);
67
+ return result;
68
+ }
69
+ function handleKeydown(e) {
70
+ if ((e.metaKey || e.ctrlKey) && e.key === "k") {
71
+ e.preventDefault();
72
+ isOpen.value = !isOpen.value;
73
+ }
74
+ }
75
+ watch(isOpen, (open) => {
76
+ if (open && allDocs.value.length === 0) loadDocuments();
77
+ });
78
+ onMounted(() => {
79
+ window.addEventListener("keydown", handleKeydown);
80
+ });
81
+ onUnmounted(() => {
82
+ window.removeEventListener("keydown", handleKeydown);
83
+ });
84
+ </script>
85
+
86
+ <template>
87
+ <UModal v-model:open="isOpen" :ui="{ content: 'p-0' }">
88
+ <template #content>
89
+ <UCommandPalette
90
+ :groups="groups"
91
+ :loading="loading"
92
+ placeholder="Search documents..."
93
+ close
94
+ @update:open="isOpen = $event"
95
+ class="h-80"
96
+ />
97
+ </template>
98
+ </UModal>
99
+ </template>
@@ -0,0 +1,22 @@
1
+ import type { Document } from "@rgby/collab-core";
2
+ type __VLS_Props = {
3
+ /** Optional space ID — searches across all spaces if omitted */
4
+ spaceId?: string;
5
+ /** Control open state */
6
+ open: boolean;
7
+ };
8
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
9
+ select: (doc: Document & {
10
+ spaceId: string;
11
+ }) => any;
12
+ "update:open": (value: boolean) => any;
13
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
14
+ onSelect?: ((doc: Document & {
15
+ spaceId: string;
16
+ }) => any) | undefined;
17
+ "onUpdate:open"?: ((value: boolean) => any) | undefined;
18
+ }>, {
19
+ spaceId: string;
20
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
21
+ declare const _default: typeof __VLS_export;
22
+ export default _default;
@@ -0,0 +1,32 @@
1
+ import type { Document, DocumentTreeNode } from "@rgby/collab-core";
2
+ type __VLS_Props = {
3
+ /** Space ID to load document tree for (required in single-space mode) */
4
+ spaceId?: string;
5
+ /** Currently selected document ID */
6
+ selectedId?: string;
7
+ /** Allow editing (rename, delete, move) */
8
+ editable?: boolean;
9
+ /** Multi-space mode: loads all spaces as collapsible groups */
10
+ multiSpace?: boolean;
11
+ };
12
+ declare function refresh(): Promise<void>;
13
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
14
+ refresh: typeof refresh;
15
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
16
+ select: (doc: DocumentTreeNode) => any;
17
+ delete: (docId: string) => any;
18
+ selectSpace: (spaceId: string) => any;
19
+ move: (docId: string, parentId: string | null, position: number) => any;
20
+ create: (doc: Document) => any;
21
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
22
+ onSelect?: ((doc: DocumentTreeNode) => any) | undefined;
23
+ onDelete?: ((docId: string) => any) | undefined;
24
+ onSelectSpace?: ((spaceId: string) => any) | undefined;
25
+ onMove?: ((docId: string, parentId: string | null, position: number) => any) | undefined;
26
+ onCreate?: ((doc: Document) => any) | undefined;
27
+ }>, {
28
+ editable: boolean;
29
+ multiSpace: boolean;
30
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
31
+ declare const _default: typeof __VLS_export;
32
+ export default _default;