sticky-horse
Version:
With StickyHorse allow your users to send feedback to your team.
152 lines (151 loc) • 7.24 kB
JavaScript
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.CursorOverlay = void 0;
var react_1 = __importStar(require("react"));
var CursorOverlay = function (_a) {
var users = _a.users, _b = _a.showUserInfo, showUserInfo = _b === void 0 ? true : _b;
var _c = (0, react_1.useState)({
height: typeof window !== 'undefined' ? window.innerHeight : 0,
width: typeof window !== 'undefined' ? window.innerWidth : 0,
}), windowDimensions = _c[0], setWindowDimensions = _c[1];
(0, react_1.useEffect)(function () {
if (typeof window === 'undefined')
return;
var updateWindowDimensions = function () {
setWindowDimensions({
height: window.innerHeight,
width: window.innerWidth,
});
};
var handleScroll = function () {
// Force re-render on scroll to update cursor positions
setWindowDimensions(function (prev) { return (__assign({}, prev)); });
};
window.addEventListener('scroll', handleScroll);
window.addEventListener('resize', updateWindowDimensions);
return function () {
window.removeEventListener('scroll', handleScroll);
window.removeEventListener('resize', updateWindowDimensions);
};
}, []);
// if (!trackedUserId) return null;
// if (!users.length && !adminCursor) return null;
return (react_1.default.createElement("div", { className: "absolute inset-0 pointer-events-none z-50" }, users.map(function (user) {
if (!(user === null || user === void 0 ? void 0 : user.cursor))
return null;
var isVisible = isCursorVisible(user.cursor, windowDimensions.height, windowDimensions.width);
var isAdmin = user.isAdmin;
if (!isVisible) {
var arrowPos = getArrowPosition(user.cursor, windowDimensions.height, windowDimensions.width);
return (react_1.default.createElement("div", { key: user.userId, className: "absolute w-10 h-10 ".concat(isAdmin ? 'bg-red-500' : 'bg-indigo-500', " rounded-full flex items-center justify-center"), style: {
left: arrowPos.x,
top: arrowPos.y,
transform: 'translate(-50%, -50%)'
} },
react_1.default.createElement("svg", { className: "w-6 h-6 text-white transform ".concat(getArrowRotation(arrowPos.direction)), fill: "none", viewBox: "0 0 24 24", stroke: "currentColor" },
react_1.default.createElement("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 14l-7 7m0 0l-7-7m7 7V3" })),
showUserInfo && (react_1.default.createElement("div", { className: "absolute left-full ml-2 ".concat(isAdmin ? 'bg-red-500' : 'bg-indigo-500', " text-white px-2 py-1 rounded text-sm whitespace-nowrap") }, isAdmin ? 'Admin' : "User ".concat(user.userId.slice(0, 6))))));
}
return (react_1.default.createElement("div", { key: user.userId, className: "absolute transform -translate-x-1/2 -translate-y-1/2", style: {
left: user.cursor.x,
top: user.cursor.y,
} },
react_1.default.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: "transform -rotate-45" },
react_1.default.createElement("path", { d: "M1 1L7.5 15L9.5 9L15 7.5L1 1Z", fill: isAdmin ? "#DC2626" : "#4F46E5", stroke: isAdmin ? "#991B1B" : "#312E81", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })),
showUserInfo && (react_1.default.createElement("div", { className: "absolute left-4 top-4 px-2 py-1 ".concat(isAdmin ? 'bg-red-600' : 'bg-indigo-600', " text-white text-xs rounded whitespace-nowrap") }, isAdmin ? 'Admin' : "User ".concat(user.userId.slice(0, 6))))));
})));
};
exports.CursorOverlay = CursorOverlay;
// Helper functions
function isCursorVisible(cursor, windowHeight, windowWidth) {
var buffer = 20;
var scrollX = window.scrollX;
var scrollY = window.scrollY;
return (cursor.x >= scrollX + buffer &&
cursor.x <= scrollX + windowWidth - buffer &&
cursor.y >= scrollY + buffer &&
cursor.y <= scrollY + windowHeight - buffer);
}
function getArrowPosition(cursor, windowHeight, windowWidth) {
var buffer = 20;
var scrollX = window.scrollX;
var scrollY = window.scrollY;
var position = {
x: cursor.x,
y: cursor.y,
direction: 'bottom'
};
if (cursor.y < scrollY + buffer) {
position.y = scrollY + buffer;
position.direction = 'top';
}
else if (cursor.y > scrollY + windowHeight - buffer) {
position.y = scrollY + windowHeight - buffer;
position.direction = 'bottom';
}
if (cursor.x < scrollX + buffer) {
position.x = scrollX + buffer;
position.direction = 'left';
}
else if (cursor.x > scrollX + windowWidth - buffer) {
position.x = scrollX + windowWidth - buffer;
position.direction = 'right';
}
return {
x: position.x - scrollX,
y: position.y - scrollY,
direction: position.direction
};
}
function getArrowRotation(direction) {
switch (direction) {
case 'top': return 'rotate-180';
case 'left': return 'rotate-90';
case 'right': return '-rotate-90';
default: return '';
}
}
;