@cloud-ru/ds-uikit-product-fields-predefined 2.0.30-preview-45edd66f.0 → 2.0.30-preview-20b4671f.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/README.md CHANGED
@@ -206,13 +206,16 @@ export function FieldMaskControlled() {
206
206
 
207
207
  Маска ввода определяется выбранной страной (`country.mask`) и меняется при смене страны. Префикс с кодом страны добавляется к итоговому значению.
208
208
 
209
- #### options — настройка списка стран
209
+ #### options — список стран
210
210
 
211
- Проп `options` (`CountrySettings`) ограничивает или переопределяет список (взаимоисключающие поля):
211
+ Проп `options` (`CountrySettings`) обязателен, поля взаимоисключающие:
212
212
 
213
- - `includedCountries` — оставить только перечисленные страны.
214
- - `excludedCountries` — исключить перечисленные из встроенного списка.
215
- - `overriddenOptions` — полностью заменить список собственными опциями.
213
+ - `includedCountries` — страны селектора (`RUSSIA_COUNTRY_CODE`, `BELARUS_COUNTRY_CODE`, …) в порядке передачи.
214
+ - `overriddenOptions` — собственные элементы списка вместо встроенных стран.
215
+
216
+ В бандл попадают флаги только переданных стран. Весь встроенный перечень — `ALL_COUNTRY_CODES`: с ним в бандл попадают все флаги (около 500 КБ в gzip), поэтому список стоит передавать явно.
217
+
218
+ Миграция с 2.x: поле без `options` — `options={{ includedCountries: ALL_COUNTRY_CODES }}`; `excludedCountries` — `includedCountries: ALL_COUNTRY_CODES.filter(...)`.
216
219
 
217
220
  #### Size (default `m`)
218
221
 
@@ -222,11 +225,11 @@ export function FieldMaskControlled() {
222
225
 
223
226
  #### Базовый
224
227
 
225
- Телефон с полным списком стран и поиском.
228
+ Телефон с полным списком стран (ALL_COUNTRY_CODES) и поиском.
226
229
 
227
230
  ```tsx
228
231
  import { PortalContextProvider } from '@cloud-ru/ds-portal-context';
229
- import { FieldPhone } from '@cloud-ru/ds-uikit-product-fields-predefined';
232
+ import { ALL_COUNTRY_CODES, FieldPhone } from '@cloud-ru/ds-uikit-product-fields-predefined';
230
233
  import { useRef, useState } from 'react';
231
234
 
232
235
  export function FieldPhoneBasic() {
@@ -236,7 +239,13 @@ export function FieldPhoneBasic() {
236
239
  return (
237
240
  <PortalContextProvider root={hostRef}>
238
241
  <div ref={hostRef} style={{ position: 'relative', width: 320 }}>
239
- <FieldPhone label='Телефон' value={value} onChange={setValue} searchPlaceholder='Поиск страны' />
242
+ <FieldPhone
243
+ label='Телефон'
244
+ value={value}
245
+ onChange={setValue}
246
+ searchPlaceholder='Поиск страны'
247
+ options={{ includedCountries: ALL_COUNTRY_CODES }}
248
+ />
240
249
  </div>
241
250
  </PortalContextProvider>
242
251
  );
@@ -325,7 +334,7 @@ export function FieldPhoneCountrySettings() {
325
334
  | `onKeyDown` | `KeyboardEventHandler<HTMLInputElement>` | — | Колбек обработки начала нажатия клавиши клавиатуры |
326
335
  | `onMouseDown` | `MouseEventHandler<HTMLInputElement>` | — | Колбек обработки нажатия кнопки мыши |
327
336
  | `onPaste` | `ClipboardEventHandler<HTMLInputElement>` | — | Колбек обработки вставки значения |
328
- | `options` | `CountrySettings` | — | Конфигурация для изменения стандартного списка стран |
337
+ | `options` | `CountrySettings` | — | Список стран селектора: встроенные страны (`includedCountries`) или собственные элементы (`overriddenOptions`) |
329
338
  | `outline` | `boolean` | `true` | Разделитель между основным полем и слотами `elementBefore` / `elementAfter` |
330
339
  | `pattern` | `string` | — | Регулярное выражение валидного инпута |
331
340
  | `readonly` | `boolean` | `false` | Только для чтения <br/> Является ли поле доступным только для чтения |
@@ -345,7 +354,7 @@ export function FieldPhoneCountrySettings() {
345
354
 
346
355
  ##### Related types
347
356
 
348
- - `CountrySettings` = `({ overriddenOptions: FieldPhoneOptionsProps[]; } & { includedCountries?: undefined; excludedCountries?: undefined; }) | ({ includedCountries: Country[]; } & { overriddenOptions?: undefined; excludedCountries?: undefined; }) | ({ excludedCountries: Country[]; } & { overriddenOptions?: undefined; includedCountries?: undefined; })`
357
+ - `CountrySettings` = `({ includedCountries: readonly Country[]; } & { overriddenOptions?: undefined; }) | ({ overriddenOptions: FieldPhoneOptionsProps[]; } & { includedCountries?: undefined; })`
349
358
 
350
359
  ### Адаптивность
351
360
 
@@ -7,7 +7,7 @@ export type FieldPhoneProps = Omit<FieldComboProps, 'prefix' | 'prefixIcon' | 'p
7
7
  /** Плейсхолдер поля поиска в выпадающем списке стран */
8
8
  searchPlaceholder?: string;
9
9
  onChangeCountry?(country: FieldPhoneOptionsProps): void;
10
- /** Конфигурация для изменения стандартного списка стран */
11
- options?: CountrySettings;
10
+ /** Список стран селектора: встроенные страны (`includedCountries`) или собственные элементы (`overriddenOptions`) */
11
+ options: CountrySettings;
12
12
  };
13
13
  export declare const FieldPhone: import("react").ForwardRefExoticComponent<Omit<FieldPhoneProps, "ref"> & import("react").RefAttributes<HTMLInputElement>>;
@@ -1,2 +1,2 @@
1
1
  import { CountrySettings, FieldPhoneOptionsProps } from '../types';
2
- export declare function useCountries(optionsSettings?: CountrySettings): FieldPhoneOptionsProps[];
2
+ export declare function useCountries(optionsSettings: CountrySettings): FieldPhoneOptionsProps[];
@@ -2,35 +2,19 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useCountries = useCountries;
4
4
  const react_1 = require("react");
5
- const countries_1 = require("../countries");
6
- const utils_1 = require("../utils");
7
5
  const useMapCountryToOptions_1 = require("./useMapCountryToOptions");
6
+ function getOptionsKey({ includedCountries, overriddenOptions }) {
7
+ if (overriddenOptions) {
8
+ return overriddenOptions
9
+ .map(({ id, iso2, mask, content }) => [id, iso2, mask, content.label, content.caption].join(':'))
10
+ .join();
11
+ }
12
+ return includedCountries.map(({ value }) => value).join();
13
+ }
8
14
  function useCountries(optionsSettings) {
9
15
  const mapCountryToOption = (0, useMapCountryToOptions_1.useMapCountryToOptions)();
10
- const filterCountries = (0, react_1.useMemo)(() => {
11
- if (!optionsSettings) {
12
- return () => true;
13
- }
14
- const { includedCountries, excludedCountries } = optionsSettings;
15
- const uniqueKey = 'value';
16
- if (includedCountries) {
17
- const includedSet = (0, utils_1.uniqueSet)(includedCountries, uniqueKey);
18
- return (country) => includedSet.has(country[uniqueKey]);
19
- }
20
- if (excludedCountries) {
21
- const excludedSet = (0, utils_1.uniqueSet)(excludedCountries, uniqueKey);
22
- return (country) => !excludedSet.has(country[uniqueKey]);
23
- }
24
- return () => true;
25
- }, [optionsSettings]);
26
- return (0, react_1.useMemo)(() => {
27
- if (optionsSettings?.overriddenOptions)
28
- return optionsSettings.overriddenOptions;
29
- return countries_1.ALL_COUNTRY_CODES.reduce((result, country) => {
30
- if (filterCountries(country)) {
31
- result.push(mapCountryToOption(country));
32
- }
33
- return result;
34
- }, []);
35
- }, [optionsSettings, filterCountries, mapCountryToOption]);
16
+ const optionsKey = getOptionsKey(optionsSettings);
17
+ return (0, react_1.useMemo)(() => optionsSettings.overriddenOptions ?? optionsSettings.includedCountries.map(mapCountryToOption),
18
+ // eslint-disable-next-line react-hooks/exhaustive-deps
19
+ [optionsKey, mapCountryToOption]);
36
20
  }
@@ -21,11 +21,12 @@ type OneOf<T extends object> = {
21
21
  };
22
22
  }[keyof T];
23
23
  export type CountrySettings = OneOf<{
24
- /** Список элементов выпадающего списка со странами; переопределяет встроенный список пакета */
24
+ /**
25
+ * Страны селектора в порядке передачи. В бандл попадают флаги только переданных стран;
26
+ * весь встроенный перечень — `ALL_COUNTRY_CODES`.
27
+ */
28
+ includedCountries: readonly Country[];
29
+ /** Собственные элементы выпадающего списка вместо встроенных стран */
25
30
  overriddenOptions: FieldPhoneOptionsProps[];
26
- /** Список стран, которые должны отображаться в селекторе (из встроенного перечня пакета) */
27
- includedCountries: Country[];
28
- /** Список стран, которые будут исключены из встроенного перечня пакета */
29
- excludedCountries: Country[];
30
31
  }>;
31
32
  export {};
@@ -1,5 +1,4 @@
1
1
  import { FieldPhoneOptionsProps } from './types';
2
- export declare const uniqueSet: <T, K extends keyof T>(arr: T[], key: K) => Set<T[K]>;
3
2
  export declare const formatPhoneNumber: <T extends {
4
3
  caption: string;
5
4
  mask: string;
@@ -1,11 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.handleAutoInsert = exports.formatPhoneNumber = exports.uniqueSet = void 0;
3
+ exports.handleAutoInsert = exports.formatPhoneNumber = void 0;
4
4
  exports.detectCountryByPhone = detectCountryByPhone;
5
5
  const awesome_phonenumber_1 = require("awesome-phonenumber");
6
6
  const countries_1 = require("./countries");
7
- const uniqueSet = (arr, key) => new Set(arr.map(obj => obj[key]));
8
- exports.uniqueSet = uniqueSet;
9
7
  /* Приходит +79878887879/+7987****875, на основании mask возвращается +7 987-888-78-79/+7 987-***-*8-75 */
10
8
  const formatPhoneNumber = (phone, countries) => {
11
9
  const digits = phone.replace(/[^\d*]/g, '');
@@ -7,7 +7,7 @@ export type FieldPhoneProps = Omit<FieldComboProps, 'prefix' | 'prefixIcon' | 'p
7
7
  /** Плейсхолдер поля поиска в выпадающем списке стран */
8
8
  searchPlaceholder?: string;
9
9
  onChangeCountry?(country: FieldPhoneOptionsProps): void;
10
- /** Конфигурация для изменения стандартного списка стран */
11
- options?: CountrySettings;
10
+ /** Список стран селектора: встроенные страны (`includedCountries`) или собственные элементы (`overriddenOptions`) */
11
+ options: CountrySettings;
12
12
  };
13
13
  export declare const FieldPhone: import("react").ForwardRefExoticComponent<Omit<FieldPhoneProps, "ref"> & import("react").RefAttributes<HTMLInputElement>>;
@@ -1432,4 +1432,4 @@ export const ALL_COUNTRY_CODES = [
1432
1432
  SOUTH_SUDAN_COUNTRY_CODE,
1433
1433
  JAPAN_COUNTRY_CODE,
1434
1434
  ];
1435
- export const ENABLED_COUNTRY_CODES = ALL_COUNTRY_CODES.filter(({ enabled }) => enabled);
1435
+ export const ENABLED_COUNTRY_CODES = /* @__PURE__ */ ALL_COUNTRY_CODES.filter(({ enabled }) => enabled);
@@ -1,2 +1,2 @@
1
1
  import { CountrySettings, FieldPhoneOptionsProps } from '../types.js';
2
- export declare function useCountries(optionsSettings?: CountrySettings): FieldPhoneOptionsProps[];
2
+ export declare function useCountries(optionsSettings: CountrySettings): FieldPhoneOptionsProps[];
@@ -1,33 +1,17 @@
1
1
  import { useMemo } from 'react';
2
- import { ALL_COUNTRY_CODES } from '../countries.js';
3
- import { uniqueSet } from '../utils.js';
4
2
  import { useMapCountryToOptions } from './useMapCountryToOptions.js';
3
+ function getOptionsKey({ includedCountries, overriddenOptions }) {
4
+ if (overriddenOptions) {
5
+ return overriddenOptions
6
+ .map(({ id, iso2, mask, content }) => [id, iso2, mask, content.label, content.caption].join(':'))
7
+ .join();
8
+ }
9
+ return includedCountries.map(({ value }) => value).join();
10
+ }
5
11
  export function useCountries(optionsSettings) {
6
12
  const mapCountryToOption = useMapCountryToOptions();
7
- const filterCountries = useMemo(() => {
8
- if (!optionsSettings) {
9
- return () => true;
10
- }
11
- const { includedCountries, excludedCountries } = optionsSettings;
12
- const uniqueKey = 'value';
13
- if (includedCountries) {
14
- const includedSet = uniqueSet(includedCountries, uniqueKey);
15
- return (country) => includedSet.has(country[uniqueKey]);
16
- }
17
- if (excludedCountries) {
18
- const excludedSet = uniqueSet(excludedCountries, uniqueKey);
19
- return (country) => !excludedSet.has(country[uniqueKey]);
20
- }
21
- return () => true;
22
- }, [optionsSettings]);
23
- return useMemo(() => {
24
- if (optionsSettings?.overriddenOptions)
25
- return optionsSettings.overriddenOptions;
26
- return ALL_COUNTRY_CODES.reduce((result, country) => {
27
- if (filterCountries(country)) {
28
- result.push(mapCountryToOption(country));
29
- }
30
- return result;
31
- }, []);
32
- }, [optionsSettings, filterCountries, mapCountryToOption]);
13
+ const optionsKey = getOptionsKey(optionsSettings);
14
+ return useMemo(() => optionsSettings.overriddenOptions ?? optionsSettings.includedCountries.map(mapCountryToOption),
15
+ // eslint-disable-next-line react-hooks/exhaustive-deps
16
+ [optionsKey, mapCountryToOption]);
33
17
  }
@@ -21,11 +21,12 @@ type OneOf<T extends object> = {
21
21
  };
22
22
  }[keyof T];
23
23
  export type CountrySettings = OneOf<{
24
- /** Список элементов выпадающего списка со странами; переопределяет встроенный список пакета */
24
+ /**
25
+ * Страны селектора в порядке передачи. В бандл попадают флаги только переданных стран;
26
+ * весь встроенный перечень — `ALL_COUNTRY_CODES`.
27
+ */
28
+ includedCountries: readonly Country[];
29
+ /** Собственные элементы выпадающего списка вместо встроенных стран */
25
30
  overriddenOptions: FieldPhoneOptionsProps[];
26
- /** Список стран, которые должны отображаться в селекторе (из встроенного перечня пакета) */
27
- includedCountries: Country[];
28
- /** Список стран, которые будут исключены из встроенного перечня пакета */
29
- excludedCountries: Country[];
30
31
  }>;
31
32
  export {};
@@ -1,5 +1,4 @@
1
1
  import { FieldPhoneOptionsProps } from './types.js';
2
- export declare const uniqueSet: <T, K extends keyof T>(arr: T[], key: K) => Set<T[K]>;
3
2
  export declare const formatPhoneNumber: <T extends {
4
3
  caption: string;
5
4
  mask: string;
@@ -1,6 +1,5 @@
1
1
  import { parsePhoneNumber } from 'awesome-phonenumber';
2
2
  import { ABKHAZIA_COUNTRY_CODE, RUSSIA_COUNTRY_CODE } from './countries.js';
3
- export const uniqueSet = (arr, key) => new Set(arr.map(obj => obj[key]));
4
3
  /* Приходит +79878887879/+7987****875, на основании mask возвращается +7 987-888-78-79/+7 987-***-*8-75 */
5
4
  export const formatPhoneNumber = (phone, countries) => {
6
5
  const digits = phone.replace(/[^\d*]/g, '');