Open VityaSchel opened 6 days ago
Here is a temporary patch for 0.3.2 version. It requires bezier-easing
package from npm in order to run CSS cubic-bezier transitions in js, so just install it on your project where you use vaul-svelte. You can apply the patch by placing it to patches/vaul-svelte@0.3.2.patch directory and running bun install
. Then use onDrag prop on Drawer.Root with percentage argument on callback:
<Drawer.Root onDrag={(_, p) => console.log('progress in range [0-1]', p)} />
diff --git a/dist/internal/vaul.js b/dist/internal/vaul.js
index 6ced7405f010443705cbfef58060d050994842f6..584eb6161b4f95a5027d51acb015a4f119c17602 100644
--- a/dist/internal/vaul.js
+++ b/dist/internal/vaul.js
@@ -5,6 +5,24 @@ import { isIOS, preventScroll } from "./prevent-scroll.js";
import { TRANSITIONS, VELOCITY_THRESHOLD } from "./constants.js";
import { handleEscapeKeydown } from "./escape-keydown.js";
import { handlePositionFixed } from "./position-fixed.js";
+import bezierEasing from 'bezier-easing'
+function animateTransition(callback, from, to) {
+ const startTime = performance.now()
+ const durationMs = TRANSITIONS.DURATION * 1000
+ const easing = bezierEasing(...TRANSITIONS.EASE)
+ function step(currentTime) {
+ const elapsed = currentTime - startTime
+ const progress = Math.min(elapsed / durationMs, 1)
+ const easedProgress = easing(progress)
+
+ callback(from + easedProgress * (to - from))
+
+ if (elapsed < durationMs) {
+ requestAnimationFrame(step)
+ }
+ }
+ requestAnimationFrame(step)
+}
const CLOSE_THRESHOLD = 0.25;
const SCROLL_LOCK_TIMEOUT = 100;
const BORDER_RADIUS = 8;
@@ -419,6 +437,12 @@ export function createVaul(props) {
if (!$drawerRef)
return;
const $direction = get(direction);
+ const drawerStyles = window.getComputedStyle($drawerRef)
+ const drawerOffsetFromSnapPoint = new DOMMatrix(drawerStyles.transform).m42
+ const drawerHeight = parseFloat(drawerStyles.height)
+ animateTransition(x => {
+ onDragProp?.(undefined, x / drawerHeight)
+ }, drawerOffsetFromSnapPoint, drawerHeight)
onClose?.();
set($drawerRef, {
transform: isVertical($direction)
@@ -469,6 +493,12 @@ export function createVaul(props) {
transform: "translate3d(0, 0, 0)",
transition: `transform ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`,
});
+ const drawerStyles = window.getComputedStyle($drawerRef)
+ const drawerOffsetFromSnapPoint = new DOMMatrix(drawerStyles.transform).m42
+ const drawerHeight = parseFloat(drawerStyles.height)
+ animateTransition(x => {
+ onDragProp?.(undefined, x / drawerHeight)
+ }, drawerOffsetFromSnapPoint, 0)
set($overlayRef, {
transition: `opacity ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`,
opacity: "1",
@@ -566,6 +596,14 @@ export function createVaul(props) {
}
openTime.set(new Date());
scaleBackground(true, props.backgroundColor);
+ setTimeout(() => {
+ const $drawerRef = get(drawerRef);
+ const drawerStyles = window.getComputedStyle($drawerRef)
+ const drawerHeight = parseFloat(drawerStyles.height)
+ animateTransition(x => {
+ onDragProp?.(undefined, 1 - (x / drawerHeight))
+ }, 0, drawerHeight)
+ }, 0)
});
effect([visible], ([$visible]) => {
if (!$visible)
Describe the feature in detail (code, mocks, or screenshots encouraged)
The component already has onDrag callback which reports percentage of dragging, but I need to get currently visible portion of drawer on screen, including all animations and dragging
What type of pull request would this be?
New Feature
Provide relevant links or additional information.
No response