@sb1/ffe-buttons-react 14.0.0 → 14.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/ActionButton.js +63 -0
- package/es/ActionButton.spec.js +31 -0
- package/es/BackButton.js +28 -0
- package/es/BackButton.spec.js +25 -0
- package/es/BaseButton.js +96 -0
- package/es/BaseButton.spec.js +91 -0
- package/es/ButtonGroup.js +38 -0
- package/es/ButtonGroup.spec.js +43 -0
- package/es/ExpandButton.js +75 -0
- package/es/ExpandButton.spec.js +87 -0
- package/es/InlineBaseButton.js +69 -0
- package/es/InlineBaseButton.spec.js +59 -0
- package/es/InlineExpandButton.js +45 -0
- package/es/InlineExpandButton.spec.js +50 -0
- package/es/PrimaryButton.js +46 -0
- package/es/PrimaryButton.spec.js +25 -0
- package/es/SecondaryButton.js +46 -0
- package/es/SecondaryButton.spec.js +25 -0
- package/es/ShortcutButton.js +39 -0
- package/es/ShortcutButton.spec.js +30 -0
- package/es/TaskButton.js +47 -0
- package/es/TaskButton.spec.js +33 -0
- package/es/TertiaryButton.js +34 -0
- package/es/TertiaryButton.spec.js +25 -0
- package/es/index.js +10 -0
- package/lib/ActionButton.js +77 -0
- package/lib/ActionButton.spec.js +38 -0
- package/lib/BackButton.js +40 -0
- package/lib/BackButton.spec.js +32 -0
- package/lib/BaseButton.js +108 -0
- package/lib/BaseButton.spec.js +98 -0
- package/lib/ButtonGroup.js +50 -0
- package/lib/ButtonGroup.spec.js +50 -0
- package/lib/ExpandButton.js +94 -0
- package/lib/ExpandButton.spec.js +97 -0
- package/lib/InlineBaseButton.js +81 -0
- package/lib/InlineBaseButton.spec.js +66 -0
- package/lib/InlineExpandButton.js +58 -0
- package/lib/InlineExpandButton.spec.js +58 -0
- package/lib/PrimaryButton.js +58 -0
- package/lib/PrimaryButton.spec.js +32 -0
- package/lib/SecondaryButton.js +58 -0
- package/lib/SecondaryButton.spec.js +32 -0
- package/lib/ShortcutButton.js +52 -0
- package/lib/ShortcutButton.spec.js +38 -0
- package/lib/TaskButton.js +59 -0
- package/lib/TaskButton.spec.js +41 -0
- package/lib/TertiaryButton.js +46 -0
- package/lib/TertiaryButton.spec.js +32 -0
- package/lib/index.js +87 -0
- package/package.json +2 -2
- package/types/index.d.ts +104 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
var _excluded = ["className", "ghost"];
|
|
2
|
+
|
|
3
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
4
|
+
|
|
5
|
+
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
6
|
+
|
|
7
|
+
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
8
|
+
|
|
9
|
+
import React from 'react';
|
|
10
|
+
import { bool, func, node, string, oneOfType, object, shape, elementType } from 'prop-types';
|
|
11
|
+
import classNames from 'classnames';
|
|
12
|
+
import Button from './BaseButton';
|
|
13
|
+
export default function ActionButton(props) {
|
|
14
|
+
var className = props.className,
|
|
15
|
+
ghost = props.ghost,
|
|
16
|
+
rest = _objectWithoutProperties(props, _excluded);
|
|
17
|
+
|
|
18
|
+
return /*#__PURE__*/React.createElement(Button, _extends({
|
|
19
|
+
buttonType: "action",
|
|
20
|
+
className: classNames(className, {
|
|
21
|
+
'ffe-button--ghost': ghost
|
|
22
|
+
})
|
|
23
|
+
}, rest));
|
|
24
|
+
}
|
|
25
|
+
ActionButton.propTypes = {
|
|
26
|
+
/** Aria label for loading indicator */
|
|
27
|
+
ariaLoadingMessage: string,
|
|
28
|
+
|
|
29
|
+
/** The button label */
|
|
30
|
+
children: node,
|
|
31
|
+
|
|
32
|
+
/** Extra class names */
|
|
33
|
+
className: string,
|
|
34
|
+
|
|
35
|
+
/** Condensed modifier. Use in condensed designs */
|
|
36
|
+
condensed: bool,
|
|
37
|
+
|
|
38
|
+
/** Disable a button in certain situations */
|
|
39
|
+
disabled: bool,
|
|
40
|
+
|
|
41
|
+
/** The rendered element, like an `<a />` or `<Link />` */
|
|
42
|
+
element: oneOfType([func, string, elementType]),
|
|
43
|
+
|
|
44
|
+
/** Applies the ghost modifier if true. */
|
|
45
|
+
ghost: bool,
|
|
46
|
+
|
|
47
|
+
/** Ref-setting function, or ref created by useRef, passed to the button element */
|
|
48
|
+
innerRef: oneOfType([func, shape({
|
|
49
|
+
current: object
|
|
50
|
+
})]),
|
|
51
|
+
|
|
52
|
+
/** Shows a loader if true */
|
|
53
|
+
isLoading: bool,
|
|
54
|
+
|
|
55
|
+
/** Icon shown to the left of the label */
|
|
56
|
+
leftIcon: node,
|
|
57
|
+
|
|
58
|
+
/** Icon shown to the right of the label */
|
|
59
|
+
rightIcon: node
|
|
60
|
+
};
|
|
61
|
+
ActionButton.defaultProps = {
|
|
62
|
+
ghost: false
|
|
63
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { shallow } from 'enzyme';
|
|
5
|
+
import ActionButton from './ActionButton';
|
|
6
|
+
var defaultProps = {
|
|
7
|
+
children: 'Click me'
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
var getWrapper = function getWrapper(props) {
|
|
11
|
+
return shallow( /*#__PURE__*/React.createElement(ActionButton, _extends({}, defaultProps, props)));
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
describe('<ActionButton />', function () {
|
|
15
|
+
it('renders without exploding', function () {
|
|
16
|
+
var wrapper = getWrapper();
|
|
17
|
+
expect(wrapper.props()).toHaveProperty('buttonType', 'action');
|
|
18
|
+
});
|
|
19
|
+
it('passes on any prop', function () {
|
|
20
|
+
var wrapper = getWrapper({
|
|
21
|
+
'aria-label': 'some label'
|
|
22
|
+
});
|
|
23
|
+
expect(wrapper.props()).toHaveProperty('aria-label', 'some label');
|
|
24
|
+
});
|
|
25
|
+
it('sets correct class when ghost prop is true', function () {
|
|
26
|
+
var wrapper = getWrapper({
|
|
27
|
+
ghost: true
|
|
28
|
+
});
|
|
29
|
+
expect(wrapper.hasClass('ffe-button--ghost')).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
});
|
package/es/BackButton.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { oneOfType, func, node, string, object, shape, elementType } from 'prop-types';
|
|
5
|
+
import InlineButton from './InlineBaseButton';
|
|
6
|
+
|
|
7
|
+
var BackButton = function BackButton(props) {
|
|
8
|
+
return /*#__PURE__*/React.createElement(InlineButton, _extends({
|
|
9
|
+
buttonType: "back"
|
|
10
|
+
}, props));
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
BackButton.propTypes = {
|
|
14
|
+
/** The button label */
|
|
15
|
+
children: node,
|
|
16
|
+
|
|
17
|
+
/** Extra class names */
|
|
18
|
+
className: string,
|
|
19
|
+
|
|
20
|
+
/** The rendered element, like an `<a />` or `<Link />` */
|
|
21
|
+
element: oneOfType([func, string, elementType]),
|
|
22
|
+
|
|
23
|
+
/** Ref-setting function, or ref created by useRef, passed to the button element */
|
|
24
|
+
innerRef: oneOfType([func, shape({
|
|
25
|
+
current: object
|
|
26
|
+
})])
|
|
27
|
+
};
|
|
28
|
+
export default BackButton;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { shallow } from 'enzyme';
|
|
5
|
+
import BackButton from './BackButton';
|
|
6
|
+
var defaultProps = {
|
|
7
|
+
children: 'Click me'
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
var getWrapper = function getWrapper(props) {
|
|
11
|
+
return shallow( /*#__PURE__*/React.createElement(BackButton, _extends({}, defaultProps, props)));
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
describe('<BackButton />', function () {
|
|
15
|
+
it('renders without exploding', function () {
|
|
16
|
+
var wrapper = getWrapper();
|
|
17
|
+
expect(wrapper.props()).toHaveProperty('buttonType', 'back');
|
|
18
|
+
});
|
|
19
|
+
it('passes on any prop', function () {
|
|
20
|
+
var wrapper = getWrapper({
|
|
21
|
+
'aria-label': 'some label'
|
|
22
|
+
});
|
|
23
|
+
expect(wrapper.props()).toHaveProperty('aria-label', 'some label');
|
|
24
|
+
});
|
|
25
|
+
});
|
package/es/BaseButton.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
var _excluded = ["ariaLoadingMessage", "buttonType", "children", "className", "condensed", "disabled", "element", "innerRef", "isLoading", "leftIcon", "rightIcon"];
|
|
2
|
+
|
|
3
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
4
|
+
|
|
5
|
+
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
6
|
+
|
|
7
|
+
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
8
|
+
|
|
9
|
+
import React from 'react';
|
|
10
|
+
import { bool, func, node, oneOf, oneOfType, string, object, shape, elementType } from 'prop-types';
|
|
11
|
+
import classNames from 'classnames';
|
|
12
|
+
/**
|
|
13
|
+
* Internal component
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
var BaseButton = function BaseButton(props) {
|
|
17
|
+
var ariaLoadingMessage = props.ariaLoadingMessage,
|
|
18
|
+
buttonType = props.buttonType,
|
|
19
|
+
children = props.children,
|
|
20
|
+
className = props.className,
|
|
21
|
+
condensed = props.condensed,
|
|
22
|
+
disabled = props.disabled,
|
|
23
|
+
Element = props.element,
|
|
24
|
+
innerRef = props.innerRef,
|
|
25
|
+
isLoading = props.isLoading,
|
|
26
|
+
leftIcon = props.leftIcon,
|
|
27
|
+
rightIcon = props.rightIcon,
|
|
28
|
+
rest = _objectWithoutProperties(props, _excluded);
|
|
29
|
+
|
|
30
|
+
var supportsSpinner = ['action', 'primary', 'secondary'].includes(buttonType);
|
|
31
|
+
return /*#__PURE__*/React.createElement(Element, _extends({
|
|
32
|
+
"aria-busy": isLoading && supportsSpinner,
|
|
33
|
+
"aria-disabled": disabled || isLoading && supportsSpinner,
|
|
34
|
+
className: classNames('ffe-button', "ffe-button--".concat(buttonType), {
|
|
35
|
+
'ffe-button--condensed': condensed
|
|
36
|
+
}, {
|
|
37
|
+
'ffe-button--loading': isLoading && supportsSpinner
|
|
38
|
+
}, className),
|
|
39
|
+
ref: innerRef
|
|
40
|
+
}, rest), /*#__PURE__*/React.createElement("span", {
|
|
41
|
+
className: "ffe-button__label"
|
|
42
|
+
}, leftIcon && /*#__PURE__*/React.cloneElement(leftIcon, {
|
|
43
|
+
className: 'ffe-button__icon ffe-button__icon--left'
|
|
44
|
+
}), children, rightIcon && /*#__PURE__*/React.cloneElement(rightIcon, {
|
|
45
|
+
className: 'ffe-button__icon ffe-button__icon--right'
|
|
46
|
+
})), supportsSpinner && /*#__PURE__*/React.createElement("span", {
|
|
47
|
+
"aria-hidden": !isLoading,
|
|
48
|
+
"aria-label": ariaLoadingMessage,
|
|
49
|
+
className: "ffe-button__spinner"
|
|
50
|
+
}));
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
BaseButton.propTypes = {
|
|
54
|
+
/** Aria label for loading indicator */
|
|
55
|
+
ariaLoadingMessage: string,
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Enum of supported prop types. Used internally only.
|
|
59
|
+
* @ignore
|
|
60
|
+
*/
|
|
61
|
+
buttonType: oneOf(['action', 'primary', 'secondary', 'shortcut', 'task']),
|
|
62
|
+
|
|
63
|
+
/** The button label */
|
|
64
|
+
children: node,
|
|
65
|
+
|
|
66
|
+
/** Extra class names */
|
|
67
|
+
className: string,
|
|
68
|
+
|
|
69
|
+
/** Condensed modifier. Use in condensed designs */
|
|
70
|
+
condensed: bool,
|
|
71
|
+
|
|
72
|
+
/** Disable a button in certain situations */
|
|
73
|
+
disabled: bool,
|
|
74
|
+
|
|
75
|
+
/** The rendered element, like an `<a />` or `<Link />` */
|
|
76
|
+
element: oneOfType([func, string, elementType]),
|
|
77
|
+
|
|
78
|
+
/** Ref-setting function, or ref created by useRef, passed to the button element */
|
|
79
|
+
innerRef: oneOfType([func, shape({
|
|
80
|
+
current: object
|
|
81
|
+
})]),
|
|
82
|
+
|
|
83
|
+
/** Shows a loader if true */
|
|
84
|
+
isLoading: bool,
|
|
85
|
+
|
|
86
|
+
/** Icon shown to the left of the label */
|
|
87
|
+
leftIcon: node,
|
|
88
|
+
|
|
89
|
+
/** Icon shown to the right of the label */
|
|
90
|
+
rightIcon: node
|
|
91
|
+
};
|
|
92
|
+
BaseButton.defaultProps = {
|
|
93
|
+
ariaLoadingMessage: 'Vennligst vent',
|
|
94
|
+
element: 'button'
|
|
95
|
+
};
|
|
96
|
+
export default BaseButton;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { shallow } from 'enzyme';
|
|
5
|
+
import BaseButton from './BaseButton';
|
|
6
|
+
var defaultProps = {
|
|
7
|
+
children: 'Click me'
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
var getWrapper = function getWrapper(props) {
|
|
11
|
+
return shallow( /*#__PURE__*/React.createElement(BaseButton, _extends({}, defaultProps, props)));
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
describe('<BaseButton />', function () {
|
|
15
|
+
it('renders without exploding', function () {
|
|
16
|
+
var wrapper = getWrapper();
|
|
17
|
+
expect(wrapper.exists()).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
it('renders the correct classes', function () {
|
|
20
|
+
var wrapper = getWrapper();
|
|
21
|
+
expect(wrapper.hasClass('ffe-button')).toBe(true);
|
|
22
|
+
wrapper.setProps({
|
|
23
|
+
className: 'custom-class',
|
|
24
|
+
buttonType: 'action'
|
|
25
|
+
});
|
|
26
|
+
expect(wrapper.hasClass('ffe-button--action')).toBe(true);
|
|
27
|
+
expect(wrapper.hasClass('custom-class')).toBe(true);
|
|
28
|
+
});
|
|
29
|
+
it('renders the correct label', function () {
|
|
30
|
+
var wrapper = getWrapper();
|
|
31
|
+
expect(wrapper.text()).toBe('Click me');
|
|
32
|
+
wrapper.setProps({
|
|
33
|
+
children: 'Press me'
|
|
34
|
+
});
|
|
35
|
+
expect(wrapper.text()).toBe('Press me');
|
|
36
|
+
});
|
|
37
|
+
it('renders left icon if set', function () {
|
|
38
|
+
var wrapper = getWrapper();
|
|
39
|
+
expect(wrapper.find('.ffe-button__icon--left').exists()).toBe(false);
|
|
40
|
+
wrapper.setProps({
|
|
41
|
+
leftIcon: /*#__PURE__*/React.createElement("svg", null)
|
|
42
|
+
});
|
|
43
|
+
expect(wrapper.find('.ffe-button__icon--left').exists()).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
it('renders right icon if set', function () {
|
|
46
|
+
var wrapper = getWrapper();
|
|
47
|
+
expect(wrapper.find('.ffe-button__icon--right').exists()).toBe(false);
|
|
48
|
+
wrapper.setProps({
|
|
49
|
+
rightIcon: /*#__PURE__*/React.createElement("svg", null)
|
|
50
|
+
});
|
|
51
|
+
expect(wrapper.find('.ffe-button__icon--right').exists()).toBe(true);
|
|
52
|
+
});
|
|
53
|
+
it('renders the specified dom node', function () {
|
|
54
|
+
var wrapper = getWrapper({
|
|
55
|
+
element: 'a'
|
|
56
|
+
});
|
|
57
|
+
expect(wrapper.is('a')).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
describe('when loading', function () {
|
|
60
|
+
it('sets the correct class', function () {
|
|
61
|
+
var wrapper = getWrapper({
|
|
62
|
+
buttonType: 'primary',
|
|
63
|
+
isLoading: true
|
|
64
|
+
});
|
|
65
|
+
expect(wrapper.hasClass('ffe-button--loading')).toBe(true);
|
|
66
|
+
});
|
|
67
|
+
it('sets the correct aria tags', function () {
|
|
68
|
+
var wrapper = getWrapper({
|
|
69
|
+
buttonType: 'primary',
|
|
70
|
+
isLoading: true
|
|
71
|
+
});
|
|
72
|
+
expect(wrapper.prop('aria-busy')).toBe(true);
|
|
73
|
+
});
|
|
74
|
+
it('disables the button', function () {
|
|
75
|
+
var wrapper = getWrapper({
|
|
76
|
+
buttonType: 'primary',
|
|
77
|
+
isLoading: true
|
|
78
|
+
});
|
|
79
|
+
expect(wrapper.prop('aria-disabled')).toBe(true);
|
|
80
|
+
});
|
|
81
|
+
it('does nothing for unsupported button type', function () {
|
|
82
|
+
var wrapper = getWrapper({
|
|
83
|
+
buttonType: 'shortcut',
|
|
84
|
+
isLoading: true
|
|
85
|
+
});
|
|
86
|
+
expect(wrapper.hasClass('ffe-button--loading')).toBe(false);
|
|
87
|
+
expect(wrapper.prop('aria-busy')).toBe(false);
|
|
88
|
+
expect(wrapper.prop('aria-disabled')).toBe(false);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
var _excluded = ["className", "thin", "inline"];
|
|
2
|
+
|
|
3
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
4
|
+
|
|
5
|
+
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
6
|
+
|
|
7
|
+
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
8
|
+
|
|
9
|
+
import React from 'react';
|
|
10
|
+
import { bool, string } from 'prop-types';
|
|
11
|
+
import classNames from 'classnames';
|
|
12
|
+
|
|
13
|
+
var ButtonGroup = function ButtonGroup(_ref) {
|
|
14
|
+
var className = _ref.className,
|
|
15
|
+
thin = _ref.thin,
|
|
16
|
+
inline = _ref.inline,
|
|
17
|
+
rest = _objectWithoutProperties(_ref, _excluded);
|
|
18
|
+
|
|
19
|
+
return /*#__PURE__*/React.createElement("div", _extends({
|
|
20
|
+
className: classNames('ffe-button-group', {
|
|
21
|
+
'ffe-button-group--thin': thin
|
|
22
|
+
}, {
|
|
23
|
+
'ffe-button-group--inline': inline
|
|
24
|
+
}, className)
|
|
25
|
+
}, rest));
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
ButtonGroup.propTypes = {
|
|
29
|
+
/** Extra class name applied in addition to the FFE classes */
|
|
30
|
+
className: string,
|
|
31
|
+
|
|
32
|
+
/** Applies the thin modifier to remove margins */
|
|
33
|
+
thin: bool,
|
|
34
|
+
|
|
35
|
+
/** Applies the inline modifier to make all child buttons inline */
|
|
36
|
+
inline: bool
|
|
37
|
+
};
|
|
38
|
+
export default ButtonGroup;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { shallow } from 'enzyme';
|
|
5
|
+
import ButtonGroup from './ButtonGroup';
|
|
6
|
+
var defaultProps = {
|
|
7
|
+
thin: false
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
var getWrapper = function getWrapper(props) {
|
|
11
|
+
return shallow( /*#__PURE__*/React.createElement(ButtonGroup, _extends({}, defaultProps, props)));
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
describe('<ButtonGroup />', function () {
|
|
15
|
+
it('renders without exploding', function () {
|
|
16
|
+
var wrapper = getWrapper();
|
|
17
|
+
expect(wrapper.exists()).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
it('renders without the the --thin modifier if thin is false', function () {
|
|
20
|
+
var wrapper = getWrapper({
|
|
21
|
+
thin: false
|
|
22
|
+
});
|
|
23
|
+
expect(wrapper.hasClass('ffe-button-group--thin')).toBe(false);
|
|
24
|
+
});
|
|
25
|
+
it('applies the --thin modifier if thin is true', function () {
|
|
26
|
+
var wrapper = getWrapper({
|
|
27
|
+
thin: true
|
|
28
|
+
});
|
|
29
|
+
expect(wrapper.hasClass('ffe-button-group--thin')).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
it('applies the --inline modifier if inline is true', function () {
|
|
32
|
+
var wrapper = getWrapper({
|
|
33
|
+
inline: true
|
|
34
|
+
});
|
|
35
|
+
expect(wrapper.hasClass('ffe-button-group--inline')).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
it('applies the given className prop', function () {
|
|
38
|
+
var wrapper = getWrapper({
|
|
39
|
+
className: 'my-class'
|
|
40
|
+
});
|
|
41
|
+
expect(wrapper.hasClass('my-class')).toBe(true);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
var _excluded = ["children", "className", "closeLabel", "element", "innerRef", "isExpanded", "leftIcon", "rightIcon"];
|
|
2
|
+
|
|
3
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
4
|
+
|
|
5
|
+
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
6
|
+
|
|
7
|
+
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
8
|
+
|
|
9
|
+
import React, { Fragment } from 'react';
|
|
10
|
+
import { bool, func, oneOfType, string, node, object, shape, elementType } from 'prop-types';
|
|
11
|
+
import classNames from 'classnames';
|
|
12
|
+
import KryssIkon from '@sb1/ffe-icons-react/lib/kryss-ikon';
|
|
13
|
+
|
|
14
|
+
var ExpandButton = function ExpandButton(props) {
|
|
15
|
+
var children = props.children,
|
|
16
|
+
className = props.className,
|
|
17
|
+
closeLabel = props.closeLabel,
|
|
18
|
+
Element = props.element,
|
|
19
|
+
innerRef = props.innerRef,
|
|
20
|
+
isExpanded = props.isExpanded,
|
|
21
|
+
leftIcon = props.leftIcon,
|
|
22
|
+
rightIcon = props.rightIcon,
|
|
23
|
+
rest = _objectWithoutProperties(props, _excluded);
|
|
24
|
+
|
|
25
|
+
return /*#__PURE__*/React.createElement(Element, _extends({
|
|
26
|
+
"aria-expanded": isExpanded,
|
|
27
|
+
"aria-label": isExpanded ? closeLabel : undefined,
|
|
28
|
+
className: classNames('ffe-button', 'ffe-button--expand', {
|
|
29
|
+
'ffe-button--expanded': isExpanded
|
|
30
|
+
}, className),
|
|
31
|
+
ref: innerRef
|
|
32
|
+
}, rest), isExpanded && /*#__PURE__*/React.createElement(KryssIkon, {
|
|
33
|
+
className: "ffe-button__icon"
|
|
34
|
+
}), !isExpanded && /*#__PURE__*/React.createElement(Fragment, null, leftIcon && /*#__PURE__*/React.cloneElement(leftIcon, {
|
|
35
|
+
className: 'ffe-button__icon ffe-button__icon--left'
|
|
36
|
+
}), children, rightIcon && /*#__PURE__*/React.cloneElement(rightIcon, {
|
|
37
|
+
className: 'ffe-button__icon ffe-button__icon--right'
|
|
38
|
+
})));
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
ExpandButton.propTypes = {
|
|
42
|
+
/** The button label */
|
|
43
|
+
children: node.isRequired,
|
|
44
|
+
|
|
45
|
+
/** Extra class names */
|
|
46
|
+
className: string,
|
|
47
|
+
|
|
48
|
+
/** The rendered element, like an `<a />` or `<Link />` */
|
|
49
|
+
element: oneOfType([func, string, elementType]),
|
|
50
|
+
|
|
51
|
+
/** An accessible label for the close-button, only shown in the "isExpanded" state */
|
|
52
|
+
closeLabel: string,
|
|
53
|
+
|
|
54
|
+
/** Icon shown to the left of the label */
|
|
55
|
+
leftIcon: node,
|
|
56
|
+
|
|
57
|
+
/** Icon shown to the right of the label */
|
|
58
|
+
rightIcon: node,
|
|
59
|
+
|
|
60
|
+
/** Ref-setting function, or ref created by useRef, passed to the button element */
|
|
61
|
+
innerRef: oneOfType([func, shape({
|
|
62
|
+
current: object
|
|
63
|
+
})]),
|
|
64
|
+
|
|
65
|
+
/** When true the component will render a circle with an X indicating whatever is controlled is in an expanded state. */
|
|
66
|
+
isExpanded: bool.isRequired,
|
|
67
|
+
|
|
68
|
+
/** Use to listen for clicks and toggle the `isExpanded` property together with whatever it is you're expanding. */
|
|
69
|
+
onClick: func.isRequired
|
|
70
|
+
};
|
|
71
|
+
ExpandButton.defaultProps = {
|
|
72
|
+
closeLabel: 'Lukk',
|
|
73
|
+
element: 'button'
|
|
74
|
+
};
|
|
75
|
+
export default ExpandButton;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { shallow } from 'enzyme';
|
|
5
|
+
import BamseIkon from '@sb1/ffe-icons-react/lib/bamse-ikon';
|
|
6
|
+
import BestikkIkon from '@sb1/ffe-icons-react/lib/bestikk-ikon';
|
|
7
|
+
import KryssIkon from '@sb1/ffe-icons-react/lib/kryss-ikon';
|
|
8
|
+
import ExpandButton from './ExpandButton';
|
|
9
|
+
var defaultProps = {
|
|
10
|
+
children: 'Click me',
|
|
11
|
+
isExpanded: false,
|
|
12
|
+
onClick: function onClick(f) {
|
|
13
|
+
return f;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
var getWrapper = function getWrapper(props) {
|
|
18
|
+
return shallow( /*#__PURE__*/React.createElement(ExpandButton, _extends({}, defaultProps, props)));
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
describe('<ExpandButton />', function () {
|
|
22
|
+
it('renders without exploding', function () {
|
|
23
|
+
var wrapper = getWrapper();
|
|
24
|
+
expect(wrapper.hasClass('ffe-button')).toBe(true);
|
|
25
|
+
expect(wrapper.hasClass('ffe-button--expand')).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
it('passes on any prop', function () {
|
|
28
|
+
var wrapper = getWrapper({
|
|
29
|
+
'aria-label': 'some label'
|
|
30
|
+
});
|
|
31
|
+
expect(wrapper.props()).toHaveProperty('aria-label', 'some label');
|
|
32
|
+
});
|
|
33
|
+
it('renders leftIcon and rightIcon', function () {
|
|
34
|
+
var wrapper = getWrapper({
|
|
35
|
+
leftIcon: /*#__PURE__*/React.createElement(BestikkIkon, null),
|
|
36
|
+
rightIcon: /*#__PURE__*/React.createElement(BamseIkon, null)
|
|
37
|
+
});
|
|
38
|
+
expect(wrapper.find(BestikkIkon).exists()).toBe(true);
|
|
39
|
+
expect(wrapper.find(BamseIkon).exists()).toBe(true);
|
|
40
|
+
});
|
|
41
|
+
it('does not use an aria-label since the button itself has a children acting as label', function () {
|
|
42
|
+
var wrapper = getWrapper();
|
|
43
|
+
expect(wrapper.prop('aria-label')).toBe(undefined);
|
|
44
|
+
});
|
|
45
|
+
describe('when expanded', function () {
|
|
46
|
+
it('does not render children', function () {
|
|
47
|
+
var wrapper = getWrapper({
|
|
48
|
+
isExpanded: true
|
|
49
|
+
});
|
|
50
|
+
expect(wrapper.text()).not.toContain('Click me');
|
|
51
|
+
});
|
|
52
|
+
it('does not render leftIcon and rightIcon', function () {
|
|
53
|
+
var wrapper = getWrapper({
|
|
54
|
+
leftIcon: /*#__PURE__*/React.createElement(BestikkIkon, null),
|
|
55
|
+
isExpanded: true,
|
|
56
|
+
rightIcon: /*#__PURE__*/React.createElement(BamseIkon, null)
|
|
57
|
+
});
|
|
58
|
+
expect(wrapper.find(BestikkIkon).exists()).toBe(false);
|
|
59
|
+
expect(wrapper.find(BamseIkon).exists()).toBe(false);
|
|
60
|
+
});
|
|
61
|
+
it('sets correct class', function () {
|
|
62
|
+
var wrapper = getWrapper({
|
|
63
|
+
isExpanded: true
|
|
64
|
+
});
|
|
65
|
+
expect(wrapper.hasClass('ffe-button--expanded')).toBe(true);
|
|
66
|
+
});
|
|
67
|
+
it('sets aria-expanded prop', function () {
|
|
68
|
+
var wrapper = getWrapper({
|
|
69
|
+
isExpanded: true
|
|
70
|
+
});
|
|
71
|
+
expect(wrapper.props()).toHaveProperty('aria-expanded', true);
|
|
72
|
+
});
|
|
73
|
+
it('renders a KryssIkon', function () {
|
|
74
|
+
var wrapper = getWrapper({
|
|
75
|
+
isExpanded: true
|
|
76
|
+
});
|
|
77
|
+
expect(wrapper.find(KryssIkon).exists()).toBe(true);
|
|
78
|
+
expect(wrapper.find(KryssIkon).hasClass('ffe-button__icon')).toBe(true);
|
|
79
|
+
});
|
|
80
|
+
it('uses the default aria-label property on the button', function () {
|
|
81
|
+
var wrapper = getWrapper({
|
|
82
|
+
isExpanded: true
|
|
83
|
+
});
|
|
84
|
+
expect(wrapper.prop('aria-label')).toBe(ExpandButton.defaultProps.closeLabel);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
var _excluded = ["buttonType", "children", "className", "element", "innerRef", "leftIcon", "rightIcon"];
|
|
2
|
+
|
|
3
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
4
|
+
|
|
5
|
+
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
6
|
+
|
|
7
|
+
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
8
|
+
|
|
9
|
+
import React from 'react';
|
|
10
|
+
import { func, string, oneOf, oneOfType, node, object, shape, elementType } from 'prop-types';
|
|
11
|
+
import classNames from 'classnames';
|
|
12
|
+
/**
|
|
13
|
+
* Internal component
|
|
14
|
+
* @ignore
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
var InlineBaseButton = function InlineBaseButton(props) {
|
|
18
|
+
var buttonType = props.buttonType,
|
|
19
|
+
children = props.children,
|
|
20
|
+
className = props.className,
|
|
21
|
+
Element = props.element,
|
|
22
|
+
innerRef = props.innerRef,
|
|
23
|
+
leftIcon = props.leftIcon,
|
|
24
|
+
rightIcon = props.rightIcon,
|
|
25
|
+
rest = _objectWithoutProperties(props, _excluded);
|
|
26
|
+
|
|
27
|
+
return /*#__PURE__*/React.createElement(Element, _extends({
|
|
28
|
+
className: classNames('ffe-inline-button', "ffe-inline-button--".concat(buttonType), className),
|
|
29
|
+
ref: innerRef
|
|
30
|
+
}, rest), leftIcon && /*#__PURE__*/React.cloneElement(leftIcon, {
|
|
31
|
+
className: 'ffe-inline-button__icon ffe-inline-button__icon--left'
|
|
32
|
+
}), /*#__PURE__*/React.createElement("span", {
|
|
33
|
+
className: "ffe-inline-button__label"
|
|
34
|
+
}, children), rightIcon && /*#__PURE__*/React.cloneElement(rightIcon, {
|
|
35
|
+
className: 'ffe-inline-button__icon ffe-inline-button__icon--right'
|
|
36
|
+
}));
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
InlineBaseButton.propTypes = {
|
|
40
|
+
/**
|
|
41
|
+
* Enum of supported prop types. Used internally only.
|
|
42
|
+
* @ignore
|
|
43
|
+
*/
|
|
44
|
+
buttonType: oneOf(['tertiary', 'back', 'expand']),
|
|
45
|
+
|
|
46
|
+
/** The button label */
|
|
47
|
+
children: node.isRequired,
|
|
48
|
+
|
|
49
|
+
/** Extra class names */
|
|
50
|
+
className: string,
|
|
51
|
+
|
|
52
|
+
/** The rendered element, like an `<a />` or `<Link />` */
|
|
53
|
+
element: oneOfType([string, func, elementType]),
|
|
54
|
+
|
|
55
|
+
/** Ref-setting function, or ref created by useRef, passed to the button element */
|
|
56
|
+
innerRef: oneOfType([func, shape({
|
|
57
|
+
current: object
|
|
58
|
+
})]),
|
|
59
|
+
|
|
60
|
+
/** Icon shown to the left of the label */
|
|
61
|
+
leftIcon: node,
|
|
62
|
+
|
|
63
|
+
/** Icon shown to the right of the label */
|
|
64
|
+
rightIcon: node
|
|
65
|
+
};
|
|
66
|
+
InlineBaseButton.defaultProps = {
|
|
67
|
+
element: 'button'
|
|
68
|
+
};
|
|
69
|
+
export default InlineBaseButton;
|