@sendbird/actionbook-core 0.10.0 → 0.10.1

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
@@ -2020,7 +2020,7 @@ function resourceTagToMarkdown() {
2020
2020
  }
2021
2021
 
2022
2022
  // src/markdown/plugins/jumpPoint.ts
2023
- var JUMP_POINT_RE = /\^([A-Za-z_]+)\^/g;
2023
+ var JUMP_POINT_RE = /\^([\p{L}\p{N}_-]+)\^/gu;
2024
2024
  function splitTextWithJumpPoints(text2) {
2025
2025
  const results = [];
2026
2026
  let lastIndex = 0;
@@ -2677,7 +2677,7 @@ function useEditorView(config) {
2677
2677
  const view = new EditorView(container, {
2678
2678
  state,
2679
2679
  nodeViews,
2680
- editable: () => configRef.current.editable !== false,
2680
+ editable: () => configRef.current.editable === true,
2681
2681
  dispatchTransaction(tr) {
2682
2682
  const newState = view.state.apply(tr);
2683
2683
  view.updateState(newState);
@@ -2733,13 +2733,87 @@ function useEditorView(config) {
2733
2733
  // src/ui/plugin/inputRulesPlugin.ts
2734
2734
  import { InputRule, textblockTypeInputRule, wrappingInputRule } from "prosemirror-inputrules";
2735
2735
  import { TextSelection } from "prosemirror-state";
2736
+
2737
+ // src/ui/plugin/slashCommandPlugin.ts
2738
+ import { Plugin, PluginKey } from "prosemirror-state";
2739
+ var slashCommandKey = new PluginKey("slashCommand");
2740
+ var TRIGGER_RE = /(?:^|\s)(\/[^\s]*)$/;
2741
+ function deriveState(state, dismissedFrom) {
2742
+ const inactive = { active: false, range: null, query: "", parentType: "" };
2743
+ const { selection } = state;
2744
+ if (!selection.empty) return inactive;
2745
+ const { $from } = selection;
2746
+ const parentType = $from.parent.type.name;
2747
+ for (let d = $from.depth; d > 0; d--) {
2748
+ if ($from.node(d).type.name === "noteBlock") return inactive;
2749
+ }
2750
+ const textBefore = $from.parent.textBetween(0, $from.parentOffset, "\n", "\0");
2751
+ const match = TRIGGER_RE.exec(textBefore);
2752
+ if (!match) return inactive;
2753
+ const slashText = match[1];
2754
+ const slashStartInParent = textBefore.lastIndexOf(slashText);
2755
+ const from = $from.start() + slashStartInParent;
2756
+ const to = $from.pos;
2757
+ if (dismissedFrom === from) return inactive;
2758
+ return {
2759
+ active: true,
2760
+ range: { from, to },
2761
+ query: slashText.slice(1),
2762
+ parentType
2763
+ };
2764
+ }
2765
+ function createSlashCommandPlugin() {
2766
+ const plugin = new Plugin({
2767
+ key: slashCommandKey,
2768
+ state: {
2769
+ init(_, state) {
2770
+ const derived = deriveState(state, null);
2771
+ return { ...derived, _dismissedFrom: null };
2772
+ },
2773
+ apply(tr, prev, _old, newState) {
2774
+ const meta = tr.getMeta(slashCommandKey);
2775
+ let dismissedFrom = prev._dismissedFrom;
2776
+ if (meta?.dismiss !== void 0) {
2777
+ dismissedFrom = meta.dismiss;
2778
+ } else if (dismissedFrom !== null) {
2779
+ const derived2 = deriveState(newState, null);
2780
+ if (derived2.active && derived2.range && derived2.range.from !== dismissedFrom) {
2781
+ dismissedFrom = null;
2782
+ }
2783
+ }
2784
+ const derived = deriveState(newState, dismissedFrom);
2785
+ return { ...derived, _dismissedFrom: dismissedFrom };
2786
+ }
2787
+ }
2788
+ // Expose only the public fields via the key
2789
+ // (InternalState is a superset of SlashCommandState so reads work fine)
2790
+ });
2791
+ return {
2792
+ name: "slashCommand",
2793
+ plugins: () => [plugin],
2794
+ keymap: () => ({
2795
+ Escape: (state, dispatch) => {
2796
+ const s = slashCommandKey.getState(state);
2797
+ if (!s?.active || !s.range) return false;
2798
+ if (dispatch) {
2799
+ const tr = state.tr;
2800
+ tr.setMeta(slashCommandKey, { dismiss: s.range.from });
2801
+ dispatch(tr);
2802
+ }
2803
+ return true;
2804
+ }
2805
+ })
2806
+ };
2807
+ }
2808
+
2809
+ // src/ui/plugin/inputRulesPlugin.ts
2736
2810
  var HEADING_RE = /^(#{1,6})\s$/;
2737
2811
  var BLOCKQUOTE_RE = /^\s*>\s$/;
2738
2812
  var CODE_BLOCK_RE = /^```([a-zA-Z0-9]*)$/;
2739
2813
  var HR_RE = /^([-*_])\1{2,}$/;
2740
2814
  var BULLET_LIST_RE = /^\s*([-*])\s$/;
2741
2815
  var ORDERED_LIST_RE = /^(\d+)\.\s$/;
2742
- var JUMP_POINT_RE2 = /\^([A-Za-z_]+)\^$/;
2816
+ var JUMP_POINT_RE2 = /\^([\p{L}\p{N}_-]+)\^$/u;
2743
2817
  var BOLD_STAR_RE = /(?:^|[^*])\*\*([^*]+)\*\*$/;
2744
2818
  var BOLD_UNDER_RE = /(?:^|[^_])__([^_]+)__$/;
2745
2819
  var ITALIC_STAR_RE = /(?:^|[^*])\*([^*]+)\*$/;
@@ -2806,6 +2880,8 @@ function handleListInputRule(state, start, end, listType, attrs) {
2806
2880
  }
2807
2881
  function markInputRule(pattern, markType, markerLen) {
2808
2882
  return new InputRule(pattern, (state, match, start, end) => {
2883
+ const slashState = slashCommandKey.getState(state);
2884
+ if (slashState?.active) return null;
2809
2885
  const textContent2 = match[1];
2810
2886
  const fullMatch = match[0];
2811
2887
  const markedLength = markerLen * 2 + textContent2.length;
@@ -3298,9 +3374,20 @@ var enterCommand = chainCommands(
3298
3374
  );
3299
3375
  var shiftEnterCommand = (state, dispatch) => {
3300
3376
  if (dispatch) {
3301
- dispatch(
3302
- state.tr.replaceSelectionWith(hardBreak.create()).scrollIntoView()
3303
- );
3377
+ const { from, to, $from } = state.selection;
3378
+ const tr = state.tr;
3379
+ if (from !== to) tr.delete(from, to);
3380
+ const insertPos = tr.mapping.map(from);
3381
+ const marks = $from.marks();
3382
+ tr.insert(insertPos, hardBreak.create());
3383
+ const afterBr = insertPos + 1;
3384
+ tr.insertText("\u200B", afterBr);
3385
+ const cursorPos = afterBr + 1;
3386
+ if (cursorPos <= tr.doc.content.size) {
3387
+ tr.setSelection(TextSelection2.create(tr.doc, cursorPos));
3388
+ }
3389
+ if (marks.length > 0) tr.setStoredMarks(marks);
3390
+ dispatch(tr.scrollIntoView());
3304
3391
  }
3305
3392
  return true;
3306
3393
  };
@@ -3327,7 +3414,7 @@ function createKeymapPlugin() {
3327
3414
 
3328
3415
  // src/ui/plugin/markdownClipboard.ts
3329
3416
  import { DOMParser as ProseMirrorDOMParser, Fragment, Slice } from "prosemirror-model";
3330
- import { Plugin, PluginKey } from "prosemirror-state";
3417
+ import { Plugin as Plugin2, PluginKey as PluginKey2 } from "prosemirror-state";
3331
3418
 
3332
3419
  // src/ast/traverse.ts
3333
3420
  var MAX_DEPTH3 = 128;
@@ -5210,7 +5297,7 @@ function buildDocumentTree(doc2) {
5210
5297
  }
5211
5298
 
5212
5299
  // src/ui/plugin/markdownClipboard.ts
5213
- var key = new PluginKey("markdownClipboard");
5300
+ var key = new PluginKey2("markdownClipboard");
5214
5301
  var MAX_PASTE_LIST_DEPTH = 3;
5215
5302
  var MAX_FLATTEN_DEPTH = 128;
5216
5303
  function flattenDeepLists(node, listDepth = 0, _recurseDepth = 0) {
@@ -5273,7 +5360,7 @@ function textToSlice(text2, view) {
5273
5360
  view.state.doc.descendants((node) => {
5274
5361
  if (node.type.name === "jumpPoint") existingIds.add(node.attrs.id);
5275
5362
  });
5276
- const deduped = text2.replace(/\^([A-Za-z_][A-Za-z0-9_]*)\^/gm, (match, id) => {
5363
+ const deduped = text2.replace(/\^([\p{L}\p{N}_-]+)\^/gmu, (match, id) => {
5277
5364
  if (existingIds.has(id)) return id;
5278
5365
  existingIds.add(id);
5279
5366
  return match;
@@ -5290,7 +5377,7 @@ function textToSlice(text2, view) {
5290
5377
  }
5291
5378
  var URL_RE = /^https?:\/\/[^\s]+$/i;
5292
5379
  function createPlugin() {
5293
- return new Plugin({
5380
+ return new Plugin2({
5294
5381
  key,
5295
5382
  props: {
5296
5383
  handlePaste(view, event) {
@@ -5356,9 +5443,9 @@ function createMarkdownClipboardPlugin() {
5356
5443
  }
5357
5444
 
5358
5445
  // src/ui/plugin/jumpPointPlugin.ts
5359
- import { Plugin as Plugin2, PluginKey as PluginKey2, TextSelection as TextSelection3 } from "prosemirror-state";
5446
+ import { Plugin as Plugin3, PluginKey as PluginKey3, TextSelection as TextSelection3 } from "prosemirror-state";
5360
5447
  import { Decoration, DecorationSet } from "prosemirror-view";
5361
- var adjacentKey = new PluginKey2("jumpPointAdjacent");
5448
+ var adjacentKey = new PluginKey3("jumpPointAdjacent");
5362
5449
  var JUMP_POINT_ADJACENT_SPEC = { jumpPointAdjacent: true };
5363
5450
  function buildDecorations(state) {
5364
5451
  const { selection } = state;
@@ -5374,10 +5461,10 @@ function buildDecorations(state) {
5374
5461
  });
5375
5462
  return DecorationSet.create(state.doc, decorations);
5376
5463
  }
5377
- var jumpPointEditKey = new PluginKey2("jumpPointEdit");
5378
- var JUMP_POINT_FULL_RE = /^\^([A-Za-z_][A-Za-z0-9_]*)\^$/;
5464
+ var jumpPointEditKey = new PluginKey3("jumpPointEdit");
5465
+ var JUMP_POINT_FULL_RE = /^\^([\p{L}\p{N}_-]+)\^$/u;
5379
5466
  function createJumpPointEditPlugin() {
5380
- return new Plugin2({
5467
+ return new Plugin3({
5381
5468
  key: jumpPointEditKey,
5382
5469
  state: {
5383
5470
  init: () => ({ rawRange: null }),
@@ -5479,7 +5566,7 @@ function createJumpPointAdjacentPlugin() {
5479
5566
  }),
5480
5567
  plugins: () => [
5481
5568
  createJumpPointEditPlugin(),
5482
- new Plugin2({
5569
+ new Plugin3({
5483
5570
  key: adjacentKey,
5484
5571
  state: {
5485
5572
  init(_, state) {
@@ -5645,9 +5732,9 @@ function createJumpPointNodeViewPlugin() {
5645
5732
  }
5646
5733
 
5647
5734
  // src/ui/plugin/jumpPointValidationPlugin.ts
5648
- import { Plugin as Plugin3, PluginKey as PluginKey3 } from "prosemirror-state";
5735
+ import { Plugin as Plugin4, PluginKey as PluginKey4 } from "prosemirror-state";
5649
5736
  import { Decoration as Decoration2, DecorationSet as DecorationSet2 } from "prosemirror-view";
5650
- var pluginKey = new PluginKey3("jumpPointValidation");
5737
+ var pluginKey = new PluginKey4("jumpPointValidation");
5651
5738
  function collectJumpPointIds(state) {
5652
5739
  const ids = /* @__PURE__ */ new Set();
5653
5740
  state.doc.descendants((node) => {
@@ -5697,7 +5784,7 @@ function createJumpPointValidationPlugin() {
5697
5784
  return {
5698
5785
  name: "jumpPointValidation",
5699
5786
  plugins: () => [
5700
- new Plugin3({
5787
+ new Plugin4({
5701
5788
  key: pluginKey,
5702
5789
  state: {
5703
5790
  init(_, state) {
@@ -5813,9 +5900,9 @@ function createInlineToolTagNodeViewPlugin() {
5813
5900
  }
5814
5901
 
5815
5902
  // src/ui/plugin/jinjaDecoration.ts
5816
- import { Plugin as Plugin4, PluginKey as PluginKey4 } from "prosemirror-state";
5903
+ import { Plugin as Plugin5, PluginKey as PluginKey5 } from "prosemirror-state";
5817
5904
  import { Decoration as Decoration3, DecorationSet as DecorationSet3 } from "prosemirror-view";
5818
- var jinjaPluginKey = new PluginKey4("jinjaDecoration");
5905
+ var jinjaPluginKey = new PluginKey5("jinjaDecoration");
5819
5906
  var JINJA_TAG_RE = /\{%\s*(if|elif|else|endif)\s*([^%]*?)\s*%\}/g;
5820
5907
  function getBlockPositions(doc2) {
5821
5908
  const blocks = [];
@@ -5906,7 +5993,7 @@ function createJinjaDecorationPlugin() {
5906
5993
  return {
5907
5994
  name: "jinjaDecoration",
5908
5995
  plugins: () => [
5909
- new Plugin4({
5996
+ new Plugin5({
5910
5997
  key: jinjaPluginKey,
5911
5998
  state: {
5912
5999
  init(_, state) {
@@ -5930,7 +6017,7 @@ function createJinjaDecorationPlugin() {
5930
6017
  // src/ui/plugin/jinjaIfBlockPlugin.tsx
5931
6018
  import { useEffect as useEffect2, useRef as useRef2, useState as useState3 } from "react";
5932
6019
  import { createRoot as createRoot2 } from "react-dom/client";
5933
- import { Plugin as Plugin5, TextSelection as TextSelection4 } from "prosemirror-state";
6020
+ import { Plugin as Plugin6, TextSelection as TextSelection4 } from "prosemirror-state";
5934
6021
  import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
5935
6022
  var PLACEHOLDER_TEXT = "Describe what AI agent should do when this condition is met";
5936
6023
  var CONDITION_PLACEHOLDER = "Write a condition in natural language";
@@ -6766,7 +6853,7 @@ var JinjaIfBranchView = class {
6766
6853
  {
6767
6854
  branchType,
6768
6855
  condition,
6769
- editable: this.view.editable,
6856
+ editable: this.view.editable && this.view.dom.getAttribute("contenteditable") !== "false",
6770
6857
  isLastBranch: showAddButton,
6771
6858
  hasElseBranch: context && nodePos != null ? getElseBranch(this.view, nodePos) : false,
6772
6859
  onConditionChange: (value) => {
@@ -6824,7 +6911,7 @@ var JinjaIfBranchView = class {
6824
6911
  };
6825
6912
  function createEditableWatcherPlugin() {
6826
6913
  let lastEditable = null;
6827
- return new Plugin5({
6914
+ return new Plugin6({
6828
6915
  view(editorView) {
6829
6916
  lastEditable = editorView.editable;
6830
6917
  return {
@@ -6855,10 +6942,10 @@ function createJinjaIfBlockPlugin() {
6855
6942
 
6856
6943
  // src/ui/plugin/linkPlugin.ts
6857
6944
  import { InputRule as InputRule2, inputRules as inputRules2 } from "prosemirror-inputrules";
6858
- import { Plugin as Plugin6, PluginKey as PluginKey5, TextSelection as TextSelection5 } from "prosemirror-state";
6945
+ import { Plugin as Plugin7, PluginKey as PluginKey6, TextSelection as TextSelection5 } from "prosemirror-state";
6859
6946
  var LINK_INPUT_RE = /\\?\[([^\]]*?)\\?\]\(([^)\s]*?)(?:\s+"([^"]*)")?\)$/;
6860
6947
  var LINK_FULL_RE = /^\\?\[([^\]]*?)\\?\]\(([^)\s]*?)(?:\s+"([^"]*)")?\)$/;
6861
- var linkEditKey = new PluginKey5("linkEdit");
6948
+ var linkEditKey = new PluginKey6("linkEdit");
6862
6949
  function getMarkRange($pos, type) {
6863
6950
  const { parentOffset } = $pos;
6864
6951
  let child = $pos.parent.childAfter(parentOffset);
@@ -6906,7 +6993,7 @@ function explodeLinkToRaw(state) {
6906
6993
  return tr;
6907
6994
  }
6908
6995
  function createLinkEditPlugin() {
6909
- return new Plugin6({
6996
+ return new Plugin7({
6910
6997
  key: linkEditKey,
6911
6998
  state: {
6912
6999
  init: () => ({ rawRange: null }),
@@ -6976,8 +7063,8 @@ function createLinkInputRule() {
6976
7063
  );
6977
7064
  }
6978
7065
  function createLinkClickPlugin() {
6979
- return new Plugin6({
6980
- key: new PluginKey5("linkClick"),
7066
+ return new Plugin7({
7067
+ key: new PluginKey6("linkClick"),
6981
7068
  props: {
6982
7069
  handleDOMEvents: {
6983
7070
  click: (_view, event) => {
@@ -7029,8 +7116,8 @@ function createLinkPlugin() {
7029
7116
  }
7030
7117
 
7031
7118
  // src/ui/plugin/dragHandlePlugin.ts
7032
- import { Plugin as Plugin7, PluginKey as PluginKey6 } from "prosemirror-state";
7033
- var PLUGIN_KEY = new PluginKey6("dragHandle");
7119
+ import { Plugin as Plugin8, PluginKey as PluginKey7 } from "prosemirror-state";
7120
+ var PLUGIN_KEY = new PluginKey7("dragHandle");
7034
7121
  var GRIP_SVG = `<svg width="12" height="12" viewBox="0 0 12 12" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
7035
7122
  <circle cx="4" cy="2.5" r="1.2"/><circle cx="8" cy="2.5" r="1.2"/>
7036
7123
  <circle cx="4" cy="6" r="1.2"/><circle cx="8" cy="6" r="1.2"/>
@@ -7837,7 +7924,7 @@ function createDragHandlePlugin() {
7837
7924
  plugins: () => {
7838
7925
  let controller = null;
7839
7926
  return [
7840
- new Plugin7({
7927
+ new Plugin8({
7841
7928
  key: PLUGIN_KEY,
7842
7929
  view(editorView) {
7843
7930
  controller = new DragHandleController(editorView);
@@ -7960,10 +8047,10 @@ function createTodoNodeViewPlugin() {
7960
8047
  }
7961
8048
 
7962
8049
  // src/ui/plugin/placeholderPlugin.ts
7963
- import { Plugin as Plugin8, PluginKey as PluginKey7 } from "prosemirror-state";
8050
+ import { Plugin as Plugin9, PluginKey as PluginKey8 } from "prosemirror-state";
7964
8051
  import { Decoration as Decoration4, DecorationSet as DecorationSet4 } from "prosemirror-view";
7965
8052
  var PLACEHOLDER_TEXT2 = "Type to start writing, or press / to insert an action.";
7966
- var pluginKey2 = new PluginKey7("placeholder");
8053
+ var pluginKey2 = new PluginKey8("placeholder");
7967
8054
  function buildDecorations4(state) {
7968
8055
  const { doc: doc2, selection } = state;
7969
8056
  if (!selection.empty) return DecorationSet4.empty;
@@ -7989,7 +8076,7 @@ function createPlaceholderPlugin() {
7989
8076
  return {
7990
8077
  name: "placeholder",
7991
8078
  plugins: () => [
7992
- new Plugin8({
8079
+ new Plugin9({
7993
8080
  key: pluginKey2,
7994
8081
  state: {
7995
8082
  init(_, state) {
@@ -8012,78 +8099,6 @@ function createPlaceholderPlugin() {
8012
8099
  };
8013
8100
  }
8014
8101
 
8015
- // src/ui/plugin/slashCommandPlugin.ts
8016
- import { Plugin as Plugin9, PluginKey as PluginKey8 } from "prosemirror-state";
8017
- var slashCommandKey = new PluginKey8("slashCommand");
8018
- var TRIGGER_RE = /(?:^|\s)(\/[^\s]*)$/;
8019
- function deriveState(state, dismissedFrom) {
8020
- const inactive = { active: false, range: null, query: "", parentType: "" };
8021
- const { selection } = state;
8022
- if (!selection.empty) return inactive;
8023
- const { $from } = selection;
8024
- const parentType = $from.parent.type.name;
8025
- for (let d = $from.depth; d > 0; d--) {
8026
- if ($from.node(d).type.name === "noteBlock") return inactive;
8027
- }
8028
- const textBefore = $from.parent.textBetween(0, $from.parentOffset, "\n", "\0");
8029
- const match = TRIGGER_RE.exec(textBefore);
8030
- if (!match) return inactive;
8031
- const slashText = match[1];
8032
- const slashStartInParent = textBefore.lastIndexOf(slashText);
8033
- const from = $from.start() + slashStartInParent;
8034
- const to = $from.pos;
8035
- if (dismissedFrom === from) return inactive;
8036
- return {
8037
- active: true,
8038
- range: { from, to },
8039
- query: slashText.slice(1),
8040
- parentType
8041
- };
8042
- }
8043
- function createSlashCommandPlugin() {
8044
- const plugin = new Plugin9({
8045
- key: slashCommandKey,
8046
- state: {
8047
- init(_, state) {
8048
- const derived = deriveState(state, null);
8049
- return { ...derived, _dismissedFrom: null };
8050
- },
8051
- apply(tr, prev, _old, newState) {
8052
- const meta = tr.getMeta(slashCommandKey);
8053
- let dismissedFrom = prev._dismissedFrom;
8054
- if (meta?.dismiss !== void 0) {
8055
- dismissedFrom = meta.dismiss;
8056
- } else if (dismissedFrom !== null) {
8057
- const derived2 = deriveState(newState, null);
8058
- if (derived2.active && derived2.range && derived2.range.from !== dismissedFrom) {
8059
- dismissedFrom = null;
8060
- }
8061
- }
8062
- const derived = deriveState(newState, dismissedFrom);
8063
- return { ...derived, _dismissedFrom: dismissedFrom };
8064
- }
8065
- }
8066
- // Expose only the public fields via the key
8067
- // (InternalState is a superset of SlashCommandState so reads work fine)
8068
- });
8069
- return {
8070
- name: "slashCommand",
8071
- plugins: () => [plugin],
8072
- keymap: () => ({
8073
- Escape: (state, dispatch) => {
8074
- const s = slashCommandKey.getState(state);
8075
- if (!s?.active || !s.range) return false;
8076
- if (dispatch) {
8077
- const tr = state.tr;
8078
- tr.setMeta(slashCommandKey, { dismiss: s.range.from });
8079
- dispatch(tr);
8080
- }
8081
- return true;
8082
- }
8083
- })
8084
- };
8085
- }
8086
-
8087
8102
  // src/ui/components/SlashCommandMenu.tsx
8088
8103
  import React4, { useEffect as useEffect3, useLayoutEffect, useRef as useRef3, useState as useState4 } from "react";
8089
8104
  import { createPortal } from "react-dom";