🚨 Latest Research:Tanstack npm Packages Compromised in Ongoing Mini Shai-Hulud Supply-Chain Attack.Learn More
Socket
Book a DemoSign in
Socket

@cloudinary/react

Package Overview
Dependencies
Maintainers
1
Versions
46
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cloudinary/react - npm Package Compare versions

Comparing version
1.0.0-beta.13
to
1.0.0-beta.14
+76
AdvancedImage.d.ts
import React from 'react';
import { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';
import { HtmlImageLayer, Plugins } from '@cloudinary/html';
interface ImgProps {
cldImg: CloudinaryImage;
plugins?: Plugins;
[x: string]: any;
}
/**
* @mixin ReactSDK
* @description The Cloudinary React SDK contains components like <AdvancedImage> to easily render your media assets from Cloudinary.
* The SDK also comes with support for optional js plugins that make the components smart, with features like lazy loading, placeholder, accessibility & responsiveness
*
* @example
* <caption>
* Please note that the order of the plugins is important. See home for more details.
* </caption>
* // Example
* import {CloudinaryImage} from "@cloudinary/url-gen/assets/CloudinaryImage";
* import {
* AdvancedImage,
* accessibility,
* responsive,
* lazyload,
* placeholder
* } from '@cloudinary/react';
*
* const App = () => {
*
* const myCld = new Cloudinary({ cloudName: 'demo'});
* let img = myCld().image('sample');
*
* return (
* <div>
* <div style={{height: "1000px"}}/>
* <AdvancedImage
* cldImg={img}
* plugins={[lazyload(), responsive(100), placeholder()]}
* />
* </div>
* )
* };
*
*
*
*
*
*/
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary image component
* @prop {CloudinaryImage} cldImg Generated by @cloudinary/url-gen
* @prop {Plugins} plugins Advanced image component plugins accessibility(), responsive(), lazyload(), placeholder()
*/
declare class AdvancedImage extends React.Component<ImgProps> {
imageRef: React.RefObject<HTMLImageElement>;
htmlLayerInstance: HtmlImageLayer;
constructor(props: ImgProps);
/**
* On mount creates a new HTMLLayer instance and initialises with ref to img element,
* user generated cloudinaryImage and the plugins to be used
*/
componentDidMount(): void;
/**
* On update we cancel running plugins and update image instance with the state of user
* cloudinaryImage and the state of plugins
*/
componentDidUpdate(): void;
/**
* On unmount we cancel the currently running plugins
*/
componentWillUnmount(): void;
render(): JSX.Element;
}
export { AdvancedImage };
import React from 'react';
import { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';
import { HtmlPictureLayer, PictureSources } from '@cloudinary/html';
interface PictureProps {
cldImg: CloudinaryImage;
breakpoints?: number[];
sources?: PictureSources;
autoOptimalBreakpoints?: boolean;
relativeWidth?: number;
[x: string]: any;
}
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary picture component
* @prop {CloudinaryImage} transformation Generated by @cloudinary/url-gen
* @prop {PictureSources} sources sources to generate source tag
* @example
* <caption>
* Using custom defined resources.
* </caption>
* const img = new CloudinaryImage('sample', { cloudName: 'demo'});
* const sources = [
* {
* minWidth:500,
* maxWidth:2000,
* sizes: "80vw,
* image: img
* },
* {
* minWidth:3000,
* maxWidth:4000,
* sizes: "80vw,
* image: img
* }];
*
* return <AdvancedPicture cldImg={img} sources={sources} />
*/
declare class AdvancedPicture extends React.Component<PictureProps> {
pictureRef: React.RefObject<HTMLPictureElement>;
htmlPictureLayerInstance: HtmlPictureLayer;
constructor(props: PictureProps);
/**
* On mount creates a new HTMLPictureLayer instance and initialises with ref to picture element,
* user generated cloudinaryImage and the sources to be used
*/
componentDidMount(): void;
/**
* On update we update the image instance with the state of user
* cloudinaryImage and the state of sources
*/
componentDidUpdate(): void;
render(): JSX.Element;
}
export { AdvancedPicture };
import { Component, EventHandler, MutableRefObject, SyntheticEvent } from 'react';
import { CloudinaryVideo } from '@cloudinary/url-gen';
import { HtmlVideoLayer, Plugins, VideoSources } from '@cloudinary/html';
declare type ReactEventHandler<T = Element> = EventHandler<SyntheticEvent<T>>;
interface VideoProps {
cldVid: CloudinaryVideo;
plugins?: Plugins;
sources?: VideoSources;
innerRef?: ((instance: any) => void) | MutableRefObject<unknown> | null;
controls?: boolean;
loop?: boolean;
muted?: boolean;
poster?: string;
preload?: string;
autoPlay?: boolean;
playsInline?: boolean;
onPlay?: ReactEventHandler<any>;
onLoadStart?: ReactEventHandler<any>;
onPlaying?: ReactEventHandler<any>;
onError?: ReactEventHandler<any>;
onEnded?: ReactEventHandler<any>;
}
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary video component
* @prop {CloudinaryVideo} transformation Generated by @cloudinary/url-gen
* @prop {Plugins} plugins Advanced image component plugins lazyload()
* @prop videoAttributes Optional attributes include controls, loop, muted, poster, preload, autoplay
* @prop videoEvents Optional video events include play, loadstart, playing, error, ended
* @prop {VideoSources} sources Optional sources to generate
* @example
* <caption>
* Using custom defined resources.
* </caption>
* const vid = new CloudinaryVideo('dog', {cloudName: 'demo'});
* const videoEl = useRef();
* const sources = [
* {
* type: 'mp4',
* codecs: ['vp8', 'vorbis'],
* transcode: videoCodec(auto())
* },
* {
* type: 'webm',
* codecs: ['avc1.4D401E', 'mp4a.40.2'],
* videoCodec: videoCodec(auto())
* }];
*
* return <AdvancedVideo cldVid={vid} sources={sources} ref={videoEl} controls />
*/
declare class AdvancedVideo extends Component<VideoProps> {
videoRef: MutableRefObject<HTMLVideoElement | null>;
htmlVideoLayerInstance: HtmlVideoLayer;
constructor(props: VideoProps);
/**
* On mount creates a new HTMLVideoLayer instance and initialises with ref to video element,
* user generated cloudinaryVideo and the plugins to be used
*/
componentDidMount(): void;
/**
* On update we cancel running plugins and update the video instance if the src
* was changed
*/
componentDidUpdate(): void;
/**
* On unmount we cancel the currently running plugins
*/
componentWillUnmount(): void;
/**
* returns video attributes
*/
getVideoAttributes(): {
controls: boolean | undefined;
loop: boolean | undefined;
muted: boolean | undefined;
poster: string | undefined;
preload: string | undefined;
autoplay: boolean | undefined;
playsinline: boolean | undefined;
};
/**
* Attach both this.videoRef and props.innerRef as ref to the given element
* @param element - the element to attach a ref to
*/
attachRef(element: HTMLVideoElement): void;
render(): JSX.Element;
}
export { AdvancedVideo };
1.0.0-beta.14 / 2021-12-05
==================
* update readme for packages (#108)
* resolve broken ts imports (#109)
* rename angular package (#107)
1.0.0-beta.13 / 2021-11-30
==================
* Add Lerna (#104)
1.0.0-beta.11 / 2021-09-14
==================
* updated to html to latest version (#96)
1.0.0-beta.10 / 2021-09-14
==================
New functionality
-----------------
* added autoOptimalBreakpoints to picture tag (#86)
Other changes
-----------------
* changed to url-gen package name (#94)
1.0.0-beta.9 / 2021-07-04
==================
* Fix/common js build (#87)
* Add advanced picture (#84)
1.0.0-beta.8 / 2021-05-12
==================
Other changes
-----------------
* Release pipeline testing
1.0.0-beta.7 / 2021-05-12
==================
Other changes
-----------------
* Fix svelte npm package file contents
1.0.0-beta.6 / 2021-05-11
==================
Other changes
-----------------
* Release pipeline testing
1.0.0-beta.4 / 2021-05-09
==================
New functionality
-----------------
* align video attributes in React and Angular(#77)
* Added ondestroy lifecycle hook to video component (#78)
Other changes
-----------------
* Disable package-lock generation by adding .npmrc config
* Feature/add vue sdk infrastructure (#74)
* Add dynamic copy right date (#76)
1.0.0-beta.3 / 2021-04-12
==================
New functionality
-----------------
* React - Add innerRef prop to AdvanceVideo component (#65)
* React - Add video component (#59)
* Shared(Breaking) - Update video sources to accept Transcode action (#64)
Other changes
-----------------
* Svelte - Fix ts errors by adding importsNotUsedAsValues rule (#68)
* Angular - Add enableProdMode() (#63)
* Svelte tests - Add svelte ssr tests (#62)
* Svelte tests - Add responsive unit tests for svelte sdk (#60)
* Angular tests - add missing angular tests (#61)
* React tests - add react e2e tests (#58)
* Svelte docs - Add svelte sdk docs (#57)
* React - Update dependency of react version to be ^16.3.0 || ^17.0.0 (#49)
* Shared - fix status canceled error on placeholder (#54)
* Shared - Feature/add video layer (#52)
1.0.0-beta.1 / 2021-02-24
==================
New functionality
-----------------
* Add svelte sdk (#48)
Other changes
-----------------
* Upgrade to base beta (#51)
* Handle placeholder onerror (#46)
* Add travis.yml file (#50)
* Docs - Add version number to the docs reference (#47)
* Docs - Finalize readme before release (#45)
1.0.0-beta.0 / 2021-02-02
==================
Other changes
---------------
* Beta release
1.0.0-alpha.5 / 2021-02-02
==================
Other changes
---------------
* Add changelog
* Test full release-cycle using jenkins
1.0.0-alpha.4 / 2021-01-31
==========================
Initial Release
-------------
* Implement plugins - Responsive, Placeholder, Accessibility, Lazyload
* Implement React and Angular image components
import { placeholder, accessibility, lazyload, responsive } from '@cloudinary/html';
import { AdvancedImage } from './AdvancedImage';
import { AdvancedVideo } from './AdvancedVideo';
import { AdvancedPicture } from './AdvancedPicture';
export { placeholder, accessibility, lazyload, responsive, AdvancedImage, AdvancedVideo, AdvancedPicture };
import { HtmlImageLayer, cancelCurrentlyRunningPlugins, isBrowser, serverSideSrc, HtmlVideoLayer, HtmlPictureLayer } from '@cloudinary/html';
export { accessibility, lazyload, placeholder, responsive } from '@cloudinary/html';
import React, { createRef, Component } from 'react';
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
_setPrototypeOf(subClass, superClass);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
var _excluded$2 = ["cldImg", "plugins"];
/**
* @mixin ReactSDK
* @description The Cloudinary React SDK contains components like <AdvancedImage> to easily render your media assets from Cloudinary.
* The SDK also comes with support for optional js plugins that make the components smart, with features like lazy loading, placeholder, accessibility & responsiveness
*
* @example
* <caption>
* Please note that the order of the plugins is important. See home for more details.
* </caption>
* // Example
* import {CloudinaryImage} from "@cloudinary/url-gen/assets/CloudinaryImage";
* import {
* AdvancedImage,
* accessibility,
* responsive,
* lazyload,
* placeholder
* } from '@cloudinary/react';
*
* const App = () => {
*
* const myCld = new Cloudinary({ cloudName: 'demo'});
* let img = myCld().image('sample');
*
* return (
* <div>
* <div style={{height: "1000px"}}/>
* <AdvancedImage
* cldImg={img}
* plugins={[lazyload(), responsive(100), placeholder()]}
* />
* </div>
* )
* };
*
*
*
*
*
*/
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary image component
* @prop {CloudinaryImage} cldImg Generated by @cloudinary/url-gen
* @prop {Plugins} plugins Advanced image component plugins accessibility(), responsive(), lazyload(), placeholder()
*/
var AdvancedImage = /*#__PURE__*/function (_React$Component) {
_inheritsLoose(AdvancedImage, _React$Component);
function AdvancedImage(props) {
var _this;
_this = _React$Component.call(this, props) || this;
_this.imageRef = /*#__PURE__*/React.createRef();
return _this;
}
/**
* On mount creates a new HTMLLayer instance and initialises with ref to img element,
* user generated cloudinaryImage and the plugins to be used
*/
var _proto = AdvancedImage.prototype;
_proto.componentDidMount = function componentDidMount() {
this.htmlLayerInstance = new HtmlImageLayer(this.imageRef.current, this.props.cldImg, this.props.plugins);
}
/**
* On update we cancel running plugins and update image instance with the state of user
* cloudinaryImage and the state of plugins
*/
;
_proto.componentDidUpdate = function componentDidUpdate() {
cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState); // call html layer to update the dom again with plugins and reset toBeCanceled
this.htmlLayerInstance.update(this.props.cldImg, this.props.plugins);
}
/**
* On unmount we cancel the currently running plugins
*/
;
_proto.componentWillUnmount = function componentWillUnmount() {
// safely cancel running events on unmount
cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);
};
_proto.render = function render() {
var _this$props = this.props,
otherProps = _objectWithoutPropertiesLoose(_this$props, _excluded$2);
if (isBrowser()) {
// on client side render
return /*#__PURE__*/React.createElement("img", Object.assign({
suppressHydrationWarning: true
}, otherProps, {
ref: this.imageRef
}));
} else {
// on server side render
var src = serverSideSrc(this.props.plugins, this.props.cldImg);
return /*#__PURE__*/React.createElement("img", Object.assign({}, otherProps, {
src: src
}));
}
};
return AdvancedImage;
}(React.Component);
var _excluded$1 = ["cldVid", "plugins", "sources", "innerRef"];
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary video component
* @prop {CloudinaryVideo} transformation Generated by @cloudinary/url-gen
* @prop {Plugins} plugins Advanced image component plugins lazyload()
* @prop videoAttributes Optional attributes include controls, loop, muted, poster, preload, autoplay
* @prop videoEvents Optional video events include play, loadstart, playing, error, ended
* @prop {VideoSources} sources Optional sources to generate
* @example
* <caption>
* Using custom defined resources.
* </caption>
* const vid = new CloudinaryVideo('dog', {cloudName: 'demo'});
* const videoEl = useRef();
* const sources = [
* {
* type: 'mp4',
* codecs: ['vp8', 'vorbis'],
* transcode: videoCodec(auto())
* },
* {
* type: 'webm',
* codecs: ['avc1.4D401E', 'mp4a.40.2'],
* videoCodec: videoCodec(auto())
* }];
*
* return <AdvancedVideo cldVid={vid} sources={sources} ref={videoEl} controls />
*/
var AdvancedVideo = /*#__PURE__*/function (_Component) {
_inheritsLoose(AdvancedVideo, _Component);
function AdvancedVideo(props) {
var _this;
_this = _Component.call(this, props) || this;
_this.videoRef = /*#__PURE__*/createRef();
_this.attachRef = _this.attachRef.bind(_assertThisInitialized(_this));
return _this;
}
/**
* On mount creates a new HTMLVideoLayer instance and initialises with ref to video element,
* user generated cloudinaryVideo and the plugins to be used
*/
var _proto = AdvancedVideo.prototype;
_proto.componentDidMount = function componentDidMount() {
this.htmlVideoLayerInstance = new HtmlVideoLayer(this.videoRef && this.videoRef.current, this.props.cldVid, this.props.sources, this.props.plugins, this.getVideoAttributes());
}
/**
* On update we cancel running plugins and update the video instance if the src
* was changed
*/
;
_proto.componentDidUpdate = function componentDidUpdate() {
cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState); // call html layer to update the dom again with plugins and reset toBeCanceled
this.htmlVideoLayerInstance.update(this.props.cldVid, this.props.sources, this.props.plugins, this.getVideoAttributes());
}
/**
* On unmount we cancel the currently running plugins
*/
;
_proto.componentWillUnmount = function componentWillUnmount() {
// safely cancel running events on unmount
cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState);
}
/**
* returns video attributes
*/
;
_proto.getVideoAttributes = function getVideoAttributes() {
return {
controls: this.props.controls,
loop: this.props.loop,
muted: this.props.muted,
poster: this.props.poster,
preload: this.props.preload,
autoplay: this.props.autoPlay,
playsinline: this.props.playsInline
};
}
/**
* Attach both this.videoRef and props.innerRef as ref to the given element
* @param element - the element to attach a ref to
*/
;
_proto.attachRef = function attachRef(element) {
this.videoRef.current = element;
var innerRef = this.props.innerRef;
if (innerRef) {
if (innerRef instanceof Function) {
innerRef(element);
} else {
innerRef.current = element;
}
}
};
_proto.render = function render() {
var _this$props = this.props,
videoEvents = _objectWithoutPropertiesLoose(_this$props, _excluded$1);
return /*#__PURE__*/React.createElement("video", Object.assign({}, videoEvents, {
ref: this.attachRef
}));
};
return AdvancedVideo;
}(Component);
var _excluded = ["cldImg", "breakpoints", "sources", "autoOptimalBreakpoints", "relativeWidth"];
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary picture component
* @prop {CloudinaryImage} transformation Generated by @cloudinary/url-gen
* @prop {PictureSources} sources sources to generate source tag
* @example
* <caption>
* Using custom defined resources.
* </caption>
* const img = new CloudinaryImage('sample', { cloudName: 'demo'});
* const sources = [
* {
* minWidth:500,
* maxWidth:2000,
* sizes: "80vw,
* image: img
* },
* {
* minWidth:3000,
* maxWidth:4000,
* sizes: "80vw,
* image: img
* }];
*
* return <AdvancedPicture cldImg={img} sources={sources} />
*/
var AdvancedPicture = /*#__PURE__*/function (_React$Component) {
_inheritsLoose(AdvancedPicture, _React$Component);
function AdvancedPicture(props) {
var _this;
_this = _React$Component.call(this, props) || this;
_this.pictureRef = /*#__PURE__*/React.createRef();
return _this;
}
/**
* On mount creates a new HTMLPictureLayer instance and initialises with ref to picture element,
* user generated cloudinaryImage and the sources to be used
*/
var _proto = AdvancedPicture.prototype;
_proto.componentDidMount = function componentDidMount() {
this.htmlPictureLayerInstance = new HtmlPictureLayer(this.pictureRef.current, this.props.cldImg, this.props.breakpoints, this.props.sources, this.props.autoOptimalBreakpoints, this.props.relativeWidth);
}
/**
* On update we update the image instance with the state of user
* cloudinaryImage and the state of sources
*/
;
_proto.componentDidUpdate = function componentDidUpdate() {
// call html layer to update the dom
this.htmlPictureLayerInstance.update(this.props.cldImg, this.props.breakpoints, this.props.sources, this.props.autoOptimalBreakpoints, this.props.relativeWidth);
};
_proto.render = function render() {
var _this$props = this.props,
otherProps = _objectWithoutPropertiesLoose(_this$props, _excluded);
return /*#__PURE__*/React.createElement("picture", Object.assign({}, otherProps, {
ref: this.pictureRef
}));
};
return AdvancedPicture;
}(React.Component);
export { AdvancedImage, AdvancedPicture, AdvancedVideo };
//# sourceMappingURL=index.esm.js.map
{"version":3,"file":"index.esm.js","sources":["../src/AdvancedImage.tsx","../src/AdvancedVideo.tsx","../src/AdvancedPicture.tsx"],"sourcesContent":["import React from 'react';\nimport { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';\n\nimport {\n HtmlImageLayer,\n Plugins,\n isBrowser,\n serverSideSrc,\n cancelCurrentlyRunningPlugins\n} from '@cloudinary/html'\n\ninterface ImgProps {\n cldImg: CloudinaryImage,\n plugins?: Plugins,\n [x: string]: any\n}\n\n/**\n * @mixin ReactSDK\n * @description The Cloudinary React SDK contains components like <AdvancedImage> to easily render your media assets from Cloudinary.\n * The SDK also comes with support for optional js plugins that make the components smart, with features like lazy loading, placeholder, accessibility & responsiveness\n *\n * @example\n * <caption>\n * Please note that the order of the plugins is important. See home for more details.\n * </caption>\n * // Example\n * import {CloudinaryImage} from \"@cloudinary/url-gen/assets/CloudinaryImage\";\n * import {\n * AdvancedImage,\n * accessibility,\n * responsive,\n * lazyload,\n * placeholder\n * } from '@cloudinary/react';\n *\n * const App = () => {\n *\n * const myCld = new Cloudinary({ cloudName: 'demo'});\n * let img = myCld().image('sample');\n *\n * return (\n * <div>\n * <div style={{height: \"1000px\"}}/>\n * <AdvancedImage\n * cldImg={img}\n * plugins={[lazyload(), responsive(100), placeholder()]}\n * />\n * </div>\n * )\n * };\n *\n *\n *\n *\n *\n */\n\n/**\n * @memberOf ReactSDK\n * @type {Component}\n * @description The Cloudinary image component\n * @prop {CloudinaryImage} cldImg Generated by @cloudinary/url-gen\n * @prop {Plugins} plugins Advanced image component plugins accessibility(), responsive(), lazyload(), placeholder()\n */\nclass AdvancedImage extends React.Component <ImgProps> {\n imageRef: React.RefObject<HTMLImageElement>;\n htmlLayerInstance: HtmlImageLayer;\n\n constructor(props: ImgProps) {\n super(props);\n this.imageRef = React.createRef();\n }\n\n /**\n * On mount creates a new HTMLLayer instance and initialises with ref to img element,\n * user generated cloudinaryImage and the plugins to be used\n */\n componentDidMount() {\n this.htmlLayerInstance = new HtmlImageLayer(\n this.imageRef.current,\n this.props.cldImg,\n this.props.plugins\n )\n }\n\n /**\n * On update we cancel running plugins and update image instance with the state of user\n * cloudinaryImage and the state of plugins\n */\n componentDidUpdate() {\n cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);\n // call html layer to update the dom again with plugins and reset toBeCanceled\n this.htmlLayerInstance.update(this.props.cldImg, this.props.plugins)\n }\n\n /**\n * On unmount we cancel the currently running plugins\n */\n componentWillUnmount() {\n // safely cancel running events on unmount\n cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);\n }\n\n render() {\n const {\n cldImg,\n plugins,\n ...otherProps // Assume any other props are for the base element\n } = this.props;\n if (isBrowser()) { // on client side render\n return <img suppressHydrationWarning {...otherProps} ref={this.imageRef} />\n } else { // on server side render\n const src = serverSideSrc(\n this.props.plugins,\n this.props.cldImg\n );\n return <img {...otherProps} src={src} />\n }\n }\n}\n\nexport { AdvancedImage };\n","import React, { Component, createRef, EventHandler, MutableRefObject, SyntheticEvent } from 'react';\nimport { CloudinaryVideo } from '@cloudinary/url-gen';\n\nimport {\n HtmlVideoLayer,\n Plugins,\n VideoSources,\n cancelCurrentlyRunningPlugins\n} from '@cloudinary/html';\n\ntype ReactEventHandler<T = Element> = EventHandler<SyntheticEvent<T>>;\n\ninterface VideoProps {\n cldVid: CloudinaryVideo,\n plugins?: Plugins,\n sources?: VideoSources,\n innerRef?: ((instance: any) => void) | MutableRefObject<unknown> | null\n\n // supported video attributes\n controls?: boolean\n loop?: boolean,\n muted?: boolean,\n poster?: string,\n preload?: string,\n autoPlay?: boolean,\n playsInline?: boolean\n\n // supported video events\n onPlay?: ReactEventHandler<any>,\n onLoadStart?: ReactEventHandler<any>,\n onPlaying?: ReactEventHandler<any>,\n onError?: ReactEventHandler<any>,\n onEnded?: ReactEventHandler<any>\n}\n\n/**\n * @memberOf ReactSDK\n * @type {Component}\n * @description The Cloudinary video component\n * @prop {CloudinaryVideo} transformation Generated by @cloudinary/url-gen\n * @prop {Plugins} plugins Advanced image component plugins lazyload()\n * @prop videoAttributes Optional attributes include controls, loop, muted, poster, preload, autoplay\n * @prop videoEvents Optional video events include play, loadstart, playing, error, ended\n * @prop {VideoSources} sources Optional sources to generate\n * @example\n * <caption>\n * Using custom defined resources.\n * </caption>\n * const vid = new CloudinaryVideo('dog', {cloudName: 'demo'});\n * const videoEl = useRef();\n * const sources = [\n * {\n * type: 'mp4',\n * codecs: ['vp8', 'vorbis'],\n * transcode: videoCodec(auto())\n * },\n * {\n * type: 'webm',\n * codecs: ['avc1.4D401E', 'mp4a.40.2'],\n * videoCodec: videoCodec(auto())\n * }];\n *\n * return <AdvancedVideo cldVid={vid} sources={sources} ref={videoEl} controls />\n */\nclass AdvancedVideo extends Component <VideoProps> {\n videoRef: MutableRefObject<HTMLVideoElement | null>\n htmlVideoLayerInstance: HtmlVideoLayer;\n\n constructor(props: VideoProps) {\n super(props);\n this.videoRef = createRef();\n this.attachRef = this.attachRef.bind(this);\n }\n\n /**\n * On mount creates a new HTMLVideoLayer instance and initialises with ref to video element,\n * user generated cloudinaryVideo and the plugins to be used\n */\n componentDidMount() {\n this.htmlVideoLayerInstance = new HtmlVideoLayer(\n this.videoRef && this.videoRef.current,\n this.props.cldVid,\n this.props.sources,\n this.props.plugins,\n this.getVideoAttributes()\n )\n }\n\n /**\n * On update we cancel running plugins and update the video instance if the src\n * was changed\n */\n componentDidUpdate() {\n cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState);\n // call html layer to update the dom again with plugins and reset toBeCanceled\n this.htmlVideoLayerInstance.update(this.props.cldVid, this.props.sources, this.props.plugins, this.getVideoAttributes())\n }\n\n /**\n * On unmount we cancel the currently running plugins\n */\n componentWillUnmount() {\n // safely cancel running events on unmount\n cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState)\n }\n\n /**\n * returns video attributes\n */\n getVideoAttributes() {\n return {\n controls: this.props.controls,\n loop: this.props.loop,\n muted: this.props.muted,\n poster: this.props.poster,\n preload: this.props.preload,\n autoplay: this.props.autoPlay,\n playsinline: this.props.playsInline\n };\n }\n\n /**\n * Attach both this.videoRef and props.innerRef as ref to the given element\n * @param element - the element to attach a ref to\n */\n attachRef(element: HTMLVideoElement) {\n this.videoRef.current = element;\n const { innerRef } = this.props;\n\n if (innerRef) {\n if (innerRef instanceof Function) {\n innerRef(element);\n } else {\n innerRef.current = element;\n }\n }\n };\n\n render() {\n const {\n cldVid,\n plugins,\n sources,\n innerRef,\n ...videoEvents // Assume any other props are for the base element\n } = this.props;\n\n return <video {...videoEvents} ref={this.attachRef} />\n }\n}\n\nexport { AdvancedVideo };\n","import React from 'react';\nimport { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';\n\nimport {\n HtmlPictureLayer,\n PictureSources\n} from '@cloudinary/html'\n\ninterface PictureProps {\n cldImg: CloudinaryImage,\n breakpoints?: number[],\n sources?: PictureSources,\n autoOptimalBreakpoints?: boolean,\n relativeWidth?: number\n [x: string]: any\n}\n\n/**\n * @memberOf ReactSDK\n * @type {Component}\n * @description The Cloudinary picture component\n * @prop {CloudinaryImage} transformation Generated by @cloudinary/url-gen\n * @prop {PictureSources} sources sources to generate source tag\n * @example\n * <caption>\n * Using custom defined resources.\n * </caption>\n * const img = new CloudinaryImage('sample', { cloudName: 'demo'});\n * const sources = [\n * {\n * minWidth:500,\n * maxWidth:2000,\n * sizes: \"80vw,\n * image: img\n * },\n * {\n * minWidth:3000,\n * maxWidth:4000,\n * sizes: \"80vw,\n * image: img\n * }];\n *\n * return <AdvancedPicture cldImg={img} sources={sources} />\n */\nclass AdvancedPicture extends React.Component <PictureProps> {\n pictureRef: React.RefObject<HTMLPictureElement>;\n htmlPictureLayerInstance: HtmlPictureLayer;\n\n constructor(props: PictureProps) {\n super(props);\n this.pictureRef = React.createRef();\n }\n\n /**\n * On mount creates a new HTMLPictureLayer instance and initialises with ref to picture element,\n * user generated cloudinaryImage and the sources to be used\n */\n componentDidMount() {\n this.htmlPictureLayerInstance = new HtmlPictureLayer(\n this.pictureRef.current,\n this.props.cldImg,\n this.props.breakpoints,\n this.props.sources,\n this.props.autoOptimalBreakpoints,\n this.props.relativeWidth\n )\n }\n\n /**\n * On update we update the image instance with the state of user\n * cloudinaryImage and the state of sources\n */\n componentDidUpdate() {\n // call html layer to update the dom\n this.htmlPictureLayerInstance.update(\n this.props.cldImg,\n this.props.breakpoints,\n this.props.sources,\n this.props.autoOptimalBreakpoints,\n this.props.relativeWidth\n );\n }\n\n render() {\n const {\n cldImg,\n breakpoints,\n sources,\n autoOptimalBreakpoints,\n relativeWidth,\n ...otherProps // Assume any other props are for the base element\n } = this.props;\n return <picture {...otherProps} ref={this.pictureRef} />\n }\n}\n\nexport { AdvancedPicture };\n"],"names":["AdvancedImage","props","imageRef","React","createRef","componentDidMount","htmlLayerInstance","HtmlImageLayer","current","cldImg","plugins","componentDidUpdate","cancelCurrentlyRunningPlugins","htmlPluginState","update","componentWillUnmount","render","otherProps","isBrowser","suppressHydrationWarning","ref","src","serverSideSrc","Component","AdvancedVideo","videoRef","attachRef","bind","htmlVideoLayerInstance","HtmlVideoLayer","cldVid","sources","getVideoAttributes","controls","loop","muted","poster","preload","autoplay","autoPlay","playsinline","playsInline","element","innerRef","Function","videoEvents","AdvancedPicture","pictureRef","htmlPictureLayerInstance","HtmlPictureLayer","breakpoints","autoOptimalBreakpoints","relativeWidth"],"mappings":"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"}
var html = require('@cloudinary/html');
var React = require('react');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
_setPrototypeOf(subClass, superClass);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
var _excluded$2 = ["cldImg", "plugins"];
/**
* @mixin ReactSDK
* @description The Cloudinary React SDK contains components like <AdvancedImage> to easily render your media assets from Cloudinary.
* The SDK also comes with support for optional js plugins that make the components smart, with features like lazy loading, placeholder, accessibility & responsiveness
*
* @example
* <caption>
* Please note that the order of the plugins is important. See home for more details.
* </caption>
* // Example
* import {CloudinaryImage} from "@cloudinary/url-gen/assets/CloudinaryImage";
* import {
* AdvancedImage,
* accessibility,
* responsive,
* lazyload,
* placeholder
* } from '@cloudinary/react';
*
* const App = () => {
*
* const myCld = new Cloudinary({ cloudName: 'demo'});
* let img = myCld().image('sample');
*
* return (
* <div>
* <div style={{height: "1000px"}}/>
* <AdvancedImage
* cldImg={img}
* plugins={[lazyload(), responsive(100), placeholder()]}
* />
* </div>
* )
* };
*
*
*
*
*
*/
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary image component
* @prop {CloudinaryImage} cldImg Generated by @cloudinary/url-gen
* @prop {Plugins} plugins Advanced image component plugins accessibility(), responsive(), lazyload(), placeholder()
*/
var AdvancedImage = /*#__PURE__*/function (_React$Component) {
_inheritsLoose(AdvancedImage, _React$Component);
function AdvancedImage(props) {
var _this;
_this = _React$Component.call(this, props) || this;
_this.imageRef = /*#__PURE__*/React__default["default"].createRef();
return _this;
}
/**
* On mount creates a new HTMLLayer instance and initialises with ref to img element,
* user generated cloudinaryImage and the plugins to be used
*/
var _proto = AdvancedImage.prototype;
_proto.componentDidMount = function componentDidMount() {
this.htmlLayerInstance = new html.HtmlImageLayer(this.imageRef.current, this.props.cldImg, this.props.plugins);
}
/**
* On update we cancel running plugins and update image instance with the state of user
* cloudinaryImage and the state of plugins
*/
;
_proto.componentDidUpdate = function componentDidUpdate() {
html.cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState); // call html layer to update the dom again with plugins and reset toBeCanceled
this.htmlLayerInstance.update(this.props.cldImg, this.props.plugins);
}
/**
* On unmount we cancel the currently running plugins
*/
;
_proto.componentWillUnmount = function componentWillUnmount() {
// safely cancel running events on unmount
html.cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);
};
_proto.render = function render() {
var _this$props = this.props,
otherProps = _objectWithoutPropertiesLoose(_this$props, _excluded$2);
if (html.isBrowser()) {
// on client side render
return /*#__PURE__*/React__default["default"].createElement("img", Object.assign({
suppressHydrationWarning: true
}, otherProps, {
ref: this.imageRef
}));
} else {
// on server side render
var src = html.serverSideSrc(this.props.plugins, this.props.cldImg);
return /*#__PURE__*/React__default["default"].createElement("img", Object.assign({}, otherProps, {
src: src
}));
}
};
return AdvancedImage;
}(React__default["default"].Component);
var _excluded$1 = ["cldVid", "plugins", "sources", "innerRef"];
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary video component
* @prop {CloudinaryVideo} transformation Generated by @cloudinary/url-gen
* @prop {Plugins} plugins Advanced image component plugins lazyload()
* @prop videoAttributes Optional attributes include controls, loop, muted, poster, preload, autoplay
* @prop videoEvents Optional video events include play, loadstart, playing, error, ended
* @prop {VideoSources} sources Optional sources to generate
* @example
* <caption>
* Using custom defined resources.
* </caption>
* const vid = new CloudinaryVideo('dog', {cloudName: 'demo'});
* const videoEl = useRef();
* const sources = [
* {
* type: 'mp4',
* codecs: ['vp8', 'vorbis'],
* transcode: videoCodec(auto())
* },
* {
* type: 'webm',
* codecs: ['avc1.4D401E', 'mp4a.40.2'],
* videoCodec: videoCodec(auto())
* }];
*
* return <AdvancedVideo cldVid={vid} sources={sources} ref={videoEl} controls />
*/
var AdvancedVideo = /*#__PURE__*/function (_Component) {
_inheritsLoose(AdvancedVideo, _Component);
function AdvancedVideo(props) {
var _this;
_this = _Component.call(this, props) || this;
_this.videoRef = /*#__PURE__*/React.createRef();
_this.attachRef = _this.attachRef.bind(_assertThisInitialized(_this));
return _this;
}
/**
* On mount creates a new HTMLVideoLayer instance and initialises with ref to video element,
* user generated cloudinaryVideo and the plugins to be used
*/
var _proto = AdvancedVideo.prototype;
_proto.componentDidMount = function componentDidMount() {
this.htmlVideoLayerInstance = new html.HtmlVideoLayer(this.videoRef && this.videoRef.current, this.props.cldVid, this.props.sources, this.props.plugins, this.getVideoAttributes());
}
/**
* On update we cancel running plugins and update the video instance if the src
* was changed
*/
;
_proto.componentDidUpdate = function componentDidUpdate() {
html.cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState); // call html layer to update the dom again with plugins and reset toBeCanceled
this.htmlVideoLayerInstance.update(this.props.cldVid, this.props.sources, this.props.plugins, this.getVideoAttributes());
}
/**
* On unmount we cancel the currently running plugins
*/
;
_proto.componentWillUnmount = function componentWillUnmount() {
// safely cancel running events on unmount
html.cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState);
}
/**
* returns video attributes
*/
;
_proto.getVideoAttributes = function getVideoAttributes() {
return {
controls: this.props.controls,
loop: this.props.loop,
muted: this.props.muted,
poster: this.props.poster,
preload: this.props.preload,
autoplay: this.props.autoPlay,
playsinline: this.props.playsInline
};
}
/**
* Attach both this.videoRef and props.innerRef as ref to the given element
* @param element - the element to attach a ref to
*/
;
_proto.attachRef = function attachRef(element) {
this.videoRef.current = element;
var innerRef = this.props.innerRef;
if (innerRef) {
if (innerRef instanceof Function) {
innerRef(element);
} else {
innerRef.current = element;
}
}
};
_proto.render = function render() {
var _this$props = this.props,
videoEvents = _objectWithoutPropertiesLoose(_this$props, _excluded$1);
return /*#__PURE__*/React__default["default"].createElement("video", Object.assign({}, videoEvents, {
ref: this.attachRef
}));
};
return AdvancedVideo;
}(React.Component);
var _excluded = ["cldImg", "breakpoints", "sources", "autoOptimalBreakpoints", "relativeWidth"];
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary picture component
* @prop {CloudinaryImage} transformation Generated by @cloudinary/url-gen
* @prop {PictureSources} sources sources to generate source tag
* @example
* <caption>
* Using custom defined resources.
* </caption>
* const img = new CloudinaryImage('sample', { cloudName: 'demo'});
* const sources = [
* {
* minWidth:500,
* maxWidth:2000,
* sizes: "80vw,
* image: img
* },
* {
* minWidth:3000,
* maxWidth:4000,
* sizes: "80vw,
* image: img
* }];
*
* return <AdvancedPicture cldImg={img} sources={sources} />
*/
var AdvancedPicture = /*#__PURE__*/function (_React$Component) {
_inheritsLoose(AdvancedPicture, _React$Component);
function AdvancedPicture(props) {
var _this;
_this = _React$Component.call(this, props) || this;
_this.pictureRef = /*#__PURE__*/React__default["default"].createRef();
return _this;
}
/**
* On mount creates a new HTMLPictureLayer instance and initialises with ref to picture element,
* user generated cloudinaryImage and the sources to be used
*/
var _proto = AdvancedPicture.prototype;
_proto.componentDidMount = function componentDidMount() {
this.htmlPictureLayerInstance = new html.HtmlPictureLayer(this.pictureRef.current, this.props.cldImg, this.props.breakpoints, this.props.sources, this.props.autoOptimalBreakpoints, this.props.relativeWidth);
}
/**
* On update we update the image instance with the state of user
* cloudinaryImage and the state of sources
*/
;
_proto.componentDidUpdate = function componentDidUpdate() {
// call html layer to update the dom
this.htmlPictureLayerInstance.update(this.props.cldImg, this.props.breakpoints, this.props.sources, this.props.autoOptimalBreakpoints, this.props.relativeWidth);
};
_proto.render = function render() {
var _this$props = this.props,
otherProps = _objectWithoutPropertiesLoose(_this$props, _excluded);
return /*#__PURE__*/React__default["default"].createElement("picture", Object.assign({}, otherProps, {
ref: this.pictureRef
}));
};
return AdvancedPicture;
}(React__default["default"].Component);
Object.defineProperty(exports, 'accessibility', {
enumerable: true,
get: function () { return html.accessibility; }
});
Object.defineProperty(exports, 'lazyload', {
enumerable: true,
get: function () { return html.lazyload; }
});
Object.defineProperty(exports, 'placeholder', {
enumerable: true,
get: function () { return html.placeholder; }
});
Object.defineProperty(exports, 'responsive', {
enumerable: true,
get: function () { return html.responsive; }
});
exports.AdvancedImage = AdvancedImage;
exports.AdvancedPicture = AdvancedPicture;
exports.AdvancedVideo = AdvancedVideo;
//# sourceMappingURL=index.js.map
{"version":3,"file":"index.js","sources":["../src/AdvancedImage.tsx","../src/AdvancedVideo.tsx","../src/AdvancedPicture.tsx"],"sourcesContent":["import React from 'react';\nimport { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';\n\nimport {\n HtmlImageLayer,\n Plugins,\n isBrowser,\n serverSideSrc,\n cancelCurrentlyRunningPlugins\n} from '@cloudinary/html'\n\ninterface ImgProps {\n cldImg: CloudinaryImage,\n plugins?: Plugins,\n [x: string]: any\n}\n\n/**\n * @mixin ReactSDK\n * @description The Cloudinary React SDK contains components like <AdvancedImage> to easily render your media assets from Cloudinary.\n * The SDK also comes with support for optional js plugins that make the components smart, with features like lazy loading, placeholder, accessibility & responsiveness\n *\n * @example\n * <caption>\n * Please note that the order of the plugins is important. See home for more details.\n * </caption>\n * // Example\n * import {CloudinaryImage} from \"@cloudinary/url-gen/assets/CloudinaryImage\";\n * import {\n * AdvancedImage,\n * accessibility,\n * responsive,\n * lazyload,\n * placeholder\n * } from '@cloudinary/react';\n *\n * const App = () => {\n *\n * const myCld = new Cloudinary({ cloudName: 'demo'});\n * let img = myCld().image('sample');\n *\n * return (\n * <div>\n * <div style={{height: \"1000px\"}}/>\n * <AdvancedImage\n * cldImg={img}\n * plugins={[lazyload(), responsive(100), placeholder()]}\n * />\n * </div>\n * )\n * };\n *\n *\n *\n *\n *\n */\n\n/**\n * @memberOf ReactSDK\n * @type {Component}\n * @description The Cloudinary image component\n * @prop {CloudinaryImage} cldImg Generated by @cloudinary/url-gen\n * @prop {Plugins} plugins Advanced image component plugins accessibility(), responsive(), lazyload(), placeholder()\n */\nclass AdvancedImage extends React.Component <ImgProps> {\n imageRef: React.RefObject<HTMLImageElement>;\n htmlLayerInstance: HtmlImageLayer;\n\n constructor(props: ImgProps) {\n super(props);\n this.imageRef = React.createRef();\n }\n\n /**\n * On mount creates a new HTMLLayer instance and initialises with ref to img element,\n * user generated cloudinaryImage and the plugins to be used\n */\n componentDidMount() {\n this.htmlLayerInstance = new HtmlImageLayer(\n this.imageRef.current,\n this.props.cldImg,\n this.props.plugins\n )\n }\n\n /**\n * On update we cancel running plugins and update image instance with the state of user\n * cloudinaryImage and the state of plugins\n */\n componentDidUpdate() {\n cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);\n // call html layer to update the dom again with plugins and reset toBeCanceled\n this.htmlLayerInstance.update(this.props.cldImg, this.props.plugins)\n }\n\n /**\n * On unmount we cancel the currently running plugins\n */\n componentWillUnmount() {\n // safely cancel running events on unmount\n cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);\n }\n\n render() {\n const {\n cldImg,\n plugins,\n ...otherProps // Assume any other props are for the base element\n } = this.props;\n if (isBrowser()) { // on client side render\n return <img suppressHydrationWarning {...otherProps} ref={this.imageRef} />\n } else { // on server side render\n const src = serverSideSrc(\n this.props.plugins,\n this.props.cldImg\n );\n return <img {...otherProps} src={src} />\n }\n }\n}\n\nexport { AdvancedImage };\n","import React, { Component, createRef, EventHandler, MutableRefObject, SyntheticEvent } from 'react';\nimport { CloudinaryVideo } from '@cloudinary/url-gen';\n\nimport {\n HtmlVideoLayer,\n Plugins,\n VideoSources,\n cancelCurrentlyRunningPlugins\n} from '@cloudinary/html';\n\ntype ReactEventHandler<T = Element> = EventHandler<SyntheticEvent<T>>;\n\ninterface VideoProps {\n cldVid: CloudinaryVideo,\n plugins?: Plugins,\n sources?: VideoSources,\n innerRef?: ((instance: any) => void) | MutableRefObject<unknown> | null\n\n // supported video attributes\n controls?: boolean\n loop?: boolean,\n muted?: boolean,\n poster?: string,\n preload?: string,\n autoPlay?: boolean,\n playsInline?: boolean\n\n // supported video events\n onPlay?: ReactEventHandler<any>,\n onLoadStart?: ReactEventHandler<any>,\n onPlaying?: ReactEventHandler<any>,\n onError?: ReactEventHandler<any>,\n onEnded?: ReactEventHandler<any>\n}\n\n/**\n * @memberOf ReactSDK\n * @type {Component}\n * @description The Cloudinary video component\n * @prop {CloudinaryVideo} transformation Generated by @cloudinary/url-gen\n * @prop {Plugins} plugins Advanced image component plugins lazyload()\n * @prop videoAttributes Optional attributes include controls, loop, muted, poster, preload, autoplay\n * @prop videoEvents Optional video events include play, loadstart, playing, error, ended\n * @prop {VideoSources} sources Optional sources to generate\n * @example\n * <caption>\n * Using custom defined resources.\n * </caption>\n * const vid = new CloudinaryVideo('dog', {cloudName: 'demo'});\n * const videoEl = useRef();\n * const sources = [\n * {\n * type: 'mp4',\n * codecs: ['vp8', 'vorbis'],\n * transcode: videoCodec(auto())\n * },\n * {\n * type: 'webm',\n * codecs: ['avc1.4D401E', 'mp4a.40.2'],\n * videoCodec: videoCodec(auto())\n * }];\n *\n * return <AdvancedVideo cldVid={vid} sources={sources} ref={videoEl} controls />\n */\nclass AdvancedVideo extends Component <VideoProps> {\n videoRef: MutableRefObject<HTMLVideoElement | null>\n htmlVideoLayerInstance: HtmlVideoLayer;\n\n constructor(props: VideoProps) {\n super(props);\n this.videoRef = createRef();\n this.attachRef = this.attachRef.bind(this);\n }\n\n /**\n * On mount creates a new HTMLVideoLayer instance and initialises with ref to video element,\n * user generated cloudinaryVideo and the plugins to be used\n */\n componentDidMount() {\n this.htmlVideoLayerInstance = new HtmlVideoLayer(\n this.videoRef && this.videoRef.current,\n this.props.cldVid,\n this.props.sources,\n this.props.plugins,\n this.getVideoAttributes()\n )\n }\n\n /**\n * On update we cancel running plugins and update the video instance if the src\n * was changed\n */\n componentDidUpdate() {\n cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState);\n // call html layer to update the dom again with plugins and reset toBeCanceled\n this.htmlVideoLayerInstance.update(this.props.cldVid, this.props.sources, this.props.plugins, this.getVideoAttributes())\n }\n\n /**\n * On unmount we cancel the currently running plugins\n */\n componentWillUnmount() {\n // safely cancel running events on unmount\n cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState)\n }\n\n /**\n * returns video attributes\n */\n getVideoAttributes() {\n return {\n controls: this.props.controls,\n loop: this.props.loop,\n muted: this.props.muted,\n poster: this.props.poster,\n preload: this.props.preload,\n autoplay: this.props.autoPlay,\n playsinline: this.props.playsInline\n };\n }\n\n /**\n * Attach both this.videoRef and props.innerRef as ref to the given element\n * @param element - the element to attach a ref to\n */\n attachRef(element: HTMLVideoElement) {\n this.videoRef.current = element;\n const { innerRef } = this.props;\n\n if (innerRef) {\n if (innerRef instanceof Function) {\n innerRef(element);\n } else {\n innerRef.current = element;\n }\n }\n };\n\n render() {\n const {\n cldVid,\n plugins,\n sources,\n innerRef,\n ...videoEvents // Assume any other props are for the base element\n } = this.props;\n\n return <video {...videoEvents} ref={this.attachRef} />\n }\n}\n\nexport { AdvancedVideo };\n","import React from 'react';\nimport { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';\n\nimport {\n HtmlPictureLayer,\n PictureSources\n} from '@cloudinary/html'\n\ninterface PictureProps {\n cldImg: CloudinaryImage,\n breakpoints?: number[],\n sources?: PictureSources,\n autoOptimalBreakpoints?: boolean,\n relativeWidth?: number\n [x: string]: any\n}\n\n/**\n * @memberOf ReactSDK\n * @type {Component}\n * @description The Cloudinary picture component\n * @prop {CloudinaryImage} transformation Generated by @cloudinary/url-gen\n * @prop {PictureSources} sources sources to generate source tag\n * @example\n * <caption>\n * Using custom defined resources.\n * </caption>\n * const img = new CloudinaryImage('sample', { cloudName: 'demo'});\n * const sources = [\n * {\n * minWidth:500,\n * maxWidth:2000,\n * sizes: \"80vw,\n * image: img\n * },\n * {\n * minWidth:3000,\n * maxWidth:4000,\n * sizes: \"80vw,\n * image: img\n * }];\n *\n * return <AdvancedPicture cldImg={img} sources={sources} />\n */\nclass AdvancedPicture extends React.Component <PictureProps> {\n pictureRef: React.RefObject<HTMLPictureElement>;\n htmlPictureLayerInstance: HtmlPictureLayer;\n\n constructor(props: PictureProps) {\n super(props);\n this.pictureRef = React.createRef();\n }\n\n /**\n * On mount creates a new HTMLPictureLayer instance and initialises with ref to picture element,\n * user generated cloudinaryImage and the sources to be used\n */\n componentDidMount() {\n this.htmlPictureLayerInstance = new HtmlPictureLayer(\n this.pictureRef.current,\n this.props.cldImg,\n this.props.breakpoints,\n this.props.sources,\n this.props.autoOptimalBreakpoints,\n this.props.relativeWidth\n )\n }\n\n /**\n * On update we update the image instance with the state of user\n * cloudinaryImage and the state of sources\n */\n componentDidUpdate() {\n // call html layer to update the dom\n this.htmlPictureLayerInstance.update(\n this.props.cldImg,\n this.props.breakpoints,\n this.props.sources,\n this.props.autoOptimalBreakpoints,\n this.props.relativeWidth\n );\n }\n\n render() {\n const {\n cldImg,\n breakpoints,\n sources,\n autoOptimalBreakpoints,\n relativeWidth,\n ...otherProps // Assume any other props are for the base element\n } = this.props;\n return <picture {...otherProps} ref={this.pictureRef} />\n }\n}\n\nexport { AdvancedPicture };\n"],"names":["AdvancedImage","props","imageRef","React","createRef","componentDidMount","htmlLayerInstance","HtmlImageLayer","current","cldImg","plugins","componentDidUpdate","cancelCurrentlyRunningPlugins","htmlPluginState","update","componentWillUnmount","render","otherProps","isBrowser","suppressHydrationWarning","ref","src","serverSideSrc","Component","AdvancedVideo","videoRef","attachRef","bind","htmlVideoLayerInstance","HtmlVideoLayer","cldVid","sources","getVideoAttributes","controls","loop","muted","poster","preload","autoplay","autoPlay","playsinline","playsInline","element","innerRef","Function","videoEvents","AdvancedPicture","pictureRef","htmlPictureLayerInstance","HtmlPictureLayer","breakpoints","autoOptimalBreakpoints","relativeWidth"],"mappings":"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"}
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@cloudinary/html'), require('react')) :
typeof define === 'function' && define.amd ? define(['exports', '@cloudinary/html', 'react'], factory) :
(global = global || self, factory(global.react = {}, global.html, global.react));
})(this, (function (exports, html, React) {
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
_setPrototypeOf(subClass, superClass);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
var _excluded$2 = ["cldImg", "plugins"];
/**
* @mixin ReactSDK
* @description The Cloudinary React SDK contains components like <AdvancedImage> to easily render your media assets from Cloudinary.
* The SDK also comes with support for optional js plugins that make the components smart, with features like lazy loading, placeholder, accessibility & responsiveness
*
* @example
* <caption>
* Please note that the order of the plugins is important. See home for more details.
* </caption>
* // Example
* import {CloudinaryImage} from "@cloudinary/url-gen/assets/CloudinaryImage";
* import {
* AdvancedImage,
* accessibility,
* responsive,
* lazyload,
* placeholder
* } from '@cloudinary/react';
*
* const App = () => {
*
* const myCld = new Cloudinary({ cloudName: 'demo'});
* let img = myCld().image('sample');
*
* return (
* <div>
* <div style={{height: "1000px"}}/>
* <AdvancedImage
* cldImg={img}
* plugins={[lazyload(), responsive(100), placeholder()]}
* />
* </div>
* )
* };
*
*
*
*
*
*/
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary image component
* @prop {CloudinaryImage} cldImg Generated by @cloudinary/url-gen
* @prop {Plugins} plugins Advanced image component plugins accessibility(), responsive(), lazyload(), placeholder()
*/
var AdvancedImage = /*#__PURE__*/function (_React$Component) {
_inheritsLoose(AdvancedImage, _React$Component);
function AdvancedImage(props) {
var _this;
_this = _React$Component.call(this, props) || this;
_this.imageRef = /*#__PURE__*/React__default["default"].createRef();
return _this;
}
/**
* On mount creates a new HTMLLayer instance and initialises with ref to img element,
* user generated cloudinaryImage and the plugins to be used
*/
var _proto = AdvancedImage.prototype;
_proto.componentDidMount = function componentDidMount() {
this.htmlLayerInstance = new html.HtmlImageLayer(this.imageRef.current, this.props.cldImg, this.props.plugins);
}
/**
* On update we cancel running plugins and update image instance with the state of user
* cloudinaryImage and the state of plugins
*/
;
_proto.componentDidUpdate = function componentDidUpdate() {
html.cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState); // call html layer to update the dom again with plugins and reset toBeCanceled
this.htmlLayerInstance.update(this.props.cldImg, this.props.plugins);
}
/**
* On unmount we cancel the currently running plugins
*/
;
_proto.componentWillUnmount = function componentWillUnmount() {
// safely cancel running events on unmount
html.cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);
};
_proto.render = function render() {
var _this$props = this.props,
otherProps = _objectWithoutPropertiesLoose(_this$props, _excluded$2);
if (html.isBrowser()) {
// on client side render
return /*#__PURE__*/React__default["default"].createElement("img", Object.assign({
suppressHydrationWarning: true
}, otherProps, {
ref: this.imageRef
}));
} else {
// on server side render
var src = html.serverSideSrc(this.props.plugins, this.props.cldImg);
return /*#__PURE__*/React__default["default"].createElement("img", Object.assign({}, otherProps, {
src: src
}));
}
};
return AdvancedImage;
}(React__default["default"].Component);
var _excluded$1 = ["cldVid", "plugins", "sources", "innerRef"];
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary video component
* @prop {CloudinaryVideo} transformation Generated by @cloudinary/url-gen
* @prop {Plugins} plugins Advanced image component plugins lazyload()
* @prop videoAttributes Optional attributes include controls, loop, muted, poster, preload, autoplay
* @prop videoEvents Optional video events include play, loadstart, playing, error, ended
* @prop {VideoSources} sources Optional sources to generate
* @example
* <caption>
* Using custom defined resources.
* </caption>
* const vid = new CloudinaryVideo('dog', {cloudName: 'demo'});
* const videoEl = useRef();
* const sources = [
* {
* type: 'mp4',
* codecs: ['vp8', 'vorbis'],
* transcode: videoCodec(auto())
* },
* {
* type: 'webm',
* codecs: ['avc1.4D401E', 'mp4a.40.2'],
* videoCodec: videoCodec(auto())
* }];
*
* return <AdvancedVideo cldVid={vid} sources={sources} ref={videoEl} controls />
*/
var AdvancedVideo = /*#__PURE__*/function (_Component) {
_inheritsLoose(AdvancedVideo, _Component);
function AdvancedVideo(props) {
var _this;
_this = _Component.call(this, props) || this;
_this.videoRef = /*#__PURE__*/React.createRef();
_this.attachRef = _this.attachRef.bind(_assertThisInitialized(_this));
return _this;
}
/**
* On mount creates a new HTMLVideoLayer instance and initialises with ref to video element,
* user generated cloudinaryVideo and the plugins to be used
*/
var _proto = AdvancedVideo.prototype;
_proto.componentDidMount = function componentDidMount() {
this.htmlVideoLayerInstance = new html.HtmlVideoLayer(this.videoRef && this.videoRef.current, this.props.cldVid, this.props.sources, this.props.plugins, this.getVideoAttributes());
}
/**
* On update we cancel running plugins and update the video instance if the src
* was changed
*/
;
_proto.componentDidUpdate = function componentDidUpdate() {
html.cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState); // call html layer to update the dom again with plugins and reset toBeCanceled
this.htmlVideoLayerInstance.update(this.props.cldVid, this.props.sources, this.props.plugins, this.getVideoAttributes());
}
/**
* On unmount we cancel the currently running plugins
*/
;
_proto.componentWillUnmount = function componentWillUnmount() {
// safely cancel running events on unmount
html.cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState);
}
/**
* returns video attributes
*/
;
_proto.getVideoAttributes = function getVideoAttributes() {
return {
controls: this.props.controls,
loop: this.props.loop,
muted: this.props.muted,
poster: this.props.poster,
preload: this.props.preload,
autoplay: this.props.autoPlay,
playsinline: this.props.playsInline
};
}
/**
* Attach both this.videoRef and props.innerRef as ref to the given element
* @param element - the element to attach a ref to
*/
;
_proto.attachRef = function attachRef(element) {
this.videoRef.current = element;
var innerRef = this.props.innerRef;
if (innerRef) {
if (innerRef instanceof Function) {
innerRef(element);
} else {
innerRef.current = element;
}
}
};
_proto.render = function render() {
var _this$props = this.props,
videoEvents = _objectWithoutPropertiesLoose(_this$props, _excluded$1);
return /*#__PURE__*/React__default["default"].createElement("video", Object.assign({}, videoEvents, {
ref: this.attachRef
}));
};
return AdvancedVideo;
}(React.Component);
var _excluded = ["cldImg", "breakpoints", "sources", "autoOptimalBreakpoints", "relativeWidth"];
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary picture component
* @prop {CloudinaryImage} transformation Generated by @cloudinary/url-gen
* @prop {PictureSources} sources sources to generate source tag
* @example
* <caption>
* Using custom defined resources.
* </caption>
* const img = new CloudinaryImage('sample', { cloudName: 'demo'});
* const sources = [
* {
* minWidth:500,
* maxWidth:2000,
* sizes: "80vw,
* image: img
* },
* {
* minWidth:3000,
* maxWidth:4000,
* sizes: "80vw,
* image: img
* }];
*
* return <AdvancedPicture cldImg={img} sources={sources} />
*/
var AdvancedPicture = /*#__PURE__*/function (_React$Component) {
_inheritsLoose(AdvancedPicture, _React$Component);
function AdvancedPicture(props) {
var _this;
_this = _React$Component.call(this, props) || this;
_this.pictureRef = /*#__PURE__*/React__default["default"].createRef();
return _this;
}
/**
* On mount creates a new HTMLPictureLayer instance and initialises with ref to picture element,
* user generated cloudinaryImage and the sources to be used
*/
var _proto = AdvancedPicture.prototype;
_proto.componentDidMount = function componentDidMount() {
this.htmlPictureLayerInstance = new html.HtmlPictureLayer(this.pictureRef.current, this.props.cldImg, this.props.breakpoints, this.props.sources, this.props.autoOptimalBreakpoints, this.props.relativeWidth);
}
/**
* On update we update the image instance with the state of user
* cloudinaryImage and the state of sources
*/
;
_proto.componentDidUpdate = function componentDidUpdate() {
// call html layer to update the dom
this.htmlPictureLayerInstance.update(this.props.cldImg, this.props.breakpoints, this.props.sources, this.props.autoOptimalBreakpoints, this.props.relativeWidth);
};
_proto.render = function render() {
var _this$props = this.props,
otherProps = _objectWithoutPropertiesLoose(_this$props, _excluded);
return /*#__PURE__*/React__default["default"].createElement("picture", Object.assign({}, otherProps, {
ref: this.pictureRef
}));
};
return AdvancedPicture;
}(React__default["default"].Component);
Object.defineProperty(exports, 'accessibility', {
enumerable: true,
get: function () { return html.accessibility; }
});
Object.defineProperty(exports, 'lazyload', {
enumerable: true,
get: function () { return html.lazyload; }
});
Object.defineProperty(exports, 'placeholder', {
enumerable: true,
get: function () { return html.placeholder; }
});
Object.defineProperty(exports, 'responsive', {
enumerable: true,
get: function () { return html.responsive; }
});
exports.AdvancedImage = AdvancedImage;
exports.AdvancedPicture = AdvancedPicture;
exports.AdvancedVideo = AdvancedVideo;
}));
//# sourceMappingURL=index.umd.js.map
{"version":3,"file":"index.umd.js","sources":["../src/AdvancedImage.tsx","../src/AdvancedVideo.tsx","../src/AdvancedPicture.tsx"],"sourcesContent":["import React from 'react';\nimport { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';\n\nimport {\n HtmlImageLayer,\n Plugins,\n isBrowser,\n serverSideSrc,\n cancelCurrentlyRunningPlugins\n} from '@cloudinary/html'\n\ninterface ImgProps {\n cldImg: CloudinaryImage,\n plugins?: Plugins,\n [x: string]: any\n}\n\n/**\n * @mixin ReactSDK\n * @description The Cloudinary React SDK contains components like <AdvancedImage> to easily render your media assets from Cloudinary.\n * The SDK also comes with support for optional js plugins that make the components smart, with features like lazy loading, placeholder, accessibility & responsiveness\n *\n * @example\n * <caption>\n * Please note that the order of the plugins is important. See home for more details.\n * </caption>\n * // Example\n * import {CloudinaryImage} from \"@cloudinary/url-gen/assets/CloudinaryImage\";\n * import {\n * AdvancedImage,\n * accessibility,\n * responsive,\n * lazyload,\n * placeholder\n * } from '@cloudinary/react';\n *\n * const App = () => {\n *\n * const myCld = new Cloudinary({ cloudName: 'demo'});\n * let img = myCld().image('sample');\n *\n * return (\n * <div>\n * <div style={{height: \"1000px\"}}/>\n * <AdvancedImage\n * cldImg={img}\n * plugins={[lazyload(), responsive(100), placeholder()]}\n * />\n * </div>\n * )\n * };\n *\n *\n *\n *\n *\n */\n\n/**\n * @memberOf ReactSDK\n * @type {Component}\n * @description The Cloudinary image component\n * @prop {CloudinaryImage} cldImg Generated by @cloudinary/url-gen\n * @prop {Plugins} plugins Advanced image component plugins accessibility(), responsive(), lazyload(), placeholder()\n */\nclass AdvancedImage extends React.Component <ImgProps> {\n imageRef: React.RefObject<HTMLImageElement>;\n htmlLayerInstance: HtmlImageLayer;\n\n constructor(props: ImgProps) {\n super(props);\n this.imageRef = React.createRef();\n }\n\n /**\n * On mount creates a new HTMLLayer instance and initialises with ref to img element,\n * user generated cloudinaryImage and the plugins to be used\n */\n componentDidMount() {\n this.htmlLayerInstance = new HtmlImageLayer(\n this.imageRef.current,\n this.props.cldImg,\n this.props.plugins\n )\n }\n\n /**\n * On update we cancel running plugins and update image instance with the state of user\n * cloudinaryImage and the state of plugins\n */\n componentDidUpdate() {\n cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);\n // call html layer to update the dom again with plugins and reset toBeCanceled\n this.htmlLayerInstance.update(this.props.cldImg, this.props.plugins)\n }\n\n /**\n * On unmount we cancel the currently running plugins\n */\n componentWillUnmount() {\n // safely cancel running events on unmount\n cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);\n }\n\n render() {\n const {\n cldImg,\n plugins,\n ...otherProps // Assume any other props are for the base element\n } = this.props;\n if (isBrowser()) { // on client side render\n return <img suppressHydrationWarning {...otherProps} ref={this.imageRef} />\n } else { // on server side render\n const src = serverSideSrc(\n this.props.plugins,\n this.props.cldImg\n );\n return <img {...otherProps} src={src} />\n }\n }\n}\n\nexport { AdvancedImage };\n","import React, { Component, createRef, EventHandler, MutableRefObject, SyntheticEvent } from 'react';\nimport { CloudinaryVideo } from '@cloudinary/url-gen';\n\nimport {\n HtmlVideoLayer,\n Plugins,\n VideoSources,\n cancelCurrentlyRunningPlugins\n} from '@cloudinary/html';\n\ntype ReactEventHandler<T = Element> = EventHandler<SyntheticEvent<T>>;\n\ninterface VideoProps {\n cldVid: CloudinaryVideo,\n plugins?: Plugins,\n sources?: VideoSources,\n innerRef?: ((instance: any) => void) | MutableRefObject<unknown> | null\n\n // supported video attributes\n controls?: boolean\n loop?: boolean,\n muted?: boolean,\n poster?: string,\n preload?: string,\n autoPlay?: boolean,\n playsInline?: boolean\n\n // supported video events\n onPlay?: ReactEventHandler<any>,\n onLoadStart?: ReactEventHandler<any>,\n onPlaying?: ReactEventHandler<any>,\n onError?: ReactEventHandler<any>,\n onEnded?: ReactEventHandler<any>\n}\n\n/**\n * @memberOf ReactSDK\n * @type {Component}\n * @description The Cloudinary video component\n * @prop {CloudinaryVideo} transformation Generated by @cloudinary/url-gen\n * @prop {Plugins} plugins Advanced image component plugins lazyload()\n * @prop videoAttributes Optional attributes include controls, loop, muted, poster, preload, autoplay\n * @prop videoEvents Optional video events include play, loadstart, playing, error, ended\n * @prop {VideoSources} sources Optional sources to generate\n * @example\n * <caption>\n * Using custom defined resources.\n * </caption>\n * const vid = new CloudinaryVideo('dog', {cloudName: 'demo'});\n * const videoEl = useRef();\n * const sources = [\n * {\n * type: 'mp4',\n * codecs: ['vp8', 'vorbis'],\n * transcode: videoCodec(auto())\n * },\n * {\n * type: 'webm',\n * codecs: ['avc1.4D401E', 'mp4a.40.2'],\n * videoCodec: videoCodec(auto())\n * }];\n *\n * return <AdvancedVideo cldVid={vid} sources={sources} ref={videoEl} controls />\n */\nclass AdvancedVideo extends Component <VideoProps> {\n videoRef: MutableRefObject<HTMLVideoElement | null>\n htmlVideoLayerInstance: HtmlVideoLayer;\n\n constructor(props: VideoProps) {\n super(props);\n this.videoRef = createRef();\n this.attachRef = this.attachRef.bind(this);\n }\n\n /**\n * On mount creates a new HTMLVideoLayer instance and initialises with ref to video element,\n * user generated cloudinaryVideo and the plugins to be used\n */\n componentDidMount() {\n this.htmlVideoLayerInstance = new HtmlVideoLayer(\n this.videoRef && this.videoRef.current,\n this.props.cldVid,\n this.props.sources,\n this.props.plugins,\n this.getVideoAttributes()\n )\n }\n\n /**\n * On update we cancel running plugins and update the video instance if the src\n * was changed\n */\n componentDidUpdate() {\n cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState);\n // call html layer to update the dom again with plugins and reset toBeCanceled\n this.htmlVideoLayerInstance.update(this.props.cldVid, this.props.sources, this.props.plugins, this.getVideoAttributes())\n }\n\n /**\n * On unmount we cancel the currently running plugins\n */\n componentWillUnmount() {\n // safely cancel running events on unmount\n cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState)\n }\n\n /**\n * returns video attributes\n */\n getVideoAttributes() {\n return {\n controls: this.props.controls,\n loop: this.props.loop,\n muted: this.props.muted,\n poster: this.props.poster,\n preload: this.props.preload,\n autoplay: this.props.autoPlay,\n playsinline: this.props.playsInline\n };\n }\n\n /**\n * Attach both this.videoRef and props.innerRef as ref to the given element\n * @param element - the element to attach a ref to\n */\n attachRef(element: HTMLVideoElement) {\n this.videoRef.current = element;\n const { innerRef } = this.props;\n\n if (innerRef) {\n if (innerRef instanceof Function) {\n innerRef(element);\n } else {\n innerRef.current = element;\n }\n }\n };\n\n render() {\n const {\n cldVid,\n plugins,\n sources,\n innerRef,\n ...videoEvents // Assume any other props are for the base element\n } = this.props;\n\n return <video {...videoEvents} ref={this.attachRef} />\n }\n}\n\nexport { AdvancedVideo };\n","import React from 'react';\nimport { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';\n\nimport {\n HtmlPictureLayer,\n PictureSources\n} from '@cloudinary/html'\n\ninterface PictureProps {\n cldImg: CloudinaryImage,\n breakpoints?: number[],\n sources?: PictureSources,\n autoOptimalBreakpoints?: boolean,\n relativeWidth?: number\n [x: string]: any\n}\n\n/**\n * @memberOf ReactSDK\n * @type {Component}\n * @description The Cloudinary picture component\n * @prop {CloudinaryImage} transformation Generated by @cloudinary/url-gen\n * @prop {PictureSources} sources sources to generate source tag\n * @example\n * <caption>\n * Using custom defined resources.\n * </caption>\n * const img = new CloudinaryImage('sample', { cloudName: 'demo'});\n * const sources = [\n * {\n * minWidth:500,\n * maxWidth:2000,\n * sizes: \"80vw,\n * image: img\n * },\n * {\n * minWidth:3000,\n * maxWidth:4000,\n * sizes: \"80vw,\n * image: img\n * }];\n *\n * return <AdvancedPicture cldImg={img} sources={sources} />\n */\nclass AdvancedPicture extends React.Component <PictureProps> {\n pictureRef: React.RefObject<HTMLPictureElement>;\n htmlPictureLayerInstance: HtmlPictureLayer;\n\n constructor(props: PictureProps) {\n super(props);\n this.pictureRef = React.createRef();\n }\n\n /**\n * On mount creates a new HTMLPictureLayer instance and initialises with ref to picture element,\n * user generated cloudinaryImage and the sources to be used\n */\n componentDidMount() {\n this.htmlPictureLayerInstance = new HtmlPictureLayer(\n this.pictureRef.current,\n this.props.cldImg,\n this.props.breakpoints,\n this.props.sources,\n this.props.autoOptimalBreakpoints,\n this.props.relativeWidth\n )\n }\n\n /**\n * On update we update the image instance with the state of user\n * cloudinaryImage and the state of sources\n */\n componentDidUpdate() {\n // call html layer to update the dom\n this.htmlPictureLayerInstance.update(\n this.props.cldImg,\n this.props.breakpoints,\n this.props.sources,\n this.props.autoOptimalBreakpoints,\n this.props.relativeWidth\n );\n }\n\n render() {\n const {\n cldImg,\n breakpoints,\n sources,\n autoOptimalBreakpoints,\n relativeWidth,\n ...otherProps // Assume any other props are for the base element\n } = this.props;\n return <picture {...otherProps} ref={this.pictureRef} />\n }\n}\n\nexport { AdvancedPicture };\n"],"names":["AdvancedImage","props","imageRef","React","createRef","componentDidMount","htmlLayerInstance","HtmlImageLayer","current","cldImg","plugins","componentDidUpdate","cancelCurrentlyRunningPlugins","htmlPluginState","update","componentWillUnmount","render","otherProps","isBrowser","suppressHydrationWarning","ref","src","serverSideSrc","Component","AdvancedVideo","videoRef","attachRef","bind","htmlVideoLayerInstance","HtmlVideoLayer","cldVid","sources","getVideoAttributes","controls","loop","muted","poster","preload","autoplay","autoPlay","playsinline","playsInline","element","innerRef","Function","videoEvents","AdvancedPicture","pictureRef","htmlPictureLayerInstance","HtmlPictureLayer","breakpoints","autoOptimalBreakpoints","relativeWidth"],"mappings":"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"}
export {};
+3
-4
{
"name": "@cloudinary/react",
"version": "1.0.0-beta.13",
"version": "1.0.0-beta.14",
"description": "A React component for Cloudinary",

@@ -78,5 +78,4 @@ "author": "cloudinary",

"dependencies": {
"@cloudinary/html": "^1.0.0-beta.13"
},
"gitHead": "d088051e0d2c71e1a33a89794846e620e1e47a4f"
"@cloudinary/html": "^1.0.0-beta.14"
}
}
+68
-25

@@ -1,37 +0,80 @@

# React-library
# Cloudinary Frontend Frameworks
## Overview
This is our React library. The objective of this layer is to use our html
library to render an image.
## About this project
## Install
Since this library is not on npm, we will install/pack this repo locally and install it on a sample angular app.
This project contains SDKs designed to work with [Cloudinary url-gen](https://github.com/cloudinary/js-url-gen) </br>
These SDKs will render CloudinaryImage or CloudinaryVideo object into the DOM.
1. clone repo
2. npm install
3. npm run build
4. npm link/pack to use build in external react library
### Packages contained within this project:
<br />
- The React SDK used to render an image & video component. [NPM](https://www.npmjs.com/package/@cloudinary/react) | {@link ReactSDK|Reference}
- The Angular SDK used to render an image & video component. [NPM](https://www.npmjs.com/package/@cloudinary/ng
) | {@link AngularSDK|Reference}
Each SDK also contains advanced features in the form of plugins, which extend the native HTMLImage and HTMLVideo elements.
## Note
This repo contains a temporary user sample for testing.
To use the sample project-
1. npm start to trigger build and live reload
2. cd into /example and run npm install/start to trigger sample user example
- {@link accessibility|accessibility} - Used to make your images more accessible to your users with visual disabilities.
- {@link lazyload|lazyload} - Used to delay loading images if they are not yet visible on the screen.
- {@link placeholder|placeholder} - Used to display a lightweight version of an image while the target image is downloading.
- {@link responsive|responsive} - Used to resize your images automatically based on the viewport size.
## Development setup
To build and link project:
- clone project
- npm run quickstart
## Usage
```tsx
## Installation
To get started, install the npm client package of your choice along with our base package.
For example, to use Cloudinary in a [React](https://cloudinary.com/documentation/react2_integration) environment, the following packages should be installed:
```bash
npm i @cloudinary/react @cloudinary/url-gen
```
**Note**: To use [Angular](https://cloudinary.com/documentation/angular2_integration) install `@cloudinary/angular`
For more information on our supported frameworks, navigate to the frameworks tab.
## Simple usage
The following is a simple example using [React](https://cloudinary.com/documentation/react2_integration).
For more information on React and other frameworks, navigate to the frameworks tab.
```javascript
// Import the cloudinary class, and the plugins you want to use
// In this case, we import a Cloudinary image type and accessibility and responsive.
import React, { Component } from 'react'
import {Cloudinary} from "@cloudinary/url-gen";
import { AdvancedImage, accessibility, responsive } from '@cloudinary/react';
import { AdvancedImage } from '@cloudinary/react'
import {CloudinaryImage} from '@cloudinary/url-gen';
let img = new CloudinaryImage()
// Once per project/app - configure your instance,
// See the documentation in @cloudinary/url-gen for more information
const myCld = new Cloudinary({ cloudName: 'demo'});
let img = myCld().image('sample');
const App = () => {
return <AdvancedImage cldImg={img}/>
};
// render your component
const App = () => {
// Create your image
// This creates a new image object
let img = myCld().image('sample');
return (
<div>
<AdvancedImage cldImg={img} plugins={[responsive(), accessibility()]}/>
</div>
)
};
```
## Plugin Order
<div>
We recommended the following order when using our plugins to achieve the best results.
<br/><br/>
```javascript
<AdvancedImage plugins={[lazyload(),responsive(), accessibility(), placeholder()]}/>
```
You can omit any plugin, but the order from above should remain.
</div>

Sorry, the diff of this file is not supported yet

import { AdvancedImage, accessibility } from '../src';
import { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';
import { mount } from 'enzyme';
import React from 'react';
const cloudinaryImage = new CloudinaryImage('sample', { cloudName: 'demo' }, { analytics: false });
describe('accessibility', () => {
it('should apply default', function (done) {
const component = mount(<AdvancedImage cldImg={cloudinaryImage} plugins={[accessibility()]} />);
setTimeout(() => {
expect(component.html()).toContain('src="https://res.cloudinary.com/demo/image/upload/co_black,e_colorize:70/sample"');
done();
}, 0);// one tick
});
it('should apply darkmode', function () {
const component = mount(<AdvancedImage cldImg={cloudinaryImage} plugins={[accessibility('darkmode')]} />);
setTimeout(() => {
expect(component.html()).toContain('src="https://res.cloudinary.com/demo/image/upload/co_black,e_colorize:70/sample"');
}, 0);// one tick
});
it('should apply brightmode', function (done) {
const component = mount(<AdvancedImage cldImg={cloudinaryImage} plugins={[accessibility('brightmode')]} />);
setTimeout(() => {
expect(component.html()).toContain('src="https://res.cloudinary.com/demo/image/upload/co_white,e_colorize:40/sample"');
done();
}, 0);// one tick
});
it('should apply monochrome', function (done) {
const component = mount(<AdvancedImage cldImg={cloudinaryImage} plugins={[accessibility('monochrome')]} />);
setTimeout(() => {
expect(component.html()).toContain('src="https://res.cloudinary.com/demo/image/upload/e_grayscale/sample"');
done();
}, 0);// one tick
});
it('should apply colorblind', function (done) {
const component = mount(<AdvancedImage cldImg={cloudinaryImage} plugins={[accessibility('colorblind')]} />);
setTimeout(() => {
expect(component.html()).toContain('src="https://res.cloudinary.com/demo/image/upload/e_assist_colorblind/sample"');
done();
}, 0);// one tick
});
it('should default if supplied with incorrect mode', function (done) {
const component = mount(<AdvancedImage cldImg={cloudinaryImage} plugins={[accessibility('ddd')]} />);
setTimeout(() => {
expect(component.html())
.toBe('<img src="https://res.cloudinary.com/demo/image/upload/co_black,e_colorize:70/sample">');
done();
}, 0);// one tick
});
});
import { AdvancedImage } from '../src'
import { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';
import { mount } from 'enzyme';
import React from 'react';
const cloudinaryImage = new CloudinaryImage('sample', { cloudName: 'demo' }, { analytics: false });
describe('AdvancedImage', () => {
it('is truthy', () => {
expect(AdvancedImage).toBeTruthy()
});
it('renders AdvancedImage', async () => {
const component = await mount(<AdvancedImage cldImg={cloudinaryImage} />);
expect(component).toMatchSnapshot();
});
it('should create an img tag', async function() {
const component = await mount(<AdvancedImage cldImg={cloudinaryImage} />);
expect(component.html()).toContain('src="https://res.cloudinary.com/demo/image/upload/sample"');
});
it('should add style to img component', async function() {
const component = await mount(<AdvancedImage style={{ opacity: '0.5' }} cldImg={cloudinaryImage} />);
expect(component.find('img').prop('style')).toStrictEqual({ opacity: '0.5' });
});
it('should resolve with a cancel on unmount', function(done) {
const component = mount(
<AdvancedImage
cldImg={cloudinaryImage}
plugins={[(_element: HTMLImageElement | HTMLVideoElement, _cldImage: CloudinaryImage, htmlPluginState: any) => {
return new Promise((resolve) => {
htmlPluginState.cleanupCallbacks.push(() => {
resolve('canceled');
});
}).then((res) => {
expect(res).toBe('canceled');
done();
});
}]}
/>);
component.unmount();
});
it('componentDidUpdate should trigger plugin rerun', function() {
const mock = jest.fn();
const component = mount(<AdvancedImage cldImg={cloudinaryImage} plugins={[mock]} />);
// plugins called once
expect(mock).toHaveBeenCalledTimes(1);
// trigger componentDidUpdate
component.setProps('');
expect(mock).toHaveBeenCalledTimes(2);
});
});
import { AdvancedPicture } from '../src';
import { CloudinaryImage } from '@cloudinary/url-gen';
import { mount } from 'enzyme';
import React from 'react';
import { sepia } from '@cloudinary/url-gen/actions/effect';
const defaultImage = new CloudinaryImage('sample', { cloudName: 'demo' }, { analytics: false });
const sepiaImage = new CloudinaryImage('sample', { cloudName: 'demo' }, { analytics: false }).effect(sepia());
const smallImage = new CloudinaryImage('dog', { cloudName: 'demo' }, { analytics: false });
const largeImage = new CloudinaryImage('woman', { cloudName: 'demo' }, { analytics: false });
describe('AdvancedPicture', () => {
beforeAll(() => {
jest.spyOn(global.console, 'error').mockImplementation(() => {});
});
afterAll(() => {
global.console.error.mockRestore();
});
it('should render picture tag with source', function (done) {
const component = mount(
<AdvancedPicture
cldImg={defaultImage} sources={[
{
minWidth: 500,
maxWidth: 800,
image: smallImage,
sizes: '80vw'
}
]}
/>);
setTimeout(() => {
expect(component.html()).toContain(
'<picture>' +
'<source media="(min-width: 500px) and (max-width: 800px)" sizes="80vw" ' +
'srcset="https://res.cloudinary.com/demo/image/upload/dog">' +
'<img src="https://res.cloudinary.com/demo/image/upload/sample">' +
'</picture>'
);
done();
}, 0);// one tick
});
it('should render picture tag using breakpoints', function (done) {
const component = mount(
<AdvancedPicture
cldImg={defaultImage} breakpoints={[500, 1000, 1500]} sources={[
{
image: smallImage
}
]}
/>);
setTimeout(() => {
expect(component.html()).toContain(
'<picture>' +
'<source srcset="https://res.cloudinary.com/demo/image/upload/c_scale,w_500/dog 500w,' +
'https://res.cloudinary.com/demo/image/upload/c_scale,w_1000/dog 1000w,' +
'https://res.cloudinary.com/demo/image/upload/c_scale,w_1500/dog 1500w">' +
'<img src="https://res.cloudinary.com/demo/image/upload/sample"></picture>'
);
done();
}, 0);// one tick
});
it('should render picture tag with multiple sources', function (done) {
const component = mount(
<AdvancedPicture
cldImg={defaultImage} sources={[
{
minWidth: 500,
maxWidth: 700,
image: smallImage,
sizes: '80vw'
},
{
minWidth: 1000,
maxWidth: 2000,
image: largeImage,
sizes: '80vw'
}
]}
/>);
setTimeout(() => {
expect(component.html()).toContain(
'<picture>' +
'<source media="(min-width: 500px) and (max-width: 700px)" sizes="80vw" ' +
'srcset="https://res.cloudinary.com/demo/image/upload/dog">' +
'<source media="(min-width: 1000px) and (max-width: 2000px)" sizes="80vw" ' +
'srcset="https://res.cloudinary.com/demo/image/upload/woman">' +
'<img src="https://res.cloudinary.com/demo/image/upload/sample">' +
'</picture>'
);
done();
}, 0);// one tick
});
it('should render picture tag with providing only minWidth', function (done) {
const component = mount(
<AdvancedPicture
cldImg={defaultImage} sources={[
{
minWidth: 500,
image: smallImage,
sizes: '80vw'
}
]}
/>);
setTimeout(() => {
expect(component.html()).toContain(
'<picture>' +
'<source media="(min-width: 500px)" sizes="80vw" srcset="https://res.cloudinary.com/demo/image/upload/dog">' +
'<img src="https://res.cloudinary.com/demo/image/upload/sample">' +
'</picture>');
done();
}, 0);// one tick
});
it('should render picture tag with providing only maxWidth', function (done) {
const component = mount(
<AdvancedPicture
cldImg={defaultImage} sources={[
{
maxWidth: 500,
image: smallImage,
sizes: '80vw'
}
]}
/>);
setTimeout(() => {
expect(component.html()).toContain(
'<picture><source media="(max-width: 500px)" sizes="80vw" ' +
'srcset="https://res.cloudinary.com/demo/image/upload/dog">' +
'<img src="https://res.cloudinary.com/demo/image/upload/sample"></picture>');
done();
}, 0);// one tick
});
it('should render without sizes attribute', function (done) {
const component = mount(
<AdvancedPicture
cldImg={defaultImage} sources={[
{
minWidth: 500,
maxWidth: 1000,
image: smallImage
}
]}
/>);
setTimeout(() => {
expect(component.html()).toContain(
'<picture>' +
'<source media="(min-width: 500px) and (max-width: 1000px)" ' +
'srcset="https://res.cloudinary.com/demo/image/upload/dog">' +
'<img src="https://res.cloudinary.com/demo/image/upload/sample"></picture>');
done();
}, 0);// one tick
});
it('autoOptimalBreakpoints: console log error when sizes and autoOptimalBreakpoints are provided',
function (done) {
mount(
<AdvancedPicture
autoOptimalBreakpoints
cldImg={defaultImage}
sources={[
{
minWidth: 500,
sizes: '500px',
image: sepiaImage
}
]}
/>);
setTimeout(() => {
expect(console.error).toHaveBeenCalled();
done();
}, 0);// one tick
});
it('autoOptimalBreakpoints: console log error when min-width and max-width not provided',
function (done) {
mount(
<AdvancedPicture
autoOptimalBreakpoints
cldImg={defaultImage}
sources={[
{
image: sepiaImage
}
]}
/>);
setTimeout(() => {
expect(console.error).toHaveBeenCalled();
done();
}, 0);// one tick
});
it('autoOptimalBreakpoints: console log error when min-width > max-width', function (done) {
mount(
<AdvancedPicture
autoOptimalBreakpoints
cldImg={defaultImage} sources={[
{
maxWidth: 500,
minWidth: 700,
image: smallImage
}
]}
/>);
setTimeout(() => {
expect(console.error).toHaveBeenCalled();
done();
}, 0);// one tick
});
it('autoOptimalBreakpoints: should produce single src when min-width = max-width', function (done) {
const component = mount(
<AdvancedPicture
autoOptimalBreakpoints
cldImg={defaultImage}
sources={[
{
minWidth: 2000,
maxWidth: 2000,
image: sepiaImage
}
]}
/>);
setTimeout(() => {
expect(component.html()).toContain('<picture>' +
'<source media="(min-width: 2000px) and (max-width: 2000px)" sizes="100vw" ' +
'srcset="https://res.cloudinary.com/demo/image/upload/e_sepia/c_scale,w_2000/sample 2000w">' +
'<img src="https://res.cloudinary.com/demo/image/upload/sample">' +
'</picture>'
);
done();
}, 0);// one tick
});
it('autoOptimalBreakpoints: user breakpoints should be used when provided', function (done) {
const component = mount(
<AdvancedPicture
autoOptimalBreakpoints
breakpoints={[500, 1000, 1500]}
cldImg={defaultImage}
sources={[
{
image: sepiaImage
}
]}
/>);
setTimeout(() => {
expect(component.html()).toContain('<picture>' +
'<source sizes="100vw" srcset="https://res.cloudinary.com/demo/image/upload/e_sepia/c_scale,w_500/sample 500w,' +
'https://res.cloudinary.com/demo/image/upload/e_sepia/c_scale,w_1000/sample 1000w,' +
'https://res.cloudinary.com/demo/image/upload/e_sepia/c_scale,w_1500/sample 1500w">' +
'<img src="https://res.cloudinary.com/demo/image/upload/sample"></picture>'
);
done();
}, 0);// one tick
});
it('autoOptimalBreakpoints: min-width and max-width above 768px', function (done) {
const component = mount(
<AdvancedPicture
autoOptimalBreakpoints
cldImg={defaultImage}
sources={[
{
minWidth: 1000,
maxWidth: 2000,
image: sepiaImage
}
]}
/>);
setTimeout(() => {
expect(component.html()).toContain('<picture>' +
'<source media="(min-width: 1000px) and (max-width: 2000px)" sizes="100vw" ' +
'srcset="https://res.cloudinary.com/demo/image/upload/e_sepia/c_scale,w_1280/sample 1280w,' +
'https://res.cloudinary.com/demo/image/upload/e_sepia/c_scale,w_1366/sample 1366w,' +
'https://res.cloudinary.com/demo/image/upload/e_sepia/c_scale,w_1536/sample 1536w' +
',https://res.cloudinary.com/demo/image/upload/e_sepia/c_scale,w_1600/sample 1600w,' +
'https://res.cloudinary.com/demo/image/upload/e_sepia/c_scale,w_1920/sample 1920w">' +
'<img src="https://res.cloudinary.com/demo/image/upload/sample">' +
'</picture>'
);
done();
}, 0);// one tick
});
it('autoOptimalBreakpoints: min-width bellow 768px', function (done) {
const component = mount(
<AdvancedPicture
autoOptimalBreakpoints
cldImg={defaultImage}
sources={[
{
minWidth: 360,
maxWidth: 1700,
image: sepiaImage
}
]}
/>);
setTimeout(() => {
expect(component.html()).toContain('<picture>' +
'<source media="(min-width: 360px) and (max-width: 1700px)" sizes="100vw" ' +
'srcset="https://res.cloudinary.com/demo/image/upload/e_sepia/c_scale,w_750/sample 750w,' +
'https://res.cloudinary.com/demo/image/upload/e_sepia/c_scale,w_828/sample 828w,' +
'https://res.cloudinary.com/demo/image/upload/e_sepia/c_scale,w_1280/sample 1280w,' +
'https://res.cloudinary.com/demo/image/upload/e_sepia/c_scale,w_1366/sample 1366w,' +
'https://res.cloudinary.com/demo/image/upload/e_sepia/c_scale,w_1536/sample 1536w">' +
'<img src="https://res.cloudinary.com/demo/image/upload/sample">' +
'</picture>'
);
done();
}, 0);// one tick
});
it('autoOptimalBreakpoints: should generate srcset using relative width', function (done) {
const component = mount(
<AdvancedPicture
autoOptimalBreakpoints
cldImg={defaultImage}
relativeWidth={0.2}
sources={[
{
minWidth: 375,
maxWidth: 414,
image: sepiaImage
}
]}
/>);
setTimeout(() => {
expect(component.html()).toContain('<picture>' +
'<source media="(min-width: 375px) and (max-width: 414px)" sizes="20vw" ' +
'srcset="https://res.cloudinary.com/demo/image/upload/e_sepia/c_scale,w_150/sample 150w,' +
'https://res.cloudinary.com/demo/image/upload/e_sepia/c_scale,w_166/sample 166w">' +
'<img src="https://res.cloudinary.com/demo/image/upload/sample">' +
'</picture>'
);
done();
}, 0);// one tick
});
it('autoOptimalBreakpoints: replace dimensions when physical-min-width > physical-max-width', function (done) {
const component = mount(
<AdvancedPicture
autoOptimalBreakpoints
cldImg={defaultImage}
sources={[
{
minWidth: 750,
maxWidth: 1000,
image: sepiaImage
}
]}
/>);
setTimeout(() => {
expect(component.html()).toContain('<picture>' +
'<source media="(min-width: 750px) and (max-width: 1000px)" sizes="100vw" ' +
'srcset="https://res.cloudinary.com/demo/image/upload/e_sepia/c_scale,w_1280/sample 1280w,' +
'https://res.cloudinary.com/demo/image/upload/e_sepia/c_scale,w_1366/sample 1366w,' +
'https://res.cloudinary.com/demo/image/upload/e_sepia/c_scale,w_1440/sample 1440w">' +
'<img src="https://res.cloudinary.com/demo/image/upload/sample">' +
'</picture>'
);
done();
}, 0);// one tick
});
});
import { AdvancedVideo } from '../src';
import { CloudinaryVideo } from '@cloudinary/url-gen';
import { mount } from 'enzyme';
import React from 'react';
import { auto, vp9 } from '@cloudinary/url-gen/qualifiers/videoCodec';
import { videoCodec } from '@cloudinary/url-gen/actions/transcode';
const cloudinaryVideo = new CloudinaryVideo('sample', { cloudName: 'demo' }, { analytics: false });
describe('AdvancedVideo', () => {
it('should render video with default sources', function (done) {
const component = mount(<AdvancedVideo cldVid={cloudinaryVideo} />);
setTimeout(() => {
expect(component.html()).toContain(
'<video>' +
'<source src="https://res.cloudinary.com/demo/video/upload/sample.webm" type="video/webm">' +
'<source src="https://res.cloudinary.com/demo/video/upload/sample.mp4" type="video/mp4">' +
'<source src="https://res.cloudinary.com/demo/video/upload/sample.ogg" type="video/ogg"></video>');
done();
}, 0);// one tick
});
it('should render video with input sources', function (done) {
const sources = [
{
type: 'mp4',
codecs: ['vp8', 'vorbis'],
transcode: videoCodec(auto())
},
{
type: 'webm',
codecs: ['avc1.4D401E', 'mp4a.40.2'],
transcode: videoCodec(vp9())
}];
const component = mount(<AdvancedVideo cldVid={cloudinaryVideo} sources={sources} />);
setTimeout(() => {
expect(component.html()).toContain(
'<video>' +
'<source src="https://res.cloudinary.com/demo/video/upload/vc_auto/sample.mp4" type="video/mp4; codecs=vp8, vorbis">' +
'<source src="https://res.cloudinary.com/demo/video/upload/vc_vp9/sample.webm" type="video/webm; codecs=avc1.4D401E, mp4a.40.2"></video>');
done();
}, 0);// one tick
});
it('should pass video attributes', function (done) {
const component = mount(<AdvancedVideo cldVid={cloudinaryVideo} controls autoPlay playsInline loop />);
setTimeout(() => {
expect(component.html()).toContain('controls="" autoplay="" playsinline="" loop=""');
done();
}, 0);// one tick
});
it('should contain poster', function (done) {
const component = mount(<AdvancedVideo cldVid={cloudinaryVideo} poster='www.example.com' />);
setTimeout(() => {
expect(component.html()).toContain('poster="www.example.com"');
done();
}, 0);// one tick
});
it('should simulate onPlay event', function (done) {
const mockCallBack = jest.fn();
const component = mount(<AdvancedVideo cldVid={cloudinaryVideo} onPlay={mockCallBack} />);
setTimeout(() => {
component.find('video').simulate('play');
expect(mockCallBack.mock.calls.length).toEqual(1);
done();
}, 0);// one tick
});
it('should simulate onLoadStart event', function (done) {
const mockCallBack = jest.fn();
const component = mount(<AdvancedVideo cldVid={cloudinaryVideo} onLoadStart={mockCallBack} />);
setTimeout(() => {
component.find('video').simulate('loadstart');
expect(mockCallBack.mock.calls.length).toEqual(1);
done();
}, 0);// one tick
});
it('should simulate onEnded event', function (done) {
const mockCallBack = jest.fn();
const component = mount(<AdvancedVideo cldVid={cloudinaryVideo} onEnded={mockCallBack} />);
setTimeout(() => {
component.find('video').simulate('ended');
expect(mockCallBack.mock.calls.length).toEqual(1);
done();
}, 0);// one tick
});
it('should simulate onError event', function (done) {
const mockCallBack = jest.fn();
const component = mount(<AdvancedVideo cldVid={cloudinaryVideo} onError={mockCallBack} />);
setTimeout(() => {
component.find('video').simulate('error');
expect(mockCallBack.mock.calls.length).toEqual(1);
done();
}, 0);// one tick
});
it('should simulate onPlaying event', function (done) {
const mockCallBack = jest.fn();
const component = mount(<AdvancedVideo cldVid={cloudinaryVideo} onPlaying={mockCallBack} />);
setTimeout(() => {
component.find('video').simulate('playing');
expect(mockCallBack.mock.calls.length).toEqual(1);
done();
}, 0);// one tick
});
it('Should support forwarding innerRef to underlying video element', () => {
const myRef = React.createRef();
mount(<AdvancedVideo cldVid={cloudinaryVideo} innerRef={myRef} />);
const video: any = myRef.current;
['play', 'pause', 'canPlayType', 'addTextTrack'].forEach((func) => {
expect(typeof video[func]).toBe('function');
});
});
});
import { AdvancedImage, lazyload } from '../src'
import { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';
import { mount } from 'enzyme';
import React from 'react';
import testWithMockedIntersectionObserver from './testUtils/setupIntersectionObserverMock';
const cloudinaryImage = new CloudinaryImage('sample', { cloudName: 'demo' }, { analytics: false });
describe('lazy-load', () => {
it('should not have src pre-scroll', async function() {
const component = await mount(
<div>
<div style={{ height: '1000px' }} />
<AdvancedImage cldImg={cloudinaryImage} plugins={[lazyload()]} />
</div>
);
// no src pre scroll
expect(component.html()).toBe('<div><div style="height: 1000px;"></div><img></div>');
});
it('should have src when in view', function(done) {
const elm = document.createElement('img');
testWithMockedIntersectionObserver((mockIntersectionEvent: ({}) => void) => {
const component = mount(<AdvancedImage cldImg={cloudinaryImage} plugins={[lazyload()]} />);
mockIntersectionEvent([{ isIntersecting: true, target: component.getDOMNode() }]);
setTimeout(() => {
expect(component.html()).toContain('src="https://res.cloudinary.com/demo/image/upload/sample"');
done();
}, 0);// one tick
});
});
it('should set lazyload root margin and threshold', function(done) {
const elm = document.createElement('img');
testWithMockedIntersectionObserver((mockIntersectionEvent: ({}) => void) => {
// @ts-ignore
const component = mount(<AdvancedImage cldImg={cloudinaryImage} plugins={[(lazyload('10px', 0.5))]} />);
mockIntersectionEvent([{ isIntersecting: true, target: component.getDOMNode() }]);
setTimeout(() => {
expect(component.html()).toContain('src="https://res.cloudinary.com/demo/image/upload/sample"');
done();
}, 0);// one tick
});
});
});
import { AdvancedImage, placeholder } from '../src'
import { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';
import { PLACEHOLDER_IMAGE_OPTIONS } from '../../html/src/utils/internalConstants';
import { mount } from 'enzyme';
import React from 'react';
import { sepia } from '@cloudinary/url-gen/actions/effect';
describe('placeholder', () => {
let cloudinaryImage: CloudinaryImage;
const mockImage = {
src: null,
onload: () => {},
onerror: () => {}
};
beforeEach(() => {
// @ts-ignore
window.Image = function() { return mockImage };
cloudinaryImage = new CloudinaryImage('sample', { cloudName: 'demo' }, { analytics: false });
});
it('should apply default', function (done) {
const component = mount(<AdvancedImage cldImg={cloudinaryImage} plugins={[placeholder()]} />);
setTimeout(() => {
expect(component.html()).toContain(`src="https://res.cloudinary.com/demo/image/upload/${PLACEHOLDER_IMAGE_OPTIONS.vectorize}/sample"`);
done();
}, 0);// one tick
});
it("should apply 'vectorize'", function () {
const component = mount(<AdvancedImage cldImg={cloudinaryImage} plugins={[placeholder('vectorize')]} />);
setTimeout(() => {
expect(component.html()).toContain(`src="https://res.cloudinary.com/demo/image/upload/${PLACEHOLDER_IMAGE_OPTIONS.vectorize}/sample"`);
}, 0);// one tick
});
it('should apply pixelate', function (done) {
const component = mount(<AdvancedImage cldImg={cloudinaryImage} plugins={[placeholder('pixelate')]} />);
setTimeout(() => {
expect(component.html()).toContain(`src="https://res.cloudinary.com/demo/image/upload/${PLACEHOLDER_IMAGE_OPTIONS.pixelate}/sample"`);
done();
}, 0);// one tick
});
it('should apply blur', function (done) {
const component = mount(<AdvancedImage cldImg={cloudinaryImage} plugins={[placeholder('blur')]} />);
setTimeout(() => {
expect(component.html()).toContain(`src="https://res.cloudinary.com/demo/image/upload/${PLACEHOLDER_IMAGE_OPTIONS.blur}/sample"`);
done();
}, 0);// one tick
});
it('should apply predominant-color', function (done) {
const component = mount(<AdvancedImage cldImg={cloudinaryImage} plugins={[placeholder('predominant-color')]} />);
setTimeout(() => {
expect(component.html()).toContain(`src="https://res.cloudinary.com/demo/image/upload/${PLACEHOLDER_IMAGE_OPTIONS['predominant-color']}/sample"`);
done();
}, 0);// one tick
});
it('should default if supplied with incorrect mode', function (done) {
const component = mount(<AdvancedImage cldImg={cloudinaryImage} plugins={[placeholder('ddd')]} />);
setTimeout(() => {
expect(component.html()).toContain(`src="https://res.cloudinary.com/demo/image/upload/${PLACEHOLDER_IMAGE_OPTIONS.vectorize}/sample"`);
done();
}, 0);// one tick
});
it('should append placeholder transformation', function (done) {
cloudinaryImage.effect(sepia());
const component = mount(<AdvancedImage cldImg={cloudinaryImage} plugins={[placeholder()]} />);
setTimeout(() => {
expect(component.html()).toContain(`src="https://res.cloudinary.com/demo/image/upload/e_sepia/${PLACEHOLDER_IMAGE_OPTIONS.vectorize}/sample"`);
done();
}, 0);// one tick
});
/*
This test is built with two setTimouts since the placeholder plugin makes use of two promises.
The placeholder image loads first. Once it loads, the promise is resolved and the
larger image will load. Once the larger image loads, promised and plugin is resolved.
*/
it('should not fail error', function (done) {
const component = mount(<AdvancedImage cldImg={cloudinaryImage} plugins={[placeholder()]} />);
setTimeout(() => {
// @ts-ignore
component.getDOMNode().onload(); // simulate element onload
setTimeout(() => {
mockImage.onerror(); // simulate image onerror
expect(mockImage.src).toBe('https://res.cloudinary.com/demo/image/upload/sample');
done();
})
}, 5);// one tick
});
});
import { AdvancedImage, responsive } from '../src'
import { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';
import { mount } from 'enzyme';
import React from 'react';
import { ResponsiveHelper } from './testUtils/responsiveHelperWrapper';
import { crop } from '@cloudinary/url-gen/actions/resize';
import { dispatchResize } from './testUtils/dispatchResize';
import FakeTimers from '@sinonjs/fake-timers'
const cloudinaryImage = new CloudinaryImage('sample', { cloudName: 'demo' }, { analytics: false });
describe('responsive', () => {
let clock:any;
beforeEach(() => {
clock = FakeTimers.install()
});
afterEach(() => {
clock.uninstall()
});
it('should apply initial container width (default 250)', async function () {
const component = mount(
<ResponsiveHelper>
<AdvancedImage cldImg={cloudinaryImage} plugins={[responsive()]} />
</ResponsiveHelper>);
window.dispatchEvent(new Event('resize'));
clock.tick(100); // timeout for debounce
const el = component.find('#wrapper').getDOMNode();
expect(el.clientWidth).toBe(250);
});
it('should update container width on window resize', function () {
const component = mount(
<ResponsiveHelper>
<AdvancedImage cldImg={cloudinaryImage} plugins={[responsive()]} />
</ResponsiveHelper>);
const el = dispatchResize(component, 100);
clock.tick(100); // timeout for debounce
expect(el.clientWidth).toBe(100);
});
it('should step by the 100th', async function () {
const component = mount(
<ResponsiveHelper>
<AdvancedImage cldImg={cloudinaryImage} plugins={[responsive(100)]} />
</ResponsiveHelper>);
await clock.tickAsync(0); // one tick
window.dispatchEvent(new Event('resize'));
await clock.tickAsync(100); // timeout for debounce
expect(component.html()).toContain('src="https://res.cloudinary.com/demo/image/upload/c_scale,w_300/sample"');
});
it('should step by breakpoints', async function () {
const component = mount(
<ResponsiveHelper>
<AdvancedImage cldImg={cloudinaryImage} plugins={[responsive([800, 1000, 1200, 3000])]} />
</ResponsiveHelper>);
await clock.tickAsync(0); // one tick
window.dispatchEvent(new Event('resize'));
await clock.tickAsync(100); // timeout for debounce
expect(component.html()).toContain('src="https://res.cloudinary.com/demo/image/upload/c_scale,w_800/sample"');
// simulate resize to 975
await clock.tickAsync(0); // one tick
dispatchResize(component, 975);
await clock.tickAsync(100); // timeout for debounce
expect(component.html()).toContain('src="https://res.cloudinary.com/demo/image/upload/c_scale,w_1000/sample"');
});
it('should not resize to larger than provided breakpoints', async function () {
const component = mount(
<ResponsiveHelper>
<AdvancedImage cldImg={cloudinaryImage} plugins={[responsive([800, 1000, 1200, 3000])]} />
</ResponsiveHelper>);
await clock.tickAsync(0); // one tick
dispatchResize(component, 4000);
await clock.tickAsync(100); // timeout for debounce
expect(component.html()).toContain('src="https://res.cloudinary.com/demo/image/upload/c_scale,w_3000/sample"');
});
it('should handle unordered breakpoints', async function () {
const component = mount(
<ResponsiveHelper>
<AdvancedImage cldImg={cloudinaryImage} plugins={[responsive([1000, 800, 3000, 1200])]} />
</ResponsiveHelper>);
await clock.tickAsync(0); // one tick
dispatchResize(component, 5000);
await clock.tickAsync(100); // timeout for debounce
expect(component.html()).toContain('src="https://res.cloudinary.com/demo/image/upload/c_scale,w_3000/sample"');
});
it('should append to existing transformation', async function () {
cloudinaryImage.resize(crop('500'));
const component = mount(
<ResponsiveHelper>
<AdvancedImage cldImg={cloudinaryImage} plugins={[responsive()]} />
</ResponsiveHelper>);
await clock.tickAsync(0); // one tick
window.dispatchEvent(new Event('resize'));
await clock.tickAsync(100); // timeout for debounce
expect(component.html()).toContain('src="https://res.cloudinary.com/demo/image/upload/c_crop,w_500/c_scale,w_250/sample"');
});
});
/**
* @jest-environment node
*/
import { AdvancedImage, placeholder, responsive, accessibility, lazyload } from '../src'
import { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';
import React from 'react';
import { renderToString } from 'react-dom/server'
const cloudinaryImage = new CloudinaryImage('sample', { cloudName: 'demo' }, { analytics: false });
describe('ssr', () => {
it('should render accessibility transformation with accessibility', function (done) {
const ElementImageHtml = renderToString(<AdvancedImage cldImg={cloudinaryImage} plugins={[accessibility()]} />);
setTimeout(() => {
expect(ElementImageHtml).toContain('https://res.cloudinary.com/demo/image/upload/co_black,e_colorize:70/sample');
done();
}, 0);// one tick
});
it('should render original image with placeholder', function (done) {
const ElementImageHtml = renderToString(<AdvancedImage cldImg={cloudinaryImage} plugins={[placeholder()]} />);
setTimeout(() => {
expect(ElementImageHtml).toContain('https://res.cloudinary.com/demo/image/upload/sample');
done();
}, 0);// one tick
});
it('should render original image when responsive', function (done) {
const ElementImageHtml = renderToString(<AdvancedImage cldImg={cloudinaryImage} plugins={[responsive()]} />);
setTimeout(() => {
expect(ElementImageHtml).toContain('https://res.cloudinary.com/demo/image/upload/sample');
done();
}, 0);// one tick
});
it('should render original image when lazy loaded', function (done) {
const ElementImageHtml = renderToString(<AdvancedImage cldImg={cloudinaryImage} plugins={[lazyload()]} />);
setTimeout(() => {
expect(ElementImageHtml).toContain('https://res.cloudinary.com/demo/image/upload/sample');
done();
}, 0);// one tick
});
});
/**
* Util function used to dispatch a resize event used in the responsive tests
* @param component
* @param resizeValue
*/
export function dispatchResize(component: any, resizeValue:number){
const el = component.find('#wrapper').getDOMNode();
Object.defineProperty(el, 'clientWidth', {value: resizeValue, configurable: true});
window.dispatchEvent(new Event('resize'));
return el;
}
import React, {useEffect, useRef, useState} from 'react';
/**
* Simulates clientWidth
* Initializes clientWidth with 250
*/
export function ResponsiveHelper(props: { children: React.ReactNode }) {
const ref = useRef(null);
const [refElement, setRefElement] = useState(false)
useEffect(() => {
const parentElement = ref.current as unknown as HTMLElement;
Object.defineProperty(parentElement, 'clientWidth', {value: 250, configurable: true});
// @ts-ignore
setRefElement(ref.current);
}, []);
return <div
id='wrapper'
ref={ref}
>
{refElement && props.children}
</div>
}
function testWithMockedIntersectionObserver(cb: (...args:any) => void) {
let intersectCallback: (root?: Element, rootMargin?: string, thresholds?: number) => void = () => {}; // will be
// populated later
let nativeIntersectionObserver = global.IntersectionObserver;
// Mock IntersectionObserver
// @ts-ignore
global.IntersectionObserver = class {
constructor(cb: (root?: Element, rootMargin?: string, thresholds?: number) => any) {
// This is the callback that notifies when an intersection occurs
// We'll store it to use it later
intersectCallback = cb;
}
observe() {}
unobserve() {}
};
cb((root?: Element, rootMargin?: string, thresholds?: number) => {
intersectCallback(root, rootMargin, thresholds);
});
// restore
global.IntersectionObserver = nativeIntersectionObserver;
}
export default testWithMockedIntersectionObserver;
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"jsx": "react",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": [
"./*.tsx"
]
}
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

Sorry, the diff of this file is not supported yet

{
"parser": "@typescript-eslint/parser",
"extends": [
"standard",
"standard-react",
"plugin:@typescript-eslint/eslint-recommended"
],
"env": {
"node": true,
"jest": true
},
"parserOptions": {
"ecmaVersion": 2020,
"ecmaFeatures": {
"legacyDecorators": true,
"jsx": true
}
},
"settings": {
"react": {
"version": "16"
}
},
"rules": {
"space-before-function-paren": 0,
"react/prop-types": 0,
"react/jsx-handler-names": 0,
"react/jsx-fragments": 0,
"react/no-unused-prop-types": 0,
"import/export": 0,
"no-unused-vars": "off",
"semi": "off"
}
}
{
"singleQuote": true,
"jsxSingleQuote": true,
"semi": false,
"tabWidth": 2,
"bracketSpacing": true,
"jsxBracketSameLine": false,
"arrowParens": "always",
"trailingComma": "none"
}
language: node_js
node_js:
- 12
- 10
module.exports = {
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript'
]
};
import React from 'react';
import { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';
import { HtmlImageLayer, Plugins } from '@cloudinary/html';
interface ImgProps {
cldImg: CloudinaryImage;
plugins?: Plugins;
[x: string]: any;
}
/**
* @mixin ReactSDK
* @description The Cloudinary React SDK contains components like <AdvancedImage> to easily render your media assets from Cloudinary.
* The SDK also comes with support for optional js plugins that make the components smart, with features like lazy loading, placeholder, accessibility & responsiveness
*
* @example
* <caption>
* Please note that the order of the plugins is important. See home for more details.
* </caption>
* // Example
* import {CloudinaryImage} from "@cloudinary/url-gen/assets/CloudinaryImage";
* import {
* AdvancedImage,
* accessibility,
* responsive,
* lazyload,
* placeholder
* } from '@cloudinary/react';
*
* const App = () => {
*
* const myCld = new Cloudinary({ cloudName: 'demo'});
* let img = myCld().image('sample');
*
* return (
* <div>
* <div style={{height: "1000px"}}/>
* <AdvancedImage
* cldImg={img}
* plugins={[lazyload(), responsive(100), placeholder()]}
* />
* </div>
* )
* };
*
*
*
*
*
*/
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary image component
* @prop {CloudinaryImage} cldImg Generated by @cloudinary/url-gen
* @prop {Plugins} plugins Advanced image component plugins accessibility(), responsive(), lazyload(), placeholder()
*/
declare class AdvancedImage extends React.Component<ImgProps> {
imageRef: React.RefObject<HTMLImageElement>;
htmlLayerInstance: HtmlImageLayer;
constructor(props: ImgProps);
/**
* On mount creates a new HTMLLayer instance and initialises with ref to img element,
* user generated cloudinaryImage and the plugins to be used
*/
componentDidMount(): void;
/**
* On update we cancel running plugins and update image instance with the state of user
* cloudinaryImage and the state of plugins
*/
componentDidUpdate(): void;
/**
* On unmount we cancel the currently running plugins
*/
componentWillUnmount(): void;
render(): JSX.Element;
}
export { AdvancedImage };
import React from 'react';
import { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';
import { HtmlPictureLayer, PictureSources } from '@cloudinary/html';
interface PictureProps {
cldImg: CloudinaryImage;
breakpoints?: number[];
sources?: PictureSources;
autoOptimalBreakpoints?: boolean;
relativeWidth?: number;
[x: string]: any;
}
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary picture component
* @prop {CloudinaryImage} transformation Generated by @cloudinary/url-gen
* @prop {PictureSources} sources sources to generate source tag
* @example
* <caption>
* Using custom defined resources.
* </caption>
* const img = new CloudinaryImage('sample', { cloudName: 'demo'});
* const sources = [
* {
* minWidth:500,
* maxWidth:2000,
* sizes: "80vw,
* image: img
* },
* {
* minWidth:3000,
* maxWidth:4000,
* sizes: "80vw,
* image: img
* }];
*
* return <AdvancedPicture cldImg={img} sources={sources} />
*/
declare class AdvancedPicture extends React.Component<PictureProps> {
pictureRef: React.RefObject<HTMLPictureElement>;
htmlPictureLayerInstance: HtmlPictureLayer;
constructor(props: PictureProps);
/**
* On mount creates a new HTMLPictureLayer instance and initialises with ref to picture element,
* user generated cloudinaryImage and the sources to be used
*/
componentDidMount(): void;
/**
* On update we update the image instance with the state of user
* cloudinaryImage and the state of sources
*/
componentDidUpdate(): void;
render(): JSX.Element;
}
export { AdvancedPicture };
import { Component, EventHandler, MutableRefObject, SyntheticEvent } from 'react';
import { CloudinaryVideo } from '@cloudinary/url-gen';
import { HtmlVideoLayer, Plugins, VideoSources } from '@cloudinary/html';
declare type ReactEventHandler<T = Element> = EventHandler<SyntheticEvent<T>>;
interface VideoProps {
cldVid: CloudinaryVideo;
plugins?: Plugins;
sources?: VideoSources;
innerRef?: ((instance: any) => void) | MutableRefObject<unknown> | null;
controls?: boolean;
loop?: boolean;
muted?: boolean;
poster?: string;
preload?: string;
autoPlay?: boolean;
playsInline?: boolean;
onPlay?: ReactEventHandler<any>;
onLoadStart?: ReactEventHandler<any>;
onPlaying?: ReactEventHandler<any>;
onError?: ReactEventHandler<any>;
onEnded?: ReactEventHandler<any>;
}
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary video component
* @prop {CloudinaryVideo} transformation Generated by @cloudinary/url-gen
* @prop {Plugins} plugins Advanced image component plugins lazyload()
* @prop videoAttributes Optional attributes include controls, loop, muted, poster, preload, autoplay
* @prop videoEvents Optional video events include play, loadstart, playing, error, ended
* @prop {VideoSources} sources Optional sources to generate
* @example
* <caption>
* Using custom defined resources.
* </caption>
* const vid = new CloudinaryVideo('dog', {cloudName: 'demo'});
* const videoEl = useRef();
* const sources = [
* {
* type: 'mp4',
* codecs: ['vp8', 'vorbis'],
* transcode: videoCodec(auto())
* },
* {
* type: 'webm',
* codecs: ['avc1.4D401E', 'mp4a.40.2'],
* videoCodec: videoCodec(auto())
* }];
*
* return <AdvancedVideo cldVid={vid} sources={sources} ref={videoEl} controls />
*/
declare class AdvancedVideo extends Component<VideoProps> {
videoRef: MutableRefObject<HTMLVideoElement | null>;
htmlVideoLayerInstance: HtmlVideoLayer;
constructor(props: VideoProps);
/**
* On mount creates a new HTMLVideoLayer instance and initialises with ref to video element,
* user generated cloudinaryVideo and the plugins to be used
*/
componentDidMount(): void;
/**
* On update we cancel running plugins and update the video instance if the src
* was changed
*/
componentDidUpdate(): void;
/**
* On unmount we cancel the currently running plugins
*/
componentWillUnmount(): void;
/**
* returns video attributes
*/
getVideoAttributes(): {
controls: boolean | undefined;
loop: boolean | undefined;
muted: boolean | undefined;
poster: string | undefined;
preload: string | undefined;
autoplay: boolean | undefined;
playsinline: boolean | undefined;
};
/**
* Attach both this.videoRef and props.innerRef as ref to the given element
* @param element - the element to attach a ref to
*/
attachRef(element: HTMLVideoElement): void;
render(): JSX.Element;
}
export { AdvancedVideo };
1.0.0-beta.13 / 2021-11-30
==================
* Add Lerna (#104)
1.0.0-beta.11 / 2021-09-14
==================
* updated to html to latest version (#96)
1.0.0-beta.10 / 2021-09-14
==================
New functionality
-----------------
* added autoOptimalBreakpoints to picture tag (#86)
Other changes
-----------------
* changed to url-gen package name (#94)
1.0.0-beta.9 / 2021-07-04
==================
* Fix/common js build (#87)
* Add advanced picture (#84)
1.0.0-beta.8 / 2021-05-12
==================
Other changes
-----------------
* Release pipeline testing
1.0.0-beta.7 / 2021-05-12
==================
Other changes
-----------------
* Fix svelte npm package file contents
1.0.0-beta.6 / 2021-05-11
==================
Other changes
-----------------
* Release pipeline testing
1.0.0-beta.4 / 2021-05-09
==================
New functionality
-----------------
* align video attributes in React and Angular(#77)
* Added ondestroy lifecycle hook to video component (#78)
Other changes
-----------------
* Disable package-lock generation by adding .npmrc config
* Feature/add vue sdk infrastructure (#74)
* Add dynamic copy right date (#76)
1.0.0-beta.3 / 2021-04-12
==================
New functionality
-----------------
* React - Add innerRef prop to AdvanceVideo component (#65)
* React - Add video component (#59)
* Shared(Breaking) - Update video sources to accept Transcode action (#64)
Other changes
-----------------
* Svelte - Fix ts errors by adding importsNotUsedAsValues rule (#68)
* Angular - Add enableProdMode() (#63)
* Svelte tests - Add svelte ssr tests (#62)
* Svelte tests - Add responsive unit tests for svelte sdk (#60)
* Angular tests - add missing angular tests (#61)
* React tests - add react e2e tests (#58)
* Svelte docs - Add svelte sdk docs (#57)
* React - Update dependency of react version to be ^16.3.0 || ^17.0.0 (#49)
* Shared - fix status canceled error on placeholder (#54)
* Shared - Feature/add video layer (#52)
1.0.0-beta.1 / 2021-02-24
==================
New functionality
-----------------
* Add svelte sdk (#48)
Other changes
-----------------
* Upgrade to base beta (#51)
* Handle placeholder onerror (#46)
* Add travis.yml file (#50)
* Docs - Add version number to the docs reference (#47)
* Docs - Finalize readme before release (#45)
1.0.0-beta.0 / 2021-02-02
==================
Other changes
---------------
* Beta release
1.0.0-alpha.5 / 2021-02-02
==================
Other changes
---------------
* Add changelog
* Test full release-cycle using jenkins
1.0.0-alpha.4 / 2021-01-31
==========================
Initial Release
-------------
* Implement plugins - Responsive, Placeholder, Accessibility, Lazyload
* Implement React and Angular image components
import { placeholder, accessibility, lazyload, responsive } from '@cloudinary/html';
import { AdvancedImage } from './AdvancedImage';
import { AdvancedVideo } from './AdvancedVideo';
import { AdvancedPicture } from './AdvancedPicture';
export { placeholder, accessibility, lazyload, responsive, AdvancedImage, AdvancedVideo, AdvancedPicture };
import { HtmlImageLayer, cancelCurrentlyRunningPlugins, isBrowser, serverSideSrc, HtmlVideoLayer, HtmlPictureLayer } from '@cloudinary/html';
export { accessibility, lazyload, placeholder, responsive } from '@cloudinary/html';
import React, { createRef, Component } from 'react';
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
_setPrototypeOf(subClass, superClass);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
var _excluded$2 = ["cldImg", "plugins"];
/**
* @mixin ReactSDK
* @description The Cloudinary React SDK contains components like <AdvancedImage> to easily render your media assets from Cloudinary.
* The SDK also comes with support for optional js plugins that make the components smart, with features like lazy loading, placeholder, accessibility & responsiveness
*
* @example
* <caption>
* Please note that the order of the plugins is important. See home for more details.
* </caption>
* // Example
* import {CloudinaryImage} from "@cloudinary/url-gen/assets/CloudinaryImage";
* import {
* AdvancedImage,
* accessibility,
* responsive,
* lazyload,
* placeholder
* } from '@cloudinary/react';
*
* const App = () => {
*
* const myCld = new Cloudinary({ cloudName: 'demo'});
* let img = myCld().image('sample');
*
* return (
* <div>
* <div style={{height: "1000px"}}/>
* <AdvancedImage
* cldImg={img}
* plugins={[lazyload(), responsive(100), placeholder()]}
* />
* </div>
* )
* };
*
*
*
*
*
*/
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary image component
* @prop {CloudinaryImage} cldImg Generated by @cloudinary/url-gen
* @prop {Plugins} plugins Advanced image component plugins accessibility(), responsive(), lazyload(), placeholder()
*/
var AdvancedImage = /*#__PURE__*/function (_React$Component) {
_inheritsLoose(AdvancedImage, _React$Component);
function AdvancedImage(props) {
var _this;
_this = _React$Component.call(this, props) || this;
_this.imageRef = /*#__PURE__*/React.createRef();
return _this;
}
/**
* On mount creates a new HTMLLayer instance and initialises with ref to img element,
* user generated cloudinaryImage and the plugins to be used
*/
var _proto = AdvancedImage.prototype;
_proto.componentDidMount = function componentDidMount() {
this.htmlLayerInstance = new HtmlImageLayer(this.imageRef.current, this.props.cldImg, this.props.plugins);
}
/**
* On update we cancel running plugins and update image instance with the state of user
* cloudinaryImage and the state of plugins
*/
;
_proto.componentDidUpdate = function componentDidUpdate() {
cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState); // call html layer to update the dom again with plugins and reset toBeCanceled
this.htmlLayerInstance.update(this.props.cldImg, this.props.plugins);
}
/**
* On unmount we cancel the currently running plugins
*/
;
_proto.componentWillUnmount = function componentWillUnmount() {
// safely cancel running events on unmount
cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);
};
_proto.render = function render() {
var _this$props = this.props,
otherProps = _objectWithoutPropertiesLoose(_this$props, _excluded$2);
if (isBrowser()) {
// on client side render
return /*#__PURE__*/React.createElement("img", Object.assign({
suppressHydrationWarning: true
}, otherProps, {
ref: this.imageRef
}));
} else {
// on server side render
var src = serverSideSrc(this.props.plugins, this.props.cldImg);
return /*#__PURE__*/React.createElement("img", Object.assign({}, otherProps, {
src: src
}));
}
};
return AdvancedImage;
}(React.Component);
var _excluded$1 = ["cldVid", "plugins", "sources", "innerRef"];
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary video component
* @prop {CloudinaryVideo} transformation Generated by @cloudinary/url-gen
* @prop {Plugins} plugins Advanced image component plugins lazyload()
* @prop videoAttributes Optional attributes include controls, loop, muted, poster, preload, autoplay
* @prop videoEvents Optional video events include play, loadstart, playing, error, ended
* @prop {VideoSources} sources Optional sources to generate
* @example
* <caption>
* Using custom defined resources.
* </caption>
* const vid = new CloudinaryVideo('dog', {cloudName: 'demo'});
* const videoEl = useRef();
* const sources = [
* {
* type: 'mp4',
* codecs: ['vp8', 'vorbis'],
* transcode: videoCodec(auto())
* },
* {
* type: 'webm',
* codecs: ['avc1.4D401E', 'mp4a.40.2'],
* videoCodec: videoCodec(auto())
* }];
*
* return <AdvancedVideo cldVid={vid} sources={sources} ref={videoEl} controls />
*/
var AdvancedVideo = /*#__PURE__*/function (_Component) {
_inheritsLoose(AdvancedVideo, _Component);
function AdvancedVideo(props) {
var _this;
_this = _Component.call(this, props) || this;
_this.videoRef = /*#__PURE__*/createRef();
_this.attachRef = _this.attachRef.bind(_assertThisInitialized(_this));
return _this;
}
/**
* On mount creates a new HTMLVideoLayer instance and initialises with ref to video element,
* user generated cloudinaryVideo and the plugins to be used
*/
var _proto = AdvancedVideo.prototype;
_proto.componentDidMount = function componentDidMount() {
this.htmlVideoLayerInstance = new HtmlVideoLayer(this.videoRef && this.videoRef.current, this.props.cldVid, this.props.sources, this.props.plugins, this.getVideoAttributes());
}
/**
* On update we cancel running plugins and update the video instance if the src
* was changed
*/
;
_proto.componentDidUpdate = function componentDidUpdate() {
cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState); // call html layer to update the dom again with plugins and reset toBeCanceled
this.htmlVideoLayerInstance.update(this.props.cldVid, this.props.sources, this.props.plugins, this.getVideoAttributes());
}
/**
* On unmount we cancel the currently running plugins
*/
;
_proto.componentWillUnmount = function componentWillUnmount() {
// safely cancel running events on unmount
cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState);
}
/**
* returns video attributes
*/
;
_proto.getVideoAttributes = function getVideoAttributes() {
return {
controls: this.props.controls,
loop: this.props.loop,
muted: this.props.muted,
poster: this.props.poster,
preload: this.props.preload,
autoplay: this.props.autoPlay,
playsinline: this.props.playsInline
};
}
/**
* Attach both this.videoRef and props.innerRef as ref to the given element
* @param element - the element to attach a ref to
*/
;
_proto.attachRef = function attachRef(element) {
this.videoRef.current = element;
var innerRef = this.props.innerRef;
if (innerRef) {
if (innerRef instanceof Function) {
innerRef(element);
} else {
innerRef.current = element;
}
}
};
_proto.render = function render() {
var _this$props = this.props,
videoEvents = _objectWithoutPropertiesLoose(_this$props, _excluded$1);
return /*#__PURE__*/React.createElement("video", Object.assign({}, videoEvents, {
ref: this.attachRef
}));
};
return AdvancedVideo;
}(Component);
var _excluded = ["cldImg", "breakpoints", "sources", "autoOptimalBreakpoints", "relativeWidth"];
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary picture component
* @prop {CloudinaryImage} transformation Generated by @cloudinary/url-gen
* @prop {PictureSources} sources sources to generate source tag
* @example
* <caption>
* Using custom defined resources.
* </caption>
* const img = new CloudinaryImage('sample', { cloudName: 'demo'});
* const sources = [
* {
* minWidth:500,
* maxWidth:2000,
* sizes: "80vw,
* image: img
* },
* {
* minWidth:3000,
* maxWidth:4000,
* sizes: "80vw,
* image: img
* }];
*
* return <AdvancedPicture cldImg={img} sources={sources} />
*/
var AdvancedPicture = /*#__PURE__*/function (_React$Component) {
_inheritsLoose(AdvancedPicture, _React$Component);
function AdvancedPicture(props) {
var _this;
_this = _React$Component.call(this, props) || this;
_this.pictureRef = /*#__PURE__*/React.createRef();
return _this;
}
/**
* On mount creates a new HTMLPictureLayer instance and initialises with ref to picture element,
* user generated cloudinaryImage and the sources to be used
*/
var _proto = AdvancedPicture.prototype;
_proto.componentDidMount = function componentDidMount() {
this.htmlPictureLayerInstance = new HtmlPictureLayer(this.pictureRef.current, this.props.cldImg, this.props.breakpoints, this.props.sources, this.props.autoOptimalBreakpoints, this.props.relativeWidth);
}
/**
* On update we update the image instance with the state of user
* cloudinaryImage and the state of sources
*/
;
_proto.componentDidUpdate = function componentDidUpdate() {
// call html layer to update the dom
this.htmlPictureLayerInstance.update(this.props.cldImg, this.props.breakpoints, this.props.sources, this.props.autoOptimalBreakpoints, this.props.relativeWidth);
};
_proto.render = function render() {
var _this$props = this.props,
otherProps = _objectWithoutPropertiesLoose(_this$props, _excluded);
return /*#__PURE__*/React.createElement("picture", Object.assign({}, otherProps, {
ref: this.pictureRef
}));
};
return AdvancedPicture;
}(React.Component);
export { AdvancedImage, AdvancedPicture, AdvancedVideo };
//# sourceMappingURL=index.esm.js.map
{"version":3,"file":"index.esm.js","sources":["../src/AdvancedImage.tsx","../src/AdvancedVideo.tsx","../src/AdvancedPicture.tsx"],"sourcesContent":["import React from 'react';\nimport { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';\n\nimport {\n HtmlImageLayer,\n Plugins,\n isBrowser,\n serverSideSrc,\n cancelCurrentlyRunningPlugins\n} from '@cloudinary/html'\n\ninterface ImgProps {\n cldImg: CloudinaryImage,\n plugins?: Plugins,\n [x: string]: any\n}\n\n/**\n * @mixin ReactSDK\n * @description The Cloudinary React SDK contains components like <AdvancedImage> to easily render your media assets from Cloudinary.\n * The SDK also comes with support for optional js plugins that make the components smart, with features like lazy loading, placeholder, accessibility & responsiveness\n *\n * @example\n * <caption>\n * Please note that the order of the plugins is important. See home for more details.\n * </caption>\n * // Example\n * import {CloudinaryImage} from \"@cloudinary/url-gen/assets/CloudinaryImage\";\n * import {\n * AdvancedImage,\n * accessibility,\n * responsive,\n * lazyload,\n * placeholder\n * } from '@cloudinary/react';\n *\n * const App = () => {\n *\n * const myCld = new Cloudinary({ cloudName: 'demo'});\n * let img = myCld().image('sample');\n *\n * return (\n * <div>\n * <div style={{height: \"1000px\"}}/>\n * <AdvancedImage\n * cldImg={img}\n * plugins={[lazyload(), responsive(100), placeholder()]}\n * />\n * </div>\n * )\n * };\n *\n *\n *\n *\n *\n */\n\n/**\n * @memberOf ReactSDK\n * @type {Component}\n * @description The Cloudinary image component\n * @prop {CloudinaryImage} cldImg Generated by @cloudinary/url-gen\n * @prop {Plugins} plugins Advanced image component plugins accessibility(), responsive(), lazyload(), placeholder()\n */\nclass AdvancedImage extends React.Component <ImgProps> {\n imageRef: React.RefObject<HTMLImageElement>;\n htmlLayerInstance: HtmlImageLayer;\n\n constructor(props: ImgProps) {\n super(props);\n this.imageRef = React.createRef();\n }\n\n /**\n * On mount creates a new HTMLLayer instance and initialises with ref to img element,\n * user generated cloudinaryImage and the plugins to be used\n */\n componentDidMount() {\n this.htmlLayerInstance = new HtmlImageLayer(\n this.imageRef.current,\n this.props.cldImg,\n this.props.plugins\n )\n }\n\n /**\n * On update we cancel running plugins and update image instance with the state of user\n * cloudinaryImage and the state of plugins\n */\n componentDidUpdate() {\n cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);\n // call html layer to update the dom again with plugins and reset toBeCanceled\n this.htmlLayerInstance.update(this.props.cldImg, this.props.plugins)\n }\n\n /**\n * On unmount we cancel the currently running plugins\n */\n componentWillUnmount() {\n // safely cancel running events on unmount\n cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);\n }\n\n render() {\n const {\n cldImg,\n plugins,\n ...otherProps // Assume any other props are for the base element\n } = this.props;\n if (isBrowser()) { // on client side render\n return <img suppressHydrationWarning {...otherProps} ref={this.imageRef} />\n } else { // on server side render\n const src = serverSideSrc(\n this.props.plugins,\n this.props.cldImg\n );\n return <img {...otherProps} src={src} />\n }\n }\n}\n\nexport { AdvancedImage };\n","import React, { Component, createRef, EventHandler, MutableRefObject, SyntheticEvent } from 'react';\nimport { CloudinaryVideo } from '@cloudinary/url-gen';\n\nimport {\n HtmlVideoLayer,\n Plugins,\n VideoSources,\n cancelCurrentlyRunningPlugins\n} from '@cloudinary/html';\n\ntype ReactEventHandler<T = Element> = EventHandler<SyntheticEvent<T>>;\n\ninterface VideoProps {\n cldVid: CloudinaryVideo,\n plugins?: Plugins,\n sources?: VideoSources,\n innerRef?: ((instance: any) => void) | MutableRefObject<unknown> | null\n\n // supported video attributes\n controls?: boolean\n loop?: boolean,\n muted?: boolean,\n poster?: string,\n preload?: string,\n autoPlay?: boolean,\n playsInline?: boolean\n\n // supported video events\n onPlay?: ReactEventHandler<any>,\n onLoadStart?: ReactEventHandler<any>,\n onPlaying?: ReactEventHandler<any>,\n onError?: ReactEventHandler<any>,\n onEnded?: ReactEventHandler<any>\n}\n\n/**\n * @memberOf ReactSDK\n * @type {Component}\n * @description The Cloudinary video component\n * @prop {CloudinaryVideo} transformation Generated by @cloudinary/url-gen\n * @prop {Plugins} plugins Advanced image component plugins lazyload()\n * @prop videoAttributes Optional attributes include controls, loop, muted, poster, preload, autoplay\n * @prop videoEvents Optional video events include play, loadstart, playing, error, ended\n * @prop {VideoSources} sources Optional sources to generate\n * @example\n * <caption>\n * Using custom defined resources.\n * </caption>\n * const vid = new CloudinaryVideo('dog', {cloudName: 'demo'});\n * const videoEl = useRef();\n * const sources = [\n * {\n * type: 'mp4',\n * codecs: ['vp8', 'vorbis'],\n * transcode: videoCodec(auto())\n * },\n * {\n * type: 'webm',\n * codecs: ['avc1.4D401E', 'mp4a.40.2'],\n * videoCodec: videoCodec(auto())\n * }];\n *\n * return <AdvancedVideo cldVid={vid} sources={sources} ref={videoEl} controls />\n */\nclass AdvancedVideo extends Component <VideoProps> {\n videoRef: MutableRefObject<HTMLVideoElement | null>\n htmlVideoLayerInstance: HtmlVideoLayer;\n\n constructor(props: VideoProps) {\n super(props);\n this.videoRef = createRef();\n this.attachRef = this.attachRef.bind(this);\n }\n\n /**\n * On mount creates a new HTMLVideoLayer instance and initialises with ref to video element,\n * user generated cloudinaryVideo and the plugins to be used\n */\n componentDidMount() {\n this.htmlVideoLayerInstance = new HtmlVideoLayer(\n this.videoRef && this.videoRef.current,\n this.props.cldVid,\n this.props.sources,\n this.props.plugins,\n this.getVideoAttributes()\n )\n }\n\n /**\n * On update we cancel running plugins and update the video instance if the src\n * was changed\n */\n componentDidUpdate() {\n cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState);\n // call html layer to update the dom again with plugins and reset toBeCanceled\n this.htmlVideoLayerInstance.update(this.props.cldVid, this.props.sources, this.props.plugins, this.getVideoAttributes())\n }\n\n /**\n * On unmount we cancel the currently running plugins\n */\n componentWillUnmount() {\n // safely cancel running events on unmount\n cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState)\n }\n\n /**\n * returns video attributes\n */\n getVideoAttributes() {\n return {\n controls: this.props.controls,\n loop: this.props.loop,\n muted: this.props.muted,\n poster: this.props.poster,\n preload: this.props.preload,\n autoplay: this.props.autoPlay,\n playsinline: this.props.playsInline\n };\n }\n\n /**\n * Attach both this.videoRef and props.innerRef as ref to the given element\n * @param element - the element to attach a ref to\n */\n attachRef(element: HTMLVideoElement) {\n this.videoRef.current = element;\n const { innerRef } = this.props;\n\n if (innerRef) {\n if (innerRef instanceof Function) {\n innerRef(element);\n } else {\n innerRef.current = element;\n }\n }\n };\n\n render() {\n const {\n cldVid,\n plugins,\n sources,\n innerRef,\n ...videoEvents // Assume any other props are for the base element\n } = this.props;\n\n return <video {...videoEvents} ref={this.attachRef} />\n }\n}\n\nexport { AdvancedVideo };\n","import React from 'react';\nimport { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';\n\nimport {\n HtmlPictureLayer,\n PictureSources\n} from '@cloudinary/html'\n\ninterface PictureProps {\n cldImg: CloudinaryImage,\n breakpoints?: number[],\n sources?: PictureSources,\n autoOptimalBreakpoints?: boolean,\n relativeWidth?: number\n [x: string]: any\n}\n\n/**\n * @memberOf ReactSDK\n * @type {Component}\n * @description The Cloudinary picture component\n * @prop {CloudinaryImage} transformation Generated by @cloudinary/url-gen\n * @prop {PictureSources} sources sources to generate source tag\n * @example\n * <caption>\n * Using custom defined resources.\n * </caption>\n * const img = new CloudinaryImage('sample', { cloudName: 'demo'});\n * const sources = [\n * {\n * minWidth:500,\n * maxWidth:2000,\n * sizes: \"80vw,\n * image: img\n * },\n * {\n * minWidth:3000,\n * maxWidth:4000,\n * sizes: \"80vw,\n * image: img\n * }];\n *\n * return <AdvancedPicture cldImg={img} sources={sources} />\n */\nclass AdvancedPicture extends React.Component <PictureProps> {\n pictureRef: React.RefObject<HTMLPictureElement>;\n htmlPictureLayerInstance: HtmlPictureLayer;\n\n constructor(props: PictureProps) {\n super(props);\n this.pictureRef = React.createRef();\n }\n\n /**\n * On mount creates a new HTMLPictureLayer instance and initialises with ref to picture element,\n * user generated cloudinaryImage and the sources to be used\n */\n componentDidMount() {\n this.htmlPictureLayerInstance = new HtmlPictureLayer(\n this.pictureRef.current,\n this.props.cldImg,\n this.props.breakpoints,\n this.props.sources,\n this.props.autoOptimalBreakpoints,\n this.props.relativeWidth\n )\n }\n\n /**\n * On update we update the image instance with the state of user\n * cloudinaryImage and the state of sources\n */\n componentDidUpdate() {\n // call html layer to update the dom\n this.htmlPictureLayerInstance.update(\n this.props.cldImg,\n this.props.breakpoints,\n this.props.sources,\n this.props.autoOptimalBreakpoints,\n this.props.relativeWidth\n );\n }\n\n render() {\n const {\n cldImg,\n breakpoints,\n sources,\n autoOptimalBreakpoints,\n relativeWidth,\n ...otherProps // Assume any other props are for the base element\n } = this.props;\n return <picture {...otherProps} ref={this.pictureRef} />\n }\n}\n\nexport { AdvancedPicture };\n"],"names":["AdvancedImage","props","imageRef","React","createRef","componentDidMount","htmlLayerInstance","HtmlImageLayer","current","cldImg","plugins","componentDidUpdate","cancelCurrentlyRunningPlugins","htmlPluginState","update","componentWillUnmount","render","otherProps","isBrowser","suppressHydrationWarning","ref","src","serverSideSrc","Component","AdvancedVideo","videoRef","attachRef","bind","htmlVideoLayerInstance","HtmlVideoLayer","cldVid","sources","getVideoAttributes","controls","loop","muted","poster","preload","autoplay","autoPlay","playsinline","playsInline","element","innerRef","Function","videoEvents","AdvancedPicture","pictureRef","htmlPictureLayerInstance","HtmlPictureLayer","breakpoints","autoOptimalBreakpoints","relativeWidth"],"mappings":"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"}
var html = require('@cloudinary/html');
var React = require('react');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
_setPrototypeOf(subClass, superClass);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
var _excluded$2 = ["cldImg", "plugins"];
/**
* @mixin ReactSDK
* @description The Cloudinary React SDK contains components like <AdvancedImage> to easily render your media assets from Cloudinary.
* The SDK also comes with support for optional js plugins that make the components smart, with features like lazy loading, placeholder, accessibility & responsiveness
*
* @example
* <caption>
* Please note that the order of the plugins is important. See home for more details.
* </caption>
* // Example
* import {CloudinaryImage} from "@cloudinary/url-gen/assets/CloudinaryImage";
* import {
* AdvancedImage,
* accessibility,
* responsive,
* lazyload,
* placeholder
* } from '@cloudinary/react';
*
* const App = () => {
*
* const myCld = new Cloudinary({ cloudName: 'demo'});
* let img = myCld().image('sample');
*
* return (
* <div>
* <div style={{height: "1000px"}}/>
* <AdvancedImage
* cldImg={img}
* plugins={[lazyload(), responsive(100), placeholder()]}
* />
* </div>
* )
* };
*
*
*
*
*
*/
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary image component
* @prop {CloudinaryImage} cldImg Generated by @cloudinary/url-gen
* @prop {Plugins} plugins Advanced image component plugins accessibility(), responsive(), lazyload(), placeholder()
*/
var AdvancedImage = /*#__PURE__*/function (_React$Component) {
_inheritsLoose(AdvancedImage, _React$Component);
function AdvancedImage(props) {
var _this;
_this = _React$Component.call(this, props) || this;
_this.imageRef = /*#__PURE__*/React__default["default"].createRef();
return _this;
}
/**
* On mount creates a new HTMLLayer instance and initialises with ref to img element,
* user generated cloudinaryImage and the plugins to be used
*/
var _proto = AdvancedImage.prototype;
_proto.componentDidMount = function componentDidMount() {
this.htmlLayerInstance = new html.HtmlImageLayer(this.imageRef.current, this.props.cldImg, this.props.plugins);
}
/**
* On update we cancel running plugins and update image instance with the state of user
* cloudinaryImage and the state of plugins
*/
;
_proto.componentDidUpdate = function componentDidUpdate() {
html.cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState); // call html layer to update the dom again with plugins and reset toBeCanceled
this.htmlLayerInstance.update(this.props.cldImg, this.props.plugins);
}
/**
* On unmount we cancel the currently running plugins
*/
;
_proto.componentWillUnmount = function componentWillUnmount() {
// safely cancel running events on unmount
html.cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);
};
_proto.render = function render() {
var _this$props = this.props,
otherProps = _objectWithoutPropertiesLoose(_this$props, _excluded$2);
if (html.isBrowser()) {
// on client side render
return /*#__PURE__*/React__default["default"].createElement("img", Object.assign({
suppressHydrationWarning: true
}, otherProps, {
ref: this.imageRef
}));
} else {
// on server side render
var src = html.serverSideSrc(this.props.plugins, this.props.cldImg);
return /*#__PURE__*/React__default["default"].createElement("img", Object.assign({}, otherProps, {
src: src
}));
}
};
return AdvancedImage;
}(React__default["default"].Component);
var _excluded$1 = ["cldVid", "plugins", "sources", "innerRef"];
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary video component
* @prop {CloudinaryVideo} transformation Generated by @cloudinary/url-gen
* @prop {Plugins} plugins Advanced image component plugins lazyload()
* @prop videoAttributes Optional attributes include controls, loop, muted, poster, preload, autoplay
* @prop videoEvents Optional video events include play, loadstart, playing, error, ended
* @prop {VideoSources} sources Optional sources to generate
* @example
* <caption>
* Using custom defined resources.
* </caption>
* const vid = new CloudinaryVideo('dog', {cloudName: 'demo'});
* const videoEl = useRef();
* const sources = [
* {
* type: 'mp4',
* codecs: ['vp8', 'vorbis'],
* transcode: videoCodec(auto())
* },
* {
* type: 'webm',
* codecs: ['avc1.4D401E', 'mp4a.40.2'],
* videoCodec: videoCodec(auto())
* }];
*
* return <AdvancedVideo cldVid={vid} sources={sources} ref={videoEl} controls />
*/
var AdvancedVideo = /*#__PURE__*/function (_Component) {
_inheritsLoose(AdvancedVideo, _Component);
function AdvancedVideo(props) {
var _this;
_this = _Component.call(this, props) || this;
_this.videoRef = /*#__PURE__*/React.createRef();
_this.attachRef = _this.attachRef.bind(_assertThisInitialized(_this));
return _this;
}
/**
* On mount creates a new HTMLVideoLayer instance and initialises with ref to video element,
* user generated cloudinaryVideo and the plugins to be used
*/
var _proto = AdvancedVideo.prototype;
_proto.componentDidMount = function componentDidMount() {
this.htmlVideoLayerInstance = new html.HtmlVideoLayer(this.videoRef && this.videoRef.current, this.props.cldVid, this.props.sources, this.props.plugins, this.getVideoAttributes());
}
/**
* On update we cancel running plugins and update the video instance if the src
* was changed
*/
;
_proto.componentDidUpdate = function componentDidUpdate() {
html.cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState); // call html layer to update the dom again with plugins and reset toBeCanceled
this.htmlVideoLayerInstance.update(this.props.cldVid, this.props.sources, this.props.plugins, this.getVideoAttributes());
}
/**
* On unmount we cancel the currently running plugins
*/
;
_proto.componentWillUnmount = function componentWillUnmount() {
// safely cancel running events on unmount
html.cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState);
}
/**
* returns video attributes
*/
;
_proto.getVideoAttributes = function getVideoAttributes() {
return {
controls: this.props.controls,
loop: this.props.loop,
muted: this.props.muted,
poster: this.props.poster,
preload: this.props.preload,
autoplay: this.props.autoPlay,
playsinline: this.props.playsInline
};
}
/**
* Attach both this.videoRef and props.innerRef as ref to the given element
* @param element - the element to attach a ref to
*/
;
_proto.attachRef = function attachRef(element) {
this.videoRef.current = element;
var innerRef = this.props.innerRef;
if (innerRef) {
if (innerRef instanceof Function) {
innerRef(element);
} else {
innerRef.current = element;
}
}
};
_proto.render = function render() {
var _this$props = this.props,
videoEvents = _objectWithoutPropertiesLoose(_this$props, _excluded$1);
return /*#__PURE__*/React__default["default"].createElement("video", Object.assign({}, videoEvents, {
ref: this.attachRef
}));
};
return AdvancedVideo;
}(React.Component);
var _excluded = ["cldImg", "breakpoints", "sources", "autoOptimalBreakpoints", "relativeWidth"];
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary picture component
* @prop {CloudinaryImage} transformation Generated by @cloudinary/url-gen
* @prop {PictureSources} sources sources to generate source tag
* @example
* <caption>
* Using custom defined resources.
* </caption>
* const img = new CloudinaryImage('sample', { cloudName: 'demo'});
* const sources = [
* {
* minWidth:500,
* maxWidth:2000,
* sizes: "80vw,
* image: img
* },
* {
* minWidth:3000,
* maxWidth:4000,
* sizes: "80vw,
* image: img
* }];
*
* return <AdvancedPicture cldImg={img} sources={sources} />
*/
var AdvancedPicture = /*#__PURE__*/function (_React$Component) {
_inheritsLoose(AdvancedPicture, _React$Component);
function AdvancedPicture(props) {
var _this;
_this = _React$Component.call(this, props) || this;
_this.pictureRef = /*#__PURE__*/React__default["default"].createRef();
return _this;
}
/**
* On mount creates a new HTMLPictureLayer instance and initialises with ref to picture element,
* user generated cloudinaryImage and the sources to be used
*/
var _proto = AdvancedPicture.prototype;
_proto.componentDidMount = function componentDidMount() {
this.htmlPictureLayerInstance = new html.HtmlPictureLayer(this.pictureRef.current, this.props.cldImg, this.props.breakpoints, this.props.sources, this.props.autoOptimalBreakpoints, this.props.relativeWidth);
}
/**
* On update we update the image instance with the state of user
* cloudinaryImage and the state of sources
*/
;
_proto.componentDidUpdate = function componentDidUpdate() {
// call html layer to update the dom
this.htmlPictureLayerInstance.update(this.props.cldImg, this.props.breakpoints, this.props.sources, this.props.autoOptimalBreakpoints, this.props.relativeWidth);
};
_proto.render = function render() {
var _this$props = this.props,
otherProps = _objectWithoutPropertiesLoose(_this$props, _excluded);
return /*#__PURE__*/React__default["default"].createElement("picture", Object.assign({}, otherProps, {
ref: this.pictureRef
}));
};
return AdvancedPicture;
}(React__default["default"].Component);
Object.defineProperty(exports, 'accessibility', {
enumerable: true,
get: function () { return html.accessibility; }
});
Object.defineProperty(exports, 'lazyload', {
enumerable: true,
get: function () { return html.lazyload; }
});
Object.defineProperty(exports, 'placeholder', {
enumerable: true,
get: function () { return html.placeholder; }
});
Object.defineProperty(exports, 'responsive', {
enumerable: true,
get: function () { return html.responsive; }
});
exports.AdvancedImage = AdvancedImage;
exports.AdvancedPicture = AdvancedPicture;
exports.AdvancedVideo = AdvancedVideo;
//# sourceMappingURL=index.js.map
{"version":3,"file":"index.js","sources":["../src/AdvancedImage.tsx","../src/AdvancedVideo.tsx","../src/AdvancedPicture.tsx"],"sourcesContent":["import React from 'react';\nimport { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';\n\nimport {\n HtmlImageLayer,\n Plugins,\n isBrowser,\n serverSideSrc,\n cancelCurrentlyRunningPlugins\n} from '@cloudinary/html'\n\ninterface ImgProps {\n cldImg: CloudinaryImage,\n plugins?: Plugins,\n [x: string]: any\n}\n\n/**\n * @mixin ReactSDK\n * @description The Cloudinary React SDK contains components like <AdvancedImage> to easily render your media assets from Cloudinary.\n * The SDK also comes with support for optional js plugins that make the components smart, with features like lazy loading, placeholder, accessibility & responsiveness\n *\n * @example\n * <caption>\n * Please note that the order of the plugins is important. See home for more details.\n * </caption>\n * // Example\n * import {CloudinaryImage} from \"@cloudinary/url-gen/assets/CloudinaryImage\";\n * import {\n * AdvancedImage,\n * accessibility,\n * responsive,\n * lazyload,\n * placeholder\n * } from '@cloudinary/react';\n *\n * const App = () => {\n *\n * const myCld = new Cloudinary({ cloudName: 'demo'});\n * let img = myCld().image('sample');\n *\n * return (\n * <div>\n * <div style={{height: \"1000px\"}}/>\n * <AdvancedImage\n * cldImg={img}\n * plugins={[lazyload(), responsive(100), placeholder()]}\n * />\n * </div>\n * )\n * };\n *\n *\n *\n *\n *\n */\n\n/**\n * @memberOf ReactSDK\n * @type {Component}\n * @description The Cloudinary image component\n * @prop {CloudinaryImage} cldImg Generated by @cloudinary/url-gen\n * @prop {Plugins} plugins Advanced image component plugins accessibility(), responsive(), lazyload(), placeholder()\n */\nclass AdvancedImage extends React.Component <ImgProps> {\n imageRef: React.RefObject<HTMLImageElement>;\n htmlLayerInstance: HtmlImageLayer;\n\n constructor(props: ImgProps) {\n super(props);\n this.imageRef = React.createRef();\n }\n\n /**\n * On mount creates a new HTMLLayer instance and initialises with ref to img element,\n * user generated cloudinaryImage and the plugins to be used\n */\n componentDidMount() {\n this.htmlLayerInstance = new HtmlImageLayer(\n this.imageRef.current,\n this.props.cldImg,\n this.props.plugins\n )\n }\n\n /**\n * On update we cancel running plugins and update image instance with the state of user\n * cloudinaryImage and the state of plugins\n */\n componentDidUpdate() {\n cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);\n // call html layer to update the dom again with plugins and reset toBeCanceled\n this.htmlLayerInstance.update(this.props.cldImg, this.props.plugins)\n }\n\n /**\n * On unmount we cancel the currently running plugins\n */\n componentWillUnmount() {\n // safely cancel running events on unmount\n cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);\n }\n\n render() {\n const {\n cldImg,\n plugins,\n ...otherProps // Assume any other props are for the base element\n } = this.props;\n if (isBrowser()) { // on client side render\n return <img suppressHydrationWarning {...otherProps} ref={this.imageRef} />\n } else { // on server side render\n const src = serverSideSrc(\n this.props.plugins,\n this.props.cldImg\n );\n return <img {...otherProps} src={src} />\n }\n }\n}\n\nexport { AdvancedImage };\n","import React, { Component, createRef, EventHandler, MutableRefObject, SyntheticEvent } from 'react';\nimport { CloudinaryVideo } from '@cloudinary/url-gen';\n\nimport {\n HtmlVideoLayer,\n Plugins,\n VideoSources,\n cancelCurrentlyRunningPlugins\n} from '@cloudinary/html';\n\ntype ReactEventHandler<T = Element> = EventHandler<SyntheticEvent<T>>;\n\ninterface VideoProps {\n cldVid: CloudinaryVideo,\n plugins?: Plugins,\n sources?: VideoSources,\n innerRef?: ((instance: any) => void) | MutableRefObject<unknown> | null\n\n // supported video attributes\n controls?: boolean\n loop?: boolean,\n muted?: boolean,\n poster?: string,\n preload?: string,\n autoPlay?: boolean,\n playsInline?: boolean\n\n // supported video events\n onPlay?: ReactEventHandler<any>,\n onLoadStart?: ReactEventHandler<any>,\n onPlaying?: ReactEventHandler<any>,\n onError?: ReactEventHandler<any>,\n onEnded?: ReactEventHandler<any>\n}\n\n/**\n * @memberOf ReactSDK\n * @type {Component}\n * @description The Cloudinary video component\n * @prop {CloudinaryVideo} transformation Generated by @cloudinary/url-gen\n * @prop {Plugins} plugins Advanced image component plugins lazyload()\n * @prop videoAttributes Optional attributes include controls, loop, muted, poster, preload, autoplay\n * @prop videoEvents Optional video events include play, loadstart, playing, error, ended\n * @prop {VideoSources} sources Optional sources to generate\n * @example\n * <caption>\n * Using custom defined resources.\n * </caption>\n * const vid = new CloudinaryVideo('dog', {cloudName: 'demo'});\n * const videoEl = useRef();\n * const sources = [\n * {\n * type: 'mp4',\n * codecs: ['vp8', 'vorbis'],\n * transcode: videoCodec(auto())\n * },\n * {\n * type: 'webm',\n * codecs: ['avc1.4D401E', 'mp4a.40.2'],\n * videoCodec: videoCodec(auto())\n * }];\n *\n * return <AdvancedVideo cldVid={vid} sources={sources} ref={videoEl} controls />\n */\nclass AdvancedVideo extends Component <VideoProps> {\n videoRef: MutableRefObject<HTMLVideoElement | null>\n htmlVideoLayerInstance: HtmlVideoLayer;\n\n constructor(props: VideoProps) {\n super(props);\n this.videoRef = createRef();\n this.attachRef = this.attachRef.bind(this);\n }\n\n /**\n * On mount creates a new HTMLVideoLayer instance and initialises with ref to video element,\n * user generated cloudinaryVideo and the plugins to be used\n */\n componentDidMount() {\n this.htmlVideoLayerInstance = new HtmlVideoLayer(\n this.videoRef && this.videoRef.current,\n this.props.cldVid,\n this.props.sources,\n this.props.plugins,\n this.getVideoAttributes()\n )\n }\n\n /**\n * On update we cancel running plugins and update the video instance if the src\n * was changed\n */\n componentDidUpdate() {\n cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState);\n // call html layer to update the dom again with plugins and reset toBeCanceled\n this.htmlVideoLayerInstance.update(this.props.cldVid, this.props.sources, this.props.plugins, this.getVideoAttributes())\n }\n\n /**\n * On unmount we cancel the currently running plugins\n */\n componentWillUnmount() {\n // safely cancel running events on unmount\n cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState)\n }\n\n /**\n * returns video attributes\n */\n getVideoAttributes() {\n return {\n controls: this.props.controls,\n loop: this.props.loop,\n muted: this.props.muted,\n poster: this.props.poster,\n preload: this.props.preload,\n autoplay: this.props.autoPlay,\n playsinline: this.props.playsInline\n };\n }\n\n /**\n * Attach both this.videoRef and props.innerRef as ref to the given element\n * @param element - the element to attach a ref to\n */\n attachRef(element: HTMLVideoElement) {\n this.videoRef.current = element;\n const { innerRef } = this.props;\n\n if (innerRef) {\n if (innerRef instanceof Function) {\n innerRef(element);\n } else {\n innerRef.current = element;\n }\n }\n };\n\n render() {\n const {\n cldVid,\n plugins,\n sources,\n innerRef,\n ...videoEvents // Assume any other props are for the base element\n } = this.props;\n\n return <video {...videoEvents} ref={this.attachRef} />\n }\n}\n\nexport { AdvancedVideo };\n","import React from 'react';\nimport { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';\n\nimport {\n HtmlPictureLayer,\n PictureSources\n} from '@cloudinary/html'\n\ninterface PictureProps {\n cldImg: CloudinaryImage,\n breakpoints?: number[],\n sources?: PictureSources,\n autoOptimalBreakpoints?: boolean,\n relativeWidth?: number\n [x: string]: any\n}\n\n/**\n * @memberOf ReactSDK\n * @type {Component}\n * @description The Cloudinary picture component\n * @prop {CloudinaryImage} transformation Generated by @cloudinary/url-gen\n * @prop {PictureSources} sources sources to generate source tag\n * @example\n * <caption>\n * Using custom defined resources.\n * </caption>\n * const img = new CloudinaryImage('sample', { cloudName: 'demo'});\n * const sources = [\n * {\n * minWidth:500,\n * maxWidth:2000,\n * sizes: \"80vw,\n * image: img\n * },\n * {\n * minWidth:3000,\n * maxWidth:4000,\n * sizes: \"80vw,\n * image: img\n * }];\n *\n * return <AdvancedPicture cldImg={img} sources={sources} />\n */\nclass AdvancedPicture extends React.Component <PictureProps> {\n pictureRef: React.RefObject<HTMLPictureElement>;\n htmlPictureLayerInstance: HtmlPictureLayer;\n\n constructor(props: PictureProps) {\n super(props);\n this.pictureRef = React.createRef();\n }\n\n /**\n * On mount creates a new HTMLPictureLayer instance and initialises with ref to picture element,\n * user generated cloudinaryImage and the sources to be used\n */\n componentDidMount() {\n this.htmlPictureLayerInstance = new HtmlPictureLayer(\n this.pictureRef.current,\n this.props.cldImg,\n this.props.breakpoints,\n this.props.sources,\n this.props.autoOptimalBreakpoints,\n this.props.relativeWidth\n )\n }\n\n /**\n * On update we update the image instance with the state of user\n * cloudinaryImage and the state of sources\n */\n componentDidUpdate() {\n // call html layer to update the dom\n this.htmlPictureLayerInstance.update(\n this.props.cldImg,\n this.props.breakpoints,\n this.props.sources,\n this.props.autoOptimalBreakpoints,\n this.props.relativeWidth\n );\n }\n\n render() {\n const {\n cldImg,\n breakpoints,\n sources,\n autoOptimalBreakpoints,\n relativeWidth,\n ...otherProps // Assume any other props are for the base element\n } = this.props;\n return <picture {...otherProps} ref={this.pictureRef} />\n }\n}\n\nexport { AdvancedPicture };\n"],"names":["AdvancedImage","props","imageRef","React","createRef","componentDidMount","htmlLayerInstance","HtmlImageLayer","current","cldImg","plugins","componentDidUpdate","cancelCurrentlyRunningPlugins","htmlPluginState","update","componentWillUnmount","render","otherProps","isBrowser","suppressHydrationWarning","ref","src","serverSideSrc","Component","AdvancedVideo","videoRef","attachRef","bind","htmlVideoLayerInstance","HtmlVideoLayer","cldVid","sources","getVideoAttributes","controls","loop","muted","poster","preload","autoplay","autoPlay","playsinline","playsInline","element","innerRef","Function","videoEvents","AdvancedPicture","pictureRef","htmlPictureLayerInstance","HtmlPictureLayer","breakpoints","autoOptimalBreakpoints","relativeWidth"],"mappings":"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"}
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@cloudinary/html'), require('react')) :
typeof define === 'function' && define.amd ? define(['exports', '@cloudinary/html', 'react'], factory) :
(global = global || self, factory(global.react = {}, global.html, global.react));
})(this, (function (exports, html, React) {
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
_setPrototypeOf(subClass, superClass);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
var _excluded$2 = ["cldImg", "plugins"];
/**
* @mixin ReactSDK
* @description The Cloudinary React SDK contains components like <AdvancedImage> to easily render your media assets from Cloudinary.
* The SDK also comes with support for optional js plugins that make the components smart, with features like lazy loading, placeholder, accessibility & responsiveness
*
* @example
* <caption>
* Please note that the order of the plugins is important. See home for more details.
* </caption>
* // Example
* import {CloudinaryImage} from "@cloudinary/url-gen/assets/CloudinaryImage";
* import {
* AdvancedImage,
* accessibility,
* responsive,
* lazyload,
* placeholder
* } from '@cloudinary/react';
*
* const App = () => {
*
* const myCld = new Cloudinary({ cloudName: 'demo'});
* let img = myCld().image('sample');
*
* return (
* <div>
* <div style={{height: "1000px"}}/>
* <AdvancedImage
* cldImg={img}
* plugins={[lazyload(), responsive(100), placeholder()]}
* />
* </div>
* )
* };
*
*
*
*
*
*/
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary image component
* @prop {CloudinaryImage} cldImg Generated by @cloudinary/url-gen
* @prop {Plugins} plugins Advanced image component plugins accessibility(), responsive(), lazyload(), placeholder()
*/
var AdvancedImage = /*#__PURE__*/function (_React$Component) {
_inheritsLoose(AdvancedImage, _React$Component);
function AdvancedImage(props) {
var _this;
_this = _React$Component.call(this, props) || this;
_this.imageRef = /*#__PURE__*/React__default["default"].createRef();
return _this;
}
/**
* On mount creates a new HTMLLayer instance and initialises with ref to img element,
* user generated cloudinaryImage and the plugins to be used
*/
var _proto = AdvancedImage.prototype;
_proto.componentDidMount = function componentDidMount() {
this.htmlLayerInstance = new html.HtmlImageLayer(this.imageRef.current, this.props.cldImg, this.props.plugins);
}
/**
* On update we cancel running plugins and update image instance with the state of user
* cloudinaryImage and the state of plugins
*/
;
_proto.componentDidUpdate = function componentDidUpdate() {
html.cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState); // call html layer to update the dom again with plugins and reset toBeCanceled
this.htmlLayerInstance.update(this.props.cldImg, this.props.plugins);
}
/**
* On unmount we cancel the currently running plugins
*/
;
_proto.componentWillUnmount = function componentWillUnmount() {
// safely cancel running events on unmount
html.cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);
};
_proto.render = function render() {
var _this$props = this.props,
otherProps = _objectWithoutPropertiesLoose(_this$props, _excluded$2);
if (html.isBrowser()) {
// on client side render
return /*#__PURE__*/React__default["default"].createElement("img", Object.assign({
suppressHydrationWarning: true
}, otherProps, {
ref: this.imageRef
}));
} else {
// on server side render
var src = html.serverSideSrc(this.props.plugins, this.props.cldImg);
return /*#__PURE__*/React__default["default"].createElement("img", Object.assign({}, otherProps, {
src: src
}));
}
};
return AdvancedImage;
}(React__default["default"].Component);
var _excluded$1 = ["cldVid", "plugins", "sources", "innerRef"];
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary video component
* @prop {CloudinaryVideo} transformation Generated by @cloudinary/url-gen
* @prop {Plugins} plugins Advanced image component plugins lazyload()
* @prop videoAttributes Optional attributes include controls, loop, muted, poster, preload, autoplay
* @prop videoEvents Optional video events include play, loadstart, playing, error, ended
* @prop {VideoSources} sources Optional sources to generate
* @example
* <caption>
* Using custom defined resources.
* </caption>
* const vid = new CloudinaryVideo('dog', {cloudName: 'demo'});
* const videoEl = useRef();
* const sources = [
* {
* type: 'mp4',
* codecs: ['vp8', 'vorbis'],
* transcode: videoCodec(auto())
* },
* {
* type: 'webm',
* codecs: ['avc1.4D401E', 'mp4a.40.2'],
* videoCodec: videoCodec(auto())
* }];
*
* return <AdvancedVideo cldVid={vid} sources={sources} ref={videoEl} controls />
*/
var AdvancedVideo = /*#__PURE__*/function (_Component) {
_inheritsLoose(AdvancedVideo, _Component);
function AdvancedVideo(props) {
var _this;
_this = _Component.call(this, props) || this;
_this.videoRef = /*#__PURE__*/React.createRef();
_this.attachRef = _this.attachRef.bind(_assertThisInitialized(_this));
return _this;
}
/**
* On mount creates a new HTMLVideoLayer instance and initialises with ref to video element,
* user generated cloudinaryVideo and the plugins to be used
*/
var _proto = AdvancedVideo.prototype;
_proto.componentDidMount = function componentDidMount() {
this.htmlVideoLayerInstance = new html.HtmlVideoLayer(this.videoRef && this.videoRef.current, this.props.cldVid, this.props.sources, this.props.plugins, this.getVideoAttributes());
}
/**
* On update we cancel running plugins and update the video instance if the src
* was changed
*/
;
_proto.componentDidUpdate = function componentDidUpdate() {
html.cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState); // call html layer to update the dom again with plugins and reset toBeCanceled
this.htmlVideoLayerInstance.update(this.props.cldVid, this.props.sources, this.props.plugins, this.getVideoAttributes());
}
/**
* On unmount we cancel the currently running plugins
*/
;
_proto.componentWillUnmount = function componentWillUnmount() {
// safely cancel running events on unmount
html.cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState);
}
/**
* returns video attributes
*/
;
_proto.getVideoAttributes = function getVideoAttributes() {
return {
controls: this.props.controls,
loop: this.props.loop,
muted: this.props.muted,
poster: this.props.poster,
preload: this.props.preload,
autoplay: this.props.autoPlay,
playsinline: this.props.playsInline
};
}
/**
* Attach both this.videoRef and props.innerRef as ref to the given element
* @param element - the element to attach a ref to
*/
;
_proto.attachRef = function attachRef(element) {
this.videoRef.current = element;
var innerRef = this.props.innerRef;
if (innerRef) {
if (innerRef instanceof Function) {
innerRef(element);
} else {
innerRef.current = element;
}
}
};
_proto.render = function render() {
var _this$props = this.props,
videoEvents = _objectWithoutPropertiesLoose(_this$props, _excluded$1);
return /*#__PURE__*/React__default["default"].createElement("video", Object.assign({}, videoEvents, {
ref: this.attachRef
}));
};
return AdvancedVideo;
}(React.Component);
var _excluded = ["cldImg", "breakpoints", "sources", "autoOptimalBreakpoints", "relativeWidth"];
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary picture component
* @prop {CloudinaryImage} transformation Generated by @cloudinary/url-gen
* @prop {PictureSources} sources sources to generate source tag
* @example
* <caption>
* Using custom defined resources.
* </caption>
* const img = new CloudinaryImage('sample', { cloudName: 'demo'});
* const sources = [
* {
* minWidth:500,
* maxWidth:2000,
* sizes: "80vw,
* image: img
* },
* {
* minWidth:3000,
* maxWidth:4000,
* sizes: "80vw,
* image: img
* }];
*
* return <AdvancedPicture cldImg={img} sources={sources} />
*/
var AdvancedPicture = /*#__PURE__*/function (_React$Component) {
_inheritsLoose(AdvancedPicture, _React$Component);
function AdvancedPicture(props) {
var _this;
_this = _React$Component.call(this, props) || this;
_this.pictureRef = /*#__PURE__*/React__default["default"].createRef();
return _this;
}
/**
* On mount creates a new HTMLPictureLayer instance and initialises with ref to picture element,
* user generated cloudinaryImage and the sources to be used
*/
var _proto = AdvancedPicture.prototype;
_proto.componentDidMount = function componentDidMount() {
this.htmlPictureLayerInstance = new html.HtmlPictureLayer(this.pictureRef.current, this.props.cldImg, this.props.breakpoints, this.props.sources, this.props.autoOptimalBreakpoints, this.props.relativeWidth);
}
/**
* On update we update the image instance with the state of user
* cloudinaryImage and the state of sources
*/
;
_proto.componentDidUpdate = function componentDidUpdate() {
// call html layer to update the dom
this.htmlPictureLayerInstance.update(this.props.cldImg, this.props.breakpoints, this.props.sources, this.props.autoOptimalBreakpoints, this.props.relativeWidth);
};
_proto.render = function render() {
var _this$props = this.props,
otherProps = _objectWithoutPropertiesLoose(_this$props, _excluded);
return /*#__PURE__*/React__default["default"].createElement("picture", Object.assign({}, otherProps, {
ref: this.pictureRef
}));
};
return AdvancedPicture;
}(React__default["default"].Component);
Object.defineProperty(exports, 'accessibility', {
enumerable: true,
get: function () { return html.accessibility; }
});
Object.defineProperty(exports, 'lazyload', {
enumerable: true,
get: function () { return html.lazyload; }
});
Object.defineProperty(exports, 'placeholder', {
enumerable: true,
get: function () { return html.placeholder; }
});
Object.defineProperty(exports, 'responsive', {
enumerable: true,
get: function () { return html.responsive; }
});
exports.AdvancedImage = AdvancedImage;
exports.AdvancedPicture = AdvancedPicture;
exports.AdvancedVideo = AdvancedVideo;
}));
//# sourceMappingURL=index.umd.js.map
{"version":3,"file":"index.umd.js","sources":["../src/AdvancedImage.tsx","../src/AdvancedVideo.tsx","../src/AdvancedPicture.tsx"],"sourcesContent":["import React from 'react';\nimport { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';\n\nimport {\n HtmlImageLayer,\n Plugins,\n isBrowser,\n serverSideSrc,\n cancelCurrentlyRunningPlugins\n} from '@cloudinary/html'\n\ninterface ImgProps {\n cldImg: CloudinaryImage,\n plugins?: Plugins,\n [x: string]: any\n}\n\n/**\n * @mixin ReactSDK\n * @description The Cloudinary React SDK contains components like <AdvancedImage> to easily render your media assets from Cloudinary.\n * The SDK also comes with support for optional js plugins that make the components smart, with features like lazy loading, placeholder, accessibility & responsiveness\n *\n * @example\n * <caption>\n * Please note that the order of the plugins is important. See home for more details.\n * </caption>\n * // Example\n * import {CloudinaryImage} from \"@cloudinary/url-gen/assets/CloudinaryImage\";\n * import {\n * AdvancedImage,\n * accessibility,\n * responsive,\n * lazyload,\n * placeholder\n * } from '@cloudinary/react';\n *\n * const App = () => {\n *\n * const myCld = new Cloudinary({ cloudName: 'demo'});\n * let img = myCld().image('sample');\n *\n * return (\n * <div>\n * <div style={{height: \"1000px\"}}/>\n * <AdvancedImage\n * cldImg={img}\n * plugins={[lazyload(), responsive(100), placeholder()]}\n * />\n * </div>\n * )\n * };\n *\n *\n *\n *\n *\n */\n\n/**\n * @memberOf ReactSDK\n * @type {Component}\n * @description The Cloudinary image component\n * @prop {CloudinaryImage} cldImg Generated by @cloudinary/url-gen\n * @prop {Plugins} plugins Advanced image component plugins accessibility(), responsive(), lazyload(), placeholder()\n */\nclass AdvancedImage extends React.Component <ImgProps> {\n imageRef: React.RefObject<HTMLImageElement>;\n htmlLayerInstance: HtmlImageLayer;\n\n constructor(props: ImgProps) {\n super(props);\n this.imageRef = React.createRef();\n }\n\n /**\n * On mount creates a new HTMLLayer instance and initialises with ref to img element,\n * user generated cloudinaryImage and the plugins to be used\n */\n componentDidMount() {\n this.htmlLayerInstance = new HtmlImageLayer(\n this.imageRef.current,\n this.props.cldImg,\n this.props.plugins\n )\n }\n\n /**\n * On update we cancel running plugins and update image instance with the state of user\n * cloudinaryImage and the state of plugins\n */\n componentDidUpdate() {\n cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);\n // call html layer to update the dom again with plugins and reset toBeCanceled\n this.htmlLayerInstance.update(this.props.cldImg, this.props.plugins)\n }\n\n /**\n * On unmount we cancel the currently running plugins\n */\n componentWillUnmount() {\n // safely cancel running events on unmount\n cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);\n }\n\n render() {\n const {\n cldImg,\n plugins,\n ...otherProps // Assume any other props are for the base element\n } = this.props;\n if (isBrowser()) { // on client side render\n return <img suppressHydrationWarning {...otherProps} ref={this.imageRef} />\n } else { // on server side render\n const src = serverSideSrc(\n this.props.plugins,\n this.props.cldImg\n );\n return <img {...otherProps} src={src} />\n }\n }\n}\n\nexport { AdvancedImage };\n","import React, { Component, createRef, EventHandler, MutableRefObject, SyntheticEvent } from 'react';\nimport { CloudinaryVideo } from '@cloudinary/url-gen';\n\nimport {\n HtmlVideoLayer,\n Plugins,\n VideoSources,\n cancelCurrentlyRunningPlugins\n} from '@cloudinary/html';\n\ntype ReactEventHandler<T = Element> = EventHandler<SyntheticEvent<T>>;\n\ninterface VideoProps {\n cldVid: CloudinaryVideo,\n plugins?: Plugins,\n sources?: VideoSources,\n innerRef?: ((instance: any) => void) | MutableRefObject<unknown> | null\n\n // supported video attributes\n controls?: boolean\n loop?: boolean,\n muted?: boolean,\n poster?: string,\n preload?: string,\n autoPlay?: boolean,\n playsInline?: boolean\n\n // supported video events\n onPlay?: ReactEventHandler<any>,\n onLoadStart?: ReactEventHandler<any>,\n onPlaying?: ReactEventHandler<any>,\n onError?: ReactEventHandler<any>,\n onEnded?: ReactEventHandler<any>\n}\n\n/**\n * @memberOf ReactSDK\n * @type {Component}\n * @description The Cloudinary video component\n * @prop {CloudinaryVideo} transformation Generated by @cloudinary/url-gen\n * @prop {Plugins} plugins Advanced image component plugins lazyload()\n * @prop videoAttributes Optional attributes include controls, loop, muted, poster, preload, autoplay\n * @prop videoEvents Optional video events include play, loadstart, playing, error, ended\n * @prop {VideoSources} sources Optional sources to generate\n * @example\n * <caption>\n * Using custom defined resources.\n * </caption>\n * const vid = new CloudinaryVideo('dog', {cloudName: 'demo'});\n * const videoEl = useRef();\n * const sources = [\n * {\n * type: 'mp4',\n * codecs: ['vp8', 'vorbis'],\n * transcode: videoCodec(auto())\n * },\n * {\n * type: 'webm',\n * codecs: ['avc1.4D401E', 'mp4a.40.2'],\n * videoCodec: videoCodec(auto())\n * }];\n *\n * return <AdvancedVideo cldVid={vid} sources={sources} ref={videoEl} controls />\n */\nclass AdvancedVideo extends Component <VideoProps> {\n videoRef: MutableRefObject<HTMLVideoElement | null>\n htmlVideoLayerInstance: HtmlVideoLayer;\n\n constructor(props: VideoProps) {\n super(props);\n this.videoRef = createRef();\n this.attachRef = this.attachRef.bind(this);\n }\n\n /**\n * On mount creates a new HTMLVideoLayer instance and initialises with ref to video element,\n * user generated cloudinaryVideo and the plugins to be used\n */\n componentDidMount() {\n this.htmlVideoLayerInstance = new HtmlVideoLayer(\n this.videoRef && this.videoRef.current,\n this.props.cldVid,\n this.props.sources,\n this.props.plugins,\n this.getVideoAttributes()\n )\n }\n\n /**\n * On update we cancel running plugins and update the video instance if the src\n * was changed\n */\n componentDidUpdate() {\n cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState);\n // call html layer to update the dom again with plugins and reset toBeCanceled\n this.htmlVideoLayerInstance.update(this.props.cldVid, this.props.sources, this.props.plugins, this.getVideoAttributes())\n }\n\n /**\n * On unmount we cancel the currently running plugins\n */\n componentWillUnmount() {\n // safely cancel running events on unmount\n cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState)\n }\n\n /**\n * returns video attributes\n */\n getVideoAttributes() {\n return {\n controls: this.props.controls,\n loop: this.props.loop,\n muted: this.props.muted,\n poster: this.props.poster,\n preload: this.props.preload,\n autoplay: this.props.autoPlay,\n playsinline: this.props.playsInline\n };\n }\n\n /**\n * Attach both this.videoRef and props.innerRef as ref to the given element\n * @param element - the element to attach a ref to\n */\n attachRef(element: HTMLVideoElement) {\n this.videoRef.current = element;\n const { innerRef } = this.props;\n\n if (innerRef) {\n if (innerRef instanceof Function) {\n innerRef(element);\n } else {\n innerRef.current = element;\n }\n }\n };\n\n render() {\n const {\n cldVid,\n plugins,\n sources,\n innerRef,\n ...videoEvents // Assume any other props are for the base element\n } = this.props;\n\n return <video {...videoEvents} ref={this.attachRef} />\n }\n}\n\nexport { AdvancedVideo };\n","import React from 'react';\nimport { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';\n\nimport {\n HtmlPictureLayer,\n PictureSources\n} from '@cloudinary/html'\n\ninterface PictureProps {\n cldImg: CloudinaryImage,\n breakpoints?: number[],\n sources?: PictureSources,\n autoOptimalBreakpoints?: boolean,\n relativeWidth?: number\n [x: string]: any\n}\n\n/**\n * @memberOf ReactSDK\n * @type {Component}\n * @description The Cloudinary picture component\n * @prop {CloudinaryImage} transformation Generated by @cloudinary/url-gen\n * @prop {PictureSources} sources sources to generate source tag\n * @example\n * <caption>\n * Using custom defined resources.\n * </caption>\n * const img = new CloudinaryImage('sample', { cloudName: 'demo'});\n * const sources = [\n * {\n * minWidth:500,\n * maxWidth:2000,\n * sizes: \"80vw,\n * image: img\n * },\n * {\n * minWidth:3000,\n * maxWidth:4000,\n * sizes: \"80vw,\n * image: img\n * }];\n *\n * return <AdvancedPicture cldImg={img} sources={sources} />\n */\nclass AdvancedPicture extends React.Component <PictureProps> {\n pictureRef: React.RefObject<HTMLPictureElement>;\n htmlPictureLayerInstance: HtmlPictureLayer;\n\n constructor(props: PictureProps) {\n super(props);\n this.pictureRef = React.createRef();\n }\n\n /**\n * On mount creates a new HTMLPictureLayer instance and initialises with ref to picture element,\n * user generated cloudinaryImage and the sources to be used\n */\n componentDidMount() {\n this.htmlPictureLayerInstance = new HtmlPictureLayer(\n this.pictureRef.current,\n this.props.cldImg,\n this.props.breakpoints,\n this.props.sources,\n this.props.autoOptimalBreakpoints,\n this.props.relativeWidth\n )\n }\n\n /**\n * On update we update the image instance with the state of user\n * cloudinaryImage and the state of sources\n */\n componentDidUpdate() {\n // call html layer to update the dom\n this.htmlPictureLayerInstance.update(\n this.props.cldImg,\n this.props.breakpoints,\n this.props.sources,\n this.props.autoOptimalBreakpoints,\n this.props.relativeWidth\n );\n }\n\n render() {\n const {\n cldImg,\n breakpoints,\n sources,\n autoOptimalBreakpoints,\n relativeWidth,\n ...otherProps // Assume any other props are for the base element\n } = this.props;\n return <picture {...otherProps} ref={this.pictureRef} />\n }\n}\n\nexport { AdvancedPicture };\n"],"names":["AdvancedImage","props","imageRef","React","createRef","componentDidMount","htmlLayerInstance","HtmlImageLayer","current","cldImg","plugins","componentDidUpdate","cancelCurrentlyRunningPlugins","htmlPluginState","update","componentWillUnmount","render","otherProps","isBrowser","suppressHydrationWarning","ref","src","serverSideSrc","Component","AdvancedVideo","videoRef","attachRef","bind","htmlVideoLayerInstance","HtmlVideoLayer","cldVid","sources","getVideoAttributes","controls","loop","muted","poster","preload","autoplay","autoPlay","playsinline","playsInline","element","innerRef","Function","videoEvents","AdvancedPicture","pictureRef","htmlPictureLayerInstance","HtmlPictureLayer","breakpoints","autoOptimalBreakpoints","relativeWidth"],"mappings":"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"}
MIT License
Copyright (c) 2020 Cloudinary
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
{
"name": "@cloudinary/react",
"version": "1.0.0-beta.13",
"description": "A React component for Cloudinary",
"author": "cloudinary",
"license": "MIT",
"repository": "https://github.com/cloudinary/frontend-frameworks",
"main": "dist/index.js",
"umd:main": "./dist/index.umd.js",
"module": "dist/index.esm.js",
"sideEffects": false,
"source": "src/index.tsx",
"engines": {
"node": ">=10"
},
"scripts": {
"build": "npm run build --prefix ../html && microbundle --format esm,umd,cjs --jsx React.createElement --compress false && cp package.json ./dist",
"start": "microbundle watch --no-compress --format modern,cjs",
"test": "jest",
"test-coverage": "jest --coverage"
},
"peerDependencies": {
"react": "^16.3.0 || ^17.0.0"
},
"devDependencies": {
"@babel/preset-env": "^7.12.10",
"@babel/preset-typescript": "^7.12.7",
"@cloudinary/url-gen": "^1.0.0-beta.5",
"@sinonjs/fake-timers": "^6.0.1",
"@testing-library/jest-dom": "^4.2.4",
"@types/enzyme": "^3.10.8",
"@types/enzyme-adapter-react-16": "^1.0.6",
"@types/jest": "^25.2.3",
"@types/node": "^12.12.38",
"@types/react": "^16.9.27",
"@types/react-dom": "^16.9.7",
"@types/sinonjs__fake-timers": "^6.0.2",
"@typescript-eslint/eslint-plugin": "^2.26.0",
"@typescript-eslint/parser": "^2.26.0",
"babel-eslint": "^10.0.3",
"cross-env": "^7.0.2",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.5",
"enzyme-to-json": "^3.6.1",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.7.0",
"eslint-config-standard": "^14.1.0",
"eslint-config-standard-react": "^9.2.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-node": "^11.0.0",
"eslint-plugin-prettier": "^3.1.1",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-react": "^7.17.0",
"eslint-plugin-standard": "^4.0.1",
"gh-pages": "^2.2.0",
"microbundle": "^0.13.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.0.4",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "^3.4.1",
"ts-jest": "^26.4.4",
"typescript": "^3.7.5"
},
"jest": {
"transformIgnorePatterns": [
"node_modules/(?!(@cloudinary/url-gen)).*\\.js$"
],
"setupFilesAfterEnv": [
"./src/setupTests.js"
],
"testPathIgnorePatterns": [
"<rootDir>/__tests__/testUtils",
"<rootDir>/dist"
]
},
"dependencies": {
"@cloudinary/html": "^1.0.0-beta.13"
}
}
# Cloudinary Frontend Frameworks
## About this project
This project contains SDKs designed to work with [Cloudinary url-gen](https://github.com/cloudinary/js-url-gen) </br>
These SDKs will render CloudinaryImage or CloudinaryVideo object into the DOM.
### Packages contained within this project:
<br />
- The React SDK used to render an image & video component. [NPM](https://www.npmjs.com/package/@cloudinary/react) | {@link ReactSDK|Reference}
- The Angular SDK used to render an image & video component. [NPM](https://www.npmjs.com/package/@cloudinary/angular) | {@link AngularSDK|Reference}
Each SDK also contains advanced features in the form of plugins, which extend the native HTMLImage and HTMLVideo elements.
- {@link accessibility|accessibility} - Used to make your images more accessible to your users with visual disabilities.
- {@link lazyload|lazyload} - Used to delay loading images if they are not yet visible on the screen.
- {@link placeholder|placeholder} - Used to display a lightweight version of an image while the target image is downloading.
- {@link responsive|responsive} - Used to resize your images automatically based on the viewport size.
## Development setup
To build and link project:
- clone project
- npm run quickstart
## Installation
To get started, install the npm client package of your choice along with our base package.
For example, to use Cloudinary in a [React](https://cloudinary.com/documentation/react2_integration) environment, the following packages should be installed:
```bash
npm i @cloudinary/react @cloudinary/url-gen
```
**Note**: To use [Angular](https://cloudinary.com/documentation/angular2_integration) install `@cloudinary/angular`
For more information on our supported frameworks, navigate to the frameworks tab.
## Simple usage
The following is a simple example using [React](https://cloudinary.com/documentation/react2_integration).
For more information on React and other frameworks, navigate to the frameworks tab.
```javascript
// Import the cloudinary class, and the plugins you want to use
// In this case, we import a Cloudinary image type and accessibility and responsive.
import React, { Component } from 'react'
import {Cloudinary} from "@cloudinary/url-gen";
import { AdvancedImage, accessibility, responsive } from '@cloudinary/react';
// Once per project/app - configure your instance,
// See the documentation in @cloudinary/url-gen for more information
const myCld = new Cloudinary({ cloudName: 'demo'});
// render your component
const App = () => {
// Create your image
// This creates a new image object
let img = myCld().image('sample');
return (
<div>
<AdvancedImage cldImg={img} plugins={[responsive(), accessibility()]}/>
</div>
)
};
```
## Plugin Order
<div>
We recommended the following order when using our plugins to achieve the best results.
<br/><br/>
```javascript
<AdvancedImage plugins={[lazyload(),responsive(), accessibility(), placeholder()]}/>
```
You can omit any plugin, but the order from above should remain.
</div>
{
"preset": "ts-jest",
"testEnvironment": "node",
"bail": true,
"collectCoverageFrom": [
"<rootDir>/src/**/*.ts"
],
"transform": {
"^.+\\.tsx?$": "ts-jest"
},
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
],
"modulePaths": [
"<rootDir>/src"
],
"snapshotSerializers": ["enzyme-to-json/serializer"],
"coverageThreshold": {
"global": {
"branches": 95,
"functions": 95,
"lines": 95,
"statements": 95
}
},
"globals": {
"ts-jest": {
"diagnostics": false
}
},
"transformIgnorePatterns": [
"node_modules/(?!(@cloudinary/url-gen)).*\\.js$"
],
"setupFilesAfterEnv": [
"./src/setupTests.js"
]
}
{
"name": "@cloudinary/react-example",
"homepage": ".",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ../node_modules/react-scripts/bin/react-scripts.js start",
"build-example": "node ../node_modules/react-scripts/bin/react-scripts.js build",
"test-example": "node ../node_modules/react-scripts/bin/react-scripts.js test",
"eject": "node ../node_modules/react-scripts/bin/react-scripts.js eject"
},
"dependencies": {
"@testing-library/jest-dom": "file:../node_modules/@testing-library/jest-dom",
"@types/jest": "file:../node_modules/@types/jest",
"@types/node": "file:../node_modules/@types/node",
"@types/react": "file:../node_modules/@types/react",
"@types/react-dom": "file:../node_modules/@types/react-dom",
"react": "file:../node_modules/react",
"react-dom": "file:../node_modules/react-dom",
"react-scripts": "file:../node_modules/react-scripts",
"typescript": "file:../node_modules/typescript",
"@cloudinary/react": "file:.."
},
"devDependencies": {
"@babel/plugin-syntax-object-rest-spread": "^7.8.3"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
This is our React playground and can be used to test library.
It is linked to the @cloudinary/react package in the parent directory for development purposes.
You can run `npm install` and then `npm start` to test your package.
import React from 'react'
import { AdvancedImage, accessibility, responsive, lazyload, placeholder } from '@cloudinary/react';
import {CloudinaryImage} from "@cloudinary/url-gen/assets/CloudinaryImage";
//This is our playground and can be used to test library
const App = () => {
let img = new CloudinaryImage('sample', { cloudName: 'demo'});
return (
<div>
<AdvancedImage cldImg={img} plugins={[responsive(100)]}/>
</div>
)
};
export default App
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
ReactDOM.render(<App />, document.getElementById('root'))
/// <reference types="react-scripts" />
{
"compilerOptions": {
"outDir": "dist",
"module": "esnext",
"lib": [
"dom",
"esnext"
],
"moduleResolution": "node",
"jsx": "react",
"sourceMap": true,
"declaration": true,
"esModuleInterop": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": false,
"noUnusedParameters": true,
"allowSyntheticDefaultImports": true,
"target": "es5",
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true
},
"include": [
"src"
],
"exclude": [
"node_modules",
"build"
]
}
import React from 'react';
import { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';
import {
HtmlImageLayer,
Plugins,
isBrowser,
serverSideSrc,
cancelCurrentlyRunningPlugins
} from '@cloudinary/html'
interface ImgProps {
cldImg: CloudinaryImage,
plugins?: Plugins,
[x: string]: any
}
/**
* @mixin ReactSDK
* @description The Cloudinary React SDK contains components like <AdvancedImage> to easily render your media assets from Cloudinary.
* The SDK also comes with support for optional js plugins that make the components smart, with features like lazy loading, placeholder, accessibility & responsiveness
*
* @example
* <caption>
* Please note that the order of the plugins is important. See home for more details.
* </caption>
* // Example
* import {CloudinaryImage} from "@cloudinary/url-gen/assets/CloudinaryImage";
* import {
* AdvancedImage,
* accessibility,
* responsive,
* lazyload,
* placeholder
* } from '@cloudinary/react';
*
* const App = () => {
*
* const myCld = new Cloudinary({ cloudName: 'demo'});
* let img = myCld().image('sample');
*
* return (
* <div>
* <div style={{height: "1000px"}}/>
* <AdvancedImage
* cldImg={img}
* plugins={[lazyload(), responsive(100), placeholder()]}
* />
* </div>
* )
* };
*
*
*
*
*
*/
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary image component
* @prop {CloudinaryImage} cldImg Generated by @cloudinary/url-gen
* @prop {Plugins} plugins Advanced image component plugins accessibility(), responsive(), lazyload(), placeholder()
*/
class AdvancedImage extends React.Component <ImgProps> {
imageRef: React.RefObject<HTMLImageElement>;
htmlLayerInstance: HtmlImageLayer;
constructor(props: ImgProps) {
super(props);
this.imageRef = React.createRef();
}
/**
* On mount creates a new HTMLLayer instance and initialises with ref to img element,
* user generated cloudinaryImage and the plugins to be used
*/
componentDidMount() {
this.htmlLayerInstance = new HtmlImageLayer(
this.imageRef.current,
this.props.cldImg,
this.props.plugins
)
}
/**
* On update we cancel running plugins and update image instance with the state of user
* cloudinaryImage and the state of plugins
*/
componentDidUpdate() {
cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);
// call html layer to update the dom again with plugins and reset toBeCanceled
this.htmlLayerInstance.update(this.props.cldImg, this.props.plugins)
}
/**
* On unmount we cancel the currently running plugins
*/
componentWillUnmount() {
// safely cancel running events on unmount
cancelCurrentlyRunningPlugins(this.htmlLayerInstance.htmlPluginState);
}
render() {
const {
cldImg,
plugins,
...otherProps // Assume any other props are for the base element
} = this.props;
if (isBrowser()) { // on client side render
return <img suppressHydrationWarning {...otherProps} ref={this.imageRef} />
} else { // on server side render
const src = serverSideSrc(
this.props.plugins,
this.props.cldImg
);
return <img {...otherProps} src={src} />
}
}
}
export { AdvancedImage };
import React from 'react';
import { CloudinaryImage } from '@cloudinary/url-gen/assets/CloudinaryImage';
import {
HtmlPictureLayer,
PictureSources
} from '@cloudinary/html'
interface PictureProps {
cldImg: CloudinaryImage,
breakpoints?: number[],
sources?: PictureSources,
autoOptimalBreakpoints?: boolean,
relativeWidth?: number
[x: string]: any
}
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary picture component
* @prop {CloudinaryImage} transformation Generated by @cloudinary/url-gen
* @prop {PictureSources} sources sources to generate source tag
* @example
* <caption>
* Using custom defined resources.
* </caption>
* const img = new CloudinaryImage('sample', { cloudName: 'demo'});
* const sources = [
* {
* minWidth:500,
* maxWidth:2000,
* sizes: "80vw,
* image: img
* },
* {
* minWidth:3000,
* maxWidth:4000,
* sizes: "80vw,
* image: img
* }];
*
* return <AdvancedPicture cldImg={img} sources={sources} />
*/
class AdvancedPicture extends React.Component <PictureProps> {
pictureRef: React.RefObject<HTMLPictureElement>;
htmlPictureLayerInstance: HtmlPictureLayer;
constructor(props: PictureProps) {
super(props);
this.pictureRef = React.createRef();
}
/**
* On mount creates a new HTMLPictureLayer instance and initialises with ref to picture element,
* user generated cloudinaryImage and the sources to be used
*/
componentDidMount() {
this.htmlPictureLayerInstance = new HtmlPictureLayer(
this.pictureRef.current,
this.props.cldImg,
this.props.breakpoints,
this.props.sources,
this.props.autoOptimalBreakpoints,
this.props.relativeWidth
)
}
/**
* On update we update the image instance with the state of user
* cloudinaryImage and the state of sources
*/
componentDidUpdate() {
// call html layer to update the dom
this.htmlPictureLayerInstance.update(
this.props.cldImg,
this.props.breakpoints,
this.props.sources,
this.props.autoOptimalBreakpoints,
this.props.relativeWidth
);
}
render() {
const {
cldImg,
breakpoints,
sources,
autoOptimalBreakpoints,
relativeWidth,
...otherProps // Assume any other props are for the base element
} = this.props;
return <picture {...otherProps} ref={this.pictureRef} />
}
}
export { AdvancedPicture };
import React, { Component, createRef, EventHandler, MutableRefObject, SyntheticEvent } from 'react';
import { CloudinaryVideo } from '@cloudinary/url-gen';
import {
HtmlVideoLayer,
Plugins,
VideoSources,
cancelCurrentlyRunningPlugins
} from '@cloudinary/html';
type ReactEventHandler<T = Element> = EventHandler<SyntheticEvent<T>>;
interface VideoProps {
cldVid: CloudinaryVideo,
plugins?: Plugins,
sources?: VideoSources,
innerRef?: ((instance: any) => void) | MutableRefObject<unknown> | null
// supported video attributes
controls?: boolean
loop?: boolean,
muted?: boolean,
poster?: string,
preload?: string,
autoPlay?: boolean,
playsInline?: boolean
// supported video events
onPlay?: ReactEventHandler<any>,
onLoadStart?: ReactEventHandler<any>,
onPlaying?: ReactEventHandler<any>,
onError?: ReactEventHandler<any>,
onEnded?: ReactEventHandler<any>
}
/**
* @memberOf ReactSDK
* @type {Component}
* @description The Cloudinary video component
* @prop {CloudinaryVideo} transformation Generated by @cloudinary/url-gen
* @prop {Plugins} plugins Advanced image component plugins lazyload()
* @prop videoAttributes Optional attributes include controls, loop, muted, poster, preload, autoplay
* @prop videoEvents Optional video events include play, loadstart, playing, error, ended
* @prop {VideoSources} sources Optional sources to generate
* @example
* <caption>
* Using custom defined resources.
* </caption>
* const vid = new CloudinaryVideo('dog', {cloudName: 'demo'});
* const videoEl = useRef();
* const sources = [
* {
* type: 'mp4',
* codecs: ['vp8', 'vorbis'],
* transcode: videoCodec(auto())
* },
* {
* type: 'webm',
* codecs: ['avc1.4D401E', 'mp4a.40.2'],
* videoCodec: videoCodec(auto())
* }];
*
* return <AdvancedVideo cldVid={vid} sources={sources} ref={videoEl} controls />
*/
class AdvancedVideo extends Component <VideoProps> {
videoRef: MutableRefObject<HTMLVideoElement | null>
htmlVideoLayerInstance: HtmlVideoLayer;
constructor(props: VideoProps) {
super(props);
this.videoRef = createRef();
this.attachRef = this.attachRef.bind(this);
}
/**
* On mount creates a new HTMLVideoLayer instance and initialises with ref to video element,
* user generated cloudinaryVideo and the plugins to be used
*/
componentDidMount() {
this.htmlVideoLayerInstance = new HtmlVideoLayer(
this.videoRef && this.videoRef.current,
this.props.cldVid,
this.props.sources,
this.props.plugins,
this.getVideoAttributes()
)
}
/**
* On update we cancel running plugins and update the video instance if the src
* was changed
*/
componentDidUpdate() {
cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState);
// call html layer to update the dom again with plugins and reset toBeCanceled
this.htmlVideoLayerInstance.update(this.props.cldVid, this.props.sources, this.props.plugins, this.getVideoAttributes())
}
/**
* On unmount we cancel the currently running plugins
*/
componentWillUnmount() {
// safely cancel running events on unmount
cancelCurrentlyRunningPlugins(this.htmlVideoLayerInstance.htmlPluginState)
}
/**
* returns video attributes
*/
getVideoAttributes() {
return {
controls: this.props.controls,
loop: this.props.loop,
muted: this.props.muted,
poster: this.props.poster,
preload: this.props.preload,
autoplay: this.props.autoPlay,
playsinline: this.props.playsInline
};
}
/**
* Attach both this.videoRef and props.innerRef as ref to the given element
* @param element - the element to attach a ref to
*/
attachRef(element: HTMLVideoElement) {
this.videoRef.current = element;
const { innerRef } = this.props;
if (innerRef) {
if (innerRef instanceof Function) {
innerRef(element);
} else {
innerRef.current = element;
}
}
};
render() {
const {
cldVid,
plugins,
sources,
innerRef,
...videoEvents // Assume any other props are for the base element
} = this.props;
return <video {...videoEvents} ref={this.attachRef} />
}
}
export { AdvancedVideo };
import {
placeholder,
accessibility,
lazyload,
responsive
} from '@cloudinary/html'
import { AdvancedImage } from './AdvancedImage';
import { AdvancedVideo } from './AdvancedVideo';
import { AdvancedPicture } from './AdvancedPicture';
export { placeholder, accessibility, lazyload, responsive, AdvancedImage, AdvancedVideo, AdvancedPicture };
import 'regenerator-runtime/runtime'
import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
Enzyme.configure({ adapter: new Adapter() });
/**
* Default CSS definition for typescript,
* will be overridden with file-specific definitions by rollup
*/
declare module '*.css' {
const content: { [className: string]: string };
export default content;
}
interface SvgrComponent extends React.StatelessComponent<React.SVGAttributes<SVGElement>> {}
declare module '*.svg' {
const svgUrl: string;
const svgComponent: SvgrComponent;
export default svgUrl;
export { svgComponent as ReactComponent }
}
{
"compilerOptions": {
"outDir": "dist",
"module": "esnext",
"lib": [
"dom",
"esnext"
],
"moduleResolution": "node",
"strictPropertyInitialization": false,
"jsx": "react",
"sourceMap": true,
"declaration": true,
"esModuleInterop": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": false,
"noUnusedParameters": true,
"allowSyntheticDefaultImports": true,
"target": "es5",
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"types": ["jest", "node"]
},
"include": [
"src"
],
"exclude": [
"node_modules",
"dist",
"playground",
"__tests__"
]
}
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "ES2015"
}
}