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": "FocusZone: updating to update alignment on click.",
"type": "patch"
}
],
"packageName": "office-ui-fabric-react",
"email": "jolore@microsoft.com"
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ exports[`CommandBar renders commands correctly 1`] = `
flex-grow: 1;
}
data-focuszone-id="FocusZone0"
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseDownCapture={[Function]}
Expand Down Expand Up @@ -286,6 +287,7 @@ exports[`CommandBar renders commands correctly 1`] = `
flex-shrink: 0;
}
data-focuszone-id="FocusZone7"
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseDownCapture={[Function]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ exports[`Breadcrumb renders breadcumb correctly 1`] = `
aria-labelledby={undefined}
className="ms-FocusZone"
data-focuszone-id="FocusZone0"
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseDownCapture={[Function]}
Expand Down Expand Up @@ -171,6 +172,7 @@ exports[`Breadcrumb renders breadcumb correctly 2`] = `
aria-labelledby={undefined}
className="ms-FocusZone"
data-focuszone-id="FocusZone5"
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseDownCapture={[Function]}
Expand Down Expand Up @@ -380,6 +382,7 @@ exports[`Breadcrumb renders breadcumb correctly 3`] = `
aria-labelledby={undefined}
className="ms-FocusZone"
data-focuszone-id="FocusZone11"
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseDownCapture={[Function]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ exports[`Calendar Test rendering simplest calendar Renders simple calendar corre
aria-labelledby={undefined}
className="ms-FocusZone"
data-focuszone-id="FocusZone12"
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseDownCapture={[Function]}
Expand Down Expand Up @@ -958,6 +959,7 @@ exports[`Calendar Test rendering simplest calendar Renders simple calendar corre
aria-labelledby={undefined}
className="ms-FocusZone"
data-focuszone-id="FocusZone13"
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseDownCapture={[Function]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ exports[`CommandBar renders CommandBar correctly 1`] = `
aria-labelledby={undefined}
className="ms-FocusZone"
data-focuszone-id="FocusZone1"
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseDownCapture={[Function]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ exports[`DetailsHeader can render 1`] = `
className="ms-FocusZone ms-DetailsHeader"
data-automationid="DetailsHeader"
data-focuszone-id="FocusZone1"
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseDownCapture={[Function]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ exports[`DetailsList renders List correctly 1`] = `
className="ms-FocusZone ms-DetailsHeader"
data-automationid="DetailsHeader"
data-focuszone-id="FocusZone1"
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseDownCapture={[Function]}
Expand Down Expand Up @@ -203,6 +204,7 @@ exports[`DetailsList renders List correctly 1`] = `
className="ms-FocusZone"
data-focuszone-id="FocusZone2"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseDownCapture={[Function]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ exports[`Facepile renders Facepile correctly 1`] = `
aria-labelledby={undefined}
className="ms-FocusZone ms-Facepile-members"
data-focuszone-id="FocusZone1"
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseDownCapture={[Function]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,87 @@ describe('FocusZone', () => {
expect(lastFocusedElement).toBe(buttonA);
});

it('click resets focus alignment when bidirectional', () => {
const component = ReactTestUtils.renderIntoDocument(
<div { ...{ onFocusCapture: _onFocus } }>
<FocusZone>
<button className='a'>a</button>
<button className='b'>b</button>
<button className='c'>c</button>
<button className='d'>d</button>
</FocusZone>
</div>
);

const focusZone = ReactDOM.findDOMNode(component as React.ReactInstance).firstChild as Element;
const buttonA = focusZone.querySelector('.a') as HTMLElement;
const buttonB = focusZone.querySelector('.b') as HTMLElement;
const buttonC = focusZone.querySelector('.c') as HTMLElement;
const buttonD = focusZone.querySelector('.d') as HTMLElement;

// Set up a grid like so:
// A B
// C D
setupElement(buttonA, {
clientRect: {
top: 0,
bottom: 20,
left: 0,
right: 20
}
});

setupElement(buttonB, {
clientRect: {
top: 0,
bottom: 20,
left: 20,
right: 40
}
});

setupElement(buttonC, {
clientRect: {
top: 20,
bottom: 40,
left: 0,
right: 20
}
});

setupElement(buttonD, {
clientRect: {
top: 20,
bottom: 40,
left: 20,
right: 40
}
});

// Focus the first button.
ReactTestUtils.Simulate.focus(buttonA);
expect(lastFocusedElement).toBe(buttonA);

// Clicking on b should focus b, and reset the focus alignment to the second column
// note that a click in a browser fires mouseDown, focus, then click events
ReactTestUtils.Simulate.focus(buttonB);
ReactTestUtils.Simulate.click(buttonB);
expect(lastFocusedElement).toBe(buttonB);

// Pressing down should go to d.
ReactTestUtils.Simulate.keyDown(focusZone, { which: KeyCodes.down });
expect(lastFocusedElement).toBe(buttonD);

// Clicking on c should focus c, and reset the focus alignment to the first column
ReactTestUtils.Simulate.focus(buttonC);
ReactTestUtils.Simulate.click(buttonC);
expect(lastFocusedElement).toBe(buttonC);

// Pressing up should go to a.
ReactTestUtils.Simulate.keyDown(focusZone, { which: KeyCodes.up });
expect(lastFocusedElement).toBe(buttonA);
});

it('correctly skips data-not-focusable elements', () => {
const component = ReactTestUtils.renderIntoDocument(
<div { ...{ onFocusCapture: _onFocus } }>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ export class FocusZone extends BaseComponent<IFocusZoneProps, {}> implements IFo
aria-describedby={ ariaDescribedBy }
onKeyDown={ this._onKeyDown }
onFocus={ this._onFocus }
onClick={ this._onClick }
onMouseDownCapture={ this._onMouseDown }
>
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.

can you add a test case to capture this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

added to FocusZone.test.tsx

{ this.props.children }
Expand Down Expand Up @@ -212,23 +213,34 @@ export class FocusZone extends BaseComponent<IFocusZoneProps, {}> implements IFo
private _onFocus = (ev: React.FocusEvent<HTMLElement>): void => {
const { onActiveElementChanged } = this.props;

if (this._isImmediateDescendantOfZone(ev.target as HTMLElement)) {
this._activeElement = ev.target as HTMLElement;
this._setFocusAlignment(this._activeElement);
this._setTargetElement(ev.target, false);
if (onActiveElementChanged) {
onActiveElementChanged(this._activeElement as HTMLElement, ev);
}
}

private _onClick = (ev: React.MouseEvent<HTMLElement>): void => {
this._setTargetElement(ev.target, true);
}

private _setTargetElement = (target: EventTarget, forceUpdateAlignment?: boolean): void => {
const { onActiveElementChanged } = this.props;

if (this._isImmediateDescendantOfZone(target as HTMLElement)) {
this._activeElement = target as HTMLElement;
this._setFocusAlignment(this._activeElement, forceUpdateAlignment, forceUpdateAlignment);
} else {
let parentElement = ev.target as HTMLElement;
let parentElement = target as HTMLElement;

while (parentElement && parentElement !== this._root.value) {
if (isElementTabbable(parentElement) && this._isImmediateDescendantOfZone(parentElement)) {
this._activeElement = parentElement;
this._setFocusAlignment(this._activeElement, forceUpdateAlignment, forceUpdateAlignment);
break;
}
parentElement = getParent(parentElement, ALLOW_VIRTUAL_ELEMENTS) as HTMLElement;
}
}
if (onActiveElementChanged) {
onActiveElementChanged(this._activeElement as HTMLElement, ev);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ exports[`Nav renders Nav correctly 1`] = `
aria-labelledby={undefined}
className="ms-FocusZone"
data-focuszone-id="FocusZone0"
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseDownCapture={[Function]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ exports[`Pivot renders Pivot correctly 1`] = `
aria-labelledby={undefined}
className="ms-FocusZone"
data-focuszone-id="FocusZone1"
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseDownCapture={[Function]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ exports[`Rating Renders Rating correctly 1`] = `
}
data-focuszone-id="FocusZone2"
data-is-focusable={false}
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseDownCapture={[Function]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ exports[`SwatchColorPicker renders SwatchColorPicker correctly 1`] = `
}
data-focuszone-id="FocusZone3"
onBlur={[Function]}
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseDownCapture={[Function]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ exports[`Pickers BasePicker renders BasePicker correctly 1`] = `
aria-labelledby={undefined}
className="ms-FocusZone"
data-focuszone-id="FocusZone0"
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseDownCapture={[Function]}
Expand Down Expand Up @@ -77,6 +78,7 @@ exports[`Pickers TagPicker renders TagPicker correctly 1`] = `
aria-labelledby={undefined}
className="ms-FocusZone"
data-focuszone-id="FocusZone17"
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseDownCapture={[Function]}
Expand Down