@indico-data/design-system 2.45.3 → 2.45.5

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": "@indico-data/design-system",
3
- "version": "2.45.3",
3
+ "version": "2.45.5",
4
4
  "description": "",
5
5
  "author": "",
6
6
  "main": "lib/index.js",
@@ -126,8 +126,9 @@ const meta: Meta = {
126
126
  category: 'State Props',
127
127
  },
128
128
  defaultValue: { summary: false },
129
- description:
130
- 'Disables the button and shows a load spinner on the left hand side of the button children',
129
+ description: `Disables the button and shows a load spinner on the left hand side of the button children by default.
130
+ If iconLeft is passed, the loading icon will be displayed on the left hand side of the iconLeft.
131
+ If iconRight is passed, the loading icon will be displayed on the right hand side of the iconRight.`,
131
132
  },
132
133
  isDisabled: {
133
134
  control: 'boolean',
@@ -416,8 +417,18 @@ export const Loading: Story = {
416
417
  </Button>
417
418
  </Col>
418
419
  <Col xs={6} sm={4} md={3} lg={2} className="mb-3">
420
+ <Button {...args} variant="action" iconRight="thumbs-up">
421
+ Icon Right
422
+ </Button>
423
+ </Col>
424
+ <Col xs={6} sm={4} md={3} lg={2} className="mb-3">
425
+ <span className="mr-2">Icon Only (Left)</span>
419
426
  <Button {...args} variant="action" iconLeft="thumbs-up" />
420
427
  </Col>
428
+ <Col xs={6} sm={4} md={3} lg={2} className="mb-3">
429
+ <span className="mr-2">Icon Only (Right)</span>
430
+ <Button {...args} variant="action" iconRight="thumbs-up" />
431
+ </Col>
421
432
  </Row>
422
433
  ),
423
434
  };
@@ -59,19 +59,19 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) =>
59
59
  onKeyDown={onKeyDown}
60
60
  {...rest}
61
61
  >
62
- {/* Loading Icon */}
63
- {isLoading && (
62
+ {/* Loading Icon on the left (default) */}
63
+ {isLoading && !iconRight && (
64
64
  <Icon
65
65
  name="indico-o"
66
66
  style={{ animation: 'spin 1s linear infinite' }}
67
- className="mr-2"
67
+ className={children ? 'mr-2' : ''}
68
68
  ariaLabel="Loading..."
69
69
  size={size}
70
70
  />
71
71
  )}
72
72
 
73
73
  {/* Left Icon */}
74
- {iconLeft && (
74
+ {iconLeft && !isLoading && (
75
75
  <Icon
76
76
  name={iconLeft}
77
77
  className={children ? 'mr-2' : ''}
@@ -84,7 +84,7 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) =>
84
84
  {children}
85
85
 
86
86
  {/* Right Icon */}
87
- {iconRight && (
87
+ {iconRight && !isLoading && (
88
88
  <Icon
89
89
  name={iconRight}
90
90
  className={children ? 'ml-2' : ''}
@@ -92,6 +92,17 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) =>
92
92
  size={size}
93
93
  />
94
94
  )}
95
+
96
+ {/* Loading Icon on the right */}
97
+ {isLoading && iconRight && (
98
+ <Icon
99
+ name="indico-o"
100
+ style={{ animation: 'spin 1s linear infinite' }}
101
+ className={children ? 'ml-2' : ''}
102
+ ariaLabel="Loading..."
103
+ size={size}
104
+ />
105
+ )}
95
106
  </button>
96
107
  );
97
108
  });
@@ -45,7 +45,7 @@ describe('Button', () => {
45
45
  expect(button).toHaveClass('btn--pill');
46
46
  });
47
47
 
48
- it('loads the corresponding loading class and shows loading icon', () => {
48
+ it('loads the corresponding loading class and shows loading icon when isLoading is true', () => {
49
49
  render(
50
50
  <Button isLoading onClick={onClick} ariaLabel="btn">
51
51
  Button
@@ -60,6 +60,43 @@ describe('Button', () => {
60
60
  expect(loadingIcon).toHaveClass('mr-2');
61
61
  });
62
62
 
63
+ it('displays the loading icon on the left when isLoading and iconLeft exists and hides the iconLeft', () => {
64
+ render(
65
+ <Button isLoading iconLeft="check" onClick={onClick} ariaLabel="btn">
66
+ Button
67
+ </Button>,
68
+ );
69
+ const loadingIcon = screen.getByLabelText('Loading...');
70
+ const iconLeft = screen.queryByLabelText('check Icon');
71
+
72
+ expect(loadingIcon).toHaveClass('mr-2');
73
+ expect(iconLeft).not.toBeInTheDocument();
74
+ });
75
+
76
+ it('displays the loading icon on the right when isLoading and iconRight exists and hides the iconRight', () => {
77
+ render(
78
+ <Button isLoading iconRight="check" onClick={onClick} ariaLabel="btn">
79
+ Button
80
+ </Button>,
81
+ );
82
+ const loadingIcon = screen.getByLabelText('Loading...');
83
+ const iconRight = screen.queryByLabelText('check Icon');
84
+
85
+ expect(loadingIcon).toHaveClass('ml-2');
86
+ expect(iconRight).not.toBeInTheDocument();
87
+ });
88
+
89
+ it('does not apply a margin to the loading icon when no children are present', () => {
90
+ render(<Button isLoading iconLeft="check" onClick={onClick} ariaLabel="btn" />);
91
+ const loadingIcon = screen.getByLabelText('Loading...');
92
+ expect(loadingIcon).not.toHaveClass('mr-2');
93
+ expect(loadingIcon).not.toHaveClass('ml-2');
94
+
95
+ render(<Button isLoading iconRight="check" onClick={onClick} ariaLabel="btn" />);
96
+ expect(loadingIcon).not.toHaveClass('mr-2');
97
+ expect(loadingIcon).not.toHaveClass('ml-2');
98
+ });
99
+
63
100
  it('does not apply the loading class when not loading', () => {
64
101
  render(
65
102
  <Button isLoading={false} onClick={onClick} ariaLabel="btn">
@@ -15,19 +15,19 @@ export const Icon = ({ name, size = 'md', className, ariaLabel, ...props }: Icon
15
15
  );
16
16
 
17
17
  const faIconName = name.split('fa-')[1];
18
- const faIcon =
19
- faIconName &&
20
- findIconDefinition({
21
- prefix: 'fas',
22
- iconName: faIconName as FAIconName,
23
- });
24
- const icon =
25
- faIcon ||
26
- findIconDefinition({
27
- prefix: 'fak',
28
- // @ts-ignore
29
- iconName: name,
30
- });
18
+
19
+ // If the icon name starts with 'fa-', it's a Font Awesome icon
20
+ // Otherwise, search for an indicon (registered under Font Awesome with a prefix of 'fak')
21
+ const icon = faIconName
22
+ ? findIconDefinition({
23
+ prefix: 'fas',
24
+ iconName: faIconName as FAIconName,
25
+ })
26
+ : findIconDefinition({
27
+ prefix: 'fak',
28
+ // @ts-ignore
29
+ iconName: name,
30
+ });
31
31
 
32
32
  if (!icon) {
33
33
  console.error(
@@ -753,8 +753,8 @@ const indicons = {
753
753
  </svg>
754
754
  ),
755
755
  url: (
756
- <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 50 50">
757
- <path d="M22 33.1h-8q-3.85 0-6.475-2.625T4.9 24t2.625-6.475T14 14.9h8v2.3h-8q-2.9 0-4.85 1.95T7.2 24t1.95 4.85T14 30.8h8zm-5.3-7.95v-2.3h14.65v2.3zM26 33.1v-2.3h8q2.9 0 4.85-1.95T40.8 24t-1.95-4.85T34 17.2h-8v-2.3h8q3.85 0 6.475 2.625T43.1 24t-2.625 6.475T34 33.1z" />
756
+ <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 100 100">
757
+ <path d="M 44.2376 70.4481 h -20.8177 q -10.0185 0 -16.8493 -6.8308 T -0.2602 46.768 t 6.8308 -16.8493 T 23.4199 23.0879 h 20.8177 v 5.9851 h -20.8177 q -7.5464 0 -12.6207 5.0743 T 5.7249 46.768 t 5.0743 12.6207 T 23.4199 64.4631 h 20.8177 z m -13.7917 -20.6876 v -5.9851 h 38.1224 v 5.9851 z M 54.6465 70.4481 v -5.9851 h 20.8177 q 7.5464 0 12.6207 -5.0743 T 93.1592 46.768 t -5.0743 -12.6207 T 75.4642 29.073 h -20.8177 v -5.9851 h 20.8177 q 10.0185 0 16.8493 6.8308 T 99.1443 46.768 t -6.8308 16.8493 T 75.4642 70.4481 z" />
758
758
  </svg>
759
759
  ),
760
760
  user: (