Skip to content

Commit

Permalink
chore(Dimmer|Grid|Sidebar): use React.forwardRef() (#4260)
Browse files Browse the repository at this point in the history
  • Loading branch information
layershifter committed Feb 18, 2022
1 parent b585e73 commit d96b8ef
Show file tree
Hide file tree
Showing 18 changed files with 233 additions and 224 deletions.
7 changes: 4 additions & 3 deletions src/collections/Grid/Grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import GridRow from './GridRow'
/**
* A grid is used to harmonize negative space in a layout.
*/
function Grid(props) {
const Grid = React.forwardRef(function (props, ref) {
const {
celled,
centered,
Expand Down Expand Up @@ -63,15 +63,16 @@ function Grid(props) {
const ElementType = getElementType(Grid, props)

return (
<ElementType {...rest} className={classes}>
<ElementType {...rest} className={classes} ref={ref}>
{children}
</ElementType>
)
}
})

Grid.Column = GridColumn
Grid.Row = GridRow

Grid.displayName = 'Grid'
Grid.propTypes = {
/** An element type to render as (string or function). */
as: PropTypes.elementType,
Expand Down
7 changes: 4 additions & 3 deletions src/collections/Grid/GridColumn.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
/**
* A column sub-component for Grid.
*/
function GridColumn(props) {
const GridColumn = React.forwardRef(function (props, ref) {
const {
children,
className,
Expand Down Expand Up @@ -57,12 +57,13 @@ function GridColumn(props) {
const ElementType = getElementType(GridColumn, props)

return (
<ElementType {...rest} className={classes}>
<ElementType {...rest} className={classes} ref={ref}>
{children}
</ElementType>
)
}
})

GridColumn.displayName = 'GridColumn'
GridColumn.propTypes = {
/** An element type to render as (string or function). */
as: PropTypes.elementType,
Expand Down
7 changes: 4 additions & 3 deletions src/collections/Grid/GridRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
/**
* A row sub-component for Grid.
*/
function GridRow(props) {
const GridRow = React.forwardRef(function (props, ref) {
const {
centered,
children,
Expand Down Expand Up @@ -49,12 +49,13 @@ function GridRow(props) {
const ElementType = getElementType(GridRow, props)

return (
<ElementType {...rest} className={classes}>
<ElementType {...rest} className={classes} ref={ref}>
{children}
</ElementType>
)
}
})

GridRow.displayName = 'GridRow'
GridRow.propTypes = {
/** An element type to render as (string or function). */
as: PropTypes.elementType,
Expand Down
71 changes: 38 additions & 33 deletions src/modules/Dimmer/Dimmer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import PropTypes from 'prop-types'
import React, { Component } from 'react'
import React from 'react'

import { createShorthandFactory, getUnhandledProps, isBrowser } from '../../lib'
import Portal from '../../addons/Portal'
Expand All @@ -9,46 +9,49 @@ import DimmerInner from './DimmerInner'
/**
* A dimmer hides distractions to focus attention on particular content.
*/
export default class Dimmer extends Component {
handlePortalMount = () => {
if (!isBrowser()) return
const Dimmer = React.forwardRef(function (props, ref) {
const { active, page } = props
const rest = getUnhandledProps(Dimmer, props)

// Heads up, IE doesn't support second argument in add()
document.body.classList.add('dimmed')
document.body.classList.add('dimmable')
}
if (page) {
const handlePortalMount = () => {
if (!isBrowser()) {
return
}

handlePortalUnmount = () => {
if (!isBrowser()) return
// Heads up, IE doesn't support second argument in add()
document.body.classList.add('dimmed')
document.body.classList.add('dimmable')
}

// Heads up, IE doesn't support second argument in add()
document.body.classList.remove('dimmed')
document.body.classList.remove('dimmable')
}
const handlePortalUnmount = () => {
if (!isBrowser()) {
return
}

render() {
const { active, page } = this.props
const rest = getUnhandledProps(Dimmer, this.props)

if (page) {
return (
<Portal
closeOnEscape={false}
closeOnDocumentClick={false}
onMount={this.handlePortalMount}
onUnmount={this.handlePortalUnmount}
open={active}
openOnTriggerClick={false}
>
<DimmerInner {...rest} active={active} page={page} />
</Portal>
)
// Heads up, IE doesn't support second argument in add()
document.body.classList.remove('dimmed')
document.body.classList.remove('dimmable')
}

return <DimmerInner {...rest} active={active} page={page} />
return (
<Portal
closeOnEscape={false}
closeOnDocumentClick={false}
onMount={handlePortalMount}
onUnmount={handlePortalUnmount}
open={active}
openOnTriggerClick={false}
>
<DimmerInner {...rest} active={active} page={page} ref={ref} />
</Portal>
)
}
}

return <DimmerInner {...rest} active={active} page={page} ref={ref} />
})

Dimmer.displayName = 'Dimmer'
Dimmer.propTypes = {
/** An active dimmer will dim its parent container. */
active: PropTypes.bool,
Expand All @@ -61,3 +64,5 @@ Dimmer.Dimmable = DimmerDimmable
Dimmer.Inner = DimmerInner

Dimmer.create = createShorthandFactory(Dimmer, (value) => ({ content: value }))

export default Dimmer
7 changes: 4 additions & 3 deletions src/modules/Dimmer/DimmerDimmable.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
/**
* A dimmable sub-component for Dimmer.
*/
function DimmerDimmable(props) {
const DimmerDimmable = React.forwardRef(function (props, ref) {
const { blurring, className, children, content, dimmed } = props

const classes = cx(
Expand All @@ -26,12 +26,13 @@ function DimmerDimmable(props) {
const ElementType = getElementType(DimmerDimmable, props)

return (
<ElementType {...rest} className={classes}>
<ElementType {...rest} className={classes} ref={ref}>
{childrenUtils.isNil(children) ? content : children}
</ElementType>
)
}
})

DimmerDimmable.displayName = 'DimmerDimmable'
DimmerDimmable.propTypes = {
/** An element type to render as (string or function). */
as: PropTypes.elementType,
Expand Down
138 changes: 62 additions & 76 deletions src/modules/Dimmer/DimmerInner.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Ref } from '@fluentui/react-component-ref'
import cx from 'clsx'
import _ from 'lodash'
import PropTypes from 'prop-types'
import React, { Component, createRef } from 'react'
import React from 'react'

import {
childrenUtils,
Expand All @@ -12,94 +11,79 @@ import {
getUnhandledProps,
useKeyOnly,
useVerticalAlignProp,
useIsomorphicLayoutEffect,
useMergedRefs,
} from '../../lib'

/**
* An inner element for a Dimmer.
*/
export default class DimmerInner extends Component {
containerRef = createRef()
contentRef = createRef()

componentDidMount() {
const { active } = this.props

this.toggleStyles(active)
}

componentDidUpdate(prevProps) {
const { active: currentActive } = this.props
const { active: prevActive } = prevProps

if (prevActive !== currentActive) this.toggleStyles(currentActive)
}

handleClick = (e) => {
const contentRef = this.contentRef.current

_.invoke(this.props, 'onClick', e, this.props)

if (contentRef && contentRef !== e.target && doesNodeContainClick(contentRef, e)) {
const DimmerInner = React.forwardRef(function (props, ref) {
const {
active,
children,
className,
content,
disabled,
inverted,
page,
simple,
verticalAlign,
} = props

const containerRef = useMergedRefs(ref, React.useRef())
const contentRef = React.useRef()

useIsomorphicLayoutEffect(() => {
if (!containerRef.current?.style) {
return
}

_.invoke(this.props, 'onClickOutside', e, this.props)
}

toggleStyles(active) {
const containerRef = this.containerRef.current

if (!containerRef || !containerRef.style) return
if (active) {
containerRef.style.setProperty('display', 'flex', 'important')
containerRef.current.style.setProperty('display', 'flex', 'important')
} else {
containerRef.style.removeProperty('display')
containerRef.current.style.removeProperty('display')
}
}
}, [active])

render() {
const {
active,
children,
className,
content,
disabled,
inverted,
page,
simple,
verticalAlign,
} = this.props

const classes = cx(
'ui',
useKeyOnly(active, 'active transition visible'),
useKeyOnly(disabled, 'disabled'),
useKeyOnly(inverted, 'inverted'),
useKeyOnly(page, 'page'),
useKeyOnly(simple, 'simple'),
useVerticalAlignProp(verticalAlign),
'dimmer',
className,
)
const rest = getUnhandledProps(DimmerInner, this.props)
const ElementType = getElementType(DimmerInner, this.props)

const childrenContent = childrenUtils.isNil(children) ? content : children

return (
<Ref innerRef={this.containerRef}>
<ElementType {...rest} className={classes} onClick={this.handleClick}>
{childrenContent && (
<div className='content' ref={this.contentRef}>
{childrenContent}
</div>
)}
</ElementType>
</Ref>
)
const handleClick = (e) => {
_.invoke(props, 'onClick', e, props)

if (contentRef.current !== e.target && doesNodeContainClick(contentRef.current, e)) {
return
}

_.invoke(props, 'onClickOutside', e, props)
}
}

const classes = cx(
'ui',
useKeyOnly(active, 'active transition visible'),
useKeyOnly(disabled, 'disabled'),
useKeyOnly(inverted, 'inverted'),
useKeyOnly(page, 'page'),
useKeyOnly(simple, 'simple'),
useVerticalAlignProp(verticalAlign),
'dimmer',
className,
)
const rest = getUnhandledProps(DimmerInner, props)
const ElementType = getElementType(DimmerInner, props)

const childrenContent = childrenUtils.isNil(children) ? content : children

return (
<ElementType {...rest} className={classes} onClick={handleClick} ref={containerRef}>
{childrenContent && (
<div className='content' ref={contentRef}>
{childrenContent}
</div>
)}
</ElementType>
)
})

DimmerInner.displayName = 'DimmerInner'
DimmerInner.propTypes = {
/** An element type to render as (string or function). */
as: PropTypes.elementType,
Expand Down Expand Up @@ -147,3 +131,5 @@ DimmerInner.propTypes = {
/** A dimmer can have its content top or bottom aligned. */
verticalAlign: PropTypes.oneOf(['bottom', 'top']),
}

export default DimmerInner
Loading

0 comments on commit d96b8ef

Please sign in to comment.