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": "Allowing use of Elements as target prop for Callouts and ContextualMenus",
"type": "patch"
}
],
"packageName": "office-ui-fabric-react",
"email": "jdrush89@gmail.com"
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ describe('Callout', () => {
expect(threwException).toEqual(false);
});

it('target HTMLElements does not throw exception', () => {
it('target Elements does not throw exception', () => {
const targetElement = document.createElement('div');
document.body.appendChild(targetElement);
let threwException = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ export interface ICalloutProps {

/**
* The target that the Callout should try to position itself based on.
* It can be either an HTMLElement a querySelector string of a valid HTMLElement
* It can be either an Element a querySelector string of a valid Element
* or a MouseEvent. If MouseEvent is given then the origin point of the event will be used.
*/
target?: HTMLElement | string | MouseEvent | IPoint | null;
target?: Element | string | MouseEvent | IPoint | null;

/**
* How the element should be positioned
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export class CalloutContentBase extends BaseComponent<ICalloutProps, ICalloutSta
private _bounds: IRectangle;
private _maxHeight: number | undefined;
private _positionAttempts: number;
private _target: HTMLElement | MouseEvent | IPoint | null;
private _target: Element | MouseEvent | IPoint | null;
private _setHeightOffsetTimer: number;

constructor(props: ICalloutProps) {
Expand Down Expand Up @@ -371,17 +371,17 @@ export class CalloutContentBase extends BaseComponent<ICalloutProps, ICalloutSta
return true;
}

private _setTargetWindowAndElement(target: HTMLElement | string | MouseEvent | IPoint | null): void {
private _setTargetWindowAndElement(target: Element | string | MouseEvent | IPoint | null): void {
if (target) {
if (typeof target === 'string') {
const currentDoc: Document = getDocument()!;
this._target = currentDoc ? currentDoc.querySelector(target) as HTMLElement : null;
this._target = currentDoc ? currentDoc.querySelector(target) as Element : null;
this._targetWindow = getWindow()!;
} else if ((target as MouseEvent).stopPropagation) {
this._targetWindow = getWindow((target as MouseEvent).toElement as HTMLElement)!;
this._target = target;
} else if ((target as HTMLElement).getBoundingClientRect) {
const targetElement: HTMLElement = target as HTMLElement;
} else if ((target as Element).getBoundingClientRect) {
const targetElement: Element = target as Element;
this._targetWindow = getWindow(targetElement)!;
this._target = target;
// HTMLImgElements can have x and y values. The check for it being a point must go last.
Expand Down Expand Up @@ -415,7 +415,7 @@ export class CalloutContentBase extends BaseComponent<ICalloutProps, ICalloutSta
}
}

private _getTarget(props: ICalloutProps = this.props): HTMLElement | string | MouseEvent | IPoint | null {
private _getTarget(props: ICalloutProps = this.props): Element | string | MouseEvent | IPoint | null {
const { useTargetPoint, targetPoint, target } = props;
return useTargetPoint ? targetPoint! : target!;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ export interface IContextualMenuState {
expandedMenuItemKey?: string;
dismissedMenuItemKey?: string;
contextualMenuItems?: IContextualMenuItem[];
contextualMenuTarget?: HTMLElement;
submenuTarget?: HTMLElement;
contextualMenuTarget?: Element;
submenuTarget?: Element;
positions?: any;
slideDirectionalClassName?: string;
subMenuId?: string;
Expand Down Expand Up @@ -93,7 +93,7 @@ export class ContextualMenu extends BaseComponent<IContextualMenuProps, IContext
private _isFocusingPreviousElement: boolean;
private _enterTimerId: number | undefined;
private _targetWindow: Window;
private _target: HTMLElement | MouseEvent | IPoint | null;
private _target: Element | MouseEvent | IPoint | null;
private _classNames: IContextualMenuClassNames;
private _isScrollIdle: boolean;
private readonly _scrollIdleDelay: number = 250 /* ms */;
Expand Down Expand Up @@ -926,11 +926,11 @@ export class ContextualMenu extends BaseComponent<IContextualMenuProps, IContext
}
}

private _setTargetWindowAndElement(target: HTMLElement | string | MouseEvent | IPoint): void {
private _setTargetWindowAndElement(target: Element | string | MouseEvent | IPoint): void {
if (target) {
if (typeof target === 'string') {
const currentDoc: Document = getDocument()!;
this._target = currentDoc ? currentDoc.querySelector(target) as HTMLElement : null;
this._target = currentDoc ? currentDoc.querySelector(target) as Element : null;
this._targetWindow = getWindow()!;
} else if ((target as MouseEvent).stopPropagation) {
this._targetWindow = getWindow((target as MouseEvent).toElement as HTMLElement)!;
Expand All @@ -939,7 +939,7 @@ export class ContextualMenu extends BaseComponent<IContextualMenuProps, IContext
this._targetWindow = getWindow()!;
this._target = target;
} else {
const targetElement: HTMLElement = target as HTMLElement;
const targetElement: Element = target as Element;
this._targetWindow = getWindow(targetElement)!;
this._target = target;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ export interface IContextualMenuProps extends React.Props<ContextualMenu>, IWith

/**
* The target that the ContextualMenu should try to position itself based on.
* It can be either an HTMLElement a querySelector string of a valid HTMLElement
* It can be either an Element a querySelector string of a valid Element
* or a MouseEvent. If MouseEvent is given then the origin point of the event will be used.
*/
target?: HTMLElement | string | MouseEvent | IPoint | null;
target?: Element | string | MouseEvent | IPoint | null;

/**
* How the element should be positioned
Expand Down Expand Up @@ -227,8 +227,8 @@ export interface IContextualMenuProps extends React.Props<ContextualMenu>, IWith
* @default ContextualMenuItem
*/
contextualMenuItemAs?:
React.ComponentClass<IContextualMenuItemProps> |
React.StatelessComponent<IContextualMenuItemProps>;
React.ComponentClass<IContextualMenuItemProps> |
React.StatelessComponent<IContextualMenuItemProps>;

/**
* Props to pass down to the FocusZone.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ export namespace positioningFunctions {
): IPartialIRectangle {
const returnValue: IPartialIRectangle = {};

const hostRect: Rectangle = _getRectangleFromHTMLElement(hostElement);
const hostRect: Rectangle = _getRectangleFromElement(hostElement);
const elementEdge = targetEdge * -1;
const elementEdgeString = RectangleEdge[elementEdge];
const returnEdge = alignmentEdge ? alignmentEdge : _getFlankingEdges(targetEdge).positiveEdge;
Expand Down Expand Up @@ -566,7 +566,7 @@ export namespace positioningFunctions {
return beakPositon;
}

export function _getRectangleFromHTMLElement(element: HTMLElement): Rectangle {
export function _getRectangleFromElement(element: Element): Rectangle {
const clientRect: ClientRect = element.getBoundingClientRect();

return new Rectangle(clientRect.left, clientRect.right, clientRect.top, clientRect.bottom);
Expand All @@ -576,14 +576,14 @@ export namespace positioningFunctions {
return new Rectangle(rect.left, rect.right, rect.top, rect.bottom);
}

export function _getTargetRect(bounds: Rectangle, target: HTMLElement | MouseEvent | IPoint | undefined) {
export function _getTargetRect(bounds: Rectangle, target: Element | MouseEvent | IPoint | undefined) {
let targetRectangle: Rectangle;
if (target) {
if ((target as MouseEvent).preventDefault) {
const ev = target as MouseEvent;
targetRectangle = new Rectangle(ev.clientX, ev.clientX, ev.clientY, ev.clientY);
} else if ((target as HTMLElement).getBoundingClientRect) {
targetRectangle = _getRectangleFromHTMLElement(target as HTMLElement);
} else if ((target as Element).getBoundingClientRect) {
targetRectangle = _getRectangleFromElement(target as Element);
// HTMLImgElements can have x and y values. The check for it being a point must go last.
} else {
const point: IPoint = target as IPoint;
Expand Down Expand Up @@ -646,7 +646,7 @@ export namespace positioningFunctions {
boundingRect,
props.coverTarget);
const positionedElement: IElementPosition = _positionElementWithinBounds(
_getRectangleFromHTMLElement(elementToPosition),
_getRectangleFromElement(elementToPosition),
targetRect,
boundingRect,
positionData,
Expand Down Expand Up @@ -762,9 +762,9 @@ export function positionCallout(props: IPositionProps,
* of the target given.
* If no bounds are provided then the window is treated as the bounds.
*/
export function getMaxHeight(target: HTMLElement | MouseEvent | IPoint, targetEdge: DirectionalHint, gapSpace: number = 0, bounds?: IRectangle) {
export function getMaxHeight(target: Element | MouseEvent | IPoint, targetEdge: DirectionalHint, gapSpace: number = 0, bounds?: IRectangle) {
const mouseTarget: MouseEvent = target as MouseEvent;
const elementTarget: HTMLElement = target as HTMLElement;
const elementTarget: Element = target as Element;
const pointTarget: IPoint = target as IPoint;
let targetRect: Rectangle;
const boundingRectangle = bounds ?
Expand All @@ -776,7 +776,7 @@ export function getMaxHeight(target: HTMLElement | MouseEvent | IPoint, targetEd
} else if (pointTarget.x !== undefined && pointTarget.y !== undefined) {
targetRect = new Rectangle(pointTarget.x, pointTarget.x, pointTarget.y, pointTarget.y);
} else {
targetRect = positioningFunctions._getRectangleFromHTMLElement(elementTarget);
targetRect = positioningFunctions._getRectangleFromElement(elementTarget);
}

return positioningFunctions._getMaxHeightFromTargetRectangle(targetRect, targetEdge, gapSpace, boundingRectangle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export enum Position {
end = 3
}
export interface IPositionProps {
target?: HTMLElement | MouseEvent | IPoint;
target?: Element | MouseEvent | IPoint;
/** how the element should be positioned */
directionalHint?: DirectionalHint;
/**
Expand Down
2 changes: 1 addition & 1 deletion packages/utilities/src/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ export function setSSR(isEnabled: boolean): void {
*
* @public
*/
export function getWindow(rootElement?: HTMLElement): Window | undefined {
export function getWindow(rootElement?: Element): Window | undefined {
if (_isSSR || typeof window === 'undefined') {
return undefined;
} else {
Expand Down