您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

Dialog.tsx 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import React, { useCallback } from 'react';
  2. import { useTranslation } from 'react-i18next';
  3. import { useDispatch } from 'react-redux';
  4. import { makeStyles } from 'tss-react/mui';
  5. import { hideDialog } from '../../../dialog/actions';
  6. import { IconCloseLarge } from '../../../icons/svg';
  7. import { withPixelLineHeight } from '../../../styles/functions.web';
  8. import BaseDialog, { IProps as IBaseDialogProps } from './BaseDialog';
  9. import Button from './Button';
  10. import ClickableIcon from './ClickableIcon';
  11. const useStyles = makeStyles()(theme => {
  12. return {
  13. header: {
  14. width: '100%',
  15. padding: '24px',
  16. boxSizing: 'border-box',
  17. display: 'flex',
  18. alignItems: 'flex-start',
  19. justifyContent: 'space-between'
  20. },
  21. title: {
  22. color: theme.palette.text01,
  23. ...withPixelLineHeight(theme.typography.heading5),
  24. margin: 0,
  25. padding: 0
  26. },
  27. content: {
  28. height: 'auto',
  29. overflowY: 'auto',
  30. width: '100%',
  31. boxSizing: 'border-box',
  32. padding: '0 24px',
  33. overflowX: 'hidden',
  34. minHeight: '40px',
  35. '@media (max-width: 448px)': {
  36. height: '100%'
  37. }
  38. },
  39. footer: {
  40. width: '100%',
  41. boxSizing: 'border-box',
  42. display: 'flex',
  43. alignItems: 'center',
  44. justifyContent: 'flex-end',
  45. padding: '24px',
  46. '& button:last-child': {
  47. marginLeft: '16px'
  48. }
  49. }
  50. };
  51. });
  52. interface IDialogProps extends IBaseDialogProps {
  53. back?: {
  54. hidden?: boolean;
  55. onClick?: () => void;
  56. translationKey?: string;
  57. };
  58. cancel?: {
  59. hidden?: boolean;
  60. translationKey?: string;
  61. };
  62. children?: React.ReactNode;
  63. disableAutoHideOnSubmit?: boolean;
  64. hideCloseButton?: boolean;
  65. ok?: {
  66. disabled?: boolean;
  67. hidden?: boolean;
  68. translationKey?: string;
  69. };
  70. onCancel?: () => void;
  71. onSubmit?: () => void;
  72. }
  73. const Dialog = ({
  74. back = { hidden: true },
  75. cancel = { translationKey: 'dialog.Cancel' },
  76. children,
  77. className,
  78. description,
  79. disableAutoHideOnSubmit = false,
  80. disableBackdropClose,
  81. hideCloseButton,
  82. disableEnter,
  83. ok = { translationKey: 'dialog.Ok' },
  84. onCancel,
  85. onSubmit,
  86. size,
  87. title,
  88. titleKey
  89. }: IDialogProps) => {
  90. const { classes } = useStyles();
  91. const { t } = useTranslation();
  92. const dispatch = useDispatch();
  93. const onClose = useCallback(() => {
  94. dispatch(hideDialog());
  95. onCancel?.();
  96. }, [ onCancel ]);
  97. const submit = useCallback(() => {
  98. !disableAutoHideOnSubmit && dispatch(hideDialog());
  99. onSubmit?.();
  100. }, [ onSubmit ]);
  101. return (
  102. <BaseDialog
  103. className = { className }
  104. description = { description }
  105. disableBackdropClose = { disableBackdropClose }
  106. disableEnter = { disableEnter }
  107. onClose = { onClose }
  108. size = { size }
  109. submit = { submit }
  110. title = { title }
  111. titleKey = { titleKey }>
  112. <div className = { classes.header }>
  113. <p
  114. className = { classes.title }
  115. id = 'dialog-title'>
  116. {title ?? t(titleKey ?? '')}
  117. </p>
  118. {!hideCloseButton && (
  119. <ClickableIcon
  120. accessibilityLabel = { t('dialog.accessibilityLabel.close') }
  121. icon = { IconCloseLarge }
  122. id = 'modal-header-close-button'
  123. onClick = { onClose } />
  124. )}
  125. </div>
  126. <div
  127. className = { classes.content }
  128. data-autofocus-inside = 'true'>
  129. {children}
  130. </div>
  131. <div
  132. className = { classes.footer }
  133. data-autofocus-inside = 'true'>
  134. {!back.hidden && <Button
  135. accessibilityLabel = { t(back.translationKey ?? '') }
  136. labelKey = { back.translationKey }
  137. // eslint-disable-next-line react/jsx-handler-names
  138. onClick = { back.onClick }
  139. type = 'secondary' />}
  140. {!cancel.hidden && <Button
  141. accessibilityLabel = { t(cancel.translationKey ?? '') }
  142. labelKey = { cancel.translationKey }
  143. onClick = { onClose }
  144. type = 'tertiary' />}
  145. {!ok.hidden && <Button
  146. accessibilityLabel = { t(ok.translationKey ?? '') }
  147. disabled = { ok.disabled }
  148. id = 'modal-dialog-ok-button'
  149. labelKey = { ok.translationKey }
  150. onClick = { submit } />}
  151. </div>
  152. </BaseDialog>
  153. );
  154. };
  155. export default Dialog;