expo-native-sheet-emojis 2.0.4 → 2.1.0
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.
|
@@ -9,11 +9,14 @@ import android.view.ViewGroup
|
|
|
9
9
|
import android.view.animation.AccelerateDecelerateInterpolator
|
|
10
10
|
import android.view.WindowManager
|
|
11
11
|
import android.view.inputmethod.InputMethodManager
|
|
12
|
+
import android.widget.Button
|
|
13
|
+
import android.widget.FrameLayout
|
|
14
|
+
import android.widget.LinearLayout
|
|
15
|
+
import androidx.core.view.AccessibilityDelegateCompat
|
|
12
16
|
import androidx.core.view.ViewCompat
|
|
13
17
|
import androidx.core.view.WindowCompat
|
|
14
18
|
import androidx.core.view.WindowInsetsCompat
|
|
15
|
-
import
|
|
16
|
-
import android.widget.LinearLayout
|
|
19
|
+
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
|
|
17
20
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
|
18
21
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
|
19
22
|
import expo.modules.kotlin.Promise
|
|
@@ -250,19 +253,37 @@ class EmojiSheetModule : Module() {
|
|
|
250
253
|
}
|
|
251
254
|
|
|
252
255
|
// Drag handle
|
|
256
|
+
val handleTargetHeight = (24 * density).toInt()
|
|
253
257
|
val handleBar = View(activity).apply {
|
|
254
258
|
val width = (40 * density).toInt()
|
|
255
259
|
val height = (4 * density).toInt()
|
|
256
|
-
layoutParams =
|
|
257
|
-
gravity = Gravity.CENTER_HORIZONTAL
|
|
260
|
+
layoutParams = FrameLayout.LayoutParams(width, height, Gravity.TOP or Gravity.CENTER_HORIZONTAL).apply {
|
|
258
261
|
topMargin = (8 * density).toInt()
|
|
259
|
-
bottomMargin = (4 * density).toInt()
|
|
260
262
|
}
|
|
261
263
|
background = GradientDrawable().apply {
|
|
262
264
|
setColor(handleColor)
|
|
263
265
|
cornerRadius = height / 2f
|
|
264
266
|
}
|
|
265
267
|
}
|
|
268
|
+
val handleTouchTarget = FrameLayout(activity).apply {
|
|
269
|
+
layoutParams = LinearLayout.LayoutParams(
|
|
270
|
+
LinearLayout.LayoutParams.MATCH_PARENT,
|
|
271
|
+
handleTargetHeight
|
|
272
|
+
)
|
|
273
|
+
contentDescription = "Dismiss emoji sheet"
|
|
274
|
+
importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES
|
|
275
|
+
isClickable = true
|
|
276
|
+
isFocusable = true
|
|
277
|
+
setOnClickListener { dismissSheet(cancelled = true) }
|
|
278
|
+
ViewCompat.setAccessibilityDelegate(this, object : AccessibilityDelegateCompat() {
|
|
279
|
+
override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfoCompat) {
|
|
280
|
+
super.onInitializeAccessibilityNodeInfo(host, info)
|
|
281
|
+
info.className = Button::class.java.name
|
|
282
|
+
info.hintText = "Double tap to dismiss."
|
|
283
|
+
}
|
|
284
|
+
})
|
|
285
|
+
addView(handleBar)
|
|
286
|
+
}
|
|
266
287
|
|
|
267
288
|
// Container
|
|
268
289
|
val halfExpandedRatio = (snapPoints.firstOrNull()?.toFloat() ?: 0.5f).coerceIn(0.05f, 1f)
|
|
@@ -285,7 +306,7 @@ class EmojiSheetModule : Module() {
|
|
|
285
306
|
}
|
|
286
307
|
clipToOutline = true
|
|
287
308
|
outlineProvider = android.view.ViewOutlineProvider.BACKGROUND
|
|
288
|
-
addView(
|
|
309
|
+
addView(handleTouchTarget)
|
|
289
310
|
val pickerLp = LinearLayout.LayoutParams(
|
|
290
311
|
LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f
|
|
291
312
|
)
|
|
@@ -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.1.0'
|
|
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 = ''
|
|
@@ -337,6 +337,7 @@ private final class SheetViewController: UIViewController, UIGestureRecognizerDe
|
|
|
337
337
|
|
|
338
338
|
private let backdropView = UIView()
|
|
339
339
|
private let sheetContainerView = UIView()
|
|
340
|
+
private let grabberHitAreaView = UIControl()
|
|
340
341
|
private let grabberView = UIView()
|
|
341
342
|
private let contentContainerView = UIView()
|
|
342
343
|
private let backdropColor: UIColor
|
|
@@ -411,6 +412,11 @@ private final class SheetViewController: UIViewController, UIGestureRecognizerDe
|
|
|
411
412
|
applyDetentLayout(currentDetent)
|
|
412
413
|
}
|
|
413
414
|
|
|
415
|
+
override func accessibilityPerformEscape() -> Bool {
|
|
416
|
+
requestDismiss()
|
|
417
|
+
return true
|
|
418
|
+
}
|
|
419
|
+
|
|
414
420
|
func embedPickerView(_ embeddedView: UIView) {
|
|
415
421
|
embeddedView.translatesAutoresizingMaskIntoConstraints = false
|
|
416
422
|
contentContainerView.addSubview(embeddedView)
|
|
@@ -574,9 +580,7 @@ private final class SheetViewController: UIViewController, UIGestureRecognizerDe
|
|
|
574
580
|
let dismissalThreshold = max(sheetContainerView.bounds.height * 0.5, 1)
|
|
575
581
|
let shouldDismiss = distance >= dismissalThreshold || velocity >= 1400
|
|
576
582
|
if shouldDismiss {
|
|
577
|
-
|
|
578
|
-
self?.onDismiss?()
|
|
579
|
-
}
|
|
583
|
+
requestDismiss()
|
|
580
584
|
return
|
|
581
585
|
}
|
|
582
586
|
|
|
@@ -632,17 +636,28 @@ private final class SheetViewController: UIViewController, UIGestureRecognizerDe
|
|
|
632
636
|
sheetContainerView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
|
|
633
637
|
sheetContainerView.layer.masksToBounds = true
|
|
634
638
|
|
|
639
|
+
grabberHitAreaView.translatesAutoresizingMaskIntoConstraints = false
|
|
640
|
+
grabberHitAreaView.backgroundColor = .clear
|
|
641
|
+
grabberHitAreaView.isAccessibilityElement = true
|
|
642
|
+
grabberHitAreaView.accessibilityLabel = "Dismiss emoji sheet"
|
|
643
|
+
grabberHitAreaView.accessibilityHint = "Double-tap to dismiss."
|
|
644
|
+
grabberHitAreaView.accessibilityTraits = .button
|
|
645
|
+
grabberHitAreaView.addTarget(self, action: #selector(handleGrabberTap), for: .touchUpInside)
|
|
646
|
+
|
|
635
647
|
grabberView.translatesAutoresizingMaskIntoConstraints = false
|
|
636
648
|
grabberView.backgroundColor = theme.handleColor
|
|
637
649
|
grabberView.layer.cornerRadius = Layout.grabberHeight / 2
|
|
650
|
+
grabberView.isUserInteractionEnabled = false
|
|
638
651
|
|
|
639
652
|
contentContainerView.translatesAutoresizingMaskIntoConstraints = false
|
|
640
653
|
contentContainerView.backgroundColor = .clear
|
|
641
654
|
|
|
655
|
+
sheetContainerView.accessibilityViewIsModal = true
|
|
642
656
|
view.addSubview(backdropView)
|
|
643
657
|
view.addSubview(sheetContainerView)
|
|
644
658
|
sheetContainerView.addSubview(contentContainerView)
|
|
645
|
-
sheetContainerView.addSubview(
|
|
659
|
+
sheetContainerView.addSubview(grabberHitAreaView)
|
|
660
|
+
grabberHitAreaView.addSubview(grabberView)
|
|
646
661
|
|
|
647
662
|
if gestureEnabled {
|
|
648
663
|
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handleSheetPan(_:)))
|
|
@@ -668,11 +683,16 @@ private final class SheetViewController: UIViewController, UIGestureRecognizerDe
|
|
|
668
683
|
sheetContainerView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
|
669
684
|
sheetBottomConstraint,
|
|
670
685
|
|
|
686
|
+
grabberHitAreaView.topAnchor.constraint(equalTo: sheetContainerView.topAnchor),
|
|
687
|
+
grabberHitAreaView.centerXAnchor.constraint(equalTo: sheetContainerView.centerXAnchor),
|
|
688
|
+
grabberHitAreaView.widthAnchor.constraint(equalToConstant: 96),
|
|
689
|
+
grabberHitAreaView.heightAnchor.constraint(equalToConstant: 24),
|
|
690
|
+
|
|
671
691
|
grabberView.topAnchor.constraint(
|
|
672
|
-
equalTo:
|
|
692
|
+
equalTo: grabberHitAreaView.topAnchor,
|
|
673
693
|
constant: Layout.grabberTopInset
|
|
674
694
|
),
|
|
675
|
-
grabberView.centerXAnchor.constraint(equalTo:
|
|
695
|
+
grabberView.centerXAnchor.constraint(equalTo: grabberHitAreaView.centerXAnchor),
|
|
676
696
|
grabberView.widthAnchor.constraint(equalToConstant: Layout.grabberWidth),
|
|
677
697
|
grabberView.heightAnchor.constraint(equalToConstant: Layout.grabberHeight),
|
|
678
698
|
|
|
@@ -684,6 +704,15 @@ private final class SheetViewController: UIViewController, UIGestureRecognizerDe
|
|
|
684
704
|
}
|
|
685
705
|
|
|
686
706
|
@objc private func handleBackdropTap() {
|
|
707
|
+
requestDismiss()
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
@objc private func handleGrabberTap() {
|
|
711
|
+
requestDismiss()
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
private func requestDismiss() {
|
|
715
|
+
guard !isAnimatingDismissal else { return }
|
|
687
716
|
dismissSheet { [weak self] in
|
|
688
717
|
self?.onDismiss?()
|
|
689
718
|
}
|
|
@@ -713,9 +742,7 @@ private final class SheetViewController: UIViewController, UIGestureRecognizerDe
|
|
|
713
742
|
velocityY > Layout.dismissVelocityThreshold
|
|
714
743
|
|
|
715
744
|
if shouldDismiss {
|
|
716
|
-
|
|
717
|
-
self?.onDismiss?()
|
|
718
|
-
}
|
|
745
|
+
requestDismiss()
|
|
719
746
|
} else {
|
|
720
747
|
let targetDetent: Detent
|
|
721
748
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-native-sheet-emojis",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
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",
|