Skip to content

Commit

Permalink
Integrate Lexical editor into Details Pane
Browse files Browse the repository at this point in the history
  • Loading branch information
QubitPi committed Dec 19, 2023
1 parent b25f120 commit 85bdf36
Show file tree
Hide file tree
Showing 7 changed files with 355 additions and 2 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"@babel/preset-env": "^7.1.0",
"@babel/preset-react": "^7.0.0",
"@hot-loader/react-dom": "^17.0.2",
"@lexical/react": "^0.12.5",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
"@testing-library/jest-dom": "^5.15.0",
"@testing-library/react": "^12.1.2",
Expand Down Expand Up @@ -137,6 +138,7 @@
"jest-canvas-mock": "^1.1.0",
"js2xmlparser": "^3.0.0",
"json-loader": "^0.5.7",
"lexical": "^0.12.5",
"lint-staged": "^4.1.3",
"mini-css-extract-plugin": "^0.4.4",
"mockdate": "^2.0.5",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ import { StyleableRelType } from './StyleableRelType'
import { PaneBody, PaneHeader, PaneTitle, PaneWrapper } from './styled'
import { DetailsPaneProps } from 'neo4j-arc'

import { DETAILS_PANE_TITLE_UPDATE } from 'neo4j-arc/graph-visualization'
import {
DETAILS_PANE_TITLE_UPDATE,
Editor
} from 'neo4j-arc/graph-visualization'

export const DETAILS_PANE_STEP_SIZE = 1000
export function DetailsPane({
Expand Down Expand Up @@ -147,6 +150,7 @@ export function DetailsPane({
nodeInspectorWidth={nodeInspectorWidth}
onGraphInteraction={onGraphInteraction}
/>
{vizItem.type === 'node' && <Editor />}
</PaneBody>
)}
</PaneWrapper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
DETAILS_PANE_TITLE_UPDATE,
GraphInteractionCallBack
} from '../Graph/GraphEventHandlerModel'
import DefaultEditor from './Editor/DefaultEditor'

export const DETAILS_PANE_STEP_SIZE = 1000
export type DetailsPaneProps = {
Expand Down Expand Up @@ -157,6 +158,7 @@ export function DefaultDetailsPane({
/>
</PaneBody>
)}
{vizItem.type === 'node' && <DefaultEditor />}
</PaneWrapper>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*
* Copyright Jiaqi Liu
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React, { useState } from 'react'

import { AutoFocusPlugin } from '@lexical/react/LexicalAutoFocusPlugin'
import { LexicalComposer } from '@lexical/react/LexicalComposer'
import { ContentEditable } from '@lexical/react/LexicalContentEditable'
import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary'
import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin'
import { HeadingNode, QuoteNode } from '@lexical/rich-text'
import { TableCellNode, TableNode, TableRowNode } from '@lexical/table'
import { ListItemNode, ListNode } from '@lexical/list'
import { CodeHighlightNode, CodeNode } from '@lexical/code'
import { AutoLinkNode, LinkNode } from '@lexical/link'
import { StyledDefaultEditor } from './styled'

export default function DefaultEditor(): JSX.Element {
const initialConfig = {
namespace: 'DefaultDetailsPaneEditor',
onError: (error: Error) => {
throw error
},
nodes: [
HeadingNode,
ListNode,
ListItemNode,
QuoteNode,
CodeNode,
CodeHighlightNode,
TableNode,
TableCellNode,
TableRowNode,
AutoLinkNode,
LinkNode
],
theme: {
ltr: 'ltr',
rtl: 'rtl',
placeholder: 'editor-placeholder',
paragraph: 'editor-paragraph',
quote: 'editor-quote',
heading: {
h1: 'editor-heading-h1',
h2: 'editor-heading-h2',
h3: 'editor-heading-h3',
h4: 'editor-heading-h4',
h5: 'editor-heading-h5'
},
list: {
nested: {
listitem: 'editor-nested-listitem'
},
ol: 'editor-list-ol',
ul: 'editor-list-ul',
listitem: 'editor-listitem'
},
image: 'editor-image',
link: 'editor-link',
text: {
bold: 'editor-text-bold',
italic: 'editor-text-italic',
overflowed: 'editor-text-overflowed',
hashtag: 'editor-text-hashtag',
underline: 'editor-text-underline',
strikethrough: 'editor-text-strikethrough',
underlineStrikethrough: 'editor-text-underlineStrikethrough',
code: 'editor-text-code'
},
code: 'editor-code',
codeHighlight: {
atrule: 'editor-tokenAttr',
attr: 'editor-tokenAttr',
boolean: 'editor-tokenProperty',
builtin: 'editor-tokenSelector',
cdata: 'editor-tokenComment',
char: 'editor-tokenSelector',
class: 'editor-tokenFunction',
'class-name': 'editor-tokenFunction',
comment: 'editor-tokenComment',
constant: 'editor-tokenProperty',
deleted: 'editor-tokenProperty',
doctype: 'editor-tokenComment',
entity: 'editor-tokenOperator',
function: 'editor-tokenFunction',
important: 'editor-tokenVariable',
inserted: 'editor-tokenSelector',
keyword: 'editor-tokenAttr',
namespace: 'editor-tokenVariable',
number: 'editor-tokenProperty',
operator: 'editor-tokenOperator',
prolog: 'editor-tokenComment',
property: 'editor-tokenProperty',
punctuation: 'editor-tokenPunctuation',
regex: 'editor-tokenVariable',
selector: 'editor-tokenSelector',
string: 'editor-tokenSelector',
symbol: 'editor-tokenProperty',
tag: 'editor-tokenProperty',
url: 'editor-tokenOperator',
variable: 'editor-tokenVariable'
}
}
}

const [floatingAnchorElem, setFloatingAnchorElem] =
useState<HTMLDivElement | null>(null)

const onRef = (_floatingAnchorElem: HTMLDivElement) => {
if (_floatingAnchorElem !== null) {
setFloatingAnchorElem(_floatingAnchorElem)
}
}

return (
<StyledDefaultEditor>
<LexicalComposer initialConfig={initialConfig}>
<div className="editor-container">
<div className="editor-inner">
<AutoFocusPlugin />
<RichTextPlugin
placeholder={<Placeholder />}
contentEditable={
<div className="editor-scroller">
<div className="editor" ref={onRef}>
<ContentEditable />
</div>
</div>
}
ErrorBoundary={LexicalErrorBoundary}
/>
</div>
</div>
</LexicalComposer>
</StyledDefaultEditor>
)
}

function Placeholder() {
return <div className="editor-placeholder">Enter some plain text...</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright Jiaqi Liu
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import styled from 'styled-components'

export const StyledDefaultEditor = styled.div`
height: 100px;
`
4 changes: 4 additions & 0 deletions src/neo4j-arc/graph-visualization/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import DefaultEditor from './GraphVisualizer/DefaultPanelContent/Editor/DefaultEditor'

export { NodeModel } from './models/Node'
export { GraphModel } from './models/Graph'
export { GraphStyleModel, Selector } from './models/GraphStyle'
Expand Down Expand Up @@ -62,3 +64,5 @@ export const resources = {
}
}
}

export { default as Editor } from './GraphVisualizer/DefaultPanelContent/Editor/DefaultEditor'
Loading

0 comments on commit 85bdf36

Please sign in to comment.