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.1544",
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
- <EmojiPicker
11
- theme={findText("light")}
12
- searchDisabled
13
- skinTonesDisabled
14
- emojiStyle={findText("apple")}
15
- width={270}
16
- height={300}
17
- onEmojiClick={onChange}
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('unordered');
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 || '#000000'}
123
+ color={currentState?.color || "#000000"}
124
124
  onChange={(v) => {
125
- onChange('color', v?.hex);
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 'emoji-picker-react';
13
- import Grammerly from './assets/grammerly';
14
- import { CompactPicker } from 'react-color';
15
- import ColorModal from './colorModal';
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, 'color', color.hex);
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, 'fontSize', name);
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, 'color', e.target.value);
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 ? 'active' : ''}
228
+ className={boldActive ? "active" : ""}
228
229
  onMouseDown={(event) => {
229
230
  event.preventDefault();
230
- toggleMark(editor, 'bold');
231
+ toggleMark(editor, "bold");
231
232
  setBoldActive(!boldActive);
232
233
  }}
233
234
  >
234
235
  <BoldIcons />
235
236
  </div>
236
237
  <div
237
- className={italicActive ? 'active' : ''}
238
+ className={italicActive ? "active" : ""}
238
239
  onMouseDown={(event) => {
239
240
  event.preventDefault();
240
- toggleMark(editor, 'italic');
241
+ toggleMark(editor, "italic");
241
242
  setItalicActive(!italicActive);
242
243
  }}
243
244
  >
244
245
  <ItalicIcon />
245
246
  </div>
246
247
  <div
247
- className={underlinective ? 'active' : 'underline'}
248
+ className={underlinective ? "active" : "underline"}
248
249
  onMouseDown={(event) => {
249
250
  event.preventDefault();
250
- toggleMark(editor, 'underline');
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 ? 'a-left active' : 'a-left'}
260
+ className={leftActive ? "a-left active" : "a-left"}
260
261
  onMouseDown={(event) => {
261
262
  event.preventDefault();
262
- toggleMark(editor, 'textAlign', 'left');
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 ? 'a-center active' : 'a-center'}
272
+ className={centerActive ? "a-center active" : "a-center"}
272
273
  onMouseDown={(event) => {
273
274
  event.preventDefault();
274
- toggleMark(editor, 'textAlign', 'center');
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 ? 'a-right active' : 'a-right'}
284
+ className={rightActive ? "a-right active" : "a-right"}
284
285
  onMouseDown={(event) => {
285
286
  event.preventDefault();
286
- toggleMark(editor, 'textAlign', 'right');
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 ? 'list-icon active' : 'list-icon'}
298
+ className={listActive ? "list-icon active" : "list-icon"}
298
299
  onClick={() => {
299
- toggleMark(editor, 'list');
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 ? 'emoji_button_active' : 'emoji_button'}
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: '18px',
327
- width: '30%',
327
+ fontSize: "18px",
328
+ width: "30%",
328
329
  // textAlign: "center",
329
- padding: '8px 17px',
330
- borderRadius: '12px',
331
- marginTop: '15px',
332
- height: '50px',
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 ?? '#313333'}
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 ?? '#313333'}
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
- // setIsReady(true);
179
- // setError(null);
180
- // if (val === "hlsLevelSwitched") {
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") {