@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/web/index.mjs CHANGED
@@ -831,20 +831,13 @@ var IconButton = ({
831
831
  IconButton.displayName = "IconButton";
832
832
 
833
833
  // src/FlexButton.tsx
834
- import {
834
+ import React5, {
835
+ forwardRef,
835
836
  useRef,
836
837
  useState as useState3
837
838
  } from "react";
838
- import { useDesignSystem } from "@xsolla/xui-core";
839
+ import { useResolvedTheme as useResolvedTheme3 } from "@xsolla/xui-core";
839
840
  import { Fragment, jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
840
- var FLEX_BUTTON_PADDING = 4;
841
- var hasVisibleLabel = (node) => {
842
- if (node == null || node === false) return false;
843
- if (typeof node === "string") return node.trim().length > 0;
844
- if (typeof node === "number") return true;
845
- if (Array.isArray(node)) return node.some(hasVisibleLabel);
846
- return true;
847
- };
848
841
  var ICON_SIZES = {
849
842
  xs: 12,
850
843
  sm: 14,
@@ -859,6 +852,32 @@ var SPINNER_SIZES = {
859
852
  lg: 18,
860
853
  xl: 20
861
854
  };
855
+ var FLEX_BUTTON_PADDING = 4;
856
+ var hasVisibleLabel = (node) => {
857
+ if (node == null || node === false || node === true) return false;
858
+ if (typeof node === "string") return node.trim().length > 0;
859
+ if (typeof node === "number") return true;
860
+ if (Array.isArray(node)) return node.some(hasVisibleLabel);
861
+ if (React5.isValidElement(node)) {
862
+ const { children: elementChildren } = node.props ?? {};
863
+ return hasVisibleLabel(elementChildren);
864
+ }
865
+ return true;
866
+ };
867
+ var hasRenderableContent = (node) => {
868
+ if (node == null || node === false || node === true) return false;
869
+ if (typeof node === "string") return node.trim().length > 0;
870
+ if (Array.isArray(node)) return node.some(hasRenderableContent);
871
+ return true;
872
+ };
873
+ var BOX_SIZES = {
874
+ xs: 20,
875
+ sm: 22,
876
+ md: 28,
877
+ lg: 32,
878
+ xl: 36
879
+ };
880
+ var getFlexButtonBoxSize = (size = "md") => BOX_SIZES[size];
862
881
  var LINE_HEIGHTS = {
863
882
  xs: "14px",
864
883
  sm: "16px",
@@ -880,322 +899,330 @@ var BORDER_RADIUS = {
880
899
  sm: 2,
881
900
  xs: 2
882
901
  };
883
- var FlexButton = ({
884
- children,
885
- variant = "brand",
886
- size = "md",
887
- background = false,
888
- hoverBackground = true,
889
- noPadding = false,
890
- disabled = false,
891
- loading = false,
892
- iconLeft,
893
- iconRight,
894
- onPress,
895
- onClick,
896
- className,
897
- type = "button",
898
- "aria-label": ariaLabel,
899
- "aria-describedby": ariaDescribedBy,
900
- "aria-expanded": ariaExpanded,
901
- "aria-haspopup": ariaHasPopup,
902
- "aria-pressed": ariaPressed,
903
- "aria-controls": ariaControls,
904
- testID,
905
- tabIndex = 0,
906
- ...buttonProps
907
- }) => {
908
- const { theme } = useDesignSystem();
909
- const [state, setState] = useState3("default");
910
- const [isFocused, setIsFocused] = useState3(false);
911
- const isMouseOverRef = useRef(false);
912
- const isDisabled = disabled || loading;
913
- const getVariantColors = (currentState) => {
914
- if (isDisabled) {
915
- return {
916
- bg: background ? theme.colors.overlay.mono : "transparent",
917
- text: theme.colors.control.text.disable,
918
- border: void 0
919
- };
920
- }
921
- const effectiveBackground = loading ? false : background;
922
- switch (variant) {
923
- case "brand":
924
- if (effectiveBackground) {
925
- return {
926
- bg: currentState === "press" ? theme.colors.control.brand.primary.bgPress : currentState === "hover" ? theme.colors.control.brand.primary.bgHover : theme.colors.background.brand.primary,
927
- text: theme.colors.content.on.brand,
928
- border: void 0
929
- };
930
- }
902
+ var FlexButton = forwardRef(
903
+ ({
904
+ children,
905
+ variant = "brand",
906
+ size = "md",
907
+ background = false,
908
+ hoverBackground = true,
909
+ noPadding = false,
910
+ disabled = false,
911
+ loading = false,
912
+ iconLeft,
913
+ iconRight,
914
+ onPress,
915
+ onClick,
916
+ className,
917
+ type = "button",
918
+ "aria-label": ariaLabel,
919
+ "aria-describedby": ariaDescribedBy,
920
+ "aria-expanded": ariaExpanded,
921
+ "aria-haspopup": ariaHasPopup,
922
+ "aria-pressed": ariaPressed,
923
+ "aria-controls": ariaControls,
924
+ testID,
925
+ tabIndex = 0,
926
+ themeMode,
927
+ themeProductContext,
928
+ ...buttonProps
929
+ }, ref) => {
930
+ const { theme } = useResolvedTheme3({ themeMode, themeProductContext });
931
+ const [state, setState] = useState3("default");
932
+ const [isFocused, setIsFocused] = useState3(false);
933
+ const isMouseOverRef = useRef(false);
934
+ const isDisabled = disabled || loading;
935
+ const getVariantColors = (currentState) => {
936
+ if (isDisabled) {
931
937
  return {
932
- bg: !hoverBackground ? "transparent" : currentState === "press" ? theme.colors.background.brand.primary : currentState === "hover" ? theme.colors.overlay.brand : "transparent",
933
- text: currentState === "press" && hoverBackground ? theme.colors.content.on.brand : theme.colors.content.brand.primary,
938
+ bg: background ? theme.colors.overlay.mono : "transparent",
939
+ text: theme.colors.control.text.disable,
934
940
  border: void 0
935
941
  };
936
- case "primary":
937
- if (effectiveBackground) {
942
+ }
943
+ const effectiveBackground = loading ? false : background;
944
+ switch (variant) {
945
+ case "brand":
946
+ if (effectiveBackground) {
947
+ return {
948
+ bg: currentState === "press" ? theme.colors.control.brand.primary.bgPress : currentState === "hover" ? theme.colors.control.brand.primary.bgHover : theme.colors.background.brand.primary,
949
+ text: theme.colors.content.on.brand,
950
+ border: void 0
951
+ };
952
+ }
953
+ return {
954
+ bg: !hoverBackground ? "transparent" : currentState === "press" ? theme.colors.background.brand.primary : currentState === "hover" ? theme.colors.overlay.brand : "transparent",
955
+ text: currentState === "press" && hoverBackground ? theme.colors.content.on.brand : theme.colors.content.brand.primary,
956
+ border: void 0
957
+ };
958
+ case "primary":
959
+ if (effectiveBackground) {
960
+ return {
961
+ bg: theme.colors.background.primary,
962
+ text: theme.colors.content.primary,
963
+ border: currentState === "press" ? theme.colors.border.primary : void 0
964
+ };
965
+ }
938
966
  return {
939
- bg: theme.colors.background.primary,
967
+ bg: !hoverBackground ? "transparent" : currentState === "press" || currentState === "hover" ? theme.colors.overlay.mono : "transparent",
940
968
  text: theme.colors.content.primary,
941
969
  border: currentState === "press" ? theme.colors.border.primary : void 0
942
970
  };
943
- }
944
- return {
945
- bg: !hoverBackground ? "transparent" : currentState === "press" || currentState === "hover" ? theme.colors.overlay.mono : "transparent",
946
- text: theme.colors.content.primary,
947
- border: currentState === "press" ? theme.colors.border.primary : void 0
948
- };
949
- case "secondary":
950
- if (effectiveBackground) {
971
+ case "secondary":
972
+ if (effectiveBackground) {
973
+ return {
974
+ bg: currentState === "press" ? theme.colors.control.mono.secondary.bgPress : currentState === "hover" ? theme.colors.control.mono.secondary.bgHover : theme.colors.background.secondary,
975
+ text: theme.colors.content.secondary,
976
+ border: void 0
977
+ };
978
+ }
951
979
  return {
952
- bg: currentState === "press" ? theme.colors.control.mono.secondary.bgPress : currentState === "hover" ? theme.colors.control.mono.secondary.bgHover : theme.colors.background.secondary,
953
- text: theme.colors.content.secondary,
980
+ bg: !hoverBackground ? "transparent" : currentState === "press" || currentState === "hover" ? theme.colors.overlay.mono : "transparent",
981
+ text: currentState === "press" ? theme.colors.content.primary : currentState === "hover" ? theme.colors.content.secondary : theme.colors.content.secondary,
954
982
  border: void 0
955
983
  };
956
- }
957
- return {
958
- bg: !hoverBackground ? "transparent" : currentState === "press" || currentState === "hover" ? theme.colors.overlay.mono : "transparent",
959
- text: currentState === "press" ? theme.colors.content.primary : currentState === "hover" ? theme.colors.content.secondary : theme.colors.content.secondary,
960
- border: void 0
961
- };
962
- case "tertiary":
963
- if (effectiveBackground) {
984
+ case "tertiary":
985
+ if (effectiveBackground) {
986
+ return {
987
+ bg: currentState === "press" ? theme.colors.control.mono.secondary.bgPress : currentState === "hover" ? theme.colors.control.mono.secondary.bgHover : theme.colors.background.secondary,
988
+ text: theme.colors.content.tertiary,
989
+ border: void 0
990
+ };
991
+ }
964
992
  return {
965
- bg: currentState === "press" ? theme.colors.control.mono.secondary.bgPress : currentState === "hover" ? theme.colors.control.mono.secondary.bgHover : theme.colors.background.secondary,
966
- text: theme.colors.content.tertiary,
993
+ bg: !hoverBackground ? "transparent" : currentState === "press" || currentState === "hover" ? theme.colors.overlay.mono : "transparent",
994
+ text: currentState === "press" ? theme.colors.content.secondary : currentState === "hover" ? theme.colors.content.tertiary : theme.colors.content.tertiary,
967
995
  border: void 0
968
996
  };
969
- }
970
- return {
971
- bg: !hoverBackground ? "transparent" : currentState === "press" || currentState === "hover" ? theme.colors.overlay.mono : "transparent",
972
- text: currentState === "press" ? theme.colors.content.secondary : currentState === "hover" ? theme.colors.content.tertiary : theme.colors.content.tertiary,
973
- border: void 0
974
- };
975
- case "brandExtra":
976
- if (effectiveBackground) {
997
+ case "brandExtra":
998
+ if (effectiveBackground) {
999
+ return {
1000
+ bg: currentState === "press" ? theme.colors.control.brandExtra.primary.bgPress : currentState === "hover" ? theme.colors.control.brandExtra.primary.bgHover : theme.colors.background.brandExtra.primary,
1001
+ text: theme.colors.content.on.brandExtra,
1002
+ border: void 0
1003
+ };
1004
+ }
977
1005
  return {
978
- bg: currentState === "press" ? theme.colors.control.brandExtra.primary.bgPress : currentState === "hover" ? theme.colors.control.brandExtra.primary.bgHover : theme.colors.background.brandExtra.primary,
979
- text: theme.colors.content.on.brandExtra,
1006
+ bg: !hoverBackground ? "transparent" : currentState === "press" ? theme.colors.background.brandExtra.primary : currentState === "hover" ? theme.colors.overlay.brandExtra : "transparent",
1007
+ text: currentState === "press" ? theme.colors.content.on.brandExtra : theme.colors.content.brandExtra.secondary,
980
1008
  border: void 0
981
1009
  };
982
- }
983
- return {
984
- bg: !hoverBackground ? "transparent" : currentState === "press" ? theme.colors.background.brandExtra.primary : currentState === "hover" ? theme.colors.overlay.brandExtra : "transparent",
985
- text: currentState === "press" ? theme.colors.content.on.brandExtra : theme.colors.content.brandExtra.secondary,
986
- border: void 0
987
- };
988
- case "inverse":
989
- if (effectiveBackground) {
1010
+ case "inverse":
1011
+ if (effectiveBackground) {
1012
+ return {
1013
+ bg: currentState === "press" ? theme.colors.control.mono.primary.bgPress : currentState === "hover" ? theme.colors.control.mono.primary.bgHover : theme.colors.background.inverse,
1014
+ text: theme.colors.content.inverse,
1015
+ border: void 0
1016
+ };
1017
+ }
990
1018
  return {
991
- bg: currentState === "press" ? theme.colors.control.mono.primary.bgPress : currentState === "hover" ? theme.colors.control.mono.primary.bgHover : theme.colors.background.inverse,
1019
+ bg: !hoverBackground ? "transparent" : currentState === "press" || currentState === "hover" ? theme.colors.overlay.mono : "transparent",
992
1020
  text: theme.colors.content.inverse,
993
1021
  border: void 0
994
1022
  };
995
- }
996
- return {
997
- bg: !hoverBackground ? "transparent" : currentState === "press" || currentState === "hover" ? theme.colors.overlay.mono : "transparent",
998
- text: theme.colors.content.inverse,
999
- border: void 0
1000
- };
1001
- default:
1002
- return {
1003
- bg: "transparent",
1004
- text: theme.colors.content.primary,
1005
- border: void 0
1006
- };
1007
- }
1008
- };
1009
- const getFocusRingColor = () => {
1010
- switch (variant) {
1011
- case "brand":
1012
- return theme.colors.overlay.brand;
1013
- case "brandExtra":
1014
- return theme.colors.overlay.brandExtra;
1015
- case "inverse":
1016
- return "rgba(255, 255, 255, 0.3)";
1017
- default:
1018
- return theme.colors.overlay.mono;
1019
- }
1020
- };
1021
- const getSpinnerColor = () => {
1022
- switch (variant) {
1023
- case "brand":
1024
- return theme.colors.content.brand.primary;
1025
- case "primary":
1026
- return theme.colors.content.primary;
1027
- case "secondary":
1028
- return theme.colors.content.secondary;
1029
- case "tertiary":
1030
- return theme.colors.content.tertiary;
1031
- case "brandExtra":
1032
- return theme.colors.content.brandExtra.secondary;
1033
- case "inverse":
1034
- return theme.colors.content.inverse;
1035
- default:
1036
- return theme.colors.content.brand.primary;
1037
- }
1038
- };
1039
- const colors = getVariantColors(state);
1040
- const focusRingColor = getFocusRingColor();
1041
- const spinnerColor = getSpinnerColor();
1042
- const iconSize = ICON_SIZES[size];
1043
- const spinnerSize = SPINNER_SIZES[size];
1044
- const fontSize = FONT_SIZES[size];
1045
- const borderRadius = BORDER_RADIUS[size];
1046
- const lineHeight = LINE_HEIGHTS[size];
1047
- const isIconOnly = !loading && !hasVisibleLabel(children) && Boolean(iconLeft || iconRight);
1048
- const iconOnlyHitArea = iconSize + FLEX_BUTTON_PADDING * 2;
1049
- const handleMouseEnter = () => {
1050
- if (!isDisabled) {
1051
- isMouseOverRef.current = true;
1052
- setState("hover");
1053
- }
1054
- };
1055
- const handleMouseLeave = () => {
1056
- if (!isDisabled) {
1057
- isMouseOverRef.current = false;
1058
- setState("default");
1059
- }
1060
- };
1061
- const handleMouseDown = () => {
1062
- if (!isDisabled) {
1063
- setState("press");
1064
- }
1065
- };
1066
- const handleMouseUp = () => {
1067
- if (!isDisabled) {
1068
- setState(isMouseOverRef.current ? "hover" : "default");
1069
- }
1070
- };
1071
- const handleFocus = () => {
1072
- if (!isDisabled) {
1073
- setIsFocused(true);
1074
- }
1075
- };
1076
- const handleBlur = () => {
1077
- setIsFocused(false);
1078
- };
1079
- const handleClick = (event) => {
1080
- if (isDisabled) return;
1081
- if (onPress) {
1082
- onPress();
1083
- }
1084
- if (onClick) {
1085
- onClick(event);
1086
- }
1087
- };
1088
- const handleKeyDown = (event) => {
1089
- if (isDisabled) return;
1090
- if (event.key === "Enter" || event.key === " ") {
1091
- event.preventDefault();
1092
- setState("press");
1093
- }
1094
- };
1095
- const handleKeyUp = (event) => {
1096
- if (isDisabled) return;
1097
- if (event.key === "Enter" || event.key === " ") {
1098
- event.preventDefault();
1099
- setState(isMouseOverRef.current ? "hover" : "default");
1023
+ default:
1024
+ return {
1025
+ bg: "transparent",
1026
+ text: theme.colors.content.primary,
1027
+ border: void 0
1028
+ };
1029
+ }
1030
+ };
1031
+ const getFocusRingColor = () => {
1032
+ switch (variant) {
1033
+ case "brand":
1034
+ return theme.colors.overlay.brand;
1035
+ case "brandExtra":
1036
+ return theme.colors.overlay.brandExtra;
1037
+ case "inverse":
1038
+ return "rgba(255, 255, 255, 0.3)";
1039
+ default:
1040
+ return theme.colors.overlay.mono;
1041
+ }
1042
+ };
1043
+ const getSpinnerColor = () => {
1044
+ switch (variant) {
1045
+ case "brand":
1046
+ return theme.colors.content.brand.primary;
1047
+ case "primary":
1048
+ return theme.colors.content.primary;
1049
+ case "secondary":
1050
+ return theme.colors.content.secondary;
1051
+ case "tertiary":
1052
+ return theme.colors.content.tertiary;
1053
+ case "brandExtra":
1054
+ return theme.colors.content.brandExtra.secondary;
1055
+ case "inverse":
1056
+ return theme.colors.content.inverse;
1057
+ default:
1058
+ return theme.colors.content.brand.primary;
1059
+ }
1060
+ };
1061
+ const colors = getVariantColors(state);
1062
+ const focusRingColor = getFocusRingColor();
1063
+ const spinnerColor = getSpinnerColor();
1064
+ const iconSize = ICON_SIZES[size];
1065
+ const spinnerSize = SPINNER_SIZES[size];
1066
+ const fontSize = FONT_SIZES[size];
1067
+ const borderRadius = BORDER_RADIUS[size];
1068
+ const lineHeight = LINE_HEIGHTS[size];
1069
+ const showTextLabel = hasVisibleLabel(children);
1070
+ const hasIconChildren = !showTextLabel && hasRenderableContent(children);
1071
+ const isIconOnly = !loading && !showTextLabel && Boolean(iconLeft || iconRight || hasIconChildren);
1072
+ const iconOnlyHitArea = getFlexButtonBoxSize(size);
1073
+ const handleMouseEnter = () => {
1074
+ if (!isDisabled) {
1075
+ isMouseOverRef.current = true;
1076
+ setState("hover");
1077
+ }
1078
+ };
1079
+ const handleMouseLeave = () => {
1080
+ if (!isDisabled) {
1081
+ isMouseOverRef.current = false;
1082
+ setState("default");
1083
+ }
1084
+ };
1085
+ const handleMouseDown = () => {
1086
+ if (!isDisabled) {
1087
+ setState("press");
1088
+ }
1089
+ };
1090
+ const handleMouseUp = () => {
1091
+ if (!isDisabled) {
1092
+ setState(isMouseOverRef.current ? "hover" : "default");
1093
+ }
1094
+ };
1095
+ const handleFocus = () => {
1096
+ if (!isDisabled) {
1097
+ setIsFocused(true);
1098
+ }
1099
+ };
1100
+ const handleBlur = () => {
1101
+ setIsFocused(false);
1102
+ };
1103
+ const handleClick = (event) => {
1104
+ if (isDisabled) return;
1100
1105
  if (onPress) {
1101
1106
  onPress();
1102
1107
  }
1103
- }
1104
- };
1105
- const borderShadow = colors.border ? `inset 0 0 0 1px ${colors.border}` : void 0;
1106
- const focusShadow = isFocused && !isDisabled ? `0 0 0 2px ${focusRingColor}` : void 0;
1107
- const boxShadows = [];
1108
- if (borderShadow) boxShadows.push(borderShadow);
1109
- if (focusShadow) boxShadows.push(focusShadow);
1110
- const combinedBoxShadow = boxShadows.length > 0 ? boxShadows.join(", ") : "none";
1111
- const buttonStyle = {
1112
- display: "inline-flex",
1113
- alignItems: "center",
1114
- justifyContent: "center",
1115
- gap: isIconOnly ? 0 : "2px",
1116
- boxSizing: "border-box",
1117
- padding: noPadding ? "0px" : `${FLEX_BUTTON_PADDING}px`,
1118
- backgroundColor: loading ? "transparent" : colors.bg,
1119
- color: colors.text,
1120
- border: "none",
1121
- borderWidth: "0px",
1122
- borderRadius: `${borderRadius}px`,
1123
- cursor: isDisabled ? "not-allowed" : "pointer",
1124
- fontSize: `${fontSize}px`,
1125
- fontWeight: 500,
1126
- lineHeight: isIconOnly ? 0 : lineHeight,
1127
- fontFamily: "inherit",
1128
- transition: "background-color 100ms ease-in-out, color 100ms ease-in-out, box-shadow 100ms ease-in-out",
1129
- outline: "none",
1130
- boxShadow: combinedBoxShadow,
1131
- opacity: isDisabled && !loading ? 0.6 : 1,
1132
- ...isIconOnly && {
1133
- width: iconOnlyHitArea,
1134
- height: iconOnlyHitArea,
1135
- minWidth: iconOnlyHitArea,
1136
- minHeight: iconOnlyHitArea,
1137
- flexShrink: 0
1138
- }
1139
- };
1140
- const contentStyle = {
1141
- display: "flex",
1142
- alignItems: "center",
1143
- justifyContent: "center",
1144
- gap: isIconOnly ? 0 : "2px",
1145
- ...isIconOnly && {
1146
- width: "100%",
1147
- height: "100%",
1148
- lineHeight: 0
1149
- }
1150
- };
1151
- const spinnerStyle = {
1152
- display: "flex",
1153
- alignItems: "center",
1154
- justifyContent: "center",
1155
- backgroundColor: "transparent",
1156
- height: lineHeight
1157
- };
1158
- const computedAriaLabel = ariaLabel || (typeof children === "string" ? children : void 0);
1159
- return /* @__PURE__ */ jsx7(
1160
- "button",
1161
- {
1162
- ...buttonProps,
1163
- type,
1164
- className,
1165
- disabled: isDisabled,
1166
- onClick: handleClick,
1167
- onMouseEnter: handleMouseEnter,
1168
- onMouseLeave: handleMouseLeave,
1169
- onMouseDown: handleMouseDown,
1170
- onMouseUp: handleMouseUp,
1171
- onKeyDown: handleKeyDown,
1172
- onKeyUp: handleKeyUp,
1173
- onFocus: handleFocus,
1174
- onBlur: handleBlur,
1175
- "aria-label": computedAriaLabel,
1176
- "aria-busy": loading || void 0,
1177
- "aria-disabled": isDisabled || void 0,
1178
- "aria-describedby": ariaDescribedBy,
1179
- "aria-expanded": ariaExpanded,
1180
- "aria-haspopup": ariaHasPopup,
1181
- "aria-pressed": ariaPressed,
1182
- "aria-controls": ariaControls,
1183
- tabIndex,
1184
- style: buttonStyle,
1185
- "data-testid": testID || "flex-button",
1186
- 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: [
1187
- iconLeft && /* @__PURE__ */ jsx7(Icon, { size: iconSize, color: colors.text, children: iconLeft }),
1188
- hasVisibleLabel(children) && /* @__PURE__ */ jsx7("span", { children }),
1189
- iconRight && /* @__PURE__ */ jsx7(Icon, { size: iconSize, color: colors.text, children: iconRight })
1190
- ] }) })
1191
- }
1192
- );
1193
- };
1108
+ if (onClick) {
1109
+ onClick(event);
1110
+ }
1111
+ };
1112
+ const handleKeyDown = (event) => {
1113
+ if (isDisabled) return;
1114
+ if (event.key === "Enter" || event.key === " ") {
1115
+ event.preventDefault();
1116
+ setState("press");
1117
+ }
1118
+ };
1119
+ const handleKeyUp = (event) => {
1120
+ if (isDisabled) return;
1121
+ if (event.key === "Enter" || event.key === " ") {
1122
+ event.preventDefault();
1123
+ setState(isMouseOverRef.current ? "hover" : "default");
1124
+ if (onPress) {
1125
+ onPress();
1126
+ }
1127
+ }
1128
+ };
1129
+ const borderShadow = colors.border ? `inset 0 0 0 1px ${colors.border}` : void 0;
1130
+ const focusShadow = isFocused && !isDisabled ? `0 0 0 2px ${focusRingColor}` : void 0;
1131
+ const boxShadows = [];
1132
+ if (borderShadow) boxShadows.push(borderShadow);
1133
+ if (focusShadow) boxShadows.push(focusShadow);
1134
+ const combinedBoxShadow = boxShadows.length > 0 ? boxShadows.join(", ") : "none";
1135
+ const buttonStyle = {
1136
+ display: "inline-flex",
1137
+ alignItems: "center",
1138
+ justifyContent: "center",
1139
+ gap: isIconOnly ? 0 : "2px",
1140
+ boxSizing: "border-box",
1141
+ padding: noPadding ? "0px" : `${FLEX_BUTTON_PADDING}px`,
1142
+ backgroundColor: loading ? "transparent" : colors.bg,
1143
+ color: colors.text,
1144
+ border: "none",
1145
+ borderWidth: "0px",
1146
+ borderRadius: `${borderRadius}px`,
1147
+ cursor: isDisabled ? "not-allowed" : "pointer",
1148
+ fontSize: `${fontSize}px`,
1149
+ fontWeight: 500,
1150
+ lineHeight: isIconOnly ? 0 : lineHeight,
1151
+ fontFamily: "inherit",
1152
+ transition: "background-color 100ms ease-in-out, color 100ms ease-in-out, box-shadow 100ms ease-in-out",
1153
+ outline: "none",
1154
+ boxShadow: combinedBoxShadow,
1155
+ opacity: isDisabled && !loading ? 0.6 : 1,
1156
+ ...isIconOnly && {
1157
+ width: iconOnlyHitArea,
1158
+ height: iconOnlyHitArea,
1159
+ minWidth: iconOnlyHitArea,
1160
+ minHeight: iconOnlyHitArea,
1161
+ flexShrink: 0
1162
+ }
1163
+ };
1164
+ const contentStyle = {
1165
+ display: "flex",
1166
+ alignItems: "center",
1167
+ justifyContent: "center",
1168
+ gap: isIconOnly ? 0 : "2px",
1169
+ ...isIconOnly && {
1170
+ width: "100%",
1171
+ height: "100%",
1172
+ lineHeight: 0
1173
+ }
1174
+ };
1175
+ const spinnerStyle = {
1176
+ display: "flex",
1177
+ alignItems: "center",
1178
+ justifyContent: "center",
1179
+ backgroundColor: "transparent",
1180
+ height: lineHeight
1181
+ };
1182
+ const computedAriaLabel = ariaLabel || (typeof children === "string" ? children : void 0);
1183
+ return /* @__PURE__ */ jsx7(
1184
+ "button",
1185
+ {
1186
+ ...buttonProps,
1187
+ ref,
1188
+ type,
1189
+ className,
1190
+ disabled: isDisabled,
1191
+ onClick: handleClick,
1192
+ onMouseEnter: handleMouseEnter,
1193
+ onMouseLeave: handleMouseLeave,
1194
+ onMouseDown: handleMouseDown,
1195
+ onMouseUp: handleMouseUp,
1196
+ onKeyDown: handleKeyDown,
1197
+ onKeyUp: handleKeyUp,
1198
+ onFocus: handleFocus,
1199
+ onBlur: handleBlur,
1200
+ "aria-label": computedAriaLabel,
1201
+ "aria-busy": loading || void 0,
1202
+ "aria-disabled": isDisabled || void 0,
1203
+ "aria-describedby": ariaDescribedBy,
1204
+ "aria-expanded": ariaExpanded,
1205
+ "aria-haspopup": ariaHasPopup,
1206
+ "aria-pressed": ariaPressed,
1207
+ "aria-controls": ariaControls,
1208
+ tabIndex,
1209
+ style: buttonStyle,
1210
+ "data-testid": testID || "flex-button",
1211
+ 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: [
1212
+ iconLeft && /* @__PURE__ */ jsx7(Icon, { size: iconSize, color: colors.text, children: iconLeft }),
1213
+ showTextLabel && /* @__PURE__ */ jsx7("span", { children }),
1214
+ hasIconChildren && /* @__PURE__ */ jsx7(Icon, { size: iconSize, color: colors.text, children }),
1215
+ iconRight && /* @__PURE__ */ jsx7(Icon, { size: iconSize, color: colors.text, children: iconRight })
1216
+ ] }) })
1217
+ }
1218
+ );
1219
+ }
1220
+ );
1194
1221
  FlexButton.displayName = "FlexButton";
