Repository: freeCodeCamp/freeCodeCamp
File: client/src/components/Donation/donation-modal-body.tsx (TypeScript)

Code before:
  donationAnimationFlag
}: {
  recentlyClaimedBlock: RecentlyClaimedBlock;
  showHeaderAndFooter: boolean;
  donationAttempted: boolean;
  showForm: boolean;
  donationAnimationFlag: boolean;
}) {
  const { t } = useTranslation();
  if (!showHeaderAndFooter || donationAttempted) {
    return null;
  } else if (!donationAnimationFlag) {
    return (
      <Row className='text-center block-modal-text'>
        <Col sm={10} smOffset={1} xs={12}>
          {recentlyClaimedBlock !== null && (
            <b>
              {t('donate.nicely-done', {
                block: t(
                  `intro:${recentlyClaimedBlock.superBlock}.blocks.${recentlyClaimedBlock.block}.title`
                )
              })}
            </b>
          )}
          <h2>{t('donate.help-us-develop')}</h2>
        </Col>
      </Row>
    );
  } else if (!showForm) {
    return (
      <Row className='text-center block-modal-text'>
        <Col sm={10} smOffset={1} xs={12}>
          <h2>{t('donate.modal-benefits-title')}</h2>
        </Col>
      </Row>
    );
  } else {
    return null;
  }
}

function CloseButtonRow({
  donationAttempted,
  closeDonationModal
}: {
  donationAttempted: boolean;
  closeDonationModal: () => void;
}) {
  const { t } = useTranslation();
  return (
    <Row>

Review comment (suggestion):
Each modal needs to have a name so that screen reader users know what the modal is for. Having an `h2` within the modal is only half of the requirement, the other half is we need to tell the dialog to use the heading as its title (using `aria-labelledby`):

```html
<div role="dialog" aria-labelledby="heading">
  <h2 id="heading">Title</h2>
</div>
```

The `Modal.Header` component already handles the accessibility part, so I just use it here instead of having to wire things ourselves.

---

`Modal.Header` and `Modal.Body` both have a bottom border to separate the modal sections. Donation modal lays its content out differently and doesn't need a border, hence the `borderless` prop.

And probably you can tell by now, I've been trying hard to avoid having to support the `className` prop. I think having multiple props for specific things allows us to consider the styling more carefully, as opposed to supporting just `className`. which would blow the door wide open for inconsistencies.

Code after:
  donationAnimationFlag
}: {
  recentlyClaimedBlock: RecentlyClaimedBlock;
  showHeaderAndFooter: boolean;
  donationAttempted: boolean;
  showForm: boolean;
  donationAnimationFlag: boolean;
}) {
  const { t } = useTranslation();

  if (!showHeaderAndFooter || donationAttempted) {
    return null;
  } else if (!donationAnimationFlag) {
    return (
      <Row className='text-center block-modal-text'>
        <Col sm={10} smOffset={1} xs={12}>
          {recentlyClaimedBlock !== null && (
            <b>
              {t('donate.nicely-done', {
                block: t(
                  `intro:${recentlyClaimedBlock.superBlock}.blocks.${recentlyClaimedBlock.block}.title`
                )
              })}
            </b>
          )}
          <Modal.Header showCloseButton={false} borderless>
            {t('donate.help-us-develop')}
          </Modal.Header>
        </Col>
      </Row>
    );
  } else if (!showForm) {
    return (
      <Row className='text-center block-modal-text'>
        <Col sm={10} smOffset={1} xs={12}>
          <Modal.Header showCloseButton={false} borderless>
            {t('donate.modal-benefits-title')}
          </Modal.Header>
        </Col>
      </Row>
    );
  } else {
    return null;
  }
}

function CloseButtonRow({
  donationAttempted,
  closeDonationModal
}: {
  donationAttempted: boolean;