@xsolla/xui-button 0.189.3 → 0.191.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.d.mts CHANGED
@@ -170,8 +170,8 @@ interface IconButtonProps extends ThemeOverrideProps {
170
170
  declare const IconButton: React.FC<IconButtonProps>;
171
171
 
172
172
  interface FlexButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "type"> {
173
- /** Button content */
174
- children: ReactNode;
173
+ /** Button label. Omit for icon-only buttons (provide `aria-label`). */
174
+ children?: ReactNode;
175
175
  /** Visual variant of the button */
176
176
  variant?: "brand" | "primary" | "secondary" | "tertiary" | "brandExtra" | "inverse";
177
177
  /** Size of the button */
package/web/index.d.ts CHANGED
@@ -170,8 +170,8 @@ interface IconButtonProps extends ThemeOverrideProps {
170
170
  declare const IconButton: React.FC<IconButtonProps>;
171
171
 
172
172
  interface FlexButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "type"> {
173
- /** Button content */
174
- children: ReactNode;
173
+ /** Button label. Omit for icon-only buttons (provide `aria-label`). */
174
+ children?: ReactNode;
175
175
  /** Visual variant of the button */
176
176
  variant?: "brand" | "primary" | "secondary" | "tertiary" | "brandExtra" | "inverse";
177
177
  /** Size of the button */
package/web/index.js CHANGED
@@ -874,6 +874,14 @@ IconButton.displayName = "IconButton";
874
874
  var import_react5 = require("react");
875
875
  var import_xui_core3 = require("@xsolla/xui-core");
876
876
  var import_jsx_runtime7 = require("react/jsx-runtime");
877
+ var FLEX_BUTTON_PADDING = 4;
878
+ var hasVisibleLabel = (node) => {
879
+ if (node == null || node === false) return false;
880
+ if (typeof node === "string") return node.trim().length > 0;
881
+ if (typeof node === "number") return true;
882
+ if (Array.isArray(node)) return node.some(hasVisibleLabel);
883
+ return true;
884
+ };
877
885
  var ICON_SIZES = {
878
886
  xs: 12,
879
887
  sm: 14,
@@ -1073,6 +1081,8 @@ var FlexButton = ({
1073
1081
  const fontSize = FONT_SIZES[size];
1074
1082
  const borderRadius = BORDER_RADIUS[size];
1075
1083
  const lineHeight = LINE_HEIGHTS[size];
1084
+ const isIconOnly = !loading && !hasVisibleLabel(children) && Boolean(iconLeft || iconRight);
1085
+ const iconOnlyHitArea = iconSize + FLEX_BUTTON_PADDING * 2;
1076
1086
  const handleMouseEnter = () => {
1077
1087
  if (!isDisabled) {
1078
1088
  isMouseOverRef.current = true;
@@ -1139,8 +1149,9 @@ var FlexButton = ({
1139
1149
  display: "inline-flex",
1140
1150
  alignItems: "center",
1141
1151
  justifyContent: "center",
1142
- gap: "2px",
1143
- padding: noPadding ? "0px" : "4px",
1152
+ gap: isIconOnly ? 0 : "2px",
1153
+ boxSizing: "border-box",
1154
+ padding: noPadding ? "0px" : `${FLEX_BUTTON_PADDING}px`,
1144
1155
  backgroundColor: loading ? "transparent" : colors.bg,
1145
1156
  color: colors.text,
1146
1157
  border: "none",
@@ -1149,18 +1160,30 @@ var FlexButton = ({
1149
1160
  cursor: isDisabled ? "not-allowed" : "pointer",
1150
1161
  fontSize: `${fontSize}px`,
1151
1162
  fontWeight: 500,
1152
- lineHeight,
1163
+ lineHeight: isIconOnly ? 0 : lineHeight,
1153
1164
  fontFamily: "inherit",
1154
1165
  transition: "background-color 100ms ease-in-out, color 100ms ease-in-out, box-shadow 100ms ease-in-out",
1155
1166
  outline: "none",
1156
1167
  boxShadow: combinedBoxShadow,
1157
- opacity: isDisabled && !loading ? 0.6 : 1
1168
+ opacity: isDisabled && !loading ? 0.6 : 1,
1169
+ ...isIconOnly && {
1170
+ width: iconOnlyHitArea,
1171
+ height: iconOnlyHitArea,
1172
+ minWidth: iconOnlyHitArea,
1173
+ minHeight: iconOnlyHitArea,
1174
+ flexShrink: 0
1175
+ }
1158
1176
  };
1159
1177
  const contentStyle = {
1160
1178
  display: "flex",
1161
1179
  alignItems: "center",
1162
1180
  justifyContent: "center",
1163
- gap: "2px"
1181
+ gap: isIconOnly ? 0 : "2px",
1182
+ ...isIconOnly && {
1183
+ width: "100%",
1184
+ height: "100%",
1185
+ lineHeight: 0
1186
+ }
1164
1187
  };
1165
1188
  const spinnerStyle = {
1166
1189
  display: "flex",
@@ -1199,7 +1222,7 @@ var FlexButton = ({
1199
1222
  "data-testid": testID || "flex-button",
1200
1223
  children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: contentStyle, children: loading ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: spinnerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Spinner, { size: spinnerSize, color: spinnerColor }) }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1201
1224
  iconLeft && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Icon, { size: iconSize, color: colors.text, children: iconLeft }),
1202
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children }),
1225
+ hasVisibleLabel(children) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children }),
1203
1226
  iconRight && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Icon, { size: iconSize, color: colors.text, children: iconRight })
1204
1227
  ] }) })
1205
1228
  }