@steroidsjs/core 3.1.5 → 3.1.7

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/en.json CHANGED
@@ -1063,5 +1063,7 @@
1063
1063
  "Название цвета для Badge": "Color name for Badge",
1064
1064
  "Название цвета для Button": "Color name for Button",
1065
1065
  "Название цвета для Text, Title": "Color name for Text, Title",
1066
- "Промежуточное состояние чекбокса — часть дочерних элементов выбрана": ""
1066
+ "Промежуточное состояние чекбокса — часть дочерних элементов выбрана": "Indeterminate checkbox state — some child items are selected",
1067
+ "Выбранная страна по умолчанию": "Country selected by default",
1068
+ "Список доступных масок для телефонных номеров разных стран.\nКаждая маска определяет формат отображения номера.": "List of available masks for phone numbers from different countries.\nEach mask defines the number display format."
1067
1069
  }
@@ -22,6 +22,7 @@ export default class FieldEnum extends Enum {
22
22
  static readonly NAV_FIELD = "NavField";
23
23
  static readonly NUMBER_FIELD = "NumberField";
24
24
  static readonly PASSWORD_FIELD = "PasswordField";
25
+ static readonly PHONE_FIELD = "PhoneField";
25
26
  static readonly RADIO_FIELD = "RadioField";
26
27
  static readonly RADIO_LIST_FIELD = "RadioListField";
27
28
  static readonly RATE_FIELD = "RateField";
@@ -54,6 +55,7 @@ export default class FieldEnum extends Enum {
54
55
  NavField: string;
55
56
  NumberField: string;
56
57
  PasswordField: string;
58
+ PhoneField: string;
57
59
  RadioField: string;
58
60
  RadioListField: string;
59
61
  RateField: string;
@@ -49,6 +49,7 @@ var FieldEnum = /** @class */ (function (_super) {
49
49
  _a[FieldEnum.NAV_FIELD] = 'NavField',
50
50
  _a[FieldEnum.NUMBER_FIELD] = 'NumberField',
51
51
  _a[FieldEnum.PASSWORD_FIELD] = 'PasswordField',
52
+ _a[FieldEnum.PHONE_FIELD] = 'PhoneField',
52
53
  _a[FieldEnum.RADIO_FIELD] = 'RadioField',
53
54
  _a[FieldEnum.RADIO_LIST_FIELD] = 'RadioListField',
54
55
  _a[FieldEnum.RATE_FIELD] = 'RateField',
@@ -82,6 +83,7 @@ var FieldEnum = /** @class */ (function (_super) {
82
83
  FieldEnum.NAV_FIELD = 'NavField';
83
84
  FieldEnum.NUMBER_FIELD = 'NumberField';
84
85
  FieldEnum.PASSWORD_FIELD = 'PasswordField';
86
+ FieldEnum.PHONE_FIELD = 'PhoneField';
85
87
  FieldEnum.RADIO_FIELD = 'RadioField';
86
88
  FieldEnum.RADIO_LIST_FIELD = 'RadioListField';
87
89
  FieldEnum.RATE_FIELD = 'RateField';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steroidsjs/core",
3
- "version": "3.1.5",
3
+ "version": "3.1.7",
4
4
  "description": "",
5
5
  "author": "Vladimir Kozhin <hello@kozhindev.com>",
6
6
  "repository": {
@@ -10,7 +10,7 @@
10
10
  "main": "dist/index.ts",
11
11
  "types": "dist/index.d.ts",
12
12
  "exports": {
13
- "./": "./dist"
13
+ "./*": "./*"
14
14
  },
15
15
  "license": "MIT",
16
16
  "homepage": "https://github.com/steroids/react",
@@ -27,6 +27,14 @@ export interface IBaseFieldProps extends IFieldWrapperInputProps, IUiComponent {
27
27
  * Callback-функция, которая вызывается при очистке input
28
28
  */
29
29
  onClear?: (value: string) => void;
30
+ /**
31
+ * Callback-функция, которая вызывается при фокусировке input
32
+ */
33
+ onFocus?: (e: Event | FocusEvent) => void;
34
+ /**
35
+ * Callback-функция, которая вызывается при потере фокуса input
36
+ */
37
+ onBlur?: (e: Event | FocusEvent) => void;
30
38
  /**
31
39
  * Свойства для компонента отображения
32
40
  * @example
@@ -1,5 +1,5 @@
1
1
  import { ISaveCursorPositionDebounceConfig } from '@steroidsjs/core/hooks/useSaveCursorPosition';
2
- import { ChangeEvent, MutableRefObject } from 'react';
2
+ import { ChangeEvent, MutableRefObject, FocusEvent } from 'react';
3
3
  import { IFieldWrapperInputProps, IFieldWrapperOutputProps } from '../Field/fieldWrapper';
4
4
  import { IBaseFieldProps } from '../InputField/InputField';
5
5
  /**
@@ -42,6 +42,14 @@ export interface INumberFieldProps extends IFieldWrapperInputProps, IBaseFieldPr
42
42
  * @example ','
43
43
  */
44
44
  thousandSeparator?: string;
45
+ /**
46
+ * Callback-функция, которая вызывается при фокусировке input
47
+ */
48
+ onFocus?: (e: Event | FocusEvent) => void;
49
+ /**
50
+ * Callback-функция, которая вызывается при потере фокуса input
51
+ */
52
+ onBlur?: (e: Event | FocusEvent) => void;
45
53
  }
46
54
  export interface INumberFieldViewProps extends INumberFieldProps, IFieldWrapperOutputProps {
47
55
  inputProps: {
@@ -0,0 +1,40 @@
1
+ import { IDropDownFieldItem } from '@steroidsjs/core/ui/form/DropDownField/DropDownField';
2
+ import { IFieldWrapperInputProps, IFieldWrapperOutputProps } from '@steroidsjs/core/ui/form/Field/fieldWrapper';
3
+ import { IBaseFieldProps, IInputFieldProps } from '@steroidsjs/core/ui/form/InputField/InputField';
4
+ export interface ICountryPhoneMask extends IDropDownFieldItem {
5
+ phoneCode: string;
6
+ phoneMask?: (string | RegExp)[];
7
+ }
8
+ /**
9
+ * PhoneField
10
+ *
11
+ * Компонент для ввода и форматирования телефонных номеров с поддержкой масок стран.
12
+ * Автоматически форматирует введенный номер в соответствии с выбранной маской.
13
+ *
14
+ */
15
+ interface IPhoneFieldProps extends IFieldWrapperInputProps, IFieldWrapperOutputProps, IBaseFieldProps {
16
+ /**
17
+ * Список доступных масок для телефонных номеров разных стран.
18
+ * Каждая маска определяет формат отображения номера.
19
+ */
20
+ phoneMasks: ICountryPhoneMask[];
21
+ /**
22
+ * Выбранная страна по умолчанию
23
+ */
24
+ initialCountryCode: string;
25
+ }
26
+ export interface IPhoneFieldDropdownProps {
27
+ onOpen: () => void;
28
+ onClose: () => void;
29
+ isOpened: boolean;
30
+ items: any[];
31
+ onItemSelect: (id: any) => void;
32
+ selectedIds: any[];
33
+ selectedItems: any[];
34
+ primaryKey: string;
35
+ }
36
+ export interface IPhoneFieldViewProps extends IPhoneFieldProps, IFieldWrapperOutputProps {
37
+ dropDownProps: IPhoneFieldDropdownProps;
38
+ }
39
+ declare const _default: import("@steroidsjs/core/ui/form/Field/fieldWrapper").FieldWrapperComponent<IInputFieldProps>;
40
+ export default _default;
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ exports.__esModule = true;
17
+ var react_1 = require("@maskito/react");
18
+ var hooks_1 = require("@steroidsjs/core/hooks");
19
+ var fieldWrapper_1 = __importDefault(require("@steroidsjs/core/ui/form/Field/fieldWrapper"));
20
+ var react_2 = require("react");
21
+ function PhoneField(props) {
22
+ var components = (0, hooks_1.useComponents)();
23
+ var _a = (0, react_2.useState)(props.initialCountryCode.toUpperCase()), selectedCountryCode = _a[0], setSelectedCountryCode = _a[1];
24
+ // Data provider
25
+ var _b = (0, hooks_1.useDataProvider)({
26
+ items: props.phoneMasks,
27
+ initialSelectedIds: []
28
+ }), items = _b.items, sourceItems = _b.sourceItems;
29
+ // Data select
30
+ var _c = (0, hooks_1.useDataSelect)({
31
+ items: items,
32
+ sourceItems: sourceItems,
33
+ inputValue: props.input.value,
34
+ selectedIds: [selectedCountryCode]
35
+ }), isOpened = _c.isOpened, setIsOpened = _c.setIsOpened, setIsFocused = _c.setIsFocused, setHoveredId = _c.setHoveredId, selectedIds = _c.selectedIds, setSelectedIds = _c.setSelectedIds, selectedItems = _c.selectedItems;
36
+ var phoneMask = (0, react_2.useMemo)(function () {
37
+ var _a;
38
+ return (_a = ((items !== null && items !== void 0 ? items : [])).find(function (countryPhoneMask) { var _a; return countryPhoneMask.id === ((_a = selectedIds[0]) !== null && _a !== void 0 ? _a : props.defaultCountryCode); })) === null || _a === void 0 ? void 0 : _a.phoneMask;
39
+ }, [items, selectedIds, props.defaultCountryCode]);
40
+ var maskedInputRef = (0, react_1.useMaskito)({
41
+ options: {
42
+ mask: phoneMask
43
+ }
44
+ });
45
+ var _d = (0, hooks_1.useSaveCursorPosition)({
46
+ inputParams: props.input
47
+ }), inputRef = _d.inputRef, onChange = _d.onChange, value = _d.value;
48
+ (0, react_2.useEffect)(function () {
49
+ if (inputRef.current) {
50
+ maskedInputRef(inputRef.current);
51
+ }
52
+ }, [inputRef, maskedInputRef]);
53
+ var onOpen = (0, react_2.useCallback)(function () {
54
+ setIsFocused(true);
55
+ setIsOpened(true);
56
+ setHoveredId(null);
57
+ }, [setHoveredId, setIsFocused, setIsOpened]);
58
+ var onItemSelect = (0, react_2.useCallback)(function (id) {
59
+ // If country changed
60
+ if (selectedCountryCode !== id) {
61
+ setSelectedIds(id);
62
+ onChange(null, '');
63
+ setSelectedCountryCode(id);
64
+ }
65
+ setIsOpened(false);
66
+ }, [setSelectedIds, setIsOpened, onChange, selectedCountryCode]);
67
+ var onClose = (0, react_2.useCallback)(function () {
68
+ setIsFocused(false);
69
+ setIsOpened(false);
70
+ }, [setIsFocused, setIsOpened]);
71
+ var onClear = (0, react_2.useCallback)(function () {
72
+ if (props.onClear) {
73
+ props.onClear('');
74
+ }
75
+ props.input.onChange('');
76
+ }, [props]);
77
+ var inputProps = (0, react_2.useMemo)(function () { return (__assign({ name: props.input.name, onInput: onChange, value: value, placeholder: props.placeholder, disabled: props.disabled, type: 'tel' }, props.inputProps)); }, [props.disabled, props.input, props.inputProps, props.placeholder, onChange, value]);
78
+ var viewProps = (0, react_2.useMemo)(function () { return ({
79
+ inputRef: inputRef,
80
+ inputProps: inputProps,
81
+ size: props.size,
82
+ errors: props.errors,
83
+ leadIcon: props.leadIcon,
84
+ showClear: props.showClear,
85
+ onClear: onClear,
86
+ input: props.input,
87
+ className: props.className,
88
+ style: props.style,
89
+ onMouseDown: props.onMouseDown,
90
+ placeholder: props.placeholder,
91
+ required: props.required,
92
+ id: props.id,
93
+ viewProps: props.viewProps,
94
+ disabled: props.disabled,
95
+ dropDownProps: {
96
+ onOpen: onOpen,
97
+ onClose: onClose,
98
+ isOpened: isOpened,
99
+ items: items,
100
+ onItemSelect: onItemSelect,
101
+ selectedIds: selectedIds,
102
+ selectedItems: selectedItems,
103
+ primaryKey: 'id'
104
+ }
105
+ }); }, [inputProps, inputRef, isOpened, items, onClose,
106
+ onClear, onItemSelect, onOpen, props.className,
107
+ props.disabled, props.errors, props.id, props.input, props.leadIcon,
108
+ props.onMouseDown, props.placeholder, props.required, props.showClear,
109
+ props.size, props.style, props.viewProps, selectedIds, selectedItems]);
110
+ // No render for hidden input
111
+ if (props.type === 'hidden') {
112
+ return null;
113
+ }
114
+ return components.ui.renderView(props.view || 'form.PhoneFieldView', viewProps);
115
+ }
116
+ PhoneField.defaultProps = {
117
+ disabled: false,
118
+ required: false
119
+ };
120
+ exports["default"] = (0, fieldWrapper_1["default"])('PhoneField', PhoneField);
@@ -0,0 +1,2 @@
1
+ import PhoneField from './PhoneField';
2
+ export default PhoneField;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ exports.__esModule = true;
6
+ var PhoneField_1 = __importDefault(require("./PhoneField"));
7
+ exports["default"] = PhoneField_1["default"];
@@ -24,6 +24,7 @@ import MaskField from './MaskField';
24
24
  import NavField from './NavField';
25
25
  import NumberField from './NumberField';
26
26
  import PasswordField from './PasswordField';
27
+ import PhoneField from './PhoneField';
27
28
  import RadioField from './RadioField';
28
29
  import RadioListField from './RadioListField';
29
30
  import RateField from './RateField';
@@ -35,7 +36,7 @@ import TextField from './TextField';
35
36
  import TimeField from './TimeField';
36
37
  import TimeRangeField from './TimeRangeField';
37
38
  import WizardForm from './WizardForm';
38
- export { AutoCompleteField, BlankField, Button, CheckboxField, CheckboxListField, CheckboxTreeField, DateField, DateRangeField, DateTimeField, DateTimeRangeField, DropDownField, Field, FieldLayout, FieldList, FieldSet, FileField, Form, HtmlField, ImageField, InputField, NavField, NumberField, PasswordField, RadioField, RadioListField, ReCaptchaField, SliderField, TextField, TimeField, RateField, MaskField, EmailField, TimeRangeField, WizardForm, SwitcherField, SwitcherListField, };
39
+ export { AutoCompleteField, BlankField, Button, CheckboxField, CheckboxListField, CheckboxTreeField, DateField, DateRangeField, DateTimeField, DateTimeRangeField, DropDownField, Field, FieldLayout, FieldList, FieldSet, FileField, Form, HtmlField, ImageField, InputField, NavField, NumberField, PasswordField, PhoneField, RadioField, RadioListField, ReCaptchaField, SliderField, TextField, TimeField, RateField, MaskField, EmailField, TimeRangeField, WizardForm, SwitcherField, SwitcherListField, };
39
40
  declare const _default: {
40
41
  AutoCompleteField: import("./Field/fieldWrapper").FieldWrapperComponent<import("./AutoCompleteField/AutoCompleteField").IAutoCompleteFieldProps>;
41
42
  BlankField: import("./Field/fieldWrapper").FieldWrapperComponent<import("./BlankField/BlankField").IBlankFieldProps>;
@@ -60,6 +61,7 @@ declare const _default: {
60
61
  NavField: import("./Field/fieldWrapper").FieldWrapperComponent<import("./NavField/NavField").INavFieldProps>;
61
62
  NumberField: import("./Field/fieldWrapper").FieldWrapperComponent<import("./NumberField/NumberField").INumberFieldProps>;
62
63
  PasswordField: import("./Field/fieldWrapper").FieldWrapperComponent<import("./PasswordField/PasswordField").IPasswordFieldProps>;
64
+ PhoneField: import("./Field/fieldWrapper").FieldWrapperComponent<import("./InputField/InputField").IInputFieldProps>;
63
65
  RadioField: typeof RadioField;
64
66
  RadioListField: typeof RadioListField;
65
67
  ReCaptchaField: import("./Field/fieldWrapper").FieldWrapperComponent<import("./ReCaptchaField/ReCaptchaField").IReCaptchaFieldProps>;
package/ui/form/index.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  exports.__esModule = true;
6
- exports.SwitcherListField = exports.SwitcherField = exports.WizardForm = exports.TimeRangeField = exports.EmailField = exports.MaskField = exports.RateField = exports.TimeField = exports.TextField = exports.SliderField = exports.ReCaptchaField = exports.RadioListField = exports.RadioField = exports.PasswordField = exports.NumberField = exports.NavField = exports.InputField = exports.ImageField = exports.HtmlField = exports.Form = exports.FileField = exports.FieldSet = exports.FieldList = exports.FieldLayout = exports.Field = exports.DropDownField = exports.DateTimeRangeField = exports.DateTimeField = exports.DateRangeField = exports.DateField = exports.CheckboxTreeField = exports.CheckboxListField = exports.CheckboxField = exports.Button = exports.BlankField = exports.AutoCompleteField = void 0;
6
+ exports.SwitcherListField = exports.SwitcherField = exports.WizardForm = exports.TimeRangeField = exports.EmailField = exports.MaskField = exports.RateField = exports.TimeField = exports.TextField = exports.SliderField = exports.ReCaptchaField = exports.RadioListField = exports.RadioField = exports.PhoneField = exports.PasswordField = exports.NumberField = exports.NavField = exports.InputField = exports.ImageField = exports.HtmlField = exports.Form = exports.FileField = exports.FieldSet = exports.FieldList = exports.FieldLayout = exports.Field = exports.DropDownField = exports.DateTimeRangeField = exports.DateTimeField = exports.DateRangeField = exports.DateField = exports.CheckboxTreeField = exports.CheckboxListField = exports.CheckboxField = exports.Button = exports.BlankField = exports.AutoCompleteField = void 0;
7
7
  var AutoCompleteField_1 = __importDefault(require("./AutoCompleteField"));
8
8
  exports.AutoCompleteField = AutoCompleteField_1["default"];
9
9
  var BlankField_1 = __importDefault(require("./BlankField"));
@@ -54,6 +54,8 @@ var NumberField_1 = __importDefault(require("./NumberField"));
54
54
  exports.NumberField = NumberField_1["default"];
55
55
  var PasswordField_1 = __importDefault(require("./PasswordField"));
56
56
  exports.PasswordField = PasswordField_1["default"];
57
+ var PhoneField_1 = __importDefault(require("./PhoneField"));
58
+ exports.PhoneField = PhoneField_1["default"];
57
59
  var RadioField_1 = __importDefault(require("./RadioField"));
58
60
  exports.RadioField = RadioField_1["default"];
59
61
  var RadioListField_1 = __importDefault(require("./RadioListField"));
@@ -100,6 +102,7 @@ exports["default"] = {
100
102
  NavField: NavField_1["default"],
101
103
  NumberField: NumberField_1["default"],
102
104
  PasswordField: PasswordField_1["default"],
105
+ PhoneField: PhoneField_1["default"],
103
106
  RadioField: RadioField_1["default"],
104
107
  RadioListField: RadioListField_1["default"],
105
108
  ReCaptchaField: ReCaptchaField_1["default"],