neuphlo-editor 1.8.2 → 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 (41) hide show
  1. package/dist/chunk-2DWEJI45.js +1296 -0
  2. package/dist/chunk-2DWEJI45.js.map +1 -0
  3. package/dist/chunk-457ETWB6.js +1351 -0
  4. package/dist/chunk-457ETWB6.js.map +1 -0
  5. package/dist/chunk-62DYB7FY.js +1305 -0
  6. package/dist/chunk-62DYB7FY.js.map +1 -0
  7. package/dist/chunk-DWGPGRTQ.js +1302 -0
  8. package/dist/chunk-DWGPGRTQ.js.map +1 -0
  9. package/dist/chunk-EG7NQJRA.js +1324 -0
  10. package/dist/chunk-EG7NQJRA.js.map +1 -0
  11. package/dist/chunk-FLLPFFI5.js +1296 -0
  12. package/dist/chunk-FLLPFFI5.js.map +1 -0
  13. package/dist/chunk-FVQHB6VC.js +1128 -0
  14. package/dist/chunk-FVQHB6VC.js.map +1 -0
  15. package/dist/chunk-GXJGZHKR.js +1326 -0
  16. package/dist/chunk-GXJGZHKR.js.map +1 -0
  17. package/dist/chunk-KCPPTLGY.js +1299 -0
  18. package/dist/chunk-KCPPTLGY.js.map +1 -0
  19. package/dist/chunk-LHG2NX6C.js +1123 -0
  20. package/dist/chunk-LHG2NX6C.js.map +1 -0
  21. package/dist/chunk-OCNM37WJ.js +1289 -0
  22. package/dist/chunk-OCNM37WJ.js.map +1 -0
  23. package/dist/chunk-RW6QBMJB.js +1300 -0
  24. package/dist/chunk-RW6QBMJB.js.map +1 -0
  25. package/dist/chunk-SOXTEP7H.js +6705 -0
  26. package/dist/chunk-SOXTEP7H.js.map +1 -0
  27. package/dist/headless/index.cjs +207 -144
  28. package/dist/headless/index.cjs.map +1 -1
  29. package/dist/headless/index.d.cts +9 -25
  30. package/dist/headless/index.d.ts +9 -25
  31. package/dist/headless/index.js +1 -1
  32. package/dist/react/index.cjs +1839 -723
  33. package/dist/react/index.cjs.map +1 -1
  34. package/dist/react/index.css +364 -8
  35. package/dist/react/index.css.map +1 -1
  36. package/dist/react/index.d.cts +10 -2
  37. package/dist/react/index.d.ts +10 -2
  38. package/dist/react/index.js +1434 -547
  39. package/dist/react/index.js.map +1 -1
  40. package/dist/styles.css +410 -8
  41. package/package.json +7 -2
package/dist/styles.css CHANGED
@@ -176,17 +176,35 @@
176
176
  .nph-editor table,
177
177
  .ProseMirror.nph-editor table {
178
178
  width: 100%;
179
- table-layout: auto;
180
- border-collapse: collapse;
181
- margin: 1.25rem 0;
179
+ table-layout: fixed;
180
+ border-collapse: separate;
181
+ border-spacing: 0;
182
+ margin: 0;
183
+ border-radius: 0.5rem;
184
+ overflow: hidden;
185
+ border: 1px solid var(--border, rgba(0, 0, 0, 0.12));
182
186
  }
183
187
  .nph-editor th,
184
188
  .nph-editor td,
185
189
  .ProseMirror.nph-editor th,
186
190
  .ProseMirror.nph-editor td {
187
- border: 1px solid var(--border, rgba(0, 0, 0, 0.12));
191
+ border-right: 1px solid var(--border, rgba(0, 0, 0, 0.12));
192
+ border-bottom: 1px solid var(--border, rgba(0, 0, 0, 0.12));
188
193
  padding: 0.5rem 0.75rem;
189
194
  vertical-align: top;
195
+ min-width: 100px;
196
+ }
197
+ .nph-editor th:last-child,
198
+ .nph-editor td:last-child,
199
+ .ProseMirror.nph-editor th:last-child,
200
+ .ProseMirror.nph-editor td:last-child {
201
+ border-right: none;
202
+ }
203
+ .nph-editor tr:last-child th,
204
+ .nph-editor tr:last-child td,
205
+ .ProseMirror.nph-editor tr:last-child th,
206
+ .ProseMirror.nph-editor tr:last-child td {
207
+ border-bottom: none;
190
208
  }
