UNPKG

@shopify/polaris

Version:

Shopify’s product component library

227 lines (205 loc) • 7.21 kB
import React$1, { forwardRef, useContext, useRef, useState, useImperativeHandle } from 'react'; import { useFeatures } from '../../utilities/features/hooks.js'; import { useUniqueId } from '../../utilities/unique-id/hooks.js'; import { classNames, variationName } from '../../utilities/css.js'; import { CancelSmallMinor, CircleInformationMajor, FlagMajor, CircleDisabledMajor, CircleAlertMajor, CircleTickMajor } from '@shopify/polaris-icons'; import { Icon as Icon$1 } from '../Icon/Icon.js'; import { UnstyledLink as UnstyledLink$1 } from '../UnstyledLink/UnstyledLink.js'; import { UnstyledButton as UnstyledButton$1 } from '../UnstyledButton/UnstyledButton.js'; import { unstyledButtonFrom } from '../UnstyledButton/utils.js'; import { Button as Button$1 } from '../Button/Button.js'; import { buttonFrom } from '../Button/utils.js'; import { WithinContentContext } from '../../utilities/within-content-context.js'; import { ButtonGroup as ButtonGroup$1 } from '../ButtonGroup/ButtonGroup.js'; import { Heading as Heading$1 } from '../Heading/Heading.js'; import { BannerContext } from '../../utilities/banner-context.js'; import styles from './Banner.scss.js'; var Banner = /*#__PURE__*/forwardRef(function Banner({ icon, action, secondaryAction, title, children, status, onDismiss, stopAnnouncements }, bannerRef) { var { newDesignLanguage } = useFeatures(); var withinContentContainer = useContext(WithinContentContext); var buttonSizeValue = withinContentContainer ? 'slim' : undefined; var id = useUniqueId('Banner'); var { wrapperRef, handleKeyUp, handleBlur, handleMouseUp, shouldShowFocus } = useBannerFocus(bannerRef); var { defaultIcon, iconColor, ariaRoleType } = useBannerAttributes(status, newDesignLanguage); var iconName = icon || defaultIcon; var className = classNames(styles.Banner, status && styles[variationName('status', status)], onDismiss && styles.hasDismiss, shouldShowFocus && styles.keyFocused, withinContentContainer ? styles.withinContentContainer : styles.withinPage, newDesignLanguage && styles.newDesignLanguage); var headingMarkup = null; var headingID; if (title) { headingID = "".concat(id, "Heading"); headingMarkup = /*#__PURE__*/React$1.createElement("div", { className: styles.Heading, id: headingID }, /*#__PURE__*/React$1.createElement(Heading$1, { element: "p" }, title)); } var actionMarkup; if (action) { if (newDesignLanguage) { actionMarkup = /*#__PURE__*/React$1.createElement("div", { className: styles.Actions }, /*#__PURE__*/React$1.createElement(ButtonGroup$1, null, /*#__PURE__*/React$1.createElement("div", { className: styles.PrimaryAction }, unstyledButtonFrom(action, { className: styles.Button })), secondaryAction && /*#__PURE__*/React$1.createElement(SecondaryActionFrom, { action: secondaryAction }))); } else { actionMarkup = /*#__PURE__*/React$1.createElement("div", { className: styles.Actions }, /*#__PURE__*/React$1.createElement(ButtonGroup$1, null, /*#__PURE__*/React$1.createElement("div", { className: styles.PrimaryAction }, buttonFrom(action, { outline: true, size: buttonSizeValue })), secondaryAction && /*#__PURE__*/React$1.createElement(SecondaryActionFrom, { action: secondaryAction }))); } } var contentMarkup = null; var contentID; if (children || actionMarkup) { contentID = "".concat(id, "Content"); contentMarkup = /*#__PURE__*/React$1.createElement("div", { className: styles.Content, id: contentID }, children, actionMarkup); } var dismissButton = onDismiss && /*#__PURE__*/React$1.createElement("div", { className: styles.Dismiss }, /*#__PURE__*/React$1.createElement(Button$1, { plain: true, icon: CancelSmallMinor, onClick: onDismiss, accessibilityLabel: "Dismiss notification" })); return /*#__PURE__*/React$1.createElement(BannerContext.Provider, { value: true }, /*#__PURE__*/React$1.createElement("div", { className: className // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex , tabIndex: 0, ref: wrapperRef, role: ariaRoleType, "aria-live": stopAnnouncements ? 'off' : 'polite', onMouseUp: handleMouseUp, onKeyUp: handleKeyUp, onBlur: handleBlur, "aria-labelledby": headingID, "aria-describedby": contentID }, dismissButton, /*#__PURE__*/React$1.createElement("div", { className: styles.Ribbon }, /*#__PURE__*/React$1.createElement(Icon$1, { source: iconName, color: iconColor, backdrop: !newDesignLanguage })), /*#__PURE__*/React$1.createElement("div", { className: styles.ContentWrapper }, headingMarkup, contentMarkup))); }); function SecondaryActionFrom({ action }) { if (action.url) { return /*#__PURE__*/React$1.createElement(UnstyledLink$1, { className: styles.SecondaryAction, url: action.url, external: action.external }, /*#__PURE__*/React$1.createElement("span", { className: styles.Text }, action.content)); } return /*#__PURE__*/React$1.createElement(UnstyledButton$1, { className: styles.SecondaryAction, onClick: action.onAction }, /*#__PURE__*/React$1.createElement("span", { className: styles.Text }, action.content)); } function useBannerAttributes(status, newDesignLanguage) { switch (status) { case 'success': return { defaultIcon: CircleTickMajor, iconColor: newDesignLanguage ? 'success' : 'greenDark', ariaRoleType: 'status' }; case 'info': return { defaultIcon: CircleInformationMajor, iconColor: newDesignLanguage ? 'highlight' : 'tealDark', ariaRoleType: 'status' }; case 'warning': return { defaultIcon: CircleAlertMajor, iconColor: newDesignLanguage ? 'warning' : 'yellowDark', ariaRoleType: 'alert' }; case 'critical': return { defaultIcon: CircleDisabledMajor, iconColor: newDesignLanguage ? 'critical' : 'redDark', ariaRoleType: 'alert' }; default: return { defaultIcon: newDesignLanguage ? CircleInformationMajor : FlagMajor, iconColor: newDesignLanguage ? 'base' : 'inkLighter', ariaRoleType: 'status' }; } } function useBannerFocus(bannerRef) { var wrapperRef = useRef(null); var [shouldShowFocus, setShouldShowFocus] = useState(false); useImperativeHandle(bannerRef, () => ({ focus: () => { var _wrapperRef$current; (_wrapperRef$current = wrapperRef.current) == null ? void 0 : _wrapperRef$current.focus(); setShouldShowFocus(true); } })); var handleKeyUp = event => { if (event.target === wrapperRef.current) { setShouldShowFocus(true); } }; var handleBlur = () => setShouldShowFocus(false); var handleMouseUp = event => { event.currentTarget.blur(); setShouldShowFocus(false); }; return { wrapperRef, handleKeyUp, handleBlur, handleMouseUp, shouldShowFocus }; } export { Banner };