@kopexa/tiptap 17.3.0 → 17.5.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.
- package/dist/{chunk-NSYSECKW.mjs → chunk-2UDCL55K.mjs} +3 -1
- package/dist/chunk-4HO7BWDC.mjs +89 -0
- package/dist/chunk-552JLRNB.mjs +35 -0
- package/dist/chunk-5SMDMQDF.mjs +34 -0
- package/dist/{chunk-XKWTI3MA.mjs → chunk-DQK6PA4U.mjs} +11 -2
- package/dist/chunk-H7MS2UMO.mjs +168 -0
- package/dist/chunk-JVSH5T4B.mjs +72 -0
- package/dist/chunk-JZBRWJHC.mjs +170 -0
- package/dist/chunk-Q5FK7SFY.mjs +75 -0
- package/dist/chunk-QIELBKP3.mjs +104 -0
- package/dist/{chunk-XNDXYI2N.mjs → chunk-XGAABDMW.mjs} +2 -1
- package/dist/extensions/variable/extract-variables.d.mts +16 -0
- package/dist/extensions/variable/extract-variables.d.ts +16 -0
- package/dist/extensions/variable/extract-variables.js +58 -0
- package/dist/extensions/variable/extract-variables.mjs +7 -0
- package/dist/extensions/variable/index.d.mts +38 -0
- package/dist/extensions/variable/index.d.ts +38 -0
- package/dist/extensions/variable/index.js +190 -0
- package/dist/extensions/variable/index.mjs +11 -0
- package/dist/extensions/variable/messages.d.mts +69 -0
- package/dist/extensions/variable/messages.d.ts +69 -0
- package/dist/extensions/variable/messages.js +98 -0
- package/dist/extensions/variable/messages.mjs +7 -0
- package/dist/extensions/variable/variable-context.d.mts +56 -0
- package/dist/extensions/variable/variable-context.d.ts +56 -0
- package/dist/extensions/variable/variable-context.js +70 -0
- package/dist/extensions/variable/variable-context.mjs +12 -0
- package/dist/extensions/variable/variable-filler-dialog.d.mts +43 -0
- package/dist/extensions/variable/variable-filler-dialog.d.ts +43 -0
- package/dist/extensions/variable/variable-filler-dialog.js +207 -0
- package/dist/extensions/variable/variable-filler-dialog.mjs +9 -0
- package/dist/extensions/variable/variable-suggestion.d.mts +31 -0
- package/dist/extensions/variable/variable-suggestion.d.ts +31 -0
- package/dist/extensions/variable/variable-suggestion.js +615 -0
- package/dist/extensions/variable/variable-suggestion.mjs +14 -0
- package/dist/extensions/variable/variable-view.d.mts +13 -0
- package/dist/extensions/variable/variable-view.d.ts +13 -0
- package/dist/extensions/variable/variable-view.js +110 -0
- package/dist/extensions/variable/variable-view.mjs +11 -0
- package/dist/hooks/use-create-editor.d.mts +8 -2
- package/dist/hooks/use-create-editor.d.ts +8 -2
- package/dist/hooks/use-create-editor.js +163 -7
- package/dist/hooks/use-create-editor.mjs +4 -1
- package/dist/index.d.mts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +1866 -1260
- package/dist/index.mjs +35 -9
- package/dist/presets/basic/editor-header.mjs +3 -3
- package/dist/presets/basic/index.d.mts +12 -1
- package/dist/presets/basic/index.d.ts +12 -1
- package/dist/presets/basic/index.js +4245 -3858
- package/dist/presets/basic/index.mjs +12 -8
- package/dist/ui/bubble-menu/index.js +3 -1
- package/dist/ui/bubble-menu/index.mjs +1 -1
- package/dist/ui/link-bubble/index.js +2 -1
- package/dist/ui/link-bubble/index.mjs +1 -1
- package/package.json +24 -24
- package/dist/chunk-LWU4F64F.mjs +0 -110
- package/dist/{chunk-FDPXD6VC.mjs → chunk-RFWNKE7D.mjs} +3 -3
package/dist/index.js
CHANGED
|
@@ -39,13 +39,20 @@ __export(index_exports, {
|
|
|
39
39
|
InlineMath: () => InlineMath,
|
|
40
40
|
MathBlock: () => MathBlock,
|
|
41
41
|
TocNode: () => TocNode,
|
|
42
|
+
VariableFillerDialog: () => VariableFillerDialog,
|
|
43
|
+
VariableNode: () => VariableNode,
|
|
44
|
+
VariableProvider: () => VariableProvider,
|
|
45
|
+
VariableSuggestion: () => VariableSuggestion,
|
|
42
46
|
convertFileToBase64: () => convertFileToBase64,
|
|
47
|
+
extractVariablesFromContent: () => extractVariablesFromContent,
|
|
43
48
|
getExtensions: () => getExtensions,
|
|
44
49
|
handleImageUpload: () => handleImageUpload,
|
|
45
50
|
isAllowedUri: () => isAllowedUri,
|
|
46
51
|
sanitizeUrl: () => sanitizeUrl,
|
|
47
52
|
useEditorFile: () => useEditorFile,
|
|
48
|
-
useEditorFileRequired: () => useEditorFileRequired
|
|
53
|
+
useEditorFileRequired: () => useEditorFileRequired,
|
|
54
|
+
useVariables: () => useVariables,
|
|
55
|
+
useVariablesWithFallback: () => useVariablesWithFallback
|
|
49
56
|
});
|
|
50
57
|
module.exports = __toCommonJS(index_exports);
|
|
51
58
|
|
|
@@ -2044,186 +2051,1160 @@ var TocNode = import_core5.Node.create({
|
|
|
2044
2051
|
}
|
|
2045
2052
|
});
|
|
2046
2053
|
|
|
2047
|
-
// src/
|
|
2048
|
-
var
|
|
2049
|
-
var
|
|
2050
|
-
var import_extension_table = require("@kopexa/extension-table");
|
|
2051
|
-
var import_extension_file_handler = require("@tiptap/extension-file-handler");
|
|
2052
|
-
var import_extension_highlight = require("@tiptap/extension-highlight");
|
|
2053
|
-
var import_extension_invisible_characters = __toESM(require("@tiptap/extension-invisible-characters"));
|
|
2054
|
-
var import_extension_list = require("@tiptap/extension-list");
|
|
2055
|
-
var import_extension_subscript = require("@tiptap/extension-subscript");
|
|
2056
|
-
var import_extension_superscript = require("@tiptap/extension-superscript");
|
|
2057
|
-
var import_extension_table_of_contents = require("@tiptap/extension-table-of-contents");
|
|
2058
|
-
var import_extension_text_align = require("@tiptap/extension-text-align");
|
|
2059
|
-
var import_extension_text_style = require("@tiptap/extension-text-style");
|
|
2060
|
-
var import_extension_typography = require("@tiptap/extension-typography");
|
|
2061
|
-
var import_extension_unique_id = require("@tiptap/extension-unique-id");
|
|
2062
|
-
var import_extensions = require("@tiptap/extensions");
|
|
2063
|
-
var import_react25 = require("@tiptap/react");
|
|
2064
|
-
var import_starter_kit = require("@tiptap/starter-kit");
|
|
2065
|
-
var import_react26 = require("react");
|
|
2054
|
+
// src/extensions/variable/index.ts
|
|
2055
|
+
var import_core6 = require("@tiptap/core");
|
|
2056
|
+
var import_react23 = require("@tiptap/react");
|
|
2066
2057
|
|
|
2067
|
-
// src/extensions/
|
|
2068
|
-
var
|
|
2069
|
-
var import_state = require("@tiptap/pm/state");
|
|
2058
|
+
// src/extensions/variable/variable-view.tsx
|
|
2059
|
+
var import_theme5 = require("@kopexa/theme");
|
|
2070
2060
|
var import_react22 = require("@tiptap/react");
|
|
2071
|
-
|
|
2072
|
-
|
|
2061
|
+
|
|
2062
|
+
// src/extensions/variable/variable-context.tsx
|
|
2063
|
+
var React = __toESM(require("react"));
|
|
2064
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2065
|
+
var VariableContext = React.createContext(null);
|
|
2066
|
+
function VariableProvider({
|
|
2067
|
+
children,
|
|
2068
|
+
variables,
|
|
2069
|
+
resolveVariable
|
|
2070
|
+
}) {
|
|
2071
|
+
const value = React.useMemo(
|
|
2072
|
+
() => ({
|
|
2073
|
+
variables,
|
|
2074
|
+
resolveVariable
|
|
2075
|
+
}),
|
|
2076
|
+
[variables, resolveVariable]
|
|
2077
|
+
);
|
|
2078
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(VariableContext.Provider, { value, children });
|
|
2079
|
+
}
|
|
2080
|
+
function useVariables() {
|
|
2081
|
+
return React.useContext(VariableContext);
|
|
2082
|
+
}
|
|
2083
|
+
function useVariablesWithFallback(fallbackVariables = []) {
|
|
2084
|
+
var _a;
|
|
2085
|
+
const context = React.useContext(VariableContext);
|
|
2086
|
+
return (_a = context == null ? void 0 : context.variables) != null ? _a : fallbackVariables;
|
|
2087
|
+
}
|
|
2088
|
+
|
|
2089
|
+
// src/extensions/variable/variable-view.tsx
|
|
2090
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2091
|
+
function VariableNodeView({ node, editor }) {
|
|
2092
|
+
var _a;
|
|
2093
|
+
const attrs = node.attrs;
|
|
2094
|
+
const { name, fallback, category } = attrs;
|
|
2095
|
+
const context = useVariables();
|
|
2096
|
+
const isEditable = (0, import_react22.useEditorState)({
|
|
2097
|
+
editor,
|
|
2098
|
+
selector: ({ editor: e }) => {
|
|
2099
|
+
var _a2;
|
|
2100
|
+
return (_a2 = e == null ? void 0 : e.isEditable) != null ? _a2 : true;
|
|
2101
|
+
}
|
|
2102
|
+
});
|
|
2103
|
+
const resolvedValue = (_a = context == null ? void 0 : context.resolveVariable) == null ? void 0 : _a.call(context, name);
|
|
2104
|
+
const hasValue = resolvedValue !== void 0 && resolvedValue !== "";
|
|
2105
|
+
const displayValue = resolvedValue || fallback;
|
|
2106
|
+
const styles = (0, import_theme5.variableNode)({ resolved: hasValue });
|
|
2107
|
+
if (!isEditable && hasValue) {
|
|
2108
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2109
|
+
import_react22.NodeViewWrapper,
|
|
2110
|
+
{
|
|
2111
|
+
as: "span",
|
|
2112
|
+
"data-type": "variable",
|
|
2113
|
+
"data-name": name,
|
|
2114
|
+
style: { userSelect: "text" },
|
|
2115
|
+
children: displayValue
|
|
2116
|
+
}
|
|
2117
|
+
);
|
|
2118
|
+
}
|
|
2119
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2120
|
+
import_react22.NodeViewWrapper,
|
|
2121
|
+
{
|
|
2122
|
+
as: "span",
|
|
2123
|
+
className: styles.wrapper(),
|
|
2124
|
+
"data-type": "variable",
|
|
2125
|
+
"data-name": name,
|
|
2126
|
+
"data-category": category,
|
|
2127
|
+
"data-resolved": hasValue ? "true" : "false",
|
|
2128
|
+
children: hasValue ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: styles.chip(), title: `{{${name}}}`, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: styles.value(), children: displayValue }) }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2129
|
+
"span",
|
|
2130
|
+
{
|
|
2131
|
+
className: styles.chip(),
|
|
2132
|
+
title: fallback ? `Fallback: ${fallback}` : void 0,
|
|
2133
|
+
children: [
|
|
2134
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: styles.bracket(), children: "{" }),
|
|
2135
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: styles.bracket(), children: "{" }),
|
|
2136
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: styles.name(), children: name }),
|
|
2137
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: styles.bracket(), children: "}" }),
|
|
2138
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: styles.bracket(), children: "}" })
|
|
2139
|
+
]
|
|
2140
|
+
}
|
|
2141
|
+
)
|
|
2142
|
+
}
|
|
2143
|
+
);
|
|
2144
|
+
}
|
|
2145
|
+
|
|
2146
|
+
// src/extensions/variable/index.ts
|
|
2147
|
+
var VariableNode = import_core6.Node.create({
|
|
2148
|
+
name: "variable",
|
|
2149
|
+
group: "inline",
|
|
2150
|
+
inline: true,
|
|
2151
|
+
atom: true,
|
|
2152
|
+
selectable: true,
|
|
2153
|
+
draggable: true,
|
|
2154
|
+
addOptions() {
|
|
2155
|
+
return {
|
|
2156
|
+
HTMLAttributes: {}
|
|
2157
|
+
};
|
|
2158
|
+
},
|
|
2159
|
+
addAttributes() {
|
|
2160
|
+
return {
|
|
2161
|
+
name: {
|
|
2162
|
+
default: "",
|
|
2163
|
+
parseHTML: (element) => element.getAttribute("data-name"),
|
|
2164
|
+
renderHTML: (attributes) => ({
|
|
2165
|
+
"data-name": attributes.name
|
|
2166
|
+
})
|
|
2167
|
+
},
|
|
2168
|
+
fallback: {
|
|
2169
|
+
default: void 0,
|
|
2170
|
+
parseHTML: (element) => element.getAttribute("data-fallback"),
|
|
2171
|
+
renderHTML: (attributes) => {
|
|
2172
|
+
if (!attributes.fallback) return {};
|
|
2173
|
+
return {
|
|
2174
|
+
"data-fallback": attributes.fallback
|
|
2175
|
+
};
|
|
2176
|
+
}
|
|
2177
|
+
},
|
|
2178
|
+
category: {
|
|
2179
|
+
default: void 0,
|
|
2180
|
+
parseHTML: (element) => element.getAttribute("data-category"),
|
|
2181
|
+
renderHTML: (attributes) => {
|
|
2182
|
+
if (!attributes.category) return {};
|
|
2183
|
+
return {
|
|
2184
|
+
"data-category": attributes.category
|
|
2185
|
+
};
|
|
2186
|
+
}
|
|
2187
|
+
}
|
|
2188
|
+
};
|
|
2189
|
+
},
|
|
2073
2190
|
parseHTML() {
|
|
2074
2191
|
return [
|
|
2075
2192
|
{
|
|
2076
|
-
tag: '
|
|
2193
|
+
tag: 'span[data-type="variable"]'
|
|
2077
2194
|
}
|
|
2078
2195
|
];
|
|
2079
2196
|
},
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
const { editor } = this;
|
|
2083
|
-
return [
|
|
2084
|
-
...((_a = this.parent) == null ? void 0 : _a.call(this)) || [],
|
|
2085
|
-
new import_state.Plugin({
|
|
2086
|
-
key: new import_state.PluginKey("linkKeyHandler"),
|
|
2087
|
-
props: {
|
|
2088
|
-
handleKeyDown: (_, event) => {
|
|
2089
|
-
const { selection } = editor.state;
|
|
2090
|
-
if (event.key === "Escape" && selection.empty !== true) {
|
|
2091
|
-
editor.commands.focus(selection.to, { scrollIntoView: false });
|
|
2092
|
-
}
|
|
2093
|
-
return false;
|
|
2094
|
-
},
|
|
2095
|
-
handleClick(view, pos) {
|
|
2096
|
-
const { schema, doc, tr } = view.state;
|
|
2097
|
-
let range;
|
|
2098
|
-
if (schema.marks.link) {
|
|
2099
|
-
range = (0, import_react22.getMarkRange)(doc.resolve(pos), schema.marks.link);
|
|
2100
|
-
}
|
|
2101
|
-
if (!range) {
|
|
2102
|
-
return;
|
|
2103
|
-
}
|
|
2104
|
-
const { from, to } = range;
|
|
2105
|
-
const start = Math.min(from, to);
|
|
2106
|
-
const end = Math.max(from, to);
|
|
2107
|
-
if (pos < start || pos > end) {
|
|
2108
|
-
return;
|
|
2109
|
-
}
|
|
2110
|
-
const $start = doc.resolve(start);
|
|
2111
|
-
const $end = doc.resolve(end);
|
|
2112
|
-
const transaction = tr.setSelection(
|
|
2113
|
-
new import_state.TextSelection($start, $end)
|
|
2114
|
-
);
|
|
2115
|
-
view.dispatch(transaction);
|
|
2116
|
-
}
|
|
2117
|
-
}
|
|
2118
|
-
})
|
|
2119
|
-
];
|
|
2120
|
-
}
|
|
2121
|
-
});
|
|
2122
|
-
|
|
2123
|
-
// src/extensions/selection/index.ts
|
|
2124
|
-
var import_state2 = require("@tiptap/pm/state");
|
|
2125
|
-
var import_view = require("@tiptap/pm/view");
|
|
2126
|
-
var import_react23 = require("@tiptap/react");
|
|
2127
|
-
var Selection = import_react23.Extension.create({
|
|
2128
|
-
name: "selection",
|
|
2129
|
-
addProseMirrorPlugins() {
|
|
2130
|
-
const { editor } = this;
|
|
2197
|
+
renderHTML({ node, HTMLAttributes }) {
|
|
2198
|
+
const attrs = node.attrs;
|
|
2131
2199
|
return [
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
}
|
|
2139
|
-
if (editor.isFocused === true || !editor.isEditable) {
|
|
2140
|
-
return null;
|
|
2141
|
-
}
|
|
2142
|
-
if ((0, import_react23.isNodeSelection)(state.selection)) {
|
|
2143
|
-
return null;
|
|
2144
|
-
}
|
|
2145
|
-
return import_view.DecorationSet.create(state.doc, [
|
|
2146
|
-
import_view.Decoration.inline(state.selection.from, state.selection.to, {
|
|
2147
|
-
class: "selection"
|
|
2148
|
-
})
|
|
2149
|
-
]);
|
|
2150
|
-
}
|
|
2151
|
-
}
|
|
2152
|
-
})
|
|
2200
|
+
"span",
|
|
2201
|
+
(0, import_core6.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, {
|
|
2202
|
+
"data-type": "variable",
|
|
2203
|
+
class: "variable-node"
|
|
2204
|
+
}),
|
|
2205
|
+
`{{${attrs.name}}}`
|
|
2153
2206
|
];
|
|
2207
|
+
},
|
|
2208
|
+
addNodeView() {
|
|
2209
|
+
return (0, import_react23.ReactNodeViewRenderer)(VariableNodeView);
|
|
2210
|
+
},
|
|
2211
|
+
addCommands() {
|
|
2212
|
+
return {
|
|
2213
|
+
insertVariable: (attrs) => ({ commands }) => {
|
|
2214
|
+
return commands.insertContent({
|
|
2215
|
+
type: this.name,
|
|
2216
|
+
attrs
|
|
2217
|
+
});
|
|
2218
|
+
}
|
|
2219
|
+
};
|
|
2154
2220
|
}
|
|
2155
2221
|
});
|
|
2156
2222
|
|
|
2157
|
-
// src/extensions/
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2223
|
+
// src/extensions/variable/extract-variables.ts
|
|
2224
|
+
function extractVariablesFromContent(content) {
|
|
2225
|
+
if (!content) return [];
|
|
2226
|
+
const variables = /* @__PURE__ */ new Map();
|
|
2227
|
+
function scan(node) {
|
|
2228
|
+
var _a;
|
|
2229
|
+
if (node.type === "variable" && ((_a = node.attrs) == null ? void 0 : _a.name)) {
|
|
2230
|
+
const name = node.attrs.name;
|
|
2231
|
+
if (!variables.has(name)) {
|
|
2232
|
+
variables.set(name, {
|
|
2233
|
+
name,
|
|
2234
|
+
label: formatVariableName(name),
|
|
2235
|
+
category: node.attrs.category || void 0,
|
|
2236
|
+
fallback: node.attrs.fallback || void 0
|
|
2237
|
+
});
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
if (node.content && Array.isArray(node.content)) {
|
|
2241
|
+
for (const child of node.content) {
|
|
2242
|
+
scan(child);
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2167
2245
|
}
|
|
2168
|
-
|
|
2246
|
+
scan(content);
|
|
2247
|
+
return Array.from(variables.values());
|
|
2169
2248
|
}
|
|
2170
|
-
|
|
2171
|
-
name
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2249
|
+
function formatVariableName(name) {
|
|
2250
|
+
return name.replace(/([A-Z])/g, " $1").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()).replace(/\s+/g, " ").trim();
|
|
2251
|
+
}
|
|
2252
|
+
|
|
2253
|
+
// src/extensions/variable/variable-filler-dialog.tsx
|
|
2254
|
+
var import_button7 = require("@kopexa/button");
|
|
2255
|
+
var import_dialog5 = require("@kopexa/dialog");
|
|
2256
|
+
var import_input2 = require("@kopexa/input");
|
|
2257
|
+
var import_label5 = require("@kopexa/label");
|
|
2258
|
+
var React2 = __toESM(require("react"));
|
|
2259
|
+
var import_react_intl14 = require("react-intl");
|
|
2260
|
+
|
|
2261
|
+
// src/extensions/variable/messages.ts
|
|
2262
|
+
var import_react_intl13 = require("react-intl");
|
|
2263
|
+
var messages6 = (0, import_react_intl13.defineMessages)({
|
|
2264
|
+
title: {
|
|
2265
|
+
id: "editor.variable.title",
|
|
2266
|
+
defaultMessage: "Variables",
|
|
2267
|
+
description: "Title for the variables section"
|
|
2177
2268
|
},
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2269
|
+
insert: {
|
|
2270
|
+
id: "editor.variable.insert",
|
|
2271
|
+
defaultMessage: "Insert variable",
|
|
2272
|
+
description: "Insert variable button label"
|
|
2273
|
+
},
|
|
2274
|
+
empty_state: {
|
|
2275
|
+
id: "editor.variable.empty_state",
|
|
2276
|
+
defaultMessage: "No variables available",
|
|
2277
|
+
description: "Empty state when no variables are defined"
|
|
2278
|
+
},
|
|
2279
|
+
hint: {
|
|
2280
|
+
id: "editor.variable.hint",
|
|
2281
|
+
defaultMessage: "Type {{ to insert a variable",
|
|
2282
|
+
description: "Hint for inserting variables"
|
|
2283
|
+
},
|
|
2284
|
+
save: {
|
|
2285
|
+
id: "editor.variable.save",
|
|
2286
|
+
defaultMessage: "Save",
|
|
2287
|
+
description: "Save button label"
|
|
2288
|
+
},
|
|
2289
|
+
cancel: {
|
|
2290
|
+
id: "editor.variable.cancel",
|
|
2291
|
+
defaultMessage: "Cancel",
|
|
2292
|
+
description: "Cancel button label"
|
|
2293
|
+
},
|
|
2294
|
+
category_company: {
|
|
2295
|
+
id: "editor.variable.category.company",
|
|
2296
|
+
defaultMessage: "Company",
|
|
2297
|
+
description: "Company variables category"
|
|
2298
|
+
},
|
|
2299
|
+
category_user: {
|
|
2300
|
+
id: "editor.variable.category.user",
|
|
2301
|
+
defaultMessage: "User",
|
|
2302
|
+
description: "User variables category"
|
|
2303
|
+
},
|
|
2304
|
+
category_date: {
|
|
2305
|
+
id: "editor.variable.category.date",
|
|
2306
|
+
defaultMessage: "Date",
|
|
2307
|
+
description: "Date variables category"
|
|
2308
|
+
},
|
|
2309
|
+
category_document: {
|
|
2310
|
+
id: "editor.variable.category.document",
|
|
2311
|
+
defaultMessage: "Document",
|
|
2312
|
+
description: "Document variables category"
|
|
2313
|
+
},
|
|
2314
|
+
category_other: {
|
|
2315
|
+
id: "editor.variable.category.other",
|
|
2316
|
+
defaultMessage: "Other",
|
|
2317
|
+
description: "Other variables category"
|
|
2318
|
+
},
|
|
2319
|
+
filler_title: {
|
|
2320
|
+
id: "editor.variable.filler.title",
|
|
2321
|
+
defaultMessage: "Fill in Variables",
|
|
2322
|
+
description: "Title for the variable filler dialog"
|
|
2323
|
+
},
|
|
2324
|
+
filler_filled: {
|
|
2325
|
+
id: "editor.variable.filler.filled",
|
|
2326
|
+
defaultMessage: "filled",
|
|
2327
|
+
description: "Label for filled count"
|
|
2212
2328
|
}
|
|
2213
2329
|
});
|
|
2214
2330
|
|
|
2215
|
-
// src/extensions/
|
|
2216
|
-
var
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2331
|
+
// src/extensions/variable/variable-filler-dialog.tsx
|
|
2332
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2333
|
+
function VariableFillerDialog({
|
|
2334
|
+
open,
|
|
2335
|
+
onOpenChange,
|
|
2336
|
+
variables,
|
|
2337
|
+
values,
|
|
2338
|
+
onSave,
|
|
2339
|
+
title,
|
|
2340
|
+
description
|
|
2341
|
+
}) {
|
|
2342
|
+
const intl = (0, import_react_intl14.useIntl)();
|
|
2343
|
+
const [localValues, setLocalValues] = React2.useState(
|
|
2344
|
+
{}
|
|
2345
|
+
);
|
|
2346
|
+
React2.useEffect(() => {
|
|
2347
|
+
if (open) {
|
|
2348
|
+
setLocalValues({ ...values });
|
|
2349
|
+
}
|
|
2350
|
+
}, [open, values]);
|
|
2351
|
+
const handleChange = React2.useCallback((name, value) => {
|
|
2352
|
+
setLocalValues((prev) => ({
|
|
2353
|
+
...prev,
|
|
2354
|
+
[name]: value
|
|
2355
|
+
}));
|
|
2356
|
+
}, []);
|
|
2357
|
+
const handleSave = React2.useCallback(() => {
|
|
2358
|
+
onSave(localValues);
|
|
2359
|
+
onOpenChange(false);
|
|
2360
|
+
}, [localValues, onSave, onOpenChange]);
|
|
2361
|
+
const handleCancel = React2.useCallback(() => {
|
|
2362
|
+
setLocalValues({ ...values });
|
|
2363
|
+
onOpenChange(false);
|
|
2364
|
+
}, [values, onOpenChange]);
|
|
2365
|
+
const groupedVariables = React2.useMemo(() => {
|
|
2366
|
+
return variables.reduce(
|
|
2367
|
+
(acc, v) => {
|
|
2368
|
+
const cat = v.category || intl.formatMessage(messages6.category_other);
|
|
2369
|
+
if (!acc[cat]) acc[cat] = [];
|
|
2370
|
+
acc[cat].push(v);
|
|
2371
|
+
return acc;
|
|
2372
|
+
},
|
|
2373
|
+
{}
|
|
2374
|
+
);
|
|
2375
|
+
}, [variables, intl]);
|
|
2376
|
+
const filledCount = React2.useMemo(() => {
|
|
2377
|
+
return variables.filter((v) => {
|
|
2378
|
+
var _a;
|
|
2379
|
+
return (_a = localValues[v.name]) == null ? void 0 : _a.trim();
|
|
2380
|
+
}).length;
|
|
2381
|
+
}, [variables, localValues]);
|
|
2382
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_dialog5.Dialog.Root, { open, onOpenChange, size: "md", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_dialog5.Dialog.Content, { children: [
|
|
2383
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_dialog5.Dialog.Header, { children: [
|
|
2384
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_dialog5.Dialog.Title, { children: title || intl.formatMessage(messages6.filler_title) }),
|
|
2385
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_dialog5.Dialog.Description, { children: description })
|
|
2386
|
+
] }),
|
|
2387
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_dialog5.Dialog.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "space-y-6", children: Object.entries(groupedVariables).map(([category, vars]) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
|
|
2388
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h4", { className: "text-sm font-semibold text-muted-foreground uppercase tracking-wide mb-3", children: category }),
|
|
2389
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "space-y-3", children: vars.map((v) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "space-y-1.5", children: [
|
|
2390
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_label5.Label, { htmlFor: `var-${v.name}`, className: "text-sm", children: [
|
|
2391
|
+
v.label,
|
|
2392
|
+
v.description && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ml-2 text-xs text-muted-foreground font-normal", children: v.description })
|
|
2393
|
+
] }),
|
|
2394
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2395
|
+
import_input2.Input,
|
|
2396
|
+
{
|
|
2397
|
+
id: `var-${v.name}`,
|
|
2398
|
+
placeholder: v.fallback || `{{${v.name}}}`,
|
|
2399
|
+
value: localValues[v.name] || "",
|
|
2400
|
+
onChange: (e) => handleChange(v.name, e.target.value)
|
|
2401
|
+
}
|
|
2402
|
+
)
|
|
2403
|
+
] }, v.name)) })
|
|
2404
|
+
] }, category)) }) }),
|
|
2405
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_dialog5.Dialog.Footer, { className: "flex items-center justify-between", children: [
|
|
2406
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "text-sm text-muted-foreground", children: [
|
|
2407
|
+
filledCount,
|
|
2408
|
+
" / ",
|
|
2409
|
+
variables.length,
|
|
2410
|
+
" ",
|
|
2411
|
+
intl.formatMessage(messages6.filler_filled)
|
|
2412
|
+
] }),
|
|
2413
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex gap-2", children: [
|
|
2414
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_button7.Button, { variant: "ghost", onClick: handleCancel, children: intl.formatMessage(messages6.cancel) }),
|
|
2415
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_button7.Button, { onClick: handleSave, children: intl.formatMessage(messages6.save) })
|
|
2416
|
+
] })
|
|
2417
|
+
] })
|
|
2418
|
+
] }) });
|
|
2419
|
+
}
|
|
2420
|
+
|
|
2421
|
+
// src/extensions/variable/variable-suggestion.tsx
|
|
2422
|
+
var import_editor_utils = require("@kopexa/editor-utils");
|
|
2423
|
+
var import_theme6 = require("@kopexa/theme");
|
|
2424
|
+
var import_state2 = require("@tiptap/pm/state");
|
|
2425
|
+
var React6 = __toESM(require("react"));
|
|
2426
|
+
|
|
2427
|
+
// src/ui/suggestion-menu/suggestion-menu.tsx
|
|
2428
|
+
var import_react27 = require("@floating-ui/react");
|
|
2429
|
+
var import_state = require("@tiptap/pm/state");
|
|
2430
|
+
var import_suggestion = require("@tiptap/suggestion");
|
|
2431
|
+
var React5 = __toESM(require("react"));
|
|
2432
|
+
|
|
2433
|
+
// src/hooks/use-floating-element.ts
|
|
2434
|
+
var import_react24 = require("@floating-ui/react");
|
|
2435
|
+
var React3 = __toESM(require("react"));
|
|
2436
|
+
function useFloatingElement(show, referencePos, zIndex, options) {
|
|
2437
|
+
const { dismissOptions, ...floatingOptions } = options || {};
|
|
2438
|
+
const { refs, update, context, floatingStyles } = (0, import_react24.useFloating)({
|
|
2439
|
+
open: show,
|
|
2440
|
+
...floatingOptions
|
|
2441
|
+
});
|
|
2442
|
+
const { isMounted, styles } = (0, import_react24.useTransitionStyles)(context);
|
|
2443
|
+
const dismiss = (0, import_react24.useDismiss)(context, dismissOptions);
|
|
2444
|
+
const { getReferenceProps, getFloatingProps } = (0, import_react24.useInteractions)([dismiss]);
|
|
2445
|
+
React3.useEffect(() => {
|
|
2446
|
+
update();
|
|
2447
|
+
}, [referencePos, update]);
|
|
2448
|
+
React3.useEffect(() => {
|
|
2449
|
+
if (referencePos === null) {
|
|
2450
|
+
return;
|
|
2451
|
+
}
|
|
2452
|
+
refs.setReference({
|
|
2453
|
+
getBoundingClientRect: () => referencePos
|
|
2454
|
+
});
|
|
2455
|
+
}, [referencePos, refs]);
|
|
2456
|
+
return React3.useMemo(
|
|
2457
|
+
() => ({
|
|
2458
|
+
isMounted,
|
|
2459
|
+
ref: refs.setFloating,
|
|
2460
|
+
style: {
|
|
2461
|
+
...styles,
|
|
2462
|
+
...floatingStyles,
|
|
2463
|
+
zIndex
|
|
2464
|
+
},
|
|
2465
|
+
update,
|
|
2466
|
+
getFloatingProps,
|
|
2467
|
+
getReferenceProps
|
|
2468
|
+
}),
|
|
2469
|
+
[
|
|
2470
|
+
floatingStyles,
|
|
2471
|
+
isMounted,
|
|
2472
|
+
refs.setFloating,
|
|
2473
|
+
styles,
|
|
2474
|
+
update,
|
|
2475
|
+
zIndex,
|
|
2476
|
+
getFloatingProps,
|
|
2477
|
+
getReferenceProps
|
|
2478
|
+
]
|
|
2479
|
+
);
|
|
2480
|
+
}
|
|
2481
|
+
|
|
2482
|
+
// src/hooks/use-menu-navigation.ts
|
|
2483
|
+
var React4 = __toESM(require("react"));
|
|
2484
|
+
function useMenuNavigation({
|
|
2485
|
+
editor,
|
|
2486
|
+
containerRef,
|
|
2487
|
+
query,
|
|
2488
|
+
items,
|
|
2489
|
+
onSelect,
|
|
2490
|
+
onClose,
|
|
2491
|
+
orientation = "vertical",
|
|
2492
|
+
autoSelectFirstItem = true
|
|
2493
|
+
}) {
|
|
2494
|
+
const [selectedIndex, setSelectedIndex] = React4.useState(
|
|
2495
|
+
autoSelectFirstItem ? 0 : -1
|
|
2496
|
+
);
|
|
2497
|
+
React4.useEffect(() => {
|
|
2498
|
+
const handleKeyboardNavigation = (event) => {
|
|
2499
|
+
if (!items.length) return false;
|
|
2500
|
+
const moveNext = () => setSelectedIndex((currentIndex) => {
|
|
2501
|
+
if (currentIndex === -1) return 0;
|
|
2502
|
+
return (currentIndex + 1) % items.length;
|
|
2503
|
+
});
|
|
2504
|
+
const movePrev = () => setSelectedIndex((currentIndex) => {
|
|
2505
|
+
if (currentIndex === -1) return items.length - 1;
|
|
2506
|
+
return (currentIndex - 1 + items.length) % items.length;
|
|
2507
|
+
});
|
|
2508
|
+
switch (event.key) {
|
|
2509
|
+
case "ArrowUp": {
|
|
2510
|
+
if (orientation === "horizontal") return false;
|
|
2511
|
+
event.preventDefault();
|
|
2512
|
+
movePrev();
|
|
2513
|
+
return true;
|
|
2514
|
+
}
|
|
2515
|
+
case "ArrowDown": {
|
|
2516
|
+
if (orientation === "horizontal") return false;
|
|
2517
|
+
event.preventDefault();
|
|
2518
|
+
moveNext();
|
|
2519
|
+
return true;
|
|
2520
|
+
}
|
|
2521
|
+
case "ArrowLeft": {
|
|
2522
|
+
if (orientation === "vertical") return false;
|
|
2523
|
+
event.preventDefault();
|
|
2524
|
+
movePrev();
|
|
2525
|
+
return true;
|
|
2526
|
+
}
|
|
2527
|
+
case "ArrowRight": {
|
|
2528
|
+
if (orientation === "vertical") return false;
|
|
2529
|
+
event.preventDefault();
|
|
2530
|
+
moveNext();
|
|
2531
|
+
return true;
|
|
2532
|
+
}
|
|
2533
|
+
case "Tab": {
|
|
2534
|
+
event.preventDefault();
|
|
2535
|
+
if (event.shiftKey) {
|
|
2536
|
+
movePrev();
|
|
2537
|
+
} else {
|
|
2538
|
+
moveNext();
|
|
2539
|
+
}
|
|
2540
|
+
return true;
|
|
2541
|
+
}
|
|
2542
|
+
case "Home": {
|
|
2543
|
+
event.preventDefault();
|
|
2544
|
+
setSelectedIndex(0);
|
|
2545
|
+
return true;
|
|
2546
|
+
}
|
|
2547
|
+
case "End": {
|
|
2548
|
+
event.preventDefault();
|
|
2549
|
+
setSelectedIndex(items.length - 1);
|
|
2550
|
+
return true;
|
|
2551
|
+
}
|
|
2552
|
+
case "Enter": {
|
|
2553
|
+
if (event.isComposing) return false;
|
|
2554
|
+
event.preventDefault();
|
|
2555
|
+
if (selectedIndex !== -1 && items[selectedIndex]) {
|
|
2556
|
+
onSelect == null ? void 0 : onSelect(items[selectedIndex]);
|
|
2557
|
+
}
|
|
2558
|
+
return true;
|
|
2559
|
+
}
|
|
2560
|
+
case "Escape": {
|
|
2561
|
+
event.preventDefault();
|
|
2562
|
+
onClose == null ? void 0 : onClose();
|
|
2563
|
+
return true;
|
|
2564
|
+
}
|
|
2565
|
+
default:
|
|
2566
|
+
return false;
|
|
2567
|
+
}
|
|
2568
|
+
};
|
|
2569
|
+
let targetElement = null;
|
|
2570
|
+
if (editor) {
|
|
2571
|
+
targetElement = editor.view.dom;
|
|
2572
|
+
} else if (containerRef == null ? void 0 : containerRef.current) {
|
|
2573
|
+
targetElement = containerRef.current;
|
|
2574
|
+
}
|
|
2575
|
+
if (targetElement) {
|
|
2576
|
+
targetElement.addEventListener("keydown", handleKeyboardNavigation, true);
|
|
2577
|
+
return () => {
|
|
2578
|
+
targetElement == null ? void 0 : targetElement.removeEventListener(
|
|
2579
|
+
"keydown",
|
|
2580
|
+
handleKeyboardNavigation,
|
|
2581
|
+
true
|
|
2582
|
+
);
|
|
2583
|
+
};
|
|
2584
|
+
}
|
|
2585
|
+
return void 0;
|
|
2586
|
+
}, [
|
|
2587
|
+
editor,
|
|
2588
|
+
containerRef,
|
|
2589
|
+
items,
|
|
2590
|
+
selectedIndex,
|
|
2591
|
+
onSelect,
|
|
2592
|
+
onClose,
|
|
2593
|
+
orientation
|
|
2594
|
+
]);
|
|
2595
|
+
React4.useEffect(() => {
|
|
2596
|
+
if (query) {
|
|
2597
|
+
setSelectedIndex(autoSelectFirstItem ? 0 : -1);
|
|
2598
|
+
}
|
|
2599
|
+
}, [query, autoSelectFirstItem]);
|
|
2600
|
+
return {
|
|
2601
|
+
selectedIndex: items.length ? selectedIndex : void 0,
|
|
2602
|
+
setSelectedIndex
|
|
2603
|
+
};
|
|
2604
|
+
}
|
|
2605
|
+
|
|
2606
|
+
// src/hooks/use-tiptap-editor.ts
|
|
2607
|
+
var import_react25 = require("@tiptap/react");
|
|
2608
|
+
var import_react26 = require("react");
|
|
2609
|
+
function useTiptapEditor(providedEditor) {
|
|
2610
|
+
const { editor: coreEditor } = (0, import_react25.useCurrentEditor)();
|
|
2611
|
+
const mainEditor = (0, import_react26.useMemo)(
|
|
2612
|
+
() => providedEditor || coreEditor,
|
|
2613
|
+
[providedEditor, coreEditor]
|
|
2614
|
+
);
|
|
2615
|
+
const editorState = (0, import_react25.useEditorState)({
|
|
2616
|
+
editor: mainEditor,
|
|
2617
|
+
selector(context) {
|
|
2618
|
+
if (!context.editor) {
|
|
2619
|
+
return {
|
|
2620
|
+
editor: null,
|
|
2621
|
+
editorState: void 0,
|
|
2622
|
+
canCommand: void 0
|
|
2623
|
+
};
|
|
2624
|
+
}
|
|
2625
|
+
return {
|
|
2626
|
+
editor: context.editor,
|
|
2627
|
+
editorState: context.editor.state,
|
|
2628
|
+
canCommand: context.editor.can
|
|
2629
|
+
};
|
|
2630
|
+
}
|
|
2631
|
+
});
|
|
2632
|
+
return editorState || { editor: null };
|
|
2633
|
+
}
|
|
2634
|
+
|
|
2635
|
+
// src/ui/suggestion-menu/suggestion-menu-utils.ts
|
|
2636
|
+
function calculateStartPosition(cursorPosition, previousNode, triggerChar) {
|
|
2637
|
+
if (!(previousNode == null ? void 0 : previousNode.text) || !triggerChar) {
|
|
2638
|
+
return cursorPosition;
|
|
2639
|
+
}
|
|
2640
|
+
const commandText = previousNode.text;
|
|
2641
|
+
const triggerCharIndex = commandText.lastIndexOf(triggerChar);
|
|
2642
|
+
if (triggerCharIndex === -1) {
|
|
2643
|
+
return cursorPosition;
|
|
2644
|
+
}
|
|
2645
|
+
const textLength = commandText.substring(triggerCharIndex).length;
|
|
2646
|
+
return cursorPosition - textLength;
|
|
2647
|
+
}
|
|
2648
|
+
function filterSuggestionItems(items, query) {
|
|
2649
|
+
const normalizedQuery = query.trim().toLowerCase();
|
|
2650
|
+
if (!normalizedQuery) {
|
|
2651
|
+
return items;
|
|
2652
|
+
}
|
|
2653
|
+
return items.filter((item) => {
|
|
2654
|
+
var _a, _b;
|
|
2655
|
+
if (item.title.toLowerCase().includes(normalizedQuery)) {
|
|
2656
|
+
return true;
|
|
2657
|
+
}
|
|
2658
|
+
if ((_a = item.subtext) == null ? void 0 : _a.toLowerCase().includes(normalizedQuery)) {
|
|
2659
|
+
return true;
|
|
2660
|
+
}
|
|
2661
|
+
if ((_b = item.keywords) == null ? void 0 : _b.some(
|
|
2662
|
+
(keyword) => keyword.toLowerCase().includes(normalizedQuery)
|
|
2663
|
+
)) {
|
|
2664
|
+
return true;
|
|
2665
|
+
}
|
|
2666
|
+
return false;
|
|
2667
|
+
}).sort((a, b) => {
|
|
2668
|
+
const aTitle = a.title.toLowerCase();
|
|
2669
|
+
const bTitle = b.title.toLowerCase();
|
|
2670
|
+
if (aTitle === normalizedQuery && bTitle !== normalizedQuery) return -1;
|
|
2671
|
+
if (bTitle === normalizedQuery && aTitle !== normalizedQuery) return 1;
|
|
2672
|
+
if (aTitle.startsWith(normalizedQuery) && !bTitle.startsWith(normalizedQuery))
|
|
2673
|
+
return -1;
|
|
2674
|
+
if (bTitle.startsWith(normalizedQuery) && !aTitle.startsWith(normalizedQuery))
|
|
2675
|
+
return 1;
|
|
2676
|
+
return 0;
|
|
2677
|
+
});
|
|
2678
|
+
}
|
|
2679
|
+
|
|
2680
|
+
// src/ui/suggestion-menu/suggestion-menu.tsx
|
|
2681
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2682
|
+
var SuggestionMenu = ({
|
|
2683
|
+
editor: providedEditor,
|
|
2684
|
+
floatingOptions,
|
|
2685
|
+
selector = "tiptap-suggestion-menu",
|
|
2686
|
+
children,
|
|
2687
|
+
maxHeight = 384,
|
|
2688
|
+
pluginKey = import_suggestion.SuggestionPluginKey,
|
|
2689
|
+
...internalSuggestionProps
|
|
2690
|
+
}) => {
|
|
2691
|
+
const { editor } = useTiptapEditor(providedEditor);
|
|
2692
|
+
const [show, setShow] = React5.useState(false);
|
|
2693
|
+
const [internalClientRect, setInternalClientRect] = React5.useState(null);
|
|
2694
|
+
const [internalCommand, setInternalCommand] = React5.useState(null);
|
|
2695
|
+
const [internalItems, setInternalItems] = React5.useState(
|
|
2696
|
+
[]
|
|
2697
|
+
);
|
|
2698
|
+
const [internalQuery, setInternalQuery] = React5.useState("");
|
|
2699
|
+
const [, setInternalRange] = React5.useState(null);
|
|
2700
|
+
const { ref, style, getFloatingProps, isMounted } = useFloatingElement(
|
|
2701
|
+
show,
|
|
2702
|
+
internalClientRect,
|
|
2703
|
+
1e3,
|
|
2704
|
+
{
|
|
2705
|
+
placement: "bottom-start",
|
|
2706
|
+
middleware: [
|
|
2707
|
+
(0, import_react27.offset)(10),
|
|
2708
|
+
(0, import_react27.flip)({
|
|
2709
|
+
mainAxis: true,
|
|
2710
|
+
crossAxis: false
|
|
2711
|
+
}),
|
|
2712
|
+
(0, import_react27.shift)(),
|
|
2713
|
+
(0, import_react27.size)({
|
|
2714
|
+
apply({ availableHeight, elements }) {
|
|
2715
|
+
if (elements.floating) {
|
|
2716
|
+
const maxHeightValue = maxHeight ? Math.min(maxHeight, availableHeight) : availableHeight;
|
|
2717
|
+
elements.floating.style.setProperty(
|
|
2718
|
+
"--suggestion-menu-max-height",
|
|
2719
|
+
`${maxHeightValue}px`
|
|
2720
|
+
);
|
|
2721
|
+
}
|
|
2722
|
+
}
|
|
2723
|
+
})
|
|
2724
|
+
],
|
|
2725
|
+
onOpenChange(open) {
|
|
2726
|
+
if (!open) {
|
|
2727
|
+
setShow(false);
|
|
2728
|
+
}
|
|
2729
|
+
},
|
|
2730
|
+
...floatingOptions
|
|
2731
|
+
}
|
|
2732
|
+
);
|
|
2733
|
+
const internalSuggestionPropsRef = React5.useRef(internalSuggestionProps);
|
|
2734
|
+
React5.useEffect(() => {
|
|
2735
|
+
internalSuggestionPropsRef.current = internalSuggestionProps;
|
|
2736
|
+
}, [internalSuggestionProps]);
|
|
2737
|
+
const closePopup = React5.useCallback(() => {
|
|
2738
|
+
setShow(false);
|
|
2739
|
+
}, []);
|
|
2740
|
+
React5.useEffect(() => {
|
|
2741
|
+
if (!editor || editor.isDestroyed) {
|
|
2742
|
+
return;
|
|
2743
|
+
}
|
|
2744
|
+
const existingPlugin = editor.state.plugins.find(
|
|
2745
|
+
(plugin) => plugin.spec.key === pluginKey
|
|
2746
|
+
);
|
|
2747
|
+
if (existingPlugin) {
|
|
2748
|
+
editor.unregisterPlugin(pluginKey);
|
|
2749
|
+
}
|
|
2750
|
+
const suggestion = (0, import_suggestion.Suggestion)({
|
|
2751
|
+
pluginKey: pluginKey instanceof import_state.PluginKey ? pluginKey : new import_state.PluginKey(pluginKey),
|
|
2752
|
+
editor,
|
|
2753
|
+
command({ editor: editor2, range, props }) {
|
|
2754
|
+
var _a, _b;
|
|
2755
|
+
if (!range) {
|
|
2756
|
+
return;
|
|
2757
|
+
}
|
|
2758
|
+
const { view, state } = editor2;
|
|
2759
|
+
const { selection } = state;
|
|
2760
|
+
const isMention = editor2.extensionManager.extensions.some(
|
|
2761
|
+
(extension) => {
|
|
2762
|
+
var _a2, _b2;
|
|
2763
|
+
const name = extension.name;
|
|
2764
|
+
return name === "mention" && ((_b2 = (_a2 = extension.options) == null ? void 0 : _a2.suggestion) == null ? void 0 : _b2.char) === internalSuggestionPropsRef.current.char;
|
|
2765
|
+
}
|
|
2766
|
+
);
|
|
2767
|
+
if (!isMention) {
|
|
2768
|
+
const cursorPosition = selection.$from.pos;
|
|
2769
|
+
const previousNode = (_a = selection.$head) == null ? void 0 : _a.nodeBefore;
|
|
2770
|
+
const startPosition = previousNode ? calculateStartPosition(
|
|
2771
|
+
cursorPosition,
|
|
2772
|
+
previousNode,
|
|
2773
|
+
internalSuggestionPropsRef.current.char
|
|
2774
|
+
) : selection.$from.start();
|
|
2775
|
+
const transaction = state.tr.deleteRange(
|
|
2776
|
+
startPosition,
|
|
2777
|
+
cursorPosition
|
|
2778
|
+
);
|
|
2779
|
+
view.dispatch(transaction);
|
|
2780
|
+
}
|
|
2781
|
+
const nodeAfter = view.state.selection.$to.nodeAfter;
|
|
2782
|
+
const overrideSpace = (_b = nodeAfter == null ? void 0 : nodeAfter.text) == null ? void 0 : _b.startsWith(" ");
|
|
2783
|
+
const rangeToUse = { ...range };
|
|
2784
|
+
if (overrideSpace) {
|
|
2785
|
+
rangeToUse.to += 1;
|
|
2786
|
+
}
|
|
2787
|
+
props.onSelect({ editor: editor2, range: rangeToUse, context: props.context });
|
|
2788
|
+
},
|
|
2789
|
+
render: () => {
|
|
2790
|
+
return {
|
|
2791
|
+
onStart: (props) => {
|
|
2792
|
+
var _a, _b;
|
|
2793
|
+
setInternalCommand(() => props.command);
|
|
2794
|
+
setInternalItems(props.items);
|
|
2795
|
+
setInternalQuery(props.query);
|
|
2796
|
+
setInternalRange(props.range);
|
|
2797
|
+
setInternalClientRect((_b = (_a = props.clientRect) == null ? void 0 : _a.call(props)) != null ? _b : null);
|
|
2798
|
+
setShow(true);
|
|
2799
|
+
},
|
|
2800
|
+
onUpdate: (props) => {
|
|
2801
|
+
var _a, _b;
|
|
2802
|
+
setInternalCommand(() => props.command);
|
|
2803
|
+
setInternalItems(props.items);
|
|
2804
|
+
setInternalQuery(props.query);
|
|
2805
|
+
setInternalRange(props.range);
|
|
2806
|
+
setInternalClientRect((_b = (_a = props.clientRect) == null ? void 0 : _a.call(props)) != null ? _b : null);
|
|
2807
|
+
},
|
|
2808
|
+
onKeyDown: (props) => {
|
|
2809
|
+
if (props.event.key === "Escape") {
|
|
2810
|
+
closePopup();
|
|
2811
|
+
return true;
|
|
2812
|
+
}
|
|
2813
|
+
return false;
|
|
2814
|
+
},
|
|
2815
|
+
onExit: () => {
|
|
2816
|
+
setInternalCommand(null);
|
|
2817
|
+
setInternalItems([]);
|
|
2818
|
+
setInternalQuery("");
|
|
2819
|
+
setInternalRange(null);
|
|
2820
|
+
setInternalClientRect(null);
|
|
2821
|
+
setShow(false);
|
|
2822
|
+
}
|
|
2823
|
+
};
|
|
2824
|
+
},
|
|
2825
|
+
...internalSuggestionPropsRef.current
|
|
2826
|
+
});
|
|
2827
|
+
editor.registerPlugin(suggestion);
|
|
2828
|
+
return () => {
|
|
2829
|
+
if (!editor.isDestroyed) {
|
|
2830
|
+
editor.unregisterPlugin(pluginKey);
|
|
2831
|
+
}
|
|
2832
|
+
};
|
|
2833
|
+
}, [editor, pluginKey, closePopup]);
|
|
2834
|
+
const onSelect = React5.useCallback(
|
|
2835
|
+
(item) => {
|
|
2836
|
+
closePopup();
|
|
2837
|
+
if (internalCommand) {
|
|
2838
|
+
internalCommand(item);
|
|
2839
|
+
}
|
|
2840
|
+
},
|
|
2841
|
+
[closePopup, internalCommand]
|
|
2842
|
+
);
|
|
2843
|
+
const { selectedIndex } = useMenuNavigation({
|
|
2844
|
+
editor,
|
|
2845
|
+
query: internalQuery,
|
|
2846
|
+
items: internalItems,
|
|
2847
|
+
onSelect
|
|
2848
|
+
});
|
|
2849
|
+
if (!isMounted || !show || !editor) {
|
|
2850
|
+
return null;
|
|
2851
|
+
}
|
|
2852
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react27.FloatingPortal, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2853
|
+
"div",
|
|
2854
|
+
{
|
|
2855
|
+
ref,
|
|
2856
|
+
style,
|
|
2857
|
+
...getFloatingProps(),
|
|
2858
|
+
"data-selector": selector,
|
|
2859
|
+
className: "tiptap-suggestion-menu",
|
|
2860
|
+
role: "listbox",
|
|
2861
|
+
"aria-label": "Suggestions",
|
|
2862
|
+
onPointerDown: (e) => e.preventDefault(),
|
|
2863
|
+
children: children({
|
|
2864
|
+
items: internalItems,
|
|
2865
|
+
selectedIndex,
|
|
2866
|
+
onSelect
|
|
2867
|
+
})
|
|
2868
|
+
}
|
|
2869
|
+
) });
|
|
2870
|
+
};
|
|
2871
|
+
|
|
2872
|
+
// src/extensions/variable/variable-suggestion.tsx
|
|
2873
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2874
|
+
var VariableSuggestionPluginKey = new import_state2.PluginKey("variableSuggestion");
|
|
2875
|
+
function VariableSuggestion({
|
|
2876
|
+
editor,
|
|
2877
|
+
variables
|
|
2878
|
+
}) {
|
|
2879
|
+
const getItems = React6.useCallback(
|
|
2880
|
+
({ query }) => {
|
|
2881
|
+
const normalizedQuery = query.toLowerCase().trim();
|
|
2882
|
+
const items = [];
|
|
2883
|
+
const matchingVariables = variables.filter((variable) => {
|
|
2884
|
+
var _a, _b;
|
|
2885
|
+
if (!normalizedQuery) return true;
|
|
2886
|
+
return variable.name.toLowerCase().includes(normalizedQuery) || variable.label.toLowerCase().includes(normalizedQuery) || ((_a = variable.category) == null ? void 0 : _a.toLowerCase().includes(normalizedQuery)) || ((_b = variable.description) == null ? void 0 : _b.toLowerCase().includes(normalizedQuery));
|
|
2887
|
+
});
|
|
2888
|
+
for (const variable of matchingVariables) {
|
|
2889
|
+
items.push({
|
|
2890
|
+
title: variable.label,
|
|
2891
|
+
subtext: variable.name,
|
|
2892
|
+
group: variable.category,
|
|
2893
|
+
keywords: [variable.name, variable.label, variable.category].filter(
|
|
2894
|
+
Boolean
|
|
2895
|
+
),
|
|
2896
|
+
onSelect: ({ editor: editor2 }) => {
|
|
2897
|
+
const attrs = {
|
|
2898
|
+
name: variable.name,
|
|
2899
|
+
fallback: variable.fallback,
|
|
2900
|
+
category: variable.category
|
|
2901
|
+
};
|
|
2902
|
+
editor2.chain().focus().insertVariable(attrs).run();
|
|
2903
|
+
}
|
|
2904
|
+
});
|
|
2905
|
+
}
|
|
2906
|
+
if (normalizedQuery && !variables.some((v) => v.name.toLowerCase() === normalizedQuery)) {
|
|
2907
|
+
items.push({
|
|
2908
|
+
title: `Neue Variable "${query}"`,
|
|
2909
|
+
subtext: query,
|
|
2910
|
+
group: "Neu",
|
|
2911
|
+
onSelect: ({ editor: editor2 }) => {
|
|
2912
|
+
const attrs = {
|
|
2913
|
+
name: query
|
|
2914
|
+
};
|
|
2915
|
+
editor2.chain().focus().insertVariable(attrs).run();
|
|
2916
|
+
}
|
|
2917
|
+
});
|
|
2918
|
+
}
|
|
2919
|
+
return items;
|
|
2920
|
+
},
|
|
2921
|
+
[variables]
|
|
2922
|
+
);
|
|
2923
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2924
|
+
SuggestionMenu,
|
|
2925
|
+
{
|
|
2926
|
+
editor,
|
|
2927
|
+
pluginKey: VariableSuggestionPluginKey,
|
|
2928
|
+
char: "{{",
|
|
2929
|
+
items: getItems,
|
|
2930
|
+
allowSpaces: false,
|
|
2931
|
+
selector: "tiptap-variable-suggestion-menu",
|
|
2932
|
+
children: (props) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(VariableList, { ...props })
|
|
2933
|
+
}
|
|
2934
|
+
);
|
|
2935
|
+
}
|
|
2936
|
+
var VariableItem = ({
|
|
2937
|
+
item,
|
|
2938
|
+
isSelected,
|
|
2939
|
+
onSelect
|
|
2940
|
+
}) => {
|
|
2941
|
+
const itemRef = React6.useRef(null);
|
|
2942
|
+
React6.useEffect(() => {
|
|
2943
|
+
const selector = document.querySelector(
|
|
2944
|
+
'[data-selector="tiptap-variable-suggestion-menu"]'
|
|
2945
|
+
);
|
|
2946
|
+
if (!itemRef.current || !isSelected || !selector) return;
|
|
2947
|
+
const overflow = (0, import_editor_utils.getElementOverflowPosition)(itemRef.current, selector);
|
|
2948
|
+
if (overflow === "top") {
|
|
2949
|
+
itemRef.current.scrollIntoView(true);
|
|
2950
|
+
} else if (overflow === "bottom") {
|
|
2951
|
+
itemRef.current.scrollIntoView(false);
|
|
2952
|
+
}
|
|
2953
|
+
}, [isSelected]);
|
|
2954
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
2955
|
+
"button",
|
|
2956
|
+
{
|
|
2957
|
+
ref: itemRef,
|
|
2958
|
+
type: "button",
|
|
2959
|
+
"data-active-state": isSelected ? "on" : "off",
|
|
2960
|
+
onClick: onSelect,
|
|
2961
|
+
className: "w-full flex items-center justify-between gap-3 px-2 py-1.5 text-sm rounded-sm outline-none hover:bg-muted data-[active-state=on]:bg-muted",
|
|
2962
|
+
children: [
|
|
2963
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-medium truncate", children: item.title }),
|
|
2964
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("code", { className: "text-xs text-muted-foreground font-mono shrink-0", children: item.subtext })
|
|
2965
|
+
]
|
|
2966
|
+
}
|
|
2967
|
+
);
|
|
2968
|
+
};
|
|
2969
|
+
var VariableList = ({
|
|
2970
|
+
items,
|
|
2971
|
+
selectedIndex,
|
|
2972
|
+
onSelect
|
|
2973
|
+
}) => {
|
|
2974
|
+
const styles = (0, import_theme6.slashDropdownMenu)();
|
|
2975
|
+
const renderedItems = React6.useMemo(() => {
|
|
2976
|
+
const rendered = [];
|
|
2977
|
+
const groups = {};
|
|
2978
|
+
items.forEach((item, index) => {
|
|
2979
|
+
const groupLabel = item.group || "";
|
|
2980
|
+
if (!groups[groupLabel]) {
|
|
2981
|
+
groups[groupLabel] = { items: [], indices: [] };
|
|
2982
|
+
}
|
|
2983
|
+
groups[groupLabel].items.push(item);
|
|
2984
|
+
groups[groupLabel].indices.push(index);
|
|
2985
|
+
});
|
|
2986
|
+
Object.entries(groups).forEach(([groupLabel, groupData], groupIndex) => {
|
|
2987
|
+
const groupItems = groupData.items.map((item, itemIndex) => {
|
|
2988
|
+
const originalIndex = groupData.indices[itemIndex];
|
|
2989
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2990
|
+
VariableItem,
|
|
2991
|
+
{
|
|
2992
|
+
item,
|
|
2993
|
+
isSelected: originalIndex === selectedIndex,
|
|
2994
|
+
onSelect: () => onSelect(item)
|
|
2995
|
+
},
|
|
2996
|
+
`item-${originalIndex}-${item.title}`
|
|
2997
|
+
);
|
|
2998
|
+
});
|
|
2999
|
+
if (groupLabel) {
|
|
3000
|
+
rendered.push(
|
|
3001
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "py-1", children: [
|
|
3002
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "px-2 py-1 text-xs font-semibold text-muted-foreground uppercase tracking-wide", children: groupLabel }),
|
|
3003
|
+
groupItems
|
|
3004
|
+
] }, `group-${groupIndex}-${groupLabel}`)
|
|
3005
|
+
);
|
|
3006
|
+
} else {
|
|
3007
|
+
rendered.push(...groupItems);
|
|
3008
|
+
}
|
|
3009
|
+
});
|
|
3010
|
+
return rendered;
|
|
3011
|
+
}, [items, selectedIndex, onSelect]);
|
|
3012
|
+
if (!renderedItems.length) {
|
|
3013
|
+
return null;
|
|
3014
|
+
}
|
|
3015
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3016
|
+
"div",
|
|
3017
|
+
{
|
|
3018
|
+
className: styles.card(),
|
|
3019
|
+
style: {
|
|
3020
|
+
maxHeight: "var(--suggestion-menu-max-height)",
|
|
3021
|
+
minWidth: "240px"
|
|
3022
|
+
},
|
|
3023
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: styles.body(), children: renderedItems })
|
|
3024
|
+
}
|
|
3025
|
+
);
|
|
3026
|
+
};
|
|
3027
|
+
|
|
3028
|
+
// src/hooks/use-create-editor.ts
|
|
3029
|
+
var import_extension_code = require("@kopexa/extension-code");
|
|
3030
|
+
var import_extension_controlref = require("@kopexa/extension-controlref");
|
|
3031
|
+
var import_extension_table = require("@kopexa/extension-table");
|
|
3032
|
+
var import_extension_file_handler = require("@tiptap/extension-file-handler");
|
|
3033
|
+
var import_extension_highlight = require("@tiptap/extension-highlight");
|
|
3034
|
+
var import_extension_invisible_characters = __toESM(require("@tiptap/extension-invisible-characters"));
|
|
3035
|
+
var import_extension_list = require("@tiptap/extension-list");
|
|
3036
|
+
var import_extension_subscript = require("@tiptap/extension-subscript");
|
|
3037
|
+
var import_extension_superscript = require("@tiptap/extension-superscript");
|
|
3038
|
+
var import_extension_table_of_contents = require("@tiptap/extension-table-of-contents");
|
|
3039
|
+
var import_extension_text_align = require("@tiptap/extension-text-align");
|
|
3040
|
+
var import_extension_text_style = require("@tiptap/extension-text-style");
|
|
3041
|
+
var import_extension_typography = require("@tiptap/extension-typography");
|
|
3042
|
+
var import_extension_unique_id = require("@tiptap/extension-unique-id");
|
|
3043
|
+
var import_extensions = require("@tiptap/extensions");
|
|
3044
|
+
var import_react31 = require("@tiptap/react");
|
|
3045
|
+
var import_starter_kit = require("@tiptap/starter-kit");
|
|
3046
|
+
var import_react32 = require("react");
|
|
3047
|
+
|
|
3048
|
+
// src/extensions/link/index.ts
|
|
3049
|
+
var import_extension_link = __toESM(require("@tiptap/extension-link"));
|
|
3050
|
+
var import_state3 = require("@tiptap/pm/state");
|
|
3051
|
+
var import_react28 = require("@tiptap/react");
|
|
3052
|
+
var Link = import_extension_link.default.extend({
|
|
3053
|
+
inclusive: false,
|
|
3054
|
+
parseHTML() {
|
|
3055
|
+
return [
|
|
3056
|
+
{
|
|
3057
|
+
tag: 'a[href]:not([data-type="button"]):not([href *= "javascript:" i])'
|
|
3058
|
+
}
|
|
3059
|
+
];
|
|
3060
|
+
},
|
|
3061
|
+
addProseMirrorPlugins() {
|
|
3062
|
+
var _a;
|
|
3063
|
+
const { editor } = this;
|
|
3064
|
+
return [
|
|
3065
|
+
...((_a = this.parent) == null ? void 0 : _a.call(this)) || [],
|
|
3066
|
+
new import_state3.Plugin({
|
|
3067
|
+
key: new import_state3.PluginKey("linkKeyHandler"),
|
|
3068
|
+
props: {
|
|
3069
|
+
handleKeyDown: (_, event) => {
|
|
3070
|
+
const { selection } = editor.state;
|
|
3071
|
+
if (event.key === "Escape" && selection.empty !== true) {
|
|
3072
|
+
editor.commands.focus(selection.to, { scrollIntoView: false });
|
|
3073
|
+
}
|
|
3074
|
+
return false;
|
|
3075
|
+
},
|
|
3076
|
+
handleClick(view, pos) {
|
|
3077
|
+
const { schema, doc, tr } = view.state;
|
|
3078
|
+
let range;
|
|
3079
|
+
if (schema.marks.link) {
|
|
3080
|
+
range = (0, import_react28.getMarkRange)(doc.resolve(pos), schema.marks.link);
|
|
3081
|
+
}
|
|
3082
|
+
if (!range) {
|
|
3083
|
+
return;
|
|
3084
|
+
}
|
|
3085
|
+
const { from, to } = range;
|
|
3086
|
+
const start = Math.min(from, to);
|
|
3087
|
+
const end = Math.max(from, to);
|
|
3088
|
+
if (pos < start || pos > end) {
|
|
3089
|
+
return;
|
|
3090
|
+
}
|
|
3091
|
+
const $start = doc.resolve(start);
|
|
3092
|
+
const $end = doc.resolve(end);
|
|
3093
|
+
const transaction = tr.setSelection(
|
|
3094
|
+
new import_state3.TextSelection($start, $end)
|
|
3095
|
+
);
|
|
3096
|
+
view.dispatch(transaction);
|
|
3097
|
+
}
|
|
3098
|
+
}
|
|
3099
|
+
})
|
|
3100
|
+
];
|
|
3101
|
+
}
|
|
3102
|
+
});
|
|
3103
|
+
|
|
3104
|
+
// src/extensions/selection/index.ts
|
|
3105
|
+
var import_state4 = require("@tiptap/pm/state");
|
|
3106
|
+
var import_view = require("@tiptap/pm/view");
|
|
3107
|
+
var import_react29 = require("@tiptap/react");
|
|
3108
|
+
var Selection = import_react29.Extension.create({
|
|
3109
|
+
name: "selection",
|
|
3110
|
+
addProseMirrorPlugins() {
|
|
3111
|
+
const { editor } = this;
|
|
3112
|
+
return [
|
|
3113
|
+
new import_state4.Plugin({
|
|
3114
|
+
key: new import_state4.PluginKey("selection"),
|
|
3115
|
+
props: {
|
|
3116
|
+
decorations(state) {
|
|
3117
|
+
if (state.selection.empty) {
|
|
3118
|
+
return null;
|
|
3119
|
+
}
|
|
3120
|
+
if (editor.isFocused === true || !editor.isEditable) {
|
|
3121
|
+
return null;
|
|
3122
|
+
}
|
|
3123
|
+
if ((0, import_react29.isNodeSelection)(state.selection)) {
|
|
3124
|
+
return null;
|
|
3125
|
+
}
|
|
3126
|
+
return import_view.DecorationSet.create(state.doc, [
|
|
3127
|
+
import_view.Decoration.inline(state.selection.from, state.selection.to, {
|
|
3128
|
+
class: "selection"
|
|
3129
|
+
})
|
|
3130
|
+
]);
|
|
3131
|
+
}
|
|
3132
|
+
}
|
|
3133
|
+
})
|
|
3134
|
+
];
|
|
3135
|
+
}
|
|
3136
|
+
});
|
|
3137
|
+
|
|
3138
|
+
// src/extensions/trailing-node/index.ts
|
|
3139
|
+
var import_state5 = require("@tiptap/pm/state");
|
|
3140
|
+
var import_react30 = require("@tiptap/react");
|
|
3141
|
+
function nodeEqualsType({
|
|
3142
|
+
types,
|
|
3143
|
+
node
|
|
3144
|
+
}) {
|
|
3145
|
+
if (!node) return false;
|
|
3146
|
+
if (Array.isArray(types)) {
|
|
3147
|
+
return types.includes(node.type);
|
|
3148
|
+
}
|
|
3149
|
+
return node.type === types;
|
|
3150
|
+
}
|
|
3151
|
+
var TrailingNode = import_react30.Extension.create({
|
|
3152
|
+
name: "trailingNode",
|
|
3153
|
+
addOptions() {
|
|
3154
|
+
return {
|
|
3155
|
+
node: "paragraph",
|
|
3156
|
+
notAfter: ["paragraph"]
|
|
3157
|
+
};
|
|
3158
|
+
},
|
|
3159
|
+
addProseMirrorPlugins() {
|
|
3160
|
+
const plugin = new import_state5.PluginKey(this.name);
|
|
3161
|
+
const disabledNodes = Object.entries(this.editor.schema.nodes).map(([, value]) => value).filter((node) => this.options.notAfter.includes(node.name));
|
|
3162
|
+
return [
|
|
3163
|
+
new import_state5.Plugin({
|
|
3164
|
+
key: plugin,
|
|
3165
|
+
appendTransaction: (_, __, state) => {
|
|
3166
|
+
const { doc, tr, schema } = state;
|
|
3167
|
+
const shouldInsertNodeAtEnd = plugin.getState(state);
|
|
3168
|
+
const endPosition = doc.content.size;
|
|
3169
|
+
const type = schema.nodes[this.options.node];
|
|
3170
|
+
if (!shouldInsertNodeAtEnd) {
|
|
3171
|
+
return null;
|
|
3172
|
+
}
|
|
3173
|
+
if (type) {
|
|
3174
|
+
return tr.insert(endPosition, type.create());
|
|
3175
|
+
}
|
|
3176
|
+
return null;
|
|
3177
|
+
},
|
|
3178
|
+
state: {
|
|
3179
|
+
init: (_, state) => {
|
|
3180
|
+
const lastNode = state.tr.doc.lastChild;
|
|
3181
|
+
return !nodeEqualsType({ node: lastNode, types: disabledNodes });
|
|
3182
|
+
},
|
|
3183
|
+
apply: (tr, value) => {
|
|
3184
|
+
if (!tr.docChanged) {
|
|
3185
|
+
return value;
|
|
3186
|
+
}
|
|
3187
|
+
const lastNode = tr.doc.lastChild;
|
|
3188
|
+
return !nodeEqualsType({ node: lastNode, types: disabledNodes });
|
|
3189
|
+
}
|
|
3190
|
+
}
|
|
3191
|
+
})
|
|
3192
|
+
];
|
|
3193
|
+
}
|
|
3194
|
+
});
|
|
3195
|
+
|
|
3196
|
+
// src/extensions/ui-state/index.ts
|
|
3197
|
+
var import_core7 = require("@tiptap/core");
|
|
3198
|
+
var defaultUiState = {
|
|
3199
|
+
aiGenerationIsSelection: false,
|
|
3200
|
+
aiGenerationIsLoading: false,
|
|
3201
|
+
aiGenerationActive: false,
|
|
3202
|
+
aiGenerationHasMessage: false,
|
|
3203
|
+
commentInputVisible: false,
|
|
2223
3204
|
lockDragHandle: false,
|
|
2224
3205
|
isDragging: false
|
|
2225
3206
|
};
|
|
2226
|
-
var UiState =
|
|
3207
|
+
var UiState = import_core7.Extension.create({
|
|
2227
3208
|
name: "uiState",
|
|
2228
3209
|
addStorage() {
|
|
2229
3210
|
return {
|
|
@@ -2439,20 +3420,22 @@ var useCreateEditor = ({
|
|
|
2439
3420
|
enableControls = false,
|
|
2440
3421
|
controlResolver,
|
|
2441
3422
|
fileHandler: fileHandlerProp,
|
|
3423
|
+
enableVariables = false,
|
|
2442
3424
|
...options
|
|
2443
3425
|
}) => {
|
|
2444
3426
|
const fileHandlerFromContext = useEditorFile();
|
|
2445
3427
|
const fileHandler = fileHandlerProp != null ? fileHandlerProp : fileHandlerFromContext;
|
|
2446
|
-
const [extensions] = (0,
|
|
3428
|
+
const [extensions] = (0, import_react32.useState)(
|
|
2447
3429
|
() => getExtensions({
|
|
2448
3430
|
editable,
|
|
2449
3431
|
placeholder,
|
|
2450
3432
|
enableControls,
|
|
2451
3433
|
controlResolver,
|
|
2452
|
-
fileHandler
|
|
3434
|
+
fileHandler,
|
|
3435
|
+
enableVariables
|
|
2453
3436
|
})
|
|
2454
3437
|
);
|
|
2455
|
-
const editor = (0,
|
|
3438
|
+
const editor = (0, import_react31.useEditor)({
|
|
2456
3439
|
editorProps: {
|
|
2457
3440
|
attributes: {
|
|
2458
3441
|
autocomplete: "off",
|
|
@@ -2471,7 +3454,7 @@ var useCreateEditor = ({
|
|
|
2471
3454
|
content: safeParseContent(content),
|
|
2472
3455
|
...options
|
|
2473
3456
|
});
|
|
2474
|
-
(0,
|
|
3457
|
+
(0, import_react32.useEffect)(() => {
|
|
2475
3458
|
if (editor && editor.isEditable !== editable) {
|
|
2476
3459
|
editor.setEditable(editable);
|
|
2477
3460
|
}
|
|
@@ -2483,7 +3466,8 @@ function getExtensions({
|
|
|
2483
3466
|
placeholder,
|
|
2484
3467
|
enableControls = false,
|
|
2485
3468
|
controlResolver,
|
|
2486
|
-
fileHandler
|
|
3469
|
+
fileHandler,
|
|
3470
|
+
enableVariables = false
|
|
2487
3471
|
}) {
|
|
2488
3472
|
const extensions = [
|
|
2489
3473
|
import_starter_kit.StarterKit.configure({
|
|
@@ -2549,6 +3533,9 @@ function getExtensions({
|
|
|
2549
3533
|
if (enableControls) {
|
|
2550
3534
|
extensions.push(import_extension_controlref.ControlKit.configure({ resolver: controlResolver }));
|
|
2551
3535
|
}
|
|
3536
|
+
if (enableVariables) {
|
|
3537
|
+
extensions.push(VariableNode);
|
|
3538
|
+
}
|
|
2552
3539
|
if (fileHandler) {
|
|
2553
3540
|
extensions.push(
|
|
2554
3541
|
import_extension_file_handler.FileHandler.configure({
|
|
@@ -2633,19 +3620,19 @@ async function handleFileUpload(editor, file, fileHandler, pos) {
|
|
|
2633
3620
|
}
|
|
2634
3621
|
|
|
2635
3622
|
// src/presets/basic/index.tsx
|
|
2636
|
-
var
|
|
2637
|
-
var
|
|
2638
|
-
var
|
|
3623
|
+
var import_theme9 = require("@kopexa/theme");
|
|
3624
|
+
var import_react56 = require("@tiptap/react");
|
|
3625
|
+
var import_react57 = require("react");
|
|
2639
3626
|
|
|
2640
3627
|
// src/context/editor-context.ts
|
|
2641
3628
|
var import_react_utils = require("@kopexa/react-utils");
|
|
2642
3629
|
var [EditorUIProvider, useEditorUIContext] = (0, import_react_utils.createContext)();
|
|
2643
3630
|
|
|
2644
3631
|
// src/hooks/use-ui-editor-state.ts
|
|
2645
|
-
var
|
|
3632
|
+
var import_react33 = require("@tiptap/react");
|
|
2646
3633
|
function useUiEditorState(editor) {
|
|
2647
3634
|
var _a;
|
|
2648
|
-
return (_a = (0,
|
|
3635
|
+
return (_a = (0, import_react33.useEditorState)({
|
|
2649
3636
|
editor,
|
|
2650
3637
|
selector: ({ editor: editor2 }) => {
|
|
2651
3638
|
if (!editor2) return defaultUiState;
|
|
@@ -2665,47 +3652,18 @@ function useUiEditorState(editor) {
|
|
|
2665
3652
|
var import_toolbar3 = require("@kopexa/toolbar");
|
|
2666
3653
|
var import_menus = require("@tiptap/react/menus");
|
|
2667
3654
|
|
|
2668
|
-
// src/ui/link-popover/link-popover.tsx
|
|
2669
|
-
var
|
|
2670
|
-
var import_icons9 = require("@kopexa/icons");
|
|
2671
|
-
var
|
|
2672
|
-
var import_popover = require("@kopexa/popover");
|
|
2673
|
-
var import_toolbar = require("@kopexa/toolbar");
|
|
2674
|
-
var
|
|
2675
|
-
|
|
2676
|
-
// src/hooks/use-tiptap-editor.ts
|
|
2677
|
-
var import_react28 = require("@tiptap/react");
|
|
2678
|
-
var import_react29 = require("react");
|
|
2679
|
-
function useTiptapEditor(providedEditor) {
|
|
2680
|
-
const { editor: coreEditor } = (0, import_react28.useCurrentEditor)();
|
|
2681
|
-
const mainEditor = (0, import_react29.useMemo)(
|
|
2682
|
-
() => providedEditor || coreEditor,
|
|
2683
|
-
[providedEditor, coreEditor]
|
|
2684
|
-
);
|
|
2685
|
-
const editorState = (0, import_react28.useEditorState)({
|
|
2686
|
-
editor: mainEditor,
|
|
2687
|
-
selector(context) {
|
|
2688
|
-
if (!context.editor) {
|
|
2689
|
-
return {
|
|
2690
|
-
editor: null,
|
|
2691
|
-
editorState: void 0,
|
|
2692
|
-
canCommand: void 0
|
|
2693
|
-
};
|
|
2694
|
-
}
|
|
2695
|
-
return {
|
|
2696
|
-
editor: context.editor,
|
|
2697
|
-
editorState: context.editor.state,
|
|
2698
|
-
canCommand: context.editor.can
|
|
2699
|
-
};
|
|
2700
|
-
}
|
|
2701
|
-
});
|
|
2702
|
-
return editorState || { editor: null };
|
|
2703
|
-
}
|
|
3655
|
+
// src/ui/link-popover/link-popover.tsx
|
|
3656
|
+
var import_button8 = require("@kopexa/button");
|
|
3657
|
+
var import_icons9 = require("@kopexa/icons");
|
|
3658
|
+
var import_input3 = require("@kopexa/input");
|
|
3659
|
+
var import_popover = require("@kopexa/popover");
|
|
3660
|
+
var import_toolbar = require("@kopexa/toolbar");
|
|
3661
|
+
var import_react34 = require("react");
|
|
2704
3662
|
|
|
2705
3663
|
// src/ui/link-popover/use-link-popover.ts
|
|
2706
|
-
var
|
|
3664
|
+
var import_editor_utils2 = require("@kopexa/editor-utils");
|
|
2707
3665
|
var import_icons8 = require("@kopexa/icons");
|
|
2708
|
-
var
|
|
3666
|
+
var React7 = __toESM(require("react"));
|
|
2709
3667
|
|
|
2710
3668
|
// src/utils/index.ts
|
|
2711
3669
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
@@ -2810,7 +3768,7 @@ function isLinkActive(editor) {
|
|
|
2810
3768
|
}
|
|
2811
3769
|
function shouldShowLinkButton(props) {
|
|
2812
3770
|
const { editor, hideWhenUnavailable } = props;
|
|
2813
|
-
const linkInSchema = (0,
|
|
3771
|
+
const linkInSchema = (0, import_editor_utils2.isMarkInSchema)("link", editor);
|
|
2814
3772
|
if (!linkInSchema || !editor) {
|
|
2815
3773
|
return false;
|
|
2816
3774
|
}
|
|
@@ -2821,15 +3779,15 @@ function shouldShowLinkButton(props) {
|
|
|
2821
3779
|
}
|
|
2822
3780
|
function useLinkHandler(props) {
|
|
2823
3781
|
const { editor, onSetLink } = props;
|
|
2824
|
-
const [url, setUrl] =
|
|
2825
|
-
|
|
3782
|
+
const [url, setUrl] = React7.useState(null);
|
|
3783
|
+
React7.useEffect(() => {
|
|
2826
3784
|
if (!editor) return;
|
|
2827
3785
|
const { href } = editor.getAttributes("link");
|
|
2828
3786
|
if (isLinkActive(editor) && url === null) {
|
|
2829
3787
|
setUrl(href || "");
|
|
2830
3788
|
}
|
|
2831
3789
|
}, [editor, url]);
|
|
2832
|
-
|
|
3790
|
+
React7.useEffect(() => {
|
|
2833
3791
|
if (!editor) return;
|
|
2834
3792
|
const updateLinkState = () => {
|
|
2835
3793
|
const { href } = editor.getAttributes("link");
|
|
@@ -2840,7 +3798,7 @@ function useLinkHandler(props) {
|
|
|
2840
3798
|
editor.off("selectionUpdate", updateLinkState);
|
|
2841
3799
|
};
|
|
2842
3800
|
}, [editor]);
|
|
2843
|
-
const setLink =
|
|
3801
|
+
const setLink = React7.useCallback(() => {
|
|
2844
3802
|
if (!url || !editor) return;
|
|
2845
3803
|
const { selection } = editor.state;
|
|
2846
3804
|
const isEmpty = selection.empty;
|
|
@@ -2853,12 +3811,12 @@ function useLinkHandler(props) {
|
|
|
2853
3811
|
setUrl(null);
|
|
2854
3812
|
onSetLink == null ? void 0 : onSetLink();
|
|
2855
3813
|
}, [editor, onSetLink, url]);
|
|
2856
|
-
const removeLink =
|
|
3814
|
+
const removeLink = React7.useCallback(() => {
|
|
2857
3815
|
if (!editor) return;
|
|
2858
3816
|
editor.chain().focus().extendMarkRange("link").unsetLink().setMeta("preventAutolink", true).run();
|
|
2859
3817
|
setUrl("");
|
|
2860
3818
|
}, [editor]);
|
|
2861
|
-
const openLink =
|
|
3819
|
+
const openLink = React7.useCallback(
|
|
2862
3820
|
(target = "_blank", features = "noopener,noreferrer") => {
|
|
2863
3821
|
if (!url) return;
|
|
2864
3822
|
const safeUrl = sanitizeUrl(url, window.location.href);
|
|
@@ -2880,8 +3838,8 @@ function useLinkState(props) {
|
|
|
2880
3838
|
const { editor, hideWhenUnavailable = false } = props;
|
|
2881
3839
|
const canSet = canSetLink(editor);
|
|
2882
3840
|
const isActive = isLinkActive(editor);
|
|
2883
|
-
const [isVisible, setIsVisible] =
|
|
2884
|
-
|
|
3841
|
+
const [isVisible, setIsVisible] = React7.useState(false);
|
|
3842
|
+
React7.useEffect(() => {
|
|
2885
3843
|
if (!editor) return;
|
|
2886
3844
|
const handleSelectionUpdate = () => {
|
|
2887
3845
|
setIsVisible(
|
|
@@ -2929,9 +3887,9 @@ function useLinkPopover(config) {
|
|
|
2929
3887
|
}
|
|
2930
3888
|
|
|
2931
3889
|
// src/ui/link-popover/link-popover.tsx
|
|
2932
|
-
var
|
|
3890
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2933
3891
|
var LinkButton = ({ className, children, ...props }) => {
|
|
2934
|
-
return /* @__PURE__ */ (0,
|
|
3892
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2935
3893
|
import_toolbar.ToolbarButton,
|
|
2936
3894
|
{
|
|
2937
3895
|
type: "button",
|
|
@@ -2943,7 +3901,7 @@ var LinkButton = ({ className, children, ...props }) => {
|
|
|
2943
3901
|
title: "Link",
|
|
2944
3902
|
isIconOnly: !children,
|
|
2945
3903
|
...props,
|
|
2946
|
-
children: children || /* @__PURE__ */ (0,
|
|
3904
|
+
children: children || /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_icons9.LinkIcon, {})
|
|
2947
3905
|
}
|
|
2948
3906
|
);
|
|
2949
3907
|
};
|
|
@@ -2956,8 +3914,8 @@ var LinkMain = ({
|
|
|
2956
3914
|
isActive,
|
|
2957
3915
|
onSave
|
|
2958
3916
|
}) => {
|
|
2959
|
-
const [isEditing, setIsEditing] = (0,
|
|
2960
|
-
(0,
|
|
3917
|
+
const [isEditing, setIsEditing] = (0, import_react34.useState)(!isActive || !url);
|
|
3918
|
+
(0, import_react34.useEffect)(() => {
|
|
2961
3919
|
setIsEditing(!isActive || !url);
|
|
2962
3920
|
}, [isActive, url]);
|
|
2963
3921
|
const handleKeyDown = (event) => {
|
|
@@ -2980,9 +3938,9 @@ var LinkMain = ({
|
|
|
2980
3938
|
setIsEditing(true);
|
|
2981
3939
|
};
|
|
2982
3940
|
if (isEditing) {
|
|
2983
|
-
return /* @__PURE__ */ (0,
|
|
2984
|
-
/* @__PURE__ */ (0,
|
|
2985
|
-
|
|
3941
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-1 min-w-[280px]", children: [
|
|
3942
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3943
|
+
import_input3.Input,
|
|
2986
3944
|
{
|
|
2987
3945
|
type: "url",
|
|
2988
3946
|
placeholder: "Enter URL...",
|
|
@@ -2996,8 +3954,8 @@ var LinkMain = ({
|
|
|
2996
3954
|
autoFocus: true
|
|
2997
3955
|
}
|
|
2998
3956
|
),
|
|
2999
|
-
/* @__PURE__ */ (0,
|
|
3000
|
-
|
|
3957
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3958
|
+
import_button8.IconButton,
|
|
3001
3959
|
{
|
|
3002
3960
|
type: "button",
|
|
3003
3961
|
size: "sm",
|
|
@@ -3005,13 +3963,13 @@ var LinkMain = ({
|
|
|
3005
3963
|
onClick: handleSave,
|
|
3006
3964
|
"aria-label": "Save link",
|
|
3007
3965
|
disabled: !url,
|
|
3008
|
-
children: /* @__PURE__ */ (0,
|
|
3966
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_icons9.CheckIcon, { className: "size-4" })
|
|
3009
3967
|
}
|
|
3010
3968
|
)
|
|
3011
3969
|
] });
|
|
3012
3970
|
}
|
|
3013
|
-
return /* @__PURE__ */ (0,
|
|
3014
|
-
/* @__PURE__ */ (0,
|
|
3971
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-1 min-w-[280px]", children: [
|
|
3972
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3015
3973
|
"a",
|
|
3016
3974
|
{
|
|
3017
3975
|
href: url,
|
|
@@ -3025,38 +3983,38 @@ var LinkMain = ({
|
|
|
3025
3983
|
children: url
|
|
3026
3984
|
}
|
|
3027
3985
|
),
|
|
3028
|
-
/* @__PURE__ */ (0,
|
|
3029
|
-
/* @__PURE__ */ (0,
|
|
3030
|
-
|
|
3986
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-0.5 border-l pl-1 ml-1", children: [
|
|
3987
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3988
|
+
import_button8.IconButton,
|
|
3031
3989
|
{
|
|
3032
3990
|
type: "button",
|
|
3033
3991
|
size: "sm",
|
|
3034
3992
|
variant: "ghost",
|
|
3035
3993
|
onClick: openLink,
|
|
3036
3994
|
"aria-label": "Open link in new tab",
|
|
3037
|
-
children: /* @__PURE__ */ (0,
|
|
3995
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_icons9.ExternalLinkIcon, { className: "size-4" })
|
|
3038
3996
|
}
|
|
3039
3997
|
),
|
|
3040
|
-
/* @__PURE__ */ (0,
|
|
3041
|
-
|
|
3998
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3999
|
+
import_button8.IconButton,
|
|
3042
4000
|
{
|
|
3043
4001
|
type: "button",
|
|
3044
4002
|
size: "sm",
|
|
3045
4003
|
variant: "ghost",
|
|
3046
4004
|
onClick: handleEdit,
|
|
3047
4005
|
"aria-label": "Edit link",
|
|
3048
|
-
children: /* @__PURE__ */ (0,
|
|
4006
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_icons9.EditIcon, { className: "size-4" })
|
|
3049
4007
|
}
|
|
3050
4008
|
),
|
|
3051
|
-
/* @__PURE__ */ (0,
|
|
3052
|
-
|
|
4009
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
4010
|
+
import_button8.IconButton,
|
|
3053
4011
|
{
|
|
3054
4012
|
type: "button",
|
|
3055
4013
|
size: "sm",
|
|
3056
4014
|
variant: "ghost",
|
|
3057
4015
|
onClick: removeLink,
|
|
3058
4016
|
"aria-label": "Remove link",
|
|
3059
|
-
children: /* @__PURE__ */ (0,
|
|
4017
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_icons9.TrashIcon, { className: "size-4" })
|
|
3060
4018
|
}
|
|
3061
4019
|
)
|
|
3062
4020
|
] })
|
|
@@ -3073,7 +4031,7 @@ function LinkPopover({
|
|
|
3073
4031
|
...buttonProps
|
|
3074
4032
|
}) {
|
|
3075
4033
|
const { editor } = useTiptapEditor(providedEditor);
|
|
3076
|
-
const [isOpen, setIsOpen] = (0,
|
|
4034
|
+
const [isOpen, setIsOpen] = (0, import_react34.useState)(false);
|
|
3077
4035
|
const {
|
|
3078
4036
|
isVisible,
|
|
3079
4037
|
canSet,
|
|
@@ -3089,18 +4047,18 @@ function LinkPopover({
|
|
|
3089
4047
|
hideWhenUnavailable,
|
|
3090
4048
|
onSetLink
|
|
3091
4049
|
});
|
|
3092
|
-
const handleOnOpenChange = (0,
|
|
4050
|
+
const handleOnOpenChange = (0, import_react34.useCallback)(
|
|
3093
4051
|
(nextIsOpen) => {
|
|
3094
4052
|
setIsOpen(nextIsOpen);
|
|
3095
4053
|
onOpenChange == null ? void 0 : onOpenChange(nextIsOpen);
|
|
3096
4054
|
},
|
|
3097
4055
|
[onOpenChange]
|
|
3098
4056
|
);
|
|
3099
|
-
const handleSetLink = (0,
|
|
4057
|
+
const handleSetLink = (0, import_react34.useCallback)(() => {
|
|
3100
4058
|
setLink();
|
|
3101
4059
|
setIsOpen(false);
|
|
3102
4060
|
}, [setLink]);
|
|
3103
|
-
const handleClick = (0,
|
|
4061
|
+
const handleClick = (0, import_react34.useCallback)(
|
|
3104
4062
|
(event) => {
|
|
3105
4063
|
onClick == null ? void 0 : onClick(event);
|
|
3106
4064
|
if (event.defaultPrevented) return;
|
|
@@ -3108,7 +4066,7 @@ function LinkPopover({
|
|
|
3108
4066
|
},
|
|
3109
4067
|
[onClick, isOpen]
|
|
3110
4068
|
);
|
|
3111
|
-
(0,
|
|
4069
|
+
(0, import_react34.useEffect)(() => {
|
|
3112
4070
|
if (autoOpenOnLinkActive && isActive) {
|
|
3113
4071
|
setIsOpen(true);
|
|
3114
4072
|
}
|
|
@@ -3116,17 +4074,17 @@ function LinkPopover({
|
|
|
3116
4074
|
if (!isVisible) {
|
|
3117
4075
|
return null;
|
|
3118
4076
|
}
|
|
3119
|
-
return /* @__PURE__ */ (0,
|
|
4077
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
3120
4078
|
import_popover.Popover.Root,
|
|
3121
4079
|
{
|
|
3122
4080
|
open: isOpen,
|
|
3123
4081
|
onOpenChange: handleOnOpenChange,
|
|
3124
4082
|
spacing: "dense",
|
|
3125
4083
|
children: [
|
|
3126
|
-
/* @__PURE__ */ (0,
|
|
4084
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3127
4085
|
import_popover.Popover.Trigger,
|
|
3128
4086
|
{
|
|
3129
|
-
render: /* @__PURE__ */ (0,
|
|
4087
|
+
render: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3130
4088
|
LinkButton,
|
|
3131
4089
|
{
|
|
3132
4090
|
"data-disabled": !canSet,
|
|
@@ -3140,7 +4098,7 @@ function LinkPopover({
|
|
|
3140
4098
|
)
|
|
3141
4099
|
}
|
|
3142
4100
|
),
|
|
3143
|
-
/* @__PURE__ */ (0,
|
|
4101
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_popover.Popover.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3144
4102
|
LinkMain,
|
|
3145
4103
|
{
|
|
3146
4104
|
url,
|
|
@@ -3159,12 +4117,12 @@ function LinkPopover({
|
|
|
3159
4117
|
LinkButton.displayName = "LinkButton";
|
|
3160
4118
|
|
|
3161
4119
|
// src/ui/mark-button/index.tsx
|
|
3162
|
-
var
|
|
4120
|
+
var import_editor_utils3 = require("@kopexa/editor-utils");
|
|
3163
4121
|
var import_icons10 = require("@kopexa/icons");
|
|
3164
4122
|
var import_toolbar2 = require("@kopexa/toolbar");
|
|
3165
|
-
var
|
|
3166
|
-
var
|
|
3167
|
-
var
|
|
4123
|
+
var import_react35 = require("@tiptap/react");
|
|
4124
|
+
var import_react36 = require("react");
|
|
4125
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
3168
4126
|
var markIcons = {
|
|
3169
4127
|
bold: import_icons10.BoldIcon,
|
|
3170
4128
|
italic: import_icons10.ItalicIcon,
|
|
@@ -3185,7 +4143,7 @@ var markShortcutKeys = {
|
|
|
3185
4143
|
};
|
|
3186
4144
|
function canToggleMark(editor, type) {
|
|
3187
4145
|
if (!editor || !editor.isEditable) return false;
|
|
3188
|
-
if (!(0,
|
|
4146
|
+
if (!(0, import_editor_utils3.isMarkInSchema)(type, editor) || (0, import_editor_utils3.isNodeTypeSelected)(editor, ["image"]))
|
|
3189
4147
|
return false;
|
|
3190
4148
|
return editor.can().toggleMark(type);
|
|
3191
4149
|
}
|
|
@@ -3210,7 +4168,7 @@ function shouldShowMarkButton(params) {
|
|
|
3210
4168
|
return false;
|
|
3211
4169
|
}
|
|
3212
4170
|
if (hideWhenUnavailable) {
|
|
3213
|
-
if ((0,
|
|
4171
|
+
if ((0, import_react35.isNodeSelection)(editor.state.selection) || !canToggleMark(editor, type)) {
|
|
3214
4172
|
return false;
|
|
3215
4173
|
}
|
|
3216
4174
|
}
|
|
@@ -3220,7 +4178,7 @@ function getFormattedMarkName(type) {
|
|
|
3220
4178
|
return type.charAt(0).toUpperCase() + type.slice(1);
|
|
3221
4179
|
}
|
|
3222
4180
|
function useMarkState(editor, type, disabled = false) {
|
|
3223
|
-
const markInSchema = (0,
|
|
4181
|
+
const markInSchema = (0, import_editor_utils3.isMarkInSchema)(type, editor);
|
|
3224
4182
|
const isDisabled = isMarkButtonDisabled(editor, type, disabled);
|
|
3225
4183
|
const isActive = isMarkActive(editor, type);
|
|
3226
4184
|
const Icon = markIcons[type];
|
|
@@ -3255,7 +4213,7 @@ var MarkButton = ({
|
|
|
3255
4213
|
shortcutKey,
|
|
3256
4214
|
formattedName
|
|
3257
4215
|
} = useMarkState(editor, type, disabled);
|
|
3258
|
-
const handleClick = (0,
|
|
4216
|
+
const handleClick = (0, import_react36.useCallback)(
|
|
3259
4217
|
(e) => {
|
|
3260
4218
|
onClick == null ? void 0 : onClick(e);
|
|
3261
4219
|
if (!e.defaultPrevented && !isDisabled && editor) {
|
|
@@ -3264,7 +4222,7 @@ var MarkButton = ({
|
|
|
3264
4222
|
},
|
|
3265
4223
|
[onClick, isDisabled, editor, type]
|
|
3266
4224
|
);
|
|
3267
|
-
const show = (0,
|
|
4225
|
+
const show = (0, import_react36.useMemo)(() => {
|
|
3268
4226
|
return shouldShowMarkButton({
|
|
3269
4227
|
editor,
|
|
3270
4228
|
type,
|
|
@@ -3275,7 +4233,7 @@ var MarkButton = ({
|
|
|
3275
4233
|
if (!show || !editor || !editor.isEditable) {
|
|
3276
4234
|
return null;
|
|
3277
4235
|
}
|
|
3278
|
-
return /* @__PURE__ */ (0,
|
|
4236
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3279
4237
|
import_toolbar2.ToolbarButton,
|
|
3280
4238
|
{
|
|
3281
4239
|
type: "button",
|
|
@@ -3293,739 +4251,326 @@ var MarkButton = ({
|
|
|
3293
4251
|
onClick: handleClick,
|
|
3294
4252
|
isIconOnly: true,
|
|
3295
4253
|
...buttonProps,
|
|
3296
|
-
children: /* @__PURE__ */ (0,
|
|
4254
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Icon, {})
|
|
3297
4255
|
}
|
|
3298
4256
|
);
|
|
3299
4257
|
};
|
|
3300
4258
|
|
|
3301
4259
|
// src/ui/bubble-menu/index.tsx
|
|
3302
|
-
var
|
|
4260
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3303
4261
|
function BubbleMenu({ editor }) {
|
|
3304
4262
|
if (!editor) {
|
|
3305
4263
|
return null;
|
|
3306
4264
|
}
|
|
3307
|
-
return /* @__PURE__ */ (0,
|
|
4265
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3308
4266
|
import_menus.BubbleMenu,
|
|
3309
4267
|
{
|
|
3310
4268
|
editor,
|
|
3311
|
-
shouldShow: ({ editor: e, state }) => {
|
|
4269
|
+
shouldShow: ({ editor: e, state, view }) => {
|
|
3312
4270
|
const { selection } = state;
|
|
3313
4271
|
const { empty } = selection;
|
|
4272
|
+
if (!view.hasFocus()) return false;
|
|
3314
4273
|
if (empty) return false;
|
|
3315
4274
|
if (e.isActive("codeBlock")) return false;
|
|
3316
4275
|
if (e.isActive("link")) return false;
|
|
4276
|
+
if (e.isActive("variable")) return false;
|
|
3317
4277
|
if (!e.isEditable) return false;
|
|
3318
4278
|
return true;
|
|
3319
4279
|
},
|
|
3320
|
-
options: {
|
|
3321
|
-
placement: "top",
|
|
3322
|
-
offset: 8
|
|
3323
|
-
},
|
|
3324
|
-
className: "rounded-lg border bg-background shadow-md",
|
|
3325
|
-
children: /* @__PURE__ */ (0,
|
|
3326
|
-
/* @__PURE__ */ (0,
|
|
3327
|
-
/* @__PURE__ */ (0,
|
|
3328
|
-
/* @__PURE__ */ (0,
|
|
3329
|
-
/* @__PURE__ */ (0,
|
|
3330
|
-
/* @__PURE__ */ (0,
|
|
3331
|
-
] }),
|
|
3332
|
-
/* @__PURE__ */ (0,
|
|
3333
|
-
/* @__PURE__ */ (0,
|
|
3334
|
-
] })
|
|
3335
|
-
}
|
|
3336
|
-
);
|
|
3337
|
-
}
|
|
3338
|
-
|
|
3339
|
-
// src/ui/copy-anchor-link-button/use-scroll-to-hash.ts
|
|
3340
|
-
var import_editor_utils3 = require("@kopexa/editor-utils");
|
|
3341
|
-
var React3 = __toESM(require("react"));
|
|
3342
|
-
|
|
3343
|
-
// src/hooks/use-floating-toolbar-visibility.ts
|
|
3344
|
-
var import_state4 = require("@tiptap/pm/state");
|
|
3345
|
-
var import_react33 = require("@tiptap/react");
|
|
3346
|
-
var React2 = __toESM(require("react"));
|
|
3347
|
-
var HIDE_FLOATING_META = "hideFloatingToolbar";
|
|
3348
|
-
var selectNodeAndHideFloating = (editor, pos) => {
|
|
3349
|
-
if (!editor) return;
|
|
3350
|
-
const { state, view } = editor;
|
|
3351
|
-
view.dispatch(
|
|
3352
|
-
state.tr.setSelection(import_state4.NodeSelection.create(state.doc, pos)).setMeta(HIDE_FLOATING_META, true)
|
|
3353
|
-
);
|
|
3354
|
-
};
|
|
3355
|
-
|
|
3356
|
-
// src/ui/copy-anchor-link-button/use-scroll-to-hash.ts
|
|
3357
|
-
function useScrollToHash(config = {}) {
|
|
3358
|
-
const {
|
|
3359
|
-
editor: providedEditor,
|
|
3360
|
-
onTargetFound = () => {
|
|
3361
|
-
},
|
|
3362
|
-
onTargetNotFound = () => {
|
|
3363
|
-
}
|
|
3364
|
-
} = config;
|
|
3365
|
-
const { editor } = useTiptapEditor(providedEditor);
|
|
3366
|
-
const scrollToNode = React3.useCallback(
|
|
3367
|
-
(id) => {
|
|
3368
|
-
var _a, _b, _c;
|
|
3369
|
-
if (!editor) return false;
|
|
3370
|
-
const attributeName = (_c = (_b = (_a = (0, import_editor_utils3.getEditorExtension)(editor, "uniqueID")) == null ? void 0 : _a.options) == null ? void 0 : _b.attributeName) != null ? _c : "data-id";
|
|
3371
|
-
let position = null;
|
|
3372
|
-
editor.state.doc.descendants((node, pos) => {
|
|
3373
|
-
var _a2;
|
|
3374
|
-
if (((_a2 = node.attrs) == null ? void 0 : _a2[attributeName]) === id) {
|
|
3375
|
-
position = pos;
|
|
3376
|
-
return false;
|
|
3377
|
-
}
|
|
3378
|
-
return true;
|
|
3379
|
-
});
|
|
3380
|
-
if (position === null) return false;
|
|
3381
|
-
selectNodeAndHideFloating(editor, position);
|
|
3382
|
-
setTimeout(() => {
|
|
3383
|
-
let dom = null;
|
|
3384
|
-
if (typeof position === "number") {
|
|
3385
|
-
dom = editor.view.nodeDOM(position);
|
|
3386
|
-
}
|
|
3387
|
-
if (dom) {
|
|
3388
|
-
dom.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
3389
|
-
}
|
|
3390
|
-
}, 0);
|
|
3391
|
-
return true;
|
|
3392
|
-
},
|
|
3393
|
-
[editor]
|
|
3394
|
-
);
|
|
3395
|
-
const handleScroll = React3.useCallback(
|
|
3396
|
-
(delay = 0) => {
|
|
3397
|
-
var _a;
|
|
3398
|
-
const hash = (_a = window.location.hash) == null ? void 0 : _a.substring(1);
|
|
3399
|
-
if (!hash) return;
|
|
3400
|
-
setTimeout(() => {
|
|
3401
|
-
if (scrollToNode(hash)) {
|
|
3402
|
-
onTargetFound(hash);
|
|
3403
|
-
} else {
|
|
3404
|
-
onTargetNotFound(hash);
|
|
3405
|
-
}
|
|
3406
|
-
}, delay);
|
|
3407
|
-
},
|
|
3408
|
-
[scrollToNode, onTargetFound, onTargetNotFound]
|
|
3409
|
-
);
|
|
3410
|
-
React3.useEffect(() => {
|
|
3411
|
-
var _a, _b;
|
|
3412
|
-
if (!editor) return;
|
|
3413
|
-
const provider = (_b = (_a = editor.extensionManager.extensions.find(
|
|
3414
|
-
(ext) => ext.name === "collaborationCaret"
|
|
3415
|
-
)) == null ? void 0 : _a.options) == null ? void 0 : _b.provider;
|
|
3416
|
-
if (provider == null ? void 0 : provider.on) {
|
|
3417
|
-
const syncHandler = () => handleScroll(500);
|
|
3418
|
-
provider.on("synced", syncHandler);
|
|
3419
|
-
return () => {
|
|
3420
|
-
var _a2;
|
|
3421
|
-
(_a2 = provider.off) == null ? void 0 : _a2.call(provider, "synced", syncHandler);
|
|
3422
|
-
};
|
|
3423
|
-
} else {
|
|
3424
|
-
handleScroll(500);
|
|
3425
|
-
}
|
|
3426
|
-
}, [editor, handleScroll]);
|
|
3427
|
-
React3.useEffect(() => {
|
|
3428
|
-
const immediateScroll = () => handleScroll();
|
|
3429
|
-
const delayedScroll = () => handleScroll(500);
|
|
3430
|
-
window.addEventListener("hashchange", immediateScroll);
|
|
3431
|
-
window.addEventListener("pageshow", delayedScroll);
|
|
3432
|
-
window.addEventListener("popstate", immediateScroll);
|
|
3433
|
-
return () => {
|
|
3434
|
-
window.removeEventListener("hashchange", immediateScroll);
|
|
3435
|
-
window.removeEventListener("pageshow", delayedScroll);
|
|
3436
|
-
window.removeEventListener("popstate", immediateScroll);
|
|
3437
|
-
};
|
|
3438
|
-
}, [handleScroll]);
|
|
3439
|
-
return { scrollToHash: scrollToNode };
|
|
3440
|
-
}
|
|
3441
|
-
|
|
3442
|
-
// src/ui/link-bubble/index.tsx
|
|
3443
|
-
var import_button8 = require("@kopexa/button");
|
|
3444
|
-
var import_icons11 = require("@kopexa/icons");
|
|
3445
|
-
var import_input3 = require("@kopexa/input");
|
|
3446
|
-
var import_menus2 = require("@tiptap/react/menus");
|
|
3447
|
-
var import_react34 = require("react");
|
|
3448
|
-
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
3449
|
-
function LinkBubble({ editor }) {
|
|
3450
|
-
const [isEditing, setIsEditing] = (0, import_react34.useState)(false);
|
|
3451
|
-
const [url, setUrl] = (0, import_react34.useState)("");
|
|
3452
|
-
const getCurrentUrl = (0, import_react34.useCallback)(() => {
|
|
3453
|
-
if (!editor) return "";
|
|
3454
|
-
const attrs = editor.getAttributes("link");
|
|
3455
|
-
return attrs.href || "";
|
|
3456
|
-
}, [editor]);
|
|
3457
|
-
(0, import_react34.useEffect)(() => {
|
|
3458
|
-
const isLinkActive2 = editor == null ? void 0 : editor.isActive("link");
|
|
3459
|
-
if (isLinkActive2) {
|
|
3460
|
-
setUrl(getCurrentUrl());
|
|
3461
|
-
setIsEditing(false);
|
|
3462
|
-
}
|
|
3463
|
-
}, [editor, getCurrentUrl]);
|
|
3464
|
-
const handleOpenLink = (0, import_react34.useCallback)(() => {
|
|
3465
|
-
const href = getCurrentUrl();
|
|
3466
|
-
if (href) {
|
|
3467
|
-
window.open(href, "_blank", "noopener,noreferrer");
|
|
3468
|
-
}
|
|
3469
|
-
}, [getCurrentUrl]);
|
|
3470
|
-
const handleRemoveLink = (0, import_react34.useCallback)(() => {
|
|
3471
|
-
editor == null ? void 0 : editor.chain().focus().unsetLink().run();
|
|
3472
|
-
}, [editor]);
|
|
3473
|
-
const handleEdit = (0, import_react34.useCallback)(() => {
|
|
3474
|
-
setUrl(getCurrentUrl());
|
|
3475
|
-
setIsEditing(true);
|
|
3476
|
-
}, [getCurrentUrl]);
|
|
3477
|
-
const handleSave = (0, import_react34.useCallback)(() => {
|
|
3478
|
-
if (url) {
|
|
3479
|
-
editor == null ? void 0 : editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
|
|
3480
|
-
} else {
|
|
3481
|
-
editor == null ? void 0 : editor.chain().focus().unsetLink().run();
|
|
3482
|
-
}
|
|
3483
|
-
setIsEditing(false);
|
|
3484
|
-
}, [editor, url]);
|
|
3485
|
-
const handleKeyDown = (0, import_react34.useCallback)(
|
|
3486
|
-
(e) => {
|
|
3487
|
-
if (e.key === "Enter") {
|
|
3488
|
-
e.preventDefault();
|
|
3489
|
-
handleSave();
|
|
3490
|
-
} else if (e.key === "Escape") {
|
|
3491
|
-
e.preventDefault();
|
|
3492
|
-
setIsEditing(false);
|
|
3493
|
-
setUrl(getCurrentUrl());
|
|
3494
|
-
}
|
|
3495
|
-
},
|
|
3496
|
-
[handleSave, getCurrentUrl]
|
|
3497
|
-
);
|
|
3498
|
-
if (!editor) {
|
|
3499
|
-
return null;
|
|
3500
|
-
}
|
|
3501
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3502
|
-
import_menus2.BubbleMenu,
|
|
3503
|
-
{
|
|
3504
|
-
editor,
|
|
3505
|
-
pluginKey: "linkBubbleMenu",
|
|
3506
|
-
shouldShow: ({ editor: e }) => {
|
|
3507
|
-
return e.isActive("link") && e.isEditable;
|
|
3508
|
-
},
|
|
3509
|
-
options: {
|
|
3510
|
-
placement: "bottom-start",
|
|
3511
|
-
offset: 8
|
|
3512
|
-
},
|
|
3513
|
-
className: "rounded-lg border bg-background shadow-md",
|
|
3514
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex items-center gap-1 p-1.5 min-w-[280px]", children: isEditing ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
3515
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3516
|
-
import_input3.Input,
|
|
3517
|
-
{
|
|
3518
|
-
type: "url",
|
|
3519
|
-
value: url,
|
|
3520
|
-
onChange: (e) => setUrl(e.target.value),
|
|
3521
|
-
onKeyDown: handleKeyDown,
|
|
3522
|
-
placeholder: "Enter URL...",
|
|
3523
|
-
className: "flex-1 h-8 text-sm",
|
|
3524
|
-
autoFocus: true
|
|
3525
|
-
}
|
|
3526
|
-
),
|
|
3527
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3528
|
-
import_button8.IconButton,
|
|
3529
|
-
{
|
|
3530
|
-
type: "button",
|
|
3531
|
-
size: "sm",
|
|
3532
|
-
variant: "ghost",
|
|
3533
|
-
onClick: handleSave,
|
|
3534
|
-
"aria-label": "Save link",
|
|
3535
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_icons11.EditIcon, { className: "size-4" })
|
|
3536
|
-
}
|
|
3537
|
-
)
|
|
3538
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
3539
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3540
|
-
"a",
|
|
3541
|
-
{
|
|
3542
|
-
href: getCurrentUrl(),
|
|
3543
|
-
target: "_blank",
|
|
3544
|
-
rel: "noopener noreferrer",
|
|
3545
|
-
className: "flex-1 text-sm text-primary truncate max-w-[200px] hover:underline px-2",
|
|
3546
|
-
onClick: (e) => {
|
|
3547
|
-
e.preventDefault();
|
|
3548
|
-
handleOpenLink();
|
|
3549
|
-
},
|
|
3550
|
-
children: getCurrentUrl()
|
|
3551
|
-
}
|
|
3552
|
-
),
|
|
3553
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-0.5 border-l pl-1 ml-1", children: [
|
|
3554
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3555
|
-
import_button8.IconButton,
|
|
3556
|
-
{
|
|
3557
|
-
type: "button",
|
|
3558
|
-
size: "sm",
|
|
3559
|
-
variant: "ghost",
|
|
3560
|
-
onClick: handleOpenLink,
|
|
3561
|
-
"aria-label": "Open link in new tab",
|
|
3562
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_icons11.ExternalLinkIcon, { className: "size-4" })
|
|
3563
|
-
}
|
|
3564
|
-
),
|
|
3565
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3566
|
-
import_button8.IconButton,
|
|
3567
|
-
{
|
|
3568
|
-
type: "button",
|
|
3569
|
-
size: "sm",
|
|
3570
|
-
variant: "ghost",
|
|
3571
|
-
onClick: handleEdit,
|
|
3572
|
-
"aria-label": "Edit link",
|
|
3573
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_icons11.EditIcon, { className: "size-4" })
|
|
3574
|
-
}
|
|
3575
|
-
),
|
|
3576
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3577
|
-
import_button8.IconButton,
|
|
3578
|
-
{
|
|
3579
|
-
type: "button",
|
|
3580
|
-
size: "sm",
|
|
3581
|
-
variant: "ghost",
|
|
3582
|
-
onClick: handleRemoveLink,
|
|
3583
|
-
"aria-label": "Remove link",
|
|
3584
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_icons11.TrashIcon, { className: "size-4" })
|
|
3585
|
-
}
|
|
3586
|
-
)
|
|
3587
|
-
] })
|
|
3588
|
-
] }) })
|
|
4280
|
+
options: {
|
|
4281
|
+
placement: "top",
|
|
4282
|
+
offset: 8
|
|
4283
|
+
},
|
|
4284
|
+
className: "rounded-lg border bg-background shadow-md",
|
|
4285
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_toolbar3.Toolbar, { radius: "md", border: "none", className: "p-1", children: [
|
|
4286
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_toolbar3.ToolbarGroup, { children: [
|
|
4287
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(MarkButton, { type: "bold" }),
|
|
4288
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(MarkButton, { type: "italic" }),
|
|
4289
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(MarkButton, { type: "strike" }),
|
|
4290
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(MarkButton, { type: "code" })
|
|
4291
|
+
] }),
|
|
4292
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_toolbar3.ToolbarSeparator, {}),
|
|
4293
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_toolbar3.ToolbarGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(LinkPopover, { autoOpenOnLinkActive: false }) })
|
|
4294
|
+
] })
|
|
3589
4295
|
}
|
|
3590
4296
|
);
|
|
3591
4297
|
}
|
|
3592
4298
|
|
|
3593
|
-
// src/ui/
|
|
3594
|
-
var
|
|
3595
|
-
var
|
|
3596
|
-
var import_separator = require("@kopexa/separator");
|
|
3597
|
-
var import_theme5 = require("@kopexa/theme");
|
|
3598
|
-
var React8 = __toESM(require("react"));
|
|
3599
|
-
|
|
3600
|
-
// src/ui/suggestion-menu/suggestion-menu.tsx
|
|
3601
|
-
var import_react36 = require("@floating-ui/react");
|
|
3602
|
-
var import_state5 = require("@tiptap/pm/state");
|
|
3603
|
-
var import_suggestion = require("@tiptap/suggestion");
|
|
3604
|
-
var React6 = __toESM(require("react"));
|
|
4299
|
+
// src/ui/copy-anchor-link-button/use-scroll-to-hash.ts
|
|
4300
|
+
var import_editor_utils4 = require("@kopexa/editor-utils");
|
|
4301
|
+
var React9 = __toESM(require("react"));
|
|
3605
4302
|
|
|
3606
|
-
// src/hooks/use-floating-
|
|
3607
|
-
var
|
|
3608
|
-
var
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
const dismiss = (0, import_react35.useDismiss)(context, dismissOptions);
|
|
3617
|
-
const { getReferenceProps, getFloatingProps } = (0, import_react35.useInteractions)([dismiss]);
|
|
3618
|
-
React4.useEffect(() => {
|
|
3619
|
-
update();
|
|
3620
|
-
}, [referencePos, update]);
|
|
3621
|
-
React4.useEffect(() => {
|
|
3622
|
-
if (referencePos === null) {
|
|
3623
|
-
return;
|
|
3624
|
-
}
|
|
3625
|
-
refs.setReference({
|
|
3626
|
-
getBoundingClientRect: () => referencePos
|
|
3627
|
-
});
|
|
3628
|
-
}, [referencePos, refs]);
|
|
3629
|
-
return React4.useMemo(
|
|
3630
|
-
() => ({
|
|
3631
|
-
isMounted,
|
|
3632
|
-
ref: refs.setFloating,
|
|
3633
|
-
style: {
|
|
3634
|
-
...styles,
|
|
3635
|
-
...floatingStyles,
|
|
3636
|
-
zIndex
|
|
3637
|
-
},
|
|
3638
|
-
update,
|
|
3639
|
-
getFloatingProps,
|
|
3640
|
-
getReferenceProps
|
|
3641
|
-
}),
|
|
3642
|
-
[
|
|
3643
|
-
floatingStyles,
|
|
3644
|
-
isMounted,
|
|
3645
|
-
refs.setFloating,
|
|
3646
|
-
styles,
|
|
3647
|
-
update,
|
|
3648
|
-
zIndex,
|
|
3649
|
-
getFloatingProps,
|
|
3650
|
-
getReferenceProps
|
|
3651
|
-
]
|
|
4303
|
+
// src/hooks/use-floating-toolbar-visibility.ts
|
|
4304
|
+
var import_state6 = require("@tiptap/pm/state");
|
|
4305
|
+
var import_react37 = require("@tiptap/react");
|
|
4306
|
+
var React8 = __toESM(require("react"));
|
|
4307
|
+
var HIDE_FLOATING_META = "hideFloatingToolbar";
|
|
4308
|
+
var selectNodeAndHideFloating = (editor, pos) => {
|
|
4309
|
+
if (!editor) return;
|
|
4310
|
+
const { state, view } = editor;
|
|
4311
|
+
view.dispatch(
|
|
4312
|
+
state.tr.setSelection(import_state6.NodeSelection.create(state.doc, pos)).setMeta(HIDE_FLOATING_META, true)
|
|
3652
4313
|
);
|
|
3653
|
-
}
|
|
4314
|
+
};
|
|
3654
4315
|
|
|
3655
|
-
// src/
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
});
|
|
3677
|
-
const movePrev = () => setSelectedIndex((currentIndex) => {
|
|
3678
|
-
if (currentIndex === -1) return items.length - 1;
|
|
3679
|
-
return (currentIndex - 1 + items.length) % items.length;
|
|
3680
|
-
});
|
|
3681
|
-
switch (event.key) {
|
|
3682
|
-
case "ArrowUp": {
|
|
3683
|
-
if (orientation === "horizontal") return false;
|
|
3684
|
-
event.preventDefault();
|
|
3685
|
-
movePrev();
|
|
3686
|
-
return true;
|
|
3687
|
-
}
|
|
3688
|
-
case "ArrowDown": {
|
|
3689
|
-
if (orientation === "horizontal") return false;
|
|
3690
|
-
event.preventDefault();
|
|
3691
|
-
moveNext();
|
|
3692
|
-
return true;
|
|
3693
|
-
}
|
|
3694
|
-
case "ArrowLeft": {
|
|
3695
|
-
if (orientation === "vertical") return false;
|
|
3696
|
-
event.preventDefault();
|
|
3697
|
-
movePrev();
|
|
3698
|
-
return true;
|
|
3699
|
-
}
|
|
3700
|
-
case "ArrowRight": {
|
|
3701
|
-
if (orientation === "vertical") return false;
|
|
3702
|
-
event.preventDefault();
|
|
3703
|
-
moveNext();
|
|
3704
|
-
return true;
|
|
3705
|
-
}
|
|
3706
|
-
case "Tab": {
|
|
3707
|
-
event.preventDefault();
|
|
3708
|
-
if (event.shiftKey) {
|
|
3709
|
-
movePrev();
|
|
3710
|
-
} else {
|
|
3711
|
-
moveNext();
|
|
3712
|
-
}
|
|
3713
|
-
return true;
|
|
3714
|
-
}
|
|
3715
|
-
case "Home": {
|
|
3716
|
-
event.preventDefault();
|
|
3717
|
-
setSelectedIndex(0);
|
|
3718
|
-
return true;
|
|
4316
|
+
// src/ui/copy-anchor-link-button/use-scroll-to-hash.ts
|
|
4317
|
+
function useScrollToHash(config = {}) {
|
|
4318
|
+
const {
|
|
4319
|
+
editor: providedEditor,
|
|
4320
|
+
onTargetFound = () => {
|
|
4321
|
+
},
|
|
4322
|
+
onTargetNotFound = () => {
|
|
4323
|
+
}
|
|
4324
|
+
} = config;
|
|
4325
|
+
const { editor } = useTiptapEditor(providedEditor);
|
|
4326
|
+
const scrollToNode = React9.useCallback(
|
|
4327
|
+
(id) => {
|
|
4328
|
+
var _a, _b, _c;
|
|
4329
|
+
if (!editor) return false;
|
|
4330
|
+
const attributeName = (_c = (_b = (_a = (0, import_editor_utils4.getEditorExtension)(editor, "uniqueID")) == null ? void 0 : _a.options) == null ? void 0 : _b.attributeName) != null ? _c : "data-id";
|
|
4331
|
+
let position = null;
|
|
4332
|
+
editor.state.doc.descendants((node, pos) => {
|
|
4333
|
+
var _a2;
|
|
4334
|
+
if (((_a2 = node.attrs) == null ? void 0 : _a2[attributeName]) === id) {
|
|
4335
|
+
position = pos;
|
|
4336
|
+
return false;
|
|
3719
4337
|
}
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
4338
|
+
return true;
|
|
4339
|
+
});
|
|
4340
|
+
if (position === null) return false;
|
|
4341
|
+
selectNodeAndHideFloating(editor, position);
|
|
4342
|
+
setTimeout(() => {
|
|
4343
|
+
let dom = null;
|
|
4344
|
+
if (typeof position === "number") {
|
|
4345
|
+
dom = editor.view.nodeDOM(position);
|
|
3724
4346
|
}
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
event.preventDefault();
|
|
3728
|
-
if (selectedIndex !== -1 && items[selectedIndex]) {
|
|
3729
|
-
onSelect == null ? void 0 : onSelect(items[selectedIndex]);
|
|
3730
|
-
}
|
|
3731
|
-
return true;
|
|
4347
|
+
if (dom) {
|
|
4348
|
+
dom.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
3732
4349
|
}
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
4350
|
+
}, 0);
|
|
4351
|
+
return true;
|
|
4352
|
+
},
|
|
4353
|
+
[editor]
|
|
4354
|
+
);
|
|
4355
|
+
const handleScroll = React9.useCallback(
|
|
4356
|
+
(delay = 0) => {
|
|
4357
|
+
var _a;
|
|
4358
|
+
const hash = (_a = window.location.hash) == null ? void 0 : _a.substring(1);
|
|
4359
|
+
if (!hash) return;
|
|
4360
|
+
setTimeout(() => {
|
|
4361
|
+
if (scrollToNode(hash)) {
|
|
4362
|
+
onTargetFound(hash);
|
|
4363
|
+
} else {
|
|
4364
|
+
onTargetNotFound(hash);
|
|
3737
4365
|
}
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
if (editor) {
|
|
3744
|
-
targetElement = editor.view.dom;
|
|
3745
|
-
} else if (containerRef == null ? void 0 : containerRef.current) {
|
|
3746
|
-
targetElement = containerRef.current;
|
|
3747
|
-
}
|
|
3748
|
-
if (targetElement) {
|
|
3749
|
-
targetElement.addEventListener("keydown", handleKeyboardNavigation, true);
|
|
3750
|
-
return () => {
|
|
3751
|
-
targetElement == null ? void 0 : targetElement.removeEventListener(
|
|
3752
|
-
"keydown",
|
|
3753
|
-
handleKeyboardNavigation,
|
|
3754
|
-
true
|
|
3755
|
-
);
|
|
3756
|
-
};
|
|
3757
|
-
}
|
|
3758
|
-
return void 0;
|
|
3759
|
-
}, [
|
|
3760
|
-
editor,
|
|
3761
|
-
containerRef,
|
|
3762
|
-
items,
|
|
3763
|
-
selectedIndex,
|
|
3764
|
-
onSelect,
|
|
3765
|
-
onClose,
|
|
3766
|
-
orientation
|
|
3767
|
-
]);
|
|
3768
|
-
React5.useEffect(() => {
|
|
3769
|
-
if (query) {
|
|
3770
|
-
setSelectedIndex(autoSelectFirstItem ? 0 : -1);
|
|
3771
|
-
}
|
|
3772
|
-
}, [query, autoSelectFirstItem]);
|
|
3773
|
-
return {
|
|
3774
|
-
selectedIndex: items.length ? selectedIndex : void 0,
|
|
3775
|
-
setSelectedIndex
|
|
3776
|
-
};
|
|
3777
|
-
}
|
|
3778
|
-
|
|
3779
|
-
// src/ui/suggestion-menu/suggestion-menu-utils.ts
|
|
3780
|
-
function calculateStartPosition(cursorPosition, previousNode, triggerChar) {
|
|
3781
|
-
if (!(previousNode == null ? void 0 : previousNode.text) || !triggerChar) {
|
|
3782
|
-
return cursorPosition;
|
|
3783
|
-
}
|
|
3784
|
-
const commandText = previousNode.text;
|
|
3785
|
-
const triggerCharIndex = commandText.lastIndexOf(triggerChar);
|
|
3786
|
-
if (triggerCharIndex === -1) {
|
|
3787
|
-
return cursorPosition;
|
|
3788
|
-
}
|
|
3789
|
-
const textLength = commandText.substring(triggerCharIndex).length;
|
|
3790
|
-
return cursorPosition - textLength;
|
|
3791
|
-
}
|
|
3792
|
-
function filterSuggestionItems(items, query) {
|
|
3793
|
-
const normalizedQuery = query.trim().toLowerCase();
|
|
3794
|
-
if (!normalizedQuery) {
|
|
3795
|
-
return items;
|
|
3796
|
-
}
|
|
3797
|
-
return items.filter((item) => {
|
|
4366
|
+
}, delay);
|
|
4367
|
+
},
|
|
4368
|
+
[scrollToNode, onTargetFound, onTargetNotFound]
|
|
4369
|
+
);
|
|
4370
|
+
React9.useEffect(() => {
|
|
3798
4371
|
var _a, _b;
|
|
3799
|
-
if (
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
(
|
|
3807
|
-
|
|
3808
|
-
|
|
4372
|
+
if (!editor) return;
|
|
4373
|
+
const provider = (_b = (_a = editor.extensionManager.extensions.find(
|
|
4374
|
+
(ext) => ext.name === "collaborationCaret"
|
|
4375
|
+
)) == null ? void 0 : _a.options) == null ? void 0 : _b.provider;
|
|
4376
|
+
if (provider == null ? void 0 : provider.on) {
|
|
4377
|
+
const syncHandler = () => handleScroll(500);
|
|
4378
|
+
provider.on("synced", syncHandler);
|
|
4379
|
+
return () => {
|
|
4380
|
+
var _a2;
|
|
4381
|
+
(_a2 = provider.off) == null ? void 0 : _a2.call(provider, "synced", syncHandler);
|
|
4382
|
+
};
|
|
4383
|
+
} else {
|
|
4384
|
+
handleScroll(500);
|
|
3809
4385
|
}
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
const
|
|
3813
|
-
const
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
4386
|
+
}, [editor, handleScroll]);
|
|
4387
|
+
React9.useEffect(() => {
|
|
4388
|
+
const immediateScroll = () => handleScroll();
|
|
4389
|
+
const delayedScroll = () => handleScroll(500);
|
|
4390
|
+
window.addEventListener("hashchange", immediateScroll);
|
|
4391
|
+
window.addEventListener("pageshow", delayedScroll);
|
|
4392
|
+
window.addEventListener("popstate", immediateScroll);
|
|
4393
|
+
return () => {
|
|
4394
|
+
window.removeEventListener("hashchange", immediateScroll);
|
|
4395
|
+
window.removeEventListener("pageshow", delayedScroll);
|
|
4396
|
+
window.removeEventListener("popstate", immediateScroll);
|
|
4397
|
+
};
|
|
4398
|
+
}, [handleScroll]);
|
|
4399
|
+
return { scrollToHash: scrollToNode };
|
|
3822
4400
|
}
|
|
3823
4401
|
|
|
3824
|
-
// src/ui/
|
|
3825
|
-
var
|
|
3826
|
-
var
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
const { ref, style, getFloatingProps, isMounted } = useFloatingElement(
|
|
3845
|
-
show,
|
|
3846
|
-
internalClientRect,
|
|
3847
|
-
1e3,
|
|
3848
|
-
{
|
|
3849
|
-
placement: "bottom-start",
|
|
3850
|
-
middleware: [
|
|
3851
|
-
(0, import_react36.offset)(10),
|
|
3852
|
-
(0, import_react36.flip)({
|
|
3853
|
-
mainAxis: true,
|
|
3854
|
-
crossAxis: false
|
|
3855
|
-
}),
|
|
3856
|
-
(0, import_react36.shift)(),
|
|
3857
|
-
(0, import_react36.size)({
|
|
3858
|
-
apply({ availableHeight, elements }) {
|
|
3859
|
-
if (elements.floating) {
|
|
3860
|
-
const maxHeightValue = maxHeight ? Math.min(maxHeight, availableHeight) : availableHeight;
|
|
3861
|
-
elements.floating.style.setProperty(
|
|
3862
|
-
"--suggestion-menu-max-height",
|
|
3863
|
-
`${maxHeightValue}px`
|
|
3864
|
-
);
|
|
3865
|
-
}
|
|
3866
|
-
}
|
|
3867
|
-
})
|
|
3868
|
-
],
|
|
3869
|
-
onOpenChange(open) {
|
|
3870
|
-
if (!open) {
|
|
3871
|
-
setShow(false);
|
|
3872
|
-
}
|
|
3873
|
-
},
|
|
3874
|
-
...floatingOptions
|
|
4402
|
+
// src/ui/link-bubble/index.tsx
|
|
4403
|
+
var import_button9 = require("@kopexa/button");
|
|
4404
|
+
var import_icons11 = require("@kopexa/icons");
|
|
4405
|
+
var import_input4 = require("@kopexa/input");
|
|
4406
|
+
var import_menus2 = require("@tiptap/react/menus");
|
|
4407
|
+
var import_react38 = require("react");
|
|
4408
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
4409
|
+
function LinkBubble({ editor }) {
|
|
4410
|
+
const [isEditing, setIsEditing] = (0, import_react38.useState)(false);
|
|
4411
|
+
const [url, setUrl] = (0, import_react38.useState)("");
|
|
4412
|
+
const getCurrentUrl = (0, import_react38.useCallback)(() => {
|
|
4413
|
+
if (!editor) return "";
|
|
4414
|
+
const attrs = editor.getAttributes("link");
|
|
4415
|
+
return attrs.href || "";
|
|
4416
|
+
}, [editor]);
|
|
4417
|
+
(0, import_react38.useEffect)(() => {
|
|
4418
|
+
const isLinkActive2 = editor == null ? void 0 : editor.isActive("link");
|
|
4419
|
+
if (isLinkActive2) {
|
|
4420
|
+
setUrl(getCurrentUrl());
|
|
4421
|
+
setIsEditing(false);
|
|
3875
4422
|
}
|
|
3876
|
-
);
|
|
3877
|
-
const
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
const closePopup = React6.useCallback(() => {
|
|
3882
|
-
setShow(false);
|
|
3883
|
-
}, []);
|
|
3884
|
-
React6.useEffect(() => {
|
|
3885
|
-
if (!editor || editor.isDestroyed) {
|
|
3886
|
-
return;
|
|
4423
|
+
}, [editor, getCurrentUrl]);
|
|
4424
|
+
const handleOpenLink = (0, import_react38.useCallback)(() => {
|
|
4425
|
+
const href = getCurrentUrl();
|
|
4426
|
+
if (href) {
|
|
4427
|
+
window.open(href, "_blank", "noopener,noreferrer");
|
|
3887
4428
|
}
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
);
|
|
3891
|
-
|
|
3892
|
-
|
|
4429
|
+
}, [getCurrentUrl]);
|
|
4430
|
+
const handleRemoveLink = (0, import_react38.useCallback)(() => {
|
|
4431
|
+
editor == null ? void 0 : editor.chain().focus().unsetLink().run();
|
|
4432
|
+
}, [editor]);
|
|
4433
|
+
const handleEdit = (0, import_react38.useCallback)(() => {
|
|
4434
|
+
setUrl(getCurrentUrl());
|
|
4435
|
+
setIsEditing(true);
|
|
4436
|
+
}, [getCurrentUrl]);
|
|
4437
|
+
const handleSave = (0, import_react38.useCallback)(() => {
|
|
4438
|
+
if (url) {
|
|
4439
|
+
editor == null ? void 0 : editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run();
|
|
4440
|
+
} else {
|
|
4441
|
+
editor == null ? void 0 : editor.chain().focus().unsetLink().run();
|
|
3893
4442
|
}
|
|
3894
|
-
|
|
3895
|
-
|
|
4443
|
+
setIsEditing(false);
|
|
4444
|
+
}, [editor, url]);
|
|
4445
|
+
const handleKeyDown = (0, import_react38.useCallback)(
|
|
4446
|
+
(e) => {
|
|
4447
|
+
if (e.key === "Enter") {
|
|
4448
|
+
e.preventDefault();
|
|
4449
|
+
handleSave();
|
|
4450
|
+
} else if (e.key === "Escape") {
|
|
4451
|
+
e.preventDefault();
|
|
4452
|
+
setIsEditing(false);
|
|
4453
|
+
setUrl(getCurrentUrl());
|
|
4454
|
+
}
|
|
4455
|
+
},
|
|
4456
|
+
[handleSave, getCurrentUrl]
|
|
4457
|
+
);
|
|
4458
|
+
if (!editor) {
|
|
4459
|
+
return null;
|
|
4460
|
+
}
|
|
4461
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4462
|
+
import_menus2.BubbleMenu,
|
|
4463
|
+
{
|
|
3896
4464
|
editor,
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
if (!
|
|
3900
|
-
|
|
3901
|
-
}
|
|
3902
|
-
const { view, state } = editor2;
|
|
3903
|
-
const { selection } = state;
|
|
3904
|
-
const isMention = editor2.extensionManager.extensions.some(
|
|
3905
|
-
(extension) => {
|
|
3906
|
-
var _a2, _b2;
|
|
3907
|
-
const name = extension.name;
|
|
3908
|
-
return name === "mention" && ((_b2 = (_a2 = extension.options) == null ? void 0 : _a2.suggestion) == null ? void 0 : _b2.char) === internalSuggestionPropsRef.current.char;
|
|
3909
|
-
}
|
|
3910
|
-
);
|
|
3911
|
-
if (!isMention) {
|
|
3912
|
-
const cursorPosition = selection.$from.pos;
|
|
3913
|
-
const previousNode = (_a = selection.$head) == null ? void 0 : _a.nodeBefore;
|
|
3914
|
-
const startPosition = previousNode ? calculateStartPosition(
|
|
3915
|
-
cursorPosition,
|
|
3916
|
-
previousNode,
|
|
3917
|
-
internalSuggestionPropsRef.current.char
|
|
3918
|
-
) : selection.$from.start();
|
|
3919
|
-
const transaction = state.tr.deleteRange(
|
|
3920
|
-
startPosition,
|
|
3921
|
-
cursorPosition
|
|
3922
|
-
);
|
|
3923
|
-
view.dispatch(transaction);
|
|
3924
|
-
}
|
|
3925
|
-
const nodeAfter = view.state.selection.$to.nodeAfter;
|
|
3926
|
-
const overrideSpace = (_b = nodeAfter == null ? void 0 : nodeAfter.text) == null ? void 0 : _b.startsWith(" ");
|
|
3927
|
-
const rangeToUse = { ...range };
|
|
3928
|
-
if (overrideSpace) {
|
|
3929
|
-
rangeToUse.to += 1;
|
|
3930
|
-
}
|
|
3931
|
-
props.onSelect({ editor: editor2, range: rangeToUse, context: props.context });
|
|
4465
|
+
pluginKey: "linkBubbleMenu",
|
|
4466
|
+
shouldShow: ({ editor: e, view }) => {
|
|
4467
|
+
if (!view.hasFocus()) return false;
|
|
4468
|
+
return e.isActive("link") && e.isEditable;
|
|
3932
4469
|
},
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
4470
|
+
options: {
|
|
4471
|
+
placement: "bottom-start",
|
|
4472
|
+
offset: 8
|
|
4473
|
+
},
|
|
4474
|
+
className: "rounded-lg border bg-background shadow-md",
|
|
4475
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex items-center gap-1 p-1.5 min-w-[280px]", children: isEditing ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
4476
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4477
|
+
import_input4.Input,
|
|
4478
|
+
{
|
|
4479
|
+
type: "url",
|
|
4480
|
+
value: url,
|
|
4481
|
+
onChange: (e) => setUrl(e.target.value),
|
|
4482
|
+
onKeyDown: handleKeyDown,
|
|
4483
|
+
placeholder: "Enter URL...",
|
|
4484
|
+
className: "flex-1 h-8 text-sm",
|
|
4485
|
+
autoFocus: true
|
|
4486
|
+
}
|
|
4487
|
+
),
|
|
4488
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4489
|
+
import_button9.IconButton,
|
|
4490
|
+
{
|
|
4491
|
+
type: "button",
|
|
4492
|
+
size: "sm",
|
|
4493
|
+
variant: "ghost",
|
|
4494
|
+
onClick: handleSave,
|
|
4495
|
+
"aria-label": "Save link",
|
|
4496
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_icons11.EditIcon, { className: "size-4" })
|
|
4497
|
+
}
|
|
4498
|
+
)
|
|
4499
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
4500
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4501
|
+
"a",
|
|
4502
|
+
{
|
|
4503
|
+
href: getCurrentUrl(),
|
|
4504
|
+
target: "_blank",
|
|
4505
|
+
rel: "noopener noreferrer",
|
|
4506
|
+
className: "flex-1 text-sm text-primary truncate max-w-[200px] hover:underline px-2",
|
|
4507
|
+
onClick: (e) => {
|
|
4508
|
+
e.preventDefault();
|
|
4509
|
+
handleOpenLink();
|
|
4510
|
+
},
|
|
4511
|
+
children: getCurrentUrl()
|
|
3966
4512
|
}
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
role: "listbox",
|
|
4005
|
-
"aria-label": "Suggestions",
|
|
4006
|
-
onPointerDown: (e) => e.preventDefault(),
|
|
4007
|
-
children: children({
|
|
4008
|
-
items: internalItems,
|
|
4009
|
-
selectedIndex,
|
|
4010
|
-
onSelect
|
|
4011
|
-
})
|
|
4513
|
+
),
|
|
4514
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-0.5 border-l pl-1 ml-1", children: [
|
|
4515
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4516
|
+
import_button9.IconButton,
|
|
4517
|
+
{
|
|
4518
|
+
type: "button",
|
|
4519
|
+
size: "sm",
|
|
4520
|
+
variant: "ghost",
|
|
4521
|
+
onClick: handleOpenLink,
|
|
4522
|
+
"aria-label": "Open link in new tab",
|
|
4523
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_icons11.ExternalLinkIcon, { className: "size-4" })
|
|
4524
|
+
}
|
|
4525
|
+
),
|
|
4526
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4527
|
+
import_button9.IconButton,
|
|
4528
|
+
{
|
|
4529
|
+
type: "button",
|
|
4530
|
+
size: "sm",
|
|
4531
|
+
variant: "ghost",
|
|
4532
|
+
onClick: handleEdit,
|
|
4533
|
+
"aria-label": "Edit link",
|
|
4534
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_icons11.EditIcon, { className: "size-4" })
|
|
4535
|
+
}
|
|
4536
|
+
),
|
|
4537
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4538
|
+
import_button9.IconButton,
|
|
4539
|
+
{
|
|
4540
|
+
type: "button",
|
|
4541
|
+
size: "sm",
|
|
4542
|
+
variant: "ghost",
|
|
4543
|
+
onClick: handleRemoveLink,
|
|
4544
|
+
"aria-label": "Remove link",
|
|
4545
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_icons11.TrashIcon, { className: "size-4" })
|
|
4546
|
+
}
|
|
4547
|
+
)
|
|
4548
|
+
] })
|
|
4549
|
+
] }) })
|
|
4012
4550
|
}
|
|
4013
|
-
)
|
|
4014
|
-
}
|
|
4551
|
+
);
|
|
4552
|
+
}
|
|
4553
|
+
|
|
4554
|
+
// src/ui/slash-dropdown-menu/slash-dropdown-menu.tsx
|
|
4555
|
+
var import_button10 = require("@kopexa/button");
|
|
4556
|
+
var import_editor_utils7 = require("@kopexa/editor-utils");
|
|
4557
|
+
var import_separator = require("@kopexa/separator");
|
|
4558
|
+
var import_theme7 = require("@kopexa/theme");
|
|
4559
|
+
var React11 = __toESM(require("react"));
|
|
4015
4560
|
|
|
4016
4561
|
// src/ui/slash-dropdown-menu/use-slash-dropdown-menu.ts
|
|
4017
|
-
var
|
|
4562
|
+
var import_editor_utils6 = require("@kopexa/editor-utils");
|
|
4018
4563
|
var import_icons13 = require("@kopexa/icons");
|
|
4019
|
-
var
|
|
4564
|
+
var React10 = __toESM(require("react"));
|
|
4020
4565
|
|
|
4021
4566
|
// src/ui/table-button/use-table.ts
|
|
4022
|
-
var
|
|
4567
|
+
var import_editor_utils5 = require("@kopexa/editor-utils");
|
|
4023
4568
|
var import_icons12 = require("@kopexa/icons");
|
|
4024
|
-
var
|
|
4025
|
-
var
|
|
4569
|
+
var import_react39 = require("@tiptap/react");
|
|
4570
|
+
var import_react40 = require("react");
|
|
4026
4571
|
function canToggle(editor) {
|
|
4027
4572
|
if (!editor || !editor.isEditable) return false;
|
|
4028
|
-
if (!(0,
|
|
4573
|
+
if (!(0, import_editor_utils5.isNodeInSchema)("table", editor) || (0, import_editor_utils5.isNodeTypeSelected)(editor, ["image"])) {
|
|
4029
4574
|
return false;
|
|
4030
4575
|
}
|
|
4031
4576
|
try {
|
|
@@ -4051,9 +4596,9 @@ function toggleTable(editor, config) {
|
|
|
4051
4596
|
function shouldShowButton(props) {
|
|
4052
4597
|
const { editor, hideWhenUnavailable } = props;
|
|
4053
4598
|
if (!editor || !editor.isEditable) return false;
|
|
4054
|
-
if (!(0,
|
|
4599
|
+
if (!(0, import_editor_utils5.isNodeInSchema)("table", editor)) return false;
|
|
4055
4600
|
if (hideWhenUnavailable) {
|
|
4056
|
-
if ((0,
|
|
4601
|
+
if ((0, import_react39.isNodeSelection)(editor.state.selection) || !canToggle) {
|
|
4057
4602
|
return false;
|
|
4058
4603
|
}
|
|
4059
4604
|
}
|
|
@@ -4066,10 +4611,10 @@ function useTableBlock(config) {
|
|
|
4066
4611
|
onToggled
|
|
4067
4612
|
} = config || {};
|
|
4068
4613
|
const { editor } = useTiptapEditor(providedEditor);
|
|
4069
|
-
const [isVisible, setIsVisible] = (0,
|
|
4614
|
+
const [isVisible, setIsVisible] = (0, import_react40.useState)(true);
|
|
4070
4615
|
const canToggleState = canToggle(editor);
|
|
4071
4616
|
const isActive = (editor == null ? void 0 : editor.isActive("table")) || false;
|
|
4072
|
-
(0,
|
|
4617
|
+
(0, import_react40.useEffect)(() => {
|
|
4073
4618
|
if (!editor) return;
|
|
4074
4619
|
const handleSelectionUpdate = () => {
|
|
4075
4620
|
setIsVisible(shouldShowButton({ editor, hideWhenUnavailable }));
|
|
@@ -4080,7 +4625,7 @@ function useTableBlock(config) {
|
|
|
4080
4625
|
editor.off("selectionUpdate", handleSelectionUpdate);
|
|
4081
4626
|
};
|
|
4082
4627
|
}, [editor, hideWhenUnavailable]);
|
|
4083
|
-
const handleToggle = (0,
|
|
4628
|
+
const handleToggle = (0, import_react40.useCallback)(() => {
|
|
4084
4629
|
if (!editor) return false;
|
|
4085
4630
|
const success = toggleTable(editor);
|
|
4086
4631
|
if (success) {
|
|
@@ -4266,8 +4811,8 @@ var getItemImplementations = () => {
|
|
|
4266
4811
|
// AI
|
|
4267
4812
|
continue_writing: {
|
|
4268
4813
|
check: (editor) => {
|
|
4269
|
-
const { hasContent } = (0,
|
|
4270
|
-
const extensionsReady = (0,
|
|
4814
|
+
const { hasContent } = (0, import_editor_utils6.hasContentAbove)(editor);
|
|
4815
|
+
const extensionsReady = (0, import_editor_utils6.isExtensionAvailable)(editor, [
|
|
4271
4816
|
"ai",
|
|
4272
4817
|
"aiAdvanced"
|
|
4273
4818
|
]);
|
|
@@ -4275,14 +4820,14 @@ var getItemImplementations = () => {
|
|
|
4275
4820
|
},
|
|
4276
4821
|
action: ({ editor }) => {
|
|
4277
4822
|
const editorChain = editor.chain().focus();
|
|
4278
|
-
const nodeSelectionPosition = (0,
|
|
4823
|
+
const nodeSelectionPosition = (0, import_editor_utils6.findSelectionPosition)({ editor });
|
|
4279
4824
|
if (nodeSelectionPosition !== null) {
|
|
4280
4825
|
editorChain.setNodeSelection(nodeSelectionPosition);
|
|
4281
4826
|
}
|
|
4282
4827
|
editorChain.run();
|
|
4283
4828
|
editor.chain().focus().aiGenerationShow().run();
|
|
4284
4829
|
requestAnimationFrame(() => {
|
|
4285
|
-
const { hasContent, content } = (0,
|
|
4830
|
+
const { hasContent, content } = (0, import_editor_utils6.hasContentAbove)(editor);
|
|
4286
4831
|
const snippet = content.length > 500 ? `...${content.slice(-500)}` : content;
|
|
4287
4832
|
const prompt = hasContent ? `Context: ${snippet}
|
|
4288
4833
|
|
|
@@ -4296,10 +4841,10 @@ Continue writing from where the text above ends. Write ONLY ONE SENTENCE. DONT R
|
|
|
4296
4841
|
}
|
|
4297
4842
|
},
|
|
4298
4843
|
ai_ask_button: {
|
|
4299
|
-
check: (editor) => (0,
|
|
4844
|
+
check: (editor) => (0, import_editor_utils6.isExtensionAvailable)(editor, ["ai", "aiAdvanced"]),
|
|
4300
4845
|
action: ({ editor }) => {
|
|
4301
4846
|
const editorChain = editor.chain().focus();
|
|
4302
|
-
const nodeSelectionPosition = (0,
|
|
4847
|
+
const nodeSelectionPosition = (0, import_editor_utils6.findSelectionPosition)({ editor });
|
|
4303
4848
|
if (nodeSelectionPosition !== null) {
|
|
4304
4849
|
editorChain.setNodeSelection(nodeSelectionPosition);
|
|
4305
4850
|
}
|
|
@@ -4309,55 +4854,55 @@ Continue writing from where the text above ends. Write ONLY ONE SENTENCE. DONT R
|
|
|
4309
4854
|
},
|
|
4310
4855
|
// Style
|
|
4311
4856
|
text: {
|
|
4312
|
-
check: (editor) => (0,
|
|
4857
|
+
check: (editor) => (0, import_editor_utils6.isNodeInSchema)("paragraph", editor),
|
|
4313
4858
|
action: ({ editor }) => {
|
|
4314
4859
|
editor.chain().focus().setParagraph().run();
|
|
4315
4860
|
}
|
|
4316
4861
|
},
|
|
4317
4862
|
heading_1: {
|
|
4318
|
-
check: (editor) => (0,
|
|
4863
|
+
check: (editor) => (0, import_editor_utils6.isNodeInSchema)("heading", editor),
|
|
4319
4864
|
action: ({ editor }) => {
|
|
4320
4865
|
editor.chain().focus().toggleHeading({ level: 1 }).run();
|
|
4321
4866
|
}
|
|
4322
4867
|
},
|
|
4323
4868
|
heading_2: {
|
|
4324
|
-
check: (editor) => (0,
|
|
4869
|
+
check: (editor) => (0, import_editor_utils6.isNodeInSchema)("heading", editor),
|
|
4325
4870
|
action: ({ editor }) => {
|
|
4326
4871
|
editor.chain().focus().toggleHeading({ level: 2 }).run();
|
|
4327
4872
|
}
|
|
4328
4873
|
},
|
|
4329
4874
|
heading_3: {
|
|
4330
|
-
check: (editor) => (0,
|
|
4875
|
+
check: (editor) => (0, import_editor_utils6.isNodeInSchema)("heading", editor),
|
|
4331
4876
|
action: ({ editor }) => {
|
|
4332
4877
|
editor.chain().focus().toggleHeading({ level: 3 }).run();
|
|
4333
4878
|
}
|
|
4334
4879
|
},
|
|
4335
4880
|
bullet_list: {
|
|
4336
|
-
check: (editor) => (0,
|
|
4881
|
+
check: (editor) => (0, import_editor_utils6.isNodeInSchema)("bulletList", editor),
|
|
4337
4882
|
action: ({ editor }) => {
|
|
4338
4883
|
editor.chain().focus().toggleBulletList().run();
|
|
4339
4884
|
}
|
|
4340
4885
|
},
|
|
4341
4886
|
ordered_list: {
|
|
4342
|
-
check: (editor) => (0,
|
|
4887
|
+
check: (editor) => (0, import_editor_utils6.isNodeInSchema)("orderedList", editor),
|
|
4343
4888
|
action: ({ editor }) => {
|
|
4344
4889
|
editor.chain().focus().toggleOrderedList().run();
|
|
4345
4890
|
}
|
|
4346
4891
|
},
|
|
4347
4892
|
task_list: {
|
|
4348
|
-
check: (editor) => (0,
|
|
4893
|
+
check: (editor) => (0, import_editor_utils6.isNodeInSchema)("taskList", editor),
|
|
4349
4894
|
action: ({ editor }) => {
|
|
4350
4895
|
editor.chain().focus().toggleTaskList().run();
|
|
4351
4896
|
}
|
|
4352
4897
|
},
|
|
4353
4898
|
quote: {
|
|
4354
|
-
check: (editor) => (0,
|
|
4899
|
+
check: (editor) => (0, import_editor_utils6.isNodeInSchema)("blockquote", editor),
|
|
4355
4900
|
action: ({ editor }) => {
|
|
4356
4901
|
editor.chain().focus().toggleBlockquote().run();
|
|
4357
4902
|
}
|
|
4358
4903
|
},
|
|
4359
4904
|
code_block: {
|
|
4360
|
-
check: (editor) => (0,
|
|
4905
|
+
check: (editor) => (0, import_editor_utils6.isNodeInSchema)("codeBlock", editor),
|
|
4361
4906
|
action: ({ editor }) => {
|
|
4362
4907
|
editor.chain().focus().toggleNode("codeBlock", "paragraph").run();
|
|
4363
4908
|
}
|
|
@@ -4374,17 +4919,17 @@ Continue writing from where the text above ends. Write ONLY ONE SENTENCE. DONT R
|
|
|
4374
4919
|
// action: ({ editor }: { editor: Editor }) => addEmojiTrigger(editor),
|
|
4375
4920
|
// },
|
|
4376
4921
|
divider: {
|
|
4377
|
-
check: (editor) => (0,
|
|
4922
|
+
check: (editor) => (0, import_editor_utils6.isNodeInSchema)("horizontalRule", editor),
|
|
4378
4923
|
action: ({ editor }) => {
|
|
4379
4924
|
editor.chain().focus().setHorizontalRule().run();
|
|
4380
4925
|
}
|
|
4381
4926
|
},
|
|
4382
4927
|
table: {
|
|
4383
|
-
check: (editor) => (0,
|
|
4928
|
+
check: (editor) => (0, import_editor_utils6.isNodeInSchema)("table", editor),
|
|
4384
4929
|
action: ({ editor }) => toggleTable(editor, { rows: 3, cols: 3, withHeaderRow: true })
|
|
4385
4930
|
},
|
|
4386
4931
|
control: {
|
|
4387
|
-
check: (editor) => (0,
|
|
4932
|
+
check: (editor) => (0, import_editor_utils6.isNodeInSchema)("controlBlock", editor),
|
|
4388
4933
|
action: ({ editor }) => {
|
|
4389
4934
|
try {
|
|
4390
4935
|
return editor.chain().focus().insertControlBlock().run();
|
|
@@ -4394,32 +4939,32 @@ Continue writing from where the text above ends. Write ONLY ONE SENTENCE. DONT R
|
|
|
4394
4939
|
}
|
|
4395
4940
|
},
|
|
4396
4941
|
table_of_contents: {
|
|
4397
|
-
check: (editor) => (0,
|
|
4942
|
+
check: (editor) => (0, import_editor_utils6.isNodeInSchema)("tableOfContentsNode", editor),
|
|
4398
4943
|
action: ({ editor }) => {
|
|
4399
4944
|
editor.chain().focus().insertTableOfContents().run();
|
|
4400
4945
|
}
|
|
4401
4946
|
},
|
|
4402
4947
|
callout: {
|
|
4403
|
-
check: (editor) => (0,
|
|
4948
|
+
check: (editor) => (0, import_editor_utils6.isNodeInSchema)("calloutNode", editor),
|
|
4404
4949
|
action: ({ editor }) => {
|
|
4405
4950
|
editor.chain().focus().insertCallout("info").run();
|
|
4406
4951
|
}
|
|
4407
4952
|
},
|
|
4408
4953
|
callout_warning: {
|
|
4409
|
-
check: (editor) => (0,
|
|
4954
|
+
check: (editor) => (0, import_editor_utils6.isNodeInSchema)("calloutNode", editor),
|
|
4410
4955
|
action: ({ editor }) => {
|
|
4411
4956
|
editor.chain().focus().insertCallout("warning").run();
|
|
4412
4957
|
}
|
|
4413
4958
|
},
|
|
4414
4959
|
math: {
|
|
4415
|
-
check: (editor) => (0,
|
|
4960
|
+
check: (editor) => (0, import_editor_utils6.isNodeInSchema)("mathBlock", editor),
|
|
4416
4961
|
action: ({ editor }) => {
|
|
4417
4962
|
editor.chain().focus().insertMathBlock().run();
|
|
4418
4963
|
}
|
|
4419
4964
|
},
|
|
4420
4965
|
// Upload
|
|
4421
4966
|
image: {
|
|
4422
|
-
check: (editor) => (0,
|
|
4967
|
+
check: (editor) => (0, import_editor_utils6.isNodeInSchema)("imageUpload", editor),
|
|
4423
4968
|
action: ({ editor }) => {
|
|
4424
4969
|
editor.chain().focus().setImageUpload().run();
|
|
4425
4970
|
}
|
|
@@ -4445,7 +4990,7 @@ function organizeItemsByGroups(items, showGroups) {
|
|
|
4445
4990
|
return organizedItems;
|
|
4446
4991
|
}
|
|
4447
4992
|
function useSlashDropdownMenu(config) {
|
|
4448
|
-
const getSlashMenuItems =
|
|
4993
|
+
const getSlashMenuItems = React10.useCallback(
|
|
4449
4994
|
(editor) => {
|
|
4450
4995
|
const items = [];
|
|
4451
4996
|
const enabledItems = (config == null ? void 0 : config.enabledItems) || Object.keys(texts);
|
|
@@ -4482,11 +5027,11 @@ function useSlashDropdownMenu(config) {
|
|
|
4482
5027
|
}
|
|
4483
5028
|
|
|
4484
5029
|
// src/ui/slash-dropdown-menu/slash-dropdown-menu.tsx
|
|
4485
|
-
var
|
|
5030
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
4486
5031
|
var SlashDropdownMenu = (props) => {
|
|
4487
5032
|
const { config, ...restProps } = props;
|
|
4488
5033
|
const { getSlashMenuItems } = useSlashDropdownMenu(config);
|
|
4489
|
-
return /* @__PURE__ */ (0,
|
|
5034
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4490
5035
|
SuggestionMenu,
|
|
4491
5036
|
{
|
|
4492
5037
|
char: "/",
|
|
@@ -4496,19 +5041,19 @@ var SlashDropdownMenu = (props) => {
|
|
|
4496
5041
|
selector: "tiptap-slash-dropdown-menu",
|
|
4497
5042
|
items: ({ query, editor }) => filterSuggestionItems(getSlashMenuItems(editor), query),
|
|
4498
5043
|
...restProps,
|
|
4499
|
-
children: (props2) => /* @__PURE__ */ (0,
|
|
5044
|
+
children: (props2) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(List, { ...props2, config })
|
|
4500
5045
|
}
|
|
4501
5046
|
);
|
|
4502
5047
|
};
|
|
4503
5048
|
var Item = (props) => {
|
|
4504
5049
|
const { item, isSelected, onSelect } = props;
|
|
4505
|
-
const itemRef =
|
|
4506
|
-
|
|
5050
|
+
const itemRef = React11.useRef(null);
|
|
5051
|
+
React11.useEffect(() => {
|
|
4507
5052
|
const selector = document.querySelector(
|
|
4508
5053
|
'[data-selector="tiptap-slash-dropdown-menu"]'
|
|
4509
5054
|
);
|
|
4510
5055
|
if (!itemRef.current || !isSelected || !selector) return;
|
|
4511
|
-
const overflow = (0,
|
|
5056
|
+
const overflow = (0, import_editor_utils7.getElementOverflowPosition)(itemRef.current, selector);
|
|
4512
5057
|
if (overflow === "top") {
|
|
4513
5058
|
itemRef.current.scrollIntoView(true);
|
|
4514
5059
|
} else if (overflow === "bottom") {
|
|
@@ -4516,13 +5061,13 @@ var Item = (props) => {
|
|
|
4516
5061
|
}
|
|
4517
5062
|
}, [isSelected]);
|
|
4518
5063
|
const BadgeIcon = item.badge;
|
|
4519
|
-
return /* @__PURE__ */ (0,
|
|
4520
|
-
|
|
5064
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5065
|
+
import_button10.Button,
|
|
4521
5066
|
{
|
|
4522
5067
|
ref: itemRef,
|
|
4523
5068
|
variant: "ghost",
|
|
4524
5069
|
color: "default",
|
|
4525
|
-
startContent: BadgeIcon && /* @__PURE__ */ (0,
|
|
5070
|
+
startContent: BadgeIcon && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(BadgeIcon, {}),
|
|
4526
5071
|
"data-active-state": isSelected ? "on" : "off",
|
|
4527
5072
|
onClick: onSelect,
|
|
4528
5073
|
fullWidth: true,
|
|
@@ -4537,14 +5082,14 @@ var List = ({
|
|
|
4537
5082
|
onSelect,
|
|
4538
5083
|
config
|
|
4539
5084
|
}) => {
|
|
4540
|
-
const styles = (0,
|
|
4541
|
-
const renderedItems =
|
|
5085
|
+
const styles = (0, import_theme7.slashDropdownMenu)();
|
|
5086
|
+
const renderedItems = React11.useMemo(() => {
|
|
4542
5087
|
const rendered = [];
|
|
4543
5088
|
const showGroups = (config == null ? void 0 : config.showGroups) !== false;
|
|
4544
5089
|
if (!showGroups) {
|
|
4545
5090
|
items.forEach((item, index) => {
|
|
4546
5091
|
rendered.push(
|
|
4547
|
-
/* @__PURE__ */ (0,
|
|
5092
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4548
5093
|
Item,
|
|
4549
5094
|
{
|
|
4550
5095
|
item,
|
|
@@ -4569,7 +5114,7 @@ var List = ({
|
|
|
4569
5114
|
Object.entries(groups).forEach(([groupLabel, groupData], groupIndex) => {
|
|
4570
5115
|
if (groupIndex > 0) {
|
|
4571
5116
|
rendered.push(
|
|
4572
|
-
/* @__PURE__ */ (0,
|
|
5117
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4573
5118
|
import_separator.Separator,
|
|
4574
5119
|
{
|
|
4575
5120
|
orientation: "horizontal"
|
|
@@ -4580,7 +5125,7 @@ var List = ({
|
|
|
4580
5125
|
}
|
|
4581
5126
|
const groupItems = groupData.items.map((item, itemIndex) => {
|
|
4582
5127
|
const originalIndex = groupData.indices[itemIndex];
|
|
4583
|
-
return /* @__PURE__ */ (0,
|
|
5128
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4584
5129
|
Item,
|
|
4585
5130
|
{
|
|
4586
5131
|
item,
|
|
@@ -4592,13 +5137,13 @@ var List = ({
|
|
|
4592
5137
|
});
|
|
4593
5138
|
if (groupLabel) {
|
|
4594
5139
|
rendered.push(
|
|
4595
|
-
/* @__PURE__ */ (0,
|
|
5140
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
4596
5141
|
"div",
|
|
4597
5142
|
{
|
|
4598
5143
|
className: styles.cardItemGroup(),
|
|
4599
5144
|
children: [
|
|
4600
|
-
/* @__PURE__ */ (0,
|
|
4601
|
-
/* @__PURE__ */ (0,
|
|
5145
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: styles.cardGroupLabel(), children: groupLabel }),
|
|
5146
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: styles.cardGroup(), children: groupItems })
|
|
4602
5147
|
]
|
|
4603
5148
|
},
|
|
4604
5149
|
`group-${groupIndex}-${groupLabel}`
|
|
@@ -4613,14 +5158,14 @@ var List = ({
|
|
|
4613
5158
|
if (!renderedItems.length) {
|
|
4614
5159
|
return null;
|
|
4615
5160
|
}
|
|
4616
|
-
return /* @__PURE__ */ (0,
|
|
5161
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4617
5162
|
"div",
|
|
4618
5163
|
{
|
|
4619
5164
|
className: styles.card(),
|
|
4620
5165
|
style: {
|
|
4621
5166
|
maxHeight: "var(--suggestion-menu-max-height)"
|
|
4622
5167
|
},
|
|
4623
|
-
children: /* @__PURE__ */ (0,
|
|
5168
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: styles.body(), children: renderedItems })
|
|
4624
5169
|
}
|
|
4625
5170
|
);
|
|
4626
5171
|
};
|
|
@@ -4630,20 +5175,20 @@ var import_icons25 = require("@kopexa/icons");
|
|
|
4630
5175
|
var import_popover3 = require("@kopexa/popover");
|
|
4631
5176
|
var import_toolbar10 = require("@kopexa/toolbar");
|
|
4632
5177
|
var import_use_is_mobile2 = require("@kopexa/use-is-mobile");
|
|
4633
|
-
var
|
|
5178
|
+
var import_react55 = require("react");
|
|
4634
5179
|
|
|
4635
5180
|
// src/hooks/use-cursor-visibility.ts
|
|
4636
|
-
var
|
|
5181
|
+
var React13 = __toESM(require("react"));
|
|
4637
5182
|
|
|
4638
5183
|
// src/hooks/use-window-size.ts
|
|
4639
|
-
var
|
|
5184
|
+
var React12 = __toESM(require("react"));
|
|
4640
5185
|
function useWindowSize() {
|
|
4641
|
-
const [windowSize, setWindowSize] =
|
|
5186
|
+
const [windowSize, setWindowSize] = React12.useState({
|
|
4642
5187
|
width: 0,
|
|
4643
5188
|
height: 0,
|
|
4644
5189
|
offsetTop: 0
|
|
4645
5190
|
});
|
|
4646
|
-
|
|
5191
|
+
React12.useEffect(() => {
|
|
4647
5192
|
handleResize();
|
|
4648
5193
|
function handleResize() {
|
|
4649
5194
|
if (typeof window === "undefined") return;
|
|
@@ -4679,19 +5224,19 @@ function useCursorVisibility({
|
|
|
4679
5224
|
elementRef = null
|
|
4680
5225
|
}) {
|
|
4681
5226
|
const { height: windowHeight } = useWindowSize();
|
|
4682
|
-
const [rect, setRect] =
|
|
5227
|
+
const [rect, setRect] = React13.useState({
|
|
4683
5228
|
x: 0,
|
|
4684
5229
|
y: 0,
|
|
4685
5230
|
width: 0,
|
|
4686
5231
|
height: 0
|
|
4687
5232
|
});
|
|
4688
|
-
const updateRect =
|
|
5233
|
+
const updateRect = React13.useCallback(() => {
|
|
4689
5234
|
var _a;
|
|
4690
5235
|
const element = (_a = elementRef == null ? void 0 : elementRef.current) != null ? _a : document.body;
|
|
4691
5236
|
const { x, y, width, height } = element.getBoundingClientRect();
|
|
4692
5237
|
setRect({ x, y, width, height });
|
|
4693
5238
|
}, [elementRef]);
|
|
4694
|
-
|
|
5239
|
+
React13.useEffect(() => {
|
|
4695
5240
|
var _a;
|
|
4696
5241
|
const element = (_a = elementRef == null ? void 0 : elementRef.current) != null ? _a : document.body;
|
|
4697
5242
|
updateRect();
|
|
@@ -4705,7 +5250,7 @@ function useCursorVisibility({
|
|
|
4705
5250
|
window.removeEventListener("scroll", updateRect);
|
|
4706
5251
|
};
|
|
4707
5252
|
}, [elementRef, updateRect]);
|
|
4708
|
-
|
|
5253
|
+
React13.useEffect(() => {
|
|
4709
5254
|
const ensureCursorVisibility = () => {
|
|
4710
5255
|
if (!editor) return;
|
|
4711
5256
|
const { state, view } = editor;
|
|
@@ -4736,18 +5281,18 @@ function useCursorVisibility({
|
|
|
4736
5281
|
|
|
4737
5282
|
// src/ui/blockquote-button/blockquote-button.tsx
|
|
4738
5283
|
var import_toolbar4 = require("@kopexa/toolbar");
|
|
4739
|
-
var
|
|
5284
|
+
var React15 = __toESM(require("react"));
|
|
4740
5285
|
|
|
4741
5286
|
// src/ui/blockquote-button/use-blockquote.ts
|
|
4742
|
-
var
|
|
5287
|
+
var import_editor_utils8 = require("@kopexa/editor-utils");
|
|
4743
5288
|
var import_icons14 = require("@kopexa/icons");
|
|
4744
|
-
var
|
|
4745
|
-
var
|
|
5289
|
+
var import_state7 = require("@tiptap/pm/state");
|
|
5290
|
+
var React14 = __toESM(require("react"));
|
|
4746
5291
|
var BLOCKQUOTE_SHORTCUT_KEY = "mod+shift+b";
|
|
4747
5292
|
function canToggleBlockquote(editor, turnInto = true) {
|
|
4748
5293
|
var _a;
|
|
4749
5294
|
if (!editor || !editor.isEditable) return false;
|
|
4750
|
-
if (!(0,
|
|
5295
|
+
if (!(0, import_editor_utils8.isNodeInSchema)("blockquote", editor) || (0, import_editor_utils8.isNodeTypeSelected)(editor, ["image"]))
|
|
4751
5296
|
return false;
|
|
4752
5297
|
if (!turnInto) {
|
|
4753
5298
|
return editor.can().toggleWrap("blockquote");
|
|
@@ -4756,12 +5301,12 @@ function canToggleBlockquote(editor, turnInto = true) {
|
|
|
4756
5301
|
const view = editor.view;
|
|
4757
5302
|
const state = view.state;
|
|
4758
5303
|
const selection = state.selection;
|
|
4759
|
-
if (selection.empty || selection instanceof
|
|
4760
|
-
const pos = (_a = (0,
|
|
5304
|
+
if (selection.empty || selection instanceof import_state7.TextSelection) {
|
|
5305
|
+
const pos = (_a = (0, import_editor_utils8.findNodePosition)({
|
|
4761
5306
|
editor,
|
|
4762
5307
|
node: state.selection.$anchor.node(1)
|
|
4763
5308
|
})) == null ? void 0 : _a.pos;
|
|
4764
|
-
if (!(0,
|
|
5309
|
+
if (!(0, import_editor_utils8.isValidPosition)(pos)) return false;
|
|
4765
5310
|
}
|
|
4766
5311
|
return true;
|
|
4767
5312
|
} catch {
|
|
@@ -4776,19 +5321,19 @@ function toggleBlockquote(editor) {
|
|
|
4776
5321
|
const view = editor.view;
|
|
4777
5322
|
let state = view.state;
|
|
4778
5323
|
let tr = state.tr;
|
|
4779
|
-
if (state.selection.empty || state.selection instanceof
|
|
4780
|
-
const pos = (_a = (0,
|
|
5324
|
+
if (state.selection.empty || state.selection instanceof import_state7.TextSelection) {
|
|
5325
|
+
const pos = (_a = (0, import_editor_utils8.findNodePosition)({
|
|
4781
5326
|
editor,
|
|
4782
5327
|
node: state.selection.$anchor.node(1)
|
|
4783
5328
|
})) == null ? void 0 : _a.pos;
|
|
4784
|
-
if (!(0,
|
|
4785
|
-
tr = tr.setSelection(
|
|
5329
|
+
if (!(0, import_editor_utils8.isValidPosition)(pos)) return false;
|
|
5330
|
+
tr = tr.setSelection(import_state7.NodeSelection.create(state.doc, pos));
|
|
4786
5331
|
view.dispatch(tr);
|
|
4787
5332
|
state = view.state;
|
|
4788
5333
|
}
|
|
4789
5334
|
const selection = state.selection;
|
|
4790
5335
|
let chain = editor.chain().focus();
|
|
4791
|
-
if (selection instanceof
|
|
5336
|
+
if (selection instanceof import_state7.NodeSelection) {
|
|
4792
5337
|
const firstChild = (_b = selection.node.firstChild) == null ? void 0 : _b.firstChild;
|
|
4793
5338
|
const lastChild = (_c = selection.node.lastChild) == null ? void 0 : _c.lastChild;
|
|
4794
5339
|
const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
|
|
@@ -4806,7 +5351,7 @@ function toggleBlockquote(editor) {
|
|
|
4806
5351
|
function shouldShowButton2(props) {
|
|
4807
5352
|
const { editor, hideWhenUnavailable } = props;
|
|
4808
5353
|
if (!editor || !editor.isEditable) return false;
|
|
4809
|
-
if (!(0,
|
|
5354
|
+
if (!(0, import_editor_utils8.isNodeInSchema)("blockquote", editor)) return false;
|
|
4810
5355
|
if (hideWhenUnavailable && !editor.isActive("code")) {
|
|
4811
5356
|
return canToggleBlockquote(editor);
|
|
4812
5357
|
}
|
|
@@ -4819,10 +5364,10 @@ function useBlockquote(config) {
|
|
|
4819
5364
|
onToggled
|
|
4820
5365
|
} = config || {};
|
|
4821
5366
|
const { editor } = useTiptapEditor(providedEditor);
|
|
4822
|
-
const [isVisible, setIsVisible] =
|
|
5367
|
+
const [isVisible, setIsVisible] = React14.useState(true);
|
|
4823
5368
|
const canToggle3 = canToggleBlockquote(editor);
|
|
4824
5369
|
const isActive = (editor == null ? void 0 : editor.isActive("blockquote")) || false;
|
|
4825
|
-
|
|
5370
|
+
React14.useEffect(() => {
|
|
4826
5371
|
if (!editor) return;
|
|
4827
5372
|
const handleSelectionUpdate = () => {
|
|
4828
5373
|
setIsVisible(shouldShowButton2({ editor, hideWhenUnavailable }));
|
|
@@ -4833,7 +5378,7 @@ function useBlockquote(config) {
|
|
|
4833
5378
|
editor.off("selectionUpdate", handleSelectionUpdate);
|
|
4834
5379
|
};
|
|
4835
5380
|
}, [editor, hideWhenUnavailable]);
|
|
4836
|
-
const handleToggle =
|
|
5381
|
+
const handleToggle = React14.useCallback(() => {
|
|
4837
5382
|
if (!editor) return false;
|
|
4838
5383
|
const success = toggleBlockquote(editor);
|
|
4839
5384
|
if (success) {
|
|
@@ -4853,7 +5398,7 @@ function useBlockquote(config) {
|
|
|
4853
5398
|
}
|
|
4854
5399
|
|
|
4855
5400
|
// src/ui/blockquote-button/blockquote-button.tsx
|
|
4856
|
-
var
|
|
5401
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
4857
5402
|
var BlockquoteButton = ({
|
|
4858
5403
|
editor: providedEditor,
|
|
4859
5404
|
text,
|
|
@@ -4878,7 +5423,7 @@ var BlockquoteButton = ({
|
|
|
4878
5423
|
hideWhenUnavailable,
|
|
4879
5424
|
onToggled
|
|
4880
5425
|
});
|
|
4881
|
-
const handleClick =
|
|
5426
|
+
const handleClick = React15.useCallback(
|
|
4882
5427
|
(event) => {
|
|
4883
5428
|
onClick == null ? void 0 : onClick(event);
|
|
4884
5429
|
if (event.defaultPrevented) return;
|
|
@@ -4889,7 +5434,7 @@ var BlockquoteButton = ({
|
|
|
4889
5434
|
if (!isVisible) {
|
|
4890
5435
|
return null;
|
|
4891
5436
|
}
|
|
4892
|
-
return /* @__PURE__ */ (0,
|
|
5437
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4893
5438
|
import_toolbar4.ToolbarButton,
|
|
4894
5439
|
{
|
|
4895
5440
|
type: "button",
|
|
@@ -4906,9 +5451,9 @@ var BlockquoteButton = ({
|
|
|
4906
5451
|
onClick: handleClick,
|
|
4907
5452
|
isIconOnly: !text && !children,
|
|
4908
5453
|
...buttonProps,
|
|
4909
|
-
children: children != null ? children : /* @__PURE__ */ (0,
|
|
4910
|
-
/* @__PURE__ */ (0,
|
|
4911
|
-
text && /* @__PURE__ */ (0,
|
|
5454
|
+
children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
5455
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Icon, {}),
|
|
5456
|
+
text && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: text })
|
|
4912
5457
|
] })
|
|
4913
5458
|
}
|
|
4914
5459
|
);
|
|
@@ -4917,18 +5462,18 @@ var BlockquoteButton = ({
|
|
|
4917
5462
|
// src/ui/codeblock-button/code-block-button.tsx
|
|
4918
5463
|
var import_icons16 = require("@kopexa/icons");
|
|
4919
5464
|
var import_toolbar5 = require("@kopexa/toolbar");
|
|
4920
|
-
var
|
|
5465
|
+
var import_react41 = require("react");
|
|
4921
5466
|
|
|
4922
5467
|
// src/ui/codeblock-button/use-code-block.ts
|
|
4923
|
-
var
|
|
5468
|
+
var import_editor_utils9 = require("@kopexa/editor-utils");
|
|
4924
5469
|
var import_icons15 = require("@kopexa/icons");
|
|
4925
|
-
var
|
|
4926
|
-
var
|
|
5470
|
+
var import_state8 = require("@tiptap/pm/state");
|
|
5471
|
+
var React16 = __toESM(require("react"));
|
|
4927
5472
|
var CODE_BLOCK_SHORTCUT_KEY = "mod+alt+c";
|
|
4928
5473
|
function canToggle2(editor, turnInto = true) {
|
|
4929
5474
|
var _a;
|
|
4930
5475
|
if (!editor || !editor.isEditable) return false;
|
|
4931
|
-
if (!(0,
|
|
5476
|
+
if (!(0, import_editor_utils9.isNodeInSchema)("codeBlock", editor) || (0, import_editor_utils9.isNodeTypeSelected)(editor, ["image"]))
|
|
4932
5477
|
return false;
|
|
4933
5478
|
if (!turnInto) {
|
|
4934
5479
|
return editor.can().toggleNode("codeBlock", "paragraph");
|
|
@@ -4937,12 +5482,12 @@ function canToggle2(editor, turnInto = true) {
|
|
|
4937
5482
|
const view = editor.view;
|
|
4938
5483
|
const state = view.state;
|
|
4939
5484
|
const selection = state.selection;
|
|
4940
|
-
if (selection.empty || selection instanceof
|
|
4941
|
-
const pos = (_a = (0,
|
|
5485
|
+
if (selection.empty || selection instanceof import_state8.TextSelection) {
|
|
5486
|
+
const pos = (_a = (0, import_editor_utils9.findNodePosition)({
|
|
4942
5487
|
editor,
|
|
4943
5488
|
node: state.selection.$anchor.node(1)
|
|
4944
5489
|
})) == null ? void 0 : _a.pos;
|
|
4945
|
-
if (!(0,
|
|
5490
|
+
if (!(0, import_editor_utils9.isValidPosition)(pos)) return false;
|
|
4946
5491
|
}
|
|
4947
5492
|
return true;
|
|
4948
5493
|
} catch {
|
|
@@ -4957,19 +5502,19 @@ function toggleCodeBlock(editor) {
|
|
|
4957
5502
|
const view = editor.view;
|
|
4958
5503
|
let state = view.state;
|
|
4959
5504
|
let tr = state.tr;
|
|
4960
|
-
if (state.selection.empty || state.selection instanceof
|
|
4961
|
-
const pos = (_a = (0,
|
|
5505
|
+
if (state.selection.empty || state.selection instanceof import_state8.TextSelection) {
|
|
5506
|
+
const pos = (_a = (0, import_editor_utils9.findNodePosition)({
|
|
4962
5507
|
editor,
|
|
4963
5508
|
node: state.selection.$anchor.node(1)
|
|
4964
5509
|
})) == null ? void 0 : _a.pos;
|
|
4965
|
-
if (!(0,
|
|
4966
|
-
tr = tr.setSelection(
|
|
5510
|
+
if (!(0, import_editor_utils9.isValidPosition)(pos)) return false;
|
|
5511
|
+
tr = tr.setSelection(import_state8.NodeSelection.create(state.doc, pos));
|
|
4967
5512
|
view.dispatch(tr);
|
|
4968
5513
|
state = view.state;
|
|
4969
5514
|
}
|
|
4970
5515
|
const selection = state.selection;
|
|
4971
5516
|
let chain = editor.chain().focus();
|
|
4972
|
-
if (selection instanceof
|
|
5517
|
+
if (selection instanceof import_state8.NodeSelection) {
|
|
4973
5518
|
const firstChild = (_b = selection.node.firstChild) == null ? void 0 : _b.firstChild;
|
|
4974
5519
|
const lastChild = (_c = selection.node.lastChild) == null ? void 0 : _c.lastChild;
|
|
4975
5520
|
const from = firstChild ? selection.from + firstChild.nodeSize : selection.from + 1;
|
|
@@ -4987,7 +5532,7 @@ function toggleCodeBlock(editor) {
|
|
|
4987
5532
|
function shouldShowButton3(props) {
|
|
4988
5533
|
const { editor, hideWhenUnavailable } = props;
|
|
4989
5534
|
if (!editor || !editor.isEditable) return false;
|
|
4990
|
-
if (!(0,
|
|
5535
|
+
if (!(0, import_editor_utils9.isNodeInSchema)("codeBlock", editor)) return false;
|
|
4991
5536
|
if (hideWhenUnavailable && !editor.isActive("code")) {
|
|
4992
5537
|
return canToggle2(editor);
|
|
4993
5538
|
}
|
|
@@ -5000,10 +5545,10 @@ function useCodeBlock(config) {
|
|
|
5000
5545
|
onToggled
|
|
5001
5546
|
} = config || {};
|
|
5002
5547
|
const { editor } = useTiptapEditor(providedEditor);
|
|
5003
|
-
const [isVisible, setIsVisible] =
|
|
5548
|
+
const [isVisible, setIsVisible] = React16.useState(true);
|
|
5004
5549
|
const canToggleState = canToggle2(editor);
|
|
5005
5550
|
const isActive = (editor == null ? void 0 : editor.isActive("codeBlock")) || false;
|
|
5006
|
-
|
|
5551
|
+
React16.useEffect(() => {
|
|
5007
5552
|
if (!editor) return;
|
|
5008
5553
|
const handleSelectionUpdate = () => {
|
|
5009
5554
|
setIsVisible(shouldShowButton3({ editor, hideWhenUnavailable }));
|
|
@@ -5014,7 +5559,7 @@ function useCodeBlock(config) {
|
|
|
5014
5559
|
editor.off("selectionUpdate", handleSelectionUpdate);
|
|
5015
5560
|
};
|
|
5016
5561
|
}, [editor, hideWhenUnavailable]);
|
|
5017
|
-
const handleToggle =
|
|
5562
|
+
const handleToggle = React16.useCallback(() => {
|
|
5018
5563
|
if (!editor) return false;
|
|
5019
5564
|
const success = toggleCodeBlock(editor);
|
|
5020
5565
|
if (success) {
|
|
@@ -5034,7 +5579,7 @@ function useCodeBlock(config) {
|
|
|
5034
5579
|
}
|
|
5035
5580
|
|
|
5036
5581
|
// src/ui/codeblock-button/code-block-button.tsx
|
|
5037
|
-
var
|
|
5582
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
5038
5583
|
var CodeBlockButton = ({
|
|
5039
5584
|
editor: providedEditor,
|
|
5040
5585
|
text,
|
|
@@ -5051,7 +5596,7 @@ var CodeBlockButton = ({
|
|
|
5051
5596
|
hideWhenUnavailable,
|
|
5052
5597
|
onToggled
|
|
5053
5598
|
});
|
|
5054
|
-
const handleClick = (0,
|
|
5599
|
+
const handleClick = (0, import_react41.useCallback)(
|
|
5055
5600
|
(event) => {
|
|
5056
5601
|
onClick == null ? void 0 : onClick(event);
|
|
5057
5602
|
if (event.defaultPrevented) return;
|
|
@@ -5062,7 +5607,7 @@ var CodeBlockButton = ({
|
|
|
5062
5607
|
if (!isVisible) {
|
|
5063
5608
|
return null;
|
|
5064
5609
|
}
|
|
5065
|
-
return /* @__PURE__ */ (0,
|
|
5610
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5066
5611
|
import_toolbar5.ToolbarButton,
|
|
5067
5612
|
{
|
|
5068
5613
|
type: "button",
|
|
@@ -5079,28 +5624,28 @@ var CodeBlockButton = ({
|
|
|
5079
5624
|
onClick: handleClick,
|
|
5080
5625
|
isIconOnly: true,
|
|
5081
5626
|
...buttonProps,
|
|
5082
|
-
children: /* @__PURE__ */ (0,
|
|
5627
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_icons16.CodeblockIcon, {})
|
|
5083
5628
|
}
|
|
5084
5629
|
);
|
|
5085
5630
|
};
|
|
5086
5631
|
|
|
5087
5632
|
// src/ui/color-highlight-popover/color-highlight-popover.tsx
|
|
5088
|
-
var
|
|
5633
|
+
var import_button11 = require("@kopexa/button");
|
|
5089
5634
|
var import_icons18 = require("@kopexa/icons");
|
|
5090
5635
|
var import_popover2 = require("@kopexa/popover");
|
|
5091
5636
|
var import_toolbar7 = require("@kopexa/toolbar");
|
|
5092
|
-
var
|
|
5637
|
+
var import_react43 = require("react");
|
|
5093
5638
|
|
|
5094
5639
|
// src/ui/color-highlight-button/color-highlight-button.tsx
|
|
5095
|
-
var
|
|
5640
|
+
var import_theme8 = require("@kopexa/theme");
|
|
5096
5641
|
var import_toolbar6 = require("@kopexa/toolbar");
|
|
5097
|
-
var
|
|
5642
|
+
var import_react42 = require("react");
|
|
5098
5643
|
|
|
5099
5644
|
// src/ui/color-highlight-button/use-color-highlight.ts
|
|
5100
|
-
var
|
|
5645
|
+
var import_editor_utils10 = require("@kopexa/editor-utils");
|
|
5101
5646
|
var import_icons17 = require("@kopexa/icons");
|
|
5102
5647
|
var import_use_is_mobile = require("@kopexa/use-is-mobile");
|
|
5103
|
-
var
|
|
5648
|
+
var React17 = __toESM(require("react"));
|
|
5104
5649
|
var import_react_hotkeys_hook = require("react-hotkeys-hook");
|
|
5105
5650
|
var COLOR_HIGHLIGHT_SHORTCUT_KEY = "mod+shift+h";
|
|
5106
5651
|
var HIGHLIGHT_COLORS = [
|
|
@@ -5163,7 +5708,7 @@ function pickHighlightColorsByValue(values) {
|
|
|
5163
5708
|
}
|
|
5164
5709
|
function canColorHighlight(editor) {
|
|
5165
5710
|
if (!editor || !editor.isEditable) return false;
|
|
5166
|
-
if (!(0,
|
|
5711
|
+
if (!(0, import_editor_utils10.isMarkInSchema)("highlight", editor) || (0, import_editor_utils10.isNodeTypeSelected)(editor, ["image"]))
|
|
5167
5712
|
return false;
|
|
5168
5713
|
return editor.can().setMark("highlight");
|
|
5169
5714
|
}
|
|
@@ -5179,7 +5724,7 @@ function removeHighlight(editor) {
|
|
|
5179
5724
|
function shouldShowButton4(props) {
|
|
5180
5725
|
const { editor, hideWhenUnavailable } = props;
|
|
5181
5726
|
if (!editor || !editor.isEditable) return false;
|
|
5182
|
-
if (!(0,
|
|
5727
|
+
if (!(0, import_editor_utils10.isMarkInSchema)("highlight", editor)) return false;
|
|
5183
5728
|
if (hideWhenUnavailable && !editor.isActive("code")) {
|
|
5184
5729
|
return canColorHighlight(editor);
|
|
5185
5730
|
}
|
|
@@ -5195,10 +5740,10 @@ function useColorHighlight(config) {
|
|
|
5195
5740
|
} = config;
|
|
5196
5741
|
const { editor } = useTiptapEditor(providedEditor);
|
|
5197
5742
|
const isMobile = (0, import_use_is_mobile.useIsMobile)();
|
|
5198
|
-
const [isVisible, setIsVisible] =
|
|
5743
|
+
const [isVisible, setIsVisible] = React17.useState(true);
|
|
5199
5744
|
const canColorHighlightState = canColorHighlight(editor);
|
|
5200
5745
|
const isActive = isColorHighlightActive(editor, highlightColor);
|
|
5201
|
-
|
|
5746
|
+
React17.useEffect(() => {
|
|
5202
5747
|
if (!editor) return;
|
|
5203
5748
|
const handleSelectionUpdate = () => {
|
|
5204
5749
|
setIsVisible(shouldShowButton4({ editor, hideWhenUnavailable }));
|
|
@@ -5209,7 +5754,7 @@ function useColorHighlight(config) {
|
|
|
5209
5754
|
editor.off("selectionUpdate", handleSelectionUpdate);
|
|
5210
5755
|
};
|
|
5211
5756
|
}, [editor, hideWhenUnavailable]);
|
|
5212
|
-
const handleColorHighlight =
|
|
5757
|
+
const handleColorHighlight = React17.useCallback(() => {
|
|
5213
5758
|
if (!editor || !canColorHighlightState || !highlightColor || !label)
|
|
5214
5759
|
return false;
|
|
5215
5760
|
if (editor.state.storedMarks) {
|
|
@@ -5228,7 +5773,7 @@ function useColorHighlight(config) {
|
|
|
5228
5773
|
return success;
|
|
5229
5774
|
}, 0);
|
|
5230
5775
|
}, [canColorHighlightState, highlightColor, editor, label, onApplied]);
|
|
5231
|
-
const handleRemoveHighlight =
|
|
5776
|
+
const handleRemoveHighlight = React17.useCallback(() => {
|
|
5232
5777
|
const success = removeHighlight(editor);
|
|
5233
5778
|
if (success) {
|
|
5234
5779
|
onApplied == null ? void 0 : onApplied({ color: "", label: "Remove highlight" });
|
|
@@ -5260,7 +5805,7 @@ function useColorHighlight(config) {
|
|
|
5260
5805
|
}
|
|
5261
5806
|
|
|
5262
5807
|
// src/ui/color-highlight-button/color-highlight-button.tsx
|
|
5263
|
-
var
|
|
5808
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
5264
5809
|
var ColorHighlightButton = ({
|
|
5265
5810
|
editor: providedEditor,
|
|
5266
5811
|
highlightColor,
|
|
@@ -5289,7 +5834,7 @@ var ColorHighlightButton = ({
|
|
|
5289
5834
|
hideWhenUnavailable,
|
|
5290
5835
|
onApplied
|
|
5291
5836
|
});
|
|
5292
|
-
const handleClick = (0,
|
|
5837
|
+
const handleClick = (0, import_react42.useCallback)(
|
|
5293
5838
|
(event) => {
|
|
5294
5839
|
onClick == null ? void 0 : onClick(event);
|
|
5295
5840
|
if (event.defaultPrevented) return;
|
|
@@ -5297,7 +5842,7 @@ var ColorHighlightButton = ({
|
|
|
5297
5842
|
},
|
|
5298
5843
|
[handleColorHighlight, onClick]
|
|
5299
5844
|
);
|
|
5300
|
-
const buttonStyle = (0,
|
|
5845
|
+
const buttonStyle = (0, import_react42.useMemo)(
|
|
5301
5846
|
() => ({
|
|
5302
5847
|
...style,
|
|
5303
5848
|
"--highlight-color": highlightColor
|
|
@@ -5307,8 +5852,8 @@ var ColorHighlightButton = ({
|
|
|
5307
5852
|
if (!isVisible) {
|
|
5308
5853
|
return null;
|
|
5309
5854
|
}
|
|
5310
|
-
const styles = (0,
|
|
5311
|
-
return /* @__PURE__ */ (0,
|
|
5855
|
+
const styles = (0, import_theme8.colorHighlightButton)();
|
|
5856
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
5312
5857
|
import_toolbar6.ToolbarButton,
|
|
5313
5858
|
{
|
|
5314
5859
|
type: "button",
|
|
@@ -5327,15 +5872,15 @@ var ColorHighlightButton = ({
|
|
|
5327
5872
|
isIconOnly: true,
|
|
5328
5873
|
...buttonProps,
|
|
5329
5874
|
children: [
|
|
5330
|
-
/* @__PURE__ */ (0,
|
|
5875
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
5331
5876
|
"span",
|
|
5332
5877
|
{
|
|
5333
5878
|
"data-active-state": isActive ? "on" : "off",
|
|
5334
5879
|
className: styles.mark()
|
|
5335
5880
|
}
|
|
5336
5881
|
),
|
|
5337
|
-
children || /* @__PURE__ */ (0,
|
|
5338
|
-
/* @__PURE__ */ (0,
|
|
5882
|
+
children || /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
5883
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
5339
5884
|
"span",
|
|
5340
5885
|
{
|
|
5341
5886
|
style: { "--highlight-color": highlightColor }
|
|
@@ -5349,13 +5894,13 @@ var ColorHighlightButton = ({
|
|
|
5349
5894
|
};
|
|
5350
5895
|
|
|
5351
5896
|
// src/ui/color-highlight-popover/color-highlight-popover.tsx
|
|
5352
|
-
var
|
|
5897
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
5353
5898
|
var ColorHighlightPopoverButton = ({
|
|
5354
5899
|
className,
|
|
5355
5900
|
children,
|
|
5356
5901
|
...props
|
|
5357
|
-
}) => /* @__PURE__ */ (0,
|
|
5358
|
-
|
|
5902
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
5903
|
+
import_button11.IconButton,
|
|
5359
5904
|
{
|
|
5360
5905
|
type: "button",
|
|
5361
5906
|
className,
|
|
@@ -5366,7 +5911,7 @@ var ColorHighlightPopoverButton = ({
|
|
|
5366
5911
|
tooltip: "Highlight",
|
|
5367
5912
|
isIconOnly: !children,
|
|
5368
5913
|
...props,
|
|
5369
|
-
children: children != null ? children : /* @__PURE__ */ (0,
|
|
5914
|
+
children: children != null ? children : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_icons18.HighlighterIcon, {})
|
|
5370
5915
|
}
|
|
5371
5916
|
);
|
|
5372
5917
|
function ColorHighlightPopoverContent({
|
|
@@ -5380,8 +5925,8 @@ function ColorHighlightPopoverContent({
|
|
|
5380
5925
|
])
|
|
5381
5926
|
}) {
|
|
5382
5927
|
const { handleRemoveHighlight } = useColorHighlight({ editor });
|
|
5383
|
-
const containerRef = (0,
|
|
5384
|
-
const menuItems = (0,
|
|
5928
|
+
const containerRef = (0, import_react43.useRef)(null);
|
|
5929
|
+
const menuItems = (0, import_react43.useMemo)(
|
|
5385
5930
|
() => [...colors, { label: "Remove highlight", value: "none" }],
|
|
5386
5931
|
[colors]
|
|
5387
5932
|
);
|
|
@@ -5399,13 +5944,13 @@ function ColorHighlightPopoverContent({
|
|
|
5399
5944
|
},
|
|
5400
5945
|
autoSelectFirstItem: false
|
|
5401
5946
|
});
|
|
5402
|
-
return /* @__PURE__ */ (0,
|
|
5403
|
-
/* @__PURE__ */ (0,
|
|
5947
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { ref: containerRef, className: "flex gap-1 items-center", children: [
|
|
5948
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
5404
5949
|
"div",
|
|
5405
5950
|
{
|
|
5406
5951
|
className: "flex items-center gap-1 outline-none",
|
|
5407
5952
|
"data-orientation": "horizontal",
|
|
5408
|
-
children: colors.map((color, index) => /* @__PURE__ */ (0,
|
|
5953
|
+
children: colors.map((color, index) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
5409
5954
|
ColorHighlightButton,
|
|
5410
5955
|
{
|
|
5411
5956
|
editor,
|
|
@@ -5418,9 +5963,9 @@ function ColorHighlightPopoverContent({
|
|
|
5418
5963
|
))
|
|
5419
5964
|
}
|
|
5420
5965
|
),
|
|
5421
|
-
/* @__PURE__ */ (0,
|
|
5422
|
-
/* @__PURE__ */ (0,
|
|
5423
|
-
|
|
5966
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_toolbar7.ToolbarSeparator, { orientation: "vertical" }),
|
|
5967
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "tiptap-button-group", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
5968
|
+
import_button11.IconButton,
|
|
5424
5969
|
{
|
|
5425
5970
|
onClick: handleRemoveHighlight,
|
|
5426
5971
|
"aria-label": "Remove highlight",
|
|
@@ -5430,7 +5975,7 @@ function ColorHighlightPopoverContent({
|
|
|
5430
5975
|
variant: "ghost",
|
|
5431
5976
|
color: "default",
|
|
5432
5977
|
"data-highlighted": selectedIndex === colors.length,
|
|
5433
|
-
children: /* @__PURE__ */ (0,
|
|
5978
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_icons18.BanIcon, {})
|
|
5434
5979
|
}
|
|
5435
5980
|
) })
|
|
5436
5981
|
] });
|
|
@@ -5449,18 +5994,18 @@ function ColorHighlightPopover({
|
|
|
5449
5994
|
...props
|
|
5450
5995
|
}) {
|
|
5451
5996
|
const { editor } = useTiptapEditor(providedEditor);
|
|
5452
|
-
const [isOpen, setIsOpen] = (0,
|
|
5997
|
+
const [isOpen, setIsOpen] = (0, import_react43.useState)(false);
|
|
5453
5998
|
const { isVisible, canColorHighlight: canColorHighlight2, isActive, label } = useColorHighlight({
|
|
5454
5999
|
editor,
|
|
5455
6000
|
hideWhenUnavailable,
|
|
5456
6001
|
onApplied
|
|
5457
6002
|
});
|
|
5458
6003
|
if (!isVisible) return null;
|
|
5459
|
-
return /* @__PURE__ */ (0,
|
|
5460
|
-
/* @__PURE__ */ (0,
|
|
6004
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_popover2.Popover.Root, { open: isOpen, onOpenChange: setIsOpen, spacing: "dense", children: [
|
|
6005
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
5461
6006
|
import_popover2.Popover.Trigger,
|
|
5462
6007
|
{
|
|
5463
|
-
render: /* @__PURE__ */ (0,
|
|
6008
|
+
render: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
5464
6009
|
ColorHighlightPopoverButton,
|
|
5465
6010
|
{
|
|
5466
6011
|
disabled: !canColorHighlight2,
|
|
@@ -5474,26 +6019,26 @@ function ColorHighlightPopover({
|
|
|
5474
6019
|
)
|
|
5475
6020
|
}
|
|
5476
6021
|
),
|
|
5477
|
-
/* @__PURE__ */ (0,
|
|
6022
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_popover2.Popover.Content, { "aria-label": "Highlight colors", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ColorHighlightPopoverContent, { editor, colors }) })
|
|
5478
6023
|
] });
|
|
5479
6024
|
}
|
|
5480
6025
|
|
|
5481
6026
|
// src/ui/heading-dropdown-menu/index.tsx
|
|
5482
|
-
var
|
|
6027
|
+
var import_button13 = require("@kopexa/button");
|
|
5483
6028
|
var import_dropdown_menu = require("@kopexa/dropdown-menu");
|
|
5484
|
-
var
|
|
6029
|
+
var import_editor_utils12 = require("@kopexa/editor-utils");
|
|
5485
6030
|
var import_icons20 = require("@kopexa/icons");
|
|
5486
|
-
var
|
|
5487
|
-
var
|
|
6031
|
+
var import_react45 = require("@tiptap/react");
|
|
6032
|
+
var React19 = __toESM(require("react"));
|
|
5488
6033
|
|
|
5489
6034
|
// src/ui/heading-button/index.tsx
|
|
5490
|
-
var
|
|
5491
|
-
var
|
|
6035
|
+
var import_button12 = require("@kopexa/button");
|
|
6036
|
+
var import_editor_utils11 = require("@kopexa/editor-utils");
|
|
5492
6037
|
var import_icons19 = require("@kopexa/icons");
|
|
5493
|
-
var
|
|
6038
|
+
var React18 = __toESM(require("react"));
|
|
5494
6039
|
|
|
5495
6040
|
// src/ui/heading-button/utils.ts
|
|
5496
|
-
var
|
|
6041
|
+
var import_react44 = require("@tiptap/react");
|
|
5497
6042
|
var headingShortcutKeys = {
|
|
5498
6043
|
1: "Ctrl-Alt-1",
|
|
5499
6044
|
2: "Ctrl-Alt-2",
|
|
@@ -5534,7 +6079,7 @@ function shouldShowHeadingButton(params) {
|
|
|
5534
6079
|
return false;
|
|
5535
6080
|
}
|
|
5536
6081
|
if (hideWhenUnavailable) {
|
|
5537
|
-
if ((0,
|
|
6082
|
+
if ((0, import_react44.isNodeSelection)(editor.state.selection)) {
|
|
5538
6083
|
return false;
|
|
5539
6084
|
}
|
|
5540
6085
|
}
|
|
@@ -5545,7 +6090,7 @@ function getFormattedHeadingName(level) {
|
|
|
5545
6090
|
}
|
|
5546
6091
|
|
|
5547
6092
|
// src/ui/heading-button/index.tsx
|
|
5548
|
-
var
|
|
6093
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
5549
6094
|
var headingIcons = {
|
|
5550
6095
|
1: import_icons19.HeadingOneIcon,
|
|
5551
6096
|
2: import_icons19.HeadingTwoIcon,
|
|
@@ -5555,7 +6100,7 @@ var headingIcons = {
|
|
|
5555
6100
|
6: import_icons19.HeadingSixIcon
|
|
5556
6101
|
};
|
|
5557
6102
|
function useHeadingState(editor, level, disabled = false) {
|
|
5558
|
-
const headingInSchema = (0,
|
|
6103
|
+
const headingInSchema = (0, import_editor_utils11.isNodeInSchema)("heading", editor);
|
|
5559
6104
|
const isDisabled = isHeadingButtonDisabled(editor, level, disabled);
|
|
5560
6105
|
const isActive = isHeadingActive(editor, level);
|
|
5561
6106
|
const Icon = headingIcons[level];
|
|
@@ -5591,7 +6136,7 @@ var HeadingButton = ({
|
|
|
5591
6136
|
shortcutKey,
|
|
5592
6137
|
formattedName
|
|
5593
6138
|
} = useHeadingState(editor, level, disabled);
|
|
5594
|
-
const handleClick =
|
|
6139
|
+
const handleClick = React18.useCallback(
|
|
5595
6140
|
(e) => {
|
|
5596
6141
|
onClick == null ? void 0 : onClick(e);
|
|
5597
6142
|
if (!e.defaultPrevented && !isDisabled && editor) {
|
|
@@ -5600,7 +6145,7 @@ var HeadingButton = ({
|
|
|
5600
6145
|
},
|
|
5601
6146
|
[onClick, isDisabled, editor, level]
|
|
5602
6147
|
);
|
|
5603
|
-
const show =
|
|
6148
|
+
const show = React18.useMemo(() => {
|
|
5604
6149
|
return shouldShowHeadingButton({
|
|
5605
6150
|
editor,
|
|
5606
6151
|
level,
|
|
@@ -5611,8 +6156,8 @@ var HeadingButton = ({
|
|
|
5611
6156
|
if (!show || !editor || !editor.isEditable) {
|
|
5612
6157
|
return null;
|
|
5613
6158
|
}
|
|
5614
|
-
return /* @__PURE__ */ (0,
|
|
5615
|
-
|
|
6159
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
6160
|
+
import_button12.Button,
|
|
5616
6161
|
{
|
|
5617
6162
|
type: "button",
|
|
5618
6163
|
className: className.trim(),
|
|
@@ -5627,7 +6172,7 @@ var HeadingButton = ({
|
|
|
5627
6172
|
tooltip: formattedName,
|
|
5628
6173
|
shortcutKeys: shortcutKey,
|
|
5629
6174
|
onClick: handleClick,
|
|
5630
|
-
startContent: /* @__PURE__ */ (0,
|
|
6175
|
+
startContent: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Icon, {}),
|
|
5631
6176
|
...buttonProps,
|
|
5632
6177
|
ref,
|
|
5633
6178
|
children: children || text
|
|
@@ -5636,7 +6181,7 @@ var HeadingButton = ({
|
|
|
5636
6181
|
};
|
|
5637
6182
|
|
|
5638
6183
|
// src/ui/heading-dropdown-menu/index.tsx
|
|
5639
|
-
var
|
|
6184
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
5640
6185
|
function HeadingDropdownMenu({
|
|
5641
6186
|
editor: providedEditor,
|
|
5642
6187
|
levels = [1, 2, 3, 4, 5, 6],
|
|
@@ -5645,26 +6190,26 @@ function HeadingDropdownMenu({
|
|
|
5645
6190
|
...props
|
|
5646
6191
|
}) {
|
|
5647
6192
|
var _a;
|
|
5648
|
-
const [isOpen, setIsOpen] =
|
|
6193
|
+
const [isOpen, setIsOpen] = React19.useState(false);
|
|
5649
6194
|
const { editor } = useTiptapEditor(providedEditor);
|
|
5650
|
-
const headingInSchema = (0,
|
|
5651
|
-
const handleOnOpenChange =
|
|
6195
|
+
const headingInSchema = (0, import_editor_utils12.isNodeInSchema)("heading", editor);
|
|
6196
|
+
const handleOnOpenChange = React19.useCallback(
|
|
5652
6197
|
(open) => {
|
|
5653
6198
|
setIsOpen(open);
|
|
5654
6199
|
onOpenChange == null ? void 0 : onOpenChange(open);
|
|
5655
6200
|
},
|
|
5656
6201
|
[onOpenChange]
|
|
5657
6202
|
);
|
|
5658
|
-
const getActiveIcon =
|
|
5659
|
-
if (!editor) return /* @__PURE__ */ (0,
|
|
6203
|
+
const getActiveIcon = React19.useCallback(() => {
|
|
6204
|
+
if (!editor) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_icons20.HeadingIcon, {});
|
|
5660
6205
|
const activeLevel = levels.find(
|
|
5661
6206
|
(level) => editor.isActive("heading", { level })
|
|
5662
6207
|
);
|
|
5663
|
-
if (!activeLevel) return /* @__PURE__ */ (0,
|
|
6208
|
+
if (!activeLevel) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_icons20.HeadingIcon, {});
|
|
5664
6209
|
const ActiveIcon = headingIcons[activeLevel];
|
|
5665
|
-
return /* @__PURE__ */ (0,
|
|
6210
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ActiveIcon, {});
|
|
5666
6211
|
}, [editor, levels]);
|
|
5667
|
-
const canToggleAnyHeading =
|
|
6212
|
+
const canToggleAnyHeading = React19.useCallback(() => {
|
|
5668
6213
|
if (!editor) return false;
|
|
5669
6214
|
return levels.some(
|
|
5670
6215
|
(level) => editor.can().toggleNode("heading", "paragraph", { level })
|
|
@@ -5672,12 +6217,12 @@ function HeadingDropdownMenu({
|
|
|
5672
6217
|
}, [editor, levels]);
|
|
5673
6218
|
const isDisabled = !canToggleAnyHeading();
|
|
5674
6219
|
const isAnyHeadingActive = (_a = editor == null ? void 0 : editor.isActive("heading")) != null ? _a : false;
|
|
5675
|
-
const show =
|
|
6220
|
+
const show = React19.useMemo(() => {
|
|
5676
6221
|
if (!headingInSchema || !editor) {
|
|
5677
6222
|
return false;
|
|
5678
6223
|
}
|
|
5679
6224
|
if (hideWhenUnavailable) {
|
|
5680
|
-
if ((0,
|
|
6225
|
+
if ((0, import_react45.isNodeSelection)(editor.state.selection) || !canToggleAnyHeading()) {
|
|
5681
6226
|
return false;
|
|
5682
6227
|
}
|
|
5683
6228
|
}
|
|
@@ -5686,9 +6231,9 @@ function HeadingDropdownMenu({
|
|
|
5686
6231
|
if (!show || !editor || !editor.isEditable) {
|
|
5687
6232
|
return null;
|
|
5688
6233
|
}
|
|
5689
|
-
return /* @__PURE__ */ (0,
|
|
5690
|
-
/* @__PURE__ */ (0,
|
|
5691
|
-
|
|
6234
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_dropdown_menu.DropdownMenu.Root, { open: isOpen, onOpenChange: handleOnOpenChange, children: [
|
|
6235
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_dropdown_menu.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
6236
|
+
import_button13.Button,
|
|
5692
6237
|
{
|
|
5693
6238
|
type: "button",
|
|
5694
6239
|
disabled: isDisabled,
|
|
@@ -5700,12 +6245,12 @@ function HeadingDropdownMenu({
|
|
|
5700
6245
|
"aria-label": "Format text as heading",
|
|
5701
6246
|
"aria-pressed": isAnyHeadingActive,
|
|
5702
6247
|
tooltip: "Heading",
|
|
5703
|
-
endContent: /* @__PURE__ */ (0,
|
|
6248
|
+
endContent: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_icons20.ChevronDownIcon, {}),
|
|
5704
6249
|
...props,
|
|
5705
6250
|
children: getActiveIcon()
|
|
5706
6251
|
}
|
|
5707
6252
|
) }),
|
|
5708
|
-
/* @__PURE__ */ (0,
|
|
6253
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_dropdown_menu.DropdownMenu.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_dropdown_menu.DropdownMenu.Group, { children: levels.map((level) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_dropdown_menu.DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5709
6254
|
HeadingButton,
|
|
5710
6255
|
{
|
|
5711
6256
|
editor,
|
|
@@ -5720,20 +6265,20 @@ function HeadingDropdownMenu({
|
|
|
5720
6265
|
}
|
|
5721
6266
|
|
|
5722
6267
|
// src/ui/list-dropdown-menu/index.tsx
|
|
5723
|
-
var
|
|
6268
|
+
var import_button15 = require("@kopexa/button");
|
|
5724
6269
|
var import_dropdown_menu2 = require("@kopexa/dropdown-menu");
|
|
5725
|
-
var
|
|
6270
|
+
var import_editor_utils14 = require("@kopexa/editor-utils");
|
|
5726
6271
|
var import_icons22 = require("@kopexa/icons");
|
|
5727
|
-
var
|
|
5728
|
-
var
|
|
6272
|
+
var import_react48 = require("@tiptap/react");
|
|
6273
|
+
var import_react49 = require("react");
|
|
5729
6274
|
|
|
5730
6275
|
// src/ui/list-button/index.tsx
|
|
5731
|
-
var
|
|
5732
|
-
var
|
|
6276
|
+
var import_button14 = require("@kopexa/button");
|
|
6277
|
+
var import_editor_utils13 = require("@kopexa/editor-utils");
|
|
5733
6278
|
var import_icons21 = require("@kopexa/icons");
|
|
5734
|
-
var
|
|
5735
|
-
var
|
|
5736
|
-
var
|
|
6279
|
+
var import_react46 = require("@tiptap/react");
|
|
6280
|
+
var import_react47 = require("react");
|
|
6281
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
5737
6282
|
var listOptions = [
|
|
5738
6283
|
{
|
|
5739
6284
|
label: "Bullet List",
|
|
@@ -5807,14 +6352,14 @@ function shouldShowListButton(params) {
|
|
|
5807
6352
|
return false;
|
|
5808
6353
|
}
|
|
5809
6354
|
if (hideWhenUnavailable) {
|
|
5810
|
-
if ((0,
|
|
6355
|
+
if ((0, import_react46.isNodeSelection)(editor.state.selection) || !canToggleList(editor, type)) {
|
|
5811
6356
|
return false;
|
|
5812
6357
|
}
|
|
5813
6358
|
}
|
|
5814
6359
|
return true;
|
|
5815
6360
|
}
|
|
5816
6361
|
function useListState(editor, type) {
|
|
5817
|
-
const listInSchema = (0,
|
|
6362
|
+
const listInSchema = (0, import_editor_utils13.isNodeInSchema)(type, editor);
|
|
5818
6363
|
const listOption = getListOption(type);
|
|
5819
6364
|
const isActive = isListActive(editor, type);
|
|
5820
6365
|
const shortcutKey = listShortcutKeys[type];
|
|
@@ -5842,7 +6387,7 @@ var ListButton = ({
|
|
|
5842
6387
|
type
|
|
5843
6388
|
);
|
|
5844
6389
|
const Icon = (listOption == null ? void 0 : listOption.icon) || import_icons21.ListIcon;
|
|
5845
|
-
const handleClick = (0,
|
|
6390
|
+
const handleClick = (0, import_react47.useCallback)(
|
|
5846
6391
|
(e) => {
|
|
5847
6392
|
onClick == null ? void 0 : onClick(e);
|
|
5848
6393
|
if (!e.defaultPrevented && editor) {
|
|
@@ -5851,7 +6396,7 @@ var ListButton = ({
|
|
|
5851
6396
|
},
|
|
5852
6397
|
[onClick, editor, type]
|
|
5853
6398
|
);
|
|
5854
|
-
const show = (0,
|
|
6399
|
+
const show = (0, import_react47.useMemo)(() => {
|
|
5855
6400
|
return shouldShowListButton({
|
|
5856
6401
|
editor,
|
|
5857
6402
|
type,
|
|
@@ -5862,8 +6407,8 @@ var ListButton = ({
|
|
|
5862
6407
|
if (!show || !editor || !editor.isEditable) {
|
|
5863
6408
|
return null;
|
|
5864
6409
|
}
|
|
5865
|
-
return /* @__PURE__ */ (0,
|
|
5866
|
-
|
|
6410
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
6411
|
+
import_button14.Button,
|
|
5867
6412
|
{
|
|
5868
6413
|
type: "button",
|
|
5869
6414
|
className: className.trim(),
|
|
@@ -5876,7 +6421,7 @@ var ListButton = ({
|
|
|
5876
6421
|
tooltip: (listOption == null ? void 0 : listOption.label) || type,
|
|
5877
6422
|
shortcutKeys: shortcutKey,
|
|
5878
6423
|
onClick: handleClick,
|
|
5879
|
-
startContent: /* @__PURE__ */ (0,
|
|
6424
|
+
startContent: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Icon, {}),
|
|
5880
6425
|
...buttonProps,
|
|
5881
6426
|
ref,
|
|
5882
6427
|
children: children || text
|
|
@@ -5885,7 +6430,7 @@ var ListButton = ({
|
|
|
5885
6430
|
};
|
|
5886
6431
|
|
|
5887
6432
|
// src/ui/list-dropdown-menu/index.tsx
|
|
5888
|
-
var
|
|
6433
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
5889
6434
|
function canToggleAnyList(editor, listTypes) {
|
|
5890
6435
|
if (!editor) return false;
|
|
5891
6436
|
return listTypes.some((type) => canToggleList(editor, type));
|
|
@@ -5905,24 +6450,24 @@ function shouldShowListDropdown(params) {
|
|
|
5905
6450
|
return false;
|
|
5906
6451
|
}
|
|
5907
6452
|
if (hideWhenUnavailable) {
|
|
5908
|
-
if ((0,
|
|
6453
|
+
if ((0, import_react48.isNodeSelection)(editor.state.selection) || !canToggleAny) {
|
|
5909
6454
|
return false;
|
|
5910
6455
|
}
|
|
5911
6456
|
}
|
|
5912
6457
|
return true;
|
|
5913
6458
|
}
|
|
5914
6459
|
function useListDropdownState(editor, availableTypes) {
|
|
5915
|
-
const [isOpen, setIsOpen] = (0,
|
|
6460
|
+
const [isOpen, setIsOpen] = (0, import_react49.useState)(false);
|
|
5916
6461
|
const listInSchema = availableTypes.some(
|
|
5917
|
-
(type) => (0,
|
|
6462
|
+
(type) => (0, import_editor_utils14.isNodeInSchema)(type, editor)
|
|
5918
6463
|
);
|
|
5919
|
-
const filteredLists = (0,
|
|
6464
|
+
const filteredLists = (0, import_react49.useMemo)(
|
|
5920
6465
|
() => getFilteredListOptions(availableTypes),
|
|
5921
6466
|
[availableTypes]
|
|
5922
6467
|
);
|
|
5923
6468
|
const canToggleAny = canToggleAnyList(editor, availableTypes);
|
|
5924
6469
|
const isAnyActive = isAnyListActive(editor, availableTypes);
|
|
5925
|
-
const handleOpenChange = (0,
|
|
6470
|
+
const handleOpenChange = (0, import_react49.useCallback)(
|
|
5926
6471
|
(open, callback) => {
|
|
5927
6472
|
setIsOpen(open);
|
|
5928
6473
|
callback == null ? void 0 : callback(open);
|
|
@@ -5940,11 +6485,11 @@ function useListDropdownState(editor, availableTypes) {
|
|
|
5940
6485
|
};
|
|
5941
6486
|
}
|
|
5942
6487
|
function useActiveListIcon(editor, filteredLists) {
|
|
5943
|
-
return (0,
|
|
6488
|
+
return (0, import_react49.useCallback)(() => {
|
|
5944
6489
|
const activeOption = filteredLists.find(
|
|
5945
6490
|
(option) => isListActive(editor, option.type)
|
|
5946
6491
|
);
|
|
5947
|
-
return activeOption ? /* @__PURE__ */ (0,
|
|
6492
|
+
return activeOption ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(activeOption.icon, {}) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_icons22.ListIcon, {});
|
|
5948
6493
|
}, [editor, filteredLists]);
|
|
5949
6494
|
}
|
|
5950
6495
|
function ListDropdownMenu({
|
|
@@ -5964,7 +6509,7 @@ function ListDropdownMenu({
|
|
|
5964
6509
|
handleOpenChange
|
|
5965
6510
|
} = useListDropdownState(editor, types);
|
|
5966
6511
|
const getActiveIcon = useActiveListIcon(editor, filteredLists);
|
|
5967
|
-
const show = (0,
|
|
6512
|
+
const show = (0, import_react49.useMemo)(() => {
|
|
5968
6513
|
return shouldShowListDropdown({
|
|
5969
6514
|
editor,
|
|
5970
6515
|
listTypes: types,
|
|
@@ -5973,16 +6518,16 @@ function ListDropdownMenu({
|
|
|
5973
6518
|
canToggleAny
|
|
5974
6519
|
});
|
|
5975
6520
|
}, [editor, types, hideWhenUnavailable, listInSchema, canToggleAny]);
|
|
5976
|
-
const handleOnOpenChange = (0,
|
|
6521
|
+
const handleOnOpenChange = (0, import_react49.useCallback)(
|
|
5977
6522
|
(open) => handleOpenChange(open, onOpenChange),
|
|
5978
6523
|
[handleOpenChange, onOpenChange]
|
|
5979
6524
|
);
|
|
5980
6525
|
if (!show || !editor || !editor.isEditable) {
|
|
5981
6526
|
return null;
|
|
5982
6527
|
}
|
|
5983
|
-
return /* @__PURE__ */ (0,
|
|
5984
|
-
/* @__PURE__ */ (0,
|
|
5985
|
-
|
|
6528
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_dropdown_menu2.DropdownMenu.Root, { open: isOpen, onOpenChange: handleOnOpenChange, children: [
|
|
6529
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_dropdown_menu2.DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6530
|
+
import_button15.Button,
|
|
5986
6531
|
{
|
|
5987
6532
|
type: "button",
|
|
5988
6533
|
variant: "ghost",
|
|
@@ -5991,12 +6536,12 @@ function ListDropdownMenu({
|
|
|
5991
6536
|
tabIndex: -1,
|
|
5992
6537
|
"aria-label": "List options",
|
|
5993
6538
|
tooltip: "List",
|
|
5994
|
-
endContent: /* @__PURE__ */ (0,
|
|
6539
|
+
endContent: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_icons22.ChevronDownIcon, {}),
|
|
5995
6540
|
...props,
|
|
5996
6541
|
children: getActiveIcon()
|
|
5997
6542
|
}
|
|
5998
6543
|
) }),
|
|
5999
|
-
/* @__PURE__ */ (0,
|
|
6544
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_dropdown_menu2.DropdownMenu.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_dropdown_menu2.DropdownMenu.Group, { children: filteredLists.map((option) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_dropdown_menu2.DropdownMenu.Item, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
6000
6545
|
ListButton,
|
|
6001
6546
|
{
|
|
6002
6547
|
editor,
|
|
@@ -6013,8 +6558,8 @@ function ListDropdownMenu({
|
|
|
6013
6558
|
|
|
6014
6559
|
// src/ui/table-button/index.tsx
|
|
6015
6560
|
var import_toolbar8 = require("@kopexa/toolbar");
|
|
6016
|
-
var
|
|
6017
|
-
var
|
|
6561
|
+
var import_react50 = require("react");
|
|
6562
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
6018
6563
|
var TableButton = ({
|
|
6019
6564
|
editor: providedEditor,
|
|
6020
6565
|
text,
|
|
@@ -6038,7 +6583,7 @@ var TableButton = ({
|
|
|
6038
6583
|
hideWhenUnavailable,
|
|
6039
6584
|
onToggled
|
|
6040
6585
|
});
|
|
6041
|
-
const handleClick = (0,
|
|
6586
|
+
const handleClick = (0, import_react50.useCallback)(
|
|
6042
6587
|
(event) => {
|
|
6043
6588
|
onClick == null ? void 0 : onClick(event);
|
|
6044
6589
|
if (event.defaultPrevented) return;
|
|
@@ -6049,7 +6594,7 @@ var TableButton = ({
|
|
|
6049
6594
|
if (!isVisible) {
|
|
6050
6595
|
return null;
|
|
6051
6596
|
}
|
|
6052
|
-
return /* @__PURE__ */ (0,
|
|
6597
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
6053
6598
|
import_toolbar8.ToolbarButton,
|
|
6054
6599
|
{
|
|
6055
6600
|
type: "button",
|
|
@@ -6065,22 +6610,22 @@ var TableButton = ({
|
|
|
6065
6610
|
onClick: handleClick,
|
|
6066
6611
|
isIconOnly: !text && !children,
|
|
6067
6612
|
...buttonProps,
|
|
6068
|
-
children: children || /* @__PURE__ */ (0,
|
|
6069
|
-
/* @__PURE__ */ (0,
|
|
6070
|
-
text && /* @__PURE__ */ (0,
|
|
6613
|
+
children: children || /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
6614
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Icon, {}),
|
|
6615
|
+
text && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { children: text })
|
|
6071
6616
|
] })
|
|
6072
6617
|
}
|
|
6073
6618
|
);
|
|
6074
6619
|
};
|
|
6075
6620
|
|
|
6076
6621
|
// src/ui/text-align-button/text-align-button.tsx
|
|
6077
|
-
var
|
|
6078
|
-
var
|
|
6622
|
+
var import_button16 = require("@kopexa/button");
|
|
6623
|
+
var import_react52 = require("react");
|
|
6079
6624
|
|
|
6080
6625
|
// src/ui/text-align-button/use-text-align.ts
|
|
6081
|
-
var
|
|
6626
|
+
var import_editor_utils15 = require("@kopexa/editor-utils");
|
|
6082
6627
|
var import_icons23 = require("@kopexa/icons");
|
|
6083
|
-
var
|
|
6628
|
+
var import_react51 = require("react");
|
|
6084
6629
|
var TEXT_ALIGN_SHORTCUT_KEYS = {
|
|
6085
6630
|
left: "mod+shift+l",
|
|
6086
6631
|
center: "mod+shift+e",
|
|
@@ -6101,7 +6646,7 @@ var textAlignLabels = {
|
|
|
6101
6646
|
};
|
|
6102
6647
|
function canSetTextAlign(editor, align) {
|
|
6103
6648
|
if (!editor || !editor.isEditable) return false;
|
|
6104
|
-
if (!(0,
|
|
6649
|
+
if (!(0, import_editor_utils15.isExtensionAvailable)(editor, "textAlign") || (0, import_editor_utils15.isNodeTypeSelected)(editor, ["image"]))
|
|
6105
6650
|
return false;
|
|
6106
6651
|
return editor.can().setTextAlign(align);
|
|
6107
6652
|
}
|
|
@@ -6124,7 +6669,7 @@ function setTextAlign(editor, align) {
|
|
|
6124
6669
|
function shouldShowButton5(props) {
|
|
6125
6670
|
const { editor, hideWhenUnavailable, align } = props;
|
|
6126
6671
|
if (!editor || !editor.isEditable) return false;
|
|
6127
|
-
if (!(0,
|
|
6672
|
+
if (!(0, import_editor_utils15.isExtensionAvailable)(editor, "textAlign")) return false;
|
|
6128
6673
|
if (hideWhenUnavailable && !editor.isActive("code")) {
|
|
6129
6674
|
return canSetTextAlign(editor, align);
|
|
6130
6675
|
}
|
|
@@ -6138,10 +6683,10 @@ function useTextAlign(config) {
|
|
|
6138
6683
|
onAligned
|
|
6139
6684
|
} = config;
|
|
6140
6685
|
const { editor } = useTiptapEditor(providedEditor);
|
|
6141
|
-
const [isVisible, setIsVisible] = (0,
|
|
6686
|
+
const [isVisible, setIsVisible] = (0, import_react51.useState)(true);
|
|
6142
6687
|
const canAlign = canSetTextAlign(editor, align);
|
|
6143
6688
|
const isActive = isTextAlignActive(editor, align);
|
|
6144
|
-
(0,
|
|
6689
|
+
(0, import_react51.useEffect)(() => {
|
|
6145
6690
|
if (!editor) return;
|
|
6146
6691
|
const handleSelectionUpdate = () => {
|
|
6147
6692
|
setIsVisible(shouldShowButton5({ editor, align, hideWhenUnavailable }));
|
|
@@ -6152,7 +6697,7 @@ function useTextAlign(config) {
|
|
|
6152
6697
|
editor.off("selectionUpdate", handleSelectionUpdate);
|
|
6153
6698
|
};
|
|
6154
6699
|
}, [editor, hideWhenUnavailable, align]);
|
|
6155
|
-
const handleTextAlign = (0,
|
|
6700
|
+
const handleTextAlign = (0, import_react51.useCallback)(() => {
|
|
6156
6701
|
if (!editor) return false;
|
|
6157
6702
|
const success = setTextAlign(editor, align);
|
|
6158
6703
|
if (success) {
|
|
@@ -6172,7 +6717,7 @@ function useTextAlign(config) {
|
|
|
6172
6717
|
}
|
|
6173
6718
|
|
|
6174
6719
|
// src/ui/text-align-button/text-align-button.tsx
|
|
6175
|
-
var
|
|
6720
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
6176
6721
|
var TextAlignButton = ({
|
|
6177
6722
|
editor: providedEditor,
|
|
6178
6723
|
align,
|
|
@@ -6199,7 +6744,7 @@ var TextAlignButton = ({
|
|
|
6199
6744
|
hideWhenUnavailable,
|
|
6200
6745
|
onAligned
|
|
6201
6746
|
});
|
|
6202
|
-
const handleClick = (0,
|
|
6747
|
+
const handleClick = (0, import_react52.useCallback)(
|
|
6203
6748
|
(e) => {
|
|
6204
6749
|
onClick == null ? void 0 : onClick(e);
|
|
6205
6750
|
if (e.defaultPrevented) return;
|
|
@@ -6210,8 +6755,8 @@ var TextAlignButton = ({
|
|
|
6210
6755
|
if (!isVisible) {
|
|
6211
6756
|
return null;
|
|
6212
6757
|
}
|
|
6213
|
-
return /* @__PURE__ */ (0,
|
|
6214
|
-
|
|
6758
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
6759
|
+
import_button16.IconButton,
|
|
6215
6760
|
{
|
|
6216
6761
|
type: "button",
|
|
6217
6762
|
disabled: canAlign,
|
|
@@ -6226,19 +6771,19 @@ var TextAlignButton = ({
|
|
|
6226
6771
|
shortcutKeys,
|
|
6227
6772
|
onClick: handleClick,
|
|
6228
6773
|
...buttonProps,
|
|
6229
|
-
children: /* @__PURE__ */ (0,
|
|
6774
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Icon, {})
|
|
6230
6775
|
}
|
|
6231
6776
|
);
|
|
6232
6777
|
};
|
|
6233
6778
|
|
|
6234
6779
|
// src/ui/undo-redo-button/undo-redo-button.tsx
|
|
6235
6780
|
var import_toolbar9 = require("@kopexa/toolbar");
|
|
6236
|
-
var
|
|
6781
|
+
var import_react54 = require("react");
|
|
6237
6782
|
|
|
6238
6783
|
// src/ui/undo-redo-button/use-undo-redo.ts
|
|
6239
|
-
var
|
|
6784
|
+
var import_editor_utils16 = require("@kopexa/editor-utils");
|
|
6240
6785
|
var import_icons24 = require("@kopexa/icons");
|
|
6241
|
-
var
|
|
6786
|
+
var import_react53 = require("react");
|
|
6242
6787
|
var UNDO_REDO_SHORTCUT_KEYS = {
|
|
6243
6788
|
undo: "mod+z",
|
|
6244
6789
|
redo: "mod+shift+z"
|
|
@@ -6253,7 +6798,7 @@ var historyIcons = {
|
|
|
6253
6798
|
};
|
|
6254
6799
|
function canExecuteUndoRedoAction(editor, action) {
|
|
6255
6800
|
if (!editor || !editor.isEditable) return false;
|
|
6256
|
-
if ((0,
|
|
6801
|
+
if ((0, import_editor_utils16.isNodeTypeSelected)(editor, ["image"])) return false;
|
|
6257
6802
|
return action === "undo" ? editor.can().undo() : editor.can().redo();
|
|
6258
6803
|
}
|
|
6259
6804
|
function executeUndoRedoAction(editor, action) {
|
|
@@ -6278,9 +6823,9 @@ function useUndoRedo(config) {
|
|
|
6278
6823
|
onExecuted
|
|
6279
6824
|
} = config;
|
|
6280
6825
|
const { editor } = useTiptapEditor(providedEditor);
|
|
6281
|
-
const [isVisible, setIsVisible] = (0,
|
|
6826
|
+
const [isVisible, setIsVisible] = (0, import_react53.useState)(true);
|
|
6282
6827
|
const canExecute = canExecuteUndoRedoAction(editor, action);
|
|
6283
|
-
(0,
|
|
6828
|
+
(0, import_react53.useEffect)(() => {
|
|
6284
6829
|
if (!editor) return;
|
|
6285
6830
|
const handleUpdate = () => {
|
|
6286
6831
|
setIsVisible(shouldShowButton6({ editor, hideWhenUnavailable, action }));
|
|
@@ -6291,7 +6836,7 @@ function useUndoRedo(config) {
|
|
|
6291
6836
|
editor.off("transaction", handleUpdate);
|
|
6292
6837
|
};
|
|
6293
6838
|
}, [editor, hideWhenUnavailable, action]);
|
|
6294
|
-
const handleAction = (0,
|
|
6839
|
+
const handleAction = (0, import_react53.useCallback)(() => {
|
|
6295
6840
|
if (!editor) return false;
|
|
6296
6841
|
const success = executeUndoRedoAction(editor, action);
|
|
6297
6842
|
if (success) {
|
|
@@ -6310,7 +6855,7 @@ function useUndoRedo(config) {
|
|
|
6310
6855
|
}
|
|
6311
6856
|
|
|
6312
6857
|
// src/ui/undo-redo-button/undo-redo-button.tsx
|
|
6313
|
-
var
|
|
6858
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
6314
6859
|
var UndoRedoButton = ({
|
|
6315
6860
|
editor: providedEditor,
|
|
6316
6861
|
action,
|
|
@@ -6329,7 +6874,7 @@ var UndoRedoButton = ({
|
|
|
6329
6874
|
hideWhenUnavailable,
|
|
6330
6875
|
onExecuted
|
|
6331
6876
|
});
|
|
6332
|
-
const handleClick = (0,
|
|
6877
|
+
const handleClick = (0, import_react54.useCallback)(
|
|
6333
6878
|
(event) => {
|
|
6334
6879
|
onClick == null ? void 0 : onClick(event);
|
|
6335
6880
|
if (event.defaultPrevented) return;
|
|
@@ -6340,7 +6885,7 @@ var UndoRedoButton = ({
|
|
|
6340
6885
|
if (!isVisible) {
|
|
6341
6886
|
return null;
|
|
6342
6887
|
}
|
|
6343
|
-
return /* @__PURE__ */ (0,
|
|
6888
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
6344
6889
|
import_toolbar9.ToolbarButton,
|
|
6345
6890
|
{
|
|
6346
6891
|
type: "button",
|
|
@@ -6355,13 +6900,13 @@ var UndoRedoButton = ({
|
|
|
6355
6900
|
onClick: handleClick,
|
|
6356
6901
|
isIconOnly: true,
|
|
6357
6902
|
...buttonProps,
|
|
6358
|
-
children: /* @__PURE__ */ (0,
|
|
6903
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Icon, {})
|
|
6359
6904
|
}
|
|
6360
6905
|
);
|
|
6361
6906
|
};
|
|
6362
6907
|
|
|
6363
6908
|
// src/presets/basic/editor-header.tsx
|
|
6364
|
-
var
|
|
6909
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
6365
6910
|
var EditorHeader = ({
|
|
6366
6911
|
editor: providedEditor,
|
|
6367
6912
|
variant
|
|
@@ -6371,7 +6916,7 @@ var EditorHeader = ({
|
|
|
6371
6916
|
const isMobile = (0, import_use_is_mobile2.useIsMobile)();
|
|
6372
6917
|
const windowSize = useWindowSize();
|
|
6373
6918
|
const { styles } = useEditorUIContext();
|
|
6374
|
-
const toolbarRef = (0,
|
|
6919
|
+
const toolbarRef = (0, import_react55.useRef)(null);
|
|
6375
6920
|
const bodyRect = useCursorVisibility({
|
|
6376
6921
|
editor,
|
|
6377
6922
|
overlayHeight: (_b = (_a = toolbarRef.current) == null ? void 0 : _a.getBoundingClientRect().height) != null ? _b : 0
|
|
@@ -6380,7 +6925,7 @@ var EditorHeader = ({
|
|
|
6380
6925
|
return null;
|
|
6381
6926
|
}
|
|
6382
6927
|
const ToolbarContent = variant === "comment" ? CommentToolbarContent : variant === "field" ? FieldToolbarContent : MainToolbarContent;
|
|
6383
|
-
return /* @__PURE__ */ (0,
|
|
6928
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: styles.toolbarContainer(), "data-slot": "editor-toolbar", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6384
6929
|
import_toolbar10.Toolbar,
|
|
6385
6930
|
{
|
|
6386
6931
|
sticky: true,
|
|
@@ -6390,54 +6935,54 @@ var EditorHeader = ({
|
|
|
6390
6935
|
bottom: `calc(100% - ${windowSize.height - bodyRect.y}px)`
|
|
6391
6936
|
} : {},
|
|
6392
6937
|
className: styles.toolbar(),
|
|
6393
|
-
children: /* @__PURE__ */ (0,
|
|
6938
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ToolbarContent, {})
|
|
6394
6939
|
}
|
|
6395
6940
|
) });
|
|
6396
6941
|
};
|
|
6397
|
-
var MainToolbarContent = () => /* @__PURE__ */ (0,
|
|
6398
|
-
/* @__PURE__ */ (0,
|
|
6399
|
-
/* @__PURE__ */ (0,
|
|
6400
|
-
/* @__PURE__ */ (0,
|
|
6942
|
+
var MainToolbarContent = () => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_jsx_runtime31.Fragment, { children: [
|
|
6943
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_toolbar10.ToolbarGroup, { children: [
|
|
6944
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(UndoRedoButton, { action: "undo" }),
|
|
6945
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(UndoRedoButton, { action: "redo" })
|
|
6401
6946
|
] }),
|
|
6402
|
-
/* @__PURE__ */ (0,
|
|
6403
|
-
/* @__PURE__ */ (0,
|
|
6404
|
-
/* @__PURE__ */ (0,
|
|
6405
|
-
/* @__PURE__ */ (0,
|
|
6406
|
-
/* @__PURE__ */ (0,
|
|
6407
|
-
/* @__PURE__ */ (0,
|
|
6947
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_toolbar10.ToolbarSeparator, {}),
|
|
6948
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_toolbar10.ToolbarGroup, { children: [
|
|
6949
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(HeadingDropdownMenu, { levels: [1, 2, 3, 4] }),
|
|
6950
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ListDropdownMenu, { types: ["bulletList", "orderedList", "taskList"] }),
|
|
6951
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(BlockquoteButton, {}),
|
|
6952
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(CodeBlockButton, {})
|
|
6408
6953
|
] }),
|
|
6409
|
-
/* @__PURE__ */ (0,
|
|
6410
|
-
/* @__PURE__ */ (0,
|
|
6411
|
-
/* @__PURE__ */ (0,
|
|
6412
|
-
/* @__PURE__ */ (0,
|
|
6413
|
-
/* @__PURE__ */ (0,
|
|
6414
|
-
/* @__PURE__ */ (0,
|
|
6415
|
-
/* @__PURE__ */ (0,
|
|
6416
|
-
/* @__PURE__ */ (0,
|
|
6417
|
-
/* @__PURE__ */ (0,
|
|
6954
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_toolbar10.ToolbarSeparator, {}),
|
|
6955
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_toolbar10.ToolbarGroup, { children: [
|
|
6956
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MarkButton, { type: "bold" }),
|
|
6957
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MarkButton, { type: "italic" }),
|
|
6958
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MarkButton, { type: "strike" }),
|
|
6959
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MarkButton, { type: "code" }),
|
|
6960
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MarkButton, { type: "underline" }),
|
|
6961
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ColorHighlightPopover, {}),
|
|
6962
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(LinkPopover, {})
|
|
6418
6963
|
] }),
|
|
6419
|
-
/* @__PURE__ */ (0,
|
|
6420
|
-
/* @__PURE__ */ (0,
|
|
6421
|
-
/* @__PURE__ */ (0,
|
|
6964
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_toolbar10.ToolbarSeparator, {}),
|
|
6965
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_toolbar10.ToolbarGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TableButton, {}) }),
|
|
6966
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MoreOptions, { hideWhenUnavailable: true })
|
|
6422
6967
|
] });
|
|
6423
|
-
var CommentToolbarContent = () => /* @__PURE__ */ (0,
|
|
6424
|
-
/* @__PURE__ */ (0,
|
|
6425
|
-
/* @__PURE__ */ (0,
|
|
6426
|
-
/* @__PURE__ */ (0,
|
|
6427
|
-
/* @__PURE__ */ (0,
|
|
6428
|
-
/* @__PURE__ */ (0,
|
|
6968
|
+
var CommentToolbarContent = () => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_jsx_runtime31.Fragment, { children: [
|
|
6969
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_toolbar10.ToolbarGroup, { children: [
|
|
6970
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MarkButton, { type: "bold" }),
|
|
6971
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MarkButton, { type: "italic" }),
|
|
6972
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MarkButton, { type: "strike" }),
|
|
6973
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MarkButton, { type: "code" })
|
|
6429
6974
|
] }),
|
|
6430
|
-
/* @__PURE__ */ (0,
|
|
6431
|
-
/* @__PURE__ */ (0,
|
|
6432
|
-
/* @__PURE__ */ (0,
|
|
6433
|
-
/* @__PURE__ */ (0,
|
|
6975
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_toolbar10.ToolbarSeparator, {}),
|
|
6976
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_toolbar10.ToolbarGroup, { children: [
|
|
6977
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(LinkPopover, {}),
|
|
6978
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ListDropdownMenu, { types: ["bulletList", "orderedList"] })
|
|
6434
6979
|
] })
|
|
6435
6980
|
] });
|
|
6436
|
-
var FieldToolbarContent = () => /* @__PURE__ */ (0,
|
|
6437
|
-
/* @__PURE__ */ (0,
|
|
6438
|
-
/* @__PURE__ */ (0,
|
|
6439
|
-
/* @__PURE__ */ (0,
|
|
6440
|
-
/* @__PURE__ */ (0,
|
|
6981
|
+
var FieldToolbarContent = () => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_toolbar10.ToolbarGroup, { children: [
|
|
6982
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MarkButton, { type: "bold" }),
|
|
6983
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MarkButton, { type: "italic" }),
|
|
6984
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MarkButton, { type: "strike" }),
|
|
6985
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(LinkPopover, {})
|
|
6441
6986
|
] });
|
|
6442
6987
|
function MoreOptions({
|
|
6443
6988
|
editor: providedEditor,
|
|
@@ -6445,8 +6990,8 @@ function MoreOptions({
|
|
|
6445
6990
|
...props
|
|
6446
6991
|
}) {
|
|
6447
6992
|
const { editor } = useTiptapEditor(providedEditor);
|
|
6448
|
-
const [show, setShow] = (0,
|
|
6449
|
-
(0,
|
|
6993
|
+
const [show, setShow] = (0, import_react55.useState)(false);
|
|
6994
|
+
(0, import_react55.useEffect)(() => {
|
|
6450
6995
|
if (!editor) return;
|
|
6451
6996
|
const handleSelectionUpdate = () => {
|
|
6452
6997
|
setShow(
|
|
@@ -6465,13 +7010,13 @@ function MoreOptions({
|
|
|
6465
7010
|
if (!show || !editor || !editor.isEditable) {
|
|
6466
7011
|
return null;
|
|
6467
7012
|
}
|
|
6468
|
-
return /* @__PURE__ */ (0,
|
|
6469
|
-
/* @__PURE__ */ (0,
|
|
6470
|
-
/* @__PURE__ */ (0,
|
|
6471
|
-
/* @__PURE__ */ (0,
|
|
7013
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_jsx_runtime31.Fragment, { children: [
|
|
7014
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_toolbar10.ToolbarSeparator, {}),
|
|
7015
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_toolbar10.ToolbarGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_popover3.Popover.Root, { spacing: "dense", width: "auto", children: [
|
|
7016
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6472
7017
|
import_popover3.Popover.Trigger,
|
|
6473
7018
|
{
|
|
6474
|
-
render: /* @__PURE__ */ (0,
|
|
7019
|
+
render: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6475
7020
|
import_toolbar10.ToolbarButton,
|
|
6476
7021
|
{
|
|
6477
7022
|
type: "button",
|
|
@@ -6483,29 +7028,29 @@ function MoreOptions({
|
|
|
6483
7028
|
title: "More options",
|
|
6484
7029
|
isIconOnly: true,
|
|
6485
7030
|
...props,
|
|
6486
|
-
children: /* @__PURE__ */ (0,
|
|
7031
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_icons25.MoreVerticalIcon, {})
|
|
6487
7032
|
}
|
|
6488
7033
|
)
|
|
6489
7034
|
}
|
|
6490
7035
|
),
|
|
6491
|
-
/* @__PURE__ */ (0,
|
|
7036
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
6492
7037
|
import_popover3.Popover.Content,
|
|
6493
7038
|
{
|
|
6494
7039
|
side: "top",
|
|
6495
7040
|
align: "end",
|
|
6496
7041
|
alignOffset: 4,
|
|
6497
7042
|
sideOffset: 4,
|
|
6498
|
-
children: /* @__PURE__ */ (0,
|
|
6499
|
-
/* @__PURE__ */ (0,
|
|
6500
|
-
/* @__PURE__ */ (0,
|
|
6501
|
-
/* @__PURE__ */ (0,
|
|
7043
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_toolbar10.Toolbar, { children: [
|
|
7044
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_toolbar10.ToolbarGroup, { children: [
|
|
7045
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MarkButton, { type: "superscript" }),
|
|
7046
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MarkButton, { type: "subscript" })
|
|
6502
7047
|
] }),
|
|
6503
|
-
/* @__PURE__ */ (0,
|
|
6504
|
-
/* @__PURE__ */ (0,
|
|
6505
|
-
/* @__PURE__ */ (0,
|
|
6506
|
-
/* @__PURE__ */ (0,
|
|
6507
|
-
/* @__PURE__ */ (0,
|
|
6508
|
-
/* @__PURE__ */ (0,
|
|
7048
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_toolbar10.ToolbarSeparator, {}),
|
|
7049
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_toolbar10.ToolbarGroup, { children: [
|
|
7050
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TextAlignButton, { align: "left" }),
|
|
7051
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TextAlignButton, { align: "center" }),
|
|
7052
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TextAlignButton, { align: "right" }),
|
|
7053
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TextAlignButton, { align: "justify" })
|
|
6509
7054
|
] })
|
|
6510
7055
|
] })
|
|
6511
7056
|
}
|
|
@@ -6537,36 +7082,87 @@ function shouldShowMoreOptions(params) {
|
|
|
6537
7082
|
}
|
|
6538
7083
|
|
|
6539
7084
|
// src/presets/basic/index.tsx
|
|
6540
|
-
var
|
|
7085
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
6541
7086
|
var BasicEditor = ({
|
|
6542
7087
|
variant,
|
|
6543
7088
|
bordered,
|
|
6544
7089
|
content,
|
|
7090
|
+
variables,
|
|
7091
|
+
variableValues,
|
|
6545
7092
|
...options
|
|
6546
7093
|
}) => {
|
|
6547
|
-
const editor = useCreateEditor({
|
|
6548
|
-
|
|
7094
|
+
const editor = useCreateEditor({
|
|
7095
|
+
content,
|
|
7096
|
+
enableVariables: !!(variables == null ? void 0 : variables.length),
|
|
7097
|
+
...options
|
|
7098
|
+
});
|
|
7099
|
+
const styles = (0, import_theme9.editorBasic)({ variant, bordered });
|
|
7100
|
+
const resolveVariable = (0, import_react57.useCallback)(
|
|
7101
|
+
(name) => variableValues == null ? void 0 : variableValues[name],
|
|
7102
|
+
[variableValues]
|
|
7103
|
+
);
|
|
6549
7104
|
if (!editor) {
|
|
6550
|
-
return /* @__PURE__ */ (0,
|
|
7105
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(LoadingSpinner, {});
|
|
6551
7106
|
}
|
|
6552
7107
|
const isBottomToolbar = variant === "field";
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
/* @__PURE__ */ (0,
|
|
6556
|
-
|
|
7108
|
+
const hasVariables = variables && variables.length > 0;
|
|
7109
|
+
const editorContent = /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(EditorUIProvider, { value: { styles }, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: styles.root(), "data-slot": "editor", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react56.EditorContext.Provider, { value: { editor }, children: [
|
|
7110
|
+
!isBottomToolbar && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(EditorHeader, { editor, variant }),
|
|
7111
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(EditorContentArea, { variant, variables }),
|
|
7112
|
+
isBottomToolbar && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(EditorHeader, { editor, variant })
|
|
6557
7113
|
] }) }) });
|
|
7114
|
+
if (hasVariables) {
|
|
7115
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VariableProvider, { variables, resolveVariable, children: editorContent });
|
|
7116
|
+
}
|
|
7117
|
+
return editorContent;
|
|
6558
7118
|
};
|
|
6559
|
-
var EditorContentArea = ({ variant }) => {
|
|
6560
|
-
const styles = (0,
|
|
6561
|
-
const { editor } = (0,
|
|
7119
|
+
var EditorContentArea = ({ variant, variables }) => {
|
|
7120
|
+
const styles = (0, import_theme9.editorBasic)({ variant });
|
|
7121
|
+
const { editor } = (0, import_react57.useContext)(import_react56.EditorContext);
|
|
6562
7122
|
const { isDragging } = useUiEditorState(editor);
|
|
6563
7123
|
useScrollToHash();
|
|
7124
|
+
const handleKeyDown = (0, import_react57.useCallback)(
|
|
7125
|
+
(e) => {
|
|
7126
|
+
if (!(editor == null ? void 0 : editor.isFocused)) return;
|
|
7127
|
+
const isMod = e.metaKey || e.ctrlKey;
|
|
7128
|
+
const key = e.key.toLowerCase();
|
|
7129
|
+
const editorShortcuts = [
|
|
7130
|
+
isMod && key === "b",
|
|
7131
|
+
// Bold
|
|
7132
|
+
isMod && key === "i",
|
|
7133
|
+
// Italic
|
|
7134
|
+
isMod && key === "u",
|
|
7135
|
+
// Underline
|
|
7136
|
+
isMod && e.shiftKey && key === "x",
|
|
7137
|
+
// Strikethrough
|
|
7138
|
+
isMod && key === "k",
|
|
7139
|
+
// Link
|
|
7140
|
+
isMod && key === "z",
|
|
7141
|
+
// Undo
|
|
7142
|
+
isMod && e.shiftKey && key === "z",
|
|
7143
|
+
// Redo
|
|
7144
|
+
isMod && key === "y",
|
|
7145
|
+
// Redo (alternative)
|
|
7146
|
+
isMod && key === "a",
|
|
7147
|
+
// Select all
|
|
7148
|
+
isMod && key === "e",
|
|
7149
|
+
// Code
|
|
7150
|
+
isMod && e.shiftKey && key === "e"
|
|
7151
|
+
// Code block
|
|
7152
|
+
];
|
|
7153
|
+
if (editorShortcuts.some(Boolean)) {
|
|
7154
|
+
e.stopPropagation();
|
|
7155
|
+
}
|
|
7156
|
+
},
|
|
7157
|
+
[editor]
|
|
7158
|
+
);
|
|
6564
7159
|
if (!editor) {
|
|
6565
7160
|
return null;
|
|
6566
7161
|
}
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
7162
|
+
const isEditable = editor.isEditable;
|
|
7163
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: styles.wrapper(), onKeyDown: handleKeyDown, children: [
|
|
7164
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
7165
|
+
import_react56.EditorContent,
|
|
6570
7166
|
{
|
|
6571
7167
|
editor,
|
|
6572
7168
|
role: "presentation",
|
|
@@ -6574,17 +7170,20 @@ var EditorContentArea = ({ variant }) => {
|
|
|
6574
7170
|
style: {
|
|
6575
7171
|
cursor: isDragging ? "grabbing" : "auto"
|
|
6576
7172
|
},
|
|
6577
|
-
children:
|
|
7173
|
+
children: [
|
|
7174
|
+
isEditable && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SlashDropdownMenu, {}),
|
|
7175
|
+
isEditable && variables && variables.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VariableSuggestion, { editor, variables })
|
|
7176
|
+
]
|
|
6578
7177
|
}
|
|
6579
7178
|
),
|
|
6580
|
-
/* @__PURE__ */ (0,
|
|
6581
|
-
/* @__PURE__ */ (0,
|
|
7179
|
+
isEditable && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(BubbleMenu, { editor }),
|
|
7180
|
+
isEditable && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(LinkBubble, { editor })
|
|
6582
7181
|
] });
|
|
6583
7182
|
};
|
|
6584
7183
|
function LoadingSpinner({ text = "Connecting..." }) {
|
|
6585
|
-
const styles = (0,
|
|
6586
|
-
return /* @__PURE__ */ (0,
|
|
6587
|
-
/* @__PURE__ */ (0,
|
|
7184
|
+
const styles = (0, import_theme9.editorSpinner)();
|
|
7185
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: styles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: styles.content(), children: [
|
|
7186
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
6588
7187
|
"svg",
|
|
6589
7188
|
{
|
|
6590
7189
|
className: styles.svg(),
|
|
@@ -6592,9 +7191,9 @@ function LoadingSpinner({ text = "Connecting..." }) {
|
|
|
6592
7191
|
fill: "none",
|
|
6593
7192
|
viewBox: "0 0 24 24",
|
|
6594
7193
|
children: [
|
|
6595
|
-
/* @__PURE__ */ (0,
|
|
6596
|
-
/* @__PURE__ */ (0,
|
|
6597
|
-
/* @__PURE__ */ (0,
|
|
7194
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("title", { children: "Loading Spinner" }),
|
|
7195
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("circle", { className: styles.circle(), cx: "12", cy: "12", r: "10" }),
|
|
7196
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6598
7197
|
"path",
|
|
6599
7198
|
{
|
|
6600
7199
|
className: styles.path(),
|
|
@@ -6604,7 +7203,7 @@ function LoadingSpinner({ text = "Connecting..." }) {
|
|
|
6604
7203
|
]
|
|
6605
7204
|
}
|
|
6606
7205
|
),
|
|
6607
|
-
/* @__PURE__ */ (0,
|
|
7206
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: styles.text(), children: text })
|
|
6608
7207
|
] }) });
|
|
6609
7208
|
}
|
|
6610
7209
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -6617,11 +7216,18 @@ function LoadingSpinner({ text = "Connecting..." }) {
|
|
|
6617
7216
|
InlineMath,
|
|
6618
7217
|
MathBlock,
|
|
6619
7218
|
TocNode,
|
|
7219
|
+
VariableFillerDialog,
|
|
7220
|
+
VariableNode,
|
|
7221
|
+
VariableProvider,
|
|
7222
|
+
VariableSuggestion,
|
|
6620
7223
|
convertFileToBase64,
|
|
7224
|
+
extractVariablesFromContent,
|
|
6621
7225
|
getExtensions,
|
|
6622
7226
|
handleImageUpload,
|
|
6623
7227
|
isAllowedUri,
|
|
6624
7228
|
sanitizeUrl,
|
|
6625
7229
|
useEditorFile,
|
|
6626
|
-
useEditorFileRequired
|
|
7230
|
+
useEditorFileRequired,
|
|
7231
|
+
useVariables,
|
|
7232
|
+
useVariablesWithFallback
|
|
6627
7233
|
});
|