mirror of
				https://github.com/beestat/app.git
				synced 2025-10-31 01:57:01 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			266 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			266 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /**
 | |
|  * Modal
 | |
|  */
 | |
| beestat.component.modal = function() {
 | |
|   beestat.component.apply(this, arguments);
 | |
| };
 | |
| beestat.extend(beestat.component.modal, beestat.component);
 | |
| 
 | |
| beestat.component.modal.prototype.decorate_ = function() {
 | |
|   var self = this;
 | |
| 
 | |
|   var mask = $.createElement('div')
 | |
|     .style({
 | |
|       'position': 'fixed',
 | |
|       'top': '0',
 | |
|       'left': '0',
 | |
|       'width': '100%',
 | |
|       'height': '100%',
 | |
|       'vertical-align': 'middle',
 | |
|       'transition': 'background 200ms ease'
 | |
|     });
 | |
|   $('body').appendChild(mask);
 | |
| 
 | |
|   var modal = $.createElement('div');
 | |
|   beestat.style.set(
 | |
|     modal,
 | |
|     {
 | |
|       'max-width': '700px',
 | |
|       'padding': beestat.style.size.gutter,
 | |
|       'position': 'absolute',
 | |
|       'top': '100px',
 | |
|       'left': '50%',
 | |
|       'transform': 'translateX(-50%)',
 | |
|       'width': '100%',
 | |
|       'transition': 'transform 200ms ease'
 | |
|     },
 | |
|     {
 | |
|       '(max-width: 900px)': {
 | |
|         'top': '0px'
 | |
|       }
 | |
|     }
 | |
|   );
 | |
| 
 | |
|   modal.style('transform', 'translateX(-50%) scale(0)');
 | |
| 
 | |
|   mask.appendChild(modal);
 | |
| 
 | |
|   this.modal_content_ = $.createElement('div');
 | |
|   beestat.style.set(
 | |
|     this.modal_content_,
 | |
|     {
 | |
|       'background': '#fff',
 | |
|       'padding': beestat.style.size.gutter,
 | |
|       'color': beestat.style.color.bluegray.dark,
 | |
|       'max-height': 'calc(100vh - ' + (200 + (beestat.style.size.gutter * 2)) + 'px)',
 | |
|       'overflow': 'auto',
 | |
|       'border-radius': beestat.style.size.border_radius,
 | |
|       'min-height': '200px'
 | |
|     },
 | |
|     {
 | |
|       '(max-width: 900px)': {
 | |
|         'max-height': 'calc(100vh - ' + (beestat.style.size.gutter * 2) + 'px)'
 | |
|       }
 | |
|     }
 | |
|   );
 | |
| 
 | |
|   modal.appendChild(this.modal_content_);
 | |
| 
 | |
|   this.mask_ = mask;
 | |
|   this.modal_ = modal;
 | |
| 
 | |
|   /*
 | |
|    * Blur the body
 | |
|    * Fade in the mask
 | |
|    * Overpop the modal
 | |
|    */
 | |
|   this.timeout_1_ = window.setTimeout(function() {
 | |
|     $('body').firstElementChild()
 | |
|       .style('filter', 'blur(3px)');
 | |
|     mask.style('background', 'rgba(0, 0, 0, 0.5)');
 | |
|     modal.style('transform', 'translateX(-50%) scale(1.05)');
 | |
|   }, 0);
 | |
| 
 | |
|   // Pop the modal back to normal size
 | |
|   this.timeout_2_ = window.setTimeout(function() {
 | |
|     modal.style('transform', 'translateX(-50%) scale(1)');
 | |
|   }, 250);
 | |
| 
 | |
|   // Escape to close
 | |
|   $(window).addEventListener('keydown.modal', function(e) {
 | |
|     if (e.which === 27) {
 | |
|       self.dispose();
 | |
|     }
 | |
|   });
 | |
| 
 | |
|   // Click the mask to close
 | |
|   $(window).addEventListener('click.modal', function(e) {
 | |
|     if (e.target === mask[0]) {
 | |
|       self.dispose();
 | |
|     }
 | |
|   });
 | |
| 
 | |
|   this.decorate_header_(this.modal_content_);
 | |
|   this.decorate_contents_(this.modal_content_);
 | |
|   this.decorate_buttons_(this.modal_content_);
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * Close the currently open modal.
 | |
|  */
 | |
| beestat.component.modal.prototype.dispose = function() {
 | |
|   if (this.rendered_ === true) {
 | |
|     var self = this;
 | |
| 
 | |
|     window.clearTimeout(this.timeout_1_);
 | |
|     window.clearTimeout(this.timeout_2_);
 | |
| 
 | |
|     this.modal_.style('transform', 'translateX(-50%) scale(0)');
 | |
|     this.mask_.style('background', 'rgba(0, 0, 0, 0)');
 | |
|     $('body').firstElementChild()
 | |
|       .style('filter', '');
 | |
| 
 | |
|     window.setTimeout(function() {
 | |
|       self.modal_.parentNode().removeChild(self.modal_);
 | |
|       self.mask_.parentNode().removeChild(self.mask_);
 | |
| 
 | |
|       delete self.mask_;
 | |
|       delete self.modal_;
 | |
|     }, 200);
 | |
| 
 | |
|     $(window).removeEventListener('keydown.modal');
 | |
|     $(window).removeEventListener('click.modal');
 | |
| 
 | |
|     this.rendered_ = false;
 | |
|   }
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * Overridden rerender function which just brazenly deletes content and writes
 | |
|  * it again. RIP event listeners. Had to do this since modal rendering does
 | |
|  * all the fancy animation and that is not desirable when rerendering.
 | |
|  */
 | |
| beestat.component.modal.prototype.rerender = function() {
 | |
|   if (this.rendered_ === true) {
 | |
|     this.modal_content_.innerHTML('');
 | |
|     this.decorate_header_(this.modal_content_);
 | |
|     this.decorate_contents_(this.modal_content_);
 | |
|     this.decorate_buttons_(this.modal_content_);
 | |
|   }
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * Decorate the header bar with the title and close icon.
 | |
|  *
 | |
|  * @param {rocket.Elements} parent
 | |
|  */
 | |
| beestat.component.modal.prototype.decorate_header_ = function(parent) {
 | |
|   var row = $.createElement('div')
 | |
|     .style({
 | |
|       'display': 'flex',
 | |
|       'align-items': 'center'
 | |
|     });
 | |
|   parent.appendChild(row);
 | |
| 
 | |
|   var column_title = $.createElement('div')
 | |
|     .style({
 | |
|       'flex': '1'
 | |
|     });
 | |
|   row.appendChild(column_title);
 | |
|   this.decorate_title_(column_title);
 | |
| 
 | |
|   var column_close = $.createElement('div')
 | |
|     .style({
 | |
|       'flex': '0 0 50px',
 | |
|       'text-align': 'right'
 | |
|     });
 | |
|   row.appendChild(column_close);
 | |
|   this.decorate_close_(column_close);
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * Decorate the title of the modal.
 | |
|  *
 | |
|  * @param {rocket.Elements} parent
 | |
|  */
 | |
| beestat.component.modal.prototype.decorate_title_ = function(parent) {
 | |
|   var title = this.get_title_();
 | |
|   if (title !== undefined) {
 | |
|     parent.appendChild($.createElement('div')
 | |
|       .innerHTML(title)
 | |
|       .style({
 | |
|         'font-weight': beestat.style.font_weight.bold,
 | |
|         'font-size': beestat.style.font_size.extra_large,
 | |
|         'white-space': 'nowrap',
 | |
|         'overflow': 'hidden',
 | |
|         'text-overflow': 'ellipsis'
 | |
|       }));
 | |
|   }
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * Decorate the close button.
 | |
|  *
 | |
|  * @param {rocket.Elements} parent
 | |
|  */
 | |
| beestat.component.modal.prototype.decorate_close_ = function(parent) {
 | |
|   var self = this;
 | |
| 
 | |
|   var close = new beestat.component.tile()
 | |
|     .set_type('pill')
 | |
|     .set_shadow(false)
 | |
|     .set_icon('close')
 | |
|     .set_text_color(beestat.style.color.gray.dark)
 | |
|     .set_background_hover_color(beestat.style.color.gray.light)
 | |
|     .addEventListener('click', function() {
 | |
|       self.dispose();
 | |
|     });
 | |
|   close.render(parent);
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * Decorate the contents of the modal.
 | |
|  */
 | |
| beestat.component.modal.prototype.decorate_contents_ = function() {
 | |
|   // Stub
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * Get the buttons that go on the bottom of this modal.
 | |
|  *
 | |
|  * @return {[beestat.component.button]} The buttons.
 | |
|  */
 | |
| beestat.component.modal.prototype.get_buttons_ = function() {
 | |
|   return [];
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * Decorate the buttons on the bottom right of the modal.
 | |
|  *
 | |
|  * @param {rocket.Elements} parent
 | |
|  */
 | |
| beestat.component.modal.prototype.decorate_buttons_ = function(parent) {
 | |
|   var buttons = this.get_buttons_();
 | |
|   if (buttons.length > 0) {
 | |
|     var container = $.createElement('div')
 | |
|       .style({
 | |
|         'margin-top': beestat.style.size.gutter,
 | |
|         'text-align': 'right'
 | |
|       });
 | |
|     parent.appendChild(container);
 | |
| 
 | |
|     var tile_group = new beestat.component.tile_group();
 | |
|     buttons.forEach(function(button) {
 | |
|       tile_group.add_tile(button);
 | |
|     });
 | |
|     tile_group.render(container);
 | |
|   }
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * Get the title of the modal.
 | |
|  */
 | |
| beestat.component.modal.prototype.get_title_ = function() {
 | |
|   // Stub
 | |
| };
 |