@vectara/vectara-ui
Version:
Vectara's design system, codified as a React and Sass component library
84 lines (83 loc) • 4.43 kB
JavaScript
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { forwardRef } from "react";
import classNames from "classnames";
import { getTrackingProps } from "../../utils/getTrackingProps";
import { useVuiContext } from "../context/Context";
import { VuiSpinner } from "../spinner/Spinner";
import { VuiTooltip } from "../tooltip/Tooltip";
const alignToClassMap = {
left: "vuiBaseButton--alignLeft",
center: "vuiBaseButton--alignCenter",
right: "vuiBaseButton--alignRight"
};
const sizeToSpinnerSizeMap = {
xs: "xs",
s: "xs",
m: "s",
l: "m"
};
export const BaseButton = forwardRef((_a, ref) => {
var { children, icon, iconSide = "left", align = "center", className, size = "m", fullWidth, onClick, onMouseOver, onMouseOut, onMouseMove, tabIndex, isInert, isDisabled, href, target, track, htmlFor, isSubmit, isLoading, spinnerColor, truncate, "aria-label": ariaLabel } = _a, rest = __rest(_a, ["children", "icon", "iconSide", "align", "className", "size", "fullWidth", "onClick", "onMouseOver", "onMouseOut", "onMouseMove", "tabIndex", "isInert", "isDisabled", "href", "target", "track", "htmlFor", "isSubmit", "isLoading", "spinnerColor", "truncate", "aria-label"]);
const { createLink } = useVuiContext();
const classes = classNames("vuiBaseButton", className, `vuiBaseButton--${size}`, alignToClassMap[align], {
"vuiBaseButton-isInert": isInert,
"vuiBaseButton-isDisabled": isDisabled,
"vuiBaseButton--fullWidth": fullWidth,
"vuiBaseButton--truncate": truncate,
[`vuiBaseButton--${isLoading ? "left" : iconSide}`]: (Boolean(icon) || isLoading) && Boolean(children)
});
let iconContainer;
if (isLoading) {
iconContainer = (_jsx("span", Object.assign({ className: "vuiBaseButtonIconContainer" }, { children: _jsx(VuiSpinner, { color: spinnerColor, size: sizeToSpinnerSizeMap[size] }) })));
}
else if (icon) {
iconContainer = _jsx("span", Object.assign({ className: "vuiBaseButtonIconContainer" }, { children: icon }));
}
let button;
if (htmlFor) {
// This is useful for controlling other elements, e.g. creating an <input type="file" />
// for uploading files and adding a button to trigger it.
button = (_jsxs("label", Object.assign({ "aria-label": ariaLabel, htmlFor: htmlFor, className: classes, tabIndex: tabIndex }, rest, { children: [iconContainer, children] })));
}
else if (href && !isDisabled) {
// Anchor tags can't be disabled, so we'll just render a button instead
// if isDisabled is true.
const wrapperClasses = classNames("vuiBaseButtonLinkWrapper", {
"vuiBaseButtonLinkWrapper--fullWidth": fullWidth
});
button = createLink(Object.assign(Object.assign({ className: wrapperClasses, href,
onClick,
onMouseOver,
onMouseOut,
onMouseMove, children: (
//* Wrap a button otherwise the flex layout breaks */}
_jsxs("button", Object.assign({ "aria-label": ariaLabel, className: classes, tabIndex: -1, ref: ref }, { children: [iconContainer, children] }))), target,
tabIndex }, rest), getTrackingProps(track)));
}
else {
const labelClasses = classNames({
"vuiBaseButtonLabel--truncate": truncate
});
const props = Object.assign({ onClick,
onMouseOver,
onMouseOut,
onMouseMove,
tabIndex, type: isSubmit ? "submit" : "button", disabled: isDisabled }, rest);
button = (_jsxs("button", Object.assign({ "aria-label": ariaLabel, className: classes }, props, { ref: ref }, { children: [iconContainer, _jsx("span", Object.assign({ className: labelClasses }, { children: children }))] })));
}
if (ariaLabel) {
return _jsx(VuiTooltip, Object.assign({ tip: ariaLabel }, { children: button }));
}
return button;
});