office-ui-fabric-react
Version:
Reusable React components for building experiences for Office 365.
144 lines (142 loc) • 8.29 kB
JavaScript
define(["require", "exports", "tslib", "react", "../../Utilities", "./Image.Props", "../../Styling", "./Image.scss"], function (require, exports, tslib_1, React, Utilities_1, Image_Props_1, Styling_1, stylesImport) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var styles = stylesImport;
exports.CoverStyleMap = (_a = {},
_a[Image_Props_1.ImageCoverStyle.landscape] = 'ms-Image-image--landscape ' + styles.imageIsLandscape,
_a[Image_Props_1.ImageCoverStyle.portrait] = 'ms-Image-image--portrait ' + styles.imageIsPortrait,
_a);
exports.ImageFitMap = (_b = {},
_b[Image_Props_1.ImageFit.center] = 'ms-Image-image--center ' + styles.imageIsCenter,
_b[Image_Props_1.ImageFit.contain] = 'ms-Image-image--contain ' + styles.imageIsContain,
_b[Image_Props_1.ImageFit.cover] = 'ms-Image-image--cover ' + styles.imageIsCover,
_b[Image_Props_1.ImageFit.none] = 'ms-Image-image--none ' + styles.imageIsNone,
_b);
var KEY_PREFIX = 'fabricImage';
var Image = (function (_super) {
tslib_1.__extends(Image, _super);
function Image(props) {
var _this = _super.call(this, props) || this;
// Make an initial assumption about the image layout until we can
// check the rendered element. The value here only takes effect when
// shouldStartVisible is true.
_this._coverStyle = Image_Props_1.ImageCoverStyle.portrait;
_this.state = {
loadState: Image_Props_1.ImageLoadState.notLoaded
};
return _this;
}
Image.prototype.componentWillReceiveProps = function (nextProps) {
if (nextProps.src !== this.props.src) {
this.setState({
loadState: Image_Props_1.ImageLoadState.notLoaded
});
}
else if (this.state.loadState === Image_Props_1.ImageLoadState.loaded) {
this._computeCoverStyle(nextProps);
}
};
Image.prototype.componentDidUpdate = function (prevProps, prevState) {
this._checkImageLoaded();
if (this.props.onLoadingStateChange
&& prevState.loadState !== this.state.loadState) {
this.props.onLoadingStateChange(this.state.loadState);
}
};
Image.prototype.render = function () {
var imageProps = Utilities_1.getNativeProps(this.props, Utilities_1.imageProperties, ['width', 'height']);
var _a = this.props, src = _a.src, alt = _a.alt, width = _a.width, height = _a.height, shouldFadeIn = _a.shouldFadeIn, className = _a.className, imageFit = _a.imageFit, role = _a.role, maximizeFrame = _a.maximizeFrame;
var loadState = this.state.loadState;
var coverStyle = this.props.coverStyle !== undefined ? this.props.coverStyle : this._coverStyle;
var loaded = loadState === Image_Props_1.ImageLoadState.loaded || (loadState === Image_Props_1.ImageLoadState.notLoaded && this.props.shouldStartVisible);
// If image dimensions aren't specified, the natural size of the image is used.
return (React.createElement("div", { className: Utilities_1.css('ms-Image', styles.root, className, (_b = {},
_b['ms-Image--maximizeFrame ' + styles.rootIsMaximizeFrame] = maximizeFrame,
_b)), style: { width: width, height: height }, ref: this._resolveRef('_frameElement') },
React.createElement("img", tslib_1.__assign({}, imageProps, { onLoad: this._onImageLoaded, onError: this._onImageError, key: KEY_PREFIX + this.props.src || '', className: Utilities_1.css('ms-Image-image', styles.image, exports.CoverStyleMap[coverStyle], (imageFit !== undefined) && exports.ImageFitMap[imageFit], !loaded && 'is-notLoaded', loaded && 'is-loaded ' + styles.imageIsLoaded, shouldFadeIn && 'is-fadeIn', loadState === Image_Props_1.ImageLoadState.error && 'is-error', loaded && shouldFadeIn && Styling_1.AnimationClassNames.fadeIn400, (_c = {},
_c['ms-Image-image--scaleWidth ' + styles.imageIsScaleWidth] = (imageFit === undefined && !!width && !height),
_c['ms-Image-image--scaleHeight ' + styles.imageIsScaleHeight] = (imageFit === undefined && !width && !!height),
_c['ms-Image-image--scaleWidthHeight ' + styles.imageIsScaleWidthHeight] = (imageFit === undefined && !!width && !!height),
_c)), ref: this._resolveRef('_imageElement'), src: src, alt: alt, role: role }))));
var _b, _c;
};
Image.prototype._onImageLoaded = function (ev) {
var _a = this.props, src = _a.src, onLoad = _a.onLoad;
if (onLoad) {
onLoad(ev);
}
this._computeCoverStyle(this.props);
if (src) {
this.setState({
loadState: Image_Props_1.ImageLoadState.loaded
});
}
};
Image.prototype._checkImageLoaded = function () {
var src = this.props.src;
var loadState = this.state.loadState;
if (loadState === Image_Props_1.ImageLoadState.notLoaded) {
// testing if naturalWidth and naturalHeight are greater than zero is better than checking
// .complete, because .complete will also be set to true if the image breaks. However,
// for some browsers, SVG images do not have a naturalWidth or naturalHeight, so fall back
// to checking .complete for these images.
var isLoaded = src && this._imageElement && (this._imageElement.naturalWidth > 0 && this._imageElement.naturalHeight > 0) ||
(this._imageElement.complete && Image._svgRegex.test(src));
if (isLoaded) {
this._computeCoverStyle(this.props);
this.setState({
loadState: Image_Props_1.ImageLoadState.loaded
});
}
}
};
Image.prototype._computeCoverStyle = function (props) {
var imageFit = props.imageFit, width = props.width, height = props.height;
// Do not compute cover style if it was already specified in props
if ((imageFit === Image_Props_1.ImageFit.cover || imageFit === Image_Props_1.ImageFit.contain) &&
this.props.coverStyle === undefined &&
this._imageElement) {
// Determine the desired ratio using the width and height props.
// If those props aren't available, measure measure the frame.
var desiredRatio = void 0;
if (!!width && !!height) {
desiredRatio = width / height;
}
else {
desiredRatio = this._frameElement.clientWidth / this._frameElement.clientHeight;
}
// Examine the source image to determine its original ratio.
var naturalRatio = this._imageElement.naturalWidth / this._imageElement.naturalHeight;
// Should we crop from the top or the sides?
if (naturalRatio > desiredRatio) {
this._coverStyle = Image_Props_1.ImageCoverStyle.landscape;
}
else {
this._coverStyle = Image_Props_1.ImageCoverStyle.portrait;
}
}
};
Image.prototype._onImageError = function (ev) {
if (this.props.onError) {
this.props.onError(ev);
}
this.setState({
loadState: Image_Props_1.ImageLoadState.error
});
};
return Image;
}(Utilities_1.BaseComponent));
Image.defaultProps = {
shouldFadeIn: true
};
Image._svgRegex = /\.svg$/i;
tslib_1.__decorate([
Utilities_1.autobind
], Image.prototype, "_onImageLoaded", null);
tslib_1.__decorate([
Utilities_1.autobind
], Image.prototype, "_onImageError", null);
exports.Image = Image;
var _a, _b;
});
//# sourceMappingURL=Image.js.map