import * as React from "react";
import {
ActivityIndicator,
View,
Text,
StyleSheet,
TouchableHighlightProps,
StyleProp,
ViewStyle,
TextStyle,
} from "react-native";
import color from "color";
import Config from "./Config";
import Icon from "./Icon";
import Touchable from "./Touchable";
import Elevation from "./Elevation";
import { withTheme } from "../core/theming";
import {
GROUPS,
FORM_TYPES,
PROP_TYPES,
COMPONENT_TYPES,
} from "../core/component-types";
import theme from "../styles/DefaultTheme";
/**
* A button is component that the user can press to trigger an action.
*
*
*
*
* Text button
*
*
*
* Outlined button
*
*
*
* Contained button
*
*
*
* ## Usage
* ```js
* import * as React from 'react';
* import { Button } from '@draftbit/ui';
*
* const MyComponent = () => (
* console.log('Pressed')}>
* Press me
*
* );
*
* export default MyComponent;
* ```
*/
type Props = {
disabled?: boolean;
type?: "solid" | "outline" | "text";
loading?: boolean;
icon?: string;
labelColor?: string;
color?: string;
children?: React.ReactNode;
onPress: () => void;
elevation?: number;
style?: StyleProp;
IconOverride?: typeof Icon;
theme: typeof theme;
} & TouchableHighlightProps;
const Button: React.FC = ({
disabled = false,
type = "solid",
loading = false,
icon,
labelColor,
color: colorOverride,
children,
onPress,
elevation = 0,
style,
theme: { colors, disabledOpacity, roundness, typography },
IconOverride = null,
...rest
}) => {
let backgroundColor, borderColor, textColor, borderWidth;
const buttonColor = colorOverride || colors.primary;
// Necessary to inject web-renderable Icons in buider.
const SelectedIcon = IconOverride || Icon;
if (type === "solid") {
backgroundColor = buttonColor;
if (disabled) {
textColor = color(colors.surface).alpha(disabledOpacity).rgb().string();
} else {
textColor = labelColor || colors.surface;
}
} else {
backgroundColor = "transparent";
if (disabled) {
textColor = color(buttonColor).alpha(disabledOpacity).rgb().string();
} else {
textColor = labelColor || buttonColor;
}
}
if (type === "outline") {
if (disabled) {
borderColor = color(buttonColor).alpha(disabledOpacity).rgb().string();
} else {
borderColor = buttonColor;
}
borderWidth = StyleSheet.hairlineWidth;
} else {
borderColor = "transparent";
borderWidth = 0;
}
const buttonStyle = {
backgroundColor,
borderColor,
borderWidth,
borderRadius: roundness,
};
const textStyle: StyleProp = {
textAlign: "center",
color: textColor,
marginVertical: 16,
marginHorizontal: 16,
};
const iconStyle = [
styles.icon,
{
marginLeft: 16,
marginRight: -8,
width: Config.buttonIconSize,
},
];
const {
margin,
marginEnd,
marginTop,
marginLeft,
marginRight,
marginBottom,
marginHorizontal,
marginVertical,
...innerStyles
} = StyleSheet.flatten(style || {});
const margins = {
margin,
marginEnd,
marginTop,
marginLeft,
marginRight,
marginBottom,
marginHorizontal,
marginVertical,
};
return (
{icon && loading !== true ? (
) : null}
{loading ? (
) : null}
{children}
);
};
const styles = StyleSheet.create({
button: {
minWidth: 64,
borderStyle: "solid",
},
content: {
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
},
icon: {
width: Config.buttonIconSize,
},
});
export default withTheme(Button);
const SEED_DATA_PROPS = {
icon: {
group: GROUPS.basic,
label: "Icon Name",
description: "Name of the icon",
editable: true,
required: true,
formType: FORM_TYPES.icon,
propType: PROP_TYPES.STRING,
defaultValue: null,
},
children: {
group: GROUPS.data,
label: "Label",
description: "Button label",
required: true,
editable: true,
formType: FORM_TYPES.string,
propType: PROP_TYPES.STRING,
defaultValue: "Get Started",
},
color: {
group: GROUPS.basic,
label: "Color Override",
description: "Override the background color of the button",
editable: true,
required: false,
formType: FORM_TYPES.color,
propType: PROP_TYPES.THEME,
defaultValue: null,
},
labelColor: {
group: GROUPS.basic,
label: "Label Color Override",
description: "Override the label color of the button",
editable: true,
required: false,
formType: FORM_TYPES.color,
propType: PROP_TYPES.THEME,
defaultValue: null,
},
disabled: {
group: GROUPS.basic,
label: "Disabled",
description: "Whether the button should be disabled",
editable: true,
required: false,
formType: FORM_TYPES.boolean,
propType: PROP_TYPES.BOOLEAN,
defaultValue: null,
},
loading: {
group: GROUPS.data,
label: "Loading",
description: "Whether to show a loading indicator",
editable: true,
required: false,
formType: FORM_TYPES.boolean,
propType: PROP_TYPES.BOOLEAN,
defaultValue: null,
},
onPress: {
group: GROUPS.basic,
label: "Action",
description: "Action to execute when button pressed",
editable: true,
required: false,
formType: FORM_TYPES.action,
defaultValue: null,
},
};
export const SEED_DATA = [
{
name: "Button Outline",
tag: "Button",
category: COMPONENT_TYPES.deprecated,
props: {
...SEED_DATA_PROPS,
type: {
group: GROUPS.uncategorized,
label: "Type",
description: "Button type",
editable: false,
required: true,
formType: FORM_TYPES.string,
propType: PROP_TYPES.STRING,
defaultValue: "outline",
},
},
layout: {},
},
{
name: "Button Solid",
tag: "Button",
category: COMPONENT_TYPES.deprecated,
props: {
...SEED_DATA_PROPS,
type: {
group: GROUPS.uncategorized,
label: "Type",
description: "Button type",
editable: false,
required: true,
formType: FORM_TYPES.string,
propType: PROP_TYPES.STRING,
defaultValue: "solid",
},
},
layout: {},
},
];