equal
deleted
inserted
replaced
1 import { Value } from 'slate' |
1 import { Value } from 'slate'; |
2 import Plain from 'slate-plain-serializer' |
2 import Plain from 'slate-plain-serializer'; |
3 import { Editor } from 'slate-react' |
3 import { Editor } from 'slate-react'; |
4 import React from 'react' |
4 import React from 'react'; |
5 import { Portal } from 'react-portal' |
5 import { Portal } from 'react-portal'; |
6 import HtmlSerializer from './HtmlSerializer' |
6 import { Trans, withNamespaces } from 'react-i18next'; |
7 import AnnotationPlugin from './AnnotationPlugin' |
7 import * as R from 'ramda'; |
8 import CategoriesTooltip from './CategoriesTooltip' |
8 import HtmlSerializer from './HtmlSerializer'; |
|
9 import AnnotationPlugin from './AnnotationPlugin'; |
|
10 import CategoriesTooltip from './CategoriesTooltip'; |
9 import './SlateEditor.css'; |
11 import './SlateEditor.css'; |
10 import { now } from '../../utils'; |
12 import { now } from '../../utils'; |
11 import { defaultAnnotationsCategories } from '../../constants'; |
13 import { defaultAnnotationsCategories } from '../../constants'; |
12 |
14 |
13 const plugins = []; |
15 const plugins = []; |
112 isPortalOpen: false, |
114 isPortalOpen: false, |
113 categories: [], |
115 categories: [], |
114 isCheckboxChecked: false, |
116 isCheckboxChecked: false, |
115 enterKeyValue: 0, |
117 enterKeyValue: 0, |
116 }; |
118 }; |
|
119 |
|
120 this.editor = React.createRef(); |
117 } |
121 } |
118 |
122 |
119 componentDidMount = () => { |
123 componentDidMount = () => { |
120 this.updateMenu(); |
124 this.updateMenu(); |
121 this.focus(); |
125 this.focus(); |
153 // Store start time once when the first character is typed |
157 // Store start time once when the first character is typed |
154 if (!isEmpty && this.state.startedAt === null) { |
158 if (!isEmpty && this.state.startedAt === null) { |
155 Object.assign(newState, { startedAt: now() }); |
159 Object.assign(newState, { startedAt: now() }); |
156 } |
160 } |
157 |
161 |
|
162 const oldState = R.clone(this.state); |
158 this.setState(newState) |
163 this.setState(newState) |
159 |
164 |
160 if (typeof this.props.onChange === 'function') { |
165 if (typeof this.props.onChange === 'function') { |
161 this.props.onChange(newState); |
166 this.props.onChange(R.clone(this.state), oldState, newState); |
162 } |
167 } |
163 } |
168 } |
164 |
169 |
165 /** |
170 /** |
166 * Check if the current selection has a mark with `type` in it. |
171 * Check if the current selection has a mark with `type` in it. |
170 */ |
175 */ |
171 |
176 |
172 hasMark = type => { |
177 hasMark = type => { |
173 const { value } = this.state |
178 const { value } = this.state |
174 return value.activeMarks.some(mark => mark.type === type) |
179 return value.activeMarks.some(mark => mark.type === type) |
175 } |
180 } |
176 |
181 |
177 /** |
182 /** |
178 * Check if the any of the currently selected blocks are of `type`. |
183 * Check if the any of the currently selected blocks are of `type`. |
179 * |
184 * |
180 * @param {String} type |
185 * @param {String} type |
182 */ |
187 */ |
183 |
188 |
184 hasBlock = type => { |
189 hasBlock = type => { |
185 const { value } = this.state |
190 const { value } = this.state |
186 return value.blocks.some(node => node.type === type) |
191 return value.blocks.some(node => node.type === type) |
187 } |
192 } |
188 |
193 |
189 asPlain = () => { |
194 asPlain = () => { |
190 return Plain.serialize(this.state.value); |
195 return Plain.serialize(this.state.value); |
191 } |
196 } |
192 |
197 |
211 const value = Plain.deserialize(''); |
216 const value = Plain.deserialize(''); |
212 this.onChange({value}); |
217 this.onChange({value}); |
213 } |
218 } |
214 |
219 |
215 focus = () => { |
220 focus = () => { |
216 this.refs.editor.focus(); |
221 if(this.editor.current) { |
217 } |
222 this.editor.current.focus(); |
218 |
223 } |
219 /** |
224 } |
|
225 |
|
226 /** |
220 * When a mark button is clicked, toggle the current mark. |
227 * When a mark button is clicked, toggle the current mark. |
221 * |
228 * |
222 * @param {Event} e |
229 * @param {Event} e |
223 * @param {String} type |
230 * @param {String} type |
224 */ |
231 */ |
514 |
521 |
515 renderToolbarCheckbox = () => { |
522 renderToolbarCheckbox = () => { |
516 return ( |
523 return ( |
517 <div className="checkbox float-right"> |
524 <div className="checkbox float-right"> |
518 <label className="mr-2"> |
525 <label className="mr-2"> |
519 <input type="checkbox" checked={this.props.isChecked} onChange={this.onCheckboxChange} /><small className="text-muted ml-1"> Appuyer sur <kbd className="bg-irinotes-form text-muted ml-1">Entrée</kbd> pour ajouter une note</small> |
526 <input type="checkbox" checked={this.props.isChecked} onChange={this.onCheckboxChange} /><small className="text-muted ml-1"><Trans i18nKey="slate_editor.press_enter_msg">Appuyer sur <kbd className="bg-irinotes-form text-muted ml-1">Entrée</kbd> pour ajouter une note</Trans></small> |
520 </label> |
527 </label> |
521 </div> |
528 </div> |
522 ) |
529 ) |
523 } |
530 } |
524 |
531 |
525 renderToolbarButtons = () => { |
532 renderToolbarButtons = () => { |
|
533 const t = this.props.t; |
526 return ( |
534 return ( |
527 <div> |
535 <div> |
528 <button type="button" id="btn-editor" className="btn btn-primary btn-sm text-secondary font-weight-bold float-right" disabled={this.props.isButtonDisabled} onClick={this.onButtonClick}> |
536 <button type="button" id="btn-editor" className="btn btn-primary btn-sm text-secondary font-weight-bold float-right text-capitalize" disabled={this.props.isButtonDisabled} onClick={this.onButtonClick}> |
529 { this.props.note ? 'Sauvegarder' : 'Ajouter' } |
537 { this.props.note ? t('common.save') : t('common.add') } |
530 </button> |
538 </button> |
531 { !this.props.note && this.renderToolbarCheckbox() } |
539 { !this.props.note && this.renderToolbarCheckbox() } |
532 </div> |
540 </div> |
533 ); |
541 ); |
534 } |
542 } |
625 * |
633 * |
626 * @return {Element} |
634 * @return {Element} |
627 */ |
635 */ |
628 |
636 |
629 renderEditor = () => { |
637 renderEditor = () => { |
|
638 const t = this.props.t; |
630 return ( |
639 return ( |
631 <div className="editor-slatejs p-2"> |
640 <div className="editor-slatejs p-2"> |
632 {this.renderHoveringMenu()} |
641 {this.renderHoveringMenu()} |
633 <Editor |
642 <Editor |
634 ref="editor" |
643 ref={this.editor} |
635 spellCheck |
644 spellCheck |
636 placeholder={'Votre espace de prise de note...'} |
645 placeholder={t('slate_editor.placeholder')} |
637 schema={schema} |
646 schema={schema} |
638 plugins={plugins} |
647 plugins={plugins} |
639 value={this.state.value} |
648 value={this.state.value} |
640 onChange={this.onChange} |
649 onChange={this.onChange} |
641 onKeyDown={this.onKeyDown} |
650 onKeyDown={this.onKeyDown} |
689 |
698 |
690 /** |
699 /** |
691 * Export. |
700 * Export. |
692 */ |
701 */ |
693 |
702 |
694 export default SlateEditor |
703 export default withNamespaces("", { |
|
704 innerRef: (ref) => { |
|
705 const editorRef = (ref && ref.props) ? ref.props.editorRef : null; |
|
706 if(editorRef && editorRef.hasOwnProperty('current')) { |
|
707 editorRef.current = ref; |
|
708 } |
|
709 } |
|
710 })(SlateEditor); |
|
711 // export default SlateEditor; |