@primer/react
Version:
An implementation of GitHub's Primer Design System using React
82 lines (81 loc) • 5.03 kB
JavaScript
import { useMergedRefs } from "../hooks/useMergedRefs.js";
import { VisuallyHidden } from "../VisuallyHidden/VisuallyHidden.js";
import { useId as useId$1 } from "../hooks/useId.js";
import Spinner from "../Spinner/Spinner.js";
import CounterLabel from "../CounterLabel/CounterLabel.js";
import { ConditionalWrapper } from "../internal/components/ConditionalWrapper.js";
import { AriaStatus } from "../live-region/AriaStatus.js";
import ButtonBase_module_css_default from "./ButtonBase.module.css.js";
import { clsx } from "clsx";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import React, { forwardRef } from "react";
import { isElement } from "react-is";
//#region src/Button/ButtonBase.tsx
const renderModuleVisual = (Visual, loading, visualName, counterLabel) => /*#__PURE__*/ jsx("span", {
"data-component": visualName,
className: clsx(!counterLabel && ButtonBase_module_css_default.Visual, loading ? ButtonBase_module_css_default.LoadingSpinner : ButtonBase_module_css_default.VisualWrap),
children: loading ? /*#__PURE__*/ jsx(Spinner, { size: "small" }) : isElement(Visual) ? Visual : /*#__PURE__*/ jsx(Visual, {})
});
renderModuleVisual.displayName = "renderModuleVisual";
const ButtonBase = /*#__PURE__*/ forwardRef(({ children, as: Component = "button", ...props }, forwardedRef) => {
const { leadingVisual: LeadingVisual, trailingVisual: TrailingVisual, trailingAction: TrailingAction, ["aria-describedby"]: ariaDescribedBy, ["aria-labelledby"]: ariaLabelledBy, count, icon: Icon, id, variant = "default", size = "medium", alignContent = "center", block = false, loading, loadingAnnouncement = "Loading", inactive, onClick, labelWrap, className, ...rest } = props;
const innerRef = React.useRef(null);
const mergedRef = useMergedRefs(forwardedRef, innerRef);
const uuid = useId$1(id);
const loadingAnnouncementID = `${uuid}-loading-announcement`;
const ariaDescribedByIds = loading ? [loadingAnnouncementID, ariaDescribedBy] : [ariaDescribedBy];
{
const el = innerRef.current;
if (el && !(el instanceof HTMLButtonElement) && !(el instanceof HTMLAnchorElement) && !(el.tagName === "SUMMARY")) console.warn("This component should be an instanceof a semantic button or anchor");
}
return /*#__PURE__*/ jsxs(ConditionalWrapper, {
if: typeof loading !== "undefined",
className: block ? ButtonBase_module_css_default.ConditionalWrapper : variant === "link" ? ButtonBase_module_css_default.ConditionalWrapperLink : void 0,
"data-loading-wrapper": true,
children: [/*#__PURE__*/ jsx(Component, {
"aria-disabled": loading ? true : void 0,
"data-component": "Button",
...rest,
ref: mergedRef,
className: clsx(ButtonBase_module_css_default.ButtonBase, className),
"data-block": block ? "block" : null,
"data-inactive": inactive ? true : void 0,
"data-loading": Boolean(loading),
"data-no-visuals": !LeadingVisual && !TrailingVisual && !TrailingAction ? true : void 0,
"data-size": size,
"data-variant": variant,
"data-label-wrap": labelWrap,
"data-has-count": count !== void 0 ? true : void 0,
"data-icon-only-counter": count !== void 0 && LeadingVisual && !children ? true : void 0,
"aria-describedby": ariaDescribedByIds.filter((descriptionID) => Boolean(descriptionID)).join(" ") || void 0,
"aria-labelledby": loading ? [`${uuid}-label`, ariaLabelledBy].filter((labelID) => Boolean(labelID)).join(" ") : ariaLabelledBy,
id,
onClick: loading ? void 0 : onClick,
children: Icon ? loading ? /*#__PURE__*/ jsx(Spinner, { size: "small" }) : isElement(Icon) ? Icon : /*#__PURE__*/ jsx(Icon, {}) : /*#__PURE__*/ jsxs(Fragment, { children: [/*#__PURE__*/ jsxs("span", {
"data-component": "buttonContent",
"data-align": alignContent,
className: ButtonBase_module_css_default.ButtonContent,
children: [
loading && !LeadingVisual && !TrailingVisual && !TrailingAction && count === void 0 && renderModuleVisual(Spinner, loading, "loadingSpinner", false),
LeadingVisual && renderModuleVisual(LeadingVisual, Boolean(loading), "leadingVisual", false),
children && /*#__PURE__*/ jsx("span", {
"data-component": "text",
className: ButtonBase_module_css_default.Label,
id: loading ? `${uuid}-label` : void 0,
children
}),
count !== void 0 && !TrailingVisual ? renderModuleVisual(/*#__PURE__*/ jsx(CounterLabel, {
className: ButtonBase_module_css_default.CounterLabel,
"data-component": "ButtonCounter",
children: count
}), Boolean(loading) && !LeadingVisual, "trailingVisual", true) : TrailingVisual ? renderModuleVisual(TrailingVisual, Boolean(loading) && !LeadingVisual, "trailingVisual", false) : null
]
}), TrailingAction && renderModuleVisual(TrailingAction, Boolean(loading) && !LeadingVisual && !TrailingVisual, "trailingAction", false)] })
}), loading && /*#__PURE__*/ jsx(VisuallyHidden, { children: /*#__PURE__*/ jsx(AriaStatus, {
id: loadingAnnouncementID,
children: loadingAnnouncement
}) })]
});
});
//#endregion
export { ButtonBase };