Make sheet zoom transition opt-in, enable for composer dialogs

Switch `disableTransition` (opt-out) to `enableTransition` (opt-in) on
Menu.Outer so the zoom transition is only used where explicitly wanted.
Enable the zoom transition on three composer controls: the language
menu, the labels dialog, and the who-can-reply dialog.

https://claude.ai/code/session_011cNDhEb2cDgg5QbVuzEyH1
This commit is contained in:
Claude
2026-02-28 20:11:38 +00:00
committed by Samuel Newman
parent 8e26b21806
commit ce397db233
7 changed files with 32 additions and 12 deletions
+5 -5
View File
@@ -98,17 +98,17 @@ export function Trigger({
export function Outer({ export function Outer({
children, children,
showCancel, showCancel,
disableTransition, enableTransition,
}: React.PropsWithChildren<{ }: React.PropsWithChildren<{
showCancel?: boolean showCancel?: boolean
style?: StyleProp<ViewStyle> style?: StyleProp<ViewStyle>
disableTransition?: boolean enableTransition?: boolean
}>) { }>) {
const context = useMenuContext() const context = useMenuContext()
const {_} = useLingui() const {_} = useLingui()
const sourceViewTag = disableTransition const sourceViewTag = enableTransition
? undefined ? (findNodeHandle(context.triggerRef.current) ?? undefined)
: (findNodeHandle(context.triggerRef.current) ?? undefined) : undefined
return ( return (
<Dialog.Outer <Dialog.Outer
@@ -77,9 +77,11 @@ export type PostInteractionSettingsFormProps = {
*/ */
export function PostInteractionSettingsControlledDialog({ export function PostInteractionSettingsControlledDialog({
control, control,
sourceViewTag,
...rest ...rest
}: PostInteractionSettingsFormProps & { }: PostInteractionSettingsFormProps & {
control: Dialog.DialogControlProps control: Dialog.DialogControlProps
sourceViewTag?: number
}) { }) {
const ax = useAnalytics() const ax = useAnalytics()
const onClose = useNonReactiveCallback(() => { const onClose = useNonReactiveCallback(() => {
@@ -100,6 +102,7 @@ export function PostInteractionSettingsControlledDialog({
nativeOptions={{ nativeOptions={{
preventExpansion: true, preventExpansion: true,
preventDismiss: rest.isDirty && rest.persist, preventDismiss: rest.isDirty && rest.persist,
sourceViewTag,
}} }}
onClose={onClose}> onClose={onClose}>
<Dialog.Handle /> <Dialog.Handle />
@@ -40,7 +40,7 @@ export function HeaderDropdown({
</Button> </Button>
)} )}
</Menu.Trigger> </Menu.Trigger>
<Menu.Outer disableTransition> <Menu.Outer>
<Menu.LabelText> <Menu.LabelText>
<Trans>Show replies as</Trans> <Trans>Show replies as</Trans>
</Menu.LabelText> </Menu.LabelText>
+10 -2
View File
@@ -1,4 +1,5 @@
import {Keyboard, View} from 'react-native' import {useRef} from 'react'
import {findNodeHandle, Keyboard, View} from 'react-native'
import {msg} from '@lingui/core/macro' import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro' import {Trans} from '@lingui/react/macro'
@@ -29,6 +30,7 @@ export function LabelsBtn({
}) { }) {
const control = Dialog.useDialogControl() const control = Dialog.useDialogControl()
const {_} = useLingui() const {_} = useLingui()
const btnRef = useRef<View>(null)
const hasLabel = labels.length > 0 const hasLabel = labels.length > 0
@@ -51,6 +53,7 @@ export function LabelsBtn({
return ( return (
<> <>
<Button <Button
ref={btnRef}
color="secondary" color="secondary"
size="small" size="small"
testID="labelsBtn" testID="labelsBtn"
@@ -73,7 +76,12 @@ export function LabelsBtn({
<ButtonIcon icon={TinyChevronIcon} size="2xs" /> <ButtonIcon icon={TinyChevronIcon} size="2xs" />
</Button> </Button>
<Dialog.Outer control={control} nativeOptions={{preventExpansion: true}}> <Dialog.Outer
control={control}
nativeOptions={{
preventExpansion: true,
sourceViewTag: findNodeHandle(btnRef.current) ?? undefined,
}}>
<Dialog.Handle /> <Dialog.Handle />
<DialogInner <DialogInner
labels={labels} labels={labels}
@@ -75,7 +75,7 @@ export function PostLanguageSelect({
<LanguageBtn currentLanguages={currentLanguages} {...props} /> <LanguageBtn currentLanguages={currentLanguages} {...props} />
)} )}
</Menu.Trigger> </Menu.Trigger>
<Menu.Outer> <Menu.Outer enableTransition>
<Menu.Group> <Menu.Group>
{dedupedHistory.map(historyItem => { {dedupedHistory.map(historyItem => {
const langCodes = historyItem.split(',') const langCodes = historyItem.split(',')
@@ -1,5 +1,11 @@
import {useEffect, useMemo, useState} from 'react' import {useEffect, useMemo, useRef, useState} from 'react'
import {Keyboard, type StyleProp, type ViewStyle} from 'react-native' import {
findNodeHandle,
Keyboard,
type StyleProp,
type View,
type ViewStyle,
} from 'react-native'
import {type AnimatedStyle} from 'react-native-reanimated' import {type AnimatedStyle} from 'react-native-reanimated'
import {type AppBskyFeedPostgate} from '@atproto/api' import {type AppBskyFeedPostgate} from '@atproto/api'
import {msg} from '@lingui/core/macro' import {msg} from '@lingui/core/macro'
@@ -46,6 +52,7 @@ export function ThreadgateBtn({
const {_} = useLingui() const {_} = useLingui()
const ax = useAnalytics() const ax = useAnalytics()
const control = Dialog.useDialogControl() const control = Dialog.useDialogControl()
const btnRef = useRef<View>(null)
const [threadgateNudged, setThreadgateNudged] = useThreadgateNudged() const [threadgateNudged, setThreadgateNudged] = useThreadgateNudged()
const [showTooltip, setShowTooltip] = useState(false) const [showTooltip, setShowTooltip] = useState(false)
const [tooltipWasShown] = useState(!threadgateNudged) const [tooltipWasShown] = useState(!threadgateNudged)
@@ -145,6 +152,7 @@ export function ThreadgateBtn({
position="top"> position="top">
<Tooltip.Target> <Tooltip.Target>
<Button <Button
ref={btnRef}
color={showTooltip ? 'primary_subtle' : 'secondary'} color={showTooltip ? 'primary_subtle' : 'secondary'}
size="small" size="small"
testID="openReplyGateButton" testID="openReplyGateButton"
@@ -167,6 +175,7 @@ export function ThreadgateBtn({
<PostInteractionSettingsControlledDialog <PostInteractionSettingsControlledDialog
control={control} control={control}
sourceViewTag={findNodeHandle(btnRef.current) ?? undefined}
onSave={() => { onSave={() => {
if (persist) { if (persist) {
persistChanges({ persistChanges({
+1 -1
View File
@@ -262,7 +262,7 @@ let ProfileMenu = ({
}} }}
</Menu.Trigger> </Menu.Trigger>
<Menu.Outer style={{minWidth: 170}} disableTransition> <Menu.Outer style={{minWidth: 170}}>
<Menu.Group> <Menu.Group>
<Menu.Item <Menu.Item
testID="profileHeaderDropdownShareBtn" testID="profileHeaderDropdownShareBtn"