Skip to content

chore(Dimmer|Grid|Sidebar): use React.forwardRef() #4260

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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