index.tsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. import {
  2. type FC
  3. } from "react";
  4. import {
  5. TouchableOpacity,
  6. View
  7. } from "react-native";
  8. import type IHighlightButtonProps from "./type";
  9. import stylesheet, {
  10. getHighlightButtonSize,
  11. getHighlightButtonType,
  12. useStyles
  13. } from "./stylesheet";
  14. import {
  15. NCoreUIKitTheme
  16. } from "../../core/hooks";
  17. import type ITextProps from "../text/type";
  18. import Loading from "../loading";
  19. import Text from "../text";
  20. /**
  21. * A generic button
  22. * @param props {@link IHighlightButtonProps}
  23. * @returns Element
  24. */
  25. const HighlightButton: FC<IHighlightButtonProps> = ({
  26. displayBehaviourWhileLoading = "disabled",
  27. verticalLocationForStretchFix = "start",
  28. spreadBehaviour = "baseline",
  29. isCustomPadding = false,
  30. icon: IconComponentProp,
  31. iconDirection = "left",
  32. isFixVerticalStretch,
  33. isDisabled = false,
  34. customBorderColor,
  35. customIconColor,
  36. customTextColor,
  37. glassEffect = 5,
  38. size = "medium",
  39. type = "glass",
  40. renderLoading,
  41. customColor,
  42. customTheme,
  43. titleStyle,
  44. isLoading,
  45. onPress,
  46. title,
  47. style,
  48. ...props
  49. }) => {
  50. const {
  51. typography,
  52. radiuses,
  53. borders,
  54. colors,
  55. spaces
  56. } = NCoreUIKitTheme.useContext(customTheme);
  57. const currentSize = getHighlightButtonSize({
  58. spaces,
  59. size
  60. });
  61. const currentType = getHighlightButtonType({
  62. type
  63. });
  64. const {
  65. container: containerDynamicStyle,
  66. loading: loadingDynamicStyle,
  67. overlay: overlayDynamicStyle,
  68. title: titleDynamicStyle
  69. } = useStyles({
  70. verticalLocationForStretchFix,
  71. displayBehaviourWhileLoading,
  72. icon: IconComponentProp,
  73. isFixVerticalStretch,
  74. customBorderColor,
  75. isCustomPadding,
  76. spreadBehaviour,
  77. iconDirection,
  78. glassEffect,
  79. currentType,
  80. currentSize,
  81. customColor,
  82. isDisabled,
  83. isLoading,
  84. radiuses,
  85. borders,
  86. colors,
  87. spaces,
  88. title,
  89. type
  90. });
  91. const titleProps: ITextProps = {
  92. color: currentType.titleColor
  93. };
  94. const iconProps: NCoreUIKit.IconCallbackProps = {
  95. size: Number(typography[currentSize.fontSize].fontSize),
  96. color: currentType.iconColor
  97. };
  98. if (isDisabled || isLoading) {
  99. const stateType = type === "danger" ? "error" : type === "glass" ? "neutral" : type;
  100. titleProps.customColor = colors.system.state.content.disabled[stateType];
  101. iconProps.customColor = colors.system.state.content.disabled[stateType];
  102. }
  103. const renderIcon = (direction: "left" | "right") => {
  104. if(iconDirection !== direction) {
  105. return null;
  106. }
  107. if(!isDisabled && !isLoading) {
  108. if(customTextColor) {
  109. const _customTextColor = customTextColor as keyof NCoreUIKit.ProjectColorPalette;
  110. iconProps.customColor = colors.project[_customTextColor] ? colors.project[_customTextColor] : customTextColor;
  111. }
  112. if(customIconColor) {
  113. const _customIconColor = customIconColor as keyof NCoreUIKit.ProjectColorPalette;
  114. iconProps.customColor = colors.project[_customIconColor] ? colors.project[_customIconColor] : customIconColor;
  115. }
  116. }
  117. if (isLoading) {
  118. if(renderLoading) {
  119. return renderLoading();
  120. }
  121. return <Loading
  122. {...iconProps}
  123. style={{
  124. ...loadingDynamicStyle
  125. }}
  126. />;
  127. }
  128. if (!IconComponentProp) {
  129. return null;
  130. }
  131. return <IconComponentProp
  132. {...iconProps}
  133. />;
  134. };
  135. const renderTitle = () => {
  136. if (!title) {
  137. return null;
  138. }
  139. if(!isDisabled && !isLoading) {
  140. if(customTextColor) {
  141. titleProps.customColor = customTextColor;
  142. }
  143. }
  144. return <Text
  145. variant={currentSize.fontSize}
  146. style={[
  147. titleStyle,
  148. stylesheet.title,
  149. titleDynamicStyle
  150. ]}
  151. {...titleProps}
  152. >
  153. {title}
  154. </Text>;
  155. };
  156. const renderOverlay = () => {
  157. return <View
  158. style={[
  159. stylesheet.loading,
  160. stylesheet.overlay,
  161. overlayDynamicStyle
  162. ]}
  163. />;
  164. };
  165. return <TouchableOpacity
  166. {...props}
  167. onPress={isDisabled || isLoading ? () => null : onPress}
  168. disabled={isDisabled || isLoading}
  169. style={[
  170. style,
  171. stylesheet.container,
  172. containerDynamicStyle
  173. ]}
  174. >
  175. {renderIcon("left")}
  176. {renderTitle()}
  177. {renderIcon("right")}
  178. {renderOverlay()}
  179. </TouchableOpacity>;
  180. };
  181. export default HighlightButton;