Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Animate drawer menu on mobile web (#7711)

* slide in/out drawer

* increase width slightly

* exponential easing function

authored by

Samuel Newman and committed by
GitHub
1a3ecdf6 66f5e3a8

+60 -14
+9 -2
src/alf/atoms.ts
··· 68 68 * Used for the outermost components on screens, to ensure that they can fill 69 69 * the screen and extend beyond. 70 70 */ 71 - // @ts-ignore - web only minHeight string 72 71 util_screen_outer: [ 73 72 web({ 74 73 minHeight: '100vh', ··· 76 75 native({ 77 76 height: '100%', 78 77 }), 79 - ] as ViewStyle, 78 + ] as StyleProp<ViewStyle>, 80 79 81 80 /* 82 81 * Theme-independent bg colors ··· 979 978 }), 980 979 zoom_out: web({ 981 980 animation: 'zoomOut ease-out 0.1s', 981 + }), 982 + slide_in_left: web({ 983 + // exponential easing function 984 + animation: 'slideInLeft cubic-bezier(0.16, 1, 0.3, 1) 0.5s', 985 + }), 986 + slide_out_left: web({ 987 + animation: 'slideOutLeft ease-in 0.15s', 988 + animationFillMode: 'forwards', 982 989 }), 983 990 // special composite animation for dialogs 984 991 zoom_fade_in: web({
+18
src/style.css
··· 215 215 } 216 216 } 217 217 218 + @keyframes slideInLeft { 219 + from { 220 + transform: translateX(-100%); 221 + } 222 + to { 223 + transform: translateX(0); 224 + } 225 + } 226 + 227 + @keyframes slideOutLeft { 228 + from { 229 + transform: translateX(0); 230 + } 231 + to { 232 + transform: translateX(-100%); 233 + } 234 + } 235 + 218 236 /* animating radix dropdowns requires knowing the data attributes */ 219 237 .dropdown-menu-transform-origin > * { 220 238 transform-origin: var(--radix-dropdown-menu-content-transform-origin);
+33 -12
src/view/shell/index.web.tsx
··· 1 - import React, {useEffect} from 'react' 1 + import {useEffect, useLayoutEffect, useState} from 'react' 2 2 import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native' 3 3 import {msg} from '@lingui/macro' 4 4 import {useLingui} from '@lingui/react' ··· 33 33 const closeAllActiveElements = useCloseAllActiveElements() 34 34 const {_} = useLingui() 35 35 const showDrawer = !isDesktop && isDrawerOpen 36 + const [showDrawerDelayedExit, setShowDrawerDelayedExit] = useState(showDrawer) 37 + 38 + useLayoutEffect(() => { 39 + if (showDrawer !== showDrawerDelayedExit) { 40 + if (showDrawer) { 41 + setShowDrawerDelayedExit(true) 42 + } else { 43 + const timeout = setTimeout(() => { 44 + setShowDrawerDelayedExit(false) 45 + }, 160) 46 + return () => clearTimeout(timeout) 47 + } 48 + } 49 + }, [showDrawer, showDrawerDelayedExit]) 36 50 37 51 useComposerKeyboardShortcut() 38 52 useIntentHandler() ··· 56 70 <Lightbox /> 57 71 <PortalOutlet /> 58 72 59 - {showDrawer && ( 73 + {showDrawerDelayedExit && ( 60 74 <> 61 75 <RemoveScrollBar /> 62 76 <TouchableWithoutFeedback ··· 66 80 setDrawerOpen(false) 67 81 } 68 82 }} 69 - accessibilityLabel={_(msg`Close navigation footer`)} 70 - accessibilityHint={_(msg`Closes bottom navigation bar`)}> 83 + accessibilityLabel={_(msg`Close drawer menu`)} 84 + accessibilityHint=""> 71 85 <View 72 86 style={[ 73 87 styles.drawerMask, 74 88 { 75 - backgroundColor: select(t.name, { 76 - light: 'rgba(0, 57, 117, 0.1)', 77 - dark: 'rgba(1, 82, 168, 0.1)', 78 - dim: 'rgba(10, 13, 16, 0.8)', 79 - }), 89 + backgroundColor: showDrawer 90 + ? select(t.name, { 91 + light: 'rgba(0, 57, 117, 0.1)', 92 + dark: 'rgba(1, 82, 168, 0.1)', 93 + dim: 'rgba(10, 13, 16, 0.8)', 94 + }) 95 + : 'transparent', 80 96 }, 97 + a.transition_color, 81 98 ]}> 82 - <View style={styles.drawerContainer}> 99 + <View 100 + style={[ 101 + styles.drawerContainer, 102 + showDrawer ? a.slide_in_left : a.slide_out_left, 103 + ]}> 83 104 <DrawerContent /> 84 105 </View> 85 106 </View> ··· 109 130 backgroundColor: colors.black, // TODO 110 131 }, 111 132 drawerMask: { 112 - // @ts-ignore web only 113 133 position: 'fixed', 114 134 width: '100%', 115 135 height: '100%', ··· 118 138 }, 119 139 drawerContainer: { 120 140 display: 'flex', 121 - // @ts-ignore web only 122 141 position: 'fixed', 123 142 top: 0, 124 143 left: 0, 125 144 height: '100%', 145 + width: 330, 146 + maxWidth: '80%', 126 147 }, 127 148 })