How they made controls at Github? Modal dialog
Tags: javascript, html, css, github
Published: 2022-01-05 05:18:25

- Episode1: [Dropdown](https://dev.to/kiranmantha/how-they-made-controls-at-github-1h18)
- Episode2: **Modal dialog**
- Episode3: [Hamburger menu](https://dev.to/kiranmantha/how-they-made-controls-at-github-hamburger-menu-20k)
- Episode4: [Popup](https://dev.to/kiranmantha/how-they-made-controls-at-github-popup-2omi)

## Recap
In previous episode we saw how to create a dropdown using details and summary tags. 

## Present
In this episode let's see how to create a modal dialog out of details and summary tags.

When we say modal dialog, it should contain 2 main things.
1. an overlay
2. a container to display content

let's start with html
```html
<details role='dialog'>
    <summary>click me to open a dialog</summary>
    <div>I'm in a dialog. click outside to close me.</div>
</details>
```

when rendered, this displays in an accordion fashion. so let's style it to look like a dialog.

```scss
:root {
  --border-color: #ccc;
  --spacing: 1rem;
  --primary: #fff;
}

details[role='dialog'] {
  display: inline-block;

  summary {
    cursor: pointer;
    border: 1px solid var(--border-color);
    padding: 10px;
  }

  summary + div {
    position: fixed;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    margin: calc(var(--spacing) * 2) auto;
    width: 500px;
    background-color: var(--primary);
    z-index: 2;
    padding: var(--spacing);
  }
}
```

all is good. The dialog says `click outside to close me`. heck but where is the overlay?? :confused:
you know the secret sauce for this in last episode:exclamation::exclamation:

tadaaaaa
```scss
  &[open] summary {
    &::before {
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      z-index: 1;
      display: block;
      cursor: default;
      content: ' ';
      background-color: rgba(0, 0, 0, 0.5);
    }
  }
```
yeahh got it?? but small change. In last episode, the `background-color` of `summary` tag is _transparent_ but here in order to give user a sense of overlay we slapped color to background. 

Now let's see the entire css:
```scss
:root {
  --border-color: #ccc;
  --spacing: 1rem;
  --primary: #fff;
}

details[role='dialog'] {
  display: inline-block;

  summary {
    cursor: pointer;
    border: 1px solid var(--border-color);
    padding: 10px;
  }

  &[open] summary {
    &::before {
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      z-index: 1;
      display: block;
      cursor: default;
      content: ' ';
      background-color: rgba(0, 0, 0, 0.5);
    }
  }

  summary + div {
    position: fixed;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    margin: calc(var(--spacing) * 2) auto;
    width: 500px;
    background-color: var(--primary);
    z-index: 2;
    padding: var(--spacing);
  }
}
```
That's it. see how simple it is to create a modal dialog?? But this implementation got its own caveats:

1. you can't stop closing the dialog when user clicks outside. So if you intend to use it, then use it for info dialogs where you just display some static content.

## Protips
### Tip:1
when you say modal dialog, you need some handlers to do some actions after dialog opens and after it is closed. Don't worry i got you covered. `Details` tag has `ontoggle` event which helps us in such scenerios.
```javascript
detailsTag.addEventListener('toggle', () => {
  if(detailsTag.open) {
    // do operation when dialog opens
  } else {
    // do operation when dialog closed
  }
})
``` 
### Tip:2
let's say you need to disable backdrop click to close the dialog. In that case, add a data attribute `data-disableBackdropClick` to summary tag and add a little more css to summary tag when dialog has `open` attribute. this is how the html and css looks:

```html
<details id='backdropDetails' role="dialog">
    <summary data-disableBackdropClick="true">click to open a dialog</summary>
    <div>
      i'm in a dialog. i cannot be closed by clicking outside and need javascript to close me.
      <button id='modalCloseButton'>close me</button>
    </div>
</details>
```

```css
....
&[open] summary[data-disableBackdropClick="true"] {
   pointer-events: none;
}
....
```

that's it. now try to click outside the modal. it won't close. Now how to close this dialog. At last we need some javascript to get this done.

```javascript
const closeButton = document.getElementById('modalCloseButton'),
  backdropDetails = document.getElementById('backdropDetails');

closeButton.onclick = function () {
  backdropDetails.open = false;
};
```
yayyyy. now whenever you click on that button, the modal will close but it will not close when you click outside of modal.


Asusual you can find the working example [here](https://stackblitz.com/edit/details-summary-tag-based-controls?file=index.html).

See you in next episode. Thanks..
Kiran :wave: