diff --git a/.size-limit b/.size-limit index 9ec95f421..0fd57b774 100644 --- a/.size-limit +++ b/.size-limit @@ -3,6 +3,6 @@ name: "Fundamental-React Size", webpack: true, path: "lib/index.js", - limit: "190 KB" + limit: "195 KB" } ] diff --git a/src/BusyIndicator/BusyIndicator.Component.js b/src/BusyIndicator/BusyIndicator.Component.js new file mode 100644 index 000000000..525c62e9e --- /dev/null +++ b/src/BusyIndicator/BusyIndicator.Component.js @@ -0,0 +1,26 @@ +import { BusyIndicator } from '../'; +import path from 'path'; +import React from 'react'; +import { ComponentPage, Example } from '../_playground'; + +export const BusyIndicatorComponent = () => { + return ( + + + + + + + + + + + + ); +}; diff --git a/src/BusyIndicator/BusyIndicator.js b/src/BusyIndicator/BusyIndicator.js new file mode 100644 index 000000000..b088efb67 --- /dev/null +++ b/src/BusyIndicator/BusyIndicator.js @@ -0,0 +1,75 @@ +import { BUSY_INDICATOR_SIZES } from '../utils/constants'; +import classnames from 'classnames'; +import CustomPropTypes from '../utils/CustomPropTypes/CustomPropTypes'; +import PropTypes from 'prop-types'; +import React, { useEffect } from 'react'; + +const BusyIndicator = React.forwardRef(({ + className, + show, + size, + disableStyles, + localizedText, + ...props +}, ref) => { + + useEffect(() => { + if (!disableStyles) { + require('fundamental-styles/dist/icon.css'); + require('fundamental-styles/dist/busy-indicator.css'); + } + }, []); + + const busyIndicatorClasses = classnames( + { + [`fd-busy-indicator--${size}`]: size === 'm' || size === 'l', + 'fd-busy-indicator': size === 's' + }, + className + ); + + if (!show) + return null; + + return ( +
+
+
+
+
+ ); +}); + +BusyIndicator.displayName = 'BusyIndicator'; + +BusyIndicator.propTypes = { + className: PropTypes.string, + disableStyles: PropTypes.bool, + localizedText: CustomPropTypes.i18n({ + loading: PropTypes.string + }), + show: PropTypes.bool, + size: PropTypes.oneOf(BUSY_INDICATOR_SIZES) +}; + +BusyIndicator.defaultProps = { + localizedText: { + loading: 'Loading' + }, + size: 'm', + show: false +}; + +BusyIndicator.propDescriptions = { + show: 'Set to **true** to make Busy Indicator visible', + localizedTextShape: { + loading: 'aria-label for Busy Indicator component' + } +}; + +export default BusyIndicator; diff --git a/src/BusyIndicator/BusyIndicator.test.js b/src/BusyIndicator/BusyIndicator.test.js new file mode 100644 index 000000000..575914cc1 --- /dev/null +++ b/src/BusyIndicator/BusyIndicator.test.js @@ -0,0 +1,64 @@ +import BusyIndicator from './BusyIndicator'; +import { mount } from 'enzyme'; +import React from 'react'; +import renderer from 'react-test-renderer'; + +describe('', () => { + const showDefaultBusyIndicator = ; + const smallBusyIndicator = ; + const largeBusyIndicator = ; + const defaultBusyIndicator = ; + const hideBusyIndicator = ; + + test('create busy indicators', () => { + // show default busy indicator + let component = renderer.create(showDefaultBusyIndicator); + let tree = component.toJSON(); + expect(tree).toMatchSnapshot(); + + // small busy indicator + component = renderer.create(smallBusyIndicator); + tree = component.toJSON(); + expect(tree).toMatchSnapshot(); + + // large busy indicator + component = renderer.create(largeBusyIndicator); + tree = component.toJSON(); + expect(tree).toMatchSnapshot(); + + // default busy indicator + component = renderer.create(defaultBusyIndicator); + tree = component.toJSON(); + expect(tree).toMatchSnapshot(); + }); + + test('hide busy indicator', () => { + // hide busy indicator + let component = renderer.create(hideBusyIndicator); + let tree = component.toJSON(); + expect(tree).toMatchSnapshot(); + }); + + describe('Prop spreading', () => { + test('should allow props to be spread to the Busy Indicator component', () => { + const element = mount(); + + expect( + element.getDOMNode().attributes['data-sample'].value + ).toBe('Sample'); + }); + }); + test('forwards the ref', () => { + let ref; + class Test extends React.Component { + constructor(props) { + super(props); + ref = React.createRef(); + } + render = () => ; + } + mount(); + expect(ref.current.tagName).toEqual('DIV'); + expect(ref.current.className).toEqual('fd-busy-indicator--m'); + }); +}); diff --git a/src/BusyIndicator/__snapshots__/BusyIndicator.test.js.snap b/src/BusyIndicator/__snapshots__/BusyIndicator.test.js.snap new file mode 100644 index 000000000..dddacf5e4 --- /dev/null +++ b/src/BusyIndicator/__snapshots__/BusyIndicator.test.js.snap @@ -0,0 +1,59 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` create busy indicators 1`] = ` +
+
+
+
+
+`; + +exports[` create busy indicators 2`] = ` +
+
+
+
+
+`; + +exports[` create busy indicators 3`] = ` +
+
+
+
+
+`; + +exports[` create busy indicators 4`] = `null`; + +exports[` hide busy indicator 1`] = `null`; diff --git a/src/BusyIndicator/__stories__/BusyIndicator.stories.js b/src/BusyIndicator/__stories__/BusyIndicator.stories.js new file mode 100644 index 000000000..edaf32dc8 --- /dev/null +++ b/src/BusyIndicator/__stories__/BusyIndicator.stories.js @@ -0,0 +1,22 @@ +import BusyIndicator from '../BusyIndicator'; +import React from 'react'; +import { storiesOf } from '@storybook/react'; +import { withKnobs } from '@storybook/addon-knobs'; + +storiesOf('Components|BusyIndicator', module) + .addDecorator(withKnobs) + .add('Default', () => ( + + )) + .add('small', () => ( + + )) + .add('large', () => ( + + )) + .add('hidden', () => ( + + )) + .add('disable styles', () => ( + Default + )); diff --git a/src/_playground/Routes.js b/src/_playground/Routes.js index 2ea81618d..03b5e6e7a 100644 --- a/src/_playground/Routes.js +++ b/src/_playground/Routes.js @@ -1,5 +1,6 @@ import { ActionBarComponent } from '../ActionBar/ActionBar.Component'; import { BreadcrumbComponent } from '../Breadcrumb/Breadcrumb.Component'; +import { BusyIndicatorComponent } from '../BusyIndicator/BusyIndicator.Component'; import Button from '../Button/Button'; import { ButtonComponent } from '../Button/Button.Component'; import { CalendarComponent } from '../Calendar/Calendar.Component'; @@ -90,6 +91,12 @@ const routes = [ component: BreadcrumbComponent, section: 'Components' }, + { + url: '/busyIndicator', + name: 'Busy Indicator', + component: BusyIndicatorComponent, + section: 'Components' + }, { url: '/button', name: 'Button', diff --git a/src/index.js b/src/index.js index aad097f31..7998644b9 100644 --- a/src/index.js +++ b/src/index.js @@ -2,6 +2,7 @@ export { default as ActionBar } from './ActionBar/ActionBar'; export { default as Checkbox } from './Forms/Checkbox'; export { default as Counter } from './Counter/Counter'; export { default as Breadcrumb } from './Breadcrumb/Breadcrumb'; +export { default as BusyIndicator } from './BusyIndicator/BusyIndicator'; export { default as Button } from './Button/Button'; export { default as ButtonGroup } from './Button/ButtonGroup'; export { default as Calendar } from './Calendar/Calendar'; diff --git a/src/utils/constants.js b/src/utils/constants.js index c953e8b09..1aeddc112 100644 --- a/src/utils/constants.js +++ b/src/utils/constants.js @@ -5,6 +5,12 @@ export const MESSAGESTRIP_TYPES = [ 'information' ]; +export const BUSY_INDICATOR_SIZES = [ + 's', + 'm', + 'l' +]; + export const BUTTON_OPTIONS = [ 'emphasized', 'transparent' diff --git a/visual-regression-testing/__image_snapshots__/storyshots-test-js-storyshots-components-busy-indicator-default-1-snap.png b/visual-regression-testing/__image_snapshots__/storyshots-test-js-storyshots-components-busy-indicator-default-1-snap.png new file mode 100644 index 000000000..9e14f5a94 Binary files /dev/null and b/visual-regression-testing/__image_snapshots__/storyshots-test-js-storyshots-components-busy-indicator-default-1-snap.png differ diff --git a/visual-regression-testing/__image_snapshots__/storyshots-test-js-storyshots-components-busy-indicator-disable-styles-1-snap.png b/visual-regression-testing/__image_snapshots__/storyshots-test-js-storyshots-components-busy-indicator-disable-styles-1-snap.png new file mode 100644 index 000000000..c53502031 Binary files /dev/null and b/visual-regression-testing/__image_snapshots__/storyshots-test-js-storyshots-components-busy-indicator-disable-styles-1-snap.png differ diff --git a/visual-regression-testing/__image_snapshots__/storyshots-test-js-storyshots-components-busy-indicator-hidden-1-snap.png b/visual-regression-testing/__image_snapshots__/storyshots-test-js-storyshots-components-busy-indicator-hidden-1-snap.png new file mode 100644 index 000000000..c53502031 Binary files /dev/null and b/visual-regression-testing/__image_snapshots__/storyshots-test-js-storyshots-components-busy-indicator-hidden-1-snap.png differ diff --git a/visual-regression-testing/__image_snapshots__/storyshots-test-js-storyshots-components-busy-indicator-large-1-snap.png b/visual-regression-testing/__image_snapshots__/storyshots-test-js-storyshots-components-busy-indicator-large-1-snap.png new file mode 100644 index 000000000..4a4cfbb66 Binary files /dev/null and b/visual-regression-testing/__image_snapshots__/storyshots-test-js-storyshots-components-busy-indicator-large-1-snap.png differ diff --git a/visual-regression-testing/__image_snapshots__/storyshots-test-js-storyshots-components-busy-indicator-small-1-snap.png b/visual-regression-testing/__image_snapshots__/storyshots-test-js-storyshots-components-busy-indicator-small-1-snap.png new file mode 100644 index 000000000..2719b2941 Binary files /dev/null and b/visual-regression-testing/__image_snapshots__/storyshots-test-js-storyshots-components-busy-indicator-small-1-snap.png differ