@razorpay/blade
Version:
The Design System that powers Razorpay
223 lines (209 loc) • 9.55 kB
JavaScript
import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
import _regeneratorRuntime from '@babel/runtime/regenerator';
import { getPresets } from './presets.js';
var _excluded = ["width", "height", "className", "style", "onLoad", "onError", "preset", "assetsPath", "gradientMapSrc", "gradientMap2Src", "gradientMapCanvas", "imageSrc"];
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
var DEFAULT_CDN_PATH = 'https://cdn.jsdelivr.net/npm/@razorpay/blade@latest/assets/spark';
var getDefaultAssets = function getDefaultAssets(assetsPath) {
return {
videoSrc: "".concat(assetsPath, "/spark-base-video.mp4"),
imageSrc: "".concat(assetsPath, "/bottom-frame.jpg"),
gradientMapSrc: "".concat(assetsPath, "/colorama-gradient-map-green.jpg"),
gradientMap2Src: "".concat(assetsPath, "/colorama-gradient-map-blue.jpg"),
centerGradientMapSrc: "".concat(assetsPath, "/colorama-center-gradient-map.jpg")
};
};
/**
* Extract config from props (exclude non-config props).
* Strips undefined values so they don't clobber preset defaults.
*/
function extractConfig(props) {
var _width = props.width,
_height = props.height,
_className = props.className,
_style = props.style,
_onLoad = props.onLoad,
_onError = props.onError,
_preset = props.preset,
_assetsPath = props.assetsPath,
_gradientMapSrc = props.gradientMapSrc,
_gradientMap2Src = props.gradientMap2Src,
_gradientMapCanvas = props.gradientMapCanvas,
_imageSrc = props.imageSrc,
config = _objectWithoutProperties(props, _excluded);
// Drop keys with undefined values so preset config isn't overridden by unset props
return Object.fromEntries(
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
Object.entries(config).filter(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
v = _ref2[1];
return v !== undefined;
}));
}
var ASSET_KEYS = new Set(['videoSrc', 'imageSrc', 'gradientMapSrc', 'gradientMap2Src', 'centerGradientMapSrc']);
/* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return */
function getPresetDefinition(preset, assetsPath) {
var presets = getPresets(assetsPath);
if (preset && preset in presets) return _objectSpread({}, presets[preset]);
return {};
}
function getPresetConfig(preset, assetsPath) {
var def = getPresetDefinition(preset, assetsPath);
return Object.fromEntries(Object.entries(def).filter(function (_ref3) {
var _ref4 = _slicedToArray(_ref3, 1),
k = _ref4[0];
return !ASSET_KEYS.has(k);
}));
}
function getPresetAssets(preset, assetsPath) {
var def = getPresetDefinition(preset, assetsPath);
return Object.fromEntries(Object.entries(def).filter(function (_ref5) {
var _ref6 = _slicedToArray(_ref5, 1),
k = _ref6[0];
return ASSET_KEYS.has(k);
}));
}
/**
* Merge preset config with user-provided config.
* Preset values are used as base; any explicit prop overrides them.
*/
function resolveConfig(props, assetsPath) {
return _objectSpread(_objectSpread({}, getPresetConfig(props.preset, assetsPath)), extractConfig(props));
}
/**
* Load an image from URL
*/
function loadImage(src) {
return new Promise(function (resolve, reject) {
var img = new Image();
img.crossOrigin = 'anonymous';
img.onload = function () {
return resolve(img);
};
img.onerror = function () {
return reject(new Error("Failed to load image: ".concat(src)));
};
img.src = src;
});
}
/**
* Load a video from URL
*/
function loadVideo(src) {
return new Promise(function (resolve, reject) {
var video = document.createElement('video');
video.src = src;
video.crossOrigin = 'anonymous';
video.loop = true;
video.muted = true;
video.playsInline = true;
video.preload = 'auto';
video.oncanplaythrough = function () {
return resolve(video);
};
video.onerror = function () {
return reject(new Error("Failed to load video: ".concat(src)));
};
video.load();
});
}
/**
* Check if browser is Safari
*/
function isSafari() {
var ua = navigator.userAgent.toLowerCase();
return ua.includes('safari') && !ua.includes('chrome') && !ua.includes('android');
}
/**
* Best guess browser zoom level (for Safari which doesn't include zoom in devicePixelRatio)
*/
function bestGuessBrowserZoom() {
var _visualViewport$scale, _visualViewport, _visualViewport$width, _visualViewport2;
var viewportScale = (_visualViewport$scale = (_visualViewport = visualViewport) === null || _visualViewport === void 0 ? void 0 : _visualViewport.scale) !== null && _visualViewport$scale !== void 0 ? _visualViewport$scale : 1;
var viewportWidth = (_visualViewport$width = (_visualViewport2 = visualViewport) === null || _visualViewport2 === void 0 ? void 0 : _visualViewport2.width) !== null && _visualViewport$width !== void 0 ? _visualViewport$width : window.innerWidth;
var scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
var innerWidth = viewportScale * viewportWidth + scrollbarWidth;
var ratio = outerWidth / innerWidth;
var zoomPercentageRounded = Math.round(100 * ratio);
// Common zoom levels divisible by 5%
if (zoomPercentageRounded % 5 === 0) {
return zoomPercentageRounded / 100;
}
// Handle special zoom levels
if (zoomPercentageRounded === 33) return 1 / 3;
if (zoomPercentageRounded === 67) return 2 / 3;
if (zoomPercentageRounded === 133) return 4 / 3;
return ratio;
}
/**
* Preload all assets for a given RazorSense preset.
* This ensures videos and images are fully loaded before the component mounts,
* preventing frame skipping in one-shot animations.
*
* @param preset - The preset name to preload assets for
* @param assetsPath - Optional CDN path for assets (defaults to Blade CDN)
* @returns Promise that resolves when all assets are loaded
*
* @example
* ```tsx
* // Preload before showing the animation
* await preloadRazorSenseAssets('circleSlideUp');
*
* // Now mount the component - assets are already cached
* <RazorSense preset="circleSlideUp" />
* ```
*/
function preloadRazorSenseAssets() {
return _preloadRazorSenseAssets.apply(this, arguments);
}
function _preloadRazorSenseAssets() {
_preloadRazorSenseAssets = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
var _presetDef$videoSrc, _presetDef$gradientMa, _presetDef$gradientMa2, _presetDef$centerGrad;
var preset,
assetsPath,
presets,
presetDef,
defaultAssets,
videoSrc,
imageSrc,
gradientMapSrc,
gradientMap2Src,
centerGradientMapSrc,
loadPromises,
_args = arguments;
return _regeneratorRuntime.wrap(function (_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
preset = _args.length > 0 && _args[0] !== undefined ? _args[0] : 'default';
assetsPath = _args.length > 1 && _args[1] !== undefined ? _args[1] : DEFAULT_CDN_PATH;
presets = getPresets(assetsPath);
presetDef = presets[preset] || {};
defaultAssets = getDefaultAssets(assetsPath);
videoSrc = (_presetDef$videoSrc = presetDef.videoSrc) !== null && _presetDef$videoSrc !== void 0 ? _presetDef$videoSrc : defaultAssets.videoSrc;
imageSrc = presetDef.imageSrc;
gradientMapSrc = (_presetDef$gradientMa = presetDef.gradientMapSrc) !== null && _presetDef$gradientMa !== void 0 ? _presetDef$gradientMa : defaultAssets.gradientMapSrc;
gradientMap2Src = (_presetDef$gradientMa2 = presetDef.gradientMap2Src) !== null && _presetDef$gradientMa2 !== void 0 ? _presetDef$gradientMa2 : defaultAssets.gradientMap2Src;
centerGradientMapSrc = (_presetDef$centerGrad = presetDef.centerGradientMapSrc) !== null && _presetDef$centerGrad !== void 0 ? _presetDef$centerGrad : defaultAssets.centerGradientMapSrc;
loadPromises = [];
if (imageSrc) {
loadPromises.push(loadImage(imageSrc));
} else if (videoSrc) {
loadPromises.push(loadVideo(videoSrc));
}
loadPromises.push(loadImage(gradientMapSrc), loadImage(gradientMap2Src), loadImage(centerGradientMapSrc));
_context.next = 1;
return Promise.all(loadPromises);
case 1:
case "end":
return _context.stop();
}
}, _callee);
}));
return _preloadRazorSenseAssets.apply(this, arguments);
}
export { DEFAULT_CDN_PATH, bestGuessBrowserZoom, getDefaultAssets, getPresetAssets, isSafari, loadImage, loadVideo, preloadRazorSenseAssets, resolveConfig };
//# sourceMappingURL=utils.js.map