@financial-times/o-labels 7.1.0 → 8.0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Changelog
2
2
 
3
+ ## [8.0.0](https://github.com/Financial-Times/origami/compare/o-labels-v7.1.2...o-labels-v8.0.0) (2026-02-05)
4
+
5
+
6
+ ### ⚠ BREAKING CHANGES
7
+
8
+ * Replace `scoop` with `exclusive`
9
+
10
+ ### Features
11
+
12
+ * Replace `scoop` with `exclusive` ([8ff2c0d](https://github.com/Financial-Times/origami/commit/8ff2c0d3cfd25cec7d3d5046ca66134fc1af1633))
13
+
14
+ ## [7.1.2](https://github.com/Financial-Times/origami/compare/o-labels-v7.1.1...o-labels-v7.1.2) (2025-10-28)
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * force release of unreleased components ([#2264](https://github.com/Financial-Times/origami/issues/2264)) ([c4faddc](https://github.com/Financial-Times/origami/commit/c4faddc35b69c712ca6a967353871d9921cd4dfc))
20
+
21
+ ## [7.1.1](https://github.com/Financial-Times/origami/compare/o-labels-v7.1.0...o-labels-v7.1.1) (2025-10-28)
22
+
23
+
24
+ ### Bug Fixes
25
+
26
+ * update o-labels badge styling to match new designs ([#2246](https://github.com/Financial-Times/origami/issues/2246)) ([66aa1fc](https://github.com/Financial-Times/origami/commit/66aa1fc8c6ee2d95a7c1d531c15875f66c70d1ab))
27
+
3
28
  ## [7.1.0](https://github.com/Financial-Times/origami/compare/o-labels-v7.0.3...o-labels-v7.1.0) (2025-10-22)
4
29
 
5
30
 
package/MIGRATION.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Migration Guide
2
2
 
3
+ ## Migrating from v7 to v8
4
+
5
+ This release removes the `content-scoop` label and replaces with `content-exclusive'. Ensure any references to `content-scoop` are updated:
6
+
7
+ ```diff
8
+ - <span class="o-labels o-labels--content-scoop">Exclusive</span>
9
+ + <span class="o-labels o-labels--content-exclusive">Exclusive</span>
10
+ ```
11
+
3
12
  ## Migrating from v6 to v7
4
13
 
5
14
  This major release introduces a new design language and visually breaking changes. This includes mobile optimised typography, icons, and buttons. It also removes peer dependencies from deprecated "o2" components.
@@ -15,6 +15,10 @@
15
15
  {
16
16
  "id": "content-premium",
17
17
  "content": "Premium"
18
+ },
19
+ {
20
+ "id": "content-exclusive",
21
+ "content": "Exclusive"
18
22
  }
19
23
  ]
20
24
  }
package/main.scss CHANGED
@@ -109,7 +109,7 @@
109
109
  padding: oPrivateSpacingByName('s1') oPrivateSpacingByName('s2');
110
110
  font-weight: oFontsWeight('bold');
111
111
  color: oPrivateFoundationGet('o3-color-palette-white');
112
- border-radius: div(2, 16) * 1rem;
112
+ border-radius: oPrivateFoundationGet('o3-border-radius-1');
113
113
 
114
114
  &.o-labels-indicator--live {
115
115
  // This needs to use the correct label tokens in the Design System
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@financial-times/o-labels",
3
- "version": "7.1.0",
3
+ "version": "8.0.0",
4
4
  "description": "Labels for content classification or to emphasise a value. Provides customisation options with the FT colour palette.",
5
5
  "keywords": [
6
6
  "label",
@@ -13,19 +13,22 @@
13
13
 
14
14
  // Define shared brand configurations
15
15
  $_o-labels-shared-brand-config: (
16
- font-scale: -1,
16
+ font-scale: 0,
17
17
  padding-vertical: oPrivateSpacingByName('s1'),
18
18
  padding-horizontal: oPrivateSpacingByName('s2'),
19
19
  border-width: 1px,
20
+ line-height: oPrivateFoundationGet('o3-type-label-line-height'),
20
21
  'big': (
21
22
  font-scale: 0,
22
23
  padding-vertical: oPrivateSpacingByName('s2'),
23
- padding-horizontal: oPrivateSpacingByName('s2')
24
+ padding-horizontal: oPrivateSpacingByName('s2'),
25
+ line-height: oPrivateFoundationGet('o3-type-label-line-height')
24
26
  ),
25
27
  'small': (
26
28
  font-scale: -1,
27
29
  padding-vertical: 2px,
28
- padding-horizontal: 4px
30
+ padding-horizontal: 4px,
31
+ line-height: 1rem
29
32
  )
30
33
  );
31
34
 
@@ -35,11 +38,19 @@ $_o-labels-shared-brand-config: (
35
38
  'variables': map-merge($_o-labels-shared-brand-config, (
36
39
  text-color: oPrivateFoundationGet('o3-color-palette-black'),
37
40
  background-color: oPrivateFoundationGet('o3-color-palette-wheat'),
41
+ border-color: oPrivateFoundationGet('o3-color-palette-wheat'),
38
42
  'content-commercial': (
39
- background-color: oPrivateColorsMix('o3-color-palette-jade', 'o3-color-palette-black', $percentage: 83.334)
43
+ background-color: oPrivateColorsMix('o3-color-palette-jade', 'o3-color-palette-black', $percentage: 83.334),
44
+ border-color: oPrivateColorsMix('o3-color-palette-jade', 'o3-color-palette-black', $percentage: 83.334)
40
45
  ),
41
46
  'content-premium': (
42
- background-color: oPrivateFoundationGet('o3-color-palette-black')
47
+ background-color: oPrivateFoundationGet('o3-color-palette-slate'),
48
+ border-color: oPrivateFoundationGet('o3-color-palette-slate')
49
+ ),
50
+ 'content-exclusive': (
51
+ background-color: oPrivateFoundationGet('o3-color-palette-ft-pink'),
52
+ border-color: oPrivateFoundationGet('o3-color-palette-ft-pink'),
53
+ text-color: oPrivateFoundationGet('o3-color-palette-black-80')
43
54
  ),
44
55
  'lifecycle-beta': (
45
56
  background-color: oPrivateFoundationGet('o3-color-palette-paper'),
@@ -57,6 +68,7 @@ $_o-labels-shared-brand-config: (
57
68
  'small',
58
69
  'content-commercial',
59
70
  'content-premium',
71
+ 'content-exclusive',
60
72
  'lifecycle-beta'
61
73
  )
62
74
  ));
@@ -67,61 +79,78 @@ $_o-labels-shared-brand-config: (
67
79
  @include oBrandDefine('o-labels', 'internal', (
68
80
  'variables': map-merge($_o-labels-shared-brand-config, (
69
81
  background-color: oPrivateColorsMix('o3-color-palette-black', 'o3-color-palette-white', 10),
82
+ border-color: oPrivateColorsMix('o3-color-palette-black', 'o3-color-palette-white', 10),
70
83
  'support-active': (
71
- background-color: oPrivateColorsMix('o3-color-palette-jade', 'o3-color-palette-black', 70)
84
+ background-color: oPrivateColorsMix('o3-color-palette-jade', 'o3-color-palette-black', 70),
85
+ border-color: oPrivateColorsMix('o3-color-palette-jade', 'o3-color-palette-black', 70)
72
86
  ),
73
87
  'support-dead': (
74
- background-color: oPrivateFoundationGet('o3-color-palette-black')
88
+ background-color: oPrivateFoundationGet('o3-color-palette-black'),
89
+ border-color: oPrivateFoundationGet('o3-color-palette-black')
75
90
  ),
76
91
  'support-deprecated': (
77
- background-color: oPrivateFoundationGet('o3-color-palette-crimson')
92
+ background-color: oPrivateFoundationGet('o3-color-palette-crimson'),
93
+ border-color: oPrivateFoundationGet('o3-color-palette-crimson')
78
94
  ),
79
95
  'support-experimental': (
80
- background-color: oPrivateFoundationGet('o3-color-palette-lemon')
96
+ background-color: oPrivateFoundationGet('o3-color-palette-lemon'),
97
+ border-color: oPrivateFoundationGet('o3-color-palette-lemon')
81
98
  ),
82
99
  'support-maintained': (
83
- background-color: oPrivateColorsMix('o3-color-palette-jade', 'o3-color-palette-black', 70)
100
+ background-color: oPrivateColorsMix('o3-color-palette-jade', 'o3-color-palette-black', 70),
101
+ border-color: oPrivateColorsMix('o3-color-palette-jade', 'o3-color-palette-black', 70)
84
102
  ),
85
103
  'tier-bronze': (
86
104
  // NOTE: service tiers not in o-colors yet, will be moved if another
87
105
  // component needs to use these colours
88
- background-color: #b78d83
106
+ background-color: #b78d83,
107
+ border-color: #b78d83
89
108
  ),
90
109
  'tier-gold': (
91
110
  // NOTE: service tiers not in o-colors yet, will be moved if another
92
111
  // component needs to use these colours
93
- background-color: #b89d62
112
+ background-color: #b89d62,
113
+ border-color: #b89d62
94
114
  ),
95
115
  'tier-platinum': (
96
116
  // NOTE: service tiers not in o-colors yet, will be moved if another
97
117
  // component needs to use these colours
98
- background-color: #e5e4e2
118
+ background-color: #e5e4e2,
119
+ border-color: #e5e4e2
99
120
  ),
100
121
  'tier-silver': (
101
122
  // NOTE: service tiers not in o-colors yet, will be moved if another
102
123
  // component needs to use these colours
103
- background-color: #c0c0c0
124
+ background-color: #c0c0c0,
125
+ border-color: #c0c0c0
104
126
  ),
105
127
  'oxford': (
106
- background-color: oPrivateFoundationGet('o3-color-palette-oxford')
128
+ background-color: oPrivateFoundationGet('o3-color-palette-oxford'),
129
+ border-color: oPrivateFoundationGet('o3-color-palette-oxford')
107
130
  ),
108
131
  'teal': (
109
- background-color: oPrivateFoundationGet('o3-color-palette-teal-50')
132
+ background-color: oPrivateFoundationGet('o3-color-palette-teal-50'),
133
+ border-color: oPrivateFoundationGet('o3-color-palette-teal-50')
110
134
  ),
111
135
  'lemon': (
112
- background-color: oPrivateFoundationGet('o3-color-palette-lemon')
136
+ background-color: oPrivateFoundationGet('o3-color-palette-lemon'),
137
+ border-color: oPrivateFoundationGet('o3-color-palette-lemon')
113
138
  ),
114
139
  'slate': (
115
- background-color: oPrivateFoundationGet('o3-color-palette-slate')
140
+ background-color: oPrivateFoundationGet('o3-color-palette-slate'),
141
+ border-color: oPrivateFoundationGet('o3-color-palette-slate')
116
142
  ),
117
143
  'jade': (
118
- background-color: oPrivateFoundationGet('o3-color-palette-jade')
144
+ background-color: oPrivateFoundationGet('o3-color-palette-jade'),
145
+ border-color: oPrivateFoundationGet('o3-color-palette-jade')
119
146
  ),
120
147
  'crimson': (
121
- background-color: oPrivateFoundationGet('o3-color-palette-crimson')
148
+ background-color: oPrivateFoundationGet('o3-color-palette-crimson'),
149
+ border-color: oPrivateFoundationGet('o3-color-palette-crimson')
122
150
  ),
123
151
  'mandarin': (
124
- background-color: oPrivateFoundationGet('o3-color-palette-mandarin')
152
+ background-color: oPrivateFoundationGet('o3-color-palette-mandarin'),
153
+ border-color: oPrivateFoundationGet('o3-color-palette-mandarin')
125
154
  )
126
155
  )),
127
156
  'supports-variants': (
@@ -151,7 +180,8 @@ $_o-labels-shared-brand-config: (
151
180
  @if oBrandIs('whitelabel') {
152
181
  @include oBrandDefine('o-labels', 'whitelabel', (
153
182
  'variables': map-merge($_o-labels-shared-brand-config, (
154
- background-color: oPrivateColorsMix('o3-color-palette-black', 'o3-color-palette-white', 10)
183
+ background-color: oPrivateColorsMix('o3-color-palette-black', 'o3-color-palette-white', 10),
184
+ border-color: oPrivateColorsMix('o3-color-palette-black', 'o3-color-palette-white', 10)
155
185
  )),
156
186
  'supports-variants': (
157
187
  'big',
@@ -7,21 +7,23 @@
7
7
  @mixin _oLabelsBaseContent() {
8
8
  @include oPrivateTypographySans(
9
9
  $scale: _oLabelsGet('font-scale'),
10
- $weight: 'semibold'
10
+ $weight: 'regular'
11
11
  );
12
- line-height: 1em;
12
+ line-height: _oLabelsGet('line-height');
13
13
  text-align: center;
14
14
  display: inline-block;
15
15
  box-sizing: border-box;
16
16
  margin: 0;
17
17
  text-decoration: none;
18
+ text-transform: oPrivateFoundationGet('o3-type-label-text-case');
18
19
  padding: calc(
19
20
  #{_oLabelsGet('padding-vertical')} - #{_oLabelsGet('border-width')}
20
21
  )
21
22
  calc(#{_oLabelsGet('padding-horizontal')} - #{_oLabelsGet('border-width')});
22
23
  color: _oLabelsGet('text-color');
23
24
  background-color: _oLabelsGet('background-color');
24
- border: solid _oLabelsGet('border-width') transparent;
25
+ border: solid _oLabelsGet('border-width') _oLabelsGet('border-color');
26
+ border-radius: oPrivateFoundationGet('o3-border-radius-1');
25
27
  }
26
28
 
27
29
  /// Size modifiers for labels.
@@ -171,7 +173,6 @@
171
173
  $scale: _oLabelsGet('font-scale', $size);
172
174
  @if $scale {
173
175
  @include oPrivateTypographySans($scale);
174
- line-height: 1;
175
176
  }
176
177
  padding: calc(
177
178
  #{_oLabelsGet('padding-vertical', $size)} - #{_oLabelsGet('border-width')}
@@ -1,6 +1,6 @@
1
1
  // Do not output placeholders twice i.e. if o-labels is imported twice.
2
2
  // This is a temporary variable, until we can use the new sass `@use` feature
3
- // that will not have the problem of re-outputting placeholders on every import
3
+ // that will not have the problem of re-outputting placeholders on every import.
4
4
  $_o-labels-first-import: true !default;
5
5
 
6
6
  @if $_o-labels-first-import == true {
@@ -30,6 +30,7 @@ $_o-labels-standard-sizes: (
30
30
  $_o-labels-standard-states: (
31
31
  'content-commercial',
32
32
  'content-premium',
33
+ 'content-exclusive',
33
34
 
34
35
  'lifecycle-beta',
35
36
 
package/src/tsx/label.tsx CHANGED
@@ -9,14 +9,10 @@ export interface SupportLabelProps extends BaseLabelProps {
9
9
  | 'support-dead'
10
10
  | 'support-deprecated'
11
11
  | 'support-experimental'
12
- | 'support-maintained'
12
+ | 'support-maintained';
13
13
  }
14
14
  export interface ServiceLabelProps extends BaseLabelProps {
15
- state:
16
- | 'tier-bronze'
17
- | 'tier-gold'
18
- | 'tier-platinum'
19
- | 'tier-silver'
15
+ state: 'tier-bronze' | 'tier-gold' | 'tier-platinum' | 'tier-silver';
20
16
  }
21
17
  export interface ColourLabelProps extends BaseLabelProps {
22
18
  state:
@@ -26,23 +22,24 @@ export interface ColourLabelProps extends BaseLabelProps {
26
22
  | 'slate'
27
23
  | 'jade'
28
24
  | 'crimson'
29
- | 'mandarin'
25
+ | 'mandarin';
30
26
  }
31
27
  export interface ContentLabelProps extends BaseLabelProps {
32
- state:
33
- | 'content-commercial'
34
- | 'content-premium'
28
+ state: 'content-commercial' | 'content-premium' | 'content-exclusive';
35
29
  }
36
30
  export interface LifeCycleLabelProps extends BaseLabelProps {
37
- state:
38
- | 'lifecycle-beta'
31
+ state: 'lifecycle-beta';
39
32
  }
40
33
 
41
34
  function SimpleLabel({
42
35
  size,
43
36
  state,
44
37
  children,
45
- }: {size?: string, state?: string, children: string}): React.JSX.Element {
38
+ }: {
39
+ size?: string;
40
+ state?: string;
41
+ children: string;
42
+ }): React.JSX.Element {
46
43
  const classNames = ['o-labels'];
47
44
  if (size) {
48
45
  classNames.push(`o-labels--${size}`);
@@ -54,23 +51,23 @@ function SimpleLabel({
54
51
  }
55
52
 
56
53
  export function BaseLabel(props: BaseLabelProps): React.JSX.Element {
57
- return SimpleLabel(props)
54
+ return SimpleLabel(props);
58
55
  }
59
56
 
60
57
  export function SupportLabel(props: SupportLabelProps): React.JSX.Element {
61
- return SimpleLabel(props)
58
+ return SimpleLabel(props);
62
59
  }
63
60
  export function ServiceLabel(props: ServiceLabelProps): React.JSX.Element {
64
- return SimpleLabel(props)
61
+ return SimpleLabel(props);
65
62
  }
66
63
  export function ColourLabel(props: ColourLabelProps): React.JSX.Element {
67
- return SimpleLabel(props)
64
+ return SimpleLabel(props);
68
65
  }
69
66
  export function ContentLabel(props: ContentLabelProps): React.JSX.Element {
70
- return SimpleLabel(props)
67
+ return SimpleLabel(props);
71
68
  }
72
69
  export function LifeCycleLabel(props: LifeCycleLabelProps): React.JSX.Element {
73
- return SimpleLabel(props)
70
+ return SimpleLabel(props);
74
71
  }
75
72
 
76
73
  export interface IndicatorLabelProps {
@@ -92,16 +89,17 @@ export function IndicatorLabel({
92
89
  if (inverse) {
93
90
  classNames.push('o-labels-indicator--inverse');
94
91
  }
95
- if(badge) {
92
+ if (badge) {
96
93
  classNames.push('o-labels-indicator--badge');
97
94
  }
98
95
  return (
99
96
  <span className={classNames.join(' ')}>
100
- <span className="o-labels-indicator__status"> {status || indicator} </span>
97
+ <span className="o-labels-indicator__status">
98
+ {' '}
99
+ {status || indicator}{' '}
100
+ </span>
101
101
  {timestamp && (
102
- <span className="o-labels-indicator__timestamp">
103
- {timestamp}
104
- </span>
102
+ <span className="o-labels-indicator__timestamp">{timestamp}</span>
105
103
  )}
106
104
  </span>
107
105
  );
@@ -109,17 +107,16 @@ export function IndicatorLabel({
109
107
 
110
108
  export interface TimestampLabelProps {
111
109
  inverse?: boolean;
112
- children?: React.JSX.Element | React.JSX.Element[]
110
+ children?: React.JSX.Element | React.JSX.Element[];
113
111
  }
114
112
 
115
- export function TimestampLabel({inverse, children}: TimestampLabelProps): React.JSX.Element {
113
+ export function TimestampLabel({
114
+ inverse,
115
+ children,
116
+ }: TimestampLabelProps): React.JSX.Element {
116
117
  const classNames = ['o-labels-timestamp'];
117
118
  if (inverse) {
118
119
  classNames.push('o-labels-timestamp--inverse');
119
120
  }
120
- return (
121
- <span className={classNames.join(' ')}>
122
- {children}
123
- </span>
124
- );
121
+ return <span className={classNames.join(' ')}>{children}</span>;
125
122
  }