@sikka/hawa 0.0.233 → 0.0.235
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_config.yml +1 -0
- package/dist/styles.css +3 -3
- package/docs/CNAME +1 -0
- package/docs/README.md +60 -0
- package/docs/_layouts/default.html +47 -0
- package/docs/assets/css/style.css +366 -0
- package/docs/documentation/229.1b36ccba973b04d66b4c.manager.bundle.js +1 -0
- package/docs/documentation/229.f7a1c971.iframe.bundle.js +1 -0
- package/docs/documentation/295.67c251ec00675ab59b60.manager.bundle.js +1 -0
- package/docs/documentation/51.07b491d3.iframe.bundle.js +2 -0
- package/docs/documentation/51.07b491d3.iframe.bundle.js.LICENSE.txt +8 -0
- package/docs/documentation/51.e44cb3212565a342a42d.manager.bundle.js +2 -0
- package/docs/documentation/51.e44cb3212565a342a42d.manager.bundle.js.LICENSE.txt +8 -0
- package/docs/documentation/551.67cd309b0648b0a52636.manager.bundle.js +1 -0
- package/docs/documentation/551.c82ea8f1.iframe.bundle.js +1 -0
- package/docs/documentation/701.07623c34.iframe.bundle.js +1 -0
- package/docs/documentation/767.e90d0d608aa8557f855d.manager.bundle.js +2 -0
- package/docs/documentation/767.e90d0d608aa8557f855d.manager.bundle.js.LICENSE.txt +94 -0
- package/docs/documentation/807.1424ceed.iframe.bundle.js +2 -0
- package/docs/documentation/807.1424ceed.iframe.bundle.js.LICENSE.txt +31 -0
- package/docs/documentation/807.4e87168c6f719304d458.manager.bundle.js +2 -0
- package/docs/documentation/807.4e87168c6f719304d458.manager.bundle.js.LICENSE.txt +31 -0
- package/docs/documentation/897.386c170cbd1467abc7ca.manager.bundle.js +2 -0
- package/docs/documentation/897.386c170cbd1467abc7ca.manager.bundle.js.LICENSE.txt +12 -0
- package/docs/documentation/897.d9a35fd0.iframe.bundle.js +2 -0
- package/docs/documentation/897.d9a35fd0.iframe.bundle.js.LICENSE.txt +12 -0
- package/docs/documentation/901.ae81c179.iframe.bundle.js +2 -0
- package/docs/documentation/901.ae81c179.iframe.bundle.js.LICENSE.txt +105 -0
- package/docs/documentation/935.3a33e233.iframe.bundle.js +1 -0
- package/docs/documentation/935.df0c782bef63c348b9da.manager.bundle.js +1 -0
- package/docs/documentation/favicon.ico +0 -0
- package/docs/documentation/iframe.html +364 -0
- package/docs/documentation/index.html +59 -0
- package/docs/documentation/main.051275cac7b0dc69501c.manager.bundle.js +1 -0
- package/docs/documentation/main.fb64f936.iframe.bundle.js +1 -0
- package/docs/documentation/project.json +1 -0
- package/docs/documentation/runtime~main.a832da8f0c3235fa0d36.manager.bundle.js +1 -0
- package/docs/documentation/runtime~main.d6831407.iframe.bundle.js +1 -0
- package/es/elements/index.d.ts +0 -1
- package/es/index.es.js +2 -2
- package/lib/elements/index.d.ts +0 -1
- package/lib/index.js +2 -2
- package/package.json +2 -3
- package/src/elements/FloatingComment.tsx +711 -92
- package/src/elements/index.ts +0 -1
- package/src/styles.css +3 -3
- package/es/elements/FloatingCommentCE.d.ts +0 -6
- package/lib/elements/FloatingCommentCE.d.ts +0 -6
- package/src/elements/FloatingCommentCE.tsx +0 -466
package/src/elements/index.ts
CHANGED
|
@@ -33,7 +33,6 @@ export * from "./HawaDatepicker"
|
|
|
33
33
|
export * from "./UserFeedback"
|
|
34
34
|
export * from "./ArrowCarousel"
|
|
35
35
|
export * from "./FloatingComment"
|
|
36
|
-
export * from "./FloatingCommentCE"
|
|
37
36
|
export * from "./FloatingCommentSlate"
|
|
38
37
|
// Inputs
|
|
39
38
|
export * from "./HawaTextField"
|
package/src/styles.css
CHANGED
|
@@ -660,9 +660,6 @@ video {
|
|
|
660
660
|
.z-50 {
|
|
661
661
|
z-index: 50;
|
|
662
662
|
}
|
|
663
|
-
.order-none {
|
|
664
|
-
order: 0;
|
|
665
|
-
}
|
|
666
663
|
.m-0 {
|
|
667
664
|
margin: 0px;
|
|
668
665
|
}
|
|
@@ -1265,6 +1262,9 @@ video {
|
|
|
1265
1262
|
.overflow-y-auto {
|
|
1266
1263
|
overflow-y: auto;
|
|
1267
1264
|
}
|
|
1265
|
+
.overflow-x-hidden {
|
|
1266
|
+
overflow-x: hidden;
|
|
1267
|
+
}
|
|
1268
1268
|
.overflow-x-clip {
|
|
1269
1269
|
overflow-x: clip;
|
|
1270
1270
|
}
|
|
@@ -1,466 +0,0 @@
|
|
|
1
|
-
import React, { useRef, useState, useEffect } from "react"
|
|
2
|
-
import { RichTextarea } from "rich-textarea"
|
|
3
|
-
import clsx from "clsx"
|
|
4
|
-
|
|
5
|
-
const Property = (props) => {
|
|
6
|
-
return (
|
|
7
|
-
<div
|
|
8
|
-
className="border-box mr-[5px] flex h-[32px] w-[32px] items-center justify-center rounded bg-gray-400 p-2"
|
|
9
|
-
onMouseDown={props.onMouseDown}
|
|
10
|
-
>
|
|
11
|
-
{props.name}
|
|
12
|
-
</div>
|
|
13
|
-
)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
type ComponentTypes = {
|
|
17
|
-
foo?: string
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const styleClasses = {
|
|
21
|
-
bold: "font-bold",
|
|
22
|
-
italic: "italic",
|
|
23
|
-
under: "underline",
|
|
24
|
-
strike: "line-through",
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export const FloatingCommentCE: React.FunctionComponent<ComponentTypes> = (
|
|
28
|
-
props
|
|
29
|
-
) => {
|
|
30
|
-
const [text, _setText] = useState({
|
|
31
|
-
content: "",
|
|
32
|
-
stylings: [], // A styling is an object with 2 indices specifying a substring of text, and the applied effect
|
|
33
|
-
revert: [0, 0],
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
const field = useRef(null)
|
|
37
|
-
const _text = useRef(text)
|
|
38
|
-
const setText = (data) => {
|
|
39
|
-
_text.current = data
|
|
40
|
-
_setText(data)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Full reversion achieved !
|
|
44
|
-
const getFieldSelection = () => {
|
|
45
|
-
if (document.activeElement != field.current) return [0, 0]
|
|
46
|
-
|
|
47
|
-
let selection = window.getSelection()
|
|
48
|
-
let nodes = Array.from(field.current.childNodes)
|
|
49
|
-
nodes = nodes.filter(
|
|
50
|
-
(item: any) => !["#text", "BR"].includes(item.nodeName)
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
let startParent: any = selection.anchorNode.parentNode
|
|
54
|
-
let startNodeIndex =
|
|
55
|
-
startParent == field.current
|
|
56
|
-
? nodes.length
|
|
57
|
-
: parseInt(startParent.dataset.childIndex)
|
|
58
|
-
|
|
59
|
-
let startPrecedingSum = nodes
|
|
60
|
-
.slice(0, startNodeIndex)
|
|
61
|
-
.map((span: any) => span.textContent.length)
|
|
62
|
-
.reduce((a, b) => a + b, 0)
|
|
63
|
-
|
|
64
|
-
let endParent: any = selection.anchorNode.parentNode
|
|
65
|
-
let endNodeIndex =
|
|
66
|
-
endParent == field.current
|
|
67
|
-
? nodes.length
|
|
68
|
-
: parseInt(endParent.dataset.childIndex)
|
|
69
|
-
|
|
70
|
-
let endPrecedingSum = nodes
|
|
71
|
-
.slice(0, endNodeIndex)
|
|
72
|
-
.map((span: any) => span.textContent.length)
|
|
73
|
-
.reduce((a, b) => a + b, 0)
|
|
74
|
-
|
|
75
|
-
let result = [
|
|
76
|
-
startPrecedingSum + selection.anchorOffset,
|
|
77
|
-
endPrecedingSum + selection.focusOffset,
|
|
78
|
-
]
|
|
79
|
-
|
|
80
|
-
// Sort to make the minimum selection the start selection
|
|
81
|
-
return result.sort((a, b) => a - b)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
useEffect(() => {
|
|
85
|
-
setTimeout(function () {
|
|
86
|
-
let [start, end] = text.revert
|
|
87
|
-
|
|
88
|
-
if (start == 0 && end == 0) return
|
|
89
|
-
|
|
90
|
-
let startNode = null
|
|
91
|
-
let endNode = null
|
|
92
|
-
|
|
93
|
-
let total = 0
|
|
94
|
-
let nodes = Array.from(field.current.childNodes)
|
|
95
|
-
|
|
96
|
-
for (let i = 0; i < nodes.length; i++) {
|
|
97
|
-
let node: any = nodes[i]
|
|
98
|
-
let sum = node.textContent.length + total
|
|
99
|
-
|
|
100
|
-
if (startNode == null && start >= total && start <= sum) {
|
|
101
|
-
startNode = nodes[i]
|
|
102
|
-
start -= total
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (endNode == null && end > total && end <= sum) {
|
|
106
|
-
endNode = nodes[i]
|
|
107
|
-
end -= total
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
total += node.textContent.length
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
var range = document.createRange()
|
|
114
|
-
var sel = window.getSelection()
|
|
115
|
-
|
|
116
|
-
range.setStart(startNode.firstChild, start)
|
|
117
|
-
range.setEnd(endNode.firstChild, end)
|
|
118
|
-
|
|
119
|
-
sel.removeAllRanges()
|
|
120
|
-
sel.addRange(range)
|
|
121
|
-
}, 0)
|
|
122
|
-
}, [text.revert])
|
|
123
|
-
|
|
124
|
-
// utility functions
|
|
125
|
-
const getRange = (start, end) => {
|
|
126
|
-
let result = []
|
|
127
|
-
for (let i = start; i <= end; i++) {
|
|
128
|
-
result.push(i)
|
|
129
|
-
}
|
|
130
|
-
return result
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const intersection = (setA, setB) => {
|
|
134
|
-
const _intersection = new Set()
|
|
135
|
-
for (const elem of setB) {
|
|
136
|
-
if (setA.has(elem)) {
|
|
137
|
-
_intersection.add(elem)
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
return _intersection
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const getMinimum = (array) => {
|
|
144
|
-
return array.sort((a, b) => a - b)[0]
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
const getMaximum = (array) => {
|
|
148
|
-
return array.sort((a, b) => b - a)[0]
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// -1 - types dont match
|
|
152
|
-
// 0 - s1 is surrounded or on the edge of the s2
|
|
153
|
-
// 1 - s1 intersects with s2
|
|
154
|
-
// 2 - s1 does not intersect with s2
|
|
155
|
-
const getCorrelation = (styling1, styling2) => {
|
|
156
|
-
if (styling1.type != styling2.type) return -1
|
|
157
|
-
|
|
158
|
-
if (
|
|
159
|
-
styling2.start <= styling1.start &&
|
|
160
|
-
styling2.finish >= styling1.finish
|
|
161
|
-
) {
|
|
162
|
-
return 0
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
let indices1 = new Set(getRange(styling1.start - 1, styling1.finish - 1))
|
|
166
|
-
let indices2 = new Set(getRange(styling2.start - 1, styling2.finish - 1))
|
|
167
|
-
|
|
168
|
-
let result = intersection(indices1, indices2)
|
|
169
|
-
|
|
170
|
-
return result.size == 0 ? 2 : 1
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Correlation handler
|
|
174
|
-
const stylingSplice = (correlations, stylings, current, type) => {
|
|
175
|
-
// Only one surround correlation is possible at one time, so use .find to fetch it
|
|
176
|
-
|
|
177
|
-
let [_, index, styling] = correlations.find(([c, _, __]) => c == 0)
|
|
178
|
-
|
|
179
|
-
// Remove correlated styling
|
|
180
|
-
stylings = stylings.filter((_, _index) => _index != index)
|
|
181
|
-
|
|
182
|
-
// Get splices
|
|
183
|
-
let added = [
|
|
184
|
-
{
|
|
185
|
-
type: type,
|
|
186
|
-
start: getMinimum([styling.start, current.start]),
|
|
187
|
-
finish: getMaximum([styling.start, current.start]),
|
|
188
|
-
},
|
|
189
|
-
{
|
|
190
|
-
type: type,
|
|
191
|
-
start: getMinimum([styling.finish, current.finish]),
|
|
192
|
-
finish: getMaximum([styling.finish, current.finish]),
|
|
193
|
-
},
|
|
194
|
-
]
|
|
195
|
-
|
|
196
|
-
// Remove empty splices (edge cases)
|
|
197
|
-
added = added.filter((item) => item.start != item.finish)
|
|
198
|
-
|
|
199
|
-
// Add to current stylings
|
|
200
|
-
stylings = [...stylings, ...added]
|
|
201
|
-
|
|
202
|
-
return stylings
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// Correlation handler
|
|
206
|
-
const stylingIntersect = (correlations, stylings, current, type) => {
|
|
207
|
-
// Filter out all intersected stylings
|
|
208
|
-
let intersections = correlations
|
|
209
|
-
.filter(([c, _, __]) => c == 1)
|
|
210
|
-
.map(([_, index, styling]) => {
|
|
211
|
-
return [index, styling]
|
|
212
|
-
})
|
|
213
|
-
|
|
214
|
-
// Add current styling with no index for the sake for endpoint indices
|
|
215
|
-
intersections.push([-1, current])
|
|
216
|
-
|
|
217
|
-
// Get minimum intersection start index
|
|
218
|
-
let start = intersections
|
|
219
|
-
.map(([_, styling]) => styling.start)
|
|
220
|
-
.sort((a, b) => a - b)[0]
|
|
221
|
-
|
|
222
|
-
// Get maximum intersection start index
|
|
223
|
-
let finish = intersections
|
|
224
|
-
.map(([_, styling]) => styling.finish)
|
|
225
|
-
.sort((a, b) => b - a)[0]
|
|
226
|
-
|
|
227
|
-
// Get indices of all intersection
|
|
228
|
-
let indices = intersections.map((e) => e[0])
|
|
229
|
-
|
|
230
|
-
// Remove all from resulting styling array
|
|
231
|
-
stylings = stylings.filter((_, index) => !indices.includes(index))
|
|
232
|
-
|
|
233
|
-
// Add widest styling which encompasses all intersections
|
|
234
|
-
stylings.push({
|
|
235
|
-
type: type,
|
|
236
|
-
start: start,
|
|
237
|
-
finish: finish,
|
|
238
|
-
})
|
|
239
|
-
|
|
240
|
-
return stylings
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
const perform = (id) => {
|
|
244
|
-
let stylings = text.stylings.slice()
|
|
245
|
-
let [selectionStart, selectionEnd] = getFieldSelection()
|
|
246
|
-
|
|
247
|
-
if (selectionStart == selectionEnd) return
|
|
248
|
-
|
|
249
|
-
let current = {
|
|
250
|
-
type: id,
|
|
251
|
-
start: selectionStart,
|
|
252
|
-
finish: selectionEnd,
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
let correlations = []
|
|
256
|
-
|
|
257
|
-
// Check the correlation between this requested styling and all other stylings
|
|
258
|
-
for (let i = 0; i < stylings.length; i++) {
|
|
259
|
-
let styling = stylings[i]
|
|
260
|
-
let correlation = getCorrelation(current, styling)
|
|
261
|
-
|
|
262
|
-
if (correlation != -1) correlations.push([correlation, i, styling])
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
let result
|
|
266
|
-
|
|
267
|
-
if (correlations.find(([c, _, __]) => c == 1)) {
|
|
268
|
-
result = stylingIntersect(correlations, stylings, current, id)
|
|
269
|
-
} else if (correlations.find(([c, _, __]) => c == 0)) {
|
|
270
|
-
result = stylingSplice(correlations, stylings, current, id)
|
|
271
|
-
} else if (
|
|
272
|
-
correlations.find(([c, _, __]) => c == 2) ||
|
|
273
|
-
correlations.length == 0
|
|
274
|
-
) {
|
|
275
|
-
result = [...stylings, current]
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
setText({
|
|
279
|
-
...text,
|
|
280
|
-
stylings: result,
|
|
281
|
-
revert: [selectionStart, selectionEnd],
|
|
282
|
-
})
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// Get stylings encompassing an index within it's range
|
|
286
|
-
const getIntersectStylings = (index, startOffset = 0, finishOffset = 0) => {
|
|
287
|
-
// Find all stylings with encompassing range
|
|
288
|
-
let matches = text.stylings.filter(
|
|
289
|
-
({ start, finish }) =>
|
|
290
|
-
index >= start + startOffset && index < finish + finishOffset
|
|
291
|
-
)
|
|
292
|
-
|
|
293
|
-
return matches
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
// Get stylings after an index
|
|
297
|
-
const getSucceedStylings = (index) => {
|
|
298
|
-
// Find all stylings after the index
|
|
299
|
-
let matches = text.stylings.filter(({ start, finish }) => start >= index)
|
|
300
|
-
|
|
301
|
-
return matches
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
const getStylingIndex = (styling) => {
|
|
305
|
-
return text.stylings.findIndex(
|
|
306
|
-
(item) =>
|
|
307
|
-
item.start == styling.start &&
|
|
308
|
-
item.finish == styling.finish &&
|
|
309
|
-
item.type == styling.type
|
|
310
|
-
)
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
const onChange = (value) => {
|
|
314
|
-
let [selectionStart, selectionEnd] = getFieldSelection()
|
|
315
|
-
|
|
316
|
-
let difference = value.length - text.content.length
|
|
317
|
-
|
|
318
|
-
let selection = selectionStart - difference
|
|
319
|
-
|
|
320
|
-
let stylings = text.stylings.slice()
|
|
321
|
-
let succeeding = getSucceedStylings(selection)
|
|
322
|
-
let changes = []
|
|
323
|
-
|
|
324
|
-
for (let succeed of succeeding) {
|
|
325
|
-
let index = getStylingIndex(succeed)
|
|
326
|
-
let styling = stylings[index]
|
|
327
|
-
|
|
328
|
-
changes.push([
|
|
329
|
-
index,
|
|
330
|
-
styling.start + difference,
|
|
331
|
-
styling.finish + difference,
|
|
332
|
-
])
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
let intersecting = getIntersectStylings(selection, 1, 1)
|
|
336
|
-
|
|
337
|
-
for (let intersect of intersecting) {
|
|
338
|
-
let index = getStylingIndex(intersect)
|
|
339
|
-
let styling = stylings[index]
|
|
340
|
-
|
|
341
|
-
changes.push([index, styling.start, styling.finish + difference])
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
let spliced = []
|
|
345
|
-
for (let [index, start, finish] of changes) {
|
|
346
|
-
stylings[index] = {
|
|
347
|
-
...stylings[index],
|
|
348
|
-
start: start,
|
|
349
|
-
finish: finish,
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
if (start >= finish) spliced.push(index)
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
stylings = stylings.filter((_, index) => !spliced.includes(index))
|
|
356
|
-
|
|
357
|
-
// if (difference == 1) difference = 0
|
|
358
|
-
|
|
359
|
-
setText({
|
|
360
|
-
...text,
|
|
361
|
-
content: value,
|
|
362
|
-
stylings: stylings,
|
|
363
|
-
revert: [selectionStart, selectionEnd],
|
|
364
|
-
})
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
const getContent = () => {
|
|
368
|
-
let content = _text.current.content
|
|
369
|
-
|
|
370
|
-
// Get all styling indices
|
|
371
|
-
let indices = _text.current.stylings
|
|
372
|
-
.map(({ start, finish }) => [start, finish])
|
|
373
|
-
.flat()
|
|
374
|
-
|
|
375
|
-
// Sort ascendingly
|
|
376
|
-
indices = indices.sort((a, b) => a - b)
|
|
377
|
-
|
|
378
|
-
// Remove duplicates
|
|
379
|
-
indices = indices.filter(
|
|
380
|
-
(element, index) => indices.indexOf(element) == index
|
|
381
|
-
)
|
|
382
|
-
|
|
383
|
-
// Add first index if not present
|
|
384
|
-
if (indices[0] != 0) indices.unshift(0)
|
|
385
|
-
|
|
386
|
-
// Add last index if not present
|
|
387
|
-
let last = content.length
|
|
388
|
-
if (indices[indices.length - 1] != last) indices.push(last)
|
|
389
|
-
|
|
390
|
-
let result = []
|
|
391
|
-
|
|
392
|
-
for (let i = 0; i < indices.length - 1; i++) {
|
|
393
|
-
result.push([indices[i], content.substring(indices[i], indices[i + 1])])
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
return result
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
// dangerouslySetInnerHTML incorrectly renders when the entire text is highlighted, copied, and then pasted in succession
|
|
400
|
-
useEffect(() => {
|
|
401
|
-
let html = getContent()
|
|
402
|
-
.map((_data, index) => {
|
|
403
|
-
let [start, data] = _data
|
|
404
|
-
|
|
405
|
-
// Get stylings encompassing an index within it's range
|
|
406
|
-
let stylings = getIntersectStylings(start)
|
|
407
|
-
|
|
408
|
-
return `<span class="${stylings
|
|
409
|
-
.map((styling) => styleClasses[styling.type])
|
|
410
|
-
.join(" ")}" data-child-index="${index}">${data}</span>`
|
|
411
|
-
})
|
|
412
|
-
.join("")
|
|
413
|
-
|
|
414
|
-
field.current.innerHTML = html
|
|
415
|
-
}, [text])
|
|
416
|
-
|
|
417
|
-
return (
|
|
418
|
-
<div className="align-center box-border flex h-min w-[400px] flex-col items-center justify-center rounded bg-blue-300 shadow-md">
|
|
419
|
-
<div className={clsx("flex w-full flex-row justify-start p-2")}>
|
|
420
|
-
<Property
|
|
421
|
-
name="B"
|
|
422
|
-
onMouseDown={(event) => {
|
|
423
|
-
event.preventDefault() // This does not take focus away from field which allows the function to retrieve the current selection data
|
|
424
|
-
perform("bold")
|
|
425
|
-
}}
|
|
426
|
-
/>
|
|
427
|
-
<Property
|
|
428
|
-
name="I"
|
|
429
|
-
onMouseDown={(event) => {
|
|
430
|
-
event.preventDefault()
|
|
431
|
-
perform("italic")
|
|
432
|
-
}}
|
|
433
|
-
/>
|
|
434
|
-
<Property
|
|
435
|
-
name="U"
|
|
436
|
-
onMouseDown={(event) => {
|
|
437
|
-
event.preventDefault()
|
|
438
|
-
perform("under")
|
|
439
|
-
}}
|
|
440
|
-
/>
|
|
441
|
-
<Property
|
|
442
|
-
name="S"
|
|
443
|
-
onMouseDown={(event) => {
|
|
444
|
-
event.preventDefault()
|
|
445
|
-
perform("strike")
|
|
446
|
-
}}
|
|
447
|
-
/>
|
|
448
|
-
</div>
|
|
449
|
-
<div className="h-[1px] w-full bg-slate-600"> </div>
|
|
450
|
-
<div className="w-full">
|
|
451
|
-
<div
|
|
452
|
-
ref={field}
|
|
453
|
-
contentEditable="true"
|
|
454
|
-
className="h-[150px] w-full resize-none border-none p-2 outline-none"
|
|
455
|
-
onInput={(event: any) => {
|
|
456
|
-
onChange(event.target.textContent)
|
|
457
|
-
}}
|
|
458
|
-
></div>
|
|
459
|
-
</div>
|
|
460
|
-
<div className="h-[1px] w-full bg-slate-600"> </div>
|
|
461
|
-
<button className="my-1 rounded bg-cyan-800 p-2 py-1 text-white">
|
|
462
|
-
Submit
|
|
463
|
-
</button>
|
|
464
|
-
</div>
|
|
465
|
-
)
|
|
466
|
-
}
|