diff --git a/common/changes/office-ui-fabric-react/auto-select_2018-05-18-15-47.json b/common/changes/office-ui-fabric-react/auto-select_2018-05-18-15-47.json new file mode 100644 index 0000000000000..f728790044206 --- /dev/null +++ b/common/changes/office-ui-fabric-react/auto-select_2018-05-18-15-47.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "office-ui-fabric-react", + "comment": "Pass SelectionZone props through DetailsList and add alternate data-selection-auto-selection attribute name", + "type": "minor" + } + ], + "packageName": "office-ui-fabric-react", + "email": "tmichon@microsoft.com" +} \ No newline at end of file diff --git a/packages/office-ui-fabric-react/src/components/DetailsList/DetailsList.tsx b/packages/office-ui-fabric-react/src/components/DetailsList/DetailsList.tsx index fed14e68c8657..dd157edca88fd 100644 --- a/packages/office-ui-fabric-react/src/components/DetailsList/DetailsList.tsx +++ b/packages/office-ui-fabric-react/src/components/DetailsList/DetailsList.tsx @@ -277,6 +277,7 @@ export class DetailsList extends BaseComponent { groups ? ( , IWithViewpo **/ selectionPreservedOnEmptyClick?: boolean; + /** + * Addition props to pass through to the selection zone created by default. + */ + selectionZoneProps?: ISelectionZoneProps; + /** Controls how the columns are adjusted. */ layoutMode?: DetailsListLayoutMode; diff --git a/packages/office-ui-fabric-react/src/utilities/selection/SelectionZone.test.tsx b/packages/office-ui-fabric-react/src/utilities/selection/SelectionZone.test.tsx index 4f7b3f70fab43..fe5ca35a57616 100644 --- a/packages/office-ui-fabric-react/src/utilities/selection/SelectionZone.test.tsx +++ b/packages/office-ui-fabric-react/src/utilities/selection/SelectionZone.test.tsx @@ -241,10 +241,15 @@ describe('SelectionZone', () => { expect(_selection.isIndexSelected(1)).toEqual(false); }); - it('select an item when a button is clicked that has data-selection-select', () => { + it('selects an item when a button is clicked that has data-selection-select', () => { ReactTestUtils.Simulate.mouseDown(_select1); expect(_selection.isIndexSelected(1)).toEqual(true); }); + + it('selects an item when a button is clicked that has data-selection-select', () => { + ReactTestUtils.Simulate.keyDown(_select1, { which: KeyCodes.enter }); + expect(_selection.isIndexSelected(1)).toEqual(true); + }); }); function _simulateClick(el: Element, eventData?: ReactTestUtils.SyntheticEventData): void { diff --git a/packages/office-ui-fabric-react/src/utilities/selection/SelectionZone.tsx b/packages/office-ui-fabric-react/src/utilities/selection/SelectionZone.tsx index ee3229566fcdf..dee94139101b8 100644 --- a/packages/office-ui-fabric-react/src/utilities/selection/SelectionZone.tsx +++ b/packages/office-ui-fabric-react/src/utilities/selection/SelectionZone.tsx @@ -196,7 +196,8 @@ export class SelectionZone extends BaseComponent { break; } else if (this._hasAttribute(target, SELECTION_INVOKE_ATTRIBUTE_NAME)) { break; - } else if ((target === itemRoot || this._hasAttribute(target, SELECTION_SELECT_ATTRIBUTE_NAME)) + } else if ( + (target === itemRoot || this._shouldAutoSelect(target)) && !this._isShiftPressed && !this._isCtrlPressed) { this._onInvokeMouseDown(ev, this._getItemIndex(itemRoot)); break; @@ -376,6 +377,11 @@ export class SelectionZone extends BaseComponent { // For toggle elements, assuming they are rendered as buttons, they will generate a click event, // so we can no-op for any keydowns in this case. break; + } else if (this._shouldAutoSelect(target)) { + // If the event went to an element which should trigger auto-select, select it and then let + // the default behavior kick in. + this._onInvokeMouseDown(ev, index); + break; } else if ((ev.which === KeyCodes.enter || ev.which === KeyCodes.space) && (target.tagName === 'BUTTON' || target.tagName === 'A' || target.tagName === 'INPUT')) { return false; @@ -441,7 +447,10 @@ export class SelectionZone extends BaseComponent { } private _onInvokeClick(ev: React.MouseEvent | React.KeyboardEvent, index: number): void { - const { selection, onItemInvoked } = this.props; + const { + selection, + onItemInvoked + } = this.props; if (onItemInvoked) { onItemInvoked(selection.getItems()[index], index, ev.nativeEvent); @@ -540,6 +549,10 @@ export class SelectionZone extends BaseComponent { return Number(itemRoot.getAttribute(SELECTION_INDEX_ATTRIBUTE_NAME)); } + private _shouldAutoSelect(element: HTMLElement): boolean { + return this._hasAttribute(element, SELECTION_SELECT_ATTRIBUTE_NAME); + } + private _hasAttribute(element: HTMLElement, attributeName: string): boolean { let isToggle = false;