@sendbird/actionbook-core 0.10.3 → 0.10.5

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/ui/index.js CHANGED
@@ -2840,10 +2840,22 @@ function handleListInputRule(state, start, end, listType, attrs) {
2840
2840
  const { depth: listDepth, node: listNode } = parentList;
2841
2841
  const paraContentSize = $from.parent.content.size;
2842
2842
  const matchedLen = end - start;
2843
- if (paraContentSize !== matchedLen) return null;
2843
+ const isMarkerOnly = paraContentSize === matchedLen;
2844
2844
  if (listNode.type === listType) {
2845
+ if (isMarkerOnly && listType === actionbookSchema.nodes.orderedList && attrs?.start != null) {
2846
+ const newStart = attrs.start;
2847
+ const currentStart = listNode.attrs.start ?? 1;
2848
+ if (newStart !== currentStart) {
2849
+ const listStart = $from.before(listDepth);
2850
+ const tr2 = state.tr.delete(start, end);
2851
+ tr2.setNodeMarkup(tr2.mapping.map(listStart), void 0, { ...listNode.attrs, start: newStart });
2852
+ tr2.setSelection(TextSelection.near(tr2.doc.resolve(tr2.mapping.map(start))));
2853
+ return tr2;
2854
+ }
2855
+ }
2845
2856
  return NOOP;
2846
2857
  }
2858
+ if (!isMarkerOnly) return NOOP;
2847
2859
  const { listItem: liType } = actionbookSchema.nodes;
2848
2860
  const tr = state.tr.delete(start, end);
2849
2861
  const $pos = tr.doc.resolve(tr.mapping.map(resolvePos));
@@ -3008,7 +3020,7 @@ function createHistoryPlugin() {
3008
3020
 
3009
3021
  // src/ui/plugin/keymapPlugin.ts
3010
3022
  import { baseKeymap, chainCommands, newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock, toggleMark, setBlockType, joinBackward } from "prosemirror-commands";
3011
- import { TextSelection as TextSelection2 } from "prosemirror-state";
3023
+ import { Plugin as Plugin2, TextSelection as TextSelection2 } from "prosemirror-state";
3012
3024
  import { keymap as keymap3 } from "prosemirror-keymap";
3013
3025
  import { liftListItem, sinkListItem, splitListItem, wrapInList } from "prosemirror-schema-list";
3014
3026
 
@@ -3104,6 +3116,10 @@ function createNoteBlockPlugin() {
3104
3116
  // src/ui/plugin/keymapPlugin.ts
3105
3117
  var TAB_CHAR = " ";
3106
3118
  var { listItem, bulletList, orderedList, hardBreak, heading, paragraph, horizontalRule, blockquote } = actionbookSchema.nodes;
3119
+ function isEffectivelyEmpty(node) {
3120
+ if (node.content.size === 0) return true;
3121
+ return node.textContent.trim().length === 0 && !node.firstChild?.isAtom;
3122
+ }
3107
3123
  var { bold: boldMark, italic: italicMark, underline: underlineMark, strikethrough: strikethroughMark, code: codeMark } = actionbookSchema.marks;
3108
3124
  function cursorDirectlyInListItem(state) {
3109
3125
  const { $from } = state.selection;
@@ -3112,9 +3128,8 @@ function cursorDirectlyInListItem(state) {
3112
3128
  var backspaceAfterList = (state, dispatch) => {
3113
3129
  const { $from } = state.selection;
3114
3130
  if (!state.selection.empty) return false;
3115
- if ($from.parentOffset !== 0) return false;
3116
3131
  if ($from.parent.type !== paragraph) return false;
3117
- if ($from.parent.content.size !== 0) return false;
3132
+ if (!isEffectivelyEmpty($from.parent)) return false;
3118
3133
  const parentDepth = $from.depth - 1;
3119
3134
  if (parentDepth < 0) return false;
3120
3135
  const indexInParent = $from.index(parentDepth);
@@ -3133,9 +3148,8 @@ var backspaceAfterList = (state, dispatch) => {
3133
3148
  var backspaceAfterLeafBlock = (state, dispatch) => {
3134
3149
  const { $from } = state.selection;
3135
3150
  if (!state.selection.empty) return false;
3136
- if ($from.parentOffset !== 0) return false;
3137
3151
  if ($from.parent.type !== paragraph) return false;
3138
- if ($from.parent.content.size !== 0) return false;
3152
+ if (!isEffectivelyEmpty($from.parent)) return false;
3139
3153
  const parentDepth = $from.depth - 1;
3140
3154
  if (parentDepth < 0) return false;
3141
3155
  const indexInParent = $from.index(parentDepth);
@@ -3150,8 +3164,8 @@ var backspaceAfterLeafBlock = (state, dispatch) => {
3150
3164
  };
3151
3165
  var backspaceDeleteEmptyBlock = (state, dispatch) => {
3152
3166
  const { $from } = state.selection;
3153
- if (!state.selection.empty || $from.parentOffset !== 0) return false;
3154
- if ($from.parent.type !== paragraph || $from.parent.content.size !== 0) return false;
3167
+ if (!state.selection.empty) return false;
3168
+ if ($from.parent.type !== paragraph || !isEffectivelyEmpty($from.parent)) return false;
3155
3169
  const deletableTypes = /* @__PURE__ */ new Set(["jinjaIfBlock", "jinjaIfBranch", "noteBlock", "blockquote"]);
3156
3170
  for (let d = $from.depth - 1; d > 0; d--) {
3157
3171
  const ancestor = $from.node(d);
@@ -3391,6 +3405,18 @@ var shiftEnterCommand = (state, dispatch) => {
3391
3405
  }
3392
3406
  return true;
3393
3407
  };
3408
+ function createEmptyDocGuardPlugin() {
3409
+ return new Plugin2({
3410
+ appendTransaction(_, __, newState) {
3411
+ const { doc: doc2 } = newState;
3412
+ if (doc2.childCount !== 1) return null;
3413
+ const only = doc2.child(0);
3414
+ if (only.type === paragraph) return null;
3415
+ if (only.content.size !== 0) return null;
3416
+ return newState.tr.setNodeMarkup(0, paragraph);
3417
+ }
3418
+ });
3419
+ }
3394
3420
  function createKeymapPlugin() {
3395
3421
  return {
3396
3422
  name: "keymapPlugin",
@@ -3408,13 +3434,13 @@ function createKeymapPlugin() {
3408
3434
  "Mod-Shift-7": wrapInList(bulletList),
3409
3435
  "Mod-Shift-8": wrapInList(orderedList)
3410
3436
  }),
3411
- plugins: () => [keymap3(baseKeymap)]
3437
+ plugins: () => [keymap3(baseKeymap), createEmptyDocGuardPlugin()]
3412
3438
  };
3413
3439
  }
3414
3440
 
3415
3441
  // src/ui/plugin/markdownClipboard.ts
3416
3442
  import { DOMParser as ProseMirrorDOMParser, Fragment, Slice } from "prosemirror-model";
3417
- import { Plugin as Plugin2, PluginKey as PluginKey2 } from "prosemirror-state";
3443
+ import { Plugin as Plugin3, PluginKey as PluginKey2 } from "prosemirror-state";
3418
3444
 
3419
3445
  // src/ast/traverse.ts
3420
3446
  var MAX_DEPTH3 = 128;
@@ -5691,7 +5717,7 @@ function textToSlice(text2, view) {
5691
5717
  }
5692
5718
  var URL_RE = /^https?:\/\/[^\s]+$/i;
5693
5719
  function createPlugin() {
5694
- return new Plugin2({
5720
+ return new Plugin3({
5695
5721
  key,
5696
5722
  props: {
5697
5723
  handlePaste(view, event) {
@@ -5757,7 +5783,7 @@ function createMarkdownClipboardPlugin() {
5757
5783
  }
5758
5784
 
5759
5785
  // src/ui/plugin/jumpPointPlugin.ts
5760
- import { Plugin as Plugin3, PluginKey as PluginKey3, TextSelection as TextSelection3 } from "prosemirror-state";
5786
+ import { Plugin as Plugin4, PluginKey as PluginKey3, TextSelection as TextSelection3 } from "prosemirror-state";
5761
5787
  import { Decoration, DecorationSet } from "prosemirror-view";
5762
5788
  var adjacentKey = new PluginKey3("jumpPointAdjacent");
5763
5789
  var JUMP_POINT_ADJACENT_SPEC = { jumpPointAdjacent: true };
@@ -5778,7 +5804,7 @@ function buildDecorations(state) {
5778
5804
  var jumpPointEditKey = new PluginKey3("jumpPointEdit");
5779
5805
  var JUMP_POINT_FULL_RE = /^\^([\p{L}\p{N}_-]+)\^$/u;
5780
5806
  function createJumpPointEditPlugin() {
5781
- return new Plugin3({
5807
+ return new Plugin4({
5782
5808
  key: jumpPointEditKey,
5783
5809
  state: {
5784
5810
  init: () => ({ rawRange: null }),
@@ -5880,7 +5906,7 @@ function createJumpPointAdjacentPlugin() {
5880
5906
  }),
5881
5907
  plugins: () => [
5882
5908
  createJumpPointEditPlugin(),
5883
- new Plugin3({
5909
+ new Plugin4({
5884
5910
  key: adjacentKey,
5885
5911
  state: {
5886
5912
  init(_, state) {
@@ -6046,7 +6072,7 @@ function createJumpPointNodeViewPlugin() {
6046
6072
  }
6047
6073
 
6048
6074
  // src/ui/plugin/jumpPointValidationPlugin.ts
6049
- import { Plugin as Plugin4, PluginKey as PluginKey4 } from "prosemirror-state";
6075
+ import { Plugin as Plugin5, PluginKey as PluginKey4 } from "prosemirror-state";
6050
6076
  import { Decoration as Decoration2, DecorationSet as DecorationSet2 } from "prosemirror-view";
6051
6077
  var pluginKey = new PluginKey4("jumpPointValidation");
6052
6078
  function collectJumpPointIds(state) {
@@ -6098,7 +6124,7 @@ function createJumpPointValidationPlugin() {
6098
6124
  return {
6099
6125
  name: "jumpPointValidation",
6100
6126
  plugins: () => [
6101
- new Plugin4({
6127
+ new Plugin5({
6102
6128
  key: pluginKey,
6103
6129
  state: {
6104
6130
  init(_, state) {
@@ -6136,9 +6162,14 @@ function buildDecorations2(state) {
6136
6162
  class: "broken-anchor-ref",
6137
6163
  "data-broken-ref": refId,
6138
6164
  title: `Anchor "${refId}" no longer exists`,
6139
- style: "color: #D9352C; text-decoration-color: #D9352C;"
6165
+ style: "color: #D9352C; font-weight: 500; text-decoration: none;"
6140
6166
  })
6141
6167
  );
6168
+ const icon = document.createElement("span");
6169
+ icon.textContent = " \u26A0";
6170
+ icon.style.cssText = "color: #D9352C; font-size: 14px; vertical-align: middle;";
6171
+ icon.setAttribute("aria-hidden", "true");
6172
+ decos.push(Decoration2.widget(to, icon, { side: 1 }));
6142
6173
  }
6143
6174
  if (decos.length === 0) return DecorationSet2.empty;
6144
6175
  return DecorationSet2.create(state.doc, decos);
@@ -6214,7 +6245,7 @@ function createInlineToolTagNodeViewPlugin() {
6214
6245
  }
6215
6246
 
6216
6247
  // src/ui/plugin/jinjaDecoration.ts
6217
- import { Plugin as Plugin5, PluginKey as PluginKey5 } from "prosemirror-state";
6248
+ import { Plugin as Plugin6, PluginKey as PluginKey5 } from "prosemirror-state";
6218
6249
  import { Decoration as Decoration3, DecorationSet as DecorationSet3 } from "prosemirror-view";
6219
6250
  var jinjaPluginKey = new PluginKey5("jinjaDecoration");
6220
6251
  var JINJA_TAG_RE = /\{%\s*(if|elif|else|endif)\s*([^%]*?)\s*%\}/g;
@@ -6307,7 +6338,7 @@ function createJinjaDecorationPlugin() {
6307
6338
  return {
6308
6339
  name: "jinjaDecoration",
6309
6340
  plugins: () => [
6310
- new Plugin5({
6341
+ new Plugin6({
6311
6342
  key: jinjaPluginKey,
6312
6343
  state: {
6313
6344
  init(_, state) {
@@ -6331,7 +6362,7 @@ function createJinjaDecorationPlugin() {
6331
6362
  // src/ui/plugin/jinjaIfBlockPlugin.tsx
6332
6363
  import { useEffect as useEffect2, useRef as useRef2, useState as useState3 } from "react";
6333
6364
  import { createRoot as createRoot2 } from "react-dom/client";
6334
- import { Plugin as Plugin6, TextSelection as TextSelection4 } from "prosemirror-state";
6365
+ import { Plugin as Plugin7, TextSelection as TextSelection4 } from "prosemirror-state";
6335
6366
  import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
6336
6367
  var PLACEHOLDER_TEXT = "Describe what AI agent should do when this condition is met";
6337
6368
  var CONDITION_PLACEHOLDER = "Write a condition in natural language";
@@ -7252,7 +7283,7 @@ var JinjaIfBranchView = class {
7252
7283
  };
7253
7284
  function createEditableWatcherPlugin() {
7254
7285
  let lastEditable = null;
7255
- return new Plugin6({
7286
+ return new Plugin7({
7256
7287
  view(editorView) {
7257
7288
  lastEditable = editorView.editable;
7258
7289
  return {
@@ -7283,7 +7314,7 @@ function createJinjaIfBlockPlugin() {
7283
7314
 
7284
7315
  // src/ui/plugin/linkPlugin.ts
7285
7316
  import { InputRule as InputRule2, inputRules as inputRules2 } from "prosemirror-inputrules";
7286
- import { Plugin as Plugin7, PluginKey as PluginKey6, TextSelection as TextSelection5 } from "prosemirror-state";
7317
+ import { Plugin as Plugin8, PluginKey as PluginKey6, TextSelection as TextSelection5 } from "prosemirror-state";
7287
7318
  var LINK_INPUT_RE = /\\?\[([^\]]*?)\\?\]\(([^)\s]*?)(?:\s+"([^"]*)")?\)$/;
7288
7319
  var LINK_FULL_RE = /^\\?\[([^\]]*?)\\?\]\(([^)\s]*?)(?:\s+"([^"]*)")?\)$/;
7289
7320
  var linkEditKey = new PluginKey6("linkEdit");
@@ -7334,7 +7365,7 @@ function explodeLinkToRaw(state) {
7334
7365
  return tr;
7335
7366
  }
7336
7367
  function createLinkEditPlugin() {
7337
- return new Plugin7({
7368
+ return new Plugin8({
7338
7369
  key: linkEditKey,
7339
7370
  state: {
7340
7371
  init: () => ({ rawRange: null }),
@@ -7409,7 +7440,7 @@ function createLinkInputRule() {
7409
7440
  );
7410
7441
  }
7411
7442
  function createLinkClickPlugin() {
7412
- return new Plugin7({
7443
+ return new Plugin8({
7413
7444
  key: new PluginKey6("linkClick"),
7414
7445
  props: {
7415
7446
  handleDOMEvents: {
@@ -7462,7 +7493,7 @@ function createLinkPlugin() {
7462
7493
  }
7463
7494
 
7464
7495
  // src/ui/plugin/dragHandlePlugin.ts
7465
- import { Plugin as Plugin8, PluginKey as PluginKey7 } from "prosemirror-state";
7496
+ import { Plugin as Plugin9, PluginKey as PluginKey7 } from "prosemirror-state";
7466
7497
  var PLUGIN_KEY = new PluginKey7("dragHandle");
7467
7498
  var GRIP_SVG = `<svg width="12" height="12" viewBox="0 0 12 12" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
7468
7499
  <circle cx="4" cy="2.5" r="1.2"/><circle cx="8" cy="2.5" r="1.2"/>
@@ -8270,7 +8301,7 @@ function createDragHandlePlugin() {
8270
8301
  plugins: () => {
8271
8302
  let controller = null;
8272
8303
  return [
8273
- new Plugin8({
8304
+ new Plugin9({
8274
8305
  key: PLUGIN_KEY,
8275
8306
  view(editorView) {
8276
8307
  controller = new DragHandleController(editorView);
@@ -8393,9 +8424,8 @@ function createTodoNodeViewPlugin() {
8393
8424
  }
8394
8425
 
8395
8426
  // src/ui/plugin/placeholderPlugin.ts
8396
- import { Plugin as Plugin9, PluginKey as PluginKey8 } from "prosemirror-state";
8427
+ import { Plugin as Plugin10, PluginKey as PluginKey8 } from "prosemirror-state";
8397
8428
  import { Decoration as Decoration4, DecorationSet as DecorationSet4 } from "prosemirror-view";
8398
- var PLACEHOLDER_TEXT2 = "Type to start writing, or press / to insert an action.";
8399
8429
  var pluginKey2 = new PluginKey8("placeholder");
8400
8430
  function buildDecorations4(state) {
8401
8431
  const { doc: doc2, selection } = state;
@@ -8413,17 +8443,25 @@ function buildDecorations4(state) {
8413
8443
  }
8414
8444
  const pos = $from.before($from.depth);
8415
8445
  const deco = Decoration4.node(pos, pos + parent.nodeSize, {
8416
- class: "ab-empty-paragraph",
8417
- "data-placeholder": PLACEHOLDER_TEXT2
8446
+ class: "ab-empty-paragraph"
8418
8447
  });
8419
8448
  return DecorationSet4.create(doc2, [deco]);
8420
8449
  }
8421
8450
  function createPlaceholderPlugin() {
8451
+ let isEditable = true;
8422
8452
  return {
8423
8453
  name: "placeholder",
8424
8454
  plugins: () => [
8425
- new Plugin9({
8455
+ new Plugin10({
8426
8456
  key: pluginKey2,
8457
+ view(editorView) {
8458
+ isEditable = editorView.editable;
8459
+ return {
8460
+ update(view) {
8461
+ isEditable = view.editable;
8462
+ }
8463
+ };
8464
+ },
8427
8465
  state: {
8428
8466
  init(_, state) {
8429
8467
  return buildDecorations4(state);
@@ -8437,6 +8475,7 @@ function createPlaceholderPlugin() {
8437
8475
  },
8438
8476
  props: {
8439
8477
  decorations(state) {
8478
+ if (!isEditable) return DecorationSet4.empty;
8440
8479
  return pluginKey2.getState(state) ?? DecorationSet4.empty;
8441
8480
  }
8442
8481
  }
@@ -10362,7 +10401,7 @@ function FloatingMenu({ view, editorState }) {
10362
10401
  }
10363
10402
 
10364
10403
  // src/ui/plugin/inlineSuggestPlugin.ts
10365
- import { Plugin as Plugin10, PluginKey as PluginKey9 } from "prosemirror-state";
10404
+ import { Plugin as Plugin11, PluginKey as PluginKey9 } from "prosemirror-state";
10366
10405
  import { Decoration as Decoration5, DecorationSet as DecorationSet5 } from "prosemirror-view";
10367
10406
  var inlineSuggestKey = new PluginKey9("inlineSuggest");
10368
10407
  var DEBOUNCE_MS = 600;
@@ -10371,7 +10410,7 @@ function createInlineSuggestPlugin(provider, endpoint, options) {
10371
10410
  return {
10372
10411
  name: "inlineSuggest",
10373
10412
  plugins: () => [
10374
- new Plugin10({
10413
+ new Plugin11({
10375
10414
  key: inlineSuggestKey,
10376
10415
  state: {
10377
10416
  init: () => ({ suggestion: null, anchorPos: null }),