diff --git a/.gitignore b/.gitignore index 91f6691..91bbd2f 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,6 @@ typings/ # IDEA .idea/ + +# Miscellaneous cache files +.DS_Store diff --git a/components.json b/components.json index 9301dbe..c39839b 100644 --- a/components.json +++ b/components.json @@ -43,6 +43,8 @@ { "name": "Design System Icons", "components": [ + "IconSprite", + "Icon", "VideoPlayIcon" ] }, diff --git a/jest.config.js b/jest.config.js index 48b62ed..12b479d 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,6 +1,7 @@ module.exports = { moduleNameMapper: { '\\.(s?css)$': 'identity-obj-proxy', + '\\.svg$': 'identity-obj-proxy', }, testURL: 'http://localhost', setupTestFrameworkScriptFile: '/jest.setup.js', diff --git a/src/components/BannerNotification/README.md b/src/components/BannerNotification/README.md index 8870ad9..2a48310 100644 --- a/src/components/BannerNotification/README.md +++ b/src/components/BannerNotification/README.md @@ -1,9 +1,11 @@ By default its rendered without close button: ```js +{ /* add sprite so we can see icons in this example */ } ``` But it can be rendered with close buttton: ```js +{ /* add sprite so we can see icons in this example */ } alert('Click')} /> ``` diff --git a/src/components/BannerNotification/__snapshots__/index.spec.js.snap b/src/components/BannerNotification/__snapshots__/index.spec.js.snap index be601bb..dc76d30 100644 --- a/src/components/BannerNotification/__snapshots__/index.spec.js.snap +++ b/src/components/BannerNotification/__snapshots__/index.spec.js.snap @@ -12,7 +12,6 @@ exports[`BannerNotification renders correctly 1`] = ` > @@ -22,12 +21,11 @@ exports[`BannerNotification renders correctly 1`] = ` lorem ipsum - messge @@ -45,7 +43,6 @@ exports[`BannerNotification renders correctly 2`] = ` > @@ -55,12 +52,11 @@ exports[`BannerNotification renders correctly 2`] = ` lorem ipsum - success @@ -78,7 +74,6 @@ exports[`BannerNotification renders correctly 3`] = ` > @@ -88,12 +83,11 @@ exports[`BannerNotification renders correctly 3`] = ` lorem ipsum - warning @@ -111,7 +105,6 @@ exports[`BannerNotification renders correctly 4`] = ` > @@ -121,12 +114,11 @@ exports[`BannerNotification renders correctly 4`] = ` lorem ipsum - alert @@ -144,7 +136,6 @@ exports[`BannerNotification renders correctly without action 1`] = ` > @@ -168,7 +159,6 @@ exports[`BannerNotification renders correctly without action 2`] = ` > @@ -192,7 +182,6 @@ exports[`BannerNotification renders correctly without action 3`] = ` > @@ -216,7 +205,6 @@ exports[`BannerNotification renders correctly without action 4`] = ` > diff --git a/src/components/BannerNotification/index.js b/src/components/BannerNotification/index.js index f1c5f06..2254370 100644 --- a/src/components/BannerNotification/index.js +++ b/src/components/BannerNotification/index.js @@ -1,17 +1,20 @@ import React from 'react'; import PropTypes from 'prop-types'; + +import Icon from '../Icon'; + import './styles.scss'; -function getIcon(type) { +function getIconName(type) { switch (type) { case ('alert'): - return '#wds-icons-error-small'; + return 'error-small'; case ('warning'): - return '#wds-icons-alert-small'; + return 'alert-small'; case ('success'): - return '#wds-icons-checkmark-circle-small'; + return 'checkmark-circle-small'; default: - return '#wds-icons-flag-small'; + return 'flag-small'; } } @@ -34,16 +37,10 @@ function getClassName(type) { const BannerNotification = ({className, type, text, onClose}) => (
- - - +
{text} - {onClose && ( - - - - )} + {onClose && }
); diff --git a/src/components/BannerNotification/index.spec.js b/src/components/BannerNotification/index.spec.js index d85951e..0b917e9 100644 --- a/src/components/BannerNotification/index.spec.js +++ b/src/components/BannerNotification/index.spec.js @@ -1,6 +1,9 @@ import React from 'react'; import renderer from 'react-test-renderer'; -import {shallow} from 'enzyme'; +import { + shallow, + mount +} from 'enzyme'; import sinon from 'sinon'; import BannerNotification from './index'; @@ -54,11 +57,11 @@ test('BannerNotification renders correctly without action', () => { test('BannerNotification onClose hander is invoked', () => { const mockOnClick = sinon.spy(); - const wrapper = shallow( + const wrapper = mount( ); - wrapper.find('.wds-banner-notification__close').simulate('click'); + wrapper.find('.wds-banner-notification__close').at(0).simulate('click'); expect(mockOnClick.calledOnce).toBe(true); }); diff --git a/src/components/BannerNotifications/README.md b/src/components/BannerNotifications/README.md index 213c500..4151c19 100644 --- a/src/components/BannerNotifications/README.md +++ b/src/components/BannerNotifications/README.md @@ -1,5 +1,6 @@ By default it renders nothing: ```js +{ /* add sprite so we can see icons in this example */ } {}} /> ``` @@ -27,5 +28,8 @@ const messages4 = [ text: 'this is an alert', id: '4', }, -]; {}} /> +];
+ { /* add sprite so we can see icons in this example */ } + {}} /> +
``` diff --git a/src/components/BannerNotifications/__snapshots__/index.spec.js.snap b/src/components/BannerNotifications/__snapshots__/index.spec.js.snap index 6ddb13c..1578b77 100644 --- a/src/components/BannerNotifications/__snapshots__/index.spec.js.snap +++ b/src/components/BannerNotifications/__snapshots__/index.spec.js.snap @@ -17,7 +17,6 @@ exports[`BannerNotifications renders correctly 2`] = ` > @@ -27,12 +26,11 @@ exports[`BannerNotifications renders correctly 2`] = ` this is a single message @@ -54,7 +52,6 @@ exports[`BannerNotifications renders correctly 3`] = ` > @@ -64,12 +61,11 @@ exports[`BannerNotifications renders correctly 3`] = ` this is a message @@ -84,7 +80,6 @@ exports[`BannerNotifications renders correctly 3`] = ` > @@ -94,12 +89,11 @@ exports[`BannerNotifications renders correctly 3`] = ` this is a success @@ -114,7 +108,6 @@ exports[`BannerNotifications renders correctly 3`] = ` > @@ -124,12 +117,11 @@ exports[`BannerNotifications renders correctly 3`] = ` this is a warning @@ -144,7 +136,6 @@ exports[`BannerNotifications renders correctly 3`] = ` > diff --git a/src/components/BannerNotifications/index.spec.js b/src/components/BannerNotifications/index.spec.js index e4c8d70..bdc1a3c 100644 --- a/src/components/BannerNotifications/index.spec.js +++ b/src/components/BannerNotifications/index.spec.js @@ -61,6 +61,6 @@ test('BannerNotifications onClose hander is invoked', () => { ); - wrapper.find('.wds-banner-notification__close').simulate('click'); + wrapper.find('.wds-banner-notification__close').at(0).simulate('click'); expect(mockOnClick.withArgs('1').calledOnce).toBe(true); }); diff --git a/src/components/Icon/README.md b/src/components/Icon/README.md new file mode 100644 index 0000000..0b048d6 --- /dev/null +++ b/src/components/Icon/README.md @@ -0,0 +1,32 @@ +This component uses the Design System icons listed at [https://fandomdesignsystem.com/#/components/assets]() + +The `name` attribute of the component refers to the icon's DS name. + +## Example usage + +Standard icon: + +``` +
+ + +
+``` + +Small or tiny icon: + +``` + +``` + +Add your own CSS class for styling: + +``` + +``` + +Other props are just passed to the SVG: + +``` + alert('click!')} style={{cursor: 'pointer'}}/> +``` diff --git a/src/components/Icon/__snapshots__/index.spec.js.snap b/src/components/Icon/__snapshots__/index.spec.js.snap new file mode 100644 index 0000000..e095e33 --- /dev/null +++ b/src/components/Icon/__snapshots__/index.spec.js.snap @@ -0,0 +1,41 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Icon component renders 1`] = ` + + + +`; + +exports[`Icon component renders with a tiny icon 1`] = ` + + + +`; + +exports[`Icon component renders with an additional CSS class 1`] = ` + + + +`; + +exports[`Icon component renders with small icon 1`] = ` + + + +`; diff --git a/src/components/Icon/index.js b/src/components/Icon/index.js new file mode 100644 index 0000000..5d71171 --- /dev/null +++ b/src/components/Icon/index.js @@ -0,0 +1,42 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import './styles.scss'; + +/** + * A single WDS icon. + * + * **NOTE**: This icon is using `IconSprite` component. + */ +const Icon = ({name, className, ...props}) => { + const classes = [ + 'wds-icon', + className, + /-small$/.test(name) ? 'wds-icon-small' : '', + /-tiny$/.test(name) ? 'wds-icon-tiny' : '', + ].filter(c => c).join(' '); + + return ( + + + + ); +}; + +Icon.propTypes = { + /** + * Icon name + */ + name: PropTypes.string.isRequired, + /** + * Additional class name + */ + className: PropTypes.string, +}; + +Icon.defaultProps = { + className: '', +}; + +export default Icon; + diff --git a/src/components/Icon/index.spec.js b/src/components/Icon/index.spec.js new file mode 100644 index 0000000..43dd782 --- /dev/null +++ b/src/components/Icon/index.spec.js @@ -0,0 +1,34 @@ +import React from 'react'; +import renderer from 'react-test-renderer'; +import {shallow} from 'enzyme'; +import sinon from 'sinon'; + +import Icon from './index'; + +test('Icon component renders', () => { + const component = renderer.create( + + ); + expect(component.toJSON()).toMatchSnapshot(); +}); + +test('Icon component renders with small icon', () => { + const component = renderer.create( + + ); + expect(component.toJSON()).toMatchSnapshot(); +}); + +test('Icon component renders with a tiny icon', () => { + const component = renderer.create( + + ); + expect(component.toJSON()).toMatchSnapshot(); +}); + +test('Icon component renders with an additional CSS class', () => { + const component = renderer.create( + + ); + expect(component.toJSON()).toMatchSnapshot(); +}); diff --git a/src/components/Icon/styles.scss b/src/components/Icon/styles.scss new file mode 100644 index 0000000..86ba19b --- /dev/null +++ b/src/components/Icon/styles.scss @@ -0,0 +1,3 @@ +@import "~design-system/dist/scss/wds-variables/index.scss"; +@import "~design-system/dist/scss/wds-mixins/index.scss"; +@import "~design-system/dist/scss/wds-components/_icons.scss"; diff --git a/src/components/IconSprite/README.md b/src/components/IconSprite/README.md new file mode 100644 index 0000000..e649d69 --- /dev/null +++ b/src/components/IconSprite/README.md @@ -0,0 +1 @@ +This component needs to be included once in the app in order to use `` component if there's no other way that the icons are included. diff --git a/src/components/IconSprite/__snapshots__/index.spec.js.snap b/src/components/IconSprite/__snapshots__/index.spec.js.snap new file mode 100644 index 0000000..e1bec1a --- /dev/null +++ b/src/components/IconSprite/__snapshots__/index.spec.js.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`IconSprite component renders 1`] = ` +
+`; diff --git a/src/components/IconSprite/index.js b/src/components/IconSprite/index.js new file mode 100644 index 0000000..36d345e --- /dev/null +++ b/src/components/IconSprite/index.js @@ -0,0 +1,11 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import * as sprite from 'design-system/dist/svg/sprite.svg'; + +const IconSprite = () => ( + // eslint-disable-next-line react/no-danger +
+); + +export default IconSprite; diff --git a/src/components/IconSprite/index.spec.js b/src/components/IconSprite/index.spec.js new file mode 100644 index 0000000..bd9cb88 --- /dev/null +++ b/src/components/IconSprite/index.spec.js @@ -0,0 +1,9 @@ +import React from 'react'; +import renderer from 'react-test-renderer'; + +import IconSprite from './index'; + +test('IconSprite component renders', () => { + const component = renderer.create(); + expect(component.toJSON()).toMatchSnapshot(); +}); diff --git a/src/index.js b/src/index.js index bb0d1d3..2460dce 100644 --- a/src/index.js +++ b/src/index.js @@ -11,6 +11,8 @@ export {default as BannerNotification} from './components/BannerNotification'; export {default as BannerNotifications} from './components/BannerNotifications'; // Icons +export {default as IconSprite} from './components/IconSprite'; +export {default as Icon} from './components/Icon'; export {default as VideoPlayIcon} from './components/VideoPlayIcon'; // Usefull flow components export {default as ContentWell} from './components/ContentWell'; diff --git a/styleguide/webpackConfig.js b/styleguide/webpackConfig.js index c076fd1..fb3c159 100644 --- a/styleguide/webpackConfig.js +++ b/styleguide/webpackConfig.js @@ -26,6 +26,10 @@ module.exports = { test: /\.s?css$/, loader: 'style-loader!css-loader!sass-loader', }, + { + test: /node_modules\/design-system\/dist\/svg\/sprite\.svg$/, + loader: 'raw-loader', + }, ], }, };