@nteract/outputs
Version:
components for rendering outputs
89 lines (88 loc) • 3.41 kB
JavaScript
"use strict";
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const React = __importStar(require("react"));
const styled_components_1 = __importDefault(require("styled-components"));
const ErrorFallbackDiv = styled_components_1.default.div `
background-color: ghostwhite;
color: black;
font-weight: 600;
display: block;
padding: 10px;
margin-bottom: 20px;
`;
const ErrorFallback = (caught) => (React.createElement(ErrorFallbackDiv, null,
React.createElement("h3", null, caught.error.toString()),
React.createElement("details", null,
React.createElement("summary", null, "stack trace"),
React.createElement("pre", null, caught.info.componentStack))));
class RichMedia extends React.PureComponent {
constructor() {
super(...arguments);
this.state = {};
this.choose = (children) => {
// We must pick only one child to render
let chosenOne = null;
const data = this.props.data;
// Find the first child element that matches something in this.props.data
React.Children.forEach(children, child => {
if (chosenOne) {
// Already have a selection
return;
}
const childElement = child;
if (!childElement ||
typeof childElement !== "object" ||
!("type" in childElement)) {
return;
}
if (childElement.type === RichMedia) {
// One of our children is itself a RichMedia we can defer to
chosenOne = this.choose(childElement.props.children);
return;
}
if (childElement.props &&
childElement.props.mediaType &&
childElement.props.mediaType in data) {
chosenOne = childElement;
return;
}
});
return chosenOne;
};
}
componentDidCatch(error, info) {
this.setState({ caughtError: { error, info } });
}
render() {
if (this.state.caughtError) {
return this.props.renderError(Object.assign(Object.assign({}, this.state.caughtError), { data: this.props.data, metadata: this.props.metadata, children: this.props.children }));
}
const chosenOne = this.choose(this.props.children);
// If we didn't find a match, render nothing
if (chosenOne === null || !chosenOne.props.mediaType) {
return null;
}
const mediaType = chosenOne.props.mediaType;
return React.cloneElement(chosenOne, {
data: this.props.data[mediaType],
metadata: this.props.metadata[mediaType]
});
}
}
exports.RichMedia = RichMedia;
RichMedia.defaultProps = {
data: {},
metadata: {},
renderError: ErrorFallback
};
exports.default = RichMedia;