UNPKG

@primer/react

Version:

An implementation of GitHub's Primer Design System using React

199 lines (196 loc) • 6.83 kB
import { clsx } from 'clsx'; import React, { useEffect, forwardRef } from 'react'; import { XIcon, AlertIcon, InfoIcon, CheckCircleIcon, StopIcon } from '@primer/octicons-react'; import { IconButton } from '../Button/IconButton.js'; import { ButtonComponent } from '../Button/Button.js'; import { useMergedRefs } from '../hooks/useMergedRefs.js'; import { useId } from '../hooks/useId.js'; import classes from './Banner.module.css.js'; import { jsx, jsxs } from 'react/jsx-runtime'; import { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden.js'; const BannerContext = /*#__PURE__*/React.createContext(undefined); const iconForVariant = { critical: /*#__PURE__*/jsx(StopIcon, {}), info: /*#__PURE__*/jsx(InfoIcon, {}), success: /*#__PURE__*/jsx(CheckCircleIcon, {}), upsell: /*#__PURE__*/jsx(InfoIcon, {}), warning: /*#__PURE__*/jsx(AlertIcon, {}) }; const Banner = /*#__PURE__*/React.forwardRef(function Banner({ 'aria-label': label, 'aria-labelledby': labelledBy, children, className, description, hideTitle, icon, leadingVisual, onDismiss, primaryAction, secondaryAction, title, variant = 'info', actionsLayout = 'default', flush = false, ...rest }, forwardRef) { const dismissible = !!onDismiss; const hasActions = primaryAction || secondaryAction; const bannerRef = React.useRef(null); const ref = useMergedRefs(forwardRef, bannerRef); const supportsCustomIcon = variant === 'info' || variant === 'upsell'; const titleId = useId(); const visual = leadingVisual !== null && leadingVisual !== void 0 ? leadingVisual : icon; if (process.env.NODE_ENV !== "production") { // This hook is called consistently depending on the environment // eslint-disable-next-line react-hooks/rules-of-hooks useEffect(() => { if (title) { return; } const { current: banner } = bannerRef; if (!banner) { return; } const hasTitle = banner.querySelector('[data-banner-title]'); if (!hasTitle) { throw new Error('Expected a title to be provided to the <Banner> component with the `title` prop or through `<Banner.Title>` but no title was found'); } }, [title]); } return /*#__PURE__*/jsx(BannerContext.Provider, { value: { titleId }, children: /*#__PURE__*/jsxs("section", { "data-component": "Banner", ...rest, "aria-labelledby": labelledBy !== null && labelledBy !== void 0 ? labelledBy : label ? undefined : titleId, "aria-label": labelledBy ? undefined : label, className: clsx(className, classes.Banner), "data-dismissible": onDismiss ? '' : undefined, "data-has-actions": hasActions ? '' : undefined, "data-title-hidden": hideTitle ? '' : undefined, "data-variant": variant, "data-actions-layout": actionsLayout, tabIndex: -1, ref: ref, "data-layout": rest.layout || 'default', "data-flush": flush ? '' : undefined, children: [/*#__PURE__*/jsx("div", { "data-component": "Banner.Icon", className: classes.BannerIcon, children: visual && supportsCustomIcon ? visual : iconForVariant[variant] }), /*#__PURE__*/jsxs("div", { className: classes.BannerContainer, children: [/*#__PURE__*/jsxs("div", { "data-component": "Banner.Content", className: classes.BannerContent, children: [title ? hideTitle ? /*#__PURE__*/jsx(VisuallyHidden, { children: /*#__PURE__*/jsx(BannerTitle, { children: title }) }) : /*#__PURE__*/jsx(BannerTitle, { children: title }) : null, description ? /*#__PURE__*/jsx(BannerDescription, { children: description }) : null, children] }), hasActions ? /*#__PURE__*/jsx(BannerActions, { primaryAction: primaryAction, secondaryAction: secondaryAction }) : null] }), dismissible ? /*#__PURE__*/jsx(IconButton, { "aria-label": "Dismiss banner", onClick: onDismiss, className: classes.BannerDismiss, icon: XIcon, variant: "invisible" }) : null] }) }); }); function BannerTitle(props) { const { as: Heading = 'h2', className, children, id, ...rest } = props; const context = React.useContext(BannerContext); const titleId = id !== null && id !== void 0 ? id : context === null || context === void 0 ? void 0 : context.titleId; return /*#__PURE__*/jsx(Heading, { ...rest, id: titleId, className: clsx(className, classes.BannerTitle), "data-component": "Banner.Title", "data-banner-title": "", children: children }); } BannerTitle.displayName = "BannerTitle"; function BannerDescription({ children, className, ...rest }) { return /*#__PURE__*/jsx("div", { ...rest, className: clsx('BannerDescription', className), "data-component": "Banner.Description", children: children }); } BannerDescription.displayName = "BannerDescription"; function BannerActions({ primaryAction, secondaryAction }) { return /*#__PURE__*/jsxs("div", { className: classes.BannerActions, "data-component": "Banner.Actions", children: [/*#__PURE__*/jsxs("div", { className: classes.BannerActionsContainer, "data-primary-action": "trailing", children: [secondaryAction !== null && secondaryAction !== void 0 ? secondaryAction : null, primaryAction !== null && primaryAction !== void 0 ? primaryAction : null] }), /*#__PURE__*/jsxs("div", { className: classes.BannerActionsContainer, "data-primary-action": "leading", children: [primaryAction !== null && primaryAction !== void 0 ? primaryAction : null, secondaryAction !== null && secondaryAction !== void 0 ? secondaryAction : null] })] }); } BannerActions.displayName = "BannerActions"; const BannerPrimaryAction = /*#__PURE__*/forwardRef(({ children, className, ...rest }, forwardedRef) => { return /*#__PURE__*/jsx(ButtonComponent, { "data-component": "Banner.PrimaryAction", ref: forwardedRef, className: clsx('BannerPrimaryAction', className), variant: "default", ...rest, children: children }); }); BannerPrimaryAction.displayName = 'BannerPrimaryAction'; const BannerSecondaryAction = /*#__PURE__*/forwardRef(({ children, className, ...rest }, forwardedRef) => { return /*#__PURE__*/jsx(ButtonComponent, { "data-component": "Banner.SecondaryAction", ref: forwardedRef, className: clsx('BannerPrimaryAction', className), variant: "invisible", ...rest, children: children }); }); BannerSecondaryAction.displayName = 'BannerSecondaryAction'; export { Banner, BannerActions, BannerDescription, BannerPrimaryAction, BannerSecondaryAction, BannerTitle };