@copilotkit/react-textarea 0.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.
Files changed (140) hide show
  1. package/.turbo/turbo-build.log +133 -0
  2. package/CHANGELOG.md +50 -0
  3. package/dist/chunk-4LJAS777.mjs +10 -0
  4. package/dist/chunk-4LJAS777.mjs.map +1 -0
  5. package/dist/chunk-5SJM4R4K.mjs +10 -0
  6. package/dist/chunk-5SJM4R4K.mjs.map +1 -0
  7. package/dist/chunk-ETGKLURC.mjs +27 -0
  8. package/dist/chunk-ETGKLURC.mjs.map +1 -0
  9. package/dist/chunk-GOAPCQCR.mjs +124 -0
  10. package/dist/chunk-GOAPCQCR.mjs.map +1 -0
  11. package/dist/chunk-H4VKQGVU.mjs +3 -0
  12. package/dist/chunk-H4VKQGVU.mjs.map +1 -0
  13. package/dist/chunk-IU3WTXLQ.mjs +3 -0
  14. package/dist/chunk-IU3WTXLQ.mjs.map +1 -0
  15. package/dist/chunk-JD7BAH7U.mjs +3 -0
  16. package/dist/chunk-JD7BAH7U.mjs.map +1 -0
  17. package/dist/chunk-JJASB23A.mjs +88 -0
  18. package/dist/chunk-JJASB23A.mjs.map +1 -0
  19. package/dist/chunk-KCHYD3EB.mjs +107 -0
  20. package/dist/chunk-KCHYD3EB.mjs.map +1 -0
  21. package/dist/chunk-KGKLUWKW.mjs +47 -0
  22. package/dist/chunk-KGKLUWKW.mjs.map +1 -0
  23. package/dist/chunk-KKG2RK2T.mjs +16 -0
  24. package/dist/chunk-KKG2RK2T.mjs.map +1 -0
  25. package/dist/chunk-L24ZN4LL.mjs +65 -0
  26. package/dist/chunk-L24ZN4LL.mjs.map +1 -0
  27. package/dist/chunk-MRXNTQOX.mjs +55 -0
  28. package/dist/chunk-MRXNTQOX.mjs.map +1 -0
  29. package/dist/chunk-NKW5OU2S.mjs +33 -0
  30. package/dist/chunk-NKW5OU2S.mjs.map +1 -0
  31. package/dist/chunk-RVJAOO4S.mjs +18 -0
  32. package/dist/chunk-RVJAOO4S.mjs.map +1 -0
  33. package/dist/chunk-TSF4AJIK.mjs +30 -0
  34. package/dist/chunk-TSF4AJIK.mjs.map +1 -0
  35. package/dist/chunk-X4FJ6WVZ.mjs +66 -0
  36. package/dist/chunk-X4FJ6WVZ.mjs.map +1 -0
  37. package/dist/chunk-Y5BUWZOI.mjs +37 -0
  38. package/dist/chunk-Y5BUWZOI.mjs.map +1 -0
  39. package/dist/chunk-YPBKY4KY.mjs +3 -0
  40. package/dist/chunk-YPBKY4KY.mjs.map +1 -0
  41. package/dist/components/copilot-textarea/base-copilot-textarea/base-copilot-textarea.d.ts +18 -0
  42. package/dist/components/copilot-textarea/base-copilot-textarea/base-copilot-textarea.mjs +17 -0
  43. package/dist/components/copilot-textarea/base-copilot-textarea/base-copilot-textarea.mjs.map +1 -0
  44. package/dist/components/copilot-textarea/base-copilot-textarea/render-element.d.ts +6 -0
  45. package/dist/components/copilot-textarea/base-copilot-textarea/render-element.mjs +4 -0
  46. package/dist/components/copilot-textarea/base-copilot-textarea/render-element.mjs.map +1 -0
  47. package/dist/components/copilot-textarea/base-copilot-textarea/render-placeholder.d.ts +6 -0
  48. package/dist/components/copilot-textarea/base-copilot-textarea/render-placeholder.mjs +4 -0
  49. package/dist/components/copilot-textarea/base-copilot-textarea/render-placeholder.mjs.map +1 -0
  50. package/dist/components/index.d.ts +4 -0
  51. package/dist/components/index.mjs +18 -0
  52. package/dist/components/index.mjs.map +1 -0
  53. package/dist/context/index.d.ts +1 -0
  54. package/dist/context/index.mjs +3 -0
  55. package/dist/context/index.mjs.map +1 -0
  56. package/dist/hooks/index.d.ts +1 -0
  57. package/dist/hooks/index.mjs +3 -0
  58. package/dist/hooks/index.mjs.map +1 -0
  59. package/dist/hooks/use-autosuggestions.d.ts +13 -0
  60. package/dist/hooks/use-autosuggestions.mjs +7 -0
  61. package/dist/hooks/use-autosuggestions.mjs.map +1 -0
  62. package/dist/hooks/use-copilot-textarea-editor.d.ts +8 -0
  63. package/dist/hooks/use-copilot-textarea-editor.mjs +5 -0
  64. package/dist/hooks/use-copilot-textarea-editor.mjs.map +1 -0
  65. package/dist/index.css +340 -0
  66. package/dist/index.css.map +1 -0
  67. package/dist/index.d.ts +4 -0
  68. package/dist/index.mjs +21 -0
  69. package/dist/index.mjs.map +1 -0
  70. package/dist/lib/debouncer.d.ts +11 -0
  71. package/dist/lib/debouncer.mjs +4 -0
  72. package/dist/lib/debouncer.mjs.map +1 -0
  73. package/dist/lib/editor-to-text.d.ts +7 -0
  74. package/dist/lib/editor-to-text.mjs +45 -0
  75. package/dist/lib/editor-to-text.mjs.map +1 -0
  76. package/dist/lib/get-text-around-cursor.d.ts +8 -0
  77. package/dist/lib/get-text-around-cursor.mjs +4 -0
  78. package/dist/lib/get-text-around-cursor.mjs.map +1 -0
  79. package/dist/lib/slatejs-edits/add-autocompletions.d.ts +8 -0
  80. package/dist/lib/slatejs-edits/add-autocompletions.mjs +4 -0
  81. package/dist/lib/slatejs-edits/add-autocompletions.mjs.map +1 -0
  82. package/dist/lib/slatejs-edits/clear-autocompletions.d.ts +8 -0
  83. package/dist/lib/slatejs-edits/clear-autocompletions.mjs +4 -0
  84. package/dist/lib/slatejs-edits/clear-autocompletions.mjs.map +1 -0
  85. package/dist/lib/slatejs-edits/replace-text.d.ts +5 -0
  86. package/dist/lib/slatejs-edits/replace-text.mjs +4 -0
  87. package/dist/lib/slatejs-edits/replace-text.mjs.map +1 -0
  88. package/dist/lib/slatejs-edits/with-partial-history.d.ts +10 -0
  89. package/dist/lib/slatejs-edits/with-partial-history.mjs +4 -0
  90. package/dist/lib/slatejs-edits/with-partial-history.mjs.map +1 -0
  91. package/dist/lib/utils.d.ts +10 -0
  92. package/dist/lib/utils.mjs +4 -0
  93. package/dist/lib/utils.mjs.map +1 -0
  94. package/dist/types/autosuggestion-state.d.ts +8 -0
  95. package/dist/types/autosuggestion-state.mjs +3 -0
  96. package/dist/types/autosuggestion-state.mjs.map +1 -0
  97. package/dist/types/autosuggestions-bare-function.d.ts +3 -0
  98. package/dist/types/autosuggestions-bare-function.mjs +3 -0
  99. package/dist/types/autosuggestions-bare-function.mjs.map +1 -0
  100. package/dist/types/base-autosuggestions-config.d.ts +9 -0
  101. package/dist/types/base-autosuggestions-config.mjs +4 -0
  102. package/dist/types/base-autosuggestions-config.mjs.map +1 -0
  103. package/dist/types/custom-editor.d.ts +29 -0
  104. package/dist/types/custom-editor.mjs +3 -0
  105. package/dist/types/custom-editor.mjs.map +1 -0
  106. package/dist/types/editor-autocomplete-state.d.ts +10 -0
  107. package/dist/types/editor-autocomplete-state.mjs +5 -0
  108. package/dist/types/editor-autocomplete-state.mjs.map +1 -0
  109. package/dist/types/index.d.ts +2 -0
  110. package/dist/types/index.mjs +5 -0
  111. package/dist/types/index.mjs.map +1 -0
  112. package/package.json +53 -0
  113. package/postcss.config.js +9 -0
  114. package/src/components/copilot-textarea/base-copilot-textarea/base-copilot-textarea.tsx +175 -0
  115. package/src/components/copilot-textarea/base-copilot-textarea/render-element.tsx +42 -0
  116. package/src/components/copilot-textarea/base-copilot-textarea/render-placeholder.tsx +25 -0
  117. package/src/components/index.ts +2 -0
  118. package/src/context/index.ts +1 -0
  119. package/src/hooks/index.ts +1 -0
  120. package/src/hooks/use-autosuggestions.ts +129 -0
  121. package/src/hooks/use-copilot-textarea-editor.tsx +104 -0
  122. package/src/index.tsx +7 -0
  123. package/src/lib/debouncer.ts +38 -0
  124. package/src/lib/editor-to-text.ts +64 -0
  125. package/src/lib/get-text-around-cursor.ts +82 -0
  126. package/src/lib/slatejs-edits/add-autocompletions.ts +30 -0
  127. package/src/lib/slatejs-edits/clear-autocompletions.ts +15 -0
  128. package/src/lib/slatejs-edits/replace-text.ts +32 -0
  129. package/src/lib/slatejs-edits/with-partial-history.ts +156 -0
  130. package/src/lib/utils.ts +59 -0
  131. package/src/styles.css +3 -0
  132. package/src/types/autosuggestion-state.ts +6 -0
  133. package/src/types/autosuggestions-bare-function.ts +5 -0
  134. package/src/types/base-autosuggestions-config.tsx +15 -0
  135. package/src/types/custom-editor.tsx +29 -0
  136. package/src/types/editor-autocomplete-state.ts +19 -0
  137. package/src/types/index.ts +4 -0
  138. package/tailwind.config.js +7 -0
  139. package/tsconfig.json +5 -0
  140. package/tsup.config.ts +12 -0
