Prompts refresh (#9781)

* Round boi

* Wrap a few things in Prompt.Content

* Couple tweaks
This commit is contained in:
Eric Bailey
2026-01-27 20:02:55 -06:00
committed by GitHub
parent 220e989f3d
commit 72b7516d9b
7 changed files with 88 additions and 100 deletions
@@ -198,10 +198,12 @@ function AltText({text}: {text: string}) {
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
<Prompt.Outer control={control}> <Prompt.Outer control={control}>
<Prompt.Content>
<Prompt.TitleText> <Prompt.TitleText>
<Trans>Alt Text</Trans> <Trans>Alt Text</Trans>
</Prompt.TitleText> </Prompt.TitleText>
<Prompt.DescriptionText selectable>{text}</Prompt.DescriptionText> <Prompt.DescriptionText selectable>{text}</Prompt.DescriptionText>
</Prompt.Content>
<Prompt.Actions> <Prompt.Actions>
<Prompt.Action <Prompt.Action
onPress={() => control.close()} onPress={() => control.close()}
+24 -38
View File
@@ -1,15 +1,9 @@
import React from 'react' import {createContext, useCallback, useContext, useId, useMemo} from 'react'
import {type GestureResponderEvent, View} from 'react-native' import {type GestureResponderEvent, View} from 'react-native'
import {msg} from '@lingui/macro' import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react' import {useLingui} from '@lingui/react'
import { import {atoms as a, useTheme, type ViewStyleProp, web} from '#/alf'
atoms as a,
useBreakpoints,
useTheme,
type ViewStyleProp,
web,
} from '#/alf'
import {Button, type ButtonColor, ButtonText} from '#/components/Button' import {Button, type ButtonColor, ButtonText} from '#/components/Button'
import * as Dialog from '#/components/Dialog' import * as Dialog from '#/components/Dialog'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
@@ -20,7 +14,7 @@ export {
useDialogControl as usePromptControl, useDialogControl as usePromptControl,
} from '#/components/Dialog' } from '#/components/Dialog'
const Context = React.createContext<{ const Context = createContext<{
titleId: string titleId: string
descriptionId: string descriptionId: string
}>({ }>({
@@ -37,12 +31,15 @@ export function Outer({
}: React.PropsWithChildren<{ }: React.PropsWithChildren<{
control: Dialog.DialogControlProps control: Dialog.DialogControlProps
testID?: string testID?: string
/**
* Native-specific options for the prompt. Extends `BottomSheetViewProps`
*/
nativeOptions?: Omit<BottomSheetViewProps, 'children'> nativeOptions?: Omit<BottomSheetViewProps, 'children'>
}>) { }>) {
const titleId = React.useId() const titleId = useId()
const descriptionId = React.useId() const descriptionId = useId()
const context = React.useMemo( const context = useMemo(
() => ({titleId, descriptionId}), () => ({titleId, descriptionId}),
[titleId, descriptionId], [titleId, descriptionId],
) )
@@ -58,7 +55,7 @@ export function Outer({
<Dialog.ScrollableInner <Dialog.ScrollableInner
accessibilityLabelledBy={titleId} accessibilityLabelledBy={titleId}
accessibilityDescribedBy={descriptionId} accessibilityDescribedBy={descriptionId}
style={web({maxWidth: 400})}> style={web([{maxWidth: 320, borderRadius: 36}])}>
{children} {children}
</Dialog.ScrollableInner> </Dialog.ScrollableInner>
</Context.Provider> </Context.Provider>
@@ -70,7 +67,7 @@ export function TitleText({
children, children,
style, style,
}: React.PropsWithChildren<ViewStyleProp>) { }: React.PropsWithChildren<ViewStyleProp>) {
const {titleId} = React.useContext(Context) const {titleId} = useContext(Context)
return ( return (
<Text <Text
nativeID={titleId} nativeID={titleId}
@@ -78,7 +75,7 @@ export function TitleText({
a.flex_1, a.flex_1,
a.text_2xl, a.text_2xl,
a.font_semi_bold, a.font_semi_bold,
a.pb_sm, a.pb_xs,
a.leading_snug, a.leading_snug,
style, style,
]}> ]}>
@@ -92,7 +89,7 @@ export function DescriptionText({
selectable, selectable,
}: React.PropsWithChildren<{selectable?: boolean}>) { }: React.PropsWithChildren<{selectable?: boolean}>) {
const t = useTheme() const t = useTheme()
const {descriptionId} = React.useContext(Context) const {descriptionId} = useContext(Context)
return ( return (
<Text <Text
nativeID={descriptionId} nativeID={descriptionId}
@@ -103,22 +100,12 @@ export function DescriptionText({
) )
} }
export function Actions({children}: React.PropsWithChildren<{}>) { export function Actions({children}: {children: React.ReactNode}) {
const {gtMobile} = useBreakpoints() return <View style={[a.w_full, a.gap_sm, a.justify_end]}>{children}</View>
}
return ( export function Content({children}: {children: React.ReactNode}) {
<View return <View style={[a.pb_sm]}>{children}</View>
style={[
a.w_full,
a.gap_md,
a.justify_end,
gtMobile
? [a.flex_row, a.flex_row_reverse, a.justify_start]
: [a.flex_col],
]}>
{children}
</View>
)
} }
export function Cancel({ export function Cancel({
@@ -130,9 +117,8 @@ export function Cancel({
cta?: string cta?: string
}) { }) {
const {_} = useLingui() const {_} = useLingui()
const {gtMobile} = useBreakpoints()
const {close} = Dialog.useDialogContext() const {close} = Dialog.useDialogContext()
const onPress = React.useCallback(() => { const onPress = useCallback(() => {
close() close()
}, [close]) }, [close])
@@ -140,7 +126,7 @@ export function Cancel({
<Button <Button
variant="solid" variant="solid"
color="secondary" color="secondary"
size={gtMobile ? 'small' : 'large'} size={'large'}
label={cta || _(msg`Cancel`)} label={cta || _(msg`Cancel`)}
onPress={onPress}> onPress={onPress}>
<ButtonText>{cta || _(msg`Cancel`)}</ButtonText> <ButtonText>{cta || _(msg`Cancel`)}</ButtonText>
@@ -170,9 +156,8 @@ export function Action({
testID?: string testID?: string
}) { }) {
const {_} = useLingui() const {_} = useLingui()
const {gtMobile} = useBreakpoints()
const {close} = Dialog.useDialogContext() const {close} = Dialog.useDialogContext()
const handleOnPress = React.useCallback( const handleOnPress = useCallback(
(e: GestureResponderEvent) => { (e: GestureResponderEvent) => {
close(() => onPress?.(e)) close(() => onPress?.(e))
}, },
@@ -181,9 +166,8 @@ export function Action({
return ( return (
<Button <Button
variant="solid"
color={color} color={color}
size={gtMobile ? 'small' : 'large'} size={'large'}
label={cta || _(msg`Confirm`)} label={cta || _(msg`Confirm`)}
onPress={handleOnPress} onPress={handleOnPress}
testID={testID}> testID={testID}>
@@ -220,8 +204,10 @@ export function Basic({
}>) { }>) {
return ( return (
<Outer control={control} testID="confirmModal"> <Outer control={control} testID="confirmModal">
<Content>
<TitleText>{title}</TitleText> <TitleText>{title}</TitleText>
{description && <DescriptionText>{description}</DescriptionText>} {description && <DescriptionText>{description}</DescriptionText>}
</Content>
<Actions> <Actions>
<Action <Action
cta={confirmButtonCta} cta={confirmButtonCta}
@@ -331,6 +331,7 @@ function Empty() {
</View> </View>
<Prompt.Outer control={confirmDialogControl}> <Prompt.Outer control={confirmDialogControl}>
<Prompt.Content>
<Prompt.TitleText> <Prompt.TitleText>
<Trans>Generate a starter pack</Trans> <Trans>Generate a starter pack</Trans>
</Prompt.TitleText> </Prompt.TitleText>
@@ -340,6 +341,7 @@ function Empty() {
your network. your network.
</Trans> </Trans>
</Prompt.DescriptionText> </Prompt.DescriptionText>
</Prompt.Content>
<Prompt.Actions> <Prompt.Actions>
<Prompt.Action <Prompt.Action
color="primary" color="primary"
@@ -677,6 +677,7 @@ function BackdatedPostIndicator({post}: {post: AppBskyFeedDefs.PostView}) {
</Button> </Button>
<Prompt.Outer control={control}> <Prompt.Outer control={control}>
<Prompt.Content>
<Prompt.TitleText> <Prompt.TitleText>
<Trans>Archived post</Trans> <Trans>Archived post</Trans>
</Prompt.TitleText> </Prompt.TitleText>
@@ -693,17 +694,12 @@ function BackdatedPostIndicator({post}: {post: AppBskyFeedDefs.PostView}) {
. .
</Trans> </Trans>
</Prompt.DescriptionText> </Prompt.DescriptionText>
<Text <Prompt.DescriptionText>
style={[
a.text_md,
a.leading_snug,
t.atoms.text_contrast_high,
a.pb_xl,
]}>
<Trans> <Trans>
Bluesky cannot confirm the authenticity of the claimed date. Bluesky cannot confirm the authenticity of the claimed date.
</Trans> </Trans>
</Text> </Prompt.DescriptionText>
</Prompt.Content>
<Prompt.Actions> <Prompt.Actions>
<Prompt.Action cta={_(msg`Okay`)} onPress={() => {}} /> <Prompt.Action cta={_(msg`Okay`)} onPress={() => {}} />
</Prompt.Actions> </Prompt.Actions>
@@ -212,6 +212,7 @@ function CantSubscribePrompt({
const {_} = useLingui() const {_} = useLingui()
return ( return (
<Prompt.Outer control={control}> <Prompt.Outer control={control}>
<Prompt.Content>
<Prompt.TitleText>Unable to subscribe</Prompt.TitleText> <Prompt.TitleText>Unable to subscribe</Prompt.TitleText>
<Prompt.DescriptionText> <Prompt.DescriptionText>
<Trans> <Trans>
@@ -219,6 +220,7 @@ function CantSubscribePrompt({
reached your limit of twenty. reached your limit of twenty.
</Trans> </Trans>
</Prompt.DescriptionText> </Prompt.DescriptionText>
</Prompt.Content>
<Prompt.Actions> <Prompt.Actions>
<Prompt.Action onPress={() => control.close()} cta={_(msg`OK`)} /> <Prompt.Action onPress={() => control.close()} cta={_(msg`OK`)} />
</Prompt.Actions> </Prompt.Actions>
@@ -5,7 +5,7 @@ import {useLingui} from '@lingui/react'
import {logger} from '#/logger' import {logger} from '#/logger'
import {useAgent, useSessionApi} from '#/state/session' import {useAgent, useSessionApi} from '#/state/session'
import {atoms as a, useBreakpoints, useTheme} from '#/alf' import {atoms as a, useTheme} from '#/alf'
import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import {type DialogOuterProps} from '#/components/Dialog' import {type DialogOuterProps} from '#/components/Dialog'
import {Divider} from '#/components/Divider' import {Divider} from '#/components/Divider'
@@ -32,7 +32,6 @@ function DeactivateAccountDialogInner({
control: DialogOuterProps['control'] control: DialogOuterProps['control']
}) { }) {
const t = useTheme() const t = useTheme()
const {gtMobile} = useBreakpoints()
const {_} = useLingui() const {_} = useLingui()
const agent = useAgent() const agent = useAgent()
const {logoutCurrentAccount} = useSessionApi() const {logoutCurrentAccount} = useSessionApi()
@@ -100,9 +99,8 @@ function DeactivateAccountDialogInner({
</View> </View>
<Prompt.Actions> <Prompt.Actions>
<Button <Button
variant="solid"
color="negative" color="negative"
size={gtMobile ? 'small' : 'large'} size="large"
label={_(msg`Yes, deactivate`)} label={_(msg`Yes, deactivate`)}
onPress={handleDeactivate}> onPress={handleDeactivate}>
<ButtonText>{_(msg`Yes, deactivate`)}</ButtonText> <ButtonText>{_(msg`Yes, deactivate`)}</ButtonText>
@@ -326,15 +326,17 @@ function LandingScreenLoaded({
setIsVisible={setAppClipOverlayVisible} setIsVisible={setAppClipOverlayVisible}
/> />
<Prompt.Outer control={androidDialogControl}> <Prompt.Outer control={androidDialogControl}>
<Prompt.Content>
<Prompt.TitleText> <Prompt.TitleText>
<Trans>Download Bluesky</Trans> <Trans>Download Bluesky</Trans>
</Prompt.TitleText> </Prompt.TitleText>
<Prompt.DescriptionText> <Prompt.DescriptionText>
<Trans> <Trans>
The experience is better in the app. Download Bluesky now and we'll The experience is better in the app. Download Bluesky now and
pick back up where you left off. we'll pick back up where you left off.
</Trans> </Trans>
</Prompt.DescriptionText> </Prompt.DescriptionText>
</Prompt.Content>
<Prompt.Actions> <Prompt.Actions>
<Prompt.Action <Prompt.Action
cta="Download on Google Play" cta="Download on Google Play"