Skip to content

Commit

Permalink
Merge pull request #2223 from adevinta/fix-2199-snackbar-swipe-styles
Browse files Browse the repository at this point in the history
fix(snackbar): fixes and improves snackbar swipe styles to avoid translate collision
  • Loading branch information
soykje authored Jun 18, 2024
2 parents 0a42943 + fe176ab commit 828d6ed
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 39 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 38 additions & 18 deletions packages/components/snackbar/src/Snackbar.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -215,22 +215,40 @@ export const QAWithNewLineAction: StoryFn = _args => (
<div>
<Snackbar />

<Button
onClick={() =>
addSnackbar({
message:
'Lorem ipsum dolor sit, amet consectetur adipisicing elit. Tempora voluptatum cupiditate ut natus distinctio illum modi, id mollitia sequi dolorem nostrum autem suscipit eius sapiente vitae ipsum amet doloribus praesentium.',
actionLabel: 'Undo',
onAction: () => console.log('Undone'),
icon: <FavoriteFill />,
isClosable: true,
actionOnNewline: true,
timeout: null,
})
}
>
Display snackbar
</Button>
<div className="grid grid-cols-1 gap-xl md:grid-cols-2">
<Button
onClick={() =>
addSnackbar({
message:
'Lorem ipsum dolor sit, amet consectetur adipisicing elit. Tempora voluptatum cupiditate ut natus distinctio illum modi, id mollitia sequi dolorem nostrum autem suscipit eius sapiente vitae ipsum amet doloribus praesentium.',
actionLabel: 'Undo',
onAction: () => console.log('Undone'),
icon: <FavoriteFill />,
isClosable: true,
timeout: null,
})
}
>
Display snackbar
</Button>

<Button
onClick={() =>
addSnackbar({
message:
'Lorem ipsum dolor sit, amet consectetur adipisicing elit. Tempora voluptatum cupiditate ut natus distinctio illum modi, id mollitia sequi dolorem nostrum autem suscipit eius sapiente vitae ipsum amet doloribus praesentium.',
actionLabel: 'Undo',
onAction: () => console.log('Undone'),
icon: <FavoriteFill />,
isClosable: true,
actionOnNewline: true,
timeout: null,
})
}
>
Display snackbar with action on new line
</Button>
</div>
</div>
)

