{"version":3,"file":"scroll-box.cjs","sources":["../../src/util/scroll-box.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from \"react\";\nimport { Box } from \"@macrostrat/ui-components\";\nimport h from \"@macrostrat/hyper\";\nimport { useColumn } from \"../context\";\n\ninterface ColumnScrollerProps {\n  scrollToHeight: number;\n  alignment: \"center\" | \"top\" | \"bottom\";\n  animated: boolean;\n  onScrolled: (height: number) => void;\n  paddingTop: number;\n  scrollContainer: () => HTMLElement;\n}\n\ninterface ScrollToOpts {\n  animated?: boolean;\n  alignment?: \"center\" | \"top\" | \"bottom\";\n}\n\nexport function ColumnScroller(props: ColumnScrollerProps) {\n  const {\n    onScrolled = defaultOnScrolled,\n    scrollContainer = defaultGetScrollContainer,\n    scrollToHeight,\n    paddingTop,\n    animated,\n    alignment,\n    ...rest\n  } = props;\n\n  const ref = useRef(null);\n  const ctx = useColumn();\n  const columnScale = ctx?.scale;\n\n  const scrollTo = useCallback(\n    (height: number, opts: ScrollToOpts) => {\n      let node = ref.current;\n      if (node == null || columnScale == null) return;\n      let { animated, alignment } = opts;\n      if (animated == null) {\n        animated = false;\n      }\n      const pixelOffset = columnScale(height);\n      const { top } = node.getBoundingClientRect();\n\n      node = scrollContainer();\n      let pos = pixelOffset + top + paddingTop;\n      const screenHeight = window.innerHeight;\n\n      if (alignment === \"center\") {\n        pos -= screenHeight / 2;\n      } else if (alignment === \"bottom\") {\n        pos -= screenHeight;\n      }\n      if (animated && \"scrollBehavior\" in document.documentElement.style) {\n        node.scrollTo({ top: pos, behavior: \"smooth\" });\n      } else {\n        node.scrollTop = pos;\n      }\n    },\n    [onScrolled, scrollContainer, ref.current, columnScale, paddingTop],\n  );\n\n  useEffect(() => {\n    const { scrollToHeight, alignment } = props;\n    if (scrollToHeight == null) {\n      return;\n    }\n    // Actually perform the scroll\n    scrollTo(scrollToHeight, { alignment, animated });\n    return onScrolled(scrollToHeight);\n  }, [scrollTo, scrollToHeight]);\n\n  const { pixelHeight } = this.context;\n  return h(Box, {\n    height: pixelHeight,\n    position: \"absolute\",\n    ref,\n    ...rest,\n  });\n}\n\nfunction defaultOnScrolled(height: number) {\n  console.log(`Scrolled to ${height} m`);\n}\n\nfunction defaultGetScrollContainer() {\n  // Todo: generalize this\n  return document.querySelector(\".panel-container\");\n}\n"],"names":["useRef","useColumn","useCallback","animated","alignment","useEffect","scrollToHeight","h","Box"],"mappings":";;;;;;;;AAmBO,SAAS,eAAe,OAA4B;AACzD,QAAM;AAAA,IACJ,aAAa;AAAA,IACb,kBAAkB;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EAAA,IACD;AAEJ,QAAM,MAAMA,MAAAA,OAAO,IAAI;AACvB,QAAM,MAAMC,OAAAA,UAAA;AACZ,QAAM,cAAc,KAAK;AAEzB,QAAM,WAAWC,MAAAA;AAAAA,IACf,CAAC,QAAgB,SAAuB;AACtC,UAAI,OAAO,IAAI;AACf,UAAI,QAAQ,QAAQ,eAAe,KAAM;AACzC,UAAI,EAAE,UAAAC,WAAU,WAAAC,eAAc;AAC9B,UAAID,aAAY,MAAM;AACpBA,oBAAW;AAAA,MACb;AACA,YAAM,cAAc,YAAY,MAAM;AACtC,YAAM,EAAE,IAAA,IAAQ,KAAK,sBAAA;AAErB,aAAO,gBAAA;AACP,UAAI,MAAM,cAAc,MAAM;AAC9B,YAAM,eAAe,OAAO;AAE5B,UAAIC,eAAc,UAAU;AAC1B,eAAO,eAAe;AAAA,MACxB,WAAWA,eAAc,UAAU;AACjC,eAAO;AAAA,MACT;AACA,UAAID,aAAY,oBAAoB,SAAS,gBAAgB,OAAO;AAClE,aAAK,SAAS,EAAE,KAAK,KAAK,UAAU,UAAU;AAAA,MAChD,OAAO;AACL,aAAK,YAAY;AAAA,MACnB;AAAA,IACF;AAAA,IACA,CAAC,YAAY,iBAAiB,IAAI,SAAS,aAAa,UAAU;AAAA,EAAA;AAGpEE,QAAAA,UAAU,MAAM;AACd,UAAM,EAAE,gBAAAC,iBAAgB,WAAAF,eAAc;AACtC,QAAIE,mBAAkB,MAAM;AAC1B;AAAA,IACF;AAEA,aAASA,iBAAgB,EAAE,WAAAF,YAAW,UAAU;AAChD,WAAO,WAAWE,eAAc;AAAA,EAClC,GAAG,CAAC,UAAU,cAAc,CAAC;AAE7B,QAAM,EAAE,gBAAgB,KAAK;AAC7B,SAAOC,WAAAA,QAAEC,aAAAA,KAAK;AAAA,IACZ,QAAQ;AAAA,IACR,UAAU;AAAA,IACV;AAAA,IACA,GAAG;AAAA,EAAA,CACJ;AACH;AAEA,SAAS,kBAAkB,QAAgB;AACzC,UAAQ,IAAI,eAAe,MAAM,IAAI;AACvC;AAEA,SAAS,4BAA4B;AAEnC,SAAO,SAAS,cAAc,kBAAkB;AAClD;;"}