<main class="main-wrapper">
    <div id="modal-dialog" class="modal-dialog">
        <button type="button" id="dialog-open" class="dialog-open">
            モーダルダイアログ<br>
            (モーダルウインドウ)を開く
        </button>
        <dialog id="dialog-panel" class="dialog-panel" role="dialog" aria-describedby="d-message">
            <p id="d-message" class="dialog-panel__paragraph" role="document">
                モーダルダイアログ(モーダルウインドウ)<br class="display-tbdt">
                とはどんなものか知っていますか?
            </p>
            <div class="dialog-panel__buttons">
                <button type="button" id="dialog-yes" class="dialog-panel__button">
                    はい
                </button>
                <button type="button" id="dialog-no" class="dialog-panel__button">
                    いいえ
                </button>
            </div>
            <button type="button" id="dialog-close" class="dialog-panel__close" aria-label="このモーダルダイアログを閉じる">
                <span class="positioning">×</span>
            </button>
        </dialog>
        <p class="dialog-response">
            ダイアログの返り値:<br>
            <em><span id="return-value"></span></em>
        </p>
    </div>
</main>
<main class="main-wrapper">
  <div id="modal-dialog" class="modal-dialog">
    <button type="button" id="dialog-open" class="dialog-open">
      モーダルダイアログ<br>
      (モーダルウインドウ)を開く
    </button>
    <dialog
      id="dialog-panel"
      class="dialog-panel"
      role="dialog"
      aria-describedby="d-message"
    >
      <p id="d-message" class="dialog-panel__paragraph" role="document">
        モーダルダイアログ(モーダルウインドウ)<br class="display-tbdt">
        とはどんなものか知っていますか?
      </p>
      <div class="dialog-panel__buttons">
        <button type="button" id="dialog-yes" class="dialog-panel__button">
          はい
        </button>
        <button type="button" id="dialog-no" class="dialog-panel__button">
          いいえ
        </button>
      </div>
      <button
        type="button"
        id="dialog-close"
        class="dialog-panel__close"
        aria-label="このモーダルダイアログを閉じる"
      >
        <span class="positioning">×</span>
      </button>
    </dialog>
    <p class="dialog-response">
      ダイアログの返り値:<br>
      <em><span id="return-value"></span></em>
    </p>
  </div>
