{"version":3,"file":"DOMUtils.mjs","sources":["../src/DOMUtils.ts"],"sourcesContent":["/**\n * @module DOMUtils\n * @description A collection of utility functions for DOM manipulation, element queries, and browser interactions.\n * @example\n * ```typescript\n * import { DOMUtils } from 'houser-js-utils';\n *\n * // Query elements safely\n * const element = DOMUtils.querySelector('.my-class');\n *\n * // Check element visibility\n * const isVisible = DOMUtils.isElementVisible(element);\n *\n * // Scroll to element\n * DOMUtils.scrollToElement(element);\n * ```\n */\n\nexport const DOMUtils = {\n  /**\n   * Adds a class to an element if it doesn't already have it.\n   * @param element - The DOM element to modify\n   * @param className - The class name to add\n   * @throws {TypeError} If element is not a valid DOM element\n   */\n  addClass(element: Element | null, className: string): void {\n    if (!element) return;\n    if (!element.classList.contains(className)) {\n      element.classList.add(className);\n    }\n  },\n\n  /**\n   * Gets the computed style of an element.\n   * @param element - The DOM element to check\n   * @param property - The CSS property to get (e.g., 'width', 'color')\n   * @returns The computed value of the property or empty string if element is null\n   */\n  getComputedStyle(element: Element | null, property: string): string {\n    if (!element) return \"\";\n    return window.getComputedStyle(element).getPropertyValue(property);\n  },\n\n  /**\n   * Gets the dimensions of an element including margins.\n   * @param element - The DOM element to measure\n   * @returns Object containing width and height, or {width: 0, height: 0} if element is null\n   */\n  getElementDimensions(element: Element | null): {\n    width: number;\n    height: number;\n  } {\n    if (!element) return { width: 0, height: 0 };\n    const rect = element.getBoundingClientRect();\n    const style = window.getComputedStyle(element);\n    return {\n      width:\n        rect.width +\n        parseFloat(style.marginLeft) +\n        parseFloat(style.marginRight),\n      height:\n        rect.height +\n        parseFloat(style.marginTop) +\n        parseFloat(style.marginBottom),\n    };\n  },\n\n  /**\n   * Gets the offset position of an element relative to the document.\n   * @param element - The DOM element to measure\n   * @returns Object containing top and left offsets, or {top: 0, left: 0} if element is null\n   */\n  getElementOffset(element: Element | null): { top: number; left: number } {\n    if (!element) return { top: 0, left: 0 };\n    const rect = element.getBoundingClientRect();\n    return {\n      top: rect.top + window.scrollY,\n      left: rect.left + window.scrollX,\n    };\n  },\n\n  /**\n   * Gets the scroll position of an element.\n   * @param element - The DOM element to check\n   * @returns Object containing scrollTop and scrollLeft values, or {scrollTop: 0, scrollLeft: 0} if element is null\n   */\n  getScrollPosition(element: Element | null): {\n    scrollTop: number;\n    scrollLeft: number;\n  } {\n    if (!element) {\n      return { scrollTop: 0, scrollLeft: 0 };\n    }\n    return {\n      scrollTop: element.scrollTop,\n      scrollLeft: element.scrollLeft,\n    };\n  },\n\n  /**\n   * Checks if an element has a specific class.\n   * @param element - The DOM element to check\n   * @param className - The class name to check for\n   * @returns True if the element has the class, false otherwise\n   */\n  hasClass(element: Element | null, className: string): boolean {\n    return element?.classList.contains(className) ?? false;\n  },\n\n  /**\n   * Checks if an element is currently fully visible in the viewport.\n   * @param element - The DOM element to check\n   * @returns True if the element is fully visible in the viewport, false otherwise\n   */\n  isElementInViewport(element: Element | null): boolean {\n    if (!element) {\n      return false;\n    }\n\n    const rect = element.getBoundingClientRect();\n    const viewportHeight =\n      window.innerHeight || document.documentElement.clientHeight;\n    const viewportWidth =\n      window.innerWidth || document.documentElement.clientWidth;\n\n    return (\n      rect.top >= 0 &&\n      rect.left >= 0 &&\n      rect.bottom <= viewportHeight &&\n      rect.right <= viewportWidth\n    );\n  },\n\n  /**\n   * Checks if an element is partially visible in the viewport.\n   * @param element - The DOM element to check\n   * @returns True if any part of the element is visible in the viewport, false otherwise\n   */\n  isElementPartiallyVisible(element: Element | null): boolean {\n    if (!element) {\n      return false;\n    }\n\n    const rect = element.getBoundingClientRect();\n    const viewportHeight =\n      window.innerHeight || document.documentElement.clientHeight;\n    const viewportWidth =\n      window.innerWidth || document.documentElement.clientWidth;\n\n    return !(\n      rect.bottom < 0 ||\n      rect.top > viewportHeight ||\n      rect.right < 0 ||\n      rect.left > viewportWidth\n    );\n  },\n\n  /**\n   * Removes a class from an element if it has it.\n   * @param element - The DOM element to modify\n   * @param className - The class name to remove\n   */\n  removeClass(element: Element | null, className: string): void {\n    if (!element) return;\n    if (element.classList.contains(className)) {\n      element.classList.remove(className);\n    }\n  },\n\n  /**\n   * Scrolls an element into view with smooth behavior.\n   * @param element - The DOM element to scroll into view\n   * @param options - ScrollIntoViewOptions for customizing scroll behavior\n   */\n  scrollIntoView(\n    element: Element | null,\n    options: ScrollIntoViewOptions = { behavior: \"smooth\" }\n  ): void {\n    element?.scrollIntoView(options);\n  },\n\n  /**\n   * Sets the scroll position of an element.\n   * @param element - The DOM element to modify\n   * @param position - Object containing scrollTop and scrollLeft values\n   */\n  setScrollPosition(\n    element: Element | null,\n    position: { scrollTop: number; scrollLeft: number }\n  ): void {\n    if (!element) return;\n    element.scrollTop = position.scrollTop;\n    element.scrollLeft = position.scrollLeft;\n  },\n\n  /**\n   * Sets a CSS property on an element.\n   * @param element - The DOM element to modify\n   * @param property - The CSS property to set (e.g., 'width', 'color')\n   * @param value - The value to set\n   */\n  setStyle(element: Element | null, property: string, value: string): void {\n    if (!element) return;\n    (element as HTMLElement).style.setProperty(property, value);\n  },\n\n  /**\n   * Toggles a class on an element.\n   * @param element - The DOM element to modify\n   * @param className - The class name to toggle\n   * @param force - Optional boolean to force add or remove the class\n   */\n  toggleClass(\n    element: Element | null,\n    className: string,\n    force?: boolean\n  ): void {\n    if (!element) return;\n    element.classList.toggle(className, force);\n  },\n\n  /**\n   * Waits for an element to be present in the DOM.\n   * @param selector - CSS selector for the element\n   * @param timeout - Maximum time to wait in milliseconds (default: 5000)\n   * @returns Promise that resolves with the element or null if not found within timeout\n   */\n  waitForElement(selector: string, timeout = 5000): Promise<Element | null> {\n    return new Promise((resolve) => {\n      if (document.querySelector(selector)) {\n        return resolve(document.querySelector(selector));\n      }\n\n      const observer = new MutationObserver(() => {\n        if (document.querySelector(selector)) {\n          observer.disconnect();\n          resolve(document.querySelector(selector));\n        }\n      });\n\n      observer.observe(document.body, {\n        childList: true,\n        subtree: true,\n      });\n\n      setTimeout(() => {\n        observer.disconnect();\n        resolve(null);\n      }, timeout);\n    });\n  },\n};\n"],"names":[],"mappings":"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"}