about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/alf/atoms.ts11
-rw-r--r--src/style.css18
-rw-r--r--src/view/shell/index.web.tsx45
3 files changed, 60 insertions, 14 deletions
diff --git a/src/alf/atoms.ts b/src/alf/atoms.ts
index 6982de75f..ae89fa2cf 100644
--- a/src/alf/atoms.ts
+++ b/src/alf/atoms.ts
@@ -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',
diff --git a/src/style.css b/src/style.css
index dd13b13be..2e118c433 100644
--- a/src/style.css
+++ b/src/style.css
@@ -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);
diff --git a/src/view/shell/index.web.tsx b/src/view/shell/index.web.tsx
index 8c30813ab..e194a49de 100644
--- a/src/view/shell/index.web.tsx
+++ b/src/view/shell/index.web.tsx
@@ -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%',
   },
 })