l-min-components 1.0.289 → 1.0.294

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "l-min-components",
3
- "version": "1.0.289",
3
+ "version": "1.0.294",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "src/assets",
@@ -17,6 +17,7 @@
17
17
  "axios-hooks": "^4.0.0",
18
18
  "chart.js": "^4.2.1",
19
19
  "classnames": "^2.3.2",
20
+ "emoji-picker-react": "^4.4.10",
20
21
  "js-cookie": "^3.0.5",
21
22
  "l-min-components": "^1.0.220",
22
23
  "moment": "^2.29.4",
@@ -33,6 +34,9 @@
33
34
  "react-modal": "^3.16.1",
34
35
  "react-router-dom": "^6.8.2",
35
36
  "react-tooltip": "^5.10.1",
37
+ "slate": "^0.94.0",
38
+ "slate-history": "^0.93.0",
39
+ "slate-react": "^0.94.0",
36
40
  "styled-components": "^5.3.6"
37
41
  },
38
42
  "devDependencies": {
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, createContext, useRef } from "react";
1
+ import React, { useState, useEffect, createContext, useRef, useContext } from "react";
2
2
  import { Outlet, useLocation } from "react-router-dom";
3
3
  import {
4
4
  Layout,
@@ -33,7 +33,7 @@ const AppMainLayout = () => {
33
33
 
34
34
  return (
35
35
  <OutletContext.Provider
36
- value={{ setRightComponent, setRightLayout, generalData, setGeneralData }}
36
+ value={{ setRightComponent, setRightLayout, generalData, setGeneralData, coming }}
37
37
  >
38
38
  <Layout coming={coming}>
39
39
  <HeaderComponent />
@@ -1,4 +1,4 @@
1
- import React, { useState, CSSProperties, useEffect } from "react";
1
+ import React, { useState, CSSProperties, useEffect, useRef } from "react";
2
2
  import {
3
3
  ControlInput,
4
4
  DropDownContainer,
@@ -35,13 +35,30 @@ const DropDownComponent = (props) => {
35
35
  //search params
36
36
  const [searchParam, setSearchParam] = useState();
37
37
 
38
+ // dropdown menu ref
39
+ const dropdownRef = useRef(null);
40
+
41
+ // click outside closes the dropdown menu
42
+ const handleClickOutside = (event) => {
43
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
44
+ setDropdown(false)
45
+ }
46
+ };
47
+
48
+ useEffect(() => {
49
+ document.addEventListener('click', handleClickOutside);
50
+ return () => {
51
+ document.removeEventListener('click', handleClickOutside);
52
+ };
53
+ }, []);
54
+
38
55
  // useEffect to return a function value onChange
39
56
  useEffect(() => {
40
57
  props?.onSelect && props?.onSelect(selected);
41
58
  }, [selected]);
42
59
 
43
60
  return (
44
- <DropDownContainer className={props?.className}>
61
+ <DropDownContainer className={props?.className} ref={dropdownRef}>
45
62
  <DropDownHeader>{props?.header}</DropDownHeader>
46
63
  <DropDownControls>
47
64
  {props?.searchable ? (
@@ -110,8 +127,8 @@ export default DropDownComponent;
110
127
  export const DownIcon = ({ width, height, fill, onClick }) => {
111
128
  return (
112
129
  <svg
113
- width={width || "14"}
114
- height={height || "8"}
130
+ width={width || "18"}
131
+ height={height || "9"}
115
132
  viewBox="0 0 14 8"
116
133
  fill="none"
117
134
  xmlns="http://www.w3.org/2000/svg"
@@ -119,10 +136,10 @@ export const DownIcon = ({ width, height, fill, onClick }) => {
119
136
  >
120
137
  <path
121
138
  d="M1 1L7 7L13 1"
122
- stroke={fill || "#18191B"}
139
+ stroke={fill || "#7C8080"}
123
140
  strokeWidth="2"
124
141
  strokeLinecap="round"
125
- strokeLinejoin="round"
142
+ strokeLinejoin="round"
126
143
  />
127
144
  </svg>
128
145
  );
@@ -29,3 +29,4 @@ export { default as ErrorPage } from "./errorPage";
29
29
  export { default as AppMainLayout } from "./AppMainLayout";
30
30
  export { OutletContext as OutletContext } from "./AppMainLayout";
31
31
  export { default as DatePickerCalender } from "./datePicker";
32
+ export { default as TextEditor } from "./textEditor"
@@ -0,0 +1,14 @@
1
+ const BinWhite = () => (
2
+ <svg
3
+ width="14"
4
+ height="18"
5
+ viewBox="0 0 14 18"
6
+ fill="none"
7
+ xmlns="http://www.w3.org/2000/svg">
8
+ <path
9
+ d="M1 16C1 17.1 1.9 18 3 18H11C12.1 18 13 17.1 13 16V4H1V16ZM14 1H10.5L9.5 0H4.5L3.5 1H0V3H14V1Z"
10
+ fill="white"
11
+ />
12
+ </svg>
13
+ );
14
+ export default BinWhite;
@@ -0,0 +1,43 @@
1
+ import React from "react";
2
+
3
+ const Grammerly = () => {
4
+ return (
5
+ <svg
6
+ width="25"
7
+ height="24"
8
+ viewBox="0 0 25 24"
9
+ fill="none"
10
+ xmlns="http://www.w3.org/2000/svg">
11
+ <path
12
+ d="M19.9232 4.94813C23.8932 8.91813 23.8232 15.3981 19.7232 19.2881C15.9332 22.8781 9.78323 22.8781 5.98323 19.2881C1.87323 15.3981 1.80322 8.91813 5.78322 4.94813C9.68322 1.03813 16.0232 1.03813 19.9232 4.94813Z"
13
+ stroke="#ADB3B3"
14
+ strokeWidth="1.5"
15
+ strokeLinecap="round"
16
+ strokeLinejoin="round"
17
+ />
18
+ <path
19
+ d="M16.6934 16.0664C14.5734 18.0664 11.1334 18.0664 9.02344 16.0664"
20
+ stroke="#ADB3B3"
21
+ strokeWidth="1.5"
22
+ strokeLinecap="round"
23
+ strokeLinejoin="round"
24
+ />
25
+ <path
26
+ d="M9.51794 8.98828H9.52693"
27
+ stroke="#ADB3B3"
28
+ strokeWidth="2.5"
29
+ strokeLinecap="round"
30
+ strokeLinejoin="round"
31
+ />
32
+ <path
33
+ d="M16.6888 8.98828H16.6978"
34
+ stroke="#ADB3B3"
35
+ strokeWidth="2.5"
36
+ strokeLinecap="round"
37
+ strokeLinejoin="round"
38
+ />
39
+ </svg>
40
+ );
41
+ };
42
+
43
+ export default Grammerly;
@@ -0,0 +1,26 @@
1
+ const MoveUpDownWhite = () => (
2
+ <svg
3
+ width="17"
4
+ height="22"
5
+ viewBox="0 0 17 22"
6
+ fill="none"
7
+ xmlns="http://www.w3.org/2000/svg">
8
+ <g clipPath="url(#clip0_5000_132541)">
9
+ <path
10
+ d="M1 7H8.5H16M1 11H16M1 15H16"
11
+ stroke="#F5F7F7"
12
+ strokeWidth="2"
13
+ strokeLinecap="round"
14
+ strokeLinejoin="round"
15
+ />
16
+ <path d="M4 18L8.5 22L13 18H4Z" fill="#F5F7F7" />
17
+ <path d="M4 4L8.5 0L13 4H4Z" fill="#F5F7F7" />
18
+ </g>
19
+ <defs>
20
+ <clipPath id="clip0_5000_132541">
21
+ <rect width="17" height="22" fill="white" />
22
+ </clipPath>
23
+ </defs>
24
+ </svg>
25
+ );
26
+ export default MoveUpDownWhite;
@@ -0,0 +1,683 @@
1
+ import { useCallback, useMemo, useEffect, useRef, useState } from "react";
2
+ import BinWhite from "./assets/binWhite";
3
+ import MoveUpDownWhite from "./assets/moveUppDownWhite";
4
+ import "./style.scss";
5
+ import { createEditor, Editor, Transforms } from "slate";
6
+ import { Slate, Editable, withReact } from "slate-react";
7
+ import { DropDownComponent,ButtonComponent, } from "l-min-components/src/components";
8
+ // import { fontList } from "../../pages/createLectures/defaults";
9
+ import EmojiPicker from "emoji-picker-react";
10
+ import Grammerly from "./assets/grammerly";
11
+
12
+ /**
13
+ * @param {{
14
+ * valueData: Object,
15
+ * placeHolder: string,
16
+ * }} props - properties of the editor
17
+ */
18
+
19
+ const TextEditor = ({
20
+ valueData,
21
+ showOptions,
22
+ announce,
23
+ click,
24
+ placeHolder,
25
+
26
+ }) => {
27
+
28
+ const [heading, setHeading] = useState("");
29
+ const [value, setValue] = useState(valueData);
30
+ const editor = useMemo(() => withReact(createEditor()), []);
31
+ const [fontColor, setFontColor] = useState("#000");
32
+ const [active, setActive] = useState(false)
33
+ const [boldActive, setBoldActive] = useState(false)
34
+ const [italicActive, setItalicActive] = useState(false)
35
+ const [underlinective, setUnderlineActive] = useState(false)
36
+ const [listActive, setListActive] = useState(false)
37
+ const [leftActive, setLeftActive] = useState(false)
38
+ const [rightActive, setRightActive] = useState(false)
39
+ const [centerActive, setCenterActive] = useState(false)
40
+ const [showEmoji, setShowEmoji] = useState();
41
+
42
+ // const [showEmoji, setShowEmoji] = useState();
43
+ const dropdownRef = useRef(null);
44
+
45
+ const handleClickOutside = (event) => {
46
+ event.preventDefault();
47
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
48
+ setShowEmoji(false);
49
+ setActive(false)
50
+ }
51
+ };
52
+
53
+ useEffect(() => {
54
+ document.addEventListener('click', handleClickOutside);
55
+ return () => {
56
+ document.removeEventListener('click', handleClickOutside);
57
+ };
58
+ }, []);
59
+
60
+ const toggleMark = (editor, format, value = true) => {
61
+ const isActive = isMarkActive(editor, format);
62
+ if (isActive) {
63
+ editor.removeMark(format);
64
+ // setActive(true)
65
+ } else {
66
+ editor.addMark(format, value);
67
+ // setActive(false)
68
+ }
69
+ };
70
+
71
+ const isMarkActive = (editor, format) => {
72
+ const marks = Editor.marks(editor);
73
+ return marks ? marks[format] === true : false;
74
+ };
75
+
76
+ const colorInput = useRef();
77
+ const defaultFontSize = useMemo(() => 16);
78
+
79
+ const fontSizes = useCallback(() => {
80
+ const numbers = [];
81
+ const startNum = 10;
82
+ const maxNum = 30;
83
+ for (let x = startNum; x <= maxNum; x++) {
84
+ numbers.push({ name: x });
85
+ }
86
+ return numbers;
87
+ }, []);
88
+
89
+
90
+ const handleEmojiButton = () => {
91
+ setShowEmoji(!showEmoji);
92
+ };
93
+
94
+ const insertEmoji = useCallback((emoji) => {
95
+ editor.insertText(emoji)
96
+ }, []);
97
+
98
+ return (
99
+ <div className="editor" ref={dropdownRef}>
100
+ <Slate
101
+ editor={editor}
102
+ value={value}
103
+ autoFocus={true}
104
+ onChange={(val) => {
105
+ setValue(val);
106
+ }}
107
+ >
108
+ <div className="editor-wrapper">
109
+ {showEmoji && (
110
+ <div
111
+ className="emoji_picker"
112
+ onMouseDown={(e) => {
113
+ e.preventDefault();
114
+ }}>
115
+ <EmojiPicker
116
+ onEmojiClick={(data) => {
117
+ insertEmoji(data.emoji);
118
+ }}
119
+ autoFocusSearch={false}
120
+ suggestedEmojisMode="frequent"
121
+ lazyLoadEmojis={true}
122
+ previewConfig={{
123
+ showPreview: false,
124
+ }}
125
+ />
126
+ </div>
127
+ )}
128
+ <div className="editor_area">
129
+ {announce && (
130
+ <input
131
+ placeholder="Announcement Heading"
132
+ value={heading}
133
+ onChange={(e) => setHeading(e.target.value)}
134
+ />
135
+ )}
136
+
137
+ <div className="editable">
138
+ <Editable renderLeaf={(props) => <Leaf {...props} />} placeholder={placeHolder} />
139
+ </div>
140
+ </div>
141
+
142
+
143
+ <div className="bottom">
144
+ <div
145
+ className="tool-bar"
146
+ onMouseDown={(e) => {
147
+ e.preventDefault();
148
+ }}>
149
+ {/* <div className="font">
150
+ <DropDownComponent
151
+ className="font-dd"
152
+ default={{ name: "Nunito" }}
153
+ dropdownData={fontList.map((font) => ({ name: font }))}
154
+ onSelect={({ name }) => {
155
+ console.log(name);
156
+ toggleMark(editor, "fontFamily", name);
157
+ }}
158
+ />
159
+ </div> */}
160
+ <div className="font-size">
161
+ <DropDownComponent
162
+ className="sizes"
163
+ default={{ name: defaultFontSize }}
164
+ dropdownData={fontSizes()}
165
+ onSelect={({ name }) => {
166
+ toggleMark(editor, "fontSize", name);
167
+ }}
168
+ />
169
+ </div>
170
+ <div
171
+ className="color-box"
172
+ onMouseDown={(e) => {
173
+ e.preventDefault();
174
+ colorInput.current.click();
175
+ }}>
176
+ <div className="wrap">
177
+ <input
178
+ type="color"
179
+ name="color"
180
+ defaultValue={fontColor}
181
+ ref={colorInput}
182
+ onChange={(e) => {
183
+ setFontColor(e.target.value);
184
+ toggleMark(editor, "color", e.target.value);
185
+ }}
186
+ />
187
+ <div
188
+ className="indicator"
189
+ style={{ backgroundColor: fontColor }}
190
+ />
191
+ <ArrowDown />
192
+ </div>
193
+ </div>
194
+ <div className="font-style">
195
+ <div
196
+ className={boldActive ? "active" : ""}
197
+ onMouseDown={(event) => {
198
+ event.preventDefault();
199
+ toggleMark(editor, "bold");
200
+ setBoldActive(!boldActive)
201
+ }}>
202
+ <BoldIcons />
203
+ </div>
204
+ <div
205
+ className={italicActive ? "active" : ""}
206
+ onMouseDown={(event) => {
207
+ event.preventDefault();
208
+ toggleMark(editor, "italic");
209
+ setItalicActive(!italicActive)
210
+ }}>
211
+ <ItalicIcon />
212
+ </div>
213
+ <div
214
+ className={underlinective ? "active" : "underline"}
215
+ onMouseDown={(event) => {
216
+ event.preventDefault();
217
+ toggleMark(editor, "underline");
218
+ setUnderlineActive(!underlinective)
219
+ }}>
220
+ <UnderlineIcon />
221
+ </div>
222
+ </div>
223
+ <div className="alignments">
224
+ <div
225
+ className={leftActive ? "a-left active" : "a-left"}
226
+ onMouseDown={(event) => {
227
+ event.preventDefault();
228
+ toggleMark(editor, "textAlign", "left");
229
+ setLeftActive(!leftActive)
230
+ setCenterActive(false)
231
+ setRightActive(false)
232
+ }}>
233
+ <TextAlignLeftIcon />
234
+ </div>
235
+ <div
236
+ className={centerActive ? "a-center active" : "a-center"}
237
+ onMouseDown={(event) => {
238
+ event.preventDefault();
239
+ toggleMark(editor, "textAlign", "center");
240
+ setCenterActive(!centerActive)
241
+ setLeftActive(false)
242
+ setRightActive(false)
243
+ }}>
244
+ <TextAlignCenterIcon />
245
+ </div>
246
+ <div
247
+ className={rightActive ? "a-right active" : "a-right"}
248
+ onMouseDown={(event) => {
249
+ event.preventDefault();
250
+ toggleMark(editor, "textAlign", "right");
251
+ setRightActive(!rightActive)
252
+ setCenterActive(false)
253
+ setLeftActive(false)
254
+ }}>
255
+ <TextAlignRight />
256
+ </div>
257
+ </div>
258
+ <div className="list" >
259
+ <div
260
+ className={listActive ? "list-icon active" : "list-icon"}
261
+ onClick={() => {
262
+ toggleMark(editor, "list");
263
+ setListActive(!listActive)
264
+ }}>
265
+ <ListIcon />
266
+ </div>
267
+ {/* <div className="first-line-icon">
268
+ <FirstLineIcon />
269
+ </div> */}
270
+ </div>
271
+ <button className={active ? "emoji_button_active" : "emoji_button" }
272
+ // onClick={handleEmojiButton}
273
+ onMouseDown={(e) => {
274
+ e.preventDefault();
275
+ setShowEmoji((state) => !state);
276
+ setActive(!active)
277
+ }}
278
+ >
279
+ {" "}
280
+ <Grammerly />{" "}
281
+ </button>
282
+ </div>
283
+ {announce && (
284
+ <ButtonComponent
285
+ text="Create Announcement"
286
+ styles={{
287
+ fontSize: "18px",
288
+ width: "30%",
289
+ // textAlign: "center",
290
+ padding: "8px 17px",
291
+ borderRadius: "12px",
292
+ marginTop: "15px",
293
+ height: "50px",
294
+ // marginLeft: "15px",
295
+ }}
296
+ onClick={click}
297
+ />
298
+ )}
299
+ </div>
300
+ </div>
301
+ </Slate>
302
+ {showOptions && (
303
+ <div className="options">
304
+ <div className="options">
305
+ <span>
306
+ <MoveUpDownWhite />
307
+ </span>
308
+ <span onClick={handleDeleteContent.bind(this, temporaryId)}>
309
+ <BinWhite />
310
+ </span>
311
+ </div>
312
+ </div>
313
+ )}
314
+ </div>
315
+ );
316
+ };
317
+
318
+ const Leaf = ({ attributes, children, leaf }) => {
319
+ if (leaf.bold) {
320
+ children = <strong>{children}</strong>;
321
+ }
322
+
323
+ if (leaf.italic) {
324
+ children = <em>{children}</em>;
325
+ }
326
+
327
+ if (leaf.underline) {
328
+ children = (
329
+ <span {...attributes} style={{ textDecoration: "underline" }}>
330
+ {children}
331
+ </span>
332
+ );
333
+ }
334
+ if (leaf.color) {
335
+ children = (
336
+ <span {...attributes} style={{ color: leaf.color }}>
337
+ {children}
338
+ </span>
339
+ );
340
+ }
341
+ if (leaf.textAlign) {
342
+ children = (
343
+ <p style={{ textAlign: leaf.textAlign }}>
344
+ <span {...attributes}>{children}</span>
345
+ </p>
346
+ );
347
+ }
348
+
349
+ if (leaf.fontFamily) {
350
+ children = (
351
+ <span {...attributes} style={{ fontFamily: leaf.fontFamily }}>
352
+ {children}
353
+ </span>
354
+ );
355
+ }
356
+
357
+ if (leaf.fontSize) {
358
+ children = (
359
+ <span {...attributes} style={{ fontSize: leaf.fontSize }}>
360
+ {children}
361
+ </span>
362
+ );
363
+ }
364
+
365
+ if (leaf.list) {
366
+ children = (
367
+ // <ul {...attributes}>
368
+ <li {...attributes}>{children}</li>
369
+ // </ul>
370
+ );
371
+ }
372
+
373
+ return <span {...attributes}>{children}</span>;
374
+ };
375
+ const BoldIcons = (props) => (
376
+ <svg
377
+ width="25"
378
+ height="25"
379
+ viewBox="0 0 25 25"
380
+ fill="none"
381
+ xmlns="http://www.w3.org/2000/svg">
382
+ <path
383
+ d="M5.80664 5.27344C5.80664 4.17344 6.70664 3.27344 7.80664 3.27344H12.9266C15.5466 3.27344 17.6766 5.40344 17.6766 8.02344C17.6766 10.6434 15.5466 12.7734 12.9266 12.7734H5.80664V5.27344Z"
384
+ stroke={props.stroke ?? "#313333"}
385
+ strokeWidth="1.5"
386
+ strokeLinecap="round"
387
+ strokeLinejoin="round"
388
+ />
389
+ <path
390
+ d="M5.80664 12.7734H15.3066C17.9266 12.7734 20.0566 14.9034 20.0566 17.5234C20.0566 20.1434 17.9266 22.2734 15.3066 22.2734H7.80664C6.70664 22.2734 5.80664 21.3734 5.80664 20.2734V12.7734V12.7734Z"
391
+ stroke={props.stroke ?? "#313333"}
392
+ strokeWidth="1.5"
393
+ strokeLinecap="round"
394
+ strokeLinejoin="round"
395
+ />
396
+ </svg>
397
+ );
398
+
399
+ const ItalicIcon = () => (
400
+ <svg
401
+ width="25"
402
+ height="25"
403
+ viewBox="0 0 25 25"
404
+ fill="none"
405
+ xmlns="http://www.w3.org/2000/svg">
406
+ <path
407
+ d="M10.5449 3.77344H19.7949"
408
+ stroke="#949999"
409
+ strokeWidth="1.5"
410
+ strokeLinecap="round"
411
+ strokeLinejoin="round"
412
+ />
413
+ <path
414
+ d="M6.04492 21.7734H15.2949"
415
+ stroke="#949999"
416
+ strokeWidth="1.5"
417
+ strokeLinecap="round"
418
+ strokeLinejoin="round"
419
+ />
420
+ <path
421
+ d="M15.1758 3.77344L10.6758 21.7734"
422
+ stroke="#949999"
423
+ strokeWidth="1.5"
424
+ strokeLinecap="round"
425
+ strokeLinejoin="round"
426
+ />
427
+ </svg>
428
+ );
429
+
430
+ const UnderlineIcon = () => (
431
+ <svg
432
+ width="25"
433
+ height="25"
434
+ viewBox="0 0 25 25"
435
+ fill="none"
436
+ xmlns="http://www.w3.org/2000/svg">
437
+ <path
438
+ d="M5.92578 21.7734H19.9258"
439
+ stroke="#949999"
440
+ strokeWidth="1.5"
441
+ strokeLinecap="round"
442
+ strokeLinejoin="round"
443
+ />
444
+ <path
445
+ d="M5.92578 3.77344V10.7734C5.92578 14.6434 9.05578 17.7734 12.9258 17.7734C16.7958 17.7734 19.9258 14.6434 19.9258 10.7734V3.77344"
446
+ stroke="#949999"
447
+ strokeWidth="1.5"
448
+ strokeLinecap="round"
449
+ strokeLinejoin="round"
450
+ />
451
+ </svg>
452
+ );
453
+
454
+ const ArrowDown = () => (
455
+ <svg
456
+ width="15"
457
+ height="15"
458
+ viewBox="0 0 15 15"
459
+ fill="none"
460
+ xmlns="http://www.w3.org/2000/svg">
461
+ <path
462
+ d="M12.5466 5.99219L8.74331 9.79552C8.29414 10.2447 7.55914 10.2447 7.10997 9.79552L3.30664 5.99219"
463
+ stroke="#949999"
464
+ strokeWidth="1.5"
465
+ strokeMiterlimit="10"
466
+ strokeLinecap="round"
467
+ strokeLinejoin="round"
468
+ />
469
+ </svg>
470
+ );
471
+
472
+ const TextAlignLeftIcon = () => (
473
+ <svg
474
+ width="25"
475
+ height="25"
476
+ viewBox="0 0 25 25"
477
+ fill="none"
478
+ xmlns="http://www.w3.org/2000/svg">
479
+ <path
480
+ d="M3.92578 5.27344H21.9258"
481
+ stroke="#949999"
482
+ strokeWidth="1.5"
483
+ strokeLinecap="round"
484
+ strokeLinejoin="round"
485
+ />
486
+ <path
487
+ d="M3.92578 10.2734H13.3958"
488
+ stroke="#949999"
489
+ strokeWidth="1.5"
490
+ strokeLinecap="round"
491
+ strokeLinejoin="round"
492
+ />
493
+ <path
494
+ d="M3.92578 15.2734H21.9258"
495
+ stroke="#949999"
496
+ strokeWidth="1.5"
497
+ strokeLinecap="round"
498
+ strokeLinejoin="round"
499
+ />
500
+ <path
501
+ d="M3.92578 20.2734H13.3958"
502
+ stroke="#949999"
503
+ strokeWidth="1.5"
504
+ strokeLinecap="round"
505
+ strokeLinejoin="round"
506
+ />
507
+ </svg>
508
+ );
509
+
510
+ const TextAlignCenterIcon = () => (
511
+ <svg
512
+ width="25"
513
+ height="25"
514
+ viewBox="0 0 25 25"
515
+ fill="none"
516
+ xmlns="http://www.w3.org/2000/svg">
517
+ <path
518
+ d="M3.92578 5.27344H21.9258"
519
+ stroke="#949999"
520
+ strokeWidth="1.5"
521
+ strokeLinecap="round"
522
+ strokeLinejoin="round"
523
+ />
524
+ <path
525
+ d="M8.18555 10.2734H17.6655"
526
+ stroke="#949999"
527
+ strokeWidth="1.5"
528
+ strokeLinecap="round"
529
+ strokeLinejoin="round"
530
+ />
531
+ <path
532
+ d="M3.92578 15.2734H21.9258"
533
+ stroke="#949999"
534
+ strokeWidth="1.5"
535
+ strokeLinecap="round"
536
+ strokeLinejoin="round"
537
+ />
538
+ <path
539
+ d="M8.18555 20.2734H17.6655"
540
+ stroke="#949999"
541
+ strokeWidth="1.5"
542
+ strokeLinecap="round"
543
+ strokeLinejoin="round"
544
+ />
545
+ </svg>
546
+ );
547
+
548
+ const TextAlignRight = () => (
549
+ <svg
550
+ width="25"
551
+ height="25"
552
+ viewBox="0 0 25 25"
553
+ fill="none"
554
+ xmlns="http://www.w3.org/2000/svg">
555
+ <path
556
+ d="M3.92578 5.27344H21.9258"
557
+ stroke="#949999"
558
+ strokeWidth="1.5"
559
+ strokeLinecap="round"
560
+ strokeLinejoin="round"
561
+ />
562
+ <path
563
+ d="M12.4551 10.2734H21.9251"
564
+ stroke="#949999"
565
+ strokeWidth="1.5"
566
+ strokeLinecap="round"
567
+ strokeLinejoin="round"
568
+ />
569
+ <path
570
+ d="M3.92578 15.2734H21.9258"
571
+ stroke="#949999"
572
+ strokeWidth="1.5"
573
+ strokeLinecap="round"
574
+ strokeLinejoin="round"
575
+ />
576
+ <path
577
+ d="M12.4551 20.2734H21.9251"
578
+ stroke="#949999"
579
+ strokeWidth="1.5"
580
+ strokeLinecap="round"
581
+ strokeLinejoin="round"
582
+ />
583
+ </svg>
584
+ );
585
+
586
+ const ListIcon = () => (
587
+ <svg
588
+ width="25"
589
+ height="25"
590
+ viewBox="0 0 25 25"
591
+ fill="none"
592
+ xmlns="http://www.w3.org/2000/svg">
593
+ <path
594
+ d="M11.9258 20.2734H21.9258"
595
+ stroke="#949999"
596
+ strokeWidth="1.5"
597
+ strokeLinecap="round"
598
+ strokeLinejoin="round"
599
+ />
600
+ <path
601
+ d="M11.9258 13.2734H21.9258"
602
+ stroke="#949999"
603
+ strokeWidth="1.5"
604
+ strokeLinecap="round"
605
+ strokeLinejoin="round"
606
+ />
607
+ <path
608
+ d="M11.9258 6.27344H21.9258"
609
+ stroke="#949999"
610
+ strokeWidth="1.5"
611
+ strokeLinecap="round"
612
+ strokeLinejoin="round"
613
+ />
614
+ <path
615
+ d="M3.92578 6.27344L4.92578 7.27344L7.92578 4.27344"
616
+ stroke="#949999"
617
+ strokeWidth="1.5"
618
+ strokeLinecap="round"
619
+ strokeLinejoin="round"
620
+ />
621
+ <path
622
+ d="M3.92578 13.2734L4.92578 14.2734L7.92578 11.2734"
623
+ stroke="#949999"
624
+ strokeWidth="1.5"
625
+ strokeLinecap="round"
626
+ strokeLinejoin="round"
627
+ />
628
+ <path
629
+ d="M3.92578 20.2734L4.92578 21.2734L7.92578 18.2734"
630
+ stroke="#949999"
631
+ strokeWidth="1.5"
632
+ strokeLinecap="round"
633
+ strokeLinejoin="round"
634
+ />
635
+ </svg>
636
+ );
637
+
638
+ const FirstLineIcon = () => (
639
+ <svg
640
+ width="25"
641
+ height="25"
642
+ viewBox="0 0 25 25"
643
+ fill="none"
644
+ xmlns="http://www.w3.org/2000/svg">
645
+ <path
646
+ d="M14.9258 5.27344H21.9258"
647
+ stroke="#949999"
648
+ strokeWidth="1.5"
649
+ strokeLinecap="round"
650
+ strokeLinejoin="round"
651
+ />
652
+ <path
653
+ d="M14.9258 10.2734H21.9258"
654
+ stroke="#949999"
655
+ strokeWidth="1.5"
656
+ strokeLinecap="round"
657
+ strokeLinejoin="round"
658
+ />
659
+ <path
660
+ d="M3.92578 15.2734H21.9258"
661
+ stroke="#949999"
662
+ strokeWidth="1.5"
663
+ strokeLinecap="round"
664
+ strokeLinejoin="round"
665
+ />
666
+ <path
667
+ d="M3.92578 20.2734H21.9258"
668
+ stroke="#949999"
669
+ strokeWidth="1.5"
670
+ strokeLinecap="round"
671
+ strokeLinejoin="round"
672
+ />
673
+ <path
674
+ d="M10.4258 9.20344V6.34344C10.4258 5.22344 9.97578 4.77344 8.84578 4.77344H5.99578C4.87578 4.77344 4.42578 5.22344 4.42578 6.34344V9.19344C4.42578 10.3234 4.87578 10.7734 5.99578 10.7734H8.84578C9.97578 10.7734 10.4258 10.3234 10.4258 9.20344Z"
675
+ stroke="#949999"
676
+ strokeWidth="1.5"
677
+ strokeLinecap="round"
678
+ strokeLinejoin="round"
679
+ />
680
+ </svg>
681
+ );
682
+
683
+ export default TextEditor;
@@ -0,0 +1,256 @@
1
+ @use "../../variables/colors" as c;
2
+
3
+ @mixin defaultPadding {
4
+ padding: 14px 19px;
5
+ }
6
+ .editor {
7
+ display: flex;
8
+ gap: 13px;
9
+
10
+ .editor-wrapper {
11
+ width: 100%;
12
+ position: relative;
13
+ background: #e5e5e5;
14
+ border-radius: 15px;
15
+
16
+ .emoji_picker{
17
+ position: absolute;
18
+ z-index: 1;
19
+ transform: translate(10px, 10px);
20
+ margin-left: 50%;
21
+ margin-top: -15%;
22
+
23
+ @media only screen and (max-width: 1700px) {
24
+ margin-top: -19%;
25
+ }
26
+ @media only screen and (max-width: 1600px) {
27
+ margin-top: -21%;
28
+ }
29
+ @media only screen and (max-width: 1500px) {
30
+ margin-top: -24%;
31
+ }
32
+ }
33
+
34
+ .editor_area{
35
+ background: #fff;
36
+ border-radius: 15px;
37
+
38
+ input{
39
+ border-radius: 12px;
40
+ background: #fff;
41
+ outline: none;
42
+ border: none;
43
+ width: 100%;
44
+ height: 30px;
45
+ font-size: 20px;
46
+ font-weight: 500;
47
+ padding-left: 30px;
48
+ border: "none";
49
+ margin-top: 20px;
50
+
51
+ }
52
+ .editable {
53
+ border-radius: 25px;
54
+ padding: 20px 30px;
55
+ background: #fff;
56
+ // background: #e5e5e5;
57
+ min-height: 193px;
58
+ }
59
+
60
+ }
61
+
62
+ .bottom{
63
+ display: flex;
64
+ justify-content: center;
65
+ align-items: center;
66
+ width: 80%;
67
+
68
+ .emoji_button{
69
+ background-color: white;
70
+ border: none;
71
+ cursor: pointer;
72
+ padding: 5px;
73
+ margin-top: 6px;
74
+ margin-right: 20px;
75
+ border-radius: 50%;
76
+ // opacity: 0.6;
77
+
78
+
79
+ }
80
+
81
+ .emoji_button_active{
82
+ background-color: #fff;
83
+ color: #00C2C2;
84
+ border: none;
85
+ cursor: pointer;
86
+ padding: 3px;
87
+ margin-top: 6px;
88
+ margin-right: 20px;
89
+ // border-radius: 50%;
90
+ svg path{
91
+ stroke: #00C2C2;
92
+ }
93
+ // border-radius: 20px;
94
+
95
+
96
+
97
+ }
98
+
99
+
100
+ & > button{
101
+ @media only screen and (max-width: 1400px) {
102
+ font-size: 17px !important;
103
+ font-weight: 700;
104
+ }
105
+ @media only screen and (max-width: 1366px) {
106
+ font-size: 15px !important;
107
+ font-weight: 600;
108
+ }
109
+ }
110
+
111
+ .tool-bar {
112
+ display: flex;
113
+ margin: auto;
114
+ margin-top: 16px;
115
+ margin-right: 20px;
116
+ padding: 16px;
117
+ background: #fff;
118
+ border: 0px solid c.$neutral-20;
119
+ border-radius: 12px;
120
+ width: 70%;
121
+ height: 60px;
122
+ // gap: 5px;
123
+
124
+
125
+
126
+ .list {
127
+ display: grid;
128
+ // grid-template-columns: 1fr 1fr;
129
+ gap: 2px;
130
+ & > div {
131
+ display: grid;
132
+ cursor: pointer;
133
+ }
134
+ .active{
135
+ color: #00C2C2;
136
+ svg path{
137
+ // stroke: #00C2C2;
138
+ stroke: #00C2C2;
139
+ }
140
+ }
141
+ }
142
+
143
+ .active{
144
+ opacity: 1;
145
+ }
146
+
147
+ .font {
148
+ .font-dd {
149
+ div {
150
+ border-width: 0px;
151
+ min-width: 215px;
152
+ }
153
+ p {
154
+ margin-right: 25px;
155
+ font-weight: 700;
156
+ }
157
+ }
158
+ }
159
+ .font-size {
160
+ .sizes {
161
+ div {
162
+ border-width: 0px;
163
+ // z-index: 999;
164
+ .iVkqGn{
165
+ padding: 11px 10px;
166
+ }
167
+ }
168
+ p {
169
+ margin-right: 25px;
170
+ font-weight: 700;
171
+ }
172
+ }
173
+ }
174
+ align-items: center;
175
+ & > div {
176
+ border-right: 1px solid c.$neutral-10;
177
+ padding: 0 6px;
178
+ }
179
+ .font-style {
180
+ display: flex;
181
+ gap: 5px;
182
+ & > div {
183
+ display: grid;
184
+ cursor: pointer;
185
+ // svg{
186
+ // fill: #00C2C2;
187
+ // }
188
+ }
189
+
190
+ .active{
191
+ color: #00C2C2;
192
+ svg path{
193
+ // fill: #00C2C2;
194
+ stroke: #00C2C2;
195
+ }
196
+ }
197
+ }
198
+ .color-box {
199
+ .wrap {
200
+ position: relative;
201
+ cursor: pointer;
202
+ display: flex;
203
+ align-items: center;
204
+ gap: 7px;
205
+ input {
206
+ position: absolute;
207
+ pointer-events: none;
208
+ opacity: 0;
209
+ }
210
+ .indicator {
211
+ width: 24px;
212
+ height: 24px;
213
+ border-radius: 50%;
214
+ }
215
+ }
216
+ }
217
+ .alignments {
218
+ display: grid;
219
+ grid-template-columns: 1fr 1fr 1fr;
220
+ gap: 16px;
221
+ cursor: pointer;
222
+ & > div {
223
+ display: grid;
224
+ }
225
+ .active{
226
+ color: #00C2C2;
227
+ svg path{
228
+ // fill: #00C2C2;
229
+ stroke: #00C2C2;
230
+ }
231
+ }
232
+
233
+ }
234
+ }
235
+ }
236
+ .options {
237
+ min-width: 40px;
238
+ display: grid;
239
+ align-content: start;
240
+ gap: 20px;
241
+ span {
242
+ width: 40px;
243
+ height: 40px;
244
+ border-radius: 50%;
245
+ display: grid;
246
+ align-content: center;
247
+ justify-items: center;
248
+ background-color: c.$error;
249
+ cursor: pointer;
250
+ &:nth-of-type(1) {
251
+ background-color: c.$primary-color-main;
252
+ }
253
+ }
254
+ }
255
+ }
256
+ }
@@ -0,0 +1,61 @@
1
+ import React, { useState, useRef, useCallback, useMemo } from 'react';
2
+ import { createEditor } from 'slate';
3
+ import { Slate, Editable, withReact } from 'slate-react';
4
+
5
+ import EmojiPicker from 'emoji-picker-react';
6
+
7
+ const App = () => {
8
+ const editorRef = useRef();
9
+ const inputRef = useRef();
10
+ const [showEmojiPicker, setShowEmojiPicker] = useState(false);
11
+
12
+ const editor = useMemo(() => withReact(createEditor()), []);
13
+
14
+ const handleEditorChange = (value) => {
15
+ // Update the editor's value
16
+ // This function will be called whenever the editor's content changes
17
+ // You can perform any necessary logic here
18
+ Editor.isFocused(editor) && Editor.insertText(editor, value);
19
+ };
20
+
21
+ const handleEmojiClick = (emoji) => {
22
+ // Insert the selected emoji at the current cursor position
23
+ const { selection } = editor;
24
+ if (selection) {
25
+ const emojiText = `:${emoji.name}:`;
26
+ Editor.insertText(editor, emojiText);
27
+ }
28
+ setShowEmojiPicker(false);
29
+ inputRef.current.focus();
30
+ };
31
+
32
+ const toggleEmojiPicker = () => {
33
+ setShowEmojiPicker(!showEmojiPicker);
34
+ };
35
+
36
+ return (
37
+ <div>
38
+ <button onClick={toggleEmojiPicker}>Toggle Emoji Picker</button>
39
+ {showEmojiPicker && (
40
+ <EmojiPicker onEmojiClick={handleEmojiClick} pickerStyle={{ position: 'absolute', bottom: '20px', right: '20px' }} />
41
+ )}
42
+ <Slate editor={editor} value={[]} onChange={handleEditorChange}>
43
+ <Editable
44
+ ref={editorRef}
45
+ onKeyDown={(event) => {
46
+ // Prevent default handling of the "Enter" key
47
+ if (event.key === 'Enter') {
48
+ event.preventDefault();
49
+ }
50
+ }}
51
+ renderElement={(props) => <div {...props} />}
52
+ renderLeaf={(props) => <span {...props} />}
53
+ autoFocus
54
+ />
55
+ </Slate>
56
+ <input ref={inputRef} />
57
+ </div>
58
+ );
59
+ };
60
+
61
+ export default App;