123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- import React from 'react';
- import {css} from '@emotion/react';
- import styled from '@emotion/styled';
- import classNames from 'classnames';
- import space from 'app/styles/space';
- import {Theme} from 'app/utils/theme';
- type Props = {
- type?: keyof Theme['alert'];
- icon?: React.ReactNode;
- system?: boolean;
- };
- type AlertProps = Omit<React.HTMLProps<HTMLDivElement>, keyof Props> & Props;
- type AlertThemeProps = {
- backgroundLight: string;
- border: string;
- iconColor: string;
- };
- const DEFAULT_TYPE = 'info';
- const getAlertColorStyles = ({
- backgroundLight,
- border,
- iconColor,
- }: AlertThemeProps) => css`
- background: ${backgroundLight};
- border: 1px solid ${border};
- svg {
- color: ${iconColor};
- }
- `;
- const getSystemAlertColorStyles = ({
- backgroundLight,
- border,
- iconColor,
- }: AlertThemeProps) => css`
- background: ${backgroundLight};
- border: 0;
- border-radius: 0;
- border-bottom: 1px solid ${border};
- svg {
- color: ${iconColor};
- }
- `;
- const alertStyles = ({theme, type = DEFAULT_TYPE, system}: Props & {theme: Theme}) => css`
- display: flex;
- margin: 0 0 ${space(3)};
- padding: ${space(1.5)} ${space(2)};
- font-size: 15px;
- box-shadow: ${theme.dropShadowLight};
- border-radius: ${theme.borderRadius};
- background: ${theme.backgroundSecondary};
- border: 1px solid ${theme.border};
- a:not([role='button']) {
- color: ${theme.textColor};
- border-bottom: 1px dotted ${theme.textColor};
- }
- ${getAlertColorStyles(theme.alert[type])};
- ${system && getSystemAlertColorStyles(theme.alert[type])};
- `;
- const IconWrapper = styled('span')`
- display: flex;
- margin-right: ${space(1)};
- /* Give the wrapper an explicit height so icons are line height with the
- * (common) line height. */
- height: 22px;
- align-items: center;
- `;
- const StyledTextBlock = styled('span')`
- line-height: 1.5;
- flex-grow: 1;
- position: relative;
- margin: auto;
- `;
- const Alert = styled(
- ({
- type,
- icon,
- children,
- className,
- system: _system, // don't forward to `div`
- ...props
- }: AlertProps) => {
- return (
- <div className={classNames(type ? `ref-${type}` : '', className)} {...props}>
- {icon && <IconWrapper>{icon}</IconWrapper>}
- <StyledTextBlock>{children}</StyledTextBlock>
- </div>
- );
- }
- )<AlertProps>`
- ${alertStyles}
- `;
- Alert.defaultProps = {
- type: DEFAULT_TYPE,
- };
- export {alertStyles};
- export default Alert;
|