@@ -0,0 +1,64 @@
1
+ import { BaseEditor, Descendant, Element } from "slate";
2
+ import { HistoryEditor } from "slate-history";
3
+ import { ReactEditor } from "slate-react";
4
+ import { SuggestionAwareText } from "../types/custom-editor";
5
+
6
+ function nodeChildrenToTextComponents(
7
+ editor: BaseEditor & ReactEditor & HistoryEditor,
8
+ nodes: Descendant[]
9
+ ): SuggestionAwareText[] {
10
+ // find inlineable elements
11
+ const indeciesOfInlineElements = new Set(
12
+ nodes
13
+ .map((node, index) => {
14
+ if (Element.isElement(node) && editor.isInline(node)) {
15
+ return index;
16
+ }
17
+ return -1;
18
+ })
19
+ .filter((index) => index !== -1)
20
+ );
21
+
22
+ // ignorable elements = inline elements,
23
+ // or neighbors of inline elements that are {text: ""}
24
+ const nonIgnorableItems = nodes.filter((node, index) => {
25
+ const isInline = indeciesOfInlineElements.has(index);
26
+ if (isInline) {
27
+ return false;
28
+ }
29
+
30
+ const isNeighbourOfInline =
31
+ indeciesOfInlineElements.has(index - 1) ||
32
+ indeciesOfInlineElements.has(index + 1);
33
+ if (isNeighbourOfInline) {
34
+ return (node as any).text !== "";
35
+ }
36
+
37
+ return true;
38
+ });
39
+
40
+ return nonIgnorableItems
41
+ .map((node) => {
42
+ if (Element.isElement(node)) {
43
+ switch (node.type) {
44
+ case "paragraph":
45
+ return nodeChildrenToTextComponents(editor, node.children);
46
+ case "suggestion":
47
+ return [];
48
+ }
49
+ } else {
50
+ return [node];
51
+ }
52
+ })
53
+ .reduce((acc, val) => acc.concat(val), []);
54
+ }
55
+
56
+ export const editorToText = (
57
+ editor: BaseEditor & ReactEditor & HistoryEditor
58
+ ) => {
59
+ const flattened = nodeChildrenToTextComponents(editor, editor.children);
60
+
61
+ const text = flattened.map((textComponent) => textComponent.text).join("\n");
62
+
63
+ return text;
64
+ };
@@ -0,0 +1,82 @@
1
+ import { Editor, Node, Path, Range, Text, Element } from "slate";
2
+ import { EditorAutocompleteState } from "../types/editor-autocomplete-state";
3
+
4
+ export function getTextAroundCursor(
5
+ editor: Editor
6
+ ): EditorAutocompleteState | null {
7
+ const { selection } = editor;
8
+
9
+ if (!selection || !Range.isCollapsed(selection)) {
10
+ return null;
11
+ }
12
+ // Create two ranges: one before the anchor and one after
13
+ const beforeRange: Range = {
14
+ anchor: Editor.start(editor, []),
15
+ focus: selection.anchor,
16
+ };
17
+ const afterRange: Range = {
18
+ anchor: selection.anchor,
19
+ focus: Editor.end(editor, []),
20
+ };
21
+
22
+ // Extract text for these ranges
23
+ const before = extractTextWithNewlines(editor, beforeRange);
24
+ const after = extractTextWithNewlines(editor, afterRange);
25
+
26
+ return {
27
+ cursorPoint: selection.anchor,
28
+ textBeforeCursor: before,
29
+ textAfterCursor: after,
30
+ };
31
+ }
32
+
33
+ export function getFullEditorTextWithNewlines(editor: Editor): string {
34
+ const fullDocumentRange: Range = {
35
+ anchor: Editor.start(editor, []),
36
+ focus: Editor.end(editor, []),
37
+ };
38
+ return extractTextWithNewlines(editor, fullDocumentRange);
39
+ }
40
+
41
+ // Helper function to extract text with newlines
42
+ export function extractTextWithNewlines(editor: Editor, range: Range): string {
43
+ const voids = false;
44
+ const [start, end] = Range.edges(range);
45
+ let text = "";
46
+ let lastBlock: Node | null = null;
47
+
48
+ for (const [node, path] of Editor.nodes(editor, {
49
+ at: range,
50
+ match: Text.isText,
51
+ voids,
52
+ })) {
53
+ let t = node.text;
54
+
55
+ // Determine the parent block of the current text node
56
+ const [block] = Editor.above(editor, {
57
+ at: path,
58
+ match: (n) => Element.isElement(n) && n.type === "paragraph",
59
+ }) || [null];
60
+
61
+ // If we encounter a new block, prepend a newline
62
+ if (lastBlock !== block && block) {
63
+ // check that lastBlock is not null to avoid adding a newline at the beginning
64
+ if (lastBlock) {
65
+ text += "\n";
66
+ }
67
+ lastBlock = block;
68
+ }
69
+
70
+ if (Path.equals(path, end.path)) {
71
+ t = t.slice(0, end.offset);
72
+ }
73
+
74
+ if (Path.equals(path, start.path)) {
75
+ t = t.slice(start.offset);
76
+ }
77
+
78
+ text += t;
79
+ }
80
+
81
+ return text;
82
+ }
@@ -0,0 +1,30 @@
1
+ import { BasePoint, Transforms } from "slate";
2
+ import { CustomEditor } from "../../types/custom-editor";
3
+
4
+ export function addAutocompletionsToEditor(
5
+ editor: CustomEditor,
6
+ newSuggestion: string,
7
+ point: BasePoint
8
+ ) {
9
+ const editorPosition = editor.selection;
10
+
11
+ Transforms.insertNodes(
12
+ editor,
13
+ [
14
+ {
15
+ type: "suggestion",
16
+ inline: true,
17
+ content: newSuggestion,
18
+ children: [{ text: "" }],
19
+ },
20
+ ],
21
+ {
22
+ at: point,
23
+ }
24
+ );
25
+
26
+ // restore cursor position
27
+ if (editorPosition) {
28
+ editor.selection = editorPosition;
29
+ }
30
+ }
@@ -0,0 +1,15 @@
1
+ import { Path, Node, Element, Transforms } from "slate";
2
+ import { CustomEditor } from "../../types/custom-editor";
3
+
4
+ export function clearAutocompletionsFromEditor(editor: CustomEditor) {
5
+ // clear previous suggestion
6
+ const paths: Path[] = [];
7
+ for (const [node, path] of Node.nodes(editor)) {
8
+ if (Element.isElement(node) && node.type === "suggestion") {
9
+ paths.push(path);
10
+ }
11
+ }
12
+ for (const path of paths) {
13
+ Transforms.removeNodes(editor, { at: path });
14
+ }
15
+ }
@@ -0,0 +1,32 @@
1
+ import { Editor, Path, Transforms, Node, Element } from "slate";
2
+
3
+ export function replaceEditorText(editor: Editor, newText: string) {
4
+ // clear all previous text
5
+ const paths: Path[] = [];
6
+ for (const [node, path] of Node.nodes(editor)) {
7
+ if (
8
+ Element.isElement(node) &&
9
+ (node.type === "paragraph" || node.type === "suggestion") &&
10
+ path.length === 1
11
+ ) {
12
+ paths.push(path);
13
+ }
14
+ }
15
+ for (const path of paths) {
16
+ Transforms.removeNodes(editor, { at: path });
17
+ }
18
+
19
+ // insert new text
20
+ Transforms.insertNodes(
21
+ editor,
22
+ [
23
+ {
24
+ type: "paragraph",
25
+ children: [{ text: newText }],
26
+ },
27
+ ],
28
+ {
29
+ at: [0],
30
+ }
31
+ );
32
+ }
@@ -0,0 +1,156 @@
1
+ import { Editor, Operation, Path, Range, Transforms } from "slate";
2
+ import { HistoryEditor } from "slate-history";
3
+
4
+ // Copy-pasted from `https://github.com/ianstormtaylor/slate/blob/main/packages/slate-history/src/with-history.ts`
5
+ // With one exception: the `shouldSave` function is passed in as an argument to `withPartialHistory` instead of being hardcoded
6
+ export type ShouldSaveToHistory = (
7
+ op: Operation,
8
+ prev: Operation | undefined
9
+ ) => boolean;
10
+
11
+ export const withPartialHistory = <T extends Editor>(
12
+ editor: T,
13
+ shouldSave: ShouldSaveToHistory
14
+ ) => {
15
+ const e = editor as T & HistoryEditor;
16
+ const { apply } = e;
17
+ e.history = { undos: [], redos: [] };
18
+
19
+ e.redo = () => {
20
+ const { history } = e;
21
+ const { redos } = history;
22
+
23
+ if (redos.length > 0) {
24
+ const batch = redos[redos.length - 1];
25
+
26
+ if (batch.selectionBefore) {
27
+ Transforms.setSelection(e, batch.selectionBefore);
28
+ }
29
+
30
+ HistoryEditor.withoutSaving(e, () => {
31
+ Editor.withoutNormalizing(e, () => {
32
+ for (const op of batch.operations) {
33
+ e.apply(op);
34
+ }
35
+ });
36
+ });
37
+
38
+ history.redos.pop();
39
+ e.writeHistory("undos", batch);
40
+ }
41
+ };
42
+
43
+ e.undo = () => {
44
+ const { history } = e;
45
+ const { undos } = history;
46
+
47
+ if (undos.length > 0) {
48
+ const batch = undos[undos.length - 1];
49
+
50
+ HistoryEditor.withoutSaving(e, () => {
51
+ Editor.withoutNormalizing(e, () => {
52
+ const inverseOps = batch.operations.map(Operation.inverse).reverse();
53
+
54
+ for (const op of inverseOps) {
55
+ e.apply(op);
56
+ }
57
+ if (batch.selectionBefore) {
58
+ Transforms.setSelection(e, batch.selectionBefore);
59
+ }
60
+ });
61
+ });
62
+
63
+ e.writeHistory("redos", batch);
64
+ history.undos.pop();
65
+ }
66
+ };
67
+
68
+ e.apply = (op: Operation) => {
69
+ const { operations, history } = e;
70
+ const { undos } = history;
71
+ const lastBatch = undos[undos.length - 1];
72
+ const lastOp =
73
+ lastBatch && lastBatch.operations[lastBatch.operations.length - 1];
74
+ let save = HistoryEditor.isSaving(e);
75
+ let merge = HistoryEditor.isMerging(e);
76
+
77
+ if (save == null) {
78
+ save = shouldSave(op, lastOp);
79
+ }
80
+
81
+ if (save) {
82
+ if (merge == null) {
83
+ if (lastBatch == null) {
84
+ merge = false;
85
+ } else if (operations.length !== 0) {
86
+ merge = true;
87
+ } else {
88
+ merge = shouldMerge(op, lastOp);
89
+ }
90
+ }
91
+
92
+ if (lastBatch && merge) {
93
+ lastBatch.operations.push(op);
94
+ } else {
95
+ const batch = {
96
+ operations: [op],
97
+ selectionBefore: e.selection,
98
+ };
99
+ e.writeHistory("undos", batch);
100
+ }
101
+
102
+ while (undos.length > 100) {
103
+ undos.shift();
104
+ }
105
+
106
+ history.redos = [];
107
+ }
108
+
109
+ apply(op);
110
+ };
111
+
112
+ e.writeHistory = (stack: "undos" | "redos", batch: any) => {
113
+ e.history[stack].push(batch);
114
+ };
115
+
116
+ return e;
117
+ };
118
+
119
+ /**
120
+ * Check whether to merge an operation into the previous operation.
121
+ */
122
+
123
+ const shouldMerge = (op: Operation, prev: Operation | undefined): boolean => {
124
+ if (
125
+ prev &&
126
+ op.type === "insert_text" &&
127
+ prev.type === "insert_text" &&
128
+ op.offset === prev.offset + prev.text.length &&
129
+ Path.equals(op.path, prev.path)
130
+ ) {
131
+ return true;
132
+ }
133
+
134
+ if (
135
+ prev &&
136
+ op.type === "remove_text" &&
137
+ prev.type === "remove_text" &&
138
+ op.offset + op.text.length === prev.offset &&
139
+ Path.equals(op.path, prev.path)
140
+ ) {
141
+ return true;
142
+ }
143
+
144
+ return false;
145
+ };
146
+
147
+ export const defaultShouldSave = (
148
+ op: Operation,
149
+ prev: Operation | undefined
150
+ ): boolean => {
151
+ if (op.type === "set_selection") {
152
+ return false;
153
+ }
154
+
155
+ return true;
156
+ };
@@ -0,0 +1,59 @@
1
+ import { clsx, type ClassValue } from "clsx";
2
+ import { customAlphabet } from "nanoid";
3
+ import { twMerge } from "tailwind-merge";
4
+
5
+ export function cn(...inputs: ClassValue[]) {
6
+ return twMerge(clsx(inputs));
7
+ }
8
+
9
+ export const nanoid = customAlphabet(
10
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
11
+ 7
12
+ ); // 7-character random string
13
+
14
+ export async function fetcher<JSON = any>(
15
+ input: RequestInfo,
16
+ init?: RequestInit
17
+ ): Promise<JSON> {
18
+ const res = await fetch(input, init);
19
+
20
+ if (!res.ok) {
21
+ const json = await res.json();
22
+ if (json.error) {
23
+ const error = new Error(json.error) as Error & {
24
+ status: number;
25
+ };
26
+ error.status = res.status;
27
+ throw error;
28
+ } else {
29
+ throw new Error("An unexpected error occurred");
30
+ }
31
+ }
32
+
33
+ return res.json();
34
+ }
35
+
36
+ export function formatDate(input: string | number | Date): string {
37
+ const date = new Date(input);
38
+ return date.toLocaleDateString("en-US", {
39
+ month: "long",
40
+ day: "numeric",
41
+ year: "numeric",
42
+ });
43
+ }
44
+
45
+ export const arraysAreEqual = (arr1: number[], arr2: number[]): boolean =>
46
+ arr1.length === arr2.length &&
47
+ arr1.every((value, index) => value === arr2[index]);
48
+
49
+ export function nullableCompatibleEqualityCheck<T>(
50
+ naiveEqualityCheck: (a: T, b: T) => boolean,
51
+ a: T | null | undefined,
52
+ b: T | null | undefined
53
+ ): boolean {
54
+ if (a === null || a === undefined || b === null || b === undefined) {
55
+ return a === b;
56
+ }
57
+
58
+ return naiveEqualityCheck(a, b);
59
+ }
package/src/styles.css ADDED
@@ -0,0 +1,3 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
@@ -0,0 +1,6 @@
1
+ import { BasePoint } from "slate";
2
+
3
+ export interface AutosuggestionState {
4
+ text: string;
5
+ point: BasePoint;
6
+ }
@@ -0,0 +1,5 @@
1
+ export type AutosuggestionsBareFunction = (
2
+ textBefore: string,
3
+ textAfter: string,
4
+ abortSignal: AbortSignal
5
+ ) => Promise<string>;
@@ -0,0 +1,15 @@
1
+ export interface BaseAutosuggestionsConfig {
2
+ purposePrompt: string;
3
+ debounceTime: number;
4
+ acceptAutosuggestionKey: string;
5
+ disableWhenEmpty: boolean;
6
+ }
7
+
8
+ export const defaultBaseAutosuggestionsConfig: Omit<
9
+ BaseAutosuggestionsConfig,
10
+ "purposePrompt"
11
+ > = {
12
+ debounceTime: 500,
13
+ acceptAutosuggestionKey: "Tab",
14
+ disableWhenEmpty: true,
15
+ };
@@ -0,0 +1,29 @@
1
+ import { BaseEditor } from "slate";
2
+ import { ReactEditor } from "slate-react";
3
+ import { HistoryEditor } from "slate-history";
4
+
5
+ export type CustomEditor = BaseEditor & ReactEditor & HistoryEditor;
6
+
7
+ export type ParagraphElement = {
8
+ type: "paragraph";
9
+ children: CustomText[];
10
+ };
11
+
12
+ export type SuggestionElement = {
13
+ type: "suggestion";
14
+ inline: boolean;
15
+ content: string;
16
+ children: CustomText[];
17
+ };
18
+
19
+ export type CustomElement = ParagraphElement | SuggestionElement;
20
+ export type SuggestionAwareText = { text: string };
21
+ export type CustomText = SuggestionAwareText;
22
+
23
+ declare module "slate" {
24
+ interface CustomTypes {
25
+ Editor: CustomEditor;
26
+ Element: CustomElement;
27
+ Text: CustomText;
28
+ }
29
+ }
@@ -0,0 +1,19 @@
1
+ import { BasePoint } from "slate";
2
+ import { arraysAreEqual } from "../lib/utils";
3
+
4
+ export interface EditorAutocompleteState {
5
+ cursorPoint: BasePoint;
6
+ textBeforeCursor: string;
7
+ textAfterCursor: string;
8
+ }
9
+ export function areEqual_autocompleteState(
10
+ prev: EditorAutocompleteState,
11
+ next: EditorAutocompleteState
12
+ ) {
13
+ return (
14
+ prev.cursorPoint.offset === next.cursorPoint.offset &&
15
+ arraysAreEqual(prev.cursorPoint.path, next.cursorPoint.path) &&
16
+ prev.textBeforeCursor === next.textBeforeCursor &&
17
+ prev.textAfterCursor === next.textAfterCursor
18
+ );
19
+ }
@@ -0,0 +1,4 @@
1
+ export { defaultBaseAutosuggestionsConfig } from "./base-autosuggestions-config";
2
+
3
+ export type { BaseAutosuggestionsConfig } from "./base-autosuggestions-config";
4
+ export type { AutosuggestionsBareFunction } from "./autosuggestions-bare-function";
@@ -0,0 +1,7 @@
1
+ const sharedConfig = require("tailwind-config/tailwind.config.js");
2
+
3
+ module.exports = {
4
+ // prefix ui lib classes to avoid conflicting with the app
5
+ // prefix: "ui-",
6
+ presets: [sharedConfig],
7
+ };
package/tsconfig.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": "tsconfig/react-library.json",
3
+ "include": ["."],
4
+ "exclude": ["dist", "build", "node_modules"],
5
+ }
package/tsup.config.ts ADDED
@@ -0,0 +1,12 @@
1
+ import { defineConfig, Options } from "tsup";
2
+
3
+ export default defineConfig((options: Options) => ({
4
+ entry: ["src/**/*.{ts,tsx}"],
5
+ format: ["esm"],
6
+ dts: true,
7
+ minify: false,
8
+ clean: true,
9
+ external: ["react"],
10
+ sourcemap: true,
11
+ ...options,
12
+ }));