1import { useState, useLayoutEffect, useCallback, useEffect } from "react";
3export function useLockBodyScroll() {
4 useLayoutEffect(() => {
5 // Get original body overflow
6 const originalStyle = window.getComputedStyle(document.body).overflow;
7 // Prevent scrolling on mount
8 document.body.style.overflow = "hidden";
9 // Re-enable scrolling when component unmounts
10 return () => (document.body.style.overflow = originalStyle);
11 }, []); // Empty array ensures effect is only run on mount and unmount
14export function useCopyToClipboard(text, notifyTimeout = 1000) {
15 const [copyStatus, setCopyStatus] = useState("inactive");
16 const copy = useCallback(() => {
17 navigator.clipboard.writeText(text).then(
18 () => setCopyStatus("copied"),
19 () => setCopyStatus("failed")
24 if (copyStatus === "inactive") {
28 const timeoutId = setTimeout(
29 () => setCopyStatus("inactive"),
33 return () => clearTimeout(timeoutId);
36 return [copyStatus, copy];
39function getStorageValue(key, defaultValue) {
40 // getting stored value
41 if (typeof window !== "undefined") {
42 const saved = window.localStorage.getItem(key);
43 const initial = saved !== null ? JSON.parse(saved) : defaultValue;
48export const useLocalStorage = (key, defaultValue) => {
49 const [value, setValue] = useState(() => {
50 return getStorageValue(key, defaultValue);
55 window.localStorage.setItem(key, JSON.stringify(value));
58 return [value, setValue];
61export const useInputChange = () => {
62 const [input, setInput] = useState({});
64 const handleInputChange = (e) =>
67 [e.currentTarget.name]: e.currentTarget.value,
70 return [input, handleInputChange];
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list