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,
},
];