@placeholderco/placeholder-ui 1.0.12 → 2.0.0

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 (276) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +134 -130
  3. package/dist/app.css +178 -0
  4. package/dist/bootstrap.min.css +3600 -0
  5. package/dist/cards/GitCard.svelte +115 -0
  6. package/dist/cards/GitCard.svelte.d.ts +22 -0
  7. package/dist/display/Avatar.svelte +29 -17
  8. package/dist/display/Avatar.svelte.d.ts +12 -2
  9. package/dist/display/LinkCollection.svelte +40 -18
  10. package/dist/display/LinkCollection.svelte.d.ts +9 -2
  11. package/dist/display/Paper.svelte +31 -19
  12. package/dist/display/Paper.svelte.d.ts +12 -3
  13. package/dist/display/alert/Alert.svelte +129 -0
  14. package/dist/display/alert/Alert.svelte.d.ts +15 -0
  15. package/dist/display/alert/AlertVariant.d.ts +1 -0
  16. package/dist/display/alert/AlertVariant.js +1 -0
  17. package/dist/display/filetree/FileTree.svelte +259 -0
  18. package/dist/display/filetree/FileTree.svelte.d.ts +76 -0
  19. package/dist/display/filetree/FileTreeItem.svelte +396 -0
  20. package/dist/display/filetree/FileTreeItem.svelte.d.ts +40 -0
  21. package/dist/display/filetree/FileTreeNode.d.ts +46 -0
  22. package/dist/display/filetree/FileTreeNode.js +115 -0
  23. package/dist/display/filetree/index.d.ts +5 -0
  24. package/dist/display/filetree/index.js +3 -0
  25. package/dist/editors/CodeMirror.svelte +306 -0
  26. package/dist/editors/CodeMirror.svelte.d.ts +31 -0
  27. package/dist/editors/tiptap/LinkActionMenu.svelte +307 -0
  28. package/dist/editors/tiptap/LinkActionMenu.svelte.d.ts +8 -0
  29. package/dist/editors/tiptap/TipTap.svelte +856 -0
  30. package/dist/editors/tiptap/TipTap.svelte.d.ts +54 -0
  31. package/dist/editors/tiptap/TipTapBubble.svelte +790 -0
  32. package/dist/editors/tiptap/TipTapBubble.svelte.d.ts +44 -0
  33. package/dist/editors/tiptap/collaboration.d.ts +55 -0
  34. package/dist/editors/tiptap/collaboration.js +1 -0
  35. package/dist/editors/tiptap/extensions/Alert.d.ts +18 -0
  36. package/dist/editors/tiptap/extensions/Alert.js +72 -0
  37. package/dist/editors/tiptap/extensions/CodeBlockEditor.d.ts +21 -0
  38. package/dist/editors/tiptap/extensions/CodeBlockEditor.js +326 -0
  39. package/dist/editors/tiptap/extensions/Div.d.ts +19 -0
  40. package/dist/editors/tiptap/extensions/Div.js +89 -0
  41. package/dist/editors/tiptap/extensions/Span.d.ts +5 -0
  42. package/dist/editors/tiptap/extensions/Span.js +56 -0
  43. package/dist/editors/tiptap/extensions/codeBlockEditor.css +236 -0
  44. package/dist/editors/tiptap/extensions/codeBlockLanguages.d.ts +17 -0
  45. package/dist/editors/tiptap/extensions/codeBlockLanguages.js +124 -0
  46. package/dist/editors/tiptap/extensions/index.d.ts +7 -0
  47. package/dist/editors/tiptap/extensions/index.js +5 -0
  48. package/dist/editors/tiptap/toolbar/AlertButton.svelte +261 -0
  49. package/dist/editors/tiptap/toolbar/AlertButton.svelte.d.ts +7 -0
  50. package/dist/editors/tiptap/toolbar/AlignCenterButton.svelte +18 -0
  51. package/dist/editors/tiptap/toolbar/AlignCenterButton.svelte.d.ts +7 -0
  52. package/dist/editors/tiptap/toolbar/AlignJustifyButton.svelte +18 -0
  53. package/dist/editors/tiptap/toolbar/AlignJustifyButton.svelte.d.ts +7 -0
  54. package/dist/editors/tiptap/toolbar/AlignLeftButton.svelte +18 -0
  55. package/dist/editors/tiptap/toolbar/AlignLeftButton.svelte.d.ts +7 -0
  56. package/dist/editors/tiptap/toolbar/AlignRightButton.svelte +18 -0
  57. package/dist/editors/tiptap/toolbar/AlignRightButton.svelte.d.ts +7 -0
  58. package/dist/editors/tiptap/toolbar/BoldButton.svelte +18 -0
  59. package/dist/editors/tiptap/toolbar/BoldButton.svelte.d.ts +7 -0
  60. package/dist/editors/tiptap/toolbar/BulletListButton.svelte +18 -0
  61. package/dist/editors/tiptap/toolbar/BulletListButton.svelte.d.ts +7 -0
  62. package/dist/editors/tiptap/toolbar/CodeBlockButton.svelte +18 -0
  63. package/dist/editors/tiptap/toolbar/CodeBlockButton.svelte.d.ts +7 -0
  64. package/dist/editors/tiptap/toolbar/CodeButton.svelte +18 -0
  65. package/dist/editors/tiptap/toolbar/CodeButton.svelte.d.ts +7 -0
  66. package/dist/editors/tiptap/toolbar/ColorButton.svelte +299 -0
  67. package/dist/editors/tiptap/toolbar/ColorButton.svelte.d.ts +20 -0
  68. package/dist/editors/tiptap/toolbar/DocumentButton.svelte +58 -0
  69. package/dist/editors/tiptap/toolbar/DocumentButton.svelte.d.ts +9 -0
  70. package/dist/editors/tiptap/toolbar/HeadingButton.svelte +30 -0
  71. package/dist/editors/tiptap/toolbar/HeadingButton.svelte.d.ts +8 -0
  72. package/dist/editors/tiptap/toolbar/HtmlButton.svelte +68 -0
  73. package/dist/editors/tiptap/toolbar/HtmlButton.svelte.d.ts +7 -0
  74. package/dist/editors/tiptap/toolbar/ImageButton.svelte +54 -0
  75. package/dist/editors/tiptap/toolbar/ImageButton.svelte.d.ts +8 -0
  76. package/dist/editors/tiptap/toolbar/ItalicButton.svelte +18 -0
  77. package/dist/editors/tiptap/toolbar/ItalicButton.svelte.d.ts +7 -0
  78. package/dist/editors/tiptap/toolbar/LinkButton.svelte +257 -0
  79. package/dist/editors/tiptap/toolbar/LinkButton.svelte.d.ts +7 -0
  80. package/dist/editors/tiptap/toolbar/OrderedListButton.svelte +18 -0
  81. package/dist/editors/tiptap/toolbar/OrderedListButton.svelte.d.ts +7 -0
  82. package/dist/editors/tiptap/toolbar/RedoButton.svelte +18 -0
  83. package/dist/editors/tiptap/toolbar/RedoButton.svelte.d.ts +7 -0
  84. package/dist/editors/tiptap/toolbar/StrikethroughButton.svelte +18 -0
  85. package/dist/editors/tiptap/toolbar/StrikethroughButton.svelte.d.ts +7 -0
  86. package/dist/editors/tiptap/toolbar/SubscriptButton.svelte +18 -0
  87. package/dist/editors/tiptap/toolbar/SubscriptButton.svelte.d.ts +7 -0
  88. package/dist/editors/tiptap/toolbar/SuperscriptButton.svelte +18 -0
  89. package/dist/editors/tiptap/toolbar/SuperscriptButton.svelte.d.ts +7 -0
  90. package/dist/editors/tiptap/toolbar/TableButton.svelte +258 -0
  91. package/dist/editors/tiptap/toolbar/TableButton.svelte.d.ts +7 -0
  92. package/dist/editors/tiptap/toolbar/ToolbarButton.svelte +84 -0
  93. package/dist/editors/tiptap/toolbar/ToolbarButton.svelte.d.ts +10 -0
  94. package/dist/editors/tiptap/toolbar/UnderlineButton.svelte +18 -0
  95. package/dist/editors/tiptap/toolbar/UnderlineButton.svelte.d.ts +7 -0
  96. package/dist/editors/tiptap/toolbar/UndoButton.svelte +18 -0
  97. package/dist/editors/tiptap/toolbar/UndoButton.svelte.d.ts +7 -0
  98. package/dist/form/Autocomplete.svelte +86 -135
  99. package/dist/form/Autocomplete.svelte.d.ts +6 -8
  100. package/dist/form/AutocompleteMulti.svelte +385 -227
  101. package/dist/form/AutocompleteMulti.svelte.d.ts +59 -10
  102. package/dist/form/Checkbox.svelte +59 -54
  103. package/dist/form/Checkbox.svelte.d.ts +14 -5
  104. package/dist/form/Chips.svelte +29 -13
  105. package/dist/form/Chips.svelte.d.ts +16 -2
  106. package/dist/form/ComboBox.svelte +30 -20
  107. package/dist/form/ComboBox.svelte.d.ts +1 -1
  108. package/dist/form/ComboBoxItemBuilder.svelte +161 -188
  109. package/dist/form/ComboBoxItemBuilder.svelte.d.ts +19 -2
  110. package/dist/form/ComboBoxMulti.svelte +38 -24
  111. package/dist/form/ComboBoxMulti.svelte.d.ts +1 -1
  112. package/dist/form/CronBuilder.svelte +84 -67
  113. package/dist/form/CronBuilder.svelte.d.ts +16 -3
  114. package/dist/form/DatePicker.svelte +148 -195
  115. package/dist/form/DateRangePicker.svelte +101 -98
  116. package/dist/form/DateTimePicker.svelte +167 -208
  117. package/dist/form/DateTimePicker.svelte.d.ts +10 -2
  118. package/dist/form/FormGroup.svelte +33 -10
  119. package/dist/form/FormGroup.svelte.d.ts +12 -2
  120. package/dist/form/Number.svelte +70 -47
  121. package/dist/form/Number.svelte.d.ts +36 -6
  122. package/dist/form/Radio.svelte +18 -18
  123. package/dist/form/RadioGroup.svelte +23 -12
  124. package/dist/form/RadioGroup.svelte.d.ts +13 -2
  125. package/dist/form/SegmentedControl.svelte +76 -56
  126. package/dist/form/SegmentedControl.svelte.d.ts +9 -4
  127. package/dist/form/Select.svelte +150 -233
  128. package/dist/form/Select.svelte.d.ts +29 -5
  129. package/dist/form/SelectMulti.svelte +163 -277
  130. package/dist/form/SelectMulti.svelte.d.ts +36 -7
  131. package/dist/form/Slider.svelte +183 -269
  132. package/dist/form/Slider.svelte.d.ts +32 -17
  133. package/dist/form/StringArrayBuilder.svelte +249 -0
  134. package/dist/form/StringArrayBuilder.svelte.d.ts +15 -0
  135. package/dist/form/Switch.svelte +164 -106
  136. package/dist/form/Switch.svelte.d.ts +22 -3
  137. package/dist/form/TextArea.svelte +49 -29
  138. package/dist/form/TextArea.svelte.d.ts +23 -3
  139. package/dist/form/Textbox.svelte +69 -68
  140. package/dist/form/Textbox.svelte.d.ts +32 -4
  141. package/dist/form/TimePicker.svelte +42 -47
  142. package/dist/form/TimePicker.svelte.d.ts +12 -2
  143. package/dist/form/comboBoxCore.svelte.d.ts +99 -0
  144. package/dist/form/comboBoxCore.svelte.js +243 -0
  145. package/dist/icon/Icon.svelte +8 -3
  146. package/dist/icon/Icon.svelte.d.ts +8 -3
  147. package/dist/icon/file-type-bmp.svg +1 -0
  148. package/dist/icon/file-type-csv.svg +1 -0
  149. package/dist/icon/file-type-doc.svg +1 -0
  150. package/dist/icon/file-type-docx.svg +1 -0
  151. package/dist/icon/file-type-jpg.svg +1 -0
  152. package/dist/icon/file-type-pdf.svg +1 -0
  153. package/dist/icon/file-type-png.svg +1 -0
  154. package/dist/icon/file-type-ppt.svg +1 -0
  155. package/dist/icon/file-type-svg.svg +1 -0
  156. package/dist/icon/file-type-txt.svg +1 -0
  157. package/dist/icon/file-type-xls.svg +1 -0
  158. package/dist/icon/file-type-zip.svg +1 -0
  159. package/dist/icon/index.d.ts +166 -151
  160. package/dist/icon/index.js +166 -152
  161. package/dist/icon/logo-placeholder.svg +6 -0
  162. package/dist/icon/source-code.svg +1 -0
  163. package/dist/icon/sun-moon.svg +1 -0
  164. package/dist/icon/table.svg +6 -0
  165. package/dist/index.d.ts +87 -26
  166. package/dist/index.js +25 -28
  167. package/dist/layout/AppShell.svelte +12 -162
  168. package/dist/layout/AppShell.svelte.d.ts +6 -27
  169. package/dist/layout/CustomNavbar.svelte +9 -7
  170. package/dist/layout/CustomNavbar.svelte.d.ts +4 -2
  171. package/dist/layout/Navbar.svelte +161 -129
  172. package/dist/layout/Navbar.svelte.d.ts +29 -15
  173. package/dist/layout/NavbarItemDisplay.svelte +2 -2
  174. package/dist/layout/NavbarItemView.svelte +182 -0
  175. package/dist/layout/NavbarItemView.svelte.d.ts +10 -0
  176. package/dist/layout/Sidenav.svelte +280 -341
  177. package/dist/layout/Sidenav.svelte.d.ts +36 -4
  178. package/dist/models/ComboBoxItem.d.ts +2 -0
  179. package/dist/models/Employee.d.ts +53 -0
  180. package/dist/models/Employee.js +23 -0
  181. package/dist/models/Hyperlink.d.ts +3 -1
  182. package/dist/models/LinkCollectionItem.d.ts +3 -1
  183. package/dist/models/NavbarItem.d.ts +6 -2
  184. package/dist/theme.svelte.d.ts +0 -1
  185. package/dist/theme.svelte.js +46 -58
  186. package/dist/ui/Accordion.svelte +81 -242
  187. package/dist/ui/Accordion.svelte.d.ts +37 -14
  188. package/dist/ui/AccordionItem.svelte +303 -0
  189. package/dist/ui/AccordionItem.svelte.d.ts +21 -0
  190. package/dist/ui/ActionIcon.svelte +25 -21
  191. package/dist/ui/ActionIcon.svelte.d.ts +15 -2
  192. package/dist/ui/Badge.svelte +163 -171
  193. package/dist/ui/Badge.svelte.d.ts +13 -5
  194. package/dist/ui/Button.svelte +178 -205
  195. package/dist/ui/Button.svelte.d.ts +19 -2
  196. package/dist/ui/ButtonVariant.d.ts +15 -1
  197. package/dist/ui/ContextMenu.svelte +146 -0
  198. package/dist/ui/ContextMenu.svelte.d.ts +37 -0
  199. package/dist/ui/ContextMenuList.svelte +188 -0
  200. package/dist/ui/ContextMenuList.svelte.d.ts +12 -0
  201. package/dist/ui/Dialog.svelte +183 -111
  202. package/dist/ui/Dialog.svelte.d.ts +21 -4
  203. package/dist/ui/Drawer.svelte +237 -184
  204. package/dist/ui/Drawer.svelte.d.ts +20 -2
  205. package/dist/ui/Dropdown.svelte +24 -14
  206. package/dist/ui/Dropdown.svelte.d.ts +11 -2
  207. package/dist/ui/Dropzone.svelte +159 -57
  208. package/dist/ui/Dropzone.svelte.d.ts +29 -2
  209. package/dist/ui/Link.svelte +12 -4
  210. package/dist/ui/Link.svelte.d.ts +8 -2
  211. package/dist/ui/Loader.svelte +23 -18
  212. package/dist/ui/Loader.svelte.d.ts +5 -2
  213. package/dist/ui/Logo.svelte +37 -0
  214. package/dist/ui/Logo.svelte.d.ts +16 -0
  215. package/dist/ui/MultiSortable.svelte +287 -0
  216. package/dist/ui/MultiSortable.svelte.d.ts +50 -0
  217. package/dist/ui/Pagination.svelte +15 -9
  218. package/dist/ui/Pagination.svelte.d.ts +6 -2
  219. package/dist/ui/Popover.svelte +43 -65
  220. package/dist/ui/Popover.svelte.d.ts +14 -5
  221. package/dist/ui/ProgressBar.svelte +28 -30
  222. package/dist/ui/ProgressBarVariant.d.ts +7 -1
  223. package/dist/ui/SegmentedControl.svelte +0 -0
  224. package/dist/ui/SegmentedControl.svelte.d.ts +26 -0
  225. package/dist/ui/Sortable.svelte +163 -0
  226. package/dist/ui/Sortable.svelte.d.ts +47 -0
  227. package/dist/ui/Table.svelte +383 -80
  228. package/dist/ui/Table.svelte.d.ts +43 -2
  229. package/dist/ui/Tabs.svelte +22 -18
  230. package/dist/ui/Tabs.svelte.d.ts +6 -2
  231. package/dist/ui/ThemeSwitcher.svelte +26 -7
  232. package/dist/ui/ThemeSwitcher.svelte.d.ts +4 -2
  233. package/dist/ui/Tooltip.svelte +312 -180
  234. package/dist/ui/Tooltip.svelte.d.ts +4 -3
  235. package/dist/uiTheme.svelte.d.ts +86 -0
  236. package/dist/uiTheme.svelte.js +214 -0
  237. package/dist/util/DateFunctions.js +1 -1
  238. package/dist/util/DragDrop.d.ts +50 -0
  239. package/dist/util/DragDrop.js +154 -0
  240. package/dist/util/NavigateTo.js +2 -2
  241. package/dist/util/dayjs.d.ts +4 -0
  242. package/dist/util/dayjs.js +15 -0
  243. package/package.json +66 -26
  244. package/dist/display/Alert.svelte +0 -179
  245. package/dist/display/Alert.svelte.d.ts +0 -13
  246. package/dist/form/FileInput.svelte +0 -235
  247. package/dist/form/FileInput.svelte.d.ts +0 -23
  248. package/dist/form/PasswordInput.svelte +0 -253
  249. package/dist/form/PasswordInput.svelte.d.ts +0 -34
  250. package/dist/form/Rating.svelte +0 -235
  251. package/dist/form/Rating.svelte.d.ts +0 -21
  252. package/dist/styles/components.css +0 -199
  253. package/dist/styles/dark.css +0 -146
  254. package/dist/styles/index.css +0 -116
  255. package/dist/styles/reset.css +0 -110
  256. package/dist/styles/semantic.css +0 -86
  257. package/dist/styles/tokens.css +0 -203
  258. package/dist/styles/utilities.css +0 -523
  259. package/dist/ui/Breadcrumbs.svelte +0 -131
  260. package/dist/ui/Breadcrumbs.svelte.d.ts +0 -16
  261. package/dist/ui/LoadingOverlay.svelte +0 -53
  262. package/dist/ui/LoadingOverlay.svelte.d.ts +0 -11
  263. package/dist/ui/Progress.svelte +0 -191
  264. package/dist/ui/Progress.svelte.d.ts +0 -15
  265. package/dist/ui/RingProgress.svelte +0 -141
  266. package/dist/ui/RingProgress.svelte.d.ts +0 -18
  267. package/dist/ui/Skeleton.svelte +0 -85
  268. package/dist/ui/Skeleton.svelte.d.ts +0 -12
  269. package/dist/ui/Stepper.svelte +0 -355
  270. package/dist/ui/Stepper.svelte.d.ts +0 -24
  271. package/dist/ui/Timeline.svelte +0 -225
  272. package/dist/ui/Timeline.svelte.d.ts +0 -23
  273. /package/dist/{actions → util}/ClickOutside.d.ts +0 -0
  274. /package/dist/{actions → util}/ClickOutside.js +0 -0
  275. /package/dist/{transitions → util}/Transitions.d.ts +0 -0
  276. /package/dist/{transitions → util}/Transitions.js +0 -0
