my fork of the bluesky client
at main 121 lines 2.7 kB view raw
1import React from 'react' 2import {StyleProp, View, ViewStyle} from 'react-native' 3 4import {atoms as a, useBreakpoints, useTheme} from '#/alf' 5import {CircleInfo_Stroke2_Corner0_Rounded as ErrorIcon} from '#/components/icons/CircleInfo' 6import {Eye_Stroke2_Corner0_Rounded as InfoIcon} from '#/components/icons/Eye' 7import {Leaf_Stroke2_Corner0_Rounded as TipIcon} from '#/components/icons/Leaf' 8import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning' 9import {Text as BaseText, TextProps} from '#/components/Typography' 10 11export const colors = { 12 warning: { 13 light: '#DFBC00', 14 dark: '#BFAF1F', 15 }, 16} 17 18type Context = { 19 type: 'info' | 'tip' | 'warning' | 'error' 20} 21 22const Context = React.createContext<Context>({ 23 type: 'info', 24}) 25 26export function Icon() { 27 const t = useTheme() 28 const {type} = React.useContext(Context) 29 const Icon = { 30 info: InfoIcon, 31 tip: TipIcon, 32 warning: WarningIcon, 33 error: ErrorIcon, 34 }[type] 35 const fill = { 36 info: t.atoms.text_contrast_medium.color, 37 tip: t.palette.primary_500, 38 warning: colors.warning.light, 39 error: t.palette.negative_500, 40 }[type] 41 return <Icon fill={fill} size="md" /> 42} 43 44export function Text({ 45 children, 46 style, 47 ...rest 48}: Pick<TextProps, 'children' | 'style'>) { 49 return ( 50 <BaseText 51 {...rest} 52 style={[ 53 a.flex_1, 54 a.text_sm, 55 a.leading_snug, 56 { 57 paddingTop: 1, 58 }, 59 style, 60 ]}> 61 {children} 62 </BaseText> 63 ) 64} 65 66export function Row({children}: {children: React.ReactNode}) { 67 return <View style={[a.flex_row, a.gap_sm]}>{children}</View> 68} 69 70export function Outer({ 71 children, 72 type = 'info', 73 style, 74}: { 75 children: React.ReactNode 76 type?: Context['type'] 77 style?: StyleProp<ViewStyle> 78}) { 79 const t = useTheme() 80 const {gtMobile} = useBreakpoints() 81 const borderColor = { 82 info: t.atoms.border_contrast_low.borderColor, 83 tip: t.atoms.border_contrast_low.borderColor, 84 warning: t.atoms.border_contrast_low.borderColor, 85 error: t.atoms.border_contrast_low.borderColor, 86 }[type] 87 return ( 88 <Context.Provider value={{type}}> 89 <View 90 style={[ 91 gtMobile ? a.p_md : a.p_sm, 92 a.rounded_sm, 93 a.border, 94 t.atoms.bg_contrast_25, 95 {borderColor}, 96 style, 97 ]}> 98 {children} 99 </View> 100 </Context.Provider> 101 ) 102} 103 104export function Admonition({ 105 children, 106 type, 107 style, 108}: { 109 children: TextProps['children'] 110 type?: Context['type'] 111 style?: StyleProp<ViewStyle> 112}) { 113 return ( 114 <Outer type={type} style={style}> 115 <Row> 116 <Icon /> 117 <Text>{children}</Text> 118 </Row> 119 </Outer> 120 ) 121}