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:
@@ -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>
|
||||||
|
|||||||
@@ -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({
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user