# Custom Hooks Documentation This document provides comprehensive documentation for all custom hooks available in the project. ## Overview Custom hooks encapsulate reusable logic and patterns across components, improving code organization, maintainability, and consistency. ## Available Hooks ### `useClickOutside` Detects clicks outside of specified elements. Useful for closing dropdowns, modals, or menus. **Location:** `app/hooks/useClickOutside.ts` **Usage:** ```tsx import { useClickOutside } from "../hooks"; const menuRef = useRef(null); const buttonRef = useRef(null); const [isOpen, setIsOpen] = useState(false); useClickOutside([menuRef, buttonRef], () => setIsOpen(false), isOpen); ``` **Parameters:** - `refs`: Array of refs to elements that should not trigger the callback - `handler`: Callback function to execute when clicking outside - `enabled`: Whether the hook is enabled (default: true) **Example:** Used in `Select.tsx` for closing dropdown menus --- ### `useAnalytics` Centralized analytics tracking for component interactions. Supports both Google Analytics (gtag) and custom callbacks. **Location:** `app/hooks/useAnalytics.ts` **Usage:** ```tsx import { useAnalytics } from "../hooks"; const { trackEvent, trackCustomEvent } = useAnalytics(); // Standard event tracking trackEvent({ event: "button_click", category: "engagement", label: "contact_button", component: "AskOrganizer", }); // Custom event with callback trackCustomEvent( "contact_button_click", { component: "AskOrganizer", variant: "centered", }, onContactClick, // Optional callback ); ``` **Returns:** - `trackEvent`: Function to track standard analytics events - `trackCustomEvent`: Function to track custom events with optional callback **Example:** Used in `AskOrganizer.tsx` for tracking button clicks --- ### `useComponentId` Generates unique component IDs for accessibility. Provides consistent ID generation pattern. **Location:** `app/hooks/useComponentId.ts` **Usage:** ```tsx import { useComponentId } from "../hooks"; const { id, labelId } = useComponentId("input", props.id); // id: "input-123" or props.id if provided // labelId: "input-123-label" ``` **Parameters:** - `prefix`: Prefix for the generated ID (e.g., "input", "select") - `providedId`: Optional ID provided via props (takes precedence) **Returns:** - `id`: Component ID - `labelId`: Associated label ID for accessibility **Example:** Used in `Input.tsx`, `TextArea.tsx`, `Checkbox.tsx` --- ### `useFormField` Manages form field event handlers with disabled state handling. Ensures handlers respect disabled state. **Location:** `app/hooks/useFormField.ts` **Usage:** ```tsx import { useFormField } from "../hooks"; const { handleChange, handleFocus, handleBlur } = useFormField(disabled, { onChange: (e) => setValue(e.target.value), onFocus: (e) => setFocused(true), onBlur: (e) => setFocused(false), }); // Use in component ``` **Parameters:** - `disabled`: Whether the field is disabled - `handlers`: Object containing onChange, onFocus, onBlur handlers **Returns:** - `handleChange`: Wrapped onChange handler - `handleFocus`: Wrapped onFocus handler - `handleBlur`: Wrapped onBlur handler **Example:** Used in `Input.tsx`, `TextArea.tsx` --- ### `useComponentStyles` Manages component size and state styles. Provides a consistent pattern for styling components. **Location:** `app/hooks/useComponentStyles.ts` **Usage:** ```tsx import { useComponentStyles } from "../hooks"; const sizeStyles = { small: { input: "h-8 text-xs", label: "text-xs" }, medium: { input: "h-10 text-sm", label: "text-sm" }, }; const stateStyles = { default: { input: "border-gray-300", label: "text-gray-700" }, focus: { input: "border-blue-500", label: "text-gray-700" }, }; const { sizeClasses, stateClasses } = useComponentStyles({ size: "medium", state: "default", disabled: false, error: false, sizeStyles, stateStyles, }); ``` **Note:** This hook is available but styling logic is often component-specific. Consider using it when you have multiple components with similar styling patterns. --- ### `useSchemaData` Generates Schema.org structured data (JSON-LD) for SEO and search engines. **Location:** `app/hooks/useSchemaData.ts` **Usage:** ```tsx import { useSchemaData } from "../hooks"; // HowTo schema const schemaData = useSchemaData({ type: "HowTo", name: "How to build a community", description: "Step-by-step guide", steps: [ { name: "Step 1", text: "Start here" }, { name: "Step 2", text: "Continue here" }, ], }); // Organization schema const orgSchema = useSchemaData({ type: "Organization", name: "Media Economies Design Lab", url: "https://communityrule.com", email: "medlab@colorado.edu", sameAs: ["https://twitter.com/medlab"], }); // Render in component