@xsolla/xui-button 0.191.0 → 0.192.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.d.mts +24 -1
- package/native/index.d.ts +24 -1
- package/native/index.js +18 -5
- package/native/index.js.map +1 -1
- package/native/index.mjs +18 -5
- package/native/index.mjs.map +1 -1
- package/package.json +4 -4
- package/web/index.d.mts +24 -1
- package/web/index.d.ts +24 -1
- package/web/index.js +18 -5
- package/web/index.js.map +1 -1
- package/web/index.mjs +18 -5
- package/web/index.mjs.map +1 -1
package/native/index.d.mts
CHANGED
|
@@ -170,7 +170,14 @@ 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
|
-
/**
|
|
173
|
+
/**
|
|
174
|
+
* Button label. Omit for icon-only buttons (provide `aria-label`).
|
|
175
|
+
*
|
|
176
|
+
* An icon may also be passed directly as `children` instead of via
|
|
177
|
+
* `iconLeft`/`iconRight`. When `children` carries no text, the button is
|
|
178
|
+
* treated as icon-only and renders as a square sized from the design-system
|
|
179
|
+
* height token for `size`.
|
|
180
|
+
*/
|
|
174
181
|
children?: ReactNode;
|
|
175
182
|
/** Visual variant of the button */
|
|
176
183
|
variant?: "brand" | "primary" | "secondary" | "tertiary" | "brandExtra" | "inverse";
|
|
@@ -190,6 +197,9 @@ interface FlexButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElem
|
|
|
190
197
|
* The component applies padding via an inline style, which overrides any CSS
|
|
191
198
|
* class or `style` prop a consumer passes, so this prop is the supported way
|
|
192
199
|
* to render a zero-padding FlexButton (e.g. an inline text action).
|
|
200
|
+
*
|
|
201
|
+
* Icon-only buttons keep their square dimensions when `noPadding` is set —
|
|
202
|
+
* only the inner padding is removed.
|
|
193
203
|
* @default false
|
|
194
204
|
*/
|
|
195
205
|
noPadding?: boolean;
|
|
@@ -224,6 +234,19 @@ interface FlexButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElem
|
|
|
224
234
|
*
|
|
225
235
|
* Renders as a semantic `<button>` element with full ARIA support.
|
|
226
236
|
*
|
|
237
|
+
* ## Icon-only buttons
|
|
238
|
+
*
|
|
239
|
+
* A FlexButton is icon-only when it has no text label and an icon is supplied
|
|
240
|
+
* either as `children` or via `iconLeft`/`iconRight`. Icon-only buttons render
|
|
241
|
+
* as a square whose side equals `theme.sizing.flexButton(size).height`, so they
|
|
242
|
+
* line up with the Modal header icon slots (36x36 at `size="xl"`).
|
|
243
|
+
*
|
|
244
|
+
* ```tsx
|
|
245
|
+
* <FlexButton variant="secondary" size="xl" aria-label="Go back">
|
|
246
|
+
* <BackwardAlt variant="line" />
|
|
247
|
+
* </FlexButton>
|
|
248
|
+
* ```
|
|
249
|
+
*
|
|
227
250
|
* ## Accessibility Features
|
|
228
251
|
*
|
|
229
252
|
* - **Semantic HTML**: Renders as a native `<button>` element
|
package/native/index.d.ts
CHANGED
|
@@ -170,7 +170,14 @@ 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
|
-
/**
|
|
173
|
+
/**
|
|
174
|
+
* Button label. Omit for icon-only buttons (provide `aria-label`).
|
|
175
|
+
*
|
|
176
|
+
* An icon may also be passed directly as `children` instead of via
|
|
177
|
+
* `iconLeft`/`iconRight`. When `children` carries no text, the button is
|
|
178
|
+
* treated as icon-only and renders as a square sized from the design-system
|
|
179
|
+
* height token for `size`.
|
|
180
|
+
*/
|
|
174
181
|
children?: ReactNode;
|
|
175
182
|
/** Visual variant of the button */
|
|
176
183
|
variant?: "brand" | "primary" | "secondary" | "tertiary" | "brandExtra" | "inverse";
|
|
@@ -190,6 +197,9 @@ interface FlexButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElem
|
|
|
190
197
|
* The component applies padding via an inline style, which overrides any CSS
|
|
191
198
|
* class or `style` prop a consumer passes, so this prop is the supported way
|
|
192
199
|
* to render a zero-padding FlexButton (e.g. an inline text action).
|
|
200
|
+
*
|
|
201
|
+
* Icon-only buttons keep their square dimensions when `noPadding` is set —
|
|
202
|
+
* only the inner padding is removed.
|
|
193
203
|
* @default false
|
|
194
204
|
*/
|
|
195
205
|
noPadding?: boolean;
|
|
@@ -224,6 +234,19 @@ interface FlexButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElem
|
|
|
224
234
|
*
|
|
225
235
|
* Renders as a semantic `<button>` element with full ARIA support.
|
|
226
236
|
*
|
|
237
|
+
* ## Icon-only buttons
|
|
238
|
+
*
|
|
239
|
+
* A FlexButton is icon-only when it has no text label and an icon is supplied
|
|
240
|
+
* either as `children` or via `iconLeft`/`iconRight`. Icon-only buttons render
|
|
241
|
+
* as a square whose side equals `theme.sizing.flexButton(size).height`, so they
|
|
242
|
+
* line up with the Modal header icon slots (36x36 at `size="xl"`).
|
|
243
|
+
*
|
|
244
|
+
* ```tsx
|
|
245
|
+
* <FlexButton variant="secondary" size="xl" aria-label="Go back">
|
|
246
|
+
* <BackwardAlt variant="line" />
|
|
247
|
+
* </FlexButton>
|
|
248
|
+
* ```
|
|
249
|
+
*
|
|
227
250
|
* ## Accessibility Features
|
|
228
251
|
*
|
|
229
252
|
* - **Semantic HTML**: Renders as a native `<button>` element
|
package/native/index.js
CHANGED
|
@@ -808,15 +808,25 @@ var IconButton = ({
|
|
|
808
808
|
IconButton.displayName = "IconButton";
|
|
809
809
|
|
|
810
810
|
// src/FlexButton.tsx
|
|
811
|
-
var import_react4 = require("react");
|
|
811
|
+
var import_react4 = __toESM(require("react"));
|
|
812
812
|
var import_xui_core3 = require("@xsolla/xui-core");
|
|
813
813
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
814
814
|
var FLEX_BUTTON_PADDING = 4;
|
|
815
815
|
var hasVisibleLabel = (node) => {
|
|
816
|
-
if (node == null || node === false) return false;
|
|
816
|
+
if (node == null || node === false || node === true) return false;
|
|
817
817
|
if (typeof node === "string") return node.trim().length > 0;
|
|
818
818
|
if (typeof node === "number") return true;
|
|
819
819
|
if (Array.isArray(node)) return node.some(hasVisibleLabel);
|
|
820
|
+
if (import_react4.default.isValidElement(node)) {
|
|
821
|
+
const { children: elementChildren } = node.props ?? {};
|
|
822
|
+
return hasVisibleLabel(elementChildren);
|
|
823
|
+
}
|
|
824
|
+
return true;
|
|
825
|
+
};
|
|
826
|
+
var hasRenderableContent = (node) => {
|
|
827
|
+
if (node == null || node === false || node === true) return false;
|
|
828
|
+
if (typeof node === "string") return node.trim().length > 0;
|
|
829
|
+
if (Array.isArray(node)) return node.some(hasRenderableContent);
|
|
820
830
|
return true;
|
|
821
831
|
};
|
|
822
832
|
var ICON_SIZES = {
|
|
@@ -1018,8 +1028,10 @@ var FlexButton = ({
|
|
|
1018
1028
|
const fontSize = FONT_SIZES[size];
|
|
1019
1029
|
const borderRadius = BORDER_RADIUS[size];
|
|
1020
1030
|
const lineHeight = LINE_HEIGHTS[size];
|
|
1021
|
-
const
|
|
1022
|
-
const
|
|
1031
|
+
const showTextLabel = hasVisibleLabel(children);
|
|
1032
|
+
const hasIconChildren = !showTextLabel && hasRenderableContent(children);
|
|
1033
|
+
const isIconOnly = !loading && !showTextLabel && Boolean(iconLeft || iconRight || hasIconChildren);
|
|
1034
|
+
const iconOnlyHitArea = theme.sizing.flexButton(size).height;
|
|
1023
1035
|
const handleMouseEnter = () => {
|
|
1024
1036
|
if (!isDisabled) {
|
|
1025
1037
|
isMouseOverRef.current = true;
|
|
@@ -1159,7 +1171,8 @@ var FlexButton = ({
|
|
|
1159
1171
|
"data-testid": testID || "flex-button",
|
|
1160
1172
|
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: [
|
|
1161
1173
|
iconLeft && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Icon, { size: iconSize, color: colors.text, children: iconLeft }),
|
|
1162
|
-
|
|
1174
|
+
showTextLabel && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children }),
|
|
1175
|
+
hasIconChildren && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Icon, { size: iconSize, color: colors.text, children }),
|
|
1163
1176
|
iconRight && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Icon, { size: iconSize, color: colors.text, children: iconRight })
|
|
1164
1177
|
] }) })
|
|
1165
1178
|
}
|