191
209
  .nph-editor th,
192
210
  .ProseMirror.nph-editor th {
@@ -194,6 +212,157 @@
194
212
  font-weight: 600;
195
213
  }
196
214
 
215
+ /* Table editing */
216
+ .nph-editor .tableWrapper,
217
+ .ProseMirror.nph-editor .tableWrapper {
218
+ overflow-x: auto;
219
+ margin: 1.25rem 0;
220
+ }
221
+
222
+ .nph-editor .selectedCell::after,
223
+ .ProseMirror.nph-editor .selectedCell::after {
224
+ content: "";
225
+ position: absolute;
226
+ inset: 0;
227
+ background: rgba(59, 130, 246, 0.1);
228
+ pointer-events: none;
229
+ z-index: 1;
230
+ }
231
+
232
+ .nph-editor td.selectedCell,
233
+ .nph-editor th.selectedCell,
234
+ .ProseMirror.nph-editor td.selectedCell,
235
+ .ProseMirror.nph-editor th.selectedCell {
236
+ position: relative;
237
+ }
238
+
239
+ .nph-editor .column-resize-handle,
240
+ .ProseMirror.nph-editor .column-resize-handle {
241
+ position: absolute;
242
+ right: -2px;
243
+ top: 0;
244
+ bottom: 0;
245
+ width: 4px;
246
+ background-color: var(--primary, #3b82f6);
247
+ pointer-events: none;
248
+ z-index: 2;
249
+ }
250
+
251
+ .nph-editor.resize-cursor,
252
+ .ProseMirror.nph-editor.resize-cursor {
253
+ cursor: col-resize;
254
+ }
255
+
256
+ /* Table grip handles — hidden by default, shown via JS on table hover */
257
+ .nph-table-grip {
258
+ display: flex;
259
+ align-items: center;
260
+ justify-content: center;
261
+ border: none;
262
+ border-radius: 0.375rem;
263
+ background: var(--muted, rgba(127, 127, 127, 0.12));
264
+ color: var(--muted-foreground, #6b7280);
265
+ cursor: pointer;
266
+ opacity: 0;
267
+ transition: opacity 0.15s ease, background-color 0.15s ease;
268
+ z-index: 50;
269
+ padding: 0;
270
+ pointer-events: none;
271
+ }
272
+ .nph-table-grip.nph-table-grip--visible {
273
+ opacity: 0.6;
274
+ pointer-events: auto;
275
+ }
276
+ .nph-table-grip.nph-table-grip--visible:hover {
277
+ opacity: 1;
278
+ background: var(--accent, rgba(127, 127, 127, 0.2));
279
+ color: var(--foreground, #111827);
280
+ }
281
+
282
+ .nph-table-grip--delete {
283
+ gap: 4px;
284
+ font-size: 12px;
285
+ color: var(--destructive, #ef4444);
286
+ background: transparent;
287
+ }
288
+ .nph-table-grip--delete.nph-table-grip--visible {
289
+ opacity: 0.4;
290
+ }
291
+ .nph-table-grip--delete.nph-table-grip--visible:hover {
292
+ opacity: 1;
293
+ color: var(--destructive, #ef4444);
294
+ background: rgba(239, 68, 68, 0.08);
295
+ }
296
+
297
+ /* Table dropdown menu */
298
+ .nph-table-dropdown {
299
+ background-color: var(--background, #ffffff);
300
+ color: var(--foreground, #111827);
301
+ border: 1px solid var(--border, rgba(0, 0, 0, 0.08));
302
+ border-radius: 0.7rem;
303
+ box-shadow: var(--shadow, 0 4px 16px rgba(0, 0, 0, 0.12));
304
+ padding: 0.25rem;
305
+ min-width: 180px;
306
+ z-index: 100;
307
+ overflow: hidden;
308
+ }
309
+ .nph-table-dropdown__item {
310
+ display: flex;
311
+ align-items: center;
312
+ gap: 0.5rem;
313
+ width: 100%;
314
+ padding: 0.375rem 0.625rem;
315
+ border: none;
316
+ border-radius: 0.375rem;
317
+ background: none;
318
+ color: inherit;
319
+ font-size: 0.8125rem;
320
+ cursor: pointer;
321
+ text-align: left;
322
+ }
323
+ .nph-table-dropdown__item:hover {
324
+ background-color: var(--muted, rgba(127, 127, 127, 0.12));
325
+ }
326
+ .nph-table-dropdown__item--destructive {
327
+ color: var(--destructive, #ef4444);
328
+ }
329
+ .nph-table-dropdown__item--destructive:hover {
330
+ background-color: rgba(239, 68, 68, 0.08);
331
+ }
332
+ .nph-table-dropdown__separator {
333
+ height: 1px;
334
+ background: var(--border, rgba(0, 0, 0, 0.08));
335
+ margin: 0.25rem 0.375rem;
336
+ }
337
+
338
+ .nph-table-grip--dragging {
339
+ opacity: 1 !important;
340
+ background: var(--primary, #2563eb) !important;
341
+ color: white !important;
342
+ }
343
+ .nph-table-drop-indicator {
344
+ background: var(--primary, #2563eb);
345
+ border-radius: 1px;
346
+ z-index: 9999;
347
+ pointer-events: none;
348
+ }
349
+
350
+ @media (prefers-color-scheme: dark) {
351
+ .nph-table-dropdown {
352
+ background-color: var(--background, #1f2937);
353
+ border-color: var(--border, rgba(255, 255, 255, 0.1));
354
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
355
+ }
356
+ .nph-table-grip {
357
+ background: var(--muted, rgba(255, 255, 255, 0.1));
358
+ color: var(--muted-foreground, #9ca3af);
359
+ }
360
+ .nph-table-grip:hover {
361
+ background: var(--accent, rgba(255, 255, 255, 0.18));
362
+ color: var(--foreground, #f3f4f6);
363
+ }
364
+ }
365
+
197
366
  /* Task list (if enabled) */
198
367
  .nph-editor ul[data-type="taskList"],
199
368
  .ProseMirror.nph-editor ul[data-type="taskList"] {
@@ -265,6 +434,15 @@
265
434
  z-index: var(--nph-z) !important;
266
435
  }
267
436
 
437
+ /* Bubble menu separator */
438
+ .nph-bubble-separator {
439
+ width: 1px;
440
+ height: 18px;
441
+ background: var(--border, rgba(0, 0, 0, 0.12));
442
+ margin: 0 2px;
443
+ flex-shrink: 0;
444
+ }
445
+
268
446
  /* Ensure Tiptap/Tippy bubble root stacks high */
269
447
  [data-tippy-root],
270
448
  .tippy-box {
@@ -289,9 +467,10 @@
289
467
  background-color: var(--background, #ffffff);
290
468
  color: var(--foreground, #111827);
291
469
  border: 1px solid var(--border, rgba(0, 0, 0, 0.08));
292
- border-radius: 0.5rem;
470
+ border-radius: 0.7rem;
293
471
  box-shadow: var(--shadow, 0 4px 16px rgba(0, 0, 0, 0.08));
294
472
  padding: 0.25rem;
473
+ overflow: hidden;
295
474
  }
296
475
 
297
476
  .nph-command__list {
@@ -337,6 +516,20 @@
337
516
  }
338
517
  }
339
518
 
519
+ /* Slash menu group headers */
520
+ .nph-command__group-header {
521
+ font-size: 0.6875rem;
522
+ font-weight: 600;
523
+ text-transform: uppercase;
524
+ letter-spacing: 0.05em;
525
+ color: var(--muted-foreground, #6b7280);
526
+ padding: 0.5rem 0.5rem 0.25rem;
527
+ margin-top: 0.25rem;
528
+ }
529
+ .nph-command__group-header:first-child {
530
+ margin-top: 0;
531
+ }
532
+
340
533
  .nph-command__item {
341
534
  display: flex;
342
535
  align-items: center;
@@ -346,6 +539,41 @@
346
539
  cursor: pointer;
347
540
  }
348
541
 
542
+ /* Icon background square */
543
+ .nph-command__item-icon {
544
+ display: flex;
545
+ align-items: center;
546
+ justify-content: center;
547
+ width: 28px;
548
+ height: 28px;
549
+ min-width: 28px;
550
+ border-radius: 0.375rem;
551
+ flex-shrink: 0;
552
+ background-color: var(--muted, rgba(127, 127, 127, 0.1));
553
+ color: var(--foreground, #111827);
554
+ }
555
+
556
+ /* Title + description layout */
557
+ .nph-command__item-content {
558
+ display: flex;
559
+ flex-direction: column;
560
+ gap: 0;
561
+ min-width: 0;
562
+ }
563
+ .nph-command__item-title {
564
+ font-size: 0.8125rem;
565
+ font-weight: 500;
566
+ line-height: 1.3;
567
+ }
568
+ .nph-command__item-description {
569
+ font-size: 0.6875rem;
570
+ color: var(--muted-foreground, #6b7280);
571
+ line-height: 1.3;
572
+ white-space: nowrap;
573
+ overflow: hidden;
574
+ text-overflow: ellipsis;
575
+ }
576
+
349
577
  .nph-command__item:hover {
350
578
  background-color: var(--muted, rgba(127, 127, 127, 0.12));
351
579
  }
@@ -521,13 +749,34 @@
521
749
  }
522
750
  }
523
751
 
752
+ /* Image & Video Block – move selection outline to the inner wrapper
753
+ so it tightly wraps the actual content, not the full-width ProseMirror container */
754
+ .nph-editor .node-imageBlock.ProseMirror-selectednode,
755
+ .nph-editor .node-videoBlock.ProseMirror-selectednode {
756
+ outline: none;
757
+ }
758
+
759
+ .nph-editor .node-imageBlock > [data-node-view-wrapper],
760
+ .nph-editor .node-videoBlock > [data-node-view-wrapper] {
761
+ line-height: 0;
762
+ font-size: 0;
763
+ }
764
+
765
+ .nph-editor .node-imageBlock.ProseMirror-selectednode > [data-node-view-wrapper],
766
+ .nph-editor .node-videoBlock.ProseMirror-selectednode > [data-node-view-wrapper] {
767
+ outline: 2px solid var(--border, #e5e7eb);
768
+ outline-offset: 2px;
769
+ border-radius: 12px;
770
+ }
771
+
524
772
  /* Image Block */
525
773
  .nph-image-block {
526
774
  display: block;
775
+ vertical-align: bottom;
527
776
  border-radius: 12px;
528
777
  box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
529
778
  border: 1px solid var(--border, #e5e7eb);
530
- max-width: 100%;
779
+ width: 100%;
531
780
  height: auto;
532
781
  cursor: pointer;
533
782
  transition: box-shadow 0.2s ease;
@@ -588,12 +837,14 @@
588
837
  flex-direction: column;
589
838
  align-items: center;
590
839
  justify-content: center;
591
- padding: 40px 32px;
592
- border-radius: 8px;
840
+ padding: 48px 32px;
841
+ border-radius: 12px;
593
842
  background-color: transparent !important;
594
843
  border: 2px dashed var(--border, #e5e7eb);
595
844
  cursor: pointer;
596
845
  transition: background-color 0.2s, border-color 0.2s;
846
+ width: 100%;
847
+ box-sizing: border-box;
597
848
  }
598
849
 
599
850
  .nph-image-uploader--dragging {
@@ -747,6 +998,12 @@
747
998
  border: none;
748
999
  }
749
1000
 
1001
+ .nph-video-block__overlay {
1002
+ position: absolute;
1003
+ inset: 0;
1004
+ cursor: pointer;
1005
+ }
1006
+
750
1007
  /* Video URL Input */
751
1008
  .nph-video-input {
752
1009
  display: flex;
@@ -850,6 +1107,151 @@
850
1107
  border-color: var(--border, #374151);
851
1108
  }
852
1109
 
1110
+ /* Drag Handle */
1111
+ .nph-drag-handle {
1112
+ display: flex;
1113
+ align-items: center;
1114
+ gap: 1px;
1115
+ opacity: 0;
1116
+ transition: opacity 0.15s ease;
1117
+ cursor: grab;
1118
+ /* Push handle away from content — floating-ui places it flush left */
1119
+ margin-right: 12px;
1120
+ }
1121
+ .nph-drag-handle:hover,
1122
+ .nph-drag-handle.visible {
1123
+ opacity: 1;
1124
+ }
1125
+
1126
+ .nph-drag-handle__btn {
1127
+ display: flex;
1128
+ align-items: center;
1129
+ justify-content: center;
1130
+ width: 18px;
1131
+ height: 18px;
1132
+ border: none;
1133
+ border-radius: 4px;
1134
+ background: transparent;
1135
+ color: var(--muted-foreground, #9ca3af);
1136
+ cursor: pointer;
1137
+ padding: 0;
1138
+ transition: background-color 0.15s, color 0.15s;
1139
+ }
1140
+ .nph-drag-handle__btn:hover {
1141
+ background-color: var(--muted, rgba(127, 127, 127, 0.12));
1142
+ color: var(--foreground, #111827);
1143
+ }
1144
+
1145
+ .nph-drag-handle__grip {
1146
+ cursor: grab;
1147
+ }
1148
+ .nph-drag-handle__grip:active {
1149
+ cursor: grabbing;
1150
+ }
1151
+
1152
+ /* Block action menu */
1153
+ .nph-block-action-menu {
1154
+ min-width: 180px;
1155
+ }
1156
+
1157
+ /* Image Resize Handle */
1158
+ .nph-resize-wrapper {
1159
+ position: relative;
1160
+ display: block;
1161
+ width: 100%;
1162
+ }
1163
+
1164
+ .nph-resize-handle {
1165
+ position: absolute;
1166
+ top: 50%;
1167
+ width: 6px;
1168
+ height: 48px;
1169
+ max-height: 50%;
1170
+ transform: translateY(-50%);
1171
+ background: var(--primary, #3b82f6);
1172
+ border-radius: 3px;
1173
+ opacity: 0;
1174
+ cursor: col-resize;
1175
+ transition: opacity 0.15s;
1176
+ z-index: 5;
1177
+ }
1178
+
1179
+ .nph-resize-wrapper:hover .nph-resize-handle,
1180
+ .nph-resize-wrapper--active .nph-resize-handle {
1181
+ opacity: 1;
1182
+ }
1183
+
1184
+ .nph-resize-handle--left {
1185
+ left: 4px;
1186
+ }
1187
+ .nph-resize-handle--right {
1188
+ right: 4px;
1189
+ }
1190
+
1191
+ /* Table of Contents */
1192
+ .nph-toc {
1193
+ display: flex;
1194
+ flex-direction: column;
1195
+ gap: 1px;
1196
+ font-size: 0.8125rem;
1197
+ }
1198
+
1199
+ .nph-toc__item {
1200
+ display: block;
1201
+ width: 100%;
1202
+ text-align: left;
1203
+ background: none;
1204
+ border: none;
1205
+ border-radius: 4px;
1206
+ padding: 4px 8px;
1207
+ color: var(--muted-foreground, #6b7280);
1208
+ cursor: pointer;
1209
+ font-size: inherit;
1210
+ line-height: 1.4;
1211
+ white-space: nowrap;
1212
+ overflow: hidden;
1213
+ text-overflow: ellipsis;
1214
+ transition: background-color 0.15s, color 0.15s;
1215
+ }
1216
+ .nph-toc__item:hover {
1217
+ background-color: var(--muted, rgba(127, 127, 127, 0.12));
1218
+ color: var(--foreground, #111827);
1219
+ }
1220
+ .nph-toc__item--active {
1221
+ color: var(--foreground, #111827);
1222
+ font-weight: 500;
1223
+ background-color: var(--accent, rgba(0, 0, 0, 0.05));
1224
+ }
1225
+
1226
+ /* Collaboration Carets */
1227
+ .nph-collab-caret {
1228
+ position: relative;
1229
+ border-left: 2px solid;
1230
+ margin-left: -1px;
1231
+ margin-right: -1px;
1232
+ pointer-events: none;
1233
+ word-break: normal;
1234
+ }
1235
+
1236
+ .nph-collab-caret__label {
1237
+ position: absolute;
1238
+ top: -1.4em;
1239
+ left: -1px;
1240
+ font-size: 0.6875rem;
1241
+ font-weight: 600;
1242
+ line-height: 1;
1243
+ color: #fff;
1244
+ padding: 1px 4px 2px;
1245
+ border-radius: 3px 3px 3px 0;
1246
+ white-space: nowrap;
1247
+ pointer-events: none;
1248
+ user-select: none;
1249
+ }
1250
+
1251
+ .nph-collab-selection {
1252
+ pointer-events: none;
1253
+ }
1254
+
853
1255
  /* Mention styles */
854
1256
  .nph-editor .mention,
855
1257
  .ProseMirror.nph-editor .mention {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neuphlo-editor",
3
- "version": "1.8.2",
3
+ "version": "2.0.0",
4
4
  "private": false,
5
5
  "description": "A lightweight React wrapper around Tiptap with sensible defaults and image upload support.",
6
6
  "type": "module",
@@ -49,10 +49,10 @@
49
49
  "lint": "eslint . --ext .ts,.tsx"
50
50
  },
51
51
  "peerDependencies": {
52
+ "@tiptap/extension-collaboration": "^3.20.2",
52
53
  "@tiptap/pm": "^3.20.2",
53
54
  "@tiptap/react": "^3.20.2",
54
55
  "@tiptap/suggestion": "^3.20.2",
55
- "@tiptap/extension-collaboration": "^3.20.2",
56
56
  "@tiptap/y-tiptap": "^3.0.2",
57
57
  "@types/react": "^18.2.0 || ^19.0.0",
58
58
  "@types/react-dom": "^18.2.0 || ^19.0.0",
@@ -81,6 +81,7 @@
81
81
  "typescript": "^5.9.2"
82
82
  },
83
83
  "dependencies": {
84
+ "@floating-ui/dom": "^1.7.6",
84
85
  "@tabler/icons-react": "^3.34.1",
85
86
  "@tiptap/core": "3.20.2",
86
87
  "@tiptap/extension-blockquote": "3.20.2",
@@ -90,7 +91,9 @@
90
91
  "@tiptap/extension-code-block": "3.20.2",
91
92
  "@tiptap/extension-code-block-lowlight": "3.20.2",
92
93
  "@tiptap/extension-collaboration": "3.20.2",
94
+ "@tiptap/extension-collaboration-caret": "3.20.2",
93
95
  "@tiptap/extension-document": "3.20.2",
96
+ "@tiptap/extension-drag-handle": "3.20.2",
94
97
  "@tiptap/extension-dropcursor": "3.20.2",
95
98
  "@tiptap/extension-gapcursor": "3.20.2",
96
99
  "@tiptap/extension-hard-break": "3.20.2",
@@ -103,10 +106,12 @@
103
106
  "@tiptap/extension-list-item": "3.20.2",
104
107
  "@tiptap/extension-list-keymap": "3.20.2",
105
108
  "@tiptap/extension-mention": "3.20.2",
109
+ "@tiptap/extension-node-range": "3.20.2",
106
110
  "@tiptap/extension-ordered-list": "3.20.2",
107
111
  "@tiptap/extension-paragraph": "3.20.2",
108
112
  "@tiptap/extension-placeholder": "3.20.2",
109
113
  "@tiptap/extension-strike": "3.20.2",
114
+ "@tiptap/extension-table": "3.20.2",
110
115
  "@tiptap/extension-text": "3.20.2",
111
116
  "@tiptap/extension-underline": "3.20.2",
112
117
  "@tiptap/extensions": "3.20.2",