-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
93ae5ae
commit b9f3ce1
Showing
5 changed files
with
153 additions
and
89 deletions.
There are no files selected for viewing
93 changes: 5 additions & 88 deletions
93
apps/sensenet/src/components/field-controls/html-editor.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,99 +1,16 @@ | ||
/** | ||
* @module FieldControls | ||
*/ | ||
import { Box, InputLabel, Typography, useTheme } from '@material-ui/core' | ||
import { changeTemplatedValue, ReactClientFieldSetting } from '@sensenet/controls-react' | ||
import React, { useEffect, useRef, useState } from 'react' | ||
import MonacoEditor from 'react-monaco-editor' | ||
|
||
import { useTheme } from '@material-ui/core' | ||
import { ReactClientFieldSetting, HtmlEditor as SnHtmlEditor } from '@sensenet/controls-react' | ||
import React from 'react' | ||
|
||
/** | ||
* Field control that represents a LongText field with Html highlights. Available values will be populated from the FieldSettings. | ||
*/ | ||
export const HtmlEditor: React.FC<ReactClientFieldSetting> = (props) => { | ||
// const localization = useLocalization() | ||
const initialState = | ||
props.fieldValue || (props.actionName === 'new' && changeTemplatedValue(props.settings.DefaultValue)) || '' | ||
const [value, setValue] = useState(initialState) | ||
const theme = useTheme() | ||
|
||
const readonly = props.actionName === 'browse' || props.settings.ReadOnly | ||
|
||
const editorRef = useRef<MonacoEditor>(null) | ||
const containerRef = useRef<HTMLDivElement>(null) | ||
|
||
useEffect(() => { | ||
console.log({ editorRef, containerRef }) | ||
|
||
if (!editorRef.current) { | ||
return | ||
} | ||
editorRef.current.editor!.onDidContentSizeChange(() => { | ||
const contentHeight = editorRef?.current?.editor?.getContentHeight() | ||
|
||
console.log('contentHeight', contentHeight) | ||
|
||
containerRef.current!.style.height = `${contentHeight}px` | ||
}) | ||
}, [editorRef, containerRef, value]) | ||
|
||
return ( | ||
<> | ||
<InputLabel shrink>{props.settings.DisplayName}</InputLabel> | ||
|
||
<div style={{ maxHeight: '68vh', margin: '0.5rem 0' }} ref={containerRef} data-test="html-editor-container"> | ||
<MonacoEditor | ||
ref={editorRef} | ||
{...props} | ||
width="100%" | ||
height="100%" | ||
value={value} | ||
onChange={(v) => { | ||
setValue(v) | ||
props.fieldOnChange?.(props.settings.Name, v) | ||
}} | ||
options={{ | ||
automaticLayout: true, | ||
contextmenu: true, | ||
hideCursorInOverviewRuler: true, | ||
lineNumbers: 'on', | ||
selectOnLineNumbers: true, | ||
scrollBeyondLastLine: false, | ||
minimap: { | ||
enabled: true, | ||
}, | ||
roundedSelection: false, | ||
readOnly: readonly, | ||
cursorStyle: 'line', | ||
scrollbar: { | ||
horizontalSliderSize: 4, | ||
verticalScrollbarSize: 6, | ||
// vertical: 'hidden', | ||
}, | ||
|
||
wordWrap: 'on', | ||
autoIndent: 'advanced', | ||
matchBrackets: 'always', | ||
language: 'html', | ||
suggest: { | ||
snippetsPreventQuickSuggestions: false, | ||
showProperties: true, | ||
showKeywords: true, | ||
showWords: true, | ||
}, | ||
}} | ||
theme={theme.palette.type === 'dark' ? 'admin-ui-dark' : 'vs-light'} | ||
editorWillMount={(monaco) => { | ||
monaco.editor.defineTheme('admin-ui-dark', { | ||
base: 'vs-dark', | ||
inherit: true, | ||
rules: [], | ||
colors: { | ||
'editor.background': '#121212', | ||
}, | ||
}) | ||
}} | ||
/> | ||
</div> | ||
</> | ||
) | ||
return <SnHtmlEditor theme={theme} {...props} /> | ||
} |
103 changes: 103 additions & 0 deletions
103
packages/sn-controls-react/src/fieldcontrols/html-editor.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/** | ||
* @module FieldControls | ||
*/ | ||
import { InputLabel, Theme } from '@material-ui/core' | ||
import React, { useEffect, useRef, useState } from 'react' | ||
import MonacoEditor from 'react-monaco-editor' | ||
|
||
import { changeTemplatedValue } from '../helpers' | ||
import { ReactClientFieldSetting } from './client-field-setting' | ||
|
||
/** | ||
* Field control that represents a LongText field. Available values will be populated from the FieldSettings. | ||
*/ | ||
export const HtmlEditor: React.FC< | ||
ReactClientFieldSetting & { | ||
theme?: Theme | ||
test?: boolean | ||
} | ||
> = (props) => { | ||
const initialState = | ||
props.fieldValue || (props.actionName === 'new' && changeTemplatedValue(props.settings.DefaultValue)) || '' | ||
const [value, setValue] = useState(initialState) | ||
|
||
const editorRef = useRef<MonacoEditor>(null) | ||
const containerRef = useRef<HTMLDivElement>(null) | ||
|
||
useEffect(() => { | ||
if (!editorRef.current) { | ||
return | ||
} | ||
editorRef.current.editor!.onDidContentSizeChange(() => { | ||
const contentHeight = editorRef?.current?.editor?.getContentHeight() | ||
|
||
containerRef.current!.style.height = `${contentHeight}px` | ||
}) | ||
}, [editorRef]) | ||
const readonly = props.actionName === 'browse' || props.settings.ReadOnly | ||
|
||
if (props.test) { | ||
return <div data-test="html-editor-container">{value}</div> | ||
} | ||
|
||
return ( | ||
<> | ||
<InputLabel shrink>{props.settings.DisplayName}</InputLabel> | ||
|
||
<div style={{ maxHeight: '68vh', margin: '0.5rem 0' }} ref={containerRef} data-test="html-editor-container"> | ||
<MonacoEditor | ||
ref={editorRef} | ||
{...props} | ||
width="100%" | ||
height="100%" | ||
value={value} | ||
onChange={(v) => { | ||
setValue(v) | ||
props.fieldOnChange?.(props.settings.Name, v) | ||
}} | ||
options={{ | ||
automaticLayout: true, | ||
contextmenu: true, | ||
hideCursorInOverviewRuler: true, | ||
lineNumbers: 'on', | ||
selectOnLineNumbers: true, | ||
scrollBeyondLastLine: false, | ||
minimap: { | ||
enabled: true, | ||
}, | ||
roundedSelection: false, | ||
readOnly: readonly, | ||
cursorStyle: 'line', | ||
scrollbar: { | ||
horizontalSliderSize: 4, | ||
verticalScrollbarSize: 6, | ||
// vertical: 'hidden', | ||
}, | ||
|
||
wordWrap: 'on', | ||
autoIndent: 'advanced', | ||
matchBrackets: 'always', | ||
language: 'html', | ||
suggest: { | ||
snippetsPreventQuickSuggestions: false, | ||
showProperties: true, | ||
showKeywords: true, | ||
showWords: true, | ||
}, | ||
}} | ||
theme={props.theme?.palette.type === 'dark' ? 'admin-ui-dark' : 'vs-light'} | ||
editorWillMount={(monaco) => { | ||
monaco.editor.defineTheme('admin-ui-dark', { | ||
base: 'vs-dark', | ||
inherit: true, | ||
rules: [], | ||
colors: { | ||
'editor.background': '#121212', | ||
}, | ||
}) | ||
}} | ||
/> | ||
</div> | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { ActionName } from '@sensenet/control-mapper' | ||
import { mount, ReactWrapper } from 'enzyme' | ||
import React from 'react' | ||
import { act } from 'react-dom/test-utils' | ||
import { defaultLocalization, HtmlEditor } from '../src/fieldcontrols' | ||
|
||
jest.mock('react-monaco-editor', () => | ||
jest.fn((props) => { | ||
return <div data-test="mock-monaco-editor">{props.value}</div> | ||
}), | ||
) | ||
|
||
describe('Html Editor', () => { | ||
it('should display the content', async () => { | ||
const props = { | ||
actionName: 'edit' as ActionName, | ||
settings: { | ||
Name: 'test', | ||
DisplayName: 'Test', | ||
Description: 'Test', | ||
Compulsory: false, | ||
ReadOnly: false, | ||
DefaultValue: 'Test', | ||
Type: 'LongTextField', | ||
FieldClassName: 'SenseNet.ContentRepository.Fields.LongTextField', | ||
}, | ||
localization: defaultLocalization, | ||
fieldValue: '<p>Test</p>', | ||
fieldOnChange: jest.fn(), | ||
} | ||
|
||
let wrapper: ReactWrapper<any, Readonly<{}>, React.Component<{}, {}, any>> | ||
|
||
await act(async () => { | ||
wrapper = mount(<HtmlEditor {...props} />) | ||
}) | ||
wrapper!.update() | ||
|
||
const htmlEditorContainer = wrapper!.find('[data-test="html-editor-container"]') | ||
|
||
expect(htmlEditorContainer.text()).toBe('<p>Test</p>') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters