UNPKG

@primer/react

Version:

An implementation of GitHub's Primer Design System using React

154 lines (151 loc) • 6.03 kB
import { clsx } from 'clsx'; import React, { useEffect, forwardRef } from 'react'; import { XIcon, StopIcon, InfoIcon, CheckCircleIcon, AlertIcon } from '@primer/octicons-react'; import { IconButton } from '../Button/IconButton.js'; import '../Button/ButtonBase.js'; import '../utils/defaultSxProp.js'; import { ButtonComponent } from '../Button/Button.js'; import { VisuallyHidden } from '../VisuallyHidden/VisuallyHidden.js'; import { useMergedRefs } from '../internal/hooks/useMergedRefs.js'; import classes from './Banner.module.css.js'; function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } const iconForVariant = { critical: /*#__PURE__*/React.createElement(StopIcon, null), info: /*#__PURE__*/React.createElement(InfoIcon, null), success: /*#__PURE__*/React.createElement(CheckCircleIcon, null), upsell: /*#__PURE__*/React.createElement(InfoIcon, null), warning: /*#__PURE__*/React.createElement(AlertIcon, null) }; const labels = { critical: 'Critical', info: 'Information', success: 'Success', upsell: 'Recommendation', warning: 'Warning' }; const Banner = /*#__PURE__*/React.forwardRef(function Banner({ 'aria-label': label, children, className, description, hideTitle, icon, onDismiss, primaryAction, secondaryAction, title, variant = 'info', ...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'; 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__*/React.createElement("section", _extends({}, rest, { "aria-label": label !== null && label !== undefined ? label : labels[variant], className: clsx(className, classes.Banner), "data-dismissible": onDismiss ? '' : undefined, "data-title-hidden": hideTitle ? '' : undefined, "data-variant": variant, tabIndex: -1, ref: ref }), /*#__PURE__*/React.createElement("div", { className: classes.BannerIcon }, icon && supportsCustomIcon ? icon : iconForVariant[variant]), /*#__PURE__*/React.createElement("div", { className: classes.BannerContainer }, /*#__PURE__*/React.createElement("div", { className: classes.BannerContent }, title ? hideTitle ? /*#__PURE__*/React.createElement(VisuallyHidden, null, /*#__PURE__*/React.createElement(BannerTitle, null, title)) : /*#__PURE__*/React.createElement(BannerTitle, null, title) : null, description ? /*#__PURE__*/React.createElement(BannerDescription, null, description) : null, children), hasActions ? /*#__PURE__*/React.createElement(BannerActions, { primaryAction: primaryAction, secondaryAction: secondaryAction }) : null), dismissible ? /*#__PURE__*/React.createElement(IconButton, { "aria-label": "Dismiss banner", onClick: onDismiss, className: classes.BannerDismiss, icon: XIcon, variant: "invisible" }) : null); }); function BannerTitle(props) { const { as: Heading = 'h2', className, children, ...rest } = props; return /*#__PURE__*/React.createElement(Heading, _extends({}, rest, { className: clsx(className, classes.BannerTitle), "data-banner-title": "" }), children); } BannerTitle.displayName = "BannerTitle"; function BannerDescription({ children, className, ...rest }) { return /*#__PURE__*/React.createElement("div", _extends({}, rest, { className: clsx('BannerDescription', className) }), children); } BannerDescription.displayName = "BannerDescription"; function BannerActions({ primaryAction, secondaryAction }) { return /*#__PURE__*/React.createElement("div", { className: classes.BannerActions }, /*#__PURE__*/React.createElement("div", { className: classes.BannerActionsContainer, "data-primary-action": "trailing" }, secondaryAction !== null && secondaryAction !== undefined ? secondaryAction : null, primaryAction !== null && primaryAction !== undefined ? primaryAction : null), /*#__PURE__*/React.createElement("div", { className: classes.BannerActionsContainer, "data-primary-action": "leading" }, primaryAction !== null && primaryAction !== undefined ? primaryAction : null, secondaryAction !== null && secondaryAction !== undefined ? secondaryAction : null)); } BannerActions.displayName = "BannerActions"; const BannerPrimaryAction = /*#__PURE__*/forwardRef(({ children, className, ...rest }, forwardedRef) => { return /*#__PURE__*/React.createElement(ButtonComponent, _extends({ ref: forwardedRef, className: clsx('BannerPrimaryAction', className), variant: "default" }, rest), children); }); BannerPrimaryAction.displayName = 'BannerPrimaryAction'; const BannerSecondaryAction = /*#__PURE__*/forwardRef(({ children, className, ...rest }, forwardedRef) => { return /*#__PURE__*/React.createElement(ButtonComponent, _extends({ ref: forwardedRef, className: clsx('BannerPrimaryAction', className), variant: "link" }, rest), children); }); BannerSecondaryAction.displayName = 'BannerSecondaryAction'; export { Banner, BannerActions, BannerDescription, BannerPrimaryAction, BannerSecondaryAction, BannerTitle };