banner.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import * as React from 'react';
  2. import {css} from '@emotion/react';
  3. import styled from '@emotion/styled';
  4. import {IconClose} from 'app/icons/iconClose';
  5. import {t} from 'app/locale';
  6. import space from 'app/styles/space';
  7. type Props = {
  8. title?: string;
  9. subtitle?: string;
  10. isDismissable?: boolean;
  11. onCloseClick?: () => void;
  12. className?: string;
  13. } & BannerWrapperProps;
  14. class Banner extends React.Component<Props> {
  15. static defaultProps: Partial<Props> = {
  16. isDismissable: true,
  17. };
  18. render() {
  19. const {
  20. title,
  21. subtitle,
  22. isDismissable,
  23. onCloseClick,
  24. children,
  25. backgroundImg,
  26. backgroundComponent,
  27. className,
  28. } = this.props;
  29. return (
  30. <BannerWrapper
  31. backgroundComponent={backgroundComponent}
  32. backgroundImg={backgroundImg}
  33. className={className}
  34. >
  35. {backgroundComponent}
  36. {isDismissable ? (
  37. <StyledIconClose aria-label={t('Close')} onClick={onCloseClick} />
  38. ) : null}
  39. <BannerContent>
  40. <BannerTitle>{title}</BannerTitle>
  41. <BannerSubtitle>{subtitle}</BannerSubtitle>
  42. <BannerActions>{children}</BannerActions>
  43. </BannerContent>
  44. </BannerWrapper>
  45. );
  46. }
  47. }
  48. type BannerWrapperProps = {
  49. backgroundImg?: string;
  50. backgroundComponent?: React.ReactNode;
  51. };
  52. const BannerWrapper = styled('div')<BannerWrapperProps>`
  53. ${p =>
  54. p.backgroundImg
  55. ? css`
  56. background: url(${p.backgroundImg});
  57. background-repeat: no-repeat;
  58. background-size: cover;
  59. background-position: center center;
  60. `
  61. : css`
  62. background: ${p.theme.gray500};
  63. `}
  64. ${p =>
  65. p.backgroundComponent &&
  66. css`
  67. display: flex;
  68. flex-direction: column;
  69. overflow: hidden;
  70. `}
  71. position: relative;
  72. margin-bottom: ${space(3)};
  73. box-shadow: ${p => p.theme.dropShadowLight};
  74. border-radius: ${p => p.theme.borderRadius};
  75. color: ${p => p.theme.white};
  76. `;
  77. const BannerContent = styled('div')`
  78. position: absolute;
  79. top: 0;
  80. left: 0;
  81. width: 100%;
  82. height: 100%;
  83. display: flex;
  84. flex-direction: column;
  85. justify-content: center;
  86. align-items: center;
  87. text-align: center;
  88. padding: ${space(4)};
  89. @media (max-width: ${p => p.theme.breakpoints[0]}) {
  90. padding: ${space(0)};
  91. }
  92. `;
  93. const BannerTitle = styled('h1')`
  94. margin-bottom: ${space(0.25)};
  95. @media (max-width: ${p => p.theme.breakpoints[0]}) {
  96. font-size: 24px;
  97. }
  98. @media (min-width: ${p => p.theme.breakpoints[1]}) {
  99. margin-top: ${space(2)};
  100. margin-bottom: ${space(0.5)};
  101. font-size: 42px;
  102. }
  103. `;
  104. const BannerSubtitle = styled('div')`
  105. font-size: ${p => p.theme.fontSizeMedium};
  106. @media (max-width: ${p => p.theme.breakpoints[0]}) {
  107. font-size: ${p => p.theme.fontSizeSmall};
  108. }
  109. @media (min-width: ${p => p.theme.breakpoints[1]}) {
  110. font-size: ${p => p.theme.fontSizeExtraLarge};
  111. margin-bottom: ${space(1)};
  112. flex-direction: row;
  113. min-width: 650px;
  114. }
  115. `;
  116. const BannerActions = styled('div')`
  117. display: flex;
  118. justify-content: center;
  119. width: 100%;
  120. @media (min-width: ${p => p.theme.breakpoints[1]}) {
  121. width: auto;
  122. }
  123. `;
  124. const StyledIconClose = styled(IconClose)`
  125. position: absolute;
  126. display: block;
  127. top: ${space(2)};
  128. right: ${space(2)};
  129. color: ${p => p.theme.white};
  130. cursor: pointer;
  131. z-index: 1;
  132. `;
  133. export default Banner;