UNPKG

@macrostrat/column-components

Version:

React rendering primitives for stratigraphic columns

1 lines 4 kB
{"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;;"}