@fluentui-copilot/react-editor-input 0.1.4 → 0.2.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 (44) hide show
  1. package/CHANGELOG.json +65 -1
  2. package/CHANGELOG.md +26 -2
  3. package/dist/index.d.ts +14 -7
  4. package/lib/components/EditorInput/EditorInput.js +3 -2
  5. package/lib/components/EditorInput/EditorInput.js.map +1 -1
  6. package/lib/components/EditorInput/EditorInput.types.js +1 -3
  7. package/lib/components/EditorInput/EditorInput.types.js.map +1 -1
  8. package/lib/components/EditorInput/index.js +1 -0
  9. package/lib/components/EditorInput/index.js.map +1 -1
  10. package/lib/components/EditorInput/renderEditorInput.js +10 -12
  11. package/lib/components/EditorInput/renderEditorInput.js.map +1 -1
  12. package/lib/components/EditorInput/useEditorInput.js +18 -58
  13. package/lib/components/EditorInput/useEditorInput.js.map +1 -1
  14. package/lib/components/EditorInput/useEditorInputContextValues.js +16 -0
  15. package/lib/components/EditorInput/useEditorInputContextValues.js.map +1 -0
  16. package/lib/components/EditorInput/useEditorInputStyles.styles.js +13 -14
  17. package/lib/components/EditorInput/useEditorInputStyles.styles.js.map +1 -1
  18. package/lib/index.js +1 -1
  19. package/lib/index.js.map +1 -1
  20. package/lib/utilities/useLexicalContentEditable.js +68 -0
  21. package/lib/utilities/useLexicalContentEditable.js.map +1 -0
  22. package/lib/utilities/useLexicalEditor.js +75 -0
  23. package/lib/utilities/useLexicalEditor.js.map +1 -0
  24. package/lib-commonjs/components/EditorInput/EditorInput.js +3 -1
  25. package/lib-commonjs/components/EditorInput/EditorInput.js.map +1 -1
  26. package/lib-commonjs/components/EditorInput/EditorInput.types.js +1 -3
  27. package/lib-commonjs/components/EditorInput/EditorInput.types.js.map +1 -1
  28. package/lib-commonjs/components/EditorInput/index.js +1 -0
  29. package/lib-commonjs/components/EditorInput/index.js.map +1 -1
  30. package/lib-commonjs/components/EditorInput/renderEditorInput.js +10 -11
  31. package/lib-commonjs/components/EditorInput/renderEditorInput.js.map +1 -1
  32. package/lib-commonjs/components/EditorInput/useEditorInput.js +10 -72
  33. package/lib-commonjs/components/EditorInput/useEditorInput.js.map +1 -1
  34. package/lib-commonjs/components/EditorInput/useEditorInputContextValues.js +27 -0
  35. package/lib-commonjs/components/EditorInput/useEditorInputContextValues.js.map +1 -0
  36. package/lib-commonjs/components/EditorInput/useEditorInputStyles.styles.js +19 -24
  37. package/lib-commonjs/components/EditorInput/useEditorInputStyles.styles.js.map +1 -1
  38. package/lib-commonjs/index.js +3 -0
  39. package/lib-commonjs/index.js.map +1 -1
  40. package/lib-commonjs/utilities/useLexicalContentEditable.js +87 -0
  41. package/lib-commonjs/utilities/useLexicalContentEditable.js.map +1 -0
  42. package/lib-commonjs/utilities/useLexicalEditor.js +74 -0
  43. package/lib-commonjs/utilities/useLexicalEditor.js.map +1 -0
  44. package/package.json +7 -7
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "useLexicalContentEditable", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return useLexicalContentEditable;
9
+ }
10
+ });
11
+ const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
12
+ const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
13
+ const _chatinputplugins = require("@fluentui-copilot/chat-input-plugins");
14
+ const _reacttexteditor = require("@fluentui-copilot/react-text-editor");
15
+ const _reactutilities = require("@fluentui/react-utilities");
16
+ const _EditorInput = require("../EditorInput");
17
+ const _useLexicalEditor = require("./useLexicalEditor");
18
+ function $insertString(text) {
19
+ const paragraphNode = (0, _reacttexteditor.$createParagraphNode)();
20
+ const textNode = (0, _reacttexteditor.$createTextNode)(text);
21
+ paragraphNode.append(textNode);
22
+ (0, _reacttexteditor.$insertNodes)([
23
+ paragraphNode
24
+ ]);
25
+ }
26
+ function useLexicalContentEditable(props) {
27
+ const { defaultValue } = props;
28
+ const customNodes = props.customNodes ? [
29
+ ...props.customNodes,
30
+ _chatinputplugins.SentinelNode
31
+ ] : [
32
+ _chatinputplugins.SentinelNode
33
+ ];
34
+ // The disabled state can also be changed by lexical (e.g. by a custom plugin) so
35
+ // we use `useControllableState` to coordinate
36
+ const [disabled, setDisabled] = (0, _reactutilities.useControllableState)({
37
+ state: props.disabled,
38
+ initialState: false
39
+ });
40
+ const editorState = typeof defaultValue === 'string' ? ()=>{
41
+ $insertString(defaultValue);
42
+ } : defaultValue;
43
+ const lexicalStyles = (0, _EditorInput.useLexicalStyles)();
44
+ const lexicalInitialConfig = {
45
+ namespace: 'fai-EditorInput',
46
+ onError: console.error,
47
+ nodes: customNodes,
48
+ editorState,
49
+ editable: !disabled,
50
+ theme: {
51
+ paragraph: lexicalStyles.paragraph
52
+ }
53
+ };
54
+ const lexicalEditor = (0, _useLexicalEditor.useLexicalEditor)(lexicalInitialConfig);
55
+ const canShowPlaceholder = (0, _reacttexteditor.useCanShowPlaceholder)(lexicalEditor);
56
+ const spanRef = _react.useCallback((span)=>{
57
+ // Register the `input` span with lexical
58
+ lexicalEditor.setRootElement(span);
59
+ }, [
60
+ lexicalEditor
61
+ ]);
62
+ // Update lexical when disabled changes
63
+ (0, _reactutilities.useIsomorphicLayoutEffect)(()=>{
64
+ lexicalEditor.setEditable(!disabled);
65
+ }, [
66
+ lexicalEditor
67
+ ]);
68
+ (0, _reactutilities.useIsomorphicLayoutEffect)(()=>{
69
+ return (0, _reacttexteditor.mergeRegister)(lexicalEditor.registerEditableListener((isEditable)=>{
70
+ setDisabled(!isEditable);
71
+ }), lexicalEditor.registerRootListener((root)=>{
72
+ if (!root) {
73
+ return;
74
+ }
75
+ // Remove lexical's inline style so we can apply our own
76
+ // Lexical needs the whitespace style to be either `pre` or `pre-wrap` to work correctly
77
+ root.style.whiteSpace = '';
78
+ }));
79
+ }, []);
80
+ return {
81
+ canShowPlaceholder,
82
+ disabled,
83
+ spanRef,
84
+ lexicalEditor,
85
+ lexicalInitialConfig
86
+ };
87
+ } //# sourceMappingURL=useLexicalContentEditable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["useLexicalContentEditable.ts"],"sourcesContent":["import * as React from 'react';\nimport { SentinelNode } from '@fluentui-copilot/chat-input-plugins';\nimport type { InitialConfigType, LexicalEditor } from '@fluentui-copilot/react-text-editor';\nimport {\n useCanShowPlaceholder,\n mergeRegister,\n $insertNodes,\n $createParagraphNode,\n $createTextNode,\n} from '@fluentui-copilot/react-text-editor';\nimport { useControllableState, useIsomorphicLayoutEffect } from '@fluentui/react-utilities';\nimport { useLexicalStyles } from '../EditorInput';\nimport { useLexicalEditor } from './useLexicalEditor';\n\nexport type UseLexicalContentEditableProps = {\n customNodes?: InitialConfigType['nodes'];\n defaultValue?: string | (() => void);\n disabled?: boolean;\n};\nexport type UseLexicalContentEditableResult = {\n canShowPlaceholder: boolean;\n disabled: boolean;\n spanRef: React.RefCallback<HTMLSpanElement>;\n lexicalEditor: LexicalEditor;\n lexicalInitialConfig: InitialConfigType;\n};\n\nfunction $insertString(text: string) {\n const paragraphNode = $createParagraphNode();\n const textNode = $createTextNode(text);\n paragraphNode.append(textNode);\n $insertNodes([paragraphNode]);\n}\n\nexport function useLexicalContentEditable(props: UseLexicalContentEditableProps): UseLexicalContentEditableResult {\n const { defaultValue } = props;\n\n const customNodes = props.customNodes ? [...props.customNodes, SentinelNode] : [SentinelNode];\n\n // The disabled state can also be changed by lexical (e.g. by a custom plugin) so\n // we use `useControllableState` to coordinate\n const [disabled, setDisabled] = useControllableState({\n state: props.disabled,\n initialState: false,\n });\n\n const editorState =\n typeof defaultValue === 'string'\n ? () => {\n $insertString(defaultValue);\n }\n : defaultValue;\n\n const lexicalStyles = useLexicalStyles();\n const lexicalInitialConfig = {\n namespace: 'fai-EditorInput',\n onError: console.error,\n nodes: customNodes,\n editorState,\n editable: !disabled,\n theme: { paragraph: lexicalStyles.paragraph },\n };\n const lexicalEditor = useLexicalEditor(lexicalInitialConfig);\n\n const canShowPlaceholder = useCanShowPlaceholder(lexicalEditor);\n\n const spanRef = React.useCallback(\n span => {\n // Register the `input` span with lexical\n lexicalEditor.setRootElement(span);\n },\n [lexicalEditor],\n );\n\n // Update lexical when disabled changes\n useIsomorphicLayoutEffect(() => {\n lexicalEditor.setEditable(!disabled);\n }, [lexicalEditor]);\n\n useIsomorphicLayoutEffect(() => {\n return mergeRegister(\n lexicalEditor.registerEditableListener(isEditable => {\n setDisabled(!isEditable);\n }),\n lexicalEditor.registerRootListener(root => {\n if (!root) {\n return;\n }\n\n // Remove lexical's inline style so we can apply our own\n // Lexical needs the whitespace style to be either `pre` or `pre-wrap` to work correctly\n root.style.whiteSpace = '';\n }),\n );\n }, []);\n\n return { canShowPlaceholder, disabled, spanRef, lexicalEditor, lexicalInitialConfig };\n}\n"],"names":["useLexicalContentEditable","$insertString","text","paragraphNode","$createParagraphNode","textNode","$createTextNode","append","$insertNodes","props","defaultValue","customNodes","SentinelNode","disabled","setDisabled","useControllableState","editorState","initialState","useLexicalStyles","lexicalInitialConfig","namespace","nodes","editable","console","paragraph","theme","useCanShowPlaceholder","lexicalEditor","lexicalStyles","setRootElement","span","useCallback","setEditable","isEditable","registerRootListener","root","useIsomorphicLayoutEffect"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BA+B8BA;;;eAAAA;;;;iEA/BP;kCACM;iCAQtB;gCACyD;6BAC/B;kCACA;AAejC,SAASC,cAAcC,IAAY;UACjCC,gBAAMA,IAAAA,qCAAgBC;UACtBC,WAAMA,IAAAA,gCAAWC,EAAAA;kBACjBH,MAAcI,CAAAA;qCACdC,EAAAA;QAAAA;KAAa;;AAAe,SAAAR,0BAAAS,KAAA;IAC9B,MAAA,EAEAC,YAAgBV,KACdS;UAEAE,cAAMA,MAAcF,WAAME,GAAW;WAAGF,MAAAE,WAAA;QAAAC,8BAAA;KAAA,GAAA;QAAAA,8BAAA;KAAA;qFAAqB;kDAAEA;UAAgB,CAAAC,UAAAC,YAAA,GAAAC,IAAAA,oCAAA,EAAA;eAACH,MAAAA,QAAAA;sBAAa;;UAG7FI,cAAA,OAAAN,iBAAA,WAA8C;QAC9CT,cAAOY;;UAELI,gBAAcC,IAAAA,6BAAA;UAChBC,uBAAA;QAEAC,WAAMJ;iBAGEf,QAAAA,KAAcS;QAChBW,OACAX;QAENM;QACAM,UAAMH,CAAAA;eACJC;uBACSG,cAAaC,SAAA;;;UAGtBF,gBAAWT,IAAAA,kCAAAA,EAAAA;UACXY,qBAAOC,IAAAA,sCAAA,EAAAC;oBAAEH,OAAWI,WAAAA,CAAAA,CAAAA;iDAAwB;QAC9CD,cAAAE,cAAA,CAAAC;OACA;QAAAH;KAAMA;2CAEqBD;iDAELK,EAAAA;sBAElBC,WAAA,CAAA,CAAAnB;;;KACAc;iDAEF,EAAA;eAACA,IAAAA,8BAAAA,EAAAA,cAAAA,wBAAAA,CAAAA,CAAAA;YAAcb,YAAA,CAAAmB;QAGjB,IAAAN,cAAAO,oBAAA,CAAuCC,CAAAA;YACvCC,IAAAA,CAAAA,MAAAA;gBACET;YACF;oEAAIA;YAAc,wFAAA;YAElBS,KAAAA,KAAAA,CAAAA,UAAAA,GAA0B;;;WAItB;;;;;;;uDAWC"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "useLexicalEditor", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return useLexicalEditor;
9
+ }
10
+ });
11
+ const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
12
+ const _reacttexteditor = require("@fluentui-copilot/react-text-editor");
13
+ const _reactutilities = require("@fluentui/react-utilities");
14
+ const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
15
+ // Merge initial state with history
16
+ const UPDATE_OPTIONS = {
17
+ tag: 'history-merge'
18
+ };
19
+ function setInitialState(editor, initialState) {
20
+ if (initialState === null) {
21
+ return;
22
+ } else if (initialState === undefined) {
23
+ editor.update(()=>{
24
+ const root = (0, _reacttexteditor.$getRoot)();
25
+ if (root.isEmpty()) {
26
+ root.append((0, _reacttexteditor.$createParagraphNode)());
27
+ }
28
+ }, UPDATE_OPTIONS);
29
+ } else {
30
+ switch(typeof initialState){
31
+ case 'string':
32
+ {
33
+ const parsedState = editor.parseEditorState(initialState);
34
+ editor.setEditorState(parsedState, UPDATE_OPTIONS);
35
+ break;
36
+ }
37
+ case 'object':
38
+ {
39
+ editor.setEditorState(initialState, UPDATE_OPTIONS);
40
+ break;
41
+ }
42
+ case 'function':
43
+ {
44
+ editor.update(()=>{
45
+ if ((0, _reacttexteditor.$getRoot)().isEmpty()) {
46
+ initialState(editor);
47
+ }
48
+ }, UPDATE_OPTIONS);
49
+ }
50
+ }
51
+ }
52
+ }
53
+ function useLexicalEditor(initialConfig) {
54
+ const { theme, namespace, nodes, onError, editorState: initialEditorState, html, editable = true } = initialConfig;
55
+ const lexicalEditor = _react.useMemo(()=>{
56
+ const lexicalEditor = (0, _reacttexteditor.createEditor)({
57
+ editable,
58
+ html,
59
+ namespace,
60
+ nodes,
61
+ onError: (error)=>onError(error, lexicalEditor),
62
+ theme
63
+ });
64
+ setInitialState(lexicalEditor, initialEditorState);
65
+ return lexicalEditor;
66
+ }, // eslint-disable-next-line react-compiler/react-compiler -- This is a valid breakage of the rules of hooks
67
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- We only want to create this context once
68
+ []);
69
+ (0, _reactutilities.useIsomorphicLayoutEffect)(()=>{
70
+ const isEditable = initialConfig.editable;
71
+ lexicalEditor.setEditable(isEditable !== undefined ? isEditable : true);
72
+ }, []);
73
+ return lexicalEditor;
74
+ } //# sourceMappingURL=useLexicalEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["useLexicalEditor.ts"],"sourcesContent":["import type { InitialConfigType, LexicalEditor } from '@fluentui-copilot/react-text-editor';\nimport { $createParagraphNode } from '@fluentui-copilot/react-text-editor';\nimport { $getRoot } from '@fluentui-copilot/react-text-editor';\nimport { createEditor } from '@fluentui-copilot/react-text-editor';\nimport { useIsomorphicLayoutEffect } from '@fluentui/react-utilities';\nimport * as React from 'react';\n\n// Merge initial state with history\nconst UPDATE_OPTIONS = { tag: 'history-merge' };\n\nfunction setInitialState(editor: LexicalEditor, initialState: InitialConfigType['editorState']) {\n if (initialState === null) {\n return;\n } else if (initialState === undefined) {\n editor.update(() => {\n const root = $getRoot();\n if (root.isEmpty()) {\n root.append($createParagraphNode());\n }\n }, UPDATE_OPTIONS);\n } else {\n switch (typeof initialState) {\n case 'string': {\n const parsedState = editor.parseEditorState(initialState);\n editor.setEditorState(parsedState, UPDATE_OPTIONS);\n break;\n }\n case 'object': {\n editor.setEditorState(initialState, UPDATE_OPTIONS);\n break;\n }\n case 'function': {\n editor.update(() => {\n if ($getRoot().isEmpty()) {\n initialState(editor);\n }\n }, UPDATE_OPTIONS);\n }\n }\n }\n}\n\nexport function useLexicalEditor(initialConfig: InitialConfigType) {\n const { theme, namespace, nodes, onError, editorState: initialEditorState, html, editable = true } = initialConfig;\n\n const lexicalEditor = React.useMemo(\n () => {\n const lexicalEditor = createEditor({\n editable,\n html,\n namespace,\n nodes,\n onError: error => onError(error, lexicalEditor),\n theme,\n });\n\n setInitialState(lexicalEditor, initialEditorState);\n\n return lexicalEditor;\n },\n // eslint-disable-next-line react-compiler/react-compiler -- This is a valid breakage of the rules of hooks\n // eslint-disable-next-line react-hooks/exhaustive-deps -- We only want to create this context once\n [],\n );\n\n useIsomorphicLayoutEffect(() => {\n const isEditable = initialConfig.editable;\n lexicalEditor.setEditable(isEditable !== undefined ? isEditable : true);\n }, []);\n\n return lexicalEditor;\n}\n"],"names":["useLexicalEditor","UPDATE_OPTIONS","tag","setInitialState","editor","initialState","undefined","update","root","$getRoot","isEmpty","$createParagraphNode","parsedState","parseEditorState","setEditorState","initialConfig","theme","namespace","onError","lexicalEditor","React","useMemo","initialEditorState","html","nodes","useIsomorphicLayoutEffect","error"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BA0CgBA;;;eAAAA;;;;iCAzCqB;gCAGK;iEACnB;AAEvB,mCAAmC;AACnC,MAAMC,iBAAiB;SAAEC;AAAqB;AAE9C,SAASC,gBAAgBC,MAAqB,EAAEC,YAA8C;QAC5FA,iBAAIA,MAAiB;;WAErB,IAAOA,iBAAIA,WAAiBC;eAC1BF,MAAOG,CAAAA;kBACLC,OAAMA,IAAAA,yBAAOC;qBACbC,OAASA,IAAAA;2BACPF,CAAAA,IAAAA,qCAAYG;;;WAGlB;eACE,OAAQN;;;wCAEEO,OAAAA,gBAAqBC,CAAAA;yCACpBC,CAAAA,aAAeF;;;;;yCAIfE,CAAAA,cAAeT;;;;;iCAItBD,CAAAA;yDACE,IAAAM,OAAID,IAAAA;;;;;;;AAOd;AAEO,SAAST,iBAAiBe,aAAgC;UAC/D,EAEAC,KAAA,WAEI,+BAGEC,kBAAAA,mBAEAC,IAAAA;UAEFC,gBAAAC,OAAAC,OAAA,CAAA;cAEAlB,gBAAgBgB,IAAAA,6BAAAA,EAAeG;;YAGjCC;YAEAN;YACEO;YAGJC,SAAAA,CAAAA,QAAAA,QAA0BC,OAAAP;;;QAG1BhB,gBAAKgB,eAAAG;QAEL,OAAOH;IACT"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentui-copilot/react-editor-input",
3
- "version": "0.1.4",
3
+ "version": "0.2.0",
4
4
  "description": "a base rich editor input.",
