Skip to content
This repository was archived by the owner on Mar 4, 2020. It is now read-only.
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Fix `Checkbox` style bug in background color [redlines] @bcalvery ([#1796](https://github.com/stardust-ui/react/pull/1796))
- Fix bidirectional `FocusZone` to land focus correctly on DOWN key press after series of UP arrow keys @sophieH29 ([#1794](https://github.com/stardust-ui/react/pull/1794))
- Fix `hand` icon in Teams theme @lucivpav ([#1782](https://github.com/stardust-ui/react/pull/1782))
- Use `target` from `Provider` in `ReactDOM.createPortal()` calls @layershifter ([#1810](https://github.com/stardust-ui/react/pull/1810))

### Features
- Add `overwrite` prop to `Provider` @layershifter ([#1780](https://github.com/stardust-ui/react/pull/1780))
Expand Down
8 changes: 5 additions & 3 deletions packages/react/src/components/Dialog/Dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Unstable_NestingAuto } from '@stardust-ui/react-component-nesting-registry'
import { documentRef, EventListener } from '@stardust-ui/react-component-event-listener'
import { Ref } from '@stardust-ui/react-component-ref'
import { EventListener } from '@stardust-ui/react-component-event-listener'
import { Ref, toRefObject } from '@stardust-ui/react-component-ref'
import * as customPropTypes from '@stardust-ui/react-proptypes'
import * as _ from 'lodash'
import * as PropTypes from 'prop-types'
Expand Down Expand Up @@ -273,6 +273,8 @@ class Dialog extends AutoControlledComponent<WithAsProp<DialogProps>, DialogStat
</ElementType>
</Ref>
)

const targetRef = toRefObject(this.context.target)
const triggerAccessibility: TriggerAccessibility = {
attributes: accessibility.attributes.trigger,
keyHandlers: accessibility.keyHandlers.trigger,
Expand Down Expand Up @@ -306,7 +308,7 @@ class Dialog extends AutoControlledComponent<WithAsProp<DialogProps>, DialogStat
</Ref>
<EventListener
listener={this.handleOverlayClick}
targetRef={documentRef}
targetRef={targetRef}
type="click"
capture
/>
Expand Down
11 changes: 6 additions & 5 deletions packages/react/src/components/Menu/MenuItem.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { documentRef, EventListener } from '@stardust-ui/react-component-event-listener'
import { Ref } from '@stardust-ui/react-component-ref'
import { EventListener } from '@stardust-ui/react-component-event-listener'
import { Ref, toRefObject } from '@stardust-ui/react-component-ref'
import * as customPropTypes from '@stardust-ui/react-proptypes'
import * as _ from 'lodash'
import cx from 'classnames'
Expand Down Expand Up @@ -212,10 +212,11 @@ class MenuItem extends AutoControlledComponent<WithAsProp<MenuItemProps>, MenuIt
indicator,
disabled,
} = this.props
const indicatorWithDefaults = indicator === undefined ? {} : indicator

const { menuOpen } = this.state

const indicatorWithDefaults = indicator === undefined ? {} : indicator
const targetRef = toRefObject(this.context.target)

const menuItemInner = childrenExist(children) ? (
children
) : (
Expand Down Expand Up @@ -272,7 +273,7 @@ class MenuItem extends AutoControlledComponent<WithAsProp<MenuItemProps>, MenuIt
})}
</Popper>
</Ref>
<EventListener listener={this.outsideClickHandler} targetRef={documentRef} type="click" />
<EventListener listener={this.outsideClickHandler} targetRef={targetRef} type="click" />
</>
) : null

Expand Down
24 changes: 12 additions & 12 deletions packages/react/src/components/Popup/Popup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { NodeRef, Unstable_NestingAuto } from '@stardust-ui/react-component-nest
import { handleRef, toRefObject, Ref } from '@stardust-ui/react-component-ref'
import * as customPropTypes from '@stardust-ui/react-proptypes'
import * as React from 'react'
import * as ReactDOM from 'react-dom'
import * as PropTypes from 'prop-types'
import * as keyboardKey from 'keyboard-key'
import * as _ from 'lodash'
Expand All @@ -13,7 +12,6 @@ import {
childrenExist,
AutoControlledComponent,
RenderResultConfig,
isBrowser,
ChildrenComponentProps,
ContentComponentProps,
StyledComponentProps,
Expand All @@ -39,6 +37,7 @@ import { ReactAccessibilityBehavior } from '../../lib/accessibility/reactTypes'
import { createShorthandFactory } from '../../lib/factories'
import createReferenceFromContextClick from './createReferenceFromContextClick'
import isRightClick from '../../lib/isRightClick'
import PortalInner from '../Portal/PortalInner'

export type PopupEvents = 'click' | 'hover' | 'focus' | 'context'
export type RestrictedClickEvents = 'click' | 'focus'
Expand Down Expand Up @@ -178,8 +177,6 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat
static defaultProps: PopupProps = {
accessibility: popupBehavior,
align: 'start',
mountDocument: isBrowser() ? document : null,
mountNode: isBrowser() ? document.body : null,
position: 'above',
on: 'click',
mouseLeaveDelay: 500,
Expand Down Expand Up @@ -247,7 +244,7 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat
<>
{this.renderTrigger(accessibility)}
{open &&
(inline ? popupContent : mountNode && ReactDOM.createPortal(popupContent, mountNode))}
(inline ? popupContent : <PortalInner mountNode={mountNode}>{popupContent}</PortalInner>)}
</>
)
}
Expand Down Expand Up @@ -479,8 +476,9 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat
trapFocus,
autoFocus,
} = this.props

const content = renderContent ? renderContent(scheduleUpdate) : propsContent
const documentRef = toRefObject(mountDocument)
const targetRef = toRefObject(mountDocument || this.context.target)

const popupContent = Popup.Content.create(content || {}, {
defaultProps: {
Expand Down Expand Up @@ -514,19 +512,19 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat

<EventListener
listener={this.handleDocumentClick(getRefs)}
targetRef={documentRef}
targetRef={targetRef}
type="click"
capture
/>
<EventListener
listener={this.handleDocumentClick(getRefs)}
targetRef={documentRef}
targetRef={targetRef}
type="contextmenu"
capture
/>
<EventListener
listener={this.handleDocumentKeyDown(getRefs)}
targetRef={documentRef}
targetRef={targetRef}
type="keydown"
capture
/>
Expand All @@ -535,13 +533,13 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat
<>
<EventListener
listener={this.dismissOnScroll}
targetRef={documentRef}
targetRef={targetRef}
type="wheel"
capture
/>
<EventListener
listener={this.dismissOnScroll}
targetRef={documentRef}
targetRef={targetRef}
type="touchmove"
capture
/>
Expand Down Expand Up @@ -596,7 +594,9 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat
*/
updateTriggerFocusableDomElement() {
const { mountDocument } = this.props
const activeElement = mountDocument.activeElement

const activeDocument = mountDocument || this.context.target
const activeElement = activeDocument.activeElement

this.triggerFocusableDomElement = this.triggerRef.current.contains(activeElement)
? activeElement
Expand Down
12 changes: 5 additions & 7 deletions packages/react/src/components/Portal/Portal.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { documentRef, EventListener } from '@stardust-ui/react-component-event-listener'
import { handleRef, Ref } from '@stardust-ui/react-component-ref'
import { EventListener } from '@stardust-ui/react-component-event-listener'
import { handleRef, Ref, toRefObject } from '@stardust-ui/react-component-ref'
import * as customPropTypes from '@stardust-ui/react-proptypes'
import * as PropTypes from 'prop-types'
import * as React from 'react'
Expand Down Expand Up @@ -121,8 +121,10 @@ class Portal extends AutoControlledComponent<PortalProps, PortalState> {
renderPortal(): JSX.Element | undefined {
const { children, content, trapFocus } = this.props
const { open } = this.state

const contentToRender = childrenExist(children) ? children : content
const focusTrapZoneProps = (_.keys(trapFocus).length && trapFocus) || {}
const targetRef = toRefObject(this.context.target)

return (
open && (
Expand All @@ -137,11 +139,7 @@ class Portal extends AutoControlledComponent<PortalProps, PortalState> {
) : (
contentToRender
)}
<EventListener
listener={this.handleDocumentClick}
targetRef={documentRef}
type="click"
/>
<EventListener listener={this.handleDocumentClick} targetRef={targetRef} type="click" />
</PortalInner>
</Ref>
)
Expand Down
14 changes: 9 additions & 5 deletions packages/react/src/components/Portal/PortalInner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import * as PropTypes from 'prop-types'
import * as _ from 'lodash'
import * as React from 'react'
import * as ReactDOM from 'react-dom'
// @ts-ignore
import { ThemeContext } from '@stardust-ui/react-fela'

import { isBrowser, ChildrenComponentProps, commonPropTypes } from '../../lib'

export interface PortalInnerProps extends ChildrenComponentProps {
Expand All @@ -27,6 +30,8 @@ export interface PortalInnerProps extends ChildrenComponentProps {
* A PortalInner is a container for Portal's content.
*/
class PortalInner extends React.Component<PortalInnerProps> {
static contextType = ThemeContext

static propTypes = {
...commonPropTypes.createCommon({
accessibility: false,
Expand All @@ -41,10 +46,6 @@ class PortalInner extends React.Component<PortalInnerProps> {
onUnmount: PropTypes.func,
}

static defaultProps = {
mountNode: isBrowser() ? document.body : null,
}

componentDidMount() {
_.invoke(this.props, 'onMount', this.props)
}
Expand All @@ -56,7 +57,10 @@ class PortalInner extends React.Component<PortalInnerProps> {
render() {
const { children, mountNode } = this.props

return mountNode && ReactDOM.createPortal(children, mountNode)
const target: HTMLElement | null = isBrowser() ? this.context.target.body : null
const container: HTMLElement | null = mountNode || target

return container && ReactDOM.createPortal(children, container)
}
}

Expand Down
1 change: 1 addition & 0 deletions packages/react/src/components/Provider/Provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ class Provider extends React.Component<WithAsProp<ProviderProps>> {
rtl,
disableAnimations,
renderer,
target,
}

const incomingContext: ProviderContextPrepared = overwrite ? {} : this.context
Expand Down
8 changes: 5 additions & 3 deletions packages/react/src/components/Toolbar/ToolbarItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import * as _ from 'lodash'
import * as PropTypes from 'prop-types'
import * as customPropTypes from '@stardust-ui/react-proptypes'
import cx from 'classnames'
import { Ref } from '@stardust-ui/react-component-ref'
import { documentRef, EventListener } from '@stardust-ui/react-component-event-listener'
import { Ref, toRefObject } from '@stardust-ui/react-component-ref'
import { EventListener } from '@stardust-ui/react-component-event-listener'

import {
UIComponent,
Expand Down Expand Up @@ -173,6 +173,8 @@ class ToolbarItem extends UIComponent<WithAsProp<ToolbarItemProps>, ToolbarItemS
menuRef = React.createRef<HTMLElement>()

renderSubmenu(menu, variables) {
const targetRef = toRefObject(this.context.target)

return (
<>
<Ref innerRef={this.menuRef}>
Expand All @@ -194,7 +196,7 @@ class ToolbarItem extends UIComponent<WithAsProp<ToolbarItemProps>, ToolbarItemS
</Ref>
<EventListener
listener={this.handleOutsideClick}
targetRef={documentRef}
targetRef={targetRef}
type="click"
capture
/>
Expand Down
6 changes: 2 additions & 4 deletions packages/react/src/components/Tooltip/Tooltip.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { toRefObject, Ref } from '@stardust-ui/react-component-ref'
import * as customPropTypes from '@stardust-ui/react-proptypes'
import * as React from 'react'
import * as ReactDOM from 'react-dom'
import * as PropTypes from 'prop-types'
import * as _ from 'lodash'

Expand All @@ -10,7 +9,6 @@ import {
childrenExist,
AutoControlledComponent,
RenderResultConfig,
isBrowser,
ChildrenComponentProps,
ContentComponentProps,
StyledComponentProps,
Expand All @@ -31,6 +29,7 @@ import TooltipContent, { TooltipContentProps } from './TooltipContent'
import { tooltipBehavior } from '../../lib/accessibility'
import { Accessibility } from '../../lib/accessibility/types'
import { ReactAccessibilityBehavior } from '../../lib/accessibility/reactTypes'
import PortalInner from '../Portal/PortalInner'

export interface TooltipSlotClassNames {
content: string
Expand Down Expand Up @@ -120,7 +119,6 @@ export default class Tooltip extends AutoControlledComponent<TooltipProps, Toolt

static defaultProps: TooltipProps = {
align: 'center',
mountNode: isBrowser() ? document.body : null,
position: 'above',
mouseLeaveDelay: 10,
pointing: true,
Expand Down Expand Up @@ -175,7 +173,7 @@ export default class Tooltip extends AutoControlledComponent<TooltipProps, Toolt
})}
</Ref>
)}
{mountNode && ReactDOM.createPortal(tooltipContent, mountNode)}
<PortalInner mountNode={mountNode}>{tooltipContent}</PortalInner>
</>
)
}
Expand Down
4 changes: 4 additions & 0 deletions packages/react/src/lib/mergeProviderContexts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const mergeProviderContexts = (
rtl: false,
disableAnimations: false,
originalThemes: [],
target: document,
} as ProviderContextPrepared

return contexts.reduce<ProviderContextPrepared>(
Expand All @@ -39,6 +40,9 @@ const mergeProviderContexts = (
acc.rtl = mergedRTL
}

// Use provided renderer if it is defined
acc.target = next.target || acc.target

// Use provided renderer if it is defined
acc.renderer = next.renderer || acc.renderer

Expand Down
2 changes: 2 additions & 0 deletions packages/react/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,15 @@ export interface ProviderContextInput {
renderer?: Renderer
rtl?: boolean
disableAnimations?: boolean
target?: Document
theme?: ThemeInput
}

export interface ProviderContextPrepared {
renderer: Renderer
rtl: boolean
disableAnimations: boolean
target: Document
theme: ThemePrepared
originalThemes: (ThemeInput | undefined)[]
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import * as React from 'react'
import { mount } from 'enzyme'

import PortalInner, { PortalInnerProps } from 'src/components/Portal/PortalInner'
import { mountWithProvider } from 'test/utils'

const mountPortalInner = (props: PortalInnerProps) =>
mount(
mountWithProvider(
<PortalInner {...props}>
<p />
</PortalInner>,
Expand Down
2 changes: 1 addition & 1 deletion packages/react/test/utils/withProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { felaRenderer } from 'src/lib'
import { ThemeInput } from 'src/themes/types'

export const EmptyThemeProvider: React.FunctionComponent = ({ children }) => (
<ThemeProvider theme={{ renderer: felaRenderer }}>{children}</ThemeProvider>
<ThemeProvider theme={{ renderer: felaRenderer, target: document }}>{children}</ThemeProvider>
)

export const mountWithProvider = (node, options?, theme?: ThemeInput) => {
Expand Down