All Downloads are FREE. Search and download functionalities are using the official Maven repository.

components.regions.ScrollSpy.Region.jsx Maven / Gradle / Ivy

The newest version!
import React, { useRef, useCallback, useState, useEffect } from 'react'
import { connect } from 'react-redux'
import classNames from 'classnames'
import { compose, setDisplayName } from 'recompose'

import { getState } from '../../snippets/ScrollContainer/ScrollContainer'
import withWidgetProps from '../withWidgetProps'
import withRegionContainer from '../withRegionContainer'
import { widgetsSelector } from '../../../ducks/widgets/selectors'
import { mapToNumeric } from '../../../tools/helpers'

import { ScrollSpyTypes } from './ScrollSpyTypes'
import { Menu } from './Menu'
import { Content } from './Content'
import { createStyle, mapContextItems } from './utils'

const DEFAULT_SCROLL_STATE = {
    clientHeight: 0,
    clientWidth: 0,
    scrollHeight: 0,
    scrollWidth: 0,
    scrollTop: 0,
    scrollLeft: 0,
    top: 0,
    left: 0,
    scrollTo() {},
}

export function Region(
    {
        id,
        title,
        className,
        style,
        pageId,
        changeActiveEntity,
        activeEntity: active,
        widgets,
        disabled,
        content: items = [],
        maxHeight: propsMaxHeight = 'auto',
        placement = 'left',
        headlines = true,
    },
) {
    const [isInit, setInit] = useState(false)
    const [scrollState, setScrollState] = useState(DEFAULT_SCROLL_STATE)

    const containerRef = useRef(null)
    const contentRef = useRef(null)
    const container = containerRef.current

    const { maxHeight } = mapToNumeric({ maxHeight: propsMaxHeight })

    const scrollable = maxHeight || style?.maxHeight || false
    const firstMenuItem = items?.[0]
    const firstMenuItemId = firstMenuItem?.id

    const scrollTo = useCallback((prop = {}) => {
        container?.scrollTo(prop)
    }, [container])

    const onChangeActive = useCallback((active) => {
        if (scrollable) {
            contentRef.current?.scrollTo(active)
        }

        changeActiveEntity(active)
    }, [contentRef, scrollable, changeActiveEntity])

    // initial scroll
    useEffect(() => {
        if (!isInit && contentRef.current && active && scrollable) {
            setInit(true)
            contentRef.current?.scrollTo(active)
        }
    }, [contentRef, active, isInit, scrollable])

    const onScroll = useCallback(() => {
        if (container) {
            setScrollState(getState(container, scrollTo))
        }
    }, [container, scrollTo])

    const currentStyle = createStyle(maxHeight, style)
    const contextItems = mapContextItems(items)

    return (
        
) } Region.propTypes = ScrollSpyTypes const mapStateToProps = state => ({ widgets: widgetsSelector(state) }) export default compose( setDisplayName('ScrollSpy'), withRegionContainer({ listKey: 'content' }), withWidgetProps, connect(mapStateToProps), )(Region)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy