Vollständiges Redesign mit Gold-Formularen, BMP-Logo, multi-step Forms (Bewerbung, Kontakt, Sponsoring), Netlify-Deployment. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1144 lines
32 KiB
JavaScript
1144 lines
32 KiB
JavaScript
import {
|
|
require_react
|
|
} from "./chunk-NKU67ILE.js";
|
|
import {
|
|
__toESM
|
|
} from "./chunk-PR4QN5HX.js";
|
|
|
|
// node_modules/@uidotdev/usehooks/index.js
|
|
var React = __toESM(require_react());
|
|
function isShallowEqual(object1, object2) {
|
|
const keys1 = Object.keys(object1);
|
|
const keys2 = Object.keys(object2);
|
|
if (keys1.length !== keys2.length) {
|
|
return false;
|
|
}
|
|
for (let key of keys1) {
|
|
if (object1[key] !== object2[key]) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
function isTouchEvent({ nativeEvent }) {
|
|
return window.TouchEvent ? nativeEvent instanceof TouchEvent : "touches" in nativeEvent;
|
|
}
|
|
function isMouseEvent(event) {
|
|
return event.nativeEvent instanceof MouseEvent;
|
|
}
|
|
function throttle(cb, ms) {
|
|
let lastTime = 0;
|
|
return () => {
|
|
const now = Date.now();
|
|
if (now - lastTime >= ms) {
|
|
cb();
|
|
lastTime = now;
|
|
}
|
|
};
|
|
}
|
|
function isPlainObject(value) {
|
|
return Object.prototype.toString.call(value) === "[object Object]";
|
|
}
|
|
function dispatchStorageEvent(key, newValue) {
|
|
window.dispatchEvent(new StorageEvent("storage", { key, newValue }));
|
|
}
|
|
function useBattery() {
|
|
const [state, setState] = React.useState({
|
|
supported: true,
|
|
loading: true,
|
|
level: null,
|
|
charging: null,
|
|
chargingTime: null,
|
|
dischargingTime: null
|
|
});
|
|
React.useEffect(() => {
|
|
if (!navigator.getBattery) {
|
|
setState((s) => ({
|
|
...s,
|
|
supported: false,
|
|
loading: false
|
|
}));
|
|
return;
|
|
}
|
|
let battery = null;
|
|
const handleChange = () => {
|
|
setState({
|
|
supported: true,
|
|
loading: false,
|
|
level: battery.level,
|
|
charging: battery.charging,
|
|
chargingTime: battery.chargingTime,
|
|
dischargingTime: battery.dischargingTime
|
|
});
|
|
};
|
|
navigator.getBattery().then((b) => {
|
|
battery = b;
|
|
handleChange();
|
|
b.addEventListener("levelchange", handleChange);
|
|
b.addEventListener("chargingchange", handleChange);
|
|
b.addEventListener("chargingtimechange", handleChange);
|
|
b.addEventListener("dischargingtimechange", handleChange);
|
|
});
|
|
return () => {
|
|
if (battery) {
|
|
battery.removeEventListener("levelchange", handleChange);
|
|
battery.removeEventListener("chargingchange", handleChange);
|
|
battery.removeEventListener("chargingtimechange", handleChange);
|
|
battery.removeEventListener("dischargingtimechange", handleChange);
|
|
}
|
|
};
|
|
}, []);
|
|
return state;
|
|
}
|
|
function useClickAway(cb) {
|
|
const ref = React.useRef(null);
|
|
const refCb = React.useRef(cb);
|
|
React.useLayoutEffect(() => {
|
|
refCb.current = cb;
|
|
});
|
|
React.useEffect(() => {
|
|
const handler = (e) => {
|
|
const element = ref.current;
|
|
if (element && !element.contains(e.target)) {
|
|
refCb.current(e);
|
|
}
|
|
};
|
|
document.addEventListener("mousedown", handler);
|
|
document.addEventListener("touchstart", handler);
|
|
return () => {
|
|
document.removeEventListener("mousedown", handler);
|
|
document.removeEventListener("touchstart", handler);
|
|
};
|
|
}, []);
|
|
return ref;
|
|
}
|
|
function oldSchoolCopy(text) {
|
|
const tempTextArea = document.createElement("textarea");
|
|
tempTextArea.value = text;
|
|
document.body.appendChild(tempTextArea);
|
|
tempTextArea.select();
|
|
document.execCommand("copy");
|
|
document.body.removeChild(tempTextArea);
|
|
}
|
|
function useCopyToClipboard() {
|
|
const [state, setState] = React.useState(null);
|
|
const copyToClipboard = React.useCallback((value) => {
|
|
const handleCopy = async () => {
|
|
var _a;
|
|
try {
|
|
if ((_a = navigator == null ? void 0 : navigator.clipboard) == null ? void 0 : _a.writeText) {
|
|
await navigator.clipboard.writeText(value);
|
|
setState(value);
|
|
} else {
|
|
throw new Error("writeText not supported");
|
|
}
|
|
} catch (e) {
|
|
oldSchoolCopy(value);
|
|
setState(value);
|
|
}
|
|
};
|
|
handleCopy();
|
|
}, []);
|
|
return [state, copyToClipboard];
|
|
}
|
|
function useCounter(startingValue = 0, options = {}) {
|
|
const { min, max } = options;
|
|
if (typeof min === "number" && startingValue < min) {
|
|
throw new Error(
|
|
`Your starting value of ${startingValue} is less than your min of ${min}.`
|
|
);
|
|
}
|
|
if (typeof max === "number" && startingValue > max) {
|
|
throw new Error(
|
|
`Your starting value of ${startingValue} is greater than your max of ${max}.`
|
|
);
|
|
}
|
|
const [count, setCount] = React.useState(startingValue);
|
|
const increment = React.useCallback(() => {
|
|
setCount((c) => {
|
|
const nextCount = c + 1;
|
|
if (typeof max === "number" && nextCount > max) {
|
|
return c;
|
|
}
|
|
return nextCount;
|
|
});
|
|
}, [max]);
|
|
const decrement = React.useCallback(() => {
|
|
setCount((c) => {
|
|
const nextCount = c - 1;
|
|
if (typeof min === "number" && nextCount < min) {
|
|
return c;
|
|
}
|
|
return nextCount;
|
|
});
|
|
}, [min]);
|
|
const set = React.useCallback(
|
|
(nextCount) => {
|
|
setCount((c) => {
|
|
if (typeof max === "number" && nextCount > max) {
|
|
return c;
|
|
}
|
|
if (typeof min === "number" && nextCount < min) {
|
|
return c;
|
|
}
|
|
return nextCount;
|
|
});
|
|
},
|
|
[max, min]
|
|
);
|
|
const reset = React.useCallback(() => {
|
|
setCount(startingValue);
|
|
}, [startingValue]);
|
|
return [
|
|
count,
|
|
{
|
|
increment,
|
|
decrement,
|
|
set,
|
|
reset
|
|
}
|
|
];
|
|
}
|
|
function useDebounce(value, delay) {
|
|
const [debouncedValue, setDebouncedValue] = React.useState(value);
|
|
React.useEffect(() => {
|
|
const handler = setTimeout(() => {
|
|
setDebouncedValue(value);
|
|
}, delay);
|
|
return () => {
|
|
clearTimeout(handler);
|
|
};
|
|
}, [value, delay]);
|
|
return debouncedValue;
|
|
}
|
|
function useDefault(initialValue, defaultValue) {
|
|
const [state, setState] = React.useState(initialValue);
|
|
if (typeof state === "undefined" || state === null) {
|
|
return [defaultValue, setState];
|
|
}
|
|
return [state, setState];
|
|
}
|
|
function useDocumentTitle(title) {
|
|
React.useEffect(() => {
|
|
document.title = title;
|
|
}, [title]);
|
|
}
|
|
function useFavicon(url) {
|
|
React.useEffect(() => {
|
|
let link = document.querySelector(`link[rel~="icon"]`);
|
|
if (!link) {
|
|
link = document.createElement("link");
|
|
link.type = "image/x-icon";
|
|
link.rel = "icon";
|
|
link.href = url;
|
|
document.head.appendChild(link);
|
|
} else {
|
|
link.href = url;
|
|
}
|
|
}, [url]);
|
|
}
|
|
function useGeolocation(options = {}) {
|
|
const [state, setState] = React.useState({
|
|
loading: true,
|
|
accuracy: null,
|
|
altitude: null,
|
|
altitudeAccuracy: null,
|
|
heading: null,
|
|
latitude: null,
|
|
longitude: null,
|
|
speed: null,
|
|
timestamp: null,
|
|
error: null
|
|
});
|
|
const optionsRef = React.useRef(options);
|
|
React.useEffect(() => {
|
|
const onEvent = ({ coords, timestamp }) => {
|
|
setState({
|
|
loading: false,
|
|
timestamp,
|
|
latitude: coords.latitude,
|
|
longitude: coords.longitude,
|
|
altitude: coords.altitude,
|
|
accuracy: coords.accuracy,
|
|
altitudeAccuracy: coords.altitudeAccuracy,
|
|
heading: coords.heading,
|
|
speed: coords.speed
|
|
});
|
|
};
|
|
const onEventError = (error) => {
|
|
setState((s) => ({
|
|
...s,
|
|
loading: false,
|
|
error
|
|
}));
|
|
};
|
|
navigator.geolocation.getCurrentPosition(
|
|
onEvent,
|
|
onEventError,
|
|
optionsRef.current
|
|
);
|
|
const watchId = navigator.geolocation.watchPosition(
|
|
onEvent,
|
|
onEventError,
|
|
optionsRef.current
|
|
);
|
|
return () => {
|
|
navigator.geolocation.clearWatch(watchId);
|
|
};
|
|
}, []);
|
|
return state;
|
|
}
|
|
var initialUseHistoryStateState = {
|
|
past: [],
|
|
present: null,
|
|
future: []
|
|
};
|
|
var useHistoryStateReducer = (state, action) => {
|
|
const { past, present, future } = state;
|
|
if (action.type === "UNDO") {
|
|
return {
|
|
past: past.slice(0, past.length - 1),
|
|
present: past[past.length - 1],
|
|
future: [present, ...future]
|
|
};
|
|
} else if (action.type === "REDO") {
|
|
return {
|
|
past: [...past, present],
|
|
present: future[0],
|
|
future: future.slice(1)
|
|
};
|
|
} else if (action.type === "SET") {
|
|
const { newPresent } = action;
|
|
if (action.newPresent === present) {
|
|
return state;
|
|
}
|
|
return {
|
|
past: [...past, present],
|
|
present: newPresent,
|
|
future: []
|
|
};
|
|
} else if (action.type === "CLEAR") {
|
|
return {
|
|
...initialUseHistoryStateState,
|
|
present: action.initialPresent
|
|
};
|
|
} else {
|
|
throw new Error("Unsupported action type");
|
|
}
|
|
};
|
|
function useHistoryState(initialPresent = {}) {
|
|
const initialPresentRef = React.useRef(initialPresent);
|
|
const [state, dispatch] = React.useReducer(useHistoryStateReducer, {
|
|
...initialUseHistoryStateState,
|
|
present: initialPresentRef.current
|
|
});
|
|
const canUndo = state.past.length !== 0;
|
|
const canRedo = state.future.length !== 0;
|
|
const undo = React.useCallback(() => {
|
|
if (canUndo) {
|
|
dispatch({ type: "UNDO" });
|
|
}
|
|
}, [canUndo]);
|
|
const redo = React.useCallback(() => {
|
|
if (canRedo) {
|
|
dispatch({ type: "REDO" });
|
|
}
|
|
}, [canRedo]);
|
|
const set = React.useCallback(
|
|
(newPresent) => dispatch({ type: "SET", newPresent }),
|
|
[]
|
|
);
|
|
const clear = React.useCallback(
|
|
() => dispatch({ type: "CLEAR", initialPresent: initialPresentRef.current }),
|
|
[]
|
|
);
|
|
return { state: state.present, set, undo, redo, clear, canUndo, canRedo };
|
|
}
|
|
function useHover() {
|
|
const [hovering, setHovering] = React.useState(false);
|
|
const previousNode = React.useRef(null);
|
|
const handleMouseEnter = React.useCallback(() => {
|
|
setHovering(true);
|
|
}, []);
|
|
const handleMouseLeave = React.useCallback(() => {
|
|
setHovering(false);
|
|
}, []);
|
|
const customRef = React.useCallback(
|
|
(node) => {
|
|
var _a;
|
|
if (((_a = previousNode.current) == null ? void 0 : _a.nodeType) === Node.ELEMENT_NODE) {
|
|
previousNode.current.removeEventListener(
|
|
"mouseenter",
|
|
handleMouseEnter
|
|
);
|
|
previousNode.current.removeEventListener(
|
|
"mouseleave",
|
|
handleMouseLeave
|
|
);
|
|
}
|
|
if ((node == null ? void 0 : node.nodeType) === Node.ELEMENT_NODE) {
|
|
node.addEventListener("mouseenter", handleMouseEnter);
|
|
node.addEventListener("mouseleave", handleMouseLeave);
|
|
}
|
|
previousNode.current = node;
|
|
},
|
|
[handleMouseEnter, handleMouseLeave]
|
|
);
|
|
return [customRef, hovering];
|
|
}
|
|
function useIdle(ms = 1e3 * 60) {
|
|
const [idle, setIdle] = React.useState(false);
|
|
React.useEffect(() => {
|
|
let timeoutId;
|
|
const handleTimeout = () => {
|
|
setIdle(true);
|
|
};
|
|
const handleEvent = throttle((e) => {
|
|
setIdle(false);
|
|
window.clearTimeout(timeoutId);
|
|
timeoutId = window.setTimeout(handleTimeout, ms);
|
|
}, 500);
|
|
const handleVisibilityChange = () => {
|
|
if (!document.hidden) {
|
|
handleEvent();
|
|
}
|
|
};
|
|
timeoutId = window.setTimeout(handleTimeout, ms);
|
|
window.addEventListener("mousemove", handleEvent);
|
|
window.addEventListener("mousedown", handleEvent);
|
|
window.addEventListener("resize", handleEvent);
|
|
window.addEventListener("keydown", handleEvent);
|
|
window.addEventListener("touchstart", handleEvent);
|
|
window.addEventListener("wheel", handleEvent);
|
|
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
return () => {
|
|
window.removeEventListener("mousemove", handleEvent);
|
|
window.removeEventListener("mousedown", handleEvent);
|
|
window.removeEventListener("resize", handleEvent);
|
|
window.removeEventListener("keydown", handleEvent);
|
|
window.removeEventListener("touchstart", handleEvent);
|
|
window.removeEventListener("wheel", handleEvent);
|
|
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
window.clearTimeout(timeoutId);
|
|
};
|
|
}, [ms]);
|
|
return idle;
|
|
}
|
|
function useIntersectionObserver(options = {}) {
|
|
const { threshold = 1, root = null, rootMargin = "0px" } = options;
|
|
const [entry, setEntry] = React.useState(null);
|
|
const previousObserver = React.useRef(null);
|
|
const customRef = React.useCallback(
|
|
(node) => {
|
|
if (previousObserver.current) {
|
|
previousObserver.current.disconnect();
|
|
previousObserver.current = null;
|
|
}
|
|
if ((node == null ? void 0 : node.nodeType) === Node.ELEMENT_NODE) {
|
|
const observer = new IntersectionObserver(
|
|
([entry2]) => {
|
|
setEntry(entry2);
|
|
},
|
|
{ threshold, root, rootMargin }
|
|
);
|
|
observer.observe(node);
|
|
previousObserver.current = observer;
|
|
}
|
|
},
|
|
[threshold, root, rootMargin]
|
|
);
|
|
return [customRef, entry];
|
|
}
|
|
function useIsClient() {
|
|
const [isClient, setIsClient] = React.useState(false);
|
|
React.useEffect(() => {
|
|
setIsClient(true);
|
|
}, []);
|
|
return isClient;
|
|
}
|
|
function useIsFirstRender() {
|
|
const renderRef = React.useRef(true);
|
|
if (renderRef.current === true) {
|
|
renderRef.current = false;
|
|
return true;
|
|
}
|
|
return renderRef.current;
|
|
}
|
|
function useList(defaultList = []) {
|
|
const [list, setList] = React.useState(defaultList);
|
|
const set = React.useCallback((l) => {
|
|
setList(l);
|
|
}, []);
|
|
const push = React.useCallback((element) => {
|
|
setList((l) => [...l, element]);
|
|
}, []);
|
|
const removeAt = React.useCallback((index) => {
|
|
setList((l) => [...l.slice(0, index), ...l.slice(index + 1)]);
|
|
}, []);
|
|
const insertAt = React.useCallback((index, element) => {
|
|
setList((l) => [...l.slice(0, index), element, ...l.slice(index)]);
|
|
}, []);
|
|
const updateAt = React.useCallback((index, element) => {
|
|
setList((l) => l.map((e, i) => i === index ? element : e));
|
|
}, []);
|
|
const clear = React.useCallback(() => setList([]), []);
|
|
return [list, { set, push, removeAt, insertAt, updateAt, clear }];
|
|
}
|
|
var setLocalStorageItem = (key, value) => {
|
|
const stringifiedValue = JSON.stringify(value);
|
|
window.localStorage.setItem(key, stringifiedValue);
|
|
dispatchStorageEvent(key, stringifiedValue);
|
|
};
|
|
var removeLocalStorageItem = (key) => {
|
|
window.localStorage.removeItem(key);
|
|
dispatchStorageEvent(key, null);
|
|
};
|
|
var getLocalStorageItem = (key) => {
|
|
return window.localStorage.getItem(key);
|
|
};
|
|
var useLocalStorageSubscribe = (callback) => {
|
|
window.addEventListener("storage", callback);
|
|
return () => window.removeEventListener("storage", callback);
|
|
};
|
|
var getLocalStorageServerSnapshot = () => {
|
|
throw Error("useLocalStorage is a client-only hook");
|
|
};
|
|
function useLocalStorage(key, initialValue) {
|
|
const getSnapshot = () => getLocalStorageItem(key);
|
|
const store = React.useSyncExternalStore(
|
|
useLocalStorageSubscribe,
|
|
getSnapshot,
|
|
getLocalStorageServerSnapshot
|
|
);
|
|
const setState = React.useCallback(
|
|
(v) => {
|
|
try {
|
|
const nextState = typeof v === "function" ? v(JSON.parse(store)) : v;
|
|
if (nextState === void 0 || nextState === null) {
|
|
removeLocalStorageItem(key);
|
|
} else {
|
|
setLocalStorageItem(key, nextState);
|
|
}
|
|
} catch (e) {
|
|
console.warn(e);
|
|
}
|
|
},
|
|
[key, store]
|
|
);
|
|
React.useEffect(() => {
|
|
if (getLocalStorageItem(key) === null && typeof initialValue !== "undefined") {
|
|
setLocalStorageItem(key, initialValue);
|
|
}
|
|
}, [key, initialValue]);
|
|
return [store ? JSON.parse(store) : initialValue, setState];
|
|
}
|
|
function useLockBodyScroll() {
|
|
React.useLayoutEffect(() => {
|
|
const originalStyle = window.getComputedStyle(document.body).overflow;
|
|
document.body.style.overflow = "hidden";
|
|
return () => {
|
|
document.body.style.overflow = originalStyle;
|
|
};
|
|
}, []);
|
|
}
|
|
function useLongPress(callback, options = {}) {
|
|
const { threshold = 400, onStart, onFinish, onCancel } = options;
|
|
const isLongPressActive = React.useRef(false);
|
|
const isPressed = React.useRef(false);
|
|
const timerId = React.useRef();
|
|
return React.useMemo(() => {
|
|
if (typeof callback !== "function") {
|
|
return {};
|
|
}
|
|
const start = (event) => {
|
|
if (!isMouseEvent(event) && !isTouchEvent(event)) return;
|
|
if (onStart) {
|
|
onStart(event);
|
|
}
|
|
isPressed.current = true;
|
|
timerId.current = setTimeout(() => {
|
|
callback(event);
|
|
isLongPressActive.current = true;
|
|
}, threshold);
|
|
};
|
|
const cancel = (event) => {
|
|
if (!isMouseEvent(event) && !isTouchEvent(event)) return;
|
|
if (isLongPressActive.current) {
|
|
if (onFinish) {
|
|
onFinish(event);
|
|
}
|
|
} else if (isPressed.current) {
|
|
if (onCancel) {
|
|
onCancel(event);
|
|
}
|
|
}
|
|
isLongPressActive.current = false;
|
|
isPressed.current = false;
|
|
if (timerId.current) {
|
|
window.clearTimeout(timerId.current);
|
|
}
|
|
};
|
|
const mouseHandlers = {
|
|
onMouseDown: start,
|
|
onMouseUp: cancel,
|
|
onMouseLeave: cancel
|
|
};
|
|
const touchHandlers = {
|
|
onTouchStart: start,
|
|
onTouchEnd: cancel
|
|
};
|
|
return {
|
|
...mouseHandlers,
|
|
...touchHandlers
|
|
};
|
|
}, [callback, threshold, onCancel, onFinish, onStart]);
|
|
}
|
|
function useMap(initialState) {
|
|
const mapRef = React.useRef(new Map(initialState));
|
|
const [, reRender] = React.useReducer((x) => x + 1, 0);
|
|
mapRef.current.set = (...args) => {
|
|
Map.prototype.set.apply(mapRef.current, args);
|
|
reRender();
|
|
return mapRef.current;
|
|
};
|
|
mapRef.current.clear = (...args) => {
|
|
Map.prototype.clear.apply(mapRef.current, args);
|
|
reRender();
|
|
};
|
|
mapRef.current.delete = (...args) => {
|
|
const res = Map.prototype.delete.apply(mapRef.current, args);
|
|
reRender();
|
|
return res;
|
|
};
|
|
return mapRef.current;
|
|
}
|
|
function useMeasure() {
|
|
const [dimensions, setDimensions] = React.useState({
|
|
width: null,
|
|
height: null
|
|
});
|
|
const previousObserver = React.useRef(null);
|
|
const customRef = React.useCallback((node) => {
|
|
if (previousObserver.current) {
|
|
previousObserver.current.disconnect();
|
|
previousObserver.current = null;
|
|
}
|
|
if ((node == null ? void 0 : node.nodeType) === Node.ELEMENT_NODE) {
|
|
const observer = new ResizeObserver(([entry]) => {
|
|
if (entry && entry.borderBoxSize) {
|
|
const { inlineSize: width, blockSize: height } = entry.borderBoxSize[0];
|
|
setDimensions({ width, height });
|
|
}
|
|
});
|
|
observer.observe(node);
|
|
previousObserver.current = observer;
|
|
}
|
|
}, []);
|
|
return [customRef, dimensions];
|
|
}
|
|
function useMediaQuery(query) {
|
|
const subscribe = React.useCallback(
|
|
(callback) => {
|
|
const matchMedia = window.matchMedia(query);
|
|
matchMedia.addEventListener("change", callback);
|
|
return () => {
|
|
matchMedia.removeEventListener("change", callback);
|
|
};
|
|
},
|
|
[query]
|
|
);
|
|
const getSnapshot = () => {
|
|
return window.matchMedia(query).matches;
|
|
};
|
|
const getServerSnapshot = () => {
|
|
throw Error("useMediaQuery is a client-only hook");
|
|
};
|
|
return React.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
}
|
|
function useMouse() {
|
|
const [state, setState] = React.useState({
|
|
x: 0,
|
|
y: 0,
|
|
elementX: 0,
|
|
elementY: 0,
|
|
elementPositionX: 0,
|
|
elementPositionY: 0
|
|
});
|
|
const ref = React.useRef(null);
|
|
React.useLayoutEffect(() => {
|
|
const handleMouseMove = (event) => {
|
|
var _a;
|
|
let newState = {
|
|
x: event.pageX,
|
|
y: event.pageY
|
|
};
|
|
if (((_a = ref.current) == null ? void 0 : _a.nodeType) === Node.ELEMENT_NODE) {
|
|
const { left, top } = ref.current.getBoundingClientRect();
|
|
const elementPositionX = left + window.scrollX;
|
|
const elementPositionY = top + window.scrollY;
|
|
const elementX = event.pageX - elementPositionX;
|
|
const elementY = event.pageY - elementPositionY;
|
|
newState.elementX = elementX;
|
|
newState.elementY = elementY;
|
|
newState.elementPositionX = elementPositionX;
|
|
newState.elementPositionY = elementPositionY;
|
|
}
|
|
setState((s) => {
|
|
return {
|
|
...s,
|
|
...newState
|
|
};
|
|
});
|
|
};
|
|
document.addEventListener("mousemove", handleMouseMove);
|
|
return () => {
|
|
document.removeEventListener("mousemove", handleMouseMove);
|
|
};
|
|
}, []);
|
|
return [state, ref];
|
|
}
|
|
var getConnection = () => {
|
|
return (navigator == null ? void 0 : navigator.connection) || (navigator == null ? void 0 : navigator.mozConnection) || (navigator == null ? void 0 : navigator.webkitConnection);
|
|
};
|
|
var useNetworkStateSubscribe = (callback) => {
|
|
window.addEventListener("online", callback, { passive: true });
|
|
window.addEventListener("offline", callback, { passive: true });
|
|
const connection = getConnection();
|
|
if (connection) {
|
|
connection.addEventListener("change", callback, { passive: true });
|
|
}
|
|
return () => {
|
|
window.removeEventListener("online", callback);
|
|
window.removeEventListener("offline", callback);
|
|
if (connection) {
|
|
connection.removeEventListener("change", callback);
|
|
}
|
|
};
|
|
};
|
|
var getNetworkStateServerSnapshot = () => {
|
|
throw Error("useNetworkState is a client-only hook");
|
|
};
|
|
function useNetworkState() {
|
|
const cache = React.useRef({});
|
|
const getSnapshot = () => {
|
|
const online = navigator.onLine;
|
|
const connection = getConnection();
|
|
const nextState = {
|
|
online,
|
|
downlink: connection == null ? void 0 : connection.downlink,
|
|
downlinkMax: connection == null ? void 0 : connection.downlinkMax,
|
|
effectiveType: connection == null ? void 0 : connection.effectiveType,
|
|
rtt: connection == null ? void 0 : connection.rtt,
|
|
saveData: connection == null ? void 0 : connection.saveData,
|
|
type: connection == null ? void 0 : connection.type
|
|
};
|
|
if (isShallowEqual(cache.current, nextState)) {
|
|
return cache.current;
|
|
} else {
|
|
cache.current = nextState;
|
|
return nextState;
|
|
}
|
|
};
|
|
return React.useSyncExternalStore(
|
|
useNetworkStateSubscribe,
|
|
getSnapshot,
|
|
getNetworkStateServerSnapshot
|
|
);
|
|
}
|
|
function useObjectState(initialValue) {
|
|
const [state, setState] = React.useState(initialValue);
|
|
const handleUpdate = React.useCallback((arg) => {
|
|
if (typeof arg === "function") {
|
|
setState((s) => {
|
|
const newState = arg(s);
|
|
if (isPlainObject(newState)) {
|
|
return {
|
|
...s,
|
|
...newState
|
|
};
|
|
}
|
|
});
|
|
}
|
|
if (isPlainObject(arg)) {
|
|
setState((s) => ({
|
|
...s,
|
|
...arg
|
|
}));
|
|
}
|
|
}, []);
|
|
return [state, handleUpdate];
|
|
}
|
|
function useOrientation() {
|
|
const [orientation, setOrientation] = React.useState({
|
|
angle: 0,
|
|
type: "landscape-primary"
|
|
});
|
|
React.useLayoutEffect(() => {
|
|
var _a;
|
|
const handleChange = () => {
|
|
const { angle, type } = window.screen.orientation;
|
|
setOrientation({
|
|
angle,
|
|
type
|
|
});
|
|
};
|
|
const handle_orientationchange = () => {
|
|
setOrientation({
|
|
type: "UNKNOWN",
|
|
angle: window.orientation
|
|
});
|
|
};
|
|
if ((_a = window.screen) == null ? void 0 : _a.orientation) {
|
|
handleChange();
|
|
window.screen.orientation.addEventListener("change", handleChange);
|
|
} else {
|
|
handle_orientationchange();
|
|
window.addEventListener("orientationchange", handle_orientationchange);
|
|
}
|
|
return () => {
|
|
var _a2;
|
|
if ((_a2 = window.screen) == null ? void 0 : _a2.orientation) {
|
|
window.screen.orientation.removeEventListener("change", handleChange);
|
|
} else {
|
|
window.removeEventListener(
|
|
"orientationchange",
|
|
handle_orientationchange
|
|
);
|
|
}
|
|
};
|
|
}, []);
|
|
return orientation;
|
|
}
|
|
var usePreferredLanguageSubscribe = (cb) => {
|
|
window.addEventListener("languagechange", cb);
|
|
return () => window.removeEventListener("languagechange", cb);
|
|
};
|
|
var getPreferredLanguageSnapshot = () => {
|
|
return navigator.language;
|
|
};
|
|
var getPreferredLanguageServerSnapshot = () => {
|
|
throw Error("usePreferredLanguage is a client-only hook");
|
|
};
|
|
function usePreferredLanguage() {
|
|
return React.useSyncExternalStore(
|
|
usePreferredLanguageSubscribe,
|
|
getPreferredLanguageSnapshot,
|
|
getPreferredLanguageServerSnapshot
|
|
);
|
|
}
|
|
function usePrevious(value) {
|
|
const [current, setCurrent] = React.useState(value);
|
|
const [previous, setPrevious] = React.useState(null);
|
|
if (value !== current) {
|
|
setPrevious(current);
|
|
setCurrent(value);
|
|
}
|
|
return previous;
|
|
}
|
|
function useQueue(initialValue = []) {
|
|
const [queue, setQueue] = React.useState(initialValue);
|
|
const add = React.useCallback((element) => {
|
|
setQueue((q) => [...q, element]);
|
|
}, []);
|
|
const remove = React.useCallback(() => {
|
|
let removedElement;
|
|
setQueue(([first, ...q]) => {
|
|
removedElement = first;
|
|
return q;
|
|
});
|
|
return removedElement;
|
|
}, []);
|
|
const clear = React.useCallback(() => {
|
|
setQueue([]);
|
|
}, []);
|
|
return {
|
|
add,
|
|
remove,
|
|
clear,
|
|
first: queue[0],
|
|
last: queue[queue.length - 1],
|
|
size: queue.length,
|
|
queue
|
|
};
|
|
}
|
|
function useRenderCount() {
|
|
const count = React.useRef(0);
|
|
count.current++;
|
|
return count.current;
|
|
}
|
|
function useRenderInfo(name = "Unknown") {
|
|
const count = React.useRef(0);
|
|
const lastRender = React.useRef();
|
|
const now = Date.now();
|
|
count.current++;
|
|
React.useEffect(() => {
|
|
lastRender.current = Date.now();
|
|
});
|
|
const sinceLastRender = lastRender.current ? now - lastRender.current : 0;
|
|
if (true) {
|
|
const info = {
|
|
name,
|
|
renders: count.current,
|
|
sinceLastRender,
|
|
timestamp: now
|
|
};
|
|
console.log(info);
|
|
return info;
|
|
}
|
|
}
|
|
function useScript(src, options = {}) {
|
|
const [status, setStatus] = React.useState("loading");
|
|
const optionsRef = React.useRef(options);
|
|
React.useEffect(() => {
|
|
let script = document.querySelector(`script[src="${src}"]`);
|
|
const domStatus = script == null ? void 0 : script.getAttribute("data-status");
|
|
if (domStatus) {
|
|
setStatus(domStatus);
|
|
return;
|
|
}
|
|
if (script === null) {
|
|
script = document.createElement("script");
|
|
script.src = src;
|
|
script.async = true;
|
|
script.setAttribute("data-status", "loading");
|
|
document.body.appendChild(script);
|
|
const handleScriptLoad = () => {
|
|
script.setAttribute("data-status", "ready");
|
|
setStatus("ready");
|
|
removeEventListeners();
|
|
};
|
|
const handleScriptError = () => {
|
|
script.setAttribute("data-status", "error");
|
|
setStatus("error");
|
|
removeEventListeners();
|
|
};
|
|
const removeEventListeners = () => {
|
|
script.removeEventListener("load", handleScriptLoad);
|
|
script.removeEventListener("error", handleScriptError);
|
|
};
|
|
script.addEventListener("load", handleScriptLoad);
|
|
script.addEventListener("error", handleScriptError);
|
|
const removeOnUnmount = optionsRef.current.removeOnUnmount;
|
|
return () => {
|
|
if (removeOnUnmount === true) {
|
|
script.remove();
|
|
removeEventListeners();
|
|
}
|
|
};
|
|
} else {
|
|
setStatus("unknown");
|
|
}
|
|
}, [src]);
|
|
return status;
|
|
}
|
|
var setSessionStorageItem = (key, value) => {
|
|
const stringifiedValue = JSON.stringify(value);
|
|
window.sessionStorage.setItem(key, stringifiedValue);
|
|
dispatchStorageEvent(key, stringifiedValue);
|
|
};
|
|
var removeSessionStorageItem = (key) => {
|
|
window.sessionStorage.removeItem(key);
|
|
dispatchStorageEvent(key, null);
|
|
};
|
|
var getSessionStorageItem = (key) => {
|
|
return window.sessionStorage.getItem(key);
|
|
};
|
|
var useSessionStorageSubscribe = (callback) => {
|
|
window.addEventListener("storage", callback);
|
|
return () => window.removeEventListener("storage", callback);
|
|
};
|
|
var getSessionStorageServerSnapshot = () => {
|
|
throw Error("useSessionStorage is a client-only hook");
|
|
};
|
|
function useSessionStorage(key, initialValue) {
|
|
const getSnapshot = () => getSessionStorageItem(key);
|
|
const store = React.useSyncExternalStore(
|
|
useSessionStorageSubscribe,
|
|
getSnapshot,
|
|
getSessionStorageServerSnapshot
|
|
);
|
|
const setState = React.useCallback(
|
|
(v) => {
|
|
try {
|
|
const nextState = typeof v === "function" ? v(JSON.parse(store)) : v;
|
|
if (nextState === void 0 || nextState === null) {
|
|
removeSessionStorageItem(key);
|
|
} else {
|
|
setSessionStorageItem(key, nextState);
|
|
}
|
|
} catch (e) {
|
|
console.warn(e);
|
|
}
|
|
},
|
|
[key, store]
|
|
);
|
|
React.useEffect(() => {
|
|
if (getSessionStorageItem(key) === null && typeof initialValue !== "undefined") {
|
|
setSessionStorageItem(key, initialValue);
|
|
}
|
|
}, [key, initialValue]);
|
|
return [store ? JSON.parse(store) : initialValue, setState];
|
|
}
|
|
function useSet(values) {
|
|
const setRef = React.useRef(new Set(values));
|
|
const [, reRender] = React.useReducer((x) => x + 1, 0);
|
|
setRef.current.add = (...args) => {
|
|
const res = Set.prototype.add.apply(setRef.current, args);
|
|
reRender();
|
|
return res;
|
|
};
|
|
setRef.current.clear = (...args) => {
|
|
Set.prototype.clear.apply(setRef.current, args);
|
|
reRender();
|
|
};
|
|
setRef.current.delete = (...args) => {
|
|
const res = Set.prototype.delete.apply(setRef.current, args);
|
|
reRender();
|
|
return res;
|
|
};
|
|
return setRef.current;
|
|
}
|
|
function useThrottle(value, interval = 500) {
|
|
const [throttledValue, setThrottledValue] = React.useState(value);
|
|
const lastUpdated = React.useRef(null);
|
|
React.useEffect(() => {
|
|
const now = Date.now();
|
|
if (lastUpdated.current && now >= lastUpdated.current + interval) {
|
|
lastUpdated.current = now;
|
|
setThrottledValue(value);
|
|
} else {
|
|
const id = window.setTimeout(() => {
|
|
lastUpdated.current = now;
|
|
setThrottledValue(value);
|
|
}, interval);
|
|
return () => window.clearTimeout(id);
|
|
}
|
|
}, [value, interval]);
|
|
return throttledValue;
|
|
}
|
|
function useToggle(initialValue) {
|
|
const [on, setOn] = React.useState(() => {
|
|
if (typeof initialValue === "boolean") {
|
|
return initialValue;
|
|
}
|
|
return Boolean(initialValue);
|
|
});
|
|
const handleToggle = React.useCallback((value) => {
|
|
if (typeof value === "boolean") {
|
|
return setOn(value);
|
|
}
|
|
return setOn((v) => !v);
|
|
}, []);
|
|
return [on, handleToggle];
|
|
}
|
|
var useVisibilityChangeSubscribe = (callback) => {
|
|
document.addEventListener("visibilitychange", callback);
|
|
return () => {
|
|
document.removeEventListener("visibilitychange", callback);
|
|
};
|
|
};
|
|
var getVisibilityChangeSnapshot = () => {
|
|
return document.visibilityState;
|
|
};
|
|
var getVisibilityChangeServerSnapshot = () => {
|
|
throw Error("useVisibilityChange is a client-only hook");
|
|
};
|
|
function useVisibilityChange() {
|
|
const visibilityState = React.useSyncExternalStore(
|
|
useVisibilityChangeSubscribe,
|
|
getVisibilityChangeSnapshot,
|
|
getVisibilityChangeServerSnapshot
|
|
);
|
|
return visibilityState === "visible";
|
|
}
|
|
function useWindowScroll() {
|
|
const [state, setState] = React.useState({
|
|
x: null,
|
|
y: null
|
|
});
|
|
const scrollTo = React.useCallback((...args) => {
|
|
if (typeof args[0] === "object") {
|
|
window.scrollTo(args[0]);
|
|
} else if (typeof args[0] === "number" && typeof args[1] === "number") {
|
|
window.scrollTo(args[0], args[1]);
|
|
} else {
|
|
throw new Error(
|
|
`Invalid arguments passed to scrollTo. See here for more info. https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo`
|
|
);
|
|
}
|
|
}, []);
|
|
React.useLayoutEffect(() => {
|
|
const handleScroll = () => {
|
|
setState({ x: window.scrollX, y: window.scrollY });
|
|
};
|
|
handleScroll();
|
|
window.addEventListener("scroll", handleScroll);
|
|
return () => {
|
|
window.removeEventListener("scroll", handleScroll);
|
|
};
|
|
}, []);
|
|
return [state, scrollTo];
|
|
}
|
|
function useWindowSize() {
|
|
const [size, setSize] = React.useState({
|
|
width: null,
|
|
height: null
|
|
});
|
|
React.useLayoutEffect(() => {
|
|
const handleResize = () => {
|
|
setSize({
|
|
width: window.innerWidth,
|
|
height: window.innerHeight
|
|
});
|
|
};
|
|
handleResize();
|
|
window.addEventListener("resize", handleResize);
|
|
return () => {
|
|
window.removeEventListener("resize", handleResize);
|
|
};
|
|
}, []);
|
|
return size;
|
|
}
|
|
export {
|
|
useBattery,
|
|
useClickAway,
|
|
useCopyToClipboard,
|
|
useCounter,
|
|
useDebounce,
|
|
useDefault,
|
|
useDocumentTitle,
|
|
useFavicon,
|
|
useGeolocation,
|
|
useHistoryState,
|
|
useHover,
|
|
useIdle,
|
|
useIntersectionObserver,
|
|
useIsClient,
|
|
useIsFirstRender,
|
|
useList,
|
|
useLocalStorage,
|
|
useLockBodyScroll,
|
|
useLongPress,
|
|
useMap,
|
|
useMeasure,
|
|
useMediaQuery,
|
|
useMouse,
|
|
useNetworkState,
|
|
useObjectState,
|
|
useOrientation,
|
|
usePreferredLanguage,
|
|
usePrevious,
|
|
useQueue,
|
|
useRenderCount,
|
|
useRenderInfo,
|
|
useScript,
|
|
useSessionStorage,
|
|
useSet,
|
|
useThrottle,
|
|
useToggle,
|
|
useVisibilityChange,
|
|
useWindowScroll,
|
|
useWindowSize
|
|
};
|
|
//# sourceMappingURL=@uidotdev_usehooks.js.map
|