Wrap Button children in an error boundary (#3340)
* Wrap Button children in an error boundary * Check for Trans componentzio/stable
parent
f04932140a
commit
5b44aa962f
|
@ -1,19 +1,21 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {
|
import {
|
||||||
Pressable,
|
|
||||||
Text,
|
|
||||||
PressableProps,
|
|
||||||
TextProps,
|
|
||||||
ViewStyle,
|
|
||||||
AccessibilityProps,
|
AccessibilityProps,
|
||||||
View,
|
Pressable,
|
||||||
TextStyle,
|
PressableProps,
|
||||||
StyleSheet,
|
|
||||||
StyleProp,
|
StyleProp,
|
||||||
|
StyleSheet,
|
||||||
|
Text,
|
||||||
|
TextProps,
|
||||||
|
TextStyle,
|
||||||
|
View,
|
||||||
|
ViewStyle,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import LinearGradient from 'react-native-linear-gradient'
|
import LinearGradient from 'react-native-linear-gradient'
|
||||||
|
import {Trans} from '@lingui/macro'
|
||||||
|
|
||||||
import {useTheme, atoms as a, tokens, android, flatten} from '#/alf'
|
import {logger} from '#/logger'
|
||||||
|
import {android, atoms as a, flatten, tokens, useTheme} from '#/alf'
|
||||||
import {Props as SVGIconProps} from '#/components/icons/common'
|
import {Props as SVGIconProps} from '#/components/icons/common'
|
||||||
import {normalizeTextStyles} from '#/components/Typography'
|
import {normalizeTextStyles} from '#/components/Typography'
|
||||||
|
|
||||||
|
@ -403,18 +405,51 @@ export function Button({
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
<Context.Provider value={context}>
|
<Context.Provider value={context}>
|
||||||
{typeof children === 'string' ? (
|
<ButtonTextErrorBoundary>
|
||||||
<ButtonText>{children}</ButtonText>
|
{/* @ts-ignore */}
|
||||||
) : typeof children === 'function' ? (
|
{typeof children === 'string' || children?.type === Trans ? (
|
||||||
children(context)
|
/* @ts-ignore */
|
||||||
) : (
|
<ButtonText>{children}</ButtonText>
|
||||||
children
|
) : typeof children === 'function' ? (
|
||||||
)}
|
children(context)
|
||||||
|
) : (
|
||||||
|
children
|
||||||
|
)}
|
||||||
|
</ButtonTextErrorBoundary>
|
||||||
</Context.Provider>
|
</Context.Provider>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ButtonTextErrorBoundary extends React.Component<
|
||||||
|
React.PropsWithChildren<{}>,
|
||||||
|
{hasError: boolean; error: Error | undefined}
|
||||||
|
> {
|
||||||
|
public state = {
|
||||||
|
hasError: false,
|
||||||
|
error: undefined,
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getDerivedStateFromError(error: Error) {
|
||||||
|
return {hasError: true, error}
|
||||||
|
}
|
||||||
|
|
||||||
|
public componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
|
||||||
|
logger.error('ButtonTextErrorBoundary caught an error', {
|
||||||
|
message: error.message,
|
||||||
|
errorInfo,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
if (this.state.hasError) {
|
||||||
|
return <ButtonText>ERROR</ButtonText>
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.props.children
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function useSharedButtonTextStyles() {
|
export function useSharedButtonTextStyles() {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {color, variant, disabled, size} = useButtonContext()
|
const {color, variant, disabled, size} = useButtonContext()
|
||||||
|
|
Loading…
Reference in New Issue