@factorialco/f0-react 12.2.0 → 12.4.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.
@@ -4,7 +4,7 @@ import { useCallback as i, useEffect as a, useRef as o, useState as s } from "re
4
4
  import { jsx as c, jsxs as l } from "react/jsx-runtime";
5
5
  //#region \0virtual:f0-component-status-data
6
6
  var u = {
7
- generatedAt: "2026-10-30T13:19:45.666Z",
7
+ generatedAt: "2026-10-31T12:18:02.614Z",
8
8
  stats: {
9
9
  total: 312,
10
10
  byStatus: {
@@ -3393,7 +3393,7 @@ var u = {
3393
3393
  hasWhenToUse: !0,
3394
3394
  hasWhenNotToUse: !0,
3395
3395
  hasDoDonts: !0,
3396
- exampleCount: 7
3396
+ exampleCount: 8
3397
3397
  },
3398
3398
  a11yTier: "enforced",
3399
3399
  storyFile: "blocks/Navigation/Sidebar/F0PrimarySidebar/__stories__/F0PrimarySidebar.stories.tsx"
@@ -3480,6 +3480,12 @@ type F0PrimarySidebarAction = {
3480
3480
  label: string;
3481
3481
  icon: IconType;
3482
3482
  onClick: () => void;
3483
+ /**
3484
+ * The button opens the page that is on screen, such as the settings. It is
3485
+ * marked like the active tab. Set `activeTab` to an id no tab has, so no tab
3486
+ * is marked as well.
3487
+ */
3488
+ active?: boolean;
3483
3489
  /** Show the unread marker over the icon. */
3484
3490
  hasUpdates?: boolean;
3485
3491
  /** A count shown instead of the plain marker. */
@@ -6273,6 +6279,12 @@ type F0ChatHeaderAction = {
6273
6279
  * Ignored for `inline` actions — the row of icon buttons has no such state.
6274
6280
  */
6275
6281
  critical?: boolean;
6282
+ /**
6283
+ * `promote` draws an inline action as an upsell (the `promote` button): the
6284
+ * action exists, but the plan leaves it out and pressing it should explain
6285
+ * why. Ignored in the overflow menu and for toggles (`active` set).
6286
+ */
6287
+ variant?: "default" | "promote";
6276
6288
  };
6277
6289
  /** The id of the built-in Messages tab, always first and the default. */
6278
6290
  export declare const F0_CHAT_MESSAGES_TAB_ID = "messages";
@@ -6667,10 +6679,17 @@ type F0ChatRuntime = {
6667
6679
  /**
6668
6680
  * Maximum size in bytes for each file selected, dropped, or pasted into the
6669
6681
  * composer. When any file exceeds the limit, the composer rejects the whole
6670
- * batch before calling `uploadFiles` and keeps the validation error visible
6671
- * until the next attachment attempt. Omit for no size limit.
6682
+ * batch before calling `uploadFiles` and shows the limit as a transient
6683
+ * error, gone after a few seconds like the other composer warnings. Omit for
6684
+ * no size limit.
6672
6685
  */
6673
6686
  maxFileSizeBytes?: number;
6687
+ /**
6688
+ * Called when a batch is rejected for {@link maxFileSizeBytes}, after the
6689
+ * composer shows its error. For hosts whose limit is a plan's, to offer the
6690
+ * upgrade.
6691
+ */
6692
+ onFileTooLarge?: (files: File[], maxFileSizeBytes: number) => void;
6674
6693
  /**
6675
6694
  * Maximum number of characters allowed in a message. The composer keeps an
6676
6695
  * oversized draft in place and shows its existing validation banner instead
@@ -12683,16 +12683,20 @@ var xT = (e) => e ? `f0-sidebar-tab:${e}` : null, ST = (e) => {
12683
12683
  }
12684
12684
  };
12685
12685
  function CT(e, t, n, r) {
12686
- let i = xT(e), a = Y(!1), o = t.some((e) => e.href !== void 0);
12686
+ let i = xT(e), a = Y(!1), o = t.some((e) => e.href !== void 0), s = t.some((e) => e.id === n);
12687
12687
  q(function() {
12688
- if (!i || a.current || (a.current = !0, o)) return;
12688
+ if (!i || a.current || (a.current = !0, o || !s)) return;
12689
12689
  let e = ST(i);
12690
12690
  e && e !== n && t.some((t) => t.id === e) && r(e);
12691
12691
  }, [i]), q(function() {
12692
- if (i) try {
12692
+ if (i && s) try {
12693
12693
  localStorage.setItem(i, n);
12694
12694
  } catch {}
12695
- }, [i, n]);
12695
+ }, [
12696
+ i,
12697
+ n,
12698
+ s
12699
+ ]);
12696
12700
  }
12697
12701
  //#endregion
12698
12702
  //#region src/blocks/Navigation/Sidebar/F0PrimarySidebar/hooks/usePresentItems.ts
@@ -12990,7 +12994,7 @@ var RT = 350, zT = (e = !0) => {
12990
12994
  glyph: /* @__PURE__ */ Q(H, {
12991
12995
  icon: e.icon,
12992
12996
  size: "lg",
12993
- color: "default"
12997
+ color: e.active ? "bold" : "default"
12994
12998
  })
12995
12999
  }), /* @__PURE__ */ Q(UT, {
12996
13000
  badge: e.badge,
@@ -13000,8 +13004,9 @@ var RT = 350, zT = (e = !0) => {
13000
13004
  }), s = /* @__PURE__ */ Q("button", {
13001
13005
  type: "button",
13002
13006
  "aria-label": r,
13007
+ "aria-current": e.active ? "page" : void 0,
13003
13008
  onClick: e.options ? void 0 : e.onClick,
13004
- className: G("flex size-9 cursor-pointer items-center justify-center rounded-lg group-hover:bg-f1-background-secondary data-[state=open]:bg-f1-background-secondary", e.options ? Zw : Xw, !e.options && "static after:absolute after:inset-0 after:z-10 after:content-['']", ir()),
13009
+ className: G("flex size-9 cursor-pointer items-center justify-center rounded-lg data-[state=open]:bg-f1-background-secondary", e.active ? "bg-f1-background-secondary" : "group-hover:bg-f1-background-secondary", e.options ? Zw : Xw, !e.options && "static after:absolute after:inset-0 after:z-10 after:content-['']", ir()),
13005
13010
  ...e.options ? a : {},
13006
13011
  children: e.options ? /* @__PURE__ */ Q(Yw, {
13007
13012
  itemId: e.id,
@@ -15972,7 +15977,7 @@ var hO = () => mO(aO, "useChatJump"), gO = (e) => {
15972
15977
  className: "flex shrink-0 items-center gap-0.5",
15973
15978
  children: [
15974
15979
  C.map((t) => t.active === void 0 ? /* @__PURE__ */ Q(er, {
15975
- variant: "ghost",
15980
+ variant: t.variant === "promote" ? "promote" : "ghost",
15976
15981
  hideLabel: !0,
15977
15982
  label: t.label,
15978
15983
  icon: t.icon,
@@ -20161,17 +20166,17 @@ var MP = {
20161
20166
  size: e.size,
20162
20167
  mimeType: e.type
20163
20168
  }, BP = (e, t) => e && t, VP = () => {
20164
- let e = W(), { sendMessage: t, editMessage: n, onInputActivity: r, stopTyping: i, uploadFiles: a, transcribe: o, maxFiles: s, maxFileSizeBytes: c, maxMessageCharacters: l, channel: u, searchMembers: d, capabilities: f } = gl(), p = !!a && zk("canUpload", u.type, f), { target: m } = _O(), { clearComposeTarget: h, registerComposerHandle: g } = vO(), _ = LP(), { registerFileDropHandler: v } = yO(), y = il(), { reducedMotion: b } = PO(), x = !!b, S = Y(null), [C, w] = X([]), T = Y(null), E = Y(null), D = Y(/* @__PURE__ */ new Set()), O = Y(0), { error: k, show: A, clear: j } = Rr(), M = m.kind === "edit", N = m.kind === "edit" ? m.message : null, P = m.kind === "reply" ? m.message : null, F = p, [I, ee] = X(!1), te = Y({ channelId: u.id });
20165
- te.current = {
20166
- channelId: u.id,
20167
- replyToId: P?.id
20169
+ let e = W(), { sendMessage: t, editMessage: n, onInputActivity: r, stopTyping: i, uploadFiles: a, transcribe: o, maxFiles: s, maxFileSizeBytes: c, onFileTooLarge: l, maxMessageCharacters: u, channel: d, searchMembers: f, capabilities: p } = gl(), m = !!a && zk("canUpload", d.type, p), { target: h } = _O(), { clearComposeTarget: g, registerComposerHandle: _ } = vO(), v = LP(), { registerFileDropHandler: y } = yO(), b = il(), { reducedMotion: x } = PO(), S = !!x, C = Y(null), [w, T] = X([]), E = Y(null), D = Y(null), O = Y(/* @__PURE__ */ new Set()), k = Y(0), { error: A, show: j, clear: M } = Rr(), N = h.kind === "edit", P = h.kind === "edit" ? h.message : null, F = h.kind === "reply" ? h.message : null, I = m, [ee, te] = X(!1), ne = Y({ channelId: d.id });
20170
+ ne.current = {
20171
+ channelId: d.id,
20172
+ replyToId: F?.id
20168
20173
  };
20169
- let ne = Y(m);
20170
- ne.current = m;
20171
- let re = K(async (n, r) => {
20174
+ let re = Y(h);
20175
+ re.current = h;
20176
+ let L = K(async (n, r) => {
20172
20177
  if (!a) return;
20173
- ee(!0);
20174
- let { channelId: i, replyToId: o } = te.current, s = n.type || "audio/webm", c = s.includes("mp4") ? "m4a" : s.includes("ogg") ? "ogg" : "webm", l = new File([n], `voice-note.${c}`, { type: s });
20178
+ te(!0);
20179
+ let { channelId: i, replyToId: o } = ne.current, s = n.type || "audio/webm", c = s.includes("mp4") ? "m4a" : s.includes("ogg") ? "ogg" : "webm", l = new File([n], `voice-note.${c}`, { type: s });
20175
20180
  try {
20176
20181
  let [e] = await a([l]);
20177
20182
  if (e && "url" in e) {
@@ -20186,88 +20191,88 @@ var MP = {
20186
20191
  name: l.name
20187
20192
  }]
20188
20193
  });
20189
- let n = ne.current;
20190
- o && n.kind === "reply" && n.message.id === o && h();
20194
+ let n = re.current;
20195
+ o && n.kind === "reply" && n.message.id === o && g();
20191
20196
  }
20192
20197
  } catch {
20193
- A(e.chat.fileUploadError);
20198
+ j(e.chat.fileUploadError);
20194
20199
  } finally {
20195
- ee(!1);
20200
+ te(!1);
20196
20201
  }
20197
20202
  }, [
20198
20203
  a,
20199
20204
  t,
20200
- h,
20201
- A,
20205
+ g,
20206
+ j,
20202
20207
  e.chat.fileUploadError
20203
- ]), L = CP({
20204
- searchMembers: d,
20205
- everyoneLabel: u.type === "group" ? e.chat.mentionEveryone : void 0
20206
- }), ie = K(({ mentions: t, mentionedEveryone: n }) => [...(t ?? []).map((e) => xP({
20208
+ ]), ie = CP({
20209
+ searchMembers: f,
20210
+ everyoneLabel: d.type === "group" ? e.chat.mentionEveryone : void 0
20211
+ }), R = K(({ mentions: t, mentionedEveryone: n }) => [...(t ?? []).map((e) => xP({
20207
20212
  id: e.id,
20208
20213
  name: e.name,
20209
20214
  avatar: e.avatar,
20210
20215
  subtitle: e.subtitle,
20211
20216
  profileHref: e.profileHref
20212
- })), ...n && u.type === "group" ? [xP({
20217
+ })), ...n && d.type === "group" ? [xP({
20213
20218
  id: _P,
20214
20219
  name: e.chat.mentionEveryone
20215
- })] : []], [u.type, e.chat.mentionEveryone]), R = PP({
20216
- getComposer: K(() => S.current, []),
20217
- isEditing: M,
20218
- toComposerMentions: ie
20219
- }), ae = K((e) => {
20220
- R.noteTextChange(), r(), e.trim().length === 0 && i?.();
20220
+ })] : []], [d.type, e.chat.mentionEveryone]), ae = PP({
20221
+ getComposer: K(() => C.current, []),
20222
+ isEditing: N,
20223
+ toComposerMentions: R
20224
+ }), oe = K((e) => {
20225
+ ae.noteTextChange(), r(), e.trim().length === 0 && i?.();
20221
20226
  }, [
20222
- R,
20227
+ ae,
20223
20228
  r,
20224
20229
  i
20225
20230
  ]);
20226
20231
  q(() => () => {
20227
20232
  i?.();
20228
20233
  }, [i]);
20229
- let oe = K((e) => {
20230
- D.current.delete(e) && URL.revokeObjectURL(e);
20234
+ let se = K((e) => {
20235
+ O.current.delete(e) && URL.revokeObjectURL(e);
20231
20236
  }, []);
20232
20237
  q(() => () => {
20233
- for (let e of D.current) URL.revokeObjectURL(e);
20234
- D.current.clear();
20238
+ for (let e of O.current) URL.revokeObjectURL(e);
20239
+ O.current.clear();
20235
20240
  }, []);
20236
- let se = C.some((e) => e.status === "uploading"), ce = J(() => [...C.filter(RP), ...C.filter((e) => !RP(e))], [C]), le = Y(0);
20241
+ let ce = w.some((e) => e.status === "uploading"), le = J(() => [...w.filter(RP), ...w.filter((e) => !RP(e))], [w]), ue = Y(0);
20237
20242
  q(() => {
20238
- le.current = C.length;
20239
- }, [C]);
20240
- let ue = K(async (t, n) => {
20241
- if (t.length === 0 || !a || !p) return;
20242
- if (j(), s !== void 0 && le.current + t.length > s) {
20243
- A(e.chat.tooManyFilesError.replace("{{maxFiles}}", String(s)));
20243
+ ue.current = w.length;
20244
+ }, [w]);
20245
+ let de = K(async (t, n) => {
20246
+ if (t.length === 0 || !a || !m) return;
20247
+ if (M(), s !== void 0 && ue.current + t.length > s) {
20248
+ j(e.chat.tooManyFilesError.replace("{{maxFiles}}", String(s)));
20244
20249
  return;
20245
20250
  }
20246
20251
  if (c !== void 0 && t.some((e) => e.size > c)) {
20247
- A(e.chat.fileTooLargeError.replace("{{maxFileSize}}", Oa(c)), { persistent: !0 });
20252
+ j(e.chat.fileTooLargeError.replace("{{maxFileSize}}", Oa(c))), l?.(t, c);
20248
20253
  return;
20249
20254
  }
20250
20255
  let r = t.map((e) => {
20251
20256
  let t = URL.createObjectURL(e);
20252
- return D.current.add(t), {
20253
- id: `att-${O.current++}`,
20257
+ return O.current.add(t), {
20258
+ id: `att-${k.current++}`,
20254
20259
  status: "uploading",
20255
20260
  attachment: zP(e, t)
20256
20261
  };
20257
20262
  });
20258
- for (let e of r) y.onFileAttached({
20263
+ for (let e of r) b.onFileAttached({
20259
20264
  kind: YD(e.attachment),
20260
20265
  source: n
20261
20266
  });
20262
- w((e) => [...e, ...r]);
20267
+ T((e) => [...e, ...r]);
20263
20268
  let i = new Set(r.map((e) => e.id));
20264
20269
  try {
20265
20270
  let e = (await a(t)).map((e, t) => ({
20266
- id: r[t]?.id ?? `att-${O.current++}`,
20271
+ id: r[t]?.id ?? `att-${k.current++}`,
20267
20272
  status: "ready",
20268
20273
  attachment: e
20269
20274
  }));
20270
- w((t) => {
20275
+ T((t) => {
20271
20276
  let n = new Map(e.map((e) => [e.id, e]));
20272
20277
  return t.flatMap((e) => {
20273
20278
  if (!i.has(e.id)) return [e];
@@ -20275,134 +20280,135 @@ var MP = {
20275
20280
  return t ? [t] : [];
20276
20281
  });
20277
20282
  });
20278
- for (let e of r) oe(e.attachment.url);
20283
+ for (let e of r) se(e.attachment.url);
20279
20284
  } catch {
20280
- w((e) => e.filter((e) => !i.has(e.id)));
20281
- for (let e of r) oe(e.attachment.url);
20282
- A(e.chat.fileUploadError);
20285
+ T((e) => e.filter((e) => !i.has(e.id)));
20286
+ for (let e of r) se(e.attachment.url);
20287
+ j(e.chat.fileUploadError);
20283
20288
  }
20284
20289
  }, [
20285
20290
  a,
20286
- p,
20291
+ m,
20287
20292
  s,
20288
20293
  c,
20294
+ l,
20295
+ M,
20289
20296
  j,
20290
- A,
20291
20297
  e.chat.tooManyFilesError,
20292
20298
  e.chat.fileTooLargeError,
20293
20299
  e.chat.fileUploadError,
20294
- oe,
20295
- y
20296
- ]), de = K((e) => {
20297
- let t = C.find((t) => t.id === e), n = t?.attachment;
20298
- n && n.kind !== "voice" && n.kind !== "location" && y.onAttachmentRemoved({ kind: YD(n) });
20299
- let r = C.some((t) => t.id !== e);
20300
- t?.status === "uploading" && oe(t.attachment.url), w((t) => t.filter((t) => t.id !== e)), requestAnimationFrame(() => {
20301
- r ? E.current?.focus() : S.current?.focus();
20300
+ se,
20301
+ b
20302
+ ]), fe = K((e) => {
20303
+ let t = w.find((t) => t.id === e), n = t?.attachment;
20304
+ n && n.kind !== "voice" && n.kind !== "location" && b.onAttachmentRemoved({ kind: YD(n) });
20305
+ let r = w.some((t) => t.id !== e);
20306
+ t?.status === "uploading" && se(t.attachment.url), T((t) => t.filter((t) => t.id !== e)), requestAnimationFrame(() => {
20307
+ r ? D.current?.focus() : C.current?.focus();
20302
20308
  });
20303
20309
  }, [
20304
- C,
20305
- oe,
20306
- y
20307
- ]), fe = K((e) => {
20308
- for (let t of e) t.status === "uploading" && oe(t.attachment.url);
20309
- }, [oe]);
20310
+ w,
20311
+ se,
20312
+ b
20313
+ ]), pe = K((e) => {
20314
+ for (let t of e) t.status === "uploading" && se(t.attachment.url);
20315
+ }, [se]);
20310
20316
  q(() => {
20311
- v((e) => void ue(e, "drop"));
20312
- }, [v, ue]);
20313
- let pe = K((e) => void ue(e, "paste"), [ue]), me = K(() => {
20314
- let e = S.current;
20315
- e?.cancelRecording(), e?.clear(), fe(C), w([]), e?.breakHistory();
20316
- }, [fe, C]), z = K((e) => {
20317
- w((t) => (fe(t), (e.attachments ?? []).filter((e) => e.kind !== "card").map((e) => ({
20318
- id: `att-${O.current++}`,
20317
+ y((e) => void de(e, "drop"));
20318
+ }, [y, de]);
20319
+ let me = K((e) => void de(e, "paste"), [de]), z = K(() => {
20320
+ let e = C.current;
20321
+ e?.cancelRecording(), e?.clear(), pe(w), T([]), e?.breakHistory();
20322
+ }, [pe, w]), he = K((e) => {
20323
+ T((t) => (pe(t), (e.attachments ?? []).filter((e) => e.kind !== "card").map((e) => ({
20324
+ id: `att-${k.current++}`,
20319
20325
  status: "ready",
20320
20326
  attachment: e
20321
- })))), S.current?.loadDraft({
20327
+ })))), C.current?.loadDraft({
20322
20328
  value: e.body,
20323
- mentions: ie(e)
20329
+ mentions: R(e)
20324
20330
  });
20325
- }, [ie, fe]), he = K((e, t) => {
20331
+ }, [R, pe]), ge = K((e, t) => {
20326
20332
  let n = e.kind === "edit" && t.kind !== "edit", r = e.kind === "edit" && t.kind === "edit" && e.message.id === t.message.id;
20327
- n && (me(), R.restore({ cleared: !0 })), t.kind === "edit" && !r && (e.kind !== "edit" && R.flush(), z(t.message)), t.kind !== "none" && S.current?.focus({ preventScroll: !0 });
20333
+ n && (z(), ae.restore({ cleared: !0 })), t.kind === "edit" && !r && (e.kind !== "edit" && ae.flush(), he(t.message)), t.kind !== "none" && C.current?.focus({ preventScroll: !0 });
20328
20334
  }, [
20329
- me,
20330
20335
  z,
20331
- R
20332
- ]), ge = J(() => ({
20333
- retarget: he,
20336
+ he,
20337
+ ae
20338
+ ]), _e = J(() => ({
20339
+ retarget: ge,
20334
20340
  abandonDraft: () => {
20335
- me(), R.restore({ cleared: !0 });
20341
+ z(), ae.restore({ cleared: !0 });
20336
20342
  }
20337
20343
  }), [
20338
- he,
20339
- me,
20340
- R
20344
+ ge,
20345
+ z,
20346
+ ae
20341
20347
  ]);
20342
20348
  q(function() {
20343
- return g(ge), () => g(null);
20344
- }, [g, ge]), q(function() {
20345
- return h;
20346
- }, [h]);
20347
- let _e = K(() => {
20348
- N && y.onEditCancelled({ messageId: N.id }), h();
20349
+ return _(_e), () => _(null);
20350
+ }, [_, _e]), q(function() {
20351
+ return g;
20352
+ }, [g]);
20353
+ let ve = K(() => {
20354
+ P && b.onEditCancelled({ messageId: P.id }), g();
20349
20355
  }, [
20350
- h,
20351
- N,
20352
- y
20353
- ]), ve = K(() => {
20354
- P && y.onReplyCancelled({ messageId: P.id }), h();
20356
+ g,
20357
+ P,
20358
+ b
20359
+ ]), ye = K(() => {
20360
+ F && b.onReplyCancelled({ messageId: F.id }), g();
20355
20361
  }, [
20356
- h,
20357
- y,
20358
- P
20359
- ]), ye = K(({ text: e, mentions: r }) => {
20362
+ g,
20363
+ b,
20364
+ F
20365
+ ]), be = K(({ text: e, mentions: r }) => {
20360
20366
  let a = e.trim();
20361
20367
  i?.();
20362
- let o = C.flatMap((e) => e.status === "ready" ? [e.attachment] : []), { mentions: s, mentionedEveryone: c } = wP(r);
20363
- N && n ? (n(N.id, {
20368
+ let o = w.flatMap((e) => e.status === "ready" ? [e.attachment] : []), { mentions: s, mentionedEveryone: c } = wP(r);
20369
+ P && n ? (n(P.id, {
20364
20370
  body: a,
20365
20371
  attachments: o.length > 0 ? o : void 0,
20366
20372
  mentions: s.length > 0 ? s : void 0,
20367
20373
  mentionedEveryone: c || void 0
20368
- }), h()) : (tl(u.id), R.noteSent(), t({
20374
+ }), g()) : (tl(d.id), ae.noteSent(), t({
20369
20375
  body: a,
20370
20376
  attachments: o.length > 0 ? o : void 0,
20371
- replyToId: P?.id,
20377
+ replyToId: F?.id,
20372
20378
  mentions: s.length > 0 ? s : void 0,
20373
20379
  mentionedEveryone: c || void 0
20374
- }), w([]), h());
20380
+ }), T([]), g());
20375
20381
  }, [
20376
- C,
20377
- u.id,
20378
- P,
20382
+ w,
20383
+ d.id,
20384
+ F,
20379
20385
  t,
20380
- h,
20386
+ g,
20381
20387
  i,
20382
- N,
20388
+ P,
20383
20389
  n,
20384
- R
20385
- ]), be = K((e) => m.kind !== "none" && (e.preventDefault(), M ? _e() : ve(), !0), [
20386
- m.kind,
20387
- M,
20388
- _e,
20389
- ve
20390
- ]), xe = K(() => C.length === 0 && m.kind === "none" && _(), [
20391
- C.length,
20392
- m.kind,
20393
- _
20394
- ]), Se = K((e) => {
20395
- S.current?.insertText(e), y.onEmojiInserted({
20390
+ ae
20391
+ ]), xe = K((e) => h.kind !== "none" && (e.preventDefault(), N ? ve() : ye(), !0), [
20392
+ h.kind,
20393
+ N,
20394
+ ve,
20395
+ ye
20396
+ ]), Se = K(() => w.length === 0 && h.kind === "none" && v(), [
20397
+ w.length,
20398
+ h.kind,
20399
+ v
20400
+ ]), Ce = K((e) => {
20401
+ C.current?.insertText(e), b.onEmojiInserted({
20396
20402
  emoji: e,
20397
20403
  source: "picker"
20398
20404
  });
20399
- }, [y]), Ce = {
20400
- duration: x ? 0 : .18,
20405
+ }, [b]), we = {
20406
+ duration: S ? 0 : .18,
20401
20407
  ease: Ga
20402
- }, we = /* @__PURE__ */ Q(jn, {
20408
+ }, Te = /* @__PURE__ */ Q(jn, {
20403
20409
  initial: !1,
20404
20410
  mode: "popLayout",
20405
- children: M && N ? /* @__PURE__ */ Q(V.div, {
20411
+ children: N && P ? /* @__PURE__ */ Q(V.div, {
20406
20412
  className: "overflow-hidden",
20407
20413
  initial: {
20408
20414
  height: 0,
@@ -20416,12 +20422,12 @@ var MP = {
20416
20422
  height: 0,
20417
20423
  opacity: 0
20418
20424
  },
20419
- transition: Ce,
20425
+ transition: we,
20420
20426
  children: /* @__PURE__ */ Q(hP, {
20421
- message: N,
20422
- onRemove: _e
20427
+ message: P,
20428
+ onRemove: ve
20423
20429
  })
20424
- }, "edit-chip") : P ? /* @__PURE__ */ Q(V.div, {
20430
+ }, "edit-chip") : F ? /* @__PURE__ */ Q(V.div, {
20425
20431
  className: "overflow-hidden",
20426
20432
  initial: {
20427
20433
  height: 0,
@@ -20435,33 +20441,33 @@ var MP = {
20435
20441
  height: 0,
20436
20442
  opacity: 0
20437
20443
  },
20438
- transition: Ce,
20444
+ transition: we,
20439
20445
  children: /* @__PURE__ */ Q(gP, {
20440
- message: P,
20441
- onRemove: ve
20446
+ message: F,
20447
+ onRemove: ye
20442
20448
  })
20443
20449
  }, "reply-chip") : null
20444
- }), Te = /* @__PURE__ */ Q(ui, {
20445
- items: ce.map((e) => ({
20450
+ }), Ee = /* @__PURE__ */ Q(ui, {
20451
+ items: le.map((e) => ({
20446
20452
  id: e.id,
20447
20453
  content: /* @__PURE__ */ Q(mP, {
20448
20454
  attachment: e.attachment,
20449
20455
  uploading: e.status === "uploading",
20450
- onRemove: () => de(e.id)
20456
+ onRemove: () => fe(e.id)
20451
20457
  })
20452
20458
  })),
20453
- label: e.t(C.length === 1 ? "chat.attachmentCount.one" : "chat.attachmentCount.other", { count: C.length }),
20454
- busy: se,
20455
- reducedMotion: x,
20456
- stripRef: E
20457
- }), Ee = (t) => /* @__PURE__ */ $(Z, { children: [
20459
+ label: e.t(w.length === 1 ? "chat.attachmentCount.one" : "chat.attachmentCount.other", { count: w.length }),
20460
+ busy: ce,
20461
+ reducedMotion: S,
20462
+ stripRef: D
20463
+ }), De = (t) => /* @__PURE__ */ $(Z, { children: [
20458
20464
  /* @__PURE__ */ Q("input", {
20459
- ref: T,
20465
+ ref: E,
20460
20466
  type: "file",
20461
20467
  multiple: !0,
20462
20468
  className: "hidden",
20463
20469
  onChange: (e) => {
20464
- ue(Array.from(e.target.files ?? []), "button"), e.target.value = "";
20470
+ de(Array.from(e.target.files ?? []), "button"), e.target.value = "";
20465
20471
  }
20466
20472
  }),
20467
20473
  /* @__PURE__ */ Q(er, {
@@ -20471,51 +20477,51 @@ var MP = {
20471
20477
  hideLabel: !0,
20472
20478
  label: e.chat.attachFile,
20473
20479
  icon: _r,
20474
- onClick: () => T.current?.click(),
20475
- disabled: !p || t === "transcribing"
20480
+ onClick: () => E.current?.click(),
20481
+ disabled: !m || t === "transcribing"
20476
20482
  }),
20477
20483
  /* @__PURE__ */ Q(Hv, {
20478
20484
  variant: "outline",
20479
20485
  size: "md",
20480
20486
  label: e.chat.addEmoji,
20481
- onSelect: Se
20487
+ onSelect: Ce
20482
20488
  })
20483
- ] }), De = l === void 0 ? void 0 : e.chat.messageTooLongError.replace("{{maxCharacters}}", l.toLocaleString());
20489
+ ] }), Oe = u === void 0 ? void 0 : e.chat.messageTooLongError.replace("{{maxCharacters}}", u.toLocaleString());
20484
20490
  return {
20485
- handleRef: S,
20491
+ handleRef: C,
20486
20492
  "data-testid": "chat-composer-surface",
20487
- onSend: ye,
20488
- sendKind: M ? "save" : "send",
20489
- hasAttachments: C.length > 0,
20490
- sendBlocked: se || I,
20491
- maxLength: l,
20492
- maxLengthError: De,
20493
- error: k,
20493
+ onSend: be,
20494
+ sendKind: N ? "save" : "send",
20495
+ hasAttachments: w.length > 0,
20496
+ sendBlocked: ce || ee,
20497
+ maxLength: u,
20498
+ maxLengthError: Oe,
20499
+ error: A,
20494
20500
  labels: { mentionPinnedDescription: e.chat.mentionEveryoneDescription },
20495
20501
  mentions: {
20496
- ...L,
20497
- scopeKey: u.id
20502
+ ...ie,
20503
+ scopeKey: d.id
20498
20504
  },
20499
20505
  autocomplete: MP,
20500
20506
  voice: {
20501
20507
  onTranscribe: o,
20502
- onAudio: F ? (e, t) => void re(e, t) : void 0,
20503
- disabled: BP(M, F),
20504
- busy: I,
20505
- onStarted: y.onVoiceRecordingStarted,
20506
- onCancelled: y.onVoiceRecordingCancelled
20508
+ onAudio: I ? (e, t) => void L(e, t) : void 0,
20509
+ disabled: BP(N, I),
20510
+ busy: ee,
20511
+ onStarted: b.onVoiceRecordingStarted,
20512
+ onCancelled: b.onVoiceRecordingCancelled
20507
20513
  },
20508
- onTextChange: ae,
20514
+ onTextChange: oe,
20509
20515
  onCleared: () => {
20510
- i?.(), R.noteTextChange();
20516
+ i?.(), ae.noteTextChange();
20511
20517
  },
20512
- onEscape: be,
20513
- onArrowUpWhenEmpty: xe,
20514
- onPasteFiles: p ? pe : void 0,
20515
- header: we,
20516
- tray: Te,
20517
- toolbarStart: Ee,
20518
- reducedMotion: x
20518
+ onEscape: xe,
20519
+ onArrowUpWhenEmpty: Se,
20520
+ onPasteFiles: m ? me : void 0,
20521
+ header: Te,
20522
+ tray: Ee,
20523
+ toolbarStart: De,
20524
+ reducedMotion: S
20519
20525
  };
20520
20526
  }, HP = (e) => e.dataTransfer?.types?.includes("Files"), UP = () => {
20521
20527
  let { dropFiles: e } = yO(), t = Y(0), [n, r] = X(!1), i = K((e) => HP(e) ? (e.preventDefault(), e.stopPropagation(), !0) : !1, []);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@factorialco/f0-react",
3
- "version": "12.2.0",
3
+ "version": "12.4.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/factorialco/f0.git",