@hh.ru/magritte-ui-phone-input 1.0.1

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.
@@ -0,0 +1,48 @@
1
+ import './index.css';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { forwardRef, useRef, useState, useEffect } from 'react';
4
+ import classNames from 'classnames';
5
+ import { useBreakpoint } from '@hh.ru/magritte-ui-breakpoint';
6
+
7
+ var styles = {"calling-code-input":"magritte-calling-code-input___Hb20f_1-0-1","callingCodeInput":"magritte-calling-code-input___Hb20f_1-0-1","calling-code-input-container":"magritte-calling-code-input-container___UXmHV_1-0-1","callingCodeInputContainer":"magritte-calling-code-input-container___UXmHV_1-0-1","disabled":"magritte-disabled___fvEeH_1-0-1","focused":"magritte-focused___Ok8x4_1-0-1","invalid":"magritte-invalid___kptbH_1-0-1","ghost-data":"magritte-ghost-data___zShvn_1-0-1","ghostData":"magritte-ghost-data___zShvn_1-0-1","focus-visible":"magritte-focus-visible___kbwmg_1-0-1","focusVisible":"magritte-focus-visible___kbwmg_1-0-1","flag-container":"magritte-flag-container___wsoAd_1-0-1","flagContainer":"magritte-flag-container___wsoAd_1-0-1","input-container":"magritte-input-container___WSSZi_1-0-1","inputContainer":"magritte-input-container___WSSZi_1-0-1","phone-input-container":"magritte-phone-input-container___D587K_1-0-1","phoneInputContainer":"magritte-phone-input-container___D587K_1-0-1","flag-icon":"magritte-flag-icon___teIdY_1-0-1","flagIcon":"magritte-flag-icon___teIdY_1-0-1","flag-emoji":"magritte-flag-emoji___pyJS7_1-0-1","flagEmoji":"magritte-flag-emoji___pyJS7_1-0-1","no-flag-emoji":"magritte-no-flag-emoji___yiuyr_1-0-1","noFlagEmoji":"magritte-no-flag-emoji___yiuyr_1-0-1"};
8
+
9
+ const CallingCodeInput = forwardRef(({ onFocus, onBlur, value, onChange, flag, onKeyDown, invalid, disabled, className }, ref) => {
10
+ const inputRef = useRef(null);
11
+ const [isFocused, setIsFocused] = useState(false);
12
+ const [isFocusVisible, setIsFocusVisible] = useState(false);
13
+ const { isMobile } = useBreakpoint();
14
+ useEffect(() => {
15
+ if (inputRef.current) {
16
+ setIsFocusVisible(isFocused && inputRef.current.classList.contains('focus-visible'));
17
+ }
18
+ }, [isFocused]);
19
+ return (jsxs("div", { className: classNames(styles.callingCodeInputContainer, className, {
20
+ [styles.focusVisible]: isFocusVisible && !disabled,
21
+ [styles.focused]: isFocused && !disabled,
22
+ [styles.invalid]: invalid && !disabled,
23
+ [styles.disabled]: disabled,
24
+ }), tabIndex: 0, onFocus: () => {
25
+ if (!isMobile) {
26
+ inputRef.current?.focus();
27
+ return;
28
+ }
29
+ setIsFocused(true);
30
+ onFocus();
31
+ }, onBlur: () => {
32
+ if (!isMobile) {
33
+ return;
34
+ }
35
+ setIsFocused(false);
36
+ onBlur();
37
+ }, ref: ref, "data-qa": "magritte-phone-input-calling-code", children: [jsx("div", { className: styles.flagContainer, children: flag }), jsxs("div", { className: styles.inputContainer, children: [jsx("input", { ref: inputRef, onFocus: () => {
38
+ setIsFocused(true);
39
+ onFocus();
40
+ }, onBlur: () => {
41
+ setIsFocused(false);
42
+ onBlur();
43
+ }, onKeyDown: onKeyDown, className: styles.callingCodeInput, value: value, onChange: (event) => onChange(event.target.value), disabled: disabled, "data-qa": "magritte-phone-input-calling-code-input" }), jsx("div", { className: styles.ghostData, "data-qa": "magritte-phone-input-calling-code-value", children: value })] })] }));
44
+ });
45
+ CallingCodeInput.displayName = 'CallingCodeInput';
46
+
47
+ export { CallingCodeInput as C, styles as s };
48
+ //# sourceMappingURL=CallingCodeInput-Dv1X6z2c.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CallingCodeInput-Dv1X6z2c.js","sources":["../src/CallingCodeInput.tsx"],"sourcesContent":["import {\n type KeyboardEventHandler,\n type ChangeEvent,\n type ReactNode,\n forwardRef,\n useState,\n useEffect,\n useRef,\n} from 'react';\nimport classnames from 'classnames';\n\nimport { useBreakpoint } from '@hh.ru/magritte-ui-breakpoint';\n\nimport styles from './phoneInput.less';\n\ninterface CallingCodeInputProps {\n flag: ReactNode;\n onChange: (value: string) => void;\n value: string;\n onFocus: VoidFunction;\n onBlur: VoidFunction;\n onKeyDown?: KeyboardEventHandler<HTMLInputElement>;\n invalid?: boolean;\n disabled?: boolean;\n className?: string | boolean;\n}\n\nexport const CallingCodeInput = forwardRef<HTMLDivElement, CallingCodeInputProps>(\n ({ onFocus, onBlur, value, onChange, flag, onKeyDown, invalid, disabled, className }, ref) => {\n const inputRef = useRef<HTMLInputElement>(null);\n const [isFocused, setIsFocused] = useState(false);\n const [isFocusVisible, setIsFocusVisible] = useState(false);\n const { isMobile } = useBreakpoint();\n\n useEffect(() => {\n if (inputRef.current) {\n setIsFocusVisible(isFocused && inputRef.current.classList.contains('focus-visible'));\n }\n }, [isFocused]);\n\n return (\n <div\n className={classnames(styles.callingCodeInputContainer, className, {\n [styles.focusVisible]: isFocusVisible && !disabled,\n [styles.focused]: isFocused && !disabled,\n [styles.invalid]: invalid && !disabled,\n [styles.disabled]: disabled,\n })}\n tabIndex={0}\n onFocus={() => {\n if (!isMobile) {\n inputRef.current?.focus();\n return;\n }\n\n setIsFocused(true);\n onFocus();\n }}\n onBlur={() => {\n if (!isMobile) {\n return;\n }\n setIsFocused(false);\n onBlur();\n }}\n ref={ref}\n data-qa=\"magritte-phone-input-calling-code\"\n >\n <div className={styles.flagContainer}>{flag}</div>\n <div className={styles.inputContainer}>\n <input\n ref={inputRef}\n onFocus={() => {\n setIsFocused(true);\n onFocus();\n }}\n onBlur={() => {\n setIsFocused(false);\n onBlur();\n }}\n onKeyDown={onKeyDown}\n className={styles.callingCodeInput}\n value={value}\n onChange={(event: ChangeEvent<HTMLInputElement>) => onChange(event.target.value)}\n disabled={disabled}\n data-qa=\"magritte-phone-input-calling-code-input\"\n />\n <div className={styles.ghostData} data-qa=\"magritte-phone-input-calling-code-value\">\n {value}\n </div>\n </div>\n </div>\n );\n }\n);\n\nCallingCodeInput.displayName = 'CallingCodeInput';\n"],"names":["_jsxs","classnames","_jsx"],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type KeyboardEventHandler, type ReactNode } from 'react';
2
+ interface CallingCodeInputProps {
3
+ flag: ReactNode;
4
+ onChange: (value: string) => void;
5
+ value: string;
6
+ onFocus: VoidFunction;
7
+ onBlur: VoidFunction;
8
+ onKeyDown?: KeyboardEventHandler<HTMLInputElement>;
9
+ invalid?: boolean;
10
+ disabled?: boolean;
11
+ className?: string | boolean;
12
+ }
13
+ export declare const CallingCodeInput: import("react").ForwardRefExoticComponent<CallingCodeInputProps & import("react").RefAttributes<HTMLDivElement>>;
14
+ export {};
@@ -0,0 +1,7 @@
1
+ import './index.css';
2
+ import 'react/jsx-runtime';
3
+ import 'react';
4
+ import 'classnames';
5
+ import '@hh.ru/magritte-ui-breakpoint';
6
+ export { C as CallingCodeInput } from './CallingCodeInput-Dv1X6z2c.js';
7
+ //# sourceMappingURL=CallingCodeInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CallingCodeInput.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,29 @@
1
+ import { type FC, type Ref } from 'react';
2
+ import { type CountryCode, type CountryCallingCode } from 'libphonenumber-js';
3
+ export interface PhoneInputProps {
4
+ defaultCountry?: CountryCode;
5
+ defaultNationalNumber?: string;
6
+ onChange: (data: {
7
+ country: CountryCode;
8
+ callingCode: CountryCallingCode;
9
+ nationalNumber: string;
10
+ phone: string;
11
+ isValid: boolean;
12
+ isPhoneValidationApiLoaded: boolean;
13
+ }) => void;
14
+ onPhoneValidationApiLoadError?: (error: Error, reload: VoidFunction) => void;
15
+ availableCountries?: CountryCode[];
16
+ priorityCountries?: CountryCode[];
17
+ invalid?: boolean;
18
+ description?: string;
19
+ errorMessage?: string;
20
+ trls: {
21
+ countryNames: Partial<Record<CountryCode, string>>;
22
+ priorityCountriesTitle: string;
23
+ };
24
+ onFocus?: VoidFunction;
25
+ onBlur?: VoidFunction;
26
+ 'data-qa'?: string;
27
+ inputsWrapperRef?: Ref<HTMLDivElement>;
28
+ }
29
+ export declare const PhoneInput: FC<PhoneInputProps>;
package/PhoneInput.js ADDED
@@ -0,0 +1,112 @@
1
+ import './index.css';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { forwardRef, useMemo, useState, useRef } from 'react';
4
+ import { useMultipleRefs } from '@hh.ru/magritte-common-use-multiple-refs';
5
+ import { FormHelper } from '@hh.ru/magritte-ui-form-helper';
6
+ import { Input } from '@hh.ru/magritte-ui-input';
7
+ import { RegionSelect } from './RegionSelect.js';
8
+ import { phoneFormatterFactory } from './phoneFormatter.js';
9
+ import { useCountrySelectOptions } from './useCountriesSelectOptions.js';
10
+ import { useLibPhoneNumber } from './useLibPhoneNumber.js';
11
+ import { s as styles } from './CallingCodeInput-Dv1X6z2c.js';
12
+ import 'classnames';
13
+ import '@hh.ru/magritte-ui-cell';
14
+ import '@hh.ru/magritte-ui-icon/country';
15
+ import './useIsFlagEmojiSupported.js';
16
+ import '@hh.ru/magritte-ui-select';
17
+ import './basicMetadata.js';
18
+ import '@hh.ru/magritte-ui-breakpoint';
19
+
20
+ const DEFAULT_PRIORITY_COUNTRIES = ['RU', 'BY', 'KZ', 'UZ'];
21
+ const notDigitsRegExp = /[\D]/g;
22
+ const PhoneInput = forwardRef(({ defaultCountry = 'RU', defaultNationalNumber = '', onChange, availableCountries, invalid, description, errorMessage, priorityCountries = DEFAULT_PRIORITY_COUNTRIES, onFocus, onBlur, trls, 'data-qa': dataQa = 'magritte-phone-input-wrapper', inputsWrapperRef, }, ref) => {
23
+ const metadataVariant = useMemo(() => {
24
+ const minimalMetadata = availableCountries?.length === DEFAULT_PRIORITY_COUNTRIES.length &&
25
+ DEFAULT_PRIORITY_COUNTRIES.every((country) => availableCountries.includes(country));
26
+ if (minimalMetadata) {
27
+ return 'ru-by-kz-uz';
28
+ }
29
+ const keys = Object.keys(trls.countryNames);
30
+ if (keys.length === DEFAULT_PRIORITY_COUNTRIES.length &&
31
+ DEFAULT_PRIORITY_COUNTRIES.every((country) => keys.includes(country))) {
32
+ return 'ru-by-kz-uz';
33
+ }
34
+ return 'max';
35
+ }, [availableCountries, trls.countryNames]);
36
+ const libPhoneNumberAPI = useLibPhoneNumber(metadataVariant);
37
+ const { getCountryCallingCode, parsePhoneNumber, isValidPhoneNumber, isLoaded } = libPhoneNumberAPI;
38
+ const [country, setCountry] = useState(defaultCountry);
39
+ const countryRef = useRef(country);
40
+ const countryCallingCodeRef = useRef(getCountryCallingCode(country));
41
+ const focusInsideRef = useRef(false);
42
+ const wrapperRef = useRef(null);
43
+ const wrapperRefMultiplexer = useMultipleRefs(wrapperRef, inputsWrapperRef);
44
+ const [phoneValue, setPhoneValue] = useState(defaultNationalNumber);
45
+ const phoneInputRef = useRef(null);
46
+ countryRef.current = country;
47
+ countryCallingCodeRef.current = getCountryCallingCode(country);
48
+ const selectOptions = useCountrySelectOptions({
49
+ availableCountries,
50
+ trls,
51
+ priorityCountries,
52
+ libPhoneNumberAPI,
53
+ });
54
+ const phoneFormatter = useMemo(() => {
55
+ return phoneFormatterFactory({
56
+ // обернуто в промис т.к. форматтер вызывается в процессе рендера BaseInput и не может синхронно
57
+ // вызывать изменения стейта другого компонента
58
+ setCountry: (country) => Promise.resolve().then(() => setCountry(country)),
59
+ currentCountryRef: countryRef,
60
+ libPhoneNumberAPI,
61
+ });
62
+ }, [libPhoneNumberAPI]);
63
+ const onChangeHandler = (country, phoneValue) => {
64
+ const callingCode = getCountryCallingCode(country);
65
+ const nationalNumber = phoneValue.replace(notDigitsRegExp, '');
66
+ onChange({
67
+ country,
68
+ callingCode,
69
+ phone: `+${callingCode}${nationalNumber}`,
70
+ nationalNumber,
71
+ isValid: isValidPhoneNumber(nationalNumber, country),
72
+ isPhoneValidationApiLoaded: isLoaded,
73
+ });
74
+ };
75
+ const focusHandler = () => {
76
+ if (focusInsideRef.current) {
77
+ return;
78
+ }
79
+ focusInsideRef.current = true;
80
+ onFocus?.();
81
+ };
82
+ const blurHandler = () => {
83
+ requestAnimationFrame(() => {
84
+ if (wrapperRef.current?.contains(document.activeElement)) {
85
+ return;
86
+ }
87
+ focusInsideRef.current = false;
88
+ onBlur?.();
89
+ });
90
+ };
91
+ return (jsxs("div", { ref: ref, children: [jsxs("div", { className: styles.phoneInputContainer, onFocus: focusHandler, onBlur: blurHandler, ref: wrapperRefMultiplexer, "data-qa": dataQa, children: [jsx(RegionSelect, { country: country, selectOptions: selectOptions, callingCode: countryCallingCodeRef.current, onChange: (newCountry) => {
92
+ try {
93
+ const phone = parsePhoneNumber(phoneValue, newCountry);
94
+ if (phone.country !== newCountry) {
95
+ setPhoneValue('');
96
+ }
97
+ }
98
+ catch {
99
+ // do nothing
100
+ }
101
+ setCountry(newCountry);
102
+ onChangeHandler(newCountry, phoneValue);
103
+ phoneInputRef.current?.focus();
104
+ }, availableCountries: availableCountries, priorityCountries: priorityCountries, libPhoneNumberAPI: libPhoneNumberAPI, invalid: invalid }), jsx(Input, { ref: phoneInputRef, size: "large", onChange: (value) => {
105
+ setPhoneValue(value);
106
+ onChangeHandler(country, value);
107
+ }, formatter: phoneFormatter, value: phoneValue, invalid: invalid, inputMode: "tel", "data-qa": "magritte-phone-input-national-number-input" })] }), jsx(FormHelper, { invalid: invalid, description: description, errorMessage: errorMessage, "data-qa": "magritte-phone-input-form-helper" })] }));
108
+ });
109
+ PhoneInput.displayName = 'PhoneInput';
110
+
111
+ export { PhoneInput };
112
+ //# sourceMappingURL=PhoneInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PhoneInput.js","sources":["../src/PhoneInput.tsx"],"sourcesContent":["import { type FC, type Ref, useState, useRef, useMemo, forwardRef } from 'react';\nimport { type CountryCode, type CountryCallingCode } from 'libphonenumber-js';\n\nimport { useMultipleRefs } from '@hh.ru/magritte-common-use-multiple-refs';\nimport { FormHelper } from '@hh.ru/magritte-ui-form-helper';\nimport { Input } from '@hh.ru/magritte-ui-input';\nimport { RegionSelect } from '@hh.ru/magritte-ui-phone-input/RegionSelect';\nimport { phoneFormatterFactory } from '@hh.ru/magritte-ui-phone-input/phoneFormatter';\nimport { useCountrySelectOptions } from '@hh.ru/magritte-ui-phone-input/useCountriesSelectOptions';\nimport { type MetadataVariant, useLibPhoneNumber } from '@hh.ru/magritte-ui-phone-input/useLibPhoneNumber';\n\nimport styles from './phoneInput.less';\n\nexport interface PhoneInputProps {\n defaultCountry?: CountryCode;\n defaultNationalNumber?: string;\n onChange: (data: {\n country: CountryCode;\n callingCode: CountryCallingCode;\n nationalNumber: string;\n phone: string;\n isValid: boolean;\n isPhoneValidationApiLoaded: boolean;\n }) => void;\n onPhoneValidationApiLoadError?: (error: Error, reload: VoidFunction) => void;\n availableCountries?: CountryCode[];\n priorityCountries?: CountryCode[];\n invalid?: boolean;\n description?: string;\n errorMessage?: string;\n trls: {\n countryNames: Partial<Record<CountryCode, string>>;\n priorityCountriesTitle: string;\n };\n onFocus?: VoidFunction;\n onBlur?: VoidFunction;\n 'data-qa'?: string;\n inputsWrapperRef?: Ref<HTMLDivElement>;\n}\n\nconst DEFAULT_PRIORITY_COUNTRIES: CountryCode[] = ['RU', 'BY', 'KZ', 'UZ'] as const;\nconst notDigitsRegExp = /[\\D]/g;\n\nexport const PhoneInput: FC<PhoneInputProps> = forwardRef<HTMLDivElement, PhoneInputProps>(\n (\n {\n defaultCountry = 'RU',\n defaultNationalNumber = '',\n onChange,\n availableCountries,\n invalid,\n description,\n errorMessage,\n priorityCountries = DEFAULT_PRIORITY_COUNTRIES,\n onFocus,\n onBlur,\n trls,\n 'data-qa': dataQa = 'magritte-phone-input-wrapper',\n inputsWrapperRef,\n },\n ref\n ) => {\n const metadataVariant: MetadataVariant = useMemo<MetadataVariant>(() => {\n const minimalMetadata =\n availableCountries?.length === DEFAULT_PRIORITY_COUNTRIES.length &&\n DEFAULT_PRIORITY_COUNTRIES.every((country) => availableCountries.includes(country));\n if (minimalMetadata) {\n return 'ru-by-kz-uz';\n }\n\n const keys = Object.keys(trls.countryNames);\n if (\n keys.length === DEFAULT_PRIORITY_COUNTRIES.length &&\n DEFAULT_PRIORITY_COUNTRIES.every((country) => keys.includes(country))\n ) {\n return 'ru-by-kz-uz';\n }\n\n return 'max';\n }, [availableCountries, trls.countryNames]);\n\n const libPhoneNumberAPI = useLibPhoneNumber(metadataVariant);\n const { getCountryCallingCode, parsePhoneNumber, isValidPhoneNumber, isLoaded } = libPhoneNumberAPI;\n const [country, setCountry] = useState<CountryCode>(defaultCountry);\n const countryRef = useRef<CountryCode>(country);\n const countryCallingCodeRef = useRef<CountryCallingCode>(getCountryCallingCode(country));\n const focusInsideRef = useRef(false);\n const wrapperRef = useRef<HTMLDivElement>(null);\n const wrapperRefMultiplexer = useMultipleRefs(wrapperRef, inputsWrapperRef);\n const [phoneValue, setPhoneValue] = useState(defaultNationalNumber);\n const phoneInputRef = useRef<HTMLInputElement>(null);\n countryRef.current = country;\n countryCallingCodeRef.current = getCountryCallingCode(country);\n\n const selectOptions = useCountrySelectOptions({\n availableCountries,\n trls,\n priorityCountries,\n libPhoneNumberAPI,\n });\n\n const phoneFormatter = useMemo(() => {\n return phoneFormatterFactory({\n // обернуто в промис т.к. форматтер вызывается в процессе рендера BaseInput и не может синхронно\n // вызывать изменения стейта другого компонента\n setCountry: (country) => Promise.resolve().then(() => setCountry(country)),\n currentCountryRef: countryRef,\n libPhoneNumberAPI,\n });\n }, [libPhoneNumberAPI]);\n\n const onChangeHandler = (country: CountryCode, phoneValue: string) => {\n const callingCode = getCountryCallingCode(country);\n const nationalNumber = phoneValue.replace(notDigitsRegExp, '');\n onChange({\n country,\n callingCode,\n phone: `+${callingCode}${nationalNumber}`,\n nationalNumber,\n isValid: isValidPhoneNumber(nationalNumber, country),\n isPhoneValidationApiLoaded: isLoaded,\n });\n };\n\n const focusHandler = () => {\n if (focusInsideRef.current) {\n return;\n }\n\n focusInsideRef.current = true;\n onFocus?.();\n };\n\n const blurHandler = () => {\n requestAnimationFrame(() => {\n if (wrapperRef.current?.contains(document.activeElement)) {\n return;\n }\n\n focusInsideRef.current = false;\n onBlur?.();\n });\n };\n\n return (\n <div ref={ref}>\n <div\n className={styles.phoneInputContainer}\n onFocus={focusHandler}\n onBlur={blurHandler}\n ref={wrapperRefMultiplexer}\n data-qa={dataQa}\n >\n <RegionSelect\n country={country}\n selectOptions={selectOptions}\n callingCode={countryCallingCodeRef.current}\n onChange={(newCountry) => {\n try {\n const phone = parsePhoneNumber(phoneValue, newCountry);\n if (phone.country !== newCountry) {\n setPhoneValue('');\n }\n } catch {\n // do nothing\n }\n setCountry(newCountry);\n onChangeHandler(newCountry, phoneValue);\n phoneInputRef.current?.focus();\n }}\n availableCountries={availableCountries}\n priorityCountries={priorityCountries}\n libPhoneNumberAPI={libPhoneNumberAPI}\n invalid={invalid}\n />\n <Input\n ref={phoneInputRef}\n size=\"large\"\n onChange={(value) => {\n setPhoneValue(value);\n onChangeHandler(country, value);\n }}\n formatter={phoneFormatter}\n value={phoneValue}\n invalid={invalid}\n inputMode=\"tel\"\n data-qa=\"magritte-phone-input-national-number-input\"\n />\n </div>\n <FormHelper\n invalid={invalid}\n description={description}\n errorMessage={errorMessage}\n data-qa=\"magritte-phone-input-form-helper\"\n />\n </div>\n );\n }\n);\n\nPhoneInput.displayName = 'PhoneInput';\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { type FC } from 'react';
2
+ import { type CountryCode, type CountryCallingCode } from 'libphonenumber-js';
3
+ import { type OptionData } from '@hh.ru/magritte-ui-phone-input/useCountriesSelectOptions';
4
+ import { type LibPhoneNumberAPI } from '@hh.ru/magritte-ui-phone-input/useLibPhoneNumber';
5
+ import { type SelectOption } from '@hh.ru/magritte-ui-select';
6
+ type RegionSelectProps = {
7
+ country: CountryCode;
8
+ selectOptions: SelectOption<OptionData>[];
9
+ callingCode: CountryCallingCode;
10
+ onChange: (country: CountryCode, callingCode: CountryCallingCode) => void;
11
+ availableCountries?: CountryCode[];
12
+ priorityCountries: CountryCode[];
13
+ invalid?: boolean;
14
+ libPhoneNumberAPI: LibPhoneNumberAPI;
15
+ };
16
+ export declare const RegionSelect: FC<RegionSelectProps>;
17
+ export {};
@@ -0,0 +1,95 @@
1
+ import './index.css';
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
+ import { useState, useRef, useCallback, useEffect } from 'react';
4
+ import classNames from 'classnames';
5
+ import { CellText, Cell, CellRightLabel } from '@hh.ru/magritte-ui-cell';
6
+ import { RUSize24, BYSize24, KZSize24, UZSize24 } from '@hh.ru/magritte-ui-icon/country';
7
+ import { s as styles, C as CallingCodeInput } from './CallingCodeInput-Dv1X6z2c.js';
8
+ import { useIsFlagEmojiSupported } from './useIsFlagEmojiSupported.js';
9
+ import { Select } from '@hh.ru/magritte-ui-select';
10
+ import '@hh.ru/magritte-ui-breakpoint';
11
+
12
+ const getFlagEmoji = (countryCode) => {
13
+ const codePoints = countryCode
14
+ .toUpperCase()
15
+ .split('')
16
+ .map((char) => 127397 + char.charCodeAt(0));
17
+ return String.fromCodePoint(...codePoints);
18
+ };
19
+ const FLAG_BY_COUNTRY_CODE = {
20
+ RU: jsx(RUSize24, {}),
21
+ BY: jsx(BYSize24, {}),
22
+ KZ: jsx(KZSize24, {}),
23
+ UZ: jsx(UZSize24, {}),
24
+ };
25
+ const renderSelectItem = ({ data, label, onChange, }) => {
26
+ if (!data) {
27
+ return (jsx(CellText, { maxLines: 1, style: "secondary", children: label }));
28
+ }
29
+ return (jsx(Cell, { left: jsxs("div", { className: styles.flagContainer, children: [jsx("span", { className: classNames({
30
+ [styles.flagEmoji]: !!FLAG_BY_COUNTRY_CODE[data.country],
31
+ }), children: getFlagEmoji(data.country) }), !!FLAG_BY_COUNTRY_CODE[data.country] && (jsx("span", { className: styles.flagIcon, children: FLAG_BY_COUNTRY_CODE[data.country] }))] }), right: jsxs(CellRightLabel, { hideIcon: true, children: ["+", data.callingCode] }), horPadding: false, vertPadding: false, onClick: () => onChange(data.country, true), children: jsx(CellText, { children: data.countryName }) }));
32
+ };
33
+ const RegionSelect = ({ selectOptions, country, callingCode, onChange, invalid, libPhoneNumberAPI, }) => {
34
+ const { getCountryCallingCode } = libPhoneNumberAPI;
35
+ const [inputValue, setInputValue] = useState(`+${callingCode}`);
36
+ const exactMatchRef = useRef(true);
37
+ const isFlagEmojiSupported = useIsFlagEmojiSupported();
38
+ const pickerRefCallback = useCallback((node) => {
39
+ if (node) {
40
+ node.classList.toggle(styles.noFlagEmoji, !isFlagEmojiSupported);
41
+ }
42
+ }, [isFlagEmojiSupported]);
43
+ useEffect(() => {
44
+ setInputValue(`+${callingCode}`);
45
+ }, [callingCode]);
46
+ return (jsx(Select, { type: "radio", options: selectOptions, value: country, onChange: (value) => onChange?.(value, getCountryCallingCode(value)), triggerProps: { size: 'large' }, widthEqualToActivator: false, searchable: selectOptions.length > 10, renderMobileItem: renderSelectItem, renderDesktopItem: renderSelectItem, pickerRef: pickerRefCallback, renderTrigger: ({ setSearchValue, onFocus, onBlur, onKeyDown, ref }) => (jsx(CallingCodeInput, { ref: ref, className: !isFlagEmojiSupported && styles.noFlagEmoji, flag: jsxs(Fragment, { children: [jsx("span", { className: classNames({
47
+ [styles.flagEmoji]: !!FLAG_BY_COUNTRY_CODE[country],
48
+ }), children: getFlagEmoji(country) }), !!FLAG_BY_COUNTRY_CODE[country] && (jsx("span", { className: styles.flagIcon, children: FLAG_BY_COUNTRY_CODE[country] }))] }), invalid: invalid, onChange: (value) => {
49
+ if (value === '') {
50
+ setInputValue('+');
51
+ setSearchValue('');
52
+ }
53
+ if (!value.startsWith('+')) {
54
+ return;
55
+ }
56
+ const code = value.substring(1);
57
+ let hasPartialMatch = false;
58
+ const exactMatch = selectOptions.find((option) => {
59
+ if (!option.data) {
60
+ return false;
61
+ }
62
+ if (option.data.callingCode.startsWith(code)) {
63
+ hasPartialMatch = true;
64
+ }
65
+ return option.data.callingCode === code;
66
+ });
67
+ // выполнится даже если есть точное совпадение
68
+ if (hasPartialMatch) {
69
+ exactMatchRef.current = false;
70
+ setInputValue(`+${code}`);
71
+ setSearchValue(code === '' ? '' : `+${code}`);
72
+ }
73
+ if (exactMatch) {
74
+ exactMatchRef.current = true;
75
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
76
+ onChange(exactMatch.data.country, exactMatch.data.callingCode);
77
+ }
78
+ }, value: inputValue, onFocus: () => {
79
+ setSearchValue('');
80
+ onFocus?.();
81
+ }, onBlur: () => {
82
+ if (!exactMatchRef.current) {
83
+ const code = inputValue.substring(1);
84
+ const bestMatch = selectOptions.find((option) => option.data?.callingCode.startsWith(code));
85
+ if (bestMatch && bestMatch.data) {
86
+ onChange(bestMatch.data.country, bestMatch.data.callingCode);
87
+ setInputValue(`+${bestMatch.data.callingCode}`);
88
+ }
89
+ }
90
+ onBlur?.();
91
+ }, onKeyDown: onKeyDown })) }));
92
+ };
93
+
94
+ export { RegionSelect };
95
+ //# sourceMappingURL=RegionSelect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RegionSelect.js","sources":["../src/RegionSelect.tsx"],"sourcesContent":["import { type FC, type Ref, type ReactNode, useState, useRef, useEffect, useCallback } from 'react';\nimport classNames from 'classnames';\nimport { type CountryCode, type CountryCallingCode } from 'libphonenumber-js';\n\nimport { Cell, CellRightLabel, CellText } from '@hh.ru/magritte-ui-cell';\nimport { RUSize24, BYSize24, KZSize24, UZSize24 } from '@hh.ru/magritte-ui-icon/country';\nimport { CallingCodeInput } from '@hh.ru/magritte-ui-phone-input/CallingCodeInput';\nimport { type OptionData } from '@hh.ru/magritte-ui-phone-input/useCountriesSelectOptions';\nimport { useIsFlagEmojiSupported } from '@hh.ru/magritte-ui-phone-input/useIsFlagEmojiSupported';\nimport { type LibPhoneNumberAPI } from '@hh.ru/magritte-ui-phone-input/useLibPhoneNumber';\nimport { type OnChangeAction, type SelectOption, Select } from '@hh.ru/magritte-ui-select';\n\nimport styles from './phoneInput.less';\n\nconst getFlagEmoji = (countryCode: CountryCode) => {\n const codePoints = countryCode\n .toUpperCase()\n .split('')\n .map((char) => 127397 + char.charCodeAt(0));\n return String.fromCodePoint(...codePoints);\n};\n\nconst FLAG_BY_COUNTRY_CODE: Partial<Record<CountryCode, ReactNode>> = {\n RU: <RUSize24 />,\n BY: <BYSize24 />,\n KZ: <KZSize24 />,\n UZ: <UZSize24 />,\n} as const;\n\nconst renderSelectItem = ({\n data,\n label,\n onChange,\n}: {\n data?: OptionData;\n label: ReactNode;\n onChange: OnChangeAction;\n}) => {\n if (!data) {\n return (\n <CellText maxLines={1} style=\"secondary\">\n {label}\n </CellText>\n );\n }\n return (\n <Cell\n left={\n <div className={styles.flagContainer}>\n <span\n className={classNames({\n [styles.flagEmoji]: !!FLAG_BY_COUNTRY_CODE[data.country],\n })}\n >\n {getFlagEmoji(data.country)}\n </span>\n {!!FLAG_BY_COUNTRY_CODE[data.country] && (\n <span className={styles.flagIcon}>{FLAG_BY_COUNTRY_CODE[data.country]}</span>\n )}\n </div>\n }\n right={<CellRightLabel hideIcon>+{data.callingCode}</CellRightLabel>}\n horPadding={false}\n vertPadding={false}\n onClick={() => onChange(data.country, true)}\n >\n <CellText>{data.countryName}</CellText>\n </Cell>\n );\n};\n\ntype RegionSelectProps = {\n country: CountryCode;\n selectOptions: SelectOption<OptionData>[];\n callingCode: CountryCallingCode;\n onChange: (country: CountryCode, callingCode: CountryCallingCode) => void;\n availableCountries?: CountryCode[];\n priorityCountries: CountryCode[];\n invalid?: boolean;\n libPhoneNumberAPI: LibPhoneNumberAPI;\n};\n\nexport const RegionSelect: FC<RegionSelectProps> = ({\n selectOptions,\n country,\n callingCode,\n onChange,\n invalid,\n libPhoneNumberAPI,\n}) => {\n const { getCountryCallingCode } = libPhoneNumberAPI;\n const [inputValue, setInputValue] = useState<string>(`+${callingCode}`);\n const exactMatchRef = useRef(true);\n\n const isFlagEmojiSupported = useIsFlagEmojiSupported();\n const pickerRefCallback = useCallback(\n (node: HTMLElement) => {\n if (node) {\n node.classList.toggle(styles.noFlagEmoji, !isFlagEmojiSupported);\n }\n },\n [isFlagEmojiSupported]\n );\n\n useEffect(() => {\n setInputValue(`+${callingCode}`);\n }, [callingCode]);\n\n return (\n <Select\n type=\"radio\"\n options={selectOptions}\n value={country}\n onChange={(value) => onChange?.(value as CountryCode, getCountryCallingCode(value as CountryCode))}\n triggerProps={{ size: 'large' }}\n widthEqualToActivator={false}\n searchable={selectOptions.length > 10}\n renderMobileItem={renderSelectItem}\n renderDesktopItem={renderSelectItem}\n pickerRef={pickerRefCallback}\n renderTrigger={({ setSearchValue, onFocus, onBlur, onKeyDown, ref }) => (\n <CallingCodeInput\n ref={ref as Ref<HTMLDivElement>}\n className={!isFlagEmojiSupported && styles.noFlagEmoji}\n flag={\n <>\n <span\n className={classNames({\n [styles.flagEmoji]: !!FLAG_BY_COUNTRY_CODE[country],\n })}\n >\n {getFlagEmoji(country)}\n </span>\n {!!FLAG_BY_COUNTRY_CODE[country] && (\n <span className={styles.flagIcon}>{FLAG_BY_COUNTRY_CODE[country]}</span>\n )}\n </>\n }\n invalid={invalid}\n onChange={(value) => {\n if (value === '') {\n setInputValue('+');\n setSearchValue('');\n }\n if (!value.startsWith('+')) {\n return;\n }\n const code = value.substring(1);\n let hasPartialMatch = false;\n const exactMatch = selectOptions.find((option) => {\n if (!option.data) {\n return false;\n }\n\n if (option.data.callingCode.startsWith(code)) {\n hasPartialMatch = true;\n }\n\n return option.data.callingCode === code;\n });\n\n // выполнится даже если есть точное совпадение\n if (hasPartialMatch) {\n exactMatchRef.current = false;\n setInputValue(`+${code}`);\n setSearchValue(code === '' ? '' : `+${code}`);\n }\n\n if (exactMatch) {\n exactMatchRef.current = true;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n onChange(exactMatch.data!.country, exactMatch.data!.callingCode);\n }\n }}\n value={inputValue}\n onFocus={() => {\n setSearchValue('');\n onFocus?.();\n }}\n onBlur={() => {\n if (!exactMatchRef.current) {\n const code = inputValue.substring(1);\n const bestMatch = selectOptions.find((option) => option.data?.callingCode.startsWith(code));\n if (bestMatch && bestMatch.data) {\n onChange(bestMatch.data.country, bestMatch.data.callingCode);\n setInputValue(`+${bestMatch.data.callingCode}`);\n }\n }\n onBlur?.();\n }}\n onKeyDown={onKeyDown}\n />\n )}\n />\n );\n};\n"],"names":["_jsx","_jsxs"],"mappings":";;;;;;;;;;AAcA,MAAM,YAAY,GAAG,CAAC,WAAwB,KAAI;IAC9C,MAAM,UAAU,GAAG,WAAW;AACzB,SAAA,WAAW,EAAE;SACb,KAAK,CAAC,EAAE,CAAC;AACT,SAAA,GAAG,CAAC,CAAC,IAAI,KAAK,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAChD,IAAA,OAAO,MAAM,CAAC,aAAa,CAAC,GAAG,UAAU,CAAC,CAAC;AAC/C,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAA4C;IAClE,EAAE,EAAEA,GAAC,CAAA,QAAQ,EAAG,EAAA,CAAA;IAChB,EAAE,EAAEA,GAAC,CAAA,QAAQ,EAAG,EAAA,CAAA;IAChB,EAAE,EAAEA,GAAC,CAAA,QAAQ,EAAG,EAAA,CAAA;IAChB,EAAE,EAAEA,GAAC,CAAA,QAAQ,EAAG,EAAA,CAAA;CACV,CAAC;AAEX,MAAM,gBAAgB,GAAG,CAAC,EACtB,IAAI,EACJ,KAAK,EACL,QAAQ,GAKX,KAAI;IACD,IAAI,CAAC,IAAI,EAAE;AACP,QAAA,QACIA,GAAA,CAAC,QAAQ,EAAA,EAAC,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAC,WAAW,EAAA,QAAA,EACnC,KAAK,EAAA,CACC,EACb;KACL;AACD,IAAA,QACIA,GAAC,CAAA,IAAI,EACD,EAAA,IAAI,EACAC,IAAK,CAAA,KAAA,EAAA,EAAA,SAAS,EAAE,MAAM,CAAC,aAAa,EAAA,QAAA,EAAA,CAChCD,cACI,SAAS,EAAE,UAAU,CAAC;AAClB,wBAAA,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC;AAC3D,qBAAA,CAAC,YAED,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAA,CACxB,EACN,CAAC,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,KACjCA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,MAAM,CAAC,QAAQ,YAAG,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAA,CAAQ,CAChF,CACC,EAAA,CAAA,EAEV,KAAK,EAAEC,IAAA,CAAC,cAAc,EAAA,EAAC,QAAQ,EAAG,IAAA,EAAA,QAAA,EAAA,CAAA,GAAA,EAAA,IAAI,CAAC,WAAW,IAAkB,EACpE,UAAU,EAAE,KAAK,EACjB,WAAW,EAAE,KAAK,EAClB,OAAO,EAAE,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,EAAA,QAAA,EAE3CD,GAAC,CAAA,QAAQ,cAAE,IAAI,CAAC,WAAW,EAAY,CAAA,EAAA,CACpC,EACT;AACN,CAAC,CAAC;AAaW,MAAA,YAAY,GAA0B,CAAC,EAChD,aAAa,EACb,OAAO,EACP,WAAW,EACX,QAAQ,EACR,OAAO,EACP,iBAAiB,GACpB,KAAI;AACD,IAAA,MAAM,EAAE,qBAAqB,EAAE,GAAG,iBAAiB,CAAC;AACpD,IAAA,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAS,CAAI,CAAA,EAAA,WAAW,CAAE,CAAA,CAAC,CAAC;AACxE,IAAA,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;AAEnC,IAAA,MAAM,oBAAoB,GAAG,uBAAuB,EAAE,CAAC;AACvD,IAAA,MAAM,iBAAiB,GAAG,WAAW,CACjC,CAAC,IAAiB,KAAI;QAClB,IAAI,IAAI,EAAE;AACN,YAAA,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,oBAAoB,CAAC,CAAC;SACpE;AACL,KAAC,EACD,CAAC,oBAAoB,CAAC,CACzB,CAAC;IAEF,SAAS,CAAC,MAAK;AACX,QAAA,aAAa,CAAC,CAAA,CAAA,EAAI,WAAW,CAAA,CAAE,CAAC,CAAC;AACrC,KAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAElB,QACIA,IAAC,MAAM,EAAA,EACH,IAAI,EAAC,OAAO,EACZ,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,CAAC,KAAK,KAAK,QAAQ,GAAG,KAAoB,EAAE,qBAAqB,CAAC,KAAoB,CAAC,CAAC,EAClG,YAAY,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAC/B,qBAAqB,EAAE,KAAK,EAC5B,UAAU,EAAE,aAAa,CAAC,MAAM,GAAG,EAAE,EACrC,gBAAgB,EAAE,gBAAgB,EAClC,iBAAiB,EAAE,gBAAgB,EACnC,SAAS,EAAE,iBAAiB,EAC5B,aAAa,EAAE,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,MAC/DA,GAAC,CAAA,gBAAgB,EACb,EAAA,GAAG,EAAE,GAA0B,EAC/B,SAAS,EAAE,CAAC,oBAAoB,IAAI,MAAM,CAAC,WAAW,EACtD,IAAI,EACAC,4BACID,GACI,CAAA,MAAA,EAAA,EAAA,SAAS,EAAE,UAAU,CAAC;4BAClB,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC;AACtD,yBAAA,CAAC,YAED,YAAY,CAAC,OAAO,CAAC,GACnB,EACN,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,KAC5BA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,MAAM,CAAC,QAAQ,YAAG,oBAAoB,CAAC,OAAO,CAAC,EAAA,CAAQ,CAC3E,CACF,EAAA,CAAA,EAEP,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,CAAC,KAAK,KAAI;AAChB,gBAAA,IAAI,KAAK,KAAK,EAAE,EAAE;oBACd,aAAa,CAAC,GAAG,CAAC,CAAC;oBACnB,cAAc,CAAC,EAAE,CAAC,CAAC;iBACtB;gBACD,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;oBACxB,OAAO;iBACV;gBACD,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;gBAChC,IAAI,eAAe,GAAG,KAAK,CAAC;gBAC5B,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,MAAM,KAAI;AAC7C,oBAAA,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;AACd,wBAAA,OAAO,KAAK,CAAC;qBAChB;oBAED,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;wBAC1C,eAAe,GAAG,IAAI,CAAC;qBAC1B;AAED,oBAAA,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC;AAC5C,iBAAC,CAAC,CAAC;;gBAGH,IAAI,eAAe,EAAE;AACjB,oBAAA,aAAa,CAAC,OAAO,GAAG,KAAK,CAAC;AAC9B,oBAAA,aAAa,CAAC,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE,CAAC,CAAC;AAC1B,oBAAA,cAAc,CAAC,IAAI,KAAK,EAAE,GAAG,EAAE,GAAG,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE,CAAC,CAAC;iBACjD;gBAED,IAAI,UAAU,EAAE;AACZ,oBAAA,aAAa,CAAC,OAAO,GAAG,IAAI,CAAC;;AAE7B,oBAAA,QAAQ,CAAC,UAAU,CAAC,IAAK,CAAC,OAAO,EAAE,UAAU,CAAC,IAAK,CAAC,WAAW,CAAC,CAAC;iBACpE;aACJ,EACD,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,MAAK;gBACV,cAAc,CAAC,EAAE,CAAC,CAAC;gBACnB,OAAO,IAAI,CAAC;AAChB,aAAC,EACD,MAAM,EAAE,MAAK;AACT,gBAAA,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE;oBACxB,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;oBACrC,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5F,oBAAA,IAAI,SAAS,IAAI,SAAS,CAAC,IAAI,EAAE;AAC7B,wBAAA,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;wBAC7D,aAAa,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,WAAW,CAAE,CAAA,CAAC,CAAC;qBACnD;iBACJ;gBACD,MAAM,IAAI,CAAC;aACd,EACD,SAAS,EAAE,SAAS,GACtB,CACL,EAAA,CACH,EACJ;AACN;;;;"}
@@ -0,0 +1,2 @@
1
+ import { type CountryCode, type CountryCallingCode } from 'libphonenumber-js/core';
2
+ export declare const basicMetadata: Readonly<Map<CountryCode, CountryCallingCode>>;