circuit-bricks
Version:
A modular, Lego-style SVG circuit component system for React (ALPHA - Not for production use)
391 lines (388 loc) • 9.42 kB
JavaScript
"use client";
;
//#region rolldown:runtime
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all) __defProp(target, name, {
get: all[name],
enumerable: true
});
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
const react = __toESM(require("react"));
//#region src/utils/ssrUtils.ts
/**
* Check if code is running in a browser environment
*/
const isBrowser = () => {
return typeof window !== "undefined" && typeof document !== "undefined";
};
/**
* Check if code is running on the server
*/
const isServer = () => {
return !isBrowser();
};
/**
* Safe access to window object
*/
const safeWindow = () => {
return isBrowser() ? window : null;
};
/**
* Safe access to document object
*/
const safeDocument = () => {
return isBrowser() ? document : null;
};
/**
* Hook to detect when component has hydrated on the client
* This prevents hydration mismatches by ensuring client-only code
* only runs after hydration is complete.
*/
const useIsClient = () => {
const [isClient, setIsClient] = (0, react.useState)(false);
(0, react.useEffect)(() => {
setIsClient(true);
}, []);
return isClient;
};
/**
* Hook to safely access browser APIs after hydration
* Returns null during SSR and initial render, then the actual value after hydration
*/
const useSafeBrowserAPI = (getBrowserValue, fallbackValue = null) => {
const isClient = useIsClient();
const [value, setValue] = (0, react.useState)(fallbackValue);
(0, react.useEffect)(() => {
if (isClient) try {
setValue(getBrowserValue());
} catch (error) {
console.warn("Error accessing browser API:", error);
setValue(fallbackValue);
}
}, [
isClient,
getBrowserValue,
fallbackValue
]);
return isClient ? value : fallbackValue;
};
/**
* SSR-safe localStorage access
*/
const safeLocalStorage = {
getItem: (key) => {
if (!isBrowser()) return null;
try {
return localStorage.getItem(key);
} catch (error) {
console.warn("Error accessing localStorage:", error);
return null;
}
},
setItem: (key, value) => {
if (!isBrowser()) return false;
try {
localStorage.setItem(key, value);
return true;
} catch (error) {
console.warn("Error setting localStorage:", error);
return false;
}
},
removeItem: (key) => {
if (!isBrowser()) return false;
try {
localStorage.removeItem(key);
return true;
} catch (error) {
console.warn("Error removing from localStorage:", error);
return false;
}
}
};
/**
* SSR-safe sessionStorage access
*/
const safeSessionStorage = {
getItem: (key) => {
if (!isBrowser()) return null;
try {
return sessionStorage.getItem(key);
} catch (error) {
console.warn("Error accessing sessionStorage:", error);
return null;
}
},
setItem: (key, value) => {
if (!isBrowser()) return false;
try {
sessionStorage.setItem(key, value);
return true;
} catch (error) {
console.warn("Error setting sessionStorage:", error);
return false;
}
},
removeItem: (key) => {
if (!isBrowser()) return false;
try {
sessionStorage.removeItem(key);
return true;
} catch (error) {
console.warn("Error removing from sessionStorage:", error);
return false;
}
}
};
/**
* SSR-safe DOM query selector
*/
const safeQuerySelector = (selector) => {
if (!isBrowser()) return null;
try {
return document.querySelector(selector);
} catch (error) {
console.warn("Error querying DOM:", error);
return null;
}
};
/**
* SSR-safe DOM query selector all
*/
const safeQuerySelectorAll = (selector) => {
if (!isBrowser()) return null;
try {
return document.querySelectorAll(selector);
} catch (error) {
console.warn("Error querying DOM:", error);
return null;
}
};
/**
* SSR-safe event listener management
*/
const safeEventListener = {
add: (element, event, handler, options) => {
if (!isBrowser() || !element) return false;
try {
element.addEventListener(event, handler, options);
return true;
} catch (error) {
console.warn("Error adding event listener:", error);
return false;
}
},
remove: (element, event, handler, options) => {
if (!isBrowser() || !element) return false;
try {
element.removeEventListener(event, handler, options);
return true;
} catch (error) {
console.warn("Error removing event listener:", error);
return false;
}
}
};
/**
* SSR-safe viewport dimensions
*/
const useViewportDimensions = () => {
const [dimensions, setDimensions] = (0, react.useState)({
width: 1024,
height: 768
});
(0, react.useEffect)(() => {
if (!isBrowser()) return;
const updateDimensions = () => {
setDimensions({
width: window.innerWidth,
height: window.innerHeight
});
};
updateDimensions();
window.addEventListener("resize", updateDimensions);
return () => {
window.removeEventListener("resize", updateDimensions);
};
}, []);
return dimensions;
};
/**
* SSR-safe media query hook
*/
const useMediaQuery = (query) => {
const [matches, setMatches] = (0, react.useState)(false);
(0, react.useEffect)(() => {
if (!isBrowser()) return;
const mediaQuery = window.matchMedia(query);
setMatches(mediaQuery.matches);
const handler = (event) => {
setMatches(event.matches);
};
mediaQuery.addEventListener("change", handler);
return () => {
mediaQuery.removeEventListener("change", handler);
};
}, [query]);
return matches;
};
/**
* SSR-safe user agent detection
*/
const useUserAgent = () => {
const [userAgent, setUserAgent] = (0, react.useState)("");
(0, react.useEffect)(() => {
if (isBrowser()) setUserAgent(navigator.userAgent);
}, []);
return userAgent;
};
/**
* Detect mobile devices
*/
const useIsMobile = () => {
const userAgent = useUserAgent();
const isSmallScreen = useMediaQuery("(max-width: 768px)");
const isMobileUA = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent);
return isMobileUA || isSmallScreen;
};
/**
* Detect touch support
*/
const useHasTouchSupport = () => {
const [hasTouch, setHasTouch] = (0, react.useState)(false);
(0, react.useEffect)(() => {
if (isBrowser()) setHasTouch("ontouchstart" in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0);
}, []);
return hasTouch;
};
//#endregion
Object.defineProperty(exports, '__export', {
enumerable: true,
get: function () {
return __export;
}
});
Object.defineProperty(exports, '__toESM', {
enumerable: true,
get: function () {
return __toESM;
}
});
Object.defineProperty(exports, 'isBrowser', {
enumerable: true,
get: function () {
return isBrowser;
}
});
Object.defineProperty(exports, 'isServer', {
enumerable: true,
get: function () {
return isServer;
}
});
Object.defineProperty(exports, 'safeDocument', {
enumerable: true,
get: function () {
return safeDocument;
}
});
Object.defineProperty(exports, 'safeEventListener', {
enumerable: true,
get: function () {
return safeEventListener;
}
});
Object.defineProperty(exports, 'safeLocalStorage', {
enumerable: true,
get: function () {
return safeLocalStorage;
}
});
Object.defineProperty(exports, 'safeQuerySelector', {
enumerable: true,
get: function () {
return safeQuerySelector;
}
});
Object.defineProperty(exports, 'safeQuerySelectorAll', {
enumerable: true,
get: function () {
return safeQuerySelectorAll;
}
});
Object.defineProperty(exports, 'safeSessionStorage', {
enumerable: true,
get: function () {
return safeSessionStorage;
}
});
Object.defineProperty(exports, 'safeWindow', {
enumerable: true,
get: function () {
return safeWindow;
}
});
Object.defineProperty(exports, 'useHasTouchSupport', {
enumerable: true,
get: function () {
return useHasTouchSupport;
}
});
Object.defineProperty(exports, 'useIsClient', {
enumerable: true,
get: function () {
return useIsClient;
}
});
Object.defineProperty(exports, 'useIsMobile', {
enumerable: true,
get: function () {
return useIsMobile;
}
});
Object.defineProperty(exports, 'useMediaQuery', {
enumerable: true,
get: function () {
return useMediaQuery;
}
});
Object.defineProperty(exports, 'useSafeBrowserAPI', {
enumerable: true,
get: function () {
return useSafeBrowserAPI;
}
});
Object.defineProperty(exports, 'useUserAgent', {
enumerable: true,
get: function () {
return useUserAgent;
}
});
Object.defineProperty(exports, 'useViewportDimensions', {
enumerable: true,
get: function () {
return useViewportDimensions;
}
});
//# sourceMappingURL=ssrUtils-LzC8HZ8m.cjs.map