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,414 +0,0 @@
1
- import React from 'react';
2
-
3
- import type { Point, TElement } from 'platejs';
4
-
5
- import {
6
- type ComboboxItemProps,
7
- Combobox,
8
- ComboboxGroup,
9
- ComboboxGroupLabel,
10
- ComboboxItem,
11
- ComboboxPopover,
12
- ComboboxProvider,
13
- ComboboxRow,
14
- Portal,
15
- useComboboxContext,
16
- useComboboxStore,
17
- } from '@ariakit/react';
18
- import { filterWords } from '@platejs/combobox';
19
- import {
20
- type UseComboboxInputResult,
21
- useComboboxInput,
22
- useHTMLInputCursorState,
23
- } from '@platejs/combobox/react';
24
- import { cva } from 'class-variance-authority';
25
- import { useComposedRef, useEditorRef } from 'platejs/react';
26
-
27
- import { cn } from '@/lib/utils';
28
- import { YjsPlugin } from '@platejs/yjs/react';
29
-
30
- type FilterFn = (
31
- item: { value: string; group?: string; keywords?: string[]; label?: string },
32
- search: string
33
- ) => boolean;
34
-
35
- type InlineComboboxContextValue = {
36
- filter: FilterFn | false;
37
- inputProps: UseComboboxInputResult['props'];
38
- inputRef: React.RefObject<HTMLInputElement | null>;
39
- removeInput: UseComboboxInputResult['removeInput'];
40
- showTrigger: boolean;
41
- trigger: string;
42
- setHasEmpty: (hasEmpty: boolean) => void;
43
- };
44
-
45
- const InlineComboboxContext = React.createContext<InlineComboboxContextValue>(
46
- null as unknown as InlineComboboxContextValue
47
- );
48
-
49
- const defaultFilter: FilterFn = (
50
- { group, keywords = [], label, value },
51
- search
52
- ) => {
53
- const uniqueTerms = new Set(
54
- [value, ...keywords, group, label].filter(Boolean)
55
- );
56
-
57
- return Array.from(uniqueTerms).some((keyword) =>
58
- filterWords(keyword!, search)
59
- );
60
- };
61
-
62
- type InlineComboboxProps = {
63
- children: React.ReactNode;
64
- element: TElement;
65
- trigger: string;
66
- filter?: FilterFn | false;
67
- hideWhenNoValue?: boolean;
68
- showTrigger?: boolean;
69
- value?: string;
70
- setValue?: (value: string) => void;
71
- };
72
-
73
- const InlineCombobox = ({
74
- children,
75
- element,
76
- filter = defaultFilter,
77
- hideWhenNoValue = false,
78
- setValue: setValueProp,
79
- showTrigger = true,
80
- trigger,
81
- value: valueProp,
82
- }: InlineComboboxProps) => {
83
- const editor = useEditorRef();
84
- const inputRef = React.useRef<HTMLInputElement>(null);
85
- const cursorState = useHTMLInputCursorState(inputRef);
86
-
87
- const [valueState, setValueState] = React.useState('');
88
- const hasValueProp = valueProp !== undefined;
89
- const value = hasValueProp ? valueProp : valueState;
90
-
91
- // Check if current user is the creator of this element (for Yjs collaboration)
92
- const isCreator = React.useMemo(() => {
93
- const elementUserId = (element as any).userId;
94
- const currentUserId = editor.getOption(YjsPlugin, 'userId');
95
-
96
- // If no userId (backwards compatibility or non-Yjs), allow
97
- if (!elementUserId) return true;
98
-
99
- return elementUserId === currentUserId;
100
- }, [editor, element]);
101
-
102
- const setValue = React.useCallback(
103
- (newValue: string) => {
104
- setValueProp?.(newValue);
105
-
106
- if (!hasValueProp) {
107
- setValueState(newValue);
108
- }
109
- },
110
- [setValueProp, hasValueProp]
111
- );
112
-
113
- /**
114
- * Track the point just before the input element so we know where to
115
- * insertText if the combobox closes due to a selection change.
116
- */
117
- const insertPoint = React.useRef<Point | null>(null);
118
-
119
- React.useEffect(() => {
120
- const path = editor.api.findPath(element);
121
-
122
- if (!path) return;
123
-
124
- const point = editor.api.before(path);
125
-
126
- if (!point) return;
127
-
128
- const pointRef = editor.api.pointRef(point);
129
- insertPoint.current = pointRef.current;
130
-
131
- return () => {
132
- pointRef.unref();
133
- };
134
- }, [editor, element]);
135
-
136
- const { props: inputProps, removeInput } = useComboboxInput({
137
- cancelInputOnBlur: true,
138
- cursorState,
139
- autoFocus: isCreator,
140
- ref: inputRef,
141
- onCancelInput: (cause) => {
142
- if (cause !== 'backspace') {
143
- editor.tf.insertText(trigger + value, {
144
- at: insertPoint?.current ?? undefined,
145
- });
146
- }
147
- if (cause === 'arrowLeft' || cause === 'arrowRight') {
148
- editor.tf.move({
149
- distance: 1,
150
- reverse: cause === 'arrowLeft',
151
- });
152
- }
153
- },
154
- });
155
-
156
- const [hasEmpty, setHasEmpty] = React.useState(false);
157
-
158
- const contextValue: InlineComboboxContextValue = React.useMemo(
159
- () => ({
160
- filter,
161
- inputProps,
162
- inputRef,
163
- removeInput,
164
- setHasEmpty,
165
- showTrigger,
166
- trigger,
167
- }),
168
- [
169
- trigger,
170
- showTrigger,
171
- filter,
172
- inputRef,
173
- inputProps,
174
- removeInput,
175
- setHasEmpty,
176
- ]
177
- );
178
-
179
- const store = useComboboxStore({
180
- // open: ,
181
- setValue: (newValue) => React.startTransition(() => setValue(newValue)),
182
- });
183
-
184
- const items = store.useState('items');
185
-
186
- /**
187
- * If there is no active ID and the list of items changes, select the first
188
- * item.
189
- */
190
- React.useEffect(() => {
191
- if (!store.getState().activeId) {
192
- store.setActiveId(store.first());
193
- }
194
- }, [items, store]);
195
-
196
- return (
197
- <span contentEditable={false}>
198
- <ComboboxProvider
199
- open={
200
- (items.length > 0 || hasEmpty) &&
201
- (!hideWhenNoValue || value.length > 0)
202
- }
203
- store={store}
204
- >
205
- <InlineComboboxContext.Provider value={contextValue}>
206
- {children}
207
- </InlineComboboxContext.Provider>
208
- </ComboboxProvider>
209
- </span>
210
- );
211
- };
212
-
213
- const InlineComboboxInput = ({
214
- className,
215
- ref: propRef,
216
- ...props
217
- }: React.HTMLAttributes<HTMLInputElement> & {
218
- ref?: React.RefObject<HTMLInputElement | null>;
219
- }) => {
220
- const {
221
- inputProps,
222
- inputRef: contextRef,
223
- showTrigger,
224
- trigger,
225
- } = React.useContext(InlineComboboxContext);
226
-
227
- const store = useComboboxContext()!;
228
- const value = store.useState('value');
229
-
230
- const ref = useComposedRef(propRef, contextRef);
231
-
232
- /**
233
- * To create an auto-resizing input, we render a visually hidden span
234
- * containing the input value and position the input element on top of it.
235
- * This works well for all cases except when input exceeds the width of the
236
- * container.
237
- */
238
-
239
- return (
240
- <>
241
- {showTrigger && trigger}
242
-
243
- <span className="relative min-h-[1lh]">
244
- <span
245
- className="invisible overflow-hidden text-nowrap"
246
- aria-hidden="true"
247
- >
248
- {value || '\u200B'}
249
- </span>
250
-
251
- <Combobox
252
- ref={ref}
253
- className={cn(
254
- 'absolute top-0 left-0 size-full bg-transparent outline-none',
255
- className
256
- )}
257
- value={value}
258
- autoSelect
259
- {...inputProps}
260
- {...props}
261
- />
262
- </span>
263
- </>
264
- );
265
- };
266
-
267
- InlineComboboxInput.displayName = 'InlineComboboxInput';
268
-
269
- const InlineComboboxContent: typeof ComboboxPopover = ({
270
- className,
271
- ...props
272
- }) => {
273
- // Portal prevents CSS from leaking into popover
274
- return (
275
- <Portal>
276
- <ComboboxPopover
277
- className={cn(
278
- 'z-500 max-h-[288px] w-[300px] overflow-y-auto rounded-md bg-popover shadow-md',
279
- className
280
- )}
281
- {...props}
282
- />
283
- </Portal>
284
- );
285
- };
286
-
287
- const comboboxItemVariants = cva(
288
- 'relative mx-1 flex h-[28px] select-none items-center rounded-sm px-2 text-foreground text-sm outline-none [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
289
- {
290
- defaultVariants: {
291
- interactive: true,
292
- },
293
- variants: {
294
- interactive: {
295
- false: '',
296
- true: 'cursor-pointer transition-colors hover:bg-accent hover:text-accent-foreground data-[active-item=true]:bg-accent data-[active-item=true]:text-accent-foreground',
297
- },
298
- },
299
- }
300
- );
301
-
302
- const InlineComboboxItem = ({
303
- className,
304
- focusEditor = true,
305
- group,
306
- keywords,
307
- label,
308
- onClick,
309
- ...props
310
- }: {
311
- focusEditor?: boolean;
312
- group?: string;
313
- keywords?: string[];
314
- label?: string;
315
- } & ComboboxItemProps &
316
- Required<Pick<ComboboxItemProps, 'value'>>) => {
317
- const { value } = props;
318
-
319
- const { filter, removeInput } = React.useContext(InlineComboboxContext);
320
-
321
- const store = useComboboxContext()!;
322
-
323
- // Optimization: Do not subscribe to value if filter is false
324
- const search = filter && store.useState('value');
325
-
326
- const visible = React.useMemo(
327
- () =>
328
- !filter || filter({ group, keywords, label, value }, search as string),
329
- [filter, group, keywords, label, value, search]
330
- );
331
-
332
- if (!visible) return null;
333
-
334
- return (
335
- <ComboboxItem
336
- className={cn(comboboxItemVariants(), className)}
337
- onClick={(event) => {
338
- removeInput(focusEditor);
339
- onClick?.(event);
340
- }}
341
- {...props}
342
- />
343
- );
344
- };
345
-
346
- const InlineComboboxEmpty = ({
347
- children,
348
- className,
349
- }: React.HTMLAttributes<HTMLDivElement>) => {
350
- const { setHasEmpty } = React.useContext(InlineComboboxContext);
351
- const store = useComboboxContext()!;
352
- const items = store.useState('items');
353
-
354
- React.useEffect(() => {
355
- setHasEmpty(true);
356
-
357
- return () => {
358
- setHasEmpty(false);
359
- };
360
- }, [setHasEmpty]);
361
-
362
- if (items.length > 0) return null;
363
-
364
- return (
365
- <div
366
- className={cn(comboboxItemVariants({ interactive: false }), className)}
367
- >
368
- {children}
369
- </div>
370
- );
371
- };
372
-
373
- const InlineComboboxRow = ComboboxRow;
374
-
375
- function InlineComboboxGroup({
376
- className,
377
- ...props
378
- }: React.ComponentProps<typeof ComboboxGroup>) {
379
- return (
380
- <ComboboxGroup
381
- {...props}
382
- className={cn(
383
- 'hidden not-last:border-b py-1.5 [&:has([role=option])]:block',
384
- className
385
- )}
386
- />
387
- );
388
- }
389
-
390
- function InlineComboboxGroupLabel({
391
- className,
392
- ...props
393
- }: React.ComponentProps<typeof ComboboxGroupLabel>) {
394
- return (
395
- <ComboboxGroupLabel
396
- {...props}
397
- className={cn(
398
- 'mt-1.5 mb-2 px-3 font-medium text-muted-foreground text-xs',
399
- className
400
- )}
401
- />
402
- );
403
- }
404
-
405
- export {
406
- InlineCombobox,
407
- InlineComboboxContent,
408
- InlineComboboxEmpty,
409
- InlineComboboxGroup,
410
- InlineComboboxGroupLabel,
411
- InlineComboboxInput,
412
- InlineComboboxItem,
413
- InlineComboboxRow,
414
- };
@@ -1,21 +0,0 @@
1
- import * as React from "react"
2
-
3
- import { cn } from "@/lib/utils"
4
-
5
- function Input({ className, type, ...props }: React.ComponentProps<"input">) {
6
- return (
7
- <input
8
- type={type}
9
- data-slot="input"
10
- className={cn(
11
- "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
12
- "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
13
- "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
14
- className
15
- )}
16
- {...props}
17
- />
18
- )
19
- }
20
-
21
- export { Input }
@@ -1,254 +0,0 @@
1
- import React from 'react';
2
-
3
- import type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';
4
-
5
- import {
6
- CalendarIcon,
7
- ChevronRightIcon,
8
- Columns3Icon,
9
- FileCodeIcon,
10
- FilmIcon,
11
- Heading1Icon,
12
- Heading2Icon,
13
- Heading3Icon,
14
- ImageIcon,
15
- Link2Icon,
16
- ListIcon,
17
- ListOrderedIcon,
18
- MinusIcon,
19
- PenToolIcon,
20
- PilcrowIcon,
21
- PlusIcon,
22
- QuoteIcon,
23
- RadicalIcon,
24
- SquareIcon,
25
- TableIcon,
26
- TableOfContentsIcon,
27
- } from 'lucide-react';
28
- import { KEYS } from 'platejs';
29
- import { type PlateEditor, useEditorRef } from 'platejs/react';
30
-
31
- import {
32
- DropdownMenu,
33
- DropdownMenuContent,
34
- DropdownMenuItem,
35
- DropdownMenuTrigger,
36
- } from '@/components/ui/dropdown-menu';
37
- import {
38
- insertBlock,
39
- insertInlineElement,
40
- } from '@/components/editor/transforms';
41
-
42
- import { ToolbarButton, ToolbarMenuGroup } from './toolbar';
43
-
44
- type Group = {
45
- group: string;
46
- items: Item[];
47
- };
48
-
49
- type Item = {
50
- icon: React.ReactNode;
51
- value: string;
52
- onSelect: (editor: PlateEditor, value: string) => void;
53
- focusEditor?: boolean;
54
- label?: string;
55
- };
56
-
57
- const groups: Group[] = [
58
- {
59
- group: 'Basic blocks',
60
- items: [
61
- {
62
- icon: <PilcrowIcon />,
63
- label: 'Paragraph',
64
- value: KEYS.p,
65
- },
66
- {
67
- icon: <Heading1Icon />,
68
- label: 'Heading 1',
69
- value: 'h1',
70
- },
71
- {
72
- icon: <Heading2Icon />,
73
- label: 'Heading 2',
74
- value: 'h2',
75
- },
76
- {
77
- icon: <Heading3Icon />,
78
- label: 'Heading 3',
79
- value: 'h3',
80
- },
81
- {
82
- icon: <TableIcon />,
83
- label: 'Table',
84
- value: KEYS.table,
85
- },
86
- {
87
- icon: <FileCodeIcon />,
88
- label: 'Code',
89
- value: KEYS.codeBlock,
90
- },
91
- {
92
- icon: <QuoteIcon />,
93
- label: 'Quote',
94
- value: KEYS.blockquote,
95
- },
96
- {
97
- icon: <MinusIcon />,
98
- label: 'Divider',
99
- value: KEYS.hr,
100
- },
101
- ].map((item) => ({
102
- ...item,
103
- onSelect: (editor, value) => {
104
- insertBlock(editor, value);
105
- },
106
- })),
107
- },
108
- {
109
- group: 'Lists',
110
- items: [
111
- {
112
- icon: <ListIcon />,
113
- label: 'Bulleted list',
114
- value: KEYS.ul,
115
- },
116
- {
117
- icon: <ListOrderedIcon />,
118
- label: 'Numbered list',
119
- value: KEYS.ol,
120
- },
121
- {
122
- icon: <SquareIcon />,
123
- label: 'To-do list',
124
- value: KEYS.listTodo,
125
- },
126
- {
127
- icon: <ChevronRightIcon />,
128
- label: 'Toggle list',
129
- value: KEYS.toggle,
130
- },
131
- ].map((item) => ({
132
- ...item,
133
- onSelect: (editor, value) => {
134
- insertBlock(editor, value);
135
- },
136
- })),
137
- },
138
- {
139
- group: 'Media',
140
- items: [
141
- {
142
- icon: <ImageIcon />,
143
- label: 'Image',
144
- value: KEYS.img,
145
- },
146
- {
147
- icon: <FilmIcon />,
148
- label: 'Embed',
149
- value: KEYS.mediaEmbed,
150
- },
151
- ].map((item) => ({
152
- ...item,
153
- onSelect: (editor, value) => {
154
- insertBlock(editor, value);
155
- },
156
- })),
157
- },
158
- {
159
- group: 'Advanced blocks',
160
- items: [
161
- {
162
- icon: <TableOfContentsIcon />,
163
- label: 'Table of contents',
164
- value: KEYS.toc,
165
- },
166
- {
167
- icon: <Columns3Icon />,
168
- label: '3 columns',
169
- value: 'action_three_columns',
170
- },
171
- {
172
- focusEditor: false,
173
- icon: <RadicalIcon />,
174
- label: 'Equation',
175
- value: KEYS.equation,
176
- },
177
- {
178
- icon: <PenToolIcon />,
179
- label: 'Excalidraw',
180
- value: KEYS.excalidraw,
181
- },
182
- ].map((item) => ({
183
- ...item,
184
- onSelect: (editor, value) => {
185
- insertBlock(editor, value);
186
- },
187
- })),
188
- },
189
- {
190
- group: 'Inline',
191
- items: [
192
- {
193
- icon: <Link2Icon />,
194
- label: 'Link',
195
- value: KEYS.link,
196
- },
197
- {
198
- focusEditor: true,
199
- icon: <CalendarIcon />,
200
- label: 'Date',
201
- value: KEYS.date,
202
- },
203
- {
204
- focusEditor: false,
205
- icon: <RadicalIcon />,
206
- label: 'Inline Equation',
207
- value: KEYS.inlineEquation,
208
- },
209
- ].map((item) => ({
210
- ...item,
211
- onSelect: (editor, value) => {
212
- insertInlineElement(editor, value);
213
- },
214
- })),
215
- },
216
- ];
217
-
218
- export function InsertToolbarButton(props: DropdownMenuProps) {
219
- const editor = useEditorRef();
220
- const [open, setOpen] = React.useState(false);
221
-
222
- return (
223
- <DropdownMenu open={open} onOpenChange={setOpen} modal={false} {...props}>
224
- <DropdownMenuTrigger asChild>
225
- <ToolbarButton pressed={open} tooltip="Insert" isDropdown>
226
- <PlusIcon />
227
- </ToolbarButton>
228
- </DropdownMenuTrigger>
229
-
230
- <DropdownMenuContent
231
- className="flex max-h-[500px] min-w-0 flex-col overflow-y-auto"
232
- align="start"
233
- >
234
- {groups.map(({ group, items: nestedItems }) => (
235
- <ToolbarMenuGroup key={group} label={group}>
236
- {nestedItems.map(({ icon, label, value, onSelect }) => (
237
- <DropdownMenuItem
238
- key={value}
239
- className="min-w-[180px]"
240
- onSelect={() => {
241
- onSelect(editor, value);
242
- editor.tf.focus();
243
- }}
244
- >
245
- {icon}
246
- {label}
247
- </DropdownMenuItem>
248
- ))}
249
- </ToolbarMenuGroup>
250
- ))}
251
- </DropdownMenuContent>
252
- </DropdownMenu>
253
- );
254
- }
@@ -1,15 +0,0 @@
1
- import type { SlateLeafProps } from 'platejs/static';
2
-
3
- import { SlateLeaf } from 'platejs/static';
4
-
5
- export function KbdLeafStatic(props: SlateLeafProps) {
6
- return (
7
- <SlateLeaf
8
- {...props}
9
- as="kbd"
10
- className="rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-sm shadow-[rgba(255,_255,_255,_0.1)_0px_0.5px_0px_0px_inset,_rgb(248,_249,_250)_0px_1px_5px_0px_inset,_rgb(193,_200,_205)_0px_0px_0px_0.5px,_rgb(193,_200,_205)_0px_2px_1px_-1px,_rgb(193,_200,_205)_0px_1px_0px_0px] dark:shadow-[rgba(255,_255,_255,_0.1)_0px_0.5px_0px_0px_inset,_rgb(26,_29,_30)_0px_1px_5px_0px_inset,_rgb(76,_81,_85)_0px_0px_0px_0.5px,_rgb(76,_81,_85)_0px_2px_1px_-1px,_rgb(76,_81,_85)_0px_1px_0px_0px]"
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 KbdLeaf(props: PlateLeafProps) {
8
- return (
9
- <PlateLeaf
10
- {...props}
11
- as="kbd"
12
- className="rounded border border-border bg-muted px-1.5 py-0.5 font-mono text-sm shadow-[rgba(255,_255,_255,_0.1)_0px_0.5px_0px_0px_inset,_rgb(248,_249,_250)_0px_1px_5px_0px_inset,_rgb(193,_200,_205)_0px_0px_0px_0.5px,_rgb(193,_200,_205)_0px_2px_1px_-1px,_rgb(193,_200,_205)_0px_1px_0px_0px] dark:shadow-[rgba(255,_255,_255,_0.1)_0px_0.5px_0px_0px_inset,_rgb(26,_29,_30)_0px_1px_5px_0px_inset,_rgb(76,_81,_85)_0px_0px_0px_0.5px,_rgb(76,_81,_85)_0px_2px_1px_-1px,_rgb(76,_81,_85)_0px_1px_0px_0px]"
13
- >
14
- {props.children}
15
- </PlateLeaf>
16
- );
17
- }