Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

feat: add tui editor #109

Merged
merged 2 commits into from
Feb 23, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"dependencies": {
"@popperjs/core": "^2.5.4",
"@reach/router": "^1.3.4",
"@toast-ui/react-editor": "^2.5.1",
"axios": "^0.21.0",
"classnames": "^2.2.6",
"express": "^4.17.1",
Expand Down
11 changes: 11 additions & 0 deletions src/components/FormField/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Field } from "react-final-form";
import { FORM_FIELD_TYPE } from "../../constants";
import TextInput from "../../components/TextInput";
import TextArea from "../../components/TextArea";
import TuiEditor from "../../components/TuiEditor";
import ReactSelect from "../../components/ReactSelect";
import DateInput from "../../components/DateInput";
import "./styles.module.scss";
Expand Down Expand Up @@ -59,6 +60,16 @@ const FormField = ({ field }) => {
step={field.step}
/>
)}
{field.type === FORM_FIELD_TYPE.TUIEDITOR && (
<TuiEditor
placeholder={field.placeholder}
value={input?.value ?? ""}
onChange={input.onChange}
// onBlur={input.onBlur}
// onFocus={input.onFocus}
className={meta.error && meta.touched ? "error" : ""}
/>
)}
{field.type === FORM_FIELD_TYPE.TEXTAREA && (
<TextArea
placeholder={field.placeholder}
Expand Down
101 changes: 101 additions & 0 deletions src/components/TuiEditor/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* TuiEditor
*/

import React, { useState } from "react";
import PropTypes from "prop-types";
import cn from "classnames";
import { Editor } from "@toast-ui/react-editor";
import styles from "./styles.module.scss";

const TuiEditor = (props) => {
const [editorElement, setEditorElement] = useState(null);
const onChange = () => {
const mk = editorElement.editorInst.getMarkdown();
props.onChange(mk);
};
return (
<div className={cn(styles["editor-container"], props.className)}>
<Editor
{...props}
ref={setEditorElement}
onChange={onChange}
initialValue={props.value}
/>
</div>
);
};

TuiEditor.defaultProps = {
height: "320px",
minHeight: "320px",
initialValue: "",
previewStyle: "",
initialEditType: "wysiwyg",
language: "en-US",
useCommandShortcut: true,
customHTMLSanitizer: null,
frontMatter: false,
hideModeSwitch: true,
referenceDefinition: false,
usageStatistics: false,
useDefaultHTMLSanitizer: true,
};

TuiEditor.propTypes = {
// Editor's initial value
value: PropTypes.string,
className: PropTypes.string,
// Markdown editor's preview style (tab, vertical)
previewStyle: PropTypes.string.isRequired,
// Editor's height style value. Height is applied as border-box ex) '300px', '100%', 'auto'
height: PropTypes.string,
// Initial editor type (markdown, wysiwyg)
initialEditType: PropTypes.string,
// Editor's min-height style value in pixel ex) '300px'
minHeight: PropTypes.string,
// The placeholder text of the editable element.
placeholder: PropTypes.string,
// hide mode switch tab bar
hideModeSwitch: PropTypes.bool,
// language, 'en-US'
language: PropTypes.string,
// whether use keyboard shortcuts to perform commands
useCommandShortcut: PropTypes.bool,
// It would be emitted when editor fully load1
onLoad: PropTypes.func,
// It would be emitted when content changed
onChange: PropTypes.func,
// It would be emitted when format change by cursor position
onStateChange: PropTypes.func,
// It would be emitted when editor get focus
onFocus: PropTypes.func,
// It would be emitted when editor loose focus
onBlur: PropTypes.func,
// hooks
hooks: PropTypes.arrayOf(PropTypes.object),
// send hostname to google analytics
usageStatistics: PropTypes.bool,
// use default htmlSanitizer
useDefaultHTMLSanitizer: PropTypes.bool,
// toolbar items.
toolbarItems: PropTypes.arrayOf(PropTypes.object),
// Array of plugins. A plugin can be either a function or an array in the form of [function, options].
plugins: PropTypes.arrayOf(PropTypes.object),
// Using extended Autolinks specified in GFM spec
extendedAutolinks: PropTypes.object,
// convertor extention
customConvertor: PropTypes.object,
// Attributes of anchor element that should be rel, target, contenteditable, hreflang, type
linkAttribute: PropTypes.object,
// Object containing custom renderer functions correspond to markdown node
customHTMLRenderer: PropTypes.object,
// whether use the specification of link reference definition
referenceDefinition: PropTypes.bool,
// custom HTML sanitizer
customHTMLSanitizer: PropTypes.func,
// whether use the front matter
frontMatter: PropTypes.bool,
};

export default TuiEditor;
37 changes: 37 additions & 0 deletions src/components/TuiEditor/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
@import "styles/include";

.editor-container {
margin-top: 10px;

:global {
// reset style for heading list in headings selection popup
.tui-popup-body {
h1,h2,h3,h4,h4,h5,h6 {
font-weight: revert;
line-height: revert;
}
}

// reset border color
.tui-editor-defaultUI {
border: 1px solid #aaaaab
}

.te-toolbar-section {
border-bottom: 1px solid #aaaaab
}

// hide uplodd file
.tui-editor-popup{
box-shadow: 0px 0px 15px 5px rgba(0,0,0,0.26);
}

.te-popup-add-image .te-tab button, .te-popup-add-image .te-file-type{
display: none !important;
}

.te-popup-add-image .te-url-type{
display: block !important;
}
}
}
15 changes: 15 additions & 0 deletions src/components/TuiEditorViewer/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* TuiEditorViewer
*/

import React, { useState } from "react";
import PropTypes from "prop-types";
import { Viewer } from "@toast-ui/react-editor";

const TuiEditorViewer = (props) => <Viewer initialValue={props.value} />;

TuiEditorViewer.propTypes = {
value: PropTypes.string,
};

export default TuiEditorViewer;
1 change: 1 addition & 0 deletions src/constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ export const ACTION_TYPE = {
export const FORM_FIELD_TYPE = {
TEXT: "text",
TEXTAREA: "textarea",
TUIEDITOR: "tuieditor",
NUMBER: "number",
SELECT: "select",
MULTISELECT: "multiselect",
Expand Down
3 changes: 2 additions & 1 deletion src/routes/JobDetails/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useData } from "hooks/useData";
import { getJobById } from "services/jobs";
import { getSkills } from "services/skills";
import LoadingIndicator from "../../components/LoadingIndicator";
import TuiEditorViewer from "../../components/TuiEditorViewer";
import withAuthentication from "../../hoc/withAuthentication";
import DataItem from "../../components/DataItem";
import IconSkill from "../../assets/images/icon-skill.svg";
Expand Down Expand Up @@ -64,7 +65,7 @@ const JobDetails = ({ teamId, jobId }) => {
{job.title}
</DataItem>
<DataItem title="Job Description" icon={<IconDescription />}>
{job.description}
<TuiEditorViewer value={job.description} />
</DataItem>
<DataItem title="Number of Openings" icon={<IconOpenings />}>
{job.numPositions}
Expand Down
2 changes: 1 addition & 1 deletion src/routes/JobForm/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const getEditJobConfig = (skillOptions, onSubmit) => {
},
{
label: "Job Description",
type: FORM_FIELD_TYPE.TEXTAREA,
type: FORM_FIELD_TYPE.TUIEDITOR,
name: "description",
placeholder: "Job Description",
},
Expand Down
4 changes: 4 additions & 0 deletions src/styles/main.vendor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@
@import "~react-redux-toastr/src/styles/index";
@import "~react-responsive-modal/styles";
@import "~react-loader-spinner/dist/loader/css/react-spinner-loader.css";

// toast-ui.react-editor styles
@import "~codemirror/lib/codemirror.css";
@import "~@toast-ui/editor/dist/toastui-editor.css"