@axinom/mosaic-ui 0.32.0-rc.1 → 0.32.0-rc.11
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/dist/components/Actions/Action/Action.d.ts.map +1 -1
- package/dist/components/Actions/Actions.models.d.ts +4 -16
- package/dist/components/Actions/Actions.models.d.ts.map +1 -1
- package/dist/components/Buttons/Button/Button.d.ts +9 -10
- package/dist/components/Buttons/Button/Button.d.ts.map +1 -1
- package/dist/components/Buttons/Button/Button.model.d.ts +21 -0
- package/dist/components/Buttons/Button/Button.model.d.ts.map +1 -0
- package/dist/components/Buttons/Button/index.d.ts +3 -0
- package/dist/components/Buttons/Button/index.d.ts.map +1 -0
- package/dist/components/Buttons/Button.model.d.ts +69 -7
- package/dist/components/Buttons/Button.model.d.ts.map +1 -1
- package/dist/components/Buttons/CompositeButton/CompositeButton.d.ts +5 -14
- package/dist/components/Buttons/CompositeButton/CompositeButton.d.ts.map +1 -1
- package/dist/components/Buttons/CompositeButton/CompositeButton.model.d.ts +20 -0
- package/dist/components/Buttons/CompositeButton/CompositeButton.model.d.ts.map +1 -0
- package/dist/components/Buttons/CompositeButton/index.d.ts +3 -0
- package/dist/components/Buttons/CompositeButton/index.d.ts.map +1 -0
- package/dist/components/Buttons/TextButton/TextButton.d.ts +5 -9
- package/dist/components/Buttons/TextButton/TextButton.d.ts.map +1 -1
- package/dist/components/Buttons/TextButton/TextButton.model.d.ts +18 -0
- package/dist/components/Buttons/TextButton/TextButton.model.d.ts.map +1 -0
- package/dist/components/Buttons/TextButton/index.d.ts +3 -0
- package/dist/components/Buttons/TextButton/index.d.ts.map +1 -0
- package/dist/components/Buttons/index.d.ts +3 -3
- package/dist/components/Buttons/index.d.ts.map +1 -1
- package/dist/components/Explorer/Explorer.d.ts.map +1 -1
- package/dist/components/Explorer/Explorer.model.d.ts +2 -2
- package/dist/components/Explorer/Explorer.model.d.ts.map +1 -1
- package/dist/components/Explorer/NavigationExplorer/NavigationExplorer.d.ts +13 -3
- package/dist/components/Explorer/NavigationExplorer/NavigationExplorer.d.ts.map +1 -1
- package/dist/components/FormElements/ToggleButton/ToggleButton.d.ts +2 -2
- package/dist/components/FormElements/ToggleButton/ToggleButton.d.ts.map +1 -1
- package/dist/components/List/List.d.ts +1 -1
- package/dist/components/List/List.d.ts.map +1 -1
- package/dist/components/List/ListRow/ListRow.d.ts.map +1 -1
- package/dist/components/PageHeader/PageHeader.d.ts +1 -22
- package/dist/components/PageHeader/PageHeader.d.ts.map +1 -1
- package/dist/components/PageHeader/PageHeader.model.d.ts +23 -0
- package/dist/components/PageHeader/PageHeader.model.d.ts.map +1 -0
- package/dist/components/PageHeader/PageHeaderAction/PageHeaderAction.d.ts +20 -33
- package/dist/components/PageHeader/PageHeaderAction/PageHeaderAction.d.ts.map +1 -1
- package/dist/components/PageHeader/PageHeaderAction/PageHeaderAction.model.d.ts +47 -0
- package/dist/components/PageHeader/PageHeaderAction/PageHeaderAction.model.d.ts.map +1 -0
- package/dist/components/PageHeader/PageHeaderAction/index.d.ts +3 -0
- package/dist/components/PageHeader/PageHeaderAction/index.d.ts.map +1 -0
- package/dist/components/PageHeader/PageHeaderBulkActions/PageHeaderBulkActions.d.ts +2 -2
- package/dist/components/PageHeader/PageHeaderBulkActions/PageHeaderBulkActions.d.ts.map +1 -1
- package/dist/components/PageHeader/index.d.ts +3 -2
- package/dist/components/PageHeader/index.d.ts.map +1 -1
- package/dist/components/models.d.ts +22 -0
- package/dist/components/models.d.ts.map +1 -1
- package/dist/index.es.js +3 -3
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/components/Actions/Action/Action.spec.tsx +16 -2
- package/src/components/Actions/Action/Action.tsx +6 -3
- package/src/components/Actions/Actions.models.ts +4 -23
- package/src/components/Buttons/Button/Button.model.ts +30 -0
- package/src/components/Buttons/Button/Button.scss +3 -1
- package/src/components/Buttons/Button/Button.spec.tsx +254 -83
- package/src/components/Buttons/Button/Button.stories.tsx +20 -0
- package/src/components/Buttons/Button/Button.tsx +103 -32
- package/src/components/Buttons/Button/index.ts +2 -0
- package/src/components/Buttons/Button.model.ts +84 -9
- package/src/components/Buttons/CompositeButton/CompositeButton.model.ts +32 -0
- package/src/components/Buttons/CompositeButton/CompositeButton.scss +6 -1
- package/src/components/Buttons/CompositeButton/CompositeButton.spec.tsx +277 -89
- package/src/components/Buttons/CompositeButton/CompositeButton.stories.tsx +20 -0
- package/src/components/Buttons/CompositeButton/CompositeButton.tsx +94 -30
- package/src/components/Buttons/CompositeButton/index.ts +2 -0
- package/src/components/Buttons/TextButton/TextButton.model.ts +27 -0
- package/src/components/Buttons/TextButton/TextButton.scss +3 -1
- package/src/components/Buttons/TextButton/TextButton.spec.tsx +198 -87
- package/src/components/Buttons/TextButton/TextButton.stories.tsx +20 -0
- package/src/components/Buttons/TextButton/TextButton.tsx +74 -20
- package/src/components/Buttons/TextButton/index.ts +2 -0
- package/src/components/Buttons/index.ts +3 -6
- package/src/components/Explorer/Explorer.model.ts +2 -2
- package/src/components/Explorer/Explorer.tsx +21 -16
- package/src/components/Explorer/NavigationExplorer/NavigationExplorer.tsx +32 -11
- package/src/components/FormElements/CustomTags/CustomTags.spec.tsx +26 -16
- package/src/components/FormElements/ToggleButton/ToggleButton.tsx +3 -3
- package/src/components/List/List.spec.tsx +23 -0
- package/src/components/List/List.stories.tsx +8 -0
- package/src/components/List/List.tsx +15 -3
- package/src/components/List/ListRow/ListRow.tsx +18 -13
- package/src/components/PageHeader/PageHeader.model.ts +23 -0
- package/src/components/PageHeader/PageHeader.stories.tsx +2 -1
- package/src/components/PageHeader/PageHeader.tsx +2 -26
- package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.model.ts +60 -0
- package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.spec.tsx +550 -383
- package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.stories.tsx +12 -1
- package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.tsx +95 -45
- package/src/components/PageHeader/PageHeaderAction/index.ts +2 -0
- package/src/components/PageHeader/PageHeaderBulkActions/PageHeaderBulkActions.spec.tsx +2 -2
- package/src/components/PageHeader/PageHeaderBulkActions/PageHeaderBulkActions.tsx +56 -43
- package/src/components/PageHeader/index.ts +3 -2
- package/src/components/models.ts +30 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axinom/mosaic-ui",
|
|
3
|
-
"version": "0.32.0-rc.
|
|
3
|
+
"version": "0.32.0-rc.11",
|
|
4
4
|
"description": "UI components for building Axinom Mosaic applications",
|
|
5
5
|
"author": "Axinom",
|
|
6
6
|
"license": "PROPRIETARY",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"build-storybook": "storybook build"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@axinom/mosaic-core": "^0.4.5-rc.
|
|
35
|
+
"@axinom/mosaic-core": "^0.4.5-rc.11",
|
|
36
36
|
"@faker-js/faker": "^7.4.0",
|
|
37
37
|
"@popperjs/core": "^2.9.2",
|
|
38
38
|
"clsx": "^1.1.0",
|
|
@@ -102,5 +102,5 @@
|
|
|
102
102
|
"publishConfig": {
|
|
103
103
|
"access": "public"
|
|
104
104
|
},
|
|
105
|
-
"gitHead": "
|
|
105
|
+
"gitHead": "095178757a7c929d25376adb504388b86c747871"
|
|
106
106
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { mount, shallow } from 'enzyme';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { act } from 'react-dom/test-utils';
|
|
4
|
-
import { BrowserRouter as Router
|
|
4
|
+
import { Link, BrowserRouter as Router } from 'react-router-dom';
|
|
5
5
|
import { noop } from '../../../helpers/utils';
|
|
6
6
|
import { TextButton } from '../../Buttons';
|
|
7
|
-
import {
|
|
7
|
+
import { ConfirmDialog, ConfirmationConfig } from '../../ConfirmDialog';
|
|
8
8
|
import { IconName, Icons } from '../../Icons';
|
|
9
9
|
import {
|
|
10
10
|
Action,
|
|
@@ -62,6 +62,20 @@ describe('Action', () => {
|
|
|
62
62
|
expect(container.hasClass('hasIcon')).toBe(true);
|
|
63
63
|
});
|
|
64
64
|
|
|
65
|
+
it(`displays a 'External' as default icon when "openInNewTab: true"`, () => {
|
|
66
|
+
const wrapper = mount(
|
|
67
|
+
<Router>
|
|
68
|
+
<Action action={{ label: 'test', path: '/', openInNewTab: true }} />
|
|
69
|
+
</Router>,
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
const icon = wrapper.find(Icons);
|
|
73
|
+
const container = wrapper.find('.container').hostNodes();
|
|
74
|
+
|
|
75
|
+
expect(icon.prop('icon')).toBe(IconName.External);
|
|
76
|
+
expect(container.hasClass('hasIcon')).toBe(true);
|
|
77
|
+
});
|
|
78
|
+
|
|
65
79
|
it(`disables link when property isDisabled is 'true'`, () => {
|
|
66
80
|
const wrapper = mount(
|
|
67
81
|
<Router>
|
|
@@ -2,8 +2,8 @@ import clsx from 'clsx';
|
|
|
2
2
|
import React, { useEffect, useState } from 'react';
|
|
3
3
|
import { Link } from 'react-router-dom';
|
|
4
4
|
import {
|
|
5
|
-
ConfirmationConfig,
|
|
6
5
|
ConfirmDialog,
|
|
6
|
+
ConfirmationConfig,
|
|
7
7
|
useConfirmationDelay,
|
|
8
8
|
} from '../../ConfirmDialog';
|
|
9
9
|
import { IconName, Icons } from '../../Icons';
|
|
@@ -183,10 +183,12 @@ const NavigationAction: React.FC<{ action: NavigationActionData }> = ({
|
|
|
183
183
|
}) => {
|
|
184
184
|
const {
|
|
185
185
|
path,
|
|
186
|
+
openInNewTab = false,
|
|
186
187
|
label,
|
|
187
|
-
icon
|
|
188
|
+
icon,
|
|
188
189
|
isDisabled = false,
|
|
189
190
|
} = action;
|
|
191
|
+
const defaultIcon = openInNewTab ? IconName.External : IconName.ChevronRight;
|
|
190
192
|
return (
|
|
191
193
|
<Link
|
|
192
194
|
to={path}
|
|
@@ -200,9 +202,10 @@ const NavigationAction: React.FC<{ action: NavigationActionData }> = ({
|
|
|
200
202
|
'action-container',
|
|
201
203
|
)}
|
|
202
204
|
data-test-id="action"
|
|
205
|
+
target={openInNewTab ? '_blank' : undefined}
|
|
203
206
|
>
|
|
204
207
|
<span data-test-id="label">{label}</span>
|
|
205
|
-
<Icons icon={icon} className={classes.icon} />
|
|
208
|
+
<Icons icon={icon ? icon : defaultIcon} className={classes.icon} />
|
|
206
209
|
</Link>
|
|
207
210
|
);
|
|
208
211
|
};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Not } from '../../types';
|
|
2
|
-
import { ConfirmationConfig, ConfirmationMode } from '../ConfirmDialog';
|
|
3
2
|
import { IconName } from '../Icons';
|
|
4
|
-
import {
|
|
3
|
+
import { ConfirmAction, DefaultHandler, LinkAction } from '../models';
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* @deprecated ActionData interface has been changed and no longer uses `actionType` property
|
|
@@ -11,7 +10,7 @@ export enum ActionType {
|
|
|
11
10
|
Context,
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
export type ActionData<THandler =
|
|
13
|
+
export type ActionData<THandler = DefaultHandler> =
|
|
15
14
|
| ContextActionData<THandler>
|
|
16
15
|
| NavigationActionData;
|
|
17
16
|
|
|
@@ -20,7 +19,7 @@ export type ActionData<THandler = DefaultSelectionHandler> =
|
|
|
20
19
|
* to render an element with JS handler
|
|
21
20
|
* and specified confirmation mode for click event
|
|
22
21
|
*/
|
|
23
|
-
export interface ContextActionData<THandler =
|
|
22
|
+
export interface ContextActionData<THandler = DefaultHandler>
|
|
24
23
|
extends ActionBaseData,
|
|
25
24
|
ConfirmAction,
|
|
26
25
|
HandledAction<THandler>,
|
|
@@ -36,29 +35,11 @@ export interface NavigationActionData
|
|
|
36
35
|
Not<ConfirmAction>,
|
|
37
36
|
Not<HandledAction<unknown>> {}
|
|
38
37
|
|
|
39
|
-
export
|
|
40
|
-
| Promise<ErrorType | undefined | void>
|
|
41
|
-
| ErrorType
|
|
42
|
-
| undefined
|
|
43
|
-
| void;
|
|
44
|
-
|
|
45
|
-
interface LinkAction {
|
|
46
|
-
/** Path to navigate to when the action is clicked. */
|
|
47
|
-
path: string;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
interface HandledAction<THandler> {
|
|
38
|
+
export interface HandledAction<THandler> {
|
|
51
39
|
/** Callback emitted when a user clicks on the Action. */
|
|
52
40
|
onActionSelected: THandler;
|
|
53
41
|
}
|
|
54
42
|
|
|
55
|
-
interface ConfirmAction {
|
|
56
|
-
/** If set to 'Simple', the action will require confirmation. If set to 'Advanced', action will require confirmation via a confirmation pop up. (default: 'None') */
|
|
57
|
-
confirmationMode?: ConfirmationMode;
|
|
58
|
-
/** Optional text overrides for the confirmation pop up. */
|
|
59
|
-
confirmationConfig?: ConfirmationConfig;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
43
|
interface ActionBaseData {
|
|
63
44
|
/**
|
|
64
45
|
* @deprecated this property is no longer used,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { IconName } from '../../Icons';
|
|
2
|
+
import {
|
|
3
|
+
ButtonIconOptions,
|
|
4
|
+
CommonJsButtonOptions,
|
|
5
|
+
CommonNavigationButtonOptions,
|
|
6
|
+
} from '../Button.model';
|
|
7
|
+
|
|
8
|
+
export type ButtonProps =
|
|
9
|
+
| (NavigationButtonProps | ContextButtonProps) & {
|
|
10
|
+
/** Optional button's height (default: 50px) */
|
|
11
|
+
width?: string | number;
|
|
12
|
+
/** Optional button's height (default: 50px) */
|
|
13
|
+
height?: string | number;
|
|
14
|
+
/** Optional icon (default: IconName.ChevronRight) */
|
|
15
|
+
icon?: IconName;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Button options for icon buttons with navigation
|
|
20
|
+
*/
|
|
21
|
+
export interface NavigationButtonProps
|
|
22
|
+
extends CommonNavigationButtonOptions,
|
|
23
|
+
Pick<ButtonIconOptions, 'icon'> {}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Button options for icon buttons with JS handlers
|
|
27
|
+
*/
|
|
28
|
+
export interface ContextButtonProps
|
|
29
|
+
extends CommonJsButtonOptions,
|
|
30
|
+
Pick<ButtonIconOptions, 'icon'> {}
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
|
|
25
25
|
&.navigation {
|
|
26
26
|
background-color: $light-blue;
|
|
27
|
+
box-sizing: border-box;
|
|
27
28
|
|
|
28
29
|
svg * {
|
|
29
30
|
stroke: white;
|
|
@@ -41,8 +42,9 @@
|
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
&.disabled {
|
|
45
46
|
background-color: $gray;
|
|
47
|
+
pointer-events: none;
|
|
46
48
|
|
|
47
49
|
svg * {
|
|
48
50
|
opacity: 0.5;
|
|
@@ -1,130 +1,301 @@
|
|
|
1
|
-
import { mount
|
|
1
|
+
import { mount } from 'enzyme';
|
|
2
2
|
import React from 'react';
|
|
3
|
+
import { Link, BrowserRouter as Router } from 'react-router-dom';
|
|
3
4
|
import { IconName, Icons } from '../../Icons';
|
|
4
5
|
import { ButtonContext } from '../Button.model';
|
|
5
6
|
import { Button } from './Button';
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
const navigationButtonProps = {
|
|
9
|
+
path: '/test',
|
|
10
|
+
};
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
describe('Button (with icon)', () => {
|
|
13
|
+
describe('ContextButtonElement', () => {
|
|
14
|
+
it('renders the component without crashing', () => {
|
|
15
|
+
const wrapper = mount(<Button />);
|
|
13
16
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const wrapper = shallow(<Button onButtonClicked={spy} />);
|
|
17
|
+
expect(wrapper).toBeTruthy();
|
|
18
|
+
});
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
it('raises the onButtonClicked event', () => {
|
|
21
|
+
const spy = jest.fn();
|
|
22
|
+
const wrapper = mount(<Button onButtonClicked={spy} />);
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
});
|
|
24
|
+
wrapper.simulate('click');
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const wrapper = shallow(<Button className={mockClassName} />);
|
|
26
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
27
|
+
});
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
it('creates a class based off of the className prop', () => {
|
|
30
|
+
const mockClassName = 'test-class';
|
|
31
|
+
const wrapper = mount(<Button className={mockClassName} />);
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
});
|
|
33
|
+
const button = wrapper.find('button');
|
|
31
34
|
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
expect(button.hasClass(mockClassName)).toBe(true);
|
|
36
|
+
});
|
|
34
37
|
|
|
35
|
-
|
|
38
|
+
it(`button 'type' must be 'button' by default`, () => {
|
|
39
|
+
const wrapper = mount(<Button />);
|
|
36
40
|
|
|
37
|
-
|
|
38
|
-
});
|
|
41
|
+
const buttonType = wrapper.find('button').prop('type');
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const mockHeight = '75px';
|
|
43
|
-
const mockWidth = '80px';
|
|
43
|
+
expect(buttonType).toBe('button');
|
|
44
|
+
});
|
|
44
45
|
|
|
45
|
-
|
|
46
|
+
it('accepts type html attribute and width/height styles', () => {
|
|
47
|
+
const mockType = 'submit';
|
|
48
|
+
const mockHeight = '75px';
|
|
49
|
+
const mockWidth = '80px';
|
|
46
50
|
|
|
47
|
-
|
|
48
|
-
let buttonStyles = wrapper
|
|
49
|
-
.find('button')
|
|
50
|
-
.prop('style') as React.CSSProperties;
|
|
51
|
+
const wrapper = mount(<Button />);
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
let buttonType = wrapper.find('button').prop('type');
|
|
54
|
+
let buttonStyles = wrapper
|
|
55
|
+
.find('button')
|
|
56
|
+
.prop('style') as React.CSSProperties;
|
|
55
57
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
expect(buttonType).toBe('button');
|
|
59
|
+
expect(buttonStyles.height).toBeUndefined();
|
|
60
|
+
expect(buttonStyles.width).toBeUndefined();
|
|
58
61
|
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
wrapper.setProps({
|
|
63
|
+
type: mockType,
|
|
64
|
+
height: mockHeight,
|
|
65
|
+
width: mockWidth,
|
|
66
|
+
});
|
|
67
|
+
wrapper.update();
|
|
61
68
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
buttonType = wrapper.find('button').prop('type');
|
|
70
|
+
buttonStyles = wrapper
|
|
71
|
+
.find('button')
|
|
72
|
+
.prop('style') as React.CSSProperties;
|
|
66
73
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
74
|
+
expect(buttonType).toBe(mockType);
|
|
75
|
+
expect(buttonStyles.height).toBe(mockHeight);
|
|
76
|
+
expect(buttonStyles.width).toBe(mockWidth);
|
|
77
|
+
});
|
|
70
78
|
|
|
71
|
-
|
|
79
|
+
it('allows the button to be enabled by default', () => {
|
|
80
|
+
const spy = jest.fn();
|
|
81
|
+
const wrapper = mount(<Button onButtonClicked={spy} />);
|
|
72
82
|
|
|
73
|
-
|
|
83
|
+
const button = wrapper.find('button');
|
|
74
84
|
|
|
75
|
-
|
|
76
|
-
expect(spy).toHaveBeenCalledTimes(1);
|
|
77
|
-
});
|
|
85
|
+
wrapper.simulate('click');
|
|
78
86
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
87
|
+
expect(button.prop('disabled')).toBe(false);
|
|
88
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
89
|
+
});
|
|
82
90
|
|
|
83
|
-
|
|
91
|
+
it('allows button to be disabled', () => {
|
|
92
|
+
const spy = jest.fn();
|
|
93
|
+
const wrapper = mount(<Button disabled={true} onButtonClicked={spy} />);
|
|
84
94
|
|
|
85
|
-
|
|
95
|
+
const button = wrapper.find('button');
|
|
86
96
|
|
|
87
|
-
|
|
88
|
-
expect(spy).not.toHaveBeenCalled();
|
|
89
|
-
});
|
|
97
|
+
wrapper.simulate('click');
|
|
90
98
|
|
|
91
|
-
|
|
92
|
-
|
|
99
|
+
expect(button.prop('disabled')).toBe(true);
|
|
100
|
+
expect(spy).not.toHaveBeenCalled();
|
|
101
|
+
});
|
|
93
102
|
|
|
94
|
-
|
|
103
|
+
it('default should have a active class', () => {
|
|
104
|
+
const wrapper = mount(<Button />);
|
|
95
105
|
|
|
96
|
-
|
|
97
|
-
});
|
|
106
|
+
const button = wrapper.find('button');
|
|
98
107
|
|
|
99
|
-
|
|
100
|
-
|
|
108
|
+
expect(button.hasClass('active')).toBe(true);
|
|
109
|
+
});
|
|
101
110
|
|
|
102
|
-
|
|
111
|
+
it('context button type should have a context class', () => {
|
|
112
|
+
const wrapper = mount(<Button buttonContext={ButtonContext.Context} />);
|
|
103
113
|
|
|
104
|
-
|
|
105
|
-
});
|
|
114
|
+
const button = wrapper.find('button');
|
|
106
115
|
|
|
107
|
-
|
|
108
|
-
|
|
116
|
+
expect(button.hasClass('context')).toBe(true);
|
|
117
|
+
});
|
|
109
118
|
|
|
110
|
-
|
|
119
|
+
it('context button type should have a icon class', () => {
|
|
120
|
+
const wrapper = mount(<Button buttonContext={ButtonContext.Icon} />);
|
|
111
121
|
|
|
112
|
-
|
|
113
|
-
});
|
|
122
|
+
const button = wrapper.find('button');
|
|
114
123
|
|
|
115
|
-
|
|
116
|
-
|
|
124
|
+
expect(button.hasClass('icon')).toBe(true);
|
|
125
|
+
});
|
|
117
126
|
|
|
118
|
-
|
|
127
|
+
it('active button type should have a active class', () => {
|
|
128
|
+
const wrapper = mount(<Button buttonContext={ButtonContext.Active} />);
|
|
119
129
|
|
|
120
|
-
|
|
121
|
-
|
|
130
|
+
const button = wrapper.find('button');
|
|
131
|
+
|
|
132
|
+
expect(button.hasClass('active')).toBe(true);
|
|
133
|
+
});
|
|
122
134
|
|
|
123
|
-
|
|
124
|
-
|
|
135
|
+
it(`renders an icon as it's image from the Icons component`, () => {
|
|
136
|
+
const wrapper = mount(<Button icon={IconName.ChevronRight} />);
|
|
137
|
+
|
|
138
|
+
const icon = wrapper.find(Icons);
|
|
139
|
+
|
|
140
|
+
expect(icon.exists()).toBe(true);
|
|
141
|
+
});
|
|
142
|
+
});
|
|
125
143
|
|
|
126
|
-
|
|
144
|
+
describe('NavigationButtonElement', () => {
|
|
145
|
+
it('renders the component without crashing', () => {
|
|
146
|
+
const wrapper = mount(
|
|
147
|
+
<Router>
|
|
148
|
+
<Button {...navigationButtonProps} />
|
|
149
|
+
</Router>,
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
expect(wrapper).toBeTruthy();
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it('creates a class based on the className prop', () => {
|
|
156
|
+
const mockClassName = 'test-class';
|
|
157
|
+
const wrapper = mount(
|
|
158
|
+
<Router>
|
|
159
|
+
<Button {...navigationButtonProps} className={mockClassName} />,
|
|
160
|
+
</Router>,
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
const link = wrapper.find('Link');
|
|
164
|
+
|
|
165
|
+
expect(link.hasClass(mockClassName)).toBe(true);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('renders the correct path in the Link component', () => {
|
|
169
|
+
const mockPath = '/test';
|
|
170
|
+
const wrapper = mount(
|
|
171
|
+
<Router>
|
|
172
|
+
<Button path={mockPath} />
|
|
173
|
+
</Router>,
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
const link = wrapper.find('Link');
|
|
177
|
+
|
|
178
|
+
expect(link.prop('to')).toBe(mockPath);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('accepts width/height styles', () => {
|
|
182
|
+
const mockHeight = '75px';
|
|
183
|
+
const mockWidth = '80px';
|
|
184
|
+
|
|
185
|
+
const wrapper = mount(
|
|
186
|
+
<Router>
|
|
187
|
+
<Button
|
|
188
|
+
{...navigationButtonProps}
|
|
189
|
+
height={mockHeight}
|
|
190
|
+
width={mockWidth}
|
|
191
|
+
/>
|
|
192
|
+
</Router>,
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
const linkStyles = wrapper
|
|
196
|
+
.find('Link')
|
|
197
|
+
.prop('style') as React.CSSProperties;
|
|
198
|
+
|
|
199
|
+
expect(linkStyles.height).toBe(mockHeight);
|
|
200
|
+
expect(linkStyles.width).toBe(mockWidth);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it('allows the button to be enabled by default', () => {
|
|
204
|
+
const wrapper = mount(
|
|
205
|
+
<Router>
|
|
206
|
+
<Button {...navigationButtonProps} />
|
|
207
|
+
</Router>,
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
const link = wrapper.find('Link');
|
|
211
|
+
|
|
212
|
+
expect(link.hasClass('disabled')).toBe(false);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it('allows button to be disabled', () => {
|
|
216
|
+
const wrapper = mount(
|
|
217
|
+
<Router>
|
|
218
|
+
<Button {...navigationButtonProps} disabled={true} />
|
|
219
|
+
</Router>,
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
const link = wrapper.find('Link');
|
|
223
|
+
|
|
224
|
+
expect(link.hasClass('disabled')).toBe(true);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it('renders the correct data-test-id attribute', () => {
|
|
228
|
+
const mockTestId = 'test-button';
|
|
229
|
+
const wrapper = mount(
|
|
230
|
+
<Router>
|
|
231
|
+
<Button {...navigationButtonProps} dataTestId={mockTestId} />
|
|
232
|
+
</Router>,
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
const link = wrapper.find('Link');
|
|
236
|
+
|
|
237
|
+
expect(link.prop('data-test-id')).toBe(mockTestId);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
it('renders the Icons component with the correct default icon', () => {
|
|
241
|
+
const wrapper = mount(
|
|
242
|
+
<Router>
|
|
243
|
+
<Button {...navigationButtonProps} />
|
|
244
|
+
</Router>,
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
const icons = wrapper.find(Icons);
|
|
248
|
+
|
|
249
|
+
expect(icons.prop('icon')).toBe(IconName.ChevronRight);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it('renders the Icons component with the correct default icon when `openInNewTab` is set to `true`', () => {
|
|
253
|
+
const wrapper = mount(
|
|
254
|
+
<Router>
|
|
255
|
+
<Button {...navigationButtonProps} openInNewTab={true} />
|
|
256
|
+
</Router>,
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
const icons = wrapper.find(Icons);
|
|
260
|
+
|
|
261
|
+
expect(icons.prop('icon')).toBe(IconName.External);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
it('opens link in new tab when `openInNewTab` is set to `true`', () => {
|
|
265
|
+
const wrapper = mount(
|
|
266
|
+
<Router>
|
|
267
|
+
<Button {...navigationButtonProps} openInNewTab={true} />
|
|
268
|
+
</Router>,
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
const link = wrapper.find(Link);
|
|
272
|
+
|
|
273
|
+
expect(link.prop('target')).toBe('_blank');
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it('does not open link in new tab by default', () => {
|
|
277
|
+
const wrapper = mount(
|
|
278
|
+
<Router>
|
|
279
|
+
<Button {...navigationButtonProps} />
|
|
280
|
+
</Router>,
|
|
281
|
+
);
|
|
282
|
+
|
|
283
|
+
const link = wrapper.find(Link);
|
|
284
|
+
|
|
285
|
+
expect(link.prop('target')).toBeUndefined();
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it('renders the Icons component with the correct icon', () => {
|
|
289
|
+
const mockIcon = IconName.Copy;
|
|
290
|
+
const wrapper = mount(
|
|
291
|
+
<Router>
|
|
292
|
+
<Button {...navigationButtonProps} icon={mockIcon} />
|
|
293
|
+
</Router>,
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
const icons = wrapper.find(Icons);
|
|
127
297
|
|
|
128
|
-
|
|
298
|
+
expect(icons.prop('icon')).toBe(mockIcon);
|
|
299
|
+
});
|
|
129
300
|
});
|
|
130
301
|
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { MemoryRouter } from 'react-router';
|
|
2
4
|
import { enumToObj } from '../../../helpers/storybook';
|
|
3
5
|
import { IconName } from '../../Icons';
|
|
4
6
|
import { ButtonContext } from '../Button.model';
|
|
@@ -29,7 +31,25 @@ const meta: Meta<typeof Button> = {
|
|
|
29
31
|
type: {
|
|
30
32
|
control: false,
|
|
31
33
|
},
|
|
34
|
+
width: {
|
|
35
|
+
control: {
|
|
36
|
+
type: 'number',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
height: {
|
|
40
|
+
control: {
|
|
41
|
+
type: 'number',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
32
44
|
},
|
|
45
|
+
decorators: [
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
47
|
+
(Story) => (
|
|
48
|
+
<MemoryRouter>
|
|
49
|
+
<Story />
|
|
50
|
+
</MemoryRouter>
|
|
51
|
+
),
|
|
52
|
+
],
|
|
33
53
|
};
|
|
34
54
|
|
|
35
55
|
export default meta;
|