Chapter 11

tailwindcss modal / モーダル ダイアログ

knaka Tech-Blog
knaka Tech-Blog
2021.05.06に更新

概要:

modalの例になります。

  • CSS modal を、参考にした例となります

関連

https://myscreate.com/modal-without-jquery/

  • CSSの参考コード / HTML

https://gist.github.com/kuc-arc-f/ea9f742e0aa0ee1fbfad0d290a7d2462


next.js + tailwindcss の例

  • next.js に組み込んだ例です

画面


参考のコード , next.js

https://github.com/kuc-arc-f/nextjs_3_17modal_2

実装など

pages/test_modal.jsx

  • modal componentを読込、使用します

  • componentDidMount, id=openModal で、modal開く イベント追加

  • this.state.modal_name : modal idを指定します

  • <Modal> で、name:モーダル名、title=タイトル文字、body=本文 を渡します

test_modal.jsx
import React from 'react';
import Layout from '../components/layout'
import Modal from '../components/modal'
//
class Page extends React.Component {
  constructor() {
    super();
    this.state = {
      modal_name:"modalArea1" ,
    };
  }
  componentDidMount(){
    const openModal = document.getElementById('openModal');
    const modalArea = document.getElementById(this.state.modal_name);
    openModal.addEventListener('click',function(){
      modalArea.classList.toggle('is-show');
    },false);  
  }
  render() {
    return (
    <div className="bg-gray-100">
      <Layout>
      <div className="container mx-auto px-5 pb-5 bg-white">
        <h1 className="text-5xl font-bold my-2">Modal-Test</h1>
        <hr className="my-2" /> 
        modal:  
        <hr className="my-2" /> 
        <button className="btn-blue" id="openModal">Open modal
        </button>
        <Modal name={this.state.modal_name}
          title="Modal-test" 
          body={`モーダルの本文の入力テスト、11111
          モーダルの本文の入力テスト、22222`}>
        </Modal>
      </div>
      </Layout>
      <style>{`
      .is-show {
        visibility: visible;
        opacity : 1;
      }
      `}</style>       
    </div>
    );
  }
}
export default Page;

components/modal.jsx

  • 閉じるイベント処理等を、追加
modal.jsx
export default class Page extends React.Component {
  constructor(props){
    super(props)
//console.log(this.props.name)
    this.state = {
      modalCloseName: this.props.name + "-closeModal" ,
      modalBgName: this.props.name + "-modalBg" ,
    };
  }  
  componentDidMount(){
    const modalArea = document.getElementById(this.props.name);
    const closeModal = document.getElementById(this.state.modalCloseName);
    const modalBg = document.getElementById(this.state.modalBgName);
    const toggle = [closeModal,modalBg];
    var len = 0;
    for(var i=0, len=toggle.length ; i<len ; i++){
      toggle[i].addEventListener('click',function(){
        modalArea.classList.toggle('is-show');
      },false);
    }
  }  
  render(){
    return (
    <div className="modal_wrap">
      <section id={this.props.name} className="modalArea">
        <div id={this.state.modalBgName} className="modalBg"></div>
        <div className="modalWrapper rounded-lg">
          <div className="modalContents">
            <h3 className="text-3xl font-bold">{this.props.title}
            </h3>
            <hr className="my-2" />
            <p>{this.props.body}</p>
            <hr className="my-2" / >
            <button className="closeModal btn-blue" id={this.state.modalCloseName}>
              Close</button>
          </div>
        </div>
      </section>
      <style>{`
      .modalArea {
        visibility: hidden;
        opacity : 0;  
        position: fixed;
        z-index: 10;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        transition: .4s;
      }
      .modalBg {
        width: 100%;
        height: 100%;
        background-color: rgba(30,30,30,0.9);
      }
      .modalWrapper {
        position: absolute;
        top: 50%;
        left: 50%;
        transform:translate(-50%,-50%);
        width: 70%;
        max-width: 500px;
        padding: 10px 30px;
        background-color: #fff;
      }
      `}</style>
    </div>
    )
  }

....