You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ModalHeader.tsx 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /* eslint-disable lines-around-comment */
  2. /* eslint-disable react/no-multi-comp */
  3. import ErrorIcon from '@atlaskit/icon/glyph/error';
  4. import WarningIcon from '@atlaskit/icon/glyph/warning';
  5. import {
  6. Header,
  7. Title,
  8. TitleText,
  9. titleIconWrapperStyles
  10. // @ts-ignore
  11. } from '@atlaskit/modal-dialog/dist/es2019/styled/Content';
  12. import { Theme } from '@mui/material';
  13. import { withStyles } from '@mui/styles';
  14. import React from 'react';
  15. import { WithTranslation } from 'react-i18next';
  16. import { translate } from '../../../i18n/functions';
  17. import { IconCloseLarge } from '../../../icons/svg';
  18. import { withPixelLineHeight } from '../../../styles/functions.web';
  19. import Button from '../../../ui/components/web/Button';
  20. import { BUTTON_TYPES } from '../../../ui/constants.web';
  21. const TitleIcon = ({ appearance }: { appearance?: 'danger' | 'warning'; }) => {
  22. if (!appearance) {
  23. return null;
  24. }
  25. const IconSymbol = appearance === 'danger' ? ErrorIcon : WarningIcon;
  26. return (
  27. <span css = { titleIconWrapperStyles(appearance) }>
  28. <IconSymbol label = { `${appearance} icon` } />
  29. </span>
  30. );
  31. };
  32. interface IProps extends WithTranslation {
  33. appearance?: 'danger' | 'warning';
  34. classes: any;
  35. heading: string;
  36. hideCloseIconButton: boolean;
  37. id?: string;
  38. isHeadingMultiline: boolean;
  39. onClose: (e?: any) => void;
  40. showKeyline: boolean;
  41. testId?: string;
  42. }
  43. /**
  44. * Creates the styles for the component.
  45. *
  46. * @param {Object} theme - The current UI theme.
  47. *
  48. * @returns {Object}
  49. */
  50. const styles = (theme: Theme) => {
  51. return {
  52. closeButton: {
  53. borderRadius: theme.shape.borderRadius,
  54. cursor: 'pointer',
  55. padding: 13,
  56. [theme.breakpoints.down(480)]: {
  57. background: theme.palette.action02
  58. },
  59. '&:hover': {
  60. background: theme.palette.ui04
  61. }
  62. },
  63. header: {
  64. boxShadow: 'none',
  65. '& h4': {
  66. ...withPixelLineHeight(theme.typography.heading5),
  67. color: theme.palette.text01
  68. }
  69. }
  70. };
  71. };
  72. /**
  73. * A default header for modal-dialog components.
  74. *
  75. * @class ModalHeader
  76. * @augments {React.Component<IProps>}
  77. */
  78. class ModalHeader extends React.Component<IProps> {
  79. static defaultProps = {
  80. isHeadingMultiline: true
  81. };
  82. /**
  83. * Initializes a new {@code ModalHeader} instance.
  84. *
  85. * @param {*} props - The read-only properties with which the new instance
  86. * is to be initialized.
  87. */
  88. constructor(props: IProps) {
  89. super(props);
  90. // Bind event handler so it is only bound once for every instance.
  91. this._onKeyPress = this._onKeyPress.bind(this);
  92. }
  93. /**
  94. * KeyPress handler for accessibility.
  95. *
  96. * @param {Object} e - The key event to handle.
  97. *
  98. * @returns {void}
  99. */
  100. _onKeyPress(e: React.KeyboardEvent) {
  101. if (this.props.onClose && (e.key === ' ' || e.key === 'Enter')) {
  102. e.preventDefault();
  103. this.props.onClose();
  104. }
  105. }
  106. /**
  107. * Implements React's {@link Component#render()}.
  108. *
  109. * @inheritdoc
  110. * @returns {ReactElement}
  111. */
  112. render() {
  113. const {
  114. id,
  115. appearance,
  116. classes,
  117. heading,
  118. hideCloseIconButton,
  119. onClose,
  120. showKeyline,
  121. isHeadingMultiline,
  122. testId,
  123. t
  124. } = this.props;
  125. if (!heading) {
  126. return null;
  127. }
  128. return (
  129. <Header
  130. className = { classes.header }
  131. showKeyline = { showKeyline }>
  132. <Title>
  133. <TitleIcon appearance = { appearance } />
  134. <TitleText
  135. data-testid = { testId && `${testId}-heading` }
  136. id = { id }
  137. isHeadingMultiline = { isHeadingMultiline }>
  138. {heading}
  139. </TitleText>
  140. </Title>
  141. {
  142. !hideCloseIconButton && <Button
  143. accessibilityLabel = { t('dialog.close') }
  144. icon = { IconCloseLarge }
  145. id = 'modal-header-close-button'
  146. onClick = { onClose }
  147. size = 'large'
  148. type = { BUTTON_TYPES.TERTIARY } />
  149. }
  150. </Header>
  151. );
  152. }
  153. }
  154. export default translate(withStyles(styles)(ModalHeader));