1195
1222
 
1196
1223
  // src/AppButton.tsx
1197
1224
  import React6, { useState as useState4 } from "react";
1198
- import { useResolvedTheme as useResolvedTheme3 } from "@xsolla/xui-core";
1225
+ import { useResolvedTheme as useResolvedTheme4 } from "@xsolla/xui-core";
1199
1226
  import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
1200
1227
  var cloneIconWithDefaults3 = (icon, defaultSize, defaultColor) => {
1201
1228
  if (!React6.isValidElement(icon)) return icon;
@@ -1232,7 +1259,7 @@ var AppButton = ({
1232
1259
  themeMode,
1233
1260
  themeProductContext
1234
1261
  }) => {
1235
- const { theme } = useResolvedTheme3({ themeMode, themeProductContext });
1262
+ const { theme } = useResolvedTheme4({ themeMode, themeProductContext });
1236
1263
  const [isKeyboardPressed, setIsKeyboardPressed] = useState4(false);
1237
1264
  const isDisabled = disabled || loading;
1238
1265
  const sizeStyles = theme.sizing.button(size);
@@ -1418,7 +1445,7 @@ AppButton.displayName = "AppButton";
1418
1445
 
1419
1446
  // src/ButtonGroup.tsx
1420
1447
  import React7 from "react";
1421
- import { useResolvedTheme as useResolvedTheme4 } from "@xsolla/xui-core";
1448
+ import { useResolvedTheme as useResolvedTheme5 } from "@xsolla/xui-core";
1422
1449
  import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
1423
1450
  var ButtonGroup = ({
1424
1451
  orientation = "horizontal",
@@ -1435,7 +1462,7 @@ var ButtonGroup = ({
1435
1462
  themeMode,
1436
1463
  themeProductContext
1437
1464
  }) => {
1438
- const { theme } = useResolvedTheme4({ themeMode, themeProductContext });
1465
+ const { theme } = useResolvedTheme5({ themeMode, themeProductContext });
1439
1466
  const flattenChildren = (children2) => {
1440
1467
  const result = [];
1441
1468
  React7.Children.forEach(children2, (child) => {
@@ -1550,6 +1577,7 @@ export {
1550
1577
  Button,
1551
1578
  ButtonGroup,
1552
1579
  FlexButton,
1553
- IconButton
1580
+ IconButton,
1581
+ getFlexButtonBoxSize
1554
1582
  };
1555
1583
  //# sourceMappingURL=index.mjs.map