Skip to content

Commit 3b2fdd6

Browse files
committed
fix(web): use wrapper drop-shadow so elevation isn't clipped
1 parent 3bec3ae commit 3b2fdd6

1 file changed

Lines changed: 23 additions & 10 deletions

File tree

src/TrueSheet.web.tsx

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -583,8 +583,17 @@ const TrueSheetComponent = forwardRef<TrueSheetMethods, TrueSheetProps>((props,
583583
// Shadow cast upward from the sheet's top edge toward the background. Matches
584584
// Android's `elevation` semantics roughly — the sheet "lifts" off whatever is
585585
// behind it. Scales linearly so higher elevation reads as more separation.
586-
const boxShadow =
587-
elevation > 0 ? `0 ${-elevation}px ${elevation * 3}px rgba(0, 0, 0, 0.15)` : undefined;
586+
// Applied to the vaul wrapper (not the drawer) as `filter: drop-shadow`: the
587+
// wrapper clips the drawer (overflow: hidden + contain: paint), which would
588+
// cut off `box-shadow` on the drawer at the wrapper edges — visible in
589+
// detached mode (bottom blur clipped in the floating gap) and when the
590+
// wrapper is narrowed by maxWidth/anchor margins (lateral blur clipped at
591+
// wrapper edges). drop-shadow on the wrapper follows the post-clip silhouette
592+
// and isn't clipped by the wrapper itself.
593+
const dropShadow =
594+
elevation > 0
595+
? `drop-shadow(0 ${-elevation}px ${elevation * 3}px rgba(0, 0, 0, 0.15))`
596+
: undefined;
588597

589598
const mergedContentStyle = useMemo<React.CSSProperties>(
590599
() => ({
@@ -598,11 +607,10 @@ const TrueSheetComponent = forwardRef<TrueSheetMethods, TrueSheetProps>((props,
598607
borderTopLeftRadius: effectiveCornerRadius,
599608
borderTopRightRadius: effectiveCornerRadius,
600609
backgroundColor: backgroundColor as string,
601-
boxShadow,
602610
// Lift content above iOS home indicator / bottom safe area when enabled.
603611
paddingBottom: insetAdjustment === 'automatic' ? 'env(safe-area-inset-bottom, 0px)' : 0,
604612
}),
605-
[backgroundColor, effectiveCornerRadius, boxShadow, insetAdjustment]
613+
[backgroundColor, effectiveCornerRadius, insetAdjustment]
606614
);
607615

608616
const defaultGrabberColor =
@@ -655,7 +663,12 @@ const TrueSheetComponent = forwardRef<TrueSheetMethods, TrueSheetProps>((props,
655663
: (maxContentWidth ?? (pageSizing ? DEFAULT_MAX_WIDTH : undefined))
656664
: undefined;
657665

658-
if (maxWidth == null && !effectiveDetached) return undefined;
666+
const needsMargins = maxWidth != null || effectiveDetached;
667+
if (!needsMargins && !dropShadow) return undefined;
668+
669+
const next: React.CSSProperties = {};
670+
if (dropShadow) next.filter = dropShadow;
671+
if (!needsMargins) return next;
659672

660673
let marginLeft: number | string;
661674
let marginRight: number | string;
@@ -670,11 +683,10 @@ const TrueSheetComponent = forwardRef<TrueSheetMethods, TrueSheetProps>((props,
670683
marginRight = anchor === 'right' ? anchorOffset : 'auto';
671684
}
672685

673-
return {
674-
...(maxWidth != null && { maxWidth }),
675-
marginLeft,
676-
marginRight,
677-
};
686+
if (maxWidth != null) next.maxWidth = maxWidth;
687+
next.marginLeft = marginLeft;
688+
next.marginRight = marginRight;
689+
return next;
678690
}, [
679691
isLandscapeOrTablet,
680692
isFormSheet,
@@ -683,6 +695,7 @@ const TrueSheetComponent = forwardRef<TrueSheetMethods, TrueSheetProps>((props,
683695
anchor,
684696
anchorOffset,
685697
effectiveDetached,
698+
dropShadow,
686699
]);
687700

688701
const handleStyle = useMemo<React.CSSProperties>(

0 commit comments

Comments
 (0)