@xsolla/xui-button 0.112.0 → 0.113.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
@@ -188,6 +188,7 @@ var Text = ({
188
188
  className,
189
189
  id,
190
190
  role,
191
+ numberOfLines: _numberOfLines,
191
192
  ...props
192
193
  }) => {
193
194
  return /* @__PURE__ */ jsx2(
@@ -1004,10 +1005,231 @@ var FlexButton = ({
1004
1005
  };
1005
1006
  FlexButton.displayName = "FlexButton";
1006
1007
 
1007
- // src/ButtonGroup.tsx
1008
- import React5 from "react";
1008
+ // src/AppButton.tsx
1009
+ import React5, { useState as useState4 } from "react";
1009
1010
  import { useDesignSystem as useDesignSystem4 } from "@xsolla/xui-core";
1010
- import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
1011
+ import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
1012
+ var cloneIconWithDefaults3 = (icon, defaultSize, defaultColor) => {
1013
+ if (!React5.isValidElement(icon)) return icon;
1014
+ const iconElement = icon;
1015
+ const existingProps = iconElement.props || {};
1016
+ return React5.cloneElement(iconElement, {
1017
+ ...existingProps,
1018
+ size: existingProps.size ?? defaultSize,
1019
+ color: existingProps.color ?? defaultColor
1020
+ });
1021
+ };
1022
+ var AppButton = ({
1023
+ size = "md",
1024
+ disabled = false,
1025
+ loading = false,
1026
+ children,
1027
+ onPress,
1028
+ iconLeft,
1029
+ iconRight,
1030
+ sublabel,
1031
+ labelAlignment = "center",
1032
+ labelIcon,
1033
+ customContent,
1034
+ "aria-label": ariaLabel,
1035
+ "aria-describedby": ariaDescribedBy,
1036
+ "aria-expanded": ariaExpanded,
1037
+ "aria-haspopup": ariaHasPopup,
1038
+ "aria-pressed": ariaPressed,
1039
+ "aria-controls": ariaControls,
1040
+ testID,
1041
+ id,
1042
+ type = "button",
1043
+ fullWidth = false
1044
+ }) => {
1045
+ const { theme } = useDesignSystem4();
1046
+ const [isKeyboardPressed, setIsKeyboardPressed] = useState4(false);
1047
+ const isDisabled = disabled || loading;
1048
+ const sizeStyles = theme.sizing.button(size);
1049
+ const tokens = theme?.colors?.control?.appButton || {
1050
+ bg: "#34474b",
1051
+ bgHover: "#3d5256",
1052
+ bgPress: "#2b3b3e",
1053
+ border: "rgba(255, 255, 255, 0.12)",
1054
+ borderHover: "rgba(255, 255, 255, 0.18)",
1055
+ borderPress: "rgba(255, 255, 255, 0.12)",
1056
+ text: "#b7c5c8",
1057
+ textDisable: "#b3b3b3"
1058
+ };
1059
+ const handlePress = () => {
1060
+ if (!isDisabled && onPress) {
1061
+ onPress();
1062
+ }
1063
+ };
1064
+ const handleKeyDown = (e) => {
1065
+ if (isDisabled) return;
1066
+ if (e.key === "Enter" || e.key === " ") {
1067
+ e.preventDefault();
1068
+ setIsKeyboardPressed(true);
1069
+ }
1070
+ };
1071
+ const handleKeyUp = (e) => {
1072
+ if (isDisabled) return;
1073
+ if (e.key === "Enter" || e.key === " ") {
1074
+ e.preventDefault();
1075
+ setIsKeyboardPressed(false);
1076
+ if (onPress) {
1077
+ onPress();
1078
+ }
1079
+ }
1080
+ };
1081
+ let backgroundColor = tokens.bg;
1082
+ if (disabled) {
1083
+ backgroundColor = tokens.bg;
1084
+ } else if (isKeyboardPressed) {
1085
+ backgroundColor = tokens.bgPress;
1086
+ }
1087
+ const borderColor = tokens.border;
1088
+ const textColor = disabled ? tokens.textDisable : tokens.text;
1089
+ return /* @__PURE__ */ jsxs4(
1090
+ Box,
1091
+ {
1092
+ as: "button",
1093
+ type,
1094
+ id,
1095
+ onPress: handlePress,
1096
+ onKeyDown: handleKeyDown,
1097
+ onKeyUp: handleKeyUp,
1098
+ disabled: isDisabled,
1099
+ "aria-label": ariaLabel,
1100
+ "aria-disabled": isDisabled || void 0,
1101
+ "aria-busy": loading || void 0,
1102
+ "aria-describedby": ariaDescribedBy,
1103
+ "aria-expanded": ariaExpanded,
1104
+ "aria-haspopup": ariaHasPopup,
1105
+ "aria-pressed": ariaPressed,
1106
+ "aria-controls": ariaControls,
1107
+ testID,
1108
+ backgroundColor,
1109
+ borderColor,
1110
+ borderWidth: borderColor !== "transparent" && borderColor !== "rgba(255, 255, 255, 0)" && borderColor !== "rgba(0, 0, 0, 0)" && !borderColor.endsWith(", 0)") ? 1 : 0,
1111
+ borderRadius: sizeStyles.borderRadius,
1112
+ height: sizeStyles.height,
1113
+ width: fullWidth ? "100%" : void 0,
1114
+ padding: 0,
1115
+ flexDirection: "row",
1116
+ alignItems: "center",
1117
+ justifyContent: "center",
1118
+ position: "relative",
1119
+ cursor: disabled ? "not-allowed" : loading ? "wait" : "pointer",
1120
+ opacity: disabled ? 0.6 : 1,
1121
+ hoverStyle: !isDisabled ? {
1122
+ backgroundColor: tokens.bgHover,
1123
+ borderColor: tokens.borderHover
1124
+ } : void 0,
1125
+ pressStyle: !isDisabled ? {
1126
+ backgroundColor: tokens.bgPress,
1127
+ borderColor: tokens.borderPress
1128
+ } : void 0,
1129
+ focusStyle: {
1130
+ outlineColor: theme.colors.border.brand,
1131
+ outlineWidth: 2,
1132
+ outlineOffset: 2,
1133
+ outlineStyle: "solid"
1134
+ },
1135
+ children: [
1136
+ loading && /* @__PURE__ */ jsx8(
1137
+ Box,
1138
+ {
1139
+ position: "absolute",
1140
+ top: 0,
1141
+ left: 0,
1142
+ right: 0,
1143
+ bottom: 0,
1144
+ alignItems: "center",
1145
+ justifyContent: "center",
1146
+ zIndex: 1,
1147
+ children: /* @__PURE__ */ jsx8(
1148
+ Spinner,
1149
+ {
1150
+ color: textColor,
1151
+ size: sizeStyles.spinnerSize,
1152
+ "aria-hidden": true
1153
+ }
1154
+ )
1155
+ }
1156
+ ),
1157
+ iconLeft && /* @__PURE__ */ jsx8(
1158
+ Box,
1159
+ {
1160
+ width: sizeStyles.iconContainerSize,
1161
+ height: sizeStyles.iconContainerSize,
1162
+ alignItems: "center",
1163
+ justifyContent: "center",
1164
+ "aria-hidden": true,
1165
+ style: {
1166
+ opacity: loading ? 0 : 1,
1167
+ pointerEvents: loading ? "none" : "auto"
1168
+ },
1169
+ children: cloneIconWithDefaults3(iconLeft, sizeStyles.iconSize, textColor)
1170
+ }
1171
+ ),
1172
+ /* @__PURE__ */ jsxs4(
1173
+ Box,
1174
+ {
1175
+ flex: fullWidth ? 1 : void 0,
1176
+ flexDirection: "row",
1177
+ alignItems: "center",
1178
+ justifyContent: labelAlignment === "left" ? "flex-start" : "center",
1179
+ paddingHorizontal: sizeStyles.padding,
1180
+ height: "100%",
1181
+ gap: sizeStyles.labelIconGap,
1182
+ style: {
1183
+ opacity: loading ? 0 : 1,
1184
+ pointerEvents: loading ? "none" : "auto"
1185
+ },
1186
+ "aria-hidden": loading ? true : void 0,
1187
+ children: [
1188
+ labelIcon && /* @__PURE__ */ jsx8(Box, { "aria-hidden": true, children: cloneIconWithDefaults3(
1189
+ labelIcon,
1190
+ sizeStyles.labelIconSize,
1191
+ textColor
1192
+ ) }),
1193
+ /* @__PURE__ */ jsx8(Text, { color: textColor, fontSize: sizeStyles.fontSize, fontWeight: "500", children }),
1194
+ sublabel && /* @__PURE__ */ jsx8(
1195
+ Text,
1196
+ {
1197
+ color: textColor,
1198
+ fontSize: sizeStyles.fontSize,
1199
+ fontWeight: "500",
1200
+ style: { opacity: 0.4 },
1201
+ children: sublabel
1202
+ }
1203
+ ),
1204
+ customContent && /* @__PURE__ */ jsx8(Box, { "aria-hidden": true, children: customContent })
1205
+ ]
1206
+ }
1207
+ ),
1208
+ iconRight && /* @__PURE__ */ jsx8(
1209
+ Box,
1210
+ {
1211
+ width: sizeStyles.iconContainerSize,
1212
+ height: sizeStyles.iconContainerSize,
1213
+ alignItems: "center",
1214
+ justifyContent: "center",
1215
+ "aria-hidden": true,
1216
+ style: {
1217
+ opacity: loading ? 0 : 1,
1218
+ pointerEvents: loading ? "none" : "auto"
1219
+ },
1220
+ children: cloneIconWithDefaults3(iconRight, sizeStyles.iconSize, textColor)
1221
+ }
1222
+ )
1223
+ ]
1224
+ }
1225
+ );
1226
+ };
1227
+ AppButton.displayName = "AppButton";
1228
+
1229
+ // src/ButtonGroup.tsx
1230
+ import React6 from "react";
1231
+ import { useDesignSystem as useDesignSystem5 } from "@xsolla/xui-core";
1232
+ import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
1011
1233
  var ButtonGroup = ({
1012
1234
  orientation = "horizontal",
1013
1235
  size = "md",
@@ -1021,11 +1243,11 @@ var ButtonGroup = ({
1021
1243
  id,
1022
1244
  testID
1023
1245
  }) => {
1024
- const { theme } = useDesignSystem4();
1246
+ const { theme } = useDesignSystem5();
1025
1247
  const flattenChildren = (children2) => {
1026
1248
  const result = [];
1027
- React5.Children.forEach(children2, (child) => {
1028
- if (React5.isValidElement(child) && child.type === React5.Fragment) {
1249
+ React6.Children.forEach(children2, (child) => {
1250
+ if (React6.isValidElement(child) && child.type === React6.Fragment) {
1029
1251
  result.push(...flattenChildren(child.props.children));
1030
1252
  } else if (child !== null && child !== void 0) {
1031
1253
  result.push(child);
@@ -1061,8 +1283,8 @@ var ButtonGroup = ({
1061
1283
  const processChildren = (childrenToProcess) => {
1062
1284
  if (orientation === "vertical") {
1063
1285
  return childrenToProcess.map((child, index) => {
1064
- if (React5.isValidElement(child)) {
1065
- return React5.cloneElement(child, {
1286
+ if (React6.isValidElement(child)) {
1287
+ return React6.cloneElement(child, {
1066
1288
  ...child.props,
1067
1289
  fullWidth: true,
1068
1290
  key: child.key ?? index
@@ -1078,9 +1300,9 @@ var ButtonGroup = ({
1078
1300
  if (useSpaceBetween) {
1079
1301
  const firstChild = processedChildren[0];
1080
1302
  const restChildren = processedChildren.slice(1);
1081
- return /* @__PURE__ */ jsxs4(Fragment2, { children: [
1303
+ return /* @__PURE__ */ jsxs5(Fragment2, { children: [
1082
1304
  firstChild,
1083
- /* @__PURE__ */ jsx8(Box, { flexDirection: "row", gap: computedGap, children: restChildren })
1305
+ /* @__PURE__ */ jsx9(Box, { flexDirection: "row", gap: computedGap, children: restChildren })
1084
1306
  ] });
1085
1307
  }
1086
1308
  if (orientation === "vertical") {
@@ -1088,8 +1310,8 @@ var ButtonGroup = ({
1088
1310
  }
1089
1311
  return children;
1090
1312
  };
1091
- return /* @__PURE__ */ jsxs4(Box, { flexDirection: "column", width: "100%", gap: 8, children: [
1092
- /* @__PURE__ */ jsx8(
1313
+ return /* @__PURE__ */ jsxs5(Box, { flexDirection: "column", width: "100%", gap: 8, children: [
1314
+ /* @__PURE__ */ jsx9(
1093
1315
  Box,
1094
1316
  {
1095
1317
  role: "group",
@@ -1106,7 +1328,7 @@ var ButtonGroup = ({
1106
1328
  children: renderChildren()
1107
1329
  }
1108
1330
  ),
1109
- error && /* @__PURE__ */ jsx8(Box, { marginTop: 4, children: /* @__PURE__ */ jsx8(
1331
+ error && /* @__PURE__ */ jsx9(Box, { marginTop: 4, children: /* @__PURE__ */ jsx9(
1110
1332
  Text,
1111
1333
  {
1112
1334
  id: errorId,
@@ -1119,7 +1341,7 @@ var ButtonGroup = ({
1119
1341
  children: error
1120
1342
  }
1121
1343
  ) }),
1122
- description && /* @__PURE__ */ jsx8(Box, { marginTop: 4, children: /* @__PURE__ */ jsx8(
1344
+ description && /* @__PURE__ */ jsx9(Box, { marginTop: 4, children: /* @__PURE__ */ jsx9(
1123
1345
  Text,
1124
1346
  {
1125
1347
  id: descriptionId,
@@ -1134,6 +1356,7 @@ var ButtonGroup = ({
1134
1356
  };
1135
1357
  ButtonGroup.displayName = "ButtonGroup";
1136
1358
  export {
1359
+ AppButton,
1137
1360
  Button,
1138
1361
  ButtonGroup,
1139
1362
  FlexButton,