# All files / src/divider useVerticalDividerHeight.ts

100% Statements 72/72
100% Branches 9/9
100% Functions 1/1
100% Lines 72/72

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    731x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    8x
    8x
    8x
    8x
    8x
    8x
    8x
    8x
    8x
    4x
    4x
    4x
    4x
    8x
    3x
    8x
    1x
    1x
    8x
    8x
    8x
    8x
    8x
    8x
    8x
    8x
    8x
     "use client";
    import type { CSSProperties, Ref, RefCallback } from "react";
    import { useCallback, useState } from "react";
    import { applyRef } from "../utils/applyRef.js";

    /** @remarks \@since 5.0.0 */
    export interface VerticalDividerHookOptions<E extends HTMLElement> {
      /**
       * An optional ref to merge with the returned ref.
       */
      ref?: Ref<E>;

      /**
       * An optional style object to merge with the divider's height style.
       */
      style?: CSSProperties;

      /**
       * The max height for the vertical divider. When this is `<= 0`, the hook will
       * be disabled.
       *
       * When the value is between 0 and 1, it will be used as a multiplier with the
       * parent element's height. When the value is greater than 1, it will be used
       * in `Math.min(parentElementHeight, maxHeight)`.
       */
      maxHeight: number;
    }

    /** @remarks \@since 5.0.0 */
    export interface VerticalDividerHeight<E extends HTMLElement> {
      ref: RefCallback<E>;
      style: CSSProperties | undefined;
    }

    /**
     * This is a small hook that is used to automatically create a vertical divider
     * based on the computed height of its parent element.
     *
     * @internal
     * @remarks \@since 5.0.0 The hook accepts an object instead of using multiple
     * params and uses a generic for the HTMLElement type.
     * @remarks \@since 6.0.0 Updated to be internal only since it doesn't make much
     * sense to be a public API.
     */
    export function useVerticalDividerHeight<E extends HTMLElement>(
      options: VerticalDividerHookOptions<E>
    ): VerticalDividerHeight<E> {
      const { ref, style, maxHeight } = options;

      const [height, setHeight] = useState<number | undefined>(undefined);
      const refCallback = useCallback(
        (instance: E | null) => {
          applyRef(instance, ref);
          if (!instance || !instance.parentElement || maxHeight === 0) {
            return;
          }

          const height = instance.parentElement.offsetHeight;
          if (maxHeight <= 1) {
            setHeight(height * maxHeight);
          } else {
            setHeight(Math.min(height, maxHeight));
          }
        },
        [maxHeight, ref]
      );

      return {
        ref: refCallback,
        style: maxHeight <= 0 ? style : { ...style, height },
      };
    }