notra-editor 0.8.2 → 0.8.3
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/components/slash-dropdown-menu/filter-slash-items.cjs +46 -0
- package/dist/components/slash-dropdown-menu/filter-slash-items.cjs.map +1 -0
- package/dist/components/slash-dropdown-menu/filter-slash-items.d.cts +15 -0
- package/dist/components/slash-dropdown-menu/filter-slash-items.d.ts +15 -0
- package/dist/components/slash-dropdown-menu/filter-slash-items.mjs +21 -0
- package/dist/components/slash-dropdown-menu/filter-slash-items.mjs.map +1 -0
- package/dist/components/slash-dropdown-menu/slash-dropdown-menu.cjs +228 -85
- package/dist/components/slash-dropdown-menu/slash-dropdown-menu.cjs.map +1 -1
- package/dist/components/slash-dropdown-menu/slash-dropdown-menu.mjs +249 -84
- package/dist/components/slash-dropdown-menu/slash-dropdown-menu.mjs.map +1 -1
- package/dist/components/{suggestion-menu/suggestion-menu-types.cjs → slash-dropdown-menu/types.cjs} +4 -4
- package/dist/components/slash-dropdown-menu/types.cjs.map +1 -0
- package/dist/components/{suggestion-menu/suggestion-menu-types.d.cts → slash-dropdown-menu/types.d.cts} +2 -2
- package/dist/components/{suggestion-menu/suggestion-menu-types.d.ts → slash-dropdown-menu/types.d.ts} +2 -2
- package/dist/components/slash-dropdown-menu/types.mjs +1 -0
- package/dist/components/slash-dropdown-menu/use-slash-items.cjs.map +1 -1
- package/dist/components/slash-dropdown-menu/use-slash-items.d.cts +2 -2
- package/dist/components/slash-dropdown-menu/use-slash-items.d.ts +2 -2
- package/dist/components/slash-dropdown-menu/use-slash-items.mjs.map +1 -1
- package/dist/components/ui/command.cjs +1 -1
- package/dist/components/ui/command.cjs.map +1 -1
- package/dist/components/ui/command.mjs +1 -1
- package/dist/components/ui/command.mjs.map +1 -1
- package/dist/components/ui/input-group.d.cts +1 -1
- package/dist/components/ui/input-group.d.ts +1 -1
- package/dist/styles/globals.css +1 -2
- package/dist/themes/default/editor.css +18 -6
- package/package.json +2 -1
- package/dist/components/suggestion-menu/filter-suggestion-items.cjs +0 -57
- package/dist/components/suggestion-menu/filter-suggestion-items.cjs.map +0 -1
- package/dist/components/suggestion-menu/filter-suggestion-items.d.cts +0 -6
- package/dist/components/suggestion-menu/filter-suggestion-items.d.ts +0 -6
- package/dist/components/suggestion-menu/filter-suggestion-items.mjs +0 -32
- package/dist/components/suggestion-menu/filter-suggestion-items.mjs.map +0 -1
- package/dist/components/suggestion-menu/suggestion-menu-types.cjs.map +0 -1
- package/dist/components/suggestion-menu/suggestion-menu-types.mjs +0 -1
- package/dist/components/suggestion-menu/suggestion-menu.cjs +0 -205
- package/dist/components/suggestion-menu/suggestion-menu.cjs.map +0 -1
- package/dist/components/suggestion-menu/suggestion-menu.d.cts +0 -27
- package/dist/components/suggestion-menu/suggestion-menu.d.ts +0 -27
- package/dist/components/suggestion-menu/suggestion-menu.mjs +0 -181
- package/dist/components/suggestion-menu/suggestion-menu.mjs.map +0 -1
- package/dist/hooks/use-floating-element.cjs +0 -55
- package/dist/hooks/use-floating-element.cjs.map +0 -1
- package/dist/hooks/use-floating-element.d.cts +0 -21
- package/dist/hooks/use-floating-element.d.ts +0 -21
- package/dist/hooks/use-floating-element.mjs +0 -35
- package/dist/hooks/use-floating-element.mjs.map +0 -1
- /package/dist/components/{suggestion-menu/suggestion-menu-types.mjs.map → slash-dropdown-menu/types.mjs.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ui/command.tsx"],"sourcesContent":["import { Command as CommandPrimitive } from 'cmdk';\nimport { SearchIcon, CheckIcon } from 'lucide-react';\nimport * as React from 'react';\n\nimport {\n\tDialog,\n\tDialogContent,\n\tDialogDescription,\n\tDialogHeader,\n\tDialogTitle\n} from './dialog.js';\nimport { InputGroup, InputGroupAddon } from './input-group.js';\nimport { cn } from '../../lib/utils.js';\n\nfunction Command({\n\tclassName,\n\t...props\n}: React.ComponentProps<typeof CommandPrimitive>) {\n\treturn (\n\t\t<CommandPrimitive\n\t\t\tclassName={cn(\n\t\t\t\t'nt:flex nt:size-full nt:flex-col nt:overflow-hidden nt:rounded-xl! nt:bg-popover nt:p-1 nt:text-popover-foreground',\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\tdata-slot=\"command\"\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction CommandDialog({\n\ttitle = 'Command Palette',\n\tdescription = 'Search for a command to run...',\n\tchildren,\n\tclassName,\n\tshowCloseButton = false,\n\t...props\n}: React.ComponentProps<typeof Dialog> & {\n\ttitle?: string;\n\tdescription?: string;\n\tclassName?: string;\n\tshowCloseButton?: boolean;\n}) {\n\treturn (\n\t\t<Dialog {...props}>\n\t\t\t<DialogHeader className=\"nt:sr-only\">\n\t\t\t\t<DialogTitle>{title}</DialogTitle>\n\t\t\t\t<DialogDescription>{description}</DialogDescription>\n\t\t\t</DialogHeader>\n\t\t\t<DialogContent\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'nt:top-1/3 nt:translate-y-0 nt:overflow-hidden nt:rounded-xl! nt:p-0',\n\t\t\t\t\tclassName\n\t\t\t\t)}\n\t\t\t\tshowCloseButton={showCloseButton}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n\nfunction CommandInput({\n\tclassName,\n\t...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n\treturn (\n\t\t<div className=\"nt:p-1 nt:pb-0\" data-slot=\"command-input-wrapper\">\n\t\t\t<InputGroup className=\"nt:h-8! nt:rounded-lg! nt:border-input/30 nt:bg-input/30 nt:shadow-none! nt:*:data-[slot=input-group-addon]:pl-2!\">\n\t\t\t\t<CommandPrimitive.Input\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t'nt:w-full nt:text-sm nt:outline-hidden nt:disabled:cursor-not-allowed nt:disabled:opacity-50',\n\t\t\t\t\t\tclassName\n\t\t\t\t\t)}\n\t\t\t\t\tdata-slot=\"command-input\"\n\t\t\t\t\t{...props}\n\t\t\t\t/>\n\t\t\t\t<InputGroupAddon>\n\t\t\t\t\t<SearchIcon className=\"nt:size-4 nt:shrink-0 nt:opacity-50\" />\n\t\t\t\t</InputGroupAddon>\n\t\t\t</InputGroup>\n\t\t</div>\n\t);\n}\n\nfunction CommandList({\n\tclassName,\n\t...props\n}: React.ComponentProps<typeof CommandPrimitive.List>) {\n\treturn (\n\t\t<CommandPrimitive.List\n\t\t\tclassName={cn(\n\t\t\t\t'nt:
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ui/command.tsx"],"sourcesContent":["import { Command as CommandPrimitive } from 'cmdk';\nimport { SearchIcon, CheckIcon } from 'lucide-react';\nimport * as React from 'react';\n\nimport {\n\tDialog,\n\tDialogContent,\n\tDialogDescription,\n\tDialogHeader,\n\tDialogTitle\n} from './dialog.js';\nimport { InputGroup, InputGroupAddon } from './input-group.js';\nimport { cn } from '../../lib/utils.js';\n\nfunction Command({\n\tclassName,\n\t...props\n}: React.ComponentProps<typeof CommandPrimitive>) {\n\treturn (\n\t\t<CommandPrimitive\n\t\t\tclassName={cn(\n\t\t\t\t'nt:flex nt:size-full nt:flex-col nt:overflow-hidden nt:rounded-xl! nt:bg-popover nt:p-1 nt:text-popover-foreground',\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\tdata-slot=\"command\"\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction CommandDialog({\n\ttitle = 'Command Palette',\n\tdescription = 'Search for a command to run...',\n\tchildren,\n\tclassName,\n\tshowCloseButton = false,\n\t...props\n}: React.ComponentProps<typeof Dialog> & {\n\ttitle?: string;\n\tdescription?: string;\n\tclassName?: string;\n\tshowCloseButton?: boolean;\n}) {\n\treturn (\n\t\t<Dialog {...props}>\n\t\t\t<DialogHeader className=\"nt:sr-only\">\n\t\t\t\t<DialogTitle>{title}</DialogTitle>\n\t\t\t\t<DialogDescription>{description}</DialogDescription>\n\t\t\t</DialogHeader>\n\t\t\t<DialogContent\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'nt:top-1/3 nt:translate-y-0 nt:overflow-hidden nt:rounded-xl! nt:p-0',\n\t\t\t\t\tclassName\n\t\t\t\t)}\n\t\t\t\tshowCloseButton={showCloseButton}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n}\n\nfunction CommandInput({\n\tclassName,\n\t...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n\treturn (\n\t\t<div className=\"nt:p-1 nt:pb-0\" data-slot=\"command-input-wrapper\">\n\t\t\t<InputGroup className=\"nt:h-8! nt:rounded-lg! nt:border-input/30 nt:bg-input/30 nt:shadow-none! nt:*:data-[slot=input-group-addon]:pl-2!\">\n\t\t\t\t<CommandPrimitive.Input\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t'nt:w-full nt:text-sm nt:outline-hidden nt:disabled:cursor-not-allowed nt:disabled:opacity-50',\n\t\t\t\t\t\tclassName\n\t\t\t\t\t)}\n\t\t\t\t\tdata-slot=\"command-input\"\n\t\t\t\t\t{...props}\n\t\t\t\t/>\n\t\t\t\t<InputGroupAddon>\n\t\t\t\t\t<SearchIcon className=\"nt:size-4 nt:shrink-0 nt:opacity-50\" />\n\t\t\t\t</InputGroupAddon>\n\t\t\t</InputGroup>\n\t\t</div>\n\t);\n}\n\nfunction CommandList({\n\tclassName,\n\t...props\n}: React.ComponentProps<typeof CommandPrimitive.List>) {\n\treturn (\n\t\t<CommandPrimitive.List\n\t\t\tclassName={cn(\n\t\t\t\t'nt:scrollbar-hide nt:max-h-72 nt:scroll-py-1 nt:overflow-x-hidden nt:overflow-y-auto nt:outline-none',\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\tdata-slot=\"command-list\"\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction CommandEmpty({\n\tclassName,\n\t...props\n}: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n\treturn (\n\t\t<CommandPrimitive.Empty\n\t\t\tclassName={cn('nt:py-6 nt:text-center nt:text-sm', className)}\n\t\t\tdata-slot=\"command-empty\"\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction CommandGroup({\n\tclassName,\n\t...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n\treturn (\n\t\t<CommandPrimitive.Group\n\t\t\tclassName={cn(\n\t\t\t\t'nt:overflow-hidden nt:p-1 nt:text-foreground nt:**:[[cmdk-group-heading]]:px-2 nt:**:[[cmdk-group-heading]]:py-1.5 nt:**:[[cmdk-group-heading]]:text-xs nt:**:[[cmdk-group-heading]]:font-medium nt:**:[[cmdk-group-heading]]:text-muted-foreground',\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\tdata-slot=\"command-group\"\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction CommandSeparator({\n\tclassName,\n\t...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n\treturn (\n\t\t<CommandPrimitive.Separator\n\t\t\tclassName={cn('nt:-mx-1 nt:h-px nt:bg-border', className)}\n\t\t\tdata-slot=\"command-separator\"\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nfunction CommandItem({\n\tclassName,\n\tchildren,\n\t...props\n}: React.ComponentProps<typeof CommandPrimitive.Item>) {\n\treturn (\n\t\t<CommandPrimitive.Item\n\t\t\tclassName={cn(\n\t\t\t\t'nt:group/command-item nt:relative nt:flex nt:cursor-default nt:items-center nt:gap-2 nt:rounded-sm nt:px-2 nt:py-1.5 nt:text-sm nt:outline-hidden nt:select-none nt:in-data-[slot=dialog-content]:rounded-lg! nt:data-[disabled=true]:pointer-events-none nt:data-[disabled=true]:opacity-50 nt:data-selected:bg-muted nt:data-selected:text-foreground nt:[&_svg]:pointer-events-none nt:[&_svg]:shrink-0 nt:[&_svg:not([class*=size-])]:size-4 nt:data-selected:*:[svg]:text-foreground',\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\tdata-slot=\"command-item\"\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t\t<CheckIcon className=\"nt:ml-auto nt:opacity-0 nt:group-has-data-[slot=command-shortcut]/command-item:hidden nt:group-data-[checked=true]/command-item:opacity-100\" />\n\t\t</CommandPrimitive.Item>\n\t);\n}\n\nfunction CommandShortcut({\n\tclassName,\n\t...props\n}: React.ComponentProps<'span'>) {\n\treturn (\n\t\t<span\n\t\t\tclassName={cn(\n\t\t\t\t'nt:ml-auto nt:text-xs nt:tracking-widest nt:text-muted-foreground nt:group-data-selected/command-item:text-foreground',\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\tdata-slot=\"command-shortcut\"\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport {\n\tCommand,\n\tCommandDialog,\n\tCommandInput,\n\tCommandList,\n\tCommandEmpty,\n\tCommandGroup,\n\tCommandItem,\n\tCommandShortcut,\n\tCommandSeparator\n};\n"],"mappings":"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","names":[]}
|
|
@@ -6,7 +6,7 @@ import { Button } from './button.cjs';
|
|
|
6
6
|
|
|
7
7
|
declare function InputGroup({ className, ...props }: React.ComponentProps<'div'>): react_jsx_runtime.JSX.Element;
|
|
8
8
|
declare const inputGroupAddonVariants: (props?: ({
|
|
9
|
-
align?: "inline-
|
|
9
|
+
align?: "inline-start" | "inline-end" | "block-start" | "block-end" | null | undefined;
|
|
10
10
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
11
11
|
declare function InputGroupAddon({ className, align, ...props }: React.ComponentProps<'div'> & VariantProps<typeof inputGroupAddonVariants>): react_jsx_runtime.JSX.Element;
|
|
12
12
|
declare const inputGroupButtonVariants: (props?: ({
|
|
@@ -6,7 +6,7 @@ import { Button } from './button.js';
|
|
|
6
6
|
|
|
7
7
|
declare function InputGroup({ className, ...props }: React.ComponentProps<'div'>): react_jsx_runtime.JSX.Element;
|
|
8
8
|
declare const inputGroupAddonVariants: (props?: ({
|
|
9
|
-
align?: "inline-
|
|
9
|
+
align?: "inline-start" | "inline-end" | "block-start" | "block-end" | null | undefined;
|
|
10
10
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
11
11
|
declare function InputGroupAddon({ className, align, ...props }: React.ComponentProps<'div'> & VariantProps<typeof inputGroupAddonVariants>): react_jsx_runtime.JSX.Element;
|
|
12
12
|
declare const inputGroupButtonVariants: (props?: ({
|
package/dist/styles/globals.css
CHANGED
|
@@ -378,21 +378,33 @@
|
|
|
378
378
|
background-color: var(--tt-bg-color);
|
|
379
379
|
}
|
|
380
380
|
|
|
381
|
-
|
|
381
|
+
.notra-editor-wrapper {
|
|
382
|
+
scrollbar-width: thin;
|
|
383
|
+
scrollbar-color: var(--tt-scrollbar-color) transparent;
|
|
384
|
+
}
|
|
385
|
+
.notra-editor-wrapper::-webkit-scrollbar {
|
|
382
386
|
width: 0.25rem;
|
|
383
387
|
}
|
|
388
|
+
.notra-editor-wrapper::-webkit-scrollbar-thumb {
|
|
389
|
+
background-color: var(--tt-scrollbar-color);
|
|
390
|
+
border-radius: 9999px;
|
|
391
|
+
}
|
|
392
|
+
.notra-editor-wrapper::-webkit-scrollbar-track {
|
|
393
|
+
background: transparent;
|
|
394
|
+
}
|
|
384
395
|
|
|
385
|
-
* {
|
|
396
|
+
.notra-editor-content * {
|
|
386
397
|
scrollbar-width: thin;
|
|
387
398
|
scrollbar-color: var(--tt-scrollbar-color) transparent;
|
|
388
399
|
}
|
|
389
|
-
|
|
390
|
-
|
|
400
|
+
.notra-editor-content ::-webkit-scrollbar {
|
|
401
|
+
width: 0.25rem;
|
|
402
|
+
}
|
|
403
|
+
.notra-editor-content ::-webkit-scrollbar-thumb {
|
|
391
404
|
background-color: var(--tt-scrollbar-color);
|
|
392
405
|
border-radius: 9999px;
|
|
393
406
|
}
|
|
394
|
-
|
|
395
|
-
::-webkit-scrollbar-track {
|
|
407
|
+
.notra-editor-content ::-webkit-scrollbar-track {
|
|
396
408
|
background: transparent;
|
|
397
409
|
}
|
|
398
410
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "notra-editor",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.3",
|
|
5
5
|
"description": "A Markdown-first rich text editor for React",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"keywords": [
|
|
@@ -75,6 +75,7 @@
|
|
|
75
75
|
"react-dom": "^19.2.0",
|
|
76
76
|
"sass": "^1.99.0",
|
|
77
77
|
"shadcn": "^4.6.0",
|
|
78
|
+
"tailwind-scrollbar-hide": "^4.0.0",
|
|
78
79
|
"tailwindcss": "^4.2.4",
|
|
79
80
|
"tsup": "^8.4.0",
|
|
80
81
|
"tw-animate-css": "^1.4.0",
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/components/suggestion-menu/filter-suggestion-items.ts
|
|
21
|
-
var filter_suggestion_items_exports = {};
|
|
22
|
-
__export(filter_suggestion_items_exports, {
|
|
23
|
-
filterSuggestionItems: () => filterSuggestionItems
|
|
24
|
-
});
|
|
25
|
-
module.exports = __toCommonJS(filter_suggestion_items_exports);
|
|
26
|
-
function filterSuggestionItems(items, query) {
|
|
27
|
-
const normalized = query.trim().toLowerCase();
|
|
28
|
-
if (!normalized) {
|
|
29
|
-
return items;
|
|
30
|
-
}
|
|
31
|
-
const matches = items.filter((item) => {
|
|
32
|
-
if (item.title.toLowerCase().includes(normalized)) return true;
|
|
33
|
-
if (item.subtext?.toLowerCase().includes(normalized)) return true;
|
|
34
|
-
if (item.keywords?.some((kw) => kw.toLowerCase().includes(normalized))) {
|
|
35
|
-
return true;
|
|
36
|
-
}
|
|
37
|
-
return false;
|
|
38
|
-
});
|
|
39
|
-
return matches.sort((a, b) => {
|
|
40
|
-
const aTitle = a.title.toLowerCase();
|
|
41
|
-
const bTitle = b.title.toLowerCase();
|
|
42
|
-
const aExact = aTitle === normalized;
|
|
43
|
-
const bExact = bTitle === normalized;
|
|
44
|
-
if (aExact && !bExact) return -1;
|
|
45
|
-
if (bExact && !aExact) return 1;
|
|
46
|
-
const aStarts = aTitle.startsWith(normalized);
|
|
47
|
-
const bStarts = bTitle.startsWith(normalized);
|
|
48
|
-
if (aStarts && !bStarts) return -1;
|
|
49
|
-
if (bStarts && !aStarts) return 1;
|
|
50
|
-
return 0;
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
54
|
-
0 && (module.exports = {
|
|
55
|
-
filterSuggestionItems
|
|
56
|
-
});
|
|
57
|
-
//# sourceMappingURL=filter-suggestion-items.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/suggestion-menu/filter-suggestion-items.ts"],"sourcesContent":["import type { SuggestionItem } from './suggestion-menu-types.js';\n\nexport function filterSuggestionItems(\n\titems: SuggestionItem[],\n\tquery: string\n): SuggestionItem[] {\n\tconst normalized = query.trim().toLowerCase();\n\n\tif (!normalized) {\n\t\treturn items;\n\t}\n\n\tconst matches = items.filter((item) => {\n\t\tif (item.title.toLowerCase().includes(normalized)) return true;\n\n\t\tif (item.subtext?.toLowerCase().includes(normalized)) return true;\n\n\t\tif (item.keywords?.some((kw) => kw.toLowerCase().includes(normalized))) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t});\n\n\treturn matches.sort((a, b) => {\n\t\tconst aTitle = a.title.toLowerCase();\n\t\tconst bTitle = b.title.toLowerCase();\n\n\t\tconst aExact = aTitle === normalized;\n\t\tconst bExact = bTitle === normalized;\n\n\t\tif (aExact && !bExact) return -1;\n\n\t\tif (bExact && !aExact) return 1;\n\n\t\tconst aStarts = aTitle.startsWith(normalized);\n\t\tconst bStarts = bTitle.startsWith(normalized);\n\n\t\tif (aStarts && !bStarts) return -1;\n\n\t\tif (bStarts && !aStarts) return 1;\n\n\t\treturn 0;\n\t});\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEO,SAAS,sBACf,OACA,OACmB;AACnB,QAAM,aAAa,MAAM,KAAK,EAAE,YAAY;AAE5C,MAAI,CAAC,YAAY;AAChB,WAAO;AAAA,EACR;AAEA,QAAM,UAAU,MAAM,OAAO,CAAC,SAAS;AACtC,QAAI,KAAK,MAAM,YAAY,EAAE,SAAS,UAAU,EAAG,QAAO;AAE1D,QAAI,KAAK,SAAS,YAAY,EAAE,SAAS,UAAU,EAAG,QAAO;AAE7D,QAAI,KAAK,UAAU,KAAK,CAAC,OAAO,GAAG,YAAY,EAAE,SAAS,UAAU,CAAC,GAAG;AACvE,aAAO;AAAA,IACR;AAEA,WAAO;AAAA,EACR,CAAC;AAED,SAAO,QAAQ,KAAK,CAAC,GAAG,MAAM;AAC7B,UAAM,SAAS,EAAE,MAAM,YAAY;AACnC,UAAM,SAAS,EAAE,MAAM,YAAY;AAEnC,UAAM,SAAS,WAAW;AAC1B,UAAM,SAAS,WAAW;AAE1B,QAAI,UAAU,CAAC,OAAQ,QAAO;AAE9B,QAAI,UAAU,CAAC,OAAQ,QAAO;AAE9B,UAAM,UAAU,OAAO,WAAW,UAAU;AAC5C,UAAM,UAAU,OAAO,WAAW,UAAU;AAE5C,QAAI,WAAW,CAAC,QAAS,QAAO;AAEhC,QAAI,WAAW,CAAC,QAAS,QAAO;AAEhC,WAAO;AAAA,EACR,CAAC;AACF;","names":[]}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
// src/components/suggestion-menu/filter-suggestion-items.ts
|
|
2
|
-
function filterSuggestionItems(items, query) {
|
|
3
|
-
const normalized = query.trim().toLowerCase();
|
|
4
|
-
if (!normalized) {
|
|
5
|
-
return items;
|
|
6
|
-
}
|
|
7
|
-
const matches = items.filter((item) => {
|
|
8
|
-
if (item.title.toLowerCase().includes(normalized)) return true;
|
|
9
|
-
if (item.subtext?.toLowerCase().includes(normalized)) return true;
|
|
10
|
-
if (item.keywords?.some((kw) => kw.toLowerCase().includes(normalized))) {
|
|
11
|
-
return true;
|
|
12
|
-
}
|
|
13
|
-
return false;
|
|
14
|
-
});
|
|
15
|
-
return matches.sort((a, b) => {
|
|
16
|
-
const aTitle = a.title.toLowerCase();
|
|
17
|
-
const bTitle = b.title.toLowerCase();
|
|
18
|
-
const aExact = aTitle === normalized;
|
|
19
|
-
const bExact = bTitle === normalized;
|
|
20
|
-
if (aExact && !bExact) return -1;
|
|
21
|
-
if (bExact && !aExact) return 1;
|
|
22
|
-
const aStarts = aTitle.startsWith(normalized);
|
|
23
|
-
const bStarts = bTitle.startsWith(normalized);
|
|
24
|
-
if (aStarts && !bStarts) return -1;
|
|
25
|
-
if (bStarts && !aStarts) return 1;
|
|
26
|
-
return 0;
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
export {
|
|
30
|
-
filterSuggestionItems
|
|
31
|
-
};
|
|
32
|
-
//# sourceMappingURL=filter-suggestion-items.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/suggestion-menu/filter-suggestion-items.ts"],"sourcesContent":["import type { SuggestionItem } from './suggestion-menu-types.js';\n\nexport function filterSuggestionItems(\n\titems: SuggestionItem[],\n\tquery: string\n): SuggestionItem[] {\n\tconst normalized = query.trim().toLowerCase();\n\n\tif (!normalized) {\n\t\treturn items;\n\t}\n\n\tconst matches = items.filter((item) => {\n\t\tif (item.title.toLowerCase().includes(normalized)) return true;\n\n\t\tif (item.subtext?.toLowerCase().includes(normalized)) return true;\n\n\t\tif (item.keywords?.some((kw) => kw.toLowerCase().includes(normalized))) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t});\n\n\treturn matches.sort((a, b) => {\n\t\tconst aTitle = a.title.toLowerCase();\n\t\tconst bTitle = b.title.toLowerCase();\n\n\t\tconst aExact = aTitle === normalized;\n\t\tconst bExact = bTitle === normalized;\n\n\t\tif (aExact && !bExact) return -1;\n\n\t\tif (bExact && !aExact) return 1;\n\n\t\tconst aStarts = aTitle.startsWith(normalized);\n\t\tconst bStarts = bTitle.startsWith(normalized);\n\n\t\tif (aStarts && !bStarts) return -1;\n\n\t\tif (bStarts && !aStarts) return 1;\n\n\t\treturn 0;\n\t});\n}\n"],"mappings":";AAEO,SAAS,sBACf,OACA,OACmB;AACnB,QAAM,aAAa,MAAM,KAAK,EAAE,YAAY;AAE5C,MAAI,CAAC,YAAY;AAChB,WAAO;AAAA,EACR;AAEA,QAAM,UAAU,MAAM,OAAO,CAAC,SAAS;AACtC,QAAI,KAAK,MAAM,YAAY,EAAE,SAAS,UAAU,EAAG,QAAO;AAE1D,QAAI,KAAK,SAAS,YAAY,EAAE,SAAS,UAAU,EAAG,QAAO;AAE7D,QAAI,KAAK,UAAU,KAAK,CAAC,OAAO,GAAG,YAAY,EAAE,SAAS,UAAU,CAAC,GAAG;AACvE,aAAO;AAAA,IACR;AAEA,WAAO;AAAA,EACR,CAAC;AAED,SAAO,QAAQ,KAAK,CAAC,GAAG,MAAM;AAC7B,UAAM,SAAS,EAAE,MAAM,YAAY;AACnC,UAAM,SAAS,EAAE,MAAM,YAAY;AAEnC,UAAM,SAAS,WAAW;AAC1B,UAAM,SAAS,WAAW;AAE1B,QAAI,UAAU,CAAC,OAAQ,QAAO;AAE9B,QAAI,UAAU,CAAC,OAAQ,QAAO;AAE9B,UAAM,UAAU,OAAO,WAAW,UAAU;AAC5C,UAAM,UAAU,OAAO,WAAW,UAAU;AAE5C,QAAI,WAAW,CAAC,QAAS,QAAO;AAEhC,QAAI,WAAW,CAAC,QAAS,QAAO;AAEhC,WAAO;AAAA,EACR,CAAC;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/suggestion-menu/suggestion-menu-types.ts"],"sourcesContent":["import type { Editor, Range } from '@tiptap/react';\n\nexport type IconComponent = React.ComponentType<React.SVGProps<SVGSVGElement>>;\n\nexport interface SuggestionItem {\n\t/** Main label shown in the menu. */\n\ttitle: string;\n\t/** Secondary description shown under the title. */\n\tsubtext?: string;\n\t/** Icon component (lucide-react). */\n\tbadge?: IconComponent;\n\t/** Group label used by callers that render grouped lists. */\n\tgroup?: string;\n\t/** Extra search keywords. */\n\tkeywords?: string[];\n\t/** Invoked when the item is chosen. */\n\tonSelect: (props: { editor: Editor; range: Range }) => void;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=suggestion-menu-types.mjs.map
|
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
"use client";
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
for (let key of __getOwnPropNames(from))
|
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
-
|
|
21
|
-
// src/components/suggestion-menu/suggestion-menu.tsx
|
|
22
|
-
var suggestion_menu_exports = {};
|
|
23
|
-
__export(suggestion_menu_exports, {
|
|
24
|
-
SuggestionMenu: () => SuggestionMenu
|
|
25
|
-
});
|
|
26
|
-
module.exports = __toCommonJS(suggestion_menu_exports);
|
|
27
|
-
var import_react = require("@floating-ui/react");
|
|
28
|
-
var import_state = require("@tiptap/pm/state");
|
|
29
|
-
var import_suggestion = require("@tiptap/suggestion");
|
|
30
|
-
var import_react2 = require("react");
|
|
31
|
-
var import_use_floating_element = require("../../hooks/use-floating-element.cjs");
|
|
32
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
33
|
-
var FLOATING_Z_INDEX = 1e3;
|
|
34
|
-
function SuggestionMenu({
|
|
35
|
-
editor,
|
|
36
|
-
char,
|
|
37
|
-
pluginKey,
|
|
38
|
-
items: itemsFn,
|
|
39
|
-
decorationClass,
|
|
40
|
-
decorationContent,
|
|
41
|
-
selector = "notra-suggestion-menu",
|
|
42
|
-
maxHeight = 384,
|
|
43
|
-
children
|
|
44
|
-
}) {
|
|
45
|
-
const [open, setOpen] = (0, import_react2.useState)(false);
|
|
46
|
-
const [decorationNode, setDecorationNode] = (0, import_react2.useState)(
|
|
47
|
-
null
|
|
48
|
-
);
|
|
49
|
-
const [items, setItems] = (0, import_react2.useState)([]);
|
|
50
|
-
const [query, setQuery] = (0, import_react2.useState)("");
|
|
51
|
-
const [selectedIndex, setSelectedIndex] = (0, import_react2.useState)(0);
|
|
52
|
-
const commandRef = (0, import_react2.useRef)(null);
|
|
53
|
-
(0, import_react2.useEffect)(() => {
|
|
54
|
-
setSelectedIndex(0);
|
|
55
|
-
}, [query, items.length]);
|
|
56
|
-
const close = (0, import_react2.useCallback)(() => {
|
|
57
|
-
setOpen(false);
|
|
58
|
-
}, []);
|
|
59
|
-
const middleware = (0, import_react2.useMemo)(
|
|
60
|
-
() => [
|
|
61
|
-
(0, import_react.offset)(8),
|
|
62
|
-
(0, import_react.flip)({ mainAxis: true, crossAxis: false }),
|
|
63
|
-
(0, import_react.shift)({ padding: 8 }),
|
|
64
|
-
(0, import_react.size)({
|
|
65
|
-
apply({ availableHeight, elements }) {
|
|
66
|
-
const next = Math.min(availableHeight, maxHeight);
|
|
67
|
-
elements.floating.style.setProperty(
|
|
68
|
-
"--suggestion-menu-max-height",
|
|
69
|
-
`${next}px`
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
})
|
|
73
|
-
],
|
|
74
|
-
[maxHeight]
|
|
75
|
-
);
|
|
76
|
-
const { setFloatingRef, style, getFloatingProps, isMounted } = (0, import_use_floating_element.useFloatingElement)(open, decorationNode, FLOATING_Z_INDEX, {
|
|
77
|
-
placement: "bottom-start",
|
|
78
|
-
middleware,
|
|
79
|
-
onOpenChange: (next) => {
|
|
80
|
-
if (!next) close();
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
const itemsFnRef = (0, import_react2.useRef)(itemsFn);
|
|
84
|
-
const decorationClassRef = (0, import_react2.useRef)(decorationClass);
|
|
85
|
-
const decorationContentRef = (0, import_react2.useRef)(decorationContent);
|
|
86
|
-
(0, import_react2.useEffect)(() => {
|
|
87
|
-
itemsFnRef.current = itemsFn;
|
|
88
|
-
decorationClassRef.current = decorationClass;
|
|
89
|
-
decorationContentRef.current = decorationContent;
|
|
90
|
-
}, [itemsFn, decorationClass, decorationContent]);
|
|
91
|
-
const itemsRef = (0, import_react2.useRef)([]);
|
|
92
|
-
const selectedIndexRef = (0, import_react2.useRef)(0);
|
|
93
|
-
(0, import_react2.useEffect)(() => {
|
|
94
|
-
itemsRef.current = items;
|
|
95
|
-
}, [items]);
|
|
96
|
-
(0, import_react2.useEffect)(() => {
|
|
97
|
-
selectedIndexRef.current = selectedIndex;
|
|
98
|
-
}, [selectedIndex]);
|
|
99
|
-
(0, import_react2.useEffect)(() => {
|
|
100
|
-
if (!editor || editor.isDestroyed) return;
|
|
101
|
-
const key = new import_state.PluginKey(pluginKey);
|
|
102
|
-
const plugin = (0, import_suggestion.Suggestion)({
|
|
103
|
-
editor,
|
|
104
|
-
char,
|
|
105
|
-
pluginKey: key,
|
|
106
|
-
decorationClass: decorationClassRef.current,
|
|
107
|
-
decorationContent: decorationContentRef.current,
|
|
108
|
-
items: ({ query: query2, editor: editor2 }) => itemsFnRef.current({ query: query2, editor: editor2 }),
|
|
109
|
-
allow: ({ state, range }) => {
|
|
110
|
-
const $from = state.doc.resolve(range.from);
|
|
111
|
-
for (let depth = $from.depth; depth > 0; depth--) {
|
|
112
|
-
const name = $from.node(depth).type.name;
|
|
113
|
-
if (name === "image" || name === "codeBlock") return false;
|
|
114
|
-
}
|
|
115
|
-
return true;
|
|
116
|
-
},
|
|
117
|
-
command: ({ editor: editor2, range, props }) => {
|
|
118
|
-
editor2.chain().focus().deleteRange(range).run();
|
|
119
|
-
props.onSelect({ editor: editor2, range });
|
|
120
|
-
},
|
|
121
|
-
render: () => ({
|
|
122
|
-
onStart: (props) => {
|
|
123
|
-
setDecorationNode(props.decorationNode ?? null);
|
|
124
|
-
setItems(props.items);
|
|
125
|
-
setQuery(props.query);
|
|
126
|
-
commandRef.current = (item) => props.command(item);
|
|
127
|
-
setOpen(true);
|
|
128
|
-
},
|
|
129
|
-
onUpdate: (props) => {
|
|
130
|
-
setDecorationNode(props.decorationNode ?? null);
|
|
131
|
-
setItems(props.items);
|
|
132
|
-
setQuery(props.query);
|
|
133
|
-
commandRef.current = (item) => props.command(item);
|
|
134
|
-
},
|
|
135
|
-
onKeyDown: ({ event }) => {
|
|
136
|
-
const list = itemsRef.current;
|
|
137
|
-
if (event.key === "ArrowDown") {
|
|
138
|
-
if (list.length > 0) {
|
|
139
|
-
setSelectedIndex((selectedIndexRef.current + 1) % list.length);
|
|
140
|
-
}
|
|
141
|
-
return true;
|
|
142
|
-
}
|
|
143
|
-
if (event.key === "ArrowUp") {
|
|
144
|
-
if (list.length > 0) {
|
|
145
|
-
setSelectedIndex(
|
|
146
|
-
(selectedIndexRef.current - 1 + list.length) % list.length
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
return true;
|
|
150
|
-
}
|
|
151
|
-
if (event.key === "Enter") {
|
|
152
|
-
const item = list[selectedIndexRef.current];
|
|
153
|
-
if (item && commandRef.current) {
|
|
154
|
-
commandRef.current(item);
|
|
155
|
-
}
|
|
156
|
-
return true;
|
|
157
|
-
}
|
|
158
|
-
if (event.key === "Escape") {
|
|
159
|
-
close();
|
|
160
|
-
return true;
|
|
161
|
-
}
|
|
162
|
-
return false;
|
|
163
|
-
},
|
|
164
|
-
onExit: () => {
|
|
165
|
-
setDecorationNode(null);
|
|
166
|
-
setItems([]);
|
|
167
|
-
setQuery("");
|
|
168
|
-
commandRef.current = null;
|
|
169
|
-
setOpen(false);
|
|
170
|
-
}
|
|
171
|
-
})
|
|
172
|
-
});
|
|
173
|
-
editor.registerPlugin(plugin);
|
|
174
|
-
return () => {
|
|
175
|
-
if (!editor.isDestroyed) {
|
|
176
|
-
editor.unregisterPlugin(key);
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
}, [editor, char, pluginKey, close]);
|
|
180
|
-
const handleSelect = (0, import_react2.useCallback)((item) => {
|
|
181
|
-
if (commandRef.current) {
|
|
182
|
-
commandRef.current(item);
|
|
183
|
-
}
|
|
184
|
-
}, []);
|
|
185
|
-
if (!isMounted || !open) return null;
|
|
186
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
187
|
-
"div",
|
|
188
|
-
{
|
|
189
|
-
ref: setFloatingRef,
|
|
190
|
-
"aria-label": "Suggestions",
|
|
191
|
-
className: "notra-suggestion-menu",
|
|
192
|
-
"data-selector": selector,
|
|
193
|
-
role: "listbox",
|
|
194
|
-
style,
|
|
195
|
-
...getFloatingProps(),
|
|
196
|
-
onPointerDown: (e) => e.preventDefault(),
|
|
197
|
-
children: children({ items, selectedIndex, onSelect: handleSelect })
|
|
198
|
-
}
|
|
199
|
-
);
|
|
200
|
-
}
|
|
201
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
202
|
-
0 && (module.exports = {
|
|
203
|
-
SuggestionMenu
|
|
204
|
-
});
|
|
205
|
-
//# sourceMappingURL=suggestion-menu.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/suggestion-menu/suggestion-menu.tsx"],"sourcesContent":["'use client';\n\nimport { flip, offset, shift, size } from '@floating-ui/react';\nimport { PluginKey } from '@tiptap/pm/state';\nimport { Suggestion } from '@tiptap/suggestion';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { useFloatingElement } from '../../hooks/use-floating-element.js';\n\nimport type { SuggestionItem } from './suggestion-menu-types.js';\nimport type { Editor } from '@tiptap/react';\nimport type {\n\tSuggestionKeyDownProps,\n\tSuggestionProps\n} from '@tiptap/suggestion';\nimport type { ReactNode } from 'react';\n\nexport interface SuggestionMenuRenderProps {\n\titems: SuggestionItem[];\n\tselectedIndex: number;\n\tonSelect: (item: SuggestionItem) => void;\n}\n\nexport interface SuggestionMenuProps {\n\teditor: Editor | null;\n\tchar: string;\n\tpluginKey: string;\n\titems: (ctx: { query: string; editor: Editor }) => SuggestionItem[];\n\tdecorationClass?: string;\n\tdecorationContent?: string;\n\tselector?: string;\n\tmaxHeight?: number;\n\tchildren: (renderProps: SuggestionMenuRenderProps) => ReactNode;\n}\n\nconst FLOATING_Z_INDEX = 1000;\n\nexport function SuggestionMenu({\n\teditor,\n\tchar,\n\tpluginKey,\n\titems: itemsFn,\n\tdecorationClass,\n\tdecorationContent,\n\tselector = 'notra-suggestion-menu',\n\tmaxHeight = 384,\n\tchildren\n}: SuggestionMenuProps) {\n\tconst [open, setOpen] = useState(false);\n\tconst [decorationNode, setDecorationNode] = useState<HTMLElement | null>(\n\t\tnull\n\t);\n\tconst [items, setItems] = useState<SuggestionItem[]>([]);\n\tconst [query, setQuery] = useState('');\n\tconst [selectedIndex, setSelectedIndex] = useState(0);\n\tconst commandRef = useRef<((item: SuggestionItem) => void) | null>(null);\n\n\t// Reset selection when the visible item list changes.\n\tuseEffect(() => {\n\t\tsetSelectedIndex(0);\n\t}, [query, items.length]);\n\n\tconst close = useCallback(() => {\n\t\tsetOpen(false);\n\t}, []);\n\n\tconst middleware = useMemo(\n\t\t() => [\n\t\t\toffset(8),\n\t\t\tflip({ mainAxis: true, crossAxis: false }),\n\t\t\tshift({ padding: 8 }),\n\t\t\tsize({\n\t\t\t\tapply({ availableHeight, elements }) {\n\t\t\t\t\tconst next = Math.min(availableHeight, maxHeight);\n\n\t\t\t\t\telements.floating.style.setProperty(\n\t\t\t\t\t\t'--suggestion-menu-max-height',\n\t\t\t\t\t\t`${next}px`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t})\n\t\t],\n\t\t[maxHeight]\n\t);\n\n\tconst { setFloatingRef, style, getFloatingProps, isMounted } =\n\t\tuseFloatingElement(open, decorationNode, FLOATING_Z_INDEX, {\n\t\t\tplacement: 'bottom-start',\n\t\t\tmiddleware,\n\t\t\tonOpenChange: (next) => {\n\t\t\t\tif (!next) close();\n\t\t\t}\n\t\t});\n\n\t// Stable refs for the latest render-callback inputs (the suggestion plugin\n\t// is registered once per editor; we don't want to re-register every render).\n\tconst itemsFnRef = useRef(itemsFn);\n\tconst decorationClassRef = useRef(decorationClass);\n\tconst decorationContentRef = useRef(decorationContent);\n\n\tuseEffect(() => {\n\t\titemsFnRef.current = itemsFn;\n\t\tdecorationClassRef.current = decorationClass;\n\t\tdecorationContentRef.current = decorationContent;\n\t}, [itemsFn, decorationClass, decorationContent]);\n\n\tconst itemsRef = useRef<SuggestionItem[]>([]);\n\tconst selectedIndexRef = useRef(0);\n\n\tuseEffect(() => {\n\t\titemsRef.current = items;\n\t}, [items]);\n\n\tuseEffect(() => {\n\t\tselectedIndexRef.current = selectedIndex;\n\t}, [selectedIndex]);\n\n\tuseEffect(() => {\n\t\tif (!editor || editor.isDestroyed) return;\n\n\t\tconst key = new PluginKey(pluginKey);\n\n\t\tconst plugin = Suggestion<SuggestionItem>({\n\t\t\teditor,\n\t\t\tchar,\n\t\t\tpluginKey: key,\n\t\t\tdecorationClass: decorationClassRef.current,\n\t\t\tdecorationContent: decorationContentRef.current,\n\n\t\t\titems: ({ query, editor }) => itemsFnRef.current({ query, editor }),\n\n\t\t\tallow: ({ state, range }) => {\n\t\t\t\tconst $from = state.doc.resolve(range.from);\n\n\t\t\t\tfor (let depth = $from.depth; depth > 0; depth--) {\n\t\t\t\t\tconst name = $from.node(depth).type.name;\n\n\t\t\t\t\tif (name === 'image' || name === 'codeBlock') return false;\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\tcommand: ({ editor, range, props }) => {\n\t\t\t\teditor.chain().focus().deleteRange(range).run();\n\t\t\t\tprops.onSelect({ editor, range });\n\t\t\t},\n\n\t\t\trender: () => ({\n\t\t\t\tonStart: (props: SuggestionProps<SuggestionItem>) => {\n\t\t\t\t\tsetDecorationNode((props.decorationNode as HTMLElement) ?? null);\n\t\t\t\t\tsetItems(props.items);\n\t\t\t\t\tsetQuery(props.query);\n\t\t\t\t\tcommandRef.current = (item) => props.command(item);\n\t\t\t\t\tsetOpen(true);\n\t\t\t\t},\n\t\t\t\tonUpdate: (props: SuggestionProps<SuggestionItem>) => {\n\t\t\t\t\tsetDecorationNode((props.decorationNode as HTMLElement) ?? null);\n\t\t\t\t\tsetItems(props.items);\n\t\t\t\t\tsetQuery(props.query);\n\t\t\t\t\tcommandRef.current = (item) => props.command(item);\n\t\t\t\t},\n\t\t\t\tonKeyDown: ({ event }: SuggestionKeyDownProps) => {\n\t\t\t\t\tconst list = itemsRef.current;\n\n\t\t\t\t\tif (event.key === 'ArrowDown') {\n\t\t\t\t\t\tif (list.length > 0) {\n\t\t\t\t\t\t\tsetSelectedIndex((selectedIndexRef.current + 1) % list.length);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (event.key === 'ArrowUp') {\n\t\t\t\t\t\tif (list.length > 0) {\n\t\t\t\t\t\t\tsetSelectedIndex(\n\t\t\t\t\t\t\t\t(selectedIndexRef.current - 1 + list.length) % list.length\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (event.key === 'Enter') {\n\t\t\t\t\t\tconst item = list[selectedIndexRef.current];\n\n\t\t\t\t\t\tif (item && commandRef.current) {\n\t\t\t\t\t\t\tcommandRef.current(item);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (event.key === 'Escape') {\n\t\t\t\t\t\tclose();\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\t\t\t\tonExit: () => {\n\t\t\t\t\tsetDecorationNode(null);\n\t\t\t\t\tsetItems([]);\n\t\t\t\t\tsetQuery('');\n\t\t\t\t\tcommandRef.current = null;\n\t\t\t\t\tsetOpen(false);\n\t\t\t\t}\n\t\t\t})\n\t\t});\n\n\t\teditor.registerPlugin(plugin);\n\n\t\treturn () => {\n\t\t\tif (!editor.isDestroyed) {\n\t\t\t\teditor.unregisterPlugin(key);\n\t\t\t}\n\t\t};\n\t}, [editor, char, pluginKey, close]);\n\n\tconst handleSelect = useCallback((item: SuggestionItem) => {\n\t\tif (commandRef.current) {\n\t\t\tcommandRef.current(item);\n\t\t}\n\t}, []);\n\n\tif (!isMounted || !open) return null;\n\n\treturn (\n\t\t<div\n\t\t\tref={setFloatingRef}\n\t\t\taria-label=\"Suggestions\"\n\t\t\tclassName=\"notra-suggestion-menu\"\n\t\t\tdata-selector={selector}\n\t\t\trole=\"listbox\"\n\t\t\tstyle={style}\n\t\t\t{...getFloatingProps()}\n\t\t\tonPointerDown={(e) => e.preventDefault()}\n\t\t>\n\t\t\t{children({ items, selectedIndex, onSelect: handleSelect })}\n\t\t</div>\n\t);\n}\n"],"mappings":"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","names":["import_react","query","editor"]}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { SuggestionItem } from './suggestion-menu-types.cjs';
|
|
3
|
-
import { Editor } from '@tiptap/react';
|
|
4
|
-
import { ReactNode } from 'react';
|
|
5
|
-
|
|
6
|
-
interface SuggestionMenuRenderProps {
|
|
7
|
-
items: SuggestionItem[];
|
|
8
|
-
selectedIndex: number;
|
|
9
|
-
onSelect: (item: SuggestionItem) => void;
|
|
10
|
-
}
|
|
11
|
-
interface SuggestionMenuProps {
|
|
12
|
-
editor: Editor | null;
|
|
13
|
-
char: string;
|
|
14
|
-
pluginKey: string;
|
|
15
|
-
items: (ctx: {
|
|
16
|
-
query: string;
|
|
17
|
-
editor: Editor;
|
|
18
|
-
}) => SuggestionItem[];
|
|
19
|
-
decorationClass?: string;
|
|
20
|
-
decorationContent?: string;
|
|
21
|
-
selector?: string;
|
|
22
|
-
maxHeight?: number;
|
|
23
|
-
children: (renderProps: SuggestionMenuRenderProps) => ReactNode;
|
|
24
|
-
}
|
|
25
|
-
declare function SuggestionMenu({ editor, char, pluginKey, items: itemsFn, decorationClass, decorationContent, selector, maxHeight, children }: SuggestionMenuProps): react_jsx_runtime.JSX.Element | null;
|
|
26
|
-
|
|
27
|
-
export { SuggestionMenu, type SuggestionMenuProps, type SuggestionMenuRenderProps };
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { SuggestionItem } from './suggestion-menu-types.js';
|
|
3
|
-
import { Editor } from '@tiptap/react';
|
|
4
|
-
import { ReactNode } from 'react';
|
|
5
|
-
|
|
6
|
-
interface SuggestionMenuRenderProps {
|
|
7
|
-
items: SuggestionItem[];
|
|
8
|
-
selectedIndex: number;
|
|
9
|
-
onSelect: (item: SuggestionItem) => void;
|
|
10
|
-
}
|
|
11
|
-
interface SuggestionMenuProps {
|
|
12
|
-
editor: Editor | null;
|
|
13
|
-
char: string;
|
|
14
|
-
pluginKey: string;
|
|
15
|
-
items: (ctx: {
|
|
16
|
-
query: string;
|
|
17
|
-
editor: Editor;
|
|
18
|
-
}) => SuggestionItem[];
|
|
19
|
-
decorationClass?: string;
|
|
20
|
-
decorationContent?: string;
|
|
21
|
-
selector?: string;
|
|
22
|
-
maxHeight?: number;
|
|
23
|
-
children: (renderProps: SuggestionMenuRenderProps) => ReactNode;
|
|
24
|
-
}
|
|
25
|
-
declare function SuggestionMenu({ editor, char, pluginKey, items: itemsFn, decorationClass, decorationContent, selector, maxHeight, children }: SuggestionMenuProps): react_jsx_runtime.JSX.Element | null;
|
|
26
|
-
|
|
27
|
-
export { SuggestionMenu, type SuggestionMenuProps, type SuggestionMenuRenderProps };
|