You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			70 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			70 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			TypeScript
		
	
| import React from 'react';
 | |
| 
 | |
| interface Props {
 | |
|   /** The View class, which will be instantiated then treated like a Backbone View */
 | |
|   readonly View: BackboneViewConstructor;
 | |
|   /** Options to be passed along to the view when constructed */
 | |
|   readonly options: object;
 | |
| }
 | |
| 
 | |
| interface BackboneView {
 | |
|   remove: () => void;
 | |
|   render: () => void;
 | |
|   el: HTMLElement;
 | |
| }
 | |
| 
 | |
| interface BackboneViewConstructor {
 | |
|   new (options: object): BackboneView;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Allows Backbone Views to be rendered inside of React (primarily for the Style Guide)
 | |
|  * while we slowly replace the internals of a given Backbone view with React.
 | |
|  */
 | |
| export class BackboneWrapper extends React.Component<Props, {}> {
 | |
|   protected el: HTMLElement | null = null;
 | |
|   protected view: BackboneView | null = null;
 | |
| 
 | |
|   public componentWillUnmount() {
 | |
|     this.teardown();
 | |
|   }
 | |
| 
 | |
|   public shouldComponentUpdate() {
 | |
|     // we're handling all updates manually
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   public render() {
 | |
|     return <div ref={this.setEl} />;
 | |
|   }
 | |
| 
 | |
|   protected setEl = (element: HTMLDivElement | null) => {
 | |
|     this.el = element;
 | |
|     this.setup();
 | |
|   };
 | |
| 
 | |
|   protected setup = () => {
 | |
|     const { el } = this;
 | |
|     const { View, options } = this.props;
 | |
| 
 | |
|     if (!el) {
 | |
|       return;
 | |
|     }
 | |
|     this.view = new View(options);
 | |
|     this.view.render();
 | |
| 
 | |
|     // It's important to let the view create its own root DOM element. This ensures that
 | |
|     //   its tagName property actually takes effect.
 | |
|     el.appendChild(this.view.el);
 | |
|   };
 | |
| 
 | |
|   protected teardown() {
 | |
|     if (!this.view) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     this.view.remove();
 | |
|     this.view = null;
 | |
|   }
 | |
| }
 |