import * as React from "react"; import { Text, Pressable, Platform, StyleSheet, TextStyle, PressableProps, ActivityIndicator, } from "react-native"; import Icon from "./Icon"; import Theme from "../styles/DefaultTheme"; import { withTheme } from "../core/theming"; import { COMPONENT_TYPES, createIconProp, createBoolProp, createTextProp, createActionProp, } from "../core/component-types"; const CONSTANTS = { baseHeight: 42, borderRadius: 4, padding: 8, icon: 24, }; type BaseProps = { title: string; disabled: boolean; loading: boolean; style?: TextStyle; onPress: () => void; icon?: string; IconOverride?: typeof Icon | null; } & PressableProps; type Props = { title: string; disabled: boolean; loading: boolean; style?: TextStyle; onPress: () => void; icon?: string; IconOverride?: typeof Icon | null; theme: typeof Theme; } & PressableProps; function Base({ title, onPress, loading, disabled, style, icon, IconOverride = null, ...props }: BaseProps): JSX.Element { const { color, fontFamily, fontWeight, fontSize, lineHeight, letterSpacing, textTransform, textAlign, textDecorationLine, textDecorationColor, textDecorationStyle, ...buttonStyles } = StyleSheet.flatten(style || ({} as TextStyle)); const titleStyles: TextStyle = { color, fontFamily, fontWeight, fontSize, lineHeight, letterSpacing, textTransform, textAlign, textDecorationLine, textDecorationColor, textDecorationStyle, }; // Necessary to inject web-renderable Icons in buider. const SelectedIcon = IconOverride || Icon; return ( { return [ styles.base, { opacity: pressed || disabled ? 0.75 : 1, }, buttonStyles, ]; }} {...props} > {loading ? ( ) : null} {icon && !loading ? ( ) : null} {title} ); } const Solid = ({ style, theme, ...props }: Props): JSX.Element => { return ( ); }; const ButtonSolid: any = withTheme(Solid); export { ButtonSolid }; const Outline = ({ style, theme, ...props }: Props): JSX.Element => { return ( ); }; const ButtonOutline: any = withTheme(Outline); export { ButtonOutline }; export const BaseLink = ({ style, theme, ...props }: Props): JSX.Element => { return ( ); }; const Link: any = withTheme(BaseLink); export { Link }; const styles = StyleSheet.create({ base: { position: "relative", flexDirection: "row", alignItems: "center", minHeight: CONSTANTS.baseHeight, paddingHorizontal: 12, fontFamily: "System", fontWeight: "700", ...Platform.select({ web: { cursor: "pointer", userSelect: "none", }, }), }, outline: { backgroundColor: "transparent", borderWidth: 1, }, bare: { backgroundColor: "transparent", padding: 0, minHeight: undefined, }, loading: { marginRight: 6, }, icon: { ...Platform.select({ web: { marginTop: 1, marginRight: 4, alignSelf: "center", }, default: { marginBottom: 2, marginRight: 4, alignSelf: "center", }, }), }, title: { flex: 1, }, }); const SEED_DATA_PROPS = { icon: createIconProp({ defaultValue: null, required: false, }), title: createTextProp({ label: "Label", description: "Button Label", defaultValue: "Get Started", }), disabled: createBoolProp({ label: "Disabled", description: "Whether the button should be disabled", }), loading: createBoolProp({ label: "Loading", description: "Whether to show a loading indicator", }), onPress: createActionProp(), }; const LAYOUT = { backgroundColor: "transparent", borderRadius: 8, fontFamily: "system-700", }; export const SEED_DATA = [ { name: "Button Outline", tag: "ButtonOutline", category: COMPONENT_TYPES.button, layout: { ...LAYOUT, backgroundColor: "transparent", borderWidth: 1, textAlign: "center", }, props: SEED_DATA_PROPS, }, { name: "Button Solid", tag: "ButtonSolid", category: COMPONENT_TYPES.button, layout: { ...LAYOUT, backgroundColor: "primary", textAlign: "center", }, props: SEED_DATA_PROPS, }, { name: "Link", tag: "Link", category: COMPONENT_TYPES.button, layout: { ...LAYOUT, backgroundColor: "transparent", color: "primary", padding: 0, minHeight: undefined, }, props: SEED_DATA_PROPS, }, ];