l-min-components 1.7.1544 → 1.7.1545
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.7.
|
|
3
|
+
"version": "1.7.1545",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"src/assets",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"draft-js": "^0.11.7",
|
|
29
29
|
"draftjs-to-html": "^0.9.1",
|
|
30
30
|
"emoji-picker-react": "^4.12.0",
|
|
31
|
+
"emojibase-data": "^16.0.3",
|
|
31
32
|
"hls.js": "^1.6.11",
|
|
32
33
|
"html-to-draftjs": "^1.5.0",
|
|
33
34
|
"i": "^0.3.7",
|
|
@@ -1,24 +1,159 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import EmojiPicker from "emoji-picker-react";
|
|
1
|
+
import React, { useMemo } from "react";
|
|
3
2
|
import styled from "styled-components";
|
|
4
3
|
import useTranslation from "../../hooks/useTranslation.jsx";
|
|
5
4
|
import wordStore from "../../mc/wordStore.json";
|
|
5
|
+
|
|
6
|
+
import data from "emojibase-data/en/data.json";
|
|
7
|
+
|
|
8
|
+
// NOTE: SearchComponent is no longer needed/imported
|
|
9
|
+
// import { SearchComponent } from "../index.js";
|
|
10
|
+
|
|
6
11
|
const EmojiModal = ({ onChange }) => {
|
|
7
12
|
const { findText } = useTranslation(wordStore);
|
|
13
|
+
const HIGH_PRIORITY_GROUPS = [0, 1];
|
|
14
|
+
|
|
15
|
+
// 1. Removed useState and handleSearchChange as search is removed
|
|
16
|
+
|
|
17
|
+
const displayedEmojis = useMemo(() => {
|
|
18
|
+
if (!Array.isArray(data)) return [];
|
|
19
|
+
|
|
20
|
+
// Helper to extract text sources once
|
|
21
|
+
const getTextSources = (emoji) => {
|
|
22
|
+
return [
|
|
23
|
+
emoji.annotation,
|
|
24
|
+
emoji.name,
|
|
25
|
+
emoji.shortcodes && emoji.shortcodes.join?.(" "),
|
|
26
|
+
emoji.keywords && emoji.keywords.join?.(" "),
|
|
27
|
+
]
|
|
28
|
+
.filter(Boolean)
|
|
29
|
+
.join(" ")
|
|
30
|
+
.toLowerCase();
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const isFaceOrHand = (emoji) => {
|
|
34
|
+
const emojiChar = emoji.emoji || "";
|
|
35
|
+
const textSources = getTextSources(emoji);
|
|
36
|
+
|
|
37
|
+
// --- 1. EXCLUSION: TARGETED EMOJIS (UPDATED) ---
|
|
38
|
+
|
|
39
|
+
// NEW EXCLUSION LIST: Blue Heart, Shaking Face, Flying Saucer, Pushing Hands, Goose
|
|
40
|
+
if (
|
|
41
|
+
emojiChar === "🩶" ||
|
|
42
|
+
emojiChar === "🩵" || // NEW: Light Blue Heart
|
|
43
|
+
emojiChar === "𫸸" || // NEW: Rightwards Pushing Hand (if standard emoji)
|
|
44
|
+
emojiChar === "𫆶" || // NEW: Goose (if standard emoji)
|
|
45
|
+
emojiChar === "𫩠" || // NEW: Wing (if standard emoji)
|
|
46
|
+
emojiChar === "𫩞" // NEW: Coral (if standard emoji)
|
|
47
|
+
)
|
|
48
|
+
return false;
|
|
49
|
+
|
|
50
|
+
// NOTE: 𫸸, 𫆶, etc., are in the private use area and might not render/filter properly
|
|
51
|
+
// depending on how emojibase handles them. Using the more common representations:
|
|
52
|
+
if (
|
|
53
|
+
emojiChar === "🫨" || // Shaking Face
|
|
54
|
+
emojiChar === "" || // Mini Jet
|
|
55
|
+
emojiChar === "🫷" || // Leftwards Pushing Hand
|
|
56
|
+
emojiChar === "🫸" || // Rightwards Pushing Hand
|
|
57
|
+
emojiChar === "" // Goose
|
|
58
|
+
)
|
|
59
|
+
return false;
|
|
60
|
+
|
|
61
|
+
// Exclude Directional Action ZWJ sequences (e.g., 🏃♂️➡️)
|
|
62
|
+
if (emojiChar.includes("➡️") || emojiChar.includes("←")) return false;
|
|
63
|
+
|
|
64
|
+
// Exclude ZWJ faces with arrows (↕️, ↔️)
|
|
65
|
+
if (
|
|
66
|
+
emojiChar.includes("↕️") ||
|
|
67
|
+
emojiChar.includes("↔️") ||
|
|
68
|
+
emojiChar.includes("⬆️") ||
|
|
69
|
+
emojiChar.includes("⬇️")
|
|
70
|
+
)
|
|
71
|
+
return false;
|
|
72
|
+
|
|
73
|
+
// Exclude ZWJ job roles (💻, ⚕️, 🌾, 🧑)
|
|
74
|
+
if (
|
|
75
|
+
emojiChar.includes("💻") ||
|
|
76
|
+
emojiChar.includes("⚕️") ||
|
|
77
|
+
emojiChar.includes("🌾") ||
|
|
78
|
+
emojiChar.includes("🧑")
|
|
79
|
+
)
|
|
80
|
+
return false;
|
|
81
|
+
|
|
82
|
+
// Arrow/Direction Text Exclusion (for non-face symbols)
|
|
83
|
+
if (
|
|
84
|
+
textSources.includes("arrow") ||
|
|
85
|
+
textSources.includes("direction") ||
|
|
86
|
+
(emoji.group === 6 &&
|
|
87
|
+
(textSources.includes("right") || textSources.includes("left")))
|
|
88
|
+
) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// --- 2. INCLUSION: Logic to keep faces/hands/hearts ---
|
|
93
|
+
const subgroup = emoji.subgroup;
|
|
94
|
+
if (typeof subgroup === "string") {
|
|
95
|
+
const s = subgroup.toLowerCase();
|
|
96
|
+
if (s.startsWith("face") || s.startsWith("hand") || s.includes("hand"))
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (
|
|
101
|
+
typeof emoji.group === "number" &&
|
|
102
|
+
HIGH_PRIORITY_GROUPS.includes(emoji.group)
|
|
103
|
+
)
|
|
104
|
+
return true;
|
|
105
|
+
|
|
106
|
+
if (textSources) {
|
|
107
|
+
if (
|
|
108
|
+
textSources.includes("face") ||
|
|
109
|
+
textSources.includes("hand") ||
|
|
110
|
+
textSources.includes("finger") ||
|
|
111
|
+
textSources.includes("heart") ||
|
|
112
|
+
textSources.includes("love")
|
|
113
|
+
) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return false;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// 1. Filtering (only Faces, Hands, Hearts remain, with all exclusions applied)
|
|
121
|
+
const filtered = data.filter(isFaceOrHand);
|
|
122
|
+
|
|
123
|
+
// 2. Sorting (Priority groups 0 and 1 remain at the top)
|
|
124
|
+
filtered.sort((a, b) => {
|
|
125
|
+
const isAPriority = HIGH_PRIORITY_GROUPS.includes(a.group);
|
|
126
|
+
const isBPriority = HIGH_PRIORITY_GROUPS.includes(b.group);
|
|
127
|
+
|
|
128
|
+
if (isAPriority && !isBPriority) return -1;
|
|
129
|
+
if (!isAPriority && isBPriority) return 1;
|
|
130
|
+
|
|
131
|
+
if (a.group !== b.group) return (a.group ?? 0) - (b.group ?? 0);
|
|
132
|
+
|
|
133
|
+
return (a.order ?? 0) - (b.order ?? 0);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
return filtered;
|
|
137
|
+
}, [data]); // Removed searchQuery from dependencies
|
|
138
|
+
|
|
8
139
|
return (
|
|
9
140
|
<Container>
|
|
10
|
-
<
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
141
|
+
<Grid>
|
|
142
|
+
{displayedEmojis?.map((emoji) => (
|
|
143
|
+
<button
|
|
144
|
+
key={emoji?.hexcode}
|
|
145
|
+
onClick={() => onChange(emoji)}
|
|
146
|
+
title={emoji?.label}
|
|
147
|
+
>
|
|
148
|
+
{emoji?.emoji}
|
|
149
|
+
</button>
|
|
150
|
+
))}
|
|
151
|
+
</Grid>
|
|
19
152
|
</Container>
|
|
20
153
|
);
|
|
21
154
|
};
|
|
155
|
+
|
|
156
|
+
// ... (Styled components remain the same) ...
|
|
22
157
|
const Container = styled.div`
|
|
23
158
|
background-color: #fff;
|
|
24
159
|
width: fit-content;
|
|
@@ -26,13 +161,57 @@ const Container = styled.div`
|
|
|
26
161
|
z-index: 3;
|
|
27
162
|
left: 0;
|
|
28
163
|
bottom: 40px;
|
|
164
|
+
width: 263px;
|
|
165
|
+
border-radius: 12px;
|
|
166
|
+
padding: 12px;
|
|
167
|
+
|
|
29
168
|
.epr-main {
|
|
30
|
-
background-color: #fff;
|
|
169
|
+
background-color: #fff !important;
|
|
31
170
|
}
|
|
32
171
|
|
|
33
172
|
.epr-header,
|
|
34
173
|
.epr-emoji-category-label {
|
|
35
|
-
display: none;
|
|
174
|
+
display: none !important;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.epr-body {
|
|
178
|
+
overflow-y: auto !important;
|
|
179
|
+
max-height: 300px !important;
|
|
180
|
+
scrollbar-width: thin;
|
|
181
|
+
will-change: transform;
|
|
182
|
+
transform: translateZ(0);
|
|
183
|
+
}
|
|
184
|
+
`;
|
|
185
|
+
|
|
186
|
+
export const Grid = styled.div`
|
|
187
|
+
display: grid;
|
|
188
|
+
grid-template-columns: repeat(4, 1fr);
|
|
189
|
+
width: 100%;
|
|
190
|
+
gap: 8px;
|
|
191
|
+
height: 280px;
|
|
192
|
+
overflow-y: auto;
|
|
193
|
+
button {
|
|
194
|
+
width: 52px;
|
|
195
|
+
height: 52px;
|
|
196
|
+
display: grid;
|
|
197
|
+
place-items: center;
|
|
198
|
+
font-size: 24px;
|
|
199
|
+
cursor: pointer;
|
|
200
|
+
border: none;
|
|
201
|
+
background: none;
|
|
202
|
+
border-radius: 10px;
|
|
203
|
+
transition: background 0.2s ease, transform 0.15s ease;
|
|
204
|
+
|
|
205
|
+
&:hover {
|
|
206
|
+
background: rgba(0, 0, 0, 0.08); /* light gray hover */
|
|
207
|
+
transform: scale(1.05);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
&:active {
|
|
211
|
+
transform: scale(0.97);
|
|
212
|
+
background: rgba(0, 0, 0, 0.12);
|
|
213
|
+
}
|
|
36
214
|
}
|
|
37
215
|
`;
|
|
216
|
+
|
|
38
217
|
export default EmojiModal;
|
|
@@ -100,7 +100,7 @@ const List = ({ currentState, onChange }) => {
|
|
|
100
100
|
aria-selected={currentState?.listType === "unordered"}
|
|
101
101
|
title={findText("Unordered")}
|
|
102
102
|
onClick={() => {
|
|
103
|
-
onChange(
|
|
103
|
+
onChange("unordered");
|
|
104
104
|
}}
|
|
105
105
|
>
|
|
106
106
|
<ListIcon />
|
|
@@ -120,9 +120,9 @@ const Colors = ({ onChange, expanded, onExpandEvent, currentState }) => {
|
|
|
120
120
|
>
|
|
121
121
|
{expanded && (
|
|
122
122
|
<ColorModal
|
|
123
|
-
color={currentState?.color ||
|
|
123
|
+
color={currentState?.color || "#000000"}
|
|
124
124
|
onChange={(v) => {
|
|
125
|
-
onChange(
|
|
125
|
+
onChange("color", v?.hex);
|
|
126
126
|
}}
|
|
127
127
|
/>
|
|
128
128
|
)}
|
|
@@ -194,7 +194,7 @@ const Fontsize = ({ onExpandEvent, expanded, onChange, currentState }) => {
|
|
|
194
194
|
onChange(i);
|
|
195
195
|
}}
|
|
196
196
|
>
|
|
197
|
-
{i}{
|
|
197
|
+
{i}{" "}
|
|
198
198
|
</li>
|
|
199
199
|
))}
|
|
200
200
|
</ul>
|
|
@@ -9,10 +9,10 @@ import ButtonComponent from "../button";
|
|
|
9
9
|
import OutsideAlerter from "../outsideEventChecker";
|
|
10
10
|
// import { fontList } from "../../pages/createLectures/defaults";
|
|
11
11
|
|
|
12
|
-
import EmojiPicker from
|
|
13
|
-
import Grammerly from
|
|
14
|
-
import { CompactPicker } from
|
|
15
|
-
import ColorModal from
|
|
12
|
+
import EmojiPicker from "emoji-picker-react";
|
|
13
|
+
import Grammerly from "./assets/grammerly";
|
|
14
|
+
import { CompactPicker } from "react-color";
|
|
15
|
+
import ColorModal from "./colorModal";
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* @param {{
|
|
@@ -127,6 +127,7 @@ const TextEditor = ({
|
|
|
127
127
|
previewConfig={{
|
|
128
128
|
showPreview: false,
|
|
129
129
|
}}
|
|
130
|
+
searchPlaceholder=""
|
|
130
131
|
/>
|
|
131
132
|
</div>
|
|
132
133
|
)}
|
|
@@ -142,7 +143,7 @@ const TextEditor = ({
|
|
|
142
143
|
color={fontColor}
|
|
143
144
|
onChangeComplete={(color) => {
|
|
144
145
|
setFontColor(color.hex);
|
|
145
|
-
toggleMark(editor,
|
|
146
|
+
toggleMark(editor, "color", color.hex);
|
|
146
147
|
}}
|
|
147
148
|
/>
|
|
148
149
|
</div>
|
|
@@ -190,7 +191,7 @@ const TextEditor = ({
|
|
|
190
191
|
}}
|
|
191
192
|
dropdownData={fontSizes()}
|
|
192
193
|
onSelect={({ name }) => {
|
|
193
|
-
toggleMark(editor,
|
|
194
|
+
toggleMark(editor, "fontSize", name);
|
|
194
195
|
}}
|
|
195
196
|
/>
|
|
196
197
|
</div>
|
|
@@ -210,7 +211,7 @@ const TextEditor = ({
|
|
|
210
211
|
ref={colorInput}
|
|
211
212
|
onChange={(e) => {
|
|
212
213
|
setFontColor(e.target.value);
|
|
213
|
-
toggleMark(editor,
|
|
214
|
+
toggleMark(editor, "color", e.target.value);
|
|
214
215
|
}}
|
|
215
216
|
/>
|
|
216
217
|
<div
|
|
@@ -224,30 +225,30 @@ const TextEditor = ({
|
|
|
224
225
|
</div>
|
|
225
226
|
<div className="font-style">
|
|
226
227
|
<div
|
|
227
|
-
className={boldActive ?
|
|
228
|
+
className={boldActive ? "active" : ""}
|
|
228
229
|
onMouseDown={(event) => {
|
|
229
230
|
event.preventDefault();
|
|
230
|
-
toggleMark(editor,
|
|
231
|
+
toggleMark(editor, "bold");
|
|
231
232
|
setBoldActive(!boldActive);
|
|
232
233
|
}}
|
|
233
234
|
>
|
|
234
235
|
<BoldIcons />
|
|
235
236
|
</div>
|
|
236
237
|
<div
|
|
237
|
-
className={italicActive ?
|
|
238
|
+
className={italicActive ? "active" : ""}
|
|
238
239
|
onMouseDown={(event) => {
|
|
239
240
|
event.preventDefault();
|
|
240
|
-
toggleMark(editor,
|
|
241
|
+
toggleMark(editor, "italic");
|
|
241
242
|
setItalicActive(!italicActive);
|
|
242
243
|
}}
|
|
243
244
|
>
|
|
244
245
|
<ItalicIcon />
|
|
245
246
|
</div>
|
|
246
247
|
<div
|
|
247
|
-
className={underlinective ?
|
|
248
|
+
className={underlinective ? "active" : "underline"}
|
|
248
249
|
onMouseDown={(event) => {
|
|
249
250
|
event.preventDefault();
|
|
250
|
-
toggleMark(editor,
|
|
251
|
+
toggleMark(editor, "underline");
|
|
251
252
|
setUnderlineActive(!underlinective);
|
|
252
253
|
}}
|
|
253
254
|
>
|
|
@@ -256,10 +257,10 @@ const TextEditor = ({
|
|
|
256
257
|
</div>
|
|
257
258
|
<div className="alignments">
|
|
258
259
|
<div
|
|
259
|
-
className={leftActive ?
|
|
260
|
+
className={leftActive ? "a-left active" : "a-left"}
|
|
260
261
|
onMouseDown={(event) => {
|
|
261
262
|
event.preventDefault();
|
|
262
|
-
toggleMark(editor,
|
|
263
|
+
toggleMark(editor, "textAlign", "left");
|
|
263
264
|
setLeftActive(!leftActive);
|
|
264
265
|
setCenterActive(false);
|
|
265
266
|
setRightActive(false);
|
|
@@ -268,10 +269,10 @@ const TextEditor = ({
|
|
|
268
269
|
<TextAlignLeftIcon />
|
|
269
270
|
</div>
|
|
270
271
|
<div
|
|
271
|
-
className={centerActive ?
|
|
272
|
+
className={centerActive ? "a-center active" : "a-center"}
|
|
272
273
|
onMouseDown={(event) => {
|
|
273
274
|
event.preventDefault();
|
|
274
|
-
toggleMark(editor,
|
|
275
|
+
toggleMark(editor, "textAlign", "center");
|
|
275
276
|
setCenterActive(!centerActive);
|
|
276
277
|
setLeftActive(false);
|
|
277
278
|
setRightActive(false);
|
|
@@ -280,10 +281,10 @@ const TextEditor = ({
|
|
|
280
281
|
<TextAlignCenterIcon />
|
|
281
282
|
</div>
|
|
282
283
|
<div
|
|
283
|
-
className={rightActive ?
|
|
284
|
+
className={rightActive ? "a-right active" : "a-right"}
|
|
284
285
|
onMouseDown={(event) => {
|
|
285
286
|
event.preventDefault();
|
|
286
|
-
toggleMark(editor,
|
|
287
|
+
toggleMark(editor, "textAlign", "right");
|
|
287
288
|
setRightActive(!rightActive);
|
|
288
289
|
setCenterActive(false);
|
|
289
290
|
setLeftActive(false);
|
|
@@ -294,9 +295,9 @@ const TextEditor = ({
|
|
|
294
295
|
</div>
|
|
295
296
|
<div className="list">
|
|
296
297
|
<div
|
|
297
|
-
className={listActive ?
|
|
298
|
+
className={listActive ? "list-icon active" : "list-icon"}
|
|
298
299
|
onClick={() => {
|
|
299
|
-
toggleMark(editor,
|
|
300
|
+
toggleMark(editor, "list");
|
|
300
301
|
setListActive(!listActive);
|
|
301
302
|
}}
|
|
302
303
|
>
|
|
@@ -307,7 +308,7 @@ const TextEditor = ({
|
|
|
307
308
|
</div> */}
|
|
308
309
|
</div>
|
|
309
310
|
<button
|
|
310
|
-
className={active ?
|
|
311
|
+
className={active ? "emoji_button_active" : "emoji_button"}
|
|
311
312
|
// onClick={handleEmojiButton}
|
|
312
313
|
onMouseDown={(e) => {
|
|
313
314
|
e.preventDefault();
|
|
@@ -323,13 +324,13 @@ const TextEditor = ({
|
|
|
323
324
|
<ButtonComponent
|
|
324
325
|
text={findText("Create Announcement")}
|
|
325
326
|
styles={{
|
|
326
|
-
fontSize:
|
|
327
|
-
width:
|
|
327
|
+
fontSize: "18px",
|
|
328
|
+
width: "30%",
|
|
328
329
|
// textAlign: "center",
|
|
329
|
-
padding:
|
|
330
|
-
borderRadius:
|
|
331
|
-
marginTop:
|
|
332
|
-
height:
|
|
330
|
+
padding: "8px 17px",
|
|
331
|
+
borderRadius: "12px",
|
|
332
|
+
marginTop: "15px",
|
|
333
|
+
height: "50px",
|
|
333
334
|
// marginLeft: "15px",
|
|
334
335
|
}}
|
|
335
336
|
onClick={click}
|
|
@@ -439,14 +440,14 @@ const BoldIcons = (props) => (
|
|
|
439
440
|
>
|
|
440
441
|
<path
|
|
441
442
|
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"
|
|
442
|
-
stroke={props.stroke ??
|
|
443
|
+
stroke={props.stroke ?? "#313333"}
|
|
443
444
|
strokeWidth="1.5"
|
|
444
445
|
strokeLinecap="round"
|
|
445
446
|
strokeLinejoin="round"
|
|
446
447
|
/>
|
|
447
448
|
<path
|
|
448
449
|
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"
|
|
449
|
-
stroke={props.stroke ??
|
|
450
|
+
stroke={props.stroke ?? "#313333"}
|
|
450
451
|
strokeWidth="1.5"
|
|
451
452
|
strokeLinecap="round"
|
|
452
453
|
strokeLinejoin="round"
|
|
@@ -175,10 +175,12 @@ const VideoPlayer2 = ({
|
|
|
175
175
|
hlsRef.current?.loadSource(url);
|
|
176
176
|
});
|
|
177
177
|
hlsRef.current?.on(Hls.Events.LEVEL_SWITCHED, (val) => {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
178
|
+
setIsReady(true);
|
|
179
|
+
setError(null);
|
|
180
|
+
if (val === "hlsLevelSwitched") {
|
|
181
|
+
setIsReady(true);
|
|
182
|
+
setError(null);
|
|
183
|
+
}
|
|
182
184
|
});
|
|
183
185
|
hlsRef.current?.on(Hls.Events.LEVEL_LOADING, (val) => {
|
|
184
186
|
if (val === "hlsLevelLoading") {
|