@tarviks/lexical-rich-editor 1.0.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/README.md +198 -0
- package/dist/index.css +817 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.mts +276 -0
- package/dist/index.d.ts +276 -0
- package/dist/index.js +6878 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +6856 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +92 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/Editor.css","../src/Nodes/Image.css","../src/Nodes/InlineImage.css","../src/Nodes/PageBreak.css","../src/Plugins/FloatLink.css","../src/Plugins/TableActionMenu.css","../src/Plugins/TableCellResizer.css","../src/Nodes/ColorPickerComponent.css","../src/Theme/codeEditor.css","../src/Theme/index.css"],"sourcesContent":["/* CharacterStylesPopupPlugin.css (RTP FIX: works inside Fluent UI Panel/Layer) */\r\n\r\n.lexical-floating-ui-host {\r\n position: fixed;\r\n inset: 0;\r\n pointer-events: none; /* host never blocks clicks */\r\n z-index: 10000000; /* above panel/layer */\r\n}\r\n\r\n/* popup is interactive */\r\n.lexical-floating-ui-host .character-style-popup {\r\n pointer-events: auto;\r\n}\r\n\r\n.character-style-popup {\r\n position: fixed; /* IMPORTANT: positioning uses viewport rects */\r\n z-index: 10000010;\r\n\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 4px;\r\n\r\n /* padding: 6px; */\r\n border-radius: 4px;\r\n\r\n background: #fff;\r\n border: 1px solid rgba(0, 0, 0, 0.06);\r\n\r\n box-shadow:\r\n 0 10px 30px rgba(0, 0, 0, 0.14),\r\n 0 2px 10px rgba(0, 0, 0, 0.08);\r\n\r\n opacity: 0;\r\n transform: translateY(6px) scale(0.98);\r\n transform-origin: top left;\r\n transition:\r\n opacity 120ms ease,\r\n transform 120ms ease;\r\n\r\n visibility: hidden;\r\n pointer-events: none;\r\n\r\n user-select: none;\r\n}\r\n\r\n.character-style-popup.is-open {\r\n opacity: 1;\r\n transform: translateY(0) scale(1);\r\n visibility: visible;\r\n pointer-events: auto;\r\n}\r\n\r\n.character-style-popup .divider {\r\n width: 1px;\r\n height: 18px;\r\n margin: 0 2px;\r\n background: rgba(0, 0, 0, 0.08);\r\n flex: 0 0 auto;\r\n}\r\n\r\n.character-style-popup :where(button):focus-visible {\r\n outline: 2px solid rgba(0, 120, 212, 0.75);\r\n outline-offset: 2px;\r\n border-radius: 10px;\r\n}\r\n\r\n.character-style-popup :where(button):disabled {\r\n opacity: 0.55;\r\n cursor: not-allowed;\r\n}\r\n",".ImageNode__contentEditable {\r\n min-height: 20px;\r\n border: 0px;\r\n resize: none;\r\n cursor: text;\r\n caret-color: rgb(5, 5, 5);\r\n display: block;\r\n position: relative;\r\n outline: 0px;\r\n padding: 10px;\r\n user-select: text;\r\n font-size: 12px;\r\n width: calc(100% - 20px);\r\n white-space: pre-wrap;\r\n word-break: break-word;\r\n}\r\n\r\n.ImageNode__placeholder {\r\n font-size: 12px;\r\n color: #888;\r\n overflow: hidden;\r\n position: absolute;\r\n text-overflow: ellipsis;\r\n top: 10px;\r\n left: 10px;\r\n user-select: none;\r\n white-space: nowrap;\r\n display: inline-block;\r\n pointer-events: none;\r\n}\r\n\r\n.image-control-wrapper--resizing {\r\n touch-action: none;\r\n}\r\n",".InlineImageNode__contentEditable {\r\n min-height: 20px;\r\n border: 0px;\r\n resize: none;\r\n cursor: text;\r\n caret-color: rgb(5, 5, 5);\r\n display: block;\r\n position: relative;\r\n tab-size: 1;\r\n outline: 0px;\r\n padding: 10px;\r\n user-select: text;\r\n font-size: 14px;\r\n line-height: 1.4em;\r\n width: calc(100% - 20px);\r\n white-space: pre-wrap;\r\n word-break: break-word;\r\n}\r\n\r\n.InlineImageNode__placeholder {\r\n font-size: 12px;\r\n color: #888;\r\n overflow: hidden;\r\n position: absolute;\r\n text-overflow: ellipsis;\r\n bottom: 10px;\r\n left: 10px;\r\n user-select: none;\r\n white-space: nowrap;\r\n display: inline-block;\r\n pointer-events: none;\r\n}\r\n\r\n.InlineImageNode_Checkbox:checked,\r\n.InlineImageNode_Checkbox:not(:checked) {\r\n position: absolute;\r\n left: -9999px;\r\n}\r\n\r\n.InlineImageNode_Checkbox:checked + label,\r\n.InlineImageNode_Checkbox:not(:checked) + label {\r\n position: absolute;\r\n padding-right: 55px;\r\n cursor: pointer;\r\n line-height: 20px;\r\n display: inline-block;\r\n color: #666;\r\n}\r\n\r\n.InlineImageNode_Checkbox:checked + label:before,\r\n.InlineImageNode_Checkbox:not(:checked) + label:before {\r\n content: '';\r\n position: absolute;\r\n right: 0;\r\n top: 0;\r\n width: 18px;\r\n height: 18px;\r\n border: 1px solid #666;\r\n background: #fff;\r\n}\r\n\r\n.InlineImageNode_Checkbox:checked + label:after,\r\n.InlineImageNode_Checkbox:not(:checked) + label:after {\r\n content: '';\r\n width: 8px;\r\n height: 8px;\r\n background: #222222;\r\n position: absolute;\r\n top: 6px;\r\n right: 6px;\r\n -webkit-transition: all 0.2s ease;\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.InlineImageNode_Checkbox:not(:checked) + label:after {\r\n opacity: 0;\r\n -webkit-transform: scale(0);\r\n transform: scale(0);\r\n}\r\n\r\n.InlineImageNode_Checkbox:checked + label:after {\r\n opacity: 1;\r\n -webkit-transform: scale(1);\r\n transform: scale(1);\r\n}\r\n","[type='page-break'] {\r\n position: relative;\r\n display: block;\r\n /* width: calc(100% + var(--editor-input-padding, 28px) * 2); */\r\n overflow: unset;\r\n /* margin-left: calc(var(--editor-input-padding, 28px) * -1); */\r\n margin-top: var(--editor-input-padding, 28px);\r\n margin-bottom: var(--editor-input-padding, 28px);\r\n\r\n border: none;\r\n border-top: 1px dashed var(--editor-color-secondary, #eeeeee);\r\n border-bottom: 1px dashed var(--editor-color-secondary, #eeeeee);\r\n background-color: var(--editor-color-secondary, #eeeeee);\r\n}\r\n\r\n[type='page-break']::before {\r\n content: '';\r\n\r\n position: absolute;\r\n top: 50%;\r\n left: calc(var(--editor-input-padding, 28px) + 12px);\r\n transform: translateY(-50%);\r\n opacity: 0.5;\r\n\r\n background-size: cover;\r\n /* background-image: url(/src/images/icons/scissors.svg); */\r\n width: 16px;\r\n height: 16px;\r\n}\r\n\r\n[type='page-break']::after {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n\r\n display: block;\r\n padding: 2px 6px;\r\n border: 1px solid #ccc;\r\n background-color: #fff;\r\n\r\n content: 'PAGE BREAK';\r\n font-size: 12px;\r\n color: #000;\r\n font-weight: 600;\r\n}\r\n\r\n.selected[type='page-break'] {\r\n border-color: var(--editor-color-primary, #4766cb);\r\n}\r\n\r\n.selected[type='page-break']::before {\r\n opacity: 1;\r\n}\r\n",".link-editor {\r\n display: flex;\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n z-index: 10;\r\n max-width: 400px;\r\n width: 100%;\r\n opacity: 0;\r\n background-color: #fff;\r\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.3);\r\n border-radius: 0 0 8px 8px;\r\n transition: opacity 0.5s;\r\n will-change: transform;\r\n}\r\n\r\n.link-editor .button {\r\n width: 20px;\r\n height: 20px;\r\n display: inline-block;\r\n padding: 6px;\r\n border-radius: 8px;\r\n cursor: pointer;\r\n margin: 0 2px;\r\n}\r\n\r\n.link-editor .button.hovered {\r\n width: 20px;\r\n height: 20px;\r\n display: inline-block;\r\n background-color: #eee;\r\n}\r\n\r\n.link-editor .button i,\r\n.actions i {\r\n background-size: contain;\r\n display: inline-block;\r\n height: 20px;\r\n width: 20px;\r\n vertical-align: -0.25em;\r\n}\r\n",".aoTableActionHandleRoot {\r\n pointer-events: auto;\r\n}\r\n\r\n.aoTableActionHandleBtn {\r\n width: 28px;\r\n height: 28px;\r\n border-radius: 8px;\r\n border: 1px solid var(--colorNeutralStroke2);\r\n background: var(--colorNeutralBackground1);\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n /* box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12); */\r\n}\r\n\r\n.aoTableActionHandleBtn:hover {\r\n background: var(--colorNeutralBackground1Hover);\r\n}\r\n\r\n.aoTableActionPopover {\r\n min-width: 280px;\r\n border-radius: 12px;\r\n padding: 4px;\r\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.16);\r\n}\r\n\r\n.aoMenuRow {\r\n display: flex;\r\n align-items: center;\r\n width: 100%;\r\n}\r\n\r\n.aoMenuLabel {\r\n display: inline-flex;\r\n gap: 8px;\r\n align-items: center;\r\n}\r\n\r\n.aoMenuShortcut {\r\n margin-left: auto;\r\n font-size: 12px;\r\n opacity: 0.7;\r\n}\r\n",".TableCellResizer__resizer {\r\n position: absolute;\r\n z-index: 99999;\r\n pointer-events: auto;\r\n}\r\n\r\n.TableCellResizer__ui {\r\n width: 10px;\r\n height: 10px;\r\n user-select: none;\r\n cursor: col-resize;\r\n}\r\n",".aoColorBtnV8 {\r\n width: 28px;\r\n height: 28px;\r\n border-radius: 6px;\r\n}\r\n\r\n.aoColorCallout {\r\n border-radius: 12px;\r\n}\r\n\r\n.aoLexRow {\r\n display: flex;\r\n align-items: center;\r\n gap: 10px;\r\n}\r\n\r\n.aoLexSwatch {\r\n width: 26px;\r\n height: 26px;\r\n border-radius: 6px;\r\n border: 1px solid #d0d0d0;\r\n}\r\n\r\n.aoLexTitle {\r\n font-size: 13px;\r\n font-weight: 600;\r\n}\r\n\r\n.aoLexLabel {\r\n width: 42px;\r\n font-size: 12px;\r\n color: #666;\r\n padding-top: 8px;\r\n}\r\n\r\n.aoLexSwatches {\r\n display: grid;\r\n grid-template-columns: repeat(9, 1fr);\r\n gap: 6px;\r\n}\r\n\r\n.aoLexSwatchBtn {\r\n width: 22px;\r\n height: 18px;\r\n border-radius: 4px;\r\n border: 1px solid #d0d0d0;\r\n cursor: pointer;\r\n padding: 0;\r\n}\r\n\r\n.aoLexSV {\r\n position: relative;\r\n width: 100%;\r\n height: 150px;\r\n border-radius: 10px;\r\n overflow: hidden;\r\n cursor: crosshair;\r\n border: 1px solid #e0e0e0;\r\n}\r\n\r\n.aoLexSVHue {\r\n position: absolute;\r\n inset: 0;\r\n}\r\n\r\n.aoLexSVWhite {\r\n position: absolute;\r\n inset: 0;\r\n background: linear-gradient(to right, #fff, rgba(255, 255, 255, 0));\r\n}\r\n\r\n.aoLexSVBlack {\r\n position: absolute;\r\n inset: 0;\r\n background: linear-gradient(to top, #000, rgba(0, 0, 0, 0));\r\n}\r\n\r\n.aoLexSVThumb {\r\n position: absolute;\r\n width: 12px;\r\n height: 12px;\r\n border-radius: 999px;\r\n border: 2px solid #fff;\r\n box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35);\r\n transform: translate(-6px, -6px);\r\n}\r\n\r\n.aoLexHue {\r\n position: relative;\r\n height: 10px;\r\n border-radius: 999px;\r\n cursor: pointer;\r\n border: 1px solid #e0e0e0;\r\n background: linear-gradient(\r\n to right,\r\n #ff0000,\r\n #ffff00,\r\n #00ff00,\r\n #00ffff,\r\n #0000ff,\r\n #ff00ff,\r\n #ff0000\r\n );\r\n}\r\n\r\n.aoLexHueThumb {\r\n position: absolute;\r\n top: 50%;\r\n width: 12px;\r\n height: 12px;\r\n border-radius: 999px;\r\n border: 2px solid #fff;\r\n box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35);\r\n transform: translate(-6px, -6px);\r\n}\r\n\r\n.aoLexPreview {\r\n height: 10px;\r\n border-radius: 999px;\r\n border: 1px solid #e0e0e0;\r\n}\r\n\r\n.aoLexActions {\r\n display: flex;\r\n justify-content: flex-end;\r\n gap: 8px;\r\n}\r\n",".editorCode {\r\n background-color: var(--colorNeutralBackground3, rgb(240, 242, 245));\r\n font-family: Menlo, Consolas, Monaco, monospace;\r\n display: block;\r\n padding: 8px 8px 8px 52px;\r\n line-height: 1.53;\r\n font-size: 13px;\r\n margin: 0;\r\n margin-top: 8px;\r\n margin-bottom: 8px;\r\n tab-size: 2;\r\n overflow-x: auto;\r\n position: relative;\r\n}\r\n\r\n.editorCode:before {\r\n content: attr(data-gutter);\r\n position: absolute;\r\n background-color: var(--colorNeutralBackground2, #eee);\r\n left: 0;\r\n top: 0;\r\n border-right: 1px solid var(--colorNeutralStroke1, #ccc);\r\n padding: 8px;\r\n color: var(--colorNeutralForeground3, #777);\r\n /* white-space: pre-wrap; */\r\n text-align: right;\r\n min-width: 25px;\r\n}\r\n.editorCode:after {\r\n content: attr(data-highlight-language);\r\n position: absolute;\r\n top: 0;\r\n right: 3px;\r\n padding: 3px;\r\n font-size: 10px;\r\n text-transform: uppercase;\r\n color: var(--colorNeutralForeground3, rgba(0, 0, 0, 0.5));\r\n}\r\n\r\n.editorTokenComment {\r\n color: var(--colorNeutralForeground3, slategray);\r\n}\r\n\r\n.editor-tokenPunctuation {\r\n color: var(--colorNeutralForeground3, #999);\r\n}\r\n\r\n.editorTokenProperty {\r\n color: var(--colorBrandForeground1, #905);\r\n}\r\n\r\n.editorTokenSelector {\r\n color: var(--colorNeutralForeground2, #690);\r\n}\r\n\r\n.editorTokenOperator {\r\n color: var(--colorNeutralForeground2, #9a6e3a);\r\n}\r\n\r\n.editorTokenAttr {\r\n color: var(--colorBrandForegroundLink, #07a);\r\n}\r\n\r\n.editorTokenVariable {\r\n color: var(--colorNeutralForeground2, #e90);\r\n}\r\n\r\n.editorTokenFunction {\r\n color: var(--colorBrandForeground1, #dd4a68);\r\n}\r\n\r\n.editor {\r\n font-size: 15px;\r\n line-height: 1.2;\r\n}\r\n\r\n.editor p {\r\n margin: 0;\r\n line-height: 1.2;\r\n}\r\n\r\n.editor div {\r\n margin: 0;\r\n}\r\n\r\n.editor img {\r\n display: block;\r\n}\r\n\r\n.editor-image {\r\n position: relative;\r\n display: inline-block;\r\n}\r\n\r\n.editor-image img {\r\n display: block;\r\n max-width: 100%;\r\n}",".underline {\r\n text-decoration: underline;\r\n}\r\n\r\n.strikethrough {\r\n text-decoration: line-through;\r\n}\r\n\r\n.underlineStrikethrough {\r\n text-decoration: underline line-through;\r\n}\r\n\r\n.italic {\r\n font-style: italic;\r\n}\r\n.capitalize {\r\n text-transform: capitalize;\r\n}\r\n.lowercase {\r\n text-transform: lowercase;\r\n}\r\n.uppercase {\r\n text-transform: uppercase;\r\n}\r\n.code {\r\n color: black;\r\n padding: 2px;\r\n background: #eee;\r\n border: 1px solid #ccc;\r\n}\r\n\r\n.table {\r\n margin-top: 4px;\r\n}\r\n.quote {\r\n margin: 0;\r\n margin-top: 6px;\r\n margin-left: 20px;\r\n margin-bottom: 10px;\r\n font-size: 15px;\r\n color: rgb(101, 103, 107);\r\n border-left-color: rgb(206, 208, 212);\r\n border-left-width: 4px;\r\n border-left-style: solid;\r\n padding-left: 16px;\r\n}\r\n.tableCell {\r\n width: 70px;\r\n border: 1px solid #bbb;\r\n padding-left: 6px;\r\n}\r\n\r\n.tableCell p {\r\n margin-bottom: 4px;\r\n}\r\n\r\n.tableCellHeader {\r\n background: #f2f3f5;\r\n}\r\n\r\nspan.editor-image {\r\n cursor: default;\r\n display: inline-block;\r\n position: relative;\r\n user-select: none;\r\n}\r\n\r\n.editor-image img {\r\n max-width: 100%;\r\n cursor: default;\r\n}\r\n\r\n.editor-image img.focused {\r\n outline: 2px solid rgb(60, 132, 244);\r\n user-select: none;\r\n}\r\n\r\n.editor-image img.focused.draggable {\r\n cursor: grab;\r\n}\r\n\r\n.editor-image img.focused.draggable:active {\r\n cursor: grabbing;\r\n}\r\n\r\n.editor-image .image-caption-container .tree-view-output {\r\n margin: 0;\r\n border-radius: 0;\r\n}\r\n\r\n.editor-image .image-caption-container {\r\n display: block;\r\n position: absolute;\r\n bottom: 4px;\r\n left: 0;\r\n right: 0;\r\n padding: 0;\r\n margin: 0;\r\n border-top: 1px solid #fff;\r\n background-color: rgba(255, 255, 255, 0.9);\r\n min-width: 100px;\r\n color: #000;\r\n overflow: hidden;\r\n}\r\n\r\n.editor-image .image-caption-button {\r\n display: block;\r\n position: absolute;\r\n bottom: 20px;\r\n left: 0;\r\n right: 0;\r\n width: 30%;\r\n padding: 10px;\r\n margin: 0 auto;\r\n border: 1px solid rgba(255, 255, 255, 0.3);\r\n border-radius: 5px;\r\n background-color: rgba(0, 0, 0, 0.5);\r\n min-width: 100px;\r\n color: #fff;\r\n cursor: pointer;\r\n user-select: none;\r\n}\r\n\r\n.editor-image .image-caption-button:hover {\r\n background-color: rgba(60, 132, 244, 0.5);\r\n}\r\n\r\n.editor-image .image-edit-button {\r\n border: 1px solid rgba(0, 0, 0, 0.3);\r\n border-radius: 5px;\r\n /* background-image: url(/src/images/icons/pencil-fill.svg); */\r\n background-size: 16px;\r\n background-position: center;\r\n background-repeat: no-repeat;\r\n width: 35px;\r\n height: 35px;\r\n vertical-align: -0.25em;\r\n position: absolute;\r\n right: 4px;\r\n top: 4px;\r\n cursor: pointer;\r\n user-select: none;\r\n}\r\n\r\n.editor-image .image-edit-button:hover {\r\n background-color: rgba(60, 132, 244, 0.1);\r\n}\r\n\r\n.editor-image .image-resizer {\r\n display: block;\r\n width: 7px;\r\n height: 7px;\r\n position: absolute;\r\n background-color: rgb(60, 132, 244);\r\n border: 1px solid #fff;\r\n}\r\n\r\n.editor-image .image-resizer.image-resizer-n {\r\n top: -6px;\r\n left: 48%;\r\n cursor: n-resize;\r\n}\r\n\r\n.editor-image .image-resizer.image-resizer-ne {\r\n top: -6px;\r\n right: -6px;\r\n cursor: ne-resize;\r\n}\r\n\r\n.editor-image .image-resizer.image-resizer-e {\r\n bottom: 48%;\r\n right: -6px;\r\n cursor: e-resize;\r\n}\r\n\r\n.editor-image .image-resizer.image-resizer-se {\r\n bottom: -2px;\r\n right: -6px;\r\n cursor: nwse-resize;\r\n}\r\n\r\n.editor-image .image-resizer.image-resizer-s {\r\n bottom: -2px;\r\n left: 48%;\r\n cursor: s-resize;\r\n}\r\n\r\n.editor-image .image-resizer.image-resizer-sw {\r\n bottom: -2px;\r\n left: -6px;\r\n cursor: sw-resize;\r\n}\r\n\r\n.editor-image .image-resizer.image-resizer-w {\r\n bottom: 48%;\r\n left: -6px;\r\n cursor: w-resize;\r\n}\r\n\r\n.editor-image .image-resizer.image-resizer-nw {\r\n top: -6px;\r\n left: -6px;\r\n cursor: nw-resize;\r\n}\r\n.inline-editor-image img {\r\n max-width: 100%;\r\n cursor: default;\r\n}\r\n\r\n.inline-editor-image img.focused {\r\n outline: 2px solid rgb(60, 132, 244);\r\n}\r\n\r\n.inline-editor-image img.focused.draggable {\r\n cursor: grab;\r\n}\r\n\r\n.inline-editor-image img.focused.draggable:active {\r\n cursor: grabbing;\r\n}\r\n\r\n.inline-editor-image .image-caption-container .tree-view-output {\r\n margin: 0;\r\n border-radius: 0;\r\n}\r\n\r\n.inline-editor-image.position-full {\r\n margin: 1em 0 1em 0;\r\n}\r\n\r\n.inline-editor-image.position-left {\r\n float: left;\r\n width: 50%;\r\n margin: 1em 1em 0 0;\r\n}\r\n\r\n.inline-editor-image.position-right {\r\n float: right;\r\n width: 50%;\r\n margin: 1em 0 0 1em;\r\n}\r\n\r\n.inline-editor-image .image-edit-button {\r\n display: block;\r\n position: absolute;\r\n top: 12px;\r\n right: 12px;\r\n padding: 6px 8px;\r\n margin: 0 auto;\r\n border: 1px solid rgba(255, 255, 255, 0.3);\r\n border-radius: 5px;\r\n background-color: rgba(0, 0, 0, 0.5);\r\n min-width: 60px;\r\n color: #fff;\r\n cursor: pointer;\r\n user-select: none;\r\n}\r\n\r\n.inline-editor-image .image-edit-button:hover {\r\n background-color: rgba(60, 132, 244, 0.5);\r\n}\r\n\r\n.inline-editor-image .image-caption-container {\r\n display: block;\r\n background-color: #f4f4f4;\r\n min-width: 100%;\r\n color: #000;\r\n overflow: hidden;\r\n}\r\n\r\n.lexical-table {\r\n border-collapse: collapse;\r\n border-spacing: 0;\r\n margin: 12px 0;\r\n overflow: hidden;\r\n}\r\n\r\n.lexical-table-row {\r\n}\r\n\r\n.lexical-table-cell,\r\n.lexical-table-cell-header {\r\n border: 1px solid #c8c8c8;\r\n padding: 10px;\r\n min-width: 90px;\r\n vertical-align: top;\r\n position: relative;\r\n background: #ffffff;\r\n}\r\n\r\n.lexical-table-cell-header {\r\n background: #f5f5f5;\r\n font-weight: 600;\r\n}\r\n\r\n/* --- SELECTION STATES (Playground-ish) --- */\r\n.lexical-table-cell-selected {\r\n background: rgba(33, 111, 219, 0.12);\r\n}\r\n\r\n.lexical-table-cell-primary-selected {\r\n outline: 2px solid rgba(33, 111, 219, 0.9);\r\n outline-offset: -2px;\r\n}\r\n\r\n.lexical-table-cell-editing {\r\n box-shadow: inset 0 0 0 2px rgba(33, 111, 219, 0.6);\r\n}\r\n\r\n/* --- RESIZER HANDLE (TableCellResizerPlugin uses this) --- */\r\n.lexical-table-cell-resizer {\r\n position: absolute;\r\n top: 0;\r\n right: -2px;\r\n width: 6px;\r\n height: 100%;\r\n cursor: col-resize;\r\n z-index: 10;\r\n}\r\n\r\n.lexical-table-cell-resizer::after {\r\n content: '';\r\n position: absolute;\r\n top: 0;\r\n left: 2px;\r\n width: 2px;\r\n height: 100%;\r\n background: rgba(33, 111, 219, 0.55);\r\n opacity: 0;\r\n transition: opacity 120ms ease-in-out;\r\n}\r\n\r\n.lexical-table-cell:hover .lexical-table-cell-resizer::after,\r\n.lexical-table-cell-header:hover .lexical-table-cell-resizer::after {\r\n opacity: 1;\r\n}\r\n\r\n/* scope to your wrapper class if possible */\r\n.editor {\r\n line-height: 1.25;\r\n}\r\n\r\n/* emails/signatures rely on tight paragraphs */\r\n.editor p {\r\n margin: 0;\r\n line-height: 1.25;\r\n}\r\n\r\n/* pasted signatures often contain divs */\r\n.editor div {\r\n margin: 0;\r\n}\r\n\r\n/* avoid baseline gaps */\r\n.editor img {\r\n vertical-align: middle;\r\n}\r\n\r\n.TableCellResizer__ui {\r\n position: absolute;\r\n z-index: 50;\r\n}\r\n"],"mappings":"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","names":[]}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
/** How the suggestion was accepted */
|
|
4
|
+
/**
|
|
5
|
+
* How an inline suggestion was accepted/committed by the user.
|
|
6
|
+
*
|
|
7
|
+
* - 'tab': Accepted via the Tab key (or ArrowRight)
|
|
8
|
+
* - 'enter': Accepted via the Enter key
|
|
9
|
+
* - 'click': Accepted by clicking on a suggestion item
|
|
10
|
+
*/
|
|
11
|
+
type AcceptMethod = 'tab' | 'enter' | 'click';
|
|
12
|
+
/** What the consumer returns for autocomplete requests */
|
|
13
|
+
type SearchPromise = {
|
|
14
|
+
promise: Promise<string[] | null>;
|
|
15
|
+
dismiss: () => void;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* A single spelling, grammar, or style issue returned by your API.
|
|
19
|
+
*
|
|
20
|
+
* `offset` and `length` are character positions in the plain-text
|
|
21
|
+
* representation of the document (`editor.getRootElement().innerText`).
|
|
22
|
+
*/
|
|
23
|
+
type SpellCheckIssue = {
|
|
24
|
+
/** Character offset in the document's plain text */
|
|
25
|
+
offset: number;
|
|
26
|
+
/** Number of characters the issue spans */
|
|
27
|
+
length: number;
|
|
28
|
+
/** Human-readable description shown in the suggestion popover */
|
|
29
|
+
message: string;
|
|
30
|
+
/** Replacement candidates, best first */
|
|
31
|
+
suggestions: string[];
|
|
32
|
+
/** Visual style of the underline: red = spelling, blue = grammar, yellow = style */
|
|
33
|
+
type?: 'spelling' | 'grammar' | 'style';
|
|
34
|
+
/** Actual word as it appears in the text (set by adapter) */
|
|
35
|
+
word?: string;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Return value of `useSpellCheck`.
|
|
39
|
+
*
|
|
40
|
+
* `promise` resolves to an object containing:
|
|
41
|
+
* - `issues` — individual misspelled words to underline
|
|
42
|
+
* - `improvedText`— the fully corrected sentence (like Grammarly's "Accept all")
|
|
43
|
+
*/
|
|
44
|
+
type SpellCheckPayload = {
|
|
45
|
+
issues: SpellCheckIssue[];
|
|
46
|
+
/** Full corrected sentence from grammar check */
|
|
47
|
+
grammarCorrection?: string;
|
|
48
|
+
/** Legacy: full improved text. Prefer grammarCorrection. */
|
|
49
|
+
improvedText?: string;
|
|
50
|
+
};
|
|
51
|
+
type SpellCheckResult = {
|
|
52
|
+
promise: Promise<SpellCheckPayload | null>;
|
|
53
|
+
dismiss: () => void;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Editor capability levels controlling which toolbar features are enabled.
|
|
57
|
+
*
|
|
58
|
+
* - none: No toolbar shown
|
|
59
|
+
* - basic: Minimal formatting (bold/italic/underline), lists, links
|
|
60
|
+
* - standard: Common formatting plus media (images, tables, etc.)
|
|
61
|
+
* - pro: Full feature set (advanced blocks and tools)
|
|
62
|
+
*/
|
|
63
|
+
declare enum ContentEditorLevel {
|
|
64
|
+
None = "none",
|
|
65
|
+
Basic = "basic",
|
|
66
|
+
Standard = "standard",
|
|
67
|
+
Pro = "pro"
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* INTERNAL: Block specification used by the ref API.
|
|
71
|
+
*
|
|
72
|
+
* Not exported from the package root to avoid locking
|
|
73
|
+
* implementation details. Subject to change without notice.
|
|
74
|
+
*/
|
|
75
|
+
type BlockSpec = {
|
|
76
|
+
kind: string;
|
|
77
|
+
html: string;
|
|
78
|
+
position?: 'start' | 'end';
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Public, imperative API exposed via the component ref.
|
|
82
|
+
*
|
|
83
|
+
* Allows programmatic read/write, focus control, and state checks.
|
|
84
|
+
*/
|
|
85
|
+
type ContentEditorRef = {
|
|
86
|
+
/** Replace the entire document content with the provided HTML. */
|
|
87
|
+
setValue: (html: string) => void;
|
|
88
|
+
/** Return the current document as HTML. */
|
|
89
|
+
getValue: () => string;
|
|
90
|
+
/** Clear the document to an empty state. */
|
|
91
|
+
clear: () => void;
|
|
92
|
+
/** Move focus to the editable area. */
|
|
93
|
+
focus: () => void;
|
|
94
|
+
/** Remove focus from the editable area. */
|
|
95
|
+
blur: () => void;
|
|
96
|
+
/** Whether the editor currently contains no user content. */
|
|
97
|
+
isEmpty: () => boolean;
|
|
98
|
+
/** Whether the editor currently has input focus. */
|
|
99
|
+
isFocused: () => boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Access the underlying Lexical editor instance for advanced usage.
|
|
102
|
+
* Returned type is `any` to avoid leaking internal Lexical types.
|
|
103
|
+
*/
|
|
104
|
+
getEditor: () => any;
|
|
105
|
+
/**
|
|
106
|
+
* Insert or update a block identified by `spec.kind`.
|
|
107
|
+
*
|
|
108
|
+
* If a block with the same `kind` exists, it will be updated;
|
|
109
|
+
* otherwise a new block is inserted. `position` controls whether
|
|
110
|
+
* the insertion occurs at the document 'start' or 'end'.
|
|
111
|
+
*/
|
|
112
|
+
upsertBlock: (spec: BlockSpec) => void;
|
|
113
|
+
/** Remove a previously inserted block by its `kind` identifier. */
|
|
114
|
+
removeBlock: (kind: string) => void;
|
|
115
|
+
/** Check whether a block with the given `kind` exists. */
|
|
116
|
+
hasBlock: (kind: string) => boolean;
|
|
117
|
+
};
|
|
118
|
+
interface ContentEditorProps {
|
|
119
|
+
/** Optional editor namespace used by Lexical for scoping. */
|
|
120
|
+
namespace?: string;
|
|
121
|
+
/** Controlled HTML value rendered by the editor. */
|
|
122
|
+
value: string;
|
|
123
|
+
/** Outer container width (e.g., '100%', '600px'). */
|
|
124
|
+
width?: string;
|
|
125
|
+
/** Outer container height (e.g., '100%', '400px'). */
|
|
126
|
+
height?: string;
|
|
127
|
+
/** When true, focuses the editor on mount. */
|
|
128
|
+
autoFocus?: boolean;
|
|
129
|
+
/** CSS margin applied to the root container. */
|
|
130
|
+
margin?: string | number;
|
|
131
|
+
/** Placeholder text shown when the editor is empty. */
|
|
132
|
+
placeholder?: string;
|
|
133
|
+
/** Height of the editable content area inside the container. */
|
|
134
|
+
contentHeight?: string;
|
|
135
|
+
/** Feature level controlling which toolbar groups are enabled. */
|
|
136
|
+
level?: ContentEditorLevel;
|
|
137
|
+
/**
|
|
138
|
+
* @deprecated Not used by the component. Prefer styling overrides instead.
|
|
139
|
+
*/
|
|
140
|
+
topPlaceholderMargin?: string;
|
|
141
|
+
/** Change handler returning the latest HTML value. */
|
|
142
|
+
onChange: (value: string) => void;
|
|
143
|
+
/** When true, the editor becomes read-only (non-interactive). */
|
|
144
|
+
readOnly?: boolean;
|
|
145
|
+
/**
|
|
146
|
+
* @deprecated Legacy flag intended to show a clear button.
|
|
147
|
+
* This is currently not wired in the UI.
|
|
148
|
+
*/
|
|
149
|
+
clearEditorMode?: boolean;
|
|
150
|
+
/**
|
|
151
|
+
* Simple autocomplete — just pass your raw async API call.
|
|
152
|
+
*
|
|
153
|
+
* The component handles all debouncing, cancellation, and ghost-text
|
|
154
|
+
* insertion internally. Return the raw API response — supported shapes:
|
|
155
|
+
* - `{ generated_text: string }` — single suggestion
|
|
156
|
+
* - `string[]` — list of suggestions
|
|
157
|
+
* - `null / undefined` — no suggestion
|
|
158
|
+
*
|
|
159
|
+
* Example:
|
|
160
|
+
* ```ts
|
|
161
|
+
* suggestFn={async (text) => {
|
|
162
|
+
* const res = await fetch('/api/suggest', { method: 'POST', body: JSON.stringify({ text }) });
|
|
163
|
+
* return res.json(); // return raw — component adapts internally
|
|
164
|
+
* }}
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
suggestFn?: (text: string, cursorIndex?: number) => Promise<any>;
|
|
168
|
+
/**
|
|
169
|
+
* Advanced: full control over autocomplete with manual cancellation.
|
|
170
|
+
* Use `suggestFn` instead unless you need a custom `dismiss()` implementation.
|
|
171
|
+
*/
|
|
172
|
+
useQuery?: (searchText?: string, cursorIndex?: number) => SearchPromise;
|
|
173
|
+
/** Called when the editor gains focus. */
|
|
174
|
+
onFocus?: () => void;
|
|
175
|
+
/** Called when the editor loses focus. */
|
|
176
|
+
onBlur?: () => void;
|
|
177
|
+
/**
|
|
178
|
+
* Fires when the user **accepts** an autocomplete suggestion (Tab / ArrowRight).
|
|
179
|
+
*
|
|
180
|
+
* Use this to send a reward signal to your backend so the model improves
|
|
181
|
+
* over time. Example:
|
|
182
|
+
* ```ts
|
|
183
|
+
* onSuggestionAccept={({ suggestionText, triggerText, method }) => {
|
|
184
|
+
* sendReward({ suggestionText, triggerText }); // hits your reward API
|
|
185
|
+
* }}
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
onSuggestionAccept?: (info: {
|
|
189
|
+
suggestionText: string;
|
|
190
|
+
triggerText?: string;
|
|
191
|
+
method: AcceptMethod;
|
|
192
|
+
}) => void;
|
|
193
|
+
/**
|
|
194
|
+
* Fires when a suggestion is displayed to the user (optional analytics hook).
|
|
195
|
+
*/
|
|
196
|
+
onSuggestionShown?: (info: {
|
|
197
|
+
suggestionText: string;
|
|
198
|
+
triggerText?: string;
|
|
199
|
+
}) => void;
|
|
200
|
+
/**
|
|
201
|
+
* Simple spell/grammar check — just pass your raw async API call.
|
|
202
|
+
*
|
|
203
|
+
* The component handles all debouncing, cancellation, response adaptation,
|
|
204
|
+
* underlines, and popovers internally. Supported API response shapes:
|
|
205
|
+
* - `{ misspelled_words: string[], suggestions: Record<string, string[]>, grammar_correction?: string }`
|
|
206
|
+
* - `{ misspelled: string[], suggestions: Record<string, string[]>, improved_text?: string }`
|
|
207
|
+
* - `SpellCheckIssue[]` (legacy — already-adapted array)
|
|
208
|
+
*
|
|
209
|
+
* Example:
|
|
210
|
+
* ```ts
|
|
211
|
+
* spellCheckFn={async (text) => {
|
|
212
|
+
* const res = await fetch('/api/spellcheck', { method: 'POST', body: JSON.stringify({ text }) });
|
|
213
|
+
* return res.json(); // return raw — component adapts internally
|
|
214
|
+
* }}
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
spellCheckFn?: (text: string) => Promise<any>;
|
|
218
|
+
/**
|
|
219
|
+
* Advanced: full control over spell check with manual cancellation.
|
|
220
|
+
* Use `spellCheckFn` instead unless you need a custom `dismiss()` implementation.
|
|
221
|
+
*/
|
|
222
|
+
useSpellCheck?: (text: string) => SpellCheckResult;
|
|
223
|
+
/**
|
|
224
|
+
* Fires when the user accepts a spell/grammar correction from the popover.
|
|
225
|
+
*
|
|
226
|
+
* Use this to POST a reward signal to your backend.
|
|
227
|
+
* ```ts
|
|
228
|
+
* onSpellCheckAccept={({ original, replacement, message, type }) => {
|
|
229
|
+
* myApi.rewardSpellCheck({ original, replacement });
|
|
230
|
+
* }}
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
onSpellCheckAccept?: (info: {
|
|
234
|
+
original: string;
|
|
235
|
+
replacement: string;
|
|
236
|
+
message: string;
|
|
237
|
+
type?: string;
|
|
238
|
+
}) => void;
|
|
239
|
+
/**
|
|
240
|
+
* Debounce delay (ms) after the user stops typing before the spell-check
|
|
241
|
+
* API is called. Defaults to 1200ms. Tune this to balance responsiveness
|
|
242
|
+
* vs. API call frequency.
|
|
243
|
+
*/
|
|
244
|
+
spellCheckIdleMs?: number;
|
|
245
|
+
/**
|
|
246
|
+
* Debounce delay (ms) after the user stops typing before the `suggestFn`
|
|
247
|
+
* API is called. Defaults to 300ms. Tune this to balance responsiveness
|
|
248
|
+
* vs. API call frequency.
|
|
249
|
+
*/
|
|
250
|
+
suggestIdleMs?: number;
|
|
251
|
+
/** When false, spell checking is disabled without unmounting the plugin. */
|
|
252
|
+
spellCheckEnabled?: boolean;
|
|
253
|
+
/** When true, shows the floating formatting toolbar near text selections. */
|
|
254
|
+
showFloatingToolbar?: boolean;
|
|
255
|
+
/**
|
|
256
|
+
* Maximum word count allowed. When set, a live counter is shown
|
|
257
|
+
* below the editor. Exceeding the limit turns the counter red.
|
|
258
|
+
* Example: wordLimit={500}
|
|
259
|
+
*/
|
|
260
|
+
wordLimit?: number;
|
|
261
|
+
/**
|
|
262
|
+
* Fires when the content crosses the configured word limit boundary.
|
|
263
|
+
*
|
|
264
|
+
* - exceeded: true -> user just exceeded the limit
|
|
265
|
+
* - exceeded: false -> user came back within the limit
|
|
266
|
+
*/
|
|
267
|
+
onWordLimitExceeded?: (info: {
|
|
268
|
+
wordCount: number;
|
|
269
|
+
wordLimit: number;
|
|
270
|
+
exceeded: boolean;
|
|
271
|
+
}) => void;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
declare const ContentEditorComponent: React.ForwardRefExoticComponent<ContentEditorProps & React.RefAttributes<ContentEditorRef>>;
|
|
275
|
+
|
|
276
|
+
export { type AcceptMethod, ContentEditorComponent, ContentEditorLevel, type ContentEditorProps, type ContentEditorRef, type SearchPromise, type SpellCheckIssue, type SpellCheckPayload, type SpellCheckResult };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
/** How the suggestion was accepted */
|
|
4
|
+
/**
|
|
5
|
+
* How an inline suggestion was accepted/committed by the user.
|
|
6
|
+
*
|
|
7
|
+
* - 'tab': Accepted via the Tab key (or ArrowRight)
|
|
8
|
+
* - 'enter': Accepted via the Enter key
|
|
9
|
+
* - 'click': Accepted by clicking on a suggestion item
|
|
10
|
+
*/
|
|
11
|
+
type AcceptMethod = 'tab' | 'enter' | 'click';
|
|
12
|
+
/** What the consumer returns for autocomplete requests */
|
|
13
|
+
type SearchPromise = {
|
|
14
|
+
promise: Promise<string[] | null>;
|
|
15
|
+
dismiss: () => void;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* A single spelling, grammar, or style issue returned by your API.
|
|
19
|
+
*
|
|
20
|
+
* `offset` and `length` are character positions in the plain-text
|
|
21
|
+
* representation of the document (`editor.getRootElement().innerText`).
|
|
22
|
+
*/
|
|
23
|
+
type SpellCheckIssue = {
|
|
24
|
+
/** Character offset in the document's plain text */
|
|
25
|
+
offset: number;
|
|
26
|
+
/** Number of characters the issue spans */
|
|
27
|
+
length: number;
|
|
28
|
+
/** Human-readable description shown in the suggestion popover */
|
|
29
|
+
message: string;
|
|
30
|
+
/** Replacement candidates, best first */
|
|
31
|
+
suggestions: string[];
|
|
32
|
+
/** Visual style of the underline: red = spelling, blue = grammar, yellow = style */
|
|
33
|
+
type?: 'spelling' | 'grammar' | 'style';
|
|
34
|
+
/** Actual word as it appears in the text (set by adapter) */
|
|
35
|
+
word?: string;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Return value of `useSpellCheck`.
|
|
39
|
+
*
|
|
40
|
+
* `promise` resolves to an object containing:
|
|
41
|
+
* - `issues` — individual misspelled words to underline
|
|
42
|
+
* - `improvedText`— the fully corrected sentence (like Grammarly's "Accept all")
|
|
43
|
+
*/
|
|
44
|
+
type SpellCheckPayload = {
|
|
45
|
+
issues: SpellCheckIssue[];
|
|
46
|
+
/** Full corrected sentence from grammar check */
|
|
47
|
+
grammarCorrection?: string;
|
|
48
|
+
/** Legacy: full improved text. Prefer grammarCorrection. */
|
|
49
|
+
improvedText?: string;
|
|
50
|
+
};
|
|
51
|
+
type SpellCheckResult = {
|
|
52
|
+
promise: Promise<SpellCheckPayload | null>;
|
|
53
|
+
dismiss: () => void;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Editor capability levels controlling which toolbar features are enabled.
|
|
57
|
+
*
|
|
58
|
+
* - none: No toolbar shown
|
|
59
|
+
* - basic: Minimal formatting (bold/italic/underline), lists, links
|
|
60
|
+
* - standard: Common formatting plus media (images, tables, etc.)
|
|
61
|
+
* - pro: Full feature set (advanced blocks and tools)
|
|
62
|
+
*/
|
|
63
|
+
declare enum ContentEditorLevel {
|
|
64
|
+
None = "none",
|
|
65
|
+
Basic = "basic",
|
|
66
|
+
Standard = "standard",
|
|
67
|
+
Pro = "pro"
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* INTERNAL: Block specification used by the ref API.
|
|
71
|
+
*
|
|
72
|
+
* Not exported from the package root to avoid locking
|
|
73
|
+
* implementation details. Subject to change without notice.
|
|
74
|
+
*/
|
|
75
|
+
type BlockSpec = {
|
|
76
|
+
kind: string;
|
|
77
|
+
html: string;
|
|
78
|
+
position?: 'start' | 'end';
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Public, imperative API exposed via the component ref.
|
|
82
|
+
*
|
|
83
|
+
* Allows programmatic read/write, focus control, and state checks.
|
|
84
|
+
*/
|
|
85
|
+
type ContentEditorRef = {
|
|
86
|
+
/** Replace the entire document content with the provided HTML. */
|
|
87
|
+
setValue: (html: string) => void;
|
|
88
|
+
/** Return the current document as HTML. */
|
|
89
|
+
getValue: () => string;
|
|
90
|
+
/** Clear the document to an empty state. */
|
|
91
|
+
clear: () => void;
|
|
92
|
+
/** Move focus to the editable area. */
|
|
93
|
+
focus: () => void;
|
|
94
|
+
/** Remove focus from the editable area. */
|
|
95
|
+
blur: () => void;
|
|
96
|
+
/** Whether the editor currently contains no user content. */
|
|
97
|
+
isEmpty: () => boolean;
|
|
98
|
+
/** Whether the editor currently has input focus. */
|
|
99
|
+
isFocused: () => boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Access the underlying Lexical editor instance for advanced usage.
|
|
102
|
+
* Returned type is `any` to avoid leaking internal Lexical types.
|
|
103
|
+
*/
|
|
104
|
+
getEditor: () => any;
|
|
105
|
+
/**
|
|
106
|
+
* Insert or update a block identified by `spec.kind`.
|
|
107
|
+
*
|
|
108
|
+
* If a block with the same `kind` exists, it will be updated;
|
|
109
|
+
* otherwise a new block is inserted. `position` controls whether
|
|
110
|
+
* the insertion occurs at the document 'start' or 'end'.
|
|
111
|
+
*/
|
|
112
|
+
upsertBlock: (spec: BlockSpec) => void;
|
|
113
|
+
/** Remove a previously inserted block by its `kind` identifier. */
|
|
114
|
+
removeBlock: (kind: string) => void;
|
|
115
|
+
/** Check whether a block with the given `kind` exists. */
|
|
116
|
+
hasBlock: (kind: string) => boolean;
|
|
117
|
+
};
|
|
118
|
+
interface ContentEditorProps {
|
|
119
|
+
/** Optional editor namespace used by Lexical for scoping. */
|
|
120
|
+
namespace?: string;
|
|
121
|
+
/** Controlled HTML value rendered by the editor. */
|
|
122
|
+
value: string;
|
|
123
|
+
/** Outer container width (e.g., '100%', '600px'). */
|
|
124
|
+
width?: string;
|
|
125
|
+
/** Outer container height (e.g., '100%', '400px'). */
|
|
126
|
+
height?: string;
|
|
127
|
+
/** When true, focuses the editor on mount. */
|
|
128
|
+
autoFocus?: boolean;
|
|
129
|
+
/** CSS margin applied to the root container. */
|
|
130
|
+
margin?: string | number;
|
|
131
|
+
/** Placeholder text shown when the editor is empty. */
|
|
132
|
+
placeholder?: string;
|
|
133
|
+
/** Height of the editable content area inside the container. */
|
|
134
|
+
contentHeight?: string;
|
|
135
|
+
/** Feature level controlling which toolbar groups are enabled. */
|
|
136
|
+
level?: ContentEditorLevel;
|
|
137
|
+
/**
|
|
138
|
+
* @deprecated Not used by the component. Prefer styling overrides instead.
|
|
139
|
+
*/
|
|
140
|
+
topPlaceholderMargin?: string;
|
|
141
|
+
/** Change handler returning the latest HTML value. */
|
|
142
|
+
onChange: (value: string) => void;
|
|
143
|
+
/** When true, the editor becomes read-only (non-interactive). */
|
|
144
|
+
readOnly?: boolean;
|
|
145
|
+
/**
|
|
146
|
+
* @deprecated Legacy flag intended to show a clear button.
|
|
147
|
+
* This is currently not wired in the UI.
|
|
148
|
+
*/
|
|
149
|
+
clearEditorMode?: boolean;
|
|
150
|
+
/**
|
|
151
|
+
* Simple autocomplete — just pass your raw async API call.
|
|
152
|
+
*
|
|
153
|
+
* The component handles all debouncing, cancellation, and ghost-text
|
|
154
|
+
* insertion internally. Return the raw API response — supported shapes:
|
|
155
|
+
* - `{ generated_text: string }` — single suggestion
|
|
156
|
+
* - `string[]` — list of suggestions
|
|
157
|
+
* - `null / undefined` — no suggestion
|
|
158
|
+
*
|
|
159
|
+
* Example:
|
|
160
|
+
* ```ts
|
|
161
|
+
* suggestFn={async (text) => {
|
|
162
|
+
* const res = await fetch('/api/suggest', { method: 'POST', body: JSON.stringify({ text }) });
|
|
163
|
+
* return res.json(); // return raw — component adapts internally
|
|
164
|
+
* }}
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
suggestFn?: (text: string, cursorIndex?: number) => Promise<any>;
|
|
168
|
+
/**
|
|
169
|
+
* Advanced: full control over autocomplete with manual cancellation.
|
|
170
|
+
* Use `suggestFn` instead unless you need a custom `dismiss()` implementation.
|
|
171
|
+
*/
|
|
172
|
+
useQuery?: (searchText?: string, cursorIndex?: number) => SearchPromise;
|
|
173
|
+
/** Called when the editor gains focus. */
|
|
174
|
+
onFocus?: () => void;
|
|
175
|
+
/** Called when the editor loses focus. */
|
|
176
|
+
onBlur?: () => void;
|
|
177
|
+
/**
|
|
178
|
+
* Fires when the user **accepts** an autocomplete suggestion (Tab / ArrowRight).
|
|
179
|
+
*
|
|
180
|
+
* Use this to send a reward signal to your backend so the model improves
|
|
181
|
+
* over time. Example:
|
|
182
|
+
* ```ts
|
|
183
|
+
* onSuggestionAccept={({ suggestionText, triggerText, method }) => {
|
|
184
|
+
* sendReward({ suggestionText, triggerText }); // hits your reward API
|
|
185
|
+
* }}
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
onSuggestionAccept?: (info: {
|
|
189
|
+
suggestionText: string;
|
|
190
|
+
triggerText?: string;
|
|
191
|
+
method: AcceptMethod;
|
|
192
|
+
}) => void;
|
|
193
|
+
/**
|
|
194
|
+
* Fires when a suggestion is displayed to the user (optional analytics hook).
|
|
195
|
+
*/
|
|
196
|
+
onSuggestionShown?: (info: {
|
|
197
|
+
suggestionText: string;
|
|
198
|
+
triggerText?: string;
|
|
199
|
+
}) => void;
|
|
200
|
+
/**
|
|
201
|
+
* Simple spell/grammar check — just pass your raw async API call.
|
|
202
|
+
*
|
|
203
|
+
* The component handles all debouncing, cancellation, response adaptation,
|
|
204
|
+
* underlines, and popovers internally. Supported API response shapes:
|
|
205
|
+
* - `{ misspelled_words: string[], suggestions: Record<string, string[]>, grammar_correction?: string }`
|
|
206
|
+
* - `{ misspelled: string[], suggestions: Record<string, string[]>, improved_text?: string }`
|
|
207
|
+
* - `SpellCheckIssue[]` (legacy — already-adapted array)
|
|
208
|
+
*
|
|
209
|
+
* Example:
|
|
210
|
+
* ```ts
|
|
211
|
+
* spellCheckFn={async (text) => {
|
|
212
|
+
* const res = await fetch('/api/spellcheck', { method: 'POST', body: JSON.stringify({ text }) });
|
|
213
|
+
* return res.json(); // return raw — component adapts internally
|
|
214
|
+
* }}
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
spellCheckFn?: (text: string) => Promise<any>;
|
|
218
|
+
/**
|
|
219
|
+
* Advanced: full control over spell check with manual cancellation.
|
|
220
|
+
* Use `spellCheckFn` instead unless you need a custom `dismiss()` implementation.
|
|
221
|
+
*/
|
|
222
|
+
useSpellCheck?: (text: string) => SpellCheckResult;
|
|
223
|
+
/**
|
|
224
|
+
* Fires when the user accepts a spell/grammar correction from the popover.
|
|
225
|
+
*
|
|
226
|
+
* Use this to POST a reward signal to your backend.
|
|
227
|
+
* ```ts
|
|
228
|
+
* onSpellCheckAccept={({ original, replacement, message, type }) => {
|
|
229
|
+
* myApi.rewardSpellCheck({ original, replacement });
|
|
230
|
+
* }}
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
onSpellCheckAccept?: (info: {
|
|
234
|
+
original: string;
|
|
235
|
+
replacement: string;
|
|
236
|
+
message: string;
|
|
237
|
+
type?: string;
|
|
238
|
+
}) => void;
|
|
239
|
+
/**
|
|
240
|
+
* Debounce delay (ms) after the user stops typing before the spell-check
|
|
241
|
+
* API is called. Defaults to 1200ms. Tune this to balance responsiveness
|
|
242
|
+
* vs. API call frequency.
|
|
243
|
+
*/
|
|
244
|
+
spellCheckIdleMs?: number;
|
|
245
|
+
/**
|
|
246
|
+
* Debounce delay (ms) after the user stops typing before the `suggestFn`
|
|
247
|
+
* API is called. Defaults to 300ms. Tune this to balance responsiveness
|
|
248
|
+
* vs. API call frequency.
|
|
249
|
+
*/
|
|
250
|
+
suggestIdleMs?: number;
|
|
251
|
+
/** When false, spell checking is disabled without unmounting the plugin. */
|
|
252
|
+
spellCheckEnabled?: boolean;
|
|
253
|
+
/** When true, shows the floating formatting toolbar near text selections. */
|
|
254
|
+
showFloatingToolbar?: boolean;
|
|
255
|
+
/**
|
|
256
|
+
* Maximum word count allowed. When set, a live counter is shown
|
|
257
|
+
* below the editor. Exceeding the limit turns the counter red.
|
|
258
|
+
* Example: wordLimit={500}
|
|
259
|
+
*/
|
|
260
|
+
wordLimit?: number;
|
|
261
|
+
/**
|
|
262
|
+
* Fires when the content crosses the configured word limit boundary.
|
|
263
|
+
*
|
|
264
|
+
* - exceeded: true -> user just exceeded the limit
|
|
265
|
+
* - exceeded: false -> user came back within the limit
|
|
266
|
+
*/
|
|
267
|
+
onWordLimitExceeded?: (info: {
|
|
268
|
+
wordCount: number;
|
|
269
|
+
wordLimit: number;
|
|
270
|
+
exceeded: boolean;
|
|
271
|
+
}) => void;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
declare const ContentEditorComponent: React.ForwardRefExoticComponent<ContentEditorProps & React.RefAttributes<ContentEditorRef>>;
|
|
275
|
+
|
|
276
|
+
export { type AcceptMethod, ContentEditorComponent, ContentEditorLevel, type ContentEditorProps, type ContentEditorRef, type SearchPromise, type SpellCheckIssue, type SpellCheckPayload, type SpellCheckResult };
|