• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Financial-Times / cm-react-components / 80223841-8c6a-431a-aa6a-22eab4aabe15

12 Nov 2025 09:19AM UTC coverage: 74.23% (-0.4%) from 74.624%
80223841-8c6a-431a-aa6a-22eab4aabe15

push

circleci

web-flow
Merge pull request #23 from Financial-Times/UPPSF-6552

Uppsf 6552

310 of 395 branches covered (78.48%)

Branch coverage included in aggregate %.

9 of 14 new or added lines in 3 files covered. (64.29%)

485 of 676 relevant lines covered (71.75%)

8.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.0
/src/components/Buttons/Button.js
1
import React, { forwardRef } from 'react';
2
import PropTypes from 'prop-types';
3

4
const classNameDefault = 'o3-button';
3✔
5
const classNameDefaultPrefix = `${classNameDefault}--`;
3✔
6
const classNameIconDefaultPrefix = `${classNameDefault}-icon--`;
3✔
7

8
const Button = forwardRef(({
3✔
9
  id,
10
  children,
11
  disabled,
12
  onClick,
13
  className: additionalClassname,
14
  primary,
15
  secondary,
16
  inverse,
17
  big,
18
  mono,
19
  icon,
20
  title,
21
  selected,
22
  brand,
23
  theme
24
}, ref) => {
25
  let buttonClasses = classNameDefault;
79✔
26

27
  if (primary) {
79✔
28
    buttonClasses += ` ${classNameDefaultPrefix}primary`;
11✔
29
  }
30
  if (secondary) {
79✔
31
    buttonClasses += ` ${classNameDefaultPrefix}secondary`;
9✔
32
  }
33
  if (inverse) {
79✔
34
    buttonClasses += ` ${classNameDefaultPrefix}inverse`;
1✔
35
  }
36
  if (big) {
79✔
37
    buttonClasses += ` ${classNameDefaultPrefix}big`;
11✔
38
  }
39
  if (mono) {
79✔
40
    buttonClasses += ` ${classNameDefaultPrefix}mono`;
11✔
41
  }
42
  if (icon) {
79✔
43
    buttonClasses += ` ${classNameDefault}-icon ${classNameIconDefaultPrefix}${icon}`;
12✔
44
    if (!children) {
12✔
45
      buttonClasses += ` ${classNameDefault}-icon--icon-only`;
11✔
46
      buttonClasses += ' o3-apply-focus-rings';
11✔
47
    }
48
  }
49
  if (additionalClassname) {
79✔
50
    buttonClasses += ` ${additionalClassname}`;
11✔
51
  }
52

53
  // Prepare data attributes for brand and theme
54
  const dataAttrs = {};
79✔
55
  if (brand) {
79!
NEW
56
    dataAttrs['data-o3-brand'] = brand;
×
57
  }
58
  if (theme) {
79!
NEW
59
    dataAttrs['data-o3-theme'] = theme;
×
60
  }
61

62
  return (
79✔
63
    <button
64
      id={id}
65
      ref={ref}
66
      data-testid={id}
67
      className={buttonClasses}
68
      disabled={disabled}
69
      onClick={onClick}
70
      title={title}
71
      aria-selected={selected}
72
      {...dataAttrs}
73
    >
74
      {children}
75
    </button>
76
  );
77
});
78

79
Button.displayName = 'Button';
3✔
80
Button.propTypes = {
3✔
81
  id: PropTypes.oneOfType([
82
    PropTypes.number,
83
    PropTypes.string
84
  ]),
85
  children: PropTypes.node,
86
  disabled: PropTypes.bool,
87
  onClick: PropTypes.func,
88
  selected: PropTypes.bool,
89
  className: PropTypes.string,
90
  primary: PropTypes.bool,
91
  secondary: PropTypes.bool,
92
  inverse: PropTypes.bool,
93
  big: PropTypes.bool,
94
  mono: PropTypes.bool,
95
  icon: PropTypes.string,
96
  title: PropTypes.string,
97
  brand: PropTypes.string,
98
  theme: PropTypes.string
99
};
100

101
export default Button;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc