@axinom/mosaic-ui 0.35.0-rc.9 → 0.35.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axinom/mosaic-ui",
3
- "version": "0.35.0-rc.9",
3
+ "version": "0.35.0",
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.8-rc.9",
35
+ "@axinom/mosaic-core": "^0.4.8",
36
36
  "@faker-js/faker": "^7.4.0",
37
37
  "@popperjs/core": "^2.9.2",
38
38
  "clsx": "^1.1.0",
@@ -104,5 +104,5 @@
104
104
  "publishConfig": {
105
105
  "access": "public"
106
106
  },
107
- "gitHead": "294d6a683845640ef70dc4ed5e9f057dfaacc388"
107
+ "gitHead": "cb1823de8e408b481091bfe0b0107815e8b49880"
108
108
  }
@@ -20,11 +20,11 @@ export type ButtonProps =
20
20
  */
21
21
  export interface NavigationButtonProps
22
22
  extends CommonNavigationButtonOptions,
23
- Pick<ButtonIconOptions, 'icon'> {}
23
+ Pick<ButtonIconOptions, 'icon' | 'customIcon'> {}
24
24
 
25
25
  /**
26
26
  * Button options for icon buttons with JS handlers
27
27
  */
28
28
  export interface ContextButtonProps
29
29
  extends CommonJsButtonOptions,
30
- Pick<ButtonIconOptions, 'icon'> {}
30
+ Pick<ButtonIconOptions, 'icon' | 'customIcon'> {}
@@ -9,6 +9,14 @@ const navigationButtonProps = {
9
9
  path: '/test',
10
10
  };
11
11
 
12
+ const CustomIcon: React.FC = () => (
13
+ <svg
14
+ version="1.1"
15
+ xmlns="http://www.w3.org/2000/svg"
16
+ viewBox="0 0 40 40"
17
+ ></svg>
18
+ );
19
+
12
20
  describe('Button (with icon)', () => {
13
21
  describe('ContextButtonElement', () => {
14
22
  it('renders the component without crashing', () => {
@@ -139,6 +147,25 @@ describe('Button (with icon)', () => {
139
147
 
140
148
  expect(icon.exists()).toBe(true);
141
149
  });
150
+
151
+ it('renders `customIcon` when provided', () => {
152
+ const wrapper = mount(<Button customIcon={<CustomIcon />} />);
153
+ const customIcon = wrapper.find(CustomIcon);
154
+
155
+ expect(customIcon.exists()).toBe(true);
156
+ });
157
+
158
+ it('renders `customIcon` instead of `icon` when both are provided', () => {
159
+ const wrapper = mount(
160
+ <Button icon={IconName.ChevronRight} customIcon={<CustomIcon />} />,
161
+ );
162
+
163
+ const customIcon = wrapper.find(CustomIcon);
164
+ const icon = wrapper.find(Icons);
165
+
166
+ expect(customIcon.exists()).toBe(true);
167
+ expect(icon.exists()).toBe(false);
168
+ });
142
169
  });
143
170
 
144
171
  describe('NavigationButtonElement', () => {
@@ -297,5 +324,34 @@ describe('Button (with icon)', () => {
297
324
 
298
325
  expect(icons.prop('icon')).toBe(mockIcon);
299
326
  });
327
+
328
+ it('renders `customIcon` when provided', () => {
329
+ const wrapper = mount(
330
+ <Router>
331
+ <Button {...navigationButtonProps} customIcon={<CustomIcon />} />
332
+ </Router>,
333
+ );
334
+ const customIcon = wrapper.find(CustomIcon);
335
+
336
+ expect(customIcon.exists()).toBe(true);
337
+ });
338
+
339
+ it('renders `customIcon` instead of `icon` when both are provided', () => {
340
+ const wrapper = mount(
341
+ <Router>
342
+ <Button
343
+ {...navigationButtonProps}
344
+ icon={IconName.ChevronRight}
345
+ customIcon={<CustomIcon />}
346
+ />
347
+ </Router>,
348
+ );
349
+
350
+ const customIcon = wrapper.find(CustomIcon);
351
+ const icon = wrapper.find(Icons);
352
+
353
+ expect(customIcon.exists()).toBe(true);
354
+ expect(icon.exists()).toBe(false);
355
+ });
300
356
  });
301
357
  });
@@ -17,6 +17,7 @@ const ButtonElement: React.ForwardRefRenderFunction<
17
17
  > = (
18
18
  {
19
19
  className,
20
+ customIcon,
20
21
  dataTestId,
21
22
  disabled = false,
22
23
  height,
@@ -30,6 +31,7 @@ const ButtonElement: React.ForwardRefRenderFunction<
30
31
  ) => {
31
32
  const commonProps = {
32
33
  className,
34
+ customIcon,
33
35
  dataTestId,
34
36
  disabled,
35
37
  height,
@@ -65,6 +67,7 @@ const ContextButtonElement = React.forwardRef<
65
67
  disabled = false,
66
68
  icon,
67
69
  className = '',
70
+ customIcon,
68
71
  dataTestId,
69
72
  onButtonClicked = noop,
70
73
  onBlur,
@@ -91,7 +94,7 @@ const ContextButtonElement = React.forwardRef<
91
94
  onBlur={onBlur}
92
95
  data-test-id={dataTestId ?? 'button'}
93
96
  >
94
- <Icons icon={icon} />
97
+ {customIcon ? customIcon : <Icons icon={icon} />}
95
98
  </button>
96
99
  );
97
100
  });
@@ -105,6 +108,7 @@ const NavigationButtonElement = React.forwardRef<
105
108
  height,
106
109
  width,
107
110
  icon,
111
+ customIcon,
108
112
  className = '',
109
113
  dataTestId = undefined,
110
114
  disabled = false,
@@ -129,7 +133,7 @@ const NavigationButtonElement = React.forwardRef<
129
133
  data-test-id={dataTestId ?? 'button'}
130
134
  target={openInNewTab ? '_blank' : undefined}
131
135
  >
132
- <Icons icon={icon ? icon : defaultIcon} />
136
+ {customIcon ? customIcon : <Icons icon={icon ? icon : defaultIcon} />}
133
137
  </Link>
134
138
  );
135
139
  });
@@ -66,6 +66,11 @@ export interface ButtonIconOptions {
66
66
  icon?: IconName;
67
67
  /** Optional Icon Position */
68
68
  iconPosition?: 'left' | 'right';
69
+ /**
70
+ * Optional custom icon.
71
+ * When provided, `icon` property is ignored.
72
+ */
73
+ customIcon?: React.ReactNode;
69
74
  }
70
75
 
71
76
  /**
@@ -1,10 +1,18 @@
1
1
  import { mount, shallow } from 'enzyme';
2
2
  import React from 'react';
3
3
  import { BrowserRouter as Router } from 'react-router-dom';
4
- import { IconName } from '../../Icons';
4
+ import { IconName, Icons } from '../../Icons';
5
5
  import { ButtonContext } from '../Button.model';
6
6
  import { CompositeButton } from './CompositeButton';
7
7
 
8
+ const CustomIcon: React.FC = () => (
9
+ <svg
10
+ version="1.1"
11
+ xmlns="http://www.w3.org/2000/svg"
12
+ viewBox="0 0 40 40"
13
+ ></svg>
14
+ );
15
+
8
16
  describe('CompositeButton', () => {
9
17
  describe('Composite context button', () => {
10
18
  it('renders the component without crashing', () => {
@@ -143,6 +151,26 @@ describe('CompositeButton', () => {
143
151
 
144
152
  expect(button.text()).toBe('');
145
153
  });
154
+
155
+ it('renders `customIcon` when provided', () => {
156
+ const wrapper = mount(<CompositeButton customIcon={<CustomIcon />} />);
157
+ const customIcon = wrapper.find(CustomIcon);
158
+
159
+ expect(customIcon.exists()).toBeTruthy();
160
+ });
161
+
162
+ it('renders `customIcon` instead of `icon` when both provided', () => {
163
+ const wrapper = mount(
164
+ <CompositeButton
165
+ customIcon={<CustomIcon />}
166
+ icon={IconName.ChevronRight}
167
+ />,
168
+ );
169
+ const customIcon = wrapper.find(CustomIcon);
170
+
171
+ expect(customIcon.exists()).toBeTruthy();
172
+ expect(wrapper.find(Icons).exists()).toBeFalsy();
173
+ });
146
174
  });
147
175
 
148
176
  describe('Composite navigation button', () => {
@@ -298,6 +326,33 @@ describe('CompositeButton', () => {
298
326
  expect(iconDiv.find('Icons').prop('icon')).toBe(IconName.External);
299
327
  });
300
328
 
329
+ it('renders `customIcon` when provided', () => {
330
+ const wrapper = mount(
331
+ <Router>
332
+ <CompositeButton customIcon={<CustomIcon />} path="/example" />
333
+ </Router>,
334
+ );
335
+ const customIcon = wrapper.find(CustomIcon);
336
+
337
+ expect(customIcon.exists()).toBeTruthy();
338
+ });
339
+
340
+ it('renders `customIcon` instead of `icon` when both provided', () => {
341
+ const wrapper = mount(
342
+ <Router>
343
+ <CompositeButton
344
+ customIcon={<CustomIcon />}
345
+ icon={IconName.ChevronRight}
346
+ path="/example"
347
+ />
348
+ </Router>,
349
+ );
350
+ const iconDiv = wrapper.find('div').at(1);
351
+
352
+ expect(iconDiv.find('CustomIcon').exists()).toBeTruthy();
353
+ expect(iconDiv.find('Icons').exists()).toBeFalsy();
354
+ });
355
+
301
356
  it('renders the default data-test-id when dataTestId prop is not provided', () => {
302
357
  const wrapper = mount(
303
358
  <Router>
@@ -22,6 +22,7 @@ import classes from './CompositeButton.scss';
22
22
  */
23
23
  export const CompositeButton: React.FC<CompositeButtonProps> = ({
24
24
  className,
25
+ customIcon,
25
26
  dataTestId,
26
27
  disabled,
27
28
  height,
@@ -35,6 +36,7 @@ export const CompositeButton: React.FC<CompositeButtonProps> = ({
35
36
  }) => {
36
37
  const commonProps = {
37
38
  className,
39
+ customIcon,
38
40
  dataTestId,
39
41
  disabled,
40
42
  height,
@@ -57,6 +59,7 @@ export const CompositeButton: React.FC<CompositeButtonProps> = ({
57
59
  const CompositeContextButton: React.FC<CompositeJsButtonProps> = ({
58
60
  buttonContext = ButtonContext.Context,
59
61
  className,
62
+ customIcon,
60
63
  dataTestId = undefined,
61
64
  disabled = false,
62
65
  height,
@@ -90,7 +93,10 @@ const CompositeContextButton: React.FC<CompositeJsButtonProps> = ({
90
93
  >
91
94
  <div>{text}</div>
92
95
  <div className={classes.icon}>
93
- {icon !== null && icon !== undefined && <Icons icon={icon} />}
96
+ {customIcon ||
97
+ (icon !== null && icon !== undefined ? (
98
+ <Icons icon={icon} />
99
+ ) : undefined)}
94
100
  </div>
95
101
  </button>
96
102
  );
@@ -98,6 +104,7 @@ const CompositeContextButton: React.FC<CompositeJsButtonProps> = ({
98
104
 
99
105
  const CompositeNavigationButton: React.FC<CompositeNavigationButtonProps> = ({
100
106
  className,
107
+ customIcon,
101
108
  dataTestId = undefined,
102
109
  disabled = false,
103
110
  height,
@@ -129,7 +136,7 @@ const CompositeNavigationButton: React.FC<CompositeNavigationButtonProps> = ({
129
136
  >
130
137
  <div>{text}</div>
131
138
  <div className={classes.icon}>
132
- <Icons icon={icon ? icon : defaultIcon} />
139
+ {customIcon ? customIcon : <Icons icon={icon ? icon : defaultIcon} />}
133
140
  </div>
134
141
  </Link>
135
142
  );
@@ -70,6 +70,10 @@
70
70
  }
71
71
 
72
72
  .formContainer {
73
+ overflow-x: hidden;
74
+ }
75
+
76
+ .paddedContent {
73
77
  padding: 30px;
74
78
  }
75
79
 
@@ -246,8 +246,8 @@ export const FormStation = <TValues extends Data, TSubmitResponse = unknown>({
246
246
  <MessageBar {...stationMessage}>{stationMessage.body}</MessageBar>
247
247
  )}
248
248
  <div
249
- className={clsx({
250
- [classes.formContainer]: !edgeToEdgeContent,
249
+ className={clsx(classes.formContainer, {
250
+ [classes.paddedContent]: !edgeToEdgeContent,
251
251
  })}
252
252
  >
253
253
  <Form>