doclific 0.2.0 → 0.2.2

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 (220) hide show
  1. package/LICENSE +17 -0
  2. package/dist/bin/doclific.js +36 -8
  3. package/package.json +11 -4
  4. package/readme.md +77 -0
  5. package/.gitattributes +0 -2
  6. package/.prettierignore +0 -5
  7. package/.prettierrc +0 -9
  8. package/.vscode/settings.json +0 -13
  9. package/frontend/components.json +0 -24
  10. package/frontend/eslint.config.js +0 -23
  11. package/frontend/index.html +0 -25
  12. package/frontend/package-lock.json +0 -15754
  13. package/frontend/public/logo.svg +0 -1
  14. package/frontend/src/App.tsx +0 -21
  15. package/frontend/src/components/app-sidebar.tsx +0 -393
  16. package/frontend/src/components/editor/editor-base-kit.tsx +0 -43
  17. package/frontend/src/components/editor/editor-kit.tsx +0 -93
  18. package/frontend/src/components/editor/plugins/align-base-kit.tsx +0 -16
  19. package/frontend/src/components/editor/plugins/align-kit.tsx +0 -18
  20. package/frontend/src/components/editor/plugins/autoformat-kit.tsx +0 -236
  21. package/frontend/src/components/editor/plugins/basic-blocks-base-kit.tsx +0 -35
  22. package/frontend/src/components/editor/plugins/basic-blocks-kit.tsx +0 -88
  23. package/frontend/src/components/editor/plugins/basic-marks-base-kit.tsx +0 -27
  24. package/frontend/src/components/editor/plugins/basic-marks-kit.tsx +0 -41
  25. package/frontend/src/components/editor/plugins/basic-nodes-kit.tsx +0 -6
  26. package/frontend/src/components/editor/plugins/block-menu-kit.tsx +0 -14
  27. package/frontend/src/components/editor/plugins/block-placeholder-kit.tsx +0 -17
  28. package/frontend/src/components/editor/plugins/block-selection-kit.tsx +0 -32
  29. package/frontend/src/components/editor/plugins/callout-base-kit.tsx +0 -7
  30. package/frontend/src/components/editor/plugins/callout-kit.tsx +0 -7
  31. package/frontend/src/components/editor/plugins/code-block-base-kit.tsx +0 -23
  32. package/frontend/src/components/editor/plugins/code-block-kit.tsx +0 -26
  33. package/frontend/src/components/editor/plugins/codebase-kit.tsx +0 -23
  34. package/frontend/src/components/editor/plugins/column-base-kit.tsx +0 -11
  35. package/frontend/src/components/editor/plugins/column-kit.tsx +0 -10
  36. package/frontend/src/components/editor/plugins/comment-base-kit.tsx +0 -7
  37. package/frontend/src/components/editor/plugins/comment-kit.tsx +0 -97
  38. package/frontend/src/components/editor/plugins/cursor-overlay-kit.tsx +0 -13
  39. package/frontend/src/components/editor/plugins/date-base-kit.tsx +0 -5
  40. package/frontend/src/components/editor/plugins/date-kit.tsx +0 -7
  41. package/frontend/src/components/editor/plugins/discussion-kit.tsx +0 -148
  42. package/frontend/src/components/editor/plugins/dnd-kit.tsx +0 -28
  43. package/frontend/src/components/editor/plugins/docx-kit.tsx +0 -6
  44. package/frontend/src/components/editor/plugins/emoji-kit.tsx +0 -13
  45. package/frontend/src/components/editor/plugins/excalidraw-kit.tsx +0 -9
  46. package/frontend/src/components/editor/plugins/exit-break-kit.tsx +0 -12
  47. package/frontend/src/components/editor/plugins/floating-toolbar-kit.tsx +0 -19
  48. package/frontend/src/components/editor/plugins/font-base-kit.tsx +0 -20
  49. package/frontend/src/components/editor/plugins/font-kit.tsx +0 -29
  50. package/frontend/src/components/editor/plugins/indent-base-kit.tsx +0 -19
  51. package/frontend/src/components/editor/plugins/indent-kit.tsx +0 -22
  52. package/frontend/src/components/editor/plugins/line-height-base-kit.tsx +0 -14
  53. package/frontend/src/components/editor/plugins/line-height-kit.tsx +0 -16
  54. package/frontend/src/components/editor/plugins/link-base-kit.tsx +0 -5
  55. package/frontend/src/components/editor/plugins/link-kit.tsx +0 -15
  56. package/frontend/src/components/editor/plugins/list-base-kit.tsx +0 -23
  57. package/frontend/src/components/editor/plugins/list-kit.tsx +0 -26
  58. package/frontend/src/components/editor/plugins/markdown-kit.tsx +0 -46
  59. package/frontend/src/components/editor/plugins/math-base-kit.tsx +0 -11
  60. package/frontend/src/components/editor/plugins/math-kit.tsx +0 -13
  61. package/frontend/src/components/editor/plugins/media-base-kit.tsx +0 -31
  62. package/frontend/src/components/editor/plugins/media-kit.tsx +0 -43
  63. package/frontend/src/components/editor/plugins/mention-base-kit.tsx +0 -7
  64. package/frontend/src/components/editor/plugins/mention-kit.tsx +0 -15
  65. package/frontend/src/components/editor/plugins/slash-kit.tsx +0 -18
  66. package/frontend/src/components/editor/plugins/suggestion-base-kit.tsx +0 -7
  67. package/frontend/src/components/editor/plugins/suggestion-kit.tsx +0 -90
  68. package/frontend/src/components/editor/plugins/table-base-kit.tsx +0 -20
  69. package/frontend/src/components/editor/plugins/table-kit.tsx +0 -22
  70. package/frontend/src/components/editor/plugins/toc-base-kit.tsx +0 -5
  71. package/frontend/src/components/editor/plugins/toc-kit.tsx +0 -14
  72. package/frontend/src/components/editor/plugins/toggle-base-kit.tsx +0 -7
  73. package/frontend/src/components/editor/plugins/toggle-kit.tsx +0 -11
  74. package/frontend/src/components/editor/transforms.ts +0 -194
  75. package/frontend/src/components/markdown-to-slate-demo.tsx +0 -50
  76. package/frontend/src/components/mode-toggle.tsx +0 -15
  77. package/frontend/src/components/theme-provider.tsx +0 -73
  78. package/frontend/src/components/ui/alert-dialog.tsx +0 -155
  79. package/frontend/src/components/ui/align-toolbar-button.tsx +0 -84
  80. package/frontend/src/components/ui/avatar.tsx +0 -51
  81. package/frontend/src/components/ui/block-context-menu.tsx +0 -199
  82. package/frontend/src/components/ui/block-discussion.tsx +0 -365
  83. package/frontend/src/components/ui/block-draggable.tsx +0 -512
  84. package/frontend/src/components/ui/block-list-static.tsx +0 -80
  85. package/frontend/src/components/ui/block-list.tsx +0 -87
  86. package/frontend/src/components/ui/block-selection.tsx +0 -42
  87. package/frontend/src/components/ui/block-suggestion.tsx +0 -473
  88. package/frontend/src/components/ui/blockquote-node-static.tsx +0 -11
  89. package/frontend/src/components/ui/blockquote-node.tsx +0 -13
  90. package/frontend/src/components/ui/button.tsx +0 -62
  91. package/frontend/src/components/ui/calendar.tsx +0 -218
  92. package/frontend/src/components/ui/callout-node-static.tsx +0 -36
  93. package/frontend/src/components/ui/callout-node.tsx +0 -63
  94. package/frontend/src/components/ui/caption.tsx +0 -63
  95. package/frontend/src/components/ui/checkbox.tsx +0 -30
  96. package/frontend/src/components/ui/code-block-node-static.tsx +0 -35
  97. package/frontend/src/components/ui/code-block-node.tsx +0 -287
  98. package/frontend/src/components/ui/code-node-static.tsx +0 -15
  99. package/frontend/src/components/ui/code-node.tsx +0 -17
  100. package/frontend/src/components/ui/codebase-snippet-node.tsx +0 -237
  101. package/frontend/src/components/ui/column-node-static.tsx +0 -29
  102. package/frontend/src/components/ui/column-node.tsx +0 -317
  103. package/frontend/src/components/ui/command.tsx +0 -182
  104. package/frontend/src/components/ui/comment-node-static.tsx +0 -15
  105. package/frontend/src/components/ui/comment-node.tsx +0 -45
  106. package/frontend/src/components/ui/comment-toolbar-button.tsx +0 -24
  107. package/frontend/src/components/ui/comment.tsx +0 -618
  108. package/frontend/src/components/ui/context-menu.tsx +0 -250
  109. package/frontend/src/components/ui/cursor-overlay.tsx +0 -66
  110. package/frontend/src/components/ui/date-node-static.tsx +0 -45
  111. package/frontend/src/components/ui/date-node.tsx +0 -93
  112. package/frontend/src/components/ui/dialog.tsx +0 -143
  113. package/frontend/src/components/ui/dropdown-menu.tsx +0 -255
  114. package/frontend/src/components/ui/dynamic-icon.tsx +0 -12
  115. package/frontend/src/components/ui/editor-static.tsx +0 -53
  116. package/frontend/src/components/ui/editor.tsx +0 -130
  117. package/frontend/src/components/ui/emoji-node.tsx +0 -69
  118. package/frontend/src/components/ui/emoji-toolbar-button.tsx +0 -628
  119. package/frontend/src/components/ui/equation-node-static.tsx +0 -98
  120. package/frontend/src/components/ui/equation-node.tsx +0 -235
  121. package/frontend/src/components/ui/equation-toolbar-button.tsx +0 -25
  122. package/frontend/src/components/ui/excalidraw-node.tsx +0 -36
  123. package/frontend/src/components/ui/export-toolbar-button.tsx +0 -174
  124. package/frontend/src/components/ui/file-selector.tsx +0 -339
  125. package/frontend/src/components/ui/floating-toolbar-buttons.tsx +0 -73
  126. package/frontend/src/components/ui/floating-toolbar.tsx +0 -85
  127. package/frontend/src/components/ui/font-color-toolbar-button.tsx +0 -831
  128. package/frontend/src/components/ui/font-size-toolbar-button.tsx +0 -152
  129. package/frontend/src/components/ui/heading-node-static.tsx +0 -68
  130. package/frontend/src/components/ui/heading-node.tsx +0 -58
  131. package/frontend/src/components/ui/highlight-node-static.tsx +0 -11
  132. package/frontend/src/components/ui/highlight-node.tsx +0 -13
  133. package/frontend/src/components/ui/history-toolbar-button.tsx +0 -50
  134. package/frontend/src/components/ui/hr-node-static.tsx +0 -20
  135. package/frontend/src/components/ui/hr-node.tsx +0 -33
  136. package/frontend/src/components/ui/import-toolbar-button.tsx +0 -97
  137. package/frontend/src/components/ui/indent-toolbar-button.tsx +0 -30
  138. package/frontend/src/components/ui/inline-combobox.tsx +0 -414
  139. package/frontend/src/components/ui/input.tsx +0 -21
  140. package/frontend/src/components/ui/insert-toolbar-button.tsx +0 -254
  141. package/frontend/src/components/ui/kbd-node-static.tsx +0 -15
  142. package/frontend/src/components/ui/kbd-node.tsx +0 -17
  143. package/frontend/src/components/ui/layout-header.tsx +0 -35
  144. package/frontend/src/components/ui/line-height-toolbar-button.tsx +0 -68
  145. package/frontend/src/components/ui/link-node-static.tsx +0 -21
  146. package/frontend/src/components/ui/link-node.tsx +0 -39
  147. package/frontend/src/components/ui/link-toolbar-button.tsx +0 -22
  148. package/frontend/src/components/ui/link-toolbar.tsx +0 -206
  149. package/frontend/src/components/ui/list-toolbar-button.tsx +0 -204
  150. package/frontend/src/components/ui/mark-toolbar-button.tsx +0 -19
  151. package/frontend/src/components/ui/media-audio-node-static.tsx +0 -17
  152. package/frontend/src/components/ui/media-audio-node.tsx +0 -39
  153. package/frontend/src/components/ui/media-embed-node.tsx +0 -136
  154. package/frontend/src/components/ui/media-file-node-static.tsx +0 -29
  155. package/frontend/src/components/ui/media-file-node.tsx +0 -47
  156. package/frontend/src/components/ui/media-image-node-static.tsx +0 -39
  157. package/frontend/src/components/ui/media-image-node.tsx +0 -80
  158. package/frontend/src/components/ui/media-placeholder-node.tsx +0 -249
  159. package/frontend/src/components/ui/media-preview-dialog.tsx +0 -152
  160. package/frontend/src/components/ui/media-toolbar-button.tsx +0 -225
  161. package/frontend/src/components/ui/media-toolbar.tsx +0 -115
  162. package/frontend/src/components/ui/media-upload-toast.tsx +0 -66
  163. package/frontend/src/components/ui/media-video-node-static.tsx +0 -30
  164. package/frontend/src/components/ui/media-video-node.tsx +0 -121
  165. package/frontend/src/components/ui/mention-node-static.tsx +0 -36
  166. package/frontend/src/components/ui/mention-node.tsx +0 -194
  167. package/frontend/src/components/ui/mode-toolbar-button.tsx +0 -123
  168. package/frontend/src/components/ui/more-toolbar-button.tsx +0 -80
  169. package/frontend/src/components/ui/paragraph-node-static.tsx +0 -13
  170. package/frontend/src/components/ui/paragraph-node.tsx +0 -15
  171. package/frontend/src/components/ui/popover.tsx +0 -46
  172. package/frontend/src/components/ui/resize-handle.tsx +0 -87
  173. package/frontend/src/components/ui/separator.tsx +0 -28
  174. package/frontend/src/components/ui/sheet.tsx +0 -139
  175. package/frontend/src/components/ui/sidebar.tsx +0 -726
  176. package/frontend/src/components/ui/skeleton.tsx +0 -13
  177. package/frontend/src/components/ui/slash-node.tsx +0 -233
  178. package/frontend/src/components/ui/sonner.tsx +0 -38
  179. package/frontend/src/components/ui/suggestion-node-static.tsx +0 -35
  180. package/frontend/src/components/ui/suggestion-node.tsx +0 -162
  181. package/frontend/src/components/ui/suggestion-toolbar-button.tsx +0 -25
  182. package/frontend/src/components/ui/table-icons.tsx +0 -862
  183. package/frontend/src/components/ui/table-node-static.tsx +0 -98
  184. package/frontend/src/components/ui/table-node.tsx +0 -656
  185. package/frontend/src/components/ui/table-toolbar-button.tsx +0 -264
  186. package/frontend/src/components/ui/toc-node-static.tsx +0 -92
  187. package/frontend/src/components/ui/toc-node.tsx +0 -55
  188. package/frontend/src/components/ui/toggle-node-static.tsx +0 -18
  189. package/frontend/src/components/ui/toggle-node.tsx +0 -36
  190. package/frontend/src/components/ui/toggle-toolbar-button.tsx +0 -22
  191. package/frontend/src/components/ui/toolbar.tsx +0 -387
  192. package/frontend/src/components/ui/tooltip.tsx +0 -59
  193. package/frontend/src/components/ui/turn-into-toolbar-button.tsx +0 -188
  194. package/frontend/src/hooks/use-debounce.ts +0 -18
  195. package/frontend/src/hooks/use-is-touch-device.ts +0 -24
  196. package/frontend/src/hooks/use-mobile.ts +0 -19
  197. package/frontend/src/hooks/use-mounted.ts +0 -11
  198. package/frontend/src/hooks/use-upload-file.ts +0 -128
  199. package/frontend/src/index.css +0 -128
  200. package/frontend/src/layout.tsx +0 -42
  201. package/frontend/src/lib/markdown-joiner-transform.ts +0 -239
  202. package/frontend/src/lib/orpc.ts +0 -13
  203. package/frontend/src/lib/uploadthing.ts +0 -19
  204. package/frontend/src/lib/utils.ts +0 -6
  205. package/frontend/src/main.tsx +0 -13
  206. package/frontend/src/pages/editor.tsx +0 -44
  207. package/frontend/src/types/docs.d.ts +0 -6
  208. package/frontend/src/types/global.d.ts +0 -9
  209. package/frontend/src/types/router.d.ts +0 -4
  210. package/frontend/tsconfig.app.json +0 -33
  211. package/frontend/tsconfig.json +0 -10
  212. package/frontend/tsconfig.node.json +0 -26
  213. package/frontend/vite.config.ts +0 -14
  214. package/src/bin/doclific.ts +0 -47
  215. package/src/core/codebase.ts +0 -39
  216. package/src/core/docs.ts +0 -90
  217. package/src/core/git.ts +0 -48
  218. package/src/server/index.ts +0 -55
  219. package/src/server/router.ts +0 -65
  220. package/tsconfig.json +0 -15
