{"version":3,"file":"VaAffix-utils.mjs","sources":["../../../../../src/components/va-affix/VaAffix-utils.ts"],"sourcesContent":["import { throttle } from '../../utils/throttle'\n\nexport type State = {\n  isTopAffixed: boolean;\n  isBottomAffixed: boolean;\n  width?: number;\n}\n\ntype Coordinates = {\n  top: number;\n  bottom: number;\n}\n\ntype ValuesToComputeAffixedState = {\n  coordinates: Coordinates;\n  offsetTop?: number;\n  offsetBottom?: number;\n  target: HTMLElement | Window | undefined;\n}\n\nexport function getWindowHeight () {\n  return document.documentElement.clientHeight ||\n    window.innerHeight ||\n    document.body.clientHeight\n}\n\nexport function computeAffixedState ({\n  coordinates,\n  offsetTop,\n  offsetBottom,\n  target,\n}: ValuesToComputeAffixedState): State {\n  let isTopAffixed = false\n  let isBottomAffixed = false\n\n  const windowHeight = getWindowHeight()\n\n  if (offsetTop != null && windowHeight) {\n    if (target === window) {\n      isTopAffixed = coordinates.top <= offsetTop\n    } else {\n      const { top } = (target as HTMLElement).getBoundingClientRect()\n      isTopAffixed = coordinates.top - top <= offsetTop\n    }\n  }\n\n  if (offsetBottom != null && windowHeight) {\n    if (target === window) {\n      isBottomAffixed = coordinates.bottom >= windowHeight - offsetBottom\n    } else {\n      const { bottom } = (target as HTMLElement).getBoundingClientRect()\n      isBottomAffixed = bottom - coordinates.bottom <= offsetBottom\n    }\n  }\n\n  return {\n    isTopAffixed,\n    isBottomAffixed,\n  }\n}\n\nfunction checkAffixedStateChange (currentState: State, nextState: State): boolean {\n  return currentState.isTopAffixed !== nextState.isTopAffixed ||\n    currentState.isBottomAffixed !== nextState.isBottomAffixed\n}\n\nexport type Context = {\n  offsetTop?: number;\n  offsetBottom?: number;\n  element: HTMLElement | undefined;\n  target: HTMLElement | Window | undefined;\n  setState: (state: State) => void;\n  getState: () => State;\n  initialPosition?: DOMRect | undefined;\n}\n\nexport function handleThrottledEvent (eventName: string | null, context: Context) {\n  const { target, element, offsetTop, offsetBottom, setState, getState, initialPosition } = context\n\n  if (!element) { return }\n\n  const isInitialCall = !eventName\n  const coordinates = element.getBoundingClientRect()\n  const options = {\n    offsetBottom,\n    offsetTop,\n    target,\n  }\n\n  const nextState = isInitialCall && initialPosition\n    ? computeAffixedState({ coordinates: initialPosition, ...options })\n    : computeAffixedState({ coordinates, ...options })\n\n  const prevState = getState()\n\n  if (checkAffixedStateChange(prevState, nextState)) {\n    setState({ ...nextState, width: coordinates.width })\n  } else if (prevState.width !== coordinates.width) {\n    setState({ ...prevState, width: coordinates.width })\n  }\n}\n\nfunction useCaptureDefault (eventName: string) {\n  // This event type must bubble to the Window object only when dispatched on the Document element\n  // https://www.w3.org/TR/2014/WD-DOM-Level-3-Events-20140925/#event-type-scroll\n  return eventName === 'scroll'\n}\n\ntype Options = {\n  handler: (eventName: string, event: Event) => void;\n  useCapture?: (eventName: string) => boolean;\n  wait?: number;\n}\n\nexport function useEventsHandlerWithThrottle (events: string[], {\n  handler,\n  useCapture = useCaptureDefault,\n  wait = 50,\n}: Options) {\n  const clearHandlersArray = events.map(eventName => {\n    const _handler = throttle((event: Event) => handler(eventName, event), wait)\n\n    window.addEventListener(eventName, _handler, useCapture(eventName))\n\n    return () => window.removeEventListener(eventName, _handler, useCapture(eventName))\n  })\n\n  return () => clearHandlersArray.forEach(clear => clear())\n}\n"],"names":[],"mappings":";AAoBO,SAAS,kBAAmB;AACjC,SAAO,SAAS,gBAAgB,gBAC9B,OAAO,eACP,SAAS,KAAK;AAClB;AAEO,SAAS,oBAAqB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuC;AACrC,MAAI,eAAe;AACnB,MAAI,kBAAkB;AAEtB,QAAM,eAAe;AAEjB,MAAA,aAAa,QAAQ,cAAc;AACrC,QAAI,WAAW,QAAQ;AACrB,qBAAe,YAAY,OAAO;AAAA,IAAA,OAC7B;AACL,YAAM,EAAE,IAAA,IAAS,OAAuB,sBAAsB;AAC/C,qBAAA,YAAY,MAAM,OAAO;AAAA,IAC1C;AAAA,EACF;AAEI,MAAA,gBAAgB,QAAQ,cAAc;AACxC,QAAI,WAAW,QAAQ;AACH,wBAAA,YAAY,UAAU,eAAe;AAAA,IAAA,OAClD;AACL,YAAM,EAAE,OAAA,IAAY,OAAuB,sBAAsB;AAC/C,wBAAA,SAAS,YAAY,UAAU;AAAA,IACnD;AAAA,EACF;AAEO,SAAA;AAAA,IACL;AAAA,IACA;AAAA,EAAA;AAEJ;AAEA,SAAS,wBAAyB,cAAqB,WAA2B;AAChF,SAAO,aAAa,iBAAiB,UAAU,gBAC7C,aAAa,oBAAoB,UAAU;AAC/C;AAYgB,SAAA,qBAAsB,WAA0B,SAAkB;AAC1E,QAAA,EAAE,QAAQ,SAAS,WAAW,cAAc,UAAU,UAAU,gBAAoB,IAAA;AAE1F,MAAI,CAAC,SAAS;AAAE;AAAA,EAAO;AAEvB,QAAM,gBAAgB,CAAC;AACjB,QAAA,cAAc,QAAQ;AAC5B,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAGF,QAAM,YAAY,iBAAiB,kBAC/B,oBAAoB,EAAE,aAAa,iBAAiB,GAAG,QAAS,CAAA,IAChE,oBAAoB,EAAE,aAAa,GAAG,QAAS,CAAA;AAEnD,QAAM,YAAY;AAEd,MAAA,wBAAwB,WAAW,SAAS,GAAG;AACjD,aAAS,EAAE,GAAG,WAAW,OAAO,YAAY,OAAO;AAAA,EAC1C,WAAA,UAAU,UAAU,YAAY,OAAO;AAChD,aAAS,EAAE,GAAG,WAAW,OAAO,YAAY,OAAO;AAAA,EACrD;AACF;AAEA,SAAS,kBAAmB,WAAmB;AAG7C,SAAO,cAAc;AACvB;AAQO,SAAS,6BAA8B,QAAkB;AAAA,EAC9D;AAAA,EACA,aAAa;AAAA,EACb,OAAO;AACT,GAAY;AACJ,QAAA,qBAAqB,OAAO,IAAI,CAAa,cAAA;AAC3C,UAAA,WAAW,SAAS,CAAC,UAAiB,QAAQ,WAAW,KAAK,GAAG,IAAI;AAE3E,WAAO,iBAAiB,WAAW,UAAU,WAAW,SAAS,CAAC;AAElE,WAAO,MAAM,OAAO,oBAAoB,WAAW,UAAU,WAAW,SAAS,CAAC;AAAA,EAAA,CACnF;AAED,SAAO,MAAM,mBAAmB,QAAQ,CAAA,UAAS,MAAO,CAAA;AAC1D;"}