UNPKG

enviroment-adviser

Version:

A permanent toast that notifies you that you are not in production

114 lines (113 loc) 4.41 kB
const css = ` #environment-adviser { background-color: #ff0000; color: white; padding: 10px 20px; border-radius: 5px; font-family: sans-serif; font-weight: bold; cursor: pointer; z-index: 9999; } `; function addStyles() { const styleSheet = document.createElement('style'); styleSheet.type = 'text/css'; styleSheet.innerText = css; document.head.appendChild(styleSheet); } export function showEnvironmentAdviser(options) { if (process.env.NODE_ENV === 'production') { return; } const scale = options?.scale ?? 1; const opacity = options?.opacity ?? 1; const animation = options?.animation ?? 'none'; const speedMultiplier = options?.transitionSpeed ?? 1; const duration = 1 / speedMultiplier; const adviser = document.createElement('div'); adviser.id = 'environment-adviser'; adviser.textContent = `ENVIRONMENT: ${process.env.NODE_ENV}`; adviser.style.position = 'fixed'; adviser.style.backgroundColor = '#ff0000'; adviser.style.color = 'white'; adviser.style.padding = `${0.625 * scale}rem ${1.25 * scale}rem`; adviser.style.borderRadius = `${0.3125 * scale}rem`; adviser.style.fontFamily = 'sans-serif'; adviser.style.fontWeight = 'bold'; adviser.style.fontSize = `${1 * scale}rem`; adviser.style.cursor = 'pointer'; adviser.style.zIndex = '9999'; adviser.style.opacity = opacity.toString(); const styleSheet = document.createElement('style'); styleSheet.innerHTML = ` @keyframes adviser-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } .adviser-spin { animation: adviser-spin ${duration}s linear; } @keyframes adviser-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.2); } } .adviser-pulse { animation: adviser-pulse ${duration}s ease-in-out; } `; document.head.appendChild(styleSheet); document.body.appendChild(adviser); const corners = ['top-right', 'bottom-right', 'bottom-left', 'top-left']; let currentCornerIndex = 0; let isMoving = false; const setPosition = (cornerName) => { const offsetRem = 1.25 * scale; const { offsetHeight: elHeight, offsetWidth: elWidth } = adviser; adviser.style.right = ''; adviser.style.bottom = ''; adviser.style.top = ''; adviser.style.left = ''; switch (cornerName) { case 'top-right': adviser.style.top = `${offsetRem}rem`; adviser.style.left = `calc(100vw - ${elWidth}px - ${offsetRem}rem)`; break; case 'bottom-right': adviser.style.top = `calc(100vh - ${elHeight}px - ${offsetRem}rem)`; adviser.style.left = `calc(100vw - ${elWidth}px - ${offsetRem}rem)`; break; case 'bottom-left': adviser.style.top = `calc(100vh - ${elHeight}px - ${offsetRem}rem)`; adviser.style.left = `${offsetRem}rem`; break; case 'top-left': adviser.style.top = `${offsetRem}rem`; adviser.style.left = `${offsetRem}rem`; break; } }; const moveAdviser = () => { if (isMoving) return; isMoving = true; currentCornerIndex = (currentCornerIndex + 1) % corners.length; const nextCorner = corners[currentCornerIndex]; if (animation === 'slide') { adviser.style.transition = `top ${duration}s linear, left ${duration}s linear`; } else { adviser.style.transition = `all ${duration}s ease-in-out`; } if (animation === 'spin' || animation === 'pulse') { adviser.classList.add(`adviser-${animation}`); } setPosition(nextCorner); setTimeout(() => { isMoving = false; if (animation === 'spin' || animation === 'pulse') { adviser.classList.remove(`adviser-${animation}`); } }, duration * 1000); }; setTimeout(() => { adviser.style.transition = 'none'; setPosition(corners[currentCornerIndex]); }, 50); window.addEventListener('resize', () => { adviser.style.transition = 'none'; setPosition(corners[currentCornerIndex]); }); adviser.addEventListener('mouseenter', moveAdviser); adviser.addEventListener('click', moveAdviser); }