@financial-times/n-conversion-forms 46.0.0 → 47.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.
@@ -7,7 +7,7 @@ export default {
7
7
  component: PaymentTerm,
8
8
  };
9
9
 
10
- export const Basic = (args) => (
10
+ export const AutoRenewingTermType = (args) => (
11
11
  <div className="ncf">
12
12
  <Fieldset>
13
13
  <PaymentTerm {...args} />
@@ -15,8 +15,55 @@ export const Basic = (args) => (
15
15
  </div>
16
16
  );
17
17
 
18
- Basic.args = {
18
+ AutoRenewingTermType.args = {
19
19
  options: [
20
+ {
21
+ name: '3 yearly',
22
+ isTrial: false,
23
+ discount: '',
24
+ selected: false,
25
+ price: '$909.00',
26
+ trialPrice: '$0.00',
27
+ trialDuration: '',
28
+ monthlyPrice: '0',
29
+ amount: '909.00',
30
+ trialAmount: null,
31
+ value: 'P3Y',
32
+ symbol: '$',
33
+ subscriptionAutoRenewTerm: true,
34
+ },
35
+ {
36
+ name: '26 monthly',
37
+ isTrial: false,
38
+ discount: '',
39
+ selected: false,
40
+ price: '£335.00',
41
+ trialPrice: '£0.00',
42
+ trialDuration: '',
43
+ monthlyPrice: null,
44
+ amount: '335.00',
45
+ trialAmount: null,
46
+ value: 'P26M',
47
+ symbol: '£',
48
+ subscriptionAutoRenewTerm: true,
49
+ },
50
+ // 2 yearly (non-trial)
51
+ {
52
+ name: '2 yearly',
53
+ isTrial: false,
54
+ discount: '',
55
+ selected: false,
56
+ price: '£310.00',
57
+ trialPrice: '£0.00',
58
+ trialDuration: '',
59
+ monthlyPrice: null,
60
+ amount: '310.00',
61
+ trialAmount: null,
62
+ value: 'P2Y',
63
+ symbol: '£',
64
+ subscriptionAutoRenewTerm: true,
65
+ },
66
+ // 2 yearly (trial)
20
67
  {
21
68
  name: '2 yearly',
22
69
  isTrial: true,
@@ -29,49 +76,70 @@ Basic.args = {
29
76
  amount: '645.00',
30
77
  trialAmount: 100,
31
78
  value: 'P2Y',
32
- currency: 'USD',
79
+ symbol: '$',
80
+ subscriptionAutoRenewTerm: true,
33
81
  },
34
82
  {
35
- name: '3 yearly',
83
+ name: '13 monthly',
36
84
  isTrial: false,
37
85
  discount: '',
38
86
  selected: false,
39
- price: '$909.00',
40
- trialPrice: '$0.00',
87
+ price: '£155.00',
88
+ trialPrice: '£0.00',
41
89
  trialDuration: '',
42
- monthlyPrice: '0',
43
- amount: '909.00',
90
+ monthlyPrice: null,
91
+ amount: '155.00',
44
92
  trialAmount: null,
45
- value: 'P3Y',
46
- currency: 'USD',
93
+ value: 'P13M',
94
+ symbol: '£',
95
+ subscriptionAutoRenewTerm: true,
47
96
  },
97
+ // Annual whose value is P1Y
48
98
  {
49
- name: '6 monthly',
99
+ name: 'annual',
50
100
  isTrial: false,
51
101
  discount: '',
52
- selected: false,
53
- price: '$229.00',
102
+ selected: true,
103
+ price: '$385.00',
54
104
  trialPrice: '$0.00',
55
105
  trialDuration: '',
56
- monthlyPrice: '0',
57
- amount: '229.00',
106
+ monthlyPrice: '$32.09',
107
+ amount: '385.00',
58
108
  trialAmount: null,
59
- value: 'P6M',
60
- currency: 'USD',
109
+ value: 'P1Y',
110
+ symbol: '$',
111
+ subscriptionAutoRenewTerm: true,
61
112
  },
113
+ // Annual whose value is P52W
62
114
  {
63
115
  name: 'annual',
64
116
  isTrial: false,
65
117
  discount: '',
66
- selected: true,
67
- price: '$385.00',
118
+ selected: false,
119
+ price: '£140.00',
120
+ trialPrice: '£0.00',
121
+ trialDuration: '',
122
+ monthlyPrice: null,
123
+ amount: '140.00',
124
+ trialAmount: null,
125
+ value: 'P52W',
126
+ symbol: '£',
127
+ subscriptionAutoRenewTerm: true,
128
+ },
129
+ {
130
+ name: '6 monthly',
131
+ isTrial: false,
132
+ discount: '',
133
+ selected: false,
134
+ price: '$229.00',
68
135
  trialPrice: '$0.00',
69
136
  trialDuration: '',
70
- monthlyPrice: '$32.09',
71
- amount: '385.00',
137
+ monthlyPrice: '0',
138
+ amount: '229.00',
72
139
  trialAmount: null,
73
- value: 'P1Y',
74
- currency: 'USD',
140
+ value: 'P6M',
141
+ symbol: '$',
142
+ subscriptionAutoRenewTerm: true,
75
143
  },
76
144
  {
77
145
  name: 'quarterly',
@@ -85,9 +153,27 @@ Basic.args = {
85
153
  amount: '95.00',
86
154
  trialAmount: null,
87
155
  value: 'P3M',
88
- currency: 'USD',
156
+ symbol: '$',
157
+ subscriptionAutoRenewTerm: true,
158
+ },
159
+ {
160
+ name: 'monthly',
161
+ isTrial: false,
162
+ discount: '',
163
+ selected: false,
164
+ price: '£42.00',
165
+ trialPrice: '£0.00',
166
+ trialDuration: '',
167
+ monthlyPrice: null,
168
+ amount: '42.00',
169
+ trialAmount: null,
170
+ value: 'P1M',
171
+ symbol: '£',
172
+ subscriptionAutoRenewTerm: true,
89
173
  },
90
174
  ],
175
+ isAutoRenewingSubscriptionTermType: true,
176
+ isNonRenewingSubscriptionTermType: false,
91
177
  };
92
178
 
93
179
  export const NonRenewingTermType = (args) => (
@@ -99,13 +185,38 @@ export const NonRenewingTermType = (args) => (
99
185
  );
100
186
  NonRenewingTermType.args = {
101
187
  options: [
188
+ {
189
+ name: 'quarterly',
190
+ isTrial: false,
191
+ discount: '',
192
+ selected: true,
193
+ price: '£15.00',
194
+ trialPrice: '£0.00',
195
+ trialDuration: '',
196
+ monthlyPrice: null,
197
+ amount: '15.00',
198
+ trialAmount: null,
199
+ value: 'P13W',
200
+ symbol: '£',
201
+ subscriptionAutoRenewTerm: false,
202
+ },
102
203
  {
103
204
  name: '8 weeks',
205
+ isTrial: false,
206
+ discount: '',
207
+ selected: false,
104
208
  price: '£19.00',
209
+ trialPrice: '£0.00',
210
+ trialDuration: '',
211
+ monthlyPrice: null,
105
212
  amount: '19.00',
213
+ trialAmount: null,
106
214
  value: 'P8W',
215
+ symbol: '£',
216
+ subscriptionAutoRenewTerm: false,
107
217
  },
108
218
  ],
219
+ isAutoRenewingSubscriptionTermType: false,
109
220
  isNonRenewingSubscriptionTermType: true,
110
221
  };
111
222
 
@@ -10,6 +10,7 @@ var _react = _interopRequireDefault(require("react"));
10
10
  var _propTypes = _interopRequireDefault(require("prop-types"));
11
11
  var _classnames = _interopRequireDefault(require("classnames"));
12
12
  var _nPricing = require("@financial-times/n-pricing");
13
+ var _helpers = require("../helpers");
13
14
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
14
15
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
15
16
  function PaymentTerm(_ref) {
@@ -36,138 +37,41 @@ function PaymentTerm(_ref) {
36
37
  _ref$isNonRenewingSub = _ref.isNonRenewingSubscriptionTermType,
37
38
  isNonRenewingSubscriptionTermType = _ref$isNonRenewingSub === void 0 ? false : _ref$isNonRenewingSub;
38
39
  /**
39
- * Compute monthly price for given term name
40
- * @param {number} amount price in number format
41
- * @param {string} currency country id of the currency
42
- * @param {string} period (expressed in IS0 8601 duration format): e.g. PxY (yearly) or PxM (montly) where x is the amount of years/months
40
+ * Capitalises a string.
41
+ * @param {string} Input string to be capitalised
43
42
  * @returns {string}
44
43
  */
45
- var getMonthlyPriceFromPeriod = function getMonthlyPriceFromPeriod(amount, currency, period) {
46
- var periodObj = new _nPricing.Period(period);
47
- var monthlyPrice = periodObj.calculatePrice('P1M', amount);
48
- return new _nPricing.Monthly({
49
- value: monthlyPrice,
50
- currency: currency
51
- }).getAmount('monthly');
44
+ var capitalise = function capitalise(string) {
45
+ return Boolean(string) ? string[0].toUpperCase() + string.slice(1) : string;
52
46
  };
53
47
 
54
48
  /**
55
- * returns period converted to time if found
56
- * otherwise returns empty string to avoid show information not mapped
57
- * @param {string} period (expressed in IS0 8601 duration format): PxY (yearly), PxM (montly), PxW (weekly), of PxD (daily), where x is the amount of years/months/weeks/days
58
- * @returns {string}
49
+ * Creates the JSX for a single payment-term option, including the input,
50
+ * title, discount messaging, and descriptive pricing copy.
51
+ *
52
+ * @param {Object} option - Payment term configuration
53
+ * @param {string} option.value - ISO 8601 duration of the subscription term of the offer
54
+ * @param {string} option.name - term name, e.g. "monthly", "annual", "2 yearly
55
+ * @param {string} option.price - Formatted display price
56
+ * @param {string|number} [option.amount] - Price expressed in numerical terms
57
+ * @param {string} [option.symbol] - Currency symbol, e.g. £
58
+ * @param {string} [option.monthlyPrice] - Precomputed monthly equivalent price (can be with or without currency symbol)
59
+ * @param {boolean} [option.discount] - Whether the option should display discount messaging
60
+ * @param {boolean} [option.bestOffer] - Whether the option should show "Best offer" instead of standard discount copy
61
+ * @param {boolean} [option.selected] - Whether the option is selected by default
62
+ * @param {boolean} [option.isTrial] - Whether the option is a trial offer
63
+ * @param {boolean} [option.subscriptionAutoRenewTerm] - Whether the option is for an auto-renewing subscription
64
+ * @param {number} [option.trialAmount] - Amount used for trial pricing
65
+ * @param {string} [option.trialDuration] - Human-readable trial duration copy
66
+ * @param {string} [option.trialPrice] - Formatted trial price
67
+ * @param {string} [option.displayName] - Override label for the term title
68
+ * @param {string} [option.title] - Fallback title for legacy or non-period terms
69
+ * @param {string} [option.subTitle] - Optional subtitle shown alongside the term title
70
+ * @param {string} [option.chargeOnText] - Optional charge timing copy for non-period offers
71
+ * @param {boolean} [option.b2cPartnership] - Whether the option is part of a B2C partnership offer
72
+ * @param {string} [option.b2cDiscountCopy] - Partnership-specific discount copy
73
+ * @returns {React.ReactElement} A rendered payment term option
59
74
  */
60
- var getTimeFromPeriod = function getTimeFromPeriod(period) {
61
- var periodUnitCodeToWordMap = {
62
- Y: 'years',
63
- M: 'months',
64
- W: 'weeks',
65
- D: 'days'
66
- };
67
- var periodUnitCode = period.substring(period.length - 1);
68
- var freq = periodUnitCodeToWordMap[periodUnitCode] || '';
69
- var amount = period.substring(1, period.length - 1);
70
- return period ? "".concat(amount, " ").concat(freq) : '';
71
- };
72
- var isValidPeriod = function isValidPeriod(period) {
73
- try {
74
- // Period should throw an error if it is not properly provided
75
- // in order to validate it, we just send in case type is string
76
- new _nPricing.Period(typeof period === 'string' ? period : '');
77
- return true;
78
- } catch (e) {
79
- return false;
80
- }
81
- };
82
- var nameMap = {
83
- annual: {
84
- title: 'Annual',
85
- price: function price(_price) {
86
- return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, "Single", ' ', /*#__PURE__*/_react["default"].createElement("span", {
87
- className: "ncf__payment-term__price ncf__strong"
88
- }, _price), ' ', "payment");
89
- },
90
- trialPrice: function trialPrice(price) {
91
- return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, "Unless you cancel during your trial you will be billed", ' ', /*#__PURE__*/_react["default"].createElement("span", {
92
- className: "ncf__payment-term__price"
93
- }, price), " per year after the trial period.");
94
- },
95
- monthlyPrice: function monthlyPrice(price) {
96
- return price && /*#__PURE__*/_react["default"].createElement("span", {
97
- className: "ncf__payment-term__equivalent-price"
98
- }, "That\u2019s equivalent to", ' ', /*#__PURE__*/_react["default"].createElement("span", {
99
- className: "ncf__payment-term__monthly-price"
100
- }, price), ' ', "per month");
101
- },
102
- renewsText: function renewsText() {
103
- return /*#__PURE__*/_react["default"].createElement("p", {
104
- className: "ncf__payment-term__renews-text"
105
- }, "Renews annually unless cancelled");
106
- }
107
- },
108
- quarterly: {
109
- title: 'Quarterly',
110
- price: function price(_price2) {
111
- return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("span", {
112
- className: "ncf__payment-term__price"
113
- }, _price2), " per quarter");
114
- },
115
- trialPrice: function trialPrice(price) {
116
- return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, "Unless you cancel during your trial you will be billed", ' ', /*#__PURE__*/_react["default"].createElement("span", {
117
- className: "ncf__payment-term__price"
118
- }, price), " per quarter after the trial period.");
119
- },
120
- monthlyPrice: function monthlyPrice() {},
121
- renewsText: function renewsText() {
122
- return /*#__PURE__*/_react["default"].createElement("p", {
123
- className: "ncf__payment-term__renews-text"
124
- }, "Renews quarterly unless cancelled");
125
- }
126
- },
127
- monthly: {
128
- title: 'Monthly',
129
- price: function price(_price3) {
130
- return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("span", {
131
- className: "ncf__payment-term__price"
132
- }, _price3), " per month");
133
- },
134
- trialPrice: function trialPrice(price) {
135
- return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, "Unless you cancel during your trial you will be billed", ' ', /*#__PURE__*/_react["default"].createElement("span", {
136
- className: "ncf__payment-term__price"
137
- }, price), " per month after the trial period.");
138
- },
139
- monthlyPrice: function monthlyPrice() {},
140
- renewsText: function renewsText() {
141
- return /*#__PURE__*/_react["default"].createElement("p", {
142
- className: "ncf__payment-term__renews-text"
143
- }, 'Renews monthly unless cancelled');
144
- }
145
- },
146
- custom: {
147
- price: function price(_price4) {
148
- return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, "Single", ' ', /*#__PURE__*/_react["default"].createElement("span", {
149
- className: "ncf__payment-term__price ncf__strong"
150
- }, _price4), ' ', "payment");
151
- },
152
- trialPrice: function trialPrice(_trialPrice, trialPeriod) {
153
- return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, "Unless you cancel during your trial you will be billed", ' ', /*#__PURE__*/_react["default"].createElement("span", {
154
- className: "ncf__payment-term__price"
155
- }, _trialPrice), " per", ' ', trialPeriod, "after the trial period.");
156
- },
157
- monthlyPrice: function monthlyPrice(_monthlyPrice) {
158
- return Boolean(_monthlyPrice) && /*#__PURE__*/_react["default"].createElement("span", {
159
- className: "ncf__payment-term__equivalent-price"
160
- }, "That\u2019s equivalent to", ' ', /*#__PURE__*/_react["default"].createElement("span", {
161
- className: "ncf__payment-term__monthly-price"
162
- }, _monthlyPrice), ' ', "per month");
163
- },
164
- renewsText: function renewsText(renewalPeriod) {
165
- return Boolean(renewalPeriod) && /*#__PURE__*/_react["default"].createElement("p", {
166
- className: "ncf__payment-term__renews-text"
167
- }, "Renews every ", renewalPeriod, " unless cancelled");
168
- }
169
- }
170
- };
171
75
  var createPaymentTerm = function createPaymentTerm(option) {
172
76
  var className = (0, _classnames["default"])(['ncf__payment-term__item', 'o-forms-input--radio-round', {
173
77
  'ncf__payment-term__item--discount': option.discount
@@ -182,50 +86,185 @@ function PaymentTerm(_ref) {
182
86
  }, option.selected && {
183
87
  defaultChecked: true
184
88
  });
89
+
90
+ /**
91
+ * Determines whether input is a valid ISO 8601 duration value that can be decoded by the Period class.
92
+ * @returns {boolean}
93
+ */
94
+ var isValidPeriod = function isValidPeriod() {
95
+ try {
96
+ // Period should throw an error if it is not properly provided
97
+ // in order to validate it, we just send in case type is string
98
+ new _nPricing.Period(typeof option.value === 'string' ? option.value : '');
99
+ return true;
100
+ } catch (error) {
101
+ return false;
102
+ }
103
+ };
104
+
105
+ /**
106
+ * Compute monthly price for given term name.
107
+ * @returns {string}
108
+ */
109
+ var getMonthlyPriceFromPeriod = function getMonthlyPriceFromPeriod() {
110
+ var periodObj = new _nPricing.Period(option.value);
111
+ var monthlyPrice = periodObj.calculatePrice('P1M', option.amount);
112
+ return new _nPricing.Monthly({
113
+ value: monthlyPrice,
114
+ symbol: option.symbol
115
+ }).getAmount('monthly');
116
+ };
117
+
118
+ /**
119
+ * Returns elements that include the text describing the price of the offer option.
120
+ * @returns {React.ReactElement}
121
+ */
122
+ var getPriceText = function getPriceText() {
123
+ var isExpressedAsSinglePayment = !option.subscriptionAutoRenewTerm ||
124
+ // With an auto-renewing annual term there is a high chance
125
+ // it will not be the same price in the second year,
126
+ // so we do not want to imply that the price will remain consistent.
127
+ // For shorter auto-renewing terms there is higher confidence that the price
128
+ // will remain consistent across subsequent terms.
129
+ option.subscriptionAutoRenewTerm && (0, _helpers.is52WeeksOrLonger)(option.value);
130
+ var isExpressedAsRecurringPayment = !isExpressedAsSinglePayment;
131
+ if (isExpressedAsSinglePayment) {
132
+ return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, "Single", ' ', /*#__PURE__*/_react["default"].createElement("span", {
133
+ className: "ncf__payment-term__price"
134
+ }, option.price), ' ', "payment");
135
+ }
136
+ if (isExpressedAsRecurringPayment) {
137
+ return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("span", {
138
+ className: "ncf__payment-term__price"
139
+ }, option.price), " per", ' ', (0, _helpers.getDurationFromISO8601Value)({
140
+ iso8601Value: option.value
141
+ }));
142
+ }
143
+ };
144
+
145
+ /**
146
+ * Returns elements that include the text describing the price increase following the trial period.
147
+ * @returns {React.ReactElement}
148
+ */
149
+ var getTrialPriceExplanatoryText = function getTrialPriceExplanatoryText() {
150
+ return /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, "Unless you cancel during your trial you will be billed", ' ', /*#__PURE__*/_react["default"].createElement("span", {
151
+ className: "ncf__payment-term__price"
152
+ }, option.price), " per", ' ', (0, _helpers.getDurationFromISO8601Value)({
153
+ iso8601Value: option.value
154
+ }), ' ', "after the trial period.");
155
+ };
156
+
157
+ /**
158
+ * Returns elements that include the text describing how regularly an auto-reniewing subscription will renew.
159
+ * @returns {React.ReactElement}
160
+ */
161
+ var getRenewalPeriodText = function getRenewalPeriodText() {
162
+ return /*#__PURE__*/_react["default"].createElement("p", {
163
+ className: "ncf__payment-term__renews-text"
164
+ }, "Renews every", ' ', (0, _helpers.getDurationFromISO8601Value)({
165
+ iso8601Value: option.value
166
+ }), " unless cancelled");
167
+ };
168
+
169
+ /**
170
+ * Returns elements that include the text describing the monthly equivalent of the subscription.
171
+ * @returns {string}
172
+ */
173
+ var getEquivalentMonthlyPrice = function getEquivalentMonthlyPrice() {
174
+ if (Boolean(option.monthlyPrice) && option.monthlyPrice !== '0') {
175
+ return isNaN(option.monthlyPrice) ? option.monthlyPrice : "".concat(option.symbol).concat(option.monthlyPrice);
176
+ }
177
+ return getMonthlyPriceFromPeriod();
178
+ };
179
+
180
+ /**
181
+ * Returns elements that include the text describing the monthly equivalent of the subscription.
182
+ * @returns {React.ReactElement}
183
+ */
184
+ var getEquivalentMonthlyPriceText = function getEquivalentMonthlyPriceText() {
185
+ return /*#__PURE__*/_react["default"].createElement("span", {
186
+ className: "ncf__payment-term__equivalent-price"
187
+ }, "That\u2019s equivalent to", ' ', /*#__PURE__*/_react["default"].createElement("span", {
188
+ className: "ncf__payment-term__monthly-price"
189
+ }, getEquivalentMonthlyPrice()), ' ', "per month");
190
+ };
191
+
192
+ /**
193
+ * Creates the standard discount badge for an option.
194
+ * Displays either "Best offer" or "Save X off RRP" when a discount exists.
195
+ *
196
+ * @returns {React.ReactElement} The discount element, or false when no discount should be shown
197
+ */
185
198
  var createDiscount = function createDiscount() {
186
199
  return option.discount && /*#__PURE__*/_react["default"].createElement("span", {
187
200
  className: "ncf__payment-term__discount"
188
201
  }, option.bestOffer ? 'Best offer' : "Save ".concat(option.discount, " off RRP"));
189
202
  };
203
+
204
+ /**
205
+ * Creates B2C partnership discount copy for eligible annual offers.
206
+ *
207
+ * @returns {React.ReactElement} The B2C discount element, or false when the option is not eligible
208
+ */
190
209
  var createB2cDiscountCopy = function createB2cDiscountCopy() {
191
210
  return option.name === 'annual' && option.b2cPartnership && option.b2cDiscountCopy && /*#__PURE__*/_react["default"].createElement("span", {
192
211
  className: "ncf__payment-term__discount"
193
212
  }, option.b2cDiscountCopy);
194
213
  };
214
+
215
+ /**
216
+ * Creates the description shown beneath the term title.
217
+ * This may include trial copy, price-per-period copy, equivalent monthly price,
218
+ * renewal messaging, or fallback non-period pricing text.
219
+ *
220
+ * @returns {React.ReactElement} The description block for the payment term
221
+ */
195
222
  var createDescription = function createDescription() {
196
- return option.isTrial ? /*#__PURE__*/_react["default"].createElement("div", {
197
- className: "ncf__payment-term__description"
198
- }, option.trialDuration || '4 weeks', " for", ' ', /*#__PURE__*/_react["default"].createElement("span", {
199
- className: "ncf__payment-term__trial-price"
200
- }, option.trialPrice), /*#__PURE__*/_react["default"].createElement("br", null), nameMap[option.name] && nameMap[option.name].trialPrice(option.price)) : /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, nameMap[option.name] ? /*#__PURE__*/_react["default"].createElement("div", {
201
- className: "ncf__payment-term__description"
202
- }, nameMap[option.name].price(option.price), nameMap[option.name].monthlyPrice(option.monthlyPrice), isAutoRenewingSubscriptionTermType && nameMap[option.name].renewsText()) :
203
- // this should cover the cases different than annual, quarterly and monthly
204
- // for those containing period on option.value, render custom template, for the rest keep legacy render
205
- isValidPeriod(option.value) ? /*#__PURE__*/_react["default"].createElement("div", {
206
- className: "ncf__payment-term__description"
207
- }, nameMap['custom'].price(option.price), nameMap['custom'].monthlyPrice(option.monthlyPrice && option.monthlyPrice !== '0' ? Number(option.monthlyPrice) : getMonthlyPriceFromPeriod(option.amount, option.currency, option.value)), isAutoRenewingSubscriptionTermType && nameMap['custom'].renewsText(getTimeFromPeriod(option.value))) : /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("span", {
223
+ if (option.isTrial) {
224
+ return /*#__PURE__*/_react["default"].createElement("div", {
225
+ className: "ncf__payment-term__description"
226
+ }, option.trialDuration || '4 weeks', " for", ' ', /*#__PURE__*/_react["default"].createElement("span", {
227
+ className: "ncf__payment-term__trial-price"
228
+ }, option.trialPrice), /*#__PURE__*/_react["default"].createElement("br", null), getTrialPriceExplanatoryText());
229
+ }
230
+ if (isValidPeriod(option.value)) {
231
+ return /*#__PURE__*/_react["default"].createElement("div", {
232
+ className: "ncf__payment-term__description"
233
+ }, getPriceText(), (0, _helpers.is90DaysOrLonger)(option.value) && getEquivalentMonthlyPriceText(), option.subscriptionAutoRenewTerm && getRenewalPeriodText());
234
+ }
235
+ return /*#__PURE__*/_react["default"].createElement("div", null, /*#__PURE__*/_react["default"].createElement("span", {
208
236
  className: largePrice ? 'ncf__payment-term__large-price' : ''
209
237
  }, option.price), option.chargeOnText && /*#__PURE__*/_react["default"].createElement("p", {
210
238
  className: "ncf__payment-term__charge-on-text"
211
- }, option.chargeOnText)));
239
+ }, option.chargeOnText));
212
240
  };
