From 46130fed1ad43c2e3f8e86b2c68cd9ad1c630b07 Mon Sep 17 00:00:00 2001 From: Kevin <83264008+coolestKev@users.noreply.github.com> Date: Tue, 7 Jan 2025 11:48:12 -0500 Subject: [PATCH] Task/htl 113692 limit dragging to header only (#1545) * task(HTL-113692): Limit dragging behavior to header only * task(HTL-113692): Limit drawer drag interaction to header only * task(HTL-113692): Fix coverage --- ...gging-to-header-only_2025-01-07-05-13.json | 10 +++++ packages/core/src/Drawer/Drawer.stories.tsx | 1 - packages/core/src/Drawer/Drawer.tsx | 19 ++++++++- packages/core/src/Drawer/hooks/useSnap.ts | 42 +++++++++---------- 4 files changed, 46 insertions(+), 26 deletions(-) create mode 100644 common/changes/pcln-design-system/task-HTL-113692-limit-dragging-to-header-only_2025-01-07-05-13.json diff --git a/common/changes/pcln-design-system/task-HTL-113692-limit-dragging-to-header-only_2025-01-07-05-13.json b/common/changes/pcln-design-system/task-HTL-113692-limit-dragging-to-header-only_2025-01-07-05-13.json new file mode 100644 index 000000000..d3939e145 --- /dev/null +++ b/common/changes/pcln-design-system/task-HTL-113692-limit-dragging-to-header-only_2025-01-07-05-13.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "pcln-design-system", + "comment": "Drawer is now draggable when user only drags the header, not the content", + "type": "patch" + } + ], + "packageName": "pcln-design-system" +} \ No newline at end of file diff --git a/packages/core/src/Drawer/Drawer.stories.tsx b/packages/core/src/Drawer/Drawer.stories.tsx index 6f35509c5..3562c5ebe 100644 --- a/packages/core/src/Drawer/Drawer.stories.tsx +++ b/packages/core/src/Drawer/Drawer.stories.tsx @@ -245,7 +245,6 @@ function DrawerScrollable(props) { height='100vh' style={{ backgroundColor: 'grey', height: '100vh', position: 'relative' }} > - Note: Mobile only feature - Please test on browser iOS/android device emulator Previous position: {snapState.prevSnapPosition} Current position: {snapState.currSnapPosition} diff --git a/packages/core/src/Drawer/Drawer.tsx b/packages/core/src/Drawer/Drawer.tsx index c4cf64fb3..5d76724ff 100644 --- a/packages/core/src/Drawer/Drawer.tsx +++ b/packages/core/src/Drawer/Drawer.tsx @@ -4,7 +4,7 @@ import { Flex } from '../Flex/Flex' import { Text } from '../Text/Text' import { DrawerRoot, DrawerWrapper, HeaderButton } from './Drawer.styled' import { ChevronDown, Close } from 'pcln-icons' -import { AnimatePresence, motion } from 'framer-motion' +import { AnimatePresence, motion, useDragControls } from 'framer-motion' import { SpaceProps, LayoutProps } from 'styled-system' import { useScrollWithShadow } from '../useScrollWithShadows/useScrollWithShadow' import { theme } from '../theme' @@ -72,6 +72,8 @@ export const Drawer: React.FC = ({ const { boxShadow, onScrollHandler } = useScrollWithShadow() const { snapPosition, handleSnap } = useSnap(snapHeights, snapDimensions, onSnapPositionChange) const SnapContainer = snapHeights ? motion.div : 'div' + const headerRef = React.useRef(null) + const dragControls = useDragControls() return ( = ({ dragConstraints={{ top: 0, bottom: 0 }} {...(snapHeights ? { onDragEnd: handleSnap } : {})} data-testid='snap-container' + dragControls={dragControls} + dragListener={false} > {isOpen && ( @@ -124,7 +128,18 @@ export const Drawer: React.FC = ({ > {(heading || onClose || onCollapse) && ( - + { + if (snapHeights) { + dragControls.start(e) + } + }} + flexDirection='column' + style={{ touchAction: 'none' }} + data-testid='drawer-header-container' + > {typeof heading === 'string' ? ( diff --git a/packages/core/src/Drawer/hooks/useSnap.ts b/packages/core/src/Drawer/hooks/useSnap.ts index 67b558f5a..ce8c6d3eb 100644 --- a/packages/core/src/Drawer/hooks/useSnap.ts +++ b/packages/core/src/Drawer/hooks/useSnap.ts @@ -20,8 +20,6 @@ export function useSnap(snapHeights, snapDimensions, onSnapPositionChange) { const [snapPosition, setSnapPosition] = useState(MIDDLE) const handleSnap = (...args) => { - const pointerType = args?.[0]?.pointerType // mouse, touch, etc. - const type = args?.[0]?.type // click, pointerup (drag), pointercancel (scroll) const info = args?.[1] const scrollOffset = info.offset.y @@ -45,29 +43,27 @@ export function useSnap(snapHeights, snapDimensions, onSnapPositionChange) { * container movement. */ - if (pointerType === 'touch' && type === 'pointerup') { - // Scroll down logic - if (SCROLL_DOWN) { - if (snapPosition === TOP) { - setSnapPosition(MIDDLE) - onSnapPositionChange({ prevSnapPosition: 'TOP', currSnapPosition: 'MIDDLE' }) - } - if (snapPosition === MIDDLE) { - setSnapPosition(BOTTOM) - onSnapPositionChange({ prevSnapPosition: 'MIDDLE', currSnapPosition: 'BOTTOM' }) - } + // Scroll down logic + if (SCROLL_DOWN) { + if (snapPosition === TOP) { + setSnapPosition(MIDDLE) + onSnapPositionChange({ prevSnapPosition: 'TOP', currSnapPosition: 'MIDDLE' }) } + if (snapPosition === MIDDLE) { + setSnapPosition(BOTTOM) + onSnapPositionChange({ prevSnapPosition: 'MIDDLE', currSnapPosition: 'BOTTOM' }) + } + } - // Scroll up logic - else if (SCROLL_UP) { - if (snapPosition === BOTTOM) { - setSnapPosition(MIDDLE) - onSnapPositionChange({ prevSnapPosition: 'BOTTOM', currSnapPosition: 'MIDDLE' }) - } - if (snapPosition === MIDDLE) { - setSnapPosition(TOP) - onSnapPositionChange({ prevSnapPosition: 'MIDDLE', currSnapPosition: 'TOP' }) - } + // Scroll up logic + else if (SCROLL_UP) { + if (snapPosition === BOTTOM) { + setSnapPosition(MIDDLE) + onSnapPositionChange({ prevSnapPosition: 'BOTTOM', currSnapPosition: 'MIDDLE' }) + } + if (snapPosition === MIDDLE) { + setSnapPosition(TOP) + onSnapPositionChange({ prevSnapPosition: 'MIDDLE', currSnapPosition: 'TOP' }) } } }