Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
a8e4cc3
Copy Overflow Code into branch
micahgodbolt Apr 17, 2017
7345c8c
Adding focus zone around overflow set
micahgodbolt Apr 17, 2017
c3ff083
Updated docs and icon props
micahgodbolt Apr 17, 2017
62a5469
Adding change file
micahgodbolt Apr 17, 2017
eb237c8
Update OverflowSet.Props.ts
micahgodbolt Apr 18, 2017
9de2ec2
Improve prop comments
micahgodbolt Apr 18, 2017
d54c5c6
Fixed merge conflict
micahgodbolt Apr 18, 2017
228ddd1
Merge branch 'master' into overflow-set
micahgodbolt Apr 18, 2017
cd011db
Fixed a few PR requests
micahgodbolt Apr 18, 2017
1085601
Merge branch 'overflow-set' of https://github.com/micahgodbolt/office…
micahgodbolt Apr 18, 2017
850c74a
Fixed overflow icon styles
micahgodbolt Apr 18, 2017
8155ef5
Created an IOverflowItemProps
micahgodbolt Apr 18, 2017
e296f1a
Merge branch 'master' into overflow-set
micahgodbolt Apr 18, 2017
e8e30c0
Merge branch 'master' into overflow-set
micahgodbolt Apr 20, 2017
458ad1f
Merge branch 'master' into overflow-set
micahgodbolt Apr 21, 2017
c81f76e
Merge branch 'master' into overflow-set
micahgodbolt Apr 21, 2017
ac1cb5e
Merge branch 'master' into overflow-set
micahgodbolt Apr 24, 2017
b526d40
Merge branch 'master' into overflow-set
micahgodbolt Apr 25, 2017
7e74eef
Merge branch 'master' into overflow-set
micahgodbolt Apr 25, 2017
fe718e3
Updated buttons to accept ClassNames, changed overflowset to use defa…
micahgodbolt Apr 25, 2017
6d9fd0f
Merge branch 'overflow-set' of https://github.com/micahgodbolt/office…
micahgodbolt Apr 25, 2017
a887b22
Merge branch 'master' into overflow-set
micahgodbolt Apr 25, 2017
82a4188
Merge branch 'master' into overflow-set
micahgodbolt Apr 26, 2017
2eab455
Merge branch 'master' into overflow-set
micahgodbolt Apr 26, 2017
fd424b4
Updated example to be more actual use case
micahgodbolt Apr 26, 2017
8f35a16
Merge branch 'overflow-set' of https://github.com/micahgodbolt/office…
micahgodbolt Apr 26, 2017
8d7bc00
Removed default overflow button render as each one will certainly be …
micahgodbolt Apr 26, 2017
e7b86db
Fixed linting errors
micahgodbolt Apr 26, 2017
82c5b6d
Merge branch 'master' into overflow-set
micahgodbolt Apr 26, 2017
988e0c7
Merge branch 'master' into overflow-set
micahgodbolt Apr 27, 2017
c0884d9
Changed onRenderOverfowButton to be of type IButtonProps for better c…
micahgodbolt Apr 27, 2017
198e3ae
Merge branch 'overflow-set' of https://github.com/micahgodbolt/office…
micahgodbolt Apr 27, 2017
2520d1d
Update button assign to mix props into empty object
micahgodbolt Apr 27, 2017
d9ba936
Moved custom onRender to the custom example. Created basic example wi…
micahgodbolt Apr 27, 2017
d57593a
Moved class props into button props file
micahgodbolt Apr 27, 2017
ac26ad3
Commented out overflow set index.ts to keep hidden for now
micahgodbolt Apr 27, 2017
e8eff9c
Fix documentation and added key back to onRenderItems
micahgodbolt Apr 28, 2017
473c484
Fixed linting errors
micahgodbolt Apr 28, 2017
78275f9
Merge branch 'master' into overflow-set
micahgodbolt Apr 28, 2017
35f9325
Merge branch 'master' into overflow-set
micahgodbolt May 1, 2017
bb54cbd
Merge branch 'overflow-set' of https://github.com/micahgodbolt/office…
micahgodbolt May 1, 2017
e8c2960
Revert button changes
micahgodbolt May 1, 2017
6d424e3
updated example and items type
micahgodbolt May 1, 2017
038b3f7
Updated dropdown to have defaultText
micahgodbolt May 2, 2017
edb0ec5
Added change file
micahgodbolt May 2, 2017
a72004f
Merge branch 'master' of https://github.com/OfficeDev/office-ui-fabri…
micahgodbolt May 3, 2017
30c1a74
Merge branch 'master' into overflow-set
micahgodbolt May 3, 2017
501956d
Merge master
micahgodbolt May 3, 2017
8f64dec
Update master_2017-05-02-22-52.json
micahgodbolt May 3, 2017
2e4df29
Merge branch 'master' into overflow-set
micahgodbolt May 3, 2017
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
1 change: 1 addition & 0 deletions common/changes/master_2017-05-02-22-52.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
],
"email": "micahgodbolt@gmail.com"
}

