{"version":3,"sources":["../../src/use-adaptive-textarea/index.ts"],"sourcesContent":["import { useRef } from 'react'\nimport { useEventListener } from '../use-event-listener'\nimport { useIsomorphicLayoutEffect } from '../use-isomorphic-layout-effect'\nimport { useLatest } from '../use-latest'\nimport { useSafeState } from '../use-safe-state'\nimport { useStableFn } from '../use-stable-fn'\nimport { useTargetElement } from '../use-target-element'\n\nimport type { DependencyList, RefObject } from 'react'\nimport type { ElementTarget } from '../use-target-element'\n\nexport interface UseAdaptiveTextareaOptions<T extends HTMLElement = HTMLElement> {\n  /**\n   * a list of dependencies to trigger the resize\n   *\n   * @defaultValue []\n   */\n  watch?: DependencyList\n  /**\n   * a list of events to trigger the resize\n   *\n   * @defaultValue ['input']\n   */\n  events?: (keyof HTMLElementEventMap)[]\n  /**\n   * whether to automatically adjust the height of the `textarea` element\n   *\n   * @defaultValue true\n   */\n  autoHeight?: boolean\n  /**\n   * a target element to apply the height style\n   *\n   * @defaultValue undefined\n   */\n  styleTarget?: ElementTarget<T>\n  /**\n   * a style property to apply the height value\n   *\n   * @defaultValue 'height'\n   */\n  styleProp?: 'height' | 'minHeight'\n  /**\n   * a callback function to be called when the height of the `textarea` element changes\n   *\n   * @defaultValue undefined\n   */\n  onResize?: (height: number, prevHeight: number) => void\n}\n\nexport interface UseAdaptiveTextareaReturns {\n  /**\n   * a React ref that should be passed to the `textarea` element\n   */\n  ref: RefObject<HTMLTextAreaElement | null>\n  /**\n   * the current height of the `textarea` element\n   */\n  height: number\n  /**\n   * a function to manually resize the `textarea` element\n   *\n   * @returns {void} `void`\n   */\n  resize(): void\n}\n\n/**\n * A React Hook that helps to create **adaptive** textarea that automatically adjust height based on its content.\n *\n * @param {UseAdaptiveTextareaOptions} options - `UseAdaptiveTextareaOptions`, see {@link UseAdaptiveTextareaOptions}\n * @returns {UseAdaptiveTextareaReturns} `UseAdaptiveTextareaReturns`, see {@link UseAdaptiveTextareaReturns}\n */\nexport function useAdaptiveTextarea<T extends HTMLElement>(\n  options: UseAdaptiveTextareaOptions<T> = {},\n): UseAdaptiveTextareaReturns {\n  const { onResize, events = ['input'], autoHeight = true, watch = [], styleTarget, styleProp = 'height' } = options\n\n  const taRef = useRef<HTMLTextAreaElement>(null)\n\n  const target = useTargetElement<T>(styleTarget, {\n    onChange() {\n      resize()\n    },\n  })\n\n  const [height, setHeight] = useSafeState(0)\n  const latest = useLatest({ height, onResize, styleProp })\n\n  const resize = useStableFn(() => {\n    /* v8 ignore next 35, it has been tested in Cypress  */\n    if (!taRef.current) return\n\n    const { onResize, styleProp, height } = latest.current\n\n    const style = window.getComputedStyle(taRef.current)\n\n    const paddingTop = Number.parseFloat(style.paddingTop)\n    const paddingBottom = Number.parseFloat(style.paddingBottom)\n    const borderTop = Number.parseFloat(style.borderTopWidth)\n    const borderBottom = Number.parseFloat(style.borderBottomWidth)\n\n    // border-box includes padding and border in the height\n    const isBorderBox = style.boxSizing === 'border-box'\n    const offset = isBorderBox ? -(borderTop + borderBottom) : paddingTop + paddingBottom\n\n    const prevHeight = taRef.current.style[styleProp]\n\n    // this is to force the scrollHeight to be calculated correctly\n    taRef.current.style[styleProp] = '1px'\n\n    const nextHeight = taRef.current.scrollHeight - offset\n\n    if (target.current) {\n      target.current.style[styleProp] = `${nextHeight}px`\n      taRef.current.style[styleProp] = prevHeight\n    } else if (autoHeight) {\n      taRef.current.style[styleProp] = `${nextHeight}px`\n    } else {\n      taRef.current.style[styleProp] = prevHeight\n    }\n\n    if (nextHeight === height) return\n\n    setHeight(nextHeight)\n    onResize?.(nextHeight, height)\n  })\n\n  // use `useLayoutEffect` to prevent layout jitter\n  useIsomorphicLayoutEffect(() => resize(), watch)\n\n  useEventListener(taRef, events, resize)\n\n  return {\n    ref: taRef,\n    height,\n    resize,\n  }\n}\n"],"names":["useAdaptiveTextarea","options","onResize","events","autoHeight","watch","styleTarget","styleProp","taRef","useRef","target","useTargetElement","onChange","resize","useSafeState","height","setHeight","latest","useLatest","useStableFn","current","style","window","getComputedStyle","paddingTop","Number","parseFloat","paddingBottom","borderTop","borderTopWidth","borderBottom","borderBottomWidth","isBorderBox","boxSizing","offset","prevHeight","nextHeight","scrollHeight","useIsomorphicLayoutEffect","useEventListener","ref"],"mappings":";;;;+BAyEgBA;;;eAAAA;;;qBAzEO;gCACU;yCACS;yBAChB;4BACG;2BACD;gCACK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmE1B,SAASA;QACdC,UAAAA,iEAAyC,CAAC;IAE1C,IAAQC,WAAmGD,QAAnGC,4BAAmGD,QAAzFE,QAAAA,sCAAS;QAAC;KAAQ,0CAAuEF,QAArEG,YAAAA,8CAAa,6CAAwDH,QAAlDI,OAAAA,oCAAQ,EAAE,mBAAEC,cAAsCL,QAAtCK,kCAAsCL,QAAzBM,WAAAA,4CAAY;IAE9F,IAAMC,QAAQC,IAAAA,aAAM,EAAsB;IAE1C,IAAMC,SAASC,IAAAA,kCAAgB,EAAIL,aAAa;QAC9CM,UAAAA,SAAAA;YACEC;QACF;IACF;IAEA,IAA4BC,iCAAAA,IAAAA,0BAAY,EAAC,QAAlCC,SAAqBD,kBAAbE,YAAaF;IAC5B,IAAMG,SAASC,IAAAA,oBAAS,EAAC;QAAEH,QAAAA;QAAQb,UAAAA;QAAUK,WAAAA;IAAU;IAEvD,IAAMM,SAASM,IAAAA,wBAAW,EAAC;QACzB,qDAAqD,GACrD,IAAI,CAACX,MAAMY,OAAO,EAAE;QAEpB,IAAwCH,kBAAAA,OAAOG,OAAO,EAA9ClB,WAAgCe,gBAAhCf,UAAUK,YAAsBU,gBAAtBV,WAAWQ,SAAWE,gBAAXF;QAE7B,IAAMM,QAAQC,OAAOC,gBAAgB,CAACf,MAAMY,OAAO;QAEnD,IAAMI,aAAaC,OAAOC,UAAU,CAACL,MAAMG,UAAU;QACrD,IAAMG,gBAAgBF,OAAOC,UAAU,CAACL,MAAMM,aAAa;QAC3D,IAAMC,YAAYH,OAAOC,UAAU,CAACL,MAAMQ,cAAc;QACxD,IAAMC,eAAeL,OAAOC,UAAU,CAACL,MAAMU,iBAAiB;QAE9D,uDAAuD;QACvD,IAAMC,cAAcX,MAAMY,SAAS,KAAK;QACxC,IAAMC,SAASF,cAAc,CAAEJ,CAAAA,YAAYE,YAAW,IAAKN,aAAaG;QAExE,IAAMQ,aAAa3B,MAAMY,OAAO,CAACC,KAAK,CAACd,UAAU;QAEjD,+DAA+D;QAC/DC,MAAMY,OAAO,CAACC,KAAK,CAACd,UAAU,GAAG;QAEjC,IAAM6B,aAAa5B,MAAMY,OAAO,CAACiB,YAAY,GAAGH;QAEhD,IAAIxB,OAAOU,OAAO,EAAE;YAClBV,OAAOU,OAAO,CAACC,KAAK,CAACd,UAAU,GAAG,AAAC,GAAa,OAAX6B,YAAW;YAChD5B,MAAMY,OAAO,CAACC,KAAK,CAACd,UAAU,GAAG4B;QACnC,OAAO,IAAI/B,YAAY;YACrBI,MAAMY,OAAO,CAACC,KAAK,CAACd,UAAU,GAAG,AAAC,GAAa,OAAX6B,YAAW;QACjD,OAAO;YACL5B,MAAMY,OAAO,CAACC,KAAK,CAACd,UAAU,GAAG4B;QACnC;QAEA,IAAIC,eAAerB,QAAQ;QAE3BC,UAAUoB;QACVlC,qBAAAA,+BAAAA,SAAWkC,YAAYrB;IACzB;IAEA,iDAAiD;IACjDuB,IAAAA,oDAAyB,EAAC;eAAMzB;OAAUR;IAE1CkC,IAAAA,kCAAgB,EAAC/B,OAAOL,QAAQU;IAEhC,OAAO;QACL2B,KAAKhC;QACLO,QAAAA;QACAF,QAAAA;IACF;AACF"}