241
+
242
+ /**
243
+ * Builds the display name shown as the payment term title.
244
+ * May prepend trial copy, use the capitalised term name for auto-renewing terms,
245
+ * derive a human-readable period for valid non-renewing terms, or fall back to
246
+ * a legacy title when no valid period is available.
247
+ *
248
+ * @returns {string} The formatted display name for the payment term
249
+ */
213
250
  var getTermDisplayName = function getTermDisplayName() {
214
251
  var showTrialCopyInTitle = option.isTrial && !isPrintOrBundle && !isDigitalEdition;
215
- var title = option.name && nameMap[option.name] ? nameMap[option.name].title : '';
216
252
  var termDisplayName = '';
217
253
  if (showTrialCopyInTitle) {
218
254
  var termName = option.displayName ? option.displayName : 'Premium Digital';
219
255
  termDisplayName = "Trial: ".concat(termName, " - ");
220
256
  }
221
257
  var getTermPeriod = function getTermPeriod() {
222
- // annual, quarterly and monthly
223
- if (nameMap[option.name]) {
224
- return title;
258
+ if (option.subscriptionAutoRenewTerm && option.name) {
259
+ return capitalise(option.name);
225
260
  }
261
+
226
262
  // custom offer with period provided
227
- if (isValidPeriod(option.value)) {
228
- return getTimeFromPeriod(option.value);
263
+ if (!option.subscriptionAutoRenewTerm && isValidPeriod(option.value)) {
264
+ return (0, _helpers.getDurationFromISO8601Value)({
265
+ iso8601Value: option.value,
266
+ excludeAmountWhenSingular: false
267
+ });
229
268
  }
230
269
  // custom legacy cases, where period is not provided
231
270
  return option.title;
@@ -284,12 +323,14 @@ PaymentTerm.propTypes = {
284
323
  isB2cPartnership: _propTypes["default"].bool,
285
324
  discount: _propTypes["default"].string,
286
325
  isTrial: _propTypes["default"].bool,
326
+ subscriptionAutoRenewTerm: _propTypes["default"].bool,
287
327
  name: _propTypes["default"].string.isRequired,
288
328
  price: _propTypes["default"].string.isRequired,
289
329
  selected: _propTypes["default"].bool,
290
330
  trialDuration: _propTypes["default"].string,
291
331
  trialPrice: _propTypes["default"].string,
292
332
  amount: _propTypes["default"].string,
333
+ symbol: _propTypes["default"].string,
293
334
  trialAmount: _propTypes["default"].number,
294
335
  value: _propTypes["default"].string.isRequired,
295
336
  monthlyPrice: _propTypes["default"].string,