expo-native-sheet-emojis 1.1.0 → 1.2.1

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.
@@ -20,11 +20,11 @@ buildscript {
20
20
  android {
21
21
  namespace "expo.community.modules.emojisheet"
22
22
 
23
- compileSdkVersion safeExtGet("compileSdkVersion", 34)
23
+ compileSdkVersion safeExtGet("compileSdkVersion", 35)
24
24
 
25
25
  defaultConfig {
26
- minSdkVersion safeExtGet("minSdkVersion", 21)
27
- targetSdkVersion safeExtGet("targetSdkVersion", 34)
26
+ minSdkVersion safeExtGet("minSdkVersion", 24)
27
+ targetSdkVersion safeExtGet("targetSdkVersion", 35)
28
28
  versionCode 1
29
29
  versionName "1.0.0"
30
30
  }
@@ -45,5 +45,7 @@ android {
45
45
  implementation "androidx.recyclerview:recyclerview:1.3.2"
46
46
  implementation "androidx.appcompat:appcompat:1.6.1"
47
47
  implementation "com.google.android.material:material:1.11.0"
48
+ implementation "androidx.emoji2:emoji2:1.6.0"
49
+ implementation "androidx.emoji2:emoji2-views-helper:1.6.0"
48
50
  }
49
51
  }
@@ -1,6 +1,7 @@
1
1
  package expo.community.modules.emojisheet
2
2
 
3
3
  import android.content.Context
4
+ import android.os.Build
4
5
  import org.json.JSONArray
5
6
 
6
7
  data class EmojiItem(
@@ -37,6 +38,7 @@ object EmojiData {
37
38
  val json = context.assets.open("emojis.json").bufferedReader().use { it.readText() }
38
39
  val array = JSONArray(json)
39
40
  val categories = mutableListOf<EmojiCategory>()
41
+ val maxVersion = maxSupportedEmojiVersion()
40
42
  for (i in 0 until array.length()) {
41
43
  val obj = array.getJSONObject(i)
42
44
  val title = obj.getString("title")
@@ -44,6 +46,8 @@ object EmojiData {
44
46
  val items = mutableListOf<EmojiItem>()
45
47
  for (j in 0 until dataArray.length()) {
46
48
  val item = dataArray.getJSONObject(j)
49
+ val emojiVersion = item.getString("v").toDoubleOrNull() ?: 0.0
50
+ if (emojiVersion > maxVersion) continue
47
51
  val keywordsArray = item.getJSONArray("keywords")
48
52
  val keywords = mutableListOf<String>()
49
53
  for (k in 0 until keywordsArray.length()) {
@@ -65,6 +69,21 @@ object EmojiData {
65
69
  return categories
66
70
  }
67
71
 
72
+ // API level → max Unicode emoji version (conservative estimates)
73
+ private fun maxSupportedEmojiVersion(): Double {
74
+ return when {
75
+ Build.VERSION.SDK_INT >= 35 -> 16.0
76
+ Build.VERSION.SDK_INT >= 34 -> 15.0
77
+ Build.VERSION.SDK_INT >= 33 -> 15.0
78
+ Build.VERSION.SDK_INT >= 32 -> 14.0
79
+ Build.VERSION.SDK_INT >= 31 -> 14.0
80
+ Build.VERSION.SDK_INT >= 30 -> 13.1
81
+ Build.VERSION.SDK_INT >= 29 -> 12.1
82
+ Build.VERSION.SDK_INT >= 28 -> 11.0
83
+ else -> 11.0
84
+ }
85
+ }
86
+
68
87
  fun displayName(categoryTitle: String, customNames: Map<String, String>? = null): String {
69
88
  customNames?.get(categoryTitle)?.let { return it }
70
89
  return categoryDisplayNames[categoryTitle] ?: categoryTitle.replace("_", " ")
@@ -8,6 +8,9 @@ import android.view.View
8
8
  import android.view.ViewGroup
9
9
  import android.view.animation.AccelerateDecelerateInterpolator
10
10
  import android.view.WindowManager
11
+ import androidx.core.view.ViewCompat
12
+ import androidx.core.view.WindowCompat
13
+ import androidx.core.view.WindowInsetsCompat
11
14
  import android.widget.FrameLayout
12
15
  import android.widget.LinearLayout
13
16
  import com.google.android.material.bottomsheet.BottomSheetBehavior
@@ -240,6 +243,18 @@ class EmojiSheetModule : Module() {
240
243
 
241
244
  bottomSheet.setContentView(container)
242
245
 
246
+ ViewCompat.setOnApplyWindowInsetsListener(container) { view, insets ->
247
+ val imeInsets = insets.getInsets(WindowInsetsCompat.Type.ime())
248
+ val systemBarInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
249
+ view.setPadding(
250
+ systemBarInsets.left,
251
+ 0,
252
+ systemBarInsets.right,
253
+ maxOf(imeInsets.bottom, systemBarInsets.bottom)
254
+ )
255
+ WindowInsetsCompat.CONSUMED
256
+ }
257
+
243
258
  // Strip ALL backgrounds from BottomSheet internals
244
259
  bottomSheet.setOnShowListener { dlg ->
245
260
  val d = dlg as BottomSheetDialog
@@ -252,7 +267,9 @@ class EmojiSheetModule : Module() {
252
267
  pickerView.loadDataAsync()
253
268
  }
254
269
 
255
- bottomSheet.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
270
+ bottomSheet.window?.let { window ->
271
+ WindowCompat.setDecorFitsSystemWindows(window, false)
272
+ }
256
273
  bottomSheet.window?.setDimAmount(backdropOpacity)
257
274
 
258
275
  bottomSheet.behavior.apply {
@@ -1,6 +1,6 @@
1
1
  Pod::Spec.new do |s|
2
2
  s.name = 'EmojiSheetModule'
3
- s.version = '1.1.0'
3
+ s.version = '1.2.1'
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 = ''
@@ -393,6 +393,23 @@ class EmojiSheetUIView: UIView,
393
393
  }
394
394
  }
395
395
 
396
+ // iOS version → max Unicode emoji version. Source: https://emojipedia.org/apple
397
+ // Cases MUST remain ordered most-specific first (Swift evaluates top-to-bottom).
398
+ private static func maxSupportedEmojiVersion() -> Double {
399
+ let osVersion = ProcessInfo.processInfo.operatingSystemVersion
400
+ switch (osVersion.majorVersion, osVersion.minorVersion) {
401
+ case (18, 4...): return 16.0
402
+ case (18, _): return 15.1
403
+ case (17, 4...): return 15.1
404
+ case (17, _): return 15.0
405
+ case (16, 4...): return 15.0
406
+ case (16, _): return 14.0
407
+ case (15, 4...): return 14.0
408
+ case (15, _): return 13.1
409
+ default: return 13.1
410
+ }
411
+ }
412
+
396
413
  private static func parseEmojiJSON() -> [EmojiSection] {
397
414
  let bundle = Bundle(for: EmojiSheetUIView.self)
398
415
  guard let url = bundle.url(forResource: "emojis", withExtension: "json"),
@@ -402,6 +419,7 @@ class EmojiSheetUIView: UIView,
402
419
  return []
403
420
  }
404
421
 
422
+ let maxVersion = Self.maxSupportedEmojiVersion()
405
423
  return json.compactMap { sectionDict -> EmojiSection? in
406
424
  guard let title = sectionDict["title"] as? String,
407
425
  let items = sectionDict["data"] as? [[String: Any]]
@@ -418,6 +436,8 @@ class EmojiSheetUIView: UIView,
418
436
  else {
419
437
  return nil
420
438
  }
439
+ let emojiVersion = Double(v) ?? 0
440
+ guard emojiVersion <= maxVersion else { return nil }
421
441
  return EmojiItem(emoji: emoji, name: name, version: v, toneEnabled: toneEnabled, keywords: keywords, id: id)
422
442
  }
423
443
  return EmojiSection(title: title, data: emojis)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-native-sheet-emojis",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
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",