### Install Dependencies
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/README.md
Installs all the necessary dependencies for the project.
```bash
npm install
```
--------------------------------
### Start Local Development Server
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/README.md
Starts a local development server, typically accessible at localhost:3000.
```bash
npm run dev
```
--------------------------------
### Basic useFetch Example
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useFetch.mdx
Demonstrates how to use the useFetch hook to fetch data from a URL and display it, handling loading and error states. This example fetches Pokemon data based on a counter.
```jsx
import * as React from "react";
import { useFetch } from "@uidotdev/usehooks";
import Card from "./Card";
export default function App() {
const [count, setCount] = React.useState(1);
const { error, data } = useFetch(
`https://pokeapi.co/api/v2/pokemon/${count}`
);
return (
useFetch
);
}
```
--------------------------------
### Basic useTimeout Example
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useTimeout.mdx
This example demonstrates how to use the useTimeout hook to trigger an action after a specified delay. The returned function can be used to clear the timeout.
```jsx
import * as React from "react";
import { useTimeout } from "@uidotdev/usehooks";
function Bomb({ hasExploded, hasDefused, handleClick }) {
if (hasExploded) {
return (
๐ฅ
You lose
);
}
if (hasDefused) {
return (
๐
You Win
);
}
return (
);
}
export default function App() {
const [hasDefused, setHasDefused] = React.useState(false);
const [hasExploded, setHasExploded] = React.useState(false);
const clear = useTimeout(() => {
setHasExploded(!hasExploded);
}, 1000);
const handleClick = () => {
clear();
setHasDefused(true);
};
return (
useTimeout
You have 1s to defuse (click) the bomb or it will explode
);
}
```
--------------------------------
### Basic useHover Example
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useHover.mdx
Demonstrates how to use the useHover hook to track hover state and change background color accordingly. Attach the returned ref to the element you want to monitor.
```jsx
import * as React from "react";
import { useHover } from "@uidotdev/usehooks";
function getRandomColor() {
const colors = ["green", "blue", "purple", "red", "pink"];
return colors[Math.floor(Math.random() * colors.length)];
}
export default function App() {
const [ref, hovering] = useHover();
const backgroundColor = hovering
? `var(--${getRandomColor()})`
: "var(--charcoal)";
return (
useHover
Hovering? {hovering ? "Yes" : "No"}
);
}
```
--------------------------------
### Get Astro CLI Help
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/README.md
Displays help information for the Astro CLI.
```bash
npm run astro --help
```
--------------------------------
### Basic useIntervalWhen Example
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useIntervalWhen.mdx
This example demonstrates how to use useIntervalWhen to create a timer that increments a counter. The timer starts when the button is clicked and stops when clicked again. The 'startImmediately' option is set to true, so the timer begins as soon as the 'when' condition becomes true.
```jsx
import * as React from "react";
import { useIntervalWhen } from "@uidotdev/usehooks";
export default function App() {
const [count, setCount] = React.useState(0);
const [when, setWhen] = React.useState(false);
useIntervalWhen(
() => {
setCount((c) => c + 0.1);
},
{ ms: 100, when, startImmediately: true }
);
return (
useIntervalWhen
);
}
```
--------------------------------
### useInterval Example
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useInterval.mdx
This example demonstrates how to use the useInterval hook to change a background color every second. It also shows how to stop the interval using the returned clearInterval function.
```jsx
import * as React from "react";
import { useInterval } from "@uidotdev/usehooks";
const colors = ["green", "blue", "purple", "red", "pink", "beige", "yellow"];
export default function App() {
const [running, setIsRunning] = React.useState(true);
const [index, setIndex] = React.useState(0);
const clear = useInterval(() => {
setIndex(index + 1);
}, 1000);
const handleStop = () => {
clear();
setIsRunning(false);
};
const color = colors[index % colors.length];
return (
useInterval
);
}
```
--------------------------------
### React useQueue Hook Example
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useQueue.mdx
Demonstrates the usage of the useQueue hook to manage a queue of numbers. Includes buttons to add, remove, and clear elements, and displays the current queue state.
```jsx
import * as React from "react";
import { useQueue } from "@uidotdev/usehooks";
function QueueDemo({ first, last, size, queue }) {
return (
Front
{queue.map((item, i) => {
const isFirst = first === item;
const isLast = last === item;
if (isFirst) {
return
First: {item}
;
}
if (isLast) {
return
Last: {item}
;
}
return
Item: {item}
;
})}
Back
{size} items in the queue
);
}
export default function App() {
const { add, remove, clear, first, last, size, queue } = useQueue([1, 2, 3]);
return (
UseQueue
);
}
```
--------------------------------
### useMeasure Hook Example
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useMeasure.mdx
This example demonstrates how to use the useMeasure hook to track the width or height of an element. Attach the returned ref to the element you want to measure. The hook provides the dimensions in the rect object.
```jsx
import * as React from "react";
import { useMeasure } from "@uidotdev/usehooks";
function Measure({ type = "horizontal" }) {
const [ref, { width, height }] = useMeasure();
return (
{type}
{type === "horizontal" ? (
) : (
)}
);
}
export default function App() {
return (
useMeasure
(Resize the rulers)
);
}
```
--------------------------------
### useClickAway Hook Example
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useClickAway.mdx
This example demonstrates how to use the useClickAway hook to close a modal when a user clicks outside of it. Attach the returned ref to the dialog element.
```jsx
import * as React from "react";
import { useClickAway } from "@uidotdev/usehooks";
import { closeIcon } from "./icons";
export default function App() {
const [isOpen, setIsOpen] = React.useState(false);
const ref = useClickAway(() => {
setIsOpen(false);
});
const handleOpenModal = () => {
if (isOpen === false) {
setIsOpen(true);
}
};
return (
<>
useClickAway
{isOpen && (
)}
>
);
}
```
--------------------------------
### Basic useCounter with Min/Max Limits
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useCounter.mdx
Demonstrates initializing useCounter with a starting value and defining minimum and maximum bounds. Includes buttons to increment, decrement, set to a specific value, and reset the counter, with the current count displayed.
```jsx
import * as React from "react";
import { useCounter } from "@uidotdev/usehooks";
export default function App() {
const [count, { increment, decrement, set, reset }] = useCounter(5, {
min: 5,
max: 10,
});
return (
UseCounter
with optional min / max
{count}
);
}
```
--------------------------------
### Basic useIntersectionObserver Example
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useIntersectionObserver.mdx
Demonstrates how to use the useIntersectionObserver hook to conditionally render content when an element becomes visible in the viewport. It utilizes default parameters for threshold, root, and rootMargin.
```jsx
import * as React from "react";
import { useIntersectionObserver } from "@uidotdev/usehooks";
import demoData from "./demoData";
const Section = ({ imgUrl, caption, href }) => {
const [ref, entry] = useIntersectionObserver({
threshold: 0,
root: null,
rootMargin: "0px",
});
return (
{entry?.isIntersecting && (
<>
{caption}
>
)}
);
};
export default function App() {
return (
{demoData.map(({ imgUrl, href, caption }, index) => {
return (
);
})}
);
}
```
--------------------------------
### useSet Hook Example
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useSet.mdx
Demonstrates how to use the useSet hook to manage a list of usernames, check for availability, and add new usernames. It includes form handling and conditional styling based on username availability.
```jsx
import * as React from "react";
import { useSet } from "@uidotdev/usehooks";
function format(val) {
return val.toLocaleLowerCase().replace(/\s/g, "");
}
export default function App() {
const [value, setValue] = React.useState("");
const set = useSet([
"benadam11",
"tylermcginnis",
"lynnandtonic",
"alexbrown40",
"uidotdev",
"bytesdotdev",
"reactnewsletter",
]);
const handleSubmit = (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const username = formData.get("username");
set.add(format(username));
setValue("");
e.target.reset();
e.target.focus();
};
const hasError = set.has(value);
return (
);
}
```
--------------------------------
### React useHistoryState Example
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useHistoryState.mdx
Demonstrates how to use the useHistoryState hook to manage a list of items with undo, redo, and clear functionality. It includes functions to add and remove items from the state.
```jsx
import * as React from "react";
import Form from "./Form";
import { useHistoryState } from "@uidotdev/usehooks";
export default function App() {
const { state, set, undo, redo, clear, canUndo, canRedo } = useHistoryState({
items: [],
});
const addTodo = (val) => {
set({
...state,
items: state.items.concat({ id: crypto.randomUUID(), name: val }),
});
};
const removeTodo = (id) => {
set({
...state,
items: state.items.filter((item) => item.id !== id),
});
};
return (
useHistoryState
{state.items.map((item, index) => {
return (
{item.name}
);
})}
);
}
```
--------------------------------
### React useCopyToClipboard Example
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useCopyToClipboard.mdx
Demonstrates how to use the useCopyToClipboard hook in a React component to copy a generated API key. It shows how to conditionally render UI elements based on whether text has been copied.
```jsx
import * as React from "react";
import { useCopyToClipboard } from "@uidotdev/usehooks";
import { copyIcon, checkIcon } from "./icons";
const randomHash = crypto.randomUUID();
export default function App() {
const [copiedText, copyToClipboard] = useCopyToClipboard();
const hasCopiedText = Boolean(copiedText);
return (
useCopyToClipboard
{randomHash}
{hasCopiedText && (
)}
);
}
```
--------------------------------
### Initialize and Use useList Hook
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useList.mdx
Demonstrates initializing the `useList` hook with a default array and using its returned methods to manipulate the list state. This example shows how to set, push, remove, insert, update, and clear list items.
```jsx
import { useList } from "@uidotdev/usehooks";
import ListDemo from "./ListDemo";
export default function App() {
const [list, { set, push, removeAt, insertAt, updateAt, clear }] = useList([
"First",
"Second",
"Third",
]);
return (
UseList
);
}
```
--------------------------------
### useToggle Hook Example
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useToggle.mdx
Demonstrates how to use the useToggle hook to manage a boolean state and toggle it using a checkbox and buttons. The hook can be called with an initial value or without one.
```jsx
import * as React from "react";
import { useToggle } from "@uidotdev/usehooks";
function ToggleDemo({ on, toggle }) {
return (
);
}
```
--------------------------------
### Basic Countdown Timer with useCountdown
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useCountdown.mdx
This example demonstrates a basic countdown timer. It sets an end time and uses the hook to display the remaining seconds. Buttons are provided to add time to the countdown.
```jsx
import * as React from "react";
import { useCountdown } from "@uidotdev/usehooks";
export default function App() {
const [endTime, setEndTime] = React.useState(new Date(Date.now() + 10000));
const [complete, setComplete] = React.useState(false);
const count = useCountdown(endTime, {
interval: 1000,
onTick: () => console.log("tick"),
onComplete: (time) => setComplete(true),
});
const handleClick = (time) => {
if (complete === true) return;
const nextTime = endTime.getTime() + time;
setEndTime(new Date(nextTime));
};
return (
useCountdown
{count}
{complete === false && (
)}
);
}
```
--------------------------------
### Basic Usage of useWindowScroll Hook
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useWindowScroll.mdx
Demonstrates how to use the useWindowScroll hook to display current scroll coordinates and scroll to specific positions. Includes examples of scrolling to absolute coordinates and using smooth scrolling.
```jsx
import * as React from "react";
import { useWindowScroll } from "@uidotdev/usehooks";
export default function App() {
const [{ x, y }, scrollTo] = useWindowScroll();
return (
useWindowScroll
{new Array(50).fill().map((_, index) => {
return
{index}
;
})}
);
}
```
--------------------------------
### Display Network State with useNetworkState
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useNetworkState.mdx
This example demonstrates how to use the useNetworkState hook to display various network status properties in a table. It requires importing React and the hook itself. This hook is intended for client-side use only.
```jsx
import * as React from "react";
import { useNetworkState } from "@uidotdev/usehooks";
export default function App() {
const network = useNetworkState();
return (
useNetworkState
{Object.keys(network).map((key) => {
return (
{key}
{`${network[key]}`}
);
})}
);
}
```
--------------------------------
### React useDefault Hook Example
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useDefault.mdx
Demonstrates how to use the useDefault hook to manage state with a default value. It shows setting initial state, updating it, and how null values trigger the default.
```jsx
import * as React from "react";
import { useDefault } from "@uidotdev/usehooks";
export default function App() {
const initialState = { name: "Tyler" };
const defaultState = { name: "Ben" };
const [user, setUser] = useDefault(initialState, defaultState);
return (
useDefault
{JSON.stringify(user)}
);
}
```
--------------------------------
### Detecting Arrow Key Presses with useKeyPress
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useKeyPress.mdx
This example demonstrates how to use useKeyPress to detect presses of arrow keys and update the UI accordingly. It sets up listeners for 'ArrowRight', 'ArrowLeft', 'ArrowUp', and 'ArrowDown', triggering a callback to visually indicate the pressed key.
```jsx
import * as React from "react";
import { useKeyPress } from "@uidotdev/usehooks";
export default function App() {
const [activeKey, setActiveKey] = React.useState("");
useKeyPress("ArrowRight", onKeyPress);
useKeyPress("ArrowLeft", onKeyPress);
useKeyPress("ArrowUp", onKeyPress);
useKeyPress("ArrowDown", onKeyPress);
function onKeyPress(e) {
e.preventDefault();
setActiveKey(e.key);
setTimeout(() => {
setActiveKey("");
}, 600);
}
return (
useKeyPress
Press one of the arrow keys on your keyboard
{Boolean(activeKey) && }
);
}
```
--------------------------------
### useSessionStorage Example
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useSessionStorage.mdx
Demonstrates how to use the useSessionStorage hook to manage a counter stored in session storage. It includes buttons to clear the cart, reload the window, and clear the entire session storage.
```jsx
import * as React from "react";
import { useSessionStorage } from "@uidotdev/usehooks";
import { cart } from "./icons";
export default function App() {
const [count, setCount] = useSessionStorage("woot", 0);
return (
useSessionStorage
);
}
```
--------------------------------
### Track Previous Value with usePrevious
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/usePrevious.mdx
This example demonstrates how to use the usePrevious hook to store and display the previous value of a color state. It updates the color on button click and shows both the current and previous colors.
```jsx
import * as React from "react";
import { usePrevious } from "@uidotdev/usehooks";
function getRandomColor() {
const colors = ["green", "blue", "purple", "red", "pink"];
return colors[Math.floor(Math.random() * colors.length)];
}
export default function App() {
const [color, setColor] = React.useState(getRandomColor());
const previousColor = usePrevious(color);
const handleClick = () => {
function getNewColor() {
const newColor = getRandomColor();
if (color === newColor) {
getNewColor();
} else {
setColor(newColor);
}
}
getNewColor();
};
return (
usePrevious
Previous: {previousColor}Current: {color}
);
}
```
--------------------------------
### useLocalStorage Hook Example
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useLocalStorage.mdx
Demonstrates how to use the useLocalStorage hook to manage drawing data persisted in localStorage. It initializes the drawing state, sets up a canvas for drawing, and saves the drawing to localStorage using the provided save function.
```jsx
import * as React from "react";
import { useLocalStorage } from "@uidotdev/usehooks";
import createDrawing from "./createDrawing";
export default function App() {
const [drawing, saveDrawing] = useLocalStorage("drawing", null);
const ref = React.useRef(null);
React.useEffect(() => {
createDrawing(ref.current, drawing, saveDrawing);
}, [drawing, saveDrawing]);
return (
useLocalStorage
(draw something)
);
}
```
--------------------------------
### Basic useOrientation Hook Usage
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useOrientation.mdx
Demonstrates how to use the useOrientation hook to get the current device orientation angle and type. It displays this information in a table and uses the orientation type to style an element.
```jsx
import * as React from "react";
import { useOrientation } from "@uidotdev/usehooks";
export default function App() {
const orientation = useOrientation();
return (
useOrientation
{Object.keys(orientation).map((key) => {
return (
{key}
{orientation[key]}
);
})}
);
}
```
--------------------------------
### Basic Usage of useRandomInterval
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useRandomInterval.mdx
This example demonstrates the basic usage of the useRandomInterval hook to add a 'heart' at random intervals. It requires React and the useRandomInterval hook. The returned 'clear' function can be used to stop the interval.
```jsx
import * as React from "react";
import { useRandomInterval } from "@uidotdev/usehooks";
import HeartsDemo from "./Heart";
export default function App() {
const demo = React.useRef(new HeartsDemo());
const clear = useRandomInterval(
() => {
demo.current.addHeart();
},
{ minDelay: 50, maxDelay: 3000 }
);
React.useEffect(() => {
demo.current.loop();
}, []);
return (
useRandomInterval
);
}
```
--------------------------------
### React Component Using useBattery
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useBattery.mdx
This example demonstrates how to use the useBattery hook in a React component to display battery information. It conditionally renders battery details or a loading message based on the hook's loading state.
```jsx
import { useBattery } from "@uidotdev/usehooks";
import Battery from "./Battery";
export default function App() {
const { loading, level, charging, chargingTime, dischargingTime } =
useBattery();
return (
<>
useBattery
{!loading ? (
) : (
Loading...
)}
>
);
}
```
--------------------------------
### Use useLogger for Component Lifecycle Logging
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useLogger.mdx
This example demonstrates how to use the useLogger hook to log lifecycle events for child components. It logs the component name and its props on mount, update, and unmount. Check the browser console for output.
```jsx
import * as React from "react";
import { useLogger } from "@uidotdev/usehooks";
function FirstChild(props) {
useLogger(props.name, props);
return (
);
}
```
--------------------------------
### Track Browser Window Size with useWindowSize
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useWindowSize.mdx
Use this hook to get the current width and height of the browser window. The hook automatically updates these values when the window is resized. It's ideal for implementing responsive layouts or conditional rendering based on screen dimensions.
```jsx
import * as React from "react";
import { useWindowSize } from "@uidotdev/usehooks";
function Browser({ size }) {
return (
);
}
export default function App() {
const size = useWindowSize();
return (
useWindowSize
Resize the window
width
{size.width}
height
{size.height}
);
}
```
--------------------------------
### Basic Usage of useRenderCount Hook
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useRenderCount.mdx
Demonstrates how to use the useRenderCount hook to display the number of times a component has rendered. This example shows incrementing a state variable to trigger re-renders and observing the corresponding increase in the render count.
```jsx
import * as React from "react";
import { useRenderCount } from "@uidotdev/usehooks";
export default function App() {
const renderCount = useRenderCount();
const [count, setCount] = React.useState(0);
return (
useRenderCount
(strict mode on)
Count: {count}
Render Count: {renderCount}
);
}
```
--------------------------------
### Preview Production Build
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/README.md
Locally previews the production build before deploying it.
```bash
npm run preview
```
--------------------------------
### Build for Production
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/README.md
Builds the project for production, outputting files to the ./dist/ directory.
```bash
npm run build
```
--------------------------------
### Get User's Preferred Language
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/usePreferredLanguage.mdx
Use this hook to get the user's preferred language. It's useful for internationalization and displaying content in the user's native language. The language is determined by browser settings.
```jsx
import * as React from "react";
import { usePreferredLanguage } from "@uidotdev/usehooks";
export default function App() {
const language = usePreferredLanguage();
return (
usePreferredLanguage
Change language here - chrome://settings/languages
The correct date format for
{language}
is{
```
```jsx
);
}
```
--------------------------------
### Responsive UI with useMediaQuery
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useMediaQuery.mdx
Demonstrates how to use the useMediaQuery hook to conditionally apply styles or render components based on different screen sizes. Ensure the hook is imported from '@uidotdev/usehooks'.
```jsx
import * as React from "react";
import { useMediaQuery } from "@uidotdev/usehooks";
import { phone, tablet, laptop, desktop } from "./icons";
export default function App() {
const isSmallDevice = useMediaQuery("only screen and (max-width : 768px)");
const isMediumDevice = useMediaQuery(
"only screen and (min-width : 769px) and (max-width : 992px)"
);
const isLargeDevice = useMediaQuery(
"only screen and (min-width : 993px) and (max-width : 1200px)"
);
const isExtraLargeDevice = useMediaQuery(
"only screen and (min-width : 1201px)"
);
return (
useMediaQuery
Resize your browser windows to see changes.
{phone}
Small
{tablet}
Medium
{laptop}
Large
{desktop}
Extra Large
);
}
```
--------------------------------
### Basic Usage of useEventListener
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useEventListener.mdx
This example demonstrates how to use useEventListener to close a modal when a click occurs outside of it. It attaches a 'mousedown' event listener to the document.
```jsx
import * as React from "react";
import { useEventListener } from "@uidotdev/usehooks";
import { closeIcon } from "./icons";
export default function App() {
const ref = React.useRef(null);
const [isOpen, setIsOpen] = React.useState(false);
const handleClick = (e) => {
const element = ref.current;
if (element && !element.contains(e.target)) {
setIsOpen(false);
}
};
useEventListener(document, "mousedown", handleClick);
return (
useEventListener
{isOpen && (
)}
);
}
```
--------------------------------
### Update Favicon Dynamically with useFavicon
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useFavicon.mdx
Use the useFavicon hook to change the favicon based on component state. This example demonstrates updating the favicon when clicking buttons.
```jsx
import * as React from "react";
import { useFavicon } from "@uidotdev/usehooks";
export default function App() {
const [favicon, setFavicon] = React.useState(
"https://ui.dev/favicon/favicon-32x32.png"
);
useFavicon(favicon);
return (
useFavicon
);
}
```
--------------------------------
### Project Structure
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/README.md
The project follows a standard Astro structure with components, layouts, and pages located in the src directory. Static assets are placed in the public directory.
```bash
/
โโโ public/
โ โโโ favicon.png
โ โโโ img
โโโ src/
โ โโโ components/
โ โ โโโ Button.astro
โ โโโ layouts/
โ โ โโโ Layout.astro
โ โโโ pages/
โ โ โโโ index.astro
โ โโโ sections/
โ โ โโโ HomeHero.astro
โโโ package.json
```
--------------------------------
### Track Document Visibility with useVisibilityChange
Source: https://github.com/uidotdev/usehooks/blob/main/usehooks.com/src/content/hooks/useVisibilityChange.mdx
Use this hook to get a boolean indicating if the document is visible. It's useful for triggering actions when a user navigates away from or back to a tab.
```jsx
import * as React from "react";
import { useVisibilityChange } from "@uidotdev/usehooks";
export default function App() {
const documentVisible = useVisibilityChange();
const [tabAwayCount, setTabAwayCount] = React.useState(0);
React.useEffect(() => {
if (documentVisible === false) {
setTabAwayCount((c) => c + 1);
}
}, [documentVisible]);
return (