10 changes: 10 additions & 0 deletions common/changes/overflow-set_2017-04-17-21-47.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "office-ui-fabric-react",
"comment": "OverflowSet: New Overflow Set componet to create sets of elements with overflow showing in callout",
"type": "patch"
}
],
"email": "micahgodbolt@gmail.com"
}
1 change: 1 addition & 0 deletions packages/office-ui-fabric-react/src/OverflowSet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './components/OverflowSet/index';
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as React from 'react';
import { OverflowSet } from './OverflowSet';
import { IContextualMenuItem } from '../../ContextualMenu';
import { IButtonProps } from '../../Button';
import { IRenderFunction } from '../../Utilities';
import { IObjectWithKey } from '../../Selection';

export interface IOverflowSetProps extends React.Props<OverflowSet> {

/**
* An array of items to be rendered by your onRenderItem function in the primary content area
*/
items?: any[] | IObjectWithKey[];
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.

I think all you want here is { id? : string}[]


/**
* An array of items to be passed to overflow contextual menu
*/
overflowItems?: IContextualMenuItem[];
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.

Why are the types different items vs overflow items?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

OverflowItems are meant to be rendered in a contextual menu. Of course there isn't anything stopping someone from rendering them in something else....If any[] is prefered I have no problems either way.

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.

I think contextualmenuitem already has a mechanism to render anything else inside them, so I think it is ok.


/**
* Method to call when trying to render an item.
*/
onRenderItem: IRenderFunction<any>;

/**
* Rendering method for overflow button and contextual menu.
*/
onRenderOverflowButton: IRenderFunction<IButtonProps>;
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.

I'm a little unsure about this API. We definitely want to be able to provide flexibility for rendering the overflow button, but it seems like we would have an onRenderMenuItem function for handling items in the contextual menu

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The rendering of the menu items is already handled by the contextual menu. and in fact IContextualMenuItem can accept an onRender function already.

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.

Ah I see. I guess I was expecting the API to list "top level controls" and "overflow controls" in a similar manner. But given the existing mechanism for overriding menu items in contextualmenuitem, this seems to make sense and also allows customization of the button itself.

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@import '../../common/common';

.root {
position: relative;
display: flex;
flex-wrap: nowrap;
}

.item {
flex-shrink: 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import * as React from 'react';
import {
css,
autobind,
BaseComponent
} from '../../Utilities';
import { IButtonProps } from '../../Button';
import { IOverflowSetProps } from './OverflowSet.Props';
import { FocusZone, FocusZoneDirection } from '../../FocusZone';

import * as stylesImport from './OverflowSet.scss';
const styles: any = stylesImport;

export class OverflowSet extends BaseComponent<IOverflowSetProps, null> {

public render() {
let {
items,
overflowItems,
onRenderOverflowButton
} = this.props;

const overflowButtonProps: IButtonProps = {
menuProps: { items: overflowItems }
};

return (
<FocusZone className={ css('ms-OverflowSet', styles.root) } direction={ FocusZoneDirection.horizontal } role='menubar' >
{ items && this._onRenderItems(items) }
{ overflowItems.length && onRenderOverflowButton(overflowButtonProps) }
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.

No default value here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

What do you mean by default value?

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.

For the onrenderoverflowbutton? I guess it makes sense given your other comment regarding how overflow items are rendered.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah, i had a default button at one time, but what does the button look like? Hover/active/selected? I'm expecting each user will customize the button to their use case. A default button wouldn't serve much purpose unless we determined what the default usecase was.

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.

Seems reasonable, we can add it later if there is a "common" button that arises

</FocusZone>
);
}

@autobind
private _onRenderItems(items: any[]): JSX.Element[] {
return items.map((item, i) => {
let key = item.key ? item.key : i;
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.

The props definition should say that items can take a key. It might even be worth explicitly stating this in the type definition instead of just putting any (though not sure how to best do that, maybe an intersection type?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I can do this in the prop items?: any[] | { key: string }[];

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Not sure if this really solves it though. Basically it's either anything, or just a key. Unless I don't understand intersection properly.

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.

You actually probably don't need an intersection, you can just say items?: {key?: string} []. You can assign anything to that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

items?: {key?: string} [] would mean that [{key: foo, bar: baz}] would be invalid. I can either specify no props or all of the props.

image

return (
<div key={ key } className={ css('ms-OverflowSet-item', styles.item) }>
{ this.props.onRenderItem(item) }
</div>
);
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as React from 'react';
import { Link } from 'office-ui-fabric-react/lib/Link';
import { LayerHost } from 'office-ui-fabric-react/lib/Layer';
import {
ExampleCard,
ComponentPage,
PropertiesTableSet
} from '@uifabric/example-app-base';
import { OverflowSetCustomExample } from './examples/OverflowSet.Custom.Example';
import { OverflowSetBasicExample } from './examples/OverflowSet.Basic.Example';

const OverflowSetCustomExampleCode = require('!raw-loader!office-ui-fabric-react/src/components/OverflowSet/examples/OverflowSet.Custom.Example.tsx') as string;
const OverflowSetBasicExampleCode = require('!raw-loader!office-ui-fabric-react/src/components/OverflowSet/examples/OverflowSet.Basic.Example.tsx') as string;

export class OverflowSetPage extends React.Component<any, any> {
public render() {
return (
<ComponentPage
title='OverflowSet'
componentName='OverflowSetExample'
overview={
<div>
<p>
The OverflowSet is a flexible container component that is useful for displaying a primary set of content with additional content in an overflow callout.
Note that the example below is only an example of how to render the component, not a specific use case.
</p>
</div>
}
exampleCards={
<LayerHost>
<ExampleCard title='OverflowSet Basic Example' code={ OverflowSetBasicExampleCode }>
<OverflowSetBasicExample />
</ExampleCard>
<ExampleCard title='OverflowSet Custom Example' code={ OverflowSetCustomExampleCode }>
<OverflowSetCustomExample />
</ExampleCard>
</LayerHost>
}
propertiesTables={
<PropertiesTableSet
sources={ [
require<string>('!raw-loader!office-ui-fabric-react/src/components/OverflowSet/OverflowSet.Props.ts')
] }
/>
}
/>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* tslint:disable:no-unused-variable */
import * as React from 'react';
/* tslint:enable:no-unused-variable */
import { BaseComponent, css } from 'office-ui-fabric-react/lib/Utilities';
import { IconButton } from 'office-ui-fabric-react/lib/Button';
import { Link } from 'office-ui-fabric-react/lib/Link';
import {
OverflowSet
} from 'office-ui-fabric-react/lib/OverflowSet';

import * as stylesImport from './OverflowSet.Example.scss';
const styles: any = stylesImport;

export class OverflowSetBasicExample extends BaseComponent<any, any> {

public render() {
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.

Maybe you should keep the basic example basic and have a "customized" example to customized. Reading the docs this is basically a for loop on items to render them as a given thing, with a menuProps.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Sounds good.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

this is done

return (
<OverflowSet
items={ [
{
key: 'item1',
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.

How come these aren't being used in the overflow set?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

fixed

name: 'Link 1',
ariaLabel: 'New. Use left and right arrow keys to navigate',
onClick: () => { return; },
},
{
key: 'item2',
name: 'Link 2',
onClick: () => { return; },
},
{
key: 'item3',
name: 'Link 3',
onClick: () => { return; }
}
] }
overflowItems={ [
{
key: 'item4',
name: 'Overflow Link 1',
onClick: () => { return; }
},
{
key: 'item5',
name: 'Overflow Link 2',
onClick: () => { return; }
}
]
}
onRenderOverflowButton={ (buttonProps) => {
return (
<IconButton
className={ css(styles.overflowButton) }
iconProps={ { iconName: 'More' } }
menuIconProps={ null }
menuProps={ buttonProps.menuProps }
/>
);
} }
onRenderItem={ (item) => {
return (
<Link
className={ css(styles.overflowLinks) }
onClick={ item.onClick }
>{ item.name }</Link>
);
} }
/>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/* tslint:disable:no-unused-variable */
import * as React from 'react';
/* tslint:enable:no-unused-variable */
import { BaseComponent, css } from 'office-ui-fabric-react/lib/Utilities';
import { DefaultButton } from 'office-ui-fabric-react/lib/Button';
import { SearchBox } from 'office-ui-fabric-react/lib/SearchBox';
import {
OverflowSet
} from 'office-ui-fabric-react/lib/OverflowSet';

import * as stylesImport from './OverflowSet.Example.scss';
const styles: any = stylesImport;

export class OverflowSetCustomExample extends BaseComponent<any, any> {

public render() {
return (
<OverflowSet
items={ [
{
key: 'search',
'onRender': (item) => {
return (
<SearchBox
labelText='Search'
/>
);
}
},
{
key: 'newItem',
name: 'New',
icon: 'Add',
ariaLabel: 'New. Use left and right arrow keys to navigate',
onClick: () => { return; },
subMenuProps: {
items: [
{
key: 'emailMessage',
name: 'Email message',
icon: 'Mail',
},
{
key: 'calendarEvent',
name: 'Calendar event',
icon: 'Calendar'
}
],
},
},
{
key: 'upload',
name: 'Upload',
icon: 'Upload',
onClick: () => { return; },
},
{
key: 'share',
name: 'Share',
icon: 'Share',
onClick: () => { return; }
}
] }
overflowItems={ [
{
key: 'newItem',
name: 'Add',
icon: 'Add',
ariaLabel: 'New. Use left and right arrow keys to navigate',
onClick: () => { return; },
subMenuProps: {
items: [
{
key: 'emailMessage',
name: 'Email message',
icon: 'Mail',
},
{
key: 'calendarEvent',
name: 'Calendar event',
icon: 'Calendar'
}
],
},
},
{
key: 'move',
name: 'Move to...',
icon: 'MoveToFolder',
onClick: () => { return; }
},
{
key: 'copy',
name: 'Copy to...',
icon: 'Copy',
onClick: () => { return; }
},
{
key: 'rename',
name: 'Rename...',
icon: 'Edit',
onClick: () => { return; }
},
{
key: 'disabled',
name: 'Disabled...',
icon: 'Cancel',
disabled: true,
onClick: () => { return; }
}
]
}
onRenderOverflowButton={ (buttonProps) => {
return (
<DefaultButton
className={ css(styles.overflowButton) }
iconProps={ { iconName: 'More' } }
menuIconProps={ null }
menuProps={ buttonProps.menuProps }
/>
);
} }
onRenderItem={ (item) => {
if (item.onRender) {
return (
item.onRender(item)
);
}
return (
<DefaultButton
iconProps={ { iconName: item.icon } }
menuProps={ item.subMenuProps }
text={ item.name }
> </DefaultButton>
);
} }
/>
);
}
}
Loading