mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
0
fork

Configure Feed

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

Better animations for dialogs, animate web composer (#7703)

* animation atoms, use for modals

* respect reduced motion

* simplify animtions

* fix atoms

authored by samuel.fm and committed by

GitHub 5d3e2e14 521a764d

+58 -28
+20
src/alf/atoms.ts
··· 965 965 transitionDelay: '50ms', 966 966 }), 967 967 968 + /* 969 + * Animaations 970 + */ 971 + fade_in: web({ 972 + animation: 'fadeIn ease-out 0.15s', 973 + }), 974 + fade_out: web({ 975 + animation: 'fadeOut ease-out 0.15s', 976 + }), 977 + zoom_in: web({ 978 + animation: 'zoomIn ease-out 0.1s', 979 + }), 980 + zoom_out: web({ 981 + animation: 'zoomOut ease-out 0.1s', 982 + }), 983 + // special composite animation for dialogs 984 + zoom_fade_in: web({ 985 + animation: 'zoomIn ease-out 0.1s, fadeIn ease-out 0.1s', 986 + }), 987 + 968 988 /** 969 989 * {@link Layout.SCROLLBAR_OFFSET} 970 990 */
+10 -14
src/components/Dialog/index.web.tsx
··· 15 15 import {RemoveScrollBar} from 'react-remove-scroll-bar' 16 16 17 17 import {logger} from '#/logger' 18 + import {useA11y} from '#/state/a11y' 18 19 import {useDialogStateControlContext} from '#/state/dialogs' 19 20 import {atoms as a, flatten, useBreakpoints, useTheme, web} from '#/alf' 20 21 import {Button, ButtonIcon} from '#/components/Button' ··· 152 153 const t = useTheme() 153 154 const {close} = React.useContext(Context) 154 155 const {gtMobile} = useBreakpoints() 156 + const {reduceMotionEnabled} = useA11y() 155 157 useFocusGuards() 156 158 return ( 157 159 <FocusScope loop asChild trapped> ··· 161 163 aria-label={label} 162 164 aria-labelledby={accessibilityLabelledBy} 163 165 aria-describedby={accessibilityDescribedBy} 164 - // @ts-ignore web only -prf 166 + // @ts-expect-error web only -prf 165 167 onClick={stopPropagation} 166 168 onStartShouldSetResponder={_ => true} 167 169 onTouchEnd={stopPropagation} ··· 177 179 shadowColor: t.palette.black, 178 180 shadowOpacity: t.name === 'light' ? 0.1 : 0.4, 179 181 shadowRadius: 30, 180 - // @ts-ignore web only 181 - animation: 'fadeIn ease-out 0.1s', 182 182 }, 183 - flatten(style), 183 + !reduceMotionEnabled && a.zoom_fade_in, 184 + style, 184 185 ])}> 185 186 <DismissableLayer 186 187 onInteractOutside={preventDefault} ··· 216 217 style={[ 217 218 a.overflow_hidden, 218 219 a.px_0, 219 - // @ts-ignore web only -sfn 220 + // @ts-expect-error web only -sfn 220 221 {maxHeight: 'calc(-36px + 100vh)'}, 221 222 webInnerStyle, 222 223 ]} ··· 262 263 263 264 function Backdrop() { 264 265 const t = useTheme() 266 + const {reduceMotionEnabled} = useA11y() 265 267 return ( 266 - <View 267 - style={{ 268 - opacity: 0.8, 269 - }}> 268 + <View style={{opacity: 0.8}}> 270 269 <View 271 270 style={[ 272 271 a.fixed, 273 272 a.inset_0, 274 - { 275 - backgroundColor: t.palette.black, 276 - // @ts-ignore web only 277 - animation: 'fadeIn ease-out 0.15s', 278 - }, 273 + {backgroundColor: t.palette.black}, 274 + !reduceMotionEnabled && a.fade_in, 279 275 ]} 280 276 /> 281 277 </View>
+9
src/style.css
··· 205 205 } 206 206 } 207 207 208 + @keyframes zoomIn { 209 + from { 210 + transform: scale(0.95); 211 + } 212 + to { 213 + transform: scale(1); 214 + } 215 + } 216 + 208 217 .force-no-clicks > *, 209 218 .force-no-clicks * { 210 219 pointer-events: none !important;
+19 -14
src/view/shell/Composer.web.tsx
··· 5 5 import {FocusScope} from '@radix-ui/react-focus-scope' 6 6 import {RemoveScrollBar} from 'react-remove-scroll-bar' 7 7 8 + import {useA11y} from '#/state/a11y' 8 9 import {useModals} from '#/state/modals' 9 10 import {ComposerOpts, useComposerState} from '#/state/shell/composer' 10 11 import { ··· 12 13 EmojiPickerPosition, 13 14 EmojiPickerState, 14 15 } from '#/view/com/composer/text-input/web/EmojiPicker.web' 15 - import {useBreakpoints, useTheme} from '#/alf' 16 + import {atoms as a, flatten, useBreakpoints, useTheme} from '#/alf' 16 17 import {ComposePost, useComposerCancelRef} from '../com/composer/Composer' 17 18 18 19 const BOTTOM_BAR_HEIGHT = 61 ··· 41 42 const {isModalActive} = useModals() 42 43 const t = useTheme() 43 44 const {gtMobile} = useBreakpoints() 45 + const {reduceMotionEnabled} = useA11y() 44 46 const [pickerState, setPickerState] = React.useState<EmojiPickerState>({ 45 47 isOpen: false, 46 48 pos: {top: 0, left: 0, right: 0, bottom: 0, nextFocusRef: null}, ··· 71 73 <DismissableLayer 72 74 role="dialog" 73 75 aria-modal 74 - style={{ 75 - position: 'fixed', 76 - top: 0, 77 - left: 0, 78 - width: '100%', 79 - height: '100%', 80 - backgroundColor: '#000c', 81 - display: 'flex', 82 - flexDirection: 'column', 83 - alignItems: 'center', 84 - }} 76 + style={flatten([ 77 + {position: 'fixed'}, 78 + a.inset_0, 79 + {backgroundColor: '#000c'}, 80 + a.flex, 81 + a.flex_col, 82 + a.align_center, 83 + !reduceMotionEnabled && a.fade_in, 84 + ])} 85 85 onFocusOutside={evt => evt.preventDefault()} 86 86 onInteractOutside={evt => evt.preventDefault()} 87 87 onDismiss={() => { ··· 96 96 !gtMobile && styles.containerMobile, 97 97 t.atoms.bg, 98 98 t.atoms.border_contrast_medium, 99 + !reduceMotionEnabled && [ 100 + a.zoom_fade_in, 101 + {animationDelay: 0.1}, 102 + {animationFillMode: 'backwards'}, 103 + ], 99 104 ]}> 100 105 <ComposePost 101 106 cancelRef={ref} ··· 123 128 borderRadius: 8, 124 129 marginBottom: 0, 125 130 borderWidth: 1, 126 - // @ts-ignore web only 131 + // @ts-expect-error web only 127 132 maxHeight: 'calc(100% - (40px * 2))', 128 133 overflow: 'hidden', 129 134 }, 130 135 containerMobile: { 131 136 borderRadius: 0, 132 137 marginBottom: BOTTOM_BAR_HEIGHT, 133 - // @ts-ignore web only 138 + // @ts-expect-error web only 134 139 maxHeight: `calc(100% - ${BOTTOM_BAR_HEIGHT}px)`, 135 140 }, 136 141 })