@shopify/polaris
Version:
Shopify’s product component library
227 lines (205 loc) • 7.21 kB
JavaScript
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 };