Skip to content

Commit

Permalink
Button: Perf improvements (#9984)
Browse files Browse the repository at this point in the history
* Button: Creating separate Actionable view to improve perf of Actionable, small perf improvements and perf scenario updates.

* Change files
  • Loading branch information
khmakoto authored and dzearing committed Aug 1, 2019
1 parent 9f1798e commit 5dd84ec
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 6 deletions.
2 changes: 1 addition & 1 deletion apps/perf-test/src/scenarios/BaseButtonNew.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { Actionable } from '@uifabric/experiments';

const scenario = <Actionable content="I am a button" />;
const scenario = <Actionable>I am a button</Actionable>;

export default scenario;
2 changes: 1 addition & 1 deletion apps/perf-test/src/scenarios/DefaultButtonNew.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { Button } from '@uifabric/experiments';

const scenario = <Button>I am a button</Button>;
const scenario = <Button content="I am a button" />;

export default scenario;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"type": "patch",
"comment": "Button: Creating separate Actionable view to improve perf of Actionable, small perf improvements and perf scenario updates.",
"packageName": "@uifabric/experiments",
"email": "[email protected]",
"commit": "b83bcc1af7a91f2ceb7966aea79a495b6330e166",
"date": "2019-07-30T00:22:55.492Z"
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { createComponent } from '../../../Foundation';
import { ActionableStyles as styles, ActionableTokens as tokens } from './Actionable.styles';
import { IActionableProps } from './Actionable.types';
import { useButtonState as state } from '../Button.state';
import { ButtonView } from '../Button.view';
import { ActionableView } from './Actionable.view';

export const Actionable: React.StatelessComponent<IActionableProps> = createComponent(ButtonView, {
export const Actionable: React.StatelessComponent<IActionableProps> = createComponent(ActionableView, {
displayName: 'Actionable',
state,
styles,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/** @jsx withSlots */
import { KeytipData } from 'office-ui-fabric-react';
import { withSlots, getSlots } from '../../../Foundation';
import { getNativeProps, anchorProperties, buttonProperties } from '../../../Utilities';

import { IActionableProps, IActionableRootElements, IActionableSlots, IActionableViewProps } from './Actionable.types';
import { IButtonComponent } from '../Button.types';

export const ActionableView: IButtonComponent['view'] = props => {
const { children, disabled, onClick, allowDisabledFocus, ariaLabel, keytipProps, buttonRef, ...rest } = props;

const { slotType, htmlType, propertiesType } = _deriveRootType(props);

// TODO: 'href' is anchor property... consider getNativeProps by root type
const buttonProps = { ...getNativeProps(rest, propertiesType) };

const Slots = getSlots<IActionableProps, IActionableSlots>(props, {
root: slotType
});

const _onClick = (ev: React.MouseEvent<HTMLAnchorElement | HTMLButtonElement | HTMLDivElement>) => {
if (!disabled && onClick) {
onClick(ev);

if (ev.defaultPrevented) {
return;
}
}
};

const Button = (keytipAttributes?: any): JSX.Element => (
<Slots.root
type={htmlType}
role="button"
onClick={_onClick}
{...buttonProps}
{...keytipAttributes}
disabled={disabled && !allowDisabledFocus}
aria-disabled={disabled}
tabIndex={!disabled || allowDisabledFocus ? 0 : undefined}
aria-label={ariaLabel}
ref={buttonRef}
>
{children}
</Slots.root>
);

return keytipProps ? (
<KeytipData keytipProps={keytipProps} disabled={disabled && !allowDisabledFocus}>
{(keytipAttributes: any): JSX.Element => Button(keytipAttributes)}
</KeytipData>
) : (
Button()
);
};

interface IActionableRootType {
slotType: IActionableRootElements;
htmlType: 'link' | 'button';
propertiesType: string[];
}

function _deriveRootType(props: IActionableViewProps): IActionableRootType {
return !!props.href
? { slotType: 'a', htmlType: 'link', propertiesType: anchorProperties }
: { slotType: 'button', htmlType: 'button', propertiesType: buttonProperties };
}
4 changes: 2 additions & 2 deletions packages/experiments/src/components/Button/Button.view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ export const ButtonView: IButtonComponent['view'] = props => {
aria-label={ariaLabel}
ref={buttonRef}
>
<Slots.icon />
<Slots.content />
{icon && <Slots.icon />}
{content && <Slots.content />}
{children}
</Slots.root>
);
Expand Down

0 comments on commit 5dd84ec

Please sign in to comment.