5
5
  "main": "lib-commonjs/index.js",
6
6
  "module": "lib/index.js",
@@ -12,15 +12,15 @@
12
12
  },
13
13
  "license": "MIT",
14
14
  "dependencies": {
15
- "@fluentui-copilot/chat-input-plugins": "^0.1.4",
16
- "@fluentui-copilot/react-chat-input-plugins": "^0.1.4",
17
- "@fluentui-copilot/react-text-editor": "^0.1.8",
15
+ "@fluentui-copilot/chat-input-plugins": "^0.2.0",
16
+ "@fluentui-copilot/react-chat-input-plugins": "^0.2.0",
17
+ "@fluentui-copilot/react-text-editor": "^0.2.0",
18
18
  "@swc/helpers": "^0.5.1"
19
19
  },
20
20
  "peerDependencies": {
21
- "@fluentui/react-components": ">=9.54.4 <10.0.0",
22
- "@fluentui/react-jsx-runtime": ">=9.0.40 <10.0.0",
23
- "@fluentui/react-utilities": ">=9.18.11 <10.0.0",
21
+ "@fluentui/react-components": ">=9.54.10 <10.0.0",
22
+ "@fluentui/react-jsx-runtime": ">=9.0.42 <10.0.0",
23
+ "@fluentui/react-utilities": ">=9.18.13 <10.0.0",
24
24
  "@types/react": ">=16.14.0 <19.0.0",
25
25
  "@types/react-dom": ">=16.9.8 <19.0.0",
26
26
  "react": ">=16.14.0 <19.0.0",