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.js 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // @flow
  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. titleIconWrapperStyles,
  9. TitleText
  10. } from '@atlaskit/modal-dialog/dist/es2019/styled/Content';
  11. import React from 'react';
  12. import { translate } from '../../../i18n';
  13. import { Icon, IconClose } from '../../../icons';
  14. const TitleIcon = ({ appearance }: { appearance?: 'danger' | 'warning' }) => {
  15. if (!appearance) {
  16. return null;
  17. }
  18. const IconSymbol = appearance === 'danger' ? ErrorIcon : WarningIcon;
  19. return (
  20. <span css = { titleIconWrapperStyles(appearance) }>
  21. <IconSymbol label = { `${appearance} icon` } />
  22. </span>
  23. );
  24. };
  25. type Props = {
  26. id: string,
  27. appearance?: 'danger' | 'warning',
  28. heading: string,
  29. hideCloseIconButton: boolean,
  30. onClose: Function,
  31. showKeyline: boolean,
  32. isHeadingMultiline: boolean,
  33. testId: string,
  34. t: Function
  35. }
  36. /**
  37. * A default header for modal-dialog components
  38. *
  39. * @export
  40. * @class ModalHeader
  41. * @extends {React.Component<Props>}
  42. */
  43. class ModalHeader extends React.Component<Props> {
  44. static defaultProps = {
  45. isHeadingMultiline: true
  46. };
  47. /**
  48. * Initializes a new {@code ModalHeader} instance.
  49. *
  50. * @param {*} props - The read-only properties with which the new instance
  51. * is to be initialized.
  52. */
  53. constructor(props) {
  54. super(props);
  55. // Bind event handler so it is only bound once for every instance.
  56. this._onKeyPress = this._onKeyPress.bind(this);
  57. }
  58. _onKeyPress: (Object) => void;
  59. /**
  60. * KeyPress handler for accessibility.
  61. *
  62. * @param {Object} e - The key event to handle.
  63. *
  64. * @returns {void}
  65. */
  66. _onKeyPress(e) {
  67. if (this.props.onClose && (e.key === ' ' || e.key === 'Enter')) {
  68. e.preventDefault();
  69. this.props.onClose();
  70. }
  71. }
  72. /**
  73. * Implements React's {@link Component#render()}.
  74. *
  75. * @inheritdoc
  76. * @returns {ReactElement}
  77. */
  78. render() {
  79. const {
  80. id,
  81. appearance,
  82. heading,
  83. hideCloseIconButton,
  84. onClose,
  85. showKeyline,
  86. isHeadingMultiline,
  87. testId,
  88. t
  89. } = this.props;
  90. if (!heading) {
  91. return null;
  92. }
  93. return (
  94. <Header showKeyline = { showKeyline }>
  95. <Title>
  96. <TitleIcon appearance = { appearance } />
  97. <TitleText
  98. data-testid = { testId && `${testId}-heading` }
  99. id = { id }
  100. isHeadingMultiline = { isHeadingMultiline }>
  101. {heading}
  102. </TitleText>
  103. </Title>
  104. {
  105. !hideCloseIconButton && <Icon
  106. ariaLabel = { t('dialog.close') }
  107. onClick = { onClose }
  108. onKeyPress = { this._onKeyPress }
  109. role = 'button'
  110. src = { IconClose }
  111. tabIndex = { 0 } />
  112. }
  113. </Header>
  114. );
  115. }
  116. }
  117. export default translate(ModalHeader);