Skip to content
This repository has been archived by the owner on Nov 16, 2023. It is now read-only.

Commit

Permalink
Add HorizontalActionList Component (#511)
Browse files Browse the repository at this point in the history
* add post action link list

* refactoring

* use correct icon color

* menuButton styling

* update snapshots

* add unit tests

* rename to MessageActionsList

* update reference images

* fix reference image

* fix vertical alignment

* update interface to support both links and clickable

* use a more generic name

* remove stale reference images

* add references with new name

* add action states for open overflow menu

* fix description

* revert menuButton color override

* update snapshot
  • Loading branch information
chrismohr authored and swese44 committed Aug 31, 2018
1 parent d81ffbe commit b2c657c
Show file tree
Hide file tree
Showing 19 changed files with 622 additions and 6 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions src/components/ActionLink/ActionLink.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,13 @@ const text = 'SharePoint Document Library website';
<ActionLink text={text} icon={Icon} ariaLabel={text} href="https://www.yammer.com" newWindow={true} />
</div>
```

Compact:

```js { "props": { "data-description": "with compact" } }
const Like = require('../Icon/icons/Like').default;

<div>
<ActionLink text="Like" icon={Like} ariaLabel="Like this Post" compact={true} />
</div>
```
19 changes: 19 additions & 0 deletions src/components/ActionLink/ActionLink.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,23 @@ describe('<ActionLink />', () => {
expect(component).toMatchSnapshot();
});
});

describe('with compact set to true', () => {
beforeEach(() => {
component = shallow(
<ActionLink
className="TEST_CLASSNAME"
text="Download"
icon={Down}
ariaLabel="Download the file"
href="https://yammer.com"
compact={true}
/>,
);
});

it('matches its snapshot', () => {
expect(component).toMatchSnapshot();
});
});
});
14 changes: 9 additions & 5 deletions src/components/ActionLink/ActionLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as React from 'react';
import { join } from '../../util/classNames';
import Block, { TextSize } from '../Block';
import Clickable from '../Clickable';
import Strong from '../Strong';
import { FixedGridRow, FixedGridColumn, GutterSize } from '../FixedGrid';
import { IconSize } from '../Icon';
import NavigationLink from '../NavigationLink';
Expand All @@ -15,17 +16,20 @@ import { ActionLinkProps, NavigationActionLinkProps, ClickableActionLinkProps }
*/
export default class ActionLink extends React.Component<ActionLinkProps> {
public render() {
const { ariaLabel, className, icon: Icon, text } = this.props;
const { ariaLabel, className, compact = false, icon: Icon, text } = this.props;

const gutterSize = compact ? GutterSize.XSMALL : GutterSize.SMALL;
const iconSize = compact ? IconSize.SMALL : IconSize.MEDIUM;
// Remove Block around Icon when this is addressed: https://github.com/Microsoft/YamUI/issues/327
const content = (
<FixedGridRow gutterSize={GutterSize.SMALL}>
<FixedGridRow gutterSize={gutterSize}>
<FixedGridColumn fixed={true}>
<Block push={2}>
<Icon size={IconSize.MEDIUM} block={true} />
<Block push={compact ? 1 : 2}>
<Icon size={iconSize} block={true} />
</Block>
</FixedGridColumn>
<FixedGridColumn>
<Block textSize={TextSize.MEDIUM_SUB}>{text}</Block>
<Block textSize={TextSize.MEDIUM_SUB}>{compact ? <Strong>{text}</Strong> : text}</Block>
</FixedGridColumn>
</FixedGridRow>
);
Expand Down
7 changes: 6 additions & 1 deletion src/components/ActionLink/ActionLink.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ export interface BaseActionLinkProps extends BaseComponentProps {
* The visible text.
*/
text: string;

/**
* A more compressed format.
*/
compact?: boolean;
}

export interface NavigationActionLinkProps extends BaseActionLinkProps {
Expand All @@ -35,7 +40,7 @@ export interface ClickableActionLinkProps extends BaseActionLinkProps {
/**
* A click handler.
*/
onClick: ((e: React.MouseEvent<HTMLButtonElement | HTMLLinkElement>) => void);
onClick?: ((ev?: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) => void);
}

export type ActionLinkProps = NavigationActionLinkProps | ClickableActionLinkProps;
35 changes: 35 additions & 0 deletions src/components/ActionLink/__snapshots__/ActionLink.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,41 @@ exports[`<ActionLink /> with additional className matches its snapshot 1`] = `
</CustomizedNavigationLink>
`;

exports[`<ActionLink /> with compact set to true matches its snapshot 1`] = `
<CustomizedNavigationLink
ariaLabel="Download the file"
block={true}
className="y-actionLink TEST_CLASSNAME"
href="https://yammer.com"
>
<FixedGridRow
gutterSize="xSmall"
>
<FixedGridColumn
fixed={true}
>
<CustomizedBlock
push={1}
>
<Down
block={true}
size="14"
/>
</CustomizedBlock>
</FixedGridColumn>
<FixedGridColumn>
<CustomizedBlock
textSize="mediumSub"
>
<Strong>
Download
</Strong>
</CustomizedBlock>
</FixedGridColumn>
</FixedGridRow>
</CustomizedNavigationLink>
`;

exports[`<ActionLink /> with href and ariaLabel matches its snapshot 1`] = `
<CustomizedNavigationLink
ariaLabel="Download file"
Expand Down
99 changes: 99 additions & 0 deletions src/components/HorizontalActionsList/HorizontalActionList.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
### Examples

```js { "props": { "data-description": "basic", "data-action-states": "[{\"action\":\"none\"},{\"action\":\"click\",\"selector\":\".y-menu-button\"},{\"action\":\"hover\",\"selector\":\".y-menu-button--item-text\"}]" } }
const Like = require('../Icon/icons/Like').default;
const Reply = require('../Icon/icons/Reply').default;
const Share = require('../Icon/icons/Share').default;
const Flag = require('../Icon/icons/Flag').default;
const Strong = require('../Strong').default;

const items = [
{
key: 'like',
icon: Like,
text: 'Like',
onClick: () => action('clicked like'),
},
{
key: 'reply',
icon: Reply,
text: 'Reply',
onClick: () => action('clicked reply'),
},
{
key: 'share',
icon: Share,
text: 'Share',
onClick: () => action('clicked share'),
},
{
key: 'flag',
icon: Flag,
text: 'Follow in Inbox',
onClick: () => action('clicked follow'),
},
];

<div style={{ maxWidth: '400px', height: '60px' }}>
<HorizontalActionList items={items} maxVisibleItemCount={3} />
</div>;
```

```js { "props": { "data-description": "counts", "data-action-states": "[{\"action\":\"none\"},{\"action\":\"hover\",\"selector\":\".y-clickable\"}]" } }
const Like = require('../Icon/icons/Like').default;
const Reply = require('../Icon/icons/Reply').default;
const Share = require('../Icon/icons/Share').default;

const items = [
{
key: 'like',
icon: Like,
text: 'Like',
unlinkedText: '4',
onClick: () => action('clicked like'),
},
{
key: 'reply',
icon: Reply,
text: 'Reply',
unlinkedText: '2',
onClick: () => action('clicked reply'),
},
{
key: 'share',
icon: Share,
text: 'Share',
onClick: () => action('clicked share'),
},
];

<div style={{ maxWidth: '400px' }}>
<HorizontalActionList items={items} maxVisibleItemCount={2} />
</div>;
```

```js { "props": { "data-description": "no overflow" } }
const Like = require('../Icon/icons/Like').default;
const Reply = require('../Icon/icons/Reply').default;
const Share = require('../Icon/icons/Share').default;

const items = [
{
key: 'like',
icon: Like,
text: 'Like',
unlinkedText: '8',
onClick: () => action('clicked like'),
},
{
key: 'reply',
icon: Reply,
text: 'Reply',
onClick: () => action('clicked reply'),
},
];

<div style={{ maxWidth: '400px' }}>
<HorizontalActionList items={items} maxVisibleItemCount={2} />
</div>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*! Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. */
import { mergeStyleSets, ITheme } from 'office-ui-fabric-react/lib/Styling';
import { memoizeFunction } from 'office-ui-fabric-react/lib/Utilities';

export interface HorizontalActionListClassNameProps {
theme: ITheme;
}

export const getClassNames = memoizeFunction((classNameProps: HorizontalActionListClassNameProps) => {
const { theme } = classNameProps;

return mergeStyleSets({
unlinkedText: {
color: theme.semanticColors.link,
paddingLeft: '0.2rem',
},
menuButton: {
top: '0.1rem',
},
});
});
76 changes: 76 additions & 0 deletions src/components/HorizontalActionsList/HorizontalActionList.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*! Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. */
import * as React from 'react';
import { shallow, ShallowWrapper } from 'enzyme';
import { HorizontalActionList } from './HorizontalActionList';
import { HorizontalActionListItem, HorizontalActionListProps } from './HorizontalActionList.types';
import Reply from '../Icon/icons/Reply';
import Like from '../Icon/icons/Like';
import { darkTheme } from '../Customizer';

describe('<HorizontalActionList />', () => {
let component: ShallowWrapper<HorizontalActionListProps>;
let items: HorizontalActionListItem[];

beforeEach(() => {
items = [
{
icon: Like,
text: 'like',
ariaLabel: 'like',
key: 'like',
unlinkedText: '1',
unlinkedTextAriaLabel: '1 person has like this post',
onClick: jest.fn().mockName('likeOnClick'),
},
{
icon: Reply,
text: 'reply',
ariaLabel: 'reply',
key: 'reply',
onClick: jest.fn().mockName('replyOnClick'),
},
];
});

describe('with one item', () => {
beforeEach(() => {
component = shallow(<HorizontalActionList items={items.slice(0, 1)} overflowMenuAriaLabel="more items" />);
});

it('matches its snapshot', () => {
expect(component).toMatchSnapshot();
});
});

describe('with all items', () => {
beforeEach(() => {
component = shallow(<HorizontalActionList items={items} overflowMenuAriaLabel="more items" />);
});

it('matches its snapshot', () => {
expect(component).toMatchSnapshot();
});
});

describe('with all items, and maxVisibleItemCount of 1', () => {
beforeEach(() => {
component = shallow(
<HorizontalActionList items={items} maxVisibleItemCount={1} overflowMenuAriaLabel="more items" />,
);
});

it('matches its snapshot', () => {
expect(component).toMatchSnapshot();
});
});

describe('with a theme', () => {
beforeEach(() => {
component = shallow(<HorizontalActionList items={items} theme={darkTheme} overflowMenuAriaLabel="more items" />);
});

it('matches its snapshot', () => {
expect(component).toMatchSnapshot();
});
});
});
Loading

0 comments on commit b2c657c

Please sign in to comment.