@financial-times/n-conversion-forms 40.0.2 → 41.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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "branch": "",
3
3
  "repo": "n-conversion-forms",
4
- "version": "851ad665946f79ea01a1d6152a42c7a2debb3ceb",
5
- "tag": "v40.0.2",
6
- "buildNumber": "15060"
4
+ "version": "2cb838a4fc4d3fd5c1911d80503a2d927ec71a27",
5
+ "tag": "v41.0.0",
6
+ "buildNumber": "15084"
7
7
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  ".toolkitrc.yml": "XiiIocllEaT8xqKRCTpTbJ+yUyduDo5aEHARUQ3vJFfSe187Ci13PEs3bWL272GFJyNz2QgRQhdov2/+LFRKuw==",
3
- "package.json": "Or39bD7+0aRIUCealkxIwU9bZKt+MC9MGSiMCbScS+oU3bCrLld+sy7mq9xS0mkAbUmWYG5FxdbWSAgYajF/nA==",
3
+ "package.json": "Q++D0RhTdwacN2+LL5eQZaV5Ck5QP637EEpW6f9Mu8Jk/PXaa11O1cCs+/TUvXxCrvDVSbepecfSkDoRv/oXzg==",
4
4
  ".circleci/config.yml": "eph42EF3EsL7jvhiiC7D7vG3vGBAGBFVC+Ncmy4Dj4rUNzK8Rls0/cr+bEF/ttMN3J6iSL1xtCXKIJVrtZ4OSQ=="
5
5
  }
