@box/threaded-annotations 4.0.7 → 4.1.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.
@@ -11,42 +11,42 @@ import '../styles/threaded-annotations2.css';var m = {
11
11
  expandable: "_expandable_16hhz_10",
12
12
  annotations: "_annotations_16hhz_18",
13
13
  highlighted: "_highlighted_16hhz_18"
14
- }, h = ({ messages: r, isResolved: h = !1, resolvedBy: g, resolvedAt: _, maxCharacterCount: v, onDelete: y, onThreadDelete: b, onAvatarClick: x, onCopyLink: S, onEdit: C, onEditError: w, onResolve: T, onUnresolve: E, onPost: D, onPostError: O, userSelectorProps: k, onEditorOpenChange: A, annotationTarget: j, onAnnotationBadgeClick: M, originalContentDeleted: N, isHighlighted: P = !1 }) => {
15
- let { viewState: F, dispatch: I, editingMessageId: L, replyMention: R, isReplyDisabled: z, isAnnotations: B } = i(), V = d(null), H = F !== n.Collapsed, U = r.length > 2, W = F === n.Collapsed && (U || !z && !h);
14
+ }, h = ({ messages: r, isResolved: h = !1, resolvedBy: g, resolvedAt: _, maxCharacterCount: v, onDelete: y, onThreadDelete: b, onAvatarClick: x, onCopyLink: S, onEdit: C, onEditError: w, onResolve: T, onUnresolve: E, onPost: D, onPostError: O, userSelectorProps: k, onEditorOpenChange: A, annotationTarget: j, onAnnotationBadgeClick: M, originalContentDeleted: N, isHighlighted: P = !1, autoFocusReplyEditor: F = !0 }) => {
15
+ let { viewState: I, dispatch: L, editingMessageId: R, replyMention: z, isReplyDisabled: B, isAnnotations: V } = i(), H = d(null), U = I !== n.Collapsed, W = r.length > 2, G = I === n.Collapsed && (W || !B && !h);
16
16
  l(() => {
17
- L && !r.some((e) => e.id === L) && I({ type: "CLEAR_EDIT" });
17
+ R && !r.some((e) => e.id === R) && L({ type: "CLEAR_EDIT" });
18
18
  }, [
19
- L,
19
+ R,
20
20
  r,
21
- I
21
+ L
22
22
  ]), l(() => {
23
- A?.(H);
24
- }, [H, A]), l(() => {
25
- if (!H) return;
23
+ A?.(U);
24
+ }, [U, A]), l(() => {
25
+ if (!U) return;
26
26
  let t = `[${Object.keys(e)[0]}]`, n = (e) => {
27
27
  let n = e.target;
28
- V.current?.contains(n) || document.querySelector(t)?.contains(n) || I({ type: "COLLAPSE" });
28
+ H.current?.contains(n) || document.querySelector(t)?.contains(n) || L({ type: "COLLAPSE" });
29
29
  };
30
30
  return document.addEventListener("mousedown", n), () => document.removeEventListener("mousedown", n);
31
- }, [H, I]);
32
- let G = r.length === 0, K = c(() => I({ type: "CLEAR_MENTION" }), [I]), q = u(() => R ? o(R) : null, [R]), J = c((e) => {
33
- if (!W) return;
31
+ }, [U, L]);
32
+ let K = r.length === 0, q = c(() => L({ type: "CLEAR_MENTION" }), [L]), J = u(() => z ? o(z) : null, [z]), Y = c((e) => {
33
+ if (!G) return;
34
34
  let t = e.target;
35
- !e.currentTarget.contains(t) || t.closest("[data-no-expand]") || I({ type: "EXPAND" });
36
- }, [W, I]);
37
- return B && G ? /* @__PURE__ */ f(t, {
35
+ !e.currentTarget.contains(t) || t.closest("[data-no-expand]") || L({ type: "EXPAND" });
36
+ }, [G, L]);
37
+ return V && K ? /* @__PURE__ */ f(t, {
38
38
  isFirstAnnotation: !0,
39
39
  maxCharacterCount: v,
40
40
  onPost: D,
41
41
  onPostError: O,
42
- onPostSuccess: K,
42
+ onPostSuccess: q,
43
43
  userSelectorProps: k
44
44
  }) : /* @__PURE__ */ p("div", {
45
- ref: V,
46
- className: s(m.threadedAnnotations, W && m.expandable, B && m.annotations, P && m.highlighted),
47
- "data-thread-expandable": W ? !0 : void 0,
45
+ ref: H,
46
+ className: s(m.threadedAnnotations, G && m.expandable, V && m.annotations, P && m.highlighted),
47
+ "data-thread-expandable": G ? !0 : void 0,
48
48
  "data-thread-highlighted": P ? !0 : void 0,
49
- onClick: W ? J : void 0,
49
+ onClick: G ? Y : void 0,
50
50
  children: [/* @__PURE__ */ f(a, {
51
51
  messages: r,
52
52
  isResolved: h,
@@ -65,12 +65,13 @@ import '../styles/threaded-annotations2.css';var m = {
65
65
  annotationTarget: j,
66
66
  onAnnotationBadgeClick: M,
67
67
  originalContentDeleted: N
68
- }), F === n.Composing && /* @__PURE__ */ f(t, {
69
- initialContent: q,
68
+ }), I === n.Composing && /* @__PURE__ */ f(t, {
69
+ autoFocus: F,
70
+ initialContent: J,
70
71
  maxCharacterCount: v,
71
72
  onPost: D,
72
73
  onPostError: O,
73
- onPostSuccess: K,
74
+ onPostSuccess: q,
74
75
  isReply: !0,
75
76
  userSelectorProps: k
76
77
  })]
@@ -2,11 +2,11 @@ import { THREADED_ANNOTATIONS_PORTAL as e } from "../../../v2/constants.js";
2
2
  import { useMentionContext as t } from "../../mention-component/mention-context.js";
3
3
  import { CustomMention as n } from "./editor-extensions/custom-mention/custom-mention.js";
4
4
  import { createSuggestionOptions as r } from "./editor-extensions/custom-mention/custom-mention-suggestions.js";
5
- import { MENTION_PLUGIN_KEY as i, normalizeMentionPastedText as a, normalizeMentionTextInput as ee } from "./editor-extensions/custom-mention/mention-trigger-normalization.js";
6
- import { useMentionState as o } from "./editor-extensions/custom-mention/useMentionState.js";
7
- import { CustomParagraph as te } from "./editor-extensions/custom-paragraph.js";
8
- import { useCharacterLimit as ne } from "./hooks/useCharacterLimit.js";
9
- import { useEditorContainerState as re } from "./hooks/useEditorContainerState.js";
5
+ import { MENTION_PLUGIN_KEY as i, normalizeMentionPastedText as ee, normalizeMentionTextInput as a } from "./editor-extensions/custom-mention/mention-trigger-normalization.js";
6
+ import { useMentionState as te } from "./editor-extensions/custom-mention/useMentionState.js";
7
+ import { CustomParagraph as ne } from "./editor-extensions/custom-paragraph.js";
8
+ import { useCharacterLimit as re } from "./hooks/useCharacterLimit.js";
9
+ import { useEditorContainerState as o } from "./hooks/useEditorContainerState.js";
10
10
  import { useMentionUserSelection as ie } from "./hooks/useMentionUserSelection.js";
11
11
  import { MessageEditorProvider as s, useMessageEditorContext as ae } from "./message-editor-context.js";
12
12
  import c from "./messages.js";
@@ -20,43 +20,43 @@ import { MessageEditorVariant as h } from "./message-editor.types.js";
20
20
  import { VisuallyHidden as oe } from "@box/blueprint-web";
21
21
  import g from "clsx";
22
22
  import { useEffect as _, useMemo as se, useRef as v } from "react";
23
- import { useIntl as y } from "react-intl";
24
- import { Fragment as b, jsx as x, jsxs as S } from "react/jsx-runtime";
25
- import { UserSelectorHeadless as C } from "@box/user-selector";
26
- import { EditorContent as w, useEditor as T } from "@tiptap/react";
27
- import E from "@tiptap/extension-document";
28
- import ce from "@tiptap/extension-text";
29
- import { Placeholder as le } from "@tiptap/extensions";
30
- var D = (s) => {
31
- let { disableComponent: D = !1, initialContent: O, isFirstAnnotation: k = !1, isReply: ue = !1, maxCharacterCount: A, userSelectorProps: j, videoTimestamp: M } = s, N = v(null), P = v(null), F = v(null), I = y(), { errorMessage: L, isLoading: R } = ae(), { close: z, isActive: B, query: V, command: H, suggestionCallbacks: de } = o(N), { closeAllPopovers: fe } = t(), U = I.formatMessage(ue ? c.placeholderReply : c.placeholderAddComment), W = s.variant === h.EDIT_MESSAGE, G = T({
23
+ import { useIntl as ce } from "react-intl";
24
+ import { Fragment as y, jsx as b, jsxs as x } from "react/jsx-runtime";
25
+ import { UserSelectorHeadless as le } from "@box/user-selector";
26
+ import { EditorContent as S, useEditor as C } from "@tiptap/react";
27
+ import w from "@tiptap/extension-document";
28
+ import T from "@tiptap/extension-text";
29
+ import { Placeholder as ue } from "@tiptap/extensions";
30
+ var E = (s) => {
31
+ let { autoFocus: E = !0, disableComponent: D = !1, initialContent: O, isFirstAnnotation: k = !1, isReply: de = !1, maxCharacterCount: A, userSelectorProps: j, videoTimestamp: M } = s, N = v(null), P = v(null), F = v(null), I = ce(), { errorMessage: L, isLoading: R } = ae(), { close: z, isActive: B, query: V, command: H, suggestionCallbacks: fe } = te(N), { closeAllPopovers: pe } = t(), U = I.formatMessage(de ? c.placeholderReply : c.placeholderAddComment), W = s.variant === h.EDIT_MESSAGE, G = C({
32
32
  shouldRerenderOnTransaction: !0,
33
33
  extensions: [
34
- E,
35
- te,
36
- le.configure({
34
+ w,
35
+ ne,
36
+ ue.configure({
37
37
  placeholder: U,
38
38
  showOnlyWhenEditable: !1
39
39
  }),
40
- ce,
41
- n.configure({ suggestion: r(i, "@", de) })
40
+ T,
41
+ n.configure({ suggestion: r(i, "@", fe) })
42
42
  ],
43
- autofocus: !0,
43
+ autofocus: E,
44
44
  content: O,
45
45
  editorProps: {
46
46
  attributes: { class: l.editor },
47
- handleTextInput: ee,
48
- transformPastedText: a
47
+ handleTextInput: a,
48
+ transformPastedText: ee
49
49
  },
50
50
  onCreate: ({ editor: e }) => {
51
- F.current = e.view.dom, e.commands.focus("end");
51
+ F.current = e.view.dom, E && e.commands.focus("end");
52
52
  },
53
53
  onUpdate: () => {
54
- fe?.();
54
+ pe?.();
55
55
  }
56
- }, [U]), { onUserSelected: pe } = ie(se(() => H && G && !G.isDestroyed ? {
56
+ }, [U]), { onUserSelected: me } = ie(se(() => H && G && !G.isDestroyed ? {
57
57
  command: H,
58
58
  editor: G
59
- } : null, [H, G])), { exceedsSingleLine: me, hasScroll: K, isAtBottom: q } = re(P, G), J = ne(G, O, A), Y = W || !k || k && me, he = !G || G?.isEmpty, X = D || R, Z = (J?.excess ?? 0) > 0, Q = he || X || Z, $ = J && J.excess > 0 && Y;
59
+ } : null, [H, G])), { exceedsSingleLine: he, hasScroll: K, isAtBottom: q } = o(P, G), J = re(G, O, A), Y = W || !k || k && he, ge = !G || G?.isEmpty, X = D || R, Z = (J?.excess ?? 0) > 0, Q = ge || X || Z, $ = J && J.excess > 0 && Y;
60
60
  _(() => {
61
61
  G && G.setEditable(!X);
62
62
  }, [G, X]), _(() => {
@@ -71,7 +71,7 @@ var D = (s) => {
71
71
  };
72
72
  }, [Z]), _(() => {
73
73
  !G || O === void 0 || queueMicrotask(() => {
74
- G.isDestroyed || (G.commands.setContent(O ?? "", { emitUpdate: !1 }), G.commands.focus("end"));
74
+ G.isDestroyed || (G.commands.setContent(O ?? "", { emitUpdate: !1 }), E && G.commands.focus("end"));
75
75
  });
76
76
  }, [O]), _(() => {
77
77
  if (!B) return;
@@ -90,11 +90,11 @@ var D = (s) => {
90
90
  cancelAnimationFrame(i), document.removeEventListener("mousedown", r), document.removeEventListener("focusin", r);
91
91
  };
92
92
  }, [z, B]);
93
- let ge = /* @__PURE__ */ x("div", { className: l.anchorElement });
94
- return /* @__PURE__ */ x("div", {
93
+ let _e = /* @__PURE__ */ b("div", { className: l.anchorElement });
94
+ return /* @__PURE__ */ b("div", {
95
95
  "data-no-expand": !0,
96
96
  className: l.messageEditorWrapper,
97
- children: /* @__PURE__ */ S("div", {
97
+ children: /* @__PURE__ */ x("div", {
98
98
  className: g(l.messageEditor, {
99
99
  [l.editorHasScroll]: K,
100
100
  [l.editorEditMode]: W,
@@ -102,21 +102,21 @@ var D = (s) => {
102
102
  [l.editorFirstAnnotation]: !W && k,
103
103
  [l.editorCharacterLimitExceeded]: Z
104
104
  }),
105
- children: [/* @__PURE__ */ S("div", {
105
+ children: [/* @__PURE__ */ x("div", {
106
106
  className: g(l.editorViewport, { [l.editorFullWidth]: Y }),
107
- children: [/* @__PURE__ */ S("div", {
107
+ children: [/* @__PURE__ */ x("div", {
108
108
  ref: P,
109
109
  className: l.editorContainer,
110
110
  "aria-label": I.formatMessage(c.scrollContainerAriaLabel),
111
- children: [/* @__PURE__ */ x(w, {
111
+ children: [/* @__PURE__ */ b(S, {
112
112
  "aria-label": I.formatMessage(c.editorContentAriaLabel),
113
113
  editor: G
114
- }), /* @__PURE__ */ x(C, {
114
+ }), /* @__PURE__ */ b(le, {
115
115
  ref: N,
116
116
  inputElementRef: F,
117
- onSelectedUserChange: pe,
117
+ onSelectedUserChange: me,
118
118
  open: B,
119
- rootElement: ge,
119
+ rootElement: _e,
120
120
  value: V,
121
121
  ...j,
122
122
  popoverContentContainerProps: {
@@ -125,39 +125,39 @@ var D = (s) => {
125
125
  avoidCollisions: !0
126
126
  }
127
127
  })]
128
- }), K && /* @__PURE__ */ x("div", {
128
+ }), K && /* @__PURE__ */ b("div", {
129
129
  className: g(l.editorFade, { [l.editorFadeHidden]: q }),
130
130
  "aria-hidden": "true"
131
131
  })]
132
- }), /* @__PURE__ */ x("div", {
132
+ }), /* @__PURE__ */ b("div", {
133
133
  className: g(l.actionsWrapper, { [l.withTimestampToggle]: !!M }),
134
- children: /* @__PURE__ */ S("div", {
134
+ children: /* @__PURE__ */ x("div", {
135
135
  className: g(l.actionsWrapperInner, {
136
136
  [l.scrolledToBottom]: q,
137
137
  [l.characterLimitExceeded]: Z
138
138
  }),
139
139
  children: [
140
- L && /* @__PURE__ */ x(f, { errorMessage: L }),
141
- J && J.excess > 0 && !Y && /* @__PURE__ */ x(oe, {
140
+ L && /* @__PURE__ */ b(f, { errorMessage: L }),
141
+ J && J.excess > 0 && !Y && /* @__PURE__ */ b(oe, {
142
142
  role: "alert",
143
143
  children: I.formatMessage(c.characterLimitExceeded, { excess: J.excess })
144
144
  }),
145
- M && /* @__PURE__ */ x(m, {
145
+ M && /* @__PURE__ */ b(m, {
146
146
  className: l.timestampToggle,
147
147
  disabled: X,
148
148
  formattedTimestamp: M.formattedTimestamp,
149
149
  isPressed: M.isPressed,
150
150
  onChange: M.onPressedChange
151
151
  }),
152
- W ? /* @__PURE__ */ S("div", {
152
+ W ? /* @__PURE__ */ x("div", {
153
153
  className: l.editActionsColumn,
154
- children: [$ && /* @__PURE__ */ x(u, {
154
+ children: [$ && /* @__PURE__ */ b(u, {
155
155
  count: J.count,
156
156
  excess: J.excess,
157
157
  maxCount: J.maxCount
158
- }), /* @__PURE__ */ x("div", {
158
+ }), /* @__PURE__ */ b("div", {
159
159
  className: l.editActionsRow,
160
- children: /* @__PURE__ */ x(d, {
160
+ children: /* @__PURE__ */ b(d, {
161
161
  disabled: Q,
162
162
  getEditorJsonContent: () => G?.getJSON(),
163
163
  onCancel: s.onEditCancel,
@@ -166,11 +166,11 @@ var D = (s) => {
166
166
  onSaveError: s.onSaveError
167
167
  })
168
168
  })]
169
- }) : /* @__PURE__ */ S(b, { children: [$ && /* @__PURE__ */ x(u, {
169
+ }) : /* @__PURE__ */ x(y, { children: [$ && /* @__PURE__ */ b(u, {
170
170
  count: J.count,
171
171
  excess: J.excess,
172
172
  maxCount: J.maxCount
173
- }), /* @__PURE__ */ x(p, {
173
+ }), /* @__PURE__ */ b(p, {
174
174
  cleanEditor: () => G?.commands.setContent("", { emitUpdate: !1 }),
175
175
  disabled: Q,
176
176
  getEditorJsonContent: () => G?.getJSON(),
@@ -183,5 +183,5 @@ var D = (s) => {
183
183
  })]
184
184
  })
185
185
  });
186
- }, O = (e) => /* @__PURE__ */ x(s, { children: /* @__PURE__ */ x(D, { ...e }) });
187
- export { O as MessageEditor, h as MessageEditorVariant };
186
+ }, D = (e) => /* @__PURE__ */ b(s, { children: /* @__PURE__ */ b(E, { ...e }) });
187
+ export { D as MessageEditor, h as MessageEditorVariant };
@@ -21,6 +21,13 @@ export interface VideoTimestampOptions {
21
21
  }
22
22
  interface BaseMessageEditorProps {
23
23
  disableComponent?: boolean;
24
+ /**
25
+ * When false, the editor does not autofocus or scroll itself into view on mount.
26
+ * Defaults to true. Set false when the host controls scroll position (e.g. deep-linking
27
+ * to a specific message), since the editor's mount-time focus scroll would otherwise
28
+ * fight that scroll and jump the viewport to the composer.
29
+ */
30
+ autoFocus?: boolean;
24
31
  /** When true (create mode only), editor does not expand to full width. Defaults to false. */
25
32
  isFirstAnnotation?: boolean;
26
33
  /**
@@ -51,6 +51,12 @@ interface ThreadedAnnotationsBaseProps {
51
51
  defaultExpanded?: boolean;
52
52
  /** When true, applies a visual highlight (border + background tint) to the thread card. Not a focus state. */
53
53
  isHighlighted?: boolean;
54
+ /**
55
+ * When false, the reply composer does not autofocus or scroll itself into view when the thread
56
+ * opens. Defaults to true. Set false when deep-linking to a specific message so the composer's
57
+ * mount-time focus scroll does not fight the host's scroll-to-message.
58
+ */
59
+ autoFocusReplyEditor?: boolean;
54
60
  }
55
61
  interface AnnotationModeProps extends ThreadedAnnotationsBaseProps {
56
62
  isAnnotations: true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@box/threaded-annotations",
3
- "version": "4.0.7",
3
+ "version": "4.1.0",
4
4
  "license": "SEE LICENSE IN LICENSE",
5
5
  "dependencies": {
6
6
  "@floating-ui/dom": "^1.6.0",