@cyberkaidev/ui 0.1.2 → 0.1.3

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.
@@ -1,13 +1,12 @@
1
1
  "use strict";
2
2
 
3
- import { Platform, Pressable, TouchableOpacity } from 'react-native';
4
- import { useColors } from "../ThemeProvider.js";
3
+ import { Platform, TouchableOpacity } from 'react-native';
4
+ import { RippleEffect } from "./RippleEffect.js";
5
5
  import { jsx as _jsx } from "react/jsx-runtime";
6
6
  /**
7
- * Base pressable. Android gets the platform touch ripple (drawn in the
8
- * foreground and clipped to the view's own shape); every other platform gets
9
- * opacity feedback. Kept in one file (not `.ios`/`.android`) so consumers' type
10
- * resolution works without `moduleSuffixes`.
7
+ * Base pressable. Android gets a touch ripple; every other platform gets
8
+ * opacity feedback. Kept in one file (not `.ios`/`.android`) so consumers'
9
+ * type resolution works without `moduleSuffixes`.
11
10
  */
12
11
  export function Button({
13
12
  children,
@@ -18,11 +17,11 @@ export function Button({
18
17
  style,
19
18
  testID,
20
19
  hitSlop,
21
- rippleColor
20
+ rippleColor,
21
+ rippleContainerBorderRadius
22
22
  }) {
23
- const colors = useColors();
24
23
  if (Platform.OS === 'android') {
25
- return /*#__PURE__*/_jsx(Pressable, {
24
+ return /*#__PURE__*/_jsx(RippleEffect, {
26
25
  testID: testID,
27
26
  style: style,
28
27
  disabled: disabled,
@@ -30,10 +29,8 @@ export function Button({
30
29
  onPressIn: onPressIn,
31
30
  onPressOut: onPressOut,
32
31
  hitSlop: hitSlop,
33
- android_ripple: {
34
- color: rippleColor ?? colors.text,
35
- foreground: true
36
- },
32
+ rippleColor: rippleColor,
33
+ rippleContainerBorderRadius: rippleContainerBorderRadius,
37
34
  children: children
38
35
  });
39
36
  }
@@ -1 +1 @@
1
- {"version":3,"names":["Platform","Pressable","TouchableOpacity","useColors","jsx","_jsx","Button","children","onPress","onPressIn","onPressOut","disabled","style","testID","hitSlop","rippleColor","colors","OS","android_ripple","color","text","foreground"],"sourceRoot":"../../../src","sources":["components/Button.tsx"],"mappings":";;AACA,SAASA,QAAQ,EAAEC,SAAS,EAAEC,gBAAgB,QAAQ,cAAc;AAGpE,SAASC,SAAS,QAAQ,qBAAkB;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAe7C;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,MAAMA,CAAC;EACrBC,QAAQ;EACRC,OAAO;EACPC,SAAS;EACTC,UAAU;EACVC,QAAQ;EACRC,KAAK;EACLC,MAAM;EACNC,OAAO;EACPC;AACK,CAAC,EAAE;EACR,MAAMC,MAAM,GAAGb,SAAS,CAAC,CAAC;EAE1B,IAAIH,QAAQ,CAACiB,EAAE,KAAK,SAAS,EAAE;IAC7B,oBACEZ,IAAA,CAACJ,SAAS;MACRY,MAAM,EAAEA,MAAO;MACfD,KAAK,EAAEA,KAAM;MACbD,QAAQ,EAAEA,QAAS;MACnBH,OAAO,EAAEA,OAAQ;MACjBC,SAAS,EAAEA,SAAU;MACrBC,UAAU,EAAEA,UAAW;MACvBI,OAAO,EAAEA,OAAQ;MACjBI,cAAc,EAAE;QACdC,KAAK,EAAEJ,WAAW,IAAIC,MAAM,CAACI,IAAI;QACjCC,UAAU,EAAE;MACd,CAAE;MAAAd,QAAA,EAEDA;IAAQ,CACA,CAAC;EAEhB;EAEA,oBACEF,IAAA,CAACH,gBAAgB;IACfW,MAAM,EAAEA,MAAO;IACfD,KAAK,EAAEA,KAAM;IACbD,QAAQ,EAAEA,QAAS;IACnBH,OAAO,EAAEA,OAAQ;IACjBC,SAAS,EAAEA,SAAU;IACrBC,UAAU,EAAEA,UAAW;IACvBI,OAAO,EAAEA,OAAQ;IAAAP,QAAA,EAEhBA;EAAQ,CACO,CAAC;AAEvB","ignoreList":[]}
1
+ {"version":3,"names":["Platform","TouchableOpacity","RippleEffect","jsx","_jsx","Button","children","onPress","onPressIn","onPressOut","disabled","style","testID","hitSlop","rippleColor","rippleContainerBorderRadius","OS"],"sourceRoot":"../../../src","sources":["components/Button.tsx"],"mappings":";;AACA,SAASA,QAAQ,EAAEC,gBAAgB,QAAQ,cAAc;AAGzD,SAASC,YAAY,QAAQ,mBAAgB;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAiB9C;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,MAAMA,CAAC;EACrBC,QAAQ;EACRC,OAAO;EACPC,SAAS;EACTC,UAAU;EACVC,QAAQ;EACRC,KAAK;EACLC,MAAM;EACNC,OAAO;EACPC,WAAW;EACXC;AACK,CAAC,EAAE;EACR,IAAIf,QAAQ,CAACgB,EAAE,KAAK,SAAS,EAAE;IAC7B,oBACEZ,IAAA,CAACF,YAAY;MACXU,MAAM,EAAEA,MAAO;MACfD,KAAK,EAAEA,KAAM;MACbD,QAAQ,EAAEA,QAAS;MACnBH,OAAO,EAAEA,OAAQ;MACjBC,SAAS,EAAEA,SAAU;MACrBC,UAAU,EAAEA,UAAW;MACvBI,OAAO,EAAEA,OAAQ;MACjBC,WAAW,EAAEA,WAAY;MACzBC,2BAA2B,EAAEA,2BAA4B;MAAAT,QAAA,EAExDA;IAAQ,CACG,CAAC;EAEnB;EAEA,oBACEF,IAAA,CAACH,gBAAgB;IACfW,MAAM,EAAEA,MAAO;IACfD,KAAK,EAAEA,KAAM;IACbD,QAAQ,EAAEA,QAAS;IACnBH,OAAO,EAAEA,OAAQ;IACjBC,SAAS,EAAEA,SAAU;IACrBC,UAAU,EAAEA,UAAW;IACvBI,OAAO,EAAEA,OAAQ;IAAAP,QAAA,EAEhBA;EAAQ,CACO,CAAC;AAEvB","ignoreList":[]}
@@ -9,6 +9,13 @@ const RELEASE_GROW_DURATION = 150;
9
9
  const RELEASE_FADE_DURATION = 250;
10
10
  const PRESS_FADE_IN_DURATION = 75;
11
11
 
12
+ // The ripple animations run on the JS driver on purpose. On the New
13
+ // Architecture a native-driven animation started in the same tick the
14
+ // `Animated.View` is created has no native view to bind to yet, so it never
15
+ // plays — which is why the ripple showed on RN 0.83 but not on 0.86+.
16
+ const USE_NATIVE_DRIVER = false;
17
+ const toFinite = (value, fallback) => Number.isFinite(value) ? value : fallback;
18
+
12
19
  /** Wraps a child and paints a touch ripple at the press location. */
13
20
  export function RippleEffect({
14
21
  children,
@@ -54,17 +61,19 @@ export function RippleEffect({
54
61
  const w2 = 0.5 * layout.width;
55
62
  const h2 = 0.5 * layout.height;
56
63
 
57
- // Fall back to the center when the gesture carries no coordinates.
58
- const {
59
- locationX,
60
- locationY
61
- } = rippleCentered || !event?.nativeEvent ? {
62
- locationX: w2,
63
- locationY: h2
64
- } : event.nativeEvent;
64
+ // Fall back to the center when the gesture carries no coordinates, and
65
+ // clamp to the pressable's box — some setups report press coordinates
66
+ // relative to the wrong ancestor, which would push the circle off-screen
67
+ // where `overflow: 'hidden'` clips it away entirely.
68
+ const centered = rippleCentered || !event?.nativeEvent;
69
+ const clampX = value => layout.width > 0 ? Math.min(Math.max(value, 0), layout.width) : value;
70
+ const clampY = value => layout.height > 0 ? Math.min(Math.max(value, 0), layout.height) : value;
71
+ const locationX = centered ? w2 : clampX(toFinite(event.nativeEvent.locationX, w2));
72
+ const locationY = centered ? h2 : clampY(toFinite(event.nativeEvent.locationY, h2));
65
73
  const offsetX = Math.abs(w2 - locationX);
66
74
  const offsetY = Math.abs(h2 - locationY);
67
- const radius = rippleSize > 0 ? 0.5 * rippleSize : Math.sqrt((w2 + offsetX) ** 2 + (h2 + offsetY) ** 2);
75
+ const computedRadius = rippleSize > 0 ? 0.5 * rippleSize : Math.sqrt((w2 + offsetX) ** 2 + (h2 + offsetY) ** 2);
76
+ const radius = Number.isFinite(computedRadius) && computedRadius > 0 ? computedRadius : Math.max(w2, h2, CIRCLE_RADIUS);
68
77
  const ripple = {
69
78
  unique: uniqueRef.current++,
70
79
  locationX,
@@ -75,13 +84,19 @@ export function RippleEffect({
75
84
  };
76
85
  ripplesRef.current.set(ripple.unique, ripple);
77
86
  activeRippleRef.current = ripple.unique;
78
-
79
- // The entrance animation is kicked off from `RippleCircle`'s mount effect,
80
- // not here: on the New Architecture, starting a native-driven animation on
81
- // an `Animated.Value` before its `Animated.View` is mounted leaves the
82
- // native driver with no view to attach to, so the ripple never shows.
87
+ Animated.timing(ripple.scale, {
88
+ toValue: 1,
89
+ duration: rippleDuration,
90
+ easing: Easing.out(Easing.ease),
91
+ useNativeDriver: USE_NATIVE_DRIVER
92
+ }).start();
93
+ Animated.timing(ripple.opacity, {
94
+ toValue: rippleOpacity,
95
+ duration: Math.min(rippleDuration, PRESS_FADE_IN_DURATION),
96
+ useNativeDriver: USE_NATIVE_DRIVER
97
+ }).start();
83
98
  setRippleIds(current => current.concat(ripple.unique));
84
- }, [layout.width, layout.height, onPressIn, rippleCentered, rippleSequential, rippleSize]);
99
+ }, [layout.width, layout.height, onPressIn, rippleCentered, rippleDuration, rippleOpacity, rippleSequential, rippleSize]);
85
100
  const handlePressOut = React.useCallback(event => {
86
101
  onPressOut?.(event);
87
102
  const releasedUnique = activeRippleRef.current;
@@ -100,11 +115,11 @@ export function RippleEffect({
100
115
  Animated.parallel([Animated.timing(ripple.scale, {
101
116
  toValue: 1,
102
117
  duration: RELEASE_GROW_DURATION,
103
- useNativeDriver: true
118
+ useNativeDriver: USE_NATIVE_DRIVER
104
119
  }), Animated.timing(ripple.opacity, {
105
120
  toValue: 0,
106
121
  duration: RELEASE_FADE_DURATION,
107
- useNativeDriver: true
122
+ useNativeDriver: USE_NATIVE_DRIVER
108
123
  })]).start(removeRipple);
109
124
  }, [onPressOut, rippleFades]);
110
125
  return /*#__PURE__*/_jsxs(Pressable, {
@@ -117,6 +132,7 @@ export function RippleEffect({
117
132
  style: style,
118
133
  children: children
119
134
  }), /*#__PURE__*/_jsx(View, {
135
+ collapsable: false,
120
136
  pointerEvents: "none",
121
137
  style: [styles.container, {
122
138
  borderRadius: rippleContainerBorderRadius
@@ -126,9 +142,7 @@ export function RippleEffect({
126
142
  if (!ripple) return null;
127
143
  return /*#__PURE__*/_jsx(RippleCircle, {
128
144
  ripple: ripple,
129
- color: color,
130
- duration: rippleDuration,
131
- toOpacity: rippleOpacity
145
+ color: color
132
146
  }, id);
133
147
  })
134
148
  })]
@@ -136,9 +150,7 @@ export function RippleEffect({
136
150
  }
137
151
  function RippleCircleComponent({
138
152
  ripple,
139
- color,
140
- duration,
141
- toOpacity
153
+ color
142
154
  }) {
143
155
  const {
144
156
  locationX,
@@ -147,21 +159,6 @@ function RippleCircleComponent({
147
159
  scale,
148
160
  opacity
149
161
  } = ripple;
150
- React.useEffect(() => {
151
- Animated.timing(scale, {
152
- toValue: 1,
153
- duration,
154
- easing: Easing.out(Easing.ease),
155
- useNativeDriver: true
156
- }).start();
157
- Animated.timing(opacity, {
158
- toValue: toOpacity,
159
- duration: Math.min(duration, PRESS_FADE_IN_DURATION),
160
- useNativeDriver: true
161
- }).start();
162
- // Entrance runs exactly once, when the ripple view mounts.
163
- // eslint-disable-next-line react-hooks/exhaustive-deps
164
- }, []);
165
162
  const rippleStyle = {
166
163
  top: locationY - CIRCLE_RADIUS,
167
164
  [I18nManager.isRTL ? 'right' : 'left']: locationX - CIRCLE_RADIUS,
@@ -1 +1 @@
1
- {"version":3,"names":["React","Animated","Easing","I18nManager","Pressable","StyleSheet","View","useColors","jsx","_jsx","jsxs","_jsxs","CIRCLE_RADIUS","RELEASE_GROW_DURATION","RELEASE_FADE_DURATION","PRESS_FADE_IN_DURATION","RippleEffect","children","rippleColor","rippleOpacity","rippleDuration","rippleSize","rippleContainerBorderRadius","rippleCentered","rippleSequential","rippleFades","disabled","style","onLayout","onPressIn","onPressOut","pressableProps","colors","color","text","layout","setLayout","useState","width","height","rippleIds","setRippleIds","ripplesRef","useRef","Map","activeRippleRef","uniqueRef","handleLayout","event","nativeEvent","handlePressIn","useCallback","current","size","w2","h2","locationX","locationY","offsetX","Math","abs","offsetY","radius","sqrt","ripple","unique","scale","Value","opacity","set","concat","handlePressOut","releasedUnique","get","removeRipple","delete","filter","id","parallel","timing","toValue","duration","useNativeDriver","start","pointerEvents","styles","container","borderRadius","map","RippleCircle","toOpacity","RippleCircleComponent","useEffect","easing","out","ease","min","rippleStyle","top","isRTL","backgroundColor","transform","interpolate","inputRange","outputRange","circle","memo","create","absoluteFillObject","overflow","position"],"sourceRoot":"../../../src","sources":["components/RippleEffect.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["React","Animated","Easing","I18nManager","Pressable","StyleSheet","View","useColors","jsx","_jsx","jsxs","_jsxs","CIRCLE_RADIUS","RELEASE_GROW_DURATION","RELEASE_FADE_DURATION","PRESS_FADE_IN_DURATION","USE_NATIVE_DRIVER","toFinite","value","fallback","Number","isFinite","RippleEffect","children","rippleColor","rippleOpacity","rippleDuration","rippleSize","rippleContainerBorderRadius","rippleCentered","rippleSequential","rippleFades","disabled","style","onLayout","onPressIn","onPressOut","pressableProps","colors","color","text","layout","setLayout","useState","width","height","rippleIds","setRippleIds","ripplesRef","useRef","Map","activeRippleRef","uniqueRef","handleLayout","event","nativeEvent","handlePressIn","useCallback","current","size","w2","h2","centered","clampX","Math","min","max","clampY","locationX","locationY","offsetX","abs","offsetY","computedRadius","sqrt","radius","ripple","unique","scale","Value","opacity","set","timing","toValue","duration","easing","out","ease","useNativeDriver","start","concat","handlePressOut","releasedUnique","get","removeRipple","delete","filter","id","parallel","collapsable","pointerEvents","styles","container","borderRadius","map","RippleCircle","RippleCircleComponent","rippleStyle","top","isRTL","backgroundColor","transform","interpolate","inputRange","outputRange","circle","memo","create","absoluteFillObject","overflow","position"],"sourceRoot":"../../../src","sources":["components/RippleEffect.tsx"],"mappings":";;AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SACEC,QAAQ,EACRC,MAAM,EACNC,WAAW,EACXC,SAAS,EACTC,UAAU,EACVC,IAAI,QACC,cAAc;AASrB,SAASC,SAAS,QAAQ,qBAAkB;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AA2B7C,MAAMC,aAAa,GAAG,EAAE;AACxB,MAAMC,qBAAqB,GAAG,GAAG;AACjC,MAAMC,qBAAqB,GAAG,GAAG;AACjC,MAAMC,sBAAsB,GAAG,EAAE;;AAEjC;AACA;AACA;AACA;AACA,MAAMC,iBAAiB,GAAG,KAAK;AAE/B,MAAMC,QAAQ,GAAGA,CAACC,KAAa,EAAEC,QAAgB,KAC/CC,MAAM,CAACC,QAAQ,CAACH,KAAK,CAAC,GAAGA,KAAK,GAAGC,QAAQ;;AAE3C;AACA,OAAO,SAASG,YAAYA,CAAC;EAC3BC,QAAQ;EACRC,WAAW;EACXC,aAAa,GAAG,GAAG;EACnBC,cAAc,GAAG,GAAG;EACpBC,UAAU,GAAG,CAAC;EACdC,2BAA2B,GAAG,CAAC;EAC/BC,cAAc,GAAG,KAAK;EACtBC,gBAAgB,GAAG,KAAK;EACxBC,WAAW,GAAG,IAAI;EAClBC,QAAQ,GAAG,KAAK;EAChBC,KAAK;EACLC,QAAQ;EACRC,SAAS;EACTC,UAAU;EACV,GAAGC;AACE,CAAC,EAAE;EACR,MAAMC,MAAM,GAAG/B,SAAS,CAAC,CAAC;EAC1B,MAAMgC,KAAK,GAAGf,WAAW,IAAIc,MAAM,CAACE,IAAI;EAExC,MAAM,CAACC,MAAM,EAAEC,SAAS,CAAC,GAAG1C,KAAK,CAAC2C,QAAQ,CAAC;IAAEC,KAAK,EAAE,CAAC;IAAEC,MAAM,EAAE;EAAE,CAAC,CAAC;EACnE,MAAM,CAACC,SAAS,EAAEC,YAAY,CAAC,GAAG/C,KAAK,CAAC2C,QAAQ,CAAW,EAAE,CAAC;EAC9D,MAAMK,UAAU,GAAGhD,KAAK,CAACiD,MAAM,CAAC,IAAIC,GAAG,CAAyB,CAAC,CAAC;EAClE,MAAMC,eAAe,GAAGnD,KAAK,CAACiD,MAAM,CAAgB,IAAI,CAAC;EACzD,MAAMG,SAAS,GAAGpD,KAAK,CAACiD,MAAM,CAAC,CAAC,CAAC;EAEjC,MAAMI,YAAY,GAAIC,KAAwB,IAAK;IACjD,MAAM;MAAEV,KAAK;MAAEC;IAAO,CAAC,GAAGS,KAAK,CAACC,WAAW,CAACd,MAAM;IAClDC,SAAS,CAAC;MAAEE,KAAK;MAAEC;IAAO,CAAC,CAAC;IAC5BX,QAAQ,GAAGoB,KAAK,CAAC;EACnB,CAAC;EAED,MAAME,aAAa,GAAGxD,KAAK,CAACyD,WAAW,CACpCH,KAA4B,IAAK;IAChCnB,SAAS,GAAGmB,KAAK,CAAC;IAElB,IAAIxB,gBAAgB,IAAIkB,UAAU,CAACU,OAAO,CAACC,IAAI,EAAE;IAEjD,MAAMC,EAAE,GAAG,GAAG,GAAGnB,MAAM,CAACG,KAAK;IAC7B,MAAMiB,EAAE,GAAG,GAAG,GAAGpB,MAAM,CAACI,MAAM;;IAE9B;IACA;IACA;IACA;IACA,MAAMiB,QAAQ,GAAGjC,cAAc,IAAI,CAACyB,KAAK,EAAEC,WAAW;IACtD,MAAMQ,MAAM,GAAI7C,KAAa,IAC3BuB,MAAM,CAACG,KAAK,GAAG,CAAC,GAAGoB,IAAI,CAACC,GAAG,CAACD,IAAI,CAACE,GAAG,CAAChD,KAAK,EAAE,CAAC,CAAC,EAAEuB,MAAM,CAACG,KAAK,CAAC,GAAG1B,KAAK;IACvE,MAAMiD,MAAM,GAAIjD,KAAa,IAC3BuB,MAAM,CAACI,MAAM,GAAG,CAAC,GAAGmB,IAAI,CAACC,GAAG,CAACD,IAAI,CAACE,GAAG,CAAChD,KAAK,EAAE,CAAC,CAAC,EAAEuB,MAAM,CAACI,MAAM,CAAC,GAAG3B,KAAK;IACzE,MAAMkD,SAAS,GAAGN,QAAQ,GACtBF,EAAE,GACFG,MAAM,CAAC9C,QAAQ,CAACqC,KAAK,CAACC,WAAW,CAACa,SAAS,EAAER,EAAE,CAAC,CAAC;IACrD,MAAMS,SAAS,GAAGP,QAAQ,GACtBD,EAAE,GACFM,MAAM,CAAClD,QAAQ,CAACqC,KAAK,CAACC,WAAW,CAACc,SAAS,EAAER,EAAE,CAAC,CAAC;IAErD,MAAMS,OAAO,GAAGN,IAAI,CAACO,GAAG,CAACX,EAAE,GAAGQ,SAAS,CAAC;IACxC,MAAMI,OAAO,GAAGR,IAAI,CAACO,GAAG,CAACV,EAAE,GAAGQ,SAAS,CAAC;IAExC,MAAMI,cAAc,GAClB9C,UAAU,GAAG,CAAC,GACV,GAAG,GAAGA,UAAU,GAChBqC,IAAI,CAACU,IAAI,CAAC,CAACd,EAAE,GAAGU,OAAO,KAAK,CAAC,GAAG,CAACT,EAAE,GAAGW,OAAO,KAAK,CAAC,CAAC;IAC1D,MAAMG,MAAM,GACVvD,MAAM,CAACC,QAAQ,CAACoD,cAAc,CAAC,IAAIA,cAAc,GAAG,CAAC,GACjDA,cAAc,GACdT,IAAI,CAACE,GAAG,CAACN,EAAE,EAAEC,EAAE,EAAEjD,aAAa,CAAC;IAErC,MAAMgE,MAAsB,GAAG;MAC7BC,MAAM,EAAEzB,SAAS,CAACM,OAAO,EAAE;MAC3BU,SAAS;MACTC,SAAS;MACTM,MAAM;MACNG,KAAK,EAAE,IAAI7E,QAAQ,CAAC8E,KAAK,CAAC,CAAC,CAAC;MAC5BC,OAAO,EAAE,IAAI/E,QAAQ,CAAC8E,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED/B,UAAU,CAACU,OAAO,CAACuB,GAAG,CAACL,MAAM,CAACC,MAAM,EAAED,MAAM,CAAC;IAC7CzB,eAAe,CAACO,OAAO,GAAGkB,MAAM,CAACC,MAAM;IAEvC5E,QAAQ,CAACiF,MAAM,CAACN,MAAM,CAACE,KAAK,EAAE;MAC5BK,OAAO,EAAE,CAAC;MACVC,QAAQ,EAAE1D,cAAc;MACxB2D,MAAM,EAAEnF,MAAM,CAACoF,GAAG,CAACpF,MAAM,CAACqF,IAAI,CAAC;MAC/BC,eAAe,EAAExE;IACnB,CAAC,CAAC,CAACyE,KAAK,CAAC,CAAC;IAEVxF,QAAQ,CAACiF,MAAM,CAACN,MAAM,CAACI,OAAO,EAAE;MAC9BG,OAAO,EAAE1D,aAAa;MACtB2D,QAAQ,EAAEpB,IAAI,CAACC,GAAG,CAACvC,cAAc,EAAEX,sBAAsB,CAAC;MAC1DyE,eAAe,EAAExE;IACnB,CAAC,CAAC,CAACyE,KAAK,CAAC,CAAC;IAEV1C,YAAY,CAAEW,OAAO,IAAKA,OAAO,CAACgC,MAAM,CAACd,MAAM,CAACC,MAAM,CAAC,CAAC;EAC1D,CAAC,EACD,CACEpC,MAAM,CAACG,KAAK,EACZH,MAAM,CAACI,MAAM,EACbV,SAAS,EACTN,cAAc,EACdH,cAAc,EACdD,aAAa,EACbK,gBAAgB,EAChBH,UAAU,CAEd,CAAC;EAED,MAAMgE,cAAc,GAAG3F,KAAK,CAACyD,WAAW,CACrCH,KAA4B,IAAK;IAChClB,UAAU,GAAGkB,KAAK,CAAC;IAEnB,MAAMsC,cAAc,GAAGzC,eAAe,CAACO,OAAO;IAC9CP,eAAe,CAACO,OAAO,GAAG,IAAI;IAC9B,IAAIkC,cAAc,KAAK,IAAI,EAAE;IAE7B,MAAMhB,MAAM,GAAG5B,UAAU,CAACU,OAAO,CAACmC,GAAG,CAACD,cAAc,CAAC;IACrD,IAAI,CAAChB,MAAM,EAAE;IAEb,MAAMkB,YAAY,GAAGA,CAAA,KAAM;MACzB9C,UAAU,CAACU,OAAO,CAACqC,MAAM,CAACH,cAAc,CAAC;MACzC7C,YAAY,CAAEW,OAAO,IACnBA,OAAO,CAACsC,MAAM,CAAEC,EAAE,IAAKA,EAAE,KAAKL,cAAc,CAC9C,CAAC;IACH,CAAC;IAED,IAAI,CAAC7D,WAAW,EAAE;MAChB+D,YAAY,CAAC,CAAC;MACd;IACF;IAEA7F,QAAQ,CAACiG,QAAQ,CAAC,CAChBjG,QAAQ,CAACiF,MAAM,CAACN,MAAM,CAACE,KAAK,EAAE;MAC5BK,OAAO,EAAE,CAAC;MACVC,QAAQ,EAAEvE,qBAAqB;MAC/B2E,eAAe,EAAExE;IACnB,CAAC,CAAC,EACFf,QAAQ,CAACiF,MAAM,CAACN,MAAM,CAACI,OAAO,EAAE;MAC9BG,OAAO,EAAE,CAAC;MACVC,QAAQ,EAAEtE,qBAAqB;MAC/B0E,eAAe,EAAExE;IACnB,CAAC,CAAC,CACH,CAAC,CAACyE,KAAK,CAACK,YAAY,CAAC;EACxB,CAAC,EACD,CAAC1D,UAAU,EAAEL,WAAW,CAC1B,CAAC;EAED,oBACEpB,KAAA,CAACP,SAAS;IAAA,GACJiC,cAAc;IAClBL,QAAQ,EAAEA,QAAS;IACnBE,QAAQ,EAAEmB,YAAa;IACvBlB,SAAS,EAAEqB,aAAc;IACzBpB,UAAU,EAAEuD,cAAe;IAAApE,QAAA,gBAE3Bd,IAAA,CAACH,IAAI;MAAC2B,KAAK,EAAEA,KAAM;MAAAV,QAAA,EAAEA;IAAQ,CAAO,CAAC,eACrCd,IAAA,CAACH,IAAI;MACH6F,WAAW,EAAE,KAAM;MACnBC,aAAa,EAAC,MAAM;MACpBnE,KAAK,EAAE,CACLoE,MAAM,CAACC,SAAS,EAChB;QAAEC,YAAY,EAAE3E;MAA4B,CAAC,CAC7C;MAAAL,QAAA,EAEDuB,SAAS,CAAC0D,GAAG,CAAEP,EAAE,IAAK;QACrB,MAAMrB,MAAM,GAAG5B,UAAU,CAACU,OAAO,CAACmC,GAAG,CAACI,EAAE,CAAC;QACzC,IAAI,CAACrB,MAAM,EAAE,OAAO,IAAI;QACxB,oBAAOnE,IAAA,CAACgG,YAAY;UAAU7B,MAAM,EAAEA,MAAO;UAACrC,KAAK,EAAEA;QAAM,GAAjC0D,EAAmC,CAAC;MAChE,CAAC;IAAC,CACE,CAAC;EAAA,CACE,CAAC;AAEhB;AAOA,SAASS,qBAAqBA,CAAC;EAAE9B,MAAM;EAAErC;AAAyB,CAAC,EAAE;EACnE,MAAM;IAAE6B,SAAS;IAAEC,SAAS;IAAEM,MAAM;IAAEG,KAAK;IAAEE;EAAQ,CAAC,GAAGJ,MAAM;EAE/D,MAAM+B,WAAW,GAAG;IAClBC,GAAG,EAAEvC,SAAS,GAAGzD,aAAa;IAC9B,CAACT,WAAW,CAAC0G,KAAK,GAAG,OAAO,GAAG,MAAM,GAAGzC,SAAS,GAAGxD,aAAa;IACjEkG,eAAe,EAAEvE,KAAK;IACtByC,OAAO;IACP+B,SAAS,EAAE,CACT;MACEjC,KAAK,EAAEA,KAAK,CAACkC,WAAW,CAAC;QACvBC,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QAClBC,WAAW,EAAE,CAAC,GAAG,GAAGtG,aAAa,EAAE+D,MAAM,GAAG/D,aAAa;MAC3D,CAAC;IACH,CAAC;EAEL,CAAC;EAED,oBAAOH,IAAA,CAACR,QAAQ,CAACK,IAAI;IAAC2B,KAAK,EAAE,CAACoE,MAAM,CAACc,MAAM,EAAER,WAAW;EAAE,CAAE,CAAC;AAC/D;AAEA,MAAMF,YAAY,gBAAGzG,KAAK,CAACoH,IAAI,CAACV,qBAAqB,CAAC;AAEtD,MAAML,MAAM,GAAGhG,UAAU,CAACgH,MAAM,CAAC;EAC/Bf,SAAS,EAAE;IACT,GAAGjG,UAAU,CAACiH,kBAAkB;IAChCC,QAAQ,EAAE;EACZ,CAAC;EACDJ,MAAM,EAAE;IACNvE,KAAK,EAAEhC,aAAa,GAAG,CAAC;IACxBiC,MAAM,EAAEjC,aAAa,GAAG,CAAC;IACzB2F,YAAY,EAAE3F,aAAa;IAC3B2G,QAAQ,EAAE,QAAQ;IAClBC,QAAQ,EAAE;EACZ;AACF,CAAC,CAAC","ignoreList":[]}
@@ -9,15 +9,16 @@ type Props = {
9
9
  style?: StyleProp<ViewStyle>;
10
10
  testID?: string;
11
11
  hitSlop?: Insets;
12
- /** Android only. Ripple color. Defaults to the theme `text` color. */
12
+ /** Android only. */
13
13
  rippleColor?: string;
14
+ /** Android only. */
15
+ rippleContainerBorderRadius?: number;
14
16
  };
15
17
  /**
16
- * Base pressable. Android gets the platform touch ripple (drawn in the
17
- * foreground and clipped to the view's own shape); every other platform gets
18
- * opacity feedback. Kept in one file (not `.ios`/`.android`) so consumers' type
19
- * resolution works without `moduleSuffixes`.
18
+ * Base pressable. Android gets a touch ripple; every other platform gets
19
+ * opacity feedback. Kept in one file (not `.ios`/`.android`) so consumers'
20
+ * type resolution works without `moduleSuffixes`.
20
21
  */
21
- export declare function Button({ children, onPress, onPressIn, onPressOut, disabled, style, testID, hitSlop, rippleColor, }: Props): import("react").JSX.Element;
22
+ export declare function Button({ children, onPress, onPressIn, onPressOut, disabled, style, testID, hitSlop, rippleColor, rippleContainerBorderRadius, }: Props): import("react").JSX.Element;
22
23
  export {};
23
24
  //# sourceMappingURL=Button.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../../src/components/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAIjE,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,SAAS,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,EACrB,QAAQ,EACR,OAAO,EACP,SAAS,EACT,UAAU,EACV,QAAQ,EACR,KAAK,EACL,MAAM,EACN,OAAO,EACP,WAAW,GACZ,EAAE,KAAK,+BAoCP"}
1
+ {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../../src/components/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAIjE,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,SAAS,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB;IACpB,2BAA2B,CAAC,EAAE,MAAM,CAAC;CACtC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,EACrB,QAAQ,EACR,OAAO,EACP,SAAS,EACT,UAAU,EACV,QAAQ,EACR,KAAK,EACL,MAAM,EACN,OAAO,EACP,WAAW,EACX,2BAA2B,GAC5B,EAAE,KAAK,+BAgCP"}
@@ -2,7 +2,8 @@ import React from 'react';
2
2
  import type { PressableProps, StyleProp, ViewStyle } from 'react-native';
3
3
  type Props = Omit<PressableProps, 'style'> & {
4
4
  children: React.ReactNode;
5
- /** Applied to an inner wrapper around `children`, not to the pressable. */
5
+ /** Applied to an inner wrapper around `children`, not to the pressable, so
6
+ * the ripple layer can never take part in the caller's flex layout. */
6
7
  style?: StyleProp<ViewStyle>;
7
8
  /** Ripple color. Default: theme `text`. */
8
9
  rippleColor?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"RippleEffect.d.ts","sourceRoot":"","sources":["../../../../src/components/RippleEffect.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B,OAAO,KAAK,EAGV,cAAc,EACd,SAAS,EACT,SAAS,EACV,MAAM,cAAc,CAAC;AAatB,KAAK,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,GAAG;IAC3C,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,2EAA2E;IAC3E,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAOF,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,WAAW,EACX,aAAmB,EACnB,cAAoB,EACpB,UAAc,EACd,2BAA+B,EAC/B,cAAsB,EACtB,gBAAwB,EACxB,WAAkB,EAClB,QAAgB,EAChB,KAAK,EACL,QAAQ,EACR,SAAS,EACT,UAAU,EACV,GAAG,cAAc,EAClB,EAAE,KAAK,qBA6IP"}
1
+ {"version":3,"file":"RippleEffect.d.ts","sourceRoot":"","sources":["../../../../src/components/RippleEffect.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B,OAAO,KAAK,EAGV,cAAc,EACd,SAAS,EACT,SAAS,EACV,MAAM,cAAc,CAAC;AAatB,KAAK,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,GAAG;IAC3C,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;4EACwE;IACxE,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAgBF,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,WAAW,EACX,aAAmB,EACnB,cAAoB,EACpB,UAAc,EACd,2BAA+B,EAC/B,cAAsB,EACtB,gBAAwB,EACxB,WAAkB,EAClB,QAAgB,EAChB,KAAK,EACL,QAAQ,EACR,SAAS,EACT,UAAU,EACV,GAAG,cAAc,EAClB,EAAE,KAAK,qBA4JP"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyberkaidev/ui",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Components for React Native",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -1,8 +1,8 @@
1
1
  import type { ReactNode } from 'react';
2
- import { Platform, Pressable, TouchableOpacity } from 'react-native';
2
+ import { Platform, TouchableOpacity } from 'react-native';
3
3
  import type { Insets, StyleProp, ViewStyle } from 'react-native';
4
4
 
5
- import { useColors } from '../ThemeProvider';
5
+ import { RippleEffect } from './RippleEffect';
6
6
 
7
7
  type Props = {
8
8
  children: ReactNode;
@@ -13,15 +13,16 @@ type Props = {
13
13
  style?: StyleProp<ViewStyle>;
14
14
  testID?: string;
15
15
  hitSlop?: Insets;
16
- /** Android only. Ripple color. Defaults to the theme `text` color. */
16
+ /** Android only. */
17
17
  rippleColor?: string;
18
+ /** Android only. */
19
+ rippleContainerBorderRadius?: number;
18
20
  };
19
21
 
20
22
  /**
21
- * Base pressable. Android gets the platform touch ripple (drawn in the
22
- * foreground and clipped to the view's own shape); every other platform gets
23
- * opacity feedback. Kept in one file (not `.ios`/`.android`) so consumers' type
24
- * resolution works without `moduleSuffixes`.
23
+ * Base pressable. Android gets a touch ripple; every other platform gets
24
+ * opacity feedback. Kept in one file (not `.ios`/`.android`) so consumers'
25
+ * type resolution works without `moduleSuffixes`.
25
26
  */
26
27
  export function Button({
27
28
  children,
@@ -33,12 +34,11 @@ export function Button({
33
34
  testID,
34
35
  hitSlop,
35
36
  rippleColor,
37
+ rippleContainerBorderRadius,
36
38
  }: Props) {
37
- const colors = useColors();
38
-
39
39
  if (Platform.OS === 'android') {
40
40
  return (
41
- <Pressable
41
+ <RippleEffect
42
42
  testID={testID}
43
43
  style={style}
44
44
  disabled={disabled}
@@ -46,13 +46,11 @@ export function Button({
46
46
  onPressIn={onPressIn}
47
47
  onPressOut={onPressOut}
48
48
  hitSlop={hitSlop}
49
- android_ripple={{
50
- color: rippleColor ?? colors.text,
51
- foreground: true,
52
- }}
49
+ rippleColor={rippleColor}
50
+ rippleContainerBorderRadius={rippleContainerBorderRadius}
53
51
  >
54
52
  {children}
55
- </Pressable>
53
+ </RippleEffect>
56
54
  );
57
55
  }
58
56
 
@@ -28,7 +28,8 @@ type RippleItemType = {
28
28
 
29
29
  type Props = Omit<PressableProps, 'style'> & {
30
30
  children: React.ReactNode;
31
- /** Applied to an inner wrapper around `children`, not to the pressable. */
31
+ /** Applied to an inner wrapper around `children`, not to the pressable, so
32
+ * the ripple layer can never take part in the caller's flex layout. */
32
33
  style?: StyleProp<ViewStyle>;
33
34
  /** Ripple color. Default: theme `text`. */
34
35
  rippleColor?: string;
@@ -46,6 +47,15 @@ const RELEASE_GROW_DURATION = 150;
46
47
  const RELEASE_FADE_DURATION = 250;
47
48
  const PRESS_FADE_IN_DURATION = 75;
48
49
 
50
+ // The ripple animations run on the JS driver on purpose. On the New
51
+ // Architecture a native-driven animation started in the same tick the
52
+ // `Animated.View` is created has no native view to bind to yet, so it never
53
+ // plays — which is why the ripple showed on RN 0.83 but not on 0.86+.
54
+ const USE_NATIVE_DRIVER = false;
55
+
56
+ const toFinite = (value: number, fallback: number) =>
57
+ Number.isFinite(value) ? value : fallback;
58
+
49
59
  /** Wraps a child and paints a touch ripple at the press location. */
50
60
  export function RippleEffect({
51
61
  children,
@@ -88,19 +98,33 @@ export function RippleEffect({
88
98
  const w2 = 0.5 * layout.width;
89
99
  const h2 = 0.5 * layout.height;
90
100
 
91
- // Fall back to the center when the gesture carries no coordinates.
92
- const { locationX, locationY } =
93
- rippleCentered || !event?.nativeEvent
94
- ? { locationX: w2, locationY: h2 }
95
- : event.nativeEvent;
101
+ // Fall back to the center when the gesture carries no coordinates, and
102
+ // clamp to the pressable's box — some setups report press coordinates
103
+ // relative to the wrong ancestor, which would push the circle off-screen
104
+ // where `overflow: 'hidden'` clips it away entirely.
105
+ const centered = rippleCentered || !event?.nativeEvent;
106
+ const clampX = (value: number) =>
107
+ layout.width > 0 ? Math.min(Math.max(value, 0), layout.width) : value;
108
+ const clampY = (value: number) =>
109
+ layout.height > 0 ? Math.min(Math.max(value, 0), layout.height) : value;
110
+ const locationX = centered
111
+ ? w2
112
+ : clampX(toFinite(event.nativeEvent.locationX, w2));
113
+ const locationY = centered
114
+ ? h2
115
+ : clampY(toFinite(event.nativeEvent.locationY, h2));
96
116
 
97
117
  const offsetX = Math.abs(w2 - locationX);
98
118
  const offsetY = Math.abs(h2 - locationY);
99
119
 
100
- const radius =
120
+ const computedRadius =
101
121
  rippleSize > 0
102
122
  ? 0.5 * rippleSize
103
123
  : Math.sqrt((w2 + offsetX) ** 2 + (h2 + offsetY) ** 2);
124
+ const radius =
125
+ Number.isFinite(computedRadius) && computedRadius > 0
126
+ ? computedRadius
127
+ : Math.max(w2, h2, CIRCLE_RADIUS);
104
128
 
105
129
  const ripple: RippleItemType = {
106
130
  unique: uniqueRef.current++,
@@ -114,10 +138,19 @@ export function RippleEffect({
114
138
  ripplesRef.current.set(ripple.unique, ripple);
115
139
  activeRippleRef.current = ripple.unique;
116
140
 
117
- // The entrance animation is kicked off from `RippleCircle`'s mount effect,
118
- // not here: on the New Architecture, starting a native-driven animation on
119
- // an `Animated.Value` before its `Animated.View` is mounted leaves the
120
- // native driver with no view to attach to, so the ripple never shows.
141
+ Animated.timing(ripple.scale, {
142
+ toValue: 1,
143
+ duration: rippleDuration,
144
+ easing: Easing.out(Easing.ease),
145
+ useNativeDriver: USE_NATIVE_DRIVER,
146
+ }).start();
147
+
148
+ Animated.timing(ripple.opacity, {
149
+ toValue: rippleOpacity,
150
+ duration: Math.min(rippleDuration, PRESS_FADE_IN_DURATION),
151
+ useNativeDriver: USE_NATIVE_DRIVER,
152
+ }).start();
153
+
121
154
  setRippleIds((current) => current.concat(ripple.unique));
122
155
  },
123
156
  [
@@ -125,6 +158,8 @@ export function RippleEffect({
125
158
  layout.height,
126
159
  onPressIn,
127
160
  rippleCentered,
161
+ rippleDuration,
162
+ rippleOpacity,
128
163
  rippleSequential,
129
164
  rippleSize,
130
165
  ]
@@ -157,12 +192,12 @@ export function RippleEffect({
157
192
  Animated.timing(ripple.scale, {
158
193
  toValue: 1,
159
194
  duration: RELEASE_GROW_DURATION,
160
- useNativeDriver: true,
195
+ useNativeDriver: USE_NATIVE_DRIVER,
161
196
  }),
162
197
  Animated.timing(ripple.opacity, {
163
198
  toValue: 0,
164
199
  duration: RELEASE_FADE_DURATION,
165
- useNativeDriver: true,
200
+ useNativeDriver: USE_NATIVE_DRIVER,
166
201
  }),
167
202
  ]).start(removeRipple);
168
203
  },
@@ -177,11 +212,9 @@ export function RippleEffect({
177
212
  onPressIn={handlePressIn}
178
213
  onPressOut={handlePressOut}
179
214
  >
180
- {/* The caller's `style` (often a flex row with `justifyContent`) is
181
- applied here, wrapping only the real children — so the absolutely
182
- positioned ripple layer below can never take part in that layout. */}
183
215
  <View style={style}>{children}</View>
184
216
  <View
217
+ collapsable={false}
185
218
  pointerEvents="none"
186
219
  style={[
187
220
  styles.container,
@@ -191,15 +224,7 @@ export function RippleEffect({
191
224
  {rippleIds.map((id) => {
192
225
  const ripple = ripplesRef.current.get(id);
193
226
  if (!ripple) return null;
194
- return (
195
- <RippleCircle
196
- key={id}
197
- ripple={ripple}
198
- color={color}
199
- duration={rippleDuration}
200
- toOpacity={rippleOpacity}
201
- />
202
- );
227
+ return <RippleCircle key={id} ripple={ripple} color={color} />;
203
228
  })}
204
229
  </View>
205
230
  </Pressable>
@@ -209,35 +234,11 @@ export function RippleEffect({
209
234
  type RippleCircleProps = {
210
235
  ripple: RippleItemType;
211
236
  color: string;
212
- duration: number;
213
- toOpacity: number;
214
237
  };
215
238
 
216
- function RippleCircleComponent({
217
- ripple,
218
- color,
219
- duration,
220
- toOpacity,
221
- }: RippleCircleProps) {
239
+ function RippleCircleComponent({ ripple, color }: RippleCircleProps) {
222
240
  const { locationX, locationY, radius, scale, opacity } = ripple;
223
241
 
224
- React.useEffect(() => {
225
- Animated.timing(scale, {
226
- toValue: 1,
227
- duration,
228
- easing: Easing.out(Easing.ease),
229
- useNativeDriver: true,
230
- }).start();
231
-
232
- Animated.timing(opacity, {
233
- toValue: toOpacity,
234
- duration: Math.min(duration, PRESS_FADE_IN_DURATION),
235
- useNativeDriver: true,
236
- }).start();
237
- // Entrance runs exactly once, when the ripple view mounts.
238
- // eslint-disable-next-line react-hooks/exhaustive-deps
239
- }, []);
240
-
241
242
  const rippleStyle = {
242
243
  top: locationY - CIRCLE_RADIUS,
243
244
  [I18nManager.isRTL ? 'right' : 'left']: locationX - CIRCLE_RADIUS,