react-native-quick-preview 1.0.4 → 1.0.5
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 +21 -21
- package/dist/index.d.mts +3 -5
- package/dist/index.d.ts +3 -5
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +22 -5
- package/src/{QuickLook.tsx → QuickPreview.tsx} +7 -7
- package/src/{QuickLookProperties.ts → QuickPreviewProperties.ts} +1 -3
- package/src/index.ts +2 -2
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# react-native-
|
|
1
|
+
# react-native-quick-preview
|
|
2
2
|
|
|
3
3
|
A beautiful, customizable quick preview modal component for React Native.
|
|
4
4
|
Think **Gorhom Bottom Sheet**, but for quick previews.
|
|
@@ -27,9 +27,9 @@ Perfect for:
|
|
|
27
27
|
## 📦 Installation
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
|
-
npm install react-native-
|
|
30
|
+
npm install react-native-quick-preview
|
|
31
31
|
# or
|
|
32
|
-
yarn add react-native-
|
|
32
|
+
yarn add react-native-quick-preview
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
---
|
|
@@ -39,7 +39,7 @@ yarn add react-native-quicklook
|
|
|
39
39
|
```tsx
|
|
40
40
|
import React, { useState } from 'react';
|
|
41
41
|
import { View, Text, TouchableOpacity } from 'react-native';
|
|
42
|
-
import {
|
|
42
|
+
import { QuickPreview } from 'react-native-quick-preview';
|
|
43
43
|
|
|
44
44
|
export default function App() {
|
|
45
45
|
const [visible, setVisible] = useState(false);
|
|
@@ -50,12 +50,12 @@ export default function App() {
|
|
|
50
50
|
<Text>Show Quick Look</Text>
|
|
51
51
|
</TouchableOpacity>
|
|
52
52
|
|
|
53
|
-
<
|
|
53
|
+
<QuickPreview visible={visible} onClose={() => setVisible(false)}>
|
|
54
54
|
<View style={{ backgroundColor: '#fff', padding: 20 }}>
|
|
55
55
|
<Text style={{ fontSize: 18, fontWeight: 'bold' }}>Quick Preview Content</Text>
|
|
56
56
|
<Text style={{ marginTop: 10 }}>Any custom content goes here.</Text>
|
|
57
57
|
</View>
|
|
58
|
-
</
|
|
58
|
+
</QuickPreview>
|
|
59
59
|
</View>
|
|
60
60
|
);
|
|
61
61
|
}
|
|
@@ -67,33 +67,33 @@ export default function App() {
|
|
|
67
67
|
|
|
68
68
|
### 🛍️ E-commerce Product Quick View
|
|
69
69
|
```tsx
|
|
70
|
-
<
|
|
70
|
+
<QuickPreview visible={visible} onClose={onClose} onPressCard={onViewDetails}>
|
|
71
71
|
<View>
|
|
72
72
|
<Image source={{ uri: product.image }} style={{ width: '100%', height: 200 }} />
|
|
73
73
|
<Text>{product.name}</Text>
|
|
74
74
|
<Text>{product.price}</Text>
|
|
75
75
|
</View>
|
|
76
|
-
</
|
|
76
|
+
</QuickPreview>
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
### 📰 Article Preview
|
|
80
80
|
```tsx
|
|
81
|
-
<
|
|
81
|
+
<QuickPreview visible={visible} onClose={onClose} theme="dark">
|
|
82
82
|
<View style={{ backgroundColor: '#1a1a1a' }}>
|
|
83
83
|
<Image source={{ uri: article.coverImage }} style={{ width: '100%', height: 200 }} />
|
|
84
84
|
<Text style={{ color: '#fff' }}>{article.title}</Text>
|
|
85
85
|
<Text style={{ color: '#ccc' }}>{article.excerpt}</Text>
|
|
86
86
|
</View>
|
|
87
|
-
</
|
|
87
|
+
</QuickPreview>
|
|
88
88
|
```
|
|
89
89
|
|
|
90
90
|
### ✈️ Travel Destination Peek
|
|
91
91
|
```tsx
|
|
92
|
-
<
|
|
92
|
+
<QuickPreview visible={visible} onClose={onClose}>
|
|
93
93
|
<Image source={{ uri: destination.image }} style={{ width: '100%', height: 200 }} />
|
|
94
94
|
<Text>{destination.title}</Text>
|
|
95
95
|
<Text>From ${destination.price}</Text>
|
|
96
|
-
</
|
|
96
|
+
</QuickPreview>
|
|
97
97
|
```
|
|
98
98
|
|
|
99
99
|
---
|
|
@@ -119,7 +119,7 @@ export default function App() {
|
|
|
119
119
|
| `avoidKeyboard` | `boolean` | `false` | Avoid keyboard overlap |
|
|
120
120
|
| `renderBackdrop` | `(opacity) => ReactNode` | `undefined` | Custom backdrop |
|
|
121
121
|
| `onBackdropPress` | `() => void` | `undefined` | Backdrop press handler |
|
|
122
|
-
| `testID` | `string` | `'
|
|
122
|
+
| `testID` | `string` | `'quickpreview'` | Test identifier |
|
|
123
123
|
| `accessibilityLabel` | `string` | `'Quick look'` | A11y label |
|
|
124
124
|
| `stylesOverride` | `object` | `{}` | Override default styles |
|
|
125
125
|
|
|
@@ -129,7 +129,7 @@ export default function App() {
|
|
|
129
129
|
|
|
130
130
|
### Custom Backdrop
|
|
131
131
|
```tsx
|
|
132
|
-
<
|
|
132
|
+
<QuickPreview
|
|
133
133
|
visible={visible}
|
|
134
134
|
onClose={onClose}
|
|
135
135
|
renderBackdrop={(opacity) => (
|
|
@@ -137,12 +137,12 @@ export default function App() {
|
|
|
137
137
|
)}
|
|
138
138
|
>
|
|
139
139
|
{/* content */}
|
|
140
|
-
</
|
|
140
|
+
</QuickPreview>
|
|
141
141
|
```
|
|
142
142
|
|
|
143
143
|
### Custom Styles
|
|
144
144
|
```tsx
|
|
145
|
-
<
|
|
145
|
+
<QuickPreview
|
|
146
146
|
visible={visible}
|
|
147
147
|
onClose={onClose}
|
|
148
148
|
stylesOverride={{
|
|
@@ -151,7 +151,7 @@ export default function App() {
|
|
|
151
151
|
}}
|
|
152
152
|
>
|
|
153
153
|
{/* content */}
|
|
154
|
-
</
|
|
154
|
+
</QuickPreview>
|
|
155
155
|
```
|
|
156
156
|
|
|
157
157
|
---
|
|
@@ -161,12 +161,12 @@ export default function App() {
|
|
|
161
161
|
```tsx
|
|
162
162
|
import { render, fireEvent } from '@testing-library/react-native';
|
|
163
163
|
|
|
164
|
-
test('
|
|
164
|
+
test('QuickPreview closes on backdrop press', () => {
|
|
165
165
|
const onClose = jest.fn();
|
|
166
166
|
const { getByTestId } = render(
|
|
167
|
-
<
|
|
167
|
+
<QuickPreview visible={true} onClose={onClose} testID="quickpreview">
|
|
168
168
|
<Text>Test content</Text>
|
|
169
|
-
</
|
|
169
|
+
</QuickPreview>
|
|
170
170
|
);
|
|
171
171
|
|
|
172
172
|
fireEvent.press(getByTestId('ql-backdrop'));
|
|
@@ -185,4 +185,4 @@ test('QuickLook closes on backdrop press', () => {
|
|
|
185
185
|
|
|
186
186
|
## 📄 License
|
|
187
187
|
|
|
188
|
-
MIT ©
|
|
188
|
+
MIT © Oliver Lindblad
|
package/dist/index.d.mts
CHANGED
|
@@ -3,14 +3,12 @@ import { Animated } from 'react-native';
|
|
|
3
3
|
|
|
4
4
|
type ThemeMode = 'light' | 'dark';
|
|
5
5
|
type CloseReason = 'programmatic' | 'backdrop' | 'backButton' | 'swipe';
|
|
6
|
-
interface
|
|
6
|
+
interface QuickPreviewProps {
|
|
7
7
|
visible: boolean;
|
|
8
8
|
onClose: () => void;
|
|
9
9
|
/** Lifecycle hooks (great for haptics/analytics) */
|
|
10
10
|
onOpen?: () => void;
|
|
11
11
|
onClosed?: (reason: CloseReason) => void;
|
|
12
|
-
/** Optional: press whole card (prefer explicit CTAs as well) */
|
|
13
|
-
onPressCard?: () => void;
|
|
14
12
|
theme?: ThemeMode;
|
|
15
13
|
backdropOpacity?: number;
|
|
16
14
|
animationDuration?: number;
|
|
@@ -37,6 +35,6 @@ interface QuickLookProps {
|
|
|
37
35
|
};
|
|
38
36
|
}
|
|
39
37
|
|
|
40
|
-
declare const
|
|
38
|
+
declare const QuickPreview: React.FC<QuickPreviewProps>;
|
|
41
39
|
|
|
42
|
-
export { type CloseReason,
|
|
40
|
+
export { type CloseReason, QuickPreview, type QuickPreviewProps, type ThemeMode };
|
package/dist/index.d.ts
CHANGED
|
@@ -3,14 +3,12 @@ import { Animated } from 'react-native';
|
|
|
3
3
|
|
|
4
4
|
type ThemeMode = 'light' | 'dark';
|
|
5
5
|
type CloseReason = 'programmatic' | 'backdrop' | 'backButton' | 'swipe';
|
|
6
|
-
interface
|
|
6
|
+
interface QuickPreviewProps {
|
|
7
7
|
visible: boolean;
|
|
8
8
|
onClose: () => void;
|
|
9
9
|
/** Lifecycle hooks (great for haptics/analytics) */
|
|
10
10
|
onOpen?: () => void;
|
|
11
11
|
onClosed?: (reason: CloseReason) => void;
|
|
12
|
-
/** Optional: press whole card (prefer explicit CTAs as well) */
|
|
13
|
-
onPressCard?: () => void;
|
|
14
12
|
theme?: ThemeMode;
|
|
15
13
|
backdropOpacity?: number;
|
|
16
14
|
animationDuration?: number;
|
|
@@ -37,6 +35,6 @@ interface QuickLookProps {
|
|
|
37
35
|
};
|
|
38
36
|
}
|
|
39
37
|
|
|
40
|
-
declare const
|
|
38
|
+
declare const QuickPreview: React.FC<QuickPreviewProps>;
|
|
41
39
|
|
|
42
|
-
export { type CloseReason,
|
|
40
|
+
export { type CloseReason, QuickPreview, type QuickPreviewProps, type ThemeMode };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var react=require('react'),reactNative=require('react-native'),jsxRuntime=require('react/jsx-runtime');var K=Object.defineProperty,U=Object.defineProperties;var X=Object.getOwnPropertyDescriptors;var
|
|
1
|
+
'use strict';var react=require('react'),reactNative=require('react-native'),jsxRuntime=require('react/jsx-runtime');var K=Object.defineProperty,U=Object.defineProperties;var X=Object.getOwnPropertyDescriptors;var x=Object.getOwnPropertySymbols;var Z=Object.prototype.hasOwnProperty,B=Object.prototype.propertyIsEnumerable;var I=(r,e,i)=>e in r?K(r,e,{enumerable:true,configurable:true,writable:true,value:i}):r[e]=i,S=(r,e)=>{for(var i in e||(e={}))Z.call(e,i)&&I(r,i,e[i]);if(x)for(var i of x(e))B.call(e,i)&&I(r,i,e[i]);return r},q=(r,e)=>U(r,X(e));var {width:ne,height:_}=reactNative.Dimensions.get("window"),se="dialog",ue=(r,e)=>`rgba(0,0,0,${e!=null?e:r==="dark"?.8:.5})`,oe=({visible:r,onClose:e,onOpen:i,onClosed:d,theme:g="light",backdropOpacity:R,animationDuration:f=220,closeOnBackdropPress:j=true,closeOnBackButton:z=true,enableSwipeToClose:v=true,swipeThreshold:M=80,unmountOnExit:k=true,avoidKeyboard:y=false,children:E,renderBackdrop:P,onBackdropPress:h,testID:T="quickpreview",accessibilityLabel:Y="Quick preview",stylesOverride:b={}})=>{let[o,D]=react.useState(false),[$,A]=react.useState(0),n=react.useRef(new reactNative.Animated.Value(0)).current,s=react.useRef(new reactNative.Animated.Value(.96)).current,u=react.useRef(new reactNative.Animated.Value(0)).current,G=react.useMemo(()=>ue(g,R),[g,R]),c=react.useRef("programmatic");react.useEffect(()=>{r&&!o?(D(true),i==null||i(),requestAnimationFrame(()=>{reactNative.Animated.parallel([reactNative.Animated.timing(n,{toValue:1,duration:f,useNativeDriver:true}),reactNative.Animated.spring(s,{toValue:1,useNativeDriver:true,friction:7,tension:80})]).start();})):!r&&o&&reactNative.Animated.parallel([reactNative.Animated.timing(n,{toValue:0,duration:f,useNativeDriver:true}),reactNative.Animated.timing(s,{toValue:.96,duration:f,useNativeDriver:true})]).start(()=>{u.setValue(0),d==null||d(c.current),c.current="programmatic",k&&D(false);});},[r,o,f,n,s,u,k,i,d]),react.useEffect(()=>{if(!y)return;let m=reactNative.Keyboard.addListener("keyboardDidShow",p=>{var N,Q;return A((Q=(N=p.endCoordinates)==null?void 0:N.height)!=null?Q:0)}),a=reactNative.Keyboard.addListener("keyboardDidHide",()=>A(0));return ()=>{m.remove(),a.remove();}},[y]);let J=react.useRef(reactNative.PanResponder.create({onMoveShouldSetPanResponder:(m,a)=>v&&Math.abs(a.dy)>Math.abs(a.dx)&&Math.abs(a.dy)>5,onPanResponderMove:(m,a)=>{if(v&&a.dy>0){u.setValue(a.dy);let p=Math.min(1,a.dy/(M*2));n.setValue(1-p*.25),s.setValue(1-p*.03);}},onPanResponderRelease:(m,a)=>{v&&(a.dy>M?(c.current="swipe",reactNative.Animated.parallel([reactNative.Animated.timing(u,{toValue:_*.35,duration:180,useNativeDriver:true}),reactNative.Animated.timing(n,{toValue:0,duration:180,useNativeDriver:true})]).start(()=>e==null?void 0:e())):reactNative.Animated.parallel([reactNative.Animated.spring(u,{toValue:0,useNativeDriver:true}),reactNative.Animated.spring(n,{toValue:1,useNativeDriver:true}),reactNative.Animated.spring(s,{toValue:1,useNativeDriver:true})]).start());}})).current;return !o&&!r?null:jsxRuntime.jsx(reactNative.Modal,{transparent:true,visible:o||r,animationType:"none",onRequestClose:()=>{z&&(c.current="backButton",e==null||e());},presentationStyle:"overFullScreen",statusBarTranslucent:reactNative.Platform.OS==="android",children:jsxRuntime.jsxs(reactNative.Animated.View,{style:[V.overlay,{backgroundColor:G,opacity:n},b.overlay],accessibilityViewIsModal:true,children:[P?P(n):jsxRuntime.jsx(reactNative.Pressable,{onPress:()=>{h==null||h(),j&&(c.current="backdrop",e==null||e());},style:reactNative.StyleSheet.absoluteFill,android_disableSound:true,accessibilityRole:"button",accessibilityLabel:"Close quick preview",testID:"qp-backdrop"}),jsxRuntime.jsx(reactNative.View,{style:[V.centerWrap,{paddingBottom:Math.max(16,y?$:16)},b.centerWrap],pointerEvents:"box-none",children:jsxRuntime.jsx(reactNative.Animated.View,q(S({},v?J.panHandlers:{}),{style:[V.container,{transform:[{scale:s},{translateY:u}]},b.container],testID:T,accessibilityRole:se,accessibilityViewIsModal:true,accessibilityLabel:Y,children:E}))})]})})},V=reactNative.StyleSheet.create({overlay:{flex:1,justifyContent:"center",alignItems:"center"},centerWrap:{flex:1,width:"100%",justifyContent:"center",alignItems:"center",paddingHorizontal:16},container:{width:Math.min(ne*.92,560),maxHeight:_*.82,borderRadius:16,overflow:"hidden",elevation:8,shadowColor:"#000",shadowOpacity:.2,shadowRadius:12,shadowOffset:{width:0,height:6},backgroundColor:"#fff"}});exports.QuickPreview=oe;//# sourceMappingURL=index.js.map
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/QuickLook.tsx"],"names":["screenWidth","screenHeight","Dimensions","dialogA11yRole","overlayColor","theme","custom","QuickLook","visible","onClose","onOpen","onClosed","backdropOpacity","animationDuration","closeOnBackdropPress","closeOnBackButton","enableSwipeToClose","swipeThreshold","unmountOnExit","avoidKeyboard","children","renderBackdrop","onBackdropPress","testID","accessibilityLabel","stylesOverride","mounted","setMounted","useState","kb","setKb","fade","useRef","Animated","scale","translateY","baseOverlay","useMemo","closeReasonRef","useEffect","show","Keyboard","e","_a","_b","hide","panResponder","PanResponder","_evt","g","jsx","Modal","Platform","jsxs","styles","Pressable","StyleSheet","View","__spreadProps","__spreadValues"],"mappings":"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","file":"index.js","sourcesContent":["// src/QuickLook.tsx\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n View,\n StyleSheet,\n Modal,\n Dimensions,\n Animated,\n Platform,\n Pressable,\n PanResponder,\n Keyboard,\n} from 'react-native';\nimport type { AccessibilityRole } from 'react-native';\nimport type { CloseReason, QuickLookProps, ThemeMode } from './QuickLookProperties';\n\nconst { width: screenWidth, height: screenHeight } = Dimensions.get('window');\n\n// TS-safe across RN versions where \"dialog\" may not exist in AccessibilityRole\nconst dialogA11yRole = 'dialog' as unknown as AccessibilityRole;\n\nconst overlayColor = (theme: ThemeMode, custom?: number) =>\n `rgba(0,0,0,${custom ?? (theme === 'dark' ? 0.8 : 0.5)})`;\n\nexport const QuickLook: React.FC<QuickLookProps> = ({\n visible,\n onClose,\n onOpen,\n onClosed,\n theme = 'light',\n backdropOpacity,\n animationDuration = 220,\n closeOnBackdropPress = true,\n closeOnBackButton = true,\n enableSwipeToClose = true,\n swipeThreshold = 80,\n unmountOnExit = true,\n avoidKeyboard = false,\n children,\n renderBackdrop,\n onBackdropPress,\n testID = 'quicklook',\n accessibilityLabel = 'Quick look',\n stylesOverride = {},\n}) => {\n const [mounted, setMounted] = useState(false);\n const [kb, setKb] = useState(0); // keyboard height\n\n const fade = useRef(new Animated.Value(0)).current;\n const scale = useRef(new Animated.Value(0.96)).current;\n const translateY = useRef(new Animated.Value(0)).current;\n\n const baseOverlay = useMemo(() => overlayColor(theme, backdropOpacity), [theme, backdropOpacity]);\n\n // Track why we closed so we can report it to onClosed\n const closeReasonRef = useRef<CloseReason>('programmatic');\n\n // Mount/unmount with animation\n useEffect(() => {\n if (visible && !mounted) {\n setMounted(true);\n onOpen?.(); // great place to trigger optional haptics in-app\n\n requestAnimationFrame(() => {\n Animated.parallel([\n Animated.timing(fade, { toValue: 1, duration: animationDuration, useNativeDriver: true }),\n Animated.spring(scale, { toValue: 1, useNativeDriver: true, friction: 7, tension: 80 }),\n ]).start();\n });\n } else if (!visible && mounted) {\n Animated.parallel([\n Animated.timing(fade, { toValue: 0, duration: animationDuration, useNativeDriver: true }),\n Animated.timing(scale, { toValue: 0.96, duration: animationDuration, useNativeDriver: true }),\n ]).start(() => {\n translateY.setValue(0);\n onClosed?.(closeReasonRef.current);\n closeReasonRef.current = 'programmatic';\n if (unmountOnExit) setMounted(false);\n });\n }\n }, [visible, mounted, animationDuration, fade, scale, translateY, unmountOnExit, onOpen, onClosed]);\n\n // Keyboard avoidance (optional)\n useEffect(() => {\n if (!avoidKeyboard) return;\n const show = Keyboard.addListener('keyboardDidShow', (e) => setKb(e.endCoordinates?.height ?? 0));\n const hide = Keyboard.addListener('keyboardDidHide', () => setKb(0));\n return () => {\n show.remove();\n hide.remove();\n };\n }, [avoidKeyboard]);\n\n // Swipe to close\n const panResponder = useRef(\n PanResponder.create({\n onMoveShouldSetPanResponder: (_evt, g) =>\n enableSwipeToClose && Math.abs(g.dy) > Math.abs(g.dx) && Math.abs(g.dy) > 5,\n onPanResponderMove: (_evt, g) => {\n if (!enableSwipeToClose) return;\n if (g.dy > 0) {\n translateY.setValue(g.dy);\n const p = Math.min(1, g.dy / (swipeThreshold * 2));\n fade.setValue(1 - p * 0.25);\n scale.setValue(1 - p * 0.03);\n }\n },\n onPanResponderRelease: (_evt, g) => {\n if (!enableSwipeToClose) return;\n if (g.dy > swipeThreshold) {\n closeReasonRef.current = 'swipe';\n Animated.parallel([\n Animated.timing(translateY, { toValue: screenHeight * 0.35, duration: 180, useNativeDriver: true }),\n Animated.timing(fade, { toValue: 0, duration: 180, useNativeDriver: true }),\n ]).start(() => onClose?.());\n } else {\n Animated.parallel([\n Animated.spring(translateY, { toValue: 0, useNativeDriver: true }),\n Animated.spring(fade, { toValue: 1, useNativeDriver: true }),\n Animated.spring(scale, { toValue: 1, useNativeDriver: true }),\n ]).start();\n }\n },\n })\n ).current;\n\n if (!mounted && !visible) return null;\n\n return (\n <Modal\n transparent\n visible={mounted || visible}\n animationType=\"none\"\n onRequestClose={() => {\n if (closeOnBackButton) {\n closeReasonRef.current = 'backButton';\n onClose?.();\n }\n }}\n presentationStyle=\"overFullScreen\"\n statusBarTranslucent={Platform.OS === 'android'}\n >\n {/* Backdrop */}\n <Animated.View\n style={[\n styles.overlay,\n { backgroundColor: baseOverlay, opacity: fade },\n stylesOverride.overlay,\n ]}\n accessibilityViewIsModal\n >\n {renderBackdrop ? (\n // If you provide a custom backdrop, you control its hit area/closing\n renderBackdrop(fade as unknown as Animated.AnimatedInterpolation<number>)\n ) : (\n <Pressable\n onPress={() => {\n onBackdropPress?.();\n if (closeOnBackdropPress) {\n closeReasonRef.current = 'backdrop';\n onClose?.();\n }\n }}\n style={StyleSheet.absoluteFill}\n android_disableSound\n accessibilityRole=\"button\"\n accessibilityLabel=\"Close quick look\"\n testID=\"ql-backdrop\"\n />\n )}\n\n {/* Centered card */}\n <View\n style={[\n styles.centerWrap,\n { paddingBottom: Math.max(16, avoidKeyboard ? kb : 16) },\n stylesOverride.centerWrap,\n ]}\n pointerEvents=\"box-none\"\n >\n <Animated.View\n {...(enableSwipeToClose ? panResponder.panHandlers : {})}\n style={[\n styles.container,\n { transform: [{ scale }, { translateY }] },\n stylesOverride.container,\n ]}\n testID={testID}\n accessibilityRole={dialogA11yRole}\n accessibilityViewIsModal\n accessibilityLabel={accessibilityLabel}\n >\n {children}\n </Animated.View>\n </View>\n </Animated.View>\n </Modal>\n );\n};\n\nconst styles = StyleSheet.create({\n overlay: { flex: 1, justifyContent: 'center', alignItems: 'center' },\n centerWrap: {\n flex: 1,\n width: '100%',\n justifyContent: 'center',\n alignItems: 'center',\n paddingHorizontal: 16,\n },\n container: {\n width: Math.min(screenWidth * 0.92, 560),\n maxHeight: screenHeight * 0.82,\n borderRadius: 16,\n overflow: 'hidden',\n elevation: 8,\n shadowColor: '#000',\n shadowOpacity: 0.2,\n shadowRadius: 12,\n shadowOffset: { width: 0, height: 6 },\n backgroundColor: '#fff',\n },\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/QuickPreview.tsx"],"names":["screenWidth","screenHeight","Dimensions","dialogA11yRole","overlayColor","theme","custom","QuickPreview","visible","onClose","onOpen","onClosed","backdropOpacity","animationDuration","closeOnBackdropPress","closeOnBackButton","enableSwipeToClose","swipeThreshold","unmountOnExit","avoidKeyboard","children","renderBackdrop","onBackdropPress","testID","accessibilityLabel","stylesOverride","mounted","setMounted","useState","kb","setKb","fade","useRef","Animated","scale","translateY","baseOverlay","useMemo","closeReasonRef","useEffect","show","Keyboard","e","_a","_b","hide","panResponder","PanResponder","_evt","g","jsx","Modal","Platform","jsxs","styles","Pressable","StyleSheet","View","__spreadProps","__spreadValues"],"mappings":"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","file":"index.js","sourcesContent":["// src/QuickPreview.tsx\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n View,\n StyleSheet,\n Modal,\n Dimensions,\n Animated,\n Platform,\n Pressable,\n PanResponder,\n Keyboard,\n} from 'react-native';\nimport type { AccessibilityRole } from 'react-native';\nimport type { CloseReason, QuickPreviewProps, ThemeMode } from './QuickPreviewProperties';\n\nconst { width: screenWidth, height: screenHeight } = Dimensions.get('window');\n\n// TS-safe across RN versions where \"dialog\" may not exist in AccessibilityRole\nconst dialogA11yRole = 'dialog' as unknown as AccessibilityRole;\n\nconst overlayColor = (theme: ThemeMode, custom?: number) =>\n `rgba(0,0,0,${custom ?? (theme === 'dark' ? 0.8 : 0.5)})`;\n\nexport const QuickPreview: React.FC<QuickPreviewProps> = ({\n visible,\n onClose,\n onOpen,\n onClosed,\n theme = 'light',\n backdropOpacity,\n animationDuration = 220,\n closeOnBackdropPress = true,\n closeOnBackButton = true,\n enableSwipeToClose = true,\n swipeThreshold = 80,\n unmountOnExit = true,\n avoidKeyboard = false,\n children,\n renderBackdrop,\n onBackdropPress,\n testID = 'quickpreview',\n accessibilityLabel = 'Quick preview',\n stylesOverride = {},\n}) => {\n const [mounted, setMounted] = useState(false);\n const [kb, setKb] = useState(0); // keyboard height\n\n const fade = useRef(new Animated.Value(0)).current;\n const scale = useRef(new Animated.Value(0.96)).current;\n const translateY = useRef(new Animated.Value(0)).current;\n\n const baseOverlay = useMemo(() => overlayColor(theme, backdropOpacity), [theme, backdropOpacity]);\n\n // Track why we closed so we can report it to onClosed\n const closeReasonRef = useRef<CloseReason>('programmatic');\n\n // Mount/unmount with animation\n useEffect(() => {\n if (visible && !mounted) {\n setMounted(true);\n onOpen?.(); // great place to trigger optional haptics in-app\n\n requestAnimationFrame(() => {\n Animated.parallel([\n Animated.timing(fade, { toValue: 1, duration: animationDuration, useNativeDriver: true }),\n Animated.spring(scale, { toValue: 1, useNativeDriver: true, friction: 7, tension: 80 }),\n ]).start();\n });\n } else if (!visible && mounted) {\n Animated.parallel([\n Animated.timing(fade, { toValue: 0, duration: animationDuration, useNativeDriver: true }),\n Animated.timing(scale, { toValue: 0.96, duration: animationDuration, useNativeDriver: true }),\n ]).start(() => {\n translateY.setValue(0);\n onClosed?.(closeReasonRef.current);\n closeReasonRef.current = 'programmatic';\n if (unmountOnExit) setMounted(false);\n });\n }\n }, [visible, mounted, animationDuration, fade, scale, translateY, unmountOnExit, onOpen, onClosed]);\n\n // Keyboard avoidance (optional)\n useEffect(() => {\n if (!avoidKeyboard) return;\n const show = Keyboard.addListener('keyboardDidShow', (e) => setKb(e.endCoordinates?.height ?? 0));\n const hide = Keyboard.addListener('keyboardDidHide', () => setKb(0));\n return () => {\n show.remove();\n hide.remove();\n };\n }, [avoidKeyboard]);\n\n // Swipe to close\n const panResponder = useRef(\n PanResponder.create({\n onMoveShouldSetPanResponder: (_evt, g) =>\n enableSwipeToClose && Math.abs(g.dy) > Math.abs(g.dx) && Math.abs(g.dy) > 5,\n onPanResponderMove: (_evt, g) => {\n if (!enableSwipeToClose) return;\n if (g.dy > 0) {\n translateY.setValue(g.dy);\n const p = Math.min(1, g.dy / (swipeThreshold * 2));\n fade.setValue(1 - p * 0.25);\n scale.setValue(1 - p * 0.03);\n }\n },\n onPanResponderRelease: (_evt, g) => {\n if (!enableSwipeToClose) return;\n if (g.dy > swipeThreshold) {\n closeReasonRef.current = 'swipe';\n Animated.parallel([\n Animated.timing(translateY, { toValue: screenHeight * 0.35, duration: 180, useNativeDriver: true }),\n Animated.timing(fade, { toValue: 0, duration: 180, useNativeDriver: true }),\n ]).start(() => onClose?.());\n } else {\n Animated.parallel([\n Animated.spring(translateY, { toValue: 0, useNativeDriver: true }),\n Animated.spring(fade, { toValue: 1, useNativeDriver: true }),\n Animated.spring(scale, { toValue: 1, useNativeDriver: true }),\n ]).start();\n }\n },\n })\n ).current;\n\n if (!mounted && !visible) return null;\n\n return (\n <Modal\n transparent\n visible={mounted || visible}\n animationType=\"none\"\n onRequestClose={() => {\n if (closeOnBackButton) {\n closeReasonRef.current = 'backButton';\n onClose?.();\n }\n }}\n presentationStyle=\"overFullScreen\"\n statusBarTranslucent={Platform.OS === 'android'}\n >\n {/* Backdrop */}\n <Animated.View\n style={[\n styles.overlay,\n { backgroundColor: baseOverlay, opacity: fade },\n stylesOverride.overlay,\n ]}\n accessibilityViewIsModal\n >\n {renderBackdrop ? (\n // If you provide a custom backdrop, you control its hit area/closing\n renderBackdrop(fade as unknown as Animated.AnimatedInterpolation<number>)\n ) : (\n <Pressable\n onPress={() => {\n onBackdropPress?.();\n if (closeOnBackdropPress) {\n closeReasonRef.current = 'backdrop';\n onClose?.();\n }\n }}\n style={StyleSheet.absoluteFill}\n android_disableSound\n accessibilityRole=\"button\"\n accessibilityLabel=\"Close quick preview\"\n testID=\"qp-backdrop\"\n />\n )}\n\n {/* Centered card */}\n <View\n style={[\n styles.centerWrap,\n { paddingBottom: Math.max(16, avoidKeyboard ? kb : 16) },\n stylesOverride.centerWrap,\n ]}\n pointerEvents=\"box-none\"\n >\n <Animated.View\n {...(enableSwipeToClose ? panResponder.panHandlers : {})}\n style={[\n styles.container,\n { transform: [{ scale }, { translateY }] },\n stylesOverride.container,\n ]}\n testID={testID}\n accessibilityRole={dialogA11yRole}\n accessibilityViewIsModal\n accessibilityLabel={accessibilityLabel}\n >\n {children}\n </Animated.View>\n </View>\n </Animated.View>\n </Modal>\n );\n};\n\nconst styles = StyleSheet.create({\n overlay: { flex: 1, justifyContent: 'center', alignItems: 'center' },\n centerWrap: {\n flex: 1,\n width: '100%',\n justifyContent: 'center',\n alignItems: 'center',\n paddingHorizontal: 16,\n },\n container: {\n width: Math.min(screenWidth * 0.92, 560),\n maxHeight: screenHeight * 0.82,\n borderRadius: 16,\n overflow: 'hidden',\n elevation: 8,\n shadowColor: '#000',\n shadowOpacity: 0.2,\n shadowRadius: 12,\n shadowOffset: { width: 0, height: 6 },\n backgroundColor: '#fff',\n },\n});\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {useState,useRef,useMemo,useEffect}from'react';import {Dimensions,StyleSheet,Animated,Keyboard,PanResponder,Modal,Pressable,View,Platform}from'react-native';import {jsx,jsxs}from'react/jsx-runtime';var K=Object.defineProperty,U=Object.defineProperties;var X=Object.getOwnPropertyDescriptors;var
|
|
1
|
+
import {useState,useRef,useMemo,useEffect}from'react';import {Dimensions,StyleSheet,Animated,Keyboard,PanResponder,Modal,Pressable,View,Platform}from'react-native';import {jsx,jsxs}from'react/jsx-runtime';var K=Object.defineProperty,U=Object.defineProperties;var X=Object.getOwnPropertyDescriptors;var x=Object.getOwnPropertySymbols;var Z=Object.prototype.hasOwnProperty,B=Object.prototype.propertyIsEnumerable;var I=(r,e,i)=>e in r?K(r,e,{enumerable:true,configurable:true,writable:true,value:i}):r[e]=i,S=(r,e)=>{for(var i in e||(e={}))Z.call(e,i)&&I(r,i,e[i]);if(x)for(var i of x(e))B.call(e,i)&&I(r,i,e[i]);return r},q=(r,e)=>U(r,X(e));var {width:ne,height:_}=Dimensions.get("window"),se="dialog",ue=(r,e)=>`rgba(0,0,0,${e!=null?e:r==="dark"?.8:.5})`,oe=({visible:r,onClose:e,onOpen:i,onClosed:d,theme:g="light",backdropOpacity:R,animationDuration:f=220,closeOnBackdropPress:j=true,closeOnBackButton:z=true,enableSwipeToClose:v=true,swipeThreshold:M=80,unmountOnExit:k=true,avoidKeyboard:y=false,children:E,renderBackdrop:P,onBackdropPress:h,testID:T="quickpreview",accessibilityLabel:Y="Quick preview",stylesOverride:b={}})=>{let[o,D]=useState(false),[$,A]=useState(0),n=useRef(new Animated.Value(0)).current,s=useRef(new Animated.Value(.96)).current,u=useRef(new Animated.Value(0)).current,G=useMemo(()=>ue(g,R),[g,R]),c=useRef("programmatic");useEffect(()=>{r&&!o?(D(true),i==null||i(),requestAnimationFrame(()=>{Animated.parallel([Animated.timing(n,{toValue:1,duration:f,useNativeDriver:true}),Animated.spring(s,{toValue:1,useNativeDriver:true,friction:7,tension:80})]).start();})):!r&&o&&Animated.parallel([Animated.timing(n,{toValue:0,duration:f,useNativeDriver:true}),Animated.timing(s,{toValue:.96,duration:f,useNativeDriver:true})]).start(()=>{u.setValue(0),d==null||d(c.current),c.current="programmatic",k&&D(false);});},[r,o,f,n,s,u,k,i,d]),useEffect(()=>{if(!y)return;let m=Keyboard.addListener("keyboardDidShow",p=>{var N,Q;return A((Q=(N=p.endCoordinates)==null?void 0:N.height)!=null?Q:0)}),a=Keyboard.addListener("keyboardDidHide",()=>A(0));return ()=>{m.remove(),a.remove();}},[y]);let J=useRef(PanResponder.create({onMoveShouldSetPanResponder:(m,a)=>v&&Math.abs(a.dy)>Math.abs(a.dx)&&Math.abs(a.dy)>5,onPanResponderMove:(m,a)=>{if(v&&a.dy>0){u.setValue(a.dy);let p=Math.min(1,a.dy/(M*2));n.setValue(1-p*.25),s.setValue(1-p*.03);}},onPanResponderRelease:(m,a)=>{v&&(a.dy>M?(c.current="swipe",Animated.parallel([Animated.timing(u,{toValue:_*.35,duration:180,useNativeDriver:true}),Animated.timing(n,{toValue:0,duration:180,useNativeDriver:true})]).start(()=>e==null?void 0:e())):Animated.parallel([Animated.spring(u,{toValue:0,useNativeDriver:true}),Animated.spring(n,{toValue:1,useNativeDriver:true}),Animated.spring(s,{toValue:1,useNativeDriver:true})]).start());}})).current;return !o&&!r?null:jsx(Modal,{transparent:true,visible:o||r,animationType:"none",onRequestClose:()=>{z&&(c.current="backButton",e==null||e());},presentationStyle:"overFullScreen",statusBarTranslucent:Platform.OS==="android",children:jsxs(Animated.View,{style:[V.overlay,{backgroundColor:G,opacity:n},b.overlay],accessibilityViewIsModal:true,children:[P?P(n):jsx(Pressable,{onPress:()=>{h==null||h(),j&&(c.current="backdrop",e==null||e());},style:StyleSheet.absoluteFill,android_disableSound:true,accessibilityRole:"button",accessibilityLabel:"Close quick preview",testID:"qp-backdrop"}),jsx(View,{style:[V.centerWrap,{paddingBottom:Math.max(16,y?$:16)},b.centerWrap],pointerEvents:"box-none",children:jsx(Animated.View,q(S({},v?J.panHandlers:{}),{style:[V.container,{transform:[{scale:s},{translateY:u}]},b.container],testID:T,accessibilityRole:se,accessibilityViewIsModal:true,accessibilityLabel:Y,children:E}))})]})})},V=StyleSheet.create({overlay:{flex:1,justifyContent:"center",alignItems:"center"},centerWrap:{flex:1,width:"100%",justifyContent:"center",alignItems:"center",paddingHorizontal:16},container:{width:Math.min(ne*.92,560),maxHeight:_*.82,borderRadius:16,overflow:"hidden",elevation:8,shadowColor:"#000",shadowOpacity:.2,shadowRadius:12,shadowOffset:{width:0,height:6},backgroundColor:"#fff"}});export{oe as QuickPreview};//# sourceMappingURL=index.mjs.map
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/QuickLook.tsx"],"names":["screenWidth","screenHeight","Dimensions","dialogA11yRole","overlayColor","theme","custom","QuickLook","visible","onClose","onOpen","onClosed","backdropOpacity","animationDuration","closeOnBackdropPress","closeOnBackButton","enableSwipeToClose","swipeThreshold","unmountOnExit","avoidKeyboard","children","renderBackdrop","onBackdropPress","testID","accessibilityLabel","stylesOverride","mounted","setMounted","useState","kb","setKb","fade","useRef","Animated","scale","translateY","baseOverlay","useMemo","closeReasonRef","useEffect","show","Keyboard","e","_a","_b","hide","panResponder","PanResponder","_evt","g","jsx","Modal","Platform","jsxs","styles","Pressable","StyleSheet","View","__spreadProps","__spreadValues"],"mappings":"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","file":"index.mjs","sourcesContent":["// src/QuickLook.tsx\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n View,\n StyleSheet,\n Modal,\n Dimensions,\n Animated,\n Platform,\n Pressable,\n PanResponder,\n Keyboard,\n} from 'react-native';\nimport type { AccessibilityRole } from 'react-native';\nimport type { CloseReason, QuickLookProps, ThemeMode } from './QuickLookProperties';\n\nconst { width: screenWidth, height: screenHeight } = Dimensions.get('window');\n\n// TS-safe across RN versions where \"dialog\" may not exist in AccessibilityRole\nconst dialogA11yRole = 'dialog' as unknown as AccessibilityRole;\n\nconst overlayColor = (theme: ThemeMode, custom?: number) =>\n `rgba(0,0,0,${custom ?? (theme === 'dark' ? 0.8 : 0.5)})`;\n\nexport const QuickLook: React.FC<QuickLookProps> = ({\n visible,\n onClose,\n onOpen,\n onClosed,\n theme = 'light',\n backdropOpacity,\n animationDuration = 220,\n closeOnBackdropPress = true,\n closeOnBackButton = true,\n enableSwipeToClose = true,\n swipeThreshold = 80,\n unmountOnExit = true,\n avoidKeyboard = false,\n children,\n renderBackdrop,\n onBackdropPress,\n testID = 'quicklook',\n accessibilityLabel = 'Quick look',\n stylesOverride = {},\n}) => {\n const [mounted, setMounted] = useState(false);\n const [kb, setKb] = useState(0); // keyboard height\n\n const fade = useRef(new Animated.Value(0)).current;\n const scale = useRef(new Animated.Value(0.96)).current;\n const translateY = useRef(new Animated.Value(0)).current;\n\n const baseOverlay = useMemo(() => overlayColor(theme, backdropOpacity), [theme, backdropOpacity]);\n\n // Track why we closed so we can report it to onClosed\n const closeReasonRef = useRef<CloseReason>('programmatic');\n\n // Mount/unmount with animation\n useEffect(() => {\n if (visible && !mounted) {\n setMounted(true);\n onOpen?.(); // great place to trigger optional haptics in-app\n\n requestAnimationFrame(() => {\n Animated.parallel([\n Animated.timing(fade, { toValue: 1, duration: animationDuration, useNativeDriver: true }),\n Animated.spring(scale, { toValue: 1, useNativeDriver: true, friction: 7, tension: 80 }),\n ]).start();\n });\n } else if (!visible && mounted) {\n Animated.parallel([\n Animated.timing(fade, { toValue: 0, duration: animationDuration, useNativeDriver: true }),\n Animated.timing(scale, { toValue: 0.96, duration: animationDuration, useNativeDriver: true }),\n ]).start(() => {\n translateY.setValue(0);\n onClosed?.(closeReasonRef.current);\n closeReasonRef.current = 'programmatic';\n if (unmountOnExit) setMounted(false);\n });\n }\n }, [visible, mounted, animationDuration, fade, scale, translateY, unmountOnExit, onOpen, onClosed]);\n\n // Keyboard avoidance (optional)\n useEffect(() => {\n if (!avoidKeyboard) return;\n const show = Keyboard.addListener('keyboardDidShow', (e) => setKb(e.endCoordinates?.height ?? 0));\n const hide = Keyboard.addListener('keyboardDidHide', () => setKb(0));\n return () => {\n show.remove();\n hide.remove();\n };\n }, [avoidKeyboard]);\n\n // Swipe to close\n const panResponder = useRef(\n PanResponder.create({\n onMoveShouldSetPanResponder: (_evt, g) =>\n enableSwipeToClose && Math.abs(g.dy) > Math.abs(g.dx) && Math.abs(g.dy) > 5,\n onPanResponderMove: (_evt, g) => {\n if (!enableSwipeToClose) return;\n if (g.dy > 0) {\n translateY.setValue(g.dy);\n const p = Math.min(1, g.dy / (swipeThreshold * 2));\n fade.setValue(1 - p * 0.25);\n scale.setValue(1 - p * 0.03);\n }\n },\n onPanResponderRelease: (_evt, g) => {\n if (!enableSwipeToClose) return;\n if (g.dy > swipeThreshold) {\n closeReasonRef.current = 'swipe';\n Animated.parallel([\n Animated.timing(translateY, { toValue: screenHeight * 0.35, duration: 180, useNativeDriver: true }),\n Animated.timing(fade, { toValue: 0, duration: 180, useNativeDriver: true }),\n ]).start(() => onClose?.());\n } else {\n Animated.parallel([\n Animated.spring(translateY, { toValue: 0, useNativeDriver: true }),\n Animated.spring(fade, { toValue: 1, useNativeDriver: true }),\n Animated.spring(scale, { toValue: 1, useNativeDriver: true }),\n ]).start();\n }\n },\n })\n ).current;\n\n if (!mounted && !visible) return null;\n\n return (\n <Modal\n transparent\n visible={mounted || visible}\n animationType=\"none\"\n onRequestClose={() => {\n if (closeOnBackButton) {\n closeReasonRef.current = 'backButton';\n onClose?.();\n }\n }}\n presentationStyle=\"overFullScreen\"\n statusBarTranslucent={Platform.OS === 'android'}\n >\n {/* Backdrop */}\n <Animated.View\n style={[\n styles.overlay,\n { backgroundColor: baseOverlay, opacity: fade },\n stylesOverride.overlay,\n ]}\n accessibilityViewIsModal\n >\n {renderBackdrop ? (\n // If you provide a custom backdrop, you control its hit area/closing\n renderBackdrop(fade as unknown as Animated.AnimatedInterpolation<number>)\n ) : (\n <Pressable\n onPress={() => {\n onBackdropPress?.();\n if (closeOnBackdropPress) {\n closeReasonRef.current = 'backdrop';\n onClose?.();\n }\n }}\n style={StyleSheet.absoluteFill}\n android_disableSound\n accessibilityRole=\"button\"\n accessibilityLabel=\"Close quick look\"\n testID=\"ql-backdrop\"\n />\n )}\n\n {/* Centered card */}\n <View\n style={[\n styles.centerWrap,\n { paddingBottom: Math.max(16, avoidKeyboard ? kb : 16) },\n stylesOverride.centerWrap,\n ]}\n pointerEvents=\"box-none\"\n >\n <Animated.View\n {...(enableSwipeToClose ? panResponder.panHandlers : {})}\n style={[\n styles.container,\n { transform: [{ scale }, { translateY }] },\n stylesOverride.container,\n ]}\n testID={testID}\n accessibilityRole={dialogA11yRole}\n accessibilityViewIsModal\n accessibilityLabel={accessibilityLabel}\n >\n {children}\n </Animated.View>\n </View>\n </Animated.View>\n </Modal>\n );\n};\n\nconst styles = StyleSheet.create({\n overlay: { flex: 1, justifyContent: 'center', alignItems: 'center' },\n centerWrap: {\n flex: 1,\n width: '100%',\n justifyContent: 'center',\n alignItems: 'center',\n paddingHorizontal: 16,\n },\n container: {\n width: Math.min(screenWidth * 0.92, 560),\n maxHeight: screenHeight * 0.82,\n borderRadius: 16,\n overflow: 'hidden',\n elevation: 8,\n shadowColor: '#000',\n shadowOpacity: 0.2,\n shadowRadius: 12,\n shadowOffset: { width: 0, height: 6 },\n backgroundColor: '#fff',\n },\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/QuickPreview.tsx"],"names":["screenWidth","screenHeight","Dimensions","dialogA11yRole","overlayColor","theme","custom","QuickPreview","visible","onClose","onOpen","onClosed","backdropOpacity","animationDuration","closeOnBackdropPress","closeOnBackButton","enableSwipeToClose","swipeThreshold","unmountOnExit","avoidKeyboard","children","renderBackdrop","onBackdropPress","testID","accessibilityLabel","stylesOverride","mounted","setMounted","useState","kb","setKb","fade","useRef","Animated","scale","translateY","baseOverlay","useMemo","closeReasonRef","useEffect","show","Keyboard","e","_a","_b","hide","panResponder","PanResponder","_evt","g","jsx","Modal","Platform","jsxs","styles","Pressable","StyleSheet","View","__spreadProps","__spreadValues"],"mappings":"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","file":"index.mjs","sourcesContent":["// src/QuickPreview.tsx\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n View,\n StyleSheet,\n Modal,\n Dimensions,\n Animated,\n Platform,\n Pressable,\n PanResponder,\n Keyboard,\n} from 'react-native';\nimport type { AccessibilityRole } from 'react-native';\nimport type { CloseReason, QuickPreviewProps, ThemeMode } from './QuickPreviewProperties';\n\nconst { width: screenWidth, height: screenHeight } = Dimensions.get('window');\n\n// TS-safe across RN versions where \"dialog\" may not exist in AccessibilityRole\nconst dialogA11yRole = 'dialog' as unknown as AccessibilityRole;\n\nconst overlayColor = (theme: ThemeMode, custom?: number) =>\n `rgba(0,0,0,${custom ?? (theme === 'dark' ? 0.8 : 0.5)})`;\n\nexport const QuickPreview: React.FC<QuickPreviewProps> = ({\n visible,\n onClose,\n onOpen,\n onClosed,\n theme = 'light',\n backdropOpacity,\n animationDuration = 220,\n closeOnBackdropPress = true,\n closeOnBackButton = true,\n enableSwipeToClose = true,\n swipeThreshold = 80,\n unmountOnExit = true,\n avoidKeyboard = false,\n children,\n renderBackdrop,\n onBackdropPress,\n testID = 'quickpreview',\n accessibilityLabel = 'Quick preview',\n stylesOverride = {},\n}) => {\n const [mounted, setMounted] = useState(false);\n const [kb, setKb] = useState(0); // keyboard height\n\n const fade = useRef(new Animated.Value(0)).current;\n const scale = useRef(new Animated.Value(0.96)).current;\n const translateY = useRef(new Animated.Value(0)).current;\n\n const baseOverlay = useMemo(() => overlayColor(theme, backdropOpacity), [theme, backdropOpacity]);\n\n // Track why we closed so we can report it to onClosed\n const closeReasonRef = useRef<CloseReason>('programmatic');\n\n // Mount/unmount with animation\n useEffect(() => {\n if (visible && !mounted) {\n setMounted(true);\n onOpen?.(); // great place to trigger optional haptics in-app\n\n requestAnimationFrame(() => {\n Animated.parallel([\n Animated.timing(fade, { toValue: 1, duration: animationDuration, useNativeDriver: true }),\n Animated.spring(scale, { toValue: 1, useNativeDriver: true, friction: 7, tension: 80 }),\n ]).start();\n });\n } else if (!visible && mounted) {\n Animated.parallel([\n Animated.timing(fade, { toValue: 0, duration: animationDuration, useNativeDriver: true }),\n Animated.timing(scale, { toValue: 0.96, duration: animationDuration, useNativeDriver: true }),\n ]).start(() => {\n translateY.setValue(0);\n onClosed?.(closeReasonRef.current);\n closeReasonRef.current = 'programmatic';\n if (unmountOnExit) setMounted(false);\n });\n }\n }, [visible, mounted, animationDuration, fade, scale, translateY, unmountOnExit, onOpen, onClosed]);\n\n // Keyboard avoidance (optional)\n useEffect(() => {\n if (!avoidKeyboard) return;\n const show = Keyboard.addListener('keyboardDidShow', (e) => setKb(e.endCoordinates?.height ?? 0));\n const hide = Keyboard.addListener('keyboardDidHide', () => setKb(0));\n return () => {\n show.remove();\n hide.remove();\n };\n }, [avoidKeyboard]);\n\n // Swipe to close\n const panResponder = useRef(\n PanResponder.create({\n onMoveShouldSetPanResponder: (_evt, g) =>\n enableSwipeToClose && Math.abs(g.dy) > Math.abs(g.dx) && Math.abs(g.dy) > 5,\n onPanResponderMove: (_evt, g) => {\n if (!enableSwipeToClose) return;\n if (g.dy > 0) {\n translateY.setValue(g.dy);\n const p = Math.min(1, g.dy / (swipeThreshold * 2));\n fade.setValue(1 - p * 0.25);\n scale.setValue(1 - p * 0.03);\n }\n },\n onPanResponderRelease: (_evt, g) => {\n if (!enableSwipeToClose) return;\n if (g.dy > swipeThreshold) {\n closeReasonRef.current = 'swipe';\n Animated.parallel([\n Animated.timing(translateY, { toValue: screenHeight * 0.35, duration: 180, useNativeDriver: true }),\n Animated.timing(fade, { toValue: 0, duration: 180, useNativeDriver: true }),\n ]).start(() => onClose?.());\n } else {\n Animated.parallel([\n Animated.spring(translateY, { toValue: 0, useNativeDriver: true }),\n Animated.spring(fade, { toValue: 1, useNativeDriver: true }),\n Animated.spring(scale, { toValue: 1, useNativeDriver: true }),\n ]).start();\n }\n },\n })\n ).current;\n\n if (!mounted && !visible) return null;\n\n return (\n <Modal\n transparent\n visible={mounted || visible}\n animationType=\"none\"\n onRequestClose={() => {\n if (closeOnBackButton) {\n closeReasonRef.current = 'backButton';\n onClose?.();\n }\n }}\n presentationStyle=\"overFullScreen\"\n statusBarTranslucent={Platform.OS === 'android'}\n >\n {/* Backdrop */}\n <Animated.View\n style={[\n styles.overlay,\n { backgroundColor: baseOverlay, opacity: fade },\n stylesOverride.overlay,\n ]}\n accessibilityViewIsModal\n >\n {renderBackdrop ? (\n // If you provide a custom backdrop, you control its hit area/closing\n renderBackdrop(fade as unknown as Animated.AnimatedInterpolation<number>)\n ) : (\n <Pressable\n onPress={() => {\n onBackdropPress?.();\n if (closeOnBackdropPress) {\n closeReasonRef.current = 'backdrop';\n onClose?.();\n }\n }}\n style={StyleSheet.absoluteFill}\n android_disableSound\n accessibilityRole=\"button\"\n accessibilityLabel=\"Close quick preview\"\n testID=\"qp-backdrop\"\n />\n )}\n\n {/* Centered card */}\n <View\n style={[\n styles.centerWrap,\n { paddingBottom: Math.max(16, avoidKeyboard ? kb : 16) },\n stylesOverride.centerWrap,\n ]}\n pointerEvents=\"box-none\"\n >\n <Animated.View\n {...(enableSwipeToClose ? panResponder.panHandlers : {})}\n style={[\n styles.container,\n { transform: [{ scale }, { translateY }] },\n stylesOverride.container,\n ]}\n testID={testID}\n accessibilityRole={dialogA11yRole}\n accessibilityViewIsModal\n accessibilityLabel={accessibilityLabel}\n >\n {children}\n </Animated.View>\n </View>\n </Animated.View>\n </Modal>\n );\n};\n\nconst styles = StyleSheet.create({\n overlay: { flex: 1, justifyContent: 'center', alignItems: 'center' },\n centerWrap: {\n flex: 1,\n width: '100%',\n justifyContent: 'center',\n alignItems: 'center',\n paddingHorizontal: 16,\n },\n container: {\n width: Math.min(screenWidth * 0.92, 560),\n maxHeight: screenHeight * 0.82,\n borderRadius: 16,\n overflow: 'hidden',\n elevation: 8,\n shadowColor: '#000',\n shadowOpacity: 0.2,\n shadowRadius: 12,\n shadowOffset: { width: 0, height: 6 },\n backgroundColor: '#fff',\n },\n});\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-quick-preview",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "A beautiful, customizable quick preview modal component for React Native",
|
|
5
5
|
"author": "Oliver Lindblad",
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,7 +37,24 @@
|
|
|
37
37
|
"react-native",
|
|
38
38
|
"modal",
|
|
39
39
|
"preview",
|
|
40
|
-
"
|
|
40
|
+
"quickpreview",
|
|
41
|
+
"quick-preview",
|
|
42
|
+
"quick-view",
|
|
43
|
+
"quick-view-modal",
|
|
44
|
+
"quick-view-dialog",
|
|
45
|
+
"quick-view-sheet",
|
|
46
|
+
"quick-view-popover",
|
|
47
|
+
"quick-view-drawer",
|
|
48
|
+
"quick-view-modal",
|
|
49
|
+
"quick-view-dialog",
|
|
50
|
+
"quick-view-sheet",
|
|
51
|
+
"quick-view-popover",
|
|
52
|
+
"quick-view-drawer",
|
|
53
|
+
"quick-view-modal",
|
|
54
|
+
"quick-view-dialog",
|
|
55
|
+
"quick-view-sheet",
|
|
56
|
+
"quick-view-popover",
|
|
57
|
+
"quick-view-drawer",
|
|
41
58
|
"expo",
|
|
42
59
|
"typescript",
|
|
43
60
|
"ui",
|
|
@@ -70,12 +87,12 @@
|
|
|
70
87
|
|
|
71
88
|
"repository": {
|
|
72
89
|
"type": "git",
|
|
73
|
-
"url": "https://github.com/Hashtagsmile/react-native-
|
|
90
|
+
"url": "https://github.com/Hashtagsmile/react-native-quick-preview.git"
|
|
74
91
|
},
|
|
75
92
|
"bugs": {
|
|
76
|
-
"url": "https://github.com/Hashtagsmile/react-native-
|
|
93
|
+
"url": "https://github.com/Hashtagsmile/react-native-quick-preview/issues"
|
|
77
94
|
},
|
|
78
|
-
"homepage": "https://github.com/Hashtagsmile/react-native-
|
|
95
|
+
"homepage": "https://github.com/Hashtagsmile/react-native-quick-preview#readme",
|
|
79
96
|
"publishConfig": { "access": "public" },
|
|
80
97
|
"engines": { "node": ">=16" }
|
|
81
98
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/
|
|
1
|
+
// src/QuickPreview.tsx
|
|
2
2
|
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import {
|
|
4
4
|
View,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
Keyboard,
|
|
13
13
|
} from 'react-native';
|
|
14
14
|
import type { AccessibilityRole } from 'react-native';
|
|
15
|
-
import type { CloseReason,
|
|
15
|
+
import type { CloseReason, QuickPreviewProps, ThemeMode } from './QuickPreviewProperties';
|
|
16
16
|
|
|
17
17
|
const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
|
|
18
18
|
|
|
@@ -22,7 +22,7 @@ const dialogA11yRole = 'dialog' as unknown as AccessibilityRole;
|
|
|
22
22
|
const overlayColor = (theme: ThemeMode, custom?: number) =>
|
|
23
23
|
`rgba(0,0,0,${custom ?? (theme === 'dark' ? 0.8 : 0.5)})`;
|
|
24
24
|
|
|
25
|
-
export const
|
|
25
|
+
export const QuickPreview: React.FC<QuickPreviewProps> = ({
|
|
26
26
|
visible,
|
|
27
27
|
onClose,
|
|
28
28
|
onOpen,
|
|
@@ -39,8 +39,8 @@ export const QuickLook: React.FC<QuickLookProps> = ({
|
|
|
39
39
|
children,
|
|
40
40
|
renderBackdrop,
|
|
41
41
|
onBackdropPress,
|
|
42
|
-
testID = '
|
|
43
|
-
accessibilityLabel = 'Quick
|
|
42
|
+
testID = 'quickpreview',
|
|
43
|
+
accessibilityLabel = 'Quick preview',
|
|
44
44
|
stylesOverride = {},
|
|
45
45
|
}) => {
|
|
46
46
|
const [mounted, setMounted] = useState(false);
|
|
@@ -164,8 +164,8 @@ export const QuickLook: React.FC<QuickLookProps> = ({
|
|
|
164
164
|
style={StyleSheet.absoluteFill}
|
|
165
165
|
android_disableSound
|
|
166
166
|
accessibilityRole="button"
|
|
167
|
-
accessibilityLabel="Close quick
|
|
168
|
-
testID="
|
|
167
|
+
accessibilityLabel="Close quick preview"
|
|
168
|
+
testID="qp-backdrop"
|
|
169
169
|
/>
|
|
170
170
|
)}
|
|
171
171
|
|
|
@@ -5,7 +5,7 @@ export type ThemeMode = 'light' | 'dark';
|
|
|
5
5
|
export type CloseReason = 'programmatic' | 'backdrop' | 'backButton' | 'swipe';
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
export interface
|
|
8
|
+
export interface QuickPreviewProps {
|
|
9
9
|
visible: boolean;
|
|
10
10
|
onClose: () => void;
|
|
11
11
|
|
|
@@ -13,8 +13,6 @@ export interface QuickLookProps {
|
|
|
13
13
|
onOpen?: () => void; // fires when animating in
|
|
14
14
|
onClosed?: (reason: CloseReason) => void; // fires after fully closed
|
|
15
15
|
|
|
16
|
-
/** Optional: press whole card (prefer explicit CTAs as well) */
|
|
17
|
-
onPressCard?: () => void;
|
|
18
16
|
|
|
19
17
|
theme?: ThemeMode;
|
|
20
18
|
backdropOpacity?: number; // default 0.5 light / 0.8 dark
|
package/src/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export type {
|
|
1
|
+
export { QuickPreview } from './QuickPreview';
|
|
2
|
+
export type { QuickPreviewProps, ThemeMode, CloseReason } from './QuickPreviewProperties';
|