| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- import {
- type FC
- } from "react";
- import {
- TouchableOpacity,
- View
- } from "react-native";
- import type IButtonProps from "./type";
- import stylesheet, {
- getButtonVariant,
- getButtonSize,
- getButtonType,
- useStyles
- } from "./stylesheet";
- import {
- NCoreUIKitTheme
- } from "../../core/hooks";
- import type {
- INCoreUIKitIconProps
- } from "../../types";
- import type ITextProps from "../text/type";
- import Loading from "../loading";
- import Text from "../text";
- /**
- * A generic button
- * @param props {@link IButtonProps}
- * @returns Element
- */
- const Button: FC<IButtonProps> = ({
- displayBehaviourWhileLoading = "disabled",
- spreadBehaviour = "baseline",
- icon: IconComponentProp,
- iconDirection = "left",
- variant = "filled",
- isDisabled = false,
- type = "primary",
- size = "medium",
- customTheme,
- titleStyle,
- isLoading,
- onPress,
- title,
- style,
- ...props
- }) => {
- const {
- typography,
- radiuses,
- borders,
- colors,
- spaces
- } = NCoreUIKitTheme.useContext(customTheme);
- const currentSize = getButtonSize({
- spaces,
- size
- });
- const currentVariant = getButtonVariant({
- variant,
- });
- const currentType = getButtonType({
- type,
- });
- const {
- container: containerDynamicStyle,
- loading: loadingDynamicStyle,
- overlay: overlayDynamicStyle,
- title: titleDynamicStyle
- } = useStyles({
- displayBehaviourWhileLoading,
- icon: IconComponentProp,
- spreadBehaviour,
- currentVariant,
- iconDirection,
- currentType,
- currentSize,
- isDisabled,
- isLoading,
- radiuses,
- variant,
- borders,
- colors,
- spaces,
- title,
- type
- });
- const titleProps: ITextProps = {
- color: currentType.titleColor,
- };
- const iconProps: INCoreUIKitIconProps = {
- size: Number(typography[currentSize.fontSize].fontSize),
- color: currentType.iconColor
- };
- if (currentVariant.titleColor !== "type") {
- titleProps.color = currentType.titleColor;
- }
- if (currentVariant.iconColor !== "type") {
- iconProps.color = currentType.iconColor;
- }
- if (type === "primary" && variant === "filled") {
- iconProps.color = "onPrimary";
- titleProps.color = "onPrimary";
- }
- if (type === "primary" && variant !== "filled") {
- iconProps.color = "emphasized";
- titleProps.color = "emphasized";
- }
- if (isDisabled || isLoading) {
- const stateType = type === "danger" ? "error" : type;
- titleProps.customColor = colors.system.state.content.disabled[stateType];
- iconProps.customColor = colors.system.state.content.disabled[stateType];
- }
- const renderIcon = () => {
- if (isLoading) {
- return <Loading
- {...iconProps}
- style={[
- loadingDynamicStyle
- ]}
- />;
- }
- if (!IconComponentProp) {
- return null;
- }
- return <IconComponentProp {...iconProps} />;
- };
- const renderTitle = () => {
- if (!title) {
- return null;
- }
- return <Text
- variant={currentSize.fontSize}
- style={[
- titleStyle,
- stylesheet.title,
- titleDynamicStyle
- ]}
- {...titleProps}
- >
- {title}
- </Text>;
- };
- const renderOverlay = () => {
- return <View
- style={[
- stylesheet.loading,
- stylesheet.overlay,
- overlayDynamicStyle
- ]}
- />;
- };
- return (
- <TouchableOpacity
- {...props}
- onPress={isDisabled || isLoading ? () => null : onPress}
- disabled={isDisabled || isLoading}
- style={[
- style,
- stylesheet.container,
- containerDynamicStyle
- ]}
- >
- {renderIcon()}
- {renderTitle()}
- {renderOverlay()}
- </TouchableOpacity>
- );
- };
- export default Button;
|