@xsolla/xui-button 0.191.0 → 0.193.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/native/index.mjs CHANGED
@@ -775,20 +775,13 @@ var IconButton = ({
775
775
  IconButton.displayName = "IconButton";
776
776
 
777
777
  // src/FlexButton.tsx
778
- import {
778
+ import React4, {
779
+ forwardRef,
779
780
  useRef,
780
781
  useState as useState3
781
782
  } from "react";
782
- import { useDesignSystem } from "@xsolla/xui-core";
783
+ import { useResolvedTheme as useResolvedTheme3 } from "@xsolla/xui-core";
783
784
  import { Fragment, jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
784
- var FLEX_BUTTON_PADDING = 4;
785
- var hasVisibleLabel = (node) => {
786
- if (node == null || node === false) return false;
787
- if (typeof node === "string") return node.trim().length > 0;
788
- if (typeof node === "number") return true;
789
- if (Array.isArray(node)) return node.some(hasVisibleLabel);
790
- return true;
791
- };
792
785
  var ICON_SIZES = {
793
786
  xs: 12,
794
787
  sm: 14,
@@ -803,6 +796,32 @@ var SPINNER_SIZES = {
803
796
  lg: 18,
804
797
  xl: 20
805
798
  };
799
+ var FLEX_BUTTON_PADDING = 4;
800
+ var hasVisibleLabel = (node) => {
801
+ if (node == null || node === false || node === true) return false;
802
+ if (typeof node === "string") return node.trim().length > 0;
803
+ if (typeof node === "number") return true;
804
+ if (Array.isArray(node)) return node.some(hasVisibleLabel);
805
+ if (React4.isValidElement(node)) {
806
+ const { children: elementChildren } = node.props ?? {};
807
+ return hasVisibleLabel(elementChildren);
808
+ }
809
+ return true;
810
+ };
811
+ var hasRenderableContent = (node) => {
812
+ if (node == null || node === false || node === true) return false;
813
+ if (typeof node === "string") return node.trim().length > 0;
814
+ if (Array.isArray(node)) return node.some(hasRenderableContent);
815
+ return true;
816
+ };
817
+ var BOX_SIZES = {
818
+ xs: 20,
819
+ sm: 22,
820
+ md: 28,
821
+ lg: 32,
822
+ xl: 36
823
+ };
824
+ var getFlexButtonBoxSize = (size = "md") => BOX_SIZES[size];
806
825
  var LINE_HEIGHTS = {
807
826
  xs: "14px",
808
827
  sm: "16px",
@@ -824,322 +843,330 @@ var BORDER_RADIUS = {
824
843
  sm: 2,
825
844
  xs: 2
826
845
  };
827
- var FlexButton = ({
828
- children,
829
- variant = "brand",
830
- size = "md",
831
- background = false,
832
- hoverBackground = true,
833
- noPadding = false,
834
- disabled = false,
835
- loading = false,
836
- iconLeft,
837
- iconRight,
838
- onPress,
839
- onClick,
840
- className,
841
- type = "button",
842
- "aria-label": ariaLabel,
843
- "aria-describedby": ariaDescribedBy,
844
- "aria-expanded": ariaExpanded,
845
- "aria-haspopup": ariaHasPopup,
846
- "aria-pressed": ariaPressed,
847
- "aria-controls": ariaControls,
848
- testID,
849
- tabIndex = 0,
850
- ...buttonProps
851
- }) => {
852
- const { theme } = useDesignSystem();
853
- const [state, setState] = useState3("default");
854
- const [isFocused, setIsFocused] = useState3(false);
855
- const isMouseOverRef = useRef(false);
856
- const isDisabled = disabled || loading;
857
- const getVariantColors = (currentState) => {
858
- if (isDisabled) {
859
- return {
860
- bg: background ? theme.colors.overlay.mono : "transparent",
861
- text: theme.colors.control.text.disable,
862
- border: void 0
863
- };
864
- }
865
- const effectiveBackground = loading ? false : background;
866
- switch (variant) {
867
- case "brand":
868
- if (effectiveBackground) {
869
- return {
870
- bg: currentState === "press" ? theme.colors.control.brand.primary.bgPress : currentState === "hover" ? theme.colors.control.brand.primary.bgHover : theme.colors.background.brand.primary,
871
- text: theme.colors.content.on.brand,
872
- border: void 0
873
- };
874
- }
846
+ var FlexButton = forwardRef(
847
+ ({
848
+ children,
849
+ variant = "brand",
850
+ size = "md",
851
+ background = false,
852
+ hoverBackground = true,
853
+ noPadding = false,
854
+ disabled = false,
855
+ loading = false,
856
+ iconLeft,
857
+ iconRight,
858
+ onPress,
859
+ onClick,
860
+ className,
861
+ type = "button",
862
+ "aria-label": ariaLabel,
863
+ "aria-describedby": ariaDescribedBy,
864
+ "aria-expanded": ariaExpanded,
865
+ "aria-haspopup": ariaHasPopup,
866
+ "aria-pressed": ariaPressed,
867
+ "aria-controls": ariaControls,
868
+ testID,
869
+ tabIndex = 0,
870
+ themeMode,
871
+ themeProductContext,
872
+ ...buttonProps
873
+ }, ref) => {
874
+ const { theme } = useResolvedTheme3({ themeMode, themeProductContext });
875
+ const [state, setState] = useState3("default");
876
+ const [isFocused, setIsFocused] = useState3(false);
877
+ const isMouseOverRef = useRef(false);
878
+ const isDisabled = disabled || loading;
879
+ const getVariantColors = (currentState) => {
880
+ if (isDisabled) {
875
881
  return {
876
- bg: !hoverBackground ? "transparent" : currentState === "press" ? theme.colors.background.brand.primary : currentState === "hover" ? theme.colors.overlay.brand : "transparent",
877
- text: currentState === "press" && hoverBackground ? theme.colors.content.on.brand : theme.colors.content.brand.primary,
882
+ bg: background ? theme.colors.overlay.mono : "transparent",
883
+ text: theme.colors.control.text.disable,
878
884
  border: void 0
879
885
  };
880
- case "primary":
881
- if (effectiveBackground) {
886
+ }
887
+ const effectiveBackground = loading ? false : background;
888
+ switch (variant) {
889
+ case "brand":
890
+ if (effectiveBackground) {
891
+ return {
892
+ bg: currentState === "press" ? theme.colors.control.brand.primary.bgPress : currentState === "hover" ? theme.colors.control.brand.primary.bgHover : theme.colors.background.brand.primary,
893
+ text: theme.colors.content.on.brand,
894
+ border: void 0
895
+ };
896
+ }
897
+ return {
898
+ bg: !hoverBackground ? "transparent" : currentState === "press" ? theme.colors.background.brand.primary : currentState === "hover" ? theme.colors.overlay.brand : "transparent",
899
+ text: currentState === "press" && hoverBackground ? theme.colors.content.on.brand : theme.colors.content.brand.primary,
900
+ border: void 0
901
+ };
902
+ case "primary":
903
+ if (effectiveBackground) {
904
+ return {
905
+ bg: theme.colors.background.primary,
906
+ text: theme.colors.content.primary,
907
+ border: currentState === "press" ? theme.colors.border.primary : void 0
908
+ };
909
+ }
882
910
  return {
883
- bg: theme.colors.background.primary,
911
+ bg: !hoverBackground ? "transparent" : currentState === "press" || currentState === "hover" ? theme.colors.overlay.mono : "transparent",
884
912
  text: theme.colors.content.primary,
885
913
  border: currentState === "press" ? theme.colors.border.primary : void 0
886
914
  };
887
- }
888
- return {
889
- bg: !hoverBackground ? "transparent" : currentState === "press" || currentState === "hover" ? theme.colors.overlay.mono : "transparent",
890
- text: theme.colors.content.primary,
891
- border: currentState === "press" ? theme.colors.border.primary : void 0
892
- };
893
- case "secondary":
894
- if (effectiveBackground) {
915
+ case "secondary":
916
+ if (effectiveBackground) {
917
+ return {
918
+ bg: currentState === "press" ? theme.colors.control.mono.secondary.bgPress : currentState === "hover" ? theme.colors.control.mono.secondary.bgHover : theme.colors.background.secondary,
919
+ text: theme.colors.content.secondary,
920
+ border: void 0
921
+ };
922
+ }
895
923
  return {
896
- bg: currentState === "press" ? theme.colors.control.mono.secondary.bgPress : currentState === "hover" ? theme.colors.control.mono.secondary.bgHover : theme.colors.background.secondary,
897
- text: theme.colors.content.secondary,
924
+ bg: !hoverBackground ? "transparent" : currentState === "press" || currentState === "hover" ? theme.colors.overlay.mono : "transparent",
925
+ text: currentState === "press" ? theme.colors.content.primary : currentState === "hover" ? theme.colors.content.secondary : theme.colors.content.secondary,
898
926
  border: void 0
899
927
  };
900
- }
901
- return {
902
- bg: !hoverBackground ? "transparent" : currentState === "press" || currentState === "hover" ? theme.colors.overlay.mono : "transparent",
903
- text: currentState === "press" ? theme.colors.content.primary : currentState === "hover" ? theme.colors.content.secondary : theme.colors.content.secondary,
904
- border: void 0
905
- };
906
- case "tertiary":
907
- if (effectiveBackground) {
928
+ case "tertiary":
929
+ if (effectiveBackground) {
930
+ return {
931
+ bg: currentState === "press" ? theme.colors.control.mono.secondary.bgPress : currentState === "hover" ? theme.colors.control.mono.secondary.bgHover : theme.colors.background.secondary,
932
+ text: theme.colors.content.tertiary,
933
+ border: void 0
934
+ };
935
+ }
908
936
  return {
909
- bg: currentState === "press" ? theme.colors.control.mono.secondary.bgPress : currentState === "hover" ? theme.colors.control.mono.secondary.bgHover : theme.colors.background.secondary,
910
- text: theme.colors.content.tertiary,
937
+ bg: !hoverBackground ? "transparent" : currentState === "press" || currentState === "hover" ? theme.colors.overlay.mono : "transparent",
938
+ text: currentState === "press" ? theme.colors.content.secondary : currentState === "hover" ? theme.colors.content.tertiary : theme.colors.content.tertiary,
911
939
  border: void 0
912
940
  };
913
- }
914
- return {
915
- bg: !hoverBackground ? "transparent" : currentState === "press" || currentState === "hover" ? theme.colors.overlay.mono : "transparent",
916
- text: currentState === "press" ? theme.colors.content.secondary : currentState === "hover" ? theme.colors.content.tertiary : theme.colors.content.tertiary,
917
- border: void 0
918
- };
919
- case "brandExtra":
920
- if (effectiveBackground) {
941
+ case "brandExtra":
942
+ if (effectiveBackground) {
943
+ return {
944
+ bg: currentState === "press" ? theme.colors.control.brandExtra.primary.bgPress : currentState === "hover" ? theme.colors.control.brandExtra.primary.bgHover : theme.colors.background.brandExtra.primary,
945
+ text: theme.colors.content.on.brandExtra,
946
+ border: void 0
947
+ };
948
+ }
921
949
  return {
922
- bg: currentState === "press" ? theme.colors.control.brandExtra.primary.bgPress : currentState === "hover" ? theme.colors.control.brandExtra.primary.bgHover : theme.colors.background.brandExtra.primary,
923
- text: theme.colors.content.on.brandExtra,
950
+ bg: !hoverBackground ? "transparent" : currentState === "press" ? theme.colors.background.brandExtra.primary : currentState === "hover" ? theme.colors.overlay.brandExtra : "transparent",
951
+ text: currentState === "press" ? theme.colors.content.on.brandExtra : theme.colors.content.brandExtra.secondary,
924
952
  border: void 0
925
953
  };
926
- }
927
- return {
928
- bg: !hoverBackground ? "transparent" : currentState === "press" ? theme.colors.background.brandExtra.primary : currentState === "hover" ? theme.colors.overlay.brandExtra : "transparent",
929
- text: currentState === "press" ? theme.colors.content.on.brandExtra : theme.colors.content.brandExtra.secondary,
930
- border: void 0
931
- };
932
- case "inverse":
933
- if (effectiveBackground) {
954
+ case "inverse":
955
+ if (effectiveBackground) {
956
+ return {
957
+ bg: currentState === "press" ? theme.colors.control.mono.primary.bgPress : currentState === "hover" ? theme.colors.control.mono.primary.bgHover : theme.colors.background.inverse,
958
+ text: theme.colors.content.inverse,
959
+ border: void 0
960
+ };
961
+ }
934
962
  return {
935
- bg: currentState === "press" ? theme.colors.control.mono.primary.bgPress : currentState === "hover" ? theme.colors.control.mono.primary.bgHover : theme.colors.background.inverse,
963
+ bg: !hoverBackground ? "transparent" : currentState === "press" || currentState === "hover" ? theme.colors.overlay.mono : "transparent",
936
964
  text: theme.colors.content.inverse,
937
965
  border: void 0
938
966
  };
939
- }
940
- return {
941
- bg: !hoverBackground ? "transparent" : currentState === "press" || currentState === "hover" ? theme.colors.overlay.mono : "transparent",
942
- text: theme.colors.content.inverse,
943
- border: void 0
944
- };
945
- default:
946
- return {
947
- bg: "transparent",
948
- text: theme.colors.content.primary,
949
- border: void 0
950
- };
951
- }
952
- };
953
- const getFocusRingColor = () => {
954
- switch (variant) {
955
- case "brand":
956
- return theme.colors.overlay.brand;
957
- case "brandExtra":
958
- return theme.colors.overlay.brandExtra;
959
- case "inverse":
960
- return "rgba(255, 255, 255, 0.3)";
961
- default:
962
- return theme.colors.overlay.mono;
963
- }
964
- };
965
- const getSpinnerColor = () => {
966
- switch (variant) {
967
- case "brand":
968
- return theme.colors.content.brand.primary;
969
- case "primary":
970
- return theme.colors.content.primary;
971
- case "secondary":
972
- return theme.colors.content.secondary;
973
- case "tertiary":
974
- return theme.colors.content.tertiary;
975
- case "brandExtra":
976
- return theme.colors.content.brandExtra.secondary;
977
- case "inverse":
978
- return theme.colors.content.inverse;
979
- default:
980
- return theme.colors.content.brand.primary;
981
- }
982
- };
983
- const colors = getVariantColors(state);
984
- const focusRingColor = getFocusRingColor();
985
- const spinnerColor = getSpinnerColor();
986
- const iconSize = ICON_SIZES[size];
987
- const spinnerSize = SPINNER_SIZES[size];
988
- const fontSize = FONT_SIZES[size];
989
- const borderRadius = BORDER_RADIUS[size];
990
- const lineHeight = LINE_HEIGHTS[size];
991
- const isIconOnly = !loading && !hasVisibleLabel(children) && Boolean(iconLeft || iconRight);
992
- const iconOnlyHitArea = iconSize + FLEX_BUTTON_PADDING * 2;
993
- const handleMouseEnter = () => {
994
- if (!isDisabled) {
995
- isMouseOverRef.current = true;
996
- setState("hover");
997
- }
998
- };
999
- const handleMouseLeave = () => {
1000
- if (!isDisabled) {
1001
- isMouseOverRef.current = false;
1002
- setState("default");
1003
- }
1004
- };
1005
- const handleMouseDown = () => {
1006
- if (!isDisabled) {
1007
- setState("press");
1008
- }
1009
- };
1010
- const handleMouseUp = () => {
1011
- if (!isDisabled) {
1012
- setState(isMouseOverRef.current ? "hover" : "default");
1013
- }
1014
- };
1015
- const handleFocus = () => {
1016
- if (!isDisabled) {
1017
- setIsFocused(true);
1018
- }
1019
- };
1020
- const handleBlur = () => {
1021
- setIsFocused(false);
1022
- };
1023
- const handleClick = (event) => {
1024
- if (isDisabled) return;
1025
- if (onPress) {
1026
- onPress();
1027
- }
1028
- if (onClick) {
1029
- onClick(event);
1030
- }
1031
- };
1032
- const handleKeyDown = (event) => {
1033
- if (isDisabled) return;
1034
- if (event.key === "Enter" || event.key === " ") {
1035
- event.preventDefault();
1036
- setState("press");
1037
- }
1038
- };
1039
- const handleKeyUp = (event) => {
1040
- if (isDisabled) return;
1041
- if (event.key === "Enter" || event.key === " ") {
1042
- event.preventDefault();
1043
- setState(isMouseOverRef.current ? "hover" : "default");
967
+ default:
968
+ return {
969
+ bg: "transparent",
970
+ text: theme.colors.content.primary,
971
+ border: void 0
972
+ };
973
+ }
974
+ };
975
+ const getFocusRingColor = () => {
976
+ switch (variant) {
977
+ case "brand":
978
+ return theme.colors.overlay.brand;
979
+ case "brandExtra":
980
+ return theme.colors.overlay.brandExtra;
981
+ case "inverse":
982
+ return "rgba(255, 255, 255, 0.3)";
983
+ default:
984
+ return theme.colors.overlay.mono;
985
+ }
986
+ };
987
+ const getSpinnerColor = () => {
988
+ switch (variant) {
989
+ case "brand":
990
+ return theme.colors.content.brand.primary;
991
+ case "primary":
992
+ return theme.colors.content.primary;
993
+ case "secondary":
994
+ return theme.colors.content.secondary;
995
+ case "tertiary":
996
+ return theme.colors.content.tertiary;
997
+ case "brandExtra":
998
+ return theme.colors.content.brandExtra.secondary;
999
+ case "inverse":
1000
+ return theme.colors.content.inverse;
1001
+ default:
1002
+ return theme.colors.content.brand.primary;
1003
+ }
1004
+ };
1005
+ const colors = getVariantColors(state);
1006
+ const focusRingColor = getFocusRingColor();
1007
+ const spinnerColor = getSpinnerColor();
1008
+ const iconSize = ICON_SIZES[size];
1009
+ const spinnerSize = SPINNER_SIZES[size];
1010
+ const fontSize = FONT_SIZES[size];
1011
+ const borderRadius = BORDER_RADIUS[size];
1012
+ const lineHeight = LINE_HEIGHTS[size];
1013
+ const showTextLabel = hasVisibleLabel(children);
1014
+ const hasIconChildren = !showTextLabel && hasRenderableContent(children);
1015
+ const isIconOnly = !loading && !showTextLabel && Boolean(iconLeft || iconRight || hasIconChildren);
1016
+ const iconOnlyHitArea = getFlexButtonBoxSize(size);
1017
+ const handleMouseEnter = () => {
1018
+ if (!isDisabled) {
1019
+ isMouseOverRef.current = true;
1020
+ setState("hover");
1021
+ }
1022
+ };
1023
+ const handleMouseLeave = () => {
1024
+ if (!isDisabled) {
1025
+ isMouseOverRef.current = false;
1026
+ setState("default");
1027
+ }
1028
+ };
1029
+ const handleMouseDown = () => {
1030
+ if (!isDisabled) {
1031
+ setState("press");
1032
+ }
1033
+ };
1034
+ const handleMouseUp = () => {
1035
+ if (!isDisabled) {
1036
+ setState(isMouseOverRef.current ? "hover" : "default");
1037
+ }
1038
+ };
1039
+ const handleFocus = () => {
1040
+ if (!isDisabled) {
1041
+ setIsFocused(true);
1042
+ }
1043
+ };
1044
+ const handleBlur = () => {
1045
+ setIsFocused(false);
1046
+ };
1047
+ const handleClick = (event) => {
1048
+ if (isDisabled) return;
1044
1049
  if (onPress) {
1045
1050
  onPress();
1046
1051
  }
1047
- }
1048
- };
1049
- const borderShadow = colors.border ? `inset 0 0 0 1px ${colors.border}` : void 0;
1050
- const focusShadow = isFocused && !isDisabled ? `0 0 0 2px ${focusRingColor}` : void 0;
1051
- const boxShadows = [];
1052
- if (borderShadow) boxShadows.push(borderShadow);
1053
- if (focusShadow) boxShadows.push(focusShadow);
1054
- const combinedBoxShadow = boxShadows.length > 0 ? boxShadows.join(", ") : "none";
1055
- const buttonStyle = {
1056
- display: "inline-flex",
1057
- alignItems: "center",
1058
- justifyContent: "center",
1059
- gap: isIconOnly ? 0 : "2px",
1060
- boxSizing: "border-box",
1061
- padding: noPadding ? "0px" : `${FLEX_BUTTON_PADDING}px`,
1062
- backgroundColor: loading ? "transparent" : colors.bg,
1063
- color: colors.text,
1064
- border: "none",
1065
- borderWidth: "0px",
1066
- borderRadius: `${borderRadius}px`,
1067
- cursor: isDisabled ? "not-allowed" : "pointer",
1068
- fontSize: `${fontSize}px`,
1069
- fontWeight: 500,
1070
- lineHeight: isIconOnly ? 0 : lineHeight,
1071
- fontFamily: "inherit",
1072
- transition: "background-color 100ms ease-in-out, color 100ms ease-in-out, box-shadow 100ms ease-in-out",
1073
- outline: "none",
1074
- boxShadow: combinedBoxShadow,
1075
- opacity: isDisabled && !loading ? 0.6 : 1,
1076
- ...isIconOnly && {
1077
- width: iconOnlyHitArea,
1078
- height: iconOnlyHitArea,
1079
- minWidth: iconOnlyHitArea,
1080
- minHeight: iconOnlyHitArea,
1081
- flexShrink: 0
1082
- }
1083
- };
1084
- const contentStyle = {
1085
- display: "flex",
1086
- alignItems: "center",
1087
- justifyContent: "center",
1088
- gap: isIconOnly ? 0 : "2px",
1089
- ...isIconOnly && {
1090
- width: "100%",
1091
- height: "100%",
1092
- lineHeight: 0
1093
- }
1094
- };
1095
- const spinnerStyle = {
1096
- display: "flex",
1097
- alignItems: "center",
1098
- justifyContent: "center",
1099
- backgroundColor: "transparent",
1100
- height: lineHeight
1101
- };
1102
- const computedAriaLabel = ariaLabel || (typeof children === "string" ? children : void 0);
1103
- return /* @__PURE__ */ jsx7(
1104
- "button",
1105
- {
1106
- ...buttonProps,
1107
- type,
1108
- className,
1109
- disabled: isDisabled,
1110
- onClick: handleClick,
1111
- onMouseEnter: handleMouseEnter,
1112
- onMouseLeave: handleMouseLeave,
1113
- onMouseDown: handleMouseDown,
1114
- onMouseUp: handleMouseUp,
1115
- onKeyDown: handleKeyDown,
1116
- onKeyUp: handleKeyUp,
1117
- onFocus: handleFocus,
1118
- onBlur: handleBlur,
1119
- "aria-label": computedAriaLabel,
1120
- "aria-busy": loading || void 0,
1121
- "aria-disabled": isDisabled || void 0,
1122
- "aria-describedby": ariaDescribedBy,
1123
- "aria-expanded": ariaExpanded,
1124
- "aria-haspopup": ariaHasPopup,
1125
- "aria-pressed": ariaPressed,
1126
- "aria-controls": ariaControls,
1127
- tabIndex,
1128
- style: buttonStyle,
1129
- "data-testid": testID || "flex-button",
1130
- children: /* @__PURE__ */ jsx7("span", { style: contentStyle, children: loading ? /* @__PURE__ */ jsx7("span", { style: spinnerStyle, children: /* @__PURE__ */ jsx7(Spinner, { size: spinnerSize, color: spinnerColor }) }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
1131
- iconLeft && /* @__PURE__ */ jsx7(Icon, { size: iconSize, color: colors.text, children: iconLeft }),
1132
- hasVisibleLabel(children) && /* @__PURE__ */ jsx7("span", { children }),
1133
- iconRight && /* @__PURE__ */ jsx7(Icon, { size: iconSize, color: colors.text, children: iconRight })
1134
- ] }) })
1135
- }
1136
- );
1137
- };
1052
+ if (onClick) {
1053
+ onClick(event);
1054
+ }
1055
+ };
1056
+ const handleKeyDown = (event) => {
1057
+ if (isDisabled) return;
1058
+ if (event.key === "Enter" || event.key === " ") {
1059
+ event.preventDefault();
1060
+ setState("press");
1061
+ }
1062
+ };
1063
+ const handleKeyUp = (event) => {
1064
+ if (isDisabled) return;
1065
+ if (event.key === "Enter" || event.key === " ") {
1066
+ event.preventDefault();
1067
+ setState(isMouseOverRef.current ? "hover" : "default");
1068
+ if (onPress) {
1069
+ onPress();
1070
+ }
1071
+ }
1072
+ };
1073
+ const borderShadow = colors.border ? `inset 0 0 0 1px ${colors.border}` : void 0;
1074
+ const focusShadow = isFocused && !isDisabled ? `0 0 0 2px ${focusRingColor}` : void 0;
1075
+ const boxShadows = [];
1076
+ if (borderShadow) boxShadows.push(borderShadow);
1077
+ if (focusShadow) boxShadows.push(focusShadow);
1078
+ const combinedBoxShadow = boxShadows.length > 0 ? boxShadows.join(", ") : "none";
1079
+ const buttonStyle = {
1080
+ display: "inline-flex",
1081
+ alignItems: "center",
1082
+ justifyContent: "center",
1083
+ gap: isIconOnly ? 0 : "2px",
1084
+ boxSizing: "border-box",
1085
+ padding: noPadding ? "0px" : `${FLEX_BUTTON_PADDING}px`,
1086
+ backgroundColor: loading ? "transparent" : colors.bg,
1087
+ color: colors.text,
1088
+ border: "none",
1089
+ borderWidth: "0px",
1090
+ borderRadius: `${borderRadius}px`,
1091
+ cursor: isDisabled ? "not-allowed" : "pointer",
1092
+ fontSize: `${fontSize}px`,
1093
+ fontWeight: 500,
1094
+ lineHeight: isIconOnly ? 0 : lineHeight,
1095
+ fontFamily: "inherit",
1096
+ transition: "background-color 100ms ease-in-out, color 100ms ease-in-out, box-shadow 100ms ease-in-out",
1097
+ outline: "none",
1098
+ boxShadow: combinedBoxShadow,
1099
+ opacity: isDisabled && !loading ? 0.6 : 1,
1100
+ ...isIconOnly && {
1101
+ width: iconOnlyHitArea,
1102
+ height: iconOnlyHitArea,
1103
+ minWidth: iconOnlyHitArea,
1104
+ minHeight: iconOnlyHitArea,
1105
+ flexShrink: 0
1106
+ }
1107
+ };
1108
+ const contentStyle = {
1109
+ display: "flex",
1110
+ alignItems: "center",
1111
+ justifyContent: "center",
1112
+ gap: isIconOnly ? 0 : "2px",
1113
+ ...isIconOnly && {
1114
+ width: "100%",
1115
+ height: "100%",
1116
+ lineHeight: 0
1117
+ }
1118
+ };
1119
+ const spinnerStyle = {
1120
+ display: "flex",
1121
+ alignItems: "center",
1122
+ justifyContent: "center",
1123
+ backgroundColor: "transparent",
1124
+ height: lineHeight
1125
+ };
1126
+ const computedAriaLabel = ariaLabel || (typeof children === "string" ? children : void 0);
1127
+ return /* @__PURE__ */ jsx7(
1128
+ "button",
1129
+ {
1130
+ ...buttonProps,
1131
+ ref,
1132
+ type,
1133
+ className,
1134
+ disabled: isDisabled,
1135
+ onClick: handleClick,
1136
+ onMouseEnter: handleMouseEnter,
1137
+ onMouseLeave: handleMouseLeave,
1138
+ onMouseDown: handleMouseDown,
1139
+ onMouseUp: handleMouseUp,
1140
+ onKeyDown: handleKeyDown,
1141
+ onKeyUp: handleKeyUp,
1142
+ onFocus: handleFocus,
1143
+ onBlur: handleBlur,
1144
+ "aria-label": computedAriaLabel,
1145
+ "aria-busy": loading || void 0,
1146
+ "aria-disabled": isDisabled || void 0,
1147
+ "aria-describedby": ariaDescribedBy,
1148
+ "aria-expanded": ariaExpanded,
1149
+ "aria-haspopup": ariaHasPopup,
1150
+ "aria-pressed": ariaPressed,
1151
+ "aria-controls": ariaControls,
1152
+ tabIndex,
1153
+ style: buttonStyle,
1154
+ "data-testid": testID || "flex-button",
1155
+ children: /* @__PURE__ */ jsx7("span", { style: contentStyle, children: loading ? /* @__PURE__ */ jsx7("span", { style: spinnerStyle, children: /* @__PURE__ */ jsx7(Spinner, { size: spinnerSize, color: spinnerColor }) }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
1156
+ iconLeft && /* @__PURE__ */ jsx7(Icon, { size: iconSize, color: colors.text, children: iconLeft }),
1157
+ showTextLabel && /* @__PURE__ */ jsx7("span", { children }),
1158
+ hasIconChildren && /* @__PURE__ */ jsx7(Icon, { size: iconSize, color: colors.text, children }),
1159
+ iconRight && /* @__PURE__ */ jsx7(Icon, { size: iconSize, color: colors.text, children: iconRight })
1160
+ ] }) })
1161
+ }
1162
+ );
1163
+ }
1164
+ );
1138
1165
  FlexButton.displayName = "FlexButton";
1139
1166
 
1140
1167
  // src/AppButton.tsx
1141
1168
  import React5, { useState as useState4 } from "react";
1142
- import { useResolvedTheme as useResolvedTheme3 } from "@xsolla/xui-core";
1169
+ import { useResolvedTheme as useResolvedTheme4 } from "@xsolla/xui-core";
1143
1170
  import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
1144
1171
  var cloneIconWithDefaults3 = (icon, defaultSize, defaultColor) => {
1145
1172
  if (!React5.isValidElement(icon)) return icon;
@@ -1176,7 +1203,7 @@ var AppButton = ({
1176
1203
  themeMode,
1177
1204
  themeProductContext
1178
1205
  }) => {
1179
- const { theme } = useResolvedTheme3({ themeMode, themeProductContext });
1206
+ const { theme } = useResolvedTheme4({ themeMode, themeProductContext });
1180
1207
  const [isKeyboardPressed, setIsKeyboardPressed] = useState4(false);
1181
1208
  const isDisabled = disabled || loading;
1182
1209
  const sizeStyles = theme.sizing.button(size);
@@ -1362,7 +1389,7 @@ AppButton.displayName = "AppButton";
1362
1389
 
1363
1390
  // src/ButtonGroup.tsx
1364
1391
  import React6 from "react";
1365
- import { useResolvedTheme as useResolvedTheme4 } from "@xsolla/xui-core";
1392
+ import { useResolvedTheme as useResolvedTheme5 } from "@xsolla/xui-core";
1366
1393
  import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
1367
1394
  var ButtonGroup = ({
1368
1395
  orientation = "horizontal",
@@ -1379,7 +1406,7 @@ var ButtonGroup = ({
1379
1406
  themeMode,
1380
1407
  themeProductContext
1381
1408
  }) => {
1382
- const { theme } = useResolvedTheme4({ themeMode, themeProductContext });
1409
+ const { theme } = useResolvedTheme5({ themeMode, themeProductContext });
1383
1410
  const flattenChildren = (children2) => {
1384
1411
  const result = [];
1385
1412
  React6.Children.forEach(children2, (child) => {
@@ -1494,6 +1521,7 @@ export {
1494
1521
  Button,
1495
1522
  ButtonGroup,
1496
1523
  FlexButton,
1497
- IconButton
1524
+ IconButton,
1525
+ getFlexButtonBoxSize
1498
1526
  };
1499
1527
  //# sourceMappingURL=index.mjs.map