{"version":3,"file":"index-gIaRUl-S.js","sources":["../../../app/javascript/src/explore/elements/ExpandableContainer/elements/ExpandButton/index.tsx","../../../app/javascript/src/explore/elements/ExpandableContainer/index.tsx"],"sourcesContent":["/* eslint-disable no-use-before-define */\nimport * as React from 'react';\nimport cls from 'classnames';\n\nimport styles from './index.module.sass';\n\ninterface Props {\n className?: string;\n onClick: () => void;\n}\n\nexport const ExpandButton = ({ className, onClick }: Props ) => (\n <button\n type=\"button\"\n className={cls(\n styles.button,\n 'bg-transparent border-0 p-0 font-weight-bold fs-5 text-secondary',\n className\n )}\n onClick={onClick}\n >\n Read More\n </button>\n);\n","import * as React from 'react';\nimport cls from 'classnames';\n\nimport BreakpointsService from 'src/explore/services/breakpoints';\nimport {\n Expand,\n ExpandProps,\n IHeightByBreakpoint,\n useInitialHeightByBreakpoint,\n} from 'src/explore/elements/Expand';\nimport { ExpandButton } from './elements/ExpandButton';\n\nimport styles from './index.module.sass';\n\nexport interface ExpandableContainerProps {\n className?:\n | string\n | {\n button?: string;\n container?: string;\n };\n CustomExpander?: React.FC<ExpanderProps>;\n initialHeight?: ExpandProps['initialHeight'];\n isOpen?: boolean;\n maskToLineBreak?: boolean;\n onToggleOpen?: ( open?: boolean ) => void;\n}\n\nexport interface ExpanderProps {\n collapsedHeight: number | null;\n isOpen: boolean;\n overflow: boolean;\n toggleExpand: () => void;\n}\n\ntype BreakPoint = keyof IHeightByBreakpoint;\n\nexport const ExpandableContainer: React.FC<ExpandableContainerProps> = ({\n children,\n className,\n CustomExpander,\n initialHeight,\n isOpen = false,\n maskToLineBreak,\n onToggleOpen,\n}) => {\n const [ buttonContainerRef, setButtonContainerRef ] = React.useState<HTMLDivElement | null>( null );\n const [ maskOffset, setMaskOffset ] = React.useState<number>( 0 );\n const [ open, setOpen ] = React.useState<boolean>( isOpen );\n\n React.useEffect(() => setOpen( isOpen ), [ isOpen ]);\n\n const contentRef = React.useRef<HTMLDivElement>( null );\n\n const handleToggleOpen = React.useCallback(() => {\n setOpen(( prevOpen ) => {\n if ( onToggleOpen ) onToggleOpen( !prevOpen );\n\n return !prevOpen;\n });\n }, [ onToggleOpen ]);\n\n const buttonContainerHeight = buttonContainerRef ? buttonContainerRef.offsetHeight : 0;\n\n // add button height to the initial height of the container\n const heightWithButton = React.useMemo(() => {\n switch ( typeof initialHeight ) {\n case 'number':\n return initialHeight + buttonContainerHeight;\n\n case 'object':\n return Object.keys( initialHeight ).reduce(\n ( prev, curr ) => ({\n ...prev,\n [curr]:\n initialHeight[curr as BreakPoint] !== null\n ? initialHeight[curr as BreakPoint] + buttonContainerHeight\n : null,\n }),\n {} as IHeightByBreakpoint\n );\n\n default:\n return undefined;\n }\n }, [ initialHeight, buttonContainerHeight ]);\n\n const currentCollapseHeight =\n useInitialHeightByBreakpoint( initialHeight )[\n BreakpointsService.getBreakpointSize() as keyof IHeightByBreakpoint\n ];\n\n React.useEffect(() => {\n const findLastLineBreak = () => {\n if ( maskToLineBreak && contentRef.current ) {\n let child: Element;\n let style: CSSStyleDeclaration;\n let lineHeight: number;\n for ( let i = 0; i < contentRef.current.children.length; i += 1 ) {\n child = contentRef.current.children[i];\n\n // find element under edge of mask\n if (\n child instanceof HTMLElement &&\n child.offsetTop + child.offsetHeight >= currentCollapseHeight\n ) {\n style = window.getComputedStyle( child );\n lineHeight = parseInt( style.lineHeight, 10 );\n\n // offset mask to set edge on line break\n setMaskOffset(( currentCollapseHeight - child.offsetTop ) % lineHeight );\n break;\n }\n }\n }\n };\n findLastLineBreak();\n window.addEventListener( 'resize', findLastLineBreak );\n return () => {\n window.removeEventListener( 'resize', findLastLineBreak );\n };\n }, [ contentRef, currentCollapseHeight, initialHeight, maskToLineBreak ]);\n\n // legacy classname support\n const classNames = typeof className === 'object' ? className : { container: className };\n\n return (\n <Expand\n className={cls( 'position-relative', classNames.container )}\n isOpen={open}\n initialHeight={heightWithButton}\n >\n {({ collapsedHeight, overflow }) => (\n <>\n <div ref={contentRef}>{children}</div>\n\n <div\n className={cls({\n 'position-absolute w-100 bg-white': overflow,\n [styles.mask]: overflow,\n [styles.hide]: overflow && open,\n })}\n style={{ top: collapsedHeight - buttonContainerHeight - maskOffset }}\n />\n\n <div\n ref={( newRef ) => setButtonContainerRef( newRef )}\n className={cls( styles.buttonContainer, 'position-absolute w-100', {\n [styles.open]: open || !overflow,\n })}\n style={{ top: collapsedHeight - buttonContainerHeight }}\n >\n {CustomExpander ? (\n <CustomExpander\n collapsedHeight={collapsedHeight}\n isOpen={open}\n overflow={overflow}\n toggleExpand={handleToggleOpen}\n />\n ) : (\n <ExpandButton className={classNames.button} onClick={handleToggleOpen} />\n )}\n </div>\n </>\n )}\n </Expand>\n );\n};\n"],"names":["ExpandButton","className","onClick","React.createElement","cls","styles","ExpandableContainer","children","CustomExpander","initialHeight","isOpen","maskToLineBreak","onToggleOpen","buttonContainerRef","setButtonContainerRef","React.useState","maskOffset","setMaskOffset","open","setOpen","React.useEffect","contentRef","React.useRef","handleToggleOpen","React.useCallback","prevOpen","buttonContainerHeight","heightWithButton","React.useMemo","prev","curr","currentCollapseHeight","useInitialHeightByBreakpoint","BreakpointsService","findLastLineBreak","child","style","lineHeight","i","classNames","Expand","collapsedHeight","overflow","React.Fragment","newRef"],"mappings":"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"}