</main>
/* No context defined. */
  • Content:
    /* /js/modules/ModalDialog.js */
    
    /**
     * ModalDialog UI class
     */
    export class ModalDialog {
      constructor(id1) {
        this.wrap = document.getElementById(id1);
        this.open = document.getElementById('dialog-open');
        this.dialog = document.querySelector(".dialog-panel[role='dialog']");
        this.yes = document.getElementById('dialog-yes');
        this.no = document.getElementById('dialog-no');
        this.close = document.getElementById('dialog-close');
        this.returnSpan = document.getElementById('return-value');
        this.openflag = true;
    
        if(this.wrap != null) {
          // eslint-disable-next-line no-undef
          dialogPolyfill.registerDialog(this.dialog);
        }
      }
      showDialog() {
        if(this.wrap != null && !this.dialog.hasAttribute('open')) {
          this.open.addEventListener('click', () => {
            if(this.openflag === true) {
              this.dialog.showModal();
              this.dialog.style.display = 'block';
              this.dialog.style.visibility = 'visible';
              this.dialog.classList.remove('is-motioned');
              this.dialog.setAttribute('tabindex', '0');
              this.dialog.focus();
              this.fixBackdrop();
    
              this.openflag = false;
            }
          });
        }
        this.opneflag = false;
      }
      hideDialog() {
        if(this.wrap != null) {
          this.yes.addEventListener('click', () => {
            if(this.dialog.hasAttribute('open')) {
              this.hideProcess('はい');
              this.unfixBackdrop();
            }
          });
          this.no.addEventListener('click', () => {
            if(this.dialog.hasAttribute('open')) {
              this.hideProcess('いいえ');
              this.unfixBackdrop();
            }
          });
          this.close.addEventListener('click', () => {
            if(this.dialog.hasAttribute('open')) {
              this.hideProcess('きみ、閉じるボタンを押したね...');
              this.unfixBackdrop();
            }
          });
          this.dialog.addEventListener('cancel', () => {
            if(this.dialog.hasAttribute('open')) {
              this.hideProcess('Escapeボタン押しました?');
              this.unfixBackdrop();
            }
          });
          this.dialog.addEventListener('click', (event) => {
            if (event.target === this.dialog && this.dialog.hasAttribute('open')) {
              this.hideProcess('きみ、ウインドウの外を押したね...');
              this.unfixBackdrop();
            }
          });
        }
      }
      fixBackdrop() {
        const body = document.body;
        const scrollY = document.documentElement.style.getPropertyValue('--scroll-y');
        body.style.position = 'fixed';
        body.style.top = `-${scrollY}`;
        body.style.width = '100%';
        body.style.overflow = 'hidden';
      }
      unfixBackdrop() {
        const body = document.body;
        const scrollY = body.style.top;
        body.style.position = '';
        body.style.top = '';
        body.style.width = '';
        body.style.overflow = '';
        window.scrollTo(0, parseInt(scrollY || '0') * -1);
      }
      hideProcess(resText) {
        this.dialog.close(resText);
        this.dialog.classList.add('is-motioned');
        this.wrap.setAttribute('tabindex', '0');
        this.wrap.focus();
        setTimeout(() => {
          this.dialog.style.visibility = 'hidden';
          this.dialog.style.display = 'none';
          this.openflag = true;
        }, 200);
      }
      respondValue() {
        if(this.wrap != null) {
          this.dialog.addEventListener('close', () => {
            this.returnSpan.innerHTML = this.dialog.returnValue;
          });
        }
      }
    }
    
    /* /js/main.js */
    
    import { ModalDialog } from './modules/ModalDialog.js';
    
    const modalDialog = new ModalDialog('modal-dialog');
    modalDialog.showDialog();
    modalDialog.hideDialog();
    modalDialog.respondValue();
  • URL: /components/raw/modal-dialog/index.js
  • Filesystem Path: src/components/2-dynamic-ui/modal-dialog/index.js
  • Size: 3.6 KB
  • Content:
    .modal-dialog {
      position: relative;
      width: 100%;
      height: calc(100vh - 6rem);
      max-width: 60rem;
      margin: auto;
    }
    .modal-dialog:hover, .modal-dialog:focus {
      outline: none;
    }
    
    .dialog-open {
      display: block;
      width: 100%;
      max-width: 300px;
      min-width: fit-content;
      margin: auto auto 4rem;
      padding: 1rem;
      border: 1px solid var(--border-color);
      text-align: center;
      border-radius: 5px;
    }
    .dialog-open:hover, .dialog-open:focus {
      background-color: #777;
      color: var(--white);
    }
    
    .dialog-panel {
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      width: fit-content;
      height: fit-content;
      margin: auto;
      padding: 0;
      border: 2px solid var(--border-color);
      background: var(--white);
      border-radius: 5px;
      /* native backdrop */
      /* polyfill backdrop */
    }
    .dialog-panel:not([open]) {
      display: block;
      visibility: hidden;
    }
    .dialog-panel[open] {
      animation: fade-in .25s ease-out, slide-down .25s ease-out;
    }
    .dialog-panel.is-motioned {
      max-width: calc(100% - 6px - 2em);
      max-height: calc(100% - 6px - 2em);
      animation: fade-out .45s ease, slide-up .45s ease;
    }
    .dialog-panel::backdrop {
      background-color: hsla(0, 0%, 0%, .5);
      animation: backdrop-fade-in .35s ease-out;
    }
    .dialog-panel + .backdrop {
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      background-color: hsla(0, 0%, 0%, .5);
      animation: fade-in .25s ease-out;
    }
    
    /* Safariのみ適用 */
    _::-webkit-full-page-media,
    _:future,
    :root .dialog-panel {
      width: 100%;
      max-width: 365px;
    }
    
    /* Edgeのみ適用 */
    @supports (-ms-ime-align: auto) {
      .dialog-panel {
        max-width: 30%;
      }
    }
    .dialog-panel__paragraph {
      margin: auto;
      padding: 3.5rem 3rem 0;
    }
    
    .dialog-panel__buttons {
      padding: 2rem 0 3.5rem;
      text-align: center;
    }
    
    .dialog-panel__button {
      display: inline-block;
      min-width: 5rem;
      padding-top: .625rem;
      padding-bottom: .525rem;
      border: 1px solid var(--border-color);
      text-align: center;
      line-height: 1.5;
      border-radius: 5px;
    }
    .dialog-panel__button:not(:first-of-type) {
      margin-left: 1.75rem;
    }
    .dialog-panel__button:hover, .dialog-panel__button:focus {
      background-color: #777;
      color: var(--white);
    }
    
    .dialog-panel__close {
      position: absolute;
      top: 1rem;
      right: 1rem;
      width: 2.3rem;
      height: 2.3rem;
      background-color: var(--black);
      font-size: 2rem;
      color: var(--white);
      border-radius: 50%;
    }
    .dialog-panel__close:hover, .dialog-panel__close:focus {
      border: 1px solid #777;
      background-color: var(--white);
      color: var(--black);
    }
    .dialog-panel__close:hover > .positioning, .dialog-panel__close:focus > .positioning {
      line-height: 1.9rem;
    }
    .dialog-panel__close > .positioning {
      display: block;
      height: 2.3rem;
      line-height: 2rem;
    }
    
    .dialog-response {
      text-align: center;
      line-height: 2;
      font-size: 1.2rem;
    }
    
    @keyframes fade-in {
      0% {
        opacity: 0;
      }
      100% {
        opacity: 1;
      }
    }
    @keyframes fade-out {
      0% {
        opacity: 1;
      }
      100% {
        opacity: 0;
      }
    }
    @keyframes slide-down {
      0% {
        opacity: 0;
        transform: translate(0, -1rem);
      }
      100% {
        opacity: 1;
        transform: translate(0, 0);
      }
    }
    @keyframes slide-up {
      0% {
        opacity: 1;
        transform: translate(0, 0);
      }
      100% {
        opacity: 0;
        transform: translate(0, -1rem);
      }
    }
    @keyframes backdrop-fade-in {
      0% {
        background-color: hsla(0, 0%, 0%, 0);
      }
      100% {
        background-color: hsla(0, 0%, 0%, .5);
      }
    }
    @keyframes backdrop-fade-out {
      0% {
        background-color: hsla(0, 0%, 0%, .5);
      }
      100% {
        background-color: hsla(0, 0%, 0%, 0);
      }
    }
  • URL: /components/raw/modal-dialog/style.css
  • Filesystem Path: src/components/2-dynamic-ui/modal-dialog/style.css
  • Size: 3.6 KB

No notes defined.