Skip to content

Commit

Permalink
migrate Popup
Browse files Browse the repository at this point in the history
  • Loading branch information
layershifter committed Jul 27, 2021
1 parent 60d5cbf commit 35a1bb1
Show file tree
Hide file tree
Showing 9 changed files with 319 additions and 230 deletions.
3 changes: 3 additions & 0 deletions src/addons/Portal/Portal.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ export interface StrictPortalProps {

/** Element to be rendered in-place where the portal is defined. */
trigger?: React.ReactNode

/** Called with a ref to the trigger node. */
triggerRef?: React.Ref<any>
}

declare class Portal extends React.Component<PortalProps> {
Expand Down
15 changes: 6 additions & 9 deletions src/addons/Portal/Portal.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import PropTypes from 'prop-types'
import React from 'react'

import {
customPropTypes,
doesNodeContainClick,
makeDebugger,
useAutoControlledValue,
useMergedRefs,
} from '../../lib'
import validateTrigger from './utils/validateTrigger'
import useTrigger from './utils/useTrigger'
import PortalInner from './PortalInner'

const debug = makeDebugger('portal')
Expand Down Expand Up @@ -38,22 +38,16 @@ function Portal(props) {
openOnTriggerClick,
openOnTriggerFocus,
openOnTriggerMouseEnter,
trigger,
} = props

/* istanbul ignore else */
if (process.env.NODE_ENV !== 'production') {
validateTrigger(trigger)
}

const [open, setOpen] = useAutoControlledValue({
state: props.open,
defaultState: props.defaultOpen,
initialState: false,
})

const contentRef = React.useRef()
const triggerRef = useMergedRefs(trigger?.ref, React.useRef())
const [triggerRef, trigger] = useTrigger(props.trigger, props.triggerRef)

const mouseEnterTimer = React.useRef()
const mouseLeaveTimer = React.useRef()
Expand Down Expand Up @@ -379,6 +373,9 @@ Portal.propTypes = {

/** Element to be rendered in-place where the portal is defined. */
trigger: PropTypes.node,

/** Called with a ref to the trigger node. */
triggerRef: customPropTypes.ref,
}

Portal.defaultProps = {
Expand Down
25 changes: 25 additions & 0 deletions src/addons/Portal/utils/useTrigger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react'

import { useMergedRefs } from '../../../lib'
import validateTrigger from './validateTrigger'

/**
* @param {React.ReactNode} trigger
* @param {React.Ref} triggerRef
*/
function useTrigger(trigger, triggerRef) {
const ref = useMergedRefs(trigger?.ref, triggerRef)

if (trigger) {
/* istanbul ignore else */
if (process.env.NODE_ENV !== 'production') {
validateTrigger(trigger)
}

return [ref, React.cloneElement(trigger, { ref })]
}

return [ref, null]
}

export default useTrigger
8 changes: 3 additions & 5 deletions src/addons/Portal/utils/validateTrigger.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ import * as ReactIs from 'react-is'
* Asserts that a passed element can be used cloned a props will be applied properly.
*/
export default function validateTrigger(element) {
if (element) {
React.Children.only(element)
React.Children.only(element)

if (ReactIs.isFragment(element)) {
throw new Error('An "React.Fragment" cannot be used as a `trigger`.')
}
if (ReactIs.isFragment(element)) {
throw new Error('An "React.Fragment" cannot be used as a `trigger`.')
}
}
18 changes: 18 additions & 0 deletions src/lib/hooks/usePrevious.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as React from 'react'

/**
* Hook keeping track of a given value from a previous execution of the component the Hook is used in.
*
* @see https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state
*/
function usePrevious(value) {
const ref = React.useRef()

React.useEffect(() => {
ref.current = value
})

return ref.current
}

export default usePrevious
3 changes: 2 additions & 1 deletion src/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export { makeDebugger }

export useAutoControlledValue from './hooks/useAutoControlledValue'
export useClassNamesOnNode from './hooks/useClassNamesOnNode'
export useMergedRefs from './hooks/useMergedRefs'
export useEventCallback from './hooks/useEventCallback'
export useIsomorphicLayoutEffect from './hooks/useIsomorphicLayoutEffect'
export useMergedRefs from './hooks/useMergedRefs'
export usePrevious from './hooks/usePrevious'
Loading

0 comments on commit 35a1bb1

Please sign in to comment.