@veracity/vui
Version:
Veracity UI is a React component library crafted for use within Veracity applications and pages. Based on Styled Components and @xstyled.
108 lines (106 loc) • 4.5 kB
JavaScript
import { activeClassName } from "../utils/consts.js";
import { filterUndefined } from "../utils/object.js";
import { cs } from "../utils/styles.js";
import fontSizes_default from "../theme/foundations/fontSizes.js";
import { useStyleConfig, useTheme } from "../core/theme.js";
import { extractNumericValue, resolveVariantKey } from "./utils.js";
import { useMemo } from "react";
//#region src/button/useButtonComputed.ts
/**
* Consolidated hook for computing all button styles and props.
* Combines theme resolution, spacing, state-based styles, and className generation.
* Reduces memoization overhead by computing all derived values in a single pass.
*
* @param options - See {@link ButtonComputedOptions} for individual field descriptions.
* @returns See {@link ComputedResult}
*/
const useButtonComputed = ({ size, variant, intentProp, borderWidthProp, disabled, isActive, isIconOnly, isRound, isElevated, hasStartIcon, hasEndIcon, isFullWidth, className, variantProp }) => {
const theme = useTheme();
const styles = useStyleConfig("Button", {
size,
...variant
}) || {};
const fallbackVariant = resolveVariantKey("primary", intentProp ?? "brand");
const defaultStyles = useStyleConfig("Button", { variant: fallbackVariant }) || {};
return useMemo(() => {
const requestedContainer = styles.container || {};
const container = requestedContainer.bg || requestedContainer.borderColor || requestedContainer.color ? requestedContainer : defaultStyles.container || {};
const { borderWidth = 1, paddingX = 16, paddingXIcon, paddingY = 12, gapX = 8, h = 40, fontSize = "md", ...buttonStyles } = container;
const normalizedStyles = {
...buttonStyles,
activeColor: buttonStyles.activeColor ?? buttonStyles.color,
hoverColor: buttonStyles.hoverColor ?? buttonStyles.color
};
const border = extractNumericValue(borderWidthProp) || borderWidth || 1;
const py = paddingY - border;
const pxForSide = (hasIcon) => {
if (isIconOnly) return 0;
return hasIcon ? paddingXIcon ?? paddingX : paddingX;
};
const spacing = {
borderWidth: border,
pl: `var(--vui-button-px-start, ${pxForSide(hasStartIcon)}px)`,
pr: `var(--vui-button-px-end, ${pxForSide(hasEndIcon)}px)`,
pt: `var(--vui-button-py-start, ${isIconOnly ? 0 : py}px)`,
pb: `var(--vui-button-py-end, ${isIconOnly ? 0 : py}px)`,
gap: `var(--vui-button-gap, ${gapX}px)`
};
const disabledProps = disabled ? filterUndefined({
"aria-disabled": disabled,
bg: container.disabledBg ?? void 0,
borderColor: container.disabledBorderColor ?? void 0,
color: container.disabledColor ?? void 0,
hoverBg: container.disabledBg ?? normalizedStyles.bg,
hoverBorderColor: container.disabledBorderColor ?? normalizedStyles.borderColor,
hoverColor: container.disabledColor ?? normalizedStyles.color,
activeBg: container.disabledBg ?? normalizedStyles.bg,
cursor: "not-allowed"
}) : {};
const activeProps = isActive ? filterUndefined({
bg: container.activeBg,
borderColor: container.activeBorderColor,
color: container.activeColor,
hoverBg: container.activeBg,
hoverBorderColor: container.activeBorderColor,
hoverColor: container.activeColor,
cursor: "default"
}) : {};
const resolvedBoxShadow = theme.shadows["md"] ?? "md";
const resolvedFontSize = fontSizes_default[fontSize] ?? fontSize;
return {
buttonStyles: normalizedStyles,
spacing,
disabledProps,
activeProps,
aliasedProps: filterUndefined({
borderRadius: isRound ? `var(--vui-button-border-radius, 9999px)` : `var(--vui-button-border-radius, ${container.borderRadius || 0}px)`,
boxShadow: isElevated ? `var(--vui-button-box-shadow, ${resolvedBoxShadow})` : void 0,
fontSize: `var(--vui-button-font-size, ${resolvedFontSize}px)`,
h: `var(--vui-button-h, ${h}px)`,
minW: isFullWidth ? void 0 : `var(--vui-button-min-w, auto)`,
w: isIconOnly ? `var(--vui-button-w, ${h}px)` : isFullWidth ? "100%" : void 0
}),
buttonClassName: cs("vui-button", className, isActive && "vui-active", variantProp ? `vui-button-variant-${variantProp}` : void 0, intentProp ? `vui-button-intent-${intentProp}` : void 0)
};
}, [
styles,
defaultStyles,
theme,
intentProp,
borderWidthProp,
hasStartIcon,
hasEndIcon,
isIconOnly,
disabled,
isActive,
isRound,
isElevated,
isFullWidth,
className,
variantProp
]);
};
//#endregion
export { useButtonComputed };
globalThis.__vuiVersion__ = "5.3.1"
//# sourceMappingURL=useButtonComputed.js.map