Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chip component #1180

Merged
merged 1 commit into from
Jan 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 15 additions & 0 deletions packages/patternfly-4/react-core/src/components/Chip/Chip.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { SFC, HTMLProps } from 'react';
import { Omit, OneOf } from '../../typeUtils';
import { TooltipPosition } from '../Tooltip';

export interface ChipProps extends HTMLProps<HTMLDivElement> {
children: string;
closeBtnAriaLabel: string;
isOverflowChip: boolean;
tooltipPosition: OneOf<typeof TooltipPosition, keyof typeof TooltipPosition>;
}

declare const Chip: SFC<ChipProps>;

export default Chip;

15 changes: 15 additions & 0 deletions packages/patternfly-4/react-core/src/components/Chip/Chip.docs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Chip } from '@patternfly/react-core';
import SimpleExample from './examples/SimpleChip';

export default {
title: 'Chip',
components: {
Chip,
},
examples: [
{
component: SimpleExample,
title: 'Simple Example'
}
]
};
100 changes: 100 additions & 0 deletions packages/patternfly-4/react-core/src/components/Chip/Chip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import React from 'react';
import { css } from '@patternfly/react-styles';
import PropTypes from 'prop-types';
import ChipButton from './ChipButton';
import { Tooltip, TooltipPosition } from '../Tooltip';
import { TimesCircleIcon } from '@patternfly/react-icons';
import styles from '@patternfly/patternfly-next/components/Chip/chip.css';
import GenerateId from '../../internal/GenerateId/GenerateId';
class Chip extends React.Component {

renderOverflowChip = () => {
const { children, className, onClick } = this.props;
return (
<div className={css(styles.chip, styles.modifiers.overflow, className)}>
<ChipButton onClick={onClick}>
<span className={css(styles.chipText)}>{children}</span>
</ChipButton>
</div>
);
}

renderChip = (randomId) => {
const {
children,
closeBtnAriaLabel,
tooltipPosition,
className,
onClick,
} = this.props;
const isTooltipVisible = children.length > 16;
if (isTooltipVisible) {
return (
<Tooltip position={tooltipPosition} content={children}>
<div className={css(styles.chip, className)}>
<span className={css(styles.chipText)} id={randomId}>
{children}
</span>
<ChipButton onClick={onClick} ariaLabel={closeBtnAriaLabel} id={`remove_${randomId}`} aria-labelledby={`remove_${randomId} ${randomId}`}>
<TimesCircleIcon aria-hidden="true" />
</ChipButton>
</div>
</Tooltip>
)
} else {
return (
<div className={css(styles.chip, className)}>
<span className={css(styles.chipText)} id={randomId}>
{children}
</span>
<ChipButton onClick={onClick} ariaLabel={closeBtnAriaLabel} id={`remove_${randomId}`} aria-labelledby={`remove_${randomId} ${randomId}`}>
<TimesCircleIcon aria-hidden="true" />
</ChipButton>
</div>
)
}
}

render() {
const {
isOverflowChip,
} = this.props;
return (
<GenerateId>
{(randomId) =>
(
<React.Fragment>
{isOverflowChip ? this.renderOverflowChip() : this.renderChip(randomId)}
</React.Fragment>
)
}
</GenerateId>
)
}
}
Chip.propTypes = {
/** Content rendered inside the chip text */
children: PropTypes.string.isRequired,
/** Aria Label for close button */
closeBtnAriaLabel: PropTypes.string,
/** ID of the chip */
id: PropTypes.string,
/** Additional classes added to the chip item */
className: PropTypes.string,
/** Flag indicating if the chip has overflow*/
isOverflowChip: PropTypes.bool,
/** Position of the tooltip which is displayed if text is longer */
tooltipPosition: PropTypes.oneOf(Object.values(TooltipPosition)),
/** Function that is called when clicking on the chip button */
onClick: PropTypes.func,
};

Chip.defaultProps = {
id: undefined,
closeBtnAriaLabel: 'close',
className: '',
tooltipPosition: 'top',
isOverflowChip: false,
};

