@brainfish-ai/editor 0.16.2 → 0.16.4
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-BJKQPlcf.js → index-4Mg03NZ0.js} +2 -2
- package/dist/{index-BIHNHMyg.js → index-B44gf6lc.js} +2 -2
- package/dist/{index-CFr33LuW.js → index-B72hrXZp.js} +2 -2
- package/dist/{index-BQa2bres.js → index-BFdVwXxe.js} +2 -2
- package/dist/{index-DJWghCuI.js → index-BL3BrmJG.js} +518 -174
- package/dist/{index-DztBKea2.js → index-BdcQa21o.js} +2 -2
- package/dist/{index-DveiglG-.js → index-BiT1CaUK.js} +3 -3
- package/dist/{index-COD_xliD.js → index-BkpCLtjh.js} +4 -4
- package/dist/{index-D7noxe1h.js → index-BuU-LxbL.js} +3 -3
- package/dist/{index-DnpXm_wT.js → index-BzH29qwV.js} +4 -4
- package/dist/{index-C-bL3Cy9.js → index-C7heuyel.js} +3 -3
- package/dist/{index-dKic9ff-.js → index-CIzWSWLU.js} +1 -1
- package/dist/{index-BBMUH80b.js → index-Ce_sp8_S.js} +2 -2
- package/dist/{index-DsUx-yKw.js → index-Ck4GUp6S.js} +2 -2
- package/dist/{index-Dv14TLjz.js → index-CvcXtLfn.js} +3 -3
- package/dist/{index-Dk6UNQWp.js → index-DH5dBgli.js} +4 -4
- package/dist/{index-mEwvGwcX.js → index-DKpql_7V.js} +2 -2
- package/dist/{index-CsaeJbB5.js → index-DOSUqw2E.js} +2 -2
- package/dist/{index-CgzQ1jj0.js → index-DRSHBn8E.js} +2 -2
- package/dist/{index-paWgasj8.js → index-D_DH6CLj.js} +3 -3
- package/dist/{index-B4R1rT37.js → index-DnZLLzeC.js} +2 -2
- package/dist/{index-CyTfufcP.js → index-F6dIPhGZ.js} +2 -2
- package/dist/{index-LyNcRvuh.js → index-ImG4tGZ8.js} +2 -2
- package/dist/{index-DnbjsrWF.js → index-MGiiJ6ZI.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/markdown-source-editor/MarkdownSourceEditor.d.ts +2 -0
- package/dist/plugins/emoji/suggest.d.ts +3 -0
- package/dist/plugins/mentions/core/types.d.ts +7 -1
- package/dist/plugins/mentions/integration/slash-factory.d.ts +5 -0
- package/dist/plugins/mentions/integration/slash-keydown.d.ts +1 -0
- package/dist/plugins/mentions/ui/MentionSlashView.d.ts +1 -0
- package/dist/plugins/mentions/ui/filterMentionSlashRows.d.ts +16 -0
- package/dist/plugins/mentions/ui/loadMentionSlashMenu.d.ts +9 -0
- package/dist/plugins/mentions/ui/mentionSlashMenuState.d.ts +57 -0
- package/dist/plugins/mentions/ui/runtime.d.ts +5 -0
- package/dist/plugins/mentions/ui/useMentionSlashMenu.d.ts +8 -11
- package/dist/stories/mentionBreakFixtures.d.ts +11 -0
- package/dist/stories/storybook-utils.d.ts +4 -0
- package/dist/types.d.ts +8 -0
- package/package.json +3 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment as Fragment$2 } from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import React__default, { createContext, useRef, useState, useMemo, useContext, useCallback, useLayoutEffect, useEffect, useId, Suspense, lazy } from 'react';
|
|
3
|
+
import React__default, { createContext, useRef, useState, useMemo, useContext, useCallback, useLayoutEffect, useEffect, useReducer, useId, Suspense, lazy } from 'react';
|
|
4
4
|
import clsx from 'clsx';
|
|
5
5
|
import { BrainfishColors } from '@brainfish-ai/components/colors';
|
|
6
6
|
import * as Y from 'yjs';
|
|
@@ -8,7 +8,7 @@ import { UndoManager, Item as Item$1, ContentType, Text as Text$2, XmlElement, e
|
|
|
8
8
|
import { flushSync, createPortal } from 'react-dom';
|
|
9
9
|
import katex from 'katex';
|
|
10
10
|
import { renderToStaticMarkup } from 'react-dom/server';
|
|
11
|
-
import { Plus, Trash, SquaresFour, Warning,
|
|
11
|
+
import { Plus, Trash, SquaresFour, Warning, CaretLeft, CaretRight, ArrowSquareOut, Info, Star, File as File$1, MagicWand, YoutubeLogo, Browser, X, Video, Paperclip, DownloadSimple, TextHOne, TextHSix, TextHFive, TextHFour, TextHThree, TextHTwo, Highlighter, ListBullets, ListNumbers, Link as Link$1, Eye, CodeSimple } from '@phosphor-icons/react';
|
|
12
12
|
import { Button } from '@brainfish-ai/components/ui/button';
|
|
13
13
|
import { Input } from '@brainfish-ai/components/ui/input';
|
|
14
14
|
import { ButtonGroup } from '@brainfish-ai/components/ui/button-group';
|
|
@@ -16,7 +16,7 @@ import { SimpleSelect } from '@brainfish-ai/components/select';
|
|
|
16
16
|
import { Tooltip, TooltipTrigger, TooltipContent } from '@brainfish-ai/components/ui/tooltip';
|
|
17
17
|
import { Command, CommandInput, CommandList, CommandGroup, CommandItem } from '@brainfish-ai/components/ui/command';
|
|
18
18
|
import { Popover, PopoverTrigger, PopoverContent } from '@brainfish-ai/components/ui/popover';
|
|
19
|
-
import { Card,
|
|
19
|
+
import { Card, CardContent, CardFooter } from '@brainfish-ai/components/ui/card';
|
|
20
20
|
import { Textarea } from '@brainfish-ai/components/ui/textarea';
|
|
21
21
|
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@brainfish-ai/components/ui/tabs';
|
|
22
22
|
|
|
@@ -41745,9 +41745,11 @@ function configureMentionStringify(crepe) {
|
|
|
41745
41745
|
}
|
|
41746
41746
|
|
|
41747
41747
|
const emptyRef = { current: [] };
|
|
41748
|
+
const emptyFooterButtonClickRef = { current: void 0 };
|
|
41748
41749
|
const MentionsRuntimeContext = createContext({
|
|
41749
41750
|
providersRef: emptyRef,
|
|
41750
|
-
providers: []
|
|
41751
|
+
providers: [],
|
|
41752
|
+
onFooterButtonClickRef: emptyFooterButtonClickRef
|
|
41751
41753
|
});
|
|
41752
41754
|
function useMentionsRuntime() {
|
|
41753
41755
|
return useContext(MentionsRuntimeContext);
|
|
@@ -41760,6 +41762,10 @@ function findMentionProvider(providers, type) {
|
|
|
41760
41762
|
return providers.find((provider) => provider.type === type);
|
|
41761
41763
|
}
|
|
41762
41764
|
|
|
41765
|
+
function pillIcon(provider, refId) {
|
|
41766
|
+
const match = provider?.candidates?.find((row) => row.id === refId);
|
|
41767
|
+
return match?.icon ?? provider?.typeIcon;
|
|
41768
|
+
}
|
|
41763
41769
|
const MENTION_PILL_CLASS = "bf-mention-pill";
|
|
41764
41770
|
function selectAdjacentMention(view, event) {
|
|
41765
41771
|
if (event.shiftKey || event.metaKey || event.ctrlKey || event.altKey) return false;
|
|
@@ -41829,7 +41835,7 @@ const MentionNodeView = () => {
|
|
|
41829
41835
|
attrs: flattenMentionAttrs(parsed)
|
|
41830
41836
|
})
|
|
41831
41837
|
);
|
|
41832
|
-
const TypeIcon = provider
|
|
41838
|
+
const TypeIcon = pillIcon(provider, provider ? parsed.extra[provider.refAttr] : void 0);
|
|
41833
41839
|
const canPreview = Boolean(provider?.onClick);
|
|
41834
41840
|
const [open, setOpen] = useState(false);
|
|
41835
41841
|
const [content, setContent] = useState(null);
|
|
@@ -41858,6 +41864,7 @@ const MentionNodeView = () => {
|
|
|
41858
41864
|
className: clsx(
|
|
41859
41865
|
MENTION_PILL_CLASS,
|
|
41860
41866
|
"inline-flex relative top-0.5 items-center gap-1 rounded-full px-2 py-0.5 h-6 text-sm font-medium align-baseline",
|
|
41867
|
+
"max-w-64 min-w-0",
|
|
41861
41868
|
{ "bg-purple-800 text-purple-100 ring-purple-300": !invalid },
|
|
41862
41869
|
{ "bg-warning text-warning border border-warning ring-yellow-500": invalid },
|
|
41863
41870
|
{ "!ring-2": selected }
|
|
@@ -41878,8 +41885,16 @@ const MentionNodeView = () => {
|
|
|
41878
41885
|
moveCaretOffMention(view, pos, node.nodeSize, event.key);
|
|
41879
41886
|
},
|
|
41880
41887
|
children: [
|
|
41881
|
-
invalid ? /* @__PURE__ */ jsx(Warning, { size: 16, weight: "regular", "data-testid": "mention-pill-warning" }) : TypeIcon ? /* @__PURE__ */ jsx(
|
|
41882
|
-
|
|
41888
|
+
invalid ? /* @__PURE__ */ jsx(Warning, { size: 16, weight: "regular", className: "shrink-0", "data-testid": "mention-pill-warning" }) : TypeIcon ? /* @__PURE__ */ jsx(
|
|
41889
|
+
TypeIcon,
|
|
41890
|
+
{
|
|
41891
|
+
size: 16,
|
|
41892
|
+
weight: provider?.iconWeight ?? "regular",
|
|
41893
|
+
className: "shrink-0",
|
|
41894
|
+
"data-testid": "mention-pill-type-icon"
|
|
41895
|
+
}
|
|
41896
|
+
) : null,
|
|
41897
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", title: parsed.label || parsed.type, children: parsed.label || parsed.type })
|
|
41883
41898
|
]
|
|
41884
41899
|
}
|
|
41885
41900
|
) }),
|
|
@@ -41917,6 +41932,30 @@ function configureMentionNodeView(ctx, nodeViewFactory) {
|
|
|
41917
41932
|
]);
|
|
41918
41933
|
}
|
|
41919
41934
|
|
|
41935
|
+
const ALL_MENTION_GROUP = "all";
|
|
41936
|
+
function filterMentionSlashRows(rows, activeGroup) {
|
|
41937
|
+
if (activeGroup === ALL_MENTION_GROUP) return rows;
|
|
41938
|
+
return rows.filter((row) => row.groupLabel === activeGroup);
|
|
41939
|
+
}
|
|
41940
|
+
function resolveMentionSlashGroup(rows, activeGroup) {
|
|
41941
|
+
if (activeGroup === ALL_MENTION_GROUP) return ALL_MENTION_GROUP;
|
|
41942
|
+
return rows.some((row) => row.groupLabel === activeGroup) ? activeGroup : ALL_MENTION_GROUP;
|
|
41943
|
+
}
|
|
41944
|
+
function mentionSlashTabIds(rows) {
|
|
41945
|
+
const labels = [ALL_MENTION_GROUP];
|
|
41946
|
+
for (const row of rows) {
|
|
41947
|
+
if (!labels.includes(row.groupLabel)) labels.push(row.groupLabel);
|
|
41948
|
+
}
|
|
41949
|
+
return labels;
|
|
41950
|
+
}
|
|
41951
|
+
function cycleMentionSlashGroup(tabIds, current, direction) {
|
|
41952
|
+
if (!tabIds.length) return ALL_MENTION_GROUP;
|
|
41953
|
+
const resolved = tabIds.includes(current) ? current : ALL_MENTION_GROUP;
|
|
41954
|
+
const index = tabIds.indexOf(resolved);
|
|
41955
|
+
const delta = direction === "next" ? 1 : -1;
|
|
41956
|
+
return tabIds[(index + delta + tabIds.length) % tabIds.length] ?? ALL_MENTION_GROUP;
|
|
41957
|
+
}
|
|
41958
|
+
|
|
41920
41959
|
//#region src/slash-plugin.ts
|
|
41921
41960
|
function slashFactory(id) {
|
|
41922
41961
|
const slashSpec = $ctx({}, `${id}_SLASH_SPEC`);
|
|
@@ -42712,7 +42751,10 @@ const mentionSlashApi = $ctx(
|
|
|
42712
42751
|
isOpen: () => false,
|
|
42713
42752
|
nav: () => {
|
|
42714
42753
|
},
|
|
42754
|
+
navGroup: () => {
|
|
42755
|
+
},
|
|
42715
42756
|
pick: () => false,
|
|
42757
|
+
focusFooterButton: () => false,
|
|
42716
42758
|
dismiss: () => {
|
|
42717
42759
|
}
|
|
42718
42760
|
},
|
|
@@ -42781,34 +42823,135 @@ function firstSlashMessage(providers, kind) {
|
|
|
42781
42823
|
return null;
|
|
42782
42824
|
}
|
|
42783
42825
|
|
|
42826
|
+
async function loadMentionSlashMenu(providers, query, signal) {
|
|
42827
|
+
const decision = decideSlashFetch(providers);
|
|
42828
|
+
if (decision.kind === "loading") return { type: "retry" };
|
|
42829
|
+
if (decision.kind === "not-connected") {
|
|
42830
|
+
return { type: "not-connected", content: firstSlashMessage(providers, "not-connected") };
|
|
42831
|
+
}
|
|
42832
|
+
try {
|
|
42833
|
+
const settled = await Promise.allSettled(
|
|
42834
|
+
decision.ready.map(async (provider) => {
|
|
42835
|
+
const items = query ? await provider.search({ query, signal }) : await provider.list({ limit: 5, signal });
|
|
42836
|
+
return items.map(
|
|
42837
|
+
(item) => ({
|
|
42838
|
+
...item,
|
|
42839
|
+
type: item.type || provider.type,
|
|
42840
|
+
groupLabel: provider.groupLabel,
|
|
42841
|
+
refAttr: provider.refAttr,
|
|
42842
|
+
provider
|
|
42843
|
+
})
|
|
42844
|
+
);
|
|
42845
|
+
})
|
|
42846
|
+
);
|
|
42847
|
+
if (signal.aborted) return { type: "retry" };
|
|
42848
|
+
const outcome = decideSlashFetchResult(settled);
|
|
42849
|
+
if (outcome === "error") {
|
|
42850
|
+
return { type: "error", content: firstSlashMessage(providers, "error") };
|
|
42851
|
+
}
|
|
42852
|
+
return {
|
|
42853
|
+
type: "loaded",
|
|
42854
|
+
rows: settled.flatMap((result) => result.status === "fulfilled" ? result.value : []),
|
|
42855
|
+
status: outcome
|
|
42856
|
+
};
|
|
42857
|
+
} catch (error) {
|
|
42858
|
+
if (signal.aborted) return { type: "retry" };
|
|
42859
|
+
if (error instanceof DOMException && error.name === "AbortError") return { type: "retry" };
|
|
42860
|
+
return { type: "error", content: firstSlashMessage(providers, "error") };
|
|
42861
|
+
}
|
|
42862
|
+
}
|
|
42863
|
+
|
|
42864
|
+
const initialMentionSlashMenuState = {
|
|
42865
|
+
open: false,
|
|
42866
|
+
query: "",
|
|
42867
|
+
status: "loading",
|
|
42868
|
+
slashContent: null,
|
|
42869
|
+
rows: [],
|
|
42870
|
+
selectedIndex: 0,
|
|
42871
|
+
activeGroup: ALL_MENTION_GROUP
|
|
42872
|
+
};
|
|
42873
|
+
function mentionSlashMenuReducer(state, action) {
|
|
42874
|
+
switch (action.type) {
|
|
42875
|
+
case "show": {
|
|
42876
|
+
const queryChanged = state.query !== action.query;
|
|
42877
|
+
if (state.open && !queryChanged) return state;
|
|
42878
|
+
return {
|
|
42879
|
+
...state,
|
|
42880
|
+
open: true,
|
|
42881
|
+
query: action.query,
|
|
42882
|
+
...queryChanged ? {
|
|
42883
|
+
activeGroup: ALL_MENTION_GROUP,
|
|
42884
|
+
selectedIndex: 0,
|
|
42885
|
+
status: "loading",
|
|
42886
|
+
rows: [],
|
|
42887
|
+
slashContent: null
|
|
42888
|
+
} : {}
|
|
42889
|
+
};
|
|
42890
|
+
}
|
|
42891
|
+
case "hide":
|
|
42892
|
+
return initialMentionSlashMenuState;
|
|
42893
|
+
case "loading":
|
|
42894
|
+
return { ...state, status: "loading", slashContent: null, rows: [] };
|
|
42895
|
+
case "not-connected":
|
|
42896
|
+
return { ...state, status: "not-connected", slashContent: action.content, rows: [] };
|
|
42897
|
+
case "error":
|
|
42898
|
+
return { ...state, status: "error", slashContent: action.content, rows: [] };
|
|
42899
|
+
case "loaded":
|
|
42900
|
+
return {
|
|
42901
|
+
...state,
|
|
42902
|
+
rows: action.rows,
|
|
42903
|
+
status: action.status,
|
|
42904
|
+
slashContent: null,
|
|
42905
|
+
selectedIndex: 0,
|
|
42906
|
+
activeGroup: resolveMentionSlashGroup(action.rows, state.activeGroup)
|
|
42907
|
+
};
|
|
42908
|
+
case "select":
|
|
42909
|
+
return { ...state, selectedIndex: action.index };
|
|
42910
|
+
case "setGroup":
|
|
42911
|
+
return { ...state, activeGroup: action.group, selectedIndex: 0 };
|
|
42912
|
+
case "nav": {
|
|
42913
|
+
const visible = visibleMentionSlashRows(state);
|
|
42914
|
+
if (!visible.length) return state;
|
|
42915
|
+
const next = action.direction === "next" ? (state.selectedIndex + 1) % visible.length : (state.selectedIndex - 1 + visible.length) % visible.length;
|
|
42916
|
+
return { ...state, selectedIndex: next };
|
|
42917
|
+
}
|
|
42918
|
+
case "navGroup":
|
|
42919
|
+
return {
|
|
42920
|
+
...state,
|
|
42921
|
+
activeGroup: cycleMentionSlashGroup(
|
|
42922
|
+
mentionSlashTabIds(state.rows),
|
|
42923
|
+
resolveMentionSlashGroup(state.rows, state.activeGroup),
|
|
42924
|
+
action.direction
|
|
42925
|
+
),
|
|
42926
|
+
selectedIndex: 0
|
|
42927
|
+
};
|
|
42928
|
+
}
|
|
42929
|
+
}
|
|
42930
|
+
function visibleMentionSlashRows(state) {
|
|
42931
|
+
return filterMentionSlashRows(state.rows, resolveMentionSlashGroup(state.rows, state.activeGroup));
|
|
42932
|
+
}
|
|
42933
|
+
function resolvedMentionSlashGroup(state) {
|
|
42934
|
+
return resolveMentionSlashGroup(state.rows, state.activeGroup);
|
|
42935
|
+
}
|
|
42936
|
+
|
|
42784
42937
|
const SEARCH_DEBOUNCE_MS = 200;
|
|
42785
42938
|
const AVAILABILITY_RECHECK_MS = 200;
|
|
42786
42939
|
function useMentionSlashMenu() {
|
|
42787
42940
|
const { view } = usePluginViewContext();
|
|
42788
42941
|
const { getInstance, loading } = useEditorAction();
|
|
42789
|
-
const { providersRef } = useMentionsRuntime();
|
|
42942
|
+
const { providersRef, onFooterButtonClickRef } = useMentionsRuntime();
|
|
42790
42943
|
const contentRef = useRef(null);
|
|
42944
|
+
const listRef = useRef(null);
|
|
42791
42945
|
const providerRef = useRef(null);
|
|
42792
42946
|
const viewRef = useRef(view);
|
|
42793
42947
|
viewRef.current = view;
|
|
42794
|
-
const listRef = useRef(null);
|
|
42795
|
-
const [open, setOpen] = useState(false);
|
|
42796
|
-
const [query, setQuery] = useState("");
|
|
42797
|
-
const [status, setStatus] = useState("loading");
|
|
42798
|
-
const [slashContent, setSlashContent] = useState(null);
|
|
42799
|
-
const [rows, setRows] = useState([]);
|
|
42800
|
-
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
42801
|
-
const [availabilityTick, setAvailabilityTick] = useState(0);
|
|
42802
42948
|
const fromToRef = useRef({ from: 0, to: 0 });
|
|
42803
|
-
const rowsRef = useRef(rows);
|
|
42804
|
-
rowsRef.current = rows;
|
|
42805
|
-
const selectedIndexRef = useRef(selectedIndex);
|
|
42806
|
-
selectedIndexRef.current = selectedIndex;
|
|
42807
|
-
const statusRef = useRef(status);
|
|
42808
|
-
statusRef.current = status;
|
|
42809
|
-
const openRef = useRef(open);
|
|
42810
|
-
openRef.current = open;
|
|
42811
42949
|
const hostRef = useRef(null);
|
|
42950
|
+
const [state, dispatch] = useReducer(mentionSlashMenuReducer, initialMentionSlashMenuState);
|
|
42951
|
+
const stateRef = useRef(state);
|
|
42952
|
+
stateRef.current = state;
|
|
42953
|
+
const visibleRows = visibleMentionSlashRows(state);
|
|
42954
|
+
const activeGroup = resolvedMentionSlashGroup(state);
|
|
42812
42955
|
useLayoutEffect(() => {
|
|
42813
42956
|
const el = contentRef.current;
|
|
42814
42957
|
if (el?.parentElement && el.parentElement !== document.body) {
|
|
@@ -42823,10 +42966,11 @@ function useMentionSlashMenu() {
|
|
|
42823
42966
|
};
|
|
42824
42967
|
}, []);
|
|
42825
42968
|
const pickRef = useRef(() => false);
|
|
42826
|
-
pickRef.current = () => {
|
|
42827
|
-
const
|
|
42969
|
+
pickRef.current = (index) => {
|
|
42970
|
+
const current = stateRef.current;
|
|
42971
|
+
const row = visibleMentionSlashRows(current)[index ?? current.selectedIndex];
|
|
42828
42972
|
const editorView = viewRef.current;
|
|
42829
|
-
if (
|
|
42973
|
+
if (current.status !== "ready") return false;
|
|
42830
42974
|
if (!row || !editorView || !editorView.editable) return false;
|
|
42831
42975
|
const inserted = insertMentionInView(editorView, fromToRef.current.from, fromToRef.current.to, row, row.provider);
|
|
42832
42976
|
if (inserted) providerRef.current?.hide();
|
|
@@ -42842,141 +42986,187 @@ function useMentionSlashMenu() {
|
|
|
42842
42986
|
root: document.body,
|
|
42843
42987
|
floatingUIOptions: { strategy: "fixed" },
|
|
42844
42988
|
shouldShow(editorView) {
|
|
42989
|
+
if (contentRef.current?.contains(document.activeElement)) return true;
|
|
42845
42990
|
if (!editorView.editable) return false;
|
|
42846
42991
|
if (!providersRef.current.length) return false;
|
|
42847
42992
|
const trigger = findMentionTrigger(editorView.state);
|
|
42848
42993
|
if (!trigger) return false;
|
|
42849
42994
|
fromToRef.current = { from: trigger.from, to: trigger.to };
|
|
42850
|
-
queueMicrotask(() => {
|
|
42851
|
-
setQuery(trigger.query);
|
|
42852
|
-
setOpen(true);
|
|
42853
|
-
});
|
|
42995
|
+
queueMicrotask(() => dispatch({ type: "show", query: trigger.query }));
|
|
42854
42996
|
return true;
|
|
42855
42997
|
}
|
|
42856
42998
|
});
|
|
42857
42999
|
slashProvider.onHide = () => {
|
|
42858
|
-
queueMicrotask(() => {
|
|
42859
|
-
setOpen(false);
|
|
42860
|
-
setRows([]);
|
|
42861
|
-
setSlashContent(null);
|
|
42862
|
-
setStatus("loading");
|
|
42863
|
-
});
|
|
43000
|
+
queueMicrotask(() => dispatch({ type: "hide" }));
|
|
42864
43001
|
};
|
|
42865
43002
|
providerRef.current = slashProvider;
|
|
42866
43003
|
const onNativeMouseDown = (event) => {
|
|
42867
43004
|
if (!viewRef.current?.editable) return;
|
|
42868
|
-
const
|
|
43005
|
+
const target = event.target instanceof Element ? event.target : null;
|
|
43006
|
+
const tabNav = target?.closest("[data-mention-tab-nav]");
|
|
43007
|
+
if (tabNav) {
|
|
43008
|
+
event.preventDefault();
|
|
43009
|
+
event.stopPropagation();
|
|
43010
|
+
const direction = tabNav.getAttribute("data-mention-tab-nav");
|
|
43011
|
+
if (direction === "next" || direction === "prev") dispatch({ type: "navGroup", direction });
|
|
43012
|
+
return;
|
|
43013
|
+
}
|
|
43014
|
+
const tab = target?.closest("[data-mention-group]");
|
|
43015
|
+
if (tab) {
|
|
43016
|
+
event.preventDefault();
|
|
43017
|
+
event.stopPropagation();
|
|
43018
|
+
const group = tab.getAttribute("data-mention-group");
|
|
43019
|
+
if (group) dispatch({ type: "setGroup", group });
|
|
43020
|
+
return;
|
|
43021
|
+
}
|
|
43022
|
+
const option = target?.closest("[data-mention-option-index]");
|
|
42869
43023
|
if (!option) return;
|
|
42870
43024
|
event.preventDefault();
|
|
42871
43025
|
event.stopPropagation();
|
|
42872
43026
|
const index = Number(option.getAttribute("data-mention-option-index"));
|
|
42873
43027
|
if (!Number.isFinite(index)) return;
|
|
42874
|
-
|
|
42875
|
-
|
|
42876
|
-
|
|
43028
|
+
dispatch({ type: "select", index });
|
|
43029
|
+
pickRef.current(index);
|
|
43030
|
+
};
|
|
43031
|
+
const onNativeKeyDown = (event) => {
|
|
43032
|
+
const target = event.target instanceof Element ? event.target : null;
|
|
43033
|
+
if (!target?.closest('[data-testid="mention-slash-footer-button"]')) return;
|
|
43034
|
+
if (event.key === "Escape") {
|
|
43035
|
+
event.preventDefault();
|
|
43036
|
+
event.stopPropagation();
|
|
43037
|
+
viewRef.current?.focus();
|
|
43038
|
+
providerRef.current?.hide();
|
|
43039
|
+
return;
|
|
43040
|
+
}
|
|
43041
|
+
if (event.key === "Tab") {
|
|
43042
|
+
event.preventDefault();
|
|
43043
|
+
viewRef.current?.focus();
|
|
43044
|
+
}
|
|
43045
|
+
};
|
|
43046
|
+
const onNativeClick = (event) => {
|
|
43047
|
+
const target = event.target instanceof Element ? event.target : null;
|
|
43048
|
+
if (!target?.closest('[data-testid="mention-slash-footer-button"]')) return;
|
|
43049
|
+
onFooterButtonClickRef.current?.();
|
|
42877
43050
|
};
|
|
42878
43051
|
content.addEventListener("mousedown", onNativeMouseDown);
|
|
43052
|
+
content.addEventListener("keydown", onNativeKeyDown);
|
|
43053
|
+
content.addEventListener("click", onNativeClick);
|
|
42879
43054
|
return () => {
|
|
42880
43055
|
content.removeEventListener("mousedown", onNativeMouseDown);
|
|
43056
|
+
content.removeEventListener("keydown", onNativeKeyDown);
|
|
43057
|
+
content.removeEventListener("click", onNativeClick);
|
|
42881
43058
|
slashProvider.destroy();
|
|
42882
43059
|
providerRef.current = null;
|
|
42883
43060
|
};
|
|
42884
|
-
}, [view, providersRef]);
|
|
43061
|
+
}, [view, providersRef, onFooterButtonClickRef]);
|
|
43062
|
+
const prevEditorStateRef = useRef(void 0);
|
|
42885
43063
|
useEffect(() => {
|
|
42886
43064
|
if (!view || !providerRef.current) return;
|
|
42887
|
-
providerRef.current.update(view);
|
|
43065
|
+
providerRef.current.update(view, prevEditorStateRef.current);
|
|
43066
|
+
prevEditorStateRef.current = view.state;
|
|
42888
43067
|
});
|
|
42889
43068
|
useEffect(() => {
|
|
42890
|
-
if (!open) return;
|
|
43069
|
+
if (!state.open) return;
|
|
42891
43070
|
const abort = new AbortController();
|
|
42892
43071
|
let recheckTimer;
|
|
42893
|
-
const
|
|
42894
|
-
const
|
|
42895
|
-
|
|
42896
|
-
if (
|
|
42897
|
-
|
|
42898
|
-
|
|
42899
|
-
|
|
42900
|
-
|
|
43072
|
+
const load = async () => {
|
|
43073
|
+
const result = await loadMentionSlashMenu(providersRef.current, state.query, abort.signal);
|
|
43074
|
+
if (abort.signal.aborted) return;
|
|
43075
|
+
if (result.type === "retry") {
|
|
43076
|
+
dispatch({ type: "loading" });
|
|
43077
|
+
recheckTimer = setTimeout(() => {
|
|
43078
|
+
void load();
|
|
43079
|
+
}, AVAILABILITY_RECHECK_MS);
|
|
42901
43080
|
return;
|
|
42902
43081
|
}
|
|
42903
|
-
|
|
42904
|
-
|
|
42905
|
-
|
|
42906
|
-
setStatus("not-connected");
|
|
42907
|
-
return;
|
|
42908
|
-
}
|
|
42909
|
-
setSlashContent(null);
|
|
42910
|
-
setStatus("loading");
|
|
42911
|
-
try {
|
|
42912
|
-
const settled = await Promise.allSettled(
|
|
42913
|
-
decision.ready.map(async (provider) => {
|
|
42914
|
-
const items = query ? await provider.search({ query, signal: abort.signal }) : await provider.list({ limit: 5, signal: abort.signal });
|
|
42915
|
-
return items.map((item) => ({
|
|
42916
|
-
...item,
|
|
42917
|
-
type: item.type || provider.type,
|
|
42918
|
-
groupLabel: provider.groupLabel,
|
|
42919
|
-
refAttr: provider.refAttr,
|
|
42920
|
-
provider
|
|
42921
|
-
}));
|
|
42922
|
-
})
|
|
42923
|
-
);
|
|
42924
|
-
if (abort.signal.aborted) return;
|
|
42925
|
-
const outcome = decideSlashFetchResult(settled);
|
|
42926
|
-
if (outcome === "error") {
|
|
42927
|
-
setRows([]);
|
|
42928
|
-
setSlashContent(firstSlashMessage(providers, "error"));
|
|
42929
|
-
setStatus("error");
|
|
42930
|
-
return;
|
|
42931
|
-
}
|
|
42932
|
-
const next = settled.flatMap((result) => result.status === "fulfilled" ? result.value : []);
|
|
42933
|
-
setRows(next);
|
|
42934
|
-
setSelectedIndex(0);
|
|
42935
|
-
setSlashContent(null);
|
|
42936
|
-
setStatus(outcome);
|
|
42937
|
-
} catch (error) {
|
|
42938
|
-
if (abort.signal.aborted) return;
|
|
42939
|
-
if (error instanceof DOMException && error.name === "AbortError") return;
|
|
42940
|
-
setRows([]);
|
|
42941
|
-
setSlashContent(firstSlashMessage(providersRef.current, "error"));
|
|
42942
|
-
setStatus("error");
|
|
42943
|
-
}
|
|
42944
|
-
}, SEARCH_DEBOUNCE_MS);
|
|
43082
|
+
dispatch(result);
|
|
43083
|
+
};
|
|
43084
|
+
const run = debounce(load, SEARCH_DEBOUNCE_MS);
|
|
42945
43085
|
void run();
|
|
42946
43086
|
return () => {
|
|
42947
43087
|
abort.abort();
|
|
42948
43088
|
run.cancel();
|
|
42949
43089
|
clearTimeout(recheckTimer);
|
|
42950
43090
|
};
|
|
42951
|
-
}, [open, query, providersRef
|
|
43091
|
+
}, [state.open, state.query, providersRef]);
|
|
42952
43092
|
useEffect(() => {
|
|
42953
43093
|
const ctx = getInstance()?.ctx;
|
|
42954
43094
|
if (!ctx) return;
|
|
42955
43095
|
ctx.set(mentionSlashApi.key, {
|
|
42956
|
-
isOpen: () =>
|
|
42957
|
-
nav: (direction) => {
|
|
42958
|
-
|
|
42959
|
-
if (!items.length) return;
|
|
42960
|
-
setSelectedIndex((index) => direction === "next" ? (index + 1) % items.length : (index - 1 + items.length) % items.length);
|
|
42961
|
-
},
|
|
43096
|
+
isOpen: () => stateRef.current.open,
|
|
43097
|
+
nav: (direction) => dispatch({ type: "nav", direction }),
|
|
43098
|
+
navGroup: (direction) => dispatch({ type: "navGroup", direction }),
|
|
42962
43099
|
pick: () => pickRef.current(),
|
|
43100
|
+
focusFooterButton: () => {
|
|
43101
|
+
const button = contentRef.current?.querySelector('[data-testid="mention-slash-footer-button"]');
|
|
43102
|
+
if (!button) return false;
|
|
43103
|
+
button.focus({ focusVisible: true });
|
|
43104
|
+
return true;
|
|
43105
|
+
},
|
|
42963
43106
|
dismiss: () => providerRef.current?.hide()
|
|
42964
43107
|
});
|
|
42965
43108
|
}, [getInstance, loading]);
|
|
42966
43109
|
useLayoutEffect(() => {
|
|
42967
43110
|
listRef.current?.querySelector('[data-selected="true"]')?.scrollIntoView({ block: "nearest" });
|
|
42968
|
-
}, [selectedIndex]);
|
|
42969
|
-
return {
|
|
43111
|
+
}, [state.selectedIndex]);
|
|
43112
|
+
return {
|
|
43113
|
+
contentRef,
|
|
43114
|
+
listRef,
|
|
43115
|
+
open: state.open,
|
|
43116
|
+
query: state.query,
|
|
43117
|
+
status: state.status,
|
|
43118
|
+
slashContent: state.slashContent,
|
|
43119
|
+
rows: state.rows,
|
|
43120
|
+
visibleRows,
|
|
43121
|
+
selectedIndex: state.selectedIndex,
|
|
43122
|
+
activeGroup,
|
|
43123
|
+
setActiveGroup: (group) => dispatch({ type: "setGroup", group })
|
|
43124
|
+
};
|
|
42970
43125
|
}
|
|
42971
43126
|
|
|
42972
43127
|
const MentionSlashView = () => {
|
|
42973
|
-
const {
|
|
42974
|
-
const
|
|
42975
|
-
|
|
42976
|
-
|
|
42977
|
-
|
|
42978
|
-
|
|
42979
|
-
|
|
43128
|
+
const { footerButtonLabel } = useMentionsRuntime();
|
|
43129
|
+
const {
|
|
43130
|
+
contentRef,
|
|
43131
|
+
listRef,
|
|
43132
|
+
open,
|
|
43133
|
+
query,
|
|
43134
|
+
status,
|
|
43135
|
+
slashContent,
|
|
43136
|
+
rows,
|
|
43137
|
+
visibleRows,
|
|
43138
|
+
selectedIndex,
|
|
43139
|
+
activeGroup,
|
|
43140
|
+
setActiveGroup
|
|
43141
|
+
} = useMentionSlashMenu();
|
|
43142
|
+
const grouped = groupRows(visibleRows);
|
|
43143
|
+
const tabGroups = groupRows(rows);
|
|
43144
|
+
const activeId = visibleRows[selectedIndex] ? `bf-mention-opt-${selectedIndex}` : void 0;
|
|
43145
|
+
const tabsRef = useRef(null);
|
|
43146
|
+
const [canScrollLeft, setCanScrollLeft] = useState(false);
|
|
43147
|
+
const [canScrollRight, setCanScrollRight] = useState(false);
|
|
43148
|
+
const measureTabs = useCallback(() => {
|
|
43149
|
+
const node = tabsRef.current;
|
|
43150
|
+
if (!node) return;
|
|
43151
|
+
setCanScrollLeft(node.scrollLeft > 1);
|
|
43152
|
+
setCanScrollRight(node.scrollLeft + node.clientWidth < node.scrollWidth - 1);
|
|
43153
|
+
}, []);
|
|
43154
|
+
useLayoutEffect(() => {
|
|
43155
|
+
const node = tabsRef.current;
|
|
43156
|
+
if (!node) return;
|
|
43157
|
+
measureTabs();
|
|
43158
|
+
const observer = new ResizeObserver(measureTabs);
|
|
43159
|
+
observer.observe(node);
|
|
43160
|
+
node.addEventListener("scroll", measureTabs, { passive: true });
|
|
43161
|
+
return () => {
|
|
43162
|
+
observer.disconnect();
|
|
43163
|
+
node.removeEventListener("scroll", measureTabs);
|
|
43164
|
+
};
|
|
43165
|
+
}, [tabGroups, open, status, measureTabs]);
|
|
43166
|
+
useLayoutEffect(() => {
|
|
43167
|
+
const tab = tabsRef.current?.querySelector(`[data-mention-group="${CSS.escape(activeGroup)}"]`);
|
|
43168
|
+
tab?.scrollIntoView({ inline: "nearest", block: "nearest", behavior: "smooth" });
|
|
43169
|
+
}, [activeGroup]);
|
|
42980
43170
|
return /* @__PURE__ */ jsx(
|
|
42981
43171
|
"div",
|
|
42982
43172
|
{
|
|
@@ -42991,26 +43181,78 @@ const MentionSlashView = () => {
|
|
|
42991
43181
|
role: "listbox",
|
|
42992
43182
|
"aria-label": "Mentions",
|
|
42993
43183
|
"aria-activedescendant": activeId,
|
|
42994
|
-
className: "text-xs p-1.5 w-
|
|
43184
|
+
className: "text-xs p-1.5 w-80 max-w-full min-w-0 overflow-hidden",
|
|
42995
43185
|
children: [
|
|
42996
43186
|
status === "loading" && /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-muted-foreground", children: "Loading…" }),
|
|
42997
43187
|
(status === "error" || status === "not-connected") && /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-muted-foreground", children: slashContent }),
|
|
42998
|
-
status === "empty" && /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-muted-foreground", children: "No matches" }),
|
|
43188
|
+
status === "empty" && /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-muted-foreground", children: query.trim() ? "No matches" : "No mentions yet" }),
|
|
42999
43189
|
status === "ready" && /* @__PURE__ */ jsxs(Fragment$2, { children: [
|
|
43000
|
-
/* @__PURE__ */
|
|
43001
|
-
/* @__PURE__ */
|
|
43002
|
-
|
|
43003
|
-
|
|
43004
|
-
|
|
43005
|
-
|
|
43190
|
+
/* @__PURE__ */ jsxs("div", { className: "relative min-w-0 max-w-full overflow-hidden border-b border-border", children: [
|
|
43191
|
+
/* @__PURE__ */ jsxs(
|
|
43192
|
+
"div",
|
|
43193
|
+
{
|
|
43194
|
+
ref: tabsRef,
|
|
43195
|
+
className: "flex w-full min-w-0 flex-nowrap overflow-x-auto overflow-y-hidden scroll-smooth [scrollbar-width:none]",
|
|
43196
|
+
children: [
|
|
43197
|
+
/* @__PURE__ */ jsx(
|
|
43198
|
+
GroupTab,
|
|
43199
|
+
{
|
|
43200
|
+
groupId: ALL_MENTION_GROUP,
|
|
43201
|
+
label: "All",
|
|
43202
|
+
count: rows.length,
|
|
43203
|
+
selected: activeGroup === ALL_MENTION_GROUP,
|
|
43204
|
+
onSelect: () => setActiveGroup(ALL_MENTION_GROUP)
|
|
43205
|
+
}
|
|
43206
|
+
),
|
|
43207
|
+
tabGroups.map((group) => /* @__PURE__ */ jsx(
|
|
43208
|
+
GroupTab,
|
|
43209
|
+
{
|
|
43210
|
+
groupId: group.label,
|
|
43211
|
+
label: group.label,
|
|
43212
|
+
count: group.rows.length,
|
|
43213
|
+
selected: activeGroup === group.label,
|
|
43214
|
+
onSelect: () => setActiveGroup(group.label)
|
|
43215
|
+
},
|
|
43216
|
+
group.label
|
|
43217
|
+
))
|
|
43218
|
+
]
|
|
43219
|
+
}
|
|
43220
|
+
),
|
|
43221
|
+
canScrollLeft ? /* @__PURE__ */ jsxs(Fragment$2, { children: [
|
|
43222
|
+
/* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-y-0 left-0 w-8 bg-gradient-to-r from-card to-transparent" }),
|
|
43223
|
+
/* @__PURE__ */ jsx(
|
|
43224
|
+
"button",
|
|
43225
|
+
{
|
|
43226
|
+
type: "button",
|
|
43227
|
+
"aria-label": "Previous mention group",
|
|
43228
|
+
"data-mention-tab-nav": "prev",
|
|
43229
|
+
className: "absolute inset-y-0 left-0 z-10 px-0.5 text-muted-foreground",
|
|
43230
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
43231
|
+
children: /* @__PURE__ */ jsx(CaretLeft, { size: 14 })
|
|
43232
|
+
}
|
|
43233
|
+
)
|
|
43234
|
+
] }) : null,
|
|
43235
|
+
canScrollRight ? /* @__PURE__ */ jsxs(Fragment$2, { children: [
|
|
43236
|
+
/* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-y-0 right-0 w-8 bg-gradient-to-l from-card to-transparent" }),
|
|
43237
|
+
/* @__PURE__ */ jsx(
|
|
43238
|
+
"button",
|
|
43239
|
+
{
|
|
43240
|
+
type: "button",
|
|
43241
|
+
"aria-label": "Next mention group",
|
|
43242
|
+
"data-mention-tab-nav": "next",
|
|
43243
|
+
className: "absolute inset-y-0 right-0 z-10 px-0.5 text-muted-foreground",
|
|
43244
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
43245
|
+
children: /* @__PURE__ */ jsx(CaretRight, { size: 14 })
|
|
43246
|
+
}
|
|
43247
|
+
)
|
|
43006
43248
|
] }) : null
|
|
43007
|
-
] })
|
|
43249
|
+
] }),
|
|
43008
43250
|
/* @__PURE__ */ jsx(CardContent, { className: "p-0 max-h-72 overflow-y-auto", children: grouped.map((group, groupIndex) => /* @__PURE__ */ jsxs("div", { children: [
|
|
43009
|
-
grouped.length > 1 && /* @__PURE__ */ jsx("div", { className: "px-2 py-1 text-xs text-muted-foreground", children: group.label }),
|
|
43251
|
+
activeGroup === ALL_MENTION_GROUP && grouped.length > 1 && /* @__PURE__ */ jsx("div", { className: "px-2 py-1 text-xs text-muted-foreground truncate", title: group.label, children: group.label }),
|
|
43010
43252
|
group.rows.map((row) => {
|
|
43011
|
-
const index =
|
|
43253
|
+
const index = visibleRows.indexOf(row);
|
|
43012
43254
|
const selected = index === selectedIndex;
|
|
43013
|
-
const TypeIcon = row.provider.typeIcon;
|
|
43255
|
+
const TypeIcon = row.icon ?? row.provider.typeIcon;
|
|
43014
43256
|
return /* @__PURE__ */ jsxs(
|
|
43015
43257
|
"div",
|
|
43016
43258
|
{
|
|
@@ -43019,25 +43261,37 @@ const MentionSlashView = () => {
|
|
|
43019
43261
|
"aria-selected": selected,
|
|
43020
43262
|
"data-selected": selected ? "true" : void 0,
|
|
43021
43263
|
"data-mention-option-index": index,
|
|
43022
|
-
className: `cursor-pointer
|
|
43264
|
+
className: `cursor-pointer flex min-w-0 items-center gap-2 p-2 ${selected ? "bg-dark-200" : ""}`,
|
|
43023
43265
|
children: [
|
|
43266
|
+
/* @__PURE__ */ jsx(TypeIcon, { size: 16, weight: "fill", className: "shrink-0 text-subtle" }),
|
|
43024
43267
|
/* @__PURE__ */ jsx(
|
|
43025
43268
|
"span",
|
|
43026
43269
|
{
|
|
43027
|
-
className:
|
|
43028
|
-
|
|
43270
|
+
className: "min-w-0 flex-1 font-semibold text-sm overflow-hidden text-ellipsis whitespace-nowrap",
|
|
43271
|
+
title: row.label,
|
|
43272
|
+
children: row.label
|
|
43029
43273
|
}
|
|
43030
|
-
)
|
|
43031
|
-
/* @__PURE__ */ jsx("span", { className: "font-semibold text-sm overflow-hidden text-ellipsis whitespace-nowrap", children: row.label }),
|
|
43032
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-subtlest whitespace-nowrap tabular-nums", children: row.inputCount ? `${row.inputCount} inputs` : null }),
|
|
43033
|
-
row.description ? /* @__PURE__ */ jsx("span", { className: "col-start-2 col-span-2 text-xs text-subtlest overflow-hidden text-ellipsis whitespace-nowrap", children: row.description }) : null
|
|
43274
|
+
)
|
|
43034
43275
|
]
|
|
43035
43276
|
},
|
|
43036
43277
|
`${row.type}-${row.id}-${index}`
|
|
43037
43278
|
);
|
|
43038
43279
|
})
|
|
43039
43280
|
] }, `${group.label}-${groupIndex}`)) }),
|
|
43040
|
-
/* @__PURE__ */ jsx(CardFooter, { className: "p-2 pb-1 border-t border-border", children: /* @__PURE__ */
|
|
43281
|
+
/* @__PURE__ */ jsx(CardFooter, { className: "p-2 pb-1 border-t border-border min-w-0", children: /* @__PURE__ */ jsxs(
|
|
43282
|
+
Button,
|
|
43283
|
+
{
|
|
43284
|
+
type: "button",
|
|
43285
|
+
variant: "link",
|
|
43286
|
+
size: "sm",
|
|
43287
|
+
className: "h-auto max-w-full min-w-0 p-0 text-lime-700 font-normal whitespace-nowrap",
|
|
43288
|
+
"data-testid": "mention-slash-footer-button",
|
|
43289
|
+
children: [
|
|
43290
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: footerButtonLabel ?? "Create a workflow" }),
|
|
43291
|
+
/* @__PURE__ */ jsx(ArrowSquareOut, { size: 14, className: "shrink-0" })
|
|
43292
|
+
]
|
|
43293
|
+
}
|
|
43294
|
+
) })
|
|
43041
43295
|
] })
|
|
43042
43296
|
]
|
|
43043
43297
|
}
|
|
@@ -43045,6 +43299,33 @@ const MentionSlashView = () => {
|
|
|
43045
43299
|
}
|
|
43046
43300
|
);
|
|
43047
43301
|
};
|
|
43302
|
+
function GroupTab({
|
|
43303
|
+
groupId,
|
|
43304
|
+
label,
|
|
43305
|
+
count,
|
|
43306
|
+
selected,
|
|
43307
|
+
onSelect
|
|
43308
|
+
}) {
|
|
43309
|
+
return /* @__PURE__ */ jsxs(
|
|
43310
|
+
"button",
|
|
43311
|
+
{
|
|
43312
|
+
type: "button",
|
|
43313
|
+
"aria-pressed": selected,
|
|
43314
|
+
"data-mention-group": groupId,
|
|
43315
|
+
"data-testid": `mention-slash-tab-${label}`,
|
|
43316
|
+
title: label,
|
|
43317
|
+
className: `relative shrink-0 scroll-mx-8 px-2 py-1.5 text-sm whitespace-nowrap flex items-center gap-1 ${selected ? "text-foreground font-semibold" : "text-subtlest"}`,
|
|
43318
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
43319
|
+
onClick: onSelect,
|
|
43320
|
+
children: [
|
|
43321
|
+
label,
|
|
43322
|
+
" ",
|
|
43323
|
+
/* @__PURE__ */ jsx("span", { className: "text-subtlest px-1.5 rounded-full bg-dark-200 text-xs tabular-nums shrink-0", children: count }),
|
|
43324
|
+
selected ? /* @__PURE__ */ jsx("span", { className: "absolute inset-x-2 bottom-0 h-0.5 rounded-sm bg-foreground" }) : null
|
|
43325
|
+
]
|
|
43326
|
+
}
|
|
43327
|
+
);
|
|
43328
|
+
}
|
|
43048
43329
|
function groupRows(rows) {
|
|
43049
43330
|
const groups = [];
|
|
43050
43331
|
for (const row of rows) {
|
|
@@ -43072,11 +43353,22 @@ function mentionSlashKeydown(ctx) {
|
|
|
43072
43353
|
event.preventDefault();
|
|
43073
43354
|
api.nav("prev");
|
|
43074
43355
|
return true;
|
|
43356
|
+
case "ArrowRight":
|
|
43357
|
+
event.preventDefault();
|
|
43358
|
+
api.navGroup("next");
|
|
43359
|
+
return true;
|
|
43360
|
+
case "ArrowLeft":
|
|
43361
|
+
event.preventDefault();
|
|
43362
|
+
api.navGroup("prev");
|
|
43363
|
+
return true;
|
|
43075
43364
|
case "Enter":
|
|
43076
|
-
case "Tab":
|
|
43077
43365
|
event.preventDefault();
|
|
43078
43366
|
api.pick();
|
|
43079
43367
|
return true;
|
|
43368
|
+
case "Tab":
|
|
43369
|
+
event.preventDefault();
|
|
43370
|
+
if (!event.shiftKey) api.focusFooterButton();
|
|
43371
|
+
return true;
|
|
43080
43372
|
case "Escape":
|
|
43081
43373
|
event.preventDefault();
|
|
43082
43374
|
api.dismiss();
|
|
@@ -70113,7 +70405,7 @@ function legacy(parser) {
|
|
|
70113
70405
|
return new LanguageSupport(StreamLanguage.define(parser));
|
|
70114
70406
|
}
|
|
70115
70407
|
function sql(dialectName) {
|
|
70116
|
-
return import('./index-
|
|
70408
|
+
return import('./index-MGiiJ6ZI.js').then(m => m.sql({ dialect: m[dialectName] }));
|
|
70117
70409
|
}
|
|
70118
70410
|
/**
|
|
70119
70411
|
An array of language descriptions for known language packages.
|
|
@@ -70124,7 +70416,7 @@ const languages = [
|
|
|
70124
70416
|
name: "C",
|
|
70125
70417
|
extensions: ["c", "h", "ino"],
|
|
70126
70418
|
load() {
|
|
70127
|
-
return import('./index-
|
|
70419
|
+
return import('./index-DOSUqw2E.js').then(m => m.cpp());
|
|
70128
70420
|
}
|
|
70129
70421
|
}),
|
|
70130
70422
|
/*@__PURE__*/LanguageDescription.of({
|
|
@@ -70132,7 +70424,7 @@ const languages = [
|
|
|
70132
70424
|
alias: ["cpp"],
|
|
70133
70425
|
extensions: ["cpp", "c++", "cc", "cxx", "hpp", "h++", "hh", "hxx"],
|
|
70134
70426
|
load() {
|
|
70135
|
-
return import('./index-
|
|
70427
|
+
return import('./index-DOSUqw2E.js').then(m => m.cpp());
|
|
70136
70428
|
}
|
|
70137
70429
|
}),
|
|
70138
70430
|
/*@__PURE__*/LanguageDescription.of({
|
|
@@ -70145,14 +70437,14 @@ const languages = [
|
|
|
70145
70437
|
name: "CSS",
|
|
70146
70438
|
extensions: ["css"],
|
|
70147
70439
|
load() {
|
|
70148
|
-
return import('./index-
|
|
70440
|
+
return import('./index-DKpql_7V.js').then(m => m.css());
|
|
70149
70441
|
}
|
|
70150
70442
|
}),
|
|
70151
70443
|
/*@__PURE__*/LanguageDescription.of({
|
|
70152
70444
|
name: "Go",
|
|
70153
70445
|
extensions: ["go"],
|
|
70154
70446
|
load() {
|
|
70155
|
-
return import('./index-
|
|
70447
|
+
return import('./index-BFdVwXxe.js').then(m => m.go());
|
|
70156
70448
|
}
|
|
70157
70449
|
}),
|
|
70158
70450
|
/*@__PURE__*/LanguageDescription.of({
|
|
@@ -70160,14 +70452,14 @@ const languages = [
|
|
|
70160
70452
|
alias: ["xhtml"],
|
|
70161
70453
|
extensions: ["html", "htm", "handlebars", "hbs"],
|
|
70162
70454
|
load() {
|
|
70163
|
-
return import('./index-
|
|
70455
|
+
return import('./index-DH5dBgli.js').then(m => m.html());
|
|
70164
70456
|
}
|
|
70165
70457
|
}),
|
|
70166
70458
|
/*@__PURE__*/LanguageDescription.of({
|
|
70167
70459
|
name: "Java",
|
|
70168
70460
|
extensions: ["java"],
|
|
70169
70461
|
load() {
|
|
70170
|
-
return import('./index-
|
|
70462
|
+
return import('./index-Ce_sp8_S.js').then(m => m.java());
|
|
70171
70463
|
}
|
|
70172
70464
|
}),
|
|
70173
70465
|
/*@__PURE__*/LanguageDescription.of({
|
|
@@ -70175,14 +70467,14 @@ const languages = [
|
|
|
70175
70467
|
alias: ["ecmascript", "js", "node"],
|
|
70176
70468
|
extensions: ["js", "mjs", "cjs"],
|
|
70177
70469
|
load() {
|
|
70178
|
-
return import('./index-
|
|
70470
|
+
return import('./index-B44gf6lc.js').then(m => m.javascript());
|
|
70179
70471
|
}
|
|
70180
70472
|
}),
|
|
70181
70473
|
/*@__PURE__*/LanguageDescription.of({
|
|
70182
70474
|
name: "Jinja",
|
|
70183
70475
|
extensions: ["j2", "jinja", "jinja2"],
|
|
70184
70476
|
load() {
|
|
70185
|
-
return import('./index-
|
|
70477
|
+
return import('./index-D_DH6CLj.js').then(m => m.jinja());
|
|
70186
70478
|
}
|
|
70187
70479
|
}),
|
|
70188
70480
|
/*@__PURE__*/LanguageDescription.of({
|
|
@@ -70190,28 +70482,28 @@ const languages = [
|
|
|
70190
70482
|
alias: ["json5"],
|
|
70191
70483
|
extensions: ["json", "map"],
|
|
70192
70484
|
load() {
|
|
70193
|
-
return import('./index-
|
|
70485
|
+
return import('./index-DnZLLzeC.js').then(m => m.json());
|
|
70194
70486
|
}
|
|
70195
70487
|
}),
|
|
70196
70488
|
/*@__PURE__*/LanguageDescription.of({
|
|
70197
70489
|
name: "JSX",
|
|
70198
70490
|
extensions: ["jsx"],
|
|
70199
70491
|
load() {
|
|
70200
|
-
return import('./index-
|
|
70492
|
+
return import('./index-B44gf6lc.js').then(m => m.javascript({ jsx: true }));
|
|
70201
70493
|
}
|
|
70202
70494
|
}),
|
|
70203
70495
|
/*@__PURE__*/LanguageDescription.of({
|
|
70204
70496
|
name: "LESS",
|
|
70205
70497
|
extensions: ["less"],
|
|
70206
70498
|
load() {
|
|
70207
|
-
return import('./index-
|
|
70499
|
+
return import('./index-C7heuyel.js').then(m => m.less());
|
|
70208
70500
|
}
|
|
70209
70501
|
}),
|
|
70210
70502
|
/*@__PURE__*/LanguageDescription.of({
|
|
70211
70503
|
name: "Liquid",
|
|
70212
70504
|
extensions: ["liquid"],
|
|
70213
70505
|
load() {
|
|
70214
|
-
return import('./index-
|
|
70506
|
+
return import('./index-CvcXtLfn.js').then(m => m.liquid());
|
|
70215
70507
|
}
|
|
70216
70508
|
}),
|
|
70217
70509
|
/*@__PURE__*/LanguageDescription.of({
|
|
@@ -70222,7 +70514,7 @@ const languages = [
|
|
|
70222
70514
|
name: "Markdown",
|
|
70223
70515
|
extensions: ["md", "markdown", "mkd"],
|
|
70224
70516
|
load() {
|
|
70225
|
-
return import('./index-
|
|
70517
|
+
return import('./index-ImG4tGZ8.js').then(m => m.markdown());
|
|
70226
70518
|
}
|
|
70227
70519
|
}),
|
|
70228
70520
|
/*@__PURE__*/LanguageDescription.of({
|
|
@@ -70237,7 +70529,7 @@ const languages = [
|
|
|
70237
70529
|
name: "PHP",
|
|
70238
70530
|
extensions: ["php", "php3", "php4", "php5", "php7", "phtml"],
|
|
70239
70531
|
load() {
|
|
70240
|
-
return import('./index-
|
|
70532
|
+
return import('./index-BiT1CaUK.js').then(m => m.php());
|
|
70241
70533
|
}
|
|
70242
70534
|
}),
|
|
70243
70535
|
/*@__PURE__*/LanguageDescription.of({
|
|
@@ -70254,28 +70546,28 @@ const languages = [
|
|
|
70254
70546
|
extensions: ["BUILD", "bzl", "py", "pyw"],
|
|
70255
70547
|
filename: /^(BUCK|BUILD)$/,
|
|
70256
70548
|
load() {
|
|
70257
|
-
return import('./index-
|
|
70549
|
+
return import('./index-Ck4GUp6S.js').then(m => m.python());
|
|
70258
70550
|
}
|
|
70259
70551
|
}),
|
|
70260
70552
|
/*@__PURE__*/LanguageDescription.of({
|
|
70261
70553
|
name: "Rust",
|
|
70262
70554
|
extensions: ["rs"],
|
|
70263
70555
|
load() {
|
|
70264
|
-
return import('./index-
|
|
70556
|
+
return import('./index-F6dIPhGZ.js').then(m => m.rust());
|
|
70265
70557
|
}
|
|
70266
70558
|
}),
|
|
70267
70559
|
/*@__PURE__*/LanguageDescription.of({
|
|
70268
70560
|
name: "Sass",
|
|
70269
70561
|
extensions: ["sass"],
|
|
70270
70562
|
load() {
|
|
70271
|
-
return import('./index-
|
|
70563
|
+
return import('./index-BuU-LxbL.js').then(m => m.sass({ indented: true }));
|
|
70272
70564
|
}
|
|
70273
70565
|
}),
|
|
70274
70566
|
/*@__PURE__*/LanguageDescription.of({
|
|
70275
70567
|
name: "SCSS",
|
|
70276
70568
|
extensions: ["scss"],
|
|
70277
70569
|
load() {
|
|
70278
|
-
return import('./index-
|
|
70570
|
+
return import('./index-BuU-LxbL.js').then(m => m.sass());
|
|
70279
70571
|
}
|
|
70280
70572
|
}),
|
|
70281
70573
|
/*@__PURE__*/LanguageDescription.of({
|
|
@@ -70291,7 +70583,7 @@ const languages = [
|
|
|
70291
70583
|
name: "TSX",
|
|
70292
70584
|
extensions: ["tsx"],
|
|
70293
70585
|
load() {
|
|
70294
|
-
return import('./index-
|
|
70586
|
+
return import('./index-B44gf6lc.js').then(m => m.javascript({ jsx: true, typescript: true }));
|
|
70295
70587
|
}
|
|
70296
70588
|
}),
|
|
70297
70589
|
/*@__PURE__*/LanguageDescription.of({
|
|
@@ -70299,14 +70591,14 @@ const languages = [
|
|
|
70299
70591
|
alias: ["ts"],
|
|
70300
70592
|
extensions: ["ts", "mts", "cts"],
|
|
70301
70593
|
load() {
|
|
70302
|
-
return import('./index-
|
|
70594
|
+
return import('./index-B44gf6lc.js').then(m => m.javascript({ typescript: true }));
|
|
70303
70595
|
}
|
|
70304
70596
|
}),
|
|
70305
70597
|
/*@__PURE__*/LanguageDescription.of({
|
|
70306
70598
|
name: "WebAssembly",
|
|
70307
70599
|
extensions: ["wat", "wast"],
|
|
70308
70600
|
load() {
|
|
70309
|
-
return import('./index-
|
|
70601
|
+
return import('./index-4Mg03NZ0.js').then(m => m.wast());
|
|
70310
70602
|
}
|
|
70311
70603
|
}),
|
|
70312
70604
|
/*@__PURE__*/LanguageDescription.of({
|
|
@@ -70314,7 +70606,7 @@ const languages = [
|
|
|
70314
70606
|
alias: ["rss", "wsdl", "xsd"],
|
|
70315
70607
|
extensions: ["xml", "xsl", "xsd", "svg"],
|
|
70316
70608
|
load() {
|
|
70317
|
-
return import('./index-
|
|
70609
|
+
return import('./index-B72hrXZp.js').then(m => m.xml());
|
|
70318
70610
|
}
|
|
70319
70611
|
}),
|
|
70320
70612
|
/*@__PURE__*/LanguageDescription.of({
|
|
@@ -70322,7 +70614,7 @@ const languages = [
|
|
|
70322
70614
|
alias: ["yml"],
|
|
70323
70615
|
extensions: ["yaml", "yml"],
|
|
70324
70616
|
load() {
|
|
70325
|
-
return import('./index-
|
|
70617
|
+
return import('./index-BdcQa21o.js').then(m => m.yaml());
|
|
70326
70618
|
}
|
|
70327
70619
|
}),
|
|
70328
70620
|
// Legacy modes ported from CodeMirror 5
|
|
@@ -71111,13 +71403,13 @@ const languages = [
|
|
|
71111
71403
|
name: "Vue",
|
|
71112
71404
|
extensions: ["vue"],
|
|
71113
71405
|
load() {
|
|
71114
|
-
return import('./index-
|
|
71406
|
+
return import('./index-BkpCLtjh.js').then(m => m.vue());
|
|
71115
71407
|
}
|
|
71116
71408
|
}),
|
|
71117
71409
|
/*@__PURE__*/LanguageDescription.of({
|
|
71118
71410
|
name: "Angular Template",
|
|
71119
71411
|
load() {
|
|
71120
|
-
return import('./index-
|
|
71412
|
+
return import('./index-BzH29qwV.js').then(m => m.angular());
|
|
71121
71413
|
}
|
|
71122
71414
|
})
|
|
71123
71415
|
];
|
|
@@ -121927,6 +122219,7 @@ const emojiSuggestProsePlugin = $prose((ctx) => {
|
|
|
121927
122219
|
selectedIndex = prev.selectedIndex;
|
|
121928
122220
|
if (nav === "next") selectedIndex = (selectedIndex + 1) % items.length;
|
|
121929
122221
|
if (nav === "prev") selectedIndex = (selectedIndex - 1 + items.length) % items.length;
|
|
122222
|
+
if (typeof nav === "number") selectedIndex = Math.min(Math.max(0, nav), items.length - 1);
|
|
121930
122223
|
}
|
|
121931
122224
|
return {
|
|
121932
122225
|
active: true,
|
|
@@ -121970,6 +122263,13 @@ const emojiSuggestProsePlugin = $prose((ctx) => {
|
|
|
121970
122263
|
}
|
|
121971
122264
|
});
|
|
121972
122265
|
});
|
|
122266
|
+
function setEmojiSuggestIndex(view, index) {
|
|
122267
|
+
view.dispatch(view.state.tr.setMeta(emojiSuggestNavMeta, index));
|
|
122268
|
+
}
|
|
122269
|
+
function insertEmojiFromSuggest(ctx, from, to, emoji) {
|
|
122270
|
+
const view = ctx.get(editorViewCtx);
|
|
122271
|
+
insertPicked(view, ctx, from, to, emoji);
|
|
122272
|
+
}
|
|
121973
122273
|
|
|
121974
122274
|
const EMOJI_TOOLTIP_NAME = "emoji-suggest";
|
|
121975
122275
|
const emojiTooltip = tooltipFactory("BRAINFISH_EMOJI");
|
|
@@ -121992,6 +122292,10 @@ function tooltipPosition(view, panel) {
|
|
|
121992
122292
|
const top = above ? coords.top - r.top - GAP : coords.bottom - r.top + GAP;
|
|
121993
122293
|
return { top, left, above };
|
|
121994
122294
|
}
|
|
122295
|
+
function optionIndex(target) {
|
|
122296
|
+
const raw = target.closest?.("[data-index]")?.getAttribute("data-index");
|
|
122297
|
+
return raw == null ? null : Number(raw);
|
|
122298
|
+
}
|
|
121995
122299
|
const EmojiTooltipView = () => {
|
|
121996
122300
|
const { view } = usePluginViewContext();
|
|
121997
122301
|
const { getInstance } = useEditorAction();
|
|
@@ -122017,17 +122321,43 @@ const EmojiTooltipView = () => {
|
|
|
122017
122321
|
left: pos.left,
|
|
122018
122322
|
transform: pos.above ? "translateY(-100%)" : void 0
|
|
122019
122323
|
},
|
|
122020
|
-
children: /* @__PURE__ */ jsx("div", { className: "menu-groups", children: /* @__PURE__ */ jsx("div", { className: "menu-group", children: /* @__PURE__ */ jsx(
|
|
122021
|
-
|
|
122022
|
-
|
|
122023
|
-
|
|
122024
|
-
|
|
122025
|
-
|
|
122026
|
-
|
|
122027
|
-
|
|
122028
|
-
|
|
122029
|
-
|
|
122030
|
-
|
|
122324
|
+
children: /* @__PURE__ */ jsx("div", { className: "menu-groups", children: /* @__PURE__ */ jsx("div", { className: "menu-group", children: /* @__PURE__ */ jsx(
|
|
122325
|
+
"ul",
|
|
122326
|
+
{
|
|
122327
|
+
role: "listbox",
|
|
122328
|
+
onMouseMove: (event) => {
|
|
122329
|
+
const index = optionIndex(event.target);
|
|
122330
|
+
if (index !== null && index !== panel.selectedIndex && view) setEmojiSuggestIndex(view, index);
|
|
122331
|
+
},
|
|
122332
|
+
onMouseDown: (event) => {
|
|
122333
|
+
event.preventDefault();
|
|
122334
|
+
const index = optionIndex(event.target);
|
|
122335
|
+
const item = index === null ? void 0 : panel.items[index];
|
|
122336
|
+
if (item) insertEmojiFromSuggest(ctx, panel.from, panel.to, item.emoji);
|
|
122337
|
+
},
|
|
122338
|
+
children: panel.items.map((item, index) => {
|
|
122339
|
+
const selected = index === panel.selectedIndex;
|
|
122340
|
+
return /* @__PURE__ */ jsxs(
|
|
122341
|
+
"li",
|
|
122342
|
+
{
|
|
122343
|
+
role: "option",
|
|
122344
|
+
"aria-selected": selected,
|
|
122345
|
+
"data-index": index,
|
|
122346
|
+
className: selected ? "hover" : void 0,
|
|
122347
|
+
children: [
|
|
122348
|
+
/* @__PURE__ */ jsx("span", { className: "text-lg leading-none", "aria-hidden": true, children: item.emoji }),
|
|
122349
|
+
/* @__PURE__ */ jsxs("span", { className: "truncate opacity-80", children: [
|
|
122350
|
+
":",
|
|
122351
|
+
item.name,
|
|
122352
|
+
":"
|
|
122353
|
+
] })
|
|
122354
|
+
]
|
|
122355
|
+
},
|
|
122356
|
+
`${item.name}-${index}`
|
|
122357
|
+
);
|
|
122358
|
+
})
|
|
122359
|
+
}
|
|
122360
|
+
) }) })
|
|
122031
122361
|
}
|
|
122032
122362
|
);
|
|
122033
122363
|
};
|
|
@@ -124232,6 +124562,7 @@ function setupCollabContentChange(crepe, onContentChangeRef, localEditPendingRef
|
|
|
124232
124562
|
});
|
|
124233
124563
|
}
|
|
124234
124564
|
|
|
124565
|
+
const SLASH_MENU_SELECTOR = `.milkdown-slash-menu:not([data-name="${EMOJI_TOOLTIP_NAME}"])`;
|
|
124235
124566
|
function useSlashMenuPortal(container) {
|
|
124236
124567
|
const reactId = useId();
|
|
124237
124568
|
const portalRootId = `bf-slash-menu-portal-${reactId.replace(/:/g, "")}`;
|
|
@@ -124276,8 +124607,8 @@ function useSlashMenuPortal(container) {
|
|
|
124276
124607
|
return portalRoot;
|
|
124277
124608
|
};
|
|
124278
124609
|
const portalSlashMenu = () => {
|
|
124279
|
-
const existing = document.getElementById(portalRootId)?.querySelector(
|
|
124280
|
-
const menu = container.querySelector(
|
|
124610
|
+
const existing = document.getElementById(portalRootId)?.querySelector(SLASH_MENU_SELECTOR);
|
|
124611
|
+
const menu = container.querySelector(SLASH_MENU_SELECTOR) ?? (existing instanceof HTMLElement ? existing : null);
|
|
124281
124612
|
if (!menu) return;
|
|
124282
124613
|
const root = getOrCreatePortalRoot();
|
|
124283
124614
|
if (menu.parentElement !== root) {
|
|
@@ -124309,7 +124640,7 @@ function useSlashMenuPortal(container) {
|
|
|
124309
124640
|
observer.disconnect();
|
|
124310
124641
|
window.removeEventListener("scroll", onScrollOrResize, true);
|
|
124311
124642
|
window.removeEventListener("resize", onScrollOrResize);
|
|
124312
|
-
const menu = document.getElementById(portalRootId)?.querySelector(
|
|
124643
|
+
const menu = document.getElementById(portalRootId)?.querySelector(SLASH_MENU_SELECTOR);
|
|
124313
124644
|
if (menu && originalParent?.isConnected) {
|
|
124314
124645
|
originalParent.insertBefore(menu, originalNextSibling);
|
|
124315
124646
|
}
|
|
@@ -124319,7 +124650,7 @@ function useSlashMenuPortal(container) {
|
|
|
124319
124650
|
}
|
|
124320
124651
|
|
|
124321
124652
|
const ReviewSuggestionsViewport = lazy(
|
|
124322
|
-
() => import('./index-
|
|
124653
|
+
() => import('./index-DRSHBn8E.js').then((module) => ({ default: module.ReviewSuggestionsViewport }))
|
|
124323
124654
|
);
|
|
124324
124655
|
const MilkdownEditorInner = ({
|
|
124325
124656
|
readOnly = false,
|
|
@@ -124543,7 +124874,18 @@ const MilkdownEditor = (props) => {
|
|
|
124543
124874
|
const mentions = props.mentions ?? [];
|
|
124544
124875
|
const mentionsRef = useRef(mentions);
|
|
124545
124876
|
mentionsRef.current = mentions;
|
|
124546
|
-
const
|
|
124877
|
+
const onFooterButtonClickRef = useRef(props.footerButton?.onClick);
|
|
124878
|
+
onFooterButtonClickRef.current = props.footerButton?.onClick;
|
|
124879
|
+
const footerButtonLabel = props.footerButton?.label;
|
|
124880
|
+
const mentionsRuntime = useMemo(
|
|
124881
|
+
() => ({
|
|
124882
|
+
providersRef: mentionsRef,
|
|
124883
|
+
providers: mentions,
|
|
124884
|
+
onFooterButtonClickRef,
|
|
124885
|
+
footerButtonLabel
|
|
124886
|
+
}),
|
|
124887
|
+
[mentions, footerButtonLabel]
|
|
124888
|
+
);
|
|
124547
124889
|
return /* @__PURE__ */ jsx(
|
|
124548
124890
|
VariableContentChannelsContext.Provider,
|
|
124549
124891
|
{
|
|
@@ -124652,7 +124994,8 @@ const MarkdownSourceEditor = React.forwardRef(
|
|
|
124652
124994
|
onChange,
|
|
124653
124995
|
slashMenu = "basic",
|
|
124654
124996
|
toolbar = "basic",
|
|
124655
|
-
mentions
|
|
124997
|
+
mentions,
|
|
124998
|
+
footerButton
|
|
124656
124999
|
}, ref) {
|
|
124657
125000
|
const [mode, setMode] = React.useState("markdown");
|
|
124658
125001
|
const [markdown, setMarkdown] = React.useState(initialMarkdown);
|
|
@@ -124720,6 +125063,7 @@ const MarkdownSourceEditor = React.forwardRef(
|
|
|
124720
125063
|
toolbar,
|
|
124721
125064
|
placeholder,
|
|
124722
125065
|
mentions,
|
|
125066
|
+
footerButton,
|
|
124723
125067
|
onContentChange: handleEditorChange
|
|
124724
125068
|
},
|
|
124725
125069
|
editorKey
|