Animate drawer menu on mobile web (#7711)
* slide in/out drawer * increase width slightly * exponential easing function
This commit is contained in:
+9
-2
@@ -68,7 +68,6 @@ export const atoms = {
|
||||
* Used for the outermost components on screens, to ensure that they can fill
|
||||
* the screen and extend beyond.
|
||||
*/
|
||||
// @ts-ignore - web only minHeight string
|
||||
util_screen_outer: [
|
||||
web({
|
||||
minHeight: '100vh',
|
||||
@@ -76,7 +75,7 @@ export const atoms = {
|
||||
native({
|
||||
height: '100%',
|
||||
}),
|
||||
] as ViewStyle,
|
||||
] as StyleProp<ViewStyle>,
|
||||
|
||||
/*
|
||||
* Theme-independent bg colors
|
||||
@@ -980,6 +979,14 @@ export const atoms = {
|
||||
zoom_out: web({
|
||||
animation: 'zoomOut ease-out 0.1s',
|
||||
}),
|
||||
slide_in_left: web({
|
||||
// exponential easing function
|
||||
animation: 'slideInLeft cubic-bezier(0.16, 1, 0.3, 1) 0.5s',
|
||||
}),
|
||||
slide_out_left: web({
|
||||
animation: 'slideOutLeft ease-in 0.15s',
|
||||
animationFillMode: 'forwards',
|
||||
}),
|
||||
// special composite animation for dialogs
|
||||
zoom_fade_in: web({
|
||||
animation: 'zoomIn ease-out 0.1s, fadeIn ease-out 0.1s',
|
||||
|
||||
@@ -215,6 +215,24 @@ input:focus {
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideInLeft {
|
||||
from {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
to {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideOutLeft {
|
||||
from {
|
||||
transform: translateX(0);
|
||||
}
|
||||
to {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
}
|
||||
|
||||
/* animating radix dropdowns requires knowing the data attributes */
|
||||
.dropdown-menu-transform-origin > * {
|
||||
transform-origin: var(--radix-dropdown-menu-content-transform-origin);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, {useEffect} from 'react'
|
||||
import {useEffect, useLayoutEffect, useState} from 'react'
|
||||
import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native'
|
||||
import {msg} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
@@ -33,6 +33,20 @@ function ShellInner() {
|
||||
const closeAllActiveElements = useCloseAllActiveElements()
|
||||
const {_} = useLingui()
|
||||
const showDrawer = !isDesktop && isDrawerOpen
|
||||
const [showDrawerDelayedExit, setShowDrawerDelayedExit] = useState(showDrawer)
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (showDrawer !== showDrawerDelayedExit) {
|
||||
if (showDrawer) {
|
||||
setShowDrawerDelayedExit(true)
|
||||
} else {
|
||||
const timeout = setTimeout(() => {
|
||||
setShowDrawerDelayedExit(false)
|
||||
}, 160)
|
||||
return () => clearTimeout(timeout)
|
||||
}
|
||||
}
|
||||
}, [showDrawer, showDrawerDelayedExit])
|
||||
|
||||
useComposerKeyboardShortcut()
|
||||
useIntentHandler()
|
||||
@@ -56,7 +70,7 @@ function ShellInner() {
|
||||
<Lightbox />
|
||||
<PortalOutlet />
|
||||
|
||||
{showDrawer && (
|
||||
{showDrawerDelayedExit && (
|
||||
<>
|
||||
<RemoveScrollBar />
|
||||
<TouchableWithoutFeedback
|
||||
@@ -66,20 +80,27 @@ function ShellInner() {
|
||||
setDrawerOpen(false)
|
||||
}
|
||||
}}
|
||||
accessibilityLabel={_(msg`Close navigation footer`)}
|
||||
accessibilityHint={_(msg`Closes bottom navigation bar`)}>
|
||||
accessibilityLabel={_(msg`Close drawer menu`)}
|
||||
accessibilityHint="">
|
||||
<View
|
||||
style={[
|
||||
styles.drawerMask,
|
||||
{
|
||||
backgroundColor: select(t.name, {
|
||||
light: 'rgba(0, 57, 117, 0.1)',
|
||||
dark: 'rgba(1, 82, 168, 0.1)',
|
||||
dim: 'rgba(10, 13, 16, 0.8)',
|
||||
}),
|
||||
backgroundColor: showDrawer
|
||||
? select(t.name, {
|
||||
light: 'rgba(0, 57, 117, 0.1)',
|
||||
dark: 'rgba(1, 82, 168, 0.1)',
|
||||
dim: 'rgba(10, 13, 16, 0.8)',
|
||||
})
|
||||
: 'transparent',
|
||||
},
|
||||
a.transition_color,
|
||||
]}>
|
||||
<View style={styles.drawerContainer}>
|
||||
<View
|
||||
style={[
|
||||
styles.drawerContainer,
|
||||
showDrawer ? a.slide_in_left : a.slide_out_left,
|
||||
]}>
|
||||
<DrawerContent />
|
||||
</View>
|
||||
</View>
|
||||
@@ -109,7 +130,6 @@ const styles = StyleSheet.create({
|
||||
backgroundColor: colors.black, // TODO
|
||||
},
|
||||
drawerMask: {
|
||||
// @ts-ignore web only
|
||||
position: 'fixed',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
@@ -118,10 +138,11 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
drawerContainer: {
|
||||
display: 'flex',
|
||||
// @ts-ignore web only
|
||||
position: 'fixed',
|
||||
top: 0,
|
||||
left: 0,
|
||||
height: '100%',
|
||||
width: 330,
|
||||
maxWidth: '80%',
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user