@tamagui/sheet 1.0.1-beta.139 → 1.0.1-beta.142
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/dist/cjs/Sheet.js +43 -51
- package/dist/cjs/Sheet.js.map +2 -2
- package/dist/cjs/types.js.map +1 -1
- package/dist/cjs/useAnimated.js +106 -0
- package/dist/cjs/useAnimated.js.map +7 -0
- package/dist/esm/Sheet.js +45 -56
- package/dist/esm/Sheet.js.map +2 -2
- package/dist/esm/useAnimated.js +80 -0
- package/dist/esm/useAnimated.js.map +7 -0
- package/dist/jsx/Sheet.js +53 -67
- package/dist/jsx/Sheet.js.map +2 -2
- package/dist/jsx/useAnimated.js +80 -0
- package/dist/jsx/useAnimated.js.map +7 -0
- package/package.json +9 -8
- package/src/Sheet.tsx +54 -70
- package/src/types.tsx +2 -2
- package/types/SHEET_HANDLE_NAME.d.ts +0 -0
- package/types/Sheet.d.ts +21 -21
- package/types/SheetContext.d.ts +1 -1
- package/types/SheetScrollView.d.ts +0 -0
- package/types/index.d.ts +0 -0
- package/types/types.d.ts +2 -2
- package/types/useAnimated.d.ts +19 -0
- package/types/useAnimation.d.ts +1 -0
- package/dist/cjs/Drawer.js +0 -284
- package/dist/cjs/Drawer.js.map +0 -7
- package/dist/cjs/RemoveScrollProps.js +0 -17
- package/dist/cjs/RemoveScrollProps.js.map +0 -7
- package/dist/esm/Drawer.js +0 -264
- package/dist/esm/Drawer.js.map +0 -7
- package/dist/esm/RemoveScrollProps.js +0 -1
- package/dist/esm/RemoveScrollProps.js.map +0 -7
- package/dist/jsx/Drawer.js +0 -220
- package/dist/jsx/Drawer.js.map +0 -7
- package/dist/jsx/RemoveScrollProps.js +0 -1
- package/dist/jsx/RemoveScrollProps.js.map +0 -7
package/dist/jsx/Sheet.js
CHANGED
|
@@ -2,8 +2,8 @@ import { useComposedRefs } from "@tamagui/compose-refs";
|
|
|
2
2
|
import {
|
|
3
3
|
Slot,
|
|
4
4
|
Theme,
|
|
5
|
+
getAnimationDriver,
|
|
5
6
|
isClient,
|
|
6
|
-
isWeb,
|
|
7
7
|
mergeEvent,
|
|
8
8
|
styled,
|
|
9
9
|
themeable,
|
|
@@ -28,10 +28,7 @@ import React, {
|
|
|
28
28
|
useRef,
|
|
29
29
|
useState
|
|
30
30
|
} from "react";
|
|
31
|
-
import {
|
|
32
|
-
Animated,
|
|
33
|
-
PanResponder
|
|
34
|
-
} from "react-native";
|
|
31
|
+
import { PanResponder } from "react-native";
|
|
35
32
|
import { SHEET_HANDLE_NAME, SHEET_NAME } from "./SHEET_HANDLE_NAME";
|
|
36
33
|
import { SheetProvider, useSheetContext } from "./SheetContext";
|
|
37
34
|
import { SheetScrollView } from "./SheetScrollView";
|
|
@@ -115,7 +112,6 @@ const SheetFrame = SheetFrameFrame.extractable(forwardRef(({ __scopeSheet, ...pr
|
|
|
115
112
|
}));
|
|
116
113
|
const HIDDEN_SIZE = 1e4;
|
|
117
114
|
const Sheet = withStaticProperties(themeable(forwardRef(function Sheet2(props, ref) {
|
|
118
|
-
var _a;
|
|
119
115
|
const {
|
|
120
116
|
__scopeSheet,
|
|
121
117
|
snapPoints: snapPointsProp = [80],
|
|
@@ -138,9 +134,13 @@ const Sheet = withStaticProperties(themeable(forwardRef(function Sheet2(props, r
|
|
|
138
134
|
console.warn(`\u26A0\uFE0F Invalid snapPoint given, snapPoints must be between 0 and 100, equal to percent height of frame`);
|
|
139
135
|
}
|
|
140
136
|
}
|
|
137
|
+
const driver = getAnimationDriver();
|
|
138
|
+
if (!driver) {
|
|
139
|
+
throw new Error(`Must set animations in tamagui.config.ts`);
|
|
140
|
+
}
|
|
141
141
|
const controller = useContext(SheetControllerContext);
|
|
142
|
-
const isHidden =
|
|
143
|
-
const disableDrag = disableDragProp
|
|
142
|
+
const isHidden = controller?.hidden || false;
|
|
143
|
+
const disableDrag = disableDragProp ?? controller?.disableDrag;
|
|
144
144
|
const themeName = useThemeName();
|
|
145
145
|
const contentRef = React.useRef(null);
|
|
146
146
|
const scrollBridge = useConstant(() => ({
|
|
@@ -156,12 +156,11 @@ const Sheet = withStaticProperties(themeable(forwardRef(function Sheet2(props, r
|
|
|
156
156
|
scrollLock: false
|
|
157
157
|
}));
|
|
158
158
|
const onChangeOpenInternal = (val) => {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
onChangeOpen == null ? void 0 : onChangeOpen(val);
|
|
159
|
+
controller?.onChangeOpen?.(val);
|
|
160
|
+
onChangeOpen?.(val);
|
|
162
161
|
};
|
|
163
162
|
const [open, setOpen] = useControllableState({
|
|
164
|
-
prop:
|
|
163
|
+
prop: controller?.open ?? openProp,
|
|
165
164
|
defaultProp: defaultOpen || true,
|
|
166
165
|
onChange: onChangeOpenInternal,
|
|
167
166
|
strategy: "most-recent-wins"
|
|
@@ -185,21 +184,20 @@ const Sheet = withStaticProperties(themeable(forwardRef(function Sheet2(props, r
|
|
|
185
184
|
setPosition_(next);
|
|
186
185
|
}
|
|
187
186
|
}, [dismissOnSnapToBottom, snapPoints.length, setPosition_, setOpen]);
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
187
|
+
const animatedNumber = driver.useAnimatedNumber(HIDDEN_SIZE);
|
|
188
|
+
const at = useRef(0);
|
|
189
|
+
driver.useAnimatedNumberReaction(animatedNumber, (value) => {
|
|
190
|
+
at.current = value;
|
|
191
|
+
scrollBridge.paneY = value;
|
|
192
|
+
});
|
|
192
193
|
const [isResizing, setIsResizing] = useState(true);
|
|
193
194
|
useIsomorphicLayoutEffect(() => {
|
|
194
195
|
if (!isResizing) {
|
|
195
196
|
setIsResizing(true);
|
|
196
197
|
}
|
|
197
198
|
}, [modal]);
|
|
198
|
-
const spring = useRef(null);
|
|
199
199
|
function stopSpring() {
|
|
200
|
-
|
|
201
|
-
(_a2 = spring.current) == null ? void 0 : _a2.stop();
|
|
202
|
-
spring.current = null;
|
|
200
|
+
animatedNumber.stop();
|
|
203
201
|
if (scrollBridge.onFinishAnimate) {
|
|
204
202
|
scrollBridge.onFinishAnimate();
|
|
205
203
|
scrollBridge.onFinishAnimate = void 0;
|
|
@@ -213,7 +211,7 @@ const Sheet = withStaticProperties(themeable(forwardRef(function Sheet2(props, r
|
|
|
213
211
|
}, [setPosition, shouldSetPositionOpen]);
|
|
214
212
|
const positions = useMemo(() => snapPoints.map((point) => getPercentSize(point, frameSize)), [frameSize, snapPoints]);
|
|
215
213
|
const animateTo = useEvent((position2) => {
|
|
216
|
-
const current =
|
|
214
|
+
const current = animatedNumber.getValue();
|
|
217
215
|
if (isHidden && open)
|
|
218
216
|
return;
|
|
219
217
|
if (!current)
|
|
@@ -229,46 +227,28 @@ const Sheet = withStaticProperties(themeable(forwardRef(function Sheet2(props, r
|
|
|
229
227
|
if (isResizing) {
|
|
230
228
|
setIsResizing(false);
|
|
231
229
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
toValue,
|
|
230
|
+
animatedNumber.setValue(toValue, {
|
|
231
|
+
type: "timing",
|
|
235
232
|
duration: 0
|
|
236
|
-
})
|
|
233
|
+
});
|
|
237
234
|
at.current = toValue;
|
|
238
235
|
return;
|
|
239
236
|
}
|
|
240
237
|
const overshootClamping = at.current === HIDDEN_SIZE;
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
overshootClamping
|
|
245
|
-
...animationConfig
|
|
246
|
-
});
|
|
247
|
-
spring.current.start(({ finished }) => {
|
|
248
|
-
if (finished) {
|
|
249
|
-
stopSpring();
|
|
250
|
-
}
|
|
238
|
+
animatedNumber.setValue(toValue, {
|
|
239
|
+
...animationConfig,
|
|
240
|
+
type: "spring",
|
|
241
|
+
overshootClamping
|
|
251
242
|
});
|
|
252
243
|
});
|
|
253
244
|
useIsomorphicLayoutEffect(() => {
|
|
254
245
|
animateTo(position);
|
|
255
246
|
}, [isHidden, frameSize, position, animateTo]);
|
|
256
|
-
const at = useRef(0);
|
|
257
|
-
useEffect(() => {
|
|
258
|
-
positionValue.current.addListener(({ value }) => {
|
|
259
|
-
at.current = value;
|
|
260
|
-
scrollBridge.paneY = value;
|
|
261
|
-
});
|
|
262
|
-
return () => {
|
|
263
|
-
positionValue.current.removeAllListeners();
|
|
264
|
-
};
|
|
265
|
-
}, []);
|
|
266
247
|
const panResponder = useMemo(() => {
|
|
267
248
|
if (disableDrag)
|
|
268
249
|
return;
|
|
269
250
|
if (!frameSize)
|
|
270
251
|
return;
|
|
271
|
-
const pos = positionValue.current;
|
|
272
252
|
const minY = positions[0];
|
|
273
253
|
scrollBridge.paneMinY = minY;
|
|
274
254
|
let startY = at.current;
|
|
@@ -318,8 +298,11 @@ const Sheet = withStaticProperties(themeable(forwardRef(function Sheet2(props, r
|
|
|
318
298
|
return true;
|
|
319
299
|
}
|
|
320
300
|
const isDraggingUp = dy < 0;
|
|
321
|
-
|
|
322
|
-
|
|
301
|
+
const isAtTop = scrollBridge.paneY <= scrollBridge.paneMinY;
|
|
302
|
+
if (isAtTop) {
|
|
303
|
+
if (!isScrolled && isDraggingUp) {
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
323
306
|
}
|
|
324
307
|
return Math.abs(dy) > 8;
|
|
325
308
|
};
|
|
@@ -329,16 +312,13 @@ const Sheet = withStaticProperties(themeable(forwardRef(function Sheet2(props, r
|
|
|
329
312
|
startY = at.current;
|
|
330
313
|
};
|
|
331
314
|
let isExternalDrag = false;
|
|
332
|
-
function setPositionValue(next) {
|
|
333
|
-
pos.setValue(next);
|
|
334
|
-
}
|
|
335
315
|
scrollBridge.drag = (dy) => {
|
|
336
316
|
if (!isExternalDrag) {
|
|
337
317
|
isExternalDrag = true;
|
|
338
318
|
grant();
|
|
339
319
|
}
|
|
340
320
|
const to = dy + startY;
|
|
341
|
-
|
|
321
|
+
animatedNumber.setValue(resisted(to, minY), { type: "direct" });
|
|
342
322
|
};
|
|
343
323
|
scrollBridge.release = release;
|
|
344
324
|
return PanResponder.create({
|
|
@@ -346,7 +326,7 @@ const Sheet = withStaticProperties(themeable(forwardRef(function Sheet2(props, r
|
|
|
346
326
|
onPanResponderGrant: grant,
|
|
347
327
|
onPanResponderMove: (_e, { dy }) => {
|
|
348
328
|
const to = dy + startY;
|
|
349
|
-
|
|
329
|
+
animatedNumber.setValue(resisted(to, minY), { type: "direct" });
|
|
350
330
|
},
|
|
351
331
|
onPanResponderEnd: finish,
|
|
352
332
|
onPanResponderTerminate: finish,
|
|
@@ -357,9 +337,8 @@ const Sheet = withStaticProperties(themeable(forwardRef(function Sheet2(props, r
|
|
|
357
337
|
let overlayComponent = null;
|
|
358
338
|
let frameComponent = null;
|
|
359
339
|
React.Children.forEach(childrenProp, (child) => {
|
|
360
|
-
var _a2, _b;
|
|
361
340
|
if (isValidElement(child)) {
|
|
362
|
-
const name =
|
|
341
|
+
const name = child.type?.["staticConfig"]?.componentName;
|
|
363
342
|
switch (name) {
|
|
364
343
|
case "SheetHandle":
|
|
365
344
|
handleComponent = child;
|
|
@@ -375,30 +354,37 @@ const Sheet = withStaticProperties(themeable(forwardRef(function Sheet2(props, r
|
|
|
375
354
|
}
|
|
376
355
|
}
|
|
377
356
|
});
|
|
378
|
-
const preventShown =
|
|
357
|
+
const preventShown = controller?.hidden && controller?.open;
|
|
358
|
+
const animatedStyle = driver.useAnimatedNumberStyle(animatedNumber, (val) => {
|
|
359
|
+
return {
|
|
360
|
+
transform: [{ translateY: frameSize === 0 ? HIDDEN_SIZE : val }]
|
|
361
|
+
};
|
|
362
|
+
});
|
|
379
363
|
if (preventShown) {
|
|
380
364
|
return null;
|
|
381
365
|
}
|
|
382
|
-
const
|
|
366
|
+
const AnimatedView = driver["NumberView"] ?? driver.View;
|
|
383
367
|
const contents = <SheetProvider modal={modal} contentRef={contentRef} dismissOnOverlayPress={dismissOnOverlayPress} dismissOnSnapToBottom={dismissOnSnapToBottom} open={open} hidden={isHidden} scope={__scopeSheet} position={position} snapPoints={snapPoints} setPosition={setPosition} setOpen={setOpen} scrollBridge={scrollBridge}>
|
|
384
368
|
{isResizing ? null : overlayComponent}
|
|
385
|
-
<
|
|
369
|
+
<AnimatedView ref={ref} {...panResponder?.panHandlers} onLayout={(e) => {
|
|
386
370
|
const next = e.nativeEvent.layout.height;
|
|
387
371
|
setFrameSize((prev) => {
|
|
388
372
|
const isBigChange = Math.abs(prev - next) > 50;
|
|
389
373
|
setIsResizing(isBigChange);
|
|
390
374
|
return next;
|
|
391
375
|
});
|
|
392
|
-
}} pointerEvents={open ? "auto" : "none"} style={
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
376
|
+
}} pointerEvents={open ? "auto" : "none"} style={[
|
|
377
|
+
{
|
|
378
|
+
position: "absolute",
|
|
379
|
+
zIndex: 10,
|
|
380
|
+
width: "100%",
|
|
381
|
+
height: "100%"
|
|
382
|
+
},
|
|
383
|
+
animatedStyle
|
|
384
|
+
]}>
|
|
399
385
|
{handleComponent}
|
|
400
386
|
<RemoveScroll enabled={open && modal && handleDisableScroll} as={Slot} allowPinchZoom shards={[contentRef]} removeScrollBar={false}>{isResizing ? null : frameComponent}</RemoveScroll>
|
|
401
|
-
</
|
|
387
|
+
</AnimatedView>
|
|
402
388
|
</SheetProvider>;
|
|
403
389
|
if (modal) {
|
|
404
390
|
return <Portal><Theme name={themeName}>{contents}</Theme></Portal>;
|
|
@@ -418,7 +404,7 @@ function getPercentSize(point, frameSize) {
|
|
|
418
404
|
return 0;
|
|
419
405
|
}
|
|
420
406
|
const pct = point / 100;
|
|
421
|
-
const next = frameSize - pct * frameSize;
|
|
407
|
+
const next = Math.round(frameSize - pct * frameSize);
|
|
422
408
|
return next;
|
|
423
409
|
}
|
|
424
410
|
function resisted(y, minY, maxOverflow = 25) {
|
package/dist/jsx/Sheet.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/Sheet.tsx"],
|
|
4
|
-
"sourcesContent": ["import { useComposedRefs } from '@tamagui/compose-refs'\nimport {\n GetProps,\n Slot,\n TamaguiElement,\n Theme,\n isClient,\n isWeb,\n mergeEvent,\n styled,\n themeable,\n useConstant,\n useEvent,\n useIsomorphicLayoutEffect,\n useThemeName,\n withStaticProperties,\n} from '@tamagui/core'\nimport { Portal } from '@tamagui/portal'\nimport { RemoveScroll } from '@tamagui/remove-scroll'\nimport { XStack, XStackProps, YStack, YStackProps } from '@tamagui/stacks'\nimport { useControllableState } from '@tamagui/use-controllable-state'\nimport React, {\n createContext,\n forwardRef,\n isValidElement,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport {\n Animated,\n GestureResponderEvent,\n PanResponder,\n PanResponderGestureState,\n View,\n} from 'react-native'\n\nimport { SHEET_HANDLE_NAME, SHEET_NAME } from './SHEET_HANDLE_NAME'\nimport { SheetProvider, useSheetContext } from './SheetContext'\nimport { SheetScrollView } from './SheetScrollView'\nimport { ScrollBridge, SheetProps, SheetScopedProps } from './types'\n\nexport { createSheetScope } from './SheetContext'\n\n/* -------------------------------------------------------------------------------------------------\n * SheetHandle\n * -----------------------------------------------------------------------------------------------*/\n\nexport const SheetHandleFrame = styled(XStack, {\n name: SHEET_HANDLE_NAME,\n height: 10,\n borderRadius: 100,\n backgroundColor: '$background',\n zIndex: 10,\n marginHorizontal: '35%',\n marginBottom: '$2',\n opacity: 0.5,\n\n hoverStyle: {\n opacity: 0.7,\n },\n\n variants: {\n open: {\n true: {\n pointerEvents: 'auto',\n },\n false: {\n opacity: 0,\n pointerEvents: 'none',\n },\n },\n } as const,\n})\n\nexport const SheetHandle = SheetHandleFrame.extractable(\n ({ __scopeSheet, ...props }: SheetScopedProps<XStackProps>) => {\n const context = useSheetContext(SHEET_HANDLE_NAME, __scopeSheet)\n return (\n <SheetHandleFrame\n onPress={() => {\n // don't toggle to the bottom snap position when dismissOnSnapToBottom set\n const max = context.snapPoints.length + (context.dismissOnSnapToBottom ? -1 : 0)\n const nextPos = (context.position + 1) % max\n context.setPosition(nextPos)\n }}\n open={context.open}\n {...props}\n />\n )\n }\n)\n\n/* -------------------------------------------------------------------------------------------------\n * SheetOverlay\n * -----------------------------------------------------------------------------------------------*/\n\nconst SHEET_OVERLAY_NAME = 'SheetOverlay'\n\nexport const SheetOverlayFrame = styled(YStack, {\n name: SHEET_OVERLAY_NAME,\n // TODO this should be $background without opacity and just customized by theme\n backgroundColor: '$color',\n fullscreen: true,\n opacity: 0.2,\n zIndex: 0,\n\n variants: {\n closed: {\n true: {\n opacity: 0,\n pointerEvents: 'none',\n },\n false: {\n pointerEvents: 'auto',\n },\n // TODO still have as const bug\n } as const,\n },\n})\n\nexport type SheetOverlayProps = GetProps<typeof SheetOverlayFrame>\n\nexport const SheetOverlay = SheetOverlayFrame.extractable(\n ({ __scopeSheet, ...props }: SheetScopedProps<SheetOverlayProps>) => {\n const context = useSheetContext(SHEET_OVERLAY_NAME, __scopeSheet)\n return (\n <SheetOverlayFrame\n closed={!context.open || context.hidden}\n {...props}\n onPress={mergeEvent(\n props.onPress,\n context.dismissOnOverlayPress\n ? () => {\n context.setOpen(false)\n }\n : undefined\n )}\n />\n )\n }\n)\n\n/* -------------------------------------------------------------------------------------------------\n * Sheet\n * -----------------------------------------------------------------------------------------------*/\n\nconst selectionStyleSheet = isClient ? document.createElement('style') : null\nif (selectionStyleSheet) {\n document.head.appendChild(selectionStyleSheet)\n}\n\nexport const SheetFrameFrame = styled(YStack, {\n name: SHEET_NAME,\n flex: 1,\n backgroundColor: '$background',\n borderTopLeftRadius: '$4',\n borderTopRightRadius: '$4',\n width: '100%',\n maxHeight: '100%',\n overflow: 'hidden',\n pointerEvents: 'auto',\n})\n\nexport const SheetFrame = SheetFrameFrame.extractable(\n forwardRef(({ __scopeSheet, ...props }: SheetScopedProps<YStackProps>, forwardedRef) => {\n const context = useSheetContext(SHEET_NAME, __scopeSheet)\n const composedContentRef = useComposedRefs(forwardedRef, context.contentRef)\n return <SheetFrameFrame ref={composedContentRef} {...props} />\n })\n)\n\n// set all the way off screen\nconst HIDDEN_SIZE = 10_000\n\nexport const Sheet = withStaticProperties(\n themeable(\n forwardRef<View, SheetProps>(function Sheet(props, ref) {\n const {\n __scopeSheet,\n snapPoints: snapPointsProp = [80],\n open: openProp,\n defaultOpen,\n children: childrenProp,\n position: positionProp,\n onChangePosition,\n onChangeOpen,\n defaultPosition,\n dismissOnOverlayPress = true,\n animationConfig,\n dismissOnSnapToBottom = false,\n disableDrag: disableDragProp,\n modal = false,\n handleDisableScroll = true,\n } = props\n\n if (process.env.NODE_ENV === 'development') {\n if (snapPointsProp.some((p) => p < 0 || p > 100)) {\n console.warn(\n `\u26A0\uFE0F Invalid snapPoint given, snapPoints must be between 0 and 100, equal to percent height of frame`\n )\n }\n }\n\n // allows for sheets to be controlled by other components\n const controller = useContext(SheetControllerContext)\n const isHidden = controller?.hidden || false\n const disableDrag = disableDragProp ?? controller?.disableDrag\n const themeName = useThemeName()\n const contentRef = React.useRef<TamaguiElement>(null)\n const scrollBridge = useConstant<ScrollBridge>(() => ({\n enabled: false,\n y: 0,\n paneY: 0,\n paneMinY: 0,\n scrollStartY: -1,\n drag: () => {},\n release: () => {},\n scrollLock: false,\n }))\n\n const onChangeOpenInternal = (val: boolean) => {\n controller?.onChangeOpen?.(val)\n onChangeOpen?.(val)\n }\n\n const [open, setOpen] = useControllableState({\n prop: controller?.open ?? openProp,\n defaultProp: defaultOpen || true,\n onChange: onChangeOpenInternal,\n strategy: 'most-recent-wins',\n })\n\n const [frameSize, setFrameSize] = useState<number>(0)\n\n const snapPoints = useMemo(\n () => (dismissOnSnapToBottom ? [...snapPointsProp, 0] : snapPointsProp),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [JSON.stringify(snapPointsProp), dismissOnSnapToBottom]\n )\n\n // lets set -1 to be always the \"open = false\" position\n const [position_, setPosition_] = useControllableState({\n prop: positionProp,\n defaultProp: defaultPosition || (open ? 0 : -1),\n onChange: onChangePosition,\n strategy: 'most-recent-wins',\n })\n const position = open === false ? -1 : position_\n\n // reset position to fully open on re-open after dismissOnSnapToBottom\n if (open && dismissOnSnapToBottom && position === snapPoints.length - 1) {\n setPosition_(0)\n }\n\n const setPosition = useCallback(\n (next: number) => {\n // close on dismissOnSnapToBottom (and set position so it animates)\n if (dismissOnSnapToBottom && next === snapPoints.length - 1) {\n setOpen(false)\n } else {\n setPosition_(next)\n }\n },\n [dismissOnSnapToBottom, snapPoints.length, setPosition_, setOpen]\n )\n\n const positionValue = useRef<Animated.Value>()\n if (!positionValue.current) {\n positionValue.current = new Animated.Value(HIDDEN_SIZE)\n }\n\n const [isResizing, setIsResizing] = useState(true)\n useIsomorphicLayoutEffect(() => {\n if (!isResizing) {\n setIsResizing(true)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [modal])\n\n const spring = useRef<Animated.CompositeAnimation | null>(null)\n function stopSpring() {\n spring.current?.stop()\n spring.current = null\n if (scrollBridge.onFinishAnimate) {\n scrollBridge.onFinishAnimate()\n scrollBridge.onFinishAnimate = undefined\n }\n }\n\n // open must set position\n const shouldSetPositionOpen = open && position < 0\n useEffect(() => {\n if (shouldSetPositionOpen) {\n setPosition(0)\n }\n }, [setPosition, shouldSetPositionOpen])\n\n const positions = useMemo(\n () => snapPoints.map((point) => getPercentSize(point, frameSize)),\n [frameSize, snapPoints]\n )\n\n const animateTo = useEvent((position: number) => {\n const current = positionValue.current\n if (isHidden && open) return\n if (!current) return\n if (frameSize === 0) return\n const hiddenValue = frameSize === 0 ? HIDDEN_SIZE : frameSize\n const toValue = isHidden || position === -1 ? hiddenValue : positions[position]\n if (at.current === toValue) return\n stopSpring()\n if (isHidden || isResizing) {\n if (isResizing) {\n setIsResizing(false)\n }\n Animated.timing(current, {\n useNativeDriver: !isWeb,\n toValue,\n duration: 0,\n }).start()\n at.current = toValue\n return\n }\n // dont bounce on initial measure to bottom\n const overshootClamping = at.current === HIDDEN_SIZE\n spring.current = Animated.spring(current, {\n useNativeDriver: !isWeb,\n toValue,\n overshootClamping,\n ...animationConfig,\n })\n spring.current.start(({ finished }) => {\n if (finished) {\n stopSpring()\n }\n })\n })\n\n useIsomorphicLayoutEffect(() => {\n animateTo(position)\n }, [isHidden, frameSize, position, animateTo])\n\n // native only fix\n const at = useRef(0)\n useEffect(() => {\n positionValue.current!.addListener(({ value }) => {\n at.current = value\n scrollBridge.paneY = value\n })\n return () => {\n positionValue.current!.removeAllListeners()\n }\n }, [])\n\n const panResponder = useMemo(\n () => {\n if (disableDrag) return\n if (!frameSize) return\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const pos = positionValue.current!\n const minY = positions[0]\n scrollBridge.paneMinY = minY\n let startY = at.current\n\n function makeUnselectable(val: boolean) {\n if (!selectionStyleSheet) return\n if (!val) {\n selectionStyleSheet.innerText = ``\n } else {\n selectionStyleSheet.innerText = `:root * { user-select: none !important; -webkit-user-select: none !important; }`\n }\n }\n\n const release = ({ vy, dragAt }: { dragAt: number; vy: number }) => {\n isExternalDrag = false\n previouslyScrolling = false\n makeUnselectable(false)\n const at = dragAt + startY\n // seems liky vy goes up to about 4 at the very most (+ is down, - is up)\n // lets base our multiplier on the total layout height\n const end = at + frameSize * vy * 0.2\n let closestPoint = 0\n let dist = Infinity\n for (let i = 0; i < positions.length; i++) {\n const position = positions[i]\n const curDist = end > position ? end - position : position - end\n if (curDist < dist) {\n dist = curDist\n closestPoint = i\n }\n }\n // have to call both because state may not change but need to snap back\n setPosition(closestPoint)\n animateTo(closestPoint)\n }\n\n const finish = (_e: GestureResponderEvent, state: PanResponderGestureState) => {\n release({\n vy: state.vy,\n dragAt: state.dy,\n })\n }\n\n let previouslyScrolling = false\n\n const onMoveShouldSet = (_e: GestureResponderEvent, { dy }: PanResponderGestureState) => {\n const isScrolled = scrollBridge.y !== 0\n if (isScrolled) {\n previouslyScrolling = true\n return false\n }\n if (previouslyScrolling) {\n previouslyScrolling = false\n return true\n }\n const isDraggingUp = dy < 0\n if (!isScrolled && isDraggingUp) {\n return false\n }\n // we could do some detection of other touchables and cancel here..\n return Math.abs(dy) > 8\n }\n\n const grant = () => {\n makeUnselectable(true)\n stopSpring()\n startY = at.current\n }\n\n let isExternalDrag = false\n\n function setPositionValue(next: number) {\n // useful to debug any \"jumping\"\n // if (process.env.NODE_ENV === 'development') {\n // const moveAmt = Math.abs(pos['_value'] - next)\n // if (moveAmt > 50) {\n // console.warn('!!!!!!!!!!!!jump!', moveAmt)\n // // debugger\n // }\n // }\n pos.setValue(next)\n }\n\n scrollBridge.drag = (dy) => {\n if (!isExternalDrag) {\n isExternalDrag = true\n grant()\n }\n const to = dy + startY\n setPositionValue(resisted(to, minY))\n }\n\n scrollBridge.release = release\n\n return PanResponder.create({\n onMoveShouldSetPanResponder: onMoveShouldSet,\n onPanResponderGrant: grant,\n onPanResponderMove: (_e, { dy }) => {\n const to = dy + startY\n setPositionValue(resisted(to, minY))\n },\n onPanResponderEnd: finish,\n onPanResponderTerminate: finish,\n onPanResponderRelease: finish,\n })\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [disableDrag, animateTo, frameSize, positions, setPosition]\n )\n\n let handleComponent: React.ReactElement | null = null\n let overlayComponent: React.ReactElement | null = null\n let frameComponent: React.ReactElement | null = null\n\n // TODO do more radix-like and don't require direct children descendents\n React.Children.forEach(childrenProp, (child) => {\n if (isValidElement(child)) {\n const name = child.type?.['staticConfig']?.componentName\n switch (name) {\n case 'SheetHandle':\n handleComponent = child\n break\n case 'Sheet':\n frameComponent = child\n break\n case 'SheetOverlay':\n overlayComponent = child\n break\n default:\n console.warn('Warning: passed invalid child to Sheet', child)\n }\n }\n })\n\n const preventShown = controller?.hidden && controller?.open\n\n if (preventShown) {\n return null\n }\n\n const translateY = frameSize === 0 ? HIDDEN_SIZE : positionValue.current\n\n const contents = (\n <SheetProvider\n modal={modal}\n contentRef={contentRef}\n dismissOnOverlayPress={dismissOnOverlayPress}\n dismissOnSnapToBottom={dismissOnSnapToBottom}\n open={open}\n hidden={isHidden}\n scope={__scopeSheet}\n position={position}\n snapPoints={snapPoints}\n setPosition={setPosition}\n setOpen={setOpen}\n scrollBridge={scrollBridge}\n >\n {isResizing ? null : overlayComponent}\n\n <Animated.View\n ref={ref}\n {...panResponder?.panHandlers}\n onLayout={(e) => {\n const next = e.nativeEvent.layout.height\n setFrameSize((prev) => {\n const isBigChange = Math.abs(prev - next) > 50\n setIsResizing(isBigChange)\n return next\n })\n }}\n pointerEvents={open ? 'auto' : 'none'}\n style={{\n position: 'absolute',\n zIndex: 10,\n width: '100%',\n height: '100%',\n transform: [{ translateY }],\n }}\n >\n {handleComponent}\n\n <RemoveScroll\n enabled={open && modal && handleDisableScroll}\n as={Slot}\n allowPinchZoom\n shards={[contentRef]}\n // causes lots of bugs on touch web on site\n removeScrollBar={false}\n >\n {isResizing ? null : frameComponent}\n </RemoveScroll>\n </Animated.View>\n </SheetProvider>\n )\n\n if (modal) {\n return (\n <Portal>\n <Theme name={themeName}>{contents}</Theme>\n </Portal>\n )\n }\n\n return contents\n })\n ),\n {\n Handle: SheetHandle,\n Frame: SheetFrame,\n Overlay: SheetOverlay,\n ScrollView: SheetScrollView,\n }\n)\n\n/* -------------------------------------------------------------------------------------------------*/\n\nfunction getPercentSize(point?: number, frameSize?: number) {\n if (!frameSize) return 0\n if (point === undefined) {\n console.warn(`No snapPoint`)\n return 0\n }\n const pct = point / 100\n const next = frameSize - pct * frameSize\n return next\n}\n\nfunction resisted(y: number, minY: number, maxOverflow = 25) {\n if (y < minY) {\n const past = minY - y\n const pctPast = Math.min(maxOverflow, past) / maxOverflow\n const diminishBy = 1.1 - Math.pow(0.1, pctPast)\n const extra = -diminishBy * maxOverflow\n return minY + extra\n }\n return y\n}\n\ntype SheetControllerContextValue = {\n disableDrag?: boolean\n open?: boolean\n // hide without \"closing\" to prevent re-animation when shown again\n hidden?: boolean\n onChangeOpen?: React.Dispatch<React.SetStateAction<boolean>> | ((val: boolean) => void)\n}\n\nconst SheetControllerContext = createContext<SheetControllerContextValue | null>(null)\n\nexport const SheetController = ({\n children,\n onChangeOpen: onChangeOpenProp,\n ...value\n}: Partial<SheetControllerContextValue> & { children?: React.ReactNode }) => {\n const onChangeOpen = useEvent(onChangeOpenProp)\n\n const memoValue = useMemo(\n () => ({\n open: value.open,\n hidden: value.hidden,\n disableDrag: value.disableDrag,\n onChangeOpen,\n }),\n [onChangeOpen, value.open, value.hidden, value.disableDrag]\n )\n\n return (\n <SheetControllerContext.Provider value={memoValue}>{children}</SheetControllerContext.Provider>\n )\n}\n"],
|
|
5
|
-
"mappings": "AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWA;
|
|
4
|
+
"sourcesContent": ["import { useComposedRefs } from '@tamagui/compose-refs'\nimport {\n GetProps,\n Slot,\n TamaguiElement,\n Theme,\n getAnimationDriver,\n isClient,\n mergeEvent,\n styled,\n themeable,\n useConstant,\n useEvent,\n useIsomorphicLayoutEffect,\n useThemeName,\n withStaticProperties,\n} from '@tamagui/core'\nimport { Portal } from '@tamagui/portal'\nimport { RemoveScroll } from '@tamagui/remove-scroll'\nimport { XStack, XStackProps, YStack, YStackProps } from '@tamagui/stacks'\nimport { useControllableState } from '@tamagui/use-controllable-state'\nimport React, {\n createContext,\n forwardRef,\n isValidElement,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { GestureResponderEvent, PanResponder, PanResponderGestureState, View } from 'react-native'\n\nimport { SHEET_HANDLE_NAME, SHEET_NAME } from './SHEET_HANDLE_NAME'\nimport { SheetProvider, useSheetContext } from './SheetContext'\nimport { SheetScrollView } from './SheetScrollView'\nimport { ScrollBridge, SheetProps, SheetScopedProps } from './types'\n\nexport { createSheetScope } from './SheetContext'\n\n/* -------------------------------------------------------------------------------------------------\n * SheetHandle\n * -----------------------------------------------------------------------------------------------*/\n\nexport const SheetHandleFrame = styled(XStack, {\n name: SHEET_HANDLE_NAME,\n height: 10,\n borderRadius: 100,\n backgroundColor: '$background',\n zIndex: 10,\n marginHorizontal: '35%',\n marginBottom: '$2',\n opacity: 0.5,\n\n hoverStyle: {\n opacity: 0.7,\n },\n\n variants: {\n open: {\n true: {\n pointerEvents: 'auto',\n },\n false: {\n opacity: 0,\n pointerEvents: 'none',\n },\n },\n } as const,\n})\n\nexport const SheetHandle = SheetHandleFrame.extractable(\n ({ __scopeSheet, ...props }: SheetScopedProps<XStackProps>) => {\n const context = useSheetContext(SHEET_HANDLE_NAME, __scopeSheet)\n return (\n <SheetHandleFrame\n onPress={() => {\n // don't toggle to the bottom snap position when dismissOnSnapToBottom set\n const max = context.snapPoints.length + (context.dismissOnSnapToBottom ? -1 : 0)\n const nextPos = (context.position + 1) % max\n context.setPosition(nextPos)\n }}\n open={context.open}\n {...props}\n />\n )\n }\n)\n\n/* -------------------------------------------------------------------------------------------------\n * SheetOverlay\n * -----------------------------------------------------------------------------------------------*/\n\nconst SHEET_OVERLAY_NAME = 'SheetOverlay'\n\nexport const SheetOverlayFrame = styled(YStack, {\n name: SHEET_OVERLAY_NAME,\n // TODO this should be $background without opacity and just customized by theme\n backgroundColor: '$color',\n fullscreen: true,\n opacity: 0.2,\n zIndex: 0,\n\n variants: {\n closed: {\n true: {\n opacity: 0,\n pointerEvents: 'none',\n },\n false: {\n pointerEvents: 'auto',\n },\n // TODO still have as const bug\n } as const,\n },\n})\n\nexport type SheetOverlayProps = GetProps<typeof SheetOverlayFrame>\n\nexport const SheetOverlay = SheetOverlayFrame.extractable(\n ({ __scopeSheet, ...props }: SheetScopedProps<SheetOverlayProps>) => {\n const context = useSheetContext(SHEET_OVERLAY_NAME, __scopeSheet)\n return (\n <SheetOverlayFrame\n closed={!context.open || context.hidden}\n {...props}\n onPress={mergeEvent(\n props.onPress,\n context.dismissOnOverlayPress\n ? () => {\n context.setOpen(false)\n }\n : undefined\n )}\n />\n )\n }\n)\n\n/* -------------------------------------------------------------------------------------------------\n * Sheet\n * -----------------------------------------------------------------------------------------------*/\n\nconst selectionStyleSheet = isClient ? document.createElement('style') : null\nif (selectionStyleSheet) {\n document.head.appendChild(selectionStyleSheet)\n}\n\nexport const SheetFrameFrame = styled(YStack, {\n name: SHEET_NAME,\n flex: 1,\n backgroundColor: '$background',\n borderTopLeftRadius: '$4',\n borderTopRightRadius: '$4',\n width: '100%',\n maxHeight: '100%',\n overflow: 'hidden',\n pointerEvents: 'auto',\n})\n\nexport const SheetFrame = SheetFrameFrame.extractable(\n forwardRef(({ __scopeSheet, ...props }: SheetScopedProps<YStackProps>, forwardedRef) => {\n const context = useSheetContext(SHEET_NAME, __scopeSheet)\n const composedContentRef = useComposedRefs(forwardedRef, context.contentRef)\n return <SheetFrameFrame ref={composedContentRef} {...props} />\n })\n)\n\n// set all the way off screen\nconst HIDDEN_SIZE = 10_000\n\nexport const Sheet = withStaticProperties(\n themeable(\n forwardRef<View, SheetProps>(function Sheet(props, ref) {\n const {\n __scopeSheet,\n snapPoints: snapPointsProp = [80],\n open: openProp,\n defaultOpen,\n children: childrenProp,\n position: positionProp,\n onChangePosition,\n onChangeOpen,\n defaultPosition,\n dismissOnOverlayPress = true,\n animationConfig,\n dismissOnSnapToBottom = false,\n disableDrag: disableDragProp,\n modal = false,\n handleDisableScroll = true,\n } = props\n\n if (process.env.NODE_ENV === 'development') {\n if (snapPointsProp.some((p) => p < 0 || p > 100)) {\n // eslint-disable-next-line no-console\n console.warn(\n `\u26A0\uFE0F Invalid snapPoint given, snapPoints must be between 0 and 100, equal to percent height of frame`\n )\n }\n }\n\n const driver = getAnimationDriver()\n if (!driver) {\n throw new Error(`Must set animations in tamagui.config.ts`)\n }\n\n // allows for sheets to be controlled by other components\n const controller = useContext(SheetControllerContext)\n const isHidden = controller?.hidden || false\n const disableDrag = disableDragProp ?? controller?.disableDrag\n const themeName = useThemeName()\n const contentRef = React.useRef<TamaguiElement>(null)\n const scrollBridge = useConstant<ScrollBridge>(() => ({\n enabled: false,\n y: 0,\n paneY: 0,\n paneMinY: 0,\n scrollStartY: -1,\n drag: () => {},\n release: () => {},\n scrollLock: false,\n }))\n\n const onChangeOpenInternal = (val: boolean) => {\n controller?.onChangeOpen?.(val)\n onChangeOpen?.(val)\n }\n\n const [open, setOpen] = useControllableState({\n prop: controller?.open ?? openProp,\n defaultProp: defaultOpen || true,\n onChange: onChangeOpenInternal,\n strategy: 'most-recent-wins',\n })\n\n const [frameSize, setFrameSize] = useState<number>(0)\n\n const snapPoints = useMemo(\n () => (dismissOnSnapToBottom ? [...snapPointsProp, 0] : snapPointsProp),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [JSON.stringify(snapPointsProp), dismissOnSnapToBottom]\n )\n\n // lets set -1 to be always the \"open = false\" position\n const [position_, setPosition_] = useControllableState({\n prop: positionProp,\n defaultProp: defaultPosition || (open ? 0 : -1),\n onChange: onChangePosition,\n strategy: 'most-recent-wins',\n })\n const position = open === false ? -1 : position_\n\n // reset position to fully open on re-open after dismissOnSnapToBottom\n if (open && dismissOnSnapToBottom && position === snapPoints.length - 1) {\n setPosition_(0)\n }\n\n const setPosition = useCallback(\n (next: number) => {\n // close on dismissOnSnapToBottom (and set position so it animates)\n if (dismissOnSnapToBottom && next === snapPoints.length - 1) {\n setOpen(false)\n } else {\n setPosition_(next)\n }\n },\n [dismissOnSnapToBottom, snapPoints.length, setPosition_, setOpen]\n )\n\n const animatedNumber = driver.useAnimatedNumber(HIDDEN_SIZE)\n\n // native only fix\n const at = useRef(0)\n driver.useAnimatedNumberReaction(animatedNumber, (value) => {\n at.current = value\n scrollBridge.paneY = value\n })\n\n const [isResizing, setIsResizing] = useState(true)\n useIsomorphicLayoutEffect(() => {\n if (!isResizing) {\n setIsResizing(true)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [modal])\n\n function stopSpring() {\n animatedNumber.stop()\n if (scrollBridge.onFinishAnimate) {\n scrollBridge.onFinishAnimate()\n scrollBridge.onFinishAnimate = undefined\n }\n }\n\n // open must set position\n const shouldSetPositionOpen = open && position < 0\n useEffect(() => {\n if (shouldSetPositionOpen) {\n setPosition(0)\n }\n }, [setPosition, shouldSetPositionOpen])\n\n const positions = useMemo(\n () => snapPoints.map((point) => getPercentSize(point, frameSize)),\n [frameSize, snapPoints]\n )\n\n const animateTo = useEvent((position: number) => {\n const current = animatedNumber.getValue()\n if (isHidden && open) return\n if (!current) return\n if (frameSize === 0) return\n const hiddenValue = frameSize === 0 ? HIDDEN_SIZE : frameSize\n const toValue = isHidden || position === -1 ? hiddenValue : positions[position]\n if (at.current === toValue) return\n stopSpring()\n if (isHidden || isResizing) {\n if (isResizing) {\n setIsResizing(false)\n }\n animatedNumber.setValue(toValue, {\n type: 'timing',\n duration: 0,\n })\n at.current = toValue\n return\n }\n // dont bounce on initial measure to bottom\n const overshootClamping = at.current === HIDDEN_SIZE\n animatedNumber.setValue(toValue, {\n ...animationConfig,\n type: 'spring',\n overshootClamping,\n })\n })\n\n useIsomorphicLayoutEffect(() => {\n animateTo(position)\n }, [isHidden, frameSize, position, animateTo])\n\n const panResponder = useMemo(\n () => {\n if (disableDrag) return\n if (!frameSize) return\n\n const minY = positions[0]\n scrollBridge.paneMinY = minY\n let startY = at.current\n\n function makeUnselectable(val: boolean) {\n if (!selectionStyleSheet) return\n if (!val) {\n selectionStyleSheet.innerText = ``\n } else {\n selectionStyleSheet.innerText = `:root * { user-select: none !important; -webkit-user-select: none !important; }`\n }\n }\n\n const release = ({ vy, dragAt }: { dragAt: number; vy: number }) => {\n isExternalDrag = false\n previouslyScrolling = false\n makeUnselectable(false)\n const at = dragAt + startY\n // seems liky vy goes up to about 4 at the very most (+ is down, - is up)\n // lets base our multiplier on the total layout height\n const end = at + frameSize * vy * 0.2\n let closestPoint = 0\n let dist = Infinity\n for (let i = 0; i < positions.length; i++) {\n const position = positions[i]\n const curDist = end > position ? end - position : position - end\n if (curDist < dist) {\n dist = curDist\n closestPoint = i\n }\n }\n // have to call both because state may not change but need to snap back\n setPosition(closestPoint)\n animateTo(closestPoint)\n }\n\n const finish = (_e: GestureResponderEvent, state: PanResponderGestureState) => {\n release({\n vy: state.vy,\n dragAt: state.dy,\n })\n }\n\n let previouslyScrolling = false\n\n const onMoveShouldSet = (_e: GestureResponderEvent, { dy }: PanResponderGestureState) => {\n const isScrolled = scrollBridge.y !== 0\n if (isScrolled) {\n previouslyScrolling = true\n return false\n }\n if (previouslyScrolling) {\n previouslyScrolling = false\n return true\n }\n const isDraggingUp = dy < 0\n const isAtTop = scrollBridge.paneY <= scrollBridge.paneMinY\n // prevent drag once at top and pulling up\n if (isAtTop) {\n if (!isScrolled && isDraggingUp) {\n return false\n }\n }\n // we could do some detection of other touchables and cancel here..\n return Math.abs(dy) > 8\n }\n\n const grant = () => {\n makeUnselectable(true)\n stopSpring()\n startY = at.current\n }\n\n let isExternalDrag = false\n\n scrollBridge.drag = (dy) => {\n if (!isExternalDrag) {\n isExternalDrag = true\n grant()\n }\n const to = dy + startY\n animatedNumber.setValue(resisted(to, minY), { type: 'direct' })\n }\n\n scrollBridge.release = release\n\n return PanResponder.create({\n onMoveShouldSetPanResponder: onMoveShouldSet,\n onPanResponderGrant: grant,\n onPanResponderMove: (_e, { dy }) => {\n const to = dy + startY\n animatedNumber.setValue(resisted(to, minY), { type: 'direct' })\n },\n onPanResponderEnd: finish,\n onPanResponderTerminate: finish,\n onPanResponderRelease: finish,\n })\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [disableDrag, animateTo, frameSize, positions, setPosition]\n )\n\n let handleComponent: React.ReactElement | null = null\n let overlayComponent: React.ReactElement | null = null\n let frameComponent: React.ReactElement | null = null\n\n // TODO do more radix-like and don't require direct children descendents\n React.Children.forEach(childrenProp, (child) => {\n if (isValidElement(child)) {\n const name = child.type?.['staticConfig']?.componentName\n switch (name) {\n case 'SheetHandle':\n handleComponent = child\n break\n case 'Sheet':\n frameComponent = child\n break\n case 'SheetOverlay':\n overlayComponent = child\n break\n default:\n // eslint-disable-next-line no-console\n console.warn('Warning: passed invalid child to Sheet', child)\n }\n }\n })\n\n const preventShown = controller?.hidden && controller?.open\n\n const animatedStyle = driver.useAnimatedNumberStyle(animatedNumber, (val) => {\n return {\n transform: [{ translateY: frameSize === 0 ? HIDDEN_SIZE : val }],\n }\n })\n\n if (preventShown) {\n return null\n }\n\n // temp until reanimated useAnimatedNumber fix\n const AnimatedView = driver['NumberView'] ?? driver.View\n\n const contents = (\n <SheetProvider\n modal={modal}\n contentRef={contentRef}\n dismissOnOverlayPress={dismissOnOverlayPress}\n dismissOnSnapToBottom={dismissOnSnapToBottom}\n open={open}\n hidden={isHidden}\n scope={__scopeSheet}\n position={position}\n snapPoints={snapPoints}\n setPosition={setPosition}\n setOpen={setOpen}\n scrollBridge={scrollBridge}\n >\n {isResizing ? null : overlayComponent}\n\n <AnimatedView\n ref={ref}\n {...panResponder?.panHandlers}\n onLayout={(e) => {\n const next = e.nativeEvent.layout.height\n setFrameSize((prev) => {\n const isBigChange = Math.abs(prev - next) > 50\n setIsResizing(isBigChange)\n return next\n })\n }}\n pointerEvents={open ? 'auto' : 'none'}\n style={[\n {\n position: 'absolute',\n zIndex: 10,\n width: '100%',\n height: '100%',\n },\n animatedStyle,\n ]}\n >\n {handleComponent}\n\n <RemoveScroll\n enabled={open && modal && handleDisableScroll}\n as={Slot}\n allowPinchZoom\n shards={[contentRef]}\n // causes lots of bugs on touch web on site\n removeScrollBar={false}\n >\n {isResizing ? null : frameComponent}\n </RemoveScroll>\n </AnimatedView>\n </SheetProvider>\n )\n\n if (modal) {\n return (\n <Portal>\n <Theme name={themeName}>{contents}</Theme>\n </Portal>\n )\n }\n\n return contents\n })\n ),\n {\n Handle: SheetHandle,\n Frame: SheetFrame,\n Overlay: SheetOverlay,\n ScrollView: SheetScrollView,\n }\n)\n\n/* -------------------------------------------------------------------------------------------------*/\n\nfunction getPercentSize(point?: number, frameSize?: number) {\n if (!frameSize) return 0\n if (point === undefined) {\n // eslint-disable-next-line no-console\n console.warn(`No snapPoint`)\n return 0\n }\n const pct = point / 100\n const next = Math.round(frameSize - pct * frameSize)\n return next\n}\n\nfunction resisted(y: number, minY: number, maxOverflow = 25) {\n if (y < minY) {\n const past = minY - y\n const pctPast = Math.min(maxOverflow, past) / maxOverflow\n const diminishBy = 1.1 - Math.pow(0.1, pctPast)\n const extra = -diminishBy * maxOverflow\n return minY + extra\n }\n return y\n}\n\ntype SheetControllerContextValue = {\n disableDrag?: boolean\n open?: boolean\n // hide without \"closing\" to prevent re-animation when shown again\n hidden?: boolean\n onChangeOpen?: React.Dispatch<React.SetStateAction<boolean>> | ((val: boolean) => void)\n}\n\nconst SheetControllerContext = createContext<SheetControllerContextValue | null>(null)\n\nexport const SheetController = ({\n children,\n onChangeOpen: onChangeOpenProp,\n ...value\n}: Partial<SheetControllerContextValue> & { children?: React.ReactNode }) => {\n const onChangeOpen = useEvent(onChangeOpenProp)\n\n const memoValue = useMemo(\n () => ({\n open: value.open,\n hidden: value.hidden,\n disableDrag: value.disableDrag,\n onChangeOpen,\n }),\n [onChangeOpen, value.open, value.hidden, value.disableDrag]\n )\n\n return (\n <SheetControllerContext.Provider value={memoValue}>{children}</SheetControllerContext.Provider>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { getAnimationDriver, useEvent } from "@tamagui/core";
|
|
2
|
+
import { useEffect, useRef } from "react";
|
|
3
|
+
import { Animated } from "react-native";
|
|
4
|
+
import {
|
|
5
|
+
useAnimatedReaction,
|
|
6
|
+
useAnimatedStyle,
|
|
7
|
+
useSharedValue
|
|
8
|
+
} from "react-native-reanimated";
|
|
9
|
+
function useAnimated() {
|
|
10
|
+
const driver = getAnimationDriver();
|
|
11
|
+
return {
|
|
12
|
+
View: driver.View,
|
|
13
|
+
Text: driver.Text
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function useAnimatedNumberReanimated(initial) {
|
|
17
|
+
const value = useSharedValue(initial);
|
|
18
|
+
return {
|
|
19
|
+
getInstance() {
|
|
20
|
+
return value;
|
|
21
|
+
},
|
|
22
|
+
getValue() {
|
|
23
|
+
return value.value;
|
|
24
|
+
},
|
|
25
|
+
setValue(next) {
|
|
26
|
+
value.value = next;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function useAnimatedNumberReactionReanimated(value, cb) {
|
|
31
|
+
useAnimatedReaction(() => value.getInstance().value, (result, prev) => {
|
|
32
|
+
if (result !== prev) {
|
|
33
|
+
cb(result);
|
|
34
|
+
}
|
|
35
|
+
}, [value]);
|
|
36
|
+
}
|
|
37
|
+
function useAnimatedNumberStyleReanimated(value, getStyle) {
|
|
38
|
+
return useAnimatedStyle(() => getStyle(value));
|
|
39
|
+
}
|
|
40
|
+
function useAnimatedNumber(initial) {
|
|
41
|
+
const value = useRef(null);
|
|
42
|
+
if (!value.current) {
|
|
43
|
+
value.current = new Animated.Value(initial);
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
getInstance() {
|
|
47
|
+
return value.current;
|
|
48
|
+
},
|
|
49
|
+
getValue() {
|
|
50
|
+
return value.current["_value"];
|
|
51
|
+
},
|
|
52
|
+
setValue(next) {
|
|
53
|
+
value.current.setValue(next);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function useAnimatedNumberReaction(value, cb) {
|
|
58
|
+
const onChange = useEvent((current) => {
|
|
59
|
+
cb(current.value);
|
|
60
|
+
});
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
const id = value.getInstance().addListener(onChange);
|
|
63
|
+
return () => {
|
|
64
|
+
value.getInstance().removeListener(id);
|
|
65
|
+
};
|
|
66
|
+
}, [value, onChange]);
|
|
67
|
+
}
|
|
68
|
+
function useAnimatedNumberStyle(value, getStyle) {
|
|
69
|
+
return getStyle(value);
|
|
70
|
+
}
|
|
71
|
+
export {
|
|
72
|
+
useAnimated,
|
|
73
|
+
useAnimatedNumber,
|
|
74
|
+
useAnimatedNumberReaction,
|
|
75
|
+
useAnimatedNumberReactionReanimated,
|
|
76
|
+
useAnimatedNumberReanimated,
|
|
77
|
+
useAnimatedNumberStyle,
|
|
78
|
+
useAnimatedNumberStyleReanimated
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=useAnimated.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/useAnimated.ts"],
|
|
4
|
+
"sourcesContent": ["import { getAnimationDriver, useEvent } from '@tamagui/core'\nimport { useEffect, useRef } from 'react'\nimport { Animated, TextStyle, ViewStyle } from 'react-native'\nimport {\n SharedValue,\n useAnimatedReaction,\n useAnimatedStyle,\n useSharedValue,\n} from 'react-native-reanimated'\n\nexport function useAnimated() {\n const driver = getAnimationDriver()\n\n return {\n View: driver.View,\n Text: driver.Text,\n }\n}\n\ntype UniversalAnimatedNumber<A> = {\n getInstance(): A\n getValue(): number\n setValue(next: number): void\n}\n\nexport function useAnimatedNumberReanimated(\n initial: number\n): UniversalAnimatedNumber<SharedValue<number>> {\n const value = useSharedValue(initial)\n\n return {\n getInstance() {\n return value\n },\n getValue() {\n return value.value\n },\n setValue(next: number) {\n value.value = next\n },\n }\n}\n\nexport function useAnimatedNumberReactionReanimated(\n value: UniversalAnimatedNumber<SharedValue<number>>,\n cb: (current: number) => void\n) {\n useAnimatedReaction(\n () => value.getInstance().value,\n (result, prev) => {\n if (result !== prev) {\n cb(result)\n }\n },\n [value]\n )\n}\n\nexport function useAnimatedNumberStyleReanimated<V extends UniversalAnimatedNumber<Animated.Value>>(\n value: V,\n getStyle: (value: V) => ViewStyle | TextStyle\n) {\n return useAnimatedStyle(() => getStyle(value))\n}\n\nexport function useAnimatedNumber(initial: number): UniversalAnimatedNumber<Animated.Value> {\n const value = useRef(null as any as Animated.Value)\n if (!value.current) {\n value.current = new Animated.Value(initial)\n }\n\n return {\n getInstance() {\n return value.current\n },\n getValue() {\n return value.current['_value']\n },\n setValue(next: number) {\n value.current.setValue(next)\n },\n }\n}\n\nexport function useAnimatedNumberReaction(\n value: UniversalAnimatedNumber<Animated.Value>,\n cb: (current: number) => void\n) {\n const onChange = useEvent((current) => {\n cb(current.value)\n })\n\n useEffect(() => {\n const id = value.getInstance().addListener(onChange)\n return () => {\n value.getInstance().removeListener(id)\n }\n }, [value, onChange])\n}\n\n// transform: [{ translateY }],\n\nexport function useAnimatedNumberStyle<V extends UniversalAnimatedNumber<Animated.Value>>(\n value: V,\n getStyle: (value: V) => ViewStyle | TextStyle\n) {\n return getStyle(value)\n}\n"],
|
|
5
|
+
"mappings": "AAAA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAOO,uBAAuB;AAC5B,QAAM,SAAS,mBAAmB;AAElC,SAAO;AAAA,IACL,MAAM,OAAO;AAAA,IACb,MAAM,OAAO;AAAA,EACf;AACF;AAQO,qCACL,SAC8C;AAC9C,QAAM,QAAQ,eAAe,OAAO;AAEpC,SAAO;AAAA,IACL,cAAc;AACZ,aAAO;AAAA,IACT;AAAA,IACA,WAAW;AACT,aAAO,MAAM;AAAA,IACf;AAAA,IACA,SAAS,MAAc;AACrB,YAAM,QAAQ;AAAA,IAChB;AAAA,EACF;AACF;AAEO,6CACL,OACA,IACA;AACA,sBACE,MAAM,MAAM,YAAY,EAAE,OAC1B,CAAC,QAAQ,SAAS;AAChB,QAAI,WAAW,MAAM;AACnB,SAAG,MAAM;AAAA,IACX;AAAA,EACF,GACA,CAAC,KAAK,CACR;AACF;AAEO,0CACL,OACA,UACA;AACA,SAAO,iBAAiB,MAAM,SAAS,KAAK,CAAC;AAC/C;AAEO,2BAA2B,SAA0D;AAC1F,QAAM,QAAQ,OAAO,IAA6B;AAClD,MAAI,CAAC,MAAM,SAAS;AAClB,UAAM,UAAU,IAAI,SAAS,MAAM,OAAO;AAAA,EAC5C;AAEA,SAAO;AAAA,IACL,cAAc;AACZ,aAAO,MAAM;AAAA,IACf;AAAA,IACA,WAAW;AACT,aAAO,MAAM,QAAQ;AAAA,IACvB;AAAA,IACA,SAAS,MAAc;AACrB,YAAM,QAAQ,SAAS,IAAI;AAAA,IAC7B;AAAA,EACF;AACF;AAEO,mCACL,OACA,IACA;AACA,QAAM,WAAW,SAAS,CAAC,YAAY;AACrC,OAAG,QAAQ,KAAK;AAAA,EAClB,CAAC;AAED,YAAU,MAAM;AACd,UAAM,KAAK,MAAM,YAAY,EAAE,YAAY,QAAQ;AACnD,WAAO,MAAM;AACX,YAAM,YAAY,EAAE,eAAe,EAAE;AAAA,IACvC;AAAA,EACF,GAAG,CAAC,OAAO,QAAQ,CAAC;AACtB;AAIO,gCACL,OACA,UACA;AACA,SAAO,SAAS,KAAK;AACvB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/sheet",
|
|
3
|
-
"version": "1.0.1-beta.
|
|
3
|
+
"version": "1.0.1-beta.142",
|
|
4
4
|
"sideEffects": [
|
|
5
5
|
"*.css"
|
|
6
6
|
],
|
|
@@ -22,12 +22,13 @@
|
|
|
22
22
|
"lint:fix": "yarn lint --fix"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@tamagui/
|
|
26
|
-
"@tamagui/
|
|
27
|
-
"@tamagui/
|
|
28
|
-
"@tamagui/
|
|
29
|
-
"@tamagui/
|
|
30
|
-
"@tamagui/
|
|
25
|
+
"@tamagui/animations-react-native": "^1.0.1-beta.142",
|
|
26
|
+
"@tamagui/compose-refs": "^1.0.1-beta.142",
|
|
27
|
+
"@tamagui/core": "^1.0.1-beta.142",
|
|
28
|
+
"@tamagui/create-context": "^1.0.1-beta.142",
|
|
29
|
+
"@tamagui/remove-scroll": "^1.0.1-beta.142",
|
|
30
|
+
"@tamagui/stacks": "^1.0.1-beta.142",
|
|
31
|
+
"@tamagui/use-controllable-state": "^1.0.1-beta.142"
|
|
31
32
|
},
|
|
32
33
|
"peerDependencies": {
|
|
33
34
|
"react": "*",
|
|
@@ -35,7 +36,7 @@
|
|
|
35
36
|
"react-native": "*"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
38
|
-
"@tamagui/build": "^1.0.1-beta.
|
|
39
|
+
"@tamagui/build": "^1.0.1-beta.142",
|
|
39
40
|
"react": "*",
|
|
40
41
|
"react-dom": "*",
|
|
41
42
|
"react-native": "*"
|