|
@@ -0,0 +1,277 @@
|
|
|
|
|
+import {
|
|
|
|
|
+ type TextStyle,
|
|
|
|
|
+ type ViewStyle,
|
|
|
|
|
+ StyleSheet
|
|
|
|
|
+} from "react-native";
|
|
|
|
|
+import {
|
|
|
|
|
+ type ButtonVariantConstantType,
|
|
|
|
|
+ type ButtonTypeConstantType,
|
|
|
|
|
+ type ButtonSizeConstantType,
|
|
|
|
|
+ type ButtonDynamicStyleType,
|
|
|
|
|
+ type ButtonMeasuresKeys,
|
|
|
|
|
+ type ButtonMeasures,
|
|
|
|
|
+ type ButtonVariants,
|
|
|
|
|
+ type ButtonVariant,
|
|
|
|
|
+ type ButtonTypes,
|
|
|
|
|
+ type ButtonSize,
|
|
|
|
|
+ type ButtonType
|
|
|
|
|
+} from "./type";
|
|
|
|
|
+import type {
|
|
|
|
|
+ Mutable
|
|
|
|
|
+} from "../../types";
|
|
|
|
|
+
|
|
|
|
|
+export const BUTTON_SIZES: Record<ButtonSize, ButtonMeasuresKeys> = {
|
|
|
|
|
+ small: {
|
|
|
|
|
+ paddingHorizontal: "spacingMd",
|
|
|
|
|
+ paddingVertical: "spacingSm",
|
|
|
|
|
+ fontSize: "labelSmallSize"
|
|
|
|
|
+ },
|
|
|
|
|
+ medium: {
|
|
|
|
|
+ paddingHorizontal: "spacingLg",
|
|
|
|
|
+ paddingVertical: "spacingMd",
|
|
|
|
|
+ fontSize: "labelMediumSize"
|
|
|
|
|
+ },
|
|
|
|
|
+ large: {
|
|
|
|
|
+ paddingHorizontal: "spacingXl",
|
|
|
|
|
+ paddingVertical: "spacingLg",
|
|
|
|
|
+ fontSize: "labelLargeSize"
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+export const BUTTON_VARIANT_STYLES: Record<
|
|
|
|
|
+ ButtonVariant,
|
|
|
|
|
+ {
|
|
|
|
|
+ titleColor: "type" | keyof NCoreUIKit.TextContentColors;
|
|
|
|
|
+ iconColor: "type" | keyof NCoreUIKit.ColorsMerged;
|
|
|
|
|
+ borderColor: "transparent" | "type" | "container";
|
|
|
|
|
+ iconColorScheme?: keyof NCoreUIKit.ThemeTokens;
|
|
|
|
|
+ containerColor: "transparent" | "type";
|
|
|
|
|
+ }
|
|
|
|
|
+> = {
|
|
|
|
|
+ filled: {
|
|
|
|
|
+ borderColor: "container",
|
|
|
|
|
+ containerColor: "type",
|
|
|
|
|
+ titleColor: "type",
|
|
|
|
|
+ iconColor: "type"
|
|
|
|
|
+ },
|
|
|
|
|
+ outline: {
|
|
|
|
|
+ containerColor: "transparent",
|
|
|
|
|
+ borderColor: "type",
|
|
|
|
|
+ titleColor: "type",
|
|
|
|
|
+ iconColor: "type"
|
|
|
|
|
+ },
|
|
|
|
|
+ ghost: {
|
|
|
|
|
+ containerColor: "transparent",
|
|
|
|
|
+ borderColor: "transparent",
|
|
|
|
|
+ titleColor: "type",
|
|
|
|
|
+ iconColor: "type"
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+export const BUTTON_TYPE_STYLES: Record<
|
|
|
|
|
+ ButtonType,
|
|
|
|
|
+ {
|
|
|
|
|
+ containerColor: keyof NCoreUIKit.ContainerContentColors;
|
|
|
|
|
+ borderColor: keyof NCoreUIKit.BorderContentColors;
|
|
|
|
|
+ titleColor: keyof NCoreUIKit.TextContentColors;
|
|
|
|
|
+ iconColor: keyof NCoreUIKit.IconContentColors;
|
|
|
|
|
+ }
|
|
|
|
|
+> = {
|
|
|
|
|
+ primary: {
|
|
|
|
|
+ containerColor: "primary",
|
|
|
|
|
+ borderColor: "emphasized",
|
|
|
|
|
+ titleColor: "onPrimary",
|
|
|
|
|
+ iconColor: "onPrimary"
|
|
|
|
|
+ },
|
|
|
|
|
+ danger: {
|
|
|
|
|
+ containerColor: "danger",
|
|
|
|
|
+ borderColor: "danger",
|
|
|
|
|
+ titleColor: "danger",
|
|
|
|
|
+ iconColor: "danger"
|
|
|
|
|
+ },
|
|
|
|
|
+ success: {
|
|
|
|
|
+ containerColor: "success",
|
|
|
|
|
+ borderColor: "success",
|
|
|
|
|
+ titleColor: "success",
|
|
|
|
|
+ iconColor: "success"
|
|
|
|
|
+ },
|
|
|
|
|
+ warning: {
|
|
|
|
|
+ containerColor: "warning",
|
|
|
|
|
+ borderColor: "warning",
|
|
|
|
|
+ titleColor: "warning",
|
|
|
|
|
+ iconColor: "warning"
|
|
|
|
|
+ },
|
|
|
|
|
+ info: {
|
|
|
|
|
+ containerColor: "info",
|
|
|
|
|
+ borderColor: "info",
|
|
|
|
|
+ titleColor: "info",
|
|
|
|
|
+ iconColor: "info"
|
|
|
|
|
+ },
|
|
|
|
|
+ neutral: {
|
|
|
|
|
+ containerColor: "subtle",
|
|
|
|
|
+ borderColor: "subtle",
|
|
|
|
|
+ titleColor: "mid",
|
|
|
|
|
+ iconColor: "mid"
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+export const getButtonType = ({
|
|
|
|
|
+ type
|
|
|
|
|
+}: ButtonTypeConstantType): ButtonTypes => {
|
|
|
|
|
+ const currentType = BUTTON_TYPE_STYLES[type];
|
|
|
|
|
+
|
|
|
|
|
+ return currentType;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+export const getButtonVariant = ({
|
|
|
|
|
+ variant
|
|
|
|
|
+}: ButtonVariantConstantType): ButtonVariants => {
|
|
|
|
|
+ const currentVariant = BUTTON_VARIANT_STYLES[variant];
|
|
|
|
|
+
|
|
|
|
|
+ return currentVariant;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+export const getButtonSize = ({
|
|
|
|
|
+ spaces,
|
|
|
|
|
+ size
|
|
|
|
|
+}: ButtonSizeConstantType): ButtonMeasures => {
|
|
|
|
|
+ const currentSize = BUTTON_SIZES[size];
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ paddingHorizontal: spaces[currentSize.paddingHorizontal],
|
|
|
|
|
+ paddingVertical: spaces[currentSize.paddingVertical],
|
|
|
|
|
+ fontSize: currentSize.fontSize
|
|
|
|
|
+ };
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const stylesheet = StyleSheet.create({
|
|
|
|
|
+ container: {
|
|
|
|
|
+ backgroundColor: "transparent",
|
|
|
|
|
+ borderColor: "transparent",
|
|
|
|
|
+ flexDirection: "row",
|
|
|
|
|
+ borderStyle: "solid",
|
|
|
|
|
+ alignItems: "center",
|
|
|
|
|
+ position: "relative",
|
|
|
|
|
+ userSelect: "none",
|
|
|
|
|
+ display: "flex"
|
|
|
|
|
+ },
|
|
|
|
|
+ title: {
|
|
|
|
|
+ margin: "0 auto",
|
|
|
|
|
+ },
|
|
|
|
|
+ loading: {},
|
|
|
|
|
+ overlay: {
|
|
|
|
|
+ position: "absolute",
|
|
|
|
|
+ display: "none",
|
|
|
|
|
+ bottom: 0,
|
|
|
|
|
+ right: 0,
|
|
|
|
|
+ left: 0,
|
|
|
|
|
+ top: 0
|
|
|
|
|
+ }
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+export const useStyles = ({
|
|
|
|
|
+ displayBehaviourWhileLoading,
|
|
|
|
|
+ spreadBehaviour,
|
|
|
|
|
+ currentVariant,
|
|
|
|
|
+ iconDirection,
|
|
|
|
|
+ currentType,
|
|
|
|
|
+ currentSize,
|
|
|
|
|
+ isDisabled,
|
|
|
|
|
+ isLoading,
|
|
|
|
|
+ radiuses,
|
|
|
|
|
+ variant,
|
|
|
|
|
+ borders,
|
|
|
|
|
+ colors,
|
|
|
|
|
+ spaces,
|
|
|
|
|
+ title,
|
|
|
|
|
+ icon,
|
|
|
|
|
+ type
|
|
|
|
|
+}: ButtonDynamicStyleType) => {
|
|
|
|
|
+ const styleType = type === "danger" ? "error" : type;
|
|
|
|
|
+
|
|
|
|
|
+ const styles = {
|
|
|
|
|
+ container: {
|
|
|
|
|
+ paddingRight: currentSize.paddingHorizontal,
|
|
|
|
|
+ paddingBottom: currentSize.paddingVertical,
|
|
|
|
|
+ paddingLeft: currentSize.paddingHorizontal,
|
|
|
|
|
+ paddingTop: currentSize.paddingVertical,
|
|
|
|
|
+ borderRadius: radiuses.md,
|
|
|
|
|
+ borderWidth: borders.line
|
|
|
|
|
+ } as Mutable<ViewStyle>,
|
|
|
|
|
+ title: {
|
|
|
|
|
+ } as Mutable<TextStyle>,
|
|
|
|
|
+ loading: {
|
|
|
|
|
+ } as Mutable<ViewStyle>,
|
|
|
|
|
+ overlay: {
|
|
|
|
|
+ borderRadius: radiuses.md - 2
|
|
|
|
|
+ } as Mutable<ViewStyle>
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ if (currentVariant.containerColor === "type") {
|
|
|
|
|
+ styles.container.backgroundColor = colors.content.container[currentType.containerColor];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ styles.container.backgroundColor = "transparent";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (currentVariant.borderColor === "type") {
|
|
|
|
|
+ styles.container.borderColor = colors.content.border[currentType.borderColor];
|
|
|
|
|
+ } else if (currentVariant.borderColor === "container") {
|
|
|
|
|
+ styles.container.borderColor = styles.container.backgroundColor;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ styles.container.borderColor = "transparent";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (isLoading) {
|
|
|
|
|
+ styles.title.marginLeft = spaces.spacingSm;
|
|
|
|
|
+
|
|
|
|
|
+ if (displayBehaviourWhileLoading === "disabled") {
|
|
|
|
|
+ if (variant !== "ghost") {
|
|
|
|
|
+ styles.container.borderColor = colors.system.state.overlay.disabled[styleType];
|
|
|
|
|
+
|
|
|
|
|
+ if (variant === "filled") {
|
|
|
|
|
+ styles.overlay.backgroundColor = colors.system.state.overlay.disabled[styleType];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (isLoading && spreadBehaviour === "stretch") {
|
|
|
|
|
+ styles.title.marginLeft = spaces.spacingSm;
|
|
|
|
|
+ styles.title.margin = "initial";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (icon && !isLoading) {
|
|
|
|
|
+ styles.title.margin = "initial";
|
|
|
|
|
+ styles.title.marginLeft = spaces.spacingSm;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (spreadBehaviour === "baseline") {
|
|
|
|
|
+ styles.container.alignSelf = spreadBehaviour;
|
|
|
|
|
+ styles.container.width = "auto";
|
|
|
|
|
+ } else if (spreadBehaviour === "stretch") {
|
|
|
|
|
+ styles.container.justifyContent = "center";
|
|
|
|
|
+ // styles.container.alignSelf = spreadBehaviour; TODO: It was required but now is not. Why ?
|
|
|
|
|
+ styles.container.width = "100%";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (isDisabled) {
|
|
|
|
|
+ if (variant !== "ghost") {
|
|
|
|
|
+ styles.container.borderColor = colors.system.state.overlay.disabled[styleType];
|
|
|
|
|
+
|
|
|
|
|
+ if (variant === "filled") {
|
|
|
|
|
+ styles.overlay.backgroundColor = colors.system.state.overlay.disabled[styleType];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (icon && title) {
|
|
|
|
|
+ if (iconDirection === "left") {
|
|
|
|
|
+ styles.title.marginLeft = spaces.spacingSm;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ styles.title.marginRight = spaces.spacingSm;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return styles;
|
|
|
|
|
+};
|
|
|
|
|
+export default stylesheet;
|