UNPKG

@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
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