@@ -0,0 +1,44 @@
1
+ import { type AnyExtension } from '@tiptap/core';
2
+ import { type CodeBlocksOptions } from './extensions/index.js';
3
+ import type { CollaborationConfig } from './collaboration.js';
4
+ export interface TipTapBubbleProps {
5
+ /** HTML content value (bindable). Ignored when collaboration is enabled. */
6
+ value?: string;
7
+ /** Label text displayed above the editor */
8
+ label?: string;
9
+ /** Mark field as required (shows asterisk) */
10
+ required?: boolean;
11
+ /** CSS classes for the FormGroup wrapper */
12
+ groupClass?: string;
13
+ /** Tooltip text on hover */
14
+ tooltipText?: string;
15
+ /** Position of the tooltip */
16
+ tooltipLocation?: 'top' | 'bottom' | 'left' | 'right';
17
+ /** Enable editing mode */
18
+ editable?: boolean;
19
+ /** Placeholder text when editor is empty */
20
+ placeholder?: string;
21
+ /** Additional CSS classes */
22
+ class?: string;
23
+ /** Async handler for image uploads, returns URL or null */
24
+ onImageUpload?: (file: File) => Promise<string | null>;
25
+ /** Callback when content changes */
26
+ onUpdate?: (html: string) => void;
27
+ /** Opt-in real-time collaboration config. When provided, content syncs via Yjs. */
28
+ collaboration?: CollaborationConfig;
29
+ /** Opt-in rich code blocks: CodeMirror-powered editing with syntax highlighting,
30
+ * autocompletion and a per-block language picker. Pass true for all languages
31
+ * or a config to narrow the offered languages and set the default. */
32
+ codeBlocks?: boolean | CodeBlocksOptions;
33
+ /** Additional TipTap extensions to register with the editor */
34
+ extensions?: AnyExtension[];
35
+ }
36
+ declare const TipTapBubble: import("svelte").Component<TipTapBubbleProps, {
37
+ getHTML: () => string;
38
+ getJSON: () => object;
39
+ setContent: (html: string) => void;
40
+ clear: () => void;
41
+ focus: () => void;
42
+ }, "value">;
43
+ type TipTapBubble = ReturnType<typeof TipTapBubble>;
44
+ export default TipTapBubble;
@@ -0,0 +1,55 @@
1
+ import type { XmlFragment } from 'yjs';
2
+ /** User identity shown on remote collaboration cursors. */
3
+ export interface CollaborationUser {
4
+ /** Display name shown on the cursor label */
5
+ name: string;
6
+ /** 6-digit hex color for the cursor and selection highlight (e.g. `'#f59e0b'`). Must be hex format — HSL, RGB, and named colors are not supported. */
7
+ color: `#${string}`;
8
+ }
9
+ /**
10
+ * Configuration for real-time collaborative editing.
11
+ *
12
+ * **Required peer dependencies** (install in your app):
13
+ * - `yjs` — CRDT document model
14
+ * - A Yjs network provider such as `y-websocket`, `y-webrtc`, or `@hocuspocus/provider`
15
+ *
16
+ * **Usage:**
17
+ * ```ts
18
+ * import * as Y from 'yjs';
19
+ * import { WebsocketProvider } from 'y-websocket';
20
+ *
21
+ * const ydoc = new Y.Doc();
22
+ * const provider = new WebsocketProvider('wss://your-server.com', 'room-id', ydoc);
23
+ *
24
+ * const collaboration = {
25
+ * fragment: ydoc.getXmlFragment('content'),
26
+ * provider,
27
+ * user: { name: 'Alice', color: '#f59e0b' }
28
+ * };
29
+ * ```
30
+ *
31
+ * **Notes:**
32
+ * - When collaboration is enabled, the `value` prop is ignored — Yjs is the source of truth.
33
+ * - The built-in undo/redo is replaced by Yjs collaborative history.
34
+ * - Your app is responsible for managing the provider lifecycle (connect/disconnect).
35
+ */
36
+ export interface CollaborationConfig {
37
+ /**
38
+ * A Yjs XML fragment to sync editor content.
39
+ *
40
+ * Create with `ydoc.getXmlFragment('content')`. All clients sharing
41
+ * the same Y.Doc and fragment name will see each other's edits.
42
+ */
43
+ fragment: XmlFragment;
44
+ /**
45
+ * A Yjs provider instance that handles network transport.
46
+ *
47
+ * Common choices:
48
+ * - `WebsocketProvider` from `y-websocket` (requires a WebSocket server)
49
+ * - `WebrtcProvider` from `y-webrtc` (peer-to-peer, no server)
50
+ * - `HocuspocusProvider` from `@hocuspocus/provider` (TipTap's managed solution)
51
+ */
52
+ provider: any;
53
+ /** Current user info displayed on remote cursors */
54
+ user: CollaborationUser;
55
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,18 @@
1
+ import { Node } from '@tiptap/core';
2
+ export interface AlertOptions {
3
+ HTMLAttributes: Record<string, any>;
4
+ }
5
+ declare module '@tiptap/core' {
6
+ interface Commands<ReturnType> {
7
+ alert: {
8
+ /**
9
+ * Insert an alert block
10
+ */
11
+ setAlert: (attributes?: {
12
+ variant?: string;
13
+ title?: string;
14
+ }) => ReturnType;
15
+ };
16
+ }
17
+ }
18
+ export declare const Alert: Node<AlertOptions, any>;
@@ -0,0 +1,72 @@
1
+ import { Node, mergeAttributes } from '@tiptap/core';
2
+ export const Alert = Node.create({
3
+ name: 'alert',
4
+ group: 'block',
5
+ content: 'block+',
6
+ defining: true,
7
+ addAttributes() {
8
+ return {
9
+ variant: {
10
+ default: 'default',
11
+ parseHTML: (element) => element.getAttribute('data-variant'),
12
+ renderHTML: (attributes) => {
13
+ return {
14
+ 'data-variant': attributes.variant,
15
+ };
16
+ },
17
+ },
18
+ title: {
19
+ default: 'Alert',
20
+ parseHTML: (element) => element.getAttribute('data-title'),
21
+ renderHTML: (attributes) => {
22
+ return {
23
+ 'data-title': attributes.title,
24
+ };
25
+ },
26
+ },
27
+ };
28
+ },
29
+ parseHTML() {
30
+ return [
31
+ {
32
+ tag: 'div[data-type="alert"]',
33
+ },
34
+ ];
35
+ },
36
+ renderHTML({ HTMLAttributes }) {
37
+ return [
38
+ 'div',
39
+ mergeAttributes(HTMLAttributes, {
40
+ 'data-type': 'alert',
41
+ class: `alert alert-${HTMLAttributes['data-variant'] || 'default'}`,
42
+ }),
43
+ [
44
+ 'div',
45
+ { class: 'alert-title', 'data-title-element': 'true' },
46
+ HTMLAttributes['data-title'] || 'Alert',
47
+ ],
48
+ ['div', { class: 'alert-content' }, 0],
49
+ ];
50
+ },
51
+ addCommands() {
52
+ return {
53
+ setAlert: (attributes) => ({ commands }) => {
54
+ return commands.insertContent({
55
+ type: this.name,
56
+ attrs: attributes,
57
+ content: [
58
+ {
59
+ type: 'paragraph',
60
+ content: [
61
+ {
62
+ type: 'text',
63
+ text: 'Enter your alert message here...',
64
+ },
65
+ ],
66
+ },
67
+ ],
68
+ });
69
+ },
70
+ };
71
+ },
72
+ });
@@ -0,0 +1,21 @@
1
+ import { type CodeBlockOptions } from '@tiptap/extension-code-block';
2
+ import { type CodeBlockLanguageId } from './codeBlockLanguages.js';
3
+ import './codeBlockEditor.css';
4
+ /** Configuration accepted by the `codeBlocks` prop on TipTap / TipTapBubble */
5
+ export interface CodeBlocksOptions {
6
+ /** Languages offered in the code block language picker (default: all registered) */
7
+ languages?: CodeBlockLanguageId[];
8
+ /** Language applied to newly inserted code blocks (default 'javascript') */
9
+ defaultLanguage?: CodeBlockLanguageId;
10
+ }
11
+ export interface CodeBlockEditorOptions extends CodeBlockOptions {
12
+ /** Language ids offered in the picker; null offers every registered language */
13
+ languages: CodeBlockLanguageId[] | null;
14
+ }
15
+ /**
16
+ * CodeBlock extension whose blocks are full CodeMirror editors: syntax
17
+ * highlighting, autocompletion, bracket matching and smart indentation, with a
18
+ * per-block language picker. Serializes to standard
19
+ * `<pre><code class="language-...">` HTML, so content round-trips unchanged.
20
+ */
21
+ export declare const CodeBlockEditor: import("@tiptap/core").Node<CodeBlockEditorOptions, any>;
@@ -0,0 +1,326 @@
1
+ import { CodeBlock } from '@tiptap/extension-code-block';
2
+ import { Selection, TextSelection } from '@tiptap/pm/state';
3
+ import { exitCode } from '@tiptap/pm/commands';
4
+ import { EditorView as CodeMirrorView, drawSelection, keymap } from '@codemirror/view';
5
+ import { Compartment, EditorState as CodeMirrorState } from '@codemirror/state';
6
+ import { defaultKeymap, indentWithTab } from '@codemirror/commands';
7
+ import { autocompletion, closeBrackets, closeBracketsKeymap, completionKeymap } from '@codemirror/autocomplete';
8
+ import { bracketMatching, indentOnInput, syntaxHighlighting } from '@codemirror/language';
9
+ import { classHighlighter } from '@lezer/highlight';
10
+ import { codeBlockLanguages, resolveCodeBlockLanguage } from './codeBlockLanguages.js';
11
+ import './codeBlockEditor.css';
12
+ /**
13
+ * Renders each code block as an embedded CodeMirror editor, following the
14
+ * ProseMirror codemirror node view pattern: CodeMirror owns the block's text and
15
+ * selection while focused, and every change is forwarded to ProseMirror so the
16
+ * document (and collaboration/undo) stay authoritative.
17
+ */
18
+ class CodeBlockView {
19
+ dom;
20
+ node;
21
+ editor;
22
+ getPos;
23
+ cm;
24
+ select;
25
+ languageCompartment = new Compartment();
26
+ updating = false;
27
+ constructor(node, editor, getPos, languages) {
28
+ this.node = node;
29
+ this.editor = editor;
30
+ this.getPos = getPos;
31
+ const editable = editor.isEditable;
32
+ this.cm = new CodeMirrorView({
33
+ doc: node.textContent,
34
+ extensions: [
35
+ keymap.of([
36
+ ...closeBracketsKeymap,
37
+ ...completionKeymap,
38
+ ...this.codeMirrorKeymap(),
39
+ ...defaultKeymap,
40
+ indentWithTab
41
+ ]),
42
+ drawSelection(),
43
+ syntaxHighlighting(classHighlighter),
44
+ bracketMatching(),
45
+ closeBrackets(),
46
+ autocompletion(),
47
+ indentOnInput(),
48
+ CodeMirrorView.lineWrapping,
49
+ this.languageCompartment.of(this.languageExtension()),
50
+ CodeMirrorView.editable.of(editable),
51
+ CodeMirrorState.readOnly.of(!editable),
52
+ CodeMirrorView.updateListener.of((update) => this.forwardUpdate(update))
53
+ ]
54
+ });
55
+ this.select = this.buildLanguageSelect(languages, editable);
56
+ this.dom = document.createElement('div');
57
+ this.dom.className = 'code-block-editor';
58
+ this.dom.appendChild(this.select);
59
+ this.dom.appendChild(this.cm.dom);
60
+ }
61
+ // The ProseMirror view is looked up lazily because node views are constructed
62
+ // while the outer view itself is still being created.
63
+ get view() {
64
+ return this.editor.view;
65
+ }
66
+ languageExtension() {
67
+ return resolveCodeBlockLanguage(this.node.attrs.language)?.load() ?? [];
68
+ }
69
+ buildLanguageSelect(languages, editable) {
70
+ const select = document.createElement('select');
71
+ select.className = 'code-block-language';
72
+ select.setAttribute('aria-label', 'Code language');
73
+ select.contentEditable = 'false';
74
+ for (const def of languages) {
75
+ const option = document.createElement('option');
76
+ option.value = def.id;
77
+ option.textContent = def.label;
78
+ select.appendChild(option);
79
+ }
80
+ select.disabled = !editable;
81
+ this.syncSelect(select);
82
+ select.addEventListener('change', () => {
83
+ const pos = this.getPos();
84
+ if (pos === undefined)
85
+ return;
86
+ this.view.dispatch(this.view.state.tr.setNodeMarkup(pos, undefined, {
87
+ ...this.node.attrs,
88
+ language: select.value
89
+ }));
90
+ this.cm.focus();
91
+ });
92
+ return select;
93
+ }
94
+ // Reflect the node's language in the picker, adding a fallback option for
95
+ // languages present in parsed content but missing from the configured list.
96
+ syncSelect(select = this.select) {
97
+ const raw = this.node.attrs.language;
98
+ const current = resolveCodeBlockLanguage(raw)?.id ?? raw ?? 'plaintext';
99
+ if (![...select.options].some((option) => option.value === current)) {
100
+ const option = document.createElement('option');
101
+ option.value = current;
102
+ option.textContent = current;
103
+ select.appendChild(option);
104
+ }
105
+ select.value = current;
106
+ }
107
+ // Map CodeMirror document/selection changes onto the ProseMirror document.
108
+ forwardUpdate(update) {
109
+ if (this.updating || !this.cm.hasFocus)
110
+ return;
111
+ const pos = this.getPos();
112
+ if (pos === undefined)
113
+ return;
114
+ let offset = pos + 1;
115
+ const { main } = update.state.selection;
116
+ const selFrom = offset + main.from;
117
+ const selTo = offset + main.to;
118
+ const pmSelection = this.view.state.selection;
119
+ if (update.docChanged || pmSelection.from !== selFrom || pmSelection.to !== selTo) {
120
+ const tr = this.view.state.tr;
121
+ update.changes.iterChanges((fromA, toA, fromB, toB, text) => {
122
+ if (text.length) {
123
+ tr.replaceWith(offset + fromA, offset + toA, this.view.state.schema.text(text.toString()));
124
+ }
125
+ else {
126
+ tr.delete(offset + fromA, offset + toA);
127
+ }
128
+ offset += toB - fromB - (toA - fromA);
129
+ });
130
+ tr.setSelection(TextSelection.create(tr.doc, selFrom, selTo));
131
+ this.view.dispatch(tr);
132
+ }
133
+ }
134
+ codeMirrorKeymap() {
135
+ return [
136
+ { key: 'ArrowUp', run: () => this.maybeEscape('line', -1) },
137
+ { key: 'ArrowLeft', run: () => this.maybeEscape('char', -1) },
138
+ { key: 'ArrowDown', run: () => this.maybeEscape('line', 1) },
139
+ { key: 'ArrowRight', run: () => this.maybeEscape('char', 1) },
140
+ { key: 'Escape', run: () => this.escape() },
141
+ {
142
+ key: 'Mod-Enter',
143
+ run: () => {
144
+ if (!exitCode(this.view.state, this.view.dispatch))
145
+ return false;
146
+ this.view.focus();
147
+ return true;
148
+ }
149
+ },
150
+ { key: 'Backspace', run: () => this.removeWhenEmpty() },
151
+ { key: 'Mod-z', run: () => this.editor.commands.undo() },
152
+ { key: 'Mod-y', run: () => this.editor.commands.redo() },
153
+ { key: 'Shift-Mod-z', run: () => this.editor.commands.redo() }
154
+ ];
155
+ }
156
+ // Move the selection out of the block when an arrow key is pressed at its edge.
157
+ maybeEscape(unit, dir) {
158
+ const { state } = this.cm;
159
+ const { main } = state.selection;
160
+ if (!main.empty)
161
+ return false;
162
+ if (unit === 'line') {
163
+ const line = state.doc.lineAt(main.head);
164
+ if (dir < 0 ? line.from > 0 : line.to < state.doc.length)
165
+ return false;
166
+ }
167
+ else if (dir < 0 ? main.from > 0 : main.to < state.doc.length) {
168
+ return false;
169
+ }
170
+ const pos = this.getPos();
171
+ if (pos === undefined)
172
+ return false;
173
+ const after = pos + this.node.nodeSize;
174
+ // Arrowing down out of a trailing code block: create a paragraph to land in.
175
+ if (dir > 0 && unit === 'line' && after >= this.view.state.doc.content.size) {
176
+ const paragraph = this.view.state.schema.nodes.paragraph.createAndFill();
177
+ if (!paragraph)
178
+ return false;
179
+ const tr = this.view.state.tr.insert(after, paragraph);
180
+ tr.setSelection(TextSelection.create(tr.doc, after + 1));
181
+ this.view.dispatch(tr.scrollIntoView());
182
+ this.view.focus();
183
+ return true;
184
+ }
185
+ const selection = Selection.near(this.view.state.doc.resolve(dir < 0 ? pos : after), dir);
186
+ this.view.dispatch(this.view.state.tr.setSelection(selection).scrollIntoView());
187
+ this.view.focus();
188
+ return true;
189
+ }
190
+ escape() {
191
+ const pos = this.getPos();
192
+ if (pos === undefined)
193
+ return false;
194
+ const selection = Selection.near(this.view.state.doc.resolve(pos + this.node.nodeSize), 1);
195
+ this.view.dispatch(this.view.state.tr.setSelection(selection).scrollIntoView());
196
+ this.view.focus();
197
+ return true;
198
+ }
199
+ // Backspace in an empty block converts it back to a paragraph.
200
+ removeWhenEmpty() {
201
+ if (this.cm.state.doc.length > 0)
202
+ return false;
203
+ const pos = this.getPos();
204
+ if (pos === undefined)
205
+ return false;
206
+ const paragraph = this.view.state.schema.nodes.paragraph.createAndFill();
207
+ if (!paragraph)
208
+ return false;
209
+ const tr = this.view.state.tr.replaceWith(pos, pos + this.node.nodeSize, paragraph);
210
+ tr.setSelection(TextSelection.create(tr.doc, pos + 1));
211
+ this.view.dispatch(tr);
212
+ this.view.focus();
213
+ return true;
214
+ }
215
+ // Apply external changes (undo, collaboration, setContent) to CodeMirror.
216
+ update(node) {
217
+ if (node.type !== this.node.type)
218
+ return false;
219
+ const previousLanguage = this.node.attrs.language;
220
+ this.node = node;
221
+ if (node.attrs.language !== previousLanguage) {
222
+ this.syncSelect();
223
+ this.cm.dispatch({
224
+ effects: this.languageCompartment.reconfigure(this.languageExtension())
225
+ });
226
+ }
227
+ const newText = node.textContent;
228
+ const currentText = this.cm.state.doc.toString();
229
+ if (newText !== currentText) {
230
+ let start = 0;
231
+ let currentEnd = currentText.length;
232
+ let newEnd = newText.length;
233
+ while (start < currentEnd &&
234
+ start < newEnd &&
235
+ currentText.charCodeAt(start) === newText.charCodeAt(start)) {
236
+ start++;
237
+ }
238
+ while (currentEnd > start &&
239
+ newEnd > start &&
240
+ currentText.charCodeAt(currentEnd - 1) === newText.charCodeAt(newEnd - 1)) {
241
+ currentEnd--;
242
+ newEnd--;
243
+ }
244
+ this.updating = true;
245
+ this.cm.dispatch({
246
+ changes: { from: start, to: currentEnd, insert: newText.slice(start, newEnd) }
247
+ });
248
+ this.updating = false;
249
+ }
250
+ return true;
251
+ }
252
+ setSelection(anchor, head) {
253
+ this.cm.focus();
254
+ this.updating = true;
255
+ this.cm.dispatch({ selection: { anchor, head } });
256
+ this.updating = false;
257
+ }
258
+ selectNode() {
259
+ this.cm.focus();
260
+ }
261
+ stopEvent() {
262
+ return true;
263
+ }
264
+ ignoreMutation() {
265
+ return true;
266
+ }
267
+ destroy() {
268
+ this.cm.destroy();
269
+ }
270
+ }
271
+ // Let arrow keys move the cursor from an adjacent textblock into a code block;
272
+ // ProseMirror can't do this itself because the block's content lives in CodeMirror.
273
+ function arrowIntoCodeBlock(direction) {
274
+ return ({ editor }) => {
275
+ const { state, view } = editor;
276
+ if (!state.selection.empty || !view.endOfTextblock(direction))
277
+ return false;
278
+ const side = direction === 'left' || direction === 'up' ? -1 : 1;
279
+ const { $head } = state.selection;
280
+ try {
281
+ const nextPos = Selection.near(state.doc.resolve(side > 0 ? $head.after() : $head.before()), side);
282
+ if (nextPos.$head && nextPos.$head.parent.type.name === 'codeBlock') {
283
+ view.dispatch(state.tr.setSelection(nextPos));
284
+ return true;
285
+ }
286
+ }
287
+ catch {
288
+ // selection sits at the document boundary — nothing to move into
289
+ }
290
+ return false;
291
+ };
292
+ }
293
+ /**
294
+ * CodeBlock extension whose blocks are full CodeMirror editors: syntax
295
+ * highlighting, autocompletion, bracket matching and smart indentation, with a
296
+ * per-block language picker. Serializes to standard
297
+ * `<pre><code class="language-...">` HTML, so content round-trips unchanged.
298
+ */
299
+ export const CodeBlockEditor = CodeBlock.extend({
300
+ addOptions() {
301
+ const parent = this.parent?.() ?? {};
302
+ return {
303
+ ...parent,
304
+ defaultLanguage: 'javascript',
305
+ languages: null
306
+ };
307
+ },
308
+ addKeyboardShortcuts() {
309
+ return {
310
+ ...this.parent?.(),
311
+ ArrowLeft: arrowIntoCodeBlock('left'),
312
+ ArrowRight: arrowIntoCodeBlock('right'),
313
+ ArrowUp: arrowIntoCodeBlock('up'),
314
+ ArrowDown: arrowIntoCodeBlock('down')
315
+ };
316
+ },
317
+ addNodeView() {
318
+ const configured = this.options.languages;
319
+ const languages = configured
320
+ ? configured
321
+ .map((id) => resolveCodeBlockLanguage(id))
322
+ .filter((def) => Boolean(def))
323
+ : codeBlockLanguages;
324
+ return ({ node, editor, getPos }) => new CodeBlockView(node, editor, getPos, languages);
325
+ }
326
+ });
@@ -0,0 +1,19 @@
1
+ import { Node } from '@tiptap/core';
2
+ export interface DivOptions {
3
+ HTMLAttributes: Record<string, any>;
4
+ }
5
+ declare module '@tiptap/core' {
6
+ interface Commands<ReturnType> {
7
+ div: {
8
+ /**
9
+ * Set the current node as a div
10
+ */
11
+ setDiv: () => ReturnType;
12
+ /**
13
+ * Toggle between div and paragraph
14
+ */
15
+ toggleDiv: () => ReturnType;
16
+ };
17
+ }
18
+ }
19
+ export declare const Div: Node<DivOptions, any>;
@@ -0,0 +1,89 @@
1
+ import { Node, mergeAttributes } from '@tiptap/core';
2
+ export const Div = Node.create({
3
+ name: 'div',
4
+ group: 'block',
5
+ content: 'block*',
6
+ isolating: false,
7
+ defining: false,
8
+ addOptions() {
9
+ return {
10
+ HTMLAttributes: {},
11
+ };
12
+ },
13
+ parseHTML() {
14
+ return [
15
+ {
16
+ tag: 'div',
17
+ // Preserve all attributes
18
+ getAttrs: (node) => {
19
+ if (typeof node === 'string')
20
+ return false;
21
+ const element = node;
22
+ // Skip if it's an alert or other custom node with data-type
23
+ if (element.getAttribute('data-type'))
24
+ return false;
25
+ // Preserve all attributes
26
+ const attrs = {};
27
+ Array.from(element.attributes).forEach(attr => {
28
+ attrs[attr.name] = attr.value;
29
+ });
30
+ return attrs;
31
+ },
32
+ },
33
+ ];
34
+ },
35
+ renderHTML({ HTMLAttributes }) {
36
+ return ['div', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
37
+ },
38
+ addCommands() {
39
+ return {
40
+ setDiv: () => ({ commands }) => {
41
+ return commands.setNode(this.name);
42
+ },
43
+ toggleDiv: () => ({ commands }) => {
44
+ return commands.toggleNode(this.name, 'paragraph');
45
+ },
46
+ };
47
+ },
48
+ addAttributes() {
49
+ return {
50
+ // Preserve all HTML attributes
51
+ class: {
52
+ default: null,
53
+ parseHTML: element => element.getAttribute('class'),
54
+ renderHTML: attributes => {
55
+ if (!attributes.class)
56
+ return {};
57
+ return { class: attributes.class };
58
+ },
59
+ },
60
+ style: {
61
+ default: null,
62
+ parseHTML: element => element.getAttribute('style'),
63
+ renderHTML: attributes => {
64
+ if (!attributes.style)
65
+ return {};
66
+ return { style: attributes.style };
67
+ },
68
+ },
69
+ id: {
70
+ default: null,
71
+ parseHTML: element => element.getAttribute('id'),
72
+ renderHTML: attributes => {
73
+ if (!attributes.id)
74
+ return {};
75
+ return { id: attributes.id };
76
+ },
77
+ },
78
+ 'data-type': {
79
+ default: null,
80
+ parseHTML: element => element.getAttribute('data-type'),
81
+ renderHTML: attributes => {
82
+ if (!attributes['data-type'])
83
+ return {};
84
+ return { 'data-type': attributes['data-type'] };
85
+ },
86
+ },
87
+ };
88
+ },
89
+ });
@@ -0,0 +1,5 @@
1
+ import { Node } from '@tiptap/core';
2
+ export interface SpanOptions {
3
+ HTMLAttributes: Record<string, any>;
4
+ }
5
+ export declare const Span: Node<SpanOptions, any>;