diff --git a/common/changes/@uifabric/utilities/detailsheader-fix_2018-03-21-00-31.json b/common/changes/@uifabric/utilities/detailsheader-fix_2018-03-21-00-31.json new file mode 100644 index 0000000000000..0549f5c0b1130 --- /dev/null +++ b/common/changes/@uifabric/utilities/detailsheader-fix_2018-03-21-00-31.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@uifabric/utilities", + "comment": "EventGroup.raise: event args are now correctly mixed into the event object.", + "type": "patch" + } + ], + "packageName": "@uifabric/utilities", + "email": "dzearing@microsoft.com" +} \ No newline at end of file diff --git a/common/changes/office-ui-fabric-react/detailsheader-fix_2018-03-21-00-31.json b/common/changes/office-ui-fabric-react/detailsheader-fix_2018-03-21-00-31.json new file mode 100644 index 0000000000000..076b42db5092a --- /dev/null +++ b/common/changes/office-ui-fabric-react/detailsheader-fix_2018-03-21-00-31.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "office-ui-fabric-react", + "comment": "DetailsList: headers now resize correctly and respect maxWidth.", + "type": "patch" + } + ], + "packageName": "office-ui-fabric-react", + "email": "dzearing@microsoft.com" +} \ No newline at end of file diff --git a/packages/office-ui-fabric-react/src/components/DetailsList/DetailsHeader.test.tsx b/packages/office-ui-fabric-react/src/components/DetailsList/DetailsHeader.test.tsx new file mode 100644 index 0000000000000..de79f7f7e6add --- /dev/null +++ b/packages/office-ui-fabric-react/src/components/DetailsList/DetailsHeader.test.tsx @@ -0,0 +1,89 @@ +import * as React from 'react'; +import { DetailsHeader } from './DetailsHeader'; +import { DetailsListLayoutMode, IColumn } from './DetailsList.types'; +import { Selection, SelectionMode } from '../../utilities/selection/index'; +import { EventGroup, createRef } from '../../Utilities'; +import { mount } from 'enzyme'; +import * as renderer from 'react-test-renderer'; + +const _items: {}[] = []; +const _selection = new Selection(); +const _columns: IColumn[] = [ + { key: 'a', name: 'a', fieldName: 'a', minWidth: 200, maxWidth: 400, calculatedWidth: 200, isResizable: true }, + { key: 'b', name: 'b', fieldName: 'a', minWidth: 200, maxWidth: 400, calculatedWidth: 200, isResizable: true } +]; + +_selection.setItems(_items); + +describe('DetailsHeader', () => { + + it('can render', () => { + const component = renderer.create( + + ); + expect(component.toJSON()).toMatchSnapshot(); + }); + + it('can resize columns', () => { + let lastResize = { size: -1, index: -1 }; + + const onColumnResized = ( + column: IColumn, + size: number, + index: number + ): { size: number; index: number; } => lastResize = { size, index }; + const headerRef = createRef(); + + const columns = []; + const wrapper = mount( + + ); + + const rootElement = wrapper.getDOMNode(); + const sizerElement = wrapper.find('[data-sizer-index=0]').getDOMNode(); + const header: any = headerRef.value; + + // Trigger a mousedown, which validates that the ref to focuszone is hooking up events. + EventGroup.raise( + sizerElement, + 'mousedown', + { + clientX: 0, + button: 0 + }, + true + ); + + // Validate we go into resize mode. + expect(sizerElement.classList.contains('is-resizing')).toBe(true); + expect(!!wrapper.state().isSizing).toBe(false); + + // Mouse move 1 pixel to the right to get into sizing mode. + wrapper.simulate('mousemove', { clientX: 1 }); + expect(!!wrapper.state().isSizing).toBe(true); + + // The header is 200; move mouse 100 to the right, the header should be 300. + header._onSizerMouseMove({ clientX: 100 }); + expect(lastResize).toEqual({ index: 0, size: 300 }); + + // Mouse move 300 pixels to the right (should be capped at 400px width + header._onSizerMouseMove({ clientX: 300 }); + expect(lastResize).toEqual({ index: 0, size: 400 }); + + // Complete sizing. + header._onSizerMouseUp(); + expect(!!wrapper.state().isSizing).toBe(false); + }); +}); \ No newline at end of file diff --git a/packages/office-ui-fabric-react/src/components/DetailsList/DetailsHeader.tsx b/packages/office-ui-fabric-react/src/components/DetailsList/DetailsHeader.tsx index 66fac2d89edb4..90fc0e3968904 100644 --- a/packages/office-ui-fabric-react/src/components/DetailsList/DetailsHeader.tsx +++ b/packages/office-ui-fabric-react/src/components/DetailsList/DetailsHeader.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import { findDOMNode } from 'react-dom'; import { BaseComponent, css, @@ -9,7 +10,7 @@ import { createRef } from '../../Utilities'; import { IColumn, DetailsListLayoutMode, ColumnActionsMode } from './DetailsList.types'; -import { FocusZone, FocusZoneDirection } from '../../FocusZone'; +import { IFocusZone, FocusZone, FocusZoneDirection } from '../../FocusZone'; import { Icon } from '../../Icon'; import { Layer } from '../../Layer'; import { GroupSpacer } from '../GroupedList/GroupSpacer'; @@ -28,7 +29,7 @@ const INNER_PADDING = 16; const ISPADDED_WIDTH = 24; export interface IDetailsHeader { - focus(): boolean; + focus: () => boolean; } export interface IDetailsHeaderProps extends React.Props { @@ -81,7 +82,7 @@ export class DetailsHeader extends BaseComponent(); + private _root = createRef(); private _id: string; @@ -101,11 +102,8 @@ export class DetailsHeader extends BaseComponent +
+ + + +
+
+ + + + a + + + +
+
+
+ + + + b + + + +
+
+
+`; diff --git a/packages/utilities/src/EventGroup.ts b/packages/utilities/src/EventGroup.ts index cb8847aece11a..d86af7d05f260 100644 --- a/packages/utilities/src/EventGroup.ts +++ b/packages/utilities/src/EventGroup.ts @@ -85,8 +85,9 @@ export class EventGroup { let ev = document.createEvent('HTMLEvents'); ev.initEvent(eventName, bubbleEvent || false, true); - // tslint:disable-next-line:no-any - (ev as any)['args'] = eventArgs; + + Object.assign(ev, eventArgs); + retVal = target.dispatchEvent(ev); // tslint:disable-next-line:no-any } else if ((document as any)['createEventObject']) { // IE8