Big refactor: ts/ directory for all typescript, including react
Split out test-specific and general utility react components too. And moved our test/legacy* files for the Style Guide into a styleguide/ subdirectory of test/. I think we'll be able to live in this directory structure for a while.
This commit is contained in:
parent
50d4dbaae7
commit
23537546fe
18 changed files with 54 additions and 37 deletions
69
ts/components/utility/BackboneWrapper.tsx
Normal file
69
ts/components/utility/BackboneWrapper.tsx
Normal file
|
@ -0,0 +1,69 @@
|
|||
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: Element | 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;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue