- );
- }
-}
-
-export default Badge;
diff --git a/packages/react-ui-components/src/Badge/badge.spec.js b/packages/react-ui-components/src/Badge/badge.spec.js
index 255bd0c952..ae6476346f 100644
--- a/packages/react-ui-components/src/Badge/badge.spec.js
+++ b/packages/react-ui-components/src/Badge/badge.spec.js
@@ -1,7 +1,7 @@
import React from 'react';
import {shallow} from 'enzyme';
import toJson from 'enzyme-to-json';
-import Badge from './badge.js';
+import Badge from './badge';
describe('', () => {
let props;
diff --git a/packages/react-ui-components/src/Badge/badge.tsx b/packages/react-ui-components/src/Badge/badge.tsx
new file mode 100644
index 0000000000..7626178316
--- /dev/null
+++ b/packages/react-ui-components/src/Badge/badge.tsx
@@ -0,0 +1,41 @@
+import mergeClassNames from 'classnames';
+import React, {PureComponent} from 'react';
+
+interface BadgeTheme {
+ readonly badge: string;
+}
+
+interface BadgeProps {
+ /**
+ * An optional `className` to attach to the wrapper.
+ */
+ readonly className?: string;
+
+ /**
+ * Badge's label.
+ */
+ readonly label: string;
+
+ /**
+ * An optional css theme to be injected.
+ */
+ readonly theme?: BadgeTheme;
+}
+
+class Badge extends PureComponent {
+ public render(): JSX.Element {
+ const {
+ className,
+ theme,
+ label,
+ ...rest
+ } = this.props;
+ const finalClassName = mergeClassNames(theme!.badge, className);
+
+ return (
+
{label}
+ );
+ }
+}
+
+export default Badge;
diff --git a/packages/react-ui-components/src/Badge/index.js b/packages/react-ui-components/src/Badge/index.js
index e951da1f8c..a0140d4de2 100644
--- a/packages/react-ui-components/src/Badge/index.js
+++ b/packages/react-ui-components/src/Badge/index.js
@@ -1,6 +1,6 @@
import {themr} from '@friendsofreactjs/react-css-themr';
-import identifiers from './../identifiers';
+import identifiers from '../identifiers';
import style from './style.css';
-import Badge from './badge.js';
+import Badge from './badge';
export default themr(identifiers.badge, style)(Badge);
diff --git a/packages/react-ui-components/src/Badge/index.spec.js b/packages/react-ui-components/src/Badge/index.spec.js
index 804013406c..db68e568fe 100644
--- a/packages/react-ui-components/src/Badge/index.spec.js
+++ b/packages/react-ui-components/src/Badge/index.spec.js
@@ -1,4 +1,4 @@
-import Badge from './index.js';
+import Badge from '.';
describe(' (entry point)', () => {
it('should export a Component.', () => {
diff --git a/packages/react-ui-components/src/Badge/index.story.js b/packages/react-ui-components/src/Badge/index.story.js
index 4a7ec719fb..f7b1eb984b 100644
--- a/packages/react-ui-components/src/Badge/index.story.js
+++ b/packages/react-ui-components/src/Badge/index.story.js
@@ -1,8 +1,8 @@
import React from 'react';
import {storiesOf} from '@storybook/react';
import {withKnobs, text} from '@storybook/addon-knobs';
-import {StoryWrapper} from './../_lib/storyUtils.js';
-import Badge from './index.js';
+import {StoryWrapper} from './../_lib/storyUtils';
+import Badge from '.';
storiesOf('Badge', module)
.addDecorator(withKnobs)
diff --git a/packages/react-ui-components/src/Bar/bar.js b/packages/react-ui-components/src/Bar/bar.js
deleted file mode 100644
index 914b76cab3..0000000000
--- a/packages/react-ui-components/src/Bar/bar.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import React, {PureComponent} from 'react';
-import PropTypes from 'prop-types';
-import mergeClassNames from 'classnames';
-
-class Bar extends PureComponent {
- static propTypes = {
- /**
- * This prop controls the vertical positioning of the Bar.
- */
- position: PropTypes.oneOf(['top', 'bottom']).isRequired,
-
- /**
- * An optional css theme to be injected.
- */
- theme: PropTypes.shape({
- 'bar': PropTypes.string,
- 'bar--top': PropTypes.string,
- 'bar--bottom': PropTypes.string
- }).isRequired,
-
- /**
- * An optional `className` to attach to the wrapper.
- */
- className: PropTypes.string,
-
- /**
- * The contents to be rendered within the `Bar`.
- */
- children: PropTypes.any.isRequired
- };
-
- render() {
- const {position, className, theme, children, ...rest} = this.props;
- const finalClassName = mergeClassNames({
- [className]: className && className.length,
- [theme.bar]: true,
- [theme['bar--top']]: position === 'top',
- [theme['bar--bottom']]: position === 'bottom'
- });
-
- return (
-
- {children}
-
- );
- }
-}
-
-export default Bar;
diff --git a/packages/react-ui-components/src/Bar/bar.spec.js b/packages/react-ui-components/src/Bar/bar.spec.js
index 2a414699f5..1616d8deb3 100644
--- a/packages/react-ui-components/src/Bar/bar.spec.js
+++ b/packages/react-ui-components/src/Bar/bar.spec.js
@@ -1,7 +1,7 @@
import React from 'react';
import {shallow} from 'enzyme';
import toJson from 'enzyme-to-json';
-import Bar from './bar.js';
+import Bar from './bar';
describe('', () => {
let props;
diff --git a/packages/react-ui-components/src/Bar/bar.tsx b/packages/react-ui-components/src/Bar/bar.tsx
new file mode 100644
index 0000000000..eb7b724506
--- /dev/null
+++ b/packages/react-ui-components/src/Bar/bar.tsx
@@ -0,0 +1,59 @@
+import mergeClassNames from 'classnames';
+import React, {PureComponent} from 'react';
+
+type BarPosition = 'top' | 'bottom';
+
+interface BarTheme {
+ readonly 'bar': string;
+ readonly 'bar--top': string;
+ readonly 'bar--bottom': string;
+}
+
+interface BarProps {
+ /**
+ * This prop controls the vertical positioning of the Bar.
+ */
+ readonly position: BarPosition;
+
+ /**
+ * An optional css theme to be injected.
+ */
+ readonly theme?: BarTheme;
+
+ /**
+ * An optional `className` to attach to the wrapper.
+ */
+ readonly className?: string;
+
+ /**
+ * The contents to be rendered within the `Bar`.
+ */
+ readonly children: React.ReactNode;
+}
+
+class Bar extends PureComponent {
+ public render(): JSX.Element {
+ const {position, className, theme, children, ...rest} = this.props;
+ const finalClassName = mergeClassNames(
+ className,
+ theme!.bar,
+ {
+ [theme!['bar--top']]: position === 'top',
+ [theme!['bar--bottom']]: position === 'bottom'
+ }
+ );
+
+ // TODO:
+ // The prop 'rest' is empty here. I suppose it contains all the attributes that are not part of the Badge Api/Interface.
+ // Consider enxtending Bagde with React.HTMLAttributes like we did in the Button component.
+ // It also enables autocomplete for the whole div Api.
+ // Consider this for the other components.
+ return (
+
+ {children}
+
+ );
+ }
+}
+
+export default Bar;
diff --git a/packages/react-ui-components/src/Bar/index.js b/packages/react-ui-components/src/Bar/index.js
index 7c06b5e395..7e1ded97f1 100644
--- a/packages/react-ui-components/src/Bar/index.js
+++ b/packages/react-ui-components/src/Bar/index.js
@@ -1,6 +1,6 @@
import {themr} from '@friendsofreactjs/react-css-themr';
-import identifiers from './../identifiers';
+import identifiers from '../identifiers';
import style from './style.css';
-import Bar from './bar.js';
+import Bar from './bar';
export default themr(identifiers.bar, style)(Bar);
diff --git a/packages/react-ui-components/src/Bar/index.spec.js b/packages/react-ui-components/src/Bar/index.spec.js
index 8cba3a8651..71b044a505 100644
--- a/packages/react-ui-components/src/Bar/index.spec.js
+++ b/packages/react-ui-components/src/Bar/index.spec.js
@@ -1,4 +1,4 @@
-import Bar from './index.js';
+import Bar from '.';
describe(' (entry point)', () => {
it('should export a Component.', () => {
diff --git a/packages/react-ui-components/src/Bar/index.story.js b/packages/react-ui-components/src/Bar/index.story.js
index 512a9aab51..ad1dde7528 100644
--- a/packages/react-ui-components/src/Bar/index.story.js
+++ b/packages/react-ui-components/src/Bar/index.story.js
@@ -1,8 +1,8 @@
import React from 'react';
import {storiesOf} from '@storybook/react';
import {withKnobs, select} from '@storybook/addon-knobs';
-import {StoryWrapper} from './../_lib/storyUtils.js';
-import Bar from './index.js';
+import {StoryWrapper} from './../_lib/storyUtils';
+import Bar from '.';
storiesOf('Bar', module)
.addDecorator(withKnobs)
diff --git a/packages/react-ui-components/src/Button/__snapshots__/button.spec.js.snap b/packages/react-ui-components/src/Button/__snapshots__/button.spec.js.snap
index 08ceb85b4f..07bd72b830 100644
--- a/packages/react-ui-components/src/Button/__snapshots__/button.spec.js.snap
+++ b/packages/react-ui-components/src/Button/__snapshots__/button.spec.js.snap
@@ -3,6 +3,7 @@
exports[` should render correctly. 1`] = `
- );
- }
-}
-
-export default Button;
diff --git a/packages/react-ui-components/src/Button/button.spec.js b/packages/react-ui-components/src/Button/button.spec.js
index 2d79b1a18b..9ef769798c 100644
--- a/packages/react-ui-components/src/Button/button.spec.js
+++ b/packages/react-ui-components/src/Button/button.spec.js
@@ -1,7 +1,7 @@
import React from 'react';
import {shallow} from 'enzyme';
import toJson from 'enzyme-to-json';
-import Button from './button.js';
+import Button from './button';
describe('', () => {
let props;
diff --git a/packages/react-ui-components/src/Button/button.tsx b/packages/react-ui-components/src/Button/button.tsx
new file mode 100644
index 0000000000..261e9509c4
--- /dev/null
+++ b/packages/react-ui-components/src/Button/button.tsx
@@ -0,0 +1,155 @@
+import mergeClassNames from 'classnames';
+import React from 'react';
+
+import {Omit, PickDefaultProps} from '../../types';
+import {makeFocusNode} from '../_lib/focusNode';
+
+export type ButtonStyle = 'clean' | 'brand' | 'lighter' | 'transparent' | 'warn';
+export type ButtonHoverStyle = 'clean' | 'brand' | 'darken' | 'warn';
+export type ButtonSize = 'small' | 'regular';
+
+interface ButtonTheme {
+ readonly 'btn': string;
+ readonly 'btn--clean': string;
+ readonly 'btn--lighter': string;
+ readonly 'btn--transparent': string;
+ readonly 'btn--brand': string;
+ readonly 'btn--brandActive': string;
+ readonly 'btn--brandHover': string;
+ readonly 'btn--cleanHover': string;
+ readonly 'btn--isPressed': string;
+ readonly 'btn--darkenHover': string;
+}
+
+// We omit the standard HTML button style attribute,
+// so we have no collision with the Button component's style property,
+// while still enjoying the intellisense and type checking for the rest of the HTML button attributes
+type HTMLButtonElementAttributesExceptStyle = Omit, 'style'>;
+
+// own props and (optional) HTML button attributes except 'style'
+export interface ButtonProps extends HTMLButtonElementAttributesExceptStyle {
+ /**
+ * This prop controls the visual pressed state of the `Button`.
+ */
+ readonly isPressed?: boolean;
+
+ /**
+ * This prop controls the visual focused state of the `Button`.
+ * When `true`, the node gets focused via the DOM API.
+ */
+ readonly isFocused?: boolean;
+
+ /**
+ * This prop controls the visual and interactive disabled state of the `Button`.
+ * When `true`, the node gets rendered with a truthy `disabled` prop.
+ */
+ readonly isDisabled?: boolean;
+
+ /**
+ * This prop controls the visual active state of the `Button`.
+ */
+ readonly isActive?: boolean;
+
+ /**
+ * The `kind` prop defines the regular visual style of the `Button`.
+ */
+ readonly style?: ButtonStyle;
+
+ /**
+ * As the `style` prop, this prop controls the visual :hover style of the `Button`.
+ */
+ readonly hoverStyle?: ButtonHoverStyle;
+
+ /**
+ * Defines the size of the button.
+ */
+ readonly size: ButtonSize;
+
+ /**
+ * An optional `className` to attach to the wrapper.
+ */
+ readonly className?: string;
+
+ /**
+ * The contents to be rendered within the `Bar`.
+ */
+ readonly children: React.ReactNode;
+
+ /**
+ * An optional css theme to be injected.
+ */
+ readonly theme?: ButtonTheme;
+
+ /**
+ * An interal prop for testing purposes, do not set this prop manually.
+ */
+ readonly _refHandler?: (isFocused: boolean) => (node: any) => void;
+}
+
+type DefaultProps = PickDefaultProps;
+
+const defaultProps: DefaultProps = {
+ _refHandler: makeFocusNode,
+ hoverStyle: 'brand',
+ isActive: false,
+ isDisabled: false,
+ isFocused: false,
+ size: 'regular',
+ style: 'lighter',
+ type: 'button',
+};
+
+class Button extends React.PureComponent {
+ public static readonly defaultProps = defaultProps;
+
+ public render(): JSX.Element {
+ const {
+ children,
+ className,
+ isPressed,
+ isFocused,
+ isDisabled,
+ isActive,
+ style,
+ hoverStyle,
+ size,
+ theme,
+ type,
+ _refHandler,
+ ...rest
+ } = this.props;
+ const effectiveStyle = isActive ? 'brand' : style;
+ const effectiveHoverStyle = isActive ? 'brand' : hoverStyle;
+ const finalClassName = mergeClassNames(
+ theme!.btn,
+ // @ts-ignore implizit any because ButtonTheme has no index signature
+ theme![`btn--size-${size}`],
+ // @ts-ignore implizit any because ButtonTheme has no index signature
+ theme![`btn--${effectiveStyle!}`],
+ // @ts-ignore implizit any because ButtonTheme has no index signature
+ theme![`btn--${effectiveHoverStyle!}Hover`],
+ {
+ [theme!['btn--brandActive']]: isActive,
+ [theme!['btn--isPressed']]: isPressed,
+ },
+ className,
+ );
+
+ return (
+
+ );
+ }
+}
+
+export default Button;
diff --git a/packages/react-ui-components/src/Button/index.js b/packages/react-ui-components/src/Button/index.js
index 34dcf12a1a..f5cf48e6be 100644
--- a/packages/react-ui-components/src/Button/index.js
+++ b/packages/react-ui-components/src/Button/index.js
@@ -1,6 +1,6 @@
import {themr} from '@friendsofreactjs/react-css-themr';
-import identifiers from './../identifiers';
+import identifiers from '../identifiers';
import style from './style.css';
-import Button from './button.js';
+import Button from './button';
export default themr(identifiers.button, style)(Button);
diff --git a/packages/react-ui-components/src/Button/index.spec.js b/packages/react-ui-components/src/Button/index.spec.js
index b06e92562d..6c8a3b0dca 100644
--- a/packages/react-ui-components/src/Button/index.spec.js
+++ b/packages/react-ui-components/src/Button/index.spec.js
@@ -1,4 +1,4 @@
-import Button from './index.js';
+import Button from '.';
describe(' (entry point)', () => {
it('should export a Component.', () => {
diff --git a/packages/react-ui-components/src/Button/index.story.js b/packages/react-ui-components/src/Button/index.story.js
index 64ab670823..fe8963a45f 100644
--- a/packages/react-ui-components/src/Button/index.story.js
+++ b/packages/react-ui-components/src/Button/index.story.js
@@ -1,8 +1,8 @@
import React from 'react';
import {storiesOf, action} from '@storybook/react';
import {withKnobs, text, boolean, select} from '@storybook/addon-knobs';
-import {StoryWrapper} from './../_lib/storyUtils.js';
-import Button from './index.js';
+import {StoryWrapper} from './../_lib/storyUtils';
+import Button from '.';
const validSizes = ['small', 'regular'];
@@ -26,7 +26,7 @@ storiesOf('Button', module)
isActive={boolean('Active', false)}
isDisabled={boolean('Disabled', false)}
size={select('Size', validSizes, 'regular')}
- >
+ >
{text('Label', 'Button Clean')}
@@ -86,7 +86,7 @@ storiesOf('Button', module)
isActive={boolean('Active', false)}
isDisabled={boolean('Disabled', false)}
size={select('Size', validSizes, 'regular')}
- >
+ >
{text('Label', 'Button Clean')}
@@ -149,7 +149,7 @@ storiesOf('Button', module)
isActive={boolean('Active', false)}
isDisabled={boolean('Disabled', false)}
size={select('Size', validSizes, 'regular')}
- >
+ >
{text('Label', 'Button Clean')}
@@ -212,7 +212,7 @@ storiesOf('Button', module)
isActive={boolean('Active', false)}
isDisabled={boolean('Disabled', false)}
size={select('Size', validSizes, 'regular')}
- >
+ >
{text('Label', 'Button Clean')}
diff --git a/packages/react-ui-components/src/ButtonGroup/buttonGroup.js b/packages/react-ui-components/src/ButtonGroup/buttonGroup.js
index ed29474d17..003dbe7f17 100644
--- a/packages/react-ui-components/src/ButtonGroup/buttonGroup.js
+++ b/packages/react-ui-components/src/ButtonGroup/buttonGroup.js
@@ -1,7 +1,7 @@
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import mergeClassNames from 'classnames';
-import ButtonGroupItem from './buttonGroupItem.js';
+import ButtonGroupItem from './buttonGroupItem';
class ButtonGroup extends PureComponent {
static propTypes = {
diff --git a/packages/react-ui-components/src/ButtonGroup/buttonGroup.spec.js b/packages/react-ui-components/src/ButtonGroup/buttonGroup.spec.js
index cb1c500c12..8f69ae79b5 100644
--- a/packages/react-ui-components/src/ButtonGroup/buttonGroup.spec.js
+++ b/packages/react-ui-components/src/ButtonGroup/buttonGroup.spec.js
@@ -1,7 +1,7 @@
import React from 'react';
import {shallow} from 'enzyme';
import toJson from 'enzyme-to-json';
-import ButtonGroup from './buttonGroup.js';
+import ButtonGroup from './buttonGroup';
describe('', () => {
let props;
diff --git a/packages/react-ui-components/src/ButtonGroup/buttonGroupItem.spec.js b/packages/react-ui-components/src/ButtonGroup/buttonGroupItem.spec.js
index 87c307884b..0500b12ef2 100644
--- a/packages/react-ui-components/src/ButtonGroup/buttonGroupItem.spec.js
+++ b/packages/react-ui-components/src/ButtonGroup/buttonGroupItem.spec.js
@@ -1,7 +1,7 @@
import React from 'react';
import {shallow} from 'enzyme';
import toJson from 'enzyme-to-json';
-import ButtonGroupItem from './buttonGroupItem.js';
+import ButtonGroupItem from './buttonGroupItem';
describe('', () => {
let props;
diff --git a/packages/react-ui-components/src/ButtonGroup/index.js b/packages/react-ui-components/src/ButtonGroup/index.js
index e5909798fe..af7f13d704 100644
--- a/packages/react-ui-components/src/ButtonGroup/index.js
+++ b/packages/react-ui-components/src/ButtonGroup/index.js
@@ -1,6 +1,6 @@
import {themr} from '@friendsofreactjs/react-css-themr';
-import identifiers from './../identifiers';
+import identifiers from '../identifiers';
import style from './style.css';
-import ButtonGroup from './buttonGroup.js';
+import ButtonGroup from './buttonGroup';
export default themr(identifiers.buttonGroup, style)(ButtonGroup);
diff --git a/packages/react-ui-components/src/ButtonGroup/index.spec.js b/packages/react-ui-components/src/ButtonGroup/index.spec.js
index 34272574f1..0390b14e87 100644
--- a/packages/react-ui-components/src/ButtonGroup/index.spec.js
+++ b/packages/react-ui-components/src/ButtonGroup/index.spec.js
@@ -1,4 +1,4 @@
-import ButtonGroup from './index.js';
+import ButtonGroup from '.';
describe(' (entry point)', () => {
it('should export a Component.', () => {
diff --git a/packages/react-ui-components/src/ButtonGroup/index.story.js b/packages/react-ui-components/src/ButtonGroup/index.story.js
index efb81f39d1..e1b12ffe97 100644
--- a/packages/react-ui-components/src/ButtonGroup/index.story.js
+++ b/packages/react-ui-components/src/ButtonGroup/index.story.js
@@ -1,9 +1,9 @@
import React from 'react';
import {storiesOf, action} from '@storybook/react';
import {withKnobs} from '@storybook/addon-knobs';
-import {StoryWrapper} from './../_lib/storyUtils.js';
-import ButtonGroup from './index.js';
-import IconButton from './../IconButton/index.js';
+import {StoryWrapper} from './../_lib/storyUtils';
+import ButtonGroup from '.';
+import IconButton from './../IconButton';
storiesOf('ButtonGroup', module)
.addDecorator(withKnobs)
@@ -18,20 +18,20 @@ storiesOf('ButtonGroup', module)
style="lighter"
icon="level-up-alt"
title="One, active"
- />
+ />
+ />
+ />
),
diff --git a/packages/react-ui-components/src/CheckBox/checkBox.js b/packages/react-ui-components/src/CheckBox/checkBox.js
deleted file mode 100644
index 607731e5ba..0000000000
--- a/packages/react-ui-components/src/CheckBox/checkBox.js
+++ /dev/null
@@ -1,81 +0,0 @@
-import React, {PureComponent} from 'react';
-import PropTypes from 'prop-types';
-import mergeClassNames from 'classnames';
-
-class CheckBox extends PureComponent {
- static propTypes = {
- /**
- * This prop controls the visual active state of the CheckBox.
- */
- isChecked: PropTypes.bool.isRequired,
-
- /**
- * This prop controls if the CheckBox is disabled or not.
- */
- isDisabled: PropTypes.bool,
-
- /**
- * An optional `className` to attach to the wrapper.
- */
- className: PropTypes.string,
-
- /**
- * An optional change handler which gets called once the user clicks on the CheckBox.
- */
- onChange: PropTypes.func,
-
- /**
- * An optional css theme to be injected.
- */
- theme: PropTypes.shape({
- checkbox: PropTypes.string,
- checkbox__input: PropTypes.string, // eslint-disable-line
- checkbox__inputMirror: PropTypes.string, // eslint-disable-line
- 'checkbox__inputMirror--active': PropTypes.string
- }).isRequired
- };
-
- handleChange = () => {
- const {onChange, isChecked} = this.props;
-
- if (onChange) {
- onChange(!isChecked);
- }
- }
-
- render() {
- const {
- isChecked,
- isDisabled,
- className,
- theme,
- ...rest
- } = this.props;
- const finalClassName = mergeClassNames({
- [className]: className && className.length,
- [theme.checkbox]: true,
- [theme.checkbox__disabled]: isDisabled
- });
- const mirrorClassNames = mergeClassNames({
- [theme.checkbox__inputMirror]: true,
- [theme['checkbox__inputMirror--active']]: isChecked
- });
-
- return (
-
-
-
-
- );
- }
-}
-
-export default CheckBox;
diff --git a/packages/react-ui-components/src/CheckBox/checkBox.spec.js b/packages/react-ui-components/src/CheckBox/checkBox.spec.js
index 1bf4952f82..5d61833569 100644
--- a/packages/react-ui-components/src/CheckBox/checkBox.spec.js
+++ b/packages/react-ui-components/src/CheckBox/checkBox.spec.js
@@ -1,7 +1,7 @@
import React from 'react';
import {shallow} from 'enzyme';
import toJson from 'enzyme-to-json';
-import CheckBox from './checkBox.js';
+import CheckBox from './checkBox';
describe('', () => {
let props;
diff --git a/packages/react-ui-components/src/CheckBox/checkBox.tsx b/packages/react-ui-components/src/CheckBox/checkBox.tsx
new file mode 100644
index 0000000000..5efde12d0d
--- /dev/null
+++ b/packages/react-ui-components/src/CheckBox/checkBox.tsx
@@ -0,0 +1,87 @@
+import mergeClassNames from 'classnames';
+import React, {PureComponent} from 'react';
+
+interface CheckBoxTheme {
+ readonly checkbox: string;
+ readonly checkbox__disabled: string;
+ readonly checkbox__input: string; // eslint-disable-line
+ readonly checkbox__inputMirror: string; // eslint-disable-line
+ readonly 'checkbox__inputMirror--active': string;
+}
+
+interface CheckBoxProps {
+ /**
+ * This prop controls the visual active state of the CheckBox.
+ */
+ readonly isChecked: boolean;
+
+ /**
+ * This prop controls if the CheckBox is disabled or not.
+ */
+ readonly isDisabled?: boolean;
+
+ /**
+ * An optional `className` to attach to the wrapper.
+ */
+ readonly className?: string;
+
+ /**
+ * An optional change handler which gets called once the user clicks on the CheckBox.
+ */
+ readonly onChange?: (isChecked: boolean) => void;
+
+ /**
+ * An optional css theme to be injected.
+ */
+ readonly theme: CheckBoxTheme;
+}
+
+class CheckBox extends PureComponent {
+ public render(): JSX.Element {
+ const {
+ isChecked,
+ isDisabled,
+ className,
+ theme,
+ ...rest
+ } = this.props;
+ const finalClassName = mergeClassNames(
+ className,
+ theme.checkbox,
+ {
+ [theme.checkbox__disabled]: isDisabled,
+ }
+ );
+ const mirrorClassNames = mergeClassNames(
+ theme.checkbox__inputMirror,
+ {
+ [theme['checkbox__inputMirror--active']]: isChecked,
+ }
+ );
+
+ return (
+
+
+
+
+ );
+ }
+
+ private readonly handleChange = () => {
+ const {onChange, isChecked} = this.props;
+
+ if (onChange) {
+ onChange(!isChecked);
+ }
+ }
+}
+
+export default CheckBox;
diff --git a/packages/react-ui-components/src/CheckBox/index.js b/packages/react-ui-components/src/CheckBox/index.js
index b75e1289ed..dfa3133b33 100644
--- a/packages/react-ui-components/src/CheckBox/index.js
+++ b/packages/react-ui-components/src/CheckBox/index.js
@@ -1,6 +1,6 @@
import {themr} from '@friendsofreactjs/react-css-themr';
-import identifiers from './../identifiers';
+import identifiers from '../identifiers';
import style from './style.css';
-import CheckBox from './checkBox.js';
+import CheckBox from './checkBox';
export default themr(identifiers.checkBox, style)(CheckBox);
diff --git a/packages/react-ui-components/src/CheckBox/index.spec.js b/packages/react-ui-components/src/CheckBox/index.spec.js
index da2402fb53..7227f9dee6 100644
--- a/packages/react-ui-components/src/CheckBox/index.spec.js
+++ b/packages/react-ui-components/src/CheckBox/index.spec.js
@@ -1,4 +1,4 @@
-import CheckBox from './index.js';
+import CheckBox from '.';
describe(' (entry point)', () => {
it('should export a Component.', () => {
diff --git a/packages/react-ui-components/src/CheckBox/index.story.js b/packages/react-ui-components/src/CheckBox/index.story.js
index ab67ec46b7..440cb2cdd6 100644
--- a/packages/react-ui-components/src/CheckBox/index.story.js
+++ b/packages/react-ui-components/src/CheckBox/index.story.js
@@ -1,8 +1,8 @@
import React from 'react';
import {storiesOf, action} from '@storybook/react';
import {withKnobs, boolean} from '@storybook/addon-knobs';
-import {StoryWrapper} from './../_lib/storyUtils.js';
-import CheckBox from './index.js';
+import {StoryWrapper} from './../_lib/storyUtils';
+import CheckBox from '.';
storiesOf('CheckBox', module)
.addDecorator(withKnobs)
diff --git a/packages/react-ui-components/src/DateInput/dateInput.spec.js b/packages/react-ui-components/src/DateInput/dateInput.spec.js
index 7a2909f574..38b71659ba 100644
--- a/packages/react-ui-components/src/DateInput/dateInput.spec.js
+++ b/packages/react-ui-components/src/DateInput/dateInput.spec.js
@@ -2,8 +2,8 @@ import React from 'react';
import {shallow} from 'enzyme';
import toJson from 'enzyme-to-json';
import moment from 'moment';
-import {createStubComponent} from './../_lib/testUtils.js';
-import {DateInput} from './dateInput.js';
+import {createStubComponent} from './../_lib/testUtils';
+import {DateInput} from './dateInput';
describe('', () => {
let props;
diff --git a/packages/react-ui-components/src/DateInput/index.js b/packages/react-ui-components/src/DateInput/index.js
index 1e32e44031..5ba7f60aaa 100644
--- a/packages/react-ui-components/src/DateInput/index.js
+++ b/packages/react-ui-components/src/DateInput/index.js
@@ -1,5 +1,5 @@
import {themr} from '@friendsofreactjs/react-css-themr';
-import identifiers from './../identifiers';
+import identifiers from '../identifiers';
import style from './style.css';
import DateInput from './dateInput';
@@ -8,9 +8,9 @@ const ThemedDateInput = themr(identifiers.dateInput, style)(DateInput);
//
// Dependency injection
//
-import injectProps from './../_lib/injectProps.js';
-import Button from './../Button/index';
-import Icon from './../Icon/index';
+import injectProps from './../_lib/injectProps';
+import Button from './../Button';
+import Icon from './../Icon';
import DatePicker from 'react-datetime';
import Collapse from 'react-collapse';
diff --git a/packages/react-ui-components/src/DateInput/index.spec.js b/packages/react-ui-components/src/DateInput/index.spec.js
index 0f844289f2..0255b2aca1 100644
--- a/packages/react-ui-components/src/DateInput/index.spec.js
+++ b/packages/react-ui-components/src/DateInput/index.spec.js
@@ -1,4 +1,4 @@
-import DateInput from './index.js';
+import DateInput from '.';
describe(' (entry point)', () => {
it('should export a Component.', () => {
diff --git a/packages/react-ui-components/src/DateInput/index.story.js b/packages/react-ui-components/src/DateInput/index.story.js
index 447f8d1da3..055b4a23b4 100644
--- a/packages/react-ui-components/src/DateInput/index.story.js
+++ b/packages/react-ui-components/src/DateInput/index.story.js
@@ -1,8 +1,8 @@
import React from 'react';
import {storiesOf, action} from '@storybook/react';
import {withKnobs, text, boolean} from '@storybook/addon-knobs';
-import {StoryWrapper} from './../_lib/storyUtils.js';
-import DateInput from './index.js';
+import {StoryWrapper} from './../_lib/storyUtils';
+import DateInput from '.';
storiesOf('DateInput', module)
.addDecorator(withKnobs)
diff --git a/packages/react-ui-components/src/Dialog/dialog.spec.js b/packages/react-ui-components/src/Dialog/dialog.spec.js
index 5ccf65771c..589d155a76 100644
--- a/packages/react-ui-components/src/Dialog/dialog.spec.js
+++ b/packages/react-ui-components/src/Dialog/dialog.spec.js
@@ -1,8 +1,8 @@
import React from 'react';
import {shallow} from 'enzyme';
import toJson from 'enzyme-to-json';
-import {createStubComponent} from './../_lib/testUtils.js';
-import {DialogWithoutEscape as Dialog} from './dialog.js';
+import {createStubComponent} from './../_lib/testUtils';
+import {DialogWithoutEscape as Dialog} from './dialog';
import Portal from 'react-portal';
describe('', () => {
diff --git a/packages/react-ui-components/src/Dialog/index.js b/packages/react-ui-components/src/Dialog/index.js
index 44cbd9433a..0f66bdc57c 100644
--- a/packages/react-ui-components/src/Dialog/index.js
+++ b/packages/react-ui-components/src/Dialog/index.js
@@ -1,15 +1,15 @@
import {themr} from '@friendsofreactjs/react-css-themr';
-import identifiers from './../identifiers';
+import identifiers from '../identifiers';
import style from './style.css';
-import Dialog from './dialog.js';
+import Dialog from './dialog';
const ThemedDialog = themr(identifiers.dialog, style)(Dialog);
//
// Dependency injection
//
-import injectProps from './../_lib/injectProps.js';
-import IconButton from './../IconButton/index';
+import injectProps from './../_lib/injectProps';
+import IconButton from './../IconButton';
export default injectProps({
IconButtonComponent: IconButton
diff --git a/packages/react-ui-components/src/Dialog/index.spec.js b/packages/react-ui-components/src/Dialog/index.spec.js
index 97b7aabeb6..c2fad6657b 100644
--- a/packages/react-ui-components/src/Dialog/index.spec.js
+++ b/packages/react-ui-components/src/Dialog/index.spec.js
@@ -1,4 +1,4 @@
-import Dialog from './index.js';
+import Dialog from '.';
describe(' (entry point)', () => {
it('should export a Component.', () => {
diff --git a/packages/react-ui-components/src/Dialog/index.story.js b/packages/react-ui-components/src/Dialog/index.story.js
index 156ef77ec4..c85338cbe0 100644
--- a/packages/react-ui-components/src/Dialog/index.story.js
+++ b/packages/react-ui-components/src/Dialog/index.story.js
@@ -1,9 +1,9 @@
import React from 'react';
import {storiesOf, action} from '@storybook/react';
import {withKnobs, text, boolean} from '@storybook/addon-knobs';
-import {StoryWrapper} from './../_lib/storyUtils.js';
-import Dialog from './index.js';
-import Button from './../Button/index.js';
+import {StoryWrapper} from './../_lib/storyUtils';
+import Dialog from '.';
+import Button from './../Button';
storiesOf('Dialog', module)
.addDecorator(withKnobs)
diff --git a/packages/react-ui-components/src/DropDown/contents.spec.js b/packages/react-ui-components/src/DropDown/contents.spec.js
index 6a793709c5..9c8313c4e6 100644
--- a/packages/react-ui-components/src/DropDown/contents.spec.js
+++ b/packages/react-ui-components/src/DropDown/contents.spec.js
@@ -1,7 +1,7 @@
import React from 'react';
import {shallow} from 'enzyme';
import toJson from 'enzyme-to-json';
-import ShallowDropDownContents from './contents.js';
+import ShallowDropDownContents from './contents';
describe('', () => {
let props;
diff --git a/packages/react-ui-components/src/DropDown/header.spec.js b/packages/react-ui-components/src/DropDown/header.spec.js
index be89fe1f20..92b0f982f0 100644
--- a/packages/react-ui-components/src/DropDown/header.spec.js
+++ b/packages/react-ui-components/src/DropDown/header.spec.js
@@ -1,8 +1,8 @@
import React from 'react';
import {shallow} from 'enzyme';
import toJson from 'enzyme-to-json';
-import {createStubComponent} from './../_lib/testUtils.js';
-import ShallowDropDownHeader from './header.js';
+import {createStubComponent} from './../_lib/testUtils';
+import ShallowDropDownHeader from './header';
describe('', () => {
let props;
diff --git a/packages/react-ui-components/src/DropDown/index.js b/packages/react-ui-components/src/DropDown/index.js
index 4454c198fc..8bb41f15b3 100644
--- a/packages/react-ui-components/src/DropDown/index.js
+++ b/packages/react-ui-components/src/DropDown/index.js
@@ -1,11 +1,11 @@
import {themr} from '@friendsofreactjs/react-css-themr';
-import identifiers from './../identifiers';
+import identifiers from '../identifiers';
import style from './style.css';
import ContextDropDownWrapper, {
StatelessDropDownWrapper,
ContextDropDownHeader,
ContextDropDownContents
-} from './wrapper.js';
+} from './wrapper';
const DropDown = themr(identifiers.dropDown, style)(ContextDropDownWrapper);
const StatelessDropDown = themr(identifiers.dropDown, style)(StatelessDropDownWrapper);
@@ -15,8 +15,8 @@ const DropDownContents = themr(identifiers.dropDownContents, style)(ContextDropD
//
// Dependency injection
//
-import injectProps from './../_lib/injectProps.js';
-import Icon from './../Icon/index';
+import injectProps from './../_lib/injectProps';
+import Icon from './../Icon';
DropDown.Header = injectProps({
IconComponent: Icon
diff --git a/packages/react-ui-components/src/DropDown/index.spec.js b/packages/react-ui-components/src/DropDown/index.spec.js
index afdbe32140..1d88a1dcd0 100644
--- a/packages/react-ui-components/src/DropDown/index.spec.js
+++ b/packages/react-ui-components/src/DropDown/index.spec.js
@@ -1,4 +1,4 @@
-import DropDown from './index.js';
+import DropDown from '.';
describe(' (entry point)', () => {
it('should export a Component.', () => {
diff --git a/packages/react-ui-components/src/DropDown/index.story.js b/packages/react-ui-components/src/DropDown/index.story.js
index 9e5385cf79..b6c669856a 100644
--- a/packages/react-ui-components/src/DropDown/index.story.js
+++ b/packages/react-ui-components/src/DropDown/index.story.js
@@ -1,8 +1,8 @@
import React from 'react';
import {storiesOf} from '@storybook/react';
import {withKnobs, text, boolean, select} from '@storybook/addon-knobs';
-import {StoryWrapper} from './../_lib/storyUtils.js';
-import DropDown from './index.js';
+import {StoryWrapper} from './../_lib/storyUtils';
+import DropDown from '.';
const validStyles = ['default', 'darker'];
diff --git a/packages/react-ui-components/src/DropDown/wrapper.js b/packages/react-ui-components/src/DropDown/wrapper.js
index d0289de7ab..b9c4483ce2 100644
--- a/packages/react-ui-components/src/DropDown/wrapper.js
+++ b/packages/react-ui-components/src/DropDown/wrapper.js
@@ -3,8 +3,8 @@ import PropTypes from 'prop-types';
import omit from 'lodash.omit';
import mergeClassNames from 'classnames';
import enhanceWithClickOutside from 'react-click-outside';
-import ShallowDropDownHeader from './header.js';
-import ShallowDropDownContents from './contents.js';
+import ShallowDropDownHeader from './header';
+import ShallowDropDownContents from './contents';
const wrapperPropTypes = {
/**
diff --git a/packages/react-ui-components/src/DropDown/wrapper.spec.js b/packages/react-ui-components/src/DropDown/wrapper.spec.js
index 1b77bcc389..8c1d1488f5 100644
--- a/packages/react-ui-components/src/DropDown/wrapper.spec.js
+++ b/packages/react-ui-components/src/DropDown/wrapper.spec.js
@@ -1,7 +1,7 @@
import React from 'react';
import {shallow} from 'enzyme';
import toJson from 'enzyme-to-json';
-import {DropDownWrapper} from './wrapper.js';
+import {DropDownWrapper} from './wrapper';
describe('', () => {
let props;
diff --git a/packages/react-ui-components/src/Frame/frame.spec.js b/packages/react-ui-components/src/Frame/frame.spec.js
index 3e9b74728e..414c2d7b17 100644
--- a/packages/react-ui-components/src/Frame/frame.spec.js
+++ b/packages/react-ui-components/src/Frame/frame.spec.js
@@ -1,7 +1,7 @@
import React from 'react';
import {shallow} from 'enzyme';
import toJson from 'enzyme-to-json';
-import Frame from './frame.js';
+import Frame from './frame';
describe('', () => {
let props;
diff --git a/packages/react-ui-components/src/Frame/index.js b/packages/react-ui-components/src/Frame/index.js
index eab1e2411d..c700ea82ed 100644
--- a/packages/react-ui-components/src/Frame/index.js
+++ b/packages/react-ui-components/src/Frame/index.js
@@ -1,5 +1,5 @@
import {themr} from '@friendsofreactjs/react-css-themr';
-import identifiers from './../identifiers';
-import Frame from './frame.js';
+import identifiers from '../identifiers';
+import Frame from './frame';
export default themr(identifiers.frame)(Frame);
diff --git a/packages/react-ui-components/src/Frame/index.spec.js b/packages/react-ui-components/src/Frame/index.spec.js
index 549fbc7e8c..068f05264e 100644
--- a/packages/react-ui-components/src/Frame/index.spec.js
+++ b/packages/react-ui-components/src/Frame/index.spec.js
@@ -1,4 +1,4 @@
-import Frame from './index.js';
+import Frame from '.';
describe(' (entry point)', () => {
it('should export a Component.', () => {
diff --git a/packages/react-ui-components/src/Headline/headline.js b/packages/react-ui-components/src/Headline/headline.js
deleted file mode 100644
index 43246b7f61..0000000000
--- a/packages/react-ui-components/src/Headline/headline.js
+++ /dev/null
@@ -1,95 +0,0 @@
-import React, {PureComponent} from 'react';
-import PropTypes from 'prop-types';
-import mergeClassNames from 'classnames';
-
-const types = [
- 'h1',
- 'h2',
- 'h3',
- 'h4',
- 'h5',
- 'h6'
-];
-
-class Headline extends PureComponent {
- static propTypes = {
- /**
- * The contents to be rendered.
- */
- children: PropTypes.any.isRequired,
-
- /**
- * The semantic tag type of the headline.
- */
- type: PropTypes.oneOf(types).isRequired,
-
- /**
- * Optional style identifier, this enables the possibility to diff the
- * semantic value of the UI to the displayed style.
- */
- style: PropTypes.oneOf(types),
-
- /**
- * An optional `className` to attach to the wrapper.
- */
- className: PropTypes.string,
-
- /**
- * An optional css theme to be injected.
- */
- theme: PropTypes.shape({
- 'heading': PropTypes.string,
- 'heading--h1': PropTypes.string
- }).isRequired
- };
-
- static defaultProps = {
- type: 'h1'
- };
-
- render() {
- const {
- type,
- className,
- children,
- theme,
- ...rest
- } = this.props;
- const classNames = mergeClassNames({
- [theme.heading]: true,
- [theme['heading--h1']]: true,
- [className]: className && className.length
- });
- let heading;
-
- switch (type) {
- case 'h1':
- heading =
{children}
;
- break;
-
- case 'h2':
- heading =
{children}
;
- break;
-
- case 'h3':
- heading =
{children}
;
- break;
-
- case 'h4':
- heading =
{children}
;
- break;
-
- case 'h5':
- heading =
{children}
;
- break;
-
- default:
- heading =
{children}
;
- break;
- }
-
- return heading;
- }
-}
-
-export default Headline;
diff --git a/packages/react-ui-components/src/Headline/headline.spec.js b/packages/react-ui-components/src/Headline/headline.spec.js
index 6d13e216b4..50c3242572 100644
--- a/packages/react-ui-components/src/Headline/headline.spec.js
+++ b/packages/react-ui-components/src/Headline/headline.spec.js
@@ -1,7 +1,7 @@
import React from 'react';
import {shallow} from 'enzyme';
import toJson from 'enzyme-to-json';
-import Headline from './headline.js';
+import Headline from './headline';
describe('', () => {
let props;
diff --git a/packages/react-ui-components/src/Headline/headline.tsx b/packages/react-ui-components/src/Headline/headline.tsx
new file mode 100644
index 0000000000..5274236740
--- /dev/null
+++ b/packages/react-ui-components/src/Headline/headline.tsx
@@ -0,0 +1,76 @@
+import mergeClassNames from 'classnames';
+import React, {PureComponent} from 'react';
+
+import {PickDefaultProps} from '../../types';
+
+type HeadlineType = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
+
+interface HeadlineTheme {
+ readonly 'heading': string;
+ readonly 'heading--h1': string;
+}
+
+interface HeadlineProps {
+ /**
+ * The contents to be rendered.
+ */
+ readonly children: React.ReactNode;
+
+ /**
+ * The semantic tag type of the headline.
+ */
+ readonly type: HeadlineType;
+
+ /**
+ * Optional style identifier, this enables the possibility to diff the
+ * semantic value of the UI to the displayed style.
+ */
+ readonly style?: HeadlineType;
+
+ /**
+ * An optional `className` to attach to the wrapper.
+ */
+ readonly className?: string;
+
+ /**
+ * An optional css theme to be injected.
+ */
+ readonly theme?: HeadlineTheme;
+}
+
+type DefaultProps = PickDefaultProps;
+
+class Headline extends PureComponent {
+ public static readonly defaultProps: DefaultProps = {
+ type: 'h1',
+ };
+
+ public render(): JSX.Element {
+ const {
+ type,
+ className,
+ children,
+ theme,
+ style, // TODO: Discuss what this style prop should do.
+ ...rest
+ } = this.props;
+ const classNames = mergeClassNames(theme!.heading, theme!['heading--h1'], className);
+
+ switch (type) {
+ case 'h1':
+ return
{
- const {onClick, id} = this.props;
- onClick(id);
- };
-
- render() {
- const {children, ...rest} = this.props;
-
- return (
-
- {children}
-
- );
- }
-}
-
-export default DropDownItem;
diff --git a/packages/react-ui-components/src/IconButtonDropDown/dropDownItem.spec.js b/packages/react-ui-components/src/IconButtonDropDown/dropDownItem.spec.js
index 6e9148063c..94514fe66b 100644
--- a/packages/react-ui-components/src/IconButtonDropDown/dropDownItem.spec.js
+++ b/packages/react-ui-components/src/IconButtonDropDown/dropDownItem.spec.js
@@ -1,7 +1,7 @@
import React from 'react';
import {shallow} from 'enzyme';
import toJson from 'enzyme-to-json';
-import DropDownItem from './dropDownItem.js';
+import DropDownItem from './dropDownItem';
describe('', () => {
let props;
diff --git a/packages/react-ui-components/src/IconButtonDropDown/dropDownItem.tsx b/packages/react-ui-components/src/IconButtonDropDown/dropDownItem.tsx
new file mode 100644
index 0000000000..959a6428b6
--- /dev/null
+++ b/packages/react-ui-components/src/IconButtonDropDown/dropDownItem.tsx
@@ -0,0 +1,44 @@
+import React, {PureComponent} from 'react';
+
+type DropDownItemId = string;
+
+interface DropDownItemProps {
+ /**
+ * The handler to call when clicking on the item of the DropDown.
+ */
+ readonly onClick: (id: DropDownItemId) => void;
+
+ /**
+ * The ID to reference the clicked item in the `onClick` handker.
+ */
+ readonly id: DropDownItemId;
+
+ /**
+ * The children to render within the anchor.
+ */
+ readonly children: React.ReactNode;
+
+ readonly className: string;
+}
+
+class DropDownItem extends PureComponent {
+ public render(): JSX.Element {
+ const {children, ...rest} = this.props;
+
+ return (
+
+ {children}
+
+ );
+ }
+
+ private readonly handleClick = () => {
+ this.props.onClick(this.props.id);
+ }
+}
+
+export default DropDownItem;
diff --git a/packages/react-ui-components/src/IconButtonDropDown/iconButtonDropDown.js b/packages/react-ui-components/src/IconButtonDropDown/iconButtonDropDown.js
deleted file mode 100644
index 5956b4ccd2..0000000000
--- a/packages/react-ui-components/src/IconButtonDropDown/iconButtonDropDown.js
+++ /dev/null
@@ -1,190 +0,0 @@
-import React, {PureComponent} from 'react';
-import PropTypes from 'prop-types';
-import mergeClassNames from 'classnames';
-import DropDownItem from './dropDownItem.js';
-
-export default class IconButtonDropDown extends PureComponent {
- state = {
- isOpen: false
- };
-
- _mouseHoldTimeout = null;
-
- _mouseHoverTimeout = null;
-
- static propTypes = {
- /**
- * The key of the Icon which is always displayed.
- */
- icon: PropTypes.string.isRequired,
-
- /**
- * Children to be rendered inside the DropDown.
- */
- children: PropTypes.any.isRequired,
-
- /**
- * You can pass an modeIcon which displays the current selected item in a leaner way.
- * Modify this prop via listening to the `onItemSelect` propType.
- */
- modeIcon: PropTypes.string.isRequired,
-
- /**
- * Will be called once the user clicks on the wrapper if
- * it is NOT opened right meow.
- */
- onClick: PropTypes.func.isRequired,
-
- /**
- * Will be called once the user selects an item.
- * You should specify an `dropDownId` prop on each child,
- * which will then be propagated to this handler as the first
- * and only argument.
- */
- onItemSelect: PropTypes.func.isRequired,
-
- /**
- * An optional css theme to be injected.
- */
- theme: PropTypes.shape({
- 'wrapper': PropTypes.string,
- 'wrapper__btn': PropTypes.string,
- 'wrapper__btnModeIcon': PropTypes.string,
- 'wrapper__dropDown': PropTypes.string,
- 'wrapper__dropDown--isOpen': PropTypes.string,
- 'wrapper__dropDownItem': PropTypes.string
- }).isRequired,
-
- /**
- * Static component dependencies which are injected from the outside (index.js)
- */
- IconComponent: PropTypes.any.isRequired,
- ButtonComponent: PropTypes.any.isRequired,
-
- /**
- * An optional `className` to attach to the wrapper.
- */
- className: PropTypes.string,
-
- /**
- * Controls the whole components disabled state.
- */
- isDisabled: PropTypes.bool,
-
- /**
- * Props which are propagated to the