Skip to content

Commit

Permalink
add multiline and rich editing to text fields (close #458) (#2498)
Browse files Browse the repository at this point in the history
  • Loading branch information
AnnieAtHasura authored and rikinsk committed Jul 22, 2019
1 parent dde9908 commit 7a68332
Show file tree
Hide file tree
Showing 5 changed files with 281 additions and 211 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.jsonNormalInput {
.normalInput {
padding-right: 30px;
}

.jsonToggleButton {
.modeToggleButton {
position: absolute;
top: 10px;
right: 10px;
Expand All @@ -11,4 +11,12 @@
&:hover {
opacity: 1.0;
}
}

.modeType {
position: absolute;
top: 6px;
right: 28px;
z-index: 100;
font-style: italic;
}
11 changes: 7 additions & 4 deletions console/src/components/Common/CustomInputTypes/JsonInput.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import React, { useState } from 'react';
import AceEditor from 'react-ace';

const styles = require('./JsonInput.scss');
import 'brace/mode/markdown';
import 'brace/theme/github';

const styles = require('./CustomInput.scss');

const NORMALKEY = 'normal';
const JSONKEY = 'json';
Expand Down Expand Up @@ -112,7 +115,7 @@ const JsonInput = props => {
value={data}
onChange={handleInputChangeAndPropagate}
onKeyUp={handleKeyUpEvent}
className={allProps.className + ' ' + styles.jsonNormalInput}
className={allProps.className + ' ' + styles.normalInput}
/>
);
};
Expand All @@ -126,12 +129,12 @@ const JsonInput = props => {
key="icon_json_editor"
className={
'fa ' +
styles.jsonToggleButton +
styles.modeToggleButton +
(editorType === JSONKEY ? ' fa-compress' : ' fa-expand')
}
onClick={() => updateState(toggleEditorType)}
title={
(editorType === JSONKEY ? 'Collapse' : 'Expand') + '(Ctrl + Space)'
(editorType === JSONKEY ? 'Collapse' : 'Expand') + ' (Ctrl + Space)'
}
/>
</span>
Expand Down
166 changes: 166 additions & 0 deletions console/src/components/Common/CustomInputTypes/TextInput.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import React, { useState } from 'react';
import AceEditor from 'react-ace';

import 'brace/mode/html';
import 'brace/mode/markdown';
import 'brace/theme/github';
import 'brace/theme/chrome';

const styles = require('./CustomInput.scss');

// editorType is what sort of editor. All are ACE Editor
// modes except 0, which is text input

// ACE editor mode names
const EDITORTYPES = [
'normal', // must be first
'text',
'markdown',
'html',
];

// human readable editor names
const EDITORTYPENAMES = [
'single line input',
'multi-line text input',
'markdown',
'html',
];

// short human readable editor names
// for the visible label
const SHORTEDITORTYPENAMES = ['', 'multi-line', 'markdown', 'html'];

const NORMALKEY = 0;

const createInitialState = data => {
const initialState = {
editorType: NORMALKEY,
data: data,
};
return initialState;
};

const TextInput = props => {
const { standardProps, placeholderProp } = props;
const { defaultValue, onChange } = standardProps;
const allProps = { ...standardProps };
delete allProps.defaultValue;
const [state, updateState] = useState(createInitialState(defaultValue));
const { editorType, data } = state;

const updateData = (newData, currentState) => {
return {
...currentState,
data: newData,
};
};

const cycleEditorType = currentState => {
const nextEditorType = (currentState.editorType + 1) % EDITORTYPES.length;

return {
...currentState,
editorType: nextEditorType,
};
};

const handleKeyUpEvent = e => {
if ((e.ctrlKey || event.metaKey) && e.which === 32) {
updateState(cycleEditorType);
}
};

const handleEditorExec = () => {
updateState(cycleEditorType);
};

const handleInputChangeAndPropagate = e => {
const val = e.target.value;
updateState(currentState => updateData(val, currentState));
if (onChange) {
onChange(e);
}
};

const handleTextAreaChangeAndPropagate = (value, e) => {
const val = value;
updateState(currentState => updateData(val, currentState));
if (onChange) {
onChange(e, value);
}
};

const getAceEditor = curmode => {
return (
<AceEditor
key="ace_text_editor"
{...allProps}
mode={curmode}
theme="chrome"
name="texttoggler"
minLines={10}
maxLines={100}
width="100%"
value={data}
showPrintMargin={false}
onChange={handleTextAreaChangeAndPropagate}
showGutter={false}
focus
commands={[
{
name: 'toggleEditor',
bindKey: { win: 'Ctrl-Space', mac: 'Command-Space' },
exec: handleEditorExec,
},
]}
/>
);
};

const getNormalEditor = () => {
return (
<input
key="input_text_editor"
{...allProps}
placeholder={placeholderProp}
value={data}
onChange={handleInputChangeAndPropagate}
onKeyUp={handleKeyUpEvent}
className={allProps.className + ' ' + styles.normalInput}
/>
);
};

const editor =
editorType === NORMALKEY
? getNormalEditor()
: getAceEditor(EDITORTYPES[editorType]);

return (
<span className="text_input_editor">
<label>{editor}</label>
<span
onClick={() => updateState(cycleEditorType)}
title={
'Change to ' +
EDITORTYPENAMES[(editorType + 1) % EDITORTYPES.length] +
' (Ctrl + Space)'
}
>
<span className={styles.modeType}>
{SHORTEDITORTYPENAMES[editorType]}
</span>
<i
key="icon_text_editor"
className={
'fa ' +
styles.modeToggleButton +
(editorType === NORMALKEY ? ' fa-expand' : ' fa-chevron-right')
}
/>
</span>
</span>
);
};
export default TextInput;
Loading

0 comments on commit 7a68332

Please sign in to comment.