portals

by kkdaily

HTML

<div id="app"></div>

CSS

body {
  background: #e6e6e6;
  padding: 20px;
  font-family: Helvetica;
}

.App {
  display: flex;
}

.image-panel {
  display: flex;
  flex-direction: column;
  background-size: cover;
  background-position: center;
  width: 100%;
  height: 70vh;
  cursor: pointer;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

.done {
  color: rgba(0, 0, 0, 0.3);
  text-decoration: line-through;
}

input {
  margin-right: 5px;
}

React

class ImagePopup extends React.Component {
  constructor(props) {
    super(props);
    this.externalWindow = null;
    this.containerDiv = document.createElement('div')
  }
  
  createPopup() {
    this.externalWindow = window.open('', 'imagePopup', 'width=500,height=500');

    if (this.externalWindow.document) {
    	this.externalWindow.document.body.appendChild(this.containerDiv)
    }
  }

  componentDidMount() {
    this.createPopup()
    // if the popup window is closed, reset the selected image to null and create a new hidden popup
    this.externalWindow.addEventListener('beforeunload', () => {
    	this.props.onClose()
      this.createPopup()
    });
  }
  
  render() {
    return ReactDOM.createPortal(
    	<div>
        <h1>{this.props.image.title}</h1>
        <img src={this.props.image.src} />
      </div>, 
      this.containerDiv
    );
  }
}

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
    	imageData: [
      	{ 
        	id: 1, 
          title: 'Dog', 
          src: 'https://cache.desktopnexus.com/thumbseg/2324/2324195-bigthumbnail.jpg'
        }, { 
        	id: 2, 
          title: 'Birbs', 
          src: 'https://i.pinimg.com/originals/df/3a/35/df3a357c8866f9f5a831472c866d158a.jpg'
        }, { 
        	id: 3, 
          title: 'Cat', 
          src: 'https://img0.ropose.com/story/9FD9_1525013319444_98380a01_a545_350x422.webp'
       	}
      ],
      selectedImage: null
    }
    this.clearSelectedImage = this.clearSelectedImage.bind(this)
  }


// This updates the title of the image being viewed in the popup window. This is called whenever the 'save' button in said popup window is clicked.
  updateImageTitle(newTitle, imageId) {
  	const updatedImageData = this.state.imageData.map(image => {
    	if (image.id === imageId) {
      	image.title = newTitle
      }
    })
 
		this.setState({
    	imageData: updatedImageData
    })
  }
  
  clearSelectedImage() {
  	this.setState({
   ...