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:
@@ -3,17 +3,13 @@ import {type StyleProp, View, type ViewStyle} from 'react-native'
|
|||||||
|
|
||||||
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
||||||
import {Button as BaseButton, type ButtonProps} from '#/components/Button'
|
import {Button as BaseButton, type ButtonProps} from '#/components/Button'
|
||||||
import {CircleInfo_Stroke2_Corner0_Rounded as ErrorIcon} from '#/components/icons/CircleInfo'
|
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfoIcon} from '#/components/icons/CircleInfo'
|
||||||
import {Eye_Stroke2_Corner0_Rounded as InfoIcon} from '#/components/icons/Eye'
|
import {CircleX_Stroke2_Corner0_Rounded as CircleXIcon} from '#/components/icons/CircleX'
|
||||||
import {Leaf_Stroke2_Corner0_Rounded as TipIcon} from '#/components/icons/Leaf'
|
|
||||||
import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning'
|
import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning'
|
||||||
import {Text as BaseText, type TextProps} from '#/components/Typography'
|
import {Text as BaseText, type TextProps} from '#/components/Typography'
|
||||||
|
|
||||||
export const colors = {
|
export const colors = {
|
||||||
warning: {
|
warning: '#FFC404',
|
||||||
light: '#DFBC00',
|
|
||||||
dark: '#BFAF1F',
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Context = {
|
type Context = {
|
||||||
@@ -29,29 +25,44 @@ export function Icon() {
|
|||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {type} = useContext(Context)
|
const {type} = useContext(Context)
|
||||||
const Icon = {
|
const Icon = {
|
||||||
info: InfoIcon,
|
info: CircleInfoIcon,
|
||||||
tip: TipIcon,
|
tip: CircleInfoIcon,
|
||||||
warning: WarningIcon,
|
warning: WarningIcon,
|
||||||
error: ErrorIcon,
|
error: CircleXIcon,
|
||||||
}[type]
|
}[type]
|
||||||
const fill = {
|
const fill = {
|
||||||
info: t.atoms.text_contrast_medium.color,
|
info: t.atoms.text_contrast_medium.color,
|
||||||
tip: t.palette.primary_500,
|
tip: t.palette.primary_500,
|
||||||
warning: colors.warning.light,
|
warning: colors.warning,
|
||||||
error: t.palette.negative_500,
|
error: t.palette.negative_500,
|
||||||
}[type]
|
}[type]
|
||||||
return <Icon fill={fill} size="md" />
|
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({
|
export function Text({
|
||||||
children,
|
children,
|
||||||
style,
|
style,
|
||||||
...rest
|
...rest
|
||||||
}: Pick<TextProps, 'children' | 'style'>) {
|
}: Pick<TextProps, 'children' | 'style'>) {
|
||||||
return (
|
return (
|
||||||
<BaseText
|
<BaseText {...rest} style={[a.text_sm, a.leading_snug, a.pr_md, style]}>
|
||||||
{...rest}
|
|
||||||
style={[a.flex_1, a.text_sm, a.leading_snug, a.pr_md, style]}>
|
|
||||||
{children}
|
{children}
|
||||||
</BaseText>
|
</BaseText>
|
||||||
)
|
)
|
||||||
@@ -60,17 +71,23 @@ export function Text({
|
|||||||
export function Button({
|
export function Button({
|
||||||
children,
|
children,
|
||||||
...props
|
...props
|
||||||
}: Omit<ButtonProps, 'size' | 'variant' | 'color'>) {
|
}: Omit<ButtonProps, 'size' | 'variant'>) {
|
||||||
return (
|
return (
|
||||||
<BaseButton size="tiny" variant="outline" color="secondary" {...props}>
|
<BaseButton size="tiny" {...props}>
|
||||||
{children}
|
{children}
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Row({children}: {children: React.ReactNode}) {
|
export function Row({
|
||||||
|
children,
|
||||||
|
style,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode
|
||||||
|
style?: StyleProp<ViewStyle>
|
||||||
|
}) {
|
||||||
return (
|
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}
|
{children}
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
@@ -88,19 +105,20 @@ export function Outer({
|
|||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {gtMobile} = useBreakpoints()
|
const {gtMobile} = useBreakpoints()
|
||||||
const borderColor = {
|
const borderColor = {
|
||||||
info: t.atoms.border_contrast_low.borderColor,
|
info: t.atoms.border_contrast_high.borderColor,
|
||||||
tip: t.atoms.border_contrast_low.borderColor,
|
tip: t.palette.primary_500,
|
||||||
warning: t.atoms.border_contrast_low.borderColor,
|
warning: colors.warning,
|
||||||
error: t.atoms.border_contrast_low.borderColor,
|
error: t.palette.negative_500,
|
||||||
}[type]
|
}[type]
|
||||||
return (
|
return (
|
||||||
<Context.Provider value={{type}}>
|
<Context.Provider value={{type}}>
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
gtMobile ? a.p_md : a.p_sm,
|
gtMobile ? a.p_md : a.p_sm,
|
||||||
|
a.p_md,
|
||||||
a.rounded_sm,
|
a.rounded_sm,
|
||||||
a.border,
|
a.border,
|
||||||
t.atoms.bg_contrast_25,
|
t.atoms.bg,
|
||||||
{borderColor},
|
{borderColor},
|
||||||
style,
|
style,
|
||||||
]}>
|
]}>
|
||||||
@@ -123,7 +141,9 @@ export function Admonition({
|
|||||||
<Outer type={type} style={style}>
|
<Outer type={type} style={style}>
|
||||||
<Row>
|
<Row>
|
||||||
<Icon />
|
<Icon />
|
||||||
<Text>{children}</Text>
|
<Content>
|
||||||
|
<Text>{children}</Text>
|
||||||
|
</Content>
|
||||||
</Row>
|
</Row>
|
||||||
</Outer>
|
</Outer>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -219,10 +219,13 @@ function Inner(props: ReportDialogProps) {
|
|||||||
<Admonition.Outer type="error">
|
<Admonition.Outer type="error">
|
||||||
<Admonition.Row>
|
<Admonition.Row>
|
||||||
<Admonition.Icon />
|
<Admonition.Icon />
|
||||||
<Admonition.Text>
|
<Admonition.Content>
|
||||||
<Trans>Something went wrong, please try again</Trans>
|
<Admonition.Text>
|
||||||
</Admonition.Text>
|
<Trans>Something went wrong, please try again</Trans>
|
||||||
|
</Admonition.Text>
|
||||||
|
</Admonition.Content>
|
||||||
<Admonition.Button
|
<Admonition.Button
|
||||||
|
color="negative_subtle"
|
||||||
label={_(msg`Retry loading report options`)}
|
label={_(msg`Retry loading report options`)}
|
||||||
onPress={() => refetchLabelers()}>
|
onPress={() => refetchLabelers()}>
|
||||||
<ButtonText>
|
<ButtonText>
|
||||||
|
|||||||
@@ -621,7 +621,7 @@ function BackdatedPostIndicator({post}: {post: AppBskyFeedDefs.PostView}) {
|
|||||||
|
|
||||||
if (!isBackdated) return null
|
if (!isBackdated) return null
|
||||||
|
|
||||||
const orange = t.name === 'light' ? colors.warning.dark : colors.warning.light
|
const orange = colors.warning
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ function AppPasswordCard({
|
|||||||
</View>
|
</View>
|
||||||
{appPassword.privileged && (
|
{appPassword.privileged && (
|
||||||
<View style={[a.flex_row, a.gap_sm, a.align_center, a.mt_md]}>
|
<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}>
|
<Text style={t.atoms.text_contrast_high}>
|
||||||
<Trans>Allows access to direct messages</Trans>
|
<Trans>Allows access to direct messages</Trans>
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ export function ActivityNotificationSettingsScreen({}: Props) {
|
|||||||
<Admonition.Outer type="tip">
|
<Admonition.Outer type="tip">
|
||||||
<Admonition.Row>
|
<Admonition.Row>
|
||||||
<Admonition.Icon />
|
<Admonition.Icon />
|
||||||
<View style={[a.flex_1, a.gap_sm]}>
|
<Admonition.Content>
|
||||||
<Admonition.Text>
|
<Admonition.Text>
|
||||||
<Trans>
|
<Trans>
|
||||||
Enable notifications for an account by visiting their
|
Enable notifications for an account by visiting their
|
||||||
@@ -166,7 +166,7 @@ export function ActivityNotificationSettingsScreen({}: Props) {
|
|||||||
.
|
.
|
||||||
</Trans>
|
</Trans>
|
||||||
</Admonition.Text>
|
</Admonition.Text>
|
||||||
</View>
|
</Admonition.Content>
|
||||||
</Admonition.Row>
|
</Admonition.Row>
|
||||||
</Admonition.Outer>
|
</Admonition.Outer>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import {View} from 'react-native'
|
|
||||||
import {type AppBskyNotificationDeclaration} from '@atproto/api'
|
import {type AppBskyNotificationDeclaration} from '@atproto/api'
|
||||||
import {msg, Trans} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
@@ -112,7 +111,7 @@ export function PrivacyAndSecuritySettingsScreen({}: Props) {
|
|||||||
<Admonition.Outer type="tip" style={[a.flex_1]}>
|
<Admonition.Outer type="tip" style={[a.flex_1]}>
|
||||||
<Admonition.Row>
|
<Admonition.Row>
|
||||||
<Admonition.Icon />
|
<Admonition.Icon />
|
||||||
<View style={[a.flex_1, a.gap_sm]}>
|
<Admonition.Content>
|
||||||
<Admonition.Text>
|
<Admonition.Text>
|
||||||
<Trans>
|
<Trans>
|
||||||
Note: Bluesky is an open and public network. This setting
|
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>
|
<Trans>Learn more about what is public on Bluesky.</Trans>
|
||||||
</InlineLinkText>
|
</InlineLinkText>
|
||||||
</Admonition.Text>
|
</Admonition.Text>
|
||||||
</View>
|
</Admonition.Content>
|
||||||
</Admonition.Row>
|
</Admonition.Row>
|
||||||
</Admonition.Outer>
|
</Admonition.Outer>
|
||||||
</SettingsList.Item>
|
</SettingsList.Item>
|
||||||
|
|||||||
@@ -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 {atoms as a, useTheme} from '#/alf'
|
||||||
import {Admonition} from '#/components/Admonition'
|
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 {InlineLinkText} from '#/components/Link'
|
||||||
import {H1} from '#/components/Typography'
|
import {H1} from '#/components/Typography'
|
||||||
|
|
||||||
export function Admonitions() {
|
export function Admonitions() {
|
||||||
|
const {_} = useLingui()
|
||||||
|
const t = useTheme()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[a.gap_md]}>
|
<View style={[a.gap_md]}>
|
||||||
<H1>Admonitions</H1>
|
<H1>Admonitions</H1>
|
||||||
@@ -30,6 +46,61 @@ export function Admonitions() {
|
|||||||
<Admonition type="error">
|
<Admonition type="error">
|
||||||
The quick brown fox jumps over the lazy dog.
|
The quick brown fox jumps over the lazy dog.
|
||||||
</Admonition>
|
</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 → Privacy and Security
|
||||||
|
</InlineLinkText>
|
||||||
|
.
|
||||||
|
</Trans>
|
||||||
|
</AdmonitionText>
|
||||||
|
</AdmonitionContent>
|
||||||
|
</AdmonitionRow>
|
||||||
|
</AdmonitionOuter>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user