Update admonition component (#9068)

* update admonition component

* fix linting, adominition alighment

* design tweak

* edge cases for admonition, update storybook

* Update src/components/Admonition.tsx

Co-authored-by: Samuel Newman <mozzius@protonmail.com>

* fix mobile version

* change button style

---------

Co-authored-by: Samuel Newman <mozzius@protonmail.com>
This commit is contained in:
Chenyu
2025-09-30 05:27:19 -07:00
committed by GitHub
parent c7ce827bfe
commit f82a6188e6
7 changed files with 130 additions and 37 deletions
+44 -24
View File
@@ -3,17 +3,13 @@ import {type StyleProp, View, type ViewStyle} from 'react-native'
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
import {Button as BaseButton, type ButtonProps} from '#/components/Button'
import {CircleInfo_Stroke2_Corner0_Rounded as ErrorIcon} from '#/components/icons/CircleInfo'
import {Eye_Stroke2_Corner0_Rounded as InfoIcon} from '#/components/icons/Eye'
import {Leaf_Stroke2_Corner0_Rounded as TipIcon} from '#/components/icons/Leaf'
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfoIcon} from '#/components/icons/CircleInfo'
import {CircleX_Stroke2_Corner0_Rounded as CircleXIcon} from '#/components/icons/CircleX'
import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning'
import {Text as BaseText, type TextProps} from '#/components/Typography'
export const colors = {
warning: {
light: '#DFBC00',
dark: '#BFAF1F',
},
warning: '#FFC404',
}
type Context = {
@@ -29,29 +25,44 @@ export function Icon() {
const t = useTheme()
const {type} = useContext(Context)
const Icon = {
info: InfoIcon,
tip: TipIcon,
info: CircleInfoIcon,
tip: CircleInfoIcon,
warning: WarningIcon,
error: ErrorIcon,
error: CircleXIcon,
}[type]
const fill = {
info: t.atoms.text_contrast_medium.color,
tip: t.palette.primary_500,
warning: colors.warning.light,
warning: colors.warning,
error: t.palette.negative_500,
}[type]
return <Icon fill={fill} size="md" />
}
export function Content({
children,
style,
...rest
}: {
children: React.ReactNode
style?: StyleProp<ViewStyle>
}) {
return (
<View
style={[a.gap_sm, a.flex_1, {minHeight: 20}, a.justify_center, style]}
{...rest}>
{children}
</View>
)
}
export function Text({
children,
style,
...rest
}: Pick<TextProps, 'children' | 'style'>) {
return (
<BaseText
{...rest}
style={[a.flex_1, a.text_sm, a.leading_snug, a.pr_md, style]}>
<BaseText {...rest} style={[a.text_sm, a.leading_snug, a.pr_md, style]}>
{children}
</BaseText>
)
@@ -60,17 +71,23 @@ export function Text({
export function Button({
children,
...props
}: Omit<ButtonProps, 'size' | 'variant' | 'color'>) {
}: Omit<ButtonProps, 'size' | 'variant'>) {
return (
<BaseButton size="tiny" variant="outline" color="secondary" {...props}>
<BaseButton size="tiny" {...props}>
{children}
</BaseButton>
)
}
export function Row({children}: {children: React.ReactNode}) {
export function Row({
children,
style,
}: {
children: React.ReactNode
style?: StyleProp<ViewStyle>
}) {
return (
<View style={[a.flex_1, a.flex_row, a.align_center, a.gap_sm]}>
<View style={[a.flex_1, a.flex_row, a.align_start, a.gap_sm, style]}>
{children}
</View>
)
@@ -88,19 +105,20 @@ export function Outer({
const t = useTheme()
const {gtMobile} = useBreakpoints()
const borderColor = {
info: t.atoms.border_contrast_low.borderColor,
tip: t.atoms.border_contrast_low.borderColor,
warning: t.atoms.border_contrast_low.borderColor,
error: t.atoms.border_contrast_low.borderColor,
info: t.atoms.border_contrast_high.borderColor,
tip: t.palette.primary_500,
warning: colors.warning,
error: t.palette.negative_500,
}[type]
return (
<Context.Provider value={{type}}>
<View
style={[
gtMobile ? a.p_md : a.p_sm,
a.p_md,
a.rounded_sm,
a.border,
t.atoms.bg_contrast_25,
t.atoms.bg,
{borderColor},
style,
]}>
@@ -123,7 +141,9 @@ export function Admonition({
<Outer type={type} style={style}>
<Row>
<Icon />
<Text>{children}</Text>
<Content>
<Text>{children}</Text>
</Content>
</Row>
</Outer>
)
@@ -219,10 +219,13 @@ function Inner(props: ReportDialogProps) {
<Admonition.Outer type="error">
<Admonition.Row>
<Admonition.Icon />
<Admonition.Text>
<Trans>Something went wrong, please try again</Trans>
</Admonition.Text>
<Admonition.Content>
<Admonition.Text>
<Trans>Something went wrong, please try again</Trans>
</Admonition.Text>
</Admonition.Content>
<Admonition.Button
color="negative_subtle"
label={_(msg`Retry loading report options`)}
onPress={() => refetchLabelers()}>
<ButtonText>
@@ -621,7 +621,7 @@ function BackdatedPostIndicator({post}: {post: AppBskyFeedDefs.PostView}) {
if (!isBackdated) return null
const orange = t.name === 'light' ? colors.warning.dark : colors.warning.light
const orange = colors.warning
return (
<>
+1 -1
View File
@@ -195,7 +195,7 @@ function AppPasswordCard({
</View>
{appPassword.privileged && (
<View style={[a.flex_row, a.gap_sm, a.align_center, a.mt_md]}>
<WarningIcon style={[{color: colors.warning[t.scheme]}]} />
<WarningIcon style={[{color: colors.warning}]} />
<Text style={t.atoms.text_contrast_high}>
<Trans>Allows access to direct messages</Trans>
</Text>
@@ -134,7 +134,7 @@ export function ActivityNotificationSettingsScreen({}: Props) {
<Admonition.Outer type="tip">
<Admonition.Row>
<Admonition.Icon />
<View style={[a.flex_1, a.gap_sm]}>
<Admonition.Content>
<Admonition.Text>
<Trans>
Enable notifications for an account by visiting their
@@ -166,7 +166,7 @@ export function ActivityNotificationSettingsScreen({}: Props) {
.
</Trans>
</Admonition.Text>
</View>
</Admonition.Content>
</Admonition.Row>
</Admonition.Outer>
) : (
@@ -1,4 +1,3 @@
import {View} from 'react-native'
import {type AppBskyNotificationDeclaration} from '@atproto/api'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
@@ -112,7 +111,7 @@ export function PrivacyAndSecuritySettingsScreen({}: Props) {
<Admonition.Outer type="tip" style={[a.flex_1]}>
<Admonition.Row>
<Admonition.Icon />
<View style={[a.flex_1, a.gap_sm]}>
<Admonition.Content>
<Admonition.Text>
<Trans>
Note: Bluesky is an open and public network. This setting
@@ -131,7 +130,7 @@ export function PrivacyAndSecuritySettingsScreen({}: Props) {
<Trans>Learn more about what is public on Bluesky.</Trans>
</InlineLinkText>
</Admonition.Text>
</View>
</Admonition.Content>
</Admonition.Row>
</Admonition.Outer>
</SettingsList.Item>
+74 -3
View File
@@ -1,11 +1,27 @@
import {View} from 'react-native'
import {Text as RNText, View} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {atoms as a} from '#/alf'
import {Admonition} from '#/components/Admonition'
import {atoms as a, useTheme} from '#/alf'
import {
Admonition,
Button as AdmonitionButton,
Content as AdmonitionContent,
Icon as AdmonitionIcon,
Outer as AdmonitionOuter,
Row as AdmonitionRow,
Text as AdmonitionText,
} from '#/components/Admonition'
import {ButtonIcon, ButtonText} from '#/components/Button'
import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as Retry} from '#/components/icons/ArrowRotateCounterClockwise'
import {BellRinging_Filled_Corner0_Rounded as BellRingingFilledIcon} from '#/components/icons/BellRinging'
import {InlineLinkText} from '#/components/Link'
import {H1} from '#/components/Typography'
export function Admonitions() {
const {_} = useLingui()
const t = useTheme()
return (
<View style={[a.gap_md]}>
<H1>Admonitions</H1>
@@ -30,6 +46,61 @@ export function Admonitions() {
<Admonition type="error">
The quick brown fox jumps over the lazy dog.
</Admonition>
<AdmonitionOuter type="error">
<AdmonitionRow>
<AdmonitionIcon />
<AdmonitionContent>
<AdmonitionText>
<Trans>Something went wrong, please try again</Trans>
</AdmonitionText>
</AdmonitionContent>
<AdmonitionButton
color="negative_subtle"
label={_(msg`Retry loading report options`)}
onPress={() => {}}>
<ButtonText>
<Trans>Retry</Trans>
</ButtonText>
<ButtonIcon icon={Retry} />
</AdmonitionButton>
</AdmonitionRow>
</AdmonitionOuter>
<AdmonitionOuter type="tip">
<AdmonitionRow>
<AdmonitionIcon />
<AdmonitionContent>
<AdmonitionText>
<Trans>
Enable notifications for an account by visiting their profile
and pressing the{' '}
<RNText style={[a.font_bold, t.atoms.text_contrast_high]}>
bell icon
</RNText>{' '}
<BellRingingFilledIcon
size="xs"
style={t.atoms.text_contrast_high}
/>
.
</Trans>
</AdmonitionText>
<AdmonitionText>
<Trans>
If you want to restrict who can receive notifications for your
account's activity, you can change this in{' '}
<InlineLinkText
label={_(msg`Privacy and Security settings`)}
to={{screen: 'ActivityPrivacySettings'}}
style={[a.font_bold]}>
Settings &rarr; Privacy and Security
</InlineLinkText>
.
</Trans>
</AdmonitionText>
</AdmonitionContent>
</AdmonitionRow>
</AdmonitionOuter>
</View>
)
}