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,656 +0,0 @@
1
- import React from 'react';
2
-
3
- import type * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
4
-
5
- import { useDraggable, useDropLine } from '@platejs/dnd';
6
- import {
7
- BlockSelectionPlugin,
8
- useBlockSelected,
9
- } from '@platejs/selection/react';
10
- import { setCellBackground } from '@platejs/table';
11
- import {
12
- TablePlugin,
13
- TableProvider,
14
- useTableBordersDropdownMenuContentState,
15
- useTableCellElement,
16
- useTableCellElementResizable,
17
- useTableElement,
18
- useTableMergeState,
19
- } from '@platejs/table/react';
20
- import { PopoverAnchor } from '@radix-ui/react-popover';
21
- import { cva } from 'class-variance-authority';
22
- import {
23
- ArrowDown,
24
- ArrowLeft,
25
- ArrowRight,
26
- ArrowUp,
27
- CombineIcon,
28
- EraserIcon,
29
- Grid2X2Icon,
30
- GripVertical,
31
- PaintBucketIcon,
32
- SquareSplitHorizontalIcon,
33
- Trash2Icon,
34
- XIcon,
35
- } from 'lucide-react';
36
- import {
37
- type TElement,
38
- type TTableCellElement,
39
- type TTableElement,
40
- type TTableRowElement,
41
- KEYS,
42
- PathApi,
43
- } from 'platejs';
44
- import {
45
- type PlateElementProps,
46
- PlateElement,
47
- useComposedRef,
48
- useEditorPlugin,
49
- useEditorRef,
50
- useEditorSelector,
51
- useElement,
52
- useFocusedLast,
53
- usePluginOption,
54
- useReadOnly,
55
- useRemoveNodeButton,
56
- useSelected,
57
- withHOC,
58
- } from 'platejs/react';
59
- import { useElementSelector } from 'platejs/react';
60
-
61
- import { Button } from '@/components/ui/button';
62
- import {
63
- DropdownMenu,
64
- DropdownMenuCheckboxItem,
65
- DropdownMenuContent,
66
- DropdownMenuGroup,
67
- DropdownMenuItem,
68
- DropdownMenuPortal,
69
- DropdownMenuTrigger,
70
- } from '@/components/ui/dropdown-menu';
71
- import { Popover, PopoverContent } from '@/components/ui/popover';
72
- import { cn } from '@/lib/utils';
73
-
74
- import { blockSelectionVariants } from './block-selection';
75
- import {
76
- ColorDropdownMenuItems,
77
- DEFAULT_COLORS,
78
- } from './font-color-toolbar-button';
79
- import { ResizeHandle } from './resize-handle';
80
- import {
81
- BorderAllIcon,
82
- BorderBottomIcon,
83
- BorderLeftIcon,
84
- BorderNoneIcon,
85
- BorderRightIcon,
86
- BorderTopIcon,
87
- } from './table-icons';
88
- import {
89
- Toolbar,
90
- ToolbarButton,
91
- ToolbarGroup,
92
- ToolbarMenuGroup,
93
- } from './toolbar';
94
- export const TableElement = withHOC(
95
- TableProvider,
96
- function TableElement({
97
- children,
98
- ...props
99
- }: PlateElementProps<TTableElement>) {
100
- const readOnly = useReadOnly();
101
- const isSelectionAreaVisible = usePluginOption(
102
- BlockSelectionPlugin,
103
- 'isSelectionAreaVisible'
104
- );
105
- const hasControls = !readOnly && !isSelectionAreaVisible;
106
- const {
107
- isSelectingCell,
108
- marginLeft,
109
- props: tableProps,
110
- } = useTableElement();
111
-
112
- const isSelectingTable = useBlockSelected(props.element.id as string);
113
-
114
- const content = (
115
- <PlateElement
116
- {...props}
117
- className={cn(
118
- 'overflow-x-auto py-5',
119
- hasControls && '-ml-2 *:data-[slot=block-selection]:left-2'
120
- )}
121
- style={{ paddingLeft: marginLeft }}
122
- >
123
- <div className="group/table relative w-fit">
124
- <table
125
- className={cn(
126
- 'mr-0 ml-px table h-px table-fixed border-collapse',
127
- isSelectingCell && 'selection:bg-transparent'
128
- )}
129
- {...tableProps}
130
- >
131
- <tbody className="min-w-full">{children}</tbody>
132
- </table>
133
-
134
- {isSelectingTable && (
135
- <div className={blockSelectionVariants()} contentEditable={false} />
136
- )}
137
- </div>
138
- </PlateElement>
139
- );
140
-
141
- if (readOnly) {
142
- return content;
143
- }
144
-
145
- return <TableFloatingToolbar>{content}</TableFloatingToolbar>;
146
- }
147
- );
148
-
149
- function TableFloatingToolbar({
150
- children,
151
- ...props
152
- }: React.ComponentProps<typeof PopoverContent>) {
153
- const { tf } = useEditorPlugin(TablePlugin);
154
- const selected = useSelected();
155
- const element = useElement<TTableElement>();
156
- const { props: buttonProps } = useRemoveNodeButton({ element });
157
- const collapsedInside = useEditorSelector(
158
- (editor) => selected && editor.api.isCollapsed(),
159
- [selected]
160
- );
161
- const isFocusedLast = useFocusedLast();
162
-
163
- const { canMerge, canSplit } = useTableMergeState();
164
-
165
- return (
166
- <Popover
167
- open={isFocusedLast && (canMerge || canSplit || collapsedInside)}
168
- modal={false}
169
- >
170
- <PopoverAnchor asChild>{children}</PopoverAnchor>
171
- <PopoverContent
172
- asChild
173
- onOpenAutoFocus={(e) => e.preventDefault()}
174
- contentEditable={false}
175
- {...props}
176
- >
177
- <Toolbar
178
- className="scrollbar-hide flex w-auto max-w-[80vw] flex-row overflow-x-auto rounded-md border bg-popover p-1 shadow-md print:hidden"
179
- contentEditable={false}
180
- >
181
- <ToolbarGroup>
182
- <ColorDropdownMenu tooltip="Background color">
183
- <PaintBucketIcon />
184
- </ColorDropdownMenu>
185
- {canMerge && (
186
- <ToolbarButton
187
- onClick={() => tf.table.merge()}
188
- onMouseDown={(e) => e.preventDefault()}
189
- tooltip="Merge cells"
190
- >
191
- <CombineIcon />
192
- </ToolbarButton>
193
- )}
194
- {canSplit && (
195
- <ToolbarButton
196
- onClick={() => tf.table.split()}
197
- onMouseDown={(e) => e.preventDefault()}
198
- tooltip="Split cell"
199
- >
200
- <SquareSplitHorizontalIcon />
201
- </ToolbarButton>
202
- )}
203
-
204
- <DropdownMenu modal={false}>
205
- <DropdownMenuTrigger asChild>
206
- <ToolbarButton tooltip="Cell borders">
207
- <Grid2X2Icon />
208
- </ToolbarButton>
209
- </DropdownMenuTrigger>
210
-
211
- <DropdownMenuPortal>
212
- <TableBordersDropdownMenuContent />
213
- </DropdownMenuPortal>
214
- </DropdownMenu>
215
-
216
- {collapsedInside && (
217
- <ToolbarGroup>
218
- <ToolbarButton tooltip="Delete table" {...buttonProps}>
219
- <Trash2Icon />
220
- </ToolbarButton>
221
- </ToolbarGroup>
222
- )}
223
- </ToolbarGroup>
224
-
225
- {collapsedInside && (
226
- <ToolbarGroup>
227
- <ToolbarButton
228
- onClick={() => {
229
- tf.insert.tableRow({ before: true });
230
- }}
231
- onMouseDown={(e) => e.preventDefault()}
232
- tooltip="Insert row before"
233
- >
234
- <ArrowUp />
235
- </ToolbarButton>
236
- <ToolbarButton
237
- onClick={() => {
238
- tf.insert.tableRow();
239
- }}
240
- onMouseDown={(e) => e.preventDefault()}
241
- tooltip="Insert row after"
242
- >
243
- <ArrowDown />
244
- </ToolbarButton>
245
- <ToolbarButton
246
- onClick={() => {
247
- tf.remove.tableRow();
248
- }}
249
- onMouseDown={(e) => e.preventDefault()}
250
- tooltip="Delete row"
251
- >
252
- <XIcon />
253
- </ToolbarButton>
254
- </ToolbarGroup>
255
- )}
256
-
257
- {collapsedInside && (
258
- <ToolbarGroup>
259
- <ToolbarButton
260
- onClick={() => {
261
- tf.insert.tableColumn({ before: true });
262
- }}
263
- onMouseDown={(e) => e.preventDefault()}
264
- tooltip="Insert column before"
265
- >
266
- <ArrowLeft />
267
- </ToolbarButton>
268
- <ToolbarButton
269
- onClick={() => {
270
- tf.insert.tableColumn();
271
- }}
272
- onMouseDown={(e) => e.preventDefault()}
273
- tooltip="Insert column after"
274
- >
275
- <ArrowRight />
276
- </ToolbarButton>
277
- <ToolbarButton
278
- onClick={() => {
279
- tf.remove.tableColumn();
280
- }}
281
- onMouseDown={(e) => e.preventDefault()}
282
- tooltip="Delete column"
283
- >
284
- <XIcon />
285
- </ToolbarButton>
286
- </ToolbarGroup>
287
- )}
288
- </Toolbar>
289
- </PopoverContent>
290
- </Popover>
291
- );
292
- }
293
-
294
- function TableBordersDropdownMenuContent(
295
- props: React.ComponentProps<typeof DropdownMenuPrimitive.Content>
296
- ) {
297
- const editor = useEditorRef();
298
- const {
299
- getOnSelectTableBorder,
300
- hasBottomBorder,
301
- hasLeftBorder,
302
- hasNoBorders,
303
- hasOuterBorders,
304
- hasRightBorder,
305
- hasTopBorder,
306
- } = useTableBordersDropdownMenuContentState();
307
-
308
- return (
309
- <DropdownMenuContent
310
- className="min-w-[220px]"
311
- onCloseAutoFocus={(e) => {
312
- e.preventDefault();
313
- editor.tf.focus();
314
- }}
315
- align="start"
316
- side="right"
317
- sideOffset={0}
318
- {...props}
319
- >
320
- <DropdownMenuGroup>
321
- <DropdownMenuCheckboxItem
322
- checked={hasTopBorder}
323
- onCheckedChange={getOnSelectTableBorder('top')}
324
- >
325
- <BorderTopIcon />
326
- <div>Top Border</div>
327
- </DropdownMenuCheckboxItem>
328
- <DropdownMenuCheckboxItem
329
- checked={hasRightBorder}
330
- onCheckedChange={getOnSelectTableBorder('right')}
331
- >
332
- <BorderRightIcon />
333
- <div>Right Border</div>
334
- </DropdownMenuCheckboxItem>
335
- <DropdownMenuCheckboxItem
336
- checked={hasBottomBorder}
337
- onCheckedChange={getOnSelectTableBorder('bottom')}
338
- >
339
- <BorderBottomIcon />
340
- <div>Bottom Border</div>
341
- </DropdownMenuCheckboxItem>
342
- <DropdownMenuCheckboxItem
343
- checked={hasLeftBorder}
344
- onCheckedChange={getOnSelectTableBorder('left')}
345
- >
346
- <BorderLeftIcon />
347
- <div>Left Border</div>
348
- </DropdownMenuCheckboxItem>
349
- </DropdownMenuGroup>
350
-
351
- <DropdownMenuGroup>
352
- <DropdownMenuCheckboxItem
353
- checked={hasNoBorders}
354
- onCheckedChange={getOnSelectTableBorder('none')}
355
- >
356
- <BorderNoneIcon />
357
- <div>No Border</div>
358
- </DropdownMenuCheckboxItem>
359
- <DropdownMenuCheckboxItem
360
- checked={hasOuterBorders}
361
- onCheckedChange={getOnSelectTableBorder('outer')}
362
- >
363
- <BorderAllIcon />
364
- <div>Outside Borders</div>
365
- </DropdownMenuCheckboxItem>
366
- </DropdownMenuGroup>
367
- </DropdownMenuContent>
368
- );
369
- }
370
-
371
- function ColorDropdownMenu({
372
- children,
373
- tooltip,
374
- }: {
375
- children: React.ReactNode;
376
- tooltip: string;
377
- }) {
378
- const [open, setOpen] = React.useState(false);
379
-
380
- const editor = useEditorRef();
381
- const selectedCells = usePluginOption(TablePlugin, 'selectedCells');
382
-
383
- const onUpdateColor = React.useCallback(
384
- (color: string) => {
385
- setOpen(false);
386
- setCellBackground(editor, { color, selectedCells: selectedCells ?? [] });
387
- },
388
- [selectedCells, editor]
389
- );
390
-
391
- const onClearColor = React.useCallback(() => {
392
- setOpen(false);
393
- setCellBackground(editor, {
394
- color: null,
395
- selectedCells: selectedCells ?? [],
396
- });
397
- }, [selectedCells, editor]);
398
-
399
- return (
400
- <DropdownMenu open={open} onOpenChange={setOpen} modal={false}>
401
- <DropdownMenuTrigger asChild>
402
- <ToolbarButton tooltip={tooltip}>{children}</ToolbarButton>
403
- </DropdownMenuTrigger>
404
-
405
- <DropdownMenuContent align="start">
406
- <ToolbarMenuGroup label="Colors">
407
- <ColorDropdownMenuItems
408
- className="px-2"
409
- colors={DEFAULT_COLORS}
410
- updateColor={onUpdateColor}
411
- />
412
- </ToolbarMenuGroup>
413
- <DropdownMenuGroup>
414
- <DropdownMenuItem className="p-2" onClick={onClearColor}>
415
- <EraserIcon />
416
- <span>Clear</span>
417
- </DropdownMenuItem>
418
- </DropdownMenuGroup>
419
- </DropdownMenuContent>
420
- </DropdownMenu>
421
- );
422
- }
423
-
424
- export function TableRowElement({
425
- children,
426
- ...props
427
- }: PlateElementProps<TTableRowElement>) {
428
- const { element } = props;
429
- const readOnly = useReadOnly();
430
- const selected = useSelected();
431
- const editor = useEditorRef();
432
- const isSelectionAreaVisible = usePluginOption(
433
- BlockSelectionPlugin,
434
- 'isSelectionAreaVisible'
435
- );
436
- const hasControls = !readOnly && !isSelectionAreaVisible;
437
-
438
- const { isDragging, previewRef, handleRef } = useDraggable({
439
- element,
440
- type: element.type,
441
- canDropNode: ({ dragEntry, dropEntry }) =>
442
- PathApi.equals(
443
- PathApi.parent(dragEntry[1]),
444
- PathApi.parent(dropEntry[1])
445
- ),
446
- onDropHandler: (_, { dragItem }) => {
447
- const dragElement = (dragItem as { element: TElement }).element;
448
-
449
- if (dragElement) {
450
- editor.tf.select(dragElement);
451
- }
452
- },
453
- });
454
-
455
- return (
456
- <PlateElement
457
- {...props}
458
- ref={useComposedRef(props.ref, previewRef)}
459
- as="tr"
460
- className={cn('group/row', isDragging && 'opacity-50')}
461
- attributes={{
462
- ...props.attributes,
463
- 'data-selected': selected ? 'true' : undefined,
464
- }}
465
- >
466
- {hasControls && (
467
- <td className="w-2 select-none" contentEditable={false}>
468
- <RowDragHandle dragRef={handleRef} />
469
- <RowDropLine />
470
- </td>
471
- )}
472
-
473
- {children}
474
- </PlateElement>
475
- );
476
- }
477
-
478
- function RowDragHandle({ dragRef }: { dragRef: React.Ref<any> }) {
479
- const editor = useEditorRef();
480
- const element = useElement();
481
-
482
- return (
483
- <Button
484
- ref={dragRef}
485
- variant="outline"
486
- className={cn(
487
- '-translate-y-1/2 absolute top-1/2 left-0 z-51 h-6 w-4 p-0 focus-visible:ring-0 focus-visible:ring-offset-0',
488
- 'cursor-grab active:cursor-grabbing',
489
- 'opacity-0 transition-opacity duration-100 group-hover/row:opacity-100 group-has-data-[resizing="true"]/row:opacity-0'
490
- )}
491
- onClick={() => {
492
- editor.tf.select(element);
493
- }}
494
- >
495
- <GripVertical className="text-muted-foreground" />
496
- </Button>
497
- );
498
- }
499
-
500
- function RowDropLine() {
501
- const { dropLine } = useDropLine();
502
-
503
- if (!dropLine) return null;
504
-
505
- return (
506
- <div
507
- className={cn(
508
- 'absolute inset-x-0 left-2 z-50 h-0.5 bg-brand/50',
509
- dropLine === 'top' ? '-top-px' : '-bottom-px'
510
- )}
511
- />
512
- );
513
- }
514
-
515
- export function TableCellElement({
516
- isHeader,
517
- ...props
518
- }: PlateElementProps<TTableCellElement> & {
519
- isHeader?: boolean;
520
- }) {
521
- const { api } = useEditorPlugin(TablePlugin);
522
- const readOnly = useReadOnly();
523
- const element = props.element;
524
-
525
- const tableId = useElementSelector(([node]) => node.id as string, [], {
526
- key: KEYS.table,
527
- });
528
- const rowId = useElementSelector(([node]) => node.id as string, [], {
529
- key: KEYS.tr,
530
- });
531
- const isSelectingTable = useBlockSelected(tableId);
532
- const isSelectingRow = useBlockSelected(rowId) || isSelectingTable;
533
- const isSelectionAreaVisible = usePluginOption(
534
- BlockSelectionPlugin,
535
- 'isSelectionAreaVisible'
536
- );
537
-
538
- const { borders, colIndex, colSpan, minHeight, rowIndex, selected, width } =
539
- useTableCellElement();
540
-
541
- const { bottomProps, hiddenLeft, leftProps, rightProps } =
542
- useTableCellElementResizable({
543
- colIndex,
544
- colSpan,
545
- rowIndex,
546
- });
547
-
548
- return (
549
- <PlateElement
550
- {...props}
551
- as={isHeader ? 'th' : 'td'}
552
- className={cn(
553
- 'h-full overflow-visible border-none bg-background p-0',
554
- element.background ? 'bg-(--cellBackground)' : 'bg-background',
555
- isHeader && 'text-left *:m-0',
556
- 'before:size-full',
557
- selected && 'before:z-10 before:bg-brand/5',
558
- "before:absolute before:box-border before:select-none before:content-['']",
559
- borders.bottom?.size && 'before:border-b before:border-b-border',
560
- borders.right?.size && 'before:border-r before:border-r-border',
561
- borders.left?.size && 'before:border-l before:border-l-border',
562
- borders.top?.size && 'before:border-t before:border-t-border'
563
- )}
564
- style={
565
- {
566
- '--cellBackground': element.background,
567
- maxWidth: width || 240,
568
- minWidth: width || 120,
569
- } as React.CSSProperties
570
- }
571
- attributes={{
572
- ...props.attributes,
573
- colSpan: api.table.getColSpan(element),
574
- rowSpan: api.table.getRowSpan(element),
575
- }}
576
- >
577
- <div
578
- className="relative z-20 box-border h-full px-3 py-2"
579
- style={{ minHeight }}
580
- >
581
- {props.children}
582
- </div>
583
-
584
- {!isSelectionAreaVisible && (
585
- <div
586
- className="group absolute top-0 size-full select-none"
587
- contentEditable={false}
588
- suppressContentEditableWarning={true}
589
- >
590
- {!readOnly && (
591
- <>
592
- <ResizeHandle
593
- {...rightProps}
594
- className="-top-2 -right-1 h-[calc(100%_+_8px)] w-2"
595
- data-col={colIndex}
596
- />
597
- <ResizeHandle {...bottomProps} className="-bottom-1 h-2" />
598
- {!hiddenLeft && (
599
- <ResizeHandle
600
- {...leftProps}
601
- className="-left-1 top-0 w-2"
602
- data-resizer-left={colIndex === 0 ? 'true' : undefined}
603
- />
604
- )}
605
-
606
- <div
607
- className={cn(
608
- 'absolute top-0 z-30 hidden h-full w-1 bg-ring',
609
- 'right-[-1.5px]',
610
- columnResizeVariants({ colIndex: colIndex as any })
611
- )}
612
- />
613
- {colIndex === 0 && (
614
- <div
615
- className={cn(
616
- 'absolute top-0 z-30 h-full w-1 bg-ring',
617
- 'left-[-1.5px]',
618
- 'fade-in hidden animate-in group-has-[[data-resizer-left]:hover]/table:block group-has-[[data-resizer-left][data-resizing="true"]]/table:block'
619
- )}
620
- />
621
- )}
622
- </>
623
- )}
624
- </div>
625
- )}
626
-
627
- {isSelectingRow && (
628
- <div className={blockSelectionVariants()} contentEditable={false} />
629
- )}
630
- </PlateElement>
631
- );
632
- }
633
-
634
- export function TableCellHeaderElement(
635
- props: React.ComponentProps<typeof TableCellElement>
636
- ) {
637
- return <TableCellElement {...props} isHeader />;
638
- }
639
-
640
- const columnResizeVariants = cva('fade-in hidden animate-in', {
641
- variants: {
642
- colIndex: {
643
- 0: 'group-has-[[data-col="0"]:hover]/table:block group-has-[[data-col="0"][data-resizing="true"]]/table:block',
644
- 1: 'group-has-[[data-col="1"]:hover]/table:block group-has-[[data-col="1"][data-resizing="true"]]/table:block',
645
- 2: 'group-has-[[data-col="2"]:hover]/table:block group-has-[[data-col="2"][data-resizing="true"]]/table:block',
646
- 3: 'group-has-[[data-col="3"]:hover]/table:block group-has-[[data-col="3"][data-resizing="true"]]/table:block',
647
- 4: 'group-has-[[data-col="4"]:hover]/table:block group-has-[[data-col="4"][data-resizing="true"]]/table:block',
648
- 5: 'group-has-[[data-col="5"]:hover]/table:block group-has-[[data-col="5"][data-resizing="true"]]/table:block',
649
- 6: 'group-has-[[data-col="6"]:hover]/table:block group-has-[[data-col="6"][data-resizing="true"]]/table:block',
650
- 7: 'group-has-[[data-col="7"]:hover]/table:block group-has-[[data-col="7"][data-resizing="true"]]/table:block',
651
- 8: 'group-has-[[data-col="8"]:hover]/table:block group-has-[[data-col="8"][data-resizing="true"]]/table:block',
652
- 9: 'group-has-[[data-col="9"]:hover]/table:block group-has-[[data-col="9"][data-resizing="true"]]/table:block',
653
- 10: 'group-has-[[data-col="10"]:hover]/table:block group-has-[[data-col="10"][data-resizing="true"]]/table:block',
654
- },
655
- },
656
- });