Expand All @@ -244,7 +262,8 @@ export const Action: StoryObj = {
<Button
onClick={() =>
addSnackbar({
message: "You're done!",
message:
'Lorem ipsum dolor sit, amet consectetur adipisicing elit. Tempora voluptatum cupiditate ut natus distinctio illum.',
actionLabel: 'Undo',
onAction: () => console.log('Undone'),
})
Expand All @@ -256,7 +275,8 @@ export const Action: StoryObj = {
<Button
onClick={() =>
addSnackbar({
message: "You're done! But maybe you should care about what you just did?",
message:
'Lorem ipsum dolor sit, amet consectetur adipisicing elit. Tempora voluptatum cupiditate ut natus distinctio illum.',
actionLabel: 'Undo',
onAction: () => console.log('Undone'),
actionOnNewline: true,
Expand Down
8 changes: 7 additions & 1 deletion packages/components/snackbar/src/Snackbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,13 @@ export const Snackbar = forwardRef<HTMLDivElement, SnackbarProps>(
useEffect(() => {
addProvider(ref)

return () => deleteProvider(ref)
return () => {
for (const toast of getGlobalSnackBarQueue().visibleToasts) {
toast.animation = undefined
}

deleteProvider(ref)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

Expand Down
3 changes: 1 addition & 2 deletions packages/components/snackbar/src/SnackbarItem.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,8 @@ export const snackbarItemVariant = cva(
"[grid-template-areas:'icon_message_close'_'._message_.'_'action_action_action']",
],
false: [
'grid-rows-[52px_1fr]',
'grid-cols-[min-content_1fr_min-content_min-content]',
"[grid-template-areas:'icon_message_action_close'_'._message_._.']",
"[grid-template-areas:'icon_message_action_close']",
],
},
},
Expand Down
8 changes: 6 additions & 2 deletions packages/components/snackbar/src/SnackbarItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ export const SnackbarItem = forwardRef<HTMLDivElement, PropsWithChildren<Snackba

const { state: swipeState, direction: swipeDirection } = useSwipe({
swipeRef: ref,
onSwipeStart: state.pauseAll,
onSwipeCancel: state.resumeAll,
onSwipeEnd: ({ direction }) => {
;['left', 'right'].includes(`${direction}`) && state.close(toast.key)
},
Expand Down Expand Up @@ -137,8 +139,10 @@ export const SnackbarItem = forwardRef<HTMLDivElement, PropsWithChildren<Snackba
{...toastProps}
{...rest}
data-animation={toast.animation}
data-swipe={swipeState}
data-swipe-direction={swipeDirection}
{...(!(swipeState === 'cancel' && toast.animation === 'exiting') && {
'data-swipe': swipeState,
'data-swipe-direction': swipeDirection,
})}
{...(toast.animation === 'exiting' && {
// Remove snackbar when the exiting animation completes
onAnimationEnd: () => state.remove(toast.key),
Expand Down
27 changes: 11 additions & 16 deletions packages/components/snackbar/src/useSwipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,8 @@ export const useSwipe = <T extends HTMLElement>({
threshold = 10,
}: SwipeArgs<T>): SwipeReturn => {
const [state, setState] = useState<SwipeReturn['state']>()
const [direction, setDirection] = useState<SwipeReturn['direction']>()

const directionRef = useRef<SwipeReturn['direction']>(direction)

const direction = useRef<SwipeReturn['direction']>()
const origin = useRef<Record<'x' | 'y', number> | null>(null)
const delta = useRef<Record<'x' | 'y', number> | null>(null)

Expand All @@ -49,24 +47,23 @@ export const useSwipe = <T extends HTMLElement>({
const deltaY = Math.abs(evt.clientY - origin.current.y)

let moveState: SwipeReturn['state']
let moveDirection: SwipeReturn['direction']

if (deltaX > deltaY && deltaX > threshold) {
moveDirection = evt.clientX > origin.current.x ? 'right' : 'left'
direction.current = evt.clientX > origin.current.x ? 'right' : 'left'
} else if (deltaY > threshold) {
moveDirection = evt.clientY > origin.current.y ? 'down' : 'up'
direction.current = evt.clientY > origin.current.y ? 'down' : 'up'
}

/**
* If no direction could be defined, then no move should be handled.
* This is particularly true with trackpads working with MacOS/Windows.
*/
if (!moveDirection) return
if (!direction.current) return

if (!delta.current) {
moveState = 'start'
delta.current = { x: deltaX, y: deltaY }
onSwipeStart?.({ state: moveState, direction: moveDirection })
onSwipeStart?.({ state: moveState, direction: direction.current })
} else {
moveState = 'move'
delta.current = { x: deltaX, y: deltaY }
Expand All @@ -78,12 +75,10 @@ export const useSwipe = <T extends HTMLElement>({
'--swipe-position-y',
`${!(deltaX > deltaY) ? evt.clientY - origin.current.y : 0}px`
)
onSwipeMove?.({ state: moveState, direction: moveDirection })
onSwipeMove?.({ state: moveState, direction: direction.current })
}

directionRef.current = moveDirection
setState(moveState)
setDirection(moveDirection)
}

const handleSwipeEnd = () => {
Expand All @@ -100,18 +95,18 @@ export const useSwipe = <T extends HTMLElement>({
if (deltaX > deltaY) {
if (deltaX > SWIPE_THRESHOLD) {
endState = 'end'
onSwipeEnd?.({ state: endState, direction: directionRef.current })
onSwipeEnd?.({ state: endState, direction: direction.current })
} else {
endState = 'cancel'
onSwipeCancel?.({ state: endState, direction: directionRef.current })
onSwipeCancel?.({ state: endState, direction: direction.current })
}
} else {
if (deltaY > SWIPE_THRESHOLD) {
endState = 'end'
onSwipeEnd?.({ state: endState, direction: directionRef.current })
onSwipeEnd?.({ state: endState, direction: direction.current })
} else {
endState = 'cancel'
onSwipeCancel?.({ state: endState, direction: directionRef.current })
onSwipeCancel?.({ state: endState, direction: direction.current })
}
}

Expand Down Expand Up @@ -143,6 +138,6 @@ export const useSwipe = <T extends HTMLElement>({

return {
state,
direction,
direction: direction.current,
}
}

0 comments on commit 828d6ed

Please sign in to comment.