@kedataindo/docflow-plugins 0.0.91 → 0.0.93

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.
package/dist/index.cjs CHANGED
@@ -42,6 +42,7 @@ __export(index_exports, {
42
42
  DateChipNode: () => DateChipNode,
43
43
  DropdownChipNode: () => DropdownChipNode,
44
44
  FileChipNode: () => FileChipNode,
45
+ FontFamilyExtension: () => import_docflow_core15.FontFamilyExtension,
45
46
  FontSizeExtension: () => import_docflow_core14.FontSizeExtension,
46
47
  FootnoteNode: () => FootnoteNode,
47
48
  LocationChipNode: () => LocationChipNode,
@@ -70,6 +71,7 @@ __export(index_exports, {
70
71
  commentPlugin: () => commentPlugin,
71
72
  createPlaceholderPlugin: () => createPlaceholderPlugin,
72
73
  defaultPlugins: () => defaultPlugins,
74
+ fontFamilyPlugin: () => fontFamilyPlugin,
73
75
  fontSizePlugin: () => fontSizePlugin,
74
76
  footnotePlugin: () => footnotePlugin,
75
77
  formattingPlugin: () => formattingPlugin,
@@ -289,6 +291,7 @@ var import_extension_table = __toESM(require("@tiptap/extension-table"), 1);
289
291
  var import_extension_table_row = __toESM(require("@tiptap/extension-table-row"), 1);
290
292
  var import_extension_table_cell = __toESM(require("@tiptap/extension-table-cell"), 1);
291
293
  var import_extension_table_header = __toESM(require("@tiptap/extension-table-header"), 1);
294
+ var import_state = require("@tiptap/pm/state");
292
295
  var CustomTable = import_extension_table.default.extend({
293
296
  addAttributes() {
294
297
  return {
@@ -358,6 +361,31 @@ var CustomTable = import_extension_table.default.extend({
358
361
  ["colgroup", ...cols],
359
362
  ["tbody", 0]
360
363
  ];
364
+ },
365
+ // #139: double-clicking an EMPTY cell resolved the caret to a neighbouring
366
+ // cell — ProseMirror's default dblclick word-selection has no text to land on
367
+ // in a cell whose only content is a trailing <br>. When the resolved position
368
+ // is not inside the cell under the pointer, place the caret at that cell's
369
+ // start instead. Non-empty cells keep the default (select the word).
370
+ addProseMirrorPlugins() {
371
+ const parent = this.parent?.() ?? [];
372
+ return [
373
+ ...parent,
374
+ new import_state.Plugin({
375
+ props: {
376
+ handleDoubleClick(view, pos, event) {
377
+ const cell = event.target?.closest?.("td, th") ?? null;
378
+ if (!cell) return false;
379
+ if ((cell.textContent ?? "").trim() !== "") return false;
380
+ void pos;
381
+ const cellPos = view.posAtDOM(cell, 0);
382
+ const selection = import_state.TextSelection.near(view.state.doc.resolve(cellPos), 1);
383
+ view.dispatch(view.state.tr.setSelection(selection));
384
+ return true;
385
+ }
386
+ }
387
+ })
388
+ ];
361
389
  }
362
390
  });
363
391
  var CustomTableCell = import_extension_table_cell.default.extend({
@@ -642,13 +670,13 @@ var import_core4 = require("@tiptap/core");
642
670
  var import_docflow_core13 = require("@kedataindo/docflow-core");
643
671
 
644
672
  // src/editorScroll.ts
645
- var import_state = require("@tiptap/pm/state");
673
+ var import_state2 = require("@tiptap/pm/state");
646
674
  function scrollEditorToPos(editor, pos, options = {}) {
647
675
  const { state, view } = editor;
648
676
  const clamped = Math.min(Math.max(0, pos), state.doc.content.size);
649
677
  let anchor = clamped;
650
678
  if (options.focus !== false) {
651
- const selection = import_state.TextSelection.near(state.doc.resolve(clamped), 1);
679
+ const selection = import_state2.TextSelection.near(state.doc.resolve(clamped), 1);
652
680
  if (!state.selection.eq(selection)) {
653
681
  view.dispatch(state.tr.setSelection(selection));
654
682
  }
@@ -933,10 +961,29 @@ var fontSizePlugin = (0, import_docflow_core14.definePlugin)({
933
961
  }
934
962
  });
935
963
 
936
- // src/textColor.ts
964
+ // src/fontFamily.ts
937
965
  var import_docflow_core15 = require("@kedataindo/docflow-core");
966
+ var fontFamilyPlugin = (0, import_docflow_core15.definePlugin)({
967
+ id: "font-family",
968
+ tiptapExtensions: [import_docflow_core15.FontFamilyExtension],
969
+ commands: {
970
+ setFontFamily: (editor, ...args) => {
971
+ const family = args[0] || "";
972
+ if (family) {
973
+ editor.commands.setFontFamily(family);
974
+ } else {
975
+ editor.commands.unsetFontFamily();
976
+ }
977
+ editor.commands.focus();
978
+ return true;
979
+ }
980
+ }
981
+ });
982
+
983
+ // src/textColor.ts
984
+ var import_docflow_core16 = require("@kedataindo/docflow-core");
938
985
  var import_extension_color = __toESM(require("@tiptap/extension-color"), 1);
939
- var textColorPlugin = (0, import_docflow_core15.definePlugin)({
986
+ var textColorPlugin = (0, import_docflow_core16.definePlugin)({
940
987
  id: "text-color",
941
988
  tiptapExtensions: [import_extension_color.default],
942
989
  toolbar: [
@@ -955,7 +1002,7 @@ var textColorPlugin = (0, import_docflow_core15.definePlugin)({
955
1002
  });
956
1003
 
957
1004
  // src/highlight.ts
958
- var import_docflow_core16 = require("@kedataindo/docflow-core");
1005
+ var import_docflow_core17 = require("@kedataindo/docflow-core");
959
1006
  var import_extension_highlight = __toESM(require("@tiptap/extension-highlight"), 1);
960
1007
  var import_core5 = require("@tiptap/core");
961
1008
  var GoogleDocsHighlight = import_extension_highlight.default.extend({
@@ -985,7 +1032,7 @@ var GoogleDocsHighlight = import_extension_highlight.default.extend({
985
1032
  return ["mark", (0, import_core5.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes), 0];
986
1033
  }
987
1034
  });
988
- var highlightPlugin = (0, import_docflow_core16.definePlugin)({
1035
+ var highlightPlugin = (0, import_docflow_core17.definePlugin)({
989
1036
  id: "highlight",
990
1037
  tiptapExtensions: [
991
1038
  GoogleDocsHighlight.configure({
@@ -1011,7 +1058,7 @@ var highlightPlugin = (0, import_docflow_core16.definePlugin)({
1011
1058
 
1012
1059
  // src/citation.ts
1013
1060
  var import_core7 = require("@tiptap/core");
1014
- var import_docflow_core17 = require("@kedataindo/docflow-core");
1061
+ var import_docflow_core18 = require("@kedataindo/docflow-core");
1015
1062
 
1016
1063
  // src/citeEngine.ts
1017
1064
  var import_citeproc = __toESM(require("citeproc"), 1);
@@ -2372,7 +2419,7 @@ function insertCitationWithSource(editor, engine, attrs) {
2372
2419
  if (spec.type === "footnote" && !editor.schema.nodes["footnote"]) return false;
2373
2420
  return editor.chain().focus().insertContent({ type: spec.type, attrs: spec.attrs }).run();
2374
2421
  }
2375
- var citationPlugin = (0, import_docflow_core17.definePlugin)({
2422
+ var citationPlugin = (0, import_docflow_core18.definePlugin)({
2376
2423
  id: "citation",
2377
2424
  tiptapExtensions: [CitationEngineExtension, CitationNode, BibliographyNode],
2378
2425
  toolbar: [{ id: "insert-citation", label: "Citation", action: "insertCitation", iconComponent: "Quote" }],
@@ -2442,15 +2489,15 @@ var citationPlugin = (0, import_docflow_core17.definePlugin)({
2442
2489
 
2443
2490
  // src/ai.ts
2444
2491
  var import_core9 = require("@tiptap/core");
2445
- var import_state3 = require("@tiptap/pm/state");
2492
+ var import_state4 = require("@tiptap/pm/state");
2446
2493
  var import_view = require("@tiptap/pm/view");
2447
2494
  var import_tiptap_markdown = require("tiptap-markdown");
2448
- var import_docflow_core18 = require("@kedataindo/docflow-core");
2495
+ var import_docflow_core19 = require("@kedataindo/docflow-core");
2449
2496
 
2450
2497
  // src/markdownInsert.ts
2451
2498
  var import_core8 = require("@tiptap/core");
2452
2499
  var import_model = require("@tiptap/pm/model");
2453
- var import_state2 = require("@tiptap/pm/state");
2500
+ var import_state3 = require("@tiptap/pm/state");
2454
2501
  var import_transform = require("@tiptap/pm/transform");
2455
2502
  function mdParser(editor) {
2456
2503
  const storage = editor.storage.markdown;
@@ -2486,7 +2533,7 @@ function selectionToInsertionEnd(tr, startLen, bias) {
2486
2533
  map.forEach((_from, _to, _newFrom, newTo) => {
2487
2534
  if (end === 0) end = newTo;
2488
2535
  });
2489
- tr.setSelection(import_state2.Selection.near(tr.doc.resolve(end), bias));
2536
+ tr.setSelection(import_state3.Selection.near(tr.doc.resolve(end), bias));
2490
2537
  }
2491
2538
  function insertMarkdownBlock(editor, view, from, to, markdown) {
2492
2539
  const fragment = markdownToFragment(editor, markdown, { inline: false });
@@ -2529,7 +2576,7 @@ function insertMarkdownBlock(editor, view, from, to, markdown) {
2529
2576
  }
2530
2577
 
2531
2578
  // src/ai.ts
2532
- var aiPluginKey = new import_state3.PluginKey("docflow-ai");
2579
+ var aiPluginKey = new import_state4.PluginKey("docflow-ai");
2533
2580
  var CONTEXT_CHARS = 1500;
2534
2581
  function getAIPreview(editor) {
2535
2582
  return editor.storage.ai ? editor.storage.ai.preview ?? null : null;
@@ -2765,7 +2812,7 @@ var AIExtension = import_core9.Extension.create({
2765
2812
  };
2766
2813
  }
2767
2814
  return [
2768
- new import_state3.Plugin({
2815
+ new import_state4.Plugin({
2769
2816
  key: aiPluginKey,
2770
2817
  state: {
2771
2818
  init: () => null,
@@ -2881,7 +2928,7 @@ var AIExtension = import_core9.Extension.create({
2881
2928
  storage.preview = null;
2882
2929
  }
2883
2930
  });
2884
- var aiPlugin = (0, import_docflow_core18.definePlugin)({
2931
+ var aiPlugin = (0, import_docflow_core19.definePlugin)({
2885
2932
  id: "ai",
2886
2933
  // The `tiptap-markdown` `Markdown` extension is registered alongside AI so
2887
2934
  // that `editor.storage.markdown.parser` is available on every editor that
@@ -2937,15 +2984,15 @@ var commentPlugin = {
2937
2984
 
2938
2985
  // src/suggestChanges.ts
2939
2986
  var import_core11 = require("@tiptap/core");
2940
- var import_state4 = require("@tiptap/pm/state");
2987
+ var import_state5 = require("@tiptap/pm/state");
2941
2988
  var import_transform2 = require("@tiptap/pm/transform");
2942
- var import_docflow_core19 = require("@kedataindo/docflow-core");
2989
+ var import_docflow_core20 = require("@kedataindo/docflow-core");
2943
2990
  var SUGGESTION_INSERT = "suggestionInsert";
2944
2991
  var SUGGESTION_DELETE = "suggestionDelete";
2945
2992
  var SUGGESTION_FORMAT = "suggestionFormat";
2946
2993
  var FORMAT_MARKS = /* @__PURE__ */ new Set(["bold", "italic", "underline", "strike", "highlight"]);
2947
2994
  var SUGGEST_APPLIED_META = "suggestChanges:applied";
2948
- var suggestChangesKey = new import_state4.PluginKey("suggestChanges");
2995
+ var suggestChangesKey = new import_state5.PluginKey("suggestChanges");
2949
2996
  var suggestionAttributes = () => ({
2950
2997
  suggestionId: {
2951
2998
  default: null,
@@ -3067,7 +3114,7 @@ var SuggestChanges = import_core11.Extension.create({
3067
3114
  if (storage) storage.suggestions = getSuggestions(editor);
3068
3115
  };
3069
3116
  return [
3070
- new import_state4.Plugin({
3117
+ new import_state5.Plugin({
3071
3118
  key: suggestChangesKey,
3072
3119
  state: {
3073
3120
  init: () => ({ mode: "editing", author: {} }),
@@ -3155,7 +3202,7 @@ var SuggestChanges = import_core11.Extension.create({
3155
3202
  const id = adjacentRunId(view.state, from, SUGGESTION_DELETE) ?? newSuggestionId();
3156
3203
  const tr = view.state.tr.addMark(from, to, del.create(markAttrs(id, current.author)));
3157
3204
  if (event.key === "Backspace" && selection.empty) {
3158
- tr.setSelection(import_state4.TextSelection.create(tr.doc, from));
3205
+ tr.setSelection(import_state5.TextSelection.create(tr.doc, from));
3159
3206
  }
3160
3207
  view.dispatch(tr);
3161
3208
  return true;
@@ -3307,7 +3354,7 @@ var acceptSuggestion = (editor, id) => resolveSuggestions(editor, true, id);
3307
3354
  var rejectSuggestion = (editor, id) => resolveSuggestions(editor, false, id);
3308
3355
  var acceptAllSuggestions = (editor) => resolveSuggestions(editor, true);
3309
3356
  var rejectAllSuggestions = (editor) => resolveSuggestions(editor, false);
3310
- var suggestChangesPlugin = (0, import_docflow_core19.definePlugin)({
3357
+ var suggestChangesPlugin = (0, import_docflow_core20.definePlugin)({
3311
3358
  id: "suggestChanges",
3312
3359
  tiptapExtensions: [SuggestionInsertMark, SuggestionDeleteMark, SuggestionFormatMark, SuggestChanges],
3313
3360
  commands: {
@@ -3322,7 +3369,7 @@ var suggestChangesPlugin = (0, import_docflow_core19.definePlugin)({
3322
3369
 
3323
3370
  // src/smartElements.ts
3324
3371
  var import_core12 = require("@tiptap/core");
3325
- var import_docflow_core20 = require("@kedataindo/docflow-core");
3372
+ var import_docflow_core21 = require("@kedataindo/docflow-core");
3326
3373
  function todayISO() {
3327
3374
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
3328
3375
  }
@@ -3692,7 +3739,7 @@ var LocationChipNode = import_core12.Node.create({
3692
3739
  };
3693
3740
  }
3694
3741
  });
3695
- var smartElementsPlugin = (0, import_docflow_core20.definePlugin)({
3742
+ var smartElementsPlugin = (0, import_docflow_core21.definePlugin)({
3696
3743
  id: "smart-elements",
3697
3744
  tiptapExtensions: [
3698
3745
  DateChipNode,
@@ -3751,10 +3798,10 @@ var smartElementsPlugin = (0, import_docflow_core20.definePlugin)({
3751
3798
  });
3752
3799
 
3753
3800
  // src/tablePageSplit.ts
3754
- var import_docflow_core21 = require("@kedataindo/docflow-core");
3801
+ var import_docflow_core22 = require("@kedataindo/docflow-core");
3755
3802
  var import_core13 = require("@tiptap/core");
3756
- var import_state5 = require("@tiptap/pm/state");
3757
- var PLUGIN_KEY = new import_state5.PluginKey("docflow/table-page-split");
3803
+ var import_state6 = require("@tiptap/pm/state");
3804
+ var PLUGIN_KEY = new import_state6.PluginKey("docflow/table-page-split");
3758
3805
  var SPLIT_MARK = "head";
3759
3806
  var MAX_SPLIT_DEPTH = 16;
3760
3807
  function readPageContentHeightPx(view, editor) {
@@ -3940,7 +3987,7 @@ var TablePageSplitExtension = import_core13.Extension.create({
3940
3987
  const ext = this;
3941
3988
  const editorRef = ext.editor ?? null;
3942
3989
  return [
3943
- new import_state5.Plugin({
3990
+ new import_state6.Plugin({
3944
3991
  key: PLUGIN_KEY,
3945
3992
  view(_editorView) {
3946
3993
  viewRef = _editorView;
@@ -3972,15 +4019,15 @@ var TablePageSplitExtension = import_core13.Extension.create({
3972
4019
  ];
3973
4020
  }
3974
4021
  });
3975
- var tablePageSplitPlugin = (0, import_docflow_core21.definePlugin)({
4022
+ var tablePageSplitPlugin = (0, import_docflow_core22.definePlugin)({
3976
4023
  id: "tablePageSplit",
3977
4024
  tiptapExtensions: [TablePageSplitExtension]
3978
4025
  });
3979
4026
 
3980
4027
  // src/slashMenu.ts
3981
4028
  var import_core14 = require("@tiptap/core");
3982
- var import_state6 = require("@tiptap/pm/state");
3983
- var import_docflow_core22 = require("@kedataindo/docflow-core");
4029
+ var import_state7 = require("@tiptap/pm/state");
4030
+ var import_docflow_core23 = require("@kedataindo/docflow-core");
3984
4031
  var slashState = {
3985
4032
  open: false,
3986
4033
  query: "",
@@ -4038,8 +4085,8 @@ var SlashMenuExtension = import_core14.Extension.create({
4038
4085
  name: "slashMenu",
4039
4086
  addProseMirrorPlugins() {
4040
4087
  return [
4041
- new import_state6.Plugin({
4042
- key: new import_state6.PluginKey("slashMenu"),
4088
+ new import_state7.Plugin({
4089
+ key: new import_state7.PluginKey("slashMenu"),
4043
4090
  props: {
4044
4091
  handleTextInput(view, from, _to, text) {
4045
4092
  if (text === "/") {
@@ -4125,7 +4172,7 @@ var SlashMenuExtension = import_core14.Extension.create({
4125
4172
  ];
4126
4173
  }
4127
4174
  });
4128
- var slashMenuPlugin = (0, import_docflow_core22.definePlugin)({
4175
+ var slashMenuPlugin = (0, import_docflow_core23.definePlugin)({
4129
4176
  id: "slash-menu",
4130
4177
  tiptapExtensions: [SlashMenuExtension],
4131
4178
  hooks: {
@@ -4153,6 +4200,7 @@ var defaultPlugins = [
4153
4200
  footnotePlugin,
4154
4201
  tocPlugin,
4155
4202
  fontSizePlugin,
4203
+ fontFamilyPlugin,
4156
4204
  textColorPlugin,
4157
4205
  highlightPlugin,
4158
4206
  citationPlugin,
@@ -4175,6 +4223,7 @@ var defaultPlugins = [
4175
4223
  DateChipNode,
4176
4224
  DropdownChipNode,
4177
4225
  FileChipNode,
4226
+ FontFamilyExtension,
4178
4227
  FontSizeExtension,
4179
4228
  FootnoteNode,
4180
4229
  LocationChipNode,
@@ -4203,6 +4252,7 @@ var defaultPlugins = [
4203
4252
  commentPlugin,
4204
4253
  createPlaceholderPlugin,
4205
4254
  defaultPlugins,
4255
+ fontFamilyPlugin,
4206
4256
  fontSizePlugin,
4207
4257
  footnotePlugin,
4208
4258
  formattingPlugin,
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as _kedata_indonesia_docflow_core from '@kedataindo/docflow-core';
2
2
  import { AIAction, DocsEditorPlugin, DocumentMode } from '@kedataindo/docflow-core';
3
- export { DocsEditorPlugin, FontSizeExtension, SlashCommand, ToolbarItem } from '@kedataindo/docflow-core';
3
+ export { DocsEditorPlugin, FontFamilyExtension, FontSizeExtension, SlashCommand, ToolbarItem } from '@kedataindo/docflow-core';
4
4
  import { Node, Editor, Extension, Mark } from '@tiptap/core';
5
5
  import { CiteEngine } from './citations.cjs';
6
6
  export { CSL_LOCALE_EN_US, CSL_STYLES, CitationAttrs, CitationCluster, CitationMode, CiteEngineOptions, CslStyleInfo, DEFAULT_CSL_STYLE, buildCitationNodes, nextCitationId, sanitizeCiteprocHtml } from './citations.cjs';
@@ -96,6 +96,16 @@ declare const tocPlugin: _kedata_indonesia_docflow_core.DocsEditorPlugin;
96
96
  */
97
97
  declare const fontSizePlugin: _kedata_indonesia_docflow_core.DocsEditorPlugin;
98
98
 
99
+ /**
100
+ * fontFamilyPlugin — provides the `setFontFamily` command action for toolbar
101
+ * use, backed by FontFamilyExtension (a `fontFamily` attribute on the TextStyle
102
+ * mark). Registered through the plugin system so the extension is added once.
103
+ *
104
+ * The toolbar passes a full CSS font stack (e.g. `Georgia, serif`) so the
105
+ * applied family is explicit and survives round-trips.
106
+ */
107
+ declare const fontFamilyPlugin: _kedata_indonesia_docflow_core.DocsEditorPlugin;
108
+
99
109
  declare const textColorPlugin: _kedata_indonesia_docflow_core.DocsEditorPlugin;
100
110
 
101
111
  declare const highlightPlugin: _kedata_indonesia_docflow_core.DocsEditorPlugin;
@@ -380,4 +390,4 @@ declare const slashMenuPlugin: _kedata_indonesia_docflow_core.DocsEditorPlugin;
380
390
 
381
391
  declare const defaultPlugins: _kedata_indonesia_docflow_core.DocsEditorPlugin[];
382
392
 
383
- export { AIExtension, type AIPreviewState, BibliographyNode, CitationEngineExtension, CitationNode, CiteEngine, type CommentMarkAttrs, CommentMark as CommentMarkExtension, DateChipNode, DropdownChipNode, FileChipNode, FootnoteNode, LocationChipNode, PageBreak, PeopleChipNode, type PlaceholderPluginOptions, SUGGESTION_DELETE, SUGGESTION_FORMAT, SUGGESTION_INSERT, SlashMenuExtension, type SuggestionAuthor, SuggestionDeleteMark, SuggestionFormatMark, SuggestionInsertMark, type SuggestionSummary, TocEntryNode, TocNode, TocPageNumNode, acceptAllSuggestions, acceptSuggestion, aiPlugin, aiPluginKey, alignmentPlugin, blockquotePlugin, citationPlugin, codeBlockPlugin, collectHeadings, commentPlugin, createPlaceholderPlugin, defaultPlugins, fontSizePlugin, footnotePlugin, formattingPlugin, getAIPreview, getCitationEngine, getSuggestions, headingsPlugin, highlightPlugin, imagePlugin, insertMarkdownBlock, linkPlugin, listsPlugin, markdownToFragment, onSlashStateChange, pageBreakPlugin, placeholderPlugin, regenerateToc, registerSlashCommands, rejectAllSuggestions, rejectSuggestion, scrollEditorToPos, setDocumentMode, setSuggestionAuthor, slashMenuPlugin, slashState, smartElementsPlugin, suggestChangesPlugin, tablePageSplitPlugin, tablePlugin, textColorPlugin, tocPlugin };
393
+ export { AIExtension, type AIPreviewState, BibliographyNode, CitationEngineExtension, CitationNode, CiteEngine, type CommentMarkAttrs, CommentMark as CommentMarkExtension, DateChipNode, DropdownChipNode, FileChipNode, FootnoteNode, LocationChipNode, PageBreak, PeopleChipNode, type PlaceholderPluginOptions, SUGGESTION_DELETE, SUGGESTION_FORMAT, SUGGESTION_INSERT, SlashMenuExtension, type SuggestionAuthor, SuggestionDeleteMark, SuggestionFormatMark, SuggestionInsertMark, type SuggestionSummary, TocEntryNode, TocNode, TocPageNumNode, acceptAllSuggestions, acceptSuggestion, aiPlugin, aiPluginKey, alignmentPlugin, blockquotePlugin, citationPlugin, codeBlockPlugin, collectHeadings, commentPlugin, createPlaceholderPlugin, defaultPlugins, fontFamilyPlugin, fontSizePlugin, footnotePlugin, formattingPlugin, getAIPreview, getCitationEngine, getSuggestions, headingsPlugin, highlightPlugin, imagePlugin, insertMarkdownBlock, linkPlugin, listsPlugin, markdownToFragment, onSlashStateChange, pageBreakPlugin, placeholderPlugin, regenerateToc, registerSlashCommands, rejectAllSuggestions, rejectSuggestion, scrollEditorToPos, setDocumentMode, setSuggestionAuthor, slashMenuPlugin, slashState, smartElementsPlugin, suggestChangesPlugin, tablePageSplitPlugin, tablePlugin, textColorPlugin, tocPlugin };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as _kedata_indonesia_docflow_core from '@kedataindo/docflow-core';
2
2
  import { AIAction, DocsEditorPlugin, DocumentMode } from '@kedataindo/docflow-core';
3
- export { DocsEditorPlugin, FontSizeExtension, SlashCommand, ToolbarItem } from '@kedataindo/docflow-core';
3
+ export { DocsEditorPlugin, FontFamilyExtension, FontSizeExtension, SlashCommand, ToolbarItem } from '@kedataindo/docflow-core';
4
4
  import { Node, Editor, Extension, Mark } from '@tiptap/core';
5
5
  import { CiteEngine } from './citations.js';
6
6
  export { CSL_LOCALE_EN_US, CSL_STYLES, CitationAttrs, CitationCluster, CitationMode, CiteEngineOptions, CslStyleInfo, DEFAULT_CSL_STYLE, buildCitationNodes, nextCitationId, sanitizeCiteprocHtml } from './citations.js';
@@ -96,6 +96,16 @@ declare const tocPlugin: _kedata_indonesia_docflow_core.DocsEditorPlugin;
96
96
  */
97
97
  declare const fontSizePlugin: _kedata_indonesia_docflow_core.DocsEditorPlugin;
98
98
 
99
+ /**
100
+ * fontFamilyPlugin — provides the `setFontFamily` command action for toolbar
101
+ * use, backed by FontFamilyExtension (a `fontFamily` attribute on the TextStyle
102
+ * mark). Registered through the plugin system so the extension is added once.
103
+ *
104
+ * The toolbar passes a full CSS font stack (e.g. `Georgia, serif`) so the
105
+ * applied family is explicit and survives round-trips.
106
+ */
107
+ declare const fontFamilyPlugin: _kedata_indonesia_docflow_core.DocsEditorPlugin;
108
+
99
109
  declare const textColorPlugin: _kedata_indonesia_docflow_core.DocsEditorPlugin;
100
110
 
101
111
  declare const highlightPlugin: _kedata_indonesia_docflow_core.DocsEditorPlugin;
@@ -380,4 +390,4 @@ declare const slashMenuPlugin: _kedata_indonesia_docflow_core.DocsEditorPlugin;
380
390
 
381
391
  declare const defaultPlugins: _kedata_indonesia_docflow_core.DocsEditorPlugin[];
382
392
 
383
- export { AIExtension, type AIPreviewState, BibliographyNode, CitationEngineExtension, CitationNode, CiteEngine, type CommentMarkAttrs, CommentMark as CommentMarkExtension, DateChipNode, DropdownChipNode, FileChipNode, FootnoteNode, LocationChipNode, PageBreak, PeopleChipNode, type PlaceholderPluginOptions, SUGGESTION_DELETE, SUGGESTION_FORMAT, SUGGESTION_INSERT, SlashMenuExtension, type SuggestionAuthor, SuggestionDeleteMark, SuggestionFormatMark, SuggestionInsertMark, type SuggestionSummary, TocEntryNode, TocNode, TocPageNumNode, acceptAllSuggestions, acceptSuggestion, aiPlugin, aiPluginKey, alignmentPlugin, blockquotePlugin, citationPlugin, codeBlockPlugin, collectHeadings, commentPlugin, createPlaceholderPlugin, defaultPlugins, fontSizePlugin, footnotePlugin, formattingPlugin, getAIPreview, getCitationEngine, getSuggestions, headingsPlugin, highlightPlugin, imagePlugin, insertMarkdownBlock, linkPlugin, listsPlugin, markdownToFragment, onSlashStateChange, pageBreakPlugin, placeholderPlugin, regenerateToc, registerSlashCommands, rejectAllSuggestions, rejectSuggestion, scrollEditorToPos, setDocumentMode, setSuggestionAuthor, slashMenuPlugin, slashState, smartElementsPlugin, suggestChangesPlugin, tablePageSplitPlugin, tablePlugin, textColorPlugin, tocPlugin };
393
+ export { AIExtension, type AIPreviewState, BibliographyNode, CitationEngineExtension, CitationNode, CiteEngine, type CommentMarkAttrs, CommentMark as CommentMarkExtension, DateChipNode, DropdownChipNode, FileChipNode, FootnoteNode, LocationChipNode, PageBreak, PeopleChipNode, type PlaceholderPluginOptions, SUGGESTION_DELETE, SUGGESTION_FORMAT, SUGGESTION_INSERT, SlashMenuExtension, type SuggestionAuthor, SuggestionDeleteMark, SuggestionFormatMark, SuggestionInsertMark, type SuggestionSummary, TocEntryNode, TocNode, TocPageNumNode, acceptAllSuggestions, acceptSuggestion, aiPlugin, aiPluginKey, alignmentPlugin, blockquotePlugin, citationPlugin, codeBlockPlugin, collectHeadings, commentPlugin, createPlaceholderPlugin, defaultPlugins, fontFamilyPlugin, fontSizePlugin, footnotePlugin, formattingPlugin, getAIPreview, getCitationEngine, getSuggestions, headingsPlugin, highlightPlugin, imagePlugin, insertMarkdownBlock, linkPlugin, listsPlugin, markdownToFragment, onSlashStateChange, pageBreakPlugin, placeholderPlugin, regenerateToc, registerSlashCommands, rejectAllSuggestions, rejectSuggestion, scrollEditorToPos, setDocumentMode, setSuggestionAuthor, slashMenuPlugin, slashState, smartElementsPlugin, suggestChangesPlugin, tablePageSplitPlugin, tablePlugin, textColorPlugin, tocPlugin };
package/dist/index.js CHANGED
@@ -181,6 +181,7 @@ import Table from "@tiptap/extension-table";
181
181
  import TableRow from "@tiptap/extension-table-row";
182
182
  import TableCell from "@tiptap/extension-table-cell";
183
183
  import TableHeader from "@tiptap/extension-table-header";
184
+ import { Plugin, TextSelection } from "@tiptap/pm/state";
184
185
  var CustomTable = Table.extend({
185
186
  addAttributes() {
186
187
  return {
@@ -250,6 +251,31 @@ var CustomTable = Table.extend({
250
251
  ["colgroup", ...cols],
251
252
  ["tbody", 0]
252
253
  ];
254
+ },
255
+ // #139: double-clicking an EMPTY cell resolved the caret to a neighbouring
256
+ // cell — ProseMirror's default dblclick word-selection has no text to land on
257
+ // in a cell whose only content is a trailing <br>. When the resolved position
258
+ // is not inside the cell under the pointer, place the caret at that cell's
259
+ // start instead. Non-empty cells keep the default (select the word).
260
+ addProseMirrorPlugins() {
261
+ const parent = this.parent?.() ?? [];
262
+ return [
263
+ ...parent,
264
+ new Plugin({
265
+ props: {
266
+ handleDoubleClick(view, pos, event) {
267
+ const cell = event.target?.closest?.("td, th") ?? null;
268
+ if (!cell) return false;
269
+ if ((cell.textContent ?? "").trim() !== "") return false;
270
+ void pos;
271
+ const cellPos = view.posAtDOM(cell, 0);
272
+ const selection = TextSelection.near(view.state.doc.resolve(cellPos), 1);
273
+ view.dispatch(view.state.tr.setSelection(selection));
274
+ return true;
275
+ }
276
+ }
277
+ })
278
+ ];
253
279
  }
254
280
  });
255
281
  var CustomTableCell = TableCell.extend({
@@ -534,13 +560,13 @@ import { Extension, Node as Node4, mergeAttributes as mergeAttributes4 } from "@
534
560
  import { definePlugin as definePlugin13 } from "@kedataindo/docflow-core";
535
561
 
536
562
  // src/editorScroll.ts
537
- import { TextSelection } from "@tiptap/pm/state";
563
+ import { TextSelection as TextSelection2 } from "@tiptap/pm/state";
538
564
  function scrollEditorToPos(editor, pos, options = {}) {
539
565
  const { state, view } = editor;
540
566
  const clamped = Math.min(Math.max(0, pos), state.doc.content.size);
541
567
  let anchor = clamped;
542
568
  if (options.focus !== false) {
543
- const selection = TextSelection.near(state.doc.resolve(clamped), 1);
569
+ const selection = TextSelection2.near(state.doc.resolve(clamped), 1);
544
570
  if (!state.selection.eq(selection)) {
545
571
  view.dispatch(state.tr.setSelection(selection));
546
572
  }
@@ -825,10 +851,29 @@ var fontSizePlugin = definePlugin14({
825
851
  }
826
852
  });
827
853
 
854
+ // src/fontFamily.ts
855
+ import { definePlugin as definePlugin15, FontFamilyExtension } from "@kedataindo/docflow-core";
856
+ var fontFamilyPlugin = definePlugin15({
857
+ id: "font-family",
858
+ tiptapExtensions: [FontFamilyExtension],
859
+ commands: {
860
+ setFontFamily: (editor, ...args) => {
861
+ const family = args[0] || "";
862
+ if (family) {
863
+ editor.commands.setFontFamily(family);
864
+ } else {
865
+ editor.commands.unsetFontFamily();
866
+ }
867
+ editor.commands.focus();
868
+ return true;
869
+ }
870
+ }
871
+ });
872
+
828
873
  // src/textColor.ts
829
- import { definePlugin as definePlugin15 } from "@kedataindo/docflow-core";
874
+ import { definePlugin as definePlugin16 } from "@kedataindo/docflow-core";
830
875
  import Color from "@tiptap/extension-color";
831
- var textColorPlugin = definePlugin15({
876
+ var textColorPlugin = definePlugin16({
832
877
  id: "text-color",
833
878
  tiptapExtensions: [Color],
834
879
  toolbar: [
@@ -847,7 +892,7 @@ var textColorPlugin = definePlugin15({
847
892
  });
848
893
 
849
894
  // src/highlight.ts
850
- import { definePlugin as definePlugin16 } from "@kedataindo/docflow-core";
895
+ import { definePlugin as definePlugin17 } from "@kedataindo/docflow-core";
851
896
  import Highlight from "@tiptap/extension-highlight";
852
897
  import { mergeAttributes as mergeAttributes5 } from "@tiptap/core";
853
898
  var GoogleDocsHighlight = Highlight.extend({
@@ -877,7 +922,7 @@ var GoogleDocsHighlight = Highlight.extend({
877
922
  return ["mark", mergeAttributes5(this.options.HTMLAttributes, HTMLAttributes), 0];
878
923
  }
879
924
  });
880
- var highlightPlugin = definePlugin16({
925
+ var highlightPlugin = definePlugin17({
881
926
  id: "highlight",
882
927
  tiptapExtensions: [
883
928
  GoogleDocsHighlight.configure({
@@ -903,7 +948,7 @@ var highlightPlugin = definePlugin16({
903
948
 
904
949
  // src/citation.ts
905
950
  import { Extension as Extension2, Node as Node6, mergeAttributes as mergeAttributes7 } from "@tiptap/core";
906
- import { definePlugin as definePlugin17 } from "@kedataindo/docflow-core";
951
+ import { definePlugin as definePlugin18 } from "@kedataindo/docflow-core";
907
952
 
908
953
  // src/citeEngine.ts
909
954
  import CSL from "citeproc";
@@ -2264,7 +2309,7 @@ function insertCitationWithSource(editor, engine, attrs) {
2264
2309
  if (spec.type === "footnote" && !editor.schema.nodes["footnote"]) return false;
2265
2310
  return editor.chain().focus().insertContent({ type: spec.type, attrs: spec.attrs }).run();
2266
2311
  }
2267
- var citationPlugin = definePlugin17({
2312
+ var citationPlugin = definePlugin18({
2268
2313
  id: "citation",
2269
2314
  tiptapExtensions: [CitationEngineExtension, CitationNode, BibliographyNode],
2270
2315
  toolbar: [{ id: "insert-citation", label: "Citation", action: "insertCitation", iconComponent: "Quote" }],
@@ -2334,10 +2379,10 @@ var citationPlugin = definePlugin17({
2334
2379
 
2335
2380
  // src/ai.ts
2336
2381
  import { Extension as Extension3 } from "@tiptap/core";
2337
- import { Plugin, PluginKey } from "@tiptap/pm/state";
2382
+ import { Plugin as Plugin2, PluginKey } from "@tiptap/pm/state";
2338
2383
  import { Decoration, DecorationSet } from "@tiptap/pm/view";
2339
2384
  import { Markdown } from "tiptap-markdown";
2340
- import { definePlugin as definePlugin18 } from "@kedataindo/docflow-core";
2385
+ import { definePlugin as definePlugin19 } from "@kedataindo/docflow-core";
2341
2386
 
2342
2387
  // src/markdownInsert.ts
2343
2388
  import { createNodeFromContent } from "@tiptap/core";
@@ -2657,7 +2702,7 @@ var AIExtension = Extension3.create({
2657
2702
  };
2658
2703
  }
2659
2704
  return [
2660
- new Plugin({
2705
+ new Plugin2({
2661
2706
  key: aiPluginKey,
2662
2707
  state: {
2663
2708
  init: () => null,
@@ -2773,7 +2818,7 @@ var AIExtension = Extension3.create({
2773
2818
  storage.preview = null;
2774
2819
  }
2775
2820
  });
2776
- var aiPlugin = definePlugin18({
2821
+ var aiPlugin = definePlugin19({
2777
2822
  id: "ai",
2778
2823
  // The `tiptap-markdown` `Markdown` extension is registered alongside AI so
2779
2824
  // that `editor.storage.markdown.parser` is available on every editor that
@@ -2829,9 +2874,9 @@ var commentPlugin = {
2829
2874
 
2830
2875
  // src/suggestChanges.ts
2831
2876
  import { Extension as Extension4, Mark as Mark2, mergeAttributes as mergeAttributes8 } from "@tiptap/core";
2832
- import { Plugin as Plugin2, PluginKey as PluginKey2, TextSelection as TextSelection2 } from "@tiptap/pm/state";
2877
+ import { Plugin as Plugin3, PluginKey as PluginKey2, TextSelection as TextSelection3 } from "@tiptap/pm/state";
2833
2878
  import { AddMarkStep, RemoveMarkStep } from "@tiptap/pm/transform";
2834
- import { definePlugin as definePlugin19 } from "@kedataindo/docflow-core";
2879
+ import { definePlugin as definePlugin20 } from "@kedataindo/docflow-core";
2835
2880
  var SUGGESTION_INSERT = "suggestionInsert";
2836
2881
  var SUGGESTION_DELETE = "suggestionDelete";
2837
2882
  var SUGGESTION_FORMAT = "suggestionFormat";
@@ -2959,7 +3004,7 @@ var SuggestChanges = Extension4.create({
2959
3004
  if (storage) storage.suggestions = getSuggestions(editor);
2960
3005
  };
2961
3006
  return [
2962
- new Plugin2({
3007
+ new Plugin3({
2963
3008
  key: suggestChangesKey,
2964
3009
  state: {
2965
3010
  init: () => ({ mode: "editing", author: {} }),
@@ -3047,7 +3092,7 @@ var SuggestChanges = Extension4.create({
3047
3092
  const id = adjacentRunId(view.state, from, SUGGESTION_DELETE) ?? newSuggestionId();
3048
3093
  const tr = view.state.tr.addMark(from, to, del.create(markAttrs(id, current.author)));
3049
3094
  if (event.key === "Backspace" && selection.empty) {
3050
- tr.setSelection(TextSelection2.create(tr.doc, from));
3095
+ tr.setSelection(TextSelection3.create(tr.doc, from));
3051
3096
  }
3052
3097
  view.dispatch(tr);
3053
3098
  return true;
@@ -3199,7 +3244,7 @@ var acceptSuggestion = (editor, id) => resolveSuggestions(editor, true, id);
3199
3244
  var rejectSuggestion = (editor, id) => resolveSuggestions(editor, false, id);
3200
3245
  var acceptAllSuggestions = (editor) => resolveSuggestions(editor, true);
3201
3246
  var rejectAllSuggestions = (editor) => resolveSuggestions(editor, false);
3202
- var suggestChangesPlugin = definePlugin19({
3247
+ var suggestChangesPlugin = definePlugin20({
3203
3248
  id: "suggestChanges",
3204
3249
  tiptapExtensions: [SuggestionInsertMark, SuggestionDeleteMark, SuggestionFormatMark, SuggestChanges],
3205
3250
  commands: {
@@ -3214,7 +3259,7 @@ var suggestChangesPlugin = definePlugin19({
3214
3259
 
3215
3260
  // src/smartElements.ts
3216
3261
  import { Node as Node7, mergeAttributes as mergeAttributes9 } from "@tiptap/core";
3217
- import { definePlugin as definePlugin20 } from "@kedataindo/docflow-core";
3262
+ import { definePlugin as definePlugin21 } from "@kedataindo/docflow-core";
3218
3263
  function todayISO() {
3219
3264
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
3220
3265
  }
@@ -3584,7 +3629,7 @@ var LocationChipNode = Node7.create({
3584
3629
  };
3585
3630
  }
3586
3631
  });
3587
- var smartElementsPlugin = definePlugin20({
3632
+ var smartElementsPlugin = definePlugin21({
3588
3633
  id: "smart-elements",
3589
3634
  tiptapExtensions: [
3590
3635
  DateChipNode,
@@ -3643,9 +3688,9 @@ var smartElementsPlugin = definePlugin20({
3643
3688
  });
3644
3689
 
3645
3690
  // src/tablePageSplit.ts
3646
- import { definePlugin as definePlugin21 } from "@kedataindo/docflow-core";
3691
+ import { definePlugin as definePlugin22 } from "@kedataindo/docflow-core";
3647
3692
  import { Extension as Extension5 } from "@tiptap/core";
3648
- import { Plugin as Plugin3, PluginKey as PluginKey3 } from "@tiptap/pm/state";
3693
+ import { Plugin as Plugin4, PluginKey as PluginKey3 } from "@tiptap/pm/state";
3649
3694
  var PLUGIN_KEY = new PluginKey3("docflow/table-page-split");
3650
3695
  var SPLIT_MARK = "head";
3651
3696
  var MAX_SPLIT_DEPTH = 16;
@@ -3832,7 +3877,7 @@ var TablePageSplitExtension = Extension5.create({
3832
3877
  const ext = this;
3833
3878
  const editorRef = ext.editor ?? null;
3834
3879
  return [
3835
- new Plugin3({
3880
+ new Plugin4({
3836
3881
  key: PLUGIN_KEY,
3837
3882
  view(_editorView) {
3838
3883
  viewRef = _editorView;
@@ -3864,15 +3909,15 @@ var TablePageSplitExtension = Extension5.create({
3864
3909
  ];
3865
3910
  }
3866
3911
  });
3867
- var tablePageSplitPlugin = definePlugin21({
3912
+ var tablePageSplitPlugin = definePlugin22({
3868
3913
  id: "tablePageSplit",
3869
3914
  tiptapExtensions: [TablePageSplitExtension]
3870
3915
  });
3871
3916
 
3872
3917
  // src/slashMenu.ts
3873
3918
  import { Extension as Extension6 } from "@tiptap/core";
3874
- import { Plugin as Plugin4, PluginKey as PluginKey4 } from "@tiptap/pm/state";
3875
- import { definePlugin as definePlugin22 } from "@kedataindo/docflow-core";
3919
+ import { Plugin as Plugin5, PluginKey as PluginKey4 } from "@tiptap/pm/state";
3920
+ import { definePlugin as definePlugin23 } from "@kedataindo/docflow-core";
3876
3921
  var slashState = {
3877
3922
  open: false,
3878
3923
  query: "",
@@ -3930,7 +3975,7 @@ var SlashMenuExtension = Extension6.create({
3930
3975
  name: "slashMenu",
3931
3976
  addProseMirrorPlugins() {
3932
3977
  return [
3933
- new Plugin4({
3978
+ new Plugin5({
3934
3979
  key: new PluginKey4("slashMenu"),
3935
3980
  props: {
3936
3981
  handleTextInput(view, from, _to, text) {
@@ -4017,7 +4062,7 @@ var SlashMenuExtension = Extension6.create({
4017
4062
  ];
4018
4063
  }
4019
4064
  });
4020
- var slashMenuPlugin = definePlugin22({
4065
+ var slashMenuPlugin = definePlugin23({
4021
4066
  id: "slash-menu",
4022
4067
  tiptapExtensions: [SlashMenuExtension],
4023
4068
  hooks: {
@@ -4045,6 +4090,7 @@ var defaultPlugins = [
4045
4090
  footnotePlugin,
4046
4091
  tocPlugin,
4047
4092
  fontSizePlugin,
4093
+ fontFamilyPlugin,
4048
4094
  textColorPlugin,
4049
4095
  highlightPlugin,
4050
4096
  citationPlugin,
@@ -4066,6 +4112,7 @@ export {
4066
4112
  DateChipNode,
4067
4113
  DropdownChipNode,
4068
4114
  FileChipNode,
4115
+ FontFamilyExtension,
4069
4116
  FontSizeExtension,
4070
4117
  FootnoteNode,
4071
4118
  LocationChipNode,
@@ -4094,6 +4141,7 @@ export {
4094
4141
  commentPlugin,
4095
4142
  createPlaceholderPlugin,
4096
4143
  defaultPlugins,
4144
+ fontFamilyPlugin,
4097
4145
  fontSizePlugin,
4098
4146
  footnotePlugin,
4099
4147
  formattingPlugin,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kedataindo/docflow-plugins",
3
3
  "license": "Apache-2.0",
4
- "version": "0.0.91",
4
+ "version": "0.0.93",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",
@@ -31,7 +31,7 @@
31
31
  "@tiptap/pm": "^2.11.0",
32
32
  "citeproc": "^2.4.63",
33
33
  "tiptap-markdown": "0.8.10",
34
- "@kedataindo/docflow-core": "0.0.86"
34
+ "@kedataindo/docflow-core": "0.0.88"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "@tiptap/core": "^2.11.0",