| author | salimr <riwad.salim@yahoo.fr> |
| Tue, 25 Sep 2018 02:02:13 +0200 | |
| changeset 157 | 5c3af4f10e92 |
| parent 143 | cfcbf4bc66f1 |
| child 159 | a4705c2b4544 |
| permissions | -rw-r--r-- |
| 157 | 1 |
import { Value } from 'slate' |
2 |
import Plain from 'slate-plain-serializer' |
|
3 |
import { Editor } from 'slate-react' |
|
| 5 | 4 |
import React from 'react' |
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
5 |
import Portal from 'react-portal' |
|
26
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
6 |
import Immutable from 'immutable' |
|
17
877d8796b86d
Store serialized HTML in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
16
diff
changeset
|
7 |
import HtmlSerializer from '../HtmlSerializer' |
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
8 |
import AnnotationPlugin from '../AnnotationPlugin' |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
9 |
import CategoriesTooltip from './CategoriesTooltip' |
|
74
043477fd5c5c
add api call to save notes. internally use ts for time data for notes and session
ymh <ymh.work@gmail.com>
parents:
72
diff
changeset
|
10 |
import { now } from '../utils'; |
|
138
a1fb2ced3049
propagate annotations categories from session protocol definition
ymh <ymh.work@gmail.com>
parents:
103
diff
changeset
|
11 |
import { defaultAnnotationsCategories } from '../constants'; |
|
19
f1b125b95fe9
Introduce "annotation" plugin.
Alexandre Segura <mex.zktk@gmail.com>
parents:
17
diff
changeset
|
12 |
|
|
f1b125b95fe9
Introduce "annotation" plugin.
Alexandre Segura <mex.zktk@gmail.com>
parents:
17
diff
changeset
|
13 |
const plugins = []; |
| 5 | 14 |
|
15 |
/** |
|
16 |
* Define the default node type. |
|
17 |
*/ |
|
18 |
||
19 |
const DEFAULT_NODE = 'paragraph' |
|
20 |
||
21 |
/** |
|
22 |
* Define a schema. |
|
23 |
* |
|
24 |
* @type {Object} |
|
25 |
*/ |
|
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
26 |
// TODO Check if we can move this to the plugin using the schema option |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
27 |
// https://docs.slatejs.org/reference/plugins/plugin.html#schema |
| 5 | 28 |
const schema = { |
29 |
nodes: { |
|
30 |
'bulleted-list': props => <ul {...props.attributes}>{props.children}</ul>, |
|
31 |
'list-item': props => <li {...props.attributes}>{props.children}</li>, |
|
32 |
'numbered-list': props => <ol {...props.attributes}>{props.children}</ol>, |
|
33 |
}, |
|
34 |
marks: { |
|
35 |
bold: { |
|
36 |
fontWeight: 'bold' |
|
37 |
}, |
|
|
25
e04714a1d4eb
Improve categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
21
diff
changeset
|
38 |
category: props => { |
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
39 |
const data = props.mark.data; |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
40 |
return <span style={{ backgroundColor: data.get('color') }}>{props.children}</span> |
| 5 | 41 |
}, |
42 |
italic: { |
|
43 |
fontStyle: 'italic' |
|
44 |
}, |
|
45 |
underlined: { |
|
| 157 | 46 |
textDecoration: 'underlined' |
| 5 | 47 |
} |
48 |
} |
|
49 |
} |
|
50 |
||
| 157 | 51 |
const initialValue = Value.fromJSON({ |
52 |
document: { |
|
53 |
nodes: [ |
|
54 |
{ |
|
55 |
object: 'block', |
|
56 |
type: 'paragraph', |
|
57 |
nodes: [ |
|
58 |
{ |
|
59 |
object: 'text', |
|
60 |
leaves: [ |
|
61 |
{ |
|
62 |
text: '', |
|
63 |
}, |
|
64 |
], |
|
65 |
}, |
|
66 |
], |
|
67 |
}, |
|
68 |
], |
|
69 |
}, |
|
70 |
}) |
|
71 |
||
| 5 | 72 |
/** |
73 |
* The rich text example. |
|
74 |
* |
|
75 |
* @type {Component} |
|
76 |
*/ |
|
77 |
||
| 8 | 78 |
class SlateEditor extends React.Component { |
| 5 | 79 |
|
80 |
/** |
|
81 |
* Deserialize the initial editor state. |
|
82 |
* |
|
83 |
* @type {Object} |
|
84 |
*/ |
|
|
11
6fb4de54acea
Delete default state, focus on textarea.
Alexandre Segura <mex.zktk@gmail.com>
parents:
8
diff
changeset
|
85 |
constructor(props) { |
|
6fb4de54acea
Delete default state, focus on textarea.
Alexandre Segura <mex.zktk@gmail.com>
parents:
8
diff
changeset
|
86 |
super(props); |
|
19
f1b125b95fe9
Introduce "annotation" plugin.
Alexandre Segura <mex.zktk@gmail.com>
parents:
17
diff
changeset
|
87 |
|
|
f1b125b95fe9
Introduce "annotation" plugin.
Alexandre Segura <mex.zktk@gmail.com>
parents:
17
diff
changeset
|
88 |
const annotationPlugin = AnnotationPlugin({ |
|
102
b0e36664f1f2
Add TextPositionSelector.
Alexandre Segura <mex.zktk@gmail.com>
parents:
80
diff
changeset
|
89 |
onChange: (text, start, end) => { |
|
b0e36664f1f2
Add TextPositionSelector.
Alexandre Segura <mex.zktk@gmail.com>
parents:
80
diff
changeset
|
90 |
this.setState({ |
|
b0e36664f1f2
Add TextPositionSelector.
Alexandre Segura <mex.zktk@gmail.com>
parents:
80
diff
changeset
|
91 |
currentSelectionText: text, |
|
b0e36664f1f2
Add TextPositionSelector.
Alexandre Segura <mex.zktk@gmail.com>
parents:
80
diff
changeset
|
92 |
currentSelectionStart: start, |
|
b0e36664f1f2
Add TextPositionSelector.
Alexandre Segura <mex.zktk@gmail.com>
parents:
80
diff
changeset
|
93 |
currentSelectionEnd: end |
|
b0e36664f1f2
Add TextPositionSelector.
Alexandre Segura <mex.zktk@gmail.com>
parents:
80
diff
changeset
|
94 |
}); |
|
19
f1b125b95fe9
Introduce "annotation" plugin.
Alexandre Segura <mex.zktk@gmail.com>
parents:
17
diff
changeset
|
95 |
} |
|
f1b125b95fe9
Introduce "annotation" plugin.
Alexandre Segura <mex.zktk@gmail.com>
parents:
17
diff
changeset
|
96 |
}); |
|
f1b125b95fe9
Introduce "annotation" plugin.
Alexandre Segura <mex.zktk@gmail.com>
parents:
17
diff
changeset
|
97 |
|
|
f1b125b95fe9
Introduce "annotation" plugin.
Alexandre Segura <mex.zktk@gmail.com>
parents:
17
diff
changeset
|
98 |
plugins.push(annotationPlugin); |
|
f1b125b95fe9
Introduce "annotation" plugin.
Alexandre Segura <mex.zktk@gmail.com>
parents:
17
diff
changeset
|
99 |
|
| 157 | 100 |
|
|
11
6fb4de54acea
Delete default state, focus on textarea.
Alexandre Segura <mex.zktk@gmail.com>
parents:
8
diff
changeset
|
101 |
this.state = { |
| 157 | 102 |
value: props.note ? initialValue : Plain.deserialize(''), |
|
16
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
103 |
startedAt: null, |
|
19
f1b125b95fe9
Introduce "annotation" plugin.
Alexandre Segura <mex.zktk@gmail.com>
parents:
17
diff
changeset
|
104 |
finishedAt: null, |
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
105 |
currentSelectionText: '', |
|
102
b0e36664f1f2
Add TextPositionSelector.
Alexandre Segura <mex.zktk@gmail.com>
parents:
80
diff
changeset
|
106 |
currentSelectionStart: 0, |
|
b0e36664f1f2
Add TextPositionSelector.
Alexandre Segura <mex.zktk@gmail.com>
parents:
80
diff
changeset
|
107 |
currentSelectionEnd: 0, |
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
108 |
hoveringMenu: null, |
|
26
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
109 |
isPortalOpen: false, |
|
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
110 |
categories: Immutable.List([]), |
|
72
7634b424f426
Add checkbox to add not on enter key.
Alexandre Segura <mex.zktk@gmail.com>
parents:
64
diff
changeset
|
111 |
isCheckboxChecked: false, |
|
11
6fb4de54acea
Delete default state, focus on textarea.
Alexandre Segura <mex.zktk@gmail.com>
parents:
8
diff
changeset
|
112 |
}; |
|
6fb4de54acea
Delete default state, focus on textarea.
Alexandre Segura <mex.zktk@gmail.com>
parents:
8
diff
changeset
|
113 |
} |
| 5 | 114 |
|
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
115 |
componentDidMount = () => { |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
116 |
this.updateMenu(); |
|
11
6fb4de54acea
Delete default state, focus on textarea.
Alexandre Segura <mex.zktk@gmail.com>
parents:
8
diff
changeset
|
117 |
this.focus(); |
|
6fb4de54acea
Delete default state, focus on textarea.
Alexandre Segura <mex.zktk@gmail.com>
parents:
8
diff
changeset
|
118 |
} |
| 5 | 119 |
|
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
120 |
componentDidUpdate = () => { |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
121 |
this.updateMenu(); |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
122 |
} |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
123 |
|
| 157 | 124 |
/** |
125 |
* On change, save the new state. |
|
| 5 | 126 |
* |
| 157 | 127 |
* @param {Change} change |
| 5 | 128 |
*/ |
129 |
||
| 157 | 130 |
onChange = ({value}) => { |
|
16
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
131 |
|
|
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
132 |
let newState = { |
| 157 | 133 |
value: value, |
|
16
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
134 |
startedAt: this.state.startedAt |
|
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
135 |
}; |
|
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
136 |
|
| 157 | 137 |
const isEmpty = value.document.length === 0; |
|
16
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
138 |
|
|
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
139 |
// Reset timers when the text is empty |
|
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
140 |
if (isEmpty) { |
|
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
141 |
Object.assign(newState, { |
|
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
142 |
startedAt: null, |
|
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
143 |
finishedAt: null |
|
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
144 |
}); |
|
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
145 |
} else { |
|
74
043477fd5c5c
add api call to save notes. internally use ts for time data for notes and session
ymh <ymh.work@gmail.com>
parents:
72
diff
changeset
|
146 |
Object.assign(newState, { finishedAt: now() }); |
|
16
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
147 |
} |
|
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
148 |
|
|
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
149 |
// Store start time once when the first character is typed |
|
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
150 |
if (!isEmpty && this.state.startedAt === null) { |
|
74
043477fd5c5c
add api call to save notes. internally use ts for time data for notes and session
ymh <ymh.work@gmail.com>
parents:
72
diff
changeset
|
151 |
Object.assign(newState, { startedAt: now() }); |
|
16
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
152 |
} |
|
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
153 |
|
|
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
154 |
this.setState(newState) |
|
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
155 |
|
|
11
6fb4de54acea
Delete default state, focus on textarea.
Alexandre Segura <mex.zktk@gmail.com>
parents:
8
diff
changeset
|
156 |
if (typeof this.props.onChange === 'function') { |
|
16
e67cd18cc594
Draft implementation of note timing.
Alexandre Segura <mex.zktk@gmail.com>
parents:
15
diff
changeset
|
157 |
this.props.onChange(newState); |
| 8 | 158 |
} |
| 5 | 159 |
} |
160 |
||
| 157 | 161 |
/** |
162 |
* Check if the current selection has a mark with `type` in it. |
|
163 |
* |
|
164 |
* @param {String} type |
|
165 |
* @return {Boolean} |
|
166 |
*/ |
|
167 |
||
168 |
hasMark = type => { |
|
169 |
const { value } = this.state |
|
170 |
return value.activeMarks.some(mark => mark.type === type) |
|
171 |
} |
|
172 |
||
173 |
/** |
|
174 |
* Check if the any of the currently selected blocks are of `type`. |
|
175 |
* |
|
176 |
* @param {String} type |
|
177 |
* @return {Boolean} |
|
178 |
*/ |
|
179 |
||
180 |
hasBlock = type => { |
|
181 |
const { value } = this.state |
|
182 |
return value.blocks.some(node => node.type === type) |
|
183 |
} |
|
184 |
||
| 5 | 185 |
asPlain = () => { |
| 157 | 186 |
return Plain.serialize(this.state.value); |
| 5 | 187 |
} |
188 |
||
| 15 | 189 |
asRaw = () => { |
| 157 | 190 |
return JSON.stringify(this.state.value.toJSON()); |
| 15 | 191 |
} |
192 |
||
|
17
877d8796b86d
Store serialized HTML in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
16
diff
changeset
|
193 |
asHtml = () => { |
| 157 | 194 |
return HtmlSerializer.serialize(this.state.value); |
|
17
877d8796b86d
Store serialized HTML in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
16
diff
changeset
|
195 |
} |
|
877d8796b86d
Store serialized HTML in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
16
diff
changeset
|
196 |
|
|
26
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
197 |
asCategories = () => { |
|
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
198 |
return this.state.categories |
|
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
199 |
} |
|
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
200 |
|
|
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
201 |
removeCategory = (categories, key, text) => { |
|
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
202 |
const categoryIndex = categories.findIndex(category => category.key === key && category.text === text) |
|
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
203 |
return categories.delete(categoryIndex) |
|
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
204 |
} |
|
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
205 |
|
| 5 | 206 |
clear = () => { |
| 157 | 207 |
const value = Plain.deserialize(''); |
208 |
this.onChange({value}); |
|
| 5 | 209 |
} |
210 |
||
|
11
6fb4de54acea
Delete default state, focus on textarea.
Alexandre Segura <mex.zktk@gmail.com>
parents:
8
diff
changeset
|
211 |
focus = () => { |
|
6fb4de54acea
Delete default state, focus on textarea.
Alexandre Segura <mex.zktk@gmail.com>
parents:
8
diff
changeset
|
212 |
this.refs.editor.focus(); |
|
6fb4de54acea
Delete default state, focus on textarea.
Alexandre Segura <mex.zktk@gmail.com>
parents:
8
diff
changeset
|
213 |
} |
|
6fb4de54acea
Delete default state, focus on textarea.
Alexandre Segura <mex.zktk@gmail.com>
parents:
8
diff
changeset
|
214 |
|
| 5 | 215 |
/** |
216 |
* On key down, if it's a formatting command toggle a mark. |
|
217 |
* |
|
218 |
* @param {Event} e |
|
219 |
* @param {Object} data |
|
| 157 | 220 |
* @param {Change} change |
221 |
* @return {Change} |
|
| 5 | 222 |
*/ |
223 |
||
| 157 | 224 |
onKeyDown = (e, change) => { |
225 |
// if (data.key === 'enter' && this.props.isChecked && typeof this.props.onEnterKeyDown === 'function') { |
|
226 |
||
227 |
// e.preventDefault(); |
|
228 |
// this.props.onEnterKeyDown(); |
|
229 |
||
230 |
// return change; |
|
231 |
// } |
|
232 |
||
233 |
// if (!data.isMod) return |
|
234 |
if (!e.ctrlKey) return |
|
235 |
// Decide what to do based on the key code... |
|
236 |
switch (e.key) { |
|
237 |
// When "B" is pressed, add a "bold" mark to the text. |
|
238 |
case 'b': { |
|
239 |
e.preventDefault() |
|
240 |
change.toggleMark('bold') |
|
|
64
aecde527900a
Introduce adding note on "enter" key.
Alexandre Segura <mex.zktk@gmail.com>
parents:
62
diff
changeset
|
241 |
|
| 157 | 242 |
return true |
243 |
} |
|
244 |
case 'i': { |
|
245 |
// When "U" is pressed, add an "italic" mark to the text. |
|
246 |
e.preventDefault() |
|
247 |
change.toggleMark('italic') |
|
|
72
7634b424f426
Add checkbox to add not on enter key.
Alexandre Segura <mex.zktk@gmail.com>
parents:
64
diff
changeset
|
248 |
|
| 157 | 249 |
return true |
250 |
} |
|
251 |
case 'u': { |
|
252 |
// When "U" is pressed, add an "underline" mark to the text. |
|
253 |
e.preventDefault() |
|
254 |
change.toggleMark('underlined') |
|
255 |
||
256 |
return true |
|
257 |
} |
|
258 |
} |
|
|
64
aecde527900a
Introduce adding note on "enter" key.
Alexandre Segura <mex.zktk@gmail.com>
parents:
62
diff
changeset
|
259 |
} |
|
aecde527900a
Introduce adding note on "enter" key.
Alexandre Segura <mex.zktk@gmail.com>
parents:
62
diff
changeset
|
260 |
|
| 157 | 261 |
/** |
| 5 | 262 |
* When a mark button is clicked, toggle the current mark. |
263 |
* |
|
264 |
* @param {Event} e |
|
265 |
* @param {String} type |
|
266 |
*/ |
|
267 |
||
268 |
onClickMark = (e, type) => { |
|
| 157 | 269 |
|
270 |
e.preventDefault() |
|
271 |
const { value } = this.state |
|
|
26
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
272 |
let { categories } = this.state |
| 5 | 273 |
|
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
274 |
let isPortalOpen = false; |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
275 |
|
|
25
e04714a1d4eb
Improve categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
21
diff
changeset
|
276 |
if (type === 'category') { |
|
e04714a1d4eb
Improve categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
21
diff
changeset
|
277 |
// Can't use toggleMark here, because it expects the same object |
|
e04714a1d4eb
Improve categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
21
diff
changeset
|
278 |
// @see https://github.com/ianstormtaylor/slate/issues/873 |
|
e04714a1d4eb
Improve categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
21
diff
changeset
|
279 |
if (this.hasMark('category')) { |
| 157 | 280 |
const categoryMarks = value.activeMarks.filter(mark => mark.type === 'category') |
|
26
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
281 |
categoryMarks.forEach(mark => { |
|
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
282 |
const key = mark.data.get('key'); |
|
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
283 |
const text = mark.data.get('text'); |
|
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
284 |
|
|
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
285 |
categories = this.removeCategory(categories, key, text) |
| 157 | 286 |
const change = value.change().removeMark(mark) |
287 |
this.onChange(change) |
|
|
26
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
288 |
}) |
|
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
289 |
|
|
25
e04714a1d4eb
Improve categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
21
diff
changeset
|
290 |
} else { |
|
e04714a1d4eb
Improve categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
21
diff
changeset
|
291 |
isPortalOpen = !this.state.isPortalOpen; |
|
e04714a1d4eb
Improve categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
21
diff
changeset
|
292 |
} |
|
19
f1b125b95fe9
Introduce "annotation" plugin.
Alexandre Segura <mex.zktk@gmail.com>
parents:
17
diff
changeset
|
293 |
} else { |
| 157 | 294 |
const change = value.change().toggleMark(type) |
295 |
this.onChange(change) |
|
|
19
f1b125b95fe9
Introduce "annotation" plugin.
Alexandre Segura <mex.zktk@gmail.com>
parents:
17
diff
changeset
|
296 |
} |
|
f1b125b95fe9
Introduce "annotation" plugin.
Alexandre Segura <mex.zktk@gmail.com>
parents:
17
diff
changeset
|
297 |
|
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
298 |
this.setState({ |
| 157 | 299 |
state: value.change, |
|
26
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
300 |
isPortalOpen: isPortalOpen, |
|
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
301 |
categories: categories |
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
302 |
}) |
| 5 | 303 |
} |
304 |
||
305 |
/** |
|
306 |
* When a block button is clicked, toggle the block type. |
|
307 |
* |
|
308 |
* @param {Event} e |
|
309 |
* @param {String} type |
|
310 |
*/ |
|
311 |
||
312 |
onClickBlock = (e, type) => { |
|
313 |
e.preventDefault() |
|
| 157 | 314 |
const { value } = this.state |
315 |
const change = value.change() |
|
316 |
const { document } = value |
|
| 5 | 317 |
|
318 |
// Handle everything but list buttons. |
|
319 |
if (type !== 'bulleted-list' && type !== 'numbered-list') { |
|
320 |
const isActive = this.hasBlock(type) |
|
321 |
const isList = this.hasBlock('list-item') |
|
322 |
||
323 |
if (isList) { |
|
| 157 | 324 |
change |
325 |
.setBlocks(isActive ? DEFAULT_NODE : type) |
|
| 5 | 326 |
.unwrapBlock('bulleted-list') |
327 |
.unwrapBlock('numbered-list') |
|
328 |
} |
|
329 |
||
330 |
else { |
|
| 157 | 331 |
change |
332 |
.setBlocks(isActive ? DEFAULT_NODE : type) |
|
| 5 | 333 |
} |
334 |
} |
|
335 |
||
336 |
// Handle the extra wrapping required for list buttons. |
|
337 |
else { |
|
338 |
const isList = this.hasBlock('list-item') |
|
| 157 | 339 |
const isType = value.blocks.some((block) => { |
| 5 | 340 |
return !!document.getClosest(block.key, parent => parent.type === type) |
341 |
}) |
|
342 |
||
343 |
if (isList && isType) { |
|
| 157 | 344 |
change |
345 |
.setBlocks(DEFAULT_NODE) |
|
| 5 | 346 |
.unwrapBlock('bulleted-list') |
347 |
.unwrapBlock('numbered-list') |
|
| 157 | 348 |
|
| 5 | 349 |
} else if (isList) { |
| 157 | 350 |
change |
| 5 | 351 |
.unwrapBlock(type === 'bulleted-list' ? 'numbered-list' : 'bulleted-list') |
352 |
.wrapBlock(type) |
|
| 157 | 353 |
|
| 5 | 354 |
} else { |
| 157 | 355 |
change |
356 |
.setBlocks('list-item') |
|
| 5 | 357 |
.wrapBlock(type) |
| 157 | 358 |
|
| 5 | 359 |
} |
360 |
} |
|
361 |
||
| 157 | 362 |
|
363 |
this.onChange(change) |
|
| 5 | 364 |
} |
365 |
||
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
366 |
onPortalOpen = (portal) => { |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
367 |
// When the portal opens, cache the menu element. |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
368 |
this.setState({ hoveringMenu: portal.firstChild }) |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
369 |
} |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
370 |
|
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
371 |
onPortalClose = (portal) => { |
| 157 | 372 |
let { value } = this.state |
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
373 |
|
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
374 |
this.setState({ |
| 157 | 375 |
value: value.change, |
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
376 |
isPortalOpen: false |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
377 |
}) |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
378 |
} |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
379 |
|
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
380 |
onCategoryClick = (category) => { |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
381 |
|
| 157 | 382 |
const { value, currentSelectionText, currentSelectionStart, currentSelectionEnd } = this.state; |
383 |
const change = value.change() |
|
|
26
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
384 |
let { categories } = this.state; |
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
385 |
|
| 157 | 386 |
const categoryMarks = value.activeMarks.filter(mark => mark.type === 'category') |
387 |
categoryMarks.forEach(mark => change.removeMark(mark)); |
|
|
26
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
388 |
|
| 157 | 389 |
change.addMark({ |
|
25
e04714a1d4eb
Improve categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
21
diff
changeset
|
390 |
type: 'category', |
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
391 |
data: { |
|
26
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
392 |
text: currentSelectionText, |
|
102
b0e36664f1f2
Add TextPositionSelector.
Alexandre Segura <mex.zktk@gmail.com>
parents:
80
diff
changeset
|
393 |
selection: { |
|
b0e36664f1f2
Add TextPositionSelector.
Alexandre Segura <mex.zktk@gmail.com>
parents:
80
diff
changeset
|
394 |
start: currentSelectionStart, |
|
b0e36664f1f2
Add TextPositionSelector.
Alexandre Segura <mex.zktk@gmail.com>
parents:
80
diff
changeset
|
395 |
end: currentSelectionEnd, |
|
b0e36664f1f2
Add TextPositionSelector.
Alexandre Segura <mex.zktk@gmail.com>
parents:
80
diff
changeset
|
396 |
}, |
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
397 |
color: category.color, |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
398 |
key: category.key |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
399 |
} |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
400 |
}) |
| 157 | 401 |
this.onChange(change) |
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
402 |
|
|
26
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
403 |
Object.assign(category, { |
| 103 | 404 |
text: currentSelectionText, |
405 |
selection: { |
|
406 |
start: currentSelectionStart, |
|
407 |
end: currentSelectionEnd, |
|
408 |
}, |
|
|
26
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
409 |
}); |
|
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
410 |
categories = categories.push(category); |
|
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
411 |
|
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
412 |
this.setState({ |
| 157 | 413 |
value: value, |
|
26
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
414 |
isPortalOpen: false, |
|
930e486ad0a8
Store categories in note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
25
diff
changeset
|
415 |
categories: categories |
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
416 |
}); |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
417 |
} |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
418 |
|
|
72
7634b424f426
Add checkbox to add not on enter key.
Alexandre Segura <mex.zktk@gmail.com>
parents:
64
diff
changeset
|
419 |
onButtonClick = () => { |
|
7634b424f426
Add checkbox to add not on enter key.
Alexandre Segura <mex.zktk@gmail.com>
parents:
64
diff
changeset
|
420 |
if (typeof this.props.onButtonClick === 'function') { |
|
7634b424f426
Add checkbox to add not on enter key.
Alexandre Segura <mex.zktk@gmail.com>
parents:
64
diff
changeset
|
421 |
this.props.onButtonClick(); |
|
7634b424f426
Add checkbox to add not on enter key.
Alexandre Segura <mex.zktk@gmail.com>
parents:
64
diff
changeset
|
422 |
} |
|
7634b424f426
Add checkbox to add not on enter key.
Alexandre Segura <mex.zktk@gmail.com>
parents:
64
diff
changeset
|
423 |
} |
|
7634b424f426
Add checkbox to add not on enter key.
Alexandre Segura <mex.zktk@gmail.com>
parents:
64
diff
changeset
|
424 |
|
|
7634b424f426
Add checkbox to add not on enter key.
Alexandre Segura <mex.zktk@gmail.com>
parents:
64
diff
changeset
|
425 |
onCheckboxChange = (e) => { |
|
7634b424f426
Add checkbox to add not on enter key.
Alexandre Segura <mex.zktk@gmail.com>
parents:
64
diff
changeset
|
426 |
if (typeof this.props.onCheckboxChange === 'function') { |
|
7634b424f426
Add checkbox to add not on enter key.
Alexandre Segura <mex.zktk@gmail.com>
parents:
64
diff
changeset
|
427 |
this.props.onCheckboxChange(e); |
|
7634b424f426
Add checkbox to add not on enter key.
Alexandre Segura <mex.zktk@gmail.com>
parents:
64
diff
changeset
|
428 |
} |
|
7634b424f426
Add checkbox to add not on enter key.
Alexandre Segura <mex.zktk@gmail.com>
parents:
64
diff
changeset
|
429 |
} |
|
7634b424f426
Add checkbox to add not on enter key.
Alexandre Segura <mex.zktk@gmail.com>
parents:
64
diff
changeset
|
430 |
|
| 8 | 431 |
/** |
| 5 | 432 |
* Render. |
433 |
* |
|
434 |
* @return {Element} |
|
435 |
*/ |
|
436 |
||
437 |
render = () => { |
|
438 |
return ( |
|
| 157 | 439 |
<div className="bg-secondary mb-5"> |
440 |
<div className="sticky-top"> |
|
| 5 | 441 |
{this.renderToolbar()} |
| 157 | 442 |
</div> |
| 5 | 443 |
{this.renderEditor()} |
| 157 | 444 |
</div> |
| 5 | 445 |
) |
446 |
} |
|
447 |
||
448 |
/** |
|
449 |
* Render the toolbar. |
|
450 |
* |
|
451 |
* @return {Element} |
|
452 |
*/ |
|
453 |
||
454 |
renderToolbar = () => { |
|
455 |
return ( |
|
| 157 | 456 |
<div className="menu toolbar-menu d-flex bg-secondary"> |
457 |
{this.renderMarkButton('bold', 'format_bold')} |
|
458 |
{this.renderMarkButton('italic', 'format_italic')} |
|
459 |
{this.renderMarkButton('underlined', 'format_underlined')} |
|
460 |
{this.renderMarkButton('category', 'label')} |
|
|
19
f1b125b95fe9
Introduce "annotation" plugin.
Alexandre Segura <mex.zktk@gmail.com>
parents:
17
diff
changeset
|
461 |
|
|
79
772b73e31069
Introduce note editing, allow deleting note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
74
diff
changeset
|
462 |
|
| 157 | 463 |
{this.renderBlockButton('numbered-list', 'format_list_numbered')} |
464 |
{this.renderBlockButton('bulleted-list', 'format_list_bulleted')} |
|
465 |
||
466 |
{this.renderToolbarButtons()} |
|
| 5 | 467 |
</div> |
468 |
) |
|
469 |
} |
|
470 |
||
|
80
b3a02ea6d097
Implement note edition.
Alexandre Segura <mex.zktk@gmail.com>
parents:
79
diff
changeset
|
471 |
renderToolbarCheckbox = () => { |
|
b3a02ea6d097
Implement note edition.
Alexandre Segura <mex.zktk@gmail.com>
parents:
79
diff
changeset
|
472 |
return ( |
| 157 | 473 |
<div className="checkbox float-right"> |
474 |
<label className="mr-2"> |
|
475 |
<input type="checkbox" checked={this.props.isChecked} onChange={this.onCheckboxChange} /><small className="text-muted ml-1"> Appuyer sur <kbd className="bg-danger text-muted ml-1">Entrée</kbd> pour ajouter une note</small> |
|
|
80
b3a02ea6d097
Implement note edition.
Alexandre Segura <mex.zktk@gmail.com>
parents:
79
diff
changeset
|
476 |
</label> |
|
b3a02ea6d097
Implement note edition.
Alexandre Segura <mex.zktk@gmail.com>
parents:
79
diff
changeset
|
477 |
</div> |
|
b3a02ea6d097
Implement note edition.
Alexandre Segura <mex.zktk@gmail.com>
parents:
79
diff
changeset
|
478 |
) |
|
b3a02ea6d097
Implement note edition.
Alexandre Segura <mex.zktk@gmail.com>
parents:
79
diff
changeset
|
479 |
} |
|
b3a02ea6d097
Implement note edition.
Alexandre Segura <mex.zktk@gmail.com>
parents:
79
diff
changeset
|
480 |
|
|
79
772b73e31069
Introduce note editing, allow deleting note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
74
diff
changeset
|
481 |
renderToolbarButtons = () => { |
|
772b73e31069
Introduce note editing, allow deleting note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
74
diff
changeset
|
482 |
return ( |
|
772b73e31069
Introduce note editing, allow deleting note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
74
diff
changeset
|
483 |
<div> |
| 157 | 484 |
<button type="button" className="btn btn-primary btn-sm text-secondary float-right mr-5" disabled={this.props.isButtonDisabled} onClick={this.onButtonClick}> |
|
143
cfcbf4bc66f1
Remove react-bootstrap from components except Modal, Collapse and Dropdown
salimr <riwad.salim@yahoo.fr>
parents:
138
diff
changeset
|
485 |
{ this.props.note ? 'Save note' : 'Ajouter' } |
|
cfcbf4bc66f1
Remove react-bootstrap from components except Modal, Collapse and Dropdown
salimr <riwad.salim@yahoo.fr>
parents:
138
diff
changeset
|
486 |
</button> |
| 157 | 487 |
{ !this.props.note && this.renderToolbarCheckbox() } |
|
79
772b73e31069
Introduce note editing, allow deleting note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
74
diff
changeset
|
488 |
</div> |
|
772b73e31069
Introduce note editing, allow deleting note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
74
diff
changeset
|
489 |
); |
|
772b73e31069
Introduce note editing, allow deleting note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
74
diff
changeset
|
490 |
} |
|
772b73e31069
Introduce note editing, allow deleting note.
Alexandre Segura <mex.zktk@gmail.com>
parents:
74
diff
changeset
|
491 |
|
| 5 | 492 |
/** |
493 |
* Render a mark-toggling toolbar button. |
|
494 |
* |
|
495 |
* @param {String} type |
|
496 |
* @param {String} icon |
|
497 |
* @return {Element} |
|
498 |
*/ |
|
499 |
||
500 |
renderMarkButton = (type, icon) => { |
|
501 |
const isActive = this.hasMark(type) |
|
502 |
const onMouseDown = e => this.onClickMark(e, type) |
|
503 |
||
| 157 | 504 |
|
| 5 | 505 |
return ( |
| 157 | 506 |
<span className="button text-primary" onMouseDown={onMouseDown} data-active={isActive}> |
| 5 | 507 |
<span className="material-icons">{icon}</span> |
508 |
</span> |
|
509 |
) |
|
510 |
} |
|
511 |
||
| 157 | 512 |
// Add a `renderMark` method to render marks. |
513 |
||
514 |
renderMark = props => { |
|
515 |
const { children, mark, attributes } = props |
|
516 |
||
517 |
switch (mark.type) { |
|
518 |
case 'bold': |
|
519 |
return <strong {...attributes}>{children}</strong> |
|
520 |
case 'code': |
|
521 |
return <code {...attributes}>{children}</code> |
|
522 |
case 'italic': |
|
523 |
return <em {...attributes}>{children}</em> |
|
524 |
case 'underlined': |
|
525 |
return <ins {...attributes}>{children}</ins> |
|
526 |
} |
|
527 |
} |
|
| 5 | 528 |
/** |
529 |
* Render a block-toggling toolbar button. |
|
530 |
* |
|
531 |
* @param {String} type |
|
532 |
* @param {String} icon |
|
533 |
* @return {Element} |
|
534 |
*/ |
|
535 |
||
536 |
renderBlockButton = (type, icon) => { |
|
| 157 | 537 |
let isActive = this.hasBlock(type) |
538 |
||
539 |
if (['numbered-list', 'bulleted-list'].includes(type)) { |
|
540 |
const { value } = this.state |
|
541 |
const parent = value.document.getParent(value.blocks.first().key) |
|
542 |
isActive = this.hasBlock('list-item') && parent && parent.type === type |
|
543 |
} |
|
| 5 | 544 |
const onMouseDown = e => this.onClickBlock(e, type) |
545 |
||
546 |
return ( |
|
| 157 | 547 |
<span className="button text-primary" onMouseDown={onMouseDown} data-active={isActive}> |
| 5 | 548 |
<span className="material-icons">{icon}</span> |
549 |
</span> |
|
550 |
) |
|
551 |
} |
|
552 |
||
| 157 | 553 |
renderNode = props => { |
554 |
const { attributes, children, node } = props |
|
555 |
||
556 |
switch (node.type) { |
|
557 |
case 'block-quote': |
|
558 |
return <blockquote {...attributes}>{children}</blockquote> |
|
559 |
case 'bulleted-list': |
|
560 |
return <ul {...attributes}>{children}</ul> |
|
561 |
case 'heading-one': |
|
562 |
return <h1 {...attributes}>{children}</h1> |
|
563 |
case 'heading-two': |
|
564 |
return <h2 {...attributes}>{children}</h2> |
|
565 |
case 'list-item': |
|
566 |
return <li {...attributes}>{children}</li> |
|
567 |
case 'numbered-list': |
|
568 |
return <ol {...attributes}>{children}</ol> |
|
569 |
} |
|
570 |
} |
|
571 |
||
| 5 | 572 |
/** |
573 |
* Render the Slate editor. |
|
574 |
* |
|
575 |
* @return {Element} |
|
576 |
*/ |
|
577 |
||
578 |
renderEditor = () => { |
|
579 |
return ( |
|
| 157 | 580 |
<div className="editor-wrapper sticky-bottom p-2"> |
|
35
97106bacb24e
Improve session page design.
Alexandre Segura <mex.zktk@gmail.com>
parents:
26
diff
changeset
|
581 |
<div className="editor-slatejs"> |
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
582 |
{this.renderHoveringMenu()} |
| 5 | 583 |
<Editor |
|
11
6fb4de54acea
Delete default state, focus on textarea.
Alexandre Segura <mex.zktk@gmail.com>
parents:
8
diff
changeset
|
584 |
ref="editor" |
| 5 | 585 |
spellCheck |
| 157 | 586 |
autoFocus |
587 |
placeholder={'Votre espace de prise de note...'} |
|
| 5 | 588 |
schema={schema} |
|
19
f1b125b95fe9
Introduce "annotation" plugin.
Alexandre Segura <mex.zktk@gmail.com>
parents:
17
diff
changeset
|
589 |
plugins={plugins} |
| 157 | 590 |
value={this.state.value} |
| 5 | 591 |
onChange={this.onChange} |
592 |
onKeyDown={this.onKeyDown} |
|
| 157 | 593 |
renderMark={this.renderMark} |
594 |
renderNode = {this.renderNode} |
|
| 5 | 595 |
/> |
596 |
</div> |
|
| 157 | 597 |
</div> |
| 5 | 598 |
) |
599 |
} |
|
600 |
||
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
601 |
renderHoveringMenu = () => { |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
602 |
return ( |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
603 |
<Portal ref="portal" |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
604 |
isOpened={this.state.isPortalOpen} isOpen={this.state.isPortalOpen} |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
605 |
onOpen={this.onPortalOpen} |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
606 |
onClose={this.onPortalClose} |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
607 |
closeOnOutsideClick={false} closeOnEsc={true}> |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
608 |
<div className="hovering-menu"> |
|
138
a1fb2ced3049
propagate annotations categories from session protocol definition
ymh <ymh.work@gmail.com>
parents:
103
diff
changeset
|
609 |
<CategoriesTooltip categories={this.props.annotationCategories || defaultAnnotationsCategories} onCategoryClick={this.onCategoryClick} /> |
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
610 |
</div> |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
611 |
</Portal> |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
612 |
) |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
613 |
} |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
614 |
|
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
615 |
updateMenu = () => { |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
616 |
|
|
62
b2514a9bcd49
migrate to redux-offline + various optimisation
ymh <ymh.work@gmail.com>
parents:
35
diff
changeset
|
617 |
const { hoveringMenu } = this.state |
|
21
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
618 |
|
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
619 |
if (!hoveringMenu) return |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
620 |
|
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
621 |
// if (state.isBlurred || state.isCollapsed) { |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
622 |
// hoveringMenu.removeAttribute('style') |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
623 |
// return |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
624 |
// } |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
625 |
|
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
626 |
const selection = window.getSelection() |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
627 |
|
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
628 |
if (selection.isCollapsed) { |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
629 |
return |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
630 |
} |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
631 |
|
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
632 |
const range = selection.getRangeAt(0) |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
633 |
const rect = range.getBoundingClientRect() |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
634 |
|
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
635 |
hoveringMenu.style.opacity = 1 |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
636 |
hoveringMenu.style.top = `${rect.top + window.scrollY + hoveringMenu.offsetHeight}px` |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
637 |
hoveringMenu.style.left = `${rect.left + window.scrollX - hoveringMenu.offsetWidth / 2 + rect.width / 2}px` |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
638 |
} |
|
284e866f55c7
First version of categories tooltip.
Alexandre Segura <mex.zktk@gmail.com>
parents:
19
diff
changeset
|
639 |
|
| 5 | 640 |
} |
641 |
||
642 |
/** |
|
643 |
* Export. |
|
644 |
*/ |
|
645 |
||
|
11
6fb4de54acea
Delete default state, focus on textarea.
Alexandre Segura <mex.zktk@gmail.com>
parents:
8
diff
changeset
|
646 |
export default SlateEditor |