export default Chip;
43 changes: 43 additions & 0 deletions packages/patternfly-4/react-core/src/components/Chip/Chip.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react';
import { shallow } from 'enzyme';
import ChipButton from './ChipButton';
import Chip from './Chip';

test('ChipButton', () => {
const view = shallow(
<ChipButton id="my-chip-button" className="chip-bttn-cls">
<b>Close</b>
</ChipButton>
);
expect(view).toMatchSnapshot();
});

describe('Chip', () => {
test('overflow', () => {
const view = shallow(
<Chip className="my-chp-cls" isOverflowChip={true}>
4 more
</Chip>
);
expect(view).toMatchSnapshot();
});

test('closable', () => {
const view = shallow(
<Chip className="my-chp-cls" id="chip_one">
Chip
</Chip>
);
expect(view).toMatchSnapshot();
});


test('closable with tooltip', () => {
const view = shallow(
<Chip className="my-chp-cls" id="chip_one">
12345678901234567891
</Chip>
);
expect(view).toMatchSnapshot();
});
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { SFC, HTMLProps } from 'react';

export interface ChipButtonProps extends HTMLProps<HTMLButtonElement> {}

declare const ChipButton: SFC<ChipButtonProps>;

export default ChipButton;
33 changes: 33 additions & 0 deletions packages/patternfly-4/react-core/src/components/Chip/ChipButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import { css } from '@patternfly/react-styles';
import PropTypes from 'prop-types';
import styles from '@patternfly/patternfly-next/components/Chip/chip.css';
import { Button } from '../Button';

const ChipButton = ({ ariaLabel, children, className, onClick, ...props }) => {
return (
<Button variant="plain" aria-label={ariaLabel} onClick={onClick} className={className} {...props}>
{children}
</Button>
);
};

ChipButton.propTypes = {
/** Aria label for chip button */
ariaLabel: PropTypes.string,
/** Content rendered inside the chip item */
children: PropTypes.node,
/** Additional classes added to the chip item */
className: PropTypes.string,
/** Function that is called when clicking on the chip button */
onClick: PropTypes.func,
};

ChipButton.defaultProps = {
ariaLabel: 'close',
children: null,
className: '',
onClick: () => { }
};

export default ChipButton;
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Chip closable 1`] = `
<GenerateId
prefix="pf-random-id-"
/>
`;

exports[`Chip closable with tooltip 1`] = `
<GenerateId
prefix="pf-random-id-"
/>
`;

exports[`Chip overflow 1`] = `
<GenerateId
prefix="pf-random-id-"
/>
`;

exports[`ChipButton 1`] = `
<Button
aria-label="close"
className="chip-bttn-cls"
component="button"
id="my-chip-button"
isActive={false}
isBlock={false}
isDisabled={false}
isFocus={false}
isHover={false}
onClick={[Function]}
type="button"
variant="plain"
>
<b>
Close
</b>
</Button>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import { Chip } from '@patternfly/react-core';

class SimpleChip extends React.Component {
state = {
show: ['chip_one', 'chip_two']
};
deleteItem = id => {
const { show } = this.state;
const ix = show.indexOf(id);
if (ix < 0) {
return;
}
this.setState(() => ({
show: [...show.slice(0, ix), ...show.slice(ix + 1, show.length)]
}));
};
render() {
const { show } = this.state
return (
<React.Fragment>
{show.includes('chip_one') && (
<Chip id="chip_one" onClick={() => this.deleteItem('chip_one')}>
Chip
</Chip>
)}
<br />
<br />
{show.includes('chip_two') && (
<Chip id="chip_two" onClick={() => this.deleteItem('chip_two')}>
Really long Chip that goes on and on
</Chip>
)}
<br />
<br />
<Chip isOverflowChip={true}>4 more</Chip>
</React.Fragment>
);
}
}

export default SimpleChip;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Chip } from './Chip';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Chip } from './Chip';
1 change: 1 addition & 0 deletions packages/patternfly-4/react-core/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export * from './Breadcrumb';
export * from './Button';
export * from './Card';
export * from './Checkbox';
export * from './Chip';
export * from './DataList';
export * from './Dropdown';
export * from './EmptyState';
Expand Down