1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
import {createContext, useContext} from 'react'
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 {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',
},
}
type Context = {
type: 'info' | 'tip' | 'warning' | 'error'
}
const Context = createContext<Context>({
type: 'info',
})
Context.displayName = 'AdmonitionContext'
export function Icon() {
const t = useTheme()
const {type} = useContext(Context)
const Icon = {
info: InfoIcon,
tip: TipIcon,
warning: WarningIcon,
error: ErrorIcon,
}[type]
const fill = {
info: t.atoms.text_contrast_medium.color,
tip: t.palette.primary_500,
warning: colors.warning.light,
error: t.palette.negative_500,
}[type]
return <Icon fill={fill} size="md" />
}
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]}>
{children}
</BaseText>
)
}
export function Button({
children,
...props
}: Omit<ButtonProps, 'size' | 'variant' | 'color'>) {
return (
<BaseButton size="tiny" variant="outline" color="secondary" {...props}>
{children}
</BaseButton>
)
}
export function Row({children}: {children: React.ReactNode}) {
return (
<View style={[a.flex_1, a.flex_row, a.align_center, a.gap_sm]}>
{children}
</View>
)
}
export function Outer({
children,
type = 'info',
style,
}: {
children: React.ReactNode
type?: Context['type']
style?: StyleProp<ViewStyle>
}) {
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,
}[type]
return (
<Context.Provider value={{type}}>
<View
style={[
gtMobile ? a.p_md : a.p_sm,
a.rounded_sm,
a.border,
t.atoms.bg_contrast_25,
{borderColor},
style,
]}>
{children}
</View>
</Context.Provider>
)
}
export function Admonition({
children,
type,
style,
}: {
children: TextProps['children']
type?: Context['type']
style?: StyleProp<ViewStyle>
}) {
return (
<Outer type={type} style={style}>
<Row>
<Icon />
<Text>{children}</Text>
</Row>
</Outer>
)
}
|