UNPKG

@elastic/eui

Version:

Elastic UI Component Library

199 lines (196 loc) 9.85 kB
import _extends from "@babel/runtime/helpers/extends"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; var _excluded = ["title", "text", "color", "size", "iconType", "children", "actionProps", "className", "heading", "onDismiss", "dismissButtonProps", "announceOnMount", "style", "data-test-subj"]; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0 and the Server Side Public License, v 1; you may not use this file except * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ import React, { forwardRef, useMemo } from 'react'; import classNames from 'classnames'; import { getTokenName } from '@elastic/eui-theme-common'; import { useCombinedRefs, useEuiMemoizedStyles, useEuiTheme } from '../../services'; import { useEuiBorderColorCSS } from '../../global_styling'; import { EuiIcon } from '../icon'; import { EuiButtonIcon } from '../button'; import { EuiText } from '../text'; import { EuiPanel } from '../panel'; import { EuiTitle } from '../title'; import { EuiI18n } from '../i18n'; import { EuiLiveAnnouncer } from '../accessibility/live_announcer'; import { EuiNotificationIcon } from '../notification_icon/notification_icon'; import { useLayoutObserver } from './use_layout_observer'; import { EuiCallOutAction } from './call_out_action'; import { euiCallOutStyles, euiCallOutHeaderStyles } from './call_out.styles'; import { euiNotificationIconStyles } from '../notification_icon/notification_icon.styles'; import { jsx as ___EmotionJSX } from "@emotion/react"; export var COLOR_TO_NOTIFICATION_ICON_MAP = { primary: 'info', success: 'success', warning: 'warning', danger: 'error' }; /** Get correct color with fallback */ var getCallOutColor = function getCallOutColor(color) { return typeof color === 'string' && COLOR_TO_NOTIFICATION_ICON_MAP.hasOwnProperty(color) ? color : 'primary'; }; export var EuiCallOut = /*#__PURE__*/forwardRef(function (_ref, ref) { var title = _ref.title, text = _ref.text, _ref$color = _ref.color, _color = _ref$color === void 0 ? 'primary' : _ref$color, _ref$size = _ref.size, size = _ref$size === void 0 ? 'm' : _ref$size, iconType = _ref.iconType, children = _ref.children, actionProps = _ref.actionProps, className = _ref.className, _ref$heading = _ref.heading, heading = _ref$heading === void 0 ? 'p' : _ref$heading, onDismiss = _ref.onDismiss, dismissButtonProps = _ref.dismissButtonProps, _ref$announceOnMount = _ref.announceOnMount, announceOnMount = _ref$announceOnMount === void 0 ? false : _ref$announceOnMount, style = _ref.style, dataTestSubj = _ref['data-test-subj'], rest = _objectWithoutProperties(_ref, _excluded); var _useEuiTheme = useEuiTheme(), euiTheme = _useEuiTheme.euiTheme; var color = getCallOutColor(_color); /* Uses resize observer to determine the container width/layout instead of native container queries, because callouts can be placed in containers without defined size (absolute positioned, no-grow flex layout etc.) where container queries would collapse by design instead of adjusting to the content dimensions. */ var layoutRef = useLayoutObserver(size); // Memoize the refs array so `useCombinedRefs` returns a stable callback-ref across renders var combinedRefs = useMemo(function () { return [layoutRef, ref]; }, [layoutRef, ref]); var panelRef = useCombinedRefs(combinedRefs); var borderColors = useEuiBorderColorCSS(); var styles = useEuiMemoizedStyles(euiCallOutStyles); var cssStyles = [styles.euiCallOut, borderColors[color], onDismiss && styles.hasDismissButton]; var highlightColorToken = getTokenName('borderStrong', color); var typeColor = euiTheme.colors[highlightColorToken]; var cssVariables = useMemo(function () { return { '--euiCallOutTypeColor': typeColor }; }, [typeColor]); var classes = classNames('euiCallOut', _defineProperty({}, "euiCallOut--".concat(color), color), className); var dismissButton = useMemo(function () { if (!onDismiss) return; var cssStyles = [styles.dismissButton.euiCallOut__dismissButton]; return ___EmotionJSX(EuiI18n, { token: "euiCallOut.dismissAriaLabel", default: "Dismiss this callout" }, function (dismissAriaLabel) { return ___EmotionJSX(EuiButtonIcon, _extends({ "data-test-subj": "euiDismissCalloutButton", "aria-label": dismissAriaLabel, css: cssStyles }, dismissButtonProps, { iconType: "cross", color: color, size: "xs", onClick: onDismiss })); }); }, [onDismiss, styles, color, dismissButtonProps]); var headerStyles = useEuiMemoizedStyles(euiCallOutHeaderStyles); var iconStyles = useEuiMemoizedStyles(euiNotificationIconStyles); var header = useMemo(function () { if (!title) return; var H = heading; var cssStyles = [headerStyles.euiCallOutHeader]; return ___EmotionJSX(EuiTitle, { size: size === 's' ? 'xxs' : 'xs', css: cssStyles }, ___EmotionJSX(H, { className: "euiCallOutHeader__title" }, title)); }, [title, heading, size, headerStyles]); var icon = useMemo(function () { if (!iconType) { var _COLOR_TO_NOTIFICATIO; var _iconType = (_COLOR_TO_NOTIFICATIO = COLOR_TO_NOTIFICATION_ICON_MAP[color]) !== null && _COLOR_TO_NOTIFICATIO !== void 0 ? _COLOR_TO_NOTIFICATIO : 'info'; return ___EmotionJSX(EuiNotificationIcon, { css: styles.icon, type: _iconType, size: size === 's' ? 'm' : 'l' }); } return ___EmotionJSX(EuiIcon, { css: [styles.icon, size === 'm' && iconStyles.size.l, ";label:icon;"], type: iconType, size: size === 's' ? 'm' : 'l', "aria-hidden": "true", color: typeColor }); }, [iconType, color, size, typeColor, styles, iconStyles]); var optionalChildren = (text || children) && ___EmotionJSX(React.Fragment, null, text && ___EmotionJSX(EuiText, { size: "s", color: "default", className: "euiCallOut__text", "data-test-subj": dataTestSubj && "".concat(dataTestSubj, "__message") }, text), children && ___EmotionJSX(EuiText, { className: "euiCallOut__additionalContent", size: size === 's' ? 'xs' : 's', color: "default", "data-test-subj": dataTestSubj && "".concat(dataTestSubj, "__content") }, children)); var actionControls = useMemo(function () { var actionPrimaryProps = _objectSpread(_objectSpread({}, actionProps === null || actionProps === void 0 ? void 0 : actionProps.primary), {}, { color: color }); var actionSecondaryProps = _objectSpread(_objectSpread({}, actionProps === null || actionProps === void 0 ? void 0 : actionProps.secondary), {}, { color: color }); var hasActionPrimary = Boolean(actionProps === null || actionProps === void 0 ? void 0 : actionProps.primary); var hasActionSecondary = Boolean(actionProps === null || actionProps === void 0 ? void 0 : actionProps.secondary); if (!hasActionPrimary && !hasActionSecondary) return null; var actionPrimary = hasActionPrimary && ___EmotionJSX(EuiCallOutAction, _extends({ actionType: "primary" }, actionPrimaryProps)); var actionSecondary = hasActionSecondary && ___EmotionJSX(EuiCallOutAction, _extends({ actionType: "secondary" }, actionSecondaryProps)); return ___EmotionJSX("div", { css: styles.actions, "data-test-subj": dataTestSubj && "".concat(dataTestSubj, "__actions") }, actionPrimary, actionSecondary); }, [actionProps, color, styles, dataTestSubj]); var announcement = useMemo(function () { if (!announceOnMount || !(title || text || children)) return null; return ___EmotionJSX(EuiLiveAnnouncer, null, title, title && text && ",\xA0", text, (title || text) && children && ",\xA0", children); }, [announceOnMount, title, text, children]); return ___EmotionJSX(EuiPanel, _extends({ borderRadius: "none", color: color, css: cssStyles // uses custom padding , paddingSize: "none", className: classes, panelRef: panelRef, grow: false, style: _objectSpread(_objectSpread({}, cssVariables), style), "data-size": size, "data-test-subj": dataTestSubj }, rest), ___EmotionJSX("div", { css: styles.wrapper }, ___EmotionJSX("div", { css: styles.body }, icon, ___EmotionJSX("div", { css: styles.content }, // Note: the DOM position of the dismiss button matters to screen reader users. // We generally want them to have some context of _what_ they're dismissing, // instead of navigating to the dismiss button first before the callout content header && optionalChildren ? ___EmotionJSX(React.Fragment, null, header, dismissButton, optionalChildren) : ___EmotionJSX(React.Fragment, null, header || optionalChildren, dismissButton))), actionControls, announcement)); }); EuiCallOut.displayName = 'EuiCallOut';