ef with anime.js

by Yukino Song

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.2.0/anime.min.js"></script>
<script src="https://unpkg.com/ef.js@latest"></script>

SCSS

html, body {
	margin: 0;
	padding: 0;
	height: 100%;
	width: 100%;
}

.container {
	height: 100%;
	width: 100%;
	position: fixed;
	top: 0;
	left: 0;
	background-color: rgba(0, 0, 0, 0.2);
	opacity: 1;
	transition: opacity 0.5s;
	display: flex;
	justify-content: center;
	align-items: center;

	&.hidden {
		opacity: 0;
	}
}

.modal {
	width: 250px;
	height: 110px;
	background: #FFF;
	padding: 12px;
	overflow: hidden;
	border: 1px solid #6fcefc;
	border-radius: 4px;
	
	& h2 {
		margin: 5px 0;
	}
	
	& button {
		float: right;
		margin: 3px;
	}
}

JavaScript

const { t, mountOptions, inform, exec } = ef

const Body = t`
>body
  >button
    @click = showModal
    .Show Modal
  >input
  	%value = {{title = Title}}
    #placeholder = Title
  >input
  	%value = {{msg = Message}}
    #placeholder = Message
  -modal
`

const ModalTpl = t`
>div.container.{{hidden = hidden}}
  >div.modal
    #style = transform: scale({{scale}})
    >h2
      .{{title}}
    >p
      .{{msg}}
    >button
      @click.stop = cancel
      .CANCEL
    >button
      @click = ok
      .OK
`

const modalInitialState = {
  $data: {
    title: 'Alert',
    msg: 'This is a pop up modal',
    scale: 0
  },
  $methods: {
    ok({state}) {
      state.$umount()
      console.log('You have comfirmed the action.')
    },
    cancel({state}) {
      state.$umount()
      console.log('You have canceld the action.')
    }
  }
}

class MyModal extends ModalTpl {
  constructor(state) {
    super(Object.assign({}, modalInitialState, state))
  }

  // Adding hooks to mount method
  $mount(...args) {
    super.$mount(...args)
    this.$data.hidden = ''
    anime({
      targets: this.$data,
      scale: 1,
      duration: 500,
    })
    console.log('The modal has been mounted!')
  }

  // Do something before unmounting
  $umount() {
    this.$data.hidden = 'hidden'
    anime({
      targets: this.$data,
      scale: 0,
      duration: 500,
      complete: () => {
        super.$umount()
      }
    })
  }
}

const modal = new MyModal()

;(new Body({
  $methods: {
    showModal({state}) {
    	inform()
    	modal.$data.title = state.$data.title
      modal.$data.msg = state.$data.msg
      state.modal = modal
      exec()
    }
  }
})).$mount({target: document.body, option: mountOptions.REPLACE})