@windrun-huaiin/third-ui 11.0.5 → 11.0.6
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/dist/fuma/mdx/gradient-button.d.ts +2 -1
- package/dist/fuma/mdx/gradient-button.js +7 -4
- package/dist/fuma/mdx/gradient-button.mjs +7 -4
- package/dist/main/x-button.d.ts +2 -0
- package/dist/main/x-button.js +10 -2
- package/dist/main/x-button.mjs +10 -2
- package/package.json +1 -1
- package/src/fuma/mdx/gradient-button.tsx +9 -3
- package/src/main/x-button.tsx +16 -3
|
@@ -5,10 +5,11 @@ export interface GradientButtonProps {
|
|
|
5
5
|
align?: 'left' | 'center' | 'right';
|
|
6
6
|
disabled?: boolean;
|
|
7
7
|
className?: string;
|
|
8
|
+
iconSizeValue?: number;
|
|
8
9
|
href?: string;
|
|
9
10
|
openInNewTab?: boolean;
|
|
10
11
|
onClick?: () => void | Promise<void>;
|
|
11
12
|
loadingText?: React.ReactNode;
|
|
12
13
|
preventDoubleClick?: boolean;
|
|
13
14
|
}
|
|
14
|
-
export declare function GradientButton({ title, icon, align, disabled, className, href, openInNewTab, onClick, loadingText, preventDoubleClick, }: GradientButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export declare function GradientButton({ title, icon, align, disabled, className, href, openInNewTab, onClick, loadingText, preventDoubleClick, iconSizeValue, }: GradientButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -9,9 +9,12 @@ var server = require('@windrun-huaiin/base-ui/components/server');
|
|
|
9
9
|
var Link = require('next/link');
|
|
10
10
|
var React = require('react');
|
|
11
11
|
|
|
12
|
-
function GradientButton({ title, icon, align = 'left', disabled = false, className = "", href, openInNewTab = true, onClick, loadingText, preventDoubleClick = true, }) {
|
|
12
|
+
function GradientButton({ title, icon, align = 'left', disabled = false, className = "", href, openInNewTab = true, onClick, loadingText, preventDoubleClick = true, iconSizeValue, }) {
|
|
13
13
|
const [isLoading, setIsLoading] = React.useState(false);
|
|
14
14
|
const actualLoadingText = loadingText || (title === null || title === void 0 ? void 0 : title.toString().trim()) || 'Loading...';
|
|
15
|
+
const iconSizeClass = (iconSizeValue && Number.isInteger(iconSizeValue) && iconSizeValue > 0)
|
|
16
|
+
? `h-${iconSizeValue} w-${iconSizeValue}`
|
|
17
|
+
: 'h-4 w-4';
|
|
15
18
|
// set justify class according to alignment
|
|
16
19
|
const getAlignmentClass = () => {
|
|
17
20
|
switch (align) {
|
|
@@ -52,7 +55,7 @@ function GradientButton({ title, icon, align = 'left', disabled = false, classNa
|
|
|
52
55
|
const iconProvided = icon !== undefined;
|
|
53
56
|
const iconNode = (() => {
|
|
54
57
|
if (isLoading) {
|
|
55
|
-
return jsxRuntime.jsx(server.globalLucideIcons.Loader2, { className:
|
|
58
|
+
return jsxRuntime.jsx(server.globalLucideIcons.Loader2, { className: utils.cn(iconSizeClass, 'text-white animate-spin') });
|
|
56
59
|
}
|
|
57
60
|
if (iconProvided) {
|
|
58
61
|
if (icon === null || icon === false) {
|
|
@@ -60,12 +63,12 @@ function GradientButton({ title, icon, align = 'left', disabled = false, classNa
|
|
|
60
63
|
}
|
|
61
64
|
if (React.isValidElement(icon)) {
|
|
62
65
|
return React.cloneElement(icon, {
|
|
63
|
-
className: utils.cn('
|
|
66
|
+
className: utils.cn(iconSizeClass, 'text-white', icon.props.className),
|
|
64
67
|
});
|
|
65
68
|
}
|
|
66
69
|
return icon;
|
|
67
70
|
}
|
|
68
|
-
return jsxRuntime.jsx(server.globalLucideIcons.ArrowRight, { className:
|
|
71
|
+
return jsxRuntime.jsx(server.globalLucideIcons.ArrowRight, { className: utils.cn(iconSizeClass, 'text-white') });
|
|
69
72
|
})();
|
|
70
73
|
const shouldRenderIcon = iconNode !== null && iconNode !== undefined;
|
|
71
74
|
const buttonContent = onClick ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [shouldRenderIcon ? jsxRuntime.jsx("span", { children: iconNode }) : null, jsxRuntime.jsx("span", { className: utils.cn(shouldRenderIcon && 'ml-1'), children: displayTitle })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { children: displayTitle }), shouldRenderIcon ? jsxRuntime.jsx("span", { className: "ml-1", children: iconNode }) : null] }));
|
|
@@ -7,9 +7,12 @@ import { globalLucideIcons } from '@windrun-huaiin/base-ui/components/server';
|
|
|
7
7
|
import Link from 'next/link';
|
|
8
8
|
import React, { useState } from 'react';
|
|
9
9
|
|
|
10
|
-
function GradientButton({ title, icon, align = 'left', disabled = false, className = "", href, openInNewTab = true, onClick, loadingText, preventDoubleClick = true, }) {
|
|
10
|
+
function GradientButton({ title, icon, align = 'left', disabled = false, className = "", href, openInNewTab = true, onClick, loadingText, preventDoubleClick = true, iconSizeValue, }) {
|
|
11
11
|
const [isLoading, setIsLoading] = useState(false);
|
|
12
12
|
const actualLoadingText = loadingText || (title === null || title === void 0 ? void 0 : title.toString().trim()) || 'Loading...';
|
|
13
|
+
const iconSizeClass = (iconSizeValue && Number.isInteger(iconSizeValue) && iconSizeValue > 0)
|
|
14
|
+
? `h-${iconSizeValue} w-${iconSizeValue}`
|
|
15
|
+
: 'h-4 w-4';
|
|
13
16
|
// set justify class according to alignment
|
|
14
17
|
const getAlignmentClass = () => {
|
|
15
18
|
switch (align) {
|
|
@@ -50,7 +53,7 @@ function GradientButton({ title, icon, align = 'left', disabled = false, classNa
|
|
|
50
53
|
const iconProvided = icon !== undefined;
|
|
51
54
|
const iconNode = (() => {
|
|
52
55
|
if (isLoading) {
|
|
53
|
-
return jsx(globalLucideIcons.Loader2, { className:
|
|
56
|
+
return jsx(globalLucideIcons.Loader2, { className: cn(iconSizeClass, 'text-white animate-spin') });
|
|
54
57
|
}
|
|
55
58
|
if (iconProvided) {
|
|
56
59
|
if (icon === null || icon === false) {
|
|
@@ -58,12 +61,12 @@ function GradientButton({ title, icon, align = 'left', disabled = false, classNa
|
|
|
58
61
|
}
|
|
59
62
|
if (React.isValidElement(icon)) {
|
|
60
63
|
return React.cloneElement(icon, {
|
|
61
|
-
className: cn('
|
|
64
|
+
className: cn(iconSizeClass, 'text-white', icon.props.className),
|
|
62
65
|
});
|
|
63
66
|
}
|
|
64
67
|
return icon;
|
|
65
68
|
}
|
|
66
|
-
return jsx(globalLucideIcons.ArrowRight, { className:
|
|
69
|
+
return jsx(globalLucideIcons.ArrowRight, { className: cn(iconSizeClass, 'text-white') });
|
|
67
70
|
})();
|
|
68
71
|
const shouldRenderIcon = iconNode !== null && iconNode !== undefined;
|
|
69
72
|
const buttonContent = onClick ? (jsxs(Fragment, { children: [shouldRenderIcon ? jsx("span", { children: iconNode }) : null, jsx("span", { className: cn(shouldRenderIcon && 'ml-1'), children: displayTitle })] })) : (jsxs(Fragment, { children: [jsx("span", { children: displayTitle }), shouldRenderIcon ? jsx("span", { className: "ml-1", children: iconNode }) : null] }));
|
package/dist/main/x-button.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ interface SingleButtonProps {
|
|
|
18
18
|
loadingText?: string;
|
|
19
19
|
minWidth?: string;
|
|
20
20
|
className?: string;
|
|
21
|
+
iconSizeValue?: number;
|
|
21
22
|
}
|
|
22
23
|
interface SplitButtonProps {
|
|
23
24
|
type: 'split';
|
|
@@ -28,6 +29,7 @@ interface SplitButtonProps {
|
|
|
28
29
|
className?: string;
|
|
29
30
|
mainButtonClassName?: string;
|
|
30
31
|
dropdownButtonClassName?: string;
|
|
32
|
+
iconSizeValue?: number;
|
|
31
33
|
}
|
|
32
34
|
type xButtonProps = SingleButtonProps | SplitButtonProps;
|
|
33
35
|
export declare function XButton(props: xButtonProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/main/x-button.js
CHANGED
|
@@ -12,6 +12,14 @@ function XButton(props) {
|
|
|
12
12
|
const [isLoading, setIsLoading] = React.useState(false);
|
|
13
13
|
const [menuOpen, setMenuOpen] = React.useState(false);
|
|
14
14
|
const menuRef = React.useRef(null);
|
|
15
|
+
const { iconSizeValue } = props;
|
|
16
|
+
const isCustomSize = iconSizeValue && Number.isInteger(iconSizeValue) && iconSizeValue > 0;
|
|
17
|
+
const loadingIconClass = isCustomSize
|
|
18
|
+
? `w-${iconSizeValue} h-${iconSizeValue} mr-1 animate-spin`
|
|
19
|
+
: "w-5 h-5 mr-1 animate-spin";
|
|
20
|
+
const chevronIconClass = isCustomSize
|
|
21
|
+
? `w-${iconSizeValue + 1} h-${iconSizeValue + 1}`
|
|
22
|
+
: "w-6 h-6";
|
|
15
23
|
// click outside to close menu
|
|
16
24
|
React.useEffect(() => {
|
|
17
25
|
if (props.type === 'split') {
|
|
@@ -51,7 +59,7 @@ function XButton(props) {
|
|
|
51
59
|
const isDisabled = button.disabled || isLoading;
|
|
52
60
|
// loadingText: props.loadingText > button.text > 'Loading...'
|
|
53
61
|
const actualLoadingText = loadingText || ((_a = button.text) === null || _a === void 0 ? void 0 : _a.trim()) || 'Loading...';
|
|
54
|
-
return (jsxRuntime.jsx("button", { onClick: () => handleButtonClick(button.onClick), disabled: isDisabled, className: utils.cn("w-full sm:w-auto", minWidth, baseButtonClass, "rounded-full", isDisabled && disabledClass, className), title: button.text, children: isLoading ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(server.globalLucideIcons.Loader2, { className:
|
|
62
|
+
return (jsxRuntime.jsx("button", { onClick: () => handleButtonClick(button.onClick), disabled: isDisabled, className: utils.cn("w-full sm:w-auto", minWidth, baseButtonClass, "rounded-full", isDisabled && disabledClass, className), title: button.text, children: isLoading ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(server.globalLucideIcons.Loader2, { className: loadingIconClass }), jsxRuntime.jsx("span", { children: actualLoadingText })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [button.icon, jsxRuntime.jsx("span", { children: button.text })] })) }));
|
|
55
63
|
}
|
|
56
64
|
// Split button
|
|
57
65
|
const { mainButton, menuItems, loadingText, menuWidth = 'w-full sm:w-40', className = '', mainButtonClassName = '', dropdownButtonClassName = '' } = props;
|
|
@@ -59,7 +67,7 @@ function XButton(props) {
|
|
|
59
67
|
// loadingText prioty:props.loadingText > mainButton.text > 'Loading...'
|
|
60
68
|
const actualLoadingText = loadingText || ((_b = mainButton.text) === null || _b === void 0 ? void 0 : _b.trim()) || 'Loading...';
|
|
61
69
|
return (jsxRuntime.jsxs("div", { className: utils.cn("relative flex flex-col sm:flex-row items-stretch w-full sm:w-auto bg-neutral-200 dark:bg-neutral-800 rounded-full gap-2 sm:gap-0", className), children: [jsxRuntime.jsx("button", { onClick: () => handleButtonClick(mainButton.onClick), disabled: isMainDisabled, className: utils.cn("flex-1 w-full", baseButtonClass, "rounded-full sm:rounded-l-full sm:rounded-r-none", isMainDisabled && disabledClass, mainButtonClassName), onMouseDown: e => { if (e.button === 2)
|
|
62
|
-
e.preventDefault(); }, children: isLoading ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(server.globalLucideIcons.Loader2, { className:
|
|
70
|
+
e.preventDefault(); }, children: isLoading ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(server.globalLucideIcons.Loader2, { className: loadingIconClass }), jsxRuntime.jsx("span", { children: actualLoadingText })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [mainButton.icon, jsxRuntime.jsx("span", { children: mainButton.text })] })) }), jsxRuntime.jsx("button", { type: "button", className: utils.cn("flex items-center justify-center w-full sm:w-10 py-1.5 bg-neutral-200 dark:bg-neutral-800 text-neutral-700 dark:text-white cursor-pointer transition hover:bg-neutral-300 dark:hover:bg-neutral-700 rounded-full sm:rounded-none sm:rounded-r-full sm:border-l sm:border-neutral-300 sm:dark:border-neutral-700", dropdownButtonClassName), onClick: e => { e.stopPropagation(); setMenuOpen(v => !v); }, "aria-label": "More actions", "aria-expanded": menuOpen, children: jsxRuntime.jsx(server.globalLucideIcons.ChevronDown, { className: chevronIconClass }) }), menuOpen && (jsxRuntime.jsx("div", { ref: menuRef, className: `absolute right-0 top-full ${menuWidth} bg-white dark:bg-neutral-800 text-neutral-800 dark:text-white text-sm rounded-xl shadow-lg z-50 border border-neutral-200 dark:border-neutral-700 overflow-hidden animate-fade-in`, children: menuItems.map((item, index) => (jsxRuntime.jsxs("button", { onClick: () => {
|
|
63
71
|
handleButtonClick(item.onClick);
|
|
64
72
|
setMenuOpen(false);
|
|
65
73
|
}, disabled: item.disabled, className: `flex items-center w-full px-4 py-3 transition hover:bg-neutral-300 dark:hover:bg-neutral-600 text-left relative ${item.disabled ? disabledClass : ''}`, style: item.splitTopBorder ? { borderTop: '1px solid #AC62FD' } : undefined, children: [jsxRuntime.jsxs("span", { className: "flex items-center", children: [item.icon, jsxRuntime.jsx("span", { children: item.text })] }), item.tag && (jsxRuntime.jsx("span", { className: "absolute right-3 top-1 text-[10px] font-semibold", style: { color: item.tag.color || '#A855F7', pointerEvents: 'none' }, children: item.tag.text }))] }, index))) }))] }));
|
package/dist/main/x-button.mjs
CHANGED
|
@@ -10,6 +10,14 @@ function XButton(props) {
|
|
|
10
10
|
const [isLoading, setIsLoading] = useState(false);
|
|
11
11
|
const [menuOpen, setMenuOpen] = useState(false);
|
|
12
12
|
const menuRef = useRef(null);
|
|
13
|
+
const { iconSizeValue } = props;
|
|
14
|
+
const isCustomSize = iconSizeValue && Number.isInteger(iconSizeValue) && iconSizeValue > 0;
|
|
15
|
+
const loadingIconClass = isCustomSize
|
|
16
|
+
? `w-${iconSizeValue} h-${iconSizeValue} mr-1 animate-spin`
|
|
17
|
+
: "w-5 h-5 mr-1 animate-spin";
|
|
18
|
+
const chevronIconClass = isCustomSize
|
|
19
|
+
? `w-${iconSizeValue + 1} h-${iconSizeValue + 1}`
|
|
20
|
+
: "w-6 h-6";
|
|
13
21
|
// click outside to close menu
|
|
14
22
|
useEffect(() => {
|
|
15
23
|
if (props.type === 'split') {
|
|
@@ -49,7 +57,7 @@ function XButton(props) {
|
|
|
49
57
|
const isDisabled = button.disabled || isLoading;
|
|
50
58
|
// loadingText: props.loadingText > button.text > 'Loading...'
|
|
51
59
|
const actualLoadingText = loadingText || ((_a = button.text) === null || _a === void 0 ? void 0 : _a.trim()) || 'Loading...';
|
|
52
|
-
return (jsx("button", { onClick: () => handleButtonClick(button.onClick), disabled: isDisabled, className: cn("w-full sm:w-auto", minWidth, baseButtonClass, "rounded-full", isDisabled && disabledClass, className), title: button.text, children: isLoading ? (jsxs(Fragment, { children: [jsx(globalLucideIcons.Loader2, { className:
|
|
60
|
+
return (jsx("button", { onClick: () => handleButtonClick(button.onClick), disabled: isDisabled, className: cn("w-full sm:w-auto", minWidth, baseButtonClass, "rounded-full", isDisabled && disabledClass, className), title: button.text, children: isLoading ? (jsxs(Fragment, { children: [jsx(globalLucideIcons.Loader2, { className: loadingIconClass }), jsx("span", { children: actualLoadingText })] })) : (jsxs(Fragment, { children: [button.icon, jsx("span", { children: button.text })] })) }));
|
|
53
61
|
}
|
|
54
62
|
// Split button
|
|
55
63
|
const { mainButton, menuItems, loadingText, menuWidth = 'w-full sm:w-40', className = '', mainButtonClassName = '', dropdownButtonClassName = '' } = props;
|
|
@@ -57,7 +65,7 @@ function XButton(props) {
|
|
|
57
65
|
// loadingText prioty:props.loadingText > mainButton.text > 'Loading...'
|
|
58
66
|
const actualLoadingText = loadingText || ((_b = mainButton.text) === null || _b === void 0 ? void 0 : _b.trim()) || 'Loading...';
|
|
59
67
|
return (jsxs("div", { className: cn("relative flex flex-col sm:flex-row items-stretch w-full sm:w-auto bg-neutral-200 dark:bg-neutral-800 rounded-full gap-2 sm:gap-0", className), children: [jsx("button", { onClick: () => handleButtonClick(mainButton.onClick), disabled: isMainDisabled, className: cn("flex-1 w-full", baseButtonClass, "rounded-full sm:rounded-l-full sm:rounded-r-none", isMainDisabled && disabledClass, mainButtonClassName), onMouseDown: e => { if (e.button === 2)
|
|
60
|
-
e.preventDefault(); }, children: isLoading ? (jsxs(Fragment, { children: [jsx(globalLucideIcons.Loader2, { className:
|
|
68
|
+
e.preventDefault(); }, children: isLoading ? (jsxs(Fragment, { children: [jsx(globalLucideIcons.Loader2, { className: loadingIconClass }), jsx("span", { children: actualLoadingText })] })) : (jsxs(Fragment, { children: [mainButton.icon, jsx("span", { children: mainButton.text })] })) }), jsx("button", { type: "button", className: cn("flex items-center justify-center w-full sm:w-10 py-1.5 bg-neutral-200 dark:bg-neutral-800 text-neutral-700 dark:text-white cursor-pointer transition hover:bg-neutral-300 dark:hover:bg-neutral-700 rounded-full sm:rounded-none sm:rounded-r-full sm:border-l sm:border-neutral-300 sm:dark:border-neutral-700", dropdownButtonClassName), onClick: e => { e.stopPropagation(); setMenuOpen(v => !v); }, "aria-label": "More actions", "aria-expanded": menuOpen, children: jsx(globalLucideIcons.ChevronDown, { className: chevronIconClass }) }), menuOpen && (jsx("div", { ref: menuRef, className: `absolute right-0 top-full ${menuWidth} bg-white dark:bg-neutral-800 text-neutral-800 dark:text-white text-sm rounded-xl shadow-lg z-50 border border-neutral-200 dark:border-neutral-700 overflow-hidden animate-fade-in`, children: menuItems.map((item, index) => (jsxs("button", { onClick: () => {
|
|
61
69
|
handleButtonClick(item.onClick);
|
|
62
70
|
setMenuOpen(false);
|
|
63
71
|
}, disabled: item.disabled, className: `flex items-center w-full px-4 py-3 transition hover:bg-neutral-300 dark:hover:bg-neutral-600 text-left relative ${item.disabled ? disabledClass : ''}`, style: item.splitTopBorder ? { borderTop: '1px solid #AC62FD' } : undefined, children: [jsxs("span", { className: "flex items-center", children: [item.icon, jsx("span", { children: item.text })] }), item.tag && (jsx("span", { className: "absolute right-3 top-1 text-[10px] font-semibold", style: { color: item.tag.color || '#A855F7', pointerEvents: 'none' }, children: item.tag.text }))] }, index))) }))] }));
|
package/package.json
CHANGED
|
@@ -12,6 +12,7 @@ export interface GradientButtonProps {
|
|
|
12
12
|
align?: 'left' | 'center' | 'right';
|
|
13
13
|
disabled?: boolean;
|
|
14
14
|
className?: string;
|
|
15
|
+
iconSizeValue?: number;
|
|
15
16
|
// for Link
|
|
16
17
|
href?: string;
|
|
17
18
|
openInNewTab?: boolean;
|
|
@@ -33,10 +34,15 @@ export function GradientButton({
|
|
|
33
34
|
onClick,
|
|
34
35
|
loadingText,
|
|
35
36
|
preventDoubleClick = true,
|
|
37
|
+
iconSizeValue,
|
|
36
38
|
}: GradientButtonProps) {
|
|
37
39
|
const [isLoading, setIsLoading] = useState(false);
|
|
38
40
|
const actualLoadingText = loadingText || title?.toString().trim() || 'Loading...'
|
|
39
41
|
|
|
42
|
+
const iconSizeClass = (iconSizeValue && Number.isInteger(iconSizeValue) && iconSizeValue > 0)
|
|
43
|
+
? `h-${iconSizeValue} w-${iconSizeValue}`
|
|
44
|
+
: 'h-4 w-4';
|
|
45
|
+
|
|
40
46
|
// set justify class according to alignment
|
|
41
47
|
const getAlignmentClass = () => {
|
|
42
48
|
switch (align) {
|
|
@@ -83,7 +89,7 @@ export function GradientButton({
|
|
|
83
89
|
|
|
84
90
|
const iconNode = (() => {
|
|
85
91
|
if (isLoading) {
|
|
86
|
-
return <icons.Loader2 className=
|
|
92
|
+
return <icons.Loader2 className={cn(iconSizeClass, 'text-white animate-spin')} />;
|
|
87
93
|
}
|
|
88
94
|
|
|
89
95
|
if (iconProvided) {
|
|
@@ -93,14 +99,14 @@ export function GradientButton({
|
|
|
93
99
|
|
|
94
100
|
if (React.isValidElement<{ className?: string }>(icon)) {
|
|
95
101
|
return React.cloneElement(icon, {
|
|
96
|
-
className: cn('
|
|
102
|
+
className: cn(iconSizeClass, 'text-white', icon.props.className),
|
|
97
103
|
});
|
|
98
104
|
}
|
|
99
105
|
|
|
100
106
|
return icon;
|
|
101
107
|
}
|
|
102
108
|
|
|
103
|
-
return <icons.ArrowRight className=
|
|
109
|
+
return <icons.ArrowRight className={cn(iconSizeClass, 'text-white')} />;
|
|
104
110
|
})();
|
|
105
111
|
|
|
106
112
|
const shouldRenderIcon = iconNode !== null && iconNode !== undefined;
|
package/src/main/x-button.tsx
CHANGED
|
@@ -28,6 +28,7 @@ interface SingleButtonProps {
|
|
|
28
28
|
loadingText?: string
|
|
29
29
|
minWidth?: string
|
|
30
30
|
className?: string
|
|
31
|
+
iconSizeValue?: number
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
// split button config
|
|
@@ -40,6 +41,7 @@ interface SplitButtonProps {
|
|
|
40
41
|
className?: string
|
|
41
42
|
mainButtonClassName?: string
|
|
42
43
|
dropdownButtonClassName?: string
|
|
44
|
+
iconSizeValue?: number
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
type xButtonProps = SingleButtonProps | SplitButtonProps
|
|
@@ -49,6 +51,17 @@ export function XButton(props: xButtonProps) {
|
|
|
49
51
|
const [menuOpen, setMenuOpen] = useState(false)
|
|
50
52
|
const menuRef = useRef<HTMLDivElement>(null)
|
|
51
53
|
|
|
54
|
+
const { iconSizeValue } = props
|
|
55
|
+
const isCustomSize = iconSizeValue && Number.isInteger(iconSizeValue) && iconSizeValue > 0
|
|
56
|
+
|
|
57
|
+
const loadingIconClass = isCustomSize
|
|
58
|
+
? `w-${iconSizeValue} h-${iconSizeValue} mr-1 animate-spin`
|
|
59
|
+
: "w-5 h-5 mr-1 animate-spin"
|
|
60
|
+
|
|
61
|
+
const chevronIconClass = isCustomSize
|
|
62
|
+
? `w-${iconSizeValue + 1} h-${iconSizeValue + 1}`
|
|
63
|
+
: "w-6 h-6"
|
|
64
|
+
|
|
52
65
|
// click outside to close menu
|
|
53
66
|
useEffect(() => {
|
|
54
67
|
if (props.type === 'split') {
|
|
@@ -108,7 +121,7 @@ export function XButton(props: xButtonProps) {
|
|
|
108
121
|
>
|
|
109
122
|
{isLoading ? (
|
|
110
123
|
<>
|
|
111
|
-
<icons.Loader2 className=
|
|
124
|
+
<icons.Loader2 className={loadingIconClass} />
|
|
112
125
|
<span>{actualLoadingText}</span>
|
|
113
126
|
</>
|
|
114
127
|
) : (
|
|
@@ -147,7 +160,7 @@ export function XButton(props: xButtonProps) {
|
|
|
147
160
|
>
|
|
148
161
|
{isLoading ? (
|
|
149
162
|
<>
|
|
150
|
-
<icons.Loader2 className=
|
|
163
|
+
<icons.Loader2 className={loadingIconClass} />
|
|
151
164
|
<span>{actualLoadingText}</span>
|
|
152
165
|
</>
|
|
153
166
|
) : (
|
|
@@ -169,7 +182,7 @@ export function XButton(props: xButtonProps) {
|
|
|
169
182
|
aria-label="More actions"
|
|
170
183
|
aria-expanded={menuOpen}
|
|
171
184
|
>
|
|
172
|
-
<icons.ChevronDown className=
|
|
185
|
+
<icons.ChevronDown className={chevronIconClass} />
|
|
173
186
|
</button>
|
|
174
187
|
|
|
175
188
|
{/* dropdown menu */}
|