Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add Admonition component (#5680)

* Add Admonition component

* Tweak mobile padding

* Format

authored by

Eric Bailey and committed by
GitHub
830b4bee 7f3b5366

+167 -2
+10 -1
.eslintrc.js
··· 23 23 'bsky-internal/avoid-unwrapped-text': [ 24 24 'error', 25 25 { 26 - impliedTextComponents: ['H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'P'], 26 + impliedTextComponents: [ 27 + 'H1', 28 + 'H2', 29 + 'H3', 30 + 'H4', 31 + 'H5', 32 + 'H6', 33 + 'P', 34 + 'Admonition', 35 + ], 27 36 impliedTextProps: [], 28 37 suggestedTextWrappers: { 29 38 Button: 'ButtonText',
+118
src/components/Admonition.tsx
··· 1 + import React from 'react' 2 + import {View} from 'react-native' 3 + 4 + import {atoms as a, useBreakpoints, useTheme} from '#/alf' 5 + import {CircleInfo_Stroke2_Corner0_Rounded as ErrorIcon} from '#/components/icons/CircleInfo' 6 + import {Eye_Stroke2_Corner0_Rounded as InfoIcon} from '#/components/icons/Eye' 7 + import {Leaf_Stroke2_Corner0_Rounded as TipIcon} from '#/components/icons/Leaf' 8 + import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons/Warning' 9 + import {Text as BaseText, TextProps} from '#/components/Typography' 10 + 11 + const colors = { 12 + warning: { 13 + light: '#DFBC00', 14 + dark: '#BFAF1F', 15 + }, 16 + } 17 + 18 + type Context = { 19 + type: 'info' | 'tip' | 'warning' | 'error' 20 + } 21 + 22 + const Context = React.createContext<Context>({ 23 + type: 'info', 24 + }) 25 + 26 + export 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 + 44 + export 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 + 66 + export function Row({children}: {children: React.ReactNode}) { 67 + return <View style={[a.flex_row, a.gap_sm]}>{children}</View> 68 + } 69 + 70 + export function Outer({ 71 + children, 72 + type = 'info', 73 + }: { 74 + children: React.ReactNode 75 + type?: Context['type'] 76 + }) { 77 + const t = useTheme() 78 + const {gtMobile} = useBreakpoints() 79 + const borderColor = { 80 + info: t.atoms.border_contrast_low.borderColor, 81 + tip: t.atoms.border_contrast_low.borderColor, 82 + warning: t.atoms.border_contrast_low.borderColor, 83 + error: t.atoms.border_contrast_low.borderColor, 84 + }[type] 85 + return ( 86 + <Context.Provider value={{type}}> 87 + <View 88 + style={[ 89 + gtMobile ? a.p_md : a.p_sm, 90 + a.rounded_sm, 91 + a.border, 92 + t.atoms.bg_contrast_25, 93 + { 94 + borderColor, 95 + }, 96 + ]}> 97 + {children} 98 + </View> 99 + </Context.Provider> 100 + ) 101 + } 102 + 103 + export function Admonition({ 104 + children, 105 + type, 106 + }: { 107 + children: TextProps['children'] 108 + type?: Context['type'] 109 + }) { 110 + return ( 111 + <Outer type={type}> 112 + <Row> 113 + <Icon /> 114 + <Text>{children}</Text> 115 + </Row> 116 + </Outer> 117 + ) 118 + }
+36
src/view/screens/Storybook/Admonitions.tsx
··· 1 + import React from 'react' 2 + import {View} from 'react-native' 3 + 4 + import {atoms as a} from '#/alf' 5 + import {Admonition} from '#/components/Admonition' 6 + import {InlineLinkText} from '#/components/Link' 7 + import {H1} from '#/components/Typography' 8 + 9 + export function Admonitions() { 10 + return ( 11 + <View style={[a.gap_md]}> 12 + <H1>Admonitions</H1> 13 + 14 + <Admonition>The quick brown fox jumps over the lazy dog.</Admonition> 15 + <Admonition type="info"> 16 + How happy the blameless vestal's lot, the world forgetting by the world 17 + forgot.{' '} 18 + <InlineLinkText 19 + label="test" 20 + to="https://letterboxd.com/film/eternal-sunshine-of-the-spotless-mind/"> 21 + Eternal sunshine of the spotless mind 22 + </InlineLinkText> 23 + ! Each pray'r accepted, and each wish resign'd. 24 + </Admonition> 25 + <Admonition type="tip"> 26 + The quick brown fox jumps over the lazy dog. 27 + </Admonition> 28 + <Admonition type="warning"> 29 + The quick brown fox jumps over the lazy dog. 30 + </Admonition> 31 + <Admonition type="error"> 32 + The quick brown fox jumps over the lazy dog. 33 + </Admonition> 34 + </View> 35 + ) 36 + }
+3 -1
src/view/screens/Storybook/index.tsx
··· 7 7 import {ListContained} from '#/view/screens/Storybook/ListContained' 8 8 import {atoms as a, ThemeProvider, useTheme} from '#/alf' 9 9 import {Button, ButtonText} from '#/components/Button' 10 + import {Admonitions} from './Admonitions' 10 11 import {Breakpoints} from './Breakpoints' 11 12 import {Buttons} from './Buttons' 12 13 import {Dialogs} from './Dialogs' ··· 80 81 </Button> 81 82 </View> 82 83 83 - <Forms /> 84 + <Admonitions /> 84 85 85 86 <ThemeProvider theme="light"> 86 87 <Theming /> ··· 92 93 <Theming /> 93 94 </ThemeProvider> 94 95 96 + <Forms /> 95 97 <Buttons /> 96 98 <Typography /> 97 99 <Spacing />