Scope fluid zoom transition to alt text dialog only

Revert the fluid sheet transition from all dialogs except the image
alt text dialog, where it works well. Restore Keyboard.dismiss() calls
in LabelsBtn and ThreadgateBtn that were removed for the transitions.

https://claude.ai/code/session_011cNDhEb2cDgg5QbVuzEyH1
This commit is contained in:
Claude
2026-02-28 23:36:26 +00:00
committed by Samuel Newman
parent 84ff3a5684
commit 4fd92766a6
8 changed files with 21 additions and 75 deletions
+3 -24
View File
@@ -1,14 +1,5 @@
import {cloneElement, Fragment, isValidElement, useMemo} from 'react'
import {
cloneElement,
Fragment,
isValidElement,
useEffect,
useMemo,
useRef,
useState,
} from 'react'
import {
findNodeHandle,
Pressable,
type StyleProp,
type TextStyle,
@@ -55,11 +46,9 @@ export function Root({
control?: Dialog.DialogControlProps
}>) {
const defaultControl = Dialog.useDialogControl()
const triggerRef = useRef<View>(null)
const context = useMemo<ContextType>(
() => ({
control: control || defaultControl,
triggerRef,
}),
[control, defaultControl],
)
@@ -90,7 +79,7 @@ export function Trigger({
pressed,
},
props: {
ref: context.triggerRef,
ref: null,
onPress: context.control.open,
onFocus,
onBlur,
@@ -106,27 +95,17 @@ export function Trigger({
export function Outer({
children,
showCancel,
enableTransition,
}: React.PropsWithChildren<{
showCancel?: boolean
style?: StyleProp<ViewStyle>
enableTransition?: boolean
}>) {
const context = useMenuContext()
const {_} = useLingui()
const [sourceViewTag, setSourceViewTag] = useState<number>()
useEffect(() => {
if (enableTransition && context.triggerRef.current) {
const tag = findNodeHandle(context.triggerRef.current)
if (tag != null) setSourceViewTag(tag)
}
}, [enableTransition, context.triggerRef])
return (
<Dialog.Outer
control={context.control}
nativeOptions={{preventExpansion: true, sourceViewTag}}>
nativeOptions={{preventExpansion: true}}>
<Dialog.Handle />
{/* Re-wrap with context since Dialogs are portal-ed to root */}
<Context.Provider value={context}>
+1 -3
View File
@@ -1,4 +1,4 @@
import {forwardRef, useCallback, useId, useMemo, useRef, useState} from 'react'
import {forwardRef, useCallback, useId, useMemo, useState} from 'react'
import {
Pressable,
type StyleProp,
@@ -62,11 +62,9 @@ export function Root({
}>) {
const {_} = useLingui()
const defaultControl = useMenuControl()
const triggerRef = useRef<View>(null)
const context = useMemo<ContextType>(
() => ({
control: control || defaultControl,
triggerRef,
}),
[control, defaultControl],
)
+1 -3
View File
@@ -3,7 +3,6 @@ import {
type AccessibilityRole,
type GestureResponderEvent,
type PressableProps,
type View,
} from 'react-native'
import type React from 'react'
@@ -13,7 +12,6 @@ import {type Props as SVGIconProps} from '#/components/icons/common'
export type ContextType = {
control: Dialog.DialogOuterProps['control']
triggerRef: React.RefObject<View | null>
}
export type ItemContextType = {
@@ -63,7 +61,7 @@ export type TriggerChildProps =
* object is empty.
*/
props: {
ref: React.RefObject<View | null>
ref: null
onPress: () => void
onFocus: () => void
onBlur: () => void
+3 -8
View File
@@ -1,5 +1,5 @@
import {memo, useCallback, useRef} from 'react'
import {findNodeHandle, View} from 'react-native'
import {memo, useCallback} from 'react'
import {View} from 'react-native'
import {msg, plural} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
@@ -41,7 +41,6 @@ let RepostButton = ({
const requireAuth = useRequireAuth()
const dialogControl = Dialog.useDialogControl()
const formatPostStatCount = useFormatPostStatCount()
const btnRef = useRef<View>(null)
const onPress = () => requireAuth(() => dialogControl.open())
@@ -57,7 +56,6 @@ let RepostButton = ({
return (
<>
<PostControlButton
ref={btnRef}
testID="repostBtn"
active={isReposted}
activeColor={t.palette.positive_500}
@@ -96,10 +94,7 @@ let RepostButton = ({
</PostControlButton>
<Dialog.Outer
control={dialogControl}
nativeOptions={{
preventExpansion: true,
sourceViewTag: findNodeHandle(btnRef.current) ?? undefined,
}}>
nativeOptions={{preventExpansion: true}}>
<Dialog.Handle />
<RepostButtonDialogInner
isReposted={isReposted}
@@ -77,11 +77,9 @@ export type PostInteractionSettingsFormProps = {
*/
export function PostInteractionSettingsControlledDialog({
control,
sourceViewTag,
...rest
}: PostInteractionSettingsFormProps & {
control: Dialog.DialogControlProps
sourceViewTag?: number
}) {
const ax = useAnalytics()
const onClose = useNonReactiveCallback(() => {
@@ -102,7 +100,6 @@ export function PostInteractionSettingsControlledDialog({
nativeOptions={{
preventExpansion: true,
preventDismiss: rest.isDirty && rest.persist,
sourceViewTag,
}}
onClose={onClose}>
<Dialog.Handle />
+6 -18
View File
@@ -1,5 +1,4 @@
import {useState} from 'react'
import {findNodeHandle, View} from 'react-native'
import {Keyboard, View} from 'react-native'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
@@ -30,14 +29,6 @@ export function LabelsBtn({
}) {
const control = Dialog.useDialogControl()
const {_} = useLingui()
const [sourceViewTag, setSourceViewTag] = useState<number>()
const btnRef = (node: View | null) => {
if (node) {
const tag = findNodeHandle(node)
if (tag != null) setSourceViewTag(tag)
}
}
const hasLabel = labels.length > 0
@@ -60,11 +51,13 @@ export function LabelsBtn({
return (
<>
<Button
ref={btnRef}
color="secondary"
size="small"
testID="labelsBtn"
onPress={() => control.open()}
onPress={() => {
Keyboard.dismiss()
control.open()
}}
label={_(msg`Content warnings`)}
accessibilityHint={_(
msg`Opens a dialog to add a content warning to your post`,
@@ -80,12 +73,7 @@ export function LabelsBtn({
<ButtonIcon icon={TinyChevronIcon} size="2xs" />
</Button>
<Dialog.Outer
control={control}
nativeOptions={{
preventExpansion: true,
sourceViewTag,
}}>
<Dialog.Outer control={control} nativeOptions={{preventExpansion: true}}>
<Dialog.Handle />
<DialogInner
labels={labels}
@@ -75,7 +75,7 @@ export function PostLanguageSelect({
<LanguageBtn currentLanguages={currentLanguages} {...props} />
)}
</Menu.Trigger>
<Menu.Outer enableTransition>
<Menu.Outer>
<Menu.Group>
{dedupedHistory.map(historyItem => {
const langCodes = historyItem.split(',')
@@ -1,10 +1,5 @@
import {useEffect, useMemo, useState} from 'react'
import {
findNodeHandle,
type StyleProp,
type View,
type ViewStyle,
} from 'react-native'
import {Keyboard, type StyleProp, type ViewStyle} from 'react-native'
import {type AnimatedStyle} from 'react-native-reanimated'
import {type AppBskyFeedPostgate} from '@atproto/api'
import {msg} from '@lingui/core/macro'
@@ -31,6 +26,7 @@ import {Group3_Stroke2_Corner0_Rounded as GroupIcon} from '#/components/icons/Gr
import * as Tooltip from '#/components/Tooltip'
import {Text} from '#/components/Typography'
import {useAnalytics} from '#/analytics'
import {IS_NATIVE} from '#/env'
import {useThreadgateNudged} from '#/storage/hooks/threadgate-nudged'
export function ThreadgateBtn({
@@ -50,13 +46,6 @@ export function ThreadgateBtn({
const {_} = useLingui()
const ax = useAnalytics()
const control = Dialog.useDialogControl()
const [sourceViewTag, setSourceViewTag] = useState<number>()
const btnRef = (node: View | null) => {
if (node) {
const tag = findNodeHandle(node)
if (tag != null) setSourceViewTag(tag)
}
}
const [threadgateNudged, setThreadgateNudged] = useThreadgateNudged()
const [showTooltip, setShowTooltip] = useState(false)
const [tooltipWasShown] = useState(!threadgateNudged)
@@ -84,6 +73,10 @@ export function ThreadgateBtn({
nudged: tooltipWasShown,
})
if (IS_NATIVE && Keyboard.isVisible()) {
Keyboard.dismiss()
}
setShowTooltip(false)
setThreadgateNudged(true)
@@ -152,7 +145,6 @@ export function ThreadgateBtn({
position="top">
<Tooltip.Target>
<Button
ref={btnRef}
color={showTooltip ? 'primary_subtle' : 'secondary'}
size="small"
testID="openReplyGateButton"
@@ -175,7 +167,6 @@ export function ThreadgateBtn({
<PostInteractionSettingsControlledDialog
control={control}
sourceViewTag={sourceViewTag}
onSave={() => {
if (persist) {
persistChanges({