expo-native-sheet-emojis 2.0.1 → 2.0.2
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/README.md
CHANGED
|
@@ -6,7 +6,7 @@ A fully native emoji picker bottom sheet for React Native. Built entirely in Swi
|
|
|
6
6
|
|
|
7
7
|
## Highlights
|
|
8
8
|
|
|
9
|
-
- **1900+ emojis** across 9 categories (Unicode Emoji up to v16.0)
|
|
9
|
+
- **1900+ emojis** across 9 categories (Unicode Emoji up to v16.0)
|
|
10
10
|
- **60+ FPS everywhere** -- native UICollectionView (iOS) and RecyclerView (Android) with no JS bridge involvement during scrolling, searching, or animations
|
|
11
11
|
- Fully native on both platforms -- no JavaScript emoji rendering, no web views, no React re-renders
|
|
12
12
|
- Search across 21 languages powered by [Unicode CLDR](https://cldr.unicode.org/) -- the industry-standard source for emoji annotations used by iOS, Android, and major platforms. Runs on a background thread to keep the UI thread free
|
|
@@ -431,6 +431,41 @@ await EmojiSheetModule.present({
|
|
|
431
431
|
| gestureEnabled | `boolean` | `true` | Swipe to dismiss |
|
|
432
432
|
| backdropOpacity | `number` | `0.22` | Backdrop opacity |
|
|
433
433
|
|
|
434
|
+
## Companion: expo-native-emojis-popup
|
|
435
|
+
|
|
436
|
+
For quick emoji reactions (like message reaction trays), the companion module [expo-native-emojis-popup](https://github.com/efstathiosntonas/expo-native-emojis-popup) provides a fully native emoji reaction popup with long-press drag-to-select, hover labels, and spring animations.
|
|
437
|
+
|
|
438
|
+
Together they form a complete reaction system:
|
|
439
|
+
|
|
440
|
+
1. User long-presses a message/post -> `expo-native-emojis-popup` shows the quick reaction tray
|
|
441
|
+
2. User taps the plus button -> your app presents `expo-native-sheet-emojis` for the full emoji catalog
|
|
442
|
+
3. Selected emoji flows back into your reaction system
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
import { EmojisPopupModule } from 'expo-native-emojis-popup';
|
|
446
|
+
import { EmojiSheetModule } from 'expo-native-sheet-emojis';
|
|
447
|
+
|
|
448
|
+
const result = await EmojisPopupModule.show({
|
|
449
|
+
anchorId: 'message:42',
|
|
450
|
+
items: [
|
|
451
|
+
{ emoji: '❤️', emoji_name: 'Red Heart', id: 'heart' },
|
|
452
|
+
{ emoji: '👍', emoji_name: 'Thumbs Up', id: 'thumbsup' },
|
|
453
|
+
{ emoji: '😂', emoji_name: 'Face with Tears of Joy', id: 'laugh' },
|
|
454
|
+
],
|
|
455
|
+
plusEnabled: true,
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
if (result.type === 'plus') {
|
|
459
|
+
// Open the full emoji picker
|
|
460
|
+
const sheetResult = await EmojiSheetModule.present({ theme: 'dark' });
|
|
461
|
+
if (!sheetResult.cancelled) {
|
|
462
|
+
handleReaction(sheetResult.emoji);
|
|
463
|
+
}
|
|
464
|
+
} else if (result.type === 'select') {
|
|
465
|
+
handleReaction(result.id);
|
|
466
|
+
}
|
|
467
|
+
```
|
|
468
|
+
|
|
434
469
|
## LLM / AI Agent Reference
|
|
435
470
|
|
|
436
471
|
If you're an AI agent or using an LLM to integrate this module, see [llms.txt](https://raw.githubusercontent.com/efstathiosntonas/expo-native-sheet-emojis/refs/heads/main/llms.txt) for a concise, structured reference with all types, APIs, and usage patterns.
|
|
@@ -111,12 +111,16 @@ class EmojiSkinTonePicker(
|
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
//
|
|
115
|
-
val
|
|
116
|
-
anchorView.
|
|
117
|
-
val
|
|
118
|
-
val
|
|
114
|
+
// Use window-relative coordinates to avoid RTL xOff flip and status bar offset
|
|
115
|
+
val anchorLocation = IntArray(2)
|
|
116
|
+
anchorView.getLocationInWindow(anchorLocation)
|
|
117
|
+
val windowWidth = anchorView.rootView.width
|
|
118
|
+
val edgePadding = (8 * density).toInt()
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
val idealLeft = anchorLocation[0] + anchorView.width / 2 - totalWidth / 2
|
|
121
|
+
val clampedLeft = idealLeft.coerceIn(edgePadding, windowWidth - totalWidth - edgePadding)
|
|
122
|
+
val popupTop = anchorLocation[1] - totalHeight - (4 * density).toInt()
|
|
123
|
+
|
|
124
|
+
popup.showAtLocation(anchorView.rootView, Gravity.NO_GRAVITY, clampedLeft, popupTop)
|
|
121
125
|
}
|
|
122
126
|
}
|
package/ios/EmojiGridView.swift
CHANGED
|
@@ -357,7 +357,8 @@ class EmojiGridView: UIView, UICollectionViewDataSource, UICollectionViewDelegat
|
|
|
357
357
|
dismissSkinTonePicker()
|
|
358
358
|
|
|
359
359
|
guard let cell = collectionView.cellForItem(at: indexPath) else { return }
|
|
360
|
-
let
|
|
360
|
+
let targetView = superview ?? self
|
|
361
|
+
let cellFrameInTarget = collectionView.convert(cell.frame, to: targetView)
|
|
361
362
|
|
|
362
363
|
if enableHaptics {
|
|
363
364
|
impactFeedbackMedium.impactOccurred()
|
|
@@ -381,19 +382,19 @@ class EmojiGridView: UIView, UICollectionViewDataSource, UICollectionViewDelegat
|
|
|
381
382
|
self.dismissSkinTonePicker()
|
|
382
383
|
}
|
|
383
384
|
|
|
384
|
-
addSubview(picker)
|
|
385
|
+
targetView.addSubview(picker)
|
|
385
386
|
picker.translatesAutoresizingMaskIntoConstraints = false
|
|
386
387
|
|
|
387
388
|
let pickerWidth: CGFloat = 6 * 48 + 16
|
|
388
389
|
let pickerHeight: CGFloat = 56
|
|
389
390
|
|
|
390
|
-
var centerX =
|
|
391
|
+
var centerX = cellFrameInTarget.midX
|
|
391
392
|
let halfWidth = pickerWidth / 2
|
|
392
|
-
centerX = max(halfWidth +
|
|
393
|
+
centerX = max(halfWidth + 8, min(targetView.bounds.width - halfWidth - 8, centerX))
|
|
393
394
|
|
|
394
395
|
NSLayoutConstraint.activate([
|
|
395
|
-
picker.centerXAnchor.constraint(equalTo:
|
|
396
|
-
picker.bottomAnchor.constraint(equalTo: topAnchor, constant:
|
|
396
|
+
picker.centerXAnchor.constraint(equalTo: targetView.leftAnchor, constant: centerX),
|
|
397
|
+
picker.bottomAnchor.constraint(equalTo: targetView.topAnchor, constant: cellFrameInTarget.minY - 4),
|
|
397
398
|
picker.widthAnchor.constraint(equalToConstant: pickerWidth),
|
|
398
399
|
picker.heightAnchor.constraint(equalToConstant: pickerHeight),
|
|
399
400
|
])
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Pod::Spec.new do |s|
|
|
2
2
|
s.name = 'EmojiSheetModule'
|
|
3
|
-
s.version = '2.0.
|
|
3
|
+
s.version = '2.0.2'
|
|
4
4
|
s.summary = 'Native emoji picker bottom sheet for React Native'
|
|
5
5
|
s.description = 'A fully native iOS/Android emoji picker presented in a bottom sheet with search, skin tones, and theming support.'
|
|
6
6
|
s.author = ''
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-native-sheet-emojis",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "A fully native emoji picker bottom sheet for React Native. Built with Swift and Kotlin for maximum performance. Features search with multilingual keywords, skin tones, frequently used tracking, theming, and configurable layout.",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"input"
|
|
33
33
|
],
|
|
34
34
|
"license": "MIT",
|
|
35
|
-
"author": "Efstathios Ntonas
|
|
35
|
+
"author": "Efstathios Ntonas",
|
|
36
36
|
"homepage": "https://github.com/efstathiosntonas/expo-native-sheet-emojis#readme",
|
|
37
37
|
"bugs": {
|
|
38
38
|
"url": "https://github.com/efstathiosntonas/expo-native-sheet-emojis/issues"
|