@gravatar-com/hovercards
Version:
Add profile hovercards to Gravatar images.
765 lines (719 loc) • 31.9 kB
JavaScript
import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react";
/******/ var __webpack_modules__ = ({
/***/ 43:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
var __webpack_unused_export__;
/**
* @license React
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var f = __webpack_require__(810),
k = Symbol["for"]("react.element"),
l = Symbol["for"]("react.fragment"),
m = Object.prototype.hasOwnProperty,
n = f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,
p = {
key: !0,
ref: !0,
__self: !0,
__source: !0
};
function q(c, a, g) {
var b,
d = {},
e = null,
h = null;
void 0 !== g && (e = "" + g);
void 0 !== a.key && (e = "" + a.key);
void 0 !== a.ref && (h = a.ref);
for (b in a) m.call(a, b) && !p.hasOwnProperty(b) && (d[b] = a[b]);
if (c && c.defaultProps) for (b in a = c.defaultProps, a) void 0 === d[b] && (d[b] = a[b]);
return {
$$typeof: k,
type: c,
key: e,
ref: h,
props: d,
_owner: n.current
};
}
__webpack_unused_export__ = l;
exports.jsx = q;
__webpack_unused_export__ = q;
/***/ }),
/***/ 823:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
if (true) {
module.exports = __webpack_require__(43);
} else {}
/***/ }),
/***/ 810:
/***/ ((module) => {
var x = y => { var x = {}; __webpack_require__.d(x, y); return x; }
var y = x => () => x
module.exports = __WEBPACK_EXTERNAL_MODULE_react__;
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
i: () => (/* reexport */ hovercards_Hovercards),
f: () => (/* reexport */ useHovercards)
});
// EXTERNAL MODULE: external "react"
var external_react_ = __webpack_require__(810);
;// CONCATENATED MODULE: ./src/use-latest.ts
/**
* A custom React hook to persist a mutable value.
*
* @template T The type of the value.
* @param {T} val The value to persist.
* @return {MutableRefObject<T>} Mutable reference object initialized to `val`.
* @internal
*/
/* harmony default export */ const use_latest = (function (val) {
var ref = (0,external_react_.useRef)(val);
ref.current = val;
return ref;
});
;// CONCATENATED MODULE: ./src/compute-position.ts
var paddingMap = {
top: 'paddingBottom',
bottom: 'paddingTop',
left: 'paddingRight',
right: 'paddingLeft'
};
/**
* Computes the position of a card relative to a ref element.
*
* @param {HTMLElement} ref - The ref element.
* @param {HTMLDivElement} card - The card element.
* @param {Options} [options={}] - The placement, offset, and auto-flip options.
* @return {ReturnValues} - The computed position values.
*/
function computingPosition(ref, card, _temp) {
var _ref = _temp === void 0 ? {} : _temp,
_ref$placement = _ref.placement,
placement = _ref$placement === void 0 ? 'right' : _ref$placement,
_ref$offset = _ref.offset,
offset = _ref$offset === void 0 ? 0 : _ref$offset,
_ref$autoFlip = _ref.autoFlip,
autoFlip = _ref$autoFlip === void 0 ? true : _ref$autoFlip;
var refRect = ref.getBoundingClientRect();
var cardRect = card.getBoundingClientRect();
var refScrollT = refRect.top + scrollY;
var refScrollB = refRect.bottom + scrollY;
var refScrollR = refRect.right + scrollX;
var refScrollL = refRect.left + scrollX;
var x = 0;
var y = 0;
var _placement$split = placement.split('-'),
dir = _placement$split[0],
align = _placement$split[1];
offset = Math.max(0, offset);
// Auto flip the card if there's not enough space
// If both sides have not enough space, then the card will be placed on the side with more space
if (autoFlip) {
var topSpace = refRect.top;
var bottomSpace = innerHeight - refRect.bottom;
var leftSpace = refRect.left;
var rightSpace = innerWidth - refRect.right;
var floatingSpaceV = cardRect.height + offset;
var floatingSpaceH = cardRect.width + offset;
if (dir === 'top' && topSpace < floatingSpaceV && bottomSpace > topSpace) {
dir = 'bottom';
}
if (dir === 'bottom' && bottomSpace < floatingSpaceV && topSpace > bottomSpace) {
dir = 'top';
}
if (dir === 'left' && leftSpace < floatingSpaceH && rightSpace > leftSpace) {
dir = 'right';
}
if (dir === 'right' && rightSpace < floatingSpaceH && leftSpace > rightSpace) {
dir = 'left';
}
}
// Calculate the position of the card
if (dir === 'top' || dir === 'bottom') {
x = refScrollL + refRect.width / 2 - cardRect.width / 2;
// The bottom offset will be filled with the card's padding
y = dir === 'top' ? refScrollT - cardRect.height - offset : refScrollB;
if (align === 'start') {
x = refScrollL;
}
if (align === 'end') {
x = refScrollR - cardRect.width;
}
} else {
// The right offset will be filled with the card's padding
x = dir === 'right' ? refScrollR : refScrollL - cardRect.width - offset;
y = refScrollT + refRect.height / 2 - cardRect.height / 2;
if (align === 'start') {
y = refScrollT;
}
if (align === 'end') {
y = refScrollB - cardRect.height;
}
}
return {
x: x,
y: y,
padding: paddingMap[dir],
paddingValue: offset
};
}
;// CONCATENATED MODULE: ./src/sanitizer.ts
function escHtml(str) {
var htmlEntities = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'`': '`'
};
// Don't escape if already escaped.
return str.replace(/&(amp|lt|gt|quot|#39|x60);|[\&<>"'`]/g, function (match) {
return match[0] === '&' ? match : htmlEntities[match];
});
}
function escUrl(url) {
return encodeURI(url);
}
;// CONCATENATED MODULE: ./src/i18n.ts
function __(i18n, key) {
return i18n[key] || key;
}
;// CONCATENATED MODULE: ./src/core.ts
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var BASE_API_URL = 'https://secure.gravatar.com';
var socialLinksOrder = ['wordpress', 'mastodon', 'tumblr', 'github', 'twitter'];
var dc = document;
var Hovercards = /*#__PURE__*/function () {
function Hovercards(_temp) {
var _this = this;
var _ref = _temp === void 0 ? {} : _temp,
_ref$placement = _ref.placement,
placement = _ref$placement === void 0 ? 'right' : _ref$placement,
_ref$autoFlip = _ref.autoFlip,
autoFlip = _ref$autoFlip === void 0 ? true : _ref$autoFlip,
_ref$offset = _ref.offset,
offset = _ref$offset === void 0 ? 10 : _ref$offset,
_ref$delayToShow = _ref.delayToShow,
delayToShow = _ref$delayToShow === void 0 ? 500 : _ref$delayToShow,
_ref$delayToHide = _ref.delayToHide,
delayToHide = _ref$delayToHide === void 0 ? 300 : _ref$delayToHide,
_ref$additionalClass = _ref.additionalClass,
additionalClass = _ref$additionalClass === void 0 ? '' : _ref$additionalClass,
_ref$myHash = _ref.myHash,
myHash = _ref$myHash === void 0 ? '' : _ref$myHash,
_ref$onQueryHovercard = _ref.onQueryHovercardRef,
onQueryHovercardRef = _ref$onQueryHovercard === void 0 ? function (ref) {
return ref;
} : _ref$onQueryHovercard,
_ref$onFetchProfileSt = _ref.onFetchProfileStart,
onFetchProfileStart = _ref$onFetchProfileSt === void 0 ? function () {} : _ref$onFetchProfileSt,
_ref$onFetchProfileSu = _ref.onFetchProfileSuccess,
onFetchProfileSuccess = _ref$onFetchProfileSu === void 0 ? function () {} : _ref$onFetchProfileSu,
_ref$onFetchProfileFa = _ref.onFetchProfileFailure,
onFetchProfileFailure = _ref$onFetchProfileFa === void 0 ? function () {} : _ref$onFetchProfileFa,
_ref$onHovercardShown = _ref.onHovercardShown,
onHovercardShown = _ref$onHovercardShown === void 0 ? function () {} : _ref$onHovercardShown,
_ref$onHovercardHidde = _ref.onHovercardHidden,
onHovercardHidden = _ref$onHovercardHidde === void 0 ? function () {} : _ref$onHovercardHidde,
_ref$i18n = _ref.i18n,
i18n = _ref$i18n === void 0 ? {} : _ref$i18n;
// Options
this._i18n = {};
// Variables
this._hovercardRefs = [];
this._showHovercardTimeoutIds = new Map();
this._hideHovercardTimeoutIds = new Map();
this._cachedProfiles = new Map();
/**
* Attaches event listeners on or within the target element.
*
* @param {HTMLElement} target - The target element to set.
* @param {Object} [options={}] - The optional parameters.
* @param options.dataAttributeName - Data attribute name associated with Gravatar hashes.
* @param options.ignoreSelector - The selector to ignore certain elements.
* @return {void}
*/
this.attach = function (target, _temp2) {
var _ref2 = _temp2 === void 0 ? {} : _temp2,
_ref2$dataAttributeNa = _ref2.dataAttributeName,
dataAttributeName = _ref2$dataAttributeNa === void 0 ? 'gravatar-hash' : _ref2$dataAttributeNa,
ignoreSelector = _ref2.ignoreSelector;
if (!target) {
return;
}
_this.detach();
_this._queryHovercardRefs(target, dataAttributeName, ignoreSelector).forEach(function (hovercardRef) {
hovercardRef.ref.addEventListener('mouseenter', function (e) {
return _this._handleMouseEnter(e, hovercardRef);
});
hovercardRef.ref.addEventListener('mouseleave', function (e) {
return _this._handleMouseLeave(e, hovercardRef);
});
});
};
/**
* Removes event listeners from hovercard refs and resets the stored list of these refs.
*
* @return {void}
*/
this.detach = function () {
if (!_this._hovercardRefs.length) {
return;
}
_this._hovercardRefs.forEach(function (_ref3) {
var ref = _ref3.ref;
ref.removeEventListener('mouseenter', function () {
return _this._handleMouseEnter;
});
ref.removeEventListener('mouseleave', function () {
return _this._handleMouseLeave;
});
});
_this._hovercardRefs = [];
};
this._placement = placement;
this._autoFlip = autoFlip;
this._offset = offset;
this._delayToShow = delayToShow;
this._delayToHide = delayToHide;
this._additionalClass = additionalClass;
this._myHash = myHash;
this._onQueryHovercardRef = onQueryHovercardRef;
this._onFetchProfileStart = onFetchProfileStart;
this._onFetchProfileSuccess = onFetchProfileSuccess;
this._onFetchProfileFailure = onFetchProfileFailure;
this._onHovercardShown = onHovercardShown;
this._onHovercardHidden = onHovercardHidden;
this._i18n = i18n;
}
/**
* Queries hovercard refs on or within the target element
*
* @param {HTMLElement} target - The element to query.
* @param {string} dataAttributeName - Data attribute name associated with Gravatar hashes.
* @param {string} [ignoreSelector] - The selector to ignore certain elements.
* @return {HTMLElement[]} - The queried hovercard refs.
* @private
*/
var _proto = Hovercards.prototype;
_proto._queryHovercardRefs = function _queryHovercardRefs(target, dataAttributeName, ignoreSelector) {
var _this2 = this;
var refs = [];
var camelAttrName = dataAttributeName.replace(/-([a-z])/g, function (g) {
return g[1].toUpperCase();
});
var ignoreRefs = ignoreSelector ? Array.from(dc.querySelectorAll(ignoreSelector)) : [];
var matchPath = 'gravatar.com/avatar/';
if (target.dataset[camelAttrName] || target.tagName === 'IMG' && target.src.includes(matchPath)) {
refs = [target];
} else {
refs = Array.from(target.querySelectorAll("img[src*=\"" + matchPath + "\"]"));
if (dataAttributeName) {
refs = [].concat(refs.filter(function (img) {
return !img.hasAttribute("data-" + dataAttributeName);
}), Array.from(target.querySelectorAll("[data-" + dataAttributeName + "]")));
}
}
this._hovercardRefs = refs.map(function (ref, idx) {
if (ignoreRefs.includes(ref)) {
return null;
}
var hash;
var params;
var dataAttrValue = ref.dataset[camelAttrName];
if (dataAttrValue) {
hash = dataAttrValue.split('?')[0];
params = dataAttrValue;
} else if (ref.tagName === 'IMG') {
hash = ref.src.split('/').pop().split('?')[0];
params = ref.src;
}
if (!hash) {
return null;
}
var p = new URLSearchParams(params);
var d = p.get('d') || p.get('default');
var f = p.get('f') || p.get('forcedefault');
var r = p.get('r') || p.get('rating');
params = [d && "d=" + d, f && "f=" + f, r && "r=" + r].filter(Boolean).join('&');
return {
id: "gravatar-hovercard-" + hash + "-" + idx,
hash: hash,
params: params ? "?" + params : '',
ref: _this2._onQueryHovercardRef(ref) || ref
};
}).filter(Boolean);
return this._hovercardRefs;
}
/**
* Creates a skeleton hovercard element.
*
* @return {HTMLDivElement} The created skeleton hovercard element.
*/;
_proto._createHovercardSkeleton = function _createHovercardSkeleton() {
var hovercard = dc.createElement('div');
hovercard.className = "gravatar-hovercard gravatar-hovercard--skeleton" + (this._additionalClass ? " " + this._additionalClass : '');
hovercard.innerHTML = "\n\t\t\t<div class=\"gravatar-hovercard__inner\">\n\t\t\t\t<div class=\"gravatar-hovercard__header\">\n\t\t\t\t\t<div class=\"gravatar-hovercard__avatar-link\"></div>\n\t\t\t\t\t<div class=\"gravatar-hovercard__name-location-link\"></div>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"gravatar-hovercard__footer\">\n\t\t\t\t\t<div class=\"gravatar-hovercard__social-link\"></div>\n\t\t\t\t\t<div class=\"gravatar-hovercard__profile-link\"\"></div>\n\t\t\t\t</div>\n\t\t\t</div>\n ";
return hovercard;
}
/**
* Creates a hovercard element with the provided profile data.
*
* @param {ProfileData} profileData - The profile data to populate the hovercard.
* @param {Object} [options] - Optional parameters for the hovercard.
* @param {string} [options.additionalClass] - Additional CSS class for the hovercard.
* @param {string} [options.myHash] - The hash of the current user.
* @param {Object} [options.i18n] - The i18n object.
* @return {HTMLDivElement} - The created hovercard element.
*/;
/**
* Waits for a specified delay and fetches the user's profile data,
* then shows the hovercard relative to the ref element.
*
* @param {HovercardRef} hovercardRef - The hovercard ref object.
* @return {void}
* @private
*/
_proto._showHovercard = function _showHovercard(_ref4) {
var _this3 = this;
var id = _ref4.id,
hash = _ref4.hash,
params = _ref4.params,
ref = _ref4.ref;
var timeoutId = setTimeout(function () {
if (dc.getElementById(id)) {
return;
}
var hovercard;
if (_this3._cachedProfiles.has(hash)) {
var profile = _this3._cachedProfiles.get(hash);
hovercard = Hovercards.createHovercard(_extends({}, profile, {
thumbnailUrl: profile.thumbnailUrl + params
}), {
additionalClass: _this3._additionalClass,
myHash: _this3._myHash,
i18n: _this3._i18n
});
} else {
hovercard = _this3._createHovercardSkeleton();
_this3._onFetchProfileStart(hash);
fetch(BASE_API_URL + "/" + hash + ".json").then(function (res) {
return res.json();
}).then(function (data) {
// API error handling
if (!(data != null && data.entry)) {
// The data will be an error message
throw new Error(data);
}
var _data$entry$ = data.entry[0],
fetchedHash = _data$entry$.hash,
thumbnailUrl = _data$entry$.thumbnailUrl,
preferredUsername = _data$entry$.preferredUsername,
displayName = _data$entry$.displayName,
currentLocation = _data$entry$.currentLocation,
aboutMe = _data$entry$.aboutMe,
accounts = _data$entry$.accounts;
_this3._cachedProfiles.set(hash, {
hash: fetchedHash,
thumbnailUrl: thumbnailUrl,
preferredUsername: preferredUsername,
displayName: displayName,
currentLocation: currentLocation,
aboutMe: aboutMe,
accounts: accounts == null ? void 0 : accounts.map(function (_ref5) {
var url = _ref5.url,
shortname = _ref5.shortname,
iconUrl = _ref5.iconUrl,
name = _ref5.name;
return {
url: url,
shortname: shortname,
iconUrl: iconUrl,
name: name
};
})
});
var profile = _this3._cachedProfiles.get(hash);
var hovercardInner = Hovercards.createHovercard(_extends({}, profile, {
thumbnailUrl: profile.thumbnailUrl + params
}), {
additionalClass: _this3._additionalClass,
myHash: _this3._myHash,
i18n: _this3._i18n
}).firstElementChild;
hovercard.classList.remove('gravatar-hovercard--skeleton');
hovercard.replaceChildren(hovercardInner);
_this3._onFetchProfileSuccess(hash, _this3._cachedProfiles.get(hash));
})["catch"](function (error) {
hovercard.firstElementChild.classList.add('gravatar-hovercard__inner--error');
hovercard.firstElementChild.innerHTML = "\n\t\t\t\t\t\t\t<img class=\"gravatar-hovercard__avatar\" src=\"https://2.gravatar.com/avatar/" + hash + params + "\" width=\"56\" height=\"56\" alt=\"Avatar\" />\n\t\t\t\t\t\t\t<i class=\"gravatar-hovercard__error-message\">" + (error.message === 'User not found' ? __(_this3._i18n, 'Sorry, we are unable to load this Gravatar profile.') : __(_this3._i18n, 'Sorry, we are unable to load this Gravatar profile. Please check your internet connection.')) + "</i>\n\t\t\t\t\t\t";
_this3._onFetchProfileFailure(hash, error);
});
}
// Set the hovercard ID here to avoid the show / hide side effect
hovercard.id = id;
// Don't hide the hovercard when the mouse is over the hovercard from the ref
hovercard.addEventListener('mouseenter', function () {
return clearInterval(_this3._hideHovercardTimeoutIds.get(id));
});
hovercard.addEventListener('mouseleave', function () {
return _this3._hideHovercard(id);
});
// Placing the hovercard at the top-level of the dc to avoid being clipped by overflow
dc.body.appendChild(hovercard);
var _computePosition = computingPosition(ref, hovercard, {
placement: _this3._placement,
offset: _this3._offset,
autoFlip: _this3._autoFlip
}),
x = _computePosition.x,
y = _computePosition.y,
padding = _computePosition.padding,
paddingValue = _computePosition.paddingValue;
hovercard.style.position = 'absolute';
hovercard.style.left = x + "px";
hovercard.style.top = y + "px";
// To bridge the gap between the ref and the hovercard,
// ensuring that the hovercard remains visible when the mouse hovers over the gap
hovercard.style[padding] = paddingValue + "px";
_this3._onHovercardShown(hash, hovercard);
}, this._delayToShow);
this._showHovercardTimeoutIds.set(id, timeoutId);
}
/**
* Waits for a specified delay and hides the hovercard.
*
* @param {string} id - The ID associated with the hovercard.
* @return {void}
* @private
*/;
_proto._hideHovercard = function _hideHovercard(id) {
var _this4 = this;
var timeoutId = setTimeout(function () {
var hovercard = dc.getElementById(id);
if (hovercard) {
hovercard.remove();
_this4._onHovercardHidden(id, hovercard);
}
}, this._delayToHide);
this._hideHovercardTimeoutIds.set(id, timeoutId);
}
/**
* Handles the mouseenter event for hovercard refs.
*
* @param {MouseEvent} e - The mouseenter event object.
* @param hovercardRef - The hovercard ref object.
* @return {void}
* @private
*/;
_proto._handleMouseEnter = function _handleMouseEnter(e, hovercardRef) {
e.stopImmediatePropagation();
// Don't hide the hovercard when the mouse is over the ref from the hovercard
clearInterval(this._hideHovercardTimeoutIds.get(hovercardRef.id));
this._showHovercard(hovercardRef);
}
/**
* Handles the mouseleave event for hovercard refs.
*
* @param {MouseEvent} e - The mouseleave event object.
* @param hovercardRef - The hovercard ref object.
* @param hovercardRef.id - The ID associated with the hovercard.
* @return {void}
* @private
*/;
_proto._handleMouseLeave = function _handleMouseLeave(e, _ref6) {
var id = _ref6.id;
e.stopImmediatePropagation();
clearInterval(this._showHovercardTimeoutIds.get(id));
this._hideHovercard(id);
};
return Hovercards;
}();
Hovercards.createHovercard = function (profileData, _temp3) {
var _ref7 = _temp3 === void 0 ? {} : _temp3,
additionalClass = _ref7.additionalClass,
myHash = _ref7.myHash,
_ref7$i18n = _ref7.i18n,
i18n = _ref7$i18n === void 0 ? {} : _ref7$i18n;
var hash = profileData.hash,
thumbnailUrl = profileData.thumbnailUrl,
preferredUsername = profileData.preferredUsername,
displayName = profileData.displayName,
currentLocation = profileData.currentLocation,
aboutMe = profileData.aboutMe,
_profileData$accounts = profileData.accounts,
accounts = _profileData$accounts === void 0 ? [] : _profileData$accounts;
var hovercard = dc.createElement('div');
hovercard.className = "gravatar-hovercard" + (additionalClass ? " " + additionalClass : '');
var profileUrl = escUrl("https://gravatar.com/" + preferredUsername + "?utm_source=hovercard");
var username = escHtml(displayName);
var isEditProfile = !aboutMe && myHash === hash;
var renderSocialLinks = accounts.reduce(function (links, _ref8) {
var url = _ref8.url,
shortname = _ref8.shortname,
iconUrl = _ref8.iconUrl,
name = _ref8.name;
var idx = socialLinksOrder.indexOf(shortname);
if (idx !== -1) {
links[idx] = "\n\t\t\t\t\t\t<a class=\"gravatar-hovercard__social-link\" href=\"" + escUrl(url) + "\" target=\"_blank\" data-service-name=\"" + shortname + "\">\n\t\t\t\t\t\t\t<img class=\"gravatar-hovercard__social-icon\" src=\"" + escUrl(iconUrl) + "\" width=\"32\" height=\"32\" alt=\"" + escHtml(name) + "\" />\n\t\t\t\t\t\t</a>\n\t\t\t\t\t";
}
return links;
}, []).join('');
hovercard.innerHTML = "\n\t\t\t<div class=\"gravatar-hovercard__inner\">\n\t\t\t\t<div class=\"gravatar-hovercard__header\">\n\t\t\t\t\t<a class=\"gravatar-hovercard__avatar-link\" href=\"" + profileUrl + "\" target=\"_blank\">\n\t\t\t\t\t\t<img class=\"gravatar-hovercard__avatar\" src=\"" + escUrl(thumbnailUrl) + "\" width=\"56\" height=\"56\" alt=\"" + username + "\" />\n\t\t\t\t\t</a>\n\t\t\t\t\t<a class=\"gravatar-hovercard__name-location-link\" href=\"" + profileUrl + "\" target=\"_blank\">\n\t\t\t\t\t\t<h4 class=\"gravatar-hovercard__name\">" + username + "</h4>\n\t\t\t\t\t\t" + (currentLocation ? "<p class=\"gravatar-hovercard__location\">" + escHtml(currentLocation) + "</p>" : '') + "\n\t\t\t\t\t</a>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"gravatar-hovercard__body\">\n\t\t\t\t\t" + (aboutMe ? "<p class=\"gravatar-hovercard__about\">" + escHtml(aboutMe) + "</p>" : '') + "\n\t\t\t\t</div>\n\t\t\t\t<div class=\"gravatar-hovercard__footer\">\n\t\t\t\t\t<div class=\"gravatar-hovercard__social-links\">\n\t\t\t\t\t\t<a class=\"gravatar-hovercard__social-link\" href=\"" + profileUrl + "\" target=\"_blank\" data-service-name=\"gravatar\">\n\t\t\t\t\t\t\t<img class=\"gravatar-hovercard__social-icon\" src=\"https://secure.gravatar.com/icons/gravatar.svg\" width=\"32\" height=\"32\" alt=\"Gravatar\" />\n\t\t\t\t\t\t</a>\n\t\t\t\t\t\t" + renderSocialLinks + "\n\t\t\t\t\t</div>\n\t\t\t\t\t<a\n\t\t\t\t\t\tclass=\"gravatar-hovercard__profile-link" + (isEditProfile ? ' gravatar-hovercard__profile-link--edit' : '') + "\"\n\t\t\t\t\t\thref=\"" + (isEditProfile ? 'https://gravatar.com/profiles/edit?utm_source=hovercard' : profileUrl) + "\"\n\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<span class=\"gravatar-hovercard__profile-link-text\">\n\t\t\t\t\t\t\t" + (isEditProfile ? __(i18n, 'Edit your profile') : __(i18n, 'View profile')) + "\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t\t\t\t\t\t<path d=\"M12.6667 8.33338L9.16666 12.1667M12.6667 8.33338L2.66666 8.33338M12.6667 8.33338L9.16666 4.83338\" stroke-width=\"1.5\"/>\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t</a>\n\t\t\t\t</div>\n\t\t\t</div>\n ";
return hovercard;
};
;// CONCATENATED MODULE: ./src/use-hovercards.ts
function useHovercards(_temp) {
var _ref = _temp === void 0 ? {} : _temp,
placement = _ref.placement,
offset = _ref.offset,
autoFlip = _ref.autoFlip,
delayToShow = _ref.delayToShow,
delayToHide = _ref.delayToHide,
additionalClass = _ref.additionalClass,
myHash = _ref.myHash,
i18n = _ref.i18n,
onQueryHovercardRef = _ref.onQueryHovercardRef,
onFetchProfileStart = _ref.onFetchProfileStart,
onFetchProfileSuccess = _ref.onFetchProfileSuccess,
onFetchProfileFailure = _ref.onFetchProfileFailure,
onHovercardShown = _ref.onHovercardShown,
onHovercardHidden = _ref.onHovercardHidden;
// These callbacks / variables won't trigger hooks update and will always be the latest
var onQueryHovercardRefRef = use_latest(onQueryHovercardRef);
var onFetchProfileStartRef = use_latest(onFetchProfileStart);
var onFetchProfileSuccessRef = use_latest(onFetchProfileSuccess);
var onFetchProfileFailureRef = use_latest(onFetchProfileFailure);
var onHovercardShownRef = use_latest(onHovercardShown);
var onHovercardHiddenRef = use_latest(onHovercardHidden);
var i18nRef = use_latest(i18n);
// Instantiate the Hovercards class only when the options change
var _useMemo = (0,external_react_.useMemo)(function () {
return new Hovercards({
placement: placement,
offset: offset,
autoFlip: autoFlip,
delayToShow: delayToShow,
delayToHide: delayToHide,
additionalClass: additionalClass,
myHash: myHash,
i18n: i18nRef.current,
onQueryHovercardRef: onQueryHovercardRefRef.current,
onFetchProfileStart: onFetchProfileStartRef.current,
onFetchProfileSuccess: onFetchProfileSuccessRef.current,
onFetchProfileFailure: onFetchProfileFailureRef.current,
onHovercardShown: onHovercardShownRef.current,
onHovercardHidden: onHovercardHiddenRef.current
});
}, [placement, offset, autoFlip, delayToShow, delayToHide, additionalClass, myHash, i18nRef, onQueryHovercardRefRef, onFetchProfileStartRef, onFetchProfileSuccessRef, onFetchProfileFailureRef, onHovercardShownRef, onHovercardHiddenRef]),
attach = _useMemo.attach,
detach = _useMemo.detach;
(0,external_react_.useEffect)(function () {
return detach;
}, [detach]);
return {
attach: attach,
detach: detach,
createHovercard: Hovercards.createHovercard
};
}
// EXTERNAL MODULE: ./node_modules/react/jsx-runtime.js
var jsx_runtime = __webpack_require__(823);
;// CONCATENATED MODULE: ./src/hovercards.tsx
var _excluded = ["children", "attach", "dataAttributeName", "ignoreSelector", "className", "style"];
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 hovercards_Hovercards(_temp) {
var _ref = _temp === void 0 ? {} : _temp,
children = _ref.children,
attach = _ref.attach,
dataAttributeName = _ref.dataAttributeName,
ignoreSelector = _ref.ignoreSelector,
className = _ref.className,
style = _ref.style,
options = _objectWithoutPropertiesLoose(_ref, _excluded);
var _useHovercards = useHovercards(options),
attachTo = _useHovercards.attach;
var containerRef = (0,external_react_.useRef)(null);
var attachRef = use_latest(attach);
(0,external_react_.useEffect)(function () {
var target = attachRef.current || containerRef.current;
if (target) {
attachTo(target, {
dataAttributeName: dataAttributeName,
ignoreSelector: ignoreSelector
});
}
}, [attachTo, attachRef, dataAttributeName, ignoreSelector]);
if (attach || !children) {
return null;
}
return /*#__PURE__*/(0,jsx_runtime.jsx)("div", {
ref: containerRef,
className: className,
style: style,
children: children
});
}
;// CONCATENATED MODULE: ./src/index.react.ts
})();
var __webpack_exports__Hovercards = __webpack_exports__.i;
var __webpack_exports__useHovercards = __webpack_exports__.f;
export { __webpack_exports__Hovercards as Hovercards, __webpack_exports__useHovercards as useHovercards };
//# sourceMappingURL=index.react.mjs.map