package/README.md CHANGED
@@ -57,8 +57,9 @@ import MyModule from 'n-conversion-forms/utils/my-module';
57
57
  - [Event Notifier](#event-notifier)
58
58
  - [Loader](#loader)
59
59
  - [Password](#password)
60
- - [Payment Term](#payment-term)
61
- - [Payment Type](#payment-type)
60
+ - [Payment Term](#paymentTerm)
61
+ - [Payment Type](#paymentType)
62
+ - [Region Selector](#regionSelector)
62
63
  - [Salesforce](#salesforce)
63
64
  - [Submit](#submit)
64
65
  - [Tracking](#tracking)
@@ -262,6 +263,32 @@ PaymentType.PAYPAL;
262
263
  PaymentType.APPLEPAY;
263
264
  ```
264
265
 
266
+ ### RegionSelector
267
+
268
+ The `RegionSelector` utility provides a form element for selecting regions (states, provinces, etc.) based on the selected country. It supports dynamic naming and labeling based on the provided options.
269
+
270
+ > **Note**: Ensure that the `country`, `regionType`, and `fieldId` used here match what is used in the props for the `RegionSelector` component in `region-selector.jsx`.
271
+
272
+ #### Usage
273
+
274
+ ```js
275
+ // Using default options
276
+ const regionSelector = new RegionSelector(document, { country: 'CAN' });
277
+
278
+ // Using custom options
279
+ const customRegionSelector = new RegionSelector(document, {
280
+ country: 'IND',
281
+ regionType: 'customRegionType',
282
+ fieldId: 'customFieldId',
283
+ });
284
+
285
+ // Example of util functions
286
+ regionSelector.hide();
287
+ regionSelector.show();
288
+ regionSelector.disable();
289
+ regionSelector.enable();
290
+ ```
291
+
265
292
  ### Salesforce
266
293
 
267
294
  Utility for converting salesforce country names to ISO country codes.
@@ -46,11 +46,10 @@ export { PaymentType } from './payment-type';
46
46
  export { Phone } from './phone';
47
47
  export { Position } from './position';
48
48
  export { ProgressIndicator } from './progress-indicator';
49
- export { Province } from './province';
49
+ export { RegionSelector } from './region-selector';
50
50
  export { RegistrationConfirmation } from './registration-confirmation';
51
51
  export { Responsibility } from './responsibility';
52
52
  export { Section } from './section';
53
- export { State } from './state';
54
53
  export { Submit } from './submit';
55
54
  export { TrialBanner } from './trial-banner';
56
55
  export { EducationJobTitle } from './education-job-title';
@@ -0,0 +1,99 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import classNames from 'classnames';
4
+
5
+ import { configByCountry } from '../utils/region-selector';
6
+
7
+ export function RegionSelector({
8
+ country = 'USA',
9
+ fieldId,
10
+ hasError = false,
11
+ isBillingSelector = false,
12
+ isDisabled = false,
13
+ isHidden = false,
14
+ label,
15
+ regionType,
16
+ selectId,
17
+ value,
18
+ }) {
19
+ const {
20
+ regions = [],
21
+ defaultRegionType,
22
+ label: defaultLabel,
23
+ } = configByCountry[country];
24
+
25
+ const dynamicRegionType = regionType || defaultRegionType;
26
+ const dynamicLabel = isBillingSelector
27
+ ? `Billing ${label || defaultLabel}`
28
+ : label || defaultLabel;
29
+ const dynamicFieldId = fieldId || `${dynamicRegionType}Field`;
30
+ const dynamicSelectId = selectId || dynamicRegionType;
31
+
32
+ const dynamicName = isBillingSelector
33
+ ? `billing${
34
+ dynamicRegionType.charAt(0).toUpperCase() + dynamicRegionType.slice(1)
35
+ }`
36
+ : dynamicRegionType;
37
+
38
+ const fieldClassNames = classNames([
39
+ 'o-forms-field',
40
+ { ncf__hidden: isHidden },
41
+ ]);
42
+
43
+ const inputWrapperClassNames = classNames([
44
+ 'o-forms-input',
45
+ 'o-forms-input--select',
46
+ { 'o-forms-input--invalid': hasError },
47
+ ]);
48
+
49
+ return (
50
+ <label
51
+ id={dynamicFieldId}
52
+ className={fieldClassNames}
53
+ data-validate="required"
54
+ htmlFor={dynamicSelectId}
55
+ >
56
+ <span className="o-forms-title">
57
+ <span className="o-forms-title__main">{dynamicLabel}</span>
58
+ </span>
59
+ <span className={inputWrapperClassNames}>
60
+ <select
61
+ id={selectId}
62
+ aria-required="true"
63
+ required
64
+ name={dynamicName}
65
+ data-trackable={`field-${dynamicRegionType}`}
66
+ disabled={isDisabled}
67
+ defaultValue={value}
68
+ >
69
+ <option disabled value="">
70
+ Please select a {defaultLabel.toLowerCase()}
71
+ </option>
72
+ {regions.map(({ code, name }) => {
73
+ return (
74
+ <option key={code} value={code}>
75
+ {name}
76
+ </option>
77
+ );
78
+ })}
79
+ </select>
80
+ <span className="o-forms-input__error">
81
+ Please select your {defaultLabel.toLowerCase()}
82
+ </span>
83
+ </span>
84
+ </label>
85
+ );
86
+ }
87
+
88
+ RegionSelector.propTypes = {
89
+ country: PropTypes.oneOf(['USA', 'CAN', 'IND']),
90
+ fieldId: PropTypes.string,
91
+ hasError: PropTypes.bool,
92
+ isBillingSelector: PropTypes.bool,
93
+ isDisabled: PropTypes.bool,
94
+ isHidden: PropTypes.bool,
95
+ label: PropTypes.string,
96
+ regionType: PropTypes.string,
97
+ selectId: PropTypes.string,
98
+ value: PropTypes.string,
99
+ };
@@ -0,0 +1,121 @@
1
+ import React from 'react';
2
+ import { RegionSelector } from './region-selector';
3
+ import Enzyme, { mount } from 'enzyme';
4
+ import Adapter from 'enzyme-adapter-react-16';
5
+ Enzyme.configure({ adapter: new Adapter() });
6
+
7
+ describe('RegionSelector', () => {
8
+ it('renders a select with a label', () => {
9
+ const props = {
10
+ country: 'USA',
11
+ };
12
+ const component = mount(<RegionSelector {...props} />);
13
+ expect(component.find('label').exists()).toBe(true);
14
+ expect(component.find('select').exists()).toBe(true);
15
+ });
16
+
17
+ it('renders the correct label based on country and isBillingSelector', () => {
18
+ const props = {
19
+ country: 'CAN',
20
+ isBillingSelector: true,
21
+ };
22
+ const component = mount(<RegionSelector {...props} />);
23
+ expect(component.find('label').text()).toContain('Billing Province');
24
+ });
25
+
26
+ it('can render an initial selected value', () => {
27
+ const props = {
28
+ country: 'USA',
29
+ value: 'AR',
30
+ };
31
+ const component = mount(<RegionSelector {...props} />);
32
+ expect(component.find('select').prop('defaultValue')).toBe('AR');
33
+ });
34
+
35
+ it('can render a disabled select', () => {
36
+ const props = {
37
+ country: 'USA',
38
+ isDisabled: true,
39
+ };
40
+ const component = mount(<RegionSelector {...props} />);
41
+ expect(component.find('select').prop('disabled')).toBe(true);
42
+ });
43
+
44
+ it('can render an error state', () => {
45
+ const props = {
46
+ country: 'USA',
47
+ hasError: true,
48
+ };
49
+ const component = mount(<RegionSelector {...props} />);
50
+ expect(component.find('.o-forms-input--invalid').exists()).toBe(true);
51
+ });
52
+
53
+ it('can hide the component', () => {
54
+ const props = {
55
+ country: 'USA',
56
+ isHidden: true,
57
+ };
58
+ const component = mount(<RegionSelector {...props} />);
59
+ expect(component.find('.ncf__hidden').exists()).toBe(true);
60
+ });
61
+
62
+ it('can override id for field', () => {
63
+ const props = {
64
+ country: 'USA',
65
+ fieldId: 'customFieldId',
66
+ };
67
+ const component = mount(<RegionSelector {...props} />);
68
+ expect(component.find('#customFieldId').exists()).toBe(true);
69
+ });
70
+
71
+ it('can override id for select', () => {
72
+ const props = {
73
+ country: 'USA',
74
+ selectId: 'customSelectId',
75
+ };
76
+ const component = mount(<RegionSelector {...props} />);
77
+ expect(component.find('select#customSelectId').exists()).toBe(true);
78
+ });
79
+
80
+ it('applies context-specific name if is billing state', () => {
81
+ const props = {
82
+ country: 'USA',
83
+ isBillingSelector: true,
84
+ };
85
+ const component = mount(<RegionSelector {...props} />);
86
+ expect(component.find('select').prop('name')).toBe('billingState');
87
+ });
88
+
89
+ it('applies context-specific name if is not billing state', () => {
90
+ const props = {
91
+ country: 'USA',
92
+ isBillingSelector: false,
93
+ };
94
+ const component = mount(<RegionSelector {...props} />);
95
+ expect(component.find('select').prop('name')).toBe('state');
96
+ });
97
+
98
+ it('renders the correct label for USA', () => {
99
+ const props = {
100
+ country: 'USA',
101
+ };
102
+ const component = mount(<RegionSelector {...props} />);
103
+ expect(component.find('label').text()).toContain('State');
104
+ });
105
+
106
+ it('renders the correct label for CAN', () => {
107
+ const props = {
108
+ country: 'CAN',
109
+ };
110
+ const component = mount(<RegionSelector {...props} />);
111
+ expect(component.find('label').text()).toContain('Province');
112
+ });
113
+
114
+ it('renders the correct label for IND', () => {
115
+ const props = {
116
+ country: 'IND',
117
+ };
118
+ const component = mount(<RegionSelector {...props} />);
119
+ expect(component.find('label').text()).toContain('State/Union Territory');
120
+ });
121
+ });
@@ -0,0 +1,84 @@
1
+ import React from 'react';
2
+ import { RegionSelector } from './region-selector';
3
+
4
+ export default {
5
+ title: 'Region Selector',
6
+ component: RegionSelector,
7
+ argTypes: {
8
+ country: { control: 'radio', options: ['USA', 'CAN', 'IND'] },
9
+ hasError: { control: 'boolean' },
10
+ isHidden: { control: 'boolean' },
11
+ isBillingSelector: { control: 'boolean' },
12
+ isDisabled: { control: 'boolean' },
13
+ region: { control: 'text' },
14
+ fieldId: { control: 'text' },
15
+ selectId: { control: 'text' },
16
+ label: { control: 'text' },
17
+ value: { control: 'text' },
18
+ },
19
+ parameters: {
20
+ docs: {
21
+ description: {
22
+ component: `
23
+ The \`RegionSelector\` component is used to select regions (states, provinces, etc.) based on the selected country. It supports dynamic naming and labeling based on the provided props.
24
+
25
+ ### Props
26
+ - **country**: The country code (e.g., 'USA', 'CAN', 'IND') to determine the list of regions.
27
+ - **value**: The selected value for the region.
28
+ - **fieldId**: Custom ID for the field label. If not provided, it defaults to \`\${region}Field\`.
29
+ - **selectId**: Custom ID for the select element. If not provided, it defaults to \`region\`.
30
+ - **label**: Custom label for the field. If not provided, it defaults to the region label based on the country.
31
+ - **hasError**: Boolean to indicate if the field has an error.
32
+ - **isHidden**: Boolean to indicate if the field should be hidden.
33
+ - **isBillingState**: Boolean to indicate if the field is for billing purposes. Adds 'Billing' prefix to the label.
34
+ - **isDisabled**: Boolean to indicate if the field should be disabled.
35
+ - **region**: Custom region name (e.g., 'state', 'province'). If not provided, it defaults to the country's default region.
36
+
37
+ ### Dynamic Logic
38
+ - **Dynamic Label**: The label is constructed based on the \`label\` prop, the country's default label, and whether it is a billing field.
39
+ - **Dynamic IDs and Names**: The \`fieldId\`, \`selectId\`, and \`name\` attributes are dynamically generated based on the \`region\` prop or the country's default region. If \`fieldId\` and \`selectId\` are provided, they are used directly.
40
+
41
+ `,
42
+ },
43
+ },
44
+ },
45
+ };
46
+
47
+ export const Basic = (args) => <RegionSelector {...args} />;
48
+ Basic.args = {
49
+ country: 'USA',
50
+ value: '',
51
+ hasError: false,
52
+ isHidden: false,
53
+ isBillingSelector: false,
54
+ isDisabled: false,
55
+ region: '',
56
+ fieldId: '',
57
+ selectId: '',
58
+ label: '',
59
+ };
60
+
61
+ export const BillingState = Basic.bind({});
62
+ BillingState.args = {
63
+ ...Basic.args,
64
+ isBillingSelector: true,
65
+ };
66
+
67
+ export const CustomRegion = Basic.bind({});
68
+ CustomRegion.args = {
69
+ ...Basic.args,
70
+ region: 'province',
71
+ };
72
+
73
+ export const CustomFieldIdAndSelectId = Basic.bind({});
74
+ CustomFieldIdAndSelectId.args = {
75
+ ...Basic.args,
76
+ fieldId: 'customFieldId',
77
+ selectId: 'customSelectId',
78
+ };
79
+
80
+ export const CustomLabel = Basic.bind({});
81
+ CustomLabel.args = {
82
+ ...Basic.args,
83
+ label: 'Custom Label',
84
+ };
package/dist/index.js CHANGED
@@ -315,10 +315,10 @@ Object.defineProperty(exports, "ProgressIndicator", {
315
315
  return _progressIndicator.ProgressIndicator;
316
316
  }
317
317
  });
318
- Object.defineProperty(exports, "Province", {
318
+ Object.defineProperty(exports, "RegionSelector", {
319
319
  enumerable: true,
320
320
  get: function get() {
321
- return _province.Province;
321
+ return _regionSelector.RegionSelector;
322
322
  }
323
323
  });
324
324
  Object.defineProperty(exports, "RegistrationConfirmation", {
@@ -339,12 +339,6 @@ Object.defineProperty(exports, "Section", {
339
339
  return _section.Section;
340
340
  }
341
341
  });
342
- Object.defineProperty(exports, "State", {
343
- enumerable: true,
344
- get: function get() {
345
- return _state.State;
346
- }
347
- });
348
342
  Object.defineProperty(exports, "Submit", {
349
343
  enumerable: true,
350
344
  get: function get() {
@@ -411,11 +405,10 @@ var _paymentType = require("./payment-type");
411
405
  var _phone = require("./phone");
412
406
  var _position = require("./position");
413
407
  var _progressIndicator = require("./progress-indicator");
414
- var _province = require("./province");
408
+ var _regionSelector = require("./region-selector");
415
409
  var _registrationConfirmation = require("./registration-confirmation");
416
410
  var _responsibility = require("./responsibility");
417
411
  var _section = require("./section");
418
- var _state = require("./state");
419
412
  var _submit = require("./submit");
420
413
  var _trialBanner = require("./trial-banner");
421
414
  var _educationJobTitle = require("./education-job-title");
@@ -4,28 +4,37 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.Province = Province;
7
+ exports.RegionSelector = RegionSelector;
8
8
  var _react = _interopRequireDefault(require("react"));
9
9
  var _propTypes = _interopRequireDefault(require("prop-types"));
10
10
  var _classnames = _interopRequireDefault(require("classnames"));
11
- var _nCommonStaticData = require("n-common-static-data");
12
- var defaultProvinces = _nCommonStaticData.canadianProvinces.provinces;
13
- function Province(_ref) {
14
- var value = _ref.value,
15
- _ref$fieldId = _ref.fieldId,
16
- fieldId = _ref$fieldId === void 0 ? 'provinceField' : _ref$fieldId,
17
- _ref$selectId = _ref.selectId,
18
- selectId = _ref$selectId === void 0 ? 'province' : _ref$selectId,
11
+ var _regionSelector = require("../utils/region-selector");
12
+ function RegionSelector(_ref) {
13
+ var _ref$country = _ref.country,
14
+ country = _ref$country === void 0 ? 'USA' : _ref$country,
15
+ fieldId = _ref.fieldId,
19
16
  _ref$hasError = _ref.hasError,
20
17
  hasError = _ref$hasError === void 0 ? false : _ref$hasError,
21
- _ref$isHidden = _ref.isHidden,
22
- isHidden = _ref$isHidden === void 0 ? false : _ref$isHidden,
23
- _ref$isBillingProvinc = _ref.isBillingProvince,
24
- isBillingProvince = _ref$isBillingProvinc === void 0 ? false : _ref$isBillingProvinc,
18
+ _ref$isBillingSelecto = _ref.isBillingSelector,
19
+ isBillingSelector = _ref$isBillingSelecto === void 0 ? false : _ref$isBillingSelecto,
25
20
  _ref$isDisabled = _ref.isDisabled,
26
21
  isDisabled = _ref$isDisabled === void 0 ? false : _ref$isDisabled,
27
- _ref$provinces = _ref.provinces,
28
- provinces = _ref$provinces === void 0 ? defaultProvinces : _ref$provinces;
22
+ _ref$isHidden = _ref.isHidden,
23
+ isHidden = _ref$isHidden === void 0 ? false : _ref$isHidden,
24
+ label = _ref.label,
25
+ regionType = _ref.regionType,
26
+ selectId = _ref.selectId,
27
+ value = _ref.value;
28
+ var _configByCountry$coun = _regionSelector.configByCountry[country],
29
+ _configByCountry$coun2 = _configByCountry$coun.regions,
30
+ regions = _configByCountry$coun2 === void 0 ? [] : _configByCountry$coun2,
31
+ defaultRegionType = _configByCountry$coun.defaultRegionType,
32
+ defaultLabel = _configByCountry$coun.label;
33
+ var dynamicRegionType = regionType || defaultRegionType;
34
+ var dynamicLabel = isBillingSelector ? "Billing ".concat(label || defaultLabel) : label || defaultLabel;
35
+ var dynamicFieldId = fieldId || "".concat(dynamicRegionType, "Field");
36
+ var dynamicSelectId = selectId || dynamicRegionType;
37
+ var dynamicName = isBillingSelector ? "billing".concat(dynamicRegionType.charAt(0).toUpperCase() + dynamicRegionType.slice(1)) : dynamicRegionType;
29
38
  var fieldClassNames = (0, _classnames["default"])(['o-forms-field', {
30
39
  ncf__hidden: isHidden
31
40
  }]);
@@ -33,28 +42,28 @@ function Province(_ref) {
33
42
  'o-forms-input--invalid': hasError
34
43
  }]);
35
44
  return /*#__PURE__*/_react["default"].createElement("label", {
36
- id: fieldId,
45
+ id: dynamicFieldId,
37
46
  className: fieldClassNames,
38
47
  "data-validate": "required",
39
- htmlFor: selectId
48
+ htmlFor: dynamicSelectId
40
49
  }, /*#__PURE__*/_react["default"].createElement("span", {
41
50
  className: "o-forms-title"
42
51
  }, /*#__PURE__*/_react["default"].createElement("span", {
43
52
  className: "o-forms-title__main"
44
- }, isBillingProvince ? 'Billing ' : '', "Province")), /*#__PURE__*/_react["default"].createElement("span", {
53
+ }, dynamicLabel)), /*#__PURE__*/_react["default"].createElement("span", {
45
54
  className: inputWrapperClassNames
46
55
  }, /*#__PURE__*/_react["default"].createElement("select", {
47
56
  id: selectId,
48
57
  "aria-required": "true",
49
58
  required: true,
50
- name: isBillingProvince ? 'billingProvince' : 'province',
51
- "data-trackable": "field-province",
59
+ name: dynamicName,
60
+ "data-trackable": "field-".concat(dynamicRegionType),
52
61
  disabled: isDisabled,
53
62
  defaultValue: value
54
63
  }, /*#__PURE__*/_react["default"].createElement("option", {
55
64
  disabled: true,
56
65
  value: ""
57
- }, "Please select a province"), provinces.map(function (_ref2) {
66
+ }, "Please select a ", defaultLabel.toLowerCase()), regions.map(function (_ref2) {
58
67
  var code = _ref2.code,
59
68
  name = _ref2.name;
60
69
  return /*#__PURE__*/_react["default"].createElement("option", {
@@ -63,18 +72,17 @@ function Province(_ref) {
63
72
  }, name);
64
73
  })), /*#__PURE__*/_react["default"].createElement("span", {
65
74
  className: "o-forms-input__error"
66
- }, "Please select your province.")));
75
+ }, "Please select your ", defaultLabel.toLowerCase())));
67
76
  }
68
- Province.propTypes = {
69
- value: _propTypes["default"].string,
77
+ RegionSelector.propTypes = {
78
+ country: _propTypes["default"].oneOf(['USA', 'CAN', 'IND']),
70
79
  fieldId: _propTypes["default"].string,
71
- selectId: _propTypes["default"].string,
72
80
  hasError: _propTypes["default"].bool,
73
- isHidden: _propTypes["default"].bool,
74
- isBillingProvince: _propTypes["default"].bool,
81
+ isBillingSelector: _propTypes["default"].bool,
75
82
  isDisabled: _propTypes["default"].bool,
76
- provinces: _propTypes["default"].arrayOf(_propTypes["default"].shape({
77
- code: _propTypes["default"].string,
78
- name: _propTypes["default"].string
79
- }))
83
+ isHidden: _propTypes["default"].bool,
84
+ label: _propTypes["default"].string,
85
+ regionType: _propTypes["default"].string,
86
+ selectId: _propTypes["default"].string,
87
+ value: _propTypes["default"].string
80
88
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@financial-times/n-conversion-forms",
3
- "version": "40.0.2",
3
+ "version": "41.0.0",
4
4
  "description": "Containing jsx components and styles for forms included on Accounts and Acquisition apps (next-signup, next-profile, next-retention, etc).",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -30,7 +30,7 @@
30
30
  "classnames": "2.5.1",
31
31
  "fetchres": "1.7.2",
32
32
  "lodash.get": "4.4.2",
33
- "n-common-static-data": "github:Financial-Times/n-common-static-data#v3.0.0"
33
+ "n-common-static-data": "github:Financial-Times/n-common-static-data#v3.1.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@babel/core": "^7.23.9",
@@ -0,0 +1,54 @@
1
+ import {
2
+ americanStates,
3
+ canadianProvinces,
4
+ indianStatesAndUnionTerritories,
5
+ } from 'n-common-static-data';
6
+ import FormElement from './form-element';
7
+
8
+ export const configByCountry = {
9
+ USA: {
10
+ regions: americanStates.states,
11
+ defaultRegionType: 'state',
12
+ label: 'State',
13
+ },
14
+ CAN: {
15
+ regions: canadianProvinces.provinces,
16
+ defaultRegionType: 'province',
17
+ label: 'Province',
18
+ },
19
+ IND: {
20
+ regions: indianStatesAndUnionTerritories.states,
21
+ defaultRegionType: 'state',
22
+ label: 'State/Union Territory',
23
+ },
24
+ };
25
+
26
+ /**
27
+ * Class representing a region selector form element.
28
+ * @extends FormElement
29
+ */
30
+ class RegionSelector extends FormElement {
31
+ /**
32
+ * Create a region selector.
33
+ *
34
+ * @param {Document} document - The document object.
35
+ * @param {Object} [options] - Options for the region selector.
36
+ * @param {string} [options.country='USA'] - The country code (e.g., 'USA', 'CAN', 'IND'). Defaults to 'USA'.
37
+ * @param {string} [options.regionType] - The type of region (e.g., 'state', 'province'). Defaults to the default region type for the country.
38
+ * @param {string} [options.fieldId] - The ID of the field element. Defaults to the default field ID for the region type.
39
+ *
40
+ * @note Ensure that the `country`, `regionType` and `fieldId` used here matches what is used in the props for the `RegionSelector` component.
41
+ */
42
+ constructor(document, { country = 'USA', regionType, fieldId } = {}) {
43
+ const defaultRegionType =
44
+ regionType || configByCountry[country].defaultRegionType;
45
+
46
+ const selector = fieldId
47
+ ? `.ncf #${fieldId}`
48
+ : `.ncf #${defaultRegionType}Field`;
49
+
50
+ super(document, selector);
51
+ }
52
+ }
53
+
54
+ export default RegionSelector;