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,287 +0,0 @@
1
- import React from 'react';
2
-
3
- import { formatCodeBlock, isLangSupported } from '@platejs/code-block';
4
- import { BracesIcon, Check, CheckIcon, CopyIcon } from 'lucide-react';
5
- import { type TCodeBlockElement, type TCodeSyntaxLeaf, NodeApi } from 'platejs';
6
- import {
7
- type PlateElementProps,
8
- type PlateLeafProps,
9
- PlateElement,
10
- PlateLeaf,
11
- } from 'platejs/react';
12
- import { useEditorRef, useElement, useReadOnly } from 'platejs/react';
13
-
14
- import { Button } from '@/components/ui/button';
15
- import {
16
- Command,
17
- CommandEmpty,
18
- CommandGroup,
19
- CommandInput,
20
- CommandItem,
21
- CommandList,
22
- } from '@/components/ui/command';
23
- import {
24
- Popover,
25
- PopoverContent,
26
- PopoverTrigger,
27
- } from '@/components/ui/popover';
28
- import { cn } from '@/lib/utils';
29
-
30
- export function CodeBlockElement(props: PlateElementProps<TCodeBlockElement>) {
31
- const { editor, element } = props;
32
-
33
- return (
34
- <PlateElement
35
- className="py-1 **:[.hljs-addition]:bg-[#f0fff4] **:[.hljs-addition]:text-[#22863a] dark:**:[.hljs-addition]:bg-[#3c5743] dark:**:[.hljs-addition]:text-[#ceead5] **:[.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable]:text-[#005cc5] dark:**:[.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable]:text-[#6596cf] **:[.hljs-built\\\\_in,.hljs-symbol]:text-[#e36209] dark:**:[.hljs-built\\\\_in,.hljs-symbol]:text-[#c3854e] **:[.hljs-bullet]:text-[#735c0f] **:[.hljs-comment,.hljs-code,.hljs-formula]:text-[#6a737d] dark:**:[.hljs-comment,.hljs-code,.hljs-formula]:text-[#6a737d] **:[.hljs-deletion]:bg-[#ffeef0] **:[.hljs-deletion]:text-[#b31d28] dark:**:[.hljs-deletion]:bg-[#473235] dark:**:[.hljs-deletion]:text-[#e7c7cb] **:[.hljs-emphasis]:italic **:[.hljs-keyword,.hljs-doctag,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language\\\\_]:text-[#d73a49] dark:**:[.hljs-keyword,.hljs-doctag,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language\\\\_]:text-[#ee6960] **:[.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo]:text-[#22863a] dark:**:[.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo]:text-[#36a84f] **:[.hljs-regexp,.hljs-string,.hljs-meta_.hljs-string]:text-[#032f62] dark:**:[.hljs-regexp,.hljs-string,.hljs-meta_.hljs-string]:text-[#3593ff] **:[.hljs-section]:font-bold **:[.hljs-section]:text-[#005cc5] dark:**:[.hljs-section]:text-[#61a5f2] **:[.hljs-strong]:font-bold **:[.hljs-title,.hljs-title.class\\\\_,.hljs-title.class\\\\_.inherited\\\\_\\\\_,.hljs-title.function\\\\_]:text-[#6f42c1] dark:**:[.hljs-title,.hljs-title.class\\\\_,.hljs-title.class\\\\_.inherited\\\\_\\\\_,.hljs-title.function\\\\_]:text-[#a77bfa]"
36
- {...props}
37
- >
38
- <div className="relative rounded-md bg-muted/50">
39
- <pre className="overflow-x-auto p-8 pr-4 font-mono text-sm leading-[normal] [tab-size:2] print:break-inside-avoid">
40
- <code>{props.children}</code>
41
- </pre>
42
-
43
- <div
44
- className="absolute top-1 right-1 z-10 flex select-none gap-0.5"
45
- contentEditable={false}
46
- >
47
- {isLangSupported(element.lang) && (
48
- <Button
49
- size="icon"
50
- variant="ghost"
51
- className="size-6 text-xs"
52
- onClick={() => formatCodeBlock(editor, { element })}
53
- title="Format code"
54
- >
55
- <BracesIcon className="!size-3.5 text-muted-foreground" />
56
- </Button>
57
- )}
58
-
59
- <CodeBlockCombobox />
60
-
61
- <CopyButton
62
- size="icon"
63
- variant="ghost"
64
- className="size-6 gap-1 text-muted-foreground text-xs"
65
- value={() => NodeApi.string(element)}
66
- />
67
- </div>
68
- </div>
69
- </PlateElement>
70
- );
71
- }
72
-
73
- function CodeBlockCombobox() {
74
- const [open, setOpen] = React.useState(false);
75
- const readOnly = useReadOnly();
76
- const editor = useEditorRef();
77
- const element = useElement<TCodeBlockElement>();
78
- const value = element.lang || 'plaintext';
79
- const [searchValue, setSearchValue] = React.useState('');
80
-
81
- const items = React.useMemo(
82
- () =>
83
- languages.filter(
84
- (language) =>
85
- !searchValue ||
86
- language.label.toLowerCase().includes(searchValue.toLowerCase())
87
- ),
88
- [searchValue]
89
- );
90
-
91
- if (readOnly) return null;
92
-
93
- return (
94
- <Popover open={open} onOpenChange={setOpen}>
95
- <PopoverTrigger asChild>
96
- <Button
97
- size="sm"
98
- variant="ghost"
99
- className="h-6 select-none justify-between gap-1 px-2 text-muted-foreground text-xs"
100
- aria-expanded={open}
101
- role="combobox"
102
- >
103
- {languages.find((language) => language.value === value)?.label ??
104
- 'Plain Text'}
105
- </Button>
106
- </PopoverTrigger>
107
- <PopoverContent
108
- className="w-[200px] p-0"
109
- onCloseAutoFocus={() => setSearchValue('')}
110
- >
111
- <Command shouldFilter={false}>
112
- <CommandInput
113
- className="h-9"
114
- value={searchValue}
115
- onValueChange={(value) => setSearchValue(value)}
116
- placeholder="Search language..."
117
- />
118
- <CommandEmpty>No language found.</CommandEmpty>
119
-
120
- <CommandList className="h-[344px] overflow-y-auto">
121
- <CommandGroup>
122
- {items.map((language) => (
123
- <CommandItem
124
- key={language.label}
125
- className="cursor-pointer"
126
- value={language.value}
127
- onSelect={(value) => {
128
- editor.tf.setNodes<TCodeBlockElement>(
129
- { lang: value },
130
- { at: element }
131
- );
132
- setSearchValue(value);
133
- setOpen(false);
134
- }}
135
- >
136
- <Check
137
- className={cn(
138
- value === language.value ? 'opacity-100' : 'opacity-0'
139
- )}
140
- />
141
- {language.label}
142
- </CommandItem>
143
- ))}
144
- </CommandGroup>
145
- </CommandList>
146
- </Command>
147
- </PopoverContent>
148
- </Popover>
149
- );
150
- }
151
-
152
- function CopyButton({
153
- value,
154
- ...props
155
- }: { value: (() => string) | string } & Omit<
156
- React.ComponentProps<typeof Button>,
157
- 'value'
158
- >) {
159
- const [hasCopied, setHasCopied] = React.useState(false);
160
-
161
- React.useEffect(() => {
162
- setTimeout(() => {
163
- setHasCopied(false);
164
- }, 2000);
165
- }, [hasCopied]);
166
-
167
- return (
168
- <Button
169
- onClick={() => {
170
- void navigator.clipboard.writeText(
171
- typeof value === 'function' ? value() : value
172
- );
173
- setHasCopied(true);
174
- }}
175
- {...props}
176
- >
177
- <span className="sr-only">Copy</span>
178
- {hasCopied ? (
179
- <CheckIcon className="!size-3" />
180
- ) : (
181
- <CopyIcon className="!size-3" />
182
- )}
183
- </Button>
184
- );
185
- }
186
-
187
- export function CodeLineElement(props: PlateElementProps) {
188
- return <PlateElement {...props} />;
189
- }
190
-
191
- export function CodeSyntaxLeaf(props: PlateLeafProps<TCodeSyntaxLeaf>) {
192
- const tokenClassName = props.leaf.className as string;
193
-
194
- return <PlateLeaf className={tokenClassName} {...props} />;
195
- }
196
-
197
- const languages: { label: string; value: string }[] = [
198
- { label: 'Auto', value: 'auto' },
199
- { label: 'Plain Text', value: 'plaintext' },
200
- { label: 'ABAP', value: 'abap' },
201
- { label: 'Agda', value: 'agda' },
202
- { label: 'Arduino', value: 'arduino' },
203
- { label: 'ASCII Art', value: 'ascii' },
204
- { label: 'Assembly', value: 'x86asm' },
205
- { label: 'Bash', value: 'bash' },
206
- { label: 'BASIC', value: 'basic' },
207
- { label: 'BNF', value: 'bnf' },
208
- { label: 'C', value: 'c' },
209
- { label: 'C#', value: 'csharp' },
210
- { label: 'C++', value: 'cpp' },
211
- { label: 'Clojure', value: 'clojure' },
212
- { label: 'CoffeeScript', value: 'coffeescript' },
213
- { label: 'Coq', value: 'coq' },
214
- { label: 'CSS', value: 'css' },
215
- { label: 'Dart', value: 'dart' },
216
- { label: 'Dhall', value: 'dhall' },
217
- { label: 'Diff', value: 'diff' },
218
- { label: 'Docker', value: 'dockerfile' },
219
- { label: 'EBNF', value: 'ebnf' },
220
- { label: 'Elixir', value: 'elixir' },
221
- { label: 'Elm', value: 'elm' },
222
- { label: 'Erlang', value: 'erlang' },
223
- { label: 'F#', value: 'fsharp' },
224
- { label: 'Flow', value: 'flow' },
225
- { label: 'Fortran', value: 'fortran' },
226
- { label: 'Gherkin', value: 'gherkin' },
227
- { label: 'GLSL', value: 'glsl' },
228
- { label: 'Go', value: 'go' },
229
- { label: 'GraphQL', value: 'graphql' },
230
- { label: 'Groovy', value: 'groovy' },
231
- { label: 'Haskell', value: 'haskell' },
232
- { label: 'HCL', value: 'hcl' },
233
- { label: 'HTML', value: 'html' },
234
- { label: 'Idris', value: 'idris' },
235
- { label: 'Java', value: 'java' },
236
- { label: 'JavaScript', value: 'javascript' },
237
- { label: 'JSON', value: 'json' },
238
- { label: 'Julia', value: 'julia' },
239
- { label: 'Kotlin', value: 'kotlin' },
240
- { label: 'LaTeX', value: 'latex' },
241
- { label: 'Less', value: 'less' },
242
- { label: 'Lisp', value: 'lisp' },
243
- { label: 'LiveScript', value: 'livescript' },
244
- { label: 'LLVM IR', value: 'llvm' },
245
- { label: 'Lua', value: 'lua' },
246
- { label: 'Makefile', value: 'makefile' },
247
- { label: 'Markdown', value: 'markdown' },
248
- { label: 'Markup', value: 'markup' },
249
- { label: 'MATLAB', value: 'matlab' },
250
- { label: 'Mathematica', value: 'mathematica' },
251
- { label: 'Mermaid', value: 'mermaid' },
252
- { label: 'Nix', value: 'nix' },
253
- { label: 'Notion Formula', value: 'notion' },
254
- { label: 'Objective-C', value: 'objectivec' },
255
- { label: 'OCaml', value: 'ocaml' },
256
- { label: 'Pascal', value: 'pascal' },
257
- { label: 'Perl', value: 'perl' },
258
- { label: 'PHP', value: 'php' },
259
- { label: 'PowerShell', value: 'powershell' },
260
- { label: 'Prolog', value: 'prolog' },
261
- { label: 'Protocol Buffers', value: 'protobuf' },
262
- { label: 'PureScript', value: 'purescript' },
263
- { label: 'Python', value: 'python' },
264
- { label: 'R', value: 'r' },
265
- { label: 'Racket', value: 'racket' },
266
- { label: 'Reason', value: 'reasonml' },
267
- { label: 'Ruby', value: 'ruby' },
268
- { label: 'Rust', value: 'rust' },
269
- { label: 'Sass', value: 'scss' },
270
- { label: 'Scala', value: 'scala' },
271
- { label: 'Scheme', value: 'scheme' },
272
- { label: 'SCSS', value: 'scss' },
273
- { label: 'Shell', value: 'shell' },
274
- { label: 'Smalltalk', value: 'smalltalk' },
275
- { label: 'Solidity', value: 'solidity' },
276
- { label: 'SQL', value: 'sql' },
277
- { label: 'Swift', value: 'swift' },
278
- { label: 'TOML', value: 'toml' },
279
- { label: 'TypeScript', value: 'typescript' },
280
- { label: 'VB.Net', value: 'vbnet' },
281
- { label: 'Verilog', value: 'verilog' },
282
- { label: 'VHDL', value: 'vhdl' },
283
- { label: 'Visual Basic', value: 'vbnet' },
284
- { label: 'WebAssembly', value: 'wasm' },
285
- { label: 'XML', value: 'xml' },
286
- { label: 'YAML', value: 'yaml' },
287
- ];
@@ -1,15 +0,0 @@
1
- import type { SlateLeafProps } from 'platejs/static';
2
-
3
- import { SlateLeaf } from 'platejs/static';
4
-
5
- export function CodeLeafStatic(props: SlateLeafProps) {
6
- return (
7
- <SlateLeaf
8
- {...props}
9
- as="code"
10
- className="whitespace-pre-wrap rounded-md bg-muted px-[0.3em] py-[0.2em] font-mono text-sm"
11
- >
12
- {props.children}
13
- </SlateLeaf>
14
- );
15
- }
@@ -1,17 +0,0 @@
1
-
2
-
3
- import type { PlateLeafProps } from 'platejs/react';
4
-
5
- import { PlateLeaf } from 'platejs/react';
6
-
7
- export function CodeLeaf(props: PlateLeafProps) {
8
- return (
9
- <PlateLeaf
10
- {...props}
11
- as="code"
12
- className="whitespace-pre-wrap rounded-md bg-muted px-[0.3em] py-[0.2em] font-mono text-sm"
13
- >
14
- {props.children}
15
- </PlateLeaf>
16
- );
17
- }
@@ -1,237 +0,0 @@
1
- import type { PlateElementProps } from 'platejs/react';
2
- import type { CodebaseSnippetElementType } from '@/components/editor/plugins/codebase-kit';
3
- import { useQuery } from '@tanstack/react-query';
4
- import { orpcTs } from '@/lib/orpc';
5
- import { createHighlighter, type Highlighter } from 'shiki';
6
- import { useEffect, useState } from 'react';
7
- import { useTheme } from '@/components/theme-provider';
8
- import { Copy, Settings } from 'lucide-react';
9
- import { FileSelector } from './file-selector';
10
- import { useEditorRef } from 'platejs/react';
11
- import { toast } from 'sonner';
12
-
13
- export function CodebaseSnippetElement({ attributes, children, element }: PlateElementProps<CodebaseSnippetElementType>) {
14
- const { theme } = useTheme();
15
- const editor = useEditorRef();
16
- const [highlighter, setHighlighter] = useState<Highlighter | null>(null);
17
- const [highlightedCode, setHighlightedCode] = useState<string>('');
18
- const [fileSelectorOpen, setFileSelectorOpen] = useState(false);
19
-
20
- const fileContents = useQuery({
21
- ...orpcTs.codebase.getFileContents.queryOptions({
22
- input: {
23
- filePath: element.filePath || '',
24
- },
25
-
26
- }),
27
- enabled: !!element.filePath,
28
- })
29
-
30
- const language = getLanguageFromPath(element.filePath);
31
-
32
- useEffect(() => {
33
- let mounted = true;
34
-
35
- const initHighlighter = async () => {
36
- try {
37
- const h = await createHighlighter({
38
- themes: ['github-dark', 'github-light'],
39
- langs: [language, 'text'],
40
- });
41
- if (mounted) {
42
- setHighlighter(h);
43
- }
44
- } catch (error) {
45
- console.error('Failed to create highlighter:', error);
46
- }
47
- };
48
-
49
- initHighlighter();
50
-
51
- return () => {
52
- mounted = false;
53
- };
54
- }, [language]);
55
-
56
- useEffect(() => {
57
- if (!highlighter || !fileContents.data) return;
58
-
59
- const highlightCode = async () => {
60
- const code = fileContents.data?.contents || '';
61
- const startLine = element.lineStart ? parseInt(element.lineStart) : 1;
62
- let endLine: number | undefined = undefined;
63
- if (element.lineEnd) {
64
- endLine = parseInt(element.lineEnd);
65
- } else {
66
- // If lineEnd is not specified, use the total number of lines as the maximum
67
- endLine = code.split('\n').length;
68
- }
69
-
70
- let codeToHighlight = code;
71
- let actualStartLine = startLine;
72
- if (startLine !== undefined && endLine !== undefined) {
73
- const lines = code.split('\n');
74
- codeToHighlight = lines.slice(startLine - 1, endLine).join('\n');
75
- actualStartLine = startLine;
76
- } else if (startLine !== undefined) {
77
- const lines = code.split('\n');
78
- codeToHighlight = lines.slice(startLine - 1).join('\n');
79
- actualStartLine = startLine;
80
- }
81
-
82
- try {
83
- const html = highlighter.codeToHtml(codeToHighlight, {
84
- lang: language,
85
- theme: theme === 'dark' ? 'github-dark' : 'github-light',
86
- });
87
-
88
- // Extract the inner content from Shiki's HTML (it wraps in pre>code)
89
- const tempDiv = document.createElement('div');
90
- tempDiv.innerHTML = html;
91
- const codeElement = tempDiv.querySelector('pre code') || tempDiv.querySelector('code');
92
- const codeContent = codeElement ? codeElement.innerHTML : html;
93
-
94
- // Split code into lines
95
- const lines = codeToHighlight.split('\n');
96
- const highlightedLines = codeContent.split('\n');
97
-
98
- // Create line-by-line structure with numbers
99
- const lineItems = lines.map((_, index) => {
100
- const lineNumber = actualStartLine + index;
101
- const highlightedLine = highlightedLines[index] || '';
102
- return `<div class="flex gap-4 hover:bg-muted/50 transition-colors"><span class="inline-block w-10 text-right text-muted-foreground select-none flex-shrink-0">${lineNumber}</span><code class="flex-1">${highlightedLine || '\n'}</code></div>`;
103
- }).join('');
104
-
105
- // Wrap the highlighted code with line numbers
106
- const codeWithLineNumbers = `<div class="overflow-x-auto"><div class="p-4 text-sm leading-normal font-mono m-0">${lineItems}</div></div>`;
107
-
108
- setHighlightedCode(codeWithLineNumbers);
109
- } catch (error) {
110
- console.error('Failed to highlight code:', error);
111
- const lines = codeToHighlight.split('\n');
112
- const lineItems = lines.map((line, index) => {
113
- const lineNumber = actualStartLine + index;
114
- return `<div class="flex gap-4 hover:bg-muted/50 transition-colors"><span class="inline-block w-10 text-right text-muted-foreground select-none flex-shrink-0">${lineNumber}</span><code class="flex-1">${line || '\n'}</code></div>`;
115
- }).join('');
116
-
117
- const fallbackHtml = `<div class="overflow-x-auto"><pre class="p-4 text-sm leading-normal font-mono m-0">${lineItems}</pre></div>`;
118
- setHighlightedCode(fallbackHtml);
119
- }
120
- };
121
-
122
- highlightCode();
123
- }, [highlighter, fileContents.data, language, theme, element.lineStart, element.lineEnd]);
124
-
125
- const handleCopy = () => {
126
- void navigator.clipboard.writeText(fileContents.data?.contents || '');
127
- toast.success('Copied to clipboard');
128
- }
129
-
130
- return (
131
- <div contentEditable={false} {...attributes} className="codebase-snippet my-4 rounded-lg border overflow-hidden">
132
- <div className="bg-muted px-4 py-2 border-b flex justify-between items-center">
133
- <div className='flex items-center gap-2'>
134
- <a href={`vscode://file/${fileContents.data?.fullPath || ''}:${element.lineStart}`}>
135
- <p className="text-sm font-medium text-muted-foreground">{element.filePath}</p>
136
- </a>
137
- <button
138
- className='bg-transparent border-none p-0 m-0 cursor-pointer'
139
- onClick={() => setFileSelectorOpen(true)}
140
- >
141
- <Settings className='size-4 text-muted-foreground' />
142
- </button>
143
- </div>
144
- <button className='bg-transparent border-none p-0 m-0 cursor-pointer' onClick={handleCopy}>
145
- <Copy className='size-4 text-muted-foreground' />
146
- </button>
147
- </div>
148
- <div className="relative">
149
- {fileContents.isLoading ? (
150
- <div className="p-4 text-sm text-muted-foreground">Loading code...</div>
151
- ) : highlightedCode ? (
152
- <div
153
- dangerouslySetInnerHTML={{ __html: highlightedCode }}
154
- />
155
- ) : (
156
- <div className="p-4 text-sm text-muted-foreground">No code to display</div>
157
- )}
158
- </div>
159
- <div className="bg-muted px-4 py-2 border-t flex justify-between items-center">
160
- <p className="text-sm font-medium text-muted-foreground">Line {element.lineStart} - {element.lineEnd}</p>
161
- </div>
162
- {children}
163
- <FileSelector
164
- open={fileSelectorOpen}
165
- onClose={() => setFileSelectorOpen(false)}
166
- onSelect={(filePath, startLine, endLine) => {
167
- editor.tf.setNodes(
168
- {
169
- filePath,
170
- lineStart: String(startLine),
171
- lineEnd: String(endLine),
172
- },
173
- { at: element }
174
- );
175
- }}
176
- currentFilePath={element.filePath}
177
- currentStartLine={element.lineStart}
178
- currentEndLine={element.lineEnd}
179
- />
180
- </div>
181
- )
182
- }
183
-
184
- function getLanguageFromPath(path?: string) {
185
- if (!path) return 'text';
186
-
187
- const ext = path.split('.').pop();
188
-
189
- switch (ext) {
190
- case 'ts':
191
- return 'ts';
192
- case 'tsx':
193
- return 'tsx';
194
- case 'jsx':
195
- return 'jsx';
196
- case 'js':
197
- return 'javascript';
198
- case 'json':
199
- return 'json';
200
- case 'go':
201
- return 'go';
202
- case 'java':
203
- return 'java';
204
- case 'kt':
205
- return 'kotlin';
206
- case 'php':
207
- return 'php';
208
- case 'rb':
209
- return 'ruby';
210
- case 'rs':
211
- return 'rust';
212
- case 'scala':
213
- return 'scala';
214
- case 'swift':
215
- return 'swift';
216
- case 'vb':
217
- return 'vbnet';
218
- case 'cs':
219
- return 'csharp';
220
- case 'py':
221
- return 'python';
222
- case 'md':
223
- return 'markdown';
224
- case 'sh':
225
- return 'shell';
226
- case 'css':
227
- return 'css';
228
- case 'html':
229
- return 'html';
230
- case 'xml':
231
- return 'xml';
232
- case 'yaml':
233
- return 'yaml';
234
- default:
235
- return 'text';
236
- }
237
- }
@@ -1,29 +0,0 @@
1
- import type { TColumnElement } from 'platejs';
2
- import type { SlateElementProps } from 'platejs/static';
3
-
4
- import { SlateElement } from 'platejs/static';
5
-
6
- export function ColumnElementStatic(props: SlateElementProps<TColumnElement>) {
7
- const { width } = props.element;
8
-
9
- return (
10
- <div className="group/column relative" style={{ width: width ?? '100%' }}>
11
- <SlateElement
12
- className="h-full px-2 pt-2 group-first/column:pl-0 group-last/column:pr-0"
13
- {...props}
14
- >
15
- <div className="relative h-full border border-transparent p-1.5">
16
- {props.children}
17
- </div>
18
- </SlateElement>
19
- </div>
20
- );
21
- }
22
-
23
- export function ColumnGroupElementStatic(props: SlateElementProps) {
24
- return (
25
- <SlateElement className="mb-2" {...props}>
26
- <div className="flex size-full rounded">{props.children}</div>
27
- </SlateElement>
28
- );
29
- }