@tamagui/sheet 1.0.1-beta.199 → 1.0.1-beta.201
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 +360 -345
- package/dist/cjs/Sheet.js.map +3 -3
- package/dist/esm/Sheet.js +360 -345
- package/dist/esm/Sheet.js.map +3 -3
- package/dist/jsx/Sheet.js +316 -304
- package/dist/jsx/Sheet.js.map +3 -3
- package/package.json +11 -11
- package/src/Sheet.tsx +394 -379
- package/types/Sheet.d.ts +2 -5
package/dist/jsx/Sheet.js
CHANGED
|
@@ -130,332 +130,344 @@ const sheetComponents = {
|
|
|
130
130
|
const ParentSheetContext = createContext({
|
|
131
131
|
zIndex: 40
|
|
132
132
|
});
|
|
133
|
+
const useSheetContoller = () => {
|
|
134
|
+
const controller = useContext(SheetControllerContext);
|
|
135
|
+
const isHidden = controller?.hidden || false;
|
|
136
|
+
const isShowingNonSheet = isHidden && controller?.open;
|
|
137
|
+
return {
|
|
138
|
+
controller,
|
|
139
|
+
isHidden,
|
|
140
|
+
isShowingNonSheet
|
|
141
|
+
};
|
|
142
|
+
};
|
|
133
143
|
const Sheet = withStaticProperties(
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
144
|
+
forwardRef(function Sheet2(props, ref) {
|
|
145
|
+
const { isShowingNonSheet } = useSheetContoller();
|
|
146
|
+
if (isShowingNonSheet) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
return <SheetImplementation ref={ref} {...props} />;
|
|
150
|
+
}),
|
|
151
|
+
sheetComponents
|
|
152
|
+
);
|
|
153
|
+
const SheetImplementation = themeable(
|
|
154
|
+
forwardRef(function SheetImplementation2(props, ref) {
|
|
155
|
+
const parentSheet = useContext(ParentSheetContext);
|
|
156
|
+
const { isHidden, controller } = useSheetContoller();
|
|
157
|
+
const {
|
|
158
|
+
__scopeSheet,
|
|
159
|
+
snapPoints: snapPointsProp = [80],
|
|
160
|
+
open: openProp,
|
|
161
|
+
defaultOpen,
|
|
162
|
+
children: childrenProp,
|
|
163
|
+
position: positionProp,
|
|
164
|
+
onPositionChange,
|
|
165
|
+
onOpenChange,
|
|
166
|
+
defaultPosition,
|
|
167
|
+
dismissOnOverlayPress = true,
|
|
168
|
+
animationConfig,
|
|
169
|
+
dismissOnSnapToBottom = false,
|
|
170
|
+
disableDrag: disableDragProp,
|
|
171
|
+
modal = false,
|
|
172
|
+
handleDisableScroll = true,
|
|
173
|
+
zIndex = parentSheet.zIndex + 1
|
|
174
|
+
} = props;
|
|
175
|
+
if (process.env.NODE_ENV === "development") {
|
|
176
|
+
if (snapPointsProp.some((p) => p < 0 || p > 100)) {
|
|
177
|
+
console.warn(
|
|
178
|
+
`\u26A0\uFE0F Invalid snapPoint given, snapPoints must be between 0 and 100, equal to percent height of frame`
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
const driver = getAnimationDriver();
|
|
183
|
+
if (!driver) {
|
|
184
|
+
throw new Error(`Must set animations in tamagui.config.ts`);
|
|
185
|
+
}
|
|
186
|
+
const disableDrag = disableDragProp ?? controller?.disableDrag;
|
|
187
|
+
const themeName = useThemeName();
|
|
188
|
+
const contentRef = React.useRef(null);
|
|
189
|
+
const scrollBridge = useConstant(() => ({
|
|
190
|
+
enabled: false,
|
|
191
|
+
y: 0,
|
|
192
|
+
paneY: 0,
|
|
193
|
+
paneMinY: 0,
|
|
194
|
+
scrollStartY: -1,
|
|
195
|
+
drag: () => {
|
|
196
|
+
},
|
|
197
|
+
release: () => {
|
|
198
|
+
},
|
|
199
|
+
scrollLock: false
|
|
200
|
+
}));
|
|
201
|
+
const onOpenChangeInternal = (val) => {
|
|
202
|
+
controller?.onOpenChange?.(val);
|
|
203
|
+
onOpenChange?.(val);
|
|
204
|
+
};
|
|
205
|
+
const [open, setOpen] = useControllableState({
|
|
206
|
+
prop: controller?.open ?? openProp,
|
|
207
|
+
defaultProp: defaultOpen || true,
|
|
208
|
+
onChange: onOpenChangeInternal,
|
|
209
|
+
strategy: "most-recent-wins"
|
|
210
|
+
});
|
|
211
|
+
const [frameSize, setFrameSize] = useState(0);
|
|
212
|
+
const snapPoints = useMemo(
|
|
213
|
+
() => dismissOnSnapToBottom ? [...snapPointsProp, 0] : snapPointsProp,
|
|
214
|
+
[JSON.stringify(snapPointsProp), dismissOnSnapToBottom]
|
|
215
|
+
);
|
|
216
|
+
const [position_, setPosition_] = useControllableState({
|
|
217
|
+
prop: positionProp,
|
|
218
|
+
defaultProp: defaultPosition || (open ? 0 : -1),
|
|
219
|
+
onChange: onPositionChange,
|
|
220
|
+
strategy: "most-recent-wins"
|
|
221
|
+
});
|
|
222
|
+
const position = open === false ? -1 : position_;
|
|
223
|
+
if (open && dismissOnSnapToBottom && position === snapPoints.length - 1) {
|
|
224
|
+
setPosition_(0);
|
|
225
|
+
}
|
|
226
|
+
const setPosition = useCallback(
|
|
227
|
+
(next) => {
|
|
228
|
+
if (dismissOnSnapToBottom && next === snapPoints.length - 1) {
|
|
229
|
+
setOpen(false);
|
|
230
|
+
} else {
|
|
231
|
+
setPosition_(next);
|
|
160
232
|
}
|
|
233
|
+
},
|
|
234
|
+
[dismissOnSnapToBottom, snapPoints.length, setPosition_, setOpen]
|
|
235
|
+
);
|
|
236
|
+
const animatedNumber = driver.useAnimatedNumber(HIDDEN_SIZE);
|
|
237
|
+
const at = useRef(0);
|
|
238
|
+
driver.useAnimatedNumberReaction(animatedNumber, (value) => {
|
|
239
|
+
at.current = value;
|
|
240
|
+
scrollBridge.paneY = value;
|
|
241
|
+
});
|
|
242
|
+
const [isResizing, setIsResizing] = useState(true);
|
|
243
|
+
useIsomorphicLayoutEffect(() => {
|
|
244
|
+
if (!isResizing) {
|
|
245
|
+
setIsResizing(true);
|
|
161
246
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
247
|
+
}, [modal]);
|
|
248
|
+
function stopSpring() {
|
|
249
|
+
animatedNumber.stop();
|
|
250
|
+
if (scrollBridge.onFinishAnimate) {
|
|
251
|
+
scrollBridge.onFinishAnimate();
|
|
252
|
+
scrollBridge.onFinishAnimate = void 0;
|
|
165
253
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
const scrollBridge = useConstant(() => ({
|
|
172
|
-
enabled: false,
|
|
173
|
-
y: 0,
|
|
174
|
-
paneY: 0,
|
|
175
|
-
paneMinY: 0,
|
|
176
|
-
scrollStartY: -1,
|
|
177
|
-
drag: () => {
|
|
178
|
-
},
|
|
179
|
-
release: () => {
|
|
180
|
-
},
|
|
181
|
-
scrollLock: false
|
|
182
|
-
}));
|
|
183
|
-
const onOpenChangeInternal = (val) => {
|
|
184
|
-
controller?.onOpenChange?.(val);
|
|
185
|
-
onOpenChange?.(val);
|
|
186
|
-
};
|
|
187
|
-
const [open, setOpen] = useControllableState({
|
|
188
|
-
prop: controller?.open ?? openProp,
|
|
189
|
-
defaultProp: defaultOpen || true,
|
|
190
|
-
onChange: onOpenChangeInternal,
|
|
191
|
-
strategy: "most-recent-wins"
|
|
192
|
-
});
|
|
193
|
-
const [frameSize, setFrameSize] = useState(0);
|
|
194
|
-
const snapPoints = useMemo(
|
|
195
|
-
() => dismissOnSnapToBottom ? [...snapPointsProp, 0] : snapPointsProp,
|
|
196
|
-
[JSON.stringify(snapPointsProp), dismissOnSnapToBottom]
|
|
197
|
-
);
|
|
198
|
-
const [position_, setPosition_] = useControllableState({
|
|
199
|
-
prop: positionProp,
|
|
200
|
-
defaultProp: defaultPosition || (open ? 0 : -1),
|
|
201
|
-
onChange: onPositionChange,
|
|
202
|
-
strategy: "most-recent-wins"
|
|
203
|
-
});
|
|
204
|
-
const position = open === false ? -1 : position_;
|
|
205
|
-
if (open && dismissOnSnapToBottom && position === snapPoints.length - 1) {
|
|
206
|
-
setPosition_(0);
|
|
254
|
+
}
|
|
255
|
+
const shouldSetPositionOpen = open && position < 0;
|
|
256
|
+
useEffect(() => {
|
|
257
|
+
if (shouldSetPositionOpen) {
|
|
258
|
+
setPosition(0);
|
|
207
259
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
)
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}, [modal]);
|
|
230
|
-
function stopSpring() {
|
|
231
|
-
animatedNumber.stop();
|
|
232
|
-
if (scrollBridge.onFinishAnimate) {
|
|
233
|
-
scrollBridge.onFinishAnimate();
|
|
234
|
-
scrollBridge.onFinishAnimate = void 0;
|
|
260
|
+
}, [setPosition, shouldSetPositionOpen]);
|
|
261
|
+
const positions = useMemo(
|
|
262
|
+
() => snapPoints.map((point) => getPercentSize(point, frameSize)),
|
|
263
|
+
[frameSize, snapPoints]
|
|
264
|
+
);
|
|
265
|
+
const animateTo = useEvent((position2) => {
|
|
266
|
+
const current = animatedNumber.getValue();
|
|
267
|
+
if (isHidden && open)
|
|
268
|
+
return;
|
|
269
|
+
if (!current)
|
|
270
|
+
return;
|
|
271
|
+
if (frameSize === 0)
|
|
272
|
+
return;
|
|
273
|
+
const hiddenValue = frameSize === 0 ? HIDDEN_SIZE : frameSize;
|
|
274
|
+
const toValue = isHidden || position2 === -1 ? hiddenValue : positions[position2];
|
|
275
|
+
if (at.current === toValue)
|
|
276
|
+
return;
|
|
277
|
+
stopSpring();
|
|
278
|
+
if (isHidden || isResizing) {
|
|
279
|
+
if (isResizing) {
|
|
280
|
+
setIsResizing(false);
|
|
235
281
|
}
|
|
282
|
+
animatedNumber.setValue(toValue, {
|
|
283
|
+
type: "timing",
|
|
284
|
+
duration: 0
|
|
285
|
+
});
|
|
286
|
+
at.current = toValue;
|
|
287
|
+
return;
|
|
236
288
|
}
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
if (
|
|
250
|
-
return;
|
|
251
|
-
if (!current)
|
|
252
|
-
return;
|
|
253
|
-
if (frameSize === 0)
|
|
289
|
+
const overshootClamping = at.current === HIDDEN_SIZE;
|
|
290
|
+
animatedNumber.setValue(toValue, {
|
|
291
|
+
...animationConfig,
|
|
292
|
+
type: "spring",
|
|
293
|
+
overshootClamping
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
useIsomorphicLayoutEffect(() => {
|
|
297
|
+
animateTo(position);
|
|
298
|
+
}, [isHidden, frameSize, position, animateTo]);
|
|
299
|
+
const panResponder = useMemo(
|
|
300
|
+
() => {
|
|
301
|
+
if (disableDrag)
|
|
254
302
|
return;
|
|
255
|
-
|
|
256
|
-
const toValue = isHidden || position2 === -1 ? hiddenValue : positions[position2];
|
|
257
|
-
if (at.current === toValue)
|
|
303
|
+
if (!frameSize)
|
|
258
304
|
return;
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
305
|
+
const minY = positions[0];
|
|
306
|
+
scrollBridge.paneMinY = minY;
|
|
307
|
+
let startY = at.current;
|
|
308
|
+
function makeUnselectable(val) {
|
|
309
|
+
if (!selectionStyleSheet)
|
|
310
|
+
return;
|
|
311
|
+
if (!val) {
|
|
312
|
+
selectionStyleSheet.innerText = ``;
|
|
313
|
+
} else {
|
|
314
|
+
selectionStyleSheet.innerText = `:root * { user-select: none !important; -webkit-user-select: none !important; }`;
|
|
263
315
|
}
|
|
264
|
-
animatedNumber.setValue(toValue, {
|
|
265
|
-
type: "timing",
|
|
266
|
-
duration: 0
|
|
267
|
-
});
|
|
268
|
-
at.current = toValue;
|
|
269
|
-
return;
|
|
270
316
|
}
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
if (!frameSize)
|
|
286
|
-
return;
|
|
287
|
-
const minY = positions[0];
|
|
288
|
-
scrollBridge.paneMinY = minY;
|
|
289
|
-
let startY = at.current;
|
|
290
|
-
function makeUnselectable(val) {
|
|
291
|
-
if (!selectionStyleSheet)
|
|
292
|
-
return;
|
|
293
|
-
if (!val) {
|
|
294
|
-
selectionStyleSheet.innerText = ``;
|
|
295
|
-
} else {
|
|
296
|
-
selectionStyleSheet.innerText = `:root * { user-select: none !important; -webkit-user-select: none !important; }`;
|
|
317
|
+
const release = ({ vy, dragAt }) => {
|
|
318
|
+
isExternalDrag = false;
|
|
319
|
+
previouslyScrolling = false;
|
|
320
|
+
makeUnselectable(false);
|
|
321
|
+
const at2 = dragAt + startY;
|
|
322
|
+
const end = at2 + frameSize * vy * 0.2;
|
|
323
|
+
let closestPoint = 0;
|
|
324
|
+
let dist = Infinity;
|
|
325
|
+
for (let i = 0; i < positions.length; i++) {
|
|
326
|
+
const position2 = positions[i];
|
|
327
|
+
const curDist = end > position2 ? end - position2 : position2 - end;
|
|
328
|
+
if (curDist < dist) {
|
|
329
|
+
dist = curDist;
|
|
330
|
+
closestPoint = i;
|
|
297
331
|
}
|
|
298
332
|
}
|
|
299
|
-
|
|
300
|
-
|
|
333
|
+
setPosition(closestPoint);
|
|
334
|
+
animateTo(closestPoint);
|
|
335
|
+
};
|
|
336
|
+
const finish = (_e, state) => {
|
|
337
|
+
release({
|
|
338
|
+
vy: state.vy,
|
|
339
|
+
dragAt: state.dy
|
|
340
|
+
});
|
|
341
|
+
};
|
|
342
|
+
let previouslyScrolling = false;
|
|
343
|
+
const onMoveShouldSet = (_e, { dy }) => {
|
|
344
|
+
const isScrolled = scrollBridge.y !== 0;
|
|
345
|
+
const isDraggingUp = dy < 0;
|
|
346
|
+
const isAtTop = scrollBridge.paneY <= scrollBridge.paneMinY;
|
|
347
|
+
if (isScrolled) {
|
|
348
|
+
previouslyScrolling = true;
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
if (previouslyScrolling) {
|
|
301
352
|
previouslyScrolling = false;
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
let dist = Infinity;
|
|
307
|
-
for (let i = 0; i < positions.length; i++) {
|
|
308
|
-
const position2 = positions[i];
|
|
309
|
-
const curDist = end > position2 ? end - position2 : position2 - end;
|
|
310
|
-
if (curDist < dist) {
|
|
311
|
-
dist = curDist;
|
|
312
|
-
closestPoint = i;
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
setPosition(closestPoint);
|
|
316
|
-
animateTo(closestPoint);
|
|
317
|
-
};
|
|
318
|
-
const finish = (_e, state) => {
|
|
319
|
-
release({
|
|
320
|
-
vy: state.vy,
|
|
321
|
-
dragAt: state.dy
|
|
322
|
-
});
|
|
323
|
-
};
|
|
324
|
-
let previouslyScrolling = false;
|
|
325
|
-
const onMoveShouldSet = (_e, { dy }) => {
|
|
326
|
-
const isScrolled = scrollBridge.y !== 0;
|
|
327
|
-
const isDraggingUp = dy < 0;
|
|
328
|
-
const isAtTop = scrollBridge.paneY <= scrollBridge.paneMinY;
|
|
329
|
-
if (isScrolled) {
|
|
330
|
-
previouslyScrolling = true;
|
|
353
|
+
return true;
|
|
354
|
+
}
|
|
355
|
+
if (isAtTop) {
|
|
356
|
+
if (!isScrolled && isDraggingUp) {
|
|
331
357
|
return false;
|
|
332
358
|
}
|
|
333
|
-
if (previouslyScrolling) {
|
|
334
|
-
previouslyScrolling = false;
|
|
335
|
-
return true;
|
|
336
|
-
}
|
|
337
|
-
if (isAtTop) {
|
|
338
|
-
if (!isScrolled && isDraggingUp) {
|
|
339
|
-
return false;
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
return Math.abs(dy) > 5;
|
|
343
|
-
};
|
|
344
|
-
const grant = () => {
|
|
345
|
-
makeUnselectable(true);
|
|
346
|
-
stopSpring();
|
|
347
|
-
startY = at.current;
|
|
348
|
-
};
|
|
349
|
-
let isExternalDrag = false;
|
|
350
|
-
scrollBridge.drag = (dy) => {
|
|
351
|
-
if (!isExternalDrag) {
|
|
352
|
-
isExternalDrag = true;
|
|
353
|
-
grant();
|
|
354
|
-
}
|
|
355
|
-
const to = dy + startY;
|
|
356
|
-
animatedNumber.setValue(resisted(to, minY), { type: "direct" });
|
|
357
|
-
};
|
|
358
|
-
scrollBridge.release = release;
|
|
359
|
-
return PanResponder.create({
|
|
360
|
-
onMoveShouldSetPanResponder: onMoveShouldSet,
|
|
361
|
-
onPanResponderGrant: grant,
|
|
362
|
-
onPanResponderMove: (_e, { dy }) => {
|
|
363
|
-
const toFull = dy + startY;
|
|
364
|
-
const to = resisted(toFull, minY);
|
|
365
|
-
animatedNumber.setValue(to, { type: "direct" });
|
|
366
|
-
},
|
|
367
|
-
onPanResponderEnd: finish,
|
|
368
|
-
onPanResponderTerminate: finish,
|
|
369
|
-
onPanResponderRelease: finish
|
|
370
|
-
});
|
|
371
|
-
},
|
|
372
|
-
[disableDrag, animateTo, frameSize, positions, setPosition]
|
|
373
|
-
);
|
|
374
|
-
let handleComponent = null;
|
|
375
|
-
let overlayComponent = null;
|
|
376
|
-
let frameComponent = null;
|
|
377
|
-
React.Children.forEach(childrenProp, (child) => {
|
|
378
|
-
if (isValidElement(child)) {
|
|
379
|
-
const name = child.type?.["staticConfig"]?.componentName;
|
|
380
|
-
switch (name) {
|
|
381
|
-
case "SheetHandle":
|
|
382
|
-
handleComponent = child;
|
|
383
|
-
break;
|
|
384
|
-
case "Sheet":
|
|
385
|
-
frameComponent = child;
|
|
386
|
-
break;
|
|
387
|
-
case "SheetOverlay":
|
|
388
|
-
overlayComponent = child;
|
|
389
|
-
break;
|
|
390
|
-
default:
|
|
391
|
-
console.warn("Warning: passed invalid child to Sheet", child);
|
|
392
359
|
}
|
|
393
|
-
|
|
394
|
-
});
|
|
395
|
-
const preventShown = controller?.hidden && controller?.open;
|
|
396
|
-
const animatedStyle = driver.useAnimatedNumberStyle(animatedNumber, (val) => {
|
|
397
|
-
return {
|
|
398
|
-
transform: [{ translateY: frameSize === 0 ? HIDDEN_SIZE : val }]
|
|
360
|
+
return Math.abs(dy) > 5;
|
|
399
361
|
};
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
const parentSheetContext = useContext(SheetInsideSheetContext);
|
|
405
|
-
const onInnerSheet = useCallback((hasChild) => {
|
|
406
|
-
setIsShowingInnerSheet(hasChild);
|
|
407
|
-
}, []);
|
|
408
|
-
useIsomorphicLayoutEffect(() => {
|
|
409
|
-
if (!parentSheetContext || !open)
|
|
410
|
-
return;
|
|
411
|
-
parentSheetContext(true);
|
|
412
|
-
return () => {
|
|
413
|
-
parentSheetContext(false);
|
|
362
|
+
const grant = () => {
|
|
363
|
+
makeUnselectable(true);
|
|
364
|
+
stopSpring();
|
|
365
|
+
startY = at.current;
|
|
414
366
|
};
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
{
|
|
433
|
-
position: "absolute",
|
|
434
|
-
zIndex,
|
|
435
|
-
width: "100%",
|
|
436
|
-
height: "100%",
|
|
437
|
-
opacity: shouldHideParentSheet ? 0 : 1
|
|
367
|
+
let isExternalDrag = false;
|
|
368
|
+
scrollBridge.drag = (dy) => {
|
|
369
|
+
if (!isExternalDrag) {
|
|
370
|
+
isExternalDrag = true;
|
|
371
|
+
grant();
|
|
372
|
+
}
|
|
373
|
+
const to = dy + startY;
|
|
374
|
+
animatedNumber.setValue(resisted(to, minY), { type: "direct" });
|
|
375
|
+
};
|
|
376
|
+
scrollBridge.release = release;
|
|
377
|
+
return PanResponder.create({
|
|
378
|
+
onMoveShouldSetPanResponder: onMoveShouldSet,
|
|
379
|
+
onPanResponderGrant: grant,
|
|
380
|
+
onPanResponderMove: (_e, { dy }) => {
|
|
381
|
+
const toFull = dy + startY;
|
|
382
|
+
const to = resisted(toFull, minY);
|
|
383
|
+
animatedNumber.setValue(to, { type: "direct" });
|
|
438
384
|
},
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
385
|
+
onPanResponderEnd: finish,
|
|
386
|
+
onPanResponderTerminate: finish,
|
|
387
|
+
onPanResponderRelease: finish
|
|
388
|
+
});
|
|
389
|
+
},
|
|
390
|
+
[disableDrag, animateTo, frameSize, positions, setPosition]
|
|
391
|
+
);
|
|
392
|
+
let handleComponent = null;
|
|
393
|
+
let overlayComponent = null;
|
|
394
|
+
let frameComponent = null;
|
|
395
|
+
React.Children.forEach(childrenProp, (child) => {
|
|
396
|
+
if (isValidElement(child)) {
|
|
397
|
+
const name = child.type?.["staticConfig"]?.componentName;
|
|
398
|
+
switch (name) {
|
|
399
|
+
case "SheetHandle":
|
|
400
|
+
handleComponent = child;
|
|
401
|
+
break;
|
|
402
|
+
case "Sheet":
|
|
403
|
+
frameComponent = child;
|
|
404
|
+
break;
|
|
405
|
+
case "SheetOverlay":
|
|
406
|
+
overlayComponent = child;
|
|
407
|
+
break;
|
|
408
|
+
default:
|
|
409
|
+
console.warn("Warning: passed invalid child to Sheet", child);
|
|
452
410
|
}
|
|
453
|
-
return <SheetInsideSheetContext.Provider value={onInnerSheet}>{modalContents}</SheetInsideSheetContext.Provider>;
|
|
454
411
|
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
412
|
+
});
|
|
413
|
+
const animatedStyle = driver.useAnimatedNumberStyle(animatedNumber, (val) => {
|
|
414
|
+
return {
|
|
415
|
+
transform: [{ translateY: frameSize === 0 ? HIDDEN_SIZE : val }]
|
|
416
|
+
};
|
|
417
|
+
});
|
|
418
|
+
const AnimatedView = driver["NumberView"] ?? driver.View;
|
|
419
|
+
const [isShowingInnerSheet, setIsShowingInnerSheet] = useState(false);
|
|
420
|
+
const shouldHideParentSheet = !isWeb && modal && isShowingInnerSheet;
|
|
421
|
+
const parentSheetContext = useContext(SheetInsideSheetContext);
|
|
422
|
+
const onInnerSheet = useCallback((hasChild) => {
|
|
423
|
+
setIsShowingInnerSheet(hasChild);
|
|
424
|
+
}, []);
|
|
425
|
+
useIsomorphicLayoutEffect(() => {
|
|
426
|
+
if (!parentSheetContext || !open)
|
|
427
|
+
return;
|
|
428
|
+
parentSheetContext(true);
|
|
429
|
+
return () => {
|
|
430
|
+
parentSheetContext(false);
|
|
431
|
+
};
|
|
432
|
+
}, [parentSheetContext, open]);
|
|
433
|
+
const nextParentContext = useMemo(
|
|
434
|
+
() => ({
|
|
435
|
+
zIndex
|
|
436
|
+
}),
|
|
437
|
+
[zIndex]
|
|
438
|
+
);
|
|
439
|
+
const contents = <ParentSheetContext.Provider value={nextParentContext}><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}>
|
|
440
|
+
{isResizing || shouldHideParentSheet ? null : overlayComponent}
|
|
441
|
+
<AnimatedView ref={ref} {...panResponder?.panHandlers} onLayout={(e) => {
|
|
442
|
+
const next = e.nativeEvent.layout.height;
|
|
443
|
+
setFrameSize((prev) => {
|
|
444
|
+
const isBigChange = Math.abs(prev - next) > 50;
|
|
445
|
+
setIsResizing(isBigChange);
|
|
446
|
+
return next;
|
|
447
|
+
});
|
|
448
|
+
}} pointerEvents={open && !shouldHideParentSheet ? "auto" : "none"} style={[
|
|
449
|
+
{
|
|
450
|
+
position: "absolute",
|
|
451
|
+
zIndex,
|
|
452
|
+
width: "100%",
|
|
453
|
+
height: "100%",
|
|
454
|
+
opacity: shouldHideParentSheet ? 0 : 1
|
|
455
|
+
},
|
|
456
|
+
animatedStyle
|
|
457
|
+
]}>
|
|
458
|
+
{handleComponent}
|
|
459
|
+
<RemoveScroll enabled={open && modal && handleDisableScroll} as={Slot} allowPinchZoom shards={[contentRef]} removeScrollBar={false}>{isResizing ? null : frameComponent}</RemoveScroll>
|
|
460
|
+
</AnimatedView>
|
|
461
|
+
</SheetProvider></ParentSheetContext.Provider>;
|
|
462
|
+
if (modal) {
|
|
463
|
+
const modalContents = <Portal zIndex={zIndex}><Theme name={themeName}>{contents}</Theme></Portal>;
|
|
464
|
+
if (isWeb) {
|
|
465
|
+
return modalContents;
|
|
466
|
+
}
|
|
467
|
+
return <SheetInsideSheetContext.Provider value={onInnerSheet}>{modalContents}</SheetInsideSheetContext.Provider>;
|
|
468
|
+
}
|
|
469
|
+
return contents;
|
|
470
|
+
})
|
|
459
471
|
);
|
|
460
472
|
const SheetInsideSheetContext = createContext(null);
|
|
461
473
|
const ControlledSheet = Sheet;
|