@tamagui/sheet 1.0.1-beta.113 → 1.0.1-beta.114
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 +126 -12
- package/dist/cjs/Sheet.js.map +2 -2
- package/dist/esm/Sheet.js +129 -14
- package/dist/esm/Sheet.js.map +2 -2
- package/dist/jsx/Sheet.js +121 -14
- package/dist/jsx/Sheet.js.map +2 -2
- package/package.json +8 -8
- package/src/Sheet.tsx +218 -50
- package/types/Sheet.d.ts +3 -1
- package/types/Sheet.d.ts.map +1 -1
package/dist/cjs/Sheet.js
CHANGED
|
@@ -29,6 +29,7 @@ __export(Sheet_exports, {
|
|
|
29
29
|
SheetHandleFrame: () => SheetHandleFrame,
|
|
30
30
|
SheetOverlay: () => SheetOverlay,
|
|
31
31
|
SheetOverlayFrame: () => SheetOverlayFrame,
|
|
32
|
+
SheetScrollView: () => SheetScrollView,
|
|
32
33
|
createSheetScope: () => createSheetScope
|
|
33
34
|
});
|
|
34
35
|
module.exports = __toCommonJS(Sheet_exports);
|
|
@@ -111,6 +112,70 @@ const SheetOverlay = SheetOverlayFrame.extractable(({ __scopeSheet, ...props })
|
|
|
111
112
|
} : void 0)
|
|
112
113
|
}));
|
|
113
114
|
});
|
|
115
|
+
const SHEET_SCROLL_VIEW_NAME = "SheetScrollView";
|
|
116
|
+
const SheetScrollView = (0, import_react.forwardRef)(({ __scopeSheet, ...props }, ref) => {
|
|
117
|
+
const { scrollBridge } = useSheetContext(SHEET_SCROLL_VIEW_NAME, __scopeSheet);
|
|
118
|
+
const [scrollEnabled, setScrollEnabled] = (0, import_react.useState)(true);
|
|
119
|
+
const state = (0, import_react.useRef)({
|
|
120
|
+
dy: 0,
|
|
121
|
+
dys: []
|
|
122
|
+
});
|
|
123
|
+
const release = () => {
|
|
124
|
+
setScrollEnabled(true);
|
|
125
|
+
const recentDys = state.current.dys.slice(-10);
|
|
126
|
+
const dist = recentDys.length ? recentDys.reduce((a, b, i) => a + b - (recentDys[i - 1] ?? recentDys[0]), 0) : 0;
|
|
127
|
+
const avgDy = dist / recentDys.length;
|
|
128
|
+
const vy = avgDy * 0.1;
|
|
129
|
+
state.current.dys = [];
|
|
130
|
+
scrollBridge.release({
|
|
131
|
+
dy: state.current.dy,
|
|
132
|
+
vy
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
return /* @__PURE__ */ import_react.default.createElement(import_react_native.ScrollView, {
|
|
136
|
+
ref,
|
|
137
|
+
onScrollBeginDrag: () => {
|
|
138
|
+
console.log("begin drag");
|
|
139
|
+
},
|
|
140
|
+
scrollEventThrottle: 16,
|
|
141
|
+
scrollEnabled,
|
|
142
|
+
onScroll: (e) => {
|
|
143
|
+
const { y } = e.nativeEvent.contentOffset;
|
|
144
|
+
scrollBridge.y = y;
|
|
145
|
+
if (y > 0) {
|
|
146
|
+
scrollBridge.scrollStartY = -1;
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
onResponderMove: (e) => {
|
|
150
|
+
const { pageY } = e.nativeEvent;
|
|
151
|
+
if (scrollBridge.y === 0) {
|
|
152
|
+
if (scrollBridge.scrollStartY === -1) {
|
|
153
|
+
scrollBridge.scrollStartY = pageY;
|
|
154
|
+
}
|
|
155
|
+
const dy = pageY - scrollBridge.scrollStartY;
|
|
156
|
+
if (dy <= 0) {
|
|
157
|
+
setScrollEnabled(true);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
setScrollEnabled(false);
|
|
161
|
+
scrollBridge.drag(dy);
|
|
162
|
+
state.current.dy = dy;
|
|
163
|
+
state.current.dys.push(dy);
|
|
164
|
+
if (state.current.dys.length > 100) {
|
|
165
|
+
state.current.dys = state.current.dys.slice(-10);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
onResponderRelease: release,
|
|
170
|
+
...props,
|
|
171
|
+
style: [
|
|
172
|
+
{
|
|
173
|
+
flex: 1
|
|
174
|
+
},
|
|
175
|
+
props.style
|
|
176
|
+
]
|
|
177
|
+
});
|
|
178
|
+
});
|
|
114
179
|
const selectionStyleSheet = import_core.isClient ? document.createElement("style") : null;
|
|
115
180
|
if (selectionStyleSheet) {
|
|
116
181
|
document.head.appendChild(selectionStyleSheet);
|
|
@@ -153,11 +218,25 @@ const Sheet = (0, import_core.withStaticProperties)((0, import_core.themeable)((
|
|
|
153
218
|
modal,
|
|
154
219
|
allowPinchZoom
|
|
155
220
|
} = props;
|
|
221
|
+
if (process.env.NODE_ENV === "development") {
|
|
222
|
+
if (snapPointsProp.some((p) => p < 0 || p > 100)) {
|
|
223
|
+
console.warn(`\u26A0\uFE0F Invalid snapPoint given, snapPoints must be between 0 and 100, equal to percent height of frame`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
156
226
|
const controller = (0, import_react.useContext)(SheetControllerContext);
|
|
157
227
|
const isHidden = (controller == null ? void 0 : controller.hidden) || false;
|
|
158
228
|
const disableDrag = disableDragProp ?? (controller == null ? void 0 : controller.disableDrag);
|
|
159
229
|
const themeName = (0, import_core.useThemeName)();
|
|
160
230
|
const contentRef = import_react.default.useRef(null);
|
|
231
|
+
const scrollBridge = (0, import_core.useConstant)(() => ({
|
|
232
|
+
enabled: false,
|
|
233
|
+
y: 0,
|
|
234
|
+
scrollStartY: -1,
|
|
235
|
+
drag: () => {
|
|
236
|
+
},
|
|
237
|
+
release: () => {
|
|
238
|
+
}
|
|
239
|
+
}));
|
|
161
240
|
const onChangeOpenInternal = (val) => {
|
|
162
241
|
var _a;
|
|
163
242
|
(_a = controller == null ? void 0 : controller.onChangeOpen) == null ? void 0 : _a.call(controller, val);
|
|
@@ -191,7 +270,7 @@ const Sheet = (0, import_core.withStaticProperties)((0, import_core.themeable)((
|
|
|
191
270
|
positionValue.current = new import_react_native.Animated.Value(HIDDEN_SIZE);
|
|
192
271
|
}
|
|
193
272
|
const [isResizing, setIsResizing] = (0, import_react.useState)(true);
|
|
194
|
-
(0,
|
|
273
|
+
(0, import_core.useIsomorphicLayoutEffect)(() => {
|
|
195
274
|
if (!isResizing) {
|
|
196
275
|
setIsResizing(true);
|
|
197
276
|
}
|
|
@@ -247,7 +326,7 @@ const Sheet = (0, import_core.withStaticProperties)((0, import_core.themeable)((
|
|
|
247
326
|
}
|
|
248
327
|
});
|
|
249
328
|
});
|
|
250
|
-
(0,
|
|
329
|
+
(0, import_core.useIsomorphicLayoutEffect)(() => {
|
|
251
330
|
animateTo(position);
|
|
252
331
|
}, [isHidden, frameSize, position, animateTo]);
|
|
253
332
|
const at = (0, import_react.useRef)(0);
|
|
@@ -276,7 +355,9 @@ const Sheet = (0, import_core.withStaticProperties)((0, import_core.themeable)((
|
|
|
276
355
|
selectionStyleSheet.innerText = `:root * { user-select: none !important; -webkit-user-select: none !important; }`;
|
|
277
356
|
}
|
|
278
357
|
}
|
|
279
|
-
const
|
|
358
|
+
const release = ({ vy, dy }) => {
|
|
359
|
+
isExternalDrag = false;
|
|
360
|
+
previouslyScrolling = false;
|
|
280
361
|
makeUnselectable(false);
|
|
281
362
|
const at2 = dy + startY;
|
|
282
363
|
const end = at2 + frameSize * vy * 0.33;
|
|
@@ -293,15 +374,45 @@ const Sheet = (0, import_core.withStaticProperties)((0, import_core.themeable)((
|
|
|
293
374
|
setPosition(closestPoint);
|
|
294
375
|
animateTo(closestPoint);
|
|
295
376
|
};
|
|
377
|
+
const finish = (_e, state) => {
|
|
378
|
+
release(state);
|
|
379
|
+
};
|
|
380
|
+
let previouslyScrolling = false;
|
|
381
|
+
const onMoveShouldSet = (_e, { dy }) => {
|
|
382
|
+
if (scrollBridge.y !== 0) {
|
|
383
|
+
previouslyScrolling = true;
|
|
384
|
+
return false;
|
|
385
|
+
}
|
|
386
|
+
if (scrollBridge.y === 0 && dy < 0) {
|
|
387
|
+
return false;
|
|
388
|
+
}
|
|
389
|
+
if (previouslyScrolling) {
|
|
390
|
+
previouslyScrolling = false;
|
|
391
|
+
return true;
|
|
392
|
+
}
|
|
393
|
+
return Math.abs(dy) > 8;
|
|
394
|
+
};
|
|
395
|
+
const grant = () => {
|
|
396
|
+
makeUnselectable(true);
|
|
397
|
+
stopSpring();
|
|
398
|
+
startY = at.current;
|
|
399
|
+
};
|
|
400
|
+
let isExternalDrag = false;
|
|
401
|
+
scrollBridge.drag = (dy) => {
|
|
402
|
+
if (!isExternalDrag) {
|
|
403
|
+
isExternalDrag = true;
|
|
404
|
+
grant();
|
|
405
|
+
}
|
|
406
|
+
const to = dy + startY;
|
|
407
|
+
pos.setValue(resisted(to, minY));
|
|
408
|
+
};
|
|
409
|
+
scrollBridge.release = release;
|
|
296
410
|
return import_react_native.PanResponder.create({
|
|
297
|
-
onMoveShouldSetPanResponder: (
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
onPanResponderGrant: () => {
|
|
301
|
-
makeUnselectable(true);
|
|
302
|
-
stopSpring();
|
|
303
|
-
startY = at.current;
|
|
411
|
+
onMoveShouldSetPanResponder: (...args) => {
|
|
412
|
+
const res = onMoveShouldSet(...args);
|
|
413
|
+
return res;
|
|
304
414
|
},
|
|
415
|
+
onPanResponderGrant: grant,
|
|
305
416
|
onPanResponderMove: (_e, { dy }) => {
|
|
306
417
|
const to = dy + startY;
|
|
307
418
|
pos.setValue(resisted(to, minY));
|
|
@@ -348,7 +459,8 @@ const Sheet = (0, import_core.withStaticProperties)((0, import_core.themeable)((
|
|
|
348
459
|
position,
|
|
349
460
|
snapPoints,
|
|
350
461
|
setPosition,
|
|
351
|
-
setOpen
|
|
462
|
+
setOpen,
|
|
463
|
+
scrollBridge
|
|
352
464
|
}, isResizing ? null : overlayComponent, isHidden ? null : handleComponent, /* @__PURE__ */ import_react.default.createElement(import_react_native.Animated.View, {
|
|
353
465
|
ref,
|
|
354
466
|
...panResponder == null ? void 0 : panResponder.panHandlers,
|
|
@@ -378,7 +490,8 @@ const Sheet = (0, import_core.withStaticProperties)((0, import_core.themeable)((
|
|
|
378
490
|
})), {
|
|
379
491
|
Handle: SheetHandle,
|
|
380
492
|
Frame: SheetFrame,
|
|
381
|
-
Overlay: SheetOverlay
|
|
493
|
+
Overlay: SheetOverlay,
|
|
494
|
+
ScrollView: SheetScrollView
|
|
382
495
|
});
|
|
383
496
|
function getPercentSize(point, frameSize) {
|
|
384
497
|
if (!frameSize)
|
|
@@ -428,6 +541,7 @@ const SheetController = ({
|
|
|
428
541
|
SheetHandleFrame,
|
|
429
542
|
SheetOverlay,
|
|
430
543
|
SheetOverlayFrame,
|
|
544
|
+
SheetScrollView,
|
|
431
545
|
createSheetScope
|
|
432
546
|
});
|
|
433
547
|
//# sourceMappingURL=Sheet.js.map
|
package/dist/cjs/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 useEvent,\n useThemeName,\n withStaticProperties,\n} from '@tamagui/core'\nimport { ScopedProps, createContextScope } from '@tamagui/create-context'\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 ReactNode,\n createContext,\n forwardRef,\n isValidElement,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\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\nconst SHEET_NAME = 'Sheet'\nconst SHEET_HANDLE_NAME = 'SheetHandle'\n\ntype RemoveScrollProps = React.ComponentProps<typeof RemoveScroll>\n\nexport type SheetProps = ScopedProps<\n {\n open?: boolean\n defaultOpen?: boolean\n onChangeOpen?: OpenChangeHandler\n position?: number\n defaultPosition?: number\n snapPoints?: number[]\n onChangePosition?: PositionChangeHandler\n children?: ReactNode\n dismissOnOverlayPress?: boolean\n dismissOnSnapToBottom?: boolean\n animationConfig?: Animated.SpringAnimationConfig\n disableDrag?: boolean\n modal?: boolean\n\n /**\n * @see https://github.com/theKashey/react-remove-scroll#usage\n */\n allowPinchZoom?: RemoveScrollProps['allowPinchZoom']\n },\n 'Sheet'\n>\n\ntype PositionChangeHandler = (position: number) => void\n\ntype OpenChangeHandler = ((open: boolean) => void) | React.Dispatch<React.SetStateAction<boolean>>\n\ntype SheetContextValue = Required<\n Pick<SheetProps, 'open' | 'position' | 'snapPoints' | 'dismissOnOverlayPress'>\n> & {\n hidden: boolean\n setPosition: PositionChangeHandler\n setOpen: React.Dispatch<React.SetStateAction<boolean>>\n allowPinchZoom: RemoveScrollProps['allowPinchZoom']\n contentRef: React.RefObject<TamaguiElement>\n dismissOnSnapToBottom: boolean\n}\n\nconst [createSheetContext, createSheetScope] = createContextScope(SHEET_NAME)\nconst [SheetProvider, useSheetContext] = createSheetContext<SheetContextValue>(\n SHEET_NAME,\n {} as any\n)\n\nexport const SheetHandleFrame = styled(XStack, {\n name: SHEET_HANDLE_NAME,\n height: 10,\n borderRadius: 100,\n backgroundColor: '$background',\n position: 'absolute',\n pointerEvents: 'auto',\n zIndex: 10,\n y: -18,\n top: 0,\n left: '35%',\n right: '35%',\n opacity: 0.5,\n\n hoverStyle: {\n opacity: 0.7,\n },\n})\n\ntype SheetScopedProps<A> = ScopedProps<A, 'Sheet'>\n\nexport const SheetHandle = SheetHandleFrame.extractable(\n ({ __scopeSheet, ...props }: SheetScopedProps<XStackProps>) => {\n const context = useSheetContext(SHEET_HANDLE_NAME, __scopeSheet)\n\n if (context.open === false) {\n return null\n }\n\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 {...props}\n />\n )\n }\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 <RemoveScroll\n enabled={context.open}\n as={Slot}\n allowPinchZoom={context.allowPinchZoom}\n shards={[context.contentRef]}\n // causes lots of bugs on touch web on site\n removeScrollBar={false}\n >\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 </RemoveScroll>\n )\n }\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>((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,\n allowPinchZoom,\n } = props\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\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: controller ? 'most-recent-wins' : 'prop-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 })\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 }\n setPosition_(next)\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 useLayoutEffect(() => {\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 }\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 useLayoutEffect(() => {\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 })\n return () => {\n positionValue.current!.removeAllListeners()\n }\n }, [])\n\n const panResponder = useMemo(() => {\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 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 finish = (_e: GestureResponderEvent, { vy, dy }: PanResponderGestureState) => {\n makeUnselectable(false)\n const at = dy + 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.33\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 return PanResponder.create({\n onMoveShouldSetPanResponder: (_e, { dy }) => {\n // we could do some detection of other touchables and cancel here..\n return Math.abs(dy) > 6\n },\n onPanResponderGrant: () => {\n makeUnselectable(true)\n stopSpring()\n startY = at.current\n },\n onPanResponderMove: (_e, { dy }) => {\n const to = dy + startY\n pos.setValue(resisted(to, minY))\n },\n onPanResponderEnd: finish,\n onPanResponderTerminate: finish,\n onPanResponderRelease: finish,\n })\n }, [disableDrag, animateTo, frameSize, positions, setPosition])\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 contents = (\n <SheetProvider\n contentRef={contentRef}\n dismissOnOverlayPress={dismissOnOverlayPress}\n dismissOnSnapToBottom={dismissOnSnapToBottom}\n allowPinchZoom={allowPinchZoom}\n open={open}\n hidden={isHidden}\n scope={__scopeSheet}\n position={position}\n snapPoints={snapPoints}\n setPosition={setPosition}\n setOpen={setOpen}\n >\n {isResizing ? null : overlayComponent}\n {/* no fancy hidden animation etc for handle for now */}\n {isHidden ? null : handleComponent}\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: frameSize === 0 ? HIDDEN_SIZE : positionValue.current }],\n }}\n >\n {isResizing ? null : frameComponent}\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 }\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\nexport { createSheetScope }\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAAgC;AAChC,
|
|
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 { ScopedProps, createContextScope } from '@tamagui/create-context'\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 ReactNode,\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 ScrollView,\n ScrollViewProps,\n View,\n} from 'react-native'\n\nconst SHEET_NAME = 'Sheet'\nconst SHEET_HANDLE_NAME = 'SheetHandle'\n\ntype RemoveScrollProps = React.ComponentProps<typeof RemoveScroll>\n\nexport type SheetProps = ScopedProps<\n {\n open?: boolean\n defaultOpen?: boolean\n onChangeOpen?: OpenChangeHandler\n position?: number\n defaultPosition?: number\n snapPoints?: number[]\n onChangePosition?: PositionChangeHandler\n children?: ReactNode\n dismissOnOverlayPress?: boolean\n dismissOnSnapToBottom?: boolean\n animationConfig?: Animated.SpringAnimationConfig\n disableDrag?: boolean\n modal?: boolean\n\n /**\n * @see https://github.com/theKashey/react-remove-scroll#usage\n */\n allowPinchZoom?: RemoveScrollProps['allowPinchZoom']\n },\n 'Sheet'\n>\n\ntype PositionChangeHandler = (position: number) => void\n\ntype OpenChangeHandler = ((open: boolean) => void) | React.Dispatch<React.SetStateAction<boolean>>\n\ntype ScrollBridge = {\n enabled: boolean\n y: number\n scrollStartY: number\n drag: (dy: number) => void\n release: (state: { dy: number; vy: number }) => void\n}\n\ntype SheetContextValue = Required<\n Pick<SheetProps, 'open' | 'position' | 'snapPoints' | 'dismissOnOverlayPress'>\n> & {\n hidden: boolean\n setPosition: PositionChangeHandler\n setOpen: React.Dispatch<React.SetStateAction<boolean>>\n allowPinchZoom: RemoveScrollProps['allowPinchZoom']\n contentRef: React.RefObject<TamaguiElement>\n dismissOnSnapToBottom: boolean\n scrollBridge: ScrollBridge\n}\n\nconst [createSheetContext, createSheetScope] = createContextScope(SHEET_NAME)\nconst [SheetProvider, useSheetContext] = createSheetContext<SheetContextValue>(\n SHEET_NAME,\n {} as any\n)\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 position: 'absolute',\n pointerEvents: 'auto',\n zIndex: 10,\n y: -18,\n top: 0,\n left: '35%',\n right: '35%',\n opacity: 0.5,\n\n hoverStyle: {\n opacity: 0.7,\n },\n})\n\ntype SheetScopedProps<A> = ScopedProps<A, 'Sheet'>\n\nexport const SheetHandle = SheetHandleFrame.extractable(\n ({ __scopeSheet, ...props }: SheetScopedProps<XStackProps>) => {\n const context = useSheetContext(SHEET_HANDLE_NAME, __scopeSheet)\n\n if (context.open === false) {\n return null\n }\n\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 {...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 <RemoveScroll\n enabled={context.open}\n as={Slot}\n allowPinchZoom={context.allowPinchZoom}\n shards={[context.contentRef]}\n // causes lots of bugs on touch web on site\n removeScrollBar={false}\n >\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 </RemoveScroll>\n )\n }\n)\n\n/* -------------------------------------------------------------------------------------------------\n * SheetScrollView\n * -----------------------------------------------------------------------------------------------*/\n\nconst SHEET_SCROLL_VIEW_NAME = 'SheetScrollView'\n\nexport const SheetScrollView = forwardRef<ScrollView, ScrollViewProps>(\n ({ __scopeSheet, ...props }: SheetScopedProps<ScrollViewProps>, ref) => {\n const { scrollBridge } = useSheetContext(SHEET_SCROLL_VIEW_NAME, __scopeSheet)\n const [scrollEnabled, setScrollEnabled] = useState(true)\n const state = useRef({\n dy: 0,\n // store a few recent dys to get velocity on release\n dys: [] as number[],\n })\n\n const release = () => {\n setScrollEnabled(true)\n const recentDys = state.current.dys.slice(-10)\n const dist = recentDys.length\n ? recentDys.reduce((a, b, i) => a + b - (recentDys[i - 1] ?? recentDys[0]), 0)\n : 0\n const avgDy = dist / recentDys.length\n const vy = avgDy * 0.1\n state.current.dys = []\n scrollBridge.release({\n dy: state.current.dy,\n vy,\n })\n }\n\n return (\n <ScrollView\n ref={ref}\n onScrollBeginDrag={() => {\n console.log('begin drag')\n }}\n scrollEventThrottle={16}\n scrollEnabled={scrollEnabled}\n onScroll={(e) => {\n const { y } = e.nativeEvent.contentOffset\n scrollBridge.y = y\n if (y > 0) {\n scrollBridge.scrollStartY = -1\n }\n }}\n onResponderMove={(e) => {\n const { pageY } = e.nativeEvent\n if (scrollBridge.y === 0) {\n if (scrollBridge.scrollStartY === -1) {\n scrollBridge.scrollStartY = pageY\n }\n const dy = pageY - scrollBridge.scrollStartY\n if (dy <= 0) {\n setScrollEnabled(true)\n return\n }\n setScrollEnabled(false)\n scrollBridge.drag(dy)\n state.current.dy = dy\n state.current.dys.push(dy)\n // only do every so often, cut down to 10 again\n if (state.current.dys.length > 100) {\n state.current.dys = state.current.dys.slice(-10)\n }\n }\n }}\n onResponderRelease={release}\n // todo release we can just grab the last dY and estimate vY using a sample of last dYs\n {...props}\n style={[\n {\n flex: 1,\n },\n props.style,\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>((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,\n allowPinchZoom,\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 scrollStartY: -1,\n drag: () => {},\n release: () => {},\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: controller ? 'most-recent-wins' : 'prop-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 })\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 }\n setPosition_(next)\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 }\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 })\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 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, dy }: { dy: number; vy: number }) => {\n isExternalDrag = false\n previouslyScrolling = false\n makeUnselectable(false)\n const at = dy + 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.33\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(state)\n }\n\n let previouslyScrolling = false\n\n const onMoveShouldSet = (_e: GestureResponderEvent, { dy }: PanResponderGestureState) => {\n if (scrollBridge.y !== 0) {\n previouslyScrolling = true\n return false\n }\n if (scrollBridge.y === 0 && dy < 0) {\n return false\n }\n if (previouslyScrolling) {\n previouslyScrolling = false\n return true\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 pos.setValue(resisted(to, minY))\n }\n\n scrollBridge.release = release\n\n return PanResponder.create({\n onMoveShouldSetPanResponder: (...args) => {\n const res = onMoveShouldSet(...args)\n // console.log('res', res, scrollBridge.y)\n return res\n },\n onPanResponderGrant: grant,\n onPanResponderMove: (_e, { dy }) => {\n const to = dy + startY\n pos.setValue(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 contents = (\n <SheetProvider\n contentRef={contentRef}\n dismissOnOverlayPress={dismissOnOverlayPress}\n dismissOnSnapToBottom={dismissOnSnapToBottom}\n allowPinchZoom={allowPinchZoom}\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 {/* no fancy hidden animation etc for handle for now */}\n {isHidden ? null : handleComponent}\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: frameSize === 0 ? HIDDEN_SIZE : positionValue.current }],\n }}\n >\n {isResizing ? null : frameComponent}\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\nexport { createSheetScope }\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/esm/Sheet.js
CHANGED
|
@@ -7,7 +7,9 @@ import {
|
|
|
7
7
|
mergeEvent,
|
|
8
8
|
styled,
|
|
9
9
|
themeable,
|
|
10
|
+
useConstant,
|
|
10
11
|
useEvent,
|
|
12
|
+
useIsomorphicLayoutEffect,
|
|
11
13
|
useThemeName,
|
|
12
14
|
withStaticProperties
|
|
13
15
|
} from "@tamagui/core";
|
|
@@ -23,14 +25,14 @@ import React, {
|
|
|
23
25
|
useCallback,
|
|
24
26
|
useContext,
|
|
25
27
|
useEffect,
|
|
26
|
-
useLayoutEffect,
|
|
27
28
|
useMemo,
|
|
28
29
|
useRef,
|
|
29
30
|
useState
|
|
30
31
|
} from "react";
|
|
31
32
|
import {
|
|
32
33
|
Animated,
|
|
33
|
-
PanResponder
|
|
34
|
+
PanResponder,
|
|
35
|
+
ScrollView
|
|
34
36
|
} from "react-native";
|
|
35
37
|
const SHEET_NAME = "Sheet";
|
|
36
38
|
const SHEET_HANDLE_NAME = "SheetHandle";
|
|
@@ -102,6 +104,70 @@ const SheetOverlay = SheetOverlayFrame.extractable(({ __scopeSheet, ...props })
|
|
|
102
104
|
} : void 0)
|
|
103
105
|
}));
|
|
104
106
|
});
|
|
107
|
+
const SHEET_SCROLL_VIEW_NAME = "SheetScrollView";
|
|
108
|
+
const SheetScrollView = forwardRef(({ __scopeSheet, ...props }, ref) => {
|
|
109
|
+
const { scrollBridge } = useSheetContext(SHEET_SCROLL_VIEW_NAME, __scopeSheet);
|
|
110
|
+
const [scrollEnabled, setScrollEnabled] = useState(true);
|
|
111
|
+
const state = useRef({
|
|
112
|
+
dy: 0,
|
|
113
|
+
dys: []
|
|
114
|
+
});
|
|
115
|
+
const release = () => {
|
|
116
|
+
setScrollEnabled(true);
|
|
117
|
+
const recentDys = state.current.dys.slice(-10);
|
|
118
|
+
const dist = recentDys.length ? recentDys.reduce((a, b, i) => a + b - (recentDys[i - 1] ?? recentDys[0]), 0) : 0;
|
|
119
|
+
const avgDy = dist / recentDys.length;
|
|
120
|
+
const vy = avgDy * 0.1;
|
|
121
|
+
state.current.dys = [];
|
|
122
|
+
scrollBridge.release({
|
|
123
|
+
dy: state.current.dy,
|
|
124
|
+
vy
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
return /* @__PURE__ */ React.createElement(ScrollView, {
|
|
128
|
+
ref,
|
|
129
|
+
onScrollBeginDrag: () => {
|
|
130
|
+
console.log("begin drag");
|
|
131
|
+
},
|
|
132
|
+
scrollEventThrottle: 16,
|
|
133
|
+
scrollEnabled,
|
|
134
|
+
onScroll: (e) => {
|
|
135
|
+
const { y } = e.nativeEvent.contentOffset;
|
|
136
|
+
scrollBridge.y = y;
|
|
137
|
+
if (y > 0) {
|
|
138
|
+
scrollBridge.scrollStartY = -1;
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
onResponderMove: (e) => {
|
|
142
|
+
const { pageY } = e.nativeEvent;
|
|
143
|
+
if (scrollBridge.y === 0) {
|
|
144
|
+
if (scrollBridge.scrollStartY === -1) {
|
|
145
|
+
scrollBridge.scrollStartY = pageY;
|
|
146
|
+
}
|
|
147
|
+
const dy = pageY - scrollBridge.scrollStartY;
|
|
148
|
+
if (dy <= 0) {
|
|
149
|
+
setScrollEnabled(true);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
setScrollEnabled(false);
|
|
153
|
+
scrollBridge.drag(dy);
|
|
154
|
+
state.current.dy = dy;
|
|
155
|
+
state.current.dys.push(dy);
|
|
156
|
+
if (state.current.dys.length > 100) {
|
|
157
|
+
state.current.dys = state.current.dys.slice(-10);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
onResponderRelease: release,
|
|
162
|
+
...props,
|
|
163
|
+
style: [
|
|
164
|
+
{
|
|
165
|
+
flex: 1
|
|
166
|
+
},
|
|
167
|
+
props.style
|
|
168
|
+
]
|
|
169
|
+
});
|
|
170
|
+
});
|
|
105
171
|
const selectionStyleSheet = isClient ? document.createElement("style") : null;
|
|
106
172
|
if (selectionStyleSheet) {
|
|
107
173
|
document.head.appendChild(selectionStyleSheet);
|
|
@@ -144,11 +210,25 @@ const Sheet = withStaticProperties(themeable(forwardRef((props, ref) => {
|
|
|
144
210
|
modal,
|
|
145
211
|
allowPinchZoom
|
|
146
212
|
} = props;
|
|
213
|
+
if (process.env.NODE_ENV === "development") {
|
|
214
|
+
if (snapPointsProp.some((p) => p < 0 || p > 100)) {
|
|
215
|
+
console.warn(`\u26A0\uFE0F Invalid snapPoint given, snapPoints must be between 0 and 100, equal to percent height of frame`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
147
218
|
const controller = useContext(SheetControllerContext);
|
|
148
219
|
const isHidden = (controller == null ? void 0 : controller.hidden) || false;
|
|
149
220
|
const disableDrag = disableDragProp ?? (controller == null ? void 0 : controller.disableDrag);
|
|
150
221
|
const themeName = useThemeName();
|
|
151
222
|
const contentRef = React.useRef(null);
|
|
223
|
+
const scrollBridge = useConstant(() => ({
|
|
224
|
+
enabled: false,
|
|
225
|
+
y: 0,
|
|
226
|
+
scrollStartY: -1,
|
|
227
|
+
drag: () => {
|
|
228
|
+
},
|
|
229
|
+
release: () => {
|
|
230
|
+
}
|
|
231
|
+
}));
|
|
152
232
|
const onChangeOpenInternal = (val) => {
|
|
153
233
|
var _a;
|
|
154
234
|
(_a = controller == null ? void 0 : controller.onChangeOpen) == null ? void 0 : _a.call(controller, val);
|
|
@@ -182,7 +262,7 @@ const Sheet = withStaticProperties(themeable(forwardRef((props, ref) => {
|
|
|
182
262
|
positionValue.current = new Animated.Value(HIDDEN_SIZE);
|
|
183
263
|
}
|
|
184
264
|
const [isResizing, setIsResizing] = useState(true);
|
|
185
|
-
|
|
265
|
+
useIsomorphicLayoutEffect(() => {
|
|
186
266
|
if (!isResizing) {
|
|
187
267
|
setIsResizing(true);
|
|
188
268
|
}
|
|
@@ -238,7 +318,7 @@ const Sheet = withStaticProperties(themeable(forwardRef((props, ref) => {
|
|
|
238
318
|
}
|
|
239
319
|
});
|
|
240
320
|
});
|
|
241
|
-
|
|
321
|
+
useIsomorphicLayoutEffect(() => {
|
|
242
322
|
animateTo(position);
|
|
243
323
|
}, [isHidden, frameSize, position, animateTo]);
|
|
244
324
|
const at = useRef(0);
|
|
@@ -267,7 +347,9 @@ const Sheet = withStaticProperties(themeable(forwardRef((props, ref) => {
|
|
|
267
347
|
selectionStyleSheet.innerText = `:root * { user-select: none !important; -webkit-user-select: none !important; }`;
|
|
268
348
|
}
|
|
269
349
|
}
|
|
270
|
-
const
|
|
350
|
+
const release = ({ vy, dy }) => {
|
|
351
|
+
isExternalDrag = false;
|
|
352
|
+
previouslyScrolling = false;
|
|
271
353
|
makeUnselectable(false);
|
|
272
354
|
const at2 = dy + startY;
|
|
273
355
|
const end = at2 + frameSize * vy * 0.33;
|
|
@@ -284,15 +366,45 @@ const Sheet = withStaticProperties(themeable(forwardRef((props, ref) => {
|
|
|
284
366
|
setPosition(closestPoint);
|
|
285
367
|
animateTo(closestPoint);
|
|
286
368
|
};
|
|
369
|
+
const finish = (_e, state) => {
|
|
370
|
+
release(state);
|
|
371
|
+
};
|
|
372
|
+
let previouslyScrolling = false;
|
|
373
|
+
const onMoveShouldSet = (_e, { dy }) => {
|
|
374
|
+
if (scrollBridge.y !== 0) {
|
|
375
|
+
previouslyScrolling = true;
|
|
376
|
+
return false;
|
|
377
|
+
}
|
|
378
|
+
if (scrollBridge.y === 0 && dy < 0) {
|
|
379
|
+
return false;
|
|
380
|
+
}
|
|
381
|
+
if (previouslyScrolling) {
|
|
382
|
+
previouslyScrolling = false;
|
|
383
|
+
return true;
|
|
384
|
+
}
|
|
385
|
+
return Math.abs(dy) > 8;
|
|
386
|
+
};
|
|
387
|
+
const grant = () => {
|
|
388
|
+
makeUnselectable(true);
|
|
389
|
+
stopSpring();
|
|
390
|
+
startY = at.current;
|
|
391
|
+
};
|
|
392
|
+
let isExternalDrag = false;
|
|
393
|
+
scrollBridge.drag = (dy) => {
|
|
394
|
+
if (!isExternalDrag) {
|
|
395
|
+
isExternalDrag = true;
|
|
396
|
+
grant();
|
|
397
|
+
}
|
|
398
|
+
const to = dy + startY;
|
|
399
|
+
pos.setValue(resisted(to, minY));
|
|
400
|
+
};
|
|
401
|
+
scrollBridge.release = release;
|
|
287
402
|
return PanResponder.create({
|
|
288
|
-
onMoveShouldSetPanResponder: (
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
onPanResponderGrant: () => {
|
|
292
|
-
makeUnselectable(true);
|
|
293
|
-
stopSpring();
|
|
294
|
-
startY = at.current;
|
|
403
|
+
onMoveShouldSetPanResponder: (...args) => {
|
|
404
|
+
const res = onMoveShouldSet(...args);
|
|
405
|
+
return res;
|
|
295
406
|
},
|
|
407
|
+
onPanResponderGrant: grant,
|
|
296
408
|
onPanResponderMove: (_e, { dy }) => {
|
|
297
409
|
const to = dy + startY;
|
|
298
410
|
pos.setValue(resisted(to, minY));
|
|
@@ -339,7 +451,8 @@ const Sheet = withStaticProperties(themeable(forwardRef((props, ref) => {
|
|
|
339
451
|
position,
|
|
340
452
|
snapPoints,
|
|
341
453
|
setPosition,
|
|
342
|
-
setOpen
|
|
454
|
+
setOpen,
|
|
455
|
+
scrollBridge
|
|
343
456
|
}, isResizing ? null : overlayComponent, isHidden ? null : handleComponent, /* @__PURE__ */ React.createElement(Animated.View, {
|
|
344
457
|
ref,
|
|
345
458
|
...panResponder == null ? void 0 : panResponder.panHandlers,
|
|
@@ -369,7 +482,8 @@ const Sheet = withStaticProperties(themeable(forwardRef((props, ref) => {
|
|
|
369
482
|
})), {
|
|
370
483
|
Handle: SheetHandle,
|
|
371
484
|
Frame: SheetFrame,
|
|
372
|
-
Overlay: SheetOverlay
|
|
485
|
+
Overlay: SheetOverlay,
|
|
486
|
+
ScrollView: SheetScrollView
|
|
373
487
|
});
|
|
374
488
|
function getPercentSize(point, frameSize) {
|
|
375
489
|
if (!frameSize)
|
|
@@ -418,6 +532,7 @@ export {
|
|
|
418
532
|
SheetHandleFrame,
|
|
419
533
|
SheetOverlay,
|
|
420
534
|
SheetOverlayFrame,
|
|
535
|
+
SheetScrollView,
|
|
421
536
|
createSheetScope
|
|
422
537
|
};
|
|
423
538
|
//# sourceMappingURL=Sheet.js.map
|