Skip to content
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "office-ui-fabric-react",
"comment": "Convert Layer component to mergeStyles",
"type": "minor"
}
],
"packageName": "office-ui-fabric-react",
"email": "v-brgarl@microsoft.com"
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { FocusZoneDirection } from '../../FocusZone';

import { ContextualMenu, canAnyMenuItemsCheck } from './ContextualMenu';
import { IContextualMenuItem, ContextualMenuItemType } from './ContextualMenu.types';
import { Layer } from '../Layer/Layer';
import { LayerBase as Layer } from '../Layer/Layer.base';
import { mount } from 'enzyme';

describe('ContextualMenu', () => {
Expand Down
178 changes: 178 additions & 0 deletions packages/office-ui-fabric-react/src/components/Layer/Layer.base.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/* tslint:disable:no-unused-variable */
import * as React from 'react';
import * as ReactDOM from 'react-dom';
/* tslint:enable:no-unused-variable */

import { Fabric } from '../../Fabric';
import {
ILayerProps,
ILayerStyleProps,
ILayerStyles,
} from './Layer.types';
import {
css,
BaseComponent,
classNamesFunction,
customizable,
getDocument,
setVirtualParent
} from '../../Utilities';

const _layersByHostId: { [hostId: string]: LayerBase[] } = {};
let _defaultHostSelector: string | undefined;

const getClassNames = classNamesFunction<ILayerStyleProps, ILayerStyles>();

// @customizable('Layer', ['theme'])
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to uncomment this before checkin, maybe there is something we can do here?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the old one didn't have it. I'm ok omitting it for now if we can't figure it out.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is commented out due to a bug, #3988. I'm leaving this commented out so it can be turned on later easily, but it's not blocking for this specific component because at least currently it does not need to use the theme.

export class LayerBase extends BaseComponent<ILayerProps, {}> {

public static defaultProps: ILayerProps = {
onLayerDidMount: () => undefined,
onLayerWillUnmount: () => undefined
};

private _rootElement: HTMLElement;
private _host: Node;
private _layerElement: HTMLElement | undefined;
private _hasMounted: boolean;
/**
* Used for notifying applicable Layers that a host is available/unavailable and to re-evaluate Layers that
* care about the specific host.
*/
public static notifyHostChanged(id: string) {
if (_layersByHostId[id]) {
_layersByHostId[id].forEach(layer => layer.forceUpdate());
}
}

/**
* Sets the default target selector to use when determining the host in which
* Layered content will be injected into. If not provided, an element will be
* created at the end of the document body.
*
* Passing in a falsey value will clear the default target and reset back to
* using a created element at the end of document body.
*/
public static setDefaultTarget(selector?: string) {
_defaultHostSelector = selector;
}

constructor(props: ILayerProps) {
super(props);

this._warnDeprecations({
onLayerMounted: 'onLayerDidMount'
});

if (this.props.hostId) {
if (!_layersByHostId[this.props.hostId]) {
_layersByHostId[this.props.hostId] = [];
}

_layersByHostId[this.props.hostId].push(this);
}
}

public componentDidMount() {
this.componentDidUpdate();
}

public componentWillUnmount() {
this._removeLayerElement();

if (this.props.hostId) {
_layersByHostId[this.props.hostId] = _layersByHostId[this.props.hostId].filter(layer => layer !== this);
if (!_layersByHostId[this.props.hostId].length) {
delete _layersByHostId[this.props.hostId];
}
}
}

public componentDidUpdate() {
const host = this._getHost();

const { className, getStyles, theme } = this.props;
const classNames = getClassNames(getStyles!,
{
theme: theme!,
className,
isNotHost: !this.props.hostId
}
);

if (host !== this._host) {
this._removeLayerElement();
}

if (host) {
this._host = host;

if (!this._layerElement) {
const doc = getDocument(this._rootElement) as Document;

this._layerElement = doc.createElement('div');
this._layerElement.className = classNames.root;

host.appendChild(this._layerElement);
setVirtualParent(this._layerElement, this._rootElement);
}

// Using this 'unstable' method allows us to retain the React context across the layer projection.
ReactDOM.unstable_renderSubtreeIntoContainer(
this,
(
<Fabric className={ classNames.content }>
{ this.props.children }
</Fabric>
),
this._layerElement,
() => {
if (!this._hasMounted) {
this._hasMounted = true;

// TODO: @deprecated cleanup required.
if (this.props.onLayerMounted) {
this.props.onLayerMounted();
}

this.props.onLayerDidMount!();
}
});
}
}

public render() {
return (
<span
className='ms-Layer'
ref={ this._resolveRef('_rootElement') }
/>
);
}

private _removeLayerElement() {
if (this._layerElement) {
this.props.onLayerWillUnmount!();

ReactDOM.unmountComponentAtNode(this._layerElement);
const parentNode = this._layerElement.parentNode;
if (parentNode) {
parentNode.removeChild(this._layerElement);
}
this._layerElement = undefined;
this._hasMounted = false;
}
}

private _getHost(): Node {
const { hostId } = this.props;
const doc = getDocument(this._rootElement) as Document;

if (hostId) {
return doc.getElementById(hostId) as Node;
} else {
return _defaultHostSelector ? doc.querySelector(_defaultHostSelector) as Node : doc.body;
}
}

}
13 changes: 0 additions & 13 deletions packages/office-ui-fabric-react/src/components/Layer/Layer.scss

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { ILayerStyleProps, ILayerStyles } from './Layer.types';
import {
IStyle,
ITheme,
} from '../../Styling';

export const getStyles = (
props: ILayerStyleProps
): ILayerStyles => {
const {
className,
theme,
isNotHost
} = props;

// const { palette, semanticColors } = theme;

return ({
root: [
'ms-Layer',
isNotHost && [
'ms-Layer--fixed',
{
position: 'fixed',
zIndex: 1000000,
top: 0,
left: 0,
width: '100vw',
height: '100vh',
visibility: 'hidden'
}
],
className
],
content: [
'ms-Layer-content',
{
visibility: 'visible'
}
]
});
};
Loading