react-junctions
Version:
Junction-based routing for React.
125 lines • 5.42 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { BrowserNavigation } from 'junctions';
import { NavigationProvider } from './NavigationProvider';
var renderToString;
try {
// This hack prevents webpack from bundling react-dom/server, but still
// allows it to be loaded when executed within junctions-static's
// jsdom environment.
renderToString = eval('require')('react-dom/server').renderToString;
}
catch (e) { }
var defaultRender = function (route, navigation, location) {
return React.createElement(route[0].component, {
junction: route[0],
env: {
navigation: navigation,
location: location
},
});
};
var navigationIdCounter = 1;
var JunctionNavigation = /** @class */ (function (_super) {
__extends(JunctionNavigation, _super);
function JunctionNavigation(props) {
var _this = _super.call(this, props) || this;
// We need to let the `BrowserNavigation` instance know when rnedering has
// complete, as we need to wait to scroll to any #hash.
_this.handleRenderComplete = function () {
if (_this.renderCompleteCallback) {
_this.renderCompleteCallback();
delete _this.renderCompleteCallback;
}
};
_this.setContainer = function (node) {
_this.containerNode = node;
};
_this.handleRouteChange = function (done) {
_this.renderCompleteCallback = done;
_this.setState({
route: _this.navigation.getRoute(),
waitingForInitialContent: false,
});
};
var root = props.root, history = props.history, followRedirects = props.followRedirects, announceTitle = props.announceTitle, setDocumentTitle = props.setDocumentTitle, waitForInitialContent = props.waitForInitialContent, disableScrollHandling = props.disableScrollHandling, _a = props.addToContext, addToContext = _a === void 0 ? true : _a;
_this.addToContext = addToContext;
_this.navigation = new BrowserNavigation({
rootJunctionTemplate: root,
history: history,
followRedirects: followRedirects,
announceTitle: announceTitle,
setDocumentTitle: setDocumentTitle,
disableScrollHandling: disableScrollHandling,
});
_this.navigation.subscribe(_this.handleRouteChange, {
waitForInitialContent: waitForInitialContent
});
if (!waitForInitialContent || !_this.navigation.isBusy()) {
_this.state = {
route: _this.navigation.getRoute()
};
}
else {
try {
_this.serverRenderedHTML = document.getElementById('JUNCTIONS_STATIC').innerHTML;
_this.shouldHydrate = true;
}
catch (e) {
_this.serverRenderedHTML = '';
}
_this.state = {
waitingForInitialContent: true,
};
}
return _this;
}
JunctionNavigation.prototype.render = function () {
// If we're rendering this server side, we need to actually render the
// content. Otherwise, we'll use whatever content the server rendered
// (if any).
var string = renderToString
? renderToString(this.getElementToRender())
: this.serverRenderedHTML;
return (React.createElement("div", { ref: this.setContainer, className: this.props.className, style: this.props.style,
// Because this element's props never changes, React will never
// re-render this string to the DOM, even if the corresponding DOM
// node's children do change.
dangerouslySetInnerHTML: { __html: string } }));
};
JunctionNavigation.prototype.componentDidMount = function () {
this.renderChildren();
};
JunctionNavigation.prototype.componentDidUpdate = function () {
this.renderChildren();
};
JunctionNavigation.prototype.getElementToRender = function () {
var render = this.props.render || defaultRender;
var content = render(this.state.route, this.navigation, this.navigation.getLocation());
if (this.addToContext) {
return (React.createElement(NavigationProvider, { navigation: this.navigation }, content));
}
else {
return content;
}
};
JunctionNavigation.prototype.renderChildren = function () {
if (!this.state.waitingForInitialContent) {
var renderer = this.shouldHydrate ? ReactDOM.hydrate : ReactDOM.render;
renderer(this.getElementToRender(), this.containerNode, this.handleRenderComplete);
}
};
return JunctionNavigation;
}(React.Component));
export { JunctionNavigation };
//# sourceMappingURL=JunctionNavigation.js.map