@pingux/astro 2.208.4-alpha.0 → 2.209.0-alpha.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/lib/cjs/components/PhoneNumberField/PhoneNumberField.d.ts +4 -0
- package/lib/cjs/components/PhoneNumberField/PhoneNumberField.js +299 -0
- package/lib/cjs/components/PhoneNumberField/PhoneNumberField.mdx +32 -0
- package/lib/cjs/components/PhoneNumberField/PhoneNumberField.stories.js +136 -0
- package/lib/cjs/components/PhoneNumberField/PhoneNumberField.test.js +158 -0
- package/lib/cjs/components/PhoneNumberField/index.d.ts +1 -0
- package/lib/cjs/components/PhoneNumberField/index.js +14 -0
- package/lib/cjs/index.d.ts +2 -0
- package/lib/cjs/index.js +56 -37
- package/lib/cjs/styles/themes/next-gen/convertedComponentList.js +1 -1
- package/lib/cjs/types/index.d.ts +1 -0
- package/lib/cjs/types/index.js +32 -21
- package/lib/cjs/types/phoneNumberField.d.ts +45 -0
- package/lib/cjs/types/phoneNumberField.js +6 -0
- package/lib/cjs/utils/designUtils/figmaLinks.d.ts +3 -0
- package/lib/cjs/utils/designUtils/figmaLinks.js +3 -0
- package/lib/cjs/utils/testUtils/universalFormSubmitTest.js +25 -11
- package/lib/components/PhoneNumberField/PhoneNumberField.js +288 -0
- package/lib/components/PhoneNumberField/PhoneNumberField.mdx +32 -0
- package/lib/components/PhoneNumberField/PhoneNumberField.stories.js +126 -0
- package/lib/components/PhoneNumberField/PhoneNumberField.test.js +155 -0
- package/lib/components/PhoneNumberField/index.js +1 -0
- package/lib/index.js +2 -0
- package/lib/styles/themes/next-gen/convertedComponentList.js +1 -1
- package/lib/types/index.js +1 -0
- package/lib/types/phoneNumberField.js +1 -0
- package/lib/utils/designUtils/figmaLinks.js +3 -0
- package/lib/utils/testUtils/universalFormSubmitTest.js +25 -11
- package/package.json +1 -1
|
@@ -170,6 +170,9 @@ var FIGMA_LINKS = exports.FIGMA_LINKS = {
|
|
|
170
170
|
withAvatar: 'https://www.figma.com/design/XDGxYAgQkcHDVjyu8OGrBv/Onyx-Specs?node-id=4470-24174&m=dev',
|
|
171
171
|
withExtraLongText: 'https://www.figma.com/file/bpbEw54gTTcdIiZs4PKK1p/Astro-Specs?node-id=44688%3A39713&mode=dev'
|
|
172
172
|
},
|
|
173
|
+
phoneNumberField: {
|
|
174
|
+
"default": 'https://www.figma.com/design/XDGxYAgQkcHDVjyu8OGrBv/Onyx-Specs?node-id=8496-31873'
|
|
175
|
+
},
|
|
173
176
|
popoverMenu: {
|
|
174
177
|
"default": 'https://www.figma.com/file/Oa6VYtJcUJzEJuuRp0p4ls/Astro?type=design&node-id=0%3A3073&t=We3h7LaaFJQnxdSy-1'
|
|
175
178
|
},
|
|
@@ -139,6 +139,7 @@ var useDefaultProps = function useDefaultProps(componentType) {
|
|
|
139
139
|
name: name
|
|
140
140
|
};
|
|
141
141
|
case 'PasswordField':
|
|
142
|
+
case 'PhoneNumberField':
|
|
142
143
|
return {
|
|
143
144
|
value: value,
|
|
144
145
|
onChange: function onChange(e) {
|
|
@@ -215,6 +216,7 @@ var getDefaultProps = function getDefaultProps(componentType, testValue) {
|
|
|
215
216
|
name: name
|
|
216
217
|
};
|
|
217
218
|
case 'PasswordField':
|
|
219
|
+
case 'PhoneNumberField':
|
|
218
220
|
case 'ComboBoxField':
|
|
219
221
|
case 'NumberField':
|
|
220
222
|
case 'MultivaluesField':
|
|
@@ -409,7 +411,7 @@ var universalFieldComponentTests = exports.universalFieldComponentTests = functi
|
|
|
409
411
|
_react2.fireEvent.click(_react2.screen.getAllByRole('option', {
|
|
410
412
|
name: testValue
|
|
411
413
|
})[0]);
|
|
412
|
-
_context2.next =
|
|
414
|
+
_context2.next = 45;
|
|
413
415
|
break;
|
|
414
416
|
case 19:
|
|
415
417
|
if (!(componentType === 'NumberField')) {
|
|
@@ -421,7 +423,7 @@ var universalFieldComponentTests = exports.universalFieldComponentTests = functi
|
|
|
421
423
|
value: testValue
|
|
422
424
|
}
|
|
423
425
|
});
|
|
424
|
-
_context2.next =
|
|
426
|
+
_context2.next = 45;
|
|
425
427
|
break;
|
|
426
428
|
case 23:
|
|
427
429
|
if (!(componentType === 'RadioGroupField')) {
|
|
@@ -429,7 +431,7 @@ var universalFieldComponentTests = exports.universalFieldComponentTests = functi
|
|
|
429
431
|
break;
|
|
430
432
|
}
|
|
431
433
|
_react2.fireEvent.click(_react2.screen.getByLabelText(testValue));
|
|
432
|
-
_context2.next =
|
|
434
|
+
_context2.next = 45;
|
|
433
435
|
break;
|
|
434
436
|
case 27:
|
|
435
437
|
if (!(componentType === 'PasswordField')) {
|
|
@@ -441,25 +443,37 @@ var universalFieldComponentTests = exports.universalFieldComponentTests = functi
|
|
|
441
443
|
value: testValue
|
|
442
444
|
}
|
|
443
445
|
});
|
|
444
|
-
_context2.next =
|
|
446
|
+
_context2.next = 45;
|
|
445
447
|
break;
|
|
446
448
|
case 31:
|
|
449
|
+
if (!(componentType === 'PhoneNumberField')) {
|
|
450
|
+
_context2.next = 35;
|
|
451
|
+
break;
|
|
452
|
+
}
|
|
453
|
+
_react2.fireEvent.change(_react2.screen.getByRole('textbox'), {
|
|
454
|
+
target: {
|
|
455
|
+
value: testValue
|
|
456
|
+
}
|
|
457
|
+
});
|
|
458
|
+
_context2.next = 45;
|
|
459
|
+
break;
|
|
460
|
+
case 35:
|
|
447
461
|
if (!(componentType === 'DatePicker')) {
|
|
448
|
-
_context2.next =
|
|
462
|
+
_context2.next = 44;
|
|
449
463
|
break;
|
|
450
464
|
}
|
|
451
465
|
iconButton = _react2.screen.queryAllByRole('button');
|
|
452
|
-
_context2.next =
|
|
466
|
+
_context2.next = 39;
|
|
453
467
|
return _userEvent["default"].click(iconButton[0]);
|
|
454
|
-
case
|
|
468
|
+
case 39:
|
|
455
469
|
cells = _react2.screen.getAllByRole('gridcell');
|
|
456
470
|
selected = (0, _find["default"])(cells).call(cells, function (cell) {
|
|
457
471
|
return cell.getAttribute('aria-selected') === 'true';
|
|
458
472
|
});
|
|
459
473
|
expect(selected === null || selected === void 0 ? void 0 : selected.children[0]).toHaveAttribute('aria-label', 'Wednesday, August 10, 2022 selected');
|
|
460
|
-
_context2.next =
|
|
474
|
+
_context2.next = 45;
|
|
461
475
|
break;
|
|
462
|
-
case
|
|
476
|
+
case 44:
|
|
463
477
|
if (componentType === 'SliderField') {
|
|
464
478
|
_react2.fireEvent.change(_react2.screen.getByRole('slider'), {
|
|
465
479
|
target: {
|
|
@@ -473,7 +487,7 @@ var universalFieldComponentTests = exports.universalFieldComponentTests = functi
|
|
|
473
487
|
}
|
|
474
488
|
});
|
|
475
489
|
}
|
|
476
|
-
case
|
|
490
|
+
case 45:
|
|
477
491
|
_react2.fireEvent.submit(_react2.screen.getByRole('form', {
|
|
478
492
|
hidden: true,
|
|
479
493
|
name: /test form 2/i
|
|
@@ -481,7 +495,7 @@ var universalFieldComponentTests = exports.universalFieldComponentTests = functi
|
|
|
481
495
|
expect(handleFormSubmit).toHaveBeenCalledWith({
|
|
482
496
|
testName: String(testValue)
|
|
483
497
|
});
|
|
484
|
-
case
|
|
498
|
+
case 47:
|
|
485
499
|
case "end":
|
|
486
500
|
return _context2.stop();
|
|
487
501
|
}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
|
|
2
|
+
import _defineProperty from "@babel/runtime-corejs3/helpers/esm/defineProperty";
|
|
3
|
+
import _objectWithoutProperties from "@babel/runtime-corejs3/helpers/esm/objectWithoutProperties";
|
|
4
|
+
import _slicedToArray from "@babel/runtime-corejs3/helpers/esm/slicedToArray";
|
|
5
|
+
var _excluded = ["countryValue", "defaultCountryValue", "helperText", "isReadOnly", "labelMode", "onCountryChange", "status"];
|
|
6
|
+
function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
7
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context6, _context7; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context6 = ownKeys(Object(t), !0)).call(_context6, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context7 = ownKeys(Object(t))).call(_context7, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
8
|
+
import _Object$entries from "@babel/runtime-corejs3/core-js-stable/object/entries";
|
|
9
|
+
import _startsWithInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/starts-with";
|
|
10
|
+
import _trimStartInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/trim-start";
|
|
11
|
+
import _findInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/find";
|
|
12
|
+
import _sliceInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/slice";
|
|
13
|
+
import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter";
|
|
14
|
+
import _concatInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/concat";
|
|
15
|
+
import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
|
|
16
|
+
import _Object$keys from "@babel/runtime-corejs3/core-js-stable/object/keys";
|
|
17
|
+
import _Object$getOwnPropertySymbols from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols";
|
|
18
|
+
import _Object$getOwnPropertyDescriptor from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor";
|
|
19
|
+
import _forEachInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/for-each";
|
|
20
|
+
import _Object$getOwnPropertyDescriptors from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors";
|
|
21
|
+
import _Object$defineProperties from "@babel/runtime-corejs3/core-js-stable/object/define-properties";
|
|
22
|
+
import _Object$defineProperty from "@babel/runtime-corejs3/core-js-stable/object/define-property";
|
|
23
|
+
import React, { forwardRef, useCallback, useState } from 'react';
|
|
24
|
+
import { useFilter } from '@react-aria/i18n';
|
|
25
|
+
import { countries as countriesObj } from 'countries-list';
|
|
26
|
+
import { v4 as uuid } from 'uuid';
|
|
27
|
+
import { Box, ComboBoxField, FieldHelperText, Input, Item, Label } from '../..';
|
|
28
|
+
import { useField, useLocalOrForwardRef, usePropWarning } from '../../hooks';
|
|
29
|
+
import { getPendoID } from '../../utils/devUtils/constants/pendoID';
|
|
30
|
+
import { jsx as ___EmotionJSX } from "@emotion/react";
|
|
31
|
+
var displayName = 'PhoneNumberField';
|
|
32
|
+
var validatePhoneNumber = function validatePhoneNumber(str) {
|
|
33
|
+
return /^$|^\+\d*$|^\d+$/.test(str);
|
|
34
|
+
};
|
|
35
|
+
var allCountries = _Object$entries(countriesObj);
|
|
36
|
+
var getCountry = function getCountry(key) {
|
|
37
|
+
return countriesObj[key];
|
|
38
|
+
};
|
|
39
|
+
var primaryDial = function primaryDial(key) {
|
|
40
|
+
var _getCountry$phone$spl, _getCountry;
|
|
41
|
+
return (_getCountry$phone$spl = (_getCountry = getCountry(key)) === null || _getCountry === void 0 ? void 0 : _getCountry.phone.split(',')[0]) !== null && _getCountry$phone$spl !== void 0 ? _getCountry$phone$spl : '';
|
|
42
|
+
};
|
|
43
|
+
var toDialCode = function toDialCode(key) {
|
|
44
|
+
var dial = primaryDial(key);
|
|
45
|
+
return dial ? "+".concat(dial) : '';
|
|
46
|
+
};
|
|
47
|
+
var parsePaste = function parsePaste(raw) {
|
|
48
|
+
var _context;
|
|
49
|
+
var digitsOnly = raw.replace(/\D/g, '');
|
|
50
|
+
if (_startsWithInstanceProperty(_context = _trimStartInstanceProperty(raw).call(raw)).call(_context, '+')) {
|
|
51
|
+
var match = _findInstanceProperty(allCountries).call(allCountries, function (_ref) {
|
|
52
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
53
|
+
c = _ref2[1];
|
|
54
|
+
return _startsWithInstanceProperty(digitsOnly).call(digitsOnly, c.phone.split(',')[0]);
|
|
55
|
+
});
|
|
56
|
+
if (match) {
|
|
57
|
+
var dialLen = match[1].phone.split(',')[0].length;
|
|
58
|
+
return {
|
|
59
|
+
countryKey: match[0],
|
|
60
|
+
localNumber: _sliceInstanceProperty(digitsOnly).call(digitsOnly, dialLen)
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
countryKey: null,
|
|
66
|
+
localNumber: digitsOnly
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
var closedState = function closedState(selectedKey) {
|
|
70
|
+
var dialCode = selectedKey ? toDialCode(selectedKey) : '';
|
|
71
|
+
return {
|
|
72
|
+
isOpen: false,
|
|
73
|
+
inputValue: dialCode,
|
|
74
|
+
searchValue: dialCode,
|
|
75
|
+
items: allCountries
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
var PhoneNumberField = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
79
|
+
var countryValue = props.countryValue,
|
|
80
|
+
defaultCountryValue = props.defaultCountryValue,
|
|
81
|
+
helperText = props.helperText,
|
|
82
|
+
isReadOnly = props.isReadOnly,
|
|
83
|
+
labelMode = props.labelMode,
|
|
84
|
+
onCountryChange = props.onCountryChange,
|
|
85
|
+
status = props.status,
|
|
86
|
+
others = _objectWithoutProperties(props, _excluded);
|
|
87
|
+
var _useField = useField(_objectSpread({
|
|
88
|
+
status: status,
|
|
89
|
+
isReadOnly: isReadOnly,
|
|
90
|
+
labelMode: labelMode
|
|
91
|
+
}, others)),
|
|
92
|
+
fieldContainerProps = _useField.fieldContainerProps,
|
|
93
|
+
fieldControlInputProps = _useField.fieldControlInputProps,
|
|
94
|
+
fieldControlWrapperProps = _useField.fieldControlWrapperProps,
|
|
95
|
+
fieldLabelProps = _useField.fieldLabelProps;
|
|
96
|
+
var onChange = fieldControlInputProps.onChange;
|
|
97
|
+
var inputRef = useLocalOrForwardRef(ref);
|
|
98
|
+
var helperTextId = uuid();
|
|
99
|
+
usePropWarning(props, 'disabled', 'isDisabled');
|
|
100
|
+
var _useFilter = useFilter({
|
|
101
|
+
sensitivity: 'base'
|
|
102
|
+
}),
|
|
103
|
+
contains = _useFilter.contains;
|
|
104
|
+
var _useState = useState(function () {
|
|
105
|
+
var key = countryValue !== null && countryValue !== void 0 ? countryValue : defaultCountryValue;
|
|
106
|
+
if (key && getCountry(key)) {
|
|
107
|
+
var dialCode = toDialCode(key);
|
|
108
|
+
return {
|
|
109
|
+
inputValue: dialCode,
|
|
110
|
+
selectedKey: key,
|
|
111
|
+
searchValue: dialCode,
|
|
112
|
+
items: allCountries,
|
|
113
|
+
isOpen: false
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
inputValue: '',
|
|
118
|
+
selectedKey: null,
|
|
119
|
+
searchValue: '',
|
|
120
|
+
items: allCountries,
|
|
121
|
+
isOpen: false
|
|
122
|
+
};
|
|
123
|
+
}),
|
|
124
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
125
|
+
fieldState = _useState2[0],
|
|
126
|
+
setFieldState = _useState2[1];
|
|
127
|
+
var isControlledCountry = countryValue !== undefined;
|
|
128
|
+
var currentSelectedKey = isControlledCountry ? countryValue !== null && countryValue !== void 0 ? countryValue : null : fieldState.selectedKey;
|
|
129
|
+
var closedDisplayValue = isControlledCountry ? toDialCode(countryValue !== null && countryValue !== void 0 ? countryValue : '') : fieldState.inputValue;
|
|
130
|
+
var currentCountryInputValue = fieldState.isOpen ? fieldState.searchValue : closedDisplayValue;
|
|
131
|
+
var inputHandler = useCallback(function (value) {
|
|
132
|
+
var search = value.toLowerCase();
|
|
133
|
+
var newItems = value ? _filterInstanceProperty(allCountries).call(allCountries, function (_ref3) {
|
|
134
|
+
var _context2;
|
|
135
|
+
var _ref4 = _slicedToArray(_ref3, 2),
|
|
136
|
+
c = _ref4[1];
|
|
137
|
+
var nameStr = _concatInstanceProperty(_context2 = "".concat(c.name)).call(_context2, c.name !== c["native"] ? " (".concat(c["native"], ")") : '');
|
|
138
|
+
var dialStr = "+".concat(c.phone.split(',')[0]).toLowerCase();
|
|
139
|
+
return contains(nameStr, value) || _includesInstanceProperty(dialStr).call(dialStr, search);
|
|
140
|
+
}) : allCountries;
|
|
141
|
+
setFieldState(function (prev) {
|
|
142
|
+
return _objectSpread(_objectSpread({}, prev), {}, {
|
|
143
|
+
inputValue: value,
|
|
144
|
+
selectedKey: null,
|
|
145
|
+
searchValue: value,
|
|
146
|
+
items: newItems
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
}, [contains]);
|
|
150
|
+
var selectionHandler = useCallback(function (key) {
|
|
151
|
+
if (!key) return;
|
|
152
|
+
var dialCode = toDialCode(key);
|
|
153
|
+
setFieldState({
|
|
154
|
+
inputValue: dialCode,
|
|
155
|
+
selectedKey: key,
|
|
156
|
+
searchValue: dialCode,
|
|
157
|
+
items: allCountries,
|
|
158
|
+
isOpen: false
|
|
159
|
+
});
|
|
160
|
+
if (onCountryChange) onCountryChange(key);
|
|
161
|
+
}, [onCountryChange]);
|
|
162
|
+
var onOpenChangeHandler = useCallback(function (open) {
|
|
163
|
+
if (!open || isReadOnly) {
|
|
164
|
+
setFieldState(function (prev) {
|
|
165
|
+
return _objectSpread(_objectSpread({}, prev), closedState(prev.selectedKey));
|
|
166
|
+
});
|
|
167
|
+
} else {
|
|
168
|
+
setFieldState(function (prev) {
|
|
169
|
+
return _objectSpread(_objectSpread({}, prev), {}, {
|
|
170
|
+
isOpen: true,
|
|
171
|
+
items: allCountries
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}, [isReadOnly]);
|
|
176
|
+
var handlePhoneChange = useCallback(function (e) {
|
|
177
|
+
if (!onChange) return;
|
|
178
|
+
if (validatePhoneNumber(e.target.value)) {
|
|
179
|
+
onChange(e);
|
|
180
|
+
} else if (inputRef.current) {
|
|
181
|
+
inputRef.current.value = '';
|
|
182
|
+
}
|
|
183
|
+
}, [inputRef, onChange]);
|
|
184
|
+
var commitPaste = useCallback(function (raw) {
|
|
185
|
+
if (!inputRef.current || !onChange) return;
|
|
186
|
+
var _parsePaste = parsePaste(raw),
|
|
187
|
+
countryKey = _parsePaste.countryKey,
|
|
188
|
+
localNumber = _parsePaste.localNumber;
|
|
189
|
+
if (countryKey) selectionHandler(countryKey);
|
|
190
|
+
inputRef.current.value = localNumber;
|
|
191
|
+
var event = {
|
|
192
|
+
target: inputRef.current,
|
|
193
|
+
currentTarget: inputRef.current
|
|
194
|
+
};
|
|
195
|
+
onChange(event);
|
|
196
|
+
}, [inputRef, onChange, selectionHandler]);
|
|
197
|
+
var handlePhonePaste = useCallback(function (e) {
|
|
198
|
+
if (isReadOnly) return;
|
|
199
|
+
e.preventDefault();
|
|
200
|
+
commitPaste(e.clipboardData.getData('text'));
|
|
201
|
+
}, [isReadOnly, commitPaste]);
|
|
202
|
+
var handleComboBoxPaste = useCallback(function (e) {
|
|
203
|
+
var _context3;
|
|
204
|
+
if (isReadOnly) return;
|
|
205
|
+
var raw = e.clipboardData.getData('text');
|
|
206
|
+
if (!_startsWithInstanceProperty(_context3 = _trimStartInstanceProperty(raw).call(raw)).call(_context3, '+')) return;
|
|
207
|
+
e.preventDefault();
|
|
208
|
+
commitPaste(raw);
|
|
209
|
+
}, [isReadOnly, commitPaste]);
|
|
210
|
+
var comboBoxWrapperSx = _objectSpread({
|
|
211
|
+
position: 'absolute',
|
|
212
|
+
zIndex: 1
|
|
213
|
+
}, fieldState.isOpen ? {
|
|
214
|
+
width: '100%'
|
|
215
|
+
} : {
|
|
216
|
+
transition: '0.2s width ease',
|
|
217
|
+
width: '110px'
|
|
218
|
+
});
|
|
219
|
+
var countryLabel = function countryLabel(c) {
|
|
220
|
+
var _context4, _context5;
|
|
221
|
+
return _concatInstanceProperty(_context4 = _concatInstanceProperty(_context5 = "".concat(c.name)).call(_context5, c.name !== c["native"] ? " (".concat(c["native"], ")") : '', " +")).call(_context4, c.phone.split(',')[0]);
|
|
222
|
+
};
|
|
223
|
+
return ___EmotionJSX(Box, _extends({
|
|
224
|
+
variant: "forms.input.fieldContainer"
|
|
225
|
+
}, getPendoID(displayName), fieldContainerProps), ___EmotionJSX(Label, fieldLabelProps), ___EmotionJSX(Box, _extends({
|
|
226
|
+
variant: "forms.input.fieldControlWrapper",
|
|
227
|
+
isRow: true
|
|
228
|
+
}, fieldControlWrapperProps, {
|
|
229
|
+
sx: {
|
|
230
|
+
position: 'relative'
|
|
231
|
+
}
|
|
232
|
+
}), ___EmotionJSX(ComboBoxField, {
|
|
233
|
+
width: "100%",
|
|
234
|
+
status: status,
|
|
235
|
+
isReadOnly: isReadOnly,
|
|
236
|
+
isOpen: fieldState.isOpen,
|
|
237
|
+
onOpenChange: onOpenChangeHandler,
|
|
238
|
+
wrapperProps: {
|
|
239
|
+
sx: comboBoxWrapperSx
|
|
240
|
+
},
|
|
241
|
+
controlProps: {
|
|
242
|
+
'aria-label': 'Country Picker',
|
|
243
|
+
onPaste: handleComboBoxPaste
|
|
244
|
+
},
|
|
245
|
+
containerProps: {
|
|
246
|
+
sx: {
|
|
247
|
+
'> label': {
|
|
248
|
+
mb: 0
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
scrollBoxProps: {
|
|
253
|
+
maxHeight: '215px',
|
|
254
|
+
sx: {
|
|
255
|
+
minWidth: '280px'
|
|
256
|
+
}
|
|
257
|
+
},
|
|
258
|
+
items: fieldState.items,
|
|
259
|
+
inputValue: currentCountryInputValue,
|
|
260
|
+
selectedKey: currentSelectedKey,
|
|
261
|
+
onInputChange: inputHandler,
|
|
262
|
+
onSelectionChange: selectionHandler,
|
|
263
|
+
menuTrigger: "focus",
|
|
264
|
+
isDisabled: fieldControlInputProps.disabled
|
|
265
|
+
}, function (item) {
|
|
266
|
+
return ___EmotionJSX(Item, {
|
|
267
|
+
key: item[0],
|
|
268
|
+
textValue: "+".concat(item[1].phone.split(',')[0])
|
|
269
|
+
}, countryLabel(item[1]));
|
|
270
|
+
}), ___EmotionJSX(Box, {
|
|
271
|
+
sx: {
|
|
272
|
+
ml: '110px',
|
|
273
|
+
width: '100%',
|
|
274
|
+
visibility: fieldState.isOpen ? 'hidden' : undefined
|
|
275
|
+
}
|
|
276
|
+
}, ___EmotionJSX(Input, _extends({
|
|
277
|
+
ref: inputRef
|
|
278
|
+
}, fieldControlInputProps, {
|
|
279
|
+
"aria-describedby": [helperText && helperTextId, fieldControlInputProps['aria-describedby']].join(fieldControlInputProps['aria-describedby'] ? ' ' : '') || undefined,
|
|
280
|
+
onChange: handlePhoneChange,
|
|
281
|
+
onPaste: handlePhonePaste
|
|
282
|
+
})))), helperText && ___EmotionJSX(FieldHelperText, {
|
|
283
|
+
status: status,
|
|
284
|
+
id: helperTextId
|
|
285
|
+
}, helperText));
|
|
286
|
+
});
|
|
287
|
+
PhoneNumberField.displayName = displayName;
|
|
288
|
+
export default PhoneNumberField;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Meta } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import * as PhoneNumberFieldStories from './PhoneNumberField.stories';
|
|
3
|
+
import AccessibilityTable from '../../utils/docUtils/AccessibilityTable';
|
|
4
|
+
import { KeyboardRows } from '../../utils/docUtils/accessibilityTableConstants';
|
|
5
|
+
|
|
6
|
+
<Meta of={PhoneNumberFieldStories} isTemplate />
|
|
7
|
+
|
|
8
|
+
# PhoneNumberField
|
|
9
|
+
|
|
10
|
+
The PhoneNumberField component combines a country selector with a phone number input, providing a complete, form-ready solution for collecting international phone numbers. The country selector is an accessible combo box that filters all countries from the `countries-list` package, and the phone input validates that only numeric characters (with an optional leading `+`) are entered.
|
|
11
|
+
|
|
12
|
+
### Required components
|
|
13
|
+
|
|
14
|
+
This component requires the following dependency to be present in the project:
|
|
15
|
+
|
|
16
|
+
- **`countries-list ^2.6.1`** — provides the full list of countries and their dial codes used to populate the country selector dropdown.
|
|
17
|
+
|
|
18
|
+
The `ComboBoxField` component (from the Astro design system) is used internally for the country selector. No additional external setup is needed beyond having `countries-list` installed.
|
|
19
|
+
|
|
20
|
+
### Accessibility
|
|
21
|
+
|
|
22
|
+
<AccessibilityTable keyboardRows={[
|
|
23
|
+
{ key: 'Tab', description: 'Moves focus between the country selector trigger and the phone number input, following the page tab sequence.' },
|
|
24
|
+
KeyboardRows.shiftTabFocusPrevious,
|
|
25
|
+
{ key: 'Arrow Down / Arrow Up', description: 'When the country selector dropdown is open, moves focus through the list of countries.' },
|
|
26
|
+
{ key: 'Enter', description: 'Selects the currently focused country in the dropdown and closes the selector.' },
|
|
27
|
+
{ key: 'Escape', description: 'Closes the country selector dropdown without changing the selection.' },
|
|
28
|
+
]} screenReaderRows={[
|
|
29
|
+
'The phone number input uses the **`aria-labelledby`** attribute to reference the field label ID, associating the visible label with the input.',
|
|
30
|
+
'The country selector combo box uses the **`aria-label`** attribute (value: `"Country Picker"`) to provide an accessible name for the combo box trigger, since its visible content is the dial code rather than a descriptive label.',
|
|
31
|
+
'The **`aria-invalid`** attribute is set on the phone input when the field has an error status.',
|
|
32
|
+
]} />
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import _Object$keys from "@babel/runtime-corejs3/core-js-stable/object/keys";
|
|
2
|
+
import _Object$getOwnPropertySymbols from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols";
|
|
3
|
+
import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter";
|
|
4
|
+
import _Object$getOwnPropertyDescriptor from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor";
|
|
5
|
+
import _forEachInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/for-each";
|
|
6
|
+
import _Object$getOwnPropertyDescriptors from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors";
|
|
7
|
+
import _Object$defineProperties from "@babel/runtime-corejs3/core-js-stable/object/define-properties";
|
|
8
|
+
import _Object$defineProperty from "@babel/runtime-corejs3/core-js-stable/object/define-property";
|
|
9
|
+
import _slicedToArray from "@babel/runtime-corejs3/helpers/esm/slicedToArray";
|
|
10
|
+
import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
|
|
11
|
+
import _defineProperty from "@babel/runtime-corejs3/helpers/esm/defineProperty";
|
|
12
|
+
function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
13
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context, _context2; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context = ownKeys(Object(t), !0)).call(_context, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context2 = ownKeys(Object(t))).call(_context2, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
14
|
+
import React, { useState } from 'react';
|
|
15
|
+
import DocsLayout from '../../../.storybook/storybookDocsLayout';
|
|
16
|
+
import { PhoneNumberField } from '../../index';
|
|
17
|
+
import { FIGMA_LINKS } from '../../utils/designUtils/figmaLinks';
|
|
18
|
+
import { ariaAttributeBaseArgTypes } from '../../utils/docUtils/ariaAttributes';
|
|
19
|
+
import { inputFieldAttributeBaseArgTypes } from '../../utils/docUtils/fieldAttributes';
|
|
20
|
+
import { statusArgTypes } from '../../utils/docUtils/statusProp';
|
|
21
|
+
import PhoneNumberFieldReadme from './PhoneNumberField.mdx';
|
|
22
|
+
import { jsx as ___EmotionJSX } from "@emotion/react";
|
|
23
|
+
export default {
|
|
24
|
+
title: 'Form/PhoneNumberField',
|
|
25
|
+
component: PhoneNumberField,
|
|
26
|
+
parameters: {
|
|
27
|
+
docs: {
|
|
28
|
+
page: function page() {
|
|
29
|
+
return ___EmotionJSX(React.Fragment, null, ___EmotionJSX(PhoneNumberFieldReadme, null), ___EmotionJSX(DocsLayout, null));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
argTypes: _objectSpread(_objectSpread(_objectSpread({}, statusArgTypes), ariaAttributeBaseArgTypes), inputFieldAttributeBaseArgTypes)
|
|
34
|
+
};
|
|
35
|
+
export var Default = function Default(args) {
|
|
36
|
+
return ___EmotionJSX(PhoneNumberField, _extends({
|
|
37
|
+
label: "Phone Number"
|
|
38
|
+
}, args));
|
|
39
|
+
};
|
|
40
|
+
Default.parameters = {
|
|
41
|
+
design: {
|
|
42
|
+
type: 'figma',
|
|
43
|
+
url: FIGMA_LINKS.phoneNumberField["default"]
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
export var Controlled = function Controlled() {
|
|
47
|
+
var _useState = useState(''),
|
|
48
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
49
|
+
value = _useState2[0],
|
|
50
|
+
setValue = _useState2[1];
|
|
51
|
+
var _useState3 = useState(undefined),
|
|
52
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
53
|
+
countryValue = _useState4[0],
|
|
54
|
+
setCountryValue = _useState4[1];
|
|
55
|
+
return ___EmotionJSX(PhoneNumberField, {
|
|
56
|
+
label: "Phone Number",
|
|
57
|
+
value: value,
|
|
58
|
+
onChange: function onChange(e) {
|
|
59
|
+
return setValue(e.target.value);
|
|
60
|
+
},
|
|
61
|
+
countryValue: countryValue,
|
|
62
|
+
onCountryChange: function onCountryChange(key) {
|
|
63
|
+
return setCountryValue(key);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
export var Disabled = function Disabled(args) {
|
|
68
|
+
return ___EmotionJSX(PhoneNumberField, _extends({
|
|
69
|
+
label: "Phone Number",
|
|
70
|
+
isDisabled: true
|
|
71
|
+
}, args));
|
|
72
|
+
};
|
|
73
|
+
export var ReadOnly = function ReadOnly(args) {
|
|
74
|
+
return ___EmotionJSX(PhoneNumberField, _extends({
|
|
75
|
+
label: "Phone Number",
|
|
76
|
+
isReadOnly: true,
|
|
77
|
+
defaultCountryValue: "US",
|
|
78
|
+
value: "2025550177"
|
|
79
|
+
}, args));
|
|
80
|
+
};
|
|
81
|
+
export var Required = function Required(args) {
|
|
82
|
+
return ___EmotionJSX(PhoneNumberField, _extends({
|
|
83
|
+
label: "Phone Number",
|
|
84
|
+
isRequired: true
|
|
85
|
+
}, args));
|
|
86
|
+
};
|
|
87
|
+
export var Error = function Error(args) {
|
|
88
|
+
return ___EmotionJSX(PhoneNumberField, _extends({
|
|
89
|
+
label: "Phone Number",
|
|
90
|
+
status: "error",
|
|
91
|
+
helperText: "Please enter a valid phone number."
|
|
92
|
+
}, args));
|
|
93
|
+
};
|
|
94
|
+
export var Warning = function Warning(args) {
|
|
95
|
+
return ___EmotionJSX(PhoneNumberField, _extends({
|
|
96
|
+
label: "Phone Number",
|
|
97
|
+
status: "warning",
|
|
98
|
+
helperText: "Double-check the country code."
|
|
99
|
+
}, args));
|
|
100
|
+
};
|
|
101
|
+
Warning.parameters = {
|
|
102
|
+
a11y: {
|
|
103
|
+
config: {
|
|
104
|
+
rules: [{
|
|
105
|
+
id: 'color-contrast',
|
|
106
|
+
enabled: false
|
|
107
|
+
}]
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
export var Success = function Success(args) {
|
|
112
|
+
return ___EmotionJSX(PhoneNumberField, _extends({
|
|
113
|
+
label: "Phone Number",
|
|
114
|
+
status: "success",
|
|
115
|
+
helperText: "Phone number verified."
|
|
116
|
+
}, args));
|
|
117
|
+
};
|
|
118
|
+
export var WithHelpHint = function WithHelpHint(args) {
|
|
119
|
+
return ___EmotionJSX(PhoneNumberField, _extends({
|
|
120
|
+
label: "Phone Number",
|
|
121
|
+
hintText: "Include country code for international numbers.",
|
|
122
|
+
helpHintProps: {
|
|
123
|
+
direction: 'right'
|
|
124
|
+
}
|
|
125
|
+
}, args));
|
|
126
|
+
};
|