diff --git a/packages/patternfly-4/react-core/src/components/Chip/Chip.d.ts b/packages/patternfly-4/react-core/src/components/Chip/Chip.d.ts new file mode 100644 index 00000000000..922ef9be54f --- /dev/null +++ b/packages/patternfly-4/react-core/src/components/Chip/Chip.d.ts @@ -0,0 +1,15 @@ +import { SFC, HTMLProps } from 'react'; +import { Omit, OneOf } from '../../typeUtils'; +import { TooltipPosition } from '../Tooltip'; + +export interface ChipProps extends HTMLProps { + children: string; + closeBtnAriaLabel: string; + isOverflowChip: boolean; + tooltipPosition: OneOf; +} + +declare const Chip: SFC; + +export default Chip; + diff --git a/packages/patternfly-4/react-core/src/components/Chip/Chip.docs.js b/packages/patternfly-4/react-core/src/components/Chip/Chip.docs.js new file mode 100644 index 00000000000..66a02d24103 --- /dev/null +++ b/packages/patternfly-4/react-core/src/components/Chip/Chip.docs.js @@ -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' + } + ] +}; diff --git a/packages/patternfly-4/react-core/src/components/Chip/Chip.js b/packages/patternfly-4/react-core/src/components/Chip/Chip.js new file mode 100644 index 00000000000..61895cfbc9a --- /dev/null +++ b/packages/patternfly-4/react-core/src/components/Chip/Chip.js @@ -0,0 +1,104 @@ +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 ( +
+ + {children} + +
+ ); + } + + renderChip = (randomId) => { + const { + children, + closeBtnAriaLabel, + tooltipPosition, + className, + onClick, + minTooltipChars + } = this.props; + const isTooltipVisible = children.length > minTooltipChars; + if (isTooltipVisible) { + return ( + +
+ + {children} + + + +
+
+ ) + } else { + return ( +
+ + {children} + + + +
+ ) + } + } + + render() { + const { + isOverflowChip, + } = this.props; + return ( + + {(randomId) => + ( + + {isOverflowChip ? this.renderOverflowChip() : this.renderChip(randomId)} + + ) + } + + ) + } +} +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, + /** Minimum character limit before showing tooltip. */ + minTooltipChars: PropTypes.number +}; + +Chip.defaultProps = { + id: undefined, + closeBtnAriaLabel: 'close', + className: '', + tooltipPosition: 'top', + isOverflowChip: false, + minTooltipChars: 16 +}; + +export default Chip; diff --git a/packages/patternfly-4/react-core/src/components/Chip/Chip.test.js b/packages/patternfly-4/react-core/src/components/Chip/Chip.test.js new file mode 100644 index 00000000000..a768d4be6b0 --- /dev/null +++ b/packages/patternfly-4/react-core/src/components/Chip/Chip.test.js @@ -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( + + Close + + ); + expect(view).toMatchSnapshot(); +}); + +describe('Chip', () => { + test('overflow', () => { + const view = shallow( + + 4 more + + ); + expect(view).toMatchSnapshot(); + }); + + test('closable', () => { + const view = shallow( + + Chip + + ); + expect(view).toMatchSnapshot(); + }); + + + test('closable with tooltip', () => { + const view = shallow( + + 12345678901234567891 + + ); + expect(view).toMatchSnapshot(); + }); +}) diff --git a/packages/patternfly-4/react-core/src/components/Chip/ChipButton.d.ts b/packages/patternfly-4/react-core/src/components/Chip/ChipButton.d.ts new file mode 100644 index 00000000000..c6f800a0f35 --- /dev/null +++ b/packages/patternfly-4/react-core/src/components/Chip/ChipButton.d.ts @@ -0,0 +1,7 @@ +import { SFC, HTMLProps } from 'react'; + +export interface ChipButtonProps extends HTMLProps {} + +declare const ChipButton: SFC; + +export default ChipButton; diff --git a/packages/patternfly-4/react-core/src/components/Chip/ChipButton.js b/packages/patternfly-4/react-core/src/components/Chip/ChipButton.js new file mode 100644 index 00000000000..53371e362c3 --- /dev/null +++ b/packages/patternfly-4/react-core/src/components/Chip/ChipButton.js @@ -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 ( + + ); +}; + +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; diff --git a/packages/patternfly-4/react-core/src/components/Chip/__snapshots__/Chip.test.js.snap b/packages/patternfly-4/react-core/src/components/Chip/__snapshots__/Chip.test.js.snap new file mode 100644 index 00000000000..48f07021aa9 --- /dev/null +++ b/packages/patternfly-4/react-core/src/components/Chip/__snapshots__/Chip.test.js.snap @@ -0,0 +1,40 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Chip closable 1`] = ` + +`; + +exports[`Chip closable with tooltip 1`] = ` + +`; + +exports[`Chip overflow 1`] = ` + +`; + +exports[`ChipButton 1`] = ` + +`; diff --git a/packages/patternfly-4/react-core/src/components/Chip/examples/SimpleChip.js b/packages/patternfly-4/react-core/src/components/Chip/examples/SimpleChip.js new file mode 100644 index 00000000000..a396515ccdb --- /dev/null +++ b/packages/patternfly-4/react-core/src/components/Chip/examples/SimpleChip.js @@ -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 ( + + {show.includes('chip_one') && ( + this.deleteItem('chip_one')}> + Chip + + )} +
+
+ {show.includes('chip_two') && ( + this.deleteItem('chip_two')}> + Really long Chip that goes on and on + + )} +
+
+ 4 more +
+ ); + } +} + +export default SimpleChip; diff --git a/packages/patternfly-4/react-core/src/components/Chip/index.d.ts b/packages/patternfly-4/react-core/src/components/Chip/index.d.ts new file mode 100644 index 00000000000..68faf22289c --- /dev/null +++ b/packages/patternfly-4/react-core/src/components/Chip/index.d.ts @@ -0,0 +1 @@ +export { default as Chip } from './Chip'; diff --git a/packages/patternfly-4/react-core/src/components/Chip/index.js b/packages/patternfly-4/react-core/src/components/Chip/index.js new file mode 100644 index 00000000000..68faf22289c --- /dev/null +++ b/packages/patternfly-4/react-core/src/components/Chip/index.js @@ -0,0 +1 @@ +export { default as Chip } from './Chip'; diff --git a/packages/patternfly-4/react-core/src/components/index.ts b/packages/patternfly-4/react-core/src/components/index.ts index 0db2b1e740c..284ca60a4e1 100644 --- a/packages/patternfly-4/react-core/src/components/index.ts +++ b/packages/patternfly-4/react-core/src/components/index.ts @@ -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';