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>
</TouchableOpacity>
<Prompt.Outer control={control}>
<Prompt.TitleText>
<Trans>Alt Text</Trans>
</Prompt.TitleText>
<Prompt.DescriptionText selectable>{text}</Prompt.DescriptionText>
<Prompt.Content>
<Prompt.TitleText>
<Trans>Alt Text</Trans>
</Prompt.TitleText>
<Prompt.DescriptionText selectable>{text}</Prompt.DescriptionText>
</Prompt.Content>
<Prompt.Actions>
<Prompt.Action
onPress={() => control.close()}
+26 -40
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 {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {
atoms as a,
useBreakpoints,
useTheme,
type ViewStyleProp,
web,
} from '#/alf'
import {atoms as a, useTheme, type ViewStyleProp, web} from '#/alf'
import {Button, type ButtonColor, ButtonText} from '#/components/Button'
import * as Dialog from '#/components/Dialog'
import {Text} from '#/components/Typography'
@@ -20,7 +14,7 @@ export {
useDialogControl as usePromptControl,
} from '#/components/Dialog'
const Context = React.createContext<{
const Context = createContext<{
titleId: string
descriptionId: string
}>({
@@ -37,12 +31,15 @@ export function Outer({
}: React.PropsWithChildren<{
control: Dialog.DialogControlProps
testID?: string
/**
* Native-specific options for the prompt. Extends `BottomSheetViewProps`
*/
nativeOptions?: Omit<BottomSheetViewProps, 'children'>
}>) {
const titleId = React.useId()
const descriptionId = React.useId()
const titleId = useId()
const descriptionId = useId()
const context = React.useMemo(
const context = useMemo(
() => ({titleId, descriptionId}),
[titleId, descriptionId],
)
@@ -58,7 +55,7 @@ export function Outer({
<Dialog.ScrollableInner
accessibilityLabelledBy={titleId}
accessibilityDescribedBy={descriptionId}
style={web({maxWidth: 400})}>
style={web([{maxWidth: 320, borderRadius: 36}])}>
{children}
</Dialog.ScrollableInner>
</Context.Provider>
@@ -70,7 +67,7 @@ export function TitleText({
children,
style,
}: React.PropsWithChildren<ViewStyleProp>) {
const {titleId} = React.useContext(Context)
const {titleId} = useContext(Context)
return (
<Text
nativeID={titleId}
@@ -78,7 +75,7 @@ export function TitleText({
a.flex_1,
a.text_2xl,
a.font_semi_bold,
a.pb_sm,
a.pb_xs,
a.leading_snug,
style,
]}>
@@ -92,7 +89,7 @@ export function DescriptionText({
selectable,
}: React.PropsWithChildren<{selectable?: boolean}>) {
const t = useTheme()
const {descriptionId} = React.useContext(Context)
const {descriptionId} = useContext(Context)
return (
<Text
nativeID={descriptionId}
@@ -103,22 +100,12 @@ export function DescriptionText({
)
}
export function Actions({children}: React.PropsWithChildren<{}>) {
const {gtMobile} = useBreakpoints()
export function Actions({children}: {children: React.ReactNode}) {
return <View style={[a.w_full, a.gap_sm, a.justify_end]}>{children}</View>
}
return (
<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 Content({children}: {children: React.ReactNode}) {
return <View style={[a.pb_sm]}>{children}</View>
}
export function Cancel({
@@ -130,9 +117,8 @@ export function Cancel({
cta?: string
}) {
const {_} = useLingui()
const {gtMobile} = useBreakpoints()
const {close} = Dialog.useDialogContext()
const onPress = React.useCallback(() => {
const onPress = useCallback(() => {
close()
}, [close])
@@ -140,7 +126,7 @@ export function Cancel({
<Button
variant="solid"
color="secondary"
size={gtMobile ? 'small' : 'large'}
size={'large'}
label={cta || _(msg`Cancel`)}
onPress={onPress}>
<ButtonText>{cta || _(msg`Cancel`)}</ButtonText>
@@ -170,9 +156,8 @@ export function Action({
testID?: string
}) {
const {_} = useLingui()
const {gtMobile} = useBreakpoints()
const {close} = Dialog.useDialogContext()
const handleOnPress = React.useCallback(
const handleOnPress = useCallback(
(e: GestureResponderEvent) => {
close(() => onPress?.(e))
},
@@ -181,9 +166,8 @@ export function Action({
return (
<Button
variant="solid"
color={color}
size={gtMobile ? 'small' : 'large'}
size={'large'}
label={cta || _(msg`Confirm`)}
onPress={handleOnPress}
testID={testID}>
@@ -220,8 +204,10 @@ export function Basic({
}>) {
return (
<Outer control={control} testID="confirmModal">
<TitleText>{title}</TitleText>
{description && <DescriptionText>{description}</DescriptionText>}
<Content>
<TitleText>{title}</TitleText>
{description && <DescriptionText>{description}</DescriptionText>}
</Content>
<Actions>
<Action
cta={confirmButtonCta}
@@ -331,15 +331,17 @@ function Empty() {
</View>
<Prompt.Outer control={confirmDialogControl}>
<Prompt.TitleText>
<Trans>Generate a starter pack</Trans>
</Prompt.TitleText>
<Prompt.DescriptionText>
<Trans>
Bluesky will choose a set of recommended accounts from people in
your network.
</Trans>
</Prompt.DescriptionText>
<Prompt.Content>
<Prompt.TitleText>
<Trans>Generate a starter pack</Trans>
</Prompt.TitleText>
<Prompt.DescriptionText>
<Trans>
Bluesky will choose a set of recommended accounts from people in
your network.
</Trans>
</Prompt.DescriptionText>
</Prompt.Content>
<Prompt.Actions>
<Prompt.Action
color="primary"
@@ -677,33 +677,29 @@ function BackdatedPostIndicator({post}: {post: AppBskyFeedDefs.PostView}) {
</Button>
<Prompt.Outer control={control}>
<Prompt.TitleText>
<Trans>Archived post</Trans>
</Prompt.TitleText>
<Prompt.DescriptionText>
<Trans>
This post claims to have been created on{' '}
<RNText style={[a.font_semi_bold]}>
{niceDate(i18n, createdAt)}
</RNText>
, but was first seen by Bluesky on{' '}
<RNText style={[a.font_semi_bold]}>
{niceDate(i18n, indexedAt)}
</RNText>
.
</Trans>
</Prompt.DescriptionText>
<Text
style={[
a.text_md,
a.leading_snug,
t.atoms.text_contrast_high,
a.pb_xl,
]}>
<Trans>
Bluesky cannot confirm the authenticity of the claimed date.
</Trans>
</Text>
<Prompt.Content>
<Prompt.TitleText>
<Trans>Archived post</Trans>
</Prompt.TitleText>
<Prompt.DescriptionText>
<Trans>
This post claims to have been created on{' '}
<RNText style={[a.font_semi_bold]}>
{niceDate(i18n, createdAt)}
</RNText>
, but was first seen by Bluesky on{' '}
<RNText style={[a.font_semi_bold]}>
{niceDate(i18n, indexedAt)}
</RNText>
.
</Trans>
</Prompt.DescriptionText>
<Prompt.DescriptionText>
<Trans>
Bluesky cannot confirm the authenticity of the claimed date.
</Trans>
</Prompt.DescriptionText>
</Prompt.Content>
<Prompt.Actions>
<Prompt.Action cta={_(msg`Okay`)} onPress={() => {}} />
</Prompt.Actions>
@@ -212,13 +212,15 @@ function CantSubscribePrompt({
const {_} = useLingui()
return (
<Prompt.Outer control={control}>
<Prompt.TitleText>Unable to subscribe</Prompt.TitleText>
<Prompt.DescriptionText>
<Trans>
We're sorry! You can only subscribe to twenty labelers, and you've
reached your limit of twenty.
</Trans>
</Prompt.DescriptionText>
<Prompt.Content>
<Prompt.TitleText>Unable to subscribe</Prompt.TitleText>
<Prompt.DescriptionText>
<Trans>
We're sorry! You can only subscribe to twenty labelers, and you've
reached your limit of twenty.
</Trans>
</Prompt.DescriptionText>
</Prompt.Content>
<Prompt.Actions>
<Prompt.Action onPress={() => control.close()} cta={_(msg`OK`)} />
</Prompt.Actions>
@@ -5,7 +5,7 @@ import {useLingui} from '@lingui/react'
import {logger} from '#/logger'
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 {type DialogOuterProps} from '#/components/Dialog'
import {Divider} from '#/components/Divider'
@@ -32,7 +32,6 @@ function DeactivateAccountDialogInner({
control: DialogOuterProps['control']
}) {
const t = useTheme()
const {gtMobile} = useBreakpoints()
const {_} = useLingui()
const agent = useAgent()
const {logoutCurrentAccount} = useSessionApi()
@@ -100,9 +99,8 @@ function DeactivateAccountDialogInner({
</View>
<Prompt.Actions>
<Button
variant="solid"
color="negative"
size={gtMobile ? 'small' : 'large'}
size="large"
label={_(msg`Yes, deactivate`)}
onPress={handleDeactivate}>
<ButtonText>{_(msg`Yes, deactivate`)}</ButtonText>
@@ -326,15 +326,17 @@ function LandingScreenLoaded({
setIsVisible={setAppClipOverlayVisible}
/>
<Prompt.Outer control={androidDialogControl}>
<Prompt.TitleText>
<Trans>Download Bluesky</Trans>
</Prompt.TitleText>
<Prompt.DescriptionText>
<Trans>
The experience is better in the app. Download Bluesky now and we'll
pick back up where you left off.
</Trans>
</Prompt.DescriptionText>
<Prompt.Content>
<Prompt.TitleText>
<Trans>Download Bluesky</Trans>
</Prompt.TitleText>
<Prompt.DescriptionText>
<Trans>
The experience is better in the app. Download Bluesky now and
we'll pick back up where you left off.
</Trans>
</Prompt.DescriptionText>
</Prompt.Content>
<Prompt.Actions>
<Prompt.Action
cta="Download on Google Play"