Skip to content
Merged
Show file tree
Hide file tree
Changes from 36 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
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
Expand Up @@ -13,49 +13,23 @@ import {
import { Icon, IIconProps } from '../../Icon';
import { DirectionalHint } from '../../common/DirectionalHint';
import { ContextualMenu, IContextualMenuProps } from '../../ContextualMenu';
import { IButtonProps, IButton } from './Button.Props';
import { IButtonProps, IButton, IButtonClassNames } from './Button.Props';
import * as stylesImport from './BaseButton.scss';
const styles: any = stylesImport;

export interface IButtonClassNames {
base?: string;
variant?: string;
isDisabled?: string;
isEnabled?: string;
description?: string;
flexContainer?: string;
icon?: string;
menuIcon?: string;
label?: string;
root?: string;
}

/**
* These props are not in the Props file as they are undocumented props only specific to BaseButton.
*
* @export
* @interface IBaseButtonProps
* @extends {IButtonProps}
*/
export interface IBaseButtonProps extends IButtonProps {
/**
* Custom class names for individual elements within the button DOM.
*/
classNames?: IButtonClassNames;
}

export interface IBaseButtonState {
menuProps?: IContextualMenuProps | null;
}

export class BaseButton extends BaseComponent<IBaseButtonProps, IBaseButtonState> implements IButton {
export class BaseButton extends BaseComponent<IButtonProps, IBaseButtonState> implements IButton {

public static defaultProps: IBaseButtonProps = {
public static defaultProps: 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 just realized this is a really bad contract; for example, it is unclear from a user how to define the color on an icon that is disabled. We need to tweak this a bit.

Can we hold off adding something that would be deprecated fast just for a sec? Sorry, know this has been a long time.

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.

So no exposing of the IButtonClassNames or any of that? Revert all the changes on the button files?

classNames: {
base: 'ms-Button',
variant: '',
isEnabled: '',
isDisabled: ''
isDisabled: '',
isOpened: '',
}
};

Expand Down Expand Up @@ -119,7 +93,8 @@ export class BaseButton extends BaseComponent<IBaseButtonProps, IBaseButtonState
{
'disabled': disabled,
[classNames.isDisabled]: disabled,
[classNames.isEnabled]: !disabled
[classNames.isEnabled]: !disabled,
[classNames.isOpened]: this.state.menuProps !== null
}),
ref: this._resolveRef('_buttonElement'),
'disabled': disabled,
Expand Down Expand Up @@ -263,7 +238,7 @@ export class BaseButton extends BaseComponent<IBaseButtonProps, IBaseButtonState
}

return (
menuIconProps ?
menuIconProps && menuIconProps.iconName ?
<Icon
{ ...menuIconProps }
className={ css(`${classNames.base}-icon`, classNames.menuIcon, menuIconProps.className) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ export interface IButtonProps extends React.HTMLAttributes<HTMLButtonElement | H
*/
className?: string;

/**
* If provided, additional class name to provide on the root element.
*/
classNames?: IButtonClassNames;

/**
* The aria label of the button for the benefit of screen readers.
*/
Expand Down Expand Up @@ -154,3 +159,17 @@ export enum ButtonType {
icon = 5,
default = 6
}

export interface IButtonClassNames {
base?: string;

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.

We should add some comments here saying what the class names correspond to so that consumers know what class names to override when customizing button styles

variant?: string;
isDisabled?: string;
isEnabled?: string;
isOpened?: string;
description?: string;
flexContainer?: string;
icon?: string;
menuIcon?: string;
label?: string;
root?: string;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import { BaseButton, IButtonClassNames } from '../BaseButton';
import { BaseComponent, nullRender } from '../../../Utilities';
import { IButtonProps } from '../Button.Props';
import { BaseButton } from '../BaseButton';
import { BaseComponent, nullRender, assign } from '../../../Utilities';
import { IButtonProps, IButtonClassNames } from '../Button.Props';
import * as stylesImport from './CommandButton.scss';
const styles: any = stylesImport;

Expand All @@ -12,6 +12,7 @@ const CLASS_NAMES: IButtonClassNames = {
menuIcon: styles.icon,
isDisabled: styles.isDisabled,
isEnabled: styles.isEnabled,
isOpened: styles.isOpened,
label: styles.label,
root: styles.root,
flexContainer: styles.flexContainer
Expand All @@ -27,9 +28,10 @@ export class CommandButton extends BaseComponent<IButtonProps, {}> {
public render() {
return (
<BaseButton
classNames={ CLASS_NAMES }
{ ...this.props }
classNames={ assign({}, CLASS_NAMES, this.props.classNames) }

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 we use the spread operator here instead of assign?

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 assign is to allow prop classnames to override the button specific class names. i.e. I want a new .isEnabled:hover style, I can override their isEnabled with my own. And since it's css modules, even if I use the same isEnabled class name, the hash will be different.

@christiango christiango Apr 30, 2017

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.

That should still work with object spread though. They are equivalent and is more compact: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html

It would be something like this classNames = { ...CLASS_NAMES, ..this.props.classNames }

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.

Pulled this out. @dzearing is doing this using glamor, and yes, spreads.

onRenderDescription={ nullRender }
{ ...this.props } />
/>
);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import { BaseButton, IButtonClassNames } from '../BaseButton';
import { BaseComponent } from '../../../Utilities';
import { IButtonProps } from '../Button.Props';
import { BaseButton } from '../BaseButton';
import { BaseComponent, assign } from '../../../Utilities';
import { IButtonProps, IButtonClassNames } from '../Button.Props';

import * as stylesImport from './CompoundButton.scss';
const styles: any = stylesImport;
Expand All @@ -27,8 +27,8 @@ export class CompoundButton extends BaseComponent<IButtonProps, {}> {
public render() {
return (
<BaseButton
classNames={ CLASS_NAMES }
{ ...this.props }
classNames={ assign({}, CLASS_NAMES, this.props.classNames) }
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

.isEnabled {

&:hover {
&:hover, &.isOpened {
background-color: $ms-color-neutralLight;
color: $ms-color-black;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import { BaseButton, IButtonClassNames } from '../BaseButton';
import { BaseComponent, nullRender } from '../../../Utilities';
import { IButtonProps } from '../Button.Props';
import { BaseButton } from '../BaseButton';
import { BaseComponent, nullRender, assign } from '../../../Utilities';
import { IButtonProps, IButtonClassNames } from '../Button.Props';

import * as stylesImport from './DefaultButton.scss';
const styles: any = stylesImport;
Expand All @@ -13,6 +13,7 @@ export const CLASS_NAMES: IButtonClassNames = {
menuIcon: styles.icon,
isDisabled: styles.isDisabled,
isEnabled: styles.isEnabled,
isOpened: styles.isOpened,
label: styles.label,
root: styles.root
};
Expand All @@ -26,9 +27,10 @@ export class DefaultButton extends BaseComponent<IButtonProps, {}> {
public render() {
return (
<BaseButton
classNames={ CLASS_NAMES }
{ ...this.props }
classNames={ assign({}, CLASS_NAMES, this.props.classNames) }
onRenderDescription={ nullRender }
{ ...this.props } />
/>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ $button-iconButtonSize: $button-core-default-height;

.isEnabled {

&:hover {
&:hover, &.isOpened {
color: $ms-color-themeDarker;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import { BaseButton, IButtonClassNames } from '../BaseButton';
import { BaseComponent, nullRender } from '../../../Utilities';
import { IButtonProps } from '../Button.Props';
import { BaseButton } from '../BaseButton';
import { BaseComponent, nullRender, assign } from '../../../Utilities';
import { IButtonProps, IButtonClassNames } from '../Button.Props';
import * as stylesImport from './IconButton.scss';
const styles: any = stylesImport;

Expand All @@ -12,6 +12,7 @@ const CLASS_NAMES: IButtonClassNames = {
menuIcon: styles.icon,
isDisabled: styles.isDisabled,
isEnabled: styles.isEnabled,
isOpened: styles.isOpened,
root: styles.root
};

Expand All @@ -24,10 +25,11 @@ export class IconButton extends BaseComponent<IButtonProps, {}> {
public render() {
return (
<BaseButton
classNames={ CLASS_NAMES }
{ ...this.props }
classNames={ assign({}, CLASS_NAMES, this.props.classNames) }
onRenderText={ nullRender }
onRenderDescription={ nullRender }
{ ...this.props } />
/>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

.isEnabled {

&:hover {
&:hover, &.isOpened {
background-color: $ms-color-themeDark;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import { BaseComponent, nullRender } from '../../../Utilities';
import { BaseButton, IButtonClassNames } from '../BaseButton';
import { IButtonProps } from '../Button.Props';
import { BaseComponent, nullRender, assign } from '../../../Utilities';
import { BaseButton } from '../BaseButton';
import { IButtonProps, IButtonClassNames } from '../Button.Props';

import * as stylesImport from './PrimaryButton.scss';
const styles: any = stylesImport;
Expand All @@ -13,6 +13,7 @@ const CLASS_NAMES: IButtonClassNames = {
menuIcon: styles.icon,
isDisabled: styles.isDisabled,
isEnabled: styles.isEnabled,
isOpened: styles.isOpened,
label: styles.label,
root: styles.root
};
Expand All @@ -26,9 +27,9 @@ export class PrimaryButton extends BaseComponent<IButtonProps, {}> {
public render() {
return (
<BaseButton
classNames={ CLASS_NAMES }
onRenderDescription={ nullRender }
{ ...this.props }
classNames={ assign({}, CLASS_NAMES, this.props.classNames) }
onRenderDescription={ nullRender }
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as React from 'react';
import { OverflowSet } from './OverflowSet';
import { IContextualMenuItem } from '../../ContextualMenu';
import { IButtonProps } from '../../Button';
import { IRenderFunction } from '../../Utilities';

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[];

/**
* 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,45 @@
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) => {
return (
<div key={ i } className={ css('ms-OverflowSet-item', styles.item) }>

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.

This isn't a great way to assign keys since it wouldn't let React's reconciler detect reorderings and insertions/deletions. More details can be found here https://facebook.github.io/react/docs/lists-and-keys.html

Can we provide a way for the consumer to pass in a unique identifier for each item?

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 think I originally had that in the map. Let me put it back in. Look for a key and fall back to i if there is no key.

{ this.props.onRenderItem(item) }
</div>
);
});
}
}
Loading