@@ -1,339 +0,0 @@
1
- import { useState, useMemo } from "react";
2
- import { ChevronRight, ChevronDown, File, Folder, X } from "lucide-react";
3
- import { cn } from "@/lib/utils";
4
- import { Button } from "@/components/ui/button";
5
- import { useQuery, useQueryClient } from "@tanstack/react-query";
6
- import { orpcTs } from "@/lib/orpc";
7
-
8
- interface FileNode {
9
- name: string;
10
- path: string;
11
- type: "file" | "directory";
12
- children?: FileNode[];
13
- }
14
-
15
- interface FileSelectorProps {
16
- open: boolean;
17
- onClose: () => void;
18
- onSelect: (filePath: string, startLine: number, endLine: number) => void;
19
- currentFilePath?: string;
20
- currentStartLine?: string;
21
- currentEndLine?: string;
22
- }
23
-
24
- export function FileSelector({
25
- open,
26
- onClose,
27
- onSelect,
28
- currentFilePath,
29
- currentStartLine,
30
- currentEndLine,
31
- }: FileSelectorProps) {
32
- const queryClient = useQueryClient();
33
- const [expandedDirs, setExpandedDirs] = useState<Set<string>>(new Set());
34
- const [selectedFile, setSelectedFile] = useState<string>(currentFilePath || "");
35
- const [startLineInput, setStartLineInput] = useState<string>(
36
- currentStartLine || ""
37
- );
38
- const [endLineInput, setEndLineInput] = useState<string>(
39
- currentEndLine || ""
40
- );
41
- const [folderContents, setFolderContents] = useState<Map<string, FileNode[]>>(new Map());
42
-
43
- const rootFolderQuery = useQuery({
44
- ...orpcTs.codebase.getFolderContents.queryOptions({
45
- input: { filePath: "" },
46
- }),
47
- enabled: open,
48
- });
49
-
50
- // Merge all folder contents for rendering (includes root folder)
51
- const allFolderContents = useMemo(() => {
52
- const merged = new Map(folderContents);
53
- if (rootFolderQuery.data) {
54
- merged.set("", rootFolderQuery.data);
55
- }
56
- return merged;
57
- }, [folderContents, rootFolderQuery.data]);
58
-
59
- const fileContentQuery = useQuery({
60
- ...orpcTs.codebase.getFileContents.queryOptions({
61
- input: { filePath: selectedFile },
62
- }),
63
- enabled: open && !!selectedFile,
64
- });
65
-
66
- const fileContent = fileContentQuery.data?.contents || "";
67
- const lineCount = fileContent.split("\n").length;
68
-
69
- // Convert inputs to numbers for calculations, with defaults
70
- const startLine = startLineInput === "" ? 1 : Math.max(1, parseInt(startLineInput) || 1);
71
- const endLine = endLineInput === ""
72
- ? (fileContentQuery.data && lineCount > 0 ? Math.min(50, lineCount) : 1)
73
- : Math.min(lineCount, Math.max(startLine, parseInt(endLineInput) || lineCount));
74
-
75
- const toggleExpanded = async (path: string) => {
76
- const newExpanded = new Set(expandedDirs);
77
- if (newExpanded.has(path)) {
78
- newExpanded.delete(path);
79
- } else {
80
- newExpanded.add(path);
81
- // Fetch folder contents if not already loaded
82
- if (!folderContents.has(path)) {
83
- try {
84
- const data = await queryClient.fetchQuery(
85
- orpcTs.codebase.getFolderContents.queryOptions({
86
- input: { filePath: path },
87
- })
88
- );
89
- setFolderContents((prev) => {
90
- const newMap = new Map(prev);
91
- newMap.set(path, data || []);
92
- return newMap;
93
- });
94
- } catch (error) {
95
- console.error("Failed to fetch folder contents:", error);
96
- }
97
- }
98
- }
99
- setExpandedDirs(newExpanded);
100
- };
101
-
102
- const handleSelectFile = (filePath: string) => {
103
- setSelectedFile(filePath);
104
- setStartLineInput("");
105
- setEndLineInput("");
106
- fileContentQuery.refetch();
107
- };
108
-
109
- const handleConfirm = () => {
110
- if (selectedFile) {
111
- onSelect(selectedFile, startLine, endLine);
112
- onClose();
113
- }
114
- };
115
-
116
- const renderFileTree = (nodes: FileNode[], depth = 0) => {
117
- return (
118
- <div>
119
- {nodes.map((node) => {
120
- const children = node.type === "directory" ? allFolderContents.get(node.path) : undefined;
121
- const isLoading = node.type === "directory" && expandedDirs.has(node.path) && !allFolderContents.has(node.path);
122
-
123
- return (
124
- <div key={node.path}>
125
- <div
126
- className={cn(
127
- "flex items-center gap-1 px-2 py-1.5 hover:bg-muted transition-colors cursor-pointer rounded text-sm",
128
- selectedFile === node.path && node.type === "file"
129
- ? "bg-primary/10"
130
- : ""
131
- )}
132
- style={{ paddingLeft: `${depth * 16 + 8}px` }}
133
- >
134
- {node.type === "directory" ? (
135
- <>
136
- <button
137
- onClick={() => toggleExpanded(node.path)}
138
- className="flex items-center justify-center w-4 h-4 p-0"
139
- disabled={isLoading}
140
- >
141
- {isLoading ? (
142
- <div className="w-4 h-4 border-2 border-primary border-t-transparent rounded-full animate-spin" />
143
- ) : expandedDirs.has(node.path) ? (
144
- <ChevronDown className="w-4 h-4" />
145
- ) : (
146
- <ChevronRight className="w-4 h-4" />
147
- )}
148
- </button>
149
- <Folder className="w-4 h-4 text-blue-500 flex-shrink-0" />
150
- <span className="text-foreground">{node.name}</span>
151
- </>
152
- ) : (
153
- <>
154
- <div className="w-4" />
155
- <File className="w-4 h-4 text-muted-foreground flex-shrink-0" />
156
- <button
157
- onClick={() => handleSelectFile(node.path)}
158
- className="text-foreground hover:text-primary"
159
- >
160
- {node.name}
161
- </button>
162
- </>
163
- )}
164
- </div>
165
- {node.type === "directory" &&
166
- expandedDirs.has(node.path) &&
167
- children && (
168
- <>{renderFileTree(children, depth + 1)}</>
169
- )}
170
- </div>
171
- );
172
- })}
173
- </div>
174
- );
175
- };
176
-
177
- if (!open) return null;
178
-
179
- return (
180
- <div className="fixed inset-0 z-50 flex items-center justify-center">
181
- {/* Backdrop */}
182
- <div className="absolute inset-0 bg-black/50" onClick={onClose} />
183
-
184
- {/* Modal */}
185
- <div className="relative z-50 w-full max-w-4xl min-h-[80vh] max-h-[calc(100vh-2rem)] mx-4 bg-background rounded-lg shadow-xl flex flex-col overflow-hidden border">
186
- {/* Header */}
187
- <div className="flex items-center justify-between px-6 py-4 border-b">
188
- <div>
189
- <h2 className="text-lg font-semibold">Select File and Lines</h2>
190
- <p className="text-sm text-muted-foreground">
191
- Choose a file and specify the line range you want to display
192
- </p>
193
- </div>
194
- <button
195
- onClick={onClose}
196
- className="p-1 hover:bg-muted rounded"
197
- >
198
- <X className="w-6 h-6" />
199
- </button>
200
- </div>
201
-
202
- {/* Content */}
203
- <div className="flex gap-4 flex-1 overflow-hidden p-6">
204
- {/* File browser */}
205
- <div className="flex-1 border rounded-lg overflow-y-auto bg-muted/50 p-2">
206
- {rootFolderQuery.isLoading ? (
207
- <div className="p-4 text-sm text-muted-foreground">
208
- Loading files...
209
- </div>
210
- ) : (
211
- renderFileTree(allFolderContents.get("") || [])
212
- )}
213
- </div>
214
-
215
- {/* Preview and line selection */}
216
- <div className="flex-1 flex flex-col gap-4">
217
- {selectedFile ? (
218
- <>
219
- <div>
220
- <p className="text-sm font-semibold mb-2">
221
- Selected:{" "}
222
- <span className="text-primary">{selectedFile}</span>
223
- </p>
224
- <p className="text-xs text-muted-foreground">
225
- Total lines: {lineCount}
226
- </p>
227
- </div>
228
-
229
- {/* Line range inputs */}
230
- <div className="flex gap-4">
231
- <div className="flex-1">
232
- <label className="text-xs font-medium text-muted-foreground block mb-1">
233
- Start Line
234
- </label>
235
- <input
236
- type="text"
237
- inputMode="numeric"
238
- value={startLineInput}
239
- onChange={(e) => {
240
- const value = e.target.value;
241
- // Allow empty string or valid numbers
242
- if (value === "" || /^\d+$/.test(value)) {
243
- setStartLineInput(value);
244
- }
245
- }}
246
- onBlur={(e) => {
247
- // Validate on blur - set to 1 if empty or invalid
248
- const num = parseInt(e.target.value);
249
- if (isNaN(num) || num < 1) {
250
- setStartLineInput("");
251
- } else if (num > lineCount) {
252
- setStartLineInput(String(lineCount));
253
- }
254
- }}
255
- className="w-full px-2 py-1 border rounded text-sm bg-background text-foreground"
256
- placeholder="1"
257
- />
258
- </div>
259
- <div className="flex-1">
260
- <label className="text-xs font-medium text-muted-foreground block mb-1">
261
- End Line
262
- </label>
263
- <input
264
- type="text"
265
- inputMode="numeric"
266
- value={endLineInput}
267
- onChange={(e) => {
268
- const value = e.target.value;
269
- // Allow empty string or valid numbers
270
- if (value === "" || /^\d+$/.test(value)) {
271
- setEndLineInput(value);
272
- }
273
- }}
274
- onBlur={(e) => {
275
- // Validate on blur
276
- const num = parseInt(e.target.value);
277
- if (isNaN(num) || num < startLine) {
278
- setEndLineInput("");
279
- } else if (num > lineCount) {
280
- setEndLineInput(String(lineCount));
281
- }
282
- }}
283
- className="w-full px-2 py-1 border rounded text-sm bg-background text-foreground"
284
- placeholder={String(lineCount)}
285
- />
286
- </div>
287
- </div>
288
-
289
- {/* Preview */}
290
- <div className="flex-1 flex flex-col">
291
- <p className="text-xs font-medium text-muted-foreground mb-1">
292
- Preview
293
- </p>
294
- <div className="flex-1 relative">
295
- <div className="bg-muted rounded border p-2 overflow-y-auto absolute inset-0 text-xs font-mono">
296
- {fileContentQuery.isLoading ? (
297
- <p className="text-muted-foreground">Loading...</p>
298
- ) : (
299
- fileContent
300
- .split("\n")
301
- .slice(startLine - 1, endLine)
302
- .map((line, idx) => (
303
- <div
304
- key={idx}
305
- className="flex gap-2 text-foreground"
306
- >
307
- <span className="text-muted-foreground w-8 text-right flex-shrink-0">
308
- {startLine + idx}
309
- </span>
310
- <span>{line}</span>
311
- </div>
312
- ))
313
- )}
314
- </div>
315
- </div>
316
- </div>
317
- </>
318
- ) : (
319
- <div className="flex items-center justify-center h-full text-muted-foreground">
320
- <p>Select a file to begin</p>
321
- </div>
322
- )}
323
- </div>
324
- </div>
325
-
326
- {/* Footer */}
327
- <div className="flex justify-end gap-2 px-6 py-4 border-t bg-muted/50">
328
- <Button variant="outline" onClick={onClose}>
329
- Cancel
330
- </Button>
331
- <Button onClick={handleConfirm} disabled={!selectedFile}>
332
- Insert Code
333
- </Button>
334
- </div>
335
- </div>
336
- </div>
337
- );
338
- }
339
-
@@ -1,73 +0,0 @@
1
-
2
-
3
- import {
4
- BoldIcon,
5
- Code2Icon,
6
- ItalicIcon,
7
- StrikethroughIcon,
8
- UnderlineIcon,
9
- } from 'lucide-react';
10
- import { KEYS } from 'platejs';
11
- import { useEditorReadOnly } from 'platejs/react';
12
-
13
- import { CommentToolbarButton } from './comment-toolbar-button';
14
- import { InlineEquationToolbarButton } from './equation-toolbar-button';
15
- import { LinkToolbarButton } from './link-toolbar-button';
16
- import { MarkToolbarButton } from './mark-toolbar-button';
17
- import { MoreToolbarButton } from './more-toolbar-button';
18
- import { SuggestionToolbarButton } from './suggestion-toolbar-button';
19
- import { ToolbarGroup } from './toolbar';
20
- import { TurnIntoToolbarButton } from './turn-into-toolbar-button';
21
-
22
- export function FloatingToolbarButtons() {
23
- const readOnly = useEditorReadOnly();
24
-
25
- return (
26
- <>
27
- {!readOnly && (
28
- <>
29
- <ToolbarGroup>
30
- <TurnIntoToolbarButton />
31
-
32
- <MarkToolbarButton nodeType={KEYS.bold} tooltip="Bold (⌘+B)">
33
- <BoldIcon />
34
- </MarkToolbarButton>
35
-
36
- <MarkToolbarButton nodeType={KEYS.italic} tooltip="Italic (⌘+I)">
37
- <ItalicIcon />
38
- </MarkToolbarButton>
39
-
40
- <MarkToolbarButton
41
- nodeType={KEYS.underline}
42
- tooltip="Underline (⌘+U)"
43
- >
44
- <UnderlineIcon />
45
- </MarkToolbarButton>
46
-
47
- <MarkToolbarButton
48
- nodeType={KEYS.strikethrough}
49
- tooltip="Strikethrough (⌘+⇧+M)"
50
- >
51
- <StrikethroughIcon />
52
- </MarkToolbarButton>
53
-
54
- <MarkToolbarButton nodeType={KEYS.code} tooltip="Code (⌘+E)">
55
- <Code2Icon />
56
- </MarkToolbarButton>
57
-
58
- <InlineEquationToolbarButton />
59
-
60
- <LinkToolbarButton />
61
- </ToolbarGroup>
62
- </>
63
- )}
64
-
65
- <ToolbarGroup>
66
- <CommentToolbarButton />
67
- <SuggestionToolbarButton />
68
-
69
- {!readOnly && <MoreToolbarButton />}
70
- </ToolbarGroup>
71
- </>
72
- );
73
- }
@@ -1,85 +0,0 @@
1
-
2
-
3
- import {
4
- type FloatingToolbarState,
5
- flip,
6
- offset,
7
- useFloatingToolbar,
8
- useFloatingToolbarState,
9
- } from '@platejs/floating';
10
- import { useComposedRef } from '@udecode/cn';
11
- import { KEYS } from 'platejs';
12
- import {
13
- useEditorId,
14
- useEventEditorValue,
15
- usePluginOption,
16
- } from 'platejs/react';
17
-
18
- import { cn } from '@/lib/utils';
19
-
20
- import { Toolbar } from './toolbar';
21
-
22
- export function FloatingToolbar({
23
- children,
24
- className,
25
- state,
26
- ...props
27
- }: React.ComponentProps<typeof Toolbar> & {
28
- state?: FloatingToolbarState;
29
- }) {
30
- const editorId = useEditorId();
31
- const focusedEditorId = useEventEditorValue('focus');
32
- const isFloatingLinkOpen = !!usePluginOption({ key: KEYS.link }, 'mode');
33
- const isAIChatOpen = usePluginOption({ key: KEYS.aiChat }, 'open');
34
-
35
- const floatingToolbarState = useFloatingToolbarState({
36
- editorId,
37
- focusedEditorId,
38
- hideToolbar: isFloatingLinkOpen || isAIChatOpen,
39
- ...state,
40
- floatingOptions: {
41
- middleware: [
42
- offset(12),
43
- flip({
44
- fallbackPlacements: [
45
- 'top-start',
46
- 'top-end',
47
- 'bottom-start',
48
- 'bottom-end',
49
- ],
50
- padding: 12,
51
- }),
52
- ],
53
- placement: 'top',
54
- ...state?.floatingOptions,
55
- },
56
- });
57
-
58
- const {
59
- clickOutsideRef,
60
- hidden,
61
- props: rootProps,
62
- ref: floatingRef,
63
- } = useFloatingToolbar(floatingToolbarState);
64
-
65
- const ref = useComposedRef<HTMLDivElement>(props.ref, floatingRef);
66
-
67
- if (hidden) return null;
68
-
69
- return (
70
- <div ref={clickOutsideRef}>
71
- <Toolbar
72
- {...props}
73
- {...rootProps}
74
- ref={ref}
75
- className={cn(
76
- 'scrollbar-hide absolute z-50 overflow-x-auto whitespace-nowrap rounded-md border bg-popover p-1 opacity-100 shadow-md print:hidden',
77
- 'max-w-[80vw]',
78
- className
79
- )}
80
- >
81
- {children}
82
- </Toolbar>
83
- </div>
84
- );
85
- }