Skip to content

Commit

Permalink
Addressing regression: Callout with event as target now has less erro…
Browse files Browse the repository at this point in the history
…rs (microsoft#10696)

* Patching callout when target is an event.

* Change files
  • Loading branch information
dzearing committed Oct 3, 2019
1 parent e803299 commit fd4b79d
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"type": "minor",
"comment": "Async methods can now take a React component as the target being passed to `getWindow`.",
"packageName": "@uifabric/utilities",
"email": "dzearing@microsoft.com",
"commit": "930e9059016e06f0b7ad6b44ac7a62e094600f59",
"date": "2019-10-02T23:57:45.256Z"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"type": "minor",
"comment": "Callout: Addressing regression when target is an event.",
"packageName": "office-ui-fabric-react",
"email": "dzearing@microsoft.com",
"commit": "930e9059016e06f0b7ad6b44ac7a62e094600f59",
"date": "2019-10-02T23:57:08.150Z"
}
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ export class CalloutContentBase extends React.Component<ICalloutProps, ICalloutS
protected _setInitialFocus = (): void => {
if (this.props.setInitialFocus && !this._didSetInitialFocus && this.state.positions && this._calloutElement.current) {
this._didSetInitialFocus = true;
this._async.requestAnimationFrame(() => focusFirstChild(this._calloutElement.current!), this._target as Element);
this._async.requestAnimationFrame(() => focusFirstChild(this._calloutElement.current!), this);
}
};

Expand Down Expand Up @@ -349,7 +349,7 @@ export class CalloutContentBase extends React.Component<ICalloutProps, ICalloutS
}

private _updateAsyncPosition(): void {
this._async.requestAnimationFrame(() => this._updatePosition(), this._target as HTMLElement);
this._async.requestAnimationFrame(() => this._updatePosition(), this);
}

private _getBeakPosition(): React.CSSProperties {
Expand Down Expand Up @@ -514,30 +514,27 @@ export class CalloutContentBase extends React.Component<ICalloutProps, ICalloutS

private _setHeightOffsetEveryFrame(): void {
if (this._calloutElement.current && this.props.finalHeight) {
this._setHeightOffsetTimer = this._async.requestAnimationFrame(
() => {
const calloutMainElem = this._calloutElement.current && (this._calloutElement.current.lastChild as HTMLElement);
this._setHeightOffsetTimer = this._async.requestAnimationFrame(() => {
const calloutMainElem = this._calloutElement.current && (this._calloutElement.current.lastChild as HTMLElement);

if (!calloutMainElem) {
return;
}
if (!calloutMainElem) {
return;
}

const cardScrollHeight: number = calloutMainElem.scrollHeight;
const cardCurrHeight: number = calloutMainElem.offsetHeight;
const scrollDiff: number = cardScrollHeight - cardCurrHeight;
const cardScrollHeight: number = calloutMainElem.scrollHeight;
const cardCurrHeight: number = calloutMainElem.offsetHeight;
const scrollDiff: number = cardScrollHeight - cardCurrHeight;

this.setState({
heightOffset: this.state.heightOffset! + scrollDiff
});
this.setState({
heightOffset: this.state.heightOffset! + scrollDiff
});

if (calloutMainElem.offsetHeight < this.props.finalHeight!) {
this._setHeightOffsetEveryFrame();
} else {
this._async.cancelAnimationFrame(this._setHeightOffsetTimer, this._target as Element);
}
},
this._target as Element
);
if (calloutMainElem.offsetHeight < this.props.finalHeight!) {
this._setHeightOffsetEveryFrame();
} else {
this._async.cancelAnimationFrame(this._setHeightOffsetTimer, this._target as Element);
}
}, this);
}
}

Expand Down
8 changes: 4 additions & 4 deletions packages/utilities/etc/utilities.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ export function assign(target: any, ...args: any[]): any;
export class Async {
constructor(parent?: object, onError?: (e: any) => void);
// (undocumented)
cancelAnimationFrame(id: number, targetElement?: Element): void;
clearImmediate(id: number, targetElement?: Element): void;
cancelAnimationFrame(id: number, targetElement?: Element | Component | null): void;
clearImmediate(id: number, targetElement?: Element | Component | null): void;
clearInterval(id: number): void;
clearTimeout(id: number): void;
debounce<T extends Function>(func: T, wait?: number, options?: {
Expand All @@ -58,8 +58,8 @@ export class Async {
// (undocumented)
protected _logError(e: any): void;
// (undocumented)
requestAnimationFrame(callback: () => void, targetElement?: Element): number;
setImmediate(callback: () => void, targetElement?: Element): number;
requestAnimationFrame(callback: () => void, targetElement?: Element | Component | null): number;
setImmediate(callback: () => void, targetElement?: Element | Component | null): number;
setInterval(callback: () => void, duration: number): number;
setTimeout(callback: () => void, duration: number): number;
throttle<T extends Function>(func: T, wait?: number, options?: {
Expand Down
9 changes: 5 additions & 4 deletions packages/utilities/src/Async.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getWindow } from './dom/getWindow';
import { Component } from 'react';

declare function setTimeout(cb: Function, delay: number): number;
declare function setInterval(cb: Function, delay: number): number;
Expand Down Expand Up @@ -142,7 +143,7 @@ export class Async {
* @param targetElement - Optional target element to use for identifying the correct window.
* @returns The setTimeout id.
*/
public setImmediate(callback: () => void, targetElement?: Element): number {
public setImmediate(callback: () => void, targetElement?: Element | Component | null): number {
let immediateId = 0;
const win = getWindow(targetElement)!;

Expand Down Expand Up @@ -180,7 +181,7 @@ export class Async {
* @param id - Id to cancel.
* @param targetElement - Optional target element to use for identifying the correct window.
*/
public clearImmediate(id: number, targetElement?: Element): void {
public clearImmediate(id: number, targetElement?: Element | Component | null): void {
const win = getWindow(targetElement)!;

if (this._immediateIds && this._immediateIds[id]) {
Expand Down Expand Up @@ -445,7 +446,7 @@ export class Async {
return resultFunction;
}

public requestAnimationFrame(callback: () => void, targetElement?: Element): number {
public requestAnimationFrame(callback: () => void, targetElement?: Element | Component | null): number {
let animationFrameId = 0;
const win = getWindow(targetElement)!;

Expand Down Expand Up @@ -479,7 +480,7 @@ export class Async {
return animationFrameId;
}

public cancelAnimationFrame(id: number, targetElement?: Element): void {
public cancelAnimationFrame(id: number, targetElement?: Element | Component | null): void {
const win = getWindow(targetElement)!;

if (this._animationFrameIds && this._animationFrameIds[id]) {
Expand Down

0 comments on commit fd4b